/src/clamav/libclamunrar/find.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | #include "rar.hpp"  | 
2  |  |  | 
3  |  | FindFile::FindFile()  | 
4  | 0  | { | 
5  | 0  |   *FindMask=0;  | 
6  | 0  |   FirstCall=true;  | 
7  |  | #ifdef _WIN_ALL  | 
8  |  |   hFind=INVALID_HANDLE_VALUE;  | 
9  |  | #else  | 
10  | 0  |   dirp=NULL;  | 
11  | 0  | #endif  | 
12  | 0  | }  | 
13  |  |  | 
14  |  |  | 
15  |  | FindFile::~FindFile()  | 
16  | 0  | { | 
17  |  | #ifdef _WIN_ALL  | 
18  |  |   if (hFind!=INVALID_HANDLE_VALUE)  | 
19  |  |     FindClose(hFind);  | 
20  |  | #else  | 
21  | 0  |   if (dirp!=NULL)  | 
22  | 0  |     closedir(dirp);  | 
23  | 0  | #endif  | 
24  | 0  | }  | 
25  |  |  | 
26  |  |  | 
27  |  | void FindFile::SetMask(const wchar *Mask)  | 
28  | 0  | { | 
29  | 0  |   wcsncpyz(FindMask,Mask,ASIZE(FindMask));  | 
30  | 0  |   FirstCall=true;  | 
31  | 0  | }  | 
32  |  |  | 
33  |  |  | 
34  |  | bool FindFile::Next(FindData *fd,bool GetSymLink)  | 
35  | 0  | { | 
36  | 0  |   fd->Error=false;  | 
37  | 0  |   if (*FindMask==0)  | 
38  | 0  |     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  | 0  |   if (FirstCall)  | 
50  | 0  |   { | 
51  | 0  |     wchar DirName[NM];  | 
52  | 0  |     wcsncpyz(DirName,FindMask,ASIZE(DirName));  | 
53  | 0  |     RemoveNameFromPath(DirName);  | 
54  | 0  |     if (*DirName==0)  | 
55  | 0  |       wcsncpyz(DirName,L".",ASIZE(DirName));  | 
56  | 0  |     char DirNameA[NM];  | 
57  | 0  |     WideToChar(DirName,DirNameA,ASIZE(DirNameA));  | 
58  | 0  |     if ((dirp=opendir(DirNameA))==NULL)  | 
59  | 0  |     { | 
60  | 0  |       fd->Error=(errno!=ENOENT);  | 
61  | 0  |       return false;  | 
62  | 0  |     }  | 
63  | 0  |   }  | 
64  | 0  |   while (1)  | 
65  | 0  |   { | 
66  | 0  |     wchar Name[NM];  | 
67  | 0  |     struct dirent *ent=readdir(dirp);  | 
68  | 0  |     if (ent==NULL)  | 
69  | 0  |       return false;  | 
70  | 0  |     if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)  | 
71  | 0  |       continue;  | 
72  | 0  |     if (!CharToWide(ent->d_name,Name,ASIZE(Name)))  | 
73  | 0  |       uiMsg(UIERROR_INVALIDNAME,UINULL,Name);  | 
74  |  | 
  | 
75  | 0  |     if (CmpName(FindMask,Name,MATCH_NAMES))  | 
76  | 0  |     { | 
77  | 0  |       wchar FullName[NM];  | 
78  | 0  |       wcsncpyz(FullName,FindMask,ASIZE(FullName));  | 
79  | 0  |       *PointToName(FullName)=0;  | 
80  | 0  |       if (wcslen(FullName)+wcslen(Name)>=ASIZE(FullName)-1)  | 
81  | 0  |       { | 
82  | 0  |         uiMsg(UIERROR_PATHTOOLONG,FullName,L"",Name);  | 
83  | 0  |         return false;  | 
84  | 0  |       }  | 
85  | 0  |       wcsncatz(FullName,Name,ASIZE(FullName));  | 
86  | 0  |       if (!FastFind(FullName,fd,GetSymLink))  | 
87  | 0  |       { | 
88  | 0  |         ErrHandler.OpenErrorMsg(FullName);  | 
89  | 0  |         continue;  | 
90  | 0  |       }  | 
91  | 0  |       wcsncpyz(fd->Name,FullName,ASIZE(fd->Name));  | 
92  | 0  |       break;  | 
93  | 0  |     }  | 
94  | 0  |   }  | 
95  | 0  | #endif  | 
96  | 0  |   fd->Flags=0;  | 
97  | 0  |   fd->IsDir=IsDir(fd->FileAttr);  | 
98  | 0  |   fd->IsLink=IsLink(fd->FileAttr);  | 
99  |  | 
  | 
