mohsen@retix.retix.COM (Mohsen Banan) (08/04/87)
>> Subject: bsd unix directory utilities wanted for msdos >> Keywords: opendir, readdir, telldir, seekdir, rewinddir, closedir, for MSDOS >> Has anyone out there rewritten the UNIX bsd directory >> scanning utilities to work for msdos? Are there any companies >> that sell libaries of unix compatable "procedures", but for MSDOS? >> How sells the best? We use Micro Soft "C". >> Thanks in advance. >> Neville >> address: >> calgary.uucp!vuwcomp!frc!ncd (Neville Dempsey) Last week-end, I ported a few UNIX utilities to MSDOS. In the process of doing so I ended up writing BSD style directory interface for MSDOS. I have not tested them much and they are not optimized. They appear to do the job, however. The following shar file contains four directories. include: Guess! dossup: DOS directory interfcae, getopt, traverse shar: A port of shar to MSDOS. Uses dossup. lsr: A simple recursive file listing utility. Uses dossup. You need to use MSC to compile every thing. If you make improvements to the BSD directory interface for MSDOS, please send me a copy. Mohsen Banan. retix!mohsen #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # include # dossup # lsr # shar # This archive created: Tue Aug 4 11:07:39 1987 export PATH; PATH=/bin:$PATH if test ! -d 'include' then mkdir 'include' fi cd 'include' if test -f 'eh.h' then echo shar: will not over-write existing file "'eh.h'" else cat << \SHAR_EOF > 'eh.h' /*+ * Description: * Exception Handler Module Header * -*/ /* * Author: Mohsen Banan. * History: * */ /* * SCCS Revision: @(#)eh.h 1.1 Released: 8/3/87 */ #ifndef _EH_H_ /*{*/ #define _EH_H_ #define EH_assert(expr)\ if (!(expr)) {\ fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);\ } #ifndef EH_oops /*{*/ #define EH_oops() fprintf(stderr,"OOPS: file %s, line %d\n", __FILE__, __LINE__) #endif /*}*/ #ifndef EH_fatal #define EH_fatal(str) fprintf(stderr,"FATAL: %s, %d: %s\n", __FILE__, __LINE__, (str)); exit(1); #endif #ifndef EH_problem #define EH_problem(str) fprintf(stderr,"PROBLEM: %s, %d: %s\n", __FILE__, __LINE__, (str)) #endif #ifndef EH_violation #define EH_violation(str) fprintf(stderr,"VIOLATION: %s, %d: %s\n", __FILE__, __LINE__, (str)) #endif #endif /*}*/ SHAR_EOF fi # end of overwriting check if test -f 'estd.h' then echo shar: will not over-write existing file "'estd.h'" else cat << \SHAR_EOF > 'estd.h' /*+ * Description: * * -*/ /* * Author: Mohsen Banan. * History: * */ /* * SCCS Revision: @(#)estd.h 1.1 Released: 8/3/87 */ #ifndef _ESTD_H_ /*{*/ #define _ESTD_H_ /* * The purpose of the standard definitions include file is to provide * consistent datatype definitions across different environments. * Thus, a SmInt (small integer) is always 8 bits, no matter which machine * it is compiled on. In the same, way a MdInt (medium integer) is always * 16 bits and LgInt (large integer) is always 32 bits. * */ #define SMSIZE 8 /* 8 bits in "small" */ #define MDSIZE 16 /* 16 bits in "medium" */ #define LGSIZE 32 /* 32 bits in "large" */ typedef char SmInt; /* SMSIZE-bit signed integer */ typedef short MdInt; /* MDSIZE-bit signed integer */ typedef long LgInt; /* LGSIZE-bit signed integer */ typedef unsigned char SmUns; /* SMSIZE-bit unsigned integer */ typedef unsigned short MdUns; /* MDSIZE-bit unsigned integer */ typedef unsigned long LgUns; /* LGSIZE-bit unsigned integer */ typedef unsigned char SmBits; /* SMSIZE-bit bit string */ typedef unsigned short MdBits; /* MDSIZE-bit bit string */ typedef unsigned long LgBits; /* LGSIZE-bit bit string */ typedef int Int; /* generic integer */ typedef unsigned int Uns; /* generic unsigned integer */ typedef int Bool; /* boolean, Int true or false variable */ #ifndef FALSE #define FALSE 0 /* Logical false, value 0 */ #endif #ifndef TRUE #define TRUE 1 /* Logical true, value 1 */ #endif typedef int SuccFail; /* Typical return Values */ #ifndef SUCCESS #define SUCCESS 0 #endif #ifndef FAIL #define FAIL (-1) #endif typedef unsigned char Byte; /* SMSIZE, smallest unit of addressable store */ typedef char Char; /* Single ASCII character */ typedef Char * String; /* Pointer to null-terminated charSequence */ typedef char * Ptr; /* pointer to arbitrary type */ typedef LgUns Arg; /* Uninterpreted LGSIZE-bit word */ #ifndef NULL #define NULL 0 /* universal empty result */ #endif #ifndef Void #define Void void /* null return type of procedures */ #endif #define STATIC static /* Names not needed outside this src module */ #ifndef LOCAL #define LOCAL /* Names not needed outside this software module */ #endif #define LCL_XTRN extern /* Names defines within this software module */ #ifndef PUBLIC #define PUBLIC /* Names needed outside this software module */ #endif #define EXTERN extern /* Names defined outside this software module */ #define DIMOF(array) (sizeof array / sizeof array[0]) #define ENDOF(array) (array - 1 + (sizeof array / sizeof array[0])) #ifndef OOPS #define OOPS() fprintf(stderr,"OOPS: file %s, line %d\n", __FILE__, __LINE__) #endif #ifndef PROBLEM #define PROBLEM() fprintf(stderr,"PROBLEM: file %s, line %d\n", __FILE__, __LINE__) #endif #ifndef TRACE #define TRACE() fprintf(stderr,"TRACE: file %s, line %d\n", __FILE__, __LINE__) #endif #endif /*}*/ SHAR_EOF fi # end of overwriting check if test ! -d 'sys' then mkdir 'sys' fi cd 'sys' if test -f 'dir.h' then echo shar: will not over-write existing file "'dir.h'" else cat << \SHAR_EOF > 'dir.h' /*+ * Description: * Simulation header file for BSD style directory facilities * in DOS environment. * -*/ /* * Author: Mohsen Banan. * History: * */ /* * SCCS Revision: @(#)dir.h 1.2 Released: 8/3/87 */ #ifdef MSDOS /*{*/ #ifndef _DIR_H_ /*{*/ #define _DIR_H_ #define MAXNAMLEN 13 struct direct { int d_namlen; char d_name[MAXNAMLEN]; }; typedef enum DirState { DirActive, /* While consecutive readdirs */ DirVirgin, /* Very first time when opendir */ DirInactive /* When (DIR *) stream changes */ } DirState; typedef struct { char dirName[128]; /* Name of the directory, including drive */ char *dirNameEnd; /* End of String Location for dirName */ DirState state; /* See DirState */ long index; /* Position of a file name inside the directory */ char indexName[MAXNAMLEN]; /* File Name corresponding to indexName */ } DIR ; extern DIR *opendir(); extern struct direct *readdir(); extern long telldir(); extern void seekdir(); #define rewinddir(dirp) seekdir((dirp), (long)0) extern void closedir(); #endif /*}*/ #else #include "/usr/include/sys/dir.h" #endif /*}*/ SHAR_EOF fi # end of overwriting check cd .. cd .. if test ! -d 'dossup' then mkdir 'dossup' fi cd 'dossup' if test -f 'bsddir.c' then echo shar: will not over-write existing file "'bsddir.c'" else cat << \SHAR_EOF > 'bsddir.c' /*+ * Description: * This file contains a series of functions that provide for * a BSD style directory interface in MSDOS envirnment. * -*/ /* * Author: Mohsen Banan. * History: * */ #ifdef SCCS_VER /*{*/ static char sccs[] = "@(#)bsddir.c 1.1 Released: 8/3/87"; #endif /*}*/ #include <stdio.h> #include <sys/types.h> #include <sys/dir.h> #include <ctype.h> #include <sys/stat.h> #include <dos.h> #include <direct.h> #include "eh.h" #include "dosos.h" #include <malloc.h> typedef struct DirsCB { DirDta dirDta; DIR *lastActive; int opensCount; } DirsCB; static DirsCB dirsCB; static char cwd[128]; /*< * Function: * Description: * Given a path to a directory, associate a directory * stream with it. Opendir returns a pointer to be used * in all subsequent operations on this directory. * * Arguments: * fileName: Path to the directory. * Returns: * If directory is accessible, and there is enough memory * to be allocated for processing, a (DIR *) is returned that * must be used in all subsequent operations. * Otherwize NULL is returned. >*/ DIR * opendir(fileName) char *fileName; /* path to the directory */ { DIR *thisDir; int i; struct stat buf; extern char *getAbsPath(); #define isdir(path) (stat(path, &buf) ? 0 : (buf.st_mode&S_IFMT)==S_IFDIR) #if 0 printf("opendir fileName=%s\n", fileName); #endif if ( ! isdir(fileName) ) { EH_problem("Bad argument"); return ( (DIR *) 0); } if ( strlen(fileName) >= sizeof(thisDir->dirName) ) { EH_problem("Bad argument"); return ( (DIR *) 0); } thisDir = (DIR *)malloc(sizeof(*thisDir)); if ( ! thisDir ) { EH_problem("Malloc"); return ( thisDir ); } /* Keep Dir Name, It may be needed Later */ strcpy(thisDir->dirName, getAbsPath(fileName)); i = strlen(thisDir->dirName); thisDir->dirNameEnd = thisDir->dirName + i; thisDir->state = DirVirgin; thisDir->index = 0; strcpy(thisDir->indexName, "*.*"); return ( thisDir ); } /*< * Function: * Description: * Reads in the next directory entry. * Arguments: * * Returns: * A pointer to the next directory entry. * Uppon reaching the end of the directory, NULL is returned. * >*/ struct direct * readdir( dirp ) DIR *dirp; { static struct direct dir; struct direct *retVal; char * srcPtr; char * dstPtr; if (getcwd(cwd, sizeof(cwd)) == (char *)0) { perror("getcwd"); exit(1); } if (chdir(dirp->dirName)) { perror("getcwd"); exit(1); } switch ( dirp->state ) { case DirInactive: if ( findLoc(dirp->index, &dirsCB.dirDta) ) { retVal = (struct direct *) 0; goto done; } if ( dirsCB.lastActive ) { dirsCB.lastActive->state = DirInactive; } dirsCB.lastActive = dirp; dirp->state = DirActive; /* Now it is as if it was active, * Also execute DirActive Code, do NOT break. */ case DirActive: if ( findNext(&dirsCB.dirDta) ) { retVal = (struct direct *) 0; goto done; } break; case DirVirgin: if ( findFirst(dirp->indexName, &dirsCB.dirDta, 0x3F) ) { retVal = (struct direct *) 0; goto done; } if ( dirsCB.lastActive ) { dirsCB.lastActive->state = DirInactive; } dirsCB.lastActive = dirp; dirp->state = DirActive; break; default: EH_oops(); break; } /* Now dirsCB.dirDta contains the information we need */ dirp->index++; strcpy(dirp->indexName, dirsCB.dirDta.fname); /* Do strcpy and change the case to lower */ for (srcPtr=dirsCB.dirDta.fname, dstPtr=dir.d_name; *srcPtr; ++srcPtr, ++dstPtr) { *dstPtr = tolower(*srcPtr); } *dstPtr = *srcPtr; /* '\0' terminate it */ dir.d_namlen = strlen(dirsCB.dirDta.fname); retVal = &dir; done: if (chdir(cwd)) { perror("chdir"); exit(1); } return ( retVal ); } /*< * Function: * Description: * Closes the named directory and frees the structure * associated with it. * >*/ void closedir( dirp ) DIR *dirp; { if ( dirp->state == DirActive ) { dirsCB.lastActive = (DIR *)0; } free(dirp); } /*< * Function: * Description: * Report the current location associated with the named directory. * >*/ long telldir( dirp ) DIR *dirp; { return ((long) dirp->index); } /*< * Function: * Description: * Sets the position of the next readdir operation. * >*/ void seekdir( dirp, loc ) DIR *dirp; long loc; { dirp->index = loc; } /*< * Function: * Description: * Given a relative path, find the absolute path. * Returns a pointer to the absolute path. * See MSC Lib for format of getcwd. * >*/ char * getAbsPath(fileName) char *fileName; { static char absPath[128]; if (getcwd(cwd, sizeof(cwd)) == (char *)0) { perror("getcwd"); exit(1); } if (chdir(fileName)) { perror("chdir"); exit(1); } if (getcwd(absPath, sizeof(absPath)) == (char *)0) { perror("getcwd"); exit(1); } if (chdir(cwd)) { perror("chdir"); exit(1); } return (absPath); } SHAR_EOF fi # end of overwriting check if test -f 'build.bat' then echo shar: will not over-write existing file "'build.bat'" else cat << \SHAR_EOF > 'build.bat' msc -DMSDOS -I..\include dosdir.c; msc -DMSDOS -I..\include bsddir.c; msc -DMSDOS -I..\include getopt.c; msc -DMSDOS -I..\include traverse.c; del dossup.lib lib dossup dosdir.obj bsddir.obj getopt.obj traverse.obj; SHAR_EOF fi # end of overwriting check if test -f 'dir.h' then echo shar: will not over-write existing file "'dir.h'" else cat << \SHAR_EOF > 'dir.h' /*+ * Description: * Simulation header file for BSD style directory facilities * in DOS environment. * -*/ /* * Author: Mohsen Banan. * History: * */ /* * SCCS Revision: @(#)dir.h 1.2 Released: 8/3/87 */ #ifdef MSDOS /*{*/ #ifndef _DIR_H_ /*{*/ #define _DIR_H_ #define MAXNAMLEN 13 struct direct { int d_namlen; char d_name[MAXNAMLEN]; }; typedef enum DirState { DirActive, /* While consecutive readdirs */ DirVirgin, /* Very first time when opendir */ DirInactive /* When (DIR *) stream changes */ } DirState; typedef struct { char dirName[128]; /* Name of the directory, including drive */ char *dirNameEnd; /* End of String Location for dirName */ DirState state; /* See DirState */ long index; /* Position of a file name inside the directory */ char indexName[MAXNAMLEN]; /* File Name corresponding to indexName */ } DIR ; extern DIR *opendir(); extern struct direct *readdir(); extern long telldir(); extern void seekdir(); #define rewinddir(dirp) seekdir((dirp), (long)0) extern void closedir(); #endif /*}*/ #else #include "/usr/include/sys/dir.h" #endif /*}*/ SHAR_EOF fi # end of overwriting check if test -f 'dosdir.c' then echo shar: will not over-write existing file "'dosdir.c'" else cat << \SHAR_EOF > 'dosdir.c' /*+ * Description: * Basic DOS directory operations. * -*/ /* * Author: Mohsen Banan. * History: * */ #ifdef SCCS_VER /*{*/ static char sccs[] = "@(#)dosdir.c 1.1 Released: 8/3/87"; #endif /*}*/ #include <stdio.h> #include <dos.h> #include "dosos.h" #include <sys/dir.h> /*< * Function: * Description: * findFirst - find first file in chosen directory * * Arguments: * * Returns: * >*/ int findFirst(path, dirDta, mask) char *path; DirDta *dirDta; unsigned int mask; { union REGS inRegs; union REGS outRegs; struct SREGS segRegs; struct DOSERROR dosErr; inRegs.x.ax = 0x1A00; /* DOS interrupt 1A */ inRegs.x.dx = GET_OFF(dirDta); segRegs.ds = GET_SEG(dirDta); intdosx(&inRegs, &outRegs, &segRegs); /* Set Data Transfer Address */ inRegs.x.ax = 0x4E00; /* DOS interrupt 4E */ inRegs.x.cx = mask; inRegs.x.dx = GET_OFF(path); segRegs.ds = GET_SEG(path); intdosx(&inRegs, &outRegs, &segRegs); /* dirDta contains the result */ if ( outRegs.x.cflag ) { dosexterr(&dosErr); /* Code 2 is File Not Found */ if ( dosErr.exterror != 2 ) { printf("exterror=%d, class=%d, action=%d, locus=%d\n", dosErr.exterror, dosErr.class, dosErr.action, dosErr.locus); } return ( -1 ); } return ( 0 ); } /*< * Function: * Description: * findNext - find the next file in the same directory * * Arguments: * * Returns: * >*/ findNext( dirDta ) DirDta *dirDta; { union REGS inRegs; union REGS outRegs; struct SREGS segRegs; struct DOSERROR dosErr; inRegs.x.ax = 0x1A00; /* DOS interrupt 1A */ inRegs.x.dx = GET_OFF(dirDta); segRegs.ds = GET_SEG(dirDta); intdosx(&inRegs, &outRegs, &segRegs); /* Set Data Transfer Address */ inRegs.x.ax = 0x4F00; /* DOS interrupt 4E */ intdosx(&inRegs, &outRegs, &segRegs); /* dirDta contains the result */ if ( outRegs.x.cflag ) { dosexterr(&dosErr); /* Code 18 is No more files */ if ( dosErr.exterror != 18 ) { printf("exterror=%d, class=%d, action=%d, locus=%d\n", dosErr.exterror, dosErr.class, dosErr.action, dosErr.locus); } return ( -1 ); } return ( 0 ); } /*< * Function: * Description: * This is a substitute for findFirst. * I couldn't get it to work the way the dicumentation says it should * work. * * Returns: * >*/ int findPath(path, dirDta) char *path; DirDta *dirDta; { if ( findFirst("*.*", dirDta, 0x3F) ) { return ( -1 ); } while ( 1 ) { if ( findNext(dirDta) ) { return ( -1 ); } if ( ! strcmp(path, dirDta->fname) ) { return ( 0 ); } } } /*< * Function: * Description: * Seek to the loaction spercified by loc. * * Returns: * >*/ int findLoc(loc, dirDta) long loc; DirDta *dirDta; { long i; if ( findFirst("*.*", dirDta, 0x3F) ) { return ( -1 ); } for (i = 0; i < loc-1; ++i) { if ( findNext(dirDta) ) { return ( -1 ); } } return ( 0 ); } SHAR_EOF fi # end of overwriting check if test -f 'dosos.h' then echo shar: will not over-write existing file "'dosos.h'" else cat << \SHAR_EOF > 'dosos.h' /*+ * Description: * Header file for DOS supplemental facilities not provided * by MSC library. * -*/ /* * Author: Mohsen Banan. * History: * */ /* * SCCS Revision: @(#)dosos.h 1.1 Released: 8/3/87 */ #ifndef _DOSOS_H_ /*{*/ #define _DOSOS_H_ #define NAMESIZ 13 /* 12 character name + '\0' */ /* DOS Disk Transfer Address table */ typedef struct DirDta { char reserved[21]; /* used in "find next" operation */ char attr; /* file attribute byte */ unsigned short ftime; /* time of last modification */ unsigned short fdate; /* date of last modification */ unsigned long fsize; /* file size in bytes */ char fname[NAMESIZ]; /* filename and extension */ } DirDta; #ifdef M_I86SM #define GET_OFF(ptr) ((unsigned) ptr) static unsigned _showds() { struct SREGS r; segread(&r); return r.ds;} #define GET_SEG(ptr) _showds(); #endif #endif /*}*/ SHAR_EOF fi # end of overwriting check if test -f 'getopt.3' then echo shar: will not over-write existing file "'getopt.3'" else cat << \SHAR_EOF > 'getopt.3' .TH GETOPT 3 local .DA 25 March 1982 .SH NAME getopt \- get option letter from argv .SH SYNOPSIS .ft B int getopt(argc, argv, optstring) .br int argc; .br char **argv; .br char *optstring; .sp extern char *optarg; .br extern int optind; .ft .SH DESCRIPTION .I Getopt returns the next option letter in .I argv that matches a letter in .IR optstring . .I Optstring is a string of recognized option letters; if a letter is followed by a colon, the option is expected to have an argument that may or may not be separated from it by white space. .I Optarg is set to point to the start of the option argument on return from .IR getopt . .PP .I Getopt places in .I optind the .I argv index of the next argument to be processed. Because .I optind is external, it is normally initialized to zero automatically before the first call to .IR getopt . .PP When all options have been processed (i.e., up to the first non-option argument), .I getopt returns .BR EOF . The special option .B \-\- may be used to delimit the end of the options; .B EOF will be returned, and .B \-\- will be skipped. .SH SEE ALSO getopt(1) .SH DIAGNOSTICS .I Getopt prints an error message on .I stderr and returns a question mark .RB ( ? ) when it encounters an option letter not included in .IR optstring . .SH EXAMPLE The following code fragment shows how one might process the arguments for a command that can take the mutually exclusive options .B a and .BR b , and the options .B f and .BR o , both of which require arguments: .PP .RS .nf main(argc, argv) int argc; char **argv; { int c; extern int optind; extern char *optarg; \&. \&. \&. while ((c = getopt(argc, argv, "abf:o:")) != EOF) switch (c) { case 'a': if (bflg) errflg++; else aflg++; break; case 'b': if (aflg) errflg++; else bproc(); break; case 'f': ifile = optarg; break; case 'o': ofile = optarg; break; case '?': default: errflg++; break; } if (errflg) { fprintf(stderr, "Usage: ..."); exit(2); } for (; optind < argc; optind++) { \&. \&. \&. } \&. \&. \&. } .RE .PP A template similar to this can be found in .IR /usr/pub/template.c . .SH HISTORY Written by Henry Spencer, working from a Bell Labs manual page. Behavior believed identical to the Bell version. .SH BUGS It is not obvious how `\-' standing alone should be treated; this version treats it as a non-option argument, which is not always right. .PP Option arguments are allowed to begin with `\-'; this is reasonable but reduces the amount of error checking possible. .PP .I Getopt is quite flexible but the obvious price must be paid: there is much it could do that it doesn't, like checking mutually exclusive options, checking type of option arguments, etc. SHAR_EOF fi # end of overwriting check if test -f 'getopt.c' then echo shar: will not over-write existing file "'getopt.c'" else cat << \SHAR_EOF > 'getopt.c' /* * getopt - get option letter from argv */ #include <stdio.h> #include <string.h> char *optarg; /* Global argument pointer. */ int optind = 0; /* Global argv index. */ static char *scan = NULL; /* Private scan pointer. */ int getopt(argc, argv, optstring) int argc; char *argv[]; char *optstring; { register char c; register char *place; optarg = NULL; if (scan == NULL || *scan == '\0') { if (optind == 0) optind++; if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return(EOF); if (strcmp(argv[optind], "--")==0) { optind++; return(EOF); } scan = argv[optind]+1; optind++; } c = *scan++; place = strchr(optstring, c); if (place == NULL || c == ':') { fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); return('?'); } place++; if (*place == ':') { if (*scan != '\0') { optarg = scan; scan = NULL; } else if (optind < argc) { optarg = argv[optind]; optind++; } else { fprintf(stderr, "%s: -%c argument missing\n", argv[0], c); return('?'); } } return(c); } SHAR_EOF fi # end of overwriting check if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else cat << \SHAR_EOF > 'makefile' # # Description: # # # SCCS Revision: @(#)makefile 1.1 Released: 8/3/87 # # ::::::::::::: PKG= $(LIBS_PATH)/dosos.a PUB_H= LCL_H= LCL_C= dosdir.c bsddir.c C_SRC= $(PUB_H) $(LCL_H) $(LCL_C) # OBJS= dosdir.o bsddir.o # $(PKG): $(OBJS) ${LB} ${PKG} ${OBJS} ${RANLIB} ${PKG} # e_pub_h: @echo ${PUB_H} e_lcl_h: @echo ${LCL_H} e_lcl_c: @echo ${LCL_C} e_c_src: @echo ${C_SRC} e_objs: @echo ${OBJS} e_pkg: @echo ${PKG} # ctags: ${LCL_C} ctags $(LCL_C) SHAR_EOF fi # end of overwriting check if test -f 'pcmake' then echo shar: will not over-write existing file "'pcmake'" else cat << \SHAR_EOF > 'pcmake' # # Description: # # # SCCS Revision: @(#)pcmake 1.1 Released: 8/3/87 # # ::::::::::::: CC= msc #CFLAGS=-DMSDOS -Zd -Od CFLAGS=-DMSDOS -I..\\include AS= masm AFLAGS= /mX LIBRARIAN= lib LIBFLAGS= .c.obj: $(CC) $(CFLAGS) $*.c; .asm.obj: $(AS) $(AFLAGS) $*.asm; PKG= dossup PUB_H= LCL_H= C_1= dosdir.c bsddir.c getopt.c traverse.c LCL_C= $(C_1) C_SRC= $(PUB_H) $(LCL_H) $(LCL_C) # O_1= dosdir.obj bsddir.obj getopt.obj traverse.obj OBJS= $(O_1) # $(PKG).lib: $(OBJS) del $(PKG).lib $(LIBRARIAN) $(PKG) $(LIBFLAGS) $(O_1); LINKER= link LNKFLAGS= /STACK:16384 ARGV= \\msc\\lib\\ssetargv.obj PDT= traverse # e_make: @echo $(MAKEFILE) e_pub_h: @echo $(PUB_H) e_lcl_h: @echo $(LCL_H) e_lcl_c: @echo $(LCL_C) e_c_src: @echo $(C_SRC) e_objs: @echo $(OBJS) e_libs: @echo $(LIBS) e_pdt: @echo $(PDT) # tags: $(LCL_C) ctags $(LCL_C) SHAR_EOF fi # end of overwriting check if test -f 'traverse.3' then echo shar: will not over-write existing file "'traverse.3'" else cat << \SHAR_EOF > 'traverse.3' .TH TRAVERSE 3WI "December 16, 1984" .SH NAME traverse \- recursively traverse a directory .SH SYNOPSIS .nf traverse (path, func) char *path; int (*func) (); func (path, filetype, position) char *path; .fi .SH DESCRIPTION traverse applies its argument function func to its argument file pathname path. If path is a directory, then traverse applies func to all its entries. This traversal is in depth first order so that files are processed in the order that they are stored in the directory. .PP The argument func should take three parameters: a file name, a file type, and a position. The call looks like this for directories: .ce (*func) (path, 'd', position); and like this for other files: .ce (*func) (path, 'f', position); The position is 0 when path is first encountered and 1 when traverse is done. This is used to allow processing before and after a directory is processed. .SH EXAMPLE .nf list (name, type, pos) char *name; { if (type == 'd') printf ("%s %s\en", pos ? "Leaving" : "Entering", name); else /* type == 'f' */ printf (" %s\en", name); } .fi .SH AUTHOR Gary Perlman .SH BUGS There are no diagnostics when directories cannot be searched. SHAR_EOF fi # end of overwriting check if test -f 'traverse.c' then echo shar: will not over-write existing file "'traverse.c'" else cat << \SHAR_EOF > 'traverse.c' /*LINTLIBRARY*/ #include <stdio.h> #include <sys/types.h> #include <sys/dir.h> #ifdef MAXNAMLEN #define namedir(entry) (entry->d_name) #define MAXNAME 256 #else #define DIR FILE #define MAXNAME (DIRSIZ+2) #define opendir(path) fopen (path, "r") #define closedir(dirp) fclose (dirp) struct direct * readdir (dirp) DIR *dirp; { static struct direct entry; if (dirp == NULL) return (NULL); for (;;) { if (fread (&entry, sizeof (struct direct), 1, dirp) == 0) return (NULL); if (entry.d_ino) return (&entry); } } char *strncpy (); char * namedir (entry) struct direct *entry; { static char name[MAXNAME]; return (strncpy (name, entry->d_name, DIRSIZ)); } #endif #include <sys/stat.h> #define isdir(path) (stat(path, &buf) ? 0 : (buf.st_mode&S_IFMT)==S_IFDIR) traverse (path, func) char *path; int (*func) (); { DIR *dirp; struct direct *entry; struct stat buf; int filetype = isdir (path) ? 'd' : 'f'; (*func) (path, filetype, 0); if (filetype == 'd') { if (chdir (path) == 0) { if (dirp = opendir (".")) { while (entry = readdir (dirp)) { char name[MAXNAME]; (void) strcpy (name, namedir (entry)); if (strcmp(name, ".") && strcmp(name, "..")) traverse (name, func); } (void) closedir(dirp); } (void) chdir (".."); } } (*func) (path, filetype, 1); } #ifdef STANDALONE static Indent = 0; tryverse (file, type, pos) char *file; { int in; if (pos == 0) { for (in = 0; in < Indent; in++) putchar ('\t'); if (type == 'd') { printf ("%s/\n", file); Indent++; } else puts (file); } else if (type == 'd') Indent--; } main (argc, argv) char **argv; { int tryverse (); char cwd[80]; char *root = argc > 1 ? argv[1] : "."; getcwd(cwd, sizeof(cwd)); traverse (root, tryverse); chdir(cwd); printf("cwd=%s\n", cwd); } #endif SHAR_EOF fi # end of overwriting check cd .. if test ! -d 'lsr' then mkdir 'lsr' fi cd 'lsr' if test -f 'build.bat' then echo shar: will not over-write existing file "'build.bat'" else cat << \SHAR_EOF > 'build.bat' msc -DMSDOS -I. -I..\include .\lsr.c; link /STACK:8000 lsr.obj \msc\lib\ssetargv.obj , lsr,, dossup ; SHAR_EOF fi # end of overwriting check if test -f 'env' then echo shar: will not over-write existing file "'env'" else cat << \SHAR_EOF > 'env' set INCFLAGS = "-I. -I../include" SHAR_EOF fi # end of overwriting check if test -f 'lsr.c' then echo shar: will not over-write existing file "'lsr.c'" else cat << \SHAR_EOF > 'lsr.c' /*+ * Description: * Recursevely list all files within a set of directories. * This utility can be used as a front end to other tools * that do don't provide for traversing of directories. * "lsr . | makekit " is an example of a possible usage. * USAGE: * lsr [-f] fileName * -f: Do not list directory names. Files only. -*/ /* * Author: Mohsen Banan. * History: * */ #ifdef SCCS_VER /*{*/ static char sccs[] = "@(#)lsr.c 1.1 Released: 8/3/87"; #endif /*}*/ /* #includes */ #include <stdio.h> #include "estd.h" #include <ctype.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #ifdef MSDOS #include <direct.h> #endif STATIC Void usage(); STATIC Void tryverse(); STATIC Char * progName; static char rootName[256] = { 0 }; static Bool filesOnlyFlag = FALSE; #ifdef MSDOS static char cwd[128]; #endif /*< * Function: * Description: * * Arguments: * * Returns: * * >*/ Int main (argc, argv) Int argc; Char * argv[]; { Bool errFlag = FALSE; Bool usageFlag = FALSE; extern char * optarg; extern int optind; Int c; progName = argv[0]; while ((c = getopt(argc, argv, "fFuU")) != EOF) { switch (c) { case 'f': case 'F': filesOnlyFlag = TRUE; break; case 'u': case 'U': usageFlag = TRUE; break; case '?': default: errFlag = TRUE; break; } } if ( usageFlag ) { usage(); exit(0); } if ( errFlag ) { usage(); exit(1); } #ifdef MSDOS if (getcwd(cwd, sizeof(cwd)) == (char *) 0) { perror("getcwd"); exit(1); } #endif do { char *path; struct stat buf; #define isdir(path) stat(path, &buf) ? 0 : (buf.st_mode&S_IFMT)==S_IFDIR) if ( optind >= argc ) { path = "."; } else { path = argv[optind]; } if ( isdir(path) { rootName[0] = '\0'; traverse(path, tryverse); } else { printf("%s\n", path); } } while ( ++optind < argc ); #ifdef MSDOS if (chdir(cwd)) { perror("chdir"); exit(1); } #endif exit (0); } STATIC Void usage () { fprintf(stderr, "Usage: %s [-f] [filename] ...\n", progName); } /*< * Function: * Description: * * Arguments: * * Returns: * >*/ static Void tryverse (file, type, pos) char *file; { int in; if (pos == 0) { if (type == 'd') { if ( * rootName ) { sprintf(rootName,"%s/%s", rootName, file); } else { sprintf(rootName,"%s", file); } if ( filesOnlyFlag == FALSE ) { printf ("%s\n", rootName); } } else { printf ("%s/%s\n", rootName, file); } } else { if (type == 'd') { extern char *strrchr(); char *rootEnd; rootEnd = strrchr(rootName, '/'); if ( rootEnd ) { *rootEnd = '\0'; } } } } SHAR_EOF fi # end of overwriting check if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else cat << \SHAR_EOF > 'makefile' # # Description: # # # SCCS Revision: @(#)makefile 1.1 Released: 8/3/87 # # ::::::::::::: PDT = lsr PUB_H = LCL_H = LCL_C = lsr.c C_SRC = ${PUB_H} ${LCL_H} ${LCL_C} OBJS = lsr.o # PUBSUP = $(LIBS_PATH)/pubsup.a LIBS = $(PUBSUP) # $(PDT): $(OBJS) ${LIBS} ${LK} -o ${PDT} ${OBJS} ${LIBS} # e_pub_h: @echo ${PUB_H} e_lcl_h: @echo ${LCL_H} e_lcl_c: @echo ${LCL_C} e_c_src: @echo ${C_SRC} e_objs: @echo ${OBJS} e_libs: @echo ${LIBS} e_pdt: @echo ${PDT} # tags: ${LCL_C} ctags $(LCL_C) SHAR_EOF fi # end of overwriting check if test -f 'pcmake' then echo shar: will not over-write existing file "'pcmake'" else cat << \SHAR_EOF > 'pcmake' # # Description: # # # SCCS Revision: @(#)pcmake 1.1 Released: 8/3/87 # # ::::::::::::: CC= msc #CFLAGS=-DMSDOS -Zi -Od GLOB=.. CFLAGS=-DMSDOS -I. -I$(GLOB)\\include LINKER= link LINKFLAGS= /STACK:8000 #LINKFLAGS= LIBRARIAN= lib LIBFLAGS= HERE= . .c.obj: $(CC) $(CFLAGS) $(HERE)\\$*.c; PDT= lsr PKG= PUB_H= LCL_H= LCL_C= lsr.c C_SRC= $(PUB_H) $(LCL_H) $(LCL_C) O_1= OBJS= lsr.obj # ARGV= \\msc\\lib\\ssetargv.obj # DOSSUP= dossup LIBS= $(DOSSUP) # $(PDT).exe: $(OBJS) $(LINKER) $(LINKFLAGS) $(OBJS) $(ARGV) ,$(PDT),,$(LIBS) ; $(PKG).lib: $(O_1) del $(PKG).lib $(LIBRARIAN) $(PKG) $(LIBFLAGS) $(O_1); # e_make: @echo $(MAKEFILE) e_pub_h: @echo $(PUB_H) e_lcl_h: @echo $(LCL_H) e_lcl_c: @echo $(LCL_C) e_c_src: @echo $(C_SRC) e_objs: @echo $(OBJS) e_libs: @echo $(LIBS) e_pdt: @echo $(PDT) # ctags: $(LCL_C) $(CTAGS) $(LCL_C) pr: $(C_SRC) mbcpr -r -n $(C_SRC) SHAR_EOF fi # end of overwriting check cd .. if test ! -d 'shar' then mkdir 'shar' fi cd 'shar' if test -f 'build.bat' then echo shar: will not over-write existing file "'build.bat'" else cat << \SHAR_EOF > 'build.bat' msc -DMSDOS -I\d\pub\include shar.c; link /STACK:16384 shar.obj \msc\lib\ssetargv.obj , shar,, dossup ; SHAR_EOF fi # end of overwriting check if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else cat << \SHAR_EOF > 'makefile' # # Description: # # # SCCS Revision: %W% Released: %G% # # ::::::::::::: PDT = shar PUB_H = LCL_H = LCL_C = shar.c C_SRC = ${PUB_H} ${LCL_H} ${LCL_C} OBJS = shar.o # PUBSUP = $(LIBS_PATH)/pubsup.a LIBS = $(PUBSUP) # $(PDT): $(OBJS) ${LIBS} ${LK} -o ${PDT} ${OBJS} ${LIBS} # e_pub_h: @echo ${PUB_H} e_lcl_h: @echo ${LCL_H} e_lcl_c: @echo ${LCL_C} e_c_src: @echo ${C_SRC} e_objs: @echo ${OBJS} e_libs: @echo ${LIBS} e_pdt: @echo ${PDT} # tags: ${LCL_C} ctags $(LCL_C) SHAR_EOF fi # end of overwriting check if test -f 'pcmake' then echo shar: will not over-write existing file "'pcmake'" else cat << \SHAR_EOF > 'pcmake' # :::::::::::::::::::::::::::::::::::::::::::::::::: # # File: Makefile # Description: Makefile for creating # # # Audit Trail: $Log:$ # # $Header: $ # # :::::::::::::::::::::::::::::::::::::::::::::::::: CC= msc #CFLAGS=-DMSDOS -Zd -Od CFLAGS=-DMSDOS -I\\d\\pub\\include LINKER= link LNKFLAGS= /STACK:16384 #LNKFLAGS= .c.obj: $(CC) $(CFLAGS) $*.c; MAKEFILE= makefile PDT= shar PUB_H= LCL_H= LCL_C= shar.c C_SRC= $(PUB_H) $(LCL_H) $(LCL_C) OBJS= shar.obj ARGV= \\msc\\lib\\ssetargv.obj # DOSSUP= dossup LIBS= $(DOSSUP) # $(PDT).exe: $(OBJS) $(LINKER) $(LNKFLAGS) $(OBJS) $(ARGV) ,$(PDT),,$(LIBS) ; # e_make: @echo $(MAKEFILE) e_pub_h: @echo $(PUB_H) e_lcl_h: @echo $(LCL_H) e_lcl_c: @echo $(LCL_C) e_c_src: @echo $(C_SRC) e_objs: @echo $(OBJS) e_libs: @echo $(LIBS) e_pdt: @echo $(PDT) # tags: $(LCL_C) ctags $(LCL_C) SHAR_EOF fi # end of overwriting check if test -f 'shar.1' then echo shar: will not over-write existing file "'shar.1'" else cat << \SHAR_EOF > 'shar.1' .TH SHAR 1net "June 3, 1985" "UNIX User's Manual" "Wang Institute" .SH NAME shar \- create file storage archive for extraction by /bin/sh .SH SYNOPSIS .B shar [-abcsv] [-d delim] [-p prefix] files .SH DESCRIPTION .I shar prints its input files with special command lines around them to be used by the shell, .I /bin/sh , to extract them later. The output can be filtered through the shell to recreate copies of the original files. .PP .I shar allows directories to be named, and .I shar prints the necessary commands .ul (mkdir & cd) to create new directories and fill them. .I shar will emit commands to make executable plain files executable. .I shar will not allow existing files to be over-written; such files must be removed by the file extractor. .SH OPTIONS .de OP .TP .B -\\$1 .. .OP a All the options. The options: .B "-v -c -b -p <tab>X" are implied. .OP s Silent running. All checking and extra output is inhibited. .OP v Print verbose feedback messages about what .I shar is doing to be printed during extraction. Sizes of plain files are echoed to allow a simple validity check. .OP c Check file size on extraction by counting characters. An error message is reported to the person doing the extraction if the sizes don't match. One reason why the sizes may not match is that .I shar will append a newline to complete incomplete last lines; .I shar prints a message that mentions added newlines. Another reason why the sizes may not match is that some network mail programs remove non-whitespace control characters. .I shar prints a message that mentions control characters to the extractor. .OP b Extract files into basenames so that files with absolute path names are put into the current directory. This option has strange effects when directories are archived. .OP d delim Use this as the ``end of file'' delimiter instead of the default. The only reason to change it is if you suspect an file contains the default delimiter: .B SHAR_EOF. .OP p prefix Use this as the prefix to each line of the archived files. This is to make sure that special characters at the start of lines are not eaten up by programs like mailers. If this option is used, the files will be extracted with the stream editor .B sed rather than .B cat so it is more efficient and portable to avoid setting the prefix, though perhaps less safe if you don't know what is in the files. .SH "SEE ALSO tar(1), cpio(1), tp(1), sh(1) .SH AUTHOR Gary Perlman (based on a shell version by James Gosling, with additions motivated by Derek Zahn, Michael Thompson, H. Morrow Long, Fred Avolio, Gran Uddeborg, & Chuck Wegrzyn) .SH LIMITATIONS .I shar does not know anything about links between files or binary files. SHAR_EOF fi # end of overwriting check if test -f 'shar.c' then echo shar: will not over-write existing file "'shar.c'" else cat << \SHAR_EOF > 'shar.c' #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> #ifdef MSDOS #include <direct.h> #endif /*{ Shar puts readable text files together in a package from which they are easy to extract. The original version was a shell script posted to the net, shown below: #Date: Mon Oct 18 11:08:34 1982 #From: decvax!microsof!uw-beave!jim (James Gosling at CMU) AR=$1 shift for i do echo a - $i echo "echo x - $i" >>$AR echo "cat >$i <<'!Funky!Stuff!'" >>$AR cat $i >>$AR echo "!Funky!Stuff!" >>$AR done I rewrote this version in C to provide better diagnostics and to run faster. The major difference is that my version does not affect any files because it prints to the standard output. Mine also has several options. Gary Perlman/Wang Institute/Tyngsboro, MA/01879/(617) 649-9731 Many enhancements motivated by Michael Thompson. Directory archiving motivated by Derek Zahn @ wisconsin His version had some problems, so I wrote a general routine for traversing a directory hierarchy. It allows marching through a directory on old and new UNIX systems. }*/ /* COMMANDS */ #define EXTRACT "#! /bin/sh" /* magic exec string at shar file start */ #define PATH "/bin:$PATH" /* search path for programs */ #define CAT "cat"; /* /bin/cat */ #define SED "sed 's/^%s//'" /* /bin/sed removes Prefix from lines */ #define MKDIR "mkdir" /* make a new dirctory */ #define CHMOD "chmod +x" /* change file protection (for executables) */ #define CHDIR "cd" /* change current directory */ #define TEST "test" /* /bin/test files */ #define WC_C "wc -c <" /* counts chars in file */ #define ECHO "echo shar" /* echo a message to extractor */ main (argc, argv) char **argv; { char cwd[80]; int shar (); int optind; if ((optind = initial (argc, argv)) < 0) exit (1); if (header (argc, argv, optind)) exit (2); #ifdef MSDOS if ( getcwd(cwd, sizeof(cwd)) == (char *)0 ) { perror("getcwd error"); exit(3); } #endif while (optind < argc) traverse (argv[optind++], shar); #ifdef MSDOS if (chdir(cwd)) { perror("chdir error"); exit(4); } #endif footer (); exit (0); } /* OPTIONS */ typedef int lgl; #define true ((lgl) 1) #define false ((lgl) 0) int Lastchar; /* the last character printed */ int Ctrlcount; /* how many bad control characters are in file */ #define USAGE "[-abcsv] [-p prefix] [-d delim] files > archive" #define OPTSTRING "abcsvp:d:" lgl Verbose = false; /* provide append/extract feedback */ lgl Basename = false; /* extract into basenames */ lgl Count = false; /* count characters to check transfer */ lgl Silent = false; /* turn off all verbosity */ char *Delim = "SHAR_EOF"; /* put after each file */ char Filter[100] = CAT; /* used to extract archived files */ char *Prefix = NULL; /* line prefix to avoid funny chars */ int /* returns the index of the first operand file */ initial (argc, argv) char **argv; { int errflg = 0; extern int optind; extern char *optarg; int C; while ((C = getopt (argc, argv, OPTSTRING)) != EOF) switch (C) { case 'v': Verbose = true; break; case 'c': Count = true; break; case 'b': Basename = true; break; case 'd': Delim = optarg; break; case 's': /* silent running */ Silent = true; Verbose = false; Count = false; Prefix = NULL; break; case 'a': /* all the options */ Verbose = true; Count = true; Basename = true; /* fall through to set prefix */ optarg = " X"; case 'p': (void) sprintf (Filter, SED, Prefix = optarg); break; default: errflg++; } if (errflg || optind == argc) { if (optind == argc) fprintf (stderr, "shar: No input files\n"); fprintf (stderr, "USAGE: shar %s\n", USAGE); return (-1); } return (optind); } header (argc, argv, optind) char **argv; { int i; lgl problems = false; long clock; char *ctime (); char *getenv (); char *NAME = getenv ("NAME"); char *ORG = getenv ("ORGANIZATION"); for (i = optind; i < argc; i++) if (access (argv[i], 4)) /* check read permission */ { fprintf (stderr, "shar: Can't read '%s'\n", argv[i]); problems++; } if (problems) return (problems); /* I have given up on putting a cut line in the archive. Too many people complained about having to remove it. puts ("-----cut here-----cut here-----cut here-----cut here-----"); */ puts (EXTRACT); puts ("# This is a shell archive, meaning:"); printf ("# 1. Remove everything above the %s line.\n", EXTRACT); puts ("# 2. Save the resulting text in a file."); puts ("# 3. Execute the file with /bin/sh (not csh) to create the files:"); for (i = optind; i < argc; i++) printf ("#\t%s\n", argv[i]); (void) time (&clock); printf ("# This archive created: %s", ctime (&clock)); if (NAME) printf ("# By:\t%s (%s)\n", NAME, ORG ? ORG : ""); printf ("export PATH; PATH=%s\n", PATH); return (0); } footer () { puts ("#\tEnd of shell archive"); puts ("exit 0"); } archive (input, output) char *input, *output; { char buf[BUFSIZ]; FILE *ioptr; if (ioptr = fopen (input, "r")) { if (Count == true) { Ctrlcount = 0; /* no bad control characters so far */ Lastchar = '\n'; /* simulate line start */ } printf ("%s << \\%s > '%s'\n", Filter, Delim, output); if (Prefix) { while (fgets (buf, BUFSIZ, ioptr)) { if (Prefix) outline (Prefix); outline (buf); } } else copyout (ioptr); /* thanks to H. Morrow Long (ittvax!long) for the next fix */ if (Lastchar != '\n') /* incomplete last line */ putchar ('\n'); /* Delim MUST begin new line! */ puts (Delim); if (Count == true && Lastchar != '\n') printf ("%s: a missing newline was added to \"'%s'\"\n", ECHO, input); if (Count == true && Ctrlcount) printf ("%s: %d control character%s may be missing from \"'%s'\"\n", ECHO, Ctrlcount, Ctrlcount > 1 ? "s" : "", input); (void) fclose (ioptr); return (0); } else { fprintf (stderr, "shar: Can't open '%s'\n", input); return (1); } } /* Copyout copies its ioptr almost as fast as possible except that it has to keep track of the last character printed. If the last character is not a newline, then shar has to add one so that the end of file delimiter is recognized by the shell. This checking costs about a 10% difference in user time. Otherwise, it is about as fast as cat. It also might count control characters. */ #define badctrl(c) (iscntrl (c) && !isspace (c)) copyout (ioptr) register FILE *ioptr; { register int C; register int L; register count; count = Count; while ((C = getc (ioptr)) != EOF) { if (count == true && badctrl (C)) Ctrlcount++; L = putchar (C); } Lastchar = L; } outline (s) register char *s; { if (*s) { while (*s) { if (Count == true && badctrl (*s)) Ctrlcount++; putchar (*s++); } Lastchar = *(s-1); } } #define FSIZE statbuf.st_size shar (file, type, pos) char *file; /* file or directory to be processed */ int type; /* either 'f' for file or 'd' for directory */ int pos; /* 0 going in to a file or dir, 1 going out */ { struct stat statbuf; char *basefile = file; if (!strcmp (file, ".")) return; if (stat (file, &statbuf)) FSIZE = 0; if (Basename == true) { while (*basefile) basefile++; /* go to end of name */ while (basefile > file && *(basefile-1) != '/') basefile--; } if (pos == 0) /* before the file starts */ { if (type == 'd') { printf ("if %s ! -d '%s'\n", TEST, basefile); printf ("then\n"); if (Verbose == true) printf (" %s: creating directory \"'%s'\"\n", ECHO, basefile); printf (" %s '%s'\n", MKDIR, basefile); printf ("fi\n"); if (Verbose == true) printf ("%s: entering directory \"'%s'\"\n", ECHO, basefile); printf ("%s '%s'\n", CHDIR, basefile); } else /* type == 'f' */ { if (Verbose == true) printf ("%s: extracting \"'%s'\" '(%d character%s)'\n", ECHO, basefile, FSIZE, FSIZE > 1 ? "s" : ""); if (Silent == false) /* this solution by G|ran Uddeborg */ { printf ("if %s -f '%s'\n", TEST, basefile); puts ("then"); printf (" %s: will not over-write existing file \"'%s'\"\n", ECHO, basefile); puts ("else"); } if (archive (file, basefile)) exit (-1); } } else /* pos == 1, after the file is archived */ { if (type == 'd') { if (Verbose == true) printf ("%s: done with directory \"'%s'\"\n", ECHO, basefile); printf ("%s ..\n", CHDIR); } else /* type == 'f' (plain file) */ { if (Count == true) { printf ("if %s %d -ne \"`%s '%s'`\"\n", TEST, FSIZE, WC_C, basefile); puts ("then"); printf (" %s: error transmitting \"'%s'\" ", ECHO, basefile); printf ("'(should have been %d character%s)'\n", FSIZE, FSIZE > 1 ? "s" : ""); puts ("fi"); } #ifndef MSDOS if (access (file, 1) == 0) /* executable -> chmod +x */ printf ("%s '%s'\n", CHMOD, basefile); #endif if (Silent == false) { puts ("fi # end of overwriting check"); } } } } SHAR_EOF fi # end of overwriting check if test -f 'env' then echo shar: will not over-write existing file "'env'" else cat << \SHAR_EOF > 'env' set INCFLAGS = "-I. -I../include" SHAR_EOF fi # end of overwriting check cd .. # End of shell archive exit 0