#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'dirlib/Makefile' <<'END_OF_FILE' X# X# TOP is top of code directory, LIB is where to put X# dirLib.o X# XTOP = $(CODE) XLIB = $(TOP)/prot X X# X# define include search path, compiler tools X# XH0 = $(TOP)/h XCC = $(VX_CC) XLD = $(VX_LD) XCFLAGS= -O -DVxWorks -nostdinc -I$(H0) -I$(VX_H) -I$(GCC_INC) X XFILES = dirLib.o dirSubs.o X# X# for dirLib.o shar source X# X#FILES = dirLib.o dirSubs.o wildmat.o strbld.o X X.c.o: X#### generate code X ${CC} ${CFLAGS} -x -r -c $*.c -o $*.o X Xall: ${FILES} X $(LD) -o $(LIB)/dirLib.o -r -x $(FILES) X Xsharfile: X shar Readme Makefile dirLib.3 dirLib.c dirLib.h dirSubs.c \ X wildmat.c strbld.c > dirLib.shar Xclean: X -rm -f *.o lint.log core *.BAK END_OF_FILE if test 626 -ne `wc -c <'dirlib/Makefile'`; then echo shar: \"'dirlib/Makefile'\" unpacked with wrong size! fi # end of 'dirlib/Makefile' fi if test -f 'dirlib/Readme' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/Readme'\" else echo shar: Extracting \"'dirlib/Readme'\" \(601 characters\) sed "s/^X//" >'dirlib/Readme' <<'END_OF_FILE' X X dirLib - directory library functions. X X These files use function prototyping. Most of the X work is done with dirSearchFnc() in dirLib.c. Examples X using dirSearchFnc() are in dirSubs.c. The wild card X matching software is from the public domain X tar code (1987) from comp.sources.misc. X X Send suggestions and comments to: X X fstauffer@.sunspot.noao.edu X sac peak observatory X sunspot, new mexico X XdirLib.c basic directory search function using wildcard X matching XdirSubs.c user applications built on dirLib.c Xwildmat.c public domain wild card matching Xstrbld.c fast string builder END_OF_FILE if test 601 -ne `wc -c <'dirlib/Readme'`; then echo shar: \"'dirlib/Readme'\" unpacked with wrong size! fi # end of 'dirlib/Readme' fi if test -f 'dirlib/dirLib.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/dirLib.3'\" else echo shar: Extracting \"'dirlib/dirLib.3'\" \(1463 characters\) sed "s/^X//" >'dirlib/dirLib.3' <<'END_OF_FILE' X.TH dirLib SOFT "31 Mar 1993" X.SH NAME XdirLib \- directory search, find, toss X.SH SYNOPSIS X.de Ss X.sp X.ft CW X.nf X.. X.de Se X.fi X.ft P X.sp X.. X.Ss X#include "dirLib.h" X/* X * directory search types for dirSearchFnc() X */ Xenum { X REGTYPE = 0x1, /* act on regular file types */ X DIRTYPE = 0x2, /* act on directory types */ X RECDIR = 0x4 /* recursively follow directory tree */ X }; X.Se X.TP 20 X.BI "int dir(" "char *directory") Xpretty directory list for directory X.TP 20 X.BI "int toss(" "char *name") Xtoss files with wildcards X.TP 20 X.BI "int dump(" "char *d0, char *d1") Xdump files from directory 0 to directory 1 X.TP 20 X.BI "find (" "char *base, char *name, int (*fnc) ()") Xfind execute name starting from base directory and execute Xfnc() with no arguments. If fnc() is not specified, then Xfind prints the filename. This is useful from command line Xto search for a name. X.TP 20 X.BI "int dtree (" "char *base, int (*fnc) ()") Xexecute directory tree from base. As each directory is found, Xexecute fnc() with no arguments. If fnc() is NULL, then Xprint the directory name. This is a good way to print the Xdirectory tree from command line. X.TP 20 X.BI "int dirSearchFnc(" "char *name, int type, int (*fnc)(),...") Xsearch for wildcard name using search type. execute fnc() on match Xpassing the name of the file and variable argument list to fnc(). Xfnc()'s arguments are fnc(char *name, ...). X.SH "SEE ALSO" Xwildmat() wild card matcher and strbld() string builder END_OF_FILE if test 1463 -ne `wc -c <'dirlib/dirLib.3'`; then echo shar: \"'dirlib/dirLib.3'\" unpacked with wrong size! fi # end of 'dirlib/dirLib.3' fi if test -f 'dirlib/dirLib.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/dirLib.c'\" else echo shar: Extracting \"'dirlib/dirLib.c'\" \(2406 characters\) sed "s/^X//" >'dirlib/dirLib.c' <<'END_OF_FILE' X X#include "vxWorks.h" X#include "ioLib.h" X#include "stdioLib.h" X X#include "clib.h" X#include "dirent.h" X#include "stat.h" X#include "local.h" X/* #define DEBUG /* helpme */ X X/* X * dirLib.c - directory stuff X * X */ X X#include "stddef.h" X#include "stdarg.h" X/* X * dirSearcFnc - search directory for names, execute function. X * X * RETURNS: OK or ERROR if can not open directory X */ Xint XdirSearchFnc (char *name, int type, int (*fnc) (),...) X{ X char string[40]; X char bstring[40]; X int len = 0; X char *file = name; X char *base; X struct dirent *de; X struct stat deStat; X DIR *fd; X char *ep; X FAST va_list ap; X char *fp[10]; X int i = 0; X if (!name || !fnc) X return ERROR; X X va_start (ap, fnc); X while (i < 10 && (fp[i] = va_arg (ap, char *))) X i++; X while (i < 10) X fp[i++] = 0; X X base = name; X len = strlen (name); X if (*(name + len) == '/') /* lop off directory slash */ X *(name + len) = 0; X X len = 0; X if (!(fd = opendir (name))) /* name did not work, strip base */ X { X if (rindex (base, '/')) /* strip off directory base */ X { X strcpy (bstring, base); X base = bstring; X ep = rindex (bstring, '/'); X *ep++ = 0; X file = ep; X } X else X base = "."; /* current directory */ X fd = opendir (base); X if (fd == NULL) /* no way */ X { X va_end (ap); X return ERROR; X } X } X len = strlen (file); X if (*(file + len) == '*') X len--; X if (*file == '*') X len--; X#ifdef DEBUG X printf ("base name %s, file %s, len %d\n", base, file, len); X#endif X X while (de = readdir (fd)) X { X stat (strbld (string, base, "/", de->d_name, 0), &deStat); X if (*de->d_name == EOS || X !strcmp (de->d_name, ".") || X !strcmp (de->d_name, "..")) X continue; X if (S_ISDIR (deStat.st_mode)) X { X if (type & RECDIR) /* recursive search */ X { X char temp[40]; X strbld (temp, string, "/", file, 0); X dirSearchFnc (temp, type, fnc, fp[0], fp[1], fp[2], fp[3], X fp[4], fp[5], fp[6], fp[7], fp[8]); X } X if (!(type & DIRTYPE)) X { X continue; X } X strbld (string, base, "/", de->d_name, "/", 0); X } else if (S_ISREG (deStat.st_mode)) X { X if (!(type & REGTYPE)) X { X continue; X } X } X#ifdef DEBUG X printf ("len %d, name %s, pattern %s\n",len,de->d_name,file); X#endif X if (!len || wildmat(de->d_name, file) == 1) X { X fnc (string, fp[0], fp[1], fp[2], fp[3], fp[4], fp[5], fp[6], X fp[7], fp[8]); X } X } X closedir (fd); X va_end (ap); X return OK; X} END_OF_FILE if test 2406 -ne `wc -c <'dirlib/dirLib.c'`; then echo shar: \"'dirlib/dirLib.c'\" unpacked with wrong size! fi # end of 'dirlib/dirLib.c' fi if test -f 'dirlib/dirLib.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/dirLib.h'\" else echo shar: Extracting \"'dirlib/dirLib.h'\" \(687 characters\) sed "s/^X//" >'dirlib/dirLib.h' <<'END_OF_FILE' X X/* X * dirLib.h - include files for dirLib and dirSub directory X * manipulation routines X */ X X/* X * different directory search function types X */ Xenum { X REGTYPE = 0x1, /* act on regular file types */ X DIRTYPE = 0x2, /* act on directory types */ X RECDIR = 0x4 /* recursively follow directory tree */ X }; X Xint dir(char *s); /* pretty directory list */ Xint toss(char *name); /* toss files with wildcards */ Xint dump(char *d0, char *d1); /* dump files from dir to dir with * */ Xint find (char *base, char *name, int (*fnc) ()); /* find and execute name */ Xint dtree (char *base, int (*fnc) ()); /* execute directory tree */ Xint dirSearchFnc(char *name, int type, int (*fnc)(),...); END_OF_FILE if test 687 -ne `wc -c <'dirlib/dirLib.h'`; then echo shar: \"'dirlib/dirLib.h'\" unpacked with wrong size! fi # end of 'dirlib/dirLib.h' fi if test -f 'dirlib/dirSubs.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/dirSubs.c'\" else echo shar: Extracting \"'dirlib/dirSubs.c'\" \(4336 characters\) sed "s/^X//" >'dirlib/dirSubs.c' <<'END_OF_FILE' X X#include "vxWorks.h" X#include "ioLib.h" X X#include "clib.h" X#include "dirent.h" X#include "stat.h" X#include "local.h" X/* #define DEBUG /* helpme */ X X/* X * dirSubs.c - directory stuff built on dirLib.c X * X * dir - pretty directory print X * X * toss - toss files X * X * dump - dump files X * X */ X X/* X * dir - pretty directory print X */ Xint Xdir (char *s) X{ X char string[40]; X int ct, ic; X int len, maxlen = 0; X struct dirent *de; X struct stat deStat; X DIR *fd; X char defpath[40]; X X /* X * if no directory, try current default path X */ X if (!s) X { X ioDefPathGet (defpath); X s = defpath; X } X fd = opendir (s); X X if (fd == NULL) X { X printf ("usage: dir [\"directory\"] - print directory\n"); X printf (" directory must be a dos or rt11 file system\n"); X return; X } X printf ("%s\n", s); /* print directory name */ X X while (de = readdir (fd)) X { X strbld (string, s, "/", de->d_name, 0); X len = strlen (de->d_name); X len = len / 8; X len = (len + 1) * 8; X maxlen = max (maxlen, len); X } X X rewinddir (fd); X maxlen += 4; /* length per entry */ X X ic = 72 / maxlen; X ct = 0; X while (de = readdir (fd)) X { X stat (strbld (string, s, "/", de->d_name, 0), &deStat); X strcpy (string, de->d_name); X len = strlen (string); X bfill (string + len, maxlen - len, ' '); X if (S_ISDIR (deStat.st_mode)) X *(string + len) = '/'; X else if (!S_ISREG (deStat.st_mode)) X *(string + len) = '@'; X *(string + maxlen) = 0; X printf ("%s", string); X if (!(++ct % ic)) X printf ("\n"); X } X if (ct % ic) X printf ("\n"); X X closedir (fd); X} X X/* X * toss files from this directory X * X * RETURNS: OK or ERROR if can not open directory X */ Xint Xtoss (char *name) X{ X if (!name) X { X printf ("\nusage: toss \"file*\" tosses all file*... files\n"); X printf( " file is complete pathname to prevent accidental toss."); X return ERROR; X } X if (dirSearchFnc (name, REGTYPE, delete, 0) == ERROR) X return ERROR; X return OK; X} X XLOCAL int d1Fnc (char *infile, char *base); X/* X * dump - dump a file system to the pwd(). X */ Xint Xdump (char *d0, char *d1) X{ X char defpath[40]; X char string[20]; X if (!d0) X { X printf ("usage: dump \"dir0\",\"dir1\"\n"); X printf (" dumps directory files between 0 and 1\n"); X printf (" if dir1 is NULL, then pwd() is used\n"); X printf ("\n example: dump \"/ram/test\"\n"); X printf (" dumps all test files to pwd directory\n"); X printf (" NOTE: must be able to ls \"d0\" and list files\n"); X return ERROR; X } X if (d1 == 0) X { X ioDefPathGet (defpath); X d1 = defpath; X } X dirSearchFnc (d0, REGTYPE, d1Fnc, d1, 0); X} X X XLOCAL int printDName (); /* print directory name */ X/* X * find and print names recursively X */ Xint Xfind (char *base, char *name, int (*fnc) ()) X{ X char string[40]; X if (!base || !name) X { X printf ("usage: find \"directory\", \"name\"\n"); X printf (" look in this directory tree for this name\n"); X printf (" name is modified with *name*, the * is wild\n"); X printf (" name without wild things must match exactly\n"); X printf (" a *name* lets the search float in filename\n"); X printf (" a name* or *name anchors name to begin or end\n"); X return ERROR; X } X if(*base) X strbld (string, base, "/", name, 0); X else X strcpy (string,name); X if (fnc) X dirSearchFnc (string, DIRTYPE | RECDIR | REGTYPE, fnc, 0); X else X dirSearchFnc (string, DIRTYPE | RECDIR | REGTYPE, printDName, 0); X return OK; X} X X/* X * print the directory tree X */ Xint Xdtree (char *base, int (*fnc) ()) X{ X char string[40]; X if (!base) X { X printf ("usage: dtree \"directory\"n"); X printf (" list this directory tree\n"); X return ERROR; X } X strbld(string,base,"/*",0); X if (fnc) X dirSearchFnc (string, RECDIR | DIRTYPE, fnc, 0); X else X dirSearchFnc (string, RECDIR | DIRTYPE, printDName, 0); X return OK; X} X X/* X * d1Fnc - build d1 names and copy X */ XLOCAL int Xd1Fnc (char *infile, char *base) X{ X char outfile[80]; X char *name; X X /* X * look at input file name, find name at end of line X */ X name = rindex (infile, '/'); X if (name) X name++; X else X name = infile; X X strbld (outfile, base, "/", name, 0); X if (copy (infile, outfile)) X printf ("copy error %s to %s\n", infile, outfile); X} X X/* X * printDName - print directory name X */ XLOCAL int XprintDName (char *string) X{ X printf ("%s\n", string); X} END_OF_FILE if test 4336 -ne `wc -c <'dirlib/dirSubs.c'`; then echo shar: \"'dirlib/dirSubs.c'\" unpacked with wrong size! fi # end of 'dirlib/dirSubs.c' fi if test -f 'dirlib/strbld.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/strbld.c'\" else echo shar: Extracting \"'dirlib/strbld.c'\" \(658 characters\) sed "s/^X//" >'dirlib/strbld.c' <<'END_OF_FILE' X#include "vxWorks.h" X#include "stddef.h" X#include "stdarg.h" X/* X * char *strbld(char *base, ...) - string build, add up X * to 8 strings to base and return pointer to first base X * X * strbld(string,arg1,arg2,arg3,0); NOTE: 0 ends list!! X * X * this is about 3 times faster than strcpy, strcat sequences, X * and is about 12 times faster than sprintf string,"%s%s...",... X * X */ Xchar * Xstrbld(char *base, ...) X{ XFAST va_list ap; XFAST char *fp; XFAST char *bp; XFAST char *dp; X X if(!base) X return NULL; X X va_start(ap,base); X *base = 0; X bp = base; X X while((fp = va_arg(ap,char *)) != (char *)0) X { X while(*bp++ = *fp++); X bp--; X } X X va_end(ap); X return base; X} END_OF_FILE if test 658 -ne `wc -c <'dirlib/strbld.c'`; then echo shar: \"'dirlib/strbld.c'\" unpacked with wrong size! fi # end of 'dirlib/strbld.c' fi if test -f 'dirlib/wildmat.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dirlib/wildmat.c'\" else echo shar: Extracting \"'dirlib/wildmat.c'\" \(3482 characters\) sed "s/^X//" >'dirlib/wildmat.c' <<'END_OF_FILE' X/* X * @(#)wildmat.c 1.3 87/11/06 Public Domain. X * XFrom: rs@mirror.TMC.COM (Rich Salz) XNewsgroups: net.sources XSubject: Small shell-style pattern matcher XMessage-ID: <596@mirror.TMC.COM> XDate: 27 Nov 86 00:06:40 GMT X XThere have been several regular-expression subroutines and one or two Xfilename-globbing routines in mod.sources. They handle lots of Xcomplicated patterns. This small piece of code handles the *?[]\ Xwildcard characters the way the standard Unix(tm) shells do, with the Xaddition that "[^.....]" is an inverse character class -- it matches Xany character not in the range ".....". Read the comments for more Xinfo. X XFor my application, I had first ripped off a copy of the "glob" routine Xfrom within the find(1) source, but that code is bad news: it recurses Xon every character in the pattern. I'm putting this replacement in the Xpublic domain. It's small, tight, and iterative. Compile with -DTEST Xto get a test driver. After you're convinced it works, install in Xwhatever way is appropriate for you. X XI would like to hear of bugs, but am not interested in additions; if I Xwere, I'd use the code I mentioned above. X*/ X/* X** Do shell-style pattern matching for ?, \, [], and * characters. X** Might not be robust in face of malformed patterns; e.g., "foo[a-" X** could cause a segmentation violation. X** X** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. X*/ X X/* X * Modified 6Nov87 by John Gilmore (hoptoad!gnu) to return a "match" X * if the pattern is immediately followed by a "/", as well as \0. X * This matches what "tar" does for matching whole subdirectories. X * X * The "*" code could be sped up by only recursing one level instead X * of two for each trial pattern, perhaps, and not recursing at all X * if a literal match of the next 2 chars would fail. X */ X#define TRUE 1 X#define FALSE 0 X X Xstatic int XStar(s, p) X register char *s; X register char *p; X{ X while (wildmat(s, p) == FALSE) X if (*++s == '\0') X return(FALSE); X return(TRUE); X} X X Xint Xwildmat(s, p) X register char *s; X register char *p; X{ X register int last; X register int matched; X register int reverse; X X for ( ; *p; s++, p++) X switch (*p) { X case '\\': X /* Literal match with following character; fall through. */ X p++; X default: X if (*s != *p) X return(FALSE); X continue; X case '?': X /* Match anything. */ X if (*s == '\0') X return(FALSE); X continue; X case '*': X /* Trailing star matches everything. */ X return(*++p ? Star(s, p) : TRUE); X case '[': X /* [^....] means inverse character class. */ X if (reverse = p[1] == '^') X p++; X for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p) X /* This next line requires a good C compiler. */ X if (*p == '-' ? *s <= *++p && *s >= last : *s == *p) X matched = TRUE; X if (matched == reverse) X return(FALSE); X continue; X } X X /* For "tar" use, matches that end at a slash also work. --hoptoad!gnu */ X return(*s == '\0' || *s == '/'); X} X X X#define TEST X#ifdef TEST X#include "stdioLib.h" X Xextern char *gets(); X X XwildTest() X{ X char pattern[80]; X char text[80]; X X while (TRUE) { X printf("Enter pattern: "); X if (gets(pattern) == NULL) X break; X while (TRUE) { X printf("Enter text: "); X if (gets(text) == NULL) X exit(0); X if (text[0] == '\0') X /* Blank line; go back and get a new pattern. */ X break; X printf(" %d\n", wildmat(text, pattern)); X } X } X exit(0); X} X#endif /* TEST */ END_OF_FILE if test 3482 -ne `wc -c <'dirlib/wildmat.c'`; then echo shar: \"'dirlib/wildmat.c'\" unpacked with wrong size! fi # end of 'dirlib/wildmat.c' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0