home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / games / utils / ztools.lha / ztools / src / verify.c < prev   
C/C++ Source or Header  |  1992-12-17  |  3KB  |  115 lines

  1. /* verify.c V1.1
  2.  *
  3.  * Perform the same action as $verify on Infocom story files.
  4.  *
  5.  * Usage: $verify story-file-name
  6.  *
  7.  * Mark Howell 11 August 1992 howell_ma@movies.enet.dec.com
  8.  *
  9.  * History:
  10.  *    Make endian neutral
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15.  
  16. #define H_TYPE 0
  17. #define H_CONFIG 1
  18. #define H_VERSION 2
  19. #define H_RELEASE_DATE 18
  20. #define H_FILE_SIZE 26
  21. #define H_CHECKSUM 28
  22. #define H_SIZE 64
  23.  
  24. #define PAGE_SIZE 512
  25.  
  26. #if !defined(EXIT_SUCCESS)
  27. #define EXIT_SUCCESS 0
  28. #endif
  29.  
  30. #if !defined(EXIT_FAILURE)
  31. #define EXIT_FAILURE 1
  32. #endif
  33.  
  34. #define get_byte(offset) ((unsigned char) header[offset])
  35. #define get_word(offset) ((unsigned short) (((unsigned short) header[offset] << 8) + (unsigned short) header[offset + 1]))
  36.  
  37. #ifdef __STDC__
  38. int main (int argc, char *argv[])
  39. #else
  40. int main (argc, argv)
  41. int argc;
  42. char *argv[];
  43. #endif
  44. {
  45.     FILE *fp;
  46.     unsigned char header[H_SIZE], buffer[PAGE_SIZE];
  47.     unsigned long file_size, size;
  48.     unsigned short checksum, calculated_checksum = 0;
  49.     int i;
  50.  
  51.     if (argc != 2) {
  52.         fprintf (stderr, "Usage: %s story-file-name\n", argv[0]);
  53.     exit (EXIT_FAILURE);
  54.     }
  55.     if ((fp = fopen (argv[1], "rb")) == NULL) {
  56.         perror ("fopen");
  57.     exit (EXIT_FAILURE);
  58.     }
  59.     if (fread (header, H_SIZE, 1, fp) != 1) {
  60.         perror ("fread(story header)");
  61.     exit (EXIT_FAILURE);
  62.     }
  63.     printf ("Story type = %d, version = %d, release date = %c%c/%c%c/%c%c, configuration byte = %02x\n",
  64.         (int) get_byte (H_TYPE),
  65.         (int) get_word (H_VERSION),
  66.         (char) get_byte (H_RELEASE_DATE + 4), (char) get_byte (H_RELEASE_DATE + 5),
  67.         (char) get_byte (H_RELEASE_DATE + 2), (char) get_byte (H_RELEASE_DATE + 3),
  68.         (char) get_byte (H_RELEASE_DATE + 0), (char) get_byte (H_RELEASE_DATE + 1),
  69.         (int) get_byte (H_CONFIG));
  70.  
  71.     checksum = (unsigned short) get_word (H_CHECKSUM);
  72.     if (checksum) {
  73.         file_size = (unsigned long) get_word (H_FILE_SIZE);
  74.         switch ((int) get_byte (H_TYPE)) {
  75.             case 6: file_size *= 2;
  76.             case 5:
  77.             case 4: file_size *= 2;
  78.             case 3: file_size *= 2;
  79.             default: break;
  80.         }
  81.  
  82.         file_size -= H_SIZE;
  83.         size = PAGE_SIZE - H_SIZE;
  84.         while (file_size) {
  85.             if (fread (buffer, (size_t) size, 1, fp) != 1) {
  86.                 perror ("fread(story data)");
  87.                 exit (EXIT_FAILURE);
  88.             }
  89.             for (i = 0; i < size; i++)
  90.                 calculated_checksum += buffer[i];
  91.             file_size -= size;
  92.             if (file_size >= PAGE_SIZE)
  93.                 size = PAGE_SIZE;
  94.             else
  95.                 size = file_size;
  96.         }
  97.  
  98.         if (checksum == calculated_checksum) {
  99.             printf ("Story file verified OK\n");
  100.         } else {
  101.             fprintf (stderr,
  102.                      "Story file verify failed! actual checksum = %x, required checksum = %x\n",
  103.                      (int) calculated_checksum,
  104.                      (int) checksum);
  105.             exit (1);
  106.         }
  107.     } else
  108.         printf ("Story file has no checksum!\n");
  109.  
  110.     fclose (fp);
  111.     exit (EXIT_SUCCESS);
  112.     return (0);
  113.  
  114. }/* $verify */
  115.