/* * Fwild and fnext for vms. See rmsio.c for more information. */ #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define EOS 0 typedef struct rmsstuff { int flag; /* Flag for nonwildcard calls */ char *wildmode; struct FAB fab; struct NAM nam; char starname[NAM$C_MAXRSS + 1]; char filename[NAM$C_MAXRSS + 1]; } RMSSTUFF; static RMSSTUFF *wilddata[_NFILE]; /* RMS struct for each file */ /* * rms->flag can take on the following values: * ISWILD A file with wild-card bytes. * UNWILD A file without wild-cards, unopened. * UNWILD_OPENED A file without wild-cards, opened. */ #define ISWILD 0 #define UNWILD 1 #define UNWILD_OPENED 2 extern FILE *cleanup(); FILE * fwild(filename, mode) char *filename; char *mode; /* * Do wildcard setup */ { register FILE *fd; register RMSSTUFF *r; register int index; /* * First get a file to work with */ if ((fd = fopen("_nl:", "r")) == NULL) { return (NULL); } /* * Warning: the package depends on fileno(fd) remaining unchanged * after calls to freopen(). */ index = fileno(fd); /* * If we've been here before, make sure buffers are released. */ cleanup(index); if ((r = malloc(sizeof (RMSSTUFF))) == NULL || (r->wildmode = malloc(strlen(mode) + 1)) == NULL) return(cleanup(index)); strcpy(r->wildmode, mode); wilddata[index] = r; /* * Setup the fab and nam blocks. */ r->fab = cc$rms_fab; /* Initialize fab */ r->nam = cc$rms_nam; /* and nam blocks */ r->fab.fab$l_nam = &r->nam; /* fab -> nam */ r->fab.fab$l_fna = filename; /* Argument filename */ r->fab.fab$b_fns = strlen(filename); /* filename size */ r->nam.nam$l_esa = r->starname; /* Expanded file name */ r->nam.nam$b_ess = NAM$C_MAXRSS + 1; /* ... size */ r->nam.nam$l_rsa = r->filename; /* Result filename */ r->nam.nam$b_rss = NAM$C_MAXRSS + 1; /* ... size */ /* * Parse the file name */ if (sys$parse(&r->fab) != RMS$_NORMAL) return (cleanup(index)); /* * Success. Null-terminate expanded file name and set flag to * distinguish between "wild" and "non-wild" filenames. */ ((char *)r->nam.nam$l_esa)[r->nam.nam$b_esl] = EOS; r->flag = ((r->nam.nam$l_fnb & NAM$M_WILDCARD) == 0) ? UNWILD : ISWILD; return (fd); } FILE * fnext(fd) FILE *fd; /* * Open the next valid file. return fd if successful, NULL if finished. */ { register int index; register RMSSTUFF *r; register int errorcode; index = fileno(fd); if ((r = wilddata[index]) == NULL || r->flag == UNWILD_OPENED) { /* * It wasn't ours, or wasn't a wildcard and * has already been processed. */ fclose(fd); fd = NULL; } else if (r->flag == UNWILD) { /* * Not a wildcard file, first time through */ fd = freopen(r->starname, r->wildmode, fd); r->flag = UNWILD_OPENED; } else { /* * Look for the next match -- who says you can't write * obscure structured code? */ for (;;) { /* * Look 'em up but skip any with * protection violation errors. */ r->fab.fab$w_ifi = 0; /* Internal file index */ if ((errorcode = sys$search(&r->fab)) == RMS$_NORMAL) { /* * We have a file. Open it if we have access rights. */ ((char *)r->nam.nam$l_rsa)[r->nam.nam$b_rsl] = EOS; if (access(r->filename, 4) != 0) { /* * The file exists, but we don't have read access. * Try for another. */ continue; } else { /* * We should be able to open the file. It this * fails, something is wrong inside the C library. */ fd = freopen(r->filename, r->wildmode, fd); break; } } else if (errorcode == RMS$_PRV) { /* * sys$search() found something, but we don't have * privileges to open it. Look for another. */ continue; } else { /* * Can't find a file. This should be RMS$_NMF. */ fclose(fd); fd = NULL; break; } } } /* * Cleanup if any errors */ if (fd == NULL) { cleanup(index); } return (fd); } static FILE * cleanup(index) register int index; /* * Empty out any stored information */ { register RMSSTUFF *r; r = wilddata[index]; if (r != NULL) { if (r->wildmode != NULL) { free(r->wildmode); } free(r); wilddata[index] = NULL; } return (NULL); }