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

📄 searchfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		free(q->pat);	q->pat = nil;}char *quicksearch(Quick *q, char *s, char *e){	char *pat, *up, *m, *ee;	uchar *j;	int len, n, c, mc;	len = q->len;	if(len < 0)		return s;	j = q->jump;	pat = q->pat;	up = q->up;	s += len;	ee = e - (len * 4 + 4);	while(s < e){		/*		 * look for a match on the last char		 */		while(s < ee && (n = j[(uchar)*s])){			s += n;			s += j[(uchar)*s];			s += j[(uchar)*s];			s += j[(uchar)*s];		}		if(s >= e)			return nil;		while(n = j[(uchar)*s]){			s += n;			if(s >= e)				return nil;		}		/*		 * does the string match?		 */		m = s - len;		for(n = 0; c = pat[n]; n++){			mc = *m++;			if(c != mc && mc != up[n])				break;		}		if(!c)			return s - len;		s += q->miss;	}	return nil;}voidfsrun(Fs *fs, int fd){	Fcall rpc;	char *err;	uchar *buf;	int n;	buf = emalloc(messagesize);	for(;;){		/*		 * reading from a pipe or a network device		 * will give an error after a few eof reads		 * however, we cannot tell the difference		 * between a zero-length read and an interrupt		 * on the processes writing to us,		 * so we wait for the error		 */		n = read9pmsg(fd, buf, messagesize);		if(n == 0)			continue;		if(n < 0)			fatal("mount read");		rpc.data = (char*)buf + IOHDRSZ;		if(convM2S(buf, n, &rpc) == 0)			continue;		// fprint(2, "recv: %F\n", &rpc);		/*		 * flushes are way too hard.		 * a reply to the original message seems to work		 */		if(rpc.type == Tflush)			continue;		else if(rpc.type >= Tmax || !fcalls[rpc.type])			err = "bad fcall type";		else			err = (*fcalls[rpc.type])(fs, &rpc);		if(err){			rpc.type = Rerror;			rpc.ename = err;		}else			rpc.type++;		n = convS2M(&rpc, buf, messagesize);		// fprint(2, "send: %F\n", &rpc);		if(write(fd, buf, n) != n)			fatal("mount write");	}}Fid*mkfid(Fs *fs, uint fid){	Fid *f;	int h;	h = fid % Nfidhash;	for(f = fs->hash[h]; f; f = f->next){		if(f->fid == fid)			return nil;	}	f = emalloc(sizeof *f);	f->next = fs->hash[h];	if(f->next != nil)		f->next->last = &f->next;	f->last = &fs->hash[h];	fs->hash[h] = f;	f->fid = fid;	f->ref = 1;	f->attached = 1;	f->open = 0;	return f;}Fid*getfid(Fs *fs, uint fid){	Fid *f;	int h;	h = fid % Nfidhash;	for(f = fs->hash[h]; f; f = f->next){		if(f->fid == fid){			if(f->attached == 0)				break;			f->ref++;			return f;		}	}	return nil;}voidputfid(Fs *, Fid *f){	f->ref--;	if(f->ref == 0 && f->attached == 0){		*f->last = f->next;		if(f->next != nil)			f->next->last = f->last;		if(f->search != nil)			searchfree(f->search);		free(f);	}}char*fsversion(Fs *, Fcall *rpc){	if(rpc->msize < 256)		return "version: message size too small";	if(rpc->msize > messagesize)		rpc->msize = messagesize;	messagesize = rpc->msize;	if(strncmp(rpc->version, "9P2000", 6) != 0)		return "unrecognized 9P version";	rpc->version = "9P2000";	return nil;}char*fsauth(Fs *, Fcall *){	return "searchfs: authentication not required";}char*fsattach(Fs *fs, Fcall *rpc){	Fid *f;	f = mkfid(fs, rpc->fid);	if(f == nil)		return Einuse;	f->open = 0;	f->qid.type = QTDIR;	f->qid.path = Qroot;	f->qid.vers = 0;	rpc->qid = f->qid;	putfid(fs, f);	return nil;}char*fswalk(Fs *fs, Fcall *rpc){	Fid *f, *nf;	int nqid, nwname, type;	char *err, *name;	ulong path;	f = getfid(fs, rpc->fid);	if(f == nil)		return Enofid;	nf = nil;	if(rpc->fid != rpc->newfid){		nf = mkfid(fs, rpc->newfid);		if(nf == nil){			putfid(fs, f);			return Einuse;		}		nf->qid = f->qid;		putfid(fs, f);		f = nf;	/* walk f */	}	err = nil;	path = f->qid.path;	nwname = rpc->nwname;	for(nqid=0; nqid<nwname; nqid++){		if(path != Qroot){			err = Enotdir;			break;		}		name = rpc->wname[nqid];		if(strcmp(name, "search") == 0){			type = QTFILE;			path = Qsearch;		}else if(strcmp(name, "stats") == 0){			type = QTFILE;			path = Qstats;		}else if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0){			type = QTDIR;			path = path;		}else{			err = Enotexist;			break;		}		rpc->wqid[nqid] = (Qid){path, 0, type};	}	if(nwname > 0){		if(nf != nil && nqid < nwname)			nf->attached = 0;		if(nqid == nwname)			f->qid = rpc->wqid[nqid-1];	}	putfid(fs, f);	rpc->nwqid = nqid;	f->open = 0;	return err;}char *fsopen(Fs *fs, Fcall *rpc){	Fid *f;	int mode;	f = getfid(fs, rpc->fid);	if(f == nil)		return Enofid;	if(f->open){		putfid(fs, f);		return Eisopen;	}	mode = rpc->mode & OPERM;	if(mode == OEXEC	|| f->qid.path == Qroot && (mode == OWRITE || mode == ORDWR)){		putfid(fs, f);		return Eperm;	}	f->open = 1;	f->where = nil;	f->n = 0;	f->search = nil;	rpc->qid = f->qid;	rpc->iounit = messagesize-IOHDRSZ;	putfid(fs, f);	return nil;}char *fscreate(Fs *, Fcall *){	return Eperm;}char*fsread(Fs *fs, Fcall *rpc){	Fid *f;	int n, off, count, len;	f = getfid(fs, rpc->fid);	if(f == nil)		return Enofid;	if(!f->open){		putfid(fs, f);		return Enotopen;	}	count = rpc->count;	off = rpc->offset;	rpc->count = 0;	if(f->qid.path == Qroot){		if(off > 0)			rpc->count = 0;		else			rpc->count = dostat(Qsearch, (uchar*)rpc->data, count);		putfid(fs, f);		if(off == 0 && rpc->count <= BIT16SZ)			return "directory read count too small";		return nil;	}	if(f->qid.path == Qstats){		len = 0;	}else{		for(len = 0; len < count; len += n){			if(f->where == nil || f->search == nil)				break;			if(f->n == 0)				f->where = searchsearch(f->search, f->where, edatabase, &f->n);			n = f->n;			if(n != 0){				if(n > count-len)					n = count-len;				memmove(rpc->data+len, f->where, n);				f->where += n;				f->n -= n;			}		}	}	putfid(fs, f);	rpc->count = len;	return nil;}char*fswrite(Fs *fs, Fcall *rpc){	Fid *f;	f = getfid(fs, rpc->fid);	if(f == nil)		return Enofid;	if(!f->open || f->qid.path != Qsearch){		putfid(fs, f);		return Enotopen;	}	if(f->search != nil)		searchfree(f->search);	f->search = searchparse(rpc->data, rpc->data + rpc->count);	if(f->search == nil){		putfid(fs, f);		return Ebadsearch;	}	f->where = database;	f->n = 0;	putfid(fs, f);	return nil;}char *fsclunk(Fs *fs, Fcall *rpc){	Fid *f;	f = getfid(fs, rpc->fid);	if(f != nil){		f->attached = 0;		putfid(fs, f);	}	return nil;}char *fsremove(Fs *, Fcall *){	return Eperm;}char *fsstat(Fs *fs, Fcall *rpc){	Fid *f;	f = getfid(fs, rpc->fid);	if(f == nil)		return Enofid;	rpc->stat = fs->statbuf;	rpc->nstat = dostat(f->qid.path, rpc->stat, sizeof fs->statbuf);	putfid(fs, f);	if(rpc->nstat <= BIT16SZ)		return "stat count too small";	return nil;}char *fswstat(Fs *, Fcall *){	return Eperm;}intdostat(int path, uchar *buf, int nbuf){	Dir d;	switch(path){	case Qroot:		d.name = ".";		d.mode = DMDIR|0555;		d.qid.type = QTDIR;		break;	case Qsearch:		d.name = "search";		d.mode = 0666;		d.qid.type = QTFILE;		break;	case Qstats:		d.name = "stats";		d.mode = 0666;		d.qid.type = QTFILE;		break;	}	d.qid.path = path;	d.qid.vers = 0;	d.length = 0;	d.uid = d.gid = d.muid = "none";	d.atime = d.mtime = time(nil);	return convD2M(&d, buf, nbuf);}char *urlunesc(char *s, char *e){	char *t, *v;	int c, n;	v = emalloc((e - s) + 1);	for(t = v; s < e; s++){		c = *s;		if(c == '%'){			if(s + 2 >= e)				break;			n = s[1];			if(n >= '0' && n <= '9')				n = n - '0';			else if(n >= 'A' && n <= 'F')				n = n - 'A' + 10;			else if(n >= 'a' && n <= 'f')				n = n - 'a' + 10;			else				break;			c = n;			n = s[2];			if(n >= '0' && n <= '9')				n = n - '0';			else if(n >= 'A' && n <= 'F')				n = n - 'A' + 10;			else if(n >= 'a' && n <= 'f')				n = n - 'a' + 10;			else				break;			s += 2;			c = c * 16 + n;		}		*t++ = c;	}	*t = 0;	return v;}inttoupper(int c){	if(c >= 'a' && c <= 'z')		c += 'A' - 'a';	return c;}inttolower(int c){	if(c >= 'A' && c <= 'Z')		c += 'a' - 'A';	return c;}voidfatal(char *fmt, ...){	va_list arg;	char buf[1024];	write(2, "searchfs: ", 8);	va_start(arg, fmt);	vseprint(buf, buf+1024, fmt, arg);	va_end(arg);	write(2, buf, strlen(buf));	write(2, "\n", 1);	exits(fmt);}void *emalloc(uint n){	void *p;	p = malloc(n);	if(p == nil)		fatal("out of memory");	memset(p, 0, n);	return p;}voidusage(void){	fprint(2, "usage: searchfs [-m mountpoint] [-s srvfile] database\n");	exits("usage");}

⌨️ 快捷键说明

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