123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "stdinc.h"
- #include "9.h"
- /* one entry buffer for reading directories */
- struct DirBuf {
- DirEntryEnum* dee;
- int valid;
- DirEntry de;
- };
- static DirBuf*
- dirBufAlloc(File* file)
- {
- DirBuf *db;
- db = vtMemAllocZ(sizeof(DirBuf));
- db->dee = deeOpen(file);
- if(db->dee == nil){
- /* can happen if dir is removed from under us */
- vtMemFree(db);
- return nil;
- }
- return db;
- }
- void
- dirBufFree(DirBuf* db)
- {
- if(db == nil)
- return;
- if(db->valid)
- deCleanup(&db->de);
- deeClose(db->dee);
- vtMemFree(db);
- }
- int
- dirDe2M(DirEntry* de, uint8_t* p, int np)
- {
- int n;
- Dir dir;
- memset(&dir, 0, sizeof(Dir));
- dir.qid.path = de->qid;
- dir.qid.vers = de->mcount;
- dir.mode = de->mode & 0777;
- if(de->mode & ModeAppend){
- dir.qid.type |= QTAPPEND;
- dir.mode |= DMAPPEND;
- }
- if(de->mode & ModeExclusive){
- dir.qid.type |= QTEXCL;
- dir.mode |= DMEXCL;
- }
- if(de->mode & ModeDir){
- dir.qid.type |= QTDIR;
- dir.mode |= DMDIR;
- }
- if(de->mode & ModeSnapshot){
- dir.qid.type |= QTMOUNT; /* just for debugging */
- dir.mode |= DMMOUNT;
- }
- if(de->mode & ModeTemporary){
- dir.qid.type |= QTTMP;
- dir.mode |= DMTMP;
- }
- dir.atime = de->atime;
- dir.mtime = de->mtime;
- dir.length = de->size;
- dir.name = de->elem;
- if((dir.uid = unameByUid(de->uid)) == nil)
- dir.uid = smprint("(%s)", de->uid);
- if((dir.gid = unameByUid(de->gid)) == nil)
- dir.gid = smprint("(%s)", de->gid);
- if((dir.muid = unameByUid(de->mid)) == nil)
- dir.muid = smprint("(%s)", de->mid);
- n = convD2M(&dir, p, np);
- vtMemFree(dir.muid);
- vtMemFree(dir.gid);
- vtMemFree(dir.uid);
- return n;
- }
- int
- dirRead(Fid* fid, uint8_t* p, int count, int64_t offset)
- {
- int n, nb;
- DirBuf *db;
- /*
- * special case of rewinding a directory
- * otherwise ignore the offset
- */
- if(offset == 0 && fid->db){
- dirBufFree(fid->db);
- fid->db = nil;
- }
- if(fid->db == nil){
- fid->db = dirBufAlloc(fid->file);
- if(fid->db == nil)
- return -1;
- }
- db = fid->db;
- for(nb = 0; nb < count; nb += n){
- if(!db->valid){
- n = deeRead(db->dee, &db->de);
- if(n < 0)
- return -1;
- if(n == 0)
- break;
- db->valid = 1;
- }
- n = dirDe2M(&db->de, p+nb, count-nb);
- if(n <= BIT16SZ)
- break;
- db->valid = 0;
- deCleanup(&db->de);
- }
- return nb;
- }
|