home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / fsrc1241.zip / findexec.c < prev    next >
C/C++ Source or Header  |  1999-02-14  |  28KB  |  716 lines

  1. /*---------------------------------------------------------------------------+
  2.  | Titel: FINDEXEC.C                                                         |
  3.  +-----------------------------------------+---------------------------------+
  4.  | Erstellt von: Michael Hohner            | Am: 13.09.1994                  |
  5.  +-----------------------------------------+---------------------------------+
  6.  | System: OS/2 2.x                                                          |
  7.  +---------------------------------------------------------------------------+
  8.  | Beschreibung:                                                             |
  9.  |                                                                           |
  10.  |   Ausfuehrung eines Suchjobs                                              |
  11.  |                                                                           |
  12.  |                                                                           |
  13.  +---------------------------------------------------------------------------+
  14.  | Bemerkungen:                                                              |
  15.  +---------------------------------------------------------------------------*/
  16.  
  17. /*----------------------------- Header-Dateien ------------------------------*/
  18. #pragma strings(readonly)
  19.  
  20. #define INCL_WIN
  21. #define INCL_BASE
  22. #include <os2.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27. #include <regex.h>
  28.  
  29. #include "main.h"
  30. #include "messages.h"
  31. #include "structs.h"
  32. #include "msgheader.h"
  33. #include "areaman\areaman.h"
  34. #include "handlemsg\handlemsg.h"
  35. #include "handlemsg\kludgeapi.h"
  36. #include "finddlg.h"
  37. #include "util\approx.h"
  38. #include "util\match.h"
  39. #include "markmanage.h"
  40. #include "util\fltutil.h"
  41. #include "utility.h"
  42. #include "dump\expt.h"
  43. #include "findexec.h"
  44.  
  45. /*--------------------------------- Defines ---------------------------------*/
  46.  
  47. /*---------------------------------- Typen ----------------------------------*/
  48.  
  49. typedef int (*CompareFunc)(char *, char *, PFINDJOB);
  50.  
  51. /*---------------------------- Globale Variablen ----------------------------*/
  52.  
  53. extern HWND hwndFindResults;
  54. extern HWND hwndFindDlg;
  55. extern HWND client;
  56. extern volatile BOOL DoingFind;
  57. extern volatile BOOL StopFind;
  58. extern int tidFind;
  59. extern MARKERLIST MarkerList;
  60.  
  61. /*----------------------- interne Funktionsprototypen -----------------------*/
  62. static int FindText(PFINDJOB pFindJob, AREADEFLIST *pAreaDef, CompareFunc pCompareFunc);
  63. static int FindPersmail(PFINDJOB pFindJob, AREADEFLIST *pAreaDef);
  64. static int FindUnsent(PFINDJOB pFindJob, AREADEFLIST *pAreaDef);
  65.  
  66. static int MarkFindAreas(PAREALIST pAreaList, PFINDJOB pFindJob, ULONG ulMask);
  67. static int UnmarkAllAreas(PAREALIST pAreaList, ULONG ulMask);
  68.  
  69. static int SensSearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob);
  70. static int CaseSearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob);
  71. static int FuzzySearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob);
  72. static int RegexSearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob);
  73. static int PrepareRegexSearch(PFINDJOB pFindJob);
  74. static int TerminateRegexSearch(PFINDJOB pFindJob);
  75.  
  76. /*---------------------------------------------------------------------------*/
  77. /* Funktionsname: FindThread2                                                */
  78. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  79. /* Beschreibung: Thread-Funktion fuer's Suchen                               */
  80. /*                                                                           */
  81. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  82. /* Parameter: pParam: Zeiger auf FINDJOB                                     */
  83. /*                                                                           */
  84. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  85. /* Rückgabewerte: -                                                          */
  86. /*                                                                           */
  87. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  88. /* Sonstiges:                                                                */
  89. /*                                                                           */
  90. /*---------------------------------------------------------------------------*/
  91.  
  92. void _Optlink FindThread2(PVOID pParam)
  93. {
  94.    PFINDJOB pFindJob=(PFINDJOB) pParam;
  95.    AREADEFLIST *zeiger=NULL;
  96.    extern AREALIST arealiste;
  97.    extern HAB anchor;
  98.    CompareFunc FindCompareFunc;
  99.    HMQ hmq = NULLHANDLE;
  100.    BOOL bRegOK=TRUE;
  101.  
  102.    INSTALLEXPT("Find");
  103.  
  104.    /* Flag setzen */
  105.    DoingFind=TRUE;
  106.    StopFind=FALSE;
  107.  
  108.    hmq=WinCreateMsgQueue(anchor, 0);
  109.    WinCancelShutdown(hmq, TRUE);
  110.  
  111.  
  112.    if ((pFindJob->ulHow & FINDHOW_METHOD_MASK) == FINDHOW_PERSMAIL)
  113.    {
  114.       SendMsg(client, WORKM_STARTFIND, MPFROMLONG(MARKFLAG_PERSMAIL), NULL);
  115.       MarkFindAreas(&arealiste, pFindJob, WORK_PERSMAIL);
  116.  
  117.       zeiger= arealiste.pFirstArea;
  118.       while(zeiger && !StopFind)
  119.       {
  120.          if (zeiger->flWork & WORK_PERSMAIL)
  121.          {
  122.             FindPersmail(pFindJob, zeiger);
  123.  
  124.             zeiger->flWork &= ~WORK_PERSMAIL;
  125.          }
  126.          zeiger = zeiger->next;
  127.       }
  128.    }
  129.    else
  130.       if ((pFindJob->ulHow & FINDHOW_METHOD_MASK) == FINDHOW_UNSENT)
  131.       {
  132.          SendMsg(client, WORKM_STARTFIND, MPFROMLONG(MARKFLAG_UNSENT), NULL);
  133.          MarkFindAreas(&arealiste, pFindJob, WORK_FIND);
  134.  
  135.          zeiger= arealiste.pFirstArea;
  136.          while(zeiger && !StopFind)
  137.          {
  138.             if (zeiger->flWork & WORK_FIND)
  139.             {
  140.                FindUnsent(pFindJob, zeiger);
  141.  
  142.                zeiger->flWork &= ~WORK_FIND;
  143.             }
  144.             zeiger = zeiger->next;
  145.          }
  146.       }
  147.       else
  148.       {
  149.          SendMsg(client, WORKM_STARTFIND, MPFROMLONG(MARKFLAG_FIND), NULL);
  150.          MarkFindAreas(&arealiste, pFindJob, WORK_FIND);
  151.  
  152.          /* Vergleichsfunktion zuordnen */
  153.          switch(pFindJob->ulHow & FINDHOW_METHOD_MASK)
  154.          {
  155.             case FINDHOW_SENS:
  156.                FindCompareFunc = SensSearch;
  157.                break;
  158.  
  159.             case FINDHOW_CASE:
  160.                FindCompareFunc = CaseSearch;
  161.                break;
  162.  
  163.             case FINDHOW_FUZZY:
  164.                FindCompareFunc = FuzzySearch;
  165.                break;
  166.  
  167.             case FINDHOW_REGEX:
  168.                FindCompareFunc = RegexSearch;
  169.                bRegOK = PrepareRegexSearch(pFindJob);
  170.                break;
  171.  
  172.             default:
  173.                FindCompareFunc = CaseSearch;
  174.                break;
  175.          }
  176.  
  177.          zeiger= arealiste.pFirstArea;
  178.          while(zeiger && !StopFind && bRegOK)
  179.          {
  180.             if (zeiger->flWork & WORK_FIND)
  181.             {
  182.                FindText(pFindJob, zeiger, FindCompareFunc);
  183.  
  184.                zeiger->flWork &= ~WORK_FIND;
  185.             }
  186.             zeiger = zeiger->next;
  187.          }
  188.          if (bRegOK)
  189.             switch(pFindJob->ulHow & FINDHOW_METHOD_MASK)
  190.             {
  191.                case FINDHOW_REGEX:
  192.                   TerminateRegexSearch(pFindJob);
  193.                   break;
  194.             }
  195.       }
  196.  
  197.    UnmarkAllAreas(&arealiste, WORK_FIND | WORK_PERSMAIL);
  198.  
  199.    /* Flag loeschen und Ende */
  200.    DoingFind=FALSE;
  201.    SendMsg(client, WORKM_STOPFIND, NULL, NULL);
  202.  
  203.    if (pFindJob->pchAreas)
  204.       free(pFindJob->pchAreas);
  205.    free(pFindJob);
  206.    WinDestroyMsgQueue(hmq);
  207.  
  208.    DEINSTALLEXPT;
  209.  
  210.    return;
  211. }
  212.  
  213. /*---------------------------------------------------------------------------*/
  214. /* Funktionsname: MarkFindAreas                                              */
  215. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  216. /* Beschreibung: Markiert die zu durchsuchenden Areas                        */
  217. /*                                                                           */
  218. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  219. /* Parameter: pAreaList: Area-Liste                                          */
  220. /*            pFindJob: Zeiger auf Suchjob                                   */
  221. /*            ulMask:   Bitmaske f. Work-Feld                                */
  222. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  223. /* Rückgabewerte: 0                                                          */
  224. /*                                                                           */
  225. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  226. /* Sonstiges:                                                                */
  227. /*                                                                           */
  228. /*---------------------------------------------------------------------------*/
  229.  
  230. static int MarkFindAreas(PAREALIST pAreaList, PFINDJOB pFindJob, ULONG ulMask)
  231. {
  232.    extern char CurrentArea[LEN_AREATAG+1];
  233.  
  234.    AREADEFLIST *zeiger=pAreaList->pFirstArea;
  235.    ULONG ulAreas = pFindJob->ulWAreas & 0x0f;
  236.    ULONG ulThisType=0;
  237.  
  238.    while (zeiger) /* Areas abklappern */
  239.    {
  240.       switch(ulAreas)
  241.       {
  242.          case FINDAREAS_CURRENT:
  243.             if (!stricmp(CurrentArea, zeiger->areadata.areatag))
  244.                zeiger->flWork |= ulMask;
  245.             break;
  246.  
  247.          case FINDAREAS_ALL:
  248.             zeiger->flWork |= ulMask;
  249.             break;
  250.  
  251.          case FINDAREAS_CUSTOMN:
  252.             if (AreaInAreaSet(pFindJob->pchAreas, zeiger->areadata.areatag))
  253.                zeiger->flWork |= ulMask;
  254.             break;
  255.  
  256.          case FINDAREAS_TYPE:
  257.             if (zeiger->areadata.areatype == AREATYPE_LOCAL)
  258.             {
  259.                if (zeiger->areadata.ulAreaOpt & AREAOPT_FROMCFG)
  260.                   ulThisType=FINDAREAS_LOCAL;
  261.                else
  262.                   ulThisType=FINDAREAS_PRIV;
  263.             }
  264.             else
  265.                if (zeiger->areadata.areatype == AREATYPE_ECHO)
  266.                   ulThisType=FINDAREAS_ECHO;
  267.                else
  268.                   ulThisType=FINDAREAS_NM;
  269.  
  270.             if (pFindJob->ulWAreas & ulThisType)
  271.                zeiger->flWork |= ulMask;
  272.             break;
  273.  
  274.          default:
  275.             break;
  276.       }
  277.  
  278.       zeiger = zeiger->next;
  279.    }
  280.  
  281.    return 0;
  282. }
  283.  
  284. /*---------------------------------------------------------------------------*/
  285. /* Funktionsname: UnmarkAllAreas                                             */
  286. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  287. /* Beschreibung: Loescht Flags bei allen Areas                               */
  288. /*                                                                           */
  289. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  290. /* Parameter: pAreaList: Area-Liste                                          */
  291. /*            ulMask: zu loeschende Flags                                    */
  292. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  293. /* Rückgabewerte: 0                                                          */
  294. /*                                                                           */
  295. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  296. /* Sonstiges:                                                                */
  297. /*                                                                           */
  298. /*---------------------------------------------------------------------------*/
  299.  
  300. static int UnmarkAllAreas(PAREALIST pAreaList, ULONG ulMask)
  301. {
  302.    AREADEFLIST *zeiger=pAreaList->pFirstArea;
  303.  
  304.    while (zeiger) /* Areas abklappern */
  305.    {
  306.       zeiger->flWork &= ~ulMask;
  307.  
  308.       zeiger = zeiger->next;
  309.    }
  310.  
  311.    return 0;
  312. }
  313.  
  314.  
  315. /*---------------------------------------------------------------------------*/
  316. /* Funktionsname: FindText                                                   */
  317. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  318. /* Beschreibung: Sucht nach Text in einer Area                               */
  319. /*                                                                           */
  320. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  321. /* Parameter: pFindJob: Zeiger auf Suchjob                                   */
  322. /*            pAreaDef: Zu durchsuchende Area                                */
  323. /*            pCompareFunc: Zeiger auf Vergleichsfunktion                    */
  324. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  325. /* Rückgabewerte: 0                                                          */
  326. /*                                                                           */
  327. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  328. /* Sonstiges:                                                                */
  329. /*                                                                           */
  330. /*---------------------------------------------------------------------------*/
  331.  
  332. static int FindText(PFINDJOB pFindJob, AREADEFLIST *pAreaDef, CompareFunc pCompareFunc)
  333. {
  334.    extern AREALIST arealiste;
  335.    extern char CurrentArea[LEN_AREATAG+1];
  336.    extern MISCOPTIONS miscoptions;
  337.    extern DRIVEREMAP driveremap;
  338.    MSGHEADER Header;
  339.    FTNMESSAGE Message;
  340.    ULONG ulMsgNum;
  341.    BOOL FoundIt=FALSE;
  342.    FINDRESULTLIST ResultList;
  343.    PFOUNDMSG pFoundMsg=NULL;
  344.    PFOUNDMSG pFoundList=NULL;
  345.  
  346.    memset(&Message, 0, sizeof(Message));
  347.  
  348.    if (!MSG_OpenArea(&arealiste, pAreaDef->areadata.areatag, miscoptions.lastreadoffset, &driveremap))
  349.    {
  350.       /* Area-Tag anzeigen */
  351.       SendMsg(client, WORKM_FINDAREA, pAreaDef->areadata.areatag, NULL);
  352.  
  353.       memset(&ResultList, 0, sizeof(ResultList));
  354.       strcpy(ResultList.pchAreaTag, pAreaDef->areadata.areatag);
  355.       ResultList.ulFindType = MARKFLAG_FIND;
  356.  
  357.       for (ulMsgNum=1; ulMsgNum<=pAreaDef->maxmessages && !StopFind; ulMsgNum++)
  358.       {
  359.          FoundIt=FALSE;
  360.  
  361.          if (!(pFindJob->ulWhere & FINDWHERE_TEXT))
  362.          {
  363.             /* Nur Header */
  364.             if (MSG_ReadHeader(&Header, &arealiste, pAreaDef->areadata.areatag, ulMsgNum))
  365.                continue;
  366.          }
  367.          else
  368.             /* gesamte Message lesen */
  369.             if (MSG_ReadNum(&Message, &Header, &arealiste, pAreaDef->areadata.areatag, ulMsgNum))
  370.                continue;
  371.  
  372.          if (!(pFindJob->ulHow & FINDHOW_UNREADONLY) || !(Header.ulAttrib & ATTRIB_READ))
  373.          {
  374.             if (pFindJob->ulWhere & FINDWHERE_FROM)
  375.                FoundIt = pCompareFunc(Header.pchFromName, pFindJob->pchWhat, pFindJob);
  376.  
  377.             if (!FoundIt && (pFindJob->ulWhere & FINDWHERE_TO))
  378.                FoundIt = pCompareFunc(Header.pchToName, pFindJob->pchWhat, pFindJob);
  379.  
  380.             if (!FoundIt && (pFindJob->ulWhere & FINDWHERE_SUBJ))
  381.                FoundIt = pCompareFunc(Header.pchSubject, pFindJob->pchWhat, pFindJob);
  382.  
  383.             if (!FoundIt && (pFindJob->ulWhere & FINDWHERE_TEXT))
  384.                FoundIt = pCompareFunc(Message.pchMessageText, pFindJob->pchWhat, pFindJob);
  385.  
  386.             if (FoundIt && hwndFindResults)
  387.             {
  388.                ULONG ulMsgID = MSG_MsgnToUid(&arealiste, pAreaDef->areadata.areatag, ulMsgNum);
  389.  
  390.                /* In Markerliste aufnehmen */
  391.                if (MarkMessage(&MarkerList, pAreaDef->areadata.areatag, ulMsgID,
  392.                                ulMsgNum, &Header, pFindJob->pchWhat, MARKFLAG_FIND, pFindJob->ulHow, pFindJob->ulWhere)==0)
  393.                {
  394.                   /* Ergebnis einketten */
  395.                   if (pFoundMsg)
  396.                   {
  397.                      pFoundMsg->next = calloc(1, sizeof(FOUNDMSG));
  398.                      pFoundMsg = pFoundMsg->next;
  399.                   }
  400.                   else
  401.                   {
  402.                      pFoundList = calloc(1, sizeof(FOUNDMSG));
  403.                      pFoundMsg = pFoundList;
  404.                   }
  405.                   pFoundMsg->Header = Header;
  406.                   pFoundMsg->ulMsgID = ulMsgID;
  407.                   pFoundMsg->ulMsgNum = ulMsgNum;
  408.                   pFoundMsg->ulHow    = pFindJob->ulHow;
  409.                   pFoundMsg->ulWhere  = pFindJob->ulWhere;
  410.                   pFoundMsg->pchFindText= pFindJob->pchWhat;
  411.                   ResultList.ulFoundMsgs++;
  412.                }
  413.             }
  414.          }
  415.  
  416.          /* Laufbalken ab und zu updaten */
  417.          if (ulMsgNum % 10 == 0)
  418.             SendMsg(client, WORKM_FINDPROGRESS,
  419.                        MPFROMLONG(pAreaDef->maxmessages?(100 * ulMsgNum / pAreaDef->maxmessages):100),
  420.                        NULL);
  421.       }
  422.  
  423.       /* Suchergebnis in Dialog einfuegen */
  424.       if (ResultList.ulFoundMsgs)
  425.          SendMsg(client, WORKM_FINDAREAEND, &ResultList, pFoundList);
  426.  
  427.       while (pFoundList)
  428.       {
  429.          pFoundMsg = pFoundList;
  430.          pFoundList = pFoundList->next;
  431.          free(pFoundMsg);
  432.       }
  433.  
  434.       /* Aufraeumen */
  435.       MSG_ClearMessage(&Header, &Message);
  436.  
  437.       MSG_CloseArea(&arealiste, pAreaDef->areadata.areatag, FALSE, miscoptions.lastreadoffset, &driveremap);
  438.    }
  439.    return 0;
  440. }
  441.  
  442. /*---------------------------------------------------------------------------*/
  443. /* Funktionsname: FindPersmail                                               */
  444. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  445. /* Beschreibung: Fuehrt den Personal Mail Scan in einer Area durch           */
  446. /*                                                                           */
  447. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  448. /* Parameter: pFindJob: Such-Job-Parameter                                   */
  449. /*            pAreaDef: Zeiger auf Area-Definition                           */
  450. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  451. /* Rückgabewerte: 0  OK                                                      */
  452. /*                1  Fehler                                                  */
  453. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  454. /* Sonstiges:                                                                */
  455. /*                                                                           */
  456. /*---------------------------------------------------------------------------*/
  457.  
  458. static int FindPersmail(PFINDJOB pFindJob, AREADEFLIST *pAreaDef)
  459. {
  460.    extern MISCOPTIONS miscoptions;
  461.    extern USERDATAOPT userdaten;
  462.    extern DRIVEREMAP driveremap;
  463.    extern AREALIST arealiste;
  464.    MSGHEADER Header;
  465.    BOOL FoundIt=FALSE;
  466.    ULONG ulMsgNum;
  467.    FINDRESULTLIST ResultList;
  468.    PFOUNDMSG pFoundMsg=NULL;
  469.    PFOUNDMSG pFoundList=NULL;
  470.  
  471.    if (!MSG_OpenArea(&arealiste, pAreaDef->areadata.areatag, miscoptions.lastreadoffset, &driveremap))
  472.    {
  473.       /* Area-Tag anzeigen */
  474.       SendMsg(client, WORKM_FINDAREA, pAreaDef->areadata.areatag, NULL);
  475.  
  476.       memset(&ResultList, 0, sizeof(ResultList));
  477.       strcpy(ResultList.pchAreaTag, pAreaDef->areadata.areatag);
  478.       ResultList.ulFindType = MARKFLAG_PERSMAIL;
  479.  
  480.       if (pFindJob->PersMailOpt.bAllMsgs)
  481.          ulMsgNum=1;
  482.       else
  483.          ulMsgNum= pAreaDef->currentmessage+1;
  484.  
  485.       for ( ; ulMsgNum<=pAreaDef->maxmessages && !StopFind; ulMsgNum++)
  486.       {
  487.          FoundIt=FALSE;
  488.  
  489.          /* Laufbalken ab und zu updaten */
  490.          if (ulMsgNum % 10 == 0)
  491.             SendMsg(client, WORKM_FINDPROGRESS,
  492.                        MPFROMLONG(pAreaDef->maxmessages?(100 * ulMsgNum / pAreaDef->maxmessages):100),
  493.                        NULL);
  494.  
  495.          if (!MSG_ReadHeader(&Header, &arealiste, pAreaDef->areadata.areatag, ulMsgNum))
  496.          {
  497.             /* evtl. gelesene Messages uebergehen */
  498.             if ((pFindJob->ulHow & FINDHOW_UNREADONLY) && (Header.ulAttrib & ATTRIB_READ))
  499.                continue;
  500.  
  501.             if (pFindJob->PersMailOpt.bAllNames)
  502.             {
  503.                int i=0;
  504.                while (i < MAX_USERNAMES && userdaten.username[i][0] &&
  505.                       stricmp(Header.pchToName, userdaten.username[i]))
  506.                   i++;
  507.                if (i < MAX_USERNAMES && userdaten.username[i][0])
  508.                   FoundIt = TRUE;
  509.             }
  510.             else
  511.                FoundIt = Header.pchToName[0]?(!stricmp(Header.pchToName, pAreaDef->areadata.username)):FALSE;
  512.  
  513.             if (FoundIt && hwndFindResults)
  514.             {
  515.                ULONG ulMsgID = MSG_MsgnToUid(&arealiste, pAreaDef->areadata.areatag, ulMsgNum);
  516.  
  517.                /* In Markerliste aufnehmen */
  518.                if (MarkMessage(&MarkerList, pAreaDef->areadata.areatag, ulMsgID,
  519.                                ulMsgNum, &Header, NULL, MARKFLAG_PERSMAIL, pFindJob->ulHow, pFindJob->ulWhere)==0)
  520.                {
  521.                   /* Ergebnis einketten */
  522.                   if (pFoundMsg)
  523.                   {
  524.                      pFoundMsg->next = calloc(1, sizeof(FOUNDMSG));
  525.                      pFoundMsg = pFoundMsg->next;
  526.                   }
  527.                   else
  528.                   {
  529.                      pFoundList = calloc(1, sizeof(FOUNDMSG));
  530.                      pFoundMsg = pFoundList;
  531.                   }
  532.                   pFoundMsg->Header = Header;
  533.                   pFoundMsg->ulMsgID = ulMsgID;
  534.                   pFoundMsg->ulMsgNum = ulMsgNum;
  535.                   pFoundMsg->ulHow    = pFindJob->ulHow;
  536.                   pFoundMsg->ulWhere  = pFindJob->ulWhere;
  537.                   pFoundMsg->pchFindText= NULL;
  538.                   ResultList.ulFoundMsgs++;
  539.                }
  540.             }
  541.          }
  542.       }
  543.       /* Suchergebnis in Dialog einfuegen */
  544.       if (ResultList.ulFoundMsgs)
  545.          SendMsg(client, WORKM_FINDAREAEND, &ResultList, pFoundList);
  546.  
  547.       while (pFoundList)
  548.       {
  549.          pFoundMsg = pFoundList;
  550.          pFoundList = pFoundList->next;
  551.          free(pFoundMsg);
  552.       }
  553.  
  554.       MSG_CloseArea(&arealiste, pAreaDef->areadata.areatag, FALSE, miscoptions.lastreadoffset, &driveremap);
  555.    }
  556.  
  557.    return 0;
  558. }
  559.  
  560. /*---------------------------------------------------------------------------*/
  561. /* Funktionsname: FindUnsent                                                 */
  562. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  563. /* Beschreibung: Fuehrt die Suche nach ungesendeten Messages in einer Area   */
  564. /*               durch                                                       */
  565. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  566. /* Parameter: pFindJob: Such-Job-Parameter                                   */
  567. /*            pAreaDef: Zeiger auf Area-Definition                           */
  568. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  569. /* Rückgabewerte: 0  OK                                                      */
  570. /*                1  Fehler                                                  */
  571. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  572. /* Sonstiges:                                                                */
  573. /*                                                                           */
  574. /*---------------------------------------------------------------------------*/
  575.  
  576. static int FindUnsent(PFINDJOB pFindJob, AREADEFLIST *pAreaDef)
  577. {
  578.    extern MISCOPTIONS miscoptions;
  579.    extern USERDATAOPT userdaten;
  580.    extern DRIVEREMAP driveremap;
  581.    extern AREALIST arealiste;
  582.    MSGHEADER Header;
  583.    ULONG ulMsgNum;
  584.    FINDRESULTLIST ResultList;
  585.    PFOUNDMSG pFoundMsg=NULL;
  586.    PFOUNDMSG pFoundList=NULL;
  587.  
  588.    if (!MSG_OpenArea(&arealiste, pAreaDef->areadata.areatag, miscoptions.lastreadoffset, &driveremap))
  589.    {
  590.       /* Area-Tag anzeigen */
  591.       SendMsg(client, WORKM_FINDAREA, pAreaDef->areadata.areatag, NULL);
  592.  
  593.       memset(&ResultList, 0, sizeof(ResultList));
  594.       strcpy(ResultList.pchAreaTag, pAreaDef->areadata.areatag);
  595.       ResultList.ulFindType = MARKFLAG_UNSENT;
  596.  
  597.       for (ulMsgNum=1 ; ulMsgNum<=pAreaDef->maxmessages && !StopFind; ulMsgNum++)
  598.       {
  599.          /* Laufbalken ab und zu updaten */
  600.          if (ulMsgNum % 10 == 0)
  601.             SendMsg(client, WORKM_FINDPROGRESS,
  602.                        MPFROMLONG(pAreaDef->maxmessages?(100 * ulMsgNum / pAreaDef->maxmessages):100),
  603.                        NULL);
  604.  
  605.          if (!MSG_ReadHeader(&Header, &arealiste, pAreaDef->areadata.areatag, ulMsgNum))
  606.          {
  607.             /* evtl. gesendete Messages uebergehen */
  608.             if (!(Header.ulAttrib & ATTRIB_LOCAL) ||
  609.                 (Header.ulAttrib & (ATTRIB_SENT | ATTRIB_SCANNED)))
  610.                continue;
  611.  
  612.             if (hwndFindResults)
  613.             {
  614.                ULONG ulMsgID = MSG_MsgnToUid(&arealiste, pAreaDef->areadata.areatag, ulMsgNum);
  615.  
  616.                /* In Markerliste aufnehmen */
  617.                if (MarkMessage(&MarkerList, pAreaDef->areadata.areatag, ulMsgID,
  618.                                ulMsgNum, &Header, NULL, MARKFLAG_UNSENT, pFindJob->ulHow, pFindJob->ulWhere)==0)
  619.                {
  620.                   /* Ergebnis einketten */
  621.                   if (pFoundMsg)
  622.                   {
  623.                      pFoundMsg->next = calloc(1, sizeof(FOUNDMSG));
  624.                      pFoundMsg = pFoundMsg->next;
  625.                   }
  626.                   else
  627.                   {
  628.                      pFoundList = calloc(1, sizeof(FOUNDMSG));
  629.                      pFoundMsg = pFoundList;
  630.                   }
  631.                   pFoundMsg->Header = Header;
  632.                   pFoundMsg->ulMsgID = ulMsgID;
  633.                   pFoundMsg->ulMsgNum = ulMsgNum;
  634.                   pFoundMsg->ulHow    = pFindJob->ulHow;
  635.                   pFoundMsg->ulWhere  = pFindJob->ulWhere;
  636.                   pFoundMsg->pchFindText= NULL;
  637.                   ResultList.ulFoundMsgs++;
  638.                }
  639.             }
  640.          }
  641.       }
  642.       /* Suchergebnis in Dialog einfuegen */
  643.       if (ResultList.ulFoundMsgs)
  644.          SendMsg(client, WORKM_FINDAREAEND, &ResultList, pFoundList);
  645.  
  646.       while (pFoundList)
  647.       {
  648.          pFoundMsg = pFoundList;
  649.          pFoundList = pFoundList->next;
  650.          free(pFoundMsg);
  651.       }
  652.  
  653.       MSG_CloseArea(&arealiste, pAreaDef->areadata.areatag, FALSE, miscoptions.lastreadoffset, &driveremap);
  654.    }
  655.  
  656.    return 0;
  657. }
  658.  
  659. static int SensSearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob)
  660. {
  661.    pFindJob = pFindJob;
  662.  
  663.    return (int) strstr(pchHaystack, pchNeedle);
  664. }
  665.  
  666. static int CaseSearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob)
  667. {
  668.    pFindJob = pFindJob;
  669.  
  670.    return (int) stristr(pchHaystack, pchNeedle);
  671. }
  672.  
  673. static int FuzzySearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob)
  674. {
  675.    char *pchStart=pchHaystack;
  676.    char *pchEnd=NULL;
  677.    int howclose;
  678.  
  679.    Fuzz_init(pchNeedle, pchHaystack, pFindJob->ulFuzzyLevel);
  680.    Fuzz_next(&pchStart, &pchEnd, &howclose);
  681.    Fuzz_term();
  682.  
  683.    if (pchStart)
  684.       return 1;
  685.    else
  686.       return 0;
  687. }
  688.  
  689. static int RegexSearch(char *pchHaystack, char *pchNeedle, PFINDJOB pFindJob)
  690. {
  691.    pchNeedle = pchNeedle;
  692.  
  693.    return !regexec(pFindJob->pOptData, pchHaystack, 0, NULL, 0);
  694. }
  695.  
  696. static int PrepareRegexSearch(PFINDJOB pFindJob)
  697. {
  698.    pFindJob->pOptData = malloc(sizeof(regex_t));
  699.    if (regcomp(pFindJob->pOptData, pFindJob->pchWhat, REG_EXTENDED|REG_NEWLINE|REG_ICASE))
  700.    {
  701.       free(pFindJob->pOptData);
  702.       return FALSE;
  703.    }
  704.    return TRUE;
  705. }
  706.  
  707. static int TerminateRegexSearch(PFINDJOB pFindJob)
  708. {
  709.    regfree(pFindJob->pOptData);
  710.    free(pFindJob->pOptData);
  711.    return TRUE;
  712. }
  713.  
  714. /*-------------------------------- Modulende --------------------------------*/
  715.  
  716.