Annotation of coherent/g/usr/lib/uucp/tay104/prott.c, revision 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.