filemac.c #6

  • //
  • guest/
  • miklos_fazekas/
  • jam/
  • src/
  • filemac.c
  • View
  • Commits
  • Open Download .zip Download (8 KB)
/*
 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */
 
# 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

/*
 * 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
 */

#ifdef GRAPHISOFT_MPW_FIX    
#include <Files.h>
#include <Aliases.h>
#include <CodeFragments.h> 

/*
** Overwrite pool alloc, to prevent out of memory error
*/
#if defined (__MSL__)
#	include <pool_alloc.h>

extern "C"
void *	__sys_alloc(size_t size)
{
	void *result = NewPtr (size);
	if (result == NULL) {
		fprintf (stderr, "# Jam Fatal error: Out of memory!\n");
		exit (1);
	}
	return result;
}
void	__sys_free(void * ptr)
{
	 DisposePtr((char*)ptr);
}
#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, 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);
	}
}
#endif

#ifdef GRAPHISOFT_MPW_FIX
#define mac_epoch_offset_  ((365L * 66L) + 17) * 24L * 60L * 60L     

void
file_dirscan( 
	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( 
	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( 
	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(
	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