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