"Fossies" - the Fresh Open Source Software Archive

Member "unrar/find.cpp" (4 May 2022, 5537 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "find.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 FindFile::FindFile()
    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 
   15 FindFile::~FindFile()
   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 
   27 void FindFile::SetMask(const wchar *Mask)
   28 {
   29   wcsncpyz(FindMask,Mask,ASIZE(FindMask));
   30   FirstCall=true;
   31 }
   32 
   33 
   34 bool 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)))
   73       uiMsg(UIERROR_INVALIDNAME,UINULL,Name);
   74 
   75     if (CmpName(FindMask,Name,MATCH_NAMES))
   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 
  108 bool 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
  173 HANDLE 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