int help_cmdfunc(int argc, char *argv[]) { const command_list_t *cmdlist = get_current_commands(); const command_t *cmd; const char *name = 0; int found, i, spaces; char abbrev; if (argc > 2) return -H_EUSAGE; if (argc == 2) name = *++argv; for (found=0, i=0; (cmd = cmdlist->commands[i]); ++i) { if (name && strcmp(name, cmd->name)) continue; found = 1; spaces = 30; if ((abbrev = find_abbrev(cmdlist, cmd))) spaces -= hprintf("%c ", abbrev); else spaces -= hprint(" "); spaces -= hprint(cmd->name); if (cmd->arghelp) spaces -= hprintf(" %s", cmd->arghelp); for (/* nothing */; spaces > 0; --spaces) hputchar(' '); hprintf(": %s\n", cmd->cmdhelp); } if (name && !found) return -H_ENOCMD; return 0; }
static int dindex(HConnect *c) { Hio *hout; Index *ix; int i, r; r = hsettext(c); if(r < 0) return r; hout = &c->hout; ix = mainindex; hprint(hout, "index=%s version=%d blocksize=%d tabsize=%d\n", ix->name, ix->version, ix->blocksize, ix->tabsize); hprint(hout, "\tbuckets=%d div=%d\n", ix->buckets, ix->div); for(i = 0; i < ix->nsects; i++) hprint(hout, "\tsect=%s for buckets [%lld,%lld) buckmax=%d\n", ix->smap[i].name, ix->smap[i].start, ix->smap[i].stop, ix->sects[i]->buckmax); for(i = 0; i < ix->narenas; i++){ if(ix->arenas[i] != nil && ix->arenas[i]->memstats.clumps != 0){ hprint(hout, "arena=%s at index [%lld,%lld)\n\t", ix->amap[i].name, ix->amap[i].start, ix->amap[i].stop); darena(hout, ix->arenas[i]); } } hflush(hout); return 0; }
int hsettype(HConnect *c, char *type) { Hio *hout; int r; r = preq(c); if(r < 0) return r; hout = &c->hout; if(c->req.vermaj){ hokheaders(c); hprint(hout, "Content-type: %s\r\n", type); if(http11(c)) hprint(hout, "Transfer-Encoding: chunked\r\n"); hprint(hout, "\r\n"); } if(http11(c)) hxferenc(hout, 1); else c->head.closeit = 1; return 0; }
void hintprint(HConnect *hc, Hio *hout, char *uri, int thresh, int havej) { int i, j, pr, prefix, fd, siz, havei, newhint = 0, n; char *query, *sf, etag[32], *wurl; Dir *dir; Hint *h, *haveh; query = hstrdup(hc, uri); urlcanon(query); j = urllookup(hashstr(query)); if(j < 0) return; query = strrchr(uri,'/'); if(!query) return; /* can't happen */ prefix = query-uri+1; /* = strlen(dirname)+1 */ h = hints[j]; for(i=0; i<nhint[j]; i++){ if(havej > 0 && havej < URLmax){ /* exclude hints client has */ haveh = hints[havej]; for(havei=0; havei<nhint[havej]; havei++) if( haveh[havei].url == h[i].url) goto continuei; } sf = urlname[h[i].url]; pr = h[i].prob; if(pr<thresh) break; n = strlen(webroot) + strlen(sf) + 1; wurl = halloc(hc, n); strcpy(wurl, webroot); strcat(wurl, sf); fd = open(wurl, OREAD); if(fd<0) continue; dir = dirfstat(fd); if(dir == nil){ close(fd); continue; } close(fd); snprint(etag, sizeof(etag), "\"%lluxv%lx\"", dir->qid.path, dir->qid.vers); siz = (int)( log((double)dir->length) * RECIPLOG2 + 0.9999); free(dir); if(strncmp(uri,sf,prefix)==0 && strchr(sf+prefix,'/')==0 && sf[prefix]!=0) sf = sf+prefix; hprint(hout, "Fresh: %d,%s,%d,%s\r\n", pr, etag, siz, sf); newhint++; continuei: ; } if(newhint) hprint(hout, "Fresh: have/%d\r\n", j); }
static void printtype(Hio *hout, HContent *type, HContent *enc) { hprint(hout, "Content-Type: %s/%s", type->generic, type->specific); /* if(cistrcmp(type->generic, "text") == 0) hprint(hout, ";charset=utf-8"); */ hprint(hout, "\r\n"); if(enc != nil) hprint(hout, "Content-Encoding: %s\r\n", enc->generic); }
static void debugamap(HConnect *c) { int i; AMap *amap; hprint(&c->hout, "<h2>arena map</h2>\n"); hprint(&c->hout, "<pre>\n"); amap = mainindex->amap; for(i=0; i<mainindex->narenas; i++) hprint(&c->hout, "%s %#llx %#llx\n", amap[i].name, amap[i].start, amap[i].stop); }
static void darena(Hio *hout, Arena *arena) { hprint(hout, "arena='%s' on %s at [%lld,%lld)\n\tversion=%d created=%d modified=%d", arena->name, arena->part->name, arena->base, arena->base + arena->size + 2 * arena->blocksize, arena->version, arena->ctime, arena->wtime); if(arena->memstats.sealed) hprint(hout, " mem=sealed"); if(arena->diskstats.sealed) hprint(hout, " disk=sealed"); if(arena->inqueue) hprint(hout, " inqueue"); hprint(hout, "\n"); if(scorecmp(zeroscore, arena->score) != 0) hprint(hout, "\tscore=%V\n", arena->score); hprint(hout, "\twritten: clumps=%d compressed clumps=%d data=%,lld compressed data=%,lld storage=%,lld\n", arena->memstats.clumps, arena->memstats.cclumps, arena->memstats.uncsize, arena->memstats.used - arena->memstats.clumps * ClumpSize, arena->memstats.used + arena->memstats.clumps * ClumpInfoSize); hprint(hout, "\tindexed: clumps=%d compressed clumps=%d data=%,lld compressed data=%,lld storage=%,lld\n", arena->diskstats.clumps, arena->diskstats.cclumps, arena->diskstats.uncsize, arena->diskstats.used - arena->diskstats.clumps * ClumpSize, arena->diskstats.used + arena->diskstats.clumps * ClumpInfoSize); }
/* * write initial part of successful header */ void hokheaders(HConnect *c) { Hio *hout; hout = &c->hout; hprint(hout, "%s 200 OK\r\n", hversion); hprint(hout, "Server: Plan9\r\n"); hprint(hout, "Date: %D\r\n", time(nil)); if(c->head.closeit) hprint(hout, "Connection: close\r\n"); else if(!http11(c)) hprint(hout, "Connection: Keep-Alive\r\n"); }
static void memsize_820() { int i, n, nr; struct e820entry nm[E820MAX]; unsigned long long start; unsigned long long end; /* Clean up, adjust and copy the BIOS-supplied E820-map. */ nr = sanitize_e820_map(e820, nm, e820_nr); /* If there is not a good 820 map use the BIOS 801/88 info */ if (nr < 1 || nr > E820MAX) { memsize_801(); return; } /* Build the memory map for testing */ n = 0; for (i=0; i<nr; i++) { if (nm[i].type == E820_RAM || nm[i].type == E820_ACPI) { start = nm[i].addr; end = start + nm[i].size; /* Don't ever use memory between 640 and 1024k */ if (start > RES_START && start < RES_END) { if (end < RES_END) { continue; } start = RES_END; } if (end > RES_START && end < RES_END) { end = RES_START; } v->pmap[n].start = (start + 4095) >> 12; v->pmap[n].end = end >> 12; v->test_pages += v->pmap[n].end - v->pmap[n].start; n++; #if 0 int epmap = 0; int lpmap = 0; if(n > 12) { epmap = 34; lpmap = -12; } hprint (11+n+lpmap,0+epmap,v->pmap[n-1].start); hprint (11+n+lpmap,10+epmap,v->pmap[n-1].end); hprint (11+n+lpmap,20+epmap,v->pmap[n-1].end - v->pmap[n-1].start); dprint (11+n+lpmap,30+epmap,nm[i].type,0,0); #endif } }
static vlong findintoc(HConnect *c, Arena *arena, uchar *score) { uchar *blk; int i; vlong off; vlong coff; ClumpInfo ci; blk = vtmalloc(arena->blocksize); off = arena->base + arena->size; coff = 0; for(i=0; i<arena->memstats.clumps; i++){ if(i%arena->clumpmax == 0){ off -= arena->blocksize; if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){ if(c) hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n", off); break; } } unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize); if(scorecmp(ci.score, score) == 0){ vtfree(blk); return coff; } coff += ClumpSize + ci.size; } vtfree(blk); return -1; }
void xmlscore(Hio *hout, u8int *v, char *tag) { if(scorecmp(zeroscore, v) == 0) return; hprint(hout, " %s=\"%V\"", tag, v); }
void xmlsealed(Hio *hout, int v, char *tag) { if(!v) return; hprint(hout, " %s=\"yes\"", tag); }
static void dotextbin(Hio *io, Graph *g) { int i, nbin; Statbin *b, bin[2000]; /* 32 kB, but whack is worse */ needstack(8192); /* double check that bin didn't kill us */ nbin = 100; binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin); hprint(io, "stats\n\n"); for(i=0; i<nbin; i++){ b = &bin[i]; hprint(io, "%d: nsamp=%d min=%d max=%d avg=%d\n", i, b->nsamp, b->min, b->max, b->avg); } }
static int diskarenatoc(HConnect *c, Arena *arena) { uchar *blk; int i; vlong off; vlong coff; ClumpInfo ci; char base[512]; int cib; snprint(base, sizeof base, "/disk?disk=%s&type=a&arena=%s", arena->part->name, arena->name); blk = vtmalloc(arena->blocksize); off = arena->base + arena->size; hprint(&c->hout, "<h2>table of contents</h2>\n"); hprint(&c->hout, "<pre>\n"); hprint(&c->hout, "%5s %6s %7s %s\n", "type", "size", "uncsize", "score"); coff = 0; cib = hargint(c, "cib", 0); for(i=0; i<arena->memstats.clumps; i++){ if(i%arena->clumpmax == 0){ off -= arena->blocksize; if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){ hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n", off); i += arena->clumpmax-1; coff = -1; continue; } } unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize); if(i/arena->clumpmax == cib || i%arena->clumpmax == 0){ hprint(&c->hout, "%5d %6d %7d %V", ci.type, ci.size, ci.uncsize, ci.score); if(coff >= 0) hprint(&c->hout, " at <a href=\"%s&clump=%#llx&score=%V\">%#llx</a>", base, coff, ci.score, coff); if(i/arena->clumpmax != cib) hprint(&c->hout, " <font size=-1><a href=\"%s&cib=%d\">more</a></font>", base, i/arena->clumpmax); hprint(&c->hout, "\n"); } if(coff >= 0) coff += ClumpSize + ci.size; } hprint(&c->hout, "</pre>\n"); return 0; }
static int disksummary(HConnect *c) { int i; Index *ix; Part *p; hprint(&c->hout, "<h1>venti disks</h1>\n"); hprint(&c->hout, "<pre>\n"); ix = mainindex; p = nil; for(i=0; i<ix->narenas; i++){ if(ix->arenas[i]->part == p) continue; p = ix->arenas[i]->part; hprint(&c->hout, "<a href=\"/disk?disk=%s&type=a\">%s</a> %s\n", p->name, p->name, ix->arenas[i]->name); } hprint(&c->hout, "\n"); p = nil; for(i=0; i<ix->nsects; i++){ if(ix->sects[i]->part == p) continue; p = ix->sects[i]->part; hprint(&c->hout, "<a href=\"/disk?disk=%s&type=i\">%s</a> %s\n", p->name, p->name, ix->sects[i]->name); } hprint(&c->hout, "\n"); if(ix->bloom){ p = ix->bloom->part; hprint(&c->hout, "<a href=\"/disk?disk=%s&type=b\">%s</a> %s\n", p->name, p->name, "bloom filter"); } return 0; }
void redirectto(char *uri) { if(connect){ hmoved(connect, uri); exits(0); }else hprint(hout, "Your selection moved to <a href=\"%U\"> here</a>.<p></body>\r\n", uri); }
int main(void) { HashTable H = InitializeTable(17); srand(time(NULL)); for (int i = 0; i < 8; i++) { int ins = rand() % 100; printf("%d ---->\n", ins); Insert(ins, H); } printf("<----------------->\n"); hprint(H); printf("<----------------->\n"); H = Rehash(H); hprint(H); return 0; }
void man(char *o, int sect, int vermaj) { int i; Hit *list; list = nil; if(*o == 0){ manindex(sect, vermaj); return; } if(sect > 0 && sect < 10) lookup(o, sect, &list); else for(i = 1; i < 9; i++) lookup(o, i, &list); if(list != nil && list->next == nil){ doconvert(list->file, vermaj); return; } if(vermaj){ hokheaders(connect); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } hprint(hout, "<head><title>plan 9 man %H", o); if(sect) hprint(hout, "(%d)\n", sect); hprint(hout, "</title></head><body>\n"); hprint(hout, "<H6>Search for %H", o); if(sect) hprint(hout, "(%d)\n", sect); hprint(hout, "</H6>\n"); for(; list; list = list->next) hprint(hout, "<p><a href=\"/magic/man2html%U\">/magic/man2html%H</a>\n", list->file, list->file); hprint(hout, "</body>\n"); }
static int sindex(HConnect *c) { Hio *hout; Index *ix; Arena *arena; vlong clumps, cclumps, uncsize, used, size; int i, r, active; r = hsettext(c); if(r < 0) return r; hout = &c->hout; ix = mainindex; hprint(hout, "index=%s\n", ix->name); active = 0; clumps = 0; cclumps = 0; uncsize = 0; used = 0; size = 0; for(i = 0; i < ix->narenas; i++){ arena = ix->arenas[i]; if(arena != nil && arena->memstats.clumps != 0){ active++; clumps += arena->memstats.clumps; cclumps += arena->memstats.cclumps; uncsize += arena->memstats.uncsize; used += arena->memstats.used; } size += arena->size; } hprint(hout, "total arenas=%,d active=%,d\n", ix->narenas, active); hprint(hout, "total space=%,lld used=%,lld\n", size, used + clumps * ClumpInfoSize); hprint(hout, "clumps=%,lld compressed clumps=%,lld data=%,lld compressed data=%,lld\n", clumps, cclumps, uncsize, used - clumps * ClumpSize); hflush(hout); return 0; }
int hdebug(HConnect *c) { char *scorestr, *op; u8int score[VtScoreSize]; if(hsethtml(c) < 0) return -1; hprint(&c->hout, "<h1>venti debug</h1>\n"); op = hargstr(c, "op", ""); if(!op[0]){ hprint(&c->hout, "no op\n"); return 0; } if(strcmp(op, "amap") == 0){ debugamap(c); return 0; } if(strcmp(op, "mem") == 0){ debugmem(c); return 0; } if(strcmp(op, "read") == 0){ scorestr = hargstr(c, "score", ""); if(vtparsescore(scorestr, nil, score) < 0){ hprint(&c->hout, "bad score %s: %r\n", scorestr); return 0; } debugread(c, score); return 0; } hprint(&c->hout, "unknown op %s", op); return 0; }
static int xset(HConnect *c) { int i, old; char *name, *value; if(hsettext(c) < 0) return -1; if((name = hargstr(c, "name", nil)) == nil || name[0] == 0){ for(i=0; namedints[i].name; i++) hprint(&c->hout, "%s = %d\n", namedints[i].name, *namedints[i].p); hflush(&c->hout); return 0; } for(i=0; namedints[i].name; i++) if(strcmp(name, namedints[i].name) == 0) break; if(!namedints[i].name){ hprint(&c->hout, "%s not found\n", name); hflush(&c->hout); return 0; } if((value = hargstr(c, "value", nil)) == nil || value[0] == 0){ hprint(&c->hout, "%s = %d\n", namedints[i].name, *namedints[i].p); hflush(&c->hout); return 0; } old = *namedints[i].p; *namedints[i].p = atoll(value); hprint(&c->hout, "%s = %d (was %d)\n", name, *namedints[i].p, old); hflush(&c->hout); return 0; }
int hdisk(HConnect *c) { char *disk, *type; Part *p; int ret; if(hsethtml(c) < 0) return -1; disk = hargstr(c, "disk", ""); if(!disk[0]) return disksummary(c); if((p = initpart(disk, OREAD)) == nil){ hprint(&c->hout, "open %s: %r", disk); return 0; } type = hargstr(c, "type", ""); switch(type[0]){ case 'a': ret = diskarenapart(c, disk, p); break; case 'b': ret = diskbloom(c, disk, p); break; case 'i': ret = diskisect(c, disk, p); break; default: hprint(&c->hout, "unknown disk type %s", type); return 0; } freepart(p); return ret; }
void vtloghdump(Hio *h, VtLog *l) { int i; VtLogChunk *c; char *name; name = l ? l->name : "<nil>"; hprint(h, "<html><head>\n"); hprint(h, "<title>Venti Server Log: %s</title>\n", name); hprint(h, "</head><body>\n"); hprint(h, "<b>Venti Server Log: %s</b>\n<p>\n", name); if(l){ c = l->w; for(i=0; i<l->nchunk; i++){ if(++c == l->chunk+l->nchunk) c = l->chunk; hwrite(h, c->p, c->wp-c->p); } } hprint(h, "</body></html>\n"); }
static int hdcacheflush(HConnect *c) { Hio *hout; int r; r = hsettext(c); if(r < 0) return r; hout = &c->hout; flushdcache(); hprint(hout, "flushed dcache\n"); hflush(hout); return 0; }
static int hicachekick(HConnect *c) { Hio *hout; int r; r = hsettext(c); if(r < 0) return r; hout = &c->hout; kickicache(); hprint(hout, "kicked icache\n"); hflush(hout); return 0; }
static int hicacheempty(HConnect *c) { Hio *hout; int r; r = hsettext(c); if(r < 0) return r; hout = &c->hout; emptyicache(); hprint(hout, "emptied icache\n"); hflush(hout); return 0; }
void kick_cpu(unsigned cpu_num) { unsigned num_sipi, apic_id; apic_id = cpu_num_to_apic_id[cpu_num]; // clear the APIC ESR register APIC_WRITE(APICR_ESR, 0); APIC_READ(APICR_ESR); // asserting the INIT IPI SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); delay(100000 / DELAY_FACTOR); // de-assert the INIT IPI SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); for (num_sipi = 0; num_sipi < 2; num_sipi++) { unsigned timeout; bool send_pending; unsigned err; APIC_WRITE(APICR_ESR, 0); SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, (unsigned)startup_32 >> 12); timeout = 0; do { delay(10); timeout++; send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; } while (send_pending && timeout < 1000); if (send_pending) { cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); } delay(100000 / DELAY_FACTOR); err = APIC_READ(APICR_ESR) & 0xef; if (err) { cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); hprint(LINE_STATUS+3, COL_MID, err); } } }
void error(char *title, char *fmt, ...) { va_list arg; char buf[1024], *out; va_start(arg, fmt); out = vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); *out = 0; hprint(hout, "%s 404 %s\n", hversion, title); hprint(hout, "Date: %D\n", time(nil)); hprint(hout, "Server: Plan9\n"); hprint(hout, "Content-type: text/html\n"); hprint(hout, "\n"); hprint(hout, "<head><title>%s</title></head>\n", title); hprint(hout, "<body><h1>%s</h1></body>\n", title); hprint(hout, "%s\n", buf); hflush(hout); writelog(connect, "Reply: 404\nReason: %s\n", title); exits(nil); }
/* * send back a nice error message if the content is unacceptable * to get this message in ie, go to tools, internet options, advanced, * and turn off Show Friendly HTTP Error Messages under the Browsing category */ static int notaccept(HConnect *c, HContent *type, HContent *enc, char *which) { Hio *hout; char *s, *e; hout = &c->hout; e = &c->xferbuf[HBufSize]; s = c->xferbuf; s = seprint(s, e, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"); s = seprint(s, e, "<html>\n<title>Unacceptable %s</title>\n<body>\n", which); s = seprint(s, e, "Your browser will not accept this data, %H, because of its %s.<br>\n", c->req.uri, which); s = seprint(s, e, "Its Content-Type is %s/%s", type->generic, type->specific); if(enc != nil) s = seprint(s, e, ", and Content-Encoding is %s", enc->generic); s = seprint(s, e, ".<br>\n\n"); s = acceptcont(s, e, c->head.oktype, "Content-Type"); s = acceptcont(s, e, c->head.okencode, "Content-Encoding"); s = seprint(s, e, "</body>\n</html>\n"); hprint(hout, "%s 406 Not Acceptable\r\n", hversion); hprint(hout, "Server: Plan9\r\n"); hprint(hout, "Date: %D\r\n", time(nil)); hprint(hout, "Content-Type: text/html\r\n"); hprint(hout, "Content-Length: %lud\r\n", s - c->xferbuf); if(c->head.closeit) hprint(hout, "Connection: close\r\n"); else if(!http11(c)) hprint(hout, "Connection: Keep-Alive\r\n"); hprint(hout, "\r\n"); if(strcmp(c->req.meth, "HEAD") != 0) hwrite(hout, c->xferbuf, s - c->xferbuf); writelog(c, "Reply: 406 Not Acceptable\nReason: %s\n", which); return hflush(hout); }
static int herror(HConnect *c) { int n; Hio *hout; hout = &c->hout; n = snprint(c->xferbuf, HBufSize, "<html><head><title>Error</title></head>\n<body><h1>Error</h1>\n<pre>%r</pre>\n</body></html>"); hprint(hout, "%s %s\r\n", hversion, "400 Bad Request"); hprint(hout, "Date: %D\r\n", time(nil)); hprint(hout, "Server: Venti\r\n"); hprint(hout, "Content-Type: text/html\r\n"); hprint(hout, "Content-Length: %d\r\n", n); if(c->head.closeit) hprint(hout, "Connection: close\r\n"); else if(!http11(c)) hprint(hout, "Connection: Keep-Alive\r\n"); hprint(hout, "\r\n"); if(c->req.meth == nil || strcmp(c->req.meth, "HEAD") != 0) hwrite(hout, c->xferbuf, n); return hflush(hout); }