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