[BACK]Return to cd9660_rrip.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / cd9660

Annotation of src/sys/fs/cd9660/cd9660_rrip.c, Revision 1.2.2.5

1.2.2.5 ! skrll       1: /*     $NetBSD: cd9660_rrip.c,v 1.2.2.4 2004/11/29 07:24:50 skrll Exp $        */
1.1       jdolecek    2:
                      3: /*-
                      4:  * Copyright (c) 1993, 1994
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley
                      8:  * by Pace Willisson (pace@blitz.com).  The Rock Ridge Extension
                      9:  * Support code is derived from software contributed to Berkeley
                     10:  * by Atsushi Murai (amurai@spec.co.jp).
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
1.2.2.1   skrll      20:  * 3. Neither the name of the University nor the names of its contributors
1.1       jdolecek   21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)cd9660_rrip.c       8.6 (Berkeley) 12/5/94
                     37:  */
                     38:
                     39: #include <sys/cdefs.h>
1.2.2.5 ! skrll      40: __KERNEL_RCSID(0, "$NetBSD: cd9660_rrip.c,v 1.2.2.4 2004/11/29 07:24:50 skrll Exp $");
1.1       jdolecek   41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/namei.h>
                     45: #include <sys/buf.h>
                     46: #include <sys/file.h>
                     47: #include <sys/vnode.h>
                     48: #include <sys/mount.h>
                     49: #include <sys/kernel.h>
                     50: #include <sys/stat.h>
                     51:
                     52: #include <sys/time.h>
                     53:
                     54: #include <fs/cd9660/iso.h>
                     55: #include <fs/cd9660/cd9660_extern.h>
                     56: #include <fs/cd9660/cd9660_node.h>
                     57: #include <fs/cd9660/cd9660_rrip.h>
                     58: #include <fs/cd9660/iso_rrip.h>
                     59:
                     60: typedef struct {
                     61:        char type[2];
                     62:        int (*func) __P((void *, ISO_RRIP_ANALYZE *));
                     63:        void (*func2) __P((void *, ISO_RRIP_ANALYZE *));
                     64:        int result;
                     65: } RRIP_TABLE;
                     66:
                     67: static int cd9660_rrip_attr __P((void *, ISO_RRIP_ANALYZE *));
                     68: static void cd9660_rrip_defattr __P((void *, ISO_RRIP_ANALYZE *));
                     69: static int cd9660_rrip_slink __P((void *, ISO_RRIP_ANALYZE *));
                     70: static int cd9660_rrip_altname __P((void *, ISO_RRIP_ANALYZE *));
                     71: static void cd9660_rrip_defname __P((void *, ISO_RRIP_ANALYZE *));
                     72: static int cd9660_rrip_pclink __P((void *, ISO_RRIP_ANALYZE *));
                     73: static int cd9660_rrip_reldir __P((void *, ISO_RRIP_ANALYZE *));
                     74: static int cd9660_rrip_tstamp __P((void *, ISO_RRIP_ANALYZE *));
                     75: static void cd9660_rrip_deftstamp __P((void *, ISO_RRIP_ANALYZE *));
                     76: static int cd9660_rrip_device __P((void *, ISO_RRIP_ANALYZE *));
                     77: static int cd9660_rrip_idflag __P((void *, ISO_RRIP_ANALYZE *));
                     78: static int cd9660_rrip_cont __P((void *, ISO_RRIP_ANALYZE *));
                     79: static int cd9660_rrip_stop __P((void *, ISO_RRIP_ANALYZE *));
                     80: static int cd9660_rrip_extref __P((void *, ISO_RRIP_ANALYZE *));
                     81: static int cd9660_rrip_loop __P((struct iso_directory_record *,
                     82:                                 ISO_RRIP_ANALYZE *, const RRIP_TABLE *));
                     83: /*
                     84:  * POSIX file attribute
                     85:  */
                     86: static int
                     87: cd9660_rrip_attr(v, ana)
                     88:        void *v;
                     89:        ISO_RRIP_ANALYZE *ana;
                     90: {
                     91:        ISO_RRIP_ATTR *p = v;
                     92:
                     93:        ana->inop->inode.iso_mode = isonum_733(p->mode);
                     94:        ana->inop->inode.iso_uid = isonum_733(p->uid);
                     95:        ana->inop->inode.iso_gid = isonum_733(p->gid);
                     96:        ana->inop->inode.iso_links = isonum_733(p->links);
                     97:        ana->fields &= ~ISO_SUSP_ATTR;
                     98:        return ISO_SUSP_ATTR;
                     99: }
                    100:
                    101: static void
                    102: cd9660_rrip_defattr(v, ana)
                    103:        void *v;
                    104:        ISO_RRIP_ANALYZE *ana;
                    105: {
                    106:        struct iso_directory_record *isodir = v;
                    107:
                    108:        /* But this is a required field! */
                    109:        printf("RRIP without PX field?\n");
                    110:        cd9660_defattr(isodir, ana->inop, NULL);
                    111: }
                    112:
                    113: /*
                    114:  * Symbolic Links
                    115:  */
                    116: static int
                    117: cd9660_rrip_slink(v, ana)
                    118:        void *v;
                    119:        ISO_RRIP_ANALYZE *ana;
                    120: {
                    121:        ISO_RRIP_SLINK  *p = v;
                    122:        ISO_RRIP_SLINK_COMPONENT *pcomp;
                    123:        ISO_RRIP_SLINK_COMPONENT *pcompe;
                    124:        int len, wlen, cont;
                    125:        char *outbuf, *inbuf;
1.2.2.4   skrll     126:
1.1       jdolecek  127:        pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
                    128:        pcompe = (ISO_RRIP_SLINK_COMPONENT *)
                    129:                ((char *)p + isonum_711(p->h.length));
                    130:        len = *ana->outlen;
                    131:        outbuf = ana->outbuf;
                    132:        cont = ana->cont;
1.2.2.4   skrll     133:
1.1       jdolecek  134:        /*
                    135:         * Gathering a Symbolic name from each component with path
                    136:         */
                    137:        for (;
                    138:             pcomp < pcompe;
                    139:             pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ
                    140:                                                  + isonum_711(pcomp->clen))) {
1.2.2.4   skrll     141:
1.1       jdolecek  142:                if (!cont) {
                    143:                        if (len < ana->maxlen) {
                    144:                                len++;
                    145:                                *outbuf++ = '/';
                    146:                        }
                    147:                }
                    148:                cont = 0;
1.2.2.4   skrll     149:
1.1       jdolecek  150:                inbuf = "..";
                    151:                wlen = 0;
1.2.2.4   skrll     152:
1.1       jdolecek  153:                switch (*pcomp->cflag) {
1.2.2.4   skrll     154:
1.1       jdolecek  155:                case ISO_SUSP_CFLAG_CURRENT:
                    156:                        /* Inserting Current */
                    157:                        wlen = 1;
                    158:                        break;
1.2.2.4   skrll     159:
1.1       jdolecek  160:                case ISO_SUSP_CFLAG_PARENT:
                    161:                        /* Inserting Parent */
                    162:                        wlen = 2;
                    163:                        break;
1.2.2.4   skrll     164:
1.1       jdolecek  165:                case ISO_SUSP_CFLAG_ROOT:
                    166:                        /* Inserting slash for ROOT */
                    167:                        /* start over from beginning(?) */
                    168:                        outbuf -= len;
                    169:                        len = 0;
                    170:                        break;
1.2.2.4   skrll     171:
1.1       jdolecek  172:                case ISO_SUSP_CFLAG_VOLROOT:
                    173:                        /* Inserting a mount point i.e. "/cdrom" */
                    174:                        /* same as above */
                    175:                        outbuf -= len;
                    176:                        len = 0;
                    177:                        inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
                    178:                        wlen = strlen(inbuf);
                    179:                        break;
1.2.2.4   skrll     180:
1.1       jdolecek  181:                case ISO_SUSP_CFLAG_HOST:
                    182:                        /* Inserting hostname i.e. "kurt.tools.de" */
                    183:                        inbuf = hostname;
                    184:                        wlen = hostnamelen;
                    185:                        break;
1.2.2.4   skrll     186:
1.1       jdolecek  187:                case ISO_SUSP_CFLAG_CONTINUE:
                    188:                        cont = 1;
                    189:                        /* fall thru */
                    190:                case 0:
                    191:                        /* Inserting component */
                    192:                        wlen = isonum_711(pcomp->clen);
                    193:                        inbuf = pcomp->name;
                    194:                        break;
                    195:                default:
                    196:                        printf("RRIP with incorrect flags?");
                    197:                        wlen = ana->maxlen + 1;
                    198:                        break;
                    199:                }
1.2.2.4   skrll     200:
1.1       jdolecek  201:                if (len + wlen > ana->maxlen) {
                    202:                        /* indicate error to caller */
                    203:                        ana->cont = 1;
                    204:                        ana->fields = 0;
                    205:                        ana->outbuf -= *ana->outlen;
                    206:                        *ana->outlen = 0;
                    207:                        return 0;
                    208:                }
1.2.2.4   skrll     209:
1.1       jdolecek  210:                memcpy(outbuf, inbuf, wlen);
                    211:                outbuf += wlen;
                    212:                len += wlen;
                    213:        }
                    214:        ana->outbuf = outbuf;
                    215:        *ana->outlen = len;
                    216:        ana->cont = cont;
