/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * filemac.c - manipulate file names and scan directories on macintosh * * External routines: * * file_dirscan() - scan a directory for files * file_time() - get timestamp of file, if not done by file_dirscan() * file_archscan() - scan an archive for files * * File_dirscan() and file_archscan() call back a caller provided function * for each file found. A flag to this callback function lets file_dirscan() * and file_archscan() indicate that a timestamp is being provided with the * file. If file_dirscan() or file_archscan() do not provide the file's * timestamp, interested parties may later call file_time(). * * 04/08/94 (seiwald) - Coherent/386 support added. * 12/19/94 (mikem) - solaris string table insanity support * 02/14/95 (seiwald) - parse and build /xxx properly * 05/03/96 (seiwald) - split into pathunix.c * 11/21/96 (peterk) - BEOS does not have Unix-style archives * 01/21/00 (malyn) - divorced from GUSI * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "filesys.h" # include "pathsys.h" # ifdef OS_MAC #ifndef GRAPHISOFT_MPW_FIX #include <Files.h> #include <Folders.h> # include <:sys:stat.h> #endif #ifdef GRAPHISOFT_MPW_FIX #include <Files.h> #include <Aliases.h> #include <CodeFragments.h> #if defined (__MSL__) /* ** Overwrite pool alloc, to prevent out of memory error */ # include <pool_alloc.h> # include <stdlib.h> #define USETEMPMEM 1 #if defined(__cplusplus) extern "C" #endif void * __sys_alloc(size_t size) { #if USETEMPMEM OSErr result; Handle hresult = TempNewHandle (size, &result); if (hresult == NULL) { fprintf (stderr, "# Jam Fatal error: Out of memory!\n"); exit (1); } HLock (hresult); return *hresult; #else void *result = NewPtr (size); if (result == NULL) { fprintf (stderr, "# Jam Fatal error: Out of memory!\n"); exit (1); } return result; #endif } void __sys_free(void * ptr) { #if USETEMPMEM Handle p = RecoverHandle ((char*)ptr); DisposeHandle (p); #else DisposePtr((char*)ptr); #endif } static void freeallmem (void) { #if __MSL__ >= 0x7000 __malloc_free_all (); #else __pool_free_all (); #endif } #endif #endif #ifndef GRAPHISOFT_MPW_FIX void CopyC2PStr(const char * cstr, StringPtr pstr) { int len; for (len = 0; *cstr && len<255; pstr[++len] = *cstr++) ; pstr[0] = len; } #endif /* * file_dirscan() - scan a directory for files */ #ifdef GRAPHISOFT_MPW_FIX /* ** For several resons we cannot use FSMakeFSSpec: ** - it doesn't supports aliases ** - only paths shorter than 256 characters are supported ** ** MakeResolvedFSSpec_Long is available in StdCLib 3.5, but we cannot link with it as it interferes with ** StdCLib, so we load it dynamically. */ static OSErr (*StdCLib_MakeResolvedFSSpec_Long)(short volume, long directory, const char *path, Str255 buffer, FSSpec *theSpec, Boolean *isFolder, Boolean *hadAlias, Boolean *leafIsAlias); void initfilemac() { CFragConnectionID StdCLib; CFragSymbolClass symClass; Ptr whoCares; Str255 error; /* * Load StdCLib */ if (GetSharedLibrary((StringPtr)"\pStdCLib", kPowerPCCFragArch, kLoadCFrag, &StdCLib, &whoCares, error)) { fprintf (stderr, "# Fatal Error: Cannot load StdCLib"); exit (1); } /* * Load Symbols */ if (FindSymbol (StdCLib, (StringPtr)"\pMakeResolvedFSSpec_Long", (Ptr *) &StdCLib_MakeResolvedFSSpec_Long, &symClass)) { fprintf (stderr, "# Fatal Error: Cannot load MakeResolvedFSSpec_Long"); exit (1); } #if defined (__MSL__) atexit (freeallmem); #endif } #endif #ifdef GRAPHISOFT_MPW_FIX #define mac_epoch_offset_ (-((365L * 66L) + 17) * 24L * 60L * 60L) void file_dirscan( const char *idir, scanback func, void *closure ) { PATHNAME f; Str255 tempStr255; OSErr result; Boolean isDirectory,hadAlias,leafIsAlias; Boolean temp; long theDirID; short theVRefNum; CInfoPBRec theCPB; int index; FSSpec theFSSpec; char filename[ MAXJPATH ]; Str255 nameBuffer; const char* dir = *idir ? idir : ":" ; /* First enter directory itself */ memset ((void*)&f, 0, sizeof(f)); f.f_dir.ptr = (char*)dir; f.f_dir.len = strlen(dir); result = StdCLib_MakeResolvedFSSpec_Long (0, 0, (char*)dir, tempStr255, &theFSSpec, &isDirectory, &hadAlias, &leafIsAlias); if ((result != noErr) || (!isDirectory)) return; /* Special case: 'Volume name:' -> enter it, otherwise enter the dir and it's parent */ (*func)( closure, (char*)dir, 0 /* not stat()'ed */, (time_t)0 ); if (!((f.f_dir.len > 1) && (f.f_dir.ptr[f.f_dir.len-1] == ':') && (memchr(f.f_dir.ptr,':',f.f_dir.len-1)==NULL))) { char name[256]; strcpy (name,"::"); f.f_base.ptr = name; f.f_base.len = strlen( name ); path_build( &f, filename, 0 ); (*func)(closure, filename, 0/* not stat()'ed */,(time_t)0 ); } /* Determine the directory id [theDirId] */ theCPB.dirInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ memcpy(tempStr255,theFSSpec.name,sizeof (theFSSpec.name)); theCPB.dirInfo.ioNamePtr = tempStr255; theCPB.dirInfo.ioVRefNum = theFSSpec.vRefNum; theCPB.dirInfo.ioDrDirID = theFSSpec.parID; result = PBGetCatInfoSync ((CInfoPBPtr)&theCPB); if ((result != noErr) || ((theCPB.hFileInfo.ioFlAttrib & kioFlAttribDirMask) == 0)) return; /* Iterte trough the directory */ index = 1; tempStr255[0] = 0; theCPB.hFileInfo.ioNamePtr = tempStr255; theCPB.dirInfo.ioFDirIndex = index; theVRefNum = theCPB.dirInfo.ioVRefNum; theDirID = theCPB.dirInfo.ioDrDirID; result = PBGetCatInfoSync ((CInfoPBPtr)&theCPB); if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); while (result == noErr) { char name[256]; time_t mt_time; strncpy (name, (const char*)&theCPB.hFileInfo.ioNamePtr[1], theCPB.hFileInfo.ioNamePtr[0]); name[theCPB.hFileInfo.ioNamePtr[0]] = 0; mt_time = mac_epoch_offset_ + theCPB.hFileInfo.ioFlMdDat; f.f_base.ptr = name; f.f_base.len = strlen( name ); path_build( &f, filename, 0 ); (*func)(closure, filename, 1, mt_time); index++; theCPB.dirInfo.ioFDirIndex = index; theCPB.dirInfo.ioVRefNum = theVRefNum; theCPB.dirInfo.ioDrDirID = theDirID; result = PBGetCatInfoSync ((CInfoPBPtr)&theCPB); } result = noErr; } #endif #ifndef GRAPHISOFT_MPW_FIX void file_dirscan( char *dir, scanback func, void *closure ) { PATHNAME f; char filename[ MAXJPATH ]; unsigned char fullPath[ 512 ]; FSSpec spec; WDPBRec vol; Str63 volName; CInfoPBRec lastInfo; int index = 1; /* First enter directory itself */ memset( (char *)&f, '\0', sizeof( f ) ); f.f_dir.ptr = dir; f.f_dir.len = strlen(dir); if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); /* Special case ":" - enter it */ if( f.f_dir.len == 1 && f.f_dir.ptr[0] == ':' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); /* Now enter contents of directory */ vol.ioNamePtr = volName; if( PBHGetVolSync( &vol ) ) return; CopyC2PStr( dir, fullPath ); if( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) ) return; lastInfo.dirInfo.ioVRefNum = spec.vRefNum; lastInfo.dirInfo.ioDrDirID = spec.parID; lastInfo.dirInfo.ioNamePtr = spec.name; lastInfo.dirInfo.ioFDirIndex = 0; lastInfo.dirInfo.ioACUser = 0; if( PBGetCatInfoSync(&lastInfo) ) return; if (!(lastInfo.dirInfo.ioFlAttrib & 0x10)) return; // ioDrDirID must be reset each time. spec.parID = lastInfo.dirInfo.ioDrDirID; for( ;; ) { lastInfo.dirInfo.ioVRefNum = spec.vRefNum; lastInfo.dirInfo.ioDrDirID = spec.parID; lastInfo.dirInfo.ioNamePtr = fullPath; lastInfo.dirInfo.ioFDirIndex = index++; if( PBGetCatInfoSync(&lastInfo) ) return; f.f_base.ptr = (char *)fullPath + 1; f.f_base.len = *fullPath; path_build( &f, filename, 0 ); (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); } } #endif /* * file_time() - get timestamp of file, if not done by file_dirscan() */ #ifdef GRAPHISOFT_MPW_FIX int file_time( const char *filename, time_t *time ) { HFileInfo fpb; Str255 tempStr255; OSErr result; Boolean wasChanged; FSSpec theFSSpec; AliasHandle theAlias; Boolean isDirectory,hadAlias,leafIsAlias; result = StdCLib_MakeResolvedFSSpec_Long (0, 0, filename, tempStr255, &theFSSpec, &isDirectory, &hadAlias, &leafIsAlias); if (result != noErr) return -1; memcpy (tempStr255, theFSSpec.name, sizeof(theFSSpec.name)); fpb.ioNamePtr = tempStr255; fpb.ioFDirIndex = 0; fpb.ioVRefNum = theFSSpec.vRefNum; fpb.ioDirID = theFSSpec.parID; result = PBGetCatInfoSync((CInfoPBPtr)&fpb); if (result != noErr) return -1; *time = mac_epoch_offset_ + fpb.ioFlMdDat; return 0; } #endif #ifndef GRAPHISOFT_MPW_FIX int file_time( const char *filename, time_t *time ) { struct stat statbuf; if( stat( filename, &statbuf ) < 0 ) return -1; *time = statbuf.st_mtime; return 0; } #endif /* * file_archscan() - scan an archive for files */ void file_archscan( const char *archive, scanback func, void *closure ) { } # endif /* macintosh */
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#11 | 2578 | Miklos Fazekas | Integrate new lexical scanner code to GSJam | ||
#10 | 2521 | Miklos Fazekas | Compile error fixes after merge | ||
#9 | 2519 | Miklos Fazekas | Sync to 2.5rc1 | ||
#8 | 1635 | Miklos Fazekas | OS-X version with CodeWarrior, fix for header scan with non-native lineendings | ||
#7 | 1590 | Miklos Fazekas | Fixed a bug with my Mac/ date implementation&minor changes | ||
#6 | 1573 | Miklos Fazekas | Merge to jam mainline. | ||
#5 | 1398 | Miklos Fazekas | Cleanup. | ||
#4 | 1395 | Miklos Fazekas | Merge with main jam | ||
#3 | 1320 | Miklos Fazekas |
MacOS related fixes: - emulation of jam's behaviour in MPW shell's scripting language (ie.: failed targets are removed) - fix for out of memory errors on MacOS. - together targets are removed |
||
#2 | 1219 | Miklos Fazekas |
MPW related fixes: - support for longer than 255 pahtnames - fixed problems with handling of paths - fix: Mac file system is case insensitive - code is compatible with MrC and MWCCP |
||
#1 | 1212 | Miklos Fazekas | Created a Jam branch | ||
//guest/perforce_software/jam/src/filemac.c | |||||
#3 | 486 | Perforce staff |
Jam 2.3. See RELNOTES for a list of changes from 2.2.x. Just about every source file was touched when jam got ANSI-fied. |
||
#2 | 213 | Perforce staff | Peter Glasscock's MPW port. | ||
#1 | 2 | laura | Add Jam/MR 2.2 source |