2
Copyright (c) 1994 - 2010, Lawrence Livermore National Security, LLC.
6
This file is part of Silo. For details, see silo.llnl.gov.
8
Redistribution and use in source and binary forms, with or without
9
modification, are permitted provided that the following conditions
12
* Redistributions of source code must retain the above copyright
13
notice, this list of conditions and the disclaimer below.
14
* Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the disclaimer (as noted
16
below) in the documentation and/or other materials provided with
18
* Neither the name of the LLNS/LLNL nor the names of its
19
contributors may be used to endorse or promote products derived
20
from this software without specific prior written permission.
22
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE
26
LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR
27
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
This work was produced at Lawrence Livermore National Laboratory under
36
Contract No. DE-AC52-07NA27344 with the DOE.
38
Neither the United States Government nor Lawrence Livermore National
39
Security, LLC nor any of their employees, makes any warranty, express
40
or implied, or assumes any liability or responsibility for the
41
accuracy, completeness, or usefulness of any information, apparatus,
42
product, or process disclosed, or represents that its use would not
43
infringe privately-owned rights.
45
Any reference herein to any specific commercial products, process, or
46
services by trade name, trademark, manufacturer or otherwise does not
47
necessarily constitute or imply its endorsement, recommendation, or
48
favoring by the United States Government or Lawrence Livermore
49
National Security, LLC. The views and opinions of authors expressed
50
herein do not necessarily state or reflect those of the United States
51
Government or Lawrence Livermore National Security, LLC, and shall not
52
be used for advertising or product endorsement purposes.
55
* PDBDIR.C - provides a directory capability for PDBLib
58
* Software Release #92-0043
65
/*-------------------------------------------------------------------------
66
* Function: lite_PD_cd
68
* Purpose: Change the current working directory. The directory
69
* may be specified by an absolute or relative path.
71
* Return: Success: TRUE
75
* Programmer: Adapted from PACT PDB
76
* Mar 4, 1996 11:41 AM EST
80
*-------------------------------------------------------------------------
83
lite_PD_cd (PDBfile *file, char *dirname) {
88
lite_PD_err[0] = '\0';
91
sprintf(lite_PD_err, "ERROR: BAD FILE ID - PD_CD\n");
95
if (dirname == NULL) {
98
strcpy(name, _lite_PD_fixname(file, dirname));
99
if (name[strlen(name) - 1] != '/') strcat(name, "/");
102
ep = lite_PD_inquire_entry(file, name, FALSE, NULL);
104
if (dirname == NULL) {
107
if (strcmp(name, "/") != 0) {
108
name[strlen(name) - 1] = '\0';
109
ep = lite_PD_inquire_entry(file, name, FALSE, NULL);
114
sprintf(lite_PD_err, "ERROR: DIRECTORY %s NOT FOUND - PD_CD\n",
121
if (strcmp(ep->type, "Directory") != 0) {
122
sprintf(lite_PD_err, "ERROR: BAD DIRECTORY %s - PD_CD\n", dirname);
125
if (file->current_prefix) SFREE(file->current_prefix);
126
file->current_prefix = lite_SC_strsavef(name, "char*:PD_CD:name");
133
/*-------------------------------------------------------------------------
134
* Function: lite_PD_ls
136
* Purpose: Return a list of all variables and directories of the
137
* specified type in the specified directory. If type is
138
* NULL, all types are returned. If path is NULL, the root
139
* directory is searched. Directories are terminated with
142
* Return: Success: Returns an array of pointers to strings.
143
* The array and the strings are allocated
144
* with score. The vector of pointers is
145
* terminated with the null pointer.
149
* Programmer: Adapted from PACT PDB
150
* Mar 4, 1996 11:17 AM EST
153
* Eric Brugger, Thu Dec 10 11:38:43 PST 1998
154
* I moved a free to be inside a loop to eliminate a memory leak.
156
* Mark Miller, Wed Jun 11 16:42:09 PDT 2008
157
* Fixed valgrind error of src/dst overlap in strcpy
158
*-------------------------------------------------------------------------
161
lite_PD_ls (PDBfile *file, char *path, char *type, int *num) {
163
char **varlist, **outlist;
165
char pattern[MAXLINE];
166
int nvars, i, has_dirs, head, pass;
168
lite_PD_err[0] = '\0';
173
sprintf(lite_PD_err, "ERROR: BAD FILE ID - PD_LS\n");
178
sprintf(lite_PD_err, "ERROR: LAST ARGUMENT NULL - PD_LS\n");
182
if (file->symtab->nelements == 0) return(NULL);
185
* Determine if file contains directories and
186
* build a pattern which names must match e.g., '/dir/abc*'
188
if (PD_has_directories(file)) {
191
if (strcmp(lite_PD_pwd(file), "/") == 0) strcpy(pattern, "/*");
192
else sprintf(pattern, "%s/*", lite_PD_pwd(file));
194
strcpy(pattern, _lite_PD_fixname(file, path));
195
ep = lite_PD_inquire_entry(file, pattern, FALSE, NULL);
196
if ((ep != NULL) && (strcmp(ep->type, "Directory") == 0)) {
197
if (pattern[strlen(pattern) - 1] == '/') strcat(pattern, "*");
198
else strcat(pattern, "/*");
200
if (pattern[strlen(pattern) - 1] != '/') {
201
strcat(pattern, "/");
202
ep = lite_PD_inquire_entry(file, pattern, FALSE, NULL);
203
if ((ep != NULL) && (strcmp(ep->type, "Directory") == 0))
204
strcat(pattern, "*");
206
pattern[strlen(pattern) - 1] = '\0';
208
pattern[strlen(pattern) - 1] = '\0';
209
ep = lite_PD_inquire_entry(file, pattern, FALSE, NULL);
210
if ((ep != NULL) && (strcmp(ep->type, "Directory") == 0))
211
strcat(pattern, "/*");
213
strcat(pattern, "/");
219
if (path == NULL) strcpy(pattern, "*");
220
else strcpy(pattern, path);
224
* Generate the list of matching names. Note that this returns items which
225
* are in the requested directory AND items which are in sub-directories of
226
* the requested directory. In other words, all names which BEGIN with the
227
* requested pattern are returned.
230
outlist = FMAKE_N(char *, file->symtab->nelements + 1, "PD_LS:outlist");
233
* The second pass is in case variables were written to the file before
234
* the first directory was created. Such variables lack an initial slash.
236
for (pass = 1; pass <= 2; pass++) {
238
if (has_dirs && (strchr(pattern + 1, '/') == NULL)) {
239
memmove(pattern, pattern+1, strlen(pattern+1)+1);
245
varlist = lite_SC_hash_dump(file->symtab, pattern);
246
if ((varlist == NULL) || (varlist[0] == NULL)) continue;
249
* Save only those variables which are IN the requested directory
250
* (not in sub-directories), and are of the requested type
252
for (i=0; (i<file->symtab->nelements) && (varlist[i]!=NULL); i++) {
254
* The entry '/' (the root directory) is a special case. It
255
* is not a child of any directory, so should be ignored.
257
if (strcmp("/", varlist[i]) == 0) continue;
260
* Check to see if type of this variable matches request.
263
ep = lite_PD_inquire_entry(file, varlist[i], FALSE, NULL);
264
if (strcmp(ep->type, type) != 0) continue;
268
* If here, then variable is of right type. If this file has
269
* directories, check for any more slashes (/'s) in the
270
* name. If any are found, this is not a leaf element. NOTE:
271
* if directories are not used, slashes are valid charcters
275
if (pattern[0] != '/') head = 0;
276
else head = strlen(pattern) - strlen(strrchr(pattern, '/')) + 1;
277
name = &(varlist[i])[head];
278
if ((strlen(name) == 0) ||
279
((pass == 2) && (name[0] == '/')) ||
280
((strchr(name, '/') != NULL) &&
281
(strchr(name, '/') != ((name + strlen(name) - 1)))))
288
* Variable is of right type and is a leaf in the requested
291
outlist[nvars++] = name;
297
* Store a null string to terminate list (just a precaution)
299
outlist[nvars] = NULL;
301
if (has_dirs) lite_SC_string_sort(outlist, nvars);
308
/*-------------------------------------------------------------------------
309
* Function: lite_PD_pwd
311
* Purpose: Returns the current working directory.
313
* Return: Success: A ptr to a statically allocated buffer
314
* which contains the name of the current
319
* Programmer: Adapted from PACT PDB
320
* Mar 4, 1996 11:31 AM EST
324
*-------------------------------------------------------------------------
327
lite_PD_pwd(PDBfile *file) {
329
static char cwd[MAXLINE];
331
lite_PD_err[0] = '\0';
334
sprintf(lite_PD_err, "ERROR: BAD FILE ID - PF_PWD\n");
338
if ((file->current_prefix == NULL) ||
339
(strcmp(file->current_prefix, "/") == 0)) {
342
strcpy(cwd, file->current_prefix);
343
cwd[strlen(cwd) - 1] = '\0';
349
/*-------------------------------------------------------------------------
350
* Function: _lite_PD_fixname
352
* Purpose: Make full pathname from current working directory
353
* and the given pathname (absolute or relative)
355
* Return: Success: Ptr to a static character buffer which
360
* Programmer: Adapted from PACT PDB
361
* Mar 4, 1996 4:40 PM EST
364
* Sean Ahern, Thu Jul 2 11:01:32 PDT 1998
365
* Fixed some indexing problems on strings.
367
*-------------------------------------------------------------------------
370
_lite_PD_fixname (PDBfile *file, char *inname) {
372
static char outname[MAXLINE];
374
char tmpstr[MAXLINE];
376
if ((file == NULL) || (inname == NULL)) return(NULL);
380
if (!PD_has_directories(file)) {
382
* If no directories, just copy verbatim.
384
strcpy(outname, inname);
387
* Break path into slash-separated tokens.
388
* Process each node individually.
390
if (inname[0] != '/') strcpy(outname, lite_PD_pwd(file));
391
strcpy(tmpstr, inname);
392
node = (char *) strtok(tmpstr, "/");
394
while (node != NULL) {
395
if (strcmp(".", node) == 0) {
397
} else if (strcmp("..", node) == 0) {
399
* Go up one level, unless already at top.
401
if (strcmp("/", outname) != 0) {
403
if (outname[strlen(outname) - 1] == '/') {
404
outname[strlen(outname) - 1] = '\0';
406
s = strrchr(outname, '/');
407
if (s != NULL) s[0] = '\0';
411
* Append to end of current path.
413
if ((strlen(outname) == 0) ||
414
(outname[strlen(outname) - 1] != '/'))
415
strcat(outname, "/");
416
strcat(outname, node);
418
node = (char *) strtok(NULL, "/");
421
if ((strlen(inname) > 0) &&
422
(inname[strlen(inname) - 1] == '/') &&
423
(outname[strlen(outname) - 1] != '/'))
424
strcat(outname, "/");
427
if (outname[0] == '\0') strcpy(outname, "/");
433
/*-------------------------------------------------------------------------
434
* Function: lite_PD_mkdir
436
* Purpose: Create a directory. The directory may be specified by an
437
* absolute or relative path.
439
* Return: Success: TRUE
443
* Programmer: Adapted from PACT
448
*-------------------------------------------------------------------------
452
lite_PD_mkdir (PDBfile *file, char *dirname) {
455
char name[MAXLINE], head[MAXLINE];
457
static int dir_num = 0;
459
lite_PD_err[0] = '\0';
462
sprintf(lite_PD_err, "ERROR: BAD FILE ID - PD_MKDIR\n");
466
if (dirname == NULL) {
467
sprintf(lite_PD_err, "ERROR: DIRECTORY NAME NULL - PD_MKDIR\n");
472
* Define type "Directory", if it hasn't been already.
474
if (!PD_has_directories(file)) {
475
if ((lite_PD_defncv(file, "Directory", 1, 0)) == NULL) return FALSE;
478
* Write out the root directory.
481
if (!lite_PD_write(file, "/", "Directory", &dir)) return(FALSE);
486
* Build an absolute pathname.
488
strcpy(name, _lite_PD_fixname(file, dirname));
489
if (name[strlen(name) - 1] != '/') strcat(name, "/");
492
* Make sure this directory hasn't already been created.
494
if (lite_PD_inquire_entry(file, name, FALSE, NULL) != NULL) {
495
sprintf(lite_PD_err, "ERROR: DIRECTORY %s ALREADY EXISTS - PD_MKDIR\n",
501
* Make sure the next higher level directory already exists.
504
head[strlen(head) - 1] = '\0';
505
s = strrchr(head, '/');
508
if (lite_PD_inquire_entry(file, head, FALSE, NULL) == NULL) {
509
head[strlen(head) - 1] = '\0';
510
sprintf(lite_PD_err, "ERROR: DIRECTORY %s DOES NOT EXIST - "
517
* Write the directory variable.
520
if (!lite_PD_write(file, name, "Directory", &dir)) return(FALSE);
525
#endif /* PDB_WRITE */