1 #include "MultiArc.hpp"
12 extern std::string gMultiArcPluginPath
;
14 BOOL
FileExists(const char *Name
)
17 return sdc_stat(Name
, &s
) != -1;
20 static void mystrlwr(char *p
)
26 static void mystrupr(char *p
)
32 BOOL
GoToFile(const char *Target
, BOOL AllowChangeDir
)
34 if (!Target
|| !*Target
)
36 BOOL rc
= FALSE
, search
= TRUE
;
39 char Name
[NM
], Dir
[NM
* 5];
42 ArrayCpyZ(Name
, FSF
.PointToName(const_cast<char *>(Target
)));
43 pathlen
= (int)(FSF
.PointToName(const_cast<char *>(Target
)) - Target
);
45 memcpy(Dir
, Target
, pathlen
);
53 Info
.Control(INVALID_HANDLE_VALUE
, FCTL_UPDATEPANEL
, (void *)1);
54 Info
.Control(INVALID_HANDLE_VALUE
, FCTL_GETPANELINFO
, &PInfo
);
55 pathlen
= strlen(Dir
);
57 if (*PInfo
.CurDir
&& PInfo
.CurDir
[strlen(PInfo
.CurDir
) - 1] != '/' // old path != "*\"
58 && Dir
[pathlen
- 1] == '/')
61 if (0 != strcmp(Dir
, PInfo
.CurDir
)) {
63 Info
.Control(INVALID_HANDLE_VALUE
, FCTL_SETPANELDIR
, &Dir
);
64 Info
.Control(INVALID_HANDLE_VALUE
, FCTL_GETPANELINFO
, &PInfo
);
70 PRI
.CurrentItem
= PInfo
.CurrentItem
;
71 PRI
.TopPanelItem
= PInfo
.TopPanelItem
;
73 for (int J
= 0; J
< PInfo
.ItemsNumber
; J
++) {
74 if (!strcmp(Name
, FSF
.PointToName(PInfo
.PanelItems
[J
].FindData
.cFileName
))) {
82 return rc
? Info
.Control(INVALID_HANDLE_VALUE
, FCTL_REDRAWPANEL
, &PRI
) : FALSE
;
85 int __isspace(int Chr
)
87 return Chr
== 0x09 || Chr
== 0x0A || Chr
== 0x0B || Chr
== 0x0C || Chr
== 0x0D || Chr
== 0x20;
90 const char *GetMsg(int MsgId
)
92 return Info
.GetMsg(Info
.ModuleNumber
, MsgId
);
96 int rar_main(int argc
, char *argv
[]);
98 extern "C" int sevenz_main(int argc
, char *argv
[]);
99 extern "C" int ha_main(int argc
, char *argv
[]);
101 #ifdef HAVE_LIBARCHIVE
102 extern "C" int libarch_main(int numargs
, char *args
[]);
105 SHAREDSYMBOL
int BuiltinMain(int argc
, char *argv
[])
112 if (strcmp(argv
[0], "7z") == 0) {
113 r
= sevenz_main(argc
, &argv
[0]);
115 } else if (strcmp(argv
[0], "rar") == 0) {
116 r
= rar_main(argc
, &argv
[0]);
118 } else if (strcmp(argv
[0], "7z") == 0) {
119 r
= sevenz_main(argc
, &argv
[0]);
120 } else if (strcmp(argv
[0], "ha") == 0) {
121 r
= ha_main(argc
, &argv
[0]);
122 #ifdef HAVE_LIBARCHIVE
123 } else if (strcmp(argv
[0], "libarch") == 0) {
124 r
= libarch_main(argc
, &argv
[0]);
127 fprintf(stderr
, "BuiltinMain: bad target '%s'\n", argv
[0]);
132 запуск треда для ожидания момента убийства лист файла */
134 static DWORD WINAPI
ThreadWhatWaitingForKillListFile(LPVOID par
)
136 KillStruct
*ks
=(KillStruct
*)par
;
138 WINPORT(WaitForSingleObject
)(ks
->hProcess
,INFINITE
);
139 WINPORT(CloseHandle
)(ks
->hThread
);
140 WINPORT(CloseHandle
)(ks
->hProcess
);
141 sdc_unlink(ks
->ListFileName
);
143 return SUPER_PUPER_ZERO
;
145 void StartThreadForKillListFile(PROCESS_INFORMATION
*pi
,char *list
)
147 if ( pi
==0 || list
==0 || *list
==0)
152 ks
=(KillStruct
*)malloc(GPTR
,sizeof(KillStruct
));
156 ks
->hThread
=pi
->hThread
;
157 ks
->hProcess
=pi
->hProcess
;
158 strcpy(ks
->ListFileName
,list
);
160 WINPORT(CloseHandle
)(WINPORT(CreateThread
)(NULL
,0xf000,ThreadWhatWaitingForKillListFile
,ks
,0 ,&dummy
));
163 /* tran 13.09.2000 $ */
166 int Execute(HANDLE hPlugin
, const std::string
&CmdStr
, int HideOutput
, int Silent
, int NeedSudo
,
167 int ShowCommand
, char *ListFileName
)
169 if (!CmdStr
.empty() && (CmdStr
[0] == ' ' || CmdStr
[0] == '\t')) { // FSF.LTrim(ExpandedCmd); //$ AA 12.11.2001
170 std::string CmdStrTrimmed
= CmdStr
;
172 CmdStrTrimmed
.erase(0, 1);
173 } while (!CmdStrTrimmed
.empty() && (CmdStrTrimmed
[0] == ' ' || CmdStrTrimmed
[0] == '\t'));
175 return Execute(hPlugin
, CmdStrTrimmed
, HideOutput
, Silent
, NeedSudo
, ShowCommand
, ListFileName
);
178 int ExitCode
, LastError
;
180 HANDLE StdInput
= NULL
;
181 HANDLE StdOutput
= NULL
;
182 HANDLE hScreen
= NULL
;
183 CONSOLE_SCREEN_BUFFER_INFO csbi
;
187 hScreen
= Info
.SaveScreen(0, 0, -1, -1);
188 const char *MsgItems
[] = {"", GetMsg(MWaitForExternalProgram
)};
189 Info
.Message(Info
.ModuleNumber
, 0, NULL
, MsgItems
, ARRAYSIZE(MsgItems
), 0);
192 WINPORT(GetConsoleScreenBufferInfo
)(StdOutput
, &csbi
);
195 FSF
.sprintf(Blank
, "%*s", csbi
.dwSize
.X
, "");
196 for (int Y
= 0; Y
< csbi
.dwSize
.Y
; Y
++)
197 Info
.Text(0, Y
, LIGHTGRAY
, Blank
);
198 Info
.Text(0, 0, 0, NULL
);
202 C
.Y
= csbi
.dwCursorPosition
.Y
;
203 WINPORT(SetConsoleCursorPosition
)(StdOutput
, C
);
207 WINPORT(GetConsoleMode
)(StdInput
, &ConsoleMode
);
208 WINPORT(SetConsoleMode
)
209 (StdInput
, ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
| ENABLE_MOUSE_INPUT
);
211 WCHAR SaveTitle
[512]{};
212 WINPORT(GetConsoleTitle
)(NULL
, SaveTitle
, ARRAYSIZE(SaveTitle
) - 1);
214 WINPORT(SetConsoleTitle
)(NULL
, StrMB2Wide(CmdStr
).c_str());
216 /* $ 14.02.2001 raVen
217 делать окошку minimize, если в фоне */
218 /* if (Opt.Background)
220 si.dwFlags=si.dwFlags | STARTF_USESHOWWINDOW;
221 si.wShowWindow=SW_MINIMIZE;
224 DWORD flags
= (HideOutput
) ? EF_HIDEOUT
: 0;
228 flags
|= EF_NOCMDPRINT
;
230 if (*CmdStr
.c_str() == '^') {
231 LastError
= ExitCode
=
232 FSF
.ExecuteLibrary(gMultiArcPluginPath
.c_str(), "BuiltinMain", CmdStr
.c_str() + 1, flags
);
234 LastError
= ExitCode
= FSF
.Execute(CmdStr
.c_str(), flags
);
237 WINPORT(SetLastError
)(LastError
);
238 WINPORT(SetConsoleTitle
)(NULL
, SaveTitle
);
239 WINPORT(SetConsoleMode
)(StdInput
, ConsoleMode
);
241 Info
.RestoreScreen(NULL
);
242 Info
.RestoreScreen(hScreen
);
248 char *QuoteText(char *Str
)
250 int LastPos
= strlen(Str
);
251 memmove(Str
+ 1, Str
, LastPos
+ 1);
252 Str
[LastPos
+ 1] = *Str
= '"';
253 Str
[LastPos
+ 2] = 0;
257 void InitDialogItems(const struct InitDialogItem
*Init
, struct FarDialogItem
*Item
, int ItemsNumber
)
260 struct FarDialogItem
*PItem
= Item
;
261 const struct InitDialogItem
*PInit
= Init
;
262 for (I
= 0; I
< ItemsNumber
; I
++, PItem
++, PInit
++) {
263 PItem
->Type
= PInit
->Type
;
264 PItem
->X1
= PInit
->X1
;
265 PItem
->Y1
= PInit
->Y1
;
266 PItem
->X2
= PInit
->X2
;
267 PItem
->Y2
= PInit
->Y2
;
268 PItem
->Focus
= PInit
->Focus
;
269 PItem
->History
= (const char *)PInit
->Selected
;
270 PItem
->Flags
= PInit
->Flags
;
271 PItem
->DefaultButton
= PInit
->DefaultButton
;
273 ((DWORD_PTR
)PInit
->Data
< 2000) ? GetMsg((unsigned int)(DWORD_PTR
)PInit
->Data
) : PInit
->Data
);
277 std::string
NumberWithCommas(unsigned long long Number
)
279 std::string out
= std::to_string(Number
);
280 for (int I
= int(out
.size()) - 4; I
>= 0; I
-= 3)
281 out
.insert(I
+ 1, 1, ',');
286 int MA_ToPercent(int32_t N1
, int32_t N2
)
296 return (int)(N1
* 100 / N2
);
299 int MA_ToPercent(int64_t N1
, int64_t N2
)
309 return (int)(N1
* 100 / N2
);
312 int IsCaseMixed(const char *Str
)
314 while (*Str
&& !isalpha(*Str
))
316 int Case
= islower(*Str
);
318 if (isalpha(*Str
) && islower(*Str
) != Case
)
325 WORD KeyCode
= VK_ESCAPE
;
326 return WINPORT(CheckForKeyPress
)(NULL
, &KeyCode
, 1, CFKP_KEEP_OTHER_EVENTS
) != 0;
329 char *GetCommaWord(char *Src
, char *Word
, char Separator
)
331 int WordPos
, SkipBrackets
;
334 SkipBrackets
= FALSE
;
335 for (WordPos
= 0; *Src
!= 0; Src
++, WordPos
++) {
336 if (*Src
== '[' && strchr(Src
+ 1, ']') != NULL
)
339 SkipBrackets
= FALSE
;
340 if (*Src
== Separator
&& !SkipBrackets
) {
343 while (__isspace(*Src
))
347 Word
[WordPos
] = *Src
;
353 int FindExecuteFile(char *OriginalName
, char *DestName
, int SizeDest
)
355 std::string cmd
= "which ";
357 FILE *f
= popen(cmd
.c_str(), "r");
359 perror("FindExecuteFile - popen");
362 if (!fgets(DestName
, SizeDest
- 1, f
))
365 DestName
[SizeDest
- 1] = 0;
368 char *e
= strchr(DestName
, '\n');
371 e
= strchr(DestName
, '\r');
374 return DestName
[0] ? TRUE
: FALSE
;
377 char *SeekDefExtPoint(char *Name
, char *DefExt
/*=NULL*/, char **Ext
/*=NULL*/)
379 FSF
.Unquote(Name
); //$ AA 15.04.2003 для правильной обработки имен в кавычках
380 Name
= FSF
.PointToName(Name
);
381 char *TempExt
= strrchr(Name
, '.');
386 return (TempExt
!= NULL
) ? (strcasecmp(TempExt
+ 1, DefExt
) ? NULL
: TempExt
) : NULL
;
389 BOOL
AddExt(char *Name
, char *Ext
)
392 FSF
.Unquote(Name
); //$ AA 15.04.2003 для правильной обработки имен в кавычках
393 if (Name
&& *Name
&& !SeekDefExtPoint(Name
, Ext
, &ExtPnt
)) {
395 char NewExt
[NM
], *Ptr
;
396 strncpy(NewExt
, Ext
, sizeof(NewExt
) - 1);
415 if (ExtPnt
&& !*(ExtPnt
+ 1))
416 strcpy(ExtPnt
+ 1, NewExt
);
418 FSF
.sprintf(Name
+ strlen(Name
), ".%s", NewExt
);
424 #ifdef _NEW_ARC_SORT_
425 void WritePrivateProfileInt(char *Section
, char *Key
, int Value
, char *Ini
)
428 wsprintf(Buf32
, "%d", Value
);
429 WritePrivateProfileString(Section
, Key
, Buf32
, Ini
);
433 int WINAPI
GetPassword(char *Password
, const char *FileName
)
435 char Prompt
[2 * NM
], InPass
[512];
436 FSF
.sprintf(Prompt
, GetMsg(MGetPasswordForFile
), FileName
);
437 if (Info
.InputBox((const char *)GetMsg(MGetPasswordTitle
), (const char *)Prompt
, NULL
, NULL
, InPass
,
438 sizeof(InPass
), NULL
, FIB_PASSWORD
| FIB_ENABLEEMPTY
)) {
439 strcpy(Password
, InPass
);
445 // Number of 100 nanosecond units from 01.01.1601 to 01.01.1970
446 #define EPOCH_BIAS I64(116444736000000000)
448 void WINAPI
UnixTimeToFileTime(DWORD time
, FILETIME
*ft
)
450 *(int64_t *)ft
= EPOCH_BIAS
+ time
* I64(10000000);
455 CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo
;
456 if (WINPORT(GetConsoleScreenBufferInfo
)(NULL
, &ConsoleScreenBufferInfo
)) // GetStdHandle(STD_OUTPUT_HANDLE)
457 return ConsoleScreenBufferInfo
.dwSize
.X
;
461 int PathMayBeAbsolute(const char *Path
)
463 return (Path
&& *Path
== '/');
468 "cdrecord-1.6.1/mkisofs-1.12b4/../cdrecord/cd_misc.c"
470 "cdrecord-1.6.1/cdrecord/cd_misc.c"
472 void NormalizePath(const char *lpcSrcName
, char *lpDestName
)
474 char *DestName
= lpDestName
;
476 char *SrcName
= strdup(lpcSrcName
);
477 char *oSrcName
= SrcName
;
481 Ptr
= strchr(SrcName
, '/');
484 Ptr
= SrcName
+ strlen(SrcName
);
486 dist
= (int)(Ptr
- SrcName
) + 1;
488 if (dist
== 1 && (*SrcName
== '/')) {
489 *DestName
= *SrcName
;
492 } else if (dist
== 2 && *SrcName
== '.') {
499 } else if (dist
== 3 && *SrcName
== '.' && SrcName
[1] == '.') {
500 if (!PathMayBeAbsolute(lpDestName
)) {
501 char *ptrCurDestName
= lpDestName
, *Temp
= NULL
;
503 for (; ptrCurDestName
< DestName
- 1; ptrCurDestName
++) {
504 if (*ptrCurDestName
== '/')
505 Temp
= ptrCurDestName
;
513 if (SrcName
[2] == '/')
519 strncpy(DestName
, SrcName
, dist
);
531 std::string
&NormalizePath(std::string
&path
)
533 std::vector
<char> dest(std::max((size_t)MAX_PATH
, path
.size()) + 1);
534 NormalizePath(path
.c_str(), &dest
[0]);
539 std::string
&ExpandEnv(std::string
&str
)
541 Environment::ExpandString(str
, false);
545 bool CanBeExecutableFileHeader(const unsigned char *Data
, int DataSize
)
550 if (Data
[0] == 0x7f && Data
[1] == 'E' && Data
[2] == 'L' && Data
[3] == 'F')
553 if (Data
[0] == 'M' && Data
[1] == 'Z')
556 if (Data
[0] == 'Z' && Data
[1] == 'M')
559 if (Data
[0] == 0xca && Data
[1] == 0xfe && Data
[2] == 0xba && Data
[3] == 0xbe)
562 if (Data
[0] == 0xfe && Data
[1] == 0xed && Data
[2] == 0xfa && (Data
[3] == 0xce || Data
[3] == 0xcf))
565 if (Data
[3] == 0xfe && Data
[2] == 0xed && Data
[1] == 0xfa && (Data
[0] == 0xce || Data
[0] == 0xcf))