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       strcpy(PointToName(FullName),ent->d_name);
96       if (!FastFind(FullName,NULL,fd,GetSymLink))
97       {
98         ErrHandler.OpenErrorMsg(FullName);
99         continue;
100       }
101       strcpy(fd->Name,FullName);
102       break;
103     }
104   }
105   *fd->NameW=0;
106 #ifdef _APPLE
107   if (!LowAscii(fd->Name))
108     UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
109 #elif defined(UNICODE_SUPPORTED)
110   if (!LowAscii(fd->Name) && UnicodeEnabled())
111     CharToWide(fd->Name,fd->NameW);
112 #endif
113 #endif
114   fd->IsDir=IsDir(fd->FileAttr);
115   FirstCall=FALSE;
116   char *Name=PointToName(fd->Name);
117   if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
118     return(Next(fd));
119   return(true);
120 }
121 
122 
FastFind(const char * FindMask,const wchar * FindMaskW,struct FindData * fd,bool GetSymLink)123 bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink)
124 {
125   fd->Error=false;
126 #ifndef _UNIX
127   if (IsWildcard(FindMask,FindMaskW))
128     return(false);
129 #endif
130 #ifdef _WIN_32
131   HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
132   if (hFind==INVALID_HANDLE_VALUE)
133     return(false);
134   FindClose(hFind);
135 #else
136   struct stat st;
137   if (GetSymLink)
138   {
139 #ifdef SAVE_LINKS
140     if (lstat(FindMask,&st)!=0)
141 #else
142     if (stat(FindMask,&st)!=0)
143 #endif
144     {
145       fd->Error=(errno!=ENOENT);
146       return(false);
147     }
148   }
149   else
150     if (stat(FindMask,&st)!=0)
151     {
152       fd->Error=(errno!=ENOENT);
153       return(false);
154     }
155 #ifdef _DJGPP
156   fd->FileAttr=chmod(FindMask,0);
157 #elif defined(_EMX)
158   fd->FileAttr=st.st_attr;
159 #else
160   fd->FileAttr=st.st_mode;
161 #endif
162   fd->IsDir=IsDir(st.st_mode);
163   fd->Size=st.st_size;
164   fd->mtime=st.st_mtime;
165   fd->atime=st.st_atime;
166   fd->ctime=st.st_ctime;
167   fd->FileTime=fd->mtime.GetDos();
168   strcpy(fd->Name,FindMask);
169 
170   *fd->NameW=0;
171 #ifdef _APPLE
172   if (!LowAscii(fd->Name))
173     UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
174 #elif defined(UNICODE_SUPPORTED)
175   if (!LowAscii(fd->Name) && UnicodeEnabled())
176     CharToWide(fd->Name,fd->NameW);
177 #endif
178 #endif
179   fd->IsDir=IsDir(fd->FileAttr);
180   return(true);
181 }
182 
183 
184 #ifdef _WIN_32
Win32Find(HANDLE hFind,const char * Mask,const wchar * MaskW,struct FindData * fd)185 HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd)
186 {
187 #ifndef _WIN_CE
188   if (WinNT())
189 #endif
190   {
191     wchar WideMask[NM];
192     if (MaskW!=NULL && *MaskW!=0)
193       strcpyw(WideMask,MaskW);
194     else
195       CharToWide(Mask,WideMask);
196 
197     WIN32_FIND_DATAW FindData;
198     if (hFind==INVALID_HANDLE_VALUE)
199     {
200       hFind=FindFirstFileW(WideMask,&FindData);
201       if (hFind==INVALID_HANDLE_VALUE)
202       {
203         int SysErr=GetLastError();
204         fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
205                    SysErr!=ERROR_PATH_NOT_FOUND &&
206                    SysErr!=ERROR_NO_MORE_FILES);
207       }
208     }
209     else
210       if (!FindNextFileW(hFind,&FindData))
211       {
212         hFind=INVALID_HANDLE_VALUE;
213         fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
214       }
215 
216     if (hFind!=INVALID_HANDLE_VALUE)
217     {
218       strcpyw(fd->NameW,WideMask);
219       strcpyw(PointToName(fd->NameW),FindData.cFileName);
220       WideToChar(fd->NameW,fd->Name);
221       fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
222       fd->FileAttr=FindData.dwFileAttributes;
223       WideToChar(FindData.cAlternateFileName,fd->ShortName);
224       fd->ftCreationTime=FindData.ftCreationTime;
225       fd->ftLastAccessTime=FindData.ftLastAccessTime;
226       fd->ftLastWriteTime=FindData.ftLastWriteTime;
227       fd->mtime=FindData.ftLastWriteTime;
228       fd->ctime=FindData.ftCreationTime;
229       fd->atime=FindData.ftLastAccessTime;
230       fd->FileTime=fd->mtime.GetDos();
231 
232 #ifndef _WIN_CE
233       if (LowAscii(fd->NameW))
234         *fd->NameW=0;
235 #endif
236     }
237   }
238 #ifndef _WIN_CE
239   else
240   {
241     char CharMask[NM];
242     if (Mask!=NULL && *Mask!=0)
243       strcpy(CharMask,Mask);
244     else
245       WideToChar(MaskW,CharMask);
246 
247     WIN32_FIND_DATA FindData;
248     if (hFind==INVALID_HANDLE_VALUE)
249     {
250       hFind=FindFirstFile(CharMask,&FindData);
251       if (hFind==INVALID_HANDLE_VALUE)
252       {
253         int SysErr=GetLastError();
254         fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
255       }
256     }
257     else
258       if (!FindNextFile(hFind,&FindData))
259       {
260         hFind=INVALID_HANDLE_VALUE;
261         fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
262       }
263 
264     if (hFind!=INVALID_HANDLE_VALUE)
265     {
266       strcpy(fd->Name,CharMask);
267       strcpy(PointToName(fd->Name),FindData.cFileName);
268       CharToWide(fd->Name,fd->NameW);
269       fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
270       fd->FileAttr=FindData.dwFileAttributes;
271       strcpy(fd->ShortName,FindData.cAlternateFileName);
272       fd->ftCreationTime=FindData.ftCreationTime;
273       fd->ftLastAccessTime=FindData.ftLastAccessTime;
274       fd->ftLastWriteTime=FindData.ftLastWriteTime;
275       fd->mtime=FindData.ftLastWriteTime;
276       fd->ctime=FindData.ftCreationTime;
277       fd->atime=FindData.ftLastAccessTime;
278       fd->FileTime=fd->mtime.GetDos();
279       if (LowAscii(fd->Name))
280         *fd->NameW=0;
281     }
282   }
283 #endif
284   return(hFind);
285 }
286 #endif
287 
288