100  | 0  |   FirstCall=false;  | 
101  | 0  |   wchar *NameOnly=PointToName(fd->Name);  | 
102  | 0  |   if (wcscmp(NameOnly,L".")==0 || wcscmp(NameOnly,L"..")==0)  | 
103  | 0  |     return Next(fd);  | 
104  | 0  |   return true;  | 
105  | 0  | }  | 
106  |  |  | 
107  |  |  | 
108  |  | bool FindFile::FastFind(const wchar *FindMask,FindData *fd,bool GetSymLink)  | 
109  | 0  | { | 
110  | 0  |   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  |  | #elif defined(_UNIX)  | 
121  |  |   char FindMaskA[NM];  | 
122  | 0  |   WideToChar(FindMask,FindMaskA,ASIZE(FindMaskA));  | 
123  |  | 
  | 
124  | 0  |   struct stat st;  | 
125  | 0  |   if (GetSymLink)  | 
126  | 0  |   { | 
127  | 0  | #ifdef SAVE_LINKS  | 
128  | 0  |     if (lstat(FindMaskA,&st)!=0)  | 
129  |  | #else  | 
130  |  |     if (stat(FindMaskA,&st)!=0)  | 
131  |  | #endif  | 
132  | 0  |     { | 
133  | 0  |       fd->Error=(errno!=ENOENT);  | 
134  | 0  |       return false;  | 
135  | 0  |     }  | 
136  | 0  |   }  | 
137  | 0  |   else  | 
138  | 0  |     if (stat(FindMaskA,&st)!=0)  | 
139  | 0  |     { | 
140  | 0  |       fd->Error=(errno!=ENOENT);  | 
141  | 0  |       return false;  | 
142  | 0  |     }  | 
143  | 0  |   fd->FileAttr=st.st_mode;  | 
144  | 0  |   fd->Size=st.st_size;  | 
145  |  | 
  | 
146  | 0  |   File::StatToRarTime(st,&fd->mtime,&fd->ctime,&fd->atime);  | 
147  |  | 
  | 
148  | 0  |   wcsncpyz(fd->Name,FindMask,ASIZE(fd->Name));  | 
149  | 0  | #endif  | 
150  | 0  |   fd->Flags=0;  | 
151  | 0  |   fd->IsDir=IsDir(fd->FileAttr);  | 
152  | 0  |   fd->IsLink=IsLink(fd->FileAttr);  | 
153  |  | 
  | 
154  | 0  |   return true;  | 
155  | 0  | }  | 
156  |  |  | 
157  |  |  | 
158  |  | #ifdef _WIN_ALL  | 
159  |  | HANDLE FindFile::Win32Find(HANDLE hFind,const wchar *Mask,FindData *fd)  | 
160  |  | { | 
161  |  |   WIN32_FIND_DATA FindData;  | 
162  |  |   if (hFind==INVALID_HANDLE_VALUE)  | 
163  |  |   { | 
164  |  |     hFind=FindFirstFile(Mask,&FindData);  | 
165  |  |     if (hFind==INVALID_HANDLE_VALUE)  | 
166  |  |     { | 
167  |  |       wchar LongMask[NM];  | 
168  |  |       if (GetWinLongPath(Mask,LongMask,ASIZE(LongMask)))  | 
169  |  |         hFind=FindFirstFile(LongMask,&FindData);  | 
170  |  |     }  | 
171  |  |     if (hFind==INVALID_HANDLE_VALUE)  | 
172  |  |     { | 
173  |  |       int SysErr=GetLastError();  | 
174  |  |       // We must not issue an error for "file not found" and "path not found",  | 
175  |  |       // because it is normal to not find anything for wildcard mask when  | 
176  |  |       // archiving. Also searching for non-existent file is normal in some  | 
177  |  |       // other modules, like WinRAR scanning for winrar_theme_description.txt  | 
178  |  |       // to check if any themes are available.  | 
179  |  |       fd->Error=SysErr!=ERROR_FILE_NOT_FOUND &&   | 
180  |  |                 SysErr!=ERROR_PATH_NOT_FOUND &&  | 
181  |  |                 SysErr!=ERROR_NO_MORE_FILES;  | 
182  |  |     }  | 
183  |  |   }  | 
184  |  |   else  | 
185  |  |     if (!FindNextFile(hFind,&FindData))  | 
186  |  |     { | 
187  |  |       hFind=INVALID_HANDLE_VALUE;  | 
188  |  |       fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;  | 
189  |  |     }  | 
190  |  |  | 
191  |  |   if (hFind!=INVALID_HANDLE_VALUE)  | 
192  |  |   { | 
193  |  |     wcsncpyz(fd->Name,Mask,ASIZE(fd->Name));  | 
194  |  |     SetName(fd->Name,FindData.cFileName,ASIZE(fd->Name));  | 
195  |  |     fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);  | 
196  |  |     fd->FileAttr=FindData.dwFileAttributes;  | 
197  |  |     fd->ftCreationTime=FindData.ftCreationTime;  | 
198  |  |     fd->ftLastAccessTime=FindData.ftLastAccessTime;  | 
199  |  |     fd->ftLastWriteTime=FindData.ftLastWriteTime;  | 
200  |  |     fd->mtime.SetWinFT(&FindData.ftLastWriteTime);  | 
201  |  |     fd->ctime.SetWinFT(&FindData.ftCreationTime);  | 
202  |  |     fd->atime.SetWinFT(&FindData.ftLastAccessTime);  | 
203  |  |  | 
204  |  |  | 
205  |  |   }  | 
206  |  |   fd->Flags=0;  | 
207  |  |   return hFind;  | 
208  |  | }  | 
209  |  | #endif  | 
210  |  |  |