/*
 *  Reboot.c - make an executable which calls exec's ColdReboot()
 *
 *  Public Domain
 *
 *  by Stefan Sticht
 *
 *  V1.00 initial release
 *  V1.01 added Ctrl-C detect
 *  V1.02 added PROMPTing and YES
 */

#define VERSION "1.02"

#include <stdlib.h>
#include <string.h>
#include <dos/dos.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>
#include <clib/utility_protos.h>
#include <pragmas/utility_pragmas.h>

/*
 *  our template for ReadArgs()
 */
#define TEMPLATE    "PROMPT/K,YES/K,TIMEOUT/K/N,QUIET/S"
#define OPT_PROMPT  0
#define OPT_YES     1
#define OPT_TIMEOUT 2
#define OPT_QUIET   3
#define OPT_COUNT   4

/*
 *  default prompt and answer
 */
#define PROMPT  "Do you really want to reboot (y/N)? "
#define YES     "y"

static char prompt[] = PROMPT;
static char yes[] = YES;

/*
 *  this array will be filled by ReadArgs()
 */
long opts[] = {
    (long)prompt,   /* OPT_PROMPT   */
    (long)yes,      /* OPT_YES      */
    0l,             /* OPT_TIMEOUT  */
    0l              /* OPT_QUIET    */
    };

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

/*
 *  some SAS/C specularities, change for other compilers!
 */
#ifdef __SASC
extern struct Library *DOSBase; /* Library base pointer from startup code */
extern struct Library *SysBase; /* Library base pointer from startup code */
void chkabort(void) {}          /* disable Ctrl-C detect */
#endif

void _main(char *line)
{
    struct RDArgs *argsptr;
    struct Library *UtilityBase;
    unsigned long seconds = 0l;
    char buffer[16];
    char *prompt;
    char *yes;
    short quiet;
    short rc = 0;

    /*
     *  check for right kickstart! Anything under V37 will be refused!
     */
    if ((DOSBase->lib_Version < 37) || (SysBase->lib_Version < 37)) exit(30);

    /*
     *  command line parsing by DOS
     */
    if (argsptr = ReadArgs(TEMPLATE, opts, NULL)) {

        /*
         *  if the user didn't specify an argument, we'll get defaults
         */
        quiet   = opts[OPT_QUIET];
        prompt  = (char *)opts[OPT_PROMPT];
        yes     = (char *)opts[OPT_YES];

        /*
         *  string in yes mustn't be longer than buffer!
         */
        if (strlen(yes) > (sizeof(buffer) - 1l)) {
            if (!quiet) PutStr("String for YES too long!\n");
            rc = 10;
            }

        if (opts[OPT_TIMEOUT]) {

            if (*(long *)(opts[OPT_TIMEOUT]) < 0l) {
                if (!quiet) PutStr("Timeout must be positive!\n");
                rc = 6;
                }

            else seconds = *(long *)(opts[OPT_TIMEOUT]);

            }

        } /* if argsptr = ReadArgs() */

    else {
        PrintFault(IoErr(), NULL);
        rc = 20;
        }

    /*
     *  prompt the user
     */
    if (!rc && !quiet) {

        if (UtilityBase = OpenLibrary("utility.library", 37l)) {

            PutStr(prompt);
            Flush(Output());
            if (FGets(Input(), buffer, sizeof(buffer))) {
                if (Strnicmp(yes, buffer, strlen(yes))) rc = 5;
                }
            else rc = 5;

            CloseLibrary(UtilityBase);
            }
        else {
            PutStr("Can't open utility.library v37 or higher!\n");
            rc = 15;
            }

        }

    if (!rc) {

        if (seconds) {
            if (!quiet)
                VPrintf("Rebooting in %ld seconds. Press Ctrl-C to abort!\n", &seconds);
            Delay(seconds * 50l);
            }

        if (SetSignal(0l, 0l) & SIGBREAKF_CTRL_C) {
            if (!quiet) PutStr("***Break\n");
            rc = 5;
            }
        else ColdReboot();

        }

    FreeArgs(argsptr);

    exit(rc);
}
