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

📄 dosfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		if(*from >= 'a' && *from <= 'z')			*to = *from + 'A' - 'a';		else			*to = *from;	}	to = ext;	for(; *from && to-ext < 3; from++, to++){		if(*from >= 'a' && *from <= 'z')			*to = *from + 'A' - 'a';		else			*to = *from;	}	chat("name is %8.8s %3.3s\n", name, ext);}/* *  walk a directory returns * 	-1 if something went wrong *	 0 if not found *	 1 if found */static intdoswalk(Dosfile *fp, char *name){	char dname[8], dext[3];	Clustbuf *p;	Dosdir *dp;	Off o, addr;	if((fp->attr & DOSDIR) == 0){		chat("walking non-directory!\n");		return -1;	}	setname(dname, dext, name);	fp->offset = 0;	/* start at the beginning */	for(;;){		addr = fileaddr(fp, fp->offset/fp->dos->sectbytes, 0);		if(addr < 0)			return 0;		p = getclust(fp->dos, addr);		if(p == 0)			return -1;		for(o=0; o<p->size; o += sizeof(Dosdir)){			dp = (Dosdir *)(p->iobuf + o);			chat("comparing to %8.8s.%3.3s\n", (char*)dp->name, (char*)dp->ext);			if(memcmp(dname, dp->name, sizeof(dp->name)) != 0)				continue;			if(memcmp(dext, dp->ext, sizeof(dp->ext)) == 0)				goto Found;		}		fp->offset += p->size;		putclust(p);	}Found:	fp->pdir = p->sector;	fp->odir = o;	putclust(p);	memmove(fp->name, dname, sizeof(fp->name));	memmove(fp->ext, dext, sizeof(fp->ext));	fp->attr = dp->attr;	fp->length = GLONG(dp->length);	fp->pstart = GSHORT(dp->start);	fp->pcurrent = 0;	fp->lcurrent = 0;	fp->offset = 0;	return 1;}static voidbootdump(Dosboot *b){	if(chatty == 0)		return;	print("magic: 0x%2.2x 0x%2.2x 0x%2.2x\n",		b->magic[0], b->magic[1], b->magic[2]);	print("version: \"%8.8s\"\n", (char*)b->version);	print("sectbytes: %d\n", GSHORT(b->sectbytes));	print("allocsize: %d\n", b->clustsize);	print("nresrv: %d\n", GSHORT(b->nresrv));	print("nfats: %d\n", b->nfats);	print("rootsize: %d\n", GSHORT(b->rootsize));	print("volsize: %d\n", GSHORT(b->volsize));	print("mediadesc: 0x%2.2x\n", b->mediadesc);	print("fatsize: %d\n", GSHORT(b->fatsize));	print("trksize: %d\n", GSHORT(b->trksize));	print("nheads: %d\n", GSHORT(b->nheads));	print("nhidden: %d\n", GLONG(b->nhidden));	print("bigvolsize: %d\n", GLONG(b->bigvolsize));	print("driveno: %d\n", b->driveno);	print("reserved0: 0x%2.2x\n", b->reserved0);	print("bootsig: 0x%2.2x\n", b->bootsig);	print("volid: 0x%8.8x\n", GLONG(b->volid));	print("label: \"%11.11s\"\n", (char*)b->label);}/* *  instructions that boot blocks can start with */#define	JMPSHORT	0xeb#define JMPNEAR		0xe9/* *  read dos file system properties */intdosinit(Dos *dos){	Clustbuf *p;	Dospart *dp;	Dosboot *b;	int i;	/* defaults till we know better */	dos->start = 0;	dos->sectbytes = 512;	dos->clustsize = 1;	dos->clustbytes = 512;	/* get first sector */	p = getclust(dos, 0);	if(p == 0){		chat("can't read boot block\n");		return -1;	}	p->dos = 0;	/* if a hard disk format, look for an active partition */	b = (Dosboot *)p->iobuf;	if(b->magic[0] != JMPNEAR && (b->magic[0] != JMPSHORT || b->magic[2] != 0x90)){		if(p->iobuf[0x1fe] != 0x55 || p->iobuf[0x1ff] != 0xaa){			print("no dos file system or partition table\n");			putclust(p);			return -1;		}		dp = (Dospart*)&p->iobuf[0x1be];		for(i = 0; i < 4; i++, dp++)			if(dp->type && dp->flag == 0x80)				break;		if(i == 4){			putclust(p);			return -1;		}		dos->start = GLONG(dp->start);		putclust(p);		p = getclust(dos, 0);		if(p == 0){			chat("can't read boot block\n");			putclust(p);			return -1;		}		p->dos = 0;	}	b = (Dosboot *)p->iobuf;	if(b->magic[0] != JMPNEAR && (b->magic[0] != JMPSHORT || b->magic[2] != 0x90)){		print("no dos file system\n");		putclust(p);		return -1;	}	if(chatty)		bootdump(b);/**/	/*	 *  determine the systems' wondersous properties	 */	dos->sectbytes = GSHORT(b->sectbytes);	dos->clustsize = b->clustsize;	dos->clustbytes = dos->sectbytes*dos->clustsize;	dos->nresrv = GSHORT(b->nresrv);	dos->nfats = b->nfats;	dos->rootsize = GSHORT(b->rootsize);	dos->volsize = GSHORT(b->volsize);	if(dos->volsize == 0)		dos->volsize = GLONG(b->bigvolsize);	dos->mediadesc = b->mediadesc;	dos->fatsize = GSHORT(b->fatsize);	dos->fatbytes = dos->sectbytes*dos->fatsize;	dos->fataddr = dos->nresrv;	dos->rootaddr = dos->fataddr + dos->nfats*dos->fatsize;	i = dos->rootsize*sizeof(Dosdir) + dos->sectbytes - 1;	i = i/dos->sectbytes;	dos->dataaddr = dos->rootaddr + i;	dos->fatclusters = 2+(dos->volsize - dos->dataaddr)/dos->clustsize;	if(dos->fatclusters < 4087)		dos->fatbits = 12;	else		dos->fatbits = 16;	dos->freeptr = 2;	putclust(p);	/*	 *  set up the root	 */	dos->root.dos = dos;	dos->root.pdir = 0;	dos->root.odir = 0;	memmove(dos->root.name, "<root>  ", 8);	memmove(dos->root.ext, "   ", 3);	dos->root.attr = DOSDIR;	dos->root.length = dos->rootsize*sizeof(Dosdir);	dos->root.pstart = 0;	dos->root.lcurrent = 0;	dos->root.pcurrent = 0;	dos->root.offset = 0;	syncclust();	return 0;}static char *nextelem(char *path, char *elem){	int i;	while(*path == '/')		path++;	if(*path==0 || *path==' ')		return 0;	for(i=0; *path && *path != '/' && *path != ' '; i++){		if(i >= NAMELEN){			print("name component too long\n");			return 0;		}		*elem++ = *path++;	}	*elem = 0;	return path;}static voidputtime(Dosdir *d){	Timet secs;	Rtc rtc;	ushort x;	secs = rtctime();	sec2rtc(secs, &rtc);	x = (rtc.hour<<11) | (rtc.min<<5) | (rtc.sec>>1);	d->time[0] = x;	d->time[1] = x>>8;	x = ((rtc.year-80)<<9) | ((rtc.mon+1)<<5) | rtc.mday;	d->date[0] = x;	d->date[1] = x>>8;}Dosfile*dosopen(Dos *dos, char *path, Dosfile *fp){	char element[NAMELEN];	*fp = dos->root;	while(path = nextelem(path, element)){		switch(doswalk(fp, element)){		case -1:			print("error walking to %s\n", element);			return 0;		case 0:			print("%s not found\n", element);			return 0;		case 1:			print("found %s attr 0x%ux start 0x%llux len %lld\n",				element, fp->attr, (Wideoff)fp->pstart,				(Wideoff)fp->length);			break;		}	}	syncclust();	return fp;}/* *  read from a dos file */longdosread(Dosfile *fp, void *a, long n){	Off addr, k, o;	Clustbuf *p;	uchar *to;	if((fp->attr & DOSDIR) == 0){		if(fp->offset >= fp->length)			return 0;		if(fp->offset+n > fp->length)			n = fp->length - fp->offset;	}	to = a;	while(n > 0){		/*		 *  read the data; sectors below dos->dataaddr		 *  are read one at a time.		 */		addr = fileaddr(fp, fp->offset/fp->dos->sectbytes, 0);		if(addr < 0)			return -1;		p = getclust(fp->dos, addr);		if(p == 0)			return -1;		/*		 *  copy the bytes we need		 */		o = fp->offset % p->size;		k = p->size - o;		if(k > n)			k = n;		memmove(to, p->iobuf+o, k);		putclust(p);		to += k;		fp->offset += k;		n -= k;	}	syncclust();	return to - (uchar *)a;}/* *  write to a dos file */longdoswrite(Dosfile *fp, void *a, long n){	Off blksize, addr, k, o;	Clustbuf *p, *pdir;	Dosdir *dp;	uchar *from;	if(fp->attr & DOSDIR){		print("write dir\n");		return -1;	}	if(fp->pdir){		pdir = getclust(fp->dos, fp->pdir);		/*		 *  should do consistency check if		 *  concurrent access is possible.		 */		if(pdir == 0)			panic("doswrite");	}else		pdir = 0;	blksize = pdir ? fp->dos->clustbytes : fp->dos->sectbytes;	from = a;	while(n > 0){		addr = fileaddr(fp, fp->offset/fp->dos->sectbytes, pdir);		if(addr < 0)			return -1;		o = fp->offset % blksize;		if(o == 0 && n >= blksize)			p = getclustz(fp->dos, addr);		else			p = getclust(fp->dos, addr);		if(p == 0)			return -1;		/*		 *  copy the bytes we need		 */		k = p->size - o;		if(k > n)			k = n;		memmove(p->iobuf+o, from, k);		p->flags |= MOD;		putclust(p);		from += k;		fp->offset += k;		n -= k;	}	if(pdir){		dp = (Dosdir *)(pdir->iobuf + fp->odir);		puttime(dp);		if(fp->offset > fp->length){			fp->length = fp->offset;			dp->length[0] = fp->length;			dp->length[1] = fp->length>>8;			dp->length[2] = fp->length>>16;			dp->length[3] = fp->length>>24;		}		pdir->flags |= MOD;		putclust(pdir);	}	syncclust();	return from - (uchar *)a;}/* *  truncate a dos file to zero length */intdostrunc(Dosfile *fp){	Clustbuf *pdir;	Dosdir *dp;	Off p, np;	if(fp->attr & DOSDIR){		print("trunc dir\n");		return -1;	}	pdir = getclust(fp->dos, fp->pdir);	if(pdir == 0)		panic("dostrunc");	p = fatwalk(fp->dos, fp->pstart);	fatwrite(fp->dos, fp->pstart, 0xffff);	while(p >= 0){		np = fatwalk(fp->dos, p);		fatwrite(fp->dos, p, 0);		p = np;	}	fp->length = 0;	dp = (Dosdir *)(pdir->iobuf + fp->odir);	puttime(dp);	dp->length[0] = 0;	dp->length[1] = 0;	dp->length[2] = 0;	dp->length[3] = 0;	pdir->flags |= MOD;	putclust(pdir);	syncclust();	return 0;}

⌨️ 快捷键说明

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