void removeall(char *p) { int fd, n, i; Dir *d; char *q; if(remove(p) >= 0) return; if((d = dirstat(p)) == nil) return; if(!(d->mode & DMDIR)) { free(d); return; } free(d); if((fd = open(p, OREAD)) < 0) return; n = dirreadall(fd, &d); close(fd); for(i=0; i<n; i++) { q = smprint("%s/%s", p, d[i].name); removeall(q); free(q); } free(d); }
void coreall(char *name) { Dir *d; int fd, i, n; char *p; if((d = dirstat(name)) == nil){ fprint(2, "%s: %r\n", name); return; } if((d->mode&DMDIR) == 0){ free(d); corefile(name, 1); return; } free(d); if((fd = open(name, OREAD)) < 0){ fprint(2, "open %s: %r\n", name); return; } n = dirreadall(fd, &d); qsort(d, n, sizeof(d[0]), timecmp); for(i=0; i<n; i++){ p = smprint("%s/%s", name, d[i].name); if(p == nil) sysfatal("out of memory"); corefile(p, 0); free(p); } }
/* * read_dir: get the file names and modification dates for the * files in /usr/news into n_list; sort them in reverse by * modification date. */ void read_dir(int update) { Dir *d; char newstime[100], *home; int i, j, n, na, fd; n_count = 0; n_list = malloc(NINC*sizeof(File)); na = NINC; home = getenv("HOME"); if(home) { sprint(newstime, TFILE, home); d = dirstat(newstime); if(d != nil) { n_list[n_count].name = strdup(""); n_list[n_count].time =d->mtime-1; n_list[n_count].length = 0; n_count++; free(d); } if(update) { fd = create(newstime, OWRITE, 0644); if(fd >= 0) close(fd); } } fd = open(NEWS, OREAD); if(fd < 0) { fprint(2, "news: "); perror(NEWS); exits(NEWS); } n = dirreadall(fd, &d); for(i=0; i<n; i++) { for(j=0; ignore[j]; j++) if(strcmp(ignore[j], d[i].name) == 0) goto ign; if(na <= n_count) { na += NINC; n_list = realloc(n_list, na*sizeof(File)); } n_list[n_count].name = strdup(d[i].name); n_list[n_count].time = d[i].mtime; n_list[n_count].length = d[i].length; n_count++; ign:; } free(d); close(fd); qsort(n_list, n_count, sizeof(File), fcmp); }
int readlevels(char *leveldir) { int fd, n; if((fd = open(leveldir, OREAD)) < 0) return -1; n = dirreadall(fd, &dir); close(fd); return n; }
Dir* loaddir(char *name, int *np) { int fd; Dir *dp; fd = open(name, OREAD); if(fd < 0) return nil; *np = dirreadall(fd, &dp); close(fd); return dp; }
static long ls(char *p, Dir **dirbuf) { int fd; long n; Dir *db; if((db = dirstat(p)) == nil || !(db->qid.type & QTDIR) || (fd = open(p, OREAD)) < 0 ) return -1; free(db); n = dirreadall(fd, dirbuf); close(fd); return n; }
// xreaddir replaces dst with a list of the names of the files in dir. // The names are relative to dir; they are not full paths. void xreaddir(Vec *dst, char *dir) { Dir *d; int fd, i, n; vreset(dst); fd = open(dir, OREAD); if(fd < 0) fatal("open %s", dir); n = dirreadall(fd, &d); for(i=0; i<n; i++) vadd(dst, d[i].name); free(d); close(fd); }
void main(int argc, char *argv[]) { int fd, i, tot, none = 1; Dir *dir, **mem; ARGBEGIN { case 'a': aflag++; break; case 'p': pflag++; break; case 'r': rflag++; break; } ARGEND; Binit(&bout, 1, OWRITE); if(chdir("/proc")==-1) error("/proc"); fd=open(".", OREAD); if(fd<0) error("/proc"); tot = dirreadall(fd, &dir); if(tot <= 0){ fprint(2, "ps: empty directory /proc\n"); exits("empty"); } mem = malloc(tot*sizeof(Dir*)); for(i=0; i<tot; i++) mem[i] = dir++; qsort(mem, tot, sizeof(Dir*), cmp); for(i=0; i<tot; i++){ ps(mem[i]->name); none = 0; } if(none) error("no processes; bad #p"); exits(0); }
void nstat(char *net, void (*f)(char*, Dir*)) { int fdir, i, tot; Dir *dir; char buf[128]; snprint(buf, sizeof buf, "%s/%s", netroot, net); fdir = open(buf, OREAD); if(fdir < 0) return; tot = dirreadall(fdir, &dir); for(i = 0; i < tot; i++) { (*f)(net, &dir[i]); Bflush(&out); } free(dir); close(fdir); }
void dodir(Fs *f) { int nfiles; int i, fd; if(chdir(f->keys) < 0){ complain("can't chdir to %s: %r", f->keys); return; } fd = open(".", OREAD); if(fd < 0){ complain("can't open %s: %r\n", f->keys); return; } nfiles = dirreadall(fd, &dirbuf); close(fd); for(i = 0; i < nfiles; i++) douser(f, dirbuf[i].name); }
Ipifc* readipifc(char *net, Ipifc *ifc, int index) { int fd, i, n; Dir *dir; char directory[128]; char buf[128]; Ipifc **l; _freeifc(ifc); l = &ifc; ifc = nil; if(net == 0) net = "/net"; snprint(directory, sizeof(directory), "%s/ipifc", net); if(index >= 0){ snprint(buf, sizeof(buf), "%s/%d/status", directory, index); _readipifc(buf, l, index); } else { fd = open(directory, OREAD); if(fd < 0) return nil; n = dirreadall(fd, &dir); close(fd); for(i = 0; i < n; i++){ if(strcmp(dir[i].name, "clone") == 0) continue; if(strcmp(dir[i].name, "stats") == 0) continue; snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name); l = _readipifc(buf, l, atoi(dir[i].name)); } free(dir); } return ifc; }
static void addtreetoar(int ar, char *file, char *shortf, int fd) { int n; Dir *dent, *dirents; String *name = s_new(); n = dirreadall(fd, &dirents); if (n < 0) fprint(2, "%s: dirreadall %s: %r\n", argv0, file); close(fd); if (n <= 0) return; if (chdir(shortf) < 0) sysfatal("chdir %s: %r", file); if (Debug) fprint(2, "chdir %s\t# %s\n", shortf, file); for (dent = dirents; dent < dirents + n; dent++) { s_reset(name); s_append(name, file); s_append(name, "/"); s_append(name, dent->name); addtoar(ar, s_to_c(name), dent->name); } s_free(name); free(dirents); /* * this assumes that shortf is just one component, which is true * during directory descent, but not necessarily true of command-line * arguments. Our caller (or addtoar's) must reset the working * directory if necessary. */ if (chdir("..") < 0) sysfatal("chdir %s/..: %r", file); if (Debug) fprint(2, "chdir ..\n"); }
/* * read disk partition tables so that readnvram via factotum * can see them. */ int readparts(void) { int i, n, ctl, data, fd; char *name, *ctlname, *dataname; Dir *dir; fd = open("/dev", OREAD); if(fd < 0) return -1; n = dirreadall(fd, &dir); close(fd); for(i = 0; i < n; i++) { name = dir[i].name; if (strncmp(name, "sd", 2) != 0) continue; ctlname = smprint("/dev/%s/ctl", name); dataname = smprint("/dev/%s/data", name); if (ctlname == nil || dataname == nil) { free(ctlname); free(dataname); continue; } ctl = open(ctlname, ORDWR); data = open(dataname, OREAD); free(ctlname); free(dataname); if (ctl >= 0 && data >= 0) setpartitions(dataname, ctl, data); close(ctl); close(data); } free(dir); return 0; }
void init(void) { int i, fd, nr; Dir *pd; char buf[128]; if((fd = open(dir, OREAD)) < 0) return; nmap = nr = dirreadall(fd, &pd); map = emalloc(nr * sizeof(KbMap)); for(i=0; i<nr; i++){ sprint(buf, "%s/%s", dir, pd[i].name); map[i].file = estrdup(buf); map[i].name = estrdup(pd[i].name); map[i].current = 0; } free(pd); close(fd); }
static void pcicfginit(void) { int fd, i, j, n, bno, dno, fno; char buf[1024], *base, *s; Pcidev *p; Dir *d; trace("pcicfginit\n"); if((fd = open(base = "/dev/pci", OREAD)) < 0) if((fd = open(base = "#$/pci", OREAD)) < 0) return; n = dirreadall(fd, &d); close(fd); for(i=0; i<n; i++) { if(strstr(d[i].name, "ctl") == nil) continue; strncpy(buf, d[i].name, sizeof(buf)); bno = strtoul(buf, &s, 10); dno = strtoul(s+1, &s, 10); fno = strtoul(s+1, nil, 10); p = mallocz(sizeof(*p), 1); p->tbdf = MKBUS(BusPCI, bno, dno, fno); sprint(buf, "%s/%d.%d.%draw", base, bno, dno, fno); if((p->rawfd = open(buf, ORDWR)) < 0){ free(p); continue; } sprint(buf, "%s/%d.%d.%dctl", base, bno, dno, fno); if((fd = open(buf, OREAD)) < 0){ close(p->rawfd); free(p); continue; } if((j = read(fd, buf, sizeof(buf)-1)) <= 0){ close(p->rawfd); close(fd); free(p); continue; } buf[j] = 0; close(fd); p->ccrb = strtol(buf, nil, 16); p->ccru = strtol(buf + 3, nil, 16); p->vid = strtol(buf + 9, &s, 16); p->did = strtol(s + 1, &s, 16); p->intl = strtol(s + 1, &s, 10); p->rid = pcicfgr8(p, PciRID); trace("%d.%d.%d: did=%X vid=%X rid=%X intl=%d ccru=%X\n", bno, dno, fno, p->did, p->vid, p->rid, p->intl, p->ccru); while(*s == ' '){ j = strtol(s+1, &s, 10); if(j < 0 || j >= nelem(p->mem)) break; p->mem[j].bar = strtoul(s+1, &s, 16); p->mem[j].size = strtoul(s+1, &s, 10); trace("\tmem[%d] = %p %d\n", j, p->mem[j].bar, p->mem[j].size); } if(pcilist != nil) pcitail->list = p; else pcilist = p; pcitail = p; } }
static int xdirread0(char **path, int (*namecmp)(char *, char *), Dir **d) { XDir *x, *p; int fd, n; Dir *t; t = nil; for(p = nil, x = xdirlist; x; p=x, x=x->next){ if(namecmp(x->path, *path)) continue; if(x == xdirlist) xdirlist = x->next; else p->next = x->next; while(t = dirstat(x->path)){ if(qidcmp(&t->qid, &x->qid)) break; free(t); x->next = xdirlist; xdirlist = x; if(strcmp(x->path, *path)){ free(*path); *path = strdup(x->path); } if(d) *d = x->dir; return x->ndir; } xdircount--; freexdir(x); break; } if((fd = open(*path, OREAD)) < 0){ free(t); if(t = xdirstat0(path, namecmp, "directory entry not found")) fd = open(*path, OREAD); } else if(t == nil) t = dirfstat(fd); n = -1; if(fd < 0 || t == nil) goto out; if((t->qid.type & QTDIR) == 0){ werrstr("not a directory"); goto out; } if((n = dirreadall(fd, d)) < 0) goto out; if(xdircount >= 8){ xdircount--; for(p = xdirlist, x = xdirlist->next; x->next; p = x, x = x->next) ; p->next = nil; freexdir(x); } x = mallocz(sizeof(*x), 1); x->qid = t->qid; x->path = strdup(*path); x->ndir = n; x->dir = *d; x->next = xdirlist; xdirlist = x; xdircount++; out: if(fd >= 0) close(fd); free(t); return n; }
static void dols(char *dir) { Dir *d; char *f, *p,*nm; long i, n; int fd; cleanname(dir); // expands "" to "."; ``dir+1'' access below depends on that if (!allowed(dir)) { error("Permission denied", "<p>Cannot list directory %s: Access prohibited</p>", dir); return; } fd = open(dir, OREAD); if (fd < 0) { error("Cannot read directory", "<p>Cannot read directory %s: %r</p>", dir); return; } if (vermaj) { hokheaders(connect); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } doctype(); hprint(hout, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"); hprint(hout, "<head><title>Index of %s</title></head>\n", dir); hprint(hout, "<body>\n"); hprint(hout, "<h1>Index of "); nm = dir; while((p = strchr(nm, '/')) != nil){ *p = '\0'; f = (*dir == '\0') ? "/" : dir; if (!(*dir == '\0' && *(dir+1) == '\0') && allowed(f)) hprint(hout, "<a href=\"/magic/webls?dir=%H\">%s/</a>", f, nm); else hprint(hout, "%s/", nm); *p = '/'; nm = p+1; } hprint(hout, "%s</h1>\n", nm); n = dirreadall(fd, &d); close(fd); maxwidths(d, n); qsort(d, n, sizeof(Dir), (int (*)(void *, void *))compar); hprint(hout, "<pre>\n"); for (i = 0; i < n; i++) { f = smprint("%s/%s", dir, d[i].name); cleanname(f); if (d[i].mode & DMDIR) { p = smprint("/magic/webls?dir=%H", f); free(f); f = p; } hprint(hout, "%M %C %*ud %-*s %-*s %*lld %s <a href=\"%s\">%s</a>\n", d[i].mode, d[i].type, devwidth, d[i].dev, uidwidth, d[i].uid, gidwidth, d[i].gid, lenwidth, d[i].length, asciitime(d[i].mtime), f, d[i].name); free(f); } f = smprint("%s/..", dir); cleanname(f); if (strcmp(f, dir) != 0 && allowed(f)) hprint(hout, "\nGo to <a href=\"/magic/webls?dir=%H\">parent</a> directory\n", f); else hprint(hout, "\nEnd of directory listing\n"); free(f); hprint(hout, "</pre>\n</body>\n</html>\n"); hflush(hout); free(d); }
Completion* complete(char *dir, char *s) { long i, l, n, nfile, len, nbytes; int fd, minlen; Dir *dirp; char **name, *p; ulong* mode; Completion *c; if(strchr(s, '/') != nil){ werrstr("slash character in name argument to complete()"); return nil; } fd = open(dir, OREAD); if(fd < 0) return nil; n = dirreadall(fd, &dirp); if(n <= 0){ close(fd); return nil; } /* find longest string, for allocation */ len = 0; for(i=0; i<n; i++){ l = strlen(dirp[i].name) + 1 + 1; /* +1 for / +1 for \0 */ if(l > len) len = l; } name = malloc(n*sizeof(char*)); mode = malloc(n*sizeof(ulong)); c = malloc(sizeof(Completion) + len); if(name == nil || mode == nil || c == nil) goto Return; memset(c, 0, sizeof(Completion)); /* find the matches */ len = strlen(s); nfile = 0; minlen = 1000000; for(i=0; i<n; i++) if(strncmp(s, dirp[i].name, len) == 0){ name[nfile] = dirp[i].name; mode[nfile] = dirp[i].mode; if(minlen > strlen(dirp[i].name)) minlen = strlen(dirp[i].name); nfile++; } if(nfile > 0) { /* report interesting results */ /* trim length back to longest common initial string */ for(i=1; i<nfile; i++) minlen = longestprefixlength(name[0], name[i], minlen); /* build the answer */ c->complete = (nfile == 1); c->advance = c->complete || (minlen > len); c->string = (char*)(c+1); memmove(c->string, name[0]+len, minlen-len); if(c->complete) c->string[minlen++ - len] = (mode[0]&DMDIR)? '/' : ' '; c->string[minlen - len] = '\0'; c->nmatch = nfile; } else { /* no match, so return all possible strings */ for(i=0; i<n; i++){ name[i] = dirp[i].name; mode[i] = dirp[i].mode; } nfile = n; c->nmatch = 0; } /* attach list of names */ nbytes = nfile * sizeof(char*); for(i=0; i<nfile; i++) nbytes += strlen(name[i]) + 1 + 1; c->filename = malloc(nbytes); if(c->filename == nil) goto Return; p = (char*)(c->filename + nfile); for(i=0; i<nfile; i++){ c->filename[i] = p; strcpy(p, name[i]); p += strlen(p); if(mode[i] & DMDIR) *p++ = '/'; *p++ = '\0'; } c->nfile = nfile; qsort(c->filename, c->nfile, sizeof(c->filename[0]), strpcmp); Return: free(name); free(mode); free(dirp); close(fd); return c; }
void main(int argc, char *argv[]) { int justinterfaces = 0; int i, tot, fd; Dir *d; char buf[128]; ARGBEGIN{ case 'i': justinterfaces = 1; break; case 'n': notrans = 1; break; case 'p': if(nproto >= nelem(proto)) sysfatal("too many protos"); proto[nproto++] = EARGF(usage()); break; default: usage(); }ARGEND; netroot = "/net"; switch(argc){ case 0: break; case 1: netroot = argv[0]; break; default: usage(); } Binit(&out, 1, OWRITE); if(justinterfaces){ pipifc(); exits(0); } if(nproto){ for(i=0; i<nproto; i++) nstat(proto[i], pip); }else{ fd = open(netroot, OREAD); if(fd < 0) sysfatal("open %s: %r", netroot); tot = dirreadall(fd, &d); for(i=0; i<tot; i++){ if(strcmp(d[i].name, "ipifc") == 0) continue; snprint(buf, sizeof buf, "%s/%s/0/local", netroot, d[i].name); if(access(buf, 0) >= 0) nstat(d[i].name, pip); } } exits(0); }
PaqDir * paqDir(char *name, Dir *dir) { Dir *dirs, *p; PaqDir *pd; int i, n, nb, fd, ndir; uchar *block, *pointer; char *nname; ulong offset; fd = open(name, OREAD); if(fd < 0) { warn("could not open directory: %s: %r", name); return nil; } ndir = dirreadall(fd, &dirs); close(fd); if(ndir < 0) { warn("could not read directory: %s: %r", name); return nil; } block = emallocz(blocksize); pointer = emallocz(blocksize); nb = 0; n = 0; nname = nil; pd = nil; for(i=0; i<ndir; i++) { p = dirs + i; free(nname); nname = emallocz(strlen(name) + strlen(p->name) + 2); sprint(nname, "%s/%s", name, p->name); if(p->mode & DMDIR) pd = paqDir(nname, p); else pd = paqFile(nname, p); if(pd == nil) continue; if(n+paqDirSize(pd) >= blocksize) { /* zero fill the block */ memset(block+n, 0, blocksize-n); offset = writeBlock(block, DirBlock); n = 0; if(nb >= blocksize/OffsetSize) { warn("directory too big for blocksize: %s", nname); goto Err; } putl(pointer+nb*OffsetSize, offset); nb++; } if(n+paqDirSize(pd) >= blocksize) { warn("directory entry does not fit in a block: %s", nname); paqDirFree(pd); continue; } putDir(block+n, pd); n += paqDirSize(pd); paqDirFree(pd); pd = nil; } if(n > 0) { /* zero fill the block */ memset(block+n, 0, blocksize-n); offset = writeBlock(block, DirBlock); if(nb >= blocksize/OffsetSize) { warn("directory too big for blocksize: %s", nname); goto Err; } putl(pointer+nb*OffsetSize, offset); } offset = writeBlock(pointer, PointerBlock); free(nname); free(dirs); paqDirFree(pd); free(block); free(pointer); return paqDirAlloc(dir, offset); Err: free(nname); free(dirs); paqDirFree(pd); free(block); free(pointer); return nil; }
void fsread(Fs *fs, Request *r, Fid *f) { int i, n, len,skip; Dir d; Symbol *dp; char buf[512]; if(f->attached == 0){ fsreply(fs, r, Enofid); return; } if((int)r->f.count < 0){ fsreply(fs, r, "bad read count"); return; } if(f->qid.type & QTDIR){ n = 0; if(f->dir == nil){ f->ndir = dirreadall(f->fd, &f->dir); f->dirindex = 0; } if(f->dir == nil) goto Return; if(r->f.offset == 0) /* seeking to zero is permitted */ f->dirindex = 0; for(; f->dirindex < f->ndir; f->dirindex++){ if((f->dir[f->dirindex].qid.type & QTDIR) == 0) continue; len = convD2M(&f->dir[f->dirindex], r->buf+n, r->f.count-n); if(len <= BIT16SZ) goto Return; n += len; } skip = f->dirindex - f->ndir; /* # depend records already read */ if(f->df){ for(i = 0; i < f->df->hlen; i++) for(dp = f->df->dhash[i]; dp; dp = dp->next){ if(skip-- > 0) continue; snprint(buf, sizeof buf, "%s.tar", dp->sym); d.name = buf; d.uid = "none"; d.gid = "none"; d.muid = "none"; d.qid.type = QTFILE; d.qid.path = (uvlong)dp; d.qid.vers = 0; d.length = f->df->file[dp->fno].tarlen; d.mode = 0444; d.mtime = time(nil); d.atime = time(nil); len = convD2M(&d, r->buf + n, r->f.count - n); if(len <= BIT16SZ) goto Return; n += len; f->dirindex++; } } } else n = mktar(f->df, f->dp, r->buf, r->f.offset, r->f.count); Return: r->f.data = (char*)r->buf; r->f.count = n; fsreply(fs, r, nil); }
void threadmain(int argc, char **argv) { int fd, i, nd; char *err, *mnt, *srv; Dir *d; srv = "usb"; mnt = "/dev"; ARGBEGIN{ case 'D': usbfsdebug++; break; case 'd': usbdebug++; break; case 's': srv = EARGF(usage()); break; case 'i': pollms = atoi(EARGF(usage())); break; case 'm': mnt = EARGF(usage()); break; default: usage(); }ARGEND; if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0) sysfatal("#u: %r"); args(); fmtinstall('U', Ufmt); quotefmtinstall(); rfork(RFNOTEG); portc = chancreate(sizeof(char *), 0); if(portc == nil) sysfatal("chancreate"); proccreate(work, portc, Stack); if(argc == 0){ fd = open("/dev/usb", OREAD); if(fd < 0) sysfatal("/dev/usb: %r"); nd = dirreadall(fd, &d); close(fd); if(nd < 2) sysfatal("/dev/usb: no hubs"); for(i = 0; i < nd; i++) if(strcmp(d[i].name, "ctl") != 0) sendp(portc, smprint("/dev/usb/%s", d[i].name)); free(d); }else for(i = 0; i < argc; i++) sendp(portc, strdup(argv[i])); sendp(portc, nil); err = recvp(portc); chanfree(portc); usbfsexits(0); usbfsinit(srv, mnt, &usbdirfs, MAFTER); snprint(ctlfs.name, sizeof(ctlfs.name), "usbdctl"); usbfsadd(&ctlfs); threadexits(err); }
static int readmbox(char *box) { int fd, i, n, nd, lines, pid; char buf[100], err[Errlen]; char *p; Biobuf *b; Dir *d, *draw; Msg *m; Waitmsg *w; unmount(nil, "/mail/fs"); switch(pid = fork()){ case -1: return senderr("can't fork to start upas/fs"); case 0: close(0); close(1); open("/dev/null", OREAD); open("/dev/null", OWRITE); execl("/bin/upas/fs", "upas/fs", "-np", "-f", box, nil); snprint(err, sizeof err, "upas/fs: %r"); _exits(err); break; default: break; } if((w = wait()) == nil || w->pid != pid || w->msg[0] != '\0'){ if(w && w->pid==pid) return senderr("%s", w->msg); else return senderr("can't initialize upas/fs"); } free(w); if(chdir("/mail/fs/mbox") < 0) return senderr("can't initialize upas/fs: %r"); if((fd = open(".", OREAD)) < 0) return senderr("cannot open /mail/fs/mbox: %r"); nd = dirreadall(fd, &d); close(fd); if(nd < 0) return senderr("cannot read from /mail/fs/mbox: %r"); msg = mallocz(sizeof(Msg)*nd, 1); if(msg == nil) return senderr("out of memory"); if(nd == 0) return 0; qsort(d, nd, sizeof(d[0]), dircmp); for(i=0; i<nd; i++){ m = &msg[nmsg]; m->upasnum = atoi(d[i].name); sprint(buf, "%d/digest", m->upasnum); if((fd = open(buf, OREAD)) < 0) continue; n = readn(fd, m->digest, sizeof m->digest - 1); close(fd); if(n < 0) continue; m->digest[n] = '\0'; /* * We need the number of message lines so that we * can adjust the byte count to include \r's. * Upas/fs gives us the number of lines in the raw body * in the lines file, but we have to count rawheader ourselves. * There is one blank line between raw header and raw body. */ sprint(buf, "%d/rawheader", m->upasnum); if((b = Bopen(buf, OREAD)) == nil) continue; lines = 0; for(;;){ p = Brdline(b, '\n'); if(p == nil){ if((n = Blinelen(b)) == 0) break; Bseek(b, n, 1); }else lines++; } Bterm(b); lines++; sprint(buf, "%d/lines", m->upasnum); if((fd = open(buf, OREAD)) < 0) continue; n = readn(fd, buf, sizeof buf - 1); close(fd); if(n < 0) continue; buf[n] = '\0'; lines += atoi(buf); sprint(buf, "%d/raw", m->upasnum); if((draw = dirstat(buf)) == nil) continue; m->bytes = lines+draw->length; free(draw); nmsg++; totalmsgs++; totalbytes += m->bytes; } return 0; }