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