MISC.C

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

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

#include "includes.h"

#define EVENT_ENABLE

#ifdef Snoop
#include "snserver.h"
extern HSNOOP hsnoop;
#endif /* Snoop */

static char newstring[200];
void fill_in_status (char *);
int find_addr (char *, ADDR *, char *);


int set_baud (unsigned baudrate, int log)
{
   register int i;
   unsigned search_rate;

   search_rate = (baudrate > max_baud.rate_value) ? max_baud.rate_value : baudrate;

   for (i = 0; btypes[i].rate_value; i++)
      {
      if (btypes[i].rate_value >= search_rate)
         {
         if ((btypes[i].rate_value != search_rate) && (search_rate < 9600))
            break;

         if (baud != i)                          /* same as what we have?     */
            {
            if (log && !un_attended)
               status_line (MSG_TXT(M_SETTING_BAUD), baudrate);
            baud = i;                            /* need this for ALT-B       */
            program_baud ();
            cur_baud = btypes[i];
            }

         cur_baud.rate_value = baudrate;


         if (un_attended && fullscreen)
            {
            (void) sprintf (junk, "%-5u Com%d", baudrate, port_ptr + 1);
            sb_move (settings_hWnd, SET_PORT_ROW, SET_COL);
            sb_puts( settings_Port, junk );
            sb_show ();
            }
         return (1);
         }
      }
   return (0);
}

void program_baud ()
{
   register unsigned int rate_mask;

   set_prior(4);                                           /* Always High    */

   if ((lock_baud && (btypes[baud].rate_value >= (unsigned)lock_baud))
   || (ARQ_lock != 0))
      rate_mask = max_baud.rate_mask;
   else
      rate_mask = btypes[baud].rate_mask;

   MDM_ENABLE (rate_mask);

   set_prior(2);                                           /* Regular        */

}

static char *specifiers = "!*+:# >";
static struct tm *tp;
static time_t ltime;

void status_line (char *fmt,...)
{
   va_list arg_ptr;

   char tmp[255];

   va_start (arg_ptr, fmt);
   if (fmt == NULL)
      return;
   (void) vsprintf (e_input, fmt, arg_ptr);
   (void) time (&ltime);
   tp = localtime (&ltime);
   if ((!fullscreen) || (!un_attended))
      {
      if ((e_input[0] != '>') || debugging_log)
         {
         (void) sprintf (tmp,"\r\n%c %02i %03s %02i:%02i:%02i " PRDCT_SHRT " %s", e_input[0],
             tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min, tp->tm_sec,
                  &e_input[1]);
         scr_printf (tmp);
         }
      }
   else
      {
      if ((e_input[0] != '>') || debugging_log)
         {
         (void) sprintf (tmp, stat_str, e_input[0],
                  tp->tm_hour, tp->tm_min, tp->tm_sec, &e_input[1]);

         fill_in_status (tmp);

#ifdef Snoop
         if(hsnoop != (HSNOOP)NULL)
            SnoopWrite(hsnoop, tmp);
#endif /* Snoop */
         }
      }
   if ((status_log != NULL) &&
       ((strchr (specifiers, e_input[0]) - strchr (specifiers, '!')) <= loglevel))
      {
      (void) fprintf (status_log, "%c %02i %s %02i:%02i:%02i BINK %s\n", e_input[0],
          tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min, tp->tm_sec,
               &e_input[1]);
      if (immed_update)
         {
         (void) fflush (status_log);
         (void) real_flush (fileno (status_log));
         need_update = 0;
         }
      else
         {
         need_update = 1;
         }
      }
   va_end (arg_ptr);
}

/*--------------------------------------------------------------------------*/
/* THROUGHPUT                                                               */
/* Print throughput message at end of transfer                              */
/*--------------------------------------------------------------------------*/
void throughput (int opt, unsigned long bytes)
{
   static long started = 0L;
   static long elapsed;
   static long cps;

   if (!opt)
      started = time (NULL);
   else if (started)
      {
      elapsed = time (NULL);
      /* The next line tests for day wrap without the date rolling over */
      if (elapsed < started)
         elapsed += 86400L;
      elapsed -= started;
      if (elapsed == 0L)
         elapsed = 1L;
      cps = (long) (bytes / (unsigned long) elapsed);
      started = (cps * 1000L) / ((long) cur_baud.rate_value);
      status_line ((char *) MSG_TXT(M_CPS_MESSAGE), cps, bytes, started);
      }
}                                                /* throughput */

