static int pc1auth(int n, Rpccall *cmd, Rpccall *reply) { uchar *argptr = cmd->args; uchar *dataptr = reply->results; String id, pw; Unixidmap *m; int uid; chat("host=%I, port=%ld: pcauth...", cmd->host, cmd->port); if(n <= 8) return garbage(reply, "count too small"); argptr += string2S(argptr, &id); argptr += string2S(argptr, &pw); if(argptr != &((uchar*)cmd->args)[n]) return garbage(reply, "bad count"); scramble(&id); scramble(&pw); m = pair2idmap("pcnfsd", cmd->host); uid = -1; if(m) uid = name2id(&m->u.ids, id.s); if(uid < 0) uid = 1; chat("\"%.*s\",\"%.*s\" uid=%d\n", utfnlen(id.s, id.n), id.s, utfnlen(pw.s, pw.n), pw.s, uid); PLONG(0); /* status */ PLONG(uid); /* uid */ PLONG(uid); /* gid */ return dataptr - (uchar*)reply->results; }
V7_PRIVATE val_t rx_exec(struct v7 *v7, val_t rx, val_t str, int lind) { if (v7_is_regexp(rx)) { val_t s = to_string(v7, str); size_t len; struct slre_loot sub; struct slre_cap *ptok = sub.caps; char *const str = (char *) v7_to_string(v7, &s, &len); const char *const end = str + len; const char *begin = str; struct v7_regexp *rp = v7_to_regexp(rx); int flag_g = slre_get_flags(rp->compiled_regexp) & SLRE_FLAG_G; if (rp->lastIndex < 0) rp->lastIndex = 0; if (flag_g || lind) begin = utfnshift(str, rp->lastIndex); if (!slre_exec(rp->compiled_regexp, 0, begin, end, &sub)) { int i; val_t arr = v7_create_array(v7); for (i = 0; i < sub.num_captures; i++, ptok++) v7_array_push(v7, arr, v7_create_string(v7, ptok->start, ptok->end - ptok->start, 1)); if (flag_g) rp->lastIndex = utfnlen(str, sub.caps->end - str); v7_set_property(v7, arr, "index", 5, V7_PROPERTY_READ_ONLY, v7_create_number(utfnlen(str, sub.caps->start - str))); return arr; } else rp->lastIndex = 0; } return v7_create_null(); }
static int pcinfo(int n, Rpccall *cmd, Rpccall *reply) { uchar *argptr = cmd->args; uchar *dataptr = reply->results; String vers, cm; int i; chat("host=%I, port=%ld: pcinfo...", cmd->host, cmd->port); if(n <= 16) return garbage(reply, "count too small"); argptr += string2S(argptr, &vers); argptr += string2S(argptr, &cm); if(argptr != &((uchar *)cmd->args)[n]) return garbage(reply, "bad count"); chat("\"%.*s\",\"%.*s\"\n", utfnlen(vers.s, vers.n), vers.s, utfnlen(cm.s, cm.n), cm.s); PLONG(sizeof(pc_vers)-1); PPTR(pc_vers, sizeof(pc_vers)-1); PLONG(sizeof(no_comment)-1); PPTR(no_comment, sizeof(no_comment)-1); PLONG(nelem(pcfacilities)); for(i=0; i<nelem(pcfacilities); i++) PLONG(pcfacilities[i]); return dataptr - (uchar *)reply->results; }
static int mntmnt(int n, Rpccall *cmd, Rpccall *reply) { int i; char dom[64]; uchar *argptr = cmd->args; uchar *dataptr = reply->results; Authunix au; Xfile *xp; String root; chat("mntmnt...\n"); if(n < 8) return garbage(reply, "n too small"); argptr += string2S(argptr, &root); if(argptr != &((uchar *)cmd->args)[n]) return garbage(reply, "bad count"); clog("host=%I, port=%ld, root=\"%.*s\"...", cmd->host, cmd->port, utfnlen(root.s, root.n), root.s); if(auth2unix(&cmd->cred, &au) != 0){ chat("auth flavor=%ld, count=%ld\n", cmd->cred.flavor, cmd->cred.count); for(i=0; i<cmd->cred.count; i++) chat(" %.2ux", ((uchar *)cmd->cred.data)[i]); chat("\n"); clog("auth: bad credentials"); return error(reply, 1); } clog("auth: %ld %.*s u=%ld g=%ld", au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid); for(i=0; i<au.gidlen; i++) chat(", %ld", au.gids[i]); chat("..."); if(getdom(cmd->host, dom, sizeof(dom))<0){ clog("auth: unknown ip address"); return error(reply, 1); } chat("dom=%s...", dom); xp = xfroot(root.s, root.n); if(xp == 0){ chat("xp=0..."); clog("mntmnt: no fs"); return error(reply, 3); } PLONG(0); dataptr += xp2fhandle(xp, dataptr); chat("OK\n"); return dataptr - (uchar *)reply->results; }
static int mntexport(int n, Rpccall *cmd, Rpccall *reply) { uchar *dataptr = reply->results; Authunix au; int i; chat("mntexport..."); if(n != 0) return garbage(reply, "mntexport"); if(auth2unix(&cmd->cred, &au) != 0){ chat("auth flavor=%ld, count=%ld\n", cmd->cred.flavor, cmd->cred.count); for(i=0; i<cmd->cred.count; i++) chat(" %.2ux", ((uchar *)cmd->cred.data)[i]); chat("..."); au.mach.n = 0; }else chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, au.mach.n), au.mach.s); PLONG(TRUE); PLONG(1); PPTR("/", 1); if(au.mach.n > 0){ PLONG(TRUE); PLONG(au.mach.n); PPTR(au.mach.s, au.mach.n); } PLONG(FALSE); PLONG(FALSE); chat("OK\n"); return dataptr - (uchar *)reply->results; }
void winread(Window *w, uint q0, uint q1, char *data) { int m, n, nr; char buf[256]; if(w->addr < 0) w->addr = winopenfile(w, "addr"); if(w->data < 0) w->data = winopenfile(w, "data"); m = q0; while(m < q1){ n = sprint(buf, "#%d", m); if(write(w->addr, buf, n) != n) error("error writing addr: %r"); n = read(w->data, buf, sizeof buf); if(n <= 0) error("reading data: %r"); nr = utfnlen(buf, n); while(m+nr >q1){ do; while(n>0 && (buf[--n]&0xC0)==0x80); --nr; } if(n == 0) break; memmove(data, buf, n); data += n; *data = 0; m += nr; } }
/* public helper routine: fmt out a null terminated string already in hand */ int fmtstrcpy(Fmt *f, char *s) { int i, j; if(!s) return __fmtcpy(f, "<nil>", 5, 5); /* if precision is specified, make sure we don't wander off the end */ if(f->flags & FmtPrec){ #ifdef PLAN9PORT Rune r; i = 0; for(j=0; j<f->prec && s[i]; j++) i += chartorune(&r, s+i); #else /* ANSI requires precision in bytes, not Runes */ for(i=0; i<f->prec; i++) if(s[i] == 0) break; j = utfnlen(s, i); /* won't print partial at end */ #endif return __fmtcpy(f, s, j, i); } return __fmtcpy(f, s, utflen(s), strlen(s)); }
static int p_seprint(Msg *m) { char *s, *p, buf[4]; Hdr *h; if(m->pe - m->ps < Hsize) return 0; h = (Hdr*)m->ps; m->ps += Hsize; m->pr = nil; if(h->type < nelem(ttab)) s = ttab[h->type]; else{ snprint(buf, sizeof buf, "%d", h->type); s = buf; } p = (char*)m->ps; m->p = seprint(m->p, m->e, "type=%s conn=%d seq=%d len=%d %.*s", s, h->conn, h->seq, h->len, (int)utfnlen(p, h->len), p); return 0; }
static int creat(int n, Rpccall *cmd, Rpccall *reply, int chdir) { Xfid *xf, *newxf; Xfile *xp; String elem; Dir dir; Sattr sattr; uchar *argptr = cmd->args; uchar *dataptr = reply->results; int trunced; if(n <= FHSIZE) return garbage(reply, "count too small"); xf = rpc2xfid(cmd, 0); argptr += FHSIZE; argptr += string2S(argptr, &elem); argptr += convM2sattr(argptr, &sattr); if(argptr != &((uchar *)cmd->args)[n]) return garbage(reply, "bad count"); if(xf == 0) return error(reply, NFSERR_STALE); xp = xf->xp; if(!(xp->qid.type & QTDIR)) return error(reply, NFSERR_NOTDIR); chat("%s/%.*s...", xp->name, utfnlen(elem.s, elem.n), elem.s); trunced = 0; if(xp->parent == xp && elem.s[0] == '#'){ newxf = xfauth(xp, &elem); if(newxf == 0) return error(reply, NFSERR_PERM); if(xfauthremove(newxf, cmd->user) < 0) return error(reply, NFSERR_PERM); trunced = 1; }else newxf = xfwalkcr(Twalk, xf, &elem, 0); if(newxf == 0){ newxf = xfwalkcr(Tcreate, xf, &elem, chdir|(sattr.mode&0777)); if(newxf) trunced = 1; else newxf = xfwalkcr(Twalk, xf, &elem, 0); } if(newxf == 0) return error(reply, NFSERR_PERM); if(!trunced && chdir) return error(reply, NFSERR_EXIST); if(!trunced && xfopen(newxf, Trunc|Oread|Owrite) < 0) return error(reply, NFSERR_PERM); if(xfstat(newxf, &dir) < 0) return error(reply, NFSERR_IO); PLONG(NFS_OK); dataptr += xp2fhandle(newxf->xp, dataptr); dataptr += dir2fattr(cmd->up, &dir, dataptr); chat("OK\n"); return dataptr - (uchar *)reply->results; }
/* * make an address, add the defaults */ char * netmkaddr(char *linear, char *defnet, char *defsrv) { static char addr[256]; char *cp; /* * dump network name */ cp = strchr(linear, '!'); if(cp == 0){ if(defnet == 0) defnet = "net"; /* allow unix sockets to omit unix! prefix */ if(access(linear, 0) >= 0){ snprint(addr, sizeof(addr), "unix!%s", linear); return addr; } /* allow host:service in deference to Unix convention */ if((cp = strchr(linear, ':')) != nil){ snprint(addr, sizeof(addr), "%s!%.*s!%s", defnet, utfnlen(linear, cp-linear), linear, cp+1); return addr; } if(defsrv) snprint(addr, sizeof(addr), "%s!%s!%s", defnet, linear, defsrv); else snprint(addr, sizeof(addr), "%s!%s", defnet, linear); return addr; } /* * if there is already a service, use it */ cp = strchr(cp+1, '!'); if(cp) return linear; /* * if the network is unix, no service */ if(strncmp(linear, "unix!", 5) == 0) return linear; /* * add default service */ if(defsrv == 0) return linear; snprint(addr, sizeof(addr), "%s!%s", linear, defsrv); return addr; }
static int pcauth(int n, Rpccall *cmd, Rpccall *reply) { uchar *argptr = cmd->args; uchar *dataptr = reply->results; String sys, id, pw, cm; Unixidmap *m; int uid; chat("host=%I, port=%ld: pcauth...", cmd->host, cmd->port); if(n <= 16) return garbage(reply, "count too small"); argptr += string2S(argptr, &sys); argptr += string2S(argptr, &id); argptr += string2S(argptr, &pw); argptr += string2S(argptr, &cm); if(argptr != &((uchar *)cmd->args)[n]) return garbage(reply, "bad count"); scramble(&id); scramble(&pw); m = pair2idmap("pcnfsd", cmd->host); uid = -1; if(m) uid = name2id(&m->u.ids, id.s); if(uid < 0) uid = 1; chat("\"%.*s\",\"%.*s\",\"%.*s\",\"%.*s\"\n", utfnlen(sys.s, sys.n), sys.s, utfnlen(id.s, id.n), id.s, utfnlen(pw.s, pw.n), pw.s, utfnlen(cm.s, cm.n), cm.s); PLONG(0); /* status - OK */ PLONG(uid); PLONG(uid); /* gid */ PLONG(0); /* ngids */ PLONG(sizeof(pc_home)-1); PPTR(pc_home, sizeof(pc_home)-1); PLONG(0); /* umask */ PLONG(sizeof(no_comment)-1); PPTR(no_comment, sizeof(no_comment)-1); return dataptr - (uchar *)reply->results; }
static int remov(int n, Rpccall *cmd, Rpccall *reply) { Session *s; Xfile *xp; Xfid *xf, *newxf; String elem; Fid *nfid; uchar *argptr = cmd->args; uchar *dataptr = reply->results; if(n <= FHSIZE) return garbage(reply, "count too small"); xf = rpc2xfid(cmd, 0); argptr += FHSIZE; argptr += string2S(argptr, &elem); if(argptr != &((uchar *)cmd->args)[n]) return garbage(reply, "bad count"); if(xf == 0) return error(reply, NFSERR_STALE); xp = xf->xp; if(!(xp->qid.type & QTDIR)) return error(reply, NFSERR_NOTDIR); chat("%s/%.*s...", xp->name, utfnlen(elem.s, elem.n), elem.s); if(xp->s->noauth == 0 && xp->parent == xp && elem.s[0] == '#') return error(reply, NFSERR_PERM); newxf = xfwalkcr(Twalk, xf, &elem, 0); if(newxf == 0) return error(reply, NFSERR_NOENT); s = xp->s; nfid = newfid(s); setfid(s, newxf->urfid); s->f.newfid = nfid - s->fids; s->f.nwname = 0; if(xmesg(s, Twalk) < 0){ putfid(s, nfid); return error(reply, NFSERR_IO); } s->f.fid = nfid - s->fids; if(xmesg(s, Tremove) < 0){ putfid(s, nfid); return error(reply, NFSERR_PERM); } putfid(s, nfid); xpclear(newxf->xp); PLONG(NFS_OK); chat("OK\n"); return dataptr - (uchar *)reply->results; }
/* public helper routine: fmt out a null terminated string already in hand */ int fmtstrcpy(Fmt *f, char *s) { int p, i; if(!s) return _fmtcpy(f, "<nil>", 5, 5); /* if precision is specified, make sure we don't wander off the end */ if(f->flags & FmtPrec){ p = f->prec; for(i = 0; i < p; i++) if(s[i] == 0) break; return _fmtcpy(f, s, utfnlen(s, i), i); /* BUG?: won't print a partial rune at end */ } return _fmtcpy(f, s, utflen(s), strlen(s)); }
void ptime(double d) { int h, m, s; char *mer; Tim t; if(flags['s']) { /* hour minute */ dtsetup(d + .5/(24*60), &t); h = t.ifa[3]; m = floor(t.ifa[4]); mer = "AM"; if(h >= 12) { mer = "PM"; h -= 12; } if(h == 0) h = 12; numb(h); if(m < 10) { if(m == 0) { print("%s exactly ...", mer); return; } print("O "); } numb(m); print("%s ...", mer); return; } /* hour minute second */ dtsetup(d, &t); h = t.ifa[3]; m = floor(t.ifa[4]); s = floor((t.ifa[4]-m) * 60); print("%.2d:%.2d:%.2d %.*s", h, m, s, utfnlen(t.tz, 3), t.tz); }
File * _fileOpen(Fs *fs, char *path, int partial) { File *f, *ff; char *p, elem[VtMaxStringSize], *opath; int n; f = fs->file; fileIncRef(f); opath = path; while(*path != 0){ for(p = path; *p && *p != '/'; p++) ; n = p - path; if(n > 0){ if(n > VtMaxStringSize){ vtSetError("%s: element too long", EBadPath); goto Err; } memmove(elem, path, n); elem[n] = 0; ff = _fileWalk(f, elem, partial && *p=='\0'); if(ff == nil){ vtSetError("%.*s: %R", utfnlen(opath, p-opath), opath); goto Err; } fileDecRef(f); f = ff; } if(*p == '/') p++; path = p; } return f; Err: fileDecRef(f); return nil; }
static int nfslookup(int n, Rpccall *cmd, Rpccall *reply) { Xfile *xp; Xfid *xf, *newxf; String elem; Dir dir; uchar *argptr = cmd->args; uchar *dataptr = reply->results; chat("lookup..."); if(n <= FHSIZE) return garbage(reply, "count too small"); xf = rpc2xfid(cmd, 0); argptr += FHSIZE; argptr += string2S(argptr, &elem); if(argptr != &((uchar *)cmd->args)[n]) return garbage(reply, "bad count"); if(xf == 0) return error(reply, NFSERR_STALE); xp = xf->xp; if(!(xp->qid.type & QTDIR)) return error(reply, NFSERR_NOTDIR); chat("%s -> \"%.*s\"...", xp->name, utfnlen(elem.s, elem.n), elem.s); if(xp->s->noauth == 0 && xp->parent == xp && elem.s[0] == '#') newxf = xfauth(xp, &elem); else newxf = xfwalkcr(Twalk, xf, &elem, 0); if(newxf == 0) return error(reply, NFSERR_NOENT); if(xfstat(newxf, &dir) < 0) return error(reply, NFSERR_IO); PLONG(NFS_OK); dataptr += xp2fhandle(newxf->xp, dataptr); dataptr += dir2fattr(cmd->up, &dir, dataptr); chat("OK\n"); return dataptr - (uchar *)reply->results; }
Xfile * xfroot(char *name, int n) { Session *s; char *p; if(n <= 0) n = strlen(name); chat("xfroot: %.*s...", utfnlen(name, n), name); if(n == 1 && name[0] == '/') return head->root; for(s=head; s; s=s->next){ if(strncmp(name, s->service, n) == 0) return s->root; p = strrchr(s->service, '!'); /* for -a tcp!foo */ if(p && strncmp(name, p+1, n) == 0) return s->root; p = strrchr(s->service, '/'); /* for -f /srv/foo */ if(p && strncmp(name, p+1, n) == 0) return s->root; } return 0; }
Document* initps(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf) { Document *d; PSInfo *ps; char *p; char *q, *r; char eol; char *nargv[1]; char fdbuf[20]; char tmp[32]; int fd; int i; int incomments; int cantranslate; int trailer=0; int nesting=0; int dumb=0; int landscape=0; long psoff; long npage, mpage; Page *page; Rectangle bbox = Rect(0,0,0,0); if(argc > 1) { fprint(2, "can only view one ps file at a time\n"); return nil; } fprint(2, "reading through postscript...\n"); if(b == nil){ /* standard input; spool to disk (ouch) */ fd = spooltodisk(buf, nbuf, nil); sprint(fdbuf, "/dev/fd/%d", fd); b = Bopen(fdbuf, OREAD); if(b == nil){ fprint(2, "cannot open disk spool file\n"); wexits("Bopen temp"); } nargv[0] = fdbuf; argv = nargv; } /* find %!, perhaps after PCL nonsense */ Bseek(b, 0, 0); psoff = 0; eol = 0; for(i=0; i<16; i++){ psoff = Boffset(b); if(!(p = Brdline(b, eol='\n')) && !(p = Brdline(b, eol='\r'))) { fprint(2, "cannot find end of first line\n"); wexits("initps"); } if(p[0]=='\x1B') p++, psoff++; if(p[0] == '%' && p[1] == '!') break; } if(i == 16){ werrstr("not ps"); return nil; } /* page counting */ npage = 0; mpage = 16; page = emalloc(mpage*sizeof(*page)); memset(page, 0, mpage*sizeof(*page)); cantranslate = goodps; incomments = 1; Keepreading: while(p = Brdline(b, eol)) { if(p[0] == '%') if(chatty) fprint(2, "ps %.*s\n", utfnlen(p, Blinelen(b)-1), p); if(npage == mpage) { mpage *= 2; page = erealloc(page, mpage*sizeof(*page)); memset(&page[npage], 0, npage*sizeof(*page)); } if(p[0] != '%' || p[1] != '%') continue; if(prefix(p, "%%BeginDocument")) { nesting++; continue; } if(nesting > 0 && prefix(p, "%%EndDocument")) { nesting--; continue; } if(nesting) continue; if(prefix(p, "%%EndComment")) { incomments = 0; continue; } if(reverse == -1 && prefix(p, "%%PageOrder")) { /* glean whether we should reverse the viewing order */ p[Blinelen(b)-1] = 0; if(strstr(p, "Ascend")) reverse = 0; else if(strstr(p, "Descend")) reverse = 1; else if(strstr(p, "Special")) dumb = 1; p[Blinelen(b)-1] = '\n'; continue; } else if(prefix(p, "%%Trailer")) { incomments = 1; page[npage].offset = Boffset(b)-Blinelen(b); trailer = 1; continue; } else if(incomments && prefix(p, "%%Orientation")) { if(strstr(p, "Landscape")) landscape = 1; } else if(incomments && Dx(bbox)==0 && prefix(p, q="%%BoundingBox")) { bbox = rdbbox(p+strlen(q)+1); if(chatty) /* can't use %R because haven't initdraw() */ fprint(2, "document bbox [%d %d %d %d]\n", RECT(bbox)); continue; } /* * If they use the initgraphics command, we can't play our translation tricks. */ p[Blinelen(b)-1] = 0; if((q=strstr(p, "initgraphics")) && ((r=strchr(p, '%'))==nil || r > q)) cantranslate = 0; p[Blinelen(b)-1] = eol; if(!prefix(p, "%%Page:")) continue; /* * figure out of the %%Page: line contains a page number * or some other page description to use in the menu bar. * * lines look like %%Page: x y or %%Page: x * we prefer just x, and will generate our * own if necessary. */ p[Blinelen(b)-1] = 0; if(chatty) fprint(2, "page %s\n", p); r = p+7; while(*r == ' ' || *r == '\t') r++; q = r; while(*q && *q != ' ' && *q != '\t') q++; free(page[npage].name); if(*r) { if(*r == '"' && *q == '"') r++, q--; if(*q) *q = 0; page[npage].name = estrdup(r); *q = 'x'; } else { snprint(tmp, sizeof tmp, "p %ld", npage+1); page[npage].name = estrdup(tmp); } /* * store the offset info for later viewing */ trailer = 0; p[Blinelen(b)-1] = eol; page[npage++].offset = Boffset(b)-Blinelen(b); } if(Blinelen(b) > 0){ fprint(2, "page: linelen %d\n", Blinelen(b)); Bseek(b, Blinelen(b), 1); goto Keepreading; } if(Dx(bbox) == 0 || Dy(bbox) == 0) bbox = Rect(0,0,612,792); /* 8½×11 */ /* * if we didn't find any pages, assume the document * is one big page */ if(npage == 0) { dumb = 1; if(chatty) fprint(2, "don't know where pages are\n"); reverse = 0; goodps = 0; trailer = 0; page[npage].name = "p 1"; page[npage++].offset = 0; } if(npage+2 > mpage) { mpage += 2; page = erealloc(page, mpage*sizeof(*page)); memset(&page[mpage-2], 0, 2*sizeof(*page)); } if(!trailer) page[npage].offset = Boffset(b); Bseek(b, 0, 2); /* EOF */ page[npage+1].offset = Boffset(b); d = emalloc(sizeof(*d)); ps = emalloc(sizeof(*ps)); ps->page = page; ps->npage = npage; ps->bbox = bbox; ps->psoff = psoff; d->extra = ps; d->npage = ps->npage; d->b = b; d->drawpage = psdrawpage; d->pagename = pspagename; d->fwdonly = ps->clueless = dumb; d->docname = argv[0]; /* * "tag" the doc as an image for now since there still is the "blank page" * problem for ps files. */ d->type = Tgfx; if(spawngs(&ps->gs, "-dSAFER") < 0) return nil; if(!cantranslate) bbox.min = ZP; setdim(&ps->gs, bbox, ppi, landscape); if(goodps){ /* * We want to only send the page (i.e. not header and trailer) information * for each page, so initialize the device by sending the header now. */ pswritepage(d, ps->gs.gsfd, -1); waitgs(&ps->gs); } if(dumb) { fprint(ps->gs.gsfd, "(%s) run\n", argv[0]); fprint(ps->gs.gsfd, "(/dev/fd/3) (w) file dup (THIS IS NOT A PLAN9 BITMAP 01234567890123456789012345678901234567890123456789\\n) writestring flushfile\n"); } ps->bbox = bbox; return d; }
void objfile(char *file, char *pkg) { vlong off, l; Biobuf *f; char magbuf[SARMAG]; char pname[150]; struct ar_hdr arhdr; pkg = smprint("%i", pkg); if(debug['v'] > 1) Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg); Bflush(&bso); f = Bopen(file, 0); if(f == nil) { diag("cannot open file: %s", file); errorexit(); } l = Bread(f, magbuf, SARMAG); if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ /* load it as a regular file */ l = Bseek(f, 0L, 2); Bseek(f, 0L, 0); ldobj(f, pkg, l, file, file, FileObj); Bterm(f); free(pkg); return; } /* skip over optional __.GOSYMDEF and process __.PKGDEF */ off = Boffset(f); l = nextar(f, off, &arhdr); if(l <= 0) { diag("%s: short read on archive file symbol header", file); goto out; } if(strncmp(arhdr.name, symname, strlen(symname)) == 0) { off += l; l = nextar(f, off, &arhdr); if(l <= 0) { diag("%s: short read on archive file symbol header", file); goto out; } } if(strncmp(arhdr.name, pkgname, strlen(pkgname))) { diag("%s: cannot find package header", file); goto out; } off += l; if(debug['u']) ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef); /* * load all the object files from the archive now. * this gives us sequential file access and keeps us * from needing to come back later to pick up more * objects. it breaks the usual C archive model, but * this is Go, not C. the common case in Go is that * we need to load all the objects, and then we throw away * the individual symbols that are unused. * * loading every object will also make it possible to * load foreign objects not referenced by __.GOSYMDEF. */ for(;;) { l = nextar(f, off, &arhdr); if(l == 0) break; if(l < 0) { diag("%s: malformed archive", file); goto out; } off += l; l = SARNAME; while(l > 0 && arhdr.name[l-1] == ' ') l--; snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name); l = atolwhex(arhdr.size); ldobj(f, pkg, l, pname, file, ArchiveObj); } out: Bterm(f); free(pkg); }
int eenter(char *ask, char *buf, int len, Mouse *m) { int done, down, tick, n, h, w, l, i; Image *b, *save, *backcol, *bordcol; Point p, o, t; Rectangle r, sc; Event ev; Rune k; o = screen->r.min; backcol = allocimagemix(display, DPurpleblue, DWhite); bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue); if(backcol == nil || bordcol == nil) return -1; while(ecankbd()) ekbd(); if(m) o = m->xy; if(buf && len > 0) n = strlen(buf); else { buf = nil; len = 0; n = 0; } k = -1; tick = n; save = nil; done = down = 0; p = stringsize(font, " "); h = p.y; w = p.x; b = screen; sc = b->clipr; replclipr(b, 0, b->r); while(!done){ p = stringsize(font, buf ? buf : ""); if(ask && ask[0]){ if(buf) p.x += w; p.x += stringwidth(font, ask); } r = rectaddpt(insetrect(Rpt(ZP, p), -4), o); p.x = 0; r = rectsubpt(r, p); p = ZP; if(r.min.x < screen->r.min.x) p.x = screen->r.min.x - r.min.x; if(r.min.y < screen->r.min.y) p.y = screen->r.min.y - r.min.y; r = rectaddpt(r, p); p = ZP; if(r.max.x > screen->r.max.x) p.x = r.max.x - screen->r.max.x; if(r.max.y > screen->r.max.y) p.y = r.max.y - screen->r.max.y; r = rectsubpt(r, p); r = insetrect(r, -2); if(save == nil){ save = allocimage(display, r, b->chan, 0, DNofill); if(save == nil){ n = -1; break; } draw(save, r, b, nil, r.min); } draw(b, r, backcol, nil, ZP); border(b, r, 2, bordcol, ZP); p = addpt(r.min, Pt(6, 6)); if(ask && ask[0]){ p = string(b, p, bordcol, ZP, font, ask); if(buf) p.x += w; } if(buf){ t = p; p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick)); draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP); draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP); draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP); p = string(b, p, display->black, ZP, font, buf+tick); } flushimage(display, 1); nodraw: i = Ekeyboard; if(m != nil) i |= Emouse; replclipr(b, 0, sc); i = eread(i, &ev); /* screen might have been resized */ if(b != screen || !eqrect(screen->clipr, sc)){ freeimage(save); save = nil; } b = screen; sc = b->clipr; replclipr(b, 0, b->r); switch(i){ default: done = 1; n = -1; break; case Ekeyboard: k = ev.kbdc; if(buf == nil || k == Keof || k == '\n'){ done = 1; break; } if(k == Knack || k == Kesc){ done = !n; buf[n = tick = 0] = 0; break; } if(k == Ksoh || k == Khome){ tick = 0; continue; } if(k == Kenq || k == Kend){ tick = n; continue; } if(k == Kright){ if(tick < n) tick += chartorune(&k, buf+tick); continue; } if(k == Kleft){ for(i = 0; i < n; i += l){ l = chartorune(&k, buf+tick); if(i+l >= tick){ tick = i; break; } } continue; } if(k == Ketb){ while(tick > 0){ tick--; if(tick == 0 || strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1])) break; } buf[n = tick] = 0; break; } if(k == Kbs){ if(tick <= 0) continue; for(i = 0; i < n; i += l){ l = chartorune(&k, buf+i); if(i+l >= tick){ memmove(buf+i, buf+i+l, n - (i+l)); buf[n -= l] = 0; tick -= l; break; } } break; } if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec) continue; if((len-n) <= (l = runelen(k))) continue; memmove(buf+tick+l, buf+tick, n - tick); runetochar(buf+tick, &k); buf[n += l] = 0; tick += l; break; case Emouse: *m = ev.mouse; if(!ptinrect(m->xy, r)){ down = 0; goto nodraw; } if(m->buttons & 7){ down = 1; if(buf && m->xy.x >= (t.x - w)){ down = 0; for(i = 0; i < n; i += l){ l = chartorune(&k, buf+i); t.x += stringnwidth(font, buf+i, 1); if(t.x > m->xy.x) break; } tick = i; } continue; } done = down; break; } if(save){ draw(b, save->r, save, nil, save->r.min); freeimage(save); save = nil; } } replclipr(b, 0, sc); freeimage(backcol); freeimage(bordcol); flushimage(display, 1); return n; }
void main(int argc, char **argv) { int i, hdr, n, eof, off; Dreprog *re[3]; int m[3]; char *p, *ep, *tag; Biobuf bout, bin; char msg[1024+1]; char buf[1024]; refile = unsharp(refile); buildre(re); ARGBEGIN{ case 'D': debug = 1; break; case 'n': maxtoklen = atoi(EARGF(usage())); break; case 'r': refile = EARGF(usage()); break; default: usage(); }ARGEND; if(argc > 1) usage(); if(argc == 1){ close(0); if(open(argv[0], OREAD) < 0) sysfatal("open %s: %r", argv[0]); } tag = nil; Binit(&bin, 0, OREAD); Binit(&bout, 1, OWRITE); ep = msg; p = msg; eof = 0; off = 0; hdr = 1; for(;;){ /* replenish buffer */ if(ep - p < 512 && !eof){ if(p > msg + 1){ n = ep - p; memmove(msg, p-1, ep-(p-1)); off += (p-1) - msg; p = msg+1; ep = p + n; } n = Bread(&bin, ep, msg+(sizeof msg - 1)- ep); if(n < 0) sysfatal("read error: %r"); if(n == 0) eof = 1; ep += n; *ep = 0; } if(p >= ep) break; if(*p == 0){ p++; continue; } if(hdr && p[-1]=='\n'){ if(p[0]=='\n') hdr = 0; else if(cistrncmp(p-1, "\nfrom:", 6) == 0) tag = "From*"; else if(cistrncmp(p-1, "\nto:", 4) == 0) tag = "To*"; else if(cistrncmp(p-1, "\nsubject:", 9) == 0) tag = "Subject*"; else if(cistrncmp(p-1, "\nreturn-path:", 13) == 0) tag = "Return-Path*"; else tag = nil; } m[0] = dregexec(re[0], p, p==msg || p[-1]=='\n'); m[1] = dregexec(re[1], p, p==msg || p[-1]=='\n'); m[2] = dregexec(re[2], p, p==msg || p[-1]=='\n'); n = m[0]; if(n < m[1]) n = m[1]; if(n < m[2]) n = m[2]; if(n <= 0){ fprint(2, "«%s» %.2ux", p, p[0]); sysfatal("no regexps matched at %ld", off + (p-msg)); } if(m[0] >= m[1] && m[0] >= m[2]){ /* "From " marks start of new message */ Bprint(&bout, "*From*\n"); n = m[0]; hdr = 1; }else if(m[2] > 1){ /* ignore */ n = m[2]; }else if(m[1] >= m[0] && m[1] >= m[2] && m[1] > 2 && m[1] <= maxtoklen){ /* keyword */ /* should do UTF-aware lowercasing, too much bother */ /* for(i=0; i<n; i++) if('A' <= p[i] && p[i] <= 'Z') p[i] += 'a' - 'A'; */ if(tag){ i = strlen(tag); memmove(buf, tag, i); memmove(buf+i, p, m[1]); buf[i+m[1]] = 0; }else{ memmove(buf, p, m[1]); buf[m[1]] = 0; } Bprint(&bout, "%s\n", buf); while(trim(buf) >= 0) Bprint(&bout, "stem*%s\n", buf); n = m[1]; }else n = m[2]; if(debug) fprint(2, "%.*s¦", utfnlen(p, n), p); p += n; } Bterm(&bout); exits(0); }
Xfid * rpc2xfid(Rpccall *cmd, Dir *dp) { char *argptr = cmd->args; Xfile *xp; Xfid *xf; Session *s; char *service; Authunix au; Qid qid; char client[256], *user; Unixidmap *m; int i; uvlong x1, x2; chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr); if(argptr[0] == 0 && argptr[1] == 0){ /* root */ chat("root..."); xp = xfroot(&argptr[2], 0); s = xp ? xp->s : 0; }else{ ulong ul; chat("noroot %.8lux...", *((ulong*)argptr)); if((ul=GLONG()) != starttime){ chat("bad tag %lux %lux...", ul, starttime); return 0; } s = (Session *)GLONG(); x1 = GLONG(); x2 = GLONG(); qid.path = x1 | (x2<<32); qid.vers = 0; qid.type = GBYTE(); xp = xfile(&qid, s, 0); } if(xp == 0){ chat("no xfile..."); return 0; } if(auth2unix(&cmd->cred, &au) != 0){ chat("auth flavor=%ld, count=%ld\n", cmd->cred.flavor, cmd->cred.count); for(i=0; i<cmd->cred.count; i++) chat(" %.2ux", ((uchar *)cmd->cred.data)[i]); chat("..."); return 0; }else{ /* chat("auth: %d %.*s u=%d g=%d", * au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid); * for(i=0; i<au.gidlen; i++) * chat(", %d", au.gids[i]); * chat("..."); */ char *p = memchr(au.mach.s, '.', au.mach.n); chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s); } if(au.mach.n >= sizeof client){ chat("client name too long..."); return 0; } memcpy(client, au.mach.s, au.mach.n); client[au.mach.n] = 0; service = xp->parent->s->service; cmd->up = m = pair2idmap(service, cmd->host); if(m == 0){ chat("no map for pair (%s,%s)...", service, client); /*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF, (cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/ /*if(getdom(cmd->host, client, sizeof(client))<0) return 0;/**/ return 0; } /*chat("map=(%s,%s)...", m->server, m->client);/**/ cmd->user = user = id2name(&m->u.ids, au.uid); if(user == 0){ chat("no user for id %ld...", au.uid); return 0; } chat("user=%s...", user);/**/ xf = 0; if(s == xp->parent->s){ if(!s->noauth) xf = setuser(xp, user); if(xf == 0) xf = setuser(xp, "none"); if(xf == 0) chat("can't set user none..."); }else xf = xp->users; if(xf) chat("uid=%s...", xf->uid); if(xf && dp && xfstat(xf, dp) < 0){ chat("can't stat %s...", xp->name); return 0; } return xf; }
static int __sendinput(Window *w, uint32_t q0, uint32_t q1) { char *s, *t; int n, nb, eofchar; static int partial; static char tmp[UTFmax]; Req *r; Rune rune; if(!q) return 0; r = q; n = 0; if(partial){ Partial: nb = partial; if(nb > r->ifcall.count) nb = r->ifcall.count; memmove(r->ofcall.data, tmp, nb); if(nb!=partial) memmove(tmp, tmp+nb, partial-nb); partial -= nb; q = r->aux; if(q == nil) eq = &q; r->aux = nil; r->ofcall.count = nb; if(debug) fprint(2, "satisfy read with partial\n"); respond(r, nil); return n; } if(q0==q1) return 0; s = emalloc((q1-q0)*UTFmax+1); n = winread(w, q0, q1, s); s[n] = '\0'; t = strpbrk(s, "\n\004"); if(t == nil){ free(s); return 0; } r = q; eofchar = 0; if(*t == '\004'){ eofchar = 1; *t = '\0'; }else *++t = '\0'; nb = utfncpy((char*)r->ofcall.data, s, r->ifcall.count); if(nb==0 && s<t && r->ifcall.count > 0){ partial = utfncpy(tmp, s, UTFmax); assert(partial > 0); chartorune(&rune, tmp); partial = runelen(rune); free(s); n = 1; goto Partial; } n = utfnlen(r->ofcall.data, nb); if(nb==strlen(s) && eofchar) n++; r->ofcall.count = nb; q = r->aux; if(q == nil) eq = &q; r->aux = nil; if(debug) fprint(2, "read returns %lud-%lud: %.*q\n", q0, q0+n, n, r->ofcall.data); respond(r, nil); return n; }