home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
576.lha
/
DisDF_v1.1
/
DisDF.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-28
|
11KB
|
473 lines
/* DisDF.c V1.1 Disables DF0-DF3 */
/* Patrick F. Misteli 22.7.91 */
/* see DisDF.doc and 'usage' below */
#define ND 4 /* max floppy drives */
#define NN 100 /* max tasknodes to scan */
#define DISABLEDP -123 /* priority of disabled task */
#define BUSYPRI -122
#include <exec/types.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <stdio.h>
#include <devices/trackdisk.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <dos.h> /* LATTICE is defined in dos.h */
/* manx 3.4b doesn't have dos.h so add one with AZTEC defined in it */
#ifdef LATTICE
#include <proto/exec.h>
#else
#ifdef AZTEC
struct IORequest *CreateExtIO();
struct MsgPort *CreatePort();
#include <functions.h>
#else
#define OTHER_COMPILER 1
struct IORequest *CreateExtIO();
struct MsgPort *CreatePort();
struct Task *DeviceProc();
struct Task *FindTask();
long SetTaskPri();
long Signal();
char *AllocMem();
struct Task *CreateTask();
#endif
#endif
extern struct ExecBase *SysBase;
char extioerrmsg[] = "DisDF CreateExtIO() error";
char creatportmsg[] = "DisDF CreatePort() error";
char nofloppymsg[] = "DisDF no floppy drive found";
char notmountmsg[] = "DisDF DFi not mounted";
char missingdmsg[] = "DisDF DFi device process missing";
char missingtmsg[] = "DisDF DFi trackdisk.device task missing";
char missingfmsg[] = "DisDF DFi File Process task missing";
char memerrormsg[] = "DisDF not enough memory";
char statusokmsg[] = "DisDF DFi trackdisk oxx File System oxx";
char statusermsg[] = "DisDF DFi error";
char busytaskmsg[] = "DisDF BusyLoop-122 running";
char *usagemsg[] =
{
"\nDisDF V1.0 toggles floppy drives' trackdisk.device tasks off or on\n",
"usage : DisDF [0] [1] [2] [3] [-d|e] [-f] [-h]",
" # drive number if not all DF0: to DF3:",
" -c change priorities and start busyloop task",
" -d disable instead of toggle",
" -e enable instead of toggle",
" -f disable floppy drives' File System tasks also",
" -h help message to stdout",
" -s status message to stdout only, tasks not changed",
" -v verbose",
NULL
};
char trackdisk[] = TD_NAME; /* "trackdisk.device" */
char filesystem[] = "File System";
char dfstr[] = "DF0:";
char busyname[] = "BusyLoop-122";
struct Task *me;
struct Node *fnode[ ND ], *tnode[ ND ];
struct Task *busytask;
int drive[ ND ], statusonly, chicken;
long previouspri;
main( argc, argv )
int argc;
char *argv[];
{
register int i;
register struct Node *np;
register int j, k;
struct Node *anode[ NN ];
int all, en, ds, fs, verbose;
unsigned failval;
struct MsgPort *diskport;
struct IOExtTD *ioexttd;
failval = 0;
all = TRUE;
en = ds = fs = verbose = statusonly = chicken = FALSE;
for ( i = 0; i < ND; i++ )
{
drive[i] = FALSE;
tnode[i] = NULL;
fnode[i] = NULL;
}
if ( argc > 1 )
{
for ( i = 1; i < argc; i++ )
{
switch ( *argv[i] )
{
case '-':
if ( argv[ i ][ 2 ] )
usageexit();
switch( argv[ i ][ 1 ])
{
case 'c':
chicken = TRUE;
break;
case 'd':
if ( en )
usageexit();
ds = TRUE;
break;
case 'e':
if ( ds )
usageexit();
en = TRUE;
break;
case 'f':
fs = TRUE;
break;
case 's':
statusonly = TRUE;
break;
case 'v':
verbose = TRUE;
break;
default :
usageexit();
break;
}
break;
case '0' :
case '1' :
case '2' :
case '3' :
if ( argv[i][1] != 0 )
usageexit();
drive[ *argv[i] - 48 ] = TRUE;
all = FALSE;
break;
default:
usageexit();
break;
} /* switch */
} /* for i */
} /* argc > 1 */
if ( all )
drive[0] = drive[1] = drive[2] = drive[3] = TRUE;
me = FindTask( 0L );
previouspri = SetTaskPri( me, -1L ); /* allow most other tasks to finish */
Forbid(); /* before grabbing the CPU until exit() */
/* find out which drives are mounted by trying to open them */
diskport = CreatePort( 0, 0 );
if( diskport == NULL )
{
puts( creatportmsg );
permexit( 11 );
}
ioexttd = (struct IOExtTD *)CreateExtIO( diskport,
(long)sizeof(struct IOExtTD ) );
if( ioexttd == 0 )
{
puts( extioerrmsg );
DeletePort( diskport );
permexit( 12 );
}
for ( i = 0; i < ND; i++ )
{
if ( drive[i] )
if ( !OpenDevice( trackdisk, (long)i, (struct IORequest *)ioexttd, 0L ) )
{ /* get pointer to its trackdisk.device task */
tnode[i] =
(struct Node *)ioexttd->iotd_Req.io_Unit->unit_MsgPort.mp_SigTask;
CloseDevice( (struct IORequest *)ioexttd );
}
}
DeleteExtIO( (struct IORequest *)ioexttd, sizeof( struct IOExtTD ) );
DeletePort( diskport );
if ( all ) /* check that at least one drive was found */
{
for ( i = 0; i < ND; i++ )
if ( tnode[i] )
break;
if ( i >= ND )
{
puts( nofloppymsg );
permexit( 13 );
}
}
else
{
for ( i = 0; i < ND; i++ ) /* check for drives specified in command */
if ( !tnode[i] )
if ( drive[i] )
{
notmountmsg[8] = 48 + i;
puts( notmountmsg );
}
}
for ( i = 0; i < ND; i++ ) /* find each mounted drive's File System task */
{
if ( tnode[i] )
{
dfstr[2] = 48 + i;
fnode[i] = (struct Node *)DeviceProc( dfstr );
if ( fnode[i] )
fnode[i] = (struct Node *)( (long)fnode[i] - sizeof(struct Task) );
else
{
tnode[i] = NULL;
missingdmsg[8] = 48 + i;
puts( missingdmsg );
failval += 1 << (i + 4);
}
}
}
/* ensure that the tasks found above are in exec's task lists */
for ( i = 0; i < NN; i++ )
anode[i] = NULL;
i = 0;
Disable();
for ( np = (struct Node *)SysBase->TaskReady.lh_Head; i < NN, np->ln_Succ;
np = np->ln_Succ )
anode[i++] = np;
for ( np = (struct Node *)SysBase->TaskWait.lh_Head; i < NN, np->ln_Succ;
np = np->ln_Succ )
anode[i++] = np;
Enable();
for ( i = 0; i < ND; i++ )
{
if ( tnode[i] )
{
for ( j = 0; j < NN; j++ )
if ( tnode[i] == anode[j] )
break;
if ( j >= NN ) /* if the task is not there, ignore this drive */
{
tnode[i] = NULL;
fnode[i] = NULL;
missingtmsg[8] = 48 + i;
puts( missingtmsg );
failval += 1 << (i + 8);
}
}
if ( fnode[i] )
{
for ( j = 0; j < NN; j++ )
if ( fnode[i] == anode[j] )
break;
if ( j >= NN )
{
tnode[i] = NULL;
fnode[i] = NULL;
missingfmsg[8] = 48 + i;
puts( missingfmsg );
failval += 1 << (i + 12);
}
}
}
if ( statusonly )
{
typestatus();
permexit( 0 );
}
if ( !chicken )
{
Disable(); /* remove tasks found above from exec's task lists */
for ( i = 0; i < ND; i++ )
if( tnode[i] )
{
Remove( tnode[i] );
Remove( fnode[i] );
}
Enable();
}
for ( i = j = 0; i < ND; i++ ) /* modify priority */
{
if ( tnode[i] )
{
if ( en || ( ( tnode[i]->ln_Pri == DISABLEDP ) && !ds ) )
{
modtask( tnode[i], 5 );
modtask( fnode[i], 10 );
}
else
{
modtask( tnode[i], DISABLEDP );
if ( fs )
modtask( fnode[i], DISABLEDP );
else
modtask( fnode[i], 10 );
}
}
}
if ( !chicken )
{
Disable(); /* put modified tasks back in exec's lists */
for ( i = 0; i < ND; i++ )
if( tnode[i] )
{
if ( tnode[i]->ln_Pri == DISABLEDP )
{
AddTail( &SysBase->TaskWait, tnode[i] );
AddTail( &SysBase->TaskWait, fnode[i] );
}
else
{
AddTail( &SysBase->TaskReady, tnode[i] );
AddTail( &SysBase->TaskReady, fnode[i] );
}
}
Enable();
}
if ( busytask = FindTask( busyname ) ) /* maybe remove busytask */
{
for ( i = j = k = 0; i < ND; i++ )
if ( tnode[i] )
if ( tnode[i]->ln_Pri == DISABLEDP )
{
j++;
if ( ((struct Task*)tnode[i])->tc_State != TS_REMOVED )
k++;
}
else /* previously removed tasks in the wait list need a nudge */
{
Signal( (struct Task *)tnode[i],
((struct Task *)tnode[i])->tc_SigAlloc );
Signal( (struct Task *)fnode[i],
((struct Task *)fnode[i])->tc_SigAlloc );
}
if ( !j || ( !chicken && k ) )
rembusytask();
}
else /* maybe add busytask */
{
if ( chicken )
for ( i = 0; i < ND; i++ )
if ( tnode[i] )
if ( tnode[i]->ln_Pri == DISABLEDP )
break;;
if ( i < ND )
addbusytask();
}
if ( verbose )
typestatus();
permexit( failval );
} /* main */
usageexit()
{
register int i;
for ( i = 0; usagemsg[i][0]; i++ )
puts( usagemsg[i] );
exit( 10 );
}
modtask( task, pri ) /* modifies task state and priority */
struct Task *task;
int pri;
{
task->tc_State = TS_WAIT;
if ( ( ((struct Node *)task)->ln_Pri = pri ) == DISABLEDP )
if ( !chicken )
task->tc_State = TS_REMOVED;
}
typestatus()
{
register int i;
for ( i = 0; i < ND; i++ )
{
if ( !drive[i] )
continue;
if ( tnode[i] )
{
statusokmsg[8] = i + 48;
if ( tnode[i]->ln_Pri == DISABLEDP )
{
statusokmsg[21] = 'f';
statusokmsg[22] = 'f';
}
else
{
statusokmsg[21] = 'n';
statusokmsg[22] = ' ';
}
if ( fnode[i]->ln_Pri == DISABLEDP )
{
statusokmsg[37] = 'f';
statusokmsg[38] = 'f';
}
else
{
statusokmsg[37] = 'n';
statusokmsg[38] = ' ';
}
puts( statusokmsg );
}
else
if ( !statusonly )
{
statusermsg[8] = i + 48;
puts( statusermsg );
}
} /* for i */
if ( FindTask( busyname ) )
puts( busytaskmsg );
} /* typestatus */
permexit( exitval ) /* all exits after Forbid() come here */
unsigned exitval;
{
SetTaskPri( me, previouspri ); /* otherwise the CLI or WB stays at -1 */
Permit(); /* SetTaskPri() reschedules Forbidden tasks ?... */
exit( exitval );
}
addbusytask() /* starts a busyloop task at priority -122 */
{
char *busycode;
if ( !( busycode = AllocMem( 32L, MEMF_CLEAR ) ) )
{
puts( memerrormsg );
permexit( 14 );
}
busycode[0] = 0x60; busycode[1] = 0xfe; /* kk: BRA kk */
CopyMemQuick( busyname, busycode + 2, 12L );
if ( !( busytask =
CreateTask( busycode + 2, (long)BUSYPRI, busycode, 128L ) ) )
{
FreeMem( busycode, 32L );
puts( memerrormsg );
permexit( 14 );
}
busytask->tc_UserData = (APTR)busycode;
}
rembusytask()
{
char *busycode;
busycode = (char *)busytask->tc_UserData;
DeleteTask( busytask );
FreeMem( busycode, 32L );
}
/* fin DisDF.c */