Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/disk/9660/dump9660.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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