1*f0d9efc0Sbeck /* 2*f0d9efc0Sbeck * hfsutils - tools for reading and writing Macintosh HFS volumes 3*f0d9efc0Sbeck * Copyright (C) 1996, 1997 Robert Leslie 4*f0d9efc0Sbeck * 5*f0d9efc0Sbeck * This program is free software; you can redistribute it and/or modify 6*f0d9efc0Sbeck * it under the terms of the GNU General Public License as published by 7*f0d9efc0Sbeck * the Free Software Foundation; either version 2 of the License, or 8*f0d9efc0Sbeck * (at your option) any later version. 9*f0d9efc0Sbeck * 10*f0d9efc0Sbeck * This program is distributed in the hope that it will be useful, 11*f0d9efc0Sbeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*f0d9efc0Sbeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*f0d9efc0Sbeck * GNU General Public License for more details. 14*f0d9efc0Sbeck * 15*f0d9efc0Sbeck * You should have received a copy of the GNU General Public License 16*f0d9efc0Sbeck * along with this program; if not, write to the Free Software 17*f0d9efc0Sbeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18*f0d9efc0Sbeck */ 19*f0d9efc0Sbeck 20*f0d9efc0Sbeck # include <time.h> 21*f0d9efc0Sbeck 22*f0d9efc0Sbeck # include "hfs.h" 23*f0d9efc0Sbeck 24*f0d9efc0Sbeck # define ERROR(code, str) (hfs_error = (str), errno = (code)) 25*f0d9efc0Sbeck 26*f0d9efc0Sbeck # define SIZE(type, n) ((size_t) (sizeof(type) * (n))) 27*f0d9efc0Sbeck # define ALLOC(type, n) ((type *) malloc(SIZE(type, n))) 28*f0d9efc0Sbeck # define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0) 29*f0d9efc0Sbeck # define FREE(ptr) ((ptr) ? (void) free((void *) ptr) : (void) 0) 30*f0d9efc0Sbeck 31*f0d9efc0Sbeck # define REALLOC(ptr, type, n) \ 32*f0d9efc0Sbeck ((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n)))) 33*f0d9efc0Sbeck # define REALLOCX(ptr, type, n) \ 34*f0d9efc0Sbeck ((n) ? REALLOC(type, n) : (FREE(ptr), (type *) 0)) 35*f0d9efc0Sbeck 36*f0d9efc0Sbeck # define BMTST(bm, num) \ 37*f0d9efc0Sbeck (((char *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07))) 38*f0d9efc0Sbeck # define BMSET(bm, num) \ 39*f0d9efc0Sbeck (((char *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07))) 40*f0d9efc0Sbeck # define BMCLR(bm, num) \ 41*f0d9efc0Sbeck (((char *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07))) 42*f0d9efc0Sbeck 43*f0d9efc0Sbeck typedef unsigned char block[HFS_BLOCKSZ]; 44*f0d9efc0Sbeck 45*f0d9efc0Sbeck typedef signed char Char; 46*f0d9efc0Sbeck typedef unsigned char UChar; 47*f0d9efc0Sbeck typedef signed char SignedByte; 48*f0d9efc0Sbeck typedef signed short Integer; 49*f0d9efc0Sbeck typedef unsigned short UInteger; 50*f0d9efc0Sbeck typedef signed long LongInt; 51*f0d9efc0Sbeck typedef unsigned long ULongInt; 52*f0d9efc0Sbeck typedef char Str15[16]; 53*f0d9efc0Sbeck typedef char Str31[32]; 54*f0d9efc0Sbeck typedef long OSType; 55*f0d9efc0Sbeck 56*f0d9efc0Sbeck typedef struct { 57*f0d9efc0Sbeck UInteger xdrStABN; /* first allocation block */ 58*f0d9efc0Sbeck UInteger xdrNumABlks; /* number of allocation blocks */ 59*f0d9efc0Sbeck } ExtDescriptor; 60*f0d9efc0Sbeck 61*f0d9efc0Sbeck typedef ExtDescriptor ExtDataRec[3]; 62*f0d9efc0Sbeck 63*f0d9efc0Sbeck typedef struct { 64*f0d9efc0Sbeck SignedByte xkrKeyLen; /* key length */ 65*f0d9efc0Sbeck SignedByte xkrFkType; /* fork type (0x00/0xff == data/resource */ 66*f0d9efc0Sbeck ULongInt xkrFNum; /* file number */ 67*f0d9efc0Sbeck UInteger xkrFABN; /* starting file allocation block */ 68*f0d9efc0Sbeck } ExtKeyRec; 69*f0d9efc0Sbeck 70*f0d9efc0Sbeck typedef struct { 71*f0d9efc0Sbeck SignedByte ckrKeyLen; /* key length */ 72*f0d9efc0Sbeck SignedByte ckrResrv1; /* reserved */ 73*f0d9efc0Sbeck ULongInt ckrParID; /* parent directory ID */ 74*f0d9efc0Sbeck Str31 ckrCName; /* catalog node name */ 75*f0d9efc0Sbeck } CatKeyRec; 76*f0d9efc0Sbeck 77*f0d9efc0Sbeck # define HFS_MAP1SZ 256 78*f0d9efc0Sbeck # define HFS_MAPXSZ 492 79*f0d9efc0Sbeck 80*f0d9efc0Sbeck # define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum]) 81*f0d9efc0Sbeck 82*f0d9efc0Sbeck # define HFS_RECKEYLEN(ptr) (*(unsigned char *) (ptr)) 83*f0d9efc0Sbeck # define HFS_RECKEYSKIP(ptr) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1) 84*f0d9efc0Sbeck # define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr)) 85*f0d9efc0Sbeck 86*f0d9efc0Sbeck # define HFS_CATDATALEN sizeof(CatDataRec) 87*f0d9efc0Sbeck # define HFS_EXTDATALEN sizeof(ExtDataRec) 88*f0d9efc0Sbeck 89*f0d9efc0Sbeck # define HFS_CATKEYLEN sizeof(CatKeyRec) 90*f0d9efc0Sbeck # define HFS_EXTKEYLEN sizeof(ExtKeyRec) 91*f0d9efc0Sbeck 92*f0d9efc0Sbeck # define HFS_CATRECMAXLEN (HFS_CATKEYLEN + HFS_CATDATALEN) 93*f0d9efc0Sbeck # define HFS_EXTRECMAXLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN) 94*f0d9efc0Sbeck 95*f0d9efc0Sbeck # define HFS_MAXRECLEN HFS_CATRECMAXLEN 96*f0d9efc0Sbeck 97*f0d9efc0Sbeck typedef struct { 98*f0d9efc0Sbeck Integer v; /* vertical coordinate */ 99*f0d9efc0Sbeck Integer h; /* horizontal coordinate */ 100*f0d9efc0Sbeck } Point; 101*f0d9efc0Sbeck 102*f0d9efc0Sbeck typedef struct { 103*f0d9efc0Sbeck Integer top; /* top edge of rectangle */ 104*f0d9efc0Sbeck Integer left; /* left edge */ 105*f0d9efc0Sbeck Integer bottom; /* bottom edge */ 106*f0d9efc0Sbeck Integer right; /* rightmost edge */ 107*f0d9efc0Sbeck } Rect; 108*f0d9efc0Sbeck 109*f0d9efc0Sbeck typedef struct { 110*f0d9efc0Sbeck Rect frRect; /* folder's rectangle */ 111*f0d9efc0Sbeck Integer frFlags; /* flags */ 112*f0d9efc0Sbeck Point frLocation; /* folder's location */ 113*f0d9efc0Sbeck Integer frView; /* folder's view */ 114*f0d9efc0Sbeck } DInfo; 115*f0d9efc0Sbeck 116*f0d9efc0Sbeck typedef struct { 117*f0d9efc0Sbeck Point frScroll; /* scroll position */ 118*f0d9efc0Sbeck LongInt frOpenChain; /* directory ID chain of open folders */ 119*f0d9efc0Sbeck Integer frUnused; /* reserved */ 120*f0d9efc0Sbeck Integer frComment; /* comment ID */ 121*f0d9efc0Sbeck LongInt frPutAway; /* directory ID */ 122*f0d9efc0Sbeck } DXInfo; 123*f0d9efc0Sbeck 124*f0d9efc0Sbeck typedef struct { 125*f0d9efc0Sbeck OSType fdType; /* file type */ 126*f0d9efc0Sbeck OSType fdCreator; /* file's creator */ 127*f0d9efc0Sbeck Integer fdFlags; /* flags */ 128*f0d9efc0Sbeck Point fdLocation; /* file's location */ 129*f0d9efc0Sbeck Integer fdFldr; /* file's window */ 130*f0d9efc0Sbeck } FInfo; 131*f0d9efc0Sbeck 132*f0d9efc0Sbeck typedef struct { 133*f0d9efc0Sbeck Integer fdIconID; /* icon ID */ 134*f0d9efc0Sbeck Integer fdUnused[4]; /* reserved */ 135*f0d9efc0Sbeck Integer fdComment; /* comment ID */ 136*f0d9efc0Sbeck LongInt fdPutAway; /* home directory ID */ 137*f0d9efc0Sbeck } FXInfo; 138*f0d9efc0Sbeck 139*f0d9efc0Sbeck typedef struct { 140*f0d9efc0Sbeck Integer drSigWord; /* volume signature (0x4244 for HFS) */ 141*f0d9efc0Sbeck LongInt drCrDate; /* date and time of volume creation */ 142*f0d9efc0Sbeck LongInt drLsMod; /* date and time of last modification */ 143*f0d9efc0Sbeck Integer drAtrb; /* volume attributes */ 144*f0d9efc0Sbeck UInteger drNmFls; /* number of files in root directory */ 145*f0d9efc0Sbeck UInteger drVBMSt; /* first block of volume bit map (always 3) */ 146*f0d9efc0Sbeck UInteger drAllocPtr; /* start of next allocation search */ 147*f0d9efc0Sbeck UInteger drNmAlBlks; /* number of allocation blocks in volume */ 148*f0d9efc0Sbeck ULongInt drAlBlkSiz; /* size (in bytes) of allocation blocks */ 149*f0d9efc0Sbeck ULongInt drClpSiz; /* default clump size */ 150*f0d9efc0Sbeck UInteger drAlBlSt; /* first allocation block in volume */ 151*f0d9efc0Sbeck LongInt drNxtCNID; /* next unused catalog node ID (dir/file ID) */ 152*f0d9efc0Sbeck UInteger drFreeBks; /* number of unused allocation blocks */ 153*f0d9efc0Sbeck char drVN[28]; /* volume name (1-27 chars) */ 154*f0d9efc0Sbeck LongInt drVolBkUp; /* date and time of last backup */ 155*f0d9efc0Sbeck Integer drVSeqNum; /* volume backup sequence number */ 156*f0d9efc0Sbeck ULongInt drWrCnt; /* volume write count */ 157*f0d9efc0Sbeck ULongInt drXTClpSiz; /* clump size for extents overflow file */ 158*f0d9efc0Sbeck ULongInt drCTClpSiz; /* clump size for catalog file */ 159*f0d9efc0Sbeck UInteger drNmRtDirs; /* number of directories in root directory */ 160*f0d9efc0Sbeck ULongInt drFilCnt; /* number of files in volume */ 161*f0d9efc0Sbeck ULongInt drDirCnt; /* number of directories in volume */ 162*f0d9efc0Sbeck LongInt drFndrInfo[8]; /* information used by the Finder */ 163*f0d9efc0Sbeck UInteger drVCSize; /* size (in blocks) of volume cache */ 164*f0d9efc0Sbeck UInteger drVBMCSize; /* size (in blocks) of volume bitmap cache */ 165*f0d9efc0Sbeck UInteger drCtlCSize; /* size (in blocks) of common volume cache */ 166*f0d9efc0Sbeck ULongInt drXTFlSize; /* size (in bytes) of extents overflow file */ 167*f0d9efc0Sbeck ExtDataRec drXTExtRec; /* first extent record for extents file */ 168*f0d9efc0Sbeck ULongInt drCTFlSize; /* size (in bytes) of catalog file */ 169*f0d9efc0Sbeck ExtDataRec drCTExtRec; /* first extent record for catalog file */ 170*f0d9efc0Sbeck } MDB; 171*f0d9efc0Sbeck 172*f0d9efc0Sbeck # define HFS_ATRB_BUSY (1 << 6) 173*f0d9efc0Sbeck # define HFS_ATRB_HLOCKED (1 << 7) 174*f0d9efc0Sbeck # define HFS_ATRB_UMOUNTED (1 << 8) 175*f0d9efc0Sbeck # define HFS_ATRB_BBSPARED (1 << 9) 176*f0d9efc0Sbeck # define HFS_ATRB_COPYPROT (1 << 14) 177*f0d9efc0Sbeck # define HFS_ATRB_SLOCKED (1 << 15) 178*f0d9efc0Sbeck 179*f0d9efc0Sbeck typedef enum { 180*f0d9efc0Sbeck cdrDirRec = 1, 181*f0d9efc0Sbeck cdrFilRec = 2, 182*f0d9efc0Sbeck cdrThdRec = 3, 183*f0d9efc0Sbeck cdrFThdRec = 4 184*f0d9efc0Sbeck } CatDataType; 185*f0d9efc0Sbeck 186*f0d9efc0Sbeck typedef struct { 187*f0d9efc0Sbeck SignedByte cdrType; /* record type */ 188*f0d9efc0Sbeck SignedByte cdrResrv2; /* reserved */ 189*f0d9efc0Sbeck union { 190*f0d9efc0Sbeck struct { /* cdrDirRec */ 191*f0d9efc0Sbeck Integer dirFlags; /* directory flags */ 192*f0d9efc0Sbeck UInteger dirVal; /* directory valence */ 193*f0d9efc0Sbeck ULongInt dirDirID; /* directory ID */ 194*f0d9efc0Sbeck LongInt dirCrDat; /* date and time of creation */ 195*f0d9efc0Sbeck LongInt dirMdDat; /* date and time of last modification */ 196*f0d9efc0Sbeck LongInt dirBkDat; /* date and time of last backup */ 197*f0d9efc0Sbeck DInfo dirUsrInfo; /* Finder information */ 198*f0d9efc0Sbeck DXInfo dirFndrInfo; /* additional Finder information */ 199*f0d9efc0Sbeck LongInt dirResrv[4]; /* reserved */ 200*f0d9efc0Sbeck } dir; 201*f0d9efc0Sbeck struct { /* cdrFilRec */ 202*f0d9efc0Sbeck SignedByte 203*f0d9efc0Sbeck filFlags; /* file flags */ 204*f0d9efc0Sbeck SignedByte 205*f0d9efc0Sbeck filTyp; /* file type */ 206*f0d9efc0Sbeck FInfo filUsrWds; /* Finder information */ 207*f0d9efc0Sbeck ULongInt filFlNum; /* file ID */ 208*f0d9efc0Sbeck UInteger filStBlk; /* first alloc block of data fork */ 209*f0d9efc0Sbeck ULongInt filLgLen; /* logical EOF of data fork */ 210*f0d9efc0Sbeck ULongInt filPyLen; /* physical EOF of data fork */ 211*f0d9efc0Sbeck UInteger filRStBlk; /* first alloc block of resource fork */ 212*f0d9efc0Sbeck ULongInt filRLgLen; /* logical EOF of resource fork */ 213*f0d9efc0Sbeck ULongInt filRPyLen; /* physical EOF of resource fork */ 214*f0d9efc0Sbeck LongInt filCrDat; /* date and time of creation */ 215*f0d9efc0Sbeck LongInt filMdDat; /* date and time of last modification */ 216*f0d9efc0Sbeck LongInt filBkDat; /* date and time of last backup */ 217*f0d9efc0Sbeck FXInfo filFndrInfo; /* additional Finder information */ 218*f0d9efc0Sbeck UInteger filClpSize; /* file clump size */ 219*f0d9efc0Sbeck ExtDataRec 220*f0d9efc0Sbeck filExtRec; /* first data fork extent record */ 221*f0d9efc0Sbeck ExtDataRec 222*f0d9efc0Sbeck filRExtRec; /* first resource fork extent record */ 223*f0d9efc0Sbeck LongInt filResrv; /* reserved */ 224*f0d9efc0Sbeck } fil; 225*f0d9efc0Sbeck struct { /* cdrThdRec */ 226*f0d9efc0Sbeck LongInt thdResrv[2]; /* reserved */ 227*f0d9efc0Sbeck ULongInt thdParID; /* parent ID for this directory */ 228*f0d9efc0Sbeck Str31 thdCName; /* name of this directory */ 229*f0d9efc0Sbeck } dthd; 230*f0d9efc0Sbeck struct { /* cdrFThdRec */ 231*f0d9efc0Sbeck LongInt fthdResrv[2]; /* reserved */ 232*f0d9efc0Sbeck ULongInt fthdParID; /* parent ID for this file */ 233*f0d9efc0Sbeck Str31 fthdCName; /* name of this file */ 234*f0d9efc0Sbeck } fthd; 235*f0d9efc0Sbeck } u; 236*f0d9efc0Sbeck } CatDataRec; 237*f0d9efc0Sbeck 238*f0d9efc0Sbeck struct _hfsfile_ { 239*f0d9efc0Sbeck struct _hfsvol_ *vol; /* pointer to volume descriptor */ 240*f0d9efc0Sbeck long parid; /* parent directory ID of this file */ 241*f0d9efc0Sbeck char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */ 242*f0d9efc0Sbeck CatDataRec cat; /* catalog information */ 243*f0d9efc0Sbeck ExtDataRec ext; /* current extent record */ 244*f0d9efc0Sbeck unsigned int fabn; /* starting file allocation block number */ 245*f0d9efc0Sbeck int fork; /* current selected fork for I/O */ 246*f0d9efc0Sbeck unsigned long pos; /* current file seek pointer */ 247*f0d9efc0Sbeck unsigned long clump; /* file's clump size, for allocation */ 248*f0d9efc0Sbeck int flags; /* bit flags */ 249*f0d9efc0Sbeck 250*f0d9efc0Sbeck struct _hfsfile_ *prev; 251*f0d9efc0Sbeck struct _hfsfile_ *next; 252*f0d9efc0Sbeck }; 253*f0d9efc0Sbeck 254*f0d9efc0Sbeck # define HFS_UPDATE_CATREC 0x01 255*f0d9efc0Sbeck 256*f0d9efc0Sbeck typedef struct { 257*f0d9efc0Sbeck ULongInt ndFLink; /* forward link */ 258*f0d9efc0Sbeck ULongInt ndBLink; /* backward link */ 259*f0d9efc0Sbeck SignedByte ndType; /* node type */ 260*f0d9efc0Sbeck SignedByte ndNHeight; /* node level */ 261*f0d9efc0Sbeck UInteger ndNRecs; /* number of records in node */ 262*f0d9efc0Sbeck Integer ndResv2; /* reserved */ 263*f0d9efc0Sbeck } NodeDescriptor; 264*f0d9efc0Sbeck 265*f0d9efc0Sbeck # define HFS_MAXRECS 35 /* maximum based on minimum record size */ 266*f0d9efc0Sbeck 267*f0d9efc0Sbeck typedef struct _node_ { 268*f0d9efc0Sbeck struct _btree_ *bt; /* btree to which this node belongs */ 269*f0d9efc0Sbeck unsigned long nnum; /* node index */ 270*f0d9efc0Sbeck NodeDescriptor nd; /* node descriptor */ 271*f0d9efc0Sbeck int rnum; /* current record index */ 272*f0d9efc0Sbeck UInteger roff[HFS_MAXRECS + 1]; /* record offsets */ 273*f0d9efc0Sbeck block data; /* raw contents of node */ 274*f0d9efc0Sbeck } node; 275*f0d9efc0Sbeck 276*f0d9efc0Sbeck enum { 277*f0d9efc0Sbeck ndIndxNode = 0x00, 278*f0d9efc0Sbeck ndHdrNode = 0x01, 279*f0d9efc0Sbeck ndMapNode = 0x02, 280*f0d9efc0Sbeck ndLeafNode = 0xff 281*f0d9efc0Sbeck }; 282*f0d9efc0Sbeck 283*f0d9efc0Sbeck struct _hfsdir_ { 284*f0d9efc0Sbeck struct _hfsvol_ *vol; /* associated volume */ 285*f0d9efc0Sbeck long dirid; /* directory ID of interest (or 0) */ 286*f0d9efc0Sbeck 287*f0d9efc0Sbeck node n; /* current B*-tree node */ 288*f0d9efc0Sbeck struct _hfsvol_ *vptr; /* current volume pointer */ 289*f0d9efc0Sbeck 290*f0d9efc0Sbeck struct _hfsdir_ *prev; 291*f0d9efc0Sbeck struct _hfsdir_ *next; 292*f0d9efc0Sbeck }; 293*f0d9efc0Sbeck 294*f0d9efc0Sbeck typedef struct { 295*f0d9efc0Sbeck UInteger bthDepth; /* current depth of tree */ 296*f0d9efc0Sbeck ULongInt bthRoot; /* number of root node */ 297*f0d9efc0Sbeck ULongInt bthNRecs; /* number of leaf records in tree */ 298*f0d9efc0Sbeck ULongInt bthFNode; /* number of first leaf node */ 299*f0d9efc0Sbeck ULongInt bthLNode; /* number of last leaf node */ 300*f0d9efc0Sbeck UInteger bthNodeSize; /* size of a node */ 301*f0d9efc0Sbeck UInteger bthKeyLen; /* maximum length of a key */ 302*f0d9efc0Sbeck ULongInt bthNNodes; /* total number of nodes in tree */ 303*f0d9efc0Sbeck ULongInt bthFree; /* number of free nodes */ 304*f0d9efc0Sbeck SignedByte bthResv[76]; /* reserved */ 305*f0d9efc0Sbeck } BTHdrRec; 306*f0d9efc0Sbeck 307*f0d9efc0Sbeck typedef struct _btree_ { 308*f0d9efc0Sbeck hfsfile f; /* subset file information */ 309*f0d9efc0Sbeck node hdrnd; /* header node */ 310*f0d9efc0Sbeck BTHdrRec hdr; /* header record */ 311*f0d9efc0Sbeck char *map; /* usage bitmap */ 312*f0d9efc0Sbeck unsigned long mapsz; /* number of bytes in bitmap */ 313*f0d9efc0Sbeck int flags; /* bit flags */ 314*f0d9efc0Sbeck 315*f0d9efc0Sbeck int (*compare)(unsigned char *, unsigned char *); 316*f0d9efc0Sbeck /* key comparison function */ 317*f0d9efc0Sbeck } btree; 318*f0d9efc0Sbeck 319*f0d9efc0Sbeck # define HFS_UPDATE_BTHDR 0x01 320*f0d9efc0Sbeck 321*f0d9efc0Sbeck struct _hfsvol_ { 322*f0d9efc0Sbeck int fd; /* volume's open file descriptor */ 323*f0d9efc0Sbeck int flags; /* bit flags */ 324*f0d9efc0Sbeck 325*f0d9efc0Sbeck #ifdef APPLE_HYB 326*f0d9efc0Sbeck hce_mem *hce; /* Extras needed by libhfs/mkisofs */ 327*f0d9efc0Sbeck #endif /* APPLE_HYB */ 328*f0d9efc0Sbeck 329*f0d9efc0Sbeck int pnum; /* ordinal HFS partition number */ 330*f0d9efc0Sbeck unsigned long vstart; /* logical block offset to start of volume */ 331*f0d9efc0Sbeck unsigned long vlen; /* number of logical blocks in volume */ 332*f0d9efc0Sbeck unsigned int lpa; /* number of logical blocks per allocation block */ 333*f0d9efc0Sbeck 334*f0d9efc0Sbeck MDB mdb; /* master directory block */ 335*f0d9efc0Sbeck block *vbm; /* volume bit map */ 336*f0d9efc0Sbeck btree ext; /* B*-tree control block for extents overflow file */ 337*f0d9efc0Sbeck btree cat; /* B*-tree control block for catalog file */ 338*f0d9efc0Sbeck long cwd; /* directory id of current working directory */ 339*f0d9efc0Sbeck 340*f0d9efc0Sbeck int refs; /* number of external references to this volume */ 341*f0d9efc0Sbeck hfsfile *files; /* list of open files */ 342*f0d9efc0Sbeck hfsdir *dirs; /* list of open directories */ 343*f0d9efc0Sbeck 344*f0d9efc0Sbeck struct _hfsvol_ *prev; 345*f0d9efc0Sbeck struct _hfsvol_ *next; 346*f0d9efc0Sbeck }; 347*f0d9efc0Sbeck 348*f0d9efc0Sbeck # define HFS_READONLY 0x01 349*f0d9efc0Sbeck 350*f0d9efc0Sbeck # define HFS_UPDATE_MDB 0x10 351*f0d9efc0Sbeck # define HFS_UPDATE_ALTMDB 0x20 352*f0d9efc0Sbeck # define HFS_UPDATE_VBM 0x40 353*f0d9efc0Sbeck 354*f0d9efc0Sbeck extern hfsvol *hfs_mounts; 355*f0d9efc0Sbeck extern hfsvol *hfs_curvol; 356