home *** CD-ROM | disk | FTP | other *** search
- /* monproc.c - monitor amigados process packet activity.
- *
- * Phillip Lindsay (c) 1987 Commodore-Amiga, Inc.
- *
- */
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/tasks.h>
- #include <exec/semaphores.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/filehandler.h>
-
- #ifdef MANX
- #include <functions.h>
- #else
- #define index stpchr /* can you say "ANSI STANDARD"...I knew you could... */
- #endif
- #include <stdio.h>
-
- /* constants */
-
- #define ONE 1L
-
- /* AmigaDOS uses task signal bit 8 for message signaling */
- #define DOS_SIGNAL 8
- #define DOS_MASK ( ONE << DOS_SIGNAL )
-
- /* referenced globals */
- extern void getprocs(),freeprocs(),givepkt();
- void memfill();
- extern struct DosLibrary *DOSBase;
- struct Message *packetwait();
- LONG pw(); /* this the asm stub that calls packetwait() */
-
- /* global data structures */
- struct MsgPort *deviceid;
- struct Process *memyselfNi;
- ULONG mymask;
- struct SignalSemaphore canreturn;
- struct Message *mymess;
-
-
- main()
- {
- struct List procs;
- struct Node *proc;
- register struct Process *devproc;
- register struct DosPacket *pkt;
- BYTE mypri;
- register ULONG waitmask,signals,oldpktwait;
- LONG mysignal;
- ULONG count,choice;
- UBYTE processname[81];
-
- puts("MONPROC - monitor AmigaDOS process packet activity.\n");
-
- memyselfNi = (struct Process *) FindTask(NULL);
- NewList(&procs); /* initialize list header */
- getprocs(&procs); /* fill list with "active" devices */
-
- if(procs.lh_TailPred == &procs) /* list empty (should never happen) */
- {
- puts("No processes.");
- exit(0);
- }
-
- /*
- * I am assuming that process list won't change. This is for hackers only.
- */
- do
- {
- puts("Enter NUMBER for process to monitor:");
- puts("Pick# Process MsgPort Name");
- for(count = 1,proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ,count++)
- printf("%4ld. %08lx %08lx %s\n",count,
- ((struct Process *)proc->ln_Name),
- &(((struct Process *)proc->ln_Name)->pr_MsgPort),
- ((struct Process *)proc->ln_Name)->pr_Task.tc_Node.ln_Name);
- printf("\nNUMBER: ");
- fflush(stdout);
- } while( scanf("%ld",&choice) == EOF ) ;
-
-
- if(!choice || choice >= count)
- {
- puts("Operation aborted.");
- freeprocs(&procs);
- exit(0);
- }
-
- /* what did he/she pick? */
- for(count = 1,proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ,count++)
- if(choice == count)
- {
- devproc = (struct Process *) proc->ln_Name;
- break;
- }
-
- /* we don't need our process list anymore */
- freeprocs(&procs);
-
- /* make a copy of the process name */
- strcpy(processname,devproc->pr_Task.tc_Node.ln_Name);
-
- /* get process msgport of process we will be monitoring */
- deviceid = &devproc->pr_MsgPort;
-
- /* grab a signal for task intercommunication */
- mysignal = (LONG) AllocSignal(-1L);
- if(mysignal == -1)
- {
- puts("Can't allocate a task signal.");
- exit(0);
- }
-
- mymask = ONE << mysignal;
-
- waitmask = SIGBREAKF_CTRL_C | mymask;
-
- /* initialize our semaphore */
- memfill(&canreturn,(ULONG)sizeof(canreturn),0L);
- InitSemaphore(&canreturn);
-
- Forbid();
- mypri = devproc->pr_Task.tc_Node.ln_Pri;
- Permit();
-
- /* make sure our priority is greater than the device task */
- SetTaskPri(memyselfNi, (ULONG)(mypri+1) );
-
- puts("Waiting for messages...[CTRL_C to quit monitoring...]");
-
- /* install our packet wait function */
- Forbid();
- oldpktwait = (ULONG) devproc->pr_PktWait;
- devproc->pr_PktWait = (APTR) pw;
- Permit();
-
- /*
- * I am using semaphores to control the monitoring of the handler's packets.
- * There is probably a hundred better ways of doing this. I just went with
- * what first came to mind. Since I am a higher priority than the handler...
- * Once I am awake I will obtain the semaphore before the lower priority
- * task has a chance...I will give it back to him once I am done with the
- * packet data structure.
- */
- do
- {
-
- signals = (ULONG) Wait(waitmask);
- ObtainSemaphore(&canreturn);
-
- if(signals & mymask) /* did the packetwait code signal us? */
- { /* yes, let's boogie... */
- pkt = (struct DosPacket *) mymess->mn_Node.ln_Name; /* get packet address */
- printf("%s: ",processname);
- givepkt(pkt);
- }
-
- ReleaseSemaphore(&canreturn);
-
- } while(!(signals & SIGBREAKF_CTRL_C));
-
- /* remove our packet wait function and install previous value */
- Forbid();
- devproc->pr_PktWait = (APTR) oldpktwait;
- Permit();
- SetTaskPri(memyselfNi,0L);
- puts("\nThere is no safe way to leave since the process is waiting in");
- puts("our installed code. We have de-installed ourselves, but you should");
- puts("be certain that the process received a packet AFTER we have been");
- puts("de-installed. Press CTRL-E if you are certain this has happened.");
- Wait(SIGBREAKF_CTRL_E);
- FreeSignal(mysignal);
- puts("All done.");
-
- } /* end of main() */
-
-
- /**
- ** local subroutines
- **/
-
- /*
- * packetwait() ... Waits for a message to arrive at your port and
- * returns it to you.
- */
- struct Message *packetwait()
- {
- #ifdef MANX /* if MANX make sure we can see our data */
- geta4();
- #endif
- /* wait for packet */
- SetSignal(FALSE,DOS_MASK); /* clear sigbit 8 */
- while( !(mymess = (struct Message *) GetMsg(deviceid)) ) Wait(DOS_MASK);
- Signal(memyselfNi,mymask); /* Wake up monitoring task he will grab the data */
- ObtainSemaphore(&canreturn); /* we get this guy when we CAN return */
- ReleaseSemaphore(&canreturn);
-
- return(mymess);
- }
-
- /*
- * memfill() - fill memory with supplied byte value for "size" bytes
- */
- void memfill(source,size,value)
- UBYTE *source;
- ULONG size;
- UBYTE value;
- {
- register UBYTE *msource=source,
- mvalue=value;
- register ULONG msize=size;
-
- if(msize)
- {
- do
- {
- --msize;
- msource[msize] = mvalue;
- } while(msize);
-
- }
- }
-
- /*
- * This code stub has been known to save lives...
- */
-
- #if MANX
- #asm
- XREF _packetwait
-
- XDEF _pw
- _pw:
- movem.l a2/a3/a4,-(sp)
- jsr _packetwait
- movem.l (sp)+,a2/a3/a4
- rts
- #endasm
- #endif
-
- /* end of procdev.c */
-