home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / FILEBASE.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  51KB  |  1,490 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. #define MAX_INDEX       256
  23.  
  24. typedef struct {
  25.    CHAR  Name[32];
  26.    ULONG Date;
  27.    ULONG Download;
  28.    ULONG Position;
  29.    ULONG IdxPosition;
  30. } NAMESORT;
  31.  
  32. TFileBase::TFileBase (void)
  33. {
  34.    fdIdx = fdDat = -1;
  35.    fUploader = FALSE;
  36.    Description = new TCollection;
  37.    Clear ();
  38.    List = NULL;
  39. }
  40.  
  41. TFileBase::TFileBase (PSZ pszPath, PSZ pszArea)
  42. {
  43.    fdIdx = fdDat = -1;
  44.    fUploader = FALSE;
  45.    Description = new TCollection;
  46.    Clear ();
  47.    Open (pszPath, pszArea);
  48.    List = NULL;
  49. }
  50.  
  51. TFileBase::~TFileBase (void)
  52. {
  53.    Clear ();
  54.    Close ();
  55.    if (Description != NULL)
  56.       delete Description;
  57.    if (List != NULL) {
  58.       List->Clear ();
  59.       delete List;
  60.    }
  61. }
  62.  
  63. USHORT TFileBase::Add (VOID)
  64. {
  65.    PSZ pszTemp;
  66.    FILEDATA fileData;
  67.    FILEINDEX fileIndex;
  68.    struct tm ftm;
  69.  
  70.    fUploader = FALSE;
  71.  
  72.    memset (&fileIndex, 0, sizeof (fileIndex));
  73.    fileIndex.Area = StringCrc32 (Area, 0xFFFFFFFFL);
  74.    strcpy (fileIndex.Name, Name);
  75.    memset (&ftm, 0, sizeof (ftm));
  76.    ftm.tm_min = UplDate.Minute;
  77.    ftm.tm_hour = UplDate.Hour;
  78.    ftm.tm_mday = UplDate.Day;
  79.    ftm.tm_mon = UplDate.Month - 1;
  80.    ftm.tm_year = UplDate.Year - 1900;
  81.    fileIndex.UploadDate = mktime (&ftm);
  82.    lseek (fdDat, 0L, SEEK_END);
  83.    fileIndex.Offset = tell (fdDat);
  84.    if (Unapproved == TRUE)
  85.       fileIndex.Flags |= FILE_UNAPPROVED;
  86.  
  87.    lseek (fdIdx, 0L, SEEK_END);
  88.    write (fdIdx, &fileIndex, sizeof (fileIndex));
  89.  
  90.    memset (&fileData, 0, sizeof (fileData));
  91.    fileData.Id = FILEBASE_ID;
  92.    strcpy (fileData.Area, Area);
  93.    strcpy (fileData.Name, Name);
  94.    strcpy (fileData.Complete, Complete);
  95.    strcpy (fileData.Keyword, Keyword);
  96.    fileData.Size = Size;
  97.    fileData.DlTimes = DlTimes;
  98.    memset (&ftm, 0, sizeof (ftm));
  99.    ftm.tm_min = Date.Minute;
  100.    ftm.tm_hour = Date.Hour;
  101.    ftm.tm_mday = Date.Day;
  102.    ftm.tm_mon = Date.Month - 1;
  103.    ftm.tm_year = Date.Year - 1900;
  104.    FileDate = fileData.FileDate = mktime (&ftm);
  105.    memset (&ftm, 0, sizeof (ftm));
  106.    ftm.tm_min = UplDate.Minute;
  107.    ftm.tm_hour = UplDate.Hour;
  108.    ftm.tm_mday = UplDate.Day;
  109.    ftm.tm_mon = UplDate.Month - 1;
  110.    ftm.tm_year = UplDate.Year - 1900;
  111.    UploadDate = fileData.UploadDate = mktime (&ftm);
  112.    fileData.Cost = Cost;
  113.    fileData.Password = Password;
  114.    fileData.Level = Level;
  115.    fileData.AccessFlags = AccessFlags;
  116.    fileData.DenyFlags = DenyFlags;
  117.    if (Unapproved == TRUE)
  118.       fileData.Flags |= FILE_UNAPPROVED;
  119.    if (CdRom == TRUE)
  120.       fileData.Flags |= FILE_CDROM;
  121.    if ((pszTemp = (PSZ)Description->First ()) != NULL) {
  122.       do {
  123.          fileData.Description += strlen (pszTemp) + 2;
  124.       } while ((pszTemp = (PSZ)Description->Next ()) != NULL);
  125.    }
  126.    if (Uploader != NULL)
  127.      fileData.Uploader = (USHORT)(strlen (Uploader) + 1);
  128.  
  129.    lseek (fdDat, 0L, SEEK_END);
  130.    write (fdDat, &fileData, sizeof (fileData));
  131.  
  132.    if ((pszTemp = (PSZ)Description->First ()) != NULL) {
  133.       do {
  134.          write (fdDat, pszTemp, strlen (pszTemp));
  135.          write (fdDat, "\r\n", 2);
  136.       } while ((pszTemp = (PSZ)Description->Next ()) != NULL);
  137.    }
  138.  
  139.    if (Uploader != NULL)
  140.      write (fdDat, Uploader, fileData.Uploader);
  141.  
  142.    return (TRUE);
  143. }
  144.  
  145. ULONG TFileBase::ChangeLibrary (PSZ pszFrom, PSZ pszTo)
  146. {
  147.    ULONG CrcFrom, Number;
  148.    FILEDATA fileData;
  149.    FILEINDEX fileIndex;
  150.  
  151.    CrcFrom = StringCrc32 (pszFrom, 0xFFFFFFFFL);
  152.    Number = 0L;
  153.  
  154.    lseek (fdIdx, 0L, SEEK_SET);
  155.  
  156.    while (read (fdIdx, &fileIndex, sizeof (fileIndex)) == sizeof (fileIndex)) {
  157.       if (fileIndex.Flags & FILE_DELETED)
  158.          continue;
  159.       if (fileIndex.Area == CrcFrom) {
  160.          lseek (fdDat, fileIndex.Offset, SEEK_SET);
  161.          read (fdDat, &fileData, sizeof (fileData));
  162.          strcpy (fileData.Area, pszTo);
  163.          lseek (fdDat, fileIndex.Offset, SEEK_SET);
  164.          write (fdDat, &fileData, sizeof (fileData));
  165.  
  166.          fileIndex.Area = StringCrc32 (pszTo, 0xFFFFFFFFL);
  167.          lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex), SEEK_SET);
  168.          write (fdIdx, &fileIndex, sizeof (fileIndex));
  169.  
  170.          Number++;
  171.       }
  172.    }
  173.  
  174.    return (Number);
  175. }
  176.  
  177. VOID TFileBase::Clear (VOID)
  178. {
  179.    memset (Area, 0, sizeof (Area));
  180.    memset (Name, 0, sizeof (Name));
  181.    memset (Complete, 0, sizeof (Complete));
  182.    memset (Keyword, 0, sizeof (Keyword));
  183.    memset (&Date, 0, sizeof (Date));
  184.    memset (&UplDate, 0, sizeof (UplDate));
  185.    Description->Clear ();
  186.    if (fUploader == TRUE)
  187.       free (pszMemUploader);
  188.    fUploader = FALSE;
  189.    Uploader = NULL;
  190.    pszMemUploader = NULL;
  191.    Size = 0;
  192.    DlTimes = 0;
  193.    Cost = 0;
  194.    Password = 0;
  195.    Level = 0;
  196.    AccessFlags = DenyFlags = 0;
  197.    FileDate = UploadDate = 0L;
  198.    Unapproved = FALSE;
  199.    CdRom = FALSE;
  200. }
  201.  
  202. VOID TFileBase::Close (VOID)
  203. {
  204.    if (fdIdx != -1)
  205.       close (fdIdx);
  206.    if (fdDat != -1)
  207.       close (fdDat);
  208.    fdIdx = fdDat = -1;
  209. }
  210.  
  211. VOID TFileBase::Delete (VOID)
  212. {
  213.    FILEDATA fileData;
  214.    FILEINDEX fileIndex;
  215.  
  216.    if (tell (fdIdx) > 0) {
  217.       lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex), SEEK_SET);
  218.       read (fdIdx, &fileIndex, sizeof (fileIndex));
  219.       fileIndex.Flags |= FILE_DELETED;
  220.       lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex), SEEK_SET);
  221.       write (fdIdx, &fileIndex, sizeof (fileIndex));
  222.  
  223.       lseek (fdDat, fileIndex.Offset, SEEK_SET);
  224.       read (fdDat, &fileData, sizeof (fileData));
  225.       fileData.Flags = fileIndex.Flags;
  226.       lseek (fdDat, fileIndex.Offset, SEEK_SET);
  227.       write (fdDat, &fileData, sizeof (fileData));
  228.  
  229.       if (List != NULL) {
  230.          List->Clear ();
  231.          delete List;
  232.          List = NULL;
  233.       }
  234.    }
  235. }
  236.  
  237. USHORT TFileBase::First (PSZ pszSearch)
  238. {
  239.    USHORT RetVal = FALSE, i, r, w;
  240.    CHAR szTemp[80], szLine[80];
  241.    NAMESORT *ns;
  242.    FILEDATA fileData;
  243.    struct tm *ftm;
  244.  
  245.    if (List == NULL) {
  246.       lseek (fdIdx, 0L, SEEK_SET);
  247.       RetVal = Next (pszSearch);
  248.    }
  249.    else if ((ns = (NAMESORT *)List->First ()) != NULL) {
  250.       lseek (fdDat, ns->Position, SEEK_SET);
  251.       read (fdDat, &fileData, sizeof (fileData));
  252.  
  253.       if (fileData.Id == FILEBASE_ID) {
  254.          Clear ();
  255.          fileData.Area[sizeof (fileData.Area) - 1] = '\0';
  256.          fileData.Name[sizeof (fileData.Name) - 1] = '\0';
  257.          fileData.Complete[sizeof (fileData.Complete) - 1] = '\0';
  258.          fileData.Keyword[sizeof (fileData.Keyword) - 1] = '\0';
  259.  
  260.          strcpy (Area, fileData.Area);
  261.          strcpy (Name, fileData.Name);
  262.          strcpy (Complete, fileData.Complete);
  263.          strcpy (Keyword, fileData.Keyword);
  264.          if (fileData.Description != 0) {
  265.             w = 0;
  266.             do {
  267.                if ((r = (USHORT)sizeof (szTemp)) > fileData.Description)
  268.                   r = fileData.Description;
  269.                r = (USHORT)read (fdDat, szTemp, r);
  270.                for (i = 0; i < r; i++) {
  271.                   if (szTemp[i] == '\r') {
  272.                      szLine[w++] = '\0';
  273.                      Description->Add (szLine, w);
  274.                      w = 0;
  275.                   }
  276.                   else if (szTemp[i] != '\n')
  277.                      szLine[w++] = szTemp[i];
  278.                }
  279.                fileData.Description -= r;
  280.             } while (fileData.Description > 0);
  281.             if (w > 0) {
  282.                szLine[w++] = '\0';
  283.                Description->Add (szLine, w);
  284.             }
  285.          }
  286.          if (fileData.Uploader != 0) {
  287.             fUploader = TRUE;
  288.             pszMemUploader = Uploader = (PSZ)malloc (fileData.Uploader);
  289.             read (fdDat, Uploader, fileData.Uploader);
  290.          }
  291.          Size = fileData.Size;
  292.          DlTimes = fileData.DlTimes;
  293.          FileDate = fileData.FileDate;
  294.          ftm = localtime ((time_t *)&fileData.FileDate);
  295.          Date.Day = (UCHAR)ftm->tm_mday;
  296.          Date.Month = (UCHAR)(ftm->tm_mon + 1);
  297.          Date.Year = (USHORT)(ftm->tm_year + 1900);
  298.          Date.Hour = (UCHAR)ftm->tm_hour;
  299.          Date.Minute = (UCHAR)ftm->tm_min;
  300.          UploadDate = fileData.UploadDate;
  301.          ftm = localtime ((time_t *)&fileData.UploadDate);
  302.          UplDate.Day = (UCHAR)ftm->tm_mday;
  303.          UplDate.Month = (UCHAR)(ftm->tm_mon + 1);
  304.          UplDate.Year = (USHORT)(ftm->tm_year + 1900);
  305.          UplDate.Hour = (UCHAR)ftm->tm_hour;
  306.          UplDate.Minute = (UCHAR)ftm->tm_min;
  307.          Cost = fileData.Cost;
  308.          Password = fileData.Password;
  309.          Level = fileData.Level;
  310.          AccessFlags = fileData.AccessFlags;
  311.          DenyFlags = fileData.DenyFlags;
  312.          Unapproved = (fileData.Flags & FILE_UNAPPROVED) ? TRUE : FALSE;
  313.          CdRom = (fileData.Flags & FILE_CDROM) ? TRUE : FALSE;
  314.          RetVal = TRUE;
  315.       }
  316.    }
  317.  
  318.    return (RetVal);
  319. }
  320.  
  321. USHORT TFileBase::MatchName (PSZ pszName, PSZ pszSearch)
  322. {
  323.    USHORT Match = TRUE;
  324.  
  325.    while (*pszName != '\0' && *pszSearch != '\0' && Match == TRUE) {
  326.       if (*pszSearch == '*') {
  327.          pszSearch++;
  328.          while (*pszName != '\0' && toupper (*pszName) != toupper (*pszSearch))
  329.             pszName++;
  330.          if (toupper (*pszName) != toupper (*pszSearch))
  331.             Match = FALSE;
  332.       }
  333.       else if (*pszSearch != '?' && toupper (*pszName) != toupper (*pszSearch))
  334.          Match = FALSE;
  335.       else {
  336.          pszSearch++;
  337.          pszName++;
  338.       }
  339.    }
  340.  
  341.    return (Match);
  342. }
  343.  
  344. USHORT TFileBase::Next (PSZ pszSearch)
  345. {
  346.    USHORT fRet = FALSE, i, r, w;
  347.    CHAR szTemp[80], szLine[80];
  348.    ULONG ulCrc;
  349.    NAMESORT *ns;
  350.    FILEDATA fileData;
  351.    FILEINDEX fileIndex;
  352.    struct tm *ftm;
  353.  
  354.    if (List == NULL && fdDat != -1) {
  355.       ulCrc = StringCrc32 (szArea, 0xFFFFFFFFL);
  356.  
  357.       while (read (fdIdx, &fileIndex, sizeof (fileIndex)) == sizeof (fileIndex)) {
  358.          if (fileIndex.Flags & FILE_DELETED)
  359.             continue;
  360.          if (szArea[0] == '\0' || fileIndex.Area == ulCrc) {
  361.             fRet = TRUE;
  362.             if (pszSearch != NULL)
  363.                fRet = MatchName (fileIndex.Name, pszSearch);
  364.             if (fRet == TRUE) {
  365.                lseek (fdDat, fileIndex.Offset, SEEK_SET);
  366.                break;
  367.             }
  368.          }
  369.       }
  370.    }
  371.    else if (List != NULL && (ns = (NAMESORT *)List->Next ()) != NULL) {
  372.       lseek (fdDat, ns->Position, SEEK_SET);
  373.       fRet = TRUE;
  374.    }
  375.  
  376.    if (fRet == TRUE) {
  377.       read (fdDat, &fileData, sizeof (fileData));
  378.  
  379.       fRet = FALSE;
  380.       if (fileData.Id == FILEBASE_ID) {
  381.          Clear ();
  382.          fileData.Area[sizeof (fileData.Area) - 1] = '\0';
  383.          fileData.Name[sizeof (fileData.Name) - 1] = '\0';
  384.          fileData.Complete[sizeof (fileData.Complete) - 1] = '\0';
  385.          fileData.Keyword[sizeof (fileData.Keyword) - 1] = '\0';
  386.  
  387.          strcpy (Area, fileData.Area);
  388.          strcpy (Name, fileData.Name);
  389.          strcpy (Complete, fileData.Complete);
  390.          strcpy (Keyword, fileData.Keyword);
  391.          if (fileData.Description != 0) {
  392.             w = 0;
  393.             do {
  394.                if ((r = (USHORT)sizeof (szTemp)) > fileData.Description)
  395.                   r = fileData.Description;
  396.                r = (USHORT)read (fdDat, szTemp, r);
  397.                for (i = 0; i < r; i++) {
  398.                   if (szTemp[i] == '\r') {
  399.                      szLine[w++] = '\0';
  400.                      Description->Add (szLine, w);
  401.                      w = 0;
  402.                   }
  403.                   else if (szTemp[i] != '\n')
  404.                      szLine[w++] = szTemp[i];
  405.                }
  406.                fileData.Description -= r;
  407.             } while (fileData.Description > 0);
  408.             if (w > 0) {
  409.                szLine[w++] = '\0';
  410.                Description->Add (szLine, w);
  411.             }
  412.          }
  413.          if (fileData.Uploader != 0) {
  414.             fUploader = TRUE;
  415.             pszMemUploader = Uploader = (PSZ)malloc (fileData.Uploader);
  416.             read (fdDat, Uploader, fileData.Uploader);
  417.          }
  418.          Size = fileData.Size;
  419.          DlTimes = fileData.DlTimes;
  420.          FileDate = fileData.FileDate;
  421.          ftm = localtime ((time_t *)&fileData.FileDate);
  422.          Date.Day = (UCHAR)ftm->tm_mday;
  423.          Date.Month = (UCHAR)(ftm->tm_mon + 1);
  424.          Date.Year = (USHORT)(ftm->tm_year + 1900);
  425.          Date.Hour = (UCHAR)ftm->tm_hour;
  426.          Date.Minute = (UCHAR)ftm->tm_min;
  427.          UploadDate = fileData.UploadDate;
  428.          ftm = localtime ((time_t *)&fileData.UploadDate);
  429.          UplDate.Day = (UCHAR)ftm->tm_mday;
  430.          UplDate.Month = (UCHAR)(ftm->tm_mon + 1);
  431.          UplDate.Year = (USHORT)(ftm->tm_year + 1900);
  432.          UplDate.Hour = (UCHAR)ftm->tm_hour;
  433.          UplDate.Minute = (UCHAR)ftm->tm_min;
  434.          Cost = fileData.Cost;
  435.          Password = fileData.Password;
  436.          Level = fileData.Level;
  437.          AccessFlags = fileData.AccessFlags;
  438.          DenyFlags = fileData.DenyFlags;
  439.          Unapproved = (fileData.Flags & FILE_UNAPPROVED) ? TRUE : FALSE;
  440.          CdRom = (fileData.Flags & FILE_CDROM) ? TRUE : FALSE;
  441.          fRet = TRUE;
  442.       }
  443.    }
  444.  
  445.    return (fRet);
  446. }
  447.  
  448. USHORT TFileBase::Open (PSZ pszDataPath, PSZ pszArea)
  449. {
  450.    CHAR szFile[128];
  451.  
  452.    strcpy (DataPath, pszDataPath);
  453.    if (DataPath[0] != '\0') {
  454. #if defined(__LINUX__)
  455.       if (DataPath[strlen (DataPath) - 1] != '/')
  456.          strcat (DataPath, "/");
  457. #else
  458.       if (DataPath[strlen (DataPath) - 1] != '\\')
  459.          strcat (DataPath, "\\");
  460. #endif
  461.    }
  462.  
  463.    sprintf (szFile, "%s%s", DataPath, "filebase.idx");
  464.    if ((fdIdx = sopen (AdjustPath (szFile), O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) == -1)
  465.       return (FALSE);
  466.  
  467.    sprintf (szFile, "%s%s", DataPath, "filebase.dat");
  468.    if ((fdDat = sopen (AdjustPath (szFile), O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) == -1) {
  469.       close (fdDat);
  470.       fdDat = -1;
  471.       return (FALSE);
  472.    }
  473.  
  474.    strcpy (szArea, pszArea);
  475.  
  476.    return (TRUE);
  477. }
  478.  
  479. VOID TFileBase::Pack (VOID)
  480. {
  481.    int fdNdx, fdNdat, Readed;
  482.    CHAR File[128], NewFile[128], *Buffer;
  483.    FILEDATA fileData;
  484.    FILEINDEX fileIndex;
  485.  
  486.    sprintf (File, "%s%s", DataPath, "filebase.$dx");
  487.    fdNdx = sopen (AdjustPath (File), O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  488.    sprintf (File, "%s%s", DataPath, "filebase.$at");
  489.    fdNdat = sopen (AdjustPath (File), O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  490.    Buffer = (CHAR *)malloc (2048);
  491.  
  492.    if (fdIdx != -1 && fdDat != -1 && fdNdx != -1 && fdNdat != -1 && Buffer != NULL) {
  493.       while (read (fdIdx, &fileIndex, sizeof (FILEINDEX)) == sizeof (FILEINDEX)) {
  494.          if (!(fileIndex.Flags & FILE_DELETED)) {
  495.             lseek (fdDat, fileIndex.Offset, SEEK_SET);
  496.  
  497.             fileIndex.Offset = tell (fdNdat);
  498.             write (fdNdx, &fileIndex, sizeof (FILEINDEX));
  499.  
  500.             read (fdDat, &fileData, sizeof (FILEDATA));
  501.             write (fdNdat, &fileData, sizeof (FILEDATA));
  502.  
  503.             while (fileData.Description > 0) {
  504.                Readed = read (fdDat, Buffer, 2048);
  505.                write (fdNdat, Buffer, Readed);
  506.                fileData.Description -= (USHORT)Readed;
  507.             }
  508.             while (fileData.Uploader > 0) {
  509.                Readed = read (fdDat, Buffer, 2048);
  510.                write (fdNdat, Buffer, Readed);
  511.                fileData.Uploader -= (USHORT)Readed;
  512.             }
  513.          }
  514.       }
  515.  
  516.       close (fdNdat);
  517.       close (fdDat);
  518.       fdNdat = -1;
  519.       sprintf (File, "%s%s", DataPath, "filebase.$at");
  520.       sprintf (NewFile, "%s%s", DataPath, "filebase.dat");
  521.       unlink (NewFile);
  522.       rename (File, NewFile);
  523.       fdDat = sopen (NewFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  524.  
  525.       close (fdNdx);
  526.       close (fdIdx);
  527.       fdNdx = -1;
  528.       sprintf (File, "%s%s", DataPath, "filebase.$dx");
  529.       sprintf (NewFile, "%s%s", DataPath, "filebase.idx");
  530.       unlink (NewFile);
  531.       rename (File, NewFile);
  532.       fdIdx = sopen (NewFile, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  533.    }
  534.  
  535.    if (Buffer != NULL)
  536.       delete Buffer;
  537.  
  538.    if (fdNdat != -1)
  539.       close (fdNdat);
  540.    sprintf (File, "%s%s", DataPath, "filebase.$at");
  541.    unlink (File);
  542.  
  543.    if (fdNdx != -1)
  544.       close (fdNdx);
  545.    sprintf (File, "%s%s", DataPath, "filebase.$dx");
  546.    unlink (File);
  547. }
  548.  
  549. USHORT TFileBase::Previous (VOID)
  550. {
  551.    USHORT fRet = FALSE, i, r, w;
  552.    CHAR szTemp[80], szLine[80];
  553.    ULONG ulCrc;
  554.    NAMESORT *ns;
  555.    FILEDATA fileData;
  556.    FILEINDEX fileIndex;
  557.    struct tm *ftm;
  558.  
  559.    if (List == NULL && fdDat != -1) {
  560.       ulCrc = StringCrc32 (szArea, 0xFFFFFFFFL);
  561.  
  562.       if (fdDat != -1) {
  563.          if (tell (fdIdx) >= sizeof (fileIndex) * 2)
  564.             do {
  565.                lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex) * 2, SEEK_SET);
  566.                read (fdIdx, &fileIndex, sizeof (fileIndex));
  567.                if (fileIndex.Flags & FILE_DELETED)
  568.                   continue;
  569.                if (szArea[0] == '\0' || fileIndex.Area == ulCrc) {
  570.                   fRet = TRUE;
  571.                   lseek (fdDat, fileIndex.Offset, SEEK_SET);
  572.                   break;
  573.                }
  574.             } while (tell (fdIdx) >= sizeof (fileIndex) * 2);
  575.       }
  576.    }
  577.    else if (List != NULL && (ns = (NAMESORT *)List->Previous ()) != NULL) {
  578.       lseek (fdDat, ns->Position, SEEK_SET);
  579.       fRet = TRUE;
  580.    }
  581.  
  582.    if (fRet == TRUE) {
  583.       read (fdDat, &fileData, sizeof (fileData));
  584.  
  585.       fRet = FALSE;
  586.       if (fileData.Id == FILEBASE_ID) {
  587.          Clear ();
  588.          fileData.Area[sizeof (fileData.Area) - 1] = '\0';
  589.          fileData.Name[sizeof (fileData.Name) - 1] = '\0';
  590.          fileData.Complete[sizeof (fileData.Complete) - 1] = '\0';
  591.          fileData.Keyword[sizeof (fileData.Keyword) - 1] = '\0';
  592.  
  593.          strcpy (Area, fileData.Area);
  594.          strcpy (Name, fileData.Name);
  595.          strcpy (Complete, fileData.Complete);
  596.          strcpy (Keyword, fileData.Keyword);
  597.          if (fileData.Description != 0) {
  598.             w = 0;
  599.             do {
  600.                if ((r = (USHORT)sizeof (szTemp)) > fileData.Description)
  601.                   r = fileData.Description;
  602.                r = (USHORT)read (fdDat, szTemp, r);
  603.                for (i = 0; i < r; i++) {
  604.                   if (szTemp[i] == '\r') {
  605.                      szLine[w++] = '\0';
  606.                      Description->Add (szLine, w);
  607.                      w = 0;
  608.                   }
  609.                   else if (szTemp[i] != '\n')
  610.                      szLine[w++] = szTemp[i];
  611.                }
  612.                fileData.Description -= r;
  613.             } while (fileData.Description > 0);
  614.             if (w > 0) {
  615.                szLine[w++] = '\0';
  616.                Description->Add (szLine, w);
  617.             }
  618.          }
  619.          if (fileData.Uploader != 0) {
  620.             fUploader = TRUE;
  621.             pszMemUploader = Uploader = (PSZ)malloc (fileData.Uploader);
  622.             read (fdDat, Uploader, fileData.Uploader);
  623.          }
  624.          Size = fileData.Size;
  625.          DlTimes = fileData.DlTimes;
  626.          FileDate = fileData.FileDate;
  627.          ftm = localtime ((time_t *)&fileData.FileDate);
  628.          Date.Day = (UCHAR)ftm->tm_mday;
  629.          Date.Month = (UCHAR)(ftm->tm_mon + 1);
  630.          Date.Year = (USHORT)(ftm->tm_year + 1900);
  631.          Date.Hour = (UCHAR)ftm->tm_hour;
  632.          Date.Minute = (UCHAR)ftm->tm_min;
  633.          UploadDate = fileData.UploadDate;
  634.          ftm = localtime ((time_t *)&fileData.UploadDate);
  635.          UplDate.Day = (UCHAR)ftm->tm_mday;
  636.          UplDate.Month = (UCHAR)(ftm->tm_mon + 1);
  637.          UplDate.Year = (USHORT)(ftm->tm_year + 1900);
  638.          UplDate.Hour = (UCHAR)ftm->tm_hour;
  639.          UplDate.Minute = (UCHAR)ftm->tm_min;
  640.          Cost = fileData.Cost;
  641.          Password = fileData.Password;
  642.          Level = fileData.Level;
  643.          AccessFlags = fileData.AccessFlags;
  644.          DenyFlags = fileData.DenyFlags;
  645.          Unapproved = (fileData.Flags & FILE_UNAPPROVED) ? TRUE : FALSE;
  646.          CdRom = (fileData.Flags & FILE_CDROM) ? TRUE : FALSE;
  647.          fRet = TRUE;
  648.       }
  649.    }
  650.  
  651.    return (fRet);
  652. }
  653.  
  654. USHORT TFileBase::Read (PSZ pszFile)
  655. {
  656.    USHORT fRet = FALSE, i, r, w;
  657.    CHAR szTemp[80], szLine[80];
  658.    ULONG ulCrc;
  659.    FILEDATA fileData;
  660.    FILEINDEX fileIndex;
  661.    struct tm *ftm;
  662.  
  663.    ulCrc = StringCrc32 (szArea, 0xFFFFFFFFL);
  664.  
  665.    if (fdDat != -1 && fdIdx != -1) {
  666.       lseek (fdIdx, 0L, SEEK_SET);
  667.       while (read (fdIdx, &fileIndex, sizeof (fileIndex)) == sizeof (fileIndex)) {
  668.          if (!(fileIndex.Flags & FILE_DELETED)) {
  669.             if (szArea[0] == '\0' || fileIndex.Area == ulCrc) {
  670.                if (!stricmp (fileIndex.Name, pszFile)) {
  671.                   fRet = TRUE;
  672.                   break;
  673.                }
  674.             }
  675.          }
  676.       }
  677.       if (fRet == TRUE) {
  678.          lseek (fdDat, fileIndex.Offset, SEEK_SET);
  679.          read (fdDat, &fileData, sizeof (fileData));
  680.  
  681.          fRet = FALSE;
  682.          if (fileData.Id == FILEBASE_ID) {
  683.             Clear ();
  684.             fileData.Area[sizeof (fileData.Area) - 1] = '\0';
  685.             fileData.Name[sizeof (fileData.Name) - 1] = '\0';
  686.             fileData.Complete[sizeof (fileData.Complete) - 1] = '\0';
  687.             fileData.Keyword[sizeof (fileData.Keyword) - 1] = '\0';
  688.  
  689.             strcpy (Area, fileData.Area);
  690.             strcpy (Name, fileData.Name);
  691.             strcpy (Complete, fileData.Complete);
  692.             strcpy (Keyword, fileData.Keyword);
  693.             if (fileData.Description != 0) {
  694.                w = 0;
  695.                do {
  696.                   if ((r = (USHORT)sizeof (szTemp)) > fileData.Description)
  697.                      r = fileData.Description;
  698.                   r = (USHORT)read (fdDat, szTemp, r);
  699.                   for (i = 0; i < r; i++) {
  700.                      if (szTemp[i] == '\r') {
  701.                         szLine[w++] = '\0';
  702.                         Description->Add (szLine, w);
  703.                         w = 0;
  704.                      }
  705.                      else if (szTemp[i] != '\n')
  706.                         szLine[w++] = szTemp[i];
  707.                   }
  708.                   fileData.Description -= r;
  709.                } while (fileData.Description > 0);
  710.                if (w > 0) {
  711.                   szLine[w++] = '\0';
  712.                   Description->Add (szLine, w);
  713.                }
  714.             }
  715.             if (fileData.Uploader != 0) {
  716.                fUploader = TRUE;
  717.                pszMemUploader = Uploader = (PSZ)malloc (fileData.Uploader);
  718.                read (fdDat, Uploader, fileData.Uploader);
  719.             }
  720.             Size = fileData.Size;
  721.             DlTimes = fileData.DlTimes;
  722.             FileDate = fileData.FileDate;
  723.             ftm = localtime ((time_t *)&fileData.FileDate);
  724.             Date.Day = (UCHAR)ftm->tm_mday;
  725.             Date.Month = (UCHAR)(ftm->tm_mon + 1);
  726.             Date.Year = (USHORT)(ftm->tm_year + 1900);
  727.             Date.Hour = (UCHAR)ftm->tm_hour;
  728.             Date.Minute = (UCHAR)ftm->tm_min;
  729.             UploadDate = fileData.UploadDate;
  730.             ftm = localtime ((time_t *)&fileData.UploadDate);
  731.             UplDate.Day = (UCHAR)ftm->tm_mday;
  732.             UplDate.Month = (UCHAR)(ftm->tm_mon + 1);
  733.             UplDate.Year = (USHORT)(ftm->tm_year + 1900);
  734.             UplDate.Hour = (UCHAR)ftm->tm_hour;
  735.             UplDate.Minute = (UCHAR)ftm->tm_min;
  736.             Cost = fileData.Cost;
  737.             Password = fileData.Password;
  738.             Level = fileData.Level;
  739.             AccessFlags = fileData.AccessFlags;
  740.             DenyFlags = fileData.DenyFlags;
  741.             Unapproved = (fileData.Flags & FILE_UNAPPROVED) ? TRUE : FALSE;
  742.             CdRom = (fileData.Flags & FILE_CDROM) ? TRUE : FALSE;
  743.             fRet = TRUE;
  744.          }
  745.       }
  746.    }
  747.  
  748.    return (fRet);
  749. }
  750.  
  751. USHORT TFileBase::Replace (VOID)
  752. {
  753.    PSZ pszTemp;
  754.    USHORT RetVal = FALSE;
  755.    ULONG ulCrc;
  756.    FILEDATA fileData;
  757.    FILEINDEX fileIndex;
  758.    struct tm ftm;
  759.  
  760.    fUploader = FALSE;
  761.    ulCrc = StringCrc32 (szArea, 0xFFFFFFFFL);
  762.  
  763.    lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex), SEEK_SET);
  764.    read (fdIdx, &fileIndex, sizeof (fileIndex));
  765.  
  766.    if ((szArea[0] != '\0' && fileIndex.Area != ulCrc) || stricmp (fileIndex.Name, Name)) {
  767.       lseek (fdIdx, 0L, SEEK_SET);
  768.       while (read (fdIdx, &fileIndex, sizeof (fileIndex)) == sizeof (fileIndex)) {
  769.          if (!(fileIndex.Flags & FILE_DELETED)) {
  770.             if (szArea[0] == '\0' || fileIndex.Area == ulCrc) {
  771.                if (!stricmp (fileIndex.Name, Name)) {
  772.                   RetVal = TRUE;
  773.                   break;
  774.                }
  775.             }
  776.          }
  777.       }
  778.    }
  779.    else
  780.       RetVal = TRUE;
  781.  
  782.    if (RetVal == TRUE) {
  783.       lseek (fdDat, fileIndex.Offset, SEEK_SET);
  784.       read (fdDat, &fileData, sizeof (fileData));
  785.       RetVal = FALSE;
  786.  
  787.       if (fileData.Id == FILEBASE_ID) {
  788.          fileData.Flags |= FILE_DELETED;
  789.          lseek (fdDat, fileIndex.Offset, SEEK_SET);
  790.          write (fdDat, &fileData, sizeof (fileData));
  791.  
  792.          lseek (fdDat, 0L, SEEK_END);
  793.  
  794.          fileIndex.Offset = tell (fdDat);
  795.          memset (&ftm, 0, sizeof (ftm));
  796.          ftm.tm_min = UplDate.Minute;
  797.          ftm.tm_hour = UplDate.Hour;
  798.          ftm.tm_mday = UplDate.Day;
  799.          ftm.tm_mon = UplDate.Month - 1;
  800.          ftm.tm_year = UplDate.Year - 1900;
  801.          fileIndex.UploadDate = mktime (&ftm);
  802.          if (Unapproved == TRUE)
  803.             fileIndex.Flags |= FILE_UNAPPROVED;
  804.          else
  805.             fileIndex.Flags &= ~FILE_UNAPPROVED;
  806.          lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex), SEEK_SET);
  807.          write (fdIdx, &fileIndex, sizeof (fileIndex));
  808.  
  809.          memset (&fileData, 0, sizeof (fileData));
  810.          strcpy (fileData.Area, Area);
  811.          strcpy (fileData.Name, Name);
  812.          strcpy (fileData.Complete, Complete);
  813.          strcpy (fileData.Keyword, Keyword);
  814.          fileData.Size = Size;
  815.          fileData.DlTimes = DlTimes;
  816.          memset (&ftm, 0, sizeof (ftm));
  817.          ftm.tm_min = Date.Minute;
  818.          ftm.tm_hour = Date.Hour;
  819.          ftm.tm_mday = Date.Day;
  820.          ftm.tm_mon = Date.Month - 1;
  821.          ftm.tm_year = Date.Year - 1900;
  822.          FileDate = fileData.FileDate = mktime (&ftm);
  823.          memset (&ftm, 0, sizeof (ftm));
  824.          ftm.tm_min = UplDate.Minute;
  825.          ftm.tm_hour = UplDate.Hour;
  826.          ftm.tm_mday = UplDate.Day;
  827.          ftm.tm_mon = UplDate.Month - 1;
  828.          ftm.tm_year = UplDate.Year - 1900;
  829.          UploadDate = fileData.UploadDate = mktime (&ftm);
  830.          fileData.Cost = Cost;
  831.          fileData.Password = Password;
  832.          fileData.Level = Level;
  833.          fileData.AccessFlags = AccessFlags;
  834.          fileData.DenyFlags = DenyFlags;
  835.          if (Unapproved == TRUE)
  836.             fileData.Flags |= FILE_UNAPPROVED;
  837.          if (CdRom == TRUE)
  838.             fileData.Flags |= FILE_CDROM;
  839.          if ((pszTemp = (PSZ)Description->First ()) != NULL) {
  840.             do {
  841.                fileData.Description += strlen (pszTemp) + 2;
  842.             } while ((pszTemp = (PSZ)Description->Next ()) != NULL);
  843.          }
  844.          if (Uploader != NULL)
  845.            fileData.Uploader = (USHORT)(strlen (Uploader) + 1);
  846.  
  847.          lseek (fdDat, 0L, SEEK_END);
  848.          write (fdDat, &fileData, sizeof (fileData));
  849.  
  850.          if ((pszTemp = (PSZ)Description->First ()) != NULL) {
  851.             do {
  852.                write (fdDat, pszTemp, strlen (pszTemp));
  853.                write (fdDat, "\r\n", 2);
  854.             } while ((pszTemp = (PSZ)Description->Next ()) != NULL);
  855.          }
  856.  
  857.          if (Uploader != NULL)
  858.            write (fdDat, Uploader, fileData.Uploader);
  859.  
  860.          RetVal = TRUE;
  861.       }
  862.    }
  863.  
  864.    return (RetVal);
  865. }
  866.  
  867. USHORT TFileBase::ReplaceHeader (VOID)
  868. {
  869.    USHORT RetVal = FALSE;
  870.    ULONG ulCrc;
  871.    FILEDATA fileData;
  872.    FILEINDEX fileIndex;
  873.    NAMESORT *ns;
  874.    struct tm ftm;
  875.  
  876.    if (List == NULL) {
  877.       ulCrc = StringCrc32 (szArea, 0xFFFFFFFFL);
  878.  
  879.       if (fdDat != -1 && fdIdx != -1) {
  880.          lseek (fdIdx, 0L, SEEK_SET);
  881.          while (read (fdIdx, &fileIndex, sizeof (fileIndex)) == sizeof (fileIndex)) {
  882.             if (!(fileIndex.Flags & FILE_DELETED)) {
  883.                if (szArea[0] == '\0' || fileIndex.Area == ulCrc) {
  884.                   if (!stricmp (fileIndex.Name, Name)) {
  885.                      lseek (fdDat, fileIndex.Offset, SEEK_SET);
  886.                      read (fdDat, &fileData, sizeof (fileData));
  887.                      if (fileData.Id == FILEBASE_ID) {
  888.                         RetVal = TRUE;
  889.                         break;
  890.                      }
  891.                   }
  892.                }
  893.             }
  894.          }
  895.       }
  896.    }
  897.    else {
  898.       if ((ns = (NAMESORT *)List->Value ()) != NULL) {
  899.          lseek (fdIdx, ns->IdxPosition, SEEK_SET);
  900.          read (fdIdx, &fileIndex, sizeof (fileIndex));
  901.          lseek (fdDat, fileIndex.Offset, SEEK_SET);
  902.          read (fdDat, &fileData, sizeof (fileData));
  903.          if (fileData.Id == FILEBASE_ID && !strcmp (fileData.Name, Name))
  904.             RetVal = TRUE;
  905.       }
  906.  
  907.       if (RetVal == FALSE) {
  908.          if ((ns = (NAMESORT *)List->First ()) != NULL)
  909.             do {
  910.                if (!stricmp (ns->Name, Name)) {
  911.                   lseek (fdIdx, ns->IdxPosition, SEEK_SET);
  912.                   read (fdIdx, &fileIndex, sizeof (fileIndex));
  913.                   lseek (fdDat, fileIndex.Offset, SEEK_SET);
  914.                   read (fdDat, &fileData, sizeof (fileData));
  915.                   if (fileData.Id == FILEBASE_ID) {
  916.                      RetVal = TRUE;
  917.                      break;
  918.                   }
  919.                }
  920.             } while ((ns = (NAMESORT *)List->Next ()) != NULL);
  921.       }
  922.    }
  923.  
  924.    if (RetVal == TRUE) {
  925.       // Aggiornamento dell'indice
  926.       fileIndex.Area = StringCrc32 (Area, 0xFFFFFFFFL);
  927.       strcpy (fileIndex.Name, Name);
  928.       memset (&ftm, 0, sizeof (ftm));
  929.       ftm.tm_min = UplDate.Minute;
  930.       ftm.tm_hour = UplDate.Hour;
  931.       ftm.tm_mday = UplDate.Day;
  932.       ftm.tm_mon = UplDate.Month - 1;
  933.       ftm.tm_year = UplDate.Year - 1900;
  934.       fileIndex.UploadDate = mktime (&ftm);
  935.       if (Unapproved == TRUE)
  936.          fileIndex.Flags |= FILE_UNAPPROVED;
  937.       else
  938.          fileIndex.Flags &= ~FILE_UNAPPROVED;
  939.  
  940.       lseek (fdIdx, tell (fdIdx) - sizeof (fileIndex), SEEK_SET);
  941.       write (fdIdx, &fileIndex, sizeof (fileIndex));
  942.  
  943.       // Aggiornamento della struttura dati principale
  944.       strcpy (fileData.Area, Area);
  945.       strcpy (fileData.Name, Name);
  946.       strcpy (fileData.Complete, Complete);
  947.       strcpy (fileData.Keyword, Keyword);
  948.       fileData.Size = Size;
  949.       fileData.DlTimes = DlTimes;
  950.       memset (&ftm, 0, sizeof (ftm));
  951.       ftm.tm_min = Date.Minute;
  952.       ftm.tm_hour = Date.Hour;
  953.       ftm.tm_mday = Date.Day;
  954.       ftm.tm_mon = Date.Month - 1;
  955.       ftm.tm_year = Date.Year - 1900;
  956.       FileDate = fileData.FileDate = mktime (&ftm);
  957.       memset (&ftm, 0, sizeof (ftm));
  958.       ftm.tm_min = UplDate.Minute;
  959.       ftm.tm_hour = UplDate.Hour;
  960.       ftm.tm_mday = UplDate.Day;
  961.       ftm.tm_mon = UplDate.Month - 1;
  962.       ftm.tm_year = UplDate.Year - 1900;
  963.       UploadDate = fileData.UploadDate = mktime (&ftm);
  964.       fileData.Cost = Cost;
  965.       fileData.Password = Password;
  966.       fileData.Level = Level;
  967.       fileData.AccessFlags = AccessFlags;
  968.       fileData.DenyFlags = DenyFlags;
  969.       if (Unapproved == TRUE)
  970.          fileData.Flags |= FILE_UNAPPROVED;
  971.       else
  972.          fileData.Flags &= ~FILE_UNAPPROVED;
  973.       if (CdRom == TRUE)
  974.          fileData.Flags |= FILE_CDROM;
  975.       else
  976.          fileData.Flags &= ~FILE_CDROM;
  977.  
  978.       lseek (fdDat, fileIndex.Offset, SEEK_SET);
  979.       write (fdDat, &fileData, sizeof (fileData));
  980.    }
  981.  
  982.    return (TRUE);
  983. }
  984.  
  985. VOID TFileBase::SearchFile (PSZ pszFile)
  986. {
  987.    USHORT i, Readed, RetVal = FALSE;
  988.    ULONG Crc;
  989.    NAMESORT ns, *pns;
  990.    FILEDATA fileData;
  991.    FILEINDEX *fileIndex;
  992.  
  993.    if (List == NULL)
  994.       List = new TCollection;
  995.    fileIndex = (FILEINDEX *)malloc (sizeof (FILEINDEX) * MAX_INDEX);
  996.    strlwr (pszFile);
  997.  
  998.    if (List != NULL && fileIndex != NULL) {
  999.       List->Clear ();
  1000.       Crc = StringCrc32 (szArea, 0xFFFFFFFFL);
  1001.  
  1002.       if (fdDat != -1 && fdIdx != -1) {
  1003.          lseek (fdIdx, 0L, SEEK_SET);
  1004.          while ((Readed = (USHORT)read (fdIdx, fileIndex, sizeof (FILEINDEX) * MAX_INDEX)) > 0) {
  1005.             Readed /= sizeof (FILEINDEX);
  1006.             for (i = 0; i < Readed; i++) {
  1007.                if (!(fileIndex[i].Flags & (FILE_DELETED|FILE_UNAPPROVED)) && (szArea[0] == '\0' || fileIndex[i].Area == Crc)) {
  1008.                   lseek (fdDat, fileIndex[i].Offset, SEEK_SET);
  1009.                   read (fdDat, &fileData, sizeof (fileData));
  1010.  
  1011.                   if (fileData.Id == FILEBASE_ID) {
  1012.                      RetVal = FALSE;
  1013.                      if (MatchName (fileIndex[i].Name, pszFile) == TRUE) {
  1014.                         fileIndex[i].Name[sizeof (fileIndex[i].Name) - 1] = '\0';
  1015.                         strcpy (ns.Name, fileIndex[i].Name);
  1016.                         ns.Position = fileIndex[i].Offset;
  1017.                         if ((pns = (NAMESORT *)List->First ()) != NULL) {
  1018.                            if (strcmp (pns->Name, ns.Name) > 0) {
  1019.                               List->Insert (&ns, sizeof (ns));
  1020.                               List->Insert (pns, sizeof (ns));
  1021.                               List->First ();
  1022.                               List->Remove ();
  1023.                               RetVal = TRUE;
  1024.                            }
  1025.                            if (RetVal == FALSE)
  1026.                               do {
  1027.                                  if (strcmp (pns->Name, ns.Name) > 0) {
  1028.                                     List->Previous ();
  1029.                                     List->Insert (&ns, sizeof (ns));
  1030.                                     RetVal = TRUE;
  1031.                                  }
  1032.                               } while (RetVal == FALSE && (pns = (NAMESORT *)List->Next ()) != NULL);
  1033.                         }
  1034.  
  1035.                         if (RetVal == FALSE)
  1036.                            List->Add (&ns, sizeof (ns));
  1037.                      }
  1038.                   }
  1039.                }
  1040.             }
  1041.          }
  1042.       }
  1043.    }
  1044.  
  1045.    if (fileIndex != NULL)
  1046.       free (fileIndex);
  1047. }
  1048.  
  1049. VOID TFileBase::SearchKeyword (PSZ pszKeyword)
  1050. {
  1051.    USHORT x, Readed, RetVal = FALSE;
  1052.    ULONG Crc;
  1053.    NAMESORT ns, *pns;
  1054.    FILEDATA fileData;
  1055.    FILEINDEX *fileIndex;
  1056.  
  1057.    if (List == NULL)
  1058.       List = new TCollection;
  1059.    fileIndex = (FILEINDEX *)malloc (sizeof (FILEINDEX) * MAX_INDEX);
  1060.    strlwr (pszKeyword);
  1061.  
  1062.    if (List != NULL && fileIndex != NULL) {
  1063.       List->Clear ();
  1064.       Crc = StringCrc32 (szArea, 0xFFFFFFFFL);
  1065.  
  1066.       if (fdDat != -1 && fdIdx != -1) {
  1067.          lseek (fdIdx, 0L, SEEK_SET);
  1068.          while ((Readed = (USHORT)read (fdIdx, fileIndex, sizeof (FILEINDEX) * MAX_INDEX)) > 0) {
  1069.             Readed /= sizeof (FILEINDEX);
  1070.             for (x = 0; x < Readed; x++) {
  1071.                if (!(fileIndex[x].Flags & (FILE_DELETED|FILE_UNAPPROVED)) && (szArea[0] == '\0' || fileIndex[x].Area == Crc)) {
  1072.                   lseek (fdDat, fileIndex[x].Offset, SEEK_SET);
  1073.                   read (fdDat, &fileData, sizeof (fileData));
  1074.  
  1075.                   if (fileData.Id == FILEBASE_ID) {
  1076.                      if (strstr (strlwr (fileData.Keyword), pszKeyword) != NULL) {
  1077.                         fileIndex[x].Name[sizeof (fileIndex[x].Name) - 1] = '\0';
  1078.                         strcpy (ns.Name, fileIndex[x].Name);
  1079.                         ns.Position = fileIndex[x].Offset;
  1080.  
  1081.                         RetVal = FALSE;
  1082.                         if ((pns = (NAMESORT *)List->First ()) != NULL) {
  1083.                            if (strcmp (pns->Name, ns.Name) > 0) {
  1084.                               List->Insert (&ns, sizeof (ns));
  1085.                               List->Insert (pns, sizeof (ns));
  1086.                               List->First ();
  1087.                               List->Remove ();
  1088.                               RetVal = TRUE;
  1089.                            }
  1090.                            if (RetVal == FALSE)
  1091.                               do {
  1092.                                  if (strcmp (pns->Name, ns.Name) > 0) {
  1093.                                     List->Previous ();
  1094.                                     List->Insert (&ns, sizeof (ns));
  1095.                                     RetVal = TRUE;
  1096.                                  }
  1097.                               } while (RetVal == FALSE && (pns = (NAMESORT *)List->Next ()) != NULL);
  1098.                         }
  1099.  
  1100.                         if (RetVal == FALSE)
  1101.                            List->Add (&ns, sizeof (ns));
  1102.                      }
  1103.                   }
  1104.                }
  1105.             }
  1106.          }
  1107.       }
  1108.    }
  1109.  
  1110.    if (fileIndex != NULL)
  1111.       free (fileIndex);
  1112. }
  1113.  
  1114. VOID TFileBase::SearchText (PSZ pszText)
  1115. {
  1116.    USHORT x, i, r, w, Readed, RetVal = FALSE, AddThis;
  1117.    CHAR szTemp[80], szLine[80];
  1118.    ULONG Crc;
  1119.    NAMESORT ns, *pns;
  1120.    FILEDATA fileData;
  1121.    FILEINDEX *fileIndex;
  1122.  
  1123.    if (List == NULL)
  1124.       List = new TCollection;
  1125.    fileIndex = (FILEINDEX *)malloc (sizeof (FILEINDEX) * MAX_INDEX);
  1126.    strlwr (pszText);
  1127.  
  1128.    if (List != NULL && fileIndex != NULL) {
  1129.       List->Clear ();
  1130.       Crc = StringCrc32 (szArea, 0xFFFFFFFFL);
  1131.  
  1132.       if (fdDat != -1 && fdIdx != -1) {
  1133.          lseek (fdIdx, 0L, SEEK_SET);
  1134.          while ((Readed = (USHORT)read (fdIdx, fileIndex, sizeof (FILEINDEX) * MAX_INDEX)) > 0) {
  1135.             Readed /= sizeof (FILEINDEX);
  1136.             for (x = 0; x < Readed; x++) {
  1137.                if (!(fileIndex[x].Flags & (FILE_DELETED|FILE_UNAPPROVED)) && (szArea[0] == '\0' || fileIndex[x].Area == Crc)) {
  1138.                   lseek (fdDat, fileIndex[x].Offset, SEEK_SET);
  1139.                   read (fdDat, &fileData, sizeof (fileData));
  1140.  
  1141.                   if (fileData.Id == FILEBASE_ID) {
  1142.                      AddThis = FALSE;
  1143.                      fileData.Name[sizeof (fileData.Name) - 1] = '\0';
  1144.                      fileData.Keyword[sizeof (fileData.Keyword) - 1] = '\0';
  1145.  
  1146.                      if (strstr (strlwr (fileData.Name), pszText) != NULL)
  1147.                         AddThis = TRUE;
  1148.                      if (strstr (strlwr (fileData.Keyword), pszText) != NULL)
  1149.                         AddThis = TRUE;
  1150.  
  1151.                      if (fileData.Description != 0 && AddThis == FALSE) {
  1152.                         w = 0;
  1153.                         do {
  1154.                            if ((r = (USHORT)sizeof (szTemp)) > fileData.Description)
  1155.                               r = fileData.Description;
  1156.                            r = (USHORT)read (fdDat, szTemp, r);
  1157.                            for (i = 0; i < r && AddThis == FALSE; i++) {
  1158.                               if (szTemp[i] == '\r') {
  1159.                                  szLine[w++] = '\0';
  1160.                                  if (strstr (strlwr (szLine), pszText) != NULL)
  1161.                                     AddThis = TRUE;
  1162.                                  w = 0;
  1163.                               }
  1164.                               else if (szTemp[i] != '\n')
  1165.                                  szLine[w++] = szTemp[i];
  1166.                            }
  1167.                            fileData.Description -= r;
  1168.                         } while (AddThis == FALSE && fileData.Description > 0);
  1169.                         if (w > 0) {
  1170.                            szLine[w++] = '\0';
  1171.                            if (strstr (strlwr (szLine), pszText) != NULL)
  1172.                               AddThis = TRUE;
  1173.                         }
  1174.                      }
  1175.  
  1176.                      if (fileData.Uploader != 0 && AddThis == FALSE) {
  1177.                         fUploader = TRUE;
  1178.                         pszMemUploader = Uploader = (PSZ)malloc (fileData.Uploader);
  1179.                         read (fdDat, Uploader, fileData.Uploader);
  1180.                      }
  1181.  
  1182.                      if (AddThis == TRUE) {
  1183.                         fileIndex[x].Name[sizeof (fileIndex[x].Name) - 1] = '\0';
  1184.                         strcpy (ns.Name, fileIndex[x].Name);
  1185.                         ns.Position = fileIndex[x].Offset;
  1186.  
  1187.                         RetVal = FALSE;
  1188.                         if ((pns = (NAMESORT *)List->First ()) != NULL) {
  1189.                            if (strcmp (pns->Name, ns.Name) > 0) {
  1190.                               List->Insert (&ns, sizeof (ns));
  1191.                               List->Insert (pns, sizeof (ns));
  1192.                               List->First ();
  1193.                               List->Remove ();
  1194.                               RetVal = TRUE;
  1195.                            }
  1196.                            if (RetVal == FALSE)
  1197.                               do {
  1198.                                  if (strcmp (pns->Name, ns.Name) > 0) {
  1199.                                     List->Previous ();
  1200.                                     List->Insert (&ns, sizeof (ns));
  1201.                                     RetVal = TRUE;
  1202.                                  }
  1203.                               } while (RetVal == FALSE && (pns = (NAMESORT *)List->Next ()) != NULL);
  1204.                         }
  1205.  
  1206.                         if (RetVal == FALSE)
  1207.                            List->Add (&ns, sizeof (ns));
  1208.                      }
  1209.                   }
  1210.                }
  1211.             }
  1212.          }
  1213.       }
  1214.    }
  1215.  
  1216.    if (fileIndex != NULL)
  1217.       free (fileIndex);
  1218. }
  1219.  
  1220. VOID TFileBase::SortByDate (ULONG ulDate)
  1221. {
  1222.    USHORT i, Readed, RetVal = FALSE;
  1223.    ULONG Crc;
  1224.    NAMESORT ns, *pns;
  1225.    FILEDATA fileData;
  1226.    FILEINDEX *fileIndex;
  1227.  
  1228.    if (List == NULL)
  1229.       List = new TCollection;
  1230.    fileIndex = (FILEINDEX *)malloc (sizeof (FILEINDEX) * MAX_INDEX);
  1231.  
  1232.    if (List != NULL && fileIndex != NULL) {
  1233.       List->Clear ();
  1234.       Crc = StringCrc32 (szArea, 0xFFFFFFFFL);
  1235.  
  1236.       if (fdDat != -1 && fdIdx != -1) {
  1237.          lseek (fdIdx, 0L, SEEK_SET);
  1238.          while ((Readed = (USHORT)read (fdIdx, fileIndex, sizeof (FILEINDEX) * MAX_INDEX)) > 0) {
  1239.             Readed /= sizeof (FILEINDEX);
  1240.             for (i = 0; i < Readed; i++) {
  1241.                if (!(fileIndex[i].Flags & (FILE_DELETED|FILE_UNAPPROVED)) && (szArea[0] == '\0' || fileIndex[i].Area == Crc)) {
  1242.                   lseek (fdDat, fileIndex[i].Offset, SEEK_SET);
  1243.                   read (fdDat, &fileData, sizeof (fileData));
  1244.  
  1245.                   if (fileData.Id == FILEBASE_ID) {
  1246.                      fileIndex[i].Name[sizeof (fileIndex[i].Name) - 1] = '\0';
  1247.                      strcpy (ns.Name, fileIndex[i].Name);
  1248.                      ns.Date = fileIndex[i].UploadDate;
  1249.                      ns.Position = fileIndex[i].Offset;
  1250.  
  1251.                      if (ns.Date > ulDate) {
  1252.                         RetVal = FALSE;
  1253.                         if ((pns = (NAMESORT *)List->First ()) != NULL) {
  1254.                            if (pns->Date < ns.Date) {
  1255.                               List->Insert (&ns, sizeof (ns));
  1256.                               List->Insert (pns, sizeof (ns));
  1257.                               List->First ();
  1258.                               List->Remove ();
  1259.                               List->First ();
  1260.                               RetVal = TRUE;
  1261.                            }
  1262.                            if (RetVal == FALSE)
  1263.                               do {
  1264.                                  if (pns->Date < ns.Date) {
  1265.                                     List->Previous ();
  1266.                                     List->Insert (&ns, sizeof (ns));
  1267.                                     RetVal = TRUE;
  1268.                                  }
  1269.                               } while (RetVal == FALSE && (pns = (NAMESORT *)List->Next ()) != NULL);
  1270.                         }
  1271.  
  1272.                         if (RetVal == FALSE)
  1273.                            List->Add (&ns, sizeof (ns));
  1274.                      }
  1275.                   }
  1276.                }
  1277.             }
  1278.          }
  1279.       }
  1280.    }
  1281.  
  1282.    if (fileIndex != NULL)
  1283.       free (fileIndex);
  1284. }
  1285.  
  1286. VOID TFileBase::SortByDownload (VOID)
  1287. {
  1288.    USHORT x, Readed, RetVal = FALSE;
  1289.    ULONG Crc;
  1290.    NAMESORT ns, *pns;
  1291.    FILEDATA fileData;
  1292.    FILEINDEX *fileIndex;
  1293.  
  1294.    if (List == NULL)
  1295.       List = new TCollection;
  1296.    fileIndex = (FILEINDEX *)malloc (sizeof (FILEINDEX) * MAX_INDEX);
  1297.  
  1298.    if (List != NULL && fileIndex != NULL) {
  1299.       List->Clear ();
  1300.       Crc = StringCrc32 (szArea, 0xFFFFFFFFL);
  1301.  
  1302.       if (fdDat != -1 && fdIdx != -1) {
  1303.          lseek (fdIdx, 0L, SEEK_SET);
  1304.          while ((Readed = (USHORT)read (fdIdx, fileIndex, sizeof (FILEINDEX) * MAX_INDEX)) > 0) {
  1305.             Readed /= sizeof (FILEINDEX);
  1306.             for (x = 0; x < Readed; x++) {
  1307.                if (!(fileIndex[x].Flags & (FILE_DELETED|FILE_UNAPPROVED)) && (szArea[0] == '\0' || fileIndex[x].Area == Crc)) {
  1308.                   lseek (fdDat, fileIndex[x].Offset, SEEK_SET);
  1309.                   read (fdDat, &fileData, sizeof (fileData));
  1310.  
  1311.                   if (fileData.Id == FILEBASE_ID) {
  1312.                      fileIndex[x].Name[sizeof (fileIndex[x].Name) - 1] = '\0';
  1313.                      strcpy (ns.Name, fileIndex[x].Name);
  1314.                      ns.Download = fileData.DlTimes;
  1315.                      ns.Position = fileIndex[x].Offset;
  1316.  
  1317.                      RetVal = FALSE;
  1318.                      if ((pns = (NAMESORT *)List->First ()) != NULL) {
  1319.                         if (pns->Download < ns.Download) {
  1320.                            List->Insert (&ns, sizeof (ns));
  1321.                            List->Insert (pns, sizeof (ns));
  1322.                            List->First ();
  1323.                            List->Remove ();
  1324.                            RetVal = TRUE;
  1325.                         }
  1326.                         if (RetVal == FALSE)
  1327.                            do {
  1328.                               if (pns->Download < ns.Download) {
  1329.                                  List->Previous ();
  1330.                                  List->Insert (&ns, sizeof (ns));
  1331.                                  RetVal = TRUE;
  1332.                               }
  1333.                            } while (RetVal == FALSE && (pns = (NAMESORT *)List->Next ()) != NULL);
  1334.                      }
  1335.  
  1336.                      if (RetVal == FALSE)
  1337.                         List->Add (&ns, sizeof (ns));
  1338.                   }
  1339.                }
  1340.             }
  1341.          }
  1342.       }
  1343.    }
  1344.  
  1345.    if (fileIndex != NULL)
  1346.       free (fileIndex);
  1347. }
  1348.  
  1349. VOID TFileBase::SortByName (VOID)
  1350. {
  1351.    USHORT i, Readed, RetVal = FALSE;
  1352.    ULONG Crc, Position;
  1353.    NAMESORT ns, *pns;
  1354.    FILEDATA fileData;
  1355.    FILEINDEX *fileIndex;
  1356.  
  1357.    if (List == NULL)
  1358.       List = new TCollection;
  1359.    fileIndex = (FILEINDEX *)malloc (sizeof (FILEINDEX) * MAX_INDEX);
  1360.  
  1361.    if (List != NULL && fileIndex != NULL) {
  1362.       List->Clear ();
  1363.       Crc = StringCrc32 (szArea, 0xFFFFFFFFL);
  1364.  
  1365.       if (fdDat != -1 && fdIdx != -1) {
  1366.          lseek (fdIdx, 0L, SEEK_SET);
  1367.          Position = 0L;
  1368.          while ((Readed = (USHORT)read (fdIdx, fileIndex, sizeof (FILEINDEX) * MAX_INDEX)) > 0) {
  1369.             Readed /= sizeof (FILEINDEX);
  1370.             for (i = 0; i < Readed; i++, Position += sizeof (FILEINDEX)) {
  1371.                if (!(fileIndex[i].Flags & (FILE_DELETED|FILE_UNAPPROVED)) && (szArea[0] == '\0' || fileIndex[i].Area == Crc)) {
  1372.                   lseek (fdDat, fileIndex[i].Offset, SEEK_SET);
  1373.                   read (fdDat, &fileData, sizeof (fileData));
  1374.  
  1375.                   if (fileData.Id == FILEBASE_ID) {
  1376.                      fileIndex[i].Name[sizeof (fileIndex[i].Name) - 1] = '\0';
  1377.                      strcpy (ns.Name, fileIndex[i].Name);
  1378.                      ns.Position = fileIndex[i].Offset;
  1379.                      ns.IdxPosition = Position;
  1380.  
  1381.                      RetVal = FALSE;
  1382.                      if ((pns = (NAMESORT *)List->First ()) != NULL) {
  1383.                         if (strcmp (pns->Name, ns.Name) > 0) {
  1384.                            List->Insert (&ns, sizeof (ns));
  1385.                            List->Insert (pns, sizeof (ns));
  1386.                            List->First ();
  1387.                            List->Remove ();
  1388.                            RetVal = TRUE;
  1389.                         }
  1390.                         if (RetVal == FALSE)
  1391.                            do {
  1392.                               if (strcmp (pns->Name, ns.Name) > 0) {
  1393.                                  List->Previous ();
  1394.                                  List->Insert (&ns, sizeof (ns));
  1395.                                  RetVal = TRUE;
  1396.                               }
  1397.                            } while (RetVal == FALSE && (pns = (NAMESORT *)List->Next ()) != NULL);
  1398.                      }
  1399.  
  1400.                      if (RetVal == FALSE)
  1401.                         List->Add (&ns, sizeof (ns));
  1402.                   }
  1403.                }
  1404.             }
  1405.          }
  1406.       }
  1407.    }
  1408.  
  1409.    if (fileIndex != NULL)
  1410.       free (fileIndex);
  1411. }
  1412.  
  1413. VOID TFileBase::ReadFileList (PSZ list, PSZ dl_path)
  1414. {
  1415.    FILE *fp;
  1416.    USHORT PendingWrite;
  1417.    CHAR Path[128], Temp[128], *p, *FileName;
  1418.    struct stat statbuf;
  1419.    struct tm *ltm;
  1420.  
  1421.    if ((fp = fopen (list, "rt")) != NULL) {
  1422.       PendingWrite = FALSE;
  1423.       while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1424.          if ((p = strchr (Temp, 0x0A)) != NULL)
  1425.             p = '\0';
  1426.          if (Temp[1] == '>') {
  1427.             if (PendingWrite == TRUE)
  1428.                Description->Add (&Temp[2]);
  1429.          }
  1430.          else {
  1431.             if (PendingWrite == TRUE) {
  1432.                Add ();
  1433.                Clear ();
  1434.                PendingWrite = FALSE;
  1435.             }
  1436.             if ((FileName = strtok (Temp, " ")) != NULL) {
  1437.                if ((p = strtok (NULL, "")) != NULL) {
  1438.                   while (*p == ' ')
  1439.                      p++;
  1440.                   if (*p == '(' || *p == '[') {
  1441.                      while (*p != ')' && *p != ']' && *p != '\0') {
  1442.                         if (isdigit (*p)) {
  1443.                            DlTimes *= 10;
  1444.                            DlTimes += *p - '0';
  1445.                         }
  1446.                         p++;
  1447.                      }
  1448.                      if (*p == ')' || *p == ']') {
  1449.                         p++;
  1450.                         while (*p == ' ')
  1451.                            p++;
  1452.                      }
  1453.                   }
  1454.                   if (*p != '\0')
  1455.                      Description->Add (p);
  1456.                }
  1457.                sprintf (Path, "%s%s", dl_path, FileName);
  1458. #if defined(__LINUX__)
  1459.                strlwr (Path);
  1460. #endif
  1461.                if (!stat (Path, &statbuf)) {
  1462.                   strcpy (Name, FileName);
  1463.                   sprintf (Complete, "%s%s", dl_path, FileName);
  1464.                   Size = statbuf.st_size;
  1465.                   ltm = localtime ((time_t *)&statbuf.st_mtime);
  1466.                   UplDate.Day = Date.Day = (UCHAR)ltm->tm_mday;
  1467.                   UplDate.Month = Date.Month = (UCHAR)(ltm->tm_mon + 1);
  1468.                   UplDate.Year = Date.Year = (USHORT)(ltm->tm_year + 1900);
  1469.                   UplDate.Hour = Date.Hour = (UCHAR)ltm->tm_hour;
  1470.                   UplDate.Minute = Date.Minute = (UCHAR)ltm->tm_min;
  1471.                   Uploader = "Sysop";
  1472.                   CdRom = FALSE;
  1473.                   PendingWrite = TRUE;
  1474.                }
  1475.                else
  1476.                   Clear ();
  1477.             }
  1478.          }
  1479.       }
  1480.       fclose (fp);
  1481.  
  1482.       if (PendingWrite == TRUE) {
  1483.          Add ();
  1484.          Clear ();
  1485.       }
  1486.    }
  1487. }
  1488.  
  1489.  
  1490.