unsigned int dircount(const char *n, int flags) { dirstack *stack = pushdir(NULL, n); unsigned int total = 0; while (NULL != stack) { DIR *dir = opendir(stack->path); char cwd[MAXNAMLEN + 1]; unsigned int dircnt = 0; struct dirent *ent; if (NULL == dir) { perror(stack->path); exit(1); } strcpy(cwd, stack->path); stack = popdir(stack); while (NULL != (ent = readdir(dir))) { char path[MAXNAMLEN + 1]; struct stat s; int res; if (MATCH == strcmp(".", ent->d_name) || MATCH == strcmp("..", ent->d_name)) continue; strcpy(path, cwd); strcat(path, "/"); strcat(path, ent->d_name); /* dirent->d_type was always set to DT_UNKNOWN on SDF */ res = lstat(path, &s); if (SUCCESS != res) perror(path); switch (s.st_mode & S_IFMT) { case S_IFDIR: if (RECURSE & flags) stack = pushdir(stack, path); break; case S_IFREG: total++; dircnt++; break; } } if (!(RECURSE & flags) || !(QUIET & flags)) printf("%s\t%u\n", cwd, dircnt); closedir(dir); } return total; }
char* rread(Fid *f) { int i, len; Ram *r; char *buf; uvlong off, end; int n, cnt; if(f->ram->busy == 0) return Enotexist; n = 0; thdr.count = 0; off = rhdr.offset; end = rhdr.offset + rhdr.count; cnt = rhdr.count; if(cnt > messagesize-IOHDRSZ) cnt = messagesize-IOHDRSZ; buf = thdr.data; if(f->ram->qid.type & QTDIR){ if(!f->ram->replete) popdir(f->ram); for(i=0,r=f->ram->child; r!=nil && i<end; r=r->next){ if(!r->busy) continue; len = ramstat(r, (uchar*)buf+n, cnt-n); if(len <= BIT16SZ) break; if(i >= off) n += len; i += len; } thdr.count = n; return 0; } r = f->ram; if(off >= r->ndata) return 0; r->atime = time(0); n = cnt; if(off+n > r->ndata) n = r->ndata - off; thdr.data = doread(r, off, n); thdr.count = n; return 0; }
char* rwalk(Fid *f) { Fid *nf; Ram *r; char *err; char *name; Ram *dir; int i; nf = nil; if(f->ram->busy == 0) return Enotexist; if(f->open) return Eisopen; if(rhdr.newfid != rhdr.fid){ nf = newfid(rhdr.newfid); nf->busy = 1; nf->open = 0; nf->rclose = 0; nf->ram = f->ram; nf->user = f->user; /* no ref count; the leakage is minor */ f = nf; } thdr.nwqid = 0; err = nil; r = f->ram; if(rhdr.nwname > 0){ for(i=0; i<rhdr.nwname; i++){ if((r->qid.type & QTDIR) == 0){ err = Enotdir; break; } if(r->busy == 0){ err = Enotexist; break; } r->atime = time(0); name = rhdr.wname[i]; dir = r; if(!perm(Pexec)){ err = Eperm; break; } if(strcmp(name, "..") == 0){ r = dir->parent; Accept: if(i == MAXWELEM){ err = "name too long"; break; } thdr.wqid[thdr.nwqid++] = r->qid; continue; } if(!dir->replete) popdir(dir); for(r=dir->child; r; r=r->next) if(r->busy && strcmp(name, r->name)==0) goto Accept; break; /* file not found */ } if(i==0 && err == nil) err = Enotexist; } if(err!=nil || thdr.nwqid<rhdr.nwname){ if(nf){ nf->busy = 0; nf->open = 0; nf->ram = 0; } }else if(thdr.nwqid == rhdr.nwname) f->ram = r; return err; }