diff options
author | Aaron M. Ucko <ucko@debian.org> | 2005-03-23 20:19:28 +0000 |
---|---|---|
committer | Aaron M. Ucko <ucko@debian.org> | 2005-03-23 20:19:28 +0000 |
commit | c36b9906c3ef791147b3643f9e485cc02568819f (patch) | |
tree | 97b50039b1b1666f165eb1b05713b820e11b09bd /corelib | |
parent | 8db608ab43e4a775576ba5ff61add11d231de4b4 (diff) |
Load ncbi (6.1.20020426) into ncbi-tools6/branches/upstream/current.
Diffstat (limited to 'corelib')
-rw-r--r-- | corelib/morefile/FSpCompat.c | 946 | ||||
-rw-r--r-- | corelib/morefile/FSpCompat.h | 586 | ||||
-rw-r--r-- | corelib/morefile/FullPath.c | 282 | ||||
-rw-r--r-- | corelib/morefile/FullPath.h | 311 | ||||
-rw-r--r-- | corelib/morefile/MoreFilesExtras.h | 3597 | ||||
-rw-r--r-- | corelib/morefile/MoreFilesX.c | 2782 | ||||
-rw-r--r-- | corelib/morefile/MoreFilesX.h | 1804 | ||||
-rw-r--r-- | corelib/morefile/Optimization.h | 109 | ||||
-rw-r--r-- | corelib/morefile/OptimizationEnd.h | 56 | ||||
-rw-r--r-- | corelib/ncbibs.c | 7 | ||||
-rw-r--r-- | corelib/ncbienv.c | 13 | ||||
-rw-r--r-- | corelib/ncbifile.c | 7 | ||||
-rw-r--r-- | corelib/ncbilcl.dwn | 14 | ||||
-rw-r--r-- | corelib/ncbilcl.hlx | 158 | ||||
-rw-r--r-- | corelib/ncbilcl.hp_ia64 | 151 | ||||
-rw-r--r-- | corelib/ncbilcl.hp_pa | 23 | ||||
-rw-r--r-- | corelib/ncbimem.c | 44 | ||||
-rw-r--r-- | corelib/ncbimem.h | 28 | ||||
-rw-r--r-- | corelib/ncbistr.c | 21 | ||||
-rw-r--r-- | corelib/ncbistr.h | 11 | ||||
-rw-r--r-- | corelib/ncbithr.c | 8 | ||||
-rw-r--r-- | corelib/ncbiwin.h | 12 | ||||
-rw-r--r-- | corelib/ncbiwww.h | 291 | ||||
-rw-r--r-- | corelib/tsprintf.c | 100 | ||||
-rw-r--r-- | corelib/wwwutils.c | 1064 |
25 files changed, 11827 insertions, 598 deletions
diff --git a/corelib/morefile/FSpCompat.c b/corelib/morefile/FSpCompat.c new file mode 100644 index 00000000..17577684 --- /dev/null +++ b/corelib/morefile/FSpCompat.c @@ -0,0 +1,946 @@ +/* + File: FSpCompat.c + + Contains: FSSpec compatibility functions. + + Version: MoreFiles + + Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved. + + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: Apple Macintosh Developer Technical Support + <http://developer.apple.com/bugreporter/> + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <2> 2/7/01 JL Added standard header. Updated names of includes. Updated + various routines to use new calling convention of the + MoreFilesExtras accessor functions. + <1> 12/06/99 JL MoreFiles 1.5. +*/ + +/* +** If building application 68K code, set GENERATENODATA to 0 for faster code. +** If building stand-alone 68K code, set GENERATENODATA to 1 so globals +** (static variables) are not used. +*/ +#ifndef GENERATENODATA +#define GENERATENODATA 0 +#endif + +#include <MacTypes.h> +#include <MacErrors.h> +#include <Files.h> +#include <LowMem.h> +#include <Gestalt.h> +#include <Resources.h> +#include <Script.h> + +#define __COMPILINGMOREFILES + +#include "MoreFilesExtras.h" +#include "FSpCompat.h" + +/*****************************************************************************/ + +/* local constants */ + +enum { + gestaltBugFixAttrsTwo = 'bugy', + gestaltFSpExchangeFilesCompatibilityFix = 26, + gestaltBugFixAttrsThree = 'bugx', + gestaltFSpCreateScriptSupportFix = 1 +}; + +/*****************************************************************************/ + +/* static prototypes */ + + +#if !__MACOSSEVENORLATER +static Boolean FSHasFSSpecCalls(void); + +static Boolean QTHasFSSpecCalls(void); +#endif /* !__MACOSSEVENORLATER */ + +#if !__MACOSSEVENFIVEORLATER +static Boolean HasFSpExchangeFilesCompatibilityFix(void); + +static OSErr GenerateUniqueName(short volume, + long *startSeed, + long dir1, + long dir2, + StringPtr uniqueName); +#endif /* !__MACOSSEVENFIVEORLATER */ + +#if !__MACOSSEVENFIVEONEORLATER +static Boolean HasFSpCreateScriptSupportFix(void); +#endif /* !__MACOSSEVENFIVEONEORLATER */ + +/*****************************************************************************/ + +/* FSHasFSSpecCalls returns true if the file system provides FSSpec calls. */ + +#if !__MACOSSEVENORLATER +static Boolean FSHasFSSpecCalls(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif + if ( Gestalt(gestaltFSAttr, &response) == noErr ) + { + result = ((response & (1L << gestaltHasFSSpecCalls)) != 0); + } +#if !GENERATENODATA + } +#endif + return ( result ); +} +#endif /* !__MACOSSEVENORLATER */ + +/*****************************************************************************/ + +/* QTHasFSSpecCalls returns true if QuickTime provides FSSpec calls */ +/* except for FSpExchangeFiles. */ + +#if !__MACOSSEVENORLATER +static Boolean QTHasFSSpecCalls(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif + result = (Gestalt(gestaltQuickTimeVersion, &response) == noErr); +#if !GENERATENODATA + } +#endif + return ( result ); +} +#endif /* !__MACOSSEVENORLATER */ + +/*****************************************************************************/ + +/* HasFSpExchangeFilesCompatibilityFix returns true if FSpExchangeFiles */ +/* compatibility code has been fixed in system software. */ +/* This was fixed by System Update 3.0, so if SystemSevenFiveOrLater */ +/* is true, then we know the fix is in. */ + +#if !__MACOSSEVENFIVEORLATER +static Boolean HasFSpExchangeFilesCompatibilityFix(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else /* !GENERATENODATA */ + Boolean result = false; +#endif /* !GENERATENODATA */ + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif /* !GENERATENODATA */ + if ( Gestalt(gestaltBugFixAttrsTwo, &response) == noErr ) + { + result = ((response & (1L << gestaltFSpExchangeFilesCompatibilityFix)) != 0); + } +#if !GENERATENODATA + } +#endif /* !GENERATENODATA */ + return ( result ); +} +#endif /* !__MACOSSEVENFIVEORLATER */ + +/*****************************************************************************/ + +/* HasFSpCreateScriptSupportFix returns true if FSpCreate and */ +/* FSpCreateResFile have been fixed in system software to correctly set */ +/* the scriptCode in the volume's catalog. */ +/* This was fixed by System 7.5 Update 1.0 */ + +#if !__MACOSSEVENFIVEONEORLATER +static Boolean HasFSpCreateScriptSupportFix(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif /* !GENERATENODATA */ + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif /* !GENERATENODATA */ + if ( Gestalt(gestaltBugFixAttrsThree, &response) == noErr ) + { + result = ((response & (1L << gestaltFSpCreateScriptSupportFix)) != 0); + } +#if !GENERATENODATA + } +#endif /* !GENERATENODATA */ + return ( result ); +} +#endif /* !__MACOSSEVENFIVEONEORLATER */ + +/*****************************************************************************/ + +/* +** File Manager FSp calls +*/ + +/*****************************************************************************/ + +pascal OSErr FSMakeFSSpecCompat(short vRefNum, + long dirID, + ConstStr255Param fileName, + FSSpec *spec) +{ + OSErr result; + +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + Boolean isDirectory; + + result = GetObjectLocation(vRefNum, dirID, fileName, + &(spec->vRefNum), &(spec->parID), spec->name, + &isDirectory); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + /* Let the file system create the FSSpec if it can since it does the job */ + /* much more efficiently than I can. */ + result = FSMakeFSSpec(vRefNum, dirID, fileName, spec); + + /* Fix a bug in Macintosh PC Exchange's MakeFSSpec code where 0 is */ + /* returned in the parID field when making an FSSpec to the volume's */ + /* root directory by passing a full pathname in MakeFSSpec's */ + /* fileName parameter. Fixed in Mac OS 8.1 */ + if ( (result == noErr) && (spec->parID == 0) ) + spec->parID = fsRtParID; + } + return ( result ); +} + +/*****************************************************************************/ + +pascal OSErr FSpOpenDFCompat(const FSSpec *spec, + char permission, + short *refNum) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + OSErr result; + HParamBlockRec pb; + + pb.ioParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.ioParam.ioNamePtr = (StringPtr) &(spec->name); + pb.ioParam.ioVersNum = 0; + pb.ioParam.ioPermssn = permission; + pb.ioParam.ioMisc = NULL; + result = PBHOpenSync(&pb); /* OpenDF not supported by System 6, so use Open */ + *refNum = pb.ioParam.ioRefNum; + return ( result ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpOpenDF(spec, permission, refNum) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpOpenRFCompat(const FSSpec *spec, + char permission, + short *refNum) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + OSErr result; + HParamBlockRec pb; + + pb.ioParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.ioParam.ioNamePtr = (StringPtr) &(spec->name); + pb.ioParam.ioVersNum = 0; + pb.ioParam.ioPermssn = permission; + pb.ioParam.ioMisc = NULL; + result = PBHOpenRFSync(&pb); + *refNum = pb.ioParam.ioRefNum; + return ( result ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpOpenRF(spec, permission, refNum) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpCreateCompat(const FSSpec *spec, + OSType creator, + OSType fileType, + ScriptCode scriptTag) +{ +#if !__MACOSSEVENFIVEONEORLATER + OSErr result; + UniversalFMPB pb; + + + if ( +#if !__MACOSSEVENORLATER + (!FSHasFSSpecCalls() && !QTHasFSSpecCalls()) || +#endif /* !__MACOSSEVENORLATER */ + !HasFSpCreateScriptSupportFix() ) + { + /* If FSpCreate isn't called, this code will be executed */ + pb.hPB.fileParam.ioVRefNum = spec->vRefNum; + pb.hPB.fileParam.ioDirID = spec->parID; + pb.hPB.fileParam.ioNamePtr = (StringPtr) &(spec->name); + pb.hPB.fileParam.ioFVersNum = 0; + result = PBHCreateSync(&(pb.hPB)); + if ( result == noErr ) + { + /* get info on created item */ + pb.ciPB.hFileInfo.ioFDirIndex = 0; + result = PBGetCatInfoSync(&(pb.ciPB)); + if ( result == noErr ) + { + /* Set fdScript in FXInfo */ + /* The negative script constants (smSystemScript, smCurrentScript, and smAllScripts) */ + /* don't make sense on disk, so only use scriptTag if scriptTag >= smRoman */ + /* (smRoman is 0). fdScript is valid if high bit is set (see IM-6, page 9-38) */ + pb.ciPB.hFileInfo.ioFlXFndrInfo.fdScript = (scriptTag >= smRoman) ? + ((char)scriptTag | (char)0x80) : + (smRoman); + /* Set creator/fileType */ + pb.ciPB.hFileInfo.ioFlFndrInfo.fdCreator = creator; + pb.ciPB.hFileInfo.ioFlFndrInfo.fdType = fileType; + /* Restore ioDirID field in pb which was changed by PBGetCatInfo */ + pb.ciPB.hFileInfo.ioDirID = spec->parID; + result = PBSetCatInfoSync(&(pb.ciPB)); + } + } + return ( result ); + } + else +#endif /* !__MACOSSEVENFIVEONEORLATER */ + { + return ( FSpCreate(spec, creator, fileType, scriptTag) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpDirCreateCompat(const FSSpec *spec, + ScriptCode scriptTag, + long *createdDirID) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + OSErr result; + UniversalFMPB pb; + + pb.hPB.fileParam.ioVRefNum = spec->vRefNum; + pb.hPB.fileParam.ioDirID = spec->parID; + pb.hPB.fileParam.ioNamePtr = (StringPtr) &(spec->name); + result = PBDirCreateSync(&(pb.hPB)); + *createdDirID = pb.hPB.fileParam.ioDirID; + if ( result == noErr ) + { + /* get info on created item */ + pb.ciPB.dirInfo.ioFDirIndex = 0; + pb.ciPB.dirInfo.ioDrDirID = spec->parID; + result = PBGetCatInfoSync(&(pb.ciPB)); + if ( result == noErr ) + { + /* Set frScript in DXInfo */ + /* The negative script constants (smSystemScript, smCurrentScript, and smAllScripts) */ + /* don't make sense on disk, so only use scriptTag if scriptTag >= smRoman */ + /* (smRoman is 0). frScript is valid if high bit is set (see IM-6, page 9-38) */ + pb.ciPB.dirInfo.ioDrFndrInfo.frScript = (scriptTag >= smRoman) ? + ((char)scriptTag | (char)0x80) : + (smRoman); + /* Restore ioDirID field in pb which was changed by PBGetCatInfo */ + pb.ciPB.dirInfo.ioDrDirID = spec->parID; + result = PBSetCatInfoSync(&(pb.ciPB)); + } + } + return ( result ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpDirCreate(spec, scriptTag, createdDirID) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpDeleteCompat(const FSSpec *spec) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + HParamBlockRec pb; + + pb.ioParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.ioParam.ioNamePtr = (StringPtr) &(spec->name); + pb.ioParam.ioVersNum = 0; + return ( PBHDeleteSync(&pb) ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpDelete(spec) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpGetFInfoCompat(const FSSpec *spec, + FInfo *fndrInfo) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + OSErr result; + HParamBlockRec pb; + + pb.fileParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.fileParam.ioNamePtr = (StringPtr) &(spec->name); + pb.fileParam.ioFVersNum = 0; + pb.fileParam.ioFDirIndex = 0; + result = PBHGetFInfoSync(&pb); + *fndrInfo = pb.fileParam.ioFlFndrInfo; + return ( result ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpGetFInfo(spec, fndrInfo) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpSetFInfoCompat(const FSSpec *spec, + const FInfo *fndrInfo) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + OSErr result; + HParamBlockRec pb; + + pb.fileParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.fileParam.ioNamePtr = (StringPtr) &(spec->name); + pb.fileParam.ioFVersNum = 0; + pb.fileParam.ioFDirIndex = 0; + result = PBHGetFInfoSync(&pb); + if ( result == noErr ) + { + pb.fileParam.ioFlFndrInfo = *fndrInfo; + pb.fileParam.ioDirID = spec->parID; + result = PBHSetFInfoSync(&pb); + } + return ( result ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpSetFInfo(spec, fndrInfo) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpSetFLockCompat(const FSSpec *spec) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + HParamBlockRec pb; + + pb.fileParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.fileParam.ioNamePtr = (StringPtr) &(spec->name); + pb.fileParam.ioFVersNum = 0; + return ( PBHSetFLockSync(&pb) ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpSetFLock(spec) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpRstFLockCompat(const FSSpec *spec) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + HParamBlockRec pb; + + pb.fileParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.fileParam.ioNamePtr = (StringPtr) &(spec->name); + pb.fileParam.ioFVersNum = 0; + return ( PBHRstFLockSync(&pb) ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpRstFLock(spec) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpRenameCompat(const FSSpec *spec, + ConstStr255Param newName) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + HParamBlockRec pb; + + pb.ioParam.ioVRefNum = spec->vRefNum; + pb.fileParam.ioDirID = spec->parID; + pb.ioParam.ioNamePtr = (StringPtr) &(spec->name); + pb.ioParam.ioVersNum = 0; + pb.ioParam.ioMisc = (Ptr) newName; + return ( PBHRenameSync(&pb) ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpRename(spec, newName) ); + } +} + +/*****************************************************************************/ + +pascal OSErr FSpCatMoveCompat(const FSSpec *source, + const FSSpec *dest) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + CMovePBRec pb; + + /* source and destination volume must be the same */ + if ( source->vRefNum != dest->vRefNum ) + return ( paramErr ); + + pb.ioNamePtr = (StringPtr) &(source->name); + pb.ioVRefNum = source->vRefNum; + pb.ioDirID = source->parID; + pb.ioNewDirID = dest->parID; + pb.ioNewName = (StringPtr) &(dest->name); + return ( PBCatMoveSync(&pb) ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpCatMove(source, dest) ); + } +} + +/*****************************************************************************/ + +/* GenerateUniqueName generates a name that is unique in both dir1 and dir2 */ +/* on the specified volume. Ripped off from Feldman's code. */ + +#if !__MACOSSEVENFIVEORLATER +static OSErr GenerateUniqueName(short volume, + long *startSeed, + long dir1, + long dir2, + StringPtr uniqueName) +{ + OSErr error = noErr; + long i; + CInfoPBRec cinfo; + unsigned char hexStr[16]; + + for ( i = 0; i < 16; ++i ) + { + if ( i < 10 ) + { + hexStr[i] = 0x30 + i; + } + else + { + hexStr[i] = 0x37 + i; + } + } + + cinfo.hFileInfo.ioVRefNum = volume; + cinfo.hFileInfo.ioFDirIndex = 0; + cinfo.hFileInfo.ioNamePtr = uniqueName; + + while ( error != fnfErr ) + { + (*startSeed)++; + cinfo.hFileInfo.ioNamePtr[0] = 8; + for ( i = 1; i <= 8; i++ ) + { + cinfo.hFileInfo.ioNamePtr[i] = hexStr[((*startSeed >> ((8-i)*4)) & 0xf)]; + } + cinfo.hFileInfo.ioDirID = dir1; + error = fnfErr; + for ( i = 1; i <= 2; i++ ) + { + error = error & PBGetCatInfoSync(&cinfo); + cinfo.hFileInfo.ioDirID = dir2; + if ( (error != fnfErr) && (error != noErr) ) + { + return ( error ); + } + } + } + return ( noErr ); +} +#endif /* !__MACOSSEVENFIVEORLATER */ + +/*****************************************************************************/ + +pascal OSErr FSpExchangeFilesCompat(const FSSpec *source, + const FSSpec *dest) +{ +#if !__MACOSSEVENFIVEORLATER + if ( +#if !__MACOSSEVENORLATER + !FSHasFSSpecCalls() || +#endif /* !__MACOSSEVENORLATER */ + !HasFSpExchangeFilesCompatibilityFix() ) + { + HParamBlockRec pb; + CInfoPBRec catInfoSource, catInfoDest; + OSErr result, result2; + Str31 unique1, unique2; + StringPtr unique1Ptr, unique2Ptr, swapola; + GetVolParmsInfoBuffer volInfo; + long theSeed, temp; + + /* Make sure the source and destination are on the same volume */ + if ( source->vRefNum != dest->vRefNum ) + { + result = diffVolErr; + goto errorExit3; + } + + /* Try PBExchangeFiles first since it preserves the file ID reference */ + pb.fidParam.ioNamePtr = (StringPtr) &(source->name); + pb.fidParam.ioVRefNum = source->vRefNum; + pb.fidParam.ioDestNamePtr = (StringPtr) &(dest->name); + pb.fidParam.ioDestDirID = dest->parID; + pb.fidParam.ioSrcDirID = source->parID; + + result = PBExchangeFilesSync(&pb); + + /* Note: The compatibility case won't work for files with *Btree control blocks. */ + /* Right now the only *Btree files are created by the system. */ + if ( result != noErr ) + { + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioBuffer = (Ptr) &volInfo; + pb.ioParam.ioReqCount = sizeof(volInfo); + result2 = PBHGetVolParmsSync(&pb); + + /* continue if volume has no fileID support (or no GetVolParms support) */ + if ( (result2 == noErr) && hasFileIDs(&volInfo) ) + { + goto errorExit3; + } + + /* Get the catalog information for each file */ + /* and make sure both files are *really* files */ + catInfoSource.hFileInfo.ioVRefNum = source->vRefNum; + catInfoSource.hFileInfo.ioFDirIndex = 0; + catInfoSource.hFileInfo.ioNamePtr = (StringPtr) &(source->name); + catInfoSource.hFileInfo.ioDirID = source->parID; + catInfoSource.hFileInfo.ioACUser = 0; /* ioACUser used to be filler2 */ + result = PBGetCatInfoSync(&catInfoSource); + if ( result != noErr ) + { + goto errorExit3; + } + if ( (catInfoSource.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) + { + result = notAFileErr; + goto errorExit3; + } + + catInfoDest.hFileInfo.ioVRefNum = dest->vRefNum; + catInfoDest.hFileInfo.ioFDirIndex = 0; + catInfoDest.hFileInfo.ioNamePtr = (StringPtr) &(dest->name); + catInfoDest.hFileInfo.ioDirID = dest->parID; + catInfoDest.hFileInfo.ioACUser = 0; /* ioACUser used to be filler2 */ + result = PBGetCatInfoSync(&catInfoDest); + if ( result != noErr ) + { + goto errorExit3; + } + if ( (catInfoDest.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) + { + result = notAFileErr; + goto errorExit3; + } + + /* generate 2 filenames that are unique in both directories */ + theSeed = 0x64666A6C; /* a fine unlikely filename */ + unique1Ptr = (StringPtr)&unique1; + unique2Ptr = (StringPtr)&unique2; + + result = GenerateUniqueName(source->vRefNum, &theSeed, source->parID, dest->parID, unique1Ptr); + if ( result != noErr ) + { + goto errorExit3; + } + + GenerateUniqueName(source->vRefNum, &theSeed, source->parID, dest->parID, unique2Ptr); + if ( result != noErr ) + { + goto errorExit3; + } + + /* rename source to unique1 */ + pb.fileParam.ioNamePtr = (StringPtr) &(source->name); + pb.ioParam.ioMisc = (Ptr) unique1Ptr; + pb.ioParam.ioVersNum = 0; + result = PBHRenameSync(&pb); + if ( result != noErr ) + { + goto errorExit3; + } + + /* rename dest to unique2 */ + pb.ioParam.ioMisc = (Ptr) unique2Ptr; + pb.ioParam.ioVersNum = 0; + pb.fileParam.ioNamePtr = (StringPtr) &(dest->name); + pb.fileParam.ioDirID = dest->parID; + result = PBHRenameSync(&pb); + if ( result != noErr ) + { + goto errorExit2; /* back out gracefully by renaming unique1 back to source */ + } + + /* If files are not in same directory, swap their locations */ + if ( source->parID != dest->parID ) + { + /* move source file to dest directory */ + pb.copyParam.ioNamePtr = unique1Ptr; + pb.copyParam.ioNewName = NULL; + pb.copyParam.ioNewDirID = dest->parID; + pb.copyParam.ioDirID = source->parID; + result = PBCatMoveSync((CMovePBPtr) &pb); + if ( result != noErr ) + { + goto errorExit1; /* back out gracefully by renaming both files to original names */ + } + + /* move dest file to source directory */ + pb.copyParam.ioNamePtr = unique2Ptr; + pb.copyParam.ioNewDirID = source->parID; + pb.copyParam.ioDirID = dest->parID; + result = PBCatMoveSync((CMovePBPtr) &pb); + if ( result != noErr) + { + /* life is very bad. We'll at least try to move source back */ + pb.copyParam.ioNamePtr = unique1Ptr; + pb.copyParam.ioNewName = NULL; + pb.copyParam.ioNewDirID = source->parID; + pb.copyParam.ioDirID = dest->parID; + (void) PBCatMoveSync((CMovePBPtr) &pb); /* ignore errors */ + goto errorExit1; /* back out gracefully by renaming both files to original names */ + } + } + + /* Make unique1Ptr point to file in source->parID */ + /* and unique2Ptr point to file in dest->parID */ + /* This lets us fall through to the rename code below */ + swapola = unique1Ptr; + unique1Ptr = unique2Ptr; + unique2Ptr = swapola; + + /* At this point, the files are in their new locations (if they were moved) */ + /* Source is named Unique1 (name pointed to by unique2Ptr) and is in dest->parID */ + /* Dest is named Unique2 (name pointed to by unique1Ptr) and is in source->parID */ + /* Need to swap attributes except mod date and swap names */ + + /* swap the catalog info by re-aiming the CInfoPB's */ + catInfoSource.hFileInfo.ioNamePtr = unique1Ptr; + catInfoDest.hFileInfo.ioNamePtr = unique2Ptr; + + catInfoSource.hFileInfo.ioDirID = source->parID; + catInfoDest.hFileInfo.ioDirID = dest->parID; + + /* Swap the original mod dates with each file */ + temp = catInfoSource.hFileInfo.ioFlMdDat; + catInfoSource.hFileInfo.ioFlMdDat = catInfoDest.hFileInfo.ioFlMdDat; + catInfoDest.hFileInfo.ioFlMdDat = temp; + + /* Here's the swap (ignore errors) */ + (void) PBSetCatInfoSync(&catInfoSource); + (void) PBSetCatInfoSync(&catInfoDest); + + /* rename unique2 back to dest */ +errorExit1: + pb.ioParam.ioMisc = (Ptr) &(dest->name); + pb.ioParam.ioVersNum = 0; + pb.fileParam.ioNamePtr = unique2Ptr; + pb.fileParam.ioDirID = dest->parID; + (void) PBHRenameSync(&pb); /* ignore errors */ + + /* rename unique1 back to source */ +errorExit2: + pb.ioParam.ioMisc = (Ptr) &(source->name); + pb.ioParam.ioVersNum = 0; + pb.fileParam.ioNamePtr = unique1Ptr; + pb.fileParam.ioDirID = source->parID; + (void) PBHRenameSync(&pb); /* ignore errors */ + } +errorExit3: { /* null statement */ } + return ( result ); + } + else +#endif /* !__MACOSSEVENFIVEORLATER */ + { + return ( FSpExchangeFiles(source, dest) ); + } +} + +/*****************************************************************************/ + +/* +** Resource Manager FSp calls +*/ + +/*****************************************************************************/ + +pascal short FSpOpenResFileCompat(const FSSpec *spec, + SignedByte permission) +{ +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + return ( HOpenResFile(spec->vRefNum, spec->parID, spec->name, permission) ); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + return ( FSpOpenResFile(spec, permission) ); + } +} + +/*****************************************************************************/ + +pascal void FSpCreateResFileCompat(const FSSpec *spec, + OSType creator, + OSType fileType, + ScriptCode scriptTag) +{ +#if !__MACOSSEVENFIVEONEORLATER + if ( +#if !__MACOSSEVENORLATER + (!FSHasFSSpecCalls() && !QTHasFSSpecCalls()) || +#endif /* !__MACOSSEVENORLATER */ + !HasFSpCreateScriptSupportFix() ) + { + OSErr result; + CInfoPBRec pb; + + HCreateResFile(spec->vRefNum, spec->parID, spec->name); + if ( ResError() == noErr ) + { + /* get info on created item */ + pb.hFileInfo.ioVRefNum = spec->vRefNum; + pb.hFileInfo.ioDirID = spec->parID; + pb.hFileInfo.ioNamePtr = (StringPtr) &(spec->name); + pb.hFileInfo.ioFDirIndex = 0; + result = PBGetCatInfoSync(&pb); + if ( result == noErr ) + { + /* Set fdScript in FXInfo */ + /* The negative script constants (smSystemScript, smCurrentScript, and smAllScripts) */ + /* don't make sense on disk, so only use scriptTag if scriptTag >= smRoman */ + /* (smRoman is 0). fdScript is valid if high bit is set (see IM-6, page 9-38) */ + pb.hFileInfo.ioFlXFndrInfo.fdScript = (scriptTag >= smRoman) ? + ((char)scriptTag | (char)0x80) : + (smRoman); + /* Set creator/fileType */ + pb.hFileInfo.ioFlFndrInfo.fdCreator = creator; + pb.hFileInfo.ioFlFndrInfo.fdType = fileType; + + /* Restore ioDirID field in pb which was changed by PBGetCatInfo */ + pb.hFileInfo.ioDirID = spec->parID; + result = PBSetCatInfoSync(&pb); + } + /* Set ResErr low memory global to result */ + LMSetResErr(result); + } + return; + } + else +#endif /* !__MACOSSEVENFIVEONEORLATER */ + { + FSpCreateResFile(spec, creator, fileType, scriptTag); + return; + } +} + +/*****************************************************************************/ diff --git a/corelib/morefile/FSpCompat.h b/corelib/morefile/FSpCompat.h new file mode 100644 index 00000000..eb90ba8d --- /dev/null +++ b/corelib/morefile/FSpCompat.h @@ -0,0 +1,586 @@ +/* + File: FSpCompat.h + + Contains: FSSpec compatibility functions. + + Version: Technology: MoreFiles + Release: 1.5.2 + + Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved. + + Bugs?: For bug reports, consult the following page on + the World Wide Web: + + http://developer.apple.com/bugreporter/ + +*/ + +/* + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. +*/ + +#ifndef __FSPCOMPAT__ +#define __FSPCOMPAT__ + +#ifndef __MACTYPES__ +#include <MacTypes.h> +#endif + +#ifndef __FILES__ +#include <Files.h> +#endif + +#include "Optimization.h" + + +#if PRAGMA_ONCE +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=mac68k +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(push, 2) +#elif PRAGMA_STRUCT_PACK + #pragma pack(2) +#endif + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSMakeFSSpecCompat( + short vRefNum, + long dirID, + ConstStr255Param fileName, + FSSpec * spec); + + +/* + The FSMakeFSSpecCompat function fills in the fields of an FSSpec record. + If the file system can't create the FSSpec, then the compatibility code + creates a FSSpec that is exactly like an FSSpec except that spec.name + for a file may not have the same capitalization as the file's catalog + entry on the disk volume. That is because fileName is parsed to get the + name instead of getting the name back from the file system. This works + fine with System 6 where FSMakeSpec isn't available. + + vRefNum input: Volume specification. + dirID input: Directory ID. + fileName input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + spec output: A file system specification to be filled in by + FSMakeFSSpecCompat. + + Result Codes + noErr 0 No error + nsvErr -35 Volume doesn¹t exist + fnfErr -43 File or directory does not exist + (FSSpec is still valid) +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpOpenDFCompat( + const FSSpec * spec, + char permission, + short * refNum); + + +/* + The FSpOpenDFCompat function opens the data fork of the file specified + by spec. + Differences from FSpOpenDF: If FSpOpenDF isn't available, + FSpOpenDFCompat uses PHBOpen because System 6 doesn't support PBHOpenDF. + This means FSpOpenDFCompat could accidentally open a driver if the + spec->name begins with a period. + + spec input: An FSSpec record specifying the file whose data + fork is to be opened. + permission input: A constant indicating the desired file access + permissions. + refNum output: A reference number of an access path to the file's + data fork. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + tmfoErr -42 Too many files open + fnfErr -43 File not found + opWrErr -49 File already open for writing + permErr -54 Attempt to open locked file for writing + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access to + the file + + __________ + + See also: FSpOpenAware +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpOpenRFCompat( + const FSSpec * spec, + char permission, + short * refNum); + + +/* + The FSpOpenRFCompat function opens the resource fork of the file + specified by spec. + + spec input: An FSSpec record specifying the file whose resource + fork is to be opened. + permission input: A constant indicating the desired file access + permissions. + refNum output: A reference number of an access path to the file's + resource fork. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + tmfoErr -42 Too many files open + fnfErr -43 File not found + opWrErr -49 File already open for writing + permErr -54 Attempt to open locked file for writing + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access to + the file + + __________ + + See also: FSpOpenRFAware +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpCreateCompat( + const FSSpec * spec, + OSType creator, + OSType fileType, + ScriptCode scriptTag); + + +/* + The FSpCreateCompat function creates a new file with the specified + type, creator, and script code. + Differences from FSpCreate: FSpCreateCompat correctly sets the + fdScript in the file's FXInfo record to scriptTag if the problem + isn't fixed in the File Manager code. + + spec input: An FSSpec record specifying the file to create. + creator input: The creator of the new file. + fileType input The file type of the new file. + scriptCode input: The code of the script system in which the file + name is to be displayed. + + Result Codes + noErr 0 No error + dirFulErr -33 File directory full + dskFulErr -34 Disk is full + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 Directory not found or incomplete pathname + wPrErr -44 Hardware volume lock + vLckdErr -46 Software volume lock + dupFNErr -48 Duplicate filename and version + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 A directory exists with that name +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpDirCreateCompat( + const FSSpec * spec, + ScriptCode scriptTag, + long * createdDirID); + + +/* + The FSpDirCreateCompat function creates a new directory and returns the + directory ID of the newDirectory. + + spec input: An FSSpec record specifying the directory to + create. + scriptCode input: The code of the script system in which the + directory name is to be displayed. + createdDirID output: The directory ID of the directory that was + created. + + Result Codes + noErr 0 No error + dirFulErr -33 File directory full + dskFulErr -34 Disk is full + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 Directory not found or incomplete pathname + wPrErr -44 Hardware volume lock + vLckdErr -46 Software volume lock + dupFNErr -48 Duplicate filename and version + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + wrgVolTypErr -123 Not an HFS volume + afpAccessDenied -5000 User does not have the correct access +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpDeleteCompat(const FSSpec * spec); + + +/* + The FSpDeleteCompat function deletes a file or directory. + + spec input: An FSSpec record specifying the file or + directory to delete. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + fBsyErr -47 File busy, directory not empty, or + working directory control block open + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpGetFInfoCompat( + const FSSpec * spec, + FInfo * fndrInfo); + + +/* + The FSpGetFInfoCompat function gets the finder information for a file. + + spec input: An FSSpec record specifying the file. + fndrInfo output: If the object is a file, then its FInfo. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: FSpGetDInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetFInfoCompat( + const FSSpec * spec, + const FInfo * fndrInfo); + + +/* + The FSpSetFInfoCompat function sets the finder information for a file. + + spec input: An FSSpec record specifying the file. + fndrInfo input: The FInfo. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Object was a directory + + __________ + + Also see: FSpSetDInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetFLockCompat(const FSSpec * spec); + + +/* + The FSpSetFLockCompat function locks a file. + + spec input: An FSSpec record specifying the file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + vLckdErr -46 Software volume lock + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access to + the file + afpObjectTypeErr -5025 Folder locking not supported by volume +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpRstFLockCompat(const FSSpec * spec); + + +/* + The FSpRstFLockCompat function unlocks a file. + + spec input: An FSSpec record specifying the file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + vLckdErr -46 Software volume lock + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access to + the file + afpObjectTypeErr -5025 Folder locking not supported by volume +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpRenameCompat( + const FSSpec * spec, + ConstStr255Param newName); + + +/* + The FSpRenameCompat function renames a file or directory. + + spec input: An FSSpec record specifying the file. + newName input: The new name of the file or directory. + + Result Codes + noErr 0 No error + dirFulErr -33 File directory full + dskFulErr -34 Volume is full + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + dupFNErr -48 Duplicate filename and version + paramErr -50 No default volume + fsRnErr -59 Problem during rename + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access to + the file +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpCatMoveCompat( + const FSSpec * source, + const FSSpec * dest); + + +/* + The FSpCatMoveCompat function moves a file or directory to a different + location on on the same volume. + + source input: An FSSpec record specifying the file or directory. + dest input: An FSSpec record specifying the name and location + of the directory into which the source file or + directory is to be moved. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename or attempt to move into + a file + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + fLckdErr -45 Target directory is locked + vLckdErr -46 Software volume lock + dupFNErr -48 Duplicate filename and version + paramErr -50 No default volume + badMovErr -122 Attempt to move into offspring + wrgVolTypErr -123 Not an HFS volume + afpAccessDenied -5000 User does not have the correct access to + the file +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpExchangeFilesCompat( + const FSSpec * source, + const FSSpec * dest); + + +/* + The FSpExchangeFilesCompat function swaps the data in two files by + changing the information in the volume's catalog and, if the files + are open, in the file control blocks. + Differences from FSpExchangeFiles: Correctly exchanges files on volumes + that don't support PBExchangeFiles. FSpExchangeFiles attempts to support + volumes that don't support PBExchangeFiles, but in System 7, 7.0.1, 7.1, + and 7 Pro, the compatibility code just doesn't work on volumes that + don't support PBExchangeFiles (even though you may get a noErr result). + System Update 3.0 and System 7.5 and later have the problems in + FSpExchangeFiles corrected. + + Result Codes + noErr 0 No error + nsvErr -35 Volume not found + ioErr -36 I/O error + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 Function not supported by volume + volOfflinErr -53 Volume is offline + wrgVolTypErr -123 Not an HFS volume + diffVolErr -1303 Files on different volumes + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Object is a directory, not a file + afpSameObjectErr -5038 Source and destination files are the same +*/ + +/*****************************************************************************/ + +EXTERN_API( short ) +FSpOpenResFileCompat( + const FSSpec * spec, + SignedByte permission); + + +/* + The FSpOpenResFileCompat function opens the resource file specified + by spec. + + spec input: An FSSpec record specifying the file whose + resource file is to be opened. + permission input: A constant indicating the desired file access + permissions. + function result output: A resource file reference number, or if there's + an error -1. + + Result Codes + noErr 0 No error + nsvErr 35 No such volume + ioErr 36 I/O error + bdNamErr 37 Bad filename or volume name (perhaps zero + length) + eofErr 39 End of file + tmfoErr 42 Too many files open + fnfErr 43 File not found + opWrErr 49 File already open with write permission + permErr 54 Permissions error (on file open) + extFSErr 58 Volume belongs to an external file system + memFullErr 108 Not enough room in heap zone + dirNFErr 120 Directory not found + mapReadErr 199 Map inconsistent with operation +*/ + +/*****************************************************************************/ + +EXTERN_API( void ) +FSpCreateResFileCompat( + const FSSpec * spec, + OSType creator, + OSType fileType, + ScriptCode scriptTag); + + +/* + The FSpCreateResFileCompat function creates a new resource file with + the specified type, creator, and script code. + Differences from FSpCreateResFile: FSpCreateResFileCompat correctly + sets the fdScript in the file's FXInfo record to scriptTag if the + problem isn't fixed in the File Manager code. + + spec input: An FSSpec record specifying the resource file to create. + creator input: The creator of the new file. + fileType input The file type of the new file. + scriptCode input: The code of the script system in which the file + name is to be displayed. + + Result Codes + noErr 0 No error + dirFulErr 33 Directory full + dskFulErr 34 Disk full + nsvErr 35 No such volume + ioErr 36 I/O error + bdNamErr 37 Bad filename or volume name (perhaps zero + length) + tmfoErr 42 Too many files open + wPrErrw 44 Disk is write-protected + fLckdErr 45 File is locked +*/ + +/*****************************************************************************/ + +#include "OptimizationEnd.h" + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=reset +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(pop) +#elif PRAGMA_STRUCT_PACK + #pragma pack() +#endif + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __FSPCOMPAT__ */ + diff --git a/corelib/morefile/FullPath.c b/corelib/morefile/FullPath.c new file mode 100644 index 00000000..702aee1e --- /dev/null +++ b/corelib/morefile/FullPath.c @@ -0,0 +1,282 @@ +/* + File: FullPath.c + + Contains: Routines for dealing with full pathnames... if you really must. + + Version: MoreFiles + + Copyright: © 1995-2001 by Apple Computer, Inc., all rights reserved. + + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: Apple Macintosh Developer Technical Support + <http://developer.apple.com/bugreporter/> + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <2> 2/7/01 JL Added standard header. Updated names of includes. + <1> 12/06/99 JL MoreFiles 1.5. +*/ + +#include <MacTypes.h> +#include <MacErrors.h> +#include <MacMemory.h> +#include <Files.h> +#include <TextUtils.h> +#include <Aliases.h> + +#define __COMPILINGMOREFILES + +#include "FSpCompat.h" +#include "FullPath.h" + +/* + IMPORTANT NOTE: + + The use of full pathnames is strongly discouraged. Full pathnames are + particularly unreliable as a means of identifying files, directories + or volumes within your application, for two primary reasons: + + € The user can change the name of any element in the path at virtually + any time. + € Volume names on the Macintosh are *not* unique. Multiple + mounted volumes can have the same name. For this reason, the use of + a full pathname to identify a specific volume may not produce the + results you expect. If more than one volume has the same name and + a full pathname is used, the File Manager currently uses the first + mounted volume it finds with a matching name in the volume queue. + + In general, you should use a file¹s name, parent directory ID, and + volume reference number to identify a file you want to open, delete, + or otherwise manipulate. + + If you need to remember the location of a particular file across + subsequent system boots, use the Alias Manager to create an alias record + describing the file. If the Alias Manager is not available, you can save + the file¹s name, its parent directory ID, and the name of the volume on + which it¹s located. Although none of these methods is foolproof, they are + much more reliable than using full pathnames to identify files. + + Nonetheless, it is sometimes useful to display a file¹s full pathname to + the user. For example, a backup utility might display a list of full + pathnames of files as it copies them onto the backup medium. Or, a + utility might want to display a dialog box showing the full pathname of + a file when it needs the user¹s confirmation to delete the file. No + matter how unreliable full pathnames may be from a file-specification + viewpoint, users understand them more readily than volume reference + numbers or directory IDs. (Hint: Use the TruncString function from + TextUtils.h with truncMiddle as the truncWhere argument to shorten + full pathnames to a displayable length.) + + The following technique for constructing the full pathname of a file is + intended for display purposes only. Applications that depend on any + particular structure of a full pathname are likely to fail on alternate + foreign file systems or under future system software versions. +*/ + +/*****************************************************************************/ + +pascal OSErr GetFullPath(short vRefNum, + long dirID, + ConstStr255Param name, + short *fullPathLength, + Handle *fullPath) +{ + OSErr result; + FSSpec spec; + + *fullPathLength = 0; + *fullPath = NULL; + + result = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); + if ( (result == noErr) || (result == fnfErr) ) + { + result = FSpGetFullPath(&spec, fullPathLength, fullPath); + } + + return ( result ); +} + +/*****************************************************************************/ + +pascal OSErr FSpGetFullPath(const FSSpec *spec, + short *fullPathLength, + Handle *fullPath) +{ + OSErr result; + OSErr realResult; + FSSpec tempSpec; + CInfoPBRec pb; + + *fullPathLength = 0; + *fullPath = NULL; + + + /* Default to noErr */ + realResult = result = noErr; + + /* work around Nav Services "bug" (it returns invalid FSSpecs with empty names) */ + if ( spec->name[0] == 0 ) + { + result = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, spec->name, &tempSpec); + } + else + { + /* Make a copy of the input FSSpec that can be modified */ + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + } + + if ( result == noErr ) + { + if ( tempSpec.parID == fsRtParID ) + { + /* The object is a volume */ + + /* Add a colon to make it a full pathname */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + /* We're done */ + result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + } + else + { + /* The object isn't a volume */ + + /* Is the object a file or a directory? */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrDirID = tempSpec.parID; + pb.dirInfo.ioFDirIndex = 0; + result = PBGetCatInfoSync(&pb); + // Allow file/directory name at end of path to not exist. + realResult = result; + if ( (result == noErr) || (result == fnfErr) ) + { + /* if the object is a directory, append a colon so full pathname ends with colon */ + if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) + { + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + } + + /* Put the object name in first */ + result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + if ( result == noErr ) + { + /* Get the ancestor directory names */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrParID = tempSpec.parID; + do /* loop until we have an error or find the root directory */ + { + pb.dirInfo.ioFDirIndex = -1; + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + result = PBGetCatInfoSync(&pb); + if ( result == noErr ) + { + /* Append colon to directory name */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + /* Add directory name to beginning of fullPath */ + (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]); + result = MemError(); + } + } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); + } + } + } + } + + if ( result == noErr ) + { + /* Return the length */ + *fullPathLength = GetHandleSize(*fullPath); + result = realResult; // return realResult in case it was fnfErr + } + else + { + /* Dispose of the handle and return NULL and zero length */ + if ( *fullPath != NULL ) + { + DisposeHandle(*fullPath); + } + *fullPath = NULL; + *fullPathLength = 0; + } + + return ( result ); +} + +/*****************************************************************************/ + +pascal OSErr FSpLocationFromFullPath(short fullPathLength, + const void *fullPath, + FSSpec *spec) +{ + AliasHandle alias; + OSErr result; + Boolean wasChanged; + Str32 nullString; + + /* Create a minimal alias from the full pathname */ + nullString[0] = 0; /* null string to indicate no zone or server name */ + result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias); + if ( result == noErr ) + { + /* Let the Alias Manager resolve the alias. */ + result = ResolveAlias(NULL, alias, spec, &wasChanged); + + /* work around Alias Mgr sloppy volume matching bug */ + if ( spec->vRefNum == 0 ) + { + /* invalidate wrong FSSpec */ + spec->parID = 0; + spec->name[0] = 0; + result = nsvErr; + } + DisposeHandle((Handle)alias); /* Free up memory used */ + } + return ( result ); +} + +/*****************************************************************************/ + +pascal OSErr LocationFromFullPath(short fullPathLength, + const void *fullPath, + short *vRefNum, + long *parID, + Str31 name) +{ + OSErr result; + FSSpec spec; + + result = FSpLocationFromFullPath(fullPathLength, fullPath, &spec); + if ( result == noErr ) + { + *vRefNum = spec.vRefNum; + *parID = spec.parID; + BlockMoveData(&spec.name[0], &name[0], spec.name[0] + 1); + } + return ( result ); +} + +/*****************************************************************************/ + diff --git a/corelib/morefile/FullPath.h b/corelib/morefile/FullPath.h new file mode 100644 index 00000000..148634a9 --- /dev/null +++ b/corelib/morefile/FullPath.h @@ -0,0 +1,311 @@ +/* + File: FullPath.h + + Contains: Routines for dealing with full pathnames... if you really must. + + Version: Technology: MoreFiles + Release: 1.5.2 + + Copyright: © 1995-2001 by Apple Computer, Inc., all rights reserved. + + Bugs?: For bug reports, consult the following page on + the World Wide Web: + + http://developer.apple.com/bugreporter/ + +*/ + +/* + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. +*/ + +/* + IMPORTANT NOTE: + + The use of full pathnames is strongly discouraged. Full pathnames are + particularly unreliable as a means of identifying files, directories + or volumes within your application, for two primary reasons: + + € The user can change the name of any element in the path at + virtually any time. + € Volume names on the Macintosh are *not* unique. Multiple + mounted volumes can have the same name. For this reason, the use of + a full pathname to identify a specific volume may not produce the + results you expect. If more than one volume has the same name and + a full pathname is used, the File Manager currently uses the first + mounted volume it finds with a matching name in the volume queue. + + In general, you should use a file¹s name, parent directory ID, and + volume reference number to identify a file you want to open, delete, + or otherwise manipulate. + + If you need to remember the location of a particular file across + subsequent system boots, use the Alias Manager to create an alias + record describing the file. If the Alias Manager is not available, you + can save the file¹s name, its parent directory ID, and the name of the + volume on which it¹s located. Although none of these methods is + foolproof, they are much more reliable than using full pathnames to + identify files. + + Nonetheless, it is sometimes useful to display a file¹s full pathname + to the user. For example, a backup utility might display a list of full + pathnames of files as it copies them onto the backup medium. Or, a + utility might want to display a dialog box showing the full pathname of + a file when it needs the user¹s confirmation to delete the file. No + matter how unreliable full pathnames may be from a file-specification + viewpoint, users understand them more readily than volume reference + numbers or directory IDs. (Hint: Use the TruncString function from + TextUtils.h with truncMiddle as the truncWhere argument to shorten + full pathnames to a displayable length.) + + The following technique for constructing the full pathname of a file is + intended for display purposes only. Applications that depend on any + particular structure of a full pathname are likely to fail on alternate + foreign file systems or under future system software versions. +*/ + +#ifndef __FULLPATH__ +#define __FULLPATH__ + +#ifndef __MACTYPES__ +#include <MacTypes.h> +#endif + +#ifndef __FILES__ +#include <Files.h> +#endif + +#include "Optimization.h" + + +#if PRAGMA_ONCE +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=mac68k +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(push, 2) +#elif PRAGMA_STRUCT_PACK + #pragma pack(2) +#endif + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetFullPath( + short vRefNum, + long dirID, + ConstStr255Param name, + short * fullPathLength, + Handle * fullPath); + + +/* + The GetFullPath function builds a full pathname to the specified + object. The full pathname is returned in the newly created handle + fullPath and the length of the full pathname is returned in + fullPathLength. Your program is responsible for disposing of the + fullPath handle. + + Note that a full pathname can be made to a file/directory that does not + yet exist if all directories up to that file/directory exist. In this case, + GetFullPath will return a fnfErr. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + fullPathLength output: The number of characters in the full pathname. + If the function fails to create a full + pathname, it sets fullPathLength to 0. + fullPath output: A handle to the newly created full pathname + buffer. If the function fails to create a + full pathname, it sets fullPath to NULL. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File or directory does not exist (fullPath + and fullPathLength are still valid) + paramErr -50 No default volume + memFullErr -108 Not enough memory + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpGetFullPath +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpGetFullPath( + const FSSpec * spec, + short * fullPathLength, + Handle * fullPath); + + +/* + The GetFullPath function builds a full pathname to the specified + object. The full pathname is returned in the newly created handle + fullPath and the length of the full pathname is returned in + fullPathLength. Your program is responsible for disposing of the + fullPath handle. + + Note that a full pathname can be made to a file/directory that does not + yet exist if all directories up to that file/directory exist. In this case, + FSpGetFullPath will return a fnfErr. + + IMPORTANT: The definition of a FSSpec is a volume reference number (not a + drive number, working directory number, or 0), a parent directory ID (not 0), + and the name of a file or folder (not an empty name, a full pathname, or + a partial pathname containing one or more colon (:) characters). + FSpGetFullPath assumes it is getting a FSSpec that matches the rules. + If you have an FSSpec record that wasn't created by FSMakeFSSpec (or + FSMakeFSSpecCompat from FSpCompat in MoreFiles which correctly builds + FSSpecs), you should call GetFullPath instead of FSpGetFullPath. + + spec input: An FSSpec record specifying the object. + fullPathLength output: The number of characters in the full pathname. + If the function fails to create a full pathname, + it sets fullPathLength to 0. + fullPath output: A handle to the newly created full pathname + buffer. If the function fails to create a + full pathname, it sets fullPath to NULL. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File or directory does not exist (fullPath + and fullPathLength are still valid) + paramErr -50 No default volume + memFullErr -108 Not enough memory + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: GetFullPath +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpLocationFromFullPath( + short fullPathLength, + const void * fullPath, + FSSpec * spec); + + +/* + The FSpLocationFromFullPath function returns a FSSpec to the object + specified by full pathname. This function requires the Alias Manager. + + fullPathLength input: The number of characters in the full pathname + of the target. + fullPath input: A pointer to a buffer that contains the full + pathname of the target. The full pathname + starts with the name of the volume, includes + all of the directory names in the path to the + target, and ends with the target name. + spec output: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 The volume is not mounted + fnfErr -43 Target not found, but volume and parent + directory found + paramErr -50 Parameter error + usrCanceledErr -128 The user canceled the operation + + __________ + + See also: LocationFromFullPath +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +LocationFromFullPath( + short fullPathLength, + const void * fullPath, + short * vRefNum, + long * parID, + Str31 name); + + +/* + The LocationFromFullPath function returns the volume reference number, + parent directory ID and name of the object specified by full pathname. + This function requires the Alias Manager. + + fullPathLength input: The number of characters in the full pathname + of the target. + fullPath input: A pointer to a buffer that contains the full + pathname of the target. The full pathname starts + with the name of the volume, includes all of + the directory names in the path to the target, + and ends with the target name. + vRefNum output: The volume reference number. + parID output: The parent directory ID of the specified object. + name output: The name of the specified object. + + Result Codes + noErr 0 No error + nsvErr -35 The volume is not mounted + fnfErr -43 Target not found, but volume and parent + directory found + paramErr -50 Parameter error + usrCanceledErr -128 The user canceled the operation + + __________ + + See also: FSpLocationFromFullPath +*/ + +/*****************************************************************************/ + +#include "OptimizationEnd.h" + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=reset +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(pop) +#elif PRAGMA_STRUCT_PACK + #pragma pack() +#endif + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __FULLPATH__ */ + diff --git a/corelib/morefile/MoreFilesExtras.h b/corelib/morefile/MoreFilesExtras.h new file mode 100644 index 00000000..1ccbc678 --- /dev/null +++ b/corelib/morefile/MoreFilesExtras.h @@ -0,0 +1,3597 @@ +/* + File: MoreFilesExtras.h + + Contains: A collection of useful high-level File Manager routines. + + Version: Technology: MoreFiles + Release: 1.5.2 + + Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved. + + Bugs?: For bug reports, consult the following page on + the World Wide Web: + + http://developer.apple.com/bugreporter/ + +*/ + +/* + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. +*/ + +#ifndef __MOREFILESEXTRAS__ +#define __MOREFILESEXTRAS__ + +#ifndef __MACTYPES__ +#include <MacTypes.h> +#endif + +#ifndef __FILES__ +#include <Files.h> +#endif + +#include "Optimization.h" + + +#if PRAGMA_ONCE +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=mac68k +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(push, 2) +#elif PRAGMA_STRUCT_PACK + #pragma pack(2) +#endif + +/*****************************************************************************/ + +/* +** Bit masks and macros to get common information out of ioACUser returned +** by PBGetCatInfo (remember to clear ioACUser before calling PBGetCatInfo +** since some file systems don't bother to set this field). +** +** Use the GetDirAccessRestrictions or FSpGetDirAccessRestrictions +** functions to retrieve the ioACUser access restrictions byte for +** a folder. +** +** Note: The access restriction byte returned by PBGetCatInfo is the +** 2's complement of the user's privileges byte returned in +** ioACAccess by PBHGetDirAccess. +*/ + +enum { + /* mask for just the access restriction bits */ + acUserAccessMask = (kioACUserNoSeeFolderMask + kioACUserNoSeeFilesMask + kioACUserNoMakeChangesMask), /* common access privilege settings */ + acUserFull = 0x00, /* no access restiction bits on */ + acUserNone = acUserAccessMask, /* all access restiction bits on */ + acUserDropBox = kioACUserNoSeeFolderMask + kioACUserNoSeeFilesMask, /* make changes, but not see files or folders */ + acUserBulletinBoard = kioACUserNoMakeChangesMask /* see files and folders, but not make changes */ +}; + + +/*****************************************************************************/ + +/* +** Deny mode permissions for use with the HOpenAware, HOpenRFAware, +** FSpOpenAware, and FSpOpenRFAware functions. +** Note: Common settings are the ones with comments. +*/ + +enum { + dmNone = 0x0000, + dmNoneDenyRd = fsRdDenyPerm, + dmNoneDenyWr = fsWrDenyPerm, + dmNoneDenyRdWr = (fsRdDenyPerm + fsWrDenyPerm), + dmRd = fsRdPerm, /* Single writer, multiple readers; the readers */ + dmRdDenyRd = (fsRdPerm + fsRdDenyPerm), + dmRdDenyWr = (fsRdPerm + fsWrDenyPerm), /* Browsing - equivalent to fsRdPerm */ + dmRdDenyRdWr = (fsRdPerm + fsRdDenyPerm + fsWrDenyPerm), + dmWr = fsWrPerm, + dmWrDenyRd = (fsWrPerm + fsRdDenyPerm), + dmWrDenyWr = (fsWrPerm + fsWrDenyPerm), + dmWrDenyRdWr = (fsWrPerm + fsRdDenyPerm + fsWrDenyPerm), + dmRdWr = fsRdWrPerm, /* Shared access - equivalent to fsRdWrShPerm */ + dmRdWrDenyRd = (fsRdWrPerm + fsRdDenyPerm), + dmRdWrDenyWr = (fsRdWrPerm + fsWrDenyPerm), /* Single writer, multiple readers; the writer */ + dmRdWrDenyRdWr = (fsRdWrPerm + fsRdDenyPerm + fsWrDenyPerm) /* Exclusive access - equivalent to fsRdWrPerm */ +}; + + +/*****************************************************************************/ + +/* +** For those times where you need to use more than one kind of File Manager parameter +** block but don't feel like wasting stack space, here's a parameter block you can reuse. +*/ + + +union UniversalFMPB { + ParamBlockRec PB; + CInfoPBRec ciPB; + DTPBRec dtPB; + HParamBlockRec hPB; + CMovePBRec cmPB; + WDPBRec wdPB; + FCBPBRec fcbPB; + XVolumeParam xPB; +}; +typedef union UniversalFMPB UniversalFMPB; +typedef UniversalFMPB * UniversalFMPBPtr; +typedef UniversalFMPBPtr * UniversalFMPBHandle; + +/* +** Used by GetUGEntries to return user or group lists +*/ + +struct UGEntry { + short objType; /* object type: -1 = group; 0 = user */ + long objID; /* the user or group ID */ + Str31 name; /* the user or group name */ +}; +typedef struct UGEntry UGEntry; +typedef UGEntry * UGEntryPtr; +typedef UGEntryPtr * UGEntryHandle; + +/* +** I use the following records instead of the AFPVolMountInfo and AFPXVolMountInfo structures in Files.h +*/ +typedef unsigned char Str8[9]; + +struct MyAFPVolMountInfo { + short length; /* length of this record */ + VolumeType media; /* type of media, always AppleShareMediaType */ + short flags; /* 0 = normal mount; set bit 0 to inhibit greeting messages */ + char nbpInterval; /* NBP interval parameter; 7 is a good choice */ + char nbpCount; /* NBP count parameter; 5 is a good choice */ + short uamType; /* User Authentication Method */ + short zoneNameOffset; /* offset from start of record to zoneName */ + short serverNameOffset; /* offset from start of record to serverName */ + short volNameOffset; /* offset from start of record to volName */ + short userNameOffset; /* offset from start of record to userName */ + short userPasswordOffset; /* offset from start of record to userPassword */ + short volPasswordOffset; /* offset from start of record to volPassword */ + Str32 zoneName; /* server's AppleTalk zone name */ + char filler1; /* to word align volPassword */ + Str32 serverName; /* server name */ + char filler2; /* to word align volPassword */ + Str27 volName; /* volume name */ + Str31 userName; /* user name (zero length Pascal string for guest) */ + Str8 userPassword; /* user password (zero length Pascal string if no user password) */ + char filler3; /* to word align volPassword */ + Str8 volPassword; /* volume password (zero length Pascal string if no volume password) */ + char filler4; /* to end record on word boundry */ +}; +typedef struct MyAFPVolMountInfo MyAFPVolMountInfo; +typedef MyAFPVolMountInfo * MyAFPVolMountInfoPtr; +typedef MyAFPVolMountInfoPtr * MyAFPVolMountInfoHandle; + +struct MyAFPXVolMountInfo { + short length; /* length of this record */ + VolumeType media; /* type of media, always AppleShareMediaType */ + short flags; /* bits for no messages, no reconnect, etc */ + char nbpInterval; /* NBP interval parameter; 7 is a good choice */ + char nbpCount; /* NBP count parameter; 5 is a good choice */ + short uamType; /* User Authentication Method */ + short zoneNameOffset; /* offset from start of record to zoneName */ + short serverNameOffset; /* offset from start of record to serverName */ + short volNameOffset; /* offset from start of record to volName */ + short userNameOffset; /* offset from start of record to userName */ + short userPasswordOffset; /* offset from start of record to userPassword */ + short volPasswordOffset; /* offset from start of record to volPassword */ + short extendedFlags; /* extended flags word */ + short uamNameOffset; /* offset to a pascal UAM name string */ + short alternateAddressOffset; /* offset to Alternate Addresses in tagged format */ + Str32 zoneName; /* server's AppleTalk zone name */ + char filler1; /* to word align volPassword */ + Str32 serverName; /* server name */ + char filler2; /* to word align volPassword */ + Str27 volName; /* volume name */ + Str31 userName; /* user name (zero length Pascal string for guest) */ + Str8 userPassword; /* user password (zero length Pascal string if no user password) */ + char filler3; /* to word align volPassword */ + Str8 volPassword; /* volume password (zero length Pascal string if no volume password) */ + char filler4; /* to word align uamNameOffset */ + Str32 uamName; /* UAM name */ + char filler5; /* to word align alternateAddress */ + char alternateAddress[1]; /* AFPAlternateAddress */ +}; +typedef struct MyAFPXVolMountInfo MyAFPXVolMountInfo; +typedef MyAFPXVolMountInfo * MyAFPXVolMountInfoPtr; +typedef MyAFPXVolMountInfoPtr * MyAFPXVolMountInfoHandle; + +/*****************************************************************************/ + +/* Functions to get information out of GetVolParmsInfoBuffer. */ + +/* version 1 field getters */ + +EXTERN_API( short ) +GetVolParmsInfoVersion(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( long ) +GetVolParmsInfoAttrib(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Handle ) +GetVolParmsInfoLocalHand(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( long ) +GetVolParmsInfoServerAdr(const GetVolParmsInfoBuffer * volParms); + + + +/* version 2 field getters (assume zero result if version < 2) */ + +EXTERN_API( long ) +GetVolParmsInfoVolumeGrade(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( long ) +GetVolParmsInfoForeignPrivID(const GetVolParmsInfoBuffer * volParms); + + + +/* version 3 field getters (assume zero result if version < 3) */ + +EXTERN_API( long ) +GetVolParmsInfoExtendedAttributes(const GetVolParmsInfoBuffer * volParms); + + + +/* attribute bits supported by all versions of GetVolParmsInfoBuffer */ + +EXTERN_API( Boolean ) +isNetworkVolume(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasLimitFCBs(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasLocalWList(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoMiniFndr(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoVNEdit(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoLclSync(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasTrshOffLine(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoSwitchTo(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoDeskItems(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoBootBlks(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasAccessCntl(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasNoSysDir(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasExtFSVol(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasOpenDeny(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasCopyFile(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasMoveRename(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasDesktopMgr(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasShortName(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasFolderLock(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasPersonalAccessPrivileges(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasUserGroupList(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasCatSearch(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasFileIDs(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasBTreeMgr(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +hasBlankAccessPrivileges(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +supportsAsyncRequests(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +supportsTrashVolumeCache(const GetVolParmsInfoBuffer * volParms); + + + +/* attribute bits supported by version 3 and greater versions of GetVolParmsInfoBuffer */ + +EXTERN_API( Boolean ) +volIsEjectable(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsHFSPlusAPIs(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsFSCatalogSearch(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsFSExchangeObjects(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupports2TBFiles(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsLongNames(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsMultiScriptNames(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsNamedForks(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volSupportsSubtreeIterators(const GetVolParmsInfoBuffer * volParms); + + +EXTERN_API( Boolean ) +volL2PCanMapFileBlocks(const GetVolParmsInfoBuffer * volParms); + + + +/*****************************************************************************/ + +/* Functions for testing ioACUser bits. */ + +EXTERN_API( Boolean ) +userIsOwner(SInt8 ioACUser); + + +EXTERN_API( Boolean ) +userHasFullAccess(SInt8 ioACUser); + + +EXTERN_API( Boolean ) +userHasDropBoxAccess(SInt8 ioACUser); + + +EXTERN_API( Boolean ) +userHasBulletinBoard(SInt8 ioACUser); + + +EXTERN_API( Boolean ) +userHasNoAccess(SInt8 ioACUser); + + + +/*****************************************************************************/ + +EXTERN_API( void ) +TruncPString( + StringPtr destination, + ConstStr255Param source, + short maxLength); + + +/* + The TruncPString function copies up to maxLength characters from + the source Pascal string to the destination Pascal string. TruncPString + ensures that the truncated string ends on a single-byte character, or on + the last byte of a multi-byte character. + + destination output: destination Pascal string. + source input: source Pascal string. + maxLength output: The maximum allowable length of the destination + string. +*/ + +/*****************************************************************************/ + +EXTERN_API( Ptr ) +GetTempBuffer( + long buffReqSize, + long * buffActSize); + + +/* + The GetTempBuffer function allocates a temporary buffer for file system + operations which is at least 1024 bytes (1K) and a multiple of + 1024 bytes. + + buffReqSize input: Size you'd like the buffer to be. + buffActSize output: Size of buffer allocated. + function result output: Pointer to memory allocated or nil if no memory + was available. The caller is responsible for + disposing of this buffer with DisposePtr. +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetVolumeInfoNoName( + ConstStr255Param pathname, + short vRefNum, + HParmBlkPtr pb); + + +/* + GetVolumeInfoNoName uses pathname and vRefNum to call PBHGetVInfoSync + in cases where the returned volume name is not needed by the caller. + The pathname and vRefNum parameters are not touched, and the pb + parameter is initialized by PBHGetVInfoSync except that ioNamePtr in + the parameter block is always returned as NULL (since it might point + to GetVolumeInfoNoName's local variable tempPathname). + + I noticed using this code in several places, so here it is once. + This reduces the code size of MoreFiles. + + pathName input: Pointer to a full pathname or nil. If you pass in a + partial pathname, it is ignored. A full pathname to a + volume must end with a colon character (:). + vRefNum input: Volume specification (volume reference number, working + directory number, drive number, or 0). + pb input: A pointer to HParamBlockRec. + output: The parameter block as filled in by PBHGetVInfoSync + except that ioNamePtr will always be NULL. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume, or pb was NULL +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +XGetVolumeInfoNoName( + ConstStr255Param pathname, + short vRefNum, + XVolumeParamPtr pb); + + +/* + XGetVolumeInfoNoName uses pathname and vRefNum to call PBXGetVolInfoSync + in cases where the returned volume name is not needed by the caller. + The pathname and vRefNum parameters are not touched, and the pb + parameter is initialized by PBXGetVolInfoSync except that ioNamePtr in + the parameter block is always returned as NULL (since it might point + to XGetVolumeInfoNoName's local variable tempPathname). + + pathName input: Pointer to a full pathname or nil. If you pass in a + partial pathname, it is ignored. A full pathname to a + volume must end with a colon character (:). + vRefNum input: Volume specification (volume reference number, working + directory number, drive number, or 0). + pb input: A pointer to HParamBlockRec. + output: The parameter block as filled in by PBXGetVolInfoSync + except that ioNamePtr will always be NULL. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume, or pb was NULL +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetCatInfoNoName( + short vRefNum, + long dirID, + ConstStr255Param name, + CInfoPBPtr pb); + + +/* + GetCatInfoNoName uses vRefNum, dirID and name to call PBGetCatInfoSync + in cases where the returned object is not needed by the caller. + The vRefNum, dirID and name parameters are not touched, and the pb + parameter is initialized by PBGetCatInfoSync except that ioNamePtr in + the parameter block is always returned as NULL (since it might point + to GetCatInfoNoName's local variable tempName). + + I noticed using this code in several places, so here it is once. + This reduces the code size of MoreFiles. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + pb input: A pointer to CInfoPBRec. + output: The parameter block as filled in by + PBGetCatInfoSync except that ioNamePtr will + always be NULL. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +DetermineVRefNum( + ConstStr255Param pathname, + short vRefNum, + short * realVRefNum); + + +/* + The DetermineVRefNum function determines the volume reference number of + a volume from a pathname, a volume specification, or a combination + of the two. + WARNING: Volume names on the Macintosh are *not* unique -- Multiple + mounted volumes can have the same name. For this reason, the use of a + volume name or full pathname to identify a specific volume may not + produce the results you expect. If more than one volume has the same + name and a volume name or full pathname is used, the File Manager + currently uses the first volume it finds with a matching name in the + volume queue. + + pathName input: Pointer to a full pathname or nil. If you pass in a + partial pathname, it is ignored. A full pathname to a + volume must end with a colon character (:). + vRefNum input: Volume specification (volume reference number, working + directory number, drive number, or 0). + realVRefNum output: The real volume reference number. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +HGetVInfo( + short volReference, + StringPtr volName, + short * vRefNum, + unsigned long * freeBytes, + unsigned long * totalBytes); + + +/* + The HGetVInfo function returns the name, volume reference number, + available space (in bytes), and total space (in bytes) for the + specified volume. You can specify the volume by providing its drive + number, volume reference number, or 0 for the default volume. + This routine is compatible with volumes up to 4 gigabytes. + + volReference input: The drive number, volume reference number, + or 0 for the default volume. + volName input: A pointer to a buffer (minimum Str27) where + the volume name is to be returned or must + be nil. + output: The volume name. + vRefNum output: The volume reference number. + freeBytes output: The number of free bytes on the volume. + freeBytes is an unsigned long value. + totalBytes output: The total number of bytes on the volume. + totalBytes is an unsigned long value. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume + + __________ + + Also see: XGetVInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +XGetVInfo( + short volReference, + StringPtr volName, + short * vRefNum, + UInt64 * freeBytes, + UInt64 * totalBytes); + + +/* + The XGetVInfo function returns the name, volume reference number, + available space (in bytes), and total space (in bytes) for the + specified volume. You can specify the volume by providing its drive + number, volume reference number, or 0 for the default volume. + This routine is compatible with volumes up to 2 terabytes. + + volReference input: The drive number, volume reference number, + or 0 for the default volume. + volName input: A pointer to a buffer (minimum Str27) where + the volume name is to be returned or must + be nil. + output: The volume name. + vRefNum output: The volume reference number. + freeBytes output: The number of free bytes on the volume. + freeBytes is an UnsignedWide value. + totalBytes output: The total number of bytes on the volume. + totalBytes is an UnsignedWide value. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume + + __________ + + Also see: HGetVInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +CheckVolLock( + ConstStr255Param pathname, + short vRefNum); + + +/* + The CheckVolLock function determines if a volume is locked - either by + hardware or by software. If CheckVolLock returns noErr, then the volume + is not locked. + + pathName input: Pointer to a full pathname or nil. If you pass in a + partial pathname, it is ignored. A full pathname to a + volume must end with a colon character (:). + vRefNum input: Volume specification (volume reference number, working + directory number, drive number, or 0). + + Result Codes + noErr 0 No error - volume not locked + nsvErr -35 No such volume + wPrErr -44 Volume locked by hardware + vLckdErr -46 Volume locked by software + paramErr -50 No default volume +*/ + +/*****************************************************************************/ +/* +** The following routines call Mac OS routines that are not supported by +** Carbon: +** +** GetDriverName +** FindDrive +** GetDiskBlocks +** GetVolState +*/ + +#if !TARGET_API_MAC_CARBON // { + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetDriverName( + short driverRefNum, + Str255 driverName); + + +/* + The GetDriverName function returns a device driver's name. + + driverRefNum input: The driver reference number. + driverName output: The driver's name. + + Result Codes + noErr 0 No error + badUnitErr -21 Bad driver reference number +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FindDrive( + ConstStr255Param pathname, + short vRefNum, + DrvQElPtr * driveQElementPtr); + + +/* + The FindDrive function returns a pointer to a mounted volume's + drive queue element. + + pathName input: Pointer to a full pathname or nil. If you + pass in a partial pathname, it is ignored. + A full pathname to a volume must end with + a colon character (:). + vRefNum input: Volume specification (volume reference + number, working directory number, drive + number, or 0). + driveQElementPtr output: Pointer to a volume's drive queue element + in the drive queue. DO NOT change the + DrvQEl. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume + nsDrvErr -56 No such drive +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetDiskBlocks( + ConstStr255Param pathname, + short vRefNum, + unsigned long * numBlocks); + + +/* + The GetDiskBlocks function returns the number of physical disk + blocks on a disk drive. NOTE: This is not the same as volume + allocation blocks! + + pathName input: Pointer to a full pathname or nil. If you + pass in a partial pathname, it is ignored. + A full pathname to a volume must end with + a colon character (:). + vRefNum input: Volume specification (volume reference + number, working directory number, drive + number, or 0). + numBlocks output: The number of physical disk blocks on the disk drive. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume, driver reference + number is zero, ReturnFormatList + returned zero blocks, DriveStatus + returned an unknown value, or + driveQElementPtr->qType is unknown + nsDrvErr -56 No such drive + statusErr 18 Driver does not respond to this + status request + badUnitErr 21 Driver reference number does not + match unit table + unitEmptyErr 22 Driver reference number specifies + a nil handle in unit table + abortErr 27 Request aborted by KillIO + notOpenErr 28 Driver not open +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetVolState( + ConstStr255Param pathname, + short vRefNum, + Boolean * volumeOnline, + Boolean * volumeEjected, + Boolean * driveEjectable, + Boolean * driverWantsEject); + + +/* + The GetVolState function determines if a volume is online or offline, + if an offline volume is ejected, and if the volume's driver is + ejectable or wants eject calls. + + pathName input: Pointer to a full pathname or nil. + vRefNum input: Volume specification (volume reference number, + working directory number, drive number, or 0). + volumeOnline output: True if the volume is online; + False if the volume is offline. + volumeEjected output: True if the volume is ejected (ejected + volumes are always offline); False if the + volume is not ejected. + driveEjectable output: True if the volume's drive is ejectable; + False if the volume's drive is not ejectable. + driverWantsEject output: True if the volume's driver wants an Eject + request after unmount (even if the drive + is not ejectable); False if the volume's + driver does not need an eject request. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume, or pb was NULL +*/ + +/*****************************************************************************/ + +#endif // } !TARGET_API_MAC_CARBON + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetVolFileSystemID( + ConstStr255Param pathname, + short vRefNum, + short * fileSystemID); + + +/* + The GetVolFileSystemID function returned the file system ID of + a mounted volume. The file system ID identifies the file system + that handles requests to a particular volume. Here's a partial list + of file system ID numbers (only Apple's file systems are listed): + FSID File System + ----- ----------------------------------------------------- + $0000 Macintosh HFS or MFS + $0100 ProDOS File System + $0101 PowerTalk Mail Enclosures + $4147 ISO 9660 File Access (through Foreign File Access) + $4242 High Sierra File Access (through Foreign File Access) + $464D QuickTake File System (through Foreign File Access) + $4953 Macintosh PC Exchange (MS-DOS) + $4A48 Audio CD Access (through Foreign File Access) + $4D4B Apple Photo Access (through Foreign File Access) + + See the Technical Note "FL 35 - Determining Which File System + Is Active" and the "Guide to the File System Manager" for more + information. + + pathName input: Pointer to a full pathname or nil. If you pass + in a partial pathname, it is ignored. A full + pathname to a volume must contain at least + one colon character (:) and must not start with + a colon character. + vRefNum input: Volume specification (volume reference number, + working directory number, drive number, or 0). + fileSystemID output: The volume's file system ID. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + paramErr -50 No default volume, or pb was NULL +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +UnmountAndEject( + ConstStr255Param pathname, + short vRefNum); + + +/* + The UnmountAndEject function unmounts and ejects a volume. The volume + is ejected only if it is ejectable and not already ejected. + + pathName input: Pointer to a full pathname or nil. If you pass in a + partial pathname, it is ignored. A full pathname to a + volume must end with a colon character (:). + vRefNum input: Volume specification (volume reference number, working + directory number, drive number, or 0). + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad volume name + fBsyErr -47 One or more files are open + paramErr -50 No default volume + nsDrvErr -56 No such drive + extFSErr -58 External file system error - no file + system claimed this call. +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +OnLine( + FSSpecPtr volumes, + short reqVolCount, + short * actVolCount, + short * volIndex); + + +/* + The OnLine function returns the list of volumes currently mounted in + an array of FSSpec records. + + A noErr result indicates that the volumes array was filled + (actVolCount == reqVolCount) and there may be additional volumes + mounted. A nsvErr result indicates that the end of the volume list + was found and actVolCount volumes were actually found this time. + + volumes input: Pointer to array of FSSpec where the volume list + is returned. + reqVolCount input: Maximum number of volumes to return (the number of + elements in the volumes array). + actVolCount output: The number of volumes actually returned. + volIndex input: The current volume index position. Set to 1 to + start with the first volume. + output: The volume index position to get the next volume. + Pass this value the next time you call OnLine to + start where you left off. + + Result Codes + noErr 0 No error, but there are more volumes + to list + nsvErr -35 No more volumes to be listed + paramErr -50 volIndex was <= 0 +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +SetDefault( + short newVRefNum, + long newDirID, + short * oldVRefNum, + long * oldDirID); + + +/* + The SetDefault function sets the default volume and directory to the + volume specified by newVRefNum and the directory specified by newDirID. + The current default volume reference number and directory ID are + returned in oldVRefNum and oldDir and must be used to restore the + default volume and directory to their previous state *as soon as + possible* with the RestoreDefault function. These two functions are + designed to be used as a wrapper around Standard I/O routines where + the location of the file is implied to be the default volume and + directory. In other words, this is how you should use these functions: + + error = SetDefault(newVRefNum, newDirID, &oldVRefNum, &oldDirID); + if ( error == noErr ) + { + // call the Stdio functions like remove, rename, tmpfile, + // fopen, freopen, etc. or non-ANSI extensions like + // fdopen,fsetfileinfo, -- create, open, unlink, etc. here! + + error = RestoreDefault(oldVRefNum, oldDirID); + } + + By using these functions as a wrapper, you won't need to open a working + directory (because SetDefault and RestoreDefault use HSetVol) and you + won't have to worry about the effects of using HSetVol (documented in + Technical Note "FL 11 - PBHSetVol is Dangerous" and in the + Inside Macintosh: Files book in the description of the HSetVol and + PBHSetVol functions) because the default volume/directory is restored + before giving up control to code that might be affected by HSetVol. + + newVRefNum input: Volume specification (volume reference number, + working directory number, drive number, or 0) of + the new default volume. + newDirID input: Directory ID of the new default directory. + oldVRefNum output: The volume specification to save for use with + RestoreDefault. + oldDirID output: The directory ID to save for use with + RestoreDefault. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + bdNamErr -37 Bad volume name + fnfErr -43 Directory not found + paramErr -50 No default volume + afpAccessDenied -5000 User does not have access to the directory + + __________ + + Also see: RestoreDefault +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +RestoreDefault( + short oldVRefNum, + long oldDirID); + + +/* + The RestoreDefault function restores the default volume and directory + to the volume specified by oldVRefNum and the directory specified by + oldDirID. The oldVRefNum and oldDirID parameters were previously + obtained from the SetDefault function. These two functions are designed + to be used as a wrapper around Standard C I/O routines where the + location of the file is implied to be the default volume and directory. + In other words, this is how you should use these functions: + + error = SetDefault(newVRefNum, newDirID, &oldVRefNum, &oldDirID); + if ( error == noErr ) + { + // call the Stdio functions like remove, rename, tmpfile, + // fopen, freopen, etc. or non-ANSI extensions like + // fdopen,fsetfileinfo, -- create, open, unlink, etc. here! + + error = RestoreDefault(oldVRefNum, oldDirID); + } + + By using these functions as a wrapper, you won't need to open a working + directory (because SetDefault and RestoreDefault use HSetVol) and you + won't have to worry about the effects of using HSetVol (documented in + Technical Note "FL 11 - PBHSetVol is Dangerous" and in the + Inside Macintosh: Files book in the description of the HSetVol and + PBHSetVol functions) because the default volume/directory is restored + before giving up control to code that might be affected by HSetVol. + + oldVRefNum input: The volume specification to restore. + oldDirID input: The directory ID to restore. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + bdNamErr -37 Bad volume name + fnfErr -43 Directory not found + paramErr -50 No default volume + rfNumErr -51 Bad working directory reference number + afpAccessDenied -5000 User does not have access to the directory + + __________ + + Also see: SetDefault +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetDInfo( + short vRefNum, + long dirID, + ConstStr255Param name, + DInfo * fndrInfo); + + +/* + The GetDInfo function gets the finder information for a directory. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + fndrInfo output: If the object is a directory, then its DInfo. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: FSpGetDInfo, FSpGetFInfoCompat +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpGetDInfo( + const FSSpec * spec, + DInfo * fndrInfo); + + +/* + The FSpGetDInfo function gets the finder information for a directory. + + spec input: An FSSpec record specifying the directory. + fndrInfo output: If the object is a directory, then its DInfo. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: FSpGetFInfoCompat, GetDInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +SetDInfo( + short vRefNum, + long dirID, + ConstStr255Param name, + const DInfo * fndrInfo); + + +/* + The SetDInfo function sets the finder information for a directory. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + fndrInfo input: The DInfo. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: FSpSetDInfo, FSpSetFInfoCompat +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetDInfo( + const FSSpec * spec, + const DInfo * fndrInfo); + + +/* + The FSpSetDInfo function sets the finder information for a directory. + + spec input: An FSSpec record specifying the directory. + fndrInfo input: The DInfo. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: FSpSetFInfoCompat, SetDInfo +*/ + +/*****************************************************************************/ + +#if OLDROUTINENAMES + #define GetDirID(vRefNum, dirID, name, theDirID, isDirectory) GetDirectoryID(vRefNum, dirID, name, theDirID, isDirectory) +#endif +EXTERN_API( OSErr ) +GetDirectoryID( + short vRefNum, + long dirID, + ConstStr255Param name, + long * theDirID, + Boolean * isDirectory); + + +/* + The GetDirectoryID function gets the directory ID number of the + directory specified. If a file is specified, then the parent + directory of the file is returned and isDirectory is false. If + a directory is specified, then that directory's ID number is + returned and isDirectory is true. + WARNING: Volume names on the Macintosh are *not* unique -- Multiple + mounted volumes can have the same name. For this reason, the use of a + volume name or full pathname to identify a specific volume may not + produce the results you expect. If more than one volume has the same + name and a volume name or full pathname is used, the File Manager + currently uses the first volume it finds with a matching name in the + volume queue. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + theDirID output: If the object is a file, then its parent directory + ID. If the object is a directory, then its ID. + isDirectory output: True if object is a directory; false if + object is a file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +#if OLDROUTINENAMES + #define DirIDFromFSSpec(spec, theDirID, isDirectory) FSpGetDirectoryID(spec, theDirID, isDirectory) +#endif +EXTERN_API( OSErr ) +FSpGetDirectoryID( + const FSSpec * spec, + long * theDirID, + Boolean * isDirectory); + + +/* + The FSpGetDirectoryID function gets the directory ID number of the + directory specified by spec. If spec is to a file, then the parent + directory of the file is returned and isDirectory is false. If + spec is to a directory, then that directory's ID number is + returned and isDirectory is true. + + spec input: An FSSpec record specifying the directory. + theDirID output: The directory ID. + isDirectory output: True if object is a directory; false if + object is a file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetDirName( + short vRefNum, + long dirID, + Str31 name); + + +/* + The GetDirName function gets the name of a directory from its + directory ID. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name output: Points to a Str31 where the directory name is to be + returned. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume or + name parameter was NULL + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetIOACUser( + short vRefNum, + long dirID, + ConstStr255Param name, + SInt8 * ioACUser); + + +/* + GetIOACUser returns a directory's access restrictions byte. + Use the masks and macro defined in MoreFilesExtras to check for + specific access priviledges. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + ioACUser output: The access restriction byte + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpGetIOACUser( + const FSSpec * spec, + SInt8 * ioACUser); + + +/* + FSpGetIOACUser returns a directory's access restrictions byte. + Use the masks and macro defined in MoreFilesExtras to check for + specific access priviledges. + + spec input: An FSSpec record specifying the directory. + ioACUser output: The access restriction byte + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetParentID( + short vRefNum, + long dirID, + ConstStr255Param name, + long * parID); + + +/* + The GetParentID function gets the parent directory ID number of the + specified object. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + parID output: The parent directory ID of the specified object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetFilenameFromPathname( + ConstStr255Param pathname, + Str255 filename); + + +/* + The GetFilenameFromPathname function gets the file (or directory) name + from the end of a full or partial pathname. Returns notAFileErr if the + pathname is nil, the pathname is empty, or the pathname cannot refer to + a filename (with a noErr result, the pathname could still refer to a + directory). + + pathname input: A full or partial pathname. + filename output: The file (or directory) name. + + Result Codes + noErr 0 No error + notAFileErr -1302 The pathname is nil, the pathname + is empty, or the pathname cannot refer + to a filename + + __________ + + See also: GetObjectLocation. +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetObjectLocation( + short vRefNum, + long dirID, + ConstStr255Param pathname, + short * realVRefNum, + long * realParID, + Str255 realName, + Boolean * isDirectory); + + +/* + The GetObjectLocation function gets a file system object's location - + that is, its real volume reference number, real parent directory ID, + and name. While we're at it, determine if the object is a file or directory. + If GetObjectLocation returns fnfErr, then the location information + returned is valid, but it describes an object that doesn't exist. + You can use the location information for another operation, such as + creating a file or directory. + + vRefNum input: Volume specification. + dirID input: Directory ID. + pathname input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + realVRefNum output: The real volume reference number. + realParID output: The parent directory ID of the specified object. + realName output: The name of the specified object (the case of the + object name may not be the same as the object's + catalog entry on disk - since the Macintosh file + system is not case sensitive, it shouldn't matter). + isDirectory output: True if object is a directory; false if object + is a file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + notAFileErr -1302 The pathname is nil, the pathname + is empty, or the pathname cannot refer + to a filename + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSMakeFSSpecCompat +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetDirItems( + short vRefNum, + long dirID, + ConstStr255Param name, + Boolean getFiles, + Boolean getDirectories, + FSSpecPtr items, + short reqItemCount, + short * actItemCount, + short * itemIndex); + + +/* + The GetDirItems function returns a list of items in the specified + directory in an array of FSSpec records. File, subdirectories, or + both can be returned in the list. + + A noErr result indicates that the items array was filled + (actItemCount == reqItemCount) and there may be additional items + left in the directory. A fnfErr result indicates that the end of + the directory list was found and actItemCount items were actually + found this time. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + getFiles input: Pass true to have files added to the items list. + getDirectories input: Pass true to have directories added to the + items list. + items input: Pointer to array of FSSpec where the item list + is returned. + reqItemCount input: Maximum number of items to return (the number + of elements in the items array). + actItemCount output: The number of items actually returned. + itemIndex input: The current item index position. Set to 1 to + start with the first item in the directory. + output: The item index position to get the next item. + Pass this value the next time you call + GetDirItems to start where you left off. + + Result Codes + noErr 0 No error, but there are more items + to list + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found, there are no more items + to be listed. + paramErr -50 No default volume or itemIndex was <= 0 + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +DeleteDirectoryContents( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The DeleteDirectoryContents function deletes the contents of a directory. + All files and subdirectories in the specified directory are deleted. + If a locked file or directory is encountered, it is unlocked and then + deleted. If any unexpected errors are encountered, + DeleteDirectoryContents quits and returns to the caller. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to directory name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + fBsyErr -47 File busy, directory not empty, or working directory control block open + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: DeleteDirectory +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +DeleteDirectory( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The DeleteDirectory function deletes a directory and its contents. + All files and subdirectories in the specified directory are deleted. + If a locked file or directory is encountered, it is unlocked and then + deleted. After deleting the directories contents, the directory is + deleted. If any unexpected errors are encountered, DeleteDirectory + quits and returns to the caller. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to directory name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + fBsyErr -47 File busy, directory not empty, or working directory control block open + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: DeleteDirectoryContents +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +CheckObjectLock( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The CheckObjectLock function determines if a file or directory is locked. + If CheckObjectLock returns noErr, then the file or directory + is not locked. If CheckObjectLock returns fLckdErr, the it is locked. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: FSpCheckObjectLock +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpCheckObjectLock(const FSSpec * spec); + + +/* + The FSpCheckObjectLock function determines if a file or directory is locked. + If FSpCheckObjectLock returns noErr, then the file or directory + is not locked. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + Also see: CheckObjectLock +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetFileSize( + short vRefNum, + long dirID, + ConstStr255Param fileName, + long * dataSize, + long * rsrcSize); + + +/* + The GetFileSize function returns the logical size of a file's + data and resource fork. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: The name of the file. + dataSize output: The number of bytes in the file's data fork. + rsrcSize output: The number of bytes in the file's resource fork. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpGetFileSize +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpGetFileSize( + const FSSpec * spec, + long * dataSize, + long * rsrcSize); + + +/* + The FSpGetFileSize function returns the logical size of a file's + data and resource fork. + + spec input: An FSSpec record specifying the file. + dataSize output: The number of bytes in the file's data fork. + rsrcSize output: The number of bytes in the file's resource fork. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume + dirNFErrdirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: GetFileSize +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +BumpDate( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The BumpDate function changes the modification date of a file or + directory to the current date/time. If the modification date is already + equal to the current date/time, then add one second to the + modification date. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpBumpDate +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpBumpDate(const FSSpec * spec); + + +/* + The FSpBumpDate function changes the modification date of a file or + directory to the current date/time. If the modification date is already + equal to the current date/time, then add one second to the + modification date. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: BumpDate +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ChangeCreatorType( + short vRefNum, + long dirID, + ConstStr255Param name, + OSType creator, + OSType fileType); + + +/* + The ChangeCreatorType function changes the creator or file type of a file. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: The name of the file. + creator input: The new creator type or 0x00000000 to leave + the creator type alone. + fileType input: The new file type or 0x00000000 to leave the + file type alone. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + notAFileErr -1302 Name was not a file + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpChangeCreatorType +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpChangeCreatorType( + const FSSpec * spec, + OSType creator, + OSType fileType); + + +/* + The FSpChangeCreatorType function changes the creator or file type of a file. + + spec input: An FSSpec record specifying the file. + creator input: The new creator type or 0x00000000 to leave + the creator type alone. + fileType input: The new file type or 0x00000000 to leave the + file type alone. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + notAFileErr -1302 Name was not a file + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: ChangeCreatorType +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ChangeFDFlags( + short vRefNum, + long dirID, + ConstStr255Param name, + Boolean setBits, + unsigned short flagBits); + + +/* + The ChangeFDFlags function sets or clears Finder Flag bits in the + fdFlags field of a file or directory's FInfo record. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + setBits input: If true, then set the bits specified in flagBits. + If false, then clear the bits specified in flagBits. + flagBits input: The flagBits parameter specifies which Finder Flag + bits to set or clear. If a bit in flagBits is set, + then the same bit in fdFlags is either set or + cleared depending on the state of the setBits + parameter. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpChangeFDFlags +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpChangeFDFlags( + const FSSpec * spec, + Boolean setBits, + unsigned short flagBits); + + +/* + The FSpChangeFDFlags function sets or clears Finder Flag bits in the + fdFlags field of a file or directory's FInfo record. + + spec input: An FSSpec record specifying the object. + setBits input: If true, then set the bits specified in flagBits. + If false, then clear the bits specified in flagBits. + flagBits input: The flagBits parameter specifies which Finder Flag + bits to set or clear. If a bit in flagBits is set, + then the same bit in fdFlags is either set or + cleared depending on the state of the setBits + parameter. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: ChangeFDFlags +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +SetIsInvisible( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The SetIsInvisible function sets the invisible bit in the fdFlags + word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpSetIsInvisible, ClearIsInvisible, FSpClearIsInvisible +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetIsInvisible(const FSSpec * spec); + + +/* + The FSpSetIsInvisible function sets the invisible bit in the fdFlags + word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetIsInvisible, ClearIsInvisible, FSpClearIsInvisible +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ClearIsInvisible( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The ClearIsInvisible function clears the invisible bit in the fdFlags + word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetIsInvisible, FSpSetIsInvisible, FSpClearIsInvisible +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpClearIsInvisible(const FSSpec * spec); + + +/* + The FSpClearIsInvisible function clears the invisible bit in the fdFlags + word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetIsInvisible, FSpSetIsInvisible, ClearIsInvisible +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +SetNameLocked( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The SetNameLocked function sets the nameLocked bit in the fdFlags word + of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpSetNameLocked, ClearNameLocked, FSpClearNameLocked +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetNameLocked(const FSSpec * spec); + + +/* + The FSpSetNameLocked function sets the nameLocked bit in the fdFlags word + of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetNameLocked, ClearNameLocked, FSpClearNameLocked +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ClearNameLocked( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The ClearNameLocked function clears the nameLocked bit in the fdFlags + word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetNameLocked, FSpSetNameLocked, FSpClearNameLocked +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpClearNameLocked(const FSSpec * spec); + + +/* + The FSpClearNameLocked function clears the nameLocked bit in the fdFlags + word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetNameLocked, FSpSetNameLocked, ClearNameLocked +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +SetIsStationery( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The SetIsStationery function sets the isStationery bit in the + fdFlags word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpSetIsStationery, ClearIsStationery, FSpClearIsStationery +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetIsStationery(const FSSpec * spec); + + +/* + The FSpSetIsStationery function sets the isStationery bit in the + fdFlags word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetIsStationery, ClearIsStationery, FSpClearIsStationery +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ClearIsStationery( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The ClearIsStationery function clears the isStationery bit in the + fdFlags word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetIsStationery, FSpSetIsStationery, FSpClearIsStationery +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpClearIsStationery(const FSSpec * spec); + + +/* + The FSpClearIsStationery function clears the isStationery bit in the + fdFlags word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetIsStationery, FSpSetIsStationery, ClearIsStationery +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +SetHasCustomIcon( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The SetHasCustomIcon function sets the hasCustomIcon bit in the + fdFlags word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpSetHasCustomIcon, ClearHasCustomIcon, FSpClearHasCustomIcon +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpSetHasCustomIcon(const FSSpec * spec); + + +/* + The FSpSetHasCustomIcon function sets the hasCustomIcon bit in the + fdFlags word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetHasCustomIcon, ClearHasCustomIcon, FSpClearHasCustomIcon +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ClearHasCustomIcon( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The ClearHasCustomIcon function clears the hasCustomIcon bit in the + fdFlags word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetHasCustomIcon, FSpSetHasCustomIcon, FSpClearHasCustomIcon +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpClearHasCustomIcon(const FSSpec * spec); + + +/* + The FSpClearHasCustomIcon function clears the hasCustomIcon bit in the + fdFlags word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: SetHasCustomIcon, FSpSetHasCustomIcon, ClearHasCustomIcon +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +ClearHasBeenInited( + short vRefNum, + long dirID, + ConstStr255Param name); + + +/* + The ClearHasBeenInited function clears the hasBeenInited bit in the + fdFlags word of the specified file or directory's finder information. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID specifies + a directory that's the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpClearHasBeenInited +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpClearHasBeenInited(const FSSpec * spec); + + +/* + The FSpClearHasBeenInited function clears the hasBeenInited bit in the + fdFlags word of the specified file or directory's finder information. + + spec input: An FSSpec record specifying the object. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: ClearHasBeenInited +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +CopyFileMgrAttributes( + short srcVRefNum, + long srcDirID, + ConstStr255Param srcName, + short dstVRefNum, + long dstDirID, + ConstStr255Param dstName, + Boolean copyLockBit); + + +/* + The CopyFileMgrAttributes function copies all File Manager attributes + from the source file or directory to the destination file or directory. + If copyLockBit is true, then set the locked state of the destination + to match the source. + + srcVRefNum input: Source volume specification. + srcDirID input: Source directory ID. + srcName input: Pointer to source object name, or nil when + srcDirID specifies a directory that's the object. + dstVRefNum input: Destination volume specification. + dstDirID input: Destination directory ID. + dstName input: Pointer to destination object name, or nil when + dstDirID specifies a directory that's the object. + copyLockBit input: If true, set the locked state of the destination + to match the source. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: FSpCopyFileMgrAttributes +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpCopyFileMgrAttributes( + const FSSpec * srcSpec, + const FSSpec * dstSpec, + Boolean copyLockBit); + + +/* + The FSpCopyFileMgrAttributes function copies all File Manager attributes + from the source file or directory to the destination file or directory. + If copyLockBit is true, then set the locked state of the destination + to match the source. + + srcSpec input: An FSSpec record specifying the source object. + dstSpec input: An FSSpec record specifying the destination object. + copyLockBit input: If true, set the locked state of the destination + to match the source. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + paramErr -50 No default volume + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: CopyFileMgrAttributes +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +HOpenAware( + short vRefNum, + long dirID, + ConstStr255Param fileName, + short denyModes, + short * refNum); + + +/* + The HOpenAware function opens the data fork of a file using deny mode + permissions instead the normal File Manager permissions. If OpenDeny + is not available, then HOpenAware translates the deny modes to the + closest File Manager permissions and tries to open the file with + OpenDF first, and then Open if OpenDF isn't available. By using + HOpenAware with deny mode permissions, a program can be "AppleShare + aware" and fall back on the standard File Manager open calls + automatically. + + vRefNum input: Volume specification. + dirID input: Directory ID. + fileName input: The name of the file. + denyModes input: The deny modes access under which to open the file. + refNum output: The file reference number of the opened file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + tmfoErr -42 Too many files open + fnfErr -43 File not found + wPrErr -44 Volume locked by hardware + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + opWrErr -49 File already open for writing + paramErr -50 No default volume + permErr -54 File is already open and cannot be opened using specified deny modes + afpAccessDenied -5000 User does not have the correct access to the file + afpDenyConflict -5006 Requested access permission not possible + + __________ + + See also: FSpOpenAware, HOpenRFAware, FSpOpenRFAware +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpOpenAware( + const FSSpec * spec, + short denyModes, + short * refNum); + + +/* + The FSpOpenAware function opens the data fork of a file using deny mode + permissions instead the normal File Manager permissions. If OpenDeny + is not available, then FSpOpenAware translates the deny modes to the + closest File Manager permissions and tries to open the file with + OpenDF first, and then Open if OpenDF isn't available. By using + FSpOpenAware with deny mode permissions, a program can be "AppleShare + aware" and fall back on the standard File Manager open calls + automatically. + + spec input: An FSSpec record specifying the file. + denyModes input: The deny modes access under which to open the file. + refNum output: The file reference number of the opened file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + tmfoErr -42 Too many files open + fnfErr -43 File not found + wPrErr -44 Volume locked by hardware + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + opWrErr -49 File already open for writing + paramErr -50 No default volume + permErr -54 File is already open and cannot be opened using specified deny modes + afpAccessDenied -5000 User does not have the correct access to the file + afpDenyConflict -5006 Requested access permission not possible + + __________ + + See also: HOpenAware, HOpenRFAware, FSpOpenRFAware +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +HOpenRFAware( + short vRefNum, + long dirID, + ConstStr255Param fileName, + short denyModes, + short * refNum); + + +/* + The HOpenRFAware function opens the resource fork of a file using deny + mode permissions instead the normal File Manager permissions. If + OpenRFDeny is not available, then HOpenRFAware translates the deny + modes to the closest File Manager permissions and tries to open the + file with OpenRF. By using HOpenRFAware with deny mode permissions, + a program can be "AppleShare aware" and fall back on the standard + File Manager open calls automatically. + + vRefNum input: Volume specification. + dirID input: Directory ID. + fileName input: The name of the file. + denyModes input: The deny modes access under which to open the file. + refNum output: The file reference number of the opened file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + tmfoErr -42 Too many files open + fnfErr -43 File not found + wPrErr -44 Volume locked by hardware + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + opWrErr -49 File already open for writing + paramErr -50 No default volume + permErr -54 File is already open and cannot be opened using specified deny modes + afpAccessDenied -5000 User does not have the correct access to the file + afpDenyConflict -5006 Requested access permission not possible + + __________ + + See also: HOpenAware, FSpOpenAware, FSpOpenRFAware +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpOpenRFAware( + const FSSpec * spec, + short denyModes, + short * refNum); + + +/* + The FSpOpenRFAware function opens the resource fork of a file using deny + mode permissions instead the normal File Manager permissions. If + OpenRFDeny is not available, then FSpOpenRFAware translates the deny + modes to the closest File Manager permissions and tries to open the + file with OpenRF. By using FSpOpenRFAware with deny mode permissions, + a program can be "AppleShare aware" and fall back on the standard + File Manager open calls automatically. + + spec input: An FSSpec record specifying the file. + denyModes input: The deny modes access under which to open the file. + refNum output: The file reference number of the opened file. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + tmfoErr -42 Too many files open + fnfErr -43 File not found + wPrErr -44 Volume locked by hardware + fLckdErr -45 File is locked + vLckdErr -46 Volume is locked or read-only + opWrErr -49 File already open for writing + paramErr -50 No default volume + permErr -54 File is already open and cannot be opened using specified deny modes + afpAccessDenied -5000 User does not have the correct access to the file + afpDenyConflict -5006 Requested access permission not possible + + __________ + + See also: HOpenAware, FSpOpenAware, HOpenRFAware +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSReadNoCache( + short refNum, + long * count, + void * buffPtr); + + +/* + The FSReadNoCache function reads any number of bytes from an open file + while asking the file system to bypass its cache mechanism. + + refNum input: The file reference number of an open file. + count input: The number of bytes to read. + output: The number of bytes actually read. + buffPtr input: A pointer to the data buffer into which the bytes are + to be read. + + Result Codes + noErr 0 No error + readErr 19 Driver does not respond to read requests + badUnitErr 21 Driver reference number does not + match unit table + unitEmptyErr 22 Driver reference number specifies a + nil handle in unit table + abortErr 27 Request aborted by KillIO + notOpenErr 28 Driver not open + ioErr 36 Data does not match in read-verify mode + fnOpnErr -38 File not open + rfNumErr -51 Bad reference number + afpAccessDenied -5000 User does not have the correct access to + the file + + __________ + + See also: FSWriteNoCache +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSWriteNoCache( + short refNum, + long * count, + const void * buffPtr); + + +/* + The FSReadNoCache function writes any number of bytes to an open file + while asking the file system to bypass its cache mechanism. + + refNum input: The file reference number of an open file. + count input: The number of bytes to write to the file. + output: The number of bytes actually written. + buffPtr input: A pointer to the data buffer from which the bytes are + to be written. + + Result Codes + noErr 0 No error + writErr 20 Driver does not respond to write requests + badUnitErr 21 Driver reference number does not + match unit table + unitEmptyErr 22 Driver reference number specifies a + nil handle in unit table + abortErr 27 Request aborted by KillIO + notOpenErr 28 Driver not open + dskFulErr -34 Disk full + ioErr 36 Data does not match in read-verify mode + fnOpnErr -38 File not open + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + rfNumErr -51 Bad reference number + wrPermErr -61 Read/write permission doesn¹t + allow writing + afpAccessDenied -5000 User does not have the correct access to + the file + + __________ + + See also: FSReadNoCache +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSWriteVerify( + short refNum, + long * count, + const void * buffPtr); + + +/* + The FSWriteVerify function writes any number of bytes to an open file + and then verifies that the data was actually written to the device. + + refNum input: The file reference number of an open file. + count input: The number of bytes to write to the file. + output: The number of bytes actually written and verified. + buffPtr input: A pointer to the data buffer from which the bytes are + to be written. + + Result Codes + noErr 0 No error + readErr 19 Driver does not respond to read requests + writErr 20 Driver does not respond to write requests + badUnitErr 21 Driver reference number does not + match unit table + unitEmptyErr 22 Driver reference number specifies a + nil handle in unit table + abortErr 27 Request aborted by KillIO + notOpenErr 28 Driver not open + dskFulErr -34 Disk full + ioErr 36 Data does not match in read-verify mode + fnOpnErr -38 File not open + eofErr -39 Logical end-of-file reached + posErr -40 Attempt to position mark before start + of file + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + rfNumErr -51 Bad reference number + gfpErr -52 Error during GetFPos + wrPermErr -61 Read/write permission doesn¹t + allow writing + memFullErr -108 Not enough room in heap zone to allocate + verify buffer + afpAccessDenied -5000 User does not have the correct access to + the file +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +CopyFork( + short srcRefNum, + short dstRefNum, + void * copyBufferPtr, + long copyBufferSize); + + +/* + The CopyFork function copies all data from the source fork to the + destination fork of open file forks and makes sure the destination EOF + is equal to the source EOF. + + srcRefNum input: The source file reference number. + dstRefNum input: The destination file reference number. + copyBufferPtr input: Pointer to buffer to use during copy. The + buffer should be at least 512-bytes minimum. + The larger the buffer, the faster the copy. + copyBufferSize input: The size of the copy buffer. + + Result Codes + noErr 0 No error + readErr 19 Driver does not respond to read requests + writErr 20 Driver does not respond to write requests + badUnitErr 21 Driver reference number does not + match unit table + unitEmptyErr 22 Driver reference number specifies a + nil handle in unit table + abortErr 27 Request aborted by KillIO + notOpenErr 28 Driver not open + dskFulErr -34 Disk full + ioErr 36 Data does not match in read-verify mode + fnOpnErr -38 File not open + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Software volume lock + rfNumErr -51 Bad reference number + wrPermErr -61 Read/write permission doesn¹t + allow writing + afpAccessDenied -5000 User does not have the correct access to + the file +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetFileLocation( + short refNum, + short * vRefNum, + long * dirID, + StringPtr fileName); + + +/* + The GetFileLocation function gets the location (volume reference number, + directory ID, and fileName) of an open file. + + refNum input: The file reference number of an open file. + vRefNum output: The volume reference number. + dirID output: The parent directory ID. + fileName input: Points to a buffer (minimum Str63) where the + filename is to be returned or must be nil. + output: The filename. + + Result Codes + noErr 0 No error + nsvErr -35 Specified volume doesn¹t exist + fnOpnErr -38 File not open + rfNumErr -51 Reference number specifies nonexistent + access path + + __________ + + See also: FSpGetFileLocation +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpGetFileLocation( + short refNum, + FSSpec * spec); + + +/* + The FSpGetFileLocation function gets the location of an open file in + an FSSpec record. + + refNum input: The file reference number of an open file. + spec output: FSSpec record containing the file name and location. + + Result Codes + noErr 0 No error + nsvErr -35 Specified volume doesn¹t exist + fnOpnErr -38 File not open + rfNumErr -51 Reference number specifies nonexistent + access path + + __________ + + See also: GetFileLocation +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +CopyDirectoryAccess( + short srcVRefNum, + long srcDirID, + ConstStr255Param srcName, + short dstVRefNum, + long dstDirID, + ConstStr255Param dstName); + + +/* + The CopyDirectoryAccess function copies the AFP directory access + privileges from one directory to another. Both directories must be on + the same file server, but not necessarily on the same server volume. + + srcVRefNum input: Source volume specification. + srcDirID input: Source directory ID. + srcName input: Pointer to source directory name, or nil when + srcDirID specifies the directory. + dstVRefNum input: Destination volume specification. + dstDirID input: Destination directory ID. + dstName input: Pointer to destination directory name, or nil when + dstDirID specifies the directory. + + Result Codes + noErr 0 No error + nsvErr -35 Volume not found + fnfErr -43 Directory not found + vLckdErr -46 Volume is locked or read-only + paramErr -50 Volume doesn't support this function + afpAccessDenied -5000 User does not have the correct access + to the directory + afpObjectTypeErr -5025 Object is a file, not a directory + + __________ + + See also: FSpCopyDirectoryAccess +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpCopyDirectoryAccess( + const FSSpec * srcSpec, + const FSSpec * dstSpec); + + +/* + The FSpCopyDirectoryAccess function copies the AFP directory access + privileges from one directory to another. Both directories must be on + the same file server, but not necessarily on the same server volume. + + srcSpec input: An FSSpec record specifying the source directory. + dstSpec input: An FSSpec record specifying the destination directory. + + Result Codes + noErr 0 No error + nsvErr -35 Volume not found + fnfErr -43 Directory not found + vLckdErr -46 Volume is locked or read-only + paramErr -50 Volume doesn't support this function + afpAccessDenied -5000 User does not have the correct access + to the directory + afpObjectTypeErr -5025 Object is a file, not a directory + + __________ + + See also: CopyDirectoryAccess +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +HMoveRenameCompat( + short vRefNum, + long srcDirID, + ConstStr255Param srcName, + long dstDirID, + ConstStr255Param dstpathName, + ConstStr255Param copyName); + + +/* + The HMoveRenameCompat function moves a file or directory and optionally + renames it. The source and destination locations must be on the same + volume. This routine works even if the volume doesn't support MoveRename. + + vRefNum input: Volume specification. + srcDirID input: Source directory ID. + srcName input: The source object name. + dstDirID input: Destination directory ID. + dstName input: Pointer to destination directory name, or + nil when dstDirID specifies a directory. + copyName input: Points to the new name if the object is to be + renamed or nil if the object isn't to be renamed. + + Result Codes + noErr 0 No error + dirFulErr -33 File directory full + dskFulErr -34 Disk is full + nsvErr -35 Volume not found + ioErr -36 I/O error + bdNamErr -37 Bad filename or attempt to move into + a file + fnfErr -43 Source file or directory not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Destination volume is read-only + fBsyErr -47 File busy, directory not empty, or + working directory control block open + dupFNErr -48 Destination already exists + paramErr -50 Volume doesn't support this function, + no default volume, or source and + volOfflinErr -53 Volume is offline + fsRnErr -59 Problem during rename + dirNFErr -120 Directory not found or incomplete pathname + badMovErr -122 Attempted to move directory into + offspring + wrgVolTypErr -123 Not an HFS volume (it's a MFS volume) + notAFileErr -1302 The pathname is nil, the pathname + is empty, or the pathname cannot refer + to a filename + diffVolErr -1303 Files on different volumes + afpAccessDenied -5000 The user does not have the right to + move the file or directory + afpObjectTypeErr -5025 Directory not found or incomplete pathname + afpSameObjectErr -5038 Source and destination files are the same + + __________ + + See also: FSpMoveRenameCompat +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +FSpMoveRenameCompat( + const FSSpec * srcSpec, + const FSSpec * dstSpec, + ConstStr255Param copyName); + + +/* + The FSpMoveRenameCompat function moves a file or directory and optionally + renames it. The source and destination locations must be on the same + volume. This routine works even if the volume doesn't support MoveRename. + + srcSpec input: An FSSpec record specifying the source object. + dstSpec input: An FSSpec record specifying the destination + directory. + copyName input: Points to the new name if the object is to be + renamed or nil if the object isn't to be renamed. + + Result Codes + noErr 0 No error + dirFulErr -33 File directory full + dskFulErr -34 Disk is full + nsvErr -35 Volume not found + ioErr -36 I/O error + bdNamErr -37 Bad filename or attempt to move into + a file + fnfErr -43 Source file or directory not found + wPrErr -44 Hardware volume lock + fLckdErr -45 File is locked + vLckdErr -46 Destination volume is read-only + fBsyErr -47 File busy, directory not empty, or + working directory control block open + dupFNErr -48 Destination already exists + paramErr -50 Volume doesn't support this function, + no default volume, or source and + volOfflinErr -53 Volume is offline + fsRnErr -59 Problem during rename + dirNFErr -120 Directory not found or incomplete pathname + badMovErr -122 Attempted to move directory into + offspring + wrgVolTypErr -123 Not an HFS volume (it's a MFS volume) + notAFileErr -1302 The pathname is nil, the pathname + is empty, or the pathname cannot refer + to a filename + diffVolErr -1303 Files on different volumes + afpAccessDenied -5000 The user does not have the right to + move the file or directory + afpObjectTypeErr -5025 Directory not found or incomplete pathname + afpSameObjectErr -5038 Source and destination files are the same + + __________ + + See also: HMoveRenameCompat +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +BuildAFPVolMountInfo( + short flags, + char nbpInterval, + char nbpCount, + short uamType, + Str32 zoneName, + Str31 serverName, + Str27 volName, + Str31 userName, + Str8 userPassword, + Str8 volPassword, + AFPVolMountInfoPtr * afpInfoPtr); + + +/* + The BuildAFPVolMountInfo function allocates and initializes the fields + of an AFPVolMountInfo record before using that record to call + the VolumeMount function. + + flags input: The AFP mounting flags. 0 = normal mount; + set bit 0 to inhibit greeting messages. + nbpInterval input: The interval used for VolumeMount's + NBP Lookup call. 7 is a good choice. + nbpCount input: The retry count used for VolumeMount's + NBP Lookup call. 5 is a good choice. + uamType input: The user authentication method to use. + zoneName input: The AppleTalk zone name of the server. + serverName input: The AFP server name. + volName input: The AFP volume name. + userName input: The user name (zero length Pascal string for + guest). + userPassWord input: The user password (zero length Pascal string + if no user password) + volPassWord input: The volume password (zero length Pascal string + if no volume password) + afpInfoPtr output: A pointer to the newly created and initialized + AFPVolMountInfo record. If the function fails to + create an AFPVolMountInfo record, it sets + afpInfoPtr to NULL and the function result is + memFullErr. Your program is responsible + for disposing of this pointer when it is finished + with it. + + Result Codes + noErr 0 No error + memFullErr -108 memory full error + + __________ + + Also see: GetVolMountInfoSize, GetVolMountInfo, VolumeMount, + RetrieveAFPVolMountInfo, BuildAFPXVolMountInfo, + RetrieveAFPXVolMountInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +RetrieveAFPVolMountInfo( + AFPVolMountInfoPtr afpInfoPtr, + short * flags, + short * uamType, + StringPtr zoneName, + StringPtr serverName, + StringPtr volName, + StringPtr userName); + + +/* + The RetrieveAFPVolMountInfo function retrieves the AFP mounting + information returned in an AFPVolMountInfo record by the + GetVolMountInfo function. + + afpInfoPtr input: Pointer to AFPVolMountInfo record that contains + the AFP mounting information. + flags output: The AFP mounting flags. + uamType output: The user authentication method used. + zoneName output: The AppleTalk zone name of the server. + serverName output: The AFP server name. + volName output: The AFP volume name. + userName output: The user name (zero length Pascal string for + guest). + + Result Codes + noErr 0 No error + paramErr -50 media field in AFP mounting information + was not AppleShareMediaType + + __________ + + Also see: GetVolMountInfoSize, GetVolMountInfo, VolumeMount, + BuildAFPVolMountInfo, BuildAFPXVolMountInfo, + RetrieveAFPXVolMountInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +BuildAFPXVolMountInfo( + short flags, + char nbpInterval, + char nbpCount, + short uamType, + Str32 zoneName, + Str31 serverName, + Str27 volName, + Str31 userName, + Str8 userPassword, + Str8 volPassword, + Str32 uamName, + unsigned long alternateAddressLength, + void * alternateAddress, + AFPXVolMountInfoPtr * afpXInfoPtr); + + +/* + The BuildAFPXVolMountInfo function allocates and initializes the fields + of an AFPXVolMountInfo record before using that record to call + the VolumeMount function. + + flags input: The AFP mounting flags. + nbpInterval input: The interval used for VolumeMount's + NBP Lookup call. 7 is a good choice. + nbpCount input: The retry count used for VolumeMount's + NBP Lookup call. 5 is a good choice. + uamType input: The user authentication method to use. + zoneName input: The AppleTalk zone name of the server. + serverName input: The AFP server name. + volName input: The AFP volume name. + userName input: The user name (zero length Pascal string + for guest). + userPassWord input: The user password (zero length Pascal + string if no user password) + volPassWord input: The volume password (zero length Pascal + string if no volume password) + uamName input: The User Authentication Method name. + alternateAddressLength input: Length of alternateAddress data. + alternateAddress input The AFPAlternateAddress (variable length) + afpXInfoPtr output: A pointer to the newly created and + initialized AFPVolMountInfo record. + If the function fails to create an + AFPVolMountInfo record, it sets + afpInfoPtr to NULL and the function + result is memFullErr. Your program is + responsible for disposing of this pointer + when it is finished with it. + + Result Codes + noErr 0 No error + memFullErr -108 memory full error + + __________ + + Also see: GetVolMountInfoSize, GetVolMountInfo, VolumeMount, + BuildAFPVolMountInfo, RetrieveAFPVolMountInfo, + RetrieveAFPXVolMountInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +RetrieveAFPXVolMountInfo( + AFPXVolMountInfoPtr afpXInfoPtr, + short * flags, + short * uamType, + StringPtr zoneName, + StringPtr serverName, + StringPtr volName, + StringPtr userName, + StringPtr uamName, + unsigned long * alternateAddressLength, + AFPAlternateAddress ** alternateAddress); + + +/* + The RetrieveAFPXVolMountInfo function retrieves the AFP mounting + information returned in an AFPXVolMountInfo record by the + GetVolMountInfo function. + + afpXInfoPtr input: Pointer to AFPXVolMountInfo record that + contains the AFP mounting information. + flags output: The AFP mounting flags. + uamType output: The user authentication method used. + zoneName output: The AppleTalk zone name of the server. + serverName output: The AFP server name. + volName output: The AFP volume name. + userName output: The user name (zero length Pascal + string for guest). + uamName output: The User Authentication Method name. + alternateAddressLength output: Length of alternateAddress data returned. + alternateAddress: output: A pointer to the newly created and + AFPAlternateAddress record (a variable + length record). If the function fails to + create an AFPAlternateAddress record, + it sets alternateAddress to NULL and the + function result is memFullErr. Your + program is responsible for disposing of + this pointer when it is finished with it. + + Result Codes + noErr 0 No error + paramErr -50 media field in AFP mounting information + was not AppleShareMediaType + memFullErr -108 memory full error + + __________ + + Also see: GetVolMountInfoSize, GetVolMountInfo, VolumeMount, + BuildAFPVolMountInfo, RetrieveAFXVolMountInfo, + BuildAFPXVolMountInfo +*/ + +/*****************************************************************************/ + +EXTERN_API( OSErr ) +GetUGEntries( + short objType, + UGEntryPtr entries, + long reqEntryCount, + long * actEntryCount, + long * objID); + + +/* + The GetUGEntries functions retrieves a list of user or group entries + from the local file server. + + objType input: The object type: -1 = group; 0 = user + UGEntries input: Pointer to array of UGEntry records where the list + is returned. + reqEntryCount input: The number of elements in the UGEntries array. + actEntryCount output: The number of entries returned. + objID input: The current index position. Set to 0 to start with + the first entry. + output: The index position to get the next entry. Pass this + value the next time you call GetUGEntries to start + where you left off. + + Result Codes + noErr 0 No error + fnfErr -43 No more users or groups + paramErr -50 Function not supported; or, ioObjID is + negative + + __________ + + Also see: GetUGEntry +*/ + +/*****************************************************************************/ + + + +#include "OptimizationEnd.h" + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=reset +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(pop) +#elif PRAGMA_STRUCT_PACK + #pragma pack() +#endif + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __MOREFILESEXTRAS__ */ + diff --git a/corelib/morefile/MoreFilesX.c b/corelib/morefile/MoreFilesX.c new file mode 100644 index 00000000..dadb4553 --- /dev/null +++ b/corelib/morefile/MoreFilesX.c @@ -0,0 +1,2782 @@ +/* + File: MoreFilesX.c + + Contains: A collection of useful high-level File Manager routines + which use the HFS Plus APIs wherever possible. + + Version: MoreFilesX 1.0 + + Copyright: © 1992-2002 by Apple Computer, Inc., all rights reserved. + + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: For bug reports, consult the following page on + the World Wide Web: + http://developer.apple.com/bugreporter/ + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <1> 1/25/02 JL MoreFilesX 1.0 +*/ + +#if 0 + #include <Carbon/Carbon.h> +#else + #include <MacTypes.h> + #include <OSUtils.h> + #include <TextCommon.h> + #include <UTCUtils.h> + #include <Finder.h> + #include <Files.h> + #include <MacErrors.h> + #include <MacMemory.h> + #include <Folders.h> + #include <HFSVolumes.h> + #include <Gestalt.h> + #include <NumberFormatting.h> + #include <Script.h> + #include <UnicodeConverter.h> + #include <Debugging.h> + #include <string.h> +#endif + +#include "MoreFilesX.h" + +/* Set BuildingMoreFilesXForMacOS9 to 1 if building for Mac OS 9 */ +#ifndef BuildingMoreFilesXForMacOS9 + #define BuildingMoreFilesXForMacOS9 0 +#endif + +/*****************************************************************************/ + +#pragma mark ----- Local type definitions ----- + +struct FSIterateContainerGlobals +{ + IterateContainerFilterProcPtr iterateFilter; /* pointer to IterateFilterProc */ + FSCatalogInfoBitmap whichInfo; /* fields of the CatalogInfo to get */ + FSCatalogInfo catalogInfo; /* FSCatalogInfo */ + FSRef ref; /* FSRef */ + FSSpec spec; /* FSSpec */ + FSSpec *specPtr; /* pointer to spec field, or NULL */ + HFSUniStr255 name; /* HFSUniStr255 */ + HFSUniStr255 *namePtr; /* pointer to name field, or NULL */ + void *yourDataPtr; /* a pointer to caller supplied data the filter may need to access */ + ItemCount maxLevels; /* maximum levels to iterate through */ + ItemCount currentLevel; /* the current level FSIterateContainerLevel is on */ + Boolean quitFlag; /* set to true if filter wants to kill interation */ + Boolean containerChanged; /* temporary - set to true if the current container changed during iteration */ + OSErr result; /* result */ + ItemCount actualObjects; /* number of objects returned */ +}; +typedef struct FSIterateContainerGlobals FSIterateContainerGlobals; + +struct FSDeleteContainerGlobals +{ + OSErr result; /* result */ + ItemCount actualObjects; /* number of objects returned */ + FSCatalogInfo catalogInfo; /* FSCatalogInfo */ +}; +typedef struct FSDeleteContainerGlobals FSDeleteContainerGlobals; + +/*****************************************************************************/ + +#pragma mark ----- Local prototypes ----- + +static +void +DeleteLevel( + const FSRef *container, + FSDeleteContainerGlobals *theGlobals); + +static +void +FSIterateContainerLevel( + FSIterateContainerGlobals *theGlobals); + +static +OSErr +GenerateUniqueHFSUniStr( + long *startSeed, + const FSRef *dir1, + const FSRef *dir2, + HFSUniStr255 *uniqueName); + +/*****************************************************************************/ + +#pragma mark ----- File Access Routines ----- + +/*****************************************************************************/ + +OSErr +FSCopyFork( + SInt16 srcRefNum, + SInt16 dstRefNum, + void *copyBufferPtr, + ByteCount copyBufferSize) +{ + OSErr srcResult; + OSErr dstResult; + OSErr result; + SInt64 forkSize; + ByteCount readActualCount; + + /* check input parameters */ + require_action((NULL != copyBufferPtr) && (0 != copyBufferSize), BadParameter, result = paramErr); + + /* get source fork size */ + result = FSGetForkSize(srcRefNum, &forkSize); + require_noerr(result, SourceFSGetForkSizeFailed); + + /* allocate disk space for destination fork */ + result = FSSetForkSize(dstRefNum, fsFromStart, forkSize); + require_noerr(result, DestinationFSSetForkSizeFailed); + + /* reset source fork's position to 0 */ + result = FSSetForkPosition(srcRefNum, fsFromStart, 0); + require_noerr(result, SourceFSSetForkPositionFailed); + + /* reset destination fork's position to 0 */ + result = FSSetForkPosition(dstRefNum, fsFromStart, 0); + require_noerr(result, DestinationFSSetForkPositionFailed); + + /* If copyBufferSize is greater than 4K bytes, make it a multiple of 4k bytes */ + /* This will make writes on local volumes faster */ + if ( (copyBufferSize >= 0x00001000) && ((copyBufferSize & 0x00000fff) != 0) ) + { + copyBufferSize &= ~(0x00001000 - 1); + } + + /* copy source to destination */ + srcResult = dstResult = noErr; + while ( (noErr == srcResult) && (noErr == dstResult) ) + { + srcResult = FSReadFork(srcRefNum, fsAtMark + noCacheMask, 0, copyBufferSize, copyBufferPtr, &readActualCount); + dstResult = FSWriteFork(dstRefNum, fsAtMark + noCacheMask, 0, readActualCount, copyBufferPtr, NULL); + } + + /* make sure there were no errors at the destination */ + require_noerr_action(dstResult, DestinationFSWriteForkFailed, result = dstResult); + + /* make sure the error at the source was eofErr */ + require_action(eofErr == srcResult, SourceResultNotEofErr, result = srcResult); + + /* everything went as expected */ + result = noErr; + +SourceResultNotEofErr: +DestinationFSWriteForkFailed: +DestinationFSSetForkPositionFailed: +SourceFSSetForkPositionFailed: +DestinationFSAllocateForkFailed: +DestinationFSSetForkSizeFailed: +SourceFSGetForkSizeFailed: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- Volume Access Routines ----- + +/*****************************************************************************/ + +OSErr +FSGetVolParms( + FSVolumeRefNum volRefNum, + UInt32 bufferSize, + GetVolParmsInfoBuffer *volParmsInfo, + UInt32 *actualInfoSize) +{ + OSErr result; + HParamBlockRec pb; + + /* check parameters */ + require_action((NULL != volParmsInfo) && (NULL != actualInfoSize), + BadParameter, result = paramErr); + + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioVRefNum = volRefNum; + pb.ioParam.ioBuffer = (Ptr)volParmsInfo; + pb.ioParam.ioReqCount = (SInt32)bufferSize; + result = PBHGetVolParmsSync(&pb); + require_noerr(result, PBHGetVolParmsSync); + + /* return number of bytes the file system returned in volParmsInfo buffer */ + *actualInfoSize = (UInt32)pb.ioParam.ioActCount; + +PBHGetVolParmsSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVRefNum( + const FSRef *ref, + FSVolumeRefNum *vRefNum) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action(NULL != vRefNum, BadParameter, result = paramErr); + + /* get the volume refNum from the FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* return volume refNum from catalogInfo */ + *vRefNum = catalogInfo.volume; + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVInfo( + FSVolumeRefNum volume, + HFSUniStr255 *volumeName, /* can be NULL */ + UInt64 *freeBytes, /* can be NULL */ + UInt64 *totalBytes) /* can be NULL */ +{ + OSErr result; + FSVolumeInfo info; + + /* ask for the volume's sizes only if needed */ + result = FSGetVolumeInfo(volume, 0, NULL, + (((NULL != freeBytes) || (NULL != totalBytes)) ? kFSVolInfoSizes : kFSVolInfoNone), + &info, volumeName, NULL); + require_noerr(result, FSGetVolumeInfo); + + if ( NULL != freeBytes ) + { + *freeBytes = info.freeBytes; + } + if ( NULL != totalBytes ) + { + *totalBytes = info.totalBytes; + } + +FSGetVolumeInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVolFileSystemID( + FSVolumeRefNum volume, + UInt16 *fileSystemID, /* can be NULL */ + UInt16 *signature) /* can be NULL */ +{ + OSErr result; + FSVolumeInfo info; + + result = FSGetVolumeInfo(volume, 0, NULL, kFSVolInfoFSInfo, &info, NULL, NULL); + require_noerr(result, FSGetVolumeInfo); + + if ( NULL != fileSystemID ) + { + *fileSystemID = info.filesystemID; + } + if ( NULL != signature ) + { + *signature = info.signature; + } + +FSGetVolumeInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetMountedVolumes( + FSRef ***volumeRefsHandle, /* pointer to handle of FSRefs */ + ItemCount *numVolumes) +{ + OSErr result; + OSErr memResult; + ItemCount volumeIndex; + FSRef ref; + + /* check parameters */ + require_action((NULL != volumeRefsHandle) && (NULL != numVolumes), + BadParameter, result = paramErr); + + /* No volumes yet */ + *numVolumes = 0; + + /* Allocate a handle for the results */ + *volumeRefsHandle = (FSRef **)NewHandle(0); + require_action(NULL != *volumeRefsHandle, NewHandle, result = memFullErr); + + /* Call FSGetVolumeInfo in loop to get all volumes starting with the first */ + volumeIndex = 1; + do + { + result = FSGetVolumeInfo(0, volumeIndex, NULL, kFSVolInfoNone, NULL, NULL, &ref); + if ( noErr == result ) + { + /* concatenate the FSRef to the end of the handle */ + PtrAndHand(&ref, (Handle)*volumeRefsHandle, sizeof(FSRef)); + memResult = MemError(); + require_noerr_action(memResult, MemoryAllocationFailed, result = memResult); + + ++(*numVolumes); /* increment the volume count */ + ++volumeIndex; /* and the volumeIndex to get the next volume*/ + } + } while ( noErr == result ); + + /* nsvErr is OK -- it just means there are no more volumes */ + require(nsvErr == result, FSGetVolumeInfo); + + return ( noErr ); + + /**********************/ + +MemoryAllocationFailed: +FSGetVolumeInfo: + + /* dispose of handle if already allocated and clear the outputs */ + if ( NULL != *volumeRefsHandle ) + { + DisposeHandle((Handle)*volumeRefsHandle); + *volumeRefsHandle = NULL; + } + *numVolumes = 0; + +NewHandle: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- FSRef/FSpec/Path/Name Conversion Routines ----- + +/*****************************************************************************/ + +OSErr +FSRefMakeFSSpec( + const FSRef *ref, + FSSpec *spec) +{ + OSErr result; + + /* check parameters */ + require_action(NULL != spec, BadParameter, result = paramErr); + + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, spec, NULL); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMakeFSRef( + FSVolumeRefNum volRefNum, + SInt32 dirID, + ConstStr255Param name, + FSRef *ref) +{ + OSErr result; + FSRefParam pb; + + /* check parameters */ + require_action(NULL != ref, BadParameter, result = paramErr); + + pb.ioVRefNum = volRefNum; + pb.ioDirID = dirID; + pb.ioNamePtr = (StringPtr)name; + pb.newRef = ref; + result = PBMakeFSRefSync(&pb); + require_noerr(result, PBMakeFSRefSync); + +PBMakeFSRefSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSStatus +FSMakePath( + SInt16 volRefNum, + SInt32 dirID, + ConstStr255Param name, + UInt8 *path, + UInt32 maxPathSize) +{ + OSStatus result; + FSRef ref; + + /* check parameters */ + require_action(NULL != path, BadParameter, result = paramErr); + + /* convert the inputs to an FSRef */ + result = FSMakeFSRef(volRefNum, dirID, name, &ref); + require_noerr(result, FSMakeFSRef); + + /* and then convert the FSRef to a path */ + result = FSRefMakePath(&ref, path, maxPathSize); + require_noerr(result, FSRefMakePath); + +FSRefMakePath: +FSMakeFSRef: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSStatus +FSPathMakeFSSpec( + const UInt8 *path, + FSSpec *spec, + Boolean *isDirectory) /* can be NULL */ +{ + OSStatus result; + FSRef ref; + + /* check parameters */ + require_action(NULL != spec, BadParameter, result = paramErr); + + /* convert the POSIX path to an FSRef */ + result = FSPathMakeRef(path, &ref, isDirectory); + require_noerr(result, FSPathMakeRef); + + /* and then convert the FSRef to an FSSpec */ + result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: +FSPathMakeRef: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +UnicodeNameGetHFSName( + UniCharCount nameLength, + const UniChar *name, + TextEncoding textEncodingHint, + Boolean isVolumeName, + Str31 hfsName) +{ + OSStatus result; + ByteCount unicodeByteLength; + ByteCount unicodeBytesConverted; + ByteCount actualPascalBytes; + UnicodeMapping uMapping; + UnicodeToTextInfo utInfo; + + /* check parameters */ + require_action(NULL != hfsName, BadParameter, result = paramErr); + + /* make sure output is valid in case we get errors or there's nothing to convert */ + StrLength(hfsName) = 0; + + unicodeByteLength = nameLength * sizeof(UniChar); + if ( 0 == unicodeByteLength ) + { + /* do nothing */ + result = noErr; + } + else + { + /* if textEncodingHint is kTextEncodingUnknown, get a "default" textEncodingHint */ + if ( kTextEncodingUnknown == textEncodingHint ) + { + ScriptCode script; + RegionCode region; + + script = (ScriptCode)GetScriptManagerVariable(smSysScript); + region = (RegionCode)GetScriptManagerVariable(smRegionCode); + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, + NULL, &textEncodingHint ); + if ( paramErr == result ) + { + /* ok, ignore the region and try again */ + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, + kTextRegionDontCare, NULL, &textEncodingHint ); + } + if ( noErr != result ) + { + /* ok... try something */ + textEncodingHint = kTextEncodingMacRoman; + } + } + + uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, + kUnicodeCanonicalDecompVariant, kUnicode16BitFormat); + uMapping.otherEncoding = GetTextEncodingBase(textEncodingHint); + uMapping.mappingVersion = kUnicodeUseHFSPlusMapping; + + result = CreateUnicodeToTextInfo(&uMapping, &utInfo); + require_noerr(result, CreateUnicodeToTextInfo); + + result = ConvertFromUnicodeToText(utInfo, unicodeByteLength, name, kUnicodeLooseMappingsMask, + 0, NULL, 0, NULL, /* offsetCounts & offsetArrays */ + isVolumeName ? kHFSMaxVolumeNameChars : kHFSMaxFileNameChars, + &unicodeBytesConverted, &actualPascalBytes, &hfsName[1]); + require_noerr(result, ConvertFromUnicodeToText); + + StrLength(hfsName) = (unsigned char)actualPascalBytes; /* fill in length byte */ + +ConvertFromUnicodeToText: + + /* verify the result in debug builds -- there's really not anything you can do if it fails */ + verify_noerr(DisposeUnicodeToTextInfo(&utInfo)); + } + +CreateUnicodeToTextInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +HFSNameGetUnicodeName( + ConstStr31Param hfsName, + TextEncoding textEncodingHint, + HFSUniStr255 *unicodeName) +{ + ByteCount unicodeByteLength; + OSStatus result; + UnicodeMapping uMapping; + TextToUnicodeInfo tuInfo; + ByteCount pascalCharsRead; + + /* check parameters */ + require_action(NULL != unicodeName, BadParameter, result = paramErr); + + /* make sure output is valid in case we get errors or there's nothing to convert */ + unicodeName->length = 0; + + if ( 0 == StrLength(hfsName) ) + { + result = noErr; + } + else + { + /* if textEncodingHint is kTextEncodingUnknown, get a "default" textEncodingHint */ + if ( kTextEncodingUnknown == textEncodingHint ) + { + ScriptCode script; + RegionCode region; + + script = GetScriptManagerVariable(smSysScript); + region = GetScriptManagerVariable(smRegionCode); + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, + NULL, &textEncodingHint); + if ( paramErr == result ) + { + /* ok, ignore the region and try again */ + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, + kTextRegionDontCare, NULL, &textEncodingHint); + } + if ( noErr != result ) + { + /* ok... try something */ + textEncodingHint = kTextEncodingMacRoman; + } + } + + uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, + kUnicodeCanonicalDecompVariant, kUnicode16BitFormat); + uMapping.otherEncoding = GetTextEncodingBase(textEncodingHint); + uMapping.mappingVersion = kUnicodeUseHFSPlusMapping; + + result = CreateTextToUnicodeInfo(&uMapping, &tuInfo); + require_noerr(result, CreateTextToUnicodeInfo); + + result = ConvertFromTextToUnicode(tuInfo, hfsName[0], &hfsName[1], + 0, /* no control flag bits */ + 0, NULL, 0, NULL, /* offsetCounts & offsetArrays */ + sizeof(unicodeName->unicode), /* output buffer size in bytes */ + &pascalCharsRead, &unicodeByteLength, unicodeName->unicode); + require_noerr(result, ConvertFromTextToUnicode); + + /* convert from byte count to char count */ + unicodeName->length = unicodeByteLength / sizeof(UniChar); + +ConvertFromTextToUnicode: + + /* verify the result in debug builds -- there's really not anything you can do if it fails */ + verify_noerr(DisposeTextToUnicodeInfo(&tuInfo)); + } + +CreateTextToUnicodeInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- File/Directory Manipulation Routines ----- + +/*****************************************************************************/ + +Boolean FSRefValid(const FSRef *ref) +{ + return ( noErr == FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, NULL, NULL) ); +} + +/*****************************************************************************/ + +OSErr +FSGetParentRef( + const FSRef *ref, + FSRef *parentRef) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action(NULL != parentRef, BadParameter, result = paramErr); + + result = FSGetCatalogInfo(ref, kFSCatInfoNodeID, &catalogInfo, NULL, NULL, parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* + * Note: FSRefs always point to real file system objects. So, there cannot + * be a FSRef to the parent of volume root directories. Early versions of + * Mac OS X do not handle this case correctly and incorrectly return a + * FSRef for the parent of volume root directories instead of returning an + * invalid FSRef (a cleared FSRef is invalid). The next three lines of code + * ensure that you won't run into this bug. WW9D! + */ + if ( fsRtDirID == catalogInfo.nodeID ) + { + /* clear parentRef and return noErr which is the proper behavior */ + memset(parentRef, 0, sizeof(FSRef)); + } + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetFileDirName( + const FSRef *ref, + HFSUniStr255 *outName) +{ + OSErr result; + + /* check parameters */ + require_action(NULL != outName, BadParameter, result = paramErr); + + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, outName, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetNodeID( + const FSRef *ref, + long *nodeID, /* can be NULL */ + Boolean *isDirectory) /* can be NULL */ +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information to get */ + whichInfo = kFSCatInfoNone; /* start with none */ + if ( NULL != nodeID ) + { + whichInfo |= kFSCatInfoNodeID; + } + if ( NULL != isDirectory ) + { + whichInfo |= kFSCatInfoNodeFlags; + } + + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + if ( NULL != nodeID ) + { + *nodeID = catalogInfo.nodeID; + } + if ( NULL != isDirectory ) + { + *isDirectory = (0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags)); + } + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetUserPrivilegesPermissions( + const FSRef *ref, + UInt8 *userPrivileges, /* can be NULL */ + UInt32 permissions[4]) /* can be NULL */ +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information to get */ + whichInfo = kFSCatInfoNone; /* start with none */ + if ( NULL != userPrivileges ) + { + whichInfo |= kFSCatInfoUserPrivs; + } + if ( NULL != permissions ) + { + whichInfo |= kFSCatInfoPermissions; + } + + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + if ( NULL != userPrivileges ) + { + *userPrivileges = catalogInfo.userPrivileges; + } + if ( NULL != permissions ) + { + BlockMoveData(&catalogInfo.permissions, permissions, sizeof(UInt32) * 4); + } + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSCheckLock( + const FSRef *ref) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSVolumeInfo volumeInfo; + + /* get nodeFlags and vRefNum for container */ + result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoVolume, &catalogInfo, NULL, NULL,NULL); + require_noerr(result, FSGetCatalogInfo); + + /* is file locked? */ + if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) ) + { + result = fLckdErr; /* file is locked */ + } + else + { + /* file isn't locked, but is volume locked? */ + + /* get volume flags */ + result = FSGetVolumeInfo(catalogInfo.volume, 0, NULL, kFSVolInfoFlags, &volumeInfo, NULL, NULL); + require_noerr(result, FSGetVolumeInfo); + + if ( 0 != (volumeInfo.flags & kFSVolFlagHardwareLockedMask) ) + { + result = wPrErr; /* volume locked by hardware */ + } + else if ( 0 != (volumeInfo.flags & kFSVolFlagSoftwareLockedMask) ) + { + result = vLckdErr; /* volume locked by software */ + } + } + +FSGetVolumeInfo: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetForkSizes( + const FSRef *ref, + UInt64 *dataLogicalSize, /* can be NULL */ + UInt64 *rsrcLogicalSize) /* can be NULL */ +{ + OSErr result; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo catalogInfo; + + whichInfo = kFSCatInfoNodeFlags; + if ( NULL != dataLogicalSize ) + { + /* get data fork size */ + whichInfo |= kFSCatInfoDataSizes; + } + if ( NULL != rsrcLogicalSize ) + { + /* get resource fork size */ + whichInfo |= kFSCatInfoRsrcSizes; + } + + /* get nodeFlags and catalog info */ + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL,NULL); + require_noerr(result, FSGetCatalogInfo); + + /* make sure FSRef was to a file */ + require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), FSRefNotFile, result = notAFileErr); + + if ( NULL != dataLogicalSize ) + { + /* return data fork size */ + *dataLogicalSize = catalogInfo.dataLogicalSize; + } + if ( NULL != rsrcLogicalSize ) + { + /* return resource fork size */ + *rsrcLogicalSize = catalogInfo.rsrcLogicalSize; + } + +FSRefNotFile: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetTotalForkSizes( + const FSRef *ref, + UInt64 *totalLogicalSize, /* can be NULL */ + UInt64 *totalPhysicalSize, /* can be NULL */ + ItemCount *forkCount) /* can be NULL */ +{ + OSErr result; + CatPositionRec forkIterator; + SInt64 forkSize; + SInt64 *forkSizePtr; + UInt64 forkPhysicalSize; + UInt64 *forkPhysicalSizePtr; + + /* Determine if forkSize needed */ + if ( NULL != totalLogicalSize) + { + *totalLogicalSize = 0; + forkSizePtr = &forkSize; + } + else + { + forkSizePtr = NULL; + } + + /* Determine if forkPhysicalSize is needed */ + if ( NULL != totalPhysicalSize ) + { + *totalPhysicalSize = 0; + forkPhysicalSizePtr = &forkPhysicalSize; + } + else + { + forkPhysicalSizePtr = NULL; + } + + /* zero fork count if returning it */ + if ( NULL != forkCount ) + { + *forkCount = 0; + } + + /* Iterate through the forks to get the sizes */ + forkIterator.initialize = 0; + do + { + result = FSIterateForks(ref, &forkIterator, NULL, forkSizePtr, forkPhysicalSizePtr); + if ( noErr == result ) + { + if ( NULL != totalLogicalSize ) + { + *totalLogicalSize += forkSize; + } + + if ( NULL != totalPhysicalSize ) + { + *totalPhysicalSize += forkPhysicalSize; + } + + if ( NULL != forkCount ) + { + ++*forkCount; + } + } + } while ( noErr == result ); + + /* any error result other than errFSNoMoreItems is serious */ + require(errFSNoMoreItems == result, FSIterateForks); + + /* Normal exit */ + result = noErr; + +FSIterateForks: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSBumpDate( + const FSRef *ref) +{ + OSStatus result; + FSCatalogInfo catalogInfo; + UTCDateTime oldDateTime; +#if !BuildingMoreFilesXForMacOS9 + FSRef parentRef; + Boolean notifyParent; +#endif + +#if !BuildingMoreFilesXForMacOS9 + /* Get the node flags, the content modification date and time, and the parent ref */ + result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoContentMod, &catalogInfo, NULL, NULL, &parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* Notify the parent if this is a file */ + notifyParent = (0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)); +#else + /* Get the content modification date and time */ + result = FSGetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); +#endif + + oldDateTime = catalogInfo.contentModDate; + + /* Get the current date and time */ + result = GetUTCDateTime(&catalogInfo.contentModDate, kUTCDefaultOptions); + require_noerr(result, GetUTCDateTime); + + /* if the old date and time is the the same as the current, bump the seconds by one */ + if ( (catalogInfo.contentModDate.fraction == oldDateTime.fraction) && + (catalogInfo.contentModDate.lowSeconds == oldDateTime.lowSeconds) && + (catalogInfo.contentModDate.highSeconds == oldDateTime.highSeconds) ) + { + ++catalogInfo.contentModDate.lowSeconds; + if ( 0 == catalogInfo.contentModDate.lowSeconds ) + { + ++catalogInfo.contentModDate.highSeconds; + } + } + + /* Bump the content modification date and time */ + result = FSSetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + +#if !BuildingMoreFilesXForMacOS9 + /* + * The problem with FNNotify is that it is not available under Mac OS 9 + * and there's no way to test for that except for looking for the symbol + * or something. So, I'll just conditionalize this for those who care + * to send a notification. + */ + + /* Send a notification for the parent of the file, or for the directory */ + result = FNNotify(notifyParent ? &parentRef : ref, kFNDirectoryModifiedMessage, kNilOptions); + require_noerr(result, FNNotify); +#endif + + /* ignore errors from FSSetCatalogInfo (volume might be write protected) and FNNotify */ +FNNotify: +FSSetCatalogInfo: + + return ( noErr ); + + /**********************/ + +GetUTCDateTime: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetFinderInfo( + const FSRef *ref, + FinderInfo *info, /* can be NULL */ + ExtendedFinderInfo *extendedInfo, /* can be NULL */ + Boolean *isDirectory) /* can be NULL */ +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information is really needed */ + whichInfo = kFSCatInfoNone; + + if ( NULL != info ) + { + /* get FinderInfo */ + whichInfo |= kFSCatInfoFinderInfo; + } + + if ( NULL != extendedInfo ) + { + /* get ExtendedFinderInfo */ + whichInfo |= kFSCatInfoFinderXInfo; + } + + if ( NULL != isDirectory ) + { + whichInfo |= kFSCatInfoNodeFlags; + } + + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* return FinderInfo if requested */ + if ( NULL != info ) + { + BlockMoveData(catalogInfo.finderInfo, info, sizeof(FinderInfo)); + } + + /* return ExtendedFinderInfo if requested */ + if ( NULL != extendedInfo) + { + BlockMoveData(catalogInfo.extFinderInfo, extendedInfo, sizeof(ExtendedFinderInfo)); + } + + /* set isDirectory Boolean if requested */ + if ( NULL != isDirectory) + { + *isDirectory = (0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags)); + } + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSSetFinderInfo( + const FSRef *ref, + const FinderInfo *info, + const ExtendedFinderInfo *extendedInfo) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information will be set */ + whichInfo = kFSCatInfoNone; /* start with none */ + if ( NULL != info ) + { + /* set FinderInfo */ + whichInfo |= kFSCatInfoFinderInfo; + BlockMoveData(info, catalogInfo.finderInfo, sizeof(FinderInfo)); + } + if ( NULL != extendedInfo ) + { + /* set ExtendedFinderInfo */ + whichInfo |= kFSCatInfoFinderXInfo; + BlockMoveData(extendedInfo, catalogInfo.extFinderInfo, sizeof(ExtendedFinderInfo)); + } + + result = FSSetCatalogInfo(ref, whichInfo, &catalogInfo); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSChangeCreatorType( + const FSRef *ref, + OSType fileCreator, + OSType fileType) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSRef parentRef; + + /* get nodeFlags, finder info, and parent FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoFinderInfo, &catalogInfo , NULL, NULL, &parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* make sure FSRef was to a file */ + require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), FSRefNotFile, result = notAFileErr); + + /* If fileType not 0x00000000, change fileType */ + if ( fileType != (OSType)0x00000000 ) + { + ((FileInfo *)&catalogInfo.finderInfo)->fileType = fileType; + } + + /* If creator not 0x00000000, change creator */ + if ( fileCreator != (OSType)0x00000000 ) + { + ((FileInfo *)&catalogInfo.finderInfo)->fileCreator = fileCreator; + } + + /* now, save the new information back to disk */ + result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + + /* and attempt to bump the parent directory's mod date to wake up */ + /* the Finder to the change we just made (ignore errors from this) */ + verify_noerr(FSBumpDate(&parentRef)); + +FSSetCatalogInfo: +FSRefNotFile: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSChangeFinderFlags( + const FSRef *ref, + Boolean setBits, + UInt16 flagBits) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSRef parentRef; + + /* get the current finderInfo */ + result = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, &parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* set or clear the appropriate bits in the finderInfo.finderFlags */ + if ( setBits ) + { + /* OR in the bits */ + ((FileInfo *)&catalogInfo.finderInfo)->finderFlags |= flagBits; + } + else + { + /* AND out the bits */ + ((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~flagBits; + } + + /* save the modified finderInfo */ + result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + + /* and attempt to bump the parent directory's mod date to wake up the Finder */ + /* to the change we just made (ignore errors from this) */ + verify_noerr(FSBumpDate(&parentRef)); + +FSSetCatalogInfo: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSSetInvisible( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kIsInvisible) ); +} + +OSErr +FSClearInvisible( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kIsInvisible) ); +} + +/*****************************************************************************/ + +OSErr +FSSetNameLocked( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kNameLocked) ); +} + +OSErr +FSClearNameLocked( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kNameLocked) ); +} + +/*****************************************************************************/ + +OSErr +FSSetIsStationery( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kIsStationery) ); +} + +OSErr +FSClearIsStationery( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kIsStationery) ); +} + +/*****************************************************************************/ + +OSErr +FSSetHasCustomIcon( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kHasCustomIcon) ); +} + +OSErr +FSClearHasCustomIcon( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kHasCustomIcon) ); +} + +/*****************************************************************************/ + +OSErr +FSClearHasBeenInited( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kHasBeenInited) ); +} + +/*****************************************************************************/ + +OSErr +FSCopyFileMgrAttributes( + const FSRef *sourceRef, + const FSRef *destinationRef, + Boolean copyLockBit) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* get the source information */ + result = FSGetCatalogInfo(sourceRef, kFSCatInfoSettableInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* don't copy the hasBeenInited bit; clear it */ + ((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~kHasBeenInited; + + /* should the locked bit be copied? */ + if ( !copyLockBit ) + { + /* no, make sure the locked bit is clear */ + catalogInfo.nodeFlags &= ~kFSNodeLockedMask; + } + + /* set the destination information */ + result = FSSetCatalogInfo(destinationRef, kFSCatInfoSettableInfo, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + +FSSetCatalogInfo: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMoveRenameObjectUnicode( + const FSRef *ref, + const FSRef *destDirectory, + UniCharCount nameLength, + const UniChar *name, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef) /* if function fails along the way, newRef is final location of file */ +{ + OSErr result; + FSVolumeRefNum vRefNum; + FSCatalogInfo catalogInfo; + FSRef originalDirectory; + TextEncoding originalTextEncodingHint; + HFSUniStr255 originalName; + long tempItemsDirID; + Str31 uniqueTempDirName; + long uniqueTempDirID; + FSRef uniqueTempDirRef; + + /* check parameters */ + require_action(NULL != newRef, BadParameter, result = paramErr); + + /* newRef = input to start with */ + BlockMoveData(ref, newRef, sizeof(FSRef)); + + /* get destDirectory's vRefNum */ + result = FSGetCatalogInfo(destDirectory, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, DestinationBad); + + /* save vRefNum */ + vRefNum = catalogInfo.volume; + + /* get ref's vRefNum, TextEncoding, name and parent directory*/ + result = FSGetCatalogInfo(ref, kFSCatInfoTextEncoding + kFSCatInfoVolume, &catalogInfo, &originalName, NULL, &originalDirectory); + require_noerr(result, SourceBad); + + /* save TextEncoding */ + originalTextEncodingHint = catalogInfo.textEncodingHint; + + /* make sure ref and destDirectory are on same volume */ + require_action(vRefNum == catalogInfo.volume, NotSameVolume, result = diffVolErr); + + /* Skip a lot of steps if we're not renaming */ + if ( NULL != name ) + { + /* find the Temporary Items Folder on sourcevRefNum */ + result = FindFolder(vRefNum, kTemporaryFolderType, kCreateFolder, &vRefNum, &tempItemsDirID); + require_noerr(result, NoTemporaryFolder); + + /* Create a new uniquely named folder in the temporary items folder. */ + /* This is done to avoid the case where 'realName' or 'copyName' already */ + /* exists in the temporary items folder. */ + + /* Start with 'A' plus the current tick count as uniqueTempDirName */ + NumToString(TickCount(), &uniqueTempDirName[1]); + uniqueTempDirName[0] = uniqueTempDirName[1] + 1; + uniqueTempDirName[1] = 'A'; + do + { + result = DirCreate(vRefNum, tempItemsDirID, uniqueTempDirName, &uniqueTempDirID); + if ( dupFNErr == result ) + { + /* Duplicate name - change the first character to the next ASCII character */ + ++uniqueTempDirName[1]; + } + } while ( (dupFNErr == result) && (uniqueTempDirName[1] < 'Z') ); /* 26 new weirdly named directories per 1/60th second - not likely! */ + require_noerr(result, CouldNotCreateUniqueTempDir); + + /* get FSRef to UniqueTempDir */ + result = FSMakeFSRef(vRefNum, uniqueTempDirID, NULL, &uniqueTempDirRef); + require_noerr(result, FSMakeFSRef); + + /* Move the object to the folder with uniqueTempDirRef for renaming */ + result = FSMoveObject(ref, &uniqueTempDirRef, newRef); + require_noerr(result, FSMoveObjectBeforeRenameFailed); + + /* Rename the object */ + result = FSRenameUnicode(newRef, nameLength, name, textEncodingHint, newRef); + require_noerr(result, FSRenameUnicode); + + /* Move object to its new home */ + result = FSMoveObject(newRef, destDirectory, newRef); + require_noerr(result, FSMoveObjectAfterRenameFailed); + + /* Done with ourTempDir, so delete it - ignore errors */ + verify_noerr(HDelete(vRefNum, uniqueTempDirID, NULL)); + } + else + { + /* Move object to its new home */ + result = FSMoveObject(newRef, destDirectory, newRef); + require_noerr(result, FSMoveObjectNoRenameFailed); + } + + return ( result ); + + /*************/ + +/* + * failure handling code when renaming + */ +FSMoveObjectAfterRenameFailed: + + /* Error handling: rename object back to original name - ignore errors */ + verify_noerr(FSRenameUnicode(newRef, originalName.length, originalName.unicode, originalTextEncodingHint, newRef)); + +FSRenameUnicode: + + /* Error handling: move object back to original location - ignore errors */ + verify_noerr(FSMoveObject(newRef, &originalDirectory, newRef)); + +FSMoveObjectBeforeRenameFailed: +FSMakeFSRef: + + /* Done with ourTempDir, so delete it - ignore errors */ + verify_noerr(HDelete(vRefNum, uniqueTempDirID, NULL)); + +CouldNotCreateUniqueTempDir: +NoTemporaryFolder: + +/* + * failure handling code for renaming or not + */ +FSMoveObjectNoRenameFailed: +NotSameVolume: +SourceBad: +DestinationBad: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +/* + The FSDeleteContainerLevel function deletes the contents of a container + directory. All files and subdirectories in the specified container are + deleted. If a locked file or directory is encountered, it is unlocked + and then deleted. If any unexpected errors are encountered, + FSDeleteContainerLevel quits and returns to the caller. + + container --> FSRef to a directory. + theGlobals --> A pointer to a FSDeleteContainerGlobals struct + which contains the variables that do not need to + be allocated each time FSDeleteContainerLevel + recurses. That lets FSDeleteContainerLevel use + less stack space per recursion level. +*/ + +static +void +FSDeleteContainerLevel( + const FSRef *container, + FSDeleteContainerGlobals *theGlobals) +{ + /* level locals */ + FSIterator iterator; + FSRef itemToDelete; + UInt16 nodeFlags; + + /* Open FSIterator for flat access and give delete optimization hint */ + theGlobals->result = FSOpenIterator(container, kFSIterateFlat + kFSIterateDelete, &iterator); + require_noerr(theGlobals->result, FSOpenIterator); + + /* delete the contents of the directory */ + do + { + /* get 1 item to delete */ + theGlobals->result = FSGetCatalogInfoBulk(iterator, 1, &theGlobals->actualObjects, + NULL, kFSCatInfoNodeFlags, &theGlobals->catalogInfo, + &itemToDelete, NULL, NULL); + if ( (noErr == theGlobals->result) && (1 == theGlobals->actualObjects) ) + { + /* save node flags in local in case we have to recurse */ + nodeFlags = theGlobals->catalogInfo.nodeFlags; + + /* is it a file or directory? */ + if ( 0 != (nodeFlags & kFSNodeIsDirectoryMask) ) + { + /* it's a directory -- delete its contents before attempting to delete it */ + FSDeleteContainerLevel(&itemToDelete, theGlobals); + } + /* are we still OK to delete? */ + if ( noErr == theGlobals->result ) + { + /* is item locked? */ + if ( 0 != (nodeFlags & kFSNodeLockedMask) ) + { + /* then attempt to unlock it (ignore result since FSDeleteObject will set it correctly) */ + theGlobals->catalogInfo.nodeFlags = nodeFlags & ~kFSNodeLockedMask; + (void) FSSetCatalogInfo(&itemToDelete, kFSCatInfoNodeFlags, &theGlobals->catalogInfo); + } + /* delete the item */ + theGlobals->result = FSDeleteObject(&itemToDelete); + } + } + } while ( noErr == theGlobals->result ); + + /* we found the end of the items normally, so return noErr */ + if ( errFSNoMoreItems == theGlobals->result ) + { + theGlobals->result = noErr; + } + + /* close the FSIterator (closing an open iterator should never fail) */ + verify_noerr(FSCloseIterator(iterator)); + +FSOpenIterator: + + return; +} + +/*****************************************************************************/ + +OSErr +FSDeleteContainerContents( + const FSRef *container) +{ + FSDeleteContainerGlobals theGlobals; + + /* delete container's contents */ + FSDeleteContainerLevel(container, &theGlobals); + + return ( theGlobals.result ); +} + +/*****************************************************************************/ + +OSErr +FSDeleteContainer( + const FSRef *container) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* get nodeFlags for container */ + result = FSGetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo, NULL, NULL,NULL); + require_noerr(result, FSGetCatalogInfo); + + /* make sure container is a directory */ + require_action(0 != (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), ContainerNotDirectory, result = dirNFErr); + + /* delete container's contents */ + result = FSDeleteContainerContents(container); + require_noerr(result, FSDeleteContainerContents); + + /* is container locked? */ + if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) ) + { + /* then attempt to unlock container (ignore result since FSDeleteObject will set it correctly) */ + catalogInfo.nodeFlags &= ~kFSNodeLockedMask; + (void) FSSetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo); + } + + /* delete the container */ + result = FSDeleteObject(container); + +FSDeleteContainerContents: +ContainerNotDirectory: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +/* + The FSIterateContainerLevel function iterates the contents of a container + directory and calls a IterateContainerFilterProc function once for each + file and directory found. + + theGlobals --> A pointer to a FSIterateContainerGlobals struct + which contains the variables needed globally by + all recusion levels of FSIterateContainerLevel. + That makes FSIterateContainer thread safe since + each call to it uses its own global world. + It also contains the variables that do not need + to be allocated each time FSIterateContainerLevel + recurses. That lets FSIterateContainerLevel use + less stack space per recursion level. +*/ + +static +void +FSIterateContainerLevel( + FSIterateContainerGlobals *theGlobals) +{ + FSIterator iterator; + + /* If maxLevels is zero, we aren't checking levels */ + /* If currentLevel < maxLevels, look at this level */ + if ( (theGlobals->maxLevels == 0) || + (theGlobals->currentLevel < theGlobals->maxLevels) ) + { + /* Open FSIterator for flat access to theGlobals->ref */ + theGlobals->result = FSOpenIterator(&theGlobals->ref, kFSIterateFlat, &iterator); + require_noerr(theGlobals->result, FSOpenIterator); + + ++theGlobals->currentLevel; /* Go to next level */ + + /* Call FSGetCatalogInfoBulk in loop to get all items in the container */ + do + { + theGlobals->result = FSGetCatalogInfoBulk(iterator, 1, &theGlobals->actualObjects, + &theGlobals->containerChanged, theGlobals->whichInfo, &theGlobals->catalogInfo, + &theGlobals->ref, theGlobals->specPtr, theGlobals->namePtr); + if ( (noErr == theGlobals->result || errFSNoMoreItems == theGlobals->result) && + (0 != theGlobals->actualObjects) ) + { + /* Call the IterateFilterProc */ + theGlobals->quitFlag = CallIterateContainerFilterProc(theGlobals->iterateFilter, + theGlobals->containerChanged, theGlobals->currentLevel, + &theGlobals->catalogInfo, &theGlobals->ref, + theGlobals->specPtr, theGlobals->namePtr, theGlobals->yourDataPtr); + /* Is it a directory? */ + if ( 0 != (theGlobals->catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) ) + { + /* Keep going? */ + if ( !theGlobals->quitFlag ) + { + /* Dive again if the IterateFilterProc didn't say "quit" */ + FSIterateContainerLevel(theGlobals); + } + } + } + /* time to fall back a level? */ + } while ( (noErr == theGlobals->result) && (!theGlobals->quitFlag) ); + + /* errFSNoMoreItems is OK - it only means we hit the end of this level */ + /* afpAccessDenied is OK, too - it only means we cannot see inside a directory */ + if ( (errFSNoMoreItems == theGlobals->result) || + (afpAccessDenied == theGlobals->result) ) + { + theGlobals->result = noErr; + } + + --theGlobals->currentLevel; /* Return to previous level as we leave */ + + /* Close the FSIterator (closing an open iterator should never fail) */ + verify_noerr(FSCloseIterator(iterator)); + } + +FSOpenIterator: + + return; +} + +/*****************************************************************************/ + +OSErr +FSIterateContainer( + const FSRef *container, + ItemCount maxLevels, + FSCatalogInfoBitmap whichInfo, + Boolean wantFSSpec, + Boolean wantName, + IterateContainerFilterProcPtr iterateFilter, + void *yourDataPtr) +{ + OSErr result; + FSIterateContainerGlobals theGlobals; + + /* make sure there is an iterateFilter */ + require_action(iterateFilter != NULL, NoIterateFilter, result = paramErr); + + /* + * set up the globals we need to access from the recursive routine + */ + theGlobals.iterateFilter = iterateFilter; + /* we need the node flags no matter what was requested so we can detect files vs. directories */ + theGlobals.whichInfo = whichInfo | kFSCatInfoNodeFlags; + /* start with input container -- the first OpenIterator will ensure it is a directory */ + theGlobals.ref = *container; + if ( wantFSSpec ) + { + theGlobals.specPtr = &theGlobals.spec; + } + else + { + theGlobals.specPtr = NULL; + } + if ( wantName ) + { + theGlobals.namePtr = &theGlobals.name; + } + else + { + theGlobals.namePtr = NULL; + } + theGlobals.yourDataPtr = yourDataPtr; + theGlobals.maxLevels = maxLevels; + theGlobals.currentLevel = 0; + theGlobals.quitFlag = false; + theGlobals.containerChanged = false; + theGlobals.result = noErr; + theGlobals.actualObjects = 0; + + /* here we go into recursion land... */ + FSIterateContainerLevel(&theGlobals); + result = theGlobals.result; + require_noerr(result, FSIterateContainerLevel); + +FSIterateContainerLevel: +NoIterateFilter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetDirectoryItems( + const FSRef *container, + FSRef ***refsHandle, /* pointer to handle of FSRefs */ + ItemCount *numRefs, + Boolean *containerChanged) +{ + /* Grab items 10 at a time. */ + enum { kMaxItemsPerBulkCall = 10 }; + + OSErr result; + OSErr memResult; + FSIterator iterator; + FSRef refs[kMaxItemsPerBulkCall]; + ItemCount actualObjects; + Boolean changed; + + /* check parameters */ + require_action((NULL != refsHandle) && (NULL != numRefs) && (NULL != containerChanged), + BadParameter, result = paramErr); + + *numRefs = 0; + *containerChanged = false; + *refsHandle = (FSRef **)NewHandle(0); + require_action(NULL != *refsHandle, NewHandle, result = memFullErr); + + /* open an FSIterator */ + result = FSOpenIterator(container, kFSIterateFlat, &iterator); + require_noerr(result, FSOpenIterator); + + /* Call FSGetCatalogInfoBulk in loop to get all items in the container */ + do + { + result = FSGetCatalogInfoBulk(iterator, kMaxItemsPerBulkCall, &actualObjects, + &changed, kFSCatInfoNone, NULL, refs, NULL, NULL); + + /* if the container changed, set containerChanged for output, but keep going */ + if ( changed ) + { + *containerChanged = changed; + } + + /* any result other than noErr and errFSNoMoreItems is serious */ + require((noErr == result) || (errFSNoMoreItems == result), FSGetCatalogInfoBulk); + + /* add objects to output array and count */ + if ( 0 != actualObjects ) + { + /* concatenate the FSRefs to the end of the handle */ + PtrAndHand(refs, (Handle)*refsHandle, actualObjects * sizeof(FSRef)); + memResult = MemError(); + require_noerr_action(memResult, MemoryAllocationFailed, result = memResult); + + *numRefs += actualObjects; + } + } while ( noErr == result ); + + verify_noerr(FSCloseIterator(iterator)); /* closing an open iterator should never fail, but... */ + + return ( noErr ); + + /**********************/ + +MemoryAllocationFailed: +FSGetCatalogInfoBulk: + + /* close the iterator */ + verify_noerr(FSCloseIterator(iterator)); + +FSOpenIterator: + /* dispose of handle if already allocated and clear the outputs */ + if ( NULL != *refsHandle ) + { + DisposeHandle((Handle)*refsHandle); + *refsHandle = NULL; + } + *numRefs = 0; + +NewHandle: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +/* + The GenerateUniqueName function generates a HFSUniStr255 name that is + unique in both dir1 and dir2. + + startSeed --> A pointer to a long which is used to generate the + unique name. + <-- It is modified on output to a value which should + be used to generate the next unique name. + dir1 --> The first directory. + dir2 --> The second directory. + uniqueName <-- A pointer to a HFSUniStr255 where the unique name + is to be returned. +*/ + +static +OSErr +GenerateUniqueHFSUniStr( + long *startSeed, + const FSRef *dir1, + const FSRef *dir2, + HFSUniStr255 *uniqueName) +{ + OSErr result; + long i; + FSRefParam pb; + FSRef newRef; + unsigned char hexStr[16] = "0123456789ABCDEF"; + + /* set up the parameter block */ + pb.name = uniqueName->unicode; + pb.nameLength = 8; /* always 8 characters */ + pb.textEncodingHint = kTextEncodingUnknown; + pb.newRef = &newRef; + + /* loop until we get fnfErr with a filename in both directories */ + result = noErr; + while ( fnfErr != result ) + { + /* convert startSeed to 8 character Unicode string */ + uniqueName->length = 8; + for ( i = 0; i < 8; ++i ) + { + uniqueName->unicode[i] = hexStr[((*startSeed >> ((7-i)*4)) & 0xf)]; + } + + /* try in dir1 */ + pb.ref = dir1; + result = PBMakeFSRefUnicodeSync(&pb); + if ( fnfErr == result ) + { + /* try in dir2 */ + pb.ref = dir2; + result = PBMakeFSRefUnicodeSync(&pb); + if ( fnfErr != result ) + { + /* exit if anything other than noErr or fnfErr */ + require_noerr(result, Dir2PBMakeFSRefUnicodeSyncFailed); + } + } + else + { + /* exit if anything other than noErr or fnfErr */ + require_noerr(result, Dir1PBMakeFSRefUnicodeSyncFailed); + } + + /* increment seed for next pass through loop, */ + /* or for next call to GenerateUniqueHFSUniStr */ + ++(*startSeed); + } + + /* we have a unique file name which doesn't exist in dir1 or dir2 */ + result = noErr; + +Dir2PBMakeFSRefUnicodeSyncFailed: +Dir1PBMakeFSRefUnicodeSyncFailed: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSExchangeObjectsCompat( + const FSRef *sourceRef, + const FSRef *destRef, + FSRef *newSourceRef, + FSRef *newDestRef) +{ + enum + { + /* get all settable info except for mod dates, plus the volume refNum and parent directory ID */ + kGetCatInformationMask = (kFSCatInfoSettableInfo | + kFSCatInfoVolume | + kFSCatInfoParentDirID) & + ~(kFSCatInfoContentMod | kFSCatInfoAttrMod), + /* set everything possible except for mod dates */ + kSetCatinformationMask = kFSCatInfoSettableInfo & + ~(kFSCatInfoContentMod | kFSCatInfoAttrMod) + }; + + OSErr result; + GetVolParmsInfoBuffer volParmsInfo; + UInt32 infoSize; + FSCatalogInfo sourceCatalogInfo; /* source file's catalog information */ + FSCatalogInfo destCatalogInfo; /* destination file's catalog information */ + HFSUniStr255 sourceName; /* source file's Unicode name */ + HFSUniStr255 destName; /* destination file's Unicode name */ + FSRef sourceCurrentRef; /* FSRef to current location of source file throughout this function */ + FSRef destCurrentRef; /* FSRef to current location of destination file throughout this function */ + FSRef sourceParentRef; /* FSRef to parent directory of source file */ + FSRef destParentRef; /* FSRef to parent directory of destination file */ + HFSUniStr255 sourceUniqueName; /* unique name given to source file while exchanging it with destination */ + HFSUniStr255 destUniqueName; /* unique name given to destination file while exchanging it with source */ + long theSeed; /* the seed for generating unique names */ + Boolean sameParentDirs; /* true if source and destinatin parent directory is the same */ + + /* check parameters */ + require_action((NULL != newSourceRef) && (NULL != newDestRef), BadParameter, result = paramErr); + + /* output refs and current refs = input refs to start with */ + BlockMoveData(sourceRef, newSourceRef, sizeof(FSRef)); + BlockMoveData(sourceRef, &sourceCurrentRef, sizeof(FSRef)); + + BlockMoveData(destRef, newDestRef, sizeof(FSRef)); + BlockMoveData(destRef, &destCurrentRef, sizeof(FSRef)); + + /* get source volume's vRefNum */ + result = FSGetCatalogInfo(&sourceCurrentRef, kFSCatInfoVolume, &sourceCatalogInfo, NULL, NULL, NULL); + require_noerr(result, DetermineSourceVRefNumFailed); + + /* see if that volume supports FSExchangeObjects */ + result = FSGetVolParms(sourceCatalogInfo.volume, sizeof(GetVolParmsInfoBuffer), + &volParmsInfo, &infoSize); + if ( (noErr == result) && VolSupportsFSExchangeObjects(&volParmsInfo) ) + { + /* yes - use FSExchangeObjects */ + result = FSExchangeObjects(sourceRef, destRef); + } + else + { + /* no - emulate FSExchangeObjects */ + + /* Note: The compatibility case won't work for files with *Btree control blocks. */ + /* Right now the only *Btree files are created by the system. */ + + /* get all catalog information and Unicode names for each file */ + result = FSGetCatalogInfo(&sourceCurrentRef, kGetCatInformationMask, &sourceCatalogInfo, &sourceName, NULL, &sourceParentRef); + require_noerr(result, SourceFSGetCatalogInfoFailed); + + result = FSGetCatalogInfo(&destCurrentRef, kGetCatInformationMask, &destCatalogInfo, &destName, NULL, &destParentRef); + require_noerr(result, DestFSGetCatalogInfoFailed); + + /* make sure source and destination are on same volume */ + require_action(sourceCatalogInfo.volume == destCatalogInfo.volume, NotSameVolume, result = diffVolErr); + + /* make sure both files are *really* files */ + require_action((0 == (sourceCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) && + (0 == (destCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)), NotAFile, result = notAFileErr); + + /* generate 2 names that are unique in both directories */ + theSeed = 0x4a696d4c; /* a fine unlikely filename */ + + result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &sourceUniqueName); + require_noerr(result, GenerateUniqueHFSUniStr1Failed); + + result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &destUniqueName); + require_noerr(result, GenerateUniqueHFSUniStr2Failed); + + /* rename sourceCurrentRef to sourceUniqueName */ + result = FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef); + require_noerr(result, FSRenameUnicode1Failed); + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + + /* rename destCurrentRef to destUniqueName */ + result = FSRenameUnicode(&destCurrentRef, destUniqueName.length, destUniqueName.unicode, kTextEncodingUnknown, newDestRef); + require_noerr(result, FSRenameUnicode2Failed); + BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef)); + + /* are the source and destination parent directories the same? */ + sameParentDirs = ( sourceCatalogInfo.parentDirID == destCatalogInfo.parentDirID ); + if ( !sameParentDirs ) + { + /* move source file to dest parent directory */ + result = FSMoveObject(&sourceCurrentRef, &destParentRef, newSourceRef); + require_noerr(result, FSMoveObject1Failed); + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + + /* move dest file to source parent directory */ + result = FSMoveObject(&destCurrentRef, &sourceParentRef, newDestRef); + require_noerr(result, FSMoveObject2Failed); + BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef)); + } + + /* At this point, the files are in their new locations (if they were moved). */ + /* The source file is named sourceUniqueName and is in the directory referred to */ + /* by destParentRef. The destination file is named destUniqueName and is in the */ + /* directory referred to by sourceParentRef. */ + + /* give source file the dest file's catalog information except for mod dates */ + result = FSSetCatalogInfo(&sourceCurrentRef, kSetCatinformationMask, &destCatalogInfo); + require_noerr(result, FSSetCatalogInfo1Failed); + + /* give dest file the source file's catalog information except for mod dates */ + result = FSSetCatalogInfo(&destCurrentRef, kSetCatinformationMask, &sourceCatalogInfo); + require_noerr(result, FSSetCatalogInfo2Failed); + + /* rename source file with dest file's name */ + result = FSRenameUnicode(&sourceCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newSourceRef); + require_noerr(result, FSRenameUnicode3Failed); + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + + /* rename dest file with source file's name */ + result = FSRenameUnicode(&destCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newDestRef); + require_noerr(result, FSRenameUnicode4Failed); + + /* we're done with no errors, so swap newSourceRef and newDestRef */ + BlockMoveData(newDestRef, newSourceRef, sizeof(FSRef)); + BlockMoveData(&sourceCurrentRef, newDestRef, sizeof(FSRef)); + } + + return ( result ); + + /**********************/ + +/* If there are any failures while emulating FSExchangeObjects, attempt to reverse any steps */ +/* already taken. In any case, newSourceRef and newDestRef will refer to the files in whatever */ +/* state and location they ended up in so that both files can be found by the calling code. */ + +FSRenameUnicode4Failed: + + /* attempt to rename source file to sourceUniqueName */ + if ( noErr == FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef) ) + { + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + } + +FSRenameUnicode3Failed: + + /* attempt to restore dest file's catalog information */ + verify_noerr(FSSetCatalogInfo(&destCurrentRef, kFSCatInfoSettableInfo, &destCatalogInfo)); + +FSSetCatalogInfo2Failed: + + /* attempt to restore source file's catalog information */ + verify_noerr(FSSetCatalogInfo(&sourceCurrentRef, kFSCatInfoSettableInfo, &sourceCatalogInfo)); + +FSSetCatalogInfo1Failed: + + if ( !sameParentDirs ) + { + /* attempt to move dest file back to dest directory */ + if ( noErr == FSMoveObject(&destCurrentRef, &destParentRef, newDestRef) ) + { + BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef)); + } + } + +FSMoveObject2Failed: + + if ( !sameParentDirs ) + { + /* attempt to move source file back to source directory */ + if ( noErr == FSMoveObject(&sourceCurrentRef, &sourceParentRef, newSourceRef) ) + { + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + } + } + +FSMoveObject1Failed: + + /* attempt to rename dest file to original name */ + verify_noerr(FSRenameUnicode(&destCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newDestRef)); + +FSRenameUnicode2Failed: + + /* attempt to rename source file to original name */ + verify_noerr(FSRenameUnicode(&sourceCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newSourceRef)); + +FSRenameUnicode1Failed: +GenerateUniqueHFSUniStr2Failed: +GenerateUniqueHFSUniStr1Failed: +NotAFile: +NotSameVolume: +DestFSGetCatalogInfoFailed: +SourceFSGetCatalogInfoFailed: +FSGetVolParmsFailed: +DetermineSourceVRefNumFailed: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- Shared Environment Routines ----- + +/*****************************************************************************/ + +OSErr +FSLockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart) +{ + OSErr result; + ParamBlockRec pb; + + pb.ioParam.ioRefNum = refNum; + pb.ioParam.ioReqCount = rangeLength; + pb.ioParam.ioPosMode = fsFromStart; + pb.ioParam.ioPosOffset = rangeStart; + result = PBLockRangeSync(&pb); + require_noerr(result, PBLockRangeSync); + +PBLockRangeSync: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSUnlockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart) +{ + OSErr result; + ParamBlockRec pb; + + pb.ioParam.ioRefNum = refNum; + pb.ioParam.ioReqCount = rangeLength; + pb.ioParam.ioPosMode = fsFromStart; + pb.ioParam.ioPosOffset = rangeStart; + result = PBUnlockRangeSync(&pb); + require_noerr(result, PBUnlockRangeSync); + +PBUnlockRangeSync: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetDirAccess( + const FSRef *ref, + SInt32 *ownerID, /* can be NULL */ + SInt32 *groupID, /* can be NULL */ + SInt32 *accessRights) /* can be NULL */ +{ + OSErr result; + FSSpec spec; + HParamBlockRec pb; + + /* get FSSpec from FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* get directory access info for FSSpec */ + pb.accessParam.ioNamePtr = (StringPtr)spec.name; + pb.accessParam.ioVRefNum = spec.vRefNum; + pb.fileParam.ioDirID = spec.parID; + result = PBHGetDirAccessSync(&pb); + require_noerr(result, PBHGetDirAccessSync); + + /* return the IDs and access rights */ + if ( NULL != ownerID ) + { + *ownerID = pb.accessParam.ioACOwnerID; + } + if ( NULL != groupID ) + { + *groupID = pb.accessParam.ioACGroupID; + } + if ( NULL != accessRights ) + { + *accessRights = pb.accessParam.ioACAccess; + } + +PBHGetDirAccessSync: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSSetDirAccess( + const FSRef *ref, + SInt32 ownerID, + SInt32 groupID, + SInt32 accessRights) +{ + OSErr result; + FSSpec spec; + HParamBlockRec pb; + + enum + { + /* Just the bits that can be set */ + kSetDirAccessSettableMask = (kioACAccessBlankAccessMask + + kioACAccessEveryoneWriteMask + kioACAccessEveryoneReadMask + kioACAccessEveryoneSearchMask + + kioACAccessGroupWriteMask + kioACAccessGroupReadMask + kioACAccessGroupSearchMask + + kioACAccessOwnerWriteMask + kioACAccessOwnerReadMask + kioACAccessOwnerSearchMask) + }; + + /* get FSSpec from FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* set directory access info for FSSpec */ + pb.accessParam.ioNamePtr = (StringPtr)spec.name; + pb.accessParam.ioVRefNum = spec.vRefNum; + pb.fileParam.ioDirID = spec.parID; + pb.accessParam.ioACOwnerID = ownerID; + pb.accessParam.ioACGroupID = groupID; + pb.accessParam.ioACAccess = accessRights & kSetDirAccessSettableMask; + result = PBHSetDirAccessSync(&pb); + require_noerr(result, PBHSetDirAccessSync); + +PBHSetDirAccessSync: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVolMountInfoSize( + FSVolumeRefNum volRefNum, + SInt16 *size) +{ + OSErr result; + ParamBlockRec pb; + + /* check parameters */ + require_action(NULL != size, BadParameter, result = paramErr); + + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioVRefNum = volRefNum; + pb.ioParam.ioBuffer = (Ptr)size; + result = PBGetVolMountInfoSize(&pb); + require_noerr(result, PBGetVolMountInfoSize); + +PBGetVolMountInfoSize: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVolMountInfo( + FSVolumeRefNum volRefNum, + void *volMountInfo) +{ + OSErr result; + ParamBlockRec pb; + + /* check parameters */ + require_action(NULL != volMountInfo, BadParameter, result = paramErr); + + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioVRefNum = volRefNum; + pb.ioParam.ioBuffer = (Ptr)volMountInfo; + result = PBGetVolMountInfo(&pb); + require_noerr(result, PBGetVolMountInfo); + +PBGetVolMountInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSVolumeMount( + const void *volMountInfo, + FSVolumeRefNum *volRefNum) +{ + OSErr result; + ParamBlockRec pb; + + /* check parameters */ + require_action(NULL != volRefNum, BadParameter, result = paramErr); + + pb.ioParam.ioBuffer = (Ptr)volMountInfo; + result = PBVolumeMount(&pb); + require_noerr(result, PBVolumeMount); + + /* return the volume reference number */ + *volRefNum = pb.ioParam.ioVRefNum; + +PBVolumeMount: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMapID( + FSVolumeRefNum volRefNum, + SInt32 ugID, + SInt16 objType, + Str31 name) +{ + OSErr result; + HParamBlockRec pb; + + /* check parameters */ + require_action(NULL != name, BadParameter, result = paramErr); + + pb.objParam.ioNamePtr = NULL; + pb.objParam.ioVRefNum = volRefNum; + pb.objParam.ioObjType = objType; + pb.objParam.ioObjNamePtr = name; + pb.objParam.ioObjID = ugID; + result = PBHMapIDSync(&pb); + require_noerr(result, PBHMapIDSync); + +PBHMapIDSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMapName( + FSVolumeRefNum volRefNum, + ConstStr255Param name, + SInt16 objType, + SInt32 *ugID) +{ + OSErr result; + HParamBlockRec pb; + + /* check parameters */ + require_action(NULL != ugID, BadParameter, result = paramErr); + + pb.objParam.ioNamePtr = NULL; + pb.objParam.ioVRefNum = volRefNum; + pb.objParam.ioObjType = objType; + pb.objParam.ioObjNamePtr = (StringPtr)name; + result = PBHMapNameSync(&pb); + require_noerr(result, PBHMapNameSync); + + /* return the user or group ID */ + *ugID = pb.objParam.ioObjID; + +PBHMapNameSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSCopyFile( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *copyName, /* can be NULL (no rename during copy) */ + TextEncoding textEncodingHint, + FSRef *newRef) /* can be NULL */ +{ + OSErr result; + FSSpec srcFileSpec; + FSCatalogInfo catalogInfo; + HParamBlockRec pb; + Str31 hfsName; + GetVolParmsInfoBuffer volParmsInfo; + UInt32 infoSize; + + /* get source FSSpec from source FSRef */ + result = FSGetCatalogInfo(srcFileRef, kFSCatInfoNone, NULL, NULL, &srcFileSpec, NULL); + require_noerr(result, FSGetCatalogInfo_srcFileRef); + + /* Make sure the volume supports CopyFile */ + result = FSGetVolParms(srcFileSpec.vRefNum, sizeof(GetVolParmsInfoBuffer), + &volParmsInfo, &infoSize); + require_action((noErr == result) && VolHasCopyFile(&volParmsInfo), + NoCopyFileSupport, result = paramErr); + + /* get destination volume reference number and destination directory ID from destination FSRef */ + result = FSGetCatalogInfo(dstDirectoryRef, kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo_dstDirectoryRef); + + /* tell the server to copy the object */ + pb.copyParam.ioVRefNum = srcFileSpec.vRefNum; + pb.copyParam.ioDirID = srcFileSpec.parID; + pb.copyParam.ioNamePtr = (StringPtr)srcFileSpec.name; + pb.copyParam.ioDstVRefNum = catalogInfo.volume; + pb.copyParam.ioNewDirID = (long)catalogInfo.nodeID; + pb.copyParam.ioNewName = NULL; + if ( NULL != copyName ) + { + result = UnicodeNameGetHFSName(nameLength, copyName, textEncodingHint, false, hfsName); + require_noerr(result, UnicodeNameGetHFSName); + + pb.copyParam.ioCopyName = hfsName; + } + else + { + pb.copyParam.ioCopyName = NULL; + } + result = PBHCopyFileSync(&pb); + require_noerr(result, PBHCopyFileSync); + + if ( NULL != newRef ) + { + verify_noerr(FSMakeFSRef(pb.copyParam.ioDstVRefNum, pb.copyParam.ioNewDirID, + pb.copyParam.ioCopyName, newRef)); + } + +PBHCopyFileSync: +UnicodeNameGetHFSName: +FSGetCatalogInfo_dstDirectoryRef: +NoCopyFileSupport: +FSGetCatalogInfo_srcFileRef: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMoveRename( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *moveName, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef) /* can be NULL */ +{ + OSErr result; + FSSpec srcFileSpec; + FSCatalogInfo catalogInfo; + HParamBlockRec pb; + Str31 hfsName; + GetVolParmsInfoBuffer volParmsInfo; + UInt32 infoSize; + + /* get source FSSpec from source FSRef */ + result = FSGetCatalogInfo(srcFileRef, kFSCatInfoNone, NULL, NULL, &srcFileSpec, NULL); + require_noerr(result, FSGetCatalogInfo_srcFileRef); + + /* Make sure the volume supports MoveRename */ + result = FSGetVolParms(srcFileSpec.vRefNum, sizeof(GetVolParmsInfoBuffer), + &volParmsInfo, &infoSize); + require_action((noErr == result) && VolHasMoveRename(&volParmsInfo), + NoMoveRenameSupport, result = paramErr); + + /* get destination volume reference number and destination directory ID from destination FSRef */ + result = FSGetCatalogInfo(dstDirectoryRef, kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo_dstDirectoryRef); + + /* make sure the source and destination are on the same volume */ + require_action(srcFileSpec.vRefNum == catalogInfo.volume, NotSameVolume, result = diffVolErr); + + /* tell the server to move and rename the object */ + pb.copyParam.ioVRefNum = srcFileSpec.vRefNum; + pb.copyParam.ioDirID = srcFileSpec.parID; + pb.copyParam.ioNamePtr = (StringPtr)srcFileSpec.name; + pb.copyParam.ioNewDirID = (long)catalogInfo.nodeID; + pb.copyParam.ioNewName = NULL; + if ( NULL != moveName ) + { + result = UnicodeNameGetHFSName(nameLength, moveName, textEncodingHint, false, hfsName); + require_noerr(result, UnicodeNameGetHFSName); + + pb.copyParam.ioCopyName = hfsName; + } + else + { + pb.copyParam.ioCopyName = NULL; + } + result = PBHMoveRenameSync(&pb); + require_noerr(result, PBHMoveRenameSync); + + if ( NULL != newRef ) + { + verify_noerr(FSMakeFSRef(pb.copyParam.ioVRefNum, pb.copyParam.ioNewDirID, + pb.copyParam.ioCopyName, newRef)); + } + +PBHMoveRenameSync: +UnicodeNameGetHFSName: +NotSameVolume: +FSGetCatalogInfo_dstDirectoryRef: +NoMoveRenameSupport: +FSGetCatalogInfo_srcFileRef: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- File ID Routines ----- + +/*****************************************************************************/ + +OSErr +FSResolveFileIDRef( + FSVolumeRefNum volRefNum, + SInt32 fileID, + FSRef *ref) +{ + OSErr result; + FIDParam pb; + Str255 tempStr; + + /* check parameters */ + require_action(NULL != ref, BadParameter, result = paramErr); + + /* resolve the file ID reference */ + StrLength(tempStr) = 0; + pb.ioNamePtr = tempStr; + pb.ioVRefNum = volRefNum; + pb.ioFileID = fileID; + result = PBResolveFileIDRefSync((HParmBlkPtr)&pb); + require_noerr(result, PBResolveFileIDRefSync); + + /* and then make an FSRef to the file */ + result = FSMakeFSRef(volRefNum, pb.ioSrcDirID, tempStr, ref); + require_noerr(result, FSMakeFSRef); + +FSMakeFSRef: +PBResolveFileIDRefSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSCreateFileIDRef( + const FSRef *ref, + SInt32 *fileID) +{ + OSErr result; + FSSpec spec; + FIDParam pb; + + /* check parameters */ + require_action(NULL != fileID, BadParameter, result = paramErr); + + /* Get an FSSpec from the FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* Create (or get) the file ID reference using the FSSpec */ + pb.ioNamePtr = (StringPtr)spec.name; + pb.ioVRefNum = spec.vRefNum; + pb.ioSrcDirID = spec.parID; + result = PBCreateFileIDRefSync((HParmBlkPtr)&pb); + require((noErr == result) || (fidExists == result) || (afpIDExists == result), + PBCreateFileIDRefSync); + + /* return the file ID reference */ + *fileID = pb.ioFileID; + +PBCreateFileIDRefSync: +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- Utility Routines ----- + +/*****************************************************************************/ + +Ptr +GetTempBuffer( + ByteCount buffReqSize, + ByteCount *buffActSize) +{ + enum + { + kSlopMemory = 0x00008000 /* 32K - Amount of free memory to leave when allocating buffers */ + }; + + Ptr tempPtr; + + /* check parameters */ + require_action(NULL != buffActSize, BadParameter, tempPtr = NULL); + + /* Make request a multiple of 4K bytes */ + buffReqSize = buffReqSize & 0xfffff000; + + if ( buffReqSize < 0x00001000 ) + { + /* Request was smaller than 4K bytes - make it 4K */ + buffReqSize = 0x00001000; + } + + /* Attempt to allocate the memory */ + tempPtr = NewPtr(buffReqSize); + + /* If request failed, go to backup plan */ + if ( (tempPtr == NULL) && (buffReqSize > 0x00001000) ) + { + /* + ** Try to get largest 4K byte block available + ** leaving some slop for the toolbox if possible + */ + long freeMemory = (FreeMem() - kSlopMemory) & 0xfffff000; + + buffReqSize = MaxBlock() & 0xfffff000; + + if ( buffReqSize > freeMemory ) + { + buffReqSize = freeMemory; + } + + if ( buffReqSize == 0 ) + { + buffReqSize = 0x00001000; + } + + tempPtr = NewPtr(buffReqSize); + } + + /* Return bytes allocated */ + if ( tempPtr != NULL ) + { + *buffActSize = buffReqSize; + } + else + { + *buffActSize = 0; + } + +BadParameter: + + return ( tempPtr ); +} + +/*****************************************************************************/ + +OSErr +FileRefNumGetFSRef( + short refNum, + FSRef *ref) +{ + return ( FSGetForkCBInfo(refNum, 0, NULL, NULL, NULL, ref, NULL) ); +} + +/*****************************************************************************/ + +OSErr +FSSetDefault( + const FSRef *newDefault, + FSRef *oldDefault) +{ + OSErr result; + FSVolumeRefNum vRefNum; + long dirID; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action((NULL != newDefault) && (NULL != oldDefault), BadParameter, result = paramErr); + + /* Get nodeFlags, vRefNum and dirID (nodeID) of newDefault */ + result = FSGetCatalogInfo(newDefault, + kFSCatInfoNodeFlags + kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* Make sure newDefault is a directory */ + require_action(0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags), NewDefaultNotDirectory, + result = dirNFErr); + + /* Get the current working directory. */ + result = HGetVol(NULL, &vRefNum, &dirID); + require_noerr(result, HGetVol); + + /* Return the oldDefault FSRef */ + result = FSMakeFSRef(vRefNum, dirID, NULL, oldDefault); + require_noerr(result, FSMakeFSRef); + + /* Set the new current working directory */ + result = HSetVol(NULL, catalogInfo.volume, catalogInfo.nodeID); + require_noerr(result, HSetVol); + +HSetVol: +FSMakeFSRef: +HGetVol: +NewDefaultNotDirectory: +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSRestoreDefault( + const FSRef *oldDefault) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action(NULL != oldDefault, BadParameter, result = paramErr); + + /* Get nodeFlags, vRefNum and dirID (nodeID) of oldDefault */ + result = FSGetCatalogInfo(oldDefault, + kFSCatInfoNodeFlags + kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* Make sure oldDefault is a directory */ + require_action(0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags), OldDefaultNotDirectory, + result = dirNFErr); + + /* Set the current working directory to oldDefault */ + result = HSetVol(NULL, catalogInfo.volume, catalogInfo.nodeID); + require_noerr(result, HSetVol); + +HSetVol: +OldDefaultNotDirectory: +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ diff --git a/corelib/morefile/MoreFilesX.h b/corelib/morefile/MoreFilesX.h new file mode 100644 index 00000000..67d2da03 --- /dev/null +++ b/corelib/morefile/MoreFilesX.h @@ -0,0 +1,1804 @@ +/* + File: MoreFilesX.h + + Contains: A collection of useful high-level File Manager routines + which use the HFS Plus APIs wherever possible. + + Version: MoreFilesX 1.0 + + Copyright: © 1992-2002 by Apple Computer, Inc., all rights reserved. + + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: For bug reports, consult the following page on + the World Wide Web: + http://developer.apple.com/bugreporter/ + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <1> 1/25/02 JL MoreFilesX 1.0 + + Notes: + What do those arrows in the documentation for each routine mean? + + --> The parameter is an input + + <-- The parameter is an output. The pointer to the variable + where the output will be returned (must not be NULL). + + <** The parameter is an optional output. If it is not a + NULL pointer, it points to the variable where the output + will be returned. If it is a NULL pointer, the output will + not be returned and will possibly let the routine and the + File Manager do less work. If you don't need an optional output, + don't ask for it. + **> The parameter is an optional input. If it is not a + NULL pointer, it points to the variable containing the + input data. If it is a NULL pointer, the input is not used + and will possibly let the routine and the File Manager + do less work. +*/ + +#ifndef __MOREFILESX__ +#define __MOREFILESX__ + +#ifndef __MACTYPES__ +#include <MacTypes.h> +#endif + +#ifndef __FINDER__ +#include <Finder.h> +#endif + +#ifndef __FILES__ +#include <Files.h> +#endif + +#ifndef __TEXTCOMMON__ +#include <TextCommon.h> +#endif + +#if PRAGMA_ONCE +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=mac68k +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(push, 2) +#elif PRAGMA_STRUCT_PACK + #pragma pack(2) +#endif + +/*****************************************************************************/ + +#pragma mark ----- FinderInfo and ExtendedFinderInfo ----- + +/* + * FSGetFinderInfo and FSSetFinderInfo use these unions for Finder information. + */ + +union FinderInfo +{ + FileInfo file; + FolderInfo folder; +}; +typedef union FinderInfo FinderInfo; + +union ExtendedFinderInfo +{ + ExtendedFileInfo file; + ExtendedFolderInfo folder; +}; +typedef union ExtendedFinderInfo ExtendedFinderInfo; + +/*****************************************************************************/ + +#pragma mark ----- GetVolParmsInfoBuffer Macros ----- + +/* + * Macros to get information out of GetVolParmsInfoBuffer. + */ + +/* version 1 field getters */ +#define GetVolParmsInfoVersion(volParms) \ + ((volParms)->vMVersion) +#define GetVolParmsInfoAttrib(volParms) \ + ((volParms)->vMAttrib) +#define GetVolParmsInfoLocalHand(volParms) \ + ((volParms)->vMLocalHand) +#define GetVolParmsInfoServerAdr(volParms) \ + ((volParms)->vMServerAdr) + +/* version 2 field getters (assume zero result if version < 2) */ +#define GetVolParmsInfoVolumeGrade(volParms) \ + (((volParms)->vMVersion >= 2) ? (volParms)->vMVolumeGrade : 0) +#define GetVolParmsInfoForeignPrivID(volParms) \ + (((volParms)->vMVersion >= 2) ? (volParms)->vMForeignPrivID : 0) + +/* version 3 field getters (assume zero result if version < 3) */ +#define GetVolParmsInfoExtendedAttributes(volParms) \ + (((volParms)->vMVersion >= 3) ? (volParms)->vMExtendedAttributes : 0) + +/* attribute bits supported by all versions of GetVolParmsInfoBuffer */ +#define VolIsNetworkVolume(volParms) \ + ((volParms)->vMServerAdr != 0) +#define VolHasLimitFCBs(volParms) \ + (((volParms)->vMAttrib & (1L << bLimitFCBs)) != 0) +#define VolHasLocalWList(volParms) \ + (((volParms)->vMAttrib & (1L << bLocalWList)) != 0) +#define VolHasNoMiniFndr(volParms) \ + (((volParms)->vMAttrib & (1L << bNoMiniFndr)) != 0) +#define VolHasNoVNEdit(volParms) \ + (((volParms)->vMAttrib & (1L << bNoVNEdit)) != 0) +#define VolHasNoLclSync(volParms) \ + (((volParms)->vMAttrib & (1L << bNoLclSync)) != 0) +#define VolHasTrshOffLine(volParms) \ + (((volParms)->vMAttrib & (1L << bTrshOffLine)) != 0) +#define VolHasNoSwitchTo(volParms) \ + (((volParms)->vMAttrib & (1L << bNoSwitchTo)) != 0) +#define VolHasNoDeskItems(volParms) \ + (((volParms)->vMAttrib & (1L << bNoDeskItems)) != 0) +#define VolHasNoBootBlks(volParms) \ + (((volParms)->vMAttrib & (1L << bNoBootBlks)) != 0) +#define VolHasAccessCntl(volParms) \ + (((volParms)->vMAttrib & (1L << bAccessCntl)) != 0) +#define VolHasNoSysDir(volParms) \ + (((volParms)->vMAttrib & (1L << bNoSysDir)) != 0) +#define VolHasExtFSVol(volParms) \ + (((volParms)->vMAttrib & (1L << bHasExtFSVol)) != 0) +#define VolHasOpenDeny(volParms) \ + (((volParms)->vMAttrib & (1L << bHasOpenDeny)) != 0) +#define VolHasCopyFile(volParms) \ + (((volParms)->vMAttrib & (1L << bHasCopyFile)) != 0) +#define VolHasMoveRename(volParms) \ + (((volParms)->vMAttrib & (1L << bHasMoveRename)) != 0) +#define VolHasDesktopMgr(volParms) \ + (((volParms)->vMAttrib & (1L << bHasDesktopMgr)) != 0) +#define VolHasShortName(volParms) \ + (((volParms)->vMAttrib & (1L << bHasShortName)) != 0) +#define VolHasFolderLock(volParms) \ + (((volParms)->vMAttrib & (1L << bHasFolderLock)) != 0) +#define VolHasPersonalAccessPrivileges(volParms) \ + (((volParms)->vMAttrib & (1L << bHasPersonalAccessPrivileges)) != 0) +#define VolHasUserGroupList(volParms) \ + (((volParms)->vMAttrib & (1L << bHasUserGroupList)) != 0) +#define VolHasCatSearch(volParms) \ + (((volParms)->vMAttrib & (1L << bHasCatSearch)) != 0) +#define VolHasFileIDs(volParms) \ + (((volParms)->vMAttrib & (1L << bHasFileIDs)) != 0) +#define VolHasBTreeMgr(volParms) \ + (((volParms)->vMAttrib & (1L << bHasBTreeMgr)) != 0) +#define VolHasBlankAccessPrivileges(volParms) \ + (((volParms)->vMAttrib & (1L << bHasBlankAccessPrivileges)) != 0) +#define VolSupportsAsyncRequests(volParms) \ + (((volParms)->vMAttrib & (1L << bSupportsAsyncRequests)) != 0) +#define VolSupportsTrashVolumeCache(volParms) \ + (((volParms)->vMAttrib & (1L << bSupportsTrashVolumeCache)) != 0) + +/* attribute bits supported by version 3 and greater versions of GetVolParmsInfoBuffer */ +#define VolIsEjectable(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bIsEjectable)) != 0) +#define VolSupportsHFSPlusAPIs(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsHFSPlusAPIs)) != 0) +#define VolSupportsFSCatalogSearch(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsFSCatalogSearch)) != 0) +#define VolSupportsFSExchangeObjects(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsFSExchangeObjects)) != 0) +#define VolSupports2TBFiles(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupports2TBFiles)) != 0) +#define VolSupportsLongNames(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsLongNames)) != 0) +#define VolSupportsMultiScriptNames(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsMultiScriptNames)) != 0) +#define VolSupportsNamedForks(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsNamedForks)) != 0) +#define VolSupportsSubtreeIterators(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsSubtreeIterators)) != 0) +#define VolL2PCanMapFileBlocks(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bL2PCanMapFileBlocks)) != 0) +#define VolParentModDateChanges(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bParentModDateChanges)) != 0) +#define VolAncestorModDateChanges(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bAncestorModDateChanges)) != 0) +#define VolSupportsSymbolicLinks(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsSymbolicLinks)) != 0) +#define VolIsAutoMounted(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bIsAutoMounted)) != 0) + +/*****************************************************************************/ + +#pragma mark ----- userPrivileges Bit Masks and Macros ----- + +/* + * Bit masks and macros to get common information out of userPrivileges byte + * returned by FSGetCatalogInfo. + * + * Note: The userPrivileges byte is the same as the ioACUser byte returned + * by PBGetCatInfo, and is the 1's complement of the user's privileges + * byte returned in ioACAccess by PBHGetDirAccess. That's where the + * ioACUser names came from. + * + * The userPrivileges are user's effective privileges based on the + * user ID and the groups that user belongs to, and the owner, group, + * and everyone privileges for the given directory. + */ + +enum +{ + /* mask for just the access restriction bits */ + kioACUserAccessMask = (kioACUserNoSeeFolderMask + + kioACUserNoSeeFilesMask + + kioACUserNoMakeChangesMask), + /* common access privilege settings */ + kioACUserFull = 0x00, /* no access restiction bits on */ + kioACUserNone = kioACUserAccessMask, /* all access restiction bits on */ + kioACUserDropBox = (kioACUserNoSeeFolderMask + + kioACUserNoSeeFilesMask), /* make changes, but not see files or folders */ + kioACUserBulletinBoard = kioACUserNoMakeChangesMask /* see files and folders, but not make changes */ +}; + + +/* Macros for testing ioACUser bits. */ + +#define UserIsOwner(userPrivileges) \ + (((userPrivileges) & kioACUserNotOwnerMask) == 0) +#define UserHasFullAccess(userPrivileges) \ + (((userPrivileges) & (kioACUserAccessMask)) == kioACUserFull) +#define UserHasDropBoxAccess(userPrivileges) \ + (((userPrivileges) & kioACUserAccessMask) == kioACUserDropBox) +#define UserHasBulletinBoard(userPrivileges) \ + (((userPrivileges) & kioACUserAccessMask) == kioACUserBulletinBoard) +#define UserHasNoAccess(userPrivileges) \ + (((userPrivileges) & kioACUserAccessMask) == kioACUserNone) + +/*****************************************************************************/ + +#pragma mark ----- File Access Routines ----- + +/*****************************************************************************/ + +#pragma mark FSCopyFork + +OSErr +FSCopyFork( + SInt16 srcRefNum, + SInt16 dstRefNum, + void *copyBufferPtr, + ByteCount copyBufferSize); + +/* + The FSCopyFork function copies all data from the source fork to the + destination fork of open file forks and makes sure the destination EOF + is equal to the source EOF. + + srcRefNum --> The source file reference number. + dstRefNum --> The destination file reference number. + copyBufferPtr --> Pointer to buffer to use during copy. The + buffer should be at least 4K-bytes minimum. + The larger the buffer, the faster the copy + (up to a point). + copyBufferSize --> The size of the copy buffer. +*/ + +/*****************************************************************************/ + +#pragma mark ----- Volume Access Routines ----- + +/*****************************************************************************/ + +#pragma mark FSGetVolParms + +OSErr +FSGetVolParms( + FSVolumeRefNum volRefNum, + UInt32 bufferSize, + GetVolParmsInfoBuffer *volParmsInfo, + UInt32 *actualInfoSize); + +/* + The FSGetVolParms function returns information about the characteristics + of a volume. A result of paramErr usually just means the volume doesn't + support GetVolParms and the feature you were going to check + for isn't available. + + volRefNum --> Volume specification. + bufferSize --> Size of buffer pointed to by volParmsInfo. + volParmsInfo <-- A GetVolParmsInfoBuffer record where the volume + attributes information is returned. + actualInfoSize <-- The number of bytes actually returned + in volParmsInfo. + + __________ + + Also see: The GetVolParmsInfoBuffer Macros for checking attribute bits + in this file +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVRefNum + +OSErr +FSGetVRefNum( + const FSRef *ref, + FSVolumeRefNum *vRefNum); + +/* + The FSGetVRefNum function determines the volume reference + number of a volume from a FSRef. + + ref --> The FSRef. + vRefNum <-- The volume reference number. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVInfo + +OSErr +FSGetVInfo( + FSVolumeRefNum volume, + HFSUniStr255 *volumeName, /* can be NULL */ + UInt64 *freeBytes, /* can be NULL */ + UInt64 *totalBytes); /* can be NULL */ + +/* + The FSGetVInfo function returns the name, available space (in bytes), + and total space (in bytes) for the specified volume. + + volume --> The volume reference number. + volumeName <** An optional pointer to a HFSUniStr255. + If not NULL, the volume name will be returned in + the HFSUniStr255. + freeBytes <** An optional pointer to a UInt64. + If not NULL, the number of free bytes on the + volume will be returned in the UInt64. + totalBytes <** An optional pointer to a UInt64. + If not NULL, the total number of bytes on the + volume will be returned in the UInt64. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVolFileSystemID + +OSErr +FSGetVolFileSystemID( + FSVolumeRefNum volume, + UInt16 *fileSystemID, /* can be NULL */ + UInt16 *signature); /* can be NULL */ + +/* + The FSGetVolFileSystemID function returns the file system ID and signature + of a mounted volume. The file system ID identifies the file system + that handles requests to a particular volume. The signature identifies the + volume type of the volume (for example, FSID 0 is Macintosh HFS Plus, HFS + or MFS, where a signature of 0x4244 identifies the volume as HFS). + Here's a partial list of file system ID numbers (only Apple's file systems + are listed): + FSID File System + ----- ----------------------------------------------------- + $0000 Macintosh HFS Plus, HFS or MFS + $0100 ProDOS File System + $0101 PowerTalk Mail Enclosures + $4147 ISO 9660 File Access (through Foreign File Access) + $4242 High Sierra File Access (through Foreign File Access) + $464D QuickTake File System (through Foreign File Access) + $4953 Macintosh PC Exchange (MS-DOS) + $4A48 Audio CD Access (through Foreign File Access) + $4D4B Apple Photo Access (through Foreign File Access) + $6173 AppleShare (later versions of AppleShare only) + + See the Technical Note "FL 35 - Determining Which File System + Is Active" and the "Guide to the File System Manager" for more + information. + + volume --> The volume reference number. + fileSystemID <** An optional pointer to a UInt16. + If not NULL, the volume's file system ID will + be returned in the UInt16. + signature <** An optional pointer to a UInt16. + If not NULL, the volume's signature will + be returned in the UInt16. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetMountedVolumes + +OSErr +FSGetMountedVolumes( + FSRef ***volumeRefsHandle, /* pointer to handle of FSRefs */ + ItemCount *numVolumes); + +/* + The FSGetMountedVolumes function returns the list of volumes currently + mounted in an array of FSRef records. The array of FSRef records is + returned in a Handle, volumeRefsHandle, which is allocated by + FSGetMountedVolumes. The caller is responsible for disposing of + volumeRefsHandle if the FSGetMountedVolumes returns noErr. + + volumeRefsHandle <-- Pointer to an FSRef Handle where the array of + FSRefs is to be returned. + numVolumes <-- The number of volumes returned in the array. +*/ + +/*****************************************************************************/ + +#pragma mark ----- FSRef/FSpec/Path/Name Conversion Routines ----- + +/*****************************************************************************/ + +#pragma mark FSRefMakeFSSpec + +OSErr +FSRefMakeFSSpec( + const FSRef *ref, + FSSpec *spec); + +/* + The FSRefMakeFSSpec function returns an FSSpec for the file or + directory specified by the ref parameter. + + ref --> An FSRef specifying the file or directory. + spec <-- The FSSpec. +*/ + +/*****************************************************************************/ + +#pragma mark FSMakeFSRef + +OSErr +FSMakeFSRef( + FSVolumeRefNum volRefNum, + SInt32 dirID, + ConstStr255Param name, + FSRef *ref); + +/* + The FSMakeFSRef function creates an FSRef from the traditional + volume reference number, directory ID and pathname inputs. It is + functionally equivalent to FSMakeFSSpec followed by FSpMakeFSRef. + + volRefNum --> Volume specification. + dirID --> Directory specification. + name --> The file or directory name, or NULL. + ref <-- The FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark FSMakePath + +OSStatus +FSMakePath( + SInt16 vRefNum, + SInt32 dirID, + ConstStr255Param name, + UInt8 *path, + UInt32 maxPathSize); + +/* + The FSMakePath function creates a pathname from the traditional volume reference + number, directory ID, and pathname inputs. It is functionally equivalent to + FSMakeFSSpec, FSpMakeFSRef, FSRefMakePath. + + volRefNum --> Volume specification. + dirID --> Directory specification. + name --> The file or directory name, or NULL. + path <-- A pointer to a buffer which FSMakePath will + fill with a C string representing the pathname + to the file or directory specified. The format of + the pathname returned can be determined with the + Gestalt selector gestaltFSAttr's + gestaltFSUsesPOSIXPathsForConversion bit. + If the gestaltFSUsesPOSIXPathsForConversion bit is + clear, the pathname is a Mac OS File Manager full + pathname in a C string, and file or directory names + in the pathname may be mangled as returned by + the File Manager. If the + gestaltFSUsesPOSIXPathsForConversion bit is set, + the pathname is a UTF8 encoded POSIX absolute + pathname in a C string. In either case, the + pathname returned can be passed back to + FSPathMakeRef to create an FSRef to the file or + directory, or FSPathMakeFSSpec to craete an FSSpec + to the file or directory. + maxPathSize --> The size of the path buffer in bytes. If the path + buffer is too small for the pathname string, + FSMakePath returns pathTooLongErr or + buffersTooSmall. +*/ + +/*****************************************************************************/ + +#pragma mark FSPathMakeFSSpec + +OSStatus +FSPathMakeFSSpec( + const UInt8 *path, + FSSpec *spec, + Boolean *isDirectory); /* can be NULL */ + +/* + The FSPathMakeFSSpec function converts a pathname to an FSSpec. + + path --> A pointer to a C String that is the pathname. The + format of the pathname you must supply can be + determined with the Gestalt selector gestaltFSAttr's + gestaltFSUsesPOSIXPathsForConversion bit. + If the gestaltFSUsesPOSIXPathsForConversion bit is + clear, the pathname must be a Mac OS File Manager + full pathname in a C string. If the + gestaltFSUsesPOSIXPathsForConversion bit is set, + the pathname must be a UTF8 encoded POSIX absolute + pathname in a C string. + spec <-- The FSSpec. + isDirectory <** An optional pointer to a Boolean. + If not NULL, true will be returned in the Boolean + if the specified path is a directory, or false will + be returned in the Boolean if the specified path is + a file. +*/ + +/*****************************************************************************/ + +#pragma mark UnicodeNameGetHFSName + +OSErr +UnicodeNameGetHFSName( + UniCharCount nameLength, + const UniChar *name, + TextEncoding textEncodingHint, + Boolean isVolumeName, + Str31 hfsName); + +/* + The UnicodeNameGetHFSName function converts a Unicode string + to a Pascal Str31 (or Str27) string using an algorithm similar to that used + by the File Manager. Note that if the name is too long or cannot be converted + using the given text encoding hint, you will get an error instead of the + mangled name that the File Manager would return. + + nameLength --> Number of UniChar in name parameter. + name --> The Unicode string to convert. + textEncodingHint --> The text encoding hint used for the conversion. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + isVolumeName --> If true, the output name will be limited to + 27 characters (kHFSMaxVolumeNameChars). If false, + the output name will be limited to 31 characters + (kHFSMaxFileNameChars). + hfsName <-- The hfsName as a Pascal string. + + __________ + + Also see: HFSNameGetUnicodeName +*/ + +/*****************************************************************************/ + +#pragma mark HFSNameGetUnicodeName + +OSErr +HFSNameGetUnicodeName( + ConstStr31Param hfsName, + TextEncoding textEncodingHint, + HFSUniStr255 *unicodeName); + +/* + The HFSNameGetUnicodeName function converts a Pascal Str31 string to an + Unicode HFSUniStr255 string using the same routines as the File Manager. + + hfsName --> The Pascal string to convert. + textEncodingHint --> The text encoding hint used for the conversion. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + unicodeName <-- The Unicode string. + + __________ + + Also see: UnicodeNameGetHFSName +*/ + +/*****************************************************************************/ + +#pragma mark ----- File/Directory Manipulation Routines ----- + +/*****************************************************************************/ + +#pragma mark FSRefValid + +Boolean FSRefValid(const FSRef *ref); + +/* + The FSRefValid function determines if an FSRef is valid. If the result is + true, then the FSRef refers to an existing file or directory. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetParentRef + +OSErr +FSGetParentRef( + const FSRef *ref, + FSRef *parentRef); + +/* + The FSGetParentRef function gets the parent directory FSRef of the + specified object. + + Note: FSRefs always point to real file system objects. So, there cannot + be a FSRef to the parent of volume root directories. If you call + FSGetParentRef with a ref to the root directory of a volume, the + function result will be noErr and the parentRef will be invalid (using it + for other file system requests will fail). + + ref --> FSRef to a file or directory. + parentRef <-- The parent directory's FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetFileDirName + +OSErr +FSGetFileDirName( + const FSRef *ref, + HFSUniStr255 *outName); + +/* + The FSGetFileDirName function gets the name of the file or directory + specified. + + ref --> FSRef to a file or directory. + outName <-- The file or directory name. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetNodeID + +OSErr +FSGetNodeID( + const FSRef *ref, + long *nodeID, /* can be NULL */ + Boolean *isDirectory); /* can be NULL */ + +/* + The GetNodeIDFromFSRef function gets the node ID number of the + file or directory specified (note: the node ID is the directory ID + for directories). + + ref --> FSRef to a file or directory. + nodeID <** An optional pointer to a long. + If not NULL, the node ID will be returned in + the long. + isDirectory <** An optional pointer to a Boolean. + If not NULL, true will be returned in the Boolean + if the object is a directory, or false will be + returned in the Boolean if object is a file. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetUserPrivilegesPermissions + +OSErr +FSGetUserPrivilegesPermissions( + const FSRef *ref, + UInt8 *userPrivileges, /* can be NULL */ + UInt32 permissions[4]); /* can be NULL */ + +/* + The FSGetUserPrivilegesPermissions function gets the userPrivileges and/or + permissions of the file or directory specified. + + ref --> FSRef to a file or directory. + userPrivileges <** An optional pointer to a UInt8. + If not NULL, the userPrivileges will be returned + in the UInt8. + permissions <** An optional pointer to an UInt32[4] array. + If not NULL, the permissions will be returned + in the UInt32[4] array. +*/ + +/*****************************************************************************/ + +#pragma mark FSCheckLock + +OSErr +FSCheckLock( + const FSRef *ref); + +/* + The FSCheckLock function determines if a file or directory is locked. + If FSCheckLock returns noErr, then the file or directory is not locked + and the volume it is on is not locked either. If FSCheckLock returns + fLckdErr, then the file or directory is locked. If FSCheckLock returns + wPrErr, then the volume is locked by hardware (i.e., locked tab on + removable media). If FSCheckLock returns vLckdErr, then the volume is + locked by software. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetForkSizes + +OSErr +FSGetForkSizes( + const FSRef *ref, + UInt64 *dataLogicalSize, /* can be NULL */ + UInt64 *rsrcLogicalSize); /* can be NULL */ + +/* + The FSGetForkSizes returns the size of the data and/or resource fork for + the specified file. + + ref --> FSRef to a file or directory. + dataLogicalSize <** An optional pointer to a UInt64. + If not NULL, the data fork's size will be + returned in the UInt64. + rsrcLogicalSize <** An optional pointer to a UInt64. + If not NULL, the resource fork's size will be + returned in the UInt64. + + __________ + + Also see: FSGetTotalForkSizes +*/ + +/*****************************************************************************/ + +#pragma mark FSGetTotalForkSizes + +OSErr +FSGetTotalForkSizes( + const FSRef *ref, + UInt64 *totalLogicalSize, /* can be NULL */ + UInt64 *totalPhysicalSize, /* can be NULL */ + ItemCount *forkCount); /* can be NULL */ + +/* + The FSGetTotalForkSizes returns the total logical size and/or the total + physical size of the specified file (i.e., it adds the sizes of all file + forks). It optionally returns the number of file forks. + + ref --> FSRef to a file or directory. + totalLogicalSize <** An optional pointer to a UInt64. + If not NULL, the sum of all fork logical sizes + will be returned in the UInt64. + totalPhysicalSize <** An optional pointer to a UInt64. + If not NULL, the sum of all fork physical sizes + will be returned in the UInt64. + forkCount <** An optional pointer to a ItemCount. + If not NULL, the number of file forks + will be returned in the ItemCount. + + __________ + + Also see: FSGetForkSizes +*/ + +/*****************************************************************************/ + +#pragma mark FSBumpDate + +OSErr +FSBumpDate( + const FSRef *ref); + +/* + The FSBumpDate function changes the content modification date of a file + or directory to the current date/time. If the content modification date + is already equal to the current date/time, then add one second to the + content modification date. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetFinderInfo + +OSErr +FSGetFinderInfo( + const FSRef *ref, + FinderInfo *info, /* can be NULL */ + ExtendedFinderInfo *extendedInfo, /* can be NULL */ + Boolean *isDirectory); /* can be NULL */ + +/* + The FSGetFinderInfo function gets the finder information for a file or + directory. + + ref --> FSRef to a file or directory. + info <** An optional pointer to a FinderInfo. + If not NULL, the FileInfo (if ref is a file) or + the FolderInfo (if ref is a folder) will be + returned in the FinderInfo. + extendedInfo <** An optional pointer to a ExtendedFinderInfo. + If not NULL, the ExtendedFileInfo (if ref is a file) + or the ExtendedFolderInfo (if ref is a folder) will + be returned in the ExtendedFinderInfo. + isDirectory <** An optional pointer to a Boolean. + If not NULL, true will be returned in the Boolean + if the object is a directory, or false will be + returned in the Boolean if object is a file. + + __________ + + Also see: FSSetFinderInfo +*/ + +/*****************************************************************************/ + +#pragma mark FSSetFinderInfo + +OSErr +FSSetFinderInfo( + const FSRef *ref, + const FinderInfo *info, /* can be NULL */ + const ExtendedFinderInfo *extendedInfo); /* can be NULL */ + +/* + The FSSetFinderInfo function sets the finder information for a file or + directory. + + ref --> FSRef to a file or directory. + info **> A pointer to a FinderInfo record with the new + FileInfo (if ref is a file) or new FolderInfo + (if ref is a folder), or NULL if the FinderInfo + is not to be changed. + extendedInfo **> A pointer to a FinderInfo record with the new + ExtendedFileInfo (if ref is a file) or new + ExtendedFolderInfo (if ref is a folder), or NULL + if the ExtendedFinderInfo is not to be changed. + + __________ + + Also see: FSGetFinderInfo +*/ + +/*****************************************************************************/ + +#pragma mark FSChangeCreatorType + +OSErr +FSChangeCreatorType( + const FSRef *ref, + OSType fileCreator, + OSType fileType); + +/* + The FSChangeCreatorType function changes the creator and/or file type of a file. + + ref --> FSRef to a file. + creator --> The new creator type or 0x00000000 to leave + the creator type alone. + fileType --> The new file type or 0x00000000 to leave the + file type alone. +*/ + +/*****************************************************************************/ + +#pragma mark FSChangeFinderFlags + +OSErr +FSChangeFinderFlags( + const FSRef *ref, + Boolean setBits, + UInt16 flagBits); + +/* + The FSChangeFinderFlags function sets or clears flag bits in + the finderFlags field of a file's FileInfo record or a + directory's FolderInfo record. + + ref --> FSRef to a file or directory. + setBits --> If true, then set the bits specified in flagBits. + If false, then clear the bits specified in flagBits. + flagBits --> The flagBits parameter specifies which Finder Flag + bits to set or clear. If a bit in flagBits is set, + then the same bit in fdFlags is either set or + cleared depending on the state of the setBits + parameter. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetInvisible + +OSErr +FSSetInvisible( + const FSRef *ref); + +#pragma mark FSClearInvisible + +OSErr +FSClearInvisible( + const FSRef *ref); + +/* + The FSSetInvisible and FSClearInvisible functions set or clear the + kIsInvisible bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetNameLocked + +OSErr +FSSetNameLocked( + const FSRef *ref); + +#pragma mark FSClearNameLocked + +OSErr +FSClearNameLocked( + const FSRef *ref); + +/* + The FSSetNameLocked and FSClearNameLocked functions set or clear the + kNameLocked bit bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetIsStationery + +OSErr +FSSetIsStationery( + const FSRef *ref); + +#pragma mark FSClearIsStationery + +OSErr +FSClearIsStationery( + const FSRef *ref); + +/* + The FSSetIsStationery and FSClearIsStationery functions set or clear the + kIsStationery bit bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetHasCustomIcon + +OSErr +FSSetHasCustomIcon( + const FSRef *ref); + +#pragma mark FSClearHasCustomIcon + +OSErr +FSClearHasCustomIcon( + const FSRef *ref); + +/* + The FSSetHasCustomIcon and FSClearHasCustomIcon functions set or clear the + kHasCustomIcon bit bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSClearHasBeenInited + +OSErr +FSClearHasBeenInited( + const FSRef *ref); + +/* + The FSClearHasBeenInited function clears the kHasBeenInited bit in the + finderFlags field of the specified file or directory's finder information. + + Note: There is no FSSetHasBeenInited function because ONLY the Finder + should set the kHasBeenInited bit. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSCopyFileMgrAttributes + +OSErr +FSCopyFileMgrAttributes( + const FSRef *sourceRef, + const FSRef *destinationRef, + Boolean copyLockBit); + +/* + The CopyFileMgrAttributes function copies all File Manager attributes + from the source file or directory to the destination file or directory. + If copyLockBit is true, then set the locked state of the destination + to match the source. + + sourceRef --> FSRef to a file or directory. + destinationRef --> FSRef to a file or directory. + copyLockBit --> If true, set the locked state of the destination + to match the source. +*/ + +/*****************************************************************************/ + +#pragma mark FSMoveRenameObjectUnicode + +OSErr +FSMoveRenameObjectUnicode( + const FSRef *ref, + const FSRef *destDirectory, + UniCharCount nameLength, + const UniChar *name, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef); /* if function fails along the way, newRef is final location of file */ + +/* + The FSMoveRenameObjectUnicode function moves a file or directory and + optionally renames it. The source and destination locations must be on + the same volume. + + Note: If the input ref parameter is invalid, this call will fail and + newRef, like ref, will be invalid. + + ref --> FSRef to a file or directory. + destDirectory --> FSRef to the destination directory. + nameLength --> Number of UniChar in name parameter. + name --> An Unicode string with the new name for the + moved object, or NULL if no rename is wanted. + textEncodingHint --> The text encoding hint used for the rename. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + newRef <-- The new FSRef of the object moved. Note that if + this function fails at any step along the way, + newRef is still then final location of the object. +*/ + +/*****************************************************************************/ + +#pragma mark FSDeleteContainerContents + +OSErr +FSDeleteContainerContents( + const FSRef *container); + +/* + The FSDeleteContainerContents function deletes the contents of a container + directory. All files and subdirectories in the specified container are + deleted. If a locked file or directory is encountered, it is unlocked and + then deleted. If any unexpected errors are encountered, + FSDeleteContainerContents quits and returns to the caller. + + container --> FSRef to a directory. + + __________ + + Also see: FSDeleteContainer +*/ + +/*****************************************************************************/ + +#pragma mark FSDeleteContainer + +OSErr +FSDeleteContainer( + const FSRef *container); + +/* + The FSDeleteContainer function deletes a container directory and its contents. + All files and subdirectories in the specified container are deleted. + If a locked file or directory is encountered, it is unlocked and then + deleted. After deleting the container's contents, the container is + deleted. If any unexpected errors are encountered, FSDeleteContainer + quits and returns to the caller. + + container --> FSRef to a directory. + + __________ + + Also see: FSDeleteContainerContents +*/ + +/*****************************************************************************/ + +#pragma mark IterateContainerFilterProcPtr + +typedef CALLBACK_API( Boolean , IterateContainerFilterProcPtr ) ( + Boolean containerChanged, + ItemCount currentLevel, + const FSCatalogInfo *catalogInfo, + const FSRef *ref, + const FSSpec *spec, + const HFSUniStr255 *name, + void *yourDataPtr); + +/* + This is the prototype for the IterateContainerFilterProc function which + is called once for each file and directory found by FSIterateContainer. + The IterateContainerFilterProc can use the read-only data it receives for + whatever it wants. + + The result of the IterateContainerFilterProc function indicates if + iteration should be stopped. To stop iteration, return true; to continue + iteration, return false. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within the IterateContainerFilterProc. + + containerChanged --> Set to true if the container's contents changed + during iteration. + currentLevel --> The current recursion level into the container. + 1 = the container, 2 = the container's immediate + subdirectories, etc. + catalogInfo --> The catalog information for the current object. + Only the fields requested by the whichInfo + parameter passed to FSIterateContainer are valid. + ref --> The FSRef to the current object. + spec --> The FSSpec to the current object if the wantFSSpec + parameter passed to FSIterateContainer is true. + name --> The name of the current object if the wantName + parameter passed to FSIterateContainer is true. + yourDataPtr --> An optional pointer to whatever data structure you + might want to access from within the + IterateFilterProc. + result <-- To stop iteration, return true; to continue + iteration, return false. + + __________ + + Also see: FSIterateContainer +*/ + +/*****************************************************************************/ + +#pragma mark CallIterateContainerFilterProc + +#define CallIterateContainerFilterProc(userRoutine, containerChanged, currentLevel, catalogInfo, ref, spec, name, yourDataPtr) \ + (*(userRoutine))((containerChanged), (currentLevel), (catalogInfo), (ref), (spec), (name), (yourDataPtr)) + +/*****************************************************************************/ + +#pragma mark FSIterateContainer + +OSErr +FSIterateContainer( + const FSRef *container, + ItemCount maxLevels, + FSCatalogInfoBitmap whichInfo, + Boolean wantFSSpec, + Boolean wantName, + IterateContainerFilterProcPtr iterateFilter, + void *yourDataPtr); + +/* + The FSIterateContainer function performs a recursive iteration (scan) of the + specified container directory and calls your IterateContainerFilterProc + function once for each file and directory found. + + The maxLevels parameter lets you control how deep the recursion goes. + If maxLevels is 1, FSIterateContainer only scans the specified directory; + if maxLevels is 2, FSIterateContainer scans the specified directory and + one subdirectory below the specified directory; etc. Set maxLevels to + zero to scan all levels. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within your IterateContainerFilterProc. + + container --> The FSRef to the container directory to iterate. + maxLevels --> Maximum number of directory levels to scan or + zero to scan all directory levels. + whichInfo --> The fields of the FSCatalogInfo you wish to get. + wantFSSpec --> Set to true if you want the FSSpec to each + object passed to your IterateContainerFilterProc. + wantName --> Set to true if you want the name of each + object passed to your IterateContainerFilterProc. + iterateFilter --> A pointer to the IterateContainerFilterProc you + want called once for each file and directory found + by FSIterateContainer. + yourDataPtr --> An optional pointer to whatever data structure you + might want to access from within the + IterateFilterProc. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetDirectoryItems + +OSErr +FSGetDirectoryItems( + const FSRef *container, + FSRef ***refsHandle, /* pointer to handle of FSRefs */ + ItemCount *numRefs, + Boolean *containerChanged); + +/* + The FSGetDirectoryItems function returns the list of items in the specified + container. The array of FSRef records is returned in a Handle, refsHandle, + which is allocated by FSGetDirectoryItems. The caller is responsible for + disposing of refsHandle if the FSGetDirectoryItems returns noErr. + + container --> FSRef to a directory. + refsHandle <-- Pointer to an FSRef Handle where the array of + FSRefs is to be returned. + numRefs <-- The number of FSRefs returned in the array. + containerChanged <-- Set to true if the container changes while the + list of items is being obtained. +*/ + +/*****************************************************************************/ + +#pragma mark FSExchangeObjectsCompat + +OSErr +FSExchangeObjectsCompat( + const FSRef *sourceRef, + const FSRef *destRef, + FSRef *newSourceRef, + FSRef *newDestRef); + +/* + The FSExchangeObjectsCompat function exchanges the data between two files. + + The FSExchangeObjectsCompat function is an enhanced version of + FSExchangeObjects function. The two enhancements FSExchangeObjectsCompat + provides are: + + 1, FSExchangeObjectsCompat will work on volumes which do not support + FSExchangeObjects. FSExchangeObjectsCompat does this by emulating + FSExchangeObjects through a series of File Manager operations. If + there is a failure at any step along the way, FSExchangeObjectsCompat + attempts to undo any steps already taken to leave the files in their + original state in their original locations. + + 2. FSExchangeObjectsCompat returns new FSRefs to the source and + destination files. Note that if this function fails at any step along + the way, newSourceRef and newDestRef still give you access to the final + locations of the files being exchanged -- even if they are renamed or + not in their original locations. + + sourceRef --> FSRef to the source file. + destRef --> FSRef to the destination file. + newSourceRef <-- The new FSRef to the source file. + newDestRef <-- The new FSRef to the destination file. +*/ + +/*****************************************************************************/ + +#pragma mark ----- Shared Environment Routines ----- + +/*****************************************************************************/ + +#pragma mark FSLockRange + +OSErr +FSLockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart); + +/* + The LockRange function locks (denies access to) a portion of a file + that was opened with shared read/write permission. + + refNum --> The file reference number of an open file. + rangeLength --> The number of bytes in the range. + rangeStart --> The starting byte in the range to lock. + + __________ + + Also see: UnlockRange +*/ + +/*****************************************************************************/ + +#pragma mark FSUnlockRange + +OSErr +FSUnlockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart); + +/* + The UnlockRange function unlocks (allows access to) a previously locked + portion of a file that was opened with shared read/write permission. + + refNum --> The file reference number of an open file. + rangeLength --> The number of bytes in the range. + rangeStart --> The starting byte in the range to unlock. + + __________ + + Also see: LockRange +*/ + +/*****************************************************************************/ + +#pragma mark FSGetDirAccess + +OSErr +FSGetDirAccess( + const FSRef *ref, + SInt32 *ownerID, /* can be NULL */ + SInt32 *groupID, /* can be NULL */ + SInt32 *accessRights); /* can be NULL */ + +/* + The FSGetDirAccess function retrieves the directory access control + information for a directory on a shared volume. + + ref --> An FSRef specifying the directory. + ownerID <** An optional pointer to a SInt32. + If not NULL, the directory's owner ID + will be returned in the SInt32. + groupID <** An optional pointer to a SInt32. + If not NULL, the directory's group ID, or 0 + if no group affiliation, will be returned in + the SInt32. + accessRights <** An optional pointer to a SInt32. + If not NULL, the directory's access rights + will be returned in the SInt32. + + __________ + + Also see: FSSetDirAccess, FSMapID, FSMapName +*/ + +/*****************************************************************************/ + +#pragma mark FSSetDirAccess + +OSErr +FSSetDirAccess( + const FSRef *ref, + SInt32 ownerID, + SInt32 groupID, + SInt32 accessRights); + +/* + The FSpSetDirAccess function changes the directory access control + information for a directory on a shared volume. You must be the owner of + a directory to change its access control information. + + ref --> An FSRef specifying the directory. + ownerID --> The directory's owner ID. + groupID --> The directory's group ID or 0 if no group affiliation. + accessRights --> The directory's access rights. + + __________ + + Also see: FSGetDirAccess, FSMapID, FSMapName +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVolMountInfoSize + +OSErr +FSGetVolMountInfoSize( + FSVolumeRefNum volRefNum, + SInt16 *size); + +/* + The FSGetVolMountInfoSize function determines the how much space the + program needs to allocate for a volume mounting information record. + + volRefNum --> Volume specification. + size <-- The space needed (in bytes) of the volume + mounting information record. + + __________ + + Also see: FSGetVolMountInfo, VolumeMount +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVolMountInfo + +OSErr +FSGetVolMountInfo( + FSVolumeRefNum volRefNum, + void *volMountInfo); + +/* + The FSGetVolMountInfo function retrieves a volume mounting information + record containing all the information needed to mount the volume, + except for passwords. + + volRefNum --> Volume specification. + volMountInfo <-- The volume mounting information. + + __________ + + Also see: FSGetVolMountInfoSize, VolumeMount +*/ + +/*****************************************************************************/ + +#pragma mark FSVolumeMount + +OSErr +FSVolumeMount( + const void *volMountInfo, + FSVolumeRefNum *volRefNum); + +/* + The VolumeMount function mounts a volume using a volume mounting + information record. + + volMountInfo --> A volume mounting information record. + volRefNum <-- The volume reference number. + + __________ + + Also see: FSGetVolMountInfoSize, FSGetVolMountInfo +*/ + +/*****************************************************************************/ + +#pragma mark FSMapID + +OSErr +FSMapID( + FSVolumeRefNum volRefNum, + SInt32 ugID, + SInt16 objType, + Str31 name); + +/* + The FSMapID function determines the name of a user or group if you know + the user or group ID. + + volRefNum --> Volume specification. + objType --> The mapping function code: + kOwnerID2Name to map a user ID to a user name + kGroupID2Name to map a group ID to a group name + name <** An optional pointer to a buffer (minimum Str31). + If not NULL, the user or group name + will be returned in the buffer. + + __________ + + Also see: FSGetDirAccess, FSSetDirAccess, FSMapName +*/ + +/*****************************************************************************/ + +#pragma mark FSMapName + +OSErr +FSMapName( + FSVolumeRefNum volRefNum, + ConstStr255Param name, + SInt16 objType, + SInt32 *ugID); + +/* + The FSMapName function determines the user or group ID if you know the + user or group name. + + volRefNum --> Volume specification. + name --> The user or group name. + objType --> The mapping function code: + kOwnerName2ID to map a user name to a user ID + kGroupName2ID to map a user name to a group ID + ugID <-- The user or group ID. + + __________ + + Also see: FSGetDirAccess, FSSetDirAccess, FSMapID +*/ + +/*****************************************************************************/ + +#pragma mark FSCopyFile + +OSErr +FSCopyFile( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *copyName, /* can be NULL (no rename during copy) */ + TextEncoding textEncodingHint, + FSRef *newRef); /* can be NULL */ + +/* + The FSCopyFile function duplicates a file and optionally renames it. + The source and destination volumes must be on the same file server. + This function instructs the server to copy the file. + + srcFileRef --> An FSRef specifying the source file. + dstDirectoryRef --> An FSRef specifying the destination directory. + nameLength --> Number of UniChar in copyName parameter (ignored + if copyName is NULL). + copyName --> Points to the new file name if the file is to be + renamed, or NULL if the file isn't to be renamed. + textEncodingHint --> The text encoding hint used for the rename. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + newRef <** An optional pointer to a FSRef. + If not NULL, the FSRef of the duplicated file + will be returned in the FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark FSMoveRename + +OSErr +FSMoveRename( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *moveName, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef); /* can be NULL */ + +/* + The FSMoveRename function moves a file or directory (object), and + optionally renames it. The source and destination locations must be on + the same shared volume. + + srcFileRef --> An FSRef specifying the source file. + dstDirectoryRef --> An FSRef specifying the destination directory. + nameLength --> Number of UniChar in moveName parameter (ignored + if copyName is NULL) + moveName --> Points to the new object name if the object is to be + renamed, or NULL if the object isn't to be renamed. + textEncodingHint --> The text encoding hint used for the rename. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + newRef <** An optional pointer to a FSRef. + If not NULL, the FSRef of the moved object + will be returned in the FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark ----- File ID Routines ----- + +/*****************************************************************************/ + +#pragma mark FSResolveFileIDRef + +OSErr +FSResolveFileIDRef( + FSVolumeRefNum volRefNum, + SInt32 fileID, + FSRef *ref); + +/* + The FSResolveFileIDRef function returns an FSRef for the file with the + specified file ID reference. + + volRefNum --> Volume specification. + fileID --> The file ID reference. + ref <-- The FSRef for the file ID reference. + + __________ + + Also see: FSCreateFileIDRef, FSDeleteFileIDRef +*/ + +/*****************************************************************************/ + +#pragma mark FSCreateFileIDRef + +OSErr +FSCreateFileIDRef( + const FSRef *ref, + SInt32 *fileID); + +/* + The FSCreateFileIDRef function creates a file ID reference for the + specified file, or if a file ID reference already exists, supplies + the file ID reference and returns the result code fidExists or afpIDExists. + + ref --> The FSRef for the file. + fileID <-- The file ID reference (if result is noErr, + fidExists, or afpIDExists). + + __________ + + Also see: GetFSRefFromFileIDRef, FSDeleteFileIDRef +*/ + +/*****************************************************************************/ + +#pragma mark FSDeleteFileIDRef + +/* + Why is there no FSDeleteFileIDRef routine? There are two reasons: + + 1. Since Mac OS 8.1, PBDeleteFileIDRef hasn't deleted file ID references. + On HFS volumes, deleting a file ID reference breaks aliases (which + use file ID references to track files as they are moved around on a + volume) and file ID references are automatically deleted when the file + they refer to is deleted. On HFS Plus volumes, file ID references are + always created when a file is created, deleted when the file is deleted, + and cannot be deleted at any other time. + + 2. PBDeleteFileIDRef causes a memory access fault under Mac OS X 10.0 + through 10.1.x. While this will be fixed in a future release, the + implementation, like the Mac OS 8/9 implementation, does not delete + file ID references. + + __________ + + Also see: GetFSRefFromFileIDRef, FSCreateFileIDRef +*/ + +/*****************************************************************************/ + +#pragma mark ----- Utility Routines ----- + +/*****************************************************************************/ + +#pragma mark GetTempBuffer + +Ptr +GetTempBuffer( + ByteCount buffReqSize, + ByteCount *buffActSize); + +/* + The GetTempBuffer function allocates a temporary buffer for file system + operations which is at least 4K bytes and a multiple of 4K bytes. + + buffReqSize --> Size you'd like the buffer to be. + buffActSize <-- The size of the buffer allocated. + function result <-- Pointer to memory allocated, or NULL if no memory + was available. The caller is responsible for + disposing of this buffer with DisposePtr. +*/ + +/*****************************************************************************/ + +#pragma mark FileRefNumGetFSRef + +OSErr +FileRefNumGetFSRef( + short refNum, + FSRef *ref); + +/* + The FileRefNumGetFSRef function gets the FSRef of an open file. + + refNum --> The file reference number of an open file. + ref <-- The FSRef to the open file. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetDefault + +OSErr +FSSetDefault( + const FSRef *newDefault, + FSRef *oldDefault); + +/* + The FSSetDefault function sets the current working directory to the + directory specified by newDefault. The previous current working directory + is returned in oldDefault and must be used to restore the current working + directory to its previous state with the FSRestoreDefault function. + These two functions are designed to be used as a wrapper around + Standard I/O routines where the location of the file is implied to be the + current working directory. This is how you should use these functions: + + result = FSSetDefault(&newDefault, &oldDefault); + if ( noErr == result ) + { + // call the Stdio functions like remove, rename, + // fopen, freopen, etc here! + + result = FSRestoreDefault(&oldDefault); + } + + newDefault --> An FSRef that specifies the new current working + directory. + oldDefault <-- The previous current working directory's FSRef. + + __________ + + Also see: FSRestoreDefault +*/ + +/*****************************************************************************/ + +#pragma mark FSRestoreDefault + +OSErr +FSRestoreDefault( + const FSRef *oldDefault); + +/* + The FSRestoreDefault function restores the current working directory + to the directory specified by oldDefault. The oldDefault parameter was + previously obtained from the FSSetDefault function. + These two functions are designed to be used as a wrapper around + Standard I/O routines where the location of the file is implied to be the + current working directory. This is how you should use these functions: + + result = FSSetDefault(&newDefault, &oldDefault); + if ( noErr == result ) + { + // call the Stdio functions like remove, rename, + // fopen, freopen, etc here! + + result = FSRestoreDefault(&oldDefault); + } + + oldDefault --> The FSRef of the location to restore. + + __________ + + Also see: FSSetDefault +*/ + +/*****************************************************************************/ + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=reset +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(pop) +#elif PRAGMA_STRUCT_PACK + #pragma pack() +#endif + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __MOREFILESX__ */ + diff --git a/corelib/morefile/Optimization.h b/corelib/morefile/Optimization.h new file mode 100644 index 00000000..d2673f93 --- /dev/null +++ b/corelib/morefile/Optimization.h @@ -0,0 +1,109 @@ +/* + File: Optimization.h + + Contains: Defines that let you make MoreFiles code more efficient. + + Version: MoreFiles + + Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved. + + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: Apple Macintosh Developer Technical Support + <http://developer.apple.com/bugreporter/> + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <1> 2/7/01 JL first checked in +*/ + +/* + The Optimization changes to MoreFiles source and header files, along with + this file and OptimizationEnd.h, let you optimize the code produced + by MoreFiles in several ways. + + 1 -- MoreFiles contains extra code so that many routines can run under + Mac OS systems back to System 6. If your program requires a specific + version of Mac OS and your program checks for that version before + calling MoreFiles routines, then you can remove a lot of compatibility + code by defining one of the following to 1: + + __MACOSSEVENFIVEONEORLATER // assume Mac OS 7.5.1 or later + __MACOSSEVENFIVEORLATER // assume Mac OS 7.5 or later + __MACOSSEVENORLATER // assume Mac OS 7.0 or later + + If you're compiling 68K code, the default is to include all compatibility code. + If you're compiling PowerPC code (TARGET_RT_MAC_CFM), the default is __MACOSSEVENORLATER + If you're compiling for Carbon code (TARGET_API_MAC_CARBON), the default is __MACOSSEVENFIVEONEORLATER + + 2 -- You may disable Pascal calling conventions in all MoreFiles routines + except for system callbacks that require Pascal calling conventions. + This will make 68K C programs both smaller and faster. + (PowerPC compilers ignore pascal calling conventions.) + Just define __WANTPASCALELIMINATION to be 1 to turn this optimization on + when building MoreFiles for use from C programs (you'll need to keep + Pascal calling conventions when linking MoreFiles routines with Pascal + programs). + + 3 -- If Metrowerks compiler is used, "#pragma internal on" may help produce + better code. However, this option can also cause problems if you're + trying to build MoreFiles as a shared library, so it is by default not used. + Just define __USEPRAGMAINTERNAL to be 1 to turn this optimization on. + + Original changes supplied by Fabrizio Oddone +*/ + +#include <ConditionalMacros.h> + +// if we're compiling for Carbon, then we're running on Mac OS 8.1 or later +#ifndef __MACOSSEVENFIVEONEORLATER + #define __MACOSSEVENFIVEONEORLATER TARGET_API_MAC_CARBON +#endif + +#ifndef __MACOSSEVENFIVEORLATER + #define __MACOSSEVENFIVEORLATER __MACOSSEVENFIVEONEORLATER +#endif + +#ifndef __MACOSSEVENORLATER + #if TARGET_RT_MAC_CFM + #define __MACOSSEVENORLATER 1 + #else + #define __MACOSSEVENORLATER __MACOSSEVENFIVEORLATER + #endif +#endif + + +#ifndef __WANTPASCALELIMINATION + #define __WANTPASCALELIMINATION 0 +#endif + +#if __WANTPASCALELIMINATION + #define pascal +#endif + + +#ifndef __USEPRAGMAINTERNAL + #define __USEPRAGMAINTERNAL 0 +#endif + +#if __USEPRAGMAINTERNAL + #if defined(__MWERKS__) + #pragma internal on + #endif +#endif diff --git a/corelib/morefile/OptimizationEnd.h b/corelib/morefile/OptimizationEnd.h new file mode 100644 index 00000000..10ed0250 --- /dev/null +++ b/corelib/morefile/OptimizationEnd.h @@ -0,0 +1,56 @@ +/* + File: OptimizationEnd.h + + Contains: Defines that let you make MoreFiles code more efficient. + + Version: MoreFiles + + Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved. + + You may incorporate this sample code into your applications without + restriction, though the sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. However, what you are + not permitted to do is to redistribute the source as "DSC Sample Code" + after having made changes. If you're going to re-distribute the source, + we require that you make it clear in the source that the code was + descended from Apple Sample Code, but that you've made changes. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: Apple Macintosh Developer Technical Support + <http://developer.apple.com/bugreporter/> + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <1> 2/7/01 JL first checked in +*/ + +/* + The Optimization changes to MoreFiles source and header files, along with + this file and Optimization.h, let you optimize the code produced by MoreFiles + in several ways. + + Original changes supplied by Fabrizio Oddone +*/ + + +#if __USEPRAGMAINTERNAL + #if defined(__MWERKS__) + #pragma internal reset + #endif +#endif + + +#if __WANTPASCALELIMINATION + #ifndef __COMPILINGMOREFILES + #undef pascal + #endif +#endif diff --git a/corelib/ncbibs.c b/corelib/ncbibs.c index 6f94986f..cd968e10 100644 --- a/corelib/ncbibs.c +++ b/corelib/ncbibs.c @@ -29,7 +29,7 @@ * * Version Creation Date: 3/4/91 * -* $Revision: 6.5 $ +* $Revision: 6.6 $ * * File Description: * ByteStore functions @@ -56,6 +56,9 @@ * 04-15-93 Schuler Changed _cdecl to LIBCALL * * $Log: ncbibs.c,v $ +* Revision 6.6 2002/02/07 21:52:40 kans +* added cast in Nlm_SwapUint4Buff call +* * Revision 6.5 2000/05/26 23:34:58 kans * added BSDupAndSwapUint4 for copying and swapping of UID lists passed over network to BIG_ENDIAN server * @@ -903,7 +906,7 @@ NLM_EXTERN Nlm_ByteStorePtr LIBCALL Nlm_BSDupAndSwapUint4 (Nlm_ByteStorePtr sour swapLen = Nlm_BSRead (source, buf, count); swapLen /= 4; /* swap Uint4 if IS_LITTLE_ENDIAN */ - Nlm_SwapUint4Buff (buf, swapLen); + Nlm_SwapUint4Buff ((Nlm_Uint4Ptr) buf, swapLen); Nlm_BSWrite (dest, buf, count); sourceLen -= count; count = MIN (sourceLen, (Nlm_Int4) BUFSIZE); diff --git a/corelib/ncbienv.c b/corelib/ncbienv.c index 8e73a8b1..4f646909 100644 --- a/corelib/ncbienv.c +++ b/corelib/ncbienv.c @@ -29,7 +29,7 @@ * * Version Creation Date: 7/7/91 * -* $Revision: 6.25 $ +* $Revision: 6.26 $ * * File Description: * portable environment functions, companions for ncbimain.c @@ -37,6 +37,9 @@ * Modifications: * -------------------------------------------------------------------------- * $Log: ncbienv.c,v $ +* Revision 6.26 2002/03/28 13:29:08 kans +* checks for OS_UNIX_DARWIN (EN) +* * Revision 6.25 2001/08/02 14:44:10 vakatov * [OSF1] NLM_XOPEN_SOURCE_500:: Kludge-fix for the weak-minded native * preprocessor @@ -718,7 +721,7 @@ static FILE* Nlm_OpenConfigFile(const Nlm_Char* file, Nlm_Boolean writeMode, Nlm #endif /* OS_UNIX */ -#ifdef OS_MAC +#if defined(OS_MAC) && !defined(OS_UNIX_DARWIN) /***************************************************************************** * * Nlm_OpenConfigFile (file, writeMode, create) @@ -845,7 +848,7 @@ Nlm_OpenConfigFile(const Nlm_Char* file, } return fp; } -#endif /* OS_MAC */ +#endif /* defined(OS_MAC) && !defined(OS_UNIX_DARWIN) */ #ifdef OS_VMS /***************************************************************************** @@ -1785,7 +1788,7 @@ static int targc = 0; static char **targv = NULL; -#ifdef WIN_MAC +#if defined(WIN_MAC) && !defined(OS_UNIX_DARWIN) static FSSpec apFileSpec; static Str255 apName; static Handle apParam; @@ -1840,7 +1843,7 @@ static void Nlm_ProgramPath_ST(Nlm_Char* buf, size_t maxsize) } } } -#endif /* WIN_MAC */ +#endif /* defined(WIN_MAC) && !defined(OS_UNIX_DARWIN) */ #if defined(OS_MSWIN) || defined(OS_VMS) diff --git a/corelib/ncbifile.c b/corelib/ncbifile.c index e23af7c4..266534bb 100644 --- a/corelib/ncbifile.c +++ b/corelib/ncbifile.c @@ -29,7 +29,7 @@ * * Version Creation Date: 3/4/91 * -* $Revision: 6.23 $ +* $Revision: 6.24 $ * * File Description: * portable file routines @@ -43,6 +43,9 @@ * 11-27-94 Ostell moved includes to ncbiwin.h to avoid conflict MSC * * $Log: ncbifile.c,v $ +* Revision 6.24 2002/04/05 19:02:47 ivanov +* Changed L_tmpnam to PATH_MAX in Nlm_TmpNam() +* * Revision 6.23 2001/08/29 17:33:15 juran * Cleanup. * @@ -1169,7 +1172,7 @@ NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_TmpNam (Nlm_CharPtr s) { #ifdef TEMPNAM_AVAIL char *filename; - static Nlm_Char save_filename[L_tmpnam+30]; + static Nlm_Char save_filename[PATH_MAX]; /* emulate tmpnam(), except get the benefits of tempnam()'s ability to */ /* place the files in another directory specified by the environment */ diff --git a/corelib/ncbilcl.dwn b/corelib/ncbilcl.dwn index b9f6ad58..2c0f1709 100644 --- a/corelib/ncbilcl.dwn +++ b/corelib/ncbilcl.dwn @@ -29,7 +29,7 @@ * * Version Creation Date: 8/1/94 * -* $Revision: 6.2 $ +* $Revision: 6.3 $ * * File Description: * system dependent header @@ -41,11 +41,21 @@ * ------- ---------- --------------------------------------------------- * * $Log: ncbilcl.dwn,v $ +* Revision 6.3 2002/01/22 16:34:54 kans +* contributor contact information copied from obsolete readme.macosx file +* * Revision 6.2 2001/04/03 21:01:54 beloslyu * changed to big endian (according to Nathan Willard <willard@turbogenomics.com>) * * Revision 6.1 2001/01/19 20:28:42 kans -* initial checkin - contributed by William Van Etten +* initial checkin - contributed by William Van Etten <vanetten@computefarm.com> +* +* William Van Etten, PhD +* Blackstone Technology Group +* 80 Summer Street +* Boston, MA 02110 +* 617-542-4770 x4003 +* vanetten@computefarm.com * * Revision 1.1 2001/01/13 15:42:41 vanetten * port to Darwin 1.2 diff --git a/corelib/ncbilcl.hlx b/corelib/ncbilcl.hlx new file mode 100644 index 00000000..1492f93f --- /dev/null +++ b/corelib/ncbilcl.hlx @@ -0,0 +1,158 @@ +/* ncbilcl.h +* =========================================================================== +* +* PUBLIC DOMAIN NOTICE +* National Center for Biotechnology Information +* +* This software/database is a "United States Government Work" under the +* terms of the United States Copyright Act. It was written as part of +* the author's official duties as a United States Government employee and +* thus cannot be copyrighted. This software/database is freely available +* to the public for use. The National Library of Medicine and the U.S. +* Government have not placed any restriction on its use or reproduction. +* +* Although all reasonable efforts have been taken to ensure the accuracy +* and reliability of the software and data, the NLM and the U.S. +* Government do not and cannot warrant the performance or results that +* may be obtained by using this software or data. The NLM and the U.S. +* Government disclaim all warranties, express or implied, including +* warranties of performance, merchantability or fitness for any particular +* purpose. +* +* Please cite the author in any work or product based on this material. +* +* =========================================================================== +* +* File Name: ncbilcl.h +* +* Author: Contributed by Howard Feldman <feldman@mshri.on.ca> +* +* Version Creation Date: 4/5/02 +* +* $Revision: 6.1 $ +* +* File Description: +* system dependent header +* version for HPPA Linux +* +* Modifications: +* -------------------------------------------------------------------------- +* $Log: ncbilcl.hlx,v $ +* Revision 6.1 2002/04/15 20:04:41 ivanov +* Initial revision +* +* ========================================================================== +*/ +#ifndef _NCBILCL_ +#define _NCBILCL_ + +/* PLATFORM DEFINITION FOR Linux */ + +#define COMP_SYSV +#define OS_UNIX +#define OS_UNIX_LINUX +#define OS_UNIX_HPPALINUX +#define PROC_HPPA +#define WIN_DUMB + + +/*----------------------------------------------------------------------*/ +/* Desired or available feature list */ +/*----------------------------------------------------------------------*/ +#define SYSV_IPC_AVAIL /* System V Interprocess Communication available */ +/*#define _POSIX_C_SOURCE 199309L*/ + +#ifndef _REENTRANT +#define _REENTRANT +#endif + +/* good for the EGCS C/C++ compiler on Linux(e.g. putenv(), tempnam() proto) */ +/*#define _SVID_SOURCE 1 */ + + +/*----------------------------------------------------------------------*/ +/* #includes */ +/*----------------------------------------------------------------------*/ +#include <sys/types.h> +#include <limits.h> +#include <sys/stat.h> +#include <stddef.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <malloc.h> +#include <memory.h> +#include <stdlib.h> +#include <math.h> +#include <errno.h> +#include <float.h> +#include <unistd.h> + +/* Check if there are POSIX threads available */ +#ifdef _POSIX_THREADS +#define POSIX_THREADS_AVAIL +#endif + + +/*----------------------------------------------------------------------*/ +/* Missing ANSI-isms */ +/*----------------------------------------------------------------------*/ +#define noalias + +#ifndef SEEK_SET +#define SEEK_SET 0 /* Set file pointer to offset */ +#define SEEK_CUR 1 /* Set file pointer to current plus offset */ +#define SEEK_END 2 /* Set file pointer to EOF plus offset */ +#endif +#ifndef FILENAME_MAX +#define FILENAME_MAX 1024 +#endif + +/*----------------------------------------------------------------------*/ +/* Aliased Logicals, Datatypes */ +/*----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------*/ +/* Misc Macros */ +/*----------------------------------------------------------------------*/ +#define PROTO(x) x /* Prototypes are acceptable */ +#define VPROTO(x) x /* Prototype for variable argument list */ +#define DIRDELIMCHR '/' +#define DIRDELIMSTR "/" +#define CWDSTR "." + +#define KBYTE (1024) +#define MBYTE (1048576) + +#define IS_LITTLE_ENDIAN +#define TEMPNAM_AVAIL + +/*----------------------------------------------------------------------*/ +/* For importing MS_DOS code */ +/*----------------------------------------------------------------------*/ +#define near +#define far +#define huge +#define cdecl +#define pascal +#define _pascal +#define _near +#define _far +#define _huge +#define _cdecl + +/*----------------------------------------------------------------------*/ +/* Macros for Floating Point */ +/*----------------------------------------------------------------------*/ +#define EXP2(x) exp((x)*LN2) +#define LOG2(x) (log(x)*(1./LN2)) +#define EXP10(x) exp((x)*LN10) +#define LOG10(x) log10(x) + +/*----------------------------------------------------------------------*/ +/* Macros Defining Limits */ +/*----------------------------------------------------------------------*/ +#define MAXALLOC 0x40000000 /* Largest permissible memory request */ + +#endif + diff --git a/corelib/ncbilcl.hp_ia64 b/corelib/ncbilcl.hp_ia64 new file mode 100644 index 00000000..85a019b9 --- /dev/null +++ b/corelib/ncbilcl.hp_ia64 @@ -0,0 +1,151 @@ +/* ncbilcl.h +* =========================================================================== +* +* PUBLIC DOMAIN NOTICE +* National Center for Biotechnology Information +* +* This software/database is a "United States Government Work" under the +* terms of the United States Copyright Act. It was written as part of +* the author's official duties as a United States Government employee and +* thus cannot be copyrighted. This software/database is freely available +* to the public for use. The National Library of Medicine and the U.S. +* Government have not placed any restriction on its use or reproduction. +* +* Although all reasonable efforts have been taken to ensure the accuracy +* and reliability of the software and data, the NLM and the U.S. +* Government do not and cannot warrant the performance or results that +* may be obtained by using this software or data. The NLM and the U.S. +* Government disclaim all warranties, express or implied, including +* warranties of performance, merchantability or fitness for any particular +* purpose. +* +* Please cite the author in any work or product based on this material. +* +* =========================================================================== +* +* File Name: ncbilcl.h +* +* $Revision: 6.1 $ +* (this file has not been tested for accuracy) +* +* File Description: +* system dependent header +* HP-UX version on IA64 +* +* ========================================================================== +*/ +#ifndef _NCBILCL_ +#define _NCBILCL_ + +/* PLATFORM DEFINITION FOR Hewlett-Packard UNDER HP-UX */ + +#define COMP_SYSV +#define OS_UNIX +#define OS_UNIX_HPUX +#define PROC_HPIA64 +#define WIN_DUMB + +/*----------------------------------------------------------------------*/ +/* Desired or available feature list */ +/*----------------------------------------------------------------------*/ +#define SYSV_IPC_AVAIL /* System V Interprocess Communication available */ +#define SYSV_STREAMS_AVAIL /* System V STREAMS module available */ + +/*----------------------------------------------------------------------*/ +/* Defines needed to trigger the correct inclusions in system files*/ +/* Reportedly needed in HP/UX 9.05 */ +/*----------------------------------------------------------------------*/ +#define _INCLUDE_POSIX_SOURCE +#define _INCLUDE_XOPEN_SOURCE +#define _XOPEN_SOURCE_EXTENDED +#define _INCLUDE_XOPEN_SOURCE_EXTENDED + +/* allow the fork with largefiles */ +#define _FILE_OFFSET_BITS 64 + +#define POSIX_THREADS_AVAIL +#define _POSIX_C_SOURCE 199506L +/*----------------------------------------------------------------------*/ +/* #includes */ +/*----------------------------------------------------------------------*/ +#include <sys/types.h> +#include <sys/resource.h> +#include <limits.h> +#include <sys/stat.h> +#include <stddef.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <malloc.h> +#include <memory.h> +#include <stdlib.h> +#include <math.h> +#include <errno.h> +#include <float.h> + +/*----------------------------------------------------------------------*/ +/* Missing ANSI-isms */ +/*----------------------------------------------------------------------*/ +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif +#ifdef FILENAME_MAX +#undef FILENAME_MAX +#endif +#define FILENAME_MAX 1024 + +/*----------------------------------------------------------------------*/ +/* Aliased Logicals, Datatypes */ +/*----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------*/ +/* Misc Macros */ +/*----------------------------------------------------------------------*/ +#if defined(__STDC__) +#define PROTO(x) x /* Function prototypes copied */ +#define VPROTO(x) x /* Prototype for variable argument list */ +#else +#define PROTO(x) () /* Function prototypes faked in */ +#define VPROTO(x) () /* Prototype for variable argument list */ +#endif +#define DIRDELIMCHR '/' +#define DIRDELIMSTR "/" +#define CWDSTR "." + +#define KBYTE (1024) +#define MBYTE (1048576) + +#define IS_BIG_ENDIAN +#define TEMPNAM_AVAIL + +/*----------------------------------------------------------------------*/ +/* For importing MS_DOS code */ +/*----------------------------------------------------------------------*/ +#define near +#define far +#define huge +#define cdecl +#define pascal +#define _pascal +#define _near +#define _far +#define _huge +#define _cdecl + +/*----------------------------------------------------------------------*/ +/* Macros for Floating Point */ +/*----------------------------------------------------------------------*/ +#define EXP2(x) exp((x)*LN2) +#define LOG2(x) (log(x)*(1./LN2)) +#define EXP10(x) exp((x)*LN10) +#define LOG10(x) (log(x)*(1./LN10)) + +/*----------------------------------------------------------------------*/ +/* Macros Defining Limits */ +/*----------------------------------------------------------------------*/ +#define MAXALLOC 0x40000000 /* Largest permissible memory request */ + +#endif /* _NCBILCL_ */ + diff --git a/corelib/ncbilcl.hp_pa b/corelib/ncbilcl.hp_pa index 5d1551e2..e37057f7 100644 --- a/corelib/ncbilcl.hp_pa +++ b/corelib/ncbilcl.hp_pa @@ -25,14 +25,17 @@ * * File Name: ncbilcl.h * -* $Revision: 6.2 $ +* $Revision: 6.1 $ * (this file has not been tested for accuracy) * * File Description: * system dependent header * HP-UX version * -* $Log: ncbilcl.hp,v $ +* $Log: ncbilcl.hp_pa,v $ +* Revision 6.1 2002/02/15 21:56:26 beloslyu +* HP-UX changes +* * Revision 6.2 2001/01/03 16:08:02 beloslyu * allow the work with largefiles * @@ -47,7 +50,7 @@ #define COMP_SYSV #define OS_UNIX -#define OS_UNIX_SYSV +#define OS_UNIX_HPUX #define PROC_HPPA #define WIN_DUMB @@ -63,9 +66,14 @@ /*----------------------------------------------------------------------*/ #define _INCLUDE_POSIX_SOURCE #define _INCLUDE_XOPEN_SOURCE +#define _XOPEN_SOURCE_EXTENDED +#define _INCLUDE_XOPEN_SOURCE_EXTENDED /* allow the fork with largefiles */ #define _FILE_OFFSET_BITS 64 + +#define POSIX_THREADS_AVAIL +#define _POSIX_C_SOURCE 199506L /*----------------------------------------------------------------------*/ /* #includes */ /*----------------------------------------------------------------------*/ @@ -84,10 +92,6 @@ #include <errno.h> #include <float.h> -#define POSIX_THREADS_AVAIL -#define _POSIX_C_SOURCE 199506L -#define _XOPEN_SOURCE_EXTENDED - /*----------------------------------------------------------------------*/ /* Missing ANSI-isms */ /*----------------------------------------------------------------------*/ @@ -96,9 +100,10 @@ #define SEEK_CUR 1 #define SEEK_END 2 #endif -#ifndef FILENAME_MAX -#define FILENAME_MAX 1024 +#ifdef FILENAME_MAX +#undef FILENAME_MAX #endif +#define FILENAME_MAX 1024 /*----------------------------------------------------------------------*/ /* Aliased Logicals, Datatypes */ diff --git a/corelib/ncbimem.c b/corelib/ncbimem.c index 703c21a6..9bbe86a7 100644 --- a/corelib/ncbimem.c +++ b/corelib/ncbimem.c @@ -29,7 +29,7 @@ * * Version Creation Date: 6/4/91 * -* $Revision: 6.17 $ +* $Revision: 6.18 $ * * File Description: * portable memory handlers for Mac, PC, Unix @@ -37,6 +37,9 @@ * Modifications: * -------------------------------------------------------------------------- * $Log: ncbimem.c,v $ +* Revision 6.18 2002/02/07 14:41:19 ivanov +* Added MemSearch() +* * Revision 6.17 2000/03/08 17:55:49 vakatov * Use Int8 for the file size. * Also, get rid of the WIN16 code, do other cleanup. @@ -268,7 +271,7 @@ static void* s_MemAllocator(void *ptr, size_t size, } if ( !size ) return Nlm_MemFree(ptr); - + x_ptr = Nlm_Realloc(ptr, size); break; } @@ -461,6 +464,33 @@ NLM_EXTERN void * LIBCALL Nlm_MemFill (void *buf, int value, size_t bytes) } +/***************************************************************************** +* +* void Nlm_MemSearch(Pointer where, where_size, Pointer what, what_size) +* search a position one block of data into another +* +*****************************************************************************/ + +NLM_EXTERN size_t LIBCALL Nlm_MemSearch(const void* where, size_t where_size, + const void* what, size_t what_size) +{ + size_t i, rbound, pos; + + rbound = where_size - what_size; + pos = -1; + i = 0; + if (where_size && what_size && where_size >= what_size) { + while ((i <= rbound) && (pos == -1)) { + if (memcmp((char*)where + i, what, what_size)==0) + pos = i; + else + i++; + } + } + return pos; +} + + #if defined(OS_MAC) || defined(OS_MSWIN) || defined(MSC_VIRT) /***** Handle functions are for Macintosh and Windows only *****/ /***** or Microsoft virtual memory manager ****/ @@ -734,12 +764,12 @@ void mac_Free (void *ptr) /***************************************************************************** * * Windows DLL-specific functions (shared memory) -* +* * dll_Malloc * dll_Calloc (not yet) * dll_Realloc (not yet) -* dll_Free -* +* dll_Free +* *****************************************************************************/ @@ -770,7 +800,7 @@ void dll_Free (void *pMem) /********************************************************************* -* Function to test whether memory-mapping is available. +* Function to test whether memory-mapping is available. * * returns TRUE if it is supported by NCBI routines. *********************************************************************/ @@ -808,7 +838,7 @@ NLM_EXTERN Nlm_MemMapPtr Nlm_MemMapInit(const Nlm_Char PNTR name) *str = '/'; /* name of a file-mapping object cannot contain '\' */ if ( !(mem_mapp->hMap = - OpenFileMapping(FILE_MAP_READ, FALSE, x_name)) ) + OpenFileMapping(FILE_MAP_READ, FALSE, x_name)) ) { /* If failed to attach to an existing file-mapping object then * create a new one(based on the specified file) */ HANDLE hFile= CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, diff --git a/corelib/ncbimem.h b/corelib/ncbimem.h index d13c8217..467faa3f 100644 --- a/corelib/ncbimem.h +++ b/corelib/ncbimem.h @@ -32,7 +32,7 @@ * * Version Creation Date: 1/1/91 * -* $Revision: 6.6 $ +* $Revision: 6.7 $ * * File Description: * prototypes for ncbi memory functions @@ -40,6 +40,9 @@ * Modifications: * -------------------------------------------------------------------------- * $Log: ncbimem.h,v $ +* Revision 6.7 2002/02/07 14:41:19 ivanov +* Added MemSearch() +* * Revision 6.6 2001/07/26 16:37:45 beloslyu * OS_UNIX_DARWIN can use mmap * @@ -101,15 +104,17 @@ extern "C" { #endif -NLM_EXTERN void* LIBCALL Nlm_MemNew(size_t size); -NLM_EXTERN void* LIBCALL Nlm_MemGet(size_t size, unsigned int flags); -NLM_EXTERN void* LIBCALL Nlm_MemMore(void* ptr, size_t size); -NLM_EXTERN void* LIBCALL Nlm_MemExtend(void* ptr, size_t size, size_t oldsize); -NLM_EXTERN void* LIBCALL Nlm_MemFree(void* ptr); -NLM_EXTERN void* LIBCALL Nlm_MemCopy(void* dst, const void* src, size_t bytes); -NLM_EXTERN void* LIBCALL Nlm_MemMove(void* dst, const void* src, size_t bytes); -NLM_EXTERN void* LIBCALL Nlm_MemFill(void* ptr, int value, size_t bytes); -NLM_EXTERN void* LIBCALL Nlm_MemDup(const void* orig, size_t size); +NLM_EXTERN void* LIBCALL Nlm_MemNew(size_t size); +NLM_EXTERN void* LIBCALL Nlm_MemGet(size_t size, unsigned int flags); +NLM_EXTERN void* LIBCALL Nlm_MemMore(void* ptr, size_t size); +NLM_EXTERN void* LIBCALL Nlm_MemExtend(void* ptr, size_t size, size_t oldsize); +NLM_EXTERN void* LIBCALL Nlm_MemFree(void* ptr); +NLM_EXTERN void* LIBCALL Nlm_MemCopy(void* dst, const void* src, size_t bytes); +NLM_EXTERN void* LIBCALL Nlm_MemMove(void* dst, const void* src, size_t bytes); +NLM_EXTERN void* LIBCALL Nlm_MemFill(void* ptr, int value, size_t bytes); +NLM_EXTERN void* LIBCALL Nlm_MemDup(const void* orig, size_t size); +NLM_EXTERN size_t LIBCALL Nlm_MemSearch(const void* where, size_t where_size, + const void* what, size_t what_size); #if defined(OS_MAC) || defined(OS_MSWIN) || defined(MSC_VIRT) NLM_EXTERN Nlm_Handle LIBCALL Nlm_HandNew(size_t size); @@ -133,7 +138,7 @@ NLM_EXTERN void mac_Free (void* ptr); /* [UNIX only] set the limit for the heap size and its increase policy for * NCBI memory allocation functions: - * MemGet, MemNew, MemMore, MemExtend + * MemGet, MemNew, MemMore, MemExtend * when the heap size reaches "curr", it ussues a warning, then it increases * "curr" by "add" bytes -- unless "curr" has already reached "max". * in the latter case, program ussues a FATAL_ERROR error message and @@ -191,6 +196,7 @@ NLM_EXTERN void* Nlm_CallocViaMalloc(size_t n_elem, size_t item_size); #define MemCpy Nlm_MemCpy #define MemChr Nlm_MemChr #define MemCmp Nlm_MemCmp +#define MemSearch Nlm_MemSearch /*** High-level NCBI functions ***/ diff --git a/corelib/ncbistr.c b/corelib/ncbistr.c index 598a6a94..4f15427e 100644 --- a/corelib/ncbistr.c +++ b/corelib/ncbistr.c @@ -29,7 +29,7 @@ * * Version Creation Date: 3/4/91 * -* $Revision: 6.10 $ +* $Revision: 6.11 $ * * File Description: * portable string routines @@ -37,6 +37,9 @@ * Modifications: * -------------------------------------------------------------------------- * $Log: ncbistr.c,v $ +* Revision 6.11 2002/01/16 16:58:38 camacho +* Changed type of buflen parameter in LabelCopy from Int2 to Uint4 +* * Revision 6.10 2001/01/05 22:43:58 shavirin * Added functions, that transfer Uint8 values to platform-independent * objects and back. @@ -874,9 +877,9 @@ NLM_EXTERN char* LIBCALL Nlm_Int8ToString (Nlm_Int8 value, char* str, size_t st * returns number of characters transferred to "to" * *****************************************************************************/ -NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopy (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen) +NLM_EXTERN Nlm_Uint4 LIBCALL Nlm_LabelCopy (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Uint4 buflen) { - Nlm_Int2 len; + Nlm_Uint4 len; if ((to == NULL) || (from == NULL) || (buflen < 0)) return 0; @@ -900,12 +903,12 @@ NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopy (Nlm_CharPtr to, Nlm_CharPtr from, Nlm } *to = '\0'; /* buffer is bufferlen+1 */ - return (Nlm_Int2)(len - buflen); + return (Nlm_Uint4)(len - buflen); } -NLM_EXTERN void LIBCALL Nlm_LabelCopyNext(Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Int2 PNTR buflen) +NLM_EXTERN void LIBCALL Nlm_LabelCopyNext(Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Uint4 PNTR buflen) { - Nlm_Int2 diff; + Nlm_Uint4 diff; diff = Nlm_LabelCopy(*to, from, *buflen); *buflen -= diff; *to += diff; @@ -927,9 +930,9 @@ NLM_EXTERN void LIBCALL Nlm_LabelCopyNext(Nlm_CharPtr PNTR to, Nlm_CharPtr from, * * *****************************************************************************/ -NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopyExtra (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix) +NLM_EXTERN Nlm_Uint4 LIBCALL Nlm_LabelCopyExtra (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Uint4 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix) { - Nlm_Int2 len, diff; + Nlm_Int4 len, diff; if ((to == NULL) || (buflen < 1) || (from == NULL)) return 0; @@ -943,7 +946,7 @@ NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopyExtra (Nlm_CharPtr to, Nlm_CharPtr from diff = Nlm_LabelCopy(to, suffix, buflen); buflen -= diff; - return (Nlm_Int2)(len-buflen); + return (Nlm_Int4)(len-buflen); } #define NEWLINE '\n' diff --git a/corelib/ncbistr.h b/corelib/ncbistr.h index 23eccbea..b859fa9d 100644 --- a/corelib/ncbistr.h +++ b/corelib/ncbistr.h @@ -29,7 +29,7 @@ * * Version Creation Date: 1/1/91 * -* $Revision: 6.6 $ +* $Revision: 6.7 $ * * File Description: * prototypes for portable string routines @@ -37,6 +37,9 @@ * Modifications: * -------------------------------------------------------------------------- * $Log: ncbistr.h,v $ +* Revision 6.7 2002/01/16 16:58:38 camacho +* Changed type of buflen parameter in LabelCopy from Int2 to Uint4 +* * Revision 6.6 2001/01/05 22:43:58 shavirin * Added functions, that transfer Uint8 values to platform-independent * objects and back. @@ -205,7 +208,7 @@ NLM_EXTERN char* LIBCALL Nlm_Uint8ToString(Nlm_Uint8 value, char* str, size_t st * returns number of characters transferred to "to" * *****************************************************************************/ -NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopy PROTO((Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen)); +NLM_EXTERN Nlm_Uint4 LIBCALL Nlm_LabelCopy PROTO((Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Uint4 buflen)); /***************************************************************************** * @@ -222,9 +225,9 @@ NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopy PROTO((Nlm_CharPtr to, Nlm_CharPtr fro * * *****************************************************************************/ -NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopyExtra PROTO((Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix)); +NLM_EXTERN Nlm_Uint4 LIBCALL Nlm_LabelCopyExtra PROTO((Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Uint4 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix)); -NLM_EXTERN void LIBCALL Nlm_LabelCopyNext PROTO((Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Int2 PNTR buflen)); +NLM_EXTERN void LIBCALL Nlm_LabelCopyNext PROTO((Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Uint4 PNTR buflen)); /* Some higher-level string manipulation functions */ NLM_EXTERN Nlm_CharPtr LIBCALL StrCpyPtr PROTO ((char FAR *Dest, char FAR *Start, char FAR *Stop)); diff --git a/corelib/ncbithr.c b/corelib/ncbithr.c index 54f41a0d..aeb221d6 100644 --- a/corelib/ncbithr.c +++ b/corelib/ncbithr.c @@ -1,4 +1,4 @@ -/* $Id: ncbithr.c,v 6.32 2001/12/14 21:09:20 ivanov Exp $ */ +/* $Id: ncbithr.c,v 6.33 2002/03/12 15:50:00 ivanov Exp $ */ /***************************************************************************** Name: ncbithr.c @@ -35,6 +35,10 @@ Modification History: ----------------------------------------------------------------------------- * $Log: ncbithr.c,v $ +* Revision 6.33 2002/03/12 15:50:00 ivanov +* Changed a name created mutex from "Nlm_InitLock32" to NULL +* in the NlmMutexInit() under WIN32 +* * Revision 6.32 2001/12/14 21:09:20 ivanov * Enable threads under WIN32 in MT-configurations * @@ -2036,7 +2040,7 @@ NLM_EXTERN TNlmMutex NlmMutexInit(TNlmMutexPtr theMutexPtr) #elif defined(WIN32_THREADS_AVAIL) {{ if (s_Init_mutex == NULL) { - HANDLE x_Init_mutex = CreateMutex(NULL, FALSE, "Nlm_InitLock32"); + HANDLE x_Init_mutex = CreateMutex(NULL, FALSE, NULL); if ( x_Init_mutex ) s_Init_mutex = x_Init_mutex; else diff --git a/corelib/ncbiwin.h b/corelib/ncbiwin.h index 6348e444..ae3f2395 100644 --- a/corelib/ncbiwin.h +++ b/corelib/ncbiwin.h @@ -29,7 +29,7 @@ * * Version Creation Date: 1/1/91 * -* $Revision: 6.3 $ +* $Revision: 6.5 $ * * File Description: * underlying window toolbox import @@ -37,6 +37,12 @@ * Modifications: * -------------------------------------------------------------------------- * $Log: ncbiwin.h,v $ +* Revision 6.5 2002/02/15 20:19:50 beloslyu +* bug fixed +* +* Revision 6.4 2002/02/15 19:53:28 beloslyu +* fix for HP-UX +* * Revision 6.3 1999/12/21 17:34:56 kans * Added ControlDefinitions.h to the Mac client portion to support universal headers version 3.3 (in preparation for Carbon compatibility) - churchill * @@ -197,13 +203,15 @@ #endif #endif -#ifdef WIN_X +#if defined(WIN_X) +#if !defined(OS_UNIX_HPUX) #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xos.h> #include <X11/Xresource.h> #include <X11/Intrinsic.h> #include <X11/StringDefs.h> +#endif #include <X11/cursorfont.h> #endif diff --git a/corelib/ncbiwww.h b/corelib/ncbiwww.h index adae5794..cd074056 100644 --- a/corelib/ncbiwww.h +++ b/corelib/ncbiwww.h @@ -1,25 +1,25 @@ -/* $Id: ncbiwww.h,v 6.5 2001/05/10 14:58:35 shavirin Exp $ +/* $Id: ncbiwww.h,v 6.7 2002/02/07 14:48:22 ivanov Exp $ * =========================================================================== * -* PUBLIC DOMAIN NOTICE +* PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information -* -* This software/database is a "United States Government Work" under the -* terms of the United States Copyright Act. It was written as part of -* the author's official duties as a United States Government employee and -* thus cannot be copyrighted. This software/database is freely available -* to the public for use. The National Library of Medicine and the U.S. -* Government have not placed any restriction on its use or reproduction. -* -* Although all reasonable efforts have been taken to ensure the accuracy -* and reliability of the software and data, the NLM and the U.S. -* Government do not and cannot warrant the performance or results that -* may be obtained by using this software or data. The NLM and the U.S. -* Government disclaim all warranties, express or implied, including +* +* This software/database is a "United States Government Work" under the +* terms of the United States Copyright Act. It was written as part of +* the author's official duties as a United States Government employee and +* thus cannot be copyrighted. This software/database is freely available +* to the public for use. The National Library of Medicine and the U.S. +* Government have not placed any restriction on its use or reproduction. +* +* Although all reasonable efforts have been taken to ensure the accuracy +* and reliability of the software and data, the NLM and the U.S. +* Government do not and cannot warrant the performance or results that +* may be obtained by using this software or data. The NLM and the U.S. +* Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular -* purpose. -* -* Please cite the author in any work or product based on this material. +* purpose. +* +* Please cite the author in any work or product based on this material. * * =========================================================================== * @@ -29,14 +29,22 @@ * * Version Creation Date: 11/03/1996 * -* $Revision: 6.5 $ +* $Revision: 6.7 $ * * File Description: -* This file contains main definitions to read and process HTTP +* This file contains main definitions to read and process HTTP * protocols input for WWW CGI programs * Currently it works for all ncbi supported platforms. * * $Log: ncbiwww.h,v $ +* Revision 6.7 2002/02/07 14:48:22 ivanov +* Added WWWGetEntriesEx(), WWWGetEntriesFormDataEx(), WWWReadFileInMemoryEx(), +* WWWGetValueSizeByIndex() -- support binary files in the multipart form-data. +* +* Revision 6.6 2002/01/28 21:27:00 ivanov +* Added WWWGetArgsEx() and WWWGetArgsAttr_...() functions. +* Added structure SWWWGetArgsAttr definition. +* * Revision 6.5 2001/05/10 14:58:35 shavirin * Fixed typo. * @@ -58,31 +66,30 @@ * Move "ncbiwww.h" and "wwwutils.c" from /network/www2(ncbiwww2.lib) * to /corelib(ncbi.lib) * -oRevision 1.7 1997/04/04 21:26:32 savchuk -oWWWInfoPtr definition has been changed. -oWWWInfoNew() prototype has been removed -o -oRevision 1.6 1997/02/26 15:20:50 shavirin -oAdded definition of function WWWGetDocRoot() -o - * Revision 1.5 1996/12/18 17:44:48 shavirin - * Added support for CC++ compiler usage. - * - * Revision 1.4 1996/12/13 22:53:18 shavirin - * Added definitions to new functions. - * .. - * - * Revision 1.3 1996/12/12 19:24:35 shavirin - * Changed definitions of WWWReadPosting() and entered new function - * WWWGetArgs(). Added WWWErrorCode definitions. - * - * Revision 1.2 1996/12/11 18:13:31 shavirin - * Main WWWInfoPtr changed to Void Pointer to hide real structure, - * that called now WWWInfoDataPtr - * - * Revision 1.1 1996/12/03 22:47:18 shavirin - * Initial revision - * +* Revision 1.7 1997/04/04 21:26:32 savchuk +* WWWInfoPtr definition has been changed. +* WWWInfoNew() prototype has been removed +* +* Revision 1.6 1997/02/26 15:20:50 shavirin +* Added definition of function WWWGetDocRoot() +* +* Revision 1.5 1996/12/18 17:44:48 shavirin +* Added support for CC++ compiler usage. +* +* Revision 1.4 1996/12/13 22:53:18 shavirin +* Added definitions to new functions. +* .. +* +* Revision 1.3 1996/12/12 19:24:35 shavirin +* Changed definitions of WWWReadPosting() and entered new function +* WWWGetArgs(). Added WWWErrorCode definitions. +* +* Revision 1.2 1996/12/11 18:13:31 shavirin +* Main WWWInfoPtr changed to Void Pointer to hide real structure, +* that called now WWWInfoDataPtr +* +* Revision 1.1 1996/12/03 22:47:18 shavirin +* Initial revision * * ========================================================================== */ @@ -107,20 +114,20 @@ o /****************************************************************************/ #define MAX_WWW_ENTRIES 4096 /* maximum number of html tags in input */ -#define WWW_MAX_NAME_LEN 512 /* Limit for Name in HTML tag */ +#define WWW_MAX_NAME_LEN 512 /* Limit for Name in HTML tag */ -#define MISC_BROWSER 0 /* Any Browser Netscape Ver. 1 included */ -#define NETSCAPE 1 /* Netscape Ver. 2 and higher */ -#define EXPLORER 2 /* Microsoft Internet Explorer. Any Version */ +#define MISC_BROWSER 0 /* Any Browser Netscape Ver. 1 included */ +#define NETSCAPE 1 /* Netscape Ver. 2 and higher */ +#define EXPLORER 2 /* Microsoft Internet Explorer. Any Version */ -#define COMMAND_LINE 0 /* program used from command line */ -#define WWW_GET 1 /* method with ?name=value&name=value&.. form */ -#define WWW_POST 2 /* input through stdin in ?..=..&..=.. form */ -#define FORM_DATA 3 /* RFC 1867 multipart/form-data */ +#define COMMAND_LINE 0 /* program used from command line */ +#define WWW_GET 1 /* method with ?name=value&name=value&.. form */ +#define WWW_POST 2 /* input through stdin in ?..=..&..=.. form */ +#define FORM_DATA 3 /* RFC 1867 multipart/form-data */ -#define LIVE_SERVER_PORT 80 /* default HTTPD live port */ +#define LIVE_SERVER_PORT 80 /* default HTTPD live port */ -#define INIT_BUFF_SIZE 4028 /* temporary buffer to read from file/stdin */ +#define INIT_BUFF_SIZE 4028 /* temporary buffer to read from file/stdin */ /****************************************************************************/ /* TYPEDEFS */ @@ -129,25 +136,27 @@ o typedef struct WWWEntry { CharPtr name; /* HTML tag NAME=.. */ CharPtr val; /* HTML tag VALUE=.. */ + Int4 size; /* Size of data in "val" */ } WWWEntry, PNTR WWWEntryPtr; /* typedef VoidPtr WWWInfo; */ typedef VoidPtr WWWInfoPtr; typedef struct WWWInfoData { - Int4 method; /* GET, POST or COMMAND_LINE */ - Int4 port; /* Server port - current server */ - CharPtr server_name; /* Server name - current server */ - CharPtr doc_root; /* Document directory of current server */ - CharPtr script_name; /* Script name - CGI program */ - CharPtr host; /* remote host of client */ - CharPtr address; /* remote address of client - may be proxy */ - CharPtr proxied_ip; /* 'real' remote address of client as set by proxy */ - CharPtr agent; /* Label of remote client */ - CharPtr query; /* Complete input buffer */ - Int4 browser; /* Value derived from Label */ - WWWEntryPtr PNTR entries; /* Parced input data */ - Int4 num_entries; /* Number of HTML tags */ + Int4 method; /* GET, POST or COMMAND_LINE */ + Int4 port; /* Server port - current server */ + CharPtr server_name; /* Server name - current server */ + CharPtr doc_root; /* Document directory of current server */ + CharPtr script_name; /* Script name - CGI program */ + CharPtr host; /* remote host of client */ + CharPtr address; /* remote address of client - may be proxy */ + CharPtr proxied_ip; /* 'real' remote addr of client as set by proxy */ + CharPtr agent; /* Label of remote client */ + CharPtr query; /* Complete input buffer */ + Int4 query_len; /* Length of data in input buffer */ + Int4 browser; /* Value derived from Label */ + WWWEntryPtr PNTR entries; /* Parced input data */ + Int4 num_entries; /* Number of HTML tags */ } WWWInfoData, PNTR WWWInfoDataPtr; typedef enum { @@ -157,6 +166,9 @@ typedef enum { } WWWErrorCode; +struct SWWWGetArgs_tag; +typedef struct SWWWGetArgsAttr_tag PNTR SWWWGetArgsAttr; + /****************************************************************************/ /* FINCTION DEFINITIONS */ /****************************************************************************/ @@ -171,40 +183,51 @@ extern "C" { pairs in the form of WWWEntry -es. Parameters: num_entries - number of paires returned WWWBuffer - main input HTTP buffer - NetscapeOK - if TRUE check for RFC 1867 will - be performed before standard processing + NetscapeOK - if TRUE check for RFC 1867 will + be performed before standard processing (Not used now) + WWWBuffer_len - length of data in the WWWBuffer Returns: Pointer to array of WWWEntry pairs - NOTE: RFC 1867 may be enabled only with Netscape Version 2 and + NOTE: RFC 1867 may be enabled only with Netscape Version 2 and higher. ------------------------------------------------------------------*/ NLM_EXTERN WWWEntryPtr PNTR WWWGetEntries(Int4Ptr num_entries, - CharPtr WWWBuffer, + CharPtr WWWBuffer, Boolean NetscapeOK); +NLM_EXTERN WWWEntryPtr PNTR WWWGetEntriesEx(Int4Ptr num_entries, + CharPtr WWWBuffer, + Int4 WWWBuffer_len); + + /* -------------------- WWWGetEntriesFomData ----------------------- Purpose: Assuming, that input buffer is in RFC 1867 - ftp://ds.internic.net/rfc/rfc1867.txt - (multipart/form-data) encoding this function - converts input into array of name, value pairs + ftp://ds.internic.net/rfc/rfc1867.txt + (multipart/form-data) encoding this function + converts input into array of name, value pairs in the form of WWWEntry -es. Parameters: WWWBuffer - main input HTTP buffer entries - pointer to array of WWWEntry -es Returns: Number of WWW entries returned - NOTE: RFC 1867 may be enabled only with Netscape Version 2 and + NOTE: RFC 1867 may be enabled only with Netscape Version 2 and higher. ------------------------------------------------------------------*/ -NLM_EXTERN Int4 WWWGetEntriesFormData(WWWEntryPtr PNTR entries, +NLM_EXTERN Int4 WWWGetEntriesFormData(WWWEntryPtr PNTR entries, CharPtr WWWBuffer); +NLM_EXTERN Int4 WWWGetEntriesFormDataEx(WWWEntryPtr PNTR entries, + CharPtr WWWBuffer, + Int4 WWWBuffer_len); + + /* ----------------------- WWWGetArgs --------------------------- Purpose: This function read HTML input in POST, GET or multipart/form-data encoding - depends upon environment. If used from command-line this function will return valid WWWInfo structure with all field blank exept info->method, that - will be set to COMMAND_LINE. - If argc == 1 this function will read WWW buffer + will be set to COMMAND_LINE. + If argc == 1 this function will read WWW buffer from STDIN, otherwise it will treat argv[1] as WWW buffer. Parameters: None @@ -217,6 +240,35 @@ NLM_EXTERN Int4 WWWGetEntriesFormData(WWWEntryPtr PNTR entries, NLM_EXTERN WWWErrorCode WWWGetArgs(WWWInfoPtr PNTR info); +/* ----------------------- WWWGetArgsEx --------------------------- + Purpose: Identical to previous function, but it have additional + parameter with working attributes + Parameters: attr - function's working attributes + Returns: WWWInfoPtr structure with processed HTTP input and + environment + + ------------------------------------------------------------------*/ + + +NLM_EXTERN WWWErrorCode WWWGetArgsEx(WWWInfoPtr PNTR info, + SWWWGetArgsAttr attr); + +/* ----------------------- WWWGetArgsAttr... ----------------------- + Purpose: This functions create, destroy and set parameter's + values to SWWWGetArgsAttr structure. + NOTE: Created structure use into WWWGetArgsEx() + ------------------------------------------------------------------*/ + +NLM_EXTERN SWWWGetArgsAttr WWWGetArgsAttr_Create(void); + +NLM_EXTERN void WWWGetArgsAttr_Destroy(SWWWGetArgsAttr attr); + +NLM_EXTERN Boolean WWWGetArgsAttr_SetFilter(SWWWGetArgsAttr attr, + Boolean filter_non_print); +NLM_EXTERN Boolean WWWGetArgsAttr_SetReadArgv(SWWWGetArgsAttr attr, + Boolean read_argv); + + /* ---------------------- WWWReadPosting ------------------------- Purpose: This function read HTML input in POST, GET or multipart/form-data encoding - depends upon @@ -224,7 +276,7 @@ NLM_EXTERN WWWErrorCode WWWGetArgs(WWWInfoPtr PNTR info); function will return valid WWWInfo structure with all field blank exept info->method, that will be set to COMMAND_LINE - No more proccesing will be performed. + No more proccesing will be performed. Parameters: None Returns: WWWInfoPtr structure with processed HTTP input and environment @@ -236,10 +288,10 @@ NLM_EXTERN WWWErrorCode WWWReadPosting(WWWInfoPtr PNTR info); /* ------------------- WWWReadFileInMemory ----------------------- - Purpose: Function reads data from file or stdin into + Purpose: Function reads data from file or stdin into string buffer (terminated by NULLB). - Parameters: fd - opened file + Parameters: fd - opened file len - number of bytes to read. If this value set to 0 file will be read until EOF or closing external connection (for sockets). @@ -247,6 +299,7 @@ NLM_EXTERN WWWErrorCode WWWReadPosting(WWWInfoPtr PNTR info); be read from input streem filter - if TRUE filtering of non-printed characters will be performed + rsize - return size of read data Returns: Pointer to allocated buffer. NOTE: Please be carefull with "len": function read input absolutely differently if len == 0 or len != 0 @@ -254,6 +307,9 @@ NLM_EXTERN WWWErrorCode WWWReadPosting(WWWInfoPtr PNTR info); ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWReadFileInMemory(FILE *fd, Int4 len, Boolean filter); +NLM_EXTERN CharPtr WWWReadFileInMemoryEx(FILE *fd, Int4 len, Boolean filter, + Int4Ptr rsize); + /* ---------------------- WWWInfoFree ------------------------- Purpose: Free WWWInfo structure @@ -266,7 +322,7 @@ NLM_EXTERN void WWWInfoFree(WWWInfoPtr info); /* ---------------------- WWWGetWWWEntry ------------------------- Purpose: Return pointer to array of name=value tags Parameters: WWWInfoPtr - Returns: Method used or -1 if error + Returns: Method used or -1 if error ------------------------------------------------------------------*/ NLM_EXTERN WWWEntryPtr PNTR WWWGetWWWEntries(WWWInfoPtr info); @@ -274,14 +330,15 @@ NLM_EXTERN WWWEntryPtr PNTR WWWGetWWWEntries(WWWInfoPtr info); /* ---------------------- WWWGetMethod ------------------------- Purpose: Return method used in WWW Request or COMMAND_LINE Parameters: WWWInfoPtr - Returns: Method used or -1 if error + Returns: Method used or -1 if error ------------------------------------------------------------------*/ NLM_EXTERN Int4 WWWGetMethod(WWWInfoPtr info); + /* ---------------------- WWWGetBrowser ------------------------- Purpose: Return browser used in WWW Request Parameters: WWWInfoPtr - Returns: Browser used or -1 if error + Returns: Browser used or -1 if error ------------------------------------------------------------------*/ NLM_EXTERN Int4 WWWGetBrowser(WWWInfoPtr info); @@ -295,65 +352,66 @@ NLM_EXTERN Int4 WWWGetNumEntries(WWWInfoPtr info); /* ---------------------- WWWGetAgent ------------------------- - Purpose: Return agent used in WWW Request + Purpose: Return agent used in WWW Request Parameters: WWWInfoPtr - Returns: Agent used or NULL if error + Returns: Agent used or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetAgent(WWWInfoPtr info); /* ---------------------- WWWGetAddress ------------------------- - Purpose: Return address used in WWW Request + Purpose: Return address used in WWW Request Parameters: WWWInfoPtr - Returns: Address used or NULL if error + Returns: Address used or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetAddress(WWWInfoPtr info); /* ---------------------- WWWGetDocRoot ------------------------- - Purpose: Return DOCUMENT_ROOT directory of current server + Purpose: Return DOCUMENT_ROOT directory of current server Parameters: WWWInfoPtr - Returns: Document root directory or NULL if error + Returns: Document root directory or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetDocRoot(WWWInfoPtr info_in); /* ---------------------- WWWGetProxedIP ------------------------- Purpose: Return 'real' client address as set by proxy server Parameters: WWWInfoPtr - Returns: Host used or NULL if error + Returns: Host used or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetProxiedIP(WWWInfoPtr info_in); /* ---------------------- WWWGetHost ------------------------- - Purpose: Return host used in WWW Request + Purpose: Return host used in WWW Request Parameters: WWWInfoPtr - Returns: Host used or NULL if error + Returns: Host used or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetHost(WWWInfoPtr info); /* ---------------------- WWWGetServer ------------------------- - Purpose: Return HTTPD server name used in WWW Request + Purpose: Return HTTPD server name used in WWW Request Parameters: WWWInfoPtr - Returns: Server name used or NULL if error + Returns: Server name used or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetServer(WWWInfoPtr info_in); /* ---------------------- WWWGetQuery ------------------------- - Purpose: Return full query used in WWW Request - + Purpose: Return full query used in WWW Request + Parameters: WWWInfoPtr - - Returns: Query used or NULL if error + + Returns: Query used or NULL if error ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetQuery(WWWInfoPtr info); + /* ---------------------- WWWGetPort ------------------------- Purpose: Return port used in WWW Request Parameters: WWWInfoPtr - Returns: Port used or -1 if error + Returns: Port used or -1 if error ------------------------------------------------------------------*/ NLM_EXTERN Int4 WWWGetPort(WWWInfoPtr info); @@ -369,24 +427,26 @@ NLM_EXTERN Int4 WWWGetPort(WWWInfoPtr info); /* ---------------------- WWWFindName ------------------------- Purpose: This function look for Name in WWW Entries structure Parameters: info - WWWInfo structure - find - Name to find - Returns: index in WWWEntry structue if "find" found and -1 if not + find - Name to find + Returns: index in WWWEntry structue if "find" found and -1 if not ------------------------------------------------------------------*/ NLM_EXTERN Int4 WWWFindName(WWWInfoPtr info, CharPtr find); + /* ---------------------- WWWFindName ------------------------- Purpose: This function look for Name in WWW Entries structure starting from specifix index value Parameters: info - WWWInfo structure find - Name to find index - index value to start with - Returns: index in WWWEntry structue if "find" found and -1 if not + Returns: index in WWWEntry structue if "find" found and -1 if not ------------------------------------------------------------------*/ NLM_EXTERN Int4 WWWFindNameEx(WWWInfoPtr info_in, CharPtr find, Int4 index); + /* ---------------------- WWWGetNameByIndex ---------------------- Purpose: This function get Name correspondig to specific - index. + index. Parameters: info - WWWInfo structure index - Index in WWW Entries structure Returns: Pointer to Name or NULL if index invalid @@ -396,7 +456,7 @@ NLM_EXTERN CharPtr WWWGetNameByIndex(WWWInfoPtr info, Int4 index); /* ------------------- WWWGetValueByIndex --------------------- Purpose: This function get Value correspondig to specific - index. + index. Parameters: info - WWWInfo structure index - Index in WWW Entries structure Returns: Pointer to Value or NULL if index invalid @@ -404,26 +464,38 @@ NLM_EXTERN CharPtr WWWGetNameByIndex(WWWInfoPtr info, Int4 index); NLM_EXTERN CharPtr WWWGetValueByIndex(WWWInfoPtr info, Int4 index); +/* ------------------- WWWGetValueSizeByIndex --------------------- + Purpose: This function get size of Value correspondig to + specific index. + Parameters: info - WWWInfo structure + index - Index in WWW Entries structure + Returns: Number of bytes stored into the Value + ------------------------------------------------------------------*/ +NLM_EXTERN Int4 WWWGetValueSizeByIndex(WWWInfoPtr info, Int4 index); + + /* ------------------- WWWGetValueByName --------------------- Purpose: This function get Value correspondig to specific - Name. + Name. Parameters: info - WWWInfo structure name - name to look for start - Index in WWW Entries structure to start from - Returns: Pointer to Value or NULL if Name was not found + Returns: Pointer to Value or NULL if Name was not found ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetValueByName(WWWInfoPtr info, CharPtr name); + /* ------------------- WWWGetValueByName --------------------- Purpose: This function get LAST Value correspondig to specific Name if there are more then one. Parameters: info - WWWInfo structure name - name to look for start - Index in WWW Entries structure to start from - Returns: Pointer to Value or NULL if Name was not found + Returns: Pointer to Value or NULL if Name was not found ------------------------------------------------------------------*/ NLM_EXTERN CharPtr WWWGetLastValueByName(WWWInfoPtr info_in, CharPtr find); + /* ------------------- WWWSubstituteValue --------------------- Purpose: This function substitute "old" value by "new" value in WWWInfo structure. @@ -435,6 +507,7 @@ NLM_EXTERN CharPtr WWWGetLastValueByName(WWWInfoPtr info_in, CharPtr find); NLM_EXTERN Boolean WWWSubstituteValue(WWWInfoPtr info_in, CharPtr old, CharPtr new_value); + /* ------------------- WWWSubstituteValueByName ------------------- Purpose: This function substitute value corresponding to "name" by "new" value in WWWInfo structure. diff --git a/corelib/tsprintf.c b/corelib/tsprintf.c index 4200a9a5..77bfee49 100644 --- a/corelib/tsprintf.c +++ b/corelib/tsprintf.c @@ -29,7 +29,7 @@ * * Version Creation Date: 07/10/96 * -* $Revision: 6.8 $ +* $Revision: 6.9 $ * * File Description: * Memory- and MT-safe "sprintf()" @@ -37,50 +37,53 @@ * Modifications: * -------------------------------------------------------------------------- * - * $Log: tsprintf.c,v $ - * Revision 6.8 2001/04/17 13:49:55 beloslyu - * changes for Linux PPC, contributed by Gary Bader <gary.bader@utoronto.ca> - * - * Revision 6.7 2001/03/23 14:04:14 beloslyu - * fix the name of strnlen to my_strnlen. It appears IBM's AIX has it's own function with this name - * - * Revision 6.6 2000/12/28 21:25:14 vakatov - * Comment fixed - * - * Revision 6.5 2000/12/28 21:16:44 vakatov - * va_args(): use "int" to fetch a "short int" argument - * - * Revision 6.4 2000/07/19 20:54:48 vakatov - * minor cleanup - * - * Revision 6.3 1998/01/28 15:57:24 vakatov - * Nlm_TSPrintfArgs(): always ignore the "vsprintf()"'s return value; - * count the resultant string length using StrLen - * - * Revision 6.2 1997/12/04 22:05:35 vakatov - * Check for NULL string arg; cut the output instead of crashing the program - * - * Revision 6.1 1997/11/26 21:26:33 vakatov - * Fixed errors and warnings issued by C and C++ (GNU and Sun) compilers - * - * Revision 6.0 1997/08/25 18:17:40 madden - * Revision changed to 6.0 - * - * Revision 1.5 1997/07/15 16:51:48 vakatov - * vsprintf_count_args() -- allow "fmt" be NULL(just return 0, don't crash) - * - * Revision 1.4 1996/12/03 21:48:33 vakatov - * Adopted for 32-bit MS-Windows DLLs - * - * Revision 1.3 1996/07/23 16:23:20 epstein - * fix for non-SYSV UNIX systems (e.g., SunOS 4) - * - * Revision 1.2 1996/07/22 15:27:31 vakatov - * Fixed "%c"-formatting bug - * - * Revision 1.1 1996/07/16 20:02:06 vakatov - * Initial revision - * +* $Log: tsprintf.c,v $ +* Revision 6.9 2002/03/11 16:55:43 ivanov +* Fixed fp_count() -- error with round-up numbers +* +* Revision 6.8 2001/04/17 13:49:55 beloslyu +* changes for Linux PPC, contributed by Gary Bader <gary.bader@utoronto.ca> +* +* Revision 6.7 2001/03/23 14:04:14 beloslyu +* fix the name of strnlen to my_strnlen. It appears IBM's AIX has it's own +* function with this name +* +* Revision 6.6 2000/12/28 21:25:14 vakatov +* Comment fixed +* +* Revision 6.5 2000/12/28 21:16:44 vakatov +* va_args(): use "int" to fetch a "short int" argument +* +* Revision 6.4 2000/07/19 20:54:48 vakatov +* minor cleanup +* +* Revision 6.3 1998/01/28 15:57:24 vakatov +* Nlm_TSPrintfArgs(): always ignore the "vsprintf()"'s return value; +* count the resultant string length using StrLen +* +* Revision 6.2 1997/12/04 22:05:35 vakatov +* Check for NULL string arg; cut the output instead of crashing the program +* +* Revision 6.1 1997/11/26 21:26:33 vakatov +* Fixed errors and warnings issued by C and C++ (GNU and Sun) compilers +* +* Revision 6.0 1997/08/25 18:17:40 madden +* Revision changed to 6.0 +* +* Revision 1.5 1997/07/15 16:51:48 vakatov +* vsprintf_count_args() -- allow "fmt" be NULL(just return 0, don't crash) +* +* Revision 1.4 1996/12/03 21:48:33 vakatov +* Adopted for 32-bit MS-Windows DLLs +* +* Revision 1.3 1996/07/23 16:23:20 epstein +* fix for non-SYSV UNIX systems (e.g., SunOS 4) +* +* Revision 1.2 1996/07/22 15:27:31 vakatov +* Fixed "%c"-formatting bug +* +* Revision 1.1 1996/07/16 20:02:06 vakatov +* Initial revision * * ========================================================================== */ @@ -156,13 +159,13 @@ static int fp_count(double fp, char type, int size, int precision, int flags) counter = 1 + 1 + precision + 5; break; case 'f': - counter = (power10 > 0.0 ? (int)power10 : 0) + 1 + 1 + precision; + counter = (power10 > 0.0 ? (int)power10 + 1 : 0) + 1 + 1 + precision; break; case 'g': { int e_count = 1 + precision + 5; int f_count = 1 + precision + - ((power10 < 0.0) ? (int)(-power10) + 1 : 0); + ((power10 < 0.0) ? (int)(-power10) + 2 : 0); counter = (f_count < e_count) ? f_count : e_count; break; } @@ -174,8 +177,7 @@ static int fp_count(double fp, char type, int size, int precision, int flags) if (precision == 0) counter--; - if ((counter >= size) && - (((fp > 0) && (flags & (PLUS|SPACE))) || (fp < 0))) + if (((fp > 0) && (flags & (PLUS|SPACE))) || (fp < 0)) counter++; return ((counter > size) ? counter : size); diff --git a/corelib/wwwutils.c b/corelib/wwwutils.c index 1544c930..4de54625 100644 --- a/corelib/wwwutils.c +++ b/corelib/wwwutils.c @@ -1,4 +1,4 @@ -/* $Id: wwwutils.c,v 6.12 2001/05/10 14:58:34 shavirin Exp $ +/* $Id: wwwutils.c,v 6.17 2002/02/07 14:48:22 ivanov Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE @@ -29,7 +29,7 @@ * * Version Creation Date: 11/03/1996 * -* $Revision: 6.12 $ +* $Revision: 6.17 $ * * File Description: * This file contains functions to read and process HTTP @@ -38,6 +38,23 @@ * *--------------------------------------------------------------------------- * $Log: wwwutils.c,v $ +* Revision 6.17 2002/02/07 14:48:22 ivanov +* Added WWWGetEntriesEx(), WWWGetEntriesFormDataEx(), WWWReadFileInMemoryEx(), +* WWWGetValueSizeByIndex() -- support binary files in the multipart form-data. +* +* Revision 6.16 2002/02/01 18:05:42 ivanov +* Little changes in WWWGetArgsInternal() +* +* Revision 6.15 2002/01/29 20:22:24 ivanov +* Added missed realization WWWGetArgsEx() +* +* Revision 6.14 2002/01/29 15:28:48 ivanov +* Typo fixed +* +* Revision 6.13 2002/01/28 21:27:00 ivanov +* Added WWWGetArgsEx() and WWWGetArgsAttr_...() functions. +* Added structure SWWWGetArgsAttr definition. +* * Revision 6.12 2001/05/10 14:58:34 shavirin * Fixed typo. * @@ -129,6 +146,23 @@ #include <ncbiwww.h> +#ifdef WIN32 /* for setmode() */ +# include <fcntl.h> +# include <io.h> +#endif + + +/****************************************************************************/ +/* INTERNAL STRUCTURES DEFINITIONS */ +/****************************************************************************/ + +typedef struct SWWWGetArgsAttr_tag +{ + Boolean filter_non_print; /* filtering non-printable characters */ + Boolean read_argv; /* read arguments from command line */ +} SWWWGetArgsAttrData; + + /****************************************************************************/ /* STATIC FINCTION DEFINITIONS */ /****************************************************************************/ @@ -138,39 +172,39 @@ static void PlusToSpace(CharPtr str); static void WWWUnescapeUrl(CharPtr url); static Char WWWx2c(CharPtr what); static Boolean WWWReadEnvironment(WWWInfoDataPtr info); -static WWWErrorCode WWWGetArgsInternal(WWWInfoPtr PNTR info, Boolean ReadArgv); +static WWWErrorCode WWWGetArgsInternal(WWWInfoPtr PNTR info, + SWWWGetArgsAttr attr); static WWWInfoPtr WWWInfoNew(void); - /****************************************************************************/ /* EXTERNAL FINCTION */ /****************************************************************************/ NLM_EXTERN void WWWInfoFree(WWWInfoPtr info_in) { - WWWInfoDataPtr info = (WWWInfoDataPtr)info_in; - - if( !info ) - return; - - info->server_name = (CharPtr) MemFree(info->server_name); - info->script_name = (CharPtr) MemFree(info->script_name); - info->host = (CharPtr) MemFree(info->host); - info->address = (CharPtr) MemFree(info->address); - info->proxied_ip = (CharPtr) MemFree(info->proxied_ip); - info->agent = (CharPtr) MemFree(info->agent); - info->doc_root = (CharPtr) MemFree(info->doc_root); - info->query = (CharPtr) MemFree(info->query); - if ( info->entries ) { - Int4 i; - for (i=0; i <= info->num_entries; i++) { - info->entries[i]->name = (CharPtr) MemFree(info->entries[i]->name); - info->entries[i]->val = (CharPtr) MemFree(info->entries[i]->val); - info->entries[i] = (WWWEntryPtr) MemFree(info->entries[i]); + WWWInfoDataPtr info = (WWWInfoDataPtr)info_in; + + if( !info ) + return; + + info->server_name = (CharPtr) MemFree(info->server_name); + info->script_name = (CharPtr) MemFree(info->script_name); + info->host = (CharPtr) MemFree(info->host); + info->address = (CharPtr) MemFree(info->address); + info->proxied_ip = (CharPtr) MemFree(info->proxied_ip); + info->agent = (CharPtr) MemFree(info->agent); + info->doc_root = (CharPtr) MemFree(info->doc_root); + info->query = (CharPtr) MemFree(info->query); + if ( info->entries ) { + Int4 i; + for (i=0; i <= info->num_entries; i++) { + info->entries[i]->name = (CharPtr) MemFree(info->entries[i]->name); + info->entries[i]->val = (CharPtr) MemFree(info->entries[i]->val); + info->entries[i] = (WWWEntryPtr) MemFree(info->entries[i]); + } + info->entries = (WWWEntryPtr PNTR) MemFree(info->entries); } - info->entries = (WWWEntryPtr PNTR) MemFree(info->entries); - } - info = (WWWInfoDataPtr) MemFree(info); + info = (WWWInfoDataPtr) MemFree(info); } @@ -179,502 +213,752 @@ NLM_EXTERN void WWWInfoFree(WWWInfoPtr info_in) Parameters: None Returns: WWWInfo structure ------------------------------------------------------------------*/ + static WWWInfoPtr WWWInfoNew(void) { - return (WWWInfoPtr) MemNew(sizeof(WWWInfoData)); + return (WWWInfoPtr) MemNew(sizeof(WWWInfoData)); } NLM_EXTERN WWWEntryPtr PNTR WWWGetWWWEntries(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; - - return(info->entries); + WWWInfoDataPtr info; + + if((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; + + return(info->entries); } + NLM_EXTERN Int4 WWWGetMethod(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return -1; - - return(info->method); + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return -1; + + return info->method; } + NLM_EXTERN Int4 WWWGetBrowser(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return -1; + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return -1; - return(info->browser); + return info->browser; } + NLM_EXTERN Int4 WWWGetNumEntries(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return -1; + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return -1; - return(info->num_entries); + return info->num_entries; } + NLM_EXTERN CharPtr WWWGetAgent(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; - return(info->agent); + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; + + return info->agent; } + NLM_EXTERN CharPtr WWWGetAddress(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; - return(info->address); + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; + + return info->address; } + NLM_EXTERN CharPtr WWWGetServer(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; - return(info->server_name); + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; + + return info->server_name; } + NLM_EXTERN CharPtr WWWGetDocRoot(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; - return(info->doc_root); + return info->doc_root; } + NLM_EXTERN CharPtr WWWGetHost(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; - return(info->host); + return info->host; } + NLM_EXTERN CharPtr WWWGetProxiedIP(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; - return(info->proxied_ip); + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; + + return info->proxied_ip; } + NLM_EXTERN CharPtr WWWGetQuery(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return NULL; + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return NULL; - return(info->query); + return info->query; } + NLM_EXTERN Int4 WWWGetPort(WWWInfoPtr info_in) { - WWWInfoDataPtr info; - - if((info = (WWWInfoDataPtr) info_in) == NULL) - return -1; - - return(info->port); + WWWInfoDataPtr info; + + if ((info = (WWWInfoDataPtr) info_in) == NULL) + return -1; + + return info->port; } + NLM_EXTERN WWWErrorCode WWWReadPosting(WWWInfoPtr PNTR info) { - return WWWGetArgsInternal(info, FALSE); + WWWErrorCode result; + SWWWGetArgsAttr attr = WWWGetArgsAttr_Create(); + if (attr == NULL) { + return WWWErrNoMem; + } + WWWGetArgsAttr_SetReadArgv(attr, FALSE); + result = WWWGetArgsInternal(info, attr); + WWWGetArgsAttr_Destroy(attr); + return result; } + NLM_EXTERN WWWErrorCode WWWGetArgs(WWWInfoPtr PNTR info) { - return WWWGetArgsInternal(info, TRUE); + WWWErrorCode result; + SWWWGetArgsAttr attr = WWWGetArgsAttr_Create(); + if (attr == NULL) { + return WWWErrNoMem; + } + WWWGetArgsAttr_SetReadArgv(attr, TRUE); + result = WWWGetArgsInternal(info, attr); + WWWGetArgsAttr_Destroy(attr); + return result; +} + + +NLM_EXTERN WWWErrorCode WWWGetArgsEx(WWWInfoPtr PNTR info, + SWWWGetArgsAttr attr) +{ + return WWWGetArgsInternal(info, attr); } + + NLM_EXTERN Boolean WWWSubstituteValue(WWWInfoPtr info_in, CharPtr old, CharPtr new_value) { Int4 i; WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; - - if(info_in == NULL || old == NULL) + + if (info_in == NULL || old == NULL) return FALSE; - - for(i = 0; i < info->num_entries; i++) { + + for (i = 0; i < info->num_entries; i++) { if (!StringICmp(info->entries[i]->val, old)) { MemFree(info->entries[i]->val); info->entries[i]->val = StringSave(new_value); + info->entries[i]->size = StringLen(info->entries[i]->val); return TRUE; } } return FALSE; } + NLM_EXTERN Boolean WWWSubstituteValueByName(WWWInfoPtr info_in, CharPtr new_value, CharPtr name) { Int4 i; WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; - - if(info_in == NULL || name == NULL) + + if (info_in == NULL || name == NULL) return FALSE; - - for(i = 0; i < info->num_entries; i++) { + + for (i = 0; i < info->num_entries; i++) { if (!StringICmp(info->entries[i]->name, name)) { MemFree(info->entries[i]->val); info->entries[i]->val = StringSave(new_value); + info->entries[i]->size = StringLen(info->entries[i]->val); return TRUE; } } return FALSE; } -static WWWErrorCode WWWGetArgsInternal(WWWInfoPtr PNTR info_out, - Boolean ReadArgv) + +static WWWErrorCode WWWGetArgsInternal(WWWInfoPtr PNTR info_out, + SWWWGetArgsAttr attr) { - Int4 WWWLen; - WWWInfoDataPtr info; - CharPtr PNTR WWWargv; - Int4 WWWargc; + Int4 WWWLen; + WWWInfoDataPtr info; + CharPtr PNTR WWWargv; + Int4 WWWargc; + Int4 rsize; - if((info = (WWWInfoDataPtr) WWWInfoNew()) == NULL) - return WWWErrNoMem; - - /* Reading environment from HTTPD */ - if(!WWWReadEnvironment(info)) { - info->method = COMMAND_LINE; +#ifdef WIN32 + setmode(fileno(stdin), _O_BINARY); +#endif - if(ReadArgv == TRUE) { - WWWargc = GetArgc(); - WWWargv = GetArgv(); - - /* Now try to initilalize WWWInfo structure from STDIN or command line */ - if(WWWargc == 1) { /* reading STDIN */ - if((info->query = WWWReadFileInMemory(stdin, 0, TRUE)) != NULL) { - info->entries = WWWGetEntries(&info->num_entries, info->query, - (Boolean)(info->browser == NETSCAPE)); + if ((info = (WWWInfoDataPtr) WWWInfoNew()) == NULL) + return WWWErrNoMem; + + /* Reading environment from HTTPD */ + if (!WWWReadEnvironment(info)) { + info->method = COMMAND_LINE; + + if (attr->read_argv == TRUE) { + WWWargc = GetArgc(); + WWWargv = GetArgv(); + /* Now try to initilalize WWWInfo from STDIN or command line */ + if (WWWargc == 1) { /* reading STDIN */ + if((info->query = WWWReadFileInMemoryEx(stdin, 0, + attr->filter_non_print, + &rsize)) != NULL) { + info->query_len = rsize; + info->entries = WWWGetEntriesEx(&info->num_entries, + info->query, + info->query_len); + } + } else { /* treat 1st parameter as input buffer */ + if ((info->query = StringSave(WWWargv[1])) != NULL) { + info->query_len = StringLen(info->query); + info->entries = WWWGetEntriesEx(&info->num_entries, + info->query, + info->query_len); + } + } } - } else { /* treat 1st parameter as input buffer */ - if((info->query = StringSave(WWWargv[1])) != NULL) { - info->entries = WWWGetEntries(&info->num_entries, info->query, - (Boolean)(info->browser == NETSCAPE)); + *info_out = (VoidPtr) info; + return WWWErrOk; + } /* COMMAND_LINE */ + + if (info->method == WWW_GET) { /* Getting GET data */ + info->query = StringSave(getenv("QUERY_STRING")); + info->query_len = StringLen(info->query); + } else if (info->method == WWW_POST) { /* Getting POST data */ + if ((getenv("CONTENT_LENGTH") != NULL) && + (WWWLen = atol(getenv("CONTENT_LENGTH"))) > 0) { + if ((info->query = WWWReadFileInMemoryEx(stdin, WWWLen, + attr->filter_non_print, + &rsize)) == NULL) { + return WWWErrNetwork; + } + info->query_len = rsize; } - } - } + } /* Method == POST */ + if (info->query != NULL) + info->entries = WWWGetEntriesEx(&info->num_entries, info->query, + info->query_len); *info_out = (VoidPtr) info; return WWWErrOk; - } /* COMMAND_LINE */ - - if(info->method == WWW_GET) { /* Getting GET data */ - info->query = StringSave(getenv("QUERY_STRING")); - } else if (info->method == WWW_POST) { /* Getting POST data */ - if((getenv("CONTENT_LENGTH") != NULL) && - (WWWLen = atol(getenv("CONTENT_LENGTH"))) > 0) { - if((info->query = WWWReadFileInMemory(stdin, WWWLen, TRUE)) == NULL) - return WWWErrNetwork; - } - } /* Method == POST */ - - if(info->query != NULL) - info->entries = WWWGetEntries(&info->num_entries, info->query, - (Uint1) (info->browser == NETSCAPE)); - *info_out = (VoidPtr) info; - return WWWErrOk; } NLM_EXTERN Int4 WWWFindName(WWWInfoPtr info_in, CharPtr find) { - - Int4 i; - WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; - if(!info || !find) - return -1; - - for(i = 0; i < info->num_entries; i++) { - if (!StringICmp(info->entries[i]->name, find)) { - return i; + Int4 i; + WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; + + if (!info || !find) + return -1; + + for (i = 0; i < info->num_entries; i++) { + if (!StringICmp(info->entries[i]->name, find)) { + return i; + } } - } - return -1; + return -1; } + + NLM_EXTERN Int4 WWWFindNameEx(WWWInfoPtr info_in, CharPtr find, Int4 index) { - + Int4 i; WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; - - if(!info || !find) + + if (!info || !find) return -1; - - if(index >= info->num_entries) + + if (index >= info->num_entries) return -1; - - for(i = index; i < info->num_entries; i++) { + + for (i = index; i < info->num_entries; i++) { if (!StringICmp(info->entries[i]->name, find)) { return i; } } - + return -1; } -NLM_EXTERN CharPtr WWWGetNameByIndex(WWWInfoPtr info_in, Int4 index) + +NLM_EXTERN CharPtr WWWGetNameByIndex(WWWInfoPtr info_in, Int4 index) +{ + WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; + + if (!info || !info->entries || index < 0 || index > info->num_entries) + return NULL; + + return info->entries[index]->name; +} + + +NLM_EXTERN CharPtr WWWGetValueByIndex(WWWInfoPtr info_in, Int4 index) { - WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; + WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; - if(!info || !info->entries || index < 0 || index > info->num_entries) - return NULL; - - return info->entries[index]->name; + if (!info || !info->entries || index < 0 || index > info->num_entries) + return NULL; + + return info->entries[index]->val; } -NLM_EXTERN CharPtr WWWGetValueByIndex(WWWInfoPtr info_in, Int4 index) + +NLM_EXTERN Int4 WWWGetValueSizeByIndex(WWWInfoPtr info_in, Int4 index) { - WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; + WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; - if(!info || !info->entries || index < 0 || index > info->num_entries) - return NULL; + if (!info || !info->entries || index < 0 || index > info->num_entries) + return -1; - return info->entries[index]->val; + return info->entries[index]->size; } -NLM_EXTERN CharPtr WWWGetValueByName(WWWInfoPtr info_in, CharPtr find) + +NLM_EXTERN CharPtr WWWGetValueByName(WWWInfoPtr info_in, CharPtr find) { - Int4 index; - WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; + Int4 index; + WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; + + if (!info || !info->entries || !find) + return NULL; + + if ((index = WWWFindName(info_in, find)) < 0) + return NULL; - if(!info || !info->entries || !find) - return NULL; - - if((index = WWWFindName(info_in, find)) < 0) - return NULL; - - return info->entries[index]->val; + return info->entries[index]->val; } -NLM_EXTERN CharPtr WWWGetLastValueByName(WWWInfoPtr info_in, CharPtr find) + +NLM_EXTERN CharPtr WWWGetLastValueByName(WWWInfoPtr info_in, CharPtr find) { Int4 index; WWWInfoDataPtr info = (WWWInfoDataPtr) info_in; CharPtr retvalue = NULL; - - if(!info || !info->entries || !find) + + if (!info || !info->entries || !find) return NULL; - + index = 0; - - while((index = WWWFindNameEx(info_in, find, index)) >= 0) + + while ((index = WWWFindNameEx(info_in, find, index)) >= 0) retvalue = info->entries[index]->val; - + return retvalue; } + NLM_EXTERN WWWEntryPtr PNTR WWWGetEntries(Int4Ptr num_entries, - CharPtr WWWBuffer_in, + CharPtr WWWBuffer_in, Boolean NetscapeOK) { - register Int4 i; - Int4 size; - CharPtr WWWBuffer; - WWWEntryPtr PNTR entries; - - if(WWWBuffer_in == NULL || WWWBuffer_in[0] == NULLB) - return NULL; - - NetscapeOK = TRUE; /* Forget it... all browsers should handle it */ - - if ((entries = (WWWEntryPtr*)MemNew(sizeof(WWWEntryPtr)*MAX_WWW_ENTRIES)) == NULL) - return NULL; - - if(NetscapeOK && StringStr(WWWBuffer_in, - "Content-Disposition: form-data;") != NULL) { - *num_entries = WWWGetEntriesFormData(entries, WWWBuffer_in); + register Int4 i; + Int4 size; + CharPtr WWWBuffer; + WWWEntryPtr PNTR entries; + + if (WWWBuffer_in == NULL || WWWBuffer_in[0] == NULLB) + return NULL; + + NetscapeOK = TRUE; /* Forget it... all browsers should handle it */ + + if ((entries = (WWWEntryPtr*)MemNew(sizeof(WWWEntryPtr) * + MAX_WWW_ENTRIES)) == NULL) + return NULL; + + if (NetscapeOK && StringStr(WWWBuffer_in, + "Content-Disposition: form-data;") != NULL) { + *num_entries = WWWGetEntriesFormData(entries, WWWBuffer_in); + return entries; + } + + WWWBuffer = StringSave(WWWBuffer_in); /* this copy may be used for logs */ + size = StringLen(WWWBuffer) + 1; + + for (i=0; WWWBuffer[0] != NULLB; i++) { + entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); + entries[i]->name = (CharPtr) MemNew(WWW_MAX_NAME_LEN); + entries[i]->val = (CharPtr) MemNew(size); + + WWWGetWord(entries[i]->val,WWWBuffer,'&'); + PlusToSpace(entries[i]->val); + WWWUnescapeUrl(entries[i]->val); + WWWGetWord(entries[i]->name,entries[i]->val,'='); + + entries[i]->name = (CharPtr) Realloc(entries[i]->name, + StringLen(entries[i]->name)+1); + entries[i]->val = (CharPtr) Realloc(entries[i]->val, + StringLen(entries[i]->val)+1); + entries[i]->size = StringLen(entries[i]->val); + } + + ASSERT ( i < MAX_WWW_ENTRIES ); + entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); + entries[i]->name = NULL; + entries[i]->val = NULL; + + MemFree(WWWBuffer); + *num_entries = i; return entries; - } - - WWWBuffer = StringSave(WWWBuffer_in); /* this copy may be used for logs */ - size = StringLen(WWWBuffer) + 1; - - for(i=0; WWWBuffer[0] != NULLB; i++) { - entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); - entries[i]->name = (CharPtr) MemNew(WWW_MAX_NAME_LEN); - entries[i]->val = (CharPtr) MemNew(size); - - WWWGetWord(entries[i]->val,WWWBuffer,'&'); - PlusToSpace(entries[i]->val); - WWWUnescapeUrl(entries[i]->val); - WWWGetWord(entries[i]->name,entries[i]->val,'='); - - entries[i]->name = (CharPtr) Realloc(entries[i]->name, - StringLen(entries[i]->name)+1); - entries[i]->val = (CharPtr) Realloc(entries[i]->val, - StringLen(entries[i]->val)+1); - } - - ASSERT ( i < MAX_WWW_ENTRIES ); - entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); - entries[i]->name = NULL; - entries[i]->val = NULL; - - MemFree(WWWBuffer); - *num_entries = i; - return entries; -} - -NLM_EXTERN Int4 WWWGetEntriesFormData(WWWEntryPtr PNTR entries, - CharPtr WWWBuffer) +} + + +NLM_EXTERN WWWEntryPtr PNTR WWWGetEntriesEx(Int4Ptr num_entries, + CharPtr WWWBuffer_in, + Int4 WWWBuffer_len) +{ + register Int4 i; + Int4 size; + CharPtr WWWBuffer; + WWWEntryPtr PNTR entries; + + if (WWWBuffer_in == NULL || WWWBuffer_in[0] == NULLB) + return NULL; + + if ((entries = (WWWEntryPtr*)MemNew(sizeof(WWWEntryPtr) * + MAX_WWW_ENTRIES)) == NULL) + return NULL; + + if (StringStr(WWWBuffer_in, "Content-Disposition: form-data;") != NULL) { + *num_entries = WWWGetEntriesFormDataEx(entries, WWWBuffer_in, + WWWBuffer_len); + return entries; + } + + WWWBuffer = StringSave(WWWBuffer_in); /* this copy may be used for logs */ + size = StringLen(WWWBuffer) + 1; + + for (i=0; WWWBuffer[0] != NULLB; i++) { + entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); + entries[i]->name = (CharPtr) MemNew(WWW_MAX_NAME_LEN); + entries[i]->val = (CharPtr) MemNew(size); + + WWWGetWord(entries[i]->val,WWWBuffer,'&'); + PlusToSpace(entries[i]->val); + WWWUnescapeUrl(entries[i]->val); + WWWGetWord(entries[i]->name,entries[i]->val,'='); + + entries[i]->name = (CharPtr) Realloc(entries[i]->name, + StringLen(entries[i]->name)+1); + entries[i]->val = (CharPtr) Realloc(entries[i]->val, + StringLen(entries[i]->val)+1); + } + + ASSERT ( i < MAX_WWW_ENTRIES ); + entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); + entries[i]->name = NULL; + entries[i]->val = NULL; + + MemFree(WWWBuffer); + *num_entries = i; + return entries; +} + + +NLM_EXTERN Int4 WWWGetEntriesFormDataEx(WWWEntryPtr PNTR entries, + CharPtr WWWBuffer_in, + Int4 WWWBuffer_len) { - - Int4 FieldLen, buff_len; + Int4 FieldLen, pos; register Int4 i; Char BoundaryString[512]; CharPtr FieldValue, FieldTmp; - CharPtr NextString; - - if(WWWBuffer == NULL || WWWBuffer[0] == NULLB) + CharPtr WWWBuffer = WWWBuffer_in; + + if (WWWBuffer == NULL || WWWBuffer[0] == NULLB) return -1; - - buff_len = StringLen(WWWBuffer); - - for(i = 0; !isspace(WWWBuffer[i]); i++) { + + if (WWWBuffer_len < 0) + WWWBuffer_len = StringLen(WWWBuffer); + + for (i = 0; !isspace(WWWBuffer[i]); i++) { BoundaryString[i] = WWWBuffer[i]; } BoundaryString[i] = NULLB; - - for(i=0; WWWBuffer[0] != NULLB; i++) { - - entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); - entries[i]->name = (CharPtr) MemNew(128); - - if((WWWBuffer = StringStr(WWWBuffer, BoundaryString)) == NULL) + + for (i=0; WWWBuffer < WWWBuffer_in + WWWBuffer_len; i++) { + + entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); + entries[i]->name = (CharPtr) MemNew(128); + + if ((pos = MemSearch(WWWBuffer, + WWWBuffer_in + WWWBuffer_len - WWWBuffer, + BoundaryString, + StringLen(BoundaryString))) < 0) break; - if( *(WWWBuffer = WWWBuffer + StringLen(BoundaryString) + 1) == '-') + WWWBuffer += pos; + if (*(WWWBuffer = WWWBuffer + StringLen(BoundaryString) + 1) == '-') break; - if((WWWBuffer = StringStr(WWWBuffer , "form-data;")) == NULL) + if ((WWWBuffer = StringStr(WWWBuffer , "form-data;")) == NULL) break; - + WWWBuffer += 11; - - if((NextString = StringStr(WWWBuffer, BoundaryString)) == NULL) + + if ((FieldLen = MemSearch(WWWBuffer, + WWWBuffer_in + WWWBuffer_len - WWWBuffer, + BoundaryString, + StringLen(BoundaryString))) < 0) break; - - FieldLen = NextString - WWWBuffer - 1; - + FieldValue = (CharPtr) MemNew(FieldLen+1); MemCopy(FieldValue, WWWBuffer, FieldLen); FieldValue[FieldLen] = NULLB; - + sscanf(FieldValue, "name=\"%s ", entries[i]->name); - - if(entries[i]->name[StringLen(entries[i]->name)-1] != ';') + + if (entries[i]->name[StringLen(entries[i]->name)-1] != ';') entries[i]->name[StringLen(entries[i]->name)-1] = NULLB; - else + else entries[i]->name[StringLen(entries[i]->name)-2] = NULLB; - - if((FieldTmp = StringStr(FieldValue, "\r\n\r\n")) != NULL) { + + if ((FieldTmp = StringStr(FieldValue, "\r\n\r\n")) != NULL) { FieldTmp = FieldTmp + 4; - FieldTmp[StringLen(FieldTmp) - 1] = NULLB; - entries[i]->val = StringSave(FieldTmp); + pos = FieldValue + FieldLen - FieldTmp; + FieldTmp[pos-2] = NULLB; + MemMove(FieldValue, FieldTmp, pos - 1); + entries[i]->val = Realloc(FieldValue, pos -1); + entries[i]->size = pos - 2; } else { + MemFree(FieldValue); entries[i]->val = ""; + entries[i]->size = 0; } - MemFree(FieldValue); } - - entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); + + entries[i] = (WWWEntryPtr) MemNew(sizeof(WWWEntry)); entries[i]->name = NULL; entries[i]->val = NULL; - + return i; } + +NLM_EXTERN Int4 WWWGetEntriesFormData(WWWEntryPtr PNTR entries, + CharPtr WWWBuffer) +{ + return WWWGetEntriesFormDataEx(entries, WWWBuffer, -1); +} + + NLM_EXTERN CharPtr WWWReadFileInMemory(FILE *fd, Int4 len, Boolean filter) { - Int4 bytes = 0; - CharPtr in_buff; - Int4 new_size = INIT_BUFF_SIZE; - Int4 buff_len = 0; - register Int4 i; - - if(fd == NULL) - return NULL; - - if(len == 0) { - /* initial allocation of memory */ - - if((in_buff = (CharPtr)MemNew(INIT_BUFF_SIZE)) == NULL) { - ErrLogPrintf("Error in allocating memory\n"); - return NULL; - } - - while ((bytes = FileRead(in_buff + buff_len, 1, - INIT_BUFF_SIZE, fd)) > 0) { - new_size += bytes; - buff_len += bytes; - - if ((in_buff = (CharPtr)Realloc(in_buff, new_size)) == NULL) { - ErrLogPrintf("Error in reallocating memory\n"); - exit(1); - } + Int4 bytes = 0; + CharPtr in_buff; + Int4 new_size = INIT_BUFF_SIZE; + Int4 buff_len = 0; + register Int4 i; + + if (fd == NULL) + return NULL; + + if (len == 0) { + /* initial allocation of memory */ + + if ((in_buff = (CharPtr)MemNew(INIT_BUFF_SIZE)) == NULL) { + ErrLogPrintf("Error in allocating memory\n"); + return NULL; + } + + while ((bytes = FileRead(in_buff + buff_len, 1, + INIT_BUFF_SIZE, fd)) > 0) { + new_size += bytes; + buff_len += bytes; + + if ((in_buff = (CharPtr)Realloc(in_buff, new_size)) == NULL) { + ErrLogPrintf("Error in reallocating memory\n"); + exit(1); + } + } + in_buff[buff_len] = NULLB; + + } else { + + in_buff = (CharPtr) MemNew(len+1); + + while (buff_len < len) { + if ((bytes = FileRead(in_buff+buff_len, 1, len, stdin)) == 0 + || bytes == len) { + buff_len += bytes; + break; /* EOF or done*/ + } else if (bytes < 0) { + /* some error setting may be here */ + return NULL; + } + buff_len += bytes; + } + in_buff[buff_len] = NULLB; + } + + /* some filtering of non-printing characters */ + + if (filter) { + for (i = 0; i < buff_len; i++) { + if (!isprint(in_buff[i]) && !isspace(in_buff[i])) + in_buff[i] = ' '; + } } - in_buff[buff_len] = NULLB; - - } else { - - in_buff = (CharPtr) MemNew(len+1); - - while(buff_len < len) { - if((bytes = FileRead(in_buff+buff_len, 1, len, stdin)) == 0 - || bytes == len) { - buff_len += bytes; - break; /* EOF or done*/ - } else if (bytes < 0) { - /* some error setting may be here */ + + return(in_buff); +} + + +NLM_EXTERN CharPtr WWWReadFileInMemoryEx(FILE *fd, Int4 len, Boolean filter, Int4Ptr rsize) +{ + Int4 bytes = 0; + CharPtr in_buff; + Int4 new_size = INIT_BUFF_SIZE; + Int4 buff_len = 0; + register Int4 i; + + if (rsize) + *rsize = 0; + + if (fd == NULL) return NULL; - } - buff_len += bytes; + + if (len == 0) { + /* initial allocation of memory */ + + if ((in_buff = (CharPtr)MemNew(INIT_BUFF_SIZE)) == NULL) { + ErrLogPrintf("Error in allocating memory\n"); + return NULL; + } + + while ((bytes = FileRead(in_buff + buff_len, 1, + INIT_BUFF_SIZE, fd)) > 0) { + new_size += bytes; + buff_len += bytes; + + if ((in_buff = (CharPtr)Realloc(in_buff, new_size)) == NULL) { + ErrLogPrintf("Error in reallocating memory\n"); + exit(1); + } + } + in_buff[buff_len] = NULLB; + + } else { + + in_buff = (CharPtr)MemNew(len+1); + + while (buff_len < len) { + if ((bytes = FileRead(in_buff+buff_len, 1, len, stdin)) == 0 + || bytes == len) { + buff_len += bytes; + break; /* EOF or done*/ + } else if (bytes < 0) { + /* some error setting may be here */ + if (rsize) + *rsize = buff_len; + return NULL; + } + buff_len += bytes; + } + in_buff[buff_len] = NULLB; + } + + /* some filtering of non-printing characters */ + + if (filter) { + for (i = 0; i < buff_len; i++) { + if (!isprint(in_buff[i]) && !isspace(in_buff[i])) + in_buff[i] = ' '; + } } - in_buff[buff_len] = NULLB; - } - - /* some filtering of non-printing characters */ - - if(filter) { - for(i = 0; i < buff_len; i++) { - if (!isprint(in_buff[i]) && !isspace(in_buff[i])) - in_buff[i] = ' '; + if (rsize) { + *rsize = buff_len; } - } - - return(in_buff); + return(in_buff); +} + + +NLM_EXTERN SWWWGetArgsAttr WWWGetArgsAttr_Create(void) +{ + SWWWGetArgsAttr attr =(SWWWGetArgsAttr)MemNew(sizeof(SWWWGetArgsAttrData)); + attr->filter_non_print = TRUE; + attr->read_argv = FALSE; + return attr; +} + + +NLM_EXTERN void WWWGetArgsAttr_Destroy(SWWWGetArgsAttr attr) +{ + MemFree(attr); +} + + +NLM_EXTERN Boolean WWWGetArgsAttr_SetFilter(SWWWGetArgsAttr attr, + Boolean filter_non_print) +{ + Boolean prev_val = attr->filter_non_print; + attr->filter_non_print = filter_non_print; + return prev_val; +} + + +NLM_EXTERN Boolean WWWGetArgsAttr_SetReadArgv(SWWWGetArgsAttr attr, + Boolean read_argv) +{ + Boolean prev_val = attr->read_argv; + attr->read_argv = read_argv; + return prev_val; } @@ -686,93 +970,103 @@ static Boolean WWWReadEnvironment(WWWInfoDataPtr info) { CharPtr Method; - if(!info) return 0; - + if (!info) + return 0; + info->method = COMMAND_LINE; - - if((Method = getenv("REQUEST_METHOD")) != NULL) { - - if(!StringICmp(Method, "GET")) { + + if ((Method = getenv("REQUEST_METHOD")) != NULL) { + + if (!StringICmp(Method, "GET")) { info->method = WWW_GET; } else if (!StringICmp(Method, "POST")) { info->method= WWW_POST; } } - - if((info->host = StringSave(getenv("REMOTE_HOST"))) == NULL) + + if ((info->host = StringSave(getenv("REMOTE_HOST"))) == NULL) info->host = StringSave("Host unknown"); - - if((info->address = StringSave(getenv("REMOTE_ADDR"))) == NULL) + + if ((info->address = StringSave(getenv("REMOTE_ADDR"))) == NULL) info->address =StringSave("Address unknown"); - - if((info->proxied_ip = StringSave(getenv("PROXIED_IP"))) == NULL) + + if ((info->proxied_ip = StringSave(getenv("PROXIED_IP"))) == NULL) info->proxied_ip = StringSave(info->address); - - if((info->doc_root = StringSave(getenv("DOCUMENT_ROOT"))) == NULL) + + if ((info->doc_root = StringSave(getenv("DOCUMENT_ROOT"))) == NULL) info->doc_root =StringSave("_unknown_"); - - if((info->agent = StringSave(getenv("HTTP_USER_AGENT"))) == NULL) - info->agent =StringSave("Agent unknown"); - - if((getenv("SERVER_PORT") == NULL) || + + if ((info->agent = StringSave(getenv("HTTP_USER_AGENT"))) == NULL) + info->agent =StringSave("Agent unknown"); + + if ((getenv("SERVER_PORT") == NULL) || (info->port = atol(getenv("SERVER_PORT"))) == 0) - info->port = -1; - - if((info->server_name = StringSave(getenv("SERVER_NAME"))) == NULL) - info->server_name = StringSave("Server unknown"); - - if((info->script_name = StringSave(getenv("SCRIPT_NAME"))) == NULL) - info->script_name = StringSave("Script unknown"); - + info->port = -1; + + if ((info->server_name = StringSave(getenv("SERVER_NAME"))) == NULL) + info->server_name = StringSave("Server unknown"); + + if ((info->script_name = StringSave(getenv("SCRIPT_NAME"))) == NULL) + info->script_name = StringSave("Script unknown"); + info->browser = MISC_BROWSER; - - if(StringStr(info->agent, "Mozilla")) + + if (StringStr(info->agent, "Mozilla")) info->browser = NETSCAPE; - + /* if(StringStr(info->agent, "MSIE") || StringStr(info->agent, "Microsoft")) info->browser = EXPLORER; */ - - if(info->method == WWW_POST || info->method == WWW_GET) + + if (info->method == WWW_POST || info->method == WWW_GET) return TRUE; else return FALSE; } - -static void WWWGetWord(CharPtr word, CharPtr line, Char stop) { - register Int4 x = 0,y =0; - - for(x=0;((line[x]) && (line[x] != stop));x++) - word[x] = line[x]; - - word[x] = '\0'; - - if(line[x]) ++x; - - while((line[y++] = line[x++]) != NULLB) - continue; - -} - -static void PlusToSpace(CharPtr str) { + + +static void WWWGetWord(CharPtr word, CharPtr line, Char stop) +{ + register Int4 x = 0,y =0; + + for (x=0; ((line[x]) && (line[x] != stop)); x++) + word[x] = line[x]; + + word[x] = '\0'; + + if (line[x]) ++x; + + while ((line[y++] = line[x++]) != NULLB) + continue; + +} + + +static void PlusToSpace(CharPtr str) +{ register Int4 x; - for(x=0; str[x]; x++) if(str[x] == '+') - str[x] = ' '; + for (x=0; str[x]; x++) if(str[x] == '+') + str[x] = ' '; } -static void WWWUnescapeUrl(CharPtr url) { + +static void WWWUnescapeUrl(CharPtr url) +{ register Int4 x,y; - for(x=0,y=0;url[y];++x,++y) { - if((url[x] = url[y]) == '%') { + for (x=0, y=0; url[y]; ++x, ++y) { + if ((url[x] = url[y]) == '%') { url[x] = WWWx2c(&url[y+1]); y+=2; } } url[x] = '\0'; } -static Char WWWx2c(CharPtr what) { + + +static Char WWWx2c(CharPtr what) +{ register Char digit; digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); |