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