diff options
author | iru <devnull@localhost> | 2011-04-16 17:42:16 -0300 |
---|---|---|
committer | iru <devnull@localhost> | 2011-04-16 17:42:16 -0300 |
commit | 478d1024433f8713927729f02285682af0e0cf9b (patch) | |
tree | 79f6fd59cf1a46a1eb5d5c980178b09dda705185 /sys | |
parent | 4d4fc2ca3453a4deb79b26eb62449eab94b86827 (diff) |
Initial import of the new boot(8). Change pccd and pcf to use it.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/src/9/boot/aux.c | 130 | ||||
-rw-r--r-- | sys/src/9/boot/boot.c | 336 | ||||
-rw-r--r-- | sys/src/9/boot/boot.h | 75 | ||||
-rw-r--r-- | sys/src/9/boot/bootauth.c | 72 | ||||
-rw-r--r-- | sys/src/9/boot/bootcache.c | 80 | ||||
-rw-r--r-- | sys/src/9/boot/bootip.c | 203 | ||||
-rw-r--r-- | sys/src/9/boot/bootmkfile | 9 | ||||
-rw-r--r-- | sys/src/9/boot/bootrc | 183 | ||||
-rw-r--r-- | sys/src/9/boot/conf.rc | 50 | ||||
-rw-r--r-- | sys/src/9/boot/doauthenticate.c | 126 | ||||
-rw-r--r-- | sys/src/9/boot/embed.c | 74 | ||||
-rw-r--r-- | sys/src/9/boot/getpasswd.c | 43 | ||||
-rw-r--r-- | sys/src/9/boot/local.c | 275 | ||||
-rw-r--r-- | sys/src/9/boot/local.rc | 72 | ||||
-rw-r--r-- | sys/src/9/boot/menu.rc | 134 | ||||
-rwxr-xr-x | sys/src/9/boot/mkboot | 47 | ||||
-rw-r--r-- | sys/src/9/boot/nopsession.c | 52 | ||||
-rw-r--r-- | sys/src/9/boot/paq.c | 67 | ||||
-rw-r--r-- | sys/src/9/boot/sac.c | 50 | ||||
-rw-r--r-- | sys/src/9/boot/settime.c | 149 | ||||
-rw-r--r-- | sys/src/9/boot/tcp.rc | 61 | ||||
-rw-r--r-- | sys/src/9/boot/testboot.c | 37 | ||||
-rw-r--r-- | sys/src/9/pc/mkfile | 3 | ||||
-rw-r--r-- | sys/src/9/pc/pccd | 8 | ||||
-rw-r--r-- | sys/src/9/pc/pcf | 8 | ||||
-rw-r--r-- | sys/src/9/port/portmkfile | 2 |
26 files changed, 586 insertions, 1760 deletions
diff --git a/sys/src/9/boot/aux.c b/sys/src/9/boot/aux.c index b5dec7764..7499c9051 100644 --- a/sys/src/9/boot/aux.c +++ b/sys/src/9/boot/aux.c @@ -2,67 +2,6 @@ #include <libc.h> #include <../boot/boot.h> -/* -int -plumb(char *dir, char *dest, int *efd, char *here) -{ - char buf[128]; - char name[128]; - int n; - - sprint(name, "%s/clone", dir); - efd[0] = open(name, ORDWR); - if(efd[0] < 0) - return -1; - n = read(efd[0], buf, sizeof(buf)-1); - if(n < 0){ - close(efd[0]); - return -1; - } - buf[n] = 0; - sprint(name, "%s/%s/data", dir, buf); - if(here){ - sprint(buf, "announce %s", here); - if(sendmsg(efd[0], buf) < 0){ - close(efd[0]); - return -1; - } - } - sprint(buf, "connect %s", dest); - if(sendmsg(efd[0], buf) < 0){ - close(efd[0]); - return -1; - } - efd[1] = open(name, ORDWR); - if(efd[1] < 0){ - close(efd[0]); - return -1; - } - return efd[1]; -} - */ - -int -sendmsg(int fd, char *msg) -{ - int n; - - n = strlen(msg); - if(write(fd, msg, n) != n) - return -1; - return 0; -} - -void -warning(char *s) -{ - char buf[ERRMAX]; - - buf[0] = '\0'; - errstr(buf, sizeof buf); - fprint(2, "boot: %s: %s\n", s, buf); -} - void fatal(char *s) { @@ -90,6 +29,33 @@ readfile(char *name, char *buf, int len) return 0; } +void +run(char *file, ...) +{ + char buf[64]; + Waitmsg *w; + int pid; + + switch(pid = fork()){ + case -1: + fatal("fork"); + case 0: + exec(file, &file); + snprint(buf, sizeof buf, "can't exec %s", file); + fatal(buf); + default: + while((w = wait()) != nil) + if(w->pid == pid) + break; + if(w == nil){ + snprint(buf, sizeof buf, "wait returned nil running %s", file); + free(w); + fatal(buf); + } + free(w); + } +} + int writefile(char *name, char *buf, int len) { @@ -104,12 +70,12 @@ writefile(char *name, char *buf, int len) } void -setenv(char *name, char *val) +setenv(char *name, char *val, int ec) { int f; char ename[64]; - snprint(ename, sizeof ename, "#e/%s", name); + snprint(ename, sizeof ename, "#e%s/%s", ec ? "c" : "", name); f = create(ename, 1, 0666); if(f < 0){ fprint(2, "create %s: %r\n", ename); @@ -142,41 +108,3 @@ srvcreate(char *name, int fd) close(f); } -void -catchint(void *a, char *note) -{ - USED(a); - if(strcmp(note, "alarm") == 0) - noted(NCONT); - noted(NDFLT); -} - -int -outin(char *prompt, char *def, int len) -{ - int n; - char buf[256]; - - if(len >= sizeof buf) - len = sizeof(buf)-1; - - if(cpuflag){ - notify(catchint); - alarm(15*1000); - } - print("%s[%s]: ", prompt, *def ? def : "no default"); - memset(buf, 0, sizeof buf); - n = read(0, buf, len); - if(cpuflag){ - alarm(0); - notify(0); - } - - if(n < 0) - return 1; - if(n > 1){ - buf[n-1] = 0; - strcpy(def, buf); - } - return n; -} diff --git a/sys/src/9/boot/boot.c b/sys/src/9/boot/boot.c index db181a09d..74b18a482 100644 --- a/sys/src/9/boot/boot.c +++ b/sys/src/9/boot/boot.c @@ -5,43 +5,20 @@ #include "../boot/boot.h" char cputype[64]; -char sys[2*64]; char reply[256]; int printcol; int mflag; int fflag; int kflag; -char *bargv[Nbarg]; -int bargc; - -static void swapproc(void); -static Method *rootserver(char*); -static void usbinit(void); -static void kbmap(void); - void boot(int argc, char *argv[]) { - int fd, afd; - Method *mp; - char *cmd, cmdbuf[64], *iargv[16]; - char rootbuf[64]; - int islocal, ishybrid; - char *rp, *rsp; - int iargc, n; - char buf[32]; - AuthInfo *ai; + Waitmsg *w; + int pid, i; fmtinstall('r', errfmt); - /* - * we should inherit the standard fds all referring to /dev/cons, - * but we're being paranoid. - */ - close(0); - close(1); - close(2); bind("#c", "/dev", MBEFORE); open("/dev/cons", OREAD); open("/dev/cons", OWRITE); @@ -53,12 +30,13 @@ boot(int argc, char *argv[]) bind("#ec", "/env", MREPL); bind("#e", "/env", MBEFORE|MCREATE); bind("#s", "/srv", MREPL|MCREATE); -#ifdef DEBUG - print("argc=%d\n", argc); - for(fd = 0; fd < argc; fd++) - print("%#p %s ", argv[fd], argv[fd]); - print("\n"); -#endif DEBUG + + if(Debug){ + print("argc=%d\n", argc); + for(i = 0; i < argc; i++) + print("%lux %s ", (ulong)argv[i], argv[i]); + print("\n"); + } ARGBEGIN{ case 'k': @@ -73,281 +51,35 @@ boot(int argc, char *argv[]) }ARGEND readfile("#e/cputype", cputype, sizeof(cputype)); - - /* - * set up usb keyboard, mouse and disk, if any. - */ - usbinit(); - - /* - * pick a method and initialize it - */ - if(method[0].name == nil) - fatal("no boot methods"); - mp = rootserver(argc ? *argv : 0); - (*mp->config)(mp); - islocal = strcmp(mp->name, "local") == 0; - ishybrid = strcmp(mp->name, "hybrid") == 0; - - /* - * load keymap if it's there. - */ - kbmap(); - - /* - * authentication agent - */ - authentication(cpuflag); - - /* - * connect to the root file system - */ - fd = (*mp->connect)(); - if(fd < 0) - fatal("can't connect to file server"); - if(getenv("srvold9p")) - fd = old9p(fd); - if(!islocal && !ishybrid){ - if(cfs) - fd = (*cfs)(fd); - } - print("version..."); - buf[0] = '\0'; - n = fversion(fd, 0, buf, sizeof buf); - if(n < 0) - fatal("can't init 9P"); - srvcreate("boot", fd); - - /* - * create the name space, mount the root fs - */ - if(bind("/", "/", MREPL) < 0) - fatal("bind /"); - rp = getenv("rootspec"); - if(rp == nil) - rp = ""; + setenv("bootdisk", bootdisk, 0); - afd = fauth(fd, rp); - if(afd >= 0){ - ai = auth_proxy(afd, auth_getkey, "proto=p9any role=client"); - if(ai == nil) - print("authentication failed (%r), trying mount anyways\n"); - } - if(mount(fd, afd, "/root", MREPL|MCREATE, rp) < 0) - fatal("mount /"); - rsp = rp; - rp = getenv("rootdir"); - if(rp == nil) - rp = rootdir; - if(bind(rp, "/", MAFTER|MCREATE) < 0){ - if(strncmp(rp, "/root", 5) == 0){ - fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp); - fatal("second bind /"); - } - snprint(rootbuf, sizeof rootbuf, "/root/%s", rp); - rp = rootbuf; - if(bind(rp, "/", MAFTER|MCREATE) < 0){ - fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp); - if(strcmp(rootbuf, "/root//plan9") == 0){ - fprint(2, "**** warning: remove rootdir=/plan9 entry from plan9.ini\n"); - rp = "/root"; - if(bind(rp, "/", MAFTER|MCREATE) < 0) - fatal("second bind /"); - }else - fatal("second bind /"); - } - } - close(fd); - setenv("rootdir", rp); - - settime(islocal, afd, rsp); - if(afd > 0) - close(afd); - swapproc(); - - cmd = getenv("init"); - if(cmd == nil){ - sprint(cmdbuf, "/%s/init -%s%s", cputype, - cpuflag ? "c" : "t", mflag ? "m" : ""); - cmd = cmdbuf; - } - iargc = tokenize(cmd, iargv, nelem(iargv)-1); - cmd = iargv[0]; - - /* make iargv[0] basename(iargv[0]) */ - if(iargv[0] = strrchr(iargv[0], '/')) - iargv[0]++; - else - iargv[0] = cmd; - - iargv[iargc] = nil; - - exec(cmd, iargv); - fatal(cmd); -} - -static Method* -findmethod(char *a) -{ - Method *mp; - int i, j; - char *cp; - - if((i = strlen(a)) == 0) - return nil; - cp = strchr(a, '!'); - if(cp) - i = cp - a; - for(mp = method; mp->name; mp++){ - j = strlen(mp->name); - if(j > i) - j = i; - if(strncmp(a, mp->name, j) == 0) - break; - } - if(mp->name) - return mp; - return nil; -} - -/* - * ask user from whence cometh the root file system - */ -static Method* -rootserver(char *arg) -{ - char prompt[256]; - Method *mp; - char *cp; - int n; - - /* look for required reply */ - readfile("#e/nobootprompt", reply, sizeof(reply)); - if(reply[0]){ - mp = findmethod(reply); - if(mp) - goto HaveMethod; - print("boot method %s not found\n", reply); - reply[0] = 0; - } - - /* make list of methods */ - mp = method; - n = sprint(prompt, "root is from (%s", mp->name); - for(mp++; mp->name; mp++) - n += sprint(prompt+n, ", %s", mp->name); - sprint(prompt+n, ")"); - - /* create default reply */ - readfile("#e/bootargs", reply, sizeof(reply)); - if(reply[0] == 0 && arg != 0) - strcpy(reply, arg); - if(reply[0]){ - mp = findmethod(reply); - if(mp == 0) - reply[0] = 0; - } - if(reply[0] == 0) - strcpy(reply, method->name); - - /* parse replies */ - do{ - outin(prompt, reply, sizeof(reply)); - mp = findmethod(reply); - }while(mp == nil); - -HaveMethod: - bargc = tokenize(reply, bargv, Nbarg-2); - bargv[bargc] = nil; - cp = strchr(reply, '!'); - if(cp) - strcpy(sys, cp+1); - return mp; -} - -static void -swapproc(void) -{ - int fd; - - fd = open("#c/swap", OWRITE); - if(fd < 0){ - warning("opening #c/swap"); - return; - } - if(write(fd, "start", 5) <= 0) - warning("starting swap kproc"); - close(fd); -} - -int -old9p(int fd) -{ - int p[2]; - - if(pipe(p) < 0) - fatal("pipe"); - - print("srvold9p..."); - switch(fork()) { + /* setup the boot namespace */ + run("/boot/mntgen", "-s", "slash", "/mnt", nil); + run("/boot/bzfs", "-f", "/boot/rootfs.bz2", "-m", "/mnt/broot", nil); + bind("/mnt/broot", "/", MAFTER); + bind("/386/bin", "/bin", MAFTER); + bind("/rc/bin", "/bin", MAFTER); + bind("/boot", "/bin", MAFTER); + + switch(pid = rfork(RFFDG|RFREND|RFPROC)){ case -1: - fatal("rfork srvold9p"); + fatal("fork error"); case 0: - dup(fd, 1); - close(fd); - dup(p[0], 0); - close(p[0]); - close(p[1]); - execl("/srvold9p", "srvold9p", "-s", 0); - fatal("exec srvold9p"); + setenv("cpuflag", cpuflag ? "1" : "0", 0); + run("/bin/rc", "/rc/bin/bootrc", nil); + break; default: - close(fd); - close(p[0]); - } - return p[1]; -} - -static void -usbinit(void) -{ - static char usbd[] = "/boot/usbd"; - - if(access("#u/usb/ctl", 0) >= 0 && bind("#u", "/dev", MAFTER) >= 0 && - access(usbd, AEXIST) >= 0) - run(usbd, nil); -} - -static void -kbmap(void) -{ - char *f; - int n, in, out; - char buf[1024]; - - f = getenv("kbmap"); - if(f == nil) - return; - if(bind("#κ", "/dev", MAFTER) < 0){ - warning("can't bind #κ"); - return; + while((w = wait()) != nil) + if(w->pid == pid) + break; + if(w == nil){ + free(w); + fatal("wait error"); + } + free(w); + break; } - in = open(f, OREAD); - if(in < 0){ - warning("can't open kbd map: %r"); - return; - } - out = open("/dev/kbmap", OWRITE); - if(out < 0) { - warning("can't open /dev/kbmap: %r"); - close(in); - return; - } - while((n = read(in, buf, sizeof(buf))) > 0) - if(write(out, buf, n) != n){ - warning("write to /dev/kbmap failed"); - break; - } - close(in); - close(out); + for(;;) + ; } diff --git a/sys/src/9/boot/boot.h b/sys/src/9/boot/boot.h index 65b20abda..1734b06fe 100644 --- a/sys/src/9/boot/boot.h +++ b/sys/src/9/boot/boot.h @@ -1,73 +1,18 @@ -typedef struct Method Method; -struct Method -{ - char *name; - void (*config)(Method*); - int (*connect)(void); - char *arg; -}; -enum -{ - Statsz= 256, - Nbarg= 16, +enum { + Debug = 0, }; -extern void authentication(int); extern char* bootdisk; extern char* rootdir; -extern int (*cfs)(int); -extern int cpuflag; -extern char cputype[]; -extern int fflag; -extern int kflag; -extern Method method[]; -extern void (*pword)(int, Method*); -extern char sys[]; -extern uchar hostkey[]; -extern uchar statbuf[Statsz]; -extern int bargc; -extern char *bargv[Nbarg]; -extern int pcload; +extern int (*cfs)(int); +extern int cpuflag; +extern char cputype[]; +extern int fflag; +extern int kflag; -/* libc equivalent */ -extern int cache(int); -extern char* checkkey(Method*, char*, char*); -extern void fatal(char*); -extern void getpasswd(char*, int); -extern void key(int, Method*); -extern int outin(char*, char*, int); -extern int plumb(char*, char*, int*, char*); +extern void fatal(char*); extern int readfile(char*, char*, int); -extern long readn(int, void*, long); -extern void run(char *file, ...); -extern int sendmsg(int, char*); -extern void setenv(char*, char*); -extern void settime(int, int, char*); -extern void srvcreate(char*, int); -extern void warning(char*); +extern void run(char*, ...); +extern void setenv(char*, char*, int); extern int writefile(char*, char*, int); extern void boot(int, char **); -extern void doauthenticate(int, Method*); -extern int old9p(int); -extern int parsefields(char*, char**, int, char*); - -/* methods */ -extern void configtcp(Method*); -extern int connecttcp(void); - -extern void configlocal(Method*); -extern int connectlocal(void); - -extern void configsac(Method*); -extern int connectsac(void); - -extern void configpaq(Method*); -extern int connectpaq(void); - -extern void configembed(Method*); -extern int connectembed(void); - -extern void configip(int, char**, int); - -/* hack for passing authentication address */ -extern char *authaddr; diff --git a/sys/src/9/boot/bootauth.c b/sys/src/9/boot/bootauth.c deleted file mode 100644 index c22b9eb4d..000000000 --- a/sys/src/9/boot/bootauth.c +++ /dev/null @@ -1,72 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <auth.h> -#include <fcall.h> -#include "../boot/boot.h" - -char *authaddr; -static void glenda(void); - -void -authentication(int cpuflag) -{ - char *s; - char *argv[16], **av; - int ac; - - if(access("/boot/factotum", AEXEC) < 0){ - glenda(); - return; - } - - /* start agent */ - ac = 0; - av = argv; - av[ac++] = "factotum"; - if(getenv("debugfactotum")) - av[ac++] = "-p"; - s = getenv("factotumopts"); - if(s != nil && *s != '\0') - av[ac++] = s; -// av[ac++] = "-d"; /* debug traces */ -// av[ac++] = "-D"; /* 9p messages */ - if(cpuflag) - av[ac++] = "-S"; - else - av[ac++] = "-u"; - av[ac++] = "-sfactotum"; - if(authaddr != nil){ - av[ac++] = "-a"; - av[ac++] = authaddr; - } - av[ac] = 0; - switch(fork()){ - case -1: - fatal("starting factotum: %r"); - case 0: - exec("/boot/factotum", av); - fatal("execing /boot/factotum"); - } - - /* wait for agent to really be there */ - while(access("/mnt/factotum", 0) < 0) - sleep(250); -} - -static void -glenda(void) -{ - int fd; - char *s; - - s = getenv("user"); - if(s == nil) - s = "glenda"; - - fd = open("#c/hostowner", OWRITE); - if(fd >= 0){ - if(write(fd, s, strlen(s)) != strlen(s)) - fprint(2, "setting #c/hostowner to %s: %r\n", s); - close(fd); - } -} diff --git a/sys/src/9/boot/bootcache.c b/sys/src/9/boot/bootcache.c deleted file mode 100644 index eb748e989..000000000 --- a/sys/src/9/boot/bootcache.c +++ /dev/null @@ -1,80 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <../boot/boot.h> - -uchar statbuf[Statsz]; - -int -cache(int fd) -{ - int argc, i, p[2]; - char *argv[5], bd[32], buf[256], partition[64], *pp; - - if(stat("/boot/cfs", statbuf, sizeof statbuf) < 0) - return fd; - - *partition = 0; - - bind("#S", "/dev", MAFTER); - readfile("#e/cfs", buf, sizeof(buf)); - if(*buf){ - argc = tokenize(buf, argv, 4); - for(i = 0; i < argc; i++){ - if(strcmp(argv[i], "off") == 0) - return fd; - else if(stat(argv[i], statbuf, sizeof statbuf) >= 0){ - strncpy(partition, argv[i], sizeof(partition)-1); - partition[sizeof(partition)-1] = 0; - } - } - } - - if(*partition == 0){ - readfile("#e/bootdisk", bd, sizeof(bd)); - if(*bd){ - if(pp = strchr(bd, ':')) - *pp = 0; - /* damned artificial intelligence */ - i = strlen(bd); - if(strcmp("disk", &bd[i-4]) == 0) - bd[i-4] = 0; - else if(strcmp("fs", &bd[i-2]) == 0) - bd[i-2] = 0; - else if(strcmp("fossil", &bd[i-6]) == 0) - bd[i-6] = 0; - sprint(partition, "%scache", bd); - if(stat(partition, statbuf, sizeof statbuf) < 0) - *bd = 0; - } - if(*bd == 0){ - sprint(partition, "%scache", bootdisk); - if(stat(partition, statbuf, sizeof statbuf) < 0) - return fd; - } - } - - print("cfs..."); - if(pipe(p)<0) - fatal("pipe"); - switch(fork()){ - case -1: - fatal("fork"); - case 0: - close(p[1]); - dup(fd, 0); - close(fd); - dup(p[0], 1); - close(p[0]); - if(fflag) - execl("/boot/cfs", "bootcfs", "-rs", "-f", partition, 0); - else - execl("/boot/cfs", "bootcfs", "-s", "-f", partition, 0); - break; - default: - close(p[0]); - close(fd); - fd = p[1]; - break; - } - return fd; -} diff --git a/sys/src/9/boot/bootip.c b/sys/src/9/boot/bootip.c deleted file mode 100644 index 94ff87026..000000000 --- a/sys/src/9/boot/bootip.c +++ /dev/null @@ -1,203 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <ip.h> - -#include "boot.h" - -static uchar fsip[IPaddrlen]; - uchar auip[IPaddrlen]; -static char mpoint[32]; - -static int isvalidip(uchar*); -static void netndb(char*, uchar*); -static void netenv(char*, uchar*); - - -void -configip(int bargc, char **bargv, int needfs) -{ - Waitmsg *w; - int argc, pid; - char **arg, **argv, buf[32], *p; - - fmtinstall('I', eipfmt); - fmtinstall('M', eipfmt); - fmtinstall('E', eipfmt); - - arg = malloc((bargc+1) * sizeof(char*)); - if(arg == nil) - fatal("%r"); - memmove(arg, bargv, bargc * sizeof(char*)); - arg[bargc] = 0; - - argc = bargc; - argv = arg; - strcpy(mpoint, "/net"); - ARGBEGIN { - case 'x': - p = ARGF(); - if(p != nil) - snprint(mpoint, sizeof(mpoint), "/net%s", p); - break; - case 'g': - case 'b': - case 'h': - case 'm': - p = ARGF(); - USED(p); - break; - } ARGEND; - - /* bind in an ip interface */ - if(bind("#I", mpoint, MAFTER) < 0) - fatal("bind #I: %r\n"); - if(access("#l0", 0) == 0 && bind("#l0", mpoint, MAFTER) < 0) - print("bind #l0: %r\n"); - if(access("#l1", 0) == 0 && bind("#l1", mpoint, MAFTER) < 0) - print("bind #l1: %r\n"); - if(access("#l2", 0) == 0 && bind("#l2", mpoint, MAFTER) < 0) - print("bind #l2: %r\n"); - if(access("#l3", 0) == 0 && bind("#l3", mpoint, MAFTER) < 0) - print("bind #l3: %r\n"); - werrstr(""); - - /* let ipconfig configure the ip interface */ - switch(pid = fork()){ - case -1: - fatal("configuring ip: %r"); - case 0: - exec("/boot/ipconfig", arg); - fatal("execing /ipconfig"); - default: - break; - } - - /* wait for ipconfig to finish */ - for(;;){ - w = wait(); - if(w != nil && w->pid == pid){ - if(w->msg[0] != 0) - fatal(w->msg); - free(w); - break; - } else if(w == nil) - fatal("configuring ip"); - free(w); - } - - if(!needfs) - return; - - /* if we didn't get a file and auth server, query user */ - netndb("fs", fsip); - if(!isvalidip(fsip)) - netenv("fs", fsip); - while(!isvalidip(fsip)){ - buf[0] = 0; - outin("filesystem IP address", buf, sizeof(buf)); - if (parseip(fsip, buf) == -1) - fprint(2, "configip: can't parse fs ip %s\n", buf); - } - - netndb("auth", auip); - if(!isvalidip(auip)) - netenv("auth", auip); - while(!isvalidip(auip)){ - buf[0] = 0; - outin("authentication server IP address", buf, sizeof(buf)); - if (parseip(auip, buf) == -1) - fprint(2, "configip: can't parse auth ip %s\n", buf); - } -} - -static void -setauthaddr(char *proto, int port) -{ - char buf[128]; - - snprint(buf, sizeof buf, "%s!%I!%d", proto, auip, port); - authaddr = strdup(buf); -} - -void -configtcp(Method*) -{ - configip(bargc, bargv, 1); - setauthaddr("tcp", 567); -} - -int -connecttcp(void) -{ - int fd; - char buf[64]; - - snprint(buf, sizeof buf, "tcp!%I!564", fsip); - fd = dial(buf, 0, 0, 0); - if (fd < 0) - werrstr("dial %s: %r", buf); - return fd; -} - -static int -isvalidip(uchar *ip) -{ - if(ipcmp(ip, IPnoaddr) == 0) - return 0; - if(ipcmp(ip, v4prefix) == 0) - return 0; - return 1; -} - -static void -netenv(char *attr, uchar *ip) -{ - int fd, n; - char buf[128]; - - ipmove(ip, IPnoaddr); - snprint(buf, sizeof(buf), "#e/%s", attr); - fd = open(buf, OREAD); - if(fd < 0) - return; - - n = read(fd, buf, sizeof(buf)-1); - if(n <= 0) - return; - buf[n] = 0; - if (parseip(ip, buf) == -1) - fprint(2, "netenv: can't parse ip %s\n", buf); -} - -static void -netndb(char *attr, uchar *ip) -{ - int fd, n, c; - char buf[1024]; - char *p; - - ipmove(ip, IPnoaddr); - snprint(buf, sizeof(buf), "%s/ndb", mpoint); - fd = open(buf, OREAD); - if(fd < 0) - return; - n = read(fd, buf, sizeof(buf)-1); - close(fd); - if(n <= 0) - return; - buf[n] = 0; - n = strlen(attr); - for(p = buf; ; p++){ - p = strstr(p, attr); - if(p == nil) - break; - c = *(p-1); - if(*(p + n) == '=' && (p == buf || c == '\n' || c == ' ' || c == '\t')){ - p += n+1; - if (parseip(ip, p) == -1) - fprint(2, "netndb: can't parse ip %s\n", p); - return; - } - } - return; -} diff --git a/sys/src/9/boot/bootmkfile b/sys/src/9/boot/bootmkfile index c189b829d..0b873ae7a 100644 --- a/sys/src/9/boot/bootmkfile +++ b/sys/src/9/boot/bootmkfile @@ -2,17 +2,8 @@ BOOTDIR=../boot BOOTLIB=$BOOTDIR/libboot.a$O BOOTFILES=\ - bootauth.$O\ aux.$O\ boot.$O\ - bootcache.$O\ - bootip.$O\ - local.$O\ - embed.$O\ - settime.$O\ - sac.$O\ - paq.$O\ - printstub.$O\ $BOOTLIB(%.$O):N: %.$O diff --git a/sys/src/9/boot/bootrc b/sys/src/9/boot/bootrc new file mode 100644 index 000000000..99a7c93c7 --- /dev/null +++ b/sys/src/9/boot/bootrc @@ -0,0 +1,183 @@ +# TODO +# settime +# handle rootspec +# handle rootdir +# clean rc environment before running init(8) +# kfs +# caching + +rfork e +# boot methods +mlocal = (configlocal connectlocal) +mtcp = (configtcp connecttcp) +mtab = (mlocal mtcp) +config=1 +connect=2 +bootargs=() + +. /rc/lib/conf.rc +. /rc/lib/menu.rc +. /rc/lib/local.rc +. /rc/lib/tcp.rc + +cputype=`{cat '#e'/cputype} + +fn fatal { + echo $* + exit $"* +} + +fn must { + $* || fatal $"*^': '^$status +} + + +fn usbinit{ + if(test -f '#u'){ + bind -a '#u' /dev + # TODO: check access to /dev/usb + must usbd + } +} + +fn kbmap{ + if(! ~ $#kbmap 0){ + bind -a '#κ' /dev + cat $kbmap > /dev/kbmap + } +} + +fn readmethod{ + resp=() + timeo=5 + found=0 + + echo + echo Storage devices + for(i in /dev/sd??){ + echo -n local!^$i' ' + echo `{sed 's/inquiry[ ]+//g; q' $i/ctl}\ + partitions: `{cat $i/ctl | grep part | awk '{print $2}'} + } + + while(~ $found 0){ + if(~ $#pcload 0) + echo -n 'root is from: ' + if not + echo -n 'kernel is at: ' + + while(~ $#resp 0){ + resp=`{tread $timeo} + if(! ~ $status ''){ + bootconf # set configuration from file + if(! ~ $#nobootprompt 0) + bootargs=$nobootprompt + resp=$bootargs + } + if(~ $resp !rc) + rc + timeo=0 + } + + method=`{echo $resp | awk -F! '{print $1}'} + NF=`{echo $resp | awk -F! '{print NF}'} + + for(i in `{seq 1 $#mtab}){ + if(~ $mtab($i) m^$method) + found = $i + } + + if(~ $found 0){ + echo method $method not found + resp=() + } + } + + methodarg = `{echo $resp | sed 's/^[A-Za-z]+!(.*)$/\1/'} + mp = $$mtab($found) +} + +fn authentication{ + # in pcload we only need to read the kernel + if(~ $pcload 1) + user=none + + if(! test -x /boot/factotum){ + if(~ $#user 0) + user=glenda + echo -n $user > '#c'/hostowner + } + + if not{ + x=(/boot/factotum -u -sfactotum) + if(~ $cpuflag 1) + x=($x -S) + if(! ~ $#authaddr 0) + x=($x -a $authaddr) + if(! ~ $#debugfactotum 0) + x=($x -p) + + must $x + } +} + +fn swapproc{ + if(test -x '#c'/swap) + echo -n start > '#c'/swap +} + +usbinit # set up usb keyboard, mouse, and disk, if any +kbmap + +configlocal # add partitions and binds + +readmethod +$mp($config) + +switch($method){ +case local + islocal=1 +case hybrid + ishybrid=1 +} + +# authentication agent +authentication + +# connect to the root file system +$mp($connect) + +swapproc + +mount -c '#s/boot' /root + +# remove part of our temporary root +unmount /$cputype/bin /bin +/mnt/broot/$cputype/bin/unmount /rc/bin /bin +/mnt/broot/$cputype/bin/unmount /boot /bin +/mnt/broot/$cputype/bin/unmount / + +if(~ $pcload 1) + /boot/echo reboot /root/$kern >/dev/reboot + +# create the name space, mount the root fs +/mnt/broot/$cputype/bin/bind / / +/mnt/broot/$cputype/bin/mount -ac '#s/boot' / + +# remove the remaining temporary root +/mnt/broot/$cputype/bin/unmount /mnt/broot + +rootdir=/root + +if(~ $#init 0){ + init=/$cputype/init + if(~ $cpuflag 1) + init=($init -c) + if not + init=($init -t) + # TODO handle mflag +} + +$init + + diff --git a/sys/src/9/boot/conf.rc b/sys/src/9/boot/conf.rc new file mode 100644 index 000000000..dd217c6c0 --- /dev/null +++ b/sys/src/9/boot/conf.rc @@ -0,0 +1,50 @@ +#!/bin/rc + +mounted=0 +found=0 + +fn confmount{ + part=`{echo $1 | sed 's!^.*/!!g; s!''$!!g'} + + switch($part){ + case dos + mprog=dossrv + case 9fat + mprog=dossrv + case fd?disk + mprog=dossrv + case data + mprog=9660srv + case * + mprog=0 + mounted=0 + } + + if(! ~ $mprog 0){ + $mprog -f $1 conf >/dev/null >[2=1] + mount /srv/conf /mnt/conf + mounted=1 + } +} + +fn findconf{ + # search cd/dvd drives first + for(d in $cddevs /dev/sd* /dev/fd*disk) + for(p in `{ls $d}){ + if(~ $found 0){ + confmount $p + if(test -e /mnt/conf/plan9.ini) + found=1 + if(test $mounted -eq 1 -a $found -eq 0){ + unmount /mnt/conf + rm /srv/conf + } + } + } +} + +fn bootconf{ + findconf + if(~ $found 1) + parseconf +} diff --git a/sys/src/9/boot/doauthenticate.c b/sys/src/9/boot/doauthenticate.c deleted file mode 100644 index f632ab08e..000000000 --- a/sys/src/9/boot/doauthenticate.c +++ /dev/null @@ -1,126 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <auth.h> -#include "../boot/boot.h" - -static char *pbmsg = "AS protocol botch"; -static char *ccmsg = "can't connect to AS"; - -long -readn(int fd, void *buf, long len) -{ - int m, n; - char *p; - - p = buf; - for(n = 0; n < len; n += m){ - m = read(fd, p+n, len-n); - if(m <= 0) - return -1; - } - return n; -} - -static char* -fromauth(Method *mp, char *trbuf, char *tbuf) -{ - int afd; - char t; - char *msg; - static char error[2*ERRMAX]; - - if(mp->auth == 0) - fatal("no method for accessing auth server"); - afd = (*mp->auth)(); - if(afd < 0) { - sprint(error, "%s: %r", ccmsg); - return error; - } - - if(write(afd, trbuf, TICKREQLEN) < 0 || read(afd, &t, 1) != 1){ - close(afd); - sprint(error, "%s: %r", pbmsg); - return error; - } - switch(t){ - case AuthOK: - msg = 0; - if(readn(afd, tbuf, 2*TICKETLEN) < 0) { - sprint(error, "%s: %r", pbmsg); - msg = error; - } - break; - case AuthErr: - if(readn(afd, error, ERRMAX) < 0) { - sprint(error, "%s: %r", pbmsg); - msg = error; - } - else { - error[ERRMAX-1] = 0; - msg = error; - } - break; - default: - msg = pbmsg; - break; - } - - close(afd); - return msg; -} - -void -doauthenticate(int fd, Method *mp) -{ - char *msg; - char trbuf[TICKREQLEN]; - char tbuf[2*TICKETLEN]; - - print("session..."); - if(fsession(fd, trbuf, sizeof trbuf) < 0) - fatal("session command failed"); - - /* no authentication required? */ - memset(tbuf, 0, 2*TICKETLEN); - if(trbuf[0] == 0) - return; - - /* try getting to an auth server */ - print("getting ticket..."); - msg = fromauth(mp, trbuf, tbuf); - print("authenticating..."); - if(msg == 0) - if(fauth(fd, tbuf) >= 0) - return; - - /* didn't work, go for the security hole */ - fprint(2, "no authentication server (%s), using your key as server key\n", msg); -} - -char* -checkkey(Method *mp, char *name, char *key) -{ - char *msg; - Ticketreq tr; - Ticket t; - char trbuf[TICKREQLEN]; - char tbuf[TICKETLEN]; - - memset(&tr, 0, sizeof tr); - tr.type = AuthTreq; - strcpy(tr.authid, name); - strcpy(tr.hostid, name); - strcpy(tr.uid, name); - convTR2M(&tr, trbuf); - msg = fromauth(mp, trbuf, tbuf); - if(msg == ccmsg){ - fprint(2, "boot: can't contact auth server, passwd unchecked\n"); - return 0; - } - if(msg) - return msg; - convM2T(tbuf, &t, key); - if(t.num == AuthTc && strcmp(name, t.cuid)==0) - return 0; - return "no match"; -} diff --git a/sys/src/9/boot/embed.c b/sys/src/9/boot/embed.c deleted file mode 100644 index d14de65f5..000000000 --- a/sys/src/9/boot/embed.c +++ /dev/null @@ -1,74 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <../boot/boot.h> - -static char *paqfile; - -void -configembed(Method *m) -{ - if(*sys == '/' || *sys == '#'){ - /* - * if the user specifies the disk in the boot cmd or - * 'root is from' prompt, use it - */ - paqfile = sys; - } else if(m->arg){ - /* - * a default is supplied when the kernel is made - */ - paqfile = m->arg; - } -} - -int -connectembed(void) -{ - int i, p[2]; - Dir *dir; - char **arg, **argp; - - dir = dirstat("/boot/paqfs"); - if(dir == nil) - return -1; - free(dir); - - dir = dirstat(paqfile); - if(dir == nil || dir->mode & DMDIR) - return -1; - free(dir); - - print("paqfs..."); - if(bind("#c", "/dev", MREPL) < 0) - fatal("bind #c"); - if(bind("#p", "/proc", MREPL) < 0) - fatal("bind #p"); - if(pipe(p)<0) - fatal("pipe"); - switch(fork()){ - case -1: - fatal("fork"); - case 0: - arg = malloc((bargc+5)*sizeof(char*)); - argp = arg; - *argp++ = "/boot/paqfs"; - *argp++ = "-iv"; - *argp++ = paqfile; - for(i=1; i<bargc; i++) - *argp++ = bargv[i]; - *argp = 0; - - dup(p[0], 0); - dup(p[1], 1); - close(p[0]); - close(p[1]); - exec("/boot/paqfs", arg); - fatal("can't exec paqfs"); - default: - break; - } - waitpid(); - - close(p[1]); - return p[0]; -} diff --git a/sys/src/9/boot/getpasswd.c b/sys/src/9/boot/getpasswd.c deleted file mode 100644 index b766e2543..000000000 --- a/sys/src/9/boot/getpasswd.c +++ /dev/null @@ -1,43 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <../boot/boot.h> - -void -getpasswd(char *p, int len) -{ - char c; - int i, n, fd; - - fd = open("#c/consctl", OWRITE); - if(fd < 0) - fatal("can't open consctl; please reboot"); - write(fd, "rawon", 5); - Prompt: - print("password: "); - n = 0; - for(;;){ - do{ - i = read(0, &c, 1); - if(i < 0) - fatal("can't read cons; please reboot"); - }while(i == 0); - switch(c){ - case '\n': - p[n] = '\0'; - close(fd); - print("\n"); - return; - case '\b': - if(n > 0) - n--; - break; - case 'u' - 'a' + 1: /* cntrl-u */ - print("\n"); - goto Prompt; - default: - if(n < len - 1) - p[n++] = c; - break; - } - } -} diff --git a/sys/src/9/boot/local.c b/sys/src/9/boot/local.c deleted file mode 100644 index f885b0d83..000000000 --- a/sys/src/9/boot/local.c +++ /dev/null @@ -1,275 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <../boot/boot.h> - -static char diskname[64]; -static char *disk; -static char **args; - -void -configlocal(Method *mp) -{ - char *p; - int n; - - if(*sys == '/' || *sys == '#'){ - /* - * if the user specifies the disk in the boot cmd or - * 'root is from' prompt, use it - */ - disk = sys; - } else if(strncmp(argv0, "dksc(0,", 7) == 0){ - /* - * on many mips arg0 of the boot command specifies the - * scsi logical unit number - */ - p = strchr(argv0, ','); - n = strtoul(p+1, 0, 10); - sprint(diskname, "#w%d/sd%dfs", n, n); - disk = diskname; - } else if(mp->arg){ - /* - * a default is supplied when the kernel is made - */ - disk = mp->arg; - } else if(*bootdisk){ - /* - * an environment variable from a pc's plan9.ini or - * from the mips nvram or generated by the kernel - * is the last resort. - */ - disk = bootdisk; - } - - /* if we've decided on one, pass it on to all programs */ - if(disk) - setenv("bootdisk", disk); - - USED(mp); -} - -int -connectlocalkfs(void) -{ - int i, pid, fd, p[2]; - char partition[64]; - char *dev; - char **arg, **argp; - Dir *d; - - if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0) - return -1; - - dev = disk ? disk : bootdisk; - snprint(partition, sizeof partition, "%sfs", dev); - fd = open(partition, OREAD); - if(fd < 0){ - strcpy(partition, dev); - fd = open(partition, OREAD); - if(fd < 0) - return -1; - } - /* - * can't do this check -- might be some other server posing as kfs. - * - memset(buf, 0, sizeof buf); - pread(fd, buf, 512, 0); - close(fd); - if(memcmp(buf+256, "kfs wren device\n", 16) != 0){ - if(strstr(partition, "/fs")) - print("no kfs file system found on %s\n", partition); - return -1; - } - * - */ - d = dirfstat(fd); - close(fd); - if(d == nil) - return -1; - if(d->mode&DMDIR){ - free(d); - return -1; - } - free(d); - - print("kfs..."); - if(pipe(p)<0) - fatal("pipe"); - switch(pid = fork()){ - case -1: - fatal("fork"); - case 0: - arg = malloc((bargc+5)*sizeof(char*)); - argp = arg; - *argp++ = "kfs"; - *argp++ = "-f"; - *argp++ = partition; - *argp++ = "-s"; - for(i=1; i<bargc; i++) - *argp++ = bargv[i]; - *argp = 0; - - dup(p[0], 0); - dup(p[1], 1); - close(p[0]); - close(p[1]); - exec("/boot/kfs", arg); - fatal("can't exec kfs"); - default: - break; - } - for(;;){ - if((i = waitpid()) == -1) - fatal("waitpid for kfs failed"); - if(i == pid) - break; - } - - close(p[1]); - return p[0]; -} - -void -run(char *file, ...) -{ - int i, pid; - - switch(pid = fork()){ - case -1: - fatal("fork"); - case 0: - exec(file, &file); - fatal(smprint("can't exec %s: %r", file)); - default: - while ((i = waitpid()) != pid && i != -1) - ; - if(i == -1) - fatal(smprint("wait failed running %s", file)); - } -} - -static int -print1(int fd, char *s) -{ - return write(fd, s, strlen(s)); -} - -void -configloopback(void) -{ - int fd; - - if((fd = open("/net/ipifc/clone", ORDWR)) < 0){ - bind("#I", "/net", MAFTER); - if((fd = open("/net/ipifc/clone", ORDWR)) < 0) - fatal("open /net/ipifc/clone for loopback"); - } - if(print1(fd, "bind loopback /dev/null") < 0 - || print1(fd, "add 127.0.0.1 255.255.255.255") < 0) - fatal("write /net/ipifc/clone for loopback"); -} - -int -connectlocalfossil(void) -{ - int fd; - char *venti, *f[32], *p; - int nf; - char partition[128], buf[512]; - char *dev; - - if(stat("/boot/fossil", statbuf, sizeof statbuf) < 0) - return -1; - - /* look for fossil partition */ - dev = disk ? disk : bootdisk; - snprint(partition, sizeof partition, "%sfossil", dev); - fd = open(partition, OREAD); - if(fd < 0){ - strcpy(partition, dev); - fd = open(partition, OREAD); - if(fd < 0) - return -1; - } - memset(buf, 0, sizeof buf); - pread(fd, buf, 512, 127*1024); - close(fd); - if(memcmp(buf, "fossil config\n", 14) != 0){ - if(strstr(partition, "/fossil")) - print("no fossil config found on %s\n", partition); - return -1; - } - - settime(1, -1, nil); - - /* make venti available */ - if((venti = getenv("venti")) && (nf = tokenize(venti, f, nelem(f)))){ - if((fd = open(f[0], OREAD)) >= 0){ - print("venti..."); - memset(buf, 0, sizeof buf); - pread(fd, buf, 512, 248*1024); - close(fd); - if(memcmp(buf, "venti config\n", 13) != 0){ - print("no venti config found on %s\n", f[0]); - return -1; - } - if(stat("/boot/venti", statbuf, sizeof statbuf) < 0){ - print("/boot/venti does not exist\n"); - return -1; - } - switch(nf){ - case 1: - f[1] = "tcp!127.1!17034"; - case 2: - f[2] = "tcp!127.1!8000"; - } - configloopback(); - run("/boot/venti", "-c", f[0], "-a", f[1], "-h", f[2], 0); - /* - * If the announce address is tcp!*!foo, then set - * $venti to tcp!127.1!foo instead, which is actually dialable. - */ - if((p = strstr(f[1], "!*!")) != 0){ - *p = 0; - snprint(buf, sizeof buf, "%s!127.1!%s", f[1], p+3); - f[1] = buf; - } - setenv("venti", f[1]); - }else{ - /* set up the network so we can talk to the venti server */ - /* this is such a crock. */ - configip(nf, f, 0); - setenv("venti", f[0]); - } - } - - /* start fossil */ - print("fossil(%s)...", partition); - run("/boot/fossil", "-f", partition, "-c", "srv -A fboot", "-c", "srv -p fscons", 0); - fd = open("#s/fboot", ORDWR); - if(fd < 0){ - print("open #s/fboot: %r\n"); - return -1; - } - remove("#s/fboot"); /* we'll repost as #s/boot */ - return fd; -} - -int -connectlocal(void) -{ - int fd; - - if(bind("#c", "/dev", MREPL) < 0) - fatal("bind #c"); - if(bind("#p", "/proc", MREPL) < 0) - fatal("bind #p"); - bind("#S", "/dev", MAFTER); - bind("#k", "/dev", MAFTER); - bind("#æ", "/dev", MAFTER); - - if((fd = connectlocalfossil()) < 0) - if((fd = connectlocalkfs()) < 0) - return -1; - return fd; -} diff --git a/sys/src/9/boot/local.rc b/sys/src/9/boot/local.rc new file mode 100644 index 000000000..8e696f6fa --- /dev/null +++ b/sys/src/9/boot/local.rc @@ -0,0 +1,72 @@ +#!/bin/rc + +cddevs=() + +# fill cddevs with cd or dvd devices +fn findcds{ + for(dev in /dev/sd*){ + x=`{sed '/([Cc][Dd]|[Dd][Vv][Dd])/!d' $dev/ctl >[2]/dev/null} + if(! ~ $#x 0) + cddevs=($cddevs $dev) + } +} + +fn configlocal{ + disk=`{echo $methodarg | sed 's,(.*)!.*,\1,g'} + fstype=`{echo $disk | sed 's,.*/(.*)$,\1,g'} + disk=`{echo $disk | sed 's,(.*)/.*$,\1,'} + + if(~ $pcload 1){ + kern=`{echo $methodarg | sed 's,.*!(.*)$,\1,g'} + + # for now we only allow kernels in the same dev/part of $methodargs + if(~ $#kern 0 || ! ~ $#bootfile 0) + kern=`{echo $bootfile | sed 's,.*!(.*)$,\1,g'} + } + + bind -a '#c' /dev >/dev/null >[2=1] + bind '#p' /proc >[2=1] >/dev/null >[2=1] + bind -a '#S' /dev >/dev/null >[2=1] + bind -a '#f' /dev >/dev/null >[2=1] + bind -a '#k' /dev >/dev/null >[2=1] + bind -a '#æ' /dev >/dev/null >[2=1] + + diskparts + findcds +} + +fn connectlocal{ + switch($fstype){ + case fossil + connectlocalfossil + case fs + connectlocalkfs + case data + # test for cd/dvd + x=`{sed '/([Cc][Dd]|[Dd][Vv][Dd])/!d' $disk^/ctl} + if(! ~ $#x 0) + must 9660srv -f $disk^/$fstype boot >/dev/null >[2=1] + case * + fatal unknown partition $fstype + } +} + +fn connectlocalfossil{ + if(! test -x /bin/fossil/fossil){ + echo no fossil + exit nofossil + } + + partition=$disk^/$fstype + + # settime(1, -1, nil) + + # make venti available + + # start fossil + echo 'fossil('$partition')...' + must fossil/fossil -f $partition -c 'srv -A boot' -c 'srv -p fscons' +} + + + diff --git a/sys/src/9/boot/menu.rc b/sys/src/9/boot/menu.rc new file mode 100644 index 000000000..c1f5242e1 --- /dev/null +++ b/sys/src/9/boot/menu.rc @@ -0,0 +1,134 @@ +#!/bin/rc + +conffile=/mnt/conf/plan9.ini +items=() + +fn menuitems{ +oifs=$ifs +ifs=' +' + # get menu items and save them in the form 'item\tstring' + x=(`{awk -F'\n' ' + $0 ~ /\[menu\]/ { + FS="[= ]" + for(nitem=1;;nitem++){ + getline + if(match($0, /\[/)) # if we entered a block, we are done + break + sub(/\,/, "") # remove comma + if(match($0, /^#/)) # comments + continue + if(match($0, /^$/)) # empty line + continue + printf("%s\t\" %d. ", $2, nitem) + for(i=3; i <= NF; i++) + printf("%s ", $i) + printf("\"\t\n") + } + } + ' $conffile}) + + ifs=' ' + for(itemline in $x){ + # separate item from string + item=`{echo $itemline(1)} + + # $menuitemtext holds the string for the item + $item(1)^text=$item(2) + items=($items $item(1)) + } + if(! ~ $#items 0){ + echo 'Plan 9 Startup Menu:' + echo '--------------------' + } + ifs=$oifs +} + +# load block definitions +fn menublock{ + for(i in `{ + awk -F'\n' -v item'='`{echo '['$1']' | sed 's/ //g'} ' + { + # find menuitem block + if(index($0, item)){ + for(;;){ + if(getline <= 0) + break + if(match($0, /\[/)) # entered a block, we are done + break + if(match($0, /^$/)) + continue + + # skip comments, quote kernel devices + if(index($0, "#") == 1) + continue + else + gsub("#", "''#''") + printf("%s\n", $1) + } + } + }' $conffile}){ + name=`{echo $i | awk -F'=' '{print $1}'} + val=`{echo $i | awk -F'=' '{print $2}'} + + # a name beginning with * denotes + # a kernel variable, save to #ec + v0=`{echo $i | sed 's/(\*).*/\1/'} + if(~ $v0 '*'){ + bind -bc '#ec' /env + eval $name'='$val + unmount '#ec' /env + } + if not + eval $name'='$val + } +} + +fn freevars{ + for(i in `{ + awk -F'\n' '{ + if(match($0, /\[/)) # entered a block, we are done + exit + if(match($0, /^$/)) + exit + # skip comments, quote kernel devices + if(index($0, "#") == 1) + exit + else + gsub("#", "''#''") + printf("%s\n", $1) + }' $conffile}){ + # a name beginning with * denotes + # a kernel variable, save to #ec + val=`{echo $i | sed 's/(\*).*/\1/'} + if(~ $val '*'){ + bind -bc '#ec' /env + eval $i + unmount '#ec' /env + } + if not eval $i + } +} + +fn parseconf{ + opt=0 + if(test -f $conffile){ + freevars + menuitems + menublock 'common' + + if(! ~ $#items 0){ + while(test $opt -lt 1 || test $opt -gt $#items){ + for(item in $items) + echo -n $`{echo $item^text} | sed 's/"//g' + + echo -n ' Selection: ' + opt=`{read} + + if(test $opt -ge 1 && test $opt -le $#items) + menublock $items($opt) + } + } + } +} + diff --git a/sys/src/9/boot/mkboot b/sys/src/9/boot/mkboot index 4502830dc..077a49d65 100755 --- a/sys/src/9/boot/mkboot +++ b/sys/src/9/boot/mkboot @@ -12,53 +12,6 @@ cat <<'---' #include <libc.h> #include "../boot/boot.h" -Method method[]={ ---- - -# -# configure all remote methods, i.e. all methods in the 'boot' section -# -# EXAMPLE -# boot -# incon -# 9600 -# 19200 -# -../port/mkextract boot 0 $* | awk '{ - printf " { \"" "" $1 "\", "\ - "config" $1 ", "\ - "connect" $1 ", " - print fieldn(2) " }," - } - - func fieldn(n, s,i) - { - s = $0 - while (n > 1) { - sub(/^[ \t]*/, "", s) - if (substr(s, 1, 1) == "\"") { - sub(/^"[^\"]*"/, "", s) - } else { - sub(/^[^ \t]*/, "", s) - } - n-- - } - sub(/^[ \t]*/, "", s) - if (substr(s, 1, 1) == "\"") { - i = index(substr(s, 2), "\"") - if (i > 0) - return substr(s, 1, i+1) - else - return s - } else { - sub(/[ \t].*/, "", s) - return s - } - }' - -cat <<'---' - { 0 }, -}; --- awk ' diff --git a/sys/src/9/boot/nopsession.c b/sys/src/9/boot/nopsession.c deleted file mode 100644 index 8893ac35d..000000000 --- a/sys/src/9/boot/nopsession.c +++ /dev/null @@ -1,52 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <auth.h> -#include <fcall.h> -#include "../boot/boot.h" - -static Fcall hdr; - -static void -rpc(int fd, int type) -{ - int n, l; - char buf[128], *p; - - hdr.type = type; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n) - fatal("write rpc"); - - print("..."); - p = buf; - l = 0; - while(l < 3) { - n = read(fd, p, 3); - if(n <= 0) - fatal("read rpc"); - if(n == 2 && l == 0 && buf[0] == 'O' && buf[1] == 'K') - continue; - p += n; - l += n; - } - if(convM2S(buf, &hdr, n) == 0){ - print("%ux %ux %ux\n", buf[0], buf[1], buf[2]); - fatal("rpc format"); - } - if(hdr.tag != NOTAG) - fatal("rpc tag not NOTAG"); - if(hdr.type == Rerror){ - print("error %s;", hdr.ename); - fatal("remote error"); - } - if(hdr.type != type+1) - fatal("not reply"); -} - -void -nop(int fd) -{ - print("nop"); - rpc(fd, Tnop); -} diff --git a/sys/src/9/boot/paq.c b/sys/src/9/boot/paq.c deleted file mode 100644 index 9536d78aa..000000000 --- a/sys/src/9/boot/paq.c +++ /dev/null @@ -1,67 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <../boot/boot.h> - -char *fparts[] = -{ - "add bootldr 0x0000000 0x0040000", - "add params 0x0040000 0x0080000", - "add kernel 0x0080000 0x0140000", - "add user 0x0140000 0x0200000", - "add ramdisk 0x0200000 0x0600000", -}; - -void -configpaq(Method*) -{ - int fd; - int i; - - if(bind("#F", "/dev", MAFTER) < 0) - fatal("bind #c"); - if(bind("#p", "/proc", MREPL) < 0) - fatal("bind #p"); - fd = open("/dev/flash/flashctl", OWRITE); - if(fd < 0) - fatal("opening flashctl"); - for(i = 0; i < nelem(fparts); i++) - if(fprint(fd, fparts[i]) < 0) - fatal(fparts[i]); - close(fd); -} - -int -connectpaq(void) -{ - int p[2]; - char **arg, **argp; - - print("paq..."); - if(pipe(p)<0) - fatal("pipe"); - switch(fork()){ - case -1: - fatal("fork"); - case 0: - arg = malloc(10*sizeof(char*)); - argp = arg; - *argp++ = "paqfs"; - *argp++ = "-v"; - *argp++ = "-i"; - *argp++ = "/dev/flash/ramdisk"; - *argp = 0; - - dup(p[0], 0); - dup(p[1], 1); - close(p[0]); - close(p[1]); - exec("/boot/paqfs", arg); - fatal("can't exec paqfs"); - default: - break; - } - waitpid(); - - close(p[1]); - return p[0]; -} diff --git a/sys/src/9/boot/sac.c b/sys/src/9/boot/sac.c deleted file mode 100644 index d7d6b6166..000000000 --- a/sys/src/9/boot/sac.c +++ /dev/null @@ -1,50 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <../boot/boot.h> - -/* - * HACK - take over from boot since file system is not - * available on a pipe - */ - -void -configsac(Method *mp) -{ - int fd; - char cmd[64]; - - USED(mp); - - /* - * create the name space, mount the root fs - */ - if(bind("/", "/", MREPL) < 0) - fatal("bind /"); - if(bind("#C", "/", MAFTER) < 0) - fatal("bind /"); - - /* fixed sysname - enables correct namespace file */ - fd = open("#c/sysname", OWRITE); - if(fd < 0) - fatal("open sysname"); - write(fd, "brick", 5); - close(fd); - - fd = open("#c/hostowner", OWRITE); - if(fd < 0) - fatal("open sysname"); - write(fd, "brick", 5); - close(fd); - - sprint(cmd, "/%s/init", cputype); - print("starting %s\n", cmd); - execl(cmd, "init", "-c", 0); - fatal(cmd); -} - -int -connectsac(void) -{ - /* does not get here */ - return -1; -} diff --git a/sys/src/9/boot/settime.c b/sys/src/9/boot/settime.c deleted file mode 100644 index d9be7585c..000000000 --- a/sys/src/9/boot/settime.c +++ /dev/null @@ -1,149 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <auth.h> -#include <fcall.h> -#include "../boot/boot.h" - -static long lusertime(char*); - -char *timeserver = "#s/boot"; - -void -settime(int islocal, int afd, char *rp) -{ - int n, f; - int timeset; - Dir dir[2]; - char timebuf[64]; - - print("time..."); - timeset = 0; - if(islocal){ - /* - * set the time from the real time clock - */ - f = open("#r/rtc", ORDWR); - if(f >= 0){ - if((n = read(f, timebuf, sizeof(timebuf)-1)) > 0){ - timebuf[n] = '\0'; - timeset = 1; - } - close(f); - }else do{ - strcpy(timebuf, "yymmddhhmm[ss]"); - outin("\ndate/time ", timebuf, sizeof(timebuf)); - }while((timeset=lusertime(timebuf)) <= 0); - } - if(timeset == 0){ - /* - * set the time from the access time of the root - */ - f = open(timeserver, ORDWR); - if(f < 0) - return; - if(mount(f, afd, "/tmp", MREPL, rp) < 0){ - warning("settime mount"); - close(f); - return; - } - close(f); - if(stat("/tmp", statbuf, sizeof statbuf) < 0) - fatal("stat"); - convM2D(statbuf, sizeof statbuf, &dir[0], (char*)&dir[1]); - sprint(timebuf, "%ld", dir[0].atime); - unmount(0, "/tmp"); - } - - f = open("#c/time", OWRITE); - if(write(f, timebuf, strlen(timebuf)) < 0) - warning("can't set #c/time"); - close(f); - print("\n"); -} - -#define SEC2MIN 60L -#define SEC2HOUR (60L*SEC2MIN) -#define SEC2DAY (24L*SEC2HOUR) - -int -g2(char **pp) -{ - int v; - - v = 10*((*pp)[0]-'0') + (*pp)[1]-'0'; - *pp += 2; - return v; -} - -/* - * days per month plus days/year - */ -static int dmsize[] = -{ - 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; -static int ldmsize[] = -{ - 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -/* - * return the days/month for the given year - */ -static int * -yrsize(int y) -{ - - if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0)) - return ldmsize; - else - return dmsize; -} - -/* - * compute seconds since Jan 1 1970 - */ -static long -lusertime(char *argbuf) -{ - char *buf; - ulong secs; - int i, y, m; - int *d2m; - - buf = argbuf; - i = strlen(buf); - if(i != 10 && i != 12) - return -1; - secs = 0; - y = g2(&buf); - m = g2(&buf); - if(y < 70) - y += 2000; - else - y += 1900; - - /* - * seconds per year - */ - for(i = 1970; i < y; i++){ - d2m = yrsize(i); - secs += d2m[0] * SEC2DAY; - } - - /* - * seconds per month - */ - d2m = yrsize(y); - for(i = 1; i < m; i++) - secs += d2m[i] * SEC2DAY; - - secs += (g2(&buf)-1) * SEC2DAY; - secs += g2(&buf) * SEC2HOUR; - secs += g2(&buf) * SEC2MIN; - if(*buf) - secs += g2(&buf); - - sprint(argbuf, "%ld", secs); - return secs; -} diff --git a/sys/src/9/boot/tcp.rc b/sys/src/9/boot/tcp.rc new file mode 100644 index 000000000..e8f45c6dd --- /dev/null +++ b/sys/src/9/boot/tcp.rc @@ -0,0 +1,61 @@ +#!/bin/rc + +fn isvalidip{ + # TODO: more precise test + if(! ~ $#1 0 && ! test `{echo $1 | sed '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/d'}) + echo -n +} + +fn configtcp{ + # TODO: + # should we accept a different mount point? + # should we add more interfaces? + + # bind in an ip interface + for(i in I l`{seq 0 3}) + bind -a '#'$i /net >/dev/null >[2=1] + + if(! test -x /bin/ip/ipconfig){ + echo no ipconfig + exit noipconfig + } + + ip/ipconfig # TODO: should receive args passed to boot(8) + + # XXX: should configuration from file override the values from ipconfig(8)? + if(~ $#fs 0){ + _fsip=`{grep fs /net/ndb | awk -F'=' '{print $2}' >/dev/null >[2=1]} + if(! ~ $#_fsip 0 && `{isvalidip $_fsip}) + fsip=$_fsip + } + + # if we didn't get a file and auth server from either + # the configuration file or ipconfig(8), ask the user + if(~ $#fsip 0){ + while(! isvalidip $fsip){ + echo -n 'filesystem IP address: ' + fsip=`{read} + } + } + + if(~ $#auth 0){ + _authip=`{grep auth /net/ndb | awk -F'=' '{print $2}' >/dev/null >[2=1]} + if(! ~ $#_authip 0 && `{isvalidip $_authip}) + authip=_authip + } + + if(~ $#authip 0){ + while(! isvalidip $authip){ + echo -n 'authentication server IP address: ' + authip=`{read} + } + } + + authaddr=tcp!$authip!567 # leave this for factotum(4) + + rm -f /env/_authip /env/_fsip +} + +fn connecttcp{ + srv -q tcp!$fsip!564 boot +} diff --git a/sys/src/9/boot/testboot.c b/sys/src/9/boot/testboot.c deleted file mode 100644 index 07333163b..000000000 --- a/sys/src/9/boot/testboot.c +++ /dev/null @@ -1,37 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <auth.h> - -void -usage(void) -{ - fprint(2, "usage: testboot cmd args...\n"); - exits("usage"); -} - -void -main(int argc, char **argv) -{ - int p[2]; - - if(argc == 1) - usage(); - - pipe(p); - switch(rfork(RFPROC|RFFDG|RFNAMEG)){ - case -1: - sysfatal("fork: %r"); - - case 0: - dup(p[0], 0); - dup(p[1], 1); - exec(argv[1], argv+1); - sysfatal("exec: %r"); - - default: - if(amount(p[0], "/n/kremvax", MREPL, "") < 0) - sysfatal("amount: %r"); - break; - } - exits(nil); -} diff --git a/sys/src/9/pc/mkfile b/sys/src/9/pc/mkfile index d61174062..632dd117a 100644 --- a/sys/src/9/pc/mkfile +++ b/sys/src/9/pc/mkfile @@ -79,6 +79,9 @@ $p$CONF: $CONF.c $OBJ $LIB $LD -o $target -T$KTZERO -l $OBJ $CONF.$O $LIB size $target +rootfs.bz2: + rc ../port/mkbootfs + # don't strip the gzipped kernels -- too frustrating when that's all you have! $p%.gz:D: $p% gzip -9 <$p$stem >$p$stem.gz diff --git a/sys/src/9/pc/pccd b/sys/src/9/pc/pccd index 0fbfbb599..76dc6afe9 100644 --- a/sys/src/9/pc/pccd +++ b/sys/src/9/pc/pccd @@ -125,6 +125,8 @@ boot boot #S/sdD0/data bootdir bootpccd.out boot - /386/bin/ip/ipconfig ipconfig - /386/bin/9660srv kfs - /386/bin/usb/usbd + /386/bin/auth/factotum + /386/bin/bzfs + /386/bin/echo + /386/bin/mntgen + rootfs.bz2 diff --git a/sys/src/9/pc/pcf b/sys/src/9/pc/pcf index 0bf8d9c98..3ce8b7ab4 100644 --- a/sys/src/9/pc/pcf +++ b/sys/src/9/pc/pcf @@ -130,8 +130,8 @@ boot boot #S/sdC0/ bootdir bootpcf.out boot - /386/bin/ip/ipconfig /386/bin/auth/factotum - /386/bin/fossil/fossil - /386/bin/venti/venti - /386/bin/usb/usbd + /386/bin/bzfs + /386/bin/echo + /386/bin/mntgen + rootfs.bz2 diff --git a/sys/src/9/port/portmkfile b/sys/src/9/port/portmkfile index 545376745..0253999d5 100644 --- a/sys/src/9/port/portmkfile +++ b/sys/src/9/port/portmkfile @@ -30,7 +30,7 @@ all:V: mk 'CONF='$i clean:V: - rm -f *.[$OS] *.root.s *.rootc.c cfs.h fs.h init.h conf.h *.out *.m errstr.h + rm -f *.[$OS] *.root.s *.rootc.c cfs.h fs.h init.h conf.h *.out *.m errstr.h rootfs.bz2 for(i in $CONFLIST $CRAPLIST) mk $i.clean |