]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/engine/filevms.c
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / tools / build / src / engine / filevms.c
CommitLineData
7c673cae
FG
1/*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/* This file is ALSO:
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)
13 */
14
15
16#include "jam.h"
17#include "filesys.h"
18
19#include "object.h"
20#include "pathsys.h"
21#include "strings.h"
22
23
24#ifdef OS_VMS
25
26/*
27 * filevms.c - manipulate file names and scan directories on VMS.
28 *
29 * This implementation is based on POSIX-style path manipulation.
30 *
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).
36 *
37 * This should allow us to re-use fileunix.c implementation,
38 * excluding archive/library member processing.
39 *
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.
43 *
44 *
45 * External routines:
46 * file_archscan() - scan an archive for files
47 * file_mkdir() - create a directory
48 * file_supported_fmt_resolution() - file modification timestamp resolution
49 *
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
56 */
57
58#include <assert.h>
59#include <stdio.h>
60
61#include <sys/stat.h> /* needed for mkdir() */
62#include <unistd.h> /* needed for read and close prototype */
63
64#include <dirent.h>
65#define STRUCT_DIRENT struct dirent
66
67
68void path_translate_to_os_( char const * f, string * file );
69
70/*
71 * file_collect_dir_content_() - collects directory content information
72 */
73
74int file_collect_dir_content_( file_info_t * const d )
75{
76 LIST * files = L0;
77 PATHNAME f;
78 DIR * dd;
79 STRUCT_DIRENT * dirent;
80 string path[ 1 ];
81 char const * dirstr;
82
83 assert( d );
84 assert( d->is_dir );
85 assert( list_empty( d->files ) );
86
87 dirstr = object_str( d->name );
88
89 memset( (char *)&f, '\0', sizeof( f ) );
90 f.f_dir.ptr = dirstr;
91 f.f_dir.len = strlen( dirstr );
92
93 if ( !*dirstr ) dirstr = ".";
94
95 if ( !( dd = opendir( dirstr ) ) )
96 return -1;
97
98 string_new( path );
99 while ( ( dirent = readdir( dd ) ) )
100 {
101 OBJECT * name;
102 f.f_base.ptr = dirent->d_name
103 #ifdef old_sinix
104 - 2 /* Broken structure definition on sinix. */
105 #endif
106 ;
107 f.f_base.len = strlen( f.f_base.ptr );
108
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 );
115 else
116 object_free( name );
117 }
118 string_free( path );
119
120 closedir( dd );
121
122 d->files = files;
123 return 0;
124}
125
126
127/*
128 * file_dirscan_() - OS specific file_dirscan() implementation
129 */
130
131void file_dirscan_( file_info_t * const d, scanback func, void * closure )
132{
133 assert( d );
134 assert( d->is_dir );
135
136 /* Special case / : enter it */
137 if ( !strcmp( object_str( d->name ), "/" ) )
138 (*func)( closure, d->name, 1 /* stat()'ed */, &d->time );
139}
140
141
142/*
143 * file_mkdir() - create a directory
144 */
145
146int file_mkdir( char const * const path )
147{
148 /* Explicit cast to remove const modifiers and avoid related compiler
149 * warnings displayed when using the intel compiler.
150 */
151 return mkdir( (char *)path, 0777 );
152}
153
154
155/*
156 * file_query_() - query information about a path from the OS
157 */
158
159void file_query_( file_info_t * const info )
160{
161 file_query_posix_( info );
162}
163
164
7c673cae
FG
165/*------------------------------------------------------------------------------
166* VMS-specific processing:
167*
168*/
169
170#include <descrip.h>
171#include <lbrdef.h>
172#include <credef.h>
173#include <mhddef.h>
174#include <lhidef.h>
175#include <lib$routines.h>
176#include <starlet.h>
177
178/* Supply missing prototypes for lbr$-routines*/
179
180#ifdef __cplusplus
181extern "C" {
182#endif /* __cplusplus */
183
184int lbr$set_module(
185 void **,
186 unsigned long *,
187 struct dsc$descriptor_s *,
188 unsigned short *,
189 void * );
190
191int lbr$open( void **,
192 struct dsc$descriptor_s *,
193 void *,
194 void *,
195 void *,
196 void *,
197 void * );
198
199int lbr$ini_control(
200 void **,
201 unsigned long *,
202 unsigned long *,
203 void * );
204
205int lbr$get_index(
206 void **,
207 unsigned long * const,
208 int (*func)( struct dsc$descriptor_s *, unsigned long *),
209 void * );
210
211int lbr$search(
212 void **,
213 unsigned long * const,
214 unsigned short *,
215 int (*func)( struct dsc$descriptor_s *, unsigned long *),
216 unsigned long *);
217
218int lbr$close(
219 void ** );
220
221#ifdef __cplusplus
222}
223#endif /* __cplusplus */
224
225
226
227static void
228file_cvttime(
229 unsigned int *curtime,
230 time_t *unixtime )
231{
232 static const size_t divisor = 10000000;
233 static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */
234 int delta[2], remainder;
235
236 lib$subx( curtime, bastim, delta );
237 lib$ediv( &divisor, delta, unixtime, &remainder );
238}
239
240
241static void downcase_inplace( char * p )
242{
243 for ( ; *p; ++p )
244 *p = tolower( *p );
245}
246
247
248static file_archive_info_t * m_archive = NULL;
249static file_info_t * m_member_found = NULL;
250static void * m_lbr_context = NULL;
251static unsigned short * m_rfa_found = NULL;
252static const unsigned long LBR_MODINDEX_NUM = 1,
253 LBR_SYMINDEX_NUM = 2; /* GST:global symbol table */
254
255
256static unsigned int set_archive_symbol( struct dsc$descriptor_s *symbol,
257 unsigned long *rfa )
258{
259 file_info_t * member = m_member_found;
260 char buf[ MAXJPATH ] = { 0 };
261
262 strncpy(buf, symbol->dsc$a_pointer, symbol->dsc$w_length);
263 buf[ symbol->dsc$w_length ] = 0;
264
265 member->files = list_push_back( member->files, object_new( buf ) );
266
267 return ( 1 ); /* continue */
268}
269
270
271static unsigned int set_archive_member( struct dsc$descriptor_s *module,
272 unsigned long *rfa )
273{
274 file_archive_info_t * archive = m_archive;
275
276 static struct dsc$descriptor_s bufdsc =
277 {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
278
279 struct mhddef *mhd;
280 char filename[128] = { 0 };
281 char buf[ MAXJPATH ] = { 0 };
282
283 int status;
284 time_t library_date;
285
286 register int i;
287 register char *p;
288
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 );
293
294 if ( !(status & 1) )
295 return ( 1 ); /* continue */
296
297 mhd = (struct mhddef *)filename;
298
299 file_cvttime( &mhd->mhd$l_datim, &library_date );
300
301 /* strncpy( filename, module->dsc$a_pointer, module->dsc$w_length );
302 */
303 for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; ++i, ++p )
304 filename[ i ] = *p;
305
306 filename[ i ] = '\0';
307
308 if ( strcmp( filename, "" ) != 0 )
309 {
310 file_info_t * member = 0;
311
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 ) );
316
317 member = filelist_back( archive->members );
318 member->is_file = 1;
319 member->is_dir = 0;
320 member->exists = 0;
321 timestamp_init( &member->time, (time_t)library_date, 0 );
322
323 m_member_found = member;
324 m_rfa_found = rfa;
325 status = lbr$search(&m_lbr_context, &LBR_SYMINDEX_NUM, m_rfa_found, set_archive_symbol, NULL);
326 }
327
328 return ( 1 ); /* continue */
329}
330
331
332
333void file_archscan( char const * arch, scanback func, void * closure )
334{
335 OBJECT * path = object_new( arch );
336 file_archive_info_t * archive = file_archive_query( path );
337
338 object_free( path );
339
340 if ( filelist_empty( archive->members ) )
341 {
342 if ( DEBUG_BINDSCAN )
343 out_printf( "scan archive %s\n", object_str( archive->file->name ) );
344
345 if ( file_collect_archive_content_( archive ) < 0 )
346 return;
347 }
348
349 /* Report the collected archive content. */
350 {
351 FILELISTITER iter = filelist_begin( archive->members );
352 FILELISTITER const end = filelist_end( archive->members );
353 char buf[ MAXJPATH ];
354
355 for ( ; iter != end ; iter = filelist_next( iter ) )
356 {
357 file_info_t * member_file = filelist_item( iter );
358 LIST * symbols = member_file->files;
359
360 /* Construct member path: 'archive-path(member-name)'
361 */
362 sprintf( buf, "%s(%s)",
363 object_str( archive->file->name ),
364 object_str( member_file->name ) );
365 {
366 OBJECT * const member = object_new( buf );
367 (*func)( closure, member, 1 /* time valid */, &member_file->time );
368 object_free( member );
369 }
370 }
371 }
372}
373
374
375/*
376 * file_archivescan_() - OS specific file_archivescan() implementation
377 */
378void file_archivescan_( file_archive_info_t * const archive, archive_scanback func,
379 void * closure )
380{
381}
382
383
384/*
385 * file_collect_archive_content_() - collects information about archive members
386 */
387
388int file_collect_archive_content_( file_archive_info_t * const archive )
389{
390 unsigned short rfa[3];
391
392 static struct dsc$descriptor_s library =
393 {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
394
395 unsigned long lfunc = LBR$C_READ;
396 unsigned long typ = LBR$C_TYP_UNK;
397
398 register int status;
399 string buf[ 1 ];
400 char vmspath[ MAXJPATH ] = { 0 };
401
402 m_archive = archive;
403
404 if ( ! filelist_empty( archive->members ) ) filelist_free( archive->members );
405
406 /* Translate path to VMS
407 */
408 string_new( buf );
409 path_translate_to_os_( object_str( archive->file->name ), buf );
410 strcpy( vmspath, buf->value );
411 string_free( buf );
412
413
414 status = lbr$ini_control( &m_lbr_context, &lfunc, &typ, NULL );
415 if ( !( status & 1 ) )
416 return -1;
417
418 library.dsc$a_pointer = vmspath;
419 library.dsc$w_length = strlen( vmspath );
420
421 status = lbr$open( &m_lbr_context, &library, NULL, NULL, NULL, NULL, NULL );
422 if ( !( status & 1 ) )
423 return -1;
424
425 /* Scan main index for modules.
426 * For each module search symbol-index to collect module's symbols.
427 */
428 status = lbr$get_index( &m_lbr_context, &LBR_MODINDEX_NUM, set_archive_member, NULL );
429
430 if ( !( status & 1 ) )
431 return -1;
432
433
434 (void) lbr$close( &m_lbr_context );
435
436 return 0;
437}
438
439#endif /* OS_VMS */
440