Merge pull request #4011 from fritsch/vdpau-settings
[vuplus_xbmc] / lib / UnrarXLib / cmddata.cpp
1 #include "rar.hpp"
2
3 CommandData::CommandData()
4 {
5   FileArgs=ExclArgs=InclArgs=StoreArgs=ArcNames=NULL;
6   Init();
7 }
8
9
10 CommandData::~CommandData()
11 {
12   Close();
13 }
14
15
16 void CommandData::Init()
17 {
18   Close();
19
20   *Command=0;
21   *ArcName=0;
22   *ArcNameW=0;
23   FileLists=false;
24   NoMoreSwitches=false;
25   TimeConverted=false;
26
27   FileArgs=new StringList;
28   ExclArgs=new StringList;
29   InclArgs=new StringList;
30   StoreArgs=new StringList;
31   ArcNames=new StringList;
32 }
33
34
35 void CommandData::Close()
36 {
37   delete FileArgs;
38   delete ExclArgs;
39   delete InclArgs;
40   delete StoreArgs;
41   delete ArcNames;
42   FileArgs=ExclArgs=InclArgs=StoreArgs=ArcNames=NULL;
43   NextVolSizes.Reset();
44 }
45
46
47 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
48 void CommandData::ParseArg(char *Arg,wchar *ArgW)
49 {
50   if (IsSwitch(*Arg) && !NoMoreSwitches)
51     if (Arg[1]=='-')
52       NoMoreSwitches=true;
53     else
54       ProcessSwitch(&Arg[1]);
55   else
56     if (*Command==0)
57     {
58       strncpy(Command,Arg,sizeof(Command));
59       if (ArgW!=NULL)
60         strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0]));
61       if (toupper(*Command)=='S')
62       {
63         const char *SFXName=Command[1] ? Command+1:DefSFXName;
64         if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
65           strcpy(SFXModule,SFXName);
66         else
67           GetConfigName(SFXName,SFXModule,true);
68       }
69 #ifndef GUI
70       *Command=toupper(*Command);
71       if (*Command!='I' && *Command!='S')
72         strupper(Command);
73 #endif
74     }
75     else
76       if (*ArcName==0)
77       {
78         strncpy(ArcName,Arg,sizeof(ArcName));
79         if (ArgW!=NULL)
80           strncpyw(ArcNameW,ArgW,sizeof(ArcNameW)/sizeof(ArcNameW[0]));
81       }
82       else
83       {
84         int Length=strlen(Arg);
85         char EndChar=Arg[Length-1];
86         char CmdChar=toupper(*Command);
87         bool Add=strchr("AFUM",CmdChar)!=NULL;
88         bool Extract=CmdChar=='X' || CmdChar=='E';
89         if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add)
90           strcpy(ExtrPath,Arg);
91         else
92           if ((Add || CmdChar=='T') && *Arg!='@')
93             FileArgs->AddString(Arg);
94           else
95           {
96             struct FindData FileData;
97             bool Found=FindFile::FastFind(Arg,NULL,&FileData);
98             if (!Found && *Arg=='@' && !IsWildcard(Arg))
99             {
100               ReadTextFile(Arg+1,FileArgs,false,true,true,true,true);
101               FileLists=true;
102             }
103             else
104               if (Found && FileData.IsDir && Extract && *ExtrPath==0)
105               {
106                 strcpy(ExtrPath,Arg);
107                 AddEndSlash(ExtrPath);
108               }
109               else
110                 FileArgs->AddString(Arg);
111           }
112       }
113 }
114 #endif
115
116
117 void CommandData::ParseDone()
118 {
119   if (FileArgs->ItemsCount()==0 && !FileLists)
120     FileArgs->AddString(MASKALL);
121   char CmdChar=toupper(*Command);
122   bool Extract=CmdChar=='X' || CmdChar=='E';
123   if (Test && Extract)
124     Test=false;
125   BareOutput=(CmdChar=='L' || CmdChar=='V') && Command[1]=='B';
126 }
127
128
129 #if !defined(SFX_MODULE) && !defined(_WIN_CE) && !defined(TARGET_POSIX)
130 void CommandData::ParseEnvVar()
131 {
132   char *EnvStr=getenv("RAR");
133   if (EnvStr!=NULL)
134     ProcessSwitchesString(EnvStr);
135 }
136 #endif
137
138
139 #if !defined(GUI) && !defined(SFX_MODULE)
140 bool CommandData::IsConfigEnabled(int argc,char *argv[])
141 {
142   bool ConfigEnabled=true;
143   for (int I=1;I<argc;I++)
144     if (IsSwitch(*argv[I]))
145     {
146       if (stricomp(&argv[I][1],"cfg-")==0)
147         ConfigEnabled=false;
148       if (strnicomp(&argv[I][1],"ilog",4)==0)
149       {
150         ProcessSwitch(&argv[I][1]);
151         InitLogOptions(LogName);
152       }
153     }
154   return(ConfigEnabled);}
155 #endif
156
157
158 #if !defined(GUI) && !defined(SFX_MODULE)
159 void CommandData::ReadConfig(int argc,char *argv[])
160 {
161   StringList List;
162   if (ReadTextFile((char*)DefConfigName,&List,true))
163   {
164     char *Str;
165     while ((Str=List.GetString())!=NULL)
166       if (strnicomp(Str,"switches=",9)==0)
167         ProcessSwitchesString(Str+9);
168   }
169 }
170 #endif
171
172
173 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
174 void CommandData::ProcessSwitchesString(char *Str)
175 {
176   while (*Str)
177   {
178     while (!IsSwitch(*Str) && *Str!=0)
179       Str++;
180     if (*Str==0)
181       break;
182     char *Next=Str;
183     while (!(Next[0]==' ' && IsSwitch(Next[1])) && *Next!=0)
184       Next++;
185     char NextChar=*Next;
186     *Next=0;
187     ProcessSwitch(Str+1);
188     *Next=NextChar;
189     Str=Next;
190   }
191 }
192 #endif
193
194
195 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
196 void CommandData::ProcessSwitch(char *Switch)
197 {
198
199   switch(toupper(Switch[0]))
200   {
201     case 'I':
202       if (strnicomp(&Switch[1],"LOG",3)==0)
203       {
204         strncpy(LogName,Switch[4] ? Switch+4:DefLogName,sizeof(LogName));
205         break;
206       }
207       if (stricomp(&Switch[1],"SND")==0)
208       {
209         Sound=true;
210         break;
211       }
212       if (stricomp(&Switch[1],"ERR")==0)
213       {
214         MsgStream=MSG_STDERR;
215         break;
216       }
217       if (strnicomp(&Switch[1],"EML",3)==0)
218       {
219         strncpy(EmailTo,Switch[4] ? Switch+4:"@",sizeof(EmailTo));
220         EmailTo[sizeof(EmailTo)-1]=0;
221         break;
222       }
223       if (stricomp(&Switch[1],"NUL")==0)
224       {
225         MsgStream=MSG_NULL;
226         break;
227       }
228       if (toupper(Switch[1])=='D')
229       {
230         for (int I=2;Switch[I]!=0;I++)
231           switch(toupper(Switch[I]))
232           {
233             case 'Q':
234               MsgStream=MSG_ERRONLY;
235               break;
236             case 'C':
237               DisableCopyright=true;
238               break;
239             case 'D':
240               DisableDone=true;
241               break;
242             case 'P':
243               DisablePercentage=true;
244               break;
245           }
246         break;
247       }
248       if (stricomp(&Switch[1],"OFF")==0)
249       {
250         Shutdown=true;
251         break;
252       }
253       break;
254     case 'T':
255       switch(toupper(Switch[1]))
256       {
257         case 'K':
258           ArcTime=ARCTIME_KEEP;
259           break;
260         case 'L':
261           ArcTime=ARCTIME_LATEST;
262           break;
263         case 'O':
264           FileTimeBefore.SetAgeText(Switch+2);
265           break;
266         case 'N':
267           FileTimeAfter.SetAgeText(Switch+2);
268           break;
269         case 'B':
270           FileTimeBefore.SetIsoText(Switch+2);
271           break;
272         case 'A':
273           FileTimeAfter.SetIsoText(Switch+2);
274           break;
275         case 'S':
276           {
277             EXTTIME_MODE Mode=EXTTIME_HIGH3;
278             bool CommonMode=Switch[2]>='0' && Switch[2]<='4';
279             if (CommonMode)
280               Mode=(EXTTIME_MODE)(Switch[2]-'0');
281             if (Switch[2]=='-')
282               Mode=EXTTIME_NONE;
283             if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0)
284               xmtime=xctime=xatime=Mode;
285             else
286             {
287               if (Switch[3]>='0' && Switch[3]<='4')
288                 Mode=(EXTTIME_MODE)(Switch[3]-'0');
289               if (Switch[3]=='-')
290                 Mode=EXTTIME_NONE;
291               switch(toupper(Switch[2]))
292               {
293                 case 'M':
294                   xmtime=Mode;
295                   break;
296                 case 'C':
297                   xctime=Mode;
298                   break;
299                 case 'A':
300                   xatime=Mode;
301                   break;
302                 case 'R':
303                   xarctime=Mode;
304                   break;
305               }
306             }
307           }
308           break;
309         case '-':
310           Test=false;
311           break;
312         case 0:
313           Test=true;
314           break;
315         default:
316           BadSwitch(Switch);
317           break;
318       }
319       break;
320     case 'A':
321       switch(toupper(Switch[1]))
322       {
323         case 'C':
324           ClearArc=true;
325           break;
326         case 'D':
327           AppendArcNameToPath=true;
328           break;
329         case 'G':
330           if (Switch[2]=='-' && Switch[3]==0)
331             GenerateArcName=0;
332           else
333           {
334             GenerateArcName=true;
335             strncpy(GenerateMask,Switch+2,sizeof(GenerateMask));
336           }
337           break;
338         case 'N': //reserved for archive name
339           break;
340         case 'O':
341           AddArcOnly=true;
342           break;
343         case 'P':
344           strcpy(ArcPath,Switch+2);
345           break;
346         case 'S':
347           SyncFiles=true;
348           break;
349       }
350       break;
351     case 'D':
352       if (Switch[2]==0)
353         switch(toupper(Switch[1]))
354         {
355           case 'S':
356             DisableSortSolid=true;
357             break;
358           case 'H':
359             OpenShared=true;
360             break;
361           case 'F':
362             DeleteFiles=true;
363             break;
364         }
365       break;
366     case 'O':
367       switch(toupper(Switch[1]))
368       {
369         case '+':
370           Overwrite=OVERWRITE_ALL;
371           break;
372         case '-':
373           Overwrite=OVERWRITE_NONE;
374           break;
375         case 'W':
376           ProcessOwners=true;
377           break;
378 #ifdef SAVE_LINKS
379         case 'L':
380           SaveLinks=true;
381           break;
382 #endif
383 #ifdef _WIN_32
384         case 'S':
385           SaveStreams=true;
386           break;
387     case 'C':
388           SetCompressedAttr=true;
389           break;
390 #endif
391         default :
392           BadSwitch(Switch);
393           break;
394       }
395       break;
396     case 'R':
397       switch(toupper(Switch[1]))
398       {
399         case 0:
400           Recurse=RECURSE_ALWAYS;
401           break;
402         case '-':
403           Recurse=0;
404           break;
405         case '0':
406           Recurse=RECURSE_WILDCARDS;
407           break;
408         case 'I':
409           {
410             Priority=atoi(Switch+2);
411             char *ChPtr=strchr(Switch+2,':');
412             if (ChPtr!=NULL)
413       {
414               SleepTime=atoi(ChPtr+1);
415               InitSystemOptions(SleepTime);
416             }
417             SetPriority(Priority);
418           }
419           break;
420       }
421       break;
422     case 'Y':
423       AllYes=true;
424       break;
425     case 'N':
426     case 'X':
427       if (Switch[1]!=0)
428       {
429         StringList *Args=toupper(Switch[0])=='N' ? InclArgs:ExclArgs;
430         if (Switch[1]=='@' && !IsWildcard(Switch))
431           ReadTextFile(Switch+2,Args,false,true,true,true,true);
432         else
433           Args->AddString(Switch+1);
434      }
435      break;
436     case 'E':
437       switch(toupper(Switch[1]))
438       {
439         case 'P':
440           switch(Switch[2])
441           {
442             case 0:
443               ExclPath=EXCL_SKIPWHOLEPATH;
444               break;
445             case '1':
446               ExclPath=EXCL_BASEPATH;
447               break;
448             case '2':
449               ExclPath=EXCL_SAVEFULLPATH;
450               break;
451             case '3':
452               ExclPath=EXCL_ABSPATH;
453               break;
454           }
455           break;
456         case 'D':
457           ExclEmptyDir=true;
458           break;
459         case 'E':
460           ProcessEA=false;
461           break;
462         case 'N':
463           NoEndBlock=true;
464           break;
465         default:
466           if (Switch[1]=='+')
467           {
468             InclFileAttr=GetExclAttr(&Switch[2]);
469             InclAttrSet=true;
470           }
471           else
472             ExclFileAttr=GetExclAttr(&Switch[1]);
473           break;
474       }
475       break;
476     case 'P':
477       if (Switch[1]==0)
478       {
479         GetPassword(PASSWORD_GLOBAL,NULL,Password,sizeof(Password));
480         eprintf("\n");
481       }
482       else
483         strncpy(Password,Switch+1,sizeof(Password));
484       break;
485     case 'H':
486       if (toupper(Switch[1])=='P')
487       {
488         EncryptHeaders=true;
489         if (Switch[2]!=0)
490           strncpy(Password,Switch+2,sizeof(Password));
491         else
492           if (*Password==0)
493           {
494             GetPassword(PASSWORD_GLOBAL,NULL,Password,sizeof(Password));
495             eprintf("\n");
496           }
497       }
498       break;
499     case 'Z':
500       strncpy(CommentFile,Switch[1]!=0 ? Switch+1:"stdin",sizeof(CommentFile));
501       break;
502     case 'M':
503       switch(toupper(Switch[1]))
504       {
505         case 'C':
506           {
507             char *Str=Switch+2;
508             if (*Str=='-')
509               for (unsigned int I=0;I<sizeof(FilterModes)/sizeof(FilterModes[0]);I++)
510                 FilterModes[I].State=FILTER_DISABLE;
511             else
512               while (*Str)
513               {
514                 int Param1=0,Param2=0;
515                 FilterState State=FILTER_AUTO;
516                 FilterType Type=FILTER_NONE;
517                 if (isdigit(*Str))
518                 {
519                   Param1=atoi(Str);
520                   while (isdigit(*Str))
521                     Str++;
522                 }
523                 if (*Str==':' && isdigit(Str[1]))
524                 {
525                   Param2=atoi(++Str);
526                   while (isdigit(*Str))
527                     Str++;
528                 }
529                 switch(toupper(*(Str++)))
530                 {
531                   case 'T': Type=FILTER_PPM;         break;
532                   case 'E': Type=FILTER_E8;          break;
533                   case 'D': Type=FILTER_DELTA;       break;
534                   case 'A': Type=FILTER_AUDIO;       break;
535                   case 'C': Type=FILTER_RGB;         break;
536                   case 'I': Type=FILTER_ITANIUM;     break;
537                   case 'L': Type=FILTER_UPCASETOLOW; break;
538                 }
539                 if (*Str=='+' || *Str=='-')
540                   State=*(Str++)=='+' ? FILTER_FORCE:FILTER_DISABLE;
541                 FilterModes[Type].State=State;
542                 FilterModes[Type].Param1=Param1;
543                 FilterModes[Type].Param2=Param2;
544               }
545             }
546           break;
547         case 'M':
548           break;
549         case 'D':
550           {
551             if ((WinSize=atoi(&Switch[2]))==0)
552               WinSize=0x10000<<(toupper(Switch[2])-'A');
553             else
554               WinSize*=1024;
555             if (!CheckWinSize())
556               BadSwitch(Switch);
557           }
558           break;
559         case 'S':
560           {
561             char *Names=Switch+2,DefNames[512];
562             if (*Names==0)
563             {
564               strcpy(DefNames,DefaultStoreList);
565               Names=DefNames;
566             }
567             while (*Names!=0)
568             {
569               char *End=strchr(Names,';');
570               if (End!=NULL)
571                 *End=0;
572               if (*Names=='.')
573                 Names++;
574               char Mask[NM];
575               if (strpbrk(Names,"*?.")==NULL)
576                 sprintf(Mask,"*.%s",Names);
577               else
578                 strcpy(Mask,Names);
579               StoreArgs->AddString(Mask);
580               if (End==NULL)
581                 break;
582               Names=End+1;
583             }
584           }
585           break;
586         default:
587           Method=Switch[1]-'0';
588           if (Method>5 || Method<0)
589             BadSwitch(Switch);
590           break;
591       }
592       break;
593     case 'V':
594       switch(toupper(Switch[1]))
595       {
596 #ifdef _WIN_32
597         case 'D':
598           EraseDisk=true;
599           break;
600 #endif
601         case 'N':
602           OldNumbering=true;
603           break;
604         case 'P':
605           VolumePause=true;
606           break;
607         case 'E':
608           if (toupper(Switch[2])=='R')
609             VersionControl=atoi(Switch+3)+1;
610           break;
611         case '-':
612           VolSize=0;
613           break;
614         default:
615           {
616             Int64 NewVolSize=atoil(&Switch[1]);
617
618             if (NewVolSize==0)
619               NewVolSize=INT64ERR;
620             else
621               switch (Switch[strlen(Switch)-1])
622               {
623                 case 'f':
624                 case 'F':
625                   switch(int64to32(NewVolSize))
626                   {
627                     case 360:
628                       NewVolSize=362496;
629                       break;
630                     case 720:
631                       NewVolSize=730112;
632                       break;
633                     case 1200:
634                       NewVolSize=1213952;
635                       break;
636                     case 1440:
637                       NewVolSize=1457664;
638                       break;
639                     case 2880:
640                       NewVolSize=2915328;
641                       break;
642                   }
643                   break;
644                 case 'k':
645                   NewVolSize*=1024;
646                   break;
647                 case 'm':
648                   NewVolSize*=1024*1024;
649                   break;
650                 case 'M':
651                   NewVolSize*=1000*1000;
652                   break;
653                 case 'g':
654                   NewVolSize*=1024*1024;
655                   NewVolSize*=1024;
656                   break;
657                 case 'G':
658                   NewVolSize*=1000*1000;
659                   NewVolSize*=1000;
660                   break;
661                 case 'b':
662                 case 'B':
663                   break;
664                 default:
665                   NewVolSize*=1000;
666                   break;
667               }
668             if (VolSize==0)
669               VolSize=NewVolSize;
670             else
671               NextVolSizes.Push(NewVolSize);
672           }
673           break;
674       }
675       break;
676     case 'F':
677       if (Switch[1]==0)
678         FreshFiles=true;
679       break;
680     case 'U':
681       if (Switch[1]==0)
682         UpdateFiles=true;
683       break;
684     case 'W':
685       strncpy(TempPath,&Switch[1],sizeof(TempPath)-1);
686       AddEndSlash(TempPath);
687       break;
688     case 'S':
689       if (strnicomp(Switch,"SFX",3)==0)
690       {
691         const char *SFXName=Switch[3] ? Switch+3:DefSFXName;
692         if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
693           strcpy(SFXModule,SFXName);
694         else
695           GetConfigName(SFXName,SFXModule,true);
696       }
697       if (isdigit(Switch[1]))
698       {
699         Solid|=SOLID_COUNT;
700         SolidCount=atoi(&Switch[1]);
701       }
702       else
703         switch(toupper(Switch[1]))
704         {
705           case 0:
706             Solid|=SOLID_NORMAL;
707             break;
708           case '-':
709             Solid=SOLID_NONE;
710             break;
711           case 'E':
712             Solid|=SOLID_FILEEXT;
713             break;
714           case 'V':
715             Solid|=Switch[2]=='-' ? SOLID_VOLUME_DEPENDENT:SOLID_VOLUME_INDEPENDENT;
716             break;
717           case 'D':
718             Solid|=SOLID_VOLUME_DEPENDENT;
719             break;
720         }
721       break;
722     case 'C':
723       if (Switch[2]==0)
724         switch(toupper(Switch[1]))
725         {
726           case '-':
727             DisableComment=true;
728             break;
729           case 'U':
730             ConvertNames=NAMES_UPPERCASE;
731             break;
732           case 'L':
733             ConvertNames=NAMES_LOWERCASE;
734             break;
735         }
736       break;
737     case 'K':
738       switch(toupper(Switch[1]))
739       {
740         case 'B':
741           KeepBroken=true;
742           break;
743         case 0:
744           Lock=true;
745           break;
746       }
747       break;
748 #ifndef GUI
749     case '?' :
750       OutHelp();
751       break;
752 #endif
753     default :
754       BadSwitch(Switch);
755       break;
756   }
757 }
758 #endif
759
760
761 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
762 void CommandData::BadSwitch(char *Switch)
763 {
764   mprintf(St(MUnknownOption),Switch);
765   ErrHandler.Exit(USER_ERROR);
766 }
767 #endif
768
769
770 #ifndef GUI
771 void CommandData::OutTitle()
772 {
773   if (BareOutput || DisableCopyright)
774     return;
775 #if defined(__GNUC__) && defined(SFX_MODULE)
776   mprintf(St(MCopyrightS));
777 #else
778 #ifndef SILENT
779   static bool TitleShown=false;
780   if (TitleShown)
781     return;
782   TitleShown=true;
783   char Version[50];
784   int Beta=RARVER_BETA;
785   if (Beta!=0)
786     sprintf(Version,"%d.%02d %s %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA);
787   else
788     sprintf(Version,"%d.%02d",RARVER_MAJOR,RARVER_MINOR);
789 #ifdef UNRAR
790   mprintf(St(MUCopyright),Version,RARVER_YEAR);
791 #else
792 #endif
793 #endif
794 #endif
795 }
796 #endif
797
798
799 void CommandData::OutHelp()
800 {
801 #if !defined(GUI) && !defined(SILENT)
802   OutTitle();
803   static MSGID Help[]={
804 #ifdef SFX_MODULE
805     MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV
806 #elif defined(UNRAR)
807     MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL,MCHelpCmdP,
808     MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm,MCHelpSwAC,MCHelpSwAD,
809     MCHelpSwAP,MCHelpSwAVm,MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,
810     MCHelpSwDH,MCHelpSwEP,MCHelpSwEP3,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
811     MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
812     MCHelpSwOp,MCHelpSwOm,MCHelpSwOC,MCHelpSwOW,MCHelpSwP,MCHelpSwPm,
813     MCHelpSwR,MCHelpSwRI,MCHelpSwTA,MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,
814     MCHelpSwTS,MCHelpSwU,MCHelpSwVUnr,MCHelpSwVER,MCHelpSwVP,MCHelpSwX,
815     MCHelpSwXa,MCHelpSwXal,MCHelpSwY
816 #else
817     MRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdA,MCHelpCmdC,MCHelpCmdCF,
818     MCHelpCmdCW,MCHelpCmdD,MCHelpCmdE,MCHelpCmdF,MCHelpCmdI,MCHelpCmdK,
819     MCHelpCmdL,MCHelpCmdM,MCHelpCmdP,MCHelpCmdR,MCHelpCmdRC,MCHelpCmdRN,
820     MCHelpCmdRR,MCHelpCmdRV,MCHelpCmdS,MCHelpCmdT,MCHelpCmdU,MCHelpCmdV,
821     MCHelpCmdX,MCHelpSw,MCHelpSwm,MCHelpSwAC,MCHelpSwAD,MCHelpSwAG,
822     MCHelpSwAO,MCHelpSwAP,MCHelpSwAS,MCHelpSwAV,MCHelpSwAVm,MCHelpSwCm,
823     MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,MCHelpSwDF,MCHelpSwDH,MCHelpSwDS,
824     MCHelpSwEa,MCHelpSwED,MCHelpSwEE,MCHelpSwEN,MCHelpSwEP,MCHelpSwEP1,
825     MCHelpSwEP2,MCHelpSwEP3,MCHelpSwF,MCHelpSwHP,MCHelpSwIDP,MCHelpSwIEML,
826     MCHelpSwIERR,MCHelpSwILOG,MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwISND,
827     MCHelpSwK,MCHelpSwKB,MCHelpSwMn,MCHelpSwMC,MCHelpSwMD,MCHelpSwMS,
828     MCHelpSwN,MCHelpSwNa,MCHelpSwNal,MCHelpSwOp,MCHelpSwOm,MCHelpSwOC,
829     MCHelpSwOL,MCHelpSwOS,MCHelpSwOW,MCHelpSwP,MCHelpSwPm,MCHelpSwR,
830     MCHelpSwR0,MCHelpSwRI,MCHelpSwRR,MCHelpSwRV,MCHelpSwS,MCHelpSwSm,
831     MCHelpSwSFX,MCHelpSwSI,MCHelpSwT,MCHelpSwTA,MCHelpSwTB,MCHelpSwTK,
832     MCHelpSwTL,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,MCHelpSwV,
833     MCHelpSwVn,MCHelpSwVD,MCHelpSwVER,MCHelpSwVN,MCHelpSwVP,MCHelpSwW,
834     MCHelpSwX,MCHelpSwXa,MCHelpSwXal,MCHelpSwY,MCHelpSwZ
835 #endif
836   };
837
838   for (int I=0;I<sizeof(Help)/sizeof(Help[0]);I++)
839   {
840 #ifndef SFX_MODULE
841 #ifdef DISABLEAUTODETECT
842     if (Help[I]==MCHelpSwV)
843       continue;
844 #endif
845 #ifndef _WIN_32
846     static MSGID Win32Only[]={
847       MCHelpSwIEML,MCHelpSwVD,MCHelpSwAC,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF,
848       MCHelpSwEP2,MCHelpSwOC
849     };
850     bool Found=false;
851     for (int J=0;J<sizeof(Win32Only)/sizeof(Win32Only[0]);J++)
852       if (Help[I]==Win32Only[J])
853       {
854         Found=true;
855         break;
856       }
857     if (Found)      continue;
858 #endif
859 #if !defined(_UNIX) && !defined(_WIN_32)
860     if (Help[I]==MCHelpSwOW)
861       continue;
862 #endif
863 #ifndef SAVE_LINKS
864     if (Help[I]==MCHelpSwOL)
865       continue;
866 #endif
867 #if defined(_WIN_32)
868     if (Help[I]==MCHelpSwRI)
869       continue;
870 #endif
871 #if !defined(_BEOS)
872     if (Help[I]==MCHelpSwEE)
873     {
874 #if defined(_EMX) && !defined(_DJGPP)
875       if (_osmode != OS2_MODE)
876         continue;
877 #else
878       continue;
879 #endif
880     }
881 #endif
882 #endif
883     mprintf(St(Help[I]));
884   }
885   mprintf("\n");
886   ErrHandler.Exit(0);
887 #endif
888 }
889
890
891 bool CommandData::ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode)
892 {
893   char *Name=ConvertPath(CheckName,NULL);
894   char FullName[NM],*CurName;
895   *FullName=0;
896   Args->Rewind();
897   while ((CurName=Args->GetString())!=NULL)
898 #ifndef SFX_MODULE
899     if (CheckFullPath && IsFullPath(CurName))
900     {
901       if (*FullName==0)
902         ConvertNameToFull(CheckName,FullName);
903       if (CmpName(CurName,FullName,MatchMode))
904         return(true);
905     }
906     else
907 #endif
908       if (CmpName(ConvertPath(CurName,NULL),Name,MatchMode))
909         return(true);
910   return(false);
911 }
912
913
914 bool CommandData::ExclCheck(char *CheckName,bool CheckFullPath)
915 {
916   if (ExclCheckArgs(ExclArgs,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
917     return(true);
918   if (InclArgs->ItemsCount()==0)
919     return(false);
920   if (ExclCheckArgs(InclArgs,CheckName,CheckFullPath,MATCH_NAMES))
921     return(false);
922   return(true);
923 }
924
925
926
927
928 #ifndef SFX_MODULE
929 bool CommandData::TimeCheck(RarTime &ft)
930 {
931   if (FileTimeBefore.IsSet() && ft>=FileTimeBefore)
932     return(true);
933   if (FileTimeAfter.IsSet() && ft<=FileTimeAfter)
934     return(true);
935 /*
936   if (FileTimeOlder!=0 || FileTimeNewer!=0)
937   {
938     if (!TimeConverted)
939     {
940       if (FileTimeOlder!=0)
941         FileTimeOlder=SecondsToDosTime(FileTimeOlder);
942       if (FileTimeNewer!=0)
943         FileTimeNewer=SecondsToDosTime(FileTimeNewer);
944       TimeConverted=true;
945     }
946     if (FileTimeOlder!=0 && ft>=FileTimeOlder)
947       return(true);
948     if (FileTimeNewer!=0 && ft<=FileTimeNewer)
949       return(true);
950
951   }
952 */
953   return(false);
954 }
955 #endif
956
957
958 int CommandData::IsProcessFile(FileHeader &NewLhd,bool *ExactMatch,int MatchType)
959 {
960   if (strlen(NewLhd.FileName)>=NM || strlenw(NewLhd.FileNameW)>=NM)
961     return(0);
962   if (ExclCheck(NewLhd.FileName,false))
963     return(0);
964 #ifndef SFX_MODULE
965   if (TimeCheck(NewLhd.mtime))
966     return(0);
967 #endif
968   char *ArgName;
969   wchar *ArgNameW;
970   FileArgs->Rewind();
971   for (int StringCount=1;FileArgs->GetString(&ArgName,&ArgNameW);StringCount++)
972   {
973 #ifndef SFX_MODULE
974     bool Unicode=(NewLhd.Flags & LHD_UNICODE) || ArgNameW!=NULL;
975     if (Unicode)
976     {
977       wchar NameW[NM],ArgW[NM],*NamePtr=NewLhd.FileNameW;
978       bool CorrectUnicode=true;
979       if (ArgNameW==NULL)
980       {
981         if (!CharToWide(ArgName,ArgW) || *ArgW==0)
982           CorrectUnicode=false;
983         ArgNameW=ArgW;
984       }
985       if ((NewLhd.Flags & LHD_UNICODE)==0)
986       {
987         if (!CharToWide(NewLhd.FileName,NameW) || *NameW==0)
988           CorrectUnicode=false;
989         NamePtr=NameW;
990       }
991       if (CmpName(ArgNameW,NamePtr,MatchType))
992       {
993         if (ExactMatch!=NULL)
994           *ExactMatch=stricompcw(ArgNameW,NamePtr)==0;
995         return(StringCount);
996       }
997       if (CorrectUnicode)
998         continue;
999     }
1000 #endif
1001     if (CmpName(ArgName,NewLhd.FileName,MatchType))
1002     {
1003       if (ExactMatch!=NULL)
1004         *ExactMatch=stricompc(ArgName,NewLhd.FileName)==0;
1005       return(StringCount);
1006     }
1007   }
1008   return(0);
1009 }
1010
1011
1012 #ifndef _WIN_CE
1013 void CommandData::ProcessCommand()
1014 {
1015 #ifndef SFX_MODULE
1016   if ((Command[1] && (strchr("FUADPXETK",*Command)!=NULL)) || *ArcName==0)
1017     OutHelp();
1018
1019 #ifdef _UNIX
1020   if (GetExt(ArcName)==NULL && (!FileExist(ArcName) || IsDir(GetFileAttr(ArcName))))
1021     strcat(ArcName,".rar");
1022 #else
1023   if (GetExt(ArcName)==NULL)
1024     strcat(ArcName,".rar");
1025 #endif
1026
1027   if (strchr("AFUMD",*Command)==NULL)
1028   {
1029     StringList ArcMasks;
1030     ArcMasks.AddString(ArcName);
1031     ScanTree Scan(&ArcMasks,Recurse,SaveLinks,SCAN_SKIPDIRS);
1032     FindData FindData;
1033     while (Scan.GetNext(&FindData)==SCAN_SUCCESS)
1034       AddArcName(FindData.Name,FindData.NameW);
1035   }
1036   else
1037     AddArcName(ArcName,NULL);
1038 #endif
1039
1040   switch(Command[0])
1041   {
1042     case 'P':
1043     case 'X':
1044     case 'E':
1045     case 'T':
1046     case 'I':
1047       {
1048         CmdExtract Extract;
1049         Extract.DoExtract(this);
1050       }
1051       break;
1052 #if !defined(GUI) && !defined(SILENT)
1053     case 'V':
1054     case 'L':
1055       ListArchive(this);
1056       break;
1057     default:
1058       OutHelp();
1059 #endif
1060   }
1061 #ifndef GUI
1062   if (!BareOutput)
1063   {
1064     mprintf("\n");
1065   }
1066 #endif
1067 }
1068 #endif
1069
1070
1071 void CommandData::AddArcName(char *Name,wchar *NameW)
1072 {
1073   ArcNames->AddString(Name,NameW);
1074 }
1075
1076
1077 bool CommandData::GetArcName(char *Name,wchar *NameW,int MaxSize)
1078 {
1079   if (!ArcNames->GetString(Name,NameW,NM))
1080     return(false);
1081   return(true);
1082 }
1083
1084
1085 bool CommandData::IsSwitch(int Ch)
1086 {
1087 #if defined(_WIN_32) || defined(_EMX)
1088   return(Ch=='-' || Ch=='/');
1089 #else
1090   return(Ch=='-');
1091 #endif
1092 }
1093
1094
1095 #ifndef SFX_MODULE
1096 uint CommandData::GetExclAttr(char *Str)
1097 {
1098   if (isdigit(*Str))
1099     return(strtol(Str,NULL,0));
1100   else
1101   {
1102     uint Attr;
1103     for (Attr=0;*Str;Str++)
1104       switch(toupper(*Str))
1105       {
1106 #ifdef _UNIX
1107         case 'D':
1108           Attr|=S_IFDIR;
1109           break;
1110         case 'V':
1111           Attr|=S_IFCHR;
1112           break;
1113 #elif defined(_WIN_32) || defined(_EMX)
1114         case 'R':
1115           Attr|=0x1;
1116           break;
1117         case 'H':
1118           Attr|=0x2;
1119           break;
1120         case 'S':
1121           Attr|=0x4;
1122           break;
1123         case 'D':
1124           Attr|=0x10;
1125           break;
1126         case 'A':
1127           Attr|=0x20;
1128           break;
1129 #endif
1130       }
1131     return(Attr);
1132   }
1133 }
1134 #endif
1135
1136 #ifndef SFX_MODULE
1137 bool CommandData::CheckWinSize()
1138 {
1139   static unsigned int ValidSize[]={
1140     0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000
1141   };
1142   for (unsigned int I=0;I<sizeof(ValidSize)/sizeof(ValidSize[0]);I++)
1143     if (WinSize==ValidSize[I])
1144       return(true);
1145   WinSize=0x400000;
1146   return(false);
1147 }
1148 #endif