home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / ncftp / older_versions / ncftp-3.2.2-src.tar.bz2 / ncftp-3.2.2-src.tar / ncftp-3.2.2 / sio / SReadline.c < prev    next >
C/C++ Source or Header  |  2003-09-01  |  4KB  |  171 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. void
  7. FlushSReadlineInfo(SReadlineInfo *srl)
  8. {
  9.     if (srl == NULL) {
  10.         errno = EINVAL;
  11.         return;
  12.     }
  13.     
  14.     /* Discards any input left in the current buffer,
  15.      * and resets the buffer and its pointer.
  16.      */
  17.     memset(srl->buf, 0, srl->bufSizeMax);
  18.     srl->bufSize = 0;        /* Nothing buffered yet. */
  19.     srl->bufLim = srl->buf + srl->bufSize;
  20.  
  21.     /* This line sets the buffer pointer
  22.      * so that the first thing to do is reset and fill the buffer
  23.      * using real I/O.
  24.      */
  25.     srl->bufPtr = srl->bufLim;
  26. }    /* FlushSReadlineInfo */
  27.  
  28.  
  29.  
  30.  
  31. int
  32. InitSReadlineInfo(SReadlineInfo *srl, int fd, char *buf, size_t bsize, int tlen, int requireEOLN)
  33. {
  34.     if ((srl == NULL) || (fd < 0) || (tlen <= 0)) {
  35.         errno = EINVAL;
  36.         return (-1);
  37.     }
  38.     
  39.     if (buf == NULL) {
  40.         if (bsize < 512)
  41.             bsize = 512;    /* Pointless, otherwise. */
  42.         buf = (char *) malloc(bsize);
  43.         if (buf == NULL)
  44.             return (-1);
  45.         srl->malloc = 1;
  46.     } else {
  47.         srl->malloc = 0;
  48.     }
  49.     memset(buf, 0, bsize);
  50.     srl->buf = buf;
  51.     srl->bufSizeMax = bsize;
  52.     srl->bufSize = 0;            /* Nothing buffered yet. */
  53.     srl->bufLim = srl->buf + srl->bufSize;
  54.     srl->fd = fd;
  55.     srl->timeoutLen = tlen;
  56.     srl->requireEOLN = requireEOLN;
  57.  
  58.     /* This line sets the buffer pointer
  59.      * so that the first thing to do is reset and fill the buffer
  60.      * using real I/O.
  61.      */
  62.     srl->bufPtr = srl->bufLim;
  63.     return (0);
  64. }    /* InitSReadlineInfo */
  65.  
  66.  
  67.  
  68.  
  69. void
  70. DisposeSReadlineInfo(SReadlineInfo *srl)
  71. {
  72.     memset(srl->buf, 0, srl->bufSizeMax);
  73.     if (srl->malloc != 0)
  74.         free(srl->buf);
  75.     memset(srl, 0, sizeof(SReadlineInfo));
  76.  
  77.     /* Note: it does not close(srl->fd). */
  78. }    /* DisposeSReadlineInfo */
  79.  
  80.  
  81.  
  82.  
  83. /* Returns the number of bytes read, including the newline which is
  84.  * also appended to the buffer.  If you don't want that newline,
  85.  * set buf[nread - 1] = '\0', if nread > 0.
  86.  */
  87.  
  88. int 
  89. SReadline(SReadlineInfo *srl, char *const linebuf, size_t linebufsize)
  90. {
  91.     int err;
  92.     char *src;
  93.     char *dst;
  94.     char *dstlim;
  95.     int len;
  96.     int nr;
  97.     int requireEOLN;
  98.     int illegals;
  99.     
  100.     if ((srl == NULL) || (linebuf == NULL) || (linebufsize < 2)) {
  101.         errno = EINVAL;
  102.         return (-1);
  103.     }
  104.  
  105.     illegals = 0;
  106.     err = 0;
  107.     dst = linebuf;
  108.     dstlim = dst + linebufsize - 1;               /* Leave room for NUL. */
  109.     src = srl->bufPtr;
  110.     requireEOLN = srl->requireEOLN;
  111.     
  112.     forever {
  113.         if ((requireEOLN == 0) && (dst >= dstlim))
  114.             break;
  115.         if (src >= srl->bufLim) {
  116.             /* Fill the buffer. */
  117.             if (illegals > 1) {
  118.                 /* Probable DOS -- return now and give you an
  119.                  * opportunity to handle bogus input.
  120.                  */
  121.                 goto done;
  122.             }
  123.             nr = SRead(srl->fd, srl->buf, srl->bufSizeMax, srl->timeoutLen, 0);
  124.             if (nr == 0) {
  125.                 /* EOF. */
  126.                 goto done;
  127.             } else if (nr < 0) {
  128.                 /* Error. */
  129.                 err = nr;
  130.                 goto done;
  131.             }
  132.             srl->bufPtr = src = srl->buf;
  133.             srl->bufLim = srl->buf + nr;
  134.             srl->bufSize = (size_t) nr;
  135.         }
  136.         if (*src == '\0') {
  137.             ++src;
  138.             illegals++;
  139.         } else if (*src == '\r') {
  140.             ++src;
  141.             /* If the next character is a \n that is valid,
  142.              * otherwise treat a stray \r as an illegal character.
  143.              */
  144.             if ((src < srl->bufLim) && (*src != '\n'))
  145.                 illegals++;
  146.         } else {
  147.             if (*src == '\n') {
  148.                 if (dst < dstlim)
  149.                     *dst++ = *src++;
  150.                 else
  151.                     src++;
  152.                 goto done;
  153.             }
  154.             if (dst < dstlim)
  155.                 *dst++ = *src++;
  156.             else
  157.                 src++;
  158.         }
  159.     }
  160.  
  161. done:
  162.     srl->bufPtr = src;
  163.     if ((requireEOLN != 0) && (dst == linebuf) && (illegals > 0))
  164.         *dst++ = '\n';
  165.     *dst = '\0';
  166.     len = (int) (dst - linebuf);
  167.     if (err < 0)
  168.         return (err);
  169.     return (len);
  170. }                               /* SReadline */
  171.