home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / FILEDATA.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  33KB  |  1,204 lines

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "lora_api.h"
  21.  
  22. TFileData::TFileData (void)
  23. {
  24.    fdDat = fdIdx = -1;
  25.    strcpy (DataFile, "file.dat");
  26.    strcpy (IdxFile, "file.idx");
  27. }
  28.  
  29. TFileData::TFileData (PSZ pszDataPath)
  30. {
  31.    strcpy (DataFile, pszDataPath);
  32.    strcpy (IdxFile, DataFile);
  33.  
  34.    fdDat = fdIdx = -1;
  35.    strcat (DataFile, "file.dat");
  36.    strcat (IdxFile, "file.idx");
  37.  
  38.    AdjustPath (strlwr (DataFile));
  39.    AdjustPath (strlwr (IdxFile));
  40. }
  41.  
  42. TFileData::~TFileData (void)
  43. {
  44.    if (fdDat != -1)
  45.       close (fdDat);
  46.    if (fdIdx != -1)
  47.       close (fdIdx);
  48. }
  49.  
  50. USHORT TFileData::Add (VOID)
  51. {
  52.    USHORT RetVal = FALSE, DoClose = FALSE;
  53.    FILES *File;
  54.    INDEX Idx;
  55.  
  56.    if (fdIdx == -1) {
  57.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  58.       DoClose = TRUE;
  59.    }
  60.    if (fdDat == -1) {
  61.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  62.       DoClose = TRUE;
  63.    }
  64.  
  65.    if (fdDat != -1 && fdIdx != -1) {
  66.       lseek (fdDat, 0L, SEEK_END);
  67.       lseek (fdIdx, 0L, SEEK_END);
  68.  
  69.       if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  70.          memset (File, 0, sizeof (FILES));
  71.          File->Size = sizeof (FILES);
  72.          Class2Struct (File);
  73.  
  74.          memset (&Idx, 0, sizeof (Idx));
  75.          strcpy (Idx.Key, Key);
  76.          Idx.Level = Level;
  77.          Idx.AccessFlags = AccessFlags;
  78.          Idx.DenyFlags = DenyFlags;
  79.          Idx.Position = tell (fdDat);
  80.  
  81.          write (fdDat, File, sizeof (FILES));
  82.          write (fdIdx, &Idx, sizeof (Idx));
  83.          RetVal = TRUE;
  84.  
  85.          free (File);
  86.       }
  87.    }
  88.  
  89.    if (DoClose == TRUE) {
  90.       if (fdDat != -1) {
  91.          close (fdDat);
  92.          fdDat = -1;
  93.       }
  94.       if (fdIdx != -1) {
  95.          close (fdIdx);
  96.          fdIdx = -1;
  97.       }
  98.    }
  99.  
  100.    return (RetVal);
  101. }
  102.  
  103. VOID TFileData::Class2Struct (FILES *File)
  104. {
  105.    strcpy (File->Display, Display);
  106.    strcpy (File->Key, Key);
  107.    File->Level = Level;
  108.    File->AccessFlags = AccessFlags;
  109.    File->DenyFlags = DenyFlags;
  110.    File->UploadLevel = UploadLevel;
  111.    File->UploadFlags = UploadFlags;
  112.    File->UploadDenyFlags = UploadDenyFlags;
  113.    File->DownloadLevel = DownloadLevel;
  114.    File->DownloadFlags = DownloadFlags;
  115.    File->DownloadDenyFlags = DownloadDenyFlags;
  116.    File->Age = Age;
  117.    strcpy (File->Download, Download);
  118.    strcpy (File->Upload, Upload);
  119.    File->CdRom = CdRom;
  120.    File->FreeDownload = FreeDownload;
  121.    File->ShowGlobal = ShowGlobal;
  122.    strcpy (File->MenuName, MenuName);
  123.    strcpy (File->Moderator, Moderator);
  124.    File->Cost = Cost;
  125.    File->ActiveFiles = ActiveFiles;
  126.    File->UnapprovedFiles = UnapprovedFiles;
  127.    strcpy (File->EchoTag, EchoTag);
  128.    File->UseFilesBBS = UseFilesBBS;
  129.    File->DlCost = DlCost;
  130.    strcpy (File->FileList, FileList);
  131. }
  132.  
  133. VOID TFileData::Delete (VOID)
  134. {
  135.    int fdNew;
  136.    ULONG Position;
  137.    FILES *File;
  138.    INDEX Idx;
  139.  
  140.    if (fdIdx == -1)
  141.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  142.    if (fdDat == -1)
  143.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  144.  
  145.    fdNew = sopen ("Temp2.Dat", O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  146.  
  147.    if (fdDat != -1 && fdIdx != -1 && fdNew != -1) {
  148.       lseek (fdDat, 0L, SEEK_SET);
  149.  
  150.       if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  151.          while (read (fdDat, File, sizeof (FILES)) == sizeof (FILES)) {
  152.             if (strcmp (LastKey, File->Key))
  153.                write (fdNew, File, sizeof (FILES));
  154.          }
  155.  
  156.          if ((Position = tell (fdIdx)) > 0L)
  157.             Position -= sizeof (Idx);
  158.  
  159.          close (fdDat);
  160.          close (fdIdx);
  161.          fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  162.          fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  163.  
  164.          if (fdDat != -1 && fdIdx != -1) {
  165.             lseek (fdNew, 0L, SEEK_SET);
  166.  
  167.             while (read (fdNew, File, sizeof (FILES)) == sizeof (FILES)) {
  168.                memset (&Idx, 0, sizeof (Idx));
  169.                strcpy (Idx.Key, File->Key);
  170.                Idx.Level = File->Level;
  171.                Idx.AccessFlags = File->AccessFlags;
  172.                Idx.DenyFlags = File->DenyFlags;
  173.                Idx.Position = tell (fdDat);
  174.  
  175.                write (fdIdx, &Idx, sizeof (Idx));
  176.                write (fdDat, File, sizeof (FILES));
  177.             }
  178.  
  179.             lseek (fdIdx, Position, SEEK_SET);
  180.             if (Next () == FALSE) {
  181.                if (Previous () == FALSE)
  182.                   New ();
  183.             }
  184.          }
  185.  
  186.          free (File);
  187.       }
  188.    }
  189.  
  190.    if (fdNew != -1) {
  191.       close (fdNew);
  192.       unlink ("Temp2.Dat");
  193.    }
  194. }
  195.  
  196. USHORT TFileData::First (VOID)
  197. {
  198.    USHORT RetVal = FALSE;
  199.  
  200.    if (fdIdx == -1)
  201.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  202.    if (fdDat == -1)
  203.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  204.  
  205.    if (fdDat != -1 && fdIdx != -1) {
  206.       lseek (fdIdx, 0L, SEEK_SET);
  207.       lseek (fdDat, 0L, SEEK_SET);
  208.       RetVal = Next ();
  209.    }
  210.  
  211.    return (RetVal);
  212. }
  213.  
  214. USHORT TFileData::Insert (class TFileData *Data)
  215. {
  216.    PSZ p;
  217.  
  218.    strcpy (Display, Data->Display);
  219.    strcpy (Key, Data->Key);
  220.    Level = Data->Level;
  221.    AccessFlags = Data->AccessFlags;
  222.    DenyFlags = Data->DenyFlags;
  223.    UploadLevel = Data->UploadLevel;
  224.    UploadFlags = Data->UploadFlags;
  225.    UploadDenyFlags = Data->UploadDenyFlags;
  226.    DownloadLevel = Data->DownloadLevel;
  227.    DownloadFlags = Data->DownloadFlags;
  228.    DownloadDenyFlags = Data->DownloadDenyFlags;
  229.    Age = Data->Age;
  230.  
  231.    strcpy (Download, Data->Download);
  232.    if (Download[strlen (Download) - 1] != '\\' && Download[strlen (Download) - 1] != '/')
  233.       strcat (Download, "\\");
  234. #if defined(__LINUX__)
  235.    while ((p = strchr (Download, '\\')) != NULL)
  236.       *p = '/';
  237. #else
  238.    while ((p = strchr (Download, '/')) != NULL)
  239.       *p = '\\';
  240. #endif
  241.  
  242.    strcpy (Upload, Data->Upload);
  243.    if (Upload[strlen (Upload) - 1] != '\\' && Upload[strlen (Upload) - 1] != '/')
  244.       strcat (Upload, "\\");
  245. #if defined(__LINUX__)
  246.    while ((p = strchr (Upload, '\\')) != NULL)
  247.       *p = '/';
  248. #else
  249.    while ((p = strchr (Upload, '/')) != NULL)
  250.       *p = '\\';
  251. #endif
  252.  
  253.    CdRom = Data->CdRom;
  254.    FreeDownload = Data->FreeDownload;
  255.    ShowGlobal = Data->ShowGlobal;
  256.    strcpy (MenuName, Data->MenuName);
  257.    strcpy (Moderator, Data->Moderator);
  258.    Cost = Data->Cost;
  259.    ActiveFiles = Data->ActiveFiles;
  260.    UnapprovedFiles = Data->UnapprovedFiles;
  261.    strcpy (EchoTag, Data->EchoTag);
  262.    UseFilesBBS = Data->UseFilesBBS;
  263.    DlCost = Data->DlCost;
  264.    strcpy (FileList, Data->FileList);
  265.  
  266.    return (Insert ());
  267. }
  268.  
  269. USHORT TFileData::Insert (VOID)
  270. {
  271.    int fdNew;
  272.    USHORT retVal = FALSE;
  273.    ULONG Position;
  274.    FILES *File;
  275.    INDEX Idx;
  276.  
  277.    if (fdIdx == -1)
  278.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  279.    if (fdDat == -1)
  280.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  281.  
  282.    fdNew = sopen ("Temp2.Dat", O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  283.  
  284.    if (fdDat != -1 && fdIdx != -1 && fdNew != -1) {
  285.       lseek (fdDat, 0L, SEEK_SET);
  286.  
  287.       if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  288.          while (read (fdDat, File, sizeof (FILES)) == sizeof (FILES)) {
  289.             write (fdNew, File, sizeof (FILES));
  290.             if (!strcmp (LastKey, File->Key)) {
  291.                memset (File, 0, sizeof (FILES));
  292.                File->Size = sizeof (FILES);
  293.                Class2Struct (File);
  294.                write (fdNew, File, sizeof (FILES));
  295.             }
  296.          }
  297.  
  298.          lseek (fdDat, 0L, SEEK_SET);
  299.          lseek (fdNew, 0L, SEEK_SET);
  300.  
  301.          Position = tell (fdIdx);
  302.          lseek (fdIdx, 0L, SEEK_SET);
  303.  
  304.          while (read (fdNew, File, sizeof (FILES)) == sizeof (FILES)) {
  305.             memset (&Idx, 0, sizeof (Idx));
  306.             strcpy (Idx.Key, File->Key);
  307.             Idx.Level = File->Level;
  308.             Idx.AccessFlags = File->AccessFlags;
  309.             Idx.DenyFlags = File->DenyFlags;
  310.             Idx.Position = tell (fdDat);
  311.  
  312.             write (fdIdx, &Idx, sizeof (Idx));
  313.             write (fdDat, File, sizeof (FILES));
  314.          }
  315.  
  316.          lseek (fdIdx, Position, SEEK_SET);
  317.          Next ();
  318.  
  319.          retVal = TRUE;
  320.          free (File);
  321.       }
  322.    }
  323.  
  324.    if (fdNew != -1) {
  325.       close (fdNew);
  326.       unlink ("Temp2.Dat");
  327.    }
  328.  
  329.    return (retVal);
  330. }
  331.  
  332. USHORT TFileData::Last (VOID)
  333. {
  334.    USHORT RetVal = FALSE, IsValid = FALSE;
  335.    FILES *File;
  336.    INDEX Idx;
  337.  
  338.    if (fdDat != -1 && fdIdx != -1) {
  339.       lseek (fdIdx, 0L, SEEK_END);
  340.       if (tell (fdIdx) >= sizeof (INDEX)) {
  341.          lseek (fdIdx, tell (fdIdx) - sizeof (INDEX), SEEK_SET);
  342.          read (fdIdx, &Idx, sizeof (Idx));
  343.          if (!(Idx.Flags & IDX_DELETED)) {
  344.             lseek (fdDat, Idx.Position, SEEK_SET);
  345.             if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  346.                if (read (fdDat, File, sizeof (FILES)) == sizeof (FILES)) {
  347.                   RetVal = TRUE;
  348.                   New ();
  349.                   Struct2Class (File);
  350.                   IsValid = TRUE;
  351.                }
  352.  
  353.                free (File);
  354.             }
  355.          }
  356.       }
  357.       while (IsValid == FALSE && tell (fdIdx) >= sizeof (INDEX) * 2) {
  358.          lseek (fdIdx, tell (fdIdx) - sizeof (INDEX) * 2, SEEK_SET);
  359.          read (fdIdx, &Idx, sizeof (Idx));
  360.          if (!(Idx.Flags & IDX_DELETED)) {
  361.             lseek (fdDat, Idx.Position, SEEK_SET);
  362.             if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  363.                if (read (fdDat, File, sizeof (FILES)) == sizeof (FILES)) {
  364.                   RetVal = TRUE;
  365.                   New ();
  366.                   Struct2Class (File);
  367.                   IsValid = TRUE;
  368.                }
  369.  
  370.                free (File);
  371.             }
  372.          }
  373.       }
  374.    }
  375.  
  376.    return (RetVal);
  377. }
  378.  
  379. VOID TFileData::New (VOID)
  380. {
  381.    memset (Display, 0, sizeof (Display));
  382.    memset (Key, 0, sizeof (Key));
  383.    Level = 0;
  384.    AccessFlags = DenyFlags = 0L;
  385.    UploadLevel = 0;
  386.    UploadFlags = UploadDenyFlags = 0L;
  387.    DownloadLevel = 0;
  388.    DownloadFlags = DownloadDenyFlags = 0L;
  389.    Age = 0;
  390.    memset (Download, 0, sizeof (Download));
  391.    memset (Upload, 0, sizeof (Upload));
  392.    CdRom = FALSE;
  393.    FreeDownload = FALSE;
  394.    ShowGlobal = TRUE;
  395.    memset (MenuName, 0, sizeof (MenuName));
  396.    memset (Moderator, 0, sizeof (Moderator));
  397.    Cost = 0L;
  398.    ActiveFiles = UnapprovedFiles = 0L;
  399.    memset (EchoTag, 0, sizeof (EchoTag));
  400. }
  401.  
  402. USHORT TFileData::Next (VOID)
  403. {
  404.    USHORT RetVal = FALSE, IsValid = FALSE;
  405.    FILES *File;
  406.    INDEX Idx;
  407.  
  408.    if (fdDat != -1 && fdIdx != -1) {
  409.       while (IsValid == FALSE && read (fdIdx, &Idx, sizeof (Idx)) == sizeof (Idx)) {
  410.          if (!(Idx.Flags & IDX_DELETED)) {
  411.             if (tell (fdDat) != Idx.Position)
  412.                lseek (fdDat, Idx.Position, SEEK_SET);
  413.             if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  414.                if (read (fdDat, File, sizeof (FILES)) == sizeof (FILES)) {
  415.                   RetVal = TRUE;
  416.                   New ();
  417.                   Struct2Class (File);
  418.                   IsValid = TRUE;
  419.                }
  420.  
  421.                free (File);
  422.             }
  423.          }
  424.       }
  425.    }
  426.  
  427.    return (RetVal);
  428. }
  429.  
  430. VOID TFileData::Pack (VOID)
  431. {
  432.    int fdNewIdx, fdNewDat;
  433.    INDEX Idx;
  434.    FILES *File;
  435.  
  436.    if (fdIdx == -1)
  437.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  438.    if (fdDat == -1)
  439.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  440.  
  441.    if (fdIdx != -1 && fdDat != -1) {
  442.       lseek (fdIdx, 0L, SEEK_SET);
  443.  
  444.       if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  445.          fdNewIdx = open ("File-New.Idx", O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  446.          fdNewDat = open ("File-New.Dat", O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  447.  
  448.          if (fdNewIdx != -1 && fdNewDat != -1) {
  449.             while (read (fdIdx, &Idx, sizeof (Idx)) == sizeof (Idx)) {
  450.                if (!(Idx.Flags & IDX_DELETED)) {
  451.                   lseek (fdDat, Idx.Position, SEEK_SET);
  452.                   read (fdDat, File, sizeof (FILES));
  453.                   Idx.Position = tell (fdNewDat);
  454.                   write (fdNewDat, File, sizeof (FILES));
  455.                   write (fdNewIdx, &Idx, sizeof (Idx));
  456.                }
  457.             }
  458.  
  459.             close (fdNewIdx);
  460.             close (fdNewDat);
  461.  
  462.             unlink (DataFile);
  463.             rename ("File-New.Dat", DataFile);
  464.             unlink (IdxFile);
  465.             rename ("File-New.Idx", IdxFile);
  466.          }
  467.  
  468.          unlink ("File-New.Dat");
  469.          unlink ("File-New.Idx");
  470.          free (File);
  471.       }
  472.  
  473.       close (fdIdx);
  474.       close (fdDat);
  475.       fdIdx = fdDat = -1;
  476.    }
  477. }
  478.  
  479. USHORT TFileData::Previous (VOID)
  480. {
  481.    USHORT RetVal = FALSE, IsValid = FALSE;
  482.    FILES *File;
  483.    INDEX Idx;
  484.  
  485.    if (fdDat != -1 && fdIdx != -1) {
  486.       while (IsValid == FALSE && tell (fdIdx) >= sizeof (INDEX) * 2) {
  487.          lseek (fdIdx, tell (fdIdx) - sizeof (INDEX) * 2, SEEK_SET);
  488.          read (fdIdx, &Idx, sizeof (Idx));
  489.          if (!(Idx.Flags & IDX_DELETED)) {
  490.             lseek (fdDat, Idx.Position, SEEK_SET);
  491.             if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  492.                if (read (fdDat, File, sizeof (FILES)) == sizeof (FILES)) {
  493.                   RetVal = TRUE;
  494.                   New ();
  495.                   Struct2Class (File);
  496.                   IsValid = TRUE;
  497.                }
  498.  
  499.                free (File);
  500.             }
  501.          }
  502.       }
  503.    }
  504.  
  505.    return (RetVal);
  506. }
  507.  
  508. USHORT TFileData::Read (PSZ pszName, USHORT fCloseFile)
  509. {
  510.    USHORT RetVal = FALSE;
  511.    FILES *File;
  512.    INDEX Idx;
  513.  
  514.    New ();
  515.  
  516.    if (fdIdx == -1)
  517.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  518.    if (fdDat == -1)
  519.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  520.  
  521.    if (fdDat != -1 && fdIdx != -1) {
  522.       lseek (fdIdx, 0L, SEEK_SET);
  523.       lseek (fdDat, 0L, SEEK_SET);
  524.  
  525.       while (RetVal == FALSE && read (fdIdx, &Idx, sizeof (Idx)) == sizeof (Idx)) {
  526.          if (!(Idx.Flags & IDX_DELETED) && !stricmp (pszName, Idx.Key)) {
  527.             if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  528.                lseek (fdDat, Idx.Position, SEEK_SET);
  529.                read (fdDat, File, sizeof (FILES));
  530.  
  531.                RetVal = TRUE;
  532.                Struct2Class (File);
  533.  
  534.                free (File);
  535.             }
  536.          }
  537.       }
  538.    }
  539.  
  540.    if (fCloseFile == TRUE) {
  541.       if (fdDat != -1) {
  542.          close (fdDat);
  543.          fdDat = -1;
  544.       }
  545.       if (fdIdx != -1) {
  546.          close (fdIdx);
  547.          fdIdx = -1;
  548.       }
  549.    }
  550.  
  551.    return (RetVal);
  552. }
  553.  
  554. USHORT TFileData::ReadEcho (PSZ pszEchoTag)
  555. {
  556.    FILE *fp;
  557.    USHORT retVal = FALSE;
  558.    FILES *File;
  559.  
  560.    New ();
  561.  
  562.    fp = fopen (DataFile, "r+b");
  563.    File = (FILES *)malloc (sizeof (FILES));
  564.  
  565.    if (fp != NULL && File != NULL) {
  566.       setvbuf (fp, NULL, _IOFBF, 2048);
  567.       while (fread (File, sizeof (FILES), 1, fp) == 1) {
  568.          if (!stricmp (pszEchoTag, File->EchoTag)) {
  569.             retVal = TRUE;
  570.             Struct2Class (File);
  571.             break;
  572.          }
  573.       }
  574.    }
  575.  
  576.    if (File != NULL)
  577.       free (File);
  578.    if (fp != NULL)
  579.       fclose (fp);
  580.  
  581.    return (retVal);
  582. }
  583.  
  584. USHORT TFileData::ReRead (VOID)
  585. {
  586.    USHORT RetVal = FALSE;
  587.  
  588.    if (fdDat != -1 && fdIdx != -1) {
  589.       if (tell (fdIdx) >= sizeof (INDEX)) {
  590.          lseek (fdIdx, tell (fdIdx) - sizeof (INDEX), SEEK_SET);
  591.          RetVal = Next ();
  592.       }
  593.    }
  594.  
  595.    return (RetVal);
  596. }
  597.  
  598. VOID TFileData::Struct2Class (FILES *File)
  599. {
  600.    PSZ p;
  601.  
  602.    strcpy (Display, File->Display);
  603.    strcpy (Key, File->Key);
  604.    Level = File->Level;
  605.    AccessFlags = File->AccessFlags;
  606.    DenyFlags = File->DenyFlags;
  607.    UploadLevel = File->UploadLevel;
  608.    UploadFlags = File->UploadFlags;
  609.    UploadDenyFlags = File->UploadDenyFlags;
  610.    DownloadLevel = File->DownloadLevel;
  611.    DownloadFlags = File->DownloadFlags;
  612.    DownloadDenyFlags = File->DownloadDenyFlags;
  613.    Age = File->Age;
  614.  
  615.    strcpy (Download, File->Download);
  616.    if (Download[strlen (Download) - 1] != '\\' && Download[strlen (Download) - 1] != '/')
  617.       strcat (Download, "\\");
  618. #if defined(__LINUX__)
  619.    while ((p = strchr (Download, '\\')) != NULL)
  620.       *p = '/';
  621. #else
  622.    while ((p = strchr (Download, '/')) != NULL)
  623.       *p = '\\';
  624. #endif
  625.  
  626.    strcpy (Upload, File->Upload);
  627.    if (Upload[strlen (Upload) - 1] != '\\' && Upload[strlen (Upload) - 1] != '/')
  628.       strcat (Upload, "\\");
  629. #if defined(__LINUX__)
  630.    while ((p = strchr (Upload, '\\')) != NULL)
  631.       *p = '/';
  632. #else
  633.    while ((p = strchr (Upload, '/')) != NULL)
  634.       *p = '\\';
  635. #endif
  636.  
  637.    CdRom = File->CdRom;
  638.    FreeDownload = File->FreeDownload;
  639.    ShowGlobal = File->ShowGlobal;
  640.    strcpy (MenuName, File->MenuName);
  641.    strcpy (Moderator, File->Moderator);
  642.    Cost = File->Cost;
  643.    ActiveFiles = File->ActiveFiles;
  644.    UnapprovedFiles = File->UnapprovedFiles;
  645.    strcpy (EchoTag, File->EchoTag);
  646.    UseFilesBBS = File->UseFilesBBS;
  647.    DlCost = File->DlCost;
  648.    strcpy (FileList, File->FileList);
  649.  
  650.    strcpy (LastKey, File->Key);
  651. }
  652.  
  653. USHORT TFileData::Update (PSZ pszNewKey)
  654. {
  655.    USHORT RetVal = FALSE, DoClose = FALSE;
  656.    FILES *File;
  657.    INDEX Idx;
  658.  
  659.    if (fdIdx == -1) {
  660.       fdIdx = sopen (IdxFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  661.       DoClose = TRUE;
  662.    }
  663.    if (fdDat == -1) {
  664.       fdDat = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  665.       DoClose = TRUE;
  666.    }
  667.  
  668.    if (fdDat != -1 && fdIdx != -1) {
  669.       if (DoClose == TRUE) {
  670.          lseek (fdIdx, 0L, SEEK_SET);
  671.          while (read (fdIdx, &Idx, sizeof (Idx)) == sizeof (Idx)) {
  672.             if (!(Idx.Flags & IDX_DELETED) && !stricmp (Key, Idx.Key)) {
  673.                RetVal = TRUE;
  674.                break;
  675.             }
  676.          }
  677.       }
  678.       else {
  679.          lseek (fdIdx, tell (fdIdx) - sizeof (INDEX), SEEK_SET);
  680.          read (fdIdx, &Idx, sizeof (Idx));
  681.  
  682.          if (strcmp (Idx.Key, Key)) {
  683.             lseek (fdIdx, 0L, SEEK_SET);
  684.             while (read (fdIdx, &Idx, sizeof (Idx)) == sizeof (Idx)) {
  685.                if (!(Idx.Flags & IDX_DELETED) && !stricmp (Key, Idx.Key)) {
  686.                   RetVal = TRUE;
  687.                   break;
  688.                }
  689.             }
  690.          }
  691.          else
  692.             RetVal = TRUE;
  693.       }
  694.  
  695.       if (RetVal == TRUE && tell (fdIdx) >= sizeof (INDEX)) {
  696.          RetVal = FALSE;
  697.  
  698.          if ((File = (FILES *)malloc (sizeof (FILES))) != NULL) {
  699.             memset (File, 0, sizeof (FILES));
  700.             File->Size = sizeof (FILES);
  701.             if (pszNewKey != NULL)
  702.                strcpy (Key, pszNewKey);
  703.  
  704.             Class2Struct (File);
  705.  
  706.             strcpy (Idx.Key, Key);
  707.             lseek (fdIdx, tell (fdIdx) - sizeof (INDEX), SEEK_SET);
  708.             write (fdIdx, &Idx, sizeof (Idx));
  709.  
  710.             lseek (fdDat, Idx.Position, SEEK_SET);
  711.             write (fdDat, File, sizeof (FILES));
  712.             free (File);
  713.  
  714.             RetVal = TRUE;
  715.          }
  716.       }
  717.    }
  718.  
  719.    if (DoClose == TRUE) {
  720.       if (fdDat != -1) {
  721.          close (fdDat);
  722.          fdDat = -1;
  723.       }
  724.       if (fdIdx != -1) {
  725.          close (fdIdx);
  726.          fdIdx = -1;
  727.       }
  728.    }
  729.  
  730.    return (RetVal);
  731. }
  732.  
  733. // --------------------------------------------------------------------------
  734.  
  735. #define ECHOLINK_INDEX     32
  736.  
  737. TFilechoLink::TFilechoLink (void)
  738. {
  739.    Data.Clear ();
  740.    strcpy (DataFile, "fecholnk.dat");
  741.    Skip4D = FALSE;
  742. }
  743.  
  744. TFilechoLink::TFilechoLink (PSZ pszDataPath)
  745. {
  746.    Data.Clear ();
  747.  
  748.    strcpy (DataFile, pszDataPath);
  749.    if (DataFile[0] != '\0') {
  750. #if defined(__LINUX__)
  751.       if (DataFile[strlen (DataFile) - 1] != '/')
  752.          strcat (DataFile, "/");
  753. #else
  754.       if (DataFile[strlen (DataFile) - 1] != '\\')
  755.          strcat (DataFile, "\\");
  756. #endif
  757.    }
  758.    strcpy (DataFile, DataFile);
  759.    strcat (DataFile, "fecholnk.dat");
  760.    Skip4D = FALSE;
  761. }
  762.  
  763. TFilechoLink::~TFilechoLink (void)
  764. {
  765.    Data.Clear ();
  766. }
  767.  
  768. USHORT TFilechoLink::Add (VOID)
  769. {
  770.    USHORT Insert = FALSE;
  771.    ECHOLINK Buffer, *Current;
  772.  
  773.    memset (&Buffer, 0, sizeof (ECHOLINK));
  774.  
  775.    Buffer.Free = FALSE;
  776.    Buffer.EchoTag = EchoTag;
  777.    Buffer.Zone = Zone;
  778.    Buffer.Net = Net;
  779.    Buffer.Node = Node;
  780.    Buffer.Point = Point;
  781.    strcpy (Buffer.Domain, Domain);
  782.    Buffer.SendOnly = SendOnly;
  783.    Buffer.ReceiveOnly = ReceiveOnly;
  784.    Buffer.PersonalOnly = PersonalOnly;
  785.    Buffer.Passive = Passive;
  786.    Buffer.Skip = Skip;
  787.  
  788.    if ((Current = (ECHOLINK *)Data.First ()) != NULL) {
  789.       if (Current->Zone > Zone)
  790.          Insert = TRUE;
  791.       else if (Current->Zone == Zone && Current->Net > Net)
  792.          Insert = TRUE;
  793.       else if (Current->Zone == Zone && Current->Net == Net && Current->Node > Node)
  794.          Insert = TRUE;
  795.       else if (Current->Zone == Zone && Current->Net == Net && Current->Node == Node && Current->Point > Point)
  796.          Insert = TRUE;
  797.  
  798.       if (Insert == TRUE) {
  799.          Data.Insert (&Buffer, sizeof (ECHOLINK));
  800.          Data.Insert (Current, sizeof (ECHOLINK));
  801.          Data.First ();
  802.          Data.Remove ();
  803.          Data.First ();
  804.       }
  805.       else {
  806.          while ((Current = (ECHOLINK *)Data.Next ()) != NULL) {
  807.             if (Current->Zone > Zone)
  808.                Insert = TRUE;
  809.             else if (Current->Zone == Zone && Current->Net > Net)
  810.                Insert = TRUE;
  811.             else if (Current->Zone == Zone && Current->Net == Net && Current->Node > Node)
  812.                Insert = TRUE;
  813.             else if (Current->Zone == Zone && Current->Net == Net && Current->Node == Node && Current->Point > Point)
  814.                Insert = TRUE;
  815.  
  816.             if (Insert == TRUE) {
  817.                Data.Previous ();
  818.                Data.Insert (&Buffer, sizeof (ECHOLINK));
  819.                break;
  820.             }
  821.          }
  822.          if (Insert == FALSE) {
  823.             Data.Add (&Buffer, sizeof (ECHOLINK));
  824.             Insert = TRUE;
  825.          }
  826.       }
  827.    }
  828.    else {
  829.       if (Insert == FALSE) {
  830.          Data.Add (&Buffer, sizeof (ECHOLINK));
  831.          Insert = TRUE;
  832.       }
  833.    }
  834.  
  835.    return (Insert);
  836. }
  837.  
  838. USHORT TFilechoLink::AddString (PSZ pszString)
  839. {
  840.    USHORT RetVal = FALSE;
  841.    CHAR Temp[128], *p;
  842.    class TAddress Address;
  843.  
  844.    strcpy (Temp, pszString);
  845.    if ((p = strtok (Temp, " ")) != NULL)
  846.       do {
  847.          Skip = FALSE;
  848.          ReceiveOnly = SendOnly = PersonalOnly = FALSE;
  849.          if (Check (p) == FALSE) {
  850.             while (isdigit (*p) == 0 && *p != '.') {
  851.                if (*p == '>')
  852.                   ReceiveOnly = TRUE;
  853.                if (*p == '<')
  854.                   SendOnly = TRUE;
  855.                if (*p == '!')
  856.                   PersonalOnly = TRUE;
  857.                p++;
  858.             }
  859.             Address.Parse (p);
  860.             if (Address.Zone != 0)
  861.                Zone = Address.Zone;
  862.             if (Address.Net != 0)
  863.                Net = Address.Net;
  864.             if (Address.Node != 0)
  865.                Node = Address.Node;
  866.             Point = Address.Point;
  867.             strcpy (Domain, Address.Domain);
  868.             RetVal = Add ();
  869.          }
  870.       } while ((p = strtok (NULL, " ")) != NULL);
  871.  
  872.    return (RetVal);
  873. }
  874.  
  875. VOID TFilechoLink::Change (PSZ pszFrom, PSZ pszTo)
  876. {
  877.    int fd, i, Count, Changed;
  878.    ULONG CrcFrom, CrcTo, Position;
  879.    ECHOLINK *Buffer;
  880.  
  881.    CrcFrom = StringCrc32 (pszFrom, 0xFFFFFFFFL);
  882.    CrcTo = StringCrc32 (pszTo, 0xFFFFFFFFL);
  883.  
  884.    if ((fd = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  885.       if ((Buffer = (ECHOLINK *)malloc (sizeof (ECHOLINK) * ECHOLINK_INDEX)) != NULL) {
  886.          do {
  887.             Changed = FALSE;
  888.  
  889.             Position = tell (fd);
  890.             Count = read (fd, Buffer, sizeof (ECHOLINK) * ECHOLINK_INDEX) / sizeof (ECHOLINK);
  891.             for (i = 0; i < Count; i++) {
  892.                if (Buffer[i].EchoTag == CrcFrom) {
  893.                   Buffer[i].EchoTag = CrcTo;
  894.                   Changed = TRUE;
  895.                }
  896.             }
  897.  
  898.             if (Changed == TRUE) {
  899.                lseek (fd, Position, SEEK_SET);
  900.                write (fd, Buffer, sizeof (ECHOLINK) * Count);
  901.             }
  902.          } while (Count == ECHOLINK_INDEX);
  903.          free (Buffer);
  904.       }
  905.  
  906.       close (fd);
  907.    }
  908. }
  909.  
  910. USHORT TFilechoLink::Check (PSZ pszAddress)
  911. {
  912.    USHORT RetVal = FALSE;
  913.    ECHOLINK *El;
  914.    class TAddress Addr;
  915.  
  916.    while (isdigit (*pszAddress) == 0 && *pszAddress != '.')
  917.       pszAddress++;
  918.    Addr.Parse (pszAddress);
  919.  
  920.    if ((El = (ECHOLINK *)Data.First ()) != NULL)
  921.       do {
  922.          if (El->Zone == Addr.Zone && El->Net == Addr.Net && El->Node == Addr.Node && El->Point == Addr.Point) {
  923.             EchoTag = El->EchoTag;
  924.             Zone = El->Zone;
  925.             Net = El->Net;
  926.             Node = El->Node;
  927.             Point = El->Point;
  928.             strcpy (Domain, El->Domain);
  929.             SendOnly = El->SendOnly;
  930.             ReceiveOnly = El->ReceiveOnly;
  931.             PersonalOnly = El->PersonalOnly;
  932.             Passive = El->Passive;
  933.             Skip = El->Skip;
  934.             if (Point == 0)
  935.                sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  936.             else
  937.                sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  938.             if (Domain[0] != '\0') {
  939.                strcat (Address, "@");
  940.                strcat (Address, Domain);
  941.             }
  942.             RetVal = TRUE;
  943.             break;
  944.          }
  945.       } while ((El = (ECHOLINK *)Data.Next ()) != NULL);
  946.  
  947.    return (RetVal);
  948. }
  949.  
  950. VOID TFilechoLink::Clear (VOID)
  951. {
  952.    Data.Clear ();
  953.    New ();
  954. }
  955.  
  956. VOID TFilechoLink::Delete (VOID)
  957. {
  958.    if (Data.Value () != NULL)
  959.       Data.Remove ();
  960. }
  961.  
  962. USHORT TFilechoLink::First (VOID)
  963. {
  964.    USHORT RetVal = FALSE;
  965.    ECHOLINK *El;
  966.  
  967.    if ((El = (ECHOLINK *)Data.First ()) != NULL) {
  968.       EchoTag = El->EchoTag;
  969.       Zone = El->Zone;
  970.       Net = El->Net;
  971.       Node = El->Node;
  972.       Point = El->Point;
  973.       strcpy (Domain, El->Domain);
  974.       SendOnly = El->SendOnly;
  975.       ReceiveOnly = El->ReceiveOnly;
  976.       PersonalOnly = El->PersonalOnly;
  977.       Passive = El->Passive;
  978.       Skip = El->Skip;
  979.       if (Point == 0)
  980.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  981.       else
  982.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  983.       if (Domain[0] != '\0') {
  984.          strcat (Address, "@");
  985.          strcat (Address, Domain);
  986.       }
  987.       if (Skip4D == TRUE && Point != 0)
  988.          ShortAddress[0] = '\0';
  989.       else
  990.          strcpy (ShortAddress, Address);
  991.       RetVal = TRUE;
  992.    }
  993.  
  994.    return (RetVal);
  995. }
  996.  
  997. VOID TFilechoLink::Load (PSZ pszEchoTag)
  998. {
  999.    int fd, i, Count;
  1000.    CHAR Temp[64];
  1001.    ULONG Crc;
  1002.    ECHOLINK *Buffer;
  1003.  
  1004.    Data.Clear ();
  1005.    strcpy (Temp, pszEchoTag);
  1006.    strupr (Temp);
  1007.    Crc = StringCrc32 (Temp, 0xFFFFFFFFL);
  1008.    EchoTag = Crc;
  1009.  
  1010.    if ((fd = sopen (DataFile, O_RDONLY|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1011.       if ((Buffer = (ECHOLINK *)malloc (sizeof (ECHOLINK) * ECHOLINK_INDEX)) != NULL) {
  1012.          do {
  1013.             Count = read (fd, Buffer, sizeof (ECHOLINK) * ECHOLINK_INDEX) / sizeof (ECHOLINK);
  1014.             for (i = 0; i < Count; i++) {
  1015.                if (Buffer[i].Free == FALSE && Buffer[i].EchoTag == Crc)
  1016.                   Data.Add (&Buffer[i], sizeof (ECHOLINK));
  1017.             }
  1018.          } while (Count == ECHOLINK_INDEX);
  1019.          free (Buffer);
  1020.       }
  1021.       close (fd);
  1022.    }
  1023.  
  1024.    First ();
  1025. }
  1026.  
  1027. VOID TFilechoLink::New (VOID)
  1028. {
  1029.    Zone = 0;
  1030.    Net = 0;
  1031.    Node = 0;
  1032.    Point = 0;
  1033.    Address[0] = Domain[0] = '\0';
  1034.    SendOnly = FALSE;
  1035.    ReceiveOnly = FALSE;
  1036.    PersonalOnly = FALSE;
  1037.    Passive = FALSE;
  1038.    Skip = FALSE;
  1039. }
  1040.  
  1041. USHORT TFilechoLink::Next (VOID)
  1042. {
  1043.    USHORT RetVal = FALSE;
  1044.    ECHOLINK *El;
  1045.  
  1046.    if ((El = (ECHOLINK *)Data.Next ()) != NULL) {
  1047.       if (Skip4D == FALSE || El->Point == 0) {
  1048.          if (Zone != El->Zone) {
  1049.             if (El->Point == 0)
  1050.                sprintf (ShortAddress, "%u:%u/%u", El->Zone, El->Net, El->Node);
  1051.             else
  1052.                sprintf (ShortAddress, "%u:%u/%u.%u", El->Zone, El->Net, El->Node, El->Point);
  1053.          }
  1054.          else if (Net != El->Net) {
  1055.             if (El->Point == 0)
  1056.                sprintf (ShortAddress, "%u/%u", El->Net, El->Node);
  1057.             else
  1058.                sprintf (ShortAddress, "%u/%u.%u", El->Net, El->Node, El->Point);
  1059.          }
  1060.          else if (Node != El->Node) {
  1061.             if (El->Point == 0)
  1062.                sprintf (ShortAddress, "%u", El->Node);
  1063.             else
  1064.                sprintf (ShortAddress, "%u.%u", El->Node, El->Point);
  1065.          }
  1066.          else
  1067.             sprintf (ShortAddress, ".%u", El->Point);
  1068.       }
  1069.       else
  1070.          ShortAddress[0] = '\0';
  1071.  
  1072.       EchoTag = El->EchoTag;
  1073.       Zone = El->Zone;
  1074.       Net = El->Net;
  1075.       Node = El->Node;
  1076.       Point = El->Point;
  1077.       strcpy (Domain, El->Domain);
  1078.       SendOnly = El->SendOnly;
  1079.       ReceiveOnly = El->ReceiveOnly;
  1080.       PersonalOnly = El->PersonalOnly;
  1081.       Passive = El->Passive;
  1082.       Skip = El->Skip;
  1083.       if (Point == 0)
  1084.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  1085.       else
  1086.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  1087.       if (Domain[0] != '\0') {
  1088.          strcat (Address, "@");
  1089.          strcat (Address, Domain);
  1090.       }
  1091.       RetVal = TRUE;
  1092.    }
  1093.  
  1094.    return (RetVal);
  1095. }
  1096.  
  1097. USHORT TFilechoLink::Previous (VOID)
  1098. {
  1099.    USHORT RetVal = FALSE;
  1100.    ECHOLINK *El;
  1101.  
  1102.    if ((El = (ECHOLINK *)Data.Previous ()) != NULL) {
  1103.       EchoTag = El->EchoTag;
  1104.       Zone = El->Zone;
  1105.       Net = El->Net;
  1106.       Node = El->Node;
  1107.       Point = El->Point;
  1108.       strcpy (Domain, El->Domain);
  1109.       SendOnly = El->SendOnly;
  1110.       ReceiveOnly = El->ReceiveOnly;
  1111.       PersonalOnly = El->PersonalOnly;
  1112.       Passive = El->Passive;
  1113.       Skip = El->Skip;
  1114.       if (Point == 0)
  1115.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  1116.       else
  1117.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  1118.       if (Domain[0] != '\0') {
  1119.          strcat (Address, "@");
  1120.          strcat (Address, Domain);
  1121.       }
  1122.       RetVal = TRUE;
  1123.    }
  1124.  
  1125.    return (RetVal);
  1126. }
  1127.  
  1128. VOID TFilechoLink::Save (VOID)
  1129. {
  1130.    int fd, i, Count, Changed;
  1131.    ULONG Position;
  1132.    ECHOLINK *Buffer, *Record;
  1133.  
  1134.    if ((fd = sopen (DataFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1135.       Record = (ECHOLINK *)Data.First ();
  1136.  
  1137.       if ((Buffer = (ECHOLINK *)malloc (sizeof (ECHOLINK) * ECHOLINK_INDEX)) != NULL) {
  1138.          do {
  1139.             Changed = FALSE;
  1140.  
  1141.             Position = tell (fd);
  1142.             Count = read (fd, Buffer, sizeof (ECHOLINK) * ECHOLINK_INDEX) / sizeof (ECHOLINK);
  1143.             for (i = 0; i < Count && Record != NULL; i++) {
  1144.                if (Buffer[i].EchoTag == Record->EchoTag || Buffer[i].Free == TRUE) {
  1145.                   memcpy (&Buffer[i], Record, sizeof (ECHOLINK));
  1146.                   Record = (ECHOLINK *)Data.Next ();
  1147.                   Changed = TRUE;
  1148.                }
  1149.             }
  1150.  
  1151.             for (; i < Count; i++) {
  1152.                if (Buffer[i].EchoTag == EchoTag) {
  1153.                   memset (&Buffer[i], 0, sizeof (ECHOLINK));
  1154.                   Buffer[i].Free = TRUE;
  1155.                   Changed = TRUE;
  1156.                }
  1157.             }
  1158.  
  1159.             if (Changed == TRUE) {
  1160.                lseek (fd, Position, SEEK_SET);
  1161.                write (fd, Buffer, sizeof (ECHOLINK) * Count);
  1162.             }
  1163.          } while (Count == ECHOLINK_INDEX);
  1164.          free (Buffer);
  1165.       }
  1166.  
  1167.       if (Record != NULL) {
  1168.          do {
  1169.             write (fd, Record, sizeof (ECHOLINK));
  1170.          } while ((Record = (ECHOLINK *)Data.Next ()) != NULL);
  1171.       }
  1172.  
  1173.       close (fd);
  1174.    }
  1175. }
  1176.  
  1177. VOID TFilechoLink::Update (VOID)
  1178. {
  1179.    ECHOLINK *Buffer;
  1180.  
  1181.    if ((Buffer = (ECHOLINK *)Data.Value ()) != NULL) {
  1182.       Buffer->EchoTag = EchoTag;
  1183.       Buffer->Zone = Zone;
  1184.       Buffer->Net = Net;
  1185.       Buffer->Node = Node;
  1186.       Buffer->Point = Point;
  1187.       strcpy (Buffer->Domain, Domain);
  1188.       Buffer->SendOnly = SendOnly;
  1189.       Buffer->ReceiveOnly = ReceiveOnly;
  1190.       Buffer->PersonalOnly = PersonalOnly;
  1191.       Buffer->Passive = Passive;
  1192.       Buffer->Skip = Skip;
  1193.       if (Point == 0)
  1194.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  1195.       else
  1196.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  1197.       if (Domain[0] != '\0') {
  1198.          strcat (Address, "@");
  1199.          strcat (Address, Domain);
  1200.       }
  1201.    }
  1202. }
  1203.  
  1204.