From fd8d404d520a3f10c143f5cbe7c170606fffc75c Mon Sep 17 00:00:00 2001 From: iru Date: Thu, 14 Apr 2011 00:35:48 -0300 Subject: Promote the old installer/livecd specific tools to normal tools under /sys/src/cmd. Where similar common tools already existed, I kept them. --- sys/lib/dist.old/cmd/bflz.c | 374 --------------- sys/lib/dist.old/cmd/bzfs/bzfs.h | 11 - sys/lib/dist.old/cmd/bzfs/mkext.c | 288 ------------ sys/lib/dist.old/cmd/bzfs/mkfile | 20 - sys/lib/dist.old/cmd/bzfs/oramfs.c | 927 ------------------------------------- sys/lib/dist.old/cmd/bzfs/unbflz.c | 108 ----- sys/lib/dist.old/cmd/bzfs/unbzip.c | 861 ---------------------------------- sys/lib/dist.old/cmd/cdsh.c | 133 ------ sys/lib/dist.old/cmd/clog.c | 59 --- sys/lib/dist.old/cmd/multi/mkfile | 76 --- sys/lib/dist.old/cmd/multi/mkmulti | 70 --- sys/lib/dist.old/cmd/multi/multi.c | 38 -- sys/lib/dist.old/cmd/tailfsrv.c | 17 - sys/lib/dist.old/cmd/touchfs.c | 66 --- sys/lib/dist.old/cmd/unbflz.c | 109 ----- sys/src/cmd/aux/bflz.c | 374 +++++++++++++++ sys/src/cmd/aux/cdsh.c | 133 ++++++ sys/src/cmd/aux/multi/mkfile | 76 +++ sys/src/cmd/aux/multi/mkmulti | 70 +++ sys/src/cmd/aux/multi/multi.c | 38 ++ sys/src/cmd/aux/tailfsrv.c | 17 + sys/src/cmd/aux/unbflz.c | 109 +++++ sys/src/cmd/bzfs/bzfs.h | 11 + sys/src/cmd/bzfs/mkext.c | 288 ++++++++++++ sys/src/cmd/bzfs/mkfile | 20 + sys/src/cmd/bzfs/oramfs.c | 927 +++++++++++++++++++++++++++++++++++++ sys/src/cmd/bzfs/unbflz.c | 108 +++++ sys/src/cmd/bzfs/unbzip.c | 861 ++++++++++++++++++++++++++++++++++ sys/src/cmd/touchfs.c | 66 +++ 29 files changed, 3098 insertions(+), 3157 deletions(-) delete mode 100644 sys/lib/dist.old/cmd/bflz.c delete mode 100644 sys/lib/dist.old/cmd/bzfs/bzfs.h delete mode 100644 sys/lib/dist.old/cmd/bzfs/mkext.c delete mode 100644 sys/lib/dist.old/cmd/bzfs/mkfile delete mode 100644 sys/lib/dist.old/cmd/bzfs/oramfs.c delete mode 100644 sys/lib/dist.old/cmd/bzfs/unbflz.c delete mode 100644 sys/lib/dist.old/cmd/bzfs/unbzip.c delete mode 100644 sys/lib/dist.old/cmd/cdsh.c delete mode 100644 sys/lib/dist.old/cmd/clog.c delete mode 100644 sys/lib/dist.old/cmd/multi/mkfile delete mode 100644 sys/lib/dist.old/cmd/multi/mkmulti delete mode 100644 sys/lib/dist.old/cmd/multi/multi.c delete mode 100644 sys/lib/dist.old/cmd/tailfsrv.c delete mode 100644 sys/lib/dist.old/cmd/touchfs.c delete mode 100644 sys/lib/dist.old/cmd/unbflz.c create mode 100644 sys/src/cmd/aux/bflz.c create mode 100644 sys/src/cmd/aux/cdsh.c create mode 100644 sys/src/cmd/aux/multi/mkfile create mode 100644 sys/src/cmd/aux/multi/mkmulti create mode 100644 sys/src/cmd/aux/multi/multi.c create mode 100644 sys/src/cmd/aux/tailfsrv.c create mode 100644 sys/src/cmd/aux/unbflz.c create mode 100644 sys/src/cmd/bzfs/bzfs.h create mode 100644 sys/src/cmd/bzfs/mkext.c create mode 100644 sys/src/cmd/bzfs/mkfile create mode 100644 sys/src/cmd/bzfs/oramfs.c create mode 100644 sys/src/cmd/bzfs/unbflz.c create mode 100644 sys/src/cmd/bzfs/unbzip.c create mode 100644 sys/src/cmd/touchfs.c (limited to 'sys') diff --git a/sys/lib/dist.old/cmd/bflz.c b/sys/lib/dist.old/cmd/bflz.c deleted file mode 100644 index 89cb361c2..000000000 --- a/sys/lib/dist.old/cmd/bflz.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Extraordinarily brute force Lempel & Ziv-like - * compressor. The input file must fit in memory - * during compression, and the output file will - * be reconstructed in memory during decompression. - * We search for large common sequences and use a - * greedy algorithm to choose which sequence gets - * compressed first. - * - * Files begin with "BLZ\n" and a 32-bit uncompressed file length. - * - * Output format is a series of blocks followed by - * a raw data section. Each block begins with a 32-bit big-endian - * number. The top bit is type and the next 31 bits - * are uncompressed size. Type is one of - * 0 - use raw data for this length - * 1 - a 32-bit offset follows - * After the blocks come the raw data. (The end of the blocks can be - * noted by summing block lengths until you reach the file length.) - */ - -#include -#include -#include - -#define malloc sbrk - -int minrun = 16; -int win = 16; -ulong outn; -int verbose; -int mindist; - -enum { Prime = 16777213 }; /* smallest prime < 2^24 (so p*256+256 < 2^32) */ -enum { NOFF = 3 }; - -Biobuf bout; -ulong length; -uchar *data; -ulong sum32(ulong, void*, long); -uchar *odat; -int nodat; -int nraw; -int rawstart; -int acct; -int zlength; -int maxchain; -int maxrle[256]; -int nnew; - -typedef struct Node Node; -struct Node { - Node *link; - ulong key; - ulong offset[NOFF]; -}; - -Node *nodepool; -int nnodepool; - -Node **hash; -uint nhash; - -uint maxlen; -uint maxsame; -uint replacesame = 8*1024*1024; - -Node *freelist, **freeend; -uint nalloc; - -Node* -allocnode(void) -{ - int i; - Node *n; - - if(nnodepool == 0){ - nnodepool = 256*1024; - nodepool = malloc(sizeof(Node)*nnodepool); - } - if(freelist){ - n = freelist; - freelist = n->link; - return n; - } - assert(nnodepool > 0); - nalloc++; - n = &nodepool[--nnodepool]; - for(i=0; ioffset[i] = -1; - - return n; -} - -void -freenode(Node *n) -{ - if(freelist == nil) - freelist = n; - else - *freeend = n; - freeend = &n->link; - n->link = nil; -} - -Node** -llookup(ulong key) -{ - uint c; - Node **l, **top, *n; - - if(nhash == 0){ - uint x; - - x = length/8; - for(nhash=1; nhashlink){ - c++; - if((*l)->key == key){ - /* move to front */ - n = *l; - *l = n->link; - n->link = *top; - *top = n; - return top; - } - } - if(c > maxlen) - maxlen = c; - return l; -} - -Node* -lookup(ulong key) -{ - return *llookup(key); -} - -void -insertnode(ulong key, ulong offset) -{ - int i; - Node *n, **l; - - l = llookup(key); - if(*l == nil){ - if(l==&hash[key&(nhash-1)]) - nnew++; - *l = allocnode(); - (*l)->key = key; - } - n = *l; - - /* add or replace last */ - for(i=0; ioffset[i]!=-1; i++) - ; - n->offset[i] = offset; -} - -void -Bputint(Biobufhdr *b, int n) -{ - uchar p[4]; - - p[0] = n>>24; - p[1] = n>>16; - p[2] = n>>8; - p[3] = n; - Bwrite(b, p, 4); -} - -void -flushraw(void) -{ - if(nraw){ - if(verbose) - fprint(2, "Raw %d+%d\n", rawstart, nraw); - zlength += 4+nraw; - Bputint(&bout, (1<<31)|nraw); - memmove(odat+nodat, data+rawstart, nraw); - nodat += nraw; - nraw = 0; - } -} - -int -rawbyte(int i) -{ - assert(acct == i); - if(nraw == 0) - rawstart = i; - acct++; - nraw++; - return 1; -} - -int -refblock(int i, int len, int off) -{ - assert(acct == i); - acct += len; - if(nraw) - flushraw(); - if(verbose) - fprint(2, "Copy %d+%d from %d\n", i, len, off); - Bputint(&bout, len); - Bputint(&bout, off); - zlength += 4+4; - return len; -} - -int -cmprun(uchar *a, uchar *b, int len) -{ - int i; - - if(a==b) - return 0; - for(i=0; ioffset[o] == -1) - break; - run = cmprun(data+i, data+n->offset[o], length-i); - if(run > maxrun && n->offset[o]+mindist < i){ - maxrun = run; - maxoff = n->offset[o]; - best = o; - } - } - if(best > 0){ - o = n->offset[best]; - for(j=best; j>0; j--) - n->offset[j] = n->offset[j-1]; - n->offset[0] = o; - } - } - - if(maxrun >= minrun) - j = i+refblock(i, maxrun, maxoff); - else - j = i+rawbyte(i); - for(; imaxrle[data[i]]){ - maxrle[data[i]] = rle; - insertnode(sum, i); - } - sum = (sum*256+data[i+win]) % Prime; - sum = (sum + data[i]*outn) % Prime; - } - } - /* could do better here */ - for(; i 0){ - data = realloc(data, length+n); - if(data == nil) - sysfatal("realloc: %r"); - memmove(data+length, buf, n); - length += n; - if(n < sizeof buf) - break; - } - odat = malloc(length); - if(odat == nil) - sysfatal("malloc: %r"); - - Binit(&bout, 1, OWRITE); - Bprint(&bout, "BLZ\n"); - Bputint(&bout, length); - outn = 1; - for(i=0; i -#include -#include -#include -#include -#include "bzfs.h" - -enum{ - LEN = 8*1024, - NFLDS = 6, /* filename, modes, uid, gid, mtime, bytes */ -}; - -void mkdirs(char*, char*); -void mkdir(char*, ulong, ulong, char*, char*); -void extract(char*, ulong, ulong, char*, char*, ulong); -void seekpast(ulong); -void error(char*, ...); -void warn(char*, ...); -void usage(void); -char *mtpt; -Biobufhdr bin; -uchar binbuf[2*LEN]; - -void -usage(void) -{ - fprint(2, "usage: bzfs [-m mtpt] [-s] [-f file] [-h]\n"); - exits("usage"); -} - -/* - * floppy disks can only be read on 512-byte - * boundaries and in 512 byte multiples. - * feed one over a pipe to allow arbitrary reading. - */ -char zero[512]; -int -blockread(int in, char *first, int nfirst) -{ - int p[2], out, n, rv; - char blk[512]; - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - rv = p[0]; - out = p[1]; - switch(rfork(RFPROC|RFNOTEG|RFFDG)){ - case -1: - sysfatal("fork: %r"); - case 0: - close(rv); - break; - default: - close(in); - close(out); - return rv; - } - - write(out, first, nfirst); - - while((n=read(in, blk, sizeof blk)) > 0){ - if(write(out, blk, n) != n) - break; - if(n == sizeof(blk) && memcmp(zero, blk, n) == n) - break; - } - _exits(0); - return -1; -} - -enum { NAMELEN = 28 }; - -void -main(int argc, char **argv) -{ - char *rargv[10]; - int rargc; - char *fields[NFLDS], name[2*LEN], *p, *namep; - char uid[NAMELEN], gid[NAMELEN]; - ulong mode, bytes, mtime; - char *file; - int i, n, stdin, fd, chatty; - char blk[512]; - - if(argc>1 && strcmp(argv[1], "RAMFS") == 0){ - argv[1] = argv[0]; - ramfsmain(argc-1, argv+1); - exits(nil); - } - if(argc>1 && strcmp(argv[1], "BUNZIP") == 0){ - _unbzip(0, 1); - exits(nil); - } - - rfork(RFNOTEG); - stdin = 0; - file = nil; - namep = name; - mtpt = "/root"; - chatty = 0; - ARGBEGIN{ - case 'd': - chatty = !chatty; - break; - case 'f': - file = ARGF(); - break; - case 's': - stdin++; - break; - case 'm': - mtpt = ARGF(); - break; - default: - usage(); - }ARGEND - - if(argc != 0) - usage(); - - if(file == nil) { - fprint(2, "must specify -f file\n"); - usage(); - } - - if((fd = open(file, OREAD)) < 0) { - fprint(2, "cannot open \"%s\": %r\n", file); - exits("open"); - } - - rargv[0] = "ramfs"; - rargc = 1; - if(stdin) - rargv[rargc++] = "-i"; - rargv[rargc++] = "-m"; - rargv[rargc++] = mtpt; - rargv[rargc] = nil; - ramfsmain(rargc, rargv); - - if(1 || strstr(file, "disk")) { /* search for archive on block boundary */ -if(chatty) fprint(2, "searching for bz\n"); - for(i=0;; i++){ - if((n = readn(fd, blk, sizeof blk)) != sizeof blk) - sysfatal("read %d gets %d: %r\n", i, n); - if(strncmp(blk, "bzfilesystem\n", 13) == 0) - break; - } -if(chatty) fprint(2, "found at %d\n", i); - } - - if(chdir(mtpt) < 0) - error("chdir %s: %r", mtpt); - - fd = unbflz(unbzip(blockread(fd, blk+13, sizeof(blk)-13))); - - Binits(&bin, fd, OREAD, binbuf, sizeof binbuf); - while(p = Brdline(&bin, '\n')){ - p[Blinelen(&bin)-1] = '\0'; -if(chatty) fprint(2, "%s\n", p); - if(strcmp(p, "end of archive") == 0){ - _exits(0); - } - if(getfields(p, fields, NFLDS, 0, " \t") != NFLDS){ - warn("too few fields in file header"); - continue; - } - strcpy(namep, fields[0]); - mode = strtoul(fields[1], 0, 8); - mtime = strtoul(fields[4], 0, 10); - bytes = strtoul(fields[5], 0, 10); - strncpy(uid, fields[2], NAMELEN); - strncpy(gid, fields[3], NAMELEN); - if(mode & DMDIR) - mkdir(name, mode, mtime, uid, gid); - else - extract(name, mode, mtime, uid, gid, bytes); - } - fprint(2, "premature end of archive\n"); - exits("premature end of archive"); -} - -char buf[8192]; - -int -ffcreate(char *name, ulong mode, char *uid, char *gid, ulong mtime, int length) -{ - int fd, om; - Dir nd; - - sprint(buf, "%s/%s", mtpt, name); - om = ORDWR; - if(mode&DMDIR) - om = OREAD; - if((fd = create(buf, om, (mode&DMDIR)|0666)) < 0) - error("create %s: %r", buf); - - nulldir(&nd); - nd.mode = mode; - nd.uid = uid; - nd.gid = gid; - nd.mtime = mtime; - if(length) - nd.length = length; - if(dirfwstat(fd, &nd) < 0) - error("fwstat %s: %r", buf); - - return fd; -} - -void -mkdir(char *name, ulong mode, ulong mtime, char *uid, char *gid) -{ - close(ffcreate(name, mode, uid, gid, mtime, 0)); -} - -void -extract(char *name, ulong mode, ulong mtime, char *uid, char *gid, ulong bytes) -{ - int fd, tot, n; - - fd = ffcreate(name, mode, uid, gid, mtime, bytes); - - for(tot = 0; tot < bytes; tot += n){ - n = sizeof buf; - if(tot + n > bytes) - n = bytes - tot; - n = Bread(&bin, buf, n); - if(n <= 0) - error("premature eof reading %s", name); - if(write(fd, buf, n) != n) - error("short write writing %s", name); - } - close(fd); -} - -void -error(char *fmt, ...) -{ - char buf[1024]; - va_list arg; - - sprint(buf, "%s: ", argv0); - va_start(arg, fmt); - vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); - va_end(arg); - fprint(2, "%s\n", buf); - exits(0); -} - -void -warn(char *fmt, ...) -{ - char buf[1024]; - va_list arg; - - sprint(buf, "%s: ", argv0); - va_start(arg, fmt); - vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); - va_end(arg); - fprint(2, "%s\n", buf); -} - -int -_efgfmt(Fmt*) -{ - return -1; -} diff --git a/sys/lib/dist.old/cmd/bzfs/mkfile b/sys/lib/dist.old/cmd/bzfs/mkfile deleted file mode 100644 index df81b5641..000000000 --- a/sys/lib/dist.old/cmd/bzfs/mkfile +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include -#include -#include "bzfs.h" - -/* - * Rather than reading /adm/users, which is a lot of work for - * a toy program, we assume all groups have the form - * NNN:user:user: - * meaning that each user is the leader of his own group. - */ - -enum -{ - OPERM = 0x3, /* mask of all permission types in open mode */ - Nram = 512, - Maxsize = 512*1024*1024, - Maxfdata = 8192, -}; - -typedef struct Fid Fid; -typedef struct Ram Ram; - -struct Fid -{ - short busy; - short open; - short rclose; - int fid; - Fid *next; - char *user; - Ram *ram; -}; - -struct Ram -{ - short busy; - short open; - long parent; /* index in Ram array */ - Qid qid; - long perm; - char *name; - ulong atime; - ulong mtime; - char *user; - char *group; - char *muid; - char *data; - long ndata; -}; - -enum -{ - Pexec = 1, - Pwrite = 2, - Pread = 4, - Pother = 1, - Pgroup = 8, - Powner = 64, -}; - -ulong path; /* incremented for each new file */ -Fid *fids; -Ram ram[Nram]; -int nram; -int mfd[2]; -char *user; -uchar mdata[IOHDRSZ+Maxfdata]; -uchar rdata[Maxfdata]; /* buffer for data in reply */ -uchar statbuf[STATMAX]; -Fcall thdr; -Fcall rhdr; -int messagesize = sizeof mdata; - -Fid * newfid(int); -uint ramstat(Ram*, uchar*, uint); -void io(void); -void *erealloc(void*, ulong); -void *emalloc(ulong); -char *estrdup(char*); -void ramfsusage(void); -int perm(Fid*, Ram*, int); -char *atom(char*); - -char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*), - *rattach(Fid*), *rwalk(Fid*), - *ropen(Fid*), *rcreate(Fid*), - *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*), - *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*); - -char *(*fcalls[])(Fid*) = { - [Tversion] rversion, - [Tflush] rflush, - [Tauth] rauth, - [Tattach] rattach, - [Twalk] rwalk, - [Topen] ropen, - [Tcreate] rcreate, - [Tread] rread, - [Twrite] rwrite, - [Tclunk] rclunk, - [Tremove] rremove, - [Tstat] rstat, - [Twstat] rwstat, -}; - -char Eperm[] = "permission denied"; -char Enotdir[] = "not a directory"; -char Enoauth[] = "no authentication in ramfs"; -char Enotexist[] = "file does not exist"; -char Einuse[] = "file in use"; -char Eexist[] = "file exists"; -char Eisdir[] = "file is a directory"; -char Enotowner[] = "not owner"; -char Eisopen[] = "file already open for I/O"; -char Excl[] = "exclusive use file already open"; -char Ename[] = "illegal name"; -char Eversion[] = "unknown 9P version"; - -int debug; - -void -notifyf(void *a, char *s) -{ - USED(a); - if(strncmp(s, "interrupt", 9) == 0) - noted(NCONT); - noted(NDFLT); -} - -void -ramfsmain(int argc, char *argv[]) -{ - Ram *r; - char *defmnt; - int p[2]; - char buf[32]; - int fd, srvfd; - int stdio = 0; - - srvfd = -1; - defmnt = "/tmp"; - ARGBEGIN{ - case 'D': - debug = 1; - break; - case 'i': /* this is DIFFERENT from normal ramfs; use 1 for both for kernel */ - defmnt = 0; - stdio = 1; - srvfd = 0; - mfd[0] = 1; - mfd[1] = 1; - break; - case 's': - defmnt = 0; - break; - case 'm': - defmnt = ARGF(); - break; - default: - ramfsusage(); - }ARGEND - - if(!stdio){ - if(pipe(p) < 0) - error("pipe failed"); - srvfd = p[1]; - mfd[0] = p[0]; - mfd[1] = p[0]; - if(defmnt == 0){ - fd = create("#s/ramfs", OWRITE, 0666); - if(fd < 0) - error("create of /srv/ramfs failed"); - sprint(buf, "%d", p[1]); - if(write(fd, buf, strlen(buf)) < 0) - error("writing /srv/ramfs"); - } - } - - user = atom(getuser()); - notify(notifyf); - nram = 1; - r = &ram[0]; - r->busy = 1; - r->data = 0; - r->ndata = 0; - r->perm = DMDIR | 0775; - r->qid.type = QTDIR; - r->qid.path = 0LL; - r->qid.vers = 0; - r->parent = 0; - r->user = user; - r->group = user; - r->muid = user; - r->atime = time(0); - r->mtime = r->atime; - r->name = estrdup("."); - - if(debug) - fmtinstall('F', fcallfmt); - switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){ - case -1: - error("fork"); - case 0: - close(srvfd); - io(); - break; - default: - close(mfd[0]); /* don't deadlock if child fails */ - if(defmnt && mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) - error("mount failed: %r"); - } -} - -char* -rversion(Fid*) -{ - Fid *f; - - for(f = fids; f; f = f->next) - if(f->busy) - rclunk(f); - if(thdr.msize > sizeof mdata) - rhdr.msize = sizeof mdata; - else - rhdr.msize = thdr.msize; - messagesize = rhdr.msize; - if(strncmp(thdr.version, "9P2000", 6) != 0) - return Eversion; - rhdr.version = "9P2000"; - return 0; -} - -char* -rauth(Fid*) -{ - return "ramfs: no authentication required"; -} - -char* -rflush(Fid *f) -{ - USED(f); - return 0; -} - -char* -rattach(Fid *f) -{ - /* no authentication! */ - f->busy = 1; - f->rclose = 0; - f->ram = &ram[0]; - rhdr.qid = f->ram->qid; - if(thdr.uname[0]) - f->user = atom(thdr.uname); - else - f->user = atom("none"); - if(strcmp(user, "none") == 0) - user = f->user; - return 0; -} - -char* -clone(Fid *f, Fid **nf) -{ - if(f->open) - return Eisopen; - if(f->ram->busy == 0) - return Enotexist; - *nf = newfid(thdr.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 */ - return 0; -} - -char* -rwalk(Fid *f) -{ - Ram *r, *fram; - char *name; - Ram *parent; - Fid *nf; - char *err; - ulong t; - int i; - - err = nil; - nf = nil; - rhdr.nwqid = 0; - if(rhdr.newfid != rhdr.fid){ - err = clone(f, &nf); - if(err) - return err; - f = nf; /* walk the new fid */ - } - fram = f->ram; - if(thdr.nwname > 0){ - t = time(0); - for(i=0; iqid.type & QTDIR) == 0){ - err = Enotdir; - break; - } - if(fram->busy == 0){ - err = Enotexist; - break; - } - fram->atime = t; - name = thdr.wname[i]; - if(strcmp(name, ".") == 0){ - Found: - rhdr.nwqid++; - rhdr.wqid[i] = fram->qid; - continue; - } - parent = &ram[fram->parent]; -#ifdef CHECKS - if(!perm(f, parent, Pexec)){ - err = Eperm; - break; - } -#endif - if(strcmp(name, "..") == 0){ - fram = parent; - goto Found; - } - for(r=ram; r < &ram[nram]; r++) - if(r->busy && r->parent==fram-ram && strcmp(name, r->name)==0){ - fram = r; - goto Found; - } - break; - } - if(i==0 && err == nil) - err = Enotexist; - } - if(nf != nil && (err!=nil || rhdr.nwqidbusy = 0; - f->ram = nil; - } - if(rhdr.nwqid == thdr.nwname) /* update the fid after a successful walk */ - f->ram = fram; - return err; -} - -char * -ropen(Fid *f) -{ - Ram *r; - int mode, trunc; - - if(f->open) - return Eisopen; - r = f->ram; - if(r->busy == 0) - return Enotexist; - if(r->perm & DMEXCL) - if(r->open) - return Excl; - mode = thdr.mode; - if(r->qid.type & QTDIR){ - if(mode != OREAD) - return Eperm; - rhdr.qid = r->qid; - return 0; - } - if(mode & ORCLOSE){ - /* can't remove root; must be able to write parent */ - if(r->qid.path==0 || !perm(f, &ram[r->parent], Pwrite)) - return Eperm; - f->rclose = 1; - } - trunc = mode & OTRUNC; - mode &= OPERM; - if(mode==OWRITE || mode==ORDWR || trunc) - if(!perm(f, r, Pwrite)) - return Eperm; - if(mode==OREAD || mode==ORDWR) - if(!perm(f, r, Pread)) - return Eperm; - if(mode==OEXEC) - if(!perm(f, r, Pexec)) - return Eperm; - if(trunc && (r->perm&DMAPPEND)==0){ - r->ndata = 0; - if(r->data) - free(r->data); - r->data = 0; - r->qid.vers++; - } - rhdr.qid = r->qid; - rhdr.iounit = messagesize-IOHDRSZ; - f->open = 1; - r->open++; - return 0; -} - -char * -rcreate(Fid *f) -{ - Ram *r; - char *name; - long parent, prm; - - if(f->open) - return Eisopen; - if(f->ram->busy == 0) - return Enotexist; - parent = f->ram - ram; - if((f->ram->qid.type&QTDIR) == 0) - return Enotdir; - /* must be able to write parent */ -#ifdef CHECKS - if(!perm(f, f->ram, Pwrite)) - return Eperm; -#endif - prm = thdr.perm; - name = thdr.name; - if(strcmp(name, ".")==0 || strcmp(name, "..")==0) - return Ename; - for(r=ram; r<&ram[nram]; r++) - if(r->busy && parent==r->parent) - if(strcmp((char*)name, r->name)==0) - return Einuse; - for(r=ram; r->busy; r++) - if(r == &ram[Nram-1]) - return "no free ram resources"; - r->busy = 1; - r->qid.path = ++path; - r->qid.vers = 0; - if(prm & DMDIR) - r->qid.type |= QTDIR; - r->parent = parent; - free(r->name); - r->name = estrdup(name); - r->user = f->user; - r->group = f->ram->group; - r->muid = f->ram->muid; - if(prm & DMDIR) - prm = (prm&~0777) | (f->ram->perm&prm&0777); - else - prm = (prm&(~0777|0111)) | (f->ram->perm&prm&0666); - r->perm = prm; - r->ndata = 0; - if(r-ram >= nram) - nram = r - ram + 1; - r->atime = time(0); - r->mtime = r->atime; - f->ram->mtime = r->atime; - f->ram = r; - rhdr.qid = r->qid; - rhdr.iounit = messagesize-IOHDRSZ; - f->open = 1; - if(thdr.mode & ORCLOSE) - f->rclose = 1; - r->open++; - return 0; -} - -char* -rread(Fid *f) -{ - Ram *r; - uchar *buf; - long off; - int n, m, cnt; - - if(f->ram->busy == 0) - return Enotexist; - n = 0; - rhdr.count = 0; - off = thdr.offset; - buf = rdata; - cnt = thdr.count; - if(cnt > messagesize) /* shouldn't happen, anyway */ - cnt = messagesize; - if(f->ram->qid.type & QTDIR){ - for(r=ram+1; off > 0; r++){ - if(r->busy && r->parent==f->ram-ram) - off -= ramstat(r, statbuf, sizeof statbuf); - if(r == &ram[nram-1]) - return 0; - } - for(; r<&ram[nram] && n < cnt; r++){ - if(!r->busy || r->parent!=f->ram-ram) - continue; - m = ramstat(r, buf+n, cnt-n); - if(m == 0) - break; - n += m; - } - rhdr.data = (char*)rdata; - rhdr.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; - rhdr.data = r->data+off; - rhdr.count = n; - return 0; -} - -char* -rwrite(Fid *f) -{ - Ram *r; - ulong off; - int cnt; - - r = f->ram; - if(r->busy == 0) - return Enotexist; - off = thdr.offset; - if(r->perm & DMAPPEND) - off = r->ndata; - cnt = thdr.count; - if(r->qid.type & QTDIR) - return Eisdir; - if(off+cnt >= Maxsize) /* sanity check */ - return "write too big"; - if(off+cnt > r->ndata) - r->data = erealloc(r->data, off+cnt); - if(off > r->ndata) - memset(r->data+r->ndata, 0, off-r->ndata); - if(off+cnt > r->ndata) - r->ndata = off+cnt; - memmove(r->data+off, thdr.data, cnt); - r->qid.vers++; - r->mtime = time(0); - rhdr.count = cnt; - return 0; -} - -void -realremove(Ram *r) -{ - r->ndata = 0; - if(r->data) - free(r->data); - r->data = 0; - r->parent = 0; - memset(&r->qid, 0, sizeof r->qid); - free(r->name); - r->name = nil; - r->busy = 0; -} - -char * -rclunk(Fid *f) -{ - if(f->open) - f->ram->open--; - if(f->rclose) - realremove(f->ram); - f->busy = 0; - f->open = 0; - f->ram = 0; - return 0; -} - -char * -rremove(Fid *f) -{ - Ram *r; - - if(f->open) - f->ram->open--; - f->busy = 0; - f->open = 0; - r = f->ram; - f->ram = 0; -#ifdef CHECKS - if(r->qid.path == 0 || !perm(f, &ram[r->parent], Pwrite)) - return Eperm; -#endif - ram[r->parent].mtime = time(0); - realremove(r); - return 0; -} - -char * -rstat(Fid *f) -{ - if(f->ram->busy == 0) - return Enotexist; - rhdr.nstat = ramstat(f->ram, statbuf, sizeof statbuf); - rhdr.stat = statbuf; - return 0; -} - -char * -rwstat(Fid *f) -{ - Ram *r, *s; - Dir dir; - - if(f->ram->busy == 0) - return Enotexist; - convM2D(thdr.stat, thdr.nstat, &dir, (char*)statbuf); - r = f->ram; - - /* - * To change length, must have write permission on file. - */ -#ifdef CHECKS - if(dir.length!=~0 && dir.length!=r->ndata){ - if(!perm(f, r, Pwrite)) - return Eperm; - } -#endif - - /* - * To change name, must have write permission in parent - * and name must be unique. - */ - if(dir.name[0]!='\0' && strcmp(dir.name, r->name)!=0){ -#ifdef CHECKS - if(!perm(f, &ram[r->parent], Pwrite)) - return Eperm; -#endif - for(s=ram; s<&ram[nram]; s++) - if(s->busy && s->parent==r->parent) - if(strcmp(dir.name, s->name)==0) - return Eexist; - } - -#ifdef OWNERS - /* - * To change mode, must be owner or group leader. - * Because of lack of users file, leader=>group itself. - */ - if(dir.mode!=~0 && r->perm!=dir.mode){ - if(strcmp(f->user, r->user) != 0) - if(strcmp(f->user, r->group) != 0) - return Enotowner; - } - - /* - * To change group, must be owner and member of new group, - * or leader of current group and leader of new group. - * Second case cannot happen, but we check anyway. - */ - if(dir.gid[0]!='\0' && strcmp(r->group, dir.gid)!=0){ - if(strcmp(f->user, r->user) == 0) - if(strcmp(f->user, dir.gid) == 0) - goto ok; - if(strcmp(f->user, r->group) == 0) - if(strcmp(f->user, dir.gid) == 0) - goto ok; - return Enotowner; - ok:; - } -#endif - - /* all ok; do it */ - if(dir.mode != ~0){ - dir.mode &= ~DMDIR; /* cannot change dir bit */ - dir.mode |= r->perm&DMDIR; - r->perm = dir.mode; - } - if(dir.name[0] != '\0'){ - free(r->name); - r->name = estrdup(dir.name); - } - if(dir.gid[0] != '\0') - r->group = atom(dir.gid); - - if(dir.uid[0] != '\0') - r->user = atom(dir.uid); - - if(dir.length!=~0 && dir.length!=r->ndata){ - r->data = erealloc(r->data, dir.length); - if(r->ndata < dir.length) - memset(r->data+r->ndata, 0, dir.length-r->ndata); - r->ndata = dir.length; - } - - if(dir.mtime != ~0) - r->mtime = dir.mtime; - - ram[r->parent].mtime = time(0); - return 0; -} - -uint -ramstat(Ram *r, uchar *buf, uint nbuf) -{ - Dir dir; - - dir.name = r->name; - dir.qid = r->qid; - dir.mode = r->perm; - dir.length = r->ndata; - dir.uid = r->user; - dir.gid = r->group; - dir.muid = r->muid; - dir.atime = r->atime; - dir.mtime = r->mtime; - return convD2M(&dir, buf, nbuf); -} - -Fid * -newfid(int fid) -{ - Fid *f, *ff; - - ff = 0; - for(f = fids; f; f = f->next) - if(f->fid == fid) - return f; - else if(!ff && !f->busy) - ff = f; - if(ff){ - ff->fid = fid; - return ff; - } - f = emalloc(sizeof *f); - f->ram = nil; - f->fid = fid; - f->next = fids; - fids = f; - return f; -} - -void -io(void) -{ - char *err; - int n, pid; - - pid = getpid(); - - for(;;){ - /* - * reading from a pipe or a network device - * will give an error after a few eof reads. - * however, we cannot tell the difference - * between a zero-length read and an interrupt - * on the processes writing to us, - * so we wait for the error. - */ - n = read9pmsg(mfd[0], mdata, messagesize); - if(n < 0) - error("mount read: %r"); - if(n == 0) - continue; - if(convM2S(mdata, n, &thdr) == 0) - continue; - - if(debug) - fprint(2, "ramfs %d:<-%F\n", pid, &thdr); - - if(!fcalls[thdr.type]) - err = "bad fcall type"; - else - err = (*fcalls[thdr.type])(newfid(thdr.fid)); - if(err){ - rhdr.type = Rerror; - rhdr.ename = err; - }else{ - rhdr.type = thdr.type + 1; - rhdr.fid = thdr.fid; - } - rhdr.tag = thdr.tag; - if(debug) - fprint(2, "ramfs %d:->%F\n", pid, &rhdr);/**/ - n = convS2M(&rhdr, mdata, messagesize); - if(n == 0) - error("convS2M error on write"); - if(write(mfd[1], mdata, n) != n) - error("mount write"); - } -} - -int -perm(Fid *f, Ram *r, int p) -{ - if((p*Pother) & r->perm) - return 1; - if(strcmp(f->user, r->group)==0 && ((p*Pgroup) & r->perm)) - return 1; - if(strcmp(f->user, r->user)==0 && ((p*Powner) & r->perm)) - return 1; - return 0; -} - -void * -emalloc(ulong n) -{ - void *p; - - p = malloc(n); - if(!p) - error("out of memory"); - memset(p, 0, n); - return p; -} - -void * -erealloc(void *p, ulong n) -{ - p = realloc(p, n); - if(!p) - error("out of memory"); - return p; -} - -char * -estrdup(char *q) -{ - char *p; - int n; - - n = strlen(q)+1; - p = malloc(n); - if(!p) - error("out of memory"); - memmove(p, q, n); - return p; -} - -void -ramfsusage(void) -{ - fprint(2, "usage: %s [-is] [-m mountpoint]\n", argv0); - exits("usage"); -} - -/* - * Custom allocators to avoid malloc overheads on small objects. - * We never free these. (See below.) - */ -typedef struct Stringtab Stringtab; -struct Stringtab { - Stringtab *link; - char *str; -}; -static Stringtab* -taballoc(void) -{ - static Stringtab *t; - static uint nt; - - if(nt == 0){ - t = malloc(64*sizeof(Stringtab)); - if(t == 0) - sysfatal("out of memory"); - nt = 64; - } - nt--; - return t++; -} - -static char* -xstrdup(char *s) -{ - char *r; - int len; - static char *t; - static int nt; - - len = strlen(s)+1; - if(len >= 8192) - sysfatal("strdup big string"); - - if(nt < len){ - t = malloc(8192); - if(t == 0) - sysfatal("out of memory"); - nt = 8192; - } - r = t; - t += len; - nt -= len; - strcpy(r, s); - return r; -} - -/* - * Return a uniquely allocated copy of a string. - * Don't free these -- they stay in the table for the - * next caller who wants that particular string. - * String comparison can be done with pointer comparison - * if you know both strings are atoms. - */ -static Stringtab *stab[1024]; - -static uint -hash(char *s) -{ - uint h; - uchar *p; - - h = 0; - for(p=(uchar*)s; *p; p++) - h = h*37 + *p; - return h; -} - -char* -atom(char *str) -{ - uint h; - Stringtab *tab; - - h = hash(str) % nelem(stab); - for(tab=stab[h]; tab; tab=tab->link) - if(strcmp(str, tab->str) == 0) - return tab->str; - - tab = taballoc(); - tab->str = xstrdup(str); - tab->link = stab[h]; - stab[h] = tab; - return tab->str; -} diff --git a/sys/lib/dist.old/cmd/bzfs/unbflz.c b/sys/lib/dist.old/cmd/bzfs/unbflz.c deleted file mode 100644 index 661d65e4d..000000000 --- a/sys/lib/dist.old/cmd/bzfs/unbflz.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include "bzfs.h" - -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]; -} - -/* - * memmove but make sure overlap works properly. - */ -void -copy(uchar *dst, uchar *src, int n) -{ - while(n-- > 0) - *dst++ = *src++; -} - -int -unbflz(int in) -{ - int rv, out, p[2]; - Biobuf *b, bin; - char buf[5]; - uchar *data; - int i, j, length, n, m, o, sum; - ulong *blk; - int nblk, mblk; - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - - rv = p[0]; - out = p[1]; - switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ - case -1: - sysfatal("fork: %r"); - case 0: - close(rv); - break; - default: - close(in); - close(out); - return rv; - } - - Binit(&bin, in, OREAD); - b = &bin; - - if(Bread(b, buf, 4) != 4) - sysfatal("short read"); - - if(memcmp(buf, "BLZ\n", 4) != 0) - sysfatal("bad header"); - - length = Bgetint(b); - data = malloc(length); - if(data == nil) - sysfatal("out of memory"); - sum = 0; - nblk = 0; - mblk = 0; - blk = nil; - while(sum < length){ - if(nblk>=mblk){ - mblk += 16384; - blk = realloc(blk, (mblk+1)*sizeof(blk[0])); - if(blk == nil) - sysfatal("out of memory"); - } - n = Bgetint(b); - blk[nblk++] = n; - if(n&(1<<31)) - n &= ~(1<<31); - else - blk[nblk++] = Bgetint(b); - sum += n; - } - if(sum != length) - sysfatal("bad compressed data %d %d", sum, length); - i = 0; - j = 0; - while(i < length){ - assert(j < nblk); - n = blk[j++]; - if(n&(1<<31)){ - n &= ~(1<<31); - if((m=Bread(b, data+i, n)) != n) - sysfatal("short read %d %d", n, m); - }else{ - o = blk[j++]; - copy(data+i, data+o, n); - } - i += n; - } - write(out, data, length); - close(in); - close(out); - _exits(0); - return -1; -} diff --git a/sys/lib/dist.old/cmd/bzfs/unbzip.c b/sys/lib/dist.old/cmd/bzfs/unbzip.c deleted file mode 100644 index 070e7ba48..000000000 --- a/sys/lib/dist.old/cmd/bzfs/unbzip.c +++ /dev/null @@ -1,861 +0,0 @@ -#include -#include -#include -#include "bzfs.h" - -/* - * THIS FILE IS NOT IDENTICAL TO THE ORIGINAL - * FROM THE BZIP2 DISTRIBUTION. - * - * It has been modified, mainly to break the library - * into smaller pieces. - * - * Russ Cox - * rsc@plan9.bell-labs.com - * July 2000 - */ - -/*---------------------------------------------*/ -/*-- - Place a 1 beside your platform, and 0 elsewhere. - Attempts to autosniff this even if you don't. ---*/ - - -/*-- - Plan 9 from Bell Labs ---*/ -#define BZ_PLAN9 1 -#define BZ_UNIX 0 - -#define exit(x) exits((x) ? "whoops" : nil) -#define size_t ulong - -#ifdef __GNUC__ -# define NORETURN __attribute__ ((noreturn)) -#else -# define NORETURN /**/ -#endif - -/*-- - Some more stuff for all platforms :-) - This might have to get moved into the platform-specific - header files if we encounter a machine with different sizes. ---*/ - -typedef char Char; -typedef unsigned char Bool; -typedef unsigned char UChar; -typedef int Int32; -typedef unsigned int UInt32; -typedef short Int16; -typedef unsigned short UInt16; - -#define True ((Bool)1) -#define False ((Bool)0) - -/*-- - IntNative is your platform's `native' int size. - Only here to avoid probs with 64-bit platforms. ---*/ -typedef int IntNative; - -#include "bzfs.h" -#include "bzlib.h" -#include "bzlib_private.h" - -static int -bunzip(int ofd, char *ofile, Biobuf *bin) -{ - int e, n, done, onemore; - char buf[8192]; - char obuf[8192]; - Biobuf bout; - bz_stream strm; - - USED(ofile); - - memset(&strm, 0, sizeof strm); - BZ2_bzDecompressInit(&strm, 0, 0); - - strm.next_in = buf; - strm.avail_in = 0; - strm.next_out = obuf; - strm.avail_out = sizeof obuf; - - done = 0; - Binit(&bout, ofd, OWRITE); - - /* - * onemore is a crummy hack to go 'round the loop - * once after we finish, to flush the output buffer. - */ - onemore = 1; - SET(e); - do { - if(!done && strm.avail_in < sizeof buf) { - if(strm.avail_in) - memmove(buf, strm.next_in, strm.avail_in); - - n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in); - if(n <= 0) - done = 1; - else - strm.avail_in += n; - strm.next_in = buf; - } - if(strm.avail_out < sizeof obuf) { - Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out); - strm.next_out = obuf; - strm.avail_out = sizeof obuf; - } - - if(onemore == 0) - break; - } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--); - - if(e != BZ_STREAM_END) { - fprint(2, "bunzip2: decompress failed\n"); - return 0; - } - - if(BZ2_bzDecompressEnd(&strm) != BZ_OK) { - fprint(2, "bunzip2: decompress end failed (can't happen)\n"); - return 0; - } - - Bterm(&bout); - - return 1; -} - -void -_unbzip(int in, int out) -{ - Biobuf bin; - - Binit(&bin, in, OREAD); - if(bunzip(out, nil, &bin) != 1) { - fprint(2, "bunzip2 failed\n"); - _exits("bunzip2"); - } -} - -int -unbzip(int in) -{ - int rv, out, p[2]; - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - - rv = p[0]; - out = p[1]; - switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ - case -1: - sysfatal("fork: %r"); - case 0: - close(rv); - break; - default: - close(in); - close(out); - return rv; - } - - _unbzip(in, out); - _exits(0); - return -1; /* not reached */ -} - -int bz_config_ok ( void ) -{ - if (sizeof(int) != 4) return 0; - if (sizeof(short) != 2) return 0; - if (sizeof(char) != 1) return 0; - return 1; -} - -void* default_bzalloc(void *o, int items, int size) -{ - USED(o); - return sbrk(items*size); -} - -void default_bzfree(void*, void*) -{ -} - -void -bz_internal_error(int) -{ - abort(); -} - -/*-------------------------------------------------------------*/ -/*--- Decompression machinery ---*/ -/*--- decompress.c ---*/ -/*-------------------------------------------------------------*/ - -/*-- - This file is a part of bzip2 and/or libbzip2, a program and - library for lossless, block-sorting data compression. - - Copyright (C) 1996-2000 Julian R Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Julian Seward, Cambridge, UK. - jseward@acm.org - bzip2/libbzip2 version 1.0 of 21 March 2000 - - This program is based on (at least) the work of: - Mike Burrows - David Wheeler - Peter Fenwick - Alistair Moffat - Radford Neal - Ian H. Witten - Robert Sedgewick - Jon L. Bentley - - For more information on these sources, see the manual. ---*/ - - - -/*---------------------------------------------------*/ -static -void makeMaps_d ( DState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->seqToUnseq[s->nInUse] = i; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -#define RETURN(rrr) \ - { retVal = rrr; goto save_state_and_return; }; - -#define GET_BITS(lll,vvv,nnn) \ - case lll: \ - { int x; if((retVal = getbits(s, lll, &x, nnn)) != 99) \ - goto save_state_and_return; vvv=x; }\ - -int -getbits(DState *s, int lll, int *vvv, int nnn) -{ - s->state = lll; - - for(;;) { - if (s->bsLive >= nnn) { - UInt32 v; - v = (s->bsBuff >> - (s->bsLive-nnn)) & ((1 << nnn)-1); - s->bsLive -= nnn; - *vvv = v; - return 99; - } - if (s->strm->avail_in == 0) return BZ_OK; - s->bsBuff - = (s->bsBuff << 8) | - ((UInt32) - (*((UChar*)(s->strm->next_in)))); - s->bsLive += 8; - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) - s->strm->total_in_hi32++; - } - return -1; /* KEN */ -} - -#define GET_UCHAR(lll,uuu) \ - GET_BITS(lll,uuu,8) - -#define GET_BIT(lll,uuu) \ - GET_BITS(lll,uuu,1) - -/*---------------------------------------------------*/ -#define GET_MTF_VAL(label1,label2,lval) \ -{ \ - if (groupPos == 0) { \ - groupNo++; \ - if (groupNo >= nSelectors) \ - RETURN(BZ_DATA_ERROR); \ - groupPos = BZ_G_SIZE; \ - gSel = s->selector[groupNo]; \ - gMinlen = s->minLens[gSel]; \ - gLimit = &(s->limit[gSel][0]); \ - gPerm = &(s->perm[gSel][0]); \ - gBase = &(s->base[gSel][0]); \ - } \ - groupPos--; \ - zn = gMinlen; \ - GET_BITS(label1, zvec, zn); \ - while (1) { \ - if (zn > 20 /* the longest code */) \ - RETURN(BZ_DATA_ERROR); \ - if (zvec <= gLimit[zn]) break; \ - zn++; \ - GET_BIT(label2, zj); \ - zvec = (zvec << 1) | zj; \ - }; \ - if (zvec - gBase[zn] < 0 \ - || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ - RETURN(BZ_DATA_ERROR); \ - lval = gPerm[zvec - gBase[zn]]; \ -} - - -/*---------------------------------------------------*/ -Int32 BZ2_decompress ( DState* s ) -{ - UChar uc; - Int32 retVal; - Int32 minLen, maxLen; - bz_stream* strm = s->strm; - - /* stuff that needs to be saved/restored */ - Int32 i; - Int32 j; - Int32 t; - Int32 alphaSize; - Int32 nGroups; - Int32 nSelectors; - Int32 EOB; - Int32 groupNo; - Int32 groupPos; - Int32 nextSym; - Int32 nblockMAX; - Int32 nblock; - Int32 es; - Int32 N; - Int32 curr; - Int32 zt; - Int32 zn; - Int32 zvec; - Int32 zj; - Int32 gSel; - Int32 gMinlen; - Int32* gLimit; - Int32* gBase; - Int32* gPerm; - - if (s->state == BZ_X_MAGIC_1) { - /*initialise the save area*/ - s->save_i = 0; - s->save_j = 0; - s->save_t = 0; - s->save_alphaSize = 0; - s->save_nGroups = 0; - s->save_nSelectors = 0; - s->save_EOB = 0; - s->save_groupNo = 0; - s->save_groupPos = 0; - s->save_nextSym = 0; - s->save_nblockMAX = 0; - s->save_nblock = 0; - s->save_es = 0; - s->save_N = 0; - s->save_curr = 0; - s->save_zt = 0; - s->save_zn = 0; - s->save_zvec = 0; - s->save_zj = 0; - s->save_gSel = 0; - s->save_gMinlen = 0; - s->save_gLimit = NULL; - s->save_gBase = NULL; - s->save_gPerm = NULL; - } - - /*restore from the save area*/ - i = s->save_i; - j = s->save_j; - t = s->save_t; - alphaSize = s->save_alphaSize; - nGroups = s->save_nGroups; - nSelectors = s->save_nSelectors; - EOB = s->save_EOB; - groupNo = s->save_groupNo; - groupPos = s->save_groupPos; - nextSym = s->save_nextSym; - nblockMAX = s->save_nblockMAX; - nblock = s->save_nblock; - es = s->save_es; - N = s->save_N; - curr = s->save_curr; - zt = s->save_zt; - zn = s->save_zn; - zvec = s->save_zvec; - zj = s->save_zj; - gSel = s->save_gSel; - gMinlen = s->save_gMinlen; - gLimit = s->save_gLimit; - gBase = s->save_gBase; - gPerm = s->save_gPerm; - - retVal = BZ_OK; - - switch (s->state) { - - GET_UCHAR(BZ_X_MAGIC_1, uc); - if (uc != 'B') RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_2, uc); - if (uc != 'Z') RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_3, uc) - if (uc != 'h') RETURN(BZ_DATA_ERROR_MAGIC); - - GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) - if (s->blockSize100k < '1' || - s->blockSize100k > '9') RETURN(BZ_DATA_ERROR_MAGIC); - s->blockSize100k -= '0'; - - if (0 && s->smallDecompress) { - s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); - s->ll4 = BZALLOC( - ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) - ); - if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); - } else { - s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); - if (s->tt == NULL) RETURN(BZ_MEM_ERROR); - } - - GET_UCHAR(BZ_X_BLKHDR_1, uc); - - if (uc == 0x17) goto endhdr_2; - if (uc != 0x31) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_2, uc); - if (uc != 0x41) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_3, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_4, uc); - if (uc != 0x26) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_5, uc); - if (uc != 0x53) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_6, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - - s->currBlockNo++; - // if (s->verbosity >= 2) - // VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); - - s->storedBlockCRC = 0; - GET_UCHAR(BZ_X_BCRC_1, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_2, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_3, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_4, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - - GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); - - s->origPtr = 0; - GET_UCHAR(BZ_X_ORIGPTR_1, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_2, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_3, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - - if (s->origPtr < 0) - RETURN(BZ_DATA_ERROR); - if (s->origPtr > 10 + 100000*s->blockSize100k) - RETURN(BZ_DATA_ERROR); - - /*--- Receive the mapping table ---*/ - for (i = 0; i < 16; i++) { - GET_BIT(BZ_X_MAPPING_1, uc); - if (uc == 1) - s->inUse16[i] = True; else - s->inUse16[i] = False; - } - - for (i = 0; i < 256; i++) s->inUse[i] = False; - - for (i = 0; i < 16; i++) - if (s->inUse16[i]) - for (j = 0; j < 16; j++) { - GET_BIT(BZ_X_MAPPING_2, uc); - if (uc == 1) s->inUse[i * 16 + j] = True; - } - makeMaps_d ( s ); - if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); - alphaSize = s->nInUse+2; - - /*--- Now the selectors ---*/ - GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); - if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); - GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); - if (nSelectors < 1) RETURN(BZ_DATA_ERROR); - for (i = 0; i < nSelectors; i++) { - j = 0; - while (True) { - GET_BIT(BZ_X_SELECTOR_3, uc); - if (uc == 0) break; - j++; - if (j >= nGroups) RETURN(BZ_DATA_ERROR); - } - s->selectorMtf[i] = j; - } - - /*--- Undo the MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], tmp, v; - for (v = 0; v < nGroups; v++) pos[v] = v; - - for (i = 0; i < nSelectors; i++) { - v = s->selectorMtf[i]; - tmp = pos[v]; - while (v > 0) { pos[v] = pos[v-1]; v--; } - pos[0] = tmp; - s->selector[i] = tmp; - } - } - - /*--- Now the coding tables ---*/ - for (t = 0; t < nGroups; t++) { - GET_BITS(BZ_X_CODING_1, curr, 5); - for (i = 0; i < alphaSize; i++) { - while (True) { - if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); - GET_BIT(BZ_X_CODING_2, uc); - if (uc == 0) break; - GET_BIT(BZ_X_CODING_3, uc); - if (uc == 0) curr++; else curr--; - } - s->len[t][i] = curr; - } - } - - /*--- Create the Huffman decoding tables ---*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - BZ2_hbCreateDecodeTables ( - &(s->limit[t][0]), - &(s->base[t][0]), - &(s->perm[t][0]), - &(s->len[t][0]), - minLen, maxLen, alphaSize - ); - s->minLens[t] = minLen; - } - - /*--- Now the MTF values ---*/ - - EOB = s->nInUse+1; - nblockMAX = 100000 * s->blockSize100k; - groupNo = -1; - groupPos = 0; - - for (i = 0; i <= 255; i++) s->unzftab[i] = 0; - - /*-- MTF init --*/ - { - Int32 ii, jj, kk; - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - /*-- end MTF init --*/ - - nblock = 0; - GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); - - while (True) { - - if (nextSym == EOB) break; - - if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { - - es = -1; - N = 1; - do { - if (nextSym == BZ_RUNA) es = es + (0+1) * N; else - if (nextSym == BZ_RUNB) es = es + (1+1) * N; - N = N * 2; - GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); - } - while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); - - es++; - uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; - s->unzftab[uc] += es; - - if (0 && s->smallDecompress) - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->ll16[nblock] = (UInt16)uc; - nblock++; - es--; - } - else - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->tt[nblock] = (UInt32)uc; - nblock++; - es--; - }; - - continue; - - } else { - - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - - /*-- uc = MTF ( nextSym-1 ) --*/ - { - Int32 ii, jj, kk, pp, lno, off; - UInt32 nn; - nn = (UInt32)(nextSym - 1); - - if (nn < MTFL_SIZE) { - /* avoid general-case expense */ - pp = s->mtfbase[0]; - uc = s->mtfa[pp+nn]; - while (nn > 3) { - Int32 z = pp+nn; - s->mtfa[(z) ] = s->mtfa[(z)-1]; - s->mtfa[(z)-1] = s->mtfa[(z)-2]; - s->mtfa[(z)-2] = s->mtfa[(z)-3]; - s->mtfa[(z)-3] = s->mtfa[(z)-4]; - nn -= 4; - } - while (nn > 0) { - s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; - }; - s->mtfa[pp] = uc; - } else { - /* general case */ - lno = nn / MTFL_SIZE; - off = nn % MTFL_SIZE; - pp = s->mtfbase[lno] + off; - uc = s->mtfa[pp]; - while (pp > s->mtfbase[lno]) { - s->mtfa[pp] = s->mtfa[pp-1]; pp--; - }; - s->mtfbase[lno]++; - while (lno > 0) { - s->mtfbase[lno]--; - s->mtfa[s->mtfbase[lno]] - = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; - lno--; - } - s->mtfbase[0]--; - s->mtfa[s->mtfbase[0]] = uc; - if (s->mtfbase[0] == 0) { - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - } - } - /*-- end uc = MTF ( nextSym-1 ) --*/ - - s->unzftab[s->seqToUnseq[uc]]++; - if (0 && s->smallDecompress) - s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else - s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); - nblock++; - - GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); - continue; - } - } - - /* Now we know what nblock is, we can do a better sanity - check on s->origPtr. - */ - if (s->origPtr < 0 || s->origPtr >= nblock) - RETURN(BZ_DATA_ERROR); - - s->state_out_len = 0; - s->state_out_ch = 0; - BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); - s->state = BZ_X_OUTPUT; - // if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); - - /*-- Set up cftab to facilitate generation of T^(-1) --*/ - s->cftab[0] = 0; - for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; - for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; - - if (0 && s->smallDecompress) { - - /*-- Make a copy of cftab, used in generation of T --*/ - for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; - - /*-- compute the T vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->ll16[i]); - SET_LL(i, s->cftabCopy[uc]); - s->cftabCopy[uc]++; - } - - /*-- Compute T^(-1) by pointer reversal on T --*/ - i = s->origPtr; - j = GET_LL(i); - do { - Int32 tmp = GET_LL(j); - SET_LL(j, i); - i = j; - j = tmp; - } - while (i != s->origPtr); - - s->tPos = s->origPtr; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_SMALL(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } else { - - /*-- compute the T^(-1) vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->tt[i] & 0xff); - s->tt[s->cftab[uc]] |= (i << 8); - s->cftab[uc]++; - } - - s->tPos = s->tt[s->origPtr] >> 8; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_FAST(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_FAST(s->k0); s->nblock_used++; - } - - } - - RETURN(BZ_OK); - - - - endhdr_2: - - GET_UCHAR(BZ_X_ENDHDR_2, uc); - if (uc != 0x72) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_3, uc); - if (uc != 0x45) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_4, uc); - if (uc != 0x38) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_5, uc); - if (uc != 0x50) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_6, uc); - if (uc != 0x90) RETURN(BZ_DATA_ERROR); - - s->storedCombinedCRC = 0; - GET_UCHAR(BZ_X_CCRC_1, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_2, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_3, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_4, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - - s->state = BZ_X_IDLE; - RETURN(BZ_STREAM_END); - - default: AssertH ( False, 4001 ); - } - - AssertH ( False, 4002 ); - - save_state_and_return: - - s->save_i = i; - s->save_j = j; - s->save_t = t; - s->save_alphaSize = alphaSize; - s->save_nGroups = nGroups; - s->save_nSelectors = nSelectors; - s->save_EOB = EOB; - s->save_groupNo = groupNo; - s->save_groupPos = groupPos; - s->save_nextSym = nextSym; - s->save_nblockMAX = nblockMAX; - s->save_nblock = nblock; - s->save_es = es; - s->save_N = N; - s->save_curr = curr; - s->save_zt = zt; - s->save_zn = zn; - s->save_zvec = zvec; - s->save_zj = zj; - s->save_gSel = gSel; - s->save_gMinlen = gMinlen; - s->save_gLimit = gLimit; - s->save_gBase = gBase; - s->save_gPerm = gPerm; - - return retVal; -} - - -/*-------------------------------------------------------------*/ -/*--- end decompress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/sys/lib/dist.old/cmd/cdsh.c b/sys/lib/dist.old/cmd/cdsh.c deleted file mode 100644 index 2162350bf..000000000 --- a/sys/lib/dist.old/cmd/cdsh.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * The `cd' shell. - * Just has cd and lc. - */ - -#include -#include -#include - -char *pwd; -char *root = "/"; - -void -usage(void) -{ - fprint(2, "usage: cdsh [-r root]\n"); - exits("usage"); -} - -int -system(char *cmd) -{ - int pid; - if((pid = fork()) < 0) - return -1; - - if(pid == 0) { - dup(2, 1); - execl("/bin/rc", "rc", "-c", cmd, nil); - exits("exec"); - } - waitpid(); - return 0; -} - -int -cd(char *s) -{ - char *newpwd; - int l; - - if(s[0] == '/') { - cleanname(s); - newpwd = strdup(s); - } else { - l = strlen(pwd)+1+strlen(s)+1+50; /* 50 = crud for unicode mistakes */ - newpwd = malloc(l); - snprint(newpwd, l, "%s/%s", pwd, s); - cleanname(newpwd); - assert(newpwd[0] == '/'); - } - - if(chdir(root) < 0 || (newpwd[1] != '\0' && chdir(newpwd+1) < 0)) { - chdir(root); - chdir(pwd+1); - free(newpwd); - return -1; - } else { - free(pwd); - pwd = newpwd; - return 0; - } -} - -void -main(int argc, char **argv) -{ - char *p; - Biobuf bin; - char *f[2]; - int nf; - - ARGBEGIN{ - case 'r': - root = ARGF(); - if(root == nil) - usage(); - if(root[0] != '/') { - fprint(2, "root must be rooted\n"); - exits("root"); - } - break; - default: - usage(); - }ARGEND; - - if(argc != 0) - usage(); - - cleanname(root); - if(cd("/") < 0) { - fprint(2, "cannot cd %s: %r\n", root); - exits("root"); - } - - Binit(&bin, 0, OREAD); - while(fprint(2, "%s%% ", pwd), (p = Brdline(&bin, '\n'))) { - p[Blinelen(&bin)-1] = '\0'; - nf = tokenize(p, f, nelem(f)); - if(nf < 1) - continue; - if(strcmp(f[0], "exit") == 0) - break; - if(strcmp(f[0], "lc") == 0) { - if(nf == 1) { - if(system("/bin/lc") < 0) - fprint(2, "lc: %r\n"); - } else if(nf == 2) { - if(strpbrk(p, "'`{}^@$#&()|\\;><")) - fprint(2, "no shell characters allowed\n"); - else { - p = f[1]; - *--p = ' '; - *--p = 'c'; - *--p = 'l'; - if(system(p) < 0) - fprint(2, "lc: %r\n"); - } - } - continue; - } - if(strcmp(f[0], "cd") == 0) { - if(nf < 2) - fprint(2, "usage: cd dir\n"); - else if(cd(f[1]) < 0) - fprint(2, "cd: %r\n"); - continue; - } - fprint(2, "commands are cd, lc, and exit\n"); - } - - print("%s\n", pwd); -} diff --git a/sys/lib/dist.old/cmd/clog.c b/sys/lib/dist.old/cmd/clog.c deleted file mode 100644 index 98d1cf5f5..000000000 --- a/sys/lib/dist.old/cmd/clog.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -char *argv0; - -int -openlog(char *name) -{ - int fd; - - fd = open(name, OWRITE); - if(fd < 0){ - fprint(2, "%s: can't open %s: %r\n", argv0, name); - return -1; - } - seek(fd, 0, 2); - return fd; -} - -void -main(int argc, char **argv) -{ - Biobuf in; - int fd; - char *p, *t; - char buf[8192]; - - argv0 = argv[0]; - if(argc != 4){ - fprint(2, "usage: %s console logfile prefix\n", argv0); - exits("usage"); - } - - fd = open(argv[1], OREAD); - if(fd < 0){ - fprint(2, "%s: can't open %s: %r\n", argv0, argv[1]); - exits("open"); - } - Binit(&in, fd, OREAD); - - fd = openlog(argv[2]); - - for(;;){ - if(p = Brdline(&in, '\n')){ - p[Blinelen(&in)-1] = 0; - if(fprint(fd, "%s: %s\n", argv[3], p) < 0){ - close(fd); - fd = openlog(argv[2]); - fprint(fd, "%s: %s\n", t, p); - } - } else if(Blinelen(&in) == 0) // true eof - break; - else { - Bread(&in, buf, sizeof buf); - } - } - exits(0); -} diff --git a/sys/lib/dist.old/cmd/multi/mkfile b/sys/lib/dist.old/cmd/multi/mkfile deleted file mode 100644 index a3acc36de..000000000 --- a/sys/lib/dist.old/cmd/multi/mkfile +++ /dev/null @@ -1,76 +0,0 @@ -objtype=386 ->../../pc/multi/$b - chmod +x ../../pc/multi/$b - } - -BIN=/sys/lib/dist/bin/$objtype -multi.h ->multiproto.h - -for(i){ -echo $i... - b=`{basename $i} - p=$b - if(~ $b [0-9]*) - p=_$b - echo void $p^_main'(int, char**);' >>$dir/multiproto.h - echo "$b", $p^_main, >>$dir/multi.h - d=`{basename -d $i} - if(~ $i disk/prep disk/fdisk){ - cd /sys/src/cmd/disk/prep - rm 8.$b - files=`{mk 8.$b | getfiles} - } - if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.out}){ - cd /sys/src/cmd/$i - rm 8.out - files=`{mk 8.out | getfiles} - } - if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.$b}){ - cd /sys/src/cmd/$i - rm 8.out - files=`{mk 8.$b | getfiles} - } - if not if(test -d /sys/src/cmd/$d && @{cd /sys/src/cmd/$d && mk 8.$b}){ - cd /sys/src/cmd/$d - rm 8.$b - files=`{mk 8.$b | getfiles} - } - if not{ - echo do not know how to make $i - exit oops - } - aux/8prefix $p^_ $files - grab $files - switch(`{pwd}){ - case /sys/src/cmd /sys/src/cmd/aux /sys/src/cmd/ip - rm 8.$b - case * - mk clean - } -} -cd $dir -8c -FVw multi.c -8l -o 8.$targ multi.8 a.*.8 -# rm a.*.8 diff --git a/sys/lib/dist.old/cmd/multi/multi.c b/sys/lib/dist.old/cmd/multi/multi.c deleted file mode 100644 index a2e3035ad..000000000 --- a/sys/lib/dist.old/cmd/multi/multi.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -#include "multiproto.h" -struct { - char *name; - void (*fn)(int, char**); -} mains[] = -{ -#include "multi.h" -}; - -void -main(int argc, char **argv) -{ - int i; - char *cmd, *p; - - if(argc == 1){ - fprint(2, "usage: multi cmd args...\n"); - exits("usage"); - } - - cmd = argv[1]; - if(p = strrchr(cmd, '/')) - cmd = p+1; - argv++; - argc--; - - for(i=0; i -#include - -void -main(void) -{ - int fd, p[2]; - char buf[8192], n; - - pipe(p); - fd = create("/srv/log", OWRITE, 0666); - fprint(fd, "%d", p[0]); - close(fd); - close(p[0]); - while((n = read(p[1], buf, sizeof buf)) >= 0) - write(1, buf, n); -} diff --git a/sys/lib/dist.old/cmd/touchfs.c b/sys/lib/dist.old/cmd/touchfs.c deleted file mode 100644 index 00fadf3f4..000000000 --- a/sys/lib/dist.old/cmd/touchfs.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include - -void -Bpass(Biobuf *bin, Biobuf *bout, int n) -{ - char buf[8192]; - int m; - - while(n > 0) { - m = sizeof buf; - if(m > n) - m = n; - m = Bread(bin, buf, m); - if(m <= 0) { - fprint(2, "corrupt archive\n"); - exits("notdone"); - } - Bwrite(bout, buf, m); - n -= m; - } - assert(n == 0); -} - -void -main(int argc, char **argv) -{ - char *p, *f[10]; - Biobuf bin, bout; - int nf; - ulong d, size; - - if(argc != 2) { - fprint(2, "usage: cat mkfs-archive | touchfs date (in seconds)\n"); - exits("usage"); - } - - d = strtoul(argv[1], 0, 0); - - quotefmtinstall(); - Binit(&bin, 0, OREAD); - Binit(&bout, 1, OWRITE); - - while(p = Brdline(&bin, '\n')) { - p[Blinelen(&bin)-1] = '\0'; - if(strcmp(p, "end of archive") == 0) { - Bprint(&bout, "end of archive\n"); - exits(0); - } - - nf = tokenize(p, f, nelem(f)); - if(nf != 6) { - fprint(2, "corrupt archive\n"); - exits("notdone"); - } - - Bprint(&bout, "%q %q %q %q %lud %q\n", - f[0], f[1], f[2], f[3], d, f[5]); - - size = strtoul(f[5], 0, 0); - Bpass(&bin, &bout, size); - } - fprint(2, "premature end of archive\n"); - exits("notdone"); -} diff --git a/sys/lib/dist.old/cmd/unbflz.c b/sys/lib/dist.old/cmd/unbflz.c deleted file mode 100644 index 5ddb821f9..000000000 --- a/sys/lib/dist.old/cmd/unbflz.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include - -void -usage(void) -{ - fprint(2, "usage: unbflz [file]\n"); - exits("usage"); -} - -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]; -} - -/* - * memmove but make sure overlap works properly. - */ -void -copy(uchar *dst, uchar *src, int n) -{ - while(n-- > 0) - *dst++ = *src++; -} - -void -main(int argc, char **argv) -{ - Biobuf *b, bin; - char buf[5]; - uchar *data; - ulong *blk, l; - int nblk, mblk; - int sum; - int i, j, length, m, n, o; - - ARGBEGIN{ - default: - usage(); - }ARGEND - - switch(argc){ - default: - usage(); - case 0: - Binit(&bin, 0, OREAD); - b = &bin; - break; - case 1: - if((b = Bopen(argv[0], OREAD)) == nil) - sysfatal("open %s: %r", argv[0]); - break; - } - - if(Bread(b, buf, 4) != 4) - sysfatal("short read"); - - if(memcmp(buf, "BLZ\n", 4) != 0) - sysfatal("bad header"); - - length = Bgetint(b); - data = malloc(length); - if(data == nil) - sysfatal("out of memory"); - sum = 0; - nblk = 0; - mblk = 0; - blk = nil; - while(sum < length){ - if(nblk>=mblk){ - mblk += 16384; - blk = realloc(blk, (mblk+1)*sizeof(blk[0])); - if(blk == nil) - sysfatal("out of memory"); - } - l = Bgetint(b); - blk[nblk++] = l; - if(l&(1<<31)) - l &= ~(1<<31); - else - blk[nblk++] = Bgetint(b); - sum += l; - } - if(sum != length) - sysfatal("bad compressed data %d %d", sum, length); - i = 0; - j = 0; - while(i < length){ - assert(j < nblk); - n = blk[j++]; - if(n&(1<<31)){ - n &= ~(1<<31); - if((m=Bread(b, data+i, n)) != n) - sysfatal("short read %d %d", n, m); - }else{ - o = blk[j++]; - copy(data+i, data+o, n); - } - i += n; - } - write(1, data, length); - exits(nil); -} diff --git a/sys/src/cmd/aux/bflz.c b/sys/src/cmd/aux/bflz.c new file mode 100644 index 000000000..89cb361c2 --- /dev/null +++ b/sys/src/cmd/aux/bflz.c @@ -0,0 +1,374 @@ +/* + * Extraordinarily brute force Lempel & Ziv-like + * compressor. The input file must fit in memory + * during compression, and the output file will + * be reconstructed in memory during decompression. + * We search for large common sequences and use a + * greedy algorithm to choose which sequence gets + * compressed first. + * + * Files begin with "BLZ\n" and a 32-bit uncompressed file length. + * + * Output format is a series of blocks followed by + * a raw data section. Each block begins with a 32-bit big-endian + * number. The top bit is type and the next 31 bits + * are uncompressed size. Type is one of + * 0 - use raw data for this length + * 1 - a 32-bit offset follows + * After the blocks come the raw data. (The end of the blocks can be + * noted by summing block lengths until you reach the file length.) + */ + +#include +#include +#include + +#define malloc sbrk + +int minrun = 16; +int win = 16; +ulong outn; +int verbose; +int mindist; + +enum { Prime = 16777213 }; /* smallest prime < 2^24 (so p*256+256 < 2^32) */ +enum { NOFF = 3 }; + +Biobuf bout; +ulong length; +uchar *data; +ulong sum32(ulong, void*, long); +uchar *odat; +int nodat; +int nraw; +int rawstart; +int acct; +int zlength; +int maxchain; +int maxrle[256]; +int nnew; + +typedef struct Node Node; +struct Node { + Node *link; + ulong key; + ulong offset[NOFF]; +}; + +Node *nodepool; +int nnodepool; + +Node **hash; +uint nhash; + +uint maxlen; +uint maxsame; +uint replacesame = 8*1024*1024; + +Node *freelist, **freeend; +uint nalloc; + +Node* +allocnode(void) +{ + int i; + Node *n; + + if(nnodepool == 0){ + nnodepool = 256*1024; + nodepool = malloc(sizeof(Node)*nnodepool); + } + if(freelist){ + n = freelist; + freelist = n->link; + return n; + } + assert(nnodepool > 0); + nalloc++; + n = &nodepool[--nnodepool]; + for(i=0; ioffset[i] = -1; + + return n; +} + +void +freenode(Node *n) +{ + if(freelist == nil) + freelist = n; + else + *freeend = n; + freeend = &n->link; + n->link = nil; +} + +Node** +llookup(ulong key) +{ + uint c; + Node **l, **top, *n; + + if(nhash == 0){ + uint x; + + x = length/8; + for(nhash=1; nhashlink){ + c++; + if((*l)->key == key){ + /* move to front */ + n = *l; + *l = n->link; + n->link = *top; + *top = n; + return top; + } + } + if(c > maxlen) + maxlen = c; + return l; +} + +Node* +lookup(ulong key) +{ + return *llookup(key); +} + +void +insertnode(ulong key, ulong offset) +{ + int i; + Node *n, **l; + + l = llookup(key); + if(*l == nil){ + if(l==&hash[key&(nhash-1)]) + nnew++; + *l = allocnode(); + (*l)->key = key; + } + n = *l; + + /* add or replace last */ + for(i=0; ioffset[i]!=-1; i++) + ; + n->offset[i] = offset; +} + +void +Bputint(Biobufhdr *b, int n) +{ + uchar p[4]; + + p[0] = n>>24; + p[1] = n>>16; + p[2] = n>>8; + p[3] = n; + Bwrite(b, p, 4); +} + +void +flushraw(void) +{ + if(nraw){ + if(verbose) + fprint(2, "Raw %d+%d\n", rawstart, nraw); + zlength += 4+nraw; + Bputint(&bout, (1<<31)|nraw); + memmove(odat+nodat, data+rawstart, nraw); + nodat += nraw; + nraw = 0; + } +} + +int +rawbyte(int i) +{ + assert(acct == i); + if(nraw == 0) + rawstart = i; + acct++; + nraw++; + return 1; +} + +int +refblock(int i, int len, int off) +{ + assert(acct == i); + acct += len; + if(nraw) + flushraw(); + if(verbose) + fprint(2, "Copy %d+%d from %d\n", i, len, off); + Bputint(&bout, len); + Bputint(&bout, off); + zlength += 4+4; + return len; +} + +int +cmprun(uchar *a, uchar *b, int len) +{ + int i; + + if(a==b) + return 0; + for(i=0; ioffset[o] == -1) + break; + run = cmprun(data+i, data+n->offset[o], length-i); + if(run > maxrun && n->offset[o]+mindist < i){ + maxrun = run; + maxoff = n->offset[o]; + best = o; + } + } + if(best > 0){ + o = n->offset[best]; + for(j=best; j>0; j--) + n->offset[j] = n->offset[j-1]; + n->offset[0] = o; + } + } + + if(maxrun >= minrun) + j = i+refblock(i, maxrun, maxoff); + else + j = i+rawbyte(i); + for(; imaxrle[data[i]]){ + maxrle[data[i]] = rle; + insertnode(sum, i); + } + sum = (sum*256+data[i+win]) % Prime; + sum = (sum + data[i]*outn) % Prime; + } + } + /* could do better here */ + for(; i 0){ + data = realloc(data, length+n); + if(data == nil) + sysfatal("realloc: %r"); + memmove(data+length, buf, n); + length += n; + if(n < sizeof buf) + break; + } + odat = malloc(length); + if(odat == nil) + sysfatal("malloc: %r"); + + Binit(&bout, 1, OWRITE); + Bprint(&bout, "BLZ\n"); + Bputint(&bout, length); + outn = 1; + for(i=0; i +#include +#include + +char *pwd; +char *root = "/"; + +void +usage(void) +{ + fprint(2, "usage: cdsh [-r root]\n"); + exits("usage"); +} + +int +system(char *cmd) +{ + int pid; + if((pid = fork()) < 0) + return -1; + + if(pid == 0) { + dup(2, 1); + execl("/bin/rc", "rc", "-c", cmd, nil); + exits("exec"); + } + waitpid(); + return 0; +} + +int +cd(char *s) +{ + char *newpwd; + int l; + + if(s[0] == '/') { + cleanname(s); + newpwd = strdup(s); + } else { + l = strlen(pwd)+1+strlen(s)+1+50; /* 50 = crud for unicode mistakes */ + newpwd = malloc(l); + snprint(newpwd, l, "%s/%s", pwd, s); + cleanname(newpwd); + assert(newpwd[0] == '/'); + } + + if(chdir(root) < 0 || (newpwd[1] != '\0' && chdir(newpwd+1) < 0)) { + chdir(root); + chdir(pwd+1); + free(newpwd); + return -1; + } else { + free(pwd); + pwd = newpwd; + return 0; + } +} + +void +main(int argc, char **argv) +{ + char *p; + Biobuf bin; + char *f[2]; + int nf; + + ARGBEGIN{ + case 'r': + root = ARGF(); + if(root == nil) + usage(); + if(root[0] != '/') { + fprint(2, "root must be rooted\n"); + exits("root"); + } + break; + default: + usage(); + }ARGEND; + + if(argc != 0) + usage(); + + cleanname(root); + if(cd("/") < 0) { + fprint(2, "cannot cd %s: %r\n", root); + exits("root"); + } + + Binit(&bin, 0, OREAD); + while(fprint(2, "%s%% ", pwd), (p = Brdline(&bin, '\n'))) { + p[Blinelen(&bin)-1] = '\0'; + nf = tokenize(p, f, nelem(f)); + if(nf < 1) + continue; + if(strcmp(f[0], "exit") == 0) + break; + if(strcmp(f[0], "lc") == 0) { + if(nf == 1) { + if(system("/bin/lc") < 0) + fprint(2, "lc: %r\n"); + } else if(nf == 2) { + if(strpbrk(p, "'`{}^@$#&()|\\;><")) + fprint(2, "no shell characters allowed\n"); + else { + p = f[1]; + *--p = ' '; + *--p = 'c'; + *--p = 'l'; + if(system(p) < 0) + fprint(2, "lc: %r\n"); + } + } + continue; + } + if(strcmp(f[0], "cd") == 0) { + if(nf < 2) + fprint(2, "usage: cd dir\n"); + else if(cd(f[1]) < 0) + fprint(2, "cd: %r\n"); + continue; + } + fprint(2, "commands are cd, lc, and exit\n"); + } + + print("%s\n", pwd); +} diff --git a/sys/src/cmd/aux/multi/mkfile b/sys/src/cmd/aux/multi/mkfile new file mode 100644 index 000000000..a3acc36de --- /dev/null +++ b/sys/src/cmd/aux/multi/mkfile @@ -0,0 +1,76 @@ +objtype=386 +>../../pc/multi/$b + chmod +x ../../pc/multi/$b + } + +BIN=/sys/lib/dist/bin/$objtype +multi.h +>multiproto.h + +for(i){ +echo $i... + b=`{basename $i} + p=$b + if(~ $b [0-9]*) + p=_$b + echo void $p^_main'(int, char**);' >>$dir/multiproto.h + echo "$b", $p^_main, >>$dir/multi.h + d=`{basename -d $i} + if(~ $i disk/prep disk/fdisk){ + cd /sys/src/cmd/disk/prep + rm 8.$b + files=`{mk 8.$b | getfiles} + } + if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.out}){ + cd /sys/src/cmd/$i + rm 8.out + files=`{mk 8.out | getfiles} + } + if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.$b}){ + cd /sys/src/cmd/$i + rm 8.out + files=`{mk 8.$b | getfiles} + } + if not if(test -d /sys/src/cmd/$d && @{cd /sys/src/cmd/$d && mk 8.$b}){ + cd /sys/src/cmd/$d + rm 8.$b + files=`{mk 8.$b | getfiles} + } + if not{ + echo do not know how to make $i + exit oops + } + aux/8prefix $p^_ $files + grab $files + switch(`{pwd}){ + case /sys/src/cmd /sys/src/cmd/aux /sys/src/cmd/ip + rm 8.$b + case * + mk clean + } +} +cd $dir +8c -FVw multi.c +8l -o 8.$targ multi.8 a.*.8 +# rm a.*.8 diff --git a/sys/src/cmd/aux/multi/multi.c b/sys/src/cmd/aux/multi/multi.c new file mode 100644 index 000000000..a2e3035ad --- /dev/null +++ b/sys/src/cmd/aux/multi/multi.c @@ -0,0 +1,38 @@ +#include +#include + +#include "multiproto.h" +struct { + char *name; + void (*fn)(int, char**); +} mains[] = +{ +#include "multi.h" +}; + +void +main(int argc, char **argv) +{ + int i; + char *cmd, *p; + + if(argc == 1){ + fprint(2, "usage: multi cmd args...\n"); + exits("usage"); + } + + cmd = argv[1]; + if(p = strrchr(cmd, '/')) + cmd = p+1; + argv++; + argc--; + + for(i=0; i +#include + +void +main(void) +{ + int fd, p[2]; + char buf[8192], n; + + pipe(p); + fd = create("/srv/log", OWRITE, 0666); + fprint(fd, "%d", p[0]); + close(fd); + close(p[0]); + while((n = read(p[1], buf, sizeof buf)) >= 0) + write(1, buf, n); +} diff --git a/sys/src/cmd/aux/unbflz.c b/sys/src/cmd/aux/unbflz.c new file mode 100644 index 000000000..5ddb821f9 --- /dev/null +++ b/sys/src/cmd/aux/unbflz.c @@ -0,0 +1,109 @@ +#include +#include +#include + +void +usage(void) +{ + fprint(2, "usage: unbflz [file]\n"); + exits("usage"); +} + +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]; +} + +/* + * memmove but make sure overlap works properly. + */ +void +copy(uchar *dst, uchar *src, int n) +{ + while(n-- > 0) + *dst++ = *src++; +} + +void +main(int argc, char **argv) +{ + Biobuf *b, bin; + char buf[5]; + uchar *data; + ulong *blk, l; + int nblk, mblk; + int sum; + int i, j, length, m, n, o; + + ARGBEGIN{ + default: + usage(); + }ARGEND + + switch(argc){ + default: + usage(); + case 0: + Binit(&bin, 0, OREAD); + b = &bin; + break; + case 1: + if((b = Bopen(argv[0], OREAD)) == nil) + sysfatal("open %s: %r", argv[0]); + break; + } + + if(Bread(b, buf, 4) != 4) + sysfatal("short read"); + + if(memcmp(buf, "BLZ\n", 4) != 0) + sysfatal("bad header"); + + length = Bgetint(b); + data = malloc(length); + if(data == nil) + sysfatal("out of memory"); + sum = 0; + nblk = 0; + mblk = 0; + blk = nil; + while(sum < length){ + if(nblk>=mblk){ + mblk += 16384; + blk = realloc(blk, (mblk+1)*sizeof(blk[0])); + if(blk == nil) + sysfatal("out of memory"); + } + l = Bgetint(b); + blk[nblk++] = l; + if(l&(1<<31)) + l &= ~(1<<31); + else + blk[nblk++] = Bgetint(b); + sum += l; + } + if(sum != length) + sysfatal("bad compressed data %d %d", sum, length); + i = 0; + j = 0; + while(i < length){ + assert(j < nblk); + n = blk[j++]; + if(n&(1<<31)){ + n &= ~(1<<31); + if((m=Bread(b, data+i, n)) != n) + sysfatal("short read %d %d", n, m); + }else{ + o = blk[j++]; + copy(data+i, data+o, n); + } + i += n; + } + write(1, data, length); + exits(nil); +} diff --git a/sys/src/cmd/bzfs/bzfs.h b/sys/src/cmd/bzfs/bzfs.h new file mode 100644 index 000000000..1de291a39 --- /dev/null +++ b/sys/src/cmd/bzfs/bzfs.h @@ -0,0 +1,11 @@ +int unbzip(int); +void _unbzip(int, int); +int unbflz(int); +int xexpand(int); +void *emalloc(ulong); +void *erealloc(void*, ulong); +char *estrdup(char*); + +void ramfsmain(int, char**); +extern int chatty; +void error(char*, ...); diff --git a/sys/src/cmd/bzfs/mkext.c b/sys/src/cmd/bzfs/mkext.c new file mode 100644 index 000000000..1fedd62cc --- /dev/null +++ b/sys/src/cmd/bzfs/mkext.c @@ -0,0 +1,288 @@ +/* + * bzip2-based file system. + * the file system itself is just a bzipped2 xzipped mkfs archive + * prefixed with "bzfilesystem\n" and suffixed with + * a kilobyte of zeros. + * + * changes to the file system are only kept in + * memory, not written back to the disk. + * + * this is intended for use on a floppy boot disk. + * we assume the file is in the dos file system and + * contiguous on the disk: finding it amounts to + * looking at the beginning of each sector for + * "bzfilesystem\n". then we pipe it through + * bunzip2 and store the files in a file tree in memory. + * things are slightly complicated by the fact that + * devfloppy requires reads to be on a 512-byte + * boundary and be a multiple of 512 bytes; we + * fork a process to relieve bunzip2 of this restriction. + */ + +#include +#include +#include +#include +#include +#include "bzfs.h" + +enum{ + LEN = 8*1024, + NFLDS = 6, /* filename, modes, uid, gid, mtime, bytes */ +}; + +void mkdirs(char*, char*); +void mkdir(char*, ulong, ulong, char*, char*); +void extract(char*, ulong, ulong, char*, char*, ulong); +void seekpast(ulong); +void error(char*, ...); +void warn(char*, ...); +void usage(void); +char *mtpt; +Biobufhdr bin; +uchar binbuf[2*LEN]; + +void +usage(void) +{ + fprint(2, "usage: bzfs [-m mtpt] [-s] [-f file] [-h]\n"); + exits("usage"); +} + +/* + * floppy disks can only be read on 512-byte + * boundaries and in 512 byte multiples. + * feed one over a pipe to allow arbitrary reading. + */ +char zero[512]; +int +blockread(int in, char *first, int nfirst) +{ + int p[2], out, n, rv; + char blk[512]; + + if(pipe(p) < 0) + sysfatal("pipe: %r"); + rv = p[0]; + out = p[1]; + switch(rfork(RFPROC|RFNOTEG|RFFDG)){ + case -1: + sysfatal("fork: %r"); + case 0: + close(rv); + break; + default: + close(in); + close(out); + return rv; + } + + write(out, first, nfirst); + + while((n=read(in, blk, sizeof blk)) > 0){ + if(write(out, blk, n) != n) + break; + if(n == sizeof(blk) && memcmp(zero, blk, n) == n) + break; + } + _exits(0); + return -1; +} + +enum { NAMELEN = 28 }; + +void +main(int argc, char **argv) +{ + char *rargv[10]; + int rargc; + char *fields[NFLDS], name[2*LEN], *p, *namep; + char uid[NAMELEN], gid[NAMELEN]; + ulong mode, bytes, mtime; + char *file; + int i, n, stdin, fd, chatty; + char blk[512]; + + if(argc>1 && strcmp(argv[1], "RAMFS") == 0){ + argv[1] = argv[0]; + ramfsmain(argc-1, argv+1); + exits(nil); + } + if(argc>1 && strcmp(argv[1], "BUNZIP") == 0){ + _unbzip(0, 1); + exits(nil); + } + + rfork(RFNOTEG); + stdin = 0; + file = nil; + namep = name; + mtpt = "/root"; + chatty = 0; + ARGBEGIN{ + case 'd': + chatty = !chatty; + break; + case 'f': + file = ARGF(); + break; + case 's': + stdin++; + break; + case 'm': + mtpt = ARGF(); + break; + default: + usage(); + }ARGEND + + if(argc != 0) + usage(); + + if(file == nil) { + fprint(2, "must specify -f file\n"); + usage(); + } + + if((fd = open(file, OREAD)) < 0) { + fprint(2, "cannot open \"%s\": %r\n", file); + exits("open"); + } + + rargv[0] = "ramfs"; + rargc = 1; + if(stdin) + rargv[rargc++] = "-i"; + rargv[rargc++] = "-m"; + rargv[rargc++] = mtpt; + rargv[rargc] = nil; + ramfsmain(rargc, rargv); + + if(1 || strstr(file, "disk")) { /* search for archive on block boundary */ +if(chatty) fprint(2, "searching for bz\n"); + for(i=0;; i++){ + if((n = readn(fd, blk, sizeof blk)) != sizeof blk) + sysfatal("read %d gets %d: %r\n", i, n); + if(strncmp(blk, "bzfilesystem\n", 13) == 0) + break; + } +if(chatty) fprint(2, "found at %d\n", i); + } + + if(chdir(mtpt) < 0) + error("chdir %s: %r", mtpt); + + fd = unbflz(unbzip(blockread(fd, blk+13, sizeof(blk)-13))); + + Binits(&bin, fd, OREAD, binbuf, sizeof binbuf); + while(p = Brdline(&bin, '\n')){ + p[Blinelen(&bin)-1] = '\0'; +if(chatty) fprint(2, "%s\n", p); + if(strcmp(p, "end of archive") == 0){ + _exits(0); + } + if(getfields(p, fields, NFLDS, 0, " \t") != NFLDS){ + warn("too few fields in file header"); + continue; + } + strcpy(namep, fields[0]); + mode = strtoul(fields[1], 0, 8); + mtime = strtoul(fields[4], 0, 10); + bytes = strtoul(fields[5], 0, 10); + strncpy(uid, fields[2], NAMELEN); + strncpy(gid, fields[3], NAMELEN); + if(mode & DMDIR) + mkdir(name, mode, mtime, uid, gid); + else + extract(name, mode, mtime, uid, gid, bytes); + } + fprint(2, "premature end of archive\n"); + exits("premature end of archive"); +} + +char buf[8192]; + +int +ffcreate(char *name, ulong mode, char *uid, char *gid, ulong mtime, int length) +{ + int fd, om; + Dir nd; + + sprint(buf, "%s/%s", mtpt, name); + om = ORDWR; + if(mode&DMDIR) + om = OREAD; + if((fd = create(buf, om, (mode&DMDIR)|0666)) < 0) + error("create %s: %r", buf); + + nulldir(&nd); + nd.mode = mode; + nd.uid = uid; + nd.gid = gid; + nd.mtime = mtime; + if(length) + nd.length = length; + if(dirfwstat(fd, &nd) < 0) + error("fwstat %s: %r", buf); + + return fd; +} + +void +mkdir(char *name, ulong mode, ulong mtime, char *uid, char *gid) +{ + close(ffcreate(name, mode, uid, gid, mtime, 0)); +} + +void +extract(char *name, ulong mode, ulong mtime, char *uid, char *gid, ulong bytes) +{ + int fd, tot, n; + + fd = ffcreate(name, mode, uid, gid, mtime, bytes); + + for(tot = 0; tot < bytes; tot += n){ + n = sizeof buf; + if(tot + n > bytes) + n = bytes - tot; + n = Bread(&bin, buf, n); + if(n <= 0) + error("premature eof reading %s", name); + if(write(fd, buf, n) != n) + error("short write writing %s", name); + } + close(fd); +} + +void +error(char *fmt, ...) +{ + char buf[1024]; + va_list arg; + + sprint(buf, "%s: ", argv0); + va_start(arg, fmt); + vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); + va_end(arg); + fprint(2, "%s\n", buf); + exits(0); +} + +void +warn(char *fmt, ...) +{ + char buf[1024]; + va_list arg; + + sprint(buf, "%s: ", argv0); + va_start(arg, fmt); + vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); + va_end(arg); + fprint(2, "%s\n", buf); +} + +int +_efgfmt(Fmt*) +{ + return -1; +} diff --git a/sys/src/cmd/bzfs/mkfile b/sys/src/cmd/bzfs/mkfile new file mode 100644 index 000000000..df81b5641 --- /dev/null +++ b/sys/src/cmd/bzfs/mkfile @@ -0,0 +1,20 @@ + +#include +#include +#include +#include "bzfs.h" + +/* + * Rather than reading /adm/users, which is a lot of work for + * a toy program, we assume all groups have the form + * NNN:user:user: + * meaning that each user is the leader of his own group. + */ + +enum +{ + OPERM = 0x3, /* mask of all permission types in open mode */ + Nram = 512, + Maxsize = 512*1024*1024, + Maxfdata = 8192, +}; + +typedef struct Fid Fid; +typedef struct Ram Ram; + +struct Fid +{ + short busy; + short open; + short rclose; + int fid; + Fid *next; + char *user; + Ram *ram; +}; + +struct Ram +{ + short busy; + short open; + long parent; /* index in Ram array */ + Qid qid; + long perm; + char *name; + ulong atime; + ulong mtime; + char *user; + char *group; + char *muid; + char *data; + long ndata; +}; + +enum +{ + Pexec = 1, + Pwrite = 2, + Pread = 4, + Pother = 1, + Pgroup = 8, + Powner = 64, +}; + +ulong path; /* incremented for each new file */ +Fid *fids; +Ram ram[Nram]; +int nram; +int mfd[2]; +char *user; +uchar mdata[IOHDRSZ+Maxfdata]; +uchar rdata[Maxfdata]; /* buffer for data in reply */ +uchar statbuf[STATMAX]; +Fcall thdr; +Fcall rhdr; +int messagesize = sizeof mdata; + +Fid * newfid(int); +uint ramstat(Ram*, uchar*, uint); +void io(void); +void *erealloc(void*, ulong); +void *emalloc(ulong); +char *estrdup(char*); +void ramfsusage(void); +int perm(Fid*, Ram*, int); +char *atom(char*); + +char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*), + *rattach(Fid*), *rwalk(Fid*), + *ropen(Fid*), *rcreate(Fid*), + *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*), + *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*); + +char *(*fcalls[])(Fid*) = { + [Tversion] rversion, + [Tflush] rflush, + [Tauth] rauth, + [Tattach] rattach, + [Twalk] rwalk, + [Topen] ropen, + [Tcreate] rcreate, + [Tread] rread, + [Twrite] rwrite, + [Tclunk] rclunk, + [Tremove] rremove, + [Tstat] rstat, + [Twstat] rwstat, +}; + +char Eperm[] = "permission denied"; +char Enotdir[] = "not a directory"; +char Enoauth[] = "no authentication in ramfs"; +char Enotexist[] = "file does not exist"; +char Einuse[] = "file in use"; +char Eexist[] = "file exists"; +char Eisdir[] = "file is a directory"; +char Enotowner[] = "not owner"; +char Eisopen[] = "file already open for I/O"; +char Excl[] = "exclusive use file already open"; +char Ename[] = "illegal name"; +char Eversion[] = "unknown 9P version"; + +int debug; + +void +notifyf(void *a, char *s) +{ + USED(a); + if(strncmp(s, "interrupt", 9) == 0) + noted(NCONT); + noted(NDFLT); +} + +void +ramfsmain(int argc, char *argv[]) +{ + Ram *r; + char *defmnt; + int p[2]; + char buf[32]; + int fd, srvfd; + int stdio = 0; + + srvfd = -1; + defmnt = "/tmp"; + ARGBEGIN{ + case 'D': + debug = 1; + break; + case 'i': /* this is DIFFERENT from normal ramfs; use 1 for both for kernel */ + defmnt = 0; + stdio = 1; + srvfd = 0; + mfd[0] = 1; + mfd[1] = 1; + break; + case 's': + defmnt = 0; + break; + case 'm': + defmnt = ARGF(); + break; + default: + ramfsusage(); + }ARGEND + + if(!stdio){ + if(pipe(p) < 0) + error("pipe failed"); + srvfd = p[1]; + mfd[0] = p[0]; + mfd[1] = p[0]; + if(defmnt == 0){ + fd = create("#s/ramfs", OWRITE, 0666); + if(fd < 0) + error("create of /srv/ramfs failed"); + sprint(buf, "%d", p[1]); + if(write(fd, buf, strlen(buf)) < 0) + error("writing /srv/ramfs"); + } + } + + user = atom(getuser()); + notify(notifyf); + nram = 1; + r = &ram[0]; + r->busy = 1; + r->data = 0; + r->ndata = 0; + r->perm = DMDIR | 0775; + r->qid.type = QTDIR; + r->qid.path = 0LL; + r->qid.vers = 0; + r->parent = 0; + r->user = user; + r->group = user; + r->muid = user; + r->atime = time(0); + r->mtime = r->atime; + r->name = estrdup("."); + + if(debug) + fmtinstall('F', fcallfmt); + switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){ + case -1: + error("fork"); + case 0: + close(srvfd); + io(); + break; + default: + close(mfd[0]); /* don't deadlock if child fails */ + if(defmnt && mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) + error("mount failed: %r"); + } +} + +char* +rversion(Fid*) +{ + Fid *f; + + for(f = fids; f; f = f->next) + if(f->busy) + rclunk(f); + if(thdr.msize > sizeof mdata) + rhdr.msize = sizeof mdata; + else + rhdr.msize = thdr.msize; + messagesize = rhdr.msize; + if(strncmp(thdr.version, "9P2000", 6) != 0) + return Eversion; + rhdr.version = "9P2000"; + return 0; +} + +char* +rauth(Fid*) +{ + return "ramfs: no authentication required"; +} + +char* +rflush(Fid *f) +{ + USED(f); + return 0; +} + +char* +rattach(Fid *f) +{ + /* no authentication! */ + f->busy = 1; + f->rclose = 0; + f->ram = &ram[0]; + rhdr.qid = f->ram->qid; + if(thdr.uname[0]) + f->user = atom(thdr.uname); + else + f->user = atom("none"); + if(strcmp(user, "none") == 0) + user = f->user; + return 0; +} + +char* +clone(Fid *f, Fid **nf) +{ + if(f->open) + return Eisopen; + if(f->ram->busy == 0) + return Enotexist; + *nf = newfid(thdr.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 */ + return 0; +} + +char* +rwalk(Fid *f) +{ + Ram *r, *fram; + char *name; + Ram *parent; + Fid *nf; + char *err; + ulong t; + int i; + + err = nil; + nf = nil; + rhdr.nwqid = 0; + if(rhdr.newfid != rhdr.fid){ + err = clone(f, &nf); + if(err) + return err; + f = nf; /* walk the new fid */ + } + fram = f->ram; + if(thdr.nwname > 0){ + t = time(0); + for(i=0; iqid.type & QTDIR) == 0){ + err = Enotdir; + break; + } + if(fram->busy == 0){ + err = Enotexist; + break; + } + fram->atime = t; + name = thdr.wname[i]; + if(strcmp(name, ".") == 0){ + Found: + rhdr.nwqid++; + rhdr.wqid[i] = fram->qid; + continue; + } + parent = &ram[fram->parent]; +#ifdef CHECKS + if(!perm(f, parent, Pexec)){ + err = Eperm; + break; + } +#endif + if(strcmp(name, "..") == 0){ + fram = parent; + goto Found; + } + for(r=ram; r < &ram[nram]; r++) + if(r->busy && r->parent==fram-ram && strcmp(name, r->name)==0){ + fram = r; + goto Found; + } + break; + } + if(i==0 && err == nil) + err = Enotexist; + } + if(nf != nil && (err!=nil || rhdr.nwqidbusy = 0; + f->ram = nil; + } + if(rhdr.nwqid == thdr.nwname) /* update the fid after a successful walk */ + f->ram = fram; + return err; +} + +char * +ropen(Fid *f) +{ + Ram *r; + int mode, trunc; + + if(f->open) + return Eisopen; + r = f->ram; + if(r->busy == 0) + return Enotexist; + if(r->perm & DMEXCL) + if(r->open) + return Excl; + mode = thdr.mode; + if(r->qid.type & QTDIR){ + if(mode != OREAD) + return Eperm; + rhdr.qid = r->qid; + return 0; + } + if(mode & ORCLOSE){ + /* can't remove root; must be able to write parent */ + if(r->qid.path==0 || !perm(f, &ram[r->parent], Pwrite)) + return Eperm; + f->rclose = 1; + } + trunc = mode & OTRUNC; + mode &= OPERM; + if(mode==OWRITE || mode==ORDWR || trunc) + if(!perm(f, r, Pwrite)) + return Eperm; + if(mode==OREAD || mode==ORDWR) + if(!perm(f, r, Pread)) + return Eperm; + if(mode==OEXEC) + if(!perm(f, r, Pexec)) + return Eperm; + if(trunc && (r->perm&DMAPPEND)==0){ + r->ndata = 0; + if(r->data) + free(r->data); + r->data = 0; + r->qid.vers++; + } + rhdr.qid = r->qid; + rhdr.iounit = messagesize-IOHDRSZ; + f->open = 1; + r->open++; + return 0; +} + +char * +rcreate(Fid *f) +{ + Ram *r; + char *name; + long parent, prm; + + if(f->open) + return Eisopen; + if(f->ram->busy == 0) + return Enotexist; + parent = f->ram - ram; + if((f->ram->qid.type&QTDIR) == 0) + return Enotdir; + /* must be able to write parent */ +#ifdef CHECKS + if(!perm(f, f->ram, Pwrite)) + return Eperm; +#endif + prm = thdr.perm; + name = thdr.name; + if(strcmp(name, ".")==0 || strcmp(name, "..")==0) + return Ename; + for(r=ram; r<&ram[nram]; r++) + if(r->busy && parent==r->parent) + if(strcmp((char*)name, r->name)==0) + return Einuse; + for(r=ram; r->busy; r++) + if(r == &ram[Nram-1]) + return "no free ram resources"; + r->busy = 1; + r->qid.path = ++path; + r->qid.vers = 0; + if(prm & DMDIR) + r->qid.type |= QTDIR; + r->parent = parent; + free(r->name); + r->name = estrdup(name); + r->user = f->user; + r->group = f->ram->group; + r->muid = f->ram->muid; + if(prm & DMDIR) + prm = (prm&~0777) | (f->ram->perm&prm&0777); + else + prm = (prm&(~0777|0111)) | (f->ram->perm&prm&0666); + r->perm = prm; + r->ndata = 0; + if(r-ram >= nram) + nram = r - ram + 1; + r->atime = time(0); + r->mtime = r->atime; + f->ram->mtime = r->atime; + f->ram = r; + rhdr.qid = r->qid; + rhdr.iounit = messagesize-IOHDRSZ; + f->open = 1; + if(thdr.mode & ORCLOSE) + f->rclose = 1; + r->open++; + return 0; +} + +char* +rread(Fid *f) +{ + Ram *r; + uchar *buf; + long off; + int n, m, cnt; + + if(f->ram->busy == 0) + return Enotexist; + n = 0; + rhdr.count = 0; + off = thdr.offset; + buf = rdata; + cnt = thdr.count; + if(cnt > messagesize) /* shouldn't happen, anyway */ + cnt = messagesize; + if(f->ram->qid.type & QTDIR){ + for(r=ram+1; off > 0; r++){ + if(r->busy && r->parent==f->ram-ram) + off -= ramstat(r, statbuf, sizeof statbuf); + if(r == &ram[nram-1]) + return 0; + } + for(; r<&ram[nram] && n < cnt; r++){ + if(!r->busy || r->parent!=f->ram-ram) + continue; + m = ramstat(r, buf+n, cnt-n); + if(m == 0) + break; + n += m; + } + rhdr.data = (char*)rdata; + rhdr.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; + rhdr.data = r->data+off; + rhdr.count = n; + return 0; +} + +char* +rwrite(Fid *f) +{ + Ram *r; + ulong off; + int cnt; + + r = f->ram; + if(r->busy == 0) + return Enotexist; + off = thdr.offset; + if(r->perm & DMAPPEND) + off = r->ndata; + cnt = thdr.count; + if(r->qid.type & QTDIR) + return Eisdir; + if(off+cnt >= Maxsize) /* sanity check */ + return "write too big"; + if(off+cnt > r->ndata) + r->data = erealloc(r->data, off+cnt); + if(off > r->ndata) + memset(r->data+r->ndata, 0, off-r->ndata); + if(off+cnt > r->ndata) + r->ndata = off+cnt; + memmove(r->data+off, thdr.data, cnt); + r->qid.vers++; + r->mtime = time(0); + rhdr.count = cnt; + return 0; +} + +void +realremove(Ram *r) +{ + r->ndata = 0; + if(r->data) + free(r->data); + r->data = 0; + r->parent = 0; + memset(&r->qid, 0, sizeof r->qid); + free(r->name); + r->name = nil; + r->busy = 0; +} + +char * +rclunk(Fid *f) +{ + if(f->open) + f->ram->open--; + if(f->rclose) + realremove(f->ram); + f->busy = 0; + f->open = 0; + f->ram = 0; + return 0; +} + +char * +rremove(Fid *f) +{ + Ram *r; + + if(f->open) + f->ram->open--; + f->busy = 0; + f->open = 0; + r = f->ram; + f->ram = 0; +#ifdef CHECKS + if(r->qid.path == 0 || !perm(f, &ram[r->parent], Pwrite)) + return Eperm; +#endif + ram[r->parent].mtime = time(0); + realremove(r); + return 0; +} + +char * +rstat(Fid *f) +{ + if(f->ram->busy == 0) + return Enotexist; + rhdr.nstat = ramstat(f->ram, statbuf, sizeof statbuf); + rhdr.stat = statbuf; + return 0; +} + +char * +rwstat(Fid *f) +{ + Ram *r, *s; + Dir dir; + + if(f->ram->busy == 0) + return Enotexist; + convM2D(thdr.stat, thdr.nstat, &dir, (char*)statbuf); + r = f->ram; + + /* + * To change length, must have write permission on file. + */ +#ifdef CHECKS + if(dir.length!=~0 && dir.length!=r->ndata){ + if(!perm(f, r, Pwrite)) + return Eperm; + } +#endif + + /* + * To change name, must have write permission in parent + * and name must be unique. + */ + if(dir.name[0]!='\0' && strcmp(dir.name, r->name)!=0){ +#ifdef CHECKS + if(!perm(f, &ram[r->parent], Pwrite)) + return Eperm; +#endif + for(s=ram; s<&ram[nram]; s++) + if(s->busy && s->parent==r->parent) + if(strcmp(dir.name, s->name)==0) + return Eexist; + } + +#ifdef OWNERS + /* + * To change mode, must be owner or group leader. + * Because of lack of users file, leader=>group itself. + */ + if(dir.mode!=~0 && r->perm!=dir.mode){ + if(strcmp(f->user, r->user) != 0) + if(strcmp(f->user, r->group) != 0) + return Enotowner; + } + + /* + * To change group, must be owner and member of new group, + * or leader of current group and leader of new group. + * Second case cannot happen, but we check anyway. + */ + if(dir.gid[0]!='\0' && strcmp(r->group, dir.gid)!=0){ + if(strcmp(f->user, r->user) == 0) + if(strcmp(f->user, dir.gid) == 0) + goto ok; + if(strcmp(f->user, r->group) == 0) + if(strcmp(f->user, dir.gid) == 0) + goto ok; + return Enotowner; + ok:; + } +#endif + + /* all ok; do it */ + if(dir.mode != ~0){ + dir.mode &= ~DMDIR; /* cannot change dir bit */ + dir.mode |= r->perm&DMDIR; + r->perm = dir.mode; + } + if(dir.name[0] != '\0'){ + free(r->name); + r->name = estrdup(dir.name); + } + if(dir.gid[0] != '\0') + r->group = atom(dir.gid); + + if(dir.uid[0] != '\0') + r->user = atom(dir.uid); + + if(dir.length!=~0 && dir.length!=r->ndata){ + r->data = erealloc(r->data, dir.length); + if(r->ndata < dir.length) + memset(r->data+r->ndata, 0, dir.length-r->ndata); + r->ndata = dir.length; + } + + if(dir.mtime != ~0) + r->mtime = dir.mtime; + + ram[r->parent].mtime = time(0); + return 0; +} + +uint +ramstat(Ram *r, uchar *buf, uint nbuf) +{ + Dir dir; + + dir.name = r->name; + dir.qid = r->qid; + dir.mode = r->perm; + dir.length = r->ndata; + dir.uid = r->user; + dir.gid = r->group; + dir.muid = r->muid; + dir.atime = r->atime; + dir.mtime = r->mtime; + return convD2M(&dir, buf, nbuf); +} + +Fid * +newfid(int fid) +{ + Fid *f, *ff; + + ff = 0; + for(f = fids; f; f = f->next) + if(f->fid == fid) + return f; + else if(!ff && !f->busy) + ff = f; + if(ff){ + ff->fid = fid; + return ff; + } + f = emalloc(sizeof *f); + f->ram = nil; + f->fid = fid; + f->next = fids; + fids = f; + return f; +} + +void +io(void) +{ + char *err; + int n, pid; + + pid = getpid(); + + for(;;){ + /* + * reading from a pipe or a network device + * will give an error after a few eof reads. + * however, we cannot tell the difference + * between a zero-length read and an interrupt + * on the processes writing to us, + * so we wait for the error. + */ + n = read9pmsg(mfd[0], mdata, messagesize); + if(n < 0) + error("mount read: %r"); + if(n == 0) + continue; + if(convM2S(mdata, n, &thdr) == 0) + continue; + + if(debug) + fprint(2, "ramfs %d:<-%F\n", pid, &thdr); + + if(!fcalls[thdr.type]) + err = "bad fcall type"; + else + err = (*fcalls[thdr.type])(newfid(thdr.fid)); + if(err){ + rhdr.type = Rerror; + rhdr.ename = err; + }else{ + rhdr.type = thdr.type + 1; + rhdr.fid = thdr.fid; + } + rhdr.tag = thdr.tag; + if(debug) + fprint(2, "ramfs %d:->%F\n", pid, &rhdr);/**/ + n = convS2M(&rhdr, mdata, messagesize); + if(n == 0) + error("convS2M error on write"); + if(write(mfd[1], mdata, n) != n) + error("mount write"); + } +} + +int +perm(Fid *f, Ram *r, int p) +{ + if((p*Pother) & r->perm) + return 1; + if(strcmp(f->user, r->group)==0 && ((p*Pgroup) & r->perm)) + return 1; + if(strcmp(f->user, r->user)==0 && ((p*Powner) & r->perm)) + return 1; + return 0; +} + +void * +emalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(!p) + error("out of memory"); + memset(p, 0, n); + return p; +} + +void * +erealloc(void *p, ulong n) +{ + p = realloc(p, n); + if(!p) + error("out of memory"); + return p; +} + +char * +estrdup(char *q) +{ + char *p; + int n; + + n = strlen(q)+1; + p = malloc(n); + if(!p) + error("out of memory"); + memmove(p, q, n); + return p; +} + +void +ramfsusage(void) +{ + fprint(2, "usage: %s [-is] [-m mountpoint]\n", argv0); + exits("usage"); +} + +/* + * Custom allocators to avoid malloc overheads on small objects. + * We never free these. (See below.) + */ +typedef struct Stringtab Stringtab; +struct Stringtab { + Stringtab *link; + char *str; +}; +static Stringtab* +taballoc(void) +{ + static Stringtab *t; + static uint nt; + + if(nt == 0){ + t = malloc(64*sizeof(Stringtab)); + if(t == 0) + sysfatal("out of memory"); + nt = 64; + } + nt--; + return t++; +} + +static char* +xstrdup(char *s) +{ + char *r; + int len; + static char *t; + static int nt; + + len = strlen(s)+1; + if(len >= 8192) + sysfatal("strdup big string"); + + if(nt < len){ + t = malloc(8192); + if(t == 0) + sysfatal("out of memory"); + nt = 8192; + } + r = t; + t += len; + nt -= len; + strcpy(r, s); + return r; +} + +/* + * Return a uniquely allocated copy of a string. + * Don't free these -- they stay in the table for the + * next caller who wants that particular string. + * String comparison can be done with pointer comparison + * if you know both strings are atoms. + */ +static Stringtab *stab[1024]; + +static uint +hash(char *s) +{ + uint h; + uchar *p; + + h = 0; + for(p=(uchar*)s; *p; p++) + h = h*37 + *p; + return h; +} + +char* +atom(char *str) +{ + uint h; + Stringtab *tab; + + h = hash(str) % nelem(stab); + for(tab=stab[h]; tab; tab=tab->link) + if(strcmp(str, tab->str) == 0) + return tab->str; + + tab = taballoc(); + tab->str = xstrdup(str); + tab->link = stab[h]; + stab[h] = tab; + return tab->str; +} diff --git a/sys/src/cmd/bzfs/unbflz.c b/sys/src/cmd/bzfs/unbflz.c new file mode 100644 index 000000000..661d65e4d --- /dev/null +++ b/sys/src/cmd/bzfs/unbflz.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include "bzfs.h" + +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]; +} + +/* + * memmove but make sure overlap works properly. + */ +void +copy(uchar *dst, uchar *src, int n) +{ + while(n-- > 0) + *dst++ = *src++; +} + +int +unbflz(int in) +{ + int rv, out, p[2]; + Biobuf *b, bin; + char buf[5]; + uchar *data; + int i, j, length, n, m, o, sum; + ulong *blk; + int nblk, mblk; + + if(pipe(p) < 0) + sysfatal("pipe: %r"); + + rv = p[0]; + out = p[1]; + switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ + case -1: + sysfatal("fork: %r"); + case 0: + close(rv); + break; + default: + close(in); + close(out); + return rv; + } + + Binit(&bin, in, OREAD); + b = &bin; + + if(Bread(b, buf, 4) != 4) + sysfatal("short read"); + + if(memcmp(buf, "BLZ\n", 4) != 0) + sysfatal("bad header"); + + length = Bgetint(b); + data = malloc(length); + if(data == nil) + sysfatal("out of memory"); + sum = 0; + nblk = 0; + mblk = 0; + blk = nil; + while(sum < length){ + if(nblk>=mblk){ + mblk += 16384; + blk = realloc(blk, (mblk+1)*sizeof(blk[0])); + if(blk == nil) + sysfatal("out of memory"); + } + n = Bgetint(b); + blk[nblk++] = n; + if(n&(1<<31)) + n &= ~(1<<31); + else + blk[nblk++] = Bgetint(b); + sum += n; + } + if(sum != length) + sysfatal("bad compressed data %d %d", sum, length); + i = 0; + j = 0; + while(i < length){ + assert(j < nblk); + n = blk[j++]; + if(n&(1<<31)){ + n &= ~(1<<31); + if((m=Bread(b, data+i, n)) != n) + sysfatal("short read %d %d", n, m); + }else{ + o = blk[j++]; + copy(data+i, data+o, n); + } + i += n; + } + write(out, data, length); + close(in); + close(out); + _exits(0); + return -1; +} diff --git a/sys/src/cmd/bzfs/unbzip.c b/sys/src/cmd/bzfs/unbzip.c new file mode 100644 index 000000000..070e7ba48 --- /dev/null +++ b/sys/src/cmd/bzfs/unbzip.c @@ -0,0 +1,861 @@ +#include +#include +#include +#include "bzfs.h" + +/* + * THIS FILE IS NOT IDENTICAL TO THE ORIGINAL + * FROM THE BZIP2 DISTRIBUTION. + * + * It has been modified, mainly to break the library + * into smaller pieces. + * + * Russ Cox + * rsc@plan9.bell-labs.com + * July 2000 + */ + +/*---------------------------------------------*/ +/*-- + Place a 1 beside your platform, and 0 elsewhere. + Attempts to autosniff this even if you don't. +--*/ + + +/*-- + Plan 9 from Bell Labs +--*/ +#define BZ_PLAN9 1 +#define BZ_UNIX 0 + +#define exit(x) exits((x) ? "whoops" : nil) +#define size_t ulong + +#ifdef __GNUC__ +# define NORETURN __attribute__ ((noreturn)) +#else +# define NORETURN /**/ +#endif + +/*-- + Some more stuff for all platforms :-) + This might have to get moved into the platform-specific + header files if we encounter a machine with different sizes. +--*/ + +typedef char Char; +typedef unsigned char Bool; +typedef unsigned char UChar; +typedef int Int32; +typedef unsigned int UInt32; +typedef short Int16; +typedef unsigned short UInt16; + +#define True ((Bool)1) +#define False ((Bool)0) + +/*-- + IntNative is your platform's `native' int size. + Only here to avoid probs with 64-bit platforms. +--*/ +typedef int IntNative; + +#include "bzfs.h" +#include "bzlib.h" +#include "bzlib_private.h" + +static int +bunzip(int ofd, char *ofile, Biobuf *bin) +{ + int e, n, done, onemore; + char buf[8192]; + char obuf[8192]; + Biobuf bout; + bz_stream strm; + + USED(ofile); + + memset(&strm, 0, sizeof strm); + BZ2_bzDecompressInit(&strm, 0, 0); + + strm.next_in = buf; + strm.avail_in = 0; + strm.next_out = obuf; + strm.avail_out = sizeof obuf; + + done = 0; + Binit(&bout, ofd, OWRITE); + + /* + * onemore is a crummy hack to go 'round the loop + * once after we finish, to flush the output buffer. + */ + onemore = 1; + SET(e); + do { + if(!done && strm.avail_in < sizeof buf) { + if(strm.avail_in) + memmove(buf, strm.next_in, strm.avail_in); + + n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in); + if(n <= 0) + done = 1; + else + strm.avail_in += n; + strm.next_in = buf; + } + if(strm.avail_out < sizeof obuf) { + Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out); + strm.next_out = obuf; + strm.avail_out = sizeof obuf; + } + + if(onemore == 0) + break; + } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--); + + if(e != BZ_STREAM_END) { + fprint(2, "bunzip2: decompress failed\n"); + return 0; + } + + if(BZ2_bzDecompressEnd(&strm) != BZ_OK) { + fprint(2, "bunzip2: decompress end failed (can't happen)\n"); + return 0; + } + + Bterm(&bout); + + return 1; +} + +void +_unbzip(int in, int out) +{ + Biobuf bin; + + Binit(&bin, in, OREAD); + if(bunzip(out, nil, &bin) != 1) { + fprint(2, "bunzip2 failed\n"); + _exits("bunzip2"); + } +} + +int +unbzip(int in) +{ + int rv, out, p[2]; + + if(pipe(p) < 0) + sysfatal("pipe: %r"); + + rv = p[0]; + out = p[1]; + switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ + case -1: + sysfatal("fork: %r"); + case 0: + close(rv); + break; + default: + close(in); + close(out); + return rv; + } + + _unbzip(in, out); + _exits(0); + return -1; /* not reached */ +} + +int bz_config_ok ( void ) +{ + if (sizeof(int) != 4) return 0; + if (sizeof(short) != 2) return 0; + if (sizeof(char) != 1) return 0; + return 1; +} + +void* default_bzalloc(void *o, int items, int size) +{ + USED(o); + return sbrk(items*size); +} + +void default_bzfree(void*, void*) +{ +} + +void +bz_internal_error(int) +{ + abort(); +} + +/*-------------------------------------------------------------*/ +/*--- Decompression machinery ---*/ +/*--- decompress.c ---*/ +/*-------------------------------------------------------------*/ + +/*-- + This file is a part of bzip2 and/or libbzip2, a program and + library for lossless, block-sorting data compression. + + Copyright (C) 1996-2000 Julian R Seward. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Julian Seward, Cambridge, UK. + jseward@acm.org + bzip2/libbzip2 version 1.0 of 21 March 2000 + + This program is based on (at least) the work of: + Mike Burrows + David Wheeler + Peter Fenwick + Alistair Moffat + Radford Neal + Ian H. Witten + Robert Sedgewick + Jon L. Bentley + + For more information on these sources, see the manual. +--*/ + + + +/*---------------------------------------------------*/ +static +void makeMaps_d ( DState* s ) +{ + Int32 i; + s->nInUse = 0; + for (i = 0; i < 256; i++) + if (s->inUse[i]) { + s->seqToUnseq[s->nInUse] = i; + s->nInUse++; + } +} + + +/*---------------------------------------------------*/ +#define RETURN(rrr) \ + { retVal = rrr; goto save_state_and_return; }; + +#define GET_BITS(lll,vvv,nnn) \ + case lll: \ + { int x; if((retVal = getbits(s, lll, &x, nnn)) != 99) \ + goto save_state_and_return; vvv=x; }\ + +int +getbits(DState *s, int lll, int *vvv, int nnn) +{ + s->state = lll; + + for(;;) { + if (s->bsLive >= nnn) { + UInt32 v; + v = (s->bsBuff >> + (s->bsLive-nnn)) & ((1 << nnn)-1); + s->bsLive -= nnn; + *vvv = v; + return 99; + } + if (s->strm->avail_in == 0) return BZ_OK; + s->bsBuff + = (s->bsBuff << 8) | + ((UInt32) + (*((UChar*)(s->strm->next_in)))); + s->bsLive += 8; + s->strm->next_in++; + s->strm->avail_in--; + s->strm->total_in_lo32++; + if (s->strm->total_in_lo32 == 0) + s->strm->total_in_hi32++; + } + return -1; /* KEN */ +} + +#define GET_UCHAR(lll,uuu) \ + GET_BITS(lll,uuu,8) + +#define GET_BIT(lll,uuu) \ + GET_BITS(lll,uuu,1) + +/*---------------------------------------------------*/ +#define GET_MTF_VAL(label1,label2,lval) \ +{ \ + if (groupPos == 0) { \ + groupNo++; \ + if (groupNo >= nSelectors) \ + RETURN(BZ_DATA_ERROR); \ + groupPos = BZ_G_SIZE; \ + gSel = s->selector[groupNo]; \ + gMinlen = s->minLens[gSel]; \ + gLimit = &(s->limit[gSel][0]); \ + gPerm = &(s->perm[gSel][0]); \ + gBase = &(s->base[gSel][0]); \ + } \ + groupPos--; \ + zn = gMinlen; \ + GET_BITS(label1, zvec, zn); \ + while (1) { \ + if (zn > 20 /* the longest code */) \ + RETURN(BZ_DATA_ERROR); \ + if (zvec <= gLimit[zn]) break; \ + zn++; \ + GET_BIT(label2, zj); \ + zvec = (zvec << 1) | zj; \ + }; \ + if (zvec - gBase[zn] < 0 \ + || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ + RETURN(BZ_DATA_ERROR); \ + lval = gPerm[zvec - gBase[zn]]; \ +} + + +/*---------------------------------------------------*/ +Int32 BZ2_decompress ( DState* s ) +{ + UChar uc; + Int32 retVal; + Int32 minLen, maxLen; + bz_stream* strm = s->strm; + + /* stuff that needs to be saved/restored */ + Int32 i; + Int32 j; + Int32 t; + Int32 alphaSize; + Int32 nGroups; + Int32 nSelectors; + Int32 EOB; + Int32 groupNo; + Int32 groupPos; + Int32 nextSym; + Int32 nblockMAX; + Int32 nblock; + Int32 es; + Int32 N; + Int32 curr; + Int32 zt; + Int32 zn; + Int32 zvec; + Int32 zj; + Int32 gSel; + Int32 gMinlen; + Int32* gLimit; + Int32* gBase; + Int32* gPerm; + + if (s->state == BZ_X_MAGIC_1) { + /*initialise the save area*/ + s->save_i = 0; + s->save_j = 0; + s->save_t = 0; + s->save_alphaSize = 0; + s->save_nGroups = 0; + s->save_nSelectors = 0; + s->save_EOB = 0; + s->save_groupNo = 0; + s->save_groupPos = 0; + s->save_nextSym = 0; + s->save_nblockMAX = 0; + s->save_nblock = 0; + s->save_es = 0; + s->save_N = 0; + s->save_curr = 0; + s->save_zt = 0; + s->save_zn = 0; + s->save_zvec = 0; + s->save_zj = 0; + s->save_gSel = 0; + s->save_gMinlen = 0; + s->save_gLimit = NULL; + s->save_gBase = NULL; + s->save_gPerm = NULL; + } + + /*restore from the save area*/ + i = s->save_i; + j = s->save_j; + t = s->save_t; + alphaSize = s->save_alphaSize; + nGroups = s->save_nGroups; + nSelectors = s->save_nSelectors; + EOB = s->save_EOB; + groupNo = s->save_groupNo; + groupPos = s->save_groupPos; + nextSym = s->save_nextSym; + nblockMAX = s->save_nblockMAX; + nblock = s->save_nblock; + es = s->save_es; + N = s->save_N; + curr = s->save_curr; + zt = s->save_zt; + zn = s->save_zn; + zvec = s->save_zvec; + zj = s->save_zj; + gSel = s->save_gSel; + gMinlen = s->save_gMinlen; + gLimit = s->save_gLimit; + gBase = s->save_gBase; + gPerm = s->save_gPerm; + + retVal = BZ_OK; + + switch (s->state) { + + GET_UCHAR(BZ_X_MAGIC_1, uc); + if (uc != 'B') RETURN(BZ_DATA_ERROR_MAGIC); + + GET_UCHAR(BZ_X_MAGIC_2, uc); + if (uc != 'Z') RETURN(BZ_DATA_ERROR_MAGIC); + + GET_UCHAR(BZ_X_MAGIC_3, uc) + if (uc != 'h') RETURN(BZ_DATA_ERROR_MAGIC); + + GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) + if (s->blockSize100k < '1' || + s->blockSize100k > '9') RETURN(BZ_DATA_ERROR_MAGIC); + s->blockSize100k -= '0'; + + if (0 && s->smallDecompress) { + s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); + s->ll4 = BZALLOC( + ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) + ); + if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); + } else { + s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); + if (s->tt == NULL) RETURN(BZ_MEM_ERROR); + } + + GET_UCHAR(BZ_X_BLKHDR_1, uc); + + if (uc == 0x17) goto endhdr_2; + if (uc != 0x31) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_2, uc); + if (uc != 0x41) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_3, uc); + if (uc != 0x59) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_4, uc); + if (uc != 0x26) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_5, uc); + if (uc != 0x53) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_6, uc); + if (uc != 0x59) RETURN(BZ_DATA_ERROR); + + s->currBlockNo++; + // if (s->verbosity >= 2) + // VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); + + s->storedBlockCRC = 0; + GET_UCHAR(BZ_X_BCRC_1, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_2, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_3, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_4, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + + GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); + + s->origPtr = 0; + GET_UCHAR(BZ_X_ORIGPTR_1, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + GET_UCHAR(BZ_X_ORIGPTR_2, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + GET_UCHAR(BZ_X_ORIGPTR_3, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + + if (s->origPtr < 0) + RETURN(BZ_DATA_ERROR); + if (s->origPtr > 10 + 100000*s->blockSize100k) + RETURN(BZ_DATA_ERROR); + + /*--- Receive the mapping table ---*/ + for (i = 0; i < 16; i++) { + GET_BIT(BZ_X_MAPPING_1, uc); + if (uc == 1) + s->inUse16[i] = True; else + s->inUse16[i] = False; + } + + for (i = 0; i < 256; i++) s->inUse[i] = False; + + for (i = 0; i < 16; i++) + if (s->inUse16[i]) + for (j = 0; j < 16; j++) { + GET_BIT(BZ_X_MAPPING_2, uc); + if (uc == 1) s->inUse[i * 16 + j] = True; + } + makeMaps_d ( s ); + if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); + alphaSize = s->nInUse+2; + + /*--- Now the selectors ---*/ + GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); + if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); + GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); + if (nSelectors < 1) RETURN(BZ_DATA_ERROR); + for (i = 0; i < nSelectors; i++) { + j = 0; + while (True) { + GET_BIT(BZ_X_SELECTOR_3, uc); + if (uc == 0) break; + j++; + if (j >= nGroups) RETURN(BZ_DATA_ERROR); + } + s->selectorMtf[i] = j; + } + + /*--- Undo the MTF values for the selectors. ---*/ + { + UChar pos[BZ_N_GROUPS], tmp, v; + for (v = 0; v < nGroups; v++) pos[v] = v; + + for (i = 0; i < nSelectors; i++) { + v = s->selectorMtf[i]; + tmp = pos[v]; + while (v > 0) { pos[v] = pos[v-1]; v--; } + pos[0] = tmp; + s->selector[i] = tmp; + } + } + + /*--- Now the coding tables ---*/ + for (t = 0; t < nGroups; t++) { + GET_BITS(BZ_X_CODING_1, curr, 5); + for (i = 0; i < alphaSize; i++) { + while (True) { + if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); + GET_BIT(BZ_X_CODING_2, uc); + if (uc == 0) break; + GET_BIT(BZ_X_CODING_3, uc); + if (uc == 0) curr++; else curr--; + } + s->len[t][i] = curr; + } + } + + /*--- Create the Huffman decoding tables ---*/ + for (t = 0; t < nGroups; t++) { + minLen = 32; + maxLen = 0; + for (i = 0; i < alphaSize; i++) { + if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; + if (s->len[t][i] < minLen) minLen = s->len[t][i]; + } + BZ2_hbCreateDecodeTables ( + &(s->limit[t][0]), + &(s->base[t][0]), + &(s->perm[t][0]), + &(s->len[t][0]), + minLen, maxLen, alphaSize + ); + s->minLens[t] = minLen; + } + + /*--- Now the MTF values ---*/ + + EOB = s->nInUse+1; + nblockMAX = 100000 * s->blockSize100k; + groupNo = -1; + groupPos = 0; + + for (i = 0; i <= 255; i++) s->unzftab[i] = 0; + + /*-- MTF init --*/ + { + Int32 ii, jj, kk; + kk = MTFA_SIZE-1; + for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { + for (jj = MTFL_SIZE-1; jj >= 0; jj--) { + s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); + kk--; + } + s->mtfbase[ii] = kk + 1; + } + } + /*-- end MTF init --*/ + + nblock = 0; + GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); + + while (True) { + + if (nextSym == EOB) break; + + if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { + + es = -1; + N = 1; + do { + if (nextSym == BZ_RUNA) es = es + (0+1) * N; else + if (nextSym == BZ_RUNB) es = es + (1+1) * N; + N = N * 2; + GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); + } + while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); + + es++; + uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; + s->unzftab[uc] += es; + + if (0 && s->smallDecompress) + while (es > 0) { + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + s->ll16[nblock] = (UInt16)uc; + nblock++; + es--; + } + else + while (es > 0) { + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + s->tt[nblock] = (UInt32)uc; + nblock++; + es--; + }; + + continue; + + } else { + + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + + /*-- uc = MTF ( nextSym-1 ) --*/ + { + Int32 ii, jj, kk, pp, lno, off; + UInt32 nn; + nn = (UInt32)(nextSym - 1); + + if (nn < MTFL_SIZE) { + /* avoid general-case expense */ + pp = s->mtfbase[0]; + uc = s->mtfa[pp+nn]; + while (nn > 3) { + Int32 z = pp+nn; + s->mtfa[(z) ] = s->mtfa[(z)-1]; + s->mtfa[(z)-1] = s->mtfa[(z)-2]; + s->mtfa[(z)-2] = s->mtfa[(z)-3]; + s->mtfa[(z)-3] = s->mtfa[(z)-4]; + nn -= 4; + } + while (nn > 0) { + s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; + }; + s->mtfa[pp] = uc; + } else { + /* general case */ + lno = nn / MTFL_SIZE; + off = nn % MTFL_SIZE; + pp = s->mtfbase[lno] + off; + uc = s->mtfa[pp]; + while (pp > s->mtfbase[lno]) { + s->mtfa[pp] = s->mtfa[pp-1]; pp--; + }; + s->mtfbase[lno]++; + while (lno > 0) { + s->mtfbase[lno]--; + s->mtfa[s->mtfbase[lno]] + = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; + lno--; + } + s->mtfbase[0]--; + s->mtfa[s->mtfbase[0]] = uc; + if (s->mtfbase[0] == 0) { + kk = MTFA_SIZE-1; + for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { + for (jj = MTFL_SIZE-1; jj >= 0; jj--) { + s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; + kk--; + } + s->mtfbase[ii] = kk + 1; + } + } + } + } + /*-- end uc = MTF ( nextSym-1 ) --*/ + + s->unzftab[s->seqToUnseq[uc]]++; + if (0 && s->smallDecompress) + s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else + s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); + nblock++; + + GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); + continue; + } + } + + /* Now we know what nblock is, we can do a better sanity + check on s->origPtr. + */ + if (s->origPtr < 0 || s->origPtr >= nblock) + RETURN(BZ_DATA_ERROR); + + s->state_out_len = 0; + s->state_out_ch = 0; + BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); + s->state = BZ_X_OUTPUT; + // if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); + + /*-- Set up cftab to facilitate generation of T^(-1) --*/ + s->cftab[0] = 0; + for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; + for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; + + if (0 && s->smallDecompress) { + + /*-- Make a copy of cftab, used in generation of T --*/ + for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; + + /*-- compute the T vector --*/ + for (i = 0; i < nblock; i++) { + uc = (UChar)(s->ll16[i]); + SET_LL(i, s->cftabCopy[uc]); + s->cftabCopy[uc]++; + } + + /*-- Compute T^(-1) by pointer reversal on T --*/ + i = s->origPtr; + j = GET_LL(i); + do { + Int32 tmp = GET_LL(j); + SET_LL(j, i); + i = j; + j = tmp; + } + while (i != s->origPtr); + + s->tPos = s->origPtr; + s->nblock_used = 0; + if (s->blockRandomised) { + BZ_RAND_INIT_MASK; + BZ_GET_SMALL(s->k0); s->nblock_used++; + BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; + } else { + BZ_GET_SMALL(s->k0); s->nblock_used++; + } + + } else { + + /*-- compute the T^(-1) vector --*/ + for (i = 0; i < nblock; i++) { + uc = (UChar)(s->tt[i] & 0xff); + s->tt[s->cftab[uc]] |= (i << 8); + s->cftab[uc]++; + } + + s->tPos = s->tt[s->origPtr] >> 8; + s->nblock_used = 0; + if (s->blockRandomised) { + BZ_RAND_INIT_MASK; + BZ_GET_FAST(s->k0); s->nblock_used++; + BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; + } else { + BZ_GET_FAST(s->k0); s->nblock_used++; + } + + } + + RETURN(BZ_OK); + + + + endhdr_2: + + GET_UCHAR(BZ_X_ENDHDR_2, uc); + if (uc != 0x72) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_3, uc); + if (uc != 0x45) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_4, uc); + if (uc != 0x38) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_5, uc); + if (uc != 0x50) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_6, uc); + if (uc != 0x90) RETURN(BZ_DATA_ERROR); + + s->storedCombinedCRC = 0; + GET_UCHAR(BZ_X_CCRC_1, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_2, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_3, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_4, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + + s->state = BZ_X_IDLE; + RETURN(BZ_STREAM_END); + + default: AssertH ( False, 4001 ); + } + + AssertH ( False, 4002 ); + + save_state_and_return: + + s->save_i = i; + s->save_j = j; + s->save_t = t; + s->save_alphaSize = alphaSize; + s->save_nGroups = nGroups; + s->save_nSelectors = nSelectors; + s->save_EOB = EOB; + s->save_groupNo = groupNo; + s->save_groupPos = groupPos; + s->save_nextSym = nextSym; + s->save_nblockMAX = nblockMAX; + s->save_nblock = nblock; + s->save_es = es; + s->save_N = N; + s->save_curr = curr; + s->save_zt = zt; + s->save_zn = zn; + s->save_zvec = zvec; + s->save_zj = zj; + s->save_gSel = gSel; + s->save_gMinlen = gMinlen; + s->save_gLimit = gLimit; + s->save_gBase = gBase; + s->save_gPerm = gPerm; + + return retVal; +} + + +/*-------------------------------------------------------------*/ +/*--- end decompress.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/sys/src/cmd/touchfs.c b/sys/src/cmd/touchfs.c new file mode 100644 index 000000000..00fadf3f4 --- /dev/null +++ b/sys/src/cmd/touchfs.c @@ -0,0 +1,66 @@ +#include +#include +#include + +void +Bpass(Biobuf *bin, Biobuf *bout, int n) +{ + char buf[8192]; + int m; + + while(n > 0) { + m = sizeof buf; + if(m > n) + m = n; + m = Bread(bin, buf, m); + if(m <= 0) { + fprint(2, "corrupt archive\n"); + exits("notdone"); + } + Bwrite(bout, buf, m); + n -= m; + } + assert(n == 0); +} + +void +main(int argc, char **argv) +{ + char *p, *f[10]; + Biobuf bin, bout; + int nf; + ulong d, size; + + if(argc != 2) { + fprint(2, "usage: cat mkfs-archive | touchfs date (in seconds)\n"); + exits("usage"); + } + + d = strtoul(argv[1], 0, 0); + + quotefmtinstall(); + Binit(&bin, 0, OREAD); + Binit(&bout, 1, OWRITE); + + while(p = Brdline(&bin, '\n')) { + p[Blinelen(&bin)-1] = '\0'; + if(strcmp(p, "end of archive") == 0) { + Bprint(&bout, "end of archive\n"); + exits(0); + } + + nf = tokenize(p, f, nelem(f)); + if(nf != 6) { + fprint(2, "corrupt archive\n"); + exits("notdone"); + } + + Bprint(&bout, "%q %q %q %q %lud %q\n", + f[0], f[1], f[2], f[3], d, f[5]); + + size = strtoul(f[5], 0, 0); + Bpass(&bin, &bout, size); + } + fprint(2, "premature end of archive\n"); + exits("notdone"); +} -- cgit v1.2.3