Introduction
Introduction Statistics Contact Development Disclaimer Help
tdump9660.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tdump9660.c (9081B)
---
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <disk.h>
5 #include <libsec.h>
6 #include "iso9660.h"
7
8 ulong now;
9 int chatty;
10 int doabort;
11 int docolon;
12 int mk9660;
13 Conform *map;
14
15 static void addprotofile(char *new, char *old, Dir *d, void *a);
16 void usage(void);
17
18 char *argv0;
19
20 void
21 usage(void)
22 {
23 if(mk9660)
24 fprint(2, "usage: mk9660 [-D:] [-9cjr] [-b bootfile] [-p…
25 else
26 fprint(2, "usage: dump9660 [-D:] [-9cjr] [-m maxsize] [-…
27 exits("usage");
28 }
29
30 int
31 main(int argc, char **argv)
32 {
33 int fix;
34 char buf[256], *dumpname, *proto, *s, *src, *status;
35 ulong block, length, newnull, cblock, clength, maxsize;
36 Cdimg *cd;
37 Cdinfo info;
38 XDir dir;
39 Direc *iconform, idumproot, iroot, *jconform, jdumproot, jroot, …
40 Dump *dump;
41
42 fix = 0;
43 status = nil;
44 memset(&info, 0, sizeof info);
45 proto = unsharp("#9/proto/allproto");
46 src = "./";
47
48 info.volumename = atom("9CD");
49 info.volumeset = atom("9VolumeSet");
50 info.publisher = atom("9Publisher");
51 info.preparer = atom("dump9660");
52 info.application = atom("dump9660");
53 info.flags = CDdump;
54 maxsize = 0;
55 mk9660 = 0;
56 fmtinstall('H', encodefmt);
57
58 ARGBEGIN{
59 case 'D':
60 chatty++;
61 break;
62 case 'M':
63 mk9660 = 1;
64 argv0 = "disk/mk9660";
65 info.flags &= ~CDdump;
66 break;
67 case '9':
68 info.flags |= CDplan9;
69 break;
70 case ':':
71 docolon = 1;
72 break;
73 case 'a':
74 doabort = 1;
75 break;
76 case 'b':
77 if(!mk9660)
78 usage();
79 info.flags |= CDbootable;
80 info.bootimage = EARGF(usage());
81 break;
82 case 'c':
83 info.flags |= CDconform;
84 break;
85 case 'f':
86 fix = 1;
87 break;
88 case 'j':
89 info.flags |= CDjoliet;
90 break;
91 case 'n':
92 now = atoi(EARGF(usage()));
93 break;
94 case 'm':
95 maxsize = strtoul(EARGF(usage()), 0, 0);
96 break;
97 case 'p':
98 proto = EARGF(usage());
99 break;
100 case 'r':
101 info.flags |= CDrockridge;
102 break;
103 case 's':
104 src = EARGF(usage());
105 break;
106 case 'v':
107 info.volumename = atom(EARGF(usage()));
108 break;
109 default:
110 usage();
111 }ARGEND
112
113 if(mk9660 && (fix || now || maxsize))
114 usage();
115
116 if(argc != 1)
117 usage();
118
119 if(now == 0)
120 now = (ulong)time(0);
121 if(mk9660){
122 if((cd = createcd(argv[0], info)) == nil)
123 sysfatal("cannot create '%s': %r", argv[0]);
124 }else{
125 if((cd = opencd(argv[0], info)) == nil)
126 sysfatal("cannot open '%s': %r", argv[0]);
127 if(!(cd->flags & CDdump))
128 sysfatal("not a dump cd");
129 }
130
131 /* create ISO9660/Plan 9 tree in memory */
132 memset(&dir, 0, sizeof dir);
133 dir.name = atom("");
134 dir.uid = atom("sys");
135 dir.gid = atom("sys");
136 dir.uidno = 0;
137 dir.gidno = 0;
138 dir.mode = DMDIR | 0755;
139 dir.mtime = now;
140 dir.atime = now;
141 dir.ctime = now;
142
143 mkdirec(&iroot, &dir);
144 iroot.srcfile = src;
145
146 /*
147 * Read new files into memory
148 */
149 if(rdproto(proto, src, addprotofile, 0, &iroot) < 0)
150 sysfatal("rdproto: %r");
151
152 if(mk9660){
153 dump = emalloc(sizeof *dump);
154 dumpname = nil;
155 }else{
156 /*
157 * Read current dump tree and _conform.map.
158 */
159 idumproot = readdumpdirs(cd, &dir, isostring);
160 readdumpconform(cd);
161 if(cd->flags & CDjoliet)
162 jdumproot = readdumpdirs(cd, &dir, jolietstring);
163
164 if(fix){
165 dumpname = nil;
166 cd->nextblock = cd->nulldump+1;
167 cd->nulldump = 0;
168 Cwseek(cd, cd->nextblock*Blocksize);
169 goto Dofix;
170 }
171
172 dumpname = adddumpdir(&idumproot, now, &dir);
173 /* note that we assume all names are conforming and thus…
174 if(cd->flags & CDjoliet) {
175 s = adddumpdir(&jdumproot, now, &dir);
176 if(s != dumpname)
177 sysfatal("dumpnames don't match %s %s\n"…
178 }
179 dump = dumpcd(cd, &idumproot);
180 cd->nextblock = cd->nulldump+1;
181 }
182
183 /*
184 * Write new files, starting where the dump tree was.
185 * Must be done before creation of the Joliet tree so that
186 * blocks and lengths are correct.
187 */
188 Cwseek(cd, cd->nextblock*Blocksize);
189 writefiles(dump, cd, &iroot);
190
191 if(cd->bootimage){
192 findbootimage(cd, &iroot);
193 Cupdatebootcat(cd);
194 }
195
196 /* create Joliet tree */
197 if(cd->flags & CDjoliet)
198 copydirec(&jroot, &iroot);
199
200 if(info.flags & CDconform) {
201 checknames(&iroot, isbadiso9660);
202 convertnames(&iroot, struprcpy);
203 } else
204 convertnames(&iroot, (char* (*)(char*, char*))strcpy);
205
206 /* isoabstract = findconform(&iroot, abstract); */
207 /* isobiblio = findconform(&iroot, biblio); */
208 /* isonotice = findconform(&iroot, notice); */
209
210 dsort(&iroot, isocmp);
211
212 if(cd->flags & CDjoliet) {
213 /* jabstract = findconform(&jroot, abstract); */
214 /* jbiblio = findconform(&jroot, biblio); */
215 /* jnotice = findconform(&jroot, notice); */
216
217 checknames(&jroot, isbadjoliet);
218 convertnames(&jroot, (char* (*)(char*, char*))strcpy);
219 dsort(&jroot, jolietcmp);
220 }
221
222 /*
223 * Write directories.
224 */
225 writedirs(cd, &iroot, Cputisodir);
226 if(cd->flags & CDjoliet)
227 writedirs(cd, &jroot, Cputjolietdir);
228
229 if(mk9660){
230 cblock = 0;
231 clength = 0;
232 newnull = 0;
233 }else{
234 /*
235 * Write incremental _conform.map block.
236 */
237 wrconform(cd, cd->nconform, &cblock, &clength);
238
239 /* jump here if we're just fixing up the cd */
240 Dofix:
241 /*
242 * Write null dump header block; everything after this w…
243 * overwritten at the next dump. Because of this, it ne…
244 * reconstructable. We reconstruct the _conform.map and…
245 * from the header blocks in dump.c, and we reconstruct …
246 * tables by walking the cd.
247 */
248 newnull = Cputdumpblock(cd);
249 }
250
251 /*
252 * Write _conform.map.
253 */
254 dir.mode = 0444;
255 if(cd->flags & (CDconform|CDjoliet)) {
256 if(!mk9660 && cd->nconform == 0){
257 block = cblock;
258 length = clength;
259 }else
260 wrconform(cd, 0, &block, &length);
261
262 if(mk9660)
263 {
264 idumproot = iroot;
265 jdumproot = jroot;
266 }
267 if(length) {
268 /* The ISO9660 name will get turned into upperca…
269 if((iconform = walkdirec(&idumproot, "_conform.m…
270 iconform = adddirec(&idumproot, "_confor…
271 jconform = nil;
272 if(cd->flags & CDjoliet) {
273 if((jconform = walkdirec(&jdumproot, "_c…
274 jconform = adddirec(&jdumproot, …
275 }
276 iconform->block = block;
277 iconform->length = length;
278 if(cd->flags & CDjoliet) {
279 jconform->block = block;
280 jconform->length = length;
281 }
282 }
283 if(mk9660) {
284 iroot = idumproot;
285 jroot = jdumproot;
286 }
287 }
288
289 if(mk9660){
290 /*
291 * Patch in root directories.
292 */
293 setroot(cd, cd->iso9660pvd, iroot.block, iroot.length);
294 setvolsize(cd, cd->iso9660pvd, cd->nextblock*Blocksize);
295 if(cd->flags & CDjoliet){
296 setroot(cd, cd->jolietsvd, jroot.block, jroot.le…
297 setvolsize(cd, cd->jolietsvd, cd->nextblock*Bloc…
298 }
299 }else{
300 /*
301 * Write dump tree at end. We assume the name characters
302 * are all conforming, so everything is already sorted p…
303 */
304 convertnames(&idumproot, (info.flags & CDconform) ? stru…
305 if(cd->nulldump) {
306 r = walkdirec(&idumproot, dumpname);
307 assert(r != nil);
308 copybutname(r, &iroot);
309 }
310 if(cd->flags & CDjoliet) {
311 convertnames(&jdumproot, (char* (*)(char*, char*…
312 if(cd->nulldump) {
313 r = walkdirec(&jdumproot, dumpname);
314 assert(r != nil);
315 copybutname(r, &jroot);
316 }
317 }
318
319 writedumpdirs(cd, &idumproot, Cputisodir);
320 if(cd->flags & CDjoliet)
321 writedumpdirs(cd, &jdumproot, Cputjolietdir);
322
323 /*
324 * Patch in new root directory entry.
325 */
326 setroot(cd, cd->iso9660pvd, idumproot.block, idumproot.l…
327 setvolsize(cd, cd->iso9660pvd, cd->nextblock*Blocksize);
328 if(cd->flags & CDjoliet){
329 setroot(cd, cd->jolietsvd, jdumproot.block, jdum…
330 setvolsize(cd, cd->jolietsvd, cd->nextblock*Bloc…
331 }
332 }
333 writepathtables(cd);
334
335 if(!mk9660){
336 /*
337 * If we've gotten too big, truncate back to what we sta…
338 * fix up the cd, and exit with a non-zero status.
339 */
340 Cwflush(cd);
341 if(cd->nulldump && maxsize && Cwoffset(cd) > maxsize){
342 fprint(2, "too big; writing old tree back\n");
343 status = "cd too big; aborted";
344
345 rmdumpdir(&idumproot, dumpname);
346 rmdumpdir(&jdumproot, dumpname);
347
348 cd->nextblock = cd->nulldump+1;
349 cd->nulldump = 0;
350 Cwseek(cd, cd->nextblock*Blocksize);
351 goto Dofix;
352 }
353
354 /*
355 * Write old null header block; this commits all our cha…
356 */
357 if(cd->nulldump){
358 Cwseek(cd, cd->nulldump*Blocksize);
359 sprint(buf, "plan 9 dump cd\n");
360 sprint(buf+strlen(buf), "%s %lud %lud %lud %lud …
361 dumpname, now, newnull, cblock, clength,…
362 iroot.length);
363 if(cd->flags & CDjoliet)
364 sprint(buf+strlen(buf), " %lud %lud",
365 jroot.block, jroot.length);
366 strcat(buf, "\n");
367 Cwrite(cd, buf, strlen(buf));
368 Cpadblock(cd);
369 Cwflush(cd);
370 }
371 }
372 fdtruncate(cd->fd, cd->nextblock*Blocksize);
373 exits(status);
374 return 0;
375 }
376
377 static void
378 addprotofile(char *new, char *old, Dir *d, void *a)
379 {
380 char *name, *p;
381 Direc *direc;
382 XDir xd;
383
384 dirtoxdir(&xd, d);
385 name = nil;
386 if(docolon && strchr(new, ':')) {
387 name = emalloc(strlen(new)+1);
388 strcpy(name, new);
389 while((p=strchr(name, ':')))
390 *p=' ';
391 new = name;
392 }
393 if((direc = adddirec((Direc*)a, new, &xd))) {
394 direc->srcfile = atom(old);
395
396 /* BUG: abstract, biblio, notice */
397 }
398 if(name)
399 free(name);
400
401 }
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.