1/*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*
8 * filemac.c - manipulate file names and scan directories on macintosh
9 *
10 * External routines:
11 *
12 *	file_dirscan() - scan a directory for files
13 *	file_time() - get timestamp of file, if not done by file_dirscan()
14 *	file_archscan() - scan an archive for files
15 *
16 * File_dirscan() and file_archscan() call back a caller provided function
17 * for each file found.  A flag to this callback function lets file_dirscan()
18 * and file_archscan() indicate that a timestamp is being provided with the
19 * file.   If file_dirscan() or file_archscan() do not provide the file's
20 * timestamp, interested parties may later call file_time().
21 *
22 * 04/08/94 (seiwald) - Coherent/386 support added.
23 * 12/19/94 (mikem) - solaris string table insanity support
24 * 02/14/95 (seiwald) - parse and build /xxx properly
25 * 05/03/96 (seiwald) - split into pathunix.c
26 * 11/21/96 (peterk) - BEOS does not have Unix-style archives
27 * 01/21/00 (malyn) - divorced from GUSI
28 * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan
29 * 11/04/02 (seiwald) - const-ing for string literals
30 */
31
32# include "jam.h"
33# include "filesys.h"
34# include "pathsys.h"
35
36# ifdef OS_MAC
37
38#include <Files.h>
39#include <Folders.h>
40
41# include <:sys:stat.h>
42
43void CopyC2PStr(const char * cstr, StringPtr pstr)
44{
45	int	len;
46
47	for (len = 0; *cstr && len<255; pstr[++len] = *cstr++)
48		;
49
50	pstr[0] = len;
51}
52
53/*
54 * file_dirscan() - scan a directory for files
55 */
56
57void
58file_dirscan(
59	const char *dir,
60	scanback func,
61	void	*closure )
62{
63	PATHNAME f;
64	char filename[ MAXJPATH ];
65	unsigned char fullPath[ 512 ];
66
67	FSSpec spec;
68	WDPBRec vol;
69	Str63 volName;
70	CInfoPBRec lastInfo;
71	int index = 1;
72
73	/* First enter directory itself */
74
75	memset( (char *)&f, '\0', sizeof( f ) );
76
77	f.f_dir.ptr = dir;
78	f.f_dir.len = strlen(dir);
79
80	if( DEBUG_BINDSCAN )
81	    printf( "scan directory %s\n", dir );
82
83	/* Special case ":" - enter it */
84
85	if( f.f_dir.len == 1 && f.f_dir.ptr[0] == ':' )
86	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
87
88	/* Now enter contents of directory */
89
90	vol.ioNamePtr = volName;
91
92	if( PBHGetVolSync( &vol ) )
93		return;
94
95	CopyC2PStr( dir, fullPath );
96
97	if( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) )
98		return;
99
100      	lastInfo.dirInfo.ioVRefNum 	= spec.vRefNum;
101   	lastInfo.dirInfo.ioDrDirID 	= spec.parID;
102   	lastInfo.dirInfo.ioNamePtr 	= spec.name;
103   	lastInfo.dirInfo.ioFDirIndex 	= 0;
104   	lastInfo.dirInfo.ioACUser 	= 0;
105
106   	if( PBGetCatInfoSync(&lastInfo) )
107		return;
108
109	if (!(lastInfo.dirInfo.ioFlAttrib & 0x10))
110		return;
111
112	// ioDrDirID must be reset each time.
113
114	spec.parID = lastInfo.dirInfo.ioDrDirID;
115
116	for( ;; )
117	{
118       	    lastInfo.dirInfo.ioVRefNum 	= spec.vRefNum;
119	    lastInfo.dirInfo.ioDrDirID	= spec.parID;
120	    lastInfo.dirInfo.ioNamePtr 	= fullPath;
121	    lastInfo.dirInfo.ioFDirIndex = index++;
122
123	    if( PBGetCatInfoSync(&lastInfo) )
124		return;
125
126	    f.f_base.ptr = (char *)fullPath + 1;
127	    f.f_base.len = *fullPath;
128
129	    path_build( &f, filename, 0 );
130
131	    (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 );
132	}
133}
134
135/*
136 * file_time() - get timestamp of file, if not done by file_dirscan()
137 */
138
139int
140file_time(
141	const char *filename,
142	time_t	*time )
143{
144	struct stat statbuf;
145
146	if( stat( filename, &statbuf ) < 0 )
147	    return -1;
148
149	*time = statbuf.st_mtime;
150
151	return 0;
152}
153
154/*
155 * file_archscan() - scan an archive for files
156 */
157
158void
159file_archscan(
160	const char *archive,
161	scanback func,
162	void	*closure )
163{
164}
165
166
167# endif /* macintosh */
168
169