123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- #include <u.h>
- #include <libc.h>
- #include <auth.h>
- #include <fcall.h>
- #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 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;
- fmtinstall('r', errfmt);
- bind("#c", "/dev", MBEFORE);
- open("/dev/cons", OREAD);
- open("/dev/cons", OWRITE);
- open("/dev/cons", OWRITE);
- /*
- * init will reinitialize its namespace.
- * #ec gets us plan9.ini settings (*var variables).
- */
- 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("%lux %s ", argv[fd], argv[fd]);
- print("\n");
- #endif DEBUG
- ARGBEGIN{
- case 'k':
- kflag = 1;
- break;
- case 'm':
- mflag = 1;
- break;
- case 'f':
- fflag = 1;
- break;
- }ARGEND
- readfile("#e/cputype", cputype, sizeof(cputype));
- /*
- * 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 its 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 = "";
-
- 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()) {
- case -1:
- fatal("rfork srvold9p");
- 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");
- default:
- close(fd);
- close(p[0]);
- }
- return p[1];
- }
- static void
- kbmap(void)
- {
- char *f;
- int in, out;
- int n;
- char buf[1024];
- f = getenv("kbmap");
- if(f == nil)
- return;
- in = open(f, OREAD);
- if(in < 0){
- warning("can't open kbd map");
- return;
- }
- if(bind("#κ", "/dev", MAFTER) < 0){
- warning("can't bind #κ");
- close(in);
- return;
- }
- out = open("/dev/kbmap", OWRITE);
- if(out < 0){
- warning("can't open /dev/kbmap");
- close(out);
- 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);
- }
|