3 ScanTree::ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs)
5 ScanTree::FileMasks=FileMasks;
6 ScanTree::Recurse=Recurse;
7 ScanTree::GetLinks=GetLinks;
8 ScanTree::GetDirs=GetDirs;
13 memset(FindStack,0,sizeof(FindStack));
24 for (int I=Depth;I>=0;I--)
25 if (FindStack[I]!=NULL)
30 int ScanTree::GetNext(FindData *FindData)
38 if ((*CurMask==0 || FastFindFile && Depth==0) && !PrepareMasks())
40 FindCode=FindProc(FindData);
41 if (FindCode==SCAN_ERROR)
46 if (FindCode==SCAN_NEXT)
48 if (FindCode==SCAN_SUCCESS && FindData->IsDir && GetDirs==SCAN_SKIPDIRS)
50 if (FindCode==SCAN_DONE && PrepareMasks())
58 bool ScanTree::PrepareMasks()
60 if (!FileMasks->GetString(CurMask,CurMaskW,sizeof(CurMask)))
63 UnixSlashToDos(CurMask);
65 char *Name=PointToName(CurMask);
67 strcat(CurMask,MASKALL);
68 if (Name[0]=='.' && (Name[1]==0 || Name[1]=='.' && Name[2]==0))
71 strcat(CurMask,MASKALL);
73 SpecPathLength=Name-CurMask;
74 // if (SpecPathLength>1)
77 bool WideName=(*CurMaskW!=0);
81 wchar *NameW=PointToName(CurMaskW);
83 strcatw(CurMaskW,MASKALLW);
84 if (NameW[0]=='.' && (NameW[1]==0 || NameW[1]=='.' && NameW[2]==0))
86 AddEndSlash(CurMaskW);
87 strcatw(CurMaskW,MASKALLW);
89 SpecPathLengthW=NameW-CurMaskW;
94 CharToWide(CurMask,WideMask);
95 SpecPathLengthW=PointToName(WideMask)-WideMask;
99 strcpy(OrigCurMask,CurMask);
100 strcpyw(OrigCurMaskW,CurMaskW);
106 int ScanTree::FindProc(FindData *FindData)
111 if (FindStack[Depth]==NULL)
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);
119 SearchAllInRoot=SearchAll;
120 if (SearchAll || Wildcards)
122 FindStack[Depth]=new FindFile;
124 strcpy(SearchMask,CurMask);
126 strcpy(PointToName(SearchMask),MASKALL);
127 FindStack[Depth]->SetMask(SearchMask);
130 wchar SearchMaskW[NM];
131 strcpyw(SearchMaskW,CurMaskW);
133 strcpyw(PointToName(SearchMaskW),MASKALLW);
134 FindStack[Depth]->SetMaskW(SearchMaskW);
142 if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
144 ErrHandler.OpenErrorMsg(ErrArcName,CurMask);
145 return(FindData->Error ? SCAN_ERROR:SCAN_NEXT);
150 if (!FastFindFile && !FindStack[Depth]->Next(FindData,GetLinks))
152 bool Error=FindData->Error;
155 if (Error && strstr(CurMask,"System Volume Information\\")!=NULL)
159 if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
165 Log(NULL,St(MScanError),CurMask);
174 delete FindStack[Depth];
175 FindStack[Depth--]=NULL;
176 while (Depth>=0 && FindStack[Depth]==NULL)
184 char *Slash=strrchrd(CurMask,CPATHDIVIDER);
189 if (Depth<SetAllMaskDepth)
190 strcpy(Mask+1,PointToName(OrigCurMask));
192 strcpy(DirName,CurMask);
193 char *PrevSlash=strrchrd(CurMask,CPATHDIVIDER);
195 strcpy(CurMask,Mask+1);
197 strcpy(PrevSlash,Mask);
202 wchar *Slash=strrchrw(CurMaskW,CPATHDIVIDER);
207 if (Depth<SetAllMaskDepth)
208 strcpyw(Mask+1,PointToName(OrigCurMaskW));
210 strcpyw(DirNameW,CurMaskW);
211 wchar *PrevSlash=strrchrw(CurMaskW,CPATHDIVIDER);
213 strcpyw(CurMaskW,Mask+1);
215 strcpyw(PrevSlash,Mask);
218 if (LowAscii(CurMaskW))
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);
230 if (!FastFindFile && Depth==0 && !SearchAllInRoot)
231 return(GetDirs==SCAN_GETCURDIRS ? SCAN_SUCCESS:SCAN_NEXT);
233 // if (GetDirs==SCAN_GETCURDIRS && Depth==0 && !SearchAllInRoot)
234 // return(SCAN_SUCCESS);
237 bool MaskAll=FastFindFile;
239 // bool MaskAll=CmpName(CurMask,FindData->Name,MATCH_NAMES);
241 strcpy(Mask,MaskAll ? MASKALL:PointToName(CurMask));
242 strcpy(CurMask,FindData->Name);
244 if (strlen(CurMask)+strlen(Mask)+1>=NM || Depth>=MAXSCANDEPTH-1)
247 Log(NULL,"\n%s%c%s",CurMask,CPATHDIVIDER,Mask);
248 Log(NULL,St(MPathTooLong));
253 AddEndSlash(CurMask);
254 strcat(CurMask,Mask);
256 if (*CurMaskW && *FindData->NameW==0)
257 CharToWide(FindData->Name,FindData->NameW);
258 if (*FindData->NameW!=0)
262 strcpyw(Mask,MASKALLW);
265 strcpyw(Mask,PointToName(CurMaskW));
267 CharToWide(PointToName(CurMask),Mask);
268 strcpyw(CurMaskW,FindData->NameW);
269 AddEndSlash(CurMaskW);
270 strcatw(CurMaskW,Mask);
274 SetAllMaskDepth=Depth;
276 if (!FastFindFile && !CmpName(CurMask,FindData->Name,MATCH_NAMES))
278 return(SCAN_SUCCESS);