1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
|
/*
* PDBDIR.C - provides a directory capability for PDBLib
*
* Source Version: 9.0
* Software Release #92-0043
*
*/
#include "cpyright.h"
#include "pdb.h"
int
_PD_link_attribute = FALSE;
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PD_CD - change the current working directory
* - The directory may be specified by an absolute or relative path.
*/
int PD_cd(file, dirname)
PDBfile *file;
char *dirname;
{char name[MAXLINE];
syment *ep;
PD_err[0] = '\0';
if (file == NULL)
{sprintf(PD_err, "ERROR: BAD FILE ID - PD_CD\n");
return(FALSE);};
if (dirname == NULL)
strcpy(name, "/");
else
{strcpy(name, _PD_fixname(file, dirname));
if (name[strlen(name) - 1] != '/')
strcat(name, "/");};
ep = PD_inquire_entry(file, name, FALSE, NULL);
if (ep == NULL)
{if (dirname == NULL)
return(FALSE);
else
{if (strcmp(name, "/") != 0)
{name[strlen(name) - 1] = '\0';
ep = PD_inquire_entry(file, name, FALSE, NULL);
strcat(name, "/");};
if (ep == NULL)
{sprintf(PD_err,
"ERROR: DIRECTORY %s NOT FOUND - PD_CD\n",
dirname);
return(FALSE);};};};
if (strcmp(ep->type, "Directory") != 0)
{sprintf(PD_err, "ERROR: BAD DIRECTORY %s - PD_CD\n", dirname);
return(FALSE);}
else
{if (file->current_prefix)
SFREE(file->current_prefix);
file->current_prefix = SC_strsavef(name, "char*:PD_CD:name");}
return(TRUE);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PD_LN - create a link to a variable
* - This function simply installs a new symbol table entry. The new
* - syment is a copy of an already existing one, but with a new name.
*/
int PD_ln(file, oldname, newname)
PDBfile *file;
char *oldname, *newname;
{syment *oldep;
char newpath[MAXLINE], oldpath[MAXLINE], dirname[MAXLINE];
char *nname, *s, **avl;
PD_err[0] = '\0';
if (file == NULL)
{sprintf(PD_err, "ERROR: BAD FILE ID - PD_LN\n");
return(FALSE);};
if (oldname == NULL)
{sprintf(PD_err, "ERROR: VARIABLE NAME NULL - PD_LN\n");
return(FALSE);};
/* if opened in read-only mode */
if (file->mode == PD_OPEN)
{sprintf(PD_err, "ERROR: FILE OPENED READ-ONLY - PD_LN\n");
return(FALSE);};
strcpy(newpath, _PD_fixname(file, newname));
nname = SC_firsttok(newpath, ".([ ");
strcpy(oldpath, _PD_fixname(file, oldname));
/* make sure the directory in newname already exists */
strcpy(dirname, nname);
s = strrchr(dirname, '/');
if ((s != NULL) && (PD_has_directories(file)))
{s[1] = '\0';
if (PD_inquire_entry(file, dirname, FALSE, NULL) == NULL)
{dirname[strlen(dirname) - 1] = '\0';
sprintf(PD_err,
"ERROR: DIRECTORY %s DOES NOT EXIST - PD_LN\n", dirname);
return(FALSE);};};
oldep = PD_inquire_entry(file, oldpath, TRUE, NULL);
if (oldep == NULL)
{sprintf(PD_err, "ERROR: VARIABLE %s NOT FOUND - PD_LN\n", oldname);
return(FALSE);};
_PD_e_install(nname, oldep, file->symtab);
if (_PD_link_attribute)
{if (!PD_inquire_attribute(file, "LINK", NULL))
if (!PD_def_attribute(file, "LINK", "char *"))
{sprintf(PD_err,
"ERROR: CANNOT CREATE LINK ATTRIBUTE - PD_LN\n");
return(FALSE);};
avl = FMAKE(char *, "PD_LN:avl");
*avl = SC_strsavef(_PD_fixname(file, oldname),
"char*:PD_LN:fname");
if (!PD_set_attribute(file, nname, "LINK", (byte *) avl))
{sprintf(PD_err, "ERROR: CANNOT SET LINK ATTRIBUTE - PD_LN\n");
return(FALSE);};};
return(TRUE);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PD_LS - return a list of all variables and directories of the specified
* - type in the specified directory. If type is null, all types are
* - returned. If path is null, the root directory is searched.
* - Directories are terminated with a slash.
*/
char **PD_ls(file, path, type, num)
PDBfile *file;
char *path;
char *type;
int *num;
{syment *ep;
char **varlist, **outlist;
char *name;
char pattern[MAXLINE];
int ne, nvars, i, has_dirs, head, pass;
PD_err[0] = '\0';
*num = 0;
ne = file->symtab->nelements;
if (file == NULL)
{sprintf(PD_err, "ERROR: BAD FILE ID - PD_LS\n");
return(NULL);};
if (num == NULL)
{sprintf(PD_err, "ERROR: LAST ARGUMENT NULL - PD_LS\n");
return(NULL);};
if (ne == 0)
return(NULL);
/* determine if file contains directories and
* build a pattern which names must match e.g., '/dir/abc*'
*/
if (PD_has_directories(file))
{has_dirs = TRUE;
if (path == NULL)
{if (strcmp(PD_pwd(file), "/") == 0)
strcpy(pattern, "/*");
else
sprintf(pattern, "%s/*", PD_pwd(file));}
else
{strcpy(pattern, _PD_fixname(file, path));
ep = PD_inquire_entry(file, pattern, FALSE, NULL);
if ((ep != NULL) && (strcmp(ep->type, "Directory") == 0))
{if (pattern[strlen(pattern) - 1] == '/')
strcat(pattern, "*");
else
strcat(pattern, "/*");}
else
{if (pattern[strlen(pattern) - 1] != '/')
{strcat(pattern, "/");
ep = PD_inquire_entry(file, pattern, FALSE, NULL);
if ((ep != NULL) && (strcmp(ep->type, "Directory") == 0))
strcat(pattern, "*");
else
pattern[strlen(pattern) - 1] = '\0';}
else
{pattern[strlen(pattern) - 1] = '\0';
ep = PD_inquire_entry(file, pattern, FALSE, NULL);
if ((ep != NULL) && (strcmp(ep->type, "Directory") == 0))
strcat(pattern, "/*");
else
strcat(pattern, "/");};};};}
else
{has_dirs = FALSE;
if (path == NULL)
strcpy(pattern, "*");
else
strcpy(pattern, path);};
/* Generate the list of matching names. Note that this returns items which
* are in the requested directory AND items which are in sub-directories of
* the requested directory. In other words, all names which BEGIN with the
* requested pattern are returned.
*/
nvars = 0;
outlist = FMAKE_N(char *, ne + 1, "PD_LS:outlist");
/* The second pass is in case variables were written to the file before
* the first directory was created. Such variables lack an initial slash.
*/
for (pass = 1; pass <= 2; pass++)
{if (pass == 2)
if (has_dirs && (strchr(pattern + 1, '/') == NULL))
strcpy(pattern, pattern + 1);
else
break;
varlist = SC_hash_dump(file->symtab, pattern);
if ((varlist == NULL) || (varlist[0] == NULL))
continue;
/* save only those variables which are IN the requested directory
* (not in sub-directories), and are of the requested type
*/
for (i = 0; (i < ne) && (varlist[i] != NULL); i++)
/* The entry '/' (the root directory) is a special case. It
* is not a child of any directory, so should be ignored.
*/
{if (strcmp("/", varlist[i]) == 0)
continue;
/* check to see if type of this variable matches request */
if (type != NULL)
{ep = PD_inquire_entry(file, varlist[i], FALSE, NULL);
if (strcmp(ep->type, type) != 0)
continue;};
/* If here, then variable is of right type. If this file has directories,
* check for any more slashes (/'s) in the name. If any are found, this
* is not a leaf element. NOTE: if directories are not used, slashes are
* valid charcters in file names.
*/
if (has_dirs)
{if (pattern[0] != '/')
head = 0;
else
head = strlen(pattern) - strlen(strrchr(pattern, '/')) + 1;
name = &(varlist[i])[head];
if ((strlen(name) == 0) ||
((pass == 2) && (name[0] == '/')) ||
((strchr(name, '/') != NULL) &&
(strchr(name, '/') != ((name + strlen(name) - 1)))))
continue;}
else
name = varlist[i];
/* variable is of right type and is a leaf in the requested directory */
outlist[nvars++] = name;};};
SFREE(varlist);
/* store a null string to terminate list (just a precaution) */
outlist[nvars] = NULL;
if (has_dirs)
SC_string_sort(outlist, nvars);
*num = nvars;
return(outlist);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PD_MKDIR - create a directory
* - The directory may be specified by an absolute or relative path.
*/
int PD_mkdir(file, dirname)
PDBfile *file;
char *dirname;
{int *dir, ret;
char name[MAXLINE], head[MAXLINE];
char *s;
static int dir_num = 0;
PD_err[0] = '\0';
if (file == NULL)
{sprintf(PD_err, "ERROR: BAD FILE ID - PD_MKDIR\n");
return(FALSE);};
if (dirname == NULL)
{sprintf(PD_err, "ERROR: DIRECTORY NAME NULL - PD_MKDIR\n");
return(FALSE);};
/* define type "Directory", if it hasn't been already */
if (!PD_has_directories(file))
{if ((PD_defncv(file, "Directory", 1, 0)) == NULL)
return(FALSE);
/* write out the root directory */
dir = FMAKE(int,"PD_MKDIR:dir");
*dir = dir_num;
ret = PD_write(file, "/", "Directory", dir);
SFREE(dir);
if (!ret)
return(FALSE);
file->current_prefix = SC_strsavef("/", "char*:PD_MKDIR:slash");
dir_num++;}
/* build an absolute pathname */
strcpy(name, _PD_fixname(file, dirname));
if (name[strlen(name) - 1] != '/')
strcat(name, "/");
/* make sure this directory hasn't already been created */
if (PD_inquire_entry(file, name, FALSE, NULL) != NULL)
{sprintf(PD_err,
"ERROR: DIRECTORY %s ALREADY EXISTS - PD_MKDIR\n", name);
return(FALSE);};
/* make sure the next higher level directory already exists */
strcpy(head, name);
head[strlen(head) - 1] = '\0';
s = strrchr(head, '/');
if (s != NULL)
{s[1] = '\0';
if (PD_inquire_entry(file, head, FALSE, NULL) == NULL)
{head[strlen(head) - 1] = '\0';
sprintf(PD_err,
"ERROR: DIRECTORY %s DOES NOT EXIST - PD_MKDIR\n", head);
return(FALSE);};};
/* write the directory variable */
dir = FMAKE(int,"PD_MKDIR:dir");
*dir = dir_num;
ret = PD_write(file, name, "Directory", dir);
SFREE(dir);
if (ret)
dir_num++;
return(ret);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* PD_PWD - return the current working directory */
char *PD_pwd(file)
PDBfile *file;
{static char cwd[MAXLINE];
PD_err[0] = '\0';
if (file == NULL)
{sprintf(PD_err, "ERROR: BAD FILE ID - PF_PWD\n");
return(NULL);};
if ((file->current_prefix == NULL) ||
(strcmp(file->current_prefix, "/") == 0))
strcpy(cwd, "/");
else
{strcpy(cwd, file->current_prefix);
cwd[strlen(cwd) - 1] = '\0';}
return(cwd);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* _PD_FIXNAME - make full pathname from current working directory
* - and the given pathname (absolute or relative)
*/
char *_PD_fixname(file, inname)
PDBfile *file;
char *inname;
{static char outname[MAXLINE];
char *node, *s;
char tmpstr[MAXLINE];
if ((file == NULL) || (inname == NULL))
return(NULL);
outname[0] = '\0';
if (!PD_has_directories(file))
/* if no directories, just copy verbatim */
strcpy(outname, inname);
else
/* Break path into slash-separated tokens.
* Process each node individually.
*/
{if (inname[0] != '/')
strcpy(outname, PD_pwd(file));
strcpy(tmpstr, inname);
node = (char *) SC_strtok(tmpstr, "/", s);
while (node != NULL)
{if (strcmp(".", node) == 0)
{/* no-op */}
/* go up one level, unless already at top */
else if (strcmp("..", node) == 0)
{if (strcmp("/", outname) != 0)
{char *s;
if (outname[strlen(outname) - 1] == '/')
outname[strlen(outname) - 1] = '\0';
s = strrchr(outname, '/');
if (s != NULL)
s[0] = '\0';};}
/* append to end of current path */
else
{if (outname[strlen(outname) - 1] != '/')
strcat(outname, "/");
strcat(outname, node);}
node = (char *) SC_strtok(NULL, "/", s);};
if ((inname[strlen(inname) - 1] == '/') &&
(outname[strlen(outname) - 1] != '/'))
strcat(outname, "/");};
if (outname[0] == '\0')
strcpy(outname, "/");
return(outname);}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
|