  1: /* 
  2:  *  MDBFBIN.C
  3:  *
  4:  *  Program:  Mini-Database
  5:  *  Written by: Leor Zolman
  6:  *  Module:   File I/O, Binary
  7:  *            Representation Version
  8:  */
  9: 
 10: #include <stdio.h>
 11: #include <stdlib.h>
 12: #include "mdb.h"
 13: 
 14: /*
 15:  * Function:    read_db
 16:  * Purpose:     Load an existing Database from disk
 17:  * Parameters:    Name of Database to load
 18:  * Return Value:  NULL on error, else # of records.
 19:  */
 20: 
 21: int read_db(char *filename)
 22: {
 23:   FILE *fp;
 24:   int nrecs, result;
 25:   struct record recbuf;
 26: 
 27: #if DYN_ARRAY
 28:   int array_size;
 29: #endif
 30:   
 31:   if ((fp = fopen(filename, "rb")) == NULL)
 32:   {
 33:     printf("Database not found.\n");
 34:     return 0;
 35:   }
 36: 
 37: #if DYN_ARRAY     /* Allocating array space dynamically   */
 38:   fseek(fp, 0L, 2);     /*    skip to end of data   */
 39:   nrecs = ftell(fp) / sizeof(struct record);  /* # of recs  */
 40:   max_recs = nrecs + MAX_TO_ADD;  /* allow MAX_TO_ADD more  */
 41:   array_size = max_recs * sizeof(struct record *);
 42:                     /* allocate the memory  */
 43:   if ((recs = malloc(array_size)) == NULL)
 44:   {
 45:     printf("Couldn't allocate recs array; aborting.\n");
 46:     return NULL;
 47:   }
 48:   fseek(fp, 0L, 0);     /* reset to beginning of data */
 49: #else
 50:   max_recs = MAX_RECS;
 51: #endif
 52:   
 53:   for (nrecs = 0; ;nrecs++)
 54:   {
 55:     result = fread(&recbuf, sizeof(struct record), 1, fp);
 56: 
 57:     if (result == 0)              /* EOF */
 58:       break;
 59: 
 60:     if (ferror(fp))
 61:       error("Error on file input. Aborting.\n");
 62: 
 63:     if ((RECS[nrecs] = alloc_rec()) == NULL)
 64:       error("Out of memory. Aborting.\n");
 65: 
 66:     *RECS[nrecs] = recbuf;    /* Copy the record  */
 67:   }
 68: 
 69:   fclose(fp);
 70:   return nrecs;
 71: }
 72: 
 73: 
 74: /*
 75:  * Function:    write_db
 76:  * Purpose:     Write current Database to disk
 77:  * Parameters:    Name of Database
 78:  * Return Value:  None
 79:  */
 80: 
 81: void write_db(char *filename)
 82: {
 83:   FILE *fp;
 84:   char *tempname = "TEMPFILE";
 85:   int result, i;
 86:   
 87:   if ((fp = fopen(tempname, "wb")) == NULL)
 88:   {
 89:     printf("Can't open Database file for reading.\n");
 90:     return;
 91:   }
 92:   
 93:   printf("Writing Database %s To Disk...\n", filename);
 94: 
 95:   for (i = 0; i < n_recs; i++)
 96:     if (fwrite(RECS[i], sizeof(struct record),
 97:                   1, fp) != 1)
 98:     {
 99:       printf("Error writing file. Aborting attempt.\n");
100:       fclose(fp);
101:       remove(tempname);
102:       return;
103:     }
104: 
105:   fclose(fp);
106:   remove(filename);
107:   while (rename(tempname, filename) == -1)
108:   {
109:     printf("Error renaming temp file: %s\n",
110:               _strerror(NULL));
111:     printf("Please enter a new filename: ");
112:     gets(filename);
113:   }
114:   printf("Database written successfully.\n");
115: }
