/*
**	$RCSfile: Broadcast.c,v $
**	$Filename: Broadcast.c $
**	$Revision: 1.1 $
**	$Date: 2000/05/01 19:47:16 $
**
**	sysmon.library support command Broadcast (version 1.1) 
**	
**	(C) Copyright 1995-2000 by Etienne Vogt
*/

#include <exec/alerts.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <workbench/startup.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
#include <stdlib.h>
#include "sysmon.h"
#include "sysmon_protos.h"
#include "sysmon_pragmas.h"

struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct SysmonBase *SysmonBase;
static struct WBStartup *wbmsg;
static struct RDArgs *myrda;
struct BroadcastMsg *bcmsg;

ULONG __saveds main(void);
static void cleanexit(ULONG rc);
static __inline BOOL SysLog(ULONG priority, APTR format, ...);

static UBYTE version[] = "$VER: Broadcast 1.1 (30.4.2000)";
static UBYTE template[] = "MESSAGE/A,COUNTDOWN/K/N,TIMEOUT/K/N,CANCEL/S,DEBUG/S,NORMAL/S,URGENT/S,SHUTDOWN/S,UNMOUNT/S,HALT/S";

#define OPT_MESSAGE	0
#define	OPT_COUNTDOWN	1
#define OPT_TIMEOUT	2
#define	OPT_CANCEL	3
#define	OPT_DEBUG	4
#define OPT_NORMAL	5
#define	OPT_URGENT	6
#define	OPT_SHUTDOWN	7
#define	OPT_UNMOUNT	8
#define	OPT_HALT	9
#define OPTMAX		10

ULONG __saveds main(void)	/* No startup code */
{
  struct Process *myproc;
  LONG opts[OPTMAX];

  SysBase = *(struct ExecBase **)4;
  DOSBase = NULL;
  SysmonBase = NULL;
  wbmsg = NULL;
  myrda = NULL;
  bcmsg = NULL;

  myproc = (struct Process *)FindTask(NULL);
  if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
  { Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
    return 100;
  }

  if (!(myproc->pr_CLI))		/* If started from WB, exit cleanly */
  { WaitPort(&(myproc->pr_MsgPort));
    wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
    cleanexit(20);
  }
  else
  { memset((char *)opts, 0, sizeof(opts));
    if ((SysmonBase = (struct SysmonBase *)OpenLibrary("sysmon.library",1)) == NULL)
    { PutStr("Broadcast : Couldn't open sysmon.library V1\n");
      cleanexit(20);
    }
    if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
    { PrintFault(IoErr(),NULL);
      cleanexit(20);
    }

    if ((bcmsg = AllocVec(sizeof(struct BroadcastMsg), MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
    { PutStr("Broadcast : No memory for struct BroadCastMsg\n");
      cleanexit(20);
    }

    bcmsg->bcm_EventTxt = (STRPTR)opts[OPT_MESSAGE];
    bcmsg->bcm_TimeOut = 50;
    bcmsg->bcm_Level = BCM_NORMAL;

    if (opts[OPT_COUNTDOWN]) bcmsg->bcm_CountDown = *((ULONG *)opts[OPT_COUNTDOWN]);
    if (opts[OPT_TIMEOUT]) bcmsg->bcm_TimeOut = *((ULONG *)opts[OPT_TIMEOUT]);

    if (opts[OPT_CANCEL]) bcmsg->bcm_Flags |= BCMF_CANCEL;

    if (opts[OPT_DEBUG]) bcmsg->bcm_Level = BCM_DEBUG;
    if (opts[OPT_NORMAL]) bcmsg->bcm_Level = BCM_NORMAL;
    if (opts[OPT_URGENT]) bcmsg->bcm_Level = BCM_URGENT;
    if (opts[OPT_SHUTDOWN]) bcmsg->bcm_Level = BCM_SHUTDOWN;
    if (opts[OPT_UNMOUNT]) bcmsg->bcm_Level = BCM_UNMOUNT;
    if (opts[OPT_HALT]) bcmsg->bcm_Level = BCM_HALT;

    if (smSendBroadcastMsg(bcmsg) >= 0)
    { Printf("Broadcast Message successfully sent to %ld clients (%ld timeouts)\n",bcmsg->bcm_ReplyCount,bcmsg->bcm_TimeOutCount);
      Printf("%s\n",bcmsg->bcm_EventTxt);
    }
    else
    { PutStr("Broadcast : Error sending broadcast message\n");
      cleanexit(10);
    }
  }
  cleanexit(0);
}

static void cleanexit(ULONG rc)
{
  if (bcmsg) FreeVec(bcmsg);
  if (myrda) FreeArgs(myrda);
  if (DOSBase) CloseLibrary((struct Library *)DOSBase);
  if (SysmonBase) CloseLibrary((struct Library *)SysmonBase);
  if (wbmsg)
  { Forbid();
    ReplyMsg((struct Message *)wbmsg);
  }
  Exit(rc);
}

static __inline BOOL SysLog(ULONG priority, APTR format, ...)
{ return smVSysLog(priority, format, &format + 1);
}
