2016-11-25 17:18:40 +01:00
|
|
|
|
/*
|
|
|
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
|
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
|
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
|
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
|
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
|
|
|
* in the LICENSE file.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <u.h>
|
|
|
|
|
#include <libc.h>
|
2017-10-20 00:55:05 +02:00
|
|
|
|
#include <envvars.h>
|
2016-11-25 17:18:40 +01:00
|
|
|
|
#include <auth.h>
|
2016-12-01 00:09:42 +01:00
|
|
|
|
#include <9P2000.h>
|
2016-11-25 17:18:40 +01:00
|
|
|
|
#include "../boot/boot.h"
|
|
|
|
|
|
|
|
|
|
char cputype[64];
|
|
|
|
|
char sys[2*64];
|
|
|
|
|
int printcol;
|
|
|
|
|
int mflag;
|
|
|
|
|
int fflag;
|
|
|
|
|
int kflag;
|
|
|
|
|
|
|
|
|
|
char *bargv[Nbarg];
|
|
|
|
|
int bargc;
|
|
|
|
|
|
|
|
|
|
static Method *rootserver(char*);
|
|
|
|
|
static void usbinit(void);
|
|
|
|
|
static int startconsole(void);
|
|
|
|
|
static int startcomconsole(void);
|
|
|
|
|
static void bindBoot(void);
|
|
|
|
|
static void unbindBoot(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;
|
|
|
|
|
|
|
|
|
|
open("/dev/cons", OREAD);
|
|
|
|
|
open("/dev/cons", OWRITE);
|
|
|
|
|
open("/dev/cons", OWRITE);
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_fmtinstall('r', jehanne_errfmt);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
|
|
bindBoot();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* start /dev/cons
|
|
|
|
|
*/
|
2017-08-13 15:24:18 +02:00
|
|
|
|
if(readfile("#ec/bootconsole", buf, sizeof(buf)) >= 0
|
2017-04-19 23:33:14 +02:00
|
|
|
|
&& jehanne_strcmp("comconsole", buf) == 0){
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(startcomconsole() < 0)
|
|
|
|
|
fatal("no console found");
|
2017-02-04 01:04:51 +01:00
|
|
|
|
} else if(startconsole() < 0){
|
|
|
|
|
if(startcomconsole() < 0)
|
|
|
|
|
fatal("no console found");
|
|
|
|
|
}
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* init will reinitialize its namespace.
|
|
|
|
|
* #ec gets us plan9.ini settings (*var variables).
|
|
|
|
|
*/
|
|
|
|
|
bind("#ec", "/env", MREPL);
|
|
|
|
|
bind("#e", "/env", MBEFORE|MCREATE);
|
|
|
|
|
bind("#s", "/srv", MREPL|MCREATE);
|
|
|
|
|
bind("#p", "/proc", MREPL|MCREATE);
|
|
|
|
|
bind("#σ", "/shr", MREPL);
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("Diex vos sait! Je m'appelle Jehanne O:-)\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
#ifdef DEBUG
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("argc=%d\n", argc);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
for(fd = 0; fd < argc; fd++)
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("%#p %s ", argv[fd], argv[fd]);
|
|
|
|
|
jehanne_print("\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
#endif //DEBUG
|
|
|
|
|
|
|
|
|
|
ARGBEGIN{
|
|
|
|
|
case 'k':
|
|
|
|
|
kflag = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'm':
|
|
|
|
|
mflag = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
fflag = 1;
|
|
|
|
|
break;
|
|
|
|
|
}ARGEND
|
2017-10-22 13:22:37 +02:00
|
|
|
|
readfile("#e/" ENV_CPUTYPE, cputype, sizeof(cputype));
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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);
|
2017-04-19 23:33:14 +02:00
|
|
|
|
islocal = jehanne_strcmp(mp->name, "local") == 0;
|
|
|
|
|
ishybrid = jehanne_strcmp(mp->name, "hybrid") == 0;
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* load keymap if it is there.
|
|
|
|
|
*/
|
|
|
|
|
kbmap();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* authentication agent
|
|
|
|
|
*/
|
|
|
|
|
authentication(cpuflag);
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("connect...");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
/*
|
|
|
|
|
* connect to the root file system
|
|
|
|
|
*/
|
|
|
|
|
fd = (*mp->connect)();
|
|
|
|
|
if(fd < 0)
|
|
|
|
|
fatal("can't connect to file server");
|
|
|
|
|
if(!islocal && !ishybrid){
|
|
|
|
|
if(cfs)
|
|
|
|
|
fd = (*cfs)(fd);
|
|
|
|
|
}
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("version...");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
n = fversion(fd, 0, buf, sizeof buf);
|
|
|
|
|
if(n < 0)
|
|
|
|
|
fatal("can't init 9P");
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_access("#s/boot", AEXIST) < 0)
|
2016-11-25 17:18:40 +01:00
|
|
|
|
srvcreate("boot", fd);
|
|
|
|
|
|
|
|
|
|
unbindBoot();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* create the name space, mount the root fs
|
|
|
|
|
*/
|
|
|
|
|
if(bind("/", "/", MREPL) < 0)
|
|
|
|
|
fatal("bind /");
|
2017-04-19 23:33:14 +02:00
|
|
|
|
rp = jehanne_getenv("rootspec");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(rp == nil)
|
|
|
|
|
rp = "";
|
|
|
|
|
|
|
|
|
|
afd = fauth(fd, rp);
|
|
|
|
|
if(afd >= 0){
|
|
|
|
|
ai = auth_proxy(afd, auth_getkey, "proto=p9any role=client");
|
|
|
|
|
if(ai == nil)
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("authentication failed (%r), trying mount anyways\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
}
|
2016-12-01 00:09:42 +01:00
|
|
|
|
if(mount(fd, afd, "/root", MREPL|MCREATE, rp, '9') < 0)
|
2016-11-25 17:18:40 +01:00
|
|
|
|
fatal("mount /");
|
|
|
|
|
rsp = rp;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
rp = jehanne_getenv("rootdir");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(rp == nil)
|
|
|
|
|
rp = rootdir;
|
|
|
|
|
if(bind(rp, "/", MAFTER|MCREATE) < 0){
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_strncmp(rp, "/root", 5) == 0){
|
|
|
|
|
jehanne_fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
fatal("second bind /");
|
|
|
|
|
}
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_snprint(rootbuf, sizeof rootbuf, "/root/%s", rp);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
rp = rootbuf;
|
|
|
|
|
if(bind(rp, "/", MAFTER|MCREATE) < 0){
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp);
|
|
|
|
|
if(jehanne_strcmp(rootbuf, "/root//plan9") == 0){
|
|
|
|
|
jehanne_fprint(2, "**** warning: remove rootdir=/plan9 entry from plan9.ini\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
rp = "/root";
|
|
|
|
|
if(bind(rp, "/", MAFTER|MCREATE) < 0)
|
|
|
|
|
fatal("second bind /");
|
|
|
|
|
}else
|
|
|
|
|
fatal("second bind /");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
setenv("rootdir", rp);
|
|
|
|
|
|
|
|
|
|
savelogs();
|
|
|
|
|
|
|
|
|
|
settime(islocal, afd, rsp);
|
|
|
|
|
if(afd > 0)
|
|
|
|
|
close(afd);
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
cmd = jehanne_getenv("init");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(cmd == nil){
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_sprint(cmdbuf, "/arch/%s/cmd/init -%s%s", cputype,
|
2016-11-25 17:18:40 +01:00
|
|
|
|
cpuflag ? "c" : "t", mflag ? "m" : "");
|
|
|
|
|
cmd = cmdbuf;
|
|
|
|
|
}
|
2017-04-19 23:33:14 +02:00
|
|
|
|
iargc = jehanne_tokenize(cmd, iargv, nelem(iargv)-1);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
cmd = iargv[0];
|
|
|
|
|
|
|
|
|
|
/* make iargv[0] basename(iargv[0]) */
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(iargv[0] = jehanne_strrchr(iargv[0], '/'))
|
2016-11-25 17:18:40 +01:00
|
|
|
|
iargv[0]++;
|
|
|
|
|
else
|
|
|
|
|
iargv[0] = cmd;
|
|
|
|
|
|
|
|
|
|
iargv[iargc] = nil;
|
|
|
|
|
|
|
|
|
|
exec(cmd, (const char**)iargv);
|
|
|
|
|
fatal(cmd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Method*
|
|
|
|
|
findmethod(char *a)
|
|
|
|
|
{
|
|
|
|
|
Method *mp;
|
|
|
|
|
int i, j;
|
|
|
|
|
char *cp;
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if((i = jehanne_strlen(a)) == 0)
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return nil;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
cp = jehanne_strchr(a, '!');
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(cp)
|
|
|
|
|
i = cp - a;
|
|
|
|
|
for(mp = method; mp->name; mp++){
|
2017-04-19 23:33:14 +02:00
|
|
|
|
j = jehanne_strlen(mp->name);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(j > i)
|
|
|
|
|
j = i;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_strncmp(a, mp->name, j) == 0)
|
2016-11-25 17:18:40 +01:00
|
|
|
|
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];
|
|
|
|
|
int rc;
|
|
|
|
|
Method *mp;
|
|
|
|
|
char *cp;
|
|
|
|
|
char reply[256];
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
/* look for required reply */
|
|
|
|
|
rc = readfile("#ec/nobootprompt", reply, sizeof(reply));
|
|
|
|
|
if(rc == 0 && reply[0]){
|
|
|
|
|
mp = findmethod(reply);
|
|
|
|
|
if(mp)
|
|
|
|
|
goto HaveMethod;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("boot method %s not found\n", reply);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
reply[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* make list of methods */
|
|
|
|
|
mp = method;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
n = jehanne_sprint(prompt, "root is from (%s", mp->name);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
for(mp++; mp->name; mp++)
|
2017-04-19 23:33:14 +02:00
|
|
|
|
n += jehanne_sprint(prompt+n, ", %s", mp->name);
|
|
|
|
|
jehanne_sprint(prompt+n, ")");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
|
|
/* create default reply */
|
|
|
|
|
readfile("#ec/bootargs", reply, sizeof(reply));
|
|
|
|
|
if(reply[0] == 0 && arg != 0)
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_strcpy(reply, arg);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(reply[0]){
|
|
|
|
|
mp = findmethod(reply);
|
|
|
|
|
if(mp == 0)
|
|
|
|
|
reply[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
if(reply[0] == 0)
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_strcpy(reply, method->name);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
|
|
/* parse replies */
|
|
|
|
|
do{
|
|
|
|
|
outin(prompt, reply, sizeof(reply));
|
|
|
|
|
mp = findmethod(reply);
|
|
|
|
|
}while(mp == nil);
|
|
|
|
|
|
|
|
|
|
HaveMethod:
|
2017-04-19 23:33:14 +02:00
|
|
|
|
bargc = jehanne_tokenize(reply, bargv, Nbarg-2);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
bargv[bargc] = nil;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
cp = jehanne_strchr(reply, '!');
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(cp)
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_strcpy(sys, cp+1);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return mp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
usbinit(void)
|
|
|
|
|
{
|
|
|
|
|
Waitmsg *w;
|
|
|
|
|
static char *argv[] = {"usbrc", nil};
|
|
|
|
|
int pid;
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if (jehanne_access(usbrcPath, AEXIST) < 0) {
|
|
|
|
|
jehanne_print("usbinit: no %s\n", usbrcPath);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
switch(pid = jehanne_fork()){
|
2016-11-25 17:18:40 +01:00
|
|
|
|
case -1:
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("usbinit: fork failed: %r\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
case 0:
|
|
|
|
|
exec(usbrcPath, (const char**)argv);
|
|
|
|
|
fatal("can't exec usbd");
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("usbinit: waiting usbrc...");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
for(;;){
|
2017-04-19 23:33:14 +02:00
|
|
|
|
w = jehanne_wait();
|
2016-11-25 17:18:40 +01:00
|
|
|
|
if(w != nil && w->pid == pid){
|
|
|
|
|
if(w->msg[0] != 0)
|
|
|
|
|
fatal(w->msg);
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_free(w);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
break;
|
|
|
|
|
} else if(w == nil) {
|
|
|
|
|
fatal("configuring usbinit");
|
|
|
|
|
} else if(w->msg[0] != 0){
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("usbinit: wait: %d %s\n", w->pid, w->msg);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
}
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_free(w);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
}
|
2017-04-19 23:33:14 +02:00
|
|
|
|
jehanne_print("done\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
startconsole(void)
|
|
|
|
|
{
|
|
|
|
|
char *dbgfile, *argv[16], **av;
|
|
|
|
|
int i;
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_access(screenconsolePath, AEXEC) < 0){
|
|
|
|
|
jehanne_print("cannot find screenconsole: %r\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* start agent */
|
|
|
|
|
i = 0;
|
|
|
|
|
av = argv;
|
|
|
|
|
av[i++] = "screenconsole";
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(dbgfile = jehanne_getenv("debugconsole")){
|
2016-11-25 17:18:40 +01:00
|
|
|
|
av[i++] = "-d";
|
|
|
|
|
av[i++] = dbgfile;
|
|
|
|
|
}
|
|
|
|
|
av[i] = 0;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
switch(jehanne_fork()){
|
2016-11-25 17:18:40 +01:00
|
|
|
|
case -1:
|
|
|
|
|
fatal("starting screenconsole");
|
|
|
|
|
case 0:
|
|
|
|
|
exec(screenconsolePath, (const char**)av);
|
|
|
|
|
fatal("execing screenconsole");
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wait for agent to really be there */
|
2017-04-19 23:33:14 +02:00
|
|
|
|
while(jehanne_access("#s/screenconsole", AEXIST) < 0){
|
|
|
|
|
jehanne_sleep(250);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
}
|
|
|
|
|
/* replace 0, 1 and 2 */
|
|
|
|
|
if((i = open("#s/screenconsole", ORDWR)) < 0)
|
|
|
|
|
fatal("open #s/screenconsole");
|
2016-12-01 00:09:42 +01:00
|
|
|
|
if(mount(i, -1, "/dev", MBEFORE, "", '9') < 0)
|
2016-11-25 17:18:40 +01:00
|
|
|
|
fatal("mount /dev");
|
|
|
|
|
if((i = open("/dev/cons", OREAD))<0)
|
|
|
|
|
fatal("open /dev/cons, OREAD");
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_dup(i, 0) != 0)
|
|
|
|
|
fatal("jehanne_dup(i, 0)");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
close(i);
|
|
|
|
|
if((i = open("/dev/cons", OWRITE))<0)
|
|
|
|
|
fatal("open /dev/cons, OWRITE");
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_dup(i, 1) != 1)
|
|
|
|
|
fatal("jehanne_dup(i, 1)");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
close(i);
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_dup(1, 2) != 2)
|
|
|
|
|
fatal("jehanne_dup(1, 2)");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
startcomconsole(void)
|
|
|
|
|
{
|
|
|
|
|
char *dbgfile, *argv[16], **av;
|
|
|
|
|
int i;
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_access(comconsolePath, AEXEC) < 0){
|
|
|
|
|
jehanne_print("cannot find comconsole: %r\n");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* start agent */
|
|
|
|
|
i = 0;
|
|
|
|
|
av = argv;
|
|
|
|
|
av[i++] = "comconsole";
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(dbgfile = jehanne_getenv("debugconsole")){
|
2016-11-25 17:18:40 +01:00
|
|
|
|
av[i++] = "-d";
|
|
|
|
|
av[i++] = dbgfile;
|
|
|
|
|
}
|
|
|
|
|
av[i++] = "-s";
|
|
|
|
|
av[i++] = "comconsole";
|
|
|
|
|
av[i++] = "#t/eia0";
|
|
|
|
|
av[i] = 0;
|
2017-04-19 23:33:14 +02:00
|
|
|
|
switch(jehanne_fork()){
|
2016-11-25 17:18:40 +01:00
|
|
|
|
case -1:
|
|
|
|
|
fatal("starting comconsole");
|
|
|
|
|
case 0:
|
|
|
|
|
exec(comconsolePath, (const char**)av);
|
|
|
|
|
fatal("execing comconsole");
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wait for agent to really be there */
|
2017-04-19 23:33:14 +02:00
|
|
|
|
while(jehanne_access("#s/comconsole", AEXIST) < 0){
|
|
|
|
|
jehanne_sleep(250);
|
2016-11-25 17:18:40 +01:00
|
|
|
|
}
|
|
|
|
|
/* replace 0, 1 and 2 */
|
|
|
|
|
if((i = open("#s/comconsole", ORDWR)) < 0)
|
|
|
|
|
fatal("open #s/comconsole");
|
2016-12-01 00:09:42 +01:00
|
|
|
|
if(mount(i, -1, "/dev", MBEFORE, "", '9') < 0)
|
2016-11-25 17:18:40 +01:00
|
|
|
|
fatal("mount /dev");
|
|
|
|
|
if((i = open("/dev/cons", OREAD))<0)
|
|
|
|
|
fatal("open /dev/cons, OREAD");
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_dup(i, 0) != 0)
|
|
|
|
|
fatal("jehanne_dup(i, 0)");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
close(i);
|
|
|
|
|
if((i = open("/dev/cons", OWRITE))<0)
|
|
|
|
|
fatal("open /dev/cons, OWRITE");
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_dup(i, 1) != 1)
|
|
|
|
|
fatal("jehanne_dup(i, 1)");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
close(i);
|
2017-04-19 23:33:14 +02:00
|
|
|
|
if(jehanne_dup(1, 2) != 2)
|
|
|
|
|
fatal("jehanne_dup(1, 2)");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
bindBoot(void)
|
|
|
|
|
{
|
|
|
|
|
BootBind *b = bootbinds;
|
|
|
|
|
|
|
|
|
|
if(b == nil || b->name == nil)
|
|
|
|
|
return;
|
|
|
|
|
while(b->name){
|
|
|
|
|
bind(b->name, b->old, b->flag);
|
|
|
|
|
++b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
unbindBoot(void)
|
|
|
|
|
{
|
|
|
|
|
BootBind *b = bootbinds;
|
|
|
|
|
|
|
|
|
|
if(b == nil || b->name == nil)
|
|
|
|
|
return;
|
|
|
|
|
while(b->name)
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
|
|
while(--b >= bootbinds){
|
|
|
|
|
unmount(b->name, b->old);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
kbmap(void)
|
|
|
|
|
{
|
|
|
|
|
char *f;
|
|
|
|
|
int n, in, out;
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
|
f = jehanne_getenv("kbmap");
|
2016-11-25 17:18:40 +01:00
|
|
|
|
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");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
out = open("/dev/kbmap", OWRITE);
|
|
|
|
|
if(out < 0) {
|
|
|
|
|
warning("can't open /dev/kbmap");
|
|
|
|
|
close(in);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
while((n = read(in, buf, sizeof(buf))) > 0)
|
|
|
|
|
if(write(out, buf, n) != n){
|
|
|
|
|
warning("write to /dev/kbmap failed");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
close(in);
|
|
|
|
|
close(out);
|
|
|
|
|
}
|