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