void statsinit(void) { static Biobuf *b = nil; static int64_t filelen = 0; int64_t newlen; int iq, n, i, nstats = 0; uint8_t *s, buf[3+HINTmax*3]; /* iq, n, (url,prob)... */ Hint *arena, *h; char *file; static void *oldarena = nil; file = "/sys/log/httpd/pathstat"; if(b == nil){ if(filelen == -1) return; /* if failed first time */ b = Bopen(file, OREAD); /* first time */ if(b == nil){ syslog(0, HTTPLOG, "no %s, abandon prefetch hints", file); filelen = -1; return; } } newlen = Bfilelen(b); /* side effect: rewinds b */ if(newlen == filelen || Bage(b)<300) return; filelen = newlen; if(oldarena){ free(oldarena); memset(nhint,0,sizeof nhint); } arena = (Hint*)ezalloc((filelen/3)*sizeof(Hint)); oldarena = arena; for(;;){ i = Bread(b,buf,3); if(i<3) break; nstats++; iq = buf[0]; iq = (iq<<8) | buf[1]; n = buf[2]; h = arena; arena += n; hints[iq] = h; nhint[iq] = n; if(Bread(b,buf,3*n)!=3*n) sysfatal("stats read error"); for(i=0; i<n; i++){ s = &buf[3*i]; h[i].url = (s[0]<<8) | s[1]; h[i].prob = s[2]; } } syslog(0, HTTPLOG, "prefetch-hints stats=%d (%.1fMB)", nstats, 1.e-6*((filelen/3)*sizeof(Hint))); }
int _read5(Biobuf *bp, Prog *p) { int as, n; Addr a; as = BGETC(bp); /* as */ if(as < 0) return 0; p->kind = aNone; p->sig = 0; if(as == ANAME || as == ASIGNAME){ if(as == ASIGNAME){ Bread(bp, &p->sig, 4); p->sig = leswal(p->sig); } p->kind = aName; p->type = type2char(BGETC(bp)); /* type */ p->sym = BGETC(bp); /* sym */ n = 0; for(;;) { as = BGETC(bp); if(as < 0) return 0; n++; if(as == 0) break; } p->id = malloc(n); if(p->id == 0) return 0; Bseek(bp, -n, 1); if(Bread(bp, p->id, n) != n) return 0; return 1; } if(as == ATEXT) p->kind = aText; else if(as == AGLOBL) p->kind = aData; skip(bp, 6); /* scond(1), reg(1), lineno(4) */ a = addr(bp); addr(bp); if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN) p->kind = aNone; p->sym = a.sym; return 1; }
char* winreadbody(Window *w, int *np) /* can't use readfile because acme doesn't report the length */ { char *s; int m, na, n; if(w->body != nil) winclosebody(w); winopenbody(w, OREAD); s = nil; na = 0; n = 0; for(;;){ if(na < n+512){ na += 1024; s = realloc(s, na+1); } m = Bread(w->body, s+n, na-n); if(m <= 0) break; n += m; } s[n] = 0; winclosebody(w); *np = n; return s; }
int oreadblock(Ofile *f, int block, uint32_t off, char *buf, int nbuf) { int n; if(block < 0 || block >= f->nblock) { werrstr("attempt to read %x/%lx\n", block, f->nblock); return -1; } if(off >= Blocksize){ print("offset too far into block\n"); return 0; } if(off+nbuf > Blocksize) nbuf = Blocksize-off; /* blocks start numbering at -1 [sic] */ off += (block+1)*Blocksize; if(Bseek(f->b, off, 0) != off){ print("seek failed\n"); return -1; } n = Bread(f->b, buf, nbuf); if(n < 0) print("Bread failed: %r"); return n; }
static int macholoadrel(MachoObj *m, MachoSect *sect) { MachoRel *rel, *r; uchar *buf, *p; int i, n; uint32 v; if(sect->rel != nil || sect->nreloc == 0) return 0; rel = mal(sect->nreloc * sizeof r[0]); n = sect->nreloc * 8; buf = mal(n); if(Bseek(m->f, m->base + sect->reloff, 0) < 0 || Bread(m->f, buf, n) != n) return -1; for(i=0; i<sect->nreloc; i++) { r = &rel[i]; p = buf+i*8; r->addr = m->e->e32(p); // TODO(rsc): Wrong interpretation for big-endian bitfields? if(r->addr & 0x80000000) { // scatterbrained relocation r->scattered = 1; v = r->addr >> 24; r->addr &= 0xFFFFFF; r->type = v & 0xF; v >>= 4; r->length = 1<<(v&3); v >>= 2; r->pcrel = v & 1; r->value = m->e->e32(p+4); } else {
static int pswritepage(Document *d, int fd, int page) { Biobuf *b = d->b; PSInfo *ps = d->extra; int t, n, i; long begin, end; char buf[8192]; if(page == -1) begin = ps->psoff; else begin = ps->page[page].offset; end = ps->page[page+1].offset; if(chatty) { fprint(2, "writepage(%d)... from #%ld to #%ld...\n", page, begin, end); } Bseek(b, begin, 0); t = end-begin; n = sizeof(buf); if(n > t) n = t; while(t > 0 && (i=Bread(b, buf, n)) > 0) { if(write(fd, buf, i) != i) return -1; t -= i; if(n > t) n = t; } return end-begin; }
int wreadall(Win *w, char **sp) { char *s; int m, na, n; if(w->body != nil) Bterm(w->body); openbody(w, OREAD); s = nil; na = 0; n = 0; for(;;){ if(na < n+512){ na += 1024; s = erealloc(s, na+1); } m = Bread(w->body, s+n, na-n); if(m <= 0) break; n += m; } s[n] = 0; Bterm(w->body); w->body = nil; *sp = s; return n; }
Entry getentry(long b) { long e, n, dtop; static Entry ans; static int anslen = 0; e = (*dict->nextoff)(b+1); ans.doff = b; if(e < 0) { dtop = Bseek(bdict, 0L, 2); if(b < dtop) { e = dtop; } else { err("couldn't seek to entry"); ans.start = 0; ans.end = 0; } } n = e-b; if(n) { if(n > anslen) { ans.start = realloc(ans.start, n); if(!ans.start) { err("out of memory"); exits("nomem"); } anslen = n; } Bseek(bdict, b, 0); n = Bread(bdict, ans.start, n); ans.end = ans.start + n; } return ans; }
void texcache_setupmemcache(void) { if (!glusememcache || texcache.memcache.noalloc || !texcache_enabled()) return; texcache.memcache.size = Bfilelength(texcache.filehandle); if (texcache.memcache.size <= 0) return; texcache.memcache.ptr = (uint8_t *)Brealloc(texcache.memcache.ptr, texcache.memcache.size); if (!texcache.memcache.ptr) { initprintf("Failed allocating %d bytes for memcache, disabling memcache.\n", (int)texcache.memcache.size); texcache_clearmemcache(); texcache.memcache.noalloc = 1; return; } if (Bread(texcache.filehandle, texcache.memcache.ptr, texcache.memcache.size) != (bssize_t)texcache.memcache.size) { initprintf("Failed reading texcache into memcache!\n"); texcache_clearmemcache(); texcache.memcache.noalloc = 1; } }
int gsopen(Modem *m) { int n; char bytes[Gshdrsize]; /* * Is this gs output */ n = Bread(m->bp, bytes, Gshdrsize); if(n != Gshdrsize) return seterror(m, Esys); if(bytes[0]!='\0' || strcmp(bytes+1, "PC Research, Inc")!=0){ Bseek(m->bp, 0, 0); return seterror(m, Esys); } m->valid |= Vtype; if(bytes[0x1d]) m->vr = 1; else m->vr = 0; m->wd = 0; m->ln = 2; m->df = 0; return Eok; }
void texcache_syncmemcache(void) { int32_t len = Bfilelength(texcache.filehandle); if (!texcache.memcache.ptr || texcache.filehandle == -1 || len <= (int32_t)texcache.memcache.size) return; texcache.memcache.ptr = (uint8_t *)Brealloc(texcache.memcache.ptr, len); if (!texcache.memcache.ptr) { texcache_clearmemcache(); initprintf("Failed syncing memcache to texcache, disabling memcache.\n"); texcache.memcache.noalloc = 1; } else { initprintf("Syncing memcache to texcache\n"); Blseek(texcache.filehandle, texcache.memcache.size, BSEEK_SET); if (Bread(texcache.filehandle, texcache.memcache.ptr + texcache.memcache.size, len - texcache.memcache.size) != (bssize_t)(len-texcache.memcache.size)) { initprintf("polymost_cachesync: Failed reading texcache into memcache!\n"); texcache_clearmemcache(); texcache.memcache.noalloc = 1; } else { texcache.memcache.size = len; } } }
int Bgetheader(Biobuf *b, Header *h) { Icon *icon; int i; uint8_t buf[40]; memset(h, 0, sizeof(*h)); if(Bread(b, buf, 6) != 6) goto eof; if(gets(&buf[0]) != 0) goto header; if(gets(&buf[2]) != 1) goto header; h->n = gets(&buf[4]); for(i = 0; i < h->n; i++){ icon = mallocz(sizeof(*icon), 1); if(icon == nil) sysfatal("malloc: %r"); if(Bread(b, buf, 16) != 16) goto eof; icon->w = buf[0]; icon->h = buf[1]; icon->ncolor = buf[2] == 0 ? 256 : buf[2]; if(buf[3] != 0) goto header; icon->nplane = gets(&buf[4]); icon->bits = gets(&buf[6]); icon->len = getl(&buf[8]); icon->offset = getl(&buf[12]); if(i == 0) h->first = icon; else h->last->next = icon; h->last = icon; } return 0; eof: werrstr("unexpected EOF"); return -1; header: werrstr("unknown header format"); return -1; }
static Data* readdata(Biobuf *b) { Data *d; char str[32]; int32_t len; if(Bread(b, str, 12) != 12) panic("can't read data hdr\n"); len = atoi(str); d = emalloc(sizeof(*d) + len); if(Bread(b, d->data, len) != len) panic("can't read data body\n"); d->len = len; return d; }
void loadstate(char *file) { bp = Bopen(file, OREAD); if(bp == nil){ message("open: %r"); return; } Bread(bp, reg, sizeof(reg)); Bread(bp, mem, sizeof(mem)); Bread(bp, vram, sizeof(vram)); Bread(bp, oam, sizeof(oam)); Bread(bp, spcmem, sizeof(spcmem)); Bread(bp, dsp, sizeof(dsp)); get16s(cgram, nelem(cgram)); ppuclock = get32(); spcclock = get32(); dspclock = get32(); stimerclock = get32(); rA = get16(); rX = get16(); rY = get16(); rS = get16(); rP = get8(); rD = get16(); rDB = get8()<<16; pc = get16(); rPB = get8()<<16; emu = get8(); irq = get8(); nmi = get8(); dma = get8(); hdma = get32(); wai = get8(); mdr = get8(); mdr1 = get8(); mdr2 = get8(); oamaddr = get16(); vramlatch = get16(); keylatch = get32(); ppux = get16(); ppuy = get16(); htime = reg[0x4207] | reg[0x4208] << 8 & 0x100; vtime = reg[0x4209] | reg[0x420a] << 8 & 0x100; subcolor = get16(); get16s(hofs, nelem(hofs)); get16s(vofs, nelem(vofs)); get16s((u16int*) m7, nelem(m7)); sA = get8(); sX = get8(); sY = get8(); sS = get8(); sP = get8(); dspstate = get8(); dspcounter = get16(); noise = get16(); Bread(bp, spctimer, sizeof(spctimer)); dspload(); Bterm(bp); }
char * doread(Ram *r, int64_t off, int32_t cnt) { int i, err; Block bs; ZipHead zh; static Qid oqid; static char buf[Maxbuf]; static uint8_t *cache = nil; if (cnt > Maxbuf) sysfatal("file too big (>%d)", Maxbuf); if (Bseek(bin, r->addr & 0x7FFFFFFFFFFFFFFFLL, 0) < 0) sysfatal("seek failed"); memset(&zh, 0, sizeof(zh)); if (!header(bin, &zh)) sysfatal("cannot get local header"); switch(zh.meth){ case 0: if (Bseek(bin, off, 1) < 0) sysfatal("seek failed"); if (Bread(bin, buf, cnt) != cnt) sysfatal("read failed"); break; case 8: if (r->qid.path != oqid.path){ oqid = r->qid; if (cache) free(cache); cache = emalloc(r->ndata); bs.pos = cache; bs.limit = cache+r->ndata; if ((err = inflate(&bs, blwrite, bin, (int(*)(void*))Bgetc)) != FlateOk) sysfatal("inflate failed - %s", flateerr(err)); if (blockcrc(crctab, crc, cache, r->ndata) != zh.crc) fprint(2, "%s - crc failed", r->name); if ((r->addr & High64) && MUNGE_CR){ for (i = 0; i < r->ndata -1; i++) if (cache[i] == '\r' && cache[i +1] == '\n') cache[i] = ' '; } } memcpy(buf, cache+off, cnt); break; default: sysfatal("%d - unsupported compression method", zh.meth); break; } return buf; }
void vncrdbytes(Vnc *v, void *a, int n) { if(Bread(&v->in, a, n) != n){ if(verbose > 1) fprint(2, "hungup while reading\n"); vnchungup(v); } }
int Bgetint(Biobuf *b) { uchar p[4]; if(Bread(b, p, 4) != 4) sysfatal("short read"); return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; }
uchar* getrange(Block *b) { uchar *data; char *status; int netfd; static Biobuf netbio; b->len = Blocksize; if(b->off + b->len > size) b->len = size - b->off; if(debug) print("getrange: %lld %lld\n", b->off, b->len); netfd = dialhttp(&netbio); fprint(netfd, "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "Accept-Encoding:\r\n" "Range: bytes=%lld-%lld\r\n" "\r\n", get, host, b->off, b->off+b->len); Bflush(&netbio); status = readhttphdr(&netbio, nil); if(status == nil) return nil; /* * Some servers (e.g., www.google.com) return 200 OK * when you ask for the entire page in one range. */ if(strstr(status, "206 Partial Content")==nil && (b->off!=0 || b->len!=size || strstr(status, "200 OK")==nil)){ free(status); close(netfd); werrstr("did not get requested range"); return nil; } free(status); data = emalloc9p(b->len); if(Bread(&netbio, data, b->len) != b->len){ free(data); close(netfd); werrstr("not enough bytes read"); return nil; } b->p = data; close(netfd); return data; }
void devread(void) { long offset, sector = bnum; int dosdev = (int) inode.i_dev; for (offset = 0; offset < cnt; offset += BPS) { Bread(dosdev, badsect(dosdev, sector++)); bcopy(I_ADDR, iodest+offset, BPS); } }
/* * * * * * utility * * * * * */ static int Bgbit32(Biobuf *b, u32int *p) { uchar tmp[4]; if(Bread(b, tmp, 4) != 4) return -1; *p = gbit32(tmp); return 0; }
char* qmail(char **argv, char *buf, int n, Biobuf *cout) { Waitmsg *status; int i, pid, pipefd[2]; char path[512]; Biobuf *bp; pid = 0; if(tflag == 0) { if(pipe(pipefd) < 0) exits("pipe"); pid = fork(); if(pid == 0) { dup(pipefd[0], 0); for(i = sysfiles(); i >= 3; i--) close(i); snprint(path, sizeof(path), "%s/qer", UPASBIN); *argv=path; exec(path, argv); exits("exec"); } Binit(&bout, pipefd[1], OWRITE); bp = &bout; } else bp = Bopen("/dev/null", OWRITE); while(n > 0) { Bwrite(bp, buf, n); if(cout) Bwrite(cout, buf, n); n = Bread(&bin, buf, sizeof(buf)-1); } Bterm(bp); if(cout) Bterm(cout); if(tflag) return 0; close(pipefd[1]); close(pipefd[0]); for(;;) { status = wait(); if(status == nil || status->pid == pid) break; free(status); } if(status == nil) strcpy(buf, "wait failed"); else { strcpy(buf, status->msg); free(status); } return buf; }
/* * * * * * logging * * * * * */ static int applylog(XDStore *ds) { int np; uchar *a, *buf; u32int addr; Biobuf *b; Dpage *p; buf = malloc(ds->ds.pagesize); if(buf == nil) return -1; b = malloc(sizeof(Biobuf)); if(b == nil) goto Error; if(seek(ds->logfd, 0, 0) != 0){ Error: free(buf); free(b); return -1; } Binit(b, ds->logfd, OREAD); if(Bgbit32(b, &addr) < 0) goto Error; if(addr != gbit32((uchar*)"log\n")){ werrstr("malformed log"); goto Error; } np = 0; for(;;){ if(Bgbit32(b, &addr) < 0) goto Error; if(addr == ~(u32int)0) break; DBG print("apply log page %ud\n", addr); p = findpage(ds, addr); if(p) a = p->a; else a = buf; if(Bread(b, a, ds->ds.pagesize) != ds->ds.pagesize) goto Error; if(pwrite(ds->fd, a, ds->ds.pagesize, addr) != ds->ds.pagesize) { abort(); goto Error; } np++; } fprint(2, "applied changes to %d pages\n", np); free(b); free(buf); return 0 && fsync(ds->fd); }
int isar(Biobuf *bp) { int n; char magbuf[SARMAG]; n = Bread(bp, magbuf, SARMAG); if(n == SARMAG && strncmp(magbuf, ARMAG, SARMAG) == 0) return 1; return 0; }
void Creadblock(Cdimg *cd, void *buf, ulong block, ulong len) { assert(block != 0); /* nothing useful there */ Bflush(&cd->bwr); if(Bseek(&cd->brd, block*Blocksize, 0) != block*Blocksize) sysfatal("error seeking to block %lud", block); if(Bread(&cd->brd, buf, len) != len) sysfatal("error reading %lud bytes at block %lud: %r %lld", len, block, Bseek(&cd->brd, 0, 2)); }
static int isobjfile(char *f) { int n, v; Biobuf *b; char buf1[5], buf2[SARMAG]; b = Bopen(f, OREAD); if(b == nil) return 0; n = Bread(b, buf1, 5); if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<')) v = 1; /* good enough for our purposes */ else{ Bseek(b, 0, 0); n = Bread(b, buf2, SARMAG); v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0; } Bterm(b); return v; }
/* read ahead a byte. so we must check peek here */ static int readbyte(Header *h) { uchar x; if(h->peek >= 0){ x = h->peek; h->peek = -1; }else if(Bread(h->fd, &x, 1) != 1) jpgerror(h, readerr); return x; }
void arread(Biobuf *b, Armember *bp, int n) /* read an image into a member buffer */ { int i; bp->member = armalloc(n); i = Bread(b, bp->member, n); if (i < 0) { free(bp->member); bp->member = 0; rderr(); } }
Proc* readsnap(Biobuf *b) { char *q; char buf[12]; int32_t pid; Proc *p, *plist; int i, n; if((q = Brdline(b, '\n')) == nil) panic("error reading snapshot file"); if(strncmp(q, "process snapshot", strlen("process snapshot")) != 0) panic("bad snapshot file format"); plist = nil; while(q = Brdline(b, '\n')) { q[Blinelen(b)-1] = 0; pid = atol(q); q += 12; p = findpid(plist, pid); if(p == nil) { p = emalloc(sizeof(*p)); p->link = plist; p->pid = pid; plist = p; } for(i=0; i<Npfile; i++) { if(strcmp(pfile[i], q) == 0) { p->d[i] = readdata(b); break; } } if(i != Npfile) continue; if(strcmp(q, "mem") == 0) { if(Bread(b, buf, 12) != 12) panic("can't read memory section"); n = atoi(buf); p->nseg = n; p->seg = emalloc(n*sizeof(*p->seg)); for(i=0; i<n; i++) readseg(&p->seg[i], b, plist); } else if(strcmp(q, "text") == 0) readseg(&p->text, b, plist); else panic("unknown section"); } return plist; }
void loadwadheader(void) { int i, j; Bread(fil1,&tempbuf[0],12); numwads = ((int)tempbuf[4])+(((int)tempbuf[5])<<8)+(((int)tempbuf[6])<<16)+(((int)tempbuf[7])<<24); i = ((int)tempbuf[8])+(((int)tempbuf[9])<<8)+(((int)tempbuf[10])<<16)+(((int)tempbuf[11])<<24); Blseek(fil1,i,BSEEK_SET); Bread(fil1,&tempbuf[0],numwads*16); j = 0; for(i=0;i<numwads;i++) { wadplc[i] = ((int)tempbuf[j])+(((int)tempbuf[j+1])<<8)+(((int)tempbuf[j+2])<<16)+(((int)tempbuf[j+3])<<24); j += 4; wadlen[i] = ((int)tempbuf[j])+(((int)tempbuf[j+1])<<8)+(((int)tempbuf[j+2])<<16)+(((int)tempbuf[j+3])<<24); j += 4; wadata[i][0] = tempbuf[j+0]; wadata[i][1] = tempbuf[j+1]; wadata[i][2] = tempbuf[j+2]; wadata[i][3] = tempbuf[j+3]; wadata[i][4] = tempbuf[j+4]; wadata[i][5] = tempbuf[j+5]; wadata[i][6] = tempbuf[j+6]; wadata[i][7] = tempbuf[j+7]; j += 8; } }
/* * Be aware that cnt is rounded up to N*BPS */ void devread(char *iodest, int sector, int cnt) { int offset; char *p; int dosdev_copy; for (offset = 0; offset < cnt; offset += BPS) { dosdev_copy = dosdev; p = Bread(dosdev_copy, badsect(sector++)); bcopy(p, iodest+offset, BPS); } }