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

1.1       root        1: /* prote.c
                      2:    The 'e' 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 prote_rcsid[] = "$Id: prote.c,v 1.1 93/07/30 07:53:17 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 my implementation of the 't'
                     40:    protocol, which is fairly similar.  The main difference between the
                     41:    protocols seems to be that 't' breaks the file into packets and
                     42:    transmits the size of the packet with each packet, whereas 'e'
                     43:    sends the size of the entire file and then sends all the data in a
                     44:    single enormous packet.
                     45: 
                     46:    The 'e' protocol does no error checking whatsoever and thus
                     47:    requires an end-to-end verified eight bit communication line, such
                     48:    as is provided by TCP.  Using it with a modem is inadvisable, since
                     49:    errors can occur between the modem and the computer.  */
                     50: 
                     51: /* The buffer size we use.  */
                     52: #define CEBUFSIZE (CRECBUFLEN / 2)
                     53: 
                     54: /* The size of the initial file size message.  */
                     55: #define CEFRAMELEN (20)
                     56: 
                     57: /* A pointer to the buffer we will use.  */
                     58: static char *zEbuf;
                     59: 
                     60: /* True if we are receiving a file.  */
                     61: static boolean fEfile;
                     62: 
                     63: /* The number of bytes we have left to send or receive.  */
                     64: static long cEbytes;
                     65: 
                     66: /* The timeout we use.  */
                     67: static int cEtimeout = 120;
                     68: 
                     69: struct uuconf_cmdtab asEproto_params[] =
                     70: {
                     71:   { "timeout", UUCONF_CMDTABTYPE_INT, (pointer) &cEtimeout, NULL },
                     72:   { NULL, 0, NULL, NULL }
                     73: };
                     74: 
                     75: /* Local function.  */
                     76: 
                     77: static boolean feprocess_data P((struct sdaemon *qdaemon, boolean *pfexit,
                     78:                                 size_t *pcneed));
                     79: 
                     80: /* Start the protocol.  */
                     81: 
                     82: boolean
                     83: festart (qdaemon, pzlog)
                     84:      struct sdaemon *qdaemon;
                     85:      char **pzlog;
                     86: {
                     87:   *pzlog = NULL;
                     88:   if (! fconn_set (qdaemon->qconn, PARITYSETTING_NONE,
                     89:                   STRIPSETTING_EIGHTBITS, XONXOFF_OFF))
                     90:     return FALSE;
                     91:   zEbuf = (char *) xmalloc (CEBUFSIZE);
                     92:   fEfile = FALSE;
                     93:   usysdep_sleep (2);
                     94:   return TRUE;
                     95: }
                     96: 
                     97: /* Stop the protocol.  */
                     98: 
                     99: /*ARGSUSED*/
                    100: boolean 
                    101: feshutdown (qdaemon)
                    102:      struct sdaemon *qdaemon;
                    103: {
                    104:   xfree ((pointer) zEbuf);
                    105:   zEbuf = NULL;
                    106:   cEtimeout = 120;
                    107:   return TRUE;
                    108: }
                    109: 
                    110: /* Send a command string.  We send everything up to and including the
                    111:    null byte.   */
                    112: 
                    113: /*ARGSUSED*/
                    114: boolean
                    115: fesendcmd (qdaemon, z, ilocal, iremote)
                    116:      struct sdaemon *qdaemon;
                    117:      const char *z;
                    118:      int ilocal;
                    119:      int iremote;
                    120: {
                    121:   DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "fesendcmd: Sending command \"%s\"", z);
                    122: 
                    123:   return fsend_data (qdaemon->qconn, z, strlen (z) + 1, TRUE);
                    124: }
                    125: 
                    126: /* Get space to be filled with data.  We provide a buffer which has
                    127:    20 bytes at the start available to hold the length.  */
                    128: 
                    129: /*ARGSUSED*/
                    130: char *
                    131: zegetspace (qdaemon, pclen)
                    132:      struct sdaemon *qdaemon;
                    133:      size_t *pclen;
                    134: {
                    135:   *pclen = CEBUFSIZE;
                    136:   return zEbuf;
                    137: }
                    138: 
                    139: /* Send out some data.  We are allowed to modify the 20 bytes
                    140:    preceding the buffer.  This allows us to send the entire block with
                    141:    header bytes in a single call.  */
                    142: 
                    143: /*ARGSIGNORED*/
                    144: boolean
                    145: fesenddata (qdaemon, zdata, cdata, ilocal, iremote, ipos)
                    146:      struct sdaemon *qdaemon;
                    147:      char *zdata;
                    148:      size_t cdata;
                    149:      int ilocal;
                    150:      int iremote;
                    151:      long ipos;
                    152: {
                    153: #if DEBUG > 0
                    154:   /* Keep track of the number of bytes we send out to make sure it all
                    155:      adds up.  */
                    156:   cEbytes -= cdata;
                    157:   if (cEbytes < 0)
                    158:     {
                    159:       ulog (LOG_ERROR, "Protocol 'e' internal error");
                    160:       return FALSE;
                    161:     }
                    162: #endif
                    163: 
                    164:   /* We pass FALSE to fsend_data since we don't expect the other side
                    165:      to be sending us anything just now.  */
                    166:   return fsend_data (qdaemon->qconn, zdata, cdata, FALSE);
                    167: }
                    168: 
                    169: /* Process data and return the amount we need in *pfneed.  */
                    170: 
                    171: static boolean
                    172: feprocess_data (qdaemon, pfexit, pcneed)
                    173:      struct sdaemon *qdaemon;
                    174:      boolean *pfexit;
                    175:      size_t *pcneed;
                    176: {
                    177:   int cinbuf, cfirst, clen;
                    178: 
                    179:   *pfexit = FALSE;
                    180: 
                    181:   cinbuf = iPrecend - iPrecstart;
                    182:   if (cinbuf < 0)
                    183:     cinbuf += CRECBUFLEN;
                    184: 
                    185:   if (! fEfile)
                    186:     {
                    187:       /* We are not receiving a file.  Commands continue up to a null
                    188:         byte.  */
                    189:       while (cinbuf > 0)
                    190:        {
                    191:          char *pnull;
                    192: 
                    193:          cfirst = CRECBUFLEN - iPrecstart;
                    194:          if (cfirst > cinbuf)
                    195:            cfirst = cinbuf;
                    196: 
                    197:          pnull = memchr (abPrecbuf + iPrecstart, '\0', (size_t) cfirst);
                    198:          if (pnull != NULL)
                    199:            cfirst = pnull - (abPrecbuf + iPrecstart) + 1;
                    200: 
                    201:          DEBUG_MESSAGE1 (DEBUG_PROTO,
                    202:                          "feprocess_data: Got %d command bytes",
                    203:                          cfirst);
                    204: 
                    205:          if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
                    206:                           (size_t) cfirst, (const char *) NULL, (size_t) 0,
                    207:                           -1, -1, (long) -1, TRUE, pfexit))
                    208:            return FALSE;
                    209: 
                    210:          iPrecstart = (iPrecstart + cfirst) % CRECBUFLEN;
                    211: 
                    212:          if (*pfexit)
                    213:            return TRUE;
                    214: 
                    215:          cinbuf = iPrecend - iPrecstart;
                    216:          if (cinbuf < 0)
                    217:            cinbuf += CRECBUFLEN;
                    218:        }
                    219: 
                    220:       if (pcneed != NULL)
                    221:        *pcneed = 1;
                    222: 
                    223:       return TRUE;
                    224:     }
                    225: 
                    226:   /* Here we are receiving a file.  We want cEbytes in total.  If we
                    227:      don't have cEbytes yet, we have to get it first.  */
                    228: 
                    229:   if (cEbytes == -1)
                    230:     {
                    231:       char ab[CEFRAMELEN + 1];
                    232: 
                    233:       if (cinbuf < CEFRAMELEN)
                    234:        {
                    235:          if (pcneed != NULL)
                    236:            *pcneed = CEFRAMELEN - cinbuf;
                    237:          return TRUE;
                    238:        }
                    239: 
                    240:       cfirst = CRECBUFLEN - iPrecstart;
                    241:       if (cfirst >= CEFRAMELEN)
                    242:        memcpy (ab, abPrecbuf + iPrecstart, (size_t) CEFRAMELEN);
                    243:       else
                    244:        {
                    245:          memcpy (ab, abPrecbuf + iPrecstart, (size_t) cfirst);
                    246:          memcpy (ab + cfirst, abPrecbuf, (size_t) CEFRAMELEN - cfirst);
                    247:        }
                    248: 
                    249:       ab[CEFRAMELEN] = '\0';
                    250:       cEbytes = strtol (ab, (char **) NULL, 10);
                    251: 
                    252:       iPrecstart = (iPrecstart + CEFRAMELEN) % CRECBUFLEN;
                    253: 
                    254:       cinbuf = iPrecend - iPrecstart;
                    255:       if (cinbuf < 0)
                    256:        cinbuf += CRECBUFLEN;
                    257:     }
                    258: 
                    259:   /* Here we can read real data for the file.  */
                    260: 
                    261:   while (cinbuf > 0)
                    262:     {
                    263:       clen = cinbuf;
                    264:       if ((long) clen > cEbytes)
                    265:        clen = (int) cEbytes;
                    266: 
                    267:       cfirst = CRECBUFLEN - iPrecstart;
                    268:       if (cfirst > clen)
                    269:        cfirst = clen;
                    270: 
                    271:       DEBUG_MESSAGE1 (DEBUG_PROTO,
                    272:                      "feprocess_data: Got %d data bytes",
                    273:                      clen);
                    274: 
                    275:       if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
                    276:                       (size_t) cfirst, abPrecbuf, (size_t) (clen - cfirst),
                    277:                       -1, -1, (long) -1, TRUE, pfexit))
                    278:        return FALSE;
                    279: 
                    280:       iPrecstart = (iPrecstart + clen) % CRECBUFLEN;
                    281:       cEbytes -= clen;
                    282: 
                    283:       if (cEbytes == 0)
                    284:        {
                    285:          if (! fgot_data (qdaemon, abPrecbuf, (size_t) 0,
                    286:                           (const char *) NULL, (size_t) 0,
                    287:                           -1, -1, (long) -1, TRUE, pfexit))
                    288:            return FALSE;
                    289:          if (*pfexit)
                    290:            return TRUE;
                    291:        }
                    292: 
                    293:       cinbuf -= clen;
                    294:     }
                    295: 
                    296:   if (pcneed != NULL)
                    297:     {
                    298:       if (cEbytes > CRECBUFLEN / 2)
                    299:        *pcneed = CRECBUFLEN / 2;
                    300:       else
                    301:        *pcneed = (int) cEbytes;
                    302:     }
                    303: 
                    304:   return TRUE;
                    305: }
                    306: 
                    307: /* Wait for data to come in and process it until we've reached the end
                    308:    of a command or a file.  */
                    309: 
                    310: boolean
                    311: fewait (qdaemon)
                    312:      struct sdaemon *qdaemon;
                    313: {
                    314:   while (TRUE)
                    315:     {
                    316:       boolean fexit;
                    317:       size_t cneed, crec;
                    318: 
                    319:       if (! feprocess_data (qdaemon, &fexit, &cneed))
                    320:        return FALSE;
                    321:       if (fexit)
                    322:        return TRUE;
                    323: 
                    324:       if (! freceive_data (qdaemon->qconn, cneed, &crec, cEtimeout, TRUE))
                    325:        return FALSE;
                    326: 
                    327:       if (crec == 0)
                    328:        {
                    329:          ulog (LOG_ERROR, "Timed out waiting for data");
                    330:          return FALSE;
                    331:        }
                    332:     }
                    333: }
                    334: 
                    335: /* File level routine, to handle transferring the amount of data and
                    336:    to set fEfile correctly.  */
                    337: 
                    338: boolean
                    339: fefile (qdaemon, qtrans, fstart, fsend, cbytes, pfhandled)
                    340:      struct sdaemon *qdaemon;
                    341:      struct stransfer *qtrans;
                    342:      boolean fstart;
                    343:      boolean fsend;
                    344:      long cbytes;
                    345:      boolean *pfhandled;
                    346: {
                    347:   *pfhandled = FALSE;
                    348: 
                    349:   if (fstart)
                    350:     {
                    351:       if (fsend)
                    352:        {
                    353:          char ab[CEFRAMELEN];
                    354: 
                    355:          DEBUG_MESSAGE1 (DEBUG_PROTO,
                    356:                          "Protocol 'e' starting to send %ld bytes",
                    357:                          cbytes);
                    358: 
                    359:          bzero (ab, (size_t) CEFRAMELEN);
                    360:          sprintf (ab, "%ld", cbytes);
                    361:          if (! fsend_data (qdaemon->qconn, ab, (size_t) CEFRAMELEN, TRUE))
                    362:            return FALSE;
                    363:          cEbytes = cbytes;
                    364:        }
                    365:       else
                    366:        {
                    367:          cEbytes = -1;
                    368:          fEfile = TRUE;
                    369:        }
                    370:     }
                    371:   else
                    372:     {
                    373:       if (! fsend)
                    374:        fEfile = FALSE;
                    375: #if DEBUG > 0
                    376:       if (cEbytes != 0)
                    377:        {
                    378:          ulog (LOG_ERROR,
                    379:                "Protocol 'e' internal error: %ld bytes left over",
                    380:                cEbytes);
                    381:          return FALSE;
                    382:        }
                    383: #endif
                    384:     }
                    385: 
                    386:   return TRUE;
                    387: }

unix.superglobalmegacorp.com

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