3 CommandData::CommandData()
5 FileArgs=ExclArgs=InclArgs=StoreArgs=ArcNames=NULL;
10 CommandData::~CommandData()
16 void CommandData::Init()
27 FileArgs=new StringList;
28 ExclArgs=new StringList;
29 InclArgs=new StringList;
30 StoreArgs=new StringList;
31 ArcNames=new StringList;
35 void CommandData::Close()
42 FileArgs=ExclArgs=InclArgs=StoreArgs=ArcNames=NULL;
47 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
48 void CommandData::ParseArg(char *Arg,wchar *ArgW)
50 if (IsSwitch(*Arg) && !NoMoreSwitches)
54 ProcessSwitch(&Arg[1]);
58 strncpy(Command,Arg,sizeof(Command));
60 strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0]));
61 if (toupper(*Command)=='S')
63 const char *SFXName=Command[1] ? Command+1:DefSFXName;
64 if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
65 strcpy(SFXModule,SFXName);
67 GetConfigName(SFXName,SFXModule,true);
70 *Command=toupper(*Command);
71 if (*Command!='I' && *Command!='S')
78 strncpy(ArcName,Arg,sizeof(ArcName));
80 strncpyw(ArcNameW,ArgW,sizeof(ArcNameW)/sizeof(ArcNameW[0]));
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)
92 if ((Add || CmdChar=='T') && *Arg!='@')
93 FileArgs->AddString(Arg);
96 struct FindData FileData;
97 bool Found=FindFile::FastFind(Arg,NULL,&FileData);
98 if (!Found && *Arg=='@' && !IsWildcard(Arg))
100 ReadTextFile(Arg+1,FileArgs,false,true,true,true,true);
104 if (Found && FileData.IsDir && Extract && *ExtrPath==0)
106 strcpy(ExtrPath,Arg);
107 AddEndSlash(ExtrPath);
110 FileArgs->AddString(Arg);
117 void CommandData::ParseDone()
119 if (FileArgs->ItemsCount()==0 && !FileLists)
120 FileArgs->AddString(MASKALL);
121 char CmdChar=toupper(*Command);
122 bool Extract=CmdChar=='X' || CmdChar=='E';
125 BareOutput=(CmdChar=='L' || CmdChar=='V') && Command[1]=='B';
129 #if !defined(SFX_MODULE) && !defined(_WIN_CE) && !defined(TARGET_POSIX)
130 void CommandData::ParseEnvVar()
132 char *EnvStr=getenv("RAR");
134 ProcessSwitchesString(EnvStr);
139 #if !defined(GUI) && !defined(SFX_MODULE)
140 bool CommandData::IsConfigEnabled(int argc,char *argv[])
142 bool ConfigEnabled=true;
143 for (int I=1;I<argc;I++)
144 if (IsSwitch(*argv[I]))
146 if (stricomp(&argv[I][1],"cfg-")==0)
148 if (strnicomp(&argv[I][1],"ilog",4)==0)
150 ProcessSwitch(&argv[I][1]);
151 InitLogOptions(LogName);
154 return(ConfigEnabled);}
158 #if !defined(GUI) && !defined(SFX_MODULE)
159 void CommandData::ReadConfig(int argc,char *argv[])
162 if (ReadTextFile((char*)DefConfigName,&List,true))
165 while ((Str=List.GetString())!=NULL)
166 if (strnicomp(Str,"switches=",9)==0)
167 ProcessSwitchesString(Str+9);
173 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
174 void CommandData::ProcessSwitchesString(char *Str)
178 while (!IsSwitch(*Str) && *Str!=0)
183 while (!(Next[0]==' ' && IsSwitch(Next[1])) && *Next!=0)
187 ProcessSwitch(Str+1);
195 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
196 void CommandData::ProcessSwitch(char *Switch)
199 switch(toupper(Switch[0]))
202 if (strnicomp(&Switch[1],"LOG",3)==0)
204 strncpy(LogName,Switch[4] ? Switch+4:DefLogName,sizeof(LogName));
207 if (stricomp(&Switch[1],"SND")==0)
212 if (stricomp(&Switch[1],"ERR")==0)
214 MsgStream=MSG_STDERR;
217 if (strnicomp(&Switch[1],"EML",3)==0)
219 strncpy(EmailTo,Switch[4] ? Switch+4:"@",sizeof(EmailTo));
220 EmailTo[sizeof(EmailTo)-1]=0;
223 if (stricomp(&Switch[1],"NUL")==0)
228 if (toupper(Switch[1])=='D')
230 for (int I=2;Switch[I]!=0;I++)
231 switch(toupper(Switch[I]))
234 MsgStream=MSG_ERRONLY;
237 DisableCopyright=true;
243 DisablePercentage=true;
248 if (stricomp(&Switch[1],"OFF")==0)
255 switch(toupper(Switch[1]))
258 ArcTime=ARCTIME_KEEP;
261 ArcTime=ARCTIME_LATEST;
264 FileTimeBefore.SetAgeText(Switch+2);
267 FileTimeAfter.SetAgeText(Switch+2);
270 FileTimeBefore.SetIsoText(Switch+2);
273 FileTimeAfter.SetIsoText(Switch+2);
277 EXTTIME_MODE Mode=EXTTIME_HIGH3;
278 bool CommonMode=Switch[2]>='0' && Switch[2]<='4';
280 Mode=(EXTTIME_MODE)(Switch[2]-'0');
283 if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0)
284 xmtime=xctime=xatime=Mode;
287 if (Switch[3]>='0' && Switch[3]<='4')
288 Mode=(EXTTIME_MODE)(Switch[3]-'0');
291 switch(toupper(Switch[2]))
321 switch(toupper(Switch[1]))
327 AppendArcNameToPath=true;
330 if (Switch[2]=='-' && Switch[3]==0)
334 GenerateArcName=true;
335 strncpy(GenerateMask,Switch+2,sizeof(GenerateMask));
338 case 'N': //reserved for archive name
344 strcpy(ArcPath,Switch+2);
353 switch(toupper(Switch[1]))
356 DisableSortSolid=true;
367 switch(toupper(Switch[1]))
370 Overwrite=OVERWRITE_ALL;
373 Overwrite=OVERWRITE_NONE;
388 SetCompressedAttr=true;
397 switch(toupper(Switch[1]))
400 Recurse=RECURSE_ALWAYS;
406 Recurse=RECURSE_WILDCARDS;
410 Priority=atoi(Switch+2);
411 char *ChPtr=strchr(Switch+2,':');
414 SleepTime=atoi(ChPtr+1);
415 InitSystemOptions(SleepTime);
417 SetPriority(Priority);
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);
433 Args->AddString(Switch+1);
437 switch(toupper(Switch[1]))
443 ExclPath=EXCL_SKIPWHOLEPATH;
446 ExclPath=EXCL_BASEPATH;
449 ExclPath=EXCL_SAVEFULLPATH;
452 ExclPath=EXCL_ABSPATH;
468 InclFileAttr=GetExclAttr(&Switch[2]);
472 ExclFileAttr=GetExclAttr(&Switch[1]);
479 GetPassword(PASSWORD_GLOBAL,NULL,Password,sizeof(Password));
483 strncpy(Password,Switch+1,sizeof(Password));
486 if (toupper(Switch[1])=='P')
490 strncpy(Password,Switch+2,sizeof(Password));
494 GetPassword(PASSWORD_GLOBAL,NULL,Password,sizeof(Password));
500 strncpy(CommentFile,Switch[1]!=0 ? Switch+1:"stdin",sizeof(CommentFile));
503 switch(toupper(Switch[1]))
509 for (unsigned int I=0;I<sizeof(FilterModes)/sizeof(FilterModes[0]);I++)
510 FilterModes[I].State=FILTER_DISABLE;
514 int Param1=0,Param2=0;
515 FilterState State=FILTER_AUTO;
516 FilterType Type=FILTER_NONE;
520 while (isdigit(*Str))
523 if (*Str==':' && isdigit(Str[1]))
526 while (isdigit(*Str))
529 switch(toupper(*(Str++)))
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;
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;
551 if ((WinSize=atoi(&Switch[2]))==0)
552 WinSize=0x10000<<(toupper(Switch[2])-'A');
561 char *Names=Switch+2,DefNames[512];
564 strcpy(DefNames,DefaultStoreList);
569 char *End=strchr(Names,';');
575 if (strpbrk(Names,"*?.")==NULL)
576 sprintf(Mask,"*.%s",Names);
579 StoreArgs->AddString(Mask);
587 Method=Switch[1]-'0';
588 if (Method>5 || Method<0)
594 switch(toupper(Switch[1]))
608 if (toupper(Switch[2])=='R')
609 VersionControl=atoi(Switch+3)+1;
616 Int64 NewVolSize=atoil(&Switch[1]);
621 switch (Switch[strlen(Switch)-1])
625 switch(int64to32(NewVolSize))
648 NewVolSize*=1024*1024;
651 NewVolSize*=1000*1000;
654 NewVolSize*=1024*1024;
658 NewVolSize*=1000*1000;
671 NextVolSizes.Push(NewVolSize);
685 strncpy(TempPath,&Switch[1],sizeof(TempPath)-1);
686 AddEndSlash(TempPath);
689 if (strnicomp(Switch,"SFX",3)==0)
691 const char *SFXName=Switch[3] ? Switch+3:DefSFXName;
692 if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
693 strcpy(SFXModule,SFXName);
695 GetConfigName(SFXName,SFXModule,true);
697 if (isdigit(Switch[1]))
700 SolidCount=atoi(&Switch[1]);
703 switch(toupper(Switch[1]))
712 Solid|=SOLID_FILEEXT;
715 Solid|=Switch[2]=='-' ? SOLID_VOLUME_DEPENDENT:SOLID_VOLUME_INDEPENDENT;
718 Solid|=SOLID_VOLUME_DEPENDENT;
724 switch(toupper(Switch[1]))
730 ConvertNames=NAMES_UPPERCASE;
733 ConvertNames=NAMES_LOWERCASE;
738 switch(toupper(Switch[1]))
761 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
762 void CommandData::BadSwitch(char *Switch)
764 mprintf(St(MUnknownOption),Switch);
765 ErrHandler.Exit(USER_ERROR);
771 void CommandData::OutTitle()
773 if (BareOutput || DisableCopyright)
775 #if defined(__GNUC__) && defined(SFX_MODULE)
776 mprintf(St(MCopyrightS));
779 static bool TitleShown=false;
784 int Beta=RARVER_BETA;
786 sprintf(Version,"%d.%02d %s %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA);
788 sprintf(Version,"%d.%02d",RARVER_MAJOR,RARVER_MINOR);
790 mprintf(St(MUCopyright),Version,RARVER_YEAR);
799 void CommandData::OutHelp()
801 #if !defined(GUI) && !defined(SILENT)
803 static MSGID Help[]={
805 MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV
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
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
838 for (int I=0;I<sizeof(Help)/sizeof(Help[0]);I++)
841 #ifdef DISABLEAUTODETECT
842 if (Help[I]==MCHelpSwV)
846 static MSGID Win32Only[]={
847 MCHelpSwIEML,MCHelpSwVD,MCHelpSwAC,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF,
848 MCHelpSwEP2,MCHelpSwOC
851 for (int J=0;J<sizeof(Win32Only)/sizeof(Win32Only[0]);J++)
852 if (Help[I]==Win32Only[J])
859 #if !defined(_UNIX) && !defined(_WIN_32)
860 if (Help[I]==MCHelpSwOW)
864 if (Help[I]==MCHelpSwOL)
868 if (Help[I]==MCHelpSwRI)
872 if (Help[I]==MCHelpSwEE)
874 #if defined(_EMX) && !defined(_DJGPP)
875 if (_osmode != OS2_MODE)
883 mprintf(St(Help[I]));
891 bool CommandData::ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode)
893 char *Name=ConvertPath(CheckName,NULL);
894 char FullName[NM],*CurName;
897 while ((CurName=Args->GetString())!=NULL)
899 if (CheckFullPath && IsFullPath(CurName))
902 ConvertNameToFull(CheckName,FullName);
903 if (CmpName(CurName,FullName,MatchMode))
908 if (CmpName(ConvertPath(CurName,NULL),Name,MatchMode))
914 bool CommandData::ExclCheck(char *CheckName,bool CheckFullPath)
916 if (ExclCheckArgs(ExclArgs,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
918 if (InclArgs->ItemsCount()==0)
920 if (ExclCheckArgs(InclArgs,CheckName,CheckFullPath,MATCH_NAMES))
929 bool CommandData::TimeCheck(RarTime &ft)
931 if (FileTimeBefore.IsSet() && ft>=FileTimeBefore)
933 if (FileTimeAfter.IsSet() && ft<=FileTimeAfter)
936 if (FileTimeOlder!=0 || FileTimeNewer!=0)
940 if (FileTimeOlder!=0)
941 FileTimeOlder=SecondsToDosTime(FileTimeOlder);
942 if (FileTimeNewer!=0)
943 FileTimeNewer=SecondsToDosTime(FileTimeNewer);
946 if (FileTimeOlder!=0 && ft>=FileTimeOlder)
948 if (FileTimeNewer!=0 && ft<=FileTimeNewer)
958 int CommandData::IsProcessFile(FileHeader &NewLhd,bool *ExactMatch,int MatchType)
960 if (strlen(NewLhd.FileName)>=NM || strlenw(NewLhd.FileNameW)>=NM)
962 if (ExclCheck(NewLhd.FileName,false))
965 if (TimeCheck(NewLhd.mtime))
971 for (int StringCount=1;FileArgs->GetString(&ArgName,&ArgNameW);StringCount++)
974 bool Unicode=(NewLhd.Flags & LHD_UNICODE) || ArgNameW!=NULL;
977 wchar NameW[NM],ArgW[NM],*NamePtr=NewLhd.FileNameW;
978 bool CorrectUnicode=true;
981 if (!CharToWide(ArgName,ArgW) || *ArgW==0)
982 CorrectUnicode=false;
985 if ((NewLhd.Flags & LHD_UNICODE)==0)
987 if (!CharToWide(NewLhd.FileName,NameW) || *NameW==0)
988 CorrectUnicode=false;
991 if (CmpName(ArgNameW,NamePtr,MatchType))
993 if (ExactMatch!=NULL)
994 *ExactMatch=stricompcw(ArgNameW,NamePtr)==0;
1001 if (CmpName(ArgName,NewLhd.FileName,MatchType))
1003 if (ExactMatch!=NULL)
1004 *ExactMatch=stricompc(ArgName,NewLhd.FileName)==0;
1005 return(StringCount);
1013 void CommandData::ProcessCommand()
1016 if ((Command[1] && (strchr("FUADPXETK",*Command)!=NULL)) || *ArcName==0)
1020 if (GetExt(ArcName)==NULL && (!FileExist(ArcName) || IsDir(GetFileAttr(ArcName))))
1021 strcat(ArcName,".rar");
1023 if (GetExt(ArcName)==NULL)
1024 strcat(ArcName,".rar");
1027 if (strchr("AFUMD",*Command)==NULL)
1029 StringList ArcMasks;
1030 ArcMasks.AddString(ArcName);
1031 ScanTree Scan(&ArcMasks,Recurse,SaveLinks,SCAN_SKIPDIRS);
1033 while (Scan.GetNext(&FindData)==SCAN_SUCCESS)
1034 AddArcName(FindData.Name,FindData.NameW);
1037 AddArcName(ArcName,NULL);
1049 Extract.DoExtract(this);
1052 #if !defined(GUI) && !defined(SILENT)
1071 void CommandData::AddArcName(char *Name,wchar *NameW)
1073 ArcNames->AddString(Name,NameW);
1077 bool CommandData::GetArcName(char *Name,wchar *NameW,int MaxSize)
1079 if (!ArcNames->GetString(Name,NameW,NM))
1085 bool CommandData::IsSwitch(int Ch)
1087 #if defined(_WIN_32) || defined(_EMX)
1088 return(Ch=='-' || Ch=='/');
1096 uint CommandData::GetExclAttr(char *Str)
1099 return(strtol(Str,NULL,0));
1103 for (Attr=0;*Str;Str++)
1104 switch(toupper(*Str))
1113 #elif defined(_WIN_32) || defined(_EMX)
1137 bool CommandData::CheckWinSize()
1139 static unsigned int ValidSize[]={
1140 0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000
1142 for (unsigned int I=0;I<sizeof(ValidSize)/sizeof(ValidSize[0]);I++)
1143 if (WinSize==ValidSize[I])