diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/boost/tools/build/src/engine/filevms.cpp | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/tools/build/src/engine/filevms.cpp')
-rw-r--r-- | src/boost/tools/build/src/engine/filevms.cpp | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/src/boost/tools/build/src/engine/filevms.cpp b/src/boost/tools/build/src/engine/filevms.cpp new file mode 100644 index 000000000..6dc84ae63 --- /dev/null +++ b/src/boost/tools/build/src/engine/filevms.cpp @@ -0,0 +1,440 @@ +/* + * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. + * + * This file is part of Jam - see jam.c for Copyright information. + */ + +/* This file is ALSO: + * Copyright 2001-2004 David Abrahams. + * Copyright 2005 Rene Rivera. + * Copyright 2015 Artur Shepilko. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) + */ + + +#include "jam.h" +#include "filesys.h" + +#include "object.h" +#include "pathsys.h" +#include "jam_strings.h" + + +#ifdef OS_VMS + +/* + * filevms.c - manipulate file names and scan directories on VMS. + * + * This implementation is based on POSIX-style path manipulation. + * + * VMS CTRL directly supports both POSIX- and native VMS-style path expressions, + * with the POSIX-to-VMS path translation performed internally by the same + * set of functions. For the most part such processing is transparent, with + * few differences mainly related to file versions (in POSIX mode only the recent + * version is visible). + * + * This should allow us to re-use fileunix.c implementation, + * excluding archive/library member processing. + * + * Thus in jam-files the path references can also remain POSIX/UNIX-style on all + * levels EXCEPT in actions scope, where these must be translated to the native + * VMS-style. This approach is somewhat similar to jam CYGWIN handling. + * + * + * External routines: + * file_archscan() - scan an archive for files + * file_mkdir() - create a directory + * file_supported_fmt_resolution() - file modification timestamp resolution + * + * External routines called only via routines in filesys.c: + * file_collect_dir_content_() - collects directory content information + * file_dirscan_() - OS specific file_dirscan() implementation + * file_query_() - query information about a path from the OS + * file_collect_archive_content_() - collects information about archive members + * file_archivescan_() - OS specific file_archivescan() implementation + */ + +#include <assert.h> +#include <stdio.h> + +#include <sys/stat.h> /* needed for mkdir() */ +#include <unistd.h> /* needed for read and close prototype */ + +#include <dirent.h> +#define STRUCT_DIRENT struct dirent + + +void path_translate_to_os_( char const * f, string * file ); + +/* + * file_collect_dir_content_() - collects directory content information + */ + +int file_collect_dir_content_( file_info_t * const d ) +{ + LIST * files = L0; + PATHNAME f; + DIR * dd; + STRUCT_DIRENT * dirent; + string path[ 1 ]; + char const * dirstr; + + assert( d ); + assert( d->is_dir ); + assert( list_empty( d->files ) ); + + dirstr = object_str( d->name ); + + memset( (char *)&f, '\0', sizeof( f ) ); + f.f_dir.ptr = dirstr; + f.f_dir.len = strlen( dirstr ); + + if ( !*dirstr ) dirstr = "."; + + if ( !( dd = opendir( dirstr ) ) ) + return -1; + + string_new( path ); + while ( ( dirent = readdir( dd ) ) ) + { + OBJECT * name; + f.f_base.ptr = dirent->d_name + #ifdef old_sinix + - 2 /* Broken structure definition on sinix. */ + #endif + ; + f.f_base.len = strlen( f.f_base.ptr ); + + string_truncate( path, 0 ); + path_build( &f, path ); + name = object_new( path->value ); + /* Immediately stat the file to preserve invariants. */ + if ( file_query( name ) ) + files = list_push_back( files, name ); + else + object_free( name ); + } + string_free( path ); + + closedir( dd ); + + d->files = files; + return 0; +} + + +/* + * file_dirscan_() - OS specific file_dirscan() implementation + */ + +void file_dirscan_( file_info_t * const d, scanback func, void * closure ) +{ + assert( d ); + assert( d->is_dir ); + + /* Special case / : enter it */ + if ( !strcmp( object_str( d->name ), "/" ) ) + (*func)( closure, d->name, 1 /* stat()'ed */, &d->time ); +} + + +/* + * file_mkdir() - create a directory + */ + +int file_mkdir( char const * const path ) +{ + /* Explicit cast to remove const modifiers and avoid related compiler + * warnings displayed when using the intel compiler. + */ + return mkdir( (char *)path, 0777 ); +} + + +/* + * file_query_() - query information about a path from the OS + */ + +void file_query_( file_info_t * const info ) +{ + file_query_posix_( info ); +} + + +/*------------------------------------------------------------------------------ +* VMS-specific processing: +* +*/ + +#include <descrip.h> +#include <lbrdef.h> +#include <credef.h> +#include <mhddef.h> +#include <lhidef.h> +#include <lib$routines.h> +#include <starlet.h> + +/* Supply missing prototypes for lbr$-routines*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int lbr$set_module( + void **, + unsigned long *, + struct dsc$descriptor_s *, + unsigned short *, + void * ); + +int lbr$open( void **, + struct dsc$descriptor_s *, + void *, + void *, + void *, + void *, + void * ); + +int lbr$ini_control( + void **, + unsigned long *, + unsigned long *, + void * ); + +int lbr$get_index( + void **, + unsigned long * const, + int (*func)( struct dsc$descriptor_s *, unsigned long *), + void * ); + +int lbr$search( + void **, + unsigned long * const, + unsigned short *, + int (*func)( struct dsc$descriptor_s *, unsigned long *), + unsigned long *); + +int lbr$close( + void ** ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + + +static void +file_cvttime( + unsigned int *curtime, + time_t *unixtime ) +{ + static const int32_t divisor = 10000000; + static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */ + int delta[2], remainder; + + lib$subx( curtime, bastim, delta ); + lib$ediv( &divisor, delta, unixtime, &remainder ); +} + + +static void downcase_inplace( char * p ) +{ + for ( ; *p; ++p ) + *p = tolower( *p ); +} + + +static file_archive_info_t * m_archive = NULL; +static file_info_t * m_member_found = NULL; +static void * m_lbr_context = NULL; +static unsigned short * m_rfa_found = NULL; +static const unsigned long LBR_MODINDEX_NUM = 1, + LBR_SYMINDEX_NUM = 2; /* GST:global symbol table */ + + +static unsigned int set_archive_symbol( struct dsc$descriptor_s *symbol, + unsigned long *rfa ) +{ + file_info_t * member = m_member_found; + char buf[ MAXJPATH ] = { 0 }; + + strncpy(buf, symbol->dsc$a_pointer, symbol->dsc$w_length); + buf[ symbol->dsc$w_length ] = 0; + + member->files = list_push_back( member->files, object_new( buf ) ); + + return ( 1 ); /* continue */ +} + + +static unsigned int set_archive_member( struct dsc$descriptor_s *module, + unsigned long *rfa ) +{ + file_archive_info_t * archive = m_archive; + + static struct dsc$descriptor_s bufdsc = + {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; + + struct mhddef *mhd; + char filename[128] = { 0 }; + char buf[ MAXJPATH ] = { 0 }; + + int status; + time_t library_date; + + register int i; + register char *p; + + bufdsc.dsc$a_pointer = filename; + bufdsc.dsc$w_length = sizeof( filename ); + status = lbr$set_module( &m_lbr_context, rfa, &bufdsc, + &bufdsc.dsc$w_length, NULL ); + + if ( !(status & 1) ) + return ( 1 ); /* continue */ + + mhd = (struct mhddef *)filename; + + file_cvttime( &mhd->mhd$l_datim, &library_date ); + + /* strncpy( filename, module->dsc$a_pointer, module->dsc$w_length ); + */ + for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; ++i, ++p ) + filename[ i ] = *p; + + filename[ i ] = '\0'; + + if ( strcmp( filename, "" ) != 0 ) + { + file_info_t * member = 0; + + /* Construct member's filename as lowercase "module.obj" */ + sprintf( buf, "%s.obj", filename ); + downcase_inplace( buf ); + archive->members = filelist_push_back( archive->members, object_new( buf ) ); + + member = filelist_back( archive->members ); + member->is_file = 1; + member->is_dir = 0; + member->exists = 0; + timestamp_init( &member->time, (time_t)library_date, 0 ); + + m_member_found = member; + m_rfa_found = rfa; + status = lbr$search(&m_lbr_context, &LBR_SYMINDEX_NUM, m_rfa_found, set_archive_symbol, NULL); + } + + return ( 1 ); /* continue */ +} + + + +void file_archscan( char const * arch, scanback func, void * closure ) +{ + OBJECT * path = object_new( arch ); + file_archive_info_t * archive = file_archive_query( path ); + + object_free( path ); + + if ( filelist_empty( archive->members ) ) + { + if ( DEBUG_BINDSCAN ) + out_printf( "scan archive %s\n", object_str( archive->file->name ) ); + + if ( file_collect_archive_content_( archive ) < 0 ) + return; + } + + /* Report the collected archive content. */ + { + FILELISTITER iter = filelist_begin( archive->members ); + FILELISTITER const end = filelist_end( archive->members ); + char buf[ MAXJPATH ]; + + for ( ; iter != end ; iter = filelist_next( iter ) ) + { + file_info_t * member_file = filelist_item( iter ); + LIST * symbols = member_file->files; + + /* Construct member path: 'archive-path(member-name)' + */ + sprintf( buf, "%s(%s)", + object_str( archive->file->name ), + object_str( member_file->name ) ); + { + OBJECT * const member = object_new( buf ); + (*func)( closure, member, 1 /* time valid */, &member_file->time ); + object_free( member ); + } + } + } +} + + +/* + * file_archivescan_() - OS specific file_archivescan() implementation + */ +void file_archivescan_( file_archive_info_t * const archive, archive_scanback func, + void * closure ) +{ +} + + +/* + * file_collect_archive_content_() - collects information about archive members + */ + +int file_collect_archive_content_( file_archive_info_t * const archive ) +{ + unsigned short rfa[3]; + + static struct dsc$descriptor_s library = + {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; + + unsigned long lfunc = LBR$C_READ; + unsigned long typ = LBR$C_TYP_UNK; + + register int status; + string buf[ 1 ]; + char vmspath[ MAXJPATH ] = { 0 }; + + m_archive = archive; + + if ( ! filelist_empty( archive->members ) ) filelist_free( archive->members ); + + /* Translate path to VMS + */ + string_new( buf ); + path_translate_to_os_( object_str( archive->file->name ), buf ); + strcpy( vmspath, buf->value ); + string_free( buf ); + + + status = lbr$ini_control( &m_lbr_context, &lfunc, &typ, NULL ); + if ( !( status & 1 ) ) + return -1; + + library.dsc$a_pointer = vmspath; + library.dsc$w_length = strlen( vmspath ); + + status = lbr$open( &m_lbr_context, &library, NULL, NULL, NULL, NULL, NULL ); + if ( !( status & 1 ) ) + return -1; + + /* Scan main index for modules. + * For each module search symbol-index to collect module's symbols. + */ + status = lbr$get_index( &m_lbr_context, &LBR_MODINDEX_NUM, set_archive_member, NULL ); + + if ( !( status & 1 ) ) + return -1; + + + (void) lbr$close( &m_lbr_context ); + + return 0; +} + +#endif /* OS_VMS */ + |