Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/gnot/boot.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname gnot/boot.c 1990/03091
## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/boot.c
0a
#include <u.h>
#include <libc.h>

#include "fcall.h"

Fcall	hdr;
char	buf[100];

void	error(char *);

main(int argc, char *argv[])
{
	int cfd, fd, n, fu, f;
	char buf[NAMELEN];

	open("#c/cons", OREAD);
	open("#c/cons", OWRITE);
	open("#c/cons", OWRITE);

	do{
		print("user: ");
		n = read(0, buf, sizeof buf);
	}while(n==0 || n==1);
	if(n < 0)
		error("can't read #c/cons; please reboot");
	buf[n-1] = 0;
	print("hello %s!\n", buf);
n = 0;
fu = 1/n;
	for(;;);
}

void
error(char *s)
{
	char buf[64];

	errstr(0, buf);
	fprint(2, "boot: %s: %s\n", s, buf);
	exits(0);
}
.
## diffname gnot/boot.c 1990/0310
## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/boot.c /n/bootesdump/1990/0310/sys/src/9/68020/boot.c
28,29c
	if(pipe(p) == -1)
		error("pipe");
	if(write(p[1], "hohoHO!", 8) != 8)
		error("write");
	if(read(p[0], buf, 8) != 8)
		error("read");
	print("%s\n", buf);
.
14a
	int p[2];
.
## diffname gnot/boot.c 1990/0312
## diff -e /n/bootesdump/1990/0310/sys/src/9/68020/boot.c /n/bootesdump/1990/0312/sys/src/9/68020/boot.c
33,36c
	close(f);
	sprint(buf, "#s/%s", "bootes");
	f = create("#s/boot", 1, 0666);
	if(f < 0)
		error("create");
	sprint(buf, "%d", fd);
	if(write(f, buf, strlen(buf)) != strlen(buf))
		error("write");
	close(f);
	
	print("mount...");
	if(bind("/", "/", MREPL) < 0)
		error("bind");
	if(mount(fd, "/", MAFTER|MCREATE, "") < 0)
		error("mount");
	print("success\n");
	execl("/68020/init", "init", 0);
	error("/68020/init");
}

void
sendmsg(int fd, char *msg)
{
	int n;

	n = strlen(msg);
	if(write(fd, msg, n) != n)
		error(msg);
.
29,31c
	close(fd);

	/*
	 *  grab the incon,
	 *  push the dk multiplexor onto it,
	 *  and use line 1 as the signalling channel.
	 */
	cfd = open("#i/ctl", 2);
	if(cfd < 0)
		error("opening #i/ctl");
	sendmsg(cfd, "push dkmux");
	sendmsg(cfd, "config 1 16");
	print("dkmux configured\n");

	/*
	 *  open a datakit channel and call ken via r70, leave the
	 *  incon ctl channel open
	 */
	fd = open("#k/2/data", 2);
	if(fd < 0)
		error("opening #k/2/data");
	cfd = open("#k/2/ctl", 2);
	if(cfd < 0)
		error("opening #k/2/ctl");
	print("#k/2/ctl open\n");
	sendmsg(cfd, "connect r70.nonet!bootes!fs");
	print("connected to r70.nonet!bootes!fs\n");
	close(cfd);

/*
	for(;;){
		print("ding\n");
		sleep(10000);
	}
/**/

	/*
	 *  talk to the file server
	 */
	print("nop...");
	hdr.type = Tnop;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n)
		error("write nop");
	n = read(fd, buf, sizeof buf);
	if(n <= 0)
		error("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]);
		error("format nop");
	}
	if(hdr.type != Rnop)
		error("not Rnop");

	print("session...");
	hdr.type = Tsession;
	hdr.lang = 'v';
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n)
		error("write session");
	n = read(fd, buf, sizeof buf);
	if(n <= 0)
		error("read session");
	if(convM2S(buf, &hdr, n) == 0)
		error("format session");
	if(hdr.type != Rsession)
		error("not Rsession");
	if(hdr.err){
		print("error %d;", hdr.err);
		error("remote error");
	}

	print("post...");
	sprint(buf, "#s/%s", "bootes");
	f = create(buf, 1, 0666);
	if(f < 0)
		error("create");
	sprint(buf, "%d", fd);
	if(write(f, buf, strlen(buf)) != strlen(buf))
.
26,27c
		error("can't read #c/user; please reboot");
	buf[n] = 0;
.
21,24c
	fd = open("#c/user", 0);
	if(fd < 0)
		error("#c/user");
	n = read(fd, buf, sizeof buf-1);
.
9c
void	error(char*);
void	sendmsg(int, char*);
.
## diffname gnot/boot.c 1990/0315
## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/boot.c /n/bootesdump/1990/0315/sys/src/9/68020/boot.c
58,64d
54d
42d
22,31d
## diffname gnot/boot.c 1990/0322
## diff -e /n/bootesdump/1990/0315/sys/src/9/68020/boot.c /n/bootesdump/1990/0322/sys/src/9/68020/boot.c
43,44c
	sendmsg(cfd, "connect helix.bootfs");
	print("connected to helix.bootfs\n");
