void acmeputsnarf(void) { int i, n; Fmt f; char *s; if(snarfbuf.nc==0) return; if(snarfbuf.nc > MAXSNARF) return; fmtstrinit(&f); for(i=0; i<snarfbuf.nc; i+=n){ n = snarfbuf.nc-i; if(n >= NSnarf) n = NSnarf; bufread(&snarfbuf, i, snarfrune, n); if(fmtprint(&f, "%.*S", n, snarfrune) < 0) break; } s = fmtstrflush(&f); if(s && s[0]) putsnarf(s); free(s); }
static char* getquoted(void) { int c; Rune r; Fmt fmt; c = getnsc(); if(c != '"') return nil; fmtstrinit(&fmt); for(;;) { r = getr(); if(r == '\n') { free(fmtstrflush(&fmt)); return nil; } if(r == '"') break; fmtrune(&fmt, r); } free(lastfmt); lastfmt = fmtstrflush(&fmt); return strdup(lastfmt); }
static void _synccmd(char*) { int i, fd; char *s; Fmt f; if(!loggedin){ sendok(""); return; } fmtstrinit(&f); fmtprint(&f, "delete mbox"); for(i=0; i<nmsg; i++) if(msg[i].deleted) fmtprint(&f, " %d", msg[i].upasnum); s = fmtstrflush(&f); if(strcmp(s, "delete mbox") != 0){ /* must have something to delete */ if((fd = open("../ctl", OWRITE)) < 0){ senderr("open ctl to delete messages: %r"); return; } if(write(fd, s, strlen(s)) < 0){ senderr("error deleting messages: %r"); return; } } sendok(""); }
int Iconv(Fmt *fp) { int i, n; uint32 *p; char *s; Fmt fmt; n = fp->prec; fp->prec = 0; if(!(fp->flags&FmtPrec) || n < 0) return fmtstrcpy(fp, "%I"); fp->flags &= ~FmtPrec; p = va_arg(fp->args, uint32*); // format into temporary buffer and // call fmtstrcpy to handle padding. fmtstrinit(&fmt); for(i=0; i<n/4; i++) { if(i > 0) fmtprint(&fmt, " "); fmtprint(&fmt, "%.8ux", *p++); } s = fmtstrflush(&fmt); fmtstrcpy(fp, s); free(s); return 0; }
char* unrfc2047(char *s) { char *p, *q, *t, *u, *v; int len; Rune r; Fmt fmt; if(s == nil) return nil; if(strstr(s, "=?") == nil) return s; fmtstrinit(&fmt); for(p=s; *p; ){ /* =?charset?e?text?= */ if(*p=='=' && *(p+1)=='?'){ p += 2; q = strchr(p, '?'); if(q == nil) goto emit; q++; if(*q == '?' || *(q+1) != '?') goto emit; t = q+2; u = strchr(t, '?'); if(u == nil || *(u+1) != '=') goto emit; switch(*q){ case 'q': case 'Q': *u = 0; v = decode(QuotedPrintableU, t, &len); break; case 'b': case 'B': *u = 0; v = decode(Base64, t, &len); break; default: goto emit; } *(q-1) = 0; v = tcs(p, v); fmtstrcpy(&fmt, v); free(v); p = u+2; } emit: p += chartorune(&r, p); fmtrune(&fmt, r); } p = fmtstrflush(&fmt); if(p == nil) sysfatal("out of memory"); free(s); return p; }
void wwwauthenticate(HttpState *hs, char *line) { char cred[64], *user, *pass, *realm, *s, *spec, *name; Fmt fmt; UserPasswd *up; spec = nil; up = nil; cred[0] = 0; hs->autherror[0] = 0; if(cistrncmp(line, "basic ", 6) != 0){ werrstr("unknown auth: %s", line); goto error; } line += 6; if(cistrncmp(line, "realm=", 6) != 0){ werrstr("missing realm: %s", line); goto error; } line += 6; user = hs->c->url->user; pass = hs->c->url->passwd; if(user==nil || pass==nil){ realm = unquote(line, &line); fmtstrinit(&fmt); name = servername(hs->netaddr); fmtprint(&fmt, "proto=pass service=http server=%q realm=%q", name, realm); free(name); if(hs->c->url->user) fmtprint(&fmt, " user=%q", hs->c->url->user); spec = fmtstrflush(&fmt); if(spec == nil) goto error; if((up = auth_getuserpasswd(nil, "%s", spec)) == nil) goto error; user = up->user; pass = up->passwd; } if((s = smprint("%s:%s", user, pass)) == nil) goto error; free(up); enc64(cred, sizeof(cred), (uint8_t*)s, strlen(s)); memset(s, 0, strlen(s)); free(s); hs->credentials = smprint("Basic %s", cred); if(hs->credentials == nil) goto error; return; error: free(up); free(spec); snprint(hs->autherror, sizeof hs->autherror, "%r"); fprint(2, "%s: Authentication failed: %r\n", argv0); }
void putenvqv(char *name, char **v, int n, int conf) { Fmt f; int i; char *val; fmtstrinit(&f); for(i=0; i<n; i++) fmtprint(&f, "%s%q", i?" ":"", v[i]); val = fmtstrflush(&f); ksetenv(name, val, conf); free(val); }
char* ctlstring(void) { int i; Fmt fmt; fmtstrinit(&fmt); fmtprint(&fmt, "inquiry %s\n", inquiry); fmtprint(&fmt, "geometry %lld %lld %lld %lld %lld\n", nsect, sectsize, c, h, s); for(i=0; i<nelem(tab); i++) if(tab[i].inuse) fmtprint(&fmt, "part %s %lld %lld\n", tab[i].name, tab[i].offset, tab[i].length); return fmtstrflush(&fmt); }
char* ctlstring(void) { Part *p; Fmt fmt; fmtstrinit(&fmt); fmtprint(&fmt, "inquiry %s\n", inquiry); fmtprint(&fmt, "geometry %lld %lld\n", nsect, sectsize); for (p = tab; p < tab + nelem(tab); p++) if (p->inuse) fmtprint(&fmt, "part %s %lld %lld\n", p->name, p->offset, p->offset + p->length); return fmtstrflush(&fmt); }
/* * print into an allocated string buffer */ char* vsmprint(char *fmt, va_list args) { Fmt f; int n; if(fmtstrinit(&f) < 0) return nil; f.args = args; n = dofmt(&f, fmt); if(n < 0) return nil; *(char*)f.to = '\0'; return (char*)f.start; }
/* Test printer that loads unusual decimal point and separator */ char* mysmprint(char *fmt, ...) { Fmt f; if(fmtstrinit(&f) < 0) return 0; va_start(f.args, fmt); f.decimal = smprint("%C", lightsmiley); f.thousands = smprint("%C", darksmiley); f.grouping = "\1\2\3\4"; if(dofmt(&f, fmt) < 0) return 0; va_end(f.args); return fmtstrflush(&f); }
/* * print into an allocated string buffer */ char* vsmprint(char *fmt, va_list args) { Fmt f; int n; if(fmtstrinit(&f) < 0) return nil; VA_COPY(f.args,args); n = dofmt(&f, fmt); VA_END(f.args); if(n < 0){ free(f.start); return nil; } return fmtstrflush(&f); }
/* * print into an allocated string buffer */ char* vsmprint(const char *fmt, va_list args) { Fmt f; int n; if(fmtstrinit(&f) < 0) return nil; va_copy(f.args,args); n = dofmt(&f, fmt); va_end(f.args); if(n < 0){ free(f.start); return nil; } return fmtstrflush(&f); }
int makeinfo(int path) { Fmt f; if(path < 0 || path > nelem(Infdir)) return -1; if(Infdir[path].buf != nil) return 0; fmtstrinit(&f); if((*Infdir[path].func)(&f) == -1) return -1; if((Infdir[path].buf = fmtstrflush(&f)) == nil) return -1; if((Infdir[path].len = strlen(Infdir[path].buf)) <= 0) return -1; return 0; }
static void setcookie(HttpState *hs, char *value) { char *s, *t; Fmt f; s = hs->setcookie; fmtstrinit(&f); if(s) fmtprint(&f, "%s", s); fmtprint(&f, "set-cookie: "); fmtprint(&f, "%s", value); fmtprint(&f, "\n"); t = fmtstrflush(&f); if(t){ free(s); hs->setcookie = t; } }
void fatal(int syserr, char *fmt, ...) { Fmt f; char *str; va_list arg; fmtstrinit(&f); fmtprint(&f, "cpu: "); va_start(arg, fmt); fmtvprint(&f, fmt, arg); va_end(arg); if(syserr) fmtprint(&f, ": %r"); fmtprint(&f, "\n"); str = fmtstrflush(&f); write(2, str, strlen(str)); exits(str); }
void fatal(int syserr, char *fmt, ...) { Fmt f; char *str; va_list arg; fmtstrinit(&f); fmtprint(&f, "cpu: "); va_start(arg, fmt); fmtvprint(&f, fmt, arg); va_end(arg); if(syserr) fmtprint(&f, ": %r"); str = fmtstrflush(&f); fprint(2, "%s\n", str); syslog(0, "cpu", str); exits(str); }
Bits getflag(char *s) { Bits flag; int f; Fmt fmt; Rune c; flag = zbits; nstar = 0; fmtstrinit(&fmt); for(;;) { s += chartorune(&c, s); if(c == 0 || c >= nelem(flagbits)) break; fmtrune(&fmt, c); f = flagbits[c]; switch(f) { case Fnone: argflag(c, Fverb); f = flagbits[c]; break; case Fstar: nstar++; case Fignor: continue; case Fl: if(bset(flag, Fl)) flag = bor(flag, blsh(Fvl)); } flag = bor(flag, blsh(f)); if(f >= Fverb) break; } free(lastfmt); lastfmt = fmtstrflush(&fmt); return flag; }
void syscallfmt(int syscallno, ...) { Proc *up = externup(); va_list list; int32_t l; Fmt fmt; void *v; int64_t vl; uintptr_t p; int i[2], len; char *a, **argv; va_start(list, syscallno); iprint("%d: %d nsyscall %d\n", up->pid, syscallno, nsyscall); fmtstrinit(&fmt); fmtprint(&fmt, "%d %s ", up->pid, up->text); if(syscallno > nsyscall) fmtprint(&fmt, " %d ", syscallno); else fmtprint(&fmt, "%s ", systab[syscallno].n); if(up->syscalltrace != nil) free(up->syscalltrace); up->syscalltrace = nil; switch(syscallno){ case CHDIR: case EXITS: case REMOVE: a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case BIND: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux", i[0]); break; case CLOSE: case NOTED: i[0] = va_arg(list, int); fmtprint(&fmt, "%d", i[0]); break; case DUP: i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %d", i[0], i[1]); break; case ALARM: l = va_arg(list, unsigned long); fmtprint(&fmt, "%#lud ", l); break; case EXEC: a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); argv = va_arg(list, char**); evenaddr(PTR2UINT(argv)); for(;;){ a = *(char**)validaddr(argv, sizeof(char**), 0); if(a == nil) break; fmtprint(&fmt, " "); fmtuserstring(&fmt, a, ""); argv++; } break; case FAUTH: i[0] = va_arg(list, int); a = va_arg(list, char*); fmtprint(&fmt, "%d", i[0]); fmtuserstring(&fmt, a, ""); break; case SEGBRK: case RENDEZVOUS: v = va_arg(list, void*); fmtprint(&fmt, "%#p ", v); v = va_arg(list, void*); fmtprint(&fmt, "%#p", v); break; case OPEN: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux", i[0]); break; case RFORK: i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux", i[0]); break; case PIPE: case BRK_: v = va_arg(list, int*); fmtprint(&fmt, "%#p", v); break; case CREATE: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%#ux %#ux", i[0], i[1]); break; case FD2PATH: case FSTAT: case FWSTAT: i[0] = va_arg(list, int); a = va_arg(list, char*); l = va_arg(list, unsigned long); fmtprint(&fmt, "%d %#p %lud", i[0], a, l); break; case NOTIFY: case SEGDETACH: v = va_arg(list, void*); fmtprint(&fmt, "%#p", v); break; case SEGATTACH: i[0] = va_arg(list, int); fmtprint(&fmt, "%d ", i[0]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); /*FALLTHROUGH*/ case SEGFREE: case SEGFLUSH: v = va_arg(list, void*); l = va_arg(list, unsigned long); fmtprint(&fmt, "%#p %lud", v, l); break; case UNMOUNT: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case SEMACQUIRE: case SEMRELEASE: v = va_arg(list, int*); i[0] = va_arg(list, int); fmtprint(&fmt, "%#p %d", v, i[0]); break; case TSEMACQUIRE: v = va_arg(list, int*); l = va_arg(list, uint32_t); fmtprint(&fmt, "%#p %ld", v, l); break; case AWAKE: vl = va_arg(list, int64_t); fmtprint(&fmt, "%lld", vl); break; case SEEK: i[0] = va_arg(list, int); vl = va_arg(list, int64_t); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %#llux %d", i[0], vl, i[1]); break; case FVERSION: i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %d ", i[0], i[1]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); l = va_arg(list, unsigned long); fmtprint(&fmt, "%lud", l); break; case WSTAT: case STAT: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); /*FALLTHROUGH*/ case ERRSTR: case AWAIT: a = va_arg(list, char*); l = va_arg(list, unsigned long); fmtprint(&fmt, "%#p %lud", a, l); break; case MOUNT: i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %d ", i[0], i[1]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux ", i[0]); a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case READ: /* deprecated */ case PREAD: i[0] = va_arg(list, int); v = va_arg(list, void*); l = va_arg(list, int32_t); fmtprint(&fmt, "%d %#p %ld", i[0], v, l); if(syscallno == PREAD){ vl = va_arg(list, int64_t); fmtprint(&fmt, " %lld", vl); } break; case WRITE: /* deprecated */ case PWRITE: i[0] = va_arg(list, int); v = va_arg(list, void*); l = va_arg(list, int32_t); fmtprint(&fmt, "%d ", i[0]); len = MIN(l, 64); fmtrwdata(&fmt, v, len, " "); fmtprint(&fmt, "%ld", l); if(syscallno == PWRITE){ vl = va_arg(list, int64_t); fmtprint(&fmt, " %lld", vl); } break; } up->syscalltrace = fmtstrflush(&fmt); }
static void xread(Req *r) { int i, size, height, ascent; vlong path; Fmt fmt; XFont *f; char *data; Memsubfont *sf; Memimage *m; path = r->fid->qid.path; switch(QTYPE(path)) { case Qroot: dirread9p(r, rootgen, nil); break; case Qfontdir: dirread9p(r, fontgen, r->fid); break; case Qsizedir: dirread9p(r, sizegen, r->fid); break; case Qfontfile: fmtstrinit(&fmt); f = &xfont[QFONT(path)]; load(f); if(f->unit == 0 && f->loadheight == nil) { readstr(r, "font missing\n"); break; } height = 0; ascent = 0; if(f->unit > 0) { height = f->height * (int)QSIZE(path)/f->unit + 0.99999999; ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999); } if(f->loadheight != nil) f->loadheight(f, QSIZE(path), &height, &ascent); fmtprint(&fmt, "%11d %11d\n", height, ascent); for(i=0; i<nelem(f->range); i++) { if(f->range[i] == 0) continue; fmtprint(&fmt, "0x%04x 0x%04x x%04x.bit\n", i*SubfontSize, ((i+1)*SubfontSize) - 1, i*SubfontSize); } data = fmtstrflush(&fmt); readstr(r, data); free(data); break; case Qsubfontfile: f = &xfont[QFONT(path)]; load(f); if(r->fid->aux == nil) { r->fid->aux = mksubfont(f, f->name, QRANGE(path)*SubfontSize, ((QRANGE(path)+1)*SubfontSize)-1, QSIZE(path), QANTIALIAS(path)); if(r->fid->aux == nil) { responderrstr(r); return; } } sf = r->fid->aux; m = sf->bits; if(r->ifcall.offset < 5*12) { char *chan; if(QANTIALIAS(path)) chan = "k8"; else chan = "k1"; data = smprint("%11s %11d %11d %11d %11d ", chan, m->r.min.x, m->r.min.y, m->r.max.x, m->r.max.y); readstr(r, data); free(data); break; } r->ifcall.offset -= 5*12; size = bytesperline(m->r, chantodepth(m->chan)) * Dy(m->r); if(r->ifcall.offset < size) { readbuf(r, byteaddr(m, m->r.min), size); break; } r->ifcall.offset -= size; data = emalloc9p(3*12+6*(sf->n+1)); sprint(data, "%11d %11d %11d ", sf->n, sf->height, sf->ascent); packinfo(sf->info, (uchar*)data+3*12, sf->n); readbuf(r, data, 3*12+6*(sf->n+1)); free(data); break; } respond(r, nil); }
void threadmain(int argc, char *argv[]) { char *s, *name; char err[ERRMAX], *cmd; int i, newdir; Fmt fmt; doquote = needsrcquote; quotefmtinstall(); /* open these early so we won't miss notification of new mail messages while we read mbox */ if((plumbsendfd = plumbopenfid("send", OWRITE|OCEXEC)) == nil) fprint(2, "warning: open plumb/send: %r\n"); if((plumbseemailfd = plumbopenfid("seemail", OREAD|OCEXEC)) == nil) fprint(2, "warning: open plumb/seemail: %r\n"); if((plumbshowmailfd = plumbopenfid("showmail", OREAD|OCEXEC)) == nil) fprint(2, "warning: open plumb/showmail: %r\n"); shortmenu = 0; srvname = "mail"; ARGBEGIN{ case 's': shortmenu = 1; break; case 'S': shortmenu = 2; break; case 'o': outgoing = EARGF(usage()); break; case 'm': smprint(maildir, "%s/", EARGF(usage())); break; case 'n': srvname = EARGF(usage()); break; default: usage(); }ARGEND acmefs = nsmount("acme",nil); if(acmefs == nil) error("cannot mount acme: %r"); mailfs = nsmount(srvname, nil); if(mailfs == nil) error("cannot mount %s: %r", srvname); name = "mbox"; newdir = 1; if(argc > 0){ i = strlen(argv[0]); if(argc>2 || i==0) usage(); /* see if the name is that of an existing /mail/fs directory */ if(argc==1 && argv[0][0] != '/' && ismaildir(argv[0])){ name = argv[0]; mboxname = estrdup(name); newdir = 0; }else{ if(argv[0][i-1] == '/') argv[0][i-1] = '\0'; s = strrchr(argv[0], '/'); if(s == nil) mboxname = estrdup(argv[0]); else{ *s++ = '\0'; if(*s == '\0') usage(); mailboxdir = argv[0]; mboxname = estrdup(s); } if(argc > 1) name = argv[1]; else name = mboxname; } } user = getenv("user"); if(user == nil) user = "******"; home = getenv("home"); if(home == nil) home = getenv("HOME"); if(home == nil) error("can't find $home"); if(mailboxdir == nil) mailboxdir = estrstrdup(home, "/mail"); if(outgoing == nil) outgoing = estrstrdup(mailboxdir, "/outgoing"); mbox.ctlfd = fsopen(mailfs, estrstrdup(mboxname, "/ctl"), OWRITE); if(mbox.ctlfd == nil) error("can't open %s: %r", estrstrdup(mboxname, "/ctl")); fsname = estrdup(name); if(newdir && argc > 0){ s = emalloc(5+strlen(mailboxdir)+strlen(mboxname)+strlen(name)+10+1); for(i=0; i<10; i++){ sprint(s, "open %s/%s %s", mailboxdir, mboxname, fsname); if(fswrite(mbox.ctlfd, s, strlen(s)) >= 0) break; err[0] = '\0'; errstr(err, sizeof err); if(strstr(err, "mbox name in use") == nil) error("can't create directory %s for mail: %s", name, err); free(fsname); fsname = emalloc(strlen(name)+10); sprint(fsname, "%s-%d", name, i); } if(i == 10) error("can't open %s/%s: %r", mailboxdir, mboxname); free(s); } s = estrstrdup(fsname, "/"); mbox.name = estrstrdup(maildir, s); mbox.level= 0; readmbox(&mbox, maildir, s); home = getenv("home"); if(home == nil) home = "/"; wbox = newwindow(); winname(wbox, mbox.name); wintagwrite(wbox, "Put Mail Delmesg ", 3+1+4+1+7+1); threadcreate(mainctl, wbox, STACK); fmtstrinit(&fmt); fmtprint(&fmt, "Mail"); if(shortmenu) fmtprint(&fmt, " -%c", "sS"[shortmenu-1]); if(outgoing) fmtprint(&fmt, " -o %s", outgoing); fmtprint(&fmt, " %s", name); cmd = fmtstrflush(&fmt); if(cmd == nil) sysfatal("out of memory"); winsetdump(wbox, "/acme/mail", cmd); mbox.w = wbox; mesgmenu(wbox, &mbox); winclean(wbox); /* wctlfd = open("/dev/wctl", OWRITE|OCEXEC); /* for acme window */ wctlfd = -1; cplumb = chancreate(sizeof(Plumbmsg*), 0); cplumbshow = chancreate(sizeof(Plumbmsg*), 0); if(strcmp(name, "mbox") == 0){ /* * Avoid creating multiple windows to send mail by only accepting * sendmail plumb messages if we're reading the main mailbox. */ plumbsendmailfd = plumbopenfid("sendmail", OREAD|OCEXEC); cplumbsend = chancreate(sizeof(Plumbmsg*), 0); proccreate(plumbsendproc, nil, STACK); threadcreate(plumbsendthread, nil, STACK); } /* start plumb reader as separate proc ... */ proccreate(plumbproc, nil, STACK); proccreate(plumbshowproc, nil, STACK); threadcreate(plumbshowthread, nil, STACK); fswrite(mbox.ctlfd, "refresh", 7); /* ... and use this thread to read the messages */ plumbthread(); }
void syscallfmt(int syscallno, ulong pc, va_list list) { long l; Fmt fmt; void *v; vlong vl; uintptr p; int i[2], len; char *a, **argv; fmtstrinit(&fmt); fmtprint(&fmt, "%uld %s ", up->pid, up->text); if(syscallno > nsyscall) fmtprint(&fmt, " %d ", syscallno); else fmtprint(&fmt, "%s ", sysctab[syscallno]? sysctab[syscallno]: "huh?"); fmtprint(&fmt, "%ulx ", pc); if(up->syscalltrace != nil) free(up->syscalltrace); switch(syscallno){ case SYSR1: p = va_arg(list, uintptr); fmtprint(&fmt, "%#p", p); break; case _ERRSTR: /* deprecated */ case CHDIR: case EXITS: case REMOVE: a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case BIND: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux", i[0]); break; case CLOSE: case NOTED: i[0] = va_arg(list, int); fmtprint(&fmt, "%d", i[0]); break; case DUP: i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %d", i[0], i[1]); break; case ALARM: l = va_arg(list, unsigned long); fmtprint(&fmt, "%#lud ", l); break; case EXEC: a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); argv = va_arg(list, char**); evenaddr(PTR2UINT(argv)); for(;;){ validaddr((ulong)argv, sizeof(char**), 0); a = *(char **)argv; if(a == nil) break; fmtprint(&fmt, " "); fmtuserstring(&fmt, a, ""); argv++; } break; case _FSESSION: /* deprecated */ case _FSTAT: /* deprecated */ case _FWSTAT: /* obsolete */ i[0] = va_arg(list, int); a = va_arg(list, char*); fmtprint(&fmt, "%d %#p", i[0], a); break; case FAUTH: i[0] = va_arg(list, int); a = va_arg(list, char*); fmtprint(&fmt, "%d", i[0]); fmtuserstring(&fmt, a, ""); break; case SEGBRK: case RENDEZVOUS: v = va_arg(list, void*); fmtprint(&fmt, "%#p ", v); v = va_arg(list, void*); fmtprint(&fmt, "%#p", v); break; case _MOUNT: /* deprecated */ i[0] = va_arg(list, int); fmtprint(&fmt, "%d ", i[0]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux ", i[0]); a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case OPEN: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux", i[0]); break; case OSEEK: /* deprecated */ i[0] = va_arg(list, int); l = va_arg(list, long); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]); break; case SLEEP: l = va_arg(list, long); fmtprint(&fmt, "%ld", l); break; case _STAT: /* obsolete */ case _WSTAT: /* obsolete */ a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); a = va_arg(list, char*); fmtprint(&fmt, "%#p", a); break; case RFORK: i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux", i[0]); break; case PIPE: case BRK_: v = va_arg(list, int*); fmtprint(&fmt, "%#p", v); break; case CREATE: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%#ux %#ux", i[0], i[1]); break; case FD2PATH: case FSTAT: case FWSTAT: i[0] = va_arg(list, int); a = va_arg(list, char*); l = va_arg(list, unsigned long); fmtprint(&fmt, "%d %#p %lud", i[0], a, l); break; case NOTIFY: case SEGDETACH: case _WAIT: /* deprecated */ v = va_arg(list, void*); fmtprint(&fmt, "%#p", v); break; case SEGATTACH: i[0] = va_arg(list, int); fmtprint(&fmt, "%d ", i[0]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); /*FALLTHROUGH*/ case SEGFREE: case SEGFLUSH: v = va_arg(list, void*); l = va_arg(list, unsigned long); fmtprint(&fmt, "%#p %lud", v, l); break; case UNMOUNT: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case SEMACQUIRE: case SEMRELEASE: v = va_arg(list, int*); i[0] = va_arg(list, int); fmtprint(&fmt, "%#p %d", v, i[0]); break; // case TSEMACQUIRE: // v = va_arg(list, long*); // l = va_arg(list, ulong); // fmtprint(&fmt, "%#p %ld", v, l); // break; case SEEK: v = va_arg(list, vlong*); i[0] = va_arg(list, int); vl = va_arg(list, vlong); i[1] = va_arg(list, int); fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]); break; case FVERSION: i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %d ", i[0], i[1]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); l = va_arg(list, unsigned long); fmtprint(&fmt, "%lud", l); break; case WSTAT: case STAT: a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); /*FALLTHROUGH*/ case ERRSTR: case AWAIT: a = va_arg(list, char*); l = va_arg(list, unsigned long); fmtprint(&fmt, "%#p %lud", a, l); break; case MOUNT: i[0] = va_arg(list, int); i[1] = va_arg(list, int); fmtprint(&fmt, "%d %d ", i[0], i[1]); a = va_arg(list, char*); fmtuserstring(&fmt, a, " "); i[0] = va_arg(list, int); fmtprint(&fmt, "%#ux ", i[0]); a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); break; case _READ: /* deprecated */ case PREAD: i[0] = va_arg(list, int); v = va_arg(list, void*); l = va_arg(list, long); fmtprint(&fmt, "%d %#p %ld", i[0], v, l); if(syscallno == PREAD){ vl = va_arg(list, vlong); fmtprint(&fmt, " %lld", vl); } break; case _WRITE: /* deprecated */ case PWRITE: i[0] = va_arg(list, int); v = va_arg(list, void*); l = va_arg(list, long); fmtprint(&fmt, "%d ", i[0]); len = MIN(l, 64); fmtrwdata(&fmt, v, len, " "); fmtprint(&fmt, "%ld", l); if(syscallno == PWRITE){ vl = va_arg(list, vlong); fmtprint(&fmt, " %lld", vl); } break; } up->syscalltrace = fmtstrflush(&fmt); }
void sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop) { long l; void* v; Fmt fmt; vlong vl; int i, len; char *a, *errstr; fmtstrinit(&fmt); if(up->syscalltrace) free(up->syscalltrace); errstr = "\"\""; switch(syscallno){ default: case ALARM: case _WRITE: case PWRITE: if(ret == -1) errstr = up->syserrstr; fmtprint(&fmt, " = %ld", ret); break; case EXEC: case SEGBRK: case SEGATTACH: case RENDEZVOUS: if((void *)ret == (void*)-1) errstr = up->syserrstr; fmtprint(&fmt, " = %#p", (void *)ret); break; case AWAIT: a = va_arg(list, char*); l = va_arg(list, unsigned long); if(ret > 0){ fmtuserstring(&fmt, a, " "); fmtprint(&fmt, "%lud = %ld", l, ret); } else{ fmtprint(&fmt, "%#p/\"\" %lud = %ld", a, l, ret); errstr = up->syserrstr; } break; case _ERRSTR: case ERRSTR: a = va_arg(list, char*); if(syscallno == _ERRSTR) l = 64; else l = va_arg(list, unsigned long); if(ret > 0){ fmtuserstring(&fmt, a, " "); fmtprint(&fmt, "%lud = %ld", l, ret); } else{ fmtprint(&fmt, "\"\" %lud = %ld", l, ret); errstr = up->syserrstr; } break; case FD2PATH: i = va_arg(list, int); USED(i); a = va_arg(list, char*); l = va_arg(list, unsigned long); if(ret > 0){ fmtuserstring(&fmt, a, " "); fmtprint(&fmt, "%lud = %ld", l, ret); } else{ fmtprint(&fmt, "\"\" %lud = %ld", l, ret); errstr = up->syserrstr; } break; case _READ: case PREAD: i = va_arg(list, int); USED(i); v = va_arg(list, void*); l = va_arg(list, long); if(ret > 0){ len = MIN(ret, 64); fmtrwdata(&fmt, v, len, ""); } else{ fmtprint(&fmt, "/\"\""); errstr = up->syserrstr; } fmtprint(&fmt, " %ld", l); if(syscallno == PREAD){ vl = va_arg(list, vlong); fmtprint(&fmt, " %lld", vl); } fmtprint(&fmt, " = %ld", ret); break; } fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop); up->syscalltrace = fmtstrflush(&fmt); }
void sysretfmt(int syscallno, Ar0* ar0, uint64_t start, uint64_t stop, ...) { Proc *up = externup(); va_list list; int32_t l; void* v; Fmt fmt; int64_t vl; int i, len; char *a, *errstr; fmtstrinit(&fmt); va_start(list, stop); if(up->syscalltrace) free(up->syscalltrace); up->syscalltrace = nil; errstr = "\"\""; switch(syscallno){ default: if(ar0->i == -1) errstr = up->errstr; fmtprint(&fmt, " = %d", ar0->i); break; case AWAKE: if(ar0->vl == 0) errstr = up->errstr; fmtprint(&fmt, " = %lld", ar0->vl); break; case SEEK: if(ar0->vl == -1) errstr = up->errstr; fmtprint(&fmt, " = %lld", ar0->vl); break; case NSEC: fmtprint(&fmt, " = %lld", ar0->vl); break; case ALARM: case WRITE: case PWRITE: if(ar0->l == -1) errstr = up->errstr; fmtprint(&fmt, " = %ld", ar0->l); break; case EXEC: case SEGBRK: case SEGATTACH: case RENDEZVOUS: if(ar0->v == (void*)-1) errstr = up->errstr; fmtprint(&fmt, " = %#p", ar0->v); break; case AWAIT: a = va_arg(list, char*); l = va_arg(list, unsigned long); if(ar0->i > 0){ fmtuserstring(&fmt, a, " "); fmtprint(&fmt, "%lud = %d", l, ar0->i); } else{ fmtprint(&fmt, "%#p/\"\" %lud = %d", a, l, ar0->i); errstr = up->errstr; } break; case ERRSTR: a = va_arg(list, char*); l = va_arg(list, unsigned long); if(ar0->i > 0){ fmtuserstring(&fmt, a, " "); fmtprint(&fmt, "%lud = %d", l, ar0->i); } else{ fmtprint(&fmt, "\"\" %lud = %d", l, ar0->i); errstr = up->errstr; } break; case FD2PATH: i = va_arg(list, int); USED(i); a = va_arg(list, char*); l = va_arg(list, unsigned long); if(ar0->i > 0){ fmtuserstring(&fmt, a, " "); fmtprint(&fmt, "%lud = %d", l, ar0->i); } else{ fmtprint(&fmt, "\"\" %lud = %d", l, ar0->i); errstr = up->errstr; } break; case READ: case PREAD: i = va_arg(list, int); USED(i); v = va_arg(list, void*); l = va_arg(list, int32_t); if(ar0->l > 0){ len = MIN(ar0->l, 64); fmtrwdata(&fmt, v, len, ""); } else{ fmtprint(&fmt, "/\"\""); errstr = up->errstr; } fmtprint(&fmt, " %ld", l); if(syscallno == PREAD){ vl = va_arg(list, int64_t); fmtprint(&fmt, " %lld", vl); } fmtprint(&fmt, " = %d", ar0->i); break; } fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop); up->syscalltrace = fmtstrflush(&fmt); }
void deadcode(void) { int i; Sym *s, *last, *p; Auto *z; Fmt fmt; if(debug['v']) Bprint(&bso, "%5.2f deadcode\n", cputime()); mark(lookup(INITENTRY, 0)); for(i=0; i<nelem(markextra); i++) mark(lookup(markextra[i], 0)); for(i=0; i<ndynexp; i++) mark(dynexp[i]); markflood(); // keep each beginning with 'typelink.' if the symbol it points at is being kept. for(s = allsym; s != S; s = s->allsym) { if(strncmp(s->name, "go.typelink.", 12) == 0) s->reachable = s->nr==1 && s->r[0].sym->reachable; } // remove dead text but keep file information (z symbols). last = nil; z = nil; for(s = textp; s != nil; s = s->next) { if(!s->reachable) { if(isz(s->autom)) z = s->autom; continue; } if(last == nil) textp = s; else last->next = s; last = s; if(z != nil) { if(!isz(s->autom)) addz(s, z); z = nil; } } if(last == nil) textp = nil; else last->next = nil; for(s = allsym; s != S; s = s->allsym) if(strncmp(s->name, "go.weak.", 8) == 0) { s->special = 1; // do not lay out in data segment s->reachable = 1; s->hide = 1; } // record field tracking references fmtstrinit(&fmt); for(s = allsym; s != S; s = s->allsym) { if(strncmp(s->name, "go.track.", 9) == 0) { s->special = 1; // do not lay out in data segment s->hide = 1; if(s->reachable) { fmtprint(&fmt, "%s", s->name+9); for(p=s->reachparent; p; p=p->reachparent) fmtprint(&fmt, "\t%s", p->name); fmtprint(&fmt, "\n"); } s->type = SCONST; s->value = 0; } } if(tracksym == nil) return; s = lookup(tracksym, 0); if(!s->reachable) return; addstrdata(tracksym, fmtstrflush(&fmt)); }