]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/rebootcmd.c
fix fuckup
[plan9front.git] / sys / src / 9 / port / rebootcmd.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6 #include        "../port/error.h"
7 #include        "a.out.h"
8
9 static ulong
10 l2be(long l)
11 {
12         uchar *cp;
13
14         cp = (uchar*)&l;
15         return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3];
16 }
17
18
19 static void
20 readn(Chan *c, void *vp, long n)
21 {
22         char *p = vp;
23         long nn;
24
25         while(n > 0) {
26                 nn = devtab[c->type]->read(c, p, n, c->offset);
27                 if(nn == 0)
28                         error(Eshort);
29                 c->offset += nn;
30                 p += nn;
31                 n -= nn;
32         }
33 }
34
35 static void
36 setbootcmd(int argc, char *argv[])
37 {
38         char *buf, *p, *ep;
39         int i;
40
41         p = buf = smalloc(1024);
42         ep = buf + 1024;
43         for(i=0; i<argc; i++)
44                 p = seprint(p, ep, "%q ", argv[i]);
45         *p = 0;
46         ksetenv("bootcmd", buf, 1);
47         free(buf);
48 }
49
50 void
51 rebootcmd(int argc, char *argv[])
52 {
53         Chan *c;
54         Exec exec;
55         ulong magic, text, rtext, entry, data, size;
56         uchar *p;
57
58         if(argc == 0)
59                 exit(0);
60
61         c = namec(argv[0], Aopen, OEXEC, 0);
62         if(waserror()){
63                 cclose(c);
64                 nexterror();
65         }
66
67         readn(c, &exec, sizeof(Exec));
68         magic = l2be(exec.magic);
69         entry = l2be(exec.entry);
70         text = l2be(exec.text);
71         data = l2be(exec.data);
72
73         if(!(magic == AOUT_MAGIC)){
74                 switch(magic){
75                 case I_MAGIC:
76                 case S_MAGIC:
77                         if((I_MAGIC == AOUT_MAGIC) || (S_MAGIC == AOUT_MAGIC))
78                                 break;
79                 default:
80                         error(Ebadexec);
81                 }
82         }
83         if(magic & HDR_MAGIC)
84                 readn(c, &exec, 8);
85
86         /* round text out to page boundary */
87         rtext = PGROUND(entry+text)-entry;
88         size = rtext + data;
89         p = malloc(size);
90         if(p == nil)
91                 error(Enomem);
92
93         if(waserror()){
94                 free(p);
95                 nexterror();
96         }
97
98         memset(p, 0, size);
99         readn(c, p, text);
100         readn(c, p + rtext, data);
101
102         ksetenv("bootfile", argv[0], 1);
103         setbootcmd(argc-1, argv+1);
104
105         reboot((void*)entry, p, size);
106
107         panic("return from reboot!");
108 }