Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/jam_src/filent.c @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 6.6 KB
Line 
1/*
2 * Copyright 1993, 1995 Christopher Seiwald.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*  This file is ALSO:
8 *  Copyright 2001-2004 David Abrahams.
9 *  Distributed under the Boost Software License, Version 1.0.
10 *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11 */
12
13# include "jam.h"
14# include "filesys.h"
15# include "pathsys.h"
16# include "strings.h"
17
18# ifdef OS_NT
19
20# ifdef __BORLANDC__
21# if __BORLANDC__ < 0x550
22# include <dir.h>
23# include <dos.h>
24# endif
25# undef FILENAME        /* cpp namespace collision */
26# define _finddata_t ffblk
27# endif
28
29# include <io.h>
30# include <sys/stat.h>
31# include <ctype.h>
32
33/*
34 * filent.c - scan directories and archives on NT
35 *
36 * External routines:
37 *
38 *      file_dirscan() - scan a directory for files
39 *      file_time() - get timestamp of file, if not done by file_dirscan()
40 *      file_archscan() - scan an archive for files
41 *
42 * File_dirscan() and file_archscan() call back a caller provided function
43 * for each file found.  A flag to this callback function lets file_dirscan()
44 * and file_archscan() indicate that a timestamp is being provided with the
45 * file.   If file_dirscan() or file_archscan() do not provide the file's
46 * timestamp, interested parties may later call file_time().
47 *
48 * 07/10/95 (taylor)  Findfirst() returns the first file on NT.
49 * 05/03/96 (seiwald) split apart into pathnt.c
50 */
51
52/*
53 * file_dirscan() - scan a directory for files
54 */
55
56void
57file_dirscan(
58        char *dir,
59        scanback func,
60        void *closure )
61{
62    PATHNAME f;
63    string filespec[1];
64    string filename[1];
65    long handle;
66    int ret;
67    struct _finddata_t finfo[1];
68
69    dir = short_path_to_long_path( dir );
70
71    /* First enter directory itself */
72
73    memset( (char *)&f, '\0', sizeof( f ) );
74
75    f.f_dir.ptr = dir;
76    f.f_dir.len = strlen(dir);
77
78    dir = *dir ? dir : ".";
79
80    /* Special case \ or d:\ : enter it */
81
82    if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
83        (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
84    else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
85        (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
86
87    /* Now enter contents of directory */
88
89    string_copy( filespec, dir );
90    string_append( filespec, "/*" );
91
92    if( DEBUG_BINDSCAN )
93        printf( "scan directory %s\n", dir );
94
95# if defined(__BORLANDC__) && __BORLANDC__ < 0x550
96    if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
97    {
98        string_free( filespec );
99        return;
100    }
101
102    string_new( filename );
103    while( !ret )
104    {
105        time_t time_write = finfo->ff_fdate;
106
107        time_write = (time_write << 16) | finfo->ff_ftime;
108        f.f_base.ptr = finfo->ff_name;
109        f.f_base.len = strlen( finfo->ff_name );
110
111        string_truncate( filename, 0 );
112        path_build( &f, filename );
113
114        (*func)( closure, filename->value, 1 /* stat()'ed */, time_write );
115
116        ret = findnext( finfo );
117    }
118# else
119    handle = _findfirst( filespec->value, finfo );
120
121    if( ret = ( handle < 0L ) )
122    {
123        string_free( filespec );
124        return;
125    }
126
127    string_new( filename );
128    while( !ret )
129    {
130        f.f_base.ptr = finfo->name;
131        f.f_base.len = strlen( finfo->name );
132
133        string_truncate( filename, 0 );
134        path_build( &f, filename, 0 );
135
136        (*func)( closure, filename->value, 1 /* stat()'ed */, finfo->time_write );
137
138        ret = _findnext( handle, finfo );
139    }
140
141    _findclose( handle );
142# endif
143    string_free( filename );
144    string_free( filespec );
145}
146
147/*
148 * file_time() - get timestamp of file, if not done by file_dirscan()
149 */
150
151int
152file_time(
153        char    *filename,
154        time_t  *time )
155{
156        /* On NT this is called only for C:/ */
157
158        struct stat statbuf;
159
160        if( stat( filename, &statbuf ) < 0 )
161            return -1;
162
163        *time = statbuf.st_mtime;
164
165        return 0;
166}
167
168int file_is_file(char* filename)
169{
170        struct stat statbuf;
171
172        if( stat( filename, &statbuf ) < 0 )
173            return -1;
174
175    if (statbuf.st_mode & S_IFREG) 
176        return 1;
177    else
178        return 0;   
179}
180
181
182/*
183 * file_archscan() - scan an archive for files
184 */
185
186/* Straight from SunOS */
187
188#define ARMAG   "!<arch>\n"
189#define SARMAG  8
190
191#define ARFMAG  "`\n"
192
193struct ar_hdr {
194        char    ar_name[16];
195        char    ar_date[12];
196        char    ar_uid[6];
197        char    ar_gid[6];
198        char    ar_mode[8];
199        char    ar_size[10];
200        char    ar_fmag[2];
201};
202
203# define SARFMAG 2
204# define SARHDR sizeof( struct ar_hdr )
205
206void
207file_archscan(
208        char *archive,
209        scanback func,
210        void *closure )
211{
212        struct ar_hdr ar_hdr;
213        char *string_table = 0;
214        char buf[ MAXJPATH ];
215        long offset;
216        int fd;
217
218        if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
219            return;
220
221        if( read( fd, buf, SARMAG ) != SARMAG ||
222            strncmp( ARMAG, buf, SARMAG ) )
223        {
224            close( fd );
225            return;
226        }
227
228        offset = SARMAG;
229
230        if( DEBUG_BINDSCAN )
231            printf( "scan archive %s\n", archive );
232
233        while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
234               !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
235        {
236            long    lar_date;
237            long    lar_size;
238            char    *name = 0;
239            char    *endname;
240            char    *c;
241
242            sscanf( ar_hdr.ar_date, "%ld", &lar_date );
243            sscanf( ar_hdr.ar_size, "%ld", &lar_size );
244
245            lar_size = ( lar_size + 1 ) & ~1;
246
247            if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' )
248            {
249                /* this is the "string table" entry of the symbol table,
250                ** which holds strings of filenames that are longer than
251                ** 15 characters (ie. don't fit into a ar_name
252                */
253
254                string_table = malloc(lar_size+1);
255                if (read(fd, string_table, lar_size) != lar_size)
256                    printf("error reading string table\n");
257                string_table[lar_size] = '\0';
258                offset += SARHDR + lar_size;
259                continue;
260            }
261            else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ')
262            {
263                /* Long filenames are recognized by "/nnnn" where nnnn is
264                ** the offset of the string in the string table represented
265                ** in ASCII decimals.
266                */
267
268                name = string_table + atoi( ar_hdr.ar_name + 1 );
269                for ( endname = name; *endname && *endname != '\n'; ++endname) {}
270            }
271            else
272            {
273                /* normal name */
274                name = ar_hdr.ar_name;
275                endname = name + sizeof( ar_hdr.ar_name );
276            }
277
278            /* strip trailing white-space, slashes, and backslashes */
279
280            while( endname-- > name )
281                if( !isspace(*endname) && *endname != '\\' && *endname != '/' )
282                    break;
283            *++endname = 0;
284
285            /* strip leading directory names, an NT specialty */
286
287            if( c = strrchr( name, '/' ) )
288                name = c + 1;
289            if( c = strrchr( name, '\\' ) )
290                name = c + 1;
291
292            sprintf( buf, "%s(%.*s)", archive, endname - name, name );
293            (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
294
295            offset += SARHDR + lar_size;
296            lseek( fd, offset, 0 );
297        }
298
299        close( fd );
300}
301
302# endif /* NT */
Note: See TracBrowser for help on using the repository browser.