.
## diffname gnot/boot.c 1990/05312
## diff -e /n/bootesdump/1990/0322/sys/src/9/68020/boot.c /n/bootesdump/1990/05312/sys/src/9/68020/boot.c
33a
	 *  fork a process to hold the incon channel open
	 */
	switch(fork()){
	case -1:
		break;
	case 0:
		for(;;)
			sleep(60*1000);
		exit(0);
	default:
		close(cfd);
		break;
	}

	/*
.
## diffname gnot/boot.c 1990/0613
## diff -e /n/bootesdump/1990/05312/sys/src/9/68020/boot.c /n/bootesdump/1990/0613/sys/src/9/68020/boot.c
123c
	if(strchr(bootline, ' '))
		execl("/68020/init", "init", "-m", 0);
	else
		execl("/68020/init", "init", 0);
.
21a
	fd = open("#e/bootline", OREAD);
	if(fd >= 0){
		read(fd, bootline, sizeof bootline);
		close(fd);
	}

.
7a
char	bootline[64];
.
## diffname gnot/boot.c 1990/0707
## diff -e /n/bootesdump/1990/0613/sys/src/9/68020/boot.c /n/bootesdump/1990/0707/sys/src/9/68020/boot.c
38c
	sendmsg(cfd, "config 1 16 norestart");
.
## diffname gnot/boot.c 1990/0917
## diff -e /n/bootesdump/1990/0707/sys/src/9/68020/boot.c /n/bootesdump/1990/0917/sys/src/9/68020/boot.c
65c
	sendmsg(cfd, "connect nfs");
.
56c
	 *  open a datakit channel and call ken, leave the
.
41c
	 *  fork a process to hold the device channel open
.
34,36d
30,31c
	 *  push the dk multiplexor onto the communications link,
.
28a
	fd = open("#e/bootdevice", OREAD);
	if(fd >= 0){
		read(fd, &bootdevice, 1);
		close(fd);
	}

	switch(bootdevice){
	case 'a':
		/*
		 *  grab the rs232 line,
		 *  make it 19200 baud,
		 *  push the async protocol onto it,
		 */
		cfd = open("#c/rs232ctl", 2);
		if(cfd < 0)
			error("opening #c/rs232ctl");
		sendmsg(cfd, "B19200");
		sendmsg(cfd, "push async");
		break;
	default:
		/*
		 *  grab the incon,
		 */
		cfd = open("#i/ctl", 2);
		if(cfd < 0)
			error("opening #i/ctl");
		break;
	}

.
8a
char	bootdevice;
.
## diffname gnot/boot.c 1990/0918
## diff -e /n/bootesdump/1990/0917/sys/src/9/68020/boot.c /n/bootesdump/1990/0918/sys/src/9/68020/boot.c
103a
	if(n==2 && buf[0]=='O' && buf[1]=='K')
		n = read(fd, buf, sizeof buf);
.
91,92c
	sprint(buf, "connect %s", bootserver);
	sendmsg(cfd, buf);
	print("connected to %s\n", bootserver);
.
34a
	fd = open("#e/bootserver", OREAD);
	if(fd >= 0){
		read(fd, bootserver, 64);
		close(fd);
	} else
		strcpy(bootserver, "nfs");
.
29d
17c
	char buf[256];
.
9a
char	bootserver[64];
.
## diffname gnot/boot.c 1990/0925
## diff -e /n/bootesdump/1990/0918/sys/src/9/68020/boot.c /n/bootesdump/1990/0925/sys/src/9/68020/boot.c
42a
	case 'A':
		/*
		 *  grab the rs232 line,
		 *  make it 9600 baud,
		 *  push the async protocol onto it,
		 */
		cfd = open("#c/rs232ctl", 2);
		if(cfd < 0)
			error("opening #c/rs232ctl");
		sendmsg(cfd, "B9600");
		sendmsg(cfd, "push async");
		break;
.
## diffname gnot/boot.c 1990/11211
## diff -e /n/bootesdump/1990/0925/sys/src/9/68020/boot.c /n/bootesdump/1990/11211/sys/src/9/68020/boot.c
199c
	errstr(buf);
.
180c
		execl("/68020/Ninit", "Ninit", 0);
.
178c
		execl("/68020/Ninit", "Ninit", "-m", 0);
.
174c
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
.
148,151d
145a
	if(hdr.type == Rerror){
		print("error %s;", hdr.ename);
		error(hdr.ename);
	}
.
137c
	hdr.tag = ~0;
.
118a
	hdr.tag = ~0;
.
103,110c
	for(i = 0; ; i++){
		fd = open("#k/2/data", 2);
		if(fd < 0)
			error("opening #k/2/data");
		cfd = open("#k/2/ctl", 2);
		if(cfd < 0)
			error("opening #k/2/ctl");
		sprint(buf, "connect %s", bootserver);
		n = strlen(buf);
		if(write(cfd, buf, n) == n)
			break;
		if(i == 5)
			error("dialing");
		print("error dialing, retrying ...\n");
		close(fd);
		close(cfd);
	}
