2
* This file is part of nzbget
4
* Copyright (C) 2007-2010 Andrei Prygounkov <hugbug@users.sourceforge.net>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
* $Date: 2010-02-08 17:08:10 +0100 (Mon, 08 Feb 2010) $
48
#include "ScriptController.h"
52
extern Options* g_pOptions;
53
extern char* (*szEnvironmentVariables)[];
54
extern DownloadQueueHolder* g_pDownloadQueueHolder;
56
static const int POSTPROCESS_PARCHECK_CURRENT = 91;
57
static const int POSTPROCESS_PARCHECK_ALL = 92;
58
static const int POSTPROCESS_SUCCESS = 93;
59
static const int POSTPROCESS_ERROR = 94;
60
static const int POSTPROCESS_NONE = 95;
63
#define CHILD_WATCHDOG 1
68
* Sometimes the forked child process doesn't start properly and hangs
69
* just during the starting. I didn't find any explanation about what
70
* could cause that problem except of a general advice, that
71
* "a forking in a multithread application is not recommended".
74
* 1) child process prints a line into stdout directly after the start;
75
* 2) parent process waits for a line for 60 seconds. If it didn't receive it
76
* the cild process assumed to hang and will be killed. Another attempt
80
class ChildWatchDog : public Thread
87
void SetProcessID(pid_t hProcessID) { m_hProcessID = hProcessID; }
90
void ChildWatchDog::Run()
92
static const int WAIT_SECONDS = 60;
93
time_t tStart = time(NULL);
94
while (!IsStopped() && (time(NULL) - tStart) < WAIT_SECONDS)
101
info("Restarting hanging child process");
102
kill(m_hProcessID, SIGKILL);
108
EnvironmentStrings::EnvironmentStrings()
112
EnvironmentStrings::~EnvironmentStrings()
114
for (Strings::iterator it = m_strings.begin(); it != m_strings.end(); it++)
121
void EnvironmentStrings::InitFromCurrentProcess()
123
for (int i = 0; (*szEnvironmentVariables)[i]; i++)
125
char* szVar = (*szEnvironmentVariables)[i];
126
Append(strdup(szVar));
130
void EnvironmentStrings::Append(char* szString)
132
m_strings.push_back(szString);
137
* Returns environment block in format suitable for using with CreateProcess.
138
* The allocated memory must be freed by caller using "free()".
140
char* EnvironmentStrings::GetStrings()
143
for (Strings::iterator it = m_strings.begin(); it != m_strings.end(); it++)
146
iSize += strlen(szVar) + 1;
149
char* szStrings = (char*)malloc(iSize);
150
char* szPtr = szStrings;
151
for (Strings::iterator it = m_strings.begin(); it != m_strings.end(); it++)
154
strcpy(szPtr, szVar);
155
szPtr += strlen(szVar) + 1;
165
* Returns environment block in format suitable for using with execve
166
* The allocated memory must be freed by caller using "free()".
168
char** EnvironmentStrings::GetStrings()
170
char** pStrings = (char**)malloc((m_strings.size() + 1) * sizeof(char*));
171
char** pPtr = pStrings;
172
for (Strings::iterator it = m_strings.begin(); it != m_strings.end(); it++)
185
ScriptController::ScriptController()
188
m_szWorkingDir = NULL;
192
m_szDefaultKindPrefix = NULL;
193
m_bTerminated = false;
194
m_environmentStrings.InitFromCurrentProcess();
197
ScriptController::~ScriptController()
201
for (const char** szArgPtr = m_szArgs; *szArgPtr; szArgPtr++)
203
free((char*)*szArgPtr);
209
void ScriptController::SetEnvVar(const char* szName, const char* szValue)
211
int iLen = strlen(szName) + strlen(szValue) + 2;
212
char* szVar = (char*)malloc(iLen);
213
snprintf(szVar, iLen, "%s=%s", szName, szValue);
214
m_environmentStrings.Append(szVar);
217
void ScriptController::PrepareEnvironmentStrings()
219
Options::OptEntries* pOptEntries = g_pOptions->LockOptEntries();
221
for (Options::OptEntries::iterator it = pOptEntries->begin(); it != pOptEntries->end(); it++)
223
Options::OptEntry* pOptEntry = *it;
224
char szVarname[1024];
225
snprintf(szVarname, sizeof(szVarname), "NZBOP_%s", pOptEntry->GetName());
227
// convert to upper case; replace "." with "_".
228
for (char* szPtr = szVarname; *szPtr; szPtr++)
234
*szPtr = toupper(*szPtr);
237
szVarname[1024-1] = '\0';
238
SetEnvVar(szVarname, pOptEntry->GetValue());
241
g_pOptions->UnlockOptEntries();
244
int ScriptController::Execute()
246
if (!Util::FileExists(m_szScript))
248
error("Could not start %s: could not find file %s", m_szInfoName, m_szScript);
252
PrepareEnvironmentStrings();
257
#ifdef CHILD_WATCHDOG
258
bool bChildConfirmed = false;
259
while (!bChildConfirmed && !m_bTerminated)
264
// build command line
265
char szCmdLine[2048];
267
for (const char** szArgPtr = m_szArgs; *szArgPtr; szArgPtr++)
269
snprintf(szCmdLine + iUsedLen, 2048 - iUsedLen, "\"%s\" ", *szArgPtr);
270
iUsedLen += strlen(*szArgPtr) + 3;
272
szCmdLine[iUsedLen < 2048 ? iUsedLen - 1 : 2048 - 1] = '\0';
274
// create pipes to write and read data
275
HANDLE hReadPipe, hWritePipe;
276
SECURITY_ATTRIBUTES SecurityAttributes;
277
memset(&SecurityAttributes, 0, sizeof(SecurityAttributes));
278
SecurityAttributes.nLength = sizeof(SecurityAttributes);
279
SecurityAttributes.bInheritHandle = TRUE;
281
CreatePipe(&hReadPipe, &hWritePipe, &SecurityAttributes, 0);
283
STARTUPINFO StartupInfo;
284
memset(&StartupInfo, 0, sizeof(StartupInfo));
285
StartupInfo.cb = sizeof(StartupInfo);
286
StartupInfo.dwFlags = STARTF_USESTDHANDLES;
287
StartupInfo.hStdInput = 0;
288
StartupInfo.hStdOutput = hWritePipe;
289
StartupInfo.hStdError = hWritePipe;
291
PROCESS_INFORMATION ProcessInfo;
292
memset(&ProcessInfo, 0, sizeof(ProcessInfo));
294
char* szEnvironmentStrings = m_environmentStrings.GetStrings();
296
BOOL bOK = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, szEnvironmentStrings, m_szWorkingDir, &StartupInfo, &ProcessInfo);
299
DWORD dwErrCode = GetLastError();
301
szErrMsg[255-1] = '\0';
302
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM || FORMAT_MESSAGE_IGNORE_INSERTS || FORMAT_MESSAGE_ARGUMENT_ARRAY,
303
NULL, dwErrCode, 0, szErrMsg, 255, NULL))
305
error("Could not start %s: %s", m_szInfoName, szErrMsg);
309
error("Could not start %s: error %i", m_szInfoName, dwErrCode);
311
free(szEnvironmentStrings);
315
free(szEnvironmentStrings);
317
debug("Child Process-ID: %i", (int)ProcessInfo.dwProcessId);
319
m_hProcess = ProcessInfo.hProcess;
321
// close unused "write" end
322
CloseHandle(hWritePipe);
324
pipein = _open_osfhandle((intptr_t)hReadPipe, _O_RDONLY);
334
error("Could not open pipe: errno %i", errno);
338
char** pEnvironmentStrings = m_environmentStrings.GetStrings();
348
error("Could not start %s: errno %i", m_szInfoName, errno);
349
free(pEnvironmentStrings);
354
// here goes the second instance
356
// create new process group (see Terminate() where it is used)
359
// close up the "read" end
362
// make the pipeout to be the same as stdout and stderr
368
#ifdef CHILD_WATCHDOG
369
fwrite("\n", 1, 1, stdout);
373
execve(m_szScript, (char* const*)m_szArgs, (char* const*)pEnvironmentStrings);
374
fprintf(stdout, "[ERROR] Could not start script: %s", strerror(errno));
379
// continue the first instance
381
debug("Child Process-ID: %i", (int)pid);
383
free(pEnvironmentStrings);
387
// close unused "write" end
392
FILE* readpipe = fdopen(pipein, "r");
395
error("Could not open pipe to %s", m_szInfoName);
399
#ifdef CHILD_WATCHDOG
400
debug("Creating child watchdog");
401
ChildWatchDog* pWatchDog = new ChildWatchDog();
402
pWatchDog->SetAutoDestroy(false);
403
pWatchDog->SetProcessID(pid);
407
char* buf = (char*)malloc(10240);
409
debug("Entering pipe-loop");
410
while (!feof(readpipe) && !m_bTerminated)
412
if (fgets(buf, 10240, readpipe))
414
#ifdef CHILD_WATCHDOG
415
if (!bChildConfirmed)
417
bChildConfirmed = true;
419
debug("Child confirmed");
425
debug("Exited pipe-loop");
427
#ifdef CHILD_WATCHDOG
428
debug("Destroying WatchDog");
429
if (!bChildConfirmed)
433
while (pWatchDog->IsRunning())
445
warn("Interrupted %s", m_szInfoName);
451
WaitForSingleObject(m_hProcess, INFINITE);
453
GetExitCodeProcess(m_hProcess, &dExitCode);
454
iExitCode = dExitCode;
457
waitpid(m_hProcess, &iStatus, 0);
458
if (WIFEXITED(iStatus))
460
iExitCode = WEXITSTATUS(iStatus);
464
#ifdef CHILD_WATCHDOG
465
} // while (!bChildConfirmed && !m_bTerminated)
470
info("Completed %s", m_szInfoName);
471
debug("Exit code %i", iExitCode);
477
void ScriptController::Terminate()
479
debug("Stopping %s", m_szInfoName);
480
m_bTerminated = true;
483
BOOL bOK = TerminateProcess(m_hProcess, -1);
485
pid_t hKillProcess = m_hProcess;
486
if (getpgid(hKillProcess) == hKillProcess)
488
// if the child process has its own group (setsid() was successful), kill the whole group
489
hKillProcess = -hKillProcess;
491
bool bOK = kill(hKillProcess, SIGKILL) == 0;
496
debug("Terminated %s", m_szInfoName);
500
error("Could not terminate %s", m_szInfoName);
503
debug("Stopped %s", m_szInfoName);
506
void ScriptController::ProcessOutput(char* szText)
508
debug("Processing output received from script");
510
for (char* pend = szText + strlen(szText) - 1; pend >= szText && (*pend == '\n' || *pend == '\r' || *pend == ' '); pend--) *pend = '\0';
512
if (strlen(szText) == 0)
518
if (!strncmp(szText, "[INFO] ", 7))
520
AddMessage(Message::mkInfo, false, g_pOptions->GetInfoTarget(), szText + 7);
522
else if (!strncmp(szText, "[WARNING] ", 10))
524
AddMessage(Message::mkWarning, false, g_pOptions->GetWarningTarget(), szText + 10);
526
else if (!strncmp(szText, "[ERROR] ", 8))
528
AddMessage(Message::mkError, false, g_pOptions->GetErrorTarget(), szText + 8);
530
else if (!strncmp(szText, "[DETAIL] ", 9))
532
AddMessage(Message::mkDetail, false, g_pOptions->GetDetailTarget(), szText + 9);
534
else if (!strncmp(szText, "[DEBUG] ", 8))
536
AddMessage(Message::mkDebug, false, g_pOptions->GetDebugTarget(), szText + 8);
540
switch (m_eDefaultLogKind)
542
case Options::slNone:
545
case Options::slDetail:
546
AddMessage(Message::mkDetail, true, g_pOptions->GetDetailTarget(), szText);
549
case Options::slInfo:
550
AddMessage(Message::mkInfo, true, g_pOptions->GetInfoTarget(), szText);
553
case Options::slWarning:
554
AddMessage(Message::mkWarning, true, g_pOptions->GetWarningTarget(), szText);
557
case Options::slError:
558
AddMessage(Message::mkError, true, g_pOptions->GetErrorTarget(), szText);
561
case Options::slDebug:
562
AddMessage(Message::mkDebug, true, g_pOptions->GetDebugTarget(), szText);
567
debug("Processing output received from script - completed");
570
void ScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Options::EMessageTarget eMessageTarget, const char* szText)
574
case Message::mkDetail:
575
detail("%s%s", (bDefaultKind && m_szDefaultKindPrefix ? m_szDefaultKindPrefix : ""), szText);
578
case Message::mkInfo:
579
info("%s%s", (bDefaultKind && m_szDefaultKindPrefix ? m_szDefaultKindPrefix : ""), szText);
582
case Message::mkWarning:
583
warn("%s%s", (bDefaultKind && m_szDefaultKindPrefix ? m_szDefaultKindPrefix : ""), szText);
586
case Message::mkError:
587
error("%s%s", (bDefaultKind && m_szDefaultKindPrefix ? m_szDefaultKindPrefix : ""), szText);
590
case Message::mkDebug:
591
debug("%s%s", (bDefaultKind && m_szDefaultKindPrefix ? m_szDefaultKindPrefix : ""), szText);
596
void PostScriptController::StartScriptJob(PostInfo* pPostInfo, const char* szScript, bool bNZBFileCompleted, bool bHasFailedParJobs)
598
info("Executing post-process-script for %s", pPostInfo->GetInfoName());
600
PostScriptController* pScriptController = new PostScriptController();
601
pScriptController->m_pPostInfo = pPostInfo;
602
pScriptController->SetScript(szScript);
603
pScriptController->SetWorkingDir(g_pOptions->GetDestDir());
604
pScriptController->m_bNZBFileCompleted = bNZBFileCompleted;
605
pScriptController->m_bHasFailedParJobs = bHasFailedParJobs;
606
pScriptController->SetAutoDestroy(false);
608
pPostInfo->SetScriptThread(pScriptController);
610
pScriptController->Start();
613
void PostScriptController::Run()
615
// the locking is needed for accessing the memebers of NZBInfo
616
g_pDownloadQueueHolder->LockQueue();
618
char szParStatus[10];
619
snprintf(szParStatus, 10, "%i", m_pPostInfo->GetParStatus());
620
szParStatus[10-1] = '\0';
622
char szCollectionCompleted[10];
623
snprintf(szCollectionCompleted, 10, "%i", (int)m_bNZBFileCompleted);
624
szCollectionCompleted[10-1] = '\0';
626
char szHasFailedParJobs[10];
627
snprintf(szHasFailedParJobs, 10, "%i", (int)m_bHasFailedParJobs);
628
szHasFailedParJobs[10-1] = '\0';
630
char szDestDir[1024];
631
strncpy(szDestDir, m_pPostInfo->GetNZBInfo()->GetDestDir(), 1024);
632
szDestDir[1024-1] = '\0';
634
char szNZBFilename[1024];
635
strncpy(szNZBFilename, m_pPostInfo->GetNZBInfo()->GetFilename(), 1024);
636
szNZBFilename[1024-1] = '\0';
638
char szParFilename[1024];
639
strncpy(szParFilename, m_pPostInfo->GetParFilename(), 1024);
640
szParFilename[1024-1] = '\0';
642
char szCategory[1024];
643
strncpy(szCategory, m_pPostInfo->GetNZBInfo()->GetCategory(), 1024);
644
szCategory[1024-1] = '\0';
646
char szInfoName[1024];
647
snprintf(szInfoName, 1024, "post-process-script for %s", m_pPostInfo->GetInfoName());
648
szInfoName[1024-1] = '\0';
649
SetInfoName(szInfoName);
651
SetDefaultKindPrefix("Post-Process: ");
652
SetDefaultLogKind(g_pOptions->GetProcessLogKind());
654
const char* szArgs[9];
655
szArgs[0] = GetScript();
656
szArgs[1] = szDestDir;
657
szArgs[2] = szNZBFilename;
658
szArgs[3] = szParFilename;
659
szArgs[4] = szParStatus;
660
szArgs[5] = szCollectionCompleted;
661
szArgs[6] = szHasFailedParJobs;
662
szArgs[7] = szCategory;
664
SetArgs(szArgs, false);
666
SetEnvVar("NZBPP_DIRECTORY", szDestDir);
667
SetEnvVar("NZBPP_NZBFILENAME", szNZBFilename);
668
SetEnvVar("NZBPP_PARFILENAME", szParFilename);
669
SetEnvVar("NZBPP_PARSTATUS", szParStatus);
670
SetEnvVar("NZBPP_NZBCOMPLETED", szCollectionCompleted);
671
SetEnvVar("NZBPP_PARFAILED", szHasFailedParJobs);
672
SetEnvVar("NZBPP_CATEGORY", szCategory);
674
for (NZBParameterList::iterator it = m_pPostInfo->GetNZBInfo()->GetParameters()->begin(); it != m_pPostInfo->GetNZBInfo()->GetParameters()->end(); it++)
676
NZBParameter* pParameter = *it;
677
char szVarname[1024];
678
snprintf(szVarname, sizeof(szVarname), "NZBPR_%s", pParameter->GetName());
679
szVarname[1024-1] = '\0';
680
SetEnvVar(szVarname, pParameter->GetValue());
683
g_pDownloadQueueHolder->UnlockQueue();
685
int iResult = Execute();
689
case POSTPROCESS_SUCCESS:
690
info("%s sucessful", szInfoName);
691
m_pPostInfo->SetScriptStatus(PostInfo::srSuccess);
694
case POSTPROCESS_ERROR:
695
info("%s failed", szInfoName);
696
m_pPostInfo->SetScriptStatus(PostInfo::srFailure);
699
case POSTPROCESS_NONE:
700
info("%s skipped", szInfoName);
701
m_pPostInfo->SetScriptStatus(PostInfo::srNone);
704
#ifndef DISABLE_PARCHECK
705
case POSTPROCESS_PARCHECK_ALL:
706
if (m_pPostInfo->GetParCheck())
708
error("%s requested par-check/repair for all collections, but they were already checked", szInfoName);
709
m_pPostInfo->SetScriptStatus(PostInfo::srFailure);
711
else if (!m_bNZBFileCompleted)
713
error("%s requested par-check/repair for all collections, but it was not the call for the last collection", szInfoName);
714
m_pPostInfo->SetScriptStatus(PostInfo::srFailure);
718
info("%s requested par-check/repair for all collections", szInfoName);
719
m_pPostInfo->SetRequestParCheck(PostInfo::rpAll);
720
m_pPostInfo->SetScriptStatus(PostInfo::srSuccess);
724
case POSTPROCESS_PARCHECK_CURRENT:
725
if (m_pPostInfo->GetParCheck())
727
error("%s requested par-check/repair for current collection, but it was already checked", szInfoName);
728
m_pPostInfo->SetScriptStatus(PostInfo::srFailure);
730
else if (strlen(m_pPostInfo->GetParFilename()) == 0)
732
error("%s requested par-check/repair for current collection, but it doesn't have any par-files", szInfoName);
733
m_pPostInfo->SetScriptStatus(PostInfo::srFailure);
737
info("%s requested par-check/repair for current collection", szInfoName);
738
m_pPostInfo->SetRequestParCheck(PostInfo::rpCurrent);
739
m_pPostInfo->SetScriptStatus(PostInfo::srSuccess);
745
info("%s terminated with unknown status", szInfoName);
746
m_pPostInfo->SetScriptStatus(PostInfo::srUnknown);
749
m_pPostInfo->SetStage(PostInfo::ptFinished);
750
m_pPostInfo->SetWorking(false);
753
void PostScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Options::EMessageTarget eMessageTarget, const char* szText)
755
if (!strncmp(szText, "[HISTORY] ", 10))
757
if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth)
759
m_pPostInfo->GetNZBInfo()->AppendMessage(eKind, 0, szText + 10);
764
ScriptController::AddMessage(eKind, bDefaultKind, eMessageTarget, szText);
766
if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth)
768
m_pPostInfo->AppendMessage(eKind, szText);
773
if (g_pOptions->GetPausePostProcess())
775
time_t tStageTime = m_pPostInfo->GetStageTime();
776
time_t tStartTime = m_pPostInfo->GetStartTime();
777
time_t tWaitTime = time(NULL);
779
// wait until Post-processor is unpaused
780
while (g_pOptions->GetPausePostProcess() && !IsStopped())
784
// update time stamps
786
time_t tDelta = time(NULL) - tWaitTime;
790
m_pPostInfo->SetStageTime(tStageTime + tDelta);
795
m_pPostInfo->SetStartTime(tStartTime + tDelta);
801
void PostScriptController::Stop()
803
debug("Stopping post-process-script");
808
void NZBScriptController::ExecuteScript(const char* szScript, const char* szNZBFilename,
809
const char* szDirectory, char** pCategory, NZBParameterList* pParameterList)
811
info("Executing nzb-process-script for %s", Util::BaseFileName(szNZBFilename));
813
NZBScriptController* pScriptController = new NZBScriptController();
814
pScriptController->SetScript(szScript);
815
pScriptController->m_pCategory = pCategory;
816
pScriptController->m_pParameterList = pParameterList;
818
char szInfoName[1024];
819
snprintf(szInfoName, 1024, "nzb-process-script for %s", Util::BaseFileName(szNZBFilename));
820
szInfoName[1024-1] = '\0';
821
pScriptController->SetInfoName(szInfoName);
823
// remove trailing slash
825
strncpy(szDir, szDirectory, 1024);
826
szDir[1024-1] = '\0';
827
int iLen = strlen(szDir);
828
if (szDir[iLen-1] == PATH_SEPARATOR)
830
szDir[iLen-1] = '\0';
833
pScriptController->SetDefaultKindPrefix("NZB-Process: ");
834
pScriptController->SetDefaultLogKind(g_pOptions->GetProcessLogKind());
836
const char* szArgs[4];
837
szArgs[0] = szScript;
839
szArgs[2] = szNZBFilename;
841
pScriptController->SetArgs(szArgs, false);
843
pScriptController->SetEnvVar("NZBNP_DIRECTORY", szDir);
844
pScriptController->SetEnvVar("NZBNP_FILENAME", szNZBFilename);
846
pScriptController->Execute();
848
delete pScriptController;
851
void NZBScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Options::EMessageTarget eMessageTarget, const char* szText)
853
if (!strncmp(szText, "[NZB] ", 6))
855
debug("Command %s detected", szText + 6);
856
if (!strncmp(szText + 6, "CATEGORY=", 9))
859
*m_pCategory = strdup(szText + 6 + 9);
861
else if (!strncmp(szText + 6, "NZBPR_", 6))
863
char* szParam = strdup(szText + 6 + 6);
864
char* szValue = strchr(szParam, '=');
868
m_pParameterList->SetParameter(szParam, szValue + 1);
872
error("Invalid command \"%s\" received from %s", szText, GetInfoName());
878
error("Invalid command \"%s\" received from %s", szText, GetInfoName());
883
ScriptController::AddMessage(eKind, bDefaultKind, eMessageTarget, szText);
887
void SchedulerScriptController::StartScript(const char* szCommandLine)
890
if (!Util::SplitCommandLine(szCommandLine, &argv))
892
error("Could not execute scheduled process-script, failed to parse command line: %s", szCommandLine);
896
info("Executing scheduled process-script %s", Util::BaseFileName(argv[0]));
898
SchedulerScriptController* pScriptController = new SchedulerScriptController();
899
pScriptController->SetScript(argv[0]);
900
pScriptController->SetArgs((const char**)argv, true);
901
pScriptController->SetAutoDestroy(true);
903
pScriptController->Start();
906
void SchedulerScriptController::Run()
908
char szInfoName[1024];
909
snprintf(szInfoName, 1024, "scheduled process-script %s", Util::BaseFileName(GetScript()));
910
szInfoName[1024-1] = '\0';
911
SetInfoName(szInfoName);
913
SetDefaultKindPrefix("Scheduled Process: ");
914
SetDefaultLogKind(g_pOptions->GetProcessLogKind());