1.2.2.4   skrll     217:
1.1       jdolecek  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(v, ana)
                    230:        void *v;
                    231:        ISO_RRIP_ANALYZE *ana;
                    232: {
                    233:        ISO_RRIP_ALTNAME *p = v;
                    234:        char *inbuf;
                    235:        int wlen;
                    236:        int cont;
1.2.2.4   skrll     237:
1.1       jdolecek  238:        inbuf = "..";
                    239:        wlen = 0;
                    240:        cont = 0;
1.2.2.4   skrll     241:
1.1       jdolecek  242:        switch (*p->flags) {
                    243:        case ISO_SUSP_CFLAG_CURRENT:
                    244:                /* Inserting Current */
                    245:                wlen = 1;
                    246:                break;
1.2.2.4   skrll     247:
1.1       jdolecek  248:        case ISO_SUSP_CFLAG_PARENT:
                    249:                /* Inserting Parent */
                    250:                wlen = 2;
                    251:                break;
1.2.2.4   skrll     252:
1.1       jdolecek  253:        case ISO_SUSP_CFLAG_HOST:
                    254:                /* Inserting hostname i.e. "kurt.tools.de" */
                    255:                inbuf = hostname;
                    256:                wlen = hostnamelen;
                    257:                break;
1.2.2.4   skrll     258:
1.1       jdolecek  259:        case ISO_SUSP_CFLAG_CONTINUE:
                    260:                cont = 1;
                    261:                /* fall thru */
                    262:        case 0:
                    263:                /* Inserting component */
                    264:                wlen = isonum_711(p->h.length) - 5;
                    265:                inbuf = (char *)p + 5;
                    266:                break;
1.2.2.4   skrll     267:
1.1       jdolecek  268:        default:
                    269:                printf("RRIP with incorrect NM flags?\n");
                    270:                wlen = ana->maxlen + 1;
                    271:                break;
                    272:        }
1.2.2.4   skrll     273:
1.1       jdolecek  274:        if ((*ana->outlen += wlen) > ana->maxlen) {
                    275:                /* treat as no name field */
                    276:                ana->fields &= ~ISO_SUSP_ALTNAME;
                    277:                ana->outbuf -= *ana->outlen - wlen;
                    278:                *ana->outlen = 0;
                    279:                return 0;
                    280:        }
1.2.2.4   skrll     281:
1.1       jdolecek  282:        memcpy(ana->outbuf, inbuf, wlen);
                    283:        ana->outbuf += wlen;
1.2.2.4   skrll     284:
1.1       jdolecek  285:        if (!cont) {
                    286:                ana->fields &= ~ISO_SUSP_ALTNAME;
                    287:                return ISO_SUSP_ALTNAME;
                    288:        }
                    289:        return 0;
                    290: }
                    291:
                    292: static void
                    293: cd9660_rrip_defname(v, ana)
                    294:        void *v;
                    295:        ISO_RRIP_ANALYZE *ana;
                    296: {
                    297:        struct iso_directory_record *isodir = v;
                    298:
                    299:        isofntrans(isodir->name, isonum_711(isodir->name_len),
                    300:                   ana->outbuf, ana->outlen,
                    301:                   1, 0, isonum_711(isodir->flags) & 4,
                    302:                   ana->imp->im_joliet_level);
                    303:        switch (ana->outbuf[0]) {
                    304:        default:
                    305:                break;
                    306:        case 0:
                    307:                ana->outbuf[0] = '.';
                    308:                *ana->outlen = 1;
                    309:                break;
                    310:        case 1:
1.2       itojun    311:                strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen);
1.1       jdolecek  312:                *ana->outlen = 2;
                    313:                break;
                    314:        }
                    315: }
                    316:
                    317: /*
                    318:  * Parent or Child Link
                    319:  */
                    320: static int
                    321: cd9660_rrip_pclink(v, ana)
                    322:        void *v;
                    323:        ISO_RRIP_ANALYZE *ana;
                    324: {
                    325:        ISO_RRIP_CLINK  *p = v;
                    326:
                    327:        *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
                    328:        ana->fields &= ~(ISO_SUSP_CLINK | ISO_SUSP_PLINK);
                    329:        return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK;
                    330: }
                    331:
                    332: /*
                    333:  * Relocated directory
                    334:  */
                    335: /*ARGSUSED*/
                    336: static int
                    337: cd9660_rrip_reldir(v, ana)
                    338:        void *v;
                    339:        ISO_RRIP_ANALYZE *ana;
                    340: {
                    341:        /* special hack to make caller aware of RE field */
                    342:        *ana->outlen = 0;
                    343:        ana->fields = 0;
                    344:        return ISO_SUSP_RELDIR | ISO_SUSP_ALTNAME
                    345:            | ISO_SUSP_CLINK | ISO_SUSP_PLINK;
                    346: }
                    347:
                    348: static int
                    349: cd9660_rrip_tstamp(v, ana)
                    350:        void *v;
                    351:        ISO_RRIP_ANALYZE *ana;
                    352: {
                    353:        ISO_RRIP_TSTAMP *p = v;
                    354:        u_char *ptime;
1.2.2.4   skrll     355:
1.1       jdolecek  356:        ptime = p->time;
1.2.2.4   skrll     357:
1.1       jdolecek  358:        /* Check a format of time stamp (7bytes/17bytes) */
                    359:        if (!(*p->flags & ISO_SUSP_TSTAMP_FORM17)) {
                    360:                if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
                    361:                        ptime += 7;
1.2.2.4   skrll     362:
1.1       jdolecek  363:                if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
                    364:                        cd9660_tstamp_conv7(ptime, &ana->inop->inode.iso_mtime);
                    365:                        ptime += 7;
                    366:                } else
                    367:                        memset(&ana->inop->inode.iso_mtime, 0, sizeof(struct timespec));
1.2.2.4   skrll     368:
1.1       jdolecek  369:                if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
                    370:                        cd9660_tstamp_conv7(ptime, &ana->inop->inode.iso_atime);
                    371:                        ptime += 7;
                    372:                } else
                    373:                        ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
1.2.2.4   skrll     374:
1.1       jdolecek  375:                if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
                    376:                        cd9660_tstamp_conv7(ptime, &ana->inop->inode.iso_ctime);
                    377:                else
                    378:                        ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
1.2.2.4   skrll     379:
1.1       jdolecek  380:        } else {
                    381:                if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
                    382:                        ptime += 17;
1.2.2.4   skrll     383:
1.1       jdolecek  384:                if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
                    385:                        cd9660_tstamp_conv17(ptime, &ana->inop->inode.iso_mtime);
                    386:                        ptime += 17;
                    387:                } else
                    388:                        memset(&ana->inop->inode.iso_mtime, 0, sizeof(struct timespec));
1.2.2.4   skrll     389:
1.1       jdolecek  390:                if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
                    391:                        cd9660_tstamp_conv17(ptime, &ana->inop->inode.iso_atime);
                    392:                        ptime += 17;
                    393:                } else
                    394:                        ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
1.2.2.4   skrll     395:
1.1       jdolecek  396:                if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
                    397:                        cd9660_tstamp_conv17(ptime, &ana->inop->inode.iso_ctime);
                    398:                else
                    399:                        ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
1.2.2.4   skrll     400:
1.1       jdolecek  401:        }
                    402:        ana->fields &= ~ISO_SUSP_TSTAMP;
                    403:        return ISO_SUSP_TSTAMP;
                    404: }
                    405:
                    406: static void
                    407: cd9660_rrip_deftstamp(v, ana)
                    408:        void *v;
                    409:        ISO_RRIP_ANALYZE *ana;
                    410: {
                    411:        struct iso_directory_record  *isodir = v;
                    412:
                    413:        cd9660_deftstamp(isodir, ana->inop, NULL);
                    414: }
                    415:
                    416: /*
                    417:  * POSIX device modes
                    418:  */
                    419: static int
                    420: cd9660_rrip_device(v, ana)
                    421:        void *v;
                    422:        ISO_RRIP_ANALYZE *ana;
                    423: {
                    424:        ISO_RRIP_DEVICE *p = v;
                    425:        u_int high, low;
1.2.2.4   skrll     426:
1.1       jdolecek  427:        high = isonum_733(p->dev_t_high);
                    428:        low  = isonum_733(p->dev_t_low);
1.2.2.4   skrll     429:
1.1       jdolecek  430:        if (high == 0)
                    431:                ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
                    432:        else
                    433:                ana->inop->inode.iso_rdev = makedev(high, minor(low));
                    434:        ana->fields &= ~ISO_SUSP_DEVICE;
                    435:        return ISO_SUSP_DEVICE;
                    436: }
                    437:
                    438: /*
                    439:  * Flag indicating
                    440:  */
                    441: static int
                    442: cd9660_rrip_idflag(v, ana)
                    443:        void *v;
                    444:        ISO_RRIP_ANALYZE *ana;
                    445: {
                    446:        ISO_RRIP_IDFLAG *p = v;
                    447:
                    448:        ana->fields &= isonum_711(p->flags) | ~0xff; /* don't touch high bits */
                    449:        /* special handling of RE field */
                    450:        if (ana->fields & ISO_SUSP_RELDIR)
                    451:                return cd9660_rrip_reldir(p, ana);
1.2.2.4   skrll     452:
1.1       jdolecek  453:        return ISO_SUSP_IDFLAG;
                    454: }
                    455:
                    456: /*
                    457:  * Continuation pointer
                    458:  */
                    459: static int
                    460: cd9660_rrip_cont(v, ana)
                    461:        void *v;
                    462:        ISO_RRIP_ANALYZE *ana;
                    463: {
                    464:        ISO_RRIP_CONT *p = v;
                    465:
                    466:        ana->iso_ce_blk = isonum_733(p->location);
                    467:        ana->iso_ce_off = isonum_733(p->offset);
                    468:        ana->iso_ce_len = isonum_733(p->length);
                    469:        return ISO_SUSP_CONT;
                    470: }
                    471:
                    472: /*
                    473:  * System Use end
                    474:  */
                    475: static int
                    476: cd9660_rrip_stop(v, ana)
                    477:        void *v;
                    478:        ISO_RRIP_ANALYZE *ana;
                    479: {
                    480:        return ISO_SUSP_STOP;
                    481: }
                    482:
                    483: /*
                    484:  * Extension reference
                    485:  */
                    486: static int
                    487: cd9660_rrip_extref(v, ana)
                    488:        void *v;
                    489:        ISO_RRIP_ANALYZE *ana;
                    490: {
                    491:        ISO_RRIP_EXTREF *p = v;
                    492:
                    493:        if (isonum_711(p->version) != 1)
                    494:                return 0;
                    495:        if (isonum_711(p->len_id) != 9
                    496:            && isonum_711(p->len_id) != 10)
                    497:                return 0;
                    498:        if (isonum_711(p->len_id) == 9
                    499:            && memcmp((char *)p + 8, "IEEE_1282", 9))
                    500:                return 0;
                    501:        if (isonum_711(p->len_id) == 10
                    502:            && memcmp((char *)p + 8, "IEEE_P1282", 10)
                    503:            && memcmp((char *)p + 8, "RRIP_1991A", 10))
                    504:                return 0;
                    505:        ana->fields &= ~ISO_SUSP_EXTREF;
                    506:        return ISO_SUSP_EXTREF;
                    507: }
                    508:
                    509:
                    510: static int
                    511: cd9660_rrip_loop(isodir, ana, table)
                    512:        struct iso_directory_record *isodir;
                    513:        ISO_RRIP_ANALYZE *ana;
                    514:        const RRIP_TABLE *table;
                    515: {
                    516:        const RRIP_TABLE *ptable;
                    517:        ISO_SUSP_HEADER *phead;
                    518:        ISO_SUSP_HEADER *pend;
                    519:        struct buf *bp = NULL;
                    520:        char *pwhead;
1.2.2.4   skrll     521:        u_int16_t c;
1.1       jdolecek  522:        int result;
1.2.2.4   skrll     523:
1.1       jdolecek  524:        /*
                    525:         * Note: If name length is odd,
                    526:         *       it will be padded by 1 byte after the name
                    527:         */
                    528:        pwhead = isodir->name + isonum_711(isodir->name_len);
                    529:        if (!(isonum_711(isodir->name_len) & 1))
                    530:                pwhead++;
                    531:        isochar(isodir->name, pwhead, ana->imp->im_joliet_level, &c);
1.2.2.4   skrll     532:
1.1       jdolecek  533:        /* If it's not the '.' entry of the root dir obey SP field */
                    534:        if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
                    535:                pwhead += ana->imp->rr_skip;
                    536:        else
                    537:                pwhead += ana->imp->rr_skip0;
1.2.2.4   skrll     538:
1.1       jdolecek  539:        phead = (ISO_SUSP_HEADER *)pwhead;
                    540:        pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
1.2.2.4   skrll     541:
1.1       jdolecek  542:        result = 0;
                    543:        while (1) {
                    544:                ana->iso_ce_len = 0;
                    545:                /*
                    546:                 * Note: "pend" should be more than one SUSP header
1.2.2.5 ! skrll     547:                 */
1.1       jdolecek  548:                while (pend >= phead + 1) {
                    549:                        if (isonum_711(phead->version) == 1) {
                    550:                                for (ptable = table; ptable->func; ptable++) {
                    551:                                        if (*phead->type == *ptable->type
                    552:                                            && phead->type[1] == ptable->type[1]) {
                    553:                                                result |= ptable->func(phead, ana);
                    554:                                                break;
                    555:                                        }
                    556:                                }
                    557:                                if (!ana->fields)
                    558:                                        break;
                    559:                        }
                    560:                        if (result & ISO_SUSP_STOP) {
                    561:                                result &= ~ISO_SUSP_STOP;
                    562:                                break;
                    563:                        }
                    564:                        /* plausibility check */
                    565:                        if (isonum_711(phead->length) < sizeof(*phead))
                    566:                                break;
                    567:                        /*
                    568:                         * move to next SUSP
                    569:                         * Hopefully this works with newer versions, too
                    570:                         */
                    571:                        phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length));
                    572:                }
1.2.2.4   skrll     573:
1.1       jdolecek  574:                if (ana->fields && ana->iso_ce_len) {
                    575:                        if (ana->iso_ce_blk >= ana->imp->volume_space_size
                    576:                            || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
                    577:                            || bread(ana->imp->im_devvp,
                    578:                                     ana->iso_ce_blk << (ana->imp->im_bshift - DEV_BSHIFT),
                    579:                                     ana->imp->logical_block_size, NOCRED, &bp))
                    580:                                /* what to do now? */
                    581:                                break;
                    582:                        phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
                    583:                        pend = (ISO_SUSP_HEADER *)((char *)phead + ana->iso_ce_len);
                    584:                } else
                    585:                        break;
                    586:        }
                    587:        if (bp)
                    588:                brelse(bp);
                    589:        /*
                    590:         * If we don't find the Basic SUSP stuffs, just set default value
                    591:         *   (attribute/time stamp)
                    592:         */
                    593:        for (ptable = table; ptable->func2; ptable++)
                    594:                if (!(ptable->result & result))
                    595:                        ptable->func2(isodir, ana);
1.2.2.4   skrll     596:
1.1       jdolecek  597:        return result;
                    598: }
                    599:
                    600: /*
                    601:  * Get Attributes.
                    602:  */
                    603: static const RRIP_TABLE rrip_table_analyze[] = {
                    604:        { "PX", cd9660_rrip_attr,       cd9660_rrip_defattr,    ISO_SUSP_ATTR },
                    605:        { "TF", cd9660_rrip_tstamp,     cd9660_rrip_deftstamp,  ISO_SUSP_TSTAMP },
                    606:        { "PN", cd9660_rrip_device,     0,                      ISO_SUSP_DEVICE },
                    607:        { "RR", cd9660_rrip_idflag,     0,                      ISO_SUSP_IDFLAG },
                    608:        { "CE", cd9660_rrip_cont,       0,                      ISO_SUSP_CONT },
                    609:        { "ST", cd9660_rrip_stop,       0,                      ISO_SUSP_STOP },
                    610:        { "",   0,                      0,                      0 }
                    611: };
                    612:
                    613: int
                    614: cd9660_rrip_analyze(isodir, inop, imp)
                    615:        struct iso_directory_record *isodir;
                    616:        struct iso_node *inop;
                    617:        struct iso_mnt *imp;
                    618: {
                    619:        ISO_RRIP_ANALYZE analyze;
1.2.2.4   skrll     620:
1.1       jdolecek  621:        analyze.inop = inop;
                    622:        analyze.imp = imp;
                    623:        analyze.fields = ISO_SUSP_ATTR | ISO_SUSP_TSTAMP | ISO_SUSP_DEVICE;
1.2.2.4   skrll     624:
1.1       jdolecek  625:        return cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze);
                    626: }
                    627:
1.2.2.5 ! skrll     628: /*
1.1       jdolecek  629:  * Get Alternate Name.
                    630:  */
                    631: static const RRIP_TABLE rrip_table_getname[] = {
                    632:        { "NM", cd9660_rrip_altname,    cd9660_rrip_defname,    ISO_SUSP_ALTNAME },
                    633:        { "CL", cd9660_rrip_pclink,     0,                      ISO_SUSP_CLINK|ISO_SUSP_PLINK },
                    634:        { "PL", cd9660_rrip_pclink,     0,                      ISO_SUSP_CLINK|ISO_SUSP_PLINK },
                    635:        { "RE", cd9660_rrip_reldir,     0,                      ISO_SUSP_RELDIR },
                    636:        { "RR", cd9660_rrip_idflag,     0,                      ISO_SUSP_IDFLAG },
                    637:        { "CE", cd9660_rrip_cont,       0,                      ISO_SUSP_CONT },
                    638:        { "ST", cd9660_rrip_stop,       0,                      ISO_SUSP_STOP },
                    639:        { "",   0,                      0,                      0 }
                    640: };
                    641:
                    642: int
                    643: cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp)
                    644:        struct iso_directory_record *isodir;
                    645:        char *outbuf;
                    646:        u_short *outlen;
                    647:        ino_t *inump;
                    648:        struct iso_mnt *imp;
                    649: {
                    650:        ISO_RRIP_ANALYZE analyze;
                    651:        const RRIP_TABLE *tab;
1.2.2.4   skrll     652:        u_int16_t c;
                    653:
1.1       jdolecek  654:        analyze.outbuf = outbuf;
                    655:        analyze.outlen = outlen;
                    656:        analyze.maxlen = NAME_MAX;
                    657:        analyze.inump = inump;
                    658:        analyze.imp = imp;
                    659:        analyze.fields = ISO_SUSP_ALTNAME | ISO_SUSP_RELDIR | ISO_SUSP_CLINK | ISO_SUSP_PLINK;
                    660:        *outlen = 0;
1.2.2.4   skrll     661:
1.1       jdolecek  662:        isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
                    663:                imp->im_joliet_level, &c);
                    664:        tab = rrip_table_getname;
                    665:        if (c == 0 || c == 1) {
                    666:                cd9660_rrip_defname(isodir, &analyze);
1.2.2.4   skrll     667:
1.1       jdolecek  668:                analyze.fields &= ~ISO_SUSP_ALTNAME;
                    669:                tab++;
                    670:        }
1.2.2.4   skrll     671:
1.1       jdolecek  672:        return cd9660_rrip_loop(isodir, &analyze, tab);
                    673: }
                    674:
1.2.2.5 ! skrll     675: /*
1.1       jdolecek  676:  * Get Symbolic Link.
                    677:  */
                    678: static const RRIP_TABLE rrip_table_getsymname[] = {
                    679:        { "SL", cd9660_rrip_slink,      0,                      ISO_SUSP_SLINK },
                    680:        { "RR", cd9660_rrip_idflag,     0,                      ISO_SUSP_IDFLAG },
                    681:        { "CE", cd9660_rrip_cont,       0,                      ISO_SUSP_CONT },
                    682:        { "ST", cd9660_rrip_stop,       0,                      ISO_SUSP_STOP },
                    683:        { "",   0,                      0,                      0 }
                    684: };
                    685:
                    686: int
                    687: cd9660_rrip_getsymname(isodir, outbuf, outlen, imp)
                    688:        struct iso_directory_record *isodir;
                    689:        char *outbuf;
                    690:        u_short *outlen;
                    691:        struct iso_mnt *imp;
                    692: {
                    693:        ISO_RRIP_ANALYZE analyze;
1.2.2.4   skrll     694:
1.1       jdolecek  695:        analyze.outbuf = outbuf;
                    696:        analyze.outlen = outlen;
                    697:        *outlen = 0;
                    698:        analyze.maxlen = MAXPATHLEN;
                    699:        analyze.cont = 1;               /* don't start with a slash */
                    700:        analyze.imp = imp;
                    701:        analyze.fields = ISO_SUSP_SLINK;
1.2.2.4   skrll     702:
1.1       jdolecek  703:        return cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) & ISO_SUSP_SLINK;
                    704: }
                    705:
                    706: static const RRIP_TABLE rrip_table_extref[] = {
                    707:        { "ER", cd9660_rrip_extref,     0,      ISO_SUSP_EXTREF },
                    708:        { "CE", cd9660_rrip_cont,       0,      ISO_SUSP_CONT },
                    709:        { "ST", cd9660_rrip_stop,       0,      ISO_SUSP_STOP },
                    710:        { "",   0,                      0,      0 }
                    711: };
                    712:
                    713: /*
                    714:  * Check for Rock Ridge Extension and return offset of its fields.
                    715:  * Note: We insist on the ER field.
                    716:  */
                    717: int
                    718: cd9660_rrip_offset(isodir, imp)
                    719:        struct iso_directory_record *isodir;
                    720:        struct iso_mnt *imp;
                    721: {
                    722:        ISO_RRIP_OFFSET *p;
                    723:        ISO_RRIP_ANALYZE analyze;
1.2.2.4   skrll     724:
1.1       jdolecek  725:        imp->rr_skip0 = 0;
                    726:        p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
                    727:        if (memcmp(p, "SP\7\1\276\357", 6)) {
                    728:                /* Maybe, it's a CDROM XA disc? */
                    729:                imp->rr_skip0 = 15;
                    730:                p = (ISO_RRIP_OFFSET *)((char *)p + 15);
                    731:                if (memcmp(p, "SP\7\1\276\357", 6))
                    732:                        return -1;
                    733:        }
1.2.2.4   skrll     734:
1.1       jdolecek  735:        analyze.imp = imp;
                    736:        analyze.fields = ISO_SUSP_EXTREF;
                    737:        if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) & ISO_SUSP_EXTREF))
                    738:                return -1;
1.2.2.4   skrll     739:
1.1       jdolecek  740:        return isonum_711(p->skip);
                    741: }

CVSweb <webmaster@jp.NetBSD.org>