~ubuntu-branches/ubuntu/trusty/silo-llnl/trusty

« back to all changes in this revision

Viewing changes to src/pdb/pdbdir.c

  • Committer: Bazaar Package Importer
  • Author(s): Alastair McKinstry
  • Date: 2011-01-02 00:03:01 UTC
  • Revision ID: james.westby@ubuntu.com-20110102000301-9s2hfsjrkguz6h4r
Tags: upstream-4.8
ImportĀ upstreamĀ versionĀ 4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 1994 - 2010, Lawrence Livermore National Security, LLC.
 
3
LLNL-CODE-425250.
 
4
All rights reserved.
 
5
 
 
6
This file is part of Silo. For details, see silo.llnl.gov.
 
7
 
 
8
Redistribution and use in source and binary forms, with or without
 
9
modification, are permitted provided that the following conditions
 
10
are met:
 
11
 
 
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
 
17
     the distribution.
 
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.
 
21
 
 
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.
 
34
 
 
35
This work was produced at Lawrence Livermore National Laboratory under
 
36
Contract No.  DE-AC52-07NA27344 with the DOE.
 
37
 
 
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.
 
44
 
 
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.
 
53
*/
 
54
/*
 
55
 * PDBDIR.C - provides a directory capability for PDBLib
 
56
 *
 
57
 * Source Version: 9.0
 
58
 * Software Release #92-0043
 
59
 *
 
60
 */
 
61
#include "pdb.h"
 
62
#include <string.h>
 
63
 
 
64
 
 
65
/*-------------------------------------------------------------------------
 
66
 * Function:    lite_PD_cd
 
67
 *
 
68
 * Purpose:     Change the current working directory.  The directory
 
69
 *              may be specified by an absolute or relative path.
 
70
 *
 
71
 * Return:      Success:        TRUE
 
72
 *
 
73
 *              Failure:        FALSE
 
74
 *
 
75
 * Programmer:  Adapted from PACT PDB
 
76
 *              Mar  4, 1996 11:41 AM EST
 
77
 *
 
78
 * Modifications:
 
79
 *
 
80
 *-------------------------------------------------------------------------
 
81
 */
 
82
int
 
83
lite_PD_cd (PDBfile *file, char *dirname) {
 
84
 
 
85
   char name[MAXLINE];
 
86
   syment *ep;
 
87
 
 
88
   lite_PD_err[0] = '\0';
 
89
 
 
90
   if (file == NULL) {
 
91
      sprintf(lite_PD_err, "ERROR: BAD FILE ID - PD_CD\n");
 
92
      return(FALSE);
 
93
   }
 
94
     
 
95
   if (dirname == NULL) {
 
96
      strcpy(name, "/");
 
97
   } else {
 
98
      strcpy(name, _lite_PD_fixname(file, dirname));
 
99
      if (name[strlen(name) - 1] != '/') strcat(name, "/");
 
100
   }
 
101
 
 
102
   ep = lite_PD_inquire_entry(file, name, FALSE, NULL);
 
103
   if (ep == NULL) {
 
104
      if (dirname == NULL) {
 
105
         return(FALSE);
 
106
      } else {
 
107
         if (strcmp(name, "/") != 0) {
 
108
            name[strlen(name) - 1] = '\0';
 
109
            ep = lite_PD_inquire_entry(file, name, FALSE, NULL);
 
110
            strcat(name, "/");
 
111
         }
 
112
 
 
113
         if (ep == NULL) {
 
114
            sprintf(lite_PD_err, "ERROR: DIRECTORY %s NOT FOUND - PD_CD\n",
 
115
                    dirname);
 
116
            return(FALSE);
 
117
         }
 
118
      }
 
119
   }
 
120
 
 
121
   if (strcmp(ep->type, "Directory") != 0) {
 
122
      sprintf(lite_PD_err, "ERROR: BAD DIRECTORY %s - PD_CD\n", dirname);
 
123
      return(FALSE);
 
124
   } else {
 
125
      if (file->current_prefix) SFREE(file->current_prefix);
 
126
      file->current_prefix = lite_SC_strsavef(name, "char*:PD_CD:name");
 
127
   }
 
128
 
 
129
   return(TRUE);
 
130
}
 
131
 
 
132
 
 
133
/*-------------------------------------------------------------------------
 
134
 * Function:    lite_PD_ls
 
135
 *
 
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
 
140
 *              a slash.
 
141
 *
 
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.
 
146
 *
 
147
 *              Failure:        NULL
 
148
 *
 
149
 * Programmer:  Adapted from PACT PDB
 
150
 *              Mar  4, 1996 11:17 AM EST
 
151
 *
 
152
 * Modifications:
 
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.
 
155
 *
 
156
 *    Mark Miller, Wed Jun 11 16:42:09 PDT 2008
 
157
 *    Fixed valgrind error of src/dst overlap in strcpy
 
158
 *-------------------------------------------------------------------------
 
159
 */
 
160
char **
 
161
lite_PD_ls (PDBfile *file, char *path, char *type, int *num) {
 
162
   syment       *ep;
 
163
   char         **varlist, **outlist;
 
164
   char         *name;
 
165
   char         pattern[MAXLINE];
 
166
   int          nvars, i, has_dirs, head, pass;
 
167
     
 
168
   lite_PD_err[0] = '\0';
 
169
 
 
170
   *num = 0;
 
171
 
 
172
   if (file == NULL) {
 
173
      sprintf(lite_PD_err, "ERROR: BAD FILE ID - PD_LS\n");
 
174
      return(NULL);
 
175
   }
 
176
 
 
177
   if (num == NULL) {
 
178
      sprintf(lite_PD_err, "ERROR: LAST ARGUMENT NULL - PD_LS\n");
 
179
      return(NULL);
 
180
   }
 
181
 
 
182
   if (file->symtab->nelements == 0) return(NULL);
 
183
    
 
184
   /*
 
185
    * Determine if file contains directories and
 
186
    * build a pattern which names must match e.g., '/dir/abc*'
 
187
    */
 
188
   if (PD_has_directories(file)) {
 
189
      has_dirs = TRUE;
 
190
      if (path == NULL) {
 
191
         if (strcmp(lite_PD_pwd(file), "/") == 0) strcpy(pattern, "/*");
 
192
         else sprintf(pattern, "%s/*", lite_PD_pwd(file));
 
193
      } else {
 
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, "/*");
 
199
         } else {
 
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, "*");
 
205
               else
 
206
                  pattern[strlen(pattern) - 1] = '\0';
 
207
            } else {
 
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, "/*");
 
212
               else
 
213
                  strcat(pattern, "/");
 
214
            }
 
215
         }
 
216
      }
 
217
   } else {
 
218
      has_dirs = FALSE;
 
219
      if (path == NULL) strcpy(pattern, "*");
 
220
      else strcpy(pattern, path);
 
221
   }
 
222
     
 
223
   /*
 
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.
 
228
    */
 
229
   nvars = 0;
 
230
   outlist = FMAKE_N(char *, file->symtab->nelements + 1, "PD_LS:outlist");
 
231
     
 
232
   /*
 
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.
 
235
    */
 
236
   for (pass = 1; pass <= 2; pass++) {
 
237
      if (pass == 2) {
 
238
         if (has_dirs && (strchr(pattern + 1, '/') == NULL)) {
 
239
            memmove(pattern, pattern+1, strlen(pattern+1)+1);
 
240
         } else {
 
241
            break;
 
242
         }
 
243
      }
 
244
 
 
245
      varlist = lite_SC_hash_dump(file->symtab, pattern);
 
246
      if ((varlist == NULL) || (varlist[0] == NULL)) continue;
 
247
     
 
248
      /*
 
249
       * Save only those variables which are IN the requested directory
 
250
       * (not in sub-directories), and are of the requested type
 
251
       */
 
252
      for (i=0; (i<file->symtab->nelements) && (varlist[i]!=NULL); i++) {
 
253
         /*
 
254
          * The entry '/' (the root directory) is a special case. It
 
255
          * is not a child of any directory, so should be ignored.
 
256
          */
 
257
         if (strcmp("/", varlist[i]) == 0) continue;
 
258
          
 
259
         /*
 
260
          * Check to see if type of this variable matches request.
 
261
          */
 
262
         if (type != NULL) {
 
263
            ep = lite_PD_inquire_entry(file, varlist[i], FALSE, NULL);
 
264
            if (strcmp(ep->type, type) != 0) continue;
 
265
         }
 
266
 
 
267
         /*
 
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
 
272
          * in file names.
 
273
          */
 
274
         if (has_dirs) {
 
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)))))
 
282
               continue;
 
283
         } else {
 
284
            name = varlist[i];
 
285
         }
 
286
          
 
287
         /*
 
288
          * Variable is of right type and is a leaf in the requested
 
289
          * directory.
 
290
          */
 
291
         outlist[nvars++] = name;
 
292
      }
 
293
      SFREE(varlist);
 
294
   }
 
295
     
 
296
   /*
 
297
    * Store a null string to terminate list (just a precaution)
 
298
    */
 
299
   outlist[nvars] = NULL;
 
300
 
 
301
   if (has_dirs) lite_SC_string_sort(outlist, nvars);
 
302
   *num = nvars;
 
303
     
 
304
   return(outlist);
 
305
}
 
306
 
 
307
 
 
308
/*-------------------------------------------------------------------------
 
309
 * Function:    lite_PD_pwd
 
310
 *
 
311
 * Purpose:     Returns the current working directory.
 
312
 *
 
313
 * Return:      Success:        A ptr to a statically allocated buffer
 
314
 *                              which contains the name of the current
 
315
 *                              directory.
 
316
 *
 
317
 *              Failure:        NULL
 
318
 *
 
319
 * Programmer:  Adapted from PACT PDB
 
320
 *              Mar  4, 1996 11:31 AM EST
 
321
 *
 
322
 * Modifications:
 
323
 *
 
324
 *-------------------------------------------------------------------------
 
325
 */
 
326
char *
 
327
lite_PD_pwd(PDBfile *file) {
 
328
 
 
329
   static char          cwd[MAXLINE];
 
330
 
 
331
   lite_PD_err[0] = '\0';
 
332
 
 
333
   if (file == NULL) {
 
334
      sprintf(lite_PD_err, "ERROR: BAD FILE ID - PF_PWD\n");
 
335
      return(NULL);
 
336
   }
 
337
 
 
338
   if ((file->current_prefix == NULL) ||
 
339
       (strcmp(file->current_prefix, "/") == 0)) {
 
340
      strcpy(cwd, "/");
 
341
   } else {
 
342
      strcpy(cwd, file->current_prefix);
 
343
      cwd[strlen(cwd) - 1] = '\0';
 
344
   }
 
345
   return(cwd);
 
346
}
 
347
 
 
348
 
 
349
/*-------------------------------------------------------------------------
 
350
 * Function:    _lite_PD_fixname
 
351
 *
 
352
 * Purpose:     Make full pathname from current working directory
 
353
 *              and the given pathname (absolute or relative)
 
354
 *
 
355
 * Return:      Success:        Ptr to a static character buffer which
 
356
 *                              holds the name.
 
357
 *
 
358
 *              Failure:        NULL
 
359
 *
 
360
 * Programmer:  Adapted from PACT PDB
 
361
 *              Mar  4, 1996  4:40 PM EST
 
362
 *
 
363
 * Modifications:
 
364
 *  Sean Ahern, Thu Jul  2 11:01:32 PDT 1998
 
365
 *  Fixed some indexing problems on strings.
 
366
 *
 
367
 *-------------------------------------------------------------------------
 
368
 */
 
369
char *
 
370
_lite_PD_fixname (PDBfile *file, char *inname) {
 
371
 
 
372
   static char  outname[MAXLINE];
 
373
   char         *node;
 
374
   char         tmpstr[MAXLINE];
 
375
 
 
376
   if ((file == NULL) || (inname == NULL)) return(NULL);
 
377
 
 
378
   outname[0] = '\0';
 
379
 
 
380
   if (!PD_has_directories(file)) {
 
381
      /*
 
382
       * If no directories, just copy verbatim.
 
383
       */
 
384
      strcpy(outname, inname);
 
385
   } else {
 
386
      /*
 
387
       * Break path into slash-separated tokens.
 
388
       * Process each node individually.
 
389
       */
 
390
      if (inname[0] != '/') strcpy(outname, lite_PD_pwd(file));
 
391
      strcpy(tmpstr, inname);
 
392
      node = (char *) strtok(tmpstr, "/");
 
393
          
 
394
      while (node != NULL) {
 
395
         if (strcmp(".",  node) == 0) {
 
396
            /*void*/
 
397
         } else if (strcmp("..", node) == 0) {
 
398
            /*
 
399
             *  Go up one level, unless already at top.
 
400
             */
 
401
            if (strcmp("/", outname) != 0) {
 
402
               char  *s;
 
403
               if (outname[strlen(outname) - 1] == '/') {
 
404
                  outname[strlen(outname) - 1] = '\0';
 
405
               }
 
406
               s = strrchr(outname, '/');
 
407
               if (s != NULL) s[0] = '\0';
 
408
            }
 
409
         } else {
 
410
            /*
 
411
             * Append to end of current path.
 
412
             */
 
413
            if ((strlen(outname) == 0) ||
 
414
                (outname[strlen(outname) - 1] != '/'))
 
415
                strcat(outname, "/");
 
416
            strcat(outname, node);
 
417
         }
 
418
         node = (char *) strtok(NULL, "/");
 
419
      }
 
420
 
 
421
      if ((strlen(inname) > 0) &&
 
422
          (inname[strlen(inname) - 1] == '/') &&
 
423
          (outname[strlen(outname) - 1] != '/'))
 
424
         strcat(outname, "/");
 
425
   }
 
426
 
 
427
   if (outname[0] == '\0') strcpy(outname, "/");
 
428
   return(outname);
 
429
}
 