void fill_in_status (char *stat_line)
{
#ifdef MILQ
   RECT                 Rect;
#endif

   (void) time (&ltime);
   tp = localtime (&ltime);
   if (fullscreen)
      {
      sb_scrl (call_hWnd, 1);

     /* This is crazy (as are all the the computations based on SB_ROWS
      * and SB_COLS).  These should be computed somewhere, and left alone.
      */

#ifdef MILQ
      GetClientRect( call_hWnd, &Rect );
      SB_ROW_STATUS = ++Rect.bottom;
#endif

#ifndef CALL_LISTBOX
      sb_move (call_hWnd, SB_ROW_STATUS, 2);
      sb_puts (call_hWnd, stat_line);
#else
      SendMessage( call_hWnd, LB_ADDSTRING, 0, (long)stat_line );
#endif

      (void) sprintf (junk, "%s %s %02d @ %02d:%02d",
               wkday[tp->tm_wday], mtext[tp->tm_mon], tp->tm_mday,
               tp->tm_hour, tp->tm_min);
      sb_move (settings_hWnd, SET_TIME_ROW, SET_TIME_COL);
      sb_puts( settings_DtTm, junk );
      sb_show ();
      }
}

void clear_statusline ()
{
   if (fullscreen)
      sb_fillc (call_hWnd, ' ');
}

#ifndef MILQ
void set_xy (char *string)
{
   WRITE_ANSI ('\r');
   WRITE_ANSI ('\n');
   scr_printf (string);
   locate_x = wherex ();
   locate_y = wherey ();
}
#endif

void _cdecl time_release ()
{
   EventSub();
   if (need_update)
      {
      (void) fflush (status_log);
      (void) real_flush (fileno (status_log));
      need_update = 0;
      }

   dos_break_off ();                            /* Turn off ^C trapping */

   (*mtask_idle) ();

}

char *fancy_str (char *string)
{
   register int flag = 0;
   char *s;

   s = string;

   while (*string)
      {
      if (isalpha (*string))                     /* If alphabetic,     */
         {
         if (flag)                               /* already saw one?   */
            *string = (char) tolower (*string);  /* Yes, lowercase it  */
         else
            {
            flag = 1;                            /* first one, flag it */
            *string = (char) toupper (*string);  /* Uppercase it       */
            }
         }
      else /* if not alphabetic  */ flag = 0;    /* reset alpha flag   */
      string++;
      }

   return (s);
}

void timer (int interval)
{
   long timeout;

   timeout = timerset ((unsigned int) (interval * 10));
   while (!timeup (timeout))
      time_release ();
}

void big_pause (int secs)
{
   long timeout;

   timeout = timerset ((unsigned int) (secs * 100));
   while (!timeup (timeout))
      {
      if (CHAR_AVAIL ())
         break;
      time_release ();
      }
}

int com_getc (int t)
{
   long t1;

   if (!CHAR_AVAIL ())
      {
      t1 = timerset ((unsigned int) (t * 100));
      while (!CHAR_AVAIL ())
         {
         if (timeup (t1))
            {
            return (EOF);
            }

         /*
          * This should work because we only do TIMED_READ when we have
          * carrier
          */
         if (!CARRIER)
            {
            return (EOF);
            }
         time_release ();
         }
      }
   return ((unsigned int)(MODEM_IN ()) & 0x00ff);
}

void scr_printf (char *string)
{
   if (string != NULL)
      if (vfossil_installed)
         (void) VioWrtTTY (string, (USHORT) strlen (string), (HVIO) 0L);
      else while (*string != 0)
         WRITE_ANSI (*string++);
}

void send_can ()
{
   int i;

   CLEAR_OUTBOUND ();
   CLEAR_INBOUND ();

   for (i = 0; i < 10; i++)
      SENDBYTE (CAN);
   for (i = 0; i < 10; i++)
      SENDBYTE (BS);
}

void invent_pkt_name (char string[])
{
   struct tm *tp;
   time_t ltime;

   (void) time (&ltime);
   tp = localtime (&ltime);
   (void) sprintf (string, "%02i%02i%02i%02i.pkt",
            tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);
}

