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