home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / VP2_409E.SZH / TOSS.C < prev    next >
Text File  |  1991-07-09  |  27KB  |  881 lines

  1. /*
  2.   $Header: toss.c 3.3 87/12/12 00:45:34 Bob Exp $
  3.  
  4.                           The Conference Mail System
  5.  
  6.               This module was originally written by Bob Hartman
  7.                        Sysop of FidoNet node 1:132/101
  8.  
  9.    Spark Software, 427-3 Amherst St, CS 2032, Suite 232, Nashua, NH 03061
  10.  
  11.  The Conference Mail System  is a  complete Echomail processing package.  It
  12.  is a superset of the original  Echomail utilities created by Jeff Rush, and
  13.  also contains ideas gleaned from the  ARCmail,  Renum,  oMMM, MGM, and Opus
  14.  programs that were created by various software authors.
  15.  
  16.  This program source code is being released with the following provisions:
  17.  
  18.  1.  You are  free to make  changes to this source  code for use on your own
  19.  machine,  however,  altered source files may not be distributed without the
  20.  consent of Spark Software.
  21.  
  22.  2.  You may distribute "patches"  or  "diff" files for any changes that you
  23.  have made, provided that the "patch" or "diff" files are also sent to Spark
  24.  Software for inclusion in future releases of the entire package.   A "diff"
  25.  file for the source archives may also contain a compiled version,  provided
  26.  it is  clearly marked as not  being created  from the original source code.
  27.  No other  executable  versions may be  distributed without  the  consent of
  28.  Spark Software.
  29.  
  30.  3.  You are free to include portions of this source code in any program you
  31.  develop, providing:  a) Credit is given to Spark Software for any code that
  32.  may is used, and  b) The resulting program is free to anyone wanting to use
  33.  it, including commercial and government users.
  34.  
  35.  4.  There is  NO  technical support  available for dealing with this source
  36.  code, or the accompanying executable files.  This source  code  is provided
  37.  as is, with no warranty expressed or implied (I hate legalease).   In other
  38.  words, if you don't know what to do with it,  don't use it,  and if you are
  39.  brave enough to use it, you're on your own.
  40.  
  41.  Spark Software may be contacted by modem at (603) 888-8179 (node 1:132/101)
  42.  on the public FidoNet network, or at the address given above.
  43.  
  44.  To use this code you will need Microsoft C version 4.0, and also Microsoft
  45.  Macro Assembler version 4.0.
  46.  
  47. */
  48.  
  49. /*
  50.    $Log:    toss.c $
  51.  * Revision 4.09d 91/06/11           GJS
  52.  * Update to compile cleanly with /W4 in MSC 6.00a
  53.  * Update for to include statistics and logging
  54.  *
  55.  * Revision 3.3  87/12/12  00:45:34  Bob
  56.  * Source code release
  57.  *
  58. */
  59.  
  60. #include <stdio.h>
  61. #include <ctype.h>
  62. #include <fcntl.h>
  63. #include <io.h>
  64. #include <time.h>
  65. #include <process.h>
  66. #include <string.h>
  67. #include <malloc.h>
  68. #include <sys\types.h>
  69. #include <sys\stat.h>
  70. #include "fastecho.h"
  71.  
  72. #define DEBUG 0
  73.  
  74. extern char *opus_date;
  75. extern char *fido_date;
  76. extern char *mspace_err;
  77. extern char *mnspace_err;
  78. extern char *ntoss_err;
  79. extern char *open_err;
  80. extern int tossed_some;
  81. extern int check_nodes;
  82. extern int pass_thru;
  83. extern int bad_msgs;
  84. extern int mail_high;
  85. extern SEACONFIG config;
  86. extern AREAS_PTR areas[];
  87. extern char board_name[], sysop_name[];
  88. extern int tot_areas;
  89. extern char *arc_cmd[];
  90. extern int nread;
  91. extern int arc_args;
  92. extern int last_msg;
  93. extern int high_one;
  94. extern int convert;
  95. extern struct tm *t2;
  96. extern struct _stamp cur_stamp;
  97. extern struct _stamp zero_stamp;
  98. extern KILLPTR killer;
  99. extern long secs_from_1980();
  100. int toss_net;
  101. int toss_node;
  102. int got_a;
  103. int last_toss_area;
  104. int dup_msgs;
  105. int dup_file;
  106. int dup_size;
  107. char dup_name[64];
  108. extern int no_matrix;
  109. extern int msgs_tossed;
  110. extern int msg_dups;
  111. extern char *weekday[];
  112.  
  113. #if STATS
  114.     extern int  security;
  115. #endif
  116.  
  117. char *_months[12] = {
  118.         "JANUARY", "FEBRUARY", "MARCH",     "APRIL",   "MAY",      "JUNE",
  119.         "JULY",    "AUGUST",   "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
  120. };
  121.  
  122. void do_date (MSG_PTR h1)
  123. {
  124.     int y, d, h, m, s;
  125.     int i;
  126.     char m1[100], junk[100], *tst1;
  127.  
  128.     tst1 = h1->date;
  129.     /* If it is a null date, then put in new format */
  130.     if (h1->date[0] == '\0')
  131.     {
  132.         /* If it is Opus, then put in Opus format */
  133.         if (convert == 1)
  134.         {
  135.             /*
  136.             sprintf (h1->date, opus_date,
  137.             t2->tm_mday, _months[t2->tm_mon], t2->tm_year,
  138.             t2->tm_hour, t2->tm_min, t2->tm_sec);
  139.             h1->date[4] = tolower (h1->date[4]);
  140.             h1->date[5] = tolower (h1->date[5]);
  141.             h1->date[19] = 0xff;
  142.             */
  143.             *tst1++ = (char) ((t2->tm_mday / 10) + '0');
  144.             *tst1++ = (char) ((t2->tm_mday % 10) + '0');
  145.             *tst1++ = ' ';
  146.             *tst1++ = _months[t2->tm_mon][0];
  147.             *tst1++ = (char) tolower (_months[t2->tm_mon][1]);
  148.             *tst1++ = (char) tolower (_months[t2->tm_mon][2]);
  149.             *tst1++ = ' ';
  150.             *tst1++ = (char) ((t2->tm_year / 10) + '0');
  151.             *tst1++ = (char) ((t2->tm_year % 10) + '0');
  152.             *tst1++ = ' ';
  153.             *tst1++ = (char) ((t2->tm_hour / 10) + '0');
  154.             *tst1++ = (char) ((t2->tm_hour % 10) + '0');
  155.             *tst1++ = ':';
  156.             *tst1++ = (char) ((t2->tm_min  / 10) + '0');
  157.             *tst1++ = (char) ((t2->tm_min  % 10) + '0');
  158.             *tst1++ = ':';
  159.             *tst1++ = (char) ((t2->tm_sec  / 10) + '0');
  160.             *tst1++ = (char) ((t2->tm_sec  % 10) + '0');
  161.             *tst1++ = '\0';
  162.             *tst1++ = 0xff;
  163.             h1->_date_written = h1->_date_arrived = cur_stamp;
  164.         }
  165.         else
  166.         {
  167.             /*
  168.             sprintf (h1->date, fido_date,
  169.             weekday[t2->tm_wday], t2->tm_mday, _months[t2->tm_mon],
  170.             t2->tm_year, t2->tm_hour, t2->tm_min);
  171.             h1->date[8] = tolower (h1->date[8]);
  172.             h1->date[9] = tolower (h1->date[9]);
  173.             */
  174.             *tst1++ = weekday[t2->tm_wday][0];
  175.             *tst1++ = (char) tolower (weekday[t2->tm_wday][1]);
  176.             *tst1++ = (char) tolower (weekday[t2->tm_wday][2]);
  177.             *tst1++ = ' ';
  178.             *tst1++ = (char) ((t2->tm_mday / 10) + '0');
  179.             *tst1++ = (char) ((t2->tm_mday % 10) + '0');
  180.             *tst1++ = ' ';
  181.             *tst1++ = _months[t2->tm_mon][0];
  182.             *tst1++ = (char) tolower (_months[t2->tm_mon][1]);
  183.             *tst1++ = (char) tolower (_months[t2->tm_mon][2]);
  184.             *tst1++ = ' ';
  185.             *tst1++ = (char) ((t2->tm_year / 10) + '0');
  186.             *tst1++ = (char) ((t2->tm_year % 10) + '0');
  187.             *tst1++ = ' ';
  188.             *tst1++ = (char) ((t2->tm_hour / 10) + '0');
  189.             *tst1++ = (char) ((t2->tm_hour % 10) + '0');
  190.             *tst1++ = ':';
  191.             *tst1++ = (char) ((t2->tm_min  / 10) + '0');
  192.             *tst1++ = (char) ((t2->tm_min  % 10) + '0');
  193.             *tst1++ = '\0';
  194.             h1->_date_written = h1->_date_arrived = zero_stamp;
  195.         }
  196.         return;
  197.     }
  198.  
  199.     s = 0;
  200.     /* It is old format, so convert to new format */
  201.     if ((i = sscanf (h1->date, "%d %s %d %d:%d:%d", &d, m1, &y, &h, &m, &s)) != 6)
  202.     {
  203.         if ((i = sscanf (h1->date, "%s %d %s %d %d:%d", junk, &d, m1, &y, &h, &m)) < 5)
  204.         {
  205.             /* Cannot recognize old format, so put in default */
  206.             /* If it is Opus, then put in Opus format */
  207.             if (convert == 1)
  208.             {
  209.                 /*
  210.                 sprintf (h1->date, opus_date,
  211.                 t2->tm_mday, _months[t2->tm_mon], t2->tm_year,
  212.                 t2->tm_hour, t2->tm_min, t2->tm_sec);
  213.                 h1->date[4] = tolower (h1->date[4]);
  214.                 h1->date[5] = tolower (h1->date[5]);
  215.                 h1->date[19] = 0xff;
  216.                 */
  217.                 *tst1++ = (char) ((t2->tm_mday / 10) + '0');
  218.                 *tst1++ = (char) ((t2->tm_mday % 10) + '0');
  219.                 *tst1++ = ' ';
  220.                 *tst1++ = _months[t2->tm_mon][0];
  221.                 *tst1++ = (char) tolower (_months[t2->tm_mon][1]);
  222.                 *tst1++ = (char) tolower (_months[t2->tm_mon][2]);
  223.                 *tst1++ = ' ';
  224.                 *tst1++ = (char) ((t2->tm_year / 10) + '0');
  225.                 *tst1++ = (char) ((t2->tm_year % 10) + '0');
  226.                 *tst1++ = ' ';
  227.                 *tst1++ = (char) ((t2->tm_hour / 10) + '0');
  228.                 *tst1++ = (char) ((t2->tm_hour % 10) + '0');
  229.                 *tst1++ = ':';
  230.                 *tst1++ = (char) ((t2->tm_min  / 10) + '0');
  231.                 *tst1++ = (char) ((t2->tm_min  % 10) + '0');
  232.                 *tst1++ = ':';
  233.                 *tst1++ = (char) ((t2->tm_sec  / 10) + '0');
  234.                 *tst1++ = (char) ((t2->tm_sec  % 10) + '0');
  235.                 *tst1++ = '\0';
  236.                 *tst1++ = 0xff;
  237.                 h1->_date_written = h1->_date_arrived = cur_stamp;
  238.             }
  239.             else
  240.             {
  241.                 /*
  242.                 sprintf (h1->date, fido_date,
  243.                 weekday[t2->tm_wday], t2->tm_mday, _months[t2->tm_mon],
  244.                 t2->tm_year, t2->tm_hour, t2->tm_min);
  245.                 h1->date[8] = tolower (h1->date[8]);
  246.                 h1->date[9] = tolower (h1->date[9]);
  247.                 */
  248.                 *tst1++ = weekday[t2->tm_wday][0];
  249.                 *tst1++ = (char) tolower (weekday[t2->tm_wday][1]);
  250.                 *tst1++ = (char) tolower (weekday[t2->tm_wday][2]);
  251.                 *tst1++ = ' ';
  252.                 *tst1++ = (char) ((t2->tm_mday / 10) + '0');
  253.                 *tst1++ = (char) ((t2->tm_mday % 10) + '0');
  254.                 *tst1++ = ' ';
  255.                 *tst1++ = _months[t2->tm_mon][0];
  256.                 *tst1++ = (char) tolower (_months[t2->tm_mon][1]);
  257.                 *tst1++ = (char) tolower (_months[t2->tm_mon][2]);
  258.                 *tst1++ = ' ';
  259.                 *tst1++ = (char) ((t2->tm_year / 10) + '0');
  260.                 *tst1++ = (char) ((t2->tm_year % 10) + '0');
  261.                 *tst1++ = ' ';
  262.                 *tst1++ = (char) ((t2->tm_hour / 10) + '0');
  263.                 *tst1++ = (char) ((t2->tm_hour % 10) + '0');
  264.                 *tst1++ = ':';
  265.                 *tst1++ = (char) ((t2->tm_min  / 10) + '0');
  266.                 *tst1++ = (char) ((t2->tm_min  % 10) + '0');
  267.                 *tst1++ = '\0';
  268.                 h1->_date_written = h1->_date_arrived = zero_stamp;
  269.             }
  270.             return;
  271.         }
  272.     }
  273.     m1[0] = (char) toupper (m1[0]);
  274.     m1[1] = (char) toupper (m1[1]);
  275.     m1[2] = (char) toupper (m1[2]);
  276.     i = 0;
  277. /*  while ((strncmp (_months[i], m1, 3) != 0) && (i != 12))
  278.         ++i;   */
  279.     for ( i=0; i<12; i++)
  280.     {
  281.         if (strncmp(_months[i], m1, 3) == 0)
  282.             break;
  283.     }
  284.  
  285.     /* If we have an undecipherable month, jam in this month */
  286.     if (i == 12)
  287.     {
  288.         if (strncmp("MEI", m1, 3) == 0)
  289.             i = 4;
  290.         else
  291.             i = t2->tm_mon;
  292.     }
  293.     /* Now we have all the pieces, plug them in */
  294.     /*
  295.     sprintf (h1->date, opus_date,
  296.     d, _months[i], y, h, m, s);
  297.     h1->date[4] = tolower (h1->date[4]);
  298.     h1->date[5] = tolower (h1->date[5]);
  299.     */
  300.     *tst1++ = (char) ((d / 10) + '0');
  301.     *tst1++ = (char) ((d % 10) + '0');
  302.     *tst1++ = ' ';
  303.     *tst1++ = _months[i][0];
  304.     *tst1++ = (char) tolower (_months[i][1]);
  305.     *tst1++ = (char) tolower (_months[i][2]);
  306.     *tst1++ = ' ';
  307.     *tst1++ = (char) ((y / 10) + '0');
  308.     *tst1++ = (char) ((y % 10) + '0');
  309.     *tst1++ = ' ';
  310.     *tst1++ = (char) ((h / 10) + '0');
  311.     *tst1++ = (char) ((h % 10) + '0');
  312.     *tst1++ = ':';
  313.     *tst1++ = (char) ((m / 10) + '0');
  314.     *tst1++ = (char) ((m % 10) + '0');
  315.     *tst1++ = ':';
  316.     *tst1++ = (char) ((s / 10) + '0');
  317.     *tst1++ = (char) ((s % 10) + '0');
  318.     *tst1++ = '\0';
  319.     if (convert == 1)
  320.     {
  321.         h1->date[19] = 0xff;
  322.         h1->_date_arrived = cur_stamp;
  323.         h1->_date_written.date = ((y - 80)<<9) + ((i+1)<<5) + d;
  324.         h1->_date_written.time = (h<<11) + (m<<5) + (s>>1);
  325.     }
  326.     else
  327.     {
  328.         h1->date[19] = '\0';
  329.         h1->_date_written = h1->_date_arrived = zero_stamp;
  330.     }
  331.  
  332. }
  333.  
  334. int findkill (KILLPTR k1)
  335. {
  336.    int i;
  337.  
  338.    if (k1->seconds == 1000000000L)
  339.       return (0);
  340.  
  341.    for (i = 0; i < dup_size; i++)
  342.       {
  343.         if (killer[i].seconds == k1->seconds)
  344.             {
  345.             if (   (killer[i].from    == k1->from)
  346.                  && (killer[i].to      == k1->to  )
  347.                  && (killer[i].subject == k1->subject)
  348.                  && (killer[i].seconds != 1000000000L))
  349.             {
  350.             return (i + 1);
  351.             }
  352.          }
  353.       }
  354.  
  355.    killer[dup_msgs] = *k1;
  356.    ++dup_msgs;
  357.    if (dup_msgs >= dup_size)
  358.       {
  359.       dup_msgs = 0;
  360.       }
  361.    return (0);
  362. }
  363.  
  364. int toss (char *dir)
  365. {
  366.     int i, j, foo, v;
  367.     int *msg_nums;
  368.     int body_count;
  369.     char *t, *t1, *q1;
  370.     char *holder;
  371.     char *holder1;
  372.     char header[sizeof(MSG)+10];
  373.     MSG_PTR h;
  374.     int f;
  375. /*  int err; */
  376.     char fname[80];
  377.  
  378.    last_toss_area = -1;
  379.    dup_msgs = 0;
  380.     holder1 = malloc ((unsigned) (NUMBLOCKS*1024 + sizeof (MSG)));
  381.     msg_nums = (int *) malloc ((unsigned) (NUMMSGS * sizeof (int)));
  382.     killer = (KILLPTR) calloc (dup_size, sizeof(KILL));
  383.     if (holder1 == NULL)
  384.         {
  385.         printf (mspace_err);
  386.         exit (2);
  387.         }
  388.     if (msg_nums == NULL)
  389.         {
  390.         printf (mnspace_err);
  391.         exit (2);
  392.         }
  393.    if (killer == NULL)
  394.       {
  395.       v = _freect (50*sizeof (KILL));
  396.       printf ("Not enough memory to kill dups based on last %d messages\n", dup_size);
  397.       printf ("Try using '-D %d' on the command line - exiting\n", v*50);
  398.       exit (2);
  399.       }
  400.  
  401.     get_msg_lst (msg_nums, &last_msg, dir, 0);
  402.     if (last_msg == 0)
  403.         {
  404.         mail_high = high_one = 0;
  405.         printf ("No messages to process\n");
  406.         free (holder1);
  407.         free ((char *) msg_nums);
  408.       free (killer);
  409.         return (0);
  410.         }
  411.     else
  412.         {
  413.         mail_high = high_one = msg_nums[last_msg-1];
  414.         }
  415.    if (no_matrix)
  416.       {
  417.       free (holder1);
  418.       free ((char *) msg_nums);
  419.       free (killer);
  420.       printf ("Not processing MAIL area\n");
  421.       return (0);
  422.       }
  423.     printf ("Processing messages numbered %d-%d in MAIL area '%s'\n",
  424.         msg_nums[0], msg_nums[last_msg-1], dir);
  425.     strcpy (fname, dir);
  426.     t1 = fname + strlen (fname);
  427.    *t1++ = '\\';
  428.     holder = holder1+sizeof(MSG);
  429.     h = (MSG_PTR) header;
  430.     t = header+sizeof(MSG);
  431.  
  432.     for (i = 0; i < last_msg; i++)
  433.         {
  434.       got_a = 0;
  435.         sprintf (t1, "%d.MSG", msg_nums[i]);
  436.       /*itoa (msg_nums[i], t1, 10);
  437.       strcat (t1, ".MSG");*/
  438. #if DEBUG
  439.       printf ("Doing file %s\n", fname);
  440. #endif
  441.         if((f = open (fname, O_RDONLY|O_BINARY)) == -1)
  442.             {
  443. #if DEBUG
  444.             printf ("not opened\n");
  445. #endif
  446.             high_one = msg_nums[i];
  447.             continue;
  448.             }
  449.         if (fast_read (f, header, sizeof(MSG)+8) != (sizeof (MSG) + 8))
  450.             {
  451. #if DEBUG
  452.             printf ("not proper size\n");
  453. #endif
  454.             (void) fast_close (f);
  455.             high_one = msg_nums[i];
  456.             continue;
  457.             }
  458.  
  459.         q1 = t;
  460.         if (*q1 == 1)
  461.             {
  462.             ++q1;
  463.          got_a = 1;
  464.             }
  465.         while ((isspace ((*q1)&0x7f)) || (*q1 == 1))
  466.             ++q1;
  467.  
  468.         /* Is it an AREA: file */
  469.         if (strncmp (q1, "AREA:", 5) != 0)
  470.             {
  471. #if DEBUG
  472.             printf ("not echomail\n");
  473. #endif
  474.             (void) fast_close (f);
  475.             high_one = msg_nums[i];
  476.             continue;
  477.             }
  478. #if DEBUG
  479.         printf ("It is Echomail to %d/%d\n", h->dest_net, h->dest);
  480. #endif
  481.         /* Is the message to us */
  482.         for (j = 1; j <= config.num_addrs; j++)
  483.             {
  484.             if (  (config.net[j] == h->dest_net)
  485.                  &&(config.node[j] == h->dest   ))
  486.                 {
  487.                 /* It matches one of our addresses! */
  488. #if DEBUG
  489.                 printf ("It is addressed to us as %d/%d\n", h->dest_net, h->dest);
  490. #endif
  491.                 break;
  492.                 }
  493.             }
  494.         if (j > config.num_addrs)
  495.             {
  496.             (void) fast_close (f);
  497.             high_one = msg_nums[i];
  498.             continue;
  499.             }
  500.         strncpy (holder, q1, 8-(int) (q1-t));
  501.  
  502.         body_count = read_all (f, holder+(8-(int) (q1-t)));
  503.  
  504. #if DEBUG
  505.         printf ("body_count = %d\n", body_count);
  506. #endif
  507.  
  508.         do_date (h);
  509.       toss_net = h->orig_net;
  510.       toss_node = h->orig;
  511.         if (tossit (fname, header, holder1, body_count, f, msg_nums[i], 5, 0) < 0)
  512.             {
  513.             printf (" in message %d\n", msg_nums[i]);
  514.          if (bad_msgs >= 0)
  515.             {
  516.             /* Just write it into the bad_msgs area */
  517.                 if (*(areas[bad_msgs]->msgs_in_area) == -1)
  518.                 {
  519.                 /* Need to get high message number here */
  520.                /* First go to the proper directory */
  521.                     (void) high_msg (areas[bad_msgs]->msg_path,
  522.                   areas[bad_msgs]->msgs_in_area, &foo);
  523.              printf ("Found %d messages in area %s\n",
  524.                         *(areas[bad_msgs]->msgs_in_area),
  525.                     areas[bad_msgs]->area_name);
  526.                if (*areas[bad_msgs]->msgs_in_area == 0)
  527.                   *areas[bad_msgs]->msgs_in_area = 1;
  528.                    }
  529.  
  530.             printf ("MAIL:%d.MSG -=> %s:%d.MSG\n", msg_nums[i],
  531.                 areas[bad_msgs]->area_name, *(areas[bad_msgs]->msgs_in_area)+1);
  532.             netit ((MSG_PTR)header, holder, body_count+5, areas[bad_msgs]->msg_path,
  533.                areas[bad_msgs]->msgs_in_area);
  534.             unlink (fname);
  535.             }
  536.             }
  537.         }
  538.  
  539.    if (last_toss_area >= 0)
  540.       {
  541.       /* Write out old killer data */
  542.       sprintf (dup_name, "%s\\CONFDUPS.DAT", areas[last_toss_area]->msg_path);
  543.       dup_file = open (dup_name, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
  544.       (void) fast_write (dup_file, (unsigned char *)&dup_msgs, sizeof (int));
  545.       v = MAGIC;
  546.       (void) fast_write (dup_file, (unsigned char *)&v, sizeof (int));
  547.       (void) fast_write (dup_file, (unsigned char *)killer, dup_size * sizeof (KILL));
  548.       (void) fast_close (dup_file);
  549.       last_toss_area = -1;
  550.       }
  551.  
  552.    free (holder1);
  553.    free ((char *) msg_nums);
  554.    free (killer);
  555.    return (0);
  556. }
  557.  
  558. int tossit (
  559.    char *fname,
  560.    char *header,
  561.    char *holder1,
  562.    int   body_count,
  563.    int   f,
  564.    int   msg_num,
  565.    int   area,
  566.    int   delit)
  567. {
  568.    int i, j, foo, v;
  569.    char *body;
  570.    char *ptr, *ptr1;
  571.    char *holder;
  572.    MSG_PTR h;
  573.    int f1;
  574.    int st;
  575.    char fname1[80];
  576.    char old_char;
  577.    KILL k1;
  578.  
  579.    /* Now see if it is tossable */
  580.    holder = holder1+sizeof(MSG)+area;
  581.    h = (MSG_PTR) header;
  582.    ptr = holder;
  583. #if DEBUG
  584.    printf ("ptr = '%10.10s'\n", ptr);
  585. #endif
  586.    /* It is tossable! */
  587.    /* First get the area to put it in */
  588.    while ((isspace ((*ptr&0x7f)) || (*ptr == 1)) && (ptr != (holder + body_count)))
  589.       ptr++;
  590.    ptr1 = ptr;
  591.    while ((!isspace ((*ptr1&0x7f))) && (ptr1 != (holder + body_count)))
  592.       ptr1++;
  593.    old_char = *ptr1;
  594.    *ptr1 = '\0';
  595.    if (*ptr == '\0')
  596.    {
  597.       printf ("Can't find the AREA name after the AREA:");
  598.       if (!delit)
  599.          (void) fast_close (f);
  600.       *ptr1 = old_char;
  601.       return (-1);
  602.    }
  603.    else
  604.    {
  605.       body = ptr1 + 1;
  606.    }
  607. #if DEBUG
  608.    printf ("It goes into area '%s'\n", ptr);
  609. #endif
  610.  
  611.    /* Now find it in our list of areas */
  612.    for (j = 0; j < tot_areas; j++)
  613.    {
  614.       if (stricmp (areas[j]->area_name, ptr) == 0)
  615.       {
  616.          /* Found it */
  617.          break;
  618.       }
  619.    }
  620.  
  621. #if DEBUG
  622.    printf ("tot_areas = %d, j = %d\n", tot_areas, j);
  623. #endif
  624.  
  625.    if (j == tot_areas)
  626.    {
  627.       if (pass_thru >= 0)
  628.       {
  629.          j = pass_thru;
  630.          body = holder1+sizeof(MSG)+area-5;
  631.          *ptr1 = old_char;
  632.       }
  633.       else
  634.       {
  635.          printf ("Unknown Area Name '%s'", ptr);
  636.          if (!delit)
  637.             (void) fast_close (f);
  638.          *ptr1 = old_char;
  639.  
  640. #if STATS
  641.          security++;
  642. #endif
  643.  
  644.          return (-1);
  645.       }
  646.    }
  647.  
  648.    i = -1;
  649.    /* Now check the node numbers if we are supposed to do that */
  650.    if (check_nodes)
  651.    {
  652.       /* First check to see if it is from us */
  653.       for (i = 1; i <= config.num_addrs; i++)
  654.       {
  655.          if (  (config.net[i] == h->orig_net)
  656.                &&(config.node[i] == h->orig   ))
  657.          {
  658.             /* It matches one of our addresses! */
  659.             break;
  660.          }
  661.       }
  662.       if (i <= config.num_addrs)
  663.       {
  664.          printf (ntoss_err, h->orig_net, h->orig);
  665.          if (!delit)
  666.             (void) fast_close (f);
  667.          *ptr1 = old_char;
  668.          return (-1);
  669.       }
  670.       for (i = 0; i < areas[j]->num_nodes; i++)
  671.       {
  672.          if ((areas[j]->net[i] == toss_net) &&
  673.              (areas[j]->node[i] == toss_node))
  674.          {
  675.             break;
  676.          }
  677.       }
  678.    }
  679.  
  680.  
  681.    /*zzl1 = strlen (areas[j]->msg_path);*/
  682.    if (i >= areas[j]->num_nodes)
  683.    {
  684.       printf (ntoss_err, toss_net, toss_node);
  685.       if (!delit)
  686.          (void) fast_close (f);
  687.       *ptr1 = old_char;
  688.  
  689. #if STATS
  690.       areas[j]->msgs_sec++;
  691. #endif
  692.  
  693.       return (-1);
  694.    }
  695.    else
  696.    {
  697.  
  698.       if (killer != NULL)
  699.       {
  700.          if (last_toss_area != j)
  701.          {
  702.             if (last_toss_area >= 0)
  703.             {
  704.                /* Write out old killer data */
  705.                sprintf (dup_name, "%s\\CONFDUPS.DAT", areas[last_toss_area]->msg_path);
  706.                dup_file = open (dup_name, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
  707.                (void) fast_write (dup_file, (unsigned char *)&dup_msgs, sizeof (int));
  708.                v = MAGIC;
  709.                (void) fast_write (dup_file, (unsigned char *)&v, sizeof (int));
  710.                (void) fast_write (dup_file, (unsigned char *)killer, dup_size * sizeof (KILL));
  711.                (void) fast_close (dup_file);
  712.                memset (killer, 0, dup_size * sizeof (KILL));
  713.                dup_msgs = 0;
  714.             }
  715.  
  716.             if ((areas[j]->flags & ROUTETHRU) ||
  717.                (areas[j]->flags & PASS_THRU) ||
  718.                (areas[j]->flags & BAD_MSGS))
  719.             {
  720.                last_toss_area = -1;
  721.             }
  722.             else
  723.             {
  724.                last_toss_area = j;
  725.                /* Input new killer data */
  726.                sprintf (dup_name, "%s\\CONFDUPS.DAT", areas[last_toss_area]->msg_path);
  727.  
  728.                if ((dup_file = open (dup_name, O_RDONLY|O_BINARY)) != -1)
  729.                {
  730.  
  731.                   if (fast_read (dup_file, (unsigned char *)&dup_msgs, sizeof (int)) != sizeof (int))
  732.                   {
  733.  
  734.                      dup_msgs = 0;
  735.                      (void) fast_close (dup_file);
  736.  
  737.                   }
  738.                   else
  739.                   {
  740.                      v = 0;
  741.  
  742.                      if (fast_read (dup_file, (unsigned char *)&v, sizeof (int)) != sizeof (int))
  743.                      {
  744.  
  745.                         dup_msgs = 0;
  746.                      }
  747.                      else if (v != MAGIC)
  748.                      {
  749.  
  750.                         dup_msgs = 0;
  751.                      }
  752.                      else
  753.                      {
  754.  
  755.                         (void) fast_read (dup_file, (unsigned char *)killer, dup_size * sizeof (KILL));
  756.  
  757.                      }
  758.                      (void) fast_close (dup_file);
  759.  
  760.                   }
  761.                }
  762.                else
  763.                {
  764.                   dup_msgs = 0;
  765.                }
  766.             }
  767.          }
  768.  
  769.  
  770.          /* Now calculate the killer data for this one */
  771.          k1.seconds = secs_from_1980 (h);
  772.          k1.from = calcrc (h->from);
  773.          k1.to = calcrc (h->to);
  774.          if ((toupper(h->subj[0]) == 'R') &&
  775.              (toupper(h->subj[1]) == 'E') &&
  776.              (h->subj[2] == ':') &&
  777.              (h->subj[3] == ' '))
  778.          {
  779.             st = 4;
  780.          }
  781.          else
  782.             st = 0;
  783.  
  784.          k1.subject = calcrc (&(h->subj[st]));
  785.  
  786.          /* If it is in the data base, then don't toss it */
  787.          if (! ((areas[j]->flags & ROUTETHRU) ||
  788.             (areas[j]->flags & PASS_THRU) ||
  789.             (areas[j]->flags & BAD_MSGS)))
  790.          {
  791.             if (findkill (&k1))
  792.             {
  793.                printf ("DUPLICATE MESSAGE");
  794.                if (!delit)
  795.                   (void) fast_close (f);
  796.                *ptr1 = old_char;
  797.                ++msg_dups;
  798.  
  799. #if STATS
  800.                areas[j]->msg_dupes++;
  801. #endif
  802.  
  803.                return (-2);
  804.             }
  805.          }
  806.       }
  807.  
  808.  
  809.       if (*(areas[j]->msgs_in_area) == -1)
  810.       {
  811.          /* Need to get high message number here */
  812.          /* First go to the proper directory */
  813.          (void) high_msg (areas[j]->msg_path, areas[j]->msgs_in_area, &foo);
  814.          printf ("Found %d messages in area %s\n",
  815.                 *(areas[j]->msgs_in_area), areas[j]->area_name);
  816.          if (*areas[j]->msgs_in_area <= 0)
  817.             *areas[j]->msgs_in_area = 1;
  818.       }
  819.  
  820.       /* Create new name */
  821.       sprintf (fname1, "%s\\%d.MSG", areas[j]->msg_path,
  822.             ++*(areas[j]->msgs_in_area));
  823. #if DEBUG
  824.       printf ("I am really going '%s' -=> '%s'\n", fname, fname1);
  825. #endif
  826.  
  827.       if (delit)
  828.          printf ("MAIL PKT %s:MSG %d -=> %s:%d.MSG\n", fname, msg_num,
  829.                 areas[j]->area_name, *(areas[j]->msgs_in_area));
  830.       else
  831.          printf ("MAIL:%d.MSG -=> %s:%d.MSG\n", msg_num,
  832.                 areas[j]->area_name, *(areas[j]->msgs_in_area));
  833.       h->attr &= SAVED;
  834.       h->cost = 0;
  835.       if (*body == '\n')
  836.          ++body;
  837.       body_count -= (body - holder);
  838.       body = body - sizeof (MSG);
  839.       memcpy (body, header, sizeof (MSG));
  840.       body_count += sizeof (MSG);
  841.  
  842. #if STATS
  843.       areas[j]->msgs_proc++;
  844.       areas[j]->msgs_size += body_count;
  845. #endif
  846.  
  847. #if DEBUG
  848.       printf ("Got body containing %d characters\n", body_count);
  849. #endif
  850.       /* Open file */
  851.       f1 = open (fname1, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
  852.       if (f1 == -1)
  853.       {
  854.          printf (open_err, fname1);
  855.          exit (2);
  856.       }
  857.       /* Write the header after clearing the proper bits */
  858.       if (write_body (f1, body, body_count, f) < body_count)
  859.       {
  860.          printf ("Didn't properly write the message body, aborting\n");
  861.          exit (2);
  862.       }
  863.       if (fast_close (f1) != 0)
  864.       {
  865.          printf ("Pretty strange, couldn't fast_close after write, aborting\n");
  866.          exit (2);
  867.       }
  868. #if DEBUG
  869.       printf ("If I got here then I should have properly written the message\n");
  870. #endif
  871.       if (!delit)
  872.       {
  873.          (void) fast_close (f);
  874.          unlink (fname);
  875.       }
  876.    }
  877.    tossed_some = 1;
  878.    ++msgs_tossed;
  879.    return (0);
  880. }
  881.