int main(int argc, char *argv[])
{
	int ch;
	int fd;
	int res;
	char *origmnt;
	char *mnt;
	static int unmount = 0;
	static int lazy = 0;
	static int quiet = 0;
	char *devfd;
	char *commfd;
	int cfd;
	const char *opts = "";

	static const struct option long_opts[] = {
		{"unmount", no_argument, NULL, 'u'},
		{"lazy",    no_argument, NULL, 'z'},
		{"quiet",   no_argument, NULL, 'q'},
		{"help",    no_argument, NULL, 'h'},
		{"version", no_argument, NULL, 'V'},
		{0, 0, 0, 0}};

	progname = strdup(argv[0]);
	if (progname == NULL) {
		fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
		exit(1);
	}

	while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
				 NULL)) != -1) {
		switch (ch) {
		case 'h':
			usage();
			break;

		case 'V':
			show_version();
			break;

		case 'o':
			opts = optarg;
			break;

		case 'u':
			unmount = 1;
			break;

		case 'z':
			lazy = 1;
			break;

		case 'q':
			quiet = 1;
			break;

		default:
			exit(1);
		}
	}

	if (lazy && !unmount) {
		fprintf(stderr, "%s: -z can only be used with -u\n", progname);
		exit(1);
	}

	if (optind >= argc) {
		fprintf(stderr, "%s: missing mountpoint argument\n", progname);
		exit(1);
	} else if (argc > optind + 1) {
		fprintf(stderr, "%s: extra arguments after the mountpoint\n",
			progname);
		exit(1);
	}

	origmnt = argv[optind];

	drop_privs();
	mnt = fuse_mnt_resolve_path(progname, origmnt);
	if (mnt != NULL) {
		res = chdir("/");
		if (res == -1) {
			fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
			exit(1);
		}
	}
	restore_privs();
	if (mnt == NULL)
		exit(1);

	umask(033);
	if (unmount) {
		if (geteuid() == 0)
			res = unmount_fuse(mnt, quiet, lazy);
		else {
			res = umount2(mnt, lazy ? 2 : 0);
			if (res == -1 && !quiet)
				fprintf(stderr,
					"%s: failed to unmount %s: %s\n",
					progname, mnt, strerror(errno));
		}
		if (res == -1)
			exit(1);
		return 0;
	}

	devfd = getenv(FUSE_DEVFD_ENV);
	if (devfd == NULL) {
		commfd = getenv(FUSE_COMMFD_ENV);
		if (commfd == NULL) {
			fprintf(stderr, "%s: old style mounting not supported\n",
				progname);
			exit(1);
		}
	}

	fd = mount_fuse(mnt, opts, devfd);
	if (fd == -1)
		exit(1);

	if (devfd == NULL) {
		cfd = atoi(commfd);
		res = send_fd(cfd, fd);
		if (res == -1)
			exit(1);
	}

	return 0;
}
int main(int argc, char *argv[])
{
	sigset_t sigset;
	int ch;
	int fd;
	int res;
	char *origmnt;
	char *mnt;
	static int unmount = 0;
	static int lazy = 0;
	static int quiet = 0;
	char *commfd;
	int cfd;
	const char *opts = "";

	static const struct option long_opts[] = {
		{"unmount", no_argument, NULL, 'u'},
		{"lazy",    no_argument, NULL, 'z'},
		{"quiet",   no_argument, NULL, 'q'},
		{"help",    no_argument, NULL, 'h'},
		{"version", no_argument, NULL, 'V'},
		{0, 0, 0, 0}};

	progname = strdup(argv[0]);
	if (progname == NULL) {
		fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
		exit(1);
	}

	while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
				 NULL)) != -1) {
		switch (ch) {
		case 'h':
			usage();
			break;

		case 'V':
			show_version();
			break;

		case 'o':
			opts = optarg;
			break;

		case 'u':
			unmount = 1;
			break;

		case 'z':
			lazy = 1;
			break;

		case 'q':
			quiet = 1;
			break;

		default:
			exit(1);
		}
	}

	if (lazy && !unmount) {
		fprintf(stderr, "%s: -z can only be used with -u\n", progname);
		exit(1);
	}

	if (optind >= argc) {
		fprintf(stderr, "%s: missing mountpoint argument\n", progname);
		exit(1);
	} else if (argc > optind + 1) {
		fprintf(stderr, "%s: extra arguments after the mountpoint\n",
			progname);
		exit(1);
	}

	origmnt = argv[optind];

	drop_privs();
	mnt = fuse_mnt_resolve_path(progname, origmnt);
	if (mnt != NULL) {
		res = chdir("/");
		if (res == -1) {
			fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
			exit(1);
		}
	}
	restore_privs();
	if (mnt == NULL)
		exit(1);

	umask(033);
	if (unmount)
		goto do_unmount;

	commfd = getenv(FUSE_COMMFD_ENV);
	if (commfd == NULL) {
		fprintf(stderr, "%s: old style mounting not supported\n",
			progname);
		exit(1);
	}

	fd = mount_fuse(mnt, opts);
	if (fd == -1)
		exit(1);

	cfd = atoi(commfd);
	res = send_fd(cfd, fd);
	if (res == -1)
		exit(1);
	close(fd);

	if (!auto_unmount)
		return 0;

	/* Become a daemon and wait for the parent to exit or die.
	   ie For the control socket to get closed. 
	   btw We don't want to use daemon() function here because
	   it forks and messes with the file descriptors. */
	setsid();
	res = chdir("/");
	if (res == -1) {
		fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
		exit(1);
	}

	sigfillset(&sigset);
	sigprocmask(SIG_BLOCK, &sigset, NULL);

	lazy  = 1;
	quiet = 1;

	while (1) {
		unsigned char buf[16];
		int n = recv(cfd, buf, sizeof(buf), 0);
		if (!n)
			break;

		if (n < 0) {
			if (errno == EINTR)
				continue;
			break;
		}
	}

