xref: /plan9/sys/src/cmd/disk/9660/iso9660.h (revision f7db61556a577f91350f05658e9c0724969b02c3)
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