]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/fileunix.c
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * Copyright 2001-2004 David Abrahams.
9 * Copyright 2005 Rene Rivera.
10 * Distributed under the Boost Software License, Version 1.0.
11 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
15 * fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS
18 * file_archscan() - scan an archive for files
19 * file_mkdir() - create a directory
20 * file_supported_fmt_resolution() - file modification timestamp resolution
22 * External routines called only via routines in filesys.c:
23 * file_collect_dir_content_() - collects directory content information
24 * file_dirscan_() - OS specific file_dirscan() implementation
25 * file_query_() - query information about a path from the OS
26 * file_collect_archive_content_() - collects information about archive members
27 * file_archivescan_() - OS specific file_archivescan() implementation
41 #include <sys/stat.h> /* needed for mkdir() */
43 #if defined( sun ) || defined( __sun ) || defined( linux )
44 # include <unistd.h> /* needed for read and close prototype */
47 #if defined( OS_SEQUENT ) || \
48 defined( OS_DGUX ) || \
49 defined( OS_SCO ) || \
54 #if defined( OS_RHAPSODY ) || defined( OS_MACOSX ) || defined( OS_NEXT )
56 # include <unistd.h> /* need unistd for rhapsody's proper lseek */
57 # define STRUCT_DIRENT struct direct
60 # define STRUCT_DIRENT struct dirent
68 #if defined( OS_MVS ) || defined( OS_INTERIX )
69 #define ARMAG "!<arch>\n"
74 struct ar_hdr
/* archive file member header - printable ascii */
76 char ar_name
[ 16 ]; /* file member name - `/' terminated */
77 char ar_date
[ 12 ]; /* file member date - decimal */
78 char ar_uid
[ 6 ]; /* file member user id - decimal */
79 char ar_gid
[ 6 ]; /* file member group id - decimal */
80 char ar_mode
[ 8 ]; /* file member mode - octal */
81 char ar_size
[ 10 ]; /* file member size - decimal */
82 char ar_fmag
[ 2 ]; /* ARFMAG - string to end header */
86 #if defined( OS_QNX ) || \
87 defined( OS_BEOS ) || \
88 defined( OS_HAIKU ) || \
96 /* Define these for AIX to get the definitions for both small and big archive
97 * file format variants.
107 * file_collect_dir_content_() - collects directory content information
110 int file_collect_dir_content_( file_info_t
* const d
)
115 STRUCT_DIRENT
** namelist
;
116 STRUCT_DIRENT
* dirent
;
122 assert( list_empty( d
->files
) );
124 dirstr
= object_str( d
->name
);
126 memset( (char *)&f
, '\0', sizeof( f
) );
127 f
.f_dir
.ptr
= dirstr
;
128 f
.f_dir
.len
= strlen( dirstr
);
130 if ( !*dirstr
) dirstr
= ".";
132 if ( -1 == ( n
= scandir( dirstr
, &namelist
, NULL
, alphasort
) ) )
139 dirent
= namelist
[ n
];
140 f
.f_base
.ptr
= dirent
->d_name
142 - 2 /* Broken structure definition on sinix. */
145 f
.f_base
.len
= strlen( f
.f_base
.ptr
);
147 string_truncate( path
, 0 );
148 path_build( &f
, path
);
149 name
= object_new( path
->value
);
150 /* Immediately stat the file to preserve invariants. */
151 if ( file_query( name
) )
152 files
= list_push_back( files
, name
);
167 * file_dirscan_() - OS specific file_dirscan() implementation
170 void file_dirscan_( file_info_t
* const d
, scanback func
, void * closure
)
175 /* Special case / : enter it */
176 if ( !strcmp( object_str( d
->name
), "/" ) )
177 (*func
)( closure
, d
->name
, 1 /* stat()'ed */, &d
->time
);
182 * file_mkdir() - create a directory
185 int file_mkdir( char const * const path
)
187 /* Explicit cast to remove const modifiers and avoid related compiler
188 * warnings displayed when using the intel compiler.
190 return mkdir( (char *)path
, 0777 );
195 * file_query_() - query information about a path from the OS
198 void file_query_( file_info_t
* const info
)
200 file_query_posix_( info
);
205 * file_supported_fmt_resolution() - file modification timestamp resolution
207 * Returns the minimum file modification timestamp resolution supported by this
208 * Boost Jam implementation. File modification timestamp changes of less than
209 * the returned value might not be recognized.
211 * Does not take into consideration any OS or file system related restrictions.
213 * Return value 0 indicates that any value supported by the OS is also supported
217 void file_supported_fmt_resolution( timestamp
* const t
)
219 /* The current implementation does not support file modification timestamp
220 * resolution of less than one second.
222 timestamp_init( t
, 1, 0 );
225 int file_collect_archive_content_( file_archive_info_t
* const archive
);
228 * file_archscan() - scan an archive for files
230 void file_archscan( char const * arch
, scanback func
, void * closure
)
232 OBJECT
* path
= object_new( arch
);
233 file_archive_info_t
* archive
= file_archive_query( path
);
237 if ( filelist_empty( archive
->members
) )
239 if ( file_collect_archive_content_( archive
) < 0 )
243 /* Report the collected archive content. */
245 FILELISTITER iter
= filelist_begin( archive
->members
);
246 FILELISTITER
const end
= filelist_end( archive
->members
);
247 char buf
[ MAXJPATH
];
249 for ( ; iter
!= end
; iter
= filelist_next( iter
) )
251 file_info_t
* member_file
= filelist_item( iter
);
252 LIST
* symbols
= member_file
->files
;
254 /* Construct member path: 'archive-path(member-name)'
256 sprintf( buf
, "%s(%s)",
257 object_str( archive
->file
->name
),
258 object_str( member_file
->name
) );
260 OBJECT
* const member
= object_new( buf
);
261 (*func
)( closure
, member
, 1 /* time valid */, &member_file
->time
);
262 object_free( member
);
270 * file_archivescan_() - OS specific file_archivescan() implementation
273 void file_archivescan_( file_archive_info_t
* const archive
, archive_scanback func
,
280 * file_collect_archive_content_() - collects information about archive members
283 #ifndef AIAMAG /* God-fearing UNIX */
286 #define SARHDR sizeof( struct ar_hdr )
288 int file_collect_archive_content_( file_archive_info_t
* const archive
)
291 struct ar_hdr ar_hdr
;
292 char * string_table
= 0;
293 char buf
[ MAXJPATH
];
296 const char * path
= object_str( archive
->file
->name
);
298 if ( ! filelist_empty( archive
->members
) ) filelist_free( archive
->members
);
300 if ( ( fd
= open( path
, O_RDONLY
, 0 ) ) < 0 )
303 if ( read( fd
, buf
, SARMAG
) != SARMAG
||
304 strncmp( ARMAG
, buf
, SARMAG
) )
312 if ( DEBUG_BINDSCAN
)
313 out_printf( "scan archive %s\n", path
);
315 while ( ( read( fd
, &ar_hdr
, SARHDR
) == SARHDR
) &&
316 !( memcmp( ar_hdr
.ar_fmag
, ARFMAG
, SARFMAG
)
318 /* OSF also has a compressed format */
319 && memcmp( ar_hdr
.ar_fmag
, ARFZMAG
, SARFMAG
)
323 char lar_name_
[ 257 ];
324 char * lar_name
= lar_name_
+ 1;
332 strncpy( lar_name
, ar_hdr
.ar_name
, sizeof( ar_hdr
.ar_name
) );
334 sscanf( ar_hdr
.ar_date
, "%ld", &lar_date
);
335 sscanf( ar_hdr
.ar_size
, "%ld", &lar_size
);
337 if ( ar_hdr
.ar_name
[ 0 ] == '/' )
339 if ( ar_hdr
.ar_name
[ 1 ] == '/' )
341 /* This is the "string table" entry of the symbol table, holding
342 * filename strings longer than 15 characters, i.e. those that
343 * do not fit into ar_name.
345 string_table
= (char *)BJAM_MALLOC_ATOMIC( lar_size
);
346 lseek( fd
, offset
+ SARHDR
, 0 );
347 if ( read( fd
, string_table
, lar_size
) != lar_size
)
348 out_printf("error reading string table\n");
350 else if ( string_table
&& ar_hdr
.ar_name
[ 1 ] != ' ' )
352 /* Long filenames are recognized by "/nnnn" where nnnn is the
353 * offset of the string in the string table represented in ASCII
357 lar_offset
= atoi( lar_name
+ 1 );
358 src
= &string_table
[ lar_offset
];
359 while ( *src
!= '/' )
366 while ( ( *++c
!= ' ' ) && ( *c
!= '/' ) );
369 if ( DEBUG_BINDSCAN
)
370 out_printf( "archive name %s found\n", lar_name
);
372 sprintf( buf
, "%s", lar_name
);
374 if ( strcmp( buf
, "") != 0 )
376 file_info_t
* member
= 0;
378 archive
->members
= filelist_push_back( archive
->members
, object_new( buf
) );
379 member
= filelist_back( archive
->members
);
383 timestamp_init( &member
->time
, (time_t)lar_date
, 0 );
386 offset
+= SARHDR
+ ( ( lar_size
+ 1 ) & ~1 );
387 lseek( fd
, offset
, 0 );
391 BJAM_FREE( string_table
);
399 #else /* AIAMAG - RS6000 AIX */
401 static void collect_archive_content_small( int fd
, file_archive_info_t
* const archive
)
403 struct fl_hdr fl_hdr
;
410 char buf
[ MAXJPATH
];
412 const char * path
= object_str( archive
->file
->name
);
414 if ( read( fd
, (char *)&fl_hdr
, FL_HSZ
) != FL_HSZ
)
417 sscanf( fl_hdr
.fl_fstmoff
, "%ld", &offset
);
419 if ( DEBUG_BINDSCAN
)
420 out_printf( "scan archive %s\n", path
);
422 while ( offset
> 0 && lseek( fd
, offset
, 0 ) >= 0 &&
423 read( fd
, &ar_hdr
, sizeof( ar_hdr
) ) >= (int)sizeof( ar_hdr
.hdr
) )
428 sscanf( ar_hdr
.hdr
.ar_namlen
, "%d" , &lar_namlen
);
429 sscanf( ar_hdr
.hdr
.ar_date
, "%ld", &lar_date
);
430 sscanf( ar_hdr
.hdr
.ar_nxtmem
, "%ld", &offset
);
435 ar_hdr
.hdr
._ar_name
.ar_name
[ lar_namlen
] = '\0';
437 sprintf( buf
, "%s", ar_hdr
.hdr
._ar_name
.ar_name
);
439 if ( strcmp( buf
, "") != 0 )
441 file_info_t
* member
= 0;
443 archive
->members
= filelist_push_back( archive
->members
, object_new( buf
) );
444 member
= filelist_back( archive
->members
);
448 timestamp_init( &member
->time
, (time_t)lar_date
, 0 );
453 /* Check for OS versions supporting the big variant. */
456 static void collect_archive_content_big( int fd
, file_archive_info_t
* const archive
)
458 struct fl_hdr_big fl_hdr
;
461 struct ar_hdr_big hdr
;
465 char buf
[ MAXJPATH
];
467 const char * path
= object_str( archive
->file
->name
);
469 if ( read( fd
, (char *)&fl_hdr
, FL_HSZ_BIG
) != FL_HSZ_BIG
)
472 sscanf( fl_hdr
.fl_fstmoff
, "%lld", &offset
);
474 if ( DEBUG_BINDSCAN
)
475 out_printf( "scan archive %s\n", path
);
477 while ( offset
> 0 && lseek( fd
, offset
, 0 ) >= 0 &&
478 read( fd
, &ar_hdr
, sizeof( ar_hdr
) ) >= sizeof( ar_hdr
.hdr
) )
483 sscanf( ar_hdr
.hdr
.ar_namlen
, "%d" , &lar_namlen
);
484 sscanf( ar_hdr
.hdr
.ar_date
, "%ld" , &lar_date
);
485 sscanf( ar_hdr
.hdr
.ar_nxtmem
, "%lld", &offset
);
490 ar_hdr
.hdr
._ar_name
.ar_name
[ lar_namlen
] = '\0';
492 sprintf( buf
, "%s", ar_hdr
.hdr
._ar_name
.ar_name
);
494 if ( strcmp( buf
, "") != 0 )
496 file_info_t
* member
= 0;
498 archive
->members
= filelist_push_back( archive
->members
, object_new( buf
) );
499 member
= filelist_back( archive
->members
);
503 timestamp_init( &member
->time
, (time_t)lar_date
, 0 );
508 #endif /* AR_HSZ_BIG */
510 int file_collect_archive_content_( file_archive_info_t
* const archive
)
513 char fl_magic
[ SAIAMAG
];
514 const char * path
= object_str( archive
->file
->name
);
516 if ( ! filelist_empty( archive
->members
) ) filelist_free( archive
->members
);
518 if ( ( fd
= open( path
, O_RDONLY
, 0 ) ) < 0 )
521 if ( read( fd
, fl_magic
, SAIAMAG
) != SAIAMAG
||
522 lseek( fd
, 0, SEEK_SET
) == -1 )
528 if ( !strncmp( AIAMAG
, fl_magic
, SAIAMAG
) )
530 /* read small variant */
531 collect_archive_content_small( fd
, archive
);
534 else if ( !strncmp( AIAMAGBIG
, fl_magic
, SAIAMAG
) )
536 /* read big variant */
537 collect_archive_content_big( fd
, archive
);
546 #endif /* AIAMAG - RS6000 AIX */
548 #endif /* USE_FILEUNIX */