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

📄 9660srv.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <auth.h>#include <fcall.h>#include "dat.h"#include "fns.h"#include "iso9660.h"static void	ireset(void);static int	iattach(Xfile*);static void	iclone(Xfile*, Xfile*);static void	iwalkup(Xfile*);static void	iwalk(Xfile*, char*);static void	iopen(Xfile*, int);static void	icreate(Xfile*, char*, long, int);static long	ireaddir(Xfile*, uchar*, long, long);static long	iread(Xfile*, char*, long, long);static long	iwrite(Xfile*, char*, long, long);static void	iclunk(Xfile*);static void	iremove(Xfile*);static void	istat(Xfile*, Dir*);static void	iwstat(Xfile*, Dir*);static char*	nstr(uchar*, int);static char*	rdate(uchar*, int);static int	getcontin(Xdata*, uchar*, uchar**);static int	getdrec(Xfile*, void*);static void	ungetdrec(Xfile*);static int	opendotdot(Xfile*, Xfile*);static int	showdrec(int, int, void*);static long	gtime(uchar*);static long	l16(void*);static long	l32(void*);static void	newdrec(Xfile*, Drec*);static int	rzdir(Xfs*, Dir*, int, Drec*);Xfsub	isosub ={	ireset, iattach, iclone, iwalkup, iwalk, iopen, icreate,	ireaddir, iread, iwrite, iclunk, iremove, istat, iwstat};static voidireset(void){}static intiattach(Xfile *root){	Xfs *cd = root->xf;	Iobuf *p; Voldesc *v; Isofile *fp; Drec *dp;	int fmt, blksize, i, n, l, haveplan9;	Iobuf *dirp;	uchar dbuf[256];	Drec *rd = (Drec *)dbuf;	uchar *q, *s;	dirp = nil;	blksize = 0;	fmt = 0;	dp = nil;	haveplan9 = 0;	for(i=VOLDESC;i<VOLDESC+100; i++){	/* +100 for sanity */		p = getbuf(cd->d, i);		v = (Voldesc*)(p->iobuf);		if(memcmp(v->byte, "\01CD001\01", 7) == 0){		/* iso */			if(dirp)				putbuf(dirp);			dirp = p;			fmt = 'z';			dp = (Drec*)v->z.desc.rootdir;			blksize = l16(v->z.desc.blksize);			chat("iso, blksize=%d...", blksize);			v = (Voldesc*)(dirp->iobuf);			haveplan9 = (strncmp((char*)v->z.boot.sysid, "PLAN 9", 6)==0);			if(haveplan9){				if(noplan9) {					chat("ignoring plan9");					haveplan9 = 0;				} else {					fmt = '9';					chat("plan9 iso...");				}			}			continue;		}		if(memcmp(&v->byte[8], "\01CDROM\01", 7) == 0){	/* high sierra */			if(dirp)				putbuf(dirp);			dirp = p;			fmt = 'r';			dp = (Drec*)v->r.desc.rootdir;			blksize = l16(v->r.desc.blksize);			chat("high sierra, blksize=%d...", blksize);			continue;		}		if(haveplan9==0 && !nojoliet		&& memcmp(v->byte, "\02CD001\01", 7) == 0){chat("%d %d\n", haveplan9, nojoliet);			/*			 * The right thing to do is walk the escape sequences looking			 * for one of 25 2F 4[035], but Microsoft seems to not honor			 * the format, which makes it hard to walk over.			 */			q = v->z.desc.escapes;			if(q[0] == 0x25 && q[1] == 0x2F && (q[2] == 0x40 || q[2] == 0x43 || q[2] == 0x45)){	/* Joliet, it appears */				if(dirp)					putbuf(dirp);				dirp = p;				fmt = 'J';				dp = (Drec*)v->z.desc.rootdir;				if(blksize != l16(v->z.desc.blksize))					fprint(2, "warning: suspicious Joliet blocksize\n");				chat("joliet...");				continue;			}		}		putbuf(p);		if(v->byte[0] == 0xFF)			break;	}	if(fmt == 0){		if(dirp)			putbuf(dirp);		return -1;	}	assert(dirp != nil);	if(chatty)		showdrec(2, fmt, dp);	if(blksize > Sectorsize){		chat("blksize too big...");		putbuf(dirp);		return -1;	}	if(waserror()){		putbuf(dirp);		nexterror();	}	root->len = sizeof(Isofile) - sizeof(Drec) + dp->reclen;	root->ptr = fp = ealloc(root->len);	if(haveplan9)		root->xf->isplan9 = 1;	fp->fmt = fmt;	fp->blksize = blksize;	fp->offset = 0;	fp->doffset = 0;	memmove(&fp->d, dp, dp->reclen);	root->qid.path = l32(dp->addr);	root->qid.type = QTDIR;	putbuf(dirp);	poperror();	if(getdrec(root, rd) >= 0){		n = rd->reclen-(34+rd->namelen);		s = (uchar*)rd->name + rd->namelen;		if((uintptr)s & 1){			s++;			n--;		}		if(n >= 7 && s[0] == 'S' && s[1] == 'P' && s[2] == 7 &&		   s[3] == 1 && s[4] == 0xBE && s[5] == 0xEF){			root->xf->issusp = 1;			root->xf->suspoff = s[6];			n -= root->xf->suspoff;			s += root->xf->suspoff;			for(; n >= 4; s += l, n -= l){				l = s[2];				if(s[0] == 'E' && s[1] == 'R'){					if(!norock && s[4] == 10 && memcmp(s+8, "RRIP_1991A", 10) == 0)						root->xf->isrock = 1;					break;				} else if(s[0] == 'C' && s[1] == 'E' && s[2] >= 28){					n = getcontin(root->xf->d, s, &s);					continue;				} else if(s[0] == 'R' && s[1] == 'R'){					if(!norock)						root->xf->isrock = 1;					break;				} else if(s[0] == 'S' && s[1] == 'T')					break;			}		}	}	if(root->xf->isrock)		chat("Rock Ridge...");	fp->offset = 0;	fp->doffset = 0;	return 0;}static voidiclone(Xfile *of, Xfile *nf){	USED(of, nf);}static voidiwalkup(Xfile *f){	long paddr;	uchar dbuf[256];	Drec *d = (Drec *)dbuf;	Xfile pf, ppf;	Isofile piso, ppiso;	memset(&pf, 0, sizeof pf);	memset(&ppf, 0, sizeof ppf);	pf.ptr = &piso;	ppf.ptr = &ppiso;	if(opendotdot(f, &pf) < 0)		error("can't open pf");	paddr = l32(pf.ptr->d.addr);	if(l32(f->ptr->d.addr) == paddr)		return;	if(opendotdot(&pf, &ppf) < 0)		error("can't open ppf");	while(getdrec(&ppf, d) >= 0){		if(l32(d->addr) == paddr){			newdrec(f, d);			f->qid.path = paddr;			f->qid.type = QTDIR;			return;		}	}	error("can't find addr of ..");}static intcasestrcmp(int isplan9, char *a, char *b){	int ca, cb;	if(isplan9)		return strcmp(a, b);	for(;;) {		ca = *a++;		cb = *b++;		if(ca >= 'A' && ca <= 'Z')			ca += 'a' - 'A';		if(cb >= 'A' && cb <= 'Z')			cb += 'a' - 'A';		if(ca != cb) {			if(ca > cb)				return 1;			return -1;		}		if(ca == 0)			return 0;	}}static voidiwalk(Xfile *f, char *name){	Isofile *ip = f->ptr;	uchar dbuf[256];	char nbuf[4*Maxname];	Drec *d = (Drec*)dbuf;	Dir dir;	char *p;	int len, vers, dvers;	vers = -1;	if(p = strchr(name, ';')) {	/* assign = */		len = p-name;		if(len >= Maxname)			len = Maxname-1;		memmove(nbuf, name, len);		vers = strtoul(p+1, 0, 10);		name = nbuf;	}/*	len = strlen(name);	if(len >= Maxname){		len = Maxname-1;		if(name != nbuf){			memmove(nbuf, name, len);			name = nbuf;		}		name[len] = 0;	}*/	chat("%d \"%s\"...", strlen(name), name);	ip->offset = 0;	setnames(&dir, nbuf);	while(getdrec(f, d) >= 0) {		dvers = rzdir(f->xf, &dir, ip->fmt, d);		if(casestrcmp(f->xf->isplan9||f->xf->isrock, name, dir.name) != 0)			continue;		newdrec(f, d);		f->qid.path = dir.qid.path;		f->qid.type = dir.qid.type;		USED(dvers);		return;	}	USED(vers);	error(Enonexist);}static voidiopen(Xfile *f, int mode){	mode &= ~OCEXEC;	if(mode != OREAD && mode != OEXEC)		error(Eperm);	f->ptr->offset = 0;	f->ptr->doffset = 0;}static voidicreate(Xfile *f, char *name, long perm, int mode){	USED(f, name, perm, mode);	error(Eperm);}static longireaddir(Xfile *f, uchar *buf, long offset, long count){	Isofile *ip = f->ptr;	Dir d;	char names[4*Maxname];	uchar dbuf[256];	Drec *drec = (Drec *)dbuf;	int n, rcnt;	if(offset==0){		ip->offset = 0;		ip->doffset = 0;	}else if(offset != ip->doffset)		error("seek in directory not allowed");	rcnt = 0;	setnames(&d, names);	while(rcnt < count && getdrec(f, drec) >= 0){		if(drec->namelen == 1){			if(drec->name[0] == 0)				continue;			if(drec->name[0] == 1)				continue;		}		rzdir(f->xf, &d, ip->fmt, drec);		d.qid.vers = f->qid.vers;		if((n = convD2M(&d, buf+rcnt, count-rcnt)) <= BIT16SZ){			ungetdrec(f);			break;		}		rcnt += n;	}	ip->doffset += rcnt;	return rcnt;}static longiread(Xfile *f, char *buf, long offset, long count){	Isofile *ip = f->ptr;	long size, addr, o, n;	int rcnt = 0;	Iobuf *p;	size = l32(ip->d.size);	if(offset >= size)		return 0;	if(offset+count > size)		count = size - offset;	addr = (l32(ip->d.addr)+ip->d.attrlen)*ip->blksize + offset;	o = (ulong)addr % Sectorsize;	addr = (ulong)addr / Sectorsize;	/*chat("d.addr=0x%x, addr=0x%x, o=0x%x...", l32(ip->d.addr), addr, o);*/	n = Sectorsize - o;	while(count > 0){		if(n > count)			n = count;		p = getbuf(f->xf->d, addr);		memmove(&buf[rcnt], &p->iobuf[o], n);		putbuf(p);		count -= n;		rcnt += n;		++addr;		o = 0;		n = Sectorsize;	}	return rcnt;}static longiwrite(Xfile *f, char *buf, long offset, long count){	USED(f, buf, offset, count);	error(Eperm);	return 0;}static voidiclunk(Xfile *f){	USED(f);}static voidiremove(Xfile *f){	USED(f);	error(Eperm);}static voidistat(Xfile *f, Dir *d){	Isofile *ip = f->ptr;	rzdir(f->xf, d, ip->fmt, &ip->d);	d->qid.vers = f->qid.vers;	if(d->qid.path==f->xf->rootqid.path){		d->qid.path = 0;		d->qid.type = QTDIR;	}}static voidiwstat(Xfile *f, Dir *d){	USED(f, d);	error(Eperm);}static intshowdrec(int fd, int fmt, void *x){	Drec *d = (Drec *)x;	int namelen;	int syslen;

⌨️ 快捷键说明

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