diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/src/9/pc/sdata.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/con.c | 11 | ||||
-rwxr-xr-x | sys/src/cmd/pkg/create | 21 | ||||
-rwxr-xr-x | sys/src/cmd/pkg/install | 12 | ||||
-rwxr-xr-x | sys/src/cmd/pkg/list | 3 | ||||
-rw-r--r-- | sys/src/cmd/pkg/mkfile | 20 | ||||
-rwxr-xr-x | sys/src/cmd/pkg/remove | 18 | ||||
-rw-r--r-- | sys/src/cmd/pkg/unpkg.c | 100 | ||||
-rw-r--r-- | sys/src/cmd/ramfs.c | 17 | ||||
-rw-r--r-- | sys/src/games/glendy.c | 530 | ||||
-rw-r--r-- | sys/src/games/mkfile | 1 |
11 files changed, 732 insertions, 2 deletions
diff --git a/sys/src/9/pc/sdata.c b/sys/src/9/pc/sdata.c index 438ee90ba..8f7ad76d3 100644 --- a/sys/src/9/pc/sdata.c +++ b/sys/src/9/pc/sdata.c @@ -2037,6 +2037,7 @@ atapnp(void) case (0x24CB<<16)|0x8086: /* 82801DB (ICH4, High-End) */ case (0x24DB<<16)|0x8086: /* 82801EB (ICH5) */ case (0x25A3<<16)|0x8086: /* 6300ESB (E7210) */ + case (0x2653<<16)|0x8086: /* 82801FBM SATA */ case (0x266F<<16)|0x8086: /* 82801FB (ICH6) */ case (0x27DF<<16)|0x8086: /* 82801G SATA (ICH7) */ case (0x27C0<<16)|0x8086: /* 82801GB SATA AHCI (ICH7) */ diff --git a/sys/src/cmd/cwfs/con.c b/sys/src/cmd/cwfs/con.c index 0a7aa2134..41fe43142 100644 --- a/sys/src/cmd/cwfs/con.c +++ b/sys/src/cmd/cwfs/con.c @@ -740,11 +740,22 @@ cmd_files(int, char *[]) print("%ld out of %ld files used\n", n, conf.nfile); } +void +cmd_chatty(int argc, char *argv[]) +{ + if(argc < 2) { + print("cmd_chatty: usage: chatty n\n"); + return; + } + chatty = atoi(argv[1]); +} + static void installcmds(void) { cmd_install("allow", "-- disable permission checking", cmd_allow); cmd_install("cfs", "[file] -- set current filesystem", cmd_cfs); + cmd_install("chatty", "n -- set chattiness", cmd_chatty); cmd_install("clean", "file [bno [addr]] -- block print/fix", cmd_clean); cmd_install("check", "[options]", cmd_check); cmd_install("clri", "[file ...] -- purge files/dirs", cmd_clri); diff --git a/sys/src/cmd/pkg/create b/sys/src/cmd/pkg/create new file mode 100755 index 000000000..ec350e731 --- /dev/null +++ b/sys/src/cmd/pkg/create @@ -0,0 +1,21 @@ +#!/bin/rc -e + +i=`{basename $1} +d=$1 +echo Creating $i +C=`{pwd} +@{ +rfork en +cd $d +mkdir /tmp/$i +mk +divergefs -p /tmp/$i / +mk install clean +unmount / +} +cd /tmp/$i/files +rm -r env +tar cv * | bzip2 -9 > $C/$i.tbz +cd /tmp +rm -r $i +echo Created $C/$i.tbz diff --git a/sys/src/cmd/pkg/install b/sys/src/cmd/pkg/install new file mode 100755 index 000000000..7bc228c8f --- /dev/null +++ b/sys/src/cmd/pkg/install @@ -0,0 +1,12 @@ +#!/bin/rc -e + +cd / +mkdir -p /sys/lib/pkg +if (test -s /sys/lib/pkg/$1) { + echo $i already installed + exit +} +echo Installing $1 +hget http://pkg.violetti.org/$cputype/$1.tbz | bunzip2 | pkg/unpkg>[2]/sys/lib/pkg/$1 +echo Done + diff --git a/sys/src/cmd/pkg/list b/sys/src/cmd/pkg/list new file mode 100755 index 000000000..419e47a52 --- /dev/null +++ b/sys/src/cmd/pkg/list @@ -0,0 +1,3 @@ +#!/bin/rc + +hget http://pkg.violetti.org/$cputype | htmlfmt | grep '\.tbz' | sed -e 's/\.tbz$//' diff --git a/sys/src/cmd/pkg/mkfile b/sys/src/cmd/pkg/mkfile new file mode 100644 index 000000000..eb206806e --- /dev/null +++ b/sys/src/cmd/pkg/mkfile @@ -0,0 +1,20 @@ +</$objtype/mkfile + +all: $O.unpkg + echo + +$O.unpkg: unpkg.c + $CC unpkg.c + $LD -o $O.unpkg unpkg.$O + +install:V: $O.unpkg + mkdir -p /$objtype/bin/pkg + cp $O.unpkg /$objtype/bin/pkg/unpkg + cp create install list remove /$objtype/bin/pkg + +clean: + rm -f $O.unpkg *.$O + +nuke: clean + rm -f /$objtype/bin/pkg/* + diff --git a/sys/src/cmd/pkg/remove b/sys/src/cmd/pkg/remove new file mode 100755 index 000000000..349d18410 --- /dev/null +++ b/sys/src/cmd/pkg/remove @@ -0,0 +1,18 @@ +#!/bin/rc -e + +cd / +if(test -s /sys/lib/pkg/$1) { + fs=(`{cat /sys/lib/pkg/$1 | awk '{print $1}'}) + ss=(`{cat /sys/lib/pkg/$1 | awk '{print $2}'}) + for(i in `{seq $#fs}) { + s=`{sha1sum $fs($i) | awk '{print $1}' | tr a-z A-Z} + if(test $s '=' $ss($i)) { + echo D $fs($i) + rm $fs($i) + } + if not { + echo M $fs($i) NOT DELETING + } + } + rm /sys/lib/pkg/$1 +} diff --git a/sys/src/cmd/pkg/unpkg.c b/sys/src/cmd/pkg/unpkg.c new file mode 100644 index 000000000..2c749e3b3 --- /dev/null +++ b/sys/src/cmd/pkg/unpkg.c @@ -0,0 +1,100 @@ +#include <u.h> +#include <libc.h> +#include <mp.h> +#include <libsec.h> + +struct th { + char *name; + ulong perm; + ulong size; + char type; + char *user, *group; +}; + +static char *sndup(char* s, ulong n) { + char *d, *p; + p = memchr(s, 0, n); + if(p) + n = p-s; + d = malloc(n+1); + memcpy(d,s,n); + d[n] = 0; + return d; +} + + +int readheader(int fd, struct th* th) { + int i; + char b[512]; + if(readn(fd, b, 512) != 512) return -1; + + // Check for end of archive + for(i=0; i<512; i++) { + if(b[i]!=0) goto rhok; + } + if(readn(fd, b, 512) != 512) return -1; + for(i=0; i<512; i++) { + if(b[i]!=0) return -1; + } + return 0; + + rhok: + th->name = sndup(b, 100); + th->perm = strtoul(b+100, nil, 8); + th->size = strtoul(b+124, nil, 8); + th->type = b[156]; + th->user = sndup(b+265, 32); + th->group= sndup(b+297, 32); + return 1; +} + +int main(void) { + while(1) { + struct th th; + ulong off; + uchar b[512]; + DigestState *s; + int wfd; + int r = readheader(0, &th); + if(r <= 0) return r; + + switch(th.type) { + case '5': + create(th.name, OREAD, DMDIR|th.perm); + break; + case '0': case 0: + print("A %s\n", th.name); + r = access(th.name, 0); + if(r == 0) { + print("File already exists: %s\n", th.name); + return -1; + } + if((wfd = create(th.name, OWRITE, th.perm)) < 0) { + print("Create failed: %s\n", th.name); + return -1; + } + s = nil; + for(off=0; off<th.size; off+=512) { + int n = th.size-off; + n = n<512 ? n : 512; + if(readn(0, b, 512) != 512) return -1; + if(write(wfd, b, n) != n) return -1; + s = sha1(b, n, nil, s); + } + + uchar digest[20], hdigest[41]; + sha1(nil, 0, digest, s); + enc16((char*)hdigest, 41, digest, 20); + fprint(2, "%s\t%s\n", th.name, hdigest); + close(wfd); + break; + default: + print("Unknown file type '%c'\n", th.type); + return -1; + } + + free(th.name); + free(th.user); + free(th.group); + } +} diff --git a/sys/src/cmd/ramfs.c b/sys/src/cmd/ramfs.c index 835a94bf9..534edc640 100644 --- a/sys/src/cmd/ramfs.c +++ b/sys/src/cmd/ramfs.c @@ -157,9 +157,11 @@ main(int argc, char *argv[]) int p[2]; int fd; int stdio = 0; + int mountflags; service = "ramfs"; defmnt = "/tmp"; + mountflags = 0; ARGBEGIN{ case 'i': defmnt = 0; @@ -186,9 +188,20 @@ main(int argc, char *argv[]) defmnt = 0; service = EARGF(usage()); break; + case 'b': + mountflags |= MBEFORE; + break; + case 'c': + mountflags |= MCREATE; + break; + case 'a': + mountflags |= MAFTER; + break; default: usage(); }ARGEND + if(mountflags == 0) + mountflags = MREPL | MCREATE; if(pipe(p) < 0) error("pipe failed"); @@ -239,7 +252,7 @@ main(int argc, char *argv[]) break; default: close(p[0]); /* don't deadlock if child fails */ - if(defmnt && mount(p[1], -1, defmnt, MREPL|MCREATE, "") < 0) + if(defmnt && mount(p[1], -1, defmnt, mountflags, "") < 0) error("mount failed"); } exits(0); @@ -902,6 +915,6 @@ estrdup(char *q) void usage(void) { - fprint(2, "usage: %s [-Dipsu] [-m mountpoint] [-S srvname]\n", argv0); + fprint(2, "usage: %s [-Dipsubac] [-m mountpoint] [-S srvname]\n", argv0); exits("usage"); } diff --git a/sys/src/games/glendy.c b/sys/src/games/glendy.c new file mode 100644 index 000000000..753bd0a55 --- /dev/null +++ b/sys/src/games/glendy.c @@ -0,0 +1,530 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <event.h> + +enum{ + /* difficulty levels (how many circles are initially occupied) */ + DEasy, /* 10≤x<15 */ + DMed, /* 5≤x<10 */ + DHard, /* 0≤x<5 */ + + /* dynamic? original game has a fixed grid size, but we don't need to abide by it */ + SzX = 11, + SzY = 11, + + Border = 10, + /* movement directions */ + NE, + E, + SE, + SW, + W, + NW, + + Won = 1, /* game-ending states */ + Lost = 2, +}; + +Font *font; + +int difficulty = DMed; +int finished; + +int grid[SzX][SzY]; +int ogrid[SzX][SzY]; /* so we can restart levels */ + +Image *gl; /* glenda */ +Image *glm; /* glenda's mask */ +Image *cc; /* clicked */ +Image *ec; /* empty; not clicked */ +Image *bg; +Image *lost; +Image *won; + + +char *mbuttons[] = +{ + "easy", + "medium", + "hard", + 0 +}; + +char *rbuttons[] = +{ + "new", + "reset", + "exit", + 0 +}; + +Menu mmenu = +{ + mbuttons, +}; + +Menu rmenu = +{ + rbuttons, +}; + +Image * +eallocimage(Rectangle r, int repl, uint color) +{ + Image *tmp; + + tmp = allocimage(display, r, screen->chan, repl, color); + if(tmp == nil) + sysfatal("cannot allocate buffer image: %r"); + + return tmp; +} + +Image * +eloadfile(char *path) +{ + Image *img; + int fd; + + fd = open(path, OREAD); + if(fd < 0) { + fprint(2, "cannot open image file %s: %r\n", path); + exits("image"); + } + img = readimage(display, fd, 0); + if(img == nil) + sysfatal("cannot load image: %r"); + close(fd); + + return img; +} + + +void +allocimages(void) +{ + Rectangle one = Rect(0, 0, 1, 1); + + cc = eallocimage(one, 1, 0x777777FF); + ec = eallocimage(one, 1, DPalegreen); + bg = eallocimage(one, 1, DPurpleblue); + lost = eallocimage(one, 1, DRed); + won = eallocimage(one, 1, DGreen); + gl = eloadfile("/lib/face/48x48x4/g/glenda.1"); + + glm = allocimage(display, Rect(0, 0, 48, 48), gl->chan, 1, DCyan); + if(glm == nil) + sysfatal("cannot allocate mask: %r"); + + draw(glm, glm->r, display->white, nil, ZP); + gendraw(glm, glm->r, display->black, ZP, gl, gl->r.min); + freeimage(gl); + gl = display->black; + + +} + +/* unnecessary calculations here, but it's fine */ +Point +board2pix(int x, int y) +{ + float d, rx, ry, yh; + int nx, ny; + + d = (float)(Dx(screen->r) > Dy(screen->r)) ? Dy(screen->r) -20 : Dx(screen->r) -20; + rx = d/(float)SzX; + rx = rx/2.0; + ry = d/(float)SzY; + ry = ry/2.0; + + yh = ry/3.73205082; + + nx = (int)((float)x*rx*2.0+rx +(y%2?rx:0.0)); /* nx = x*(2rx) + rx + rx (conditional) */ + ny = (int)((float)y*(ry*2.0-(y>0?yh:0.0)) + ry); /* ny = y*(2ry-yh) +ry */ + return Pt(nx, ny); +} + +Point +pix2board(int x, int y) +{ + float d, rx, ry, yh; + int ny, nx; + + /* XXX: float→int causes small rounding errors */ + + d = (float)(Dx(screen->r) > Dy(screen->r)) ? Dy(screen->r) -20: Dx(screen->r)-20; + rx = d/(float)SzX; + rx = rx/2.0; + ry =d/(float)SzY; + ry = ry/2.0; + + yh = ry/3.73205082; + + /* reverse board2pix() */ + ny = (int)(((float)y - ry)/(2*ry - ((y>2*ry)?yh:0.0)) + 0.5); /* ny = (y - ry)/(2ry-yh) */ + nx = (int)(((float)x - rx - (ny%2?rx:0.0))/(rx*2.0) + 0.5); /* nx = (x - rx - rx)/2rx */ + + if (nx >= SzX) + nx = SzX-1; + if (ny >=SzY) + ny = SzY-1; + + return Pt(nx, ny); +} + +void +initlevel(void) +{ + int i, cnt = 10, x, y; + + for(x = 0; x < SzX; x++) + for(y = 0; y < SzY; y++) + ogrid[x][y] = 100; + + switch(difficulty){ + case DEasy: + cnt = 10 + nrand(5); + break; + case DMed: + cnt = 5 + nrand(5); + break; + case DHard: + cnt = nrand(5); + break; + } + for(i = 0; i < cnt; i++) { + do { + x = nrand(SzX); + y = nrand(SzY); + } while(ogrid[x][y] != 100); + ogrid[x][y] = 999; + } + + ogrid[SzX/2][SzY/2] = 1000; + + memcpy(grid, ogrid, sizeof grid); + + finished = 0; + +} + +void +drawlevel(void) +{ + Point p; + int x, y, rx, ry, d; + char *s = nil; + + if(finished) + draw(screen, screen->r, finished==Won?won:lost, nil, ZP); + else + draw(screen, screen->r, bg, nil, ZP); + + d = (Dx(screen->r) > Dy(screen->r)) ? Dy(screen->r) -20: Dx(screen->r) -20; + rx = (int)ceil((float)(d-2*Border)/(float)SzX)/2; + ry = (int)ceil((float)(d-2*Border)/(float)SzY)/2; + + for(x = 0; x < SzX; x++) { + for(y = 0; y < SzY; y++) { + p = board2pix(x, y); + switch(grid[x][y]){ + case 999: + fillellipse(screen, addpt(screen->r.min, p), rx, ry, cc, ZP); + break; + case 1000: + p = addpt(screen->r.min, p); + fillellipse(screen, p, rx, ry, ec, ZP); + p = subpt(p, Pt(24, 24)); + draw(screen, Rpt(p, addpt(p, Pt(48, 48))), gl, glm, ZP); + break; + default: + fillellipse(screen, addpt(screen->r.min, p), rx, ry, ec, ZP); + USED(s); + /* uncomment the following to see game state and field scores */ + /*s = smprint("%d", grid[x][y]); + string(screen, addpt(screen->r.min, p), display->black, ZP, font, s); + free(s); + */ + break; + } + } + } + flushimage(display, 1); +} + +void +domove(int dir, int x, int y) +{ + if(x == 0 || x == SzX-1 || y == 0 || y == SzY-1) + goto done; + + switch(dir){ + case NE: + if(y%2) + grid[x+1][y-1] = 1000; + else + grid[x][y-1] = 1000; + break; + case E: + grid[x+1][y] = 1000; + break; + case SE: + if(y%2) + grid[x+1][y+1] = 1000; + else + grid[x][y+1] = 1000; + break; + case SW: + if(y%2) + grid[x][y+1] = 1000; + else + grid[x-1][y+1] = 1000; + break; + case W: + grid[x-1][y] = 1000; + break; + case NW: + if(y%2) + grid[x][y-1] = 1000; + else + grid[x-1][y-1] = 1000; + break; + } +done: + grid[x][y] = 100; +} + +Point +findglenda(void) +{ + int x, y; + for(x = 0; x < SzX; x++) + for(y = 0; y < SzY; y++) + if(grid[x][y] == 1000) + return Pt(x, y); + return Pt(-1, -1); +} + +int +checknext(int dir, int x, int y) +{ + switch(dir){ + case NE: + return grid[x+(y%2?1:0)][y-1]; + case E: + return grid[x+1][y]; + case SE: + return grid[x+(y%2?1:0)][y+1]; + case SW: + return grid[x+(y%2?0:-1)][y+1]; + case W: + return grid[x-1][y]; + case NW: + return grid[x+(y%2?0:-1)][y-1]; + default: + sysfatal("andrey messed up big time"); + } + return 1000; +} +/* the following two routines constitute the "game AI" +* they score the field based on the number of moves +* required to reach the edge from a particular point +* scores > 100 are "dead spots" (this assumes the field +* is not larger than ~100*2 +* +* routines need to run at least twice to ensure a field is properly +* scored: there are errors that creep up due to the nature of +* traversing the board +*/ +int +score1(int x, int y) { + int dir, min = 999, next; + + if(x == 0 || x == SzX-1 || y == 0 || y == SzY-1) + return 1; /* we can always escape from the edges */ + + for(dir = NE; dir <= NW; dir++) { + next = checknext(dir, x, y); + if(next < min) + min = next; + } + return 1+min; +} + +void +calc(void) +{ + int i, x, y; + for(i = 0; i < SzX; i++) /* assumes SzX = SzY */ + for(x = i; x < SzX-i; x++) + for(y = i; y < SzY-i; y++) + if(grid[x][y] != 999) + grid[x][y] = score1(x, y); +} + +void +nextglenda(void) +{ + int min =1000, next, dir, nextdir = 0, count = 0; + Point p = findglenda(); + + calc(); + calc(); + calc(); + + grid[p.x][p.y] = 1000; + + for(dir = NE; dir <= NW; dir++) { + next = checknext(dir, p.x, p.y); + if(next < min) { + min = next; + nextdir = dir; + ++count; + } else if(next == min) { + nextdir = (nrand(++count) == 0)?dir:nextdir; + } + } + if(min < 100) + domove(nextdir, p.x, p.y); + else + finished = Won; + + if(eqpt(findglenda(), Pt(-1, -1))) + finished = Lost; +} + +int +checkfinished(void) +{ + int i, j; + for(i = 0; i < SzX; i++) + for(j = 0; j < SzY; j++) + if(grid[i][j] == 'E') + return 0; + return 1; +} + +void +move(Point m) +{ + Point p, nm; + int x, y; + + nm = subpt(m, screen->r.min); + + /* figure out where the click falls */ + p = pix2board(nm.x, nm.y); + + if(grid[p.x][p.y] >= 999) + return; + + /* reset the board scores */ + grid[p.x][p.y] = 999; + for(x = 0; x < SzX; x++) + for(y = 0; y < SzY; y++) + if(grid[x][y] != 999 && grid[x][y] != 1000) + grid[x][y] = 100; + + nextglenda(); +} + +void +resize(void) +{ + int fd, size = (Dx(screen->r) > Dy(screen->r)) ? Dy(screen->r) + 20 : Dx(screen->r)+20; + + fd = open("/dev/wctl", OWRITE); + if(fd >= 0){ + fprint(fd, "resize -dx %d -dy %d", size, size); + close(fd); + } + +} + + +void +eresized(int new) +{ + if(new && getwindow(display, Refnone) < 0) + sysfatal("can't reattach to window"); + + drawlevel(); +} + +void +main(int argc, char **argv) +{ + Mouse m; + Event ev; + int e, mousedown=0; + char *fontname; + + USED(argv, argc); + + if(initdraw(nil, nil, "glendy") < 0) + sysfatal("initdraw failed: %r"); + einit(Emouse); + + resize(); + + srand(time(0)); + + allocimages(); + initlevel(); /* must happen before "eresized" */ + eresized(0); + + fontname = "/lib/font/bit/lucidasans/unicode.8.font"; + if((font = openfont(display, fontname)) == nil) + sysfatal("font '%s' not found", fontname); + + for(;;) { + e = event(&ev); + switch(e) { + case Emouse: + m = ev.mouse; + if(m.buttons == 0) { + if(mousedown && !finished) { + mousedown = 0; + move(m.xy); + drawlevel(); + } + } + if(m.buttons&1) { + mousedown = 1; + } + if(m.buttons&2) { + switch(emenuhit(2, &m, &mmenu)) { + case 0: + difficulty = DEasy; + initlevel(); + break; + case 1: + difficulty = DMed; + initlevel(); + break; + case 2: + difficulty = DHard; + initlevel(); + break; + } + drawlevel(); + } + if(m.buttons&4) { + switch(emenuhit(3, &m, &rmenu)) { + case 0: + initlevel(); + break; + case 1: + memcpy(grid, ogrid, sizeof grid); + finished = 0; + break; + case 2: + exits(nil); + } + drawlevel(); + } + break; + } + } +} diff --git a/sys/src/games/mkfile b/sys/src/games/mkfile index 73467cc32..e59b1ad7f 100644 --- a/sys/src/games/mkfile +++ b/sys/src/games/mkfile @@ -9,6 +9,7 @@ TARG=4s\ life\ memo\ mole\ + glendy\ OFILES= HFILES= |