summaryrefslogtreecommitdiff
path: root/vchat-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'vchat-connection.c')
-rw-r--r--vchat-connection.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/vchat-connection.c b/vchat-connection.c
index 6b38168..06ea187 100644
--- a/vchat-connection.c
+++ b/vchat-connection.c
@@ -35,6 +35,10 @@
35static int serverfd = -1; 35static int serverfd = -1;
36unsigned int want_tcp_keepalive = 0; 36unsigned int want_tcp_keepalive = 0;
37 37
38/* TODO: NEEDS TO GO. status-variable from vchat-client.c
39 * eventloop is done as long as this is true */
40extern int status;
41
38/* Generic tcp connector, blocking */ 42/* Generic tcp connector, blocking */
39static int connect_tcp_socket( const char *server, const char *port ) { 43static int connect_tcp_socket( const char *server, const char *port ) {
40 struct addrinfo hints, *res, *res0; 44 struct addrinfo hints, *res, *res0;
@@ -213,10 +217,65 @@ vc_sendmessage (const char *msg)
213 } 217 }
214} 218}
215 219
216ssize_t 220/* offset in buffer (for linebreaks at packet borders) */
217vc_receivemessage (char *buffer, size_t size) { 221#define BUFSIZE 4096
218 if (getintoption(CF_USESSL)) 222static char _buf[BUFSIZE];
219 return vc_tls_receivemessage (buffer, size); 223static size_t _buf_fill;
224
225/* get data from servers connection */
226void
227vc_receive (void)
228{
229 char *endmsg;
230 size_t freebytes = BUFSIZE - _buf_fill;
231 ssize_t bytes;
232
233 if (!getintoption(CF_USESSL))
234 bytes = read(serverfd, _buf + _buf_fill, freebytes);
220 else 235 else
221 return read(serverfd, buffer, size); 236 bytes = vc_tls_receivemessage(_buf + _buf_fill, freebytes);
237
238 /* Our tls functions may require retries with handshakes etc, this is signalled by -2 */
239 if (bytes == -2)
240 return;
241
242 /* Error on the socket read? raise error message, bail out */
243 if (bytes == -1) {
244 snprintf (tmpstr, TMPSTRSIZE, "Receive fails, %s.", strerror(errno));
245 snprintf (errstr, ERRSTRSIZE, "Receive fails, %s.\n", strerror(errno));
246 writecf (FS_ERR,tmpstr);
247 status = 0;
248 return;
249 }
250
251 /* end of file from server? */
252 if (bytes == 0) {
253 /* inform user, bail out */
254 writecf (FS_SERV, "* EOF from server.");
255 snprintf (errstr, ERRSTRSIZE, "* EOF from server.\n");
256 status = 0;
257 return;
258 }
259
260 _buf_fill += bytes;
261
262 /* as long as there are lines .. */
263 while ((endmsg = memchr(_buf, '\n', _buf_fill)) != NULL) {
264 if (endmsg > _buf) {
265 /* Zero terminate message, optionally chomp CR */
266 endmsg[0] = 0;
267 if (endmsg[-1] == '\r')
268 endmsg[-1] = 0;
269 /* If terminating and chomping left us with a message, give it to line handler */
270 if (_buf[0]) {
271#ifdef DEBUG
272 /* debugging? log network input! */
273 fprintf (stderr, "<| %s\n", _buf);
274#endif
275 protocol_parsemsg (_buf);
276 }
277 }
278 _buf_fill -= 1 + endmsg - _buf;
279 memmove(_buf, endmsg + 1, _buf_fill);
280 }
222} 281}