ref: 478d1024433f8713927729f02285682af0e0cf9b
parent: 4d4fc2ca3453a4deb79b26eb62449eab94b86827
author: iru <devnull@localhost>
date: Sat Apr 16 13:42:16 EDT 2011
Initial import of the new boot(8). Change pccd and pcf to use it.
--- a/sys/src/9/boot/aux.c
+++ b/sys/src/9/boot/aux.c
@@ -2,68 +2,7 @@
#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)
{
char buf[ERRMAX];
@@ -90,6 +29,33 @@
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 @@
}
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 @@
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;
-}
--- a/sys/src/9/boot/boot.c
+++ b/sys/src/9/boot/boot.c
@@ -5,7 +5,6 @@
#include "../boot/boot.h"
char cputype[64];
-char sys[2*64];
char reply[256];
int printcol;
int mflag;
@@ -12,36 +11,14 @@
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,13 +30,14 @@
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':
kflag = 1;
@@ -73,281 +51,35 @@
}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);
+ /* 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);
- 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()) {
+ 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]);
+ while((w = wait()) != nil)
+ if(w->pid == pid)
+ break;
+ if(w == nil){
+ free(w);
+ fatal("wait error");
+ }
+ free(w);
+ break;
}
- 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;
- }
-
- 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(;;)
+ ;
}
--- 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 {
+ Debug = 0,
};
-enum
-{
- Statsz= 256,
- Nbarg= 16,
-};
-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;
--- a/sys/src/9/boot/bootauth.c
+++ /dev/null
@@ -1,72 +1,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);
- }
-}
--- a/sys/src/9/boot/bootcache.c
+++ /dev/null
@@ -1,80 +1,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;
-}
--- a/sys/src/9/boot/bootip.c
+++ /dev/null
@@ -1,203 +1,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;
-}
--- a/sys/src/9/boot/bootmkfile
+++ b/sys/src/9/boot/bootmkfile
@@ -2,17 +2,8 @@
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
--- /dev/null
+++ b/sys/src/9/boot/bootrc
@@ -1,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
+
+
--- /dev/null
+++ b/sys/src/9/boot/conf.rc
@@ -1,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
+}
--- a/sys/src/9/boot/doauthenticate.c
+++ /dev/null
@@ -1,126 +1,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";
-}
--- a/sys/src/9/boot/embed.c
+++ /dev/null
@@ -1,74 +1,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];
-}
--- a/sys/src/9/boot/getpasswd.c
+++ /dev/null
@@ -1,43 +1,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;
- }
- }
-}
--- a/sys/src/9/boot/local.c
+++ /dev/null
@@ -1,275 +1,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;
-}
--- /dev/null
+++ b/sys/src/9/boot/local.rc
@@ -1,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'
+}
+
+
+
--- /dev/null
+++ b/sys/src/9/boot/menu.rc
@@ -1,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)
+ }
+ }
+ }
+}
+
--- a/sys/src/9/boot/mkboot
+++ b/sys/src/9/boot/mkboot
@@ -12,53 +12,6 @@
#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 '
--- a/sys/src/9/boot/nopsession.c
+++ /dev/null
@@ -1,52 +1,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);
-}
--- a/sys/src/9/boot/paq.c
+++ /dev/null
@@ -1,67 +1,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];
-}
--- a/sys/src/9/boot/sac.c
+++ /dev/null
@@ -1,50 +1,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;
-}
--- a/sys/src/9/boot/settime.c
+++ /dev/null
@@ -1,149 +1,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;
-}
--- /dev/null
+++ b/sys/src/9/boot/tcp.rc
@@ -1,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
+}
--- a/sys/src/9/boot/testboot.c
+++ /dev/null
@@ -1,37 +1,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);
-}
--- a/sys/src/9/pc/mkfile
+++ b/sys/src/9/pc/mkfile
@@ -79,6 +79,9 @@
$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
--- a/sys/src/9/pc/pccd
+++ b/sys/src/9/pc/pccd
@@ -125,6 +125,8 @@
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
--- a/sys/src/9/pc/pcf
+++ b/sys/src/9/pc/pcf
@@ -130,8 +130,8 @@
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
--- a/sys/src/9/port/portmkfile
+++ b/sys/src/9/port/portmkfile
@@ -30,7 +30,7 @@
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