M boot/boot.c => boot/boot.c +15 -14
@@ 112,21 112,22 @@ boot(int argc, char *argv[])
newkernel();
/*
- * if a local file server exists and it's not the
- * root file server, start it and mount it onto /n/kfs
+ * if a local file server exists and it's not
+ * running, start it and mount it onto /n/kfs
*/
- if(!islocal){
- for(mp = method; mp->name; mp++)
- if(strcmp(mp->name, "local")==0){
- (*mp->config)(mp);
- fd = (*mp->connect)();
- if(fd < 0)
- break;
- if(mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") < 0)
- print("failed to mount kfs\n");
- close(fd);
- break;
- }
+ for(mp = method; mp->name; mp++){
+ if(strcmp(mp->name, "local") != 0)
+ continue;
+ if(access("#s/kfs", ORDWR) >= 0)
+ break;
+ (*mp->config)(mp);
+ fd = (*mp->connect)();
+ if(fd < 0)
+ break;
+ if(mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") < 0)
+ print("failed to mount kfs\n");
+ close(fd);
+ break;
}
settime(islocal);
M boot/boot.h => boot/boot.h +6 -0
@@ 60,6 60,9 @@ extern int connecths(void);
extern void configincon(Method*);
extern int authincon(void);
extern int connectincon(void);
+extern void configcincon(Method*);
+extern int authcincon(void);
+extern int connectcincon(void);
extern void configil(Method*);
extern int authil(void);
extern int connectil(void);
@@ 72,3 75,6 @@ extern int connectcyc(void);
extern void configlocal(Method*);
extern int authlocal(void);
extern int connectlocal(void);
+extern void configbri(Method*);
+extern int authbri(void);
+extern int connectbri(void);
M boot/settime.c => boot/settime.c +94 -3
@@ 3,6 3,8 @@
#include <fcall.h>
#include "../boot/boot.h"
+static long lusertime(char*);
+
void
settime(int islocal)
{
@@ 25,7 27,10 @@ settime(int islocal)
timeset = 1;
}
close(f);
- }
+ }else do{
+ strcpy(dirbuf, "yymmddhhmm[ss]");
+ outin("\ndate/time ", dirbuf, sizeof(dirbuf));
+ }while((timeset=lusertime(dirbuf)) <= 0);
}
if(timeset == 0){
/*
@@ 52,10 57,96 @@ settime(int islocal)
write(f, dirbuf, strlen(dirbuf));
close(f);
}
- close(f);
}
f = open("#c/time", OWRITE);
- write(f, dirbuf, strlen(dirbuf));
+ if(write(f, dirbuf, strlen(dirbuf)) < 0)
+ warning("can't set #c/time");
close(f);
}
+
+#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 yr)
+{
+ if((yr % 4) == 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;
+}
M gnot/devhifi.c => gnot/devhifi.c +0 -5
@@ 155,8 155,6 @@ hifistat(Chan *c, char *dp)
Chan*
hifiopen(Chan *c, int omode)
{
- Hifichan *hp = &hifichan[c->dev];
-
if(c->qid.path == CHDIR){
if(omode != OREAD)
error(Eperm);
@@ 183,8 181,6 @@ hificreate(Chan *c, char *name, int omode, ulong perm)
void
hificlose(Chan *c)
{
- Hifichan *hp = &hifichan[c->dev];
-
if(c->qid.path != CHDIR)
streamclose(c);
}
@@ 235,7 231,6 @@ long
hifiwrite(Chan *c, void *buf, long n, ulong offset)
{
Hifichan *hp = &hifichan[c->dev];
- Hifi *hifi = hp->hdev;
char nbuf[32], *p;
if(n < 0)
M gnot/devincon.c => gnot/devincon.c +1 -0
@@ 875,6 875,7 @@ rdpackets(Incon *ip)
* how to use more than one incon, this routine only
* is for incon[0].
*/
+void
inconintr(Ureg *ur)
{
uchar status;
M gnot/main.c => gnot/main.c +1 -0
@@ 350,6 350,7 @@ confinit(void)
conf.portispaged = 0;
conf.cntrlp = 0;
conf.dkif = 2;
+ confinit1(mul);
}
/*
M port/devconc.c => port/devconc.c +1 -0
@@ 466,6 466,7 @@ concread(Chan *c, void *a, long n, ulong offset)
if(c->qid.path & CHDIR)
return devdirread(c, a, n, 0, 0, concgen);
error(Eio);
+ return -1; /* does not return */
}
long
M port/devcons.c => port/devcons.c +0 -1
@@ 176,7 176,6 @@ panic(char *fmt, ...)
else
for(;;);
}
-
int
pprint(char *fmt, ...)
{
M port/devproc.c => port/devproc.c +0 -1
@@ 184,7 184,6 @@ procopen(Chan *c, int omode)
c->qid.vers = p->pid;
return devopen(c, omode, 0, 0, procgen);
-;
}
void
M port/portfns.h => port/portfns.h +2 -1
@@ 26,7 26,7 @@ void closemount(Mount*);
void closepgrp(Pgrp*);
long clrfpintr(void);
void confinit(void);
-void confinit1(int mul);
+void confinit1(int);
int consactive(void);
void consdebug(void);
Block *copyb(Block*, int);
@@ 104,6 104,7 @@ void kbdrepeat(int);
void kickpager(void);
int kprint(char*, ...);
void kproc(char*, void(*)(void*), void*);
+void kproftimer(ulong);
void ksetenv(char*, char*);
void ksetterm(char*);
long latin1(uchar*);
A port/stsplice.c => port/stsplice.c +82 -0
@@ 0,0 1,82 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+#define splicedebug 1
+
+#define DPRINT if(splicedebug)kprint
+
+/*
+ * Splice line discipline.
+ */
+
+static void spliceopen(Queue*, Stream*);
+static void spliceclose(Queue*);
+static void spliceoput(Queue*, Block*);
+static void spliceiput(Queue*, Block*);
+Qinfo spliceinfo =
+{
+ spliceiput,
+ spliceoput,
+ spliceopen,
+ spliceclose,
+ "splice"
+};
+
+static void
+spliceopen(Queue *q, Stream *s)
+{
+ DPRINT("spliceopen q=0x%ux s=0x%ux\n", q, s);
+
+ WR(q)->ptr = s; /* pointer to ourselves */
+ RD(q)->ptr = 0; /* pointer to other side */
+}
+
+static void
+spliceclose(Queue *q)
+{
+ DPRINT("spliceclose q=0x%ux us=0x%ux them=0x%ux\n",
+ q, WR(q)->ptr, RD(q)->ptr);
+
+ RD(q)->ptr = 0;
+ WR(q)->ptr = 0;
+}
+
+static void
+spliceoput(Queue *q, Block *bp)
+{
+ int fd;
+ Chan *c;
+ Stream *s;
+
+ if(bp->type != M_CTL){
+ PUTNEXT(q, bp);
+ return;
+ }
+ fd = strtol((char *)bp->rptr, 0, 0);
+ freeb(bp);
+ if(RD(q)->ptr)
+ error("stream already spliced");
+ c = fdtochan(fd, ORDWR, 0);
+ s = c->stream;
+ if(s == 0)
+ error("splice attempt on non-stream");
+ pushq(s, &spliceinfo);
+ RD(q)->ptr = s;
+ RD(s->procq->next)->ptr = WR(q)->ptr;
+}
+
+static void
+spliceiput(Queue *q, Block *bp)
+{
+ Stream *s;
+
+ if(bp->type == M_HANGUP)
+ PUTNEXT(q, bp);
+ else
+ FLOWCTL(((Stream *)q->ptr)->procq, bp);
+}