]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/bitsy/bitsyload.c
ip/cifsd: dont return garbage in upper 32 bit of unix extension stat fields
[plan9front.git] / sys / src / cmd / bitsy / bitsyload.c
1 #include <u.h>
2 #include <libc.h>
3
4 enum
5 {
6         Magic= 0x5a5abeef,
7 };
8
9 typedef struct Method Method;
10 struct Method {
11         char *verb;
12         char *part;
13         char *file;
14 };
15
16 Method method[] =
17 {
18         { "k", "/dev/flash/kernel", "/sys/src/9/bitsy/9bitsy" },
19         { "r", "/dev/flash/ramdisk", "/sys/src/9/bitsy/paqdisk" },
20         { "u", "/dev/flash/user", "/sys/src/9/bitsy/user" },
21 };
22
23 void
24 leputl(uchar *p, ulong x)
25 {
26         *p++ = x;
27         *p++ = x>>8;
28         *p++ = x>>16;
29         *p = x>>24;
30 }
31
32 void
33 usage(void)
34 {
35         fprint(2, "usage: %s k|r [file]\n", argv0);
36         exits("usage"); 
37 }
38
39 void
40 main(int argc, char **argv)
41 {
42         char *file;
43         int ctl, in, out;
44         int i, n;
45         uchar *buf;
46         char ctlfile[64];
47         char ctldata[1024];
48         char *args[10];
49         Dir *d;
50         ulong nsects, sectsize;
51         Method *m;
52
53         ARGBEGIN {
54         } ARGEND;
55
56         if(argc == 0)
57                 usage();
58
59         for(m = method; m < method + nelem(method); m++)
60                 if(strcmp(argv[0], m->verb) == 0)
61                         break;
62         if(m == method + nelem(method))
63                 usage();
64
65         if(argc < 2)
66                 file = m->file;
67         else
68                 file = argv[1];
69
70         in = open(file, OREAD);
71         if(in < 0)
72                 sysfatal("%s: %r", file);
73         d = dirfstat(in);
74         if(d == nil)
75                 sysfatal("stating %s: %r", file);
76
77         out = open(m->part, OWRITE);
78         if(out < 0)
79                 sysfatal("%s: %r", m->part);
80         sprint(ctlfile, "%sctl", m->part);
81         ctl = open(ctlfile, ORDWR);
82         if(ctl < 0)
83                 sysfatal("%s: %r", ctlfile);
84
85         i = read(ctl, ctldata, sizeof(ctldata) - 1);
86         if (i <= 0)
87                 sysfatal("%s: %r", ctlfile);
88         ctldata[i] = '\0';
89         i = tokenize(ctldata, args, nelem(args));
90         if(i < 7)
91                 sysfatal("bad flash geometry");
92
93         nsects = atoi(args[5]);
94         sectsize = atoi(args[6]);
95         if(nsects < 3)
96                 sysfatal("unreasonable value for nsects: %lud", nsects);
97         if(sectsize < 512)
98                 sysfatal("unreasonable value for sectsize: %lud", sectsize);
99
100         /* allocate a buffer and read in the whole file */
101         n = d->length;
102         buf = malloc(n + sectsize);
103         if(buf == nil)
104                 sysfatal("not enough room to read in file: %r");
105
106         print("reading %d bytes of %s\n", n, file);
107         if(readn(in, buf, n) != n)
108                 sysfatal("error reading file: %r");
109         close(in);
110
111         memset(buf + n, 0, sectsize);
112         n = ((n+sectsize-1)/sectsize)*sectsize;
113
114         if (nsects * sectsize < n)
115                 sysfatal("file too large (%d) for partition (%lud)", n, nsects * sectsize);
116
117         print("erasing %s\n", m->part);
118         if(fprint(ctl, "erase") < 0)
119                 sysfatal("erase %s: %r", ctlfile);
120         close(ctl);
121         print("writing %s\n", m->part);
122
123         for (i = 0; i < n; i += sectsize)
124                 if(write(out, buf + i, sectsize) != sectsize)
125                         sysfatal("writing %s at %d: %r", file, i);
126
127         print("write done\n");
128         close(in);
129         close(out);
130 }