find.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #include "rar.hpp"
  2. FindFile::FindFile()
  3. {
  4. *FindMask=0;
  5. *FindMaskW=0;
  6. FirstCall=true;
  7. #ifdef _WIN_ALL
  8. hFind=INVALID_HANDLE_VALUE;
  9. #else
  10. dirp=NULL;
  11. #endif
  12. }
  13. FindFile::~FindFile()
  14. {
  15. #ifdef _WIN_ALL
  16. if (hFind!=INVALID_HANDLE_VALUE)
  17. FindClose(hFind);
  18. #else
  19. if (dirp!=NULL)
  20. closedir(dirp);
  21. #endif
  22. }
  23. void FindFile::SetMask(const char *FindMask)
  24. {
  25. strcpy(FindFile::FindMask,NullToEmpty(FindMask));
  26. if (*FindMaskW==0)
  27. CharToWide(FindMask,FindMaskW);
  28. FirstCall=true;
  29. }
  30. void FindFile::SetMaskW(const wchar *FindMaskW)
  31. {
  32. if (FindMaskW==NULL)
  33. return;
  34. wcscpy(FindFile::FindMaskW,FindMaskW);
  35. if (*FindMask==0)
  36. WideToChar(FindMaskW,FindMask);
  37. FirstCall=true;
  38. }
  39. bool FindFile::Next(struct FindData *fd,bool GetSymLink)
  40. {
  41. fd->Error=false;
  42. if (*FindMask==0)
  43. return(false);
  44. #ifdef _WIN_ALL
  45. if (FirstCall)
  46. {
  47. if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE)
  48. return(false);
  49. }
  50. else
  51. if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE)
  52. return(false);
  53. #else
  54. if (FirstCall)
  55. {
  56. char DirName[NM];
  57. strcpy(DirName,FindMask);
  58. RemoveNameFromPath(DirName);
  59. if (*DirName==0)
  60. strcpy(DirName,".");
  61. if ((dirp=opendir(DirName))==NULL)
  62. {
  63. fd->Error=(errno!=ENOENT);
  64. return(false);
  65. }
  66. }
  67. while (1)
  68. {
  69. struct dirent *ent=readdir(dirp);
  70. if (ent==NULL)
  71. return(false);
  72. if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
  73. continue;
  74. if (CmpName(FindMask,ent->d_name,MATCH_NAMES))
  75. {
  76. char FullName[NM];
  77. strcpy(FullName,FindMask);
  78. *PointToName(FullName)=0;
  79. if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1)
  80. {
  81. #ifndef SILENT
  82. Log(NULL,"\n%s%s",FullName,ent->d_name);
  83. Log(NULL,St(MPathTooLong));
  84. #endif
  85. return(false);
  86. }
  87. strcat(FullName,ent->d_name);
  88. if (!FastFind(FullName,NULL,fd,GetSymLink))
  89. {
  90. ErrHandler.OpenErrorMsg(FullName);
  91. continue;
  92. }
  93. strcpy(fd->Name,FullName);
  94. break;
  95. }
  96. }
  97. *fd->NameW=0;
  98. #ifdef _APPLE
  99. if (!LowAscii(fd->Name))
  100. UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
  101. #elif defined(UNICODE_SUPPORTED)
  102. if (!LowAscii(fd->Name) && UnicodeEnabled())
  103. CharToWide(fd->Name,fd->NameW);
  104. #endif
  105. #endif
  106. fd->Flags=0;
  107. fd->IsDir=IsDir(fd->FileAttr);
  108. FirstCall=false;
  109. char *Name=PointToName(fd->Name);
  110. if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
  111. return(Next(fd));
  112. return(true);
  113. }
  114. bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,FindData *fd,bool GetSymLink)
  115. {
  116. fd->Error=false;
  117. #ifndef _UNIX
  118. if (IsWildcard(FindMask,FindMaskW))
  119. return(false);
  120. #endif
  121. #ifdef _WIN_ALL
  122. HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
  123. if (hFind==INVALID_HANDLE_VALUE)
  124. return(false);
  125. FindClose(hFind);
  126. #else
  127. struct stat st;
  128. if (GetSymLink)
  129. {
  130. #ifdef SAVE_LINKS
  131. if (lstat(FindMask,&st)!=0)
  132. #else
  133. if (stat(FindMask,&st)!=0)
  134. #endif
  135. {
  136. fd->Error=(errno!=ENOENT);
  137. return(false);
  138. }
  139. }
  140. else
  141. if (stat(FindMask,&st)!=0)
  142. {
  143. fd->Error=(errno!=ENOENT);
  144. return(false);
  145. }
  146. #ifdef _DJGPP
  147. fd->FileAttr=_chmod(FindMask,0);
  148. #elif defined(_EMX)
  149. fd->FileAttr=st.st_attr;
  150. #else
  151. fd->FileAttr=st.st_mode;
  152. #endif
  153. fd->IsDir=IsDir(st.st_mode);
  154. fd->Size=st.st_size;
  155. fd->mtime=st.st_mtime;
  156. fd->atime=st.st_atime;
  157. fd->ctime=st.st_ctime;
  158. fd->FileTime=fd->mtime.GetDos();
  159. strcpy(fd->Name,FindMask);
  160. *fd->NameW=0;
  161. #ifdef _APPLE
  162. if (!LowAscii(fd->Name))
  163. UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
  164. #elif defined(UNICODE_SUPPORTED)
  165. if (!LowAscii(fd->Name) && UnicodeEnabled())
  166. CharToWide(fd->Name,fd->NameW);
  167. #endif
  168. #endif
  169. fd->Flags=0;
  170. fd->IsDir=IsDir(fd->FileAttr);
  171. return(true);
  172. }
  173. #ifdef _WIN_ALL
  174. HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,FindData *fd)
  175. {
  176. #ifndef _WIN_CE
  177. if (WinNT())
  178. #endif
  179. {
  180. wchar WideMask[NM];
  181. if (MaskW!=NULL && *MaskW!=0)
  182. wcscpy(WideMask,MaskW);
  183. else
  184. CharToWide(Mask,WideMask);
  185. WIN32_FIND_DATAW FindData;
  186. if (hFind==INVALID_HANDLE_VALUE)
  187. {
  188. hFind=FindFirstFileW(WideMask,&FindData);
  189. if (hFind==INVALID_HANDLE_VALUE)
  190. {
  191. int SysErr=GetLastError();
  192. fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
  193. SysErr!=ERROR_PATH_NOT_FOUND &&
  194. SysErr!=ERROR_NO_MORE_FILES);
  195. }
  196. }
  197. else
  198. if (!FindNextFileW(hFind,&FindData))
  199. {
  200. hFind=INVALID_HANDLE_VALUE;
  201. fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
  202. }
  203. if (hFind!=INVALID_HANDLE_VALUE)
  204. {
  205. wcscpy(fd->NameW,WideMask);
  206. wcscpy(PointToName(fd->NameW),FindData.cFileName);
  207. WideToChar(fd->NameW,fd->Name);
  208. fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
  209. fd->FileAttr=FindData.dwFileAttributes;
  210. wcscpy(fd->ShortName,FindData.cAlternateFileName);
  211. fd->ftCreationTime=FindData.ftCreationTime;
  212. fd->ftLastAccessTime=FindData.ftLastAccessTime;
  213. fd->ftLastWriteTime=FindData.ftLastWriteTime;
  214. fd->mtime=FindData.ftLastWriteTime;
  215. fd->ctime=FindData.ftCreationTime;
  216. fd->atime=FindData.ftLastAccessTime;
  217. fd->FileTime=fd->mtime.GetDos();
  218. #ifndef _WIN_CE
  219. // if (LowAscii(fd->NameW))
  220. // *fd->NameW=0;
  221. #endif
  222. }
  223. }
  224. #ifndef _WIN_CE
  225. else
  226. {
  227. char CharMask[NM];
  228. if (Mask!=NULL && *Mask!=0)
  229. strcpy(CharMask,Mask);
  230. else
  231. WideToChar(MaskW,CharMask);
  232. WIN32_FIND_DATAA FindData;
  233. if (hFind==INVALID_HANDLE_VALUE)
  234. {
  235. hFind=FindFirstFileA(CharMask,&FindData);
  236. if (hFind==INVALID_HANDLE_VALUE)
  237. {
  238. int SysErr=GetLastError();
  239. fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
  240. }
  241. }
  242. else
  243. if (!FindNextFileA(hFind,&FindData))
  244. {
  245. hFind=INVALID_HANDLE_VALUE;
  246. fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
  247. }
  248. if (hFind!=INVALID_HANDLE_VALUE)
  249. {
  250. strcpy(fd->Name,CharMask);
  251. strcpy(PointToName(fd->Name),FindData.cFileName);
  252. CharToWide(fd->Name,fd->NameW);
  253. fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
  254. fd->FileAttr=FindData.dwFileAttributes;
  255. CharToWide(FindData.cAlternateFileName,fd->ShortName);
  256. fd->ftCreationTime=FindData.ftCreationTime;
  257. fd->ftLastAccessTime=FindData.ftLastAccessTime;
  258. fd->ftLastWriteTime=FindData.ftLastWriteTime;
  259. fd->mtime=FindData.ftLastWriteTime;
  260. fd->ctime=FindData.ftCreationTime;
  261. fd->atime=FindData.ftLastAccessTime;
  262. fd->FileTime=fd->mtime.GetDos();
  263. // if (LowAscii(fd->Name))
  264. // *fd->NameW=0;
  265. }
  266. }
  267. #endif
  268. fd->Flags=0;
  269. return(hFind);
  270. }
  271. #endif