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 >
Wrap
C/C++ Source or Header
|
1991-03-07
|
8KB
|
288 lines
/* 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);
}