xref: /plan9/sys/src/cmd/init.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <auth.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier void	readenv(char*, char*, int);
63e12c5d1SDavid du Colombier void	setenv(char*, char*);
73e12c5d1SDavid du Colombier void	cpenv(char*, char*);
83e12c5d1SDavid du Colombier void	closefds(void);
93e12c5d1SDavid du Colombier void	fexec(void(*)(void));
103e12c5d1SDavid du Colombier void	rcexec(void);
113e12c5d1SDavid du Colombier void	cpustart(void);
123e12c5d1SDavid du Colombier void	pass(int);
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier char	*service;
153e12c5d1SDavid du Colombier char	*cmd;
163e12c5d1SDavid du Colombier char	cpu[NAMELEN];
173e12c5d1SDavid du Colombier char	sysname[NAMELEN];
183e12c5d1SDavid du Colombier int	manual;
193e12c5d1SDavid du Colombier int	iscpu;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier void
223e12c5d1SDavid du Colombier main(int argc, char *argv[])
233e12c5d1SDavid du Colombier {
243e12c5d1SDavid du Colombier 	char user[NAMELEN];
253e12c5d1SDavid du Colombier 	int consctl, key;
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	closefds();
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier 	service = "cpu";
303e12c5d1SDavid du Colombier 	manual = 0;
313e12c5d1SDavid du Colombier 	ARGBEGIN{
323e12c5d1SDavid du Colombier 	case 'c':
333e12c5d1SDavid du Colombier 		service = "cpu";
343e12c5d1SDavid du Colombier 		break;
353e12c5d1SDavid du Colombier 	case 'm':
363e12c5d1SDavid du Colombier 		manual = 1;
373e12c5d1SDavid du Colombier 		break;
383e12c5d1SDavid du Colombier 	case 't':
393e12c5d1SDavid du Colombier 		service = "terminal";
403e12c5d1SDavid du Colombier 		break;
413e12c5d1SDavid du Colombier 	}ARGEND
423e12c5d1SDavid du Colombier 	cmd = *argv;
433e12c5d1SDavid du Colombier 
443e12c5d1SDavid du Colombier 	readenv("#e/cputype", cpu, sizeof cpu);
453e12c5d1SDavid du Colombier 	setenv("#e/objtype", cpu);
463e12c5d1SDavid du Colombier 	setenv("#e/service", service);
473e12c5d1SDavid du Colombier 	cpenv("/adm/timezone/local", "#e/timezone");
483e12c5d1SDavid du Colombier 	readenv("#c/user", user, sizeof user);
493e12c5d1SDavid du Colombier 	readenv("#c/sysname", sysname, sizeof sysname);
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier 	newns(user, 0);
523e12c5d1SDavid du Colombier 
533e12c5d1SDavid du Colombier 	iscpu = strcmp(service, "cpu")==0;
543e12c5d1SDavid du Colombier 
55*219b2ee8SDavid du Colombier 	if(iscpu && manual == 0)
563e12c5d1SDavid du Colombier 		fexec(cpustart);
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier 	for(;;){
593e12c5d1SDavid du Colombier 		if(iscpu){
603e12c5d1SDavid du Colombier 			consctl = open("#c/consctl", OWRITE);
613e12c5d1SDavid du Colombier 			key = open("#c/key", OREAD);
623e12c5d1SDavid du Colombier 			if(consctl<0 || key<0 || write(consctl, "rawon", 5) != 5)
633e12c5d1SDavid du Colombier 				print("init: can't check password; insecure\n");
643e12c5d1SDavid du Colombier 			else{
653e12c5d1SDavid du Colombier 				pass(key);
663e12c5d1SDavid du Colombier 				write(consctl, "rawoff", 6);
673e12c5d1SDavid du Colombier 			}
683e12c5d1SDavid du Colombier 			close(consctl);
693e12c5d1SDavid du Colombier 			close(key);
703e12c5d1SDavid du Colombier 		}
713e12c5d1SDavid du Colombier 		print("\ninit: starting /bin/rc\n");
723e12c5d1SDavid du Colombier 		fexec(rcexec);
733e12c5d1SDavid du Colombier 		manual = 1;
743e12c5d1SDavid du Colombier 		cmd = 0;
753e12c5d1SDavid du Colombier 		sleep(1000);
763e12c5d1SDavid du Colombier 	}
773e12c5d1SDavid du Colombier }
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier void
803e12c5d1SDavid du Colombier pass(int fd)
813e12c5d1SDavid du Colombier {
823e12c5d1SDavid du Colombier 	char key[DESKEYLEN];
833e12c5d1SDavid du Colombier 	char typed[32];
843e12c5d1SDavid du Colombier 	char crypted[DESKEYLEN];
853e12c5d1SDavid du Colombier 	int i;
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	for(;;){
883e12c5d1SDavid du Colombier 		readenv("#c/sysname", sysname, sizeof sysname);
893e12c5d1SDavid du Colombier 		print("\n%s password:", sysname);
903e12c5d1SDavid du Colombier 		for(i=0; i<sizeof typed; i++){
913e12c5d1SDavid du Colombier 			if(read(0, typed+i, 1) != 1){
923e12c5d1SDavid du Colombier 				print("init: can't read password; insecure\n");
933e12c5d1SDavid du Colombier 				return;
943e12c5d1SDavid du Colombier 			}
953e12c5d1SDavid du Colombier 			if(typed[i] == '\n'){
963e12c5d1SDavid du Colombier 				typed[i] = 0;
973e12c5d1SDavid du Colombier 				break;
983e12c5d1SDavid du Colombier 			}
993e12c5d1SDavid du Colombier 		}
1003e12c5d1SDavid du Colombier 		if(i == sizeof typed)
1013e12c5d1SDavid du Colombier 			continue;
1023e12c5d1SDavid du Colombier 		if(passtokey(crypted, typed) == 0)
1033e12c5d1SDavid du Colombier 			continue;
1043e12c5d1SDavid du Colombier 		seek(fd, 0, 0);
1053e12c5d1SDavid du Colombier 		if(read(fd, key, DESKEYLEN) != DESKEYLEN){
1063e12c5d1SDavid du Colombier 			print("init: can't read key; insecure\n");
1073e12c5d1SDavid du Colombier 			return;
1083e12c5d1SDavid du Colombier 		}
1093e12c5d1SDavid du Colombier 		if(memcmp(crypted, key, sizeof key))
1103e12c5d1SDavid du Colombier 			continue;
1113e12c5d1SDavid du Colombier 		/* clean up memory */
1123e12c5d1SDavid du Colombier 		memset(crypted, 0, sizeof crypted);
1133e12c5d1SDavid du Colombier 		memset(key, 0, sizeof key);
1143e12c5d1SDavid du Colombier 		return;
1153e12c5d1SDavid du Colombier 	}
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier void
1193e12c5d1SDavid du Colombier fexec(void (*execfn)(void))
1203e12c5d1SDavid du Colombier {
1213e12c5d1SDavid du Colombier 	Waitmsg w;
1223e12c5d1SDavid du Colombier 	int pid, i;
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier 	switch(pid=fork()){
1253e12c5d1SDavid du Colombier 	case 0:
1263e12c5d1SDavid du Colombier 		(*execfn)();
1273e12c5d1SDavid du Colombier 		print("init: exec error: %r\n");
1283e12c5d1SDavid du Colombier 		exits("exec");
1293e12c5d1SDavid du Colombier 	case -1:
1303e12c5d1SDavid du Colombier 		print("init: fork error: %r\n");
1313e12c5d1SDavid du Colombier 		exits("fork");
1323e12c5d1SDavid du Colombier 	default:
1333e12c5d1SDavid du Colombier 	casedefault:
1343e12c5d1SDavid du Colombier 		i = wait(&w);
1353e12c5d1SDavid du Colombier 		if(i == -1)
1363e12c5d1SDavid du Colombier 			print("init: wait error: %r\n");
1373e12c5d1SDavid du Colombier 		else if(i != pid)
1383e12c5d1SDavid du Colombier 			goto casedefault;
1393e12c5d1SDavid du Colombier 		if(strcmp(w.msg, "exec") == 0){
1403e12c5d1SDavid du Colombier 			print("init: sleeping because exec failed\n");
1413e12c5d1SDavid du Colombier 			for(;;)
1423e12c5d1SDavid du Colombier 				sleep(1000);
1433e12c5d1SDavid du Colombier 		}
1443e12c5d1SDavid du Colombier 		if(w.msg[0])
1453e12c5d1SDavid du Colombier 			print("init: rc exit status: %s\n", w.msg);
1463e12c5d1SDavid du Colombier 		break;
1473e12c5d1SDavid du Colombier 	}
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier 
1503e12c5d1SDavid du Colombier void
1513e12c5d1SDavid du Colombier rcexec(void)
1523e12c5d1SDavid du Colombier {
1533e12c5d1SDavid du Colombier 	if(cmd)
1543e12c5d1SDavid du Colombier 		execl("/bin/rc", "rc", "-c", cmd, 0);
1553e12c5d1SDavid du Colombier 	else if(manual || iscpu)
1563e12c5d1SDavid du Colombier 		execl("/bin/rc", "rc", 0);
1573e12c5d1SDavid du Colombier 	else if(strcmp(service, "terminal") == 0)
158*219b2ee8SDavid du Colombier 		execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . lib/profile", 0);
1593e12c5d1SDavid du Colombier 	else
1603e12c5d1SDavid du Colombier 		execl("/bin/rc", "rc", 0);
1613e12c5d1SDavid du Colombier }
1623e12c5d1SDavid du Colombier 
1633e12c5d1SDavid du Colombier void
1643e12c5d1SDavid du Colombier cpustart(void)
1653e12c5d1SDavid du Colombier {
1663e12c5d1SDavid du Colombier 	execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", 0);
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier 
1693e12c5d1SDavid du Colombier void
1703e12c5d1SDavid du Colombier readenv(char *name, char *val, int len)
1713e12c5d1SDavid du Colombier {
1723e12c5d1SDavid du Colombier 	int f;
1733e12c5d1SDavid du Colombier 
1743e12c5d1SDavid du Colombier 	f = open(name, OREAD);
1753e12c5d1SDavid du Colombier 	if(f < 0){
1763e12c5d1SDavid du Colombier 		print("init: can't open %s\n", name);
1773e12c5d1SDavid du Colombier 		return;
1783e12c5d1SDavid du Colombier 	}
1793e12c5d1SDavid du Colombier 	len = read(f, val, len-1);
1803e12c5d1SDavid du Colombier 	close(f);
1813e12c5d1SDavid du Colombier 	if(len < 0)
1823e12c5d1SDavid du Colombier 		print("init: can't read %s\n", name);
1833e12c5d1SDavid du Colombier 	else
1843e12c5d1SDavid du Colombier 		val[len] = '\0';
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier void
1883e12c5d1SDavid du Colombier setenv(char *var, char *val)
1893e12c5d1SDavid du Colombier {
1903e12c5d1SDavid du Colombier 	int fd;
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	fd = create(var, OWRITE, 0644);
1933e12c5d1SDavid du Colombier 	if(fd < 0)
1943e12c5d1SDavid du Colombier 		print("init: can't open %s\n", var);
1953e12c5d1SDavid du Colombier 	else{
1963e12c5d1SDavid du Colombier 		fprint(fd, val);
1973e12c5d1SDavid du Colombier 		close(fd);
1983e12c5d1SDavid du Colombier 	}
1993e12c5d1SDavid du Colombier }
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier void
2023e12c5d1SDavid du Colombier cpenv(char *file, char *var)
2033e12c5d1SDavid du Colombier {
2043e12c5d1SDavid du Colombier 	int i, fd;
2053e12c5d1SDavid du Colombier 	char buf[8192];
2063e12c5d1SDavid du Colombier 
2073e12c5d1SDavid du Colombier 	fd = open(file, OREAD);
2083e12c5d1SDavid du Colombier 	if(fd < 0)
2093e12c5d1SDavid du Colombier 		print("init: can't open %s\n", file);
2103e12c5d1SDavid du Colombier 	else{
2113e12c5d1SDavid du Colombier 		i = read(fd, buf, sizeof(buf)-1);
2123e12c5d1SDavid du Colombier 		if(i <= 0)
2133e12c5d1SDavid du Colombier 			print("init: can't read %s: %r\n", file);
2143e12c5d1SDavid du Colombier 		else{
2153e12c5d1SDavid du Colombier 			close(fd);
2163e12c5d1SDavid du Colombier 			buf[i] = 0;
2173e12c5d1SDavid du Colombier 			setenv(var, buf);
2183e12c5d1SDavid du Colombier 		}
2193e12c5d1SDavid du Colombier 	}
2203e12c5d1SDavid du Colombier }
2213e12c5d1SDavid du Colombier 
2223e12c5d1SDavid du Colombier /*
2233e12c5d1SDavid du Colombier  *  clean up after /boot
2243e12c5d1SDavid du Colombier  */
2253e12c5d1SDavid du Colombier void
2263e12c5d1SDavid du Colombier closefds(void)
2273e12c5d1SDavid du Colombier {
2283e12c5d1SDavid du Colombier 	int i;
2293e12c5d1SDavid du Colombier 
2303e12c5d1SDavid du Colombier 	for(i = 3; i < 30; i++)
2313e12c5d1SDavid du Colombier 		close(i);
2323e12c5d1SDavid du Colombier }
233