home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 488.lha / modengine_v1.0 / mod_dos.c < prev    next >
C/C++ Source or Header  |  1991-03-07  |  8KB  |  288 lines

  1. /* mod_dos.c
  2.  * Copyright (C) 1990 Commodore-Amiga, Inc.
  3.  * written by David N. Junod
  4.  *
  5.  * DOS command shell message handling routines
  6.  *
  7.  */
  8.  
  9. #include "mod.h"
  10.  
  11. /* variables required for a DOS shell */
  12. struct DOSInfo
  13. {
  14.     struct MsgPort *drport;    /* DOS reply port */
  15.     UBYTE *winspec;        /* Shell window spec */
  16.     UBYTE *closing_msg;        /* Closing message */
  17.     BPTR acons;            /* Console file handle */
  18.     struct StandardPacket *dmsg;/* DOS packet */
  19.     UBYTE aprompt[25];        /* prompt */
  20.     BOOL packet_out;        /* is a READ outstanding? */
  21.     UBYTE buff[BUFFLEN + 1];    /* used for reading user input */
  22.     struct Process *atask;    /* Our own process structure */
  23.     BPTR old_CIS;        /* Orig. console input stream */
  24.     BPTR old_COS;        /* Orig. console output stream */
  25.     APTR old_ConsoleTask;    /* Orig. console task */
  26.     SHORT dstatus;        /* The current status of the shell */
  27. };
  28.  
  29. /* DOS message handling routines */
  30. BOOL open_dos (struct AppInfo *, struct MsgHandler *mh);
  31. BOOL handle_dos (struct AppInfo *, struct MsgHandler *mh);
  32. BOOL close_dos (struct AppInfo *, struct MsgHandler *mh);
  33. BOOL shutdown_dos (struct AppInfo *, struct MsgHandler *mh);
  34. VOID DisplayPrompt ( struct MsgHandler *mh );
  35. struct StandardPacket *setup_dos_message ( void );
  36. VOID send_read_packet (struct StandardPacket *,BPTR,struct MsgPort *, UBYTE *);
  37.  
  38. struct MsgHandler *setup_dos (struct AppInfo * ai,
  39.                   UBYTE * winspec, UBYTE * prompt, UBYTE * close,
  40.                   BOOL immed)
  41. {
  42.     struct MsgHandler *mh = NULL;
  43.     struct DOSInfo *md = NULL;
  44.  
  45.     if (md = (struct DOSInfo *)
  46.     AllocMem (sizeof (struct DOSInfo), MEMF_CLEAR|MEMF_PUBLIC))
  47.     {
  48.     /* initialize data */
  49.     md->closing_msg = close;
  50.     md->winspec = winspec;
  51.     strcpy (md->aprompt, prompt);
  52.  
  53.     /* get the current process information */
  54.     md->atask = (struct Process *) FindTask (0);
  55.  
  56.     /* make backups of the default task information */
  57.     md->old_CIS = md->atask->pr_CIS;
  58.     md->old_COS = md->atask->pr_COS;
  59.     md->old_ConsoleTask = md->atask->pr_ConsoleTask;
  60.     md->packet_out = FALSE;
  61.  
  62.     /* Mark shell window as being closed */
  63.     md->dstatus = AS_CLOSED;
  64.  
  65.     /* set up a port for DOS replys */
  66.     if (md->drport = CreatePort (NULL, 0L))
  67.     {
  68.         /* set up a DOS packet for the asynchronous read from the window */
  69.         if (md->dmsg = setup_dos_message ())
  70.         {
  71.         mh = (struct MsgHandler *)
  72.             AllocMem (sizeof (struct MsgHandler), MEMF_CLEAR|MEMF_PUBLIC);
  73.         if (mh)
  74.         {
  75.             mh->mh_Node.ln_Type = MH_HANDLER_T;
  76.             mh->mh_Node.ln_Pri  = MH_HANDLER_P;
  77.             mh->mh_Node.ln_Name = "DOS";
  78.             mh->mh_SigBits = (1L << md->drport->mp_SigBit);
  79.             mh->mh_Func[MH_OPEN] = open_dos;
  80.             mh->mh_Func[MH_HANDLE] = handle_dos;
  81.             mh->mh_Func[MH_CLOSE] = close_dos;
  82.             mh->mh_Func[MH_SHUTDOWN] = shutdown_dos;
  83.             mh->mh_Data = md;
  84.  
  85.             /* open immediately? */
  86.             if (immed)
  87.             {
  88.             if (open_dos (ai, mh))
  89.                 return (mh);
  90.             }
  91.             else
  92.             return (mh);
  93.  
  94.             FreeMem (mh, sizeof (struct MsgHandler));
  95.         }
  96.         else
  97.             NotifyUser (NULL, "Not enough memory");
  98.  
  99.         FreeMem (md->dmsg, sizeof (struct StandardPacket));
  100.         md->dmsg = NULL;
  101.         }
  102.         DeletePort (md->drport);
  103.         md->drport = NULL;
  104.     }
  105.     FreeMem (md, sizeof (struct DOSInfo));
  106.     }
  107.     return (mh);
  108. }
  109.  
  110. BOOL open_dos (struct AppInfo * ai, struct MsgHandler * mh)
  111. {
  112.     struct DOSInfo *md = mh->mh_Data;
  113.     struct FileHandle *handle;
  114.  
  115.     if (!md->acons)
  116.     {
  117.     if (md->acons = Open (md->winspec, MODE_NEWFILE))
  118.     {
  119.         /* Set the standard input/output to this console window */
  120.         md->atask->pr_CIS = md->acons;
  121.         md->atask->pr_COS = md->acons;
  122.  
  123.         /* Convert the BPTR to a C pointer */
  124.         handle = (struct FileHandle *) (md->acons << 2);
  125.  
  126.         /* Set the console task in case they open a window off ours */
  127.         md->atask->pr_ConsoleTask = (APTR) handle->fh_Type;
  128.  
  129.         /* Display the prompt */
  130.         DisplayPrompt (mh);
  131.         md->dstatus = AS_OPEN;
  132.  
  133.         /* send a packet out for user input */
  134.         if (!md->packet_out)
  135.         {
  136.         /* send a packet to DOS asking for user keyboard input */
  137.         send_read_packet (md->dmsg, md->acons, md->drport, md->buff);
  138.         md->packet_out = TRUE;
  139.         }
  140.  
  141.     }
  142.     }
  143.     return ((BOOL) ((md->acons) ? TRUE : FALSE));
  144. }
  145.  
  146. /* handle DOS messages */
  147. BOOL handle_dos (struct AppInfo * ai, struct MsgHandler * mh)
  148. {
  149.     struct DOSInfo *md = mh->mh_Data;
  150.  
  151.     if (GetMsg (md->drport))
  152.     {
  153.     /* not out any more */
  154.     md->packet_out = FALSE;
  155.  
  156.     /* If the shell CLOSE gadget was hit, or ^\ */
  157.     if (md->dmsg->sp_Pkt.dp_Res1 == 0)
  158.     {
  159.         md->dstatus = AS_GOING;
  160.     }
  161.     else
  162.     {
  163.         md->buff[md->dmsg->sp_Pkt.dp_Res1 - 1] = 0;
  164.  
  165.         if (strlen (md->buff) > 0)
  166.         {
  167.         /* perform the function */
  168.         PerfFunc (ai, NULL, md->buff);
  169.  
  170.         /* display the prompt */
  171.         DisplayPrompt (mh);
  172.         }
  173.         else
  174.         /* they entered a blank line, let's end the shell */
  175.         md->dstatus = AS_GOING;
  176.     }
  177.     /* send out a packet for user input */
  178.     if (!md->packet_out && md->dstatus >= AS_OPEN)
  179.     {
  180.         /* send a packet to DOS asking for user keyboard input */
  181.         send_read_packet (md->dmsg, md->acons, md->drport, md->buff);
  182.         md->packet_out = TRUE;
  183.     }
  184.     close_dos (ai, mh);
  185.     }
  186.     return (TRUE);
  187. }
  188.  
  189. BOOL close_dos (struct AppInfo * ai, struct MsgHandler * mh)
  190. {
  191.     struct DOSInfo *md = mh->mh_Data;
  192.  
  193.     if (md->dstatus == AS_GOING)
  194.     {
  195.     /* User has indicated that he wants to close the command shell. */
  196.     md->dstatus = AS_CLOSING;
  197.     Write (md->acons, md->closing_msg, (LONG) strlen (md->closing_msg));
  198.     }
  199.  
  200.     if (md->dstatus == AS_CLOSING && !ai->numcmds)
  201.     {
  202.     if (md->acons)
  203.     {
  204.         /* safely restore the default information */
  205.         md->atask->pr_CIS = md->old_CIS;
  206.         md->atask->pr_COS = md->old_COS;
  207.         md->atask->pr_ConsoleTask = md->old_ConsoleTask;
  208.  
  209.         /* close the console window */
  210.         Close (md->acons);
  211.     }
  212.  
  213.     md->dstatus = AS_CLOSED;
  214.     md->acons = NULL;
  215.     }
  216.     return ((BOOL) ((md->acons) ? TRUE : FALSE));
  217. }
  218.  
  219. BOOL shutdown_dos (struct AppInfo * ai, struct MsgHandler * mh)
  220. {
  221.     struct DOSInfo *md = mh->mh_Data;
  222.  
  223.     if (mh)
  224.     {
  225.     if (md)
  226.     {
  227.         if (md->acons)
  228.         md->dstatus = AS_GOING;
  229.         close_dos (ai, mh);
  230.  
  231.         if (md->drport)
  232.         DeletePort (md->drport);
  233.  
  234.         if (md->dmsg)
  235.         FreeMem (md->dmsg, sizeof (struct StandardPacket));
  236.     }
  237.  
  238.     Remove ((struct Node *) mh);
  239.     FreeMem (mh, sizeof (struct MsgHandler));
  240.     }
  241.  
  242.     return (TRUE);
  243. }
  244.  
  245. VOID DisplayPrompt (struct MsgHandler * mh)
  246. {
  247.     struct DOSInfo *md = mh->mh_Data;
  248.  
  249.     Write (md->acons, md->aprompt, (LONG) strlen (md->aprompt));
  250. }
  251.  
  252. struct StandardPacket *setup_dos_message ()
  253. {
  254.     struct StandardPacket *new_packet;
  255.  
  256.     /* get a packet */
  257.     if (new_packet = (struct StandardPacket *)
  258.     AllocMem (sizeof (struct StandardPacket), MEMF_CLEAR|MEMF_PUBLIC))
  259.     {
  260.     new_packet->sp_Msg.mn_Node.ln_Name =
  261.       (UBYTE *) & (new_packet->sp_Pkt);
  262.     new_packet->sp_Pkt.dp_Link = &(new_packet->sp_Msg);
  263.     }
  264.     return (new_packet);
  265. }
  266.  
  267. VOID send_read_packet (struct StandardPacket * dos_message,
  268.                 BPTR console_fh,
  269.                 struct MsgPort * dos_reply_port,
  270.                 UBYTE * buff)
  271. {
  272.     struct FileHandle *file_handle;
  273.  
  274.     /* change a BPTR to a REAL pointer */
  275.     file_handle = (struct FileHandle *) (console_fh << 2);
  276.  
  277.     /* setup the packet for reading */
  278.     dos_message->sp_Pkt.dp_Arg1 = file_handle->fh_Arg1;
  279.     dos_message->sp_Pkt.dp_Arg2 = (LONG) buff;
  280.     dos_message->sp_Pkt.dp_Arg3 = BUFFLEN;
  281.     dos_message->sp_Pkt.dp_Type = ACTION_READ;
  282.     dos_message->sp_Pkt.dp_Port = dos_reply_port;
  283.     dos_message->sp_Msg.mn_ReplyPort = dos_reply_port;
  284.  
  285.     /* now send it */
  286.     PutMsg (file_handle->fh_Type, (struct Message *) dos_message);
  287. }
  288.