📄 searchfs.c
字号:
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 + -