430
 
 
431
 
 
432
 
 
433
/*-------------------------------------------------------------------------
 
434
 * Function:    lite_PD_mkdir
 
435
 *
 
436
 * Purpose:     Create a directory.  The directory may be specified by an
 
437
 *              absolute or relative path.
 
438
 *
 
439
 * Return:      Success:        TRUE
 
440
 *
 
441
 *              Failure:        FALSE
 
442
 *
 
443
 * Programmer:  Adapted from PACT
 
444
 *              Apr 17, 1996
 
445
 *
 
446
 * Modifications:
 
447
 *
 
448
 *-------------------------------------------------------------------------
 
449
 */
 
450
#ifdef PDB_WRITE
 
451
int
 
452
lite_PD_mkdir (PDBfile *file, char *dirname) {
 
453
 
 
454
   int dir;
 
455
   char name[MAXLINE], head[MAXLINE];
 
456
   char *s;
 
457
   static int dir_num = 0;
 
458
     
 
459
   lite_PD_err[0] = '\0';
 
460
 
 
461
   if (file == NULL) {
 
462
      sprintf(lite_PD_err, "ERROR: BAD FILE ID - PD_MKDIR\n");
 
463
      return(FALSE);
 
464
   }
 
465
 
 
466
   if (dirname == NULL) {
 
467
      sprintf(lite_PD_err, "ERROR: DIRECTORY NAME NULL - PD_MKDIR\n");
 
468
      return(FALSE);
 
469
   }
 
470
     
 
471
   /*
 
472
    * Define type "Directory", if it hasn't been already.
 
473
    */
 
474
   if (!PD_has_directories(file)) {
 
475
      if ((lite_PD_defncv(file, "Directory", 1, 0)) == NULL) return FALSE;
 
476
          
 
477
      /*
 
478
       * Write out the root directory.
 
479
       */
 
480
      dir  = dir_num;
 
481
      if (!lite_PD_write(file, "/", "Directory", &dir)) return(FALSE);
 
482
      dir_num++;
 
483
   }
 
484
 
 
485
   /*
 
486
    * Build an absolute pathname.
 
487
    */
 
488
   strcpy(name, _lite_PD_fixname(file, dirname));
 
489
   if (name[strlen(name) - 1] != '/') strcat(name, "/");
 
490
 
 
491
   /*
 
492
    * Make sure this directory hasn't already been created.
 
493
    */
 
494
   if (lite_PD_inquire_entry(file, name, FALSE, NULL) != NULL) {
 
495
      sprintf(lite_PD_err, "ERROR: DIRECTORY %s ALREADY EXISTS - PD_MKDIR\n",
 
496
              name);
 
497
      return(FALSE);
 
498
   }
 
499
 
 
500
   /*
 
501
    * Make sure the next higher level directory already exists.
 
502
    */
 
503
   strcpy(head, name);
 
504
   head[strlen(head) - 1] = '\0';
 
505
   s = strrchr(head, '/');
 
506
   if (s != NULL) {
 
507
      s[1] = '\0';
 
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 - "
 
511
                 "PD_MKDIR\n", head);
 
512
         return(FALSE);
 
513
      }
 
514
   }
 
515
 
 
516
   /*
 
517
    * Write the directory variable.
 
518
    */
 
519
   dir = dir_num;
 
520
   if (!lite_PD_write(file, name, "Directory", &dir)) return(FALSE);
 
521
   dir_num++;
 
522
     
 
523
   return(TRUE);
 
524
}
 
525
#endif /* PDB_WRITE */