home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pendem.zip / BOOKFL.C < prev    next >
Text File  |  1994-07-21  |  24KB  |  832 lines

  1. /* ==========================================================================
  2.  *   Sarka Martinez (407) 982- 5580, Pen Developer Magazine July/August '94 page 73
  3.  *
  4.  *          Copyright.
  5.  *
  6.  *                      OCO Source Materials
  7.  *
  8.  *                      5706-110 (C) Copyright IBM Corp. 1993
  9.  *
  10.  * ======================================================================== */
  11.  
  12. /* ======================================================================
  13.  *                            IBM CONFIDENTIAL
  14.  * ======================================================================
  15.  *
  16.  *  product name.
  17.  *
  18.  *  Filespec.                 BOOKFL.C
  19.  *
  20.  *  Author.                   Sarka Martinez
  21.  *
  22.  *  Date-Written.             05-11-1993
  23.  *
  24.  *  Copyright.                Copyright (C) IBM Corporation 1993
  25.  *                            LICENSED MATERIAL-PROGRAM PROPERTY OF IBM
  26.  *
  27.  *  Change History.
  28.  *
  29.  *    Rel  Programmer      Date      Description
  30.  *   ----- -------------   -------    --------------------------------
  31.  *    1.00 Sarka Martinez   051193    Demo Stage
  32.  *
  33.  * =================================================================== */
  34. #define INCL_DOS
  35. #define INCL_WIN
  36. #define INCL_DOSDATETIME
  37. #define INCL_GPI
  38.  
  39. #include <os2.h>
  40. #include <fcntl.h>
  41. #include <sys\types.h>
  42. #include <sys\stat.h>
  43. #include <io.h>
  44. #include <string.h>                     // C-runtime String routines
  45. #include <stdio.h>                      // C-Standard I/O functions
  46. #include <stdlib.h>
  47. #include "book.h"
  48.  
  49. SHORT FindNameFileLoc(INT *hf, CARDINFO *CardInfo, DATAFILE *FileD);
  50. SHORT GetName(INT *hf, CHAR *RecId, USHORT len);
  51. SHORT FindRecIdFileLoc(INT *hf, CARDINFO *CardInfo, DATAFILE *FileD);
  52. SHORT GetRecID(INT *hf, CHAR *RecId, USHORT len);
  53. SHORT UpdateFile(INT *hf, CARDINFO *CardInfo, USHORT len, DATAFILE *FileD);
  54. SHORT CreateNewFile(INT *hf, CARDINFO *CardInfo);
  55. SHORT FindFileSec(INT *hf, DATAFILE *FileD, CHAR *RecId);
  56. SHORT DelFile(INT *hf, USHORT len, LONG old_pos, DATAFILE *FileD);
  57.  
  58. CARDINFO *Names;
  59. extern HAB   hab;
  60. extern CHAR  *BookPath;
  61.  
  62. // read the .dat file and insert all info into the global data struct...
  63. USHORT GetAllRecords(HWND hwnd, USHORT *numRecs)
  64. {
  65.    USHORT     fieldLength, fileLength;
  66.    DATAFILE  *FileD;
  67.    CHAR       file[45], Bmpfile[45];
  68.    INT        hf;
  69.    HPS        hps;    /* Handle to Presentation space */
  70.  
  71.  
  72.      *numRecs = 0;
  73.      FileD = (DATAFILE *)malloc(sizeof(DATAFILE));
  74.      FileD->FileData = (CHAR *)malloc(FILE_MAXSIZE+1);
  75.  
  76.      sprintf(file, "%s\\book.dat", BookPath);
  77.      hf = open(file, O_RDONLY);
  78.      if (hf == -1 || hf == 0)
  79.        return 1;
  80.      FileD->TotLen = read(hf, FileD->FileData, FILE_MAXSIZE);
  81.      close(hf);
  82.  
  83.      if ((FileD->TotLen == 0) || (FileD->TotLen == -1))
  84.        return 1;
  85.  
  86.      fileLength = 0;
  87.      if ((Names = (CARDINFO *) malloc(MAXNAMES*sizeof(CARDINFO))) == NULL) {
  88.        DosBeep(500,100);
  89.        return 2;
  90.      }
  91.  
  92.      while (fileLength < FileD->TotLen)
  93.      {
  94.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 8; fieldLength++, fileLength++)
  95.          Names[*numRecs].RecId[fieldLength] = FileD->FileData[fileLength];
  96.        Names[*numRecs].RecId[fieldLength] = '\0';
  97.        fileLength++;
  98.  
  99.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 30; fieldLength++, fileLength++)
  100.          Names[*numRecs].LName[fieldLength] = FileD->FileData[fileLength];
  101.        Names[*numRecs].LName[fieldLength] = '\0';
  102.        fileLength++;  // skip the return line char.
  103.  
  104.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 30; fieldLength++, fileLength++)
  105.          Names[*numRecs].FName[fieldLength] = FileD->FileData[fileLength];
  106.        Names[*numRecs].FName[fieldLength] = '\0';
  107.        fileLength++;
  108.  
  109.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 1; fieldLength++, fileLength++)
  110.          Names[*numRecs].Initial[fieldLength] = FileD->FileData[fileLength];
  111.        Names[*numRecs].Initial[fieldLength] = '\0';
  112.        fileLength++;
  113.  
  114.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 100; fieldLength++, fileLength++)
  115.          Names[*numRecs].Company[fieldLength] = FileD->FileData[fileLength];
  116.        Names[*numRecs].Company[fieldLength] = '\0';
  117.        fileLength++;
  118.  
  119.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 100; fieldLength++, fileLength++)
  120.          Names[*numRecs].Division[fieldLength] = FileD->FileData[fileLength];
  121.        Names[*numRecs].Division[fieldLength] = '\0';
  122.        fileLength++;
  123.  
  124.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 201; fieldLength++, fileLength++)
  125.          Names[*numRecs].StrAddr[fieldLength] = FileD->FileData[fileLength];
  126.        Names[*numRecs].StrAddr[fieldLength] = '\0';
  127.        fileLength++;
  128.  
  129.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 30; fieldLength++, fileLength++)
  130.          Names[*numRecs].City[fieldLength] = FileD->FileData[fileLength];
  131.        Names[*numRecs].City[fieldLength] = '\0';
  132.        fileLength++;
  133.  
  134.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 2; fieldLength++, fileLength++)
  135.          Names[*numRecs].State[fieldLength] = FileD->FileData[fileLength];
  136.        Names[*numRecs].State[fieldLength] = '\0';
  137.        fileLength++;
  138.  
  139.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 10; fieldLength++, fileLength++)
  140.          Names[*numRecs].Zip[fieldLength] = FileD->FileData[fileLength];
  141.        Names[*numRecs].Zip[fieldLength] = '\0';
  142.        fileLength++;
  143.  
  144.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 15; fieldLength++, fileLength++)
  145.          Names[*numRecs].Phone[fieldLength] = FileD->FileData[fileLength];
  146.        Names[*numRecs].Phone[fieldLength] = '\0';
  147.        fileLength++;
  148.  
  149.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 15; fieldLength++, fileLength++)
  150.          Names[*numRecs].Fax[fieldLength] = FileD->FileData[fileLength];
  151.        Names[*numRecs].Fax[fieldLength] = '\0';
  152.        fileLength++;
  153.  
  154.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 8; fieldLength++, fileLength++)
  155.          Names[*numRecs].PagerID[fieldLength] = FileD->FileData[fileLength];
  156.        Names[*numRecs].PagerID[fieldLength] = '\0';
  157.        fileLength++;
  158.  
  159.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 8; fieldLength++, fileLength++)
  160.          Names[*numRecs].MailUserId[fieldLength] = FileD->FileData[fileLength];
  161.        Names[*numRecs].MailUserId[fieldLength] = '\0';
  162.        fileLength++;
  163.  
  164.        for (fieldLength = 0; FileD->FileData[fileLength] != '\n' && fieldLength < 8; fieldLength++, fileLength++)
  165.          Names[*numRecs].MailNodeId[fieldLength] = FileD->FileData[fileLength];
  166.        Names[*numRecs].MailNodeId[fieldLength] = '\0';
  167.        fileLength++;
  168.  
  169.       // read in the logo bitmap
  170.       sprintf(Bmpfile, "%s\\%s.bmp", BookPath, Names[*numRecs].RecId);
  171.       hps = WinGetPS (hwnd);
  172.       Names[*numRecs].hbmBitmap = ReadBitmapFile(Bmpfile, &hps);
  173.       WinReleasePS (hps);
  174.  
  175.       (*numRecs)++;
  176.     }
  177.  
  178. }
  179.  
  180.  
  181. HBITMAP ReadBitmapFile(PSZ PictureDataFile, HPS *hpsMem)
  182. {
  183.     HDC     hdc;
  184.     PBYTE   lpFileBuf;
  185.     SIZEL   lSize;
  186.     HBITMAP pbm;
  187.     FILE    *fp;
  188.     SEL     Sel;
  189.     USHORT  Row;
  190.     USHORT  MaxLines;
  191.     USHORT  BytesPerLine;
  192.     SIZEL   sz;
  193.  
  194.     static struct
  195.     {
  196.         BITMAPFILEHEADER bmfh;          // Data from loaded bitmap file
  197.         RGB              palette[256];
  198.     } bm;
  199.  
  200.     /* open bitmap file */
  201.  
  202.     if ((fp = fopen(PictureDataFile, "rb")) == NULL)
  203.         return NULLHANDLE;
  204.  
  205.     /* read bitmap file header */
  206.  
  207.     fread(&bm.bmfh, sizeof(BITMAPFILEHEADER), 1, fp);
  208.  
  209.     /* make sure it really is a bitmap */
  210.  
  211.     if ( bm.bmfh.usType != BFT_BMAP || bm.bmfh.bmp.cBitCount > 24 )
  212.     {
  213.         fclose(fp);
  214.         return NULLHANDLE;
  215.     }
  216.  
  217.     /* skip past BMP file palette */
  218.  
  219.     fread( bm.palette, (1 << bm.bmfh.bmp.cBitCount) * sizeof(RGB), 1, fp);
  220.  
  221.     /* Create a memory DC */
  222.     hdc = DevOpenDC(hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE);
  223.     if (hdc == DEV_ERROR)
  224.     {
  225.         fclose(fp);
  226.         return NULLHANDLE;
  227.     }
  228.  
  229.     /* Create a memory PS */
  230.  
  231.     lSize.cx = 0L;
  232.     lSize.cy = 0L;
  233.  
  234.     *hpsMem = GpiCreatePS(hab, hdc, &lSize, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
  235.     if (*hpsMem == GPI_ERROR)
  236.     {
  237.         fclose(fp);
  238.         return NULLHANDLE;
  239.     }
  240.  
  241.     /* Create a bitmap */
  242.  
  243.     pbm = GpiCreateBitmap(*hpsMem, (PBITMAPINFOHEADER2)&bm.bmfh.bmp,
  244.                           0L, NULL, NULLHANDLE);
  245.  
  246.     /* Associate the bitmap to the memory presentation space */
  247.  
  248.     GpiSetBitmap(*hpsMem, pbm);
  249.  
  250. #define  BYTES_IN_LONGWORD  4
  251. #define  BITS_IN_4_BYTES   32
  252.  
  253.     /* calculate the number of bytes per scan line */
  254.  
  255.     BytesPerLine = ((( (USHORT)bm.bmfh.bmp.cBitCount * (USHORT)bm.bmfh.bmp.cx +
  256.            (BITS_IN_4_BYTES - 1)) / BITS_IN_4_BYTES) * bm.bmfh.bmp.cPlanes
  257.                      * BYTES_IN_LONGWORD);
  258.  
  259.     if (BytesPerLine == 0)
  260.     {
  261.         fclose(fp);
  262.         return NULLHANDLE;
  263.     }
  264.  
  265.     /* allocate memory for reading bitmap file */
  266.  
  267.         // initialize
  268.     for ( Sel = 0, MaxLines = (USHORT) (32768L / BytesPerLine);
  269.       // test
  270.       (lpFileBuf = (PBYTE)malloc((USHORT)(MaxLines * BytesPerLine)))
  271. //          DosAllocSeg((USHORT)(MaxLines * BytesPerLine), (PSEL)&Sel, NULL)
  272.                && (MaxLines > 1);
  273.           // decriment
  274.           MaxLines /= 2 );
  275.  
  276. //    if (!Sel)
  277. //    {
  278. //        fclose(fp);
  279. //        return NULLHANDLE;                    // no memory
  280. //    }
  281.  
  282. //    lpFileBuf = (PBYTE)MAKEP(Sel, 0);   // make a far pointer
  283.  
  284.     /* read the file and set the bitmap bits as we go */
  285.  
  286.     Row = 0;
  287.  
  288.     if (MaxLines > (SHORT) bm.bmfh.bmp.cy)
  289.       MaxLines = (SHORT) bm.bmfh.bmp.cy;
  290.  
  291.     while (Row < (SHORT) bm.bmfh.bmp.cy)
  292.     {
  293.         fread( lpFileBuf, (USHORT)(BytesPerLine * MaxLines), 1, fp );
  294.  
  295.         GpiSetBitmapBits(*hpsMem, (LONG) Row, (LONG) MaxLines, lpFileBuf,
  296.                          (PBITMAPINFO2) &bm.bmfh.bmp);
  297.  
  298.         Row += MaxLines;
  299.  
  300.         if ((SHORT) bm.bmfh.bmp.cy - Row < MaxLines)
  301.             MaxLines = (SHORT) bm.bmfh.bmp.cy - Row;
  302.     }
  303.  
  304. //    DosFreeSeg(Sel);
  305.     free(lpFileBuf);
  306.  
  307.     fclose(fp);
  308.  
  309.     sz.cx = bm.bmfh.bmp.cx;
  310.     sz.cy = bm.bmfh.bmp.cy;
  311.     GpiSetBitmapDimension(pbm, &sz);
  312.     GpiSetBitmap(*hpsMem, NULLHANDLE);
  313.     GpiDestroyPS(*hpsMem);
  314.     DevCloseDC(hdc);
  315.  
  316.     return pbm;
  317. }
  318.  
  319. // prepare to update the .dat file
  320. VOID PrepUpdRec(CARDINFO *CardInfo, CHAR *bmp_file, USHORT bmp_length)
  321. {
  322.      DATAFILE  *FileD;
  323.      CHAR       file[45];
  324.      INT        hf;
  325.      SHORT      rc;
  326.  
  327.      FileD = (DATAFILE *)malloc(sizeof(DATAFILE));
  328.      FileD->FileData = (CHAR *)malloc(FILE_MAXSIZE+1);
  329.  
  330.      sprintf(file, "%s\\book.dat", BookPath);
  331.      hf = open(file, O_RDONLY);
  332.      if (hf == -1 || hf == 0)
  333.        return;
  334.      FileD->TotLen = read(hf, FileD->FileData, FILE_MAXSIZE);
  335.      close(hf);
  336.  
  337.      hf = open(file, O_RDWR);
  338.      rc = FindRecIdFileLoc(&hf, CardInfo, FileD);
  339.      close(hf);
  340.  
  341.       // copy the .bmp over
  342.       sprintf(file, "%s\\%s.bmp", BookPath, CardInfo->RecId);
  343.       hf = open(file, O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  344.       if (hf == -1 || hf == 0)
  345.         return;
  346.       lseek(hf, 0L, SEEK_SET);
  347.       write( hf, bmp_file, bmp_length);
  348.       close(hf);
  349.  
  350.       free(FileD->FileData);
  351.       free(FileD);
  352. }
  353.  
  354. // prepare to add a new record to the .dat file
  355. VOID PrepAddToRec(CARDINFO *CardInfo, CHAR *bmp_file, USHORT bmp_length)
  356. {
  357.      DATAFILE  *FileD;
  358.      CHAR       file[45];
  359.      INT        hf;
  360.      SHORT      rc;
  361.  
  362.      FileD = (DATAFILE *)malloc(sizeof(DATAFILE));
  363.      FileD->FileData = (CHAR *)malloc(FILE_MAXSIZE+1);
  364.  
  365.      sprintf(file, "%s\\book.dat", BookPath);
  366.      hf = open(file, O_RDONLY);
  367.      if (hf == -1 || hf == 0) {  // file does not exist, so creat it
  368.        hf = open(file, O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  369.        lseek(hf, 0L, SEEK_SET);
  370.        CreateNewFile(&hf, CardInfo);
  371.        close(hf);
  372.      }
  373.      else {
  374.         FileD->TotLen = read(hf, FileD->FileData, FILE_MAXSIZE);
  375.         close(hf);
  376.  
  377.         hf = open(file, O_RDWR);
  378.         // find where to add this name, .dat file stays in alphabetic order.
  379.         rc = FindNameFileLoc(&hf, CardInfo, FileD);
  380.         close(hf);
  381.      }
  382.      // copy the .bmp over
  383.      sprintf(file, "%s\\%s.bmp", BookPath, CardInfo->RecId);
  384.      hf = open(file, O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  385.      if (hf == -1 || hf == 0)
  386.        return;
  387.      lseek(hf, 0L, SEEK_SET);
  388.      write( hf, bmp_file, bmp_length);
  389.      close(hf);
  390.  
  391.      free(FileD->FileData);
  392.      free(FileD);
  393. }
  394.  
  395. // Find and Compare the Last Name fields inorder to insert a new record in the
  396. // correct area, file is in alphabetic order...
  397. // as of this time there is no support for people w/ the same last name...
  398. // the new record will simply be inserted before the old one.
  399. SHORT FindNameFileLoc(INT *hf, CARDINFO *CardInfo, DATAFILE *FileD)
  400. {
  401.   CHAR str[1], currName[31];
  402.   SHORT  rc=0, line=0, i=0, len=0, prevlen=0;
  403.  
  404.  
  405.   // skip the RecId field & get to the Last Name field
  406.   while (!eof(*hf) && (line < 1) && (len < 101)) {
  407.     rc = read(*hf, str, 1);
  408.     if (rc == -1)
  409.       return rc;
  410.  
  411.     len++;
  412.     if (str[0] == '\n')
  413.       line = 1;
  414.   }
  415.   // at Last name field, now read it in
  416.   // len is 0 because you want to add it to the front of the file
  417.   len = GetName(hf, currName, 0);
  418.   if (len == -1)
  419.     return  -1;
  420.  
  421.   // if the string is not higher in the alphabet
  422.   // hardcoded for codepage 437
  423.   if (WinCompareStrings(hab, (ULONG)437, (ULONG)1,
  424.                         CardInfo->LName, currName, 0L) != WCS_GT) {
  425.     rc = UpdateFile(hf, CardInfo, len, FileD);
  426.     if (rc)
  427.       return 1;
  428.     return 0;
  429.   }
  430.  
  431.   line = 0;
  432.   /* find Next User Id line */
  433.   while (!eof(*hf)) {
  434.     if (line == 13)
  435.       prevlen = len;  // add begining of record so save that point.
  436.     while (!eof(*hf) && (line < 15) && (i < 101)) {
  437.       rc = read(*hf, str, 1);
  438.       if (rc == -1)
  439.         return rc;
  440.  
  441.       i++;
  442.       len++;
  443.       if (str[0] == '\n') {
  444.         line++;
  445.         i=0;
  446.       }
  447.     }
  448.     if (i >= 101)
  449.       return 1;
  450.  
  451.     if (!eof(*hf)) {
  452.       /* find Last name */
  453.       len = GetName(hf, currName, len);
  454.       if (len == -1)
  455.         return  -1;
  456.  
  457.       if (WinCompareStrings(hab, (ULONG)437, (ULONG)1,
  458.                             CardInfo->LName, currName, 0L) != WCS_GT) {
  459.         // want to add it before this record so use prevlen...
  460.         rc = UpdateFile(hf, CardInfo, prevlen, FileD);
  461.         if (rc)
  462.           return 1;
  463.         return 0;
  464.       }
  465.       line=0;
  466.       prevlen=0;
  467.       i=0;
  468.     }
  469.     else  /* entry was not found */
  470.       return 1;
  471.   }
  472.   return 1; /* entry was not found */
  473. }
  474.  
  475. // read in the Last Name field in the file
  476. SHORT GetName(INT *hf, CHAR *LName, USHORT len)
  477. {
  478.   CHAR   str[1];
  479.   SHORT  rc=0, i=0;
  480.  
  481.   /* find Last Name*/
  482.   while (!eof(*hf) && (i < 31)) {
  483.     rc = read(*hf, str, 1);
  484.     if (rc == -1)
  485.       return rc;
  486.  
  487.     len++;
  488.     if (str[0] != '\n')
  489.       LName[i] = str[0];
  490.     else {
  491.       LName[i] = '\0';
  492.       return len;
  493.     }
  494.     i++;
  495.   }
  496.   if (!eof(*hf)) {
  497.     LName[i] = '\0';
  498.     return len;
  499.   }
  500.   else
  501.     return -1;
  502. }
  503.  
  504. // Find and Compare the RecordID fields inorder update the correct record
  505. SHORT FindRecIdFileLoc(INT *hf, CARDINFO *CardInfo, DATAFILE *FileD)
  506. {
  507.   CHAR str[1], currRec[9];
  508.   SHORT  rc=0, line=0, i=0, len=0;
  509.  
  510.  
  511.   len = GetRecID(hf, currRec, len);
  512.   if (len == -1)
  513.     return  -1;
  514.  
  515.   if (strcmp(currRec, CardInfo->RecId) == 0) {
  516.     rc = UpdateFile(hf, CardInfo, len, FileD);
  517.     if (rc)
  518.       return 1;
  519.     return 0;
  520.   }
  521.  
  522.   /* find Next User Id line */
  523.   while (!eof(*hf)) {
  524.     while (!eof(*hf) && (line < 15) && (i < 101)) {
  525.       rc = read(*hf, str, 1);
  526.       if (rc == -1)
  527.         return rc;
  528.  
  529.       i++;
  530.       len++;
  531.       if (str[0] == '\n') {
  532.         line++;
  533.         i=0;
  534.       }
  535.     }
  536.     if (i >= 101)
  537.       return 1;
  538.  
  539.     if (!eof(*hf)) {
  540.       /* find User Id */
  541.       len = GetRecID(hf, currRec, len);
  542.       if (len == -1)
  543.         return  -1;
  544.  
  545.       if (strcmp(currRec, CardInfo->RecId) == 0) {
  546.         rc = UpdateFile(hf, CardInfo, len, FileD);
  547.         if (rc)
  548.           return 1;
  549.         return 0;
  550.       }
  551.       line=0;
  552.       i=0;
  553.     }
  554.     else  /* entry was not found */
  555.       return 1;
  556.   }
  557.   return 1; /* entry was not found */
  558. }
  559.  
  560. // read in the record id field in the .dat file
  561. SHORT GetRecID(INT *hf, CHAR *RecId, USHORT len)
  562. {
  563.   CHAR   str[1];
  564.   SHORT  rc=0, i=0;
  565.  
  566.   /* find User Id */
  567.   while (!eof(*hf) && (i < 9)) {
  568.     rc = read(*hf, str, 1);
  569.     if (rc == -1)
  570.       return rc;
  571.  
  572.     len++;
  573.     if (str[0] != '\n')
  574.       RecId[i] = str[0];
  575.     else {
  576.       RecId[i] = '\0';
  577.       return len;
  578.     }
  579.     i++;
  580.   }
  581.   if (!eof(*hf)) {
  582.     RecId[i] = '\0';
  583.     return len;
  584.   }
  585.   else
  586.     return -1;
  587. }
  588.  
  589. // actually update the .dat file
  590. SHORT UpdateFile(INT *hf, CARDINFO *CardInfo, USHORT len, DATAFILE *FileD)
  591. {
  592.    CHAR currRec[9], *Data;
  593.    SHORT i=0, rc=0, lines=0;
  594.    LONG  pos=0;
  595.  
  596.  
  597.     write(*hf, CardInfo->LName, strlen(CardInfo->LName));
  598.     write(*hf, "\n", 1);
  599.     write(*hf, CardInfo->FName, strlen(CardInfo->FName));
  600.     write(*hf, "\n", 1);
  601.     write(*hf, CardInfo->Initial, strlen(CardInfo->Initial));
  602.     write(*hf, "\n", 1);
  603.     write(*hf, CardInfo->Company, strlen(CardInfo->Company));
  604.     write(*hf, "\n", 1);
  605.     write(*hf, CardInfo->Division, strlen(CardInfo->Division));
  606.     write(*hf, "\n", 1);
  607.     write(*hf, CardInfo->StrAddr, strlen(CardInfo->StrAddr));
  608.     write(*hf, "\n", 1);
  609.     write(*hf, CardInfo->City, strlen(CardInfo->City));
  610.     write(*hf, "\n", 1);
  611.     write(*hf, CardInfo->State, strlen(CardInfo->State));
  612.     write(*hf, "\n", 1);
  613.     write(*hf, CardInfo->Zip, strlen(CardInfo->Zip));
  614.     write(*hf, "\n", 1);
  615.  
  616.     write(*hf, CardInfo->Phone, strlen(CardInfo->Phone));
  617.     write(*hf, "\n", 1);
  618.     write(*hf, CardInfo->Fax, strlen(CardInfo->Fax));
  619.     write(*hf, "\n", 1);
  620.     write(*hf, CardInfo->PagerID, strlen(CardInfo->PagerID));
  621.     write(*hf, "\n", 1);
  622.     write(*hf, CardInfo->MailUserId, strlen(CardInfo->MailUserId));
  623.     write(*hf, "\n", 1);
  624.     write(*hf, CardInfo->MailNodeId, strlen(CardInfo->MailNodeId));
  625.     rc = write(*hf, "\n", 1);
  626.     if (rc == -1)
  627.       return 1;
  628.  
  629.     /* append the rest of the old file on end */
  630.     while(len != FileD->TotLen)
  631.       len++;
  632.  
  633.     Data = &(FileD->FileData[len]);
  634.     rc = write(*hf, Data, (FileD->TotLen - len));
  635.     if (rc == -1)
  636.       return 1;
  637.  
  638.     /* force and End of File */
  639.     pos = tell(*hf);
  640.     chsize(*hf, pos);
  641.  
  642.     return 0;
  643. }
  644.  
  645. // create a brand new .dat file
  646. SHORT CreateNewFile(INT *hf, CARDINFO *CardInfo)
  647. {
  648.    CHAR currRec[9], *Data;
  649.    SHORT i=0, rc=0, lines=0;
  650.    LONG  pos=0;
  651.    DATETIME  TimeData;
  652.  
  653.     DosGetDateTime(&TimeData);
  654.     sprintf(CardInfo->RecId, "%d%d%d%d", TimeData.day, TimeData.month,
  655.             TimeData.hours, TimeData.minutes);
  656.     write(*hf, CardInfo->RecId, strlen(CardInfo->RecId));
  657.     write(*hf, "\n", 1);
  658.     write(*hf, CardInfo->LName, strlen(CardInfo->LName));
  659.     write(*hf, "\n", 1);
  660.     write(*hf, CardInfo->FName, strlen(CardInfo->FName));
  661.     write(*hf, "\n", 1);
  662.     write(*hf, CardInfo->Initial, strlen(CardInfo->Initial));
  663.     write(*hf, "\n", 1);
  664.     write(*hf, CardInfo->Company, strlen(CardInfo->Company));
  665.     write(*hf, "\n", 1);
  666.     write(*hf, CardInfo->Division, strlen(CardInfo->Division));
  667.     write(*hf, "\n", 1);
  668.     write(*hf, CardInfo->StrAddr, strlen(CardInfo->StrAddr));
  669.     write(*hf, "\n", 1);
  670.     write(*hf, CardInfo->City, strlen(CardInfo->City));
  671.     write(*hf, "\n", 1);
  672.     write(*hf, CardInfo->State, strlen(CardInfo->State));
  673.     write(*hf, "\n", 1);
  674.     write(*hf, CardInfo->Zip, strlen(CardInfo->Zip));
  675.     write(*hf, "\n", 1);
  676.  
  677.     write(*hf, CardInfo->Phone, strlen(CardInfo->Phone));
  678.     write(*hf, "\n", 1);
  679.     write(*hf, CardInfo->Fax, strlen(CardInfo->Fax));
  680.     write(*hf, "\n", 1);
  681.     write(*hf, CardInfo->PagerID, strlen(CardInfo->PagerID));
  682.     write(*hf, "\n", 1);
  683.     write(*hf, CardInfo->MailUserId, strlen(CardInfo->MailUserId));
  684.     write(*hf, "\n", 1);
  685.     write(*hf, CardInfo->MailNodeId, strlen(CardInfo->MailNodeId));
  686.     rc = write(*hf, "\n", 1);
  687.     if (rc == -1)
  688.       return 1;
  689.  
  690.     /* force and End of File */
  691.     pos = tell(*hf);
  692.     chsize(*hf, pos);
  693.  
  694.     return 0;
  695. }
  696.  
  697.  
  698. // prepare to delete a record out of the .dat file
  699. VOID PrepDelRec(CHAR *RecId)
  700. {
  701.      DATAFILE   *FileD;
  702.      CHAR       file[45];
  703.      INT        hf;
  704.      SHORT      rc;
  705.  
  706.      FileD = (DATAFILE *)malloc(sizeof(DATAFILE));
  707.      FileD->FileData = (CHAR *)malloc(FILE_MAXSIZE+1);
  708.  
  709.      sprintf(file, "%s\\book.dat", BookPath);
  710.      hf = open(file, O_RDONLY);
  711.      if (hf == -1 || hf == 0)
  712.        return;
  713.  
  714.      FileD->TotLen = read(hf, FileD->FileData, FILE_MAXSIZE);
  715.      close(hf);
  716.  
  717.      hf = open(file, O_RDWR);
  718.      rc = FindFileSec(&hf, FileD, RecId);
  719.  
  720.      if (rc || hf == -1 || hf == 0)
  721.        return;
  722.  
  723.      // erase the .bmp
  724.      sprintf(file, "%s\\%s.bmp", BookPath, RecId);
  725.      unlink(file);
  726.  
  727.      free(FileD->FileData);
  728.      free(FileD);
  729. }
  730.  
  731.  
  732. // Compare the RecordID fields inorder delete the correct record
  733. SHORT FindFileSec(INT *hf, DATAFILE *FileD, CHAR *RecId)
  734. {
  735.   CHAR str[1], currRec[9];
  736.   SHORT  rc=0, line=0, i=0, len=0, tmp_len;
  737.   LONG pos;
  738.  
  739.   /* know the location before the user's ID */
  740.   tmp_len=len;
  741.   pos = tell(*hf);
  742.   /* find User Id */
  743.   len = GetRecID(hf, currRec, len);
  744.   if (len == -1)
  745.     return  -1;
  746.   if (strcmp(currRec, RecId) == 0) {
  747.     rc = DelFile(hf, tmp_len, pos, FileD);
  748.     if (rc)
  749.       return 1;
  750.     return 0;
  751.   }
  752.  
  753.   /* find Next Record Id line */
  754.   while (!eof(*hf)) {
  755.     while (!eof(*hf) && (line < 15) && (i < 101)) {
  756.       rc = read(*hf, str, 1);
  757.       if (rc == -1)
  758.         return rc;
  759.       i++;
  760.       len++;
  761.       if (str[0] == '\n') {
  762.         line++;
  763.         i=0;
  764.       }
  765.     }
  766.     if (i >= 101)
  767.       return 1;
  768.     if (!eof(*hf)) {
  769.       /* know the location before the RecordID */
  770.       tmp_len=len;
  771.       pos = tell(*hf);
  772.       /* find Record Id */
  773.       len = GetRecID(hf, currRec, len);
  774.       if (len == -1)
  775.         return  -1;
  776.       if (strcmp(currRec, RecId) == 0) {
  777.         rc = DelFile(hf, tmp_len, pos, FileD);
  778.         if (rc)
  779.           return 1;
  780.         return 0;
  781.       }
  782.       line=0;
  783.       i=0;
  784.     }
  785.     else  /* entry was not found */
  786.       return 1;
  787.   }
  788.   return 1; /* entry was not found */
  789. }
  790.  
  791. // actually delete a section of the .dat file inorder to remove a record
  792. SHORT DelFile(INT *hf, USHORT len, LONG old_pos, DATAFILE *FileD)
  793. {
  794.    CHAR  *Data;
  795.    SHORT rc=0, i=0, line=0;
  796.    LONG  pos=0;
  797.  
  798.   /* find Next User Id line */
  799.   while ((FileD->TotLen > len) && (line < 15) && (i < 101)) {
  800.     i++;
  801.     len++;
  802.     if (FileD->FileData[len] == '\n') {
  803.       line++;
  804.       i=0;
  805.     }
  806.   }
  807.   if (i > 101)
  808.     return 1;
  809.   /* get past the last new line */
  810.   len++;
  811.  
  812.   /* dont add any thing to the end of file just close it */
  813.   if (FileD->TotLen <= len) {
  814.     chsize(*hf, old_pos);
  815.   }
  816.   else {
  817.     /* move back to position before the user's ID */
  818.     lseek(*hf, old_pos, SEEK_SET);
  819.     Data = &(FileD->FileData[len]);
  820.     rc = write(*hf, Data, (FileD->TotLen - len));
  821.     if (rc == -1)
  822.       return 1;
  823.  
  824.     /* force and End of File */
  825.     pos = tell(*hf);
  826.     chsize(*hf, pos);
  827.   }
  828.   close(*hf);
  829.  
  830.   return 0;
  831. }
  832.