[BACK]Return to cd9660_rrip.c CVS log [TXT][DIR] Up to [local] / sys / isofs / cd9660

Annotation of sys/isofs/cd9660/cd9660_rrip.c, Revision 1.1.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