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

📄 archfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * archfs - mount mkfs style archives */#include <u.h>#include <libc.h>#include <bio.h>#include <auth.h>#include <fcall.h>#include <thread.h>#include <9p.h>Tree *archtree;Biobuf *b;int verbose;typedef struct Ahdr Ahdr;struct Ahdr {	char *name;	Dir;};typedef struct Arch Arch;struct Arch {	vlong off;	vlong length;};static void*emalloc(long sz){	void *v;	v = malloc(sz);	if(v == nil)		sysfatal("malloc %lud fails\n", sz);	memset(v, 0, sz);	return v;}static char*estrdup(char *s){	s = strdup(s);	if(s == nil)		sysfatal("strdup (%.10s) fails\n", s);	return s;}static char*Bgetline(Biobuf *b){	char *p;	if(p = Brdline(b, '\n'))		p[Blinelen(b)-1] = '\0';	return p;}Ahdr*gethdr(Biobuf *b){	Ahdr *a;	char *p, *f[10];	if((p = Bgetline(b)) == nil)		return nil;	if(strcmp(p, "end of archive") == 0) {		werrstr("");		return nil;	}	if(tokenize(p, f, nelem(f)) != 6) {		werrstr("bad format");		return nil;	}	a = emalloc(sizeof(*a));	a->name = estrdup(f[0]);	a->mode = strtoul(f[1], 0, 8);	a->uid = estrdup(f[2]);	a->gid = estrdup(f[3]);	a->mtime = strtoll(f[4], 0, 10);	a->length = strtoll(f[5], 0, 10);	return a;}static Arch*newarch(vlong off, vlong length){	static Arch *abuf;	static int nabuf;	if(nabuf == 0) {		nabuf = 256;		abuf = emalloc(sizeof(Arch)*nabuf);	}	nabuf--;	abuf->off = off;	abuf->length = length;	return abuf++;}static File*createpath(File *f, char *name, char *u, ulong m){	char *p;	File *nf;	if(verbose)		fprint(2, "createpath %s\n", name);	incref(f);	while(f && (p = strchr(name, '/'))) {		*p = '\0';		if(strcmp(name, "") != 0 && strcmp(name, ".") != 0){			/* this would be a race if we were multithreaded */			incref(f);	/* so walk doesn't kill it immediately on failure */			if((nf = walkfile(f, name)) == nil)				nf = createfile(f, name, u, DMDIR|0777, nil);			decref(f);			f = nf;		}		*p = '/';		name = p+1;	}	if(f == nil)		return nil;	incref(f);	if((nf = walkfile(f, name)) == nil)		nf = createfile(f, name, u, m, nil);	decref(f);	return nf;}static voidarchcreatefile(char *name, Arch *arch, Dir *d){	File *f;	f = createpath(archtree->root, name, d->uid, d->mode);	if(f == nil)		sysfatal("creating %s: %r", name);	free(f->gid);	f->gid = estrdup9p(d->gid);	f->aux = arch;	f->mtime = d->mtime;	f->length = d->length;	decref(f);}static voidfsread(Req *r){	Arch *a;	char err[ERRMAX];	int n;	a = r->fid->file->aux;	if(a->length <= r->ifcall.offset) 		r->ifcall.count = 0;	else if(a->length <= r->ifcall.offset+r->ifcall.count)		r->ifcall.count = a->length - r->ifcall.offset;	werrstr("unknown error");	if(Bseek(b, a->off+r->ifcall.offset, 0) < 0 	|| (n = Bread(b, r->ofcall.data, r->ifcall.count)) < 0) {		err[0] = '\0';		errstr(err, sizeof err);		respond(r, err);	} else {		r->ofcall.count = n;		respond(r, nil);		}}Srv fs = {	.read=	fsread,};static voidusage(void){	fprint(2, "usage: archfs [-abcC] [-m mtpt] archfile\n");	exits("usage");}voidmain(int argc, char **argv){	Ahdr *a;	ulong flag;	char *mtpt;	char err[ERRMAX];	flag = 0;	mtpt = "/mnt/arch";	ARGBEGIN{	case 'D':		chatty9p++;		break;	case 'a':		flag |= MAFTER;		break;	case 'b':		flag |= MBEFORE;		break;	case 'c':		flag |= MCREATE;		break;	case 'C':		flag |= MCACHE;		break;	case 'm':		mtpt = EARGF(usage());		break;	default:		usage();		break;	}ARGEND;	if(argc != 1)		usage();	if((b = Bopen(argv[0], OREAD)) == nil)		sysfatal("open '%s': %r", argv[0]);	archtree = fs.tree = alloctree("sys", "sys", DMDIR|0775, nil);	while(a = gethdr(b)) {		archcreatefile(a->name, newarch(Boffset(b), a->length), a);		Bseek(b, a->length, 1);	}	err[0] = '\0';	errstr(err, sizeof err);	if(err[0])		sysfatal("reading archive: %s", err);	postmountsrv(&fs, nil, mtpt, flag);	exits(0);}

⌨️ 快捷键说明

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