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 <../boot/boot.h>
|
||||
|
||||
/*
|
||||
int
|
||||
plumb(char *dir, char *dest, int *efd, char *here)
|
||||
{
|
||||
char buf[128];
|
||||
char name[128];
|
||||
int n;
|
||||
|
||||
sprint(name, "%s/clone", dir);
|
||||
efd[0] = open(name, ORDWR);
|
||||
if(efd[0] < 0)
|
||||
return -1;
|
||||
n = read(efd[0], buf, sizeof(buf)-1);
|
||||
if(n < 0){
|
||||
close(efd[0]);
|
||||
return -1;
|
||||
}
|
||||
buf[n] = 0;
|
||||
sprint(name, "%s/%s/data", dir, buf);
|
||||
if(here){
|
||||
sprint(buf, "announce %s", here);
|
||||
if(sendmsg(efd[0], buf) < 0){
|
||||
close(efd[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
sprint(buf, "connect %s", dest);
|
||||
if(sendmsg(efd[0], buf) < 0){
|
||||
close(efd[0]);
|
||||
return -1;
|
||||
}
|
||||
efd[1] = open(name, ORDWR);
|
||||
if(efd[1] < 0){
|
||||
close(efd[0]);
|
||||
return -1;
|
||||
}
|
||||
return efd[1];
|
||||
}
|
||||
*/
|
||||
|
||||
int
|
||||
sendmsg(int fd, char *msg)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = strlen(msg);
|
||||
if(write(fd, msg, n) != n)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
warning(char *s)
|
||||
{
|
||||
char buf[ERRMAX];
|
||||
|
||||
buf[0] = '\0';
|
||||
errstr(buf, sizeof buf);
|
||||
fprint(2, "boot: %s: %s\n", s, buf);
|
||||
}
|
||||
|
||||
void
|
||||
fatal(char *s)
|
||||
{
|
||||
|
@ -90,6 +29,33 @@ readfile(char *name, char *buf, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
run(char *file, ...)
|
||||
{
|
||||
char buf[64];
|
||||
Waitmsg *w;
|
||||
int pid;
|
||||
|
||||
switch(pid = fork()){
|
||||
case -1:
|
||||
fatal("fork");
|
||||
case 0:
|
||||
exec(file, &file);
|
||||
snprint(buf, sizeof buf, "can't exec %s", file);
|
||||
fatal(buf);
|
||||
default:
|
||||
while((w = wait()) != nil)
|
||||
if(w->pid == pid)
|
||||
break;
|
||||
if(w == nil){
|
||||
snprint(buf, sizeof buf, "wait returned nil running %s", file);
|
||||
free(w);
|
||||
fatal(buf);
|
||||
}
|
||||
free(w);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
writefile(char *name, char *buf, int len)
|
||||
{
|
||||
|
@ -104,12 +70,12 @@ writefile(char *name, char *buf, int len)
|
|||
}
|
||||
|
||||
void
|
||||
setenv(char *name, char *val)
|
||||
setenv(char *name, char *val, int ec)
|
||||
{
|
||||
int f;
|
||||
char ename[64];
|
||||
|
||||
snprint(ename, sizeof ename, "#e/%s", name);
|
||||
snprint(ename, sizeof ename, "#e%s/%s", ec ? "c" : "", name);
|
||||
f = create(ename, 1, 0666);
|
||||
if(f < 0){
|
||||
fprint(2, "create %s: %r\n", ename);
|
||||
|
@ -142,41 +108,3 @@ srvcreate(char *name, int fd)
|
|||
close(f);
|
||||
}
|
||||
|
||||
void
|
||||
catchint(void *a, char *note)
|
||||
{
|
||||
USED(a);
|
||||
if(strcmp(note, "alarm") == 0)
|
||||
noted(NCONT);
|
||||
noted(NDFLT);
|
||||
}
|
||||
|
||||
int
|
||||
outin(char *prompt, char *def, int len)
|
||||
{
|
||||
int n;
|
||||
char buf[256];
|
||||
|
||||
if(len >= sizeof buf)
|
||||
len = sizeof(buf)-1;
|
||||
|
||||
if(cpuflag){
|
||||
notify(catchint);
|
||||
alarm(15*1000);
|
||||
}
|
||||
print("%s[%s]: ", prompt, *def ? def : "no default");
|
||||
memset(buf, 0, sizeof buf);
|
||||
n = read(0, buf, len);
|
||||
if(cpuflag){
|
||||
alarm(0);
|
||||
notify(0);
|
||||
}
|
||||
|
||||
if(n < 0)
|
||||
return 1;
|
||||
if(n > 1){
|
||||
buf[n-1] = 0;
|
||||
strcpy(def, buf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -5,43 +5,20 @@
|
|||
#include "../boot/boot.h"
|
||||
|
||||
char cputype[64];
|
||||
char sys[2*64];
|
||||
char reply[256];
|
||||
int printcol;
|
||||
int mflag;
|
||||
int fflag;
|
||||
int kflag;
|
||||
|
||||
char *bargv[Nbarg];
|
||||
int bargc;
|
||||
|
||||
static void swapproc(void);
|
||||
static Method *rootserver(char*);
|
||||
static void usbinit(void);
|
||||
static void kbmap(void);
|
||||
|
||||
void
|
||||
boot(int argc, char *argv[])
|
||||
{
|
||||
int fd, afd;
|
||||
Method *mp;
|
||||
char *cmd, cmdbuf[64], *iargv[16];
|
||||
char rootbuf[64];
|
||||
int islocal, ishybrid;
|
||||
char *rp, *rsp;
|
||||
int iargc, n;
|
||||
char buf[32];
|
||||
AuthInfo *ai;
|
||||
Waitmsg *w;
|
||||
int pid, i;
|
||||
|
||||
fmtinstall('r', errfmt);
|
||||
|
||||
/*
|
||||
* we should inherit the standard fds all referring to /dev/cons,
|
||||
* but we're being paranoid.
|
||||
*/
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
bind("#c", "/dev", MBEFORE);
|
||||
open("/dev/cons", OREAD);
|
||||
open("/dev/cons", OWRITE);
|
||||
|
@ -53,12 +30,13 @@ boot(int argc, char *argv[])
|
|||
bind("#ec", "/env", MREPL);
|
||||
bind("#e", "/env", MBEFORE|MCREATE);
|
||||
bind("#s", "/srv", MREPL|MCREATE);
|
||||
#ifdef DEBUG
|
||||
print("argc=%d\n", argc);
|
||||
for(fd = 0; fd < argc; fd++)
|
||||
print("%#p %s ", argv[fd], argv[fd]);
|
||||
print("\n");
|
||||
#endif DEBUG
|
||||
|
||||
if(Debug){
|
||||
print("argc=%d\n", argc);
|
||||
for(i = 0; i < argc; i++)
|
||||
print("%lux %s ", (ulong)argv[i], argv[i]);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
ARGBEGIN{
|
||||
case 'k':
|
||||
|
@ -73,281 +51,35 @@ boot(int argc, char *argv[])
|
|||
}ARGEND
|
||||
|
||||
readfile("#e/cputype", cputype, sizeof(cputype));
|
||||
|
||||
/*
|
||||
* set up usb keyboard, mouse and disk, if any.
|
||||
*/
|
||||
usbinit();
|
||||
|
||||
/*
|
||||
* pick a method and initialize it
|
||||
*/
|
||||
if(method[0].name == nil)
|
||||
fatal("no boot methods");
|
||||
mp = rootserver(argc ? *argv : 0);
|
||||
(*mp->config)(mp);
|
||||
islocal = strcmp(mp->name, "local") == 0;
|
||||
ishybrid = strcmp(mp->name, "hybrid") == 0;
|
||||
|
||||
/*
|
||||
* load keymap if it's there.
|
||||
*/
|
||||
kbmap();
|
||||
|
||||
/*
|
||||
* authentication agent
|
||||
*/
|
||||
authentication(cpuflag);
|
||||
|
||||
/*
|
||||
* connect to the root file system
|
||||
*/
|
||||
fd = (*mp->connect)();
|
||||
if(fd < 0)
|
||||
fatal("can't connect to file server");
|
||||
if(getenv("srvold9p"))
|
||||
fd = old9p(fd);
|
||||
if(!islocal && !ishybrid){
|
||||
if(cfs)
|
||||
fd = (*cfs)(fd);
|
||||
}
|
||||
print("version...");
|
||||
buf[0] = '\0';
|
||||
n = fversion(fd, 0, buf, sizeof buf);
|
||||
if(n < 0)
|
||||
fatal("can't init 9P");
|
||||
srvcreate("boot", fd);
|
||||
|
||||
/*
|
||||
* create the name space, mount the root fs
|
||||
*/
|
||||
if(bind("/", "/", MREPL) < 0)
|
||||
fatal("bind /");
|
||||
rp = getenv("rootspec");
|
||||
if(rp == nil)
|
||||
rp = "";
|
||||
setenv("bootdisk", bootdisk, 0);
|
||||
|
||||
afd = fauth(fd, rp);
|
||||
if(afd >= 0){
|
||||
ai = auth_proxy(afd, auth_getkey, "proto=p9any role=client");
|
||||
if(ai == nil)
|
||||
print("authentication failed (%r), trying mount anyways\n");
|
||||
}
|
||||
if(mount(fd, afd, "/root", MREPL|MCREATE, rp) < 0)
|
||||
fatal("mount /");
|
||||
rsp = rp;
|
||||
rp = getenv("rootdir");
|
||||
if(rp == nil)
|
||||
rp = rootdir;
|
||||
if(bind(rp, "/", MAFTER|MCREATE) < 0){
|
||||
if(strncmp(rp, "/root", 5) == 0){
|
||||
fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp);
|
||||
fatal("second bind /");
|
||||
}
|
||||
snprint(rootbuf, sizeof rootbuf, "/root/%s", rp);
|
||||
rp = rootbuf;
|
||||
if(bind(rp, "/", MAFTER|MCREATE) < 0){
|
||||
fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp);
|
||||
if(strcmp(rootbuf, "/root//plan9") == 0){
|
||||
fprint(2, "**** warning: remove rootdir=/plan9 entry from plan9.ini\n");
|
||||
rp = "/root";
|
||||
if(bind(rp, "/", MAFTER|MCREATE) < 0)
|
||||
fatal("second bind /");
|
||||
}else
|
||||
fatal("second bind /");
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
setenv("rootdir", rp);
|
||||
/* 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]);
|
||||
}
|
||||
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;
|
||||
while((w = wait()) != nil)
|
||||
if(w->pid == pid)
|
||||
break;
|
||||
if(w == nil){
|
||||
free(w);
|
||||
fatal("wait error");
|
||||
}
|
||||
close(in);
|
||||
close(out);
|
||||
free(w);
|
||||
break;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,73 +1,18 @@
|
|||
typedef struct Method Method;
|
||||
struct Method
|
||||
{
|
||||
char *name;
|
||||
void (*config)(Method*);
|
||||
int (*connect)(void);
|
||||
char *arg;
|
||||
};
|
||||
enum
|
||||
{
|
||||
Statsz= 256,
|
||||
Nbarg= 16,
|
||||
enum {
|
||||
Debug = 0,
|
||||
};
|
||||
|
||||
extern void authentication(int);
|
||||
extern char* bootdisk;
|
||||
extern char* rootdir;
|
||||
extern int (*cfs)(int);
|
||||
extern int cpuflag;
|
||||
extern char cputype[];
|
||||
extern int fflag;
|
||||
extern int kflag;
|
||||
extern Method method[];
|
||||
extern void (*pword)(int, Method*);
|
||||
extern char sys[];
|
||||
extern uchar hostkey[];
|
||||
extern uchar statbuf[Statsz];
|
||||
extern int bargc;
|
||||
extern char *bargv[Nbarg];
|
||||
extern int pcload;
|
||||
extern int (*cfs)(int);
|
||||
extern int cpuflag;
|
||||
extern char cputype[];
|
||||
extern int fflag;
|
||||
extern int kflag;
|
||||
|
||||
/* libc equivalent */
|
||||
extern int cache(int);
|
||||
extern char* checkkey(Method*, char*, char*);
|
||||
extern void fatal(char*);
|
||||
extern void getpasswd(char*, int);
|
||||
extern void key(int, Method*);
|
||||
extern int outin(char*, char*, int);
|
||||
extern int plumb(char*, char*, int*, char*);
|
||||
extern void fatal(char*);
|
||||
extern int readfile(char*, char*, int);
|
||||
extern long readn(int, void*, long);
|
||||
extern void run(char *file, ...);
|
||||
extern int sendmsg(int, char*);
|
||||
extern void setenv(char*, char*);
|
||||
extern void settime(int, int, char*);
|
||||
extern void srvcreate(char*, int);
|
||||
extern void warning(char*);
|
||||
extern void run(char*, ...);
|
||||
extern void setenv(char*, char*, int);
|
||||
extern int writefile(char*, char*, int);
|
||||
extern void boot(int, char **);
|
||||
extern void doauthenticate(int, Method*);
|
||||
extern int old9p(int);
|
||||
extern int parsefields(char*, char**, int, char*);
|
||||
|
||||
/* methods */
|
||||
extern void configtcp(Method*);
|
||||
extern int connecttcp(void);
|
||||
|
||||
extern void configlocal(Method*);
|
||||
extern int connectlocal(void);
|
||||
|
||||
extern void configsac(Method*);
|
||||
extern int connectsac(void);
|
||||
|
||||
extern void configpaq(Method*);
|
||||
extern int connectpaq(void);
|
||||
|
||||
extern void configembed(Method*);
|
||||
extern int connectembed(void);
|
||||
|
||||
extern void configip(int, char**, int);
|
||||
|
||||
/* hack for passing authentication address */
|
||||
extern char *authaddr;
|
||||
|
|
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
|
|
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 "../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 '
|
||||
|
|
|
@ -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
|
||||
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
|
||||
|
|
|
@ -125,6 +125,8 @@ boot boot #S/sdD0/data
|
|||
|
||||
bootdir
|
||||
bootpccd.out boot
|
||||
/386/bin/ip/ipconfig ipconfig
|
||||
/386/bin/9660srv kfs
|
||||
/386/bin/usb/usbd
|
||||
/386/bin/auth/factotum
|
||||
/386/bin/bzfs
|
||||
/386/bin/echo
|
||||
/386/bin/mntgen
|
||||
rootfs.bz2
|
||||
|
|
|
@ -130,8 +130,8 @@ boot boot #S/sdC0/
|
|||
|
||||
bootdir
|
||||
bootpcf.out boot
|
||||
/386/bin/ip/ipconfig
|
||||
/386/bin/auth/factotum
|
||||
/386/bin/fossil/fossil
|
||||
/386/bin/venti/venti
|
||||
/386/bin/usb/usbd
|
||||
/386/bin/bzfs
|
||||
/386/bin/echo
|
||||
/386/bin/mntgen
|
||||
rootfs.bz2
|
||||
|
|
|
@ -30,7 +30,7 @@ all:V:
|
|||
mk 'CONF='$i
|
||||
|
||||
clean:V:
|
||||
rm -f *.[$OS] *.root.s *.rootc.c cfs.h fs.h init.h conf.h *.out *.m errstr.h
|
||||
rm -f *.[$OS] *.root.s *.rootc.c cfs.h fs.h init.h conf.h *.out *.m errstr.h rootfs.bz2
|
||||
for(i in $CONFLIST $CRAPLIST)
|
||||
mk $i.clean
|
||||
|
||||
|
|
Loading…
Reference in a new issue