/* reboot program by Kees Lemmens; May 1993 */

/* version  1.1 : July 1993

	Non-existing devices caused bus-errors in wall function.
	This made the program useless for users of non MEGA-STE
	ATARI's. Sorry !!
	It now checks to see if the device exists before sending
	the shutdown messages to that device.

   version 1.2 : Sept 1993

	Reboot can only be run by uid 0 (root) from now on.
*/

#ifdef __PUREC__
#include <tos.h>
#else
#include <osbind.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <signal.h>
#include "ux_misc.h"

#define WARM 0
#define COLD 1

void domessage(char *msg,char *term,va_list ptr)
{	FILE *fp;

	/* avoid adressing non-existing devices !!! */

	if((fp=fopen(term,"w")) == NULL)
		return;	
	vfprintf(fp,msg,ptr);
	fclose(fp);
}

void wall(char *msg,...)
{	int t;
	va_list ptr;
	char **terms;
	char *tosterms[]  = { "con:", "aux:", NULL };
	char *mintterms[] = 
	{	"u:\\dev\\console", "u:\\dev\\modem1" ,
		"u:\\dev\\modem2" ,	"u:\\dev\\modem3" ,
		"u:\\dev\\serial1", "u:\\dev\\serial2",
		"u:\\dev\\serial3",  NULL
	};
	
	if(RunningMint())
		terms=mintterms;
	else
		terms = tosterms;

	va_start(ptr,msg);

	for(t=0;terms[t] != NULL; t++)
		domessage(msg,terms[t],ptr);
	va_end(ptr);
}

void reset(int mode)
{	long suret;
	long *memvalid    = (long *)0x420L;
	long *resvalid    = (long *)0x426L;
	long *resetptr    = (long *)0x0004L;

	suret=Super(0L);
	
	if(*resvalid != 0x31415926L)
	{	printf("\r\nReset vector invalid, reboot aborted");
		exit(1);
	}
	else
	{	if(mode == COLD) *memvalid = 0L;
		Supexec((long (*)())(*resetptr));
	}
	Super((void *)suret);
}

#define MINSZ 60

void main(int argc,char *argv[])
{	time_t tstart,tend;
	struct tm *ctm;
	int susptm,x,coldfl=0,gap=5;
	char *msg1=	"\n\n\t*** System shutdown message from root@atari ***"
				"\n\nSystem going down in %d minutes\n";
	char *msg2=	"\n\n\t*** FINAL System shutdown message from"
				" root@atari ***\n\nSystem going down NOW !!"
				"\n\nSystem shutdown time has arrived\n";
	char *msg3=	"\n\n\t*** System shutdown aborted !! ***\n\n";

	if(RunningMint())
	{	if(Pgetuid() != 0)
		{	printf("Not enough privileges to reboot system.\n");
			exit(1);
		}
	}
	x=argc;
	while(--x>0)
	{	if(*argv[1]=='-')
		{	switch(*(++argv[1]))
			{	case 'c':	coldfl=1; break;
				default:	printf("Usage= reboot [-c] [interval]\n");
							exit(1);
			}
			++argv; --argc;
		}
	}	
	if(argc>1) gap = atoi(argv[1]);
	
	time(&tstart);
	tend = tstart + gap*MINSZ;
	ctm=localtime(&tend);
	printf("\nShutdown at %02d:%02d (in %d minutes)",
			ctm->tm_hour,ctm->tm_min,gap);

	signal(SIGINT,SIG_IGN);
	
	while(time(&tstart) < tend)
	{	wall(msg1,(int)((tend-tstart+2)/MINSZ));
		susptm = (tend - tstart > 5*MINSZ) ? 5*MINSZ : MINSZ;
		for(x=0;x<susptm;x+=5)
		{	sleep(5);
			if (Cconis())	/* provide escape on remote terminals */
			{	if((int)Crawcin() == '\03')
				{	wall(msg3);
					exit(1);
				}
			}
		}
	}
	wall(msg2);
	sleep(3);	/* time to read console message ! */
	
	if(coldfl) 	reset(COLD);
	else reset(WARM);	
	exit(0);
}