home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_mail
/
bsrc_250.arj
/
MAILER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
30KB
|
877 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/* */
/* */
/* This module was written by Bob Hartman */
/* */
/* */
/* BinkleyTerm Mail Control Routines */
/* */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.250. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
/* P.O. Box 460398 AlterNet 7:491/0 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n343.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
int poll_node (ADDRP);
int call_node (ADDRP, int);
int unattended ()
{
#ifdef MILQ
REGIONP OldCurWin = CurWinSet( callwin );
#endif
int no_inbound = 0;
int j, m;
long init_timer, t = -1L, t1; /* used for the timeouts */
long blank_timer;
struct _key_fnc_hdr *OldKeyFncHdr;
int done = 1; /* if we exit with this,
* get out of BT */
HFILE stream;
USHORT got;
#ifdef MILQ
HWND OldActvAccel = MilqueActvAccel;
HWND OldActvWnd = MilqueActvWnd;
MilqueActvAccel = MilqueMailerAccel;
MilqueActvWnd = MilqueMailerWnd;
SetFocus( MilqueMailerActvWnd );
#endif
un_attended = 1;
clear_statusline ();
comm_bits = BITS_8;
parity = NO_PARITY;
stop_bits = STOP_1;
program_baud ();
OldKeyFncHdr = KbMapSet (&UnattendedKeyFncHdr);
if (fullscreen)
{
screen_clear ();
sb_dirty ();
}
opening_banner ();
if (fullscreen)
{
mailer_banner ();
}
if ((stream = share_open (PRDCT_PRFX ".BAN", O_RDONLY|O_BINARY, DENY_WRITE)) != -1)
{
(void)_dos_read (stream, BBSwelcome, WELCOME_LEN, &got);
(void) close (stream);
}
else
{
BBSwelcome[0] = '\0';
}
/* Initialize the random number generator */
j = (int) time (NULL);
srand ((unsigned int) j);
status_line (MSG_TXT(M_BINK_BEGIN), ANNOUNCE, COMPILER_NAME);
set_xy ("");
set_prior(4); /* Always High */
XON_DISABLE ();
set_prior(2); /* Regular */
/* Turn off forced events */
if (noforce)
{
find_event ();
noforce = 0;
}
if (redo_dynam)
{
for (j = 0; j < num_events; j++)
{
e_ptrs[j].behavior &= ~MAT_SKIP;
}
redo_dynam = 0;
}
/*
* See if we should exit before initializing the modem (and therefore
* possibly letting a call sneak through)
*/
find_event ();
do_ready (MSG_TXT(M_READY_INIT));
/* Make sure we have all necessary parameters and that the nodelist
* index gets read in. If not, then we must exit right now.
*/
if (!net_params || !nodefind (&boss_addr, 0))
if (boss_addr.Net != 0xffff)
{
status_line (MSG_TXT(M_MISCONFIGURED));
errl_exit (254);
}
/* Set up outbound mail */
list_next_event ();
set_up_outbound ();
if (!CARRIER)
{
mdm_init (modem_init); /* Reinit modem */
}
blank_timer = timerset ((unsigned int)blank_time);/* Set a timer */
init_timer = timerset ((unsigned int)60000); /* Set a 10 minute timer */
t1 = timerset ((unsigned) next_minute ()); /* Set a 1 minute timer */
waitfor_line = timerset ((unsigned int)6000); /* no collisions for 1 min*/
top_of_mail:
un_attended = 1;
no_inbound = 0;
m = 1;
/* As long as we don't press a key */
bad_char:
more_mail = 1;
while (!(KEYPRESS () || ctrlc_ctr))
{
find_event ();
#ifdef MILQ
if ( hold_hWnd != GetFocus() )
SendMessage( node_hWnd, WM_COMMAND, GD_LAST, (long)&hist.last_addr );
#endif
/* Show that we are ready */
if (m)
{
if (fullscreen)
{
do_ready (MSG_TXT(M_READY_WAITING));
list_next_event ();
}
else
status_line (MSG_TXT(M_EVENT_WAITING), cur_event + 1);
blank_timer = timerset ((unsigned int)blank_time);/* Set a timer */
init_timer = timerset ((unsigned int)60000);/* Set a 10 min timer */
t1 = timerset ((unsigned) next_minute ()); /* Set a 1 min timer */
}
if (timeup (t1))
{
put_up_time ();
list_next_event ();
t1 = timerset ((unsigned) next_minute ()); /* Set a 1 min timer */
}
/* See if blanking interval has elapsed */
if (timeup (blank_timer))
{
blank_timer = timerset ((unsigned int)blank_time);
screen_blank = 1;
if (fullscreen)
sb_show ();
}
/* If we haven't gotten anything in 10 minutes, re-init the modem */
if (timeup (init_timer))
{
mdm_init (modem_init);
init_timer = timerset ((unsigned int)60000); /* Set a 10 minute timer */
/*
* Say that we have more mail so that things entered through other
* side of a multi-tasker will still go out
*/
set_up_outbound ();
more_mail = 1;
}
m = 0;
if (cur_event >= 0)
no_inbound = (e_ptrs[cur_event].behavior & MAT_OUTONLY);
else
no_inbound = 1;
if (t != -1L)
t = random_time ((cur_event >= 0) ? e_ptrs[cur_event].wait_time : 5);
else
t = timerset (1000);
/* variable 'no_inbound' will be TRUE if we are manually dialing out
* or if we are in an event where we do not want incoming stuff.
*/
while ((!timeup (t)) && (!KEYPRESS ()) && (m == 0) && !ctrlc_ctr)
{
find_event ();
time_release ();
if (timeup (t1))
{
put_up_time ();
list_next_event ();
t1 = timerset ((unsigned) next_minute ());/* Set a 1 min timer*/
}
/* If we want inbound, see if there is any. If we send
anything, clean up afterwards ... */
if (!no_inbound)
{
m = handle_inbound_mail (0);
if (m)
xmit_sameplace ();
}
}
if ((m) && (fullscreen))
{
do_ready (MSG_TXT(M_READY_WAITING));
list_next_event ();
}
immed_call:
find_event ();
/* If we have pressed a key, get out */
if (KEYPRESS () || ctrlc_ctr)
break;
/* If we are not in an event, or if this is a no-outbound
event, loop again */
if ((cur_event < 0) || (e_ptrs[cur_event].behavior & MAT_NOOUT))
{
time_release ();
continue;
}
if (more_mail)
more_mail = xmit_next (&next_addr);
if (more_mail)
m = call_node (&next_addr, no_inbound);
else
{
/* No more mail to do, was it dynamic? */
if (e_ptrs[cur_event].behavior & MAT_DYNAM)
{
if (!blank_on_key)
screen_blank = 0;
e_ptrs[cur_event].behavior |= MAT_SKIP;
status_line (":%s %s %d", MSG_TXT(M_END_OF), MSG_TXT(M_DYNAMIC_EVENT), cur_event + 1);
t = -1L;
goto top_of_mail;
}
}
}
screen_blank = 0;
if (fullscreen)
sb_show ();
/* Eat the character we pressed */
if (ctrlc_ctr || !KEYPRESS ())
{
/*
* Be serious, there had to be a key pressed or we wouldn't be here I
* know it sounds silly, but ^C will sometimes do crap like this
*/
status_line (MSG_TXT(M_EXIT_REQUEST));
}
else
{
blank_timer = timerset ((unsigned int)blank_time);/* Set a timer */
j = (int) KbRemap (FOSSIL_CHAR ());
if (((unsigned)j & F_UN_BASE) == F_UN_BASE)
switch ((unsigned)j)
{
case F_UN_FUNKEY1:
case F_UN_FUNKEY2:
case F_UN_FUNKEY3:
case F_UN_FUNKEY4:
case F_UN_FUNKEY5:
case F_UN_FUNKEY6:
case F_UN_FUNKEY7:
case F_UN_FUNKEY8:
case F_UN_FUNKEY9:
case F_UN_FUNKEY10:
j = 1 + (int)((unsigned) j - (unsigned)F_UN_FUNKEY1);
status_line (MSG_TXT(M_FUNCTION_KEY), j * 10);
errl_exit (j * 10);
break;
case F_UN_BLANKSCREEN:
screen_blank = 1;
if (fullscreen)
sb_show ();
break;
case F_UN_CLEARHIST:
j = hist.which_day;
(void) memset (&hist, 0, sizeof (HISTORY));
hist.which_day = j;
if (fullscreen)
{
do_today ();
sb_show ();
}
break;
case F_UN_MSGEDITOR:
if (BBSreader != NULL)
{
vfossil_cursor (1);
status_line (MSG_TXT(M_DISABLE_MODEM));
mdm_init (modem_busy);
exit_DTR ();
status_line (MSG_TXT(M_BEGIN_MESSAGE_READER));
vfossil_close ();
b_spawn (BBSreader);
vfossil_init ();
if (fullscreen)
{
screen_clear ();
sb_dirty ();
opening_banner ();
mailer_banner ();
}
status_line (MSG_TXT(M_END_MESSAGE_READER));
set_up_outbound ();
m = 1;
more_mail = 1;
status_line (MSG_TXT(M_ENABLE_MODEM));
RAISE_DTR ();
mdm_init (modem_init);
waitfor_line = timerset ((unsigned int)6000);
}
else
{
set_xy (NULL);
status_line (MSG_TXT(M_NO_MESSAGE_READER));
set_xy (NULL);
m = 1;
}
break;
case F_UN_GETFILE:
if (sb_popup (10, 10, 7, 60, Do_Get, 0))
{
status_line (MSG_TXT(M_NO_GET));
}
else
{
set_up_outbound ();
m = 1;
more_mail = 1;
}
break;
case F_UN_REINITMODEM:
/* The idea for this code came from Holger Schurig */
mdm_hangup ();
set_up_outbound ();
m = 1;
more_mail = 1;
break;
case F_UN_SHELL:
status_line (MSG_TXT(M_SHELLING));
if (fullscreen)
gotoxy (0, SB_ROWS);
vfossil_cursor (1);
(void) cputs (MSG_TXT(M_TYPE_EXIT));
LOWER_DTR ();
change_prompt ();
b_spawn (NULL);
if (fullscreen)
{
screen_clear ();
sb_dirty ();
opening_banner ();
mailer_banner ();
}
status_line (MSG_TXT(M_BINKLEY_BACK));
m = 1;
set_up_outbound ();
set_prior(4); /* Always High */
RAISE_DTR ();
set_prior(2); /* Regular */
break;
case F_UN_KILLNODESMAIL:
if (sb_popup (10, 5, 4, 70, Do_Kill, 0))
{
status_line (MSG_TXT(M_NO_KILL));
}
else
{
set_up_outbound ();
m = 1;
more_mail = 1;
}
break;
case F_UN_POLLBOSS:
(void) poll_node (&boss_addr);
m = 1;
break;
case F_UN_ANSWER:
if (ans_str != NULL)
mdm_cmd_string (ans_str, 0);
break;
case F_UN_POLLNODE:
(void) poll_node ((ADDRP)NULL);
m = 1;
break;
case F_UN_QUITTHISEVENT:
if (cur_event >= 0)
e_ptrs[cur_event].behavior |= MAT_SKIP;
goto top_of_mail;
case F_UN_RESTARTEVENTS:
for (j = 0; j < num_events; j++)
{
/* Don't redo forced events */
if (!(e_ptrs[j].behavior & MAT_FORCED))
{
e_ptrs[j].last_ran = (char)-1;
e_ptrs[j].behavior &= ~MAT_SKIP;
}
}
goto top_of_mail;
case F_UN_SENDFILE:
if (sb_popup (10, 5, 6, 70, Do_Send, 0))
{
status_line (MSG_TXT(M_NO_SEND));
}
else
{
set_up_outbound ();
m = 1;
more_mail = 1;
}
break;
case F_UN_TERMINALMODE:
status_line (MSG_TXT(M_ENTER_TERMINAL_MODE));
done = 0; /* We won't exit now */
goto mail_done;
case F_UN_REPAINTSCREEN:
if (fullscreen)
{
screen_clear ();
sb_dirty ();
sb_show ();
}
break;
case F_UN_HELPSCREEN:
mailer_help ();
if (fullscreen)
{
screen_clear ();
sb_dirty ();
opening_banner ();
mailer_banner ();
}
m = 1;
break;
case F_UN_EXITBINK:
status_line (MSG_TXT(M_EXIT_REQUEST));
goto mail_done;
case F_UN_SHELL1:
case F_UN_SHELL2:
case F_UN_SHELL3:
case F_UN_SHELL4:
case F_UN_SHELL5:
case F_UN_SHELL6:
case F_UN_SHELL7:
case F_UN_SHELL8:
case F_UN_SHELL9:
j = (int) ((unsigned) j - (unsigned)F_UN_SHELL1);
if (shells[j] != NULL)
{
status_line (MSG_TXT(M_KEYBOARD_SHELL), j + 1);
mdm_init (modem_busy);
exit_DTR ();
close_up ();
vfossil_cursor (1);
b_spawn (shells[j]);
come_back ();
m = 1;
status_line (MSG_TXT(M_END_KEYBOARD_SHELL));
screen_clear ();
if (fullscreen)
sb_dirty ();
opening_banner ();
mailer_banner ();
set_up_outbound ();
RAISE_DTR ();
mdm_init (modem_init);
waitfor_line = timerset ((unsigned int)6000);
}
else
status_line (MSG_TXT(M_NO_KEYBOARD_SHELL), j + 1);
break;
case F_PEND_PGUP:
if (next_mail == NULL)
{
next_mail = mail_top;
}
if (next_mail != NULL)
{
for (j = 0; j < SB_ROW_HOLD; j++)
{
if (next_mail->prev != NULL)
next_mail = next_mail->prev;
}
xmit_window (next_mail);
}
break;
case F_PEND_PGDN:
if (next_mail == NULL)
{
next_mail = mail_top;
}
if (next_mail != NULL)
{
for (j = 0; j < SB_ROW_HOLD; j++)
{
if (next_mail->next != NULL)
next_mail = next_mail->next;
}
xmit_window (next_mail);
}
break;
case F_PEND_UPAR:
if (next_mail == NULL)
{
next_mail = mail_top;
}
if (next_mail != NULL)
{
if (next_mail->prev != NULL)
next_mail = next_mail->prev;
xmit_window (next_mail);
}
break;
case F_PEND_DNAR:
if (next_mail == NULL)
{
next_mail = mail_top;
}
if (next_mail != NULL)
{
if (next_mail->next != NULL)
next_mail = next_mail->next;
xmit_window (next_mail);
}
break;
case F_PEND_HOME:
next_mail = mail_top;
xmit_window (next_mail);
break;
case F_PEND_END:
if (next_mail == NULL)
{
next_mail = mail_top;
}
if (next_mail != NULL)
{
while (next_mail->next != NULL)
{
next_mail = next_mail->next;
}
}
for (j = 0; j < (SB_ROW_HOLD - 1); j++)
{
if (next_mail->prev != NULL)
next_mail = next_mail->prev;
}
xmit_window (next_mail);
break;
case F_UN_CALLRIGHTNOW:
if (cur_event >= 0)
if (e_ptrs[cur_event].behavior & MAT_NOOUT)
{
status_line (MSG_TXT(M_NO_CALLS_NOW));
goto immed_call;
}
status_line (MSG_TXT(M_IMMEDIATE_CALL));
m = 0;
more_mail = 1;
goto immed_call;
default:
status_line (MSG_TXT(M_JUNK_CHARACTER));
m = 1;
break;
}
else
switch (toupper (j & 0xff))
{
case 3:
status_line (MSG_TXT(M_EXIT_REQUEST));
goto mail_done;
case 0x20:
m = 1;
break;
default:
status_line (MSG_TXT(M_JUNK_CHARACTER));
m = 1;
break;
}
goto bad_char;
}
mail_done:
write_sched ();
status_line (MSG_TXT (M_BINK_END), ANNOUNCE, COMPILER_NAME);
un_attended = 0;
if (fullscreen)
{
gotoxy (0, SB_ROWS);
}
set_prior(4); /* Always High */
XON_ENABLE ();
set_prior(2); /* Regular */
(void) KbMapSet(OldKeyFncHdr);
#ifdef MILQ
MilqueActvAccel = OldActvAccel;
MilqueActvWnd = OldActvWnd;
MilqueMailerActvWnd = GetFocus();
CurWinSet( OldCurWin );
#endif
return (done);
}
/*
* Poll a node. If address is supplied, use it. Otherwise,
* make a popup and ask for it.
*/
int poll_node (ADDRP address)
{
int m;
char jbuf[90];
if (address == (ADDRP)NULL)
{
status_line (MSG_TXT(M_POLL_MODE));
if (!fullscreen)
{
scr_printf ("\r\n");
clear_eol ();
scr_printf (MSG_TXT(M_ENTER_NET_NODE));
m = get_number (jbuf);
if (m)
{
m = find_address (jbuf, &next_addr);
}
if (!(m >= 1 && nodefind (&next_addr, 1)))
return (-1);
}
else
if (!sb_popup (10, 10, 4, 60, Do_Poll, 0))
{
status_line (MSG_TXT(M_POLL_COMPLETED));
return (-1);
}
}
else
next_addr = *address;
doing_poll = 1;
if (fullscreen)
{
sprintf( junk,
"%s %s",
MSG_TXT(M_CURRENTLY_POLLING),
Full_Addr_Str( &next_addr ) );
sb_move (file_hWnd, 1, 2);
FlLnModeSet( FILE_LN_1, 0 );
sb_puts( GetDlgItem( file_hWnd, FILE_LN_1 ), junk );
}
set_prior(4); /* Always High */
if ((do_mail (&next_addr, 1) == 1) && sent_mail)
{
next_mail = find_mail (&next_addr);
(void) bad_call (&next_addr, -1);
xmit_delete ();
}
set_prior(2); /* Regular */
doing_poll = 0;
status_line (MSG_TXT(M_POLL_COMPLETED));
if (fullscreen)
{
mailer_banner ();
clear_filetransfer ();
}
RAISE_DTR ();
mdm_init (modem_init);
return (0);
}
/*
* Call a node. If we get through, do call accounting. If
* we have a dialout collision, try to get the inbound.
*/
int call_node (ADDRP address, int no_inbound)
{
MAILP mp;
int m;
/* save the next call in the list in case we exit */
if ((next_mail == NULL) || (next_mail->next == NULL))
{
mp = mail_top;
}
else
{
mp = next_mail->next;
}
hist.next_addr = mp->mail_addr;
/* If this is a CM call, tell do_mail not to pay
attention to the nodelist flags! */
if ((e_ptrs[cur_event].behavior & (MAT_CM | MAT_HIPRICM))
&& (next_mail->mailtypes & MAIL_CRASH))
m = -1;
else m = 0;
set_prior(4); /* Always High */
m = do_mail (address, m);
set_prior(2); /* Regular */
/*
* If there was a session, handle bad-call accounting
* based on whether the session was a complete success
* or not. Then take an exit if appropriate, based on
* what actually arrived here.
*/
if (m > 0)
{
if (m == 1) /* There was a good session */
{
if (!sent_mail)
{
/* We connected but the transfer didn't work */
(void) bad_call (address, 1);
}
else
{
/* We got through, so delete his status file */
(void) bad_call (address, -1);
xmit_delete ();
}
}
if (m == 2) /* Nothing happened */
(void) bad_call (address, 2);
/* Take an exit if we got something in */
if (got_arcmail || got_packet || got_mail)
receive_exit ();
mailer_banner ();
}
else if (m < 0)
{
if (m == -1)
status_line (MSG_TXT(M_INCOMING_CALL));
/* Call collision or NO-DIAL-TONE. Try to answer the
call in time to catch the remote. Exception: if it
has been less than a minute since unbusying the line. */
if (!no_inbound && timeup (waitfor_line))
{
m = handle_inbound_mail (1);
if (m)
xmit_sameplace ();
}
}
return (m);
}