1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 */ 17/* 18 * Part of Very Secure FTPd 19 * Licence: GPL v2 20 * Author: Chris Evans 21 * netstr.c 22 * 23 * The netstr interface extends the standard string interface, adding 24 * functions which can cope safely with building strings from the network, 25 * and send them out too. 26 */ 27 28#include "netstr.h" 29#include "str.h" 30#include "sysstr.h" 31#include "utility.h" 32#include "sysutil.h" 33 34void 35str_netfd_alloc(struct mystr* p_str, int fd, char term, char* p_readbuf, 36 unsigned int maxlen) 37{ 38 int retval; 39 unsigned int bytes_read; 40 unsigned int i; 41 char* p_readpos = p_readbuf; 42 unsigned int left = maxlen; 43 while (1) 44 { 45 if (p_readpos + left != p_readbuf + maxlen) 46 { 47 bug("poor buffer accounting in str_netfd_alloc"); 48 } 49 /* Did we hit the max? */ 50 if (left == 0) 51 { 52 str_empty(p_str); 53 return; 54 } 55 retval = vsf_sysutil_recv_peek(fd, p_readpos, left); 56 if (vsf_sysutil_retval_is_error(retval)) 57 { 58 die("vsf_sysutil_recv_peek"); 59 } 60 else if (retval == 0) 61 { 62 die("vsf_sysutil_recv_peek: no data"); 63 } 64 bytes_read = (unsigned int) retval; 65 /* Search for the terminator */ 66 for (i=0; i < bytes_read; i++) 67 { 68 if (p_readpos[i] == term) 69 { 70 /* Got it! */ 71 retval = vsf_sysutil_read_loop(fd, p_readpos, i + 1); 72 if (vsf_sysutil_retval_is_error(retval) || 73 (unsigned int) retval != i + 1) 74 { 75 die("vsf_sysutil_read_loop"); 76 } 77 if (p_readpos[i] != term) 78 { 79 die("missing terminator in str_netfd_alloc"); 80 } 81 str_alloc_alt_term(p_str, p_readbuf, term); 82 return; 83 } 84 } 85 /* Not found in this read chunk, so consume the data and re-loop */ 86 if (bytes_read > left) 87 { 88 bug("bytes_read > left in str_netfd_alloc"); 89 } 90 left -= bytes_read; 91 retval = vsf_sysutil_read_loop(fd, p_readpos, bytes_read); 92 if (vsf_sysutil_retval_is_error(retval) || 93 (unsigned int) retval != bytes_read) 94 { 95 die("vsf_sysutil_read_loop"); 96 } 97 p_readpos += bytes_read; 98 } /* END: while(1) */ 99} 100 101int 102str_netfd_write(const struct mystr* p_str, int fd) 103{ 104 int ret = 0; 105 int retval; 106 unsigned int str_len = str_getlen(p_str); 107 if (str_len == 0) 108 { 109 bug("zero str_len in str_netfd_write"); 110 } 111 retval = str_write_loop(p_str, fd); 112 if (vsf_sysutil_retval_is_error(retval) || (unsigned int) retval != str_len) 113 { 114 ret = -1; 115 } 116 return ret; 117} 118 119int 120str_netfd_read(struct mystr* p_str, int fd, unsigned int len) 121{ 122 int retval; 123 str_reserve(p_str, len); 124 str_trunc(p_str, len); 125 retval = str_read_loop(p_str, fd); 126 if (vsf_sysutil_retval_is_error(retval) || (unsigned int) retval != len) 127 { 128 return -1; 129 } 130 return retval; 131} 132 133