From 3faecf9a00512dcbc8712c4bca9adae72fb64410 Mon Sep 17 00:00:00 2001 From: Kenneth Heafield Date: Sat, 12 May 2012 14:01:52 -0400 Subject: Give in and copy bjam into cdec source code --- jam-files/engine/filevms.c | 327 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 jam-files/engine/filevms.c (limited to 'jam-files/engine/filevms.c') diff --git a/jam-files/engine/filevms.c b/jam-files/engine/filevms.c new file mode 100644 index 00000000..d2ab2047 --- /dev/null +++ b/jam-files/engine/filevms.c @@ -0,0 +1,327 @@ +/* + * 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. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + */ + +# include "jam.h" +# include "filesys.h" +# include "pathsys.h" + +# ifdef OS_VMS + +/* + * filevms.c - scan directories and libaries on VMS + * + * External routines: + * + * file_dirscan() - scan a directory for files + * file_time() - get timestamp of file, if not done by file_dirscan() + * file_archscan() - scan an archive for files + * + * File_dirscan() and file_archscan() call back a caller provided function + * for each file found. A flag to this callback function lets file_dirscan() + * and file_archscan() indicate that a timestamp is being provided with the + * file. If file_dirscan() or file_archscan() do not provide the file's + * timestamp, interested parties may later call file_time(). + * + * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length! + * 05/03/96 (seiwald) - split into pathvms.c + */ + +# include +# include +# include +# include +# include +# include +# include + +#include +#include +#include +#include +#include +#include + +/* 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 *, + int (*func)( struct dsc$descriptor_s *, unsigned long *), + void * ); + +int lbr$close( + void ** ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +static void +file_cvttime( + unsigned int *curtime, + time_t *unixtime ) +{ + static const size_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 ); +} + +# define DEFAULT_FILE_SPECIFICATION "[]*.*;0" + +# define min( a,b ) ((a)<(b)?(a):(b)) + +void +file_dirscan( + char *dir, + scanback func, + void *closure ) +{ + + struct FAB xfab; + struct NAM xnam; + struct XABDAT xab; + char esa[256]; + char filename[256]; + string filename2[1]; + char dirname[256]; + register int status; + PATHNAME f; + + memset( (char *)&f, '\0', sizeof( f ) ); + + f.f_root.ptr = dir; + f.f_root.len = strlen( dir ); + + /* get the input file specification + */ + xnam = cc$rms_nam; + xnam.nam$l_esa = esa; + xnam.nam$b_ess = sizeof( esa ) - 1; + xnam.nam$l_rsa = filename; + xnam.nam$b_rss = min( sizeof( filename ) - 1, NAM$C_MAXRSS ); + + xab = cc$rms_xabdat; /* initialize extended attributes */ + xab.xab$b_cod = XAB$C_DAT; /* ask for date */ + xab.xab$l_nxt = NULL; /* terminate XAB chain */ + + xfab = cc$rms_fab; + xfab.fab$l_dna = DEFAULT_FILE_SPECIFICATION; + xfab.fab$b_dns = sizeof( DEFAULT_FILE_SPECIFICATION ) - 1; + xfab.fab$l_fop = FAB$M_NAM; + xfab.fab$l_fna = dir; /* address of file name */ + xfab.fab$b_fns = strlen( dir ); /* length of file name */ + xfab.fab$l_nam = &xnam; /* address of NAB block */ + xfab.fab$l_xab = (char *)&xab; /* address of XAB block */ + + + status = sys$parse( &xfab ); + + if ( DEBUG_BINDSCAN ) + printf( "scan directory %s\n", dir ); + + if ( !( status & 1 ) ) + return; + + + + /* Add bogus directory for [000000] */ + + if ( !strcmp( dir, "[000000]" ) ) + { + (*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ ); + } + + /* Add bogus directory for [] */ + + if ( !strcmp( dir, "[]" ) ) + { + (*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ ); + (*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ ); + } + + string_new( filename2 ); + while ( (status = sys$search( &xfab )) & 1 ) + { + char *s; + time_t time; + + /* "I think that might work" - eml */ + + sys$open( &xfab ); + sys$close( &xfab ); + + file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time ); + + filename[xnam.nam$b_rsl] = '\0'; + + /* What we do with the name depends on the suffix: */ + /* .dir is a directory */ + /* .xxx is a file with a suffix */ + /* . is no suffix at all */ + + if ( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) ) + { + /* directory */ + sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name ); + f.f_dir.ptr = dirname; + f.f_dir.len = strlen( dirname ); + f.f_base.ptr = 0; + f.f_base.len = 0; + f.f_suffix.ptr = 0; + f.f_suffix.len = 0; + } + else + { + /* normal file with a suffix */ + f.f_dir.ptr = 0; + f.f_dir.len = 0; + f.f_base.ptr = xnam.nam$l_name; + f.f_base.len = xnam.nam$b_name; + f.f_suffix.ptr = xnam.nam$l_type; + f.f_suffix.len = xnam.nam$b_type; + } + + string_truncate( filename2, 0 ); + path_build( &f, filename2, 0 ); + + /* + if ( DEBUG_SEARCH ) + printf("root '%s' base %.*s suf %.*s = %s\n", + dir, + xnam.nam$b_name, xnam.nam$l_name, + xnam.nam$b_type, xnam.nam$l_type, + filename2 ); + */ + + (*func)( closure, filename2->value, 1 /* time valid */, time ); + } + string_free( filename2 ); +} + +int +file_time( + char *filename, + time_t *time ) +{ + /* This should never be called, as all files are */ + /* timestampped in file_dirscan() and file_archscan() */ + return -1; +} + +static char *VMS_archive = 0; +static scanback VMS_func; +static void *VMS_closure; +static void *context; + +static int +file_archmember( + struct dsc$descriptor_s *module, + unsigned long *rfa ) +{ + static struct dsc$descriptor_s bufdsc = + {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; + + struct mhddef *mhd; + char filename[128]; + char buf[ MAXJPATH ]; + + 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( &context, rfa, &bufdsc, + &bufdsc.dsc$w_length, NULL ); + + if ( !(status & 1) ) + return ( 1 ); + + mhd = (struct mhddef *)filename; + + file_cvttime( &mhd->mhd$l_datim, &library_date ); + + for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; ++i, ++p ) + filename[ i ] = *p; + + filename[ i ] = '\0'; + + sprintf( buf, "%s(%s.obj)", VMS_archive, filename ); + + (*VMS_func)( VMS_closure, buf, 1 /* time valid */, (time_t)library_date ); + + return ( 1 ); +} + + +void file_archscan( char * archive, scanback func, void * closure ) +{ + 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; + unsigned long index = 1; + + register int status; + + VMS_archive = archive; + VMS_func = func; + VMS_closure = closure; + + status = lbr$ini_control( &context, &lfunc, &typ, NULL ); + if ( !( status & 1 ) ) + return; + + library.dsc$a_pointer = archive; + library.dsc$w_length = strlen( archive ); + + status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL ); + if ( !( status & 1 ) ) + return; + + (void) lbr$get_index( &context, &index, file_archmember, NULL ); + + (void) lbr$close( &context ); +} + +# endif /* VMS */ -- cgit v1.2.3