home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
trojanpr
/
chksum.arc
/
CHKSUM.C
next >
Wrap
Text File
|
1988-04-06
|
7KB
|
201 lines
/****************************************************************************/
/*** CHKSUM.C -- computes and verifies a 16 bit CRC for any file. ***/
/*** Can be used to see if two files with the same or ***/
/*** different names are identical. Can also be used to ***/
/*** make sure that no surreptitious changes have been ***/
/*** made to a file ... say by a virus. ***/
/*** ***/
/*** Written by Bob Taylor, 8602 Woodlake Dr., Richmond, VA 23229. ***/
/*** using Turbo C, V1.5 March 1,1988 ***/
/****************************************************************************/
/*** Revision History: ***/
/*** 4/6/88 -- Added ERRORLEVEL control: 1 for mis-match, 0 for ***/
/*** OK. Allows automated use. Also, added silent ***/
/*** switch so that ERRORLEVEL is the only way a mis- ***/
/*** match is reported. (This may be DANGEROUS!) ***/
/*** ***/
/*** 3/13/88 -- Cleaned up comments and added "Hit any key ..." ***/
/*** when incorrect chksum detected. Also, changed ***/
/*** emergency output to go directly to the console via ***/
/*** cprintf and cputs, rather than to stderr. ***/
/****************************************************************************/
#include <dos.h>
#include <dir.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <stdarg.h>
#include <fcntl.h>
#include "stoi.c" /* String TO Integer -- interpret argv[]. */
#include "crc16.c" /* Table Lookup for 16 bit CRC, and updcrc macro. */
#define odd(x) (1 == ((x) & 1))
#define E(x) fprintf(stderr,x)
#define FALSE 0
#define TRUE !FALSE
#define MISMATCH 1
unsigned int bufsiz; /* Size of buffer to allocate for files. */
char * bufptr; /* Ptr to buffer where files are read in. */
/****************************************************************************/
/*** usage() - display the syntax options for chksum ***/
/****************************************************************************/
void usage()
{
E("syntax is: chksum filspec -or-\n");
E(" chksum [-s] fil1 sum1 fil2 sum2 ... filn sumn\n");
E("In the first form, filspec may be a wildcard. The\n");
E("checksum is calculated for all matching files.\n");
E("In the second, a checksum is calculated for each\n");
E("file, and compared to the number given after the file\n");
E("name on the command line. Any mismatch is noted.\n");
E("\n-s indicates that chksum will be silent, i.e. only\n");
E("report mismatches via DOS's ERRORLEVEL. It will be\n");
E("set to 1 if a mismatch occurs, 0 otherwise.\n\n");
exit(1);
}
/****************************************************************************/
/*** dochksum(file name) -- calculate the CRC for a specified file. No ***/
/*** wildcards are allowed ... the file name must be fully specified. ***/
/****************************************************************************/
int dochksum(char *path)
{
unsigned int bytes;
int crc,fi;
register unsigned int i;
if( -1 == (fi=open(path,O_RDONLY | O_BINARY)) ) {
fprintf(stderr,"chksum: Can't open %s\n ",path);
return(0);
}
crc=0;
while( 0 < (bytes=read(fi,bufptr,bufsiz)) )
{
for (i=0; bytes > i; i++)
crc = updcrc(bufptr[i],crc); /* macro to do CRC table lookup */
}
close(fi);
return(crc);
}
/****************************************************************************/
/*** showcksum(file spec) -- Given a file spec, which may be a wild-card,***/
/*** calculate a CRC for each matching file. Include Hidden and System***/
/*** files, since they are most prone to viral infection. ***/
/****************************************************************************/
void showcksum(char *fn)
{
struct ffblk fil;
char path[MAXPATH],dr[MAXDRIVE],dir[MAXDIR],fin[MAXFILE],ex[MAXEXT];
char *pathend;
int crc;
if( 0!=findfirst(fn,&fil,FA_HIDDEN | FA_SYSTEM) ) {
fprintf(stderr,"chksum: can't find file %s\n",fn);
exit(3);
}
fnsplit(fn,dr,dir,fin,ex);
strcpy(path,dr);
strcat(path,dir);
pathend = path + strlen(path);
do {
strcpy(pathend,fil.ff_name);
crc=dochksum(path);
printf("\n%s%s%-12s : %#06X (%u)",dr,dir,fil.ff_name,crc,crc);
}
while( 0==findnext(&fil) );
printf("\n");
}
/****************************************************************************/
/*** verifycksum(file name,CRC) -- compute a CRC for the specified file, ***/
/*** and compare it with the given CRC value. If they aren't the same,***/
/*** Yell to the console (NOT stderr) using "cprintf and cputs". ***/
/****************************************************************************/
int verifycksum(char *fil,int num,int silent)
{
int crc;
int badfile = FALSE; /* flag that indicates a mis-match found. */
crc=dochksum(fil);
if( crc != num ) {
if( silent == 0) {
cprintf(" * * * WARNING!! ... Checksum NOT verified. *\a *\a *\a\n");
cprintf(" File: %s Submitted CRC: %#04X Calculated CRC: %#04X\n\n",
fil,num,crc);
cputs("Hit any key to continue ...");
getch();
cputs("\n\n");
}
badfile = MISMATCH;
}
return(badfile);
}
/****************************************************************************/
/*** allocbuf() -- allocate a large input buffer for reading in the files,***/
/*** and assign its size and location to global variables, for use in ***/
/*** dochksum(). ***/
/****************************************************************************/
void allocbuf()
{
bufsiz=coreleft()-256;
bufptr =(char *) malloc((size_t) bufsiz);
if( bufptr == NULL ) {
fprintf(stderr,"chksum: Can't allocate input buffer of size %u.\n",
bufsiz);
exit(4);
}
}
/****************************************************************************/
/*** MAIN -- check the number of command line arguments, and dispatch ***/
/*** accordingly. If there are no arguments, show the syntax. ***/
/****************************************************************************/
main(int argc,char **argv)
{
int i;
int silent = FALSE; /* flag for the silent option */
int rc = 0; /* return code - sets ERRORLEVEL */
if( argc<2 ) usage();
if( '-'==argv[1][0] )
if( (2==strlen(argv[1])) && ('s'==tolower(argv[1][1])) )
silent = 1;
else {
fprintf(stderr,"chksum: illegal option: %s\n\n",argv[1]);
usage();
}
if( (argc-silent)>2 && !odd(argc-silent) ) {
E("chksum: Files and Checksums must be paired.\n\n");
usage();
}
else {
allocbuf();
if( (argc-silent)==2 ) showcksum(argv[1+silent]);
else for( i=1+silent; i<argc; i+=2)
rc |= verifycksum(argv[i],stoi(&argv[i+1]),silent);
}
return(rc);
}