Annotation of XNU/bsd/isofs/cd9660/cd9660_rrip.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.