]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/init.c
python: update python build configuration to new ape capabilities like getaddrinfo...
[plan9front.git] / sys / src / cmd / init.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <authsrv.h>
5
6 char*   readenv(char*);
7 void    setenv(char*, char*);
8 void    cpenv(char*, char*);
9 void    closefds(void);
10 int     procopen(int, char*, int);
11 void    fexec(void(*)(void));
12 void    rcexec(void);
13 void    cpustart(void);
14 void    pass(int);
15
16 char    *service;
17 char    *cmd;
18 char    *cpu;
19 char    *systemname;
20 int     manual;
21 int     iscpu;
22
23 void
24 main(int argc, char *argv[])
25 {
26         char *user;
27         int fd;
28
29         closefds();
30
31         service = "cpu";
32         manual = 0;
33         ARGBEGIN{
34         case 'c':
35                 service = "cpu";
36                 break;
37         case 'm':
38                 manual = 1;
39                 break;
40         case 't':
41                 service = "terminal";
42                 break;
43         }ARGEND
44         cmd = *argv;
45
46         fd = procopen(getpid(), "ctl", OWRITE);
47         if(fd >= 0){
48                 if(write(fd, "pri 10", 6) != 6)
49                         print("init: warning: can't set priority: %r\n");
50                 close(fd);
51         }
52
53         cpu = readenv("#e/cputype");
54         setenv("#e/objtype", cpu);
55         setenv("#e/service", service);
56         cpenv("/adm/timezone/local", "#e/timezone");
57         user = readenv("#c/user");
58         systemname = readenv("#c/sysname");
59
60         newns(user, 0);
61         iscpu = strcmp(service, "cpu")==0;
62
63         if(iscpu && manual == 0)
64                 fexec(cpustart);
65
66         for(;;){
67                 print("\ninit: starting /bin/rc\n");
68                 fexec(rcexec);
69                 manual = 1;
70                 cmd = 0;
71                 sleep(1000);
72         }
73 }
74
75 void
76 pass(int fd)
77 {
78         char key[DESKEYLEN];
79         char typed[32];
80         char crypted[DESKEYLEN];
81         int i;
82
83         for(;;){
84                 print("\n%s password:", systemname);
85                 for(i=0; i<sizeof typed; i++){
86                         if(read(0, typed+i, 1) != 1){
87                                 print("init: can't read password; insecure\n");
88                                 return;
89                         }
90                         if(typed[i] == '\n'){
91                                 typed[i] = 0;
92                                 break;
93                         }
94                 }
95                 if(i == sizeof typed)
96                         continue;
97                 if(passtokey(crypted, typed) == 0)
98                         continue;
99                 seek(fd, 0, 0);
100                 if(read(fd, key, DESKEYLEN) != DESKEYLEN){
101                         print("init: can't read key; insecure\n");
102                         return;
103                 }
104                 if(memcmp(crypted, key, sizeof key))
105                         continue;
106                 /* clean up memory */
107                 memset(crypted, 0, sizeof crypted);
108                 memset(key, 0, sizeof key);
109                 return;
110         }
111 }
112
113 static int gotnote;
114 static int interrupted;
115
116 void
117 pinhead(void*, char *msg)
118 {
119         gotnote = 1;
120         if(strcmp(msg, "interrupt") == 0)
121                 interrupted = 1;
122         else
123                 fprint(2, "init got note '%s'\n", msg);
124         noted(NCONT);
125 }
126
127 void
128 fexec(void (*execfn)(void))
129 {
130         Waitmsg *w;
131         int fd, pid;
132
133         switch(pid=fork()){
134         case 0:
135                 rfork(RFNOTEG);
136                 (*execfn)();
137                 print("init: exec error: %r\n");
138                 exits("exec");
139         case -1:
140                 print("init: fork error: %r\n");
141                 exits("fork");
142         default:
143                 fd = procopen(pid, "notepg", OWRITE);
144         casedefault:
145                 notify(pinhead);
146                 interrupted = 0;
147                 gotnote = 0;
148                 w = wait();
149                 if(w == nil){
150                         if(interrupted && fd >= 0)
151                                 write(fd, "interrupt", 9);
152                         if(gotnote)
153                                 goto casedefault;
154                         print("init: wait error: %r\n");
155                         break;
156                 }
157                 if(w->pid != pid){
158                         free(w);
159                         goto casedefault;
160                 }
161                 if(strstr(w->msg, "exec error") != 0){
162                         print("init: exit string %s\n", w->msg);
163                         print("init: sleeping because exec failed\n");
164                         free(w);
165                         for(;;)
166                                 sleep(1000);
167                 }
168                 if(w->msg[0])
169                         print("init: rc exit status: %s\n", w->msg);
170                 free(w);
171                 break;
172         }
173         if(fd >= 0)
174                 close(fd);
175 }
176
177 void
178 rcexec(void)
179 {
180         if(cmd)
181                 execl("/bin/rc", "rc", "-c", cmd, nil);
182         else if(manual || iscpu)
183                 execl("/bin/rc", "rc", nil);
184         else if(strcmp(service, "terminal") == 0)
185                 execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . lib/profile", nil);
186         else
187                 execl("/bin/rc", "rc", nil);
188 }
189
190 void
191 cpustart(void)
192 {
193         execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", nil);
194 }
195
196 char*
197 readenv(char *name)
198 {
199         int f, len;
200         Dir *d;
201         char *val;
202
203         f = open(name, OREAD);
204         if(f < 0){
205                 print("init: can't open %s: %r\n", name);
206                 return "*unknown*";     
207         }
208         d = dirfstat(f);
209         if(d == nil){
210                 print("init: can't stat %s: %r\n", name);
211                 return "*unknown*";
212         }
213         len = d->length;
214         free(d);
215         if(len == 0)    /* device files can be zero length but have contents */
216                 len = 64;
217         val = malloc(len+1);
218         if(val == nil){
219                 print("init: can't malloc %s: %r\n", name);
220                 return "*unknown*";
221         }
222         len = read(f, val, len);
223         close(f);
224         if(len < 0){
225                 print("init: can't read %s: %r\n", name);
226                 return "*unknown*";
227         }else
228                 val[len] = '\0';
229         return val;
230 }
231
232 void
233 setenv(char *var, char *val)
234 {
235         int fd;
236
237         fd = create(var, OWRITE, 0644);
238         if(fd < 0)
239                 print("init: can't open %s\n", var);
240         else{
241                 fprint(fd, val);
242                 close(fd);
243         }
244 }
245
246 void
247 cpenv(char *file, char *var)
248 {
249         int i, fd;
250         char buf[8192];
251
252         fd = open(file, OREAD);
253         if(fd < 0)
254                 print("init: can't open %s\n", file);
255         else{
256                 i = read(fd, buf, sizeof(buf)-1);
257                 if(i <= 0)
258                         print("init: can't read %s: %r\n", file);
259                 else{
260                         close(fd);
261                         buf[i] = 0;
262                         setenv(var, buf);
263                 }
264         }
265 }
266
267 /*
268  *  clean up after /boot
269  */
270 void
271 closefds(void)
272 {
273         int i;
274
275         for(i = 3; i < 30; i++)
276                 close(i);
277 }
278
279 int
280 procopen(int pid, char *name, int mode)
281 {
282         char buf[128];
283         int fd;
284
285         snprint(buf, sizeof(buf), "#p/%d/%s", pid, name);
286         fd = open(buf, mode);
287         if(fd < 0)
288                 print("init: warning: can't open %s: %r\n", name);
289         return fd;
290 }