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

📄 mmounter.c

📁 linux下的一个mount工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	string dirname = getOption(device, "mountbase", MOUNTBASE)+"/"+generateFriendlyMountPoint(device, label, fs);	if(exists(dirname) && !rm(dirname))	{		unsigned int count = 1;		while(exists(dirname+"-"+itoa(count)) && !rm(dirname+"-"+itoa(count)))			count++;		dirname += "-"+itoa(count);	}	return dirname;}bool ejectDevice(const string & device){	string eject = getOption(device,"eject");	if(eject=="")		return false;	vector<string> args;	args.push_back(device);	return (run(eject, args)==0);}bool mountDevice(const string & device, const string & fs, const string & label, string & dirname){	vector<string> args;		dirname = generateMountPoint(device, label, fs);	mkdir(dirname.c_str(),0);	symlink(".", (dirname+string("/"FINGERPRINT)).c_str());	args.push_back(device);	args.push_back(dirname);	args.push_back("-t");	args.push_back(fs);	args.push_back("-o");	args.push_back(getOption(device, "options", "defaults"));	if(getOption(device, "options."+fs)!="")	{		args.push_back("-o");		args.push_back(getOption(device, "options."+fs));	}	if(run(getOption(device, "mount", MOUNT),args)!=0)	{		rm(dirname);		dirname = "";		return false;	}	else		return true;}bool linkMountedDevice(const string & device, const string & label, const string & fs, const string & mountpoint, string & dirname){	dirname = generateMountPoint(device, label, fs);	if(symlink(mountpoint.c_str(), dirname.c_str())==0)		return true;	else	{		dirname = "";		return false;	}}bool umountDevice(const string & path){	string device = "";		if(!findMountedDevice(path, device) || getOption(device, "userdisk", "no")!="yes")		return false;		vector<string> args;		args.push_back(device);	if(run(getOption(device, "umount", UMOUNT),args)!=0)		return false;	else		return true;}bool cleanUnusedMountPoints(const string & device){	string dirname = getOption(device, "mountbase", MOUNTBASE);	DIR * dir = opendir(dirname.c_str());		if(!dir)		return false;	while(struct dirent * entry = readdir(dir))	{		if(isSymlink(dirname+string("/")+string(entry->d_name)+string("/"FINGERPRINT)))		{			DIAGNOSTIC("cleaning " << entry->d_name << endl);			rm(dirname+string("/")+string(entry->d_name));		}	}	closedir(dir);	return true;}void addToCache(const string & device, const string & mountpoint){	string dirname = getOption(device, "cache", CACHEDIR)+"/"+basename(device);		mkdir(dirname.c_str(), 0777);		symlink(device.c_str(),(dirname+string("/device")).c_str());	symlink(mountpoint.c_str(),(dirname+string("/mountpoint")).c_str());}void removeFromCache(const string & device){	string dirname = getOption(device, "cache", CACHEDIR)+"/"+basename(device);		rm(dirname+string("/device"));	rm(dirname+string("/mountpoint"));	rm(dirname);}bool checkIfCached(const string & device, string & mountpoint){	string dirname = getOption(device, "cache", CACHEDIR)+"/"+basename(device);		if(isSymlink(dirname+string("/mountpoint"))&&(resolveLinks(dirname+string("/device"))==resolveLinks(device)))	{		mountpoint = resolveLinks(dirname+string("/mountpoint"));		return true;	}	else		return false;}void * workingThread(void * p){	string * device = (string*)p;	string current_dir, current_fs, current_volid, ignored="";	bool mmounted = false;	int delay;	if(*device == "*")		return NULL;	DIAGNOSTIC("Polling " << (*device)		<< " (" << getOption(*device, "type","unknown") << ")"		<< endl);		cleanUnusedMountPoints(*device);	monitoringDevice(*device);	delay = atoi(getOption(*device, "delay", "10").c_str());	if(delay<=0) delay = 10;	while(running)	{				if(readable(*device))		{			string mounted_on = "";			bool is_mounted = checkIfDeviceMounted(resolveLinks(*device), mounted_on);			string fs="", labelname="", eject="";						if(!mmounted)	// reset cached values			{				current_dir = "";				current_fs = "";				current_volid = "";			}						if(is_mounted)	// device is currently mounted			{				if(!mmounted)					mmounted |= checkIfCached(*device, current_dir);									if(!mmounted)	// we didn't mount it -> try to symlink to it				{					if(getFSTypeAndVolumeName(*device, fs, labelname))					{						mmounted = linkMountedDevice(*device, labelname, fs, mounted_on, current_dir);						current_fs = fs;						current_volid = labelname;					}				}				else				{					if(resolveLinks(mounted_on)!=resolveLinks(current_dir))	// it's no longer mounted where we mounted it -> forget we mounted it					{						removeFromCache(*device);						mmounted = false;						rm(current_dir);					}				}								ignored = "";			}			else	// device is not currently mounted			{				if(mmounted)	// we thought it was -> eject it and cleanup mount point/symlink				{					removeFromCache(*device);					mmounted = false;					rm(current_dir);					if(!ejectDevice(*device))	// try to eject it						ignored = current_fs+"/"+current_volid;		// ignore this disk so that we won't try to mount it back					else						ignored = "";	// the disk has been successfully ejected				}				else				{					if(getFSTypeAndVolumeName(*device, fs, labelname))	// mmm... seems we could mount it...					{						if(fs+"/"+labelname!=ignored)	// check that we are not ignoring this disk						{							mmounted = mountDevice(*device, fs, labelname, current_dir);	// try to mount it														if(!mmounted)	// failed to mount it								ejectDevice(*device);							else								addToCache(*device, current_dir);														ignored = "";	// the disk we were ignoring has been removed							current_fs = fs;							current_volid = labelname;						}					}					else	// FS couldn't be detected, shut up (device could be offline or containing an unknown FS (audio CD...)					{						ignored = "";	// the disk we were ignoring has been removed					}				}			}		}				sleep(delay);	}		if(mmounted)	{		//umount(current_dir.c_str());		rm(current_dir);	}		DIAGNOSTIC("Stopping polling " << *device << endl);	delete device;	return NULL;}void * sourcePartitionFile(void * p){	string * filename = (string *)p;	int delay = 10;	vector<pthread_t> threads;		DIAGNOSTIC("Sourcing " << *filename << endl);		delay = atoi(getOption("<"+*filename, "delay", "10").c_str());	if(delay<=0) delay = 10;		while(running)	{		FILE * input = fopen(filename->c_str(), "r");				if(input)		{			char line[MAXPATHLEN+1];						while (fgets(line, sizeof(line), input))			{				int ma, mi, sz;				char ptname[MAXPATHLEN+1];				char * s;								if (sscanf (line, " %d %d %d %[^\n]\n", &ma, &mi, &sz, ptname) != 4)					continue;					//skip extended partitions (heuristic: size 1)				if (sz == 1)					continue;					// skip entire disk (minor 0, 64, ... on ide; 0, 16, ... on sd)				// heuristic: partition name ends in a digit				for(s = ptname; *s; s++);				if (isdigit(s[-1]))					if(!isDeviceMonitored(resolveLinks("/dev/"+string(ptname))))					{						pthread_t thread;												DIAGNOSTIC("partition found: " << ptname << endl);						if(pthread_create(&thread,							NULL,							workingThread, 							new string("/dev/"+string(ptname))))							threads.push_back(thread);					}			}						fclose(input);		}				sleep(delay);	}		if(filename)		delete(filename);		for(size_t i=0; i<threads.size(); i++)	{		if(threads[i])			pthread_join(threads[i], NULL);	}		return NULL;}void * listeningThread(void *){	struct my_msgbuf * msg = (struct my_msgbuf*)malloc(sizeof(struct my_msgbuf)+MAXPATHLEN);			while(running)	{		if(msgrcv(msg_queue, (struct msgbuf*)msg, MAXPATHLEN, 0, MSG_NOERROR)!=-1)				switch(msg->mtype)		{			case MMOUNTER_UMOUNT:				umountDevice(msg->mtext);			break;			default:				DIAGNOSTIC("unknown command !" << endl);		}	}			free(msg);}int go(CONFFile conf){	config = &conf;	vector<string> devices = config->listSections();	vector<pthread_t> threads;	pthread_t listeningthread;	pthread_t thread;	size_t i;		pthread_create(&listeningthread, NULL, listeningThread, NULL);		for(i=0; i<devices.size(); i++)			cleanUnusedMountPoints(devices[i]);	for(i=0; i<devices.size(); i++)	{		if(devices[i]!="*")		{						if(devices[i][0]=='<')		// we have to autodetect partitions			{				if(pthread_create(&thread,					NULL,					sourcePartitionFile, 					new string(devices[i].substr(1)))==0)	// strip the leading '<'					threads.push_back(thread);			}			else			{				if(pthread_create(&thread,					NULL,					workingThread, 					new string(devices[i]))==0)					threads.push_back(thread);			}		}	}	for(size_t i=0; i<threads.size(); i++)	{		if(threads[i])			pthread_join(threads[i], NULL);	}	return 0;}int main(int argc, const char * * argv){	int c;	string config = "";	while((c = getopt (argc, (char*const*)argv, "Vgc:")) != -1)	switch(c)	{	case 'V':		cout << VERSION << endl;		return 0;	case 'g':		debug = true;		break;	case 'c':		config = string(optarg);		break;	case '?':		cerr << "usage:" << endl		<< "\t" << argv[0] << " [-V]" << endl		<< "\t" << argv[0] << " [-g] [-c configfile]" << endl;		return 1;	}		rundaemon &= !debug;		if(rundaemon)	{		if(fork())			return 0;		setpgrp();		close(0);		close(1);				ofstream varrunpid(PIDFILE);		varrunpid << getpid() << endl;	}	getlabel["ext2"] = ext2_getlabel;	getlabel["ext3"] = ext2_getlabel;	getlabel["hfs"] = hfs_getlabel;	getlabel["vfat"] = vfat_getlabel;	getlabel["iso9660"] = iso9660_getlabel;	getlabel["ntfs"] = ntfs_getlabel;		signal(SIGTERM, sigterm);	signal(SIGINT, sigterm);		if(config=="")		config = ETCMMOUNTERCONF;		msg_queue = msgget(ftok(config.c_str(), 0), IPC_CREAT | 0666);	// create a world-accessible msg queue		if(msg_queue==-1)		DIAGNOSTIC("could not create message queue" << endl);		int result = go(CONFFile(config.c_str()));		if(msg_queue!=-1)		msgctl(msg_queue, IPC_RMID, NULL);		return result;}

⌨️ 快捷键说明

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