/* * lufsmount.c * Copyright (C) 2002 Florin Malita * * This file is part of LUFS, a free userspace filesystem implementation. * See http://lufs.sourceforge.net/ for updates. * * LUFS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * LUFS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #ifdef DEBUGGING #define TRACE(x...) fprintf(stderr, x) #else #define TRACE(x...) do{}while(0); #endif #define ERROR(x...) fprintf(stderr, x) #define MAX_LEN 1024 char *short_opts = "hvu:g:f:d:c:o:Opq"; struct option long_opts[] = { {"help", 0, NULL, 'h'}, {"uid", 1, NULL, 'u'}, {"gid", 1, NULL, 'g'}, {"fmask", 1, NULL, 'f'}, {"dmask", 1, NULL, 'd'}, {"channels",1, NULL, 'c'}, {"opts", 1, NULL, 'o'}, {"own_fs", 0, NULL, 'O'}, {"verbose", 0, NULL, 'v'}, {"password",0, NULL, 'p'}, {"quiet", 0, NULL, 'q'}, {NULL, 0, NULL, 0} }; char buf[MAX_LEN]; void usage(FILE *fp, char *prgname){ fprintf(fp, "Usage: %s ://[[:]@][:][/] [options]\n", prgname); fprintf(fp, " -c, --channels=NR_CHAN the number of transfer channels per filesystem\n"); fprintf(fp, " -d, --dmask=MASK minimum dir permissions\n"); fprintf(fp, " -f, --fmask=MASK minimum file permissions\n"); fprintf(fp, " -g, --gid=GID the gid to own the mounted filesystem\n"); fprintf(fp, " -h, --help display this help and exit\n"); fprintf(fp, " -o, --opts opt=val[,...] file system specific options\n"); fprintf(fp, " -O, --own_fs force fs ownership of the mounting user\n"); fprintf(fp, " -p, --password interactively prompt for password if not specified\n"); fprintf(fp, " -q --quiet disable all logging from daemon (close all fds)\n"); fprintf(fp, " -u, --uid=UID the uid to own the mounted filesystem\n"); fprintf(fp, " -v, --verbose print the mount command before executing\n"); } int main(int argc, char **argv){ int res, verbose = 0, own_fs = 0, ask_pass = 0, quiet = 0; char *uid = NULL, *gid = NULL; char *options = NULL, *chan = NULL; char *fmask = NULL, *dmask = NULL; char *url, *mpoint, *fs; char *user = NULL, *pass = NULL, *root = NULL, *port = NULL; char *i, *j; do{ res = getopt_long(argc, argv, short_opts, long_opts, NULL); switch(res){ case 'h': usage(stdout, argv[0]); return 0; case 'u': uid = optarg; break; case 'g': gid = optarg; break; case 'v': verbose = 1; break; case 'f': fmask = optarg; break; case 'd': dmask = optarg; break; case 'c': chan = optarg; break; case 'p': ask_pass = 1; break; case 'q': quiet = 1; break; case 'o': options = optarg; break; case 'O': own_fs=1; break; default: case '?': TRACE("wrong option\n"); usage(stderr, argv[0]); return 1; case -1: break; }; }while(res != -1); if(optind > argc - 2){ usage(stderr, argv[0]); return 1; } url = argv[optind++]; mpoint = argv[optind++]; TRACE("url: %s\n", url); TRACE("mountpoint: %s\n", mpoint); if(!(i = strstr(url, "://"))){ ERROR("invalid URL (%s): protocol delimiter not found\n", url); return 1; } *i = 0; fs = url; url = i + 3; TRACE("fs: %s\n", fs); i = strchr(url, '@'); j = strchr(url, '/'); if((i) && ((i < j) || (j == NULL))){ *i = 0; user = url; url = i + 1; if((i = strchr(user, ':'))){ *i = 0; pass = i + 1; TRACE("pass: %s\n", pass); } TRACE("user: %s\n", user); } if((i = strchr(url, '/'))){ *i = 0; root = i + 1; TRACE("root: %s\n", root); } if((i = strchr(url, ':'))){ *i = 0; port = i + 1; TRACE("port: %s\n", port); } TRACE("host: %s\n", url); if(!pass && ask_pass) pass = getpass("password:"); if(snprintf(buf, MAX_LEN, "lufsd none %s -o fs=%s", mpoint, fs) >= MAX_LEN) goto too_long; if(strcmp(url, "")){ if(strlen(buf) + strlen(",host=") + strlen(url) >= MAX_LEN) goto too_long; strcat(buf, ",host="); strcat(buf, url); } if(user){ if(strlen(buf) + strlen(",username=") + strlen(user) >= MAX_LEN) goto too_long; strcat(buf, ",username="); strcat(buf, user); } if(pass){ if(strlen(buf) + strlen(",password=") + strlen(pass) >= MAX_LEN) goto too_long; strcat(buf, ",password="); strcat(buf, pass); } if(port){ if(strlen(buf) + strlen(",port=") + strlen(port) >= MAX_LEN) goto too_long; strcat(buf, ",port="); strcat(buf, port); } if(root){ if(strlen(buf) + strlen(",root=/") + strlen(root) >= MAX_LEN) goto too_long; strcat(buf, ",root=/"); strcat(buf, root); } if(uid){ if(strlen(buf) + strlen(",uid=") + strlen(uid) >= MAX_LEN) goto too_long; strcat(buf, ",uid="); strcat(buf, uid); } if(gid){ if(strlen(buf) + strlen(",gid=") + strlen(gid) >= MAX_LEN) goto too_long; strcat(buf, ",gid="); strcat(buf, gid); } if(fmask){ if(strlen(buf) + strlen(",fmask=") + strlen(fmask) >= MAX_LEN) goto too_long; strcat(buf, ",fmask="); strcat(buf, fmask); } if(dmask){ if(strlen(buf) + strlen(",dmask=") + strlen(dmask) >= MAX_LEN) goto too_long; strcat(buf, ",dmask="); strcat(buf, dmask); } if(chan){ if(strlen(buf) + strlen(",channels=") + strlen(chan) >= MAX_LEN) goto too_long; strcat(buf, ",channels="); strcat(buf, chan); } if(options){ if(strlen(buf) + strlen(",") + strlen(options) >= MAX_LEN) goto too_long; strcat(buf, ","); strcat(buf, options); } if(own_fs){ if(strlen(buf) + strlen(",own_fs") >= MAX_LEN) goto too_long; strcat(buf, ",own_fs"); } if(quiet){ if(strlen(buf) + strlen(",quiet") >= MAX_LEN) goto too_long; strcat(buf, ",quiet"); } TRACE("cmd: %s\n", buf); if(verbose) printf("executing command: %s\n", buf); return system(buf); too_long: ERROR("options too long!\n"); return 1; }