Annotation of src/sys/fs/cd9660/cd9660_rrip.c, Revision 1.2.2.5
1.2.2.5 ! skrll 1: /* $NetBSD: cd9660_rrip.c,v 1.2.2.4 2004/11/29 07:24:50 skrll Exp $ */
1.1 jdolecek 2:
3: /*-
4: * Copyright (c) 1993, 1994
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley
8: * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
9: * Support code is derived from software contributed to Berkeley
10: * by Atsushi Murai (amurai@spec.co.jp).
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
1.2.2.1 skrll 20: * 3. Neither the name of the University nor the names of its contributors
1.1 jdolecek 21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: *
36: * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94
37: */
38:
39: #include <sys/cdefs.h>
1.2.2.5 ! skrll 40: __KERNEL_RCSID(0, "$NetBSD: cd9660_rrip.c,v 1.2.2.4 2004/11/29 07:24:50 skrll Exp $");
1.1 jdolecek 41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/namei.h>
45: #include <sys/buf.h>
46: #include <sys/file.h>
47: #include <sys/vnode.h>
48: #include <sys/mount.h>
49: #include <sys/kernel.h>
50: #include <sys/stat.h>
51:
52: #include <sys/time.h>
53:
54: #include <fs/cd9660/iso.h>
55: #include <fs/cd9660/cd9660_extern.h>
56: #include <fs/cd9660/cd9660_node.h>
57: #include <fs/cd9660/cd9660_rrip.h>
58: #include <fs/cd9660/iso_rrip.h>
59:
60: typedef struct {
61: char type[2];
62: int (*func) __P((void *, ISO_RRIP_ANALYZE *));
63: void (*func2) __P((void *, ISO_RRIP_ANALYZE *));
64: int result;
65: } RRIP_TABLE;
66:
67: static int cd9660_rrip_attr __P((void *, ISO_RRIP_ANALYZE *));
68: static void cd9660_rrip_defattr __P((void *, ISO_RRIP_ANALYZE *));
69: static int cd9660_rrip_slink __P((void *, ISO_RRIP_ANALYZE *));
70: static int cd9660_rrip_altname __P((void *, ISO_RRIP_ANALYZE *));
71: static void cd9660_rrip_defname __P((void *, ISO_RRIP_ANALYZE *));
72: static int cd9660_rrip_pclink __P((void *, ISO_RRIP_ANALYZE *));
73: static int cd9660_rrip_reldir __P((void *, ISO_RRIP_ANALYZE *));
74: static int cd9660_rrip_tstamp __P((void *, ISO_RRIP_ANALYZE *));
75: static void cd9660_rrip_deftstamp __P((void *, ISO_RRIP_ANALYZE *));
76: static int cd9660_rrip_device __P((void *, ISO_RRIP_ANALYZE *));
77: static int cd9660_rrip_idflag __P((void *, ISO_RRIP_ANALYZE *));
78: static int cd9660_rrip_cont __P((void *, ISO_RRIP_ANALYZE *));
79: static int cd9660_rrip_stop __P((void *, ISO_RRIP_ANALYZE *));
80: static int cd9660_rrip_extref __P((void *, ISO_RRIP_ANALYZE *));
81: static int cd9660_rrip_loop __P((struct iso_directory_record *,
82: ISO_RRIP_ANALYZE *, const RRIP_TABLE *));
83: /*
84: * POSIX file attribute
85: */
86: static int
87: cd9660_rrip_attr(v, ana)
88: void *v;
89: ISO_RRIP_ANALYZE *ana;
90: {
91: ISO_RRIP_ATTR *p = v;
92:
93: ana->inop->inode.iso_mode = isonum_733(p->mode);
94: ana->inop->inode.iso_uid = isonum_733(p->uid);
95: ana->inop->inode.iso_gid = isonum_733(p->gid);
96: ana->inop->inode.iso_links = isonum_733(p->links);
97: ana->fields &= ~ISO_SUSP_ATTR;
98: return ISO_SUSP_ATTR;
99: }
100:
101: static void
102: cd9660_rrip_defattr(v, ana)
103: void *v;
104: ISO_RRIP_ANALYZE *ana;
105: {
106: struct iso_directory_record *isodir = v;
107:
108: /* But this is a required field! */
109: printf("RRIP without PX field?\n");
110: cd9660_defattr(isodir, ana->inop, NULL);
111: }
112:
113: /*
114: * Symbolic Links
115: */
116: static int
117: cd9660_rrip_slink(v, ana)
118: void *v;
119: ISO_RRIP_ANALYZE *ana;
120: {
121: ISO_RRIP_SLINK *p = v;
122: ISO_RRIP_SLINK_COMPONENT *pcomp;
123: ISO_RRIP_SLINK_COMPONENT *pcompe;
124: int len, wlen, cont;
125: char *outbuf, *inbuf;
1.2.2.4 skrll 126:
1.1 jdolecek 127: pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
128: pcompe = (ISO_RRIP_SLINK_COMPONENT *)
129: ((char *)p + isonum_711(p->h.length));
130: len = *ana->outlen;
131: outbuf = ana->outbuf;
132: cont = ana->cont;
1.2.2.4 skrll 133:
1.1 jdolecek 134: /*
135: * Gathering a Symbolic name from each component with path
136: */
137: for (;
138: pcomp < pcompe;
139: pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ
140: + isonum_711(pcomp->clen))) {
1.2.2.4 skrll 141:
1.1 jdolecek 142: if (!cont) {
143: if (len < ana->maxlen) {
144: len++;
145: *outbuf++ = '/';
146: }
147: }
148: cont = 0;
1.2.2.4 skrll 149:
1.1 jdolecek 150: inbuf = "..";
151: wlen = 0;
1.2.2.4 skrll 152:
1.1 jdolecek 153: switch (*pcomp->cflag) {
1.2.2.4 skrll 154:
1.1 jdolecek 155: case ISO_SUSP_CFLAG_CURRENT:
156: /* Inserting Current */
157: wlen = 1;
158: break;
1.2.2.4 skrll 159:
1.1 jdolecek 160: case ISO_SUSP_CFLAG_PARENT:
161: /* Inserting Parent */
162: wlen = 2;
163: break;
1.2.2.4 skrll 164:
1.1 jdolecek 165: case ISO_SUSP_CFLAG_ROOT:
166: /* Inserting slash for ROOT */
167: /* start over from beginning(?) */
168: outbuf -= len;
169: len = 0;
170: break;
1.2.2.4 skrll 171:
1.1 jdolecek 172: case ISO_SUSP_CFLAG_VOLROOT:
173: /* Inserting a mount point i.e. "/cdrom" */
174: /* same as above */
175: outbuf -= len;
176: len = 0;
177: inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
178: wlen = strlen(inbuf);
179: break;
1.2.2.4 skrll 180:
1.1 jdolecek 181: case ISO_SUSP_CFLAG_HOST:
182: /* Inserting hostname i.e. "kurt.tools.de" */
183: inbuf = hostname;
184: wlen = hostnamelen;
185: break;
1.2.2.4 skrll 186:
1.1 jdolecek 187: case ISO_SUSP_CFLAG_CONTINUE:
188: cont = 1;
189: /* fall thru */
190: case 0:
191: /* Inserting component */
192: wlen = isonum_711(pcomp->clen);
193: inbuf = pcomp->name;
194: break;
195: default:
196: printf("RRIP with incorrect flags?");
197: wlen = ana->maxlen + 1;
198: break;
199: }
1.2.2.4 skrll 200:
1.1 jdolecek 201: if (len + wlen > ana->maxlen) {
202: /* indicate error to caller */
203: ana->cont = 1;
204: ana->fields = 0;
205: ana->outbuf -= *ana->outlen;
206: *ana->outlen = 0;
207: return 0;
208: }
1.2.2.4 skrll 209:
1.1 jdolecek 210: memcpy(outbuf, inbuf, wlen);
211: outbuf += wlen;
212: len += wlen;
213: }
214: ana->outbuf = outbuf;
215: *ana->outlen = len;
216: ana->cont = cont;
1.2.2.4 skrll 217:
1.1 jdolecek 218: if (!isonum_711(p->flags)) {
219: ana->fields &= ~ISO_SUSP_SLINK;
220: return ISO_SUSP_SLINK;
221: }
222: return 0;
223: }
224:
225: /*
226: * Alternate name
227: */
228: static int
229: cd9660_rrip_altname(v, ana)
230: void *v;
231: ISO_RRIP_ANALYZE *ana;
232: {
233: ISO_RRIP_ALTNAME *p = v;
234: char *inbuf;
235: int wlen;
236: int cont;
1.2.2.4 skrll 237:
1.1 jdolecek 238: inbuf = "..";
239: wlen = 0;
240: cont = 0;
1.2.2.4 skrll 241:
1.1 jdolecek 242: switch (*p->flags) {
243: case ISO_SUSP_CFLAG_CURRENT:
244: /* Inserting Current */
245: wlen = 1;
246: break;
1.2.2.4 skrll 247:
1.1 jdolecek 248: case ISO_SUSP_CFLAG_PARENT:
249: /* Inserting Parent */
250: wlen = 2;
251: break;
1.2.2.4 skrll 252:
1.1 jdolecek 253: case ISO_SUSP_CFLAG_HOST:
254: /* Inserting hostname i.e. "kurt.tools.de" */
255: inbuf = hostname;
256: wlen = hostnamelen;
257: break;
1.2.2.4 skrll 258:
1.1 jdolecek 259: case ISO_SUSP_CFLAG_CONTINUE:
260: cont = 1;
261: /* fall thru */
262: case 0:
263: /* Inserting component */
264: wlen = isonum_711(p->h.length) - 5;
265: inbuf = (char *)p + 5;
266: break;
1.2.2.4 skrll 267:
1.1 jdolecek 268: default:
269: printf("RRIP with incorrect NM flags?\n");
270: wlen = ana->maxlen + 1;
271: break;
272: }
1.2.2.4 skrll 273:
1.1 jdolecek 274: if ((*ana->outlen += wlen) > ana->maxlen) {
275: /* treat as no name field */
276: ana->fields &= ~ISO_SUSP_ALTNAME;
277: ana->outbuf -= *ana->outlen - wlen;
278: *ana->outlen = 0;
279: return 0;
280: }
1.2.2.4 skrll 281:
1.1 jdolecek 282: memcpy(ana->outbuf, inbuf, wlen);
283: ana->outbuf += wlen;
1.2.2.4 skrll 284:
1.1 jdolecek 285: if (!cont) {
286: ana->fields &= ~ISO_SUSP_ALTNAME;
287: return ISO_SUSP_ALTNAME;
288: }
289: return 0;
290: }
291:
292: static void
293: cd9660_rrip_defname(v, ana)
294: void *v;
295: ISO_RRIP_ANALYZE *ana;
296: {
297: struct iso_directory_record *isodir = v;
298:
299: isofntrans(isodir->name, isonum_711(isodir->name_len),
300: ana->outbuf, ana->outlen,
301: 1, 0, isonum_711(isodir->flags) & 4,
302: ana->imp->im_joliet_level);
303: switch (ana->outbuf[0]) {
304: default:
305: break;
306: case 0:
307: ana->outbuf[0] = '.';
308: *ana->outlen = 1;
309: break;
310: case 1:
1.2 itojun 311: strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen);
1.1 jdolecek 312: *ana->outlen = 2;
313: break;
314: }
315: }
316:
317: /*
318: * Parent or Child Link
319: */
320: static int
321: cd9660_rrip_pclink(v, ana)
322: void *v;
323: ISO_RRIP_ANALYZE *ana;
324: {
325: ISO_RRIP_CLINK *p = v;
326:
327: *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
328: ana->fields &= ~(ISO_SUSP_CLINK | ISO_SUSP_PLINK);
329: return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK;
330: }
331:
332: /*
333: * Relocated directory
334: */
335: /*ARGSUSED*/
336: static int
337: cd9660_rrip_reldir(v, ana)
338: void *v;
339: ISO_RRIP_ANALYZE *ana;
340: {
341: /* special hack to make caller aware of RE field */
342: *ana->outlen = 0;
343: ana->fields = 0;
344: return ISO_SUSP_RELDIR | ISO_SUSP_ALTNAME
345: | ISO_SUSP_CLINK | ISO_SUSP_PLINK;
346: }
347:
348: static int
349: cd9660_rrip_tstamp(v, ana)
350: void *v;
351: ISO_RRIP_ANALYZE *ana;
352: {
353: ISO_RRIP_TSTAMP *p = v;
354: u_char *ptime;
1.2.2.4 skrll 355:
1.1 jdolecek 356: ptime = p->time;
1.2.2.4 skrll 357:
1.1 jdolecek 358: /* Check a format of time stamp (7bytes/17bytes) */
359: if (!(*p->flags & ISO_SUSP_TSTAMP_FORM17)) {
360: if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
361: ptime += 7;
1.2.2.4 skrll 362:
1.1 jdolecek 363: if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
364: cd9660_tstamp_conv7(ptime, &ana->inop->inode.iso_mtime);
365: ptime += 7;
366: } else
367: memset(&ana->inop->inode.iso_mtime, 0, sizeof(struct timespec));
1.2.2.4 skrll 368:
1.1 jdolecek 369: if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
370: cd9660_tstamp_conv7(ptime, &ana->inop->inode.iso_atime);
371: ptime += 7;
372: } else
373: ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
1.2.2.4 skrll 374:
1.1 jdolecek 375: if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
376: cd9660_tstamp_conv7(ptime, &ana->inop->inode.iso_ctime);
377: else
378: ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
1.2.2.4 skrll 379:
1.1 jdolecek 380: } else {
381: if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
382: ptime += 17;
1.2.2.4 skrll 383:
1.1 jdolecek 384: if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
385: cd9660_tstamp_conv17(ptime, &ana->inop->inode.iso_mtime);
386: ptime += 17;
387: } else
388: memset(&ana->inop->inode.iso_mtime, 0, sizeof(struct timespec));
1.2.2.4 skrll 389:
1.1 jdolecek 390: if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
391: cd9660_tstamp_conv17(ptime, &ana->inop->inode.iso_atime);
392: ptime += 17;
393: } else
394: ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
1.2.2.4 skrll 395:
1.1 jdolecek 396: if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
397: cd9660_tstamp_conv17(ptime, &ana->inop->inode.iso_ctime);
398: else
399: ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
1.2.2.4 skrll 400:
1.1 jdolecek 401: }
402: ana->fields &= ~ISO_SUSP_TSTAMP;
403: return ISO_SUSP_TSTAMP;
404: }
405:
406: static void
407: cd9660_rrip_deftstamp(v, ana)
408: void *v;
409: ISO_RRIP_ANALYZE *ana;
410: {
411: struct iso_directory_record *isodir = v;
412:
413: cd9660_deftstamp(isodir, ana->inop, NULL);
414: }
415:
416: /*
417: * POSIX device modes
418: */
419: static int
420: cd9660_rrip_device(v, ana)
421: void *v;
422: ISO_RRIP_ANALYZE *ana;
423: {
424: ISO_RRIP_DEVICE *p = v;
425: u_int high, low;
1.2.2.4 skrll 426:
1.1 jdolecek 427: high = isonum_733(p->dev_t_high);
428: low = isonum_733(p->dev_t_low);
1.2.2.4 skrll 429:
1.1 jdolecek 430: if (high == 0)
431: ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
432: else
433: ana->inop->inode.iso_rdev = makedev(high, minor(low));
434: ana->fields &= ~ISO_SUSP_DEVICE;
435: return ISO_SUSP_DEVICE;
436: }
437:
438: /*
439: * Flag indicating
440: */
441: static int
442: cd9660_rrip_idflag(v, ana)
443: void *v;
444: ISO_RRIP_ANALYZE *ana;
445: {
446: ISO_RRIP_IDFLAG *p = v;
447:
448: ana->fields &= isonum_711(p->flags) | ~0xff; /* don't touch high bits */
449: /* special handling of RE field */
450: if (ana->fields & ISO_SUSP_RELDIR)
451: return cd9660_rrip_reldir(p, ana);
1.2.2.4 skrll 452:
1.1 jdolecek 453: return ISO_SUSP_IDFLAG;
454: }
455:
456: /*
457: * Continuation pointer
458: */
459: static int
460: cd9660_rrip_cont(v, ana)
461: void *v;
462: ISO_RRIP_ANALYZE *ana;
463: {
464: ISO_RRIP_CONT *p = v;
465:
466: ana->iso_ce_blk = isonum_733(p->location);
467: ana->iso_ce_off = isonum_733(p->offset);
468: ana->iso_ce_len = isonum_733(p->length);
469: return ISO_SUSP_CONT;
470: }
471:
472: /*
473: * System Use end
474: */
475: static int
476: cd9660_rrip_stop(v, ana)
477: void *v;
478: ISO_RRIP_ANALYZE *ana;
479: {
480: return ISO_SUSP_STOP;
481: }
482:
483: /*
484: * Extension reference
485: */
486: static int
487: cd9660_rrip_extref(v, ana)
488: void *v;
489: ISO_RRIP_ANALYZE *ana;
490: {
491: ISO_RRIP_EXTREF *p = v;
492:
493: if (isonum_711(p->version) != 1)
494: return 0;
495: if (isonum_711(p->len_id) != 9
496: && isonum_711(p->len_id) != 10)
497: return 0;
498: if (isonum_711(p->len_id) == 9
499: && memcmp((char *)p + 8, "IEEE_1282", 9))
500: return 0;
501: if (isonum_711(p->len_id) == 10
502: && memcmp((char *)p + 8, "IEEE_P1282", 10)
503: && memcmp((char *)p + 8, "RRIP_1991A", 10))
504: return 0;
505: ana->fields &= ~ISO_SUSP_EXTREF;
506: return ISO_SUSP_EXTREF;
507: }
508:
509:
510: static int
511: cd9660_rrip_loop(isodir, ana, table)
512: struct iso_directory_record *isodir;
513: ISO_RRIP_ANALYZE *ana;
514: const RRIP_TABLE *table;
515: {
516: const RRIP_TABLE *ptable;
517: ISO_SUSP_HEADER *phead;
518: ISO_SUSP_HEADER *pend;
519: struct buf *bp = NULL;
520: char *pwhead;
1.2.2.4 skrll 521: u_int16_t c;
1.1 jdolecek 522: int result;
1.2.2.4 skrll 523:
1.1 jdolecek 524: /*
525: * Note: If name length is odd,
526: * it will be padded by 1 byte after the name
527: */
528: pwhead = isodir->name + isonum_711(isodir->name_len);
529: if (!(isonum_711(isodir->name_len) & 1))
530: pwhead++;
531: isochar(isodir->name, pwhead, ana->imp->im_joliet_level, &c);
1.2.2.4 skrll 532:
1.1 jdolecek 533: /* If it's not the '.' entry of the root dir obey SP field */
534: if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
535: pwhead += ana->imp->rr_skip;
536: else
537: pwhead += ana->imp->rr_skip0;
1.2.2.4 skrll 538:
1.1 jdolecek 539: phead = (ISO_SUSP_HEADER *)pwhead;
540: pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
1.2.2.4 skrll 541:
1.1 jdolecek 542: result = 0;
543: while (1) {
544: ana->iso_ce_len = 0;
545: /*
546: * Note: "pend" should be more than one SUSP header
1.2.2.5 ! skrll 547: */
1.1 jdolecek 548: while (pend >= phead + 1) {
549: if (isonum_711(phead->version) == 1) {
550: for (ptable = table; ptable->func; ptable++) {
551: if (*phead->type == *ptable->type
552: && phead->type[1] == ptable->type[1]) {
553: result |= ptable->func(phead, ana);
554: break;
555: }
556: }
557: if (!ana->fields)
558: break;
559: }
560: if (result & ISO_SUSP_STOP) {
561: result &= ~ISO_SUSP_STOP;
562: break;
563: }
564: /* plausibility check */
565: if (isonum_711(phead->length) < sizeof(*phead))
566: break;
567: /*
568: * move to next SUSP
569: * Hopefully this works with newer versions, too
570: */
571: phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length));
572: }
1.2.2.4 skrll 573:
1.1 jdolecek 574: if (ana->fields && ana->iso_ce_len) {
575: if (ana->iso_ce_blk >= ana->imp->volume_space_size
576: || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
577: || bread(ana->imp->im_devvp,
578: ana->iso_ce_blk << (ana->imp->im_bshift - DEV_BSHIFT),
579: ana->imp->logical_block_size, NOCRED, &bp))
580: /* what to do now? */
581: break;
582: phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
583: pend = (ISO_SUSP_HEADER *)((char *)phead + ana->iso_ce_len);
584: } else
585: break;
586: }
587: if (bp)
588: brelse(bp);
589: /*
590: * If we don't find the Basic SUSP stuffs, just set default value
591: * (attribute/time stamp)
592: */
593: for (ptable = table; ptable->func2; ptable++)
594: if (!(ptable->result & result))
595: ptable->func2(isodir, ana);
1.2.2.4 skrll 596:
1.1 jdolecek 597: return result;
598: }
599:
600: /*
601: * Get Attributes.
602: */
603: static const RRIP_TABLE rrip_table_analyze[] = {
604: { "PX", cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR },
605: { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP },
606: { "PN", cd9660_rrip_device, 0, ISO_SUSP_DEVICE },
607: { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
608: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
609: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
610: { "", 0, 0, 0 }
611: };
612:
613: int
614: cd9660_rrip_analyze(isodir, inop, imp)
615: struct iso_directory_record *isodir;
616: struct iso_node *inop;
617: struct iso_mnt *imp;
618: {
619: ISO_RRIP_ANALYZE analyze;
1.2.2.4 skrll 620:
1.1 jdolecek 621: analyze.inop = inop;
622: analyze.imp = imp;
623: analyze.fields = ISO_SUSP_ATTR | ISO_SUSP_TSTAMP | ISO_SUSP_DEVICE;
1.2.2.4 skrll 624:
1.1 jdolecek 625: return cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze);
626: }
627:
1.2.2.5 ! skrll 628: /*
1.1 jdolecek 629: * Get Alternate Name.
630: */
631: static const RRIP_TABLE rrip_table_getname[] = {
632: { "NM", cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME },
633: { "CL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
634: { "PL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
635: { "RE", cd9660_rrip_reldir, 0, ISO_SUSP_RELDIR },
636: { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
637: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
638: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
639: { "", 0, 0, 0 }
640: };
641:
642: int
643: cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp)
644: struct iso_directory_record *isodir;
645: char *outbuf;
646: u_short *outlen;
647: ino_t *inump;
648: struct iso_mnt *imp;
649: {
650: ISO_RRIP_ANALYZE analyze;
651: const RRIP_TABLE *tab;
1.2.2.4 skrll 652: u_int16_t c;
653:
1.1 jdolecek 654: analyze.outbuf = outbuf;
655: analyze.outlen = outlen;
656: analyze.maxlen = NAME_MAX;
657: analyze.inump = inump;
658: analyze.imp = imp;
659: analyze.fields = ISO_SUSP_ALTNAME | ISO_SUSP_RELDIR | ISO_SUSP_CLINK | ISO_SUSP_PLINK;
660: *outlen = 0;
1.2.2.4 skrll 661:
1.1 jdolecek 662: isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
663: imp->im_joliet_level, &c);
664: tab = rrip_table_getname;
665: if (c == 0 || c == 1) {
666: cd9660_rrip_defname(isodir, &analyze);
1.2.2.4 skrll 667:
1.1 jdolecek 668: analyze.fields &= ~ISO_SUSP_ALTNAME;
669: tab++;
670: }
1.2.2.4 skrll 671:
1.1 jdolecek 672: return cd9660_rrip_loop(isodir, &analyze, tab);
673: }
674:
1.2.2.5 ! skrll 675: /*
1.1 jdolecek 676: * Get Symbolic Link.
677: */
678: static const RRIP_TABLE rrip_table_getsymname[] = {
679: { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
680: { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
681: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
682: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
683: { "", 0, 0, 0 }
684: };
685:
686: int
687: cd9660_rrip_getsymname(isodir, outbuf, outlen, imp)
688: struct iso_directory_record *isodir;
689: char *outbuf;
690: u_short *outlen;
691: struct iso_mnt *imp;
692: {
693: ISO_RRIP_ANALYZE analyze;
1.2.2.4 skrll 694:
1.1 jdolecek 695: analyze.outbuf = outbuf;
696: analyze.outlen = outlen;
697: *outlen = 0;
698: analyze.maxlen = MAXPATHLEN;
699: analyze.cont = 1; /* don't start with a slash */
700: analyze.imp = imp;
701: analyze.fields = ISO_SUSP_SLINK;
1.2.2.4 skrll 702:
1.1 jdolecek 703: return cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) & ISO_SUSP_SLINK;
704: }
705:
706: static const RRIP_TABLE rrip_table_extref[] = {
707: { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF },
708: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
709: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
710: { "", 0, 0, 0 }
711: };
712:
713: /*
714: * Check for Rock Ridge Extension and return offset of its fields.
715: * Note: We insist on the ER field.
716: */
717: int
718: cd9660_rrip_offset(isodir, imp)
719: struct iso_directory_record *isodir;
720: struct iso_mnt *imp;
721: {
722: ISO_RRIP_OFFSET *p;
723: ISO_RRIP_ANALYZE analyze;
1.2.2.4 skrll 724:
1.1 jdolecek 725: imp->rr_skip0 = 0;
726: p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
727: if (memcmp(p, "SP\7\1\276\357", 6)) {
728: /* Maybe, it's a CDROM XA disc? */
729: imp->rr_skip0 = 15;
730: p = (ISO_RRIP_OFFSET *)((char *)p + 15);
731: if (memcmp(p, "SP\7\1\276\357", 6))
732: return -1;
733: }
1.2.2.4 skrll 734:
1.1 jdolecek 735: analyze.imp = imp;
736: analyze.fields = ISO_SUSP_EXTREF;
737: if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) & ISO_SUSP_EXTREF))
738: return -1;
1.2.2.4 skrll 739:
1.1 jdolecek 740: return isonum_711(p->skip);
741: }
CVSweb <webmaster@jp.NetBSD.org>