⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 submountd.c

📁 linux下mount各种文件系统的程序submount的源代码
💻 C
字号:
/***************************************************************************                           submountd.c                             -------------------    begin                : Wed May 14 12:29:05 EDT 2003    copyright            : (C) 2003-2004 by Eugene S. Weiss    email                : eweiss@sbcglobal.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program 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.                                   * *                                                                         * ***************************************************************************/ /* This is the user portion of the submount system.  It's just a lightweight  * program for mountiong and unmounting filesystems.  */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/mount.h>#include <sys/user.h>#include <unistd.h>#include <sys/param.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <syslog.h>#include "submountd.h"static struct fs_options fs_opts[] = {	{"iso9660", 1, 0, 1},	{"ntfs", 1, 1, 1},	{"udf", 1, 1, 1},	{NULL, 0, 0, 0}};/* This is the main routine for the unmounting daemon.  It checks that * the filesystem it mounted is at the top of the mountpoint, and then * attempts a umount if it is.  If EBUSY is returned from the umount call, * the loop is continued.  As of version 0.2, it includes a kludge to prevent * layer-caking mounts when a program automatically mounts a device without * checking if it is already mounted (urpmi).  It xshould be removed once the * programs that do this are fixed. */void umountd(struct mount_params *p){	int retval, match;	FILE *mntlist;	char line[4096], fs[16], top[16], mntpt[4096 + 1];	sleep(SPINUP_DELAY);	for (;;) {		sleep(INTERVAL);		mntlist = fopen(MOUNT_LIST, "r");		if (!mntlist)			continue;		match = 0;		while (fgets(line, 4096, mntlist)) {			sscanf(line, "%*s %4096s %15s", mntpt, fs);			if (strcmp(p->mountpoint, mntpt) == 0) {				strcpy(top, fs);				match++;			}		}		fclose(mntlist);		if ((!match) || ((strncmp(fs, "subfs", 6) == 0) &&					(match < 3)))  {			exit(EXIT_SUCCESS);		}		if ((strcmp(p->fstype, fs) == 0) || (match > 2)) {			retval = umount(p->mountpoint);			if ((!retval) && (match < 3))				exit(EXIT_SUCCESS);			if (errno != EBUSY)				exit(EXIT_FAILURE);		}	}}/* Forks off the unmounting daemon. */void launch_umountd(struct mount_params *p){	pid_t pid;	pid = fork();	switch (pid) {	case -1:		break;	case 0:		umountd(p);	default:		break;	}	return;}/* Removes options relevent only to non-UNIX filesystems so they can be * used for mounts with automatic filesystem determination. */char *proc_options(char *fstype, char *options){	char *tmp, *ptr;	int iocharset = 0, umask = 0, uid = 0, i = 0;	if (!(tmp = malloc(strlen(options) + 1)))		exit(EXIT_FAILURE);	if (strcmp("vfat", fstype) == 0) {		strcpy(tmp, options);		return tmp;	}	while (fs_opts[i].name) {		if (strcmp(fs_opts[i].name, fstype) == 0) {			iocharset = fs_opts[i].iocharset;			umask = fs_opts[i].umask;			uid = fs_opts[i].uid;			break;		}		i++;	}	tmp[0] = '\0';	while ((ptr = strsep(&options, ","))) {		if ((!strstr(ptr, "codepage")) &&		    ((!strstr(ptr, "iocharset")) || (iocharset)) &&		    ((!strstr(ptr, "umask")) || (umask)) &&		    ((!strstr(ptr, "uid=")) || (uid)) &&		    ((!strstr(ptr, "gid=")) || (uid))) {			strcat(tmp, ptr);			strcat(tmp, ",");		}	}	return tmp;}/* Actual mounting done here. */int do_mount(char *device, char *mountpoint, char *fstype,	     unsigned long flags, char *options){	int retval = mount(device, mountpoint, fstype, flags, options);	if (retval) {		if ((errno == EROFS) && (!(flags & MS_RDONLY))) {			flags |= MS_RDONLY;			retval = do_mount(device, mountpoint, fstype, flags,				  options);		}		return retval;	}	return 0;}char *floppyfss[] = {"vfat", "ext2", NULL };char *cdfss[] = {"iso9660", "udf", NULL };/* Mounts a set of fs types from the arrays above, or a list provided by the * user.  When it's only a question of two or three fs types, this will be * faster than auto, particularly for floppies. */char *do_list_mount(struct mount_params *p, char **types){	char **list, *opts, *copy;	int retval = 0, i = 0;	if (types)		list = types;	else if (strncmp("floppyfss", p->fstype, 9) == 0)		list = floppyfss;	else if (strncmp("cdfss", p->fstype, 5) == 0)		list = cdfss;	else		return NULL;	if (!(copy = malloc(strlen(p->options) + 1)))		exit(EXIT_FAILURE);	while (list[i]) {		strcpy(copy, p->options);		opts = proc_options(list[i], copy);		retval =		    do_mount(p->device, p->mountpoint, list[i], p->flags,			     opts);		free(opts);		if (!retval) {			free(copy);			return list[i];		}		i++;	}	free(copy);	return NULL;}/* Mounts from a colon seperated list. */char *user_list_mount(struct mount_params *p){	int len = strlen(p->fstype);	int i, num_types = 1;	char **list, *fstype;	for (i = 0; i < len; i++) {		if (p->fstype[i] == ':')			num_types++;	}	if (!(list = malloc(sizeof(*list) * (num_types + 1))))		exit(EXIT_FAILURE);	i = 0;	while ((list[i] = strsep(&p->fstype, ":")))		i++;	fstype = do_list_mount(p, list);	free(list);	return fstype;}int main(int argc, char *argv[]){	int i, retval = 0;	struct mount_params p;	char *ptr, *opts = NULL;	openlog("submountd", LOG_CONS | LOG_ODELAY, LOG_USER);	if (argc != 6) {		ERR("%d arguments received, 6 needed.\n", argc);		exit(EXIT_FAILURE);	}	/* Test option size-- if anything is bigger than PAGE_SIZE, this	   didn't come from the kernel. */	for (i = 0; i < argc; i++) {		ptr = argv[i];		if ((strnlen(ptr, getpagesize())) > (getpagesize() - 1)) {			ERR("Argument too large for syscall.\n");			exit(EXIT_FAILURE);		}	}	p.device = argv[1];	p.mountpoint = argv[2];	p.fstype = argv[3];	p.options = argv[5];	sscanf(argv[4], "%lx", &p.flags);	if (strchr(p.fstype, ':')) {		p.fstype = user_list_mount(&p);		if (!p.fstype)			retval = -1;	} else if (strstr(p.fstype, "fss")) {		p.fstype = do_list_mount(&p, NULL);		if (!p.fstype)			retval = -1;	} else if (strncmp("auto", p.fstype, 5) == 0) {		p.fstype = do_guess_fstype(p.device);		if (!p.fstype) {			ERR("unable to determine filesystem type\n");			retval = -1;		}		else {		opts = proc_options(p.fstype, p.options);		retval =		    do_mount(p.device, p.mountpoint, p.fstype, p.flags,			     opts);		free(opts);		}	} else		retval =		    do_mount(p.device, p.mountpoint, p.fstype, p.flags,			     p.options);	if (retval) {		ERR("mount failure, %s\n", strerror(errno));		exit(EXIT_FAILURE);	}	launch_umountd(&p);	exit(EXIT_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -