diff options
Diffstat (limited to 'unix/boot/rmfiles')
-rw-r--r-- | unix/boot/rmfiles/README | 4 | ||||
-rw-r--r-- | unix/boot/rmfiles/mkpkg.sh | 6 | ||||
-rw-r--r-- | unix/boot/rmfiles/rmfiles.c | 383 | ||||
-rw-r--r-- | unix/boot/rmfiles/rmfiles.hlp | 95 |
4 files changed, 488 insertions, 0 deletions
diff --git a/unix/boot/rmfiles/README b/unix/boot/rmfiles/README new file mode 100644 index 00000000..45bc830c --- /dev/null +++ b/unix/boot/rmfiles/README @@ -0,0 +1,4 @@ +RMFILES -- Descend a directory tree, removing or listing all the specified + files therein. This is similar to the RMBIN utility, except that + it is not limited to removing binary files. This task is used to + strip production versions of the system down to the essentials. diff --git a/unix/boot/rmfiles/mkpkg.sh b/unix/boot/rmfiles/mkpkg.sh new file mode 100644 index 00000000..43d8dbd3 --- /dev/null +++ b/unix/boot/rmfiles/mkpkg.sh @@ -0,0 +1,6 @@ +# Make and install the RMFILES utility. + +$CC -c $HSI_CF rmfiles.c +$CC $HSI_LF rmfiles.o $HSI_LIBS -o rmfiles.e +mv -f rmfiles.e ../../hlib +rm *.o diff --git a/unix/boot/rmfiles/rmfiles.c b/unix/boot/rmfiles/rmfiles.c new file mode 100644 index 00000000..a6321d41 --- /dev/null +++ b/unix/boot/rmfiles/rmfiles.c @@ -0,0 +1,383 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#define import_spp +#define import_knames +#include <iraf.h> + +#include "../bootProto.h" + + +#define MAXEXTN 128 +#define ALL 0 /* delete all files */ +#define ALLBUT 1 /* delete all but listed files */ +#define ONLY 2 /* delete only listed files */ + +int verbose; /* print names of deleted files */ +int execute; /* permission to delete files */ +int debug; /* print debugging info */ + +extern char *vfn2osfn(); + + +extern int ZZSTRT (void); +extern int ZZSTOP (void); + +static void rmfiles (char *prog, int oneliner); +static void stripdir (char *dir, char *path, char *extnlist[], int mode); +static int got_one (char *fname, char *extnlist[]); + + +/* + * RMFILES -- Delete all files with the listed extensions in the listed + * directory trees. + * + * rmfiles [-dnv] [-f progfile] dir action extns + * + * -d debug + * -n no execute; do not delete files + * -v print names of files as they are deleted + * -f progfile name of file containing program script + * dir root directory of tree to be pruned + * action one of "-all", "-allbut", "-only" + * extns extensions of files to be deleted + * + * There is no default action as a safety measure. If -all is specifed, + * the extension list is ignored. + */ +int main (int argc, char *argv[]) +{ + char prog[SZ_LINE+1]; + char *argp, *ip, *op; + int oneliner, argno; + + ZZSTRT(); + + if (argc < 2) + goto help_; + + verbose = 0; + execute = 1; + debug = 0; + + for (argno=1; (argp = argv[argno]) != NULL; argno++) + if (*argp == '-') { + for (argp++; *argp; argp++) + switch (*argp) { + case 'd': + debug++; + break; + case 'n': /* no execute */ + execute = 0; + /* fall through */ + case 'v': /* set verbose mode */ + verbose = 1; + break; + + case 'f': + argno++; + if (argv[argno] == NULL) { + fprintf (stderr, "illegal `-f progfile' switch\n"); + exit (OSOK+1); + } + rmfiles (argv[argno], oneliner=NO); + break; + + default: + goto help_; + } + + } else { + /* Program is on command line. The rest of the command + * line is assumed to be the program. + */ + for (op=prog; (ip = argv[argno]) != NULL; argno++) { + while ((*op = *ip++)) + op++; + *op++ = ' '; + } + *op = EOS; + + rmfiles (prog, oneliner=YES); + break; + } + + + ZZSTOP(); + exit (OSOK); +help_: + fprintf (stderr, "rmfiles [-dnv] [-p prog] [progfile]\n"); + ZZSTOP(); + exit (OSOK+1); + + return (0); +} + + +/* RMFILES -- Strip (delete) the indicated files in the indicated + * directories. We are driven either by a program in the named text file, + * or in the prog string itself. + */ +static void +rmfiles ( + char *prog, /* program, or program file name */ + int oneliner /* if !oneliner, open program file */ +) +{ + char dir[SZ_PATHNAME+1], path[SZ_PATHNAME+1]; + char *extnlist[MAXEXTN], *ip, *op; + char lbuf[SZ_LINE+1]; + int nextn, mode; + FILE *fp = NULL; + + if (debug) { + fprintf (stderr, "rmfiles @(%s), exe=%d, ver=%d\n", prog, execute, + verbose); + fflush (stderr); + } + + /* Is program in a file, or in the "prog" string? + */ + if (oneliner) + strcpy (lbuf, prog); + else { + /* Open the program file. + */ + if ((fp = fopen (vfn2osfn(prog,0), "r")) == NULL) { + fprintf (stderr, "cannot open progfile `%s'\n", prog); + fflush (stderr); + return; + } + } + + while (oneliner || fgets (lbuf, SZ_LINE, fp) != NULL) { + /* Skip comment lines and blank lines, and any whitespace at + * the beginning of program lines. + */ + for (ip=lbuf; isspace(*ip); ip++) + ; + if (*ip == EOS || *ip == '#') { + if (oneliner) + break; + else + continue; + } + + /* Check for a single filename entry of the form `-file filename', + * deleting the named file if this type of entry is encountered. + */ + if (strncmp (ip, "-file", 5) == 0) { + for (ip=ip+5; isspace(*ip); ip++) + ; + for (op=path; (*op = *ip); ip++, op++) + if (isspace(*op)) + break; + *op = EOS; + if (*path == EOS) + continue; + + if (verbose) { + printf ("%s\n", path); + fflush (stdout); + } + + if (execute) { + if (os_delete (path) == ERR) { + fprintf (stderr, "cannot delete `%s'\n", path); + fflush (stderr); + } + } + + continue; + } + + /* Parse the program line into the directory pathname, mode, + * and extension list. The program entry must be all on one + * line. + */ + for (op=dir; (*op = *ip); ip++, op++) + if (isspace(*op)) + break; + *op = EOS; + + while (isspace(*ip)) + ip++; + if (strncmp (ip, "-allbut", 7) == 0) { + mode = ALLBUT; + ip += 7; + } else if (strncmp (ip, "-all", 4) == 0) { + mode = ALL; + ip += 4; + } else if (strncmp (ip, "-only", 5) == 0) { + mode = ONLY; + ip += 5; + } else { + fprintf (stderr, "error: no action specified: %s\n", lbuf); + fflush (stderr); + if (oneliner) + return; + else + continue; + } + + /* Construct a list of pointers to the extension strings. + */ + for (nextn=0; nextn < MAXEXTN; nextn++) { + while (isspace(*ip)) + ip++; + if (*ip == EOS || *ip == '#') + break; + + extnlist[nextn] = ip; + while (*ip && !isspace(*ip)) + ip++; + *ip++ = EOS; + } + + extnlist[nextn] = NULL; + + if (debug) { + fprintf (stderr, "rootdir=%s, mode=%d, extns:", dir, mode); + for (nextn=0; extnlist[nextn]; nextn++) + fprintf (stderr, " %s", extnlist[nextn]); + fprintf (stderr, "\n"); + fflush (stderr); + } + + /* Strip the named directory tree. + */ + path[0] = EOS; + stripdir (dir, path, extnlist, mode); + + if (oneliner) + break; + } + + if (!oneliner) + fclose (fp); +} + + +/* STRIPDIR -- Starting with the named directory, scan that directory and + * all subdirectories, deleting (or listing) the files therein depending + * on the mode, which can be ALL, ALLBUT, or ONLY. We chdir to each directory + * to minimize path searches. + */ +static void +stripdir ( + char *dir, /* start with this directory */ + char *path, /* pathname of current directory */ + char *extnlist[], /* list of file extensions */ + int mode /* ALL, ALLBUT, ONLY */ +) +{ + char oldpath[SZ_PATHNAME+1]; + char newpath[SZ_PATHNAME+1]; + char fname[SZ_PATHNAME+1]; + int deleteit, dp; + + if (debug) { + fprintf (stderr, "stripdir %s%s\n", path, dir); + fflush (stderr); + } + + if ((dp = os_diropen (dir)) == ERR) { + fprintf (stderr, "cannot open subdirectory `%s'\n", dir); + fflush (stderr); + return; + } + + os_fpathname ("", oldpath, SZ_PATHNAME); + sprintf (newpath, "%s%s/", path, dir); + + /* Descend into the subdirectory. + */ + if (strcmp (dir, ".") != 0) + if (os_chdir (dir) == ERR) { + os_dirclose (dp); + fprintf (stderr, "cannot change directory to `%s'\n", newpath); + fflush (stderr); + return; + } + + /* Scan through the directory. + */ + while (os_gfdir (dp, fname, SZ_PATHNAME) > 0) { + if (os_filetype (fname) == DIRECTORY_FILE) { + stripdir (fname, newpath, extnlist, mode); + continue; + } else if (mode == ALL) { + deleteit = YES; + } else { + deleteit = got_one (fname, extnlist); + if (mode == ALLBUT) + deleteit = !deleteit; + } + + if (!deleteit) + continue; + + if (verbose) { + printf ("%s%s\n", newpath, fname); + fflush (stdout); + } + + if (execute) { + if (os_delete (fname) == ERR) { + fprintf (stderr, "cannot delete `%s'\n", fname); + fflush (stderr); + } + } + } + + /* Return from the subdirectory. + */ + if (strcmp (dir, ".") != 0) + if (os_chdir (oldpath) == ERR) { + fprintf (stderr, "cannot return from subdirectory `%s'\n", + newpath); + fflush (stderr); + } + + os_dirclose (dp); +} + + +/* GOT_ONE -- Check the file extension, if there is one, to see if the + * file is on the list of extensions. + */ +static int +got_one ( + char *fname, /* file to be examined */ + char *extnlist[] /* list of extensions */ +) +{ + register char *ip, *ep; + register int ch, i; + char *extn; + + extn = NULL; + for (ip=fname; (ch = *ip); ip++) + if (ch == '.') + extn = ip; + + /* If the file has no extension it is not on the list. + */ + if (extn == NULL) + return (NO); + + /* Check the list of extensions. + */ + ch = *(extn + 1); + if (extnlist[0] != NULL) + for (i=0; (ep = extnlist[i]); i++) + if (*(ep+1) == ch) + if (strcmp (ep, extn) == 0) + return (YES); + + return (NO); +} diff --git a/unix/boot/rmfiles/rmfiles.hlp b/unix/boot/rmfiles/rmfiles.hlp new file mode 100644 index 00000000..b9e0125d --- /dev/null +++ b/unix/boot/rmfiles/rmfiles.hlp @@ -0,0 +1,95 @@ +.help rmfiles Jul86 "softools" +.ih +NAME +rmfiles -- find/remove files in subdirectories +.ih +USAGE +rmfiles [-dnv] [-f progfile] rootdir action extns +.ih +PARAMETERS +.ls 4 -d +Print debug messages. +.le +.ls 4 -n +No execute; do not delete files. This option may be used to generate +a list of binary files for some purpose other than deletion, or to verify +the delete operation before destroying the files. +.le +.ls 4 -v +Print names of files as they are deleted. +.le +.ls 4 -f progfile +Take delete commands from the named file. If this option is specified +the remaining arguments are normally omitted. +.le +.ls 4 rootdir +The root directory of the directory tree to be pruned. This must be a +path from the current directory or from a logical directory. +.le +.ls 4 action +The possible actions are listed below. This is a required parameter. +.ls +.ls 8 -all +Delete all files. +.le +.ls 8 -allbut +Delete all files except those with the listed extensions. +.le +.ls 8 -only +Delete only those files with the listed extensions. +.le +.le +.le +.ls 4 extns +A list of filename extensions delimited by spaces, e.g., ".a .o .e .hlp". +.le +.ih +DESCRIPTION +The \fIrmfiles\fR utility is used to delete (or list) files in one or more +directory trees. If only one directory tree is to be pruned the necessary +instructions can be entered on the command line, otherwise a program file +must be used. When developing a program file, a dry run using the "-n" +switch is recommended to see what files will be deleted. + +If a program file is used each line in the file has one of two possible +formats. If a directory is to be pruned the syntax is the same as is +used when a one line program is entered on the command line, i.e.: + + rootdir action extns + +The significance of each field is as described in the ARGUMENTS section +above. The program file may also contain lines of the form + + -file filename + +to delete one or more files by name. This is useful for removing files +which do not fit into any recognizable class. + +Comments and blank lines are permitted anywhere in the program file. +All filenames are IRAF virtual filenames (or host filenames). + +\fIRmfiles\fR is a bootstrap utility implemented as a foreign task, hence +it may be called either from within IRAF or from the host system. +.ih +EXAMPLES +1. Delete all .o, .e, .a, and .hd files in the directory "iraf$pkg". +Print the names of the files as they are deleted. Note that one must +move to the directory containing the directory to be pruned before running +\fIrmfiles\fR. + +.nf + cl> cd iraf + cl> rmfiles -v pkg .o .e .a .hd +.fi + +2. Strip the entire IRAF system, using the program in file "hlib$stripper". +The use of the $ in the filename here could cause problems on some systems +since \fIrmfiles\fR is a foreign task. + +.nf + cl> cd iraf + cl> rmfiles -vf hlib$stripper +.fi +.ih +SEE ALSO +rmbin, rtar, wtar |