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

📄 mount_tfs.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
 */voidfind_subdirs(mnt, path, subdir_list)	struct mntent	*mnt;	char		*path;	Nse_list	subdir_list;{	struct stat	statb;	int		len = strlen(path);	char		*dir;	if (!NSE_STREQ(mnt->mnt_type, "tfs")) {		return;	}	if (tfs_major_dev == 0 && stat(mnt->mnt_dir, &statb) == 0) {		tfs_major_dev = statb.st_dev >> 8;	}	if (0 == strncmp(mnt->mnt_dir, path, len) &&	    mnt->mnt_dir[len] == '/') {		dir = mnt->mnt_dir + len + 1;		while (*dir == '/') {			dir++;		}		(void) nse_list_add_new_copy(subdir_list, dir);	}}Nse_errbuild_subdirs(subdir, dir)	char		*subdir;	char		*dir;{	char		path[MAXPATHLEN];	strcpy(path, dir);	nse_pathcat(path, subdir);	return make_directory(path);}/* * Set searchlinks from the directory 'from' to the directory 'to', so * that when 'from' is TFS-mounted, the tfsd will be able to follow the * searchlinks to make it appear to the user that the contents of 'from' * are overlaid over the contents of 'to'.  Recursively set searchlinks * for all sub-directories of 'from' which have matching sub-directories * under 'to'.  'backmost' is TRUE if 'to' is the layer furthest in back * (i.e. the directory being mounted on.) */Nse_errbuild_searchlinks(from, to, backmost)	char		*from;	char		*to;	bool_t		backmost;{	char		dir[MAXPATHLEN];	char		searchlink[MAXPATHLEN];	char		*str;	Nse_err		err;	/*	 * First make sure that the directory is writeable, so that we can	 * print a decent error message if it isn't.  (If the directory isn't	 * writeable, then we won't be able to write .tfs_info to set	 * searchlinks.)  The directory will be unwriteable if either the	 * user doesn't have write permissions for the directory or the	 * directory is in a filesystem that was mounted read-only.	 */	strcpy(dir, from);	nse_pathcat(dir, ".tfs_tmp");	if (open(dir, O_RDWR | O_CREAT, 0666) < 0) {		err = nse_err_alloc_rec(errno, &str);		sprintf(str, "%s is not writeable", from);		return err;	}	if (unlink(dir) < 0) {		fprintf(stderr, "%s: Warning: can't unlink %s\n",			nse_get_cmdname(), dir);	}	strcpy(dir, from);	strcpy(searchlink, to);	return recursive_set_searchlinks(dir, searchlink, backmost);}Nse_errrecursive_set_searchlinks(path, searchlink, backmost)	char		*path;	char		*searchlink;{	DIR		*dirp;	struct direct	*dp;	struct stat	statb;	char		*curname;	Nse_err		err;	dirp = opendir(path);	if (dirp == NULL) {		return nse_err_format_errno("Opendir of '%s'\n", path);	}	while (dp = readdir(dirp)) {		if (NSE_STREQ(dp->d_name, ".") ||		    NSE_STREQ(dp->d_name, "..") ||		    0 == strncmp(dp->d_name, NSE_TFS_FILE_PREFIX,				 NSE_TFS_FILE_PREFIX_LEN)) {			continue;		}		nse_pathcat(path, dp->d_name);		if (lstat(path, &statb) < 0) {			closedir(dirp);			return nse_err_format_errno("Lstat of '%s'\n", path);		}		if (NSE_ISDIR(&statb)) {			nse_pathcat(searchlink, dp->d_name);			closedir(dirp);			if (err = recursive_set_searchlinks(path,							    searchlink,							    backmost)) {				return err;			}			curname = rindex(path, '/');			*curname++ = '\0';			*rindex(searchlink, '/') = '\0';			dirp = opendir(path);			if (dirp == NULL) {				return nse_err_format_errno(						"Opendir of '%s'\n", path);			}			/*			 * Pick up where we left off.			 */			while (dp = readdir(dirp)) {				if (NSE_STREQ(curname, dp->d_name)) {					break;				}			}		} else {			*rindex(path, '/') = '\0';		}	}	closedir(dirp);	return set_searchlink(path, searchlink, backmost);}/* * Sets searchlink of directory 'path' to point to directory 'back_path'. * Doesn't set searchlink if 'back_path' is a non-existent directory. */Nse_errset_searchlink(path, back_path, backmost)	char		*path;	char		*back_path;	bool_t		backmost;{	struct stat	statb;	char		old_slink[MAXPATHLEN];	char		back_slink[MAXPATHLEN];	char		*searchlink = back_path;	bool_t		ok_to_set;	bool_t		is_tfs_dir;	int		euid;	Nse_err		err;	if ((err = nse_get_searchlink(path, old_slink)) &&	    err->code != ENOENT) {		return err;	}	ok_to_set = (stat(back_path, &statb) == 0 && NSE_ISDIR(&statb));	if (ok_to_set && backmost) {		/*		 * Determine if the directory in back is under an existing		 * TFS mount.  (TFS mounts have a fixed major dev #.)		 */		is_tfs_dir = ((statb.st_dev >> 8) == tfs_major_dev);		if (is_tfs_dir) {			/*			 * If we're doing a TFS mount over an existing TFS			 * mount, then the searchlink should be set to the			 * tfsd's current frontmost layer for this dir,			 * which is the name returned by nse_tfs_getname().			 * Make the RPC call to the tfsd as root, not as			 * the current effective user, so that the RPC			 * client handle can be used by root later to send			 * the TFS_MOUNT request to the tfsd.			 */			euid = geteuid();			setreuid(0, 0);			setregid(0, 0);			err = nse_tfs_getname(TFSD_ENV_NAME, back_path,					      back_slink);			setregid(0, group_of_user(euid));			setreuid(0, euid);			if (err) {				if (err->code == NSE_TFS_NOT_UNDER_MOUNTPT) {					is_tfs_dir = FALSE;				} else {					return err;				}			}		}		if (!is_tfs_dir) {			/*			 * Searchlink to backmost directory points to			 * /tmp_mnt/Tfs_native/'back_path'.  (See header			 * comments.)			 */			strcpy(back_slink, tfs_loopback_dir);			strcat(back_slink, back_path);			/*			 * If backmost directory contains a .tfs_info file,			 * remove it (otherwise, if there is a searchlink			 * in the .tfs_info, then there will be another			 * directory in back of the 'backmost' directory.)			 */			nse_pathcat(back_path, NSE_TFS_FILE);			if (stat(back_path, &statb) == 0) {				(void) unlink(back_path);			}			*rindex(back_path, '/') = '\0';		}		searchlink = back_slink;	}	if (!ok_to_set) {		if (old_slink[0] != '\0' &&		    (err = nse_set_searchlink(path, ""))) {			return err;		}		return NULL;	}	if (NSE_STREQ(searchlink, old_slink)) {		return NULL;	}	return nse_set_searchlink(path, searchlink);}Nse_errmake_directory(dir)	char		*dir;{	char		*cp;	Nse_err		err;	if (access(dir, 0) == 0) {		return NULL;	}	cp = rindex(dir, '/');	*cp = '\0';	if (err = make_directory(dir)) {		return err;	}	*cp = '/';	if (mkdir(dir, 0775) < 0) {		return nse_err_format_errno("Mkdir of '%s'\n", dir);	}	return NULL;}voidunmount_all(mtab_list)	Nse_list	mtab_list;{	struct mntent	*mnt;	Nse_listelem	elem;	Nse_listelem	end;	NSE_LIST_ITERATE_REV(mtab_list, struct mntent *, mnt, elem, end) {		if (unmount(mnt->mnt_dir) < 0) {			fprintf(stderr, "%s: Warning: can't unmount '%s': ",				nse_get_cmdname(), mnt->mnt_dir);			perror("");		}	}}intgroup_of_user(uid)	int		uid;{	struct passwd	*pwd;	static int	last_uid;	static int	last_gid;	if (uid == last_uid) {		return last_gid;	}	pwd = getpwuid(uid);	if (pwd) {		last_uid = uid;		last_gid = pwd->pw_gid;		return pwd->pw_gid;	} else {		last_uid = 0;		last_gid = 0;		return 0;	}}char *str_copy(str)	char		*str;{	char		*str2;	if (str != NULL) {		str2 = NSE_STRDUP(str);		return(str2);	}	return(NULL);}/* * Ops vector for elements of a string list. */static	Nse_listops_rec string_ops= {	NULL,	str_copy,	(Nse_voidfunc) free,	NULL,	(Nse_boolfunc) _nse_streq_func,};/* * Create and return a string list. */Nse_listnse_stringlist_create(){	Nse_list	list;	list = nse_list_alloc(&string_ops);	return list;}options(argcp, argvp)	int *argcp;	char ***argvp;{	char		*opts;	int		argc;	char		**argv;	argc = *argcp;	argv = *argvp;	while (argc && **argv == '-') {		opts = &argv[0][1];		switch (*opts) {		case 'r':			read_only = TRUE;			break;		default:			usage();			/* NOTREACHED */		}		argv++;		argc--;	}	*argcp = argc;	*argvp = argv;	return (0);}usage(){	fprintf(stderr, "Usage: %s [-r] fs1 fs2 ... fsN dir\n",		nse_get_cmdname());	exit(1);}

⌨️ 快捷键说明

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