"Fossies" - the Fresh Open Source Software Archive

Member "unrar/cmdfilter.cpp" (4 May 2022, 10691 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 "cmdfilter.cpp" see the Fossies "Dox" file reference documentation.

    1 // Return 'true' if we need to exclude the file from processing as result
    2 // of -x switch. If CheckInclList is true, we also check the file against
    3 // the include list created with -n switch.
    4 bool CommandData::ExclCheck(const wchar *CheckName,bool Dir,bool CheckFullPath,bool CheckInclList)
    5 {
    6   if (CheckArgs(&ExclArgs,Dir,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
    7     return true;
    8   if (!CheckInclList || InclArgs.ItemsCount()==0)
    9     return false;
   10   if (CheckArgs(&InclArgs,Dir,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
   11     return false;
   12   return true;
   13 }
   14 
   15 
   16 bool CommandData::CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,bool CheckFullPath,int MatchMode)
   17 {
   18   wchar *Name=ConvertPath(CheckName,NULL,0);
   19   wchar FullName[NM];
   20   wchar CurMask[NM];
   21   *FullName=0;
   22   Args->Rewind();
   23   while (Args->GetString(CurMask,ASIZE(CurMask)))
   24   {
   25     wchar *LastMaskChar=PointToLastChar(CurMask);
   26     bool DirMask=IsPathDiv(*LastMaskChar); // Mask for directories only.
   27 
   28     if (Dir)
   29     {
   30       // CheckName is a directory.
   31       if (DirMask)
   32       {
   33         // We process the directory and have the directory exclusion mask.
   34         // So let's convert "mask\" to "mask" and process it normally.
   35         
   36         *LastMaskChar=0;
   37       }
   38       else
   39       {
   40         // REMOVED, we want -npath\* to match empty folders too.
   41         // If mask has wildcards in name part and does not have the trailing
   42         // '\' character, we cannot use it for directories.
   43       
   44         // if (IsWildcard(PointToName(CurMask)))
   45         //  continue;
   46       }
   47     }
   48     else
   49     {
   50       // If we process a file inside of directory excluded by "dirmask\".
   51       // we want to exclude such file too. So we convert "dirmask\" to
   52       // "dirmask\*". It is important for operations other than archiving
   53       // with -x. When archiving with -x, directory matched by "dirmask\"
   54       // is excluded from further scanning.
   55 
   56       if (DirMask)
   57         wcsncatz(CurMask,L"*",ASIZE(CurMask));
   58     }
   59 
   60 #ifndef SFX_MODULE
   61     if (CheckFullPath && IsFullPath(CurMask))
   62     {
   63       // We do not need to do the special "*\" processing here, because
   64       // unlike the "else" part of this "if", now we convert names to full
   65       // format, so they all include the path, which is matched by "*\"
   66       // correctly. Moreover, removing "*\" from mask would break
   67       // the comparison, because now all names have the path.
   68 
   69       if (*FullName==0)
   70         ConvertNameToFull(CheckName,FullName,ASIZE(FullName));
   71       if (CmpName(CurMask,FullName,MatchMode))
   72         return true;
   73     }
   74     else
   75 #endif
   76     {
   77       wchar NewName[NM+2],*CurName=Name;
   78 
   79       // Important to convert before "*\" check below, so masks like
   80       // d:*\something are processed properly.
   81       wchar *CmpMask=ConvertPath(CurMask,NULL,0);
   82 
   83       if (CmpMask[0]=='*' && IsPathDiv(CmpMask[1]))
   84       {
   85         // We want "*\name" to match 'name' not only in subdirectories,
   86         // but also in the current directory. We convert the name
   87         // from 'name' to '.\name' to be matched by "*\" part even if it is
   88         // in current directory.
   89         NewName[0]='.';
   90         NewName[1]=CPATHDIVIDER;
   91         wcsncpyz(NewName+2,Name,ASIZE(NewName)-2);
   92         CurName=NewName;
   93       }
   94 
   95       if (CmpName(CmpMask,CurName,MatchMode))
   96         return true;
   97     }
   98   }
   99   return false;
  100 }
  101 
  102 
  103 
  104 
  105 #ifndef SFX_MODULE
  106 // Now this function performs only one task and only in Windows version:
  107 // it skips symlinks to directories if -e1024 switch is specified.
  108 // Symlinks are skipped in ScanTree class, so their entire contents
  109 // is skipped too. Without this function we would check the attribute
  110 // only directly before archiving, so we would skip the symlink record,
  111 // but not the contents of symlinked directory.
  112 bool CommandData::ExclDirByAttr(uint FileAttr)
  113 {
  114 #ifdef _WIN_ALL
  115   if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0 &&
  116       (ExclFileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0)
  117     return true;
  118 #endif
  119   return false;
  120 }
  121 #endif
  122 
  123 
  124 
  125 
  126 #if !defined(SFX_MODULE)
  127 void CommandData::SetTimeFilters(const wchar *Mod,bool Before,bool Age)
  128 {
  129   bool ModeOR=false,TimeMods=false;
  130   const wchar *S=Mod;
  131   // Check if any 'mca' modifiers are present, set OR mode if 'o' is present,
  132   // skip modifiers and set S to beginning of time string. Be sure to check
  133   // *S!=0, because termination 0 is a part of string for wcschr.
  134   for (;*S!=0 && wcschr(L"MCAOmcao",*S)!=NULL;S++)
  135     if (*S=='o' || *S=='O')
  136       ModeOR=true;
  137     else
  138       TimeMods=true;
  139 
  140   if (!TimeMods) // Assume 'm' if no modifiers are specified.
  141     Mod=L"m";
  142 
  143   // Set the specified time for every modifier. Be sure to check *Mod!=0,
  144   // because termination 0 is a part of string for wcschr. This check is
  145   // important when we set Mod to "m" above.
  146   for (;*Mod!=0 && wcschr(L"MCAOmcao",*Mod)!=NULL;Mod++)
  147     switch(toupperw(*Mod))
  148     {
  149       case 'M': 
  150         if (Before)
  151         {
  152           Age ? FileMtimeBefore.SetAgeText(S):FileMtimeBefore.SetIsoText(S);
  153           FileMtimeBeforeOR=ModeOR;
  154         }
  155         else
  156         {
  157           Age ? FileMtimeAfter.SetAgeText(S):FileMtimeAfter.SetIsoText(S);
  158           FileMtimeAfterOR=ModeOR;
  159         }
  160         break;
  161       case 'C':
  162         if (Before)
  163         {
  164           Age ? FileCtimeBefore.SetAgeText(S):FileCtimeBefore.SetIsoText(S);
  165           FileCtimeBeforeOR=ModeOR;
  166         }
  167         else
  168         {
  169           Age ? FileCtimeAfter.SetAgeText(S):FileCtimeAfter.SetIsoText(S);
  170           FileCtimeAfterOR=ModeOR;
  171         }
  172         break;
  173       case 'A':
  174         if (Before)
  175         {
  176           Age ? FileAtimeBefore.SetAgeText(S):FileAtimeBefore.SetIsoText(S);
  177           FileAtimeBeforeOR=ModeOR;
  178         }
  179         else
  180         {
  181           Age ? FileAtimeAfter.SetAgeText(S):FileAtimeAfter.SetIsoText(S);
  182           FileAtimeAfterOR=ModeOR;
  183         }
  184         break;
  185     }
  186 }
  187 #endif
  188 
  189 
  190 #ifndef SFX_MODULE
  191 // Return 'true' if we need to exclude the file from processing.
  192 bool CommandData::TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta)
  193 {
  194   bool FilterOR=false;
  195 
  196   if (FileMtimeBefore.IsSet()) // Filter present.
  197     if (ftm>=FileMtimeBefore) // Condition not matched.
  198       if (FileMtimeBeforeOR) 
  199         FilterOR=true; // Not matched OR filter is present.
  200       else
  201         return true; // Exclude file in AND mode.
  202     else  // Condition matched.
  203       if (FileMtimeBeforeOR) 
  204         return false; // Include file in OR mode.
  205 
  206   if (FileMtimeAfter.IsSet()) // Filter present.
  207     if (ftm<FileMtimeAfter) // Condition not matched.
  208       if (FileMtimeAfterOR) 
  209         FilterOR=true; // Not matched OR filter is present.
  210       else
  211         return true; // Exclude file in AND mode.
  212     else  // Condition matched.
  213       if (FileMtimeAfterOR) 
  214         return false; // Include file in OR mode.
  215 
  216   if (FileCtimeBefore.IsSet()) // Filter present.
  217     if (ftc>=FileCtimeBefore) // Condition not matched.
  218       if (FileCtimeBeforeOR) 
  219         FilterOR=true; // Not matched OR filter is present.
  220       else
  221         return true; // Exclude file in AND mode.
  222     else  // Condition matched.
  223       if (FileCtimeBeforeOR) 
  224         return false; // Include file in OR mode.
  225 
  226   if (FileCtimeAfter.IsSet()) // Filter present.
  227     if (ftc<FileCtimeAfter) // Condition not matched.
  228       if (FileCtimeAfterOR) 
  229         FilterOR=true; // Not matched OR filter is present.
  230       else
  231         return true; // Exclude file in AND mode.
  232     else  // Condition matched.
  233       if (FileCtimeAfterOR) 
  234         return false; // Include file in OR mode.
  235 
  236   if (FileAtimeBefore.IsSet()) // Filter present.
  237     if (fta>=FileAtimeBefore) // Condition not matched.
  238       if (FileAtimeBeforeOR) 
  239         FilterOR=true; // Not matched OR filter is present.
  240       else
  241         return true; // Exclude file in AND mode.
  242     else  // Condition matched.
  243       if (FileAtimeBeforeOR) 
  244         return false; // Include file in OR mode.
  245 
  246   if (FileAtimeAfter.IsSet()) // Filter present.
  247     if (fta<FileAtimeAfter) // Condition not matched.
  248       if (FileAtimeAfterOR) 
  249         FilterOR=true; // Not matched OR filter is present.
  250       else
  251         return true; // Exclude file in AND mode.
  252     else  // Condition matched.
  253       if (FileAtimeAfterOR) 
  254         return false; // Include file in OR mode.
  255 
  256   return FilterOR; // Exclude if all OR filters are not matched.
  257 }
  258 #endif
  259 
  260 
  261 #ifndef SFX_MODULE
  262 // Return 'true' if we need to exclude the file from processing.
  263 bool CommandData::SizeCheck(int64 Size)
  264 {
  265   if (Size==INT64NDF) // If called from archive formats like bzip2, not storing the file size.
  266     return false;
  267   if (FileSizeLess!=INT64NDF && Size>=FileSizeLess)
  268     return true;
  269   if (FileSizeMore!=INT64NDF && Size<=FileSizeMore)
  270     return true;
  271   return false;
  272 }
  273 #endif
  274 
  275 
  276 
  277 
  278 // Return 0 if file must not be processed or a number of matched parameter otherwise.
  279 int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
  280                                bool Flags,wchar *MatchedArg,uint MatchedArgSize)
  281 {
  282   if (MatchedArg!=NULL && MatchedArgSize>0)
  283     *MatchedArg=0;
  284   bool Dir=FileHead.Dir;
  285   if (ExclCheck(FileHead.FileName,Dir,false,true))
  286     return 0;
  287 #ifndef SFX_MODULE
  288   if (TimeCheck(FileHead.mtime,FileHead.ctime,FileHead.atime))
  289     return 0;
  290   if ((FileHead.FileAttr & ExclFileAttr)!=0 || FileHead.Dir && ExclDir)
  291     return 0;
  292   if (InclAttrSet && (!FileHead.Dir && (FileHead.FileAttr & InclFileAttr)==0 ||
  293       FileHead.Dir && !InclDir))
  294     return 0;
  295   if (!Dir && SizeCheck(FileHead.UnpSize))
  296     return 0;
  297 #endif
  298   wchar *ArgName;
  299   FileArgs.Rewind();
  300   for (int StringCount=1;(ArgName=FileArgs.GetString())!=NULL;StringCount++)
  301     if (CmpName(ArgName,FileHead.FileName,MatchType))
  302     {
  303       if (ExactMatch!=NULL)
  304         *ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0;
  305       if (MatchedArg!=NULL)
  306         wcsncpyz(MatchedArg,ArgName,MatchedArgSize);
  307       return StringCount;
  308     }
  309   return 0;
  310 }
  311 
  312 
  313 #if !defined(SFX_MODULE)
  314 void CommandData::SetStoreTimeMode(const wchar *S)
  315 {
  316   if (*S==0 || IsDigit(*S) || *S=='-' || *S=='+')
  317   {
  318     // Apply -ts, -ts1, -ts-, -ts+ to all 3 times.
  319     // Handle obsolete -ts[2,3,4] as ts+.
  320     EXTTIME_MODE Mode=EXTTIME_MAX;
  321     if (*S=='-')
  322       Mode=EXTTIME_NONE;
  323     if (*S=='1')
  324       Mode=EXTTIME_1S;
  325     xmtime=xctime=xatime=Mode;
  326     S++;
  327   }
  328 
  329   while (*S!=0)
  330   {
  331     EXTTIME_MODE Mode=EXTTIME_MAX;
  332     if (S[1]=='-')
  333       Mode=EXTTIME_NONE;
  334     if (S[1]=='1')
  335       Mode=EXTTIME_1S;
  336     switch(toupperw(*S))
  337     {
  338       case 'M':
  339         xmtime=Mode;
  340         break;
  341       case 'C':
  342         xctime=Mode;
  343         break;
  344       case 'A':
  345         xatime=Mode;
  346         break;
  347       case 'P':
  348         PreserveAtime=true;
  349         break;
  350     }
  351     S++;
  352   }
  353 }
  354 #endif