home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_mail
/
bsrc_250.arj
/
FTSC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
25KB
|
801 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 FTSC Mail Session 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"
#define rb_plus "r+b"
int FTSC_callback (char *);
int FTSC_time (long);
int FTSC_sendmail (void);
int FTSC_recvmail (int);
#define NUM_FLAGS 4
void FTSC_sender (int wz)
{
int j;
char junkbuff[128];
long t1;
XON_DISABLE ();
first_block = 0;
if (!wz)
{
first_block = 1;
status_line (MSG_TXT(M_SEND_FALLBACK));
who_is_he = 0;
(void) sprintf (junkbuff, "*%s (%s)",
newnodedes.SystemName,
Full_Addr_Str (&remote_addr));
status_line (junkbuff);
}
Netmail_Session = 1;
(void) FTSC_sendmail ();
t1 = timerset (4500);
/* See what the receiver would like us to do */
while ((!timeup (t1)) && CARRIER)
{
if ((j = PEEKBYTE ()) >= 0)
{
switch (j)
{
case TSYNC:
CLEAR_INBOUND ();
if (FTSC_recvmail (1))
goto get_out;
t1 = timerset (4500);
break;
case SYN:
CLEAR_INBOUND ();
if (on_our_nickel)
(void) SEA_recvreq ();
else
{
SENDBYTE (CAN);
status_line (MSG_TXT(M_REFUSING_IN_FREQ));
}
t1 = timerset (4500);
break;
case ENQ:
CLEAR_INBOUND ();
SEA_sendreq ();
goto get_out;
case NAK:
case 'C':
CLEAR_INBOUND ();
SENDBYTE (EOT);
t1 = timerset (4500);
break;
default:
CLEAR_INBOUND ();
SENDBYTE (SUB);
break;
}
}
else
{
time_release ();
}
}
if (!CARRIER)
{
status_line (MSG_TXT(M_NO_CARRIER));
CLEAR_INBOUND ();
first_block = 0;
return;
}
if (timeup (t1))
{
(void) FTSC_recvmail (1);
status_line (MSG_TXT(M_TOO_LONG));
}
get_out:
first_block = 0;
t1 = timerset (100);
while (!timeup (t1))
time_release ();
if (!wz)
status_line (MSG_TXT(M_0001_END));
}
int FTSC_receiver (int wz)
{
char fname[64];
int havemail, done, np;
unsigned int i;
long t1, t2;
struct stat buf;
char *HoldName;
struct FILEINFO dta;
ADDR tmp;
first_block = 0;
XON_DISABLE ();
if (!wz)
{
first_block = 1;
status_line (MSG_TXT(M_RECV_FALLBACK));
who_is_he = 1;
}
Netmail_Session = 1;
CLEAR_INBOUND ();
/* Save the state of pickup for now */
done = no_pickup;
no_pickup = 0;
if (FTSC_recvmail (0))
{
/* Restore the state of pickup */
no_pickup = done;
if (!wz)
status_line (MSG_TXT(M_0001_END));
first_block = 0;
return (1);
}
/* Restore the state of pickup */
no_pickup = done;
remote_addr = called_addr;
HoldName = HoldAreaNameMunge(&called_addr);
/* Now see if we should send anything back to him */
(void) sprintf (fname, "%s%s.?UT", HoldName, Hex_Addr_Str (&remote_addr));
havemail = !dfind (&dta, fname, 0);
if (!havemail)
{
(void) sprintf (fname, "%s%s.?LO", HoldName, Hex_Addr_Str (&remote_addr));
havemail = !dfind (&dta, fname, 0);
}
if (!havemail)
{
for (np = 0; np <= ALIAS_CNT; np++)
{
if (alias[np].Net == 0)
break;
(void) sprintf (fname, "%s%s.REQ", CURRENT.sc_Inbound, Hex_Addr_Str (&(alias[np])));
havemail = !dfind (&dta, fname, 0);
if (havemail)
break;
}
}
if (!havemail)
{
status_line (MSG_TXT(M_NOTHING_TO_SEND), Full_Addr_Str (&remote_addr));
}
else
{
/* OS/2 likes this */
while (!dfind (&dta, NULL, 1))
;
status_line (MSG_TXT(M_GIVING_MAIL), Full_Addr_Str (&remote_addr));
/* Send the TSYNC's until we get a C or NAK or CAN back */
t1 = timerset (3000); /* set 30 second timeout */
done = 0;
while (!timeup (t1) && CARRIER && !done) /* till then or CD lost */
{
SENDBYTE (TSYNC);
t2 = timerset (300);
while (CARRIER && (!timeup (t2)) && !done)
{
switch (TIMED_READ (0))
{
case 'C':
case NAK:
done = 1;
(void) FTSC_sendmail ();
break;
case CAN:
done = 1;
status_line (MSG_TXT(M_REFUSE_PICKUP), Full_Addr_Str (&remote_addr));
break;
default:
time_release ();
}
}
}
}
first_block = 0;
if (wz)
return TRUE; /* All done if this is WaZOO */
/* Now see if we want to request anything */
tmp = remote_addr;
/* For a point, massage the address to get the right .REQ filename */
if (tmp.Point != 0)
{
tmp.Node = tmp.Point;
tmp.Point = 0;
tmp.Net = (pvtnet > 0) ? (unsigned int) pvtnet : 0;
}
(void) sprintf (fname, "%s%s.REQ", HoldName, Hex_Addr_Str (&tmp));
if (!stat (fname, &buf))
{
/* Send the SYN character and wait for an ENQ or CAN */
t1 = timerset (3000); /* set 30 second timeout */
done = 0;
while (!timeup (t1) && CARRIER && !done) /* till then or CD lost */
{
SENDBYTE (SYN);
t2 = timerset (500);
while (CARRIER && (!timeup (t2)) && !done)
{
i = (unsigned) TIMED_READ (0);
switch (i)
{
case ENQ:
SEA_sendreq ();
break;
case CAN:
done = 1;
break;
case 'C':
case NAK:
SENDBYTE (EOT);
break;
case SUB:
SENDBYTE (SYN);
break;
default:
time_release ();
}
}
}
}
/* Finally, can he request anything from us */
if (!no_requests)
(void) SEA_recvreq ();
status_line (MSG_TXT(M_0001_END));
return TRUE;
}
int FTSC_sendmail ()
{
FILE *fp;
char fname[80];
char s[80];
char *sptr;
char *HoldName;
int c;
int i;
int j = 0;
struct stat buf;
struct _pkthdr *tmppkt;
time_t t1;
struct tm *tm1;
XON_DISABLE ();
sptr = s;
/*--------------------------------------------------------------------*/
/* Send all waiting ?UT files (mail packets) */
/*--------------------------------------------------------------------*/
*ext_flags = 'O';
HoldName = HoldAreaNameMunge(&called_addr);
for (c = 0; c < NUM_FLAGS; c++)
{
#ifndef JACK_DECKER
if (caller && (ext_flags[c] == 'H'))
continue;
#endif
(void) sprintf (fname,
"%s%s.%cUT",
HoldName, Hex_Addr_Str (&called_addr), ext_flags[c]);
if (!stat (fname, &buf))
break;
} /* for */
/*--- Build a dummy PKT file name */
invent_pkt_name (s);
status_line (MSG_TXT(M_PACKET_MSG));
if (c == NUM_FLAGS)
{
(void) sprintf (fname,
"%s%s.OUT",
HoldName, Hex_Addr_Str (&called_addr));
if ((fp = fopen (fname, "wb")) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), fname);
return (1);
}
t1 = time (NULL);
tm1 = localtime (&t1);
tmppkt = (struct _pkthdr *) calloc (1, sizeof (struct _pkthdr));
if (tmppkt == NULL)
{
status_line (MSG_TXT(M_MEM_ERROR));
(void) fclose (fp);
return (1);
}
tmppkt->orig_node = (int) alias[assumed].Node;
tmppkt->dest_node = called_addr.Node;
tmppkt->ver = PKTVER;
tmppkt->orig_net = (int) alias[assumed].Net;
tmppkt->dest_net = called_addr.Net;
tmppkt->product = PRDCT_CODE;
if (n_getpassword (&called_addr))
{
if (remote_password != NULL)
{
(void) strupr (remote_password);
(void) strncpy ((char *) (tmppkt->password), remote_password, 8);
}
}
tmppkt->orig_zone = (int) alias[assumed].Zone;
tmppkt->dest_zone = called_addr.Zone;
if (((called_addr.Domain != NULL)
&& (called_addr.Domain != alias[assumed].Domain)
&& (my_addr.Domain != NULL))
|| (alias[assumed].Point != 0))
{
/* Make it a type 2.2 packet instead */
tmppkt->year = alias[assumed].Point;
tmppkt->month = called_addr.Point;
tmppkt->day = 0;
tmppkt->hour = 0;
tmppkt->minute = 0;
tmppkt->second = 0;
tmppkt->rate = 2;
if (alias[assumed].Domain != NULL)
{
for (i = 0; domain_name[i] != NULL; i++)
{
if (domain_name[i] == alias[assumed].Domain)
{
break;
}
}
if (i < 49)
{
(void) strncpy ((char *)tmppkt->B_fill2, domain_abbrev[i], 8);
}
}
for (i = 0; domain_name[i] != NULL; i++)
{
if (domain_name[i] == called_addr.Domain)
{
break;
}
}
if ((i < 49) && (domain_name[i] != NULL))
{
(void) strncpy ((char *)&(tmppkt->B_fill2[8]), domain_abbrev[i], 8);
}
}
else
{
tmppkt->year = tm1->tm_year;
tmppkt->month = tm1->tm_mon;
tmppkt->day = tm1->tm_mday;
tmppkt->hour = tm1->tm_hour;
tmppkt->minute = tm1->tm_min;
tmppkt->second = tm1->tm_sec;
tmppkt->rate = 0;
}
(void) fwrite ((char *) tmppkt, sizeof (struct _pkthdr), 1, fp);
free (tmppkt);
(void) fwrite ("\0\0", 2, 1, fp);
(void) fclose (fp);
}
else
{
if ((fp = fopen (fname, rb_plus)) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), fname);
return (1);
}
tmppkt = (struct _pkthdr *) calloc (1, sizeof (struct _pkthdr));
if (tmppkt == NULL)
{
status_line (MSG_TXT(M_MEM_ERROR));
return (1);
}
if (fread (tmppkt, 1, sizeof (struct _pkthdr), fp) < sizeof (struct _pkthdr))
{
(void) got_error (MSG_TXT(M_READ_MSG), fname);
free (tmppkt);
(void) fclose (fp);
return (1);
}
if (n_getpassword (&called_addr))
{
if (remote_password != NULL)
{
(void) strupr (remote_password);
(void) strncpy ((char *) (tmppkt->password), remote_password, 8);
}
}
/* Make sure the zone info is in there */
tmppkt->orig_node = (int) alias[assumed].Node;
tmppkt->orig_net = (int) alias[assumed].Net;
tmppkt->orig_zone = (int) alias[assumed].Zone;
tmppkt->dest_zone = called_addr.Zone;
if ((called_addr.Domain != NULL) &&
(called_addr.Domain != alias[assumed].Domain) &&
(my_addr.Domain != NULL))
{
/* Make it a type 2.2 packet instead */
tmppkt->year = alias[assumed].Point;
tmppkt->month = called_addr.Point;
tmppkt->day = 0;
tmppkt->hour = 0;
tmppkt->minute = 0;
tmppkt->second = 0;
tmppkt->rate = 2;
if (alias[assumed].Domain != NULL)
{
for (i = 0; domain_name[i] != NULL; i++)
{
if (domain_name[i] == alias[assumed].Domain)
{
break;
}
}
if (i < 49)
{
(void) strncpy ((char *)tmppkt->B_fill2, domain_abbrev[i], 8);
}
}
for (i = 0; domain_name[i] != NULL; i++)
{
if (domain_name[i] == called_addr.Domain)
{
break;
}
}
if (i < 49)
{
(void) strncpy ((char *)&(tmppkt->B_fill2[8]), domain_abbrev[i], 8);
}
}
(void) fseek (fp, 0L, SEEK_SET);
(void) fwrite (tmppkt, 1, sizeof (struct _pkthdr), fp);
(void) fclose (fp);
free (tmppkt);
}
net_problems = (no_sealink) ? Telink_Send_File (fname, s) : SEAlink_Send_File (fname, s);
if (net_problems != 0)
{
if (c == NUM_FLAGS)
(void) unlink (fname);
return (net_problems);
}
/* Delete the sent packet */
(void) unlink (fname);
/*--------------------------------------------------------------------*/
/* Send files listed in ?LO files (attached files) */
/*--------------------------------------------------------------------*/
*ext_flags = 'F';
status_line (" %s %s", MSG_TXT(M_OUTBOUND), MSG_TXT(M_FILE_ATTACHES));
if (!do_FLOfile (ext_flags, FTSC_callback))
return FALSE;
/*--------------------------------------------------------------------*/
/* Send our File requests to other system if it's a WaZOO */
/*--------------------------------------------------------------------*/
if (requests_ok && remote_capabilities)
{
(void) sprintf (fname, request_template, HoldName, Hex_Addr_Str (&called_addr));
if (!stat (fname, &buf))
{
if (!(((unsigned) remote_capabilities) & WZ_FREQ))
status_line (MSG_TXT(M_FREQ_DECLINED));
else
{
status_line (MSG_TXT(M_MAKING_FREQ));
if (FTSC_callback (fname))
(void) unlink (fname);
}
}
}
/*--------------------------------------------------------------------*/
/* Process WaZOO file requests from other system */
/*--------------------------------------------------------------------*/
j = respond_to_file_requests (j, FTSC_callback, FTSC_time);
/* Now close out the file attaches */
sent_mail = 1;
*sptr = 0;
status_line (" %s %s %s", MSG_TXT(M_END_OF), MSG_TXT(M_OUTBOUND), MSG_TXT(M_FILE_ATTACHES));
(void) Batch_Send (NULL);
return TRUE;
}
int FTSC_recvmail (int outbound_session)
{
char fname[80];
char fname1[80];
char fname2[80];
struct _pkthdr tmppkt;
FILE *fp, *fp1;
int done;
int j;
char *starting_inbound;
status_line (MSG_TXT(M_RECV_MAIL));
if (!CARRIER)
{
status_line (MSG_TXT(M_NO_CARRIER));
CLEAR_INBOUND ();
return (1);
}
XON_DISABLE ();
done = 0;
/* If we don't want to pickup stuff */
if (no_pickup)
{
status_line (MSG_TXT(M_NO_PICKUP));
SENDBYTE (CAN);
}
else
{
status_line (" %s %s", MSG_TXT(M_INBOUND), MSG_TXT(M_MAIL_PACKET));
/* Invent a dummy name for the packet */
invent_pkt_name (fname1);
/* Receive the packet with special netmail protocol */
CLEAR_INBOUND ();
starting_inbound = CURRENT.sc_Inbound;
if (Xmodem_Receive_File (CURRENT.sc_Inbound, fname1) == 0)
{
got_packet = 1;
}
(void) sprintf (fname, "%s%s", starting_inbound, fname1);
/* Check the password if there is one */
if ((!remote_capabilities) &&
(!outbound_session) &&
(n_getpassword (&remote_addr)))
{
if (remote_password != NULL)
{
got_packet = 0;
if ((fp = fopen (fname, rb_plus)) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), fname);
status_line (MSG_TXT(M_PWD_ERR_ASSUMED));
return (1);
}
if (fread (&tmppkt, 1, sizeof (struct _pkthdr), fp) < sizeof (struct _pkthdr))
{
(void) got_error (MSG_TXT(M_OPEN_MSG), fname);
status_line (MSG_TXT(M_PWD_ERR_ASSUMED));
(void) fclose (fp);
return (1);
}
(void) fclose (fp);
if (n_password ((char *) (tmppkt.password), remote_password))
{
tmppkt.orig_zone = 0;
(void) strcpy (fname1, fname);
j = (int) strlen (fname) - 3;
(void) strcpy (&(fname[j]), "Bad");
if (rename (fname1, fname))
{
status_line (MSG_TXT(M_CANT_RENAME_MAIL), fname1);
}
else
{
status_line (MSG_TXT(M_MAIL_PACKET_RENAMED), fname);
}
return (1);
}
}
got_packet = 1;
}
/*
* See if things changed after the fact. If so, we want to move
* the mail packet from the non-secured directory into the
* secured one. This is slightly tricky. Start with a simple rename
* and if that doesn't work (it might not if we're spanning drives)
* do a simple copy/unlink.
*
* Steal resources such as 'done' and 'Secbuf' wherever that makes sense.
*/
if (strcmp (starting_inbound, CURRENT.sc_Inbound) != 0)
{
(void) strcpy (fname2, CURRENT.sc_Inbound);
(void) strcat (fname2, fname1);
/* Try the easy case first. A straight rename. */
done = 1;
if (rename (fname2, fname))
{
/* If we get here, the straight rename didn't work. Let's
* do a copy. Use Secbuf since while we are here, we're
* not doing any file transfers.
*/
done = 0; /* default is failure till files are open */
if ((fp = fopen (fname, rb_plus)) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), fname);
}
else
if ((fp1 = fopen (fname2, "wb")) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), fname2);
}
else /* Here both packets are open */
/* Steal Secbuf because nobody's using it now */
{
done = 1; /* default is success now */
while ((j = fread (Secbuf, 1, WAZOOMAX, fp)) > 0)
{
if (fwrite (Secbuf, j, 1, fp1) != 1)
{
(void) got_error (MSG_TXT(M_WRITE_MSG), fname2);
done = 0; /* only possible failure = write err */
break;
}
}
(void) fclose (fp1);
if (done == 0) /* Figure out which file to delete */
(void) unlink (fname2);
else
(void) unlink (fname);
}
}
if (done == 0)
status_line (MSG_TXT(M_CANT_RENAME_MAIL), fname);
else
status_line (MSG_TXT(M_MAIL_PACKET_RENAMED), fname2);
}
/*
* If this was an inbound session, we need to set up the
* node flags for the node.
*/
got_mail = got_packet;
if (!outbound_session)
{
if (flag_file (TEST_AND_SET, &remote_addr, 1))
return (1);
called_addr = remote_addr;
}
done = 0;
/* Now receive the files if possible */
status_line (" %s %s", MSG_TXT(M_INBOUND), MSG_TXT(M_FILE_ATTACHES));
done = Batch_Receive (CURRENT.sc_Inbound);
}
status_line (" %s %s %s", MSG_TXT(M_END_OF), MSG_TXT(M_INBOUND), MSG_TXT(M_FILE_ATTACHES));
CLEAR_INBOUND ();
return (done);
}
int FTSC_callback (char *sptr)
{
net_problems = Batch_Send (sptr);
if (net_problems != 0)
{
net_problems = 1;
return FALSE;
}
return TRUE;
}
int FTSC_time (long filesize)
{
int i;
i = (int) (filesize * 10 / cur_baud.rate_value * 100 / 94);
return (i);
}