diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-04-11 19:47:05 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-04-11 19:47:05 +0000 |
commit | 45bab89362ebe122d60d5e9b1e2b949b26168db3 (patch) | |
tree | c430eb677a06d8c823fd1d2d4a9f7790c0c275d2 /sys/lib/dist.old/cmd | |
parent | 05569f6f2c54a19c1c85a7f10742913cd8904787 (diff) |
livecd
Diffstat (limited to 'sys/lib/dist.old/cmd')
-rw-r--r-- | sys/lib/dist.old/cmd/bargraph.c | 346 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bflz.c | 374 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bzfs/bzfs.h | 11 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bzfs/mkext.c | 288 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bzfs/mkfile | 20 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bzfs/oramfs.c | 927 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bzfs/unbflz.c | 108 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/bzfs/unbzip.c | 861 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/cdsh.c | 133 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/clog.c | 59 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/mkfile | 24 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/multi/mkfile | 76 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/multi/mkmulti | 70 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/multi/multi.c | 38 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/tailfsrv.c | 17 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/touchfs.c | 66 | ||||
-rw-r--r-- | sys/lib/dist.old/cmd/unbflz.c | 109 |
17 files changed, 3527 insertions, 0 deletions
diff --git a/sys/lib/dist.old/cmd/bargraph.c b/sys/lib/dist.old/cmd/bargraph.c new file mode 100644 index 000000000..f7a142ea9 --- /dev/null +++ b/sys/lib/dist.old/cmd/bargraph.c @@ -0,0 +1,346 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <bio.h> +#include <event.h> + +enum {PNCTL=3}; + +static char* rdenv(char*); +int newwin(char*); +Rectangle screenrect(void); + +int nokill; +int textmode; +char *title; + +Image *light; +Image *dark; +Image *text; + +void +initcolor(void) +{ + text = display->black; + light = allocimagemix(display, DPalegreen, DWhite); + dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen); +} + +Rectangle rbar; +Point ptext; +vlong n, d; +int last; +int lastp = -1; +int first = 1; + +char backup[80]; + +void +drawbar(void) +{ + int i, j; + int p; + char buf[200], bar[100], *s; + static char lastbar[100]; + + if(n > d || n < 0 || d <= 0) + return; + + i = (Dx(rbar)*n)/d; + p = (n*100LL)/d; + + if(textmode){ + bar[0] = '|'; + for(j=0; j<i; j++) + bar[j+1] = '#'; + for(; j<60; j++) + bar[j+1] = '-'; + bar[61] = '|'; + bar[62] = ' '; + sprint(bar+63, "%3d%% ", p); + for(i=0; bar[i]==lastbar[i] && bar[i]; i++) + ; + memset(buf, '\b', strlen(lastbar)-i); + strcpy(buf+strlen(lastbar)-i, bar+i); + if(buf[0]) + write(1, buf, strlen(buf)); + strcpy(lastbar, bar); + return; + } + + if(lastp == p && last == i) + return; + + if(lastp != p){ + sprint(buf, "%d%%", p); + + stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP); + lastp = p; + } + + if(last != i){ + draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y), + dark, nil, ZP); + last = i; + } + flushimage(display, 1); +} + +void +eresized(int new) +{ + Point p, q; + Rectangle r; + + if(new && getwindow(display, Refnone) < 0) + fprint(2,"can't reattach to window"); + + r = screen->r; + draw(screen, r, light, nil, ZP); + p = string(screen, addpt(r.min, Pt(4,4)), text, ZP, + display->defaultfont, title); + + p.x = r.min.x+4; + p.y += display->defaultfont->height+4; + + q = subpt(r.max, Pt(4,4)); + rbar = Rpt(p, q); + + ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4); + border(screen, rbar, -2, dark, ZP); + last = 0; + lastp = -1; + + drawbar(); +} + +void +bar(Biobuf *b) +{ + char *p, *f[2]; + Event e; + int k, die, parent, child; + + parent = getpid(); + + die = 0; + if(textmode) + child = -1; + else + switch(child = rfork(RFMEM|RFPROC)) { + case 0: + sleep(1000); + while(!die && (k = eread(Ekeyboard|Emouse, &e))) { + if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */ + die = 1; + postnote(PNPROC, parent, "interrupt"); + _exits("interrupt"); + } + } + _exits(0); + } + + while(!die && (p = Brdline(b, '\n'))) { + p[Blinelen(b)-1] = '\0'; + if(tokenize(p, f, 2) != 2) + continue; + n = strtoll(f[0], 0, 0); + d = strtoll(f[1], 0, 0); + drawbar(); + } + postnote(PNCTL, child, "kill"); +} + + +void +usage(void) +{ + fprint(2, "usage: bargraph [-kt] [-w minx,miny,maxx,maxy] 'title'\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + Biobuf b; + char *p, *q; + int lfd; + + p = "0,0,200,60"; + + ARGBEGIN{ + case 'w': + p = ARGF(); + break; + case 't': + textmode = 1; + break; + case 'k': + nokill = 1; + break; + default: + usage(); + }ARGEND; + + if(argc != 1) + usage(); + + title = argv[0]; + + lfd = dup(0, -1); + + while(q = strchr(p, ',')) + *q = ' '; + Binit(&b, lfd, OREAD); + if(textmode || newwin(p) < 0){ + textmode = 1; + rbar = Rect(0, 0, 60, 1); + }else{ + initdraw(0, 0, "bar"); + initcolor(); + einit(Emouse|Ekeyboard); + eresized(0); + } + bar(&b); +} + + +/* all code below this line should be in the library, but is stolen from colors instead */ +static char* +rdenv(char *name) +{ + char *v; + int fd, size; + + fd = open(name, OREAD); + if(fd < 0) + return 0; + size = seek(fd, 0, 2); + v = malloc(size+1); + if(v == 0){ + fprint(2, "%s: can't malloc: %r\n", argv0); + exits("no mem"); + } + seek(fd, 0, 0); + read(fd, v, size); + v[size] = 0; + close(fd); + return v; +} + +int +newwin(char *win) +{ + char *srv, *mntsrv; + char spec[100]; + int srvfd, cons, pid; + + switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){ + case -1: + fprint(2, "bargraph: can't fork: %r\n"); + return -1; + case 0: + break; + default: + exits(0); + } + + srv = rdenv("/env/wsys"); + if(srv == 0){ + mntsrv = rdenv("/mnt/term/env/wsys"); + if(mntsrv == 0){ + fprint(2, "bargraph: can't find $wsys\n"); + return -1; + } + srv = malloc(strlen(mntsrv)+10); + sprint(srv, "/mnt/term%s", mntsrv); + free(mntsrv); + pid = 0; /* can't send notes to remote processes! */ + }else + pid = getpid(); + USED(pid); + srvfd = open(srv, ORDWR); + free(srv); + if(srvfd == -1){ + fprint(2, "bargraph: can't open %s: %r\n", srv); + return -1; + } + sprint(spec, "new -r %s", win); + if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){ + fprint(2, "bargraph: can't mount /mnt/wsys: %r (spec=%s)\n", spec); + return -1; + } + close(srvfd); + unmount("/mnt/acme", "/dev"); + bind("/mnt/wsys", "/dev", MBEFORE); + cons = open("/dev/cons", OREAD); + if(cons==-1){ + NoCons: + fprint(2, "bargraph: can't open /dev/cons: %r"); + return -1; + } + dup(cons, 0); + close(cons); + cons = open("/dev/cons", OWRITE); + if(cons==-1) + goto NoCons; + dup(cons, 1); + dup(cons, 2); + close(cons); +// wctlfd = open("/dev/wctl", OWRITE); + return 0; +} + +Rectangle +screenrect(void) +{ + int fd; + char buf[12*5]; + + fd = open("/dev/screen", OREAD); + if(fd == -1) + fd=open("/mnt/term/dev/screen", OREAD); + if(fd == -1){ + fprint(2, "%s: can't open /dev/screen: %r\n", argv0); + exits("window read"); + } + if(read(fd, buf, sizeof buf) != sizeof buf){ + fprint(2, "%s: can't read /dev/screen: %r\n", argv0); + exits("screen read"); + } + close(fd); + return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48)); +} + +int +postnote(int group, int pid, char *note) +{ + char file[128]; + int f, r; + + switch(group) { + case PNPROC: + sprint(file, "/proc/%d/note", pid); + break; + case PNGROUP: + sprint(file, "/proc/%d/notepg", pid); + break; + case PNCTL: + sprint(file, "/proc/%d/ctl", pid); + break; + default: + return -1; + } + + f = open(file, OWRITE); + if(f < 0) + return -1; + + r = strlen(note); + if(write(f, note, r) != r) { + close(f); + return -1; + } + close(f); + return 0; +} diff --git a/sys/lib/dist.old/cmd/bflz.c b/sys/lib/dist.old/cmd/bflz.c new file mode 100644 index 000000000..89cb361c2 --- /dev/null +++ b/sys/lib/dist.old/cmd/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 <u.h> +#include <libc.h> +#include <bio.h> + +#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; i<NOFF; i++) + n->offset[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; nhash<x; nhash<<=1) + ; + hash = sbrk(sizeof(Node*)*nhash); + } + + top = &hash[key&(nhash-1)]; + c = 0; + for(l=top; *l; l=&(*l)->link){ + 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; i<NOFF-1 && n->offset[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; i<len && a[i]==b[i]; i++) + ; + return i; +} + +int +countrle(uchar *a) +{ + int i; + + for(i=0; a[i]==a[0]; i++) + ; + return i; +} + +void +compress(void) +{ + int best, i, j, o, rle, run, maxrun, maxoff; + ulong sum; + Node *n; + + sum = 0; + for(i=0; i<win && i<length; i++) + sum = (sum*256+data[i])%Prime; + for(i=0; i<length-win; ){ + maxrun = 0; + maxoff = 0; + if(verbose) + fprint(2, "look %.6lux\n", sum); + n = lookup(sum); + if(n){ + best = -1; + for(o=0; o<NOFF; o++){ + if(n->offset[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(; i<j; i++){ + /* avoid huge chains from large runs of same byte */ + rle = countrle(data+i); + if(rle<4) + insertnode(sum, i); + else if(rle>maxrle[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<length; i++) + rawbyte(i); + flushraw(); +} + +void +usage(void) +{ + fprint(2, "usage: bflz [-n winsize] [file]\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int fd, i, n; + char buf[10485760]; + + ARGBEGIN{ + case 'd': + verbose = 1; + break; + case 's': + replacesame = atoi(EARGF(usage())); + break; + case 'm': + mindist = atoi(EARGF(usage())); + break; + case 'n': + win = atoi(EARGF(usage())); + minrun = win; + break; + default: + usage(); + }ARGEND + + switch(argc){ + default: + usage(); + case 0: + fd = 0; + break; + case 1: + if((fd = open(argv[0], OREAD)) < 0) + sysfatal("open %s: %r", argv[0]); + break; + } + + while((n = readn(fd, buf, sizeof buf)) > 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<win; i++) + outn = (outn * 256) % Prime; + + if(verbose) + fprint(2, "256^%d = %.6lux\n", win, outn); + outn = Prime - outn; + if(verbose) + fprint(2, "outn = %.6lux\n", outn); + + compress(); + Bwrite(&bout, odat, nodat); + Bterm(&bout); + fprint(2, "brk %p\n", sbrk(1)); + fprint(2, "%d nodes used; %d of %d hash slots used\n", nalloc, nnew, nhash); + exits(nil); +} diff --git a/sys/lib/dist.old/cmd/bzfs/bzfs.h b/sys/lib/dist.old/cmd/bzfs/bzfs.h new file mode 100644 index 000000000..1de291a39 --- /dev/null +++ b/sys/lib/dist.old/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/lib/dist.old/cmd/bzfs/mkext.c b/sys/lib/dist.old/cmd/bzfs/mkext.c new file mode 100644 index 000000000..1fedd62cc --- /dev/null +++ b/sys/lib/dist.old/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 <u.h> +#include <libc.h> +#include <bio.h> +#include <auth.h> +#include <fcall.h> +#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 new file mode 100644 index 000000000..df81b5641 --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/mkfile @@ -0,0 +1,20 @@ +</$objtype/mkfile + +TARG=bzfs + +OFILES=\ + mkext.$O\ + oramfs.$O\ + unbflz.$O\ + unbzip.$O\ + +HFILES=bzfs.h + +BIN=/sys/lib/dist/bin/$objtype +LIB=/sys/src/cmd/bzip2/lib/libbzip2.a$O +</sys/src/cmd/mkone + +CFLAGS=$CFLAGS -p -I/sys/src/cmd/bzip2/lib + +/sys/src/cmd/bzip2/lib/libbzip2.a$O: + @{cd /sys/src/cmd/bzip2/lib && mk} diff --git a/sys/lib/dist.old/cmd/bzfs/oramfs.c b/sys/lib/dist.old/cmd/bzfs/oramfs.c new file mode 100644 index 000000000..cba02724a --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/oramfs.c @@ -0,0 +1,927 @@ +#include <u.h> +#include <libc.h> +#include <auth.h> +#include <fcall.h> +#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; i<thdr.nwname && i<MAXWELEM; i++){ + if((fram->qid.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.nwqid<thdr.nwname)){ + /* clunk the new fid, which is the one we walked */ + f->busy = 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 new file mode 100644 index 000000000..661d65e4d --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/unbflz.c @@ -0,0 +1,108 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#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 new file mode 100644 index 000000000..070e7ba48 --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/unbzip.c @@ -0,0 +1,861 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#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 new file mode 100644 index 000000000..2162350bf --- /dev/null +++ b/sys/lib/dist.old/cmd/cdsh.c @@ -0,0 +1,133 @@ +/* + * The `cd' shell. + * Just has cd and lc. + */ + +#include <u.h> +#include <libc.h> +#include <bio.h> + +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 new file mode 100644 index 000000000..98d1cf5f5 --- /dev/null +++ b/sys/lib/dist.old/cmd/clog.c @@ -0,0 +1,59 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +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/mkfile b/sys/lib/dist.old/cmd/mkfile new file mode 100644 index 000000000..bbcd1351c --- /dev/null +++ b/sys/lib/dist.old/cmd/mkfile @@ -0,0 +1,24 @@ +</$objtype/mkfile +CPUS=386 + +TARG=\ + bargraph\ + bflz\ + cdsh\ + tailfsrv\ + touchfs\ + unbflz\ + +OFILES= +HFILES= + +BIN=/sys/lib/dist/bin/$objtype +</sys/src/cmd/mkmany + +all:V: bzfs!all +install:V: bzfs!install +clean:V: bzfs!clean + +bzfs!%:V: + cd bzfs; mk $stem; cd .. + diff --git a/sys/lib/dist.old/cmd/multi/mkfile b/sys/lib/dist.old/cmd/multi/mkfile new file mode 100644 index 000000000..a3acc36de --- /dev/null +++ b/sys/lib/dist.old/cmd/multi/mkfile @@ -0,0 +1,76 @@ +objtype=386 +</$objtype/mkfile + +TARG=multi + +PIECES=\ + aux/mouse\ + aux/pcmcia\ + aux/vga\ + aux/zerotrunc\ + disk/fdisk\ + disk/format\ + disk/mbr\ + disk/prep\ +# fossil/fossil\ +# fossil/flfmt\ + ip/ipconfig\ + ip/ppp\ + ndb/cs\ + ndb/dns\ +# replica/applylog\ + 9660srv\ +# awk\ + basename\ + cat\ + chgrp\ + chmod\ + cleanname\ + cmp\ + cp\ + date\ + dd\ + dossrv\ + echo\ + ed\ + ext2srv\ +# fcp\ + grep\ + hget\ + hoc\ + ls\ + mc\ + mount\ + mv\ + ps\ + read\ +# rio\ + rm\ + sed\ + sort\ + srv\ +# stats\ + syscall\ + tail\ + tee\ + test\ + wc\ + xd\ + +8.multi:V: mkmulti mkfile + mkmulti $PIECES + ls -l 8.multi + ls -l /386/bin/$PIECES | awk '{s += $6} END{print s}' + +scripts:V: + rm -rf ../../pc/multi + mkdir ../../pc/multi + for(i in $PIECES){ + b=`{basename $i} + echo '#!/bin/multi' >>../../pc/multi/$b + chmod +x ../../pc/multi/$b + } + +BIN=/sys/lib/dist/bin/$objtype +</sys/src/cmd/mkmany + diff --git a/sys/lib/dist.old/cmd/multi/mkmulti b/sys/lib/dist.old/cmd/multi/mkmulti new file mode 100644 index 000000000..2317e51e8 --- /dev/null +++ b/sys/lib/dist.old/cmd/multi/mkmulti @@ -0,0 +1,70 @@ +#!/bin/rc + +targ=multi + +n=0 +dir=`{pwd} + +fn grab { + echo using $* + for(i){ + n=`{echo 1+$n|hoc} + mv $i $dir/a.$n.8 + } +} + +fn getfiles { + sed -n 's/^(pcc|8\^l|8l) +(-o [^ ]* +)?([^\-].*)/ \3/p' | sed 's/ -[^ ]*//g' | + sed 's/ [^ ]*\.a//g' +} + +rm a.*.8 +>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 new file mode 100644 index 000000000..a2e3035ad --- /dev/null +++ b/sys/lib/dist.old/cmd/multi/multi.c @@ -0,0 +1,38 @@ +#include <u.h> +#include <libc.h> + +#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<nelem(mains); i++){ + if(strcmp(cmd, mains[i].name) == 0){ + mains[i].fn(argc, argv); + return; + } + } + fprint(2, "multi: no such cmd %s\n", cmd); + exits("no cmd"); +} diff --git a/sys/lib/dist.old/cmd/tailfsrv.c b/sys/lib/dist.old/cmd/tailfsrv.c new file mode 100644 index 000000000..fc41f42ff --- /dev/null +++ b/sys/lib/dist.old/cmd/tailfsrv.c @@ -0,0 +1,17 @@ +#include <u.h> +#include <libc.h> + +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 new file mode 100644 index 000000000..00fadf3f4 --- /dev/null +++ b/sys/lib/dist.old/cmd/touchfs.c @@ -0,0 +1,66 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +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 new file mode 100644 index 000000000..5ddb821f9 --- /dev/null +++ b/sys/lib/dist.old/cmd/unbflz.c @@ -0,0 +1,109 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +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); +} |