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