home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / FMAIL120.RAR / FMSTRUCT.ZIP / cfgfile.c next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  10.8 KB  |  316 lines

  1. /*
  2.    CFGFILE.C
  3.  
  4.    Config file interface routines for FMail 1.20
  5.    Copyright (C) 1996 Folkert J. Wijnstra. All rights reserved.
  6.  
  7.    All information in this document is subject to change at any time
  8.    without prior notice!
  9. */
  10.  
  11.  
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <fcntl.h>
  15. #include <sys\stat.h>
  16. #include <io.h>
  17. #include <time.h>
  18.  
  19. #include "fmstruct.h"
  20. #include "cfgfile.h"
  21. #include "internal.h" /* not necessary for 3rd party programs */
  22.  
  23.  
  24. /* set to non-zero value if automatic conversion is desired */
  25. u16  allowConversion = 0;
  26.  
  27.  
  28. typedef struct
  29. {
  30.    const char     *fileName;
  31.    const u16      recordSize;
  32.    fhandle        handle;
  33.    char           *recBuf;
  34.    char           *revString;
  35.    u16            revNumber;
  36.    const u16      dataType;
  37.    const u16      init;
  38.    u16            status;
  39.    headerType     header;
  40. } configFileInfoType;
  41.  
  42.  
  43. static configFileInfoType fileData[MAX_CFG_FILES] =
  44.    {
  45.     /* CFG_GENERAL */
  46.     {       "FMAIL.CFG", sizeof(configType),    -1, NULL,
  47.                 "FMail Configuration File rev. 1.1\x1a",
  48.                  0x0110, DATATYPE_CF, 'CF', 0 },
  49.     /* CFG_NODES */
  50.     {       "FMAIL.NOD", sizeof(nodeInfoType), -1, NULL,
  51.                 "FMail Node File rev. 1.1\x1a",
  52.                  0x0110, DATATYPE_NO, 'NO', 0 },
  53.     /* CFG_ECHOAREAS */
  54.     {       "FMAIL.AR",  sizeof(rawEchoType),  -1, NULL,
  55.                 "FMail Area File rev. 1.1\x1a",
  56.                  0x0110, DATATYPE_AE, 'AE', 0 },
  57.     /* CFG_AREADEF */
  58.     {       "FMAIL.ARD", sizeof(rawEchoType),  -1, NULL,
  59.                 "FMail Area File rev. 1.1\x1a",
  60.                  0x0110, DATATYPE_AD, 'AD', 0 } };
  61.  
  62.  
  63. static configFileInfoType cfiArr[MAX_CFG_FILES];
  64.  
  65. extern char configPath[128]; /* Path to directory with FMail config files */
  66.  
  67.  
  68.  
  69. s16 openConfig(u16 fileType, headerType **header, void **buf)
  70. {
  71.    pathType areaInfoPath, tempPath;
  72.    fhandle  temphandle;
  73.    uchar    *helpPtr;
  74.    u16        count;
  75.    u16      orgRecSize;
  76.    u16      converted = 0;
  77.  
  78.    if (fileType >= MAX_CFG_FILES) return 0;
  79.  
  80. restart:
  81.    strcpy(areaInfoPath, configPath);
  82.    strcat(areaInfoPath, fileData[fileType].fileName);
  83.  
  84.    memset(&cfiArr[fileType].header, 0, sizeof(headerType));
  85.    cfiArr[fileType].status = 0;
  86.  
  87.    if ((cfiArr[fileType].handle = open(areaInfoPath, O_BINARY|O_RDWR|O_CREAT|O_DENYALL, S_IREAD|S_IWRITE)) == -1)
  88.    {  return 0;
  89.    }
  90.    if (filelength(cfiArr[fileType].handle) == 0)
  91.    {
  92.       strcpy(cfiArr[fileType].header.versionString, fileData[fileType].revString);
  93.       cfiArr[fileType].header.revNumber    = fileData[fileType].revNumber;
  94.       cfiArr[fileType].header.headerSize   = sizeof(headerType);
  95.       cfiArr[fileType].header.recordSize   = fileData[fileType].recordSize;
  96.       cfiArr[fileType].header.dataType     = fileData[fileType].dataType;
  97.       cfiArr[fileType].header.totalRecords = 0;
  98.       cfiArr[fileType].header.lastModified = time(&cfiArr[fileType].header.creationDate);
  99.  
  100.       write(cfiArr[fileType].handle, &cfiArr[fileType].header, sizeof(headerType));
  101.    }
  102.    else
  103.    {
  104.       read(cfiArr[fileType].handle, &cfiArr[fileType].header, sizeof(headerType));
  105.  
  106.       if (memcmp(cfiArr[fileType].header.versionString, "FMail", 5) ||
  107.           (cfiArr[fileType].header.headerSize < sizeof(headerType)) ||
  108.           ((!allowConversion || converted) && cfiArr[fileType].header.recordSize < fileData[fileType].recordSize) ||
  109.       (cfiArr[fileType].header.dataType != fileData[fileType].dataType))
  110.       {
  111. error:   close(cfiArr[fileType].handle);
  112.      cfiArr[fileType].handle = -1;
  113.      *header = NULL;
  114.      *buf = NULL;
  115.      return 0;
  116.       }
  117.       if (cfiArr[fileType].header.recordSize < fileData[fileType].recordSize)
  118.       {
  119.          /* convert old record format */
  120.          strcpy(tempPath, areaInfoPath);
  121.          if ( (helpPtr = strrchr(tempPath, '.')) == NULL )
  122.             goto error;
  123.          strcpy(helpPtr+1, "$$$");
  124.          if ((cfiArr[fileType].recBuf = malloc(fileData[fileType].recordSize)) == NULL)
  125.             goto error;
  126.          if ((temphandle = open(tempPath, O_BINARY|O_RDWR|O_CREAT|O_DENYALL, S_IREAD|S_IWRITE)) == -1)
  127.          {  free(cfiArr[fileType].recBuf);
  128.             goto error;
  129.          }
  130.          orgRecSize = cfiArr[fileType].header.recordSize;
  131.          strcpy(cfiArr[fileType].header.versionString, fileData[fileType].revString);
  132.          cfiArr[fileType].header.revNumber    = fileData[fileType].revNumber;
  133.          cfiArr[fileType].header.headerSize   = sizeof(headerType);
  134.          cfiArr[fileType].header.recordSize   = fileData[fileType].recordSize;
  135.          cfiArr[fileType].header.dataType     = fileData[fileType].dataType;
  136.          time(&cfiArr[fileType].header.lastModified);
  137.          write(temphandle, &cfiArr[fileType].header, sizeof(headerType));
  138.          for ( count = 0; count < cfiArr[fileType].header.totalRecords; count++ )
  139.          {  memset(cfiArr[fileType].recBuf, 0, fileData[fileType].recordSize);
  140.             if ( read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, orgRecSize) != orgRecSize )
  141.             {  free(cfiArr[fileType].recBuf);
  142.                close(temphandle);
  143.                unlink(tempPath);
  144.                goto error;
  145.             }
  146.             if (write(temphandle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) !=
  147.                                                            cfiArr[fileType].header.recordSize)
  148.             {  free(cfiArr[fileType].recBuf);
  149.                close(temphandle);
  150.                unlink(tempPath);
  151.                goto error;
  152.             }
  153.          }
  154.          converted = 1;
  155.          free(cfiArr[fileType].recBuf);
  156.          close(temphandle);
  157.          close(cfiArr[fileType].handle);
  158.          unlink(areaInfoPath);
  159.          rename(tempPath, areaInfoPath);
  160.      cfiArr[fileType].handle = -1;
  161.      *header = NULL;
  162.          *buf = NULL;
  163.          goto restart;
  164.       }
  165.    }
  166.    if ((cfiArr[fileType].recBuf = malloc(cfiArr[fileType].header.recordSize)) == NULL)
  167.       goto error;
  168.    *header = &cfiArr[fileType].header;
  169.    *buf    = cfiArr[fileType].recBuf;
  170.    return 1;
  171. }
  172.  
  173.  
  174. s16 getRec(u16 fileType, s16 index)
  175. {
  176.    if (cfiArr[fileType].handle == -1) return 0;
  177.  
  178.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  179.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  180.    {  return 0;
  181.    }
  182.    if (read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  183.    {  return 0;
  184.    }
  185.    return 1;
  186. }
  187.  
  188.  
  189. s16 putRec(u16 fileType, s16 index)
  190. {
  191.    if (cfiArr[fileType].handle == -1) return 0;
  192.  
  193.    *(u16*)cfiArr[fileType].recBuf = fileData[fileType].init;
  194.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  195.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  196.    {  return 0;
  197.    }
  198.    if (write (cfiArr[fileType].handle, cfiArr[fileType].recBuf,
  199.           cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  200.    {  return 0;
  201.    }
  202.    cfiArr[fileType].status = 1;
  203.    return 1;
  204. }
  205.  
  206.  
  207. s16 insRec(u16 fileType, s16 index)
  208. {
  209.    s16  count;
  210.    void *tempBuf;
  211.  
  212.    if (cfiArr[fileType].handle == -1) return 0;
  213.  
  214.    *(u16*)cfiArr[fileType].recBuf = fileData[fileType].init;
  215.  
  216.    if ((tempBuf = malloc(cfiArr[fileType].header.recordSize)) == NULL) return 0;
  217.    count = cfiArr[fileType].header.totalRecords;
  218.  
  219.    while (--count >= index)
  220.    {  if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  221.                 cfiArr[fileType].header.recordSize*(s32)count, SEEK_SET) == -1)
  222.       {  free(tempBuf);
  223.      return 0;
  224.       }
  225.       if (read(cfiArr[fileType].handle, tempBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  226.       {  free(tempBuf);
  227.      return 0;
  228.       }
  229.       if (write(cfiArr[fileType].handle, tempBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  230.       {  free(tempBuf);
  231.      return 0;
  232.       }
  233.    }
  234.    free(tempBuf);
  235.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  236.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  237.    {  return 0;
  238.    }
  239.    if (write(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  240.    {  return 0;
  241.    }
  242.    cfiArr[fileType].header.totalRecords++;
  243.    if (lseek(cfiArr[fileType].handle, 0, SEEK_SET) == -1)
  244.    {  return 0;
  245.    }
  246.    time(&cfiArr[fileType].header.lastModified);
  247.    if (write(cfiArr[fileType].handle, &cfiArr[fileType].header, cfiArr[fileType].header.headerSize) != cfiArr[fileType].header.headerSize)
  248.    {  return 0;
  249.    }
  250.    cfiArr[fileType].status = 1;
  251.    return 1;
  252. }
  253.  
  254.  
  255. s16 delRec(u16 fileType, s16 index)
  256. {
  257.    if (cfiArr[fileType].handle == -1) return 0;
  258.    while (++index < cfiArr[fileType].header.totalRecords)
  259.    {  if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  260.                 cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  261.       {  return 0;
  262.       }
  263.       if (read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  264.       {  return 0;
  265.       }
  266.       if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  267.                 cfiArr[fileType].header.recordSize*(s32)(index-1), SEEK_SET) == -1)
  268.       {  return 0;
  269.       }
  270.       if (write(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  271.       {  return 0;
  272.       }
  273.    }
  274.    chsize(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  275.           cfiArr[fileType].header.recordSize*(s32)--cfiArr[fileType].header.totalRecords);
  276.  
  277.    if (lseek(cfiArr[fileType].handle, 0, SEEK_SET) == -1)
  278.    {  return 0;
  279.    }
  280.    time(&cfiArr[fileType].header.lastModified);
  281.    write(cfiArr[fileType].handle, &cfiArr[fileType].header, cfiArr[fileType].header.headerSize);
  282.  
  283.    cfiArr[fileType].status = 1;
  284.    return 1;
  285. }
  286.  
  287.  
  288. s16 chgNumRec(u16 fileType, s16 number)
  289. {
  290.     cfiArr[fileType].header.totalRecords = number;
  291.     cfiArr[fileType].status = 1;
  292.     return 1;
  293. }
  294.  
  295.  
  296. s16 closeConfig(u16 fileType)
  297. {
  298.    if (cfiArr[fileType].handle == -1) return 0;
  299.  
  300.    if ((cfiArr[fileType].status == 1) &&
  301.        (lseek(cfiArr[fileType].handle, 0, SEEK_SET) != -1))
  302.    {
  303.       time(&cfiArr[fileType].header.lastModified);
  304.       write(cfiArr[fileType].handle, &cfiArr[fileType].header, cfiArr[fileType].header.headerSize);
  305.       chsize(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  306.                       cfiArr[fileType].header.recordSize*
  307.                                       (s32)cfiArr[fileType].header.totalRecords);
  308.    }
  309.    close(cfiArr[fileType].handle);
  310.    cfiArr[fileType].handle = -1;
  311.    free(cfiArr[fileType].recBuf);
  312.    cfiArr[fileType].recBuf = NULL;
  313.  
  314.    return 1;
  315. }
  316.