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

📄 vold.c

📁 linux下自动mount各种即插即用设备的一个小程序源码 文件包含内容: /vold.h /vold.c /split.h /split.c /disktype-6/disktype.c
💻 C
📖 第 1 页 / 共 2 页
字号:
			}		}	}		return(ret);}/*	Fills in a valid mountpoint (if != NULL). If we already have a mountpoint (from fstab) believe the user and return.	Otherwise try to create one with volumename or device in which case we have to test if we can really use it */void get_mountpoint(vold_mount* vm) {    char target[MAX_STRLEN + 1];    char* devicename;	char* tmp;		if(vm == NULL) return;		if(vm->mountpoint != NULL) {		/* we already ha a mountpoint, believe the user! */		return;	}	 	/* no fixed mount. mounting automatic */	if(vm->volumename != NULL && strlen(vm->volumename) > 0) {		/* we have a volume label. now strip illegal chars ('/') */		debugmsg("stripping illegal char '/' from volume label: '%s'", vm->volumename);		tmp = strstr(vm->volumename, "/");		while(tmp != NULL) {			*tmp = '_';			tmp = strstr(vm->volumename, "/");		}		debugmsg("legal volume label after stripping: '%s'", vm->volumename);		snprintf(target, MAX_STRLEN, "%s/%s", volumeroot, vm->volumename);    } else {    	/* no volume label, create a generic mountpoint (/Volumes/sda1)*/    	devicename = strrchr(vm->device, '/');    	snprintf(target, MAX_STRLEN, "%s%s", volumeroot, devicename);    	debugmsg("device has no label, mountpoint: %s", target);   	}	target[MAX_STRLEN] = '\0';	/*	validate mountpoint: check if folder exists, 		not already used by another device etc. 		returns a valid mountpoint (and creates directory automatically) */	vm->mountpoint = validate_mountpoint(target, 0);	/* vm->mountflags = defaultmountflags; */	}/*	Checks if target can be used as mountpoint. If not adds a number to it and recursively calls itself to check again.	final target is either target or "target X" with 0 < X <= 255 */char* validate_mountpoint(char* target, int recursion_level) {	struct stat buf;	char real_target[MAX_STRLEN + 1];	char* new_target;		if(target == NULL || recursion_level > 255) return NULL;		if(recursion_level != 0) {		/* we are in recursion mode. add the recursion suffix to name */		snprintf(real_target, MAX_STRLEN, "%s #%i", target, recursion_level);		real_target[MAX_STRLEN] = '\0';	} else {		snprintf(real_target, MAX_STRLEN, "%s", target);		real_target[MAX_STRLEN] = '\0';	}		if( stat(real_target, &buf) == 0) {		/*	target exists */		if(S_ISDIR(buf.st_mode) && !dir_mounted(real_target)) {			/* good, use directory as mountpoint */		} else {			/*	either dir already used by another mount or something else				-> try new mountpoint */			debugmsg("validate: not selecting %s: dir already used", real_target);			debugmsg("isdir: %s, ismounted: %s", S_ISDIR(buf.st_mode)?"yes":"no", dir_mounted(real_target)?"yes":"no");			new_target = validate_mountpoint(target, recursion_level + 1);			return(new_target);		}		} else {		/* target does not exist. very good, now mkdir and return */		umask(0);		if( mkdir(real_target, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {			/* could not create mountpoint, try to find another */			debugmsg("validate: not selecting %s: cannot create dir", real_target);			debugmsg("reason: %s", strerror(errno));			new_target = validate_mountpoint(target, recursion_level + 1);			return(new_target);		}	}	return strdup(real_target);}/*	Tests if device is mounted. It doesn't matter whether device contains a device ('/dev/sda') or	a mountpoint ('/mnt/cdrom') */int dir_mounted(char* device) {	FILE* fd;	struct mntent* m;	int ret = 0;	if(device == NULL) return 0;		fd = fopen("/proc/mounts", "r+");	if(fd == NULL) {		errormsg("Cannot open /proc/mounts: %s", strerror(errno));		return 0;	}		for(m = getmntent(fd); m != NULL; m = getmntent(fd)) {				if( strncmp(device, m->mnt_fsname, MAX_STRLEN) == 0 || strncmp(device, m->mnt_dir, MAX_STRLEN) == 0) {			/* device is already mounted */			ret = 1;			break;		}	}	if(m) free(m);		fclose(fd);	return ret;}/* returns 1 if it could find a uuid */int get_uuid_from_fs(char* fstype, char* device, uuid_t uuid) {	/* TODO */	return 0;}/* reads the config file */void loadconfigfile(char* filename) {	FILE* configfile;	char line[MAX_STRLEN + 1];	char* p;	int argc;	char* argv[128];	char* linecopy;	int linecount = 0;	if( !(configfile = fopen(filename, "r")) ) {		fprintf(stderr, "*WARNING* config file %s not found. Using defaults\n", filename);		return;	}	while( !feof(configfile) ) {		linecount++;		fgets(line, sizeof line, configfile);		if( (p = strpbrk(line, "#\r\n")))			*p = 0;		linecopy = strdup(line);		argc = splitline(argv, (sizeof argv)/(sizeof argv[0]), linecopy);		exec_config(argc, argv, linecount);	}	fclose(configfile);}#define BEGIN_CONFIG(option, argcmin)	\if(!strcmp(argv[0], option)) {\	if(argc < argcmin) {\		fprintf(stderr, "LINE %i "option": to few arguments\n", linecount); \		return; \	}#define CONFIG_OPTION(option,argcmin)	\} else if(!strcmp(argv[0], option)) {\	if(argc < argcmin) {\		fprintf(stderr, "LINE %i "option": to few arguments\n", linecount); \		return; \	}#define END_CONFIG				}int option_true(char* option) {	if(strspn(&option[0], "1tTyYjJ")) {		return 1;	}	return 0;}/* config file executor - returns number of arguments parsed, -1 on error */void exec_config(int argc, char* argv[], int linecount) {	int ivar1;	if(!argc)		return;		BEGIN_CONFIG("volumeroot", 1)		strncpy(volumeroot, argv[1], MAX_STRLEN);	CONFIG_OPTION("check_delay", 1)		check_delay = atoi(argv[1]);	CONFIG_OPTION("default_mntopts", 1)		/* TODO */	CONFIG_OPTION("scan", 1)		ivar1 = 0;		if(argc > 2) {			ivar1 = option_true(argv[2]);		}		sdevice_add(sdevice_new(argv[1], ivar1));	CONFIG_OPTION("uuid_filecheck", 1)		uuid_filecheck = option_true(argv[1]);	CONFIG_OPTION("background", 1)		background = option_true(argv[1]);	CONFIG_OPTION("debug", 1)		debug = option_true(argv[1]);	CONFIG_OPTION("include", 1)		loadconfigfile(argv[1]);	END_CONFIG		}/* read the commandline arguments */void getconfig(int argc, char* argv[]) {	int c = 0, opt_index = 0;	int cmd_debug = -1;	int cmd_background = -1;	char cmd_pidfile[MAX_STRLEN + 1] = "";	static struct option long_options[] = {		                                      { "debug", 0, 0, 'd'},		                                      { "background", 0, 0, 'b' },		                                      { "configfile", 1, 0, 'c' },		                                      { "help", 0, 0, 'h' },		                                      { "pidfile", 1, 0, 'p' },		                                      { 0, 0, 0, 0 }	                                      };	/* first of all read in the command line - needed to see what configfile to read etc */	while (c != -1) {		c = getopt_long(argc, argv, "dbc:hp:", long_options, &opt_index);		switch(c) {		case 0:			/* we got a long only option */			/* this time we don't have any *///			if(!strcmp("ppp-pidfile", long_options[opt_index].name))//				strncpy(cmd_ppp_pidfile, optarg, MAX_STRLEN);			break;		case 'd':			cmd_debug = 1;			break;		case 'b':			cmd_background = 1;			break;		case 'c':			/* no cmd_configfilename here of course! */			strncpy(configfilename, optarg, MAX_STRLEN);			break;		case 'h':			showversion();			showhelp();			quit(0);			break;		case 'p':			strncpy(cmd_pidfile, optarg, MAX_STRLEN);			break;		case '?':			showhelp();			quit(1);			break;		}	}	if(optind < argc) {		fprintf(stderr, "unrecognized options: ");		while(optind < argc)			fprintf(stderr, "%s ", argv[optind++]);		fprintf(stderr, "\n");		showhelp();		quit(1);	}	/* now read the configfile */	loadconfigfile(configfilename);	/* now let the commandline override the options from the configfile! */	if(strcmp("", cmd_pidfile))		strncpy(pidfile, cmd_pidfile, MAX_STRLEN);	if(cmd_debug != -1)		debug = cmd_debug;	if(cmd_background != -1)		background= cmd_background;}/* shows a help message */void showhelp() {	printf("usage: vold [-dbh] [-c configfile] [-p pidfile] \n");	printf("\noptions:\n"	       " -d   --debug               debug mode\n"	       " -b   --background          fork() to background - deamonize and stay silent\n"	       " -h   --help                display this help message\n"	       " -c   --configfile [file]   read configuration from 'file' (defaults to\n"	       "                            "VOLD_ROOT VOLD_CONFIGFILE")\n"	       "      --pidfile             pidfile to use (defaults to "VOLD_PIDFILE")\n"	      );}/* shows the version and welcome message */void showversion() {	printf("vold - GNU/Linux Volume Daemon V"VOLD_VERSION"."VOLD_SUBVERSION" - written by Clemens Wacha\n\n");}/* writes pid file to /var/run/vold.pid */void writepidfile(char* filename) {    FILE* fpid = NULL;	    if( (fpid = fopen(filename, "r")) ) {	errormsg("The pid file '%s' does already exist!", filename);	errormsg("Use --pidfile to choose another filename\n");	quit(1);    }    if( !(fpid = fopen(filename, "w")) ) {	errormsg("Can't create pid file\n");	quit(1);    }    fprintf(fpid, "%i\n", getpid() );    fflush(fpid);    fclose(fpid);    debugmsg("writing pidfile done\n");}/* signal handler */void signal_handler(int signum) {	debugmsg("\ngot signal - quitting\n");	done = 1;}void check_on_signal(int signum) {	logmsg("Got SIGUSR1. Scanning on demand...");	vmount_list();	scan_devices(0);}/* cleanup stuff */void quit(int errorlevel) {	sdevice_free(scan_list);	vmount_free(mount_list);	exit(errorlevel);}int main(int argc, char* argv[]) {    int pid;	uid_t uid;		    /* install signals */    signal(SIGTERM, signal_handler);    signal(SIGINT, signal_handler);	signal(SIGUSR1, check_on_signal);	showversion();	uid = geteuid();	if(uid != 0) {		errormsg("You are NOT root! Only root can run this program");		exit(1);	}    /* initial setup */	snprintf(configfilename, MAX_STRLEN, "%s%s",VOLD_ROOT,VOLD_CONFIGFILE);	strncpy(pidfile, VOLD_PIDFILE, MAX_STRLEN);	strncpy(volumeroot, VOLD_VOLUMEROOT, MAX_STRLEN);	getconfig(argc, argv);    /* begin fork stuff */    if(background) {	pid = fork();	switch(pid) {		case -1:	    	errormsg("Cannot fork to background - Exiting\n\n");	    	quit(1);	    	break;		case 0:	    	writepidfile(pidfile); //update pidfile	    	break;		default:	    	/* quit father process */	    	quit(0);	    	break;		}    }    /* end fork stuff */      load_mounts();	load_fstab();	scan_devices(0);	    debugmsg("Greetings! - Entering Main Loop");    while(!done) {		scan_devices(1);		sleep(check_delay);    }	remove(pidfile);    quit(0);    return 0;}

⌨️ 快捷键说明

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