home *** CD-ROM | disk | FTP | other *** search
/ ftp.rarlab.com / 2014.05.ftp.rarlab.com.tar / ftp.rarlab.com / rar / unrar_vms_alpha-3.6.5.zip / scantree.cxx < prev    next >
C/C++ Source or Header  |  2006-06-27  |  7KB  |  280 lines

  1. #include "rar.hpp"
  2.  
  3. ScanTree::ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs)
  4. {
  5.   ScanTree::FileMasks=FileMasks;
  6.   ScanTree::Recurse=Recurse;
  7.   ScanTree::GetLinks=GetLinks;
  8.   ScanTree::GetDirs=GetDirs;
  9.  
  10.   SetAllMaskDepth=0;
  11.   *CurMask=0;
  12.   *CurMaskW=0;
  13.   memset(FindStack,0,sizeof(FindStack));
  14.   Depth=0;
  15.   Errors=0;
  16.   FastFindFile=false;
  17.   *ErrArcName=0;
  18.   Cmd=NULL;
  19. }
  20.  
  21.  
  22. ScanTree::~ScanTree()
  23. {
  24.   for (int I=Depth;I>=0;I--)
  25.     if (FindStack[I]!=NULL)
  26.       delete FindStack[I];
  27. }
  28.  
  29.  
  30. int ScanTree::GetNext(FindData *FindData)
  31. {
  32.   if (Depth<0)
  33.     return(SCAN_DONE);
  34.  
  35.   int FindCode;
  36.   while (1)
  37.   {
  38.     if ((*CurMask==0 || FastFindFile && Depth==0) && !PrepareMasks())
  39.       return(SCAN_DONE);
  40.     FindCode=FindProc(FindData);
  41.     if (FindCode==SCAN_ERROR)
  42.     {
  43.       Errors++;
  44.       continue;
  45.     }
  46.     if (FindCode==SCAN_NEXT)
  47.       continue;
  48.     if (FindCode==SCAN_SUCCESS && FindData->IsDir && GetDirs==SCAN_SKIPDIRS)
  49.       continue;
  50.     if (FindCode==SCAN_DONE && PrepareMasks())
  51.       continue;
  52.     break;
  53.   }
  54.   return(FindCode);
  55. }
  56.  
  57.  
  58. bool ScanTree::PrepareMasks()
  59. {
  60.   if (!FileMasks->GetString(CurMask,CurMaskW,sizeof(CurMask)))
  61.     return(false);
  62. #ifdef _WIN_32
  63.   UnixSlashToDos(CurMask);
  64. #endif
  65.   char *Name=PointToName(CurMask);
  66.   if (*Name==0)
  67.     strcat(CurMask,MASKALL);
  68.   if (Name[0]=='.' && (Name[1]==0 || Name[1]=='.' && Name[2]==0))
  69.   {
  70.     AddEndSlash(CurMask);
  71.     strcat(CurMask,MASKALL);
  72.   }
  73.   SpecPathLength=Name-CurMask;
  74. //  if (SpecPathLength>1)
  75. //    SpecPathLength--;
  76.  
  77.   bool WideName=(*CurMaskW!=0);
  78.  
  79.   if (WideName)
  80.   {
  81.     wchar *NameW=PointToName(CurMaskW);
  82.     if (*NameW==0)
  83.       strcatw(CurMaskW,(const wchar *)MASKALLW);
  84.     if (NameW[0]=='.' && (NameW[1]==0 || NameW[1]=='.' && NameW[2]==0))
  85.     {
  86.       AddEndSlash(CurMaskW);
  87.       strcatw(CurMaskW,(const wchar *)MASKALLW);
  88.     }
  89.     SpecPathLengthW=NameW-CurMaskW;
  90.   }
  91.   else
  92.   {
  93.     wchar WideMask[NM];
  94.     CharToWide(CurMask,WideMask);
  95.     SpecPathLengthW=PointToName(WideMask)-WideMask;
  96.   }
  97.   Depth=0;
  98.  
  99.   strcpy(OrigCurMask,CurMask);
  100.   strcpyw(OrigCurMaskW,CurMaskW);
  101.  
  102.   return(true);
  103. }
  104.  
  105.  
  106. int ScanTree::FindProc(FindData *FindData)
  107. {
  108.   if (*CurMask==0)
  109.     return(SCAN_NEXT);
  110.   FastFindFile=false;
  111.   if (FindStack[Depth]==NULL)
  112.   {
  113.     bool Wildcards=IsWildcard(CurMask,CurMaskW);
  114.     bool FindCode=!Wildcards && FindFile::FastFind(CurMask,CurMaskW,FindData,GetLinks);
  115.     bool IsDir=FindCode && FindData->IsDir;
  116.     bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS ||
  117.                    Wildcards && Recurse==RECURSE_WILDCARDS);
  118.     if (Depth==0)
  119.       SearchAllInRoot=SearchAll;
  120.     if (SearchAll || Wildcards)
  121.     {
  122.       FindStack[Depth]=new FindFile;
  123.       char SearchMask[NM];
  124.       strcpy(SearchMask,CurMask);
  125.       if (SearchAll)
  126.         strcpy(PointToName(SearchMask),MASKALL);
  127.       FindStack[Depth]->SetMask(SearchMask);
  128.       if (*CurMaskW)
  129.       {
  130.         wchar SearchMaskW[NM];
  131.         strcpyw(SearchMaskW,CurMaskW);
  132.         if (SearchAll)
  133.           strcpyw(PointToName(SearchMaskW),(const wchar *)MASKALLW);
  134.         FindStack[Depth]->SetMaskW(SearchMaskW);
  135.       }
  136.     }
  137.     else
  138.     {
  139.       FastFindFile=true;
  140.       if (!FindCode)
  141.       {
  142.         if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
  143.           return(SCAN_NEXT);
  144.         ErrHandler.OpenErrorMsg(ErrArcName,CurMask);
  145.         return(FindData->Error ? SCAN_ERROR:SCAN_NEXT);
  146.       }
  147.     }
  148.   }
  149.  
  150.   if (!FastFindFile && !FindStack[Depth]->Next(FindData,GetLinks))
  151.   {
  152.     bool Error=FindData->Error;
  153.  
  154. #ifdef _WIN_32
  155.     if (Error && strstr(CurMask,"System Volume Information\\")!=NULL)
  156.       Error=false;
  157. #endif
  158.  
  159.     if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
  160.       Error=false;
  161.  
  162. #ifndef SILENT
  163.     if (Error)
  164.     {
  165.       Log(NULL,St(MScanError),CurMask);
  166.     }
  167. #endif
  168.  
  169.     char DirName[NM];
  170.     wchar DirNameW[NM];
  171.     *DirName=0;
  172.     *DirNameW=0;
  173.  
  174.     delete FindStack[Depth];
  175.     FindStack[Depth--]=NULL;
  176.     while (Depth>=0 && FindStack[Depth]==NULL)
  177.       Depth--;
  178.     if (Depth < 0)
  179.     {
  180.       if (Error)
  181.         Errors++;
  182.       return(SCAN_DONE);
  183.     }
  184.     char *Slash=strrchrd(CurMask,CPATHDIVIDER);
  185.     if (Slash!=NULL)
  186.     {
  187.       char Mask[NM];
  188.       strcpy(Mask,Slash);
  189.       if (Depth<SetAllMaskDepth)
  190.         strcpy(Mask+1,PointToName(OrigCurMask));
  191.       *Slash=0;
  192.       strcpy(DirName,CurMask);
  193.       char *PrevSlash=strrchrd(CurMask,CPATHDIVIDER);
  194.       if (PrevSlash==NULL)
  195.         strcpy(CurMask,Mask+1);
  196.       else
  197.         strcpy(PrevSlash,Mask);
  198.     }
  199.  
  200.     if (*CurMaskW!=0)
  201.     {
  202.       wchar *Slash=strrchrw(CurMaskW,CPATHDIVIDER);
  203.       if (Slash!=NULL)
  204.       {
  205.         wchar Mask[NM];
  206.         strcpyw(Mask,Slash);
  207.         if (Depth<SetAllMaskDepth)
  208.           strcpyw(Mask+1,PointToName(OrigCurMaskW));
  209.         *Slash=0;
  210.         strcpyw(DirNameW,CurMaskW);
  211.         wchar *PrevSlash=strrchrw(CurMaskW,CPATHDIVIDER);
  212.         if (PrevSlash==NULL)
  213.           strcpyw(CurMaskW,Mask+1);
  214.         else
  215.           strcpyw(PrevSlash,Mask);
  216.       }
  217. #ifndef _WIN_CE
  218.       if (LowAscii(CurMaskW))
  219.         *CurMaskW=0;
  220. #endif
  221.     }
  222.     if (GetDirs==SCAN_GETDIRSTWICE &&
  223.         FindFile::FastFind(DirName,DirNameW,FindData,GetLinks) && FindData->IsDir)
  224.       return(Error ? SCAN_ERROR:SCAN_SUCCESS);
  225.     return(Error ? SCAN_ERROR:SCAN_NEXT);
  226.   }
  227.  
  228.   if (FindData->IsDir)
  229.   {
  230.     if (!FastFindFile && Depth==0 && !SearchAllInRoot)
  231.       return(GetDirs==SCAN_GETCURDIRS ? SCAN_SUCCESS:SCAN_NEXT);
  232.  
  233. //    if (GetDirs==SCAN_GETCURDIRS && Depth==0 && !SearchAllInRoot)
  234. //      return(SCAN_SUCCESS);
  235.  
  236.     char Mask[NM];
  237.     bool MaskAll=FastFindFile;
  238.  
  239. //    bool MaskAll=CmpName(CurMask,FindData->Name,MATCH_NAMES);
  240.  
  241.     strcpy(Mask,MaskAll ? MASKALL:PointToName(CurMask));
  242.     strcpy(CurMask,FindData->Name);
  243.  
  244.     if (strlen(CurMask)+strlen(Mask)+1>=NM || Depth>=MAXSCANDEPTH-1)
  245.     {
  246. #ifndef SILENT
  247.       Log(NULL,"\n%s%c%s",CurMask,CPATHDIVIDER,Mask);
  248.       Log(NULL,St(MPathTooLong));
  249. #endif
  250.       return(SCAN_ERROR);
  251.     }
  252.  
  253.     AddEndSlash(CurMask);
  254.     strcat(CurMask,Mask);
  255.  
  256.     if (*CurMaskW && *FindData->NameW==0)
  257.       CharToWide(FindData->Name,FindData->NameW);
  258.     if (*FindData->NameW!=0)
  259.     {
  260.       wchar Mask[NM];
  261.       if (FastFindFile)
  262.         strcpyw(Mask,(const wchar *)MASKALLW);
  263.       else
  264.         if (*CurMaskW)
  265.           strcpyw(Mask,PointToName(CurMaskW));
  266.         else
  267.           CharToWide(PointToName(CurMask),Mask);
  268.       strcpyw(CurMaskW,FindData->NameW);
  269.       AddEndSlash(CurMaskW);
  270.       strcatw(CurMaskW,Mask);
  271.     }
  272.     Depth++;
  273.     if (MaskAll)
  274.       SetAllMaskDepth=Depth;
  275.   }
  276.   if (!FastFindFile && !CmpName(CurMask,FindData->Name,MATCH_NAMES))
  277.     return(SCAN_NEXT);
  278.   return(SCAN_SUCCESS);
  279. }
  280.