find.cpp 5.5 KB

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