From:	CSBVAX::MRGATE!@KL.SRI.Com:BOB%HOWARD@cc.utah.edu@SMTP 13-SEP-1987 07:04
To:	EVERHART
Subj:	checksum/verify program (4 of 4)

Received: from CC.UTAH.EDU by KL.SRI.COM with TCP; Sun 13 Sep 87 02:36:25-PDT
Date: Sun, 13 Sep 87 03:38 MST
From: BOB%HOWARD@cc.utah.edu
Subject: checksum/verify program (4 of 4)
To: info-vax@KL.SRI.COM
X-VMS-To: INFOVAX

$Part4:
$ File_is="TYPEDEFS.H"
$ Check_Sum_is=958757556
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X/*
X  typedefs.h  -  type definitions
X*/
X
V#ifndef TYPEDEFS                                                     /* if we h
Xave not included typdefs then do it */
V#define TYPEDEFS                                                     /* define 
XTYPEDEFS to indicate they are defined */
X
Xtypedef unsigned int    u_int;
Xtypedef          int    s_int;
Xtypedef unsigned char   u_byte;
Xtypedef          char   s_byte;
Xtypedef unsigned short  u_word;
Xtypedef          short  s_word;
Xtypedef unsigned long   u_long;
Xtypedef          long   s_long;
Xtypedef          float  s_real;
Xtypedef          double d_real;
X
X#endif
$ GoSub Convert_File
$ File_is="VERIFY.C"
$ Check_Sum_is=436419089
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X/*
XCHECKSUM / VERIFY
X
X  Computes a checksum for a file or files.  These checksums are often used
X  with the VERIFY command to verify that files have not been changed since
X  the checksum was performed.
X
X  Format:
X
X    CHECKSUM [filespec1] [filespec2]
X    VERIFY   [filespec2] [filespec3]
X
X  Filespec1 determins which files are to be checksummed.  Wildcards and full
X  pathnames are allowed.  If the filespec is not given on the command line
X  you will be prompted for it.  This filespec is required.
X
X  Filespec2 specifies the name of an optional output file for the checksums
X  or required input file for the VERIFY command.  No wildcards are allowed. 
X  If the filespec is not given on the command line you will be prompted for it.
X  The CHECKSUM command will send its output to stdio if you press return at
X  this prompt.
X  
X  Filespec3 specifies an optional output file for the VERIFY command.  If
X  the filespec is not given on the command line you will be prompted for it.
X  The VERIFY command will send its output to stdio if you press return at
X  this prompt.
X
X
X  Example:
X
X   CHECKSUM *.* FOO.CKS
X   VERIFY FOO.CKS
X
X  The example above checksums all files in the current directory and writes
X  the results to FOO.CKS.  These checksums are then verified against the
X  current files by using the VERIFY command which writes its verifications
X  to stdio.
X
X  If you want to verify files against those in another directory you
X  must edit the pathnames in the checksum file (FOO.CKS in the example.)
X
X  Note:
X
X    Directories and multiple versions of files are not checksummed.
X  
X*/
X
X#include <stdio.h>
X#include <descrip.h>
X#include <rmsdef.h>
X#include "typedefs.h"
X
X#define  out_of_chars -1
X#define  max_spec_chars 80
X
Xstatic struct dsc$descriptor_s search_file;
Xstatic struct dsc$descriptor_s result_file;
Xstatic u_long context;
Xstatic u_byte search_filename[max_spec_chars];
Xstatic u_byte result_filename[max_spec_chars];
X
Xu_byte filespec[max_spec_chars];
Xu_byte infile[max_spec_chars];              /* FILENAME OF FILES TO VERIFY */
Xu_byte outfile[max_spec_chars];             /* FILENAME TO WRITE CHECKSUMS TO */
X
Xs_long old_checksum;
X
XFILE *fp, *in_fp, *out_fp;
X
X
X/**********************************************************************/
X/*                                                                    */
X/*                           GET_FILESPEC                             */
X/*                                                                    */
X/**********************************************************************/
X
Xs_word get_filespec()
X{
X  register s_word i;
X  u_byte buff;
X
X  /* READ FILE SPECIFICATION BY READING TO THE FIRST SPACE IN THE LINE. */
X  /* THEN SCAN BACKWARDS THROUGH THE CHARS  AND REPLACE DOTS WITH NULLS */
X
X  for( i=0; i<max_spec_chars ; i++) filespec[ i ] = '\0';
X  i = 0;
X  while((( filespec[ i++ ] = getc( in_fp ) ) != ' ') &&
X       (!feof( in_fp )));
X  if( feof( in_fp )) return(out_of_chars);
X
X  filespec[ --i ] = '\0'; /* GET RID OF SPACE */
X  while( filespec [ --i ] == '.') filespec[ i ] = '\0';
X
X
X  /* READ THE CHECKSUM */
X
X  fscanf(in_fp,"%d", &old_checksum);
X  while(( buff = getc( in_fp )) != '\n' );
X}
X
X
X
X
X
X
X/************************************************************************/
X/*                                                                      */
X/*                          MAIN                                        */
X/*                                                                      */
X/************************************************************************/
X
Xmain(argc, argv)
Xs_word argc;
Xu_byte *argv[];
X{
X
X  register u_word sum;             /* CHECKSUM */
X  register u_word i;               /* PLAIN'OL i */
X  register s_word dots;            /* DOT CHARACTERS FOR FORMATED OUTPUT */
X
X  u_word write_to_file;            /* BOOLEAN */
X  u_word missing;                  /* BOOLEAN */
X  u_word files_on_com_line;        /* BOOLEAN */
X
X  u_byte buff;
X  s_long n_good;                   /* COUNT OF GOOD FILES */
X  s_long n_bad;                    /* COUNT OF BAD FILES */
X  s_long n_missing;                /* COUNT OF MISSING FILES */
X
X  /* INITIALIZE SOME STUFF */
X
X  n_good = n_bad = n_missing = 0;
X  files_on_com_line = FALSE;
X  write_to_file = FALSE;
X  outfile[0] = '\0';
X  infile[0] = '\0';
X
X  if( argc > 3 ) {
X    fprintf(stderr,"To many command line arguments.\n");
X    goto bail_out;
X  }
X
X  if( argc > 1) {                 /* GET INPUT FILE IF ON COMMAND LINE */
X    files_on_com_line = TRUE;
X    strcpy(&infile, argv[1]);
X  }
X
X  if( argc == 3) {                /* GET OUTPUT FILE IF ON COMMAND LINE */
X    write_to_file = TRUE;
X    strcpy(&outfile, argv[2]);
X  }
X  
X
Xif( !files_on_com_line ) {        /* GET FROM USER IF NOT ON COMMAND LINE */
X
X  while ( infile[0] == '\0' ) {
X    printf("File         : ");
X    gets  (infile);
X  }
X  printf("Output file  : ");
X  gets  (outfile);
X  printf("\n\n");
X}
X
X  /* OPEN THE INPUT FILE */
X
X  if ( (in_fp = fopen(infile, "r")) == NULL) {
X    fprintf(stderr,"Can't open %s\n",infile);
X    goto bail_out;
X  }
X
X
X  /* IF AN OUTPUT FILE WAS SPECIFIED THEN SET A FLAG AND OPEN THE FILE */
X
X  if (outfile[0] != '\0') {
X    write_to_file = TRUE;
X    if ( (out_fp = fopen(outfile, "w")) == NULL) {
X      fprintf(stderr,"Can't open %s\n",outfile);
X      goto bail_out;
X    }
X  }
X
X
X  /* FOR EACH FILE, IF YOU CAN OPEN IT THEN CHECKSUM IT ELSE SET missing */
X  /* TO TRUE. */
X
X      while ( get_filespec() != out_of_chars ) {
X
X        missing = FALSE;
X        if ( (fp = fopen(filespec, "r")) != NULL) {
X          sum = 1;
X          while ( !feof(fp)){                    /* WHILE NOT EOF */
X            sum += (unsigned) fgetc(fp);         /* READ A CHARACTER */
X            if (sum & 0X8000) {                  /* ROTATE IF HIGH BIT SET */
X              sum <<= 1;
X              sum++;
X            }
X            else
X              sum <<= 1;                         /* ELSE JUST SHIFT */
X          }
X          fclose(fp);
X        }
X        else missing = TRUE;
X
X
X        /* IF OUTPUT IS TO A FILE... */
X
X        if (write_to_file) {
X          fprintf(out_fp,"%s",filespec);
X          dots = 70 - strlen(filespec);
X          if (dots > 0) for(i=1; i<dots; i++) fprintf(out_fp,"%c",'.'); 
X          if (missing) {
X            fprintf(out_fp,"  Missing\n");
X            n_missing++;
X          }
X          else {
X            if (old_checksum == sum) {
X              fprintf(out_fp,"  Good\n");
X              n_good++;
X            }
X            else {
X              fprintf(out_fp,"  Bad\n");
X              n_bad++;
X            }
X          }
X        }
X        
X        /* IF OUTPUT IS TO STDOUT */
X        
X        else {
X          printf("%s",filespec);
X          dots = 70 - strlen(filespec);
X          if (dots > 0) for(i=1; i<dots; i++) printf("%c",'.'); 
X          if (missing) {
X            printf("  Missing\n");
X            n_missing++;
X          }
X          else {
X            if (old_checksum == sum) {
X              printf("  Good\n");
X              n_good++;
X            }
X            else {
X              printf("  Bad\n");
X              n_bad++;
X            }
X          }
X        }
X      }
X
X  if (write_to_file) {
X    fprintf(out_fp,"\n\n");
X    fprintf(out_fp,"                        ");
X    fprintf(out_fp,"Good     :  %d\n",n_good);
X    fprintf(out_fp,"                        ");
X    fprintf(out_fp,"Bad      :  %d\n",n_bad);
X    fprintf(out_fp,"                        ");
X    fprintf(out_fp,"Missing  :  %d\n",n_missing);
X    fclose(out_fp);
X  }
X  else {
X    printf("\n\n");
X    printf("                        ");
X    printf("Good     :  %d\n",n_good);
X    printf("                        ");
X    printf("Bad      :  %d\n",n_bad);
X    printf("                        ");
X    printf("Missing  :  %d\n",n_missing);
X  }
X
X bail_out:;
X}
$ GoSub Convert_File
$ Exit
