|
|
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.