home *** CD-ROM | disk | FTP | other *** search
- /* mod_dos.c
- * Copyright (C) 1990 Commodore-Amiga, Inc.
- * written by David N. Junod
- *
- * DOS command shell message handling routines
- *
- */
-
- #include "mod.h"
-
- /* variables required for a DOS shell */
- struct DOSInfo
- {
- struct MsgPort *drport; /* DOS reply port */
- UBYTE *winspec; /* Shell window spec */
- UBYTE *closing_msg; /* Closing message */
- BPTR acons; /* Console file handle */
- struct StandardPacket *dmsg;/* DOS packet */
- UBYTE aprompt[25]; /* prompt */
- BOOL packet_out; /* is a READ outstanding? */
- UBYTE buff[BUFFLEN + 1]; /* used for reading user input */
- struct Process *atask; /* Our own process structure */
- BPTR old_CIS; /* Orig. console input stream */
- BPTR old_COS; /* Orig. console output stream */
- APTR old_ConsoleTask; /* Orig. console task */
- SHORT dstatus; /* The current status of the shell */
- };
-
- /* DOS message handling routines */
- BOOL open_dos (struct AppInfo *, struct MsgHandler *mh);
- BOOL handle_dos (struct AppInfo *, struct MsgHandler *mh);
- BOOL close_dos (struct AppInfo *, struct MsgHandler *mh);
- BOOL shutdown_dos (struct AppInfo *, struct MsgHandler *mh);
- VOID DisplayPrompt ( struct MsgHandler *mh );
- struct StandardPacket *setup_dos_message ( void );
- VOID send_read_packet (struct StandardPacket *,BPTR,struct MsgPort *, UBYTE *);
-
- struct MsgHandler *setup_dos (struct AppInfo * ai,
- UBYTE * winspec, UBYTE * prompt, UBYTE * close,
- BOOL immed)
- {
- struct MsgHandler *mh = NULL;
- struct DOSInfo *md = NULL;
-
- if (md = (struct DOSInfo *)
- AllocMem (sizeof (struct DOSInfo), MEMF_CLEAR|MEMF_PUBLIC))
- {
- /* initialize data */
- md->closing_msg = close;
- md->winspec = winspec;
- strcpy (md->aprompt, prompt);
-
- /* get the current process information */
- md->atask = (struct Process *) FindTask (0);
-
- /* make backups of the default task information */
- md->old_CIS = md->atask->pr_CIS;
- md->old_COS = md->atask->pr_COS;
- md->old_ConsoleTask = md->atask->pr_ConsoleTask;
- md->packet_out = FALSE;
-
- /* Mark shell window as being closed */
- md->dstatus = AS_CLOSED;
-
- /* set up a port for DOS replys */
- if (md->drport = CreatePort (NULL, 0L))
- {
- /* set up a DOS packet for the asynchronous read from the window */
- if (md->dmsg = setup_dos_message ())
- {
- mh = (struct MsgHandler *)
- AllocMem (sizeof (struct MsgHandler), MEMF_CLEAR|MEMF_PUBLIC);
- if (mh)
- {
- mh->mh_Node.ln_Type = MH_HANDLER_T;
- mh->mh_Node.ln_Pri = MH_HANDLER_P;
- mh->mh_Node.ln_Name = "DOS";
- mh->mh_SigBits = (1L << md->drport->mp_SigBit);
- mh->mh_Func[MH_OPEN] = open_dos;
- mh->mh_Func[MH_HANDLE] = handle_dos;
- mh->mh_Func[MH_CLOSE] = close_dos;
- mh->mh_Func[MH_SHUTDOWN] = shutdown_dos;
- mh->mh_Data = md;
-
- /* open immediately? */
- if (immed)
- {
- if (open_dos (ai, mh))
- return (mh);
- }
- else
- return (mh);
-
- FreeMem (mh, sizeof (struct MsgHandler));
- }
- else
- NotifyUser (NULL, "Not enough memory");
-
- FreeMem (md->dmsg, sizeof (struct StandardPacket));
- md->dmsg = NULL;
- }
- DeletePort (md->drport);
- md->drport = NULL;
- }
- FreeMem (md, sizeof (struct DOSInfo));
- }
- return (mh);
- }
-
- BOOL open_dos (struct AppInfo * ai, struct MsgHandler * mh)
- {
- struct DOSInfo *md = mh->mh_Data;
- struct FileHandle *handle;
-
- if (!md->acons)
- {
- if (md->acons = Open (md->winspec, MODE_NEWFILE))
- {
- /* Set the standard input/output to this console window */
- md->atask->pr_CIS = md->acons;
- md->atask->pr_COS = md->acons;
-
- /* Convert the BPTR to a C pointer */
- handle = (struct FileHandle *) (md->acons << 2);
-
- /* Set the console task in case they open a window off ours */
- md->atask->pr_ConsoleTask = (APTR) handle->fh_Type;
-
- /* Display the prompt */
- DisplayPrompt (mh);
- md->dstatus = AS_OPEN;
-
- /* send a packet out for user input */
- if (!md->packet_out)
- {
- /* send a packet to DOS asking for user keyboard input */
- send_read_packet (md->dmsg, md->acons, md->drport, md->buff);
- md->packet_out = TRUE;
- }
-
- }
- }
- return ((BOOL) ((md->acons) ? TRUE : FALSE));
- }
-
- /* handle DOS messages */
- BOOL handle_dos (struct AppInfo * ai, struct MsgHandler * mh)
- {
- struct DOSInfo *md = mh->mh_Data;
-
- if (GetMsg (md->drport))
- {
- /* not out any more */
- md->packet_out = FALSE;
-
- /* If the shell CLOSE gadget was hit, or ^\ */
- if (md->dmsg->sp_Pkt.dp_Res1 == 0)
- {
- md->dstatus = AS_GOING;
- }
- else
- {
- md->buff[md->dmsg->sp_Pkt.dp_Res1 - 1] = 0;
-
- if (strlen (md->buff) > 0)
- {
- /* perform the function */
- PerfFunc (ai, NULL, md->buff);
-
- /* display the prompt */
- DisplayPrompt (mh);
- }
- else
- /* they entered a blank line, let's end the shell */
- md->dstatus = AS_GOING;
- }
- /* send out a packet for user input */
- if (!md->packet_out && md->dstatus >= AS_OPEN)
- {
- /* send a packet to DOS asking for user keyboard input */
- send_read_packet (md->dmsg, md->acons, md->drport, md->buff);
- md->packet_out = TRUE;
- }
- close_dos (ai, mh);
- }
- return (TRUE);
- }
-
- BOOL close_dos (struct AppInfo * ai, struct MsgHandler * mh)
- {
- struct DOSInfo *md = mh->mh_Data;
-
- if (md->dstatus == AS_GOING)
- {
- /* User has indicated that he wants to close the command shell. */
- md->dstatus = AS_CLOSING;
- Write (md->acons, md->closing_msg, (LONG) strlen (md->closing_msg));
- }
-
- if (md->dstatus == AS_CLOSING && !ai->numcmds)
- {
- if (md->acons)
- {
- /* safely restore the default information */
- md->atask->pr_CIS = md->old_CIS;
- md->atask->pr_COS = md->old_COS;
- md->atask->pr_ConsoleTask = md->old_ConsoleTask;
-
- /* close the console window */
- Close (md->acons);
- }
-
- md->dstatus = AS_CLOSED;
- md->acons = NULL;
- }
- return ((BOOL) ((md->acons) ? TRUE : FALSE));
- }
-
- BOOL shutdown_dos (struct AppInfo * ai, struct MsgHandler * mh)
- {
- struct DOSInfo *md = mh->mh_Data;
-
- if (mh)
- {
- if (md)
- {
- if (md->acons)
- md->dstatus = AS_GOING;
- close_dos (ai, mh);
-
- if (md->drport)
- DeletePort (md->drport);
-
- if (md->dmsg)
- FreeMem (md->dmsg, sizeof (struct StandardPacket));
- }
-
- Remove ((struct Node *) mh);
- FreeMem (mh, sizeof (struct MsgHandler));
- }
-
- return (TRUE);
- }
-
- VOID DisplayPrompt (struct MsgHandler * mh)
- {
- struct DOSInfo *md = mh->mh_Data;
-
- Write (md->acons, md->aprompt, (LONG) strlen (md->aprompt));
- }
-
- struct StandardPacket *setup_dos_message ()
- {
- struct StandardPacket *new_packet;
-
- /* get a packet */
- if (new_packet = (struct StandardPacket *)
- AllocMem (sizeof (struct StandardPacket), MEMF_CLEAR|MEMF_PUBLIC))
- {
- new_packet->sp_Msg.mn_Node.ln_Name =
- (UBYTE *) & (new_packet->sp_Pkt);
- new_packet->sp_Pkt.dp_Link = &(new_packet->sp_Msg);
- }
- return (new_packet);
- }
-
- VOID send_read_packet (struct StandardPacket * dos_message,
- BPTR console_fh,
- struct MsgPort * dos_reply_port,
- UBYTE * buff)
- {
- struct FileHandle *file_handle;
-
- /* change a BPTR to a REAL pointer */
- file_handle = (struct FileHandle *) (console_fh << 2);
-
- /* setup the packet for reading */
- dos_message->sp_Pkt.dp_Arg1 = file_handle->fh_Arg1;
- dos_message->sp_Pkt.dp_Arg2 = (LONG) buff;
- dos_message->sp_Pkt.dp_Arg3 = BUFFLEN;
- dos_message->sp_Pkt.dp_Type = ACTION_READ;
- dos_message->sp_Pkt.dp_Port = dos_reply_port;
- dos_message->sp_Msg.mn_ReplyPort = dos_reply_port;
-
- /* now send it */
- PutMsg (file_handle->fh_Type, (struct Message *) dos_message);
- }
-