Annotation of XNU/bsd/isofs/cd9660/cd9660_util.c, revision 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_util.c,v 1.8 1994/12/13 22:33:25 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_util.c       8.3 (Berkeley) 12/5/94
        !            62:  *
        !            63:  * HISTORY
        !            64:  *  7-Dec-98   Add ATTR_VOL_MOUNTFLAGS attribute support - djb
        !            65:  * 18-Nov-98   Add support for volfs - djb
        !            66:  */
        !            67: 
        !            68: #include <sys/param.h>
        !            69: #include <sys/systm.h>
        !            70: #include <sys/namei.h>
        !            71: #include <sys/resourcevar.h>
        !            72: #include <sys/kernel.h>
        !            73: #include <sys/file.h>
        !            74: #include <sys/stat.h>
        !            75: #include <sys/buf.h>
        !            76: #include <sys/proc.h>
        !            77: #include <sys/conf.h>
        !            78: #include <sys/mount.h>
        !            79: #include <sys/vnode.h>
        !            80: #include <miscfs/specfs/specdev.h> /* XXX */
        !            81: #include <miscfs/fifofs/fifo.h> /* XXX */
        !            82: #include <sys/malloc.h>
        !            83: #include <sys/dir.h>
        !            84: #include <sys/attr.h>
        !            85: #include <kern/assert.h>
        !            86: 
        !            87: #include <isofs/cd9660/iso.h>
        !            88: #include <isofs/cd9660/cd9660_node.h>
        !            89: #include <isofs/cd9660/iso_rrip.h>
        !            90: 
        !            91: /*
        !            92:  * translate and compare a filename
        !            93:  * Note: Version number plus ';' may be omitted.
        !            94:  */
        !            95: int
        !            96: isofncmp(fn, fnlen, isofn, isolen)
        !            97:        u_char *fn, *isofn;
        !            98:        int fnlen, isolen;
        !            99: {
        !           100:        int i, j;
        !           101:        char c;
        !           102:        
        !           103:        while (--fnlen >= 0) {
        !           104:                if (--isolen < 0)
        !           105:                        return *fn;
        !           106:                if ((c = *isofn++) == ';') {
        !           107:                        switch (*fn++) {
        !           108:                        default:
        !           109:                                return *--fn;
        !           110:                        case 0:
        !           111:                                return 0;
        !           112:                        case ';':
        !           113:                                break;
        !           114:                        }
        !           115:                        for (i = 0; --fnlen >= 0; i = i * 10 + *fn++ - '0') {
        !           116:                                if (*fn < '0' || *fn > '9') {
        !           117:                                        return -1;
        !           118:                                }
        !           119:                        }
        !           120:                        for (j = 0; --isolen >= 0; j = j * 10 + *isofn++ - '0');
        !           121:                        return i - j;
        !           122:                }
        !           123:                if (c != *fn) {
        !           124:                        if (c >= 'A' && c <= 'Z') {
        !           125:                                if (c + ('a' - 'A') != *fn) {
        !           126:                                        if (*fn >= 'a' && *fn <= 'z')
        !           127:                                                return *fn - ('a' - 'A') - c;
        !           128:                                        else
        !           129:                                                return *fn - c;
        !           130:                                }
        !           131:                        } else
        !           132:                                return *fn - c;
        !           133:                }
        !           134:                fn++;
        !           135:        }
        !           136:        if (isolen > 0) {
        !           137:                switch (*isofn) {
        !           138:                default:
        !           139:                        return -1;
        !           140:                case '.':
        !           141:                        if (isofn[1] != ';')
        !           142:                                return -1;
        !           143:                case ';':
        !           144:                        return 0;
        !           145:                }
        !           146:        }
        !           147:        return 0;
        !           148: }
        !           149: 
        !           150: /*
        !           151:  * translate a filename
        !           152:  */
        !           153: void
        !           154: isofntrans(infn, infnlen, outfn, outfnlen, original, assoc)
        !           155:        u_char *infn, *outfn;
        !           156:        int infnlen;
        !           157:        u_short *outfnlen;
        !           158:        int original;
        !           159:        int assoc;
        !           160: {
        !           161:        int fnidx = 0;
        !           162:        
        !           163:        if (assoc) {
        !           164:                *outfn++ = ASSOCCHAR;
        !           165:                fnidx++;
        !           166:                infnlen++;
        !           167:        }
        !           168:        for (; fnidx < infnlen; fnidx++) {
        !           169:                char c = *infn++;
        !           170:                
        !           171:                if (!original && c >= 'A' && c <= 'Z')
        !           172:                        *outfn++ = c + ('a' - 'A');
        !           173:                else if (!original && c == '.' && *infn == ';')
        !           174:                        break;
        !           175:                else if (!original && c == ';')
        !           176:                        break;
        !           177:                else
        !           178:                        *outfn++ = c;
        !           179:        }
        !           180:        *outfnlen = fnidx;
        !           181: }
        !           182: 
        !           183: 
        !           184: int
        !           185: attrcalcsize(struct attrlist *attrlist)
        !           186: {
        !           187:        int size;
        !           188:        attrgroup_t a;
        !           189:        
        !           190: #if ((ATTR_CMN_NAME                    | ATTR_CMN_DEVID                        | ATTR_CMN_FSID                         | ATTR_CMN_OBJTYPE              | \
        !           191:       ATTR_CMN_OBJTAG          | ATTR_CMN_OBJID                        | ATTR_CMN_OBJPERMANENTID       | ATTR_CMN_PAROBJID             | \
        !           192:       ATTR_CMN_SCRIPT          | ATTR_CMN_CRTIME                       | ATTR_CMN_MODTIME                      | ATTR_CMN_CHGTIME              | \
        !           193:       ATTR_CMN_ACCTIME         | ATTR_CMN_BKUPTIME                     | ATTR_CMN_FNDRINFO                     | ATTR_CMN_OWNERID              | \
        !           194:       ATTR_CMN_GRPID           | ATTR_CMN_ACCESSMASK           | ATTR_CMN_NAMEDATTRCOUNT       | ATTR_CMN_NAMEDATTRLIST| \
        !           195:       ATTR_CMN_FLAGS) != ATTR_CMN_VALIDMASK)
        !           196: #warning AttributeBlockSize: Missing bits in common mask computation!
        !           197: #endif
        !           198:        assert((attrlist->commonattr & ~ATTR_CMN_VALIDMASK) == 0);
        !           199: 
        !           200: #if ((ATTR_VOL_FSTYPE          | ATTR_VOL_SIGNATURE            | ATTR_VOL_SIZE                         | ATTR_VOL_SPACEFREE    | \
        !           201:       ATTR_VOL_SPACEAVAIL      | ATTR_VOL_MINALLOCATION        | ATTR_VOL_ALLOCATIONCLUMP      | ATTR_VOL_IOBLOCKSIZE  | \
        !           202:       ATTR_VOL_OBJCOUNT                | ATTR_VOL_FILECOUNT            | ATTR_VOL_DIRCOUNT                     | ATTR_VOL_MAXOBJCOUNT  | \
        !           203:       ATTR_VOL_MOUNTPOINT      | ATTR_VOL_NAME                         | ATTR_VOL_MOUNTFLAGS           | ATTR_VOL_INFO) != ATTR_VOL_VALIDMASK)
        !           204: #warning AttributeBlockSize: Missing bits in volume mask computation!
        !           205: #endif
        !           206:        assert((attrlist->volattr & ~ATTR_VOL_VALIDMASK) == 0);
        !           207: 
        !           208: #if ((ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT) != ATTR_DIR_VALIDMASK)
        !           209: #warning AttributeBlockSize: Missing bits in directory mask computation!
        !           210: #endif
        !           211:        assert((attrlist->dirattr & ~ATTR_DIR_VALIDMASK) == 0);
        !           212: #if ((ATTR_FILE_LINKCOUNT      | ATTR_FILE_TOTALSIZE           | ATTR_FILE_ALLOCSIZE           | ATTR_FILE_IOBLOCKSIZE         | \
        !           213:       ATTR_FILE_CLUMPSIZE      | ATTR_FILE_DEVTYPE                     | ATTR_FILE_FILETYPE            | ATTR_FILE_FORKCOUNT           | \
        !           214:       ATTR_FILE_FORKLIST       | ATTR_FILE_DATALENGTH          | ATTR_FILE_DATAALLOCSIZE       | ATTR_FILE_DATAEXTENTS         | \
        !           215:       ATTR_FILE_RSRCLENGTH     | ATTR_FILE_RSRCALLOCSIZE       | ATTR_FILE_RSRCEXTENTS) != ATTR_FILE_VALIDMASK)
        !           216: #warning AttributeBlockSize: Missing bits in file mask computation!
        !           217: #endif
        !           218:        assert((attrlist->fileattr & ~ATTR_FILE_VALIDMASK) == 0);
        !           219: 
        !           220: #if ((ATTR_FORK_TOTALSIZE | ATTR_FORK_ALLOCSIZE) != ATTR_FORK_VALIDMASK)
        !           221: #warning AttributeBlockSize: Missing bits in fork mask computation!
        !           222: #endif
        !           223:        assert((attrlist->forkattr & ~ATTR_FORK_VALIDMASK) == 0);
        !           224: 
        !           225:        size = 0;
        !           226:        
        !           227:        if ((a = attrlist->commonattr) != 0) {
        !           228:         if (a & ATTR_CMN_NAME) size += sizeof(struct attrreference);
        !           229:                if (a & ATTR_CMN_DEVID) size += sizeof(dev_t);
        !           230:                if (a & ATTR_CMN_FSID) size += sizeof(fsid_t);
        !           231:                if (a & ATTR_CMN_OBJTYPE) size += sizeof(fsobj_type_t);
        !           232:                if (a & ATTR_CMN_OBJTAG) size += sizeof(fsobj_tag_t);
        !           233:                if (a & ATTR_CMN_OBJID) size += sizeof(fsobj_id_t);
        !           234:         if (a & ATTR_CMN_OBJPERMANENTID) size += sizeof(fsobj_id_t);
        !           235:                if (a & ATTR_CMN_PAROBJID) size += sizeof(fsobj_id_t);
        !           236:                if (a & ATTR_CMN_SCRIPT) size += sizeof(text_encoding_t);
        !           237:                if (a & ATTR_CMN_CRTIME) size += sizeof(struct timespec);
        !           238:                if (a & ATTR_CMN_MODTIME) size += sizeof(struct timespec);
        !           239:                if (a & ATTR_CMN_CHGTIME) size += sizeof(struct timespec);
        !           240:                if (a & ATTR_CMN_ACCTIME) size += sizeof(struct timespec);
        !           241:                if (a & ATTR_CMN_BKUPTIME) size += sizeof(struct timespec);
        !           242:                if (a & ATTR_CMN_FNDRINFO) size += 32 * sizeof(u_int8_t);
        !           243:                if (a & ATTR_CMN_OWNERID) size += sizeof(uid_t);
        !           244:                if (a & ATTR_CMN_GRPID) size += sizeof(gid_t);
        !           245:                if (a & ATTR_CMN_ACCESSMASK) size += sizeof(u_long);
        !           246:                if (a & ATTR_CMN_NAMEDATTRCOUNT) size += sizeof(u_long);
        !           247:                if (a & ATTR_CMN_NAMEDATTRLIST) size += sizeof(struct attrreference);
        !           248:                if (a & ATTR_CMN_FLAGS) size += sizeof(u_long);
        !           249:        };
        !           250:        if ((a = attrlist->volattr) != 0) {
        !           251:                if (a & ATTR_VOL_FSTYPE) size += sizeof(u_long);
        !           252:                if (a & ATTR_VOL_SIGNATURE) size += sizeof(u_long);
        !           253:                if (a & ATTR_VOL_SIZE) size += sizeof(off_t);
        !           254:                if (a & ATTR_VOL_SPACEFREE) size += sizeof(off_t);
        !           255:                if (a & ATTR_VOL_SPACEAVAIL) size += sizeof(off_t);
        !           256:                if (a & ATTR_VOL_MINALLOCATION) size += sizeof(off_t);
        !           257:                if (a & ATTR_VOL_ALLOCATIONCLUMP) size += sizeof(off_t);
        !           258:                if (a & ATTR_VOL_IOBLOCKSIZE) size += sizeof(size_t);
        !           259:                if (a & ATTR_VOL_OBJCOUNT) size += sizeof(u_long);
        !           260:                if (a & ATTR_VOL_FILECOUNT) size += sizeof(u_long);
        !           261:                if (a & ATTR_VOL_DIRCOUNT) size += sizeof(u_long);
        !           262:                if (a & ATTR_VOL_MAXOBJCOUNT) size += sizeof(u_long);
        !           263:                if (a & ATTR_VOL_MOUNTPOINT) size += sizeof(struct attrreference);
        !           264:         if (a & ATTR_VOL_NAME) size += sizeof(struct attrreference);
        !           265:         if (a & ATTR_VOL_MOUNTFLAGS) size += sizeof(u_long);
        !           266:        };
        !           267:        if ((a = attrlist->dirattr) != 0) {
        !           268:                if (a & ATTR_DIR_LINKCOUNT) size += sizeof(u_long);
        !           269:                if (a & ATTR_DIR_ENTRYCOUNT) size += sizeof(u_long);
        !           270:        };
        !           271:        if ((a = attrlist->fileattr) != 0) {
        !           272:                if (a & ATTR_FILE_LINKCOUNT) size += sizeof(u_long);
        !           273:                if (a & ATTR_FILE_TOTALSIZE) size += sizeof(off_t);
        !           274:                if (a & ATTR_FILE_ALLOCSIZE) size += sizeof(off_t);
        !           275:                if (a & ATTR_FILE_IOBLOCKSIZE) size += sizeof(size_t);
        !           276:                if (a & ATTR_FILE_CLUMPSIZE) size += sizeof(off_t);
        !           277:                if (a & ATTR_FILE_DEVTYPE) size += sizeof(u_long);
        !           278:                if (a & ATTR_FILE_FILETYPE) size += sizeof(u_long);
        !           279:                if (a & ATTR_FILE_FORKCOUNT) size += sizeof(u_long);
        !           280:                if (a & ATTR_FILE_FORKLIST) size += sizeof(struct attrreference);
        !           281:                if (a & ATTR_FILE_DATALENGTH) size += sizeof(off_t);
        !           282:                if (a & ATTR_FILE_DATAALLOCSIZE) size += sizeof(off_t);
        !           283:                if (a & ATTR_FILE_DATAEXTENTS) size += sizeof(extentrecord);
        !           284:                if (a & ATTR_FILE_RSRCLENGTH) size += sizeof(off_t);
        !           285:                if (a & ATTR_FILE_RSRCALLOCSIZE) size += sizeof(off_t);
        !           286:                if (a & ATTR_FILE_RSRCEXTENTS) size += sizeof(extentrecord);
        !           287:        };
        !           288:        if ((a = attrlist->forkattr) != 0) {
        !           289:                if (a & ATTR_FORK_TOTALSIZE) size += sizeof(off_t);
        !           290:                if (a & ATTR_FORK_ALLOCSIZE) size += sizeof(off_t);
        !           291:        };
        !           292: 
        !           293:     return size;
        !           294: }
        !           295: 
        !           296: 
        !           297: 
        !           298: void
        !           299: packvolattr (struct attrlist *alist,
        !           300:                         struct iso_node *ip,   /* ip for root directory */
        !           301:                         void **attrbufptrptr,
        !           302:                         void **varbufptrptr)
        !           303: {
        !           304:     void *attrbufptr;
        !           305:     void *varbufptr;
        !           306:        struct iso_mnt *imp;
        !           307:        attrgroup_t a;
        !           308:        u_long attrlength;
        !           309:        
        !           310:        attrbufptr = *attrbufptrptr;
        !           311:        varbufptr = *varbufptrptr;
        !           312:        imp = ip->i_mnt;
        !           313: 
        !           314:     if ((a = alist->commonattr) != 0) {
        !           315:         if (a & ATTR_CMN_NAME) {
        !           316:             attrlength = strlen( imp->volume_id ) + 1;
        !           317:             ((struct attrreference *)attrbufptr)->attr_dataoffset = varbufptr - attrbufptr;
        !           318:             ((struct attrreference *)attrbufptr)->attr_length = attrlength;
        !           319:             (void) strncpy((unsigned char *)varbufptr, imp->volume_id, attrlength);
        !           320: 
        !           321:             /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
        !           322:             varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
        !           323:             ++((struct attrreference *)attrbufptr);
        !           324:         };
        !           325:                if (a & ATTR_CMN_DEVID) *((dev_t *)attrbufptr)++ = imp->im_devvp->v_rdev;
        !           326:                if (a & ATTR_CMN_FSID) *((fsid_t *)attrbufptr)++ = ITOV(ip)->v_mount->mnt_stat.f_fsid;
        !           327:                if (a & ATTR_CMN_OBJTYPE) *((fsobj_type_t *)attrbufptr)++ = 0;
        !           328:                if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = VT_ISOFS;
        !           329:                if (a & ATTR_CMN_OBJID) {
        !           330:                        ((fsobj_id_t *)attrbufptr)->fid_objno = 0;
        !           331:                        ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
        !           332:                        ++((fsobj_id_t *)attrbufptr);
        !           333:                };
        !           334:         if (a & ATTR_CMN_OBJPERMANENTID) {
        !           335:             ((fsobj_id_t *)attrbufptr)->fid_objno = 0;
        !           336:             ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
        !           337:             ++((fsobj_id_t *)attrbufptr);
        !           338:         };
        !           339:                if (a & ATTR_CMN_PAROBJID) {
        !           340:             ((fsobj_id_t *)attrbufptr)->fid_objno = 0;
        !           341:                        ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
        !           342:                        ++((fsobj_id_t *)attrbufptr);
        !           343:                };
        !           344:         if (a & ATTR_CMN_SCRIPT) *((text_encoding_t *)attrbufptr)++ = 0;
        !           345:                if (a & ATTR_CMN_CRTIME) *((struct timespec *)attrbufptr)++ = imp->creation_date;
        !           346:                if (a & ATTR_CMN_MODTIME) *((struct timespec *)attrbufptr)++ = imp->modification_date;
        !           347:                if (a & ATTR_CMN_CHGTIME) *((struct timespec *)attrbufptr)++ = imp->modification_date;
        !           348:                if (a & ATTR_CMN_ACCTIME) *((struct timespec *)attrbufptr)++ = imp->modification_date;
        !           349:                if (a & ATTR_CMN_BKUPTIME) {
        !           350:                        ((struct timespec *)attrbufptr)->tv_sec = 0;
        !           351:                        ((struct timespec *)attrbufptr)->tv_nsec = 0;
        !           352:                        ++((struct timespec *)attrbufptr);
        !           353:                };
        !           354:                if (a & ATTR_CMN_FNDRINFO) {
        !           355:             bzero (attrbufptr, 32 * sizeof(u_int8_t));
        !           356:             attrbufptr += 32 * sizeof(u_int8_t);
        !           357:                };
        !           358:                if (a & ATTR_CMN_OWNERID) *((uid_t *)attrbufptr)++ = ip->inode.iso_uid;
        !           359:                if (a & ATTR_CMN_GRPID) *((gid_t *)attrbufptr)++ = ip->inode.iso_gid;
        !           360:                if (a & ATTR_CMN_ACCESSMASK) *((u_long *)attrbufptr)++ = (u_long)ip->inode.iso_mode;
        !           361:                if (a & ATTR_CMN_FLAGS) *((u_long *)attrbufptr)++ = 0;
        !           362:        };
        !           363:        
        !           364:        if ((a = alist->volattr) != 0) {
        !           365:                off_t blocksize = (off_t)imp->logical_block_size;
        !           366: 
        !           367:                if (a & ATTR_VOL_FSTYPE) *((u_long *)attrbufptr)++ = (u_long)imp->im_mountp->mnt_vfc->vfc_typenum;
        !           368:                if (a & ATTR_VOL_SIGNATURE) *((u_long *)attrbufptr)++ = (u_long)ISO9660SIGNATURE;
        !           369:         if (a & ATTR_VOL_SIZE) *((off_t *)attrbufptr)++ = (off_t)imp->volume_space_size * blocksize;
        !           370:         if (a & ATTR_VOL_SPACEFREE) *((off_t *)attrbufptr)++ = 0;
        !           371:         if (a & ATTR_VOL_SPACEAVAIL) *((off_t *)attrbufptr)++ = 0;
        !           372:         if (a & ATTR_VOL_MINALLOCATION) *((off_t *)attrbufptr)++ = blocksize;
        !           373:                if (a & ATTR_VOL_ALLOCATIONCLUMP) *((off_t *)attrbufptr)++ = blocksize;
        !           374:         if (a & ATTR_VOL_IOBLOCKSIZE) *((size_t *)attrbufptr)++ = blocksize;
        !           375:                if (a & ATTR_VOL_OBJCOUNT) *((u_long *)attrbufptr)++ = 0;
        !           376:                if (a & ATTR_VOL_FILECOUNT) *((u_long *)attrbufptr)++ = 0;
        !           377:                if (a & ATTR_VOL_DIRCOUNT) *((u_long *)attrbufptr)++ = 0;
        !           378:                if (a & ATTR_VOL_MAXOBJCOUNT) *((u_long *)attrbufptr)++ = 0xFFFFFFFF;
        !           379:         if (a & ATTR_VOL_NAME) {
        !           380:             attrlength = strlen( imp->volume_id ) + 1;
        !           381:             ((struct attrreference *)attrbufptr)->attr_dataoffset = varbufptr - attrbufptr;
        !           382:             ((struct attrreference *)attrbufptr)->attr_length = attrlength;
        !           383:             (void) strncpy((unsigned char *)varbufptr, imp->volume_id, attrlength);
        !           384: 
        !           385:             /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
        !           386:             varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
        !           387:             ++((struct attrreference *)attrbufptr);
        !           388:         };
        !           389:                if (a & ATTR_VOL_MOUNTFLAGS) *((u_long *)attrbufptr)++ = (u_long)imp->im_mountp->mnt_flag;
        !           390:        };
        !           391: 
        !           392:        *attrbufptrptr = attrbufptr;
        !           393:        *varbufptrptr = varbufptr;
        !           394: }
        !           395: 
        !           396: 
        !           397: void
        !           398: packcommonattr (struct attrlist *alist,
        !           399:                                struct iso_node *ip,
        !           400:                                void **attrbufptrptr,
        !           401:                                void **varbufptrptr)
        !           402: {
        !           403:        void *attrbufptr;
        !           404:        void *varbufptr;
        !           405:        attrgroup_t a;
        !           406:        u_long attrlength;
        !           407:        
        !           408:        attrbufptr = *attrbufptrptr;
        !           409:        varbufptr = *varbufptrptr;
        !           410:        
        !           411:     if ((a = alist->commonattr) != 0) {
        !           412:                struct iso_mnt *imp = ip->i_mnt;
        !           413: 
        !           414:         if (a & ATTR_CMN_NAME) {
        !           415:                        /* special case root since we know how to get it's name */
        !           416:                        if (ITOV(ip)->v_flag & VROOT) {
        !           417:                                attrlength = strlen( imp->volume_id ) + 1;
        !           418:                                (void) strncpy((unsigned char *)varbufptr, imp->volume_id, attrlength);
        !           419:                } else {
        !           420:                attrlength = strlen(ip->i_name) + 1;
        !           421:                                (void) strncpy((unsigned char *)varbufptr, ip->i_name, attrlength);
        !           422:             }
        !           423: 
        !           424:                        ((struct attrreference *)attrbufptr)->attr_dataoffset = varbufptr - attrbufptr;
        !           425:                        ((struct attrreference *)attrbufptr)->attr_length = attrlength;
        !           426:             /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
        !           427:             varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
        !           428:             ++((struct attrreference *)attrbufptr);
        !           429:         };
        !           430:                if (a & ATTR_CMN_DEVID) *((dev_t *)attrbufptr)++ = ip->i_dev;
        !           431:                if (a & ATTR_CMN_FSID) *((fsid_t *)attrbufptr)++ = ITOV(ip)->v_mount->mnt_stat.f_fsid;
        !           432:                if (a & ATTR_CMN_OBJTYPE) *((fsobj_type_t *)attrbufptr)++ = ITOV(ip)->v_type;
        !           433:                if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = ITOV(ip)->v_tag;
        !           434:         if (a & ATTR_CMN_OBJID)        {
        !           435:                        if (ITOV(ip)->v_flag & VROOT)
        !           436:                                ((fsobj_id_t *)attrbufptr)->fid_objno = 2;      /* force root to be 2 */
        !           437:                        else
        !           438:                ((fsobj_id_t *)attrbufptr)->fid_objno = ip->i_number;
        !           439:                        ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
        !           440:                        ++((fsobj_id_t *)attrbufptr);
        !           441:                };
        !           442:         if (a & ATTR_CMN_OBJPERMANENTID)       {
        !           443:                        if (ITOV(ip)->v_flag & VROOT)
        !           444:                                ((fsobj_id_t *)attrbufptr)->fid_objno = 2;      /* force root to be 2 */
        !           445:                        else
        !           446:                ((fsobj_id_t *)attrbufptr)->fid_objno = ip->i_number;
        !           447:             ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
        !           448:             ++((fsobj_id_t *)attrbufptr);
        !           449:         };
        !           450:                if (a & ATTR_CMN_PAROBJID) {
        !           451:                        struct iso_directory_record *dp = (struct iso_directory_record *)imp->root;
        !           452:                        ino_t rootino = isodirino(dp, imp);
        !           453: 
        !           454:                        if (ip->i_number == rootino)
        !           455:                                ((fsobj_id_t *)attrbufptr)->fid_objno = 1;      /* force root parent to be 1 */
        !           456:                        else if (ip->i_parent == rootino)
        !           457:                                ((fsobj_id_t *)attrbufptr)->fid_objno = 2;      /* force root to be 2 */
        !           458:                        else
        !           459:                ((fsobj_id_t *)attrbufptr)->fid_objno = ip->i_parent;
        !           460:                        ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
        !           461:                        ++((fsobj_id_t *)attrbufptr);
        !           462:                };
        !           463:         if (a & ATTR_CMN_SCRIPT) *((text_encoding_t *)attrbufptr)++ = 0;
        !           464:                if (a & ATTR_CMN_CRTIME) *((struct timespec *)attrbufptr)++ = ip->inode.iso_mtime;
        !           465:                if (a & ATTR_CMN_MODTIME) *((struct timespec *)attrbufptr)++ = ip->inode.iso_mtime;
        !           466:                if (a & ATTR_CMN_CHGTIME) *((struct timespec *)attrbufptr)++ = ip->inode.iso_ctime;
        !           467:                if (a & ATTR_CMN_ACCTIME) *((struct timespec *)attrbufptr)++ = ip->inode.iso_atime;
        !           468:                if (a & ATTR_CMN_BKUPTIME) {
        !           469:                        ((struct timespec *)attrbufptr)->tv_sec = 0;
        !           470:                        ((struct timespec *)attrbufptr)->tv_nsec = 0;
        !           471:                        ++((struct timespec *)attrbufptr);
        !           472:                };
        !           473:                if (a & ATTR_CMN_FNDRINFO) {
        !           474:                        struct finder_info finfo = {0};
        !           475: 
        !           476:                        finfo.fdFlags = ip->i_FinderFlags;
        !           477:                        if (ITOV(ip)->v_type == VREG) {
        !           478:                                finfo.fdType = ip->i_FileType;
        !           479:                                finfo.fdCreator = ip->i_Creator;
        !           480:                        }
        !           481:             bcopy (&finfo, attrbufptr, sizeof(finfo));
        !           482:             attrbufptr += sizeof(finfo);
        !           483:             bzero (attrbufptr, EXTFNDRINFOSIZE);
        !           484:             attrbufptr += EXTFNDRINFOSIZE;
        !           485:                };
        !           486:                if (a & ATTR_CMN_OWNERID) *((uid_t *)attrbufptr)++ = ip->inode.iso_uid;
        !           487:                if (a & ATTR_CMN_GRPID) *((gid_t *)attrbufptr)++ = ip->inode.iso_gid;
        !           488:                if (a & ATTR_CMN_ACCESSMASK) *((u_long *)attrbufptr)++ = (u_long)ip->inode.iso_mode;
        !           489:                if (a & ATTR_CMN_FLAGS) *((u_long *)attrbufptr)++ = 0; /* could also use ip->i_flag */
        !           490:        };
        !           491:        
        !           492:        *attrbufptrptr = attrbufptr;
        !           493:        *varbufptrptr = varbufptr;
        !           494: }
        !           495: 
        !           496: 
        !           497: void
        !           498: packdirattr(struct attrlist *alist,
        !           499:                        struct iso_node *ip,
        !           500:                        void **attrbufptrptr,
        !           501:                        void **varbufptrptr)
        !           502: {
        !           503:     void *attrbufptr;
        !           504:     attrgroup_t a;
        !           505:        
        !           506:        attrbufptr = *attrbufptrptr;
        !           507:        
        !           508:        a = alist->dirattr;
        !           509:        if ((ITOV(ip)->v_type == VDIR) && (a != 0)) {
        !           510:                if (a & ATTR_DIR_LINKCOUNT) *((u_long *)attrbufptr)++ = ip->inode.iso_links;
        !           511:                if (a & ATTR_DIR_ENTRYCOUNT) *((u_long *)attrbufptr)++ = 2; /* XXX */
        !           512:        };
        !           513:        
        !           514:        *attrbufptrptr = attrbufptr;
        !           515: }
        !           516: 
        !           517: 
        !           518: void
        !           519: packfileattr(struct attrlist *alist,
        !           520:                         struct iso_node *ip,
        !           521:                         void **attrbufptrptr,
        !           522:                         void **varbufptrptr)
        !           523: {
        !           524:     void *attrbufptr = *attrbufptrptr;
        !           525:     void *varbufptr = *varbufptrptr;
        !           526:     attrgroup_t a = alist->fileattr;
        !           527:        
        !           528:        if ((ITOV(ip)->v_type == VREG) && (a != 0)) {
        !           529:                if (a & ATTR_FILE_LINKCOUNT) *((u_long *)attrbufptr)++ = ip->inode.iso_links;
        !           530:                if (a & ATTR_FILE_TOTALSIZE) *((off_t *)attrbufptr)++ = (off_t)ip->i_size;
        !           531:                if (a & ATTR_FILE_ALLOCSIZE) *((off_t *)attrbufptr)++ = (off_t)ip->i_size;
        !           532:                if (a & ATTR_FILE_IOBLOCKSIZE) *((u_long *)attrbufptr)++ = ip->i_mnt->logical_block_size;
        !           533:                if (a & ATTR_FILE_CLUMPSIZE) *((u_long *)attrbufptr)++ = ip->i_mnt->logical_block_size;
        !           534:                if (a & ATTR_FILE_DEVTYPE) *((u_long *)attrbufptr)++ = (u_long)ip->inode.iso_rdev;
        !           535:                if (0 /* XXX associated file */) {
        !           536:                        if (a & ATTR_FILE_RSRCLENGTH) *((off_t *)attrbufptr)++ = ip->i_size;
        !           537:                        if (a & ATTR_FILE_RSRCALLOCSIZE) *((off_t *)attrbufptr)++ = ip->i_size;
        !           538:                        if (a & ATTR_FILE_DATALENGTH) *((off_t *)attrbufptr)++ = (off_t)0;
        !           539:                        if (a & ATTR_FILE_DATAALLOCSIZE) *((off_t *)attrbufptr)++ = (off_t)0;
        !           540:                } else {
        !           541:                        if (a & ATTR_FILE_DATALENGTH) *((off_t *)attrbufptr)++ = (off_t)ip->i_size;
        !           542:                        if (a & ATTR_FILE_DATAALLOCSIZE) *((off_t *)attrbufptr)++ = (off_t)ip->i_size;
        !           543:                        if (a & ATTR_FILE_RSRCLENGTH) *((off_t *)attrbufptr)++ = (off_t)0;
        !           544:                        if (a & ATTR_FILE_RSRCALLOCSIZE) *((off_t *)attrbufptr)++ = (off_t)0;
        !           545:                };
        !           546:        };
        !           547:        
        !           548:        *attrbufptrptr = attrbufptr;
        !           549:        *varbufptrptr = varbufptr;
        !           550: }
        !           551: 
        !           552: 
        !           553: void
        !           554: packattrblk(struct attrlist *alist,
        !           555:                        struct vnode *vp,
        !           556:                        void **attrbufptrptr,
        !           557:                        void **varbufptrptr)
        !           558: {
        !           559:        struct iso_node *ip = VTOI(vp);
        !           560: 
        !           561:        if (alist->volattr != 0) {
        !           562:                packvolattr(alist, ip, attrbufptrptr, varbufptrptr);
        !           563:        } else {
        !           564:                packcommonattr(alist, ip, attrbufptrptr, varbufptrptr);
        !           565:                
        !           566:                switch (ITOV(ip)->v_type) {
        !           567:                  case VDIR:
        !           568:                        packdirattr(alist, ip, attrbufptrptr, varbufptrptr);
        !           569:                        break;
        !           570:                        
        !           571:                  case VREG:
        !           572:                        packfileattr(alist, ip, attrbufptrptr, varbufptrptr);
        !           573:                        break;
        !           574:                  
        !           575:        #if 0                                                   /* XXX PPD TBC */
        !           576:                  case VFORK:
        !           577:                        packforkattr(alist, ip, attrbufptrptr, varbufptrptr);
        !           578:                        break;
        !           579:        #endif
        !           580:                  
        !           581:                  /* Without this the compiler complains about VNON,VBLK,VCHR,VLNK,VSOCK,VFIFO,VBAD and VSTR
        !           582:                     not being handled...
        !           583:                   */
        !           584:                  default:
        !           585:                        /* XXX PPD - Panic? */
        !           586:                        break;
        !           587:                };
        !           588:        };
        !           589: };

unix.superglobalmegacorp.com

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