.
17c
	int cfd, fd, n, fu, f, i;
.
4,5d
2a
#include <fcall.h>
.
## diffname gnot/boot.c 1990/1122
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/boot.c /n/bootesdump/1990/1122/sys/src/9/68020/boot.c
189c
		execl("/68020/init", "init", 0);
.
187c
		execl("/68020/init", "init", "-m", 0);
.
## diffname gnot/boot.c 1991/0108
## diff -e /n/bootesdump/1990/1122/sys/src/9/68020/boot.c /n/bootesdump/1991/0108/sys/src/9/68020/boot.c
185a

	f = create("#e/bootnet", 1, 0666);
	if(f >= 0){
		if(write(f, "dk", 2) != 2)
			error("writing bootnet");
		close(f);
		if(bind("#kdk", "/net/dk", MREPL) < 0)
			error("binding bootnet");
	}

.
## diffname gnot/boot.c 1991/0115
## diff -e /n/bootesdump/1991/0108/sys/src/9/68020/boot.c /n/bootesdump/1991/0115/sys/src/9/68020/boot.c
54a
	case 's':
.
## diffname gnot/boot.c 1991/01151
## diff -e /n/bootesdump/1991/0115/sys/src/9/68020/boot.c /n/bootesdump/1991/01151/sys/src/9/68020/boot.c
185a

	/*
	 * set the time from the access time of the root of the file server,
	 * accessible as /..
	 */
	print("time...");
	if(stat("/..", buf) < 0)
		error("stat");
	convM2D(buf, &dir);
	f = open("#c/time", OWRITE);
	sprint(buf, "%ld", dir.atime);
	write(f, buf, strlen(buf));
	close(f);
	
.
18a
	Dir dir;
.
## diffname gnot/boot.c 1991/0131
## diff -e /n/bootesdump/1991/01151/sys/src/9/68020/boot.c /n/bootesdump/1991/0131/sys/src/9/68020/boot.c
203,210c
	bind("#k", "/net/net", MREPL);
	bind("#k", "/net/dk", MREPL);
.
## diffname gnot/boot.c 1991/0214
## diff -e /n/bootesdump/1991/0201/sys/src/9/68020/boot.c /n/bootesdump/1991/0214/sys/src/9/gnot/boot.c
203,210c
	/*
	 *  if we have a cfs, give it the file server as fd 0
	 *  and requests on fd 1
	 */
	if(pipe(p)<0)
		error("pipe");
	switch(fork()){
	case -1:
		error("fork");
	case 0:
		close(p[1]);
		dup(fd, 0);
		close(fd);
		dup(p[0], 1);
		close(p[0]);
		execl("/cfs", "bootcfs", "-s", 0);
		break;
	default:
		close(p[0]);
		close(fd);
		fd = p[1];
		break;
	}
	return fd;
.
192,201c
	f = open("/cfs", OREAD);
	if(f < 0)
		return fd;
	print("cfs...");
.
189,190c
	 *  if there's no /cfs, just return the fd to the
	 *  file server
.
164,186c
/*
 *  see if we have a cache file system server in the kernel,
 *  and use it if we do
 */
int
cache(int fd)
{
	int f;
	ulong i;
	int p[2];
.
162a
}
.
145a
/*
 *  send nop to file server
 */
void
session(int fd)
{
	long n;

.
144a
}
.
124,126c
/*
 *  read arguments passed by kernel as
 *  environment variables - YECH!
 */
void
bootparams(void)
{
	int f;

	f = open("#e/bootline", OREAD);
	if(f >= 0){
		read(f, bootline, sizeof bootline);
		close(f);
	}
	f = open("#e/bootdevice", OREAD);
	if(f >= 0){
		read(f, &bootdevice, 1);
		close(f);
	}
	f = open("#e/bootserver", OREAD);
	if(f >= 0){
		read(f, bootserver, 64);
		close(f);
	} else
		strcpy(bootserver, "nfs");
}

/*
 *  send nop to file server
 */
void
nop(int fd)
{
	long n;

.
122a
	return fd;
}
.
117c
		print("error dialing %s, retrying ...\n", bootserver);
.
100,103c
/*
 *  open a datakit channel and call ken, return an fd to the
 *  connection.
 */
int
dkdial(void)
{
	int fd, cfd;
	int i;
	long n;

.
98a
}
.
86a
	 *  forever
