mirror of https://github.com/lianthony/NT4.0
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.
1352 lines
40 KiB
1352 lines
40 KiB
/*
|
|
* init.c - initialization code
|
|
* HISTORY:
|
|
* 27-May-87 danl Add NEWMAILONSTART
|
|
* 09-Mar-87 danl if pArgSt->LoadAlias, set fNotifyTools and move
|
|
* GetAliases to KeyManager
|
|
* 10-Mar-87 danl RecordFolder, treat as string, not filename
|
|
* 12-Mar-87 danl Use DISPLAYSTR to display welcome string
|
|
* 02-Apr-87 danl "No new mail" sent to std out, not stderr
|
|
* 02-Apr-87 mz Fix spelling of fprintf
|
|
* 11-Apr-87 mz Use PASCAL/INTERNAL
|
|
* 21-Apr-87 danl Add pShell to init
|
|
* 30-Apr-87 danl Test for fConfirmNewFld in StartUpZM
|
|
* 06-May-87 danl fCheckMail = TRUE; in initialization
|
|
* 14-May-87 danl SetScrnSt: send msg GOTOIDOCALL
|
|
* 21-May-87 danl Init strTmpDrv;
|
|
* 21-May-87 danl Removed SHOWHEAP
|
|
* 18-Jun-87 danl Add ConfirmComposeAbort
|
|
* 19-Jun-87 danl Add UPDATEWZMAIL, UpdFile etc.
|
|
* 20-Jun-87 danl Add WZMAILEXE
|
|
* 22-Jun-87 danl Bug fixes: UpdFile - always disconnect, honor PHONE
|
|
* Moved argStruct from zm.h
|
|
* 29-Jun-87 danl Added SETCLOCK
|
|
* 01-Jul-87 danl test idoc, inote against -1 not ERROR
|
|
* 01-Jul-87 danl Use strWZMAIL
|
|
* 06-Jul-87 danl Add -u to usage
|
|
* 14-Jul-87 danl Add BackupExpunge
|
|
* 15-Jul-87 danl Use fNotifyTools flags
|
|
* 15-Jul-87 danl Set F_UPDXENIXDL if updated aliases.has
|
|
* 16-Jul-87 danl DefBold: mask off high order bit
|
|
* 20-Jul-87 danl Use ReadKey instead of getc
|
|
* 21-Jul-87 danl Add pRFAIndent
|
|
* 27-Jul-87 danl fpHeapDump is stderr
|
|
* 04-Aug-87 danl Added call to fNetInstalled
|
|
* 06-Aug-87 danl Output NoNetMsg if net not installed and user
|
|
* booted with -u
|
|
* 07-Aug-87 danl Added SORTHEADER
|
|
* 20-Aug-87 danl Change "FTP" to "MTP"
|
|
* 21-Aug-1987 mz Change references from MAXARG to MAXLINELEN
|
|
* Add viking support
|
|
* 24-Aug-1987 mz Ignore HEADERS=ALL
|
|
* 27-Aug-87 danl Test rtn value of ExpandFilename
|
|
* 02-Sep-87 danl Added test for TMP defined in environment
|
|
* 03-Sep-87 danl Added exit code -4,
|
|
* 08-Sep-87 danl Put conditional OS2 in SetClock
|
|
* 15-Sep-87 danl If new mail and setlock works then break
|
|
* 16-Sep-87 danl IFDEF'd out UpdateFromToolsvrAliaseshas
|
|
* 18-Sep-87 danl Convert to new video interfaces
|
|
* 21-Sep-87 danl UpdFile: test for *pDst
|
|
* 24-Sep-87 danl Add ySize to ClearScrn call
|
|
* 24-Sep-87 danl Default rows, cols is y,x from initial dos state
|
|
* 25-Sep-87 danl Add KBOpen, KBClose
|
|
* 06-Oct-1987 mz Fix update .exe to current dir problem
|
|
* Correctly generate phone file name
|
|
* 06-Oct-87 bw Use strSHELLNAME instead of "command.com"
|
|
* 07-Oct-1987 mz Fix setting of shellname and shell flags when not specd
|
|
* 13-Oct-87 bw Update to WZMAILEXE and WZMAILPEXE.
|
|
* 19-Nov-87 sz Add BeepOnMail, -p passWord functions
|
|
* 15-Mar-88 danl Added Bootcnt
|
|
* 17-Mar-1988 mz Rational tools.ini processing; reasonable defaults
|
|
* 21-Mar-1988 mz Fix bad code in environment var processing
|
|
* 12-Oct-1989 leefi v1.10.73, got rid of some lint (-W3) warnings
|
|
* 10-Nov-1989 mz v1.10.73, replaced stat.st_atime with stat.st_mtime
|
|
*
|
|
*/
|
|
|
|
#define INCL_DOSINFOSEG
|
|
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
#include <dos.h>
|
|
#include <fcntl.h>
|
|
#include <io.h>
|
|
#include <malloc.h>
|
|
#include <memory.h>
|
|
#include <time.h>
|
|
#include <process.h>
|
|
#include <signal.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
|
|
#include "wzport.h"
|
|
#include <tools.h>
|
|
#include "dh.h"
|
|
|
|
#include "zm.h"
|
|
|
|
VOID * (_CRTAPI1 *mt_alloc)(size_t);
|
|
VOID * (_CRTAPI1 *dh_alloc)(size_t);
|
|
VOID (_CRTAPI1 *dh_free)(PVOID);
|
|
|
|
extern PSTR strLOCKMSG;
|
|
|
|
extern PSTR pVersion;
|
|
|
|
|
|
INT fhErr;
|
|
|
|
PSTR pstrYES = "yes";
|
|
PSTR pstrNO = "no";
|
|
|
|
INT myMin, myMid, myMax;
|
|
|
|
#define DOSSETDATE 0x2B
|
|
#define DOSSETTIME 0x2D
|
|
#define DOSGETTIME 0x2C
|
|
#define ROMGETDATE 0x04
|
|
#define ROMGETTIME 0x02
|
|
#define ROMTIME 0x1A
|
|
|
|
#define VARINT 0x00
|
|
#define VARBOOL 0x01
|
|
#define VARSTRING 0x02
|
|
#define VARALLOC 0x80
|
|
#define VARMASK 0x7f
|
|
|
|
#define VARNO (PSTR) FALSE
|
|
#define VARYES (PSTR) TRUE
|
|
|
|
struct varitem {
|
|
FLAG fType; /* type of item */
|
|
PSTR pName; /* pointer to tools.ini name */
|
|
union {
|
|
PSTR * ppval; /* pointer to pointer to char string */
|
|
FLAG * pfval; /* pointer to flag value */
|
|
INT * pival; /* pointer to int value */
|
|
} vval;
|
|
};
|
|
|
|
#define VAR_MONITORCOLS 0
|
|
#define VAR_MONITORROWS 1
|
|
|
|
struct varitem vartbl[] = {
|
|
VARINT, "xSize", (PSTR *) & xSize, /* Must be first */
|
|
VARINT, "ySize", (PSTR *) & ySize, /* must be second */
|
|
VARSTRING, "Aliases.has", & pAliasFN,
|
|
VARSTRING, "Alias", & DefMailName,
|
|
VARSTRING, "DefDirectory", & DefDirectory,
|
|
VARSTRING, "DefFolder", & DefMailbox, /* default and expand */
|
|
VARSTRING, "Editor", & DefMailEdit, /* default */
|
|
VARSTRING, "Help", & DefHelpPath,
|
|
VARSTRING, "Host", & DefMailHost,
|
|
VARSTRING, "Headers", & pInitHdrCmd,
|
|
VARSTRING, "MailInfo.lst", & pMailInfoFN,
|
|
VARSTRING, "PasswordAge", & pszPasswordAge,
|
|
VARSTRING, "Phone.Lst", & pPhoneFN,
|
|
VARSTRING, "Print", & pPrintCmd,
|
|
VARSTRING, "RecordFolder", & RecordFolder,
|
|
VARSTRING, "RFAIndent", & pRFAIndent, /* default | */
|
|
VARSTRING, "Shell", & pShellCmd,
|
|
VARSTRING, "ShellSwitch", & pShellFlags,
|
|
VARSTRING, "Tools.Ini", & pToolsini,
|
|
VARSTRING, "XenixDL", & pXenixdl,
|
|
VARSTRING, "toolsini", & pToolsini,
|
|
VARSTRING, "phoneServer", & pPhoneServer,
|
|
VARBOOL, "AppendReply", (PSTR *) & fAppendReply,
|
|
VARBOOL, "BackupExpunge", (PSTR *) & fBackupExpunge,
|
|
VARBOOL, "Chron", (PSTR *) & DefMOChron, /* opposite */
|
|
VARBOOL, "ConfirmComposeAbort", (PSTR *) & fConfirmComposeAbort,
|
|
VARBOOL, "ConfirmNewFld", (PSTR *) & fConfirmNewFld,
|
|
VARBOOL, "ExpungeOnQuit", (PSTR *) & fExpungeOnQuit,
|
|
VARBOOL, "MeToo", (PSTR *) & fMetoo,
|
|
VARBOOL, "NewMailOnSend", (PSTR *) & fNewmailOnSend,
|
|
VARBOOL, "NewMailOnStart", (PSTR *) & fNewmailOnStart,
|
|
VARBOOL, "Phone", (PSTR *) & fGetPhone,
|
|
VARBOOL, "SetClock", (PSTR *) & fSetClock,
|
|
VARBOOL, "SortHeaderAliases", (PSTR *) & fSortHdr,
|
|
VARBOOL, "WindowBorders", (PSTR *) & fWinBorders,
|
|
VARBOOL, "ShellWait", (PSTR *) & fShellWait,
|
|
VARBOOL, "PrintWait", (PSTR *) & fPrintWait,
|
|
VARINT, "BeepOnMail", (PSTR *) & fBeepOnMail,
|
|
VARINT, "Background", (PSTR *) & bgAttr,
|
|
VARINT, "Foreground", (PSTR *) & fgAttr,
|
|
VARINT, "Cols", (PSTR *) & xSize,
|
|
VARINT, "NewMailInterval", (PSTR *) & cSecNewmail,
|
|
VARINT, "Rows", (PSTR *) & ySize,
|
|
VARINT, "ShowSize", (PSTR *) & cShowSize,
|
|
VARINT, "BootCount", (PSTR *) & BootCount,
|
|
FALSE, NULL, NULL
|
|
};
|
|
|
|
/* default values
|
|
*/
|
|
PSTR pInitConfig[] =
|
|
{ "aliases.has=$INIT:\\aliases.has",
|
|
"defdirectory=.",
|
|
"deffolder=mailbox.fld",
|
|
"editor=edlin",
|
|
"help=.",
|
|
"host=none",
|
|
"mailinfo.lst=$INIT:\\mailinfo.lst",
|
|
"phone.lst=$INIT:\\phone.lst",
|
|
"print=print ",
|
|
"rfaindent=| ",
|
|
"backupexpunge=YES",
|
|
"chron=YES",
|
|
"ConfirmComposeAbort=YES",
|
|
"ConfirmNewFld=YES",
|
|
"metoo=YES",
|
|
"NewMailOnStart=YES",
|
|
"Phone=YES",
|
|
"SetClock=YES",
|
|
"SortHeaderAliases=YES",
|
|
"UpdateWzmail=YES",
|
|
"WindowBorders=YES",
|
|
"ShowSize=2000",
|
|
"ShellWait=YES",
|
|
"PrintWait=NO",
|
|
"PasswordAge=6:00:00",
|
|
NULL
|
|
};
|
|
|
|
#ifdef NT
|
|
|
|
PCHAR_INFO pLocalScreen;
|
|
PCHAR_INFO pBlankScreen;
|
|
COORD localScreenSize;
|
|
|
|
|
|
//
|
|
// Screen attributes
|
|
//
|
|
#define BLACK_FGD 0
|
|
#define BLUE_FGD FOREGROUND_BLUE
|
|
#define GREEN_FGD FOREGROUND_GREEN
|
|
#define CYAN_FGD (FOREGROUND_BLUE | FOREGROUND_GREEN)
|
|
#define RED_FGD FOREGROUND_RED
|
|
#define MAGENTA_FGD (FOREGROUND_BLUE | FOREGROUND_RED)
|
|
#define YELLOW_FGD (FOREGROUND_GREEN | FOREGROUND_RED)
|
|
#define WHITE_FGD (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
|
|
|
|
#define BLACK_BGD 0
|
|
#define BLUE_BGD BACKGROUND_BLUE
|
|
#define GREEN_BGD BACKGROUND_GREEN
|
|
#define CYAN_BGD (BACKGROUND_BLUE | BACKGROUND_GREEN)
|
|
#define RED_BGD BACKGROUND_RED
|
|
#define MAGENTA_BGD (BACKGROUND_BLUE | BACKGROUND_RED)
|
|
#define YELLOW_BGD (BACKGROUND_GREEN | BACKGROUND_RED)
|
|
#define WHITE_BGD (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)
|
|
|
|
//
|
|
// The AttrBg and AttrFg arrays are used for mapping DOS attributes
|
|
// to the WIN32 attributes.
|
|
//
|
|
WORD AttrBg[ ] = {
|
|
BLACK_BGD, // black
|
|
BLUE_BGD, // blue
|
|
GREEN_BGD, // green
|
|
CYAN_BGD, // cyan
|
|
RED_BGD, // red
|
|
MAGENTA_BGD, // magenta
|
|
YELLOW_BGD, // brown
|
|
WHITE_BGD, // light gray
|
|
(BLACK_BGD | BACKGROUND_INTENSITY), // dark gray
|
|
(BLUE_BGD | BACKGROUND_INTENSITY), // light blue
|
|
(GREEN_BGD | BACKGROUND_INTENSITY), // light green
|
|
(CYAN_BGD | BACKGROUND_INTENSITY), // light cyan
|
|
(RED_BGD | BACKGROUND_INTENSITY), // light red
|
|
(MAGENTA_BGD | BACKGROUND_INTENSITY), // light magenta
|
|
(YELLOW_BGD | BACKGROUND_INTENSITY), // light yellow
|
|
(WHITE_BGD | BACKGROUND_INTENSITY) // white
|
|
};
|
|
|
|
WORD AttrFg[ ] = {
|
|
BLACK_FGD, // black
|
|
BLUE_FGD, // blue
|
|
GREEN_FGD, // green
|
|
CYAN_FGD, // cyan
|
|
RED_FGD, // red
|
|
MAGENTA_FGD, // magenta
|
|
YELLOW_FGD, // brown
|
|
WHITE_FGD, // light gray
|
|
(BLACK_FGD | FOREGROUND_INTENSITY), // dark gray
|
|
(BLUE_FGD | FOREGROUND_INTENSITY), // light blue
|
|
(GREEN_FGD | FOREGROUND_INTENSITY), // light green
|
|
(CYAN_FGD | FOREGROUND_INTENSITY), // light cyan
|
|
(RED_FGD | FOREGROUND_INTENSITY), // light red
|
|
(MAGENTA_FGD | FOREGROUND_INTENSITY), // light magenta
|
|
(YELLOW_FGD | FOREGROUND_INTENSITY), // light yellow
|
|
(WHITE_FGD | FOREGROUND_INTENSITY) // white
|
|
};
|
|
|
|
//
|
|
// GET_ATTRIBUTE performs the mapping from old attributes to new attributes
|
|
//
|
|
#define GET_ATTRIBUTE(x) (AttrFg[x & 0x000F ] | AttrBg[( x & 0x00F0 ) >> 4])
|
|
|
|
#endif
|
|
|
|
PSTR INTERNAL SprintStr (PSTR pFmt, ...)
|
|
{
|
|
char buf[MAXLINELEN];
|
|
va_list vaPtr;
|
|
|
|
va_start (vaPtr, pFmt);
|
|
vsprintf (buf, pFmt, vaPtr);
|
|
va_end (vaPtr);
|
|
|
|
return ZMMakeStr (buf);
|
|
}
|
|
|
|
INT PASCAL INTERNAL cvtfromBCD (USHORT value)
|
|
{
|
|
register USHORT n0,n1,n2,n3; /* The 4 nibbles in value */
|
|
n0 = (USHORT)(value & 0x000F);
|
|
n1 = (USHORT)((value & 0x00F0) >> 4);
|
|
n2 = (USHORT)((value & 0x0F00) >> 8);
|
|
n3 = (USHORT)((value & 0xF000) >> 12); /* split out the 4 nibbles in word */
|
|
return (INT)((((n3)*10+n2)*10+n1)*10+n0); /* Return word expanded */
|
|
}
|
|
|
|
/* SetClock - Sets the Dos Date/Time from the CMOS if running on
|
|
* a PC/AT compatible. Handles the date rollover problem that
|
|
* exists in some versions of the dos
|
|
*/
|
|
VOID PASCAL INTERNAL SetClock (VOID)
|
|
{
|
|
#ifndef OS2
|
|
#ifndef NT
|
|
union REGS dreg;
|
|
INT year, month, day;
|
|
UCHAR hour, minute, second;
|
|
LPUCHAR Model_Byte = (LPUCHAR)0xF000FFFE;
|
|
|
|
if (*Model_Byte != 0xFC)
|
|
return;
|
|
dreg.h.ah = ROMGETDATE; /* ROM function to read date */
|
|
int86(ROMTIME,&dreg,&dreg);
|
|
year = cvtfromBCD((USHORT)dreg.x.cx);
|
|
month = cvtfromBCD((USHORT)dreg.h.dh);
|
|
day = cvtfromBCD((USHORT)dreg.h.dl);
|
|
dreg.h.ah = DOSSETDATE;
|
|
dreg.x.cx = year;
|
|
dreg.h.dh = (UCHAR)month;
|
|
dreg.h.dl = (UCHAR)day;
|
|
intdos(&dreg,&dreg);
|
|
if (!dreg.h.al) {
|
|
dreg.h.ah = ROMGETTIME; /* ROM function to read time */
|
|
int86(ROMTIME,&dreg,&dreg);
|
|
hour = (UCHAR)cvtfromBCD((USHORT)dreg.h.ch);
|
|
minute = (UCHAR)cvtfromBCD((USHORT)dreg.h.cl);
|
|
second = (UCHAR)cvtfromBCD((USHORT)dreg.h.dh);
|
|
dreg.h.ah = DOSGETTIME;
|
|
intdos(&dreg,&dreg); /* Read DOS time */
|
|
if (hour != dreg.h.ch)
|
|
dreg.h.ch = hour;
|
|
if (minute != dreg.h.cl)
|
|
dreg.h.cl = minute;
|
|
dreg.h.ah = DOSSETTIME;
|
|
intdos(&dreg,&dreg);
|
|
if (!dreg.h.al)
|
|
return;
|
|
}
|
|
fprintf (stderr, "Error setting date/time from CMOS\nType a char to continue\n" );
|
|
ReadKey();
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ArgParse - parse command line args, set up argstruct to reflect cmd lin args.
|
|
*
|
|
* arguments:
|
|
* argc argc from command line
|
|
* argv argv from command line
|
|
* pArgSt pointer to arg struct to place settings in
|
|
*
|
|
* return value:
|
|
* pArgSt command line arguments are OK.
|
|
* NULL error in command line arguments.
|
|
*
|
|
* IMPORTANT:
|
|
* ArgParse will terminate ZM via exit ( 1 ) if there is an error in the
|
|
* command line arguments.
|
|
*/
|
|
PARG PASCAL INTERNAL ArgParse ( SHORT argc, PSTR argv[], PARG pArgSt )
|
|
{
|
|
FLAG error = FALSE;
|
|
INT GivenAliases = 0;
|
|
INT i;
|
|
|
|
fReadOnlyAll = fReadOnlyCur = FALSE;
|
|
pArgSt->pMfldLoad = ( PSTR ) ZMalloc ( MAXLINELEN );
|
|
pArgSt->pAliasList = ( PSTR ) ZMalloc ( MAXLINELEN );
|
|
*( pArgSt->pMfldLoad ) = '\0';
|
|
*( pArgSt->pAliasList ) = '\0';
|
|
pArgSt->LoadAlias = TRUE;
|
|
pArgSt->fUpdate = pArgSt->DebugWin = FALSE;
|
|
for ( i = 1; i < (INT)argc; i++) {
|
|
if ( ( *argv [ i ] == '-' ) || ( *argv [ i ] == '/' ) ) {
|
|
switch ( tolower ( *( argv [ i ] + 1 ) ) ) {
|
|
case 'n':
|
|
fCheckAnyMail = TRUE;
|
|
break;
|
|
case 'r' :
|
|
fReadOnlyCur = fReadOnlyAll = TRUE;
|
|
break;
|
|
case 'a' :
|
|
pArgSt->LoadAlias = FALSE;
|
|
break;
|
|
case 'u' :
|
|
//allow for backwards compatibility, but does nothing
|
|
break;
|
|
case 'f' :
|
|
if ( *( pArgSt->pMfldLoad ) != '\0' )
|
|
*( pArgSt->pMfldLoad ) = '\0';
|
|
if ( i + 1 < argc ) {
|
|
strcpy ( pArgSt->pMfldLoad, argv [ ++i ] );
|
|
} else
|
|
error = TRUE;
|
|
break;
|
|
case 'd' :
|
|
|
|
#if DEBUG
|
|
pArgSt->DebugWin = TRUE;
|
|
#endif
|
|
break;
|
|
case 's':
|
|
if ( i + 1 < argc )
|
|
pInitScript = argv [ ++i ];
|
|
else
|
|
error = TRUE;
|
|
break;
|
|
case 'p':
|
|
if ( i + 1 < argc )
|
|
GetPassword ( argv [ ++i ] );
|
|
else
|
|
error = TRUE;
|
|
break;
|
|
default :
|
|
error = TRUE;
|
|
break;
|
|
}
|
|
if ( GivenAliases < 0 )
|
|
GivenAliases = 1;
|
|
} else if ( ( GivenAliases == 0 ) || ( GivenAliases == -1 ) ) {
|
|
GivenAliases = -1;
|
|
strcat ( pArgSt->pAliasList, argv [ i ] );
|
|
strcat ( pArgSt->pAliasList, strBLANK );
|
|
} else
|
|
error = TRUE;
|
|
}
|
|
if ( error )
|
|
ZMexit ( 1,
|
|
"Usage: WZMAIL [-n] [-r] [-a] [-s scriptfile] [-f <mailfolder>] [aliases]" );
|
|
return pArgSt;
|
|
}
|
|
|
|
|
|
|
|
/* EnvOrIni - replacement for getenvini, allows a FILE * and long as param
|
|
*/
|
|
PSTR PASCAL INTERNAL EnvOrIni (FILE *fp, LONG lPos, PSTR pstrEnv, PSTR pstrTag )
|
|
{
|
|
PSTR p = NULL;
|
|
PSTR pstrTmp = NULL;
|
|
|
|
if (!(pstrTmp = (PSTR)malloc ((strlen (pstrEnv) + strlen (pstrTag) + 2) * sizeof(CHAR))))
|
|
return NULL;
|
|
strcpy (pstrTmp, pstrTag);
|
|
strcat (pstrTmp, "_");
|
|
strcat (pstrTmp, pstrEnv);
|
|
pstrTmp = strupr (pstrTmp); /* getenv requires upper case */
|
|
// if ((p = getenv (pstrTmp))) {
|
|
if ((p = getenvOem (pstrTmp))) {
|
|
/* found in env so do NOT look into switch file */
|
|
if (*(p = whiteskip (p)))
|
|
/* found non-white space char so return non-NULL */
|
|
p = strdup (p);
|
|
else
|
|
/* rhs has only white space char */
|
|
p = NULL;
|
|
}
|
|
else {
|
|
if ( !fp ) {
|
|
if ( ( fp = swopen ( strTOOLSINI, strWZMAIL ) ) ) {
|
|
p = swfind (pstrEnv, fp, pstrTag);
|
|
swclose ( fp );
|
|
}
|
|
}
|
|
else {
|
|
fseek ( fp, lPos, SEEK_SET );
|
|
p = swfind (pstrEnv, fp, pstrTag); /* swfind does an alloc if found */
|
|
}
|
|
}
|
|
free (pstrTmp);
|
|
return p;
|
|
}
|
|
|
|
|
|
|
|
/* SetLock - Create Lock file
|
|
*
|
|
* if lock file does not exist
|
|
* create it
|
|
* else
|
|
* ask user to continue or quit
|
|
*/
|
|
FLAG PASCAL INTERNAL SetLock ( FLAG fAskUser )
|
|
{
|
|
FLAG fRtn;
|
|
PSTR pstrFN = NULL;
|
|
INT fh;
|
|
CHAR ch;
|
|
|
|
pstrFN = ExpandFilename ( "MAILLOCK.XXX", strFLD );
|
|
if ( ( fh = open ( pstrFN, O_CREAT | O_EXCL, S_IREAD | S_IWRITE ) ) != -1 )
|
|
fRtn = OK;
|
|
else if ( fAskUser ) {
|
|
/* purge any type ahead
|
|
*/
|
|
while ( kbwait (0) )
|
|
ReadKey ( );
|
|
fprintf ( stderr, strLOCKMSG, pstrFN );
|
|
while ((ch = (char)ReadKey()) != 'c' && ch != 'r')
|
|
;
|
|
fRtn = ch == (char)'c' ? OK : ERROR;
|
|
}
|
|
else
|
|
fRtn = ERROR;
|
|
ZMfree ( pstrFN );
|
|
close ( fh );
|
|
return fRtn;
|
|
}
|
|
|
|
VOID PASCAL INTERNAL FreeLock (VOID)
|
|
{
|
|
PSTR pstrFN = NULL;
|
|
|
|
unlink ( ( pstrFN = ExpandFilename ( "MAILLOCK.XXX", strFLD ) ) );
|
|
ZMfree ( pstrFN );
|
|
}
|
|
|
|
/* WhiteSpaceFix - remove leading/trailing whitespace
|
|
*/
|
|
|
|
PSTR PASCAL INTERNAL WhiteSpaceFix (PSTR p)
|
|
{
|
|
PSTR p1 = strend (p);
|
|
|
|
p = whiteskip (p);
|
|
|
|
while (p1 > p && p1[-1] == ' ')
|
|
p1--;
|
|
*p1 = '\0';
|
|
return p;
|
|
}
|
|
|
|
/* search vartbl for p as an entry and if found changes is value to q
|
|
*/
|
|
VOID PASCAL INTERNAL SetVartbl ( PSTR p, PSTR q )
|
|
{
|
|
PSTR p1 = NULL;
|
|
struct varitem *pVaritem = vartbl;
|
|
|
|
p = WhiteSpaceFix (p);
|
|
q = WhiteSpaceFix (q);
|
|
|
|
if (*q == '\0')
|
|
return;
|
|
|
|
while (pVaritem->pName != NULL) {
|
|
if (!strcmpis ( p, pVaritem->pName ) )
|
|
break;
|
|
pVaritem++;
|
|
}
|
|
|
|
if (pVaritem->pName != NULL)
|
|
switch ( pVaritem->fType & VARMASK ) {
|
|
case VARINT:
|
|
*(pVaritem->vval.pival) = atoi ( q );
|
|
break;
|
|
case VARBOOL:
|
|
*(pVaritem->vval.pfval) = strcmpis ( q, "no" );
|
|
break;
|
|
case VARSTRING:
|
|
/* treat quoted value nicely by trimming off quotes
|
|
*/
|
|
if ( *q == '\"' && *(p1 = strend(q)-1) == '\"') {
|
|
*q++;
|
|
*p1 = '\0';
|
|
}
|
|
ZMfree (*(pVaritem->vval.ppval));
|
|
*(pVaritem->vval.ppval) = ZMMakeStr ( q );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ProcessConfigString - handle a name=value string
|
|
*
|
|
* p character pointer to name=value string
|
|
*/
|
|
VOID ProcessConfigString (PSTR p)
|
|
{
|
|
PSTR p1 = NULL;
|
|
|
|
if (*(p1 = strbscan (p, "=")) != '\0') {
|
|
*p1++ = '\0';
|
|
SetVartbl (p, p1);
|
|
}
|
|
}
|
|
|
|
/* scan tools.ini [wzmail] and save values, as appropriate, in vartbl
|
|
*/
|
|
VOID PASCAL INTERNAL GetToolsIni (VOID)
|
|
{
|
|
FILE *fp = NULL;
|
|
CHAR buf[MAXARG];
|
|
|
|
if ((fp = swopen (strTOOLSINI, strWZMAIL)) != NULL) {
|
|
while (swread (buf, MAXARG, fp))
|
|
ProcessConfigString (buf);
|
|
swclose ( fp );
|
|
}
|
|
else
|
|
ZMexit ( 1, "Can't open tools.ini" );
|
|
}
|
|
|
|
|
|
/*
|
|
* enumerate vartbl, for each entry look in dos env for wzmail_variable
|
|
* and if found store in vartbl
|
|
*/
|
|
VOID PASCAL INTERNAL GetEnvIni (VOID)
|
|
{
|
|
PSTR p = NULL;
|
|
PSTR q = NULL;
|
|
CHAR buf[MAXARG];
|
|
struct varitem *pVaritem = vartbl;
|
|
|
|
strcpy ( buf, "WZMAIL_" );
|
|
p = strend ( buf );
|
|
while (pVaritem->pName != NULL) {
|
|
strcpy ( p, pVaritem->pName );
|
|
upper ( p );
|
|
// if ( ( q = getenv ( buf ) ) )
|
|
if ( ( q = getenvOem ( buf ) ) )
|
|
SetVartbl ( p, q );
|
|
pVaritem++;
|
|
}
|
|
}
|
|
|
|
/* GetEnvironment - set up the global variables which come from the environment
|
|
*
|
|
* arguments:
|
|
* pArgv0 - argv[0] to main
|
|
*
|
|
* return value:
|
|
* none
|
|
*
|
|
*/
|
|
VOID PASCAL INTERNAL GetEnvironment ( PSTR pArgv0, FLAG fUpdOption )
|
|
{
|
|
PSTR p = NULL;
|
|
CHAR buf[MAXLINELEN];
|
|
INT fore, back;
|
|
FLAG fReboot = FALSE;
|
|
INT i;
|
|
#ifdef NT
|
|
CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
|
|
#endif
|
|
|
|
#if defined (OS2)
|
|
DosGetInfoSeg ((PSEL) &SELECTOROF (pInfoSegG),
|
|
(PSEL) &SELECTOROF (pInfoSegL));
|
|
#endif
|
|
|
|
pArgv0; fUpdOption; /* make compiler happy */
|
|
|
|
#if 0
|
|
//
|
|
// Set strings for files, tools.ini sections per argv0 - set to "wzmail"
|
|
// by constant.c by default
|
|
//
|
|
|
|
//
|
|
// BUGBUG - need to strip off leading and trailing junk before turning
|
|
// this on.
|
|
//
|
|
|
|
if (pArgv0[0] != '\0') {
|
|
strWZMAIL = ZMMakeStr (pArgv0);
|
|
strcpy (buf, pArgv0);
|
|
strcat (buf, ".dl");
|
|
strWZMAILDL = ZMMakeStr (buf);
|
|
strcpy (buf, pArgv0);
|
|
strcat (buf, ".tmp");
|
|
strWZMAILTMP = ZMMakeStr (buf);
|
|
strcpy (buf, pArgv0);
|
|
strcat (buf, ".hlp");
|
|
strWZMAILHLP = ZMMakeStr (buf);
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Get monitor name and put it into the vartbl as display_rows
|
|
* display_cols. Retrieve current foreground and background
|
|
* attributes.
|
|
*/
|
|
attrInit = GetAttr();
|
|
fgAttr = (attrInit) & 0x0f;
|
|
bgAttr = (attrInit >> 4) & 0x0f;
|
|
|
|
#ifdef NT
|
|
|
|
if (GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &ScreenInfo))
|
|
{
|
|
ySize = ScreenInfo.dwSize.Y;
|
|
xSize = ScreenInfo.dwSize.X;
|
|
}
|
|
else
|
|
ZMexit ( 1, "Can't determine console state" );
|
|
vartbl[VAR_MONITORROWS].pName = SprintStr ("%s_rows", "VGA");
|
|
vartbl[VAR_MONITORCOLS].pName = SprintStr ("%s_cols", "VGA");
|
|
|
|
#else
|
|
|
|
if ( (dosVShandle = GetVideoState ()) == -1 )
|
|
ZMexit ( 1, "Can't determine video monitor state" );
|
|
p = NameVideoState ( dosVShandle );
|
|
vartbl[VAR_MONITORROWS].pName = SprintStr ("%s_rows", p);
|
|
vartbl[VAR_MONITORCOLS].pName = SprintStr ("%s_cols", p);
|
|
DecodeVideoState ( dosVShandle, &ySize, &xSize );
|
|
|
|
#endif
|
|
|
|
/* load up default configuration
|
|
*/
|
|
for (i = 0; pInitConfig[i] != NULL; i++)
|
|
ProcessConfigString (pInitConfig[i]);
|
|
|
|
/* read tools.ini
|
|
*/
|
|
GetToolsIni();
|
|
|
|
/* read dos environemnt
|
|
*/
|
|
GetEnvIni();
|
|
|
|
|
|
SetMaxPasswordAge();
|
|
|
|
if (fSetClock)
|
|
SetClock ();
|
|
|
|
if ( DefDirectory[strlen ( DefDirectory ) - 1] != '\\' ) {
|
|
DefDirectory = SprintStr ("%s\\", p = DefDirectory);
|
|
ZMfree (p);
|
|
}
|
|
|
|
|
|
|
|
findpath (pAliasFN, buf, TRUE);
|
|
ZMfree (pAliasFN);
|
|
pAliasFN = ZMMakeStr (buf);
|
|
|
|
findpath (pPhoneFN, buf, TRUE);
|
|
ZMfree (pPhoneFN);
|
|
pPhoneFN = ZMMakeStr (buf);
|
|
|
|
findpath (pMailInfoFN, buf, TRUE);
|
|
ZMfree (pMailInfoFN);
|
|
pMailInfoFN = ZMMakeStr (buf);
|
|
fMailInfoDown = FALSE;
|
|
|
|
buf[0] = 0;
|
|
findpath ("$INIT:\\myphone.lst", buf, FALSE);
|
|
pMyPhoneFN = ZMMakeStr (buf);
|
|
|
|
/* Set up the bold/normal attributes
|
|
*
|
|
* Make sure that the user has specified a valid set of attributes.
|
|
*/
|
|
fore = fgAttr;
|
|
back = bgAttr;
|
|
|
|
if ( ( fore < 0 ) || ( fore > 15 ) || ( fore == back ) )
|
|
fore = 7;
|
|
if ( ( back < 0 ) || ( back > 15 ) || ( fore == back ) )
|
|
back = 0;
|
|
|
|
if (fore == back) {
|
|
fore = 7;
|
|
back = 0;
|
|
}
|
|
|
|
DefBold = ( fore << 4 ) + back;
|
|
DefNorm = ( back << 4 ) + fore;
|
|
|
|
#ifdef NT /* convert attributes to WIN32 values */
|
|
DefBold = GET_ATTRIBUTE(DefBold);
|
|
DefNorm = GET_ATTRIBUTE(DefNorm);
|
|
|
|
#else
|
|
/* If we are in real mode or are running in a full-screen window
|
|
* disable the blink bit
|
|
*/
|
|
#if !defined (OS2)
|
|
DefBold &= 0x7F;
|
|
DefNorm &= 0x7F;
|
|
#else
|
|
if (ISFULLSCREEN) {
|
|
DefBold &= 0x7F;
|
|
DefNorm &= 0x7F;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
DefMailbox = ExpandFilename ( p = DefMailbox, strFLD );
|
|
ZMfree (p);
|
|
DefMOChron = !DefMOChron;
|
|
|
|
if (DefMailName != NULL)
|
|
strlwr (DefMailName);
|
|
|
|
if (pShellCmd == NULL) {
|
|
// if ((pShellCmd = getenv ("COMSPEC")) == NULL)
|
|
if ((pShellCmd = getenvOem ("COMSPEC")) == NULL)
|
|
pShellCmd = strSHELLNAME;
|
|
if ( pShellFlags == NULL)
|
|
pShellFlags = ZMMakeStr ("/c");
|
|
}
|
|
|
|
pShellFlags = SprintStr (" %s ", p = pShellFlags);
|
|
ZMfree (p);
|
|
|
|
if ( (pInitHdrCmd != NULL) && (!strcmpis (pInitHdrCmd, strAll)) ) {
|
|
ZMfree (pInitHdrCmd);
|
|
pInitHdrCmd = NULL;
|
|
}
|
|
|
|
if (!fNewmailOnStart) {
|
|
/* This prevents CheckMail from do a new mail the first time it is
|
|
* it is called
|
|
*/
|
|
(VOID)time ( &lTmLastMail );
|
|
fCheckMail = FALSE;
|
|
}
|
|
|
|
if ( fWinBorders ) {
|
|
C_TL= 0xDA;
|
|
C_TR= 0xBF;
|
|
C_BL= 0xC0;
|
|
C_BR= 0xD9;
|
|
C_H = 0xC4;
|
|
C_V = 0xB3;
|
|
}
|
|
else {
|
|
C_TL= 0xC9;
|
|
C_TR= 0xBB;
|
|
C_BL= 0xC8;
|
|
C_BR= 0xBC;
|
|
C_H = 0xCD;
|
|
C_V = 0xBA;
|
|
}
|
|
|
|
cSecNewmail *= 60;
|
|
cSecConnect = 300;
|
|
|
|
fMailAllowed = fNetInstalled () && (DefMailName != NULL);
|
|
|
|
tzset();
|
|
}
|
|
|
|
|
|
|
|
|
|
/* SetScrnSt - set screen state to the passed value, update the screen.
|
|
*
|
|
* arguments:
|
|
* mode BHDRNOCOMP : big headers window, no compose window
|
|
* BIGHEADERS : big header window, small compose window
|
|
* BIGCOMPOSE : big compose window, small header window
|
|
*
|
|
* return value:
|
|
* none
|
|
*/
|
|
VOID PASCAL INTERNAL SetScrnSt ( INT state )
|
|
{
|
|
BOX box;
|
|
UINT fDrawCompose = FALSE;
|
|
UINT fDrawHeaders = FALSE;
|
|
|
|
switch (state) {
|
|
case BHDRNOCOMP :
|
|
if ( hCompose != NULL )
|
|
CloseWindow ( hCompose );
|
|
SetRect ( &box, 0, 0, myMax, xSize );
|
|
fDrawHeaders = ResizeWindow (hHeaders, &box);
|
|
break;
|
|
case BIGHEADERS :
|
|
assert ( hCompose );
|
|
SetRect ( &box, myMin + 1, 0, myMin + myMid - 1, xSize );
|
|
fDrawHeaders = ResizeWindow (hHeaders, &box);
|
|
SetRect ( &box, 0, 0, myMin, xSize );
|
|
fDrawCompose = ResizeWindow (hCompose, &box);
|
|
break;
|
|
case BIGCOMPOSE :
|
|
assert ( hCompose );
|
|
SetRect ( &box, 0, 0, myMid, xSize );
|
|
fDrawCompose = ResizeWindow (hCompose, &box);
|
|
SetRect (&box, myMid + 1, 0, myMin + myMid - 1, xSize);
|
|
fDrawHeaders = ResizeWindow (hHeaders, &box);
|
|
break;
|
|
default :
|
|
break;
|
|
}
|
|
SendMessage ( hHeaders, GOTOIDOCALL, mpInoteIdoc[inoteBold] );
|
|
if (fDrawCompose)
|
|
DrawWindow (hCompose, TRUE);
|
|
if (fDrawHeaders)
|
|
DrawWindow (hHeaders, TRUE);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/* SetUpScreen - get screen parameters, open up the command and debug windows.
|
|
*
|
|
* arguments:
|
|
* debugWin TRUE => open a debug window
|
|
*
|
|
* return value:
|
|
* none.
|
|
*/
|
|
VOID PASCAL INTERNAL SetUpScreen ( FLAG debugWin )
|
|
{
|
|
#ifdef NT
|
|
int i;
|
|
COORD dwSize;
|
|
CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
|
|
SMALL_RECT Window;
|
|
#endif
|
|
debugWin; /* make compiler happy - used if debug on */
|
|
|
|
hCompose = NULL;
|
|
attrInit = GetAttr( );
|
|
|
|
#ifdef NT
|
|
dwSize.X = (SHORT) xSize;
|
|
dwSize.Y = (SHORT) ySize;
|
|
Window.Left = 0;
|
|
Window.Top = 0;
|
|
Window.Right = (SHORT) (xSize-1);
|
|
Window.Bottom = (SHORT) (ySize-1);
|
|
|
|
//
|
|
// Allocate local and blank local screen buffers.
|
|
// Initialize blanking buffer (characters only, not attributes)
|
|
// to blanks for use by clrScrn. set blank buffer size.
|
|
//
|
|
|
|
if ( (pBlankScreen = (PCHAR_INFO) ZMalloc ( xSize * ySize * sizeof (CHAR_INFO))) &&
|
|
(pLocalScreen = (PCHAR_INFO) ZMalloc ( xSize * ySize * sizeof (CHAR_INFO))) ) {
|
|
for ( i = 0; i < ( xSize * ySize); i++ )
|
|
pBlankScreen[i].Char.AsciiChar = ' ';
|
|
localScreenSize.X = (SHORT) xSize;
|
|
localScreenSize.Y = (SHORT) ySize;
|
|
}
|
|
else
|
|
ZMexit (1, "Could not setup local screen buffers");
|
|
|
|
if ( ! (GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE),
|
|
&ScreenInfo)) ) {
|
|
ZMexit (1, "Get setup monitor screen");
|
|
}
|
|
else
|
|
SetLastError (0);
|
|
if ( (ScreenInfo.dwSize.X > (SHORT) xSize) ||
|
|
(ScreenInfo.dwSize.Y > (SHORT) ySize) ) {
|
|
|
|
//
|
|
// Window is larger than desired (configured) size
|
|
// Must resize window down first, then screen buffer
|
|
//
|
|
|
|
SetConsoleWindowInfo (GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &Window);
|
|
SetConsoleScreenBufferSize (GetStdHandle(STD_OUTPUT_HANDLE), dwSize);
|
|
}
|
|
else if ( (ScreenInfo.dwSize.X < (SHORT) xSize) ||
|
|
(ScreenInfo.dwSize.Y < (SHORT) ySize) ) {
|
|
|
|
//
|
|
// Window is smaller than desired (configured) size
|
|
// Must resize screen buffer up first, then window
|
|
//
|
|
SetConsoleScreenBufferSize (GetStdHandle(STD_OUTPUT_HANDLE), dwSize);
|
|
SetConsoleWindowInfo (GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &Window);
|
|
}
|
|
|
|
//
|
|
// If neither of the above, xSize and ySize have been determined
|
|
// from current screen buffer (which = current window), so do nothing
|
|
//
|
|
|
|
if (GetLastError()) {
|
|
fprintf ( stderr, "Can't set %s monitor to %d rows by %d cols - err %d\n",
|
|
"VGA", ySize, xSize, GetLastError() );
|
|
ZMexit ( 1, NULL );
|
|
}
|
|
SetVideoState ( zmVShandle );
|
|
fScreenSetup = TRUE;
|
|
|
|
#else
|
|
if ( (zmVShandle = EncodeVideoState ( dosVShandle, ySize, xSize )) == -1 ) {
|
|
fprintf ( stderr, "Can't set %s monitor to %d rows by %d cols\n",
|
|
NameVideoState ( dosVShandle ), ySize, xSize );
|
|
ZMexit ( 1, NULL );
|
|
}
|
|
SetVideoState ( zmVShandle );
|
|
|
|
fScreenSetup = TRUE;
|
|
|
|
if ( !strcmpis ( NameVideoState ( dosVShandle ), "VIKING" ) )
|
|
ClearScrn ( DefNorm, ySize );
|
|
#endif
|
|
|
|
#if DEBUG
|
|
if ( ( debugWin ) && ( ySize >= 25 ) ) {
|
|
CmdHeight = 7;
|
|
DebHeight = ( ySize / 8 ) + 3;
|
|
hDebug = CreateWindow ( "Debug", 0, ySize - DebHeight,
|
|
xSize, DebHeight,
|
|
debugProc, StdSKey, 0 );
|
|
} else
|
|
#endif
|
|
|
|
{
|
|
DebHeight = 0;
|
|
CmdHeight = 7 - ( fWinBorders ? 0 : 1 );
|
|
hDebug = NULL;
|
|
}
|
|
|
|
HdrHeight = ySize - ( CmdHeight + DebHeight );
|
|
hCommand = NULL; /* to ensure non-random for first CheckTime call */
|
|
hCommand = CreateWindow ( "Command", 0, HdrHeight,
|
|
-xSize, -CmdHeight,
|
|
cmdProc, StdSKey, 0 );
|
|
SETFLAG (hCommand->fsFlag, WF_NODISCARD);
|
|
SendMessage ( hCommand, DISPLAYSTR, "Welcome to " );
|
|
SendMessage ( hCommand, DISPLAYSTR, pVersion );
|
|
|
|
myMax = HdrHeight - 1;
|
|
myMid = HdrHeight - 7;
|
|
myMin = 7;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/* StartUpZM - parse command line args, set up globals, get environment vars,
|
|
* open up the standard windows.
|
|
*
|
|
* arguments:
|
|
* pArgStruc pointer to argStruct with set up information in it.
|
|
*
|
|
* return value:
|
|
* none
|
|
*
|
|
* IMPORTANT:
|
|
* StartUpZM will terminate ZM when any of these occur:
|
|
* 1 - unable to open mailfolder pArgSt->pMfldLoad when -f arg given
|
|
* 2 - unable to create mail temp when pArgSt->pAliasList != NULL
|
|
* 3 - unable to create your default mailfolder when -f arg not given
|
|
*/
|
|
FLAG PASCAL INTERNAL StartUpZM ( PSTR pArgv0, PARG pArgSt )
|
|
{
|
|
struct stat statBuf;
|
|
Fhandle fh;
|
|
FLAG fCreateFld;
|
|
CHAR pathBuf [ MAXPATHLEN ];
|
|
PSTR pTmpFN = NULL;
|
|
PSTR pTmp = NULL;
|
|
|
|
statBuf; /* make compiler happy - used only if "heapcrap" */
|
|
|
|
/* get the default environment variables, set up some globals */
|
|
idocLast = -1;
|
|
fhMailBox = ERROR;
|
|
AliasesAround = ERROR;
|
|
lTmConnect = lTmLastMail = 0L;
|
|
fCheckMail = TRUE;
|
|
pPrevHdrCmd = ZMMakeStr (strAll);
|
|
|
|
GetEnvironment ( pArgv0, pArgSt->fUpdate );
|
|
|
|
pTmpFN = mktmpnam ( );
|
|
rootpath ( pTmpFN, pathBuf );
|
|
strncpy ( strTmpDrv, strlwr ( pathBuf ), 2 );
|
|
strTmpDrv[3] = '\0';
|
|
ZMfree ( pTmpFN );
|
|
|
|
if ( fMailAllowed && fCheckAnyMail ) {
|
|
switch ( AnyMail ( ) ) {
|
|
case 1:
|
|
/* there is newmail
|
|
* if we can set the lock, then wzmail not running, so
|
|
* continue booting, if we can't set lock then wzmail
|
|
* is currently running and we should not let the user
|
|
* back in but merely say there is new mail
|
|
*/
|
|
if ( SetLock ( FALSE ) ) {
|
|
fprintf ( stdout, "New mail on server. Type exit to return to wzmail.\n" );
|
|
ZMexit ( 4, NULL );
|
|
}
|
|
break;
|
|
case 0:
|
|
fprintf ( stdout, "No new mail\n" );
|
|
ZMexit ( 3, NULL );
|
|
case -1:
|
|
ZMexit ( 1, "Network not installed or functioning" );
|
|
case -2:
|
|
ZMexit ( 1, "Unable to connect to host" );
|
|
case -3:
|
|
ZMexit ( 1, NULL );
|
|
}
|
|
}
|
|
else
|
|
if ( SetLock ( TRUE ) )
|
|
return ERROR;
|
|
|
|
/* if the user started with aliasese on the command line, enter compose */
|
|
/* note that they won't be able to do general cmds and view mail if */
|
|
/* this is the case. */
|
|
if ( *( pArgSt->pAliasList ) != '\0' ) {
|
|
/* make zm quit following exit from compose */
|
|
fComposeOnBoot = TRUE;
|
|
fDirectComp = TRUE;
|
|
pstrDirectComp = ZMMakeStr ( pArgSt->pAliasList );
|
|
fNewmailOnSend = FALSE;
|
|
}
|
|
if ( pTmp = EnvOrIni ( NULL, 0L, "VERSION", strWZMAIL ))
|
|
{
|
|
if ( strcmpis ( pTmp, pVersion ) )
|
|
fNotifyTools |= F_NEWVERSION;
|
|
ZMfree ( pTmp );
|
|
}
|
|
|
|
#if defined (HEAPCRAP)
|
|
pTmp = AppendStr ( DefDirectory, strHEAPDUMP, NULL, FALSE );
|
|
if ( !stat ( pTmp, &statBuf ) && statBuf.st_size > 0 ) {
|
|
fNotifyTools |= F_SENDHEAPDUMP;
|
|
fpHeapDump = NULL;
|
|
}
|
|
else
|
|
/* leave fpHeapDump open in case we need to dump heap
|
|
*/
|
|
fhErr = fileno ( fpHeapDump = fopen ( pTmp, "wb" ) );
|
|
ZMfree ( pTmp );
|
|
#endif
|
|
|
|
|
|
pTmp = ( *( pArgSt->pMfldLoad ) ?
|
|
ExpandFilename ( pArgSt->pMfldLoad, strFLD ) : ZMMakeStr ( DefMailbox ) );
|
|
|
|
if ( !pTmp )
|
|
ZMexit ( 1, strINVALIDFLDSPEC );
|
|
if ( ( fh = getfolder ( pTmp, FLD_SPEC, FLD_READWRITE ) ) == ERROR ) {
|
|
if ( fConfirmNewFld ) {
|
|
fprintf ( stderr,
|
|
"Mailfolder %s does not exist\nType 'y' to create it. ", pTmp );
|
|
fCreateFld = ReadChar () == 'y';
|
|
}
|
|
else
|
|
fCreateFld = TRUE;
|
|
if ( fCreateFld ) {
|
|
fprintf ( stderr, "\nCreating mailfolder ...\n" );
|
|
if ( ( fh = getfolder ( pTmp, FLD_CREATE, FLD_READWRITE ) ) == ERROR ) {
|
|
FreeLock ( );
|
|
ZMexit ( 1, "Unable to create mailfolder" );
|
|
}
|
|
}
|
|
else {
|
|
FreeLock ( );
|
|
ZMexit ( 1, NULL );
|
|
}
|
|
}
|
|
putfolder ( fh );
|
|
SetUpScreen ( pArgSt->DebugWin );
|
|
fSetBox ( pTmp, DFRNTFLD );
|
|
ZMfree ( pTmp );
|
|
|
|
if ( pArgSt->LoadAlias )
|
|
fNotifyTools |= F_LOADALIAS;
|
|
|
|
Disconnect ( );
|
|
|
|
ZMfree ( pArgSt->pAliasList );
|
|
ZMfree ( pArgSt->pMfldLoad );
|
|
SendMessage (hCommand, DISPLAY, "");
|
|
if (!fNetInstalled ())
|
|
SendMessage (hCommand, DISPLAY, "Network not installed. You are unable to send mail");
|
|
else
|
|
if (DefMailName == NULL)
|
|
SendMessage (hCommand, DISPLAY, "No mail alias defined. You are unable to send mail");
|
|
SendMessage ( hCommand, DISPLAY, "" );
|
|
|
|
return OK;
|
|
}
|
|
|
|
//
|
|
// Control break handler - On CTRL-BREAK, calls ZMexit which will
|
|
// restore the console mode and cursor. Doesn't actaully return
|
|
// from CTRL-BREAK case (exits in ZMexit). Ignores CTRL-C.
|
|
//
|
|
|
|
BOOL
|
|
ctrlHandler (
|
|
ULONG CtrlType
|
|
) {
|
|
|
|
if (CtrlType == CTRL_BREAK_EVENT) {
|
|
ZMexit (0, NULL);
|
|
return (TRUE);
|
|
}
|
|
else {
|
|
return (FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
INT _CRTAPI1 main( SHORT c, char *v[] )
|
|
{
|
|
struct argStruct ArgData;
|
|
INT i;
|
|
|
|
ConvertAppToOem( c, v );
|
|
#ifdef NT
|
|
|
|
if (!SetConsoleCtrlHandler ( ctrlHandler, TRUE )) {
|
|
ZMexit ( 1, "Unable to register break handler");
|
|
}
|
|
initConsoleHandles ( );
|
|
|
|
#endif
|
|
|
|
|
|
/* The following is needed since the change to vector implementation
|
|
* changed from unsigned to void * (correctly, mind you) but we do
|
|
* too much overloading of unsigned in this &(%*&^$ code.
|
|
*
|
|
* PORTABILITY NOTE: Until the NT environment tools change the type
|
|
* of vectors to void *, we need a portable VECTYPE type
|
|
* (conditionally #defined in wzport.h).
|
|
*/
|
|
if ((sizeof (VECTYPE) < sizeof (INT)) || (sizeof (VECTYPE) < sizeof (PCHAR))) {
|
|
printf ("VECTOR implementation at risk\n");
|
|
exit (1);
|
|
}
|
|
|
|
|
|
ToRaw ( );
|
|
if ( ( i = KBOpen() ) ) {
|
|
fprintf ( stderr, "KBOpen error: %d\n" );
|
|
ZMexit ( 1, NULL );
|
|
}
|
|
/* signal ( SIGINT, SIG_IGN ); */
|
|
mt_alloc = dh_alloc = tools_alloc = ZMalloc;
|
|
dh_free = ZMfree;
|
|
|
|
pFirstNode = ZMalloc ( 1 ); /* use for assertion checking */
|
|
if ( StartUpZM ( *v, ArgParse ( c, v, &ArgData ) ) == ERROR )
|
|
ZMexit ( 1, NULL );
|
|
|
|
hFocus = hHeaders;
|
|
KeyManager ( );
|
|
|
|
if ( !fDirectComp ) {
|
|
if ( hHeaders != NULL )
|
|
CloseBox ( fExpungeOnQuit );
|
|
}
|
|
ZMDisconnect ( );
|
|
CloseAllWindows ( );
|
|
|
|
ZMexit ( 0, NULL );
|
|
return (0);
|
|
}
|
|
|
|
VOID PASCAL INTERNAL ZMexit ( INT i, PSTR pMsg )
|
|
{
|
|
if ( UsrPassWrd )
|
|
memset(UsrPassWrd, 'x', strlen(UsrPassWrd) + 1);
|
|
if ( !i )
|
|
FreeLock ( );
|
|
if ( fScreenSetup ) {
|
|
|
|
#ifdef NT
|
|
ClearScrn (attrInit, ySize);
|
|
#else
|
|
if ( strcmpis ( NameVideoState ( dosVShandle ), "VIKING" ) )
|
|
ClearScrn ( attrInit, ySize );
|
|
#endif
|
|
|
|
cursor ( 0, 0 );
|
|
SetVideoState ( dosVShandle );
|
|
}
|
|
ToCooked ( );
|
|
cursorVisible ( );
|
|
if ( pMsg )
|
|
fprintf ( stderr, "%s\n", pMsg );
|
|
exit ( i );
|
|
}
|
|
|
|
/*** SetMaxPasswordAge - sets lPasswordAge to the time specified
|
|
*
|
|
* Arguments: none
|
|
*
|
|
* Uses: pszPasswordAge - pointer to string of format [[H:]M:]S
|
|
* where H,M,S are integers
|
|
* lPasswordAge - maximum password age in seconds
|
|
*
|
|
* Effects: lPasswordAge is set to the specified amount of time.
|
|
* If time specified is more than 12 hours or less than 1
|
|
* second, the default of 6 hours will be used.
|
|
*
|
|
* Note: as an example, 10 hours may be specified as any of the following:
|
|
*
|
|
* 10:00:00 600:00 36000
|
|
*
|
|
* hours minutes seconds
|
|
*
|
|
*/
|
|
void PASCAL INTERNAL SetMaxPasswordAge(void)
|
|
{
|
|
LONG lAgePart;
|
|
PSTR pszRest, pszLastRest;
|
|
INT i;
|
|
|
|
lPasswordAge = 0L;
|
|
pszRest = pszLastRest = pszPasswordAge;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
lAgePart = strtol(pszLastRest, &pszRest, 10);
|
|
if (pszRest != pszLastRest) {
|
|
lPasswordAge = lPasswordAge * 60 + lAgePart;
|
|
if (*pszRest != ':')
|
|
break;
|
|
pszLastRest = pszRest += 1;
|
|
}
|
|
}
|
|
|
|
if (lPasswordAge < 1 || lPasswordAge > 43200) //incorrect time maps
|
|
lPasswordAge = 21600; //to 6 hour default
|
|
}
|
|
|