Initial import of the new boot(8). Change pccd and pcf to use it.
This commit is contained in:
parent
4d4fc2ca34
commit
478d102443
26 changed files with 586 additions and 1760 deletions
|
@ -2,67 +2,6 @@
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <../boot/boot.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
|
void
|
||||||
fatal(char *s)
|
fatal(char *s)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +29,33 @@ readfile(char *name, char *buf, int len)
|
||||||
return 0;
|
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
|
int
|
||||||
writefile(char *name, char *buf, int len)
|
writefile(char *name, char *buf, int len)
|
||||||
{
|
{
|
||||||
|
@ -104,12 +70,12 @@ writefile(char *name, char *buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setenv(char *name, char *val)
|
setenv(char *name, char *val, int ec)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
char ename[64];
|
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);
|
f = create(ename, 1, 0666);
|
||||||
if(f < 0){
|
if(f < 0){
|
||||||
fprint(2, "create %s: %r\n", ename);
|
fprint(2, "create %s: %r\n", ename);
|
||||||
|
@ -142,41 +108,3 @@ srvcreate(char *name, int fd)
|
||||||
close(f);
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,43 +5,20 @@
|
||||||
#include "../boot/boot.h"
|
#include "../boot/boot.h"
|
||||||
|
|
||||||
char cputype[64];
|
char cputype[64];
|
||||||
char sys[2*64];
|
|
||||||
char reply[256];
|
char reply[256];
|
||||||
int printcol;
|
int printcol;
|
||||||
int mflag;
|
int mflag;
|
||||||
int fflag;
|
int fflag;
|
||||||
int kflag;
|
int kflag;
|
||||||
|
|
||||||
char *bargv[Nbarg];
|
|
||||||
int bargc;
|
|
||||||
|
|
||||||
static void swapproc(void);
|
|
||||||
static Method *rootserver(char*);
|
|
||||||
static void usbinit(void);
|
|
||||||
static void kbmap(void);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
boot(int argc, char *argv[])
|
boot(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int fd, afd;
|
Waitmsg *w;
|
||||||
Method *mp;
|
int pid, i;
|
||||||
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);
|
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);
|
bind("#c", "/dev", MBEFORE);
|
||||||
open("/dev/cons", OREAD);
|
open("/dev/cons", OREAD);
|
||||||
open("/dev/cons", OWRITE);
|
open("/dev/cons", OWRITE);
|
||||||
|
@ -53,12 +30,13 @@ boot(int argc, char *argv[])
|
||||||
bind("#ec", "/env", MREPL);
|
bind("#ec", "/env", MREPL);
|
||||||
bind("#e", "/env", MBEFORE|MCREATE);
|
bind("#e", "/env", MBEFORE|MCREATE);
|
||||||
bind("#s", "/srv", MREPL|MCREATE);
|
bind("#s", "/srv", MREPL|MCREATE);
|
||||||
#ifdef DEBUG
|
|
||||||
|
if(Debug){
|
||||||
print("argc=%d\n", argc);
|
print("argc=%d\n", argc);
|
||||||
for(fd = 0; fd < argc; fd++)
|
for(i = 0; i < argc; i++)
|
||||||
print("%#p %s ", argv[fd], argv[fd]);
|
print("%lux %s ", (ulong)argv[i], argv[i]);
|
||||||
print("\n");
|
print("\n");
|
||||||
#endif DEBUG
|
}
|
||||||
|
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
case 'k':
|
case 'k':
|
||||||
|
@ -73,281 +51,35 @@ boot(int argc, char *argv[])
|
||||||
}ARGEND
|
}ARGEND
|
||||||
|
|
||||||
readfile("#e/cputype", cputype, sizeof(cputype));
|
readfile("#e/cputype", cputype, sizeof(cputype));
|
||||||
|
setenv("bootdisk", bootdisk, 0);
|
||||||
|
|
||||||
/*
|
/* setup the boot namespace */
|
||||||
* set up usb keyboard, mouse and disk, if any.
|
run("/boot/mntgen", "-s", "slash", "/mnt", nil);
|
||||||
*/
|
run("/boot/bzfs", "-f", "/boot/rootfs.bz2", "-m", "/mnt/broot", nil);
|
||||||
usbinit();
|
bind("/mnt/broot", "/", MAFTER);
|
||||||
|
bind("/386/bin", "/bin", MAFTER);
|
||||||
|
bind("/rc/bin", "/bin", MAFTER);
|
||||||
|
bind("/boot", "/bin", MAFTER);
|
||||||
|
|
||||||
/*
|
switch(pid = rfork(RFFDG|RFREND|RFPROC)){
|
||||||
* 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 = "";
|
|
||||||
|
|
||||||
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:
|
case -1:
|
||||||
fatal("rfork srvold9p");
|
fatal("fork error");
|
||||||
case 0:
|
case 0:
|
||||||
dup(fd, 1);
|
setenv("cpuflag", cpuflag ? "1" : "0", 0);
|
||||||
close(fd);
|
run("/bin/rc", "/rc/bin/bootrc", nil);
|
||||||
dup(p[0], 0);
|
break;
|
||||||
close(p[0]);
|
|
||||||
close(p[1]);
|
|
||||||
execl("/srvold9p", "srvold9p", "-s", 0);
|
|
||||||
fatal("exec srvold9p");
|
|
||||||
default:
|
default:
|
||||||
close(fd);
|
while((w = wait()) != nil)
|
||||||
close(p[0]);
|
if(w->pid == pid)
|
||||||
|
break;
|
||||||
|
if(w == nil){
|
||||||
|
free(w);
|
||||||
|
fatal("wait error");
|
||||||
}
|
}
|
||||||
return p[1];
|
free(w);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
close(in);
|
|
||||||
close(out);
|
for(;;)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
typedef struct Method Method;
|
enum {
|
||||||
struct Method
|
Debug = 0,
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
void (*config)(Method*);
|
|
||||||
int (*connect)(void);
|
|
||||||
char *arg;
|
|
||||||
};
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
Statsz= 256,
|
|
||||||
Nbarg= 16,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void authentication(int);
|
|
||||||
extern char* bootdisk;
|
extern char* bootdisk;
|
||||||
extern char* rootdir;
|
extern char* rootdir;
|
||||||
extern int (*cfs)(int);
|
extern int (*cfs)(int);
|
||||||
|
@ -20,54 +9,10 @@ extern int cpuflag;
|
||||||
extern char cputype[];
|
extern char cputype[];
|
||||||
extern int fflag;
|
extern int fflag;
|
||||||
extern int kflag;
|
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;
|
|
||||||
|
|
||||||
/* libc equivalent */
|
|
||||||
extern int cache(int);
|
|
||||||
extern char* checkkey(Method*, char*, char*);
|
|
||||||
extern void fatal(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 int readfile(char*, char*, int);
|
extern int readfile(char*, char*, int);
|
||||||
extern long readn(int, void*, long);
|
extern void run(char*, ...);
|
||||||
extern void run(char *file, ...);
|
extern void setenv(char*, char*, int);
|
||||||
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 int writefile(char*, char*, int);
|
extern int writefile(char*, char*, int);
|
||||||
extern void boot(int, char **);
|
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;
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -2,17 +2,8 @@ BOOTDIR=../boot
|
||||||
BOOTLIB=$BOOTDIR/libboot.a$O
|
BOOTLIB=$BOOTDIR/libboot.a$O
|
||||||
|
|
||||||
BOOTFILES=\
|
BOOTFILES=\
|
||||||
bootauth.$O\
|
|
||||||
aux.$O\
|
aux.$O\
|
||||||
boot.$O\
|
boot.$O\
|
||||||
bootcache.$O\
|
|
||||||
bootip.$O\
|
|
||||||
local.$O\
|
|
||||||
embed.$O\
|
|
||||||
settime.$O\
|
|
||||||
sac.$O\
|
|
||||||
paq.$O\
|
|
||||||
printstub.$O\
|
|
||||||
|
|
||||||
$BOOTLIB(%.$O):N: %.$O
|
$BOOTLIB(%.$O):N: %.$O
|
||||||
|
|
||||||
|
|
183
sys/src/9/boot/bootrc
Normal file
183
sys/src/9/boot/bootrc
Normal file
|
@ -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
|
||||||
|
|
||||||
|
|
50
sys/src/9/boot/conf.rc
Normal file
50
sys/src/9/boot/conf.rc
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -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";
|
|
||||||
}
|
|
|
@ -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];
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
72
sys/src/9/boot/local.rc
Normal file
72
sys/src/9/boot/local.rc
Normal file
|
@ -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'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
134
sys/src/9/boot/menu.rc
Normal file
134
sys/src/9/boot/menu.rc
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,53 +12,6 @@ cat <<'---'
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "../boot/boot.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 '
|
awk '
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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];
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
61
sys/src/9/boot/tcp.rc
Normal file
61
sys/src/9/boot/tcp.rc
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -79,6 +79,9 @@ $p$CONF: $CONF.c $OBJ $LIB
|
||||||
$LD -o $target -T$KTZERO -l $OBJ $CONF.$O $LIB
|
$LD -o $target -T$KTZERO -l $OBJ $CONF.$O $LIB
|
||||||
size $target
|
size $target
|
||||||
|
|
||||||
|
rootfs.bz2:
|
||||||
|
rc ../port/mkbootfs
|
||||||
|
|
||||||
# don't strip the gzipped kernels -- too frustrating when that's all you have!
|
# don't strip the gzipped kernels -- too frustrating when that's all you have!
|
||||||
$p%.gz:D: $p%
|
$p%.gz:D: $p%
|
||||||
gzip -9 <$p$stem >$p$stem.gz
|
gzip -9 <$p$stem >$p$stem.gz
|
||||||
|
|
|
@ -125,6 +125,8 @@ boot boot #S/sdD0/data
|
||||||
|
|
||||||
bootdir
|
bootdir
|
||||||
bootpccd.out boot
|
bootpccd.out boot
|
||||||
/386/bin/ip/ipconfig ipconfig
|
/386/bin/auth/factotum
|
||||||
/386/bin/9660srv kfs
|
/386/bin/bzfs
|
||||||
/386/bin/usb/usbd
|
/386/bin/echo
|
||||||
|
/386/bin/mntgen
|
||||||
|
rootfs.bz2
|
||||||
|
|
|
@ -130,8 +130,8 @@ boot boot #S/sdC0/
|
||||||
|
|
||||||
bootdir
|
bootdir
|
||||||
bootpcf.out boot
|
bootpcf.out boot
|
||||||
/386/bin/ip/ipconfig
|
|
||||||
/386/bin/auth/factotum
|
/386/bin/auth/factotum
|
||||||
/386/bin/fossil/fossil
|
/386/bin/bzfs
|
||||||
/386/bin/venti/venti
|
/386/bin/echo
|
||||||
/386/bin/usb/usbd
|
/386/bin/mntgen
|
||||||
|
rootfs.bz2
|
||||||
|
|
|
@ -30,7 +30,7 @@ all:V:
|
||||||
mk 'CONF='$i
|
mk 'CONF='$i
|
||||||
|
|
||||||
clean:V:
|
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)
|
for(i in $CONFLIST $CRAPLIST)
|
||||||
mk $i.clean
|
mk $i.clean
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue