home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / EDGE1_704.DMS / in.adf / ExtraStuff / Edge_SasC.lha / echohandler / EchoHandler.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-03  |  4.7 KB  |  204 lines

  1. /* Echo Handler V1.2
  2. ** ©1991 Henrik Nordström
  3. ** Ängsvägen 1
  4. ** 756 45 Uppsala
  5. ** Sweden
  6. **
  7. ** Fully public domain, and truly a real hack...
  8. ** Use it in any way you like, but don't blame me if it doesn't work.
  9. ** This little code needs AmigaDOS 2.0-> to work without modification
  10. ** if you like, write your own packet-handling functions and compile it
  11. ** to work whith 1.1->
  12. ** functions needed in 2.0 is: WaitPkt, and ReplyPkt
  13. **
  14. ** Example for use:
  15. ** .>dir >ECHO:dirdump ram: all
  16. ** .>list >ECHO:ram:listdump dh0:
  17. **
  18. ** compiled with SAS/C 5.10b
  19. **
  20. ** lc -v -O EchoHandler.c
  21. ** blink EchoHandler.o
  22. ** copy EchoHandler L:
  23. **
  24. ** Mount list entry to use ECHO:
  25. ** ECHO:
  26. **     Handler = l:EchoHandler
  27. **     Stacksize = 3000
  28. **     Priority = 5
  29. **     GlobVec = -1
  30. ** #
  31. **
  32. */
  33.  
  34. #include <string.h>
  35.  
  36. #include <dos/dos.h>
  37. #include <dos/dosextens.h>
  38. #include <dos/filehandler.h>
  39.  
  40. #include <proto/exec.h>
  41. #include <proto/dos.h>
  42.  
  43. struct Library *SysBase;
  44. struct DosLibrary *DOSBase;
  45.  
  46. struct filedata
  47. {
  48.   BPTR confh;
  49.   BPTR filefh;
  50. };
  51.  
  52. void __saveds
  53. start (void)
  54. {
  55.   struct DosPacket *pkt;
  56.   struct DeviceNode *node;
  57.   struct Process *myproc;
  58.   struct Process *theirproc;
  59.   struct MsgPort *myport;
  60.   struct FileHandle *fh;
  61.   struct filedata *fd;
  62.   int die = FALSE;
  63.   LONG type;
  64.   LONG arg1;
  65.   LONG arg2;
  66.   LONG arg3;
  67.   int opencount = 0;
  68.   char *name;
  69.   BPTR confh;
  70.   BPTR filefh;
  71.   char *data;
  72.   int len;
  73.   BPTR oldcurrentdir;
  74.   LONG filemode;
  75.   LONG filepos;
  76.   
  77.   SysBase = *((struct Library **) 4L);
  78.   myproc = (struct Process *) FindTask (NULL);
  79.   myport = &myproc->pr_MsgPort;
  80.  
  81.   DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 36);
  82.   if (DOSBase == NULL)
  83.     return;
  84.  
  85.   pkt = WaitPkt ();
  86.   node = BADDR (pkt->dp_Arg3);
  87.  
  88.   /*
  89.    * Install process if everything OK and stay resident forever! * (or
  90.    * until killed whith ACTION_DIE) )
  91.    */
  92.   node->dn_Task = myport;
  93.   ReplyPkt (pkt, DOSTRUE, pkt->dp_Arg2);
  94.  
  95.   do
  96.     {
  97.       pkt = WaitPkt ();
  98.       type = pkt->dp_Type;
  99.       arg1 = pkt->dp_Arg1;
  100.       arg2 = pkt->dp_Arg2;
  101.       arg3 = pkt->dp_Arg3;
  102.       fd = (struct filedata *) arg1;
  103.       switch (type)
  104.     {
  105.     case ACTION_FINDINPUT:
  106.       filemode=MODE_OLDFILE;
  107.       goto OPEN_FILE;
  108.     case ACTION_FINDOUTPUT:
  109.       filemode=MODE_NEWFILE;
  110.       goto OPEN_FILE;
  111.     case ACTION_FINDUPDATE:
  112.       filemode=MODE_READWRITE;
  113.       goto OPEN_FILE;
  114.     OPEN_FILE:
  115.       fh = (struct FileHandle *) BADDR (arg1);
  116.       name = (char *) BADDR (arg3) + 1;
  117.       /* Strip ECHO: from filename */
  118.       while (*name && *name != ':')
  119.         name++;
  120.       if (*name == ':')
  121.         name++;
  122.  
  123.       /*
  124.        * Find the two output streams
  125.        *  1: current output of calling process
  126.        *  2: filename relative to calling process CurrentDir
  127.        */
  128.       theirproc = (struct Process *) pkt->dp_Port->mp_SigTask;
  129.       oldcurrentdir = CurrentDir (theirproc->pr_CurrentDir);
  130.       if(theirproc->pr_CLI)
  131.         confh = ((struct CommandLineInterface *)BADDR(theirproc->pr_CLI))->cli_CurrentOutput;
  132.       else
  133.         confh = theirproc->pr_COS;
  134.       filefh = Open (name, filemode);
  135.       CurrentDir (oldcurrentdir);
  136.       if (!filefh)
  137.         {
  138.           ReplyPkt (pkt, DOSFALSE, IoErr ());
  139.           break;
  140.         }
  141.       fd = (struct filedata *) AllocMem (sizeof (*fd), 0);
  142.       if (fd == NULL)
  143.         {
  144.           Close (filefh);
  145.           ReplyPkt (pkt, DOSFALSE, ERROR_NO_FREE_STORE);
  146.           break;
  147.         }
  148.       /* Everything OK! fill in datastructure and reply. */
  149.       fd->confh = confh;
  150.       fd->filefh = filefh;
  151.       /* real strange names in 2.02... probably better names in include 2.04 */
  152.       fh->fh_Port = (struct MsgPort *)(-1L); /* Interactive */
  153.       fh->fh_Type = myport;  /* Message port */
  154.       fh->fh_Arg1 = (LONG) fd; /* File data, passed as ARG1 to all functions */
  155.       ReplyPkt (pkt, DOSTRUE, 0);
  156.       opencount++;
  157.       break;
  158.     case ACTION_WRITE:
  159.       data = (char *) arg2;
  160.       len = arg3;
  161.       if (fd->confh)
  162.         Write (fd->confh, data, len);
  163.       if (fd->filefh)
  164.         Write (fd->filefh, data, len);
  165.       ReplyPkt (pkt, len, 0);
  166.       break;
  167.     case ACTION_READ:
  168.       data = (char *) arg2;
  169.       len = arg3;
  170.       if (fd->filefh)
  171.         len=Read (fd->filefh, data, len);
  172.       if(len<0)
  173.         ReplyPkt(pkt, len, IoErr());
  174.       if (fd->filefh && len>0)
  175.         Write (fd->confh, data, len);
  176.       ReplyPkt (pkt, len, 0);
  177.       break;
  178.     case ACTION_SEEK:
  179.       filepos=Seek(fd->filefh,arg2,arg3);
  180.       ReplyPkt(pkt,filepos,IoErr());
  181.       break;
  182.     case ACTION_END:
  183.       if (fd->filefh)
  184.         Close (fd->filefh);
  185.       FreeMem ((APTR) fd, sizeof (*fd));
  186.       ReplyPkt (pkt, DOSTRUE, 0);
  187.       opencount--;
  188.       break;
  189.     case ACTION_DIE:
  190.       /* Action_KillHandler */
  191.       die = TRUE;
  192.       node->dn_Task = NULL;
  193.       ReplyPkt (pkt, DOSTRUE, 0);
  194.       break;
  195.     default:
  196.       /* Action_CantHandleThis B-( */
  197.       ReplyPkt (pkt, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
  198.       break;
  199.     }
  200.   } while (!die || opencount > 0);
  201.  
  202.   CloseLibrary ((struct Library *) DOSBase);
  203. }
  204.