Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

492 lines
15 KiB

/* cmd0.c - main loop for command processor
*
* HISTORY:
* 22-Mar-87 danl ShowHeap: use strFMTHEAP
* 13-Mar-87 danl ShowHeap: remove heapset
* 10-Mar-87 danl Add DISPLAYSTR
* 10-Mar-87 danl Add DoSend
* 09-Mar-87 danl Add DoRetain
* 09-Mar-87 danl DoScript: don't display password command
* 07-Feb-87 danl DoCommand - R -> reply all
* 31-Jan-87 danl DoCommand - for '.' and '*', apply mpInoteIdoc
* 09-Apr-1987 mz Use whiteskip/whitescan
* 11-Apr-1987 mz Use PASCAL/INTERNAL
* 04-May-1987 mz Fixed semantic bug
* 10-May-1987 mz Remove duplicate code
* 15-May-87 danl GOTOIDOC -> GOTOIDOCALL
* 15-May-87 danl DoScript: use pathopen
* 21-May-87 danl Remove ShowHeap, Add CheckDiskFree
* 26-May-87 danl add tolower to freespac call
* 01-Jun-87 danl PgUp ... beep if not empty cmd line
* 02-Jun-87 danl DoScript: if no explicit path, look local and then PATH
* 01-Jul-87 danl test idoc, inote against -1 not ERROR
* 05-Aug-87 danl Remove test for DoReply and 'R'
* 21-Aug-1987 mz Change references from MAXARG to MAXLINELEN
* 10-Sep-87 danl RIGHT, LEFT are ignored, no beeping
* 23-Mar-1988 mz Make ^C/^U/ESC all erase to beginning of line
* 19-Apr-1988 mz Add ! and CD command
* 12-Oct-1989 leefi v1.10.73, added NEWPASS command
*
*/
#define INCL_DOSINFOSEG
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include "wzport.h"
#include <tools.h>
#include <process.h>
#include "dh.h"
#include "zm.h"
extern UINT uLargestAlloc;
extern PSTR DOSReadMode;
#define FREETHRESHOLD 100000L
PSTR pCmd; /* pointer to end of command */
/*
** NOTE: order determines precedence
*/
struct CFT commands [ ] = {
{ "?", DoHelp, FALSE , F_HDRWIN },
{ "abort", DoExit, COMPABORT , F_COMPWIN },
{ "append", DoAppend, TRUE , F_COMPWIN },
{ "bug", DoBUG, FALSE , F_HDRWIN },
{ "compose", DoCompose, FALSE , F_HDRWIN },
{ "copy", DoCopyOrMove, COPYMSGS , F_HDRWIN },
{ "create", DoCreate, FALSE , F_HDRWIN },
{ "cd", DoChDir, FALSE , F_HDRWIN },
{ "delete", DoDelOrUndel, DELMSGS , F_HDRWIN },
{ "edit", DoEdit, FALSE , F_FOCUSWIN },
{ "expunge", DoExpunge, FALSE , F_HDRWIN },
{ "forward", DoForward, FALSE , F_HDRWIN },
{ "get", DoGet, FALSE , F_HDRWIN },
{ "headers", DoHeaders, FALSE , F_HDRWIN },
{ "help", DoHelp, FALSE , F_HDRWIN },
{ "move", DoCopyOrMove, MOVEMSGS , F_HDRWIN },
{ "mailinfo", DoMailInfo, TRUE , F_HDRWIN },
{ "msft", DoMSFT, TRUE , F_HDRWIN },
{ "newmail", DoNewMail, TRUE , F_HDRWIN },
{ "newpass", DoNewPass, FALSE , F_HDRWIN }, // leefi
{ "print", DoPrint, FALSE , F_HDRWIN },
{ "password", DoPassword, FALSE , F_HDRWIN },
{ "phone", DoPhone, FALSE , F_HDRWIN },
{ "quit", DoQuit, FALSE , F_HDRWIN },
{ "reply", DoReply, FALSE , F_HDRWIN },
{ "reset", DoSetOrReset, RESETFLAGS , F_HDRWIN },
{ "retain", DoRetain, FALSE , F_COMPWIN },
{ "send", DoSend, FALSE , F_HDRWIN },
{ "save", DoExit, COMPSAVE , F_COMPWIN },
{ "script", DoScript, FALSE , F_HDRWIN },
{ "set", DoSetOrReset, SETFLAGS , F_HDRWIN },
{ "shell", DoShell, FALSE , F_HDRWIN },
{ "show", DoShow, FALSE , F_HDRWIN },
{ "undelete", DoDelOrUndel, UNDELMSGS , F_HDRWIN },
{ "write", DoWrite, FALSE , F_HDRWIN },
{ "whois", DoWhoIs, FALSE , F_FOCUSWIN },
#if defined (HEAPCRAP)
{ "xheap", DoXHeap, FALSE , F_HDRWIN },
{ "xfree", DoXFree, FALSE , F_HDRWIN },
#endif
{ NULL, NULL, FALSE , F_HDRWIN }
};
/*
** DoScript - read a file and for each line in file call DoCommand
**
** Code for this command is in cmd0 because it accesses directly into
** commandline [ ]
**
*/
VOID PASCAL INTERNAL DoScript ( HW hWnd, PSTR p, INT operation )
{
FILE *fp = NULL;
CHAR buf[MAXPATHLEN];
operation;
if (*strbscan (p, "\\/"))
fp = fopen (p, DOSReadMode);
else
if ((fp = fopen (p, DOSReadMode)) == NULL) {
sprintf (commandLine, "$PATH:\\%s", p);
fp = pathopen (commandLine, buf, DOSReadMode);
}
if ( !fp )
SendMessage ( hWnd, DISPLAY, "Could not open script file.");
else {
while ( fgetl ( commandLine, MAXLINELEN, fp ) ) {
/*
** don't display password command
*/
if ( !strpre ( "pa", commandLine ) ) {
SendMessage ( hWnd, DISPPROMPT, FALSE );
SendMessage ( hWnd, DISPLAY, commandLine );
}
DoCommand ( hWnd );
}
fclose ( fp );
}
}
/*
** CheckDiskFree - checks to see if the amount of disk space on the
** current folder drive and temp drive are above the minimum. If
** not, a msg is displayed in the title bar of the command window.
**
** DiskFreeChange - used by CheckDiskFree to do the work common to both
** drives
*/
FLAG PASCAL INTERNAL DiskFreeChange (PSTR pstrDrive, PLONG plFree, PSTR pstrMsg )
{
LONG lFreeOld = *plFree;
*plFree = freespac ( tolower(pstrDrive[0]) - 0x60 );
if ( FREETHRESHOLD > *plFree ) {
strncat ( pstrMsg, pstrDrive, 2 );
strcat ( pstrMsg, strBLANK );
}
return ( *plFree > FREETHRESHOLD && FREETHRESHOLD > lFreeOld ) ||
( *plFree < FREETHRESHOLD && FREETHRESHOLD < lFreeOld ) ;
}
VOID PASCAL INTERNAL CheckDiskFree ( VOID )
{
PSTR buf = "** Disk space low on x: x: ** ";
static LONG lFreeCurFld = 0L;
static LONG lFreeTmpDrv = 0L;
FLAG fNewMsg = FALSE;
buf[21] = '\0';
fNewMsg |= DiskFreeChange ( mboxName, &lFreeCurFld, buf );
if ( *mboxName != *strTmpDrv )
fNewMsg |= DiskFreeChange ( strTmpDrv, &lFreeTmpDrv, buf );
if ( fNewMsg ) {
strcat ( buf, "** " );
SendMessage ( hCommand, DISPTITLE, (buf[24] ? buf : strEMPTY ) );
if ( buf[24] )
SendMessage ( hCommand, DISPLAY, buf );
}
}
/* DoCommand - execute command found in commandLine.
*
* The message selection list is parsed by MsgList.
*
* hWnd is the window of interest
*/
VOID PASCAL INTERNAL DoCommand ( HW hWnd )
{
PSTR p = NULL;
PSTR p1 = NULL;
INT i;
if ( fComposeOnBoot ) {
fComposeOnBoot = FALSE;
DoCompose ( hWnd, pstrDirectComp, 0 );
SendMessage ( hWnd, DISPPROMPT, TRUE );
return;
}
CheckDiskFree ( );
p = whiteskip ( commandLine );
/* If line indicates shell escape
*/
if (*p == '!')
DoShell (hWnd, whiteskip (p + 1), 0);
else
/* if line is simple number or special message indicator
*/
if (*strbskip (p, "0123456789") == '\0' ||
!strcmps (p, "*") || !strcmps (p, ".") || !strcmp (p, "$")) {
switch (*p) {
case '*':
i = mpInoteIdoc[inoteLast];
break;
case '$':
i = idocLast;
break;
case '.':
i = mpInoteIdoc[inoteBold];
break;
default:
i = atoi (p) - 1;
}
if (ReadMessage (i))
SendMessage (hHeaders, GOTOIDOCALL, i);
else
SendMessage (hWnd, DISPLAY, "Unable to read that message.");
}
else {
/* parse off <command><whitespace><args>
*/
p1 = whitescan ( p );
if ( *p1 != '\0' )
*p1++ = '\0';
p1 = whiteskip ( p1 );
/* resolves ambiguous commands in favor of precedence ordering
*/
for (i = 0; commands[i].cmd != NULL; i++)
if (strpre (p, commands[i].cmd))
break;
if ( commands [ i ].cmd != NULL ) {
if ( commands [ i ].fWin == F_COMPWIN && !hCompose )
SendMessage (hWnd, DISPLAY,
"There is no compose window for this command." );
else
( *commands [ i ].func ) ( hWnd, p1, commands [ i ].data );
}
else
SendMessage (hWnd, DISPLAY, "No matching command found");
}
CheckDiskFree ( );
}
/* CommandChar - process character input in the command window.
*
* CommandChar receives all character input and is responsible for:
*
* o Passing page-scrolling messages to the header window.
* No tricks are used here.
*
* o Text echoing of command-line commands.
* This involves processing DEL/BACKSPACE, ^W (for deleting prior words)
* and ^U (for deleting entire lines).
*
* o Handing completed lines to the command parser.
*
* hWnd window that received the character
* c char that was just input
*/
VOID PASCAL INTERNAL CommandChar ( HW hWnd, INT c )
{
INT width = TWINWIDTH ( hWnd );
IDOC idoc;
if ( fComposeOnBoot ) {
DoCommand ( hWnd );
return;
}
switch (c) {
case CTRL_D:
case CTRL_U:
if ( hCompose ) {
SetScrnSt ( c == CTRL_U ? BIGHEADERS : BIGCOMPOSE );
break;
}
if (c == CTRL_D)
break;
/* Fall through for ^U
*/
case CTRL_C :
case ESC:
while (pCmd > commandLine)
SendMessage (hWnd, KEY, BACKSPACE);
break;
case SHIFT_TAB:
hFocus = ( hFocus == hHeaders && hCompose ? hCompose : hHeaders );
SendMessage ( hWnd, DISPPROMPT, TRUE );
break;
case CTRL_T:
case CTRL_B:
case CTRL_K:
case CTRL_L:
case HOME:
case END:
case PGUP:
case PGDN:
if ( hFocus == hCompose )
SendMessage ( hCompose, KEY, c );
else
if ( hFocus == hHeaders ) {
if ( pCmd != commandLine )
Bell ();
else
if ( idocLast != -1 )
SendMessage ( hHeaders, KEY, c );
}
break;
/* CTRLENTER is special. It is allowed while there is a command being
* input. Its function is merely to read the first unread message.
*/
case CTRLENTER:
/* disallow reading while read window is up */
if ( ( idoc = NextUnread ( inoteBold ) ) != -1 ) {
ReadMessage ( idoc );
SendMessage ( hHeaders, GOTOIDOCALL, idocRead );
}
else {
/* display an error message then, redraw the current line the
* user is typing on.
*/
SendMessage ( hWnd, DISPLAY,
"\r\nNo unread message after current message." );
SendMessage ( hWnd, DISPPROMPT, TRUE );
StreamOut ( hWnd, commandLine, pCmd - commandLine, DefNorm );
}
break;
case ENTER:
/* ENTER is special. If it occurs at the beginning of a line, then the
* intention is to read the currently hilighted message. If there is
* any text in the command line, then we will go and execute the command.
*/
if ( hFocus == hHeaders && pCmd == commandLine ) {
ReadMessage ( mpInoteIdoc [ inoteBold ] );
break;
}
/* ELSE FALL THROUGH
*/
case CTRL_P:
case CTRL_N:
case UP:
case DOWN:
if ( hFocus == hCompose && c != ENTER )
SendMessage ( hCompose, KEY, c );
else {
if ( pCmd != commandLine ) {
/* advance to next line, do command, then output prompt */
WindLevel -= strlen ( commandLine );
#if DEBUG
debout ( "Cur level %d", WindLevel );
#endif
pCmd = commandLine;
StreamOut ( hWnd, strCRLF, 2, DefNorm );
fDelUndelBold = FALSE;
DoCommand ( hWnd );
if ( fDelUndelBold && c == ENTER )
c = DOWN;
if ( !fQuit )
SendMessage ( hWnd, DISPPROMPT, FALSE );
}
if ( c != ENTER && idocLast != -1 )
SendMessage ( hHeaders, KEY, c );
}
break;
case RIGHT:
case LEFT:
break;
case BACKSPACE:
case RUBOUT:
/* BACKSPACE or RUBOUT is used to delete the previous character. */
if ( pCmd != commandLine ) {
*--pCmd = '\0';
StreamOut (hWnd, "\b", 1, DefNorm);
WindLevel--;
#if DEBUG
debout ( "Cur level %d", WindLevel );
#endif
}
break;
default:
/* other extended characters are unrecognized */
if ( ( c > 0xFF ) || ( pCmd >= &commandLine [MAXLINELEN - 1 ] ) )
Bell ();
else
if ( isascii(c) && isprint ( c ) ) {
*pCmd = (CHAR) c;
StreamOut (hWnd, pCmd, 1, DefNorm);
*++pCmd = '\0';
WindLevel++;
#if DEBUG
debout ( "Cur level %d", WindLevel );
#endif
}
break;
}
cchCmdLine = pCmd - commandLine;
}
/* cmdProc - manage all messages and display for the command window
*
* The command window takes texual commands
*
* hWnd handle of window receiving message
* command command in message
* data data peculiar to the command
*/
VOID PASCAL INTERNAL cmdProc ( HW hWnd, INT command, WDATA data )
{
PSTR p = (PSTR)data;
PSTR pTmp = NULL;
INT width = TWINWIDTH ( hWnd );
INT winSize = width *TWINHEIGHT ( hWnd ) *sizeof ( CHAR );
switch (command) {
case KEY:
CommandChar ( hWnd, (UINT)data );
break;
case CREATE:
SetCursor ( hWnd, 0, 0 );
hWnd->pContent = PoolAlloc ( winSize );
hWnd->contSize = winSize;
Fill ( ( LPSTR ) hWnd->pContent, ' ', winSize );
SendMessage ( hWnd, CLRCMDLN, 0 );
break;
case CLRCMDLN :
*(pCmd = commandLine) = '\0';
SendMessage (hWnd, DISPPROMPT, TRUE);
break;
case DISPPROMPT :
if ((UINT)data && hWnd->crsrX != 0)
SendMessage (hWnd, DISPLAY, "");
if ( hCompose )
p = ( hFocus == hCompose ? "Compose>" : "Headers>" );
else
p = ">";
SendMessage (hWnd, DISPLAYSTR, p);
break;
case DISPTITLE:
pTmp = AppendSep ( "Command", strBLANK, p, FALSE );
SetWindowText ( hWnd, pTmp );
ZMfree ( pTmp );
break;
default:
defWndProc (hWnd, command, data);
break;
}
}