YOOHOO.C

18.3 KB be3759e01060e27b…
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*                                                                          */
/*      ------------         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 Vince Perriello                 */
/*                                                                          */
/*                                                                          */
/*                     BinkleyTerm "YooHoo" Processor                       */
/*                                                                          */
/*                                                                          */
/*    For complete  details  of the licensing restrictions, please refer    */
/*    to the License  agreement,  which  is published in its entirety in    */
/*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
/*                                                                          */
/*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
/*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
/*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
/*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
/*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
/*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
/*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
/*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
/*                                                                          */
/*                                                                          */
/* You can contact Bit Bucket Software Co. at any one of the following      */
/* addresses:                                                               */
/*                                                                          */
/* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
/* P.O. Box 460398                AlterNet 7:491/0                          */
/* Aurora, CO 80046               BBS-Net  86:2030/1                        */
/*                                Internet f491.n343.z1.fidonet.org         */
/*                                                                          */
/* Please feel free to contact us at any time to share your comments about  */
/* our software and/or licensing policies.                                  */
/*                                                                          */
/*                                                                          */
/*--------------------------------------------------------------------------*/

/* Include this file before any other includes or defines! */

#include "includes.h"

int Send_Hello_Packet (int);
int Recv_Hello_Packet (int);

/*--------------------------------------------------------------------------*/
/* YOOHOO SENDER    (used when I am the CALLING system)                     */
/*--------------------------------------------------------------------------*/
int YooHoo_Sender (void)
{
   char *sptr;

   if (un_attended && fullscreen)
      {
      sb_move (file_hWnd, 2, 2);
      FlLnModeSet( FILE_LN_2, 0 );
      sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 ), "YooHoo" );
      sb_show ();
      }
   else
      {
      set_xy ("YooHoo ");
      }

   /*--------------------------------------------------------------------*/
   /* Clean up any mess that may be around                               */
   /*--------------------------------------------------------------------*/
   CLEAR_OUTBOUND ();
   CLEAR_INBOUND ();
   XON_DISABLE ();

   if (!Send_Hello_Packet (1))
      sptr = MSG_TXT(M_HE_HUNG_UP);

   else
      {
      if (TIMED_READ (30) == YOOHOO)
         return Recv_Hello_Packet (1);

      status_line ("!No YOOHOO/2U2");
      sptr = IDUNNO_msg;
      }

   status_line (sptr);
   return (0);
}

/*--------------------------------------------------------------------------*/
/* YOOHOO RECEIVER  (Used when I am the CALLED system)                      */
/*--------------------------------------------------------------------------*/

int YooHoo_Receiver (void)
{
   int i;
   int c;

   if (un_attended && fullscreen)
      {
      sb_move (file_hWnd, 2, 2);
      FlLnModeSet( FILE_LN_2, 0 );
      sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 ), "YooHoo" );
      sb_show ();
      }
   else
      {
      set_xy ("YooHoo ");
      }

   /*--------------------------------------------------------------------*/
   /* Clean up any mess that may be around                               */
   /*--------------------------------------------------------------------*/
   CLEAR_OUTBOUND ();
   CLEAR_INBOUND ();
   XON_DISABLE ();

   if (Recv_Hello_Packet(0) == 0)
      return (0);

   for (i = 0; (CARRIER) && (i < 10); i++)
      {
      if ((c = TIMED_READ (10)) == ENQ)
         {
         if ((i = Send_Hello_Packet (0)) == 0)
            b_init ();
         return (i);
         }

      if (c > 0)
         {
         (void) printf ("[%x] ", c);

         /* Delay one second, then try again */
         big_pause (1);

         CLEAR_INBOUND ();
         }

      SENDBYTE (YOOHOO);
      }

   status_line (MSG_TXT(M_FUBAR_MSG));
   b_init ();
   return (0);

}                                                /* YooHoo Receiver */

