1*80ee5cbfSDavid du Colombier #include <u.h> 2*80ee5cbfSDavid du Colombier #include <libc.h> 3*80ee5cbfSDavid du Colombier #include <bio.h> 4*80ee5cbfSDavid du Colombier #include <libsec.h> 5*80ee5cbfSDavid du Colombier 6*80ee5cbfSDavid du Colombier #include "iso9660.h" 7*80ee5cbfSDavid du Colombier 8*80ee5cbfSDavid du Colombier static void 9*80ee5cbfSDavid du Colombier writelittlebig4(uchar *buf, ulong x) 10*80ee5cbfSDavid du Colombier { 11*80ee5cbfSDavid du Colombier buf[0] = buf[7] = x; 12*80ee5cbfSDavid du Colombier buf[1] = buf[6] = x>>8; 13*80ee5cbfSDavid du Colombier buf[2] = buf[5] = x>>16; 14*80ee5cbfSDavid du Colombier buf[3] = buf[4] = x>>24; 15*80ee5cbfSDavid du Colombier } 16*80ee5cbfSDavid du Colombier 17*80ee5cbfSDavid du Colombier void 18*80ee5cbfSDavid du Colombier rewritedot(Cdimg *cd, Direc *d) 19*80ee5cbfSDavid du Colombier { 20*80ee5cbfSDavid du Colombier uchar buf[Blocksize]; 21*80ee5cbfSDavid du Colombier Cdir *c; 22*80ee5cbfSDavid du Colombier 23*80ee5cbfSDavid du Colombier Creadblock(cd, buf, d->block, Blocksize); 24*80ee5cbfSDavid du Colombier c = (Cdir*)buf; 25*80ee5cbfSDavid du Colombier assert(c->len != 0); 26*80ee5cbfSDavid du Colombier assert(c->namelen == 1 && c->name[0] == '\0'); /* dot */ 27*80ee5cbfSDavid du Colombier writelittlebig4(c->dloc, d->block); 28*80ee5cbfSDavid du Colombier writelittlebig4(c->dlen, d->length); 29*80ee5cbfSDavid du Colombier 30*80ee5cbfSDavid du Colombier Cwseek(cd, d->block*Blocksize); 31*80ee5cbfSDavid du Colombier Cwrite(cd, buf, Blocksize); 32*80ee5cbfSDavid du Colombier } 33*80ee5cbfSDavid du Colombier 34*80ee5cbfSDavid du Colombier void 35*80ee5cbfSDavid du Colombier rewritedotdot(Cdimg *cd, Direc *d, Direc *dparent) 36*80ee5cbfSDavid du Colombier { 37*80ee5cbfSDavid du Colombier uchar buf[Blocksize]; 38*80ee5cbfSDavid du Colombier Cdir *c; 39*80ee5cbfSDavid du Colombier 40*80ee5cbfSDavid du Colombier Creadblock(cd, buf, d->block, Blocksize); 41*80ee5cbfSDavid du Colombier c = (Cdir*)buf; 42*80ee5cbfSDavid du Colombier assert(c->len != 0); 43*80ee5cbfSDavid du Colombier assert(c->namelen == 1 && c->name[0] == '\0'); /* dot */ 44*80ee5cbfSDavid du Colombier 45*80ee5cbfSDavid du Colombier c = (Cdir*)(buf+c->len); 46*80ee5cbfSDavid du Colombier assert(c->len != 0); 47*80ee5cbfSDavid du Colombier assert(c->namelen == 1 && c->name[0] == '\001'); /* dotdot*/ 48*80ee5cbfSDavid du Colombier 49*80ee5cbfSDavid du Colombier writelittlebig4(c->dloc, dparent->block); 50*80ee5cbfSDavid du Colombier writelittlebig4(c->dlen, dparent->length); 51*80ee5cbfSDavid du Colombier 52*80ee5cbfSDavid du Colombier Cwseek(cd, d->block*Blocksize); 53*80ee5cbfSDavid du Colombier Cwrite(cd, buf, Blocksize); 54*80ee5cbfSDavid du Colombier } 55*80ee5cbfSDavid du Colombier 56*80ee5cbfSDavid du Colombier /* 57*80ee5cbfSDavid du Colombier * Write each non-directory file. We copy the file to 58*80ee5cbfSDavid du Colombier * the cd image, and then if it turns out that we've 59*80ee5cbfSDavid du Colombier * seen this stream of bits before, we push the next block 60*80ee5cbfSDavid du Colombier * pointer back. This ensures consistency between the MD5s 61*80ee5cbfSDavid du Colombier * and the data on the CD image. MD5 summing on one pass 62*80ee5cbfSDavid du Colombier * and copying on another would not ensure this. 63*80ee5cbfSDavid du Colombier */ 64*80ee5cbfSDavid du Colombier void 65*80ee5cbfSDavid du Colombier writefiles(Dump *d, Cdimg *cd, Direc *direc) 66*80ee5cbfSDavid du Colombier { 67*80ee5cbfSDavid du Colombier int i; 68*80ee5cbfSDavid du Colombier uchar buf[8192], digest[MD5dlen]; 69*80ee5cbfSDavid du Colombier ulong length, n, start; 70*80ee5cbfSDavid du Colombier Biobuf *b; 71*80ee5cbfSDavid du Colombier DigestState *s; 72*80ee5cbfSDavid du Colombier Dumpdir *dd; 73*80ee5cbfSDavid du Colombier 74*80ee5cbfSDavid du Colombier if(direc->mode & CHDIR) { 75*80ee5cbfSDavid du Colombier for(i=0; i<direc->nchild; i++) 76*80ee5cbfSDavid du Colombier writefiles(d, cd, &direc->child[i]); 77*80ee5cbfSDavid du Colombier return; 78*80ee5cbfSDavid du Colombier } 79*80ee5cbfSDavid du Colombier 80*80ee5cbfSDavid du Colombier assert(direc->block == 0); 81*80ee5cbfSDavid du Colombier 82*80ee5cbfSDavid du Colombier if((b = Bopen(direc->srcfile, OREAD)) == nil){ 83*80ee5cbfSDavid du Colombier fprint(2, "warning: cannot open '%s': %r", direc->srcfile); 84*80ee5cbfSDavid du Colombier direc->block = 0; 85*80ee5cbfSDavid du Colombier direc->length = 0; 86*80ee5cbfSDavid du Colombier return; 87*80ee5cbfSDavid du Colombier } 88*80ee5cbfSDavid du Colombier 89*80ee5cbfSDavid du Colombier start = cd->nextblock; 90*80ee5cbfSDavid du Colombier assert(start != 0); 91*80ee5cbfSDavid du Colombier 92*80ee5cbfSDavid du Colombier Cwseek(cd, start*Blocksize); 93*80ee5cbfSDavid du Colombier 94*80ee5cbfSDavid du Colombier s = md5(nil, 0, nil, nil); 95*80ee5cbfSDavid du Colombier length = 0; 96*80ee5cbfSDavid du Colombier while((n = Bread(b, buf, sizeof buf)) > 0) { 97*80ee5cbfSDavid du Colombier md5(buf, n, nil, s); 98*80ee5cbfSDavid du Colombier Cwrite(cd, buf, n); 99*80ee5cbfSDavid du Colombier length += n; 100*80ee5cbfSDavid du Colombier } 101*80ee5cbfSDavid du Colombier md5(nil, 0, digest, s); 102*80ee5cbfSDavid du Colombier Bterm(b); 103*80ee5cbfSDavid du Colombier Cpadblock(cd); 104*80ee5cbfSDavid du Colombier 105*80ee5cbfSDavid du Colombier if(length != direc->length) { 106*80ee5cbfSDavid du Colombier fprint(2, "warning: %s changed size underfoot\n", direc->srcfile); 107*80ee5cbfSDavid du Colombier direc->length = length; 108*80ee5cbfSDavid du Colombier } 109*80ee5cbfSDavid du Colombier 110*80ee5cbfSDavid du Colombier if(length == 0) 111*80ee5cbfSDavid du Colombier direc->block = 0; 112*80ee5cbfSDavid du Colombier else if((dd = lookupmd5(d, digest))) { 113*80ee5cbfSDavid du Colombier assert(dd->length == length); 114*80ee5cbfSDavid du Colombier assert(dd->block != 0); 115*80ee5cbfSDavid du Colombier direc->block = dd->block; 116*80ee5cbfSDavid du Colombier cd->nextblock = start; 117*80ee5cbfSDavid du Colombier } else { 118*80ee5cbfSDavid du Colombier direc->block = start; 119*80ee5cbfSDavid du Colombier insertmd5(d, atom(direc->name), digest, start, length); 120*80ee5cbfSDavid du Colombier } 121*80ee5cbfSDavid du Colombier } 122*80ee5cbfSDavid du Colombier 123*80ee5cbfSDavid du Colombier /* 124*80ee5cbfSDavid du Colombier * Write a directory tree. We work from the leaves, 125*80ee5cbfSDavid du Colombier * and patch the dotdot pointers afterward. 126*80ee5cbfSDavid du Colombier */ 127*80ee5cbfSDavid du Colombier static void 128*80ee5cbfSDavid du Colombier _writedirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int), int level) 129*80ee5cbfSDavid du Colombier { 130*80ee5cbfSDavid du Colombier int i, l, ll; 131*80ee5cbfSDavid du Colombier ulong start, next; 132*80ee5cbfSDavid du Colombier 133*80ee5cbfSDavid du Colombier if((d->mode & CHDIR) == 0) 134*80ee5cbfSDavid du Colombier return; 135*80ee5cbfSDavid du Colombier 136*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 137*80ee5cbfSDavid du Colombier writedirs(cd, &d->child[i], put); 138*80ee5cbfSDavid du Colombier 139*80ee5cbfSDavid du Colombier l = 0; 140*80ee5cbfSDavid du Colombier l += put(cd, d, (level == 0) ? DTrootdot : DTdot, 0, l); 141*80ee5cbfSDavid du Colombier l += put(cd, nil, DTdotdot, 0, l); 142*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 143*80ee5cbfSDavid du Colombier l += put(cd, &d->child[i], DTiden, 0, l); 144*80ee5cbfSDavid du Colombier 145*80ee5cbfSDavid du Colombier start = cd->nextblock; 146*80ee5cbfSDavid du Colombier cd->nextblock += (l+Blocksize-1)/Blocksize; 147*80ee5cbfSDavid du Colombier next = cd->nextblock; 148*80ee5cbfSDavid du Colombier 149*80ee5cbfSDavid du Colombier Cwseek(cd, start*Blocksize); 150*80ee5cbfSDavid du Colombier ll = 0; 151*80ee5cbfSDavid du Colombier ll += put(cd, d, (level == 0) ? DTrootdot : DTdot, 1, ll); 152*80ee5cbfSDavid du Colombier ll += put(cd, nil, DTdotdot, 1, ll); 153*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 154*80ee5cbfSDavid du Colombier ll += put(cd, &d->child[i], DTiden, 1, ll); 155*80ee5cbfSDavid du Colombier assert(ll == l); 156*80ee5cbfSDavid du Colombier Cpadblock(cd); 157*80ee5cbfSDavid du Colombier assert(Cwoffset(cd) == next*Blocksize); 158*80ee5cbfSDavid du Colombier 159*80ee5cbfSDavid du Colombier d->block = start; 160*80ee5cbfSDavid du Colombier d->length = (next - start) * Blocksize; 161*80ee5cbfSDavid du Colombier rewritedot(cd, d); 162*80ee5cbfSDavid du Colombier rewritedotdot(cd, d, d); 163*80ee5cbfSDavid du Colombier 164*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 165*80ee5cbfSDavid du Colombier if(d->child[i].mode & CHDIR) 166*80ee5cbfSDavid du Colombier rewritedotdot(cd, &d->child[i], d); 167*80ee5cbfSDavid du Colombier } 168*80ee5cbfSDavid du Colombier 169*80ee5cbfSDavid du Colombier void 170*80ee5cbfSDavid du Colombier writedirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int)) 171*80ee5cbfSDavid du Colombier { 172*80ee5cbfSDavid du Colombier /* 173*80ee5cbfSDavid du Colombier * If we're writing a mk9660 image, then the root really 174*80ee5cbfSDavid du Colombier * is the root, so start at level 0. If we're writing a dump image, 175*80ee5cbfSDavid du Colombier * then the "root" is really going to be two levels down once 176*80ee5cbfSDavid du Colombier * we patch in the dump hierarchy above it, so start at level non-zero. 177*80ee5cbfSDavid du Colombier */ 178*80ee5cbfSDavid du Colombier _writedirs(cd, d, put, mk9660 ? 0 : 1); 179*80ee5cbfSDavid du Colombier } 180*80ee5cbfSDavid du Colombier 181*80ee5cbfSDavid du Colombier 182*80ee5cbfSDavid du Colombier /* 183*80ee5cbfSDavid du Colombier * Write the dump tree. This is like writedirs but once we get to 184*80ee5cbfSDavid du Colombier * the roots of the individual days we just patch the parent dotdot blocks. 185*80ee5cbfSDavid du Colombier */ 186*80ee5cbfSDavid du Colombier static void 187*80ee5cbfSDavid du Colombier _writedumpdirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int), int level) 188*80ee5cbfSDavid du Colombier { 189*80ee5cbfSDavid du Colombier int i; 190*80ee5cbfSDavid du Colombier ulong start; 191*80ee5cbfSDavid du Colombier 192*80ee5cbfSDavid du Colombier switch(level) { 193*80ee5cbfSDavid du Colombier case 0: 194*80ee5cbfSDavid du Colombier /* write root, list of years, also conform.map */ 195*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 196*80ee5cbfSDavid du Colombier if(d->child[i].mode & CHDIR) 197*80ee5cbfSDavid du Colombier _writedumpdirs(cd, &d->child[i], put, level+1); 198*80ee5cbfSDavid du Colombier chat("write dump root dir at %lud\n", cd->nextblock); 199*80ee5cbfSDavid du Colombier goto Writedir; 200*80ee5cbfSDavid du Colombier 201*80ee5cbfSDavid du Colombier case 1: /* write year, list of days */ 202*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 203*80ee5cbfSDavid du Colombier _writedumpdirs(cd, &d->child[i], put, level+1); 204*80ee5cbfSDavid du Colombier chat("write dump %s dir at %lud\n", d->name, cd->nextblock); 205*80ee5cbfSDavid du Colombier goto Writedir; 206*80ee5cbfSDavid du Colombier 207*80ee5cbfSDavid du Colombier Writedir: 208*80ee5cbfSDavid du Colombier start = cd->nextblock; 209*80ee5cbfSDavid du Colombier Cwseek(cd, start*Blocksize); 210*80ee5cbfSDavid du Colombier 211*80ee5cbfSDavid du Colombier put(cd, d, (level == 0) ? DTrootdot : DTdot, 1, Cwoffset(cd)); 212*80ee5cbfSDavid du Colombier put(cd, nil, DTdotdot, 1, Cwoffset(cd)); 213*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 214*80ee5cbfSDavid du Colombier put(cd, &d->child[i], DTiden, 1, Cwoffset(cd)); 215*80ee5cbfSDavid du Colombier Cpadblock(cd); 216*80ee5cbfSDavid du Colombier 217*80ee5cbfSDavid du Colombier d->block = start; 218*80ee5cbfSDavid du Colombier d->length = (cd->nextblock - start) * Blocksize; 219*80ee5cbfSDavid du Colombier 220*80ee5cbfSDavid du Colombier rewritedot(cd, d); 221*80ee5cbfSDavid du Colombier rewritedotdot(cd, d, d); 222*80ee5cbfSDavid du Colombier 223*80ee5cbfSDavid du Colombier for(i=0; i<d->nchild; i++) 224*80ee5cbfSDavid du Colombier if(d->child[i].mode & CHDIR) 225*80ee5cbfSDavid du Colombier rewritedotdot(cd, &d->child[i], d); 226*80ee5cbfSDavid du Colombier break; 227*80ee5cbfSDavid du Colombier 228*80ee5cbfSDavid du Colombier case 2: /* write day: already written, do nothing */ 229*80ee5cbfSDavid du Colombier break; 230*80ee5cbfSDavid du Colombier 231*80ee5cbfSDavid du Colombier default: 232*80ee5cbfSDavid du Colombier assert(0); 233*80ee5cbfSDavid du Colombier } 234*80ee5cbfSDavid du Colombier } 235*80ee5cbfSDavid du Colombier 236*80ee5cbfSDavid du Colombier void 237*80ee5cbfSDavid du Colombier writedumpdirs(Cdimg *cd, Direc *d, int (*put)(Cdimg*, Direc*, int, int, int)) 238*80ee5cbfSDavid du Colombier { 239*80ee5cbfSDavid du Colombier _writedumpdirs(cd, d, put, 0); 240*80ee5cbfSDavid du Colombier } 241*80ee5cbfSDavid du Colombier 242*80ee5cbfSDavid du Colombier static int 243*80ee5cbfSDavid du Colombier Cputplan9(Cdimg *cd, Direc *d, int dot, int dowrite) 244*80ee5cbfSDavid du Colombier { 245*80ee5cbfSDavid du Colombier int l, n; 246*80ee5cbfSDavid du Colombier 247*80ee5cbfSDavid du Colombier if(dot != DTiden) 248*80ee5cbfSDavid du Colombier return 0; 249*80ee5cbfSDavid du Colombier 250*80ee5cbfSDavid du Colombier l = 0; 251*80ee5cbfSDavid du Colombier if(d->flags & Dbadname) { 252*80ee5cbfSDavid du Colombier n = strlen(d->name); 253*80ee5cbfSDavid du Colombier l += 1+n; 254*80ee5cbfSDavid du Colombier if(dowrite) { 255*80ee5cbfSDavid du Colombier Cputc(cd, n); 256*80ee5cbfSDavid du Colombier Cputs(cd, d->name, n); 257*80ee5cbfSDavid du Colombier } 258*80ee5cbfSDavid du Colombier } else { 259*80ee5cbfSDavid du Colombier l++; 260*80ee5cbfSDavid du Colombier if(dowrite) 261*80ee5cbfSDavid du Colombier Cputc(cd, 0); 262*80ee5cbfSDavid du Colombier } 263*80ee5cbfSDavid du Colombier 264*80ee5cbfSDavid du Colombier n = strlen(d->uid); 265*80ee5cbfSDavid du Colombier l += 1+n; 266*80ee5cbfSDavid du Colombier if(dowrite) { 267*80ee5cbfSDavid du Colombier Cputc(cd, n); 268*80ee5cbfSDavid du Colombier Cputs(cd, d->uid, n); 269*80ee5cbfSDavid du Colombier } 270*80ee5cbfSDavid du Colombier 271*80ee5cbfSDavid du Colombier n = strlen(d->gid); 272*80ee5cbfSDavid du Colombier l += 1+n; 273*80ee5cbfSDavid du Colombier if(dowrite) { 274*80ee5cbfSDavid du Colombier Cputc(cd, n); 275*80ee5cbfSDavid du Colombier Cputs(cd, d->gid, n); 276*80ee5cbfSDavid du Colombier } 277*80ee5cbfSDavid du Colombier 278*80ee5cbfSDavid du Colombier if(l & 1) { 279*80ee5cbfSDavid du Colombier l++; 280*80ee5cbfSDavid du Colombier if(dowrite) 281*80ee5cbfSDavid du Colombier Cputc(cd, 0); 282*80ee5cbfSDavid du Colombier } 283*80ee5cbfSDavid du Colombier l += 8; 284*80ee5cbfSDavid du Colombier if(dowrite) 285*80ee5cbfSDavid du Colombier Cputn(cd, d->mode, 4); 286*80ee5cbfSDavid du Colombier 287*80ee5cbfSDavid du Colombier return l; 288*80ee5cbfSDavid du Colombier } 289*80ee5cbfSDavid du Colombier 290*80ee5cbfSDavid du Colombier /* 291*80ee5cbfSDavid du Colombier * Write a directory entry. 292*80ee5cbfSDavid du Colombier */ 293*80ee5cbfSDavid du Colombier static int 294*80ee5cbfSDavid du Colombier genputdir(Cdimg *cd, Direc *d, int dot, int joliet, int dowrite, int offset) 295*80ee5cbfSDavid du Colombier { 296*80ee5cbfSDavid du Colombier int f, n, l, lp; 297*80ee5cbfSDavid du Colombier long o; 298*80ee5cbfSDavid du Colombier 299*80ee5cbfSDavid du Colombier f = 0; 300*80ee5cbfSDavid du Colombier if(dot != DTiden || (d->mode & CHDIR)) 301*80ee5cbfSDavid du Colombier f |= 2; 302*80ee5cbfSDavid du Colombier 303*80ee5cbfSDavid du Colombier n = 1; 304*80ee5cbfSDavid du Colombier if(dot == DTiden) { 305*80ee5cbfSDavid du Colombier if(joliet) 306*80ee5cbfSDavid du Colombier n = 2*utflen(d->confname); 307*80ee5cbfSDavid du Colombier else 308*80ee5cbfSDavid du Colombier n = strlen(d->confname); 309*80ee5cbfSDavid du Colombier } 310*80ee5cbfSDavid du Colombier 311*80ee5cbfSDavid du Colombier l = 33+n; 312*80ee5cbfSDavid du Colombier if(l & 1) 313*80ee5cbfSDavid du Colombier l++; 314*80ee5cbfSDavid du Colombier assert(l <= 255); 315*80ee5cbfSDavid du Colombier 316*80ee5cbfSDavid du Colombier if(joliet == 0) { 317*80ee5cbfSDavid du Colombier if(cd->flags & CDplan9) 318*80ee5cbfSDavid du Colombier l += Cputplan9(cd, d, dot, 0); 319*80ee5cbfSDavid du Colombier else if(cd->flags & CDrockridge) 320*80ee5cbfSDavid du Colombier l += Cputsysuse(cd, d, dot, 0, l); 321*80ee5cbfSDavid du Colombier assert(l <= 255); 322*80ee5cbfSDavid du Colombier } 323*80ee5cbfSDavid du Colombier 324*80ee5cbfSDavid du Colombier if(dowrite == 0) { 325*80ee5cbfSDavid du Colombier if(Blocksize - offset%Blocksize < l) 326*80ee5cbfSDavid du Colombier l += Blocksize - offset%Blocksize; 327*80ee5cbfSDavid du Colombier return l; 328*80ee5cbfSDavid du Colombier } 329*80ee5cbfSDavid du Colombier 330*80ee5cbfSDavid du Colombier assert(offset%Blocksize == Cwoffset(cd)%Blocksize); 331*80ee5cbfSDavid du Colombier 332*80ee5cbfSDavid du Colombier o = Cwoffset(cd); 333*80ee5cbfSDavid du Colombier lp = 0; 334*80ee5cbfSDavid du Colombier if(Blocksize - Cwoffset(cd)%Blocksize < l) { 335*80ee5cbfSDavid du Colombier lp = Blocksize - Cwoffset(cd)%Blocksize; 336*80ee5cbfSDavid du Colombier Cpadblock(cd); 337*80ee5cbfSDavid du Colombier } 338*80ee5cbfSDavid du Colombier 339*80ee5cbfSDavid du Colombier Cputc(cd, l); /* length of directory record */ 340*80ee5cbfSDavid du Colombier Cputc(cd, 0); /* extended attribute record length */ 341*80ee5cbfSDavid du Colombier if(d) { 342*80ee5cbfSDavid du Colombier if((d->mode & CHDIR) == 0) 343*80ee5cbfSDavid du Colombier assert(d->length == 0 || d->block >= 18); 344*80ee5cbfSDavid du Colombier 345*80ee5cbfSDavid du Colombier Cputn(cd, d->block, 4); /* location of extent */ 346*80ee5cbfSDavid du Colombier Cputn(cd, d->length, 4); /* data length */ 347*80ee5cbfSDavid du Colombier } else { 348*80ee5cbfSDavid du Colombier Cputn(cd, 0, 4); 349*80ee5cbfSDavid du Colombier Cputn(cd, 0, 4); 350*80ee5cbfSDavid du Colombier } 351*80ee5cbfSDavid du Colombier Cputdate(cd, d ? d->mtime : now); /* recorded date */ 352*80ee5cbfSDavid du Colombier Cputc(cd, f); /* file flags */ 353*80ee5cbfSDavid du Colombier Cputc(cd, 0); /* file unit size */ 354*80ee5cbfSDavid du Colombier Cputc(cd, 0); /* interleave gap size */ 355*80ee5cbfSDavid du Colombier Cputn(cd, 1, 2); /* volume sequence number */ 356*80ee5cbfSDavid du Colombier Cputc(cd, n); /* length of file identifier */ 357*80ee5cbfSDavid du Colombier 358*80ee5cbfSDavid du Colombier if(dot == DTiden) { /* identifier */ 359*80ee5cbfSDavid du Colombier if(joliet) 360*80ee5cbfSDavid du Colombier Cputrscvt(cd, d->confname, n); 361*80ee5cbfSDavid du Colombier else 362*80ee5cbfSDavid du Colombier Cputs(cd, d->confname, n); 363*80ee5cbfSDavid du Colombier }else 364*80ee5cbfSDavid du Colombier if(dot == DTdotdot) 365*80ee5cbfSDavid du Colombier Cputc(cd, 1); 366*80ee5cbfSDavid du Colombier else 367*80ee5cbfSDavid du Colombier Cputc(cd, 0); 368*80ee5cbfSDavid du Colombier 369*80ee5cbfSDavid du Colombier if(Cwoffset(cd) & 1) /* pad */ 370*80ee5cbfSDavid du Colombier Cputc(cd, 0); 371*80ee5cbfSDavid du Colombier 372*80ee5cbfSDavid du Colombier if(joliet == 0) { 373*80ee5cbfSDavid du Colombier if(cd->flags & CDplan9) 374*80ee5cbfSDavid du Colombier Cputplan9(cd, d, dot, 1); 375*80ee5cbfSDavid du Colombier else if(cd->flags & CDrockridge) 376*80ee5cbfSDavid du Colombier Cputsysuse(cd, d, dot, 1, Cwoffset(cd)-(o+lp)); 377*80ee5cbfSDavid du Colombier } 378*80ee5cbfSDavid du Colombier 379*80ee5cbfSDavid du Colombier assert(o+lp+l == Cwoffset(cd)); 380*80ee5cbfSDavid du Colombier return lp+l; 381*80ee5cbfSDavid du Colombier } 382*80ee5cbfSDavid du Colombier 383*80ee5cbfSDavid du Colombier int 384*80ee5cbfSDavid du Colombier Cputisodir(Cdimg *cd, Direc *d, int dot, int dowrite, int offset) 385*80ee5cbfSDavid du Colombier { 386*80ee5cbfSDavid du Colombier return genputdir(cd, d, dot, 0, dowrite, offset); 387*80ee5cbfSDavid du Colombier } 388*80ee5cbfSDavid du Colombier 389*80ee5cbfSDavid du Colombier int 390*80ee5cbfSDavid du Colombier Cputjolietdir(Cdimg *cd, Direc *d, int dot, int dowrite, int offset) 391*80ee5cbfSDavid du Colombier { 392*80ee5cbfSDavid du Colombier return genputdir(cd, d, dot, 1, dowrite, offset); 393*80ee5cbfSDavid du Colombier } 394*80ee5cbfSDavid du Colombier 395*80ee5cbfSDavid du Colombier void 396*80ee5cbfSDavid du Colombier Cputendvd(Cdimg *cd) 397*80ee5cbfSDavid du Colombier { 398*80ee5cbfSDavid du Colombier Cputc(cd, 255); /* volume descriptor set terminator */ 399*80ee5cbfSDavid du Colombier Cputs(cd, "CD001", 5); /* standard identifier */ 400*80ee5cbfSDavid du Colombier Cputc(cd, 1); /* volume descriptor version */ 401*80ee5cbfSDavid du Colombier Cpadblock(cd); 402*80ee5cbfSDavid du Colombier } 403