home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
System
/
ExecuteOnReset
/
ExecuteOnReset.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-08-13
|
7KB
|
288 lines
/*******************************************************************************
*
* Program: ExecuteOnReset
* Filename: ExecuteOnReset.c
*
* Usage: Run <>NIL: ExecuteOnReset [-p pri] string1 [string2] ...
* -p pri - priority (default: 0)
* string1 - command line 1 to execute
* string2 - optional command line 2 to execute
* ... - more command lines.
*
* Contents: Installes a reset handler which executes the command
* lines on case of a reset (CTRL-Amiga-Amiga). After
* execution of all commands the handler continues with
* the reset (or other installed reset handlers)
* imediately! So if you do some disk tasks add a
* "Wait 3 secs" line as last command to avoid non
* validated disks. You must be cautionous: The Amiga
* allows a maximum of 10 seconds to do all reset handler
* tasks. After this amount of time a hard reset occurs
* regardless if a command has finished or not. If you
* install more reset handlers you can choose the order
* of execution by the priority argument.
* The Run command is necessary to detach from the shell.
* A CTRL-C signal removes the handler.
*
* Language: C
*
* Link-instr.: Objects: c.o ExecuteOnReset.o keyhandler.o
* Libraries: amiga.lib
* Output: ExecuteOnReset
*
* Author: Johannes R. Geiss
*
* Copyright: Amigavisions
*
* History: $HISTORY:
*
* 08 Aug 2000 : 001.001 : written jgeiss
*
* Version: $VER: ExecuteOnReset 1.001 (08 Aug 2000)
*
*******************************************************************************/
/**************/
/*- Includes -*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/interrupts.h>
#include <dos/dos.h>
#include <devices/keyboard.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
/*************/
/*- Imports -*/
extern void ResetHandler();
/*****************/
/*- Definitions -*/
#define VER "1.1"
#define CSI "\x9b"
#define COLORBOLD CSI "1;33m"
#define COLOR CSI "0;33m"
#define NORMAL CSI "0m"
/*************/
/*- Structs -*/
struct MyData
{
struct Task *MyTask;
ULONG MySignal;
};
/**********/
/*- main -*/
int main(int argc, char *argv[])
{
BYTE pri = 0;
int i, start;
UWORD len;
char *command;
int rc = 0;
ULONG MySignal;
struct MyData MyDataStuff;
struct Interrupt *keyHandler;
struct IOStdReq *keyReqBlk;
/*
* handle arguments
*/
i = 1;
if((argc > i) && (!strcmp(argv[i], "?"))) {
printf("\n"
COLORBOLD "ExecuteOnReset V" VER ":" COLOR " Copyright (C) 2000, Amigavisions" NORMAL "\n"
"Usage: Run <>NIL: %s [-p pri] string1 [string2] ...\n"
" -p pri - priority (default: 0)\n"
" string1 - command line 1 to execute\n"
" string2 - optional command line 2 to execute\n"
" ... - more command lines.\n"
"Installes a reset handler which executes the command lines on case of a reset\n"
"(CTRL-Amiga-Amiga). After execution of all commands the handler continues with\n"
"the reset (or other installed reset handlers) imediately! So if you do some disk\n"
"tasks add a \"Wait 3 secs\" line as last command to avoid non validated disks.\n"
"You must be cautionous: The Amiga allows a maximum of 10 seconds to do all reset\n"
"handler tasks. After this amount of time a hard reset occurs regardless if a\n"
"command has finished or not. If you install more reset handlers you can choose\n"
"the order of execution by the priority argument.\n"
"The Run command is necessary to detach from the shell. A CTRL-C signal removes\n"
"the handler.\n"
"\n", argv[0]);
return 5;
}
if((argc > i) && (argv[i][0] == '-')) {
if(argv[i][1] == 'p') {
if(argv[i][2]) pri = atoi(&argv[i++][2]);
else if(argc > ++i) pri = atoi(argv[i++]);
else {
fprintf(stderr, "%s: missing priority\n", argv[0]);
return 10;
}
}
else {
fprintf(stderr, "%s: unknown option: -%c\n", argv[0], argv[i][1]);
return 11;
}
}
start = i;
len = 0;
while(i < argc) len += strlen(argv[i++]) + 1;
if(len == 0) {
fprintf(stderr, "%s: missing command line\n", argv[0]);
return 12;
}
/*
* create command
*/
if(command = AllocMem(len, MEMF_PUBLIC|MEMF_CLEAR)) {
i = start;
while(i < argc) {
strcat(command, argv[i++]);
strcat(command, "\n");
}
/*
* install reset handler
*/
if((MySignal = AllocSignal(-1l)) != -1) {
MyDataStuff.MyTask = FindTask(NULL);
MyDataStuff.MySignal = 1l << MySignal;
if(keyHandler = AllocMem(sizeof(struct Interrupt),
MEMF_PUBLIC|MEMF_CLEAR)) {
if(keyReqBlk = (struct IOStdReq *)
CreateExtIO(CreatePort(NULL, 0), sizeof(struct IOStdReq))) {
if(!(OpenDevice("keyboard.device", NULL,
(struct IORequest *)keyReqBlk, NULL))) {
keyHandler->is_Code = ResetHandler;
keyHandler->is_Data = (APTR)&MyDataStuff;
keyHandler->is_Node.ln_Pri = pri;
keyHandler->is_Node.ln_Name = argv[0];
keyReqBlk->io_Data = (APTR)keyHandler;
keyReqBlk->io_Command = KBD_ADDRESETHANDLER;
DoIO((struct IORequest *)keyReqBlk);
/*
* wait for reset or CTRL-C
*/
if(Wait(MyDataStuff.MySignal|SIGBREAKF_CTRL_C)
& MyDataStuff.MySignal) {
/*
* captured a reset
* now execute the command(s)
*/
system(command);
/*
* tell reset handler we are finished
* so others can do their job
*/
keyReqBlk->io_Data = (APTR)keyHandler;
keyReqBlk->io_Command = KBD_RESETHANDLERDONE;
DoIO((struct IORequest *)keyReqBlk);
/*
* wait for reset
*/
Wait(0l);
}
/*
* got a CTRL-C
* so we remove ourself
*/
keyReqBlk->io_Data = (APTR)keyHandler;
keyReqBlk->io_Command = KBD_REMRESETHANDLER;
DoIO((struct IORequest *)keyReqBlk);
CloseDevice((struct IORequest *)keyReqBlk);
}
else {
fprintf(stderr, "%s: couldn't open keyboard device\n", argv[0]);
rc = 24;
}
}
else {
fprintf(stderr, "%s: couldn't create keyboard io\n", argv[0]);
rc = 23;
}
FreeMem(keyHandler, sizeof(struct Interrupt));
}
else {
fprintf(stderr, "%s: couldn't allocate memory\n", argv[0]);
rc = 22;
}
FreeSignal(MySignal);
}
else {
fprintf(stderr, "%s: couldn't allocate signal\n", argv[0]);
rc = 21;
}
FreeMem(command, len);
}
else {
fprintf(stderr, "%s: couldn't allocate memory\n", argv[0]);
rc = 20;
}
/*
* exit
*/
return rc;
}
/** EOF **/