/*--------------------------------------------------------------------------*/
/* SEND HELLO PACKET                                                        */
/*--------------------------------------------------------------------------*/
int Send_Hello_Packet (int Sender)
{
   int i;
   struct _Hello Hello;
   char *sptr;
   long response_timer;
   word crc;
   word num_errs = 0;
   word can_do_domain = 0;
   char junkbuff[128];

   /*--------------------------------------------------------------------*/
   /* Setup HELLO structure                                              */
   /*--------------------------------------------------------------------*/
   (void) memset ((char *) &Hello, 0, sizeof (struct _Hello));

   Hello.signal = 'o';
   Hello.hello_version = 1;

   Hello.product = PRDCT_CODE;
   Hello.product_maj = BINK_MAJVERSION;
   Hello.product_min = BINK_MINVERSION;

   (void) strncpy (Hello.sysop, sysop, 19);
   Hello.sysop[19] = '\0';

   Hello.my_zone = alias[assumed].Zone;
   if ((pvtnet >= 0) && (Sender) &&
       ((called_addr.Zone == boss_addr.Zone) || (called_addr.Zone == 0) || (boss_addr.Zone == 0)) &&
       (called_addr.Net == boss_addr.Net) && (called_addr.Node == boss_addr.Node) &&
       ((called_addr.Domain == boss_addr.Domain) || (boss_addr.Domain == NULL) || (called_addr.Domain == NULL)))
      {
      Hello.my_net = boss_addr.Net;
      Hello.my_node = boss_addr.Node;
      Hello.my_point = alias[assumed].Node;
      }
   else
      {
      Hello.my_net = alias[assumed].Net;
      Hello.my_node = alias[assumed].Node;
      Hello.my_point = alias[assumed].Point;
      }
/*
 * If we are the calling system, turn on all our capabilities.
 * If we are the called system, choose from the set that the
 * caller gave us, and only send the one we prefer.
 */
   can_do_domain = (my_addr.Domain != NULL) ? DO_DOMAIN : 0;
   if (!Sender)
      {
      can_do_domain = remote_capabilities & can_do_domain;
      if (remote_capabilities & my_capabilities & DOES_IANUS)
         Hello.capabilities = DOES_IANUS;
      else if (remote_capabilities & my_capabilities & ZED_ZAPPER)
         Hello.capabilities = ZED_ZAPPER;
      else if (remote_capabilities & my_capabilities & ZED_ZIPPER)
         Hello.capabilities = ZED_ZIPPER;
      else if (remote_capabilities & my_capabilities & Y_DIETIFNA)
         Hello.capabilities = Y_DIETIFNA;
      }
   else Hello.capabilities = my_capabilities;

   (void) strncpy (Hello.my_name, system_name, 58);
   Hello.my_name[58] = '\0';
   Hello.capabilities |= can_do_domain;
   if (can_do_domain && (alias[assumed].Domain != NULL))
      {
      if (strlen (system_name) + strlen (alias[assumed].Domain) > 57)
         {
         Hello.my_name[57 - strlen (alias[assumed].Domain)] = '\0';
         }
      sptr = Hello.my_name + strlen (Hello.my_name) + 1;
      (void) strcpy (sptr, alias[assumed].Domain);
      }

   if (n_getpassword (&remote_addr))
      {
      (void) strncpy ((char *)Hello.my_password, remote_password, 8);
      }

   if ((matrix_mask & TAKE_REQ) &&
       ((!Sender) || (on_our_nickel)))
      Hello.capabilities |= WZ_FREQ;

   /*--------------------------------------------------------------------*/
   /* Disable handshaking and ^C/^K handling                             */
   /*--------------------------------------------------------------------*/
   XON_DISABLE ();

   /*--------------------------------------------------------------------*/
   /* Send the packet.                                                   */
   /* Load outbound buffer quickly, and get modem busy sending.          */
   /*--------------------------------------------------------------------*/

xmit_packet:

   SENDBYTE (0x1f);

   sptr = (char *) (&Hello);
   SENDCHARS (sptr, 128, 1);

   /*--------------------------------------------------------------------*/
   /* Calculate CRC while modem is sending its buffer                    */
   /*--------------------------------------------------------------------*/
   for (crc = i = 0; i < 128; i++)
      {
      crc = xcrc (crc, (byte) sptr[i]);
      }

   CLEAR_INBOUND ();

   SENDBYTE ((unsigned char) (crc >> 8));
   SENDBYTE ((unsigned char) (crc & 0xff));

   response_timer = timerset (4000);

   while (!timeup(response_timer) && CARRIER)
      {
      if (!CHAR_AVAIL ())
         {
         if (got_ESC ())
            {
            LOWER_DTR ();
            sptr  = MSG_TXT(M_KBD_MSG);
            goto no_response;
            }
         time_release ();
         continue;
         }   

      switch (i = TIMED_READ (0))
         {
         case ACK:
            return (1);

         case '?':
            status_line (MSG_TXT(M_DRATS));

         case ENQ:
            if (++num_errs == 10)
                {
                sptr = MSG_TXT(M_FUBAR_MSG);
                goto no_response;
                }
            goto xmit_packet;

         default:
            if (i > 0)                   /* Could just be line noise */
               {
               }
            break;
         }
      }

   if (!CARRIER)
      sptr = MSG_TXT(M_NO_CARRIER);
   else
      {
      (void) sprintf (junkbuff, "!%s",MSG_TXT(M_TIMEOUT));
      sptr = junkbuff;
      }

no_response:

   status_line (sptr);
   return (0);

}                                                /* Send Hello */


