Blob


1 /*
2 * iso9660.h
3 *
4 * Routines and data structures to support reading and writing
5 * ISO 9660 CD images. 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 */
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;
20 #ifndef CHLINK
21 #define CHLINK 0
22 #endif
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 */
32 ulong mode;
33 ulong atime;
34 ulong mtime;
35 ulong ctime;
37 vlong length;
38 };
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 */
49 ulong block;
50 ulong length;
51 int flags;
53 char *uid;
54 char *gid;
55 char *symlink;
56 ulong mode;
57 long atime;
58 long ctime;
59 long mtime;
61 ulong uidno;
62 ulong gidno;
64 Direc *child;
65 int nchild;
66 };
67 enum { /* Direc flags */
68 Dbadname = 1<<0, /* Non-conformant name */
69 };
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;
81 /* file names for various parameters */
82 char *abstract;
83 char *biblio;
84 char *notice;
86 /* path table */
87 ulong pathsize;
88 ulong lpathloc;
89 ulong mpathloc;
91 /* root of file tree */
92 Direc root;
93 };
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 ulong rrcontin; /* rock ridge continuation offset */
112 ulong nulldump; /* next dump block */
113 ulong nconform; /* number of conform entries written already */
114 ulong bootcatptr;
115 ulong bootcatblock;
116 ulong bootimageptr;
117 Direc *bootdirec;
118 char *bootimage;
120 Biobuf brd;
121 Biobuf bwr;
123 int flags;
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 };
138 typedef struct Tx Tx;
139 struct Tx {
140 char *bad; /* atoms */
141 char *good;
142 };
144 struct Conform {
145 Tx *t;
146 int nt; /* delta = 32 */
147 };
149 struct Cdinfo {
150 int flags;
152 char *volumename;
154 char *volumeset;
155 char *publisher;
156 char *preparer;
157 char *application;
158 char *bootimage;
159 };
161 enum {
162 Blocklen = 2048,
163 };
165 /*
166 * This is a doubly binary tree.
167 * We have a tree keyed on the MD5 values
168 * as well as a tree keyed on the block numbers.
169 */
170 typedef struct Dump Dump;
171 typedef struct Dumpdir Dumpdir;
173 struct Dump {
174 Cdimg *cd;
175 Dumpdir *md5root;
176 Dumpdir *blockroot;
177 };
179 struct Dumpdir {
180 char *name;
181 uchar md5[MD5dlen];
182 ulong block;
183 ulong length;
184 Dumpdir *md5left;
185 Dumpdir *md5right;
186 Dumpdir *blockleft;
187 Dumpdir *blockright;
188 };
190 struct Dumproot {
191 char *name;
192 int nkid;
193 Dumproot *kid;
194 Direc root;
195 Direc jroot;
196 };
198 /*
199 * ISO9660 on-CD structures.
200 */
201 typedef struct Cdir Cdir;
202 typedef struct Cpath Cpath;
203 typedef struct Cvoldesc Cvoldesc;
205 /* a volume descriptor block */
206 struct Cvoldesc {
207 uchar magic[8]; /* 0x01, "CD001", 0x01, 0x00 */
208 uchar systemid[32]; /* system identifier */
209 uchar volumeid[32]; /* volume identifier */
210 uchar unused[8]; /* character set in secondary desc */
211 uchar volsize[8]; /* volume size */
212 uchar charset[32];
213 uchar volsetsize[4]; /* volume set size = 1 */
214 uchar volseqnum[4]; /* volume sequence number = 1 */
215 uchar blocksize[4]; /* logical block size */
216 uchar pathsize[8]; /* path table size */
217 uchar lpathloc[4]; /* Lpath */
218 uchar olpathloc[4]; /* optional Lpath */
219 uchar mpathloc[4]; /* Mpath */
220 uchar ompathloc[4]; /* optional Mpath */
221 uchar rootdir[34]; /* directory entry for root */
222 uchar volumeset[128]; /* volume set identifier */
223 uchar publisher[128];
224 uchar preparer[128]; /* data preparer identifier */
225 uchar application[128]; /* application identifier */
226 uchar notice[37]; /* copyright notice file */
227 uchar abstract[37]; /* abstract file */
228 uchar biblio[37]; /* bibliographic file */
229 uchar cdate[17]; /* creation date */
230 uchar mdate[17]; /* modification date */
231 uchar xdate[17]; /* expiration date */
232 uchar edate[17]; /* effective date */
233 uchar fsvers; /* file system version = 1 */
234 };
236 /* a directory entry */
237 struct Cdir {
238 uchar len;
239 uchar xlen;
240 uchar dloc[8];
241 uchar dlen[8];
242 uchar date[7];
243 uchar flags;
244 uchar unitsize;
245 uchar gapsize;
246 uchar volseqnum[4];
247 uchar namelen;
248 uchar name[1]; /* chumminess */
249 };
251 /* a path table entry */
252 struct Cpath {
253 uchar namelen;
254 uchar xlen;
255 uchar dloc[4];
256 uchar parent[2];
257 uchar name[1]; /* chumminess */
258 };
260 enum { /* Rockridge flags */
261 RR_PX = 1<<0,
262 RR_PN = 1<<1,
263 RR_SL = 1<<2,
264 RR_NM = 1<<3,
265 RR_CL = 1<<4,
266 RR_PL = 1<<5,
267 RR_RE = 1<<6,
268 RR_TF = 1<<7,
269 };
271 enum { /* CputrripTF type argument */
272 TFcreation = 1<<0,
273 TFmodify = 1<<1,
274 TFaccess = 1<<2,
275 TFattributes = 1<<3,
276 TFbackup = 1<<4,
277 TFexpiration = 1<<5,
278 TFeffective = 1<<6,
279 TFlongform = 1<<7,
280 };
282 enum { /* CputrripNM flag types */
283 NMcontinue = 1<<0,
284 NMcurrent = 1<<1,
285 NMparent = 1<<2,
286 NMroot = 1<<3,
287 NMvolroot = 1<<4,
288 NMhost = 1<<5,
289 };
291 /* boot.c */
292 void Cputbootvol(Cdimg*);
293 void Cputbootcat(Cdimg*);
294 void Cupdatebootvol(Cdimg*);
295 void Cupdatebootcat(Cdimg*);
296 void findbootimage(Cdimg*, Direc*);
298 /* cdrdwr.c */
299 Cdimg *createcd(char*, Cdinfo);
300 Cdimg *opencd(char*, Cdinfo);
301 void Creadblock(Cdimg*, void*, ulong, ulong);
302 ulong big(void*, int);
303 ulong little(void*, int);
304 int parsedir(Cdimg*, Direc*, uchar*, int, char *(*)(uchar*, int));
305 void setroot(Cdimg*, ulong, ulong, ulong);
306 void setvolsize(Cdimg*, ulong, ulong);
307 void setpathtable(Cdimg*, ulong, ulong, ulong, ulong);
308 void Cputc(Cdimg*, int);
309 void Cputnl(Cdimg*, ulong, int);
310 void Cputnm(Cdimg*, ulong, int);
311 void Cputn(Cdimg*, long, int);
312 void Crepeat(Cdimg*, int, int);
313 void Cputs(Cdimg*, char*, int);
314 void Cwrite(Cdimg*, void*, int);
315 void Cputr(Cdimg*, Rune);
316 void Crepeatr(Cdimg*, Rune, int);
317 void Cputrs(Cdimg*, Rune*, int);
318 void Cputrscvt(Cdimg*, char*, int);
319 void Cpadblock(Cdimg*);
320 void Cputdate(Cdimg*, ulong);
321 void Cputdate1(Cdimg*, ulong);
322 void Cread(Cdimg*, void*, int);
323 void Cwflush(Cdimg*);
324 void Cwseek(Cdimg*, ulong);
325 ulong Cwoffset(Cdimg*);
326 ulong Croffset(Cdimg*);
327 int Cgetc(Cdimg*);
328 void Crseek(Cdimg*, ulong);
329 char *Crdline(Cdimg*, int);
330 int Clinelen(Cdimg*);
332 /* conform.c */
333 void rdconform(Cdimg*);
334 char *conform(char*, int);
335 void wrconform(Cdimg*, int, ulong*, ulong*);
337 /* direc.c */
338 void mkdirec(Direc*, XDir*);
339 Direc *walkdirec(Direc*, char*);
340 Direc *adddirec(Direc*, char*, XDir*);
341 void copydirec(Direc*, Direc*);
342 void checknames(Direc*, int (*)(char*));
343 void convertnames(Direc*, char* (*)(char*, char*));
344 void dsort(Direc*, int (*)(const void*, const void*));
345 void setparents(Direc*);
347 /* dump.c */
348 ulong Cputdumpblock(Cdimg*);
349 int hasdump(Cdimg*);
350 Dump *dumpcd(Cdimg*, Direc*);
351 Dumpdir *lookupmd5(Dump*, uchar*);
352 void insertmd5(Dump*, char*, uchar*, ulong, ulong);
354 Direc readdumpdirs(Cdimg*, XDir*, char*(*)(uchar*,int));
355 char *adddumpdir(Direc*, ulong, XDir*);
356 void copybutname(Direc*, Direc*);
358 void readkids(Cdimg*, Direc*, char*(*)(uchar*,int));
359 void freekids(Direc*);
360 void readdumpconform(Cdimg*);
361 void rmdumpdir(Direc*, char*);
363 /* ichar.c */
364 char *isostring(uchar*, int);
365 int isbadiso9660(char*);
366 int isocmp(const void*, const void*);
367 int isisofrog(char);
368 void Cputisopvd(Cdimg*, Cdinfo);
370 /* jchar.c */
371 char *jolietstring(uchar*, int);
372 int isbadjoliet(char*);
373 int jolietcmp(const void*, const void*);
374 int isjolietfrog(Rune);
375 void Cputjolietsvd(Cdimg*, Cdinfo);
377 /* path.c */
378 void writepathtables(Cdimg*);
380 /* util.c */
381 void *emalloc(ulong);
382 void *erealloc(void*, ulong);
383 char *atom(char*);
384 char *struprcpy(char*, char*);
385 int chat(char*, ...);
387 /* unix.c, plan9.c */
388 void dirtoxdir(XDir*, Dir*);
389 void fdtruncate(int, ulong);
390 long uidno(char*);
391 long gidno(char*);
393 /* rune.c */
394 Rune *strtorune(Rune*, char*);
395 Rune *runechr(Rune*, Rune);
396 int runecmp(Rune*, Rune*);
398 /* sysuse.c */
399 int Cputsysuse(Cdimg*, Direc*, int, int, int);
401 /* write.c */
402 void writefiles(Dump*, Cdimg*, Direc*);
403 void writedirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int));
404 void writedumpdirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int));
405 int Cputisodir(Cdimg*, Direc*, int, int, int);
406 int Cputjolietdir(Cdimg*, Direc*, int, int, int);
407 void Cputendvd(Cdimg*);
409 enum {
410 Blocksize = 2048,
411 Ndirblock = 16, /* directory blocks allocated at once */
413 DTdot = 0,
414 DTdotdot,
415 DTiden,
416 DTroot,
417 DTrootdot,
418 };
420 extern ulong now;
421 extern Conform *map;
422 extern int chatty;
423 extern int docolon;
424 extern int mk9660;