.
41a
	/*
	 *  make a /srv/boot and a /srv/bootes
	 */
	print("post...");
	sprint(buf, "#s/%s", "bootes");
	f = create(buf, 1, 0666);
	if(f < 0)
		error("create");
	sprint(buf, "%d", fd);
	if(write(f, buf, strlen(buf)) != strlen(buf))
		error("write");
	close(f);
	sprint(buf, "#s/%s", "bootes");
	f = create("#s/boot", 1, 0666);
	if(f < 0)
		error("create");
	sprint(buf, "%d", fd);
	if(write(f, buf, strlen(buf)) != strlen(buf))
		error("write");
	close(f);

	/*
	 *  mount file server root after #/ root
	 */
	if(bind("/", "/", MREPL) < 0)
		error("bind");
	print("mount...");
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");

	/*
	 * set the time from the access time of the root of the file server,
	 * accessible as /..
	 */
	print("time...");
	if(stat("/..", buf) < 0)
		error("stat");
	convM2D(buf, &dir);
	f = open("#c/time", OWRITE);
	sprint(buf, "%ld", dir.atime);
	write(f, buf, strlen(buf));
	close(f);
	
	print("success\n");

	bind("#k", "/net/net", MREPL);
	bind("#k", "/net/dk", MREPL);

	if(strchr(bootline, ' '))
		execl("/68020/init", "init", "-m", 0);
	else
		execl("/68020/init", "init", 0);
	error("/68020/init");
}

/*
 *  open the network device, push on the needed multiplexors
 */
void
dkconfig(void)
{
	int cfd;

.
25,40c
	bootparams();
	dkconfig();
	fd = dkdial();
	nop(fd);
	session(fd);
	fd = cache(fd);
.
18d
16c
	int fd, f;
.
12a
void	bootparams(void);
void	dkconfig(void);
int	dkdial(void);
void	nop(int);
void	session(int);
int	cache(int);
.
## diffname gnot/boot.c 1991/0314
## diff -e /n/bootesdump/1991/0214/sys/src/9/gnot/boot.c /n/bootesdump/1991/0314/sys/src/9/gnot/boot.c
310c
		if(format)
			execl("/cfs", "bootcfs", "-fs", 0);
		else
			execl("/cfs", "bootcfs", "-s", 0);
.
205a
		cp = bootline;
		while(cp = strchr(cp, ' ')){
			if(*++cp != '-')
				continue;
			while(*cp && *cp!=' ')
				switch(*cp++){
				case 'f':
					format = 1;
					break;
				case 'm':
					manual = 1;
					break;
				}
		}
.
204c
		read(f, bootline, sizeof(bootline)-1);
.
201a
	format = 0;
	manual = 0;
.
200a
	char *cp;
.
85c
	if(manual)
.
9a
int	format;
int	manual;
.
## diffname gnot/boot.c 1991/0418
## diff -e /n/bootesdump/1991/0314/sys/src/9/gnot/boot.c /n/bootesdump/1991/0418/sys/src/9/gnot/boot.c
89,90c
	else {
		switch(fork()){
		case -1:
			print("can't start connection server\n");
			break;
		case 0:
			execl("/68020/init", "init", "-d", "/bin/cs", 0);
			error("/68020/bin/cs");
			break;
		default:
			execl("/68020/init", "init", 0);
		}
	}
.
## diffname gnot/boot.c 1991/0430
## diff -e /n/bootesdump/1991/0418/sys/src/9/gnot/boot.c /n/bootesdump/1991/0430/sys/src/9/gnot/boot.c
30a

	i = create("#e/sysname", 1, 0666);
	if(i < 0)
		error("sysname");
	if(write(i, argv[0], strlen(argv[0])) != strlen(argv[0]))
		error("sysname");
	close(i);
	i = create("#e/terminal", 1, 0666);
	if(i < 0)
		error("terminal");
	if(write(i, "at&t gnot 1", strlen("at&t gnot 1")) < 0)
		error("terminal");
	close(i);
.
24c
	int fd, f, i;
.
## diffname gnot/boot.c 1991/0507
## diff -e /n/bootesdump/1991/0430/sys/src/9/gnot/boot.c /n/bootesdump/1991/0507/sys/src/9/gnot/boot.c
103,113c
		execl("/68020/init", "init", 0);
.
## diffname gnot/boot.c 1991/0606
## diff -e /n/bootesdump/1991/0507/sys/src/9/gnot/boot.c /n/bootesdump/1991/0606/sys/src/9/gnot/boot.c
138c
			error("opening #t/tty0ctl");
.
136c
		cfd = open("#t/tty0ctl", 2);
.
125c
			error("opening #t/tty0ctl");
.
123c
		cfd = open("#t/tty0ctl", 2);
.
## diffname gnot/boot.c 1991/0820
## diff -e /n/bootesdump/1991/0606/sys/src/9/gnot/boot.c /n/bootesdump/1991/0820/sys/src/9/gnot/boot.c
291c
	hdr.tag = NOTAG;
.
263c
	hdr.tag = NOTAG;
.
## diffname gnot/boot.c 1991/0906
## diff -e /n/bootesdump/1991/0820/sys/src/9/gnot/boot.c /n/bootesdump/1991/0906/sys/src/9/gnot/boot.c
374a
}

/*
 *  prompt and get input
 */
