]> git.saurik.com Git - apple/xnu.git/blame - bsd/isofs/cd9660/cd9660_rrip.c
xnu-792.17.14.tar.gz
[apple/xnu.git] / bsd / isofs / cd9660 / cd9660_rrip.c
CommitLineData
1c79356b 1/*
5d5c5d0d
A
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
8f6c56a5
A
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
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
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 */
97static int
91447636 98cd9660_rrip_attr(ISO_RRIP_ATTR *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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
108static void
91447636 109cd9660_rrip_defattr(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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 */
119static int
91447636 120cd9660_rrip_slink(ISO_RRIP_SLINK *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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;
91447636 176 inbuf = &(vfs_statfs(ana->imp->im_mountp)->f_mntonname);
1c79356b
A
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 */
228static int
91447636 229cd9660_rrip_altname(ISO_RRIP_ALTNAME *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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
289static void
91447636 290cd9660_rrip_defname(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana)
1c79356b
A
291{
292 strcpy(ana->outbuf,"..");
293 switch (*isodir->name) {
294 default:
295 isofntrans(isodir->name, isonum_711(isodir->name_len),
55e303ae
A
296 ana->outbuf, ana->outlen, 1,
297 isonum_711(isodir->flags) & associatedBit);
1c79356b
A
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 */
311static int
91447636 312cd9660_rrip_pclink(ISO_RRIP_CLINK *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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 */
91447636 322/* ARGSUSED */
1c79356b 323static int
91447636 324cd9660_rrip_reldir(__unused ISO_RRIP_RELDIR *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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
332static int
91447636 333cd9660_rrip_tstamp(ISO_RRIP_TSTAMP *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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
387static void
91447636
A
388cd9660_rrip_deftstamp(struct iso_directory_record *isodir,
389 ISO_RRIP_ANALYZE *ana)
1c79356b
A
390{
391 cd9660_deftstamp(isodir,ana->inop,NULL);
392}
393
394/*
395 * POSIX device modes
396 */
397static int
91447636 398cd9660_rrip_device(ISO_RRIP_DEVICE *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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 */
416static int
91447636 417cd9660_rrip_idflag(ISO_RRIP_IDFLAG *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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 */
430static int
91447636 431cd9660_rrip_cont(ISO_RRIP_CONT *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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 */
91447636 442/* ARGSUSED */
1c79356b 443static int
91447636 444cd9660_rrip_stop(__unused ISO_SUSP_HEADER *p, __unused ISO_RRIP_ANALYZE *ana)
1c79356b
A
445{
446 return ISO_SUSP_STOP;
447}
448
449/*
450 * Extension reference
451 */
452static int
91447636 453cd9660_rrip_extref(ISO_RRIP_EXTREF *p, ISO_RRIP_ANALYZE *ana)
1c79356b
A
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
91447636
A
463typedef int (*rrip_table_func)(ISO_SUSP_HEADER *phead, ISO_RRIP_ANALYZE *ana);
464typedef int (*rrip_table_func2)(struct iso_directory_record *isodir,
465 ISO_RRIP_ANALYZE *ana);
1c79356b
A
466typedef struct {
467 char type[2];
91447636
A
468 rrip_table_func func;
469 rrip_table_func2 func2;
1c79356b
A
470 int result;
471} RRIP_TABLE;
472
473static int
91447636
A
474cd9660_rrip_loop(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana,
475 RRIP_TABLE *table)
1c79356b
A
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]) {
91447636 513 result |= (ptable->func(phead,ana));
1c79356b
A
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
91447636 537 || buf_bread(ana->imp->im_devvp,
1c79356b 538#if 1 // radar 1669467 - logical and physical blocksize are the same
91447636 539 (daddr64_t)((unsigned)ana->iso_ce_blk),
1c79356b 540#else
91447636 541 (daddr64_t)((unsigned)(ana->iso_ce_blk << (ana->imp->im_bshift - DEV_BSHIFT))),
1c79356b
A
542#endif // radar 1669467
543 ana->imp->logical_block_size, NOCRED, &bp))
544 /* what to do now? */
545 break;
91447636 546 phead = (ISO_SUSP_HEADER *)((char *)buf_dataptr(bp) + ana->iso_ce_off);
1c79356b
A
547 pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len);
548 } else
549 break;
550 }
551 if (bp)
91447636 552 buf_brelse(bp);
1c79356b
A
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 */
567static RRIP_TABLE rrip_table_analyze[] = {
91447636
A
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 },
1c79356b
A
580 { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
581 { "", 0, 0, 0 }
582};
583
584int
91447636
A
585cd9660_rrip_analyze(struct iso_directory_record *isodir, struct iso_node *inop,
586 struct iso_mnt *imp)
1c79356b
A
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 */
600static RRIP_TABLE rrip_table_getname[] = {
91447636
A
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 },
1c79356b
A
614 { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
615 { "", 0, 0, 0 }
616};
617
618int
91447636
A
619cd9660_rrip_getname(struct iso_directory_record *isodir, char *outbuf,
620 u_short *outlen, ino_t *inump, struct iso_mnt *imp)
1c79356b
A
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 */
648static RRIP_TABLE rrip_table_getsymname[] = {
91447636
A
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 },
1c79356b
A
655 { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
656 { "", 0, 0, 0 }
657};
658
659int
91447636
A
660cd9660_rrip_getsymname(struct iso_directory_record *isodir, char *outbuf,
661 u_short *outlen, struct iso_mnt *imp)
1c79356b
A
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
676static RRIP_TABLE rrip_table_extref[] = {
91447636
A
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 },
1c79356b
A
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 */
689int
91447636 690cd9660_rrip_offset(struct iso_directory_record *isodir, struct iso_mnt *imp)
1c79356b
A
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}