unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

find.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
4{
5 *FindMask=0;
6 FirstCall=true;
7#ifdef _WIN_ALL
8 hFind=INVALID_HANDLE_VALUE;
9#else
10 dirp=NULL;
11#endif
12}
13
14
16{
17#ifdef _WIN_ALL
18 if (hFind!=INVALID_HANDLE_VALUE)
19 FindClose(hFind);
20#else
21 if (dirp!=NULL)
22 closedir(dirp);
23#endif
24}
25
26
27void FindFile::SetMask(const wchar *Mask)
28{
30 FirstCall=true;
31}
32
33
34bool FindFile::Next(FindData *fd,bool GetSymLink)
35{
36 fd->Error=false;
37 if (*FindMask==0)
38 return false;
39#ifdef _WIN_ALL
40 if (FirstCall)
41 {
42 if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,fd))==INVALID_HANDLE_VALUE)
43 return false;
44 }
45 else
46 if (Win32Find(hFind,FindMask,fd)==INVALID_HANDLE_VALUE)
47 return false;
48#else
49 if (FirstCall)
50 {
51 wchar DirName[NM];
52 wcsncpyz(DirName,FindMask,ASIZE(DirName));
53 RemoveNameFromPath(DirName);
54 if (*DirName==0)
55 wcsncpyz(DirName,L".",ASIZE(DirName));
56 char DirNameA[NM];
57 WideToChar(DirName,DirNameA,ASIZE(DirNameA));
58 if ((dirp=opendir(DirNameA))==NULL)
59 {
60 fd->Error=(errno!=ENOENT);
61 return false;
62 }
63 }
64 while (1)
65 {
66 wchar Name[NM];
67 struct dirent *ent=readdir(dirp);
68 if (ent==NULL)
69 return false;
70 if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
71 continue;
72 if (!CharToWide(ent->d_name,Name,ASIZE(Name)))
74
76 {
77 wchar FullName[NM];
78 wcsncpyz(FullName,FindMask,ASIZE(FullName));
79 *PointToName(FullName)=0;
80 if (wcslen(FullName)+wcslen(Name)>=ASIZE(FullName)-1)
81 {
82 uiMsg(UIERROR_PATHTOOLONG,FullName,L"",Name);
83 return false;
84 }
85 wcsncatz(FullName,Name,ASIZE(FullName));
86 if (!FastFind(FullName,fd,GetSymLink))
87 {
88 ErrHandler.OpenErrorMsg(FullName);
89 continue;
90 }
91 wcsncpyz(fd->Name,FullName,ASIZE(fd->Name));
92 break;
93 }
94 }
95#endif
96 fd->Flags=0;
97 fd->IsDir=IsDir(fd->FileAttr);
98 fd->IsLink=IsLink(fd->FileAttr);
99
100 FirstCall=false;
101 wchar *NameOnly=PointToName(fd->Name);
102 if (wcscmp(NameOnly,L".")==0 || wcscmp(NameOnly,L"..")==0)
103 return Next(fd);
104 return true;
105}
106
107
108bool FindFile::FastFind(const wchar *FindMask,FindData *fd,bool GetSymLink)
109{
110 fd->Error=false;
111#ifndef _UNIX
112 if (IsWildcard(FindMask))
113 return false;
114#endif
115#ifdef _WIN_ALL
116 HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,fd);
117 if (hFind==INVALID_HANDLE_VALUE)
118 return false;
119 FindClose(hFind);
120#else
121 char FindMaskA[NM];
122 WideToChar(FindMask,FindMaskA,ASIZE(FindMaskA));
123
124 struct stat st;
125 if (GetSymLink)
126 {
127#ifdef SAVE_LINKS
128 if (lstat(FindMaskA,&st)!=0)
129#else
130 if (stat(FindMaskA,&st)!=0)
131#endif
132 {
133 fd->Error=(errno!=ENOENT);
134 return false;
135 }
136 }
137 else
138 if (stat(FindMaskA,&st)!=0)
139 {
140 fd->Error=(errno!=ENOENT);
141 return false;
142 }
143 fd->FileAttr=st.st_mode;
144 fd->Size=st.st_size;
145
146#ifdef UNIX_TIME_NS
147#if defined(_APPLE)
148 fd->mtime.SetUnixNS(st.st_mtimespec.tv_sec*(uint64)1000000000+st.st_mtimespec.tv_nsec);
149 fd->atime.SetUnixNS(st.st_atimespec.tv_sec*(uint64)1000000000+st.st_atimespec.tv_nsec);
150 fd->ctime.SetUnixNS(st.st_ctimespec.tv_sec*(uint64)1000000000+st.st_ctimespec.tv_nsec);
151#else
152 fd->mtime.SetUnixNS(st.st_mtim.tv_sec*(uint64)1000000000+st.st_mtim.tv_nsec);
153 fd->atime.SetUnixNS(st.st_atim.tv_sec*(uint64)1000000000+st.st_atim.tv_nsec);
154 fd->ctime.SetUnixNS(st.st_ctim.tv_sec*(uint64)1000000000+st.st_ctim.tv_nsec);
155#endif
156#else
157 fd->mtime.SetUnix(st.st_mtime);
158 fd->atime.SetUnix(st.st_atime);
159 fd->ctime.SetUnix(st.st_ctime);
160#endif
161
162 wcsncpyz(fd->Name,FindMask,ASIZE(fd->Name));
163#endif
164 fd->Flags=0;
165 fd->IsDir=IsDir(fd->FileAttr);
166 fd->IsLink=IsLink(fd->FileAttr);
167
168 return true;
169}
170
171
172#ifdef _WIN_ALL
173HANDLE FindFile::Win32Find(HANDLE hFind,const wchar *Mask,FindData *fd)
174{
175 WIN32_FIND_DATA FindData;
176 if (hFind==INVALID_HANDLE_VALUE)
177 {
178 hFind=FindFirstFile(Mask,&FindData);
179 if (hFind==INVALID_HANDLE_VALUE)
180 {
181 wchar LongMask[NM];
182 if (GetWinLongPath(Mask,LongMask,ASIZE(LongMask)))
183 hFind=FindFirstFile(LongMask,&FindData);
184 }
185 if (hFind==INVALID_HANDLE_VALUE)
186 {
187 int SysErr=GetLastError();
188 // We must not issue an error for "file not found" and "path not found",
189 // because it is normal to not find anything for wildcard mask when
190 // archiving. Also searching for non-existent file is normal in some
191 // other modules, like WinRAR scanning for winrar_theme_description.txt
192 // to check if any themes are available.
193 fd->Error=SysErr!=ERROR_FILE_NOT_FOUND &&
194 SysErr!=ERROR_PATH_NOT_FOUND &&
195 SysErr!=ERROR_NO_MORE_FILES;
196 }
197 }
198 else
199 if (!FindNextFile(hFind,&FindData))
200 {
201 hFind=INVALID_HANDLE_VALUE;
202 fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
203 }
204
205 if (hFind!=INVALID_HANDLE_VALUE)
206 {
207 wcsncpyz(fd->Name,Mask,ASIZE(fd->Name));
208 SetName(fd->Name,FindData.cFileName,ASIZE(fd->Name));
209 fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
210 fd->FileAttr=FindData.dwFileAttributes;
211 fd->ftCreationTime=FindData.ftCreationTime;
212 fd->ftLastAccessTime=FindData.ftLastAccessTime;
213 fd->ftLastWriteTime=FindData.ftLastWriteTime;
214 fd->mtime.SetWinFT(&FindData.ftLastWriteTime);
215 fd->ctime.SetWinFT(&FindData.ftCreationTime);
216 fd->atime.SetWinFT(&FindData.ftLastAccessTime);
217
218
219 }
220 fd->Flags=0;
221 return hFind;
222}
223#endif
224
ErrorHandler ErrHandler
void OpenErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:164
bool FirstCall
Definition: find.hpp:35
void SetMask(const wchar *Mask)
Definition: find.cpp:27
FindFile()
Definition: find.cpp:3
~FindFile()
Definition: find.cpp:15
wchar FindMask[NM]
Definition: find.hpp:34
bool Next(FindData *fd, bool GetSymLink=false)
Definition: find.cpp:34
static bool FastFind(const wchar *FindMask, FindData *fd, bool GetSymLink=false)
Definition: find.cpp:108
DIR * dirp
Definition: find.hpp:39
void SetUnix(time_t ut)
Definition: timefn.cpp:170
void SetUnixNS(uint64 ns)
Definition: timefn.cpp:193
bool IsLink(uint Attr)
Definition: filefn.cpp:238
bool IsDir(uint Attr)
Definition: filefn.cpp:218
bool CmpName(const wchar *Wildcard, const wchar *Name, int CmpMode)
Definition: match.cpp:19
@ MATCH_NAMES
Definition: match.hpp:5
bool IsWildcard(const wchar *Str)
Definition: pathfn.cpp:121
wchar * PointToName(const wchar *Path)
Definition: pathfn.cpp:3
void RemoveNameFromPath(wchar *Path)
Definition: pathfn.cpp:208
void SetName(wchar *FullName, const wchar *Name, size_t MaxSize)
Definition: pathfn.cpp:67
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
uint64_t uint64
Definition: rartypes.hpp:11
#define INT32TO64(high, low)
Definition: rartypes.hpp:19
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:275
void wcsncatz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:300
Definition: find.hpp:9
RarTime atime
Definition: find.hpp:17
RarTime mtime
Definition: find.hpp:15
uint64 Size
Definition: find.hpp:11
wchar Name[NM]
Definition: find.hpp:10
uint Flags
Definition: find.hpp:23
uint FileAttr
Definition: find.hpp:12
bool IsLink
Definition: find.hpp:14
bool Error
Definition: find.hpp:24
RarTime ctime
Definition: find.hpp:16
bool IsDir
Definition: find.hpp:13
void uiMsg(UIMESSAGE_CODE Code)
Definition: ui.hpp:148
#define UINULL
Definition: ui.hpp:146
@ UIERROR_PATHTOOLONG
Definition: ui.hpp:38
@ UIERROR_INVALIDNAME
Definition: ui.hpp:29
bool WideToChar(const wchar *Src, char *Dest, size_t DestSize)
Definition: unicode.cpp:20
bool CharToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:85