int ArcCommand::ReplaceVar(std::string &Command) { int MaxNamesLength = 0x10000; std::string LocalAllFilesMask = AllFilesMask; bool UseSlash = false; bool FolderMask = false; bool FolderName = false; bool NameOnly = false; bool PathOnly = false; int QuoteName = 0; if (Command.size() < 3) return 0; char Chr = Command[2] & (~0x20); if (Command[0] != '%' || Command[1] != '%' || Chr < 'A' || Chr > 'Z') return 0; int VarLength = 3; while (VarLength < Command.size()) { bool BreakScan = false; Chr = Command[VarLength]; if (Command[2]=='F' && Chr >= '0' && Chr <= '9') { MaxNamesLength = FSF.atoi(Command.c_str() + VarLength); while (Chr >= '0' && Chr <= '9' && VarLength < Command.size()) Chr = Command[++VarLength]; continue; } if (Command[2]=='E' && Chr >= '0' && Chr <= '9') { MaxAllowedExitCode = FSF.atoi(Command.c_str() + VarLength); while (Chr >= '0' && Chr <= '9' && VarLength < Command.size()) Chr=Command[++VarLength]; continue; } switch (Command[VarLength]) { case 'A': break; /* deprecated AnsiCode = true; */ case 'Q': QuoteName = 1; break; case 'q': QuoteName = 2; break; case 'S': UseSlash = true; break; case 'M': FolderMask = true; break; case 'N': FolderName = true; break; case 'W': NameOnly = true; break; case 'P': PathOnly = true; break; case '*': LocalAllFilesMask = "*"; break; default: BreakScan = true; } if (BreakScan) break; VarLength++; } if ( (MaxNamesLength-=(int)Command.size()) <= 0) MaxNamesLength = 1; if (!FolderMask && !FolderName) FolderName = true; ///////////////////////////////// switch (Command[2]) { case 'A': case 'a': /* deprecated: short name - works same as normal name */ Command = ArcName; if (PathOnly) CutToPathOrSpace(Command); QuoteCmdArgIfNeed(Command); break; case 'D': case 'E': Command.clear(); break; case 'L': case 'l': if (!MakeListFile(ListFileName, QuoteName, UseSlash, FolderName, NameOnly, PathOnly, FolderMask, LocalAllFilesMask.c_str())) { return -1; } Command = ListFileName; QuoteCmdArgIfNeed(Command); break; case 'P': Command = Password; break; case 'C': if (*CommentFileName) //второй раз сюда не лезем break; { Command.clear(); int CommentFile; if (FSF.MkTemp(CommentFileName, "FAR") && (CommentFile = sdc_open(CommentFileName, O_CREAT | O_TRUNC | O_RDWR, 0660)) != -1) { char Buf[512]; if(Info.InputBox(GetMsg(MComment), GetMsg(MInputComment), NULL, "", Buf, sizeof(Buf), NULL, 0)) //??тут можно и заполнить строку комментарием, но надо знать, файловый //?? он или архивный. да и имя файла в архиве тоже надо знать... { sdc_write(CommentFile, Buf, strlen(Buf)); sdc_close(CommentFile); Command = CommentFileName; } WINPORT(FlushConsoleInputBuffer)(NULL);//GetStdHandle(STD_INPUT_HANDLE)); } } break; case 'r': Command = RealArcDir; if (!Command.empty()) Command+= '/'; break; case 'R': Command = RealArcDir; if (UseSlash) { } QuoteCmdArgIfNeed(Command); break; case 'W': Command = TempPath; break; case 'F': case 'f': if (PanelItem!=NULL) { std::string CurArcDir = ArcDir; if (!CurArcDir.empty() && CurArcDir[CurArcDir.size() - 1] != GOOD_SLASH) CurArcDir+= GOOD_SLASH; std::string Names, Name; if (NameNumber == -1) NameNumber = 0; while (NameNumber < ItemsNumber || Command[2] == 'f') { int IncreaseNumber = 0; DWORD FileAttr; if (!NextFileName.empty()) { Name = PrefixFileName; Name+= CurArcDir; Name+= NextFileName; NextFileName.clear(); FileAttr = 0; } else { int N; if (Command[2]=='f' && PrevFileNameNumber!=-1) N = PrevFileNameNumber; else { N = NameNumber; IncreaseNumber=1; } if (N >= ItemsNumber) break; *PrefixFileName=0; char *cFileName = PanelItem[N].FindData.cFileName; if(PanelItem[N].UserData && (PanelItem[N].Flags & PPIF_USERDATA)) { struct ArcItemUserData *aud=(struct ArcItemUserData*)PanelItem[N].UserData; if(aud->SizeStruct == sizeof(struct ArcItemUserData)) { if(aud->Prefix) strncpy(PrefixFileName,aud->Prefix,sizeof(PrefixFileName)); if(aud->LinkName) cFileName=aud->LinkName; } } // CHECK for BUGS!! Name = PrefixFileName; if(*cFileName != GOOD_SLASH) { Name+= CurArcDir; Name+= cFileName; } else Name+= cFileName+1; NormalizePath(Name); FileAttr = PanelItem[N].FindData.dwFileAttributes; PrevFileNameNumber = N; } if (NameOnly) { size_t slash = Name.rfind(GOOD_SLASH); if (slash != std::string::npos) Name.erase(0, slash + 1); } if (PathOnly) CutToPathOrSpace(Name); if (Names.empty() || (Names.size() + Name.size() < MaxNamesLength && Command[2] != 'f')) { NameNumber+= IncreaseNumber; if (FileAttr & FILE_ATTRIBUTE_DIRECTORY) { std::string FolderMaskName = Name; if (!PathOnly) { FolderMaskName+= GOOD_SLASH; FolderMaskName+= LocalAllFilesMask; } else CutToPathOrSpace(FolderMaskName); if (FolderMask) { if (FolderName) NextFileName.swap(FolderMaskName); else Name.swap(FolderMaskName); } } if (QuoteName==1) QuoteCmdArgIfNeed(Name); else if (QuoteName==2) QuoteCmdArg(Name); if (!Names.empty()) Names+= ' '; Names+= Name; } else break; } Command.swap(Names); } else Command.clear(); break; default: return 0; } return VarLength; }
int ArcCommand::ReplaceVar(char *Command,int &Length) { char Chr=Command[2]&(~0x20); if (Command[0]!='%' || Command[1]!='%' || Chr < 'A' || Chr > 'Z') return FALSE; char SaveStr[MAX_COMMAND_LENGTH],LocalAllFilesMask[NM]; int QuoteName=0,UseSlash=FALSE,FolderMask=FALSE,FolderName=FALSE; int NameOnly=FALSE,PathOnly=FALSE,AnsiCode=FALSE; int MaxNamesLength=127; int VarLength=3; lstrcpy(LocalAllFilesMask,AllFilesMask); while (1) { int BreakScan=FALSE; Chr=Command[VarLength]; if (Command[2]=='F' && Chr >= '0' && Chr <= '9') { MaxNamesLength=FSF.atoi(&Command[VarLength]); while (Chr >= '0' && Chr <= '9') Chr=Command[++VarLength]; continue; } if (Command[2]=='E' && Chr >= '0' && Chr <= '9') { MaxAllowedExitCode=FSF.atoi(&Command[VarLength]); while (Chr >= '0' && Chr <= '9') Chr=Command[++VarLength]; continue; } switch(Command[VarLength]) { case 'A': AnsiCode=TRUE; break; case 'Q': QuoteName=1; break; case 'q': QuoteName=2; break; case 'S': UseSlash=TRUE; break; case 'M': FolderMask=TRUE; break; case 'N': FolderName=TRUE; break; case 'W': NameOnly=TRUE; break; case 'P': PathOnly=TRUE; break; case '*': lstrcpy(LocalAllFilesMask,"*"); break; default: BreakScan=TRUE; break; } if (BreakScan) break; VarLength++; } if ((MaxNamesLength-=Length)<=0) MaxNamesLength=1; if (MaxNamesLength>MAX_COMMAND_LENGTH-512) MaxNamesLength=MAX_COMMAND_LENGTH-512; if (FolderMask==FALSE && FolderName==FALSE) FolderName=TRUE; lstrcpy(SaveStr,Command+VarLength); switch(Command[2]) { case 'A': lstrcpy(Command,ArcName); if (AnsiCode) OemToChar(Command,Command); if (PathOnly) { char *NamePtr=(char *)FSF.PointToName(Command); if (NamePtr!=Command) *(NamePtr-1)=0; else lstrcpy(Command," "); } FSF.QuoteSpaceOnly(Command); break; case 'a': { int Dot=strchr(FSF.PointToName(ArcName),'.')!=NULL; ConvertNameToShort(ArcName,Command); char *Slash=strrchr(ArcName,'\\'); if (GetFileAttributes(ArcName)==0xFFFFFFFF && Slash!=NULL && Slash!=ArcName) { char Path[NM]; lstrcpy(Path,ArcName); Path[Slash-ArcName]=0; ConvertNameToShort(Path,Command); lstrcat(Command,Slash); } if (Dot && strchr(FSF.PointToName(Command),'.')==NULL) lstrcat(Command,"."); if (AnsiCode) OemToChar(Command,Command); if (PathOnly) { char *NamePtr=(char *)FSF.PointToName(Command); if (NamePtr!=Command) *(NamePtr-1)=0; else lstrcpy(Command," "); } } FSF.QuoteSpaceOnly(Command); break; case 'D': *Command=0; break; case 'E': *Command=0; break; case 'l': case 'L': if (!MakeListFile(ListFileName,Command[2]=='l',QuoteName,UseSlash, FolderName,NameOnly,PathOnly,FolderMask, LocalAllFilesMask,AnsiCode)) return -1; char QListName[NM+2]; FSF.QuoteSpaceOnly(lstrcpy(QListName,ListFileName)); lstrcpy(Command,QListName); break; case 'P': lstrcpy(Command,Password); break; case 'C': if(*CommentFileName) //второй раз сюда не лезем break; { *Command=0; HANDLE CommentFile; //char CommentFileName[MAX_PATH]; char Buf[512]; SECURITY_ATTRIBUTES sa; sa.nLength=sizeof(sa); sa.lpSecurityDescriptor=NULL; sa.bInheritHandle=TRUE; if(FSF.MkTemp(CommentFileName, "FAR") && (CommentFile=CreateFile(CommentFileName, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, /*FILE_ATTRIBUTE_TEMPORARY|*//*FILE_FLAG_DELETE_ON_CLOSE*/0, NULL)) != INVALID_HANDLE_VALUE) { DWORD Count; if(Info.InputBox(GetMsg(MComment), GetMsg(MInputComment), NULL, "", Buf, sizeof(Buf), NULL, 0)) //??тут можно и заполнить строку комментарием, но надо знать, файловый //?? он или архивный. да и имя файла в архиве тоже надо знать... { WriteFile(CommentFile, Buf, lstrlen(Buf), &Count, NULL); lstrcpy(Command, CommentFileName); CloseHandle(CommentFile); } FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); } } break; case 'R': lstrcpy(Command,RealArcDir); if (UseSlash) { for (int I=0;Command[I];I++) if (Command[I]=='\\') // Command[I]='//'; /* $ 28.11.2000 AS */ Command[I]='/'; /* AS $*/ } FSF.QuoteSpaceOnly(Command); break; case 'W': lstrcpy(Command,TempPath); break; case 'f': case 'F': if (PanelItem!=NULL) { char CurArcDir[NM]; lstrcpy(CurArcDir,ArcDir); int Length=lstrlen(CurArcDir); if (Length>0 && CurArcDir[Length-1]!='\\') lstrcat(CurArcDir,"\\"); char Names[MAX_COMMAND_LENGTH]; *Names=0; if (NameNumber==-1) NameNumber=0; while (NameNumber<ItemsNumber || Command[2]=='f') { char Name[NM*2]; int IncreaseNumber=0,FileAttr; if (*NextFileName) { FSF.sprintf(Name,"%s%s%s",PrefixFileName,CurArcDir,NextFileName); *NextFileName=0; FileAttr=0; } else { int N; if (Command[2]=='f' && PrevFileNameNumber!=-1) N=PrevFileNameNumber; else { N=NameNumber; IncreaseNumber=1; } if (N>=ItemsNumber) break; *PrefixFileName=0; char *cFileName=PanelItem[N].FindData.cFileName; if(PanelItem[N].UserData && (PanelItem[N].Flags & PPIF_USERDATA)) { struct ArcItemUserData *aud=(struct ArcItemUserData*)PanelItem[N].UserData; if(aud->SizeStruct == sizeof(struct ArcItemUserData)) { if(aud->Prefix) lstrcpyn(PrefixFileName,aud->Prefix,sizeof(PrefixFileName)); if(aud->LinkName) cFileName=aud->LinkName; } } // CHECK for BUGS!! if(*cFileName == '\\' || *cFileName == '/') FSF.sprintf(Name,"%s%s",PrefixFileName,cFileName+1); else FSF.sprintf(Name,"%s%s%s",PrefixFileName,CurArcDir,cFileName); NormalizePath(Name,Name); FileAttr=PanelItem[N].FindData.dwFileAttributes; PrevFileNameNumber=N; } if (AnsiCode) OemToChar(Name,Name); if (NameOnly) { char NewName[NM]; lstrcpy(NewName,FSF.PointToName(Name)); lstrcpy(Name,NewName); } if (PathOnly) { char *NamePtr=(char *)FSF.PointToName(Name); if (NamePtr!=Name) *(NamePtr-1)=0; else lstrcpy(Name," "); } if (*Names==0 || (lstrlen(Names)+lstrlen(Name)<MaxNamesLength && Command[2]!='f')) { NameNumber+=IncreaseNumber; if (FileAttr & FILE_ATTRIBUTE_DIRECTORY) { char FolderMaskName[NM]; //lstrcpy(LocalAllFilesMask,PrefixFileName); FSF.sprintf(FolderMaskName,"%s\\%s",Name,LocalAllFilesMask); if (PathOnly) { lstrcpy(FolderMaskName,Name); char *NamePtr=(char *)FSF.PointToName(FolderMaskName); if (NamePtr!=FolderMaskName) *(NamePtr-1)=0; else lstrcpy(FolderMaskName," "); } if (FolderMask) { if (FolderName) lstrcpy(NextFileName,FolderMaskName); else lstrcpy(Name,FolderMaskName); } } if (QuoteName==1) FSF.QuoteSpaceOnly(Name); else if (QuoteName==2) QuoteText(Name); if (UseSlash) for (int I=0;Name[I];I++) if (Name[I]=='\\') // Name[I]='//'; /* $ 28.11.2000 AS */ Name[I]='/'; /* AS $*/ if (*Names) lstrcat(Names," "); lstrcat(Names,Name); } else break; } lstrcpy(Command,Names); } else *Command=0; break; default: return FALSE; } Length=lstrlen(Command); lstrcat(Command,SaveStr); return TRUE; }