int
outin(char *prompt, char *def, int len)
{
	int n;
	char buf[256];

	do{
		print("%s[%s]: ", prompt, def);
		n = read(0, buf, len);
	}while(n==0);
	if(n < 0)
		error("can't read #c/cons; please reboot");
	if(n != 1){
		buf[n-1] = 0;
		strcpy(def, buf);
	}
	return n;
}
void
connect(int fd)
{
	char xbuf[128];
	int i, pid, n, rcons;

	print("[ctrl-d to attach fs]\n");

	switch(pid = fork()) {
	case -1:
		error("fork failed");
	case 0:
		for(;;) {
			n = read(fd, xbuf, sizeof(xbuf));
			if(n < 0) {
				errstr(xbuf);
				print("[remote read error (%s)]\n", xbuf);
				for(;;);
			}
			for(i = 0; i < n; i++)
				if(xbuf[i] == Cr)
					xbuf[i] = ' ';
			write(1, xbuf, n);
		}
	default:
		rcons = open("#c/rcons", OREAD);
		if(rcons < 0)
			error("opening rcons");

		for(;;) {
			read(rcons, xbuf, 1);
			switch(xbuf[0]) {
			case CtrlD:
				kill(pid);
				close(rcons);
				return;
			default:
				n = write(fd, xbuf, 1);
				if(n < 0) {
					errstr(xbuf);
					kill(pid);
					close(rcons);
					print("[remote write error (%s)]\n", xbuf);
				}
			}
		}
	}
}

void
kill(int pid)
{
	char xbuf[32];
	int f;

	sprint(xbuf, "/proc/%d/note", pid);
	f = open(xbuf, OWRITE);
	write(f, "die", 3);
	close(f);
}

