home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / MAILOVLY.C < prev    next >
C/C++ Source or Header  |  1992-04-21  |  21KB  |  876 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*                 This module was written by Bob Hartman                   */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                   BinkleyTerm Mail Control Routines                      */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491, 1:141/491  */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n132.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. #include <stdio.h>
  47. #include <signal.h>
  48. #include <ctype.h>
  49. #include <conio.h>
  50. #include <sys/types.h>
  51. #include <sys/stat.h>
  52. #include <string.h>
  53. #include <fcntl.h>
  54. #include <time.h>
  55. #include <dos.h>
  56. #include <process.h>
  57. #include <stdlib.h>
  58. #include <io.h>
  59.  
  60. #include "com.h"
  61. #include "xfer.h"
  62. #include "zmodem.h"
  63. #include "keybd.h"
  64. #include "sbuf.h"
  65. #include "sched.h"
  66. #include "externs.h"
  67. #include "prototyp.h"
  68. #include "defines.h"
  69. #include "vfossil.h"
  70.  
  71. static char mail_stat (MAILP);
  72. static int xmit_install (MAILP, int, char *);
  73. static void xmit_sort (void);
  74.  
  75. void xmit_sameplace()
  76.     {
  77.     MAILP p, p1;
  78.  
  79.     /* Find the guy we just gave mail to */
  80.     p = find_mail (&remote_addr);
  81.     remote_addr.Zone = remote_addr.Net = remote_addr.Node = remote_addr.Point = 0;
  82.     remote_addr.Domain = NULL;
  83.     if (p == NULL)
  84.         {
  85.         /* He is not there */
  86.         return;
  87.         }
  88.  
  89.     /* Save our current pointer */
  90.     p1 = next_mail;
  91.     if (p != next_mail)
  92.         {
  93.         /* If it is not the one we just gave mail to, save ptr and delete */
  94.         next_mail = p;
  95.         xmit_delete ();
  96.         next_mail = p1;
  97.         }
  98.     else
  99.         {
  100.         /* It was the guy at the head of the list, so just delete him */
  101.         xmit_delete ();
  102.         }
  103.  
  104.     /* If we came in with a null, leave with a null */
  105.     if (p1 == NULL)
  106.         next_mail = NULL;
  107.  
  108.     return;
  109.     }
  110.  
  111.  
  112.  
  113. MAILP find_mail(address)
  114. ADDR *address;
  115.     {
  116.     MAILP p;
  117.  
  118.     p = mail_top;
  119.     while (p != NULL)
  120.         {
  121.         if ((no_zones || (p->mail_addr.Zone == address->Zone)) &&
  122.             (p->mail_addr.Net == address->Net) &&
  123.             (p->mail_addr.Node == address->Node) &&
  124.             (p->mail_addr.Point == address->Point) &&
  125.             ((p->mail_addr.Domain == address->Domain) ||
  126.             ((p->mail_addr.Domain == my_addr.Domain) &&
  127.             (address->Domain == NULL))))
  128.             break;
  129.         p = p->next;
  130.         }
  131.  
  132.     return (p);
  133.     }
  134.  
  135.  
  136.  
  137. static int xmit_install (p, zone, domain)
  138. MAILP p;
  139. int zone;
  140. char *domain;
  141.     {
  142.     MAILP p1, p2;
  143.     int rettype;
  144.    ADDR tmp;
  145.  
  146. #ifdef IBMC
  147.     char tnet[5], tnode[5];
  148. #endif
  149.  
  150.  
  151. #ifndef IBMC
  152.     if (sscanf (dta_str.name, "%04x%04x.", &(tmp.Net), &(tmp.Node)) != 2)
  153.         return (1);
  154. #else
  155.     if (sscanf (dta_str.name, "%4s%4s.", tnet, tnode) != 2)
  156.         return (1);
  157.     if (sscanf (tnet, "%04x", &(tmp.Net)) + sscanf (tnode, "%04x", &(tmp.Node)) != 2)
  158.         return (1);
  159. #endif /* IBMC */
  160.  
  161.     tmp.Zone = zone;
  162.     tmp.Domain = domain;
  163.     tmp.Point = 0;
  164.  
  165.     p2 = find_mail (&tmp);
  166.     if (p2 == NULL)
  167.         {
  168.         /* We didn't find it in what we have already */
  169.         p1 = p;
  170.         p1->mail_addr.Zone = tmp.Zone;
  171.         p1->mail_addr.Net = tmp.Net;
  172.         p1->mail_addr.Node = tmp.Node;
  173.         p1->mail_addr.Point = tmp.Point;
  174.         p1->mail_addr.Domain = tmp.Domain;
  175.         rettype = 0;
  176.         }
  177.     else
  178.         {
  179.         /* We found it, so we have to make sure the higher level routine knows */
  180.         p1 = p2;
  181.         rettype = 1;
  182.         }
  183.  
  184.     switch (dta_str.name[9])
  185.         {
  186.         case 'C':      /* Crash */
  187.             p1->mailtypes |= MAIL_CRASH;
  188.             break;
  189.  
  190.         case 'H':      /* Hold */
  191.             p1->mailtypes |= MAIL_HOLD;
  192.             break;
  193.  
  194.         case 'F':      /* Normal */
  195.         case 'O':
  196.             p1->mailtypes |= MAIL_NORMAL;
  197.             break;
  198.  
  199.         case 'D':      /* Direct */
  200.             p1->mailtypes |= MAIL_DIRECT;
  201.             break;
  202.  
  203.         case 'R':      /* Request */
  204.             p1->mailtypes |= MAIL_REQUEST;
  205.             break;
  206.         }
  207.  
  208.     if (!nodefind (&(p1->mail_addr), 0))
  209.         {
  210.         p1->mailtypes |= MAIL_UNKNOWN;
  211.         return (rettype);
  212.         }
  213.  
  214.     /* Don't call for "HOLD" or "REQ" stuff. */
  215.     if ((dta_str.name[9] == 'H') || (dta_str.name[9] == 'R'))
  216.         return (rettype);
  217.  
  218.     /* If there's no event, set mail to 'go' */
  219.     if (cur_event < 0)
  220.         {
  221.         p1->mailtypes |= MAIL_WILLGO;
  222.         return (rettype);
  223.         }
  224.  
  225.     /* If it is a crash only event and this wasn't crash, return */
  226.     if ((dta_str.name[9] != 'C') && (e_ptrs[cur_event]->behavior & MAT_CM))
  227.         return (rettype);
  228.  
  229.     /* Is this a local only event? */
  230.     if (e_ptrs[cur_event]->behavior & MAT_LOCAL)
  231.         {
  232.         /*
  233.         * If this is supposed to be only local, then get out if it isn't
  234.         */
  235.         if (e_ptrs[cur_event]->node_cost >= 0)
  236.             {
  237.             if ((int) newnodedes.RealCost > e_ptrs[cur_event]->node_cost)
  238.                 return (rettype);
  239.             }
  240.         else
  241.             {
  242.             if ((int) newnodedes.RealCost < -e_ptrs[cur_event]->node_cost)
  243.                 return (rettype);
  244.             }
  245.         }
  246.  
  247.     /* Is this a non-mail window event? */
  248.     if (newnodelist && (!(e_ptrs[cur_event]->behavior & MAT_NOMAIL24)))
  249.         {
  250.         /* If this guy can't handle crash, get out and try again */
  251.         if (!(newnodedes.NodeFlags & B_CM))
  252.             return (rettype);
  253.         }
  254.  
  255.     /* Is this a receive only event? */
  256.     if (e_ptrs[cur_event]->behavior & MAT_NOOUT)
  257.         return (rettype);
  258.  
  259.     /* Is this a non-CM event? */
  260.     if (newnodelist && (e_ptrs[cur_event]->behavior & MAT_NOCM) &&
  261.         (newnodedes.NodeFlags & B_CM))
  262.         return (rettype);
  263.  
  264.     /* See if we spent too much calling him already */
  265.     if (bad_call (&(p1->mail_addr), 0))
  266.         {
  267.         p1->mailtypes |= MAIL_TOOBAD;
  268.         return (rettype);
  269.         }
  270.  
  271.     p1->mailtypes |= MAIL_WILLGO;
  272.  
  273.     return (rettype);
  274.     }
  275.  
  276.  
  277.  
  278. static char mail_stat (p)
  279. MAILP p;
  280.     {
  281.     if (p->mailtypes & MAIL_UNKNOWN)
  282.         return ('!');
  283.     if (p->mailtypes & MAIL_TOOBAD)
  284.         return ('x');
  285.     if (p->mailtypes & MAIL_TRIED)
  286.         return ('#');
  287.     if (p->mailtypes & MAIL_WILLGO)
  288.         return ('*');
  289.     return ('-');
  290.     }
  291.  
  292.  
  293.  
  294. static char *mail_status_chars (unsigned int);
  295. char msc[10];
  296.  
  297.  
  298.  
  299. static char *mail_status_chars (p)
  300. unsigned int p;
  301.     {
  302.     char *q;
  303.  
  304.     q = msc;
  305.  
  306.     if (p & MAIL_CRASH  )
  307.         *q++ = 'C';
  308.     if (p & MAIL_HOLD   )
  309.         *q++ = 'H';
  310.     if (p & MAIL_DIRECT )
  311.         *q++ = 'D';
  312.     if (p & MAIL_NORMAL )
  313.         *q++ = 'N';
  314.     if (p & MAIL_REQUEST)
  315.         *q++ = 'R';
  316.     *q++ = '\0';
  317.  
  318.     return (msc);
  319.     }
  320.  
  321.  
  322.  
  323. void xmit_window (p1)
  324. MAILP p1;
  325.     {
  326.     MAILP p;
  327.     int i;
  328.     char j[40];
  329.     char j1[40];
  330.  
  331.     if (!fullscreen)
  332.         return;
  333.  
  334.     p = p1;
  335.  
  336.     sb_fillc (holdwin, ' ');
  337.  
  338.     if (p == NULL)
  339.         {
  340.         sb_move (holdwin, 3, 5);
  341.         sb_puts (holdwin, (unsigned char *) msgtxt[M_NOTHING_IN_OUTBOUND]);
  342.         return;
  343.         }
  344.  
  345.     sb_move (holdwin, 1, 2);
  346.     sb_puts (holdwin, (unsigned char *) msgtxt[M_OUTBOUND_HEADER]);
  347.  
  348.     for (i = 2; i < 6; i++)
  349.         {
  350.         if (p == NULL)
  351.             break;
  352.  
  353.         sb_move (holdwin, i, 2);
  354.         sprintf (j, "%s", Full_Addr_Str (&(p->mail_addr)));
  355.         sprintf (j1, "%-21.21s %5.5s %c", j,
  356.         mail_status_chars (p->mailtypes),
  357.         mail_stat (p));
  358.         sb_puts (holdwin, (unsigned char *) j1);
  359.         p = p->next;
  360.         }
  361.  
  362.     p = mail_top;
  363.  
  364.     for (; i < 6; i++)
  365.         {
  366.         if ((p == p1) || (p == NULL))
  367.             break;
  368.  
  369.         sb_move (holdwin, i, 2);
  370.         sprintf (j, "%s", Full_Addr_Str (&(p->mail_addr)));
  371.         sprintf (j1, "%-21.21s %5.5s %c", j,
  372.         mail_status_chars (p->mailtypes),
  373.         mail_stat (p));
  374.         sb_puts (holdwin, (unsigned char *) j1);
  375.         p = p->next;
  376.         }
  377.  
  378.     sb_show ();
  379.     }
  380.  
  381.  
  382.  
  383. static void xmit_sort ()
  384.     {
  385.     MAILP p, p1, p2;
  386.  
  387.     p = mail_top;
  388.  
  389.     /* Find the first that is sendable */
  390.     while (p != NULL)
  391.         {
  392.         if ((p->mailtypes & MAIL_WILLGO) &&
  393.             (!(p->mailtypes & MAIL_TOOBAD)) &&
  394.             (!(p->mailtypes & MAIL_UNKNOWN)))
  395.             break;
  396.         p = p->next;
  397.         }
  398.  
  399.     if (p == NULL)
  400.         return;
  401.  
  402.     /* Put the first sendable one on top */
  403.     if (p != mail_top)
  404.         {
  405.         p->prev->next = p->next;
  406.         if (p->next != NULL)
  407.             p->next->prev = p->prev;
  408.         p->prev = NULL;
  409.         p->next = mail_top;
  410.         mail_top->prev = p;
  411.         mail_top = p;
  412.         }
  413.  
  414.     p1 = p;
  415.     p = p1->next;
  416.     while (p != NULL)
  417.         {
  418.         if ((p->mailtypes & MAIL_WILLGO) &&
  419.             (!(p->mailtypes & MAIL_TOOBAD)) &&
  420.             (!(p->mailtypes & MAIL_UNKNOWN)))
  421.             {
  422.             if (p->prev == p1)
  423.                 {
  424.                 p1 = p;
  425.                 p = p->next;
  426.                 continue;
  427.                 }
  428.             p2 = p->next;
  429.             p->prev->next = p->next;
  430.             if (p->next != NULL)
  431.                 p->next->prev = p->prev;
  432.             p->next = p1->next;
  433.             if (p1->next != NULL)
  434.                 p1->next->prev = p;
  435.             p->prev = p1;
  436.             p1->next = p;
  437.             p1 = p;
  438.             p = p2;
  439.             }
  440.         else
  441.             p = p->next;
  442.         }
  443.     }
  444.  
  445.  
  446.  
  447. void xmit_reset ()
  448.     {
  449.     MAILP p;
  450.     int i, j, k, done, zone;
  451.     char *domain;
  452.     ADDR tmp;
  453.  
  454.     /* First get rid of all the old junk */
  455.     p = mail_top;
  456.     if (p != NULL)
  457.         {
  458.         while (p->next != NULL)
  459.             p = p->next;
  460.         while (p->prev != NULL)
  461.             {
  462.             p = p->prev;
  463.             free (p->next);
  464.             }
  465.         if (p != NULL)
  466.             free (p);
  467.         }
  468.  
  469.     p = mail_top = NULL;
  470.  
  471.     k = 0;
  472.     domain = domain_name[0];
  473.  
  474.     do
  475.         {
  476.         zone = (int) alias[0].Zone;
  477.  
  478.         while (zone > 0)
  479.             {
  480.             i = 0;
  481.             while (outb[i] != NULL)
  482.                 {
  483.                 tmp.Zone = zone;
  484.                 tmp.Net = 0;
  485.                 tmp.Node = 0;
  486.                 tmp.Point = 0;
  487.                 tmp.Domain = domain;
  488.                 sprintf (next_one, "%s%s", HoldAreaNameMunge(&tmp), outb[i++]);
  489.  
  490.                 done = 0;
  491.                 j = 0;
  492.  
  493.                 while (!done)
  494.                     {
  495.                     /* See if we have any more at this level */
  496. #ifndef OS_2
  497.                     if (dfind (&dta_str, next_one, j))
  498. #else
  499.                     if ( (j) ? dir_findnexta (&dta_str) : dir_findfirsta (next_one, _A_NORMAL, &dta_str))
  500. #endif
  501.                         {
  502.                         /* No more at this level, so go to next level */
  503.                         done = 1;
  504.                         }
  505.                     else
  506.                         {
  507.                         /* We found a name, remember it */
  508.                         if (p == NULL)
  509.                             p = mail_top = (MAILP) calloc (sizeof (MAIL), 1);
  510.                         else
  511.                             {
  512.                             p->next = (MAILP) calloc (sizeof (MAIL), 1);
  513.                             p->next->prev = p;
  514.                             p = p->next;
  515.                             }
  516.  
  517.                         if (xmit_install (p, zone, domain))
  518.                             {
  519.                             /* No good */
  520.                             if (p->prev != NULL)
  521.                                 {
  522.                                 p = p->prev;
  523.                                 free (p->next);
  524.                                 p->next = NULL;
  525.                                 }
  526.                             else
  527.                                 {
  528.                                 free (p);
  529.                                 p = mail_top = NULL;
  530.                                 }
  531.                             }
  532.  
  533.                         ++j;
  534.                         } /* got one */
  535.                     } /* while (!done) */
  536.                 } /* while (outb[i] != null */
  537.  
  538.             if (no_zones)
  539.                 break;
  540.  
  541.             /* Get the next zone number */
  542.             tmp.Zone = -1;
  543.             zone = nodefind (&tmp, 0);
  544.             if (zone == (int) alias[0].Zone)
  545.                 zone = nodefind (&tmp, 0);
  546.             }
  547.  
  548.         domain = domain_name[++k];
  549.         }
  550.     while (domain != NULL);
  551.  
  552.     next_mail = NULL;
  553.  
  554.     xmit_sort ();
  555.  
  556.     xmit_window (mail_top);
  557.     }
  558.  
  559.  
  560.  
  561. int xmit_next (xaddr)
  562. ADDR *xaddr;
  563.     {
  564.     /* Set up the proper pointer */
  565.     if ((next_mail == NULL) || (next_mail->next == NULL))
  566.         next_mail = mail_top;
  567.     else
  568.         next_mail = next_mail->next;
  569.  
  570.     /* Loop through till we find something we can send */
  571.     while (next_mail != NULL)
  572.         {
  573.         if ((next_mail->mailtypes & MAIL_WILLGO) &&
  574.             (!(next_mail->mailtypes & MAIL_UNKNOWN)) &&
  575.             (!(next_mail->mailtypes & MAIL_TOOBAD)))
  576.             {
  577.             if (bad_call (&(next_mail->mail_addr), 0))
  578.                 next_mail->mailtypes |= MAIL_TOOBAD;
  579.             else
  580.                 {
  581.                 xaddr->Zone = next_mail->mail_addr.Zone;
  582.                 xaddr->Net = next_mail->mail_addr.Net;
  583.                 xaddr->Node = next_mail->mail_addr.Node;
  584.                 xaddr->Point = next_mail->mail_addr.Point;
  585.                 xaddr->Domain = next_mail->mail_addr.Domain;
  586.                 xmit_window (next_mail);
  587.                 return (1);
  588.                 }
  589.             }
  590.         next_mail = next_mail->next;
  591.         }
  592.  
  593.     /* Read the disk again since we reached the end of the list */
  594. #ifdef OS_2
  595.     xmit_reset ();
  596. #endif
  597.  
  598.     next_mail = mail_top;
  599.  
  600.     /* Try the new list and see what happens */
  601.     while (next_mail != NULL)
  602.         {
  603.         if ((next_mail->mailtypes & MAIL_WILLGO) &&
  604.             (!(next_mail->mailtypes & MAIL_UNKNOWN)) &&
  605.             (!(next_mail->mailtypes & MAIL_TOOBAD)))
  606.             {
  607.             if (bad_call (&(next_mail->mail_addr), 0))
  608.                 next_mail->mailtypes |= MAIL_TOOBAD;
  609.             else
  610.                 {
  611.                 xaddr->Zone = next_mail->mail_addr.Zone;
  612.                 xaddr->Net = next_mail->mail_addr.Net;
  613.                 xaddr->Node = next_mail->mail_addr.Node;
  614.                 xaddr->Point = next_mail->mail_addr.Point;
  615.                 xaddr->Domain = next_mail->mail_addr.Domain;
  616.                 xmit_window (next_mail);
  617.                 return (1);
  618.                 }
  619.             }
  620.         next_mail = next_mail->next;
  621.         }
  622.  
  623.     /* Oh well, we tried */
  624.     xmit_window (mail_top);
  625.     return (0);
  626.     }
  627.  
  628.  
  629.  
  630. void xmit_delete ()
  631.     {
  632.     MAILP p;
  633.     int i;
  634.  
  635.     if (next_mail == NULL)
  636.         return;
  637.  
  638.     i = 0;
  639.     while (outb[i] != NULL)
  640.         {
  641.         sprintf (next_one, "%s%s.%s",
  642.             HoldAreaNameMunge(&(next_mail->mail_addr)),
  643.             Hex_Addr_Str (&(next_mail->mail_addr)),
  644.             &(outb[i++][2]));
  645.  
  646.         if (!dfind (&dta_str, next_one, 0))
  647.             {
  648.             status_line (msgtxt[M_STILL_HAVE_MAIL], Full_Addr_Str (&(next_mail->mail_addr)));
  649.             /* We still have something for him */
  650.             next_mail->mailtypes &= ~MAIL_WILLGO;
  651.             next_mail->mailtypes |= MAIL_TRIED;
  652.             return;
  653.             }
  654.         }
  655.  
  656.     if (next_mail != mail_top)
  657.         {
  658.         p = next_mail->next;
  659.         next_mail = next_mail->prev;
  660.         free (next_mail->next);
  661.         next_mail->next = p;
  662.         if (p != NULL)
  663.             p->prev = next_mail;
  664.         xmit_window (next_mail);
  665.         }
  666.     else
  667.         {
  668.         mail_top = mail_top->next;
  669.         free (next_mail);
  670.         if (mail_top != NULL)
  671.             mail_top->prev = NULL;
  672.         xmit_window (mail_top);
  673.         next_mail = NULL;
  674.         }
  675.     }
  676.  
  677.  
  678.  
  679. static char fname[80];
  680. static char fname1[80];
  681.  
  682.  
  683.  
  684. int bad_call (baddr, rwd)
  685. ADDR *baddr;
  686. int rwd;
  687.     {
  688.     int res;
  689.     int i, j;
  690.     struct FILEINFO bad_dta;
  691.     FILE *bad_wazoo;
  692.     char *p;
  693.     char *HoldName;
  694.  
  695.     HoldName = HoldAreaNameMunge(baddr);
  696.     sprintf (fname, "%s%s.$$?", HoldName, Hex_Addr_Str (baddr));
  697.     j = (int) strlen (fname) - 1;                       /* Point at ?          */
  698.     res = -1;                                     /* Initialize to fail  */
  699.  
  700.     i = 0;                                        /* This says findfirst */
  701.     while (!dfind (&bad_dta, fname, i))           /* as long as we match */
  702.         {
  703.         if (isdigit (bad_dta.name[11]))            /* is there a digit?   */
  704.             {
  705.             fname[j] = bad_dta.name[11];            /* Yes, copy to fname  */
  706.             res = fname[j] - '0';                   /* Save it for testing */
  707.             break;                                  /* Get out of while    */
  708.             }
  709.         else i = 1;                                /* Else use findnext   */
  710.         }
  711.  
  712.     if (res == -1)                                /* Successful search?  */
  713.         fname[j] = '0';                            /* No, base digit = 0  */
  714.  
  715.     if (rwd > 0)
  716.         {
  717.         /* Writing a bad call  */
  718.  
  719.         /* First create a filename that is one higher than what we've got */
  720.         strcpy (fname1, fname);
  721.         fname1[j]++;
  722.         if (fname1[j] > '9')
  723.             fname1[j] = '9';
  724.  
  725.         if (res == -1)                             /* Did we have a file? */
  726.             {                                       /* No, make one.       */
  727.             if (rwd == 2)                           /* No carrier */
  728.                 res = open (fname, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
  729.             else /* With carrier */
  730.                 res = open (fname1, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
  731.             i = rwd - 1;                            /* zero-based count    */
  732.             write (res, (char *) &i, sizeof (int)); /* write it out        */
  733.             close (res);                            /* close the file      */
  734.             }
  735.         else
  736.             {                                       /* There was a file    */
  737.  
  738.             /*
  739.             * 2 = Unsuccessful, No carrier. Update contents of the file.
  740.             */
  741.  
  742.             if (rwd == 2)
  743.                 {
  744.                 i = open (fname, O_RDONLY|O_BINARY);
  745.                 read (i, (char *) &res, sizeof (int));
  746.                 close (i);
  747.  
  748.                 ++res;
  749.  
  750.                 i = open (fname, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
  751.                 write (i, (char *) &res, sizeof (int));
  752.                 close (i);
  753.                 }
  754.  
  755.             /*
  756.             * 1 = Unsuccessful, Carrier. Update file name to reflect the
  757.             * failure.
  758.             */
  759.  
  760.             else
  761.                 {
  762.                 rename (fname, fname1);
  763.                 }
  764.             }
  765.         }
  766.     else if (rwd == 0)
  767.         {
  768.  
  769.         /*
  770.         * 0 = We are reading a bad call status
  771.         */
  772.  
  773.         /* Is it automatically ok (no .$$ file there) ? */
  774.         if (res == -1)
  775.             return (0);
  776.  
  777.         /* Were there too many connects with carrier? */
  778.         if (res >= max_connects)
  779.             return (1);
  780.  
  781.         /* Ok, check for connects without carrier */
  782.         res = 0;
  783.         i = open (fname, O_RDONLY|O_BINARY);
  784.         read (i, (char *) &res, sizeof (int));
  785.         close (i);
  786.         return (res >= max_noconnects);
  787.         }
  788.     else
  789.         {
  790.  
  791.         /*
  792.         * -1 = Cleanup of bad call status. This happens in two steps:
  793.         * a) delete 'netnode.$$?' in hold area;
  794.         * b) if a 'netnode.Z' file exists in hold area,
  795.         *    1) delete all BADWAZOO.xxx files listed in the .Z file;
  796.         *    2) delete the 'netnode.z' file.
  797.         */
  798.  
  799.         if (res != -1)
  800.             unlink (fname);
  801.  
  802.         if (!mail_finished)
  803.             return (0);
  804.  
  805.         sprintf (fname, "%s%s.Z", HoldName, Hex_Addr_Str (baddr));
  806.         if (dexists (fname))
  807.             {
  808.             if ((bad_wazoo = fopen (fname, read_ascii)) == NULL)
  809.                 got_error (msgtxt[M_OPEN_MSG], fname);
  810.             else
  811.                 {
  812.                 while (!feof (bad_wazoo))
  813.                     {
  814.                     e_input[0] = '\0';
  815.                     if (!fgets (e_input, 64, bad_wazoo))
  816.                         break;
  817.                     /* Point to BADWAZOO.xxx */
  818.                     p = strchr (e_input, ' ') + 1;
  819.                     /* Then just past it and terminate */
  820.                     p = strchr (p, ' ');
  821.                     *p = '\0';
  822.                     /* Back to where we were */
  823.                     p = strchr (e_input, ' ') + 1;
  824.  
  825.                     /* Build file name and delete file */
  826.                     strcpy (fname1, CurrentNetFiles);
  827.                     strcat (fname1, p);
  828.                     unlink (fname1);
  829.                     }
  830.                 fclose (bad_wazoo);
  831.                 }
  832.             unlink (fname);
  833.             }
  834.         }
  835.     return (0);
  836.     }
  837.  
  838.  
  839.  
  840. void set_up_outbound ()
  841.     {
  842.     MAILP mp;
  843.  
  844.     xmit_reset ();
  845.  
  846.     /* and remember where we left off */
  847.     if (hist.next_net != 0)
  848.         {
  849.         next_addr.Zone = hist.next_zone;
  850.         next_addr.Net = hist.next_net;
  851.         next_addr.Node = hist.next_node;
  852.         next_addr.Point = 0;
  853.         next_addr.Domain = NULL;
  854.         mp = find_mail (&next_addr);
  855.         if ((mp == NULL) || (mp->prev == NULL))
  856.             {
  857.             next_mail = NULL;
  858.             xmit_window (mail_top);
  859.             }
  860.         else
  861.             {
  862.             next_mail = mp->prev;
  863.             xmit_window (next_mail);
  864.             }
  865.         }
  866.     else
  867.         {
  868.         next_addr.Zone = 0;
  869.         next_addr.Net = 0;
  870.         next_addr.Node = 0;
  871.         next_addr.Point = 0;
  872.         next_addr.Domain = NULL;
  873.         xmit_window (mail_top);
  874.         }
  875.     }
  876.