1 /* 2 * iso9660.h 3 * 4 * Routines and data structures to support reading and writing ISO 9660 CD images. 5 * See the ISO 9660 or ECMA 119 standards. 6 * 7 * Also supports Rock Ridge extensions for long file names and Unix stuff. 8 * Also supports Microsoft's Joliet extensions for Unicode and long file names. 9 * Also supports El Torito bootable CD spec. 10 */ 11 12 typedef struct Cdimg Cdimg; 13 typedef struct Cdinfo Cdinfo; 14 typedef struct Conform Conform; 15 typedef struct Direc Direc; 16 typedef struct Dumproot Dumproot; 17 typedef struct Voldesc Voldesc; 18 typedef struct XDir XDir; 19 20 #ifndef CHLINK 21 #define CHLINK 0 22 #endif 23 24 struct XDir { 25 char *name; 26 char *uid; 27 char *gid; 28 char *symlink; 29 ulong uidno; /* Numeric uid */ 30 ulong gidno; /* Numeric gid */ 31 32 ulong mode; 33 ulong atime; 34 ulong mtime; 35 ulong ctime; 36 37 vlong length; 38 }; 39 40 /* 41 * A directory entry in a ISO9660 tree. 42 * The extra data (uid, etc.) here is put into the system use areas. 43 */ 44 struct Direc { 45 char *name; /* real name */ 46 char *confname; /* conformant name */ 47 char *srcfile; /* file to copy onto the image */ 48 49 ulong block; 50 ulong length; 51 int flags; 52 53 char *uid; 54 char *gid; 55 char *symlink; 56 ulong mode; 57 long atime; 58 long ctime; 59 long mtime; 60 61 ulong uidno; 62 ulong gidno; 63 64 Direc *child; 65 int nchild; 66 }; 67 enum { /* Direc flags */ 68 Dbadname = 1<<0, /* Non-conformant name */ 69 }; 70 71 /* 72 * Data found in a volume descriptor. 73 */ 74 struct Voldesc { 75 char *systemid; 76 char *volumeset; 77 char *publisher; 78 char *preparer; 79 char *application; 80 81 /* file names for various parameters */ 82 char *abstract; 83 char *biblio; 84 char *notice; 85 86 /* path table */ 87 ulong pathsize; 88 ulong lpathloc; 89 ulong mpathloc; 90 91 /* root of file tree */ 92 Direc root; 93 }; 94 95 /* 96 * An ISO9660 CD image. Various parameters are kept in memory but the 97 * real image file is opened for reading and writing on fd. 98 * 99 * The bio buffers brd and bwr moderate reading and writing to the image. 100 * The routines we use are careful to flush one before or after using the other, 101 * as necessary. 102 */ 103 struct Cdimg { 104 char *file; 105 int fd; 106 ulong dumpblock; 107 ulong nextblock; 108 ulong iso9660pvd; 109 ulong jolietsvd; 110 ulong pathblock; 111 uvlong rrcontin; /* rock ridge continuation offset */ 112 ulong nulldump; /* next dump block */ 113 ulong nconform; /* number of conform entries written already */ 114 uvlong bootcatptr; 115 ulong bootcatblock; 116 uvlong bootimageptr; 117 Direc *bootdirec; 118 char *bootimage; 119 120 Biobuf brd; 121 Biobuf bwr; 122 123 int flags; 124 125 Voldesc iso; 126 Voldesc joliet; 127 }; 128 enum { /* Cdimg->flags, Cdinfo->flags */ 129 CDjoliet = 1<<0, 130 CDplan9 = 1<<1, 131 CDconform = 1<<2, 132 CDrockridge = 1<<3, 133 CDnew = 1<<4, 134 CDdump = 1<<5, 135 CDbootable = 1<<6, 136 CDbootnoemu = 1<<7, 137 }; 138 139 typedef struct Tx Tx; 140 struct Tx { 141 char *bad; /* atoms */ 142 char *good; 143 }; 144 145 struct Conform { 146 Tx *t; 147 int nt; /* delta = 32 */ 148 }; 149 150 struct Cdinfo { 151 int flags; 152 153 char *volumename; 154 155 char *volumeset; 156 char *publisher; 157 char *preparer; 158 char *application; 159 char *bootimage; 160 }; 161 162 //enum { 163 // Blocklen = 2048, /* unused */ 164 //}; 165 166 /* 167 * This is a doubly binary tree. 168 * We have a tree keyed on the MD5 values 169 * as well as a tree keyed on the block numbers. 170 */ 171 typedef struct Dump Dump; 172 typedef struct Dumpdir Dumpdir; 173 174 struct Dump { 175 Cdimg *cd; 176 Dumpdir *md5root; 177 Dumpdir *blockroot; 178 }; 179 180 struct Dumpdir { 181 char *name; 182 uchar md5[MD5dlen]; 183 ulong block; 184 ulong length; 185 Dumpdir *md5left; 186 Dumpdir *md5right; 187 Dumpdir *blockleft; 188 Dumpdir *blockright; 189 }; 190 191 struct Dumproot { 192 char *name; 193 int nkid; 194 Dumproot *kid; 195 Direc root; 196 Direc jroot; 197 }; 198 199 /* 200 * ISO9660 on-CD structures. 201 */ 202 typedef struct Cdir Cdir; 203 typedef struct Cpath Cpath; 204 typedef struct Cvoldesc Cvoldesc; 205 206 /* a volume descriptor block */ 207 struct Cvoldesc { 208 uchar magic[8]; /* 0x01, "CD001", 0x01, 0x00 */ 209 uchar systemid[32]; /* system identifier */ 210 uchar volumeid[32]; /* volume identifier */ 211 uchar unused[8]; /* character set in secondary desc */ 212 uchar volsize[8]; /* volume size */ 213 uchar charset[32]; 214 uchar volsetsize[4]; /* volume set size = 1 */ 215 uchar volseqnum[4]; /* volume sequence number = 1 */ 216 uchar blocksize[4]; /* logical block size */ 217 uchar pathsize[8]; /* path table size */ 218 uchar lpathloc[4]; /* Lpath */ 219 uchar olpathloc[4]; /* optional Lpath */ 220 uchar mpathloc[4]; /* Mpath */ 221 uchar ompathloc[4]; /* optional Mpath */ 222 uchar rootdir[34]; /* directory entry for root */ 223 uchar volumeset[128]; /* volume set identifier */ 224 uchar publisher[128]; 225 uchar preparer[128]; /* data preparer identifier */ 226 uchar application[128]; /* application identifier */ 227 uchar notice[37]; /* copyright notice file */ 228 uchar abstract[37]; /* abstract file */ 229 uchar biblio[37]; /* bibliographic file */ 230 uchar cdate[17]; /* creation date */ 231 uchar mdate[17]; /* modification date */ 232 uchar xdate[17]; /* expiration date */ 233 uchar edate[17]; /* effective date */ 234 uchar fsvers; /* file system version = 1 */ 235 }; 236 237 /* a directory entry */ 238 struct Cdir { 239 uchar len; 240 uchar xlen; 241 uchar dloc[8]; 242 uchar dlen[8]; 243 uchar date[7]; 244 uchar flags; 245 uchar unitsize; 246 uchar gapsize; 247 uchar volseqnum[4]; 248 uchar namelen; 249 uchar name[1]; /* chumminess */ 250 }; 251 252 /* a path table entry */ 253 struct Cpath { 254 uchar namelen; 255 uchar xlen; 256 uchar dloc[4]; 257 uchar parent[2]; 258 uchar name[1]; /* chumminess */ 259 }; 260 261 enum { /* Rockridge flags */ 262 RR_PX = 1<<0, 263 RR_PN = 1<<1, 264 RR_SL = 1<<2, 265 RR_NM = 1<<3, 266 RR_CL = 1<<4, 267 RR_PL = 1<<5, 268 RR_RE = 1<<6, 269 RR_TF = 1<<7, 270 }; 271 272 enum { /* CputrripTF type argument */ 273 TFcreation = 1<<0, 274 TFmodify = 1<<1, 275 TFaccess = 1<<2, 276 TFattributes = 1<<3, 277 TFbackup = 1<<4, 278 TFexpiration = 1<<5, 279 TFeffective = 1<<6, 280 TFlongform = 1<<7, 281 }; 282 283 enum { /* CputrripNM flag types */ 284 NMcontinue = 1<<0, 285 NMcurrent = 1<<1, 286 NMparent = 1<<2, 287 NMroot = 1<<3, 288 NMvolroot = 1<<4, 289 NMhost = 1<<5, 290 }; 291 292 /* boot.c */ 293 void Cputbootvol(Cdimg*); 294 void Cputbootcat(Cdimg*); 295 void Cupdatebootvol(Cdimg*); 296 void Cupdatebootcat(Cdimg*); 297 void findbootimage(Cdimg*, Direc*); 298 299 /* cdrdwr.c */ 300 Cdimg *createcd(char*, Cdinfo); 301 Cdimg *opencd(char*, Cdinfo); 302 void Creadblock(Cdimg*, void*, ulong, ulong); 303 ulong big(void*, int); 304 ulong little(void*, int); 305 int parsedir(Cdimg*, Direc*, uchar*, int, char *(*)(uchar*, int)); 306 void setroot(Cdimg*, ulong, ulong, ulong); 307 void setvolsize(Cdimg*, ulong, ulong); 308 void setpathtable(Cdimg*, ulong, ulong, ulong, ulong); 309 void Cputc(Cdimg*, int); 310 void Cputnl(Cdimg*, ulong, int); 311 void Cputnm(Cdimg*, ulong, int); 312 void Cputn(Cdimg*, long, int); 313 void Crepeat(Cdimg*, int, int); 314 void Cputs(Cdimg*, char*, int); 315 void Cwrite(Cdimg*, void*, int); 316 void Cputr(Cdimg*, Rune); 317 void Crepeatr(Cdimg*, Rune, int); 318 void Cputrs(Cdimg*, Rune*, int); 319 void Cputrscvt(Cdimg*, char*, int); 320 void Cpadblock(Cdimg*); 321 void Cputdate(Cdimg*, ulong); 322 void Cputdate1(Cdimg*, ulong); 323 void Cread(Cdimg*, void*, int); 324 void Cwflush(Cdimg*); 325 void Cwseek(Cdimg*, vlong); 326 uvlong Cwoffset(Cdimg*); 327 uvlong Croffset(Cdimg*); 328 int Cgetc(Cdimg*); 329 void Crseek(Cdimg*, vlong); 330 char *Crdline(Cdimg*, int); 331 int Clinelen(Cdimg*); 332 333 /* conform.c */ 334 void rdconform(Cdimg*); 335 char *conform(char*, int); 336 void wrconform(Cdimg*, int, ulong*, uvlong*); 337 338 /* direc.c */ 339 void mkdirec(Direc*, XDir*); 340 Direc *walkdirec(Direc*, char*); 341 Direc *adddirec(Direc*, char*, XDir*); 342 void copydirec(Direc*, Direc*); 343 void checknames(Direc*, int (*)(char*)); 344 void convertnames(Direc*, char* (*)(char*, char*)); 345 void dsort(Direc*, int (*)(const void*, const void*)); 346 void setparents(Direc*); 347 348 /* dump.c */ 349 ulong Cputdumpblock(Cdimg*); 350 int hasdump(Cdimg*); 351 Dump *dumpcd(Cdimg*, Direc*); 352 Dumpdir *lookupmd5(Dump*, uchar*); 353 void insertmd5(Dump*, char*, uchar*, ulong, ulong); 354 355 Direc readdumpdirs(Cdimg*, XDir*, char*(*)(uchar*,int)); 356 char *adddumpdir(Direc*, ulong, XDir*); 357 void copybutname(Direc*, Direc*); 358 359 void readkids(Cdimg*, Direc*, char*(*)(uchar*,int)); 360 void freekids(Direc*); 361 void readdumpconform(Cdimg*); 362 void rmdumpdir(Direc*, char*); 363 364 /* ichar.c */ 365 char *isostring(uchar*, int); 366 int isbadiso9660(char*); 367 int isocmp(const void*, const void*); 368 int isisofrog(char); 369 void Cputisopvd(Cdimg*, Cdinfo); 370 371 /* jchar.c */ 372 char *jolietstring(uchar*, int); 373 int isbadjoliet(char*); 374 int jolietcmp(const void*, const void*); 375 int isjolietfrog(Rune); 376 void Cputjolietsvd(Cdimg*, Cdinfo); 377 378 /* path.c */ 379 void writepathtables(Cdimg*); 380 381 /* util.c */ 382 void *emalloc(ulong); 383 void *erealloc(void*, ulong); 384 char *atom(char*); 385 char *struprcpy(char*, char*); 386 int chat(char*, ...); 387 388 /* unix.c, plan9.c */ 389 void dirtoxdir(XDir*, Dir*); 390 void fdtruncate(int, ulong); 391 long uidno(char*); 392 long gidno(char*); 393 394 /* rune.c */ 395 Rune *strtorune(Rune*, char*); 396 Rune *runechr(Rune*, Rune); 397 int runecmp(Rune*, Rune*); 398 399 /* sysuse.c */ 400 int Cputsysuse(Cdimg*, Direc*, int, int, int); 401 402 /* write.c */ 403 void writefiles(Dump*, Cdimg*, Direc*); 404 void writedirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int)); 405 void writedumpdirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int)); 406 int Cputisodir(Cdimg*, Direc*, int, int, int); 407 int Cputjolietdir(Cdimg*, Direc*, int, int, int); 408 void Cputendvd(Cdimg*); 409 410 enum { 411 Blocksize = 2048, 412 Ndirblock = 16, /* directory blocks allocated at once */ 413 414 DTdot = 0, 415 DTdotdot, 416 DTiden, 417 DTroot, 418 DTrootdot, 419 }; 420 421 extern ulong now; 422 extern Conform *map; 423 extern int chatty; 424 extern int docolon; 425 extern int mk9660; 426 extern int blocksize; 427