mountd.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,539 行 · 第 1/5 页

C
2,539
字号
			   if export is not in kernel's exportfsdata, add it 			*/			if (k_ptr == NULL) {#ifdef DEBUG_FULL				(void) fprintf(stderr, "Adding new export %s to kernel\n", ex2->ex_name);#endif DEBUG_FULL 				extokex(ex2, &kbuf);				if ((exportfs(EXPORTFS_CREATE, NULL, &kbuf)) < 0) {					syslog(LOG_ERR, "exportfs CREATE of %s: %m", kbuf.e_path);					exit (1);				}			}			/*			 * if kernel's exportfsdata struct is not uptodate, replace it 			 */			else if (!(ex_same(k_ptr, ex2))) {#ifdef DEBUG_FULL				(void) fprintf(stderr, "Fixing kernel export %s\n", ex2->ex_name);#endif DEBUG_FULL 				extokex(k_ptr, &kbuf);				if ((exportfs (EXPORTFS_REMOVE, NULL, &kbuf))< 0) {					syslog(LOG_ERR, "exportfs REMOVE of %s: %m", kbuf.e_path);					exit (1);				}				extokex(ex2, &kbuf);				if ((exportfs(EXPORTFS_CREATE, NULL, &kbuf)) < 0) {					syslog(LOG_ERR, "exportfs CREATE(2) of %s: %m", kbuf.e_path);					exit (1);				}				k_ptr->ex_name= "CHECKED";			}			else k_ptr->ex_name= "CHECKED";		}	}	/*	 * Loop through k_ex list looking for entries that need to be 	 * removed from kernel's exportfsdata list.	 */	for (k_ptr=k_ex; k_ptr!=NULL; k_ptr=k_ptr->ex_next) {		if (strcmp(k_ptr->ex_name, "CHECKED") != 0) {#ifdef DEBUG_FULL			(void)fprintf(stderr,"Removing kernel export %s\n", k_ptr->ex_name);#endif DEBUG_FULL 			extokex(k_ptr, &kbuf);			if ((exportfs (EXPORTFS_REMOVE, NULL, &kbuf)) < 0) {				syslog(LOG_ERR, "exportfs REMOVE(2) of %s: %m", kbuf.e_path);				exit (1);			}		}	}	freeex(k_ex);#ifdef DEBUG_FULL 	(void) fprintf (stderr, "*** Kernel exportfsdata after changes ***\n");	cookie = 0;	for (;;) {		if ((exportfs (EXPORTFS_READ, &cookie, &kbuf)) < 0) {			syslog(LOG_ERR, "exportfs READ(2): %m");			exit (1);		}		(void)fprintf(stderr,"export name %s", kbuf.e_path);		(void)fprintf(stderr,"-r=%d  dev: %d  ino: %d", kbuf.e_rootmap, kbuf.e_fsid, kbuf.e_gnum);		if (kbuf.e_flags & M_EXRONLY)			(void)fprintf(stderr," (M_EXRONLY)");		(void)fprintf(stderr, "\n");		if (kbuf.e_more == 0) break;	}	(void)fprintf(stderr, "\n");#endif DEBUG_FULL}/* * Compare kernel's export entry to mountd's */ex_same (k_ex, ex)	struct exports *k_ex, *ex;{	if ((k_ex->ex_rootmap!=ex->ex_rootmap) || (k_ex->ex_flags!=ex->ex_flags) ||		(k_ex->ex_ino != ex->ex_ino) || (k_ex->ex_gen != ex->ex_gen) || 		(k_ex->ex_dev != ex->ex_dev))		return (FALSE);	return (TRUE);}newdev (name, dev, ino, gen)	char *name;	dev_t dev;	ino_t ino;	u_long gen;{	struct exports *new;	char *newname;	new = (struct exports *)exmalloc(sizeof(*new));	newname = (char *)exmalloc(strlen(name) + 1);	(void) strcpy(newname, name);	new->ex_name = newname;	new->ex_dev = dev;	new->ex_ino = ino;	new->ex_gen = gen;	new->ex_next = NULL;	new->ex_rootmap = -2;		/* Initialize to nobody */	new->ex_flags = 0;	new->ex_groups = NULL;		/* Groups ptr */	new->ex_devptr = exports;	exports = new;}struct exports *newex(name, next, dev, ino, gen, rootmap, flags)	char *name;	struct exports *next;	dev_t dev;	ino_t ino;	u_long gen;	short rootmap;	u_int flags;{	struct exports *new;	char *newname;	new = (struct exports *)exmalloc(sizeof(*new));	newname = (char *)exmalloc(strlen(name) + 1);	(void) strcpy(newname, name);	new->ex_name = newname;	new->ex_dev = dev;	new->ex_ino = ino;	new->ex_gen = gen;	new->ex_rootmap = rootmap;	new->ex_flags = flags;	new->ex_next = next;	new->ex_groups = NULL;		/* Groups ptr */	new->ex_devptr = NULL;	return (new);}extokex(ex, kex)	struct exports *ex;	struct exportfsdata *kex;{	(void)strcpy (kex->e_path, ex->ex_name);	kex->e_fsid = ex->ex_dev;	kex->e_gnum = ex->ex_ino;	kex->e_gen = ex->ex_gen;	kex->e_rootmap = ex->ex_rootmap;	kex->e_flags = ex->ex_flags;	kex->e_more = 0;}struct groups *newgroup(name, next)	char *name;	struct groups *next;{	struct groups *new;	char *newname;	new = (struct groups *)exmalloc(sizeof(*new));	newname = (char *)exmalloc(strlen(name) + 1);	(void) strcpy(newname, name);	new->g_name = newname;	new->g_next = next;	new->g_hbit = 0;	return (new);}setopt(str, ex)	char *str;	struct exports *ex;{	char *m, *n;	/*	 * Parse options	 */	switch (str[0]) {	case 'r':		/*		 * If r, then set root mapping field		 */		m = str;		m++;		if (*m != '=') {			syslog(LOG_ERR, "%s bad export option format in %s", str, EXPORTS);			return;		}		else {			m++;			if (*m == '-')				n = ++m;			else				n = m;			for (; !n ; n++)				if (!isdigit(*n)) {					/*		 		 	 * Bad string		 		 	 */					syslog(LOG_ERR, "%c unknown root mapping integer in %s", *m, EXPORTS);					return;				}			ex->ex_rootmap = atoi(m);		}		break;	case 'n':		/*		 * if n, ignore (no filehandle obsolete)		 */		break;	case 'o':		/*		 * if o, set flags field for readonly		 */		ex->ex_flags |= M_EXRONLY;		break;	default:		/*		 * Bad option		 */		syslog(LOG_ERR, "%c unknown export option in %s", str[0], EXPORTS);		break;	}	return;}/* * Flatten exports list to show directory entries. */flatten_exports(){	struct exports *ex, *ex2;	struct exports *exnew = NULL;	struct groups *groups;	struct groups *groupsnew = NULL;#ifdef DEBUG_FULL	(void) fprintf(stderr, "\n******* Flattening exports: *******\n");#endif DEBUG_FULL	for (ex = exports; ex != NULL; ex = ex->ex_devptr) {		for (ex2 = ex; ex2 != NULL; ex2 = ex2->ex_next) {#ifdef DEBUG_FULL			(void) fprintf(stderr, "making newex for %s\n", ex2->ex_name);#endif DEBUG_FULL			exnew = newex(ex2->ex_name, exnew, NULL, NULL, NULL, NULL, NULL);			for (groups = ex2->ex_groups, groupsnew = NULL; groups != NULL; groups = groups->g_next) {#ifdef DEBUG_FULL				(void) fprintf(stderr, "making newgroup for %s\n", groups->g_name);#endif DEBUG_FULL				groupsnew = newgroup(groups->g_name, groupsnew);			}			exnew->ex_groups = groupsnew;		}	}	flatexports = exnew;}char *exmalloc(size)	int size;{	char *ret;	if ((ret = (char *)malloc((unsigned) size)) == 0) {		syslog(LOG_ERR, "Memory allocation failed in exmalloc: %m");		exit(1);	}	return (ret);}/* * Free entire ex list */freeex(ex)	struct exports *ex;{	struct exports *next_ex, *next_dev;	struct groups *group_ptr, *next_group;	while (ex) {		next_dev = ex->ex_devptr;		while (ex) {			next_ex = ex->ex_next;			group_ptr = ex->ex_groups;			while (group_ptr) {				next_group = group_ptr->g_next;				free (group_ptr->g_name);				free ((char *)group_ptr);				group_ptr = next_group;			}			free (ex->ex_name);			free ((char *)ex);			ex = next_ex;		}		ex = next_dev;	}}#ifdef DEBUGprint_exports(ex)	struct exports *ex;{	struct groups *groups;	struct exports *ex2;	(void) fprintf(stderr, "\nexport list begin:\n");	for (; ex != NULL; ex = ex->ex_devptr) {		for (ex2 = ex; ex2 != NULL; ex2 = ex2->ex_next) {			(void) fprintf(stderr, "fs or dir: %s dev: %x", 				ex2->ex_name, ex2->ex_dev);			(void) fprintf(stderr, " -r=%d ", ex2->ex_rootmap);			if (ex2->ex_flags & M_EXRONLY)				(void) fprintf(stderr, " ( M_EXRONLY )");			(void) fprintf(stderr, "\n\tdev: %d, ino: %d", ex2->ex_dev, ex2->ex_ino);			for (groups= ex2->ex_groups; groups!= NULL; groups= groups->g_next)				(void) fprintf(stderr, " %s, hbit: %d", 					groups->g_name, groups->g_hbit);			(void) fprintf(stderr, "\n");		}		(void) fprintf(stderr, "finish exports for this dev\n");	}	(void) fprintf(stderr, "export list end:\n\n");}#endif DEBUGusage(){	(void) fprintf(stderr,"usage: mountd [-i -d -s]\n");	(void) fflush(stderr);	exit(1);}mtd_abort(){	/*	 * This routine is a do-nothing to replace the libc abort, to prevent	 * mountd from crashing all the time.  It is safe to remove this stub	 * if running under inetd, since inetd will just restart us when we	 * crash and the core dumps may be useful.	 */}/* * Restore saved mount state; rewrite file without commented out * entries */rmtab_load(){        char *path;        char *name;        char *end;        struct mountdlist *ml;        char line[MAXRMTABLINELEN];	int fd;        f = fopen(RMTAB, "r");        if (f != NULL) {                while (fgets(line, sizeof(line), f) != NULL) {                        name = line;                        path = strchr(name, ':');                        if (*name != '#' && path != NULL) {                                *path = 0;                                path++;                                end = strchr(path, '\n');                                if (end != NULL) {                                        *end = 0;                                }                                ml = (struct mountdlist *)                                        exmalloc(sizeof(struct mountdlist));                                ml->ml_path = (char *)                                        exmalloc(strlen(path) + 1);                                (void)strcpy(ml->ml_path, path);                                 ml->ml_name = (char *)                                        exmalloc(strlen(name) + 1);                                (void)strcpy(ml->ml_name, name);                                ml->ml_nxt = mountlist;                                mountlist = ml;                        }                }                (void)fclose(f);        }	fd = open(RMTAB, O_CREAT|O_TRUNC|O_RDWR, 0644);	f = fdopen(fd, "r+");        if (f != NULL) {                for (ml = mountlist; ml != NULL; ml = ml->ml_nxt) {                        ml->ml_pos = rmtab_insert(ml->ml_name, ml->ml_path);                }		return(fd);        }	return(-1);}longrmtab_insert(name, path)        char *name;        char *path;{        long pos;        if (f == NULL || fseek(f, 0L, 2) == -1) {                return (-1);        }        pos = ftell(f);        if (fprintf(f, "%s:%s\n", name, path) == EOF) {                return (-1);        }	fflush(f);        return (pos);}rmtab_delete(pos)        long pos;{        if (f != NULL && pos != -1 && fseek(f, pos, 0) == 0) {                (void) fprintf(f, "#");                fflush(f);	}}build_ngcache(){	int err, i;	struct ypall_callback cbinfo;	cbinfo.foreach = getkeys;	cbinfo.data = NULL;	err = yp_all(mydomain, "netgroup", &cbinfo);	if (err) {		if (err != YPERR_MAP)			syslog(LOG_ERR, "YP error building netgroup cache: %s",				yperr_string(err));		return;	}	for (i=0; i< num_ngs; i++) {		(void)expand_ng(ng_names[i]);		free(ng_names[i]);	}	}/* * Called for each netgroup in yp database.  Returns 0 to have yp_all * call it again to process the next netgroup. */static intgetkeys(status, key, kl, val, vl, data)	int status;	char *key;	int kl;	char *val;	int vl;	char *data;{	int size;	if (status == YP_TRUE) {		size = kl + 1;		ng_names[num_ngs] = (char *)malloc((unsigned) size);		strncpy(ng_names[num_ngs], key, kl);		ng_names[num_ngs++][kl] = '\0';		/*		 * initial cache size is limited to 100 netgroups		 */		if (num_ngs == 100)  			return(1);		return(0);	}	if (status != YP_NOMORE)		syslog(LOG_ERR, "YP error expanding netgroups: %s",			yperr_string(ypprot_err(status)));	return(1);}intexpand_ng(ngname)	char *ngname;{	char *machp, *userp, *domainp;	int is_a_ng=0;	setnetgrent(ngname);	while (getnetgrent(&machp, &userp, &domainp)) {		if (is_a_ng++ == 0)  			new_ng(ngname);		if ((domainp == NULL) || (strcmp(domainp, mydomain) == 0)) {			if (machp == NULL) {				new_ng_host("everyone");				break;			}			else if (isalnum(*machp) || (*machp == '_'))				new_ng_host(machp);		}	}	endnetgrent();#ifdef DEBUG	(void)fprintf(stderr,"Expand ng of %s returning %d\n", ngname, is_a_ng);#endif DEBUG	return(is_a_ng);

⌨️ 快捷键说明

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