diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 16:53:33 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 16:53:33 +0300 |
commit | e463eb40363ff4c68b1d903f4e0cdd0ac1c5977f (patch) | |
tree | d5e9f57c28f026cb21de3bd77cc10cd7f64aaa85 /sys/lib/dist | |
parent | b41b9034225ab3e49980d9de55c141011b6383b0 (diff) |
Import sources from 2011-03-30 iso image - sys/lib
Diffstat (limited to 'sys/lib/dist')
99 files changed, 7031 insertions, 0 deletions
diff --git a/sys/lib/dist/cdstub/bootdisk.img b/sys/lib/dist/cdstub/bootdisk.img new file mode 100755 index 000000000..e69de29bb --- /dev/null +++ b/sys/lib/dist/cdstub/bootdisk.img diff --git a/sys/lib/dist/cmd/bargraph.c b/sys/lib/dist/cmd/bargraph.c new file mode 100755 index 000000000..f7a142ea9 --- /dev/null +++ b/sys/lib/dist/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/cmd/bflz.c b/sys/lib/dist/cmd/bflz.c new file mode 100755 index 000000000..89cb361c2 --- /dev/null +++ b/sys/lib/dist/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/cmd/bzfs/bzfs.h b/sys/lib/dist/cmd/bzfs/bzfs.h new file mode 100755 index 000000000..1de291a39 --- /dev/null +++ b/sys/lib/dist/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/cmd/bzfs/mkext.c b/sys/lib/dist/cmd/bzfs/mkext.c new file mode 100755 index 000000000..1fedd62cc --- /dev/null +++ b/sys/lib/dist/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/cmd/bzfs/mkfile b/sys/lib/dist/cmd/bzfs/mkfile new file mode 100755 index 000000000..df81b5641 --- /dev/null +++ b/sys/lib/dist/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/cmd/bzfs/oramfs.c b/sys/lib/dist/cmd/bzfs/oramfs.c new file mode 100755 index 000000000..cba02724a --- /dev/null +++ b/sys/lib/dist/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/cmd/bzfs/unbflz.c b/sys/lib/dist/cmd/bzfs/unbflz.c new file mode 100755 index 000000000..661d65e4d --- /dev/null +++ b/sys/lib/dist/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/cmd/bzfs/unbzip.c b/sys/lib/dist/cmd/bzfs/unbzip.c new file mode 100755 index 000000000..070e7ba48 --- /dev/null +++ b/sys/lib/dist/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/cmd/cdsh.c b/sys/lib/dist/cmd/cdsh.c new file mode 100755 index 000000000..2162350bf --- /dev/null +++ b/sys/lib/dist/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/cmd/clog.c b/sys/lib/dist/cmd/clog.c new file mode 100755 index 000000000..98d1cf5f5 --- /dev/null +++ b/sys/lib/dist/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/cmd/mkfile b/sys/lib/dist/cmd/mkfile new file mode 100755 index 000000000..bbcd1351c --- /dev/null +++ b/sys/lib/dist/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/cmd/multi/mkfile b/sys/lib/dist/cmd/multi/mkfile new file mode 100755 index 000000000..a3acc36de --- /dev/null +++ b/sys/lib/dist/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/cmd/multi/mkmulti b/sys/lib/dist/cmd/multi/mkmulti new file mode 100755 index 000000000..2317e51e8 --- /dev/null +++ b/sys/lib/dist/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/cmd/multi/multi.c b/sys/lib/dist/cmd/multi/multi.c new file mode 100755 index 000000000..a2e3035ad --- /dev/null +++ b/sys/lib/dist/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/cmd/tailfsrv.c b/sys/lib/dist/cmd/tailfsrv.c new file mode 100755 index 000000000..fc41f42ff --- /dev/null +++ b/sys/lib/dist/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/cmd/touchfs.c b/sys/lib/dist/cmd/touchfs.c new file mode 100755 index 000000000..00fadf3f4 --- /dev/null +++ b/sys/lib/dist/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/cmd/unbflz.c b/sys/lib/dist/cmd/unbflz.c new file mode 100755 index 000000000..5ddb821f9 --- /dev/null +++ b/sys/lib/dist/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); +} diff --git a/sys/lib/dist/logcompress.awk b/sys/lib/dist/logcompress.awk new file mode 100755 index 000000000..3267a48f7 --- /dev/null +++ b/sys/lib/dist/logcompress.awk @@ -0,0 +1,15 @@ +{ + verb[$4] = $3 + data[$4] = sprintf("%s %s %s %s %s %s", $5, $6, $7, $8, $9, $10) +} + +END{ + for(i in verb) + if(verb[i] != "d") + printf("a %s %s\n", i, data[i]) |"sort +1" + close("sort +1") + for(i in verb) + if(verb[i] == "d") + printf("d %s %s\n", i, data[i]) |"sort -r +1" + close("sort -r +1") +} diff --git a/sys/lib/dist/logtime.awk b/sys/lib/dist/logtime.awk new file mode 100755 index 000000000..f974f8db6 --- /dev/null +++ b/sys/lib/dist/logtime.awk @@ -0,0 +1,3 @@ +{ + printf("%s %d %s\n", t, NR, $0); +} diff --git a/sys/lib/dist/mkfile b/sys/lib/dist/mkfile new file mode 100755 index 000000000..98dcd8fee --- /dev/null +++ b/sys/lib/dist/mkfile @@ -0,0 +1,221 @@ +# /sys/lib/dist/mkfile +src9=/n/sources/plan9 # what to export +dist=/sys/lib/dist # where this machinery lives +scr=/n/other/dist # scratch space before copying to web.protect +# import /sys/lib/dist/web.protect from the outside +x=`{setup} + +cd:V: $scr/plan9.iso + +ncd:V: $scr/plan9-new.iso.bz2 + +ncd-dist:V: $scr/plan9-new.iso.bz2 + mk $dist/web.protect/plan9-new.iso.bz2 + +cd-dist:V: $scr/plan9.iso.bz2 + mk $dist/web.protect/plan9.iso.bz2 + +contrib-cd:V: $scr/contrib.iso.bz2 + mk $dist/web.protect/contrib.iso.bz2 + +$scr/%.iso:D: $src9/dist/replica/plan9.log + @ { cd pc; mk cddisk } + rm -f $target + bind pc/cddisk cdstub/bootdisk.img + if(! test -f $src9/bootdisk.img) + bind -a cdstub $src9 + title=`{date | sed 's/(...) (...) (..) (..:..):.. (...) (....)/Plan 9 - \2 \3 \6 \4/'} + title=$"title + echo 'CD:' $title + disk/mk9660 -9cj -v $title -s $src9 -b bootdisk.img $target + +# copy compressed file from scratch space to the distribution, carefully +$dist/web.protect/%.iso.bz2: $scr/%.iso.bz2 + >>$target.new + chmod +t $target.new # waste write buf, not venti store + cp $prereq $target.new + # replace previous version with a flash cut + if (test -e $target) + mv $target $target.old # try to not clobber downloads in progress + mv $target.new $target + +cd-cleanup:V: + rm -f $dist/web.protect/*.iso.bz2.old # remove old versions after a delay + +# generate replica log & db for $src9 only +scan:V: + test -d $scr # make sure other was mounted above + test -d $src9 + test -d $dist/web.protect + lock scan.lock replica/scan $dist/sources.replica + chmod +t $src9/dist/replica/*.^(db log) + +# generate replica log & db for all of /n/sources +scanall:V: + @ { + rfork ne + d=/n/sources + test -d $src9 + lock scanall.lock replica/scan $dist/sourcesall.replica + chmod +t $src9/dist/replica/*.^(db log) + } + +compresslog:V: + { + awk -f logcompress.awk $src9/dist/replica/plan9.log | + awk -f logtime.awk -v 't='^`{date -n} >/tmp/plan9.log + rm -f $src9/dist/replica/plan9.new.log + cp /tmp/plan9.log $src9/dist/replica/plan9.new.log && + mv $src9/dist/replica/plan9.new.log $src9/dist/replica/plan9.log + } <scan.lock + +#restart:V: +# rm -f $src9/dist/replica/plan9.db +# rm -f $src9/dist/replica/plan9.log +# chmod 664 $src9/dist/replica/plan9.db >$src9/dist/replica/plan9.db +# chmod 664 $src9/dist/replica/plan9.log >$src9/dist/replica/plan9.log +# chmod +a $src9/dist/replica/plan9.log +# mk scan + +odump:V: + disk/dump9660 -9cj -v 'Plan 9 4e Dumps' -s $src9 \ + -p /sys/lib/sysconfig/proto/allproto $scr/distdump.iso + +cd.install:V: +# if(~ $sysname achille){ +# echo; echo; echo '*** run this on a real machine, like chips.' +# exit bad +# } + bzip2 -9 <$scr/plan9.iso >web.protect/nplan9.iso.bz2 + +D.install:V: + D=/n/roro/usr/rob/testplan9 + 9fs roro + test -d $D + cp $D$dist/pc/ndisk $dist/web.protect/ndisk + cp $D$dist/pc/9loaddebug $dist/web.protect/n9loaddebug + +reallyinstall:V: + if(! ~ $sysname achille){ + echo; echo; echo '*** this needs to run on achille.' + exit bad + } + cd web.protect + for (i in plan9.iso.bz2 disk 9loaddebug vmware.zip) + if(test -f n$i){ + mv $i _$i && { mv n$i $i || mv _$i $i } + } + rm /srv/ramfs.9down4e + $dist/startcache + +dump:V: + rm -f /srv/9660.xxx + 9660srv 9660.xxx + mount /srv/9660.xxx /n/kremvax $scr/plan9.iso + now=`{mtime $dist/web.protect/plan9.iso.bz2 | awk '{print $1}'} + ls -l /rls/plan9/4e.iso + disk/dump9660 -9cj -s /n/kremvax -n $now /rls/plan9/4e.iso + ls -l /rls/plan9/4e.iso + rm /srv/9660.xxx + +reencode:V: + rm -f $scr/nplan9.iso + rm -f /srv/9660.xxx + 9660srv 9660.xxx + mount /srv/9660.xxx /n/kremvax $scr/plan9.iso + disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s /n/kremvax \ + -b bootdisk.img $scr/nplan9.iso + rm /srv/9660.xxx + +# compress a cd image in scratch space +$scr/%.iso.bz2:D: $scr/%.iso + @ { + cd $scr + bzip2 -9 <$stem.iso >n$stem.iso.bz2 && + { + if (test -e $stem.iso.bz2) + mv $stem.iso.bz2 _$stem.iso.bz2 + mv n$stem.iso.bz2 $stem.iso.bz2 + } + echo `{date} md5 `{md5sum <$stem.iso.bz2} \ + sha1 `{sha1sum <$stem.iso.bz2} \ + $stem.iso.bz2 >>/usr/web/plan9checksums.txt + } + +$scr/contrib.iso:DV: + rm -f $target + disk/mk9660 -9cj -v 'Plan 9 Extras' -s /n/sources \ + -p ./contrib.proto $target + +rebuild:V: + chmod +l build.lock >>build.lock + rebuild <build.lock + +rebuild-mail:V: + chmod +l build.lock >>build.lock + rebuild <build.lock + datemail 'nightly build errors' 9trouble <buildit.out + datemail 'nightly build differences' 9trouble <checkbuild.out + status='' + +scansources-mail:V: + scansources | datemail 'nightly fs vs. sources scan' 9trouble + +worldwritable-mail:V: + test -e $src9 + @ {cd /n/sources; /usr/rsc/bin/$cputype/lsr -t -d} | + awk '$2 ~ /[2367]$/' | grep -vf ok-writable | + datemail 'WRITABLE FILES ON SOURCES' 9trouble || status='' + status='' + @ { + cd $src9 + /usr/rsc/bin/$cputype/lsr -t -d $src9 + } | + awk '$2 ~ /[2367][^2367].$/' | + datemail 'non-group-writable files on sources' 9trouble + status='' + # use /n/boot to avoid walking the archives mounted under + # /lib/vac, or other mounts or binds. + rfork n + 9fs boot + test -e /n/boot/sys + /usr/rsc/bin/$cputype/lsr -t -d /n/boot/sys /n/boot/lib | + grep -v '/lib/audio/|/sys/src/cmd/vac/test/' | # give us a break + awk '$2 ~ /[2367][^2367].$/' | + datemail 'non-group-writable files on fs' 9trouble + status='' + +9.tar.gz:V: + @{ + rfork n + 9fs sources + test -e $src9 + bind -a $src9 $src9/sys/src + cd $src9/sys/src + tar c LICENSE NOTICE 9 + } | gzip >$target + +9-export:V: 9.tar.gz + 9fs sources + cp 9.tar.gz /n/sources/extra/9.tgz + chmod +t /n/sources/extra/9.tgz + +plan9.tar.bz2:V: + @{ + rfork n + 9fs sources + cd /n/sources + test -e $src9 + bind /n/empty $src9/lib/font + bind /n/empty $src9/sys/lib/postscript/font + bind /n/empty $src9/sys/lib/ghostscript + bind /n/empty $src9/sys/src/cmd/gs + tar c plan9/LICENSE* plan9/NOTICE plan9/*/mkfile plan9/*/include \ + plan9/acme/*/src plan9/acme/bin/source \ + plan9/^(adm cron lib lp mail rc sys tmp usr) + } | bzip2 >$target + +plan9-export:V: plan9.tar.bz2 + 9fs sources + chmod +t plan9.tar.bz2 + mv plan9.tar.bz2 /n/sources/extra/plan9.tar.bz2 diff --git a/sys/lib/dist/pc/cd0.proto b/sys/lib/dist/pc/cd0.proto new file mode 100755 index 000000000..62bdb1b10 --- /dev/null +++ b/sys/lib/dist/pc/cd0.proto @@ -0,0 +1 @@ +cddisk diff --git a/sys/lib/dist/pc/emptyfile b/sys/lib/dist/pc/emptyfile new file mode 100755 index 000000000..e69de29bb --- /dev/null +++ b/sys/lib/dist/pc/emptyfile diff --git a/sys/lib/dist/pc/glenda/bin/rc/riostart b/sys/lib/dist/pc/glenda/bin/rc/riostart new file mode 100755 index 000000000..cc5dfa8f2 --- /dev/null +++ b/sys/lib/dist/pc/glenda/bin/rc/riostart @@ -0,0 +1,4 @@ +#!/bin/rc + +window '0 0 100 100' games/clock +window '80 80 610 360' /usr/glenda/lib/first.window diff --git a/sys/lib/dist/pc/glenda/lib/first.window b/sys/lib/dist/pc/glenda/lib/first.window new file mode 100755 index 000000000..c4f264ef2 --- /dev/null +++ b/sys/lib/dist/pc/glenda/lib/first.window @@ -0,0 +1,11 @@ +#!/bin/rc +echo -n readme > /dev/label +echo 'You have completed the Installation Process.' + +cat<<'!' + +Welcome to Plan 9. +This is rc. +! + +exec rc diff --git a/sys/lib/dist/pc/glenda/lib/profile b/sys/lib/dist/pc/glenda/lib/profile new file mode 100755 index 000000000..7767e8a01 --- /dev/null +++ b/sys/lib/dist/pc/glenda/lib/profile @@ -0,0 +1,16 @@ +if(test -f '#m/mousectl') { + echo -n accelerated > '#m/mousectl' + echo -n 'res 3' > '#m/mousectl' +} +user=`{cat /dev/user} +home=/usr/$user +bind -a $home/bin/rc /bin +bind -a $home/bin/$cputype /bin +bind -c $home/tmp /tmp +rio -si inst/gui +echo +echo +echo 'failed to start rio. you can start a text-based installation by running' +echo +echo ' inst/textonly' +echo diff --git a/sys/lib/dist/pc/inst/bootfloppy b/sys/lib/dist/pc/inst/bootfloppy new file mode 100755 index 000000000..c9aebbc51 --- /dev/null +++ b/sys/lib/dist/pc/inst/bootfloppy @@ -0,0 +1,47 @@ +#!/bin/rc + +rfork e + +echo +echo 'Insert a disk other than your installation boot disk' +echo 'into your floppy drive; it will be erased to create' +echo 'the boot floppy.' +echo +echo -n 'Press enter when ready.' +read >/dev/null >[2]/dev/null + +if(~ $#adisk 1) + ; # do nothing +if not if(~ $#bootfile 0) + adisk=/dev/fd0disk +if not { + switch($bootfile) { + case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'} + case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} + case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops + } +} + +if(! ~ `{ls -l $adisk | awk '{print $6}'} 1474560){ + echo 'Will not format non-floppy disk '^$"adisk. >[1=2] + exit 'bad adisk' +} + +log Formatting boot floppy +if (test -e /n/newfs/386/9loadnousb) + bind /n/newfs/386/9loadnousb /n/newfs/386/9load # cater to old bioses +disk/format -b /386/pbs \ + -fd $adisk /n/newfs/386/9load /n/newfs/386/9pcdisk.gz \ + /tmp/plan9ini.bak +x=$status + +if(~ $x ''){ + echo + echo 'Done!' + echo +} +exit $x diff --git a/sys/lib/dist/pc/inst/bootplan9 b/sys/lib/dist/pc/inst/bootplan9 new file mode 100755 index 000000000..942c043b0 --- /dev/null +++ b/sys/lib/dist/pc/inst/bootplan9 @@ -0,0 +1,55 @@ +#!/bin/rc + +first=`{ls -p '#S' | sed 1q} +if(! ~ $first $disk) { + echo 'warning: The plan 9 partition is not on the boot disk,' + echo 'so making it the active partition will have no effect.' +} + +p9offset=`{grep '^part 9fat ' /dev/$disk/ctl |awk '{print $3}'} +if(! ~ $#p9offset 1) { + echo 'could not find plan 9 partition.' + echo 'cannot happen' + exit bad +} + +if(test $p9offset -gt 4128695) { # 65536 * 63 - 10 + echo + echo 'Your Plan 9 partition is more than 2GB into your disk,' + echo 'and the master boot records used by Windows 9x/ME' + echo 'cannot access it (and thus cannot boot it).' + echo + echo 'You can install the Plan 9 master boot record, which can load' + echo 'partitions far into the disk.' + echo +} + +echo 'If you use the Windows NT/2000/XP master boot record' +echo 'or a master boot record from a Unix clone (e.g., LILO or' +echo 'FreeBSD bootmgr), it is probably safe to continue using' +echo 'that boot record rather than install the Plan 9 boot record.' +echo +prompt 'Install the Plan 9 master boot record' y n +switch($rd) { +case n + ; +case y + disk/mbr -m /386/mbr /dev/$disk/data +} + +log Setting Plan 9 partition active. +p9part=`{disk/fdisk /dev/$disk/data >[2]/dev/null </dev/null | + grep PLAN9 | sed 1q | sed 's/ *(p.) .*/\1/'} +if(~ $#p9part 0){ + echo 'You have no Plan 9 partitions (How could this happen?)' >[1=2] + exit 'no plan 9 partition found' +} +p9part=$p9part(1) +{ echo 'A '^$p9part; echo w } | disk/fdisk /dev/$disk/data >[2]/dev/null >/dev/null +x=$status +if(~ $x '' '|'){ + echo + echo 'The Plan 9 partition is now marked as active.' + exit '' +} +exit $x diff --git a/sys/lib/dist/pc/inst/bootsetup b/sys/lib/dist/pc/inst/bootsetup new file mode 100755 index 000000000..cc22fe6ee --- /dev/null +++ b/sys/lib/dist/pc/inst/bootsetup @@ -0,0 +1,125 @@ +#!/bin/rc + +# desc: create a boot floppy or configure hard disk to boot plan 9 +# prereq: copydist + +switch($1) { +case go + echo + echo 'Initializing Plan 9 FAT configuration partition (9fat)' + echo + + fat=(/dev/sd*/9fat) + fat=$fat(1) + disk=`{echo $fat | sed 's:/dev/::;s:/9fat::'} + bootfs=`{echo $fs | sed 's:/dev/(sd..)/(.*):\1!\2:'} + bootfat=`{echo $fs | sed 's:/dev/(sd..)/(.*):\1!9fat:'} + if(! test -f /dev/$disk/9fat) { + echo 'You have no 9fat partition. Can''t setup booting.' + exit + } + + if(! test -f /tmp/plan9.ini) { + { + sfs=`{echo $fs | sed 's;/dev;#S;'} + if(~ $fstype fossil fossil+venti){ + echo bootfile'='$bootfat!9pcf + echo 'bootargs=local!'^$sfs + echo 'bootdisk=local!'^$sfs + } + if not { + echo bootfile'='$bootfs!/386/9pcdisk + echo 'bootdisk=local!'^$sfs + } + if(~ $fstype fossil+venti){ + venti=`{echo $ventiarena | sed 's;/dev;#S;'} + echo venti'='^$venti + } + # sort -u avoids dups which could otherwise trigger + # pointless boot menus. + grep -v '(^\[)|menuitem|adisk|bootfile|bootdisk|bootargs|nobootprompt|mouseport|vgasize|monitor|cdboot' /tmp/plan9.orig | + sort -u + echo 'mouseport='^$mouseport + echo 'monitor='^$monitor + echo 'vgasize='^$vgasize + } >/tmp/plan9.ini + } + if(! test -f /tmp/plan9ini.bak) + cp /tmp/plan9.ini /tmp/plan9ini.bak + + need9fatformat=no + if(! isfat /dev/$disk/9fat) + need9fatformat=yes + if not if(! mount -c /srv/dos /n/9fat /dev/$disk/9fat >[2]/dev/null) + need9fatformat=yes + if not if(! test -f /n/9fat/plan9.ini) + need9fatformat=yes + + if (test -e /n/newfs/386/9loadnousb) + bind /n/newfs/386/9loadnousb /n/newfs/386/9load # cater to old bioses + if(~ $need9fatformat yes){ + log Initializing Plan 9 FAT partition. + disk/format -r 2 -d -b /386/pbs \ + /dev/$disk/9fat /n/newfs/386/9load + # silently install pbslba if the partition is way into the disk. + # it''s our only hope. only need this for >8.5GB into the disk. + # but... + # there are so few non-LBA bioses out + # there anymore that we'll do this even if we're only 2GB into + # the disk. it's just not worth the headaches of dealing with + # crappy bioses that don't address the whole 8.5GB properly + + 9fatoffset=`{grep '^part 9fat ' /dev/$disk/ctl | awk '{print $4}'} + if(! ~ $#9fatoffset 1) { + echo 'could not find plan 9 partition.' + echo 'cannot happen' + exit bad + } + if(test $9fatoffset -gt 2097152) # 2GB + disk/format -b /386/pbslba /dev/$disk/9fat + + mount -c /srv/dos /n/9fat /dev/$disk/9fat + } + + if(! test -f /n/9fat/4e){ + logprog cp /n/newfs/386/9load /n/9fat/9load + logprog cp /n/newfs/386/9pcf /n/9fat/9pcf + if(test -f /n/9fat/plan9.ini && ! test -f /n/9fat/plan9-3e.ini) + logprog mv /n/9fat/plan9.ini /n/9fat/plan9-3e.ini + if(test -f /n/9fat/9pcdisk && ! test -f /n/9fat/9pc3e) + logprog mv /n/9fat/9pcdisk /n/9fat/9pc3e + + awk -f /bin/inst/mkini.awk >/n/9fat/plan9.ini + >/n/9fat/4e + } + + echo + echo 'There are myriad ways to boot a Plan 9 system.' + echo 'You can use any of the following.' + echo + echo ' floppy - create a boot floppy' + echo ' plan9 - make the plan 9 disk partition the default for booting' + echo ' win9x - add a plan 9 option to windows 9x boot menu' + echo ' winnt - add a plan 9 option to windows nt/2000/xp boot manager' + echo + echo 'If you are upgrading an extant third edition installation and booting' + echo 'from something other than a floppy, you needn''t run anything here.' + echo 'Just type ctl-d.' + + oldbootsetup=$didbootsetup + didbootsetup=1 + export didbootsetup + prompt 'Enable boot method' floppy plan9 win9x winnt + + if(! boot$rd){ + didbootsetup=$oldbootsetup + export didbootsetup + } + +case checkdone + xxxfat=(/dev/sd*/9fat) + if(! isfat $xxxfat(1) || ! ~ $didbootsetup 1){ + bootsetup=ready + export bootsetup + } +} diff --git a/sys/lib/dist/pc/inst/bootwin9x b/sys/lib/dist/pc/inst/bootwin9x new file mode 100755 index 000000000..68c2d1923 --- /dev/null +++ b/sys/lib/dist/pc/inst/bootwin9x @@ -0,0 +1,117 @@ +#!/bin/rc + +dosdisk=`{ls /dev/sd??/dos >[2]/dev/null | sed 1q | sed 's!.*/(.*)/dos!\1!'} +if(~ $#dosdisk 0 || ! c: || ! test -f /n/c:/autoexec.bat || ! test -f /n/c:/config.sys) { + echo 'Could not find autoexec.bat or config.sys on the first FAT disk.' + exit bad +} + +for (i in autoexec config msdos) + if(test -f /n/c:/$i.p9) { + echo 'A Plan 9 backup already exists; will not edit system files again.' + exit bad + } + +for (i in autoexec.bat config.sys msdos.sys) + if(! cp /n/c:/$i /n/c:/^`{echo $i | sed 's/\.(bat|sys)$/.p9/'}) { + echo 'Could not back up '^$i^'; will not continue.' + exit bad + } + +if(! test -d /n/c:/plan9 && ! mkdir /n/c:/plan9) { + echo 'Could not create directory /n/c:/plan9.' + exit bad +} + +if(! cp /n/newfs/386/^(9load ld.com 9pcdisk) /tmp/plan9ini.bak /n/c:/plan9) { + echo 'Could not copy Plan 9 boot files into /n/c:/plan9.' + exit bad +} + +chmod +w /n/c:/autoexec.bat /n/c:/config.sys /n/c:/msdos.sys + +if(grep -si 'Plan ?9' /n/c:/config.sys || grep -si 'Plan ?9' /n/c:/autoexec.bat) { + echo 'Plan 9 entries already in config.sys or autoexec.bat.' + echo 'Not changing them; refer to Plan 9 install documentation' + echo 'to configure manually.' + exit bad +} + +if(! grep -si '\[menu\]' /n/c:/config.sys) { + { + echo 1 + echo i + echo '[menu]
' + echo 'menuitem=windows, Windows
' + echo 'menudefault=windows
' + echo '
' + echo '[common]
' + echo '
' + echo '[windows]
' + echo . + echo w + echo q + } | ed /n/c:/config.sys >/dev/null >[2]/dev/null +} + +{ + echo 1 + echo '/\[[Mm][Ee][Nn][Uu]\]' + echo '?^[Mm][Ee][Nn][Uu][Ii][Tt][Ee][Mm]=' + echo a + echo 'menuitem=plan9, Plan 9 from Bell Labs
' + echo . + echo '$' + echo a + echo '
' + echo '[plan9]
' + echo '
' + echo . + echo w + echo q +} | ed /n/c:/config.sys >/dev/null>[2]/dev/null + +{ + echo 1 + echo i + echo '@echo off
' + echo 'if %config%==plan9 goto plan9
' + echo 'goto notplan9
' + echo ':plan9
' + echo 'plan9\ld '^$dosdisk^'!dos!plan9/9load
' + echo ':notplan9
' + echo . + echo w + echo q +} | ed /n/c:/autoexec.bat >/dev/null>[2]/dev/null + +fn zeroopt { + if(grep -s '^'^$1^'=1' /n/c:/msdos.sys) { + { + echo '/^'^$1^'=1/s/=1/=0/' + echo w + echo q + } | ed /n/c:/msdos.sys>/dev/null>[2]/dev/null + } + if not if (grep -s '^'^$1^'=0' /n/c:/msdos.sys) + ; + if not { + { + echo 1 + echo i + echo '[Options]
' + echo 'Logo=0
' + echo . + echo w + echo q + } | ed /n/c:/msdos.sys>/dev/null>[2]/dev/null + } +} + +if(grep -si '^\[paths\]' /n/c:/msdos.sys){ # Windows 9x rather than DOS + zeroopt Logo +# zeroopt BootGUI +} + +echo 'Plan 9 added to Windows 9X boot menu.' +exit '' diff --git a/sys/lib/dist/pc/inst/bootwinnt b/sys/lib/dist/pc/inst/bootwinnt new file mode 100755 index 000000000..ee92f5d76 --- /dev/null +++ b/sys/lib/dist/pc/inst/bootwinnt @@ -0,0 +1,47 @@ +#!/bin/rc + +if(! c: || ! test -f /n/c:/boot.ini) { + echo 'Could not find NT''s boot.ini on the first FAT disk.' + exit bad +} + +if(test -f /n/c:/boot.p9) { + echo 'A Plan 9 backup already exists; will not edit boot.ini again.' + exit bad +} + +if(! cp /n/c:/boot.ini /n/c:/boot.p9) { + echo 'Could not back up boot.ini; will not continue.' + exit bad +} + +chmod +w /n/c:/boot.ini + +if(! grep -si '\[operating systems\]' /n/c:/boot.ini) { + echo 'Could not parse boot.ini.' + exit bad +} + +if(grep -si 'Plan 9' /n/c:/boot.ini) { + p9file=`{grep 'Plan 9' /n/c:/boot.ini | sed 1q | sed 's/=.*//'} + if(! ~ $p9file [Cc]:'\'*) { + echo 'Unexpected Plan 9 entry in boot.ini already; not continuing.' + exit bad + } +} + +if not { + p9file='c:\bootsect.p9' + echo 'c:\bootsect.p9 = "Plan 9 from Bell Labs"
' >>/n/c:/boot.ini +} + +p9file=/n/^`{echo $p9file | sed 's!\\!/!g'} + + +if(dd -if /dev/$disk/plan9 -bs 512 -count 1 -of $p9file >/dev/null >[2]/dev/null) { + echo 'Plan 9 added to Windows NT boot menu.' + exit '' +} + +echo 'Error copying Plan 9 boot sector to file.' +exit bad diff --git a/sys/lib/dist/pc/inst/configarch b/sys/lib/dist/pc/inst/configarch new file mode 100755 index 000000000..61912bfdb --- /dev/null +++ b/sys/lib/dist/pc/inst/configarch @@ -0,0 +1,40 @@ +#!/bin/rc + +# desc: set source of distribution archives +# prereq: mountfs + +switch($1) { +case go + echo + echo 'Will you be using a distribution archive on local media or the internet?' + echo + + prompt 'Distribution is from' local internet + archmedium=$rd + export archmedium + + switch($archmedium) { + case local + exec configlocal go + case internet + exec configip go + } + +case checkdone + switch($#archmedium) { + case 1 + switch($archmedium) { + case local + exec configlocal checkdone + case internet + exec configip checkdone + case * + configarch=notdone + export configarch + } + case * + configarch=notdone + export configarch + } +} + diff --git a/sys/lib/dist/pc/inst/configdist b/sys/lib/dist/pc/inst/configdist new file mode 100755 index 000000000..3e99bea0d --- /dev/null +++ b/sys/lib/dist/pc/inst/configdist @@ -0,0 +1,22 @@ +#!/bin/rc + +# prereq: mountfs +# desc: choose the source of the distribution archive + +switch($1){ +case checkdone + if(! ~ $distisfrom net local){ + configdist=ready + export configdist + } + +case go + echo 'Are you going to download the distribution' + echo 'from the internet or do you have it on local media?' + echo + prompt -d local 'Distribution is from' local net + distisfrom=$rd + export distisfrom +} + + diff --git a/sys/lib/dist/pc/inst/configether b/sys/lib/dist/pc/inst/configether new file mode 100755 index 000000000..0922ea339 --- /dev/null +++ b/sys/lib/dist/pc/inst/configether @@ -0,0 +1,53 @@ +#!/bin/rc + +# desc: configure your internet connection via an ethernet card + +switch($1) { +case go + echo + echo 'Please choose a method for configuring your ethernet connection.' + echo + echo ' manual - specify IP address, network mask, gateway IP address' + echo ' dhcp - use DHCP to automatically configure' + echo + + prompt 'Configuration method' manual dhcp + ethermethod=$rd + gwaddr=xxx + ipaddr=xxx + ipmask=xxx + switch($ethermethod){ + case dhcp + echo + echo 'Some ISPs, notably @HOME, require a host name passed with DHCP' + echo 'requests. An example for @HOME would be "cc1018221-a". If your' + echo 'ISP supplied you such a name, enter it.' + echo + prompt -d none 'host name'; dhcphost=$rd + switch($dhcphost){ + case none + dhcphost=(); + case * + dhcphost=(-h $dhcphost) + } + export dhcphost + case manual + prompt 'ip address'; ipaddr=$rd + prompt 'network mask'; ipmask=$rd + prompt 'gateway address'; gwaddr=$rd + export ipaddr ipmask gwaddr + } + + export ethermethod gwaddr ipaddr ipmask dhcphost + exec startether go + +case checkdone + if(! ~ $ethermethod manual dhcp) { + configether=notdone + export configether + } + if(~ $ethermethod manual && ~ 0 $#ipaddr $#ipmask $#gwaddr) { + configether=notdone + export configether + } +} diff --git a/sys/lib/dist/pc/inst/configfs b/sys/lib/dist/pc/inst/configfs new file mode 100755 index 000000000..81f82897c --- /dev/null +++ b/sys/lib/dist/pc/inst/configfs @@ -0,0 +1,23 @@ +#!/bin/rc + +# desc: choose the type of file system to install + +switch($1){ +case checkdone + if(! ~ $fstype fossil fossil+venti){ + configfs=ready + export configfs + } + +case go + echo 'You can install the following types of file systems:' + echo + echo ' fossil the new Plan9 fileserver' + echo ' fossil+venti fossil + a archival dump server' + echo + prompt -d fossil 'File system' fossil fossil+venti + fstype=$rd + export fstype +} + + diff --git a/sys/lib/dist/pc/inst/configip b/sys/lib/dist/pc/inst/configip new file mode 100755 index 000000000..a7873c9f1 --- /dev/null +++ b/sys/lib/dist/pc/inst/configip @@ -0,0 +1,64 @@ +#!/bin/rc + +switch($1) { +case go + + devs='' + if(test -d '#l/ether0' >[2]/dev/null) + devs=$devs^ether + if(test -f '#t'/eia? >[2]/dev/null) + devs=$devs^ppp + + switch($devs){ + case '' + echo + echo 'Could not find ethernet card nor serial port nor modem.' + echo 'Please use a local copy of the distribution archive.' + echo + ifc=none + + case ppp + echo + echo 'No ethernet card was detected, but there is a serial port or modem.' + echo 'We will configure PPP.' + echo + ifc=ppp + + case ether + echo + echo 'No serial port or modem detected, but there is an ethernet card.' + echo 'We will configure the ethernet.' + echo + ifc=ether + + case etherppp + echo + echo 'You can connect to the internet via' + echo 'a local ethernet or a dial-up PPP connection.' + echo + prompt 'Interface to use' ether ppp + ifc=$rd + } + + ipinterface=$ifc + export ipinterface + + switch($ifc) { + case ether + exec configether go + case ppp + exec configppp go + } + +case checkdone + if(~ $#ipinterface 1) + switch($ipinterface) { + case ether + exec configether checkdone + case ppp + exec configppp checkdone + } + configarch=notdone + export configarch + +} diff --git a/sys/lib/dist/pc/inst/confignet b/sys/lib/dist/pc/inst/confignet new file mode 100755 index 000000000..182ed40cb --- /dev/null +++ b/sys/lib/dist/pc/inst/confignet @@ -0,0 +1,67 @@ +#!/bin/rc + +# prereq: configdist +# desc: configure the network to download the distribution + +switch($1){ +case checkready checkdone + if(! ~ $distisfrom net){ + confignet=notdone + export confignet + exit + } + if(~ $distisfrom net && ~ $netisfrom ppp ether){ + x=config$netisfrom + $x=done + config$netisfrom checkdone + confignet=$$x + export confignet + exit + } + confignet=ready + export confignet + exit + +case go + devs='' + if(test -d '#l/ether0' >[2]/dev/null) + devs=$devs^ether + if(test -f '#t'/eia? >[2]/dev/null) + devs=$devs^ppp + + switch($devs){ + case '' + echo + echo 'Could not find ethernet card nor serial port nor modem.' + echo 'Please use a local copy of the distribution archive.' + echo + netisfrom=none + + case ppp + echo + echo 'No ethernet card was detected, but there is a serial port or modem.' + echo 'We will configure PPP.' + echo + netisfrom=ppp + + case ether + echo + echo 'No serial port or modem detected, but there is an ethernet card.' + echo 'We will configure the ethernet.' + echo + netisfrom=ether + + case etherppp + echo + echo 'You can connect to the internet via' + echo 'a local ethernet or a dial-up PPP connection.' + echo + prompt 'Interface to use' ether ppp + netisfrom=$rd + } + + export netisfrom + if(~ $netisfrom ether ppp) + exec config$netisfrom go +} + diff --git a/sys/lib/dist/pc/inst/configppp b/sys/lib/dist/pc/inst/configppp new file mode 100755 index 000000000..6bbffc4f0 --- /dev/null +++ b/sys/lib/dist/pc/inst/configppp @@ -0,0 +1,63 @@ +#!/bin/rc + +# desc: configure your internet connection via ppp over a modem + +switch($1) { +case go + devs=`{ls -p '#t/'eia? >[2]/dev/null} + if(~ $#devs 0) { + echo 'No serial port found; this can''t happen.' # because configip checks + exit + } + + # not going to use the mouse for PPP + if(~ eia^$mouseport $devs) + devs=`{echo $devs | sed 's/eia'^$mouseport^'//'} + + if(~ $#devs 0) { + echo 'The only serial port you have is your mouse.' + echo 'Cannot configure PPP.' + exit + } + + echo + echo 'Please choose the serial port or modem to use to connect to your ISP.' + echo + for(i in $devs) { + n=`{echo $i | sed 's/eia//'} + n=`{hoc -e 1+$n} + echo ' '^$i^'(Windows'' COM'^$n^')' + } + echo + prompt 'Serial device' $devs + pppdev=$rd + + echo + echo 'Pick a baud rate for the PPP connection.' + echo + prompt -d 115200 'Baud rate' + pppbaud=$rd + + echo + echo 'You can specify your dialup phone number, username, and password,' + echo 'or you can log in manually by typing the modem commands yourself.' + echo + prompt 'Dialing method' auto manual + pppmethod=$rd + + switch($pppmethod){ + case auto + prompt 'PPP phone number'; pppphone=$rd + prompt 'PPP phone username'; pppuser=$rd + prompt 'PPP phone password'; ppppasswd=$rd + } + + export pppdev pppmethod pppphone ppppasswd pppuser pppbaud + exec startppp go + +case checkdone + if(! ~ $#pppmethod 1 || ! test -f /dev/$pppdev){ + configppp=notdone + export configppp + } +} diff --git a/sys/lib/dist/pc/inst/copydist b/sys/lib/dist/pc/inst/copydist new file mode 100755 index 000000000..507d5602b --- /dev/null +++ b/sys/lib/dist/pc/inst/copydist @@ -0,0 +1,31 @@ +#!/bin/rc + +# prereq: mountdist +# desc: copy the distribution into the file system + +switch($1){ +case checkready + if(! test -d /n/dist/dist/replica){ + copydist=notdone + export copydist + exit + } + if(test -f /n/newfs/dist/replica/didplan9){ + copydist=done + export copydist + exit + } +case go + inst/watchfd applylog 0 `{ls -l /n/dist/dist/replica/plan9.log | awk '{print $6}'} 'Installing file system' & + replica/pull -c / /rc/bin/inst/replcfg + if(~ $status '' *conflicts || test -f /n/newfs/dist/replica/didplan9witherrors) + >/n/newfs/dist/replica/didplan9 + if not + >/n/newfs/dist/replica/didplan9witherrors + +case checkdone + if(! test -f /n/newfs/dist/replica/didplan9){ + copydist=notdone + export copydist + } +} diff --git a/sys/lib/dist/pc/inst/defs b/sys/lib/dist/pc/inst/defs new file mode 100755 index 000000000..f9c9454c0 --- /dev/null +++ b/sys/lib/dist/pc/inst/defs @@ -0,0 +1,162 @@ +nl=' +' +tab=' ' +if(~ $#distname 0) + distname=plan9 + +wctl=/dev/null +if(test -w /dev/wctl) + wctl=/dev/wctl + +fn log { + echo $* >>/srv/log +} + +fn logprog { + echo '% '^$"* >>/srv/log + $* >[2=1] >>/srv/log +} + +fn sigint { + # nothing happens +} + +fn prompt { + def=() + what=() + if(~ $1 -d && ! ~ $#* 1){ + def=$2 + shift + shift + } + + optstr=() + if(~ $1 -w && ! ~ $#* 1){ + optstr=$2 + shift + shift + } + + pr=$1 + shift + + opts=($*) + if(~ $#opts 0) { + suf=' ' + } + if not if(! ~ $#optstr 0) { + if(~ $optstr '') + suf=' ' + if not { + pr=$pr^' ('^$"optstr^')' + suf='' + } + } + if not { + pr=$pr^' ('^$1 + shift + for(i) + pr=$pr^', '^$i + pr=$pr^')' + suf='' + } + + if(~ $#def 1) + pr=$pr^$suf^'['^$def^']' + if not + pr=$pr^$suf^'[no default]' + + pr=$pr^': ' + + + okay=no + while(~ $okay no) { + echo -n current >$wctl + echo -n top >$wctl + echo -n $pr >[1=2] + ifs='' {rd=`{read}} + if(~ $#rd 0) + exit notdone + if(~ $rd !*){ + ifs='' {rd=`{echo $rd | sed 's/!//'}} + echo $rd + rc -c $rd + echo !$status + } + if not{ + rd=`{echo $rd} + if(~ $#rd 0 || ~ $rd '') + rd=$def + + switch($#opts){ + case 0 + if(! ~ $rd '') + okay=yes + case * + if(~ $rd $opts) + okay=yes + } + } + } + echo -n $rd >/env/rd # just in case +} + +fn desc { + echo -n ' '^$1^' - ' + grep '^# desc: ' $1 | sed 's/# desc: //' +} + +fn prereq { + grep '^# prereq:' $1 | sed 's/# prereq://' +} + +fn mustdo { + echo You must `{grep '^# mustdo:' $1 | sed 's/# mustdo://'} +} + +# there's no easy way to pass shell variables +# up from children to parents; the parents have +# to be coerced into noticing that the environment +# changed, even when in the same environment group. +# +# instead, we explicitly export the variables we want +# to percolate, and the parent calls coherence to reread +# the variables. +# +# we just append to the vars file, so that later exports +# override earlier ones; when we call coherence, +# the duplicates are thrown out. + +fn export { + null=() + nonnull=() + for(i in $*){ + if(~ $#$i 0) + null=($null $i) + if not + nonnull=($nonnull $i) + } + if(! ~ $#nonnull 0) + whatis $nonnull |grep -v '^\./' >>/tmp/vars >[2]/dev/null + for(i in $null) + echo $i^'=()' >>/tmp/vars +} + +fn coherence { + if(test -f /tmp/vars) { + grep '^[a-z]*=' /tmp/vars >/tmp/vars2 + v=`{sed 's/^([a-z]*)=.*/\1/' /tmp/vars2 | sort -u} + . /tmp/vars2 + rm /tmp/vars2 + rm /tmp/vars + export $v + } +} + +# ip device stats + +fn isipdevup { + grep -s $1 /net/ipifc/*/status >[2]/dev/null +} + + diff --git a/sys/lib/dist/pc/inst/download b/sys/lib/dist/pc/inst/download new file mode 100755 index 000000000..70d7f5ba7 --- /dev/null +++ b/sys/lib/dist/pc/inst/download @@ -0,0 +1,56 @@ +#!/bin/rc + +# prereq: mountfs +# desc: download or continue to download the distribution archives + +switch($1) { +case checkready + devs=(`{cat /net/ipifc/*/status >[2]/dev/null | + grep -v '127\.0\.0\.1' | + sed 's/ .*//'}) + if(~ $#devs 0) { + download=notdone + export download + } + if(~ $mountdist done){ + download=notdone + export download + } + +case go + if(! test -f /srv/cs) { + log starting cs, dns + logprog ndb/cs >>/srv/log >[2=1] + logprog ndb/dns -r >>/srv/log >[2=1] + } + if(! test -f /net/cs) { + logprog mount -a /srv/cs /net + logprog mount -a /srv/dns /net + } + + # BUG make restartable + echo 'Downloading distribution package...' + baropt='-w 145,129,445,168' + if(~ $textinst 1) + baropt=-t + if(! hget -vo /n/newfs/dist/_plan9.iso.bz2 $installurl/plan9.iso.bz2 |[2] bargraph $baropt 'downloading '^plan9.iso.bz2) + exit + mv /n/newfs/dist/_plan9.iso.bz2 /n/newfs/dist/plan9.iso.bz2 + if(~ $fstype fossil){ + echo fsys main sync >>/srv/fscons + } + + echo 'The distribution is downloaded.' + + srvmedia=() + mountmedia=(mount /srv/fossil /n/distmedia) + distmediadir=/dist + export distmediadir mountmedia distmedia + +case checkdone + if(! test -f /n/newfs/dist/plan9.iso.bz2) { + download=notdone + export download + } +} + diff --git a/sys/lib/dist/pc/inst/finish b/sys/lib/dist/pc/inst/finish new file mode 100755 index 000000000..e616e64e1 --- /dev/null +++ b/sys/lib/dist/pc/inst/finish @@ -0,0 +1,19 @@ +#!/bin/rc + +# desc: finish the installation and reboot +# prereq: bootsetup +# mustdo: + +switch($1) { +case checkdone + finish=ready + export finish + +case go + if(~ $cdboot yes){ + echo 'Congratulations; you''ve completed the install.' + echo + halt + } + stop go finished +} diff --git a/sys/lib/dist/pc/inst/fmtfossil b/sys/lib/dist/pc/inst/fmtfossil new file mode 100755 index 000000000..98bf33fc1 --- /dev/null +++ b/sys/lib/dist/pc/inst/fmtfossil @@ -0,0 +1,91 @@ +#!/bin/rc + +# desc: initialize disks for a fossil server +# prereq: configfs + +switch($1){ +case checkready checkdone + if(! ~ $fstype fossil+venti fossil){ + fmtfossil=notdone + export fmtfossil + exit + } + ff=`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null} + if(~ $#ff 0){ + fmtfossil=notdone + export fmtfossil + exit + } + gg=() + for(f in $ff) + if(isfossil $f) + gg=($gg $f) + if(~ $#gg 0){ + fmtfossil=ready + export fmtfossil + exit + } + fmtfossil=done + export fmtfossil + exit + +case go + ff=`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null} + if(~ $#ff 0){ + echo 'You need to create a partition or partitions to hold the Fossil write cache.' + echo 'The partition name must begin with "fossil".' + echo + fmtfossil=notdone + export fmtfossil + exit + } + default=() + if(~ $#ff 1){ + default=(-d $ff) + } + echo You have the following fossil partitions. + echo + prompt $default 'Fossil partition to format' $ff + f=$rd + + do=yes + if(isfossil $f){ + echo $f appears to already be formatted as Fossil file system. + echo Do you really want to reformat it? + echo + prompt -d no 'Reformat '$f yes no + do=$rd + } + if(~ $do yes){ + fossil/flfmt -y $f + n=`{cat /dev/swap | grep ' user' | sed 's/^[0-9]+\/([0-9]+) .*/\1/'} + if(test $n -gt 32768) + m=3000 # if have at least 128 user MB, use 24MB for fossil + if not if(test $n -gt 16384) + m=1500 # 64 user MB => 12MB for fossil + if not if(test $n -gt 8192) + m=750 # 32 user MB => 6MB for fossil + if not + m=256 # 2MB for fossil (this will be slow) + + # if we're using a venti in the back, take hourly snapshots + # that retire after three days, in addition to the daily dumps at 5am + if(~ $fstype fossil+venti){ + v='' + snap='fsys main snaptime -s 60 -a 0500 -t 2880' + } + # otherwise, take the daily dumps but nothing else -- + # we can't retire snapshots unless dumps are being archived + if not{ + v='-V' + snap='' + } + echo \ +'fsys main config '^$f^' +fsys main open '^$v^' -c '^$m^' +'^$snap^' +' | fossil/conf -w $f + } + + echo Done. +} diff --git a/sys/lib/dist/pc/inst/fmtventi b/sys/lib/dist/pc/inst/fmtventi new file mode 100755 index 000000000..db79440ac --- /dev/null +++ b/sys/lib/dist/pc/inst/fmtventi @@ -0,0 +1,190 @@ +#!/bin/rc + +# desc: initialize disks for a venti server +# prereq: mountdist + +switch($1){ +case checkready checkdone + if(! ~ $fstype fossil+venti){ + fmtventi=notdone + export fmtventi + exit + } + if(! test -e /bin/venti/fmtarenas || ! test -e /bin/venti/fmtisect || ! test -e /bin/venti/fmtindex){ + bind -a /n/dist/386/bin/venti /bin/venti + if(! test -e /bin/venti/fmtarenas || ! test -e /bin/venti/fmtisect || ! test -e /bin/venti/fmtindex){ + fmtventi=notdone + export fmtventi + exit + } + } + ff=`{ls /dev/sd*/arenas* /dev/fs/arenas* >[2]/dev/null} + if(~ $#ff 0){ + fmtventi=notdone + export fmtventi + exit + } + gg=() + for(f in $ff) + if(isventi $f) + gg=($gg $f) + if(~ $#gg 0){ + fmtventi=ready + export fmtventi + exit + } + + ventiarena=$gg(1) + export ventiarena + + fmtventi=done + export fmtventi + exit + +case go + ff=`{ls /dev/sd*/arenas* /dev/fs/arenas* >[2]/dev/null} + if(~ $#ff 0){ + echo 'You need to create a partition or partitions to hold the Venti arenas.' + echo 'The arena partition names must begin with "arenas".' + echo + fmtventi=notdone + export fmtventi + exit + } + default=(-d $"ff) + if(! ~ $#ventiarena 0){ + default=(-d $"ventiarena) + } + echo You have the following Venti arena partitions. + ls -l $ff + echo + + prompt $default 'Venti arena partitions to use' + aa=`{echo $rd} + bad=no + for(a in $aa){ + if(! ~ $a $ff){ + echo 'Bad venti arena partition' $a + fmtventi=notdone + export fmtventi + exit + } + } + ventiarena=$aa + export ventiarena + + gg=`{ls /dev/sd*/isect* /dev/fs/isect* >[2]/dev/null} + if(~ $#gg 0){ + echo 'You need to create a partition or partitions to hold the Venti indices.' + echo 'The index partition names must begin with "isect".' + echo + fmtventi=notdone + export fmtventi + exit + } + default=(-d $"gg) + if(! ~ $#ventiindex 0){ + default=(-d $"ventiindex) + } + + echo You have the following Venti index partitions. + ls -l $gg + echo + + prompt $default 'Venti index partitions to use' + aa=`{echo $rd} + bad=no + for(a in $aa){ + if(! ~ $a $gg){ + echo 'Bad venti index partition' $a + fmtventi=notdone + export fmtventi + exit + } + } + ventiindex=$aa + export ventiindex + + n=-1 + fmta=() + for(a in $ventiarena){ + do=yes + n=`{hoc -e 1+$n} + if(isventiarenas $a){ + echo File $a is already formatted as a Venti arenas partition. + prompt -d no 'Reformat '$a yes no + do=$rd + } + if(~ $do yes) + fmta=($fmta arenas$n:$a) + } + + n=-1 + fmti=() + for(a in $ventiindex){ + do=yes + n=`{hoc -e 1+$n} + if(isventiisect $a){ + echo File $a is already formatted as a Venti index section. + prompt -d no 'Reformat '$a yes no + do=$rd + } + if(~ $do yes) + fmti=($fmti isect$n:$a) + } + + echo Formatting Venti arenas and indices (this takes a while). + # do each disk in parallel + echo good >/tmp/fmt + dd=() + for(a in $fmta $fmti){ + d=`{echo $a | sed 's!.*:(/.*/).*!\1!'} + if(! ~ $d $dd) + dd=($dd $d) + } + for(d in $dd){ + { + for(a in $fmta){ + i=`{echo $a | sed 's!(.*):(/.*/)(.*)!\1 \2 \2\3!'} + if(~ $i(2) $d){ + echo $i(3) ... + venti/fmtarenas $i(1) $i(3) || echo bad >/tmp/fmt + echo done with $i(3) + } + } + for(a in $fmti){ + i=`{echo $a | sed 's!(.*):(/.*/)(.*)!\1 \2 \2\3!'} + if(~ $i(2) $d){ + echo $i(3) ... + venti/fmtisect $i(1) $i(3) || echo bad >/tmp/fmt + echo done with $i(3) + } + } + } & + } + wait + if(~ bad `{cat /tmp/fmt}){ + echo There were errors formatting the indices and arenas. + fmtventi=ready + export fmtventi + exit errors + } + + echo Done formatting Venti arenas and indices. + + v=$ventiarena(1) + echo Storing Venti config on $v... + { + echo index main + for(i in $ventiindex) + echo isect $i + for(a in $ventiarena) + echo arenas $a + } | venti/conf -w $v + + echo Initializing index... + venti/fmtindex $v + + echo Done with Venti! +} + diff --git a/sys/lib/dist/pc/inst/gui b/sys/lib/dist/pc/inst/gui new file mode 100755 index 000000000..afb0981d0 --- /dev/null +++ b/sys/lib/dist/pc/inst/gui @@ -0,0 +1,7 @@ +#!/bin/rc + +cd /bin/inst +echo blanktime 0 >/dev/vgactl +. defs + +startwin 640 480 diff --git a/sys/lib/dist/pc/inst/halt b/sys/lib/dist/pc/inst/halt new file mode 100755 index 000000000..4554359f0 --- /dev/null +++ b/sys/lib/dist/pc/inst/halt @@ -0,0 +1,18 @@ +#!/bin/rc + +echo -n 'Halting file systems...' + +if(ps | grep -s ' venti$') + venti/sync -h tcp!127.0.0.1!17034 +if(ps | grep -s ' fossil$'){ + echo fsys all halt >>/srv/fscons + slay fossil|rc +} + +echo done +echo +echo Remember to take the install disk out of the drive. +echo Feel free to turn off your computer. +while() + sleep 3600 + diff --git a/sys/lib/dist/pc/inst/hasmbr b/sys/lib/dist/pc/inst/hasmbr new file mode 100755 index 000000000..1adaa0a5b --- /dev/null +++ b/sys/lib/dist/pc/inst/hasmbr @@ -0,0 +1,12 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: hasmbr /dev/sdC0/part' >[1=2] + exit usage +} + +x=`{xd -b $1 | sed -n '32p;32q'} +if(~ $x(16) 55 && ~ $x(17) aa) + exit '' +exit nope + diff --git a/sys/lib/dist/pc/inst/hdrs b/sys/lib/dist/pc/inst/hdrs new file mode 100755 index 000000000..0b934999f --- /dev/null +++ b/sys/lib/dist/pc/inst/hdrs @@ -0,0 +1,7 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: hdrs file.9gz' >[1=2] + exit usage +} +gunzip < $1 | disk/mkext -h diff --git a/sys/lib/dist/pc/inst/is9660 b/sys/lib/dist/pc/inst/is9660 new file mode 100755 index 000000000..1d138e55e --- /dev/null +++ b/sys/lib/dist/pc/inst/is9660 @@ -0,0 +1,12 @@ +#!/bin/rc + +# 0000000 01 C D 0 0 1 01 00 P L A N 9 + +if(! ~ $#* 1) { + echo 'usage: is9660 /dev/sdC0/part' >[1=2] + exit usage +} + +ifs=$nl {id=`{dd -if $1 -bs 2048 -skip 16>[2]/dev/null | xd -c | sed 1q | sed 's/.........(....................).*/\1/'}} +~ $id '01 C D 0 0 1 01' +exit $status diff --git a/sys/lib/dist/pc/inst/isext2 b/sys/lib/dist/pc/inst/isext2 new file mode 100755 index 000000000..b79265f6a --- /dev/null +++ b/sys/lib/dist/pc/inst/isext2 @@ -0,0 +1,11 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: isext2 /dev/sdC0/part' >[1=2] + exit usage +} + +cmp -s <{dd -if $1 -bs 1 -count 2 -skip 1080 >[2]/dev/null | xd -b |sed 1q} \ + <{echo '0000000 53 ef'} + +exit $status diff --git a/sys/lib/dist/pc/inst/isfat b/sys/lib/dist/pc/inst/isfat new file mode 100755 index 000000000..860278571 --- /dev/null +++ b/sys/lib/dist/pc/inst/isfat @@ -0,0 +1,22 @@ +#!/bin/rc + +rfork e + +# 0000000 eb 3c 90 P l a n 9 . 0 0 00 02 04 02 00 +# 0000010 02 00 02 02 P f8 14 00 ? 00 ff 00 ~ 04 } 00 +# 0000020 02 P 00 00 80 00 ) a8 04 } 00 C Y L I N +# 0000030 D R I C A L F A T 1 6 fa 8c + +if(! ~ $#* 1) { + echo 'usage: isfat /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +fn fat { + cmp -s <{dd -if $arg -bs 1 -count 3 -skip $1 >[2]/dev/null} <{echo -n FAT} +} + +fat 54 || fat 82 +exit $status + diff --git a/sys/lib/dist/pc/inst/isfossil b/sys/lib/dist/pc/inst/isfossil new file mode 100755 index 000000000..21c7d3e29 --- /dev/null +++ b/sys/lib/dist/pc/inst/isfossil @@ -0,0 +1,16 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isfossil /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 127 | + dd -quiet 1 -bs 14 -count 1} <{echo 'fossil config'}) + exit noconfig +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 128 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 37 76 ae 89'}) + exit notwritebuffer +exit 0 + diff --git a/sys/lib/dist/pc/inst/isventi b/sys/lib/dist/pc/inst/isventi new file mode 100755 index 000000000..555c27a7f --- /dev/null +++ b/sys/lib/dist/pc/inst/isventi @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventi /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 248 | + dd -quiet 1 -bs 13 -count 1} <{echo 'venti config'}) + exit noconfig +exit 0 + diff --git a/sys/lib/dist/pc/inst/isventiarenas b/sys/lib/dist/pc/inst/isventiarenas new file mode 100755 index 000000000..dfce274de --- /dev/null +++ b/sys/lib/dist/pc/inst/isventiarenas @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventiarenas /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 256 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 a9 e4 a5 e7'}) + exit notarenas +exit 0 + diff --git a/sys/lib/dist/pc/inst/isventiisect b/sys/lib/dist/pc/inst/isventiisect new file mode 100755 index 000000000..0b11c9c4e --- /dev/null +++ b/sys/lib/dist/pc/inst/isventiisect @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventiisect /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 256 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 d1 5c 5e c7'}) + exit notisect +exit 0 + diff --git a/sys/lib/dist/pc/inst/main b/sys/lib/dist/pc/inst/main new file mode 100755 index 000000000..25ac0d168 --- /dev/null +++ b/sys/lib/dist/pc/inst/main @@ -0,0 +1,115 @@ +#!/bin/rc + +. defs + +while() +{ +div=-------------------------------------- +echo +echo $div +echo +echo -n 'Preparing menu...' + +# must be topologically sorted (by prereq) +tasks=(\ + configfs\ + partdisk prepdisk\ + fmtfossil\ + mountfs\ + configdist\ + confignet\ + mountdist\ + fmtventi\ + download\ + copydist\ + bootsetup finish stop\ + stopether stopppp\ +) +# startether startppp stopether stopppp download\ + +# these don't show up in the menu but still matter +pseudotasks=(configip havefiles etherup etherdown pppup pppdown) + +for(i in $tasks $pseudotasks) + $i=notdone + +coherence + +for(i in $tasks $pseudotasks) + if(~ $#$i 0) + $i=notdone + +# +# we believe the environment about what is done +# only if we've confirmed it. since the tasks list is sorted so that +# prereqs of xxx come before xxx, it's okay to assume xxx +# is done until proven otherwise -- either a prereq or checkdone +# will say so. +# + +done=() +ready=() +rm /env/done +rm /env/ready +for(i in $tasks) { + $i=done + for(j in `{prereq $i}) + if(! ~ $$j done) + $i=notdone + if(~ $$i done) { + export $i + $i checkdone + $i=`{grep '^'$i^'=' /tmp/vars | sed -n '$p' | sed 's/.*=//'} + } + + if(~ $$i notdone ready) { + okay=yes + for(j in `{prereq $i}) + if(! ~ $$j done) + okay=no + switch($okay){ + case yes + $i=ready + export $i + $i checkready + $i=`{grep '^'$i^'=' /tmp/vars | sed -n '$p' | sed 's/.*=//'} + case no + $i=notdone + } + } + + if(~ $$i done ready) + $$i=($$$i $i) # rc can be just as complicated as perl! +} + +export $tasks $pseudotasks done ready +coherence +echo + +if(! ~ $#done 0) { + echo 'The following tasks are done: ' + for(i in $done) + desc $i + echo +} + +echo 'The following unfinished tasks are ready to be done:' +for(i in $ready) + desc $i +echo + +if(~ $#ready 0) { + echo hey you finished everything! not supposed to happen. + sleep 100 + exit +} + +prompt -d $ready(1) -w '' 'Task to do' $done $ready + +echo +echo $div + +$rd go +$rd=done # if it's not, the check will figure that out +export $rd +} diff --git a/sys/lib/dist/pc/inst/mainloop b/sys/lib/dist/pc/inst/mainloop new file mode 100755 index 000000000..94d58efc4 --- /dev/null +++ b/sys/lib/dist/pc/inst/mainloop @@ -0,0 +1,23 @@ +#!/bin/rc + +sleep 86400 & +cd /bin/inst +. defs +fn sigint { } + +coherence + +disks=`{ls /dev/sd*/data >[2]/dev/null | sed 's!/dev/(sd..)/data!\1!'} +for (i in /dev/sd*/data) + if(test -f $i) + disk/fdisk -p $i>`{basename -d $i}^/ctl >[2]/dev/null +for(i in /dev/sd*/plan9*) + if(test -f $i) + disk/prep -p $i >`{basename -d $i}^/ctl >[2]/dev/null + +# we run this while() here so that ctl-d won''t exit from us -- it''ll only exit main! +# main contains a while() loop too, to avoid the hit of +# continually reexecing from here. + +while() + main diff --git a/sys/lib/dist/pc/inst/mkini.awk b/sys/lib/dist/pc/inst/mkini.awk new file mode 100755 index 000000000..7ddf6a80f --- /dev/null +++ b/sys/lib/dist/pc/inst/mkini.awk @@ -0,0 +1,59 @@ +BEGIN{ + m = "common" + haveold = 0; + while(getline <"/n/9fat/plan9-3e.ini" > 0){ + haveold = 1 + if($0 ~ /\[.*\]/){ + m = substr($0, 2, length($0)-2) + continue + } + if(m=="menu" && $0 ~ /^menuitem=4e,/) + continue + a[m] = a[m] $0 "\n" + } + + a["4e"] = "" + while(getline <"/tmp/plan9.ini" > 0) + a["4e"] = a["4e"] $0 "\n" + + if(a["menu"] == "" && haveold){ + a["menu"] = "menuitem=3e, Plan 9 Third Edition\n" + a["3e"] = "" + } + + if(a["common"] != ""){ + for(i in a) + if(i != "4e" && i != "common" && i != "menu") + a[i] = a["common"] a[i] + delete a["common"] + } + + bootdisk4e=ENVIRON["fs"] + gsub("/dev/", "boot(args|disk|file)=local!#S/", bootdisk4e) + + if(!haveold) + print a["4e"] + else{ + print "[menu]" + print "menuitem=4e, Plan 9 Fourth Edition" + print a["menu"] + print "" + delete a["menu"] + + print "[4e]" + print a["4e"] + print "" + delete a["4e"] + + for(i in a){ + # BUG: if rootdir is already there we should rewrite it + # sometimes into /3e/whatwasthere + if(a[i] ~ bootdisk4e && !(a[i] ~ /rootdir=/)) + a[i] = "rootdir=/root/3e\n" a[i] + print "[" i "]" + gsub(/9fat!9pcdisk/, "9fat!9pc3e", a[i]) + print a[i] + print "" + } + } +} diff --git a/sys/lib/dist/pc/inst/mountdist b/sys/lib/dist/pc/inst/mountdist new file mode 100755 index 000000000..8d171a1cc --- /dev/null +++ b/sys/lib/dist/pc/inst/mountdist @@ -0,0 +1,222 @@ +#!/bin/rc + +# prereq: mountfs configdist +# desc: locate and mount the distribution + +fn domount{ + if(! test -e $mountmedia(2)) + logprog $srvmedia + unmount /n/distmedia >[2]/dev/null + logprog $mountmedia +} + +fn exitifdone{ + if(test -f /n/dist/dist/replica/plan9.db) + exit +} + +fn trycdimage{ + if(test -f $1){ + rm -f /srv/9660.dist + unmount /n/dist + 9660srv 9660.dist >[2]/dev/null + logprog mount /srv/9660.dist /n/dist $1 + exitifdone + mountdist=notdone + export mountdist + exit notdone + } +} + +fn trycdimagebz2 { + if(test -f $1){ + echo -n 'bunzip2 < '^$1^' >/n/newfs/dist/plan9.iso' + bunzip2 < $1 >/n/newfs/dist/_plan9.iso && + mv /n/newfs/dist/_plan9.iso /n/newfs/dist/plan9.iso + echo + trycdimage /n/newfs/dist/plan9.iso + mountdist=notdone + export mountdist + exit notdone + } +} + +fn havedist { + test -f $1/dist/replica/plan9.db || + test -f $1/plan9.iso || + test -f $1/plan9.iso.bz2 +} + +switch($1){ +case checkready + if(! ~ $distisfrom local && ! ~ $download done){ + mountdist=notdone + export mountdist + } + if(! ~ $#mountmedia 0 1){ + if(domount){ + mountdist=done + export mountdist + if(mountdist checkdone) + exit + } + srvmedia=() + mountmedia=() + mountdist=ready + export srvmedia mountmedia mountdist + } + +case go + fat=() + ext2=() + x9660=() + fossil=() + + echo Please wait... Scanning storage devices... + + parts=`{ls /dev/sd??/* >[2]/dev/null | grep -v '/(plan9.*|ctl|log|raw)$'} + for (i in $parts) { + echo -n ' '^$i + n=`{echo $i | sed 's;/;_;g'} + if(! test -f /tmp/localpart.$n) + dd -if $i -bs 2048 -count 32 -of /tmp/localpart.$n >[2]/dev/null + if(isfat /tmp/localpart.$n) + fat=($fat $i) + if(isext2 /tmp/localpart.$n) + ext2=($ext2 $i) + if(is9660 /tmp/localpart.$n) + x9660=($x9660 $i) + if(isfossil $i) + fossil=($fossil $i) + echo + } + echo + echo The following storage media were detected. + echo Choose the one containing the distribution. + echo + for(i in $parts){ + switch($i){ + case $fat + echo ' '^$i^' (microsoft fat)' + case $ext2 + echo ' '^$i^' (linux ext2)' + case $x9660 + echo ' '^$i^' (iso9660 cdrom)' + case $fossil + echo ' '^$i^' (plan9 fossil)' + } + } + echo + + mountstatus=x + while(! ~ $mountstatus ''){ + prompt -w '' 'Distribution disk' $fat $x9660 $fossil + disk=$rd + + srvmedia=() + mountmedia=() + switch($disk){ + case $fs + mountmedia=(bind /n/newfs /n/distmedia) + case $fat + srvmedia=(dossrv) + mountmedia=(mount /srv/dos /n/distmedia $disk) + case $ext2 + srvmedia=(ext2srv -r) + mountmedia=(mount /srv/ext2 /n/distmedia $disk) + case $x9660 + srvmedia=(9660srv) + mountmedia=(mount /srv/9660 /n/distmedia $disk) + case $fossil + echo 'srv fossil.mountdist' > /tmp/fossi.conf + echo 'fsys main config '^$disk >> /tmp/fossil.conf + echo 'fsys main open -AWVP' >> /tmp/fossil.conf + echo 'fsys main' >> /tmp/fossil.conf + srvmedia=(fossil/fossil -c '. /tmp/fossil.conf') + mountmedia=(mount /srv/fossil.mountdist /n/distmedia) + case * + echo Unknown disk type '(cannot happen)' + exit oops + } + export srvmedia mountmedia + domount + mountstatus=$status + } + + first=yes + dir=/ + while(~ $first yes || ! havedist /n/distmedia/$dir){ + if(~ $first yes){ + echo + echo Which directory contains the distribution? + echo 'Any of the following will suffice (in order of preference):' + echo ' - the root directory of the cd image' + echo ' - the directory containing plan9.iso' + echo ' - the directory containing plan9.iso.bz2' + echo 'Typing `browse'' will put you in a shell that you can use to' + echo 'look for the directory.' + echo + first=no + } + + prompt -d browse 'Location of archives' + dir=$rd + if(~ $dir browse){ + echo This is a simple shell. Commands are: + echo ' cd directory - change to directory' + echo ' lc - list contents of current directory' + echo ' exit - exit shell' + echo + echo 'Move to the directory containing the distribution' + echo 'and then exit.' + echo + oifs=$ifs + ifs=$nl + dir=`{cdsh -r /n/distmedia} + ifs=$oifs + } + if(~ $#dir 0) + dir=safdsfdsfdsf + if(! ~ $#dir 1) + dir=$"dir + if(! havedist /n/distmedia/$dir) + echo 'No distribution found in '^`{cleanname /$dir} + } + + distmediadir=$dir + export distmediadir + +case checkdone + if(! ~ $#distmediadir 1){ + mountdist=notdone + export mountdist + exit notdone + } + if(! havedist /n/distmedia/$distmediadir && ! havedist /n/newfs/dist){ + mountdist=notdone + export mountdist + exit notdone + } + + exitifdone + + if(test -f /n/distmedia/$distmediadir/dist/replica/plan9.db){ + bind /n/distmedia/$distmediadir /n/dist + bind -a /n/dist/386/bin /bin + bind -a /n/dist/rc/bin /bin + exitifdone + mountdist=notdone + export mountdist + exit notdone + } + + trycdimage /n/distmedia/$distmediadir/plan9.iso + trycdimage /n/newfs/dist/plan9.iso + + trycdimagebz2 /n/distmedia/$distmediadir/plan9.iso.bz2 + trycdimagebz2 /n/newfs/dist/plan9.iso.bz2 + + mountdist=notdone + export mountdist + exit notdone +} diff --git a/sys/lib/dist/pc/inst/mountfossil b/sys/lib/dist/pc/inst/mountfossil new file mode 100755 index 000000000..e98a3f48c --- /dev/null +++ b/sys/lib/dist/pc/inst/mountfossil @@ -0,0 +1,104 @@ +#!/bin/rc + +switch($1){ +case checkready checkdone + if(! ~ $fmtfossil done){ + mountfs=notdone + export mountfs + exit + } + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*){ + mountfs=notdone + export mountfs + exit + } + if(! ~ $#fossil 1 || ! test -f $fossil){ + mountfs=ready + export mountfs + exit + } + if(! ps | grep -s ' fossil$'){ + echo 'srv -p fscons' > /env/fossilconf + echo 'srv -AP fossil' >> /env/fossilconf + fossil/conf $fossil | sed 's/^fsys main open .*/& -AWVP/' | + sed 's/^fsys main snaptime .*//' >> /env/fossilconf + if(! logprog fossil/fossil -c .' /env/fossilconf'>>[2]/srv/log){ + echo 'fossil: '^$status + mountfs=ready + export mountfs + exit oops + } + if(! test -f /srv/fossil){ + echo 'fossil did not create /srv/fossil' + mountfs=ready + exit oops + } + cat /srv/fscons >>/srv/log & + if(! logprog mount -c /srv/fossil /n/newfs){ + echo 'mount: '^$status + mountfs=ready + export mountfs + exit oops + } + fs=$fossil + export fs + } + if(! test -s /n/newfs/adm/users){ + echo fsys main create /active/adm adm sys d775 >>/srv/fscons + echo fsys main create /active/adm/users adm sys 664 >>/srv/fscons + echo uname upas :upas >>/srv/fscons + echo users -w >>/srv/fscons + sleep 2 + } + if(! test -s /n/newfs/adm/users){ + echo 'could not create /adm/users' + mountfs=ready + export mountfs + exit oops + } + for(i in dist dist/replica dist/replica/client){ + if(! test -d /n/newfs/$i) + echo fsys main create /active/$i sys sys d775 >>/srv/fscons + sleep 2 + } + if(! test -d /n/newfs/dist/replica/client){ + echo 'could not create /dist/replica/client' + mountfs=ready + export mountfs + exit oops + } + if(! test -e /n/newfs/dist/replica/client/plan9.db){ + echo fsys main create /active/dist/replica/client/plan9.db sys sys 664 >>/srv/fscons + echo fsys main create /active/dist/replica/client/plan9.log sys sys a664 >>/srv/fscons + } + if(test -d /n/newfs/dist/replica/client && test -f /n/newfs/adm/users){ + mountfs=done + export mountfs + exit + } + mountfs=ready + export mountfs + exit + +case go + echo 'The following partitions named fossil* were found.' + echo + echo 'Please choose one to use as the installation file system' + echo 'for your Plan 9 installation.' + echo + files=(`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null}) + ls -l $files + echo + if(~ $#fossil 1 && ~ $fossil $files) + default=(-d $fossil) + if not if(~ $#files 1) + default=(-d $files) + if not + default=() + prompt $default 'Fossil partition' $files + slay fossil|rc + fossil=$rd + export fossil +} + + diff --git a/sys/lib/dist/pc/inst/mountfs b/sys/lib/dist/pc/inst/mountfs new file mode 100755 index 000000000..8aa9b16ff --- /dev/null +++ b/sys/lib/dist/pc/inst/mountfs @@ -0,0 +1,14 @@ +#!/bin/rc + +# desc: choose and mount file system partition +# prereq: configfs + +switch($fstype){ +case fossil fossil+venti + exec mountfossil $* +case * + mountfs=notdone + export mountfs + exit +} + diff --git a/sys/lib/dist/pc/inst/moveoldfs b/sys/lib/dist/pc/inst/moveoldfs new file mode 100755 index 000000000..819beeb39 --- /dev/null +++ b/sys/lib/dist/pc/inst/moveoldfs @@ -0,0 +1,72 @@ +#!/bin/rc + +# desc: move an old third edition plan 9 file system out of the way +# prereq: mountfs + +rootfiles=(\ + 386\ + 68000\ + 68020\ + LICENSE\ + NOTICE\ + acme\ + adm\ + alpha\ + arm\ + cron\ + dist\ + fd\ + lib\ + lp\ + mail\ + mips\ + mnt\ + n\ + power\ + rc\ + sparc\ + sys\ + tmp\ + usr/glenda\ + wrap\ +) + +switch($1){ +case checkready + if(! test -d /n/kfs/wrap){ + moveoldfs=done + export moveoldfs + } + +case go + if(test -d /n/kfs/wrap){ + echo 'You have a Third Edition Plan 9 installation on '^$fs^'.' + echo 'We need to move the old file system out of the way (into /3e)' + echo 'in order to continue.' + echo + prompt 'Move old file system' y n + switch($rd){ + case y + kname=`{kfsname $fs} + log Moving old Plan 9 installation into /3e on kfs + logprog disk/kfscmd -n$kname 'create /3e sys sys 555 d' >>[2]/srv/log + logprog disk/kfscmd -n$kname 'create /3e/usr sys sys 555 d' >>[2]/srv/log + for(i in $rootfiles) + if(test -e /n/kfs/$i) + logprog disk/kfscmd -n$kname 'rename /'^$i^' /3e/'^$i + # copy extant /adm/users in case there have been modifications + logprog disk/kfscmd -n$kname 'create /adm adm adm 555 d' >>[2]/srv/log + logprog cp /n/kfs/3e/adm/users /n/kfs/adm/users >>[2]/srv/log + + case n + echo 'Okay, but we can''t continue.' + echo + } + } + +case checkdone + if(test -d /n/kfs/wrap){ + moveoldfs=notdone + export moveoldfs + } +} diff --git a/sys/lib/dist/pc/inst/partdisk b/sys/lib/dist/pc/inst/partdisk new file mode 100755 index 000000000..430d45f3f --- /dev/null +++ b/sys/lib/dist/pc/inst/partdisk @@ -0,0 +1,73 @@ +#!/bin/rc + +# desc: edit partition tables (e.g., to create a plan 9 partition) +# prereq: configfs + +switch($1){ +case go + disks=`{ls /dev/sd*/data >[2]/dev/null | sed 's!/dev/(sd..)/data!\1!'} + if(~ $#disks 0) { + echo 'No disk devices were found on your system.' + echo 'The installation process cannot continue.' + exit giveup + } + + echo 'The following disk devices were found.' + echo + for(i in $disks) { + desc=`{cat /dev/$i/ctl | sed 1q | sed 's/inquiry //'} + echo $i '-' $desc + echo e | disk/fdisk -r /dev/$i/data >[2]/dev/null | grep -v '^ mbr' + echo + } + + okay=no + defdisk=$disks(1) + + if(~ $#disks 1) + default=(-d $disks) + if not + default=() + prompt $default 'Disk to partition' $disks + disk=$rd + + if(! hasmbr /dev/$disk/data) { + echo 'The disk you selected HAS NO master boot record on its first sector.' + echo '(Perhaps it is a completely blank disk.)' + echo 'You need a master boot record to use the disk.' + echo 'Should we install a default master boot record?' + echo + prompt 'Install mbr' y n + switch($rd) { + case y + disk/mbr -m /386/mbr /dev/$disk/data + pickdisk=done + } + } + echo + echo 'This is disk/fdisk; use it to create a Plan 9 partition.' + echo 'If there is enough room, a Plan 9 partition will be' + echo 'suggested; you can probably just type ''w'' and then ''q''.' + echo + disk/fdisk -a /dev/$disk/data + disk/fdisk -p /dev/$disk/data >/dev/$disk/ctl >[2]/dev/null + for(i in /dev/sd*/plan9*){ + if(test -f $i){ + d=`{basename -d $i} + disk/prep -p $i >$d/ctl >[2]/dev/null + } + } + +case checkdone + # we want at least one disk with both an mbr and a plan9 partition + mbrandplan9=0 + disks=`{ls /dev/sd*/plan9 >[2]/dev/null | sed 's!/dev/(sd..)/plan9!\1!'} + for(disk in $disks) { + if(hasmbr /dev/$disk/data) + mbrandplan9=1 + } + if(~ $mbrandplan9 0){ + partdisk=notdone + export partdisk + } +} diff --git a/sys/lib/dist/pc/inst/prepdisk b/sys/lib/dist/pc/inst/prepdisk new file mode 100755 index 000000000..6ef4a92f8 --- /dev/null +++ b/sys/lib/dist/pc/inst/prepdisk @@ -0,0 +1,63 @@ +#!/bin/rc + +# desc: subdivide plan 9 disk partition +# prereq: partdisk + +fn autotype { + if(~ $fstype fossil) + echo -a 9fat -a nvram -a fossil -a swap + if(~ $fstype fossil+venti) + echo -a 9fat -a nvram -a arenas -a isect -a fossil -a swap # -a other +} + +switch($1) { +case checkready + if(! test -f /dev/sd*/plan9*){ + prepdisk=notdone + export prepdisk + } + +case go + echo 'The following Plan 9 disk partitions were found.' + echo + disks=(/dev/sd*/plan9*) + for (i in $disks){ + echo $i + echo q | disk/prep -r $i >[2]/dev/null + echo + } + if(~ $#disks 1) + default=(-d $disks) + if not + default=() + prompt $default 'Plan 9 partition to subdivide' $disks + disk=$rd + + echo 'This is disk/prep; use it to subdivide the Plan 9 partition.' + echo 'If it is not yet subdivided, a sensible layout will be suggested;' + echo 'you can probably just type ''w'' and then ''q''.' + echo + disk/prep `{autotype} $disk + disk/prep -p $disk >`{basename -d $disk}^/ctl >[2]/dev/null + +case checkdone + if(! test -f /dev/sd*/9fat) + prepdisk=ready + + if(! ~ $prepdisk ready){ + prepdisk=done + switch($fstype){ + case fossil + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*) + prepdisk=ready + case fossil+venti + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*) + prepdisk=ready + if(! test -f /dev/sd*/arenas && ! test -f /dev/fs/arenas*) + prepdisk=ready + if(! test -f /dev/sd*/isect && ! test -f /dev/fs/isect*) + prepdisk=ready + } + } + export prepdisk +} diff --git a/sys/lib/dist/pc/inst/replcfg b/sys/lib/dist/pc/inst/replcfg new file mode 100755 index 000000000..30aed8607 --- /dev/null +++ b/sys/lib/dist/pc/inst/replcfg @@ -0,0 +1,18 @@ +#!/bin/rc + +s=/n/dist/dist/replica +serverroot=/n/dist +serverlog=$s/plan9.log +serverproto=$s/plan9.proto +fn servermount { status='' } +fn serverupdate { status='' } + +fn clientmount { status='' } +c=/n/newfs/dist/replica +clientroot=/n/newfs +clientproto=$c/plan9.proto +clientdb=$c/client/plan9.db +clientexclude=(dist/replica/client) +clientlog=$c/client/plan9.log + +applyopt=(-t -u -T$c/client/plan9.time) diff --git a/sys/lib/dist/pc/inst/startether b/sys/lib/dist/pc/inst/startether new file mode 100755 index 000000000..077504c1a --- /dev/null +++ b/sys/lib/dist/pc/inst/startether @@ -0,0 +1,30 @@ +#!/bin/rc + +# desc: activate ethernet card +# prereq: configether + +switch($1) { +case checkready + if(isipdevup /net/ether0) { + startether=done + export startether + } + +case go + if(isipdevup /net/ether0) + exit + + log starting ethernet $ethermethod config + switch($ethermethod) { + case manual + ip/ipconfig -g $gwaddr ether /net/ether0 $ipaddr $ipmask >>[2]/srv/log + case dhcp + ip/ipconfig $dhcphost -D >>/srv/log >[2=1] + } + +case checkdone + if(! isipdevup /net/ether0) { + startether=notdone + export startether + } +} diff --git a/sys/lib/dist/pc/inst/startppp b/sys/lib/dist/pc/inst/startppp new file mode 100755 index 000000000..02bc090ef --- /dev/null +++ b/sys/lib/dist/pc/inst/startppp @@ -0,0 +1,30 @@ +#!/bin/rc + +# desc: activate ppp connection +# prereq: configppp + +switch($1) { +case checkready checkdone + if (isipdevup '^pkt[0-9]') + startppp=done + export startppp + +case go + if(isipdevup '^pkt[0-9]') + exit + + ctl=$pppdev^ctl + echo b115200 >$ctl + + switch($pppmethod) { + case manual + echo + echo 'Please dial the modem, and type ctl-d when PPP has started.' + echo 'You may need to type ctl-m to send modem commands.' + echo + ip/ppp -f -u -b b^$pppbaud -p /dev/^$pppdev + + case auto + ip/ppp -f -b b^$pppbaud -p /dev/^$pppdev -s $"pppuser:$"ppppasswd -t 'atdt'^$"pppphone + } +} diff --git a/sys/lib/dist/pc/inst/startwin b/sys/lib/dist/pc/inst/startwin new file mode 100755 index 000000000..bcd542890 --- /dev/null +++ b/sys/lib/dist/pc/inst/startwin @@ -0,0 +1,46 @@ +#!/bin/rc + +fn time { date | sed 's/.........$//'} + +rm -f /srv/log + +if(~ $#* 2) { + wid=$1 + ht=$2 +} +if not { + scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) + wid=$scr(7) + ht=$scr(8) +} + +if(test $ht -gt 800) + ht=800 + +if(test $wid -gt 800) + wid=800 + +statwid=`{hoc -e $wid^'*.2'} +if(test $statwid -lt 180) + statwid=180 +if(test $statwid -gt 300) + statwid=300 + +logwid=`{hoc -e $wid^-$statwid} +if(test $logwid -gt 1000) + logwid=1000 + +loght=`{hoc -e $ht^'*.25'} +if(test $loght -lt 130) + loght=130 + +textht=`{hoc -e $ht^-$loght} + +window 0,$textht,$statwid,$ht stats -lmisce +window $statwid,$textht,^`{hoc -e $logwid+$statwid}^,$ht tailfsrv +window 0,0,^`{hoc -e $logwid+$statwid}^,$textht inst/mainloop + +while(! test -f /srv/log) + sleep 1 + +log `{time} Installation process started diff --git a/sys/lib/dist/pc/inst/stop b/sys/lib/dist/pc/inst/stop new file mode 100755 index 000000000..a1d48694f --- /dev/null +++ b/sys/lib/dist/pc/inst/stop @@ -0,0 +1,50 @@ +#!/bin/rc + +# desc: save the current installation state, to be resumed later +# prereq: +# mustdo: + +switch($1) { +case checkdone + stop=notdone + export stop + +case checkready + if(~ $cdboot yes){ + stop=notdone + export stop + } + +case go + coherence + switch($2){ + case finished + echo 'We need to write the state of the current installation to the install floppy,' + echo 'so that you can pick up from here if, for example, you want to set up' + echo 'more boot methods.' + echo + case * + echo 'We need to write the state of the current installation to the install floppy.' + echo 'so that you can pick up from here when you wish to continue.' + echo + } + echo -n 'Please make sure the install floppy is in the floppy drive and press enter.' + read >/dev/null >[2]/dev/null + + if(! a:) { + echo 'Couldn''t mount the floppy disk; sorry.' + exit + } + + if(cp /tmp/vars /n/a:/9inst.cnf || cp /tmp/vars /n/a:/9inst.cnf) { + echo 'Your install state has been saved to the install floppy.' + if(~ $2 finished){ + echo + echo 'Congratulations; you''ve completed the install.' + } + echo + halt + } + + echo 'Couldn''t save the state to your install floppy. Sorry.' +} diff --git a/sys/lib/dist/pc/inst/stopether b/sys/lib/dist/pc/inst/stopether new file mode 100755 index 000000000..59063f0e0 --- /dev/null +++ b/sys/lib/dist/pc/inst/stopether @@ -0,0 +1,20 @@ +#!/bin/rc + +# desc: shut down the ethernet connection +# prereq: + + +switch($1) { +case checkready + if(! isipdevup /net/ether0) { + stopether=notdone + export stopether + } + +case go + ip/ipconfig ether /net/ether0 unbind + +case checkdone + stopether=notdone + export stopether +} diff --git a/sys/lib/dist/pc/inst/stopppp b/sys/lib/dist/pc/inst/stopppp new file mode 100755 index 000000000..70b9ce1fe --- /dev/null +++ b/sys/lib/dist/pc/inst/stopppp @@ -0,0 +1,19 @@ +#!/bin/rc + +# desc: shut down the ppp connection +# prereq: + +switch($1) { +case checkready + if(! ~ $#pppdev 1 || ! isipdevup '^pkt[0-9]') { + stopppp=notdone + export stopppp + } + +case go + kill ppp | rc + +case checkdone + stopppp=notdone + export stopppp +} diff --git a/sys/lib/dist/pc/inst/textonly b/sys/lib/dist/pc/inst/textonly new file mode 100755 index 000000000..1c3922ce4 --- /dev/null +++ b/sys/lib/dist/pc/inst/textonly @@ -0,0 +1,15 @@ +#!/bin/rc + +# text-only install +cd /bin/inst +. defs + +textinst=1 +export textinst + +tailfsrv & +while(! test -f /srv/log) + sleep 1 +log `{date} Installation process started +inst/mainloop + diff --git a/sys/lib/dist/pc/inst/watchfd b/sys/lib/dist/pc/inst/watchfd new file mode 100755 index 000000000..ca37294e3 --- /dev/null +++ b/sys/lib/dist/pc/inst/watchfd @@ -0,0 +1,17 @@ +#!/bin/rc + +p=`{ps | grep $1 | sed 's/[^ ]* +([^ ]+) .*/\1/' } +while(! ~ $#p 1) { + sleep 1 + p=`{ps | grep $1 | sed 's/[^ ]* +([^ ]+) .*/\1/'} +} +p=$p(1) + +baropt='-w 145,129,445,168' +if(~ $textinst 1) + baropt=-t + +{ + while(test -f /proc/$p/fd) + grep '^ *'^$2^' ' /proc/$p/fd >[2]/dev/null +} | awk '{print $9 " '^$3^'"; fflush("/dev/stdout")}' | bargraph $baropt $4 diff --git a/sys/lib/dist/pc/inst/xxx b/sys/lib/dist/pc/inst/xxx new file mode 100755 index 000000000..56b4eb23a --- /dev/null +++ b/sys/lib/dist/pc/inst/xxx @@ -0,0 +1,9 @@ +#!/bin/rc + +ip/ipconfig +echo ' auth=204.178.31.3 + authdom=cs.bell-labs.com' >>/net/ndb +ndb/cs +auth/factotum +bind -a /bin/auth / +cpu -e clear -h tcp!204.178.31.2 diff --git a/sys/lib/dist/pc/mkfile b/sys/lib/dist/pc/mkfile new file mode 100755 index 000000000..43ee0b751 --- /dev/null +++ b/sys/lib/dist/pc/mkfile @@ -0,0 +1,100 @@ +out=outside # outside web server +s=/sys/lib/dist/pc +x=`{bind -b /sys/lib/dist/bin/$cputype /bin} +default:V: ndisk + ls -l ndisk + +SUB=`{ls sub inst} +boot.raw:Q: proto $SUB + rm -rf boot + mkdir boot + bind /dev/null /sys/log/timesync + # make files writable for now. + cat proto | sed 's!d000!d775!;s!000!664!;s!555!775!;s!444!664!' >proto.cp + disk/mkfs -a proto.cp | disk/mkext -d boot + @{ + cd boot/386 + strip init + cd bin + strip * */* >[2]/dev/null || status='' + } + cat proto | sed 's!/.*!!' >proto.cp + disk/mkfs -a -s boot proto.cp | tee >{wc -c >[1=2]} | + touchfs 1000000000 >boot.raw + +boot.bz2:Q: boot.raw + ls -l boot.raw + bflz -n 32 < boot.raw >boot.bflz + ls -l boot.bflz + bzip2 -9 < boot.bflz >$target + ls -l $target + +root.bz2:Q: boot.bz2 + { + echo bzfilesystem + cat boot.bz2 + dd -if /dev/zero -bs 1024 -count 1 >[2]/dev/null + } >$target + ls -l $target + +/sys/src/9/pc/9pcflop.gz: root.bz2 + @{ + rfork n + cd /sys/src/9/pc + mk 'CONF=pcflop' 9pcflop.gz + } + +/sys/src/9/pc/9pccd.gz: + @{ + cd /sys/src/9/pc + mk 'CONF=pccd' 9pccd.gz + } + +# disk/format apparently uses stat to obtain a file's real name, so +# binding 9loadusb onto 9load will store the name 9loadusb in the +# generated fat filesystem. the same is true for plan9.ini.cd and plan9.ini. + +9load: /386/9loadlite +# cp $prereq $target + if (test -e /386/9loadnousb) + cp /386/9loadnousb $target # cater to old bioses + cp /386/9loadlitedebug 9loaddebug + +ndisk: 9load /sys/src/9/pc/9pcflop.gz plan9.ini /lib/vgadb + dd -if /dev/zero -of ndisk -bs 1024 -count 1440 >[2]/dev/null + disk/format -f -b /386/pbs -d ndisk \ + 9load /sys/src/9/pc/9pcflop.gz plan9.ini /lib/vgadb + ls -l ndisk + +# cannot list both 9pcflop.gz and 9pccd.gz because they cannot be built +# in parallel. stupid mk +cddisk:DV: 9load /sys/src/9/pc/9pcflop.gz plan9.ini.cd /lib/vgadb + mk -a /sys/src/9/pc/9pccd.gz + mk -a /sys/src/9/pc/9pcflop.gz + rfork n + cp -x plan9.ini.cd subst/plan9.ini + dd -if /dev/zero -of cddisk -bs 1024 -count 2880 >[2]/dev/null + disk/format -t 3½QD -f -b /386/pbs -d cddisk \ + 9load /sys/src/9/pc/^(9pcflop.gz 9pccd.gz) \ + subst/plan9.ini /lib/vgadb + ls -l cddisk + +clean:V: + if (! unmount 9load >[2]/dev/null) + ; + rm -rf boot boot.bz2 boot.bflz boot.raw root.bz2 9pcflop ndisk 9load cddisk proto.cp 9loaddebug + +install:V: ndisk 9loaddebug + 9fs $out + dst=/n/$out/sys/lib/dist/web.protect + cp 9loaddebug $dst + gzip -9 < ndisk > $dst/plan9.flp.gz + # mk clean + +test:V: ndisk 9loaddebug + cp 9loaddebug ../web.protect2/n9loaddebug + cp ndisk ../web.protect2/ndisk + +cd0:D: cddisk + rm -f cd0 + disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s . -p cd0.proto -b cddisk cd0 diff --git a/sys/lib/dist/pc/plan9.ini b/sys/lib/dist/pc/plan9.ini new file mode 100755 index 000000000..71f98e5e1 --- /dev/null +++ b/sys/lib/dist/pc/plan9.ini @@ -0,0 +1,37 @@ +# config for initial floppy booting + +[menu] +menuitem=boot, Boot Plan 9 +# menuitem=debug, Boot Plan 9 and debug 9load +menudefault=boot, 10 + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +distname=plan9 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +nobootprompt=local!/boot/bzroot +installurl=http://plan9.bell-labs.com/plan9/download/plan9.iso.bz2 +# serial console on COM1 +#console=0 + +[boot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist/pc/plan9.ini.blank b/sys/lib/dist/pc/plan9.ini.blank new file mode 100755 index 000000000..be51a5dd4 --- /dev/null +++ b/sys/lib/dist/pc/plan9.ini.blank @@ -0,0 +1,10 @@ +THIS IS A 512 byte BLANK PLAN9.INI + + + + + + + + + diff --git a/sys/lib/dist/pc/plan9.ini.cd b/sys/lib/dist/pc/plan9.ini.cd new file mode 100755 index 000000000..11a2435ca --- /dev/null +++ b/sys/lib/dist/pc/plan9.ini.cd @@ -0,0 +1,40 @@ +# config for initial cd booting + +[menu] +menuitem=install, Install Plan 9 from this CD +menuitem=cdboot, Boot Plan 9 from this CD +# menuitem=debug, Boot Plan 9 from this CD and debug 9load + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +adisk=/dev/sdD0/cdboot +cdboot=yes +# console=0 +# baud=9600 + +[install] +nobootprompt=local!/boot/bzroot +bootfile=sdD0!cdboot!9pcflop.gz + +[cdboot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist/pc/plan9.ini.vmware b/sys/lib/dist/pc/plan9.ini.vmware new file mode 100755 index 000000000..dfee230ad --- /dev/null +++ b/sys/lib/dist/pc/plan9.ini.vmware @@ -0,0 +1,20 @@ +# config for initial vmware booting + +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +# *nodumpstack=1 + +partition=new +nobootprompt=local!/boot/bzroot +bootfile=fd0!9pcflop.gz + +mouseport=ps2 +monitor=xga +vgasize=1024x768x16 +#adisk=/dev/sdD0/cdboot +console=0 +baud=9600 diff --git a/sys/lib/dist/pc/proto b/sys/lib/dist/pc/proto new file mode 100755 index 000000000..a12695d44 --- /dev/null +++ b/sys/lib/dist/pc/proto @@ -0,0 +1,175 @@ +386 d775 sys sys +# 9load 555 sys sys + init 555 sys sys +# ld.com 555 sys sys + mbr 555 sys sys + pbs 555 sys sys + pbslba 555 sys sys + bin d775 sys sys + auth d555 sys sys +# i think factotum is only needed if we include cpu +# factotum 555 sys sys + aux d555 sys sys + isvmware 555 sys sys + mouse 555 sys sys /sys/lib/dist/pc/multi/mouse + pcmcia 555 sys sys /sys/lib/dist/pc/multi/pcmcia + # stub 555 sys sys + vga 555 sys sys /sys/lib/dist/pc/multi/vga + vmware 555 sys sys /sys/lib/dist/pc/sub/vmware + # vmware 555 sys sys + # vmwarefs 555 sys sys + # vmmousepoll 555 sys sys + zerotrunc 555 sys sys /sys/lib/dist/pc/multi/zerotrunc + disk d555 sys sys + fdisk 555 sys sys /sys/lib/dist/pc/multi/fdisk + format 555 sys sys /sys/lib/dist/pc/multi/format +# kfs 555 sys sys +# kfscmd 555 sys sys + mbr 555 sys sys /sys/lib/dist/pc/multi/mbr + prep 555 sys sys /sys/lib/dist/pc/multi/prep + fossil d555 sys sys + fossil 555 sys sys + flfmt 555 sys sys + conf 555 sys sys + ip d555 sys sys + ipconfig 555 sys sys /sys/lib/dist/pc/multi/ipconfig + ppp 555 sys sys /sys/lib/dist/pc/multi/ppp + ndb d555 sys sys +# csquery and dnsquery could go + cs 555 sys sys /sys/lib/dist/pc/multi/cs +# csquery 555 sys sys + dns 555 sys sys /sys/lib/dist/pc/multi/dns +# dnsquery 555 sys sys + replica d555 sys sys + applylog 555 sys sys + changes 555 sys sys + compactdb 555 sys sys /sys/lib/dist/pc/sub/compactdb + pull 555 sys sys + venti d555 sys sys +# venti 555 sys sys +# conf 555 sys sys +# fmtarenas 555 sys sys +# fmtindex 555 sys sys +# fmtisect 555 sys sys + 9660srv 555 sys sys /sys/lib/dist/pc/multi/9660srv +# acme could go +# acme 555 sys sys + awk 555 sys sys + bargraph 555 sys sys /sys/lib/dist/bin/386/bargraph + basename 555 sys sys /sys/lib/dist/pc/multi/basename + cat 555 sys sys /sys/lib/dist/pc/multi/cat + chgrp 555 sys sys /sys/lib/dist/pc/multi/chgrp + chmod 555 sys sys /sys/lib/dist/pc/multi/chmod + cleanname 555 sys sys /sys/lib/dist/pc/multi/cleanname + cmp 555 sys sys /sys/lib/dist/pc/multi/cmp + cdsh 555 sys sys /sys/lib/dist/bin/386/cdsh + cp 555 sys sys /sys/lib/dist/pc/multi/cp +# cpu could go +# cpu 555 sys sys + date 555 sys sys /sys/lib/dist/pc/multi/date + dd 555 sys sys /sys/lib/dist/pc/multi/dd + dossrv 555 sys sys /sys/lib/dist/pc/multi/dossrv + echo 555 sys sys /sys/lib/dist/pc/multi/echo + ed 555 sys sys /sys/lib/dist/pc/multi/ed +# if cpu goes, exportfs could go +# exportfs 555 sys sys + ext2srv 555 sys sys /sys/lib/dist/pc/multi/ext2srv + fcp 555 sys sys + grep 555 sys sys /sys/lib/dist/pc/multi/grep + hget 555 sys sys /sys/lib/dist/pc/multi/hget + hoc 555 sys sys /sys/lib/dist/pc/multi/hoc + ls 555 sys sys /sys/lib/dist/pc/multi/ls + mc 555 sys sys /sys/lib/dist/pc/multi/mc + mount 555 sys sys /sys/lib/dist/pc/multi/mount + multi 555 sys sys /sys/lib/dist/bin/386/multi + mv 555 sys sys /sys/lib/dist/pc/multi/mv +# netkey 555 sys sys + ps 555 sys sys /sys/lib/dist/pc/multi/ps + rc 555 sys sys + read 555 sys sys /sys/lib/dist/pc/multi/read + rio 555 sys sys + rm 555 sys sys /sys/lib/dist/pc/multi/rm + sed 555 sys sys /sys/lib/dist/pc/multi/sed +# snoopy could go +# snoopy 555 sys sys + sort 555 sys sys /sys/lib/dist/pc/multi/sort + srv 555 sys sys /sys/lib/dist/pc/multi/srv +# ssh 555 sys sys + stats 555 sys sys + syscall 555 sys sys /sys/lib/dist/pc/multi/syscall + tail 555 sys sys /sys/lib/dist/pc/multi/tail + tailfsrv 555 sys sys /sys/lib/dist/bin/386/tailfsrv + tee 555 sys sys /sys/lib/dist/pc/multi/tee +# telnet 555 sys sys + test 555 sys sys /sys/lib/dist/pc/multi/test + wc 555 sys sys /sys/lib/dist/pc/multi/wc + xd 555 sys sys /sys/lib/dist/pc/multi/xd +adm d555 adm adm + timezone d555 sys sys + local 555 sys sys +lib d777 sys sys + font d555 sys sys + bit d555 sys sys + lucidasans d555 sys sys + lstr.12 444 sys sys + typelatin1.7.font 444 sys sys +# lucm d555 sys sys +# latin1.9 444 sys sys +# latin1.9.font 444 sys sys + namespace 444 sys sys + ndb d555 sys sys + common 444 sys sys /sys/lib/dist/pc/sub/common + local 444 sys sys /sys/lib/dist/pc/sub/local + vgadb 666 sys sys /dev/null +fd d555 sys sys +mnt d777 sys sys + arch d000 sys sys + temp d000 sys sys + vmware d000 sys sys + wsys d000 sys sys +n d777 sys sys + a: d000 sys sys + a d000 sys sys + c: d000 sys sys + c d000 sys sys + 9fat d000 sys sys + kremvax d000 sys sys /sys/lib/dist/pc/empty + newfs d000 sys sys + dist d000 sys sys /sys/lib/dist/pc/empty + distmedia d000 sys sys /sys/lib/dist/pc/empty +rc d555 sys sys + bin d775 sys sys + inst d775 sys sys /sys/lib/dist/pc/empty + + - sys sys /sys/lib/dist/pc/inst + 9fat: 555 sys sys + a: 555 sys sys /sys/lib/dist/pc/sub/a: + bind 555 sys sys /sys/lib/dist/pc/sub/bind + boota: 555 sys sys /sys/lib/dist/pc/sub/boota: + bunzip2 555 sys sys /sys/lib/dist/pc/sub/bunzip2 + c: 555 sys sys + dosmnt 555 sys sys + kill 555 sys sys + lc 555 sys sys + mkdir 555 sys sys /sys/lib/dist/pc/sub/mkdir + pci 555 sys sys + pwd 555 sys sys /sys/lib/dist/pc/sub/pwd + ramfs 555 sys sys /sys/lib/dist/pc/sub/ramfs + replica d555 sys sys + changes 555 sys sys + defs 555 sys sys + pull 555 sys sys + slay 555 sys sys + sleep 555 sys sys /sys/lib/dist/pc/sub/sleep + termrc 555 sys sys /sys/lib/dist/pc/sub/termrc + unmount 555 sys sys /sys/lib/dist/pc/sub/unmount + window 555 sys sys + lib d555 sys sys + rcmain 444 sys sys +sys d555 sys sys + log d555 sys sys + dns 444 sys sys /sys/lib/dist/pc/emptyfile + timesync 444 sys sys /sys/lib/dist/pc/emptyfile +tmp d555 sys sys +usr d555 sys sys + glenda d775 glenda glenda + + - glenda glenda /sys/lib/dist/pc/glenda diff --git a/sys/lib/dist/pc/sub/D003753 b/sys/lib/dist/pc/sub/D003753 new file mode 100755 index 000000000..8624d6ea1 --- /dev/null +++ b/sys/lib/dist/pc/sub/D003753 @@ -0,0 +1,22 @@ +#!/bin/rc +if(! test -f /srv/dos) + dossrv >/dev/null </dev/null >[2]/dev/null +unmount /n/a:>[2]/dev/null + +if(~ $#adisk 1) + ; # do nothing +if not if(~ $#bootfile 0) + adisk=/dev/fd0disk +if not { + switch($bootfile) { + case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'} + case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} + case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops + } +} + +mount -c /srv/dos /n/a: $adisk diff --git a/sys/lib/dist/pc/sub/F004116 b/sys/lib/dist/pc/sub/F004116 new file mode 100755 index 000000000..5f6809b3b --- /dev/null +++ b/sys/lib/dist/pc/sub/F004116 @@ -0,0 +1,24 @@ +#!/bin/rc + +rfork e +if(! test -f /srv/dos) + dossrv >/dev/null </dev/null >[2]/dev/null +unmount /n/a:>[2]/dev/null + +switch($bootfile) { +case sd*!cdboot!* + # just look for the right file. bootfile isn''t trustworthy + adisk=/dev/sd*/cdboot + if(! ~ $#adisk 1) + adisk=$adisk(1) +case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/dos#'} +case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} +case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops +} + +mount -c /srv/dos /n/a: $adisk + diff --git a/sys/lib/dist/pc/sub/bind b/sys/lib/dist/pc/sub/bind new file mode 100755 index 000000000..bc01455d7 --- /dev/null +++ b/sys/lib/dist/pc/sub/bind @@ -0,0 +1,21 @@ +#!/bin/rc + +rfork e +flag=0 +while(~ $1 -*){ + switch($1){ + case -b + flag=1 + case -a + flag=2 + case -c + flag=4 + case -ac -ca + flag=6 + case -bc -cb + flag=5 + } + shift +} + +syscall bind $1 $2 $flag >[2]/dev/null diff --git a/sys/lib/dist/pc/sub/bunzip2 b/sys/lib/dist/pc/sub/bunzip2 new file mode 100755 index 000000000..0a876c6c2 --- /dev/null +++ b/sys/lib/dist/pc/sub/bunzip2 @@ -0,0 +1,4 @@ +#!/bin/rc + +exec /boot/kfs BUNZIP +# kfs is bzfs
\ No newline at end of file diff --git a/sys/lib/dist/pc/sub/common b/sys/lib/dist/pc/sub/common new file mode 100755 index 000000000..ec3e1bca2 --- /dev/null +++ b/sys/lib/dist/pc/sub/common @@ -0,0 +1,123 @@ +# +# services +# +tcp=cs port=1 +tcp=echo port=7 +tcp=discard port=9 +tcp=systat port=11 +tcp=daytime port=13 +tcp=netstat port=15 +tcp=chargen port=19 +tcp=ftp-data port=20 +tcp=ftp port=21 +tcp=ssh port=22 +tcp=telnet port=23 +tcp=smtp port=25 +tcp=time port=37 +tcp=whois port=43 +tcp=domain port=53 +tcp=uucp port=64 +tcp=gopher port=70 +tcp=rje port=77 +tcp=finger port=79 +tcp=http port=80 +tcp=link port=87 +tcp=supdup port=95 +tcp=hostnames port=101 +tcp=iso-tsap port=102 +tcp=x400 port=103 +tcp=x400-snd port=104 +tcp=csnet-ns port=105 +tcp=pop-2 port=109 +tcp=pop3 port=110 +tcp=sunrpc port=111 +tcp=uucp-path port=117 +tcp=nntp port=119 +tcp=netbios port=139 +tcp=NeWS port=144 +tcp=print-srv port=170 +tcp=z39.50 port=210 +tcp=fsb port=400 +tcp=sysmon port=401 +tcp=proxy port=402 +tcp=proxyd port=404 +tcp=https port=443 +tcp=ssmtp port=465 +tcp=snntp port=563 +tcp=rexec port=512 restricted= +tcp=login port=513 restricted= +tcp=shell port=514 restricted= +tcp=printer port=515 +tcp=courier port=530 +tcp=cscan port=531 +tcp=uucp port=540 +tcp=9fs port=564 +tcp=whoami port=565 +tcp=guard port=566 +tcp=ticket port=567 +tcp=fmclient port=729 +tcp=ingreslock port=1524 +tcp=webster port=2627 +tcp=weather port=3000 +tcp=Xdisplay port=6000 +tcp=styx port=6666 +tcp=mpeg port=6667 +tcp=rstyx port=6668 +tcp=infdb port=6669 +tcp=infsigner port=6671 +tcp=infcsigner port=6672 +tcp=inflogin port=6673 +tcp=bandt port=7330 +tcp=face port=32000 +tcp=ocpu port=17005 +tcp=ocpunote port=17006 +tcp=exportfs port=17007 +tcp=rexexec port=17009 +tcp=ncpu port=17010 +tcp=ncpunote port=17011 +tcp=cpu port=17013 +tcp=video port=17028 +tcp=vgen port=17029 +tcp=alefnslook port=17030 +tcp=411 port=17031 +tcp=flyboy port=17032 + +il=echo port=7 +il=discard port=9 +il=chargen port=19 +il=whoami port=565 +il=ticket port=566 +il=challbox port=567 +il=ocpu port=17005 +il=ocpunote port=17006 +il=exportfs port=17007 +il=9fs port=17008 +il=rexexec port=17009 +il=ncpu port=17010 +il=ncpunote port=17011 +il=tcpu port=17012 +il=cpu port=17013 +il=fsauth port=17020 +il=rexauth port=17021 +il=changekey port=17022 +il=chal port=17023 +il=check port=17024 +il=juke port=17026 +il=video port=17028 +il=vgen port=17029 +il=alefnslook port=17030 +il=ramfs port=17031 + +udp=echo port=7 +udp=tacacs port=49 +udp=tftp port=69 +udp=bootpc port=68 +udp=bootp port=67 +udp=dns port=53 +udp=ntp port=123 +udp=rip port=520 +udp=bfs port=2201 +udp=virgil port=2202 +udp=bandt2 port=7331 + +gre=ppp port=34827 diff --git a/sys/lib/dist/pc/sub/compactdb b/sys/lib/dist/pc/sub/compactdb new file mode 100755 index 000000000..6033f7a0a --- /dev/null +++ b/sys/lib/dist/pc/sub/compactdb @@ -0,0 +1,4 @@ +#!/bin/rc + +exec cat $* + diff --git a/sys/lib/dist/pc/sub/local b/sys/lib/dist/pc/sub/local new file mode 100755 index 000000000..ec278a401 --- /dev/null +++ b/sys/lib/dist/pc/sub/local @@ -0,0 +1,8 @@ + +# +# files comprising the database, use as many as you like +# +database= + file=/lib/ndb/local + file=/lib/ndb/common + diff --git a/sys/lib/dist/pc/sub/mkdir b/sys/lib/dist/pc/sub/mkdir new file mode 100755 index 000000000..b4452b9a9 --- /dev/null +++ b/sys/lib/dist/pc/sub/mkdir @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall create $1 0 020000000775 >[2]/dev/null diff --git a/sys/lib/dist/pc/sub/ndist b/sys/lib/dist/pc/sub/ndist new file mode 100755 index 000000000..2916986a1 --- /dev/null +++ b/sys/lib/dist/pc/sub/ndist @@ -0,0 +1,16 @@ +#!/bin/rc + +s=/n/dist/dist/replica +serverroot=/n/dist +serverlog=$s/plan9.log +serverproto=$s/plan9.proto +fn servermount { status='' } +fn serverupdate { status='' } + +fn clientmount { status='' } +c=/n/kfs/dist/replica +clientroot=/n/kfs +clientproto=$c/plan9.proto +clientdb=$c/client/plan9.db +clientexclude=(dist/replica/client) +clientlog=$c/client/plan9.log diff --git a/sys/lib/dist/pc/sub/pci b/sys/lib/dist/pc/sub/pci new file mode 100755 index 000000000..c55d4b397 --- /dev/null +++ b/sys/lib/dist/pc/sub/pci @@ -0,0 +1,5 @@ +#!/bin/rc + +rfork n +bind '#$' /mnt +cat /mnt/pci/*ctl diff --git a/sys/lib/dist/pc/sub/pwd b/sys/lib/dist/pc/sub/pwd new file mode 100755 index 000000000..f75568e7c --- /dev/null +++ b/sys/lib/dist/pc/sub/pwd @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall -o fd2path 0 buf 1024 < . >[2]/dev/null diff --git a/sys/lib/dist/pc/sub/ramfs b/sys/lib/dist/pc/sub/ramfs new file mode 100755 index 000000000..285cd8717 --- /dev/null +++ b/sys/lib/dist/pc/sub/ramfs @@ -0,0 +1,4 @@ +#!/bin/rc + +exec boot/kfs RAMFS $* +# kfs is bzfs diff --git a/sys/lib/dist/pc/sub/sleep b/sys/lib/dist/pc/sub/sleep new file mode 100755 index 000000000..07e6bb8be --- /dev/null +++ b/sys/lib/dist/pc/sub/sleep @@ -0,0 +1,8 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: sleep n' >[1=2] + exit usage +} + +syscall sleep $1^000 >/dev/null >[2]/dev/null diff --git a/sys/lib/dist/pc/sub/termrc b/sys/lib/dist/pc/sub/termrc new file mode 100755 index 000000000..a194ee9b0 --- /dev/null +++ b/sys/lib/dist/pc/sub/termrc @@ -0,0 +1,121 @@ +#!/bin/rc + +if(~ $#debug 1 && ~ $debug yes) + flag x + +if not + debug=0 + +if(~ $debug yes) echo env... +sysname=gnot +font=/lib/font/bit/lucidasans/typelatin1.7.font + +for (i in '#P' '#f' '#m' '#t' '#v') { + if(~ $debug yes) echo bind $i + bind -a $i /dev >/dev/null >[2=1] +} +if(~ $debug yes) echo binddev done + +for(disk in /dev/sd??) { + if(test -f $disk/data && test -f $disk/ctl){ + disk/fdisk -p $disk/data >$disk/ctl >[2]/dev/null +# if(~ $#nosddma 0) +# echo dma on >$disk/ctl +# if(~ $#nosdrwm 0) +# echo rwm on >$disk/ctl + } +} + +for (i in /sys/log/*) { + if(~ $debug yes) echo bind $i + bind /dev/null $i +} + +if(~ $debug yes) echo bindlog done + +bind -a '#l' /net >/dev/null >[2=1] + +dossrv +boota: +boota: # again, just in case a timeout made the earlier one fail +cp /n/a:/plan9.ini /tmp/plan9.orig +if(! ~ $cdboot yes){ + pci >/n/a:/pci.txt >[2]/dev/null + cp /dev/kmesg /n/a:/boot.txt >[2]/dev/null +} + +# restore a partial install +if(test -f /n/a:/9inst.cnf) + cp /n/a:/9inst.cnf /tmp/vars + +# make vgadb easier to edit +if(test -f /n/a:/vgadb) + cp /n/a:/vgadb /lib/vgadb + +aux/vmware + +# configure loopback device without touching /net/ndb +{ + echo bind loopback /dev/null + echo add 127.0.0.1 255.255.255.0 +} >/net/ipifc/clone + +if(~ $#dmamode 0) + dmamode=ask +if(~ $dmamode ask){ + echo -n 'use DMA for ide drives[yes]: ' + dmamode=`{read} + if(~ $#dmamode 0) + dmamode=yes +} +if(~ $dmamode yes) + for(i in /dev/sd*/ctl) + if(test -f $i) + {echo dma on; echo rwm on >[2]/dev/null} >$i + +if(~ $installmode ask){ + echo -n 'install mode is (text, graphics)[graphics]: ' + installmode=`{read} + if(~ $#installmode 0) + installmode=graphics +} +if(~ $installmode text){ + mouseport=() + vgasize=() + monitor=() +} +if not + installmode=graphics + +if(~ $mouseport ask){ + echo -n 'mouseport is (ps2, ps2intellimouse, 0, 1, 2)[ps2]: ' + mouseport=`{read} + if(~ $#mouseport 0) + mouseport=ps2 +} +if(~ $vgasize ask){ + echo -n 'vgasize [640x480x8]: ' + vgasize=`{read} + if(~ $#vgasize 0) + vgasize=640x480x8 +} +if(~ $monitor ask){ + echo -n 'monitor is [xga]: ' + monitor=`{read} + if(~ $#monitor 0) + monitor=xga +} +if(~ $#mouseport 1) { + aux/mouse $mouseport + if(~ $#vgasize 1 && ! ~ $vgasize '') { + vgasize=`{echo $vgasize} + if(! ~ $cdboot yes) + aux/vga -vip $vgasize >/n/a:/vgainfo.txt + sleep 2 # wait for floppy to finish + aux/vga -l $vgasize + if(! ~ $#novgaaccel 0) + echo -n 'hwaccel off' >'#v/vgactl' >[2]/dev/null + if(! ~ $#novgablank 0) + echo -n 'hwblank off' >'#v/vgactl' >[2]/dev/null + } +} + diff --git a/sys/lib/dist/pc/sub/unmount b/sys/lib/dist/pc/sub/unmount new file mode 100755 index 000000000..0c736afa6 --- /dev/null +++ b/sys/lib/dist/pc/sub/unmount @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall unmount 0 $1 >[2]/dev/null diff --git a/sys/lib/dist/pc/sub/users b/sys/lib/dist/pc/sub/users new file mode 100755 index 000000000..fd2edbe3d --- /dev/null +++ b/sys/lib/dist/pc/sub/users @@ -0,0 +1,7 @@ +-1:adm:adm: +0:none:none: +1:tor:tor: +2:glenda:glenda: +10000:sys:: +10001:upas:upas: +10002:bootes:bootes: diff --git a/sys/lib/dist/pc/sub/vmware b/sys/lib/dist/pc/sub/vmware new file mode 100755 index 000000000..8b398c972 --- /dev/null +++ b/sys/lib/dist/pc/sub/vmware @@ -0,0 +1,10 @@ +#!/bin/rc +# vmware - if we're running in a vmware virtual machine, tweak set up +if(aux/isvmware -s){ + echo hwaccel off >'#v/vgactl' + echo -n off >'#P/i8253timerset' + for (ctl in '#S'/sd[C-H]?/ctl) + if (test -e $ctl && grep -s '^config .* dma ' $ctl && + ! grep -s '^config (848A|.* dma 00000000 )' $ctl) + echo 'dma on' >$ctl +} diff --git a/sys/lib/dist/pc/subst/plan9.ini b/sys/lib/dist/pc/subst/plan9.ini new file mode 100755 index 000000000..11a2435ca --- /dev/null +++ b/sys/lib/dist/pc/subst/plan9.ini @@ -0,0 +1,40 @@ +# config for initial cd booting + +[menu] +menuitem=install, Install Plan 9 from this CD +menuitem=cdboot, Boot Plan 9 from this CD +# menuitem=debug, Boot Plan 9 from this CD and debug 9load + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +adisk=/dev/sdD0/cdboot +cdboot=yes +# console=0 +# baud=9600 + +[install] +nobootprompt=local!/boot/bzroot +bootfile=sdD0!cdboot!9pcflop.gz + +[cdboot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist/setup b/sys/lib/dist/setup new file mode 100755 index 000000000..a1c381bd7 --- /dev/null +++ b/sys/lib/dist/setup @@ -0,0 +1,10 @@ +#!/bin/rc +# setup - prep for the mkfile +9fs sources +9fs other +9fs outfsother +if (test -e /cfg/$sysname/config) + . /cfg/$sysname/config +if not + outip=204.178.31.2 +import -c tcp!$outip!666 $dist/web.protect |