299 lines
6.4 KiB
C
299 lines
6.4 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 <stddef.h>
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
|
|
#include <proto/dos.h>
|
|
#include <proto/exec.h>
|
|
#include <exec/ports.h>
|
|
#include <exec/memory.h>
|
|
|
|
#include "global.h"
|
|
#include "message.h"
|
|
#include "string.h"
|
|
|
|
const char *vers = "\0$VER: TimeControl 1.12 (31.01.2021)";
|
|
|
|
#define ARGSFORMAT "ID/S,VERSION/S,STATUS/S,TIME/S,ZONE/S,START/S,STOP/S,SHOW/S,HIDE/S,SHUTDOWN/S"
|
|
|
|
struct RDArgs *rdargs = NULL;
|
|
struct MsgPort *replyPort = NULL;
|
|
LONG returnCode = 0;
|
|
|
|
struct progargs
|
|
{
|
|
long id;
|
|
long version;
|
|
long status;
|
|
long time;
|
|
long timezone;
|
|
long start;
|
|
long stop;
|
|
long show;
|
|
long hide;
|
|
long shutdown;
|
|
};
|
|
|
|
void InitializeArgs(struct progargs *args)
|
|
{
|
|
args->id = FALSE;
|
|
args->version = FALSE;
|
|
args->status = FALSE;
|
|
args->time = FALSE;
|
|
args->timezone = FALSE;
|
|
args->start = FALSE;
|
|
args->stop = FALSE;
|
|
args->show = FALSE;
|
|
args->hide = FALSE;
|
|
args->shutdown = FALSE;
|
|
}
|
|
|
|
struct ControlMesage *CreateControlMessage(long messageId)
|
|
{
|
|
struct ControlMesage *message;
|
|
message = (struct ControlMesage *)AllocVec(sizeof(struct ControlMesage), MEMF_ANY | MEMF_CLEAR);
|
|
|
|
if (message)
|
|
{
|
|
message->AppMsg.Msg.mn_Node.ln_Type = NT_MESSAGE;
|
|
message->AppMsg.Msg.mn_Length = sizeof(struct ControlMesage);
|
|
message->AppMsg.Msg.mn_ReplyPort = replyPort;
|
|
message->AppMsg.MsgType = MSGTYPE_CTRL;
|
|
message->AppMsg.MsgId = messageId;
|
|
message->Args = NULL;
|
|
message->Result = AllocVec(128, MEMF_ANY | MEMF_CLEAR);
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
void SendControlMessage(struct ControlMesage *message)
|
|
{
|
|
struct MsgPort *port;
|
|
|
|
Forbid();
|
|
port = FindPort((CONST_STRPTR)CONTROL_PORT_NAME);
|
|
if (port != NULL)
|
|
{
|
|
PutMsg(port, (struct Message *)message);
|
|
}
|
|
Permit();
|
|
|
|
if (port != NULL)
|
|
{
|
|
WaitPort(replyPort);
|
|
GetMsg(replyPort);
|
|
|
|
if (message->Code == ATK_CTRL_UNKNOWN)
|
|
{
|
|
Printf((STRPTR)APP_SHORT_NAME " could not process control command.\n");
|
|
}
|
|
else if (*message->Result != '\0')
|
|
{
|
|
Printf((STRPTR)message->Result);
|
|
Printf((STRPTR) "\n");
|
|
}
|
|
|
|
if (message->Code > returnCode)
|
|
{
|
|
returnCode = message->Code;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Printf((STRPTR) "Could not send control message.\n");
|
|
}
|
|
}
|
|
|
|
void FreeControlMessage(struct ControlMesage *message)
|
|
{
|
|
if (!message)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (message->Args)
|
|
{
|
|
FreeVec(message->Args);
|
|
}
|
|
|
|
if (message->Result)
|
|
{
|
|
FreeVec(message->Result);
|
|
}
|
|
|
|
FreeVec(message);
|
|
}
|
|
|
|
void SendSimpleMessage(long messageId)
|
|
{
|
|
struct ControlMesage *message = CreateControlMessage(messageId);
|
|
if (message)
|
|
{
|
|
SendControlMessage(message);
|
|
FreeControlMessage(message);
|
|
}
|
|
}
|
|
|
|
void ValidateArgs(struct progargs *args)
|
|
{
|
|
if (args->start && args->stop)
|
|
{
|
|
Printf((STRPTR) "Please either START or STOP in arguments.\n");
|
|
args->start = FALSE;
|
|
args->stop = FALSE;
|
|
}
|
|
|
|
if (args->show && args->hide)
|
|
{
|
|
Printf((STRPTR) "Please either SHOW or HIDE in arguments.\n");
|
|
args->show = FALSE;
|
|
args->hide = FALSE;
|
|
}
|
|
}
|
|
|
|
void ProcessArgs(struct progargs *args)
|
|
{
|
|
BOOL processed = FALSE;
|
|
|
|
if (args->id)
|
|
{
|
|
SendSimpleMessage(ATK_ID);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->version)
|
|
{
|
|
SendSimpleMessage(ATK_VERSION);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->status)
|
|
{
|
|
SendSimpleMessage(ATK_STATUS);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->time)
|
|
{
|
|
SendSimpleMessage(ATK_TIME);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->timezone)
|
|
{
|
|
SendSimpleMessage(ATK_TIMEZONE);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->show)
|
|
{
|
|
SendSimpleMessage(ATK_SHOW);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->hide)
|
|
{
|
|
SendSimpleMessage(ATK_HIDE);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->start)
|
|
{
|
|
SendSimpleMessage(ATK_ENABLE);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->stop)
|
|
{
|
|
SendSimpleMessage(ATK_DISABLE);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (args->shutdown)
|
|
{
|
|
SendSimpleMessage(ATK_SHUTDOWN);
|
|
processed = TRUE;
|
|
}
|
|
|
|
if (!processed)
|
|
{
|
|
Printf((STRPTR) "Please specify arguments.\n");
|
|
}
|
|
}
|
|
|
|
void Cleanup(void)
|
|
{
|
|
if (replyPort)
|
|
{
|
|
DeleteMsgPort(replyPort);
|
|
}
|
|
|
|
if (rdargs)
|
|
{
|
|
FreeArgs(rdargs);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
struct progargs args;
|
|
struct MsgPort *port;
|
|
|
|
InitializeArgs(&args);
|
|
|
|
rdargs = ReadArgs((STRPTR)ARGSFORMAT, (APTR)&args, NULL);
|
|
if (!rdargs)
|
|
{
|
|
PrintFault(IoErr(), (APTR)argv[0]);
|
|
Cleanup();
|
|
exit(5);
|
|
}
|
|
|
|
port = FindPort((CONST_STRPTR)CONTROL_PORT_NAME);
|
|
if (port == NULL)
|
|
{
|
|
Printf((STRPTR)APP_SHORT_NAME " is not running.\n");
|
|
Cleanup();
|
|
exit(1);
|
|
}
|
|
|
|
replyPort = CreateMsgPort();
|
|
if (replyPort == NULL)
|
|
{
|
|
Cleanup();
|
|
exit(5);
|
|
}
|
|
|
|
ValidateArgs(&args);
|
|
ProcessArgs(&args);
|
|
|
|
Cleanup();
|
|
return returnCode;
|
|
}
|