1 #include "rar.hpp"
2 
FindFile()3 FindFile::FindFile()
4 {
5   *FindMask=0;
6   *FindMaskW=0;
7   FirstCall=true;
8 #ifdef _WIN_32
9   hFind=INVALID_HANDLE_VALUE;
10 #else
11   dirp=NULL;
12 #endif
13 }
14 
15 
~FindFile()16 FindFile::~FindFile()
17 {
18 #ifdef _WIN_32
19   if (hFind!=INVALID_HANDLE_VALUE)
20     FindClose(hFind);
21 #else
22   if (dirp!=NULL)
23     closedir(dirp);
24 #endif
25 }
26 
27 
SetMask(const char * FindMask)28 void FindFile::SetMask(const char *FindMask)
29 {
30   strcpy(FindFile::FindMask,FindMask);
31   if (*FindMaskW==0)
32     CharToWide(FindMask,FindMaskW);
33   FirstCall=true;
34 }
35 
36 
SetMaskW(const wchar * FindMaskW)37 void FindFile::SetMaskW(const wchar *FindMaskW)
38 {
39   if (FindMaskW==NULL)
40     return;
41   strcpyw(FindFile::FindMaskW,FindMaskW);
42   if (*FindMask==0)
43     WideToChar(FindMaskW,FindMask);
44   FirstCall=true;
45 }
46 
47 
Next(struct FindData * fd,bool GetSymLink)48 bool FindFile::Next(struct FindData *fd,bool GetSymLink)
49 {
50   fd->Error=false;
51   if (*FindMask==0)
52     return(false);
53 #ifdef _WIN_32
54   if (FirstCall)
55   {
56     if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE)
57       return(false);
58   }
59   else
60     if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE)
61       return(false);
62 #else
63   if (FirstCall)
64   {
65     char DirName[NM];
66     strcpy(DirName,FindMask);
67     RemoveNameFromPath(DirName);
68     if (*DirName==0)
69       strcpy(DirName,".");
70 /*
71     else
72     {
73       int Length=strlen(DirName);
74       if (Length>1 && DirName[Length-1]==CPATHDIVIDER && (Length!=3 || !IsDriveDiv(DirName[1])))
75         DirName[Length-1]=0;
76     }
77 */
78     if ((dirp=opendir(DirName))==NULL)
79     {
80       fd->Error=(errno!=ENOENT);
81       return(false);
82     }
83   }
84   while (1)
85   {
86     struct dirent *ent=readdir(dirp);
87     if (ent==NULL)
88       return(false);
89     if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
90       continue;
91     if (CmpName(FindMask,ent->d_name,MATCH_NAMES))
92     {
93       char FullName[NM];
94       strcpy(FullName,FindMask);
95       *PointToName(FullName)=0;
96       if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1)
97       {
98 #ifndef SILENT
99         Log(NULL,"\n%s%s",FullName,ent->d_name);
100         Log(NULL,St(MPathTooLong));
101 #endif
102         return(false);
103       }
104       strcat(FullName,ent->d_name);
105       if (!FastFind(FullName,NULL,fd,GetSymLink))
106       {
107         ErrHandler.OpenErrorMsg(FullName);
108         continue;
109       }
110       strcpy(fd->Name,FullName);
111       break;
112     }
113   }
114   *fd->NameW=0;
115 #ifdef _APPLE
116   if (!LowAscii(fd->Name))
117     UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
118 #elif defined(UNICODE_SUPPORTED)
119   if (!LowAscii(fd->Name) && UnicodeEnabled())
120     CharToWide(fd->Name,fd->NameW);
121 #endif
122 #endif
123   fd->Flags=0;
124   fd->IsDir=IsDir(fd->FileAttr);
125   FirstCall=false;
126   char *Name=PointToName(fd->Name);
127   if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
128     return(Next(fd));
129   return(true);
130 }
131 
132 
FastFind(const char * FindMask,const wchar * FindMaskW,struct FindData * fd,bool GetSymLink)133 bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink)
134 {
135   fd->Error=false;
136 #ifndef _UNIX
137   if (IsWildcard(FindMask,FindMaskW))
138     return(false);
139 #endif
140 #ifdef _WIN_32
141   HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
142   if (hFind==INVALID_HANDLE_VALUE)
143     return(false);
144   FindClose(hFind);
145 #else
146   struct stat st;
147   if (GetSymLink)
148   {
149 #ifdef SAVE_LINKS
150     if (lstat(FindMask,&st)!=0)
151 #else
152     if (stat(FindMask,&st)!=0)
153 #endif
154     {
155       fd->Error=(errno!=ENOENT);
156       return(false);
157     }
158   }
159   else
160     if (stat(FindMask,&st)!=0)
161     {
162       fd->Error=(errno!=ENOENT);
163       return(false);
164     }
165 #ifdef _DJGPP
166   fd->FileAttr=_chmod(FindMask,0);
167 #elif defined(_EMX)
168   fd->FileAttr=st.st_attr;
169 #else
170   fd->FileAttr=st.st_mode;
171 #endif
172   fd->IsDir=IsDir(st.st_mode);
173   fd->Size=st.st_size;
174   fd->mtime=st.st_mtime;
175   fd->atime=st.st_atime;
176   fd->ctime=st.st_ctime;
177   fd->FileTime=fd->mtime.GetDos();
178   strcpy(fd->Name,FindMask);
179 
180   *fd->NameW=0;
181 #ifdef _APPLE
182   if (!LowAscii(fd->Name))
183     UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
184 #elif defined(UNICODE_SUPPORTED)
185   if (!LowAscii(fd->Name) && UnicodeEnabled())
186     CharToWide(fd->Name,fd->NameW);
187 #endif
188 #endif
189   fd->Flags=0;
190   fd->IsDir=IsDir(fd->FileAttr);
191   return(true);
192 }
193 
194 
195 #ifdef _WIN_32
Win32Find(HANDLE hFind,const char * Mask,const wchar * MaskW,struct FindData * fd)196 HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd)
197 {
198 #ifndef _WIN_CE
199   if (WinNT())
200 #endif
201   {
202     wchar WideMask[NM];
203     if (MaskW!=NULL && *MaskW!=0)
204       strcpyw(WideMask,MaskW);
205     else
206       CharToWide(Mask,WideMask);
207 
208     WIN32_FIND_DATAW FindData;
209     if (hFind==INVALID_HANDLE_VALUE)
210     {
211       hFind=FindFirstFileW(WideMask,&FindData);
212       if (hFind==INVALID_HANDLE_VALUE)
213       {
214         int SysErr=GetLastError();
215         fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
216                    SysErr!=ERROR_PATH_NOT_FOUND &&
217                    SysErr!=ERROR_NO_MORE_FILES);
218       }
219     }
220     else
221       if (!FindNextFileW(hFind,&FindData))
222       {
223         hFind=INVALID_HANDLE_VALUE;
224         fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
225       }
226 
227     if (hFind!=INVALID_HANDLE_VALUE)
228     {
229       strcpyw(fd->NameW,WideMask);
230       strcpyw(PointToName(fd->NameW),FindData.cFileName);
231       WideToChar(fd->NameW,fd->Name);
232       fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
233       fd->FileAttr=FindData.dwFileAttributes;
234       WideToChar(FindData.cAlternateFileName,fd->ShortName);
235       fd->ftCreationTime=FindData.ftCreationTime;
236       fd->ftLastAccessTime=FindData.ftLastAccessTime;
237       fd->ftLastWriteTime=FindData.ftLastWriteTime;
238       fd->mtime=FindData.ftLastWriteTime;
239       fd->ctime=FindData.ftCreationTime;
240       fd->atime=FindData.ftLastAccessTime;
241       fd->FileTime=fd->mtime.GetDos();
242 
243 #ifndef _WIN_CE
244       if (LowAscii(fd->NameW))
245         *fd->NameW=0;
246 #endif
247     }
248   }
249 #ifndef _WIN_CE
250   else
251   {
252     char CharMask[NM];
253     if (Mask!=NULL && *Mask!=0)
254       strcpy(CharMask,Mask);
255     else
256       WideToChar(MaskW,CharMask);
257 
258     WIN32_FIND_DATA FindData;
259     if (hFind==INVALID_HANDLE_VALUE)
260     {
261       hFind=FindFirstFile(CharMask,&FindData);
262       if (hFind==INVALID_HANDLE_VALUE)
263       {
264         int SysErr=GetLastError();
265         fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
266       }
267     }
268     else
269       if (!FindNextFile(hFind,&FindData))
270       {
271         hFind=INVALID_HANDLE_VALUE;
272         fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
273       }
274 
275     if (hFind!=INVALID_HANDLE_VALUE)
276     {
277       strcpy(fd->Name,CharMask);
278       strcpy(PointToName(fd->Name),FindData.cFileName);
279       CharToWide(fd->Name,fd->NameW);
280       fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
281       fd->FileAttr=FindData.dwFileAttributes;
282       strcpy(fd->ShortName,FindData.cAlternateFileName);
283       fd->ftCreationTime=FindData.ftCreationTime;
284       fd->ftLastAccessTime=FindData.ftLastAccessTime;
285       fd->ftLastWriteTime=FindData.ftLastWriteTime;
286       fd->mtime=FindData.ftLastWriteTime;
287       fd->ctime=FindData.ftCreationTime;
288       fd->atime=FindData.ftLastAccessTime;
289       fd->FileTime=fd->mtime.GetDos();
290       if (LowAscii(fd->Name))
291         *fd->NameW=0;
292     }
293   }
294 #endif
295   fd->Flags=0;
296   return(hFind);
297 }
298 #endif
299 
300