summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xvchat-protocol.c93
1 files changed, 38 insertions, 55 deletions
diff --git a/vchat-protocol.c b/vchat-protocol.c
index b7d654e..0451b77 100755
--- a/vchat-protocol.c
+++ b/vchat-protocol.c
@@ -692,76 +692,59 @@ parsemsg (char *message)
692} 692}
693 693
694/* offset in buffer (for linebreaks at packet borders) */ 694/* offset in buffer (for linebreaks at packet borders) */
695static int bufoff = 0; 695#define BUFSIZE 4096
696static char _buf[BUFSIZE];
697static size_t _buf_fill;
696 698
697/* get data from servers filedescriptor */ 699/* get data from servers filedescriptor */
698void 700void
699networkinput (void) 701networkinput (void)
700{ 702{
701 int bytes; 703 char *endmsg;
702 char *tmp = NULL; 704 size_t freebytes = BUFSIZE - _buf_fill;
703#define BUFSIZE 4096 705 ssize_t bytes = vc_receivemessage(&_buf[_buf_fill], freebytes);
704 char buf[BUFSIZE]; /* data buffer */
705 char *ltmp = buf;
706 buf[BUFSIZE-1] = '\0'; /* sanity stop */
707 706
708 /* receive data at offset */ 707 /* Our tls functions may require retries with handshakes etc, this is signalled by -2 */
709 bytes = vc_receivemessage(&buf[bufoff], BUFSIZE-1 - bufoff); 708 if (bytes == -2)
709 return;
710 710
711 /* no bytes transferred? raise error message, bail out */ 711 /* Error on the socket read? raise error message, bail out */
712 if (bytes < 0) 712 if (bytes == -1) {
713 {
714 snprintf (tmpstr, TMPSTRSIZE, "Receive fails, %s.", strerror(errno)); 713 snprintf (tmpstr, TMPSTRSIZE, "Receive fails, %s.", strerror(errno));
715 strncpy(errstr,tmpstr,TMPSTRSIZE-2); 714 snprintf (errstr, ERRSTRSIZE, "Receive fails, %s.\n", strerror(errno));
716 errstr[TMPSTRSIZE-2] = '\0';
717 strcat(errstr,"\n");
718 writecf (FS_ERR,tmpstr); 715 writecf (FS_ERR,tmpstr);
719 status = 0; 716 status = 0;
720 } 717 return;
718 }
719
721 /* end of file from server? */ 720 /* end of file from server? */
722 else if (bytes == 0) 721 if (bytes == 0) {
723 {
724 /* inform user, bail out */ 722 /* inform user, bail out */
725 writecf (FS_SERV,"* EOF from server"); 723 writecf (FS_SERV, "* EOF from server.");
726 strncpy(errstr,"* EOF from server",TMPSTRSIZE-2); 724 snprintf (errstr, ERRSTRSIZE, "* EOF from server.\n");
727 errstr[TMPSTRSIZE-2] = '\0';
728 strcat(errstr,"\n");
729 status = 0; 725 status = 0;
730 } 726 return;
731 else 727 }
732 { 728
733 /* terminate message */ 729 _buf_fill += bytes;
734 buf[bytes + bufoff] = '\0'; 730
735 /* as long as there are lines .. */ 731 /* as long as there are lines .. */
736 while ((tmp = strchr (ltmp, '\n')) != NULL) 732 while ((endmsg = memchr(_buf, '\n', _buf_fill)) != NULL) {
737 { 733 if (endmsg > _buf) {
738 /* did the server send CR+LF instead of LF with the last line? */ 734 /* Zero terminate message, optionally chomp CR */
739 if (tmp[-1] == '\r') 735 endmsg[0] = 0;
740 tmp[-1] = '\0'; 736 if (endmsg[-1] == '\r')
741 737 endmsg[-1] = 0;
742 /* remove newline from previous message, advance pointer of next 738 /* If terminating and chomping left us with a message, give it to line handler */
743 * message */ 739 if (_buf[0]) {
744 tmp[0] = '\0';
745 tmp++;
746
747 /* we have a last message? give away to line handler! */
748 if (ltmp[0])
749 {
750#ifdef DEBUG 740#ifdef DEBUG
751 /* debugging? log network input! */ 741 /* debugging? log network input! */
752 fprintf (stderr, "<| %s\n", ltmp); 742 fprintf (stderr, "<| %s\n", _buf);
753#endif 743#endif
754 parsemsg (ltmp); 744 parsemsg (_buf);
755 }
756
757 /* move line along .. */
758 ltmp = tmp;
759 } 745 }
760 /* buffer exhausted, move partial line to start of buffer and go on .. */
761 bufoff = (bytes+bufoff) - (ltmp-buf);
762 if (bufoff > 0)
763 memmove (buf, ltmp, bufoff);
764 else
765 bufoff = 0;
766 } 746 }
747 _buf_fill -= 1 + endmsg - _buf;
748 memmove(_buf, endmsg + 1, _buf_fill);
749 }
767} 750}