void
passwd(void)
{
	Dir d;
	char c;
	int i, n, fd, p[2];

	fd = open("#c/rcons", OREAD);
	if(fd < 0)
		error("can't open #c/rcons; please reboot");
 Prompt:		
	print("password: ");
	n = 0;
	do{
		do{
			i = read(fd, &c, 1);
			if(i < 0)
				error("can't read #c/rcons; please reboot");
		}while(i == 0);
		switch(c){
		case '\n':
			break;
		case '\b':
			if(n > 0)
				n--;
			break;
		case 'u' - 'a' + 1:		/* cntrl-u */
			print("\n");
			goto Prompt;
		default:
			password[n++] = c;
			break;
		}
	}while(c != '\n' && n < sizeof(password));
	password[n] = '\0';
	close(fd);
	print("\n");
.
367a
prerror(char *s)
{
	char buf[64];

	errstr(buf);
	fprint(2, "boot: %s: %s\n", s, buf);
}

/*
 *  print error and exit
 */
void
.
366a
/*
 *  print error
 */
.
346c
			execl("/cfs", "bootcfs", "-s", "-p", "#r/hd0cache", 0);
.
344c
			execl("/cfs", "bootcfs", "-fs", "-p", "#r/hd0cache", 0);
.
325a
	if(dirstat("#r/hd0cache", &d) < 0)
		return fd;
.
323,324c
	if(dirstat("/cfs", &d) < 0)
.
317a
	Dir d;
.
315d
282c
 *  send session to file server
.
273c
		print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n",
.
240,250d
238a
		buf[2] = '\0';
		if(strcmp(buf, "OK") == 0)
			return 0;
		else if(strcmp(buf, "CH") == 0) {
			sprint(buf, "%s\n%s\n", username, password);
			write(fd, buf, strlen(buf));	
		} else  if(strcmp(buf, "NO") == 0) {
			passwd();
			sprint(buf, "%s\n%s\n", username, password);
			write(fd, buf, strlen(buf));	
		}
.
219,237c
	for(;;) {
		n = read(fd, buf, sizeof(buf));
		if(n != 2){
			passwd();
			return -1;
.
216,217c
	int n;
.
213,214c
int
authenticate(int fd)
.
210,211c
 * authenticate with r70
.
208a
void
boot(int fd)
{
	int n, f;
	char *srvname;
	Dir dir;
	char dirbuf[DIRLEN];

	srvname = strrchr(sys, '/');
	if(srvname)
		srvname++;
	else
		srvname = sys;
	nop(fd);
	session(fd);
	fd = cache(fd);

	/*
	 *  stick handles to the file system
	 *  into /srv
	 */
	print("post...");
	sprint(buf, "#s/%s", srvname);
	f = create(buf, 1, 0666);
	if(f < 0)
		error("create");
	sprint(buf, "%d", fd);
	if(write(f, buf, strlen(buf)) != strlen(buf))
		error("write");
	close(f);
	f = create("#s/boot", 1, 0666);
	if(f < 0)
		error("create");
	sprint(buf, "%d", fd);
	if(write(f, buf, strlen(buf)) != strlen(buf))
		error("write");
	close(f);

	/*
	 *  make the root a union
	 */
	print("mount...");
	if(bind("/", "/", MREPL) < 0)
		error("bind");
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");

	/*
	 *  set the time from the access time of the root
	 *  of the file server, accessible as /..
	 */
	print("time...");
	if(stat("/..", dirbuf) < 0)
		error("stat");
	convM2D(dirbuf, &dir);
	f = open("#c/time", OWRITE);
	sprint(dirbuf, "%ld", dir.atime);
	write(f, dirbuf, strlen(dirbuf));
	close(f);

	print("success\n");

	/*
	 *  put a generic network device into the namespace
	 */
	if(netdev){
		char buf[64];
		sprint(buf, "/net/%s", net);
		bind(netdev, buf, MREPL);
		bind(netdev, "/net/net", MREPL);
	}
	if(net){
		char buf[64];
		sprint(buf, "/lib/netaddr.%s", net);
		print("binding %s onto /lib/netaddr.net\n", buf);
		bind(buf, "/lib/netaddr.net", MREPL);
	}
}

.
206c
	net = "dk";
	netdev = "#k";
	return fd;	
.
204c
	print("connected to %s\n", arg);
	sendmsg(cfd, "init");
.
202a
		sleep(500);
.
199,200c
			return -1;
.
194,196c

		if(write(cfd, buf, n)==n && authenticate(fd)==0)
.
191c
		cfd = open("#k/2/ctl", ORDWR);
.
188c
		fd = open("#k/2/data", ORDWR);
.
186a
	sprint(buf, "connect %s", arg);
	n = strlen(buf);

.
181c
dkdial(char *arg)
.
176,179d
157c
	if(authenticated)
		sendmsg(cfd, "config 1 16 norestart");
	else
		sendmsg(cfd, "config 1 16 restart");
.
155a
	if(bootdevice == 'i')
		authenticated = 1;
}

/*
 *  set flavor of terminal
 */
void
termtype(char *t)
{
	int fd;

	fd = create("#e/terminal", 1, 0666);
	if(fd < 0)
		error("terminal");
	if(write(fd, t, strlen(t)) < 0)
		error("terminal");
	close(fd);
}

/*
 *  get user and password if the
 *  boot rom didn't authenticate
 */
void
userpasswd(void)
{
	int fd;

	outin("user", username, sizeof(username));
	passwd();

	/*
	 *  set user id
	 */
	fd = open("#c/user", OWRITE|OTRUNC);
	if(fd >= 0){
		write(fd, username, strlen(username));
		close(fd);
	}
}

#define FS "(9)600 serial, (1)9200 serial, (i)incon"
/*
 *  if we've booted off the disk, figure out where to get the
 *  file service from
 */
int
fileserver(void)
{
	char reply[4];

	if(bootdevice != 's')
		return bootdevice;

	for(;;){
		strcpy(reply, "9");
		strcpy(sys, DEFSYS);
		outin(FS, reply, sizeof(reply));
		switch(reply[0]){
		case 'i':
			outin("server", sys, sizeof(sys));
			return 'i';
		case 'l':
			return 'l';
		case '1':
			outin("server", sys, sizeof(sys));
			return 'a';
		case '9':
			outin("server", sys, sizeof(sys));
			return 'A';
		}
	}
}

/*
 *  get the incon control channel
 */
int
inconctl(void)
{
	int cfd;

	cfd = open("#i/ctl", ORDWR);
	if(cfd < 0)
		error("opening #i/ctl");

	return cfd;
}

/*
 *  get the serial control channel and let the
 *  user connect to the TSM8
 */
int
asyncctl(char *baud)
{
	int cfd, dfd;
	char reply[4];

	cfd = open("#t/tty0ctl", ORDWR);
	if(cfd < 0)
		error("opening #t/tty0ctl");

	sendmsg(cfd, baud);

	dfd = open("#t/tty0", ORDWR);
	if(dfd < 0)
		error("opening #t/tty0");

	connect(dfd);
	close(dfd);
	sendmsg(cfd, "push async");
	return cfd;
}

/*
 *  configure the datakit
 */
void
dkconfig(int cfd)
{
.
153,154c
	 *  perhaps a stupid assumption
.
150a
	f = open("#e/bootdevice", OREAD);
	if(f >= 0){
		read(f, &bootdevice, 1);
		close(f);
	}
	f = open("#e/bootserver", OREAD);
	if(f >= 0){
		read(f, sys, sizeof(sys));
		close(f);
	} else
		strcpy(sys, DEFSYS);
.
116,149c
	format = 0;
	manual = 0;
	f = open("#e/bootline", OREAD);
	if(f >= 0){
		read(f, bootline, sizeof(bootline)-1);
		close(f);
		cp = bootline;
		while(cp = strchr(cp, ' ')){
			if(*++cp != '-')
				continue;
			while(*cp && *cp!=' ')
				switch(*cp++){
				case 'f':
					format = 1;
					break;
				case 'm':
					manual = 1;
					break;
				}
		}
.
114c
	int f;
	char *cp;
.
112c
bootparams(void)
.
109c
 *  read arguments passed by kernel as
 *  environment variables - YECH!
.
104d
102c
	else
.
99a
	/*
	 *  go to init
	 */
.
97,98c
	/*
	 *  set up the file system connection
	 */
	boot(fd);
.
86,95c
	dkconfig(cfd);
	for(;;){
		fd = dkdial(sys);
		if(fd >= 0)
			break;
		print("can't connect, retrying...\n");
		sleep(1000);
	}
.
83,84c
	 *  start up the datakit and connect to
	 *  file server
.
76,80c
	switch(fileserver()){
	case 'a':
		cfd = asyncctl("B19200");
		break;
	case 'A':
		cfd = asyncctl("B9600");
		break;
	case 'i':
	default:
		cfd = inconctl();
		break;
	}
.
74c
	 *  get the control channel for the network
	 *  device
.
55,71c
	if(!authenticated){
		strcpy(username, "none");
		userpasswd();
	}
.
53c
	 *  user/passwd pair if the boot rom didn't
	 *  authenticate
.
46,50c
	termtype("at&t gnot 1");
.
32,44c
	/*
	 *  get parameters passed by boot rom to kernel
	 */
.
30a
	sleep(1000);
.
27a

.
24,26c
	int cfd;
	int fd;
.
21a
/*
 * Ethernet type stations boot over ether or use dk via RS232.
 */
.
20a
void	sendmsg(int, char *);
void	connect(int);
void	kill(int);
void	passwd(void);
int	authenticate(int);
void	termtype(char*);
void	userpasswd(void);
int	fileserver(void);
int	inconctl(void);
int	asyncctl(char*);
void	dkconfig(int);
void	boot(int);
.
16,17c
int	outin(char *, char *, int);
void	prerror(char *);
void	error(char *);
int	dkdial(char *);
.
13,14c
int format;
int manual;

/*
 *  predeclared
 */
.
8,11c
char	password[32];
char	username[32];
char	sys[NAMELEN];
char	buf[4*1024];
.
6c
char	*scmd;
char 	bootdevice;
int	authenticated;

.
4a
#define DEFSYS "Nfs"

enum
{
	CtrlD	= 4,
	Cr	= 13,
};

char	*net;
char	*netdev;

.
## diffname gnot/boot.c 1991/0907
## diff -e /n/bootesdump/1991/0906/sys/src/9/gnot/boot.c /n/bootesdump/1991/0907/sys/src/9/gnot/boot.c
202,204d
199c
setuser(char *name)
.
163a
	f = open("#e/bootuser", OREAD);
	if(f >= 0){
		read(f, &bootuser, sizeof(bootuser));
		close(f);
	}
.
81a
	setuser(username);
.
80c
		outin("user", username, sizeof(username));
		passwd();
	} else {
		strcpy(username, bootuser);
.
47c
void	setuser(char*);
.
22,23c
char	bootuser[NAMELEN];
char	password[NAMELEN];
char	username[NAMELEN];
.
## diffname gnot/boot.c 1991/0912
## diff -e /n/bootesdump/1991/0907/sys/src/9/gnot/boot.c /n/bootesdump/1991/0912/sys/src/9/gnot/boot.c
218c
		if(write(fd, username, strlen(username)) <= 0)
			print("error writing %s to /dev/user\n", username);
.
176c
		read(f, sys, sizeof(sys)-1);
.
171c
		read(f, &bootuser, sizeof(bootuser)-1);
.
## diffname gnot/boot.c 1991/0926
## diff -e /n/bootesdump/1991/0912/sys/src/9/gnot/boot.c /n/bootesdump/1991/0926/sys/src/9/gnot/boot.c
562c
			execl("/cfs", "bootcfs", "-s", "-p", "#w/hd0cache", 0);
.
560c
			execl("/cfs", "bootcfs", "-fs", "-p", "#w/hd0cache", 0);
.
540c
	if(dirstat("#w/hd0cache", &d) < 0)
.
420,437d
417d
413,415c
	if(!fromserver){
		/*
		 *  set the time from the real time clock or file system
		 */
		f = open("#r/rtc", ORDWR);
		if(f > 0){
			if((n = read(f, dirbuf, sizeof(dirbuf)-1)) < 0)
				error("reading rtc");
			dirbuf[n] = 0;
			close(f);
		} else
			fromserver = 1;
	}
	if(fromserver){
		/*
		 *  set the time from the access time of the root
		 *  of the file server
		 */
		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)
			error("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){
			if(write(f, dirbuf, strlen(dirbuf)) < 0)
				error("writing rtc");
			close(f);
		}
		close(f);
	}
.
408,411d
399,406c
/*
 *  set the system time
 */
void
settime(int fromserver)
{
	int n, f;
	Dir dir;
	char dirbuf[DIRLEN];
	char *srvname;
.
391,397c
}
.
382c
	if(bind("#c", "/dev", MREPL) < 0)
		error("bind #c");
	if(bind("#p", "/proc", MREPL) < 0)
		error("bind #p");

	if(pipe(p)<0)
		error("pipe");
	switch(fork()){
	case -1:
		error("fork");
	case 0:
		sprint(sbuf, "%d", p[0]);
		sprint(rbuf, "%d", p[1]);
		execl("/kfs", "kfs", "-f", "#w/hd0fs", "-s", sbuf, rbuf, 0);
		error("can't exec kfs");
	default:
		break;
	}

	close(p[1]);

/*
 *  NEW KERNEL - these can both be MAFTER
 */
	if(bootfs){
		mtpt = "/";
		if(mount(p[0], mtpt, MAFTER|MCREATE, "", "") < 0)
			error("mount");
		srvcreate("boot", p[0]);
	} else {
		mtpt = "/n/kfs";
		if(mount(p[0], mtpt, MREPL|MCREATE, "", "") < 0)
			error("mount");
	}
	
	close(p[0]);

	return 0;
}

void
srvcreate(char *name, int fd)
{
	char *srvname;
	int f;

	srvname = strrchr(name, '/');
	if(srvname)
		srvname++;
	else
		srvname = name;

.
379,380c
	 *  because kfs uses /dev/time, /dev/pid, and /proc/#
.
377a
	return 0;
}

/*
 *  connect to a file system over the incon
 */
int
inconfs(void)
{
	int fd, cfd, dfd;
	char reply[4];

	if(!authenticated){
		passwd();
		outin("server", sys, sizeof(sys));
	}
	cfd = open("#i/ctl", ORDWR);
	if(cfd < 0)
		error("opening #i/ctl");

	dkconfig(cfd);
	for(;;){
		fd = dkdial(sys);
		if(fd >= 0)
			break;
		print("can't connect, retrying...\n");
		sleep(1000);
	}

	nop(fd);
	session(fd);
	fd = cache(fd);
	srvcreate(sys, fd);
	srvcreate("boot", fd);
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");
	close(fd);

	return 0;
}

/*
 *  plug the local file system into the name space
 */
int
localfs(int bootfs)
{
	ulong i;
	int p[2];
	Dir d;
	char sbuf[32];
	char rbuf[32];
	char *mtpt;

	if(dirstat("/kfs", &d) < 0)
		return -1;
	if(dirstat("#w/hd0fs", &d) < 0)
		return -1;

	print("local\n");

.
376a
	srvcreate(sys, fd);
	srvcreate("boot", fd);
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");
	close(fd);
.
369,373c
	if(!authenticated){
		passwd();
		outin("server", sys, sizeof(sys));
	}

	cfd = open("#t/tty0ctl", ORDWR);
	if(cfd < 0)
		error("opening #t/tty0ctl");
	sendmsg(cfd, baud);

	dfd = open("#t/tty0", ORDWR);
	if(dfd < 0)
		error("opening #t/tty0");
	connect(dfd);
	close(dfd);
	sendmsg(cfd, "push async");

	dkconfig(cfd);
	for(;;){
		fd = dkdial(sys);
		if(fd >= 0)
			break;
		print("can't connect, retrying...\n");
		sleep(1000);
	}

.
364,367c
	int fd, cfd, dfd;
	char reply[4];
.
361,362c
/*
 *  connect to a file system over the serial line
 */
int
asyncfs(char *baud)
.
353d
258,298d
251d
248d
245,246c
		case 'n':
			return 'n';
.
243d
238c
		strcpy(reply, "n");
.
224c
#define FS "remote fs is (9)600 serial, (1)9200 serial, (n)ot used"
.
218,219c
		write(fd, username, strlen(username));
.
180,184c
	if(bootdevice != 's')
.
176c
		read(f, sys, sizeof(sys));
.
171c
		read(f, &bootuser, sizeof(bootuser));
.
135c
 *  environment variables
.
118,125d
116a
	if(net){
		sprint(buf, "/lib/netaddr.%s", net);
		bind(buf, "/lib/netaddr.net", MREPL);
	}
.
109,115c
	if(netdev){
		sprint(buf, "/net/%s", net);
		bind(netdev, buf, MREPL);
		bind(netdev, "/net/net", MREPL);
.
106,107c
	 *  put a default net into the name space
.
103a
	settime(fromserver);
.
101c
		localfs(1);
		fromserver = 0;
.
99a
		inconfs();
		localfs(0);
		fromserver = 1;
		break;
.
97c
		asyncfs("B9600");
		localfs(0);
		fromserver = 1;
.
94c
		asyncfs("B19200");
		localfs(0);
		fromserver = 1;
.
91a
	if(bind("/", "/", MREPL) < 0)
		error("bind");

	/*
	 *  connect to file systems
	 */
.
89,90c
	 *  make the root a union
.
82d
76,77c
	 *  prompt for user if the boot rom didn't authenticate
.
73d
67c
	termtype("at&t gnot 1");
.
63d
61a
	int fromserver;
.
60d
53c
void	srvcreate(char*, int);
void	settime(int);
.
50,51c
int	inconfs(void);
int	asyncfs(char*);
int	localfs(int);
.
## diffname gnot/boot.c 1991/0927 # deleted
## diff -e /n/bootesdump/1991/0926/sys/src/9/gnot/boot.c /n/bootesdump/1991/0927/sys/src/9/gnot/boot.c
1,832d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.