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 *loaderdirec; 118 Direc *bootdirec; 119 char *bootimage; 120 char *loader; 121 122 Biobuf brd; 123 Biobuf bwr; 124 125 int flags; 126 127 Voldesc iso; 128 Voldesc joliet; 129 }; 130 enum { /* Cdimg->flags, Cdinfo->flags */ 131 CDjoliet = 1<<0, 132 CDplan9 = 1<<1, 133 CDconform = 1<<2, 134 CDrockridge = 1<<3, 135 CDnew = 1<<4, 136 CDdump = 1<<5, 137 CDbootable = 1<<6, 138 CDbootnoemu = 1<<7, 139 CDpbs= 1<<8, 140 }; 141 142 typedef struct Tx Tx; 143 struct Tx { 144 char *bad; /* atoms */ 145 char *good; 146 }; 147 148 struct Conform { 149 Tx *t; 150 int nt; /* delta = 32 */ 151 }; 152 153 struct Cdinfo { 154 int flags; 155 156 char *volumename; 157 158 char *volumeset; 159 char *publisher; 160 char *preparer; 161 char *application; 162 char *bootimage; 163 char *loader; 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 Cfillpbs(Cdimg*); 298 void findbootimage(Cdimg*, Direc*); 299 void findloader(Cdimg*, Direc*); 300 301 /* cdrdwr.c */ 302 Cdimg *createcd(char*, Cdinfo); 303 Cdimg *opencd(char*, Cdinfo); 304 void Creadblock(Cdimg*, void*, ulong, ulong); 305 ulong big(void*, int); 306 ulong little(void*, int); 307 int parsedir(Cdimg*, Direc*, uchar*, int, char *(*)(uchar*, int)); 308 void setroot(Cdimg*, ulong, ulong, ulong); 309 void setvolsize(Cdimg*, uvlong, ulong); 310 void setpathtable(Cdimg*, ulong, ulong, ulong, ulong); 311 void Cputc(Cdimg*, int); 312 void Cputnl(Cdimg*, uvlong, int); 313 void Cputnm(Cdimg*, uvlong, int); 314 void Cputn(Cdimg*, uvlong, int); 315 void Crepeat(Cdimg*, int, int); 316 void Cputs(Cdimg*, char*, int); 317 void Cwrite(Cdimg*, void*, int); 318 void Cputr(Cdimg*, Rune); 319 void Crepeatr(Cdimg*, Rune, int); 320 void Cputrs(Cdimg*, Rune*, int); 321 void Cputrscvt(Cdimg*, char*, int); 322 void Cpadblock(Cdimg*); 323 void Cputdate(Cdimg*, ulong); 324 void Cputdate1(Cdimg*, ulong); 325 void Cread(Cdimg*, void*, int); 326 void Cwflush(Cdimg*); 327 void Cwseek(Cdimg*, vlong); 328 uvlong Cwoffset(Cdimg*); 329 uvlong Croffset(Cdimg*); 330 int Cgetc(Cdimg*); 331 void Crseek(Cdimg*, vlong); 332 char *Crdline(Cdimg*, int); 333 int Clinelen(Cdimg*); 334 335 /* conform.c */ 336 void rdconform(Cdimg*); 337 char *conform(char*, int); 338 void wrconform(Cdimg*, int, ulong*, uvlong*); 339 340 /* direc.c */ 341 void mkdirec(Direc*, XDir*); 342 Direc *walkdirec(Direc*, char*); 343 Direc *adddirec(Direc*, char*, XDir*); 344 void copydirec(Direc*, Direc*); 345 void checknames(Direc*, int (*)(char*)); 346 void convertnames(Direc*, char* (*)(char*, char*)); 347 void dsort(Direc*, int (*)(const void*, const void*)); 348 void setparents(Direc*); 349 350 /* dump.c */ 351 ulong Cputdumpblock(Cdimg*); 352 int hasdump(Cdimg*); 353 Dump *dumpcd(Cdimg*, Direc*); 354 Dumpdir *lookupmd5(Dump*, uchar*); 355 void insertmd5(Dump*, char*, uchar*, ulong, ulong); 356 357 Direc readdumpdirs(Cdimg*, XDir*, char*(*)(uchar*,int)); 358 char *adddumpdir(Direc*, ulong, XDir*); 359 void copybutname(Direc*, Direc*); 360 361 void readkids(Cdimg*, Direc*, char*(*)(uchar*,int)); 362 void freekids(Direc*); 363 void readdumpconform(Cdimg*); 364 void rmdumpdir(Direc*, char*); 365 366 /* ichar.c */ 367 char *isostring(uchar*, int); 368 int isbadiso9660(char*); 369 int isocmp(const void*, const void*); 370 int isisofrog(char); 371 void Cputisopvd(Cdimg*, Cdinfo); 372 373 /* jchar.c */ 374 char *jolietstring(uchar*, int); 375 int isbadjoliet(char*); 376 int jolietcmp(const void*, const void*); 377 int isjolietfrog(Rune); 378 void Cputjolietsvd(Cdimg*, Cdinfo); 379 380 /* path.c */ 381 void writepathtables(Cdimg*); 382 383 /* util.c */ 384 void *emalloc(ulong); 385 void *erealloc(void*, ulong); 386 char *atom(char*); 387 char *struprcpy(char*, char*); 388 int chat(char*, ...); 389 390 /* unix.c, plan9.c */ 391 void dirtoxdir(XDir*, Dir*); 392 void fdtruncate(int, ulong); 393 long uidno(char*); 394 long gidno(char*); 395 396 /* rune.c */ 397 Rune *strtorune(Rune*, char*); 398 Rune *runechr(Rune*, Rune); 399 int runecmp(Rune*, Rune*); 400 401 /* sysuse.c */ 402 int Cputsysuse(Cdimg*, Direc*, int, int, int); 403 404 /* write.c */ 405 void writefiles(Dump*, Cdimg*, Direc*); 406 void writedirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int)); 407 void writedumpdirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int)); 408 int Cputisodir(Cdimg*, Direc*, int, int, int); 409 int Cputjolietdir(Cdimg*, Direc*, int, int, int); 410 void Cputendvd(Cdimg*); 411 412 enum { 413 Blocksize = 2048, 414 Ndirblock = 16, /* directory blocks allocated at once */ 415 416 DTdot = 0, 417 DTdotdot, 418 DTiden, 419 DTroot, 420 DTrootdot, 421 }; 422 423 extern ulong now; 424 extern Conform *map; 425 extern int chatty; 426 extern int docolon; 427 extern int mk9660; 428 extern int blocksize; 429