Mercurial > pidgin
comparison src/protocols/irc/irc.c @ 2687:2d544f48146d
[gaim-migrate @ 2700]
Anyone up for some fun!
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Wed, 07 Nov 2001 11:14:33 +0000 |
| parents | 37d80035e77f |
| children | f3c094e78609 |
comparison
equal
deleted
inserted
replaced
| 2686:7b21c5446baf | 2687:2d544f48146d |
|---|---|
| 49 | 49 |
| 50 struct irc_data { | 50 struct irc_data { |
| 51 int fd; | 51 int fd; |
| 52 gboolean online; | 52 gboolean online; |
| 53 guint32 timer; | 53 guint32 timer; |
| 54 | |
| 55 char *rxqueue; | |
| 56 int rxlen; | |
| 54 | 57 |
| 55 GString *str; | 58 GString *str; |
| 56 int bc; | 59 int bc; |
| 57 | 60 |
| 58 char *chantypes; | 61 char *chantypes; |
| 773 g_free(tmp); | 776 g_free(tmp); |
| 774 } | 777 } |
| 775 /* XXX should probably write_to_conv or something here */ | 778 /* XXX should probably write_to_conv or something here */ |
| 776 } | 779 } |
| 777 | 780 |
| 778 static void irc_callback(gpointer data, gint source, GaimInputCondition condition) | 781 static gboolean irc_parse(struct gaim_connection *gc, char *buf) |
| 779 { | 782 { |
| 780 struct gaim_connection *gc = data; | |
| 781 struct irc_data *idata = gc->proto_data; | 783 struct irc_data *idata = gc->proto_data; |
| 782 int i = 0; | |
| 783 gchar d[IRC_BUF_LEN], *buf = d; | |
| 784 gchar outbuf[IRC_BUF_LEN]; | 784 gchar outbuf[IRC_BUF_LEN]; |
| 785 char *word[PDIWORDS], *word_eol[PDIWORDS]; | 785 char *word[PDIWORDS], *word_eol[PDIWORDS]; |
| 786 char pdibuf[522]; | 786 char pdibuf[522]; |
| 787 char *ex, ip[128], nick[128]; | 787 char *ex, ip[128], nick[128]; |
| 788 char *cmd; | 788 char *cmd; |
| 789 | 789 |
| 790 if (!idata->online) { | |
| 791 /* Now lets sign ourselves on */ | |
| 792 account_online(gc); | |
| 793 serv_finish_login(gc); | |
| 794 | |
| 795 if (bud_list_cache_exists(gc)) | |
| 796 do_import(gc, NULL); | |
| 797 | |
| 798 /* we don't call this now because otherwise some IRC servers might not like us */ | |
| 799 idata->timer = g_timeout_add(20000, irc_request_buddy_update, gc); | |
| 800 idata->online = TRUE; | |
| 801 } | |
| 802 | |
| 803 do { | |
| 804 if (read(idata->fd, buf + i, 1) <= 0) { | |
| 805 hide_login_progress(gc, "Read error"); | |
| 806 signoff(gc); | |
| 807 return; | |
| 808 } | |
| 809 } while (buf[i++] != '\n'); | |
| 810 | |
| 811 buf[--i] = '\0'; | |
| 812 g_strchomp(buf); | |
| 813 debug_printf("IRC S: %s\n", buf); | |
| 814 | |
| 815 /* Check for errors */ | 790 /* Check for errors */ |
| 816 | 791 |
| 817 if (*buf != ':') { | 792 if (*buf != ':') { |
| 818 if (!strncmp(buf, "NOTICE ", 7)) | 793 if (!strncmp(buf, "NOTICE ", 7)) |
| 819 buf += 7; | 794 buf += 7; |
| 820 if (!strncmp(buf, "PING ", 5)) { | 795 if (!strncmp(buf, "PING ", 5)) { |
| 796 int r = FALSE; | |
| 821 g_snprintf(outbuf, sizeof(outbuf), "PONG %s\r\n", buf + 5); | 797 g_snprintf(outbuf, sizeof(outbuf), "PONG %s\r\n", buf + 5); |
| 822 if (irc_write(idata->fd, outbuf, strlen(outbuf)) < 0) { | 798 if (irc_write(idata->fd, outbuf, strlen(outbuf)) < 0) { |
| 823 hide_login_progress(gc, _("Unable to write")); | 799 hide_login_progress(gc, _("Unable to write")); |
| 824 signoff(gc); | 800 signoff(gc); |
| 801 r = TRUE; | |
| 825 } | 802 } |
| 826 return; | 803 return r; |
| 827 } | 804 } |
| 828 /* XXX doesn't handle ERROR */ | 805 /* XXX doesn't handle ERROR */ |
| 829 return; | 806 return FALSE; |
| 830 } | 807 } |
| 831 | 808 |
| 832 buf++; | 809 buf++; |
| 833 | 810 |
| 834 process_data_init(pdibuf, buf, word, word_eol, FALSE); | 811 process_data_init(pdibuf, buf, word, word_eol, FALSE); |
| 835 | 812 |
| 836 if (atoi(word[2])) { | 813 if (atoi(word[2])) { |
| 837 if (*word_eol[3]) | 814 if (*word_eol[3]) |
| 838 process_numeric(gc, word, word_eol); | 815 process_numeric(gc, word, word_eol); |
| 839 return; | 816 return FALSE; |
| 840 } | 817 } |
| 841 | 818 |
| 842 cmd = word[2]; | 819 cmd = word[2]; |
| 843 | 820 |
| 844 ex = strchr(pdibuf, '!'); | 821 ex = strchr(pdibuf, '!'); |
| 854 nick[sizeof(nick)-1] = 0; | 831 nick[sizeof(nick)-1] = 0; |
| 855 if ((ex - pdibuf) < sizeof (nick)) | 832 if ((ex - pdibuf) < sizeof (nick)) |
| 856 nick[ex - pdibuf] = 0; /* cut the buffer at the '!' */ | 833 nick[ex - pdibuf] = 0; /* cut the buffer at the '!' */ |
| 857 } | 834 } |
| 858 | 835 |
| 859 if (!strcmp(cmd, "INVITE")) { /* */ | 836 if (!strcmp(cmd, "INVITE")) { /* */ |
| 860 } else if (!strcmp(cmd, "JOIN")) { | 837 } else if (!strcmp(cmd, "JOIN")) { |
| 861 char *chan = *word[3] == ':' ? word[3] + 1 : word[3]; | 838 char *chan = *word[3] == ':' ? word[3] + 1 : word[3]; |
| 862 if (!g_strcasecmp(gc->displayname, nick)) { | 839 if (!g_strcasecmp(gc->displayname, nick)) { |
| 863 static int id = 1; | 840 static int id = 1; |
| 864 serv_got_joined_chat(gc, id++, chan); | 841 serv_got_joined_chat(gc, id++, chan); |
| 869 } | 846 } |
| 870 } else if (!strcmp(cmd, "KICK")) { | 847 } else if (!strcmp(cmd, "KICK")) { |
| 871 if (!strcmp(gc->displayname, word[4])) { | 848 if (!strcmp(gc->displayname, word[4])) { |
| 872 struct conversation *c = irc_find_chat(gc, word[3]); | 849 struct conversation *c = irc_find_chat(gc, word[3]); |
| 873 if (!c) | 850 if (!c) |
| 874 return; | 851 return FALSE; |
| 875 gc->buddy_chats = g_slist_remove(gc->buddy_chats, c); | 852 gc->buddy_chats = g_slist_remove(gc->buddy_chats, c); |
| 876 c->gc = NULL; | 853 c->gc = NULL; |
| 877 g_snprintf(outbuf, sizeof(outbuf), _("You have been kicked from %s: %s"), | 854 g_snprintf(outbuf, sizeof(outbuf), _("You have been kicked from %s: %s"), |
| 878 word[3], *word_eol[5] == ':' ? word_eol[5] + 1: word_eol[5]); | 855 word[3], *word_eol[5] == ':' ? word_eol[5] + 1: word_eol[5]); |
| 879 do_error_dialog(outbuf, _("IRC Error")); | 856 do_error_dialog(outbuf, _("IRC Error")); |
| 896 struct conversation *c; | 873 struct conversation *c; |
| 897 GList *r; | 874 GList *r; |
| 898 if (*chan == ':') | 875 if (*chan == ':') |
| 899 chan++; | 876 chan++; |
| 900 if (!(c = irc_find_chat(gc, chan))) | 877 if (!(c = irc_find_chat(gc, chan))) |
| 901 return; | 878 return FALSE; |
| 902 if (!strcmp(nick, gc->displayname)) { | 879 if (!strcmp(nick, gc->displayname)) { |
| 903 serv_got_chat_left(gc, c->id); | 880 serv_got_chat_left(gc, c->id); |
| 904 return; | 881 return FALSE; |
| 905 } | 882 } |
| 906 r = c->in_room; | 883 r = c->in_room; |
| 907 while (r) { | 884 while (r) { |
| 908 char *who = r->data; | 885 char *who = r->data; |
| 909 if (*who == '@') | 886 if (*who == '@') |
| 919 r = r->next; | 896 r = r->next; |
| 920 } | 897 } |
| 921 } else if (!strcmp(cmd, "PRIVMSG")) { | 898 } else if (!strcmp(cmd, "PRIVMSG")) { |
| 922 char *to, *msg; | 899 char *to, *msg; |
| 923 if (!*word[3]) | 900 if (!*word[3]) |
| 924 return; | 901 return FALSE; |
| 925 to = word[3]; | 902 to = word[3]; |
| 926 msg = *word_eol[4] == ':' ? word_eol[4] + 1 : word_eol[4]; | 903 msg = *word_eol[4] == ':' ? word_eol[4] + 1 : word_eol[4]; |
| 927 if (msg[0] == 1 && msg[strlen (msg) - 1] == 1) { /* ctcp */ | 904 if (msg[0] == 1 && msg[strlen (msg) - 1] == 1) { /* ctcp */ |
| 928 if (!g_strncasecmp(msg + 1, "DCC ", 4)) | 905 if (!g_strncasecmp(msg + 1, "DCC ", 4)) |
| 929 process_data_init(pdibuf, buf, word, word_eol, TRUE); | 906 process_data_init(pdibuf, buf, word, word_eol, TRUE); |
| 944 nick, topic); | 921 nick, topic); |
| 945 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time(NULL)); | 922 write_to_conv(c, buf, WFLAG_SYSTEM, NULL, time(NULL)); |
| 946 } | 923 } |
| 947 } else if (!strcmp(cmd, "WALLOPS")) { /* */ | 924 } else if (!strcmp(cmd, "WALLOPS")) { /* */ |
| 948 } | 925 } |
| 926 | |
| 927 return FALSE; | |
| 928 } | |
| 929 | |
| 930 static void irc_callback(gpointer data, gint source, GaimInputCondition condition) | |
| 931 { | |
| 932 struct gaim_connection *gc = data; | |
| 933 struct irc_data *idata = gc->proto_data; | |
| 934 int i = 0; | |
| 935 gchar buf[1024]; | |
| 936 gboolean off; | |
| 937 | |
| 938 if (!idata->online) { | |
| 939 /* Now lets sign ourselves on */ | |
| 940 account_online(gc); | |
| 941 serv_finish_login(gc); | |
| 942 | |
| 943 if (bud_list_cache_exists(gc)) | |
| 944 do_import(gc, NULL); | |
| 945 | |
| 946 /* we don't call this now because otherwise some IRC servers might not like us */ | |
| 947 idata->timer = g_timeout_add(20000, irc_request_buddy_update, gc); | |
| 948 idata->online = TRUE; | |
| 949 } | |
| 950 | |
| 951 i = read(idata->fd, buf, 1024); | |
| 952 if (i <= 0) { | |
| 953 hide_login_progress(gc, "Read error"); | |
| 954 signoff(gc); | |
| 955 return; | |
| 956 } | |
| 957 | |
| 958 idata->rxqueue = g_realloc(idata->rxqueue, i + idata->rxlen + 1); | |
| 959 memcpy(idata->rxqueue + idata->rxlen, buf, i); | |
| 960 idata->rxlen += i; | |
| 961 idata->rxqueue[idata->rxlen] = 0; | |
| 962 | |
| 963 while (1) { | |
| 964 char *d, *e; | |
| 965 int len; | |
| 966 | |
| 967 if (!idata->rxqueue || ((e = strchr(idata->rxqueue, '\n')) == NULL)) | |
| 968 return; | |
| 969 | |
| 970 len = e - idata->rxqueue + 1; | |
| 971 d = g_strndup(idata->rxqueue, len); | |
| 972 g_strchomp(d); | |
| 973 debug_printf("IRC S: %s\n", d); | |
| 974 | |
| 975 idata->rxlen -= len; | |
| 976 if (idata->rxlen) { | |
| 977 char *tmp = g_strdup(e + 1); | |
| 978 g_free(idata->rxqueue); | |
| 979 idata->rxqueue = tmp; | |
| 980 } else { | |
| 981 g_free(idata->rxqueue); | |
| 982 idata->rxqueue = NULL; | |
| 983 } | |
| 984 | |
| 985 off = irc_parse(gc, d); | |
| 986 | |
| 987 g_free(d); | |
| 988 | |
| 989 if (off) | |
| 990 return; | |
| 991 } | |
| 949 } | 992 } |
| 950 | 993 |
| 951 static void irc_login_callback(gpointer data, gint source, GaimInputCondition condition) | 994 static void irc_login_callback(gpointer data, gint source, GaimInputCondition condition) |
| 952 { | 995 { |
| 953 struct gaim_connection *gc = data; | 996 struct gaim_connection *gc = data; |
| 1026 struct irc_data *idata = (struct irc_data *)gc->proto_data; | 1069 struct irc_data *idata = (struct irc_data *)gc->proto_data; |
| 1027 gchar buf[IRC_BUF_LEN]; | 1070 gchar buf[IRC_BUF_LEN]; |
| 1028 | 1071 |
| 1029 g_snprintf(buf, sizeof(buf), "QUIT :Download Gaim [%s]\r\n", WEBSITE); | 1072 g_snprintf(buf, sizeof(buf), "QUIT :Download Gaim [%s]\r\n", WEBSITE); |
| 1030 irc_write(idata->fd, buf, strlen(buf)); | 1073 irc_write(idata->fd, buf, strlen(buf)); |
| 1074 | |
| 1075 if (idata->rxqueue) | |
| 1076 g_free(idata->rxqueue); | |
| 1077 idata->rxqueue = NULL; | |
| 1078 idata->rxlen = 0; | |
| 1031 | 1079 |
| 1032 g_free(idata->chantypes); | 1080 g_free(idata->chantypes); |
| 1033 g_free(idata->chanmodes); | 1081 g_free(idata->chanmodes); |
| 1034 g_free(idata->nickmodes); | 1082 g_free(idata->nickmodes); |
| 1035 | 1083 |
