home *** CD-ROM | disk | FTP | other *** search
- /* Echo Handler V1.2
- ** ©1991 Henrik Nordström
- ** Ängsvägen 1
- ** 756 45 Uppsala
- ** Sweden
- **
- ** Fully public domain, and truly a real hack...
- ** Use it in any way you like, but don't blame me if it doesn't work.
- ** This little code needs AmigaDOS 2.0-> to work without modification
- ** if you like, write your own packet-handling functions and compile it
- ** to work whith 1.1->
- ** functions needed in 2.0 is: WaitPkt, and ReplyPkt
- **
- ** Example for use:
- ** .>dir >ECHO:dirdump ram: all
- ** .>list >ECHO:ram:listdump dh0:
- **
- ** compiled with SAS/C 5.10b
- **
- ** lc -v -O EchoHandler.c
- ** blink EchoHandler.o
- ** copy EchoHandler L:
- **
- ** Mount list entry to use ECHO:
- ** ECHO:
- ** Handler = l:EchoHandler
- ** Stacksize = 3000
- ** Priority = 5
- ** GlobVec = -1
- ** #
- **
- */
-
- #include <string.h>
-
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/filehandler.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- struct Library *SysBase;
- struct DosLibrary *DOSBase;
-
- struct filedata
- {
- BPTR confh;
- BPTR filefh;
- };
-
- void __saveds
- start (void)
- {
- struct DosPacket *pkt;
- struct DeviceNode *node;
- struct Process *myproc;
- struct Process *theirproc;
- struct MsgPort *myport;
- struct FileHandle *fh;
- struct filedata *fd;
- int die = FALSE;
- LONG type;
- LONG arg1;
- LONG arg2;
- LONG arg3;
- int opencount = 0;
- char *name;
- BPTR confh;
- BPTR filefh;
- char *data;
- int len;
- BPTR oldcurrentdir;
- LONG filemode;
- LONG filepos;
-
- SysBase = *((struct Library **) 4L);
- myproc = (struct Process *) FindTask (NULL);
- myport = &myproc->pr_MsgPort;
-
- DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 36);
- if (DOSBase == NULL)
- return;
-
- pkt = WaitPkt ();
- node = BADDR (pkt->dp_Arg3);
-
- /*
- * Install process if everything OK and stay resident forever! * (or
- * until killed whith ACTION_DIE) )
- */
- node->dn_Task = myport;
- ReplyPkt (pkt, DOSTRUE, pkt->dp_Arg2);
-
- do
- {
- pkt = WaitPkt ();
- type = pkt->dp_Type;
- arg1 = pkt->dp_Arg1;
- arg2 = pkt->dp_Arg2;
- arg3 = pkt->dp_Arg3;
- fd = (struct filedata *) arg1;
- switch (type)
- {
- case ACTION_FINDINPUT:
- filemode=MODE_OLDFILE;
- goto OPEN_FILE;
- case ACTION_FINDOUTPUT:
- filemode=MODE_NEWFILE;
- goto OPEN_FILE;
- case ACTION_FINDUPDATE:
- filemode=MODE_READWRITE;
- goto OPEN_FILE;
- OPEN_FILE:
- fh = (struct FileHandle *) BADDR (arg1);
- name = (char *) BADDR (arg3) + 1;
- /* Strip ECHO: from filename */
- while (*name && *name != ':')
- name++;
- if (*name == ':')
- name++;
-
- /*
- * Find the two output streams
- * 1: current output of calling process
- * 2: filename relative to calling process CurrentDir
- */
- theirproc = (struct Process *) pkt->dp_Port->mp_SigTask;
- oldcurrentdir = CurrentDir (theirproc->pr_CurrentDir);
- if(theirproc->pr_CLI)
- confh = ((struct CommandLineInterface *)BADDR(theirproc->pr_CLI))->cli_CurrentOutput;
- else
- confh = theirproc->pr_COS;
- filefh = Open (name, filemode);
- CurrentDir (oldcurrentdir);
- if (!filefh)
- {
- ReplyPkt (pkt, DOSFALSE, IoErr ());
- break;
- }
- fd = (struct filedata *) AllocMem (sizeof (*fd), 0);
- if (fd == NULL)
- {
- Close (filefh);
- ReplyPkt (pkt, DOSFALSE, ERROR_NO_FREE_STORE);
- break;
- }
- /* Everything OK! fill in datastructure and reply. */
- fd->confh = confh;
- fd->filefh = filefh;
- /* real strange names in 2.02... probably better names in include 2.04 */
- fh->fh_Port = (struct MsgPort *)(-1L); /* Interactive */
- fh->fh_Type = myport; /* Message port */
- fh->fh_Arg1 = (LONG) fd; /* File data, passed as ARG1 to all functions */
- ReplyPkt (pkt, DOSTRUE, 0);
- opencount++;
- break;
- case ACTION_WRITE:
- data = (char *) arg2;
- len = arg3;
- if (fd->confh)
- Write (fd->confh, data, len);
- if (fd->filefh)
- Write (fd->filefh, data, len);
- ReplyPkt (pkt, len, 0);
- break;
- case ACTION_READ:
- data = (char *) arg2;
- len = arg3;
- if (fd->filefh)
- len=Read (fd->filefh, data, len);
- if(len<0)
- ReplyPkt(pkt, len, IoErr());
- if (fd->filefh && len>0)
- Write (fd->confh, data, len);
- ReplyPkt (pkt, len, 0);
- break;
- case ACTION_SEEK:
- filepos=Seek(fd->filefh,arg2,arg3);
- ReplyPkt(pkt,filepos,IoErr());
- break;
- case ACTION_END:
- if (fd->filefh)
- Close (fd->filefh);
- FreeMem ((APTR) fd, sizeof (*fd));
- ReplyPkt (pkt, DOSTRUE, 0);
- opencount--;
- break;
- case ACTION_DIE:
- /* Action_KillHandler */
- die = TRUE;
- node->dn_Task = NULL;
- ReplyPkt (pkt, DOSTRUE, 0);
- break;
- default:
- /* Action_CantHandleThis B-( */
- ReplyPkt (pkt, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
- break;
- }
- } while (!die || opencount > 0);
-
- CloseLibrary ((struct Library *) DOSBase);
- }
-