http://prdownloads.sourceforge.net/lufs/lufs-0.9.6.tar.gz?download
[lufs.git] / util / lufsmount.c
1 /*
2  * lufsmount.c
3  * Copyright (C) 2002 Florin Malita <mali@go.ro>
4  *
5  * This file is part of LUFS, a free userspace filesystem implementation.
6  * See http://lufs.sourceforge.net/ for updates.
7  *
8  * LUFS is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * LUFS is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #ifndef _GNU_SOURCE
29 #define _GNU_SOURCE
30 #endif
31 #include <getopt.h>
32
33 #ifdef DEBUGGING
34 #define TRACE(x...) fprintf(stdout, x)
35 #else 
36 #define TRACE(x...) do{}while(0);
37 #endif 
38
39 #define ERROR(x...) fprintf(stderr, x)
40
41 #define MAX_LEN         1024
42
43 char *short_opts = "hvu:g:f:d:c:o:Opq";
44 struct option long_opts[] = {
45     {"help",    0, NULL, 'h'},
46     {"uid",     1, NULL, 'u'},
47     {"gid",     1, NULL, 'g'},
48     {"fmask",   1, NULL, 'f'},
49     {"dmask",   1, NULL, 'd'},
50     {"channels",1, NULL, 'c'},
51     {"opts",    1, NULL, 'o'},
52     {"own_fs",  0, NULL, 'O'},
53     {"verbose", 0, NULL, 'v'},
54     {"password",0, NULL, 'p'},
55     {"quiet",   0, NULL, 'q'},
56     {NULL,      0, NULL, 0}
57 };
58 char buf[MAX_LEN];
59
60
61 void
62 usage(FILE *fp, char *prgname){
63     fprintf(fp, "Usage: %s <fs_type>://[<user>[:<pass>]@]<host>[:<port>][/<remote_root>] <mountpoint> [options]\n", prgname);
64     fprintf(fp, "   -c, --channels=NR_CHAN    the number of transfer channels per filesystem\n");
65     fprintf(fp, "   -d, --dmask=MASK          minimum dir permissions\n");
66     fprintf(fp, "   -f, --fmask=MASK          minimum file permissions\n");
67     fprintf(fp, "   -g, --gid=GID             the gid to own the mounted filesystem\n");
68     fprintf(fp, "   -h, --help                display this help and exit\n");
69     fprintf(fp, "   -o, --opts opt=val[,...]  file system specific options\n");
70     fprintf(fp, "   -O, --own_fs              force fs ownership of the mounting user\n");
71     fprintf(fp, "   -p, --password            interactively prompt for password if not specified\n");
72     fprintf(fp, "   -q  --quiet               disable all logging from daemon (close all fds)\n");
73     fprintf(fp, "   -u, --uid=UID             the uid to own the mounted filesystem\n");
74     fprintf(fp, "   -v, --verbose             print the mount command before executing\n");
75 }
76
77 int
78 main(int argc, char **argv){
79     int res, verbose = 0, own_fs = 0, ask_pass = 0, quiet = 0;
80     char *uid = NULL, *gid = NULL;
81     char *options = NULL, *chan = NULL;
82     char *fmask = NULL, *dmask = NULL;
83     char *url, *mpoint, *fs;
84     char *user = NULL, *pass = NULL, *root = NULL, *port = NULL;
85     char *i, *j;
86
87     do{
88         res = getopt_long(argc, argv, short_opts, long_opts, NULL);
89
90         switch(res){
91         case 'h':
92             usage(stdout, argv[0]);
93             return 0;
94
95         case 'u':
96             uid = optarg;
97             break;
98
99         case 'g':
100             gid = optarg;
101             break;
102         
103         case 'v':
104             verbose = 1;
105             break;
106
107         case 'f':
108             fmask = optarg;
109             break;
110
111         case 'd':
112             dmask = optarg;
113             break;
114
115         case 'c':
116             chan = optarg;
117             break;
118             
119         case 'p':
120             ask_pass = 1;
121             break;
122
123         case 'q':
124             quiet = 1;
125             break;
126
127         case 'o':
128             options = optarg;
129             break;
130
131         case 'O':
132             own_fs=1;
133             break;
134
135         default:
136         case '?':
137             TRACE("wrong option\n");
138             usage(stderr, argv[0]);
139             return 1;
140
141         case -1:
142             break;
143         };
144     }while(res != -1);
145     
146     if(optind > argc - 2){
147         usage(stderr, argv[0]);
148         return 1;
149     }
150     
151     url = argv[optind++];
152     mpoint = argv[optind++];
153
154     TRACE("url: %s\n", url);
155     TRACE("mountpoint: %s\n", mpoint);
156     
157     if(!(i = strstr(url, "://"))){
158         ERROR("invalid URL (%s): protocol delimiter not found\n", url);
159         return 1;
160     }
161     
162     *i = 0;
163     fs = url;
164     url = i + 3;
165     TRACE("fs: %s\n", fs);
166
167     i = strchr(url, '@');
168     j = strchr(url, '/');
169
170     if((i) && ((i < j) || (j == NULL))){
171         *i = 0;
172         user = url;
173         url = i + 1;
174         
175         if((i = strchr(user, ':'))){
176             *i = 0;
177             pass = i + 1;
178             TRACE("pass: %s\n", pass);
179         }
180         TRACE("user: %s\n", user);
181     }
182        
183     if((i = strchr(url, '/'))){
184         *i = 0;
185         root = i + 1;
186         TRACE("root: %s\n", root);
187     }
188
189     if((i = strchr(url, ':'))){
190         *i = 0;
191         port = i + 1;
192         TRACE("port: %s\n", port);
193     }
194
195     TRACE("host: %s\n", url);
196
197     if(!pass && ask_pass)
198         pass = getpass("password:");
199
200
201     if(snprintf(buf, MAX_LEN, "lufsd none %s -o fs=%s", mpoint, fs) >= MAX_LEN)
202         goto too_long;
203
204     if(strcmp(url, "")){
205         if(strlen(buf) + strlen(",host=") + strlen(url) >= MAX_LEN)
206             goto too_long;
207
208         strcat(buf, ",host=");
209         strcat(buf, url);
210     }
211         
212     if(user){
213         if(strlen(buf) + strlen(",username=") + strlen(user) >= MAX_LEN)
214             goto too_long;
215
216         strcat(buf, ",username=");
217         strcat(buf, user);
218     }
219
220     if(pass){
221         if(strlen(buf) + strlen(",password=") + strlen(pass) >= MAX_LEN)
222             goto too_long;
223
224         strcat(buf, ",password=");
225         strcat(buf, pass);
226     }
227
228     if(port){
229         if(strlen(buf) + strlen(",port=") + strlen(port) >= MAX_LEN)
230             goto too_long;
231             
232         strcat(buf, ",port=");
233         strcat(buf, port);    
234     }
235
236     if(root){
237         if(strlen(buf) + strlen(",root=/") + strlen(root) >= MAX_LEN)
238             goto too_long;
239             
240         strcat(buf, ",root=/");
241         strcat(buf, root);
242     }
243
244     if(uid){
245         if(strlen(buf) + strlen(",uid=") + strlen(uid) >= MAX_LEN)
246             goto too_long;
247
248         strcat(buf, ",uid=");
249         strcat(buf, uid);
250     }
251
252     if(gid){
253         if(strlen(buf) + strlen(",gid=") + strlen(gid) >= MAX_LEN)
254             goto too_long;
255
256         strcat(buf, ",gid=");
257         strcat(buf, gid);
258     }
259
260     if(fmask){
261         if(strlen(buf) + strlen(",fmask=") + strlen(fmask) >= MAX_LEN)
262             goto too_long;
263
264         strcat(buf, ",fmask=");
265         strcat(buf, fmask);
266     }
267
268     if(dmask){
269         if(strlen(buf) + strlen(",dmask=") + strlen(dmask) >= MAX_LEN)
270             goto too_long;
271
272         strcat(buf, ",dmask=");
273         strcat(buf, dmask);
274     }
275
276     if(chan){
277         if(strlen(buf) + strlen(",channels=") + strlen(chan) >= MAX_LEN)
278             goto too_long;
279
280         strcat(buf, ",channels=");
281         strcat(buf, chan);
282     }
283
284     if(options){
285         if(strlen(buf) + strlen(",") + strlen(options) >= MAX_LEN)
286             goto too_long;
287
288         strcat(buf, ",");
289         strcat(buf, options);
290     }
291
292     if(own_fs){
293         if(strlen(buf) + strlen(",own_fs") >= MAX_LEN)
294             goto too_long;
295
296         strcat(buf, ",own_fs");
297     }
298
299     if(quiet){
300         if(strlen(buf) + strlen(",quiet") >= MAX_LEN)
301             goto too_long;
302
303         strcat(buf, ",quiet");
304     }
305
306     TRACE("cmd: %s\n", buf);
307
308     if(verbose)
309         printf("executing command: %s\n", buf);
310
311     return system(buf);
312
313   too_long:
314     ERROR("options too long!\n");
315     return 1;
316 }