[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     ! 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