xref: /plan9/sys/src/cmd/aux/reboot.c (revision bdd62a84a206e1491ba0943e040ae63e131fbb4e)
1 #include <u.h>
2 #include <libc.h>
3 
4 void
reboot(void)5 reboot(void)
6 {
7 	int fd;
8 	fd = open("/dev/reboot", OWRITE);
9 	if(fd >= 0)
10 		write(fd, "reboot", 6);
11 	exits(0);
12 }
13 
14 char*
readenv(char * name,char * buf,int n)15 readenv(char *name, char *buf, int n)
16 {
17 	char *ans;
18 	int f;
19 	char ename[200];
20 
21 	ans = buf;
22 	ename[0] = 0;
23 	strcat(ename, "/env/");
24 	strcat(ename, name);
25 	f = open(ename, OREAD);
26 	if(f < 0)
27 		return 0;
28 	n = read(f, ans, n-1);
29 	if(n < 0)
30 		ans = 0;
31 	else
32 		ans[n] = 0;
33 	close(f);
34 	return ans;
35 }
36 
37 int alarmed;
38 
39 void
ding(void *,char * msg)40 ding(void*, char*msg)
41 {
42 	if(strstr(msg, "alarm")){
43 		alarmed = 1;
44 		noted(NCONT);
45 	}
46 	noted(NDFLT);
47 }
48 
49 void
main(int argc,char ** argv)50 main(int argc, char **argv)
51 {
52 	int fd;
53 	char buf[256];
54 	char file[128];
55 	char *p;
56 	Dir *d;
57 
58 	if(argc > 1)
59 		strecpy(file, file+sizeof file, argv[1]);
60 	else{
61 		p = readenv("cputype", buf, sizeof buf);
62 		if(p == 0)
63 			exits(0);
64 		file[0] = 0;
65 		strcat(file, "/");
66 		strcat(file, p);
67 		strcat(file, "/lib");
68 	}
69 	if (access(file, AREAD) < 0)
70 		sysfatal("%s not readable: %r", file);
71 
72 	switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFCFDG)){
73 	case 0:
74 		break;
75 	default:
76 		exits(0);
77 	}
78 
79 	notify(ding);
80 	fd = open(file, OREAD);
81 	if (fd < 0)
82 		exits("no file");
83 
84 	//  the logic here is to make a request every 5 minutes.
85 	//  If the request alarms out, that's OK, the file server
86 	//  may just be busy.  If the request fails for any other
87 	//  reason, it's probably because the connection went
88 	//  away so reboot.
89 	for(;;){
90 		alarm(1000*60);
91 		alarmed = 0;
92 
93 		d = dirfstat(fd);
94 		free(d);
95 		if(d == nil)
96 			if(!alarmed)
97 				reboot();
98 		alarm(0);
99 		sleep(60*1000*5);
100 	}
101 }
102