180ee5cbfSDavid du Colombier #include <u.h> 280ee5cbfSDavid du Colombier #include <libc.h> 380ee5cbfSDavid du Colombier #include <bio.h> 480ee5cbfSDavid du Colombier #include <libsec.h> 580ee5cbfSDavid du Colombier 680ee5cbfSDavid du Colombier #include "iso9660.h" 780ee5cbfSDavid du Colombier 880ee5cbfSDavid du Colombier static void 980ee5cbfSDavid du Colombier writelittlebig4(uchar *buf, ulong x) 1080ee5cbfSDavid du Colombier { 1180ee5cbfSDavid du Colombier buf[0] = buf[7] = x; 1280ee5cbfSDavid du Colombier buf[1] = buf[6] = x>>8; 1380ee5cbfSDavid du Colombier buf[2] = buf[5] = x>>16; 1480ee5cbfSDavid du Colombier buf[3] = buf[4] = x>>24; 1580ee5cbfSDavid du Colombier } 1680ee5cbfSDavid du Colombier 1780ee5cbfSDavid du Colombier void 1880ee5cbfSDavid du Colombier rewritedot(Cdimg *cd, Direc *d) 1980ee5cbfSDavid du Colombier { 2080ee5cbfSDavid du Colombier uchar buf[Blocksize]; 2180ee5cbfSDavid du Colombier Cdir *c; 2280ee5cbfSDavid du Colombier 2380ee5cbfSDavid du Colombier Creadblock(cd, buf, d->block, Blocksize); 2480ee5cbfSDavid du Colombier c = (Cdir*)buf; 2580ee5cbfSDavid du Colombier assert(c->len != 0); 2680ee5cbfSDavid du Colombier assert(c->namelen == 1 && c->name[0] == '\0'); /* dot */ 2780ee5cbfSDavid du Colombier writelittlebig4(c->dloc, d->block); 2880ee5cbfSDavid du Colombier writelittlebig4(c->dlen, d->length); 2980ee5cbfSDavid du Colombier 3080ee5cbfSDavid du Colombier Cwseek(cd, d->block*Blocksize); 3180ee5cbfSDavid du Colombier Cwrite(cd, buf, Blocksize); 3280ee5cbfSDavid du Colombier } 3380ee5cbfSDavid du Colombier 3480ee5cbfSDavid du Colombier void 3580ee5cbfSDavid du Colombier rewritedotdot(Cdimg *cd, Direc *d, Direc *dparent) 3680ee5cbfSDavid du Colombier { 3780ee5cbfSDavid du Colombier uchar buf[Blocksize]; 3880ee5cbfSDavid du Colombier Cdir *c; 3980ee5cbfSDavid du Colombier 4080ee5cbfSDavid du Colombier Creadblock(cd, buf, d->block, Blocksize); 4180ee5cbfSDavid du Colombier c = (Cdir*)buf; 4280ee5cbfSDavid du Colombier assert(c->len != 0); 4380ee5cbfSDavid du Colombier assert(c->namelen == 1 && c->name[0] == '\0'); /* dot */ 4480ee5cbfSDavid du Colombier 4580ee5cbfSDavid du Colombier c = (Cdir*)(buf+c->len); 4680ee5cbfSDavid du Colombier assert(c->len != 0); 4780ee5cbfSDavid du Colombier assert(c->namelen == 1 && c->name[0] == '\001'); /* dotdot*/ 4880ee5cbfSDavid du Colombier 4980ee5cbfSDavid du Colombier writelittlebig4(c->dloc, dparent->block); 5080ee5cbfSDavid du Colombier writelittlebig4(c->dlen, dparent->length); 5180ee5cbfSDavid du Colombier 5280ee5cbfSDavid du Colombier Cwseek(cd, d->block*Blocksize); 5380ee5cbfSDavid du Colombier Cwrite(cd, buf, Blocksize); 5480ee5cbfSDavid du Colombier } 5580ee5cbfSDavid du Colombier 5680ee5cbfSDavid du Colombier /* 5780ee5cbfSDavid du Colombier * Write each non-directory file. We copy the file to 5880ee5cbfSDavid du Colombier * the cd image, and then if it turns out that we've 5980ee5cbfSDavid du Colombier * seen this stream of bits before, we push the next block 6080ee5cbfSDavid du Colombier * pointer back. This ensures consistency between the MD5s 6180ee5cbfSDavid du Colombier * and the data on the CD image. MD5 summing on one pass 6280ee5cbfSDavid du Colombier * and copying on another would not ensure this. 6380ee5cbfSDavid du Colombier */ 6480ee5cbfSDavid du Colombier void 6580ee5cbfSDavid du Colombier writefiles(Dump *d, Cdimg *cd, Direc *direc) 6680ee5cbfSDavid du Colombier { 6780ee5cbfSDavid du Colombier int i; 6880ee5cbfSDavid du Colombier uchar buf[8192], digest[MD5dlen]; 6980ee5cbfSDavid du Colombier ulong length, n, start; 7080ee5cbfSDavid du Colombier Biobuf *b; 7180ee5cbfSDavid du Colombier DigestState *s; 7280ee5cbfSDavid du Colombier Dumpdir *dd; 7380ee5cbfSDavid du Colombier 749a747e4fSDavid du Colombier if(direc->mode & DMDIR) { 7580ee5cbfSDavid du Colombier for(i=0; i<direc->nchild; i++) 7680ee5cbfSDavid du Colombier writefiles(d, cd, &direc->child[i]); 7780ee5cbfSDavid du Colombier return; 7880ee5cbfSDavid du Colombier } 7980ee5cbfSDavid du Colombier 8080ee5cbfSDavid du Colombier assert(direc->block == 0); 8180ee5cbfSDavid du Colombier 8280ee5cbfSDavid du Colombier if((b = Bopen(direc->srcfile, OREAD)) == nil){ 839a747e4fSDavid du Colombier fprint(2, "warning: cannot open '%s': %r\n", direc->srcfile); 8480ee5cbfSDavid du Colombier direc->block = 0; 8580ee5cbfSDavid du Colombier direc->length = 0; 8680ee5cbfSDavid du Colombier return; 8780ee5cbfSDavid du Colombier } 8880ee5cbfSDavid du Colombier 8980ee5cbfSDavid du Colombier start = cd->nextblock; 9080ee5cbfSDavid du Colombier assert(start != 0); 9180ee5cbfSDavid du Colombier 9280ee5cbfSDavid du Colombier Cwseek(cd, start*Blocksize); 9380ee5cbfSDavid du Colombier 9480ee5cbfSDavid du Colombier s = md5(nil, 0, nil, nil); 9580ee5cbfSDavid du Colombier length = 0; 9680ee5cbfSDavid du Colombier while((n = Bread(b, buf, sizeof buf)) > 0) { 9780ee5cbfSDavid du Colombier md5(buf, n, nil, s); 9880ee5cbfSDavid du Colombier Cwrite(cd, buf, n); 9980ee5cbfSDavid du Colombier length += n; 10080ee5cbfSDavid du Colombier } 10180ee5cbfSDavid du Colombier md5(nil, 0, digest, s); 10280ee5cbfSDavid du Colombier Bterm(b); 10380ee5cbfSDavid du Colombier Cpadblock(cd); 10480ee5cbfSDavid du Colombier 10580ee5cbfSDavid du Colombier if(length != direc->length) { 10680ee5cbfSDavid du Colombier fprint(2, "warning: %s changed size underfoot\n", direc->srcfile); 10780ee5cbfSDavid du Colombier direc->length = length; 10880ee5cbfSDavid du Colombier } 10980ee5cbfSDavid du Colombier 11080ee5cbfSDavid du Colombier if(length == 0) 11180ee5cbfSDavid du Colombier direc->block = 0; 11280ee5cbfSDavid du Colombier else if((dd = lookupmd5(d, digest))) { 11380ee5cbfSDavid du Colombier assert(dd->length == length); 11480ee5cbfSDavid du Colombier assert(dd->block != 0); 11580ee5cbfSDavid du Colombier direc->block = dd->block; 11680ee5cbfSDavid du Colombier cd->nextblock = start; 11780ee5cbfSDavid du Colombier } else { 11880ee5cbfSDavid du Colombier direc->block = start; 119*b7b24591SDavid du Colombier if(chatty) 120*b7b24591SDavid du Colombier fprint(2, "lookup %.16H %lud (%s) failed\n", digest, length, direc->name); 12180ee5cbfSDavid du Colombier insertmd5(d, atom(direc->name), digest, start, length); 12280ee5cbfSDavid du Colombier } 12380ee5cbfSDavid du Colombier } 12480ee5cbfSDavid du Colombier 12580ee5cbfSDavid du Colombier /* 12680ee5cbfSDavid du Colombier * Write a directory tree. We work from the leaves, 12780ee5cbfSDavid du Colombier * and patch the dotdot pointers afterward. 12880ee5cbfSDavid du Colombier */ 12980ee5cbfSDavid du Colombier static void 13080ee5cbfSDavid du Colombier _writedirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int), int level) 13180ee5cbfSDavid du Colombier { 13280ee5cbfSDavid du Colombier int i, l, ll; 13380ee5cbfSDavid du Colombier ulong start, next; 13480ee5cbfSDavid du Colombier 1359a747e4fSDavid du Colombier if((d->mode & DMDIR) == 0) 13680ee5cbfSDavid du Colombier return; 13780ee5cbfSDavid du Colombier 13880ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 13980ee5cbfSDavid du Colombier writedirs(cd, &d->child[i], put); 14080ee5cbfSDavid du Colombier 14180ee5cbfSDavid du Colombier l = 0; 14280ee5cbfSDavid du Colombier l += put(cd, d, (level == 0) ? DTrootdot : DTdot, 0, l); 14380ee5cbfSDavid du Colombier l += put(cd, nil, DTdotdot, 0, l); 14480ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 14580ee5cbfSDavid du Colombier l += put(cd, &d->child[i], DTiden, 0, l); 14680ee5cbfSDavid du Colombier 14780ee5cbfSDavid du Colombier start = cd->nextblock; 14880ee5cbfSDavid du Colombier cd->nextblock += (l+Blocksize-1)/Blocksize; 14980ee5cbfSDavid du Colombier next = cd->nextblock; 15080ee5cbfSDavid du Colombier 15180ee5cbfSDavid du Colombier Cwseek(cd, start*Blocksize); 15280ee5cbfSDavid du Colombier ll = 0; 15380ee5cbfSDavid du Colombier ll += put(cd, d, (level == 0) ? DTrootdot : DTdot, 1, ll); 15480ee5cbfSDavid du Colombier ll += put(cd, nil, DTdotdot, 1, ll); 15580ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 15680ee5cbfSDavid du Colombier ll += put(cd, &d->child[i], DTiden, 1, ll); 15780ee5cbfSDavid du Colombier assert(ll == l); 15880ee5cbfSDavid du Colombier Cpadblock(cd); 15980ee5cbfSDavid du Colombier assert(Cwoffset(cd) == next*Blocksize); 16080ee5cbfSDavid du Colombier 16180ee5cbfSDavid du Colombier d->block = start; 16280ee5cbfSDavid du Colombier d->length = (next - start) * Blocksize; 16380ee5cbfSDavid du Colombier rewritedot(cd, d); 16480ee5cbfSDavid du Colombier rewritedotdot(cd, d, d); 16580ee5cbfSDavid du Colombier 16680ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 1679a747e4fSDavid du Colombier if(d->child[i].mode & DMDIR) 16880ee5cbfSDavid du Colombier rewritedotdot(cd, &d->child[i], d); 16980ee5cbfSDavid du Colombier } 17080ee5cbfSDavid du Colombier 17180ee5cbfSDavid du Colombier void 17280ee5cbfSDavid du Colombier writedirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int)) 17380ee5cbfSDavid du Colombier { 17480ee5cbfSDavid du Colombier /* 17580ee5cbfSDavid du Colombier * If we're writing a mk9660 image, then the root really 17680ee5cbfSDavid du Colombier * is the root, so start at level 0. If we're writing a dump image, 17780ee5cbfSDavid du Colombier * then the "root" is really going to be two levels down once 17880ee5cbfSDavid du Colombier * we patch in the dump hierarchy above it, so start at level non-zero. 17980ee5cbfSDavid du Colombier */ 18080ee5cbfSDavid du Colombier _writedirs(cd, d, put, mk9660 ? 0 : 1); 18180ee5cbfSDavid du Colombier } 18280ee5cbfSDavid du Colombier 18380ee5cbfSDavid du Colombier 18480ee5cbfSDavid du Colombier /* 18580ee5cbfSDavid du Colombier * Write the dump tree. This is like writedirs but once we get to 18680ee5cbfSDavid du Colombier * the roots of the individual days we just patch the parent dotdot blocks. 18780ee5cbfSDavid du Colombier */ 18880ee5cbfSDavid du Colombier static void 18980ee5cbfSDavid du Colombier _writedumpdirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int), int level) 19080ee5cbfSDavid du Colombier { 19180ee5cbfSDavid du Colombier int i; 19280ee5cbfSDavid du Colombier ulong start; 19380ee5cbfSDavid du Colombier 19480ee5cbfSDavid du Colombier switch(level) { 19580ee5cbfSDavid du Colombier case 0: 19680ee5cbfSDavid du Colombier /* write root, list of years, also conform.map */ 19780ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 1989a747e4fSDavid du Colombier if(d->child[i].mode & DMDIR) 19980ee5cbfSDavid du Colombier _writedumpdirs(cd, &d->child[i], put, level+1); 20080ee5cbfSDavid du Colombier chat("write dump root dir at %lud\n", cd->nextblock); 20180ee5cbfSDavid du Colombier goto Writedir; 20280ee5cbfSDavid du Colombier 20380ee5cbfSDavid du Colombier case 1: /* write year, list of days */ 20480ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 20580ee5cbfSDavid du Colombier _writedumpdirs(cd, &d->child[i], put, level+1); 20680ee5cbfSDavid du Colombier chat("write dump %s dir at %lud\n", d->name, cd->nextblock); 20780ee5cbfSDavid du Colombier goto Writedir; 20880ee5cbfSDavid du Colombier 20980ee5cbfSDavid du Colombier Writedir: 21080ee5cbfSDavid du Colombier start = cd->nextblock; 21180ee5cbfSDavid du Colombier Cwseek(cd, start*Blocksize); 21280ee5cbfSDavid du Colombier 21380ee5cbfSDavid du Colombier put(cd, d, (level == 0) ? DTrootdot : DTdot, 1, Cwoffset(cd)); 21480ee5cbfSDavid du Colombier put(cd, nil, DTdotdot, 1, Cwoffset(cd)); 21580ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 21680ee5cbfSDavid du Colombier put(cd, &d->child[i], DTiden, 1, Cwoffset(cd)); 21780ee5cbfSDavid du Colombier Cpadblock(cd); 21880ee5cbfSDavid du Colombier 21980ee5cbfSDavid du Colombier d->block = start; 22080ee5cbfSDavid du Colombier d->length = (cd->nextblock - start) * Blocksize; 22180ee5cbfSDavid du Colombier 22280ee5cbfSDavid du Colombier rewritedot(cd, d); 22380ee5cbfSDavid du Colombier rewritedotdot(cd, d, d); 22480ee5cbfSDavid du Colombier 22580ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 2269a747e4fSDavid du Colombier if(d->child[i].mode & DMDIR) 22780ee5cbfSDavid du Colombier rewritedotdot(cd, &d->child[i], d); 22880ee5cbfSDavid du Colombier break; 22980ee5cbfSDavid du Colombier 23080ee5cbfSDavid du Colombier case 2: /* write day: already written, do nothing */ 23180ee5cbfSDavid du Colombier break; 23280ee5cbfSDavid du Colombier 23380ee5cbfSDavid du Colombier default: 23480ee5cbfSDavid du Colombier assert(0); 23580ee5cbfSDavid du Colombier } 23680ee5cbfSDavid du Colombier } 23780ee5cbfSDavid du Colombier 23880ee5cbfSDavid du Colombier void 23980ee5cbfSDavid du Colombier writedumpdirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int)) 24080ee5cbfSDavid du Colombier { 24180ee5cbfSDavid du Colombier _writedumpdirs(cd, d, put, 0); 24280ee5cbfSDavid du Colombier } 24380ee5cbfSDavid du Colombier 24480ee5cbfSDavid du Colombier static int 24580ee5cbfSDavid du Colombier Cputplan9(Cdimg *cd, Direc *d, int dot, int dowrite) 24680ee5cbfSDavid du Colombier { 24780ee5cbfSDavid du Colombier int l, n; 24880ee5cbfSDavid du Colombier 24980ee5cbfSDavid du Colombier if(dot != DTiden) 25080ee5cbfSDavid du Colombier return 0; 25180ee5cbfSDavid du Colombier 25280ee5cbfSDavid du Colombier l = 0; 25380ee5cbfSDavid du Colombier if(d->flags & Dbadname) { 25480ee5cbfSDavid du Colombier n = strlen(d->name); 25580ee5cbfSDavid du Colombier l += 1+n; 25680ee5cbfSDavid du Colombier if(dowrite) { 25780ee5cbfSDavid du Colombier Cputc(cd, n); 25880ee5cbfSDavid du Colombier Cputs(cd, d->name, n); 25980ee5cbfSDavid du Colombier } 26080ee5cbfSDavid du Colombier } else { 26180ee5cbfSDavid du Colombier l++; 26280ee5cbfSDavid du Colombier if(dowrite) 26380ee5cbfSDavid du Colombier Cputc(cd, 0); 26480ee5cbfSDavid du Colombier } 26580ee5cbfSDavid du Colombier 26680ee5cbfSDavid du Colombier n = strlen(d->uid); 26780ee5cbfSDavid du Colombier l += 1+n; 26880ee5cbfSDavid du Colombier if(dowrite) { 26980ee5cbfSDavid du Colombier Cputc(cd, n); 27080ee5cbfSDavid du Colombier Cputs(cd, d->uid, n); 27180ee5cbfSDavid du Colombier } 27280ee5cbfSDavid du Colombier 27380ee5cbfSDavid du Colombier n = strlen(d->gid); 27480ee5cbfSDavid du Colombier l += 1+n; 27580ee5cbfSDavid du Colombier if(dowrite) { 27680ee5cbfSDavid du Colombier Cputc(cd, n); 27780ee5cbfSDavid du Colombier Cputs(cd, d->gid, n); 27880ee5cbfSDavid du Colombier } 27980ee5cbfSDavid du Colombier 28080ee5cbfSDavid du Colombier if(l & 1) { 28180ee5cbfSDavid du Colombier l++; 28280ee5cbfSDavid du Colombier if(dowrite) 28380ee5cbfSDavid du Colombier Cputc(cd, 0); 28480ee5cbfSDavid du Colombier } 28580ee5cbfSDavid du Colombier l += 8; 28680ee5cbfSDavid du Colombier if(dowrite) 28780ee5cbfSDavid du Colombier Cputn(cd, d->mode, 4); 28880ee5cbfSDavid du Colombier 28980ee5cbfSDavid du Colombier return l; 29080ee5cbfSDavid du Colombier } 29180ee5cbfSDavid du Colombier 29280ee5cbfSDavid du Colombier /* 29380ee5cbfSDavid du Colombier * Write a directory entry. 29480ee5cbfSDavid du Colombier */ 29580ee5cbfSDavid du Colombier static int 29680ee5cbfSDavid du Colombier genputdir(Cdimg *cd, Direc *d, int dot, int joliet, int dowrite, int offset) 29780ee5cbfSDavid du Colombier { 29880ee5cbfSDavid du Colombier int f, n, l, lp; 29980ee5cbfSDavid du Colombier long o; 30080ee5cbfSDavid du Colombier 30180ee5cbfSDavid du Colombier f = 0; 3029a747e4fSDavid du Colombier if(dot != DTiden || (d->mode & DMDIR)) 30380ee5cbfSDavid du Colombier f |= 2; 30480ee5cbfSDavid du Colombier 30580ee5cbfSDavid du Colombier n = 1; 30680ee5cbfSDavid du Colombier if(dot == DTiden) { 30780ee5cbfSDavid du Colombier if(joliet) 30880ee5cbfSDavid du Colombier n = 2*utflen(d->confname); 30980ee5cbfSDavid du Colombier else 31080ee5cbfSDavid du Colombier n = strlen(d->confname); 31180ee5cbfSDavid du Colombier } 31280ee5cbfSDavid du Colombier 31380ee5cbfSDavid du Colombier l = 33+n; 31480ee5cbfSDavid du Colombier if(l & 1) 31580ee5cbfSDavid du Colombier l++; 31680ee5cbfSDavid du Colombier assert(l <= 255); 31780ee5cbfSDavid du Colombier 31880ee5cbfSDavid du Colombier if(joliet == 0) { 31980ee5cbfSDavid du Colombier if(cd->flags & CDplan9) 32080ee5cbfSDavid du Colombier l += Cputplan9(cd, d, dot, 0); 32180ee5cbfSDavid du Colombier else if(cd->flags & CDrockridge) 32280ee5cbfSDavid du Colombier l += Cputsysuse(cd, d, dot, 0, l); 32380ee5cbfSDavid du Colombier assert(l <= 255); 32480ee5cbfSDavid du Colombier } 32580ee5cbfSDavid du Colombier 32680ee5cbfSDavid du Colombier if(dowrite == 0) { 32780ee5cbfSDavid du Colombier if(Blocksize - offset%Blocksize < l) 32880ee5cbfSDavid du Colombier l += Blocksize - offset%Blocksize; 32980ee5cbfSDavid du Colombier return l; 33080ee5cbfSDavid du Colombier } 33180ee5cbfSDavid du Colombier 33280ee5cbfSDavid du Colombier assert(offset%Blocksize == Cwoffset(cd)%Blocksize); 33380ee5cbfSDavid du Colombier 33480ee5cbfSDavid du Colombier o = Cwoffset(cd); 33580ee5cbfSDavid du Colombier lp = 0; 33680ee5cbfSDavid du Colombier if(Blocksize - Cwoffset(cd)%Blocksize < l) { 33780ee5cbfSDavid du Colombier lp = Blocksize - Cwoffset(cd)%Blocksize; 33880ee5cbfSDavid du Colombier Cpadblock(cd); 33980ee5cbfSDavid du Colombier } 34080ee5cbfSDavid du Colombier 34180ee5cbfSDavid du Colombier Cputc(cd, l); /* length of directory record */ 34280ee5cbfSDavid du Colombier Cputc(cd, 0); /* extended attribute record length */ 34380ee5cbfSDavid du Colombier if(d) { 3449a747e4fSDavid du Colombier if((d->mode & DMDIR) == 0) 34580ee5cbfSDavid du Colombier assert(d->length == 0 || d->block >= 18); 34680ee5cbfSDavid du Colombier 34780ee5cbfSDavid du Colombier Cputn(cd, d->block, 4); /* location of extent */ 34880ee5cbfSDavid du Colombier Cputn(cd, d->length, 4); /* data length */ 34980ee5cbfSDavid du Colombier } else { 35080ee5cbfSDavid du Colombier Cputn(cd, 0, 4); 35180ee5cbfSDavid du Colombier Cputn(cd, 0, 4); 35280ee5cbfSDavid du Colombier } 35380ee5cbfSDavid du Colombier Cputdate(cd, d ? d->mtime : now); /* recorded date */ 35480ee5cbfSDavid du Colombier Cputc(cd, f); /* file flags */ 35580ee5cbfSDavid du Colombier Cputc(cd, 0); /* file unit size */ 35680ee5cbfSDavid du Colombier Cputc(cd, 0); /* interleave gap size */ 35780ee5cbfSDavid du Colombier Cputn(cd, 1, 2); /* volume sequence number */ 35880ee5cbfSDavid du Colombier Cputc(cd, n); /* length of file identifier */ 35980ee5cbfSDavid du Colombier 36080ee5cbfSDavid du Colombier if(dot == DTiden) { /* identifier */ 36180ee5cbfSDavid du Colombier if(joliet) 36280ee5cbfSDavid du Colombier Cputrscvt(cd, d->confname, n); 36380ee5cbfSDavid du Colombier else 36480ee5cbfSDavid du Colombier Cputs(cd, d->confname, n); 36580ee5cbfSDavid du Colombier }else 36680ee5cbfSDavid du Colombier if(dot == DTdotdot) 36780ee5cbfSDavid du Colombier Cputc(cd, 1); 36880ee5cbfSDavid du Colombier else 36980ee5cbfSDavid du Colombier Cputc(cd, 0); 37080ee5cbfSDavid du Colombier 37180ee5cbfSDavid du Colombier if(Cwoffset(cd) & 1) /* pad */ 37280ee5cbfSDavid du Colombier Cputc(cd, 0); 37380ee5cbfSDavid du Colombier 37480ee5cbfSDavid du Colombier if(joliet == 0) { 37580ee5cbfSDavid du Colombier if(cd->flags & CDplan9) 37680ee5cbfSDavid du Colombier Cputplan9(cd, d, dot, 1); 37780ee5cbfSDavid du Colombier else if(cd->flags & CDrockridge) 37880ee5cbfSDavid du Colombier Cputsysuse(cd, d, dot, 1, Cwoffset(cd)-(o+lp)); 37980ee5cbfSDavid du Colombier } 38080ee5cbfSDavid du Colombier 38180ee5cbfSDavid du Colombier assert(o+lp+l == Cwoffset(cd)); 38280ee5cbfSDavid du Colombier return lp+l; 38380ee5cbfSDavid du Colombier } 38480ee5cbfSDavid du Colombier 38580ee5cbfSDavid du Colombier int 38680ee5cbfSDavid du Colombier Cputisodir(Cdimg *cd, Direc *d, int dot, int dowrite, int offset) 38780ee5cbfSDavid du Colombier { 38880ee5cbfSDavid du Colombier return genputdir(cd, d, dot, 0, dowrite, offset); 38980ee5cbfSDavid du Colombier } 39080ee5cbfSDavid du Colombier 39180ee5cbfSDavid du Colombier int 39280ee5cbfSDavid du Colombier Cputjolietdir(Cdimg *cd, Direc *d, int dot, int dowrite, int offset) 39380ee5cbfSDavid du Colombier { 39480ee5cbfSDavid du Colombier return genputdir(cd, d, dot, 1, dowrite, offset); 39580ee5cbfSDavid du Colombier } 39680ee5cbfSDavid du Colombier 39780ee5cbfSDavid du Colombier void 39880ee5cbfSDavid du Colombier Cputendvd(Cdimg *cd) 39980ee5cbfSDavid du Colombier { 40080ee5cbfSDavid du Colombier Cputc(cd, 255); /* volume descriptor set terminator */ 40180ee5cbfSDavid du Colombier Cputs(cd, "CD001", 5); /* standard identifier */ 40280ee5cbfSDavid du Colombier Cputc(cd, 1); /* volume descriptor version */ 40380ee5cbfSDavid du Colombier Cpadblock(cd); 40480ee5cbfSDavid du Colombier } 405