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

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*     $NetBSD: cd9660_vfsops.c,v 1.18 1995/03/09 12:05:36 mycroft Exp $       */
                     23: 
                     24: /*-
                     25:  * Copyright (c) 1994
                     26:  *     The Regents of the University of California.  All rights reserved.
                     27:  *
                     28:  * This code is derived from software contributed to Berkeley
                     29:  * by Pace Willisson ([email protected]).  The Rock Ridge Extension
                     30:  * Support code is derived from software contributed to Berkeley
                     31:  * by Atsushi Murai ([email protected]).
                     32:  *
                     33:  * Redistribution and use in source and binary forms, with or without
                     34:  * modification, are permitted provided that the following conditions
                     35:  * are met:
                     36:  * 1. Redistributions of source code must retain the above copyright
                     37:  *    notice, this list of conditions and the following disclaimer.
                     38:  * 2. Redistributions in binary form must reproduce the above copyright
                     39:  *    notice, this list of conditions and the following disclaimer in the
                     40:  *    documentation and/or other materials provided with the distribution.
                     41:  * 3. All advertising materials mentioning features or use of this software
                     42:  *    must display the following acknowledgement:
                     43:  *     This product includes software developed by the University of
                     44:  *     California, Berkeley and its contributors.
                     45:  * 4. Neither the name of the University nor the names of its contributors
                     46:  *    may be used to endorse or promote products derived from this software
                     47:  *    without specific prior written permission.
                     48:  *
                     49:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     50:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     51:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     52:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     53:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     54:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     55:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     56:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     57:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     58:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     59:  * SUCH DAMAGE.
                     60:  *
                     61:  *     @(#)cd9660_vfsops.c     8.9 (Berkeley) 12/5/94
                     62: 
                     63: 
                     64: 
                     65:  * HISTORY
                     66:  * 18-Nov-98   Add support for volfs - djb
                     67:  * 22-Jan-98   radar 1669467 - ISO 9660 CD support - jwc
                     68: 
                     69:  */
                     70: 
                     71: #include <sys/param.h>
                     72: #include <sys/systm.h>
                     73: #include <sys/namei.h>
                     74: #include <sys/proc.h>
                     75: #include <sys/kernel.h>
                     76: #include <sys/vnode.h>
                     77: #include <miscfs/specfs/specdev.h>
                     78: #include <sys/mount.h>
                     79: #include <sys/buf.h>
                     80: #include <sys/file.h>
                     81: #include <sys/disklabel.h>
                     82: #include <sys/ioctl.h>
                     83: #include <sys/errno.h>
                     84: #include <sys/malloc.h>
                     85: #include <sys/stat.h>
                     86: 
                     87: #include <isofs/cd9660/iso.h>
                     88: #include <isofs/cd9660/iso_rrip.h>
                     89: #include <isofs/cd9660/cd9660_node.h>
                     90: #include <isofs/cd9660/cd9660_mount.h>
                     91: 
                     92: extern int enodev ();
                     93: 
                     94: struct vfsops cd9660_vfsops = {
                     95:        cd9660_mount,
                     96:        cd9660_start,
                     97:        cd9660_unmount,
                     98:        cd9660_root,
                     99:        cd9660_quotactl,
                    100:        cd9660_statfs,
                    101:        cd9660_sync,
                    102:        cd9660_vget,
                    103:        cd9660_fhtovp,
                    104:        cd9660_vptofh,
                    105:        cd9660_init,
                    106:        cd9660_sysctl
                    107: };
                    108: 
                    109: /*
                    110:  * Called by vfs_mountroot when iso is going to be mounted as root.
                    111:  *
                    112:  * Name is updated by mount(8) after booting.
                    113:  */
                    114: #define ROOTNAME       "root_device"
                    115: 
                    116: static int iso_mountfs __P((struct vnode *devvp, struct mount *mp,
                    117:                struct proc *p, struct iso_args *argp));
                    118: #if 1 // radar 1669467
                    119: static void    DRGetTypeCreatorAndFlags(       struct iso_mnt * theMountPointPtr,
                    120:                                                                                        struct iso_directory_record * theDirRecPtr, 
                    121:                                                                                        u_int32_t * theTypePtr, 
                    122:                                                                                        u_int32_t * theCreatorPtr, 
                    123:                                                                                        u_int16_t * theFlagsPtr ); // radar 1669467
                    124: 
                    125: int                            cd9660_vget_internal(   struct mount *mp, 
                    126:                                                                                ino_t ino, 
                    127:                                                                                struct vnode **vpp, 
                    128:                                                                                int relocated, 
                    129:                                                                                struct iso_directory_record *isodir, 
                    130:                                                                                struct proc *p );
                    131: #endif // radar 1669467
                    132: 
                    133: 
                    134: int
                    135: cd9660_mountroot()
                    136: {
                    137:        register struct mount *mp;
                    138:        extern struct vnode *rootvp;
                    139:        struct proc *p = current_proc();        /* XXX */
                    140:        struct iso_mnt *imp;
                    141:        //register struct fs *fs;   radar 1669467 - get rid of warning
                    142:        size_t size;
                    143:        int error;
                    144:        struct iso_args args;
                    145:        
                    146:        
                    147:        /*
                    148:         * Get vnodes for swapdev and rootdev.
                    149:         */
                    150: #if 0
                    151:        if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
                    152:                panic("cd9660_mountroot: can't setup bdevvp's");
                    153: #else
                    154:        if ( bdevvp(rootdev, &rootvp))
                    155:                panic("cd9660_mountroot: can't setup bdevvp's");
                    156: 
                    157: #endif
                    158: 
                    159:        MALLOC_ZONE(mp, struct mount *,
                    160:                        sizeof(struct mount), M_MOUNT, M_WAITOK);
                    161:        bzero((char *)mp, (u_long)sizeof(struct mount));
                    162:        mp->mnt_op = &cd9660_vfsops;
                    163:        mp->mnt_flag = MNT_RDONLY;
                    164:        LIST_INIT(&mp->mnt_vnodelist);
                    165:        args.flags = ISOFSMNT_ROOT;
                    166:        if ((error = iso_mountfs(rootvp, mp, p, &args))) {
                    167:                FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
                    168:                return (error);
                    169:        }
                    170:        simple_lock(&mountlist_slock);
                    171:     #if 0
                    172:        if (error = VFS_LOCK(mp)) {
                    173:                (void)cd9660_unmount(mp, 0, p);
                    174:                FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
                    175:                return (error);
                    176:        }
                    177:     #endif
                    178:        CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
                    179:        simple_unlock(&mountlist_slock);
                    180:        mp->mnt_vnodecovered = NULLVP;
                    181:        imp = VFSTOISOFS(mp);
                    182:        (void) copystr("/", mp->mnt_stat.f_mntonname, MNAMELEN - 1,
                    183:            &size);
                    184:        bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
                    185:        (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                    186:            &size);
                    187:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                    188:        (void)cd9660_statfs(mp, &mp->mnt_stat, p);
                    189: //     VFS_UNLOCK(mp);
                    190:        return (0);
                    191: }
                    192: 
                    193: /*
                    194:  * VFS Operations.
                    195:  *
                    196:  * mount system call
                    197:  */
                    198: int
                    199: cd9660_mount(mp, path, data, ndp, p)
                    200:        register struct mount *mp;
                    201:        char *path;
                    202:        caddr_t data;
                    203:        struct nameidata *ndp;
                    204:        struct proc *p;
                    205: {
                    206:        struct vnode *devvp;
                    207:        struct iso_args args;
                    208:        size_t size;
                    209:        int error;
                    210:        struct iso_mnt *imp;
                    211:        
                    212:        if ( (error = copyin(data, (caddr_t)&args, sizeof (struct iso_args))) ) // radar 1669467 - fix compiler warning
                    213:                return (error);
                    214:        
                    215:        if ((mp->mnt_flag & MNT_RDONLY) == 0)
                    216:                return (EROFS);
                    217:        
                    218:        imp = VFSTOISOFS(mp); // radar 1669467 - imp could be used with out getting set up.
                    219: 
                    220:        /*
                    221:         * If updating, check whether changing from read-only to
                    222:         * read/write; if there is no device name, that's all we do.
                    223:         */
                    224:        if (mp->mnt_flag & MNT_UPDATE) {
                    225:                //imp = VFSTOISOFS(mp);  radar 1669467 - we do this above now
                    226:                if (args.fspec == 0)
                    227:                        return (vfs_export(mp, &imp->im_export, &args.export));
                    228:        }
                    229:        /*
                    230:         * Not an update, or updating the name: look up the name
                    231:         * and verify that it refers to a sensible block device.
                    232:         */
                    233:        NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
                    234:        if ( (error = namei(ndp)) )
                    235:                return (error);
                    236:        devvp = ndp->ni_vp;
                    237: 
                    238:        if (devvp->v_type != VBLK) {
                    239:                vrele(devvp);
                    240:                return ENOTBLK;
                    241:        }
                    242:        if (major(devvp->v_rdev) >= nblkdev) {
                    243:                vrele(devvp);
                    244:                return ENXIO;
                    245:        }
                    246:        if ((mp->mnt_flag & MNT_UPDATE) == 0)
                    247:                error = iso_mountfs(devvp, mp, p, &args);
                    248:        else {
                    249:                if (devvp != imp->im_devvp)
                    250:                        error = EINVAL; /* needs translation */
                    251:                else
                    252:                        vrele(devvp);
                    253:        }
                    254:        if (error) {
                    255:                vrele(devvp);
                    256:                return error;
                    257:        }
                    258: 
                    259:        /* Set the mount flag to indicate that we support volfs  */
                    260:     mp->mnt_flag |= MNT_DOVOLFS;
                    261: 
                    262:        //imp = VFSTOISOFS(mp); radar 1669467 - we do this above now
                    263:        (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
                    264:        bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
                    265:        (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                    266:            &size);
                    267:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                    268:        return 0;
                    269: }
                    270: 
                    271: /*
                    272:  * Common code for mount and mountroot
                    273:  */
                    274: static int
                    275: iso_mountfs(devvp, mp, p, argp)
                    276:        register struct vnode *devvp;
                    277:        struct mount *mp;
                    278:        struct proc *p;
                    279:        struct iso_args *argp;
                    280: {
                    281:        register struct iso_mnt *isomp = (struct iso_mnt *)0;
                    282:        struct buf *bp = NULL;
                    283:        dev_t dev = devvp->v_rdev;
                    284:        int error = EINVAL;
                    285:        //int i, size;
                    286:        int needclose = 0;
                    287:        int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
                    288:        extern struct vnode *rootvp;
                    289:        int iso_bsize;
                    290:        int iso_blknum;
                    291:        struct iso_volume_descriptor *vdp;
                    292:        struct iso_primary_descriptor *pri;
                    293:        struct iso_directory_record *rootp;
                    294:        int logical_block_size;
                    295: #ifdef 0
                    296:        int devBlockSize=0;
                    297: #endif /* NeXT */
                    298:        
                    299:        if (!ronly)
                    300:                return EROFS;
                    301:        
                    302:        /*
                    303:         * Disallow multiple mounts of the same device.
                    304:         * Disallow mounting of a device that is currently in use
                    305:         * (except for root, which might share swap device for miniroot).
                    306:         * Flush out any old buffers remaining from a previous use.
                    307:         */
                    308:        if ( (error = vfs_mountedon(devvp)) )
                    309:                return error;
                    310:        if ( vcount(devvp) > 1 && devvp != rootvp )
                    311:                return EBUSY;
                    312:        if ( (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) )
                    313:                return (error);
                    314: 
                    315:        if ( (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) )
                    316:                return error;
                    317:        needclose = 1;
                    318:        
                    319:        /* This is the "logical sector size".  The standard says this
                    320:         * should be 2048 or the physical sector size on the device,
                    321:         * whichever is greater.  For now, we'll just use a constant.
                    322:         */
                    323:        iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
                    324:        
                    325:        for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
                    326: 
                    327: #if 1 // radar 1669467
                    328:                if ( (error = bread(devvp, iso_blknum, iso_bsize, NOCRED, &bp)) )
                    329:                {
                    330:                        goto out;
                    331:                };
                    332: #else 
                    333:                /* Old code that used incorrect block - btodb is wrong - we should read the iso_blknum */
                    334:                if (error = bread(devvp, iso_blknum * btodb(iso_bsize),
                    335:                                  iso_bsize, NOCRED, &bp)) {
                    336:             #ifdef DEBUG
                    337:                printf("cd9660_vfsops.c: iso_mountfs: bread() returned %d.\n", error);
                    338:             #endif
                    339:                        goto out;
                    340:                };
                    341: #endif // radar 1669467
                    342: 
                    343:                vdp = (struct iso_volume_descriptor *)bp->b_data;
                    344:                if (bcmp (vdp->volume_desc_id, ISO_STANDARD_ID, sizeof vdp->volume_desc_id) != 0) {
                    345:                         #ifdef DEBUG
                    346:                        printf("cd9660_vfsops.c: iso_mountfs: Invalid ID in volume desciptor.\n");
                    347:                         #endif
                    348:                        error = EINVAL;
                    349:                        goto out;
                    350:                }
                    351:                
                    352:                if (isonum_711 (vdp->type) == ISO_VD_END) {
                    353:                         #ifdef DEBUG
                    354:                        printf("cd9660_vfsops.c: iso_mountfs: isonum_711() != ISO_VD_END.\n");
                    355:                         #endif
                    356:                        error = EINVAL;
                    357:                        goto out;
                    358:                }
                    359:                
                    360:                if (isonum_711 (vdp->type) == ISO_VD_PRIMARY)
                    361:                        break;
                    362:                brelse(bp);
                    363:        }
                    364:        
                    365:        if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) {
                    366:                 #ifdef DEBUG
                    367:                printf("cd9660_vfsops.c: iso_mountfs: isnum_711() != ISO_VD_PRIMARY.\n");
                    368:                #endif
                    369:                error = EINVAL;
                    370:                goto out;
                    371:        }
                    372:        
                    373:        pri = (struct iso_primary_descriptor *)vdp;
                    374:        
                    375:        logical_block_size = isonum_723 (pri->logical_block_size);
                    376:        
                    377:        if (logical_block_size < DEV_BSIZE || logical_block_size > MAXBSIZE
                    378:            || (logical_block_size & (logical_block_size - 1)) != 0) {
                    379:                error = EINVAL;
                    380:                goto out;
                    381:        }
                    382:        
                    383:        rootp = (struct iso_directory_record *)pri->root_directory_record;
                    384:        
                    385: //     isomp = malloc(sizeof *isomp, M_ISOFSMNT, M_WAITOK);
                    386:        MALLOC(isomp, struct iso_mnt *, sizeof *isomp, M_ISOFSMNT, M_WAITOK);
                    387:        bzero((caddr_t)isomp, sizeof *isomp);
                    388:        isomp->logical_block_size = logical_block_size;
                    389:        isomp->volume_space_size = isonum_733 (pri->volume_space_size);
                    390:        bcopy (rootp, isomp->root, sizeof isomp->root);
                    391:        isomp->root_extent = isonum_733 (rootp->extent);
                    392:        isomp->root_size = isonum_733 (rootp->size);
                    393: 
                    394:        /*
                    395:         * getattrlist wants the volume name, create date and modify date
                    396:         */
                    397: 
                    398:     /* Remove any trailing white space */
                    399:     if ( strlen(pri->volume_id) ) {
                    400:        char            *myPtr;
                    401:        
                    402:                myPtr = pri->volume_id + strlen( pri->volume_id ) - 1;
                    403:                while ( *myPtr == ' ' && myPtr >= pri->volume_id ) {
                    404:                *myPtr = 0x00;
                    405:                myPtr--;
                    406:                }
                    407:     }
                    408:        /* YYY need to use secondary volume descriptor name for kanji disks */
                    409:        bcopy(pri->volume_id, isomp->volume_id, sizeof(isomp->volume_id));
                    410:        cd9660_tstamp_conv17(pri->creation_date, &isomp->creation_date);
                    411:        cd9660_tstamp_conv17(pri->modification_date, &isomp->modification_date);
                    412: 
                    413: #if 0
                    414:        kprintf("\n************************************************************************* \n");
                    415:        kprintf( "iso_mountfs - pri->primary_desc_id is \"%c%c%c%c%c\" \n",
                    416:                        pri->primary_desc_id[0], pri->primary_desc_id[1], pri->primary_desc_id[2], 
                    417:                        pri->primary_desc_id[3], pri->primary_desc_id[4] );
                    418:        kprintf( "iso_mountfs - pri->CDXASignature is \"%c%c%c%c%c%c%c%c\" \n",
                    419:                        pri->CDXASignature[0], pri->CDXASignature[1], pri->CDXASignature[2], 
                    420:                        pri->CDXASignature[3], pri->CDXASignature[4], pri->CDXASignature[5],
                    421:                        pri->CDXASignature[6], pri->CDXASignature[7] );
                    422: #endif
                    423: 
                    424: #if 1 // radar 1669467
                    425:        /* See if this is a CD-XA volume */
                    426:        if ( bcmp( pri->CDXASignature, ISO_XA_ID, sizeof(pri->CDXASignature) ) == 0 ) 
                    427:                isomp->im_flags2 |= IMF2_IS_CDXA;
                    428: #endif // radar 1669467
                    429:                        
                    430:        isomp->im_bmask = logical_block_size - 1;
                    431:        isomp->im_bshift = 0;
                    432:        while ((1 << isomp->im_bshift) < isomp->logical_block_size)
                    433:                isomp->im_bshift++;
                    434: 
                    435:        bp->b_flags |= B_AGE;
                    436:        brelse(bp);
                    437:        bp = NULL;
                    438: 
                    439:        mp->mnt_data = (qaddr_t)isomp;
                    440:        mp->mnt_stat.f_fsid.val[0] = (long)dev;
                    441:        mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
                    442:        mp->mnt_maxsymlinklen = 0;
                    443:        mp->mnt_flag |= MNT_LOCAL;
                    444:        isomp->im_mountp = mp;
                    445:        isomp->im_dev = dev;
                    446:        isomp->im_devvp = devvp;        
                    447:        devvp->v_specflags |= SI_MOUNTEDON;
                    448:        
                    449:        /* Check the Rock Ridge Extention support */
                    450:        if (!(argp->flags & ISOFSMNT_NORRIP)) {
                    451:                if ( (error = bread(isomp->im_devvp,
                    452: #if 1 // radar 1669467
                    453:                                  (isomp->root_extent + isonum_711(rootp->ext_attr_length)),
                    454: #else
                    455:                                  (isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
                    456:                                  (isomp->im_bshift - DEV_BSHIFT),
                    457: #endif // radar 1669467
                    458:                                  isomp->logical_block_size, NOCRED, &bp)) )
                    459:                    goto out;
                    460:                
                    461:                rootp = (struct iso_directory_record *)bp->b_data;
                    462:                
                    463:                if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
                    464:                    argp->flags  |= ISOFSMNT_NORRIP;
                    465:                } else {
                    466:                    argp->flags  &= ~ISOFSMNT_GENS;
                    467:                }
                    468:                
                    469:                /*
                    470:                 * The contents are valid,
                    471:                 * but they will get reread as part of another vnode, so...
                    472:                 */
                    473:                bp->b_flags |= B_AGE;
                    474:                brelse(bp);
                    475:                bp = NULL;
                    476:        }
                    477:        isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT);
                    478:        switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) {
                    479:        default:
                    480:            isomp->iso_ftype = ISO_FTYPE_DEFAULT;
                    481:            break;
                    482:        case ISOFSMNT_GENS|ISOFSMNT_NORRIP:
                    483:            isomp->iso_ftype = ISO_FTYPE_9660;
                    484:            break;
                    485:        case 0:
                    486:            isomp->iso_ftype = ISO_FTYPE_RRIP;
                    487:            break;
                    488:        }
                    489:        
                    490:        return 0;
                    491: out:
                    492:        if (bp)
                    493:                brelse(bp);
                    494:        if (needclose)
                    495:                (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
                    496:        if (isomp) {
                    497:                FREE((caddr_t)isomp, M_ISOFSMNT);
                    498:                mp->mnt_data = (qaddr_t)0;
                    499:        }
                    500: 
                    501:        /* Clear the mounted on bit in the devvp If it   */
                    502:        /* not set, this is a nop and there is no way to */
                    503:        /* get here with it set unless we did it.  If you*/
                    504:        /* are making code changes which makes the above */
                    505:        /* assumption not true, change this code.        */
                    506: 
                    507:        devvp->v_specflags &= ~SI_MOUNTEDON;
                    508: 
                    509:        return error;
                    510: }
                    511: 
                    512: /*
                    513:  * Make a filesystem operational.
                    514:  * Nothing to do at the moment.
                    515:  */
                    516: /* ARGSUSED */
                    517: int
                    518: cd9660_start(mp, flags, p)
                    519:        struct mount *mp;
                    520:        int flags;
                    521:        struct proc *p;
                    522: {
                    523:        return 0;
                    524: }
                    525: 
                    526: 
                    527: /*
                    528:  * unmount system call
                    529:  */
                    530: int
                    531: cd9660_unmount(mp, mntflags, p)
                    532:        struct mount *mp;
                    533:        int mntflags;
                    534:        struct proc *p;
                    535: {
                    536:        register struct iso_mnt *isomp;
                    537:        int error, flags = 0;
                    538:        
                    539:        if ( (mntflags & MNT_FORCE) )
                    540:                flags |= FORCECLOSE;
                    541: #if 0
                    542:        mntflushbuf(mp, 0);
                    543:        if (mntinvalbuf(mp))
                    544:                return EBUSY;
                    545: #endif
                    546:        if ( (error = vflush(mp, NULLVP, flags)) )
                    547:                return (error);
                    548: 
                    549:        isomp = VFSTOISOFS(mp);
                    550: 
                    551: #ifdef ISODEVMAP
                    552:        if (isomp->iso_ftype == ISO_FTYPE_RRIP)
                    553:                iso_dunmap(isomp->im_dev);
                    554: #endif
                    555:        
                    556:        isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON;
                    557:        error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, p);
                    558:        vrele(isomp->im_devvp);
                    559:        FREE((caddr_t)isomp, M_ISOFSMNT);
                    560:        mp->mnt_data = (qaddr_t)0;
                    561:        mp->mnt_flag &= ~MNT_LOCAL;
                    562: 
                    563:        return (error);
                    564: }
                    565: 
                    566: /*
                    567:  * Return root of a filesystem
                    568:  */
                    569: int
                    570: cd9660_root(mp, vpp)
                    571:        struct mount *mp;
                    572:        struct vnode **vpp;
                    573: {
                    574:        struct iso_mnt *imp = VFSTOISOFS(mp);
                    575:        struct iso_directory_record *dp =
                    576:            (struct iso_directory_record *)imp->root;
                    577:        ino_t ino = isodirino(dp, imp);
                    578:        
                    579:        /*
                    580:         * With RRIP we must use the `.' entry of the root directory.
                    581:         * Simply tell vget, that it's a relocated directory.
                    582:         */
                    583:        return (cd9660_vget_internal(mp, ino, vpp,
                    584:            imp->iso_ftype == ISO_FTYPE_RRIP, dp, current_proc()));
                    585: }
                    586: 
                    587: /*
                    588:  * Do operations associated with quotas, not supported
                    589:  */
                    590: /* ARGSUSED */
                    591: int
                    592: cd9660_quotactl(mp, cmd, uid, arg, p)
                    593:        struct mount *mp;
                    594:        int cmd;
                    595:        uid_t uid;
                    596:        caddr_t arg;
                    597:        struct proc *p;
                    598: {
                    599: 
                    600:        return (EOPNOTSUPP);
                    601: }
                    602: 
                    603: /*
                    604:  * Get file system statistics.
                    605:  */
                    606: int
                    607: cd9660_statfs(mp, sbp, p)
                    608:        struct mount *mp;
                    609:        register struct statfs *sbp;
                    610:        struct proc *p;
                    611: {
                    612:        register struct iso_mnt *isomp;
                    613:        
                    614:        isomp = VFSTOISOFS(mp);
                    615: 
                    616: #ifdef COMPAT_09
                    617:        sbp->f_type = 5;
                    618: #else
                    619:        sbp->f_type = 0;
                    620: #endif
                    621:        sbp->f_bsize = isomp->logical_block_size;
                    622:        sbp->f_iosize = sbp->f_bsize;   /* XXX */
                    623:        sbp->f_blocks = isomp->volume_space_size;
                    624:        sbp->f_bfree = 0; /* total free blocks */
                    625:        sbp->f_bavail = 0; /* blocks free for non superuser */
                    626:        sbp->f_files =  0; /* total files */
                    627:        sbp->f_ffree = 0; /* free file nodes */
                    628:        if (sbp != &mp->mnt_stat) {
                    629:                bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
                    630:                bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
                    631:        }
                    632: 
                    633: #if 1 // radar 1669467
                    634:        strncpy( sbp->f_fstypename, mp->mnt_vfc->vfc_name, (MFSNAMELEN - 1) );
                    635:        sbp->f_fstypename[(MFSNAMELEN - 1)] = '\0';
                    636: #else
                    637:        strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
                    638:        sbp->f_fstypename[MFSNAMELEN] = '\0';
                    639: #endif // radar 1669467
                    640: 
                    641:        /* Use the first spare for flags: */
                    642:        sbp->f_spare[0] = isomp->im_flags;
                    643: 
                    644:        return 0;
                    645: }
                    646: 
                    647: /* ARGSUSED */
                    648: int
                    649: cd9660_sync(mp, waitfor, cred, p)
                    650:        struct mount *mp;
                    651:        int waitfor;
                    652:        struct ucred *cred;
                    653:        struct proc *p;
                    654: {
                    655: 
                    656:        return (0);
                    657: }
                    658: 
                    659: /*
                    660:  * File handle to vnode
                    661:  *
                    662:  * Have to be really careful about stale file handles:
                    663:  * - check that the inode number is in range
                    664:  * - call iget() to get the locked inode
                    665:  * - check for an unallocated inode (i_mode == 0)
                    666:  * - check that the generation number matches
                    667:  */
                    668: 
                    669: struct ifid {
                    670:        ushort  ifid_len;
                    671:        ushort  ifid_pad;
                    672:        int     ifid_ino;
                    673:        long    ifid_start;
                    674: };
                    675: 
                    676: /* ARGSUSED */
                    677: int
                    678: cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
                    679:        register struct mount *mp;
                    680:        struct fid *fhp;
                    681:        struct mbuf *nam;
                    682:        struct vnode **vpp;
                    683:        int *exflagsp;
                    684:        struct ucred **credanonp;
                    685: {
                    686:        struct ifid *ifhp = (struct ifid *)fhp;
                    687:        register struct iso_node *ip;
                    688:        register struct netcred *np;
                    689:        register struct iso_mnt *imp = VFSTOISOFS(mp);
                    690:        struct vnode *nvp;
                    691:        int error;
                    692:        
                    693: #ifdef ISOFS_DBG
                    694:        printf("fhtovp: ino %d, start %ld\n",
                    695:               ifhp->ifid_ino, ifhp->ifid_start);
                    696: #endif
                    697:        
                    698:        /*
                    699:         * Get the export permission structure for this <mp, client> tuple.
                    700:         */
                    701:        np = vfs_export_lookup(mp, &imp->im_export, nam);
                    702:        if (np == NULL)
                    703:                return (EACCES);
                    704: 
                    705:        if ( (error = VFS_VGET(mp, &ifhp->ifid_ino, &nvp)) ) {
                    706:                *vpp = NULLVP;
                    707:                return (error);
                    708:        }
                    709:        ip = VTOI(nvp);
                    710:        if (ip->inode.iso_mode == 0) {
                    711:                vput(nvp);
                    712:                *vpp = NULLVP;
                    713:                return (ESTALE);
                    714:        }
                    715:        *vpp = nvp;
                    716:        *exflagsp = np->netc_exflags;
                    717:        *credanonp = &np->netc_anon;
                    718:        return (0);
                    719: }
                    720: 
                    721: int
                    722: cd9660_vget(mp, ino, vpp)
                    723:        struct mount *mp;
                    724:        void *ino;
                    725:        struct vnode **vpp;
                    726: {
                    727:        /*
                    728:         * XXXX
                    729:         * It would be nice if we didn't always set the `relocated' flag
                    730:         * and force the extra read, but I don't want to think about fixing
                    731:         * that right now.
                    732:         */
                    733: 
                    734: #if 1 // radar 1669467 - fix compiler warning
                    735: 
                    736:        return ( cd9660_vget_internal( mp, *(ino_t*)ino, vpp, 0, 
                    737:                                                                   (struct iso_directory_record *) 0,
                    738:                                                                   current_proc()) );
                    739: 
                    740: #else // radar 1669467
                    741: 
                    742:        return (cd9660_vget_internal(mp, *(ino_t*)ino, vpp,
                    743: #if 0
                    744:            VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
                    745: #else
                    746:            0,
                    747: #endif
                    748:            (struct iso_directory_entry *)0));
                    749: #endif // radar 1669467
                    750: }
                    751: 
                    752: int
                    753: cd9660_vget_internal(mp, ino, vpp, relocated, isodir, p)
                    754:        struct mount *mp;
                    755:        ino_t ino;
                    756:        struct vnode **vpp;
                    757:        int relocated;
                    758:        struct iso_directory_record *isodir;
                    759:     struct proc *p;
                    760: {
                    761:        register struct iso_mnt *imp;
                    762:        struct iso_node *ip;
                    763:        struct buf *bp;
                    764:        struct vnode *vp, *nvp;
                    765:        dev_t dev;
                    766:        int error;
                    767: 
                    768:        imp = VFSTOISOFS(mp);
                    769:        dev = imp->im_dev;
                    770:        if ((*vpp = cd9660_ihashget(dev, ino, p)) != NULLVP)
                    771:                return (0);
                    772: 
                    773:        MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE,
                    774:            M_WAITOK);
                    775:        /* Allocate a new vnode/iso_node. */
                    776:        if ( (error = getnewvnode(VT_ISOFS, mp, cd9660_vnodeop_p, &vp)) ) {
                    777:                FREE(ip, M_ISOFSNODE);
                    778:                *vpp = NULLVP;
                    779:                return (error);
                    780:        }
                    781:        bzero((caddr_t)ip, sizeof(struct iso_node));
                    782: 
                    783: // radar 1669467 - chw initialize the lock structure now that we are using
                    784: //                the lock manager
                    785: 
                    786:        lockinit(&ip->i_lock, PINOD,"inode",0,0);
                    787:        vp->v_data = ip;
                    788:        ip->i_vnode = vp;
                    789:        ip->i_dev = dev;
                    790:        ip->i_number = ino;
                    791: 
                    792:        /*
                    793:         * Put it onto its hash chain and lock it so that other requests for
                    794:         * this inode will block if they arrive while we are sleeping waiting
                    795:         * for old data structures to be purged or for the contents of the
                    796:         * disk portion of this inode to be read.
                    797:         */
                    798:        cd9660_ihashins(ip);
                    799: 
                    800:        if (isodir == 0) {
                    801:                int lbn, off;
                    802: 
                    803:                lbn = lblkno(imp, ino);
                    804:                if (lbn >= imp->volume_space_size) {
                    805:                        vput(vp);
                    806:                        printf("fhtovp: lbn exceed volume space %d\n", lbn);
                    807:                        return (ESTALE);
                    808:                }
                    809:        
                    810:                off = blkoff(imp, ino);
                    811:                if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
                    812:                        vput(vp);
                    813:                        printf("fhtovp: crosses block boundary %d\n",
                    814:                               off + ISO_DIRECTORY_RECORD_SIZE);
                    815:                        return (ESTALE);
                    816:                }
                    817:        
                    818:                error = bread(imp->im_devvp,
                    819: #if 1 // radar 1669467
                    820:                              lbn,
                    821: #else
                    822:                              lbn << (imp->im_bshift - DEV_BSHIFT),
                    823: #endif // radar 1669467
                    824:                              imp->logical_block_size, NOCRED, &bp);
                    825:                if (error) {
                    826:                        vput(vp);
                    827:                        brelse(bp);
                    828:                        printf("fhtovp: bread error %d\n",error);
                    829:                        return (error);
                    830:                }
                    831:                isodir = (struct iso_directory_record *)(bp->b_data + off);
                    832: 
                    833:                if (off + isonum_711(isodir->length) >
                    834:                    imp->logical_block_size) {
                    835:                        vput(vp);
                    836:                        if (bp != 0)
                    837:                                brelse(bp);
                    838:                        printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
                    839:                               off +isonum_711(isodir->length), off,
                    840:                               isonum_711(isodir->length));
                    841:                        return (ESTALE);
                    842:                }
                    843: 
                    844:                /*
                    845:                 * for directories we can get parentID from adjacent parent directory record
                    846:                 */
                    847:                if ((isonum_711(isodir->flags) & directoryBit) && (isodir->name[0] == 0)) {
                    848:                        struct iso_directory_record *pdp;
                    849:                        
                    850:                        pdp = (struct iso_directory_record *) ((char *)bp->b_data + isonum_711(isodir->length));
                    851:                        if ((isonum_711(pdp->flags) & directoryBit) && (pdp->name[0] == 1))
                    852:                                ip->i_parent = isodirino(pdp, imp);
                    853:                        
                    854:                }
                    855: #if 0
                    856:                if (isonum_733(isodir->extent) +
                    857:                    isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) {
                    858:                        if (bp != 0)
                    859:                                brelse(bp);
                    860:                        printf("fhtovp: file start miss %d vs %d\n",
                    861:                               isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length),
                    862:                               ifhp->ifid_start);
                    863:                        return (ESTALE);
                    864:                }
                    865: #endif
                    866:        } else
                    867:                bp = 0;
                    868: 
                    869:        ip->i_mnt = imp;
                    870:        ip->i_devvp = imp->im_devvp;
                    871:        VREF(ip->i_devvp);
                    872: 
                    873:        if (relocated) {
                    874:                /*
                    875:                 * On relocated directories we must
                    876:                 * read the `.' entry out of a dir.
                    877:                 */
                    878:                ip->iso_start = ino >> imp->im_bshift;
                    879:                if (bp != 0)
                    880:                        brelse(bp);
                    881:                if ( (error = VOP_BLKATOFF(vp, (off_t)0, NULL, &bp)) ) {
                    882:                        vput(vp);
                    883:                        return (error);
                    884:                }
                    885:                isodir = (struct iso_directory_record *)bp->b_data;
                    886:        }
                    887: 
                    888: #if 1 // radar 1669467
                    889: 
                    890:        /* go get apple extensions to ISO directory record or use defaults when there are no apple */
                    891:        /* extensions.   */
                    892:        if ( (isonum_711( isodir->flags ) & directoryBit) == 0 )
                    893:        {
                    894:                /* This is an ISO directory record for a file */
                    895:                DRGetTypeCreatorAndFlags( imp, isodir, &ip->i_FileType, 
                    896:                                                                  &ip->i_Creator, &ip->i_FinderFlags );
                    897:        }
                    898: 
                    899: #endif // radar 1669467
                    900: 
                    901:        ip->iso_extent = isonum_733(isodir->extent);
                    902:        ip->i_size = isonum_733(isodir->size);
                    903:        ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
                    904: 
                    905:        /*
                    906:         * if we have a valid name, fill in i_name
                    907:         */
                    908:        if (((u_char)isodir->name[0]) > 1) {
                    909:                u_short namelen;
                    910: 
                    911:                if (imp->iso_ftype == ISO_FTYPE_RRIP) {
                    912:                        ino_t inump = 0;
                    913:        
                    914:                        cd9660_rrip_getname(isodir, ip->i_name, &namelen, &inump, imp);
                    915:                } else {
                    916:                        isofntrans (isodir->name, isonum_711(isodir->name_len),
                    917:                                        ip->i_name, &namelen,
                    918:                                        imp->iso_ftype == ISO_FTYPE_9660,
                    919:                                        isonum_711(isodir->flags) & associatedBit);
                    920:                }
                    921:        
                    922:                if (namelen > (sizeof(ip->i_name) - 1))
                    923:                        namelen = sizeof(ip->i_name) - 1;
                    924:                ip->i_name[namelen] = '\0';
                    925:        }
                    926:        
                    927:        /*
                    928:         * Setup time stamp, attribute
                    929:         */
                    930:        vp->v_type = VNON;
                    931:        switch (imp->iso_ftype) {
                    932:        default:        /* ISO_FTYPE_9660 */
                    933:            {
                    934:                struct buf *bp2;
                    935:                int off;
                    936:                if ((imp->im_flags & ISOFSMNT_EXTATT)
                    937:                    && (off = isonum_711(isodir->ext_attr_length)))
                    938:                        VOP_BLKATOFF(vp, (off_t)-(off << imp->im_bshift), NULL,
                    939:                                     &bp2);
                    940:                else
                    941:                        bp2 = NULL;
                    942:                cd9660_defattr(isodir, ip, bp2);
                    943:                cd9660_deftstamp(isodir, ip, bp2);
                    944:                if (bp2)
                    945:                        brelse(bp2);
                    946:                break;
                    947:            }
                    948:        case ISO_FTYPE_RRIP:
                    949:                cd9660_rrip_analyze(isodir, ip, imp);
                    950:                break;
                    951:        }
                    952: 
                    953:        if (bp != 0)
                    954:                brelse(bp);
                    955: 
                    956:        /*
                    957:         * Initialize the associated vnode
                    958:         */
                    959:        switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) {
                    960:        case VFIFO:
                    961: #if    FIFO
                    962:                vp->v_op = cd9660_fifoop_p;
                    963:                break;
                    964: #else
                    965:                vput(vp);
                    966:                return (EOPNOTSUPP);
                    967: #endif /* FIFO */
                    968:        case VCHR:
                    969:        case VBLK:
                    970:                /*
                    971:                 * if device, look at device number table for translation
                    972:                 */
                    973: #ifdef ISODEVMAP
                    974:                if (dp = iso_dmap(dev, ino, 0))
                    975:                        ip->inode.iso_rdev = dp->d_dev;
                    976: #endif
                    977:                vp->v_op = cd9660_specop_p;
                    978:                if ( (nvp = checkalias(vp, ip->inode.iso_rdev, mp)) ) {
                    979:                        /*
                    980:                         * Discard unneeded vnode, but save its iso_node.
                    981:                         */
                    982:                        cd9660_ihashrem(ip);
                    983:                        VOP_UNLOCK(vp, 0, p);
                    984:                        nvp->v_data = vp->v_data;
                    985:                        vp->v_data = NULL;
                    986:                        vp->v_op = spec_vnodeop_p;
                    987:                        vrele(vp);
                    988:                        vgone(vp);
                    989:                        /*
                    990:                         * Reinitialize aliased inode.
                    991:                         */
                    992:                        vp = nvp;
                    993:                        ip->i_vnode = vp;
                    994:                        cd9660_ihashins(ip);
                    995:                }
                    996:                break;
                    997:        default:                // radar 1669467 - fix compiler warning
                    998:                break;
                    999:        }
                   1000:        
                   1001:        if (ip->iso_extent == imp->root_extent) {
                   1002:                vp->v_flag |= VROOT;
                   1003:                ip->i_parent = 1;       /* root's parent is always 1 by convention */
                   1004:        }
                   1005:        /*
                   1006:         * XXX need generation number?
                   1007:         */
                   1008: 
                   1009:        *vpp = vp;
                   1010: 
                   1011:        return (0);
                   1012: }
                   1013: 
                   1014: 
                   1015: /************************************************************************
                   1016:  *
                   1017:  *  Function:  DRGetTypeCreatorAndFlags
                   1018:  *
                   1019:  *  Purpose:   Set up the fileType, fileCreator and fileFlags
                   1020:  *
                   1021:  *  Returns:   none
                   1022:  *
                   1023:  *  Side Effects:      sets *theTypePtr, *theCreatorPtr, and *theFlagsPtr
                   1024:  *
                   1025:  *  Description:
                   1026:  *
                   1027:  *  Revision History:
                   1028:  *     28 Jul 88       BL�B    Added a new extension type of 6, which allows
                   1029:  *                                             the specification of four of the finder flags.
                   1030:  *                                             We let the creator of the disk just copy over
                   1031:  *                                             the finder flags, but we only look at always
                   1032:  *                                             switch launch, system, bundle, and locked bits.
                   1033:  *     15 Aug 88       BL�B    The Apple extensions to ISO 9660 implemented the
                   1034:  *                                             padding field at the end of a directory record
                   1035:  *                                             incorrectly.
                   1036:  *     19 Jul 89       BG              Rewrote routine to handle the "new" Apple
                   1037:  *                                             Extensions definition, as well as take into
                   1038:  *                                             account the possibility of "other" definitions.
                   1039:  *     02 Nov 89       BG              Corrected the 'AA' SystemUseID processing to
                   1040:  *                                             check for SystemUseID == 2 (HFS).  Was incorrectly
                   1041:  *                                             checking for SystemUseID == 1 (ProDOS) before.
                   1042:  *     18 Mar 92       CMP             Fixed the check for whether len_fi was odd or even.
                   1043:  *                                             Before it would always assume even for an XA record.
                   1044:  *     26 Dec 97       jwc             Swiped from MacOS implementation of ISO 9660 CD-ROM support
                   1045:  *                                             and modified to work in MacOSX file system.
                   1046:  *
                   1047:  *********************************************************************** */
                   1048:  
                   1049: static void DRGetTypeCreatorAndFlags(  struct iso_mnt * theMountPointPtr,
                   1050:                                                                                struct iso_directory_record * theDirRecPtr, 
                   1051:                                                                                u_int32_t * theTypePtr, 
                   1052:                                                                                u_int32_t * theCreatorPtr, 
                   1053:                                                                                u_int16_t * theFlagsPtr )
                   1054: {
                   1055:        int                                     foundStuff;
                   1056:        u_int32_t                       myType;
                   1057:        u_int32_t                       myCreator;
                   1058:        AppleExtension          *myAppleExtPtr;
                   1059:        NewAppleExtension       *myNewAppleExtPtr;
                   1060:        u_int16_t                       myFinderFlags;
                   1061:        char                            *myPtr;
                   1062: 
                   1063:        foundStuff = 1;
                   1064:        myType = 0L;
                   1065:        myCreator = 0L;
                   1066:        myFinderFlags = 0;
                   1067:        *theFlagsPtr = 0x0000;
                   1068: 
                   1069:        /* handle the fact that our original apple extensions didn't take
                   1070:           into account the padding byte on a file name */
                   1071: 
                   1072:        myPtr = &theDirRecPtr->name[ (isonum_711(theDirRecPtr->name_len)) ];
                   1073:        
                   1074:        /* if string length is even, bump myPtr for padding byte */
                   1075:        if ( ((isonum_711(theDirRecPtr->name_len)) & 0x01) == 0 )
                   1076:                myPtr++;
                   1077:        myAppleExtPtr = (AppleExtension *) myPtr;
                   1078: 
                   1079:        /* checking for whether or not the new 'AA' code is being called (and if so, correctly) */
                   1080:        if ( (isonum_711(theDirRecPtr->length)) <= 
                   1081:                 ISO_DIRECTORY_RECORD_SIZE + (isonum_711(theDirRecPtr->name_len)) )
                   1082:        {
                   1083:                foundStuff = 0;
                   1084:                goto DoneLooking;
                   1085:        }
                   1086: 
                   1087:        if ( myAppleExtPtr->signature[0] == 'B' && myAppleExtPtr->signature[1] == 'A' )
                   1088:        {
                   1089:                int             i;
                   1090: 
                   1091:                switch ( isonum_711(myAppleExtPtr->systemUseID) )
                   1092:                {
                   1093:                        case 0x00:      /* nothing there.  use default */
                   1094:                                foundStuff = 0;
                   1095:                                break;
                   1096:                        case 0x02:      /* no icon */
                   1097:                        case 0x04:      /* icon, no bundle bit */
                   1098:                                for ( i = 0; i < 4; i++ )
                   1099:                                        myType = (myType << 8) | myAppleExtPtr->fileType[i];
                   1100:                                        
                   1101:                                for ( i = 0; i < 4; i++ )
                   1102:                                        myCreator = (myCreator << 8) | myAppleExtPtr->fileCreator[i];
                   1103:                                        
                   1104:                                *theFlagsPtr |= fInitedBit;
                   1105:                                break;
                   1106:                        case 0x03:      /* no icon, bundle bit */
                   1107:                        case 0x05:      /* icon and bundle bit */
                   1108:                                for ( i = 0; i < 4; i++ )
                   1109:                                        myType = (myType << 8) | myAppleExtPtr->fileType[i];
                   1110:                                        
                   1111:                                for ( i = 0; i < 4; i++ )
                   1112:                                        myCreator = (myCreator << 8) | myAppleExtPtr->fileCreator[i];
                   1113:                                        
                   1114:                                *theFlagsPtr |= fInitedBit | fHasBundleBit;
                   1115:                                break;
                   1116:                        case 0x06:      /* finder flags in word at end */
                   1117:                                for ( i = 0; i < 4; i++ )
                   1118:                                        myType = (myType << 8) | myAppleExtPtr->fileType[i];
                   1119:                                        
                   1120:                                for ( i = 0; i < 4; i++ )
                   1121:                                        myCreator = (myCreator << 8) | myAppleExtPtr->fileCreator[i];
                   1122:                                        
                   1123:                                myFinderFlags = 
                   1124:                                        (myAppleExtPtr->finderFlags[0] << 8) | myAppleExtPtr->finderFlags[1];
                   1125:                                        
                   1126:                                /* just check the following four bits--all others always set to 0 */
                   1127:                                myFinderFlags &= (fAlwaysBit | fSystemBit | fHasBundleBit | fLockedBit);
                   1128:                                *theFlagsPtr |= (fInitedBit | myFinderFlags);
                   1129:                                break;
                   1130:                        default:
                   1131:                                foundStuff = 0;
                   1132:                }
                   1133:                goto DoneLooking;
                   1134:        }
                   1135:        
                   1136:        /*
                   1137:         *              If signature[]s != 'BA', then (1) this is not an old-style disc and we
                   1138:         *              need to look at ALL available SystemUse possibilities;  (2)  this could
                   1139:         *              possibly be a CD-XA style disc and our offset calculations need to
                   1140:         *              take this into account.
                   1141:         */
                   1142: 
                   1143:        foundStuff = 0; /* now we default to *false* until we find a good one */
                   1144:        myPtr = (char *) myAppleExtPtr;
                   1145: 
                   1146:        if ( (theMountPointPtr->im_flags2 & IMF2_IS_CDXA) != 0 )
                   1147:                myPtr += 14;/* add in CD-XA fixed record offset (tnx, Phillips) */
                   1148:        myNewAppleExtPtr = (NewAppleExtension *) myPtr;
                   1149: 
                   1150:        /* calculate the "real" end of the directory record information */
                   1151:        myPtr = ((char *) theDirRecPtr) + (isonum_711(theDirRecPtr->length));
                   1152:        while( (char *) myNewAppleExtPtr < myPtr )      /* end of directory buffer */
                   1153:        {
                   1154:                /*
                   1155:                 *      If we get here, we can assume that ALL further entries in this
                   1156:                 *      directory record are of the form:
                   1157:                 *
                   1158:                 *              struct OptionalSystemUse
                   1159:                 *              {
                   1160:                 *                      byte    Signature[2];
                   1161:                 *                      byte    systemUseID;
                   1162:                 *                      byte    OSULength;
                   1163:                 *                      byte    fileType[4];            # only if HFS
                   1164:                 *                      byte    fileCreator[4];         # only if HFS
                   1165:                 *                      byte    finderFlags[2];         # only if HFS
                   1166:                 *              };
                   1167:                 *
                   1168:                 *      This means that we can examine the Signature bytes to see if they are 'AA'
                   1169:                 *      (the NEW Apple extension signature).  If they are, deal with them.  If they
                   1170:                 *      aren't, the OSULength field will tell us how long this extension info is
                   1171:                 *      (including the signature and length bytes) and that will allow us to walk
                   1172:                 *      the OptionalSystemUse records until we hit the end of them or run off the
                   1173:                 *      end of the directory record.
                   1174:                 */
                   1175:                u_char                          *myFromPtr, *myToPtr;
                   1176:                union
                   1177:                {
                   1178:                        u_int32_t               fourchars;
                   1179:                        u_char                  chars[4];
                   1180:                } myChars;
                   1181: 
                   1182:                if ( myNewAppleExtPtr->signature[0] == 'A' && myNewAppleExtPtr->signature[1] == 'A' )
                   1183:                {
                   1184:                        if ( isonum_711(myNewAppleExtPtr->systemUseID) == 2 )   /* HFS */
                   1185:                        {
                   1186:                                foundStuff = 1;                 /* we got one! */
                   1187: 
                   1188:                                myFromPtr = &myNewAppleExtPtr->fileType[0]; 
                   1189:                                myToPtr = &myChars.chars[0];
                   1190:                                *myToPtr++ = *myFromPtr++; 
                   1191:                                *myToPtr++ = *myFromPtr++; 
                   1192:                                *myToPtr++ = *myFromPtr++; 
                   1193:                                *myToPtr = *myFromPtr;
                   1194:                                myType = myChars.fourchars;             /* copy file type to user var */
                   1195: 
                   1196:                                myFromPtr = &myNewAppleExtPtr->fileCreator[0]; 
                   1197:                                myToPtr = &myChars.chars[0];
                   1198:                                *myToPtr++ = *myFromPtr++; 
                   1199:                                *myToPtr++ = *myFromPtr++; 
                   1200:                                *myToPtr++ = *myFromPtr++; 
                   1201:                                *myToPtr = *myFromPtr;
                   1202:                                myCreator = myChars.fourchars;  /* copy creator to user var */
                   1203: 
                   1204:                                myFromPtr = &myNewAppleExtPtr->finderFlags[0]; 
                   1205:                                myToPtr = &myChars.chars[2];    /* *flags* is a short */
                   1206:                                myChars.fourchars = 0; 
                   1207:                                *myToPtr++ = *myFromPtr++; 
                   1208:                                *myToPtr = *myFromPtr;
                   1209:                                myFinderFlags = myChars.fourchars;
                   1210:                                myFinderFlags &= ( fAlwaysBit | fSystemBit | fHasBundleBit | fLockedBit );
                   1211:                                *theFlagsPtr = (myFinderFlags | fInitedBit); /* return Finder flags to user var */
                   1212: 
                   1213:                                break;          /* exit the loop */
                   1214:                        }
                   1215:                }
                   1216: 
                   1217:                /*
                   1218:                 *      Check to see if we have a reasonable OSULength value.
                   1219:                 *      ZERO is not an acceptable value.  Nor is any value less than 4.
                   1220:                 */
                   1221: 
                   1222:                if ( (isonum_711(myNewAppleExtPtr->OSULength)) < 4 ) 
                   1223:                        break;  /* not acceptable - get out! */
                   1224: 
                   1225:                /* otherwise, step past this SystemUse record */
                   1226:                (char *)myNewAppleExtPtr += (isonum_711(myNewAppleExtPtr->OSULength));
                   1227:                
                   1228:        } // end of while loop
                   1229: 
                   1230: DoneLooking:
                   1231:        if ( foundStuff != 0 )
                   1232:        {
                   1233:                *theTypePtr    = myType;
                   1234:                *theCreatorPtr = myCreator;
                   1235:        }
                   1236:        else
                   1237:        {
                   1238:                *theTypePtr = DEFAULTTYPE;
                   1239:                *theCreatorPtr = DEFAULTCREATOR;
                   1240:                *theFlagsPtr |= fInitedBit;
                   1241:        }
                   1242:        
                   1243:        return;
                   1244:        
                   1245: } /* DRGetTypeCreatorAndFlags */
                   1246: 
                   1247: 
                   1248: /*
                   1249:  * Vnode pointer to File handle
                   1250:  */
                   1251: /* ARGSUSED */
                   1252: int
                   1253: cd9660_vptofh(vp, fhp)
                   1254:        struct vnode *vp;
                   1255:        struct fid *fhp;
                   1256: {
                   1257:        register struct iso_node *ip = VTOI(vp);
                   1258:        register struct ifid *ifhp;
                   1259:        
                   1260:        ifhp = (struct ifid *)fhp;
                   1261:        ifhp->ifid_len = sizeof(struct ifid);
                   1262:        
                   1263:        ifhp->ifid_ino = ip->i_number;
                   1264:        ifhp->ifid_start = ip->iso_start;
                   1265:        
                   1266: #ifdef ISOFS_DBG
                   1267:        printf("vptofh: ino %d, start %ld\n",
                   1268:               ifhp->ifid_ino,ifhp->ifid_start);
                   1269: #endif
                   1270:        return 0;
                   1271: }
                   1272: 
                   1273: /*
                   1274:  * Fast-FileSystem only?
                   1275:  */
                   1276: int
                   1277: cd9660_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                   1278:      int * name;
                   1279:      u_int namelen;
                   1280:      void* oldp;
                   1281:      size_t * oldlenp;
                   1282:      void * newp;
                   1283:      size_t newlen;
                   1284:      struct proc * p;
                   1285: {
                   1286:      return EOPNOTSUPP;
                   1287: }
                   1288: 

unix.superglobalmegacorp.com

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