home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software, Co. */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / Freely Available<tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* (C) Copyright 1987-96, Bit Bucket Software Co. */
- /* */
- /* This module was contributed by Michael Buenter */
- /* Based on original code by Arjen Lentz */
- /* HydraCom adaptation for 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.260. */
- /* */
- /* 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:42/1491 */
- /* 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. */
- /* */
- /*--------------------------------------------------------------------------*/
-
- /*=============================================================================
-
- HydraCom Version 1.08
- (+ rev. upto 18 dec 93)
-
- A sample implementation of the
- HYDRA Bi-Directional File Transfer Protocol
-
- HydraCom was written by
- Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT
- COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
-
- The HYDRA protocol was designed by
- Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT and
- Joaquim H. Homrighausen
- COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
-
-
- Revision history:
- 06 Sep 1991 - (AGL) First tryout
- .. ... .... - Internal development
- 11 Jan 1993 - HydraCom version 1.00, Hydra revision 001 (01 Dec 1992)
- 13 Mar 1993 - HydraCom version 1.03, Hydra revision 001 (01 Dec 1992)
- ..
- Changes made by Michael Buenter:
- 03 Dec 1993 - adapted hydra for BT-EE and BT 2.58, many changes
- ..
- Updated source fixes by Arjen Lentz:
- 04 Sep 1993 - HydraCom version 1.08, Hydra revision 001 (01 Dec 1992)
- 23 Dec 1993 - updated to post-1.08 revisions upto 18 Dec 1993
-
- For complete details of the Hydra and HydraCom licensing restrictions,
- please refer to the license agreements which are published in their entirety
- in HYDRACOM.C and LICENSE.DOC, and also contained in the documentation file
- HYDRACOM.DOC
-
- Use of this file is subject to the restrictions contained in the Hydra and
- HydraCom licensing agreements. 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 LENTZ SOFTWARE-DEVELOPMENT and/or Joaquim
- Homrighausen at one of the addresses listed below. In no event should you
- proceed to use this file without having accepted the terms of the Hydra and
- HydraCom licensing agreements, or such other agreement as you are able to
- reach with LENTZ SOFTWARE-DEVELOMENT and Joaquim Homrighausen.
-
-
- Hydra protocol design and HydraCom driver: Hydra protocol design:
- Arjen G. Lentz Joaquim H. Homrighausen
- LENTZ SOFTWARE-DEVELOPMENT 389, route d'Arlon
- Langegracht 7B L-8011 Strassen
- 3811 BT Amersfoort Luxembourg
- The Netherlands
- FidoNet 2:283/512, AINEX-BBS +31-33-633916 FidoNet 2:270/17
- arjen_lentz@f512.n283.z2.fidonet.org joho@ae.lu
-
- Please feel free to contact us at any time to share your comments about our
- software and/or licensing policies.
-
- =============================================================================*/
-
- #include "includes.h"
- #include "hydra.h"
- #include "aglcrc.h"
-
- /* external prototypes from janus.c */
- void j_status (char *,...);
- void j_msgend (word);
- void j_message (word, char *,...);
- int j_error (char *, char *);
- void xfer_summary (char *, char *, long *, int);
- void update_status (long *, long *, long, int *, int);
- long through (long *, long *);
-
- int xfer_init (char *fname, long fsize, long ftime);
- int xfer_okay (void);
-
- #define inteli(x) (x)
- #define intell(x) (x)
-
- /* HYDRA's memory ---------------------------------------------------------- */
- static BOOL originator; /* are we the orig side? */
- static int batchesdone; /* No. HYDRA batches done */
- static BOOL hdxlink; /* hdx link & not orig side */
- static ULONG options; /* INIT options hydra_init() */
- static word timeout; /* general timeout in secs */
- static char abortstr[] =
- {24, 24, 24, 24, 24, 24, 24, 24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0};
-
- #ifdef HYDRADEV
- static char *hdxmsg = "Fallback to one-way xfer";
-
- #endif
- static char *pktprefix = "";
- static char *autostr = "hydra\r";
- static word *crc16tab; /* CRC-16 table */
- static ULONG *crc32tab; /* CRC-32 table */
- static char *GenericError = "!%s";
-
- static byte *txbuf, *rxbuf; /* packet buffers */
- static ULONG txoptions, rxoptions; /* HYDRA options (INIT seq) */
- static char txpktprefix[H_PKTPREFIX + 1]; /* pkt prefix str they want */
- static long txwindow, rxwindow; /* window size (0=streaming) */
- static h_timer braindead; /* braindead timer */
- static byte *txbufin; /* read data from disk here */
- static byte txlastc; /* last byte put in txbuf */
- static byte rxdle; /* count of received H_DLEs */
- static byte rxpktformat; /* format of pkt receiving */
- static byte *rxbufptr; /* current position in rxbuf */
- static byte *rxbufmax; /* highwatermark of rxbuf */
- static char txfname[13], rxfname[13]; /* fname of current files */
- static char rxpathname[PATHLEN]; /* pathname of currrent file */
- static long txftime, rxftime; /* file timestamp (UNIX) */
- static long txfsize, rxfsize; /* file length */
- static int txfd, rxfd; /* file handles */
- static word rxpktlen; /* length of last packet */
- static word rxblklen; /* len of last good data blk */
- static int txstate, rxstate; /* xmit/recv states */
- static long txpos, rxpos; /* current position in files */
- static long txoldpos, rxoldpos; /* last position in files */
- static word txblklen; /* length of last block sent */
- static word txmaxblklen; /* max block length allowed */
- static long txlastack; /* last dataack received */
- static long txstart, rxstart; /* time we started this file */
- static int txoldeta, rxoldeta; /* last time needed */
- static long txoffset, rxoffset; /* offset in file we begun */
- static h_timer txtimer, rxtimer; /* retry timers */
- static word txretries, rxretries; /* retry counters */
- static long rxlastsync; /* filepos last sync retry */
- static long txsyncid, rxsyncid; /* id of last resync */
- static word txgoodneeded; /* to send before larger blk */
- static word txgoodbytes; /* no. sent at this blk size */
-
- struct _h_flags
- {
- char *str;
- ULONG val;
- };
-
- static struct _h_flags h_flags[] =
- {
- {"XON", HOPT_XONXOFF},
- {"TLN", HOPT_TELENET},
- {"CTL", HOPT_CTLCHRS},
- {"HIC", HOPT_HIGHCTL},
- {"HI8", HOPT_HIGHBIT},
- {"BRK", HOPT_CANBRK},
- {"ASC", HOPT_CANASC},
- {"UUE", HOPT_CANUUE},
- {"C32", HOPT_CRC32},
- {"DEV", HOPT_DEVICE},
- {"FPT", HOPT_FPT},
- {NULL, 0x0L}
- };
-
- /*-------------------------------------------------------------------------*/
- static int Next_y; /* Number of next available line on screen */
- static int Tx_y; /* Line number of file transmission status display */
- static int Rx_y; /* Line number of file reception status display */
-
- static char *
- h_revdate (long revstamp)
- {
- static char buf[12];
- struct tm *t;
-
- t = localtime (&revstamp);
- sprintf (buf, "%02d %s %d",
- t->tm_mday, mtext[t->tm_mon], t->tm_year + 1900);
-
- return (buf);
- } /*h_revdate()*/
-
- #ifdef HYDRADEV
- /*---------------------------------------------------------------------------*/
- static void
- hydra_msgdev (byte * data, word len)
- { /* text is already NUL terminated by calling func hydra_devrecv() */
- len = len;
- j_status ("*HMSGDEV: %s", data);
- } /*hydra_msgdev()*/
-
- /*---------------------------------------------------------------------------*/
- static int devtxstate; /* dev xmit state */
- static h_timer devtxtimer; /* dev xmit retry timer */
- static word devtxretries; /* dev xmit retry counter */
- static long devtxid, devrxid; /* id of last devdata pkt */
- static char devtxdev[H_FLAGLEN + 1]; /* xmit device ident flag */
- static byte *devtxbuf; /* ptr to usersupplied dbuf */
- static word devtxlen; /* len of data in xmit buf */
-
- struct _h_dev
- {
- char *dev;
- void (*func) (byte * data, word len);
- };
-
- static struct _h_dev h_dev[] =
- {
- {"MSG", hydra_msgdev}, /* internal protocol msg */
- {"CON", NULL}, /* text to console (chat) */
- {"PRN", NULL}, /* data to printer */
- {"ERR", NULL}, /* text to error output */
- {NULL, NULL}
- };
-
- /*---------------------------------------------------------------------------*/
- BOOL
- hydra_devfree (void)
- {
- if (devtxstate || !(txoptions & HOPT_DEVICE) || txstate >= HTX_END)
- return (FALSE); /* busy or not allowed */
- else
- return (TRUE); /* allowed to send a new pkt */
- } /*hydra_devfree()*/
-
- /*---------------------------------------------------------------------------*/
- BOOL
- hydra_devsend (char *dev, byte * data, word len)
- {
- if (!dev || !data || !len || !hydra_devfree ())
- return (FALSE);
-
- strncpy (devtxdev, dev, H_FLAGLEN);
- devtxdev[H_FLAGLEN] = '\0';
- strupr (devtxdev);
- devtxbuf = data;
- devtxlen = (len > H_MAXBLKLEN) ? H_MAXBLKLEN : len;
-
- devtxid++;
- devtxtimer = h_timer_reset ();
- devtxretries = 0;
- devtxstate = HTD_DATA;
-
- return (TRUE);
- } /*hydra_devsend()*/
-
- /*---------------------------------------------------------------------------*/
- BOOL
- hydra_devfunc (char *dev, void (*func) (byte * data, word len))
- {
- register int i;
-
- for (i = 0; h_dev[i].dev; i++)
- {
- if (!strnicmp (dev, h_dev[i].dev, H_FLAGLEN))
- {
- h_dev[i].func = func;
- return (TRUE);
- }
- }
-
- return (FALSE);
- } /*hydra_devfunc()*/
-
- /*---------------------------------------------------------------------------*/
- static void
- hydra_devrecv (void)
- {
- register char *p = (char *) rxbuf;
- register int i;
- word len = rxpktlen;
-
- p += (int) sizeof (long); /* skip the id long */
- len -= (int) sizeof (long);
-
- for (i = 0; h_dev[i].dev; i++)
- { /* walk through devs */
- if (!strncmp (p, h_dev[i].dev, H_FLAGLEN))
- {
- if (h_dev[i].func)
- {
- len -= ((int) strlen (p)) + 1; /* sub devstr len */
- p += ((int) strlen (p)) + 1; /* skip devtag */
- p[len] = '\0'; /* NUL terminate */
- (*h_dev[i].func) ((byte *) p, len); /* call output func */
- }
- break;
- }
- }
- } /*hydra_devrecv()*/
-
- #endif
-
- /*---------------------------------------------------------------------------*/
- int
- xfer_init (char *fname, long fsize, long ftime)
- {
- int i;
- char namebuf[PATHLEN];
-
- Resume_WaZOO = 0;
-
- strcpy (rxpathname, remote_capabilities ? CURRENT.sc_Inbound : download_path);
- strcat (rxpathname, fname);
-
- /*--------------------------------------------------------------------*/
- /* Save info on WaZOO transfer in case of abort */
- /*--------------------------------------------------------------------*/
- if (remote_capabilities)
- {
- (void) strcpy (Resume_name, fname);
- (void) sprintf (Resume_info, "%ld %lo", fsize, ftime);
- }
-
- /*--------------------------------------------------------------------*/
- /* Check if this is a failed WaZOO transfer which should be resumed */
- /*--------------------------------------------------------------------*/
- if (remote_capabilities && dexists (Abortlog_name))
- {
- Resume_WaZOO = (byte) check_failed (Abortlog_name, fname, Resume_info, namebuf);
- }
-
- if (Resume_WaZOO)
- {
- strcpy (rxpathname, CURRENT.sc_Inbound);
- strcat (rxpathname, namebuf);
- }
- else
- {
- if (dexists (rxpathname))
- {
- struct stat f;
-
- stat (rxpathname, &f);
- if (fsize == f.st_size && ftime == f.st_mtime)
- return (FALSE); /* already have file */
- else
- {
- i = strlen (rxpathname) - 1;
- if ((!overwrite) || (is_arcmail (rxpathname, i)))
- {
- unique_name (rxpathname);
- }
- else
- {
- (void) unlink (rxpathname);
- }
- }
- } /* if exist */
- } /* Resume_WaZOO */
-
- return (TRUE);
- } /*xfer_init()*/
-
- /*---------------------------------------------------------------------------*/
- int
- xfer_okay (void)
- {
- static char new_pathname[PATHLEN];
- char *p;
-
- remove_abort (Abortlog_name, Resume_name);
- strcpy (new_pathname, CURRENT.sc_Inbound);
- p = new_pathname + ((int) strlen (new_pathname)); /* start of fname */
- strcat (new_pathname, Resume_name); /* add real fname */
- unique_name (new_pathname); /* make it unique */
- if (rename (rxpathname, new_pathname)) /* rename temp to real */
- status_line ("!Could not rename '%s' to '%s'", rxpathname, new_pathname);
- strcpy (rxpathname, new_pathname);
- return (stricmp (p, Resume_name)); /* dup rename? */
- }
-
- /*---------------------------------------------------------------------------*/
- static void
- put_flags (char *buf, struct _h_flags flags[], long val)
- {
- register char *p;
- register int i;
-
- p = buf;
- for (i = 0; flags[i].val; i++)
- {
- if (val & flags[i].val)
- {
- if (p > buf)
- *p++ = ',';
- strcpy (p, flags[i].str);
- p += H_FLAGLEN;
- }
- }
- *p = '\0';
- } /*put_flags()*/
-
- /*---------------------------------------------------------------------------*/
- static ULONG
- get_flags (char *buf, struct _h_flags flags[])
- {
- register ULONG val;
- register char *p;
- register int i;
-
- val = 0x0L;
- for (p = strtok (buf, ","); p; p = strtok (NULL, ","))
- {
- for (i = 0; flags[i].val; i++)
- {
- if (!strcmp (p, flags[i].str))
- {
- val |= flags[i].val;
- break;
- }
- }
- }
- return (val);
- } /*get_flags()*/
-
- /*---------------------------------------------------------------------------*/
- /* CRC-16/32 code now separate source *//*AGL:10mar93*/
-
- /*---------------------------------------------------------------------------*/
- static byte *
- put_binbyte (register byte * p, register byte c)
- {
- register byte n;
-
- n = c;
- if (txoptions & HOPT_HIGHCTL)
- n &= 0x7f;
-
- if (n == H_DLE ||
- ((txoptions & HOPT_XONXOFF) && (n == XON || n == XOFF)) ||
- ((txoptions & HOPT_TELENET) && n == '\r' && txlastc == '@') ||
- ((txoptions & HOPT_CTLCHRS) && (n < 32 || n == 127)))
- {
- *p++ = H_DLE;
- c ^= 0x40;
- }
-
- *p++ = c;
- txlastc = n;
-
- return (p);
- } /*put_binbyte()*/
-
- /*---------------------------------------------------------------------------*/
- static void
- txpkt (register word len, int type)
- {
- register byte *in, *out;
- register word c, n;
- BOOL crc32 = FALSE;
- byte format;
- static char hexdigit[] = "0123456789abcdef";
-
- txbufin[len++] = (byte)type;
-
- switch (type)
- {
- case HPKT_START:
- case HPKT_INIT:
- case HPKT_INITACK:
- case HPKT_END:
- case HPKT_IDLE:
- format = HCHR_HEXPKT;
- break;
-
- default:
- /* COULD do smart format selection depending on data and options! */
- if (txoptions & HOPT_HIGHBIT)
- {
- if ((txoptions & HOPT_CTLCHRS) && (txoptions & HOPT_CANUUE))
- format = HCHR_UUEPKT;
- else if (txoptions & HOPT_CANASC)
- format = HCHR_ASCPKT;
- else
- format = HCHR_HEXPKT;
- }
- else
- format = HCHR_BINPKT;
- break;
- }
-
- if (format != HCHR_HEXPKT && (txoptions & HOPT_CRC32))
- crc32 = TRUE;
-
- #ifdef DEBUG
- if (debugging_log)
- {
- char *s1, *s2, *s3, *s4;
-
- j_status (">-> PKT (format='%c' type='%c' crc=%d len=%d)",
- (char) format, (char) type, crc32 ? 32 : 16, (int) len - 1);
-
- switch (type)
- {
- case HPKT_START:
- j_status ("> <autostr>START");
- break;
- case HPKT_INIT:
- s1 = ((char *) txbufin) + ((int) strlen ((char *) txbufin)) + 1;
- s2 = s1 + ((int) strlen (s1)) + 1;
- s3 = s2 + ((int) strlen (s2)) + 1;
- s4 = s3 + ((int) strlen (s3)) + 1;
- /* j_status("> INIT (appinfo='%s' can='%s' want='%s' options='%s' pktprefix='%s')",
- (char *) txbufin, s1, s2, s3, s4); */
- break;
- case HPKT_INITACK:
- j_status ("> INITACK");
- break;
- case HPKT_FINFO:
- j_status ("> FINFO (%s)", txbufin);
- break;
- case HPKT_FINFOACK:
- if (rxfd >= 0)
- {
- if (rxpos > 0L)
- s1 = "RES";
- else
- s1 = "BOF";
- }
- else if (rxpos == -1L)
- s1 = "HAVE";
- else if (rxpos == -2L)
- s1 = "SKIP";
- else
- s1 = "EOB";
- j_status ("> FINFOACK (pos=%ld %s rxstate=%d rxfd=%d)",
- rxpos, s1, (int) rxstate, rxfd);
- break;
- case HPKT_DATA:
- j_status ("> DATA (ofs=%ld len=%d)",
- intell (h_long1 (txbufin)), (int) len - 5);
- break;
- case HPKT_DATAACK:
- j_status ("> DATAACK (ofs=%ld)",
- intell (h_long1 (txbufin)));
- break;
- case HPKT_RPOS:
- j_status ("> RPOS (pos=%ld%s blklen=%ld syncid=%ld)",
- rxpos, rxpos < 0L ? " SKIP" : "",
- intell (h_long2 (txbufin)), rxsyncid);
- break;
- case HPKT_EOF:
- j_status ("> EOF (ofs=%ld%s)",
- txpos, txpos < 0L ? " SKIP" : "");
- break;
- case HPKT_EOFACK:
- j_status ("> EOFACK");
- break;
- case HPKT_IDLE:
- j_status ("> IDLE");
- break;
- case HPKT_END:
- j_status ("> END");
- break;
- #ifdef HYDRADEV
- case HPKT_DEVDATA:
- j_status ("> DEVDATA (id=%ld dev='%s' len=%hu)",
- devtxid, devtxdev, devtxlen);
- break;
- case HPKT_DEVDACK:
- j_status ("> DEVDACK (id=%ld)",
- intell (h_long1 (rxbuf)));
- break;
- #endif
- default: /* This couldn't possibly happen! ;-) */
- break;
- }
- }
- #endif
-
- if (crc32)
- {
- ULONG crc = CRC32POST (crc32block (crc32tab, CRC32INIT, txbufin, len)); /*AGL:10mar93*/
-
- txbufin[len++] = (byte) crc;
- txbufin[len++] = (byte) (crc >> 8);
- txbufin[len++] = (byte) (crc >> 16);
- txbufin[len++] = (byte) (crc >> 24);
- }
- else
- {
- word crc = CRC16POST (crc16block (crc16tab, CRC16INIT, txbufin, len)); /*AGL:10mar93*/
-
- txbufin[len++] = (byte) crc;
- txbufin[len++] = (byte) (crc >> 8);
- }
-
- in = txbufin;
- out = txbuf;
- txlastc = 0;
- *out++ = H_DLE;
- *out++ = format;
-
- switch (format)
- {
- case HCHR_HEXPKT:
- for (; len > 0; len--, in++)
- {
- if (*in & 0x80)
- {
- *out++ = '\\';
- *out++ = hexdigit[((*in) >> 4) & 0x0f];
- *out++ = hexdigit[(*in) & 0x0f];
- }
- else if (*in < 32 || *in == 127)
- {
- *out++ = H_DLE;
- *out++ = (byte)((*in) ^ 0x40);
- }
- else if (*in == '\\')
- {
- *out++ = '\\';
- *out++ = '\\';
- }
- else
- *out++ = *in;
- }
- break;
-
- case HCHR_BINPKT:
- for (; len > 0; len--)
- out = put_binbyte (out, *in++);
- break;
-
- case HCHR_ASCPKT:
- for (n = c = 0; len > 0; len--)
- {
- c |= ((*in++) << n);
- out = put_binbyte (out, (byte)(c & 0x7f));
- c >>= 7;
- if (++n >= 7)
- {
- out = put_binbyte (out, (byte)(c & 0x7f));
- n = c = 0;
- }
- }
- if (n > 0)
- out = put_binbyte (out, (byte)(c & 0x7f));
- break;
-
- case HCHR_UUEPKT:
- for (; len >= 3; in += 3, len -= 3)
- {
- *out++ = (byte) h_uuenc (in[0] >> 2);
- *out++ = (byte) h_uuenc (((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f));
- *out++ = (byte) h_uuenc (((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03));
- *out++ = (byte) h_uuenc (in[2] & 0x3f);
- }
- if (len > 0)
- {
- *out++ = (byte) h_uuenc (in[0] >> 2);
- *out++ = (byte) h_uuenc (((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f));
- if (len == 2)
- *out++ = (byte) h_uuenc ((in[1] << 2) & 0x3c);
- }
- break;
- }
-
- *out++ = H_DLE;
- *out++ = HCHR_PKTEND;
-
- if (type != HPKT_DATA && format != HCHR_BINPKT)
- {
- *out++ = '\r';
- *out++ = '\n';
- }
-
- for (in = (byte *) txpktprefix; *in; in++)
- {
- switch (*in)
- {
- case 221: /* transmit break signal for one second */
- do_break(TRUE);
- {
- h_timer t = h_timer_set (2);
- while (!h_timer_expired (t, h_timer_get ()))
- time_release ();
- }
- do_break(FALSE);
- break;
- case 222:
- {
- h_timer t = h_timer_set (2);
-
- while (!h_timer_expired (t, h_timer_get ()))
- time_release ();
- }
- break;
- case 223:
- SENDBYTE (0);
- break;
- default:
- SENDBYTE (*in);
- break;
- }
- }
-
- ComTXBlockTimeout (txbuf, (USHORT) (out - txbuf), braindead);
- } /*txpkt()*/
-
- /*---------------------------------------------------------------------------*/
- static int
- rxpkt (void)
- {
- register byte *p, *q = rxbuf;
- register word n, i;
- short c;
- h_timer tnow = h_timer_get (); /*AGL:16jul93*/
-
- if (got_ESC ())
- return (H_SYSABORT);
- if (!CARRIER)
- return (H_CARRIER);
-
- if (h_timer_running (braindead) && h_timer_expired (braindead, tnow))
- {
- #ifdef DEBUG
- if (debugging_log)
- j_status (" <- BrainDead (timer=%08lx time=%08lx)", braindead, tnow);
- #endif
- return (H_BRAINTIME);
- }
-
- if (h_timer_running (txtimer) && h_timer_expired (txtimer, tnow))
- {
- #ifdef DEBUG
- if (debugging_log)
- j_status (" <- TxTimer (timer=%08lx time=%08lx)", txtimer, tnow);
- #endif
- return (H_TXTIME);
- }
-
- #ifdef HYDRADEV
- if (h_timer_running (devtxtimer) && h_timer_expired (devtxtimer, tnow))
- {
- #ifdef DEBUG
- if (debugging_log)
- j_status (" <- DevTxTimer (timer=%08lx time=%08lx)", devtxtimer, time (NULL));
- #endif
- return (H_DEVTXTIME);
- }
- #endif
-
- p = rxbufptr;
-
- while (CHAR_AVAIL ())
- {
- c = MODEM_IN ();
- if (rxoptions & HOPT_HIGHBIT)
- c &= 0x7f;
-
- n = c;
- if (rxoptions & HOPT_HIGHCTL)
- n &= 0x7f;
- if (n != H_DLE &&
- (((rxoptions & HOPT_XONXOFF) && (n == XON || n == XOFF)) ||
- ((rxoptions & HOPT_CTLCHRS) && (n < 32 || n == 127))))
- continue;
-
- if (rxdle || c == H_DLE)
- {
- switch (c)
- {
- case H_DLE:
- if (++rxdle >= 5)
- return (H_CANCEL);
- break;
-
- case HCHR_PKTEND:
- rxbufptr = p;
-
- switch (rxpktformat)
- {
- case HCHR_BINPKT:
- q = rxbufptr;
- break;
-
- case HCHR_HEXPKT:
- for (p = q = rxbuf; p < rxbufptr; p++)
- {
- if (*p == '\\' && *++p != '\\')
- {
- i = *p;
- n = *++p;
- if ((i -= '0') > 9)
- i -= ('a' - ':');
- if ((n -= '0') > 9)
- n -= ('a' - ':');
- if ((i & ~0x0f) || (n & ~0x0f))
- {
- c = H_NOPKT;
- break;
- }
- *q++ = (byte) ((i << 4) | n);
- }
- else
- *q++ = *p;
- }
- if (p > rxbufptr)
- c = H_NOPKT;
- break;
-
- case HCHR_ASCPKT:
- n = i = 0;
- for (p = q = rxbuf; p < rxbufptr; p++)
- {
- i |= ((*p & 0x7f) << n);
- if ((n += 7) >= 8)
- {
- *q++ = (byte) (i & 0xff);
- i >>= 8;
- n -= 8;
- }
- }
- break;
-
- case HCHR_UUEPKT:
- n = (int) (rxbufptr - rxbuf);
- for (p = q = rxbuf; n >= 4; n -= 4, p += 4)
- {
- if (p[0] <= ' ' || p[0] >= 'a' ||
- p[1] <= ' ' || p[1] >= 'a' ||
- p[2] <= ' ' || p[2] >= 'a' ||
- p[3] <= ' ' || p[3] >= 'a')
- {
- c = H_NOPKT;
- break;
- }
- *q++ = (byte) ((h_uudec (p[0]) << 2) | (h_uudec (p[1]) >> 4));
- *q++ = (byte) ((h_uudec (p[1]) << 4) | (h_uudec (p[2]) >> 2));
- *q++ = (byte) ((h_uudec (p[2]) << 6) | h_uudec (p[3]));
- }
- if (n >= 2)
- {
- if (p[0] <= ' ' || p[0] >= 'a' ||
- p[1] <= ' ' || p[1] >= 'a')
- {
- c = H_NOPKT;
- break;
- }
- *q++ = (byte) ((h_uudec (p[0]) << 2) | (h_uudec (p[1]) >> 4));
- if (n == 3)
- {
- if (p[2] <= ' ' || p[2] >= 'a')
- {
- c = H_NOPKT;
- break;
- }
- *q++ = (byte) ((h_uudec (p[1]) << 4) | (h_uudec (p[2]) >> 2));
- }
- }
- break;
-
- default: /* This'd mean internal fluke */
- #ifdef DEBUG
- if (debugging_log)
- {
- j_status (" <- <PKTEND> (pktformat='%c' dec=%d hex=%02x) ??",
- (char) rxpktformat, (int) rxpktformat, (int) rxpktformat);
- }
- #endif
- c = H_NOPKT;
- break;
- }
-
- rxbufptr = NULL;
-
- if (c == H_NOPKT)
- break;
-
- rxpktlen = (word) (q - rxbuf);
- if (rxpktformat != HCHR_HEXPKT && (rxoptions & HOPT_CRC32))
- {
- if (rxpktlen < 5)
- {
- c = H_NOPKT;
- break;
- }
- n = h_crc32test (crc32block (crc32tab, CRC32INIT, rxbuf, rxpktlen)); /*AGL:10mar93*/
- rxpktlen -= (int) sizeof (long); /* remove CRC-32 */
- }
- else
- {
- if (rxpktlen < 3)
- {
- c = H_NOPKT;
- break;
- }
- n = h_crc16test (crc16block (crc16tab, CRC16INIT, rxbuf, rxpktlen)); /*AGL:10mar93*/
- rxpktlen -= (int) sizeof (word); /* remove CRC-16 */
- }
-
- rxpktlen--; /* remove type */
-
- if (n)
- {
- #ifdef DEBUG
- if (debugging_log)
- {
- char *s1, *s2, *s3, *s4;
-
- j_status ("><- PKT (format='%c' type='%c' len=%hd)",
- (char) rxpktformat, rxbuf[rxpktlen], rxpktlen);
-
- switch (rxbuf[rxpktlen])
- {
- case HPKT_START:
- j_status ("< START");
- break;
- case HPKT_INIT:
- s1 = ((char *) rxbuf) + ((int) strlen ((char *) rxbuf)) + 1;
- s2 = s1 + ((int) strlen (s1)) + 1;
- s3 = s2 + ((int) strlen (s2)) + 1;
- s4 = s3 + ((int) strlen (s3)) + 1;
- /* j_status("< INIT (appinfo='%s' can='%s' want='%s' options='%s' pktprefix='%s')",
- (char *) rxbuf, s1, s2, s3, s4); */
- break;
- case HPKT_INITACK:
- j_status ("< INITACK");
- break;
- case HPKT_FINFO:
- j_status ("< FINFO ('%s' rxstate=%d)", rxbuf, (int) rxstate);
- break;
- case HPKT_FINFOACK:
- j_status ("< FINFOACK (pos=%ld txstate=%d txfd=%d)",
- intell (h_long1 (rxbuf)), (int) txstate, txfd);
- break;
- case HPKT_DATA:
- j_status ("< DATA (rxstate=%d pos=%ld len=%hu)",
- (int) rxstate, intell (h_long1 (rxbuf)),
- (word) (rxpktlen - ((int) sizeof (long))));
-
- break;
- case HPKT_DATAACK:
- j_status ("< DATAACK (rxstate=%d pos=%ld)",
- (int) rxstate, intell (h_long1 (rxbuf)));
- break;
- case HPKT_RPOS:
- j_status ("< RPOS (pos=%ld%s blklen=%hu->%ld syncid=%ld%s txstate=%d txfd=%d)",
- intell (h_long1 (rxbuf)),
- intell (h_long1 (rxbuf)) < 0L ? " SKIP" : "",
- txblklen, intell (h_long2 (rxbuf)),
- intell (h_long3 (rxbuf)),
- intell (h_long3 (rxbuf)) == rxsyncid ? " DUP" : "",
- (int) txstate, txfd);
- break;
- case HPKT_EOF:
- j_status ("< EOF (rxstate=%d pos=%ld%s)",
- (int) rxstate, intell (h_long1 (rxbuf)),
- intell (h_long1 (rxbuf)) < 0L ? " SKIP" : "");
- break;
- case HPKT_EOFACK:
- j_status ("< EOFACK (txstate=%d)", (int) txstate);
- break;
- case HPKT_IDLE:
- j_status ("< IDLE");
- break;
- case HPKT_END:
- j_status ("< END");
- break;
- #ifdef HYDRADEV
- case HPKT_DEVDATA:
- s1 = ((char *) rxbuf) + ((int) sizeof (long));
-
- j_status ("< DEVDATA (id=%ld dev=%s len=%u",
- intell (h_long1 (rxbuf)), s1,
- (int) rxpktlen - (((int) sizeof (long)) + ((int) strlen (s1)) + 1));
-
- break;
- case HPKT_DEVDACK:
- j_status ("< DEVDACK (devtxstate=%d id=%ld)",
- (int) devtxstate, intell (h_long1 (rxbuf)));
- break;
- #endif
- default:
- j_status ("< Unkown pkttype %c (txstate=%d rxstate=%d)",
- rxbuf[rxpktlen], (int) txstate, (int) rxstate);
- break;
- }
- }
- #endif
- return ((int) rxbuf[rxpktlen]);
- } /*goodpkt*/
-
- #ifdef DEBUG
- if (debugging_log)
- j_status (">Bad CRC (format='%c' type='%c' len=%d)",
- (char) rxpktformat, rxbuf[rxpktlen], (int) rxpktlen);
- #endif
- break;
-
- case HCHR_BINPKT:
- case HCHR_HEXPKT:
- case HCHR_ASCPKT:
- case HCHR_UUEPKT:
- #ifdef DEBUG
- if (debugging_log)
- j_status (" <- <PKTSTART> (pktformat='%c')", (char) c);
- #endif
- rxpktformat = (byte) c;
- p = rxbufptr = rxbuf;
- rxdle = 0;
- break;
-
- default:
- if (p)
- {
- if (p < rxbufmax)
- *p++ = (byte) (c ^ 0x40);
- else
- {
- #ifdef DEBUG
- if (debugging_log)
- j_status (" <- Pkt too long - discarded");
- #endif
- p = NULL;
- }
- }
- rxdle = 0;
- break;
- } /* case */
- }
- else if (p)
- {
- if (p < rxbufmax)
- *p++ = (byte) c;
- else
- {
- #ifdef DEBUG
- if (debugging_log)
- j_status (" <- Pkt too long - discarded");
- #endif
- p = NULL;
- }
- }
- }
-
- rxbufptr = p;
-
- time_release ();
- return (H_NOPKT);
- } /*rxpkt()*/
-
- /*---------------------------------------------------------------------------*/
- void
- hydra_badxfer (void)
- {
- if (rxfd >= 0)
- {
- close (rxfd);
- rxfd = -1;
- if (remote_capabilities)
- {
- if (!Resume_WaZOO)
- {
- add_abort (Abortlog_name, Resume_name, rxpathname, CURRENT.sc_Inbound, Resume_info);
- }
- }
- else
- {
- (void) unlink (rxpathname);
- }
- }
- } /*hydra_badxfer()*/
-
- /*---------------------------------------------------------------------------*/
- void
- hydra_init (ULONG want_options)
- {
- char *HoldName;
-
- txbuf = Txbuf;
- rxbuf = txbuf + H_BUFLEN;
-
- crc16tab = (word *) malloc (CRC_TABSIZE * ((int) sizeof (word)));
- crc32tab = (ULONG *) malloc (CRC_TABSIZE * ((int) sizeof (ULONG)));
-
- if (!txbuf || !rxbuf || !crc16tab || !crc32tab)
- {
- status_line (MSG_TXT (M_MEM_ERROR));
- mdm_hangup ();
- return;
- }
- txbufin = txbuf + ((H_MAXBLKLEN + H_OVERHEAD + 5) * 2);
- rxbufmax = rxbuf + H_MAXPKTLEN;
-
- crc16init (crc16tab, CRC16POLY);
- crc32init (crc32tab, CRC32POLY);
-
- batchesdone = 0;
- mail_finished = 1;
-
- originator = remote_capabilities ? (isOriginator ? TRUE : FALSE) : TRUE;
-
- HoldName = HoldAreaNameMunge (&called_addr);
-
- (void) sprintf (Abortlog_name, "%s%s.Z\0",
- HoldName, Hex_Addr_Str (&remote_addr));
-
- if (originator)
- hdxlink = FALSE;
- else
- hdxlink = !((janus_baud >= cur_baud.rate_value) || (janus_OK));
-
- options = (want_options & HCAN_OPTIONS) & ~HUNN_OPTIONS;
-
- timeout = (word) (40960L / cur_baud.rate_value);
- if (timeout < H_MINTIMER)
- timeout = H_MINTIMER;
- else if (timeout > H_MAXTIMER)
- timeout = H_MAXTIMER;
-
- txmaxblklen = (short) ((cur_baud.rate_value / 300) * 128);
- if (txmaxblklen < 256)
- txmaxblklen = 256;
- else if (txmaxblklen > H_MAXBLKLEN)
- txmaxblklen = H_MAXBLKLEN;
-
- rxblklen = txblklen = (cur_baud.rate_value < 2400U) ? 256 : 512;
-
- txgoodbytes = 0;
- txgoodneeded = txmaxblklen; /*AGL:23feb93*/
-
- txstate = HTX_DONE;
-
- set_prior (3); /* Time Critical */
- XON_DISABLE ();
-
- if (un_attended && fullscreen)
- {
- clear_filetransfer ();
- sb_show ();
- Tx_y = 1;
- Rx_y = 2;
- }
- else
- {
- set_xy (NULL);
- Rx_y = Tx_y = Next_y = locate_y;
- }
-
- } /*hydra_init()*/
-
- /*---------------------------------------------------------------------------*/
- void
- hydra_deinit (void)
- {
- free (crc16tab);
- free (crc32tab);
-
- set_prior (4); /* Always High */
- } /*hydra_deinit()*/
-
- /*---------------------------------------------------------------------------*/
- int
- hydra (char *txpathname, char *txalias)
- {
- int res = 0;
- int pkttype;
- char *p, *q;
- int i;
- struct stat f;
-
- /*-------------------------------------------------------------------*/
- if (txstate == HTX_DONE)
- {
- txstate = HTX_START;
- txoptions = HTXI_OPTIONS;
- txpktprefix[0] = '\0';
-
- rxstate = HRX_INIT;
- rxoptions = HRXI_OPTIONS;
- rxfd = -1;
- rxdle = 0;
- rxbufptr = NULL;
- rxtimer = h_timer_reset ();
-
- #ifdef HYDRADEV
- devtxid = devrxid = 0L;
- devtxtimer = h_timer_reset ();
- devtxstate = HTD_DONE;
- #endif
-
- braindead = h_timer_set (H_BRAINDEAD);
- }
- else
- txstate = HTX_FINFO;
-
- txtimer = h_timer_reset ();
- txretries = 0;
-
- /*-------------------------------------------------------------------*/
- if (txpathname)
- {
- stat (txpathname, &f);
- txfsize = f.st_size;
- txftime = f.st_mtime;
-
- if ((txfd = share_open (txpathname, O_RDONLY | O_BINARY, DENY_WRITE)) < 0)
- {
- j_error (MSG_TXT (M_OPEN_MSG), txpathname);
- return (XFER_SKIP);
- }
-
- if (isatty (txfd))
- {
- errno = 1;
- (void) j_error (MSG_TXT (M_DEVICE_MSG), txpathname);
- close (txfd);
- return (XFER_SKIP);
- }
-
- strupr (txpathname);
- for (p = txpathname, q = txfname; *p; p++)
- {
- if (*q = *p, *p == '\\' || *p == ':' || *p == '/')
- q = txfname;
- else
- q++;
- }
- *q = '\0';
-
- if (txalias)
- strupr (txalias);
-
- txstart = 0L;
- txsyncid = 0L;
- }
- else
- {
- txfd = -1;
- strcpy (txfname, "");
- }
-
- /*-------------------------------------------------------------------*/
- do
- {
- #ifdef HYDRADEV
- /*----------------------------------------------------------------*/
- switch (devtxstate)
- {
- /*---------------------------------------------------------*/
- case HTD_DATA:
- if (txstate > HTX_RINIT)
- {
- h_long1 (txbufin) = intell (devtxid);
- p = ((char *) txbufin) + ((int) sizeof (long));
-
- strcpy (p, devtxdev);
- p += H_FLAGLEN + 1;
- memcpy (p, devtxbuf, devtxlen);
- txpkt (((int) sizeof (long)) + H_FLAGLEN + 1 + devtxlen, HPKT_DEVDATA);
-
- devtxtimer = h_timer_set ((!rxstate && txstate == HTX_REND) ? timeout / 2 : timeout); /*AGL:10mar93*/
- devtxstate = HTD_DACK;
- }
- break;
-
- /*---------------------------------------------------------*/
- default:
- break;
-
- /*---------------------------------------------------------*/
- }
- #endif
- /*----------------------------------------------------------------*/
- switch (txstate)
- {
- /*---------------------------------------------------------*/
- case HTX_START:
- SENDCHARS (autostr, (int) strlen (autostr), 1);
- txpkt (0, HPKT_START);
- txtimer = h_timer_set (H_START);
- txstate = HTX_SWAIT;
- break;
-
- /*---------------------------------------------------------*/
- case HTX_INIT:
- p = (char *) txbufin;
- sprintf (p, "%08lx%s,%s", H_REVSTAMP, PRDCT_PRTY, PRDCT_VRSN);
- p += ((int) strlen (p)) + 1; /* our app info & HYDRA rev. */
- put_flags (p, h_flags, HCAN_OPTIONS); /* what we CAN */
- p += ((int) strlen (p)) + 1;
- put_flags (p, h_flags, options); /* what we WANT */
- p += ((int) strlen (p)) + 1;
- sprintf (p, "%08lx%08lx", /* TxRx windows */
- hydra_txwindow, hydra_rxwindow);
- p += ((int) strlen (p)) + 1;
- strcpy (p, pktprefix); /* pkt prefix string we want */
- p += ((int) strlen (p)) + 1;
-
- txoptions = HTXI_OPTIONS;
- txpkt ((word) (((byte *) p) - txbufin), HPKT_INIT);
- txoptions = rxoptions;
- txtimer = h_timer_set (timeout / 2);
- txstate = HTX_INITACK;
- break;
-
- /*---------------------------------------------------------*/
- case HTX_FINFO:
- if (txfd >= 0)
- {
- if (!txretries)
- {
- txoldpos = txoldeta = -1;
- if (!un_attended || !fullscreen)
- Tx_y = Next_y;
- if (txalias)
- xfer_summary (MSG_TXT (M_SEND), txalias, &txfsize, Tx_y);
- else
- xfer_summary (MSG_TXT (M_SEND), txfname, &txfsize, Tx_y);
- strlwr (txfname);
- }
- sprintf ((char *) txbufin, "%08lx%08lx%08lx%08lx%08lx%s",
- txftime, txfsize, 0L, 0L, 0L,
- txalias ? txalias : txfname);
- }
- else
- {
- if (!txretries)
- {
- j_msgend (Tx_y);
- #ifdef DEBUG
- j_status ("+HSEND: End of batch");
- #endif
- }
- strcpy ((char *) txbufin, txfname);
- }
- txpkt (((int) strlen ((char *) txbufin)) + 1, HPKT_FINFO);
- txtimer = h_timer_set (txretries ? timeout / 2 : timeout);
- txstate = HTX_FINFOACK;
- break;
-
- /*---------------------------------------------------------*/
- case HTX_XDATA:
- if (ComTXRemain () > txmaxblklen)
- break;
-
- if (txpos < 0L)
- i = -1; /* Skip */
- else
- {
- h_long1 (txbufin) = intell (txpos);
- if ((i = read (txfd, txbufin + ((int) sizeof (long)), txblklen)) < 0)
- {
- j_error (MSG_TXT (M_READ_MSG), txfname);
- close (txfd);
- txfd = -1;
- txpos = -2L;/* Skip */
- }
- }
-
- if (i > 0)
- {
- txpos += i;
- txpkt (((int) sizeof (long)) + i, HPKT_DATA);
-
- if (txblklen < txmaxblklen &&
- (txgoodbytes += i) >= txgoodneeded)
- {
- txblklen <<= 1;
- if (txblklen >= txmaxblklen)
- {
- txblklen = txmaxblklen;
- txgoodneeded = 0;
- }
- txgoodbytes = 0;
- }
-
- if (txwindow && (txpos >= (txlastack + txwindow)))
- {
- txtimer = h_timer_set (txretries ? timeout / 2 : timeout);
- txstate = HTX_DATAACK;
- }
-
- if (!txstart)
- txstart = time (NULL);
- update_status (&txpos, &txoldpos, txfsize - txpos, &txoldeta, Tx_y);
- break;
- }
-
- /* fallthrough to HTX_EOF */
-
- /*---------------------------------------------------------*/
- case HTX_EOF:
- h_long1 (txbufin) = intell (txpos);
- txpkt ((int) sizeof (long), HPKT_EOF);
-
- txtimer = h_timer_set (txretries ? timeout / 2 : timeout);
- txstate = HTX_EOFACK;
- break;
-
- /*---------------------------------------------------------*/
- case HTX_END:
- txpkt (0, HPKT_END);
- txpkt (0, HPKT_END);
- txtimer = h_timer_set (timeout / 2);
- txstate = HTX_ENDACK;
- break;
-
- /*---------------------------------------------------------*/
- default:
- break;
-
- /*---------------------------------------------------------*/
- }
-
- /*----------------------------------------------------------------*/
- pkttype = rxpkt ();
-
- /*----------------------------------------------------------*/
- switch (pkttype)
- {
- /*---------------------------------------------------*/
- case H_CARRIER:
- case H_CANCEL:
- case H_SYSABORT:
- case H_BRAINTIME:
- switch (pkttype)
- {
- case H_CARRIER:
- j_status (GenericError, &(MSG_TXT (M_NO_CARRIER)[1]));
- break;
- case H_CANCEL:
- j_status (MSG_TXT (M_SESSION_ABORT));
- break;
- case H_SYSABORT:
- j_status (GenericError, &(MSG_TXT (M_KBD_MSG)[1]));
- break;
- case H_BRAINTIME:
- j_status (MSG_TXT (M_OTHER_DIED));
- break;
- }
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
-
- /*---------------------------------------------------*/
- case H_TXTIME:
- if (txstate == HTX_XWAIT || txstate == HTX_REND)
- {
- txpkt (0, HPKT_IDLE);
- txtimer = h_timer_set (H_IDLE);
- break;
- }
-
- if (++txretries > H_RETRIES)
- {
- j_status (MSG_TXT (M_FUBAR_MSG));
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
- }
-
- j_message (Tx_y, MSG_TXT (M_TIMEOUT));
- #ifdef DEBUG
- j_status ("-HSEND: Timeout - Retry %u", txretries);
- #endif
- txtimer = h_timer_reset ();
-
- switch (txstate)
- {
- case HTX_SWAIT:
- txstate = HTX_START;
- break;
- case HTX_INITACK:
- txstate = HTX_INIT;
- break;
- case HTX_FINFOACK:
- txstate = HTX_FINFO;
- break;
- case HTX_DATAACK:
- txstate = HTX_XDATA;
- break;
- case HTX_EOFACK:
- txstate = HTX_EOF;
- break;
- case HTX_ENDACK:
- txstate = HTX_END;
- break;
- }
- break;
-
- /*---------------------------------------------------*/
- #ifdef HYDRADEV
- case H_DEVTXTIME:
- if (++devtxretries > H_RETRIES)
- {
- j_status (MSG_TXT (M_FUBAR_MSG));
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
- }
-
- j_message (Tx_y, MSG_TXT (M_TIMEOUT));
- #ifdef DEBUG
- j_status ("-HDEVTX: Timeout - Retry %u", devtxretries);
- #endif
- devtxtimer = h_timer_reset ();
- devtxstate = HTD_DATA;
- break;
- #endif
- /*---------------------------------------------------*/
- case HPKT_START:
- if (txstate == HTX_START || txstate == HTX_SWAIT)
- {
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_INIT;
- braindead = h_timer_set (H_BRAINDEAD);
- }
- break;
-
- /*---------------------------------------------------*/
- case HPKT_INIT:
- if (rxstate == HRX_INIT)
- {
- p = (char *) rxbuf;
- p += ((int) strlen (p)) + 1;
- q = p + ((int) strlen (p)) + 1;
- rxoptions = options | HUNN_OPTIONS;
- rxoptions |= get_flags (q, h_flags);
- rxoptions &= get_flags (p, h_flags);
- rxoptions &= HCAN_OPTIONS;
- if (rxoptions < (options & HNEC_OPTIONS))
- {
- j_status ("!HYDRA: Incompatible on this link");
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
- }
- p = q + ((int) strlen (q)) + 1;
- rxwindow = txwindow = 0L;
- sscanf (p, "%08lx%08lx", &rxwindow, &txwindow);
- if (rxwindow < 0L)
- rxwindow = 0L;
- if (hydra_rxwindow &&
- (!rxwindow || hydra_rxwindow < rxwindow))
- rxwindow = hydra_rxwindow;
- if (txwindow < 0L)
- txwindow = 0L;
- if (hydra_txwindow &&
- (!txwindow || hydra_txwindow < txwindow))
- txwindow = hydra_txwindow;
- p += ((int) strlen (p)) + 1;
- strncpy (txpktprefix, p, H_PKTPREFIX);
- txpktprefix[H_PKTPREFIX] = '\0';
-
- if (!batchesdone)
- {
- long revstamp;
-
- p = (char *) rxbuf;
- sscanf (p, "%08lx", &revstamp);
- j_status (">HYDRA: Other's HydraRev=%s",
- h_revdate (revstamp));
- p += 8;
- if ((q = strchr (p, ',')) != NULL)
- *q = ' ';
- if ((q = strchr (p, ',')) != NULL)
- *q = '/';
- j_status (">HYDRA: Other's App.Info '%s'", p);
- put_flags ((char *) rxbuf, h_flags, rxoptions);
- j_status (">HYDRA: Using link options '%s'", rxbuf);
- if (txwindow || rxwindow)
- j_status (">HYDRA: Window tx=%ld rx=%ld", txwindow, rxwindow);
- }
-
- txoptions = rxoptions;
- rxstate = HRX_FINFO;
-
- #ifdef HYDRADEV
- if (rxoptions & HOPT_DEVICE)
- {
- p = "Remote has no chat facility available\r\n";
- hydra_devsend ("CON", (byte *) p, (int) strlen (p));
- }
- #endif
- }
-
- txpkt (0, HPKT_INITACK);
- break;
-
- /*---------------------------------------------------*/
- case HPKT_INITACK:
- if (txstate == HTX_INIT || txstate == HTX_INITACK)
- {
- braindead = h_timer_set (H_BRAINDEAD);
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_RINIT;
- }
- break;
-
- /*---------------------------------------------------*/
- case HPKT_FINFO:
- if (rxstate == HRX_FINFO)
- {
- braindead = h_timer_set (H_BRAINDEAD);
- if (!rxbuf[0])
- {
- j_msgend (Rx_y);
- #ifdef DEBUG
- j_status ("*HRECV: End of batch");
- #endif
- rxpos = 0L;
- rxstate = HRX_DONE;
- batchesdone++;
- }
- else
- {
- long diskfree;
-
- rxfsize = rxftime = 0L;
- rxoldpos = rxoldeta = -1;
- rxfname[0] = '\0';
- sscanf ((char *) rxbuf, "%08lx%08lx%*08lx%*08lx%*08lx%s",
- &rxftime, &rxfsize, rxfname);
- strlwr (rxfname);
-
- i = strlen (rxfname) - 1;
- if ((i > 2) && (rxfname[i - 2] == 'r') &&
- (rxfname[i - 1] == 'e') && (rxfname[i] == 'q'))
- {
- (void) sprintf (&rxfname[i - 1], "%02x", TaskNumber);
- }
-
- if (!xfer_init (rxfname, rxfsize, rxftime)) /* Already have file */
- {
- j_status (MSG_TXT (M_ALREADY_HAVE), rxpathname);
- rxpos = -1L;
- }
- else
- {
- diskfree = zfree (rxpathname);
- if (rxfsize + 10240L > diskfree)
- {
- j_status (MSG_TXT (M_OUT_OF_DISK_SPACE));
- rxpos = -2L;
- }
- else
- {
- if (dexists (rxpathname)) /* Resuming? */
- {
- if ((rxfd = open (rxpathname, O_RDWR | O_BINARY, 0)) < 0)
- {
- j_error (MSG_TXT (M_OPEN_MSG), rxpathname);
- rxpos = -2L;
- }
- }
- else if ((rxfd = open (rxpathname, O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE)) < 0)
- {
- j_error (MSG_TXT (M_OPEN_MSG), rxpathname);
- rxpos = -2L;
- }
-
- if (rxfd >= 0)
- {
- p = check_netfile (rxfname);
- j_status ("#%s %s %s", MSG_TXT (M_RECEIVING), (p) ? p : " ", rxfname);
- if (!un_attended || !fullscreen)
- Rx_y = Next_y;
- xfer_summary (MSG_TXT (M_RECV), rxfname, &rxfsize, Rx_y);
- if (lseek (rxfd, 0L, SEEK_END) < 0L)
- {
- (void) j_error (MSG_TXT (M_SEEK_MSG), rxpathname);
- hydra_badxfer ();
- rxpos = -2L;
- }
- else
- {
- diskfree = zfree (rxpathname); /*AGL:07jul93*/
- rxoffset = rxpos = tell (rxfd);
- if (rxpos < 0L)
- {
- (void) j_error (MSG_TXT (M_SEEK_MSG), rxfname);
- hydra_badxfer ();
- rxpos = -2L;
- }
- else
- {
- if ((rxfsize - rxoffset) + 10240L > diskfree)
- { /*AGL:07jul93*/
- j_status (MSG_TXT (M_OUT_OF_DISK_SPACE));
- hydra_badxfer ();
- rxpos = -2L;
- }
- else
- {
- rxstart = 0L;
- rxtimer = h_timer_reset ();
- rxretries = 0;
- rxlastsync = 0L;
- rxsyncid = 0L;
- update_status (&rxpos, &rxoldpos, rxfsize - rxpos, &rxoldeta, Rx_y);
- if (rxpos > 0L)
- {
- j_status (MSG_TXT (M_SYNCHRONIZING_OFFSET), rxpos);
- }
- rxstate = HRX_DATA;
- }
- }
- }
- }
- }
- }
- }
- }
- else if (rxstate == HRX_DONE)
- rxpos = (!rxbuf[0]) ? 0L : -2L;
-
- h_long1 (txbufin) = intell (rxpos);
- txpkt ((int) sizeof (long), HPKT_FINFOACK);
-
- break;
-
- /*---------------------------------------------------*/
- case HPKT_FINFOACK:
- if (txstate == HTX_FINFO || txstate == HTX_FINFOACK)
- {
- braindead = h_timer_set (H_BRAINDEAD);
- txretries = 0;
- if (!txfname[0])
- {
- txtimer = h_timer_set (H_IDLE);
- txstate = HTX_REND;
- }
- else
- {
- txtimer = h_timer_reset ();
- txpos = intell (h_long1 (rxbuf));
- if (txpos >= 0L)
- {
- txoffset = txpos;
- txlastack = txpos;
- update_status (&txpos, &txoldpos, txfsize - txpos, &txoldeta, Tx_y);
- if (txpos > 0L)
- {
- j_status (MSG_TXT (M_SYNCHRONIZING_OFFSET), txpos);
- if (lseek (txfd, txpos, SEEK_SET) < 0L)
- {
- (void) j_error (MSG_TXT (M_SEEK_MSG), txfname);
- close (txfd);
- txfd = -1;
- txpos = -2L;
- txstate = HTX_EOF;
- break;
- }
- }
- txstate = HTX_XDATA;
- }
- else
- {
- close (txfd);
- if (txpos == -1L)
- {
- j_status (MSG_TXT (M_REMOTE_REFUSED), txfname);
- return (XFER_OK);
- }
- else
- /* (txpos < -1L) file NOT sent */
- {
- j_status ("+HSEND: Skipping %s", txfname);
- return (XFER_SKIP);
- }
- }
- }
- }
- break;
-
- /*---------------------------------------------------*/
- case HPKT_DATA:
- if (rxstate == HRX_DATA)
- {
- if (intell (h_long1 (rxbuf)) != rxpos ||
- intell (h_long1 (rxbuf)) < 0L)
- {
- if (intell (h_long1 (rxbuf)) <= rxlastsync)
- {
- rxtimer = h_timer_reset ();
- rxretries = 0;
- }
- rxlastsync = intell (h_long1 (rxbuf));
-
- if (!h_timer_running (rxtimer) ||
- h_timer_expired (rxtimer, h_timer_get ()))
- {
- if (rxretries > 4)
- {
- if (txstate < HTX_REND &&
- !originator && !hdxlink)
- {
- hdxlink = TRUE;
- rxretries = 0;
- }
- }
- if (++rxretries > H_RETRIES)
- {
- j_status (MSG_TXT (M_FUBAR_MSG));
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
- }
- if (rxretries == 1 || rxretries == 4) /*AGL:14may93*/
- rxsyncid++;
-
- rxblklen /= 2;
- i = rxblklen;
- if (i <= 64)
- i = 64;
- else if (i <= 128)
- i = 128;
- else if (i <= 256)
- i = 256;
- else if (i <= 512)
- i = 512;
- else
- i = 1024;
- j_message (Rx_y, MSG_TXT (M_J_BAD_PACKET), rxpos);
- #ifdef DEBUG
- j_status ("-HRECV: Bad pkt at %ld - Retry %u (newblklen=%u)",
- rxpos, rxretries, i);
- #endif
- h_long1 (txbufin) = intell (rxpos);
- h_long2 (txbufin) = intell ((long) i);
- h_long3 (txbufin) = intell (rxsyncid);
- txpkt (3 * ((int) sizeof (long)), HPKT_RPOS);
-
- rxtimer = h_timer_set (timeout);
- }
- }
- else
- {
- braindead = h_timer_set (H_BRAINDEAD);
- rxpktlen -= (int) sizeof (long);
-
- rxblklen = rxpktlen;
- if (write (rxfd, rxbuf + ((int) sizeof (long)), rxpktlen) < 0)
- {
- j_error (MSG_TXT (M_WRITE_MSG), rxfname);
- hydra_badxfer ();
- rxpos = -2L;
- rxretries = 1;
- rxsyncid++;
- h_long1 (txbufin) = intell (rxpos);
- h_long2 (txbufin) = intell (0L);
- h_long3 (txbufin) = intell (rxsyncid);
- txpkt (3 * ((int) sizeof (long)), HPKT_RPOS);
-
- rxtimer = h_timer_set (timeout);
- break;
- }
- rxretries = 0;
- rxtimer = h_timer_reset ();
- rxlastsync = rxpos;
- rxpos += rxpktlen;
- if (rxwindow)
- {
- h_long1 (txbufin) = intell (rxpos);
- txpkt ((int) sizeof (long), HPKT_DATAACK);
- }
- if (!rxstart)
- rxstart = time (NULL) -
- ((rxpktlen * 10) / cur_baud.rate_value);
- update_status (&rxpos, &rxoldpos, rxfsize - rxpos, &rxoldeta, Rx_y);
- } /*badpkt*/
- } /*rxstate==HRX_DATA*/
- break;
-
- /*---------------------------------------------------*/
- case HPKT_DATAACK:
- if (txstate == HTX_XDATA || txstate == HTX_DATAACK ||
- txstate == HTX_XWAIT ||
- txstate == HTX_EOF || txstate == HTX_EOFACK)
- {
- if (txwindow && intell (h_long1 (rxbuf)) > txlastack)
- {
- txlastack = intell (h_long1 (rxbuf));
- if (txstate == HTX_DATAACK &&
- (txpos < (txlastack + txwindow)))
- {
- txstate = HTX_XDATA;
- txretries = 0;
- txtimer = h_timer_reset ();
- }
- }
- }
- break;
-
- /*---------------------------------------------------*/
- case HPKT_RPOS:
- if (txstate == HTX_XDATA || txstate == HTX_DATAACK ||
- txstate == HTX_XWAIT ||
- txstate == HTX_EOF || txstate == HTX_EOFACK)
- {
- if (intell (h_long3 (rxbuf)) != txsyncid)
- {
- txsyncid = intell (h_long3 (rxbuf));
- txretries = 1;
- }
- else
- /*AGL:14may93*/
- {
- if (++txretries > H_RETRIES)
- {
- j_status (MSG_TXT (M_FUBAR_MSG));
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
- }
- if (txretries != 4)
- break; /*AGL:14may93*/
- }
-
- txtimer = h_timer_reset ();
- txpos = intell (h_long1 (rxbuf));
- if (txpos < 0L)
- {
- if (txfd >= 0)
- {
- j_status ("+HSEND: Skipping %s", txfname);
- close (txfd);
- txfd = -1;
- txstate = HTX_EOF;
- }
- txpos = -2L;
- break;
- }
-
- if (txblklen > (word) intell (h_long2 (rxbuf)))
- txblklen = (word) intell (h_long2 (rxbuf));
- else
- txblklen >>= 1;
- if (txblklen <= 64)
- txblklen = 64;
- else if (txblklen <= 128)
- txblklen = 128;
- else if (txblklen <= 256)
- txblklen = 256;
- else if (txblklen <= 512)
- txblklen = 512;
- else
- txblklen = 1024;
- txgoodbytes = 0;
- txgoodneeded += txmaxblklen * 2; /*AGL:23feb93*/
- if (txgoodneeded > txmaxblklen * 8) /*AGL:23feb93*/
- txgoodneeded = txmaxblklen * 8; /*AGL:23feb93*/
-
- update_status (&txpos, &txoldpos, txfsize - txpos, &txoldeta, Tx_y);
- j_status (MSG_TXT (M_SYNCHRONIZING_OFFSET), txpos);
- if (lseek (txfd, txpos, SEEK_SET) < 0L)
- {
- (void) j_error (MSG_TXT (M_SEEK_MSG), txfname);
- close (txfd);
- txfd = -1;
- txpos = -2L;
- txstate = HTX_EOF;
- break;
- }
-
- if (txstate != HTX_XWAIT)
- txstate = HTX_XDATA;
- }
- break;
-
- /*---------------------------------------------------*/
- case HPKT_EOF:
- if (rxstate == HRX_DATA)
- {
- if (intell (h_long1 (rxbuf)) < 0L)
- {
- hydra_badxfer ();
- j_status ("+HRECV: Skipping %s", rxfname);
- rxstate = HRX_FINFO;
- braindead = h_timer_set (H_BRAINDEAD);
- }
- else if (intell (h_long1 (rxbuf)) != rxpos)
- {
- if (intell (h_long1 (rxbuf)) <= rxlastsync)
- {
- rxtimer = h_timer_reset ();
- rxretries = 0;
- }
- rxlastsync = intell (h_long1 (rxbuf));
-
- if (!h_timer_running (rxtimer) ||
- h_timer_expired (rxtimer, h_timer_get ()))
- {
- if (++rxretries > H_RETRIES)
- {
- j_status (MSG_TXT (M_FUBAR_MSG));
- txstate = HTX_DONE;
- res = XFER_ABORT;
- break;
- }
- if (rxretries == 1 || rxretries == 4) /*AGL:14may93*/
- rxsyncid++;
-
- rxblklen /= 2;
- i = rxblklen;
- if (i <= 64)
- i = 64;
- else if (i <= 128)
- i = 128;
- else if (i <= 256)
- i = 256;
- else if (i <= 512)
- i = 512;
- else
- i = 1024;
-
- j_status ("-HRECV: Bad EOF at %ld - Retry %u (newblklen=%u)",
- rxpos, rxretries, i);
- h_long1 (txbufin) = intell (rxpos);
- h_long2 (txbufin) = intell ((long) i);
- h_long3 (txbufin) = intell (rxsyncid);
- txpkt (3 * ((int) sizeof (long)), HPKT_RPOS);
-
- rxtimer = h_timer_set (timeout);
- }
- }
- else
- {
- long rxtime;
-
- close (rxfd);
- rxfd = -1;
-
- if (Resume_WaZOO) /* resumed transfer? */
- {
- if (xfer_okay ())
- {
- j_status (MSG_TXT (M_RENAME_MSG), rxpathname);
- }
- }
-
- if (rxftime > 0) /* utime doesn't like negative numbers */
- {
- struct utimbuf utimes;
-
- utimes.UT_ACTIME = rxftime;
- utimes.modtime = rxftime;
- (void) utime (rxpathname, (UTIMBUF *) & utimes);
- }
-
- rxtime = through (&rxfsize, &rxstart);
- rxfsize = rxpos - rxoffset;
- j_status ("%s-H%s %s", MSG_TXT (M_FILE_RECEIVED), (txoptions & HOPT_CRC32) ? "/32" : " ", rxpathname);
- j_msgend (Rx_y);
- update_files (0, rxpathname, rxfsize, rxtime, 0);
-
- rxstate = HRX_FINFO;
- braindead = h_timer_set (H_BRAINDEAD);
- } /*skip/badeof/eof*/
- } /*rxstate==HRX_DATA*/
-
- if (rxstate == HRX_FINFO)
- txpkt (0, HPKT_EOFACK);
- break;
-
- /*---------------------------------------------------*/
- case HPKT_EOFACK:
- if (txstate == HTX_EOF || txstate == HTX_EOFACK)
- {
- braindead = h_timer_set (H_BRAINDEAD);
- if (txfd >= 0)
- {
- long txtime;
-
- close (txfd);
-
- txfsize = txpos - txoffset;
- txtime = through (&txfsize, &txstart);
- j_status ("%s-H%s %s", MSG_TXT (M_FILE_SENT), (txoptions & HOPT_CRC32) ? "/32" : " ", txpathname);
- j_msgend (Tx_y);
- update_files (1, txpathname, txfsize, txtime, 0);
-
- return (XFER_OK);
- }
- else
- return (XFER_SKIP);
- }
- break;
-
- /*---------------------------------------------------*/
- case HPKT_IDLE:
- if (txstate == HTX_XWAIT)
- {
- hdxlink = FALSE;
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_XDATA;
- }
- else if (txstate >= HTX_FINFO && txstate < HTX_REND)
- braindead = h_timer_set (H_BRAINDEAD);
- break;
-
- /*---------------------------------------------------*/
- case HPKT_END:
- if (txstate == HTX_END || txstate == HTX_ENDACK)
- {
- txpkt (0, HPKT_END);
- txpkt (0, HPKT_END);
- txpkt (0, HPKT_END);
- #ifdef DEBUG
- j_status ("+HYDRA: Completed");
- #endif
- txstate = HTX_DONE;
- res = XFER_OK;
- }
- break;
-
- #ifdef HYDRADEV
- /*---------------------------------------------------*/
- case HPKT_DEVDATA:
- if (devrxid != intell (h_long1 (rxbuf)))
- {
- hydra_devrecv ();
- devrxid = intell (h_long1 (rxbuf));
- }
- h_long1 (txbufin) = h_long1 (rxbuf); /*AGL:10feb93*/
- txpkt ((int) sizeof (long), HPKT_DEVDACK);
-
- break;
-
- /*---------------------------------------------------*/
- case HPKT_DEVDACK:
- if (devtxstate && (devtxid == intell (h_long1 (rxbuf))))
- {
- devtxtimer = h_timer_reset ();
- devtxstate = HTD_DONE;
- }
- break;
- #endif
-
- /*---------------------------------------------------*/
- default: /* unknown packet types: IGNORE, no error! */
- break;
-
- /*---------------------------------------------------*/
- } /*(pkttype)*/
-
- /*------------------------------------------------------*/
- switch (txstate)
- {
- /*---------------------------------------------------*/
- case HTX_START:
- case HTX_SWAIT:
- if (rxstate == HRX_FINFO)
- {
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_INIT;
- }
- break;
-
- /*---------------------------------------------------*/
- case HTX_RINIT:
- if (rxstate == HRX_FINFO)
- {
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_FINFO;
- }
- break;
-
- /*---------------------------------------------------*/
- case HTX_XDATA:
- if (rxstate && hdxlink)
- {
- j_status (MSG_TXT (M_GOING_ONE_WAY));
- #ifdef HYDRADEV
- hydra_devsend ("MSG", (byte *) hdxmsg, (int) strlen (hdxmsg));
- #endif
- txtimer = h_timer_set (H_IDLE);
- txstate = HTX_XWAIT;
- }
- break;
-
- /*---------------------------------------------------*/
- case HTX_XWAIT:
- if (!rxstate)
- {
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_XDATA;
- }
- break;
-
- /*---------------------------------------------------*/
- case HTX_REND:
- #ifdef HYDRADEV
- if (!rxstate && !devtxstate)
- #else
- if (!rxstate)
- #endif
- {
- txtimer = h_timer_reset ();
- txretries = 0;
- txstate = HTX_END;
- }
- break;
-
- /*---------------------------------------------------*/
- default: /* any other state - nothing to do */
- break;
-
- } /*switch(txstate)*/
-
- }
- while (txstate);
-
- if (txfd >= 0)
- close (txfd);
- hydra_badxfer ();
-
- if (res == XFER_ABORT)
- {
- CLEAR_OUTBOUND ();
- if (remote_capabilities)
- LOWER_DTR ();
- if (CARRIER)
- {
- braindead = h_timer_set (10); /* wait max. 10s after abort */
- ComTXBlockTimeout (abortstr, (int) strlen (abortstr), braindead);
- while (!OUT_EMPTY () && CARRIER && !h_timer_expired (braindead, h_timer_get ()))
- time_release ();
- CLEAR_OUTBOUND ();
- }
- CLEAR_INBOUND ();
- mail_finished = 0;
- }
- else
- {
- braindead = h_timer_set (10); /* wait max. 10s after abort */
- while (!OUT_EMPTY () && CARRIER && !h_timer_expired (braindead, h_timer_get ()))
- time_release ();
- }
- return (res);
- } /*hydra()*/
-
- /* end of hydra.c */
-