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