static char *suffixes[8] = {
                            "SU", "MO", "TU", "WE", "TH", "FR", "SA", NULL
};

int is_user (char *p)
{
   char *q;
   char far *r;
   int i, j;

   if (cur_event < 0)
      return (0);

   q = strchr (p, '.');
   if (q != NULL)
      {
      ++q;
      for (i = 0; i < 6; i++)
         {
         r = &(e_ptrs[cur_event].err_extent[i][0]);
         for (j = 0; j < 3; j++)
            {
            if ((tolower (q[j]) != tolower (r[j])) && (q[j] != '?'))
               break;
            }
         if (j == 3)
            user_exits[i] = 1;
         }
      }

   return (0);
}

int is_arcmail (char *p, int n)
{
   int i;
   char c[128];

   if (!isdigit (p[n]))
      {
      return (is_user (p));
      }

   (void) strcpy (c, p);
   (void) strupr (c);

   for (i = n - 11; i < n - 3; i++)
      {
      if ((!isdigit (c[i])) && ((c[i] > 'F') || (c[i] < 'A')))
         return (is_user (p));
      }

   for (i = 0; i < 7; i++)
      {
      if (strnicmp (&c[n - 2], suffixes[i], 2) == 0)
         break;
      }

   if (i >= 7)
      {
      return (is_user (p));
      }

   got_arcmail = 1;
   return (1);
}

int get_number (char *target)
{
   ADDR gaddr;
   int k;

#ifndef MILQ
   (void) fgets (target, 100, stdin);
#endif

   k = (int) strlen (target);

#ifndef MILQ
   if (k == 1)
      return (0);
   target[--k] = '\0';                           /* no '\n' */
#endif

   if (!isdigit (target[0]) && target[0] != '\"')
      {
      (*userfunc) (target, &gaddr);
      if ((gaddr.Net != 0xffff) && (gaddr.Node != 0xffff) && (gaddr.Zone != 0xffff))
         {
         (void) sprintf (target, "%s", Full_Addr_Str (&gaddr));
         }
      else return (0);                           /* Gotta have addr */
      }
   return (1);
}

void gong ()
{
   long t;
   int i;

   if (!gong_allowed)
      return;

   for (i = 0; i < 15; i++)
      {
      WRITE_ANSI ('\07');                        /* Bell code       */
      t = timerset (100);                        /* 1 second        */
      while (!timeup (t))
         {
         if (KEYPRESS ())                        /* If key pressed, */
            {
            (void) READKB ();                    /* Throw it away   */
            return;                              /* And get out     */
            }
         }
      }
}

char *skip_blanks (char *string)
{
   while (*string && isspace (*string))
      ++string;
   return (string);
}

char *skip_to_blank (char *string)
{
   while (*string && (!isspace (*string)))
      ++string;
   return (string);
}

#ifdef DEBUG
void show_debug_name (char *string)
{
   int x, y;
   static char *filler = "                           ";

   x = wherex ();
   y = wherey ();
   gotoxy (40, 0);
   scr_printf (string);
   scr_printf (&filler[strlen (string)]);
   gotoxy (x, y);
}
#endif

int parse (char *input, struct parse_list far list[])
{
   int i, j;
   char *p;
   char far *q;

   for (i = 0; list[i].p_length; i++)
      {
      p = input;
      q = list[i].p_string;
      for (j = list[i].p_length; j > 0; j--, p++, q++)
         {
         if (tolower(*p) != tolower (*q))
            break;
         }
      if (j == 0)
         return (++i);
      }
   return (-1);
}

void change_prompt ()
{
   char *s;

   if (newstring[0])
      {
      (void) putenv (newstring);
      return;
      }

   (void) strcpy (newstring, "PROMPT=[");
   (void) strcat (newstring, xfer_id);
   (void) strcat (newstring, COMPILER_NAME);
   (void) strcat (newstring, " Shell]$_");
   s = getenv ("PROMPT");
   if (s)
      {
      (void) strcat (newstring, s);
      }
   else
      {
      (void) strcat (newstring, "$P$G");
      }

   (void) putenv (newstring);
}

