/* * UPD: update * * HISTORY: * * 4/13/86 danl Fix /d bug. Print warning on eq time ne length * 4/11/86 danl Remove test for length just before copyfile * 4/09/86 danl Converted to ztools\lib * 5/07/86 danl Add msg if no such source found * 5/29/86 danl Add /s flag * 6/02/86 danl Add /g flag * 6/04/86 danl Allow %n with /g flag * 6/10/86 danl Allow blank lines in /g file, # are not echo'd * 6/12/86 danl Output \n and ends of lines * 6/26/86 danl Convert from fatal to usage * 7/01/86 danl Add /a flag * 12/04/86 danl Add /p flag * 12/24/86 danl Use malloc for pPat * 2/24/87 brianwi Use findclose() * 2/25/87 brianwi Add 'echo' and 'rem' to /g files * 07-Apr-87 danl Add fAnyUpd * 13-Apr-87 brianwi Issue error message if source dir invalid * 07-May-87 danl Add /e switch * 22-May-87 brianwi Fix descent from root directory bug * 20-Aug-87 brianwi Fix Null Pointer with /o ( free(pPat) in walk() ) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Forward Function Declarations... int _CRTAPI1 main( int, char ** ); int savespec( char * ); int copyfile( char *, struct findType *, char * ); void walk( char *, struct findType *, void *); void RecWalk( char *, struct findType *, void * ); void saveext( char * ); void usage( char *, ... ); void getfile( int, char ** ); char *rgstrUsage[] = { "Usage: UPD [/nxdfvosape] {src directories}+ dest directory [{wildcard specs}*]", " UPD /g file", " Options:", " -n No saving of replaced files to deleted directory", " -x eXclude files, see tools.ini", " -d Descend into subdirectories", " -f Files differ, then update", " -v Verbose", " -o Only files already existing in dest are updated", " -s Subdirectory DEBUG has priority", " -a Archive bit on source should NOT be reset", " -p Print actions, but do nothing", " -e Exit codes 1-error or no src else 0", " Default is 1-update done 0-no updates done", " -g Get params from file", 0}; #define BUFLEN 256 #define MAXSPEC 32 #define MAXFIL 256 #define MAXARGV 20 char *exclude[MAXFIL], dir[BUFLEN]; unsigned _stack = 4096; flagType fInGetfile = FALSE; flagType _fExpand = FALSE; flagType fDescend = FALSE; flagType fAll = FALSE; flagType fExclude = FALSE; flagType fDel = TRUE; flagType fVerbose = FALSE; flagType fOnly = FALSE; flagType fSubDebug = FALSE; /* TRUE => priority to subdir DEBUG */ flagType fArchiveReset = TRUE; flagType fPrintOnly = FALSE; flagType fErrorExit = FALSE; /* TRUE => exit (1) errors or no src else 0 */ flagType fNoSrc = FALSE; /* TRUE => "No src msg emitted" */ int numexcl = 0; int cCopied = 0; int fAnyUpd = 0; int nWildSpecs = 0; char *wildSpecs[MAXSPEC]; struct findType buf; char source[BUFLEN], dest[BUFLEN], srcDebug[BUFLEN]; /* for use by getfile */ char *argv[MAXARGV]; char bufIn[BUFLEN]; char strLine[BUFLEN]; char ekoLine[BUFLEN]; /* undestroyed copy of line for echo */ savespec (p) char *p; { char namebuf[ 16 ]; int i; buf.fbuf.dwFileAttributes = 0; namebuf[ 0 ] = 0; if (strchr(p, '\\') || strchr(p, ':' ) ) return FALSE; ffirst( p, FILE_ATTRIBUTE_DIRECTORY, &buf ); findclose( &buf ); if ( /* !HASATTR( buf.attr, FILE_ATTRIBUTE_DIRECTORY ) && */ filename( p, namebuf ) ) { fileext( p, namebuf); upper( namebuf ); for (i=0; i %s", src, dst ); fAnyUpd = 1; if ( !fPrintOnly ) { if (fDel) fNewfile = (flagType)((fdelete(dst)) ? TRUE : FALSE ); if (!(result = fcopy( src, dst ))) { if (fArchiveReset) SetFileAttributes( src, srctype->fbuf.dwFileAttributes & ~FILE_ATTRIBUTE_ARCHIVE ); if (fVerbose || fNewfile) printf( " [OK]" ); } else printf( " %s - %s", result, error() ); } else printf ( " [no upd]" ); printf( "\n" ); fflush( stdout ); } void walk ( char *p, struct findType *b, void *dummy ) { int fNotFound; char *pPat; char *pT = p; struct findType *bT = b; struct findType bufT; if( strcmp( bT->fbuf.cFileName, "." ) && strcmp( bT->fbuf.cFileName, ".." ) ) { if (HASATTR (bT->fbuf.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) { /* do nothing if you find a dir */ } else if( !HASATTR( bT->fbuf.dwFileAttributes, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM ) ) { // // Note: windows does not support FILE_ATTRIBUTE_VOLUME_LABEL, so // it was removed from above // pPat = malloc ( BUFLEN ); strcpy( pPat, dest ); if (*(strend( pPat ) - 1) != '\\') { strcat( pPat, "\\" ); } fileext( pT, strend ( pPat ) ); /* ffirst == 0 => file found */ if (fOnly && ffirst( pPat, -1, &buf ) ) { free ( pPat ); return; } if (fOnly) { findclose( &buf ); } /* so far we know src\file and dest\file exist */ if (fSubDebug) { /* now check to see if src\DEBUG\file exists */ drive(pT, srcDebug); path(pT, srcDebug + strlen(srcDebug)); strcat(srcDebug + strlen(srcDebug), "debug\\"); fileext(pT, srcDebug + strlen(srcDebug)); if( !ffirst( srcDebug, -1, &bufT ) ) { findclose( &bufT ); /* it exists so use it for the compares below */ pT = srcDebug; bT = &bufT; } } cCopied++; if( ( fNotFound = ffirst( pPat, -1, &buf ) ) || ( CompareFileTime( &buf.fbuf.ftLastWriteTime, &bT->fbuf.ftLastWriteTime ) < 0 ) || ( fAll && CompareFileTime( &buf.fbuf.ftLastWriteTime, &bT->fbuf.ftLastWriteTime ) > 0 ) ) { copyfile( pT, bT, pPat ); } else if( !fNotFound && CompareFileTime( &buf.fbuf.ftLastWriteTime, &bT->fbuf.ftLastWriteTime ) == 0 && buf.fbuf.nFileSizeLow != bT->fbuf.nFileSizeLow ) { printf("\n\007UPD: warning - %s not copied\n", pT); printf("\007UPD: warning - same time, different length in src & dest\n", pT); } findclose( &buf ); free ( pPat ); } } dummy; } /* a first walking routine, just copies the files on given directory */ /* doesn't deal with nested subdirectories. Ie split the process up into */ /* two parts, first deal with files on current directory, then deal with */ /* subdirectories as necessary. */ /* only called when fDescend is true */ void RecWalk ( char *p, struct findType *b, void *dummy ) { char *pPat; char *pDestEnd; int i; if (strcmp (b->fbuf.cFileName, ".") && strcmp (b->fbuf.cFileName, "..")) if (HASATTR (b->fbuf.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) && !HASATTR (b->fbuf.dwFileAttributes, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) { /* ignore Hidden and System directories */ pPat = malloc ( BUFLEN ); if ( (pDestEnd = strend(dest))[-1] != '\\' ) strcat(pDestEnd, "\\"); fileext(p, strend(pDestEnd)); sprintf( pPat, "%s\\*.*", p); forfile( pPat, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM, RecWalk, NULL ); for (i=0; i=2; i--) if (!savespec( v[ i ] )) break; else c--; /* Still must be at least one source dir and the dest dir. */ if (c < 2) usage( 0 ); /* Make sure destination is a valid directory */ rootpath( v[ c-1 ], dest ); if (ffirst( dest, FILE_ATTRIBUTE_DIRECTORY, &buf ) == -1) usage( "Destination directory does not exist - ", v[ c-1 ], 0 ); else { findclose( &buf ); c--; } if (!nWildSpecs) savespec( "*.*" ); if (fVerbose) { printf( "Copying all files matching:" ); for (i=0; i