Annotation of coherent/g/usr/lib/uucp/tay104/prott.c, revision 1.1.1.1

1.1       root        1: /* prott.c
                      2:    The 't' protocol.
                      3: 
                      4:    Copyright (C) 1991, 1992 Ian Lance Taylor
                      5: 
                      6:    This file is part of the Taylor UUCP package.
                      7: 
                      8:    This program is free software; you can redistribute it and/or
                      9:    modify it under the terms of the GNU General Public License as
                     10:    published by the Free Software Foundation; either version 2 of the
                     11:    License, or (at your option) any later version.
                     12: 
                     13:    This program is distributed in the hope that it will be useful, but
                     14:    WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     16:    General Public License for more details.
                     17: 
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with this program; if not, write to the Free Software
                     20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     21: 
                     22:    The author of the program may be contacted at [email protected] or
                     23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
                     24:    */
                     25: 
                     26: #include "uucp.h"
                     27: 
                     28: #if USE_RCS_ID
                     29: const char prott_rcsid[] = "$Id: prott.c,v 1.1 93/07/30 07:53:37 bin Exp Locker: bin $";
                     30: #endif
                     31: 
                     32: #include "uudefs.h"
                     33: #include "uuconf.h"
                     34: #include "conn.h"
                     35: #include "trans.h"
                     36: #include "system.h"
                     37: #include "prot.h"
                     38: 
                     39: /* This implementation is based on code written by Rick Adams.
                     40: 
                     41:    This code implements the 't' protocol, which does no error checking
                     42:    whatsoever and thus requires an end-to-end verified eight bit
                     43:    communication line, such as is provided by TCP.  Using it with a
                     44:    modem is unadvisable, since errors can occur between the modem and
                     45:    the computer.  */
                     46: 
                     47: /* The buffer size we use.  */
                     48: #define CTBUFSIZE (1024)
                     49: 
                     50: /* The offset in the buffer to the data.  */
                     51: #define CTFRAMELEN (4)
                     52: 
                     53: /* Commands are sent in multiples of this size.  */
                     54: #define CTPACKSIZE (512)
                     55: 
                     56: /* A pointer to the buffer we will use.  */
                     57: static char *zTbuf;
                     58: 
                     59: /* True if we are receiving a file.  */
                     60: static boolean fTfile;
                     61: 
                     62: /* The timeout we use.  */
                     63: static int cTtimeout = 120;
                     64: 
                     65: struct uuconf_cmdtab asTproto_params[] =
                     66: {
                     67:   { "timeout", UUCONF_CMDTABTYPE_INT, (pointer) &cTtimeout, NULL },
                     68:   { NULL, 0, NULL, NULL }
                     69: };
                     70: 
                     71: /* Local function.  */
                     72: 
                     73: static boolean ftprocess_data P((struct sdaemon *qdaemon, boolean *pfexit,
                     74:                                 size_t *pcneed));
                     75: 
                     76: /* Start the protocol.  */
                     77: 
                     78: boolean
                     79: ftstart (qdaemon, pzlog)
                     80:      struct sdaemon *qdaemon;
                     81:      char **pzlog;
                     82: {
                     83:   *pzlog = NULL;
                     84:   if (! fconn_set (qdaemon->qconn, PARITYSETTING_NONE,
                     85:                   STRIPSETTING_EIGHTBITS, XONXOFF_OFF))
                     86:     return FALSE;
                     87:   zTbuf = (char *) xmalloc (CTBUFSIZE + CTFRAMELEN);
                     88:   /* The first two bytes of the buffer are always zero.  */
                     89:   zTbuf[0] = 0;
                     90:   zTbuf[1] = 0;
                     91:   fTfile = FALSE;
                     92:   usysdep_sleep (2);
                     93:   return TRUE;
                     94: }
                     95: 
                     96: /* Stop the protocol.  */
                     97: 
                     98: /*ARGSUSED*/
                     99: boolean 
                    100: ftshutdown (qdaemon)
                    101:      struct sdaemon *qdaemon;
                    102: {
                    103:   xfree ((pointer) zTbuf);
                    104:   zTbuf = NULL;
                    105:   cTtimeout = 120;
                    106:   return TRUE;
                    107: }
                    108: 
                    109: /* Send a command string.  We send everything up to and including the
                    110:    null byte.  The number of bytes we send must be a multiple of
                    111:    TPACKSIZE.  */
                    112: 
                    113: /*ARGSUSED*/
                    114: boolean
                    115: ftsendcmd (qdaemon, z, ilocal, iremote)
                    116:      struct sdaemon *qdaemon;
                    117:      const char *z;
                    118:      int ilocal;
                    119:      int iremote;
                    120: {
                    121:   size_t clen, csend;
                    122:   char *zalc;
                    123:   boolean fret;
                    124: 
                    125:   DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "ftsendcmd: Sending command \"%s\"", z);
                    126: 
                    127:   clen = strlen (z);
                    128: 
                    129:   /* We need to send the smallest multiple of CTPACKSIZE which is
                    130:      greater than clen (not equal to clen, since we need room for the
                    131:      null byte).  */
                    132:   csend = ((clen / CTPACKSIZE) + 1) * CTPACKSIZE;
                    133: 
                    134:   zalc = zbufalc (csend);
                    135:   memcpy (zalc, z, clen);
                    136:   bzero (zalc + clen, csend - clen);
                    137: 
                    138:   fret = fsend_data (qdaemon->qconn, zalc, csend, TRUE);
                    139:   ubuffree (zalc);
                    140:   return fret;
                    141: }
                    142: 
                    143: /* Get space to be filled with data.  We provide a buffer which has
                    144:    four bytes at the start available to hold the length.  */
                    145: 
                    146: /*ARGSIGNORED*/
                    147: char *
                    148: ztgetspace (qdaemon, pclen)
                    149:      struct sdaemon *qdaemon;
                    150:      size_t *pclen;
                    151: {
                    152:   *pclen = CTBUFSIZE;
                    153:   return zTbuf + CTFRAMELEN;
                    154: }
                    155: 
                    156: /* Send out some data.  We are allowed to modify the four bytes
                    157:    preceding the buffer.  This allows us to send the entire block with
                    158:    header bytes in a single call.  */
                    159: 
                    160: /*ARGSIGNORED*/
                    161: boolean
                    162: ftsenddata (qdaemon, zdata, cdata, ilocal, iremote, ipos)
                    163:      struct sdaemon *qdaemon;
                    164:      char *zdata;
                    165:      size_t cdata;
                    166:      int ilocal;
                    167:      int iremote;
                    168:      long ipos;
                    169: {
                    170:   /* Here we do htonl by hand, since it doesn't exist everywhere.  We
                    171:      know that the amount of data cannot be greater than CTBUFSIZE, so
                    172:      the first two bytes of this value will always be 0.  They were
                    173:      set to 0 in ftstart so we don't touch them here.  This is useful
                    174:      because we cannot portably right shift by 24 or 16, since we
                    175:      might be dealing with sixteen bit integers.  */
                    176:   zdata[-2] = (char) ((cdata >> 8) & 0xff);
                    177:   zdata[-1] = (char) (cdata & 0xff);
                    178: 
                    179:   /* We pass FALSE to fsend_data since we don't expect the other side
                    180:      to be sending us anything just now.  */
                    181:   return fsend_data (qdaemon->qconn, zdata - CTFRAMELEN, cdata + CTFRAMELEN,
                    182:                     FALSE);
                    183: }
                    184: 
                    185: /* Process data and return the amount we need in *pfneed.  */
                    186: 
                    187: static boolean
                    188: ftprocess_data (qdaemon, pfexit, pcneed)
                    189:      struct sdaemon *qdaemon;
                    190:      boolean *pfexit;
                    191:      size_t *pcneed;
                    192: {
                    193:   int cinbuf, cfirst, clen;
                    194: 
                    195:   *pfexit = FALSE;
                    196: 
                    197:   cinbuf = iPrecend - iPrecstart;
                    198:   if (cinbuf < 0)
                    199:     cinbuf += CRECBUFLEN;
                    200: 
                    201:   if (! fTfile)
                    202:     {
                    203:       /* We are not receiving a file.  Commands are read in chunks of
                    204:         CTPACKSIZE.  */
                    205:       while (cinbuf >= CTPACKSIZE)
                    206:        {
                    207:          cfirst = CRECBUFLEN - iPrecstart;
                    208:          if (cfirst > CTPACKSIZE)
                    209:            cfirst = CTPACKSIZE;
                    210: 
                    211:          DEBUG_MESSAGE1 (DEBUG_PROTO,
                    212:                          "ftprocess_data: Got %d command bytes",
                    213:                          cfirst);
                    214: 
                    215:          if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
                    216:                           (size_t) cfirst, abPrecbuf,
                    217:                           (size_t) CTPACKSIZE - cfirst,
                    218:                           -1, -1, (long) -1, TRUE, pfexit))
                    219:            return FALSE;
                    220: 
                    221:          iPrecstart = (iPrecstart + CTPACKSIZE) % CRECBUFLEN;
                    222: 
                    223:          if (*pfexit)
                    224:            return TRUE;
                    225: 
                    226:          cinbuf -= CTPACKSIZE;
                    227:        }
                    228: 
                    229:       if (pcneed != NULL)
                    230:        *pcneed = CTPACKSIZE - cinbuf;
                    231: 
                    232:       return TRUE;
                    233:     }
                    234: 
                    235:   /* Here we are receiving a file.  The data comes in blocks.  The
                    236:      first four bytes contain the length, followed by that amount of
                    237:      data.  */
                    238: 
                    239:   while (cinbuf >= CTFRAMELEN)
                    240:     {
                    241:       /* The length is stored in network byte order, MSB first.  */
                    242: 
                    243:       clen = (((((((abPrecbuf[iPrecstart] & 0xff) << 8)
                    244:                  + (abPrecbuf[(iPrecstart + 1) % CRECBUFLEN] & 0xff)) << 8)
                    245:                + (abPrecbuf[(iPrecstart + 2) % CRECBUFLEN] & 0xff)) << 8)
                    246:              + (abPrecbuf[(iPrecstart + 3) % CRECBUFLEN] & 0xff));
                    247: 
                    248:       if (cinbuf < clen + CTFRAMELEN)
                    249:        {
                    250:          if (pcneed != NULL)
                    251:            *pcneed = clen + CTFRAMELEN - cinbuf;
                    252:          return TRUE;
                    253:        }
                    254: 
                    255:       iPrecstart = (iPrecstart + CTFRAMELEN) % CRECBUFLEN;
                    256: 
                    257:       cfirst = CRECBUFLEN - iPrecstart;
                    258:       if (cfirst > clen)
                    259:        cfirst = clen;
                    260: 
                    261:       DEBUG_MESSAGE1 (DEBUG_PROTO,
                    262:                      "ftprocess_data: Got %d data bytes",
                    263:                      clen);
                    264: 
                    265:       if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
                    266:                       (size_t) cfirst, abPrecbuf, (size_t) (clen - cfirst),
                    267:                       -1, -1, (long) -1, TRUE, pfexit))
                    268:        return FALSE;
                    269: 
                    270:       iPrecstart = (iPrecstart + clen) % CRECBUFLEN;
                    271:                           
                    272:       if (*pfexit)
                    273:        return TRUE;
                    274: 
                    275:       cinbuf -= clen + CTFRAMELEN;
                    276:     }
                    277: 
                    278:   if (pcneed != NULL)
                    279:     *pcneed = CTFRAMELEN - cinbuf;
                    280: 
                    281:   return TRUE;
                    282: }
                    283: 
                    284: /* Wait for data to come in and process it until we've reached the end
                    285:    of a command or a file.  */
                    286: 
                    287: boolean
                    288: ftwait (qdaemon)
                    289:      struct sdaemon *qdaemon;
                    290: {
                    291:   while (TRUE)
                    292:     {
                    293:       boolean fexit;
                    294:       size_t cneed, crec;
                    295: 
                    296:       if (! ftprocess_data (qdaemon, &fexit, &cneed))
                    297:        return FALSE;
                    298:       if (fexit)
                    299:        return TRUE;
                    300: 
                    301:       if (! freceive_data (qdaemon->qconn, cneed, &crec, cTtimeout, TRUE))
                    302:        return FALSE;
                    303: 
                    304:       if (crec == 0)
                    305:        {
                    306:          ulog (LOG_ERROR, "Timed out waiting for data");
                    307:          return FALSE;
                    308:        }
                    309:     }
                    310: }
                    311: 
                    312: /* File level routine, to set fTfile correctly.  */
                    313: 
                    314: /*ARGSUSED*/
                    315: boolean
                    316: ftfile (qdaemon, qtrans, fstart, fsend, cbytes, pfhandled)
                    317:      struct sdaemon *qdaemon;
                    318:      struct stransfer *qtrans;
                    319:      boolean fstart;
                    320:      boolean fsend;
                    321:      long cbytes;
                    322:      boolean *pfhandled;
                    323: {
                    324:   *pfhandled = FALSE;
                    325: 
                    326:   if (! fsend)
                    327:     fTfile = fstart;
                    328: 
                    329:   return TRUE;
                    330: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.