"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