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

📄 symtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
voidmoveentry(ep, newname)	register struct entry *ep;	char *newname;{	struct entry *np;	char *cp;	np = lookupparent(newname);	if (np == NULL)		badentry(ep, "cannot move ROOT");	if (np != ep->e_parent) {		removeentry(ep);		ep->e_parent = np;		ep->e_sibling = np->e_entries;		np->e_entries = ep;	}	cp = rindex(newname, '/') + 1;	freename(ep->e_name);	ep->e_name = savename(cp);	ep->e_namlen = strlen(cp);	if (strcmp(gentempname(ep), ep->e_name) == 0)		ep->e_flags |= TMPNAME;	else		ep->e_flags &= ~TMPNAME;}/* * Remove an entry in the tree structure */static voidremoveentry(ep)	register struct entry *ep;{	register struct entry *np;	np = ep->e_parent;	if (np->e_entries == ep) {		np->e_entries = ep->e_sibling;	} else {		for (np = np->e_entries; np != NULL; np = np->e_sibling) {			if (np->e_sibling == ep) {				np->e_sibling = ep->e_sibling;				break;			}		}		if (np == NULL)			badentry(ep, "cannot find entry in parent list");	}}/* * Table of unused string entries, sorted by length. *  * Entries are allocated in STRTBLINCR sized pieces so that names * of similar lengths can use the same entry. The value of STRTBLINCR * is chosen so that every entry has at least enough space to hold * a "struct strtbl" header. Thus every entry can be linked onto an * apprpriate free list. * * NB. The macro "allocsize" below assumes that "struct strhdr" *     has a size that is a power of two. */struct strhdr {	struct strhdr *next;};#define STRTBLINCR	(sizeof(struct strhdr))#define allocsize(size)	(((size) + 1 + STRTBLINCR - 1) & ~(STRTBLINCR - 1))static struct strhdr strtblhdr[allocsize(NAME_MAX) / STRTBLINCR];/* * Allocate space for a name. It first looks to see if it already * has an appropriate sized entry, and if not allocates a new one. */char *savename(name)	char *name;{	struct strhdr *np;	long len;	char *cp;	if (name == NULL)		panic("bad name\n");	len = strlen(name);	np = strtblhdr[len / STRTBLINCR].next;	if (np != NULL) {		strtblhdr[len / STRTBLINCR].next = np->next;		cp = (char *)np;	} else {		cp = malloc((unsigned)allocsize(len));		if (cp == NULL)			panic("no space for string table\n");	}	(void) strcpy(cp, name);	return (cp);}/* * Free space for a name. The resulting entry is linked onto the * appropriate free list. */voidfreename(name)	char *name;{	struct strhdr *tp, *np;		tp = &strtblhdr[strlen(name) / STRTBLINCR];	np = (struct strhdr *)name;	np->next = tp->next;	tp->next = np;}/* * Useful quantities placed at the end of a dumped symbol table. */struct symtableheader {	long	volno;	long	stringsize;	long	entrytblsize;	time_t	dumptime;	time_t	dumpdate;	ino_t	maxino;	long	ntrec;};/* * dump a snapshot of the symbol table */voiddumpsymtable(filename, checkpt)	char *filename;	long checkpt;{	register struct entry *ep, *tep;	register ino_t i;	struct entry temp, *tentry;	long mynum = 1, stroff = 0;	FILE *fd;	struct symtableheader hdr;	vprintf(stdout, "Check pointing the restore\n");	if (Nflag)		return;	if ((fd = fopen(filename, "w")) == NULL) {		fprintf(stderr, "fopen: %s\n", strerror(errno));		panic("cannot create save file %s for symbol table\n",			filename);	}	clearerr(fd);	/*	 * Assign indicies to each entry	 * Write out the string entries	 */	for (i = ROOTINO; i < maxino; i++) {		for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {			ep->e_index = mynum++;			(void) fwrite(ep->e_name, sizeof(char),			       (int)allocsize(ep->e_namlen), fd);		}	}	/*	 * Convert pointers to indexes, and output	 */	tep = &temp;	stroff = 0;	for (i = ROOTINO; i < maxino; i++) {		for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {			bcopy((char *)ep, (char *)tep,				(long)sizeof(struct entry));			tep->e_name = (char *)stroff;			stroff += allocsize(ep->e_namlen);			tep->e_parent = (struct entry *)ep->e_parent->e_index;			if (ep->e_links != NULL)				tep->e_links =					(struct entry *)ep->e_links->e_index;			if (ep->e_sibling != NULL)				tep->e_sibling =					(struct entry *)ep->e_sibling->e_index;			if (ep->e_entries != NULL)				tep->e_entries =					(struct entry *)ep->e_entries->e_index;			if (ep->e_next != NULL)				tep->e_next =					(struct entry *)ep->e_next->e_index;			(void) fwrite((char *)tep, sizeof(struct entry), 1, fd);		}	}	/*	 * Convert entry pointers to indexes, and output	 */	for (i = 0; i < entrytblsize; i++) {		if (entry[i] == NULL)			tentry = NULL;		else			tentry = (struct entry *)entry[i]->e_index;		(void) fwrite((char *)&tentry, sizeof(struct entry *), 1, fd);	}	hdr.volno = checkpt;	hdr.maxino = maxino;	hdr.entrytblsize = entrytblsize;	hdr.stringsize = stroff;	hdr.dumptime = dumptime;	hdr.dumpdate = dumpdate;	hdr.ntrec = ntrec;	(void) fwrite((char *)&hdr, sizeof(struct symtableheader), 1, fd);	if (ferror(fd)) {		fprintf(stderr, "fwrite: %s\n", strerror(errno));		panic("output error to file %s writing symbol table\n",			filename);	}	(void) fclose(fd);}/* * Initialize a symbol table from a file */voidinitsymtable(filename)	char *filename;{	char *base;	long tblsize;	register struct entry *ep;	struct entry *baseep, *lep;	struct symtableheader hdr;	struct stat stbuf;	register long i;	int fd;	vprintf(stdout, "Initialize symbol table.\n");	if (filename == NULL) {		entrytblsize = maxino / HASHFACTOR;		entry = (struct entry **)			calloc((unsigned)entrytblsize, sizeof(struct entry *));		if (entry == (struct entry **)NULL)			panic("no memory for entry table\n");		ep = addentry(".", ROOTINO, NODE);		ep->e_flags |= NEW;		return;	}	if ((fd = open(filename, O_RDONLY, 0)) < 0) {		fprintf(stderr, "open: %s\n", strerror(errno));		panic("cannot open symbol table file %s\n", filename);	}	if (fstat(fd, &stbuf) < 0) {		fprintf(stderr, "stat: %s\n", strerror(errno));		panic("cannot stat symbol table file %s\n", filename);	}	tblsize = stbuf.st_size - sizeof(struct symtableheader);	base = calloc(sizeof(char), (unsigned)tblsize);	if (base == NULL)		panic("cannot allocate space for symbol table\n");	if (read(fd, base, (int)tblsize) < 0 ||	    read(fd, (char *)&hdr, sizeof(struct symtableheader)) < 0) {		fprintf(stderr, "read: %s\n", strerror(errno));		panic("cannot read symbol table file %s\n", filename);	}	switch (command) {	case 'r':		/*		 * For normal continuation, insure that we are using		 * the next incremental tape		 */		if (hdr.dumpdate != dumptime) {			if (hdr.dumpdate < dumptime)				fprintf(stderr, "Incremental tape too low\n");			else				fprintf(stderr, "Incremental tape too high\n");			done(1);		}		break;	case 'R':		/*		 * For restart, insure that we are using the same tape		 */		curfile.action = SKIP;		dumptime = hdr.dumptime;		dumpdate = hdr.dumpdate;		if (!bflag)			newtapebuf(hdr.ntrec);		getvol(hdr.volno);		break;	default:		panic("initsymtable called from command %c\n", command);		break;	}	maxino = hdr.maxino;	entrytblsize = hdr.entrytblsize;	entry = (struct entry **)		(base + tblsize - (entrytblsize * sizeof(struct entry *)));	baseep = (struct entry *)(base + hdr.stringsize - sizeof(struct entry));	lep = (struct entry *)entry;	for (i = 0; i < entrytblsize; i++) {		if (entry[i] == NULL)			continue;		entry[i] = &baseep[(long)entry[i]];	}	for (ep = &baseep[1]; ep < lep; ep++) {		ep->e_name = base + (long)ep->e_name;		ep->e_parent = &baseep[(long)ep->e_parent];		if (ep->e_sibling != NULL)			ep->e_sibling = &baseep[(long)ep->e_sibling];		if (ep->e_links != NULL)			ep->e_links = &baseep[(long)ep->e_links];		if (ep->e_entries != NULL)			ep->e_entries = &baseep[(long)ep->e_entries];		if (ep->e_next != NULL)			ep->e_next = &baseep[(long)ep->e_next];	}}

⌨️ 快捷键说明

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