M boot/aux.c => boot/aux.c +1 -0
@@ 107,6 107,7 @@ srvcreate(char *name, int fd)
{
char *srvname;
int f;
+ char buf[2*NAMELEN];
srvname = strrchr(name, '/');
if(srvname)
M boot/boot.c => boot/boot.c +23 -179
@@ 1,22 1,11 @@
#include <u.h>
#include <libc.h>
-#include <fcall.h>
-#include "../port/bootp.h"
-#include "../port/arp.h"
+#include "../boot/boot.h"
#define DEFSYS "bootes"
typedef struct Net Net;
typedef struct Flavor Flavor;
-enum
-{
- Nterm = 4,
- CtrlD = 4,
- Cr = 13,
- View = 0x80,
-};
-
-Fcall hdr;
int printcol;
char cputype[NAMELEN];
@@ 28,20 17,17 @@ int mflag;
int fflag;
int kflag;
-void nop(int);
-void session(int);
int cache(int);
void swapproc(void);
-void settime(int);
Method *rootserver(char*);
void
-main(int argc, char *argv)
+main(int argc, char *argv[])
{
int fd;
Method *mp;
char cmd[64];
- char flags[5];
+ char flags[6];
int islocal;
sleep(1000);
@@ 71,14 57,14 @@ main(int argc, char *argv)
/*
* pick a method and initialize it
*/
- mp = rootserver(*argv);
- islocal = strcmp(mp->name, "local") == 0;
+ mp = rootserver(argc ? *argv : 0);
(*mp->config)(mp);
+ islocal = strcmp(mp->name, "local") == 0;
/*
* get/set key or password
*/
- (*pword)(mp);
+ (*pword)(islocal, mp);
/*
* connect to the root file system
@@ 89,7 75,8 @@ main(int argc, char *argv)
if(!islocal){
nop(fd);
session(fd);
- fd = cache(fd);
+ if(cfs)
+ fd = (*cfs)(fd);
srvcreate(sys, fd);
}
srvcreate("boot", fd);
@@ 104,17 91,19 @@ main(int argc, char *argv)
close(fd);
/*
- * start local fs if its not the root file server
+ * if a local file server exists and it's not the
+ * root file server, start it and mount it onto /n/kfs
*/
if(!islocal){
for(mp = method; mp->name; mp++)
if(strcmp(mp->name, "local")==0){
- local = (*mp->connect)(mp);
- if(local < 0)
+ (*mp->config)(mp);
+ fd = (*mp->connect)();
+ if(fd < 0)
break;
- if(mount(local, "/n/kfs", MAFTER|MCREATE, "", "") < 0)
+ if(mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") < 0)
fatal("mount");
- close(local);
+ close(fd);
break;
}
}
@@ 124,13 113,13 @@ main(int argc, char *argv)
sleep(1000);
sprint(cmd, "/%s/init", cputype);
- sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m", "");
+ sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : "");
execl(cmd, "init", flags, 0);
fatal(cmd);
}
/*
- * ask user from whence comes the root file system
+ * ask user from whence cometh the root file system
*/
Method*
rootserver(char *arg)
@@ 142,18 131,18 @@ rootserver(char *arg)
int n;
mp = method;
- n = 0;
- sprint(prompt, "root is from (", mp->name);
+ n = sprint(prompt, "root is from (%s", mp->name);
for(mp++; mp->name; mp++)
n += sprint(prompt+n, ", %s", mp->name);
sprint(prompt+n, ")");
- for(;;){
+ if(arg)
+ strcpy(reply, arg);
+ else
strcpy(reply, method->name);
- if(arg == 0)
+ for(;;){
+ if(arg == 0 || mflag)
outin(prompt, reply, sizeof(reply));
- else
- strcpy(reply, arg);
arg = 0;
for(mp = method; mp->name; mp++)
if(*reply == *mp->name){
@@ 168,94 157,6 @@ rootserver(char *arg)
}
void
-nop(int fd)
-{
- long n;
-
- print("nop...");
- hdr.type = Tnop;
- hdr.tag = NOTAG;
- n = convS2M(&hdr, buf);
- if(write(fd, buf, n) != n)
- fatal("write nop");
- n = read(fd, buf, sizeof buf);
- if(n==2 && buf[0]=='O' && buf[1]=='K')
- n = read(fd, buf, sizeof buf);
- if(n <= 0)
- fatal("read nop");
- if(convM2S(buf, &hdr, n) == 0) {
- print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n",
- n, buf[0], buf[1], buf[2], buf[3]);
- fatal("format nop");
- }
- if(hdr.type != Rnop)
- fatal("not Rnop");
-}
-
-void
-session(int fd)
-{
- long n;
-
- print("session...");
- hdr.type = Tsession;
- hdr.tag = NOTAG;
- n = convS2M(&hdr, buf);
- if(write(fd, buf, n) != n)
- fatal("write session");
- n = read(fd, buf, sizeof buf);
- if(n <= 0)
- fatal("read session");
- if(convM2S(buf, &hdr, n) == 0)
- fatal("format session");
- if(hdr.type == Rerror){
- print("error %s;", hdr.ename);
- fatal(hdr.ename);
- }
- if(hdr.type != Rsession)
- fatal("not Rsession");
-}
-
-int
-cache(int fd)
-{
- ulong i;
- int p[2];
- char d[DIRLEN];
- char partition[2*NAMELEN];
-
- if(stat("/cfs", d) < 0)
- return fd;
- sprint(partition, "%scache", bootdisk);
- if(stat(partition, d) < 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(format)
- execl("/cfs", "bootcfs", "-fs", "-p", partition, 0);
- else
- execl("/cfs", "bootcfs", "-s", "-p", partition, 0);
- break;
- default:
- close(p[0]);
- close(fd);
- fd = p[1];
- break;
- }
- return fd;
-}
-
-void
swapproc(void)
{
int fd;
@@ 268,60 169,3 @@ swapproc(void)
if(write(fd, "start", 5) <= 0)
warning("starting swap kproc");
}
-
-void
-settime(int islocal)
-{
- int n, f;
- int timeset;
- Dir dir;
- char dirbuf[DIRLEN];
- char *srvname;
-
- 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, dirbuf, sizeof(dirbuf)-1)) > 0){
- dirbuf[n] = 0;
- timeset = 1;
- }
- close(f);
- }
- }
- if(timeset == 0){
- /*
- * set the time from the access time of the root
- */
- f = open("#s/boot", ORDWR);
- if(f < 0)
- return;
- if(mount(f, "/n/boot", MREPL, "", "") < 0){
- close(f);
- return;
- }
- close(f);
- if(stat("/n/boot", dirbuf) < 0)
- fatal("stat");
- convM2D(dirbuf, &dir);
- sprint(dirbuf, "%ld", dir.atime);
- unmount(0, "/n/boot");
- /*
- * set real time clock if there is one
- */
- f = open("#r/rtc", ORDWR);
- if(f > 0){
- write(f, dirbuf, strlen(dirbuf));
- close(f);
- }
- close(f);
- }
-
- f = open("#c/time", OWRITE);
- write(f, dirbuf, strlen(dirbuf));
- close(f);
-}
M boot/boot.h => boot/boot.h +44 -34
@@ 3,57 3,67 @@ struct Method
{
char *name;
void (*config)(Method*);
- void (*auth)(Method*);
- void (*connect)(Method*);
+ int (*auth)(void);
+ int (*connect)(void);
char *arg;
};
-extern char terminal[NAMELEN];
-extern char sys[2*NAMELEN];
-extern char password[NAMELEN];
-extern char username[NAMELEN];
+extern char* bootdisk;
+extern int (*cfs)(int);
+extern int cpuflag;
extern char cputype[NAMELEN];
-extern char *bootdisk;
-extern char *initflag;
-extern void (*pword)(Method*);
+extern int fflag;
extern int kflag;
+extern Method method[];
+extern char password[NAMELEN];
+extern void (*pword)(int, Method*);
+extern char sys[2*NAMELEN];
+extern char terminal[NAMELEN];
+extern char username[NAMELEN];
/* libc equivalent */
-extern int plumb(char*, char*, int*, char*);
-extern int outin(char*, char*, int);
-extern int sendmsg(int, char*);
-extern void warning(char*);
+extern int cache(int);
+extern int dkauth(void);
+extern int dkconnect(void);
extern void fatal(char*);
+extern void getpasswd(char*, int);
+extern void key(int, Method*);
+extern void newkernel(void);
+extern void nop(int);
+extern int outin(char*, char*, int);
+extern int passtokey(char*, char*, int);
+extern int plumb(char*, char*, int*, char*);
extern int readenv(char*, char*, int);
+extern int sendmsg(int, char*);
+extern void session(int);
extern void setenv(char*, char*);
+extern void settime(int);
extern void srvcreate(char*, int);
-extern int dkauth(void);
-extern int dkconnect(void);
-extern void userpasswd(int);
-extern void getpasswd(char*, int);
+extern void userpasswd(int, Method*);
+extern void warning(char*);
/* methods */
extern void config9600(Method*);
-extern int auth9600(Method*);
-extern int connect9600(Method*);
-extern void config192000(Method*);
-extern int auth192000(Method*);
-extern int connect192000(Method*);
+extern int auth9600(void);
+extern int connect9600(void);
+extern void config19200(Method*);
+extern int auth19200(void);
+extern int connect19200(void);
extern void confighs(Method*);
-extern int authhs(Method*);
-extern int connecths(Method*);
+extern int authhs(void);
+extern int connecths(void);
extern void configincon(Method*);
-extern int authincon(Method*);
-extern int connectincon(Method*);
+extern int authincon(void);
+extern int connectincon(void);
extern void configil(Method*);
-extern int authil(Method*);
-extern int connectil(Method*);
+extern int authil(void);
+extern int connectil(void);
extern void configtcp(Method*);
-extern int authtcp(Method*);
-extern int connecttcp(Method*);
+extern int authtcp(void);
+extern int connecttcp(void);
extern void configcyc(Method*);
-extern int authcyc(Method*);
-extern int connectcyc(Method*);
+extern int authcyc(void);
+extern int connectcyc(void);
extern void configlocal(Method*);
-extern int authlocal(Method*);
-extern int connectlocal(Method*);
+extern int authlocal(void);
+extern int connectlocal(void);
M boot/getpasswd.c => boot/getpasswd.c +25 -0
@@ 2,6 2,31 @@
#include <libc.h>
#include <../boot/boot.h>
+int
+passtokey(char *key, char *p, int n)
+{
+ uchar t[10];
+ int c;
+
+ memset(t, ' ', sizeof t);
+ if(n < 5)
+ return 0;
+ if(n > 10)
+ n = 10;
+ strncpy((char*)t, p, n);
+ if(n >= 9){
+ c = p[8] & 0xf;
+ if(n == 10)
+ c += p[9] << 4;
+ for(n = 0; n < 8; n++)
+ if(c & (1 << n))
+ t[n] -= ' ';
+ }
+ for(n = 0; n < 7; n++)
+ key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1)));
+ return 1;
+}
+
void
getpasswd(char *p, int len)
{
M boot/key.c => boot/key.c +4 -6
@@ 3,11 3,12 @@
#include <../boot/boot.h>
void
-key(Method *mp)
+key(int islocal, Method *mp)
{
char password[20], key[7];
int prompt, fd;
+ USED(islocal);
USED(mp);
prompt = kflag;
@@ 18,16 19,13 @@ key(Method *mp)
}
if(prompt){
do
- if(getpasswd(password, sizeof password) < 0){
- warning("can't read cons");
- return;
- }
+ getpasswd(password, sizeof password);
while(!passtokey(key, password, strlen(password)));
}else if(seek(fd, 1024+900, 0) < 0 || read(fd, key, 7) != 7){
close(fd);
warning("can't read key from nvram");
}
- if(kflag && seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7){
+ if(kflag && (seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7)){
close(fd);
warning("can't write key to nvram");
}
M boot/local.c => boot/local.c +1 -1
@@ 30,7 30,7 @@ connectlocal(void)
if(stat("/kfs", d) < 0)
return -1;
- sprint(partition, "%sfs", mp->arg ? mp->arg : bootdisk);
+ sprint(partition, "%sfs", disk ? disk : bootdisk);
if(stat(partition, d) < 0)
return -1;
A boot/nopsession.c => boot/nopsession.c +56 -0
@@ 0,0 1,56 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include "../boot/boot.h"
+
+static Fcall hdr;
+static char buf[4*1024];
+
+void
+nop(int fd)
+{
+ long n;
+
+ print("nop...");
+ hdr.type = Tnop;
+ hdr.tag = NOTAG;
+ n = convS2M(&hdr, buf);
+ if(write(fd, buf, n) != n)
+ fatal("write nop");
+ n = read(fd, buf, sizeof buf);
+ if(n==2 && buf[0]=='O' && buf[1]=='K')
+ n = read(fd, buf, sizeof buf);
+ if(n <= 0)
+ fatal("read nop");
+ if(convM2S(buf, &hdr, n) == 0) {
+ print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n",
+ n, buf[0], buf[1], buf[2], buf[3]);
+ fatal("format nop");
+ }
+ if(hdr.type != Rnop)
+ fatal("not Rnop");
+}
+
+void
+session(int fd)
+{
+ long n;
+
+ print("session...");
+ hdr.type = Tsession;
+ hdr.tag = NOTAG;
+ n = convS2M(&hdr, buf);
+ if(write(fd, buf, n) != n)
+ fatal("write session");
+ n = read(fd, buf, sizeof buf);
+ if(n <= 0)
+ fatal("read session");
+ if(convM2S(buf, &hdr, n) == 0)
+ fatal("format session");
+ if(hdr.type == Rerror){
+ print("error %s;", hdr.ename);
+ fatal(hdr.ename);
+ }
+ if(hdr.type != Rsession)
+ fatal("not Rsession");
+}
A boot/settime.c => boot/settime.c +61 -0
@@ 0,0 1,61 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include "../boot/boot.h"
+
+void
+settime(int islocal)
+{
+ int n, f;
+ int timeset;
+ Dir dir;
+ char dirbuf[DIRLEN];
+ char *srvname;
+
+ 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, dirbuf, sizeof(dirbuf)-1)) > 0){
+ dirbuf[n] = 0;
+ timeset = 1;
+ }
+ close(f);
+ }
+ }
+ if(timeset == 0){
+ /*
+ * set the time from the access time of the root
+ */
+ f = open("#s/boot", ORDWR);
+ if(f < 0)
+ return;
+ if(mount(f, "/n/boot", MREPL, "", "") < 0){
+ close(f);
+ return;
+ }
+ close(f);
+ if(stat("/n/boot", dirbuf) < 0)
+ fatal("stat");
+ convM2D(dirbuf, &dir);
+ sprint(dirbuf, "%ld", dir.atime);
+ unmount(0, "/n/boot");
+ /*
+ * set real time clock if there is one
+ */
+ f = open("#r/rtc", ORDWR);
+ if(f > 0){
+ write(f, dirbuf, strlen(dirbuf));
+ close(f);
+ }
+ close(f);
+ }
+
+ f = open("#c/time", OWRITE);
+ write(f, dirbuf, strlen(dirbuf));
+ close(f);
+}
M boot/userpasswd.c => boot/userpasswd.c +2 -27
@@ 4,36 4,11 @@
char password[NAMELEN];
-static int
-passtokey(char *key, char *p, int n)
-{
- uchar t[10];
- int c;
-
- memset(t, ' ', sizeof t);
- if(n < 5)
- return 0;
- if(n > 10)
- n = 10;
- strncpy((char*)t, p, n);
- if(n >= 9){
- c = p[8] & 0xf;
- if(n == 10)
- c += p[9] << 4;
- for(n = 0; n < 8; n++)
- if(c & (1 << n))
- t[n] -= ' ';
- }
- for(n = 0; n < 7; n++)
- key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1)));
- return 1;
-}
-
/*
* get/set user name and password. verify password with auth server.
*/
void
-userpasswd(Method *mp)
+userpasswd(int islocal, Method *mp)
{
char key[7];
char buf[8 + NAMELEN];
@@ 44,7 19,7 @@ userpasswd(Method *mp)
outin("user", username, sizeof(username));
}
crfd = fd = -1;
- while(strcmp(username, "none") != 0 && strcmp(mp->name, "local") != 0){
+ while(strcmp(username, "none") != 0 && !islocal){
getpasswd(password, sizeof password);
if(!passtokey(key, password, strlen(password))){
print("bad password; try again\n");
M gnot/fns.h => gnot/fns.h +2 -1
@@ 7,6 7,7 @@
#define P_write(sel, addr, val, type) P_oper(sel, *(type *)(PORT+addr) = val)
void addportintr(int (*)(void));
+void bootargs(ulong);
void clearmmucache(void);
void duartclock(void);
void duartinit(void);
@@ 58,7 59,7 @@ int spl1(void);
void spldone(void);
int splduart(void);
int tas(char*);
-void touser(void);
+void touser(void*);
#define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1]))
#define kmapperm(x) kmap(x)
#define getcallerpc(x) (*(ulong*)(x))
M gnot/l.s => gnot/l.s +4 -3
@@ 29,17 29,18 @@ dead:
BRA dead
/*
- * Take first processor into user mode. Leave enough room on the stack
+ * Take first processor into user mode. Leave enough room on the kernel stack
* for a full-sized Ureg (including long bus error format) to fit
+ * - argument is stack pointer to user
*/
-TEXT touser(SB), $-4
+TEXT touser(SB), $0
+ MOVL usp+0(FP), A0
MOVL $(USERADDR+BY2PG-UREGVARSZ), A7
MOVW $0, -(A7)
MOVL $(UTZERO+32), -(A7) /* header is in text */
MOVW $0, -(A7)
- MOVL $(USTKTOP-6*BY2WD), A0 /* MAXSYSARG=6 */
MOVL A0, USP
MOVW $(SUPER|SPL(0)), SR
MOVL $8, R0
M gnot/main.c => gnot/main.c +76 -14
@@ 11,7 11,6 @@
#include <gnot.h>
typedef struct Boot Boot;
-
struct Boot
{
long station;
@@ 23,11 22,11 @@ struct Boot
};
#define BOOT ((Boot*)0)
-char bootuser[NAMELEN];
-char bootline[64];
-char bootserver[64];
-char bootdevice[2];
-int bank[2];
+char bootuser[NAMELEN];
+char bootline[64];
+char bootserver[72];
+int bank[2];
+uchar *sp;
void unloadboot(void);
@@ 66,10 65,25 @@ main(void)
void
unloadboot(void)
{
+ char s[64];
+
strncpy(bootuser, BOOT->user, NAMELEN);
memmove(bootline, BOOT->line, 64);
- memmove(bootserver, BOOT->server, 64);
- bootdevice[0] = BOOT->device;
+ memmove(s, BOOT->server, 64);
+ switch(BOOT->device){
+ case 'a':
+ sprint(bootserver, "19200!%s", s);
+ break;
+ case 'A':
+ sprint(bootserver, "9600!%s", s);
+ break;
+ case 'i':
+ sprint(bootserver, "incon!%s", s);
+ break;
+ default:
+ sprint(bootserver, "scsi!%s", s);
+ break;
+ }
}
void
@@ 124,14 138,10 @@ init0(void)
if(!waserror()){
ksetterm("at&t %s");
ksetenv("cputype", "68020");
- ksetenv("bootuser", bootuser);
- ksetenv("bootline", bootline);
- ksetenv("bootserver", bootserver);
- ksetenv("bootdevice", bootdevice);
poperror();
}
- touser();
+ touser(sp);
}
FPsave initfp;
@@ 143,6 153,7 @@ userinit(void)
Segment *s;
User *up;
KMap *k;
+ Page *pg;
p = newproc();
p->pgrp = newpgrp();
@@ 171,10 182,15 @@ userinit(void)
kunmap(k);
/*
- * User Stack
+ * User Stack, copy in boot arguments
*/
s = newseg(SG_STACK, USTKTOP-BY2PG, 1);
p->seg[SSEG] = s;
+ pg = newpage(1, 0, USTKTOP-BY2PG);
+ segpage(s, pg);
+ k = kmap(pg);
+ bootargs(VA(k));
+ kunmap(k);
/*
* Text
@@ 189,6 205,52 @@ userinit(void)
ready(p);
}
+uchar *
+pusharg(char *p)
+{
+ int n;
+
+ n = strlen(p)+1;
+ sp -= n;
+ memmove(sp, p, n);
+ return sp;
+}
+
+void
+bootargs(ulong base)
+{
+ int i, ac;
+ uchar *av[32];
+ char *p, *pp;
+ uchar **lsp;
+
+ sp = (uchar*)base + BY2PG - MAXSYSARG*BY2WD;
+
+ ac = 0;
+ for(p = bootline; p && *p; p = pp){
+ pp = strchr(p, ' ');
+ if(pp)
+ *pp++ = 0;
+ av[ac++] = pusharg(p);
+ }
+ if(bootuser[0]){
+ av[ac++] = pusharg("-u");
+ av[ac++] = pusharg(bootuser);
+ }
+ av[ac++] = pusharg(bootserver);
+
+ /* 4 byte word align stack */
+ sp = (uchar*)((ulong)sp & ~3);
+
+ /* build argc, argv on stack */
+ sp -= (ac+1)*sizeof(sp);
+ lsp = (uchar**)sp;
+ for(i = 0; i < ac; i++)
+ *lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
+ *lsp = 0;
+ sp += (USTKTOP - BY2PG) - base - sizeof(sp);
+}
+
void
exit(void)
{
M port/devcons.c => port/devcons.c +3 -3
@@ 379,7 379,7 @@ int
readnum(ulong off, char *buf, ulong n, ulong val, int size)
{
char tmp[64];
- Op op = { tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG };
+ Op op = (Op){ tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG };
numbconv(&op, 10);
tmp[size-1] = ' ';
@@ 597,12 597,12 @@ consread(Chan *c, void *buf, long n, ulong offset)
if(offset != 0 || n != 8)
error(Ebadarg);
chal = u->p->pgrp->crypt->chal;
- chal[0] = 0;
+ chal[0] = RXschal;
for(i=1; i<8; i++)
chal[i] = nrand(256);
memmove(buf, chal, 8);
encrypt(evekey, buf, 8);
- chal[0] = 1;
+ chal[0] = RXstick;
return n;
case Quser:
M port/devip.c => port/devip.c +5 -7
@@ 11,8 11,8 @@
enum
{
- Nrprotocol = 3, /* Number of protocols supported by this driver */
- Nipsubdir = 4, /* Number of subdirectory entries per connection */
+ Nrprotocol = 3, /* Number of protocols supported by this driver */
+ Nipsubdir = 4, /* Number of subdirectory entries per connection */
};
int udpsum = 1;
@@ 38,7 38,7 @@ void iloput(Queue *, Block *);
void ilopen(Queue *, Stream *);
void ilclose(Queue *);
-Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp" };
+Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp", 0, 1 };
Qinfo udpinfo = { udpstiput, udpstoput, udpstopen, udpstclose, "udp" };
Qinfo ilinfo = { iliput, iloput, ilopen, ilclose, "il" };
@@ 164,12 164,10 @@ ipincoming(Ipconv *base, Ipconv *from)
qunlock(new);
continue;
}
- if(from)
- /* copy ownership from listening channel */
+ if(from) /* copy ownership from listening channel */
netown(new->net, new->index,
new->net->prot[from->index].owner, 0);
- else
- /* current user becomes owner */
+ else /* current user becomes owner */
netown(new->net, new->index, u->p->user, 0);
new->ref = 1;
M port/devmnt.c => port/devmnt.c +59 -29
@@ 67,6 67,7 @@ void mntdirfix(uchar*, Chan*);
void mntgate(Mnt*);
void mntrpcread(Mnt*, Mntrpc*);
void mntdoclunk(Mnt *, Mntrpc *);
+void mntauth(Mnt *, Mntrpc *, char *, ushort);
enum
{
@@ 123,6 124,8 @@ Chan*
mntattach(char *muxattach)
{
Mnt *m, *e;
+ Stream *s;
+ Qinfo *qi;
struct bogus{
Chan *chan;
char *spec;
@@ 159,9 162,23 @@ mntattach(char *muxattach)
m->c->flag |= CMSG;
m->blocksize = MAXFDATA;
+ /* If we have a stream based protocol (TCP/IP) we push fcall to block
+ * up P9 protocol messages into single deliminted blocks
+ */
+ s = m->c->stream;
+ qi = qinfofind("fcall");
+ if(s)
+ if(s->procq->next)
+ if(s->procq->next->info->nodelim) {
+ if(qi == 0)
+ error(Ebadctl);
+ pushq(s, qi);
+ }
+
switch(devchar[m->c->type]) {
default:
m->mux = 0;
+ break;
case 'H': /* Cyclone */
m->mux = 1;
break;
@@ 177,8 194,6 @@ mattach(Mnt *m, char *spec, char *serv)
{
Chan *c;
Mntrpc *r;
- char chal[8];
- int i;
r = mntralloc();
c = devattach('M', spec);
@@ 193,31 208,10 @@ mattach(Mnt *m, char *spec, char *serv)
nexterror();
}
- if(*serv){
- r->request.type = Tauth;
- r->request.fid = c->fid;
- memmove(r->request.uname, u->p->user, NAMELEN);
- chal[0] = 1;
- for(i = 1; i < sizeof chal; i++)
- chal[i++] = nrand(256);
- memmove(r->request.chal, chal, 8);
- strncpy(r->request.chal+8, serv, NAMELEN);
- encrypt(u->p->pgrp->crypt->key, r->request.chal, 8+NAMELEN);
- if(waserror())
- memset(r->request.auth, 0, sizeof r->request.auth);
- else{
- mountrpc(m, r);
- poperror();
- decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*8+2*DESKEYLEN);
- chal[0] = 4;
- if(memcmp(chal, r->reply.chal, 8) != 0)
- error(Eperm);
- memmove(r->request.auth, r->reply.chal+8+DESKEYLEN, 8+DESKEYLEN);
- }
- r->done = 0;
- r->flushed = 0;
- }else
- memset(r->request.auth, 0, sizeof r->request.auth);
+ memset(r->request.auth, 0, sizeof r->request.auth);
+ if(*serv)
+ mntauth(m, r, serv, c->fid);
+
r->request.type = Tattach;
r->request.fid = c->fid;
@@ 233,6 227,42 @@ mattach(Mnt *m, char *spec, char *serv)
return c;
}
+void
+mntauth(Mnt *m, Mntrpc *f, char *serv, ushort fid)
+{
+ Mntrpc *r;
+ uchar chal[CHLEN];
+ int i;
+
+ r = mntralloc();
+ if(waserror()) {
+ mntfree(r);
+ return;
+ }
+
+ r->request.type = Tauth;
+ r->request.fid = fid;
+ memmove(r->request.uname, u->p->user, NAMELEN);
+ chal[0] = FScchal;
+ for(i = 1; i < CHLEN; i++)
+ chal[i++] = nrand(256);
+
+ memmove(r->request.chal, chal, CHLEN);
+ strncpy(r->request.chal+CHLEN, serv, NAMELEN);
+ encrypt(u->p->pgrp->crypt->key, r->request.chal, CHLEN+NAMELEN);
+
+ mountrpc(m, r);
+ decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*CHLEN+2*DESKEYLEN);
+ chal[0] = FSctick;
+ poperror();
+ if(memcmp(chal, r->reply.chal, CHLEN) != 0) {
+ mntfree(r);
+ error(Eperm);
+ }
+ memmove(f->request.auth, r->reply.chal+CHLEN+DESKEYLEN, CHLEN+DESKEYLEN);
+ mntfree(r);
+}
+
Chan*
mntclone(Chan *c, Chan *nc)
{
@@ 790,8 820,8 @@ mntdump(void)
for(m = mntalloc.mntarena; m < me; m++) {
if(m->ref == 0)
continue;
- print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n", m->id, m->mux, m->queue,
- m->rip,
+ print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n",
+ m->id, m->mux, m->queue, m->rip,
m->rip ? m->rip->pid : 0, m->rip ? m->rip->text : "no");
}
print("rpcfree 0x%lux\n", mntalloc.rpcfree);
M port/page.c => port/page.c +0 -1
@@ 195,7 195,6 @@ pageinit(void)
ulong i, vmem, pmem, hw, hr;
Page *p;
-print("addr0 %lux addr1 %lux\n", palloc.addr0, palloc.addr1);
/*
* calculate an upper bound to the number of pages structures
* we'll need (np).
M port/portdat.h => port/portdat.h +19 -5
@@ 156,8 156,8 @@ struct Chan
Mount *mnt; /* mount point that derived Chan */
ulong mountid;
int fid; /* for devmnt */
+ Stream *stream; /* for stream channels */
union {
- Stream *stream; /* for stream channels */
void *aux;
Qid pgrpid; /* for #p/notepg */
int mntindex; /* for devmnt */
@@ 579,6 579,7 @@ struct Qinfo
void (*close)(Queue*);
char *name;
void (*reset)(void); /* initialization */
+ char nodelim; /* True if stream does not preserve delimiters */
Qinfo *next;
};
@@ 590,7 591,8 @@ struct Qinfo
#define QHIWAT 0x4 /* queue has gone past the high water mark */
#define QDEBUG 0x8
-struct Queue {
+struct Queue
+{
Blist;
int flag;
Qinfo *info; /* line discipline definition */
@@ 603,7 605,8 @@ struct Queue {
void *ptr; /* private info for the queue */
};
-struct Stream {
+struct Stream
+{
QLock; /* structure lock */
short inuse; /* number of processes in stream */
short opens; /* number of processes with stream open */
@@ 623,7 626,6 @@ struct Stream {
*/
#define RD(q) ((q)->other < (q) ? (q->other) : q)
#define WR(q) ((q)->other > (q) ? (q->other) : q)
-#define GLOBAL(a) (((ulong)(a)) & 0x80000000)
#define STREAMTYPE(x) ((x)&0x1f)
#define STREAMID(x) (((x)&~CHDIR)>>5)
#define STREAMQID(i,t) (((i)<<5)|(t))
@@ 684,7 686,7 @@ extern FPsave initfp;
extern Conf conf;
extern ulong initcode[];
extern Dev devtab[];
-extern char devchar[];
+extern char *devchar;
extern char *conffile;
extern char *statename[];
extern Palloc palloc;
@@ 696,3 698,15 @@ extern int nrdy;
#define CHDIR 0x80000000L
#define CHAPPEND 0x40000000L
#define CHEXCL 0x20000000L
+
+/*
+ * auth messages
+ */
+#define CHLEN 8
+enum{
+ FScchal = 1,
+ FSctick,
+
+ RXschal = 0,
+ RXstick = 1,
+};
M port/portfns.h => port/portfns.h +2 -0
@@ 143,6 143,7 @@ Segment* newseg(int, ulong, ulong);
Waitq* newwaitq(void);
char* nextelem(char*, char*);
void nexterror(void);
+int nodelims(Stream*);
int notify(Ureg*);
int nrand(int);
void nullput(Queue*, Block*);
@@ 182,6 183,7 @@ void putstr(char*);
void putstrn(char*, long);
void putswap(Page*);
ulong pwait(Waitmsg*);
+Qinfo* qinfofind(char*);
void qlock(QLock*);
void qunlock(QLock*);
int readnum(ulong, char*, ulong, ulong, int);
M port/stfcall.c => port/stfcall.c +106 -167
@@ 7,91 7,74 @@
#include "fcall.h"
-#define DPRINT if(fcalldebug)kprint
-
-int fcalldebug = 0;
-
-typedef struct Fcalld Fcalld;
-
-struct Fcalld{
- int dev; /* ref. for debug output */
- int state;
- int type; /* of current message */
- int need; /* bytes remaining in current message */
- int nhdr; /* bytes of header treasured up in hdr */
- uchar hdr[16];
-};
-
-enum {
- Startup, Startup1, Begin, Header, Data
+enum
+{
+ Twritehdr = 15, /* Min bytes for Twrite */
+ Rreadhdr = 8, /* Min bytes for Rread */
+ Twritecnt = 13, /* Offset in byte stream of write count */
+ Rreadcnt = 5, /* Offset for Readcnt */
};
-/*
- * fcall stream module definition
- */
static void fcalliput(Queue*, Block*);
static void fcalloput(Queue*, Block*);
static void fcallopen(Queue*, Stream*);
static void fcallclose(Queue*);
static void fcallreset(void);
-Qinfo fcallinfo =
+Qinfo fcallinfo = { fcalliput, fcalloput, fcallopen, fcallclose, "fcall", fcallreset };
+
+static uchar msglen[256] =
{
- fcalliput,
- fcalloput,
- fcallopen,
- fcallclose,
- "fcall",
- fcallreset
+ [Tnop] 3,
+ [Rnop] 3,
+ [Tsession] 3,
+ [Rsession] 3,
+ [Terror] 0,
+ [Rerror] 67,
+ [Tflush] 5,
+ [Rflush] 3,
+ [Tattach] 89,
+ [Rattach] 13,
+ [Tclone] 7,
+ [Rclone] 5,
+ [Twalk] 33,
+ [Rwalk] 13,
+ [Topen] 6,
+ [Ropen] 13,
+ [Tcreate] 38,
+ [Rcreate] 13,
+ [Tread] 15,
+ [Rread] 8,
+ [Twrite] 16,
+ [Rwrite] 7,
+ [Tclunk] 5,
+ [Rclunk] 5,
+ [Tremove] 5,
+ [Rremove] 5,
+ [Tstat] 5,
+ [Rstat] 121,
+ [Twstat] 121,
+ [Rwstat] 5,
+ [Tclwalk] 35,
+ [Rclwalk] 13,
+ [Tauth] 69,
+ [Rauth] 35,
};
-static Block * putmsg(Queue*, Block*, int);
-
-static uchar msglen[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 3, 3, 3, 0, 67, 5, 3, 89, 13, 7, 5, 33, 13,
- 6, 13, 38, 13, 15, 8, 16, 7, 5, 5, 5, 5, 5,121,121, 5,
- 35, 13, 69, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
static void
fcallreset(void)
-{}
+{
+}
static void
fcallopen(Queue *q, Stream *s)
{
- Fcalld *f;
-
- DPRINT("fcallopen %d\n", s->dev);
-
- q->ptr = allocb(sizeof(Fcalld));
- f = (Fcalld *)((Block *)q->ptr)->base;
- f->dev = s->dev;
- f->state = Startup;
- f->type = 0;
- f->need = 0;
- f->nhdr = 0;
+ USED(q, s);
}
static void
fcallclose(Queue * q)
{
- Fcalld *f = (Fcalld *)((Block *)q->ptr)->base;
-
- DPRINT("fcallstclose %d\n", f->dev);
- freeb(q->ptr);
- q->ptr = 0;
+ USED(q);
}
void
@@ 100,125 83,81 @@ fcalloput(Queue *q, Block *bp)
PUTNEXT(q, bp);
}
+void
+upstream(Queue *q, ulong len)
+{
+ Block *bl, **tail, *bp;
+ ulong l;
+
+ tail = &bl;
+ while(len) {
+ l = BLEN(q->first);
+ if(l > len)
+ break;
+ bp = getq(q); /* Consume all of block */
+ *tail = bp;
+ tail = &bp->next;
+ len -= l;
+ }
+ if(len) { /* Consume partial block */
+ lock(q);
+ *tail = copyb(q->first, len);
+ q->first->rptr += len;
+ q->len -= len;
+ unlock(q);
+ }
+ for(bp = bl; bp->next; bp = bp->next)
+ ;
+ bp->flags |= S_DELIM;
+ PUTNEXT(q, bl);
+}
static void
fcalliput(Queue *q, Block *bp)
{
- Fcalld *f = (Fcalld *)((Block *)q->ptr)->base;
- int len, n;
+ ulong len, need, off;
- len = BLEN(bp);
- DPRINT("fcalliput %d: blen=%d\n", f->dev, len);
- if(bp->type != M_DATA){
- DPRINT("fcalliput %d: type=%d\n", f->dev, bp->type);
+ if(bp->type != M_DATA) {
PUTNEXT(q, bp);
return;
}
- bp->flags &= ~S_DELIM;
- if(len == 0){
+ if(BLEN(bp) == 0) {
freeb(bp);
return;
}
- while(len > 0)switch(f->state){
- case Startup:
- if (len == 1 && bp->rptr[0] == 'O'){
- DPRINT("fcalliput %d: O\n", f->dev);
- PUTNEXT(q, bp);
- f->state = Startup1;
- return;
- }
- if(bp->rptr[0] == 'O' && bp->rptr[1] == 'K'){
- DPRINT("fcalliput %d: OK\n", f->dev);
- bp = putmsg(q, bp, 2);
- len -= 2;
- }
- f->state = Begin;
- break;
- case Startup1:
- if(bp->rptr[0] == 'K'){
- DPRINT("fcalliput %d: K\n", f->dev);
- bp = putmsg(q, bp, 1);
- len -= 1;
- f->state = Begin;
- break;
- }
- f->type = 'O';
- f->need = msglen['O']-1;
- f->state = Data;
- DPRINT("fcalliput %d: type=%d, need=%d\n",
- f->dev, f->type, f->need);
- break;
+ /* Stash the data */
+ bp->flags &= ~S_DELIM;
+ putq(q, bp);
- case Begin:
- f->type = bp->rptr[0];
- f->need = msglen[f->type];
- f->nhdr = 0;
- if(f->type == Twrite || f->type == Rread)
- f->state = Header;
- else
- f->state = Data;
- DPRINT("fcalliput %d: type=%d, need=%d\n",
- f->dev, f->type, f->need);
- break;
+ bp = q->first;
+ switch(bp->rptr[0]) { /* This is the type */
+ default:
+ len = msglen[bp->rptr[0]];
+ if(len == 0)
+ error(Emountrpc);
+ if(q->len >= len)
+ upstream(q, len);
- case Header:
- n = f->need;
- if(n > len)
- n = len;
- memmove(&f->hdr[f->nhdr], bp->rptr, n);
- f->nhdr += n;
- DPRINT("fcalliput %d: nhdr=%d\n",
- f->dev, f->nhdr);
- if(n == f->need){
- f->need += f->hdr[f->nhdr-3];
- f->need += f->hdr[f->nhdr-2] << 8;
- f->state = Data;
- DPRINT("fcalliput %d: need=%d\n",
- f->dev, f->need);
- }
- /* fall through */
-
- case Data:
- if(f->need > len){
- f->need -= len;
- PUTNEXT(q, bp);
- return;
- }
- bp = putmsg(q, bp, f->need);
- len -= f->need;
- f->state = Begin;
+ return;
+ case Twrite: /* Fmt: TGGFFOOOOOOOOCC */
+ len = Twritehdr; /* T = type, G = tag, F = fid */
+ off = Twritecnt; /* O = offset, C = count */
+ break;
+ case Rread: /* Fmt: TGGFFCC */
+ len = Rreadhdr;
+ off = Rreadcnt;
break;
}
-}
-static Block *
-putmsg(Queue *q, Block *bp, int n)
-{
- Block *xbp;
- int k;
+ if(q->len < len)
+ return;
- DPRINT("putmsg: n=%d\n\n", n);
- k = BLEN(bp) - n;
- if(k == 0){
- bp->flags |= S_DELIM;
- PUTNEXT(q, bp);
- return 0;
- }
- if(n <= k){
- xbp = allocb(n);
- memmove(xbp->wptr, bp->rptr, n);
- xbp->wptr += n;
- bp->rptr += n;
- xbp->flags |= S_DELIM;
- PUTNEXT(q, xbp);
- return bp;
- }
- xbp = allocb(k);
- memmove(xbp->wptr, bp->rptr+n, k);
- xbp->wptr += k;
- bp->wptr -= k;
- bp->flags |= S_DELIM;
- PUTNEXT(q, bp);
- return xbp;
+ pullup(q->first, len);
+ bp = q->first;
+ need = len+bp->rptr[off]+(bp->rptr[off+1]<<8);
+ if(q->len < need)
+ return;
+
+ upstream(q, need);
}
M port/stream.c => port/stream.c +45 -3
@@ 708,17 708,17 @@ nullput(Queue *q, Block *bp)
/*
* find the info structure for line discipline 'name'
*/
-static Qinfo *
+Qinfo *
qinfofind(char *name)
{
Qinfo *qi;
if(name == 0)
- error(Ebadld);
+ return 0;
for(qi = lds; qi; qi = qi->next)
if(strcmp(qi->name, name)==0)
return qi;
- error(Ebadld);
+ return 0;
}
/*
@@ 1260,6 1260,8 @@ streamctlwrite(Chan *c, void *a, long n)
freeb(bp);
} else if(streamparse("push", bp)){
qi = qinfofind((char *)bp->rptr);
+ if(qi == 0)
+ error(Ebadld);
pushq(s, qi);
freeb(bp);
} else if(streamparse("pop", bp)){
@@ 1415,6 1417,46 @@ streamstat(Chan *c, char *db, char *name)
convD2M(&dir, db);
}
+Block *
+copyb(Block *bp, int count)
+{
+ Block *nb, *head, **p;
+ int l;
+
+ p = &head;
+ while(count) {
+ l = BLEN(bp);
+ if(count < l)
+ l = count;
+ nb = allocb(l);
+ if(nb == 0)
+ panic("copyb.1");
+ memmove(nb->wptr, bp->rptr, l);
+ nb->wptr += l;
+ count -= l;
+ if(bp->flags & S_DELIM)
+ nb->flags |= S_DELIM;
+ *p = nb;
+ p = &nb->next;
+ bp = bp->next;
+ if(bp == 0)
+ break;
+ }
+ if(count) {
+ nb = allocb(count);
+ if(nb == 0)
+ panic("copyb.2");
+ memset(nb->wptr, 0, count);
+ nb->wptr += count;
+ nb->flags |= S_DELIM;
+ *p = nb;
+ }
+ if(blen(head) == 0)
+ print("copyb: zero length\n");
+
+ return head;
+}
+
/*
* Dump all block information of how many blocks are in which queues
*/
M port/tcpinput.c => port/tcpinput.c +0 -40
@@ 748,46 748,6 @@ dupb(Block **hp, Block *bp, int offset, int count)
return bytes;
}
-Block *
-copyb(Block *bp, int count)
-{
- Block *nb, *head, **p;
- int l;
-
- p = &head;
- while(count) {
- l = BLEN(bp);
- if(count < l)
- l = count;
- nb = allocb(l);
- if(nb == 0)
- panic("copyb.1");
- memmove(nb->wptr, bp->rptr, l);
- nb->wptr += l;
- count -= l;
- if(bp->flags & S_DELIM)
- nb->flags |= S_DELIM;
- *p = nb;
- p = &nb->next;
- bp = bp->next;
- if(bp == 0)
- break;
- }
- if(count) {
- nb = allocb(count);
- if(nb == 0)
- panic("copyb.2");
- memset(nb->wptr, 0, count);
- nb->wptr += count;
- nb->flags |= S_DELIM;
- *p = nb;
- }
- if(blen(head) == 0)
- print("copyb: zero length\n");
-
- return head;
-}
-
ushort tcp_mss = DEF_MSS; /* Maximum segment size to be sent with SYN */
int tcp_irtt = DEF_RTT; /* Initial guess at round trip time */
M power/boot.c => power/boot.c +1 -1
@@ 396,7 396,7 @@ key(void)
close(fd);
prerror("can't read key from nvram");
}
- if(setkey && seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7){
+ if(setkey && (seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7)){
close(fd);
prerror("can't write key to nvram");
}
M power/l.s => power/l.s +1 -1
@@ 63,7 63,7 @@ clrbss:
TEXT touser(SB), $-4
- MOVW R1, SP
+ MOVW R1, SP /* user stack pointer */
MOVW M(STATUS), R1
OR $(KUP|IEP), R1
MOVW R1, M(STATUS)