void update_files (int t)
{
   char s[10];

   if (un_attended && fullscreen)
      {
      if (t)
         {
         ++hist.files_out;
         }
      else
         {
         ++hist.files_in;
         }

      (void) sprintf (s, "%d/%d", hist.files_in, hist.files_out);
      sb_move (history_hWnd, HIST_FILE_ROW, HIST_COL);
      sb_puts( history_Fl, s );
      sb_show ();
      }
}

static char *last_str[] = {
                           "     None    ",
                           "     WaZOO   ",
                           "     FTS-0001",
                           "     BBS     ",
                           "     Ext Mail"
};

void last_type (int n, ADDRP taddr)
{
   int i;
   char *p;
   char j[90];

   if (fullscreen)
      sb_move (history_hWnd, HIST_LAST_ROW, HIST_COL2);

   if ((n == 1) || (n == 2))
      {
      if (((int)taddr->Zone != -1000) && ((int)taddr->Net > 0))
         {
         (void) sprintf (j, "%s", Full_Addr_Str (taddr));
         if ((p = strchr (j, '@')) != NULL)
            *p = '\0';
         for (i = (int) strlen (j); i < 13; i++)
            j[i] = ' ';
         j[i] = '\0';
         hist.last_addr = *taddr;
         SendMessage( node_hWnd, WM_COMMAND, GD_CRNT, (long)&hist.last_addr );
         }
      else
         {
         (void) strcpy (j, "     FTS-0001");
         }
      if (fullscreen) {
         sb_puts( history_Last, j );
         }
      }
   else
      {
      if ((n < 0) || (n > 4))
         n = 0;

      if (fullscreen)
         sb_puts (history_Last, last_str[n]);
      }

   hist.last_caller = n;
}


/*--------------------------------------------------------------------------*/
/* CHECK_NETFILE -- find out if the file we've got is a netfile.            */
/*--------------------------------------------------------------------------*/

char *check_netfile (char *fname)
{
   register char *p;
   register int n;

   p = fname;
   n = (int) strlen (p) - 1;

   if ((p[n] == 't') && (p[n - 1] == 'k') && (p[n - 2] == 'p') && (p[n - 3] == '.'))
      {
      got_packet = 1;
      got_mail = 1;
      p = MSG_TXT(M_MAIL_PACKET);
      }
   else if (is_arcmail (p, n))
      {
      got_mail = 1;
      p = MSG_TXT(M_COMPRESSED_MAIL);
      }
   else
      {
      /* Don't set 'got_mail' if it's a .REQ file */
      if ((p[n] != 'q') || (p[n - 1] != 'e') || (p[n - 2] != 'r') || (p[n - 3] != '.'))
         got_mail = 1;
      p = MSG_TXT(M_NET_FILE);
      }

   return (p);
}

/*--------------------------------------------------------------------------*/
/* UNIQUE_NAME                                                              */
/* Increments the suffix of a filename as necessary to make the name unique */
/*--------------------------------------------------------------------------*/
void unique_name (char *fname)
{
   static char suffix[] = ".001";
   register char *p;
   register int n;

   if (dexists (fname))
      {                                          /* If file already exists...      */
      p = fname;
      while (*p && *p != '.')
         p++;                                    /* ...find the extension, if
                                                  * any  */
      for (n = 0; n < 4; n++)                    /* ...fill it out if
                                                  * neccessary   */
         if (!*p)
            {
            *p = suffix[n];
            *(++p) = '\0';
            }
         else p++;

      while (dexists (fname))                    /* ...If 'file.ext' exists
                                                  * suffix++ */
         {
         p = fname + strlen (fname) - 1;
         for (n = 3; n--;)
            {
            if (!isdigit (*p))
               *p = '0';
            if (++(*p) <= '9')
               break;
            else *p-- = '0';
            }                                    /* for */
         }                                       /* while */
      }                                          /* if exist */
}                                                /* unique_name */

int got_ESC ()
{
   while (KEYPRESS ())
      {
      screen_blank = 0;
      if (fullscreen && un_attended)
         sb_show ();
      if (READKB () == 27)     /* ESC pressed?        */
         {
         while (KEYPRESS ())
            (void) READKB ();
         return (1);
         }
      }
   return (0);
}

long cost_of_call (long s, long e)
{
   long a;

   a = e - s;
   a = (a + 59) / 60;
   return (a * newnodedes.RealCost);
}

