The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

filent.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 1993, 1995 Christopher Seiwald.
00003  *
00004  * This file is part of Jam - see jam.c for Copyright information.
00005  */
00006 
00007 /*  This file is ALSO:
00008  *  (C) Copyright David Abrahams 2001. Permission to copy, use,
00009  *  modify, sell and distribute this software is granted provided this
00010  *  copyright notice appears in all copies. This software is provided
00011  *  "as is" without express or implied warranty, and with no claim as
00012  *  to its suitability for any purpose.
00013  */
00014 
00015 # include "jam.h"
00016 # include "filesys.h"
00017 # include "pathsys.h"
00018 # include "strings.h"
00019 
00020 # ifdef OS_NT
00021 
00022 # ifdef __BORLANDC__
00023 # if __BORLANDC__ < 0x550
00024 # include <dir.h>
00025 # include <dos.h>
00026 # endif
00027 # undef FILENAME        /* cpp namespace collision */
00028 # define _finddata_t ffblk
00029 # endif
00030 
00031 # include <io.h>
00032 # include <sys/stat.h>
00033 
00034 /*
00035  * filent.c - scan directories and archives on NT
00036  *
00037  * External routines:
00038  *
00039  *      file_dirscan() - scan a directory for files
00040  *      file_time() - get timestamp of file, if not done by file_dirscan()
00041  *      file_archscan() - scan an archive for files
00042  *
00043  * File_dirscan() and file_archscan() call back a caller provided function
00044  * for each file found.  A flag to this callback function lets file_dirscan()
00045  * and file_archscan() indicate that a timestamp is being provided with the
00046  * file.   If file_dirscan() or file_archscan() do not provide the file's
00047  * timestamp, interested parties may later call file_time().
00048  *
00049  * 07/10/95 (taylor)  Findfirst() returns the first file on NT.
00050  * 05/03/96 (seiwald) split apart into pathnt.c
00051  */
00052 
00053 /*
00054  * file_dirscan() - scan a directory for files
00055  */
00056 
00057 void
00058 file_dirscan( 
00059         char *dir,
00060         scanback func,
00061         void *closure )
00062 {
00063     PATHNAME f;
00064     string filespec[1];
00065     string filename[1];
00066     long handle;
00067     int ret;
00068     struct _finddata_t finfo[1];
00069 
00070     dir = short_path_to_long_path( dir );
00071         
00072     /* First enter directory itself */
00073 
00074     memset( (char *)&f, '\0', sizeof( f ) );
00075 
00076     f.f_dir.ptr = dir;
00077     f.f_dir.len = strlen(dir);
00078 
00079     dir = *dir ? dir : ".";
00080 
00081     /* Special case \ or d:\ : enter it */
00082  
00083     if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
00084         (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
00085     else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
00086         (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
00087 
00088     /* Now enter contents of directory */
00089 
00090     string_copy( filespec, dir );
00091     string_append( filespec, "/*" );
00092 
00093     if( DEBUG_BINDSCAN )
00094         printf( "scan directory %s\n", dir );
00095 
00096 # if defined(__BORLANDC__) && __BORLANDC__ < 0x550
00097     if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
00098     {
00099         string_free( filespec );
00100         return;
00101     }
00102 
00103     string_new( filename );
00104     while( !ret )
00105     {
00106         time_t time_write = finfo->ff_fdate;
00107 
00108         time_write = (time_write << 16) | finfo->ff_ftime;
00109         f.f_base.ptr = finfo->ff_name;
00110         f.f_base.len = strlen( finfo->ff_name );
00111 
00112         string_truncate( filename, 0 );
00113         path_build( &f, filename );
00114 
00115         (*func)( closure, filename->value, 1 /* stat()'ed */, time_write );
00116 
00117         ret = findnext( finfo );
00118     }
00119 # else
00120     handle = _findfirst( filespec->value, finfo );
00121 
00122     if( ret = ( handle < 0L ) )
00123     {
00124         string_free( filespec );
00125         return;
00126     }
00127         
00128     string_new( filename );
00129     while( !ret )
00130     {
00131         f.f_base.ptr = finfo->name;
00132         f.f_base.len = strlen( finfo->name );
00133 
00134         string_truncate( filename, 0 );
00135         path_build( &f, filename, 0 );
00136 
00137         (*func)( closure, filename->value, 1 /* stat()'ed */, finfo->time_write );
00138  
00139         ret = _findnext( handle, finfo );
00140     }
00141 
00142     _findclose( handle );
00143 # endif
00144     string_free( filename );
00145     string_free( filespec );
00146 }
00147 
00148 /*
00149  * file_time() - get timestamp of file, if not done by file_dirscan()
00150  */
00151 
00152 int
00153 file_time(
00154         char    *filename,
00155         time_t  *time )
00156 {
00157         /* On NT this is called only for C:/ */
00158 
00159         struct stat statbuf;
00160 
00161         if( stat( filename, &statbuf ) < 0 )
00162             return -1;
00163 
00164         *time = statbuf.st_mtime;
00165 
00166         return 0;
00167 }
00168 
00169 /*
00170  * file_archscan() - scan an archive for files
00171  */
00172 
00173 /* Straight from SunOS */
00174 
00175 #define ARMAG   "!<arch>\n"
00176 #define SARMAG  8
00177 
00178 #define ARFMAG  "`\n"
00179 
00180 struct ar_hdr {
00181         char    ar_name[16];
00182         char    ar_date[12];
00183         char    ar_uid[6];
00184         char    ar_gid[6];
00185         char    ar_mode[8];
00186         char    ar_size[10];
00187         char    ar_fmag[2];
00188 };
00189 
00190 # define SARFMAG 2
00191 # define SARHDR sizeof( struct ar_hdr )
00192 
00193 void
00194 file_archscan(
00195         char *archive,
00196         scanback func,
00197         void *closure )
00198 {
00199         struct ar_hdr ar_hdr;
00200         char *string_table = 0;
00201         char buf[ MAXJPATH ];
00202         long offset;
00203         int fd;
00204 
00205         if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
00206             return;
00207 
00208         if( read( fd, buf, SARMAG ) != SARMAG ||
00209             strncmp( ARMAG, buf, SARMAG ) )
00210         {
00211             close( fd );
00212             return;
00213         }
00214 
00215         offset = SARMAG;
00216 
00217         if( DEBUG_BINDSCAN )
00218             printf( "scan archive %s\n", archive );
00219 
00220         while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
00221                !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
00222         {
00223             long    lar_date;
00224             long    lar_size;
00225             char    *name = 0;
00226             char    *endname;
00227             char    *c;
00228 
00229             sscanf( ar_hdr.ar_date, "%ld", &lar_date );
00230             sscanf( ar_hdr.ar_size, "%ld", &lar_size );
00231 
00232             lar_size = ( lar_size + 1 ) & ~1;
00233 
00234             if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' )
00235             {
00236                 /* this is the "string table" entry of the symbol table,
00237                 ** which holds strings of filenames that are longer than
00238                 ** 15 characters (ie. don't fit into a ar_name
00239                 */
00240 
00241                 string_table = malloc(lar_size);
00242                 if (read(fd, string_table, lar_size) != lar_size)
00243                     printf("error reading string table\n");
00244                 offset += SARHDR + lar_size;
00245                 continue;
00246             }
00247             else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ')
00248             {
00249                 /* Long filenames are recognized by "/nnnn" where nnnn is
00250                 ** the offset of the string in the string table represented
00251                 ** in ASCII decimals.
00252                 */
00253 
00254                 name = string_table + atoi( ar_hdr.ar_name + 1 );
00255                 endname = name + strlen( name );
00256             }
00257             else
00258             {
00259                 /* normal name */
00260                 name = ar_hdr.ar_name;
00261                 endname = name + sizeof( ar_hdr.ar_name );
00262             }
00263 
00264             /* strip trailing space, slashes, and backslashes */
00265 
00266             while( endname-- > name )
00267                 if( *endname != ' ' && *endname != '\\' && *endname != '/' )
00268                     break;
00269             *++endname = 0;
00270 
00271             /* strip leading directory names, an NT specialty */
00272 
00273             if( c = strrchr( name, '/' ) )
00274                 name = c + 1;
00275             if( c = strrchr( name, '\\' ) )
00276                 name = c + 1;
00277 
00278             sprintf( buf, "%s(%.*s)", archive, endname - name, name );
00279             (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
00280 
00281             offset += SARHDR + lar_size;
00282             lseek( fd, offset, 0 );
00283         }
00284 
00285         close( fd );
00286 }
00287 
00288 # endif /* NT */

Generated on Mon Nov 8 17:07:34 2004 for MPT by  doxygen 1.3.9.1