📄 cs.c
字号:
{ int mode; char *err; err = 0; mode = job->request.mode; if(mf->qid.type & QTDIR){ if(mode) err = "permission denied"; } job->reply.qid = mf->qid; job->reply.iounit = 0; sendmsg(job, err);}voidrcreate(Job *job, Mfile *mf){ USED(mf); sendmsg(job, "creation permission denied");}voidrread(Job *job, Mfile *mf){ int i, n, cnt; long off, toff, clock; Dir dir; uchar buf[Maxfdata]; char *err; n = 0; err = 0; off = job->request.offset; cnt = job->request.count; if(mf->qid.type & QTDIR){ clock = time(0); if(off == 0){ dir.name = "cs"; dir.qid.type = QTFILE; dir.qid.vers = vers; dir.qid.path = Qcs; dir.mode = 0666; dir.length = 0; dir.uid = mf->user; dir.gid = mf->user; dir.muid = mf->user; dir.atime = clock; /* wrong */ dir.mtime = clock; /* wrong */ n = convD2M(&dir, buf, sizeof buf); } job->reply.data = (char*)buf; } else { for(;;){ /* look for an answer at the right offset */ toff = 0; for(i = 0; mf->reply[i] && i < mf->nreply; i++){ n = mf->replylen[i]; if(off < toff + n) break; toff += n; } if(i < mf->nreply) break; /* got something to return */ /* try looking up more answers */ if(lookup(mf) == 0){ /* no more */ n = 0; goto send; } } /* give back a single reply (or part of one) */ job->reply.data = mf->reply[i] + (off - toff); if(cnt > toff - off + n) n = toff - off + n; else n = cnt; }send: job->reply.count = n; sendmsg(job, err);}voidcleanmf(Mfile *mf){ int i; if(mf->net != nil){ free(mf->net); mf->net = nil; } if(mf->host != nil){ free(mf->host); mf->host = nil; } if(mf->serv != nil){ free(mf->serv); mf->serv = nil; } if(mf->rem != nil){ free(mf->rem); mf->rem = nil; } for(i = 0; i < mf->nreply; i++){ free(mf->reply[i]); mf->reply[i] = nil; mf->replylen[i] = 0; } mf->nreply = 0; mf->nextnet = netlist;}voidrwrite(Job *job, Mfile *mf){ int cnt, n; char *err; char *field[4]; char curerr[64]; err = 0; cnt = job->request.count; if(mf->qid.type & QTDIR){ err = "can't write directory"; goto send; } if(cnt >= Maxrequest){ err = "request too long"; goto send; } job->request.data[cnt] = 0; /* * toggle debugging */ if(strncmp(job->request.data, "debug", 5)==0){ debug ^= 1; syslog(1, logfile, "debug %d", debug); goto send; } /* * toggle debugging */ if(strncmp(job->request.data, "paranoia", 8)==0){ paranoia ^= 1; syslog(1, logfile, "paranoia %d", paranoia); goto send; } /* * add networks to the default list */ if(strncmp(job->request.data, "add ", 4)==0){ if(job->request.data[cnt-1] == '\n') job->request.data[cnt-1] = 0; netadd(job->request.data+4); readipinterfaces(); goto send; } /* * refresh all state */ if(strncmp(job->request.data, "refresh", 7)==0){ netinit(1); goto send; } /* start transaction with a clean slate */ cleanmf(mf); /* * look for a general query */ if(*job->request.data == '!'){ err = genquery(mf, job->request.data+1); goto send; } if(debug) syslog(0, logfile, "write %s", job->request.data); if(paranoia) syslog(0, paranoiafile, "write %s by %s", job->request.data, mf->user); /* * break up name */ n = getfields(job->request.data, field, 4, 1, "!"); switch(n){ case 1: mf->net = strdup("net"); mf->host = strdup(field[0]); break; case 4: mf->rem = strdup(field[3]); /* fall through */ case 3: mf->serv = strdup(field[2]); /* fall through */ case 2: mf->host = strdup(field[1]); mf->net = strdup(field[0]); break; } /* * do the first net worth of lookup */ if(lookup(mf) == 0){ rerrstr(curerr, sizeof curerr); err = curerr; }send: job->reply.count = cnt; sendmsg(job, err);}voidrclunk(Job *job, Mfile *mf){ cleanmf(mf); free(mf->user); mf->user = 0; mf->busy = 0; mf->fid = 0; sendmsg(job, 0);}voidrremove(Job *job, Mfile *mf){ USED(mf); sendmsg(job, "remove permission denied");}voidrstat(Job *job, Mfile *mf){ Dir dir; uchar buf[IOHDRSZ+Maxfdata]; if(mf->qid.type & QTDIR){ dir.name = "."; dir.mode = DMDIR|0555; } else { dir.name = "cs"; dir.mode = 0666; } dir.qid = mf->qid; dir.length = 0; dir.uid = mf->user; dir.gid = mf->user; dir.muid = mf->user; dir.atime = dir.mtime = time(0); job->reply.nstat = convD2M(&dir, buf, sizeof buf); job->reply.stat = buf; sendmsg(job, 0);}voidrwstat(Job *job, Mfile *mf){ USED(mf); sendmsg(job, "wstat permission denied");}voidsendmsg(Job *job, char *err){ int n; uchar mdata[IOHDRSZ + Maxfdata]; char ename[ERRMAX]; if(err){ job->reply.type = Rerror; snprint(ename, sizeof(ename), "cs: %s", err); job->reply.ename = ename; }else{ job->reply.type = job->request.type+1; } job->reply.tag = job->request.tag; n = convS2M(&job->reply, mdata, sizeof mdata); if(n == 0){ syslog(1, logfile, "sendmsg convS2M of %F returns 0", &job->reply); abort(); } lock(&joblock); if(job->flushed == 0) if(write(mfd[1], mdata, n)!=n) error("mount write"); unlock(&joblock); if(debug) syslog(0, logfile, "%F %d", &job->reply, n);}voiderror(char *s){ syslog(1, "cs", "%s: %r", s); _exits(0);}static intisvalidip(uchar *ip){ return ipcmp(ip, IPnoaddr) != 0 && ipcmp(ip, v4prefix) != 0;}static uchar loopbacknet[IPaddrlen] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 0};static uchar loopbackmask[IPaddrlen] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0};voidreadipinterfaces(void){ if(myipaddr(ipa, mntpt) != 0) ipmove(ipa, IPnoaddr); sprint(ipaddr, "%I", ipa); if (debug) syslog(0, "dns", "ipaddr is %s\n", ipaddr);}/* * get the system name */voidipid(void){ uchar addr[6]; Ndbtuple *t, *tt; char *p, *attr; Ndbs s; int f; char buf[Maxpath]; /* use environment, ether addr, or ipaddr to get system name */ if(mysysname == 0){ /* * environment has priority. * * on the sgi power the default system name * is the ip address. ignore that. * */ p = getenv("sysname"); if(p && *p){ attr = ipattr(p); if(strcmp(attr, "ip") != 0) mysysname = strdup(p); } /* * the /net/ndb contains what the network * figured out from DHCP. use that name if * there is one. */ if(mysysname == 0 && netdb != nil){ ndbreopen(netdb); for(tt = t = ndbparse(netdb); t != nil; t = t->entry){ if(strcmp(t->attr, "sys") == 0){ mysysname = strdup(t->val); break; } } ndbfree(tt); } /* next network database, ip address, and ether address to find a name */ if(mysysname == 0){ t = nil; if(isvalidip(ipa)) free(ndbgetvalue(db, &s, "ip", ipaddr, "sys", &t)); if(t == nil){ for(f = 0; f < 3; f++){ snprint(buf, sizeof buf, "%s/ether%d", mntpt, f); if(myetheraddr(addr, buf) >= 0){ snprint(eaddr, sizeof(eaddr), "%E", addr); free(ndbgetvalue(db, &s, "ether", eaddr, "sys", &t)); if(t != nil) break; } } } for(tt = t; tt != nil; tt = tt->entry){ if(strcmp(tt->attr, "sys") == 0){ mysysname = strdup(tt->val); break; } } ndbfree(t); } /* nothing else worked, use the ip address */ if(mysysname == 0 && isvalidip(ipa)) mysysname = strdup(ipaddr); /* set /dev/sysname if we now know it */ if(mysysname){ f = open("/dev/sysname", OWRITE); if(f >= 0){ write(f, mysysname, strlen(mysysname)); close(f); } } }}/* * Set up a list of default networks by looking for * /net/ * /clone. */voidnetinit(int background){ char clone[Maxpath]; Network *np; static int working; if(background){ switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){ case 0: break; default: return; } lock(&netlock); } /* add the mounted networks to the default list */ for(np = network; np->net; np++){ if(np->considered) continue; snprint(clone, sizeof(clone), "%s/%s/clone", mntpt, np->net); if(access(clone, AEXIST) < 0) continue; if(netlist) last->next = np; else netlist = np; last = np; np->next = 0; np->considered = 1; } /* find out what our ip address is */ readipinterfaces(); /* set the system name if we need to, these says ip is all we have */ ipid(); if(debug) syslog(0, logfile, "mysysname %s eaddr %s ipaddr %s ipa %I\n", mysysname?mysysname:"???", eaddr, ipaddr, ipa); if(background){ unlock(&netlock); _exits(0); }}/* * add networks to the standard list */voidnetadd(char *p){ Network *np; char *field[12]; int i, n; n = getfields(p, field, 12, 1, " "); for(i = 0; i < n; i++){ for(np = network; np->net; np++){ if(strcmp(field[i], np->net) != 0) continue; if(np->considered) break; if(netlist) last->next = np; else netlist = np; last = np; np->next = 0; np->considered = 1; } }}intlookforproto(Ndbtuple *t, char *proto){ for(; t != nil; t = t->entry) if(strcmp(t->attr, "proto") == 0 && strcmp(t->val, proto) == 0) return 1; return 0;}/* * lookup a request. the network "net" means we should pick the * best network to get there. */intlookup(Mfile *mf){ Network *np; char *cp; Ndbtuple *nt, *t; char reply[Maxreply]; int i, rv; int hack; /* open up the standard db files */ if(db == 0) ndbinit(); if(db == 0) error("can't open mf->network database\n"); rv = 0; if(mf->net == nil) return 0; /* must have been a genquery */ if(strcmp(mf->net, "net") == 0){ /* * go through set of default nets */ for(np = mf->nextnet; np; np = np->next){ nt = (*np->lookup)(np, mf->host, mf->serv, 1); if(nt == nil) continue; hack = np->fasttimeouthack && !lookforproto(nt, np->net); for(t = nt; mf->nreply < Nreply && t; t = t->entry){ cp = (*np->trans)(t, np, mf->serv, mf->rem, hack); if(cp){ /* avoid duplicates */ for(i = 0; i < mf->nreply; i++) if(strcmp(mf->reply[i], cp) == 0) break; if(i == mf->nreply){ /* save the reply */ mf->replylen[mf->nreply] = strlen(cp); mf->reply[mf->nreply++] = cp; rv++; } } } ndbfree(nt); np = np->next; break; } mf->nextnet = np; return rv; } /* * if not /net, we only get one lookup */ if(mf->nreply != 0) return 0; /* * look for a specific network */ for(np = netlist; np && np->net != nil; np++){ if(np->fasttimeouthack) continue; if(strcmp(np->net, mf->net) == 0) break; } if(np && np->net != nil){ /* * known network */ nt = (*np->lookup)(np, mf->host, mf->serv, 1); for(t = nt; mf->nreply < Nreply && t; t = t->entry){ cp = (*np->trans)(t, np, mf->serv, mf->rem, 0); if(cp){ mf->replylen[mf->nreply] = strlen(cp); mf->reply[mf->nreply++] = cp; rv++; } } ndbfree(nt); return rv; } else { /* * not a known network, don't translate host or service */ if(mf->serv) snprint(reply, sizeof(reply), "%s/%s/clone %s!%s", mntpt, mf->net, mf->host, mf->serv); else snprint(reply, sizeof(reply), "%s/%s/clone %s", mntpt, mf->net, mf->host); mf->reply[0] = strdup(reply); mf->replylen[0] = strlen(reply); mf->nreply = 1; return 1; }}/* * translate an ip service name into a port number. If it's a numeric port * number, look for restricted access. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -