[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.9.10.1

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

CVSweb <webmaster@jp.NetBSD.org>