Listing 3

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