home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / FMLW_142.ZIP / FMSTRUCT.ZIP / CFGFILE.C next >
C/C++ Source or Header  |  1998-01-31  |  13KB  |  360 lines

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