|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* $NetBSD: cd9660_rrip.c,v 1.11 1994/12/24 15:30:10 cgd Exp $ */ ! 23: ! 24: /*- ! 25: * Copyright (c) 1993, 1994 ! 26: * The Regents of the University of California. All rights reserved. ! 27: * ! 28: * This code is derived from software contributed to Berkeley ! 29: * by Pace Willisson ([email protected]). The Rock Ridge Extension ! 30: * Support code is derived from software contributed to Berkeley ! 31: * by Atsushi Murai ([email protected]). ! 32: * ! 33: * Redistribution and use in source and binary forms, with or without ! 34: * modification, are permitted provided that the following conditions ! 35: * are met: ! 36: * 1. Redistributions of source code must retain the above copyright ! 37: * notice, this list of conditions and the following disclaimer. ! 38: * 2. Redistributions in binary form must reproduce the above copyright ! 39: * notice, this list of conditions and the following disclaimer in the ! 40: * documentation and/or other materials provided with the distribution. ! 41: * 3. All advertising materials mentioning features or use of this software ! 42: * must display the following acknowledgement: ! 43: * This product includes software developed by the University of ! 44: * California, Berkeley and its contributors. ! 45: * 4. Neither the name of the University nor the names of its contributors ! 46: * may be used to endorse or promote products derived from this software ! 47: * without specific prior written permission. ! 48: * ! 49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 59: * SUCH DAMAGE. ! 60: * ! 61: * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94 ! 62: ! 63: ! 64: ! 65: * HISTORY ! 66: * 22-Jan-98 radar 1669467 - ISO 9660 CD support - jwc ! 67: ! 68: */ ! 69: ! 70: #include <sys/param.h> ! 71: #include <sys/systm.h> ! 72: #include <sys/namei.h> ! 73: #include <sys/buf.h> ! 74: #include <sys/file.h> ! 75: #include <sys/vnode.h> ! 76: #include <sys/mount.h> ! 77: #include <sys/kernel.h> ! 78: #include <sys/stat.h> ! 79: #include <sys/types.h> ! 80: ! 81: #include <sys/time.h> ! 82: ! 83: #include <isofs/cd9660/iso.h> ! 84: #include <isofs/cd9660/cd9660_node.h> ! 85: #include <isofs/cd9660/cd9660_rrip.h> ! 86: #include <isofs/cd9660/iso_rrip.h> ! 87: ! 88: /* ! 89: * POSIX file attribute ! 90: */ ! 91: static int ! 92: cd9660_rrip_attr(p,ana) ! 93: ISO_RRIP_ATTR *p; ! 94: ISO_RRIP_ANALYZE *ana; ! 95: { ! 96: ana->inop->inode.iso_mode = isonum_733(p->mode); ! 97: ana->inop->inode.iso_uid = isonum_733(p->uid); ! 98: ana->inop->inode.iso_gid = isonum_733(p->gid); ! 99: ana->inop->inode.iso_links = isonum_733(p->links); ! 100: ana->fields &= ~ISO_SUSP_ATTR; ! 101: return ISO_SUSP_ATTR; ! 102: } ! 103: ! 104: static void ! 105: cd9660_rrip_defattr(isodir,ana) ! 106: struct iso_directory_record *isodir; ! 107: ISO_RRIP_ANALYZE *ana; ! 108: { ! 109: /* But this is a required field! */ ! 110: printf("RRIP without PX field?\n"); ! 111: cd9660_defattr(isodir,ana->inop,NULL); ! 112: } ! 113: ! 114: /* ! 115: * Symbolic Links ! 116: */ ! 117: static int ! 118: cd9660_rrip_slink(p,ana) ! 119: ISO_RRIP_SLINK *p; ! 120: 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 = ana->imp->im_mountp->mnt_stat.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(p,ana) ! 230: ISO_RRIP_ALTNAME *p; ! 231: 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(isodir,ana) ! 293: struct iso_directory_record *isodir; ! 294: ISO_RRIP_ANALYZE *ana; ! 295: { ! 296: strcpy(ana->outbuf,".."); ! 297: switch (*isodir->name) { ! 298: default: ! 299: isofntrans(isodir->name,isonum_711(isodir->name_len), ! 300: ana->outbuf,ana->outlen, ! 301: 1,isonum_711(isodir->flags) & associatedBit); ! 302: break; ! 303: case 0: ! 304: *ana->outlen = 1; ! 305: break; ! 306: case 1: ! 307: *ana->outlen = 2; ! 308: break; ! 309: } ! 310: } ! 311: ! 312: /* ! 313: * Parent or Child Link ! 314: */ ! 315: static int ! 316: cd9660_rrip_pclink(p,ana) ! 317: ISO_RRIP_CLINK *p; ! 318: ISO_RRIP_ANALYZE *ana; ! 319: { ! 320: *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift; ! 321: ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK); ! 322: return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK; ! 323: } ! 324: ! 325: /* ! 326: * Relocated directory ! 327: */ ! 328: static int ! 329: cd9660_rrip_reldir(p,ana) ! 330: ISO_RRIP_RELDIR *p; ! 331: ISO_RRIP_ANALYZE *ana; ! 332: { ! 333: /* special hack to make caller aware of RE field */ ! 334: *ana->outlen = 0; ! 335: ana->fields = 0; ! 336: return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK; ! 337: } ! 338: ! 339: static int ! 340: cd9660_rrip_tstamp(p,ana) ! 341: ISO_RRIP_TSTAMP *p; ! 342: ISO_RRIP_ANALYZE *ana; ! 343: { ! 344: u_char *ptime; ! 345: ! 346: ptime = p->time; ! 347: ! 348: /* Check a format of time stamp (7bytes/17bytes) */ ! 349: if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) { ! 350: if (*p->flags&ISO_SUSP_TSTAMP_CREAT) ! 351: ptime += 7; ! 352: ! 353: if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { ! 354: cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime); ! 355: ptime += 7; ! 356: } else ! 357: bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec)); ! 358: ! 359: if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { ! 360: cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime); ! 361: ptime += 7; ! 362: } else ! 363: ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; ! 364: ! 365: if (*p->flags&ISO_SUSP_TSTAMP_ATTR) ! 366: cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime); ! 367: else ! 368: ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; ! 369: ! 370: } else { ! 371: if (*p->flags&ISO_SUSP_TSTAMP_CREAT) ! 372: ptime += 17; ! 373: ! 374: if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { ! 375: cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime); ! 376: ptime += 17; ! 377: } else ! 378: bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec)); ! 379: ! 380: if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { ! 381: cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime); ! 382: ptime += 17; ! 383: } else ! 384: ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; ! 385: ! 386: if (*p->flags&ISO_SUSP_TSTAMP_ATTR) ! 387: cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime); ! 388: else ! 389: ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; ! 390: ! 391: } ! 392: ana->fields &= ~ISO_SUSP_TSTAMP; ! 393: return ISO_SUSP_TSTAMP; ! 394: } ! 395: ! 396: static void ! 397: cd9660_rrip_deftstamp(isodir,ana) ! 398: struct iso_directory_record *isodir; ! 399: ISO_RRIP_ANALYZE *ana; ! 400: { ! 401: cd9660_deftstamp(isodir,ana->inop,NULL); ! 402: } ! 403: ! 404: /* ! 405: * POSIX device modes ! 406: */ ! 407: static int ! 408: cd9660_rrip_device(p,ana) ! 409: ISO_RRIP_DEVICE *p; ! 410: ISO_RRIP_ANALYZE *ana; ! 411: { ! 412: u_int high, low; ! 413: ! 414: high = isonum_733(p->dev_t_high); ! 415: low = isonum_733(p->dev_t_low); ! 416: ! 417: if (high == 0) ! 418: ana->inop->inode.iso_rdev = makedev(major(low), minor(low)); ! 419: else ! 420: ana->inop->inode.iso_rdev = makedev(high, minor(low)); ! 421: ana->fields &= ~ISO_SUSP_DEVICE; ! 422: return ISO_SUSP_DEVICE; ! 423: } ! 424: ! 425: /* ! 426: * Flag indicating ! 427: */ ! 428: static int ! 429: cd9660_rrip_idflag(p,ana) ! 430: ISO_RRIP_IDFLAG *p; ! 431: ISO_RRIP_ANALYZE *ana; ! 432: { ! 433: ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */ ! 434: /* special handling of RE field */ ! 435: if (ana->fields&ISO_SUSP_RELDIR) ! 436: return cd9660_rrip_reldir(p,ana); ! 437: ! 438: return ISO_SUSP_IDFLAG; ! 439: } ! 440: ! 441: /* ! 442: * Continuation pointer ! 443: */ ! 444: static int ! 445: cd9660_rrip_cont(p,ana) ! 446: ISO_RRIP_CONT *p; ! 447: ISO_RRIP_ANALYZE *ana; ! 448: { ! 449: ana->iso_ce_blk = isonum_733(p->location); ! 450: ana->iso_ce_off = isonum_733(p->offset); ! 451: ana->iso_ce_len = isonum_733(p->length); ! 452: return ISO_SUSP_CONT; ! 453: } ! 454: ! 455: /* ! 456: * System Use end ! 457: */ ! 458: static int ! 459: cd9660_rrip_stop(p,ana) ! 460: ISO_SUSP_HEADER *p; ! 461: ISO_RRIP_ANALYZE *ana; ! 462: { ! 463: return ISO_SUSP_STOP; ! 464: } ! 465: ! 466: /* ! 467: * Extension reference ! 468: */ ! 469: static int ! 470: cd9660_rrip_extref(p,ana) ! 471: ISO_RRIP_EXTREF *p; ! 472: ISO_RRIP_ANALYZE *ana; ! 473: { ! 474: if (isonum_711(p->len_id) != 10 ! 475: || bcmp((char *)p + 8,"RRIP_1991A",10) ! 476: || isonum_711(p->version) != 1) ! 477: return 0; ! 478: ana->fields &= ~ISO_SUSP_EXTREF; ! 479: return ISO_SUSP_EXTREF; ! 480: } ! 481: ! 482: typedef struct { ! 483: char type[2]; ! 484: int (*func)(); ! 485: void (*func2)(); ! 486: int result; ! 487: } RRIP_TABLE; ! 488: ! 489: static int ! 490: cd9660_rrip_loop(isodir,ana,table) ! 491: struct iso_directory_record *isodir; ! 492: ISO_RRIP_ANALYZE *ana; ! 493: RRIP_TABLE *table; ! 494: { ! 495: register RRIP_TABLE *ptable; ! 496: register ISO_SUSP_HEADER *phead; ! 497: register ISO_SUSP_HEADER *pend; ! 498: struct buf *bp = NULL; ! 499: char *pwhead; ! 500: int result; ! 501: ! 502: /* ! 503: * Note: If name length is odd, ! 504: * it will be padding 1 byte after the name ! 505: */ ! 506: pwhead = isodir->name + isonum_711(isodir->name_len); ! 507: if (!(isonum_711(isodir->name_len)&1)) ! 508: pwhead++; ! 509: ! 510: /* If it's not the '.' entry of the root dir obey SP field */ ! 511: if (*isodir->name != 0 ! 512: || isonum_733(isodir->extent) != ana->imp->root_extent) ! 513: pwhead += ana->imp->rr_skip; ! 514: else ! 515: pwhead += ana->imp->rr_skip0; ! 516: ! 517: phead = (ISO_SUSP_HEADER *)pwhead; ! 518: pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); ! 519: ! 520: result = 0; ! 521: while (1) { ! 522: ana->iso_ce_len = 0; ! 523: /* ! 524: * Note: "pend" should be more than one SUSP header ! 525: */ ! 526: while (pend >= phead + 1) { ! 527: if (isonum_711(phead->version) == 1) { ! 528: for (ptable = table; ptable->func; ptable++) { ! 529: if (*phead->type == *ptable->type ! 530: && phead->type[1] == ptable->type[1]) { ! 531: result |= ptable->func(phead,ana); ! 532: break; ! 533: } ! 534: } ! 535: if (!ana->fields) ! 536: break; ! 537: } ! 538: if (result&ISO_SUSP_STOP) { ! 539: result &= ~ISO_SUSP_STOP; ! 540: break; ! 541: } ! 542: /* plausibility check */ ! 543: if (isonum_711(phead->length) < sizeof(*phead)) ! 544: break; ! 545: /* ! 546: * move to next SUSP ! 547: * Hopefully this works with newer versions, too ! 548: */ ! 549: phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length)); ! 550: } ! 551: ! 552: if (ana->fields && ana->iso_ce_len) { ! 553: if (ana->iso_ce_blk >= ana->imp->volume_space_size ! 554: || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size ! 555: || bread(ana->imp->im_devvp, ! 556: #if 1 // radar 1669467 - logical and physical blocksize are the same ! 557: ana->iso_ce_blk, ! 558: #else ! 559: ana->iso_ce_blk << (ana->imp->im_bshift - DEV_BSHIFT), ! 560: #endif // radar 1669467 ! 561: ana->imp->logical_block_size, NOCRED, &bp)) ! 562: /* what to do now? */ ! 563: break; ! 564: phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off); ! 565: pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len); ! 566: } else ! 567: break; ! 568: } ! 569: if (bp) ! 570: brelse(bp); ! 571: /* ! 572: * If we don't find the Basic SUSP stuffs, just set default value ! 573: * (attribute/time stamp) ! 574: */ ! 575: for (ptable = table; ptable->func2; ptable++) ! 576: if (!(ptable->result&result)) ! 577: ptable->func2(isodir,ana); ! 578: ! 579: return result; ! 580: } ! 581: ! 582: /* ! 583: * Get Attributes. ! 584: */ ! 585: static RRIP_TABLE rrip_table_analyze[] = { ! 586: { "PX", cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR }, ! 587: { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP }, ! 588: { "PN", cd9660_rrip_device, 0, ISO_SUSP_DEVICE }, ! 589: { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! 590: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, ! 591: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, ! 592: { "", 0, 0, 0 } ! 593: }; ! 594: ! 595: int ! 596: cd9660_rrip_analyze(isodir,inop,imp) ! 597: struct iso_directory_record *isodir; ! 598: struct iso_node *inop; ! 599: struct iso_mnt *imp; ! 600: { ! 601: ISO_RRIP_ANALYZE analyze; ! 602: ! 603: analyze.inop = inop; ! 604: analyze.imp = imp; ! 605: analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE; ! 606: ! 607: return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze); ! 608: } ! 609: ! 610: /* ! 611: * Get Alternate Name. ! 612: */ ! 613: static RRIP_TABLE rrip_table_getname[] = { ! 614: { "NM", cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME }, ! 615: { "CL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, ! 616: { "PL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, ! 617: { "RE", cd9660_rrip_reldir, 0, ISO_SUSP_RELDIR }, ! 618: { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! 619: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, ! 620: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, ! 621: { "", 0, 0, 0 } ! 622: }; ! 623: ! 624: int ! 625: cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp) ! 626: struct iso_directory_record *isodir; ! 627: char *outbuf; ! 628: u_short *outlen; ! 629: ino_t *inump; ! 630: struct iso_mnt *imp; ! 631: { ! 632: ISO_RRIP_ANALYZE analyze; ! 633: RRIP_TABLE *tab; ! 634: ! 635: analyze.outbuf = outbuf; ! 636: analyze.outlen = outlen; ! 637: analyze.maxlen = NAME_MAX; ! 638: analyze.inump = inump; ! 639: analyze.imp = imp; ! 640: analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK; ! 641: *outlen = 0; ! 642: ! 643: tab = rrip_table_getname; ! 644: if (*isodir->name == 0 ! 645: || *isodir->name == 1) { ! 646: cd9660_rrip_defname(isodir,&analyze); ! 647: ! 648: analyze.fields &= ~ISO_SUSP_ALTNAME; ! 649: tab++; ! 650: } ! 651: ! 652: return cd9660_rrip_loop(isodir,&analyze,tab); ! 653: } ! 654: ! 655: /* ! 656: * Get Symbolic Link. ! 657: */ ! 658: static RRIP_TABLE rrip_table_getsymname[] = { ! 659: { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK }, ! 660: { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! 661: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, ! 662: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, ! 663: { "", 0, 0, 0 } ! 664: }; ! 665: ! 666: int ! 667: cd9660_rrip_getsymname(isodir,outbuf,outlen,imp) ! 668: struct iso_directory_record *isodir; ! 669: char *outbuf; ! 670: u_short *outlen; ! 671: struct iso_mnt *imp; ! 672: { ! 673: ISO_RRIP_ANALYZE analyze; ! 674: ! 675: analyze.outbuf = outbuf; ! 676: analyze.outlen = outlen; ! 677: *outlen = 0; ! 678: analyze.maxlen = MAXPATHLEN; ! 679: analyze.cont = 1; /* don't start with a slash */ ! 680: analyze.imp = imp; ! 681: analyze.fields = ISO_SUSP_SLINK; ! 682: ! 683: return (cd9660_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK); ! 684: } ! 685: ! 686: static RRIP_TABLE rrip_table_extref[] = { ! 687: { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF }, ! 688: { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, ! 689: { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, ! 690: { "", 0, 0, 0 } ! 691: }; ! 692: ! 693: /* ! 694: * Check for Rock Ridge Extension and return offset of its fields. ! 695: * Note: We insist on the ER field. ! 696: */ ! 697: int ! 698: cd9660_rrip_offset(isodir,imp) ! 699: struct iso_directory_record *isodir; ! 700: struct iso_mnt *imp; ! 701: { ! 702: ISO_RRIP_OFFSET *p; ! 703: ISO_RRIP_ANALYZE analyze; ! 704: ! 705: imp->rr_skip0 = 0; ! 706: p = (ISO_RRIP_OFFSET *)(isodir->name + 1); ! 707: if (bcmp(p,"SP\7\1\276\357",6)) { ! 708: /* Maybe, it's a CDROM XA disc? */ ! 709: imp->rr_skip0 = 15; ! 710: p = (ISO_RRIP_OFFSET *)((char *)p + 15); ! 711: if (bcmp(p,"SP\7\1\276\357",6)) ! 712: return -1; ! 713: } ! 714: ! 715: analyze.imp = imp; ! 716: analyze.fields = ISO_SUSP_EXTREF; ! 717: if (!(cd9660_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF)) ! 718: return -1; ! 719: ! 720: return isonum_711(p->skip); ! 721: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.