/*--------------------------------------------------------------------------*/
/* RECEIVE HELLO PACKET                                                     */
/*--------------------------------------------------------------------------*/
int Recv_Hello_Packet (int Sender)
{
   int i;
   int c;
   int j;
   struct _Hello Hello;
   char *sptr, *p;
   byte num_errs = 0;
   word crc;
   word lsb;
   word msb;
   long master_timeout, hello_timeout;
   char junkbuff[128];
   ADDR his_boss;

   sptr = NULL;

   /*--------------------------------------------------------------------*/
   /* Get the Hello structure                                            */
   /*--------------------------------------------------------------------*/

/* big_pause (1);  */                           /* Wait for quiet. */
   
   if (un_attended && fullscreen)
      {
      sb_move (file_hWnd, 2, 2);
      FlLnModeSet( FILE_LN_2, 0 );
      sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 ), "YooHoo/2U2" );
      sb_show ();
      }
   else
      {
      set_xy ("YooHoo/2U2 ");
      }

   SENDBYTE (ENQ);                               /* Let the other system know
                                                  * we heard YooHoo. */

   master_timeout = timerset (12000);   /* No more than 2 mins! */

watch_for_header:

   for (;;)
      {
      if (sptr)
         {
         status_line (sptr);
         sptr = NULL;
         }

      if ((c = TIMED_READ (20)) == 0x1f)
         break;

      if (got_ESC ())
         {
         sptr = MSG_TXT(M_KBD_MSG);
         goto receive_failed;
         }

      if (!CARRIER)
         {
         sptr = MSG_TXT(M_NO_CARRIER);
         goto receive_failed;
         }

      if (timeup(master_timeout))
         goto timeout;

      if (c >= 0)                               /* noise? */
         {
         hello_timeout = timerset (1000);       /* Look for up to 10 secs  */
         while (((c = PEEKBYTE ()) >= 0) && (c != 0x1f) && (CARRIER))
            {
            if (timeup(hello_timeout))
               break;
            (void) MODEM_IN ();                 /* Eat non-YooHoo chars    */
            }

         if (c != 0x1f)                         /* If we didn't get YooHoo */
            {
            CLEAR_INBOUND ();                   /* Throw out what we have  */
            SENDBYTE (ENQ);                     /* Start over with ENQ     */
            }
         }

      }                         /* while */


/*receive_packet:*/

   sptr = (char *) (&Hello);

   hello_timeout = timerset (3000);

   for (i = 0, crc = 0; i < 128; i++)
      {

      while (PEEKBYTE () < 0)
         {
         if (timeup (master_timeout) || timeup (hello_timeout))
            goto timeout;
        
         if (got_ESC ())
            {
            sptr = MSG_TXT(M_KBD_MSG);
            goto receive_failed;
            }

         if (!CARRIER)
            {
            sptr = MSG_TXT(M_NO_CARRIER);
            goto receive_failed;
            }

         time_release ();
   }

      c = TIMED_READ (0);

      sptr[i] = (char) c;
      crc = xcrc (crc, (byte) c);
      }

   if (!CARRIER)
      {
      sptr = MSG_TXT(M_NO_CARRIER);
      goto receive_failed;
      }

   if (((int)(msb = TIMED_READ (10)) < 0) || ((int)(lsb = TIMED_READ (10)) < 0))
      {
      sptr = MSG_TXT(M_SHRT_MSG);
      goto hello_error;
      }

   if (((msb << 8) | lsb) == crc)
      goto process_hello;

   (void) sprintf (junkbuff, "!%s", MSG_TXT(M_CRC_MSG));
   sptr = junkbuff;

hello_error:

   if (timeup(master_timeout))
      goto timeout;

   if ((num_errs++) > 10)
      {
      sptr = MSG_TXT(M_FUBAR_MSG);
      goto receive_failed;
      }

   CLEAR_INBOUND ();
   SENDBYTE ('?');
   goto watch_for_header;

process_hello:

  /* The idea for removing junk characters came from Holger Schurig */
  /* Get rid of junk characters */
  for (p = Hello.my_name; *p != '\0'; p++)
    if (*p < ' ')
      *p = ' ';

  /* Get rid of junk characters */
  for (p = Hello.sysop; *p != '\0'; p++)
    if (*p < ' ')
      *p = ' ';

   remote_addr.Zone = Hello.my_zone;
   remote_addr.Net = Hello.my_net;
   remote_addr.Node = Hello.my_node;
   remote_addr.Point = Hello.my_point;
   if ((Hello.capabilities & DO_DOMAIN) && (my_addr.Domain != NULL))
      {
      remote_addr.Domain = find_domain (&(Hello.my_name[strlen (Hello.my_name) + 1]));
      }
   else
      remote_addr.Domain = NULL;


   if (strlen (Hello.my_name) > 42)
      Hello.my_name[42] = '\0';

   Hello.sysop[19] = '\0';

   remote_capabilities = Hello.capabilities;

   his_boss = remote_addr;
   his_boss.Point = 0;

   if (nodefind (&his_boss, 0) && !remote_addr.Zone)
      remote_addr.Zone = found_zone;

   (void) sprintf (junkbuff, "*%s (%s)",
            Hello.my_name,
            Full_Addr_Str (&remote_addr));
   status_line (junkbuff);

   if ((pvtnet >= 0) &&
       ((remote_addr.Zone == alias[assumed].Zone) || (remote_addr.Zone == 0)) &&
       (remote_addr.Net == boss_addr.Net) && (remote_addr.Node == boss_addr.Node) &&
       (remote_addr.Point > 0))
      {
      remote_addr.Net = pvtnet;
      remote_addr.Node = Hello.my_point;
      remote_addr.Point = 0;
      }

   log_product (Hello.product, Hello.product_maj, Hello.product_min);

#ifdef MILQ
   if ( isMILQUE == Hello.product )
     UsePaths = TRUE;
   if ( UsePaths )
     status_line( " Paths Will Be Used" );
#endif

   if (Hello.sysop[0])
      status_line (":Sysop: %s", Hello.sysop);

   if ((pvtnet >= 0) && (remote_addr.Point > 0))
      {
      remote_addr.Point = 0;
      remote_addr.Node = (unsigned int) -1;
      }

   if (n_getpassword (&remote_addr))
      {
      if ((j = n_password ((char *)Hello.my_password, remote_password)) != 0)
         {
         if ((j == 1) || ((j == 2) && (!Sender)))
            {
            LOWER_DTR ();                            /* He'll never get it right */
            timer (2);                             /* Wait two secs */
            sptr = NULL;                           /* Already logged something */
            goto receive_failed;
            }
         else
            {
            status_line (MSG_TXT(M_PASSWORD_OVERRIDE));
            }
         }
      }

   CLEAR_INBOUND ();

   SENDBYTE (ACK);
   SENDBYTE (YOOHOO);

   return (1);
 
timeout:

   (void) sprintf (junkbuff, "!%s",MSG_TXT(M_TIMEOUT));
   sptr = junkbuff;

receive_failed:

   status_line (sptr);
   b_init ();
   return (0);
}                                               /* Recv Hello */

/* END OF FILE: yoohoo.c */