netstr.c
上传用户:ig0539
上传日期:2022-05-21
资源大小:181k
文件大小:3k
源码类别:

Ftp客户端

开发平台:

C/C++

  1. /*
  2.  * Part of Very Secure FTPd
  3.  * Licence: GPL v2
  4.  * Author: Chris Evans
  5.  * netstr.c
  6.  *
  7.  * The netstr interface extends the standard string interface, adding
  8.  * functions which can cope safely with building strings from the network,
  9.  * and send them out too.
  10.  */
  11. #include "netstr.h"
  12. #include "str.h"
  13. #include "sysstr.h"
  14. #include "utility.h"
  15. #include "sysutil.h"
  16. int
  17. str_netfd_alloc(struct vsf_session* p_sess,
  18.                 struct mystr* p_str,
  19.                 char term,
  20.                 char* p_readbuf,
  21.                 unsigned int maxlen,
  22.                 str_netfd_read_t p_peekfunc,
  23.                 str_netfd_read_t p_readfunc)
  24. {
  25.   int retval;
  26.   unsigned int bytes_read;
  27.   unsigned int i;
  28.   char* p_readpos = p_readbuf;
  29.   unsigned int left = maxlen;
  30.   while (1)
  31.   {
  32.     if (p_readpos + left != p_readbuf + maxlen)
  33.     {
  34.       bug("poor buffer accounting in str_netfd_alloc");
  35.     }
  36.     /* Did we hit the max? */
  37.     if (left == 0)
  38.     {
  39.       str_empty(p_str);
  40.       return -1;
  41.     }
  42.     retval = (*p_peekfunc)(p_sess, p_readpos, left);
  43.     if (vsf_sysutil_retval_is_error(retval))
  44.     {
  45.       die("vsf_sysutil_recv_peek");
  46.     }
  47.     else if (retval == 0)
  48.     {
  49.       die("vsf_sysutil_recv_peek: no data");
  50.     }
  51.     bytes_read = (unsigned int) retval;
  52.     /* Search for the terminator */
  53.     for (i=0; i < bytes_read; i++)
  54.     {
  55.       if (p_readpos[i] == term)
  56.       {
  57.         /* Got it! */
  58.         retval = (*p_readfunc)(p_sess, p_readpos, i + 1);
  59.         if (vsf_sysutil_retval_is_error(retval) ||
  60.             (unsigned int) retval != i + 1)
  61.         {
  62.           die("vsf_sysutil_read_loop");
  63.         }
  64.         if (p_readpos[i] != term)
  65.         {
  66.           die("missing terminator in str_netfd_alloc");
  67.         }
  68.         str_alloc_alt_term(p_str, p_readbuf, term);
  69.         return (int) i;
  70.       }
  71.     }
  72.     /* Not found in this read chunk, so consume the data and re-loop */
  73.     if (bytes_read > left)
  74.     {
  75.       bug("bytes_read > left in str_netfd_alloc");
  76.     }
  77.     left -= bytes_read;
  78.     retval = (*p_readfunc)(p_sess, p_readpos, bytes_read);
  79.     if (vsf_sysutil_retval_is_error(retval) ||
  80.         (unsigned int) retval != bytes_read)
  81.     {
  82.       die("vsf_sysutil_read_loop");
  83.     }
  84.     p_readpos += bytes_read;
  85.   } /* END: while(1) */
  86. }
  87. int
  88. str_netfd_write(const struct mystr* p_str, int fd)
  89. {
  90.   int ret = 0;
  91.   int retval;
  92.   unsigned int str_len = str_getlen(p_str);
  93.   if (str_len == 0)
  94.   {
  95.     bug("zero str_len in str_netfd_write");
  96.   }
  97.   retval = str_write_loop(p_str, fd);
  98.   if (vsf_sysutil_retval_is_error(retval) || (unsigned int) retval != str_len)
  99.   {
  100.     ret = -1;
  101.   }
  102.   return ret;
  103. }
  104. int
  105. str_netfd_read(struct mystr* p_str, int fd, unsigned int len)
  106. {
  107.   int retval;
  108.   str_reserve(p_str, len);
  109.   str_trunc(p_str, len);
  110.   retval = str_read_loop(p_str, fd);
  111.   if (vsf_sysutil_retval_is_error(retval) || (unsigned int) retval != len)
  112.   {
  113.     return -1;
  114.   }
  115.   return retval;
  116. }