do_unmount:
	if (geteuid() == 0)
		res = unmount_fuse(mnt, quiet, lazy);
	else {
		res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
		if (res == -1 && !quiet)
			fprintf(stderr,
				"%s: failed to unmount %s: %s\n",
				progname, mnt, strerror(errno));
	}
	if (res == -1)
		exit(1);
	return 0;
}
Exemple #3
0
int main(int argc, char *argv[])
{
    int ch;
    int fd;
    int res;
    char *origmnt;
    char *mnt;
    static int unmount = 0;
    static int lazy = 0;
    static int quiet = 0;
    char *commfd;
    int cfd;
    const char *opts = "";

    static const struct option long_opts[] = {
        {"unmount", no_argument, NULL, 'u'},
        {"lazy",    no_argument, NULL, 'z'},
        {"quiet",   no_argument, NULL, 'q'},
        {"help",    no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'V'},
        {0, 0, 0, 0}};

    progname = strdup(argv[0]);
    if (progname == NULL) {
        fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
        exit(1);
    }

    while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts, NULL)) != -1) {
        switch (ch) {
        case 'h':
            usage();
            break;

        case 'V':
            show_version();
            break;

        case 'o':
            opts = optarg;
            break;

        case 'u':
            unmount = 1;
            break;

        case 'z':
            lazy = 1;
            break;

        case 'q':
            quiet = 1;
            break;

        default:
            exit(1);
        }
    }

    if (lazy && !unmount) {
        fprintf(stderr, "%s: -z can only be used with -u\n", progname);
        exit(1);
    }

    if (optind >= argc) {
        fprintf(stderr, "%s: missing mountpoint argument\n", progname);
        exit(1);
    }

    origmnt = argv[optind];

    drop_privs();
    mnt = resolve_path(origmnt);
    restore_privs();
    if (mnt == NULL)
        exit(1);

    umask(033);
    if (unmount) {
        if (geteuid() == 0) {
            int mtablock = lock_mtab();
            res = unmount_fuse(mnt, quiet, lazy);
            unlock_mtab(mtablock);
        } else
            res = do_unmount(mnt, quiet, lazy);
        if (res == -1)
            exit(1);
        return 0;
    }

    commfd = getenv(FUSE_COMMFD_ENV);
    if (commfd == NULL) {
        fprintf(stderr, "%s: old style mounting not supported\n", progname);
        exit(1);
    }

    fd = mount_fuse(mnt, opts);
    if (fd == -1)
        exit(1);

    cfd = atoi(commfd);
    res = send_fd(cfd, fd);
    if (res == -1)
        exit(1);

    return 0;
}
Exemple #4
0
int main(int argc, char *argv[])
{
    int a;
    int fd;
    int res;
    char *origmnt;
    char *mnt;
    int unmount = 0;
    char **userprog;
    int numargs;
    char mypath[PATH_MAX];
    char *unmount_cmd;
    char *commfd;
    char verstr[128];
    int flags = 0;

    progname = argv[0];

    for(a = 1; a < argc; a++) {
        if(argv[a][0] != '-')
            break;

        switch(argv[a][1]) {
        case 'c':
            flags |= FUSE_KERNEL_CACHE;
            break;

        case 'h':
            usage();
            break;

        case 'u':
            unmount = 1;
            break;

        case 'p':
            flags |= FUSE_DEFAULT_PERMISSIONS;
            break;

        case 'x':
            if(getuid() != 0) {
                fprintf(stderr, "%s: option %s is allowed only for root\n",
                        progname, argv[a]);
                exit(1);
            }
            flags |= FUSE_ALLOW_OTHER;
            break;

        default:
            fprintf(stderr, "%s: Unknown option %s\n", progname, argv[a]);
            exit(1);
        }
    }

    if(a == argc) {
        fprintf(stderr, "%s: Missing mountpoint argument\n", progname);
        exit(1);
    }

    origmnt = argv[a++];

    if(getpid() != 0)
        drop_privs();

    mnt = resolve_path(origmnt, unmount);
    if(mnt == NULL)
        exit(1);

    if(getpid() != 0)
        restore_privs();

    if(unmount) {
        res = remove_mount(mnt);
        if(res == -1)
            exit(1);

        return 0;
    }

    commfd = getenv(FUSE_COMMFD_ENV);

    if(a == argc && commfd == NULL) {
        fprintf(stderr, "%s: Missing program argument\n", progname);
        exit(1);
    }

    userprog = argv + a;
    numargs = argc - a;

    fd = mount_fuse(mnt, flags);
    if(fd == -1)
        exit(1);

    if(commfd != NULL) {
        int cfd = atoi(commfd);
        res = send_fd(cfd, fd);
        if(res == -1)
            exit(1);
        exit(0);
    }

    /* Dup the file descriptor to stdin */
    if(fd != 0) {
        dup2(fd, 0);
        close(fd);
    }

    /* Strangely this doesn't work after dropping permissions... */
    res = readlink("/proc/self/exe", mypath, sizeof(mypath) - 1);
    if(res == -1) {
        fprintf(stderr, "%s: failed to determine self path: %s\n",
                progname, strerror(errno));
        strcpy(mypath, "fusermount");
        fprintf(stderr, "using %s as the default\n", mypath);
    }
    else
        mypath[res] = '\0';

    /* Drop setuid/setgid permissions */
    setuid(getuid());
    setgid(getgid());

    unmount_cmd = (char *) malloc(strlen(mypath) + strlen(mnt) + 64);
    sprintf(unmount_cmd, "%s -u %s", mypath, mnt);
    setenv(FUSE_UMOUNT_CMD_ENV, unmount_cmd, 1);
    sprintf(verstr, "%i", FUSE_KERNEL_VERSION);
    setenv(FUSE_KERNEL_VERSION_ENV, verstr, 1);
    setenv(FUSE_MOUNTED_ENV, "", 1);

    execvp(userprog[0], userprog);
    fprintf(stderr, "%s: failed to exec %s: %s\n", progname, userprog[0],
            strerror(errno));

    close(0);
    system(unmount_cmd);
    return 1;
}