]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/init.c
sgi: keyboard, mouse and cursor for indy
[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*   readfile(char*);
7 char*   readenv(char*);
8 void    setenv(char*, char*);
9 void    cpenv(char*, char*);
10 void    closefds(void);
11 int     procopen(int, char*, int);
12 void    fexec(void(*)(void));
13 void    rcexec(void);
14 void    cpustart(void);
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                         fprint(2, "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
58         user = readenv("#c/user");
59         systemname = readenv("#c/sysname");
60
61         newns(user, 0);
62         iscpu = strcmp(service, "cpu")==0;
63
64         if(iscpu && manual == 0)
65                 fexec(cpustart);
66
67         for(;;){
68                 fprint(2, "\ninit: starting /bin/rc\n");
69                 fexec(rcexec);
70                 manual = 1;
71                 cmd = 0;
72                 sleep(1000);
73         }
74 }
75
76 static int gotnote;
77 static int interrupted;
78
79 void
80 pinhead(void*, char *msg)
81 {
82         gotnote = 1;
83         if(strcmp(msg, "interrupt") == 0)
84                 interrupted = 1;
85         else
86                 fprint(2, "init got note '%s'\n", msg);
87         noted(NCONT);
88 }
89
90 void
91 fexec(void (*execfn)(void))
92 {
93         Waitmsg *w;
94         int fd, pid;
95
96         switch(pid=fork()){
97         case 0:
98                 rfork(RFNOTEG);
99                 (*execfn)();
100                 fprint(2, "init: exec error: %r\n");
101                 exits("exec");
102         case -1:
103                 fprint(2, "init: fork error: %r\n");
104                 return;
105         default:
106                 fd = procopen(pid, "notepg", OWRITE);
107         casedefault:
108                 notify(pinhead);
109                 interrupted = 0;
110                 gotnote = 0;
111                 w = wait();
112                 if(w == nil){
113                         if(interrupted && fd >= 0)
114                                 write(fd, "interrupt", 9);
115                         if(gotnote)
116                                 goto casedefault;
117                         fprint(2, "init: wait error: %r\n");
118                         break;
119                 }
120                 if(w->pid != pid){
121                         free(w);
122                         goto casedefault;
123                 }
124                 if(strstr(w->msg, "exec error") != 0){
125                         fprint(2, "init: exit string %s\n", w->msg);
126                         fprint(2, "init: sleeping because exec failed\n");
127                         for(;;)
128                                 sleep(1000);
129                 }
130                 if(w->msg[0])
131                         fprint(2, "init: rc exit status: %s\n", w->msg);
132                 free(w);
133                 break;
134         }
135         if(fd >= 0)
136                 close(fd);
137 }
138
139 void
140 rcexec(void)
141 {
142         if(cmd)
143                 execl("/bin/rc", "rc", "-c", cmd, nil);
144         else if(manual || iscpu)
145                 execl("/bin/rc", "rc", nil);
146         else if(strcmp(service, "terminal") == 0)
147                 execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . ./lib/profile", nil);
148         else
149                 execl("/bin/rc", "rc", nil);
150 }
151
152 void
153 cpustart(void)
154 {
155         execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", nil);
156 }
157
158 char*
159 readfile(char *name)
160 {
161         int f, len;
162         Dir *d;
163         char *val;
164
165         f = open(name, OREAD);
166         if(f < 0){
167                 fprint(2, "init: can't open %s: %r\n", name);
168                 return nil;     
169         }
170         d = dirfstat(f);
171         if(d == nil){
172                 fprint(2, "init: can't stat %s: %r\n", name);
173                 close(f);
174                 return nil;
175         }
176         len = d->length;
177         free(d);
178         if(len == 0)    /* device files can be zero length but have contents */
179                 len = 64;
180         val = malloc(len+1);
181         if(val == nil){
182                 fprint(2, "init: can't malloc %s: %r\n", name);
183                 close(f);
184                 return nil;
185         }
186         len = read(f, val, len);
187         close(f);
188         if(len < 0){
189                 fprint(2, "init: can't read %s: %r\n", name);
190                 return nil;
191         }else
192                 val[len] = '\0';
193         return val;
194 }
195
196 char*
197 readenv(char *name)
198 {
199         char *val;
200
201         val = readfile(name);
202         if(val == nil)
203                 val = "*unknown*";
204         return val;
205 }
206
207 void
208 setenv(char *name, char *val)
209 {
210         int fd;
211
212         fd = create(name, OWRITE, 0644);
213         if(fd < 0)
214                 fprint(2, "init: can't create %s: %r\n", name);
215         else{
216                 write(fd, val, strlen(val));
217                 close(fd);
218         }
219 }
220
221 void
222 cpenv(char *from, char *to)
223 {
224         char *val;
225
226         val = readfile(from);
227         if(val != nil){
228                 setenv(to, val);
229                 free(val);
230         }
231 }
232
233 /*
234  *  clean up after /boot
235  */
236 void
237 closefds(void)
238 {
239         int i;
240
241         for(i = 3; i < 30; i++)
242                 close(i);
243 }
244
245 int
246 procopen(int pid, char *name, int mode)
247 {
248         char buf[128];
249         int fd;
250
251         snprint(buf, sizeof(buf), "#p/%d/%s", pid, name);
252         fd = open(buf, mode);
253         if(fd < 0)
254                 fprint(2, "init: warning: can't open %s: %r\n", name);
255         return fd;
256 }