180ee5cbfSDavid du Colombier #include <u.h>
280ee5cbfSDavid du Colombier #include <libc.h>
380ee5cbfSDavid du Colombier #include <bio.h>
480ee5cbfSDavid du Colombier #include <disk.h>
580ee5cbfSDavid du Colombier #include <libsec.h>
680ee5cbfSDavid du Colombier #include "iso9660.h"
780ee5cbfSDavid du Colombier
880ee5cbfSDavid du Colombier ulong now;
980ee5cbfSDavid du Colombier int chatty;
1080ee5cbfSDavid du Colombier int doabort;
1180ee5cbfSDavid du Colombier int docolon;
1280ee5cbfSDavid du Colombier int mk9660;
1373ee67a1SDavid du Colombier vlong dataoffset;
144fec87e5SDavid du Colombier int blocksize;
1580ee5cbfSDavid du Colombier Conform *map;
1680ee5cbfSDavid du Colombier
1780ee5cbfSDavid du Colombier static void addprotofile(char *new, char *old, Dir *d, void *a);
1880ee5cbfSDavid du Colombier void usage(void);
1980ee5cbfSDavid du Colombier
2080ee5cbfSDavid du Colombier char *argv0;
2180ee5cbfSDavid du Colombier
2280ee5cbfSDavid du Colombier void
usage(void)2380ee5cbfSDavid du Colombier usage(void)
2480ee5cbfSDavid du Colombier {
2580ee5cbfSDavid du Colombier if(mk9660)
269b7bf7dfSDavid du Colombier fprint(2, "usage: disk/mk9660 [-D:] [-9cjr] "
279b7bf7dfSDavid du Colombier "[-[bB] bootfile] [-o offset blocksize] "
289b7bf7dfSDavid du Colombier "[-p proto] [-s src] cdimage\n");
2980ee5cbfSDavid du Colombier else
309b7bf7dfSDavid du Colombier fprint(2, "usage: disk/dump9660 [-D:] [-9cjr] "
319b7bf7dfSDavid du Colombier "[-m maxsize] [-n now] "
329b7bf7dfSDavid du Colombier "[-p proto] [-s src] cdimage\n");
3380ee5cbfSDavid du Colombier exits("usage");
3480ee5cbfSDavid du Colombier }
3580ee5cbfSDavid du Colombier
3673ee67a1SDavid du Colombier void
main(int argc,char ** argv)3780ee5cbfSDavid du Colombier main(int argc, char **argv)
3880ee5cbfSDavid du Colombier {
3980ee5cbfSDavid du Colombier int fix;
4073ee67a1SDavid du Colombier ulong block, newnull, cblock;
4173ee67a1SDavid du Colombier vlong maxsize;
4273ee67a1SDavid du Colombier uvlong length, clength;
4380ee5cbfSDavid du Colombier char buf[256], *dumpname, *proto, *s, *src, *status;
4480ee5cbfSDavid du Colombier Cdimg *cd;
4580ee5cbfSDavid du Colombier Cdinfo info;
4680ee5cbfSDavid du Colombier XDir dir;
4780ee5cbfSDavid du Colombier Direc *iconform, idumproot, iroot, *jconform, jdumproot, jroot, *r;
4880ee5cbfSDavid du Colombier Dump *dump;
4980ee5cbfSDavid du Colombier
5080ee5cbfSDavid du Colombier fix = 0;
5180ee5cbfSDavid du Colombier status = nil;
5280ee5cbfSDavid du Colombier memset(&info, 0, sizeof info);
5380ee5cbfSDavid du Colombier proto = "/sys/lib/sysconfig/proto/allproto";
5480ee5cbfSDavid du Colombier src = "./";
5580ee5cbfSDavid du Colombier
5680ee5cbfSDavid du Colombier info.volumename = atom("9CD");
5780ee5cbfSDavid du Colombier info.volumeset = atom("9VolumeSet");
5880ee5cbfSDavid du Colombier info.publisher = atom("9Publisher");
5980ee5cbfSDavid du Colombier info.preparer = atom("dump9660");
6080ee5cbfSDavid du Colombier info.application = atom("dump9660");
6180ee5cbfSDavid du Colombier info.flags = CDdump;
6280ee5cbfSDavid du Colombier maxsize = 0;
6380ee5cbfSDavid du Colombier mk9660 = 0;
64b7b24591SDavid du Colombier fmtinstall('H', encodefmt);
6580ee5cbfSDavid du Colombier
6680ee5cbfSDavid du Colombier ARGBEGIN{
6780ee5cbfSDavid du Colombier case 'D':
6880ee5cbfSDavid du Colombier chatty++;
6980ee5cbfSDavid du Colombier break;
7080ee5cbfSDavid du Colombier case 'M':
7180ee5cbfSDavid du Colombier mk9660 = 1;
7280ee5cbfSDavid du Colombier argv0 = "disk/mk9660";
7380ee5cbfSDavid du Colombier info.flags &= ~CDdump;
7480ee5cbfSDavid du Colombier break;
7580ee5cbfSDavid du Colombier case '9':
7680ee5cbfSDavid du Colombier info.flags |= CDplan9;
7780ee5cbfSDavid du Colombier break;
7880ee5cbfSDavid du Colombier case ':':
7980ee5cbfSDavid du Colombier docolon = 1;
8080ee5cbfSDavid du Colombier break;
8180ee5cbfSDavid du Colombier case 'a':
8280ee5cbfSDavid du Colombier doabort = 1;
8380ee5cbfSDavid du Colombier break;
8443751f27SDavid du Colombier case 'B':
8543751f27SDavid du Colombier info.flags |= CDbootnoemu;
8643751f27SDavid du Colombier /* fall through */
879a747e4fSDavid du Colombier case 'b':
889a747e4fSDavid du Colombier if(!mk9660)
899a747e4fSDavid du Colombier usage();
909a747e4fSDavid du Colombier info.flags |= CDbootable;
919a747e4fSDavid du Colombier info.bootimage = EARGF(usage());
929a747e4fSDavid du Colombier break;
9380ee5cbfSDavid du Colombier case 'c':
9480ee5cbfSDavid du Colombier info.flags |= CDconform;
9580ee5cbfSDavid du Colombier break;
9680ee5cbfSDavid du Colombier case 'f':
9780ee5cbfSDavid du Colombier fix = 1;
9880ee5cbfSDavid du Colombier break;
9980ee5cbfSDavid du Colombier case 'j':
10080ee5cbfSDavid du Colombier info.flags |= CDjoliet;
10180ee5cbfSDavid du Colombier break;
10280ee5cbfSDavid du Colombier case 'n':
10380ee5cbfSDavid du Colombier now = atoi(EARGF(usage()));
10480ee5cbfSDavid du Colombier break;
10580ee5cbfSDavid du Colombier case 'm':
10673ee67a1SDavid du Colombier maxsize = strtoull(EARGF(usage()), 0, 0);
10780ee5cbfSDavid du Colombier break;
1084fec87e5SDavid du Colombier case 'o':
10973ee67a1SDavid du Colombier dataoffset = atoll(EARGF(usage()));
1104fec87e5SDavid du Colombier blocksize = atoi(EARGF(usage()));
1114fec87e5SDavid du Colombier if(blocksize%Blocksize)
1124fec87e5SDavid du Colombier sysfatal("bad block size %d -- must be multiple of 2048", blocksize);
1134fec87e5SDavid du Colombier blocksize /= Blocksize;
1144fec87e5SDavid du Colombier break;
11580ee5cbfSDavid du Colombier case 'p':
11680ee5cbfSDavid du Colombier proto = EARGF(usage());
11780ee5cbfSDavid du Colombier break;
11880ee5cbfSDavid du Colombier case 'r':
11980ee5cbfSDavid du Colombier info.flags |= CDrockridge;
12080ee5cbfSDavid du Colombier break;
12180ee5cbfSDavid du Colombier case 's':
12280ee5cbfSDavid du Colombier src = EARGF(usage());
12380ee5cbfSDavid du Colombier break;
12480ee5cbfSDavid du Colombier case 'v':
12580ee5cbfSDavid du Colombier info.volumename = atom(EARGF(usage()));
12680ee5cbfSDavid du Colombier break;
127f7db6155SDavid du Colombier case 'x':
128f7db6155SDavid du Colombier info.flags |= CDpbs;
129f7db6155SDavid du Colombier info.loader = EARGF(usage());
130f7db6155SDavid du Colombier break;
13180ee5cbfSDavid du Colombier default:
13280ee5cbfSDavid du Colombier usage();
13380ee5cbfSDavid du Colombier }ARGEND
13480ee5cbfSDavid du Colombier
135f7db6155SDavid du Colombier if(info.flags & CDpbs && !(info.flags & CDbootnoemu))
136f7db6155SDavid du Colombier usage();
137f7db6155SDavid du Colombier
13880ee5cbfSDavid du Colombier if(mk9660 && (fix || now || maxsize))
13980ee5cbfSDavid du Colombier usage();
14080ee5cbfSDavid du Colombier
14180ee5cbfSDavid du Colombier if(argc != 1)
14280ee5cbfSDavid du Colombier usage();
14380ee5cbfSDavid du Colombier
14480ee5cbfSDavid du Colombier if(now == 0)
14580ee5cbfSDavid du Colombier now = (ulong)time(0);
14680ee5cbfSDavid du Colombier if(mk9660){
14780ee5cbfSDavid du Colombier if((cd = createcd(argv[0], info)) == nil)
14880ee5cbfSDavid du Colombier sysfatal("cannot create '%s': %r", argv[0]);
14980ee5cbfSDavid du Colombier }else{
15080ee5cbfSDavid du Colombier if((cd = opencd(argv[0], info)) == nil)
15180ee5cbfSDavid du Colombier sysfatal("cannot open '%s': %r", argv[0]);
15280ee5cbfSDavid du Colombier if(!(cd->flags & CDdump))
15380ee5cbfSDavid du Colombier sysfatal("not a dump cd");
15480ee5cbfSDavid du Colombier }
15580ee5cbfSDavid du Colombier
15680ee5cbfSDavid du Colombier /* create ISO9660/Plan 9 tree in memory */
15780ee5cbfSDavid du Colombier memset(&dir, 0, sizeof dir);
15880ee5cbfSDavid du Colombier dir.name = atom("");
15980ee5cbfSDavid du Colombier dir.uid = atom("sys");
16080ee5cbfSDavid du Colombier dir.gid = atom("sys");
16180ee5cbfSDavid du Colombier dir.uidno = 0;
16280ee5cbfSDavid du Colombier dir.gidno = 0;
1639a747e4fSDavid du Colombier dir.mode = DMDIR | 0755;
16480ee5cbfSDavid du Colombier dir.mtime = now;
16580ee5cbfSDavid du Colombier dir.atime = now;
16680ee5cbfSDavid du Colombier dir.ctime = now;
16780ee5cbfSDavid du Colombier
16880ee5cbfSDavid du Colombier mkdirec(&iroot, &dir);
16980ee5cbfSDavid du Colombier iroot.srcfile = src;
17080ee5cbfSDavid du Colombier
17180ee5cbfSDavid du Colombier /*
17280ee5cbfSDavid du Colombier * Read new files into memory
17380ee5cbfSDavid du Colombier */
17480ee5cbfSDavid du Colombier if(rdproto(proto, src, addprotofile, nil, &iroot) < 0)
17580ee5cbfSDavid du Colombier sysfatal("rdproto: %r");
17680ee5cbfSDavid du Colombier
17780ee5cbfSDavid du Colombier if(mk9660){
17880ee5cbfSDavid du Colombier dump = emalloc(sizeof *dump);
17980ee5cbfSDavid du Colombier dumpname = nil;
18080ee5cbfSDavid du Colombier }else{
18180ee5cbfSDavid du Colombier /*
18280ee5cbfSDavid du Colombier * Read current dump tree and _conform.map.
18380ee5cbfSDavid du Colombier */
18480ee5cbfSDavid du Colombier idumproot = readdumpdirs(cd, &dir, isostring);
18580ee5cbfSDavid du Colombier readdumpconform(cd);
18680ee5cbfSDavid du Colombier if(cd->flags & CDjoliet)
18780ee5cbfSDavid du Colombier jdumproot = readdumpdirs(cd, &dir, jolietstring);
18880ee5cbfSDavid du Colombier
18980ee5cbfSDavid du Colombier if(fix){
19080ee5cbfSDavid du Colombier dumpname = nil;
19180ee5cbfSDavid du Colombier cd->nextblock = cd->nulldump+1;
19280ee5cbfSDavid du Colombier cd->nulldump = 0;
19373ee67a1SDavid du Colombier Cwseek(cd, (vlong)cd->nextblock * Blocksize);
19480ee5cbfSDavid du Colombier goto Dofix;
19580ee5cbfSDavid du Colombier }
19680ee5cbfSDavid du Colombier
19780ee5cbfSDavid du Colombier dumpname = adddumpdir(&idumproot, now, &dir);
19880ee5cbfSDavid du Colombier /* note that we assume all names are conforming and thus sorted */
19980ee5cbfSDavid du Colombier if(cd->flags & CDjoliet) {
20080ee5cbfSDavid du Colombier s = adddumpdir(&jdumproot, now, &dir);
20180ee5cbfSDavid du Colombier if(s != dumpname)
20214cc0f53SDavid du Colombier sysfatal("dumpnames don't match %s %s", dumpname, s);
20380ee5cbfSDavid du Colombier }
20480ee5cbfSDavid du Colombier dump = dumpcd(cd, &idumproot);
20580ee5cbfSDavid du Colombier cd->nextblock = cd->nulldump+1;
20680ee5cbfSDavid du Colombier }
20780ee5cbfSDavid du Colombier
20880ee5cbfSDavid du Colombier /*
20980ee5cbfSDavid du Colombier * Write new files, starting where the dump tree was.
21080ee5cbfSDavid du Colombier * Must be done before creation of the Joliet tree so that
21180ee5cbfSDavid du Colombier * blocks and lengths are correct.
21280ee5cbfSDavid du Colombier */
21373ee67a1SDavid du Colombier if(dataoffset > (vlong)cd->nextblock * Blocksize)
2144fec87e5SDavid du Colombier cd->nextblock = (dataoffset+Blocksize-1)/Blocksize;
21573ee67a1SDavid du Colombier Cwseek(cd, (vlong)cd->nextblock * Blocksize);
21680ee5cbfSDavid du Colombier writefiles(dump, cd, &iroot);
21780ee5cbfSDavid du Colombier
2189a747e4fSDavid du Colombier if(cd->bootimage){
2199a747e4fSDavid du Colombier findbootimage(cd, &iroot);
220f7db6155SDavid du Colombier if(cd->loader)
221f7db6155SDavid du Colombier findloader(cd, &iroot);
2229a747e4fSDavid du Colombier Cupdatebootcat(cd);
2239a747e4fSDavid du Colombier }
2249a747e4fSDavid du Colombier
22580ee5cbfSDavid du Colombier /* create Joliet tree */
22680ee5cbfSDavid du Colombier if(cd->flags & CDjoliet)
22780ee5cbfSDavid du Colombier copydirec(&jroot, &iroot);
22880ee5cbfSDavid du Colombier
22980ee5cbfSDavid du Colombier if(info.flags & CDconform) {
23080ee5cbfSDavid du Colombier checknames(&iroot, isbadiso9660);
23180ee5cbfSDavid du Colombier convertnames(&iroot, struprcpy);
23280ee5cbfSDavid du Colombier } else
23380ee5cbfSDavid du Colombier convertnames(&iroot, (void *) strcpy);
23480ee5cbfSDavid du Colombier
23580ee5cbfSDavid du Colombier // isoabstract = findconform(&iroot, abstract);
23680ee5cbfSDavid du Colombier // isobiblio = findconform(&iroot, biblio);
23780ee5cbfSDavid du Colombier // isonotice = findconform(&iroot, notice);
23880ee5cbfSDavid du Colombier
23980ee5cbfSDavid du Colombier dsort(&iroot, isocmp);
24080ee5cbfSDavid du Colombier
24180ee5cbfSDavid du Colombier if(cd->flags & CDjoliet) {
24280ee5cbfSDavid du Colombier // jabstract = findconform(&jroot, abstract);
24380ee5cbfSDavid du Colombier // jbiblio = findconform(&jroot, biblio);
24480ee5cbfSDavid du Colombier // jnotice = findconform(&jroot, notice);
24580ee5cbfSDavid du Colombier
24680ee5cbfSDavid du Colombier checknames(&jroot, isbadjoliet);
24780ee5cbfSDavid du Colombier convertnames(&jroot, (void *) strcpy);
24880ee5cbfSDavid du Colombier dsort(&jroot, jolietcmp);
24980ee5cbfSDavid du Colombier }
25080ee5cbfSDavid du Colombier
25180ee5cbfSDavid du Colombier /*
25280ee5cbfSDavid du Colombier * Write directories.
25380ee5cbfSDavid du Colombier */
25480ee5cbfSDavid du Colombier writedirs(cd, &iroot, Cputisodir);
25580ee5cbfSDavid du Colombier if(cd->flags & CDjoliet)
25680ee5cbfSDavid du Colombier writedirs(cd, &jroot, Cputjolietdir);
25780ee5cbfSDavid du Colombier
25880ee5cbfSDavid du Colombier if(mk9660){
25980ee5cbfSDavid du Colombier cblock = 0;
26080ee5cbfSDavid du Colombier clength = 0;
26180ee5cbfSDavid du Colombier newnull = 0;
26280ee5cbfSDavid du Colombier }else{
26380ee5cbfSDavid du Colombier /*
26480ee5cbfSDavid du Colombier * Write incremental _conform.map block.
26580ee5cbfSDavid du Colombier */
26680ee5cbfSDavid du Colombier wrconform(cd, cd->nconform, &cblock, &clength);
26780ee5cbfSDavid du Colombier
26880ee5cbfSDavid du Colombier /* jump here if we're just fixing up the cd */
26980ee5cbfSDavid du Colombier Dofix:
27080ee5cbfSDavid du Colombier /*
27180ee5cbfSDavid du Colombier * Write null dump header block; everything after this will be
27280ee5cbfSDavid du Colombier * overwritten at the next dump. Because of this, it needs to be
27380ee5cbfSDavid du Colombier * reconstructable. We reconstruct the _conform.map and dump trees
27480ee5cbfSDavid du Colombier * from the header blocks in dump.c, and we reconstruct the path
27580ee5cbfSDavid du Colombier * tables by walking the cd.
27680ee5cbfSDavid du Colombier */
27780ee5cbfSDavid du Colombier newnull = Cputdumpblock(cd);
27880ee5cbfSDavid du Colombier }
279f7db6155SDavid du Colombier if(info.flags & CDpbs)
280f7db6155SDavid du Colombier Cfillpbs(cd);
28180ee5cbfSDavid du Colombier
28280ee5cbfSDavid du Colombier /*
28380ee5cbfSDavid du Colombier * Write _conform.map.
28480ee5cbfSDavid du Colombier */
28580ee5cbfSDavid du Colombier dir.mode = 0444;
28680ee5cbfSDavid du Colombier if(cd->flags & (CDconform|CDjoliet)) {
28780ee5cbfSDavid du Colombier if(!mk9660 && cd->nconform == 0){
28880ee5cbfSDavid du Colombier block = cblock;
28980ee5cbfSDavid du Colombier length = clength;
29080ee5cbfSDavid du Colombier }else
29180ee5cbfSDavid du Colombier wrconform(cd, 0, &block, &length);
29280ee5cbfSDavid du Colombier
29380ee5cbfSDavid du Colombier if(mk9660)
29480ee5cbfSDavid du Colombier {
29580ee5cbfSDavid du Colombier idumproot = iroot;
29680ee5cbfSDavid du Colombier jdumproot = jroot;
29780ee5cbfSDavid du Colombier }
29880ee5cbfSDavid du Colombier if(length) {
29980ee5cbfSDavid du Colombier /* The ISO9660 name will get turned into uppercase when written. */
30080ee5cbfSDavid du Colombier if((iconform = walkdirec(&idumproot, "_conform.map")) == nil)
30180ee5cbfSDavid du Colombier iconform = adddirec(&idumproot, "_conform.map", &dir);
30280ee5cbfSDavid du Colombier jconform = nil;
30380ee5cbfSDavid du Colombier if(cd->flags & CDjoliet) {
30480ee5cbfSDavid du Colombier if((jconform = walkdirec(&jdumproot, "_conform.map")) == nil)
30580ee5cbfSDavid du Colombier jconform = adddirec(&jdumproot, "_conform.map", &dir);
30680ee5cbfSDavid du Colombier }
30780ee5cbfSDavid du Colombier iconform->block = block;
30880ee5cbfSDavid du Colombier iconform->length = length;
30980ee5cbfSDavid du Colombier if(cd->flags & CDjoliet) {
31080ee5cbfSDavid du Colombier jconform->block = block;
31180ee5cbfSDavid du Colombier jconform->length = length;
31280ee5cbfSDavid du Colombier }
31380ee5cbfSDavid du Colombier }
31480ee5cbfSDavid du Colombier if(mk9660) {
31580ee5cbfSDavid du Colombier iroot = idumproot;
31680ee5cbfSDavid du Colombier jroot = jdumproot;
31780ee5cbfSDavid du Colombier }
31880ee5cbfSDavid du Colombier }
31980ee5cbfSDavid du Colombier
32080ee5cbfSDavid du Colombier if(mk9660){
32180ee5cbfSDavid du Colombier /*
32280ee5cbfSDavid du Colombier * Patch in root directories.
32380ee5cbfSDavid du Colombier */
32480ee5cbfSDavid du Colombier setroot(cd, cd->iso9660pvd, iroot.block, iroot.length);
325*a587111cSDavid du Colombier setvolsize(cd, cd->iso9660pvd, cd->nextblock);
32680ee5cbfSDavid du Colombier if(cd->flags & CDjoliet){
32780ee5cbfSDavid du Colombier setroot(cd, cd->jolietsvd, jroot.block, jroot.length);
328*a587111cSDavid du Colombier setvolsize(cd, cd->jolietsvd, cd->nextblock);
32980ee5cbfSDavid du Colombier }
33080ee5cbfSDavid du Colombier }else{
33180ee5cbfSDavid du Colombier /*
33280ee5cbfSDavid du Colombier * Write dump tree at end. We assume the name characters
33380ee5cbfSDavid du Colombier * are all conforming, so everything is already sorted properly.
33480ee5cbfSDavid du Colombier */
33580ee5cbfSDavid du Colombier convertnames(&idumproot, (info.flags & CDconform) ? (void *) struprcpy : (void *) strcpy);
33680ee5cbfSDavid du Colombier if(cd->nulldump) {
33780ee5cbfSDavid du Colombier r = walkdirec(&idumproot, dumpname);
33880ee5cbfSDavid du Colombier assert(r != nil);
33980ee5cbfSDavid du Colombier copybutname(r, &iroot);
34080ee5cbfSDavid du Colombier }
34180ee5cbfSDavid du Colombier if(cd->flags & CDjoliet) {
34280ee5cbfSDavid du Colombier convertnames(&jdumproot, (void *) strcpy);
34380ee5cbfSDavid du Colombier if(cd->nulldump) {
34480ee5cbfSDavid du Colombier r = walkdirec(&jdumproot, dumpname);
34580ee5cbfSDavid du Colombier assert(r != nil);
34680ee5cbfSDavid du Colombier copybutname(r, &jroot);
34780ee5cbfSDavid du Colombier }
34880ee5cbfSDavid du Colombier }
34980ee5cbfSDavid du Colombier
35080ee5cbfSDavid du Colombier writedumpdirs(cd, &idumproot, Cputisodir);
35180ee5cbfSDavid du Colombier if(cd->flags & CDjoliet)
35280ee5cbfSDavid du Colombier writedumpdirs(cd, &jdumproot, Cputjolietdir);
35380ee5cbfSDavid du Colombier
35480ee5cbfSDavid du Colombier /*
35580ee5cbfSDavid du Colombier * Patch in new root directory entry.
35680ee5cbfSDavid du Colombier */
35780ee5cbfSDavid du Colombier setroot(cd, cd->iso9660pvd, idumproot.block, idumproot.length);
358*a587111cSDavid du Colombier setvolsize(cd, cd->iso9660pvd, cd->nextblock);
35980ee5cbfSDavid du Colombier if(cd->flags & CDjoliet){
36080ee5cbfSDavid du Colombier setroot(cd, cd->jolietsvd, jdumproot.block, jdumproot.length);
361*a587111cSDavid du Colombier setvolsize(cd, cd->jolietsvd, cd->nextblock);
36280ee5cbfSDavid du Colombier }
36380ee5cbfSDavid du Colombier }
36480ee5cbfSDavid du Colombier writepathtables(cd);
36580ee5cbfSDavid du Colombier
36680ee5cbfSDavid du Colombier if(!mk9660){
36780ee5cbfSDavid du Colombier /*
36880ee5cbfSDavid du Colombier * If we've gotten too big, truncate back to what we started with,
36980ee5cbfSDavid du Colombier * fix up the cd, and exit with a non-zero status.
37080ee5cbfSDavid du Colombier */
37180ee5cbfSDavid du Colombier Cwflush(cd);
37280ee5cbfSDavid du Colombier if(cd->nulldump && maxsize && Cwoffset(cd) > maxsize){
37380ee5cbfSDavid du Colombier fprint(2, "too big; writing old tree back\n");
37480ee5cbfSDavid du Colombier status = "cd too big; aborted";
37580ee5cbfSDavid du Colombier
37680ee5cbfSDavid du Colombier rmdumpdir(&idumproot, dumpname);
37780ee5cbfSDavid du Colombier rmdumpdir(&jdumproot, dumpname);
37880ee5cbfSDavid du Colombier
37980ee5cbfSDavid du Colombier cd->nextblock = cd->nulldump+1;
38080ee5cbfSDavid du Colombier cd->nulldump = 0;
38173ee67a1SDavid du Colombier Cwseek(cd, (vlong)cd->nextblock * Blocksize);
38280ee5cbfSDavid du Colombier goto Dofix;
38380ee5cbfSDavid du Colombier }
38480ee5cbfSDavid du Colombier
38580ee5cbfSDavid du Colombier /*
38680ee5cbfSDavid du Colombier * Write old null header block; this commits all our changes.
38780ee5cbfSDavid du Colombier */
38880ee5cbfSDavid du Colombier if(cd->nulldump){
38973ee67a1SDavid du Colombier Cwseek(cd, (vlong)cd->nulldump * Blocksize);
39080ee5cbfSDavid du Colombier sprint(buf, "plan 9 dump cd\n");
39173ee67a1SDavid du Colombier sprint(buf+strlen(buf), "%s %lud %lud %lud %llud %lud %lud",
39273ee67a1SDavid du Colombier dumpname, now, newnull, cblock, clength,
39373ee67a1SDavid du Colombier iroot.block, iroot.length);
39480ee5cbfSDavid du Colombier if(cd->flags & CDjoliet)
39580ee5cbfSDavid du Colombier sprint(buf+strlen(buf), " %lud %lud",
39680ee5cbfSDavid du Colombier jroot.block, jroot.length);
39780ee5cbfSDavid du Colombier strcat(buf, "\n");
39880ee5cbfSDavid du Colombier Cwrite(cd, buf, strlen(buf));
39980ee5cbfSDavid du Colombier Cpadblock(cd);
40080ee5cbfSDavid du Colombier Cwflush(cd);
40180ee5cbfSDavid du Colombier }
40280ee5cbfSDavid du Colombier }
40373ee67a1SDavid du Colombier fdtruncate(cd->fd, (vlong)cd->nextblock * Blocksize);
40480ee5cbfSDavid du Colombier exits(status);
40580ee5cbfSDavid du Colombier }
40680ee5cbfSDavid du Colombier
40780ee5cbfSDavid du Colombier static void
addprotofile(char * new,char * old,Dir * d,void * a)40880ee5cbfSDavid du Colombier addprotofile(char *new, char *old, Dir *d, void *a)
40980ee5cbfSDavid du Colombier {
41080ee5cbfSDavid du Colombier char *name, *p;
41180ee5cbfSDavid du Colombier Direc *direc;
41280ee5cbfSDavid du Colombier XDir xd;
41380ee5cbfSDavid du Colombier
41480ee5cbfSDavid du Colombier dirtoxdir(&xd, d);
41580ee5cbfSDavid du Colombier name = nil;
41680ee5cbfSDavid du Colombier if(docolon && strchr(new, ':')) {
41780ee5cbfSDavid du Colombier name = emalloc(strlen(new)+1);
41880ee5cbfSDavid du Colombier strcpy(name, new);
41980ee5cbfSDavid du Colombier while((p=strchr(name, ':')))
42080ee5cbfSDavid du Colombier *p=' ';
42180ee5cbfSDavid du Colombier new = name;
42280ee5cbfSDavid du Colombier }
42380ee5cbfSDavid du Colombier if((direc = adddirec((Direc*)a, new, &xd))) {
42480ee5cbfSDavid du Colombier direc->srcfile = atom(old);
42580ee5cbfSDavid du Colombier
42680ee5cbfSDavid du Colombier // BUG: abstract, biblio, notice
42780ee5cbfSDavid du Colombier }
42880ee5cbfSDavid du Colombier if(name)
42980ee5cbfSDavid du Colombier free(name);
43080ee5cbfSDavid du Colombier }
431