/*
 *  Notify - the small notification utility
 *  © 1991 Stefan Sticht
 *  freely distributable
 *
 *  To compile with DICE: dcc -r Notify.c -o Notify
 *
 *  V1.00 25 Sep 1991 Stefan Sticht
 */

#define VERSION "V1.00"

#include <stdlib.h>
#include <dos/notify.h>
#include <exec/memory.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

/*
 *  some SAS/C specularities, change for other compilers!
 */
#ifdef __SASC
#include <pragmas/dos_pragmas.h>    /* pragmas for inline library calls         */
#include <pragmas/exec_pragmas.h>   /* pragmas for inline library calls         */
void chkabort(void) {}              /* disable Ctrl-C detect                    */
#endif

extern struct Library *SYSBase;     /* Library base pointer from startup code   */
extern struct Library *DOSBase;     /* Library base pointer from startup code   */

/*
 *  a string, which will be found by Version
 */
char version[] = "\0$VER: Notify " VERSION;

#define TEMPLATE "File/A,Times/K/N,Quiet/S"
#define OPT_FILE            0
#define OPT_TIMES           1
#define OPT_QUIET           2
#define OPT_COUNT           3
/*
 *  this array will be filled by ReadArgs()
 */
long options[OPT_COUNT];

void _main(char *line)
{
	struct NotifyRequest *notifyrequest;
    long rc = 20;
    long times = 1;
    struct RDArgs *args;
    unsigned long sigreceived;
    unsigned char signal;

    /*
     *  first check DOS version; we require at least V37
     */
    if (DOSBase->lib_Version >= 37l) {
        /*
         *  get command line arguments
         */
        if (args = ReadArgs((UBYTE *)TEMPLATE, options, NULL)) {
            /*
             *  alloc public memory for notifyrequest
             */
            if (notifyrequest = (struct NotifyRequest *)AllocMem(sizeof(struct NotifyRequest), MEMF_PUBLIC)) {
                /*
                 *  alloc a signal
                 */
                if ((signal = AllocSignal(-1)) != -1l) {
                    /*
                     *  fill out notifyrequest
                     */
                    notifyrequest->nr_Name = (char *)options[OPT_FILE];
                    notifyrequest->nr_Flags = NRF_SEND_SIGNAL;
                    notifyrequest->nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
                    notifyrequest->nr_stuff.nr_Signal.nr_SignalNum = signal;
                    /*
                     *  now start a notify
                     */
                    if (StartNotify(notifyrequest) == DOSTRUE) {

                        rc = 0;
                        if (options[OPT_TIMES]) times = *((long *)options[OPT_TIMES]);
                        if (!options[OPT_QUIET]) VPrintf("Notification on %s started...\n", &options[OPT_FILE]);

                        while (times--) {
                            /*
                             *  Wait times times for a signal or one time for a break signal
                             */
                            sigreceived = Wait(SIGBREAKF_CTRL_C | (1 << signal));
                            if (sigreceived & SIGBREAKF_CTRL_C) {
                                /*
                                 *  user pressed or sent Ctrl-C
                                 */
                                times = 0;
                                rc = 5;
                                if (!options[OPT_QUIET]) PutStr("***Break\n");
                                }

                            if ((sigreceived & (1 << signal)) && !options[OPT_QUIET])
                                PutStr("Notified.\n");

                            } /* while times */
                        /*
                         *  remove notify
                         */
                    	EndNotify(notifyrequest);

                        }

                    else {
                        /*
                         *  StartNotify returned an error
                         */
                        rc = 10;
                        PrintFault(IoErr(), "Error");
                        }

                    /*
                     *  free allocated signal
                     */
                    FreeSignal((long)signal);

                    } /* if signal = AllocSignal() */

                else if (!options[OPT_QUIET]) PutStr("Couldn't allocate signal!\n");

                /*
                 *  free memory of notifyrequest
                 */
                FreeMem(notifyrequest, sizeof(struct NotifyRequest));

                } /* if notifyrequest = AllocMem() */

            else if (!options[OPT_QUIET]) PutStr("Couldn't allocate memory!\n");

            /*
             *  free arguments allocated by ReadArgs()
             */
            FreeArgs(args);

            } /* if args = ReadArgs() */

        else {
            /*
             *  wrong number of or wrong arguments
             */
            if (!options[OPT_QUIET]) PrintFault(IoErr(), NULL);
            }

        } /* if (DOSBase->dl_lib.lib_Version > 37l) */

    exit(rc);
}
