include include define SZ_RSRSTRUCT 6 define RSR_TOP Memi[$1] define RSR_MAX Memi[$1+1] define RSR_LISTPTR Memi[$1+2] define RSR_PATPTR Memi[$1+3] define RSR_VFNPTR Memi[$1+4] define RSR_OSFNPTR Memi[$1+5] define RSR_LIST Memi[RSR_LISTPTR($1)+RSR_TOP($1)-1] define RSR_PAT Memc[RSR_PATPTR($1)] define RSR_VFN Memc[RSR_VFNPTR($1)] define RSR_OSFN Memc[RSR_OSFNPTR($1)] .help rsearch .nf___________________________________________________________________________ RSEARCH -- Recursively search a directory for files matching a pattern B.Simon 01-May-1989 Original B.Simon 29-Aug-1990 Changed to allow absolute pathnames B.Simon 10-Oct-1990 Changed '*' to '?*' B.Simon 04-Aug-1992 Added call to fixpath The following three procedures allow a program to search a directory recursively, that is, not only is the top directory searched, but also all subdirectories of that directory. The search is initiated by calling opnrsearch(), which sets up the stack used to support the recursive search. Then each file is retrieved by a call to getrsearch(), which retrieves the file name and file information. Finally, the data structure is released by a call to clsrsearch(). .endhelp______________________________________________________________________ # OPNRSEARCH -- Open a recursive directory search pointer procedure opnrsearch (dir, pattern, maxdepth) char dir[ARB] # i: Top level directory name char pattern[ARB] # i: Pattern to match in search int maxdepth # i: Maximum depth to search #-- int status, ic pointer sp, osfn, template, errmsg, ch, p string notrans "Cannot understand directory name (%s)" int patmake() pointer opndirlist() begin # Allocate memory for temporary strings call smark (sp) call salloc (osfn, SZ_PATHNAME, TY_CHAR) call salloc (template, SZ_PATHNAME, TY_CHAR) call salloc (errmsg, SZ_LINE, TY_CHAR) # Allocate memory for recursive search structure call calloc (p, SZ_RSRSTRUCT, TY_INT) call malloc (RSR_LISTPTR(p), max(1, maxdepth), TY_INT) call malloc (RSR_PATPTR(p), SZ_FNAME, TY_CHAR) call malloc (RSR_VFNPTR(p), SZ_PATHNAME, TY_CHAR) call malloc (RSR_OSFNPTR(p), SZ_PATHNAME, TY_CHAR) # Initialize structure RSR_TOP(p) = 1 RSR_MAX(p) = max(1, maxdepth) if (pattern[1] == EOS) { RSR_PAT(p) = EOS } else { ic = 1 ch = template while (pattern[ic] != EOS) { if (pattern[ic] == '*') { Memc[ch] = '?' ch = ch + 1 } Memc[ch] = pattern[ic] ch = ch + 1 ic = ic + 1 } Memc[ch] = EOS status = patmake (Memc[template], RSR_PAT(p), SZ_FNAME) } RSR_VFN(p) = EOS # Translate directory name to OS format call fmapfn (dir, Memc[osfn], SZ_FNAME) call strupk (Memc[osfn], Memc[osfn], SZ_FNAME) call zfpath (Memc[osfn], RSR_OSFN(p), SZ_PATHNAME, status) if (status != ERR) call zfsubd (RSR_OSFN(p), SZ_PATHNAME, "", status) if (status == ERR) { call sprintf (Memc[errmsg], SZ_LINE, notrans) call pargstr (dir) call error (1, Memc[errmsg]) } # Open the top level directory RSR_LIST(p) = opndirlist (RSR_OSFN(p)) call sfree (sp) return (p) end # GETRSEARCH -- Get the next file in the recursive search bool procedure getrsearch (p, info, fname, maxch) pointer p # i: Pointer to recursive search structure long info[LEN_FINFO] # o: Information about the file char fname[ARB] # o: File name int maxch # i: Declared length of file name and path #-- bool found char slash int status pointer sp, ic, jc, file, osfile, path data slash / '/' / string noback "Cannot back up OS directory chain" string nodown "Cannot descend OS directory chain" pointer opndirlist() int getdirlist(), finfo(), pat_amatch(), strlen() begin # Allocate memory for temporary strings call smark (sp) call salloc (file, SZ_FNAME, TY_CHAR) call salloc (osfile, SZ_FNAME, TY_CHAR) call salloc (path, SZ_PATHNAME, TY_CHAR) found = false while (! found) { # Fetch next file name # Close directory list if no more files in directory while (getdirlist (RSR_LIST(p), Memc[file], maxch) == EOF) { call clsdirlist (RSR_LIST(p)) RSR_TOP(p) = RSR_TOP(p) - 1 if (RSR_TOP(p) == 0) { fname[1] = EOS return (false) } # Reset directory names to previous directory jc = RSR_VFNPTR(p) for (ic = RSR_VFNPTR(p); Memc[ic] != EOS; ic = ic + 1) { if (Memc[ic] == '/' && Memc[ic+1] != EOS) jc = ic + 1 } Memc[jc] = EOS call zfsubd (RSR_OSFN(p), SZ_PATHNAME, "..", status) if (status == ERR) call error (1, noback) call fixpath (RSR_OSFN(p)) } call strcpy (RSR_OSFN(p), Memc[path], SZ_PATHNAME) call fmapfn (Memc[file], Memc[osfile], SZ_FNAME) call strupk (Memc[osfile], Memc[osfile], SZ_FNAME) call strcat (Memc[osfile], Memc[path], SZ_PATHNAME) status = finfo (Memc[path], info) if (status != ERR) { # If the file is a directory and we have not reached # the maximum depth, open the subdirectory if (FI_TYPE(info) == FI_DIRECTORY) { if (RSR_TOP(p) < RSR_MAX(p)) { # Change the directory names to include # the subddirectory call strcat (Memc[file], RSR_VFN(p), SZ_PATHNAME) call strcat ("/", RSR_VFN(p), SZ_PATHNAME) call zfsubd (RSR_OSFN(p), SZ_PATHNAME, Memc[file], status) if (status == ERR) call error (1, nodown) RSR_TOP(p) = RSR_TOP(p) + 1 RSR_LIST(p) = opndirlist (RSR_OSFN(p)) } # Copy the file name to the output string # with the virtual file name as a prefix } else { if (RSR_PAT(p) == EOS) found = true else found = pat_amatch (Memc[file], 1, RSR_PAT(p)) == strlen (Memc[file]) } } } call strcpy (RSR_VFN(p), fname, maxch) call strcat (Memc[file], fname, maxch) call sfree (sp) return (true) end procedure clsrsearch (p) pointer p # io: Pointer to recursive search structure #-- begin if (p == NULL) return if (RSR_LISTPTR(p) != NULL) { call mfree (RSR_LISTPTR(p), TY_INT) RSR_LISTPTR(p) = NULL } if (RSR_PATPTR(p) != NULL) { call mfree (RSR_PATPTR(p), TY_CHAR) RSR_PATPTR(p) = NULL } if (RSR_VFNPTR(p) != NULL) { call mfree (RSR_VFNPTR(p), TY_CHAR) RSR_VFNPTR(p) = NULL } if (RSR_OSFNPTR(p) != NULL) { call mfree (RSR_OSFNPTR(p), TY_CHAR) RSR_OSFNPTR(p) = NULL } call mfree (p, TY_INT) p = NULL end