Mercurial > hg > nnchat
comparison nnchat.c @ 403:7bec02f382fb
Refactor the connection and protocol handling a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 24 May 2012 05:28:44 +0300 |
parents | 563a70e8a303 |
children | d11a68f214eb |
comparison
equal
deleted
inserted
replaced
402:563a70e8a303 | 403:7bec02f382fb |
---|---|
633 } | 633 } |
634 return FALSE; | 634 return FALSE; |
635 } | 635 } |
636 | 636 |
637 | 637 |
638 int handleUser(nn_conn_t *conn, const char *str) | 638 int nnproto_handle_user(nn_conn_t *conn) |
639 { | 639 { |
640 const char *msg = "</USER><MESSAGE>", *p = str; | 640 static const char *msg = "</USER><MESSAGE>"; |
641 char *p = conn->ptr; | |
641 BOOL isMine, isIgnored = FALSE; | 642 BOOL isMine, isIgnored = FALSE; |
642 char *s, *t, *userName; | 643 char *s, *t, *userName; |
643 | 644 |
644 (void) conn; | |
645 | |
646 /* Find start of the message */ | 645 /* Find start of the message */ |
647 s = strstr(str, msg); | 646 s = strstr(p, msg); |
648 if (!s) return 1; | 647 if (!s) return 1; |
649 *s = 0; | 648 *s = 0; |
650 s += strlen(msg); | 649 s += strlen(msg); |
651 | 650 |
652 /* Find end of the message */ | 651 /* Find end of the message */ |
749 th_free(s); | 748 th_free(s); |
750 th_free(userName); | 749 th_free(userName); |
751 return 0; | 750 return 0; |
752 } | 751 } |
753 | 752 |
753 | |
754 int nnproto_handle_login(nn_conn_t *conn) | |
755 { | |
756 char tmpStr[256]; | |
754 str_get_timestamp(tmpStr, sizeof(tmpStr), "%c"); | 757 str_get_timestamp(tmpStr, sizeof(tmpStr), "%c"); |
755 | 758 |
756 int handleLogin(nn_conn_t *conn, const char *str) | 759 if (!nn_conn_buf_strcmp(conn, "FAILURE>")) |
757 { | |
758 char tmpStr[256]; | |
759 | |
760 getTimeStamp(tmpStr, sizeof(tmpStr), "%c"); | |
761 | |
762 if (!strncmp(str, "FAILURE", 7)) | |
763 { | 760 { |
764 printMsg(NULL, "½1½Login failure½0½ - ½3½%s½0½\n", tmpStr); | 761 printMsg(NULL, "½1½Login failure½0½ - ½3½%s½0½\n", tmpStr); |
765 return -2; | 762 return -2; |
766 } | 763 } |
767 else if (!strncmp(str, "SUCCESS", 7)) | 764 else if (!nn_conn_buf_strcmp(conn, "SUCCESS>")) |
768 { | 765 { |
769 printMsg(NULL, "½2½Login success½0½ - ½3½%s½0½\n", tmpStr); | 766 printMsg(NULL, "½2½Login success½0½ - ½3½%s½0½\n", tmpStr); |
770 nn_conn_send_msg(conn, optUserNameEnc, "%%2FRequestUserList"); | 767 nn_conn_send_msg(conn, optUserNameEnc, "%%2FRequestUserList"); |
771 return 0; | 768 return 0; |
772 } | 769 } |
773 else | 770 else |
774 return 1; | 771 return 1; |
775 } | 772 } |
776 | 773 |
777 | 774 |
778 int handleAddUser(nn_conn_t *conn, const char *str) | 775 int nnproto_handle_add_user(nn_conn_t *conn) |
779 { | 776 { |
780 char *p, *s = strstr(str, "</ADD_USER>"); | 777 char *p, *s, *str = conn->ptr; |
781 nn_window_t *win; | 778 nn_window_t *win; |
782 | 779 |
783 (void) conn; | 780 s = nn_conn_buf_strstr(conn, "</ADD_USER>"); |
784 | |
785 if (!s) return 1; | 781 if (!s) return 1; |
786 *s = 0; | 782 *s = 0; |
787 | 783 |
788 p = nn_dbldecode_str(str); | 784 p = nn_dbldecode_str(str); |
789 if (!p) return -1; | 785 if (!p) return -1; |
798 th_free(p); | 794 th_free(p); |
799 return 0; | 795 return 0; |
800 } | 796 } |
801 | 797 |
802 | 798 |
803 int handleDeleteUser(nn_conn_t *conn, const char *str) | 799 int nnproto_handle_delete_user(nn_conn_t *conn) |
804 { | 800 { |
805 char *p, *s = strstr(str, "</DELETE_USER>"); | 801 char *p, *s, *str = conn->ptr; |
806 nn_window_t *win; | 802 nn_window_t *win; |
807 | 803 |
808 (void) conn; | 804 s = nn_conn_buf_strstr(conn, "</DELETE_USER>"); |
809 | |
810 if (!s) return 1; | 805 if (!s) return 1; |
811 *s = 0; | 806 *s = 0; |
812 | 807 |
813 p = nn_dbldecode_str(str); | 808 p = nn_dbldecode_str(str); |
814 if (!p) return -1; | 809 if (!p) return -1; |
823 th_free(p); | 818 th_free(p); |
824 return 0; | 819 return 0; |
825 } | 820 } |
826 | 821 |
827 | 822 |
828 int handleFoo(nn_conn_t *conn, const char *str) | 823 int nnproto_handle_num_clients(nn_conn_t *conn) |
824 { | |
825 nn_conn_buf_strstr(conn, "</NUMCLIENTS>"); | |
826 return 0; | |
827 } | |
828 | |
829 | |
830 int nnproto_handle_boot(nn_conn_t *conn) | |
829 { | 831 { |
830 (void) conn; | 832 (void) conn; |
831 (void) str; | |
832 | |
833 return 0; | |
834 } | |
835 | |
836 | |
837 int handleBoot(nn_conn_t *conn, const char *str) | |
838 { | |
839 (void) conn; | |
840 (void) str; | |
841 errorMsg("Booted by server.\n"); | 833 errorMsg("Booted by server.\n"); |
842 return -1; | 834 return -1; |
843 } | 835 } |
844 | 836 |
845 | 837 |
846 typedef struct | 838 typedef struct |
847 { | 839 { |
848 char *cmd; | 840 char *cmd; |
849 ssize_t len; | 841 ssize_t len; |
850 int (*handler)(nn_conn_t *, const char *); | 842 int (*handler)(nn_conn_t *); |
851 } protocmd_t; | 843 } nn_protocolcmd_t; |
852 | 844 |
853 | 845 |
854 static protocmd_t protoCmds[] = | 846 static nn_protocolcmd_t protoCmds[] = |
855 { | 847 { |
856 { "<USER>", -1, handleUser }, | 848 { "<USER>", -1, nnproto_handle_user }, |
857 { "<LOGIN_", -1, handleLogin }, | 849 { "<LOGIN_", -1, nnproto_handle_login }, |
858 { "<DELETE_USER>", -1, handleDeleteUser }, | 850 { "<DELETE_USER>", -1, nnproto_handle_delete_user }, |
859 { "<ADD_USER>", -1, handleAddUser }, | 851 { "<ADD_USER>", -1, nnproto_handle_add_user }, |
860 { "<NUMCLIENTS>", -1, handleFoo }, | 852 { "<NUMCLIENTS>", -1, nnproto_handle_num_clients }, |
861 { "<BOOT />", -1, handleBoot }, | 853 { "<BOOT />", -1, nnproto_handle_boot }, |
862 }; | 854 }; |
863 | 855 |
864 static const int nprotoCmds = sizeof(protoCmds) / sizeof(protoCmds[0]); | 856 static const int nprotoCmds = sizeof(protoCmds) / sizeof(protoCmds[0]); |
865 | 857 |
866 | 858 |
867 int handleProtocol(nn_conn_t *conn, const char *buf, const ssize_t bufLen) | 859 int nn_parse_protocol(nn_conn_t *conn) |
868 { | 860 { |
869 static BOOL protoCmdsInit = FALSE; | 861 static BOOL protoCmdsInit = FALSE; |
870 int i; | 862 int i; |
871 | 863 |
872 if (!protoCmdsInit) | 864 if (!protoCmdsInit) |
873 { | 865 { |
874 for (i = 0; i < nprotoCmds; i++) | 866 for (i = 0; i < nprotoCmds; i++) |
875 protoCmds[i].len = strlen(protoCmds[i].cmd); | 867 protoCmds[i].len = strlen(protoCmds[i].cmd); |
868 | |
876 protoCmdsInit = TRUE; | 869 protoCmdsInit = TRUE; |
877 } | 870 } |
878 | 871 |
879 for (i = 0; i < nprotoCmds; i++) | 872 for (i = 0; i < nprotoCmds; i++) |
880 { | 873 { |
881 ssize_t cmdLen = protoCmds[i].len; | 874 if (!nn_conn_buf_strncmp(conn, protoCmds[i].cmd, protoCmds[i].len)) |
882 if (cmdLen < bufLen && !strncmp(buf, protoCmds[i].cmd, cmdLen)) | 875 return protoCmds[i].handler(conn); |
883 return protoCmds[i].handler(conn, buf + cmdLen); | |
884 } | 876 } |
885 | 877 |
886 if (optDebug) | 878 if (optDebug) |
887 { | 879 { |
888 printMsg(NULL, "Unknown protocmd: \"%s\"\n", buf); | 880 printMsg(NULL, "Unknown protocmd: \"%s\"\n", conn->ptr); |
889 return 0; | 881 return 0; |
890 } | 882 } |
891 else | 883 else |
892 return 1; | 884 return 1; |
893 } | 885 } |
1702 | 1694 |
1703 /* Enter mainloop */ | 1695 /* Enter mainloop */ |
1704 nn_conn_reset(conn); | 1696 nn_conn_reset(conn); |
1705 while (!isError && !exitProg) | 1697 while (!isError && !exitProg) |
1706 { | 1698 { |
1707 int cres = nn_conn_pull(conn); | 1699 nn_conn_reset(conn); |
1708 if (cres == 0 && *(conn->ptr - 1) == 0) | 1700 do { |
1709 { | 1701 int cres = nn_conn_pull(conn); |
1710 char *ptr = conn->buf; | 1702 if (cres == 0 && *(conn->in_ptr - 1) == 0) |
1711 do | 1703 { |
1712 { | 1704 int result = nn_parse_protocol(conn); |
1713 size_t bufLen = strlen(ptr) + 1; | |
1714 int result = handleProtocol(conn, ptr, bufLen); | |
1715 | |
1716 if (result > 0) | 1705 if (result > 0) |
1717 { | 1706 { |
1718 /* Couldn't handle the message for some reason */ | 1707 /* Couldn't handle the message for some reason */ |
1719 printMsg(currWin, "Could not handle: %s\n", ptr); | 1708 printMsg(currWin, "Could not handle: %s\n", conn->ptr); |
1720 } | 1709 } |
1721 else if (result < 0) | 1710 else if (result < 0) |
1722 { | 1711 { |
1723 /* Fatal error, quit */ | 1712 /* Fatal error, quit */ |
1724 errorMsg("Fatal error with message: %s\n", ptr); | 1713 errorMsg("Fatal error with message: %s\n", conn->ptr); |
1725 isError = TRUE; | 1714 isError = TRUE; |
1726 } | 1715 } |
1727 | 1716 } |
1728 conn->total -= bufLen; | 1717 } |
1729 ptr += bufLen; | 1718 while (conn->total_bytes > 0 && !isError); |
1730 } | 1719 |
1731 while (conn->total > 0 && !isError); | |
1732 nn_conn_reset(conn); | |
1733 } | |
1734 if (!nn_conn_check(conn)) | 1720 if (!nn_conn_check(conn)) |
1735 isError = TRUE; | 1721 isError = TRUE; |
1736 | 1722 |
1737 /* Handle user input */ | 1723 /* Handle user input */ |
1738 if (cursesInit) | 1724 if (cursesInit) |