/*                                                                     */
/* Programma CRC32.c - Codifica, decodifica e verifica un file con     */
/*                     checksum CRC a 32 bit, inserite dopo ogni bloc- */
/*                     co di 1024 byte del file originale.             */
/*                                                                     */
/* di Alberto Geneletti         per Amiga Magazine    Marzo 1992       */
/*                                                                     */
/* Compiled with LATTICE 5.02                                          */
/*                                                                     */
/* compile : lc crc32.c                                                */
/* link    : blink from lib:c.o, crcutils.o, crc32.o to crc32          */
/*           library lib:lc.lib                                        */
/*                                                                     */
/* Attenzione : in questo sorgente sono stati ridotti al minimo i      */
/*              commenti. Per maggiori chiarimenti confrontare con     */
/*              l'analogo listato commentato del comando CRC16.        */
/*                                                                     */
/* Vedere anche: CRCUtils.c e CRC16/32.doc                             */
/*                                                                     */

#include <stdio.h>
#ifdef LATTICE
int CXBRK(void) 
 { 
  return(0);
 }
#endif

#define BLOCKLEN 1024

FILE *fpa;
FILE *fpb;
unsigned char *Buffer;

void quit(int);

main(int argc, char *argv[])

{
int crc,ok,LunghezzaMessaggio;
char FileName[38];
char *Suffisso = ".CRC32";


/* La seguente sezione di codice fornisce note informative run-time,   */
/* che vengono visualizzate nel caso non venga passato alcun argomento */
/* o ne vengano passati in numero errato.                              */

if (argc == 1)
 {
  printf("\nCRC32 : di Alberto Geneletti 1992.\n\n");
  printf("        Codifica e decodifica un file con checksum CRC a 32 bit,\n");
  printf("        suddividendo il messaggio in blocchi di 1024 bytes per \n");
  printf("        una maggiore affidabilita'.\n\n");
 }

if (argc != 3)
 { 
  printf("Usage: CRC32 File ADD/CHECK/REMOVE\n");
  quit(1);
 }

/*        Viene allocata la memoria per il buffer di lavoro.           */

if ((Buffer = (unsigned char *)malloc(BLOCKLEN + 4)) == NULL)
 {
  printf("CRC32 error: out of memory.\n");
  quit(2);
 }

strcpy(FileName,*++argv);
strcat(FileName,Suffisso);

/* Si procede in base all'opzione selezionata.                         */
   
if ((ok = strcmp(*++argv,"ADD")) == NULL)



/*                      O p z i o n e   A D D .                        */


   {

        if ((fpa = fopen(*--argv, "r")) == NULL)
         { 
          printf("CRC32: can\'t open source file %s.\n", *argv);
          quit(3);
         }

        if ((fpb = fopen(FileName, "w")) == NULL)
        { 
          printf("CRC32 error: can\'t create destination file %s.\n", FileName);
          quit(4);
         }

        do
         {
          LunghezzaMessaggio = fread(Buffer,1,BLOCKLEN,fpa);

          if (LunghezzaMessaggio)
           crc = DoCRC32(Buffer,LunghezzaMessaggio);

          LunghezzaMessaggio += 4;
          fwrite(Buffer,1,LunghezzaMessaggio,fpb);
          LunghezzaMessaggio -= 4;
         }
        while (LunghezzaMessaggio == BLOCKLEN);

        printf("CRC32: Created the new file %s\n", FileName);
   }

else 
  if((ok = strcmp(*argv,"CHECK")) == NULL)



/*                      O p z i o n e   C H E C K .                    */

   {
        if ((fpa = fopen(FileName, "r")) == NULL)
         { 
          printf("CRC32: can\'t open file %s.\n", FileName);
          quit(5);
         }

        do
         {
          LunghezzaMessaggio = fread(Buffer,1,BLOCKLEN + 4,fpa);

           if (LunghezzaMessaggio)
            {
             LunghezzaMessaggio -= 4;

             if((ok = CheckCRC32(Buffer,LunghezzaMessaggio)) != NULL)
              {
               printf("CRC32: Checked the file %s Bad checksum. FILE CORRUPTED.\n",FileName);
               quit(6);
              }
            }
          }
        while (LunghezzaMessaggio == BLOCKLEN);

        printf("CRC32: Checked the file %s Good checksums.\n", FileName);
   }

else 
  if((ok = strcmp(*argv,"REMOVE")) == NULL)



/*                      O p z i o n e   R E M O V E  .                  */

   {
        if ((fpa = fopen(FileName, "r")) == NULL)
         { 
          printf("CRC32: can\'t open source file %s.\n", FileName);
          quit(7);
         }

        if ((fpb = fopen(*--argv,"w")) == NULL)
         { 
          printf("CRC32 error: can\'t create destination file %s.\n", *argv);
          quit(8);
         }

        do
         {
          LunghezzaMessaggio = fread(Buffer,1,BLOCKLEN + 4,fpa);

          if (LunghezzaMessaggio)
           {
            LunghezzaMessaggio -= 4;

            if((ok = CheckCRC32(Buffer,LunghezzaMessaggio)) != NULL)
             {
              printf("CRC32 warning: The current block has a BAD CHECKSUM.\n");
             }
           }

          fwrite(Buffer,1,LunghezzaMessaggio,fpb);
         }
        while (LunghezzaMessaggio == BLOCKLEN);

        fclose(fpa); fpa = NULL;

        if ((ok = remove(FileName)) != NULL)
         { 
          printf("CRC32: can\'t open remove file %s.\n", FileName);
          quit(9);
         }

         printf("CRC32: Removed file %s\n", FileName);
   }
else
   {
    printf("CRC32 error: BAD OPTION.\n");
    quit(10);
   }

 
quit(0);     
}

void quit(error)
{
if (fpa) fclose(fpa);
if (fpb) fclose(fpb);
if (Buffer) free(Buffer);

exit(error);
}

/* end of source CRC32.c */


