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