]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/filevms.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 * Copyright 2015 Artur Shepilko.
11 * Distributed under the Boost Software License, Version 1.0.
12 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
27 * filevms.c - manipulate file names and scan directories on VMS.
29 * This implementation is based on POSIX-style path manipulation.
31 * VMS CTRL directly supports both POSIX- and native VMS-style path expressions,
32 * with the POSIX-to-VMS path translation performed internally by the same
33 * set of functions. For the most part such processing is transparent, with
34 * few differences mainly related to file versions (in POSIX mode only the recent
35 * version is visible).
37 * This should allow us to re-use fileunix.c implementation,
38 * excluding archive/library member processing.
40 * Thus in jam-files the path references can also remain POSIX/UNIX-style on all
41 * levels EXCEPT in actions scope, where these must be translated to the native
42 * VMS-style. This approach is somewhat similar to jam CYGWIN handling.
46 * file_archscan() - scan an archive for files
47 * file_mkdir() - create a directory
48 * file_supported_fmt_resolution() - file modification timestamp resolution
50 * External routines called only via routines in filesys.c:
51 * file_collect_dir_content_() - collects directory content information
52 * file_dirscan_() - OS specific file_dirscan() implementation
53 * file_query_() - query information about a path from the OS
54 * file_collect_archive_content_() - collects information about archive members
55 * file_archivescan_() - OS specific file_archivescan() implementation
61 #include <sys/stat.h> /* needed for mkdir() */
62 #include <unistd.h> /* needed for read and close prototype */
65 #define STRUCT_DIRENT struct dirent
68 void path_translate_to_os_( char const * f
, string
* file
);
71 * file_collect_dir_content_() - collects directory content information
74 int file_collect_dir_content_( file_info_t
* const d
)
79 STRUCT_DIRENT
* dirent
;
85 assert( list_empty( d
->files
) );
87 dirstr
= object_str( d
->name
);
89 memset( (char *)&f
, '\0', sizeof( f
) );
91 f
.f_dir
.len
= strlen( dirstr
);
93 if ( !*dirstr
) dirstr
= ".";
95 if ( !( dd
= opendir( dirstr
) ) )
99 while ( ( dirent
= readdir( dd
) ) )
102 f
.f_base
.ptr
= dirent
->d_name
104 - 2 /* Broken structure definition on sinix. */
107 f
.f_base
.len
= strlen( f
.f_base
.ptr
);
109 string_truncate( path
, 0 );
110 path_build( &f
, path
);
111 name
= object_new( path
->value
);
112 /* Immediately stat the file to preserve invariants. */
113 if ( file_query( name
) )
114 files
= list_push_back( files
, name
);
128 * file_dirscan_() - OS specific file_dirscan() implementation
131 void file_dirscan_( file_info_t
* const d
, scanback func
, void * closure
)
136 /* Special case / : enter it */
137 if ( !strcmp( object_str( d
->name
), "/" ) )
138 (*func
)( closure
, d
->name
, 1 /* stat()'ed */, &d
->time
);
143 * file_mkdir() - create a directory
146 int file_mkdir( char const * const path
)
148 /* Explicit cast to remove const modifiers and avoid related compiler
149 * warnings displayed when using the intel compiler.
151 return mkdir( (char *)path
, 0777 );
156 * file_query_() - query information about a path from the OS
159 void file_query_( file_info_t
* const info
)
161 file_query_posix_( info
);
165 /*------------------------------------------------------------------------------
166 * VMS-specific processing:
175 #include <lib$routines.h>
178 /* Supply missing prototypes for lbr$-routines*/
182 #endif /* __cplusplus */
187 struct dsc$descriptor_s
*,
191 int lbr$
open( void **,
192 struct dsc$descriptor_s
*,
207 unsigned long * const,
208 int (*func
)( struct dsc$descriptor_s
*, unsigned long *),
213 unsigned long * const,
215 int (*func
)( struct dsc$descriptor_s
*, unsigned long *),
223 #endif /* __cplusplus */
229 unsigned int *curtime
,
232 static const size_t divisor
= 10000000;
233 static unsigned int bastim
[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */
234 int delta
[2], remainder
;
236 lib$
subx( curtime
, bastim
, delta
);
237 lib$
ediv( &divisor
, delta
, unixtime
, &remainder
);
241 static void downcase_inplace( char * p
)
248 static file_archive_info_t
* m_archive
= NULL
;
249 static file_info_t
* m_member_found
= NULL
;
250 static void * m_lbr_context
= NULL
;
251 static unsigned short * m_rfa_found
= NULL
;
252 static const unsigned long LBR_MODINDEX_NUM
= 1,
253 LBR_SYMINDEX_NUM
= 2; /* GST:global symbol table */
256 static unsigned int set_archive_symbol( struct dsc$descriptor_s
*symbol
,
259 file_info_t
* member
= m_member_found
;
260 char buf
[ MAXJPATH
] = { 0 };
262 strncpy(buf
, symbol
->dsc$a_pointer
, symbol
->dsc$w_length
);
263 buf
[ symbol
->dsc$w_length
] = 0;
265 member
->files
= list_push_back( member
->files
, object_new( buf
) );
267 return ( 1 ); /* continue */
271 static unsigned int set_archive_member( struct dsc$descriptor_s
*module
,
274 file_archive_info_t
* archive
= m_archive
;
276 static struct dsc$descriptor_s bufdsc
=
277 {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, NULL
};
280 char filename
[128] = { 0 };
281 char buf
[ MAXJPATH
] = { 0 };
289 bufdsc
.dsc$a_pointer
= filename
;
290 bufdsc
.dsc$w_length
= sizeof( filename
);
291 status
= lbr$
set_module( &m_lbr_context
, rfa
, &bufdsc
,
292 &bufdsc
.dsc$w_length
, NULL
);
295 return ( 1 ); /* continue */
297 mhd
= (struct mhddef
*)filename
;
299 file_cvttime( &mhd
->mhd$l_datim
, &library_date
);
301 /* strncpy( filename, module->dsc$a_pointer, module->dsc$w_length );
303 for ( i
= 0, p
= module
->dsc$a_pointer
; i
< module
->dsc$w_length
; ++i
, ++p
)
306 filename
[ i
] = '\0';
308 if ( strcmp( filename
, "" ) != 0 )
310 file_info_t
* member
= 0;
312 /* Construct member's filename as lowercase "module.obj" */
313 sprintf( buf
, "%s.obj", filename
);
314 downcase_inplace( buf
);
315 archive
->members
= filelist_push_back( archive
->members
, object_new( buf
) );
317 member
= filelist_back( archive
->members
);
321 timestamp_init( &member
->time
, (time_t)library_date
, 0 );
323 m_member_found
= member
;
325 status
= lbr$
search(&m_lbr_context
, &LBR_SYMINDEX_NUM
, m_rfa_found
, set_archive_symbol
, NULL
);
328 return ( 1 ); /* continue */
333 void file_archscan( char const * arch
, scanback func
, void * closure
)
335 OBJECT
* path
= object_new( arch
);
336 file_archive_info_t
* archive
= file_archive_query( path
);
340 if ( filelist_empty( archive
->members
) )
342 if ( DEBUG_BINDSCAN
)
343 out_printf( "scan archive %s\n", object_str( archive
->file
->name
) );
345 if ( file_collect_archive_content_( archive
) < 0 )
349 /* Report the collected archive content. */
351 FILELISTITER iter
= filelist_begin( archive
->members
);
352 FILELISTITER
const end
= filelist_end( archive
->members
);
353 char buf
[ MAXJPATH
];
355 for ( ; iter
!= end
; iter
= filelist_next( iter
) )
357 file_info_t
* member_file
= filelist_item( iter
);
358 LIST
* symbols
= member_file
->files
;
360 /* Construct member path: 'archive-path(member-name)'
362 sprintf( buf
, "%s(%s)",
363 object_str( archive
->file
->name
),
364 object_str( member_file
->name
) );
366 OBJECT
* const member
= object_new( buf
);
367 (*func
)( closure
, member
, 1 /* time valid */, &member_file
->time
);
368 object_free( member
);
376 * file_archivescan_() - OS specific file_archivescan() implementation
378 void file_archivescan_( file_archive_info_t
* const archive
, archive_scanback func
,
385 * file_collect_archive_content_() - collects information about archive members
388 int file_collect_archive_content_( file_archive_info_t
* const archive
)
390 unsigned short rfa
[3];
392 static struct dsc$descriptor_s library
=
393 {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, NULL
};
395 unsigned long lfunc
= LBR$C_READ
;
396 unsigned long typ
= LBR$C_TYP_UNK
;
400 char vmspath
[ MAXJPATH
] = { 0 };
404 if ( ! filelist_empty( archive
->members
) ) filelist_free( archive
->members
);
406 /* Translate path to VMS
409 path_translate_to_os_( object_str( archive
->file
->name
), buf
);
410 strcpy( vmspath
, buf
->value
);
414 status
= lbr$
ini_control( &m_lbr_context
, &lfunc
, &typ
, NULL
);
415 if ( !( status
& 1 ) )
418 library
.dsc$a_pointer
= vmspath
;
419 library
.dsc$w_length
= strlen( vmspath
);
421 status
= lbr$
open( &m_lbr_context
, &library
, NULL
, NULL
, NULL
, NULL
, NULL
);
422 if ( !( status
& 1 ) )
425 /* Scan main index for modules.
426 * For each module search symbol-index to collect module's symbols.
428 status
= lbr$
get_index( &m_lbr_context
, &LBR_MODINDEX_NUM
, set_archive_member
, NULL
);
430 if ( !( status
& 1 ) )
434 (void) lbr$
close( &m_lbr_context
);