home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
VP2SRC.ZIP
/
ARC_E.C
< prev
next >
Wrap
Text File
|
1991-04-24
|
21KB
|
659 lines
/*
$Header: arc_e.c 3.3 87/12/12 00:39:56 Bob Exp $
The Conference Mail System
This module was originally written by Bob Hartman
Sysop of FidoNet node 1:132/101
Spark Software, 427-3 Amherst St, CS 2032, Suite 232, Nashua, NH 03061
The Conference Mail System is a complete Echomail processing package. It
is a superset of the original Echomail utilities created by Jeff Rush, and
also contains ideas gleaned from the ARCmail, Renum, oMMM, MGM, and Opus
programs that were created by various software authors.
This program source code is being released with the following provisions:
1. You are free to make changes to this source code for use on your own
machine, however, altered source files may not be distributed without the
consent of Spark Software.
2. You may distribute "patches" or "diff" files for any changes that you
have made, provided that the "patch" or "diff" files are also sent to Spark
Software for inclusion in future releases of the entire package. A "diff"
file for the source archives may also contain a compiled version, provided
it is clearly marked as not being created from the original source code.
No other executable versions may be distributed without the consent of
Spark Software.
3. You are free to include portions of this source code in any program you
develop, providing: a) Credit is given to Spark Software for any code that
may is used, and b) The resulting program is free to anyone wanting to use
it, including commercial and government users.
4. There is NO technical support available for dealing with this source
code, or the accompanying executable files. This source code is provided
as is, with no warranty expressed or implied (I hate legalease). In other
words, if you don't know what to do with it, don't use it, and if you are
brave enough to use it, you're on your own.
Spark Software may be contacted by modem at (603) 888-8179 (node 1:132/101)
on the public FidoNet network, or at the address given above.
To use this code you will need Microsoft C version 4.0, and also Microsoft
Macro Assembler version 4.0.
*/
/*
$Log: arc_e.c $
* Revision 3.3 87/12/12 00:39:56 Bob
* Source code release
*
*/
#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <process.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "fastecho.h"
#define DEBUG 0
static char *asuffix[] =
{ "SU?", "MO?", "TU?", "WE?", "TH?", "FR?", "SA?", NULL };
extern SEACONFIG config;
extern AREAS_PTR areas[];
extern char board_name[], sysop_name[];
extern int tot_areas;
extern char bbsfile[];
extern char *arc_cmd[];
extern int nread;
extern int arc_args;
extern int last_msg;
extern int high_one;
extern int convert;
extern int dup_size;
extern struct tm *t2;
extern struct _stamp cur_stamp;
extern int pass_thru;
extern int route_thru;
extern int toss_net, toss_node;
extern int num_pw;
extern PW_PTR pw[];
extern int got_a;
extern int kill_null;
int bad_pkt = 0;
int bad_pw = 0;
extern int bad_msgs;
extern int msgs_tossed;
extern WBUFFER wbuffs[];
extern KILLPTR killer;
extern long secs_from_1980();
extern int last_toss_area;
extern int dup_msgs;
extern int dup_file;
extern char dup_name[];
int arcmail ()
{
int i, j, k, l, done;
char archive[80];
char arcname[64];
char cmd[80];
char tnet[5];
char tnode[5];
for (i = 0; asuffix[i]; i++)
{
sprintf (archive, "%s\\*.%s", config.filepath, asuffix[i]);
j = 0;
(void) filedir (archive, j, arcname, 0);
done = 0;
while (arcname[0] != '\0')
{
#if DEBUG
printf ("Got filename '%s' for j = %d\n", arcname, j);
#endif
for (k = 0; k < 8; k++)
{
if (isdigit (arcname[k]) ||
((arcname[k] >= 'A') && (arcname[k] <= 'F')))
{
continue;
}
else
{
done = 1;
break;
}
}
if ((done) || ((i != 7) && (!isalnum(arcname[strlen(arcname)-1]))))
{
#if DEBUG
printf ("Not an arcmail style packet\n");
#endif
done = 0;
++j;
}
else
{
sprintf (cmd, "%s\\%s", config.filepath, arcname);
/* sscanf (arcname, "%04x%04x.", &toss_net, &toss_node); */
sscanf (arcname, "%4s%4s.", tnet, tnode);
sscanf (tnet, "%04x", &toss_net);
sscanf (tnode, "%04x", &toss_node);
toss_net += config.net[1];
toss_node += config.node[1];
printf ("Unpacking packet '%s' from %d/%d\n", cmd, toss_net, toss_node);
strcpy (arc_cmd[arc_args], cmd);
if (spawnvp (P_WAIT, arc_cmd[0], arc_cmd))
{
printf ("\nError while attempting to unARC '%s'\n", cmd);
printf ("If packets were unARC'd, then '%s' will be deleted\n", cmd);
printf ("otherwise it will be left intact for future processing\n");
}
if (tosspkt ("."))
{
printf ("\nNo ARCmail packets from '%s' - ARCHIVE NOT REMOVED!\n", cmd);
++j;
}
else
{
printf ("\nTossing successful - deleting ARCmail packet '%s'\n", cmd);
unlink (cmd);
}
for (l = 0; l < j; l++)
{
(void) filedir (archive, l, arcname, 0);
}
}
(void) filedir (archive, j, arcname, 0);
}
}
return (0);
}
void netit (
MSG_PTR header,
char *holder,
int body_count,
char *netpath,
int *high_one)
{
int f, j;
char junk[80];
#if DEBUG
printf ("in netit() with body_count = %d\n", body_count);
#endif
/* Determine if it is to us */
for (j = 1; j <= config.num_addrs; j++)
{
if ( (config.net[j] == header->dest_net)
&&(config.node[j] == header->dest ))
{
/* It matches one of our addresses! */
break;
}
}
if (j > config.num_addrs)
{
#if DEBUG
printf ("Putting in MSGFWD bit\n");
#endif
header->attr |= MSGFWD;
}
++(*high_one);
sprintf (junk, "%s\\%d.MSG", netpath, *high_one);
#if DEBUG
printf ("attempting to open '%s'\n", junk);
#endif
if ((f = open (junk, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE)) == -1)
{
printf ("Cannot open file '%s' for message. Message lost\n", junk);
return;
}
#if DEBUG
printf ("attempting to write header\n");
#endif
if (write_header (f, header) != sizeof (MSG))
{
printf ("Could not write to file '%s'. Message lost\n", junk);
(void) fast_close (f);
return;
}
#if DEBUG
printf ("attempting to write body\n");
#endif
if (fast_write (f, holder, body_count) != body_count)
{
printf ("Could not write to file '%s'. Message lost\n", junk);
(void) fast_close (f);
return;
}
#if DEBUG
printf ("returning from netit\n");
#endif
(void) fast_close (f);
++msgs_tossed;
return;
}
int unpackpkt (char *pktname)
{
int i, j, foo, foo1, foo2, foo3, v;
int body_count;
char *q1;
char *holder;
char *holder1;
static char header[sizeof(MSG)+10000];
MSG_PTR h;
int f, err;
PKTHDR p;
PACKED p1;
extern last_loc;
/* Read in the Packet header */
if ((f = open (pktname, O_RDONLY|O_BINARY)) == -1)
{
printf ("Could not open packet '%s'\n", pktname);
return (1);
}
#if DEBUG
printf ("Got Packet opened\n");
#endif
if (wbuffs[f].wbuff == NULL)
{
wbuffs[f].wbuff = wbuffs[f].wptr = _fmalloc (BIGSIZE);
if (wbuffs[f].wbuff != NULL)
wbuffs[f].wsize = 0;
}
#if DEBUG
printf ("Got buffer\n"); /*DEBUG*/
#endif
if (fast_read (f, (char *) &p, sizeof (PKTHDR)) != sizeof (PKTHDR))
{
_ffree (wbuffs[f].wbuff);
wbuffs[f].wbuff = wbuffs[f].wptr = NULL;
wbuffs[f].wsize = -1;
(void) fast_close (f);
printf ("Packet '%s' was a short packet\n", pktname);
return (0);
}
#if DEBUG
printf ("Got full header\n"); /*DEBUG*/
#endif
/* Make sure it is addressed to us */
for (i = 1; i <= config.num_addrs; i++)
{
if ((p.dest_net == config.net[i]) && (p.dest_node == config.node[i]))
break;
}
/*AK*/
if (toss_net == 0 && toss_node == 0)
{
toss_net = p.orig_net;
toss_node = p.orig_node;
}
else if (toss_net != p.orig_net || toss_node != p.orig_node)
{
(void) fast_close (f);
printf ("Packet '%s' origin differs from arcmail origin. Packet ignored\n", pktname);
return (0);
}
/* It was to us */
if (i <= config.num_addrs)
{
#if DEBUG
printf ("Its addressed to us\n"); /*DEBUG*/
#endif
for (i = 0; i < num_pw; i++)
{
/* Find out if we have a password for this guy */
if ((pw[i]->net == p.orig_net) && (pw[i]->node == p.orig_node))
{
/* We do, so uppercase it */
for (j = 0; j < 8; j++)
{
p.password[j] = (char) toupper (p.password[j]);
}
/* Do they match? */
if (strcmp (p.password, pw[i]->password))
{
/* No match! Bad news */
printf ("Packet '%s' does not have proper password for node %d/%d\n",
pktname, p.orig_net, p.orig_node);
_ffree (wbuffs[f].wbuff);
wbuffs[f].wbuff = wbuffs[f].wptr = NULL;
wbuffs[f].wsize = -1;
(void) fast_close (f);
bad_pw = 1;
return (1);
}
}
}
}
#if DEBUG
printf ("Passed PW check \n"); /*DEBUG*/
#endif
last_toss_area = -1;
dup_msgs = 0;
holder1 = malloc ((unsigned) (NUMBLOCKS*1024 + sizeof (MSG)));
if (holder1 == NULL)
{
(void) fast_close (f);
printf ("Could not malloc() message space, aborting\n");
exit (2);
}
#if DEBUG
printf ("Passed msg space \n"); /*DEBUG*/
#endif
killer = (KILLPTR) calloc (dup_size, sizeof(KILL));
if (killer == NULL)
{
v = _freect (50*sizeof (KILL));
printf ("Not enough memory to kill dups based on last %d messages\n", dup_size);
printf ("Try using '-D %d' on the command line - exiting\n", v*50);
exit (2);
}
holder = holder1+sizeof(MSG);
h = (MSG_PTR) header;
/* while version != 0 */
if (fast_read (f, (char *) &p1, 2) != 2)
{
p1.ver = 0;
printf ("Packet '%s' was a short packet\n", pktname);
}
i = 0;
while (p1.ver == PKTVER)
{
++i;
if (fast_read (f, (char *) &(p1.orig_node), sizeof (PACKED) - 2) != sizeof (PACKED) -2)
{
printf ("Packet '%s' was a short packet\n", pktname);
break;
}
/* Fill in the message structure and read in message */
memset ((char *) h, 0, sizeof (MSG));
if (get_to_null (f, h->date, &foo)
|| get_to_null (f, h->to, &foo1)
|| get_to_null (f, h->from, &foo2)
|| get_to_null (f, h->subj, &foo3)
|| get_to_null (f, holder, &body_count))
{
printf ("Packet '%s' was a short packet\n", pktname);
break;
}
if ((foo > 20) || (foo1 > 36) || (foo2 > 36) || (foo3 > 72))
{
printf ("Packet '%s' contains invalid data - aborting packet\n", pktname);
break;
}
#if DEBUG
printf ("Passed hdr check \n"); /*DEBUG*/
#endif
/* Fill in the rest of the message header */
do_date (h);
#if DEBUG
printf ("Passed do_date (h) \n"); /*DEBUG*/
#endif
h->times = 0;
h->dest = p1.dest_node;
h->orig = p1.orig_node;
h->cost = p1.cost;
h->orig_net = p1.orig_net;
h->dest_net = p1.dest_net;
h->reply = 0;
h->attr = p1.attr&(int)NO_CLEAR;
h->up = 0;
#if DEBUG
printf ("Header filled in \n"); /*DEBUG*/
#endif
/* See if we should toss it */
got_a = 0;
q1 = holder;
if (*q1 == 1)
{
++q1;
--body_count;
got_a = 1;
}
while ((isspace ((*q1)&0x7f)) || (*q1 == 1))
{
++q1;
--body_count;
}
#if DEBUG
printf ("Body contains %d bytes\n", body_count); /*DEBUG*/
#endif
/* Is it an AREA: file */
if ((body_count == 0) && (kill_null))
{
printf ("MAIL PKT %s:MSG %d -> NULL MSG - DELETED\n", pktname, i);
}
else if (strncmp (q1, "AREA:", 5) != 0)
{
#if DEBUG
printf ("not echomail\n");
#endif
/* Just write it into the netmail area */
printf ("MAIL PKT %s:MSG %d -=> MAIL:%d.MSG from %d/%d\n",
pktname, i, high_one+1, ((MSG *) h)->orig_net, ((MSG *) h)->orig);
netit (h, holder, body_count, config.mailpath, &high_one);
}
/* It is echomail, but is it to us? */
else
{
#if DEBUG
printf ("It is echomail\n");
#endif
for (j = 1; j <= config.num_addrs; j++)
{
if ( (config.net[j] == h->dest_net)
&&(config.node[j] == h->dest ))
{
/* It matches one of our addresses! */
#if DEBUG
printf ("It is addressed to us as %d/%d\n", h->dest_net, h->dest);
#endif
break;
}
}
if (j > config.num_addrs)
{
#if DEBUG
printf ("Not to us\n");
#endif
if (route_thru < 0)
{
/* Just write it into the netmail area */
printf ("MAIL PKT %s:MSG %d -=> MAIL:%d.MSG\n", pktname, i, high_one+1);
netit (h, holder, body_count, config.mailpath, &high_one);
}
else
{
/* Just write it into the routethru area */
if (*(areas[route_thru]->msgs_in_area) == -1)
{
/* Need to get high message number here */
/* First go to the proper directory */
(void) high_msg (areas[route_thru]->msg_path,
areas[route_thru]->msgs_in_area, &foo);
printf ("Found %d messages in area %s\n",
*(areas[route_thru]->msgs_in_area),
areas[route_thru]->area_name);
if (*areas[route_thru]->msgs_in_area == 0)
*areas[route_thru]->msgs_in_area = 1;
}
printf ("MAIL PKT %s:MSG %d -=> ROUTETHRU:%d.MSG\n", pktname,
i, *(areas[route_thru]->msgs_in_area) + 1);
netit (h, holder, body_count, areas[route_thru]->msg_path,
areas[route_thru]->msgs_in_area);
}
}
else
{
/* Toss it properly */
#if DEBUG
printf ("Tossing it\n");
#endif
if ((err = tossit (pktname, header, q1, body_count-5, f, i, 5-sizeof(MSG), 1)) < 0)
{
printf (" in message %d in packet '%s'\n", i, pktname);
if (bad_msgs < 0)
{
if (err != -2)
{
/* Just write it into the netmail area */
printf ("*** Message rerouted to netmail area as MAIL:%d.MSG ***\n", high_one+1);
netit (h, holder, body_count, config.mailpath, &high_one);
}
else
{
printf ("*** Message skipped\n");
}
}
else
{
/* Just write it into the bad_msgs area */
if (*(areas[bad_msgs]->msgs_in_area) == -1)
{
/* Need to get high message number here */
/* First go to the proper directory */
(void) high_msg (areas[bad_msgs]->msg_path,
areas[bad_msgs]->msgs_in_area, &foo);
printf ("Found %d messages in area %s\n",
*(areas[bad_msgs]->msgs_in_area),
areas[bad_msgs]->area_name);
if (*areas[bad_msgs]->msgs_in_area == 0)
*areas[bad_msgs]->msgs_in_area = 1;
}
printf ("MAIL PKT %s:MSG %d -=> BAD_MSGS:%d.MSG\n", pktname,
i, *(areas[bad_msgs]->msgs_in_area) + 1);
netit (h, holder, body_count, areas[bad_msgs]->msg_path,
areas[bad_msgs]->msgs_in_area);
}
}
}
}
if (fast_read (f, (char *) &p1, 2) != 2)
{
printf ("Packet '%s' was a short packet\n", pktname);
break;
}
}
if (last_toss_area >= 0)
{
/* Write out old killer data */
sprintf (dup_name, "%s\\CONFDUPS.DAT", areas[last_toss_area]->msg_path);
dup_file = open (dup_name, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
(void) fast_write (dup_file, (unsigned char *)&dup_msgs, sizeof (int));
v = MAGIC;
(void) fast_write (dup_file, (unsigned char *)&v, sizeof (int));
(void) fast_write (dup_file, (unsigned char *)killer, dup_size * sizeof (KILL));
(void) fast_close (dup_file);
}
_ffree (wbuffs[f].wbuff);
wbuffs[f].wbuff = wbuffs[f].wptr = NULL;
wbuffs[f].wsize = -1;
(void) fast_close (f);
free (holder1);
free (killer);
/* Else return 0 */
return (0);
}
int tosspkt (char *dir)
{
int j, k, ret, ct;
char pktname[20];
char pktname1[64];
char pktn[64];
/* char pktsave[20]; */
j = 0;
ret = 1;
sprintf (pktn, "%s\\*.PKT", dir);
ct = strlen (dir) + 1;
(void) filedir (pktn, j, pktname, 0);
while (pktname[0] != '\0')
{
sprintf (pktname1, "%s\\%s", dir, pktname);
printf ("Tossing packet '%s'\n", pktname1);
if (unpackpkt (pktname1))
{
bad_pkt = 1;
printf ("Problem with packet '%s' ", pktname1);
if (pktname[8] != '.')
{
printf ("- continuing\n");
++j;
}
else
{
strcpy (&pktname[9], "BAD");
sprintf (pktn, "%s\\%s", dir, pktname);
if (rename (pktname1, pktn) == 0)
{
printf ("renamed '%s'\n", pktn);
}
else
{
printf ("rename failed, packet removed\n");
unlink (pktname1);
}
sprintf (pktn, "%s\\*.PKT", dir);
for (k = 0; k < j; k++)
{
(void) filedir (pktn, k, pktname, 0);
}
}
}
else
{
ret = 0;
unlink (pktname1);
for (k = 0; k < j; k++)
{
(void) filedir (pktn, k, pktname, 0);
}
}
(void) filedir (pktn, j, pktname, 0);
}
return (ret);
}
void arc_e ()
{
/* Now unARC all the other ARCmail and toss that stuff */
(void) arcmail();
}