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