543 lines
16 KiB
C
543 lines
16 KiB
C
|
/*-
|
||
|
* Copyright (c) 2020-2021 Carsten Sonne Larsen <cs@innolan.net>
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "config.h"
|
||
|
#include "global.h"
|
||
|
#include "string.h"
|
||
|
#include "message.h"
|
||
|
#include "setting.h"
|
||
|
#include "text.h"
|
||
|
#include "sync.h"
|
||
|
#include "conv.h"
|
||
|
#include "mem.h"
|
||
|
#include "win.h"
|
||
|
#include "val.h"
|
||
|
#include "tz.h"
|
||
|
|
||
|
#include <proto/rexxsyslib.h>
|
||
|
#include <rexx/storage.h>
|
||
|
#include <rexx/rxslib.h>
|
||
|
|
||
|
#include "logmod.h"
|
||
|
#define MODULENAME "ARexx"
|
||
|
|
||
|
static char *arexxHelpText = NULL;
|
||
|
|
||
|
typedef void (*ArexxCommand)(struct RexxMsg *, char **);
|
||
|
|
||
|
struct ArexxCommandDef
|
||
|
{
|
||
|
const int Identifier;
|
||
|
const char *Name;
|
||
|
const char *Description;
|
||
|
ArexxCommand Command;
|
||
|
int Parameters;
|
||
|
};
|
||
|
|
||
|
struct ArexxParameterDef
|
||
|
{
|
||
|
const int Identifier;
|
||
|
const char *Keyword;
|
||
|
};
|
||
|
|
||
|
static void ArexxIdentifierCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxVersionCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxHelpCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxStatusCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxTimezoneCommand(struct RexxMsg *msg, char **);
|
||
|
static void ArexxLastSyncCommand(struct RexxMsg *msg, char **);
|
||
|
static void ArexxLastAdjustCommand(struct RexxMsg *msg, char **);
|
||
|
static void ArexxGetValueCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxSetValueCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxShowCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxHideCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxStartCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxStopCommand(struct RexxMsg *, char **);
|
||
|
static void ArexxShutdownCommand(struct RexxMsg *, char **);
|
||
|
|
||
|
#define AREXX_COMMAND_OK 0
|
||
|
#define AREXX_COMMAND_ERROR 1
|
||
|
#define AREXX_COMMAND_UNKNOWN 10
|
||
|
#define AREXX_COMMAND_PARM_UNKNOWN 11
|
||
|
#define AREXX_COMMAND_PARM_INVALID 12
|
||
|
#define AREXX_COMMAND_SHUTDOWN 99
|
||
|
|
||
|
static struct ArexxCommandDef arexxCommands[] = {
|
||
|
{1, "ID", "Get application identifier", ArexxIdentifierCommand, 0},
|
||
|
{2, "VERSION", "Get application version number", ArexxVersionCommand},
|
||
|
{3, "HELP", "Get a list of ARexx commands and a short description", ArexxHelpCommand, 0},
|
||
|
{4, "STATUS", "Get current synchronization status", ArexxStatusCommand, 0},
|
||
|
{5, "TIMEZONE", "Get current time zone", ArexxTimezoneCommand, 0},
|
||
|
{6, "LASTSYNC", "Get time of last synchronization operation", ArexxLastSyncCommand, 0},
|
||
|
{7, "LASTADJ", "Get time of last clock adjustment", ArexxLastAdjustCommand, 0},
|
||
|
{8, "GET", "Get a runtime configuration value", ArexxGetValueCommand, 1},
|
||
|
{9, "SET", "Set a runtime configuration value", ArexxSetValueCommand, 2},
|
||
|
{10, "SHOW", "Show settings window", ArexxShowCommand, 0},
|
||
|
{11, "HIDE", "Hide settings window", ArexxHideCommand, 0},
|
||
|
{12, "START", "Start the time synchronization process", ArexxStartCommand, 0},
|
||
|
{13, "STOP", "Stop the time synchronization process", ArexxStopCommand, 0},
|
||
|
{14, "SHUTDOWN", "Shutdown " APP_SHORT_NAME, ArexxShutdownCommand, 0}};
|
||
|
|
||
|
#define AREXX_COMMAND_COUNT 14
|
||
|
|
||
|
#define AREXX_PARAMETER_UNKNOWN 0
|
||
|
#define AREXX_PARAMETER_SERVER 1
|
||
|
#define AREXX_PARAMETER_PORT 2
|
||
|
#define AREXX_PARAMETER_THRESHOLD 3
|
||
|
#define AREXX_PARAMETER_INTERVAL 4
|
||
|
#define AREXX_PARAMETER_PRIORITY 5
|
||
|
#define AREXX_PARAMETER_POPKEY 6
|
||
|
#define AREXX_PARAMETER_POPUP 7
|
||
|
#define AREXX_PARAMETER_READONLY 8
|
||
|
#define AREXX_PARAMETER_EXPERT 9
|
||
|
#define AREXX_PARAMETER_TIMEOUT 10
|
||
|
|
||
|
static struct ArexxParameterDef arexxParameters[] = {
|
||
|
{AREXX_PARAMETER_SERVER, KEYWORD_SERVER},
|
||
|
{AREXX_PARAMETER_PORT, KEYWORD_PORT},
|
||
|
{AREXX_PARAMETER_THRESHOLD, KEYWORD_THRESHOLD},
|
||
|
{AREXX_PARAMETER_INTERVAL, KEYWORD_INTERVAL},
|
||
|
{AREXX_PARAMETER_PRIORITY, KEYWORD_PRIORITY},
|
||
|
{AREXX_PARAMETER_POPKEY, KEYWORD_POPKEY},
|
||
|
{AREXX_PARAMETER_POPUP, KEYWORD_POPUP},
|
||
|
{AREXX_PARAMETER_READONLY, KEYWORD_READONLY},
|
||
|
{AREXX_PARAMETER_EXPERT, KEYWORD_EXPERT},
|
||
|
{AREXX_PARAMETER_TIMEOUT, KEYWORD_TIMEOUT}};
|
||
|
|
||
|
#define AREXX_PARAMETER_COUNT 10
|
||
|
|
||
|
#define AREXX_MAX_ARGS_COUNT 8
|
||
|
|
||
|
static void SplitAndTerminate(char *string, char **res)
|
||
|
{
|
||
|
char *p = string;
|
||
|
char **q = res;
|
||
|
int count = 1;
|
||
|
|
||
|
while (*p != '\0')
|
||
|
{
|
||
|
if (*p == ' ')
|
||
|
{
|
||
|
// Terminate
|
||
|
*p = '\0';
|
||
|
p++;
|
||
|
|
||
|
// Skip trailing spaces
|
||
|
while (*p == ' ')
|
||
|
p++;
|
||
|
|
||
|
*q = p;
|
||
|
q++;
|
||
|
count++;
|
||
|
|
||
|
// Bail out
|
||
|
if (count >= AREXX_MAX_ARGS_COUNT)
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void BuildArexxHelpText(void)
|
||
|
{
|
||
|
char *p;
|
||
|
int i, line, len = 0;
|
||
|
|
||
|
if (arexxHelpText != NULL)
|
||
|
return;
|
||
|
|
||
|
len += 26; // Header
|
||
|
len += 71 * 2; // Spacer
|
||
|
|
||
|
for (i = 0; i < AREXX_COMMAND_COUNT; i++)
|
||
|
{
|
||
|
len += StrLen(arexxCommands[i].Description) + 14;
|
||
|
}
|
||
|
|
||
|
arexxHelpText = (char *)AllocStringSafe(len);
|
||
|
if (arexxHelpText == NULL)
|
||
|
return;
|
||
|
|
||
|
p = AppendText(arexxHelpText, " Command | Description\n");
|
||
|
p = AppendChar(p, '-', 70);
|
||
|
p = AppendChar(p, '\n', 1);
|
||
|
|
||
|
for (i = 0; i < AREXX_COMMAND_COUNT; i++)
|
||
|
{
|
||
|
line = 10 - StrLen(arexxCommands[i].Name);
|
||
|
p = AppendChar(p, ' ', 1);
|
||
|
p = AppendText(p, arexxCommands[i].Name);
|
||
|
p = AppendChar(p, ' ', line);
|
||
|
p = AppendChar(p, '|', 1);
|
||
|
p = AppendChar(p, ' ', 1);
|
||
|
p = AppendText(p, arexxCommands[i].Description);
|
||
|
p = AppendChar(p, '\n', 1);
|
||
|
}
|
||
|
|
||
|
p = AppendChar(p, '-', 70);
|
||
|
}
|
||
|
|
||
|
void CleanupArexx(void)
|
||
|
{
|
||
|
if (arexxHelpText != NULL)
|
||
|
{
|
||
|
FreeMemSafe(arexxHelpText);
|
||
|
arexxHelpText = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ArexxIdentifierCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)APP_TITLE, (LONG)StrLen(APP_TITLE));
|
||
|
}
|
||
|
|
||
|
static void ArexxVersionCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)APP_VERSION, (LONG)StrLen(APP_VERSION));
|
||
|
}
|
||
|
|
||
|
static void ArexxHelpCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
BuildArexxHelpText();
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)arexxHelpText, (LONG)StrLen(arexxHelpText));
|
||
|
}
|
||
|
|
||
|
static void ArexxStatusCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
if (SynchronizerRunning)
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)TextSyncOn, (LONG)StrLen(TextSyncOn));
|
||
|
else
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)TextSyncOff, (LONG)StrLen(TextSyncOff));
|
||
|
}
|
||
|
|
||
|
static void ArexxTimezoneCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
char Timezone[TIMEZONE_TEXT_LEN];
|
||
|
GetTimezoneText(AppLocale, Timezone, UTC_NO_PARENS);
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)Timezone, (LONG)StrLen(Timezone));
|
||
|
}
|
||
|
|
||
|
static void ArexxLastSyncCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
struct timeval tv = LastSync;
|
||
|
if (tv.tv_sec == 0 && tv.tv_micro == 0)
|
||
|
{
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)TextNoResponses, (LONG)StrLen(TextNoResponses));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char result[64];
|
||
|
Utc2Str(&tv, result);
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)result, (LONG)StrLen(result));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ArexxLastAdjustCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
struct timeval tv = LastAdjust;
|
||
|
if (tv.tv_sec == 0 && tv.tv_micro == 0)
|
||
|
{
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)TextNoClockAdjust, (LONG)StrLen(TextNoClockAdjust));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char result[64];
|
||
|
Utc2Str(&tv, result);
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)result, (LONG)StrLen(result));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int ArexxFindParameter(char **parms)
|
||
|
{
|
||
|
int i;
|
||
|
char *parm = parms[0];
|
||
|
|
||
|
if (parm == NULL || *parm == '\0')
|
||
|
{
|
||
|
return AREXX_PARAMETER_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < AREXX_PARAMETER_COUNT; i++)
|
||
|
{
|
||
|
if (Stricmp((STRPTR)parm, (STRPTR)arexxParameters[i].Keyword) == 0)
|
||
|
{
|
||
|
return arexxParameters[i].Identifier;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return AREXX_PARAMETER_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
static void ArexxGetValueCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
char buf[MAXLONGLONGCHARSIZE];
|
||
|
char *res;
|
||
|
int param = ArexxFindParameter(parms);
|
||
|
|
||
|
switch (param)
|
||
|
{
|
||
|
case AREXX_PARAMETER_UNKNOWN:
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_UNKNOWN;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_SERVER:
|
||
|
res = Settings->DestinationAddress;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_PORT:
|
||
|
res = Settings->DestinationPort;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_THRESHOLD:
|
||
|
LongLongToStr(Settings->Threshold, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_INTERVAL:
|
||
|
LongToStr(Settings->Interval, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_PRIORITY:
|
||
|
LongToStr(Settings->Priority, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_POPKEY:
|
||
|
res = Settings->PopKey;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_POPUP:
|
||
|
BoolToStr(Settings->Popup, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_READONLY:
|
||
|
BoolToStr(Settings->Readonly, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_EXPERT:
|
||
|
BoolToStr(Settings->Expert, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_TIMEOUT:
|
||
|
LongToStr(Settings->Timeout, buf);
|
||
|
res = buf;
|
||
|
break;
|
||
|
default:
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_UNKNOWN;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (msg->rm_Result1 != AREXX_COMMAND_PARM_UNKNOWN)
|
||
|
{
|
||
|
msg->rm_Result2 = (LONG)CreateArgstring((STRPTR)res, (LONG)StrLen(res));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ArexxSetValueCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
int param = ArexxFindParameter(parms++);
|
||
|
char *valueString = *parms;
|
||
|
long long longlongValue;
|
||
|
long longValue;
|
||
|
bool boolValue;
|
||
|
|
||
|
switch (param)
|
||
|
{
|
||
|
case AREXX_PARAMETER_UNKNOWN:
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_UNKNOWN;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_SERVER:
|
||
|
SetServer(valueString, APPLY_VALUE);
|
||
|
break;
|
||
|
case AREXX_PARAMETER_PORT:
|
||
|
SetPort(valueString, APPLY_VALUE);
|
||
|
break;
|
||
|
case AREXX_PARAMETER_THRESHOLD:
|
||
|
if (TryParseLongLong(valueString, &longlongValue))
|
||
|
SetThreshold(valueString, APPLY_VALUE);
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_INTERVAL:
|
||
|
if (TryParseLong(valueString, &longValue))
|
||
|
SetInterval(longValue, APPLY_VALUE);
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_PRIORITY:
|
||
|
if (TryParseLong(valueString, &longValue))
|
||
|
SetPriority(valueString, APPLY_VALUE);
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_POPKEY:
|
||
|
// TODO: Remove CX filter object and add new filter (Settings->PopKey)
|
||
|
// http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node0587.html
|
||
|
break;
|
||
|
case AREXX_PARAMETER_POPUP:
|
||
|
if (TryParseBoolean(valueString, &boolValue))
|
||
|
Settings->Popup = boolValue;
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_READONLY:
|
||
|
if (TryParseBoolean(valueString, &boolValue))
|
||
|
Settings->Readonly = boolValue;
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_EXPERT:
|
||
|
if (TryParseBoolean(valueString, &boolValue))
|
||
|
{
|
||
|
Settings->Expert = boolValue;
|
||
|
SendWindowMessage(ATK_SHUTDOWN);
|
||
|
ShowSettingWindow();
|
||
|
}
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
case AREXX_PARAMETER_TIMEOUT:
|
||
|
if (TryParseLong(valueString, &longValue))
|
||
|
SetTimeout(longValue, APPLY_VALUE);
|
||
|
else
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_INVALID;
|
||
|
break;
|
||
|
default:
|
||
|
msg->rm_Result1 = AREXX_COMMAND_PARM_UNKNOWN;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ArexxShowCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
ShowSettingWindow();
|
||
|
}
|
||
|
|
||
|
static void ArexxHideCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
SendWindowMessage(ATK_SHUTDOWN);
|
||
|
}
|
||
|
|
||
|
static void ArexxStartCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
if (!SynchronizerRunning)
|
||
|
{
|
||
|
Activate();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// TODO: Set error text
|
||
|
msg->rm_Result1 = AREXX_COMMAND_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ArexxStopCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
if (SynchronizerRunning)
|
||
|
{
|
||
|
Deactivate();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// TODO: Set error text
|
||
|
msg->rm_Result1 = AREXX_COMMAND_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ArexxShutdownCommand(struct RexxMsg *msg, char **parms)
|
||
|
{
|
||
|
LogWarn("Requesting shutdown");
|
||
|
msg->rm_Result1 = AREXX_COMMAND_SHUTDOWN;
|
||
|
}
|
||
|
|
||
|
static bool HandleArexxMessage(struct RexxMsg *msg)
|
||
|
{
|
||
|
int i;
|
||
|
bool found = false;
|
||
|
bool cont = true;
|
||
|
|
||
|
msg->rm_Result1 = AREXX_COMMAND_UNKNOWN;
|
||
|
msg->rm_Result2 = 0;
|
||
|
|
||
|
for (i = 0; i < AREXX_COMMAND_COUNT; i++)
|
||
|
{
|
||
|
if (arexxCommands[i].Parameters == 0 && Stricmp((STRPTR)msg->rm_Args[0], (STRPTR)arexxCommands[i].Name) == 0)
|
||
|
{
|
||
|
LogNotice("Received %s", arexxCommands[i].Name);
|
||
|
msg->rm_Result1 = AREXX_COMMAND_OK;
|
||
|
arexxCommands[i].Command(msg, NULL);
|
||
|
found = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!found)
|
||
|
{
|
||
|
char *args[AREXX_MAX_ARGS_COUNT];
|
||
|
char *buf = AllocStringSafe(StrLen(msg->rm_Args[0]) + 1);
|
||
|
|
||
|
StrCopy(buf, msg->rm_Args[0]);
|
||
|
for (i = 1; i < AREXX_MAX_ARGS_COUNT; i++)
|
||
|
{
|
||
|
args[i] = NULL;
|
||
|
}
|
||
|
|
||
|
SplitAndTerminate(buf, args);
|
||
|
for (i = 0; i < AREXX_COMMAND_COUNT; i++)
|
||
|
{
|
||
|
if (arexxCommands[i].Parameters > 0 && Stricmp((STRPTR)buf, (STRPTR)arexxCommands[i].Name) == 0)
|
||
|
{
|
||
|
LogNotice("Received %s", arexxCommands[i].Name);
|
||
|
msg->rm_Result1 = AREXX_COMMAND_OK;
|
||
|
arexxCommands[i].Command(msg, args);
|
||
|
found = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FreeMemSafe(buf);
|
||
|
}
|
||
|
|
||
|
if (msg->rm_Result1 == AREXX_COMMAND_SHUTDOWN)
|
||
|
{
|
||
|
msg->rm_Result1 = AREXX_COMMAND_OK;
|
||
|
cont = false;
|
||
|
}
|
||
|
|
||
|
return cont;
|
||
|
}
|
||
|
|
||
|
bool HandleARexxMessages(void)
|
||
|
{
|
||
|
bool cont = true;
|
||
|
struct RexxMsg *msg;
|
||
|
|
||
|
while ((msg = (struct RexxMsg *)GetNewMessage(MSGPORT_AREXX)))
|
||
|
{
|
||
|
cont &= HandleArexxMessage(msg);
|
||
|
ReplyMsg((struct Message *)msg);
|
||
|
}
|
||
|
|
||
|
return cont;
|
||
|
}
|