home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / prot.c < prev    next >
C/C++ Source or Header  |  1995-08-20  |  7KB  |  242 lines

  1. /* prot.c
  2.    Protocol support routines to move commands and data around.
  3.  
  4.    Copyright (C) 1991, 1992, 1994 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #if USE_RCS_ID
  29. const char prot_rcsid[] = "$Id: prot.c,v 1.32 1995/06/21 19:15:07 ian Rel $";
  30. #endif
  31.  
  32. #include <errno.h>
  33.  
  34. #include "uudefs.h"
  35. #include "uuconf.h"
  36. #include "system.h"
  37. #include "conn.h"
  38. #include "prot.h"
  39.  
  40. /* Variables visible to the protocol-specific routines.  */
  41.  
  42. /* Buffer to hold received data.  */
  43. char abPrecbuf[CRECBUFLEN];
  44.  
  45. /* Index of start of data in abPrecbuf.  */
  46. int iPrecstart;
  47.  
  48. /* Index of end of data (first byte not included in data) in abPrecbuf.  */
  49. int iPrecend;
  50.  
  51. /* We want to output and input at the same time, if supported on this
  52.    machine.  If we have something to send, we send it all while
  53.    accepting a large amount of data.  Once we have sent everything we
  54.    look at whatever we have received.  If data comes in faster than we
  55.    can send it, we may run out of buffer space.  */
  56.  
  57. boolean
  58. fsend_data (qconn, zsend, csend, fdoread)
  59.      struct sconnection *qconn;
  60.      const char *zsend;
  61.      size_t csend;
  62.      boolean fdoread;
  63. {
  64.   if (! fdoread)
  65.     return fconn_write (qconn, zsend, csend);
  66.  
  67.   while (csend > 0)
  68.     {
  69.       size_t crec, csent;
  70.  
  71.       if (iPrecend < iPrecstart)
  72.     crec = iPrecstart - iPrecend - 1;
  73.       else
  74.     {
  75.       crec = CRECBUFLEN - iPrecend;
  76.       if (iPrecstart == 0)
  77.         --crec;
  78.     }
  79.  
  80.       if (crec == 0)
  81.     return fconn_write (qconn, zsend, csend);
  82.  
  83.       csent = csend;
  84.  
  85.       if (! fconn_io (qconn, zsend, &csent, abPrecbuf + iPrecend, &crec))
  86.     return FALSE;
  87.  
  88.       csend -= csent;
  89.       zsend += csent;
  90.  
  91.       iPrecend = (iPrecend + crec) % CRECBUFLEN;
  92.     }
  93.  
  94.   return TRUE;
  95. }
  96.  
  97. /* Read data from the other system when we have nothing to send.  The
  98.    argument cneed is the amount of data the caller wants, and ctimeout
  99.    is the timeout in seconds.  The function sets *pcrec to the amount
  100.    of data which was actually received, which may be less than cneed
  101.    if there isn't enough room in the receive buffer.  If no data is
  102.    received before the timeout expires, *pcrec will be returned as 0.
  103.    If an error occurs, the function returns FALSE.  If the freport
  104.    argument is FALSE, no error should be reported.  */
  105.  
  106. boolean
  107. freceive_data (qconn, cneed, pcrec, ctimeout, freport)
  108.      struct sconnection *qconn;
  109.      size_t cneed;
  110.      size_t *pcrec;
  111.      int ctimeout;
  112.      boolean freport;
  113. {
  114.   /* Set *pcrec to the maximum amount of data we can read.  fconn_read
  115.      expects *pcrec to be the buffer size, and sets it to the amount
  116.      actually received.  */
  117.   if (iPrecend < iPrecstart)
  118.     *pcrec = iPrecstart - iPrecend - 1;
  119.   else
  120.     {
  121.       *pcrec = CRECBUFLEN - iPrecend;
  122.       if (iPrecstart == 0)
  123.     --(*pcrec);
  124.     }
  125.  
  126. #if DEBUG > 0
  127.   /* If we have no room in the buffer, we're in trouble.  The
  128.      protocols must be written to ensure that this can't happen.  */
  129.   if (*pcrec == 0)
  130.     ulog (LOG_FATAL, "freceive_data: No room in buffer");
  131. #endif
  132.  
  133.   /* If we don't have room for all the data the caller wants, we
  134.      simply have to expect less.  We'll get the rest later.  */
  135.   if (*pcrec < cneed)
  136.     cneed = *pcrec;
  137.  
  138.   if (! fconn_read (qconn, abPrecbuf + iPrecend, pcrec, cneed, ctimeout,
  139.             freport))
  140.     return FALSE;
  141.  
  142.   iPrecend = (iPrecend + *pcrec) % CRECBUFLEN;
  143.  
  144.   return TRUE;
  145. }
  146.  
  147. /* Read a single character.  Get it out of the receive buffer if it's
  148.    there, otherwise ask freceive_data for at least one character.
  149.    This is used because as a protocol is shutting down freceive_data
  150.    may read ahead and eat characters that should be read outside the
  151.    protocol routines.  We call freceive_data rather than fconn_read
  152.    with an argument of 1 so that we can get all the available data in
  153.    a single system call.  The ctimeout argument is the timeout in
  154.    seconds; the freport argument is FALSE if no error should be
  155.    reported.  This returns a character, or -1 on timeout or -2 on
  156.    error.  */
  157.  
  158. int
  159. breceive_char (qconn, ctimeout, freport)
  160.      struct sconnection *qconn;
  161.      int ctimeout;
  162.      boolean freport;
  163. {
  164.   char b;
  165.  
  166.   if (iPrecstart == iPrecend)
  167.     {
  168.       size_t crec;
  169.  
  170.       if (! freceive_data (qconn, sizeof (char), &crec, ctimeout, freport))
  171.     return -2;
  172.       if (crec == 0)
  173.     return -1;
  174.     }
  175.  
  176.   b = abPrecbuf[iPrecstart];
  177.   iPrecstart = (iPrecstart + 1) % CRECBUFLEN;
  178.   return BUCHAR (b);
  179. }
  180.  
  181. /* Send mail about a file transfer.  We send to the given mailing
  182.    address if there is one, otherwise to the user.  */
  183.  
  184. boolean
  185. fmail_transfer (fsuccess, zuser, zmail, zwhy, zfromfile, zfromsys,
  186.         ztofile, ztosys, zsaved)
  187.      boolean fsuccess;
  188.      const char *zuser;
  189.      const char *zmail;
  190.      const char *zwhy;
  191.      const char *zfromfile;
  192.      const char *zfromsys;
  193.      const char *ztofile;
  194.      const char *ztosys;
  195.      const char *zsaved;
  196. {
  197.   const char *zsendto;
  198.   const char *az[20];
  199.   int i;
  200.  
  201.   if (zmail != NULL && *zmail != '\0')
  202.     zsendto = zmail;
  203.   else
  204.     zsendto = zuser;
  205.  
  206.   i = 0;
  207.   az[i++] = "The file\n\t";
  208.   if (zfromsys != NULL)
  209.     {
  210.       az[i++] = zfromsys;
  211.       az[i++] = "!";
  212.     }
  213.   az[i++] = zfromfile;
  214.   if (fsuccess)
  215.     az[i++] = "\nwas successfully transferred to\n\t";
  216.   else
  217.     az[i++] = "\ncould not be transferred to\n\t";
  218.   if (ztosys != NULL)
  219.     {
  220.       az[i++] = ztosys;
  221.       az[i++] = "!";
  222.     }
  223.   az[i++] = ztofile;
  224.   az[i++] = "\nas requested by\n\t";
  225.   az[i++] = zuser;
  226.   if (! fsuccess)
  227.     {
  228.       az[i++] = "\nfor the following reason:\n\t";
  229.       az[i++] = zwhy;
  230.       az[i++] = "\n";
  231.     }
  232.   if (zsaved != NULL)
  233.     {
  234.       az[i++] = zsaved;
  235.       az[i++] = "\n";
  236.     }
  237.  
  238.   return fsysdep_mail (zsendto,
  239.                fsuccess ? "UUCP succeeded" : "UUCP failed",
  240.                i, az);
  241. }
  242.