--- siefs-0.5/siefs/siefs.c.alt-command-line 2006-12-31 17:59:28 +0300 +++ siefs-0.5/siefs/siefs.c 2006-12-31 18:05:18 +0300 @@ -558,25 +558,63 @@ release: siefs_close, }; -void usage() { +static void usage() +{ + static char *help_argv[] = { "...", "-ho", NULL }; - fprintf(stderr, "Usage: mount -t siefs [-o options] comm_device mountpoint\n\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, "\tuid=\t\towner id\n"); - fprintf(stderr, "\tgid=\t\tgroup id\n"); - fprintf(stderr, "\tumask=\t\tumask value (octal)\n"); - fprintf(stderr, "\tbaudrate=\t\tcommunication speed\n"); - fprintf(stderr, "\tdevice=\t\tcommunication device (for use in fstab)\n"); - fprintf(stderr, "\tnohide\t\t\tdon't hide `telecom' directory\n"); - exit(1); + fprintf(stderr, + "Usage: siefs [options...] device mountpoint [-- FUSE_options...]\n" + " mount -t siefs [-o mount_options] device mountpoint\n" + "\n" + "Options:\n" + " -o opt,opt... mount options\n" + " -n do not update mtab (not supported)\n" + " -v verbose mode (not supported, ignored)\n" + " -h show this help text and exit\n" + "\n" + "Mount options (see also FUSE mount options below):\n" + " -o uid= owner id\n" + " -o gid= group id\n" + " -o umask= umask value (octal)\n" + " -o iocharset= charset for file names\n" + " -o baudrate= communication speed\n" + " -o device= communication device (for use in fstab)\n" + " -o nohide don't hide 'telecom' directory\n" + "\n" + ); + /* Show FUSE options */ + fuse_main(2, help_argv, &siefs_oper); + exit(0); } void cleanup() { obex_shutdown(g_os); } -void parse_options(char *p) +static void add_option(char **options, const char *new_option) +{ + if (*options) { + size_t old_len = strlen(*options); + size_t added_len = strlen(new_option); + char *new_options = malloc(old_len + added_len + 2); + + if (!new_options) { + perror("siefs: out of memory"); + exit(1); + } + memcpy(new_options, *options, old_len); + new_options[old_len] = ','; + memcpy(new_options + old_len + 1, new_option, added_len + 1); + free(*options); + *options = new_options; + } else { + *options = strdup(new_option); + } +} + +static void parse_options(char *options, char **fuse_options) { + char *p = strtok(options, ","); while (p && *p) { if (strncmp(p, "baudrate=", 9) == 0) { g_baudrate = atoi(p+9); @@ -588,67 +626,85 @@ g_umask = strtol(p+6, NULL, 8); } else if (strncmp(p, "iocharset=", 10) == 0) { g_iocharset = strdup(p+10); - *(g_iocharset + strcspn(g_iocharset, ",")) = '\0'; } else if (strncmp(p, "nohide", 6) == 0) { g_hidetc = 0; } else if (strncmp(p, "device=", 7) == 0) { comm_device = strdup(p+7); - *(comm_device + strcspn(comm_device, ",")) = '\0'; + } else { + /* unknown options are passed to FUSE */ + add_option(fuse_options, p); } - p = strchr(p, ','); - if (p) p++; + p = strtok(NULL, ","); } } int main(int argc, char *argv[]) { - char **fuse_argv = (char **) malloc(3 + argc + 1); - char *p, *pp, *env_path; - int i, j, path_size; - pid_t pid; - char default_comm[] = "/dev/mobile"; - char *mntpoint; - - p = strrchr(argv[0], '/'); - p = (p == NULL) ? argv[0] : p+1; - if (strncmp(p, "mount", 5) == 0) { - - /* original call, "mount.siefs /dev/ttyS0 /mnt/mobile -o ..." */ - if (argc < 3) - usage(); - - comm_device = argv[1]; - mntpoint = argv[2]; - if ((argc>3) && (strncmp(argv[3],"-o", 2) == 0)) - parse_options(argv[4]); - } - else { - - /* recall from fusermount, "mount.siefs /dev/ttyS0 ..." */ - if ((argc != 2) && (argc < 4)) - usage(); - - comm_device = argv[1]; - g_baudrate = -1; - g_uid = getuid(); - g_gid = getgid(); - g_umask = umask(0); - g_hidetc = 1; - umask(g_umask); - - if (argc == 2) { - comm_device = default_comm; - mntpoint = argv[1]; - } - else if (argc >= 4) { - if ( strncmp(argv[1], "-o", 2) == 0) { - parse_options(argv[2]); - mntpoint = argv[3]; - } + static char default_comm[] = "/dev/mobile"; + int fuse_argc; + char **fuse_argv; + char *options = NULL; + char *fuse_options = NULL; + char *mountpoint; + char *p, *env_path; + int path_size; + int c; + + while ((c = getopt(argc, argv, "hnvo:")) != -1) { + switch (c) { + case 'h': + usage(); + break; + + case 'n': + fprintf(stderr, "siefs: disabling mtab update is not supported\n"); + return 1; + + case 'v': + /* option '-v' is ignored */ + break; + + case 'o': + if (options) { + fprintf(stderr, "siefs: duplicate '-o ...' option\n"); + return 1; + } + options = optarg; + break; + + case '?': + /* getopt has already printed an error message */ + fprintf(stderr, "Try 'siefs -h' for more information.\n"); + return 1; + + default: + abort(); } } + if (argc < optind + 1) { + fprintf(stderr, "siefs: required parameter missing\n"); + fprintf(stderr, "Try 'siefs -h' for more information.\n"); + return 1; + } + + if (argc == optind + 1) + comm_device = default_comm; + else + comm_device = argv[optind++]; + mountpoint = argv[optind++]; + + g_baudrate = -1; + g_uid = getuid(); + g_gid = getgid(); + g_umask = umask(0); + g_hidetc = 1; + umask(g_umask); + + if (options) + parse_options(options, &fuse_options); + bzero(&dir_st, sizeof(dir_st)); bzero(&file_st, sizeof(file_st)); dir_st.st_nlink = file_st.st_nlink = 1; @@ -670,29 +726,21 @@ exit(1); } - pid = fork(); - if (pid < 0) { - - perror("fork"); - exit(1); - - } else if (pid != 0) { - - /* parent process */ - usleep(200000); - return 0; - - } - - /* child process */ - setsid(); - atexit(cleanup); - fuse_argv[0] = argv[0]; - fuse_argv[1] = mntpoint; - fuse_argv[2] = NULL; - fuse_main(2, fuse_argv, &siefs_oper); + fuse_argc = 0; + fuse_argv = malloc(sizeof(char *) * (argc - optind + 5)); + fuse_argv[fuse_argc++] = argv[0]; + fuse_argv[fuse_argc++] = mountpoint; + if (fuse_options) { + fuse_argv[fuse_argc++] = "-o"; + fuse_argv[fuse_argc++] = fuse_options; + } + while (optind < argc) { + fuse_argv[fuse_argc++] = argv[optind++]; + } + fuse_argv[fuse_argc] = NULL; + fuse_main(fuse_argc, fuse_argv, &siefs_oper); return 0;