void screen_clear ()
{
#ifndef MILQ
   unsigned int r;
   PCH q;

   if (!vfossil_installed)
      scr_printf ("\033[H\033[2J");
   else
      {
      for (r = 0; (int) r <= (int) SB_ROWS; r++)
         {
         q = (PCH) blanks;
         (void) VioWrtCellStr ((PCH) q, (USHORT) (SB_COLS * 2), (USHORT) r, (USHORT) 0, (HVIO) 0L);
         }

      gotoxy (0, 0);
      }
#endif
}

void clear_eol ()
{
   unsigned int x, y;
   PCH q;

   if (!vfossil_installed)
      (void) printf ("\033[K");
   else
      {
      x = (unsigned int) wherex();
      y = (unsigned int) wherey();

      q = (PCH) blanks;
      (void) VioWrtCellStr ((PCH) q, (USHORT) ((SB_COLS - x) * 2), (USHORT) y, (USHORT) x, (HVIO) 0L);
      }
}

void log_product (int product, int version, int subversion)
{
   switch (product)
      {

/*  Special case Opus.
 */
      case isOPUS:
         status_line ("%s Opus %s %d.%02d", MSG_TXT(M_REMOTE_USES),
                      MSG_TXT(M_VERSION), version,
                      (subversion == 48) ? 0 : subversion);
         break;

      default:
         status_line ("%s %s %s %d.%02d", MSG_TXT(M_REMOTE_USES),
                 PRDCT_NM(product), MSG_TXT(M_VERSION), version, subversion);
         break;
      }
return;
}

int next_minute ()
{
   time_t long_time;
   struct tm *tm;

   /* Get the current time into a structure */

   (void) time (&long_time);
   tm = localtime (&long_time);

   return ((60 - (tm->tm_sec % 60)) * 100 + 1);
}

void can_Janus (char *p)
{
   J_TYPESP j;

   janus_OK = 0;
   for (j = j_top; j != NULL; j = j->next)
      {
      if (strnicmp (p, j->j_match, strlen (j->j_match)) == 0)
         {
         janus_OK = 1;
         break;
         }
      }
}

int check_failed (char *fname, char *theirname, char *info, char *ourname)
{
   FILE *abortlog;
   char linebuf[64];
   char *p, *badname;
   int ret;

   ret = 0;
   if ((abortlog = fopen (fname, read_ascii)) == NULL)
      {
      (void) got_error (MSG_TXT(M_OPEN_MSG), fname);
      }
   else
      {
      while (!feof (abortlog))
         {
         linebuf[0] = '\0';
         if (!fgets ((p = linebuf), 64, abortlog))
            break;
         while (*p >= ' ')
            ++p;
         *p = '\0';
         p = strchr (linebuf, ' ');
         *p = '\0';
         if (!stricmp (linebuf, theirname))
            {
            p = strchr ((badname = ++p), ' ');
            *p = '\0';
            if (!stricmp (++p, info))
               {
               (void) strcpy (ourname, badname);
               ret = 1;
               break;
               }
            }
         }
      (void) fclose (abortlog);
      }

  return (ret);
}

void add_abort (char *fname, char *rname, char *cname,
                char *cpath, char *info)
{
   FILE *abortlog;
   char namebuf[100];

   (void) strcpy (namebuf, cpath);
   (void) strcat (namebuf, "BadWaZOO.001");
   unique_name (namebuf);
   (void) rename (cname, namebuf);
   if ((abortlog = fopen (fname, "at")) == NULL)
      {
      (void) got_error (MSG_TXT(M_OPEN_MSG), fname);
      (void) unlink (namebuf);
      }
   else
      {
      (void) fprintf (abortlog, "%s %s %s\n", rname, namebuf + strlen (cpath), info);
      (void) fclose (abortlog);
      }
}

void remove_abort (char *fname, char *rname)
{
  FILE *abortlog, *newlog;
  char namebuf[100];
  char linebuf[100];
  char *p;
  int c;

  if (!dexists (fname))
    return;

   if ((abortlog = fopen (fname, read_ascii)) == NULL)
      {
      (void) got_error (MSG_TXT(M_OPEN_MSG), fname);
      }
   else
      {
      (void) strcpy (namebuf, fname);
      (void) strcpy (namebuf + strlen (namebuf) - 1, "TMP");
      c = 0;
      if ((newlog = fopen (namebuf, write_ascii)) == NULL)
         {
         (void) got_error (MSG_TXT(M_OPEN_MSG), namebuf);
         (void) fclose (abortlog);
         }
      else
         {
         while (!feof (abortlog))
            {
            linebuf[0] = '\0';
            if (!fgets (linebuf, 64, abortlog))
               break;
            p = linebuf;
            while (*p > ' ')
               ++p;
            *p = '\0';
            if (stricmp (linebuf, rname))
               {
               *p = ' ';
               (void) fputs (linebuf, newlog);
               ++c;
               }
            }
         (void) fclose (abortlog);
         (void) fclose (newlog);
         (void) unlink (fname);
         if (c)
            (void) rename (namebuf, fname);
         else (void) unlink (namebuf);
         }
      }
}

/*
 * The next routine is used in the count down timer during file
 * transfers, and were provided by Jon Sabol, along with the other code that
 * calls these routines.
 */

void elapse_time ()
{
   time_t ltime;
   time_t etime;
   long eh;
   long em;
   long es;


   if (fullscreen && (un_attended || doing_poll))
      {
      (void) time (&ltime);

      if (ltime < etm)
         ltime += 86400L;
      etime = ltime - etm;
      eh = etime / 3600L;
      em = (etime / 60L) - (eh * 60L);
      es = etime - (eh * 3600L) - (em * 60L);

#ifndef MILQ
      (void) sprintf ( junk,
                       "%s:  %02ld:%02ld:%02ld",
                        MSG_TXT(M_ELAPSED),
                        eh, em, es);
      sb_move (settings_hWnd, SET_TASK_ROW, SET_TIME_COL);
      sb_puts (settings_hWnd, junk);
#else
      (void) sprintf ( last_Elapsed_Str,
                       "%02ld:%02ld:%02ld",
                         eh, em, es);
      if (etime)
        sb_puts( node_Elapsed, last_Elapsed_Str );
#endif
      sb_show ();
      }
}

int find_addr (char *node, ADDRP addr, char *d)
{
   int ret;

   ret = 1;
   if (alias[0].Node == 0xffff)
      addr->Zone = 0;
   else
      addr->Zone = alias[0].Zone;
   addr->Net = 0;
   addr->Node = 0;
   addr->Point = 0;
   addr->Domain = NULL;
   d[0] = '\0';
   if ((ret = sscanf (node, "%d:%d/%d.%d@%s",
      &(addr->Zone), &(addr->Net), &(addr->Node), &(addr->Point), d)) < 3)
      {
      if (alias[0].Node == 0xffff)
         addr->Zone = 0;
      else
         addr->Zone = alias[0].Zone;
      d[0] = '\0';
      if ((ret = sscanf (node, "%d/%d.%d@%s",
         &(addr->Net), &(addr->Node), &(addr->Point), d)) < 2)
         {
         addr->Net = alias[0].Net;
         d[0] = '\0';
         if (sscanf (node, "%d.%d@%s",
            &(addr->Node), &(addr->Point), d) < 1)
            {
            ret = 0;
            }
         else if (ret == 1)
            {
            d[0] = '\0';
            (void) sscanf (node, "%d@%s",
               &(addr->Node), d);
            }
         }
      else if (ret == 2)
         {
         d[0] = '\0';
         (void) sscanf (node, "%d/%d@%s",
            &(addr->Net), &(addr->Node), d);
         }
      }
   else if (ret == 3)
      {
      d[0] = '\0';
      (void) sscanf (node, "%d:%d/%d@%s",
         &(addr->Zone), &(addr->Net), &(addr->Node), d);
      }

   return (ret);
}

int parse_address (char *node, ADDRP addr)
{
   int ret;
   char d[100];

   ret = find_addr (node, addr, d);

   if (d[0] != '\0')
      {
      addr->Domain = add_domain (d);
      }
   else addr->Domain = NULL;

   return (ret);
}

int find_address (char *node, ADDRP addr)
{
   int ret;
   char d[100];
   char *p;

   d[0] = '\0';
   p = skip_blanks (node);
   if (!isdigit (*p))
      {
      (*userfunc) (p, addr);
      if ((addr->Net == 0xffff) || (addr->Node == 0xffff) || (addr->Zone == 0xffff))
         {
         ret = 0;
         }
      else
         {
         ret = 1;
         }
      }
   else
      {
      ret = find_addr (p, addr, d);
      }

   if (d[0] != '\0')
      {
      addr->Domain = find_domain (d);
      }

   return (ret);
}

char *add_domain (char *d)
{
   char *p;
   int i;

   for (i = 0; (p = domain_name[i]) != NULL; i++)
      {
      if (strnicmp (d, p, strlen (p)) == 0)
         return (p);
      }

   if (i >= 49)
      return (NULL);

   domain_name[i] = strdup (d);
   return (domain_name[i]);
}

char *find_domain (char *d)
{
   char *p, *q, *s;
   char c;
   int i, j, k;

   j = strlen (d);
   /* First see if we can find the whole domain name at the right */
   for (i = 0; (p = domain_name[i]) != NULL; i++)
      {
      k = strlen (p);
      if (k > j)
         continue;

      q = &(d[j - k]);
      if (strnicmp (q, p, k) == 0)
         {
         return (p);
         }
      }

   /* Ok, now see if we can find the abbreviated name at the right */
   for (i = 0; (p = domain_abbrev[i]) != NULL; i++)
      {
      k = strlen (p);
      if (k > j)
         continue;

      q = &(d[j - k]);
      if (strnicmp (q, p, k) == 0)
         {
         return (domain_name[i]);
         }
      }

   /* If there is a period in it, see if we can match the abbreviated name
      just before the period */
   if ((s = strrchr (d, '.')) != NULL)
      {
      c = *s;
      *s = '\0';
      j = strlen (d);
      for (i = 0; (p = domain_abbrev[i]) != NULL; i++)
         {
         k = strlen (p);
         if (k > j)
            continue;

         q = &(d[j - k]);
         if (strnicmp (q, p, k) == 0)
            {
            *s = c;
            return (domain_name[i]);
            }
         }
      *s = c;
      }

   return (NULL);
}

char addr_str[100];

char *Hex_Addr_Str (ADDRP a)
{
   if (a->Point != 0)
      {
      (void) sprintf (addr_str, "%04x%04x.PNT\\%08x", a->Net, a->Node, a->Point);
      }
   else (void) sprintf (addr_str, "%04x%04x", a->Net, a->Node);
   return (addr_str);
}

char *Full_Addr_Str (ADDRP a)
{
   char t1[10];
   char t2[30];
   char t3[10];
   char t4[50];

   if (a->Zone && !no_zones)
      (void) sprintf (t1, "%u:", a->Zone);
   else
      t1[0] = '\0';

   (void) sprintf (t2, "%u/%u", a->Net, a->Node);

   if (a->Point)
      (void) sprintf (t3, ".%u", a->Point);
   else
      t3[0] = '\0';

   if (a->Domain != NULL)
      (void) sprintf (t4, "@%s", a->Domain);
   else
      t4[0] = '\0';

   (void) strcpy (addr_str, t1);
   (void) strcat (addr_str, t2);
   (void) strcat (addr_str, t3);
   (void) strcat (addr_str, t4);
   return (addr_str);
}

unsigned int crc_block(unsigned char *ptr, int count)
{
   unsigned int crc;
   int i;

   for (crc = 0, i = 0; i < count; i++, ptr++)
      {
      crc = xcrc (crc, (byte) *ptr);
      }
   return (crc & 0xFFFF);
}

void Data_Check (XMDATAP xtmp, int mode)
{
  int i;
  unsigned char cs;
  unsigned char *cp;
  unsigned int cs1;

  /* If we are in checksum mode, just do it */
  if (mode == CHECKSUM)
    {
    cp = xtmp->data_bytes;
    cs = 0;
    for (i = 0; i < 128; i++)
      {
      cs += *cp++;
      }
    xtmp->data_check[0] = cs;
    }
  /* If we are in CRC mode, run the characters through the CRC calculator */
  else
    {
    cs1 = crc_block (xtmp->data_bytes, 128);
    xtmp->data_check[0] = (unsigned char) (cs1 >> 8);
    xtmp->data_check[1] = (unsigned char) (cs1 & 0xff);
    }
}