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

📄 mntgen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <fcall.h>#include <thread.h>#include <9p.h>#include <mp.h>#include <libsec.h>static voidusage(void){	fprint(2, "mntgen [-s srvname] [mtpt]\n");	exits("usage");}ulong time0;typedef struct Tab Tab;struct Tab{	char *name;	vlong qid;	ulong time;	int ref;};Tab *tab;int ntab;int mtab;static Tab*findtab(vlong path){	int i;	for(i=0; i<ntab; i++)		if(tab[i].qid == path)			return &tab[i];	return nil;}static vlonghash(char *name){	vlong digest[MD5dlen / sizeof(vlong) + 1];	md5((uchar *)name, strlen(name), (uchar *)digest, nil);	return digest[0] & ((1ULL<<48)-1);}static voidfsopen(Req *r){	if(r->ifcall.mode != OREAD)		respond(r, "permission denied");	else		respond(r, nil);}static intdirgen(int i, Dir *d, void*){	if(i >= ntab)		return -1;	memset(d, 0, sizeof *d);	d->qid.type = QTDIR;	d->uid = estrdup9p("sys");	d->gid = estrdup9p("sys");	d->mode = DMDIR|0555;	d->length = 0;	if(i == -1){		d->name = estrdup9p("/");		d->atime = d->mtime = time0;	}else{		d->qid.path = tab[i].qid;		d->name = estrdup9p(tab[i].name);		d->atime = d->mtime = tab[i].time;	}	return 0;}static voidfsread(Req *r){	if(r->fid->qid.path == 0)		dirread9p(r, dirgen, nil);	else		r->ofcall.count = 0;	respond(r, nil);}static voidfsstat(Req *r){	Tab *t;	vlong qid;	qid = r->fid->qid.path;	if(qid == 0)		dirgen(-1, &r->d, nil);	else{		if((t = findtab(qid)) == nil){			respond(r, "path not found (???)");			return;		}		dirgen(t-tab, &r->d, nil);	}	respond(r, nil);}static char*fswalk1(Fid *fid, char *name, void*){	int i;	Tab *t;	vlong h;	if(fid->qid.path != 0){		/* nothing in child directory */		if(strcmp(name, "..") == 0){			if((t = findtab(fid->qid.path)) != nil)				t->ref--;			fid->qid.path = 0;			return nil;		}		return "path not found";	}	/* root */	if(strcmp(name, "..") == 0)		return nil;	for(i=0; i<ntab; i++)		if(strcmp(tab[i].name, name) == 0){			tab[i].ref++;			fid->qid.path = tab[i].qid;			return nil;		}	h = hash(name);	if(findtab(h) != nil)		return "hash collision";	/* create it */	if(ntab == mtab){		if(mtab == 0)			mtab = 16;		else			mtab *= 2;		tab = erealloc9p(tab, sizeof(tab[0])*mtab);	}	tab[ntab].qid = h;	fid->qid.path = tab[ntab].qid;	tab[ntab].name = estrdup9p(name);	tab[ntab].time = time(0);	tab[ntab].ref = 1;	ntab++;	return nil;}static char*fsclone(Fid *fid, Fid*, void*){	Tab *t;	if((t = findtab(fid->qid.path)) != nil)		t->ref++;	return nil;}static voidfswalk(Req *r){	walkandclone(r, fswalk1, fsclone, nil);}static voidfsclunk(Fid *fid){	Tab *t;	vlong qid;	qid = fid->qid.path;	if(qid == 0)		return;	if((t = findtab(qid)) == nil){		fprint(2, "warning: cannot find %llux\n", qid);		return;	}	if(--t->ref == 0){		free(t->name);		tab[t-tab] = tab[--ntab];	}else if(t->ref < 0)		fprint(2, "warning: negative ref count for %s\n", t->name);}static voidfsattach(Req *r){	char *spec;	spec = r->ifcall.aname;	if(spec && spec[0]){		respond(r, "invalid attach specifier");		return;	}		r->ofcall.qid = (Qid){0, 0, QTDIR};	r->fid->qid = r->ofcall.qid;	respond(r, nil);}Srv fs={.attach=	fsattach,.open=	fsopen,.read=	fsread,.stat=	fsstat,.walk=	fswalk,.destroyfid=	fsclunk};voidmain(int argc, char **argv){	char *service;	time0 = time(0);	service = nil;	ARGBEGIN{	case 'D':		chatty9p++;		break;	case 's':		service = EARGF(usage());		break;	default:		usage();	}ARGEND	if(argc > 1)		usage();	postmountsrv(&fs, service, argc ? argv[0] : "/n", MAFTER);	exits(nil);}

⌨️ 快捷键说明

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