Mercurial > pidgin
comparison src/server.c @ 6982:083d1e4a9c78
[gaim-migrate @ 7538]
This is Mr. Holland's Opus. And by Mr. Holland I mean Robot101. He
rewrote the coreish IM image support so that the binary data gets
ripped out in the prpl and put in an imgstore instead of just being
passed in the same huge as char string as the actual message. This
is good because it's prpl agnostic, or something. It also means
we don't have a silly length of "-1" with pretty much every send or
receive IM function.
It should be crash free, bug free, and memleak free, but additional
testing is always a good thing.
If you like good stuff then you'll love this patch. But don't take
my word for it--ba dun dunt!
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sat, 27 Sep 2003 19:17:21 +0000 |
| parents | 66dd420d3d23 |
| children | 0ffd540660df |
comparison
equal
deleted
inserted
replaced
| 6981:abd3c684da31 | 6982:083d1e4a9c78 |
|---|---|
| 256 } | 256 } |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 | 259 |
| 260 int serv_send_im(GaimConnection *gc, const char *name, const char *message, | 260 int serv_send_im(GaimConnection *gc, const char *name, const char *message, |
| 261 int len, GaimImFlags imflags) | 261 GaimImFlags imflags) |
| 262 { | 262 { |
| 263 GaimConversation *c; | 263 GaimConversation *c; |
| 264 int val = -EINVAL; | 264 int val = -EINVAL; |
| 265 GaimPluginProtocolInfo *prpl_info = NULL; | 265 GaimPluginProtocolInfo *prpl_info = NULL; |
| 266 | 266 |
| 268 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | 268 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
| 269 | 269 |
| 270 c = gaim_find_conversation_with_account(name, gc->account); | 270 c = gaim_find_conversation_with_account(name, gc->account); |
| 271 | 271 |
| 272 if (prpl_info && prpl_info->send_im) | 272 if (prpl_info && prpl_info->send_im) |
| 273 val = prpl_info->send_im(gc, name, message, len, imflags); | 273 val = prpl_info->send_im(gc, name, message, imflags); |
| 274 | 274 |
| 275 if (!(imflags & GAIM_IM_AUTO_RESP)) | 275 if (!(imflags & GAIM_IM_AUTO_RESP)) |
| 276 serv_touch_idle(gc); | 276 serv_touch_idle(gc); |
| 277 | 277 |
| 278 if (gc->away && | 278 if (gc->away && |
| 833 /* | 833 /* |
| 834 * woo. i'm actually going to comment this function. isn't that fun. make | 834 * woo. i'm actually going to comment this function. isn't that fun. make |
| 835 * sure to follow along, kids | 835 * sure to follow along, kids |
| 836 */ | 836 */ |
| 837 void serv_got_im(GaimConnection *gc, const char *who, const char *msg, | 837 void serv_got_im(GaimConnection *gc, const char *who, const char *msg, |
| 838 GaimImFlags imflags, time_t mtime, gint len) | 838 GaimImFlags imflags, time_t mtime) |
| 839 { | 839 { |
| 840 GaimConversation *cnv; | 840 GaimConversation *cnv; |
| 841 GaimMessageFlags auto_resp; | 841 GaimMessageFlags msgflags; |
| 842 char *message, *name; | 842 char *message, *name; |
| 843 char *angel, *buffy; | 843 char *angel, *buffy; |
| 844 int plugin_return; | 844 int plugin_return; |
| 845 | 845 |
| 846 /* | 846 /* |
| 850 cnv = gaim_find_conversation_with_account(who, gc->account); | 850 cnv = gaim_find_conversation_with_account(who, gc->account); |
| 851 | 851 |
| 852 /* | 852 /* |
| 853 * Plugin stuff. we pass a char ** but we don't want to pass what's | 853 * Plugin stuff. we pass a char ** but we don't want to pass what's |
| 854 * been given us by the prpls. So we create temp holders and pass | 854 * been given us by the prpls. So we create temp holders and pass |
| 855 * those instead. It's basically just to avoid segfaults. Of course, | 855 * those instead. It's basically just to avoid segfaults. |
| 856 * if the data is binary, plugins don't see it. Bitch all you want; | |
| 857 * I really don't want you to be dealing with it. | |
| 858 */ | 856 */ |
| 859 if (len < 0) { | 857 buffy = g_malloc(MAX(strlen(msg) + 1, BUF_LONG)); |
| 860 buffy = g_malloc(MAX(strlen(msg) + 1, BUF_LONG)); | 858 strcpy(buffy, msg); |
| 861 strcpy(buffy, msg); | 859 angel = g_strdup(who); |
| 862 angel = g_strdup(who); | 860 |
| 863 | 861 plugin_return = GPOINTER_TO_INT( |
| 864 plugin_return = GPOINTER_TO_INT( | 862 gaim_signal_emit_return_1(gaim_conversations_get_handle(), |
| 865 gaim_signal_emit_return_1(gaim_conversations_get_handle(), | 863 "received-im-msg", gc->account, |
| 866 "received-im-msg", gc->account, | 864 &angel, &buffy, &imflags)); |
| 867 &angel, &buffy, &imflags)); | 865 |
| 868 | 866 if (!buffy || !angel || plugin_return) { |
| 869 if (!buffy || !angel || plugin_return) { | 867 if (buffy) |
| 870 if (buffy) | 868 g_free(buffy); |
| 871 g_free(buffy); | 869 if (angel) |
| 872 if (angel) | 870 g_free(angel); |
| 873 g_free(angel); | 871 return; |
| 874 return; | 872 } |
| 875 } | 873 name = angel; |
| 876 name = angel; | 874 message = buffy; |
| 877 message = buffy; | |
| 878 } else { | |
| 879 name = g_strdup(who); | |
| 880 message = g_memdup(msg, len); | |
| 881 } | |
| 882 | 875 |
| 883 /* | 876 /* |
| 884 * If you can't figure this out, stop reading right now. | 877 * If you can't figure this out, stop reading right now. |
| 885 * "We're not worthy! We're not worthy!" | 878 * "We're not worthy! We're not worthy!" |
| 886 */ | 879 */ |
| 887 if (len < 0 && | 880 if (gaim_prefs_get_bool("/gaim/gtk/conversations/show_urls_as_links")) { |
| 888 gaim_prefs_get_bool("/gaim/gtk/conversations/show_urls_as_links")) { | |
| 889 | |
| 890 buffy = linkify_text(message); | 881 buffy = linkify_text(message); |
| 891 g_free(message); | 882 g_free(message); |
| 892 message = buffy; | 883 message = buffy; |
| 893 } | 884 } |
| 894 | 885 |
| 895 /* | 886 /* |
| 896 * Um. When we call gaim_conversation_write with the message we received, | 887 * Um. When we call gaim_conversation_write with the message we received, |
| 897 * it's nice to pass whether or not it was an auto-response. So if it | 888 * it's nice to pass whether or not it was an auto-response. So if it |
| 898 * was an auto-response, we set the appropriate flag. This is just so | 889 * was an auto-response, we set the appropriate flag. This is just so |
| 899 * prpls don't have to know about GAIM_MESSAGE_* (though some do anyway) | 890 * prpls don't have to know about GAIM_MESSAGE_* (though some do anyway). |
| 891 * We also need to preserve the flag that tells the UI to look for the | |
| 892 * associated images. | |
| 900 */ | 893 */ |
| 894 msgflags = GAIM_MESSAGE_RECV; | |
| 901 if (imflags & GAIM_IM_AUTO_RESP) | 895 if (imflags & GAIM_IM_AUTO_RESP) |
| 902 auto_resp = GAIM_MESSAGE_AUTO_RESP; | 896 msgflags |= GAIM_MESSAGE_AUTO_RESP; |
| 903 else | 897 if (imflags & GAIM_IM_IMAGES) |
| 904 auto_resp = 0; | 898 msgflags |= GAIM_MESSAGE_IMAGES; |
| 905 | 899 |
| 906 /* | 900 /* |
| 907 * Alright. Two cases for how to handle this. Either we're away or | 901 * Alright. Two cases for how to handle this. Either we're away or |
| 908 * we're not. If we're not, then it's easy. If we are, then there | 902 * we're not. If we're not, then it's easy. If we are, then there |
| 909 * are three or four different ways of handling it and different | 903 * are three or four different ways of handling it and different |
| 938 GtkTreeIter iter; | 932 GtkTreeIter iter; |
| 939 gchar path[10]; | 933 gchar path[10]; |
| 940 | 934 |
| 941 qm = g_new0(struct queued_message, 1); | 935 qm = g_new0(struct queued_message, 1); |
| 942 g_snprintf(qm->name, sizeof(qm->name), "%s", name); | 936 g_snprintf(qm->name, sizeof(qm->name), "%s", name); |
| 943 qm->message = g_memdup(message, len == -1 ? strlen(message) + 1 : len); | 937 qm->message = g_strdup(message); |
| 944 qm->account = gc->account; | 938 qm->account = gc->account; |
| 945 qm->tm = mtime; | 939 qm->tm = mtime; |
| 946 qm->flags = GAIM_MESSAGE_RECV | auto_resp; | 940 qm->flags = msgflags; |
| 947 qm->len = len; | |
| 948 message_queue = g_slist_append(message_queue, qm); | 941 message_queue = g_slist_append(message_queue, qm); |
| 949 | 942 |
| 950 row = find_queue_row_by_name(qm->name); | 943 row = find_queue_row_by_name(qm->name); |
| 951 if (row >= 0) { | 944 if (row >= 0) { |
| 952 char number[32]; | 945 char number[32]; |
| 977 * while away), and then write it to the convo window. | 970 * while away), and then write it to the convo window. |
| 978 */ | 971 */ |
| 979 if (cnv == NULL) | 972 if (cnv == NULL) |
| 980 cnv = gaim_conversation_new(GAIM_CONV_IM, gc->account, name); | 973 cnv = gaim_conversation_new(GAIM_CONV_IM, gc->account, name); |
| 981 | 974 |
| 982 gaim_im_write(GAIM_IM(cnv), NULL, message, len, | 975 gaim_im_write(GAIM_IM(cnv), NULL, message, msgflags, mtime); |
| 983 GAIM_MESSAGE_RECV | auto_resp, mtime); | |
| 984 } | 976 } |
| 985 | 977 |
| 986 /* | 978 /* |
| 987 * Regardless of whether we queue it or not, we should send an | 979 * Regardless of whether we queue it or not, we should send an |
| 988 * auto-response. That is, of course, unless the horse.... no wait. | 980 * auto-response. That is, of course, unless the horse.... no wait. |
| 1024 } | 1016 } |
| 1025 lar->sent = t; | 1017 lar->sent = t; |
| 1026 | 1018 |
| 1027 /* apply default fonts and colors */ | 1019 /* apply default fonts and colors */ |
| 1028 tmpmsg = stylize(gc->away, MSG_LEN); | 1020 tmpmsg = stylize(gc->away, MSG_LEN); |
| 1029 serv_send_im(gc, name, away_subs(tmpmsg, alias), -1, GAIM_IM_AUTO_RESP); | 1021 serv_send_im(gc, name, away_subs(tmpmsg, alias), GAIM_IM_AUTO_RESP); |
| 1030 if (!cnv && awayqueue && | 1022 if (!cnv && awayqueue && |
| 1031 gaim_prefs_get_bool("/gaim/gtk/away/queue_messages")) { | 1023 gaim_prefs_get_bool("/gaim/gtk/away/queue_messages")) { |
| 1032 | 1024 |
| 1033 struct queued_message *qm; | 1025 struct queued_message *qm; |
| 1034 | 1026 |
| 1036 g_snprintf(qm->name, sizeof(qm->name), "%s", name); | 1028 g_snprintf(qm->name, sizeof(qm->name), "%s", name); |
| 1037 qm->message = g_strdup(away_subs(tmpmsg, alias)); | 1029 qm->message = g_strdup(away_subs(tmpmsg, alias)); |
| 1038 qm->account = gc->account; | 1030 qm->account = gc->account; |
| 1039 qm->tm = mtime; | 1031 qm->tm = mtime; |
| 1040 qm->flags = GAIM_MESSAGE_SEND | GAIM_MESSAGE_AUTO_RESP; | 1032 qm->flags = GAIM_MESSAGE_SEND | GAIM_MESSAGE_AUTO_RESP; |
| 1041 qm->len = -1; | |
| 1042 message_queue = g_slist_append(message_queue, qm); | 1033 message_queue = g_slist_append(message_queue, qm); |
| 1043 } else if (cnv != NULL) | 1034 } else if (cnv != NULL) |
| 1044 gaim_im_write(GAIM_IM(cnv), NULL, away_subs(tmpmsg, alias), | 1035 gaim_im_write(GAIM_IM(cnv), NULL, away_subs(tmpmsg, alias), |
| 1045 len, GAIM_MESSAGE_SEND | GAIM_MESSAGE_AUTO_RESP, mtime); | 1036 GAIM_MESSAGE_SEND | GAIM_MESSAGE_AUTO_RESP, mtime); |
| 1046 | 1037 |
| 1047 g_free(tmpmsg); | 1038 g_free(tmpmsg); |
| 1048 } else { | 1039 } else { |
| 1049 /* | 1040 /* |
| 1050 * We're not away. This is easy. If the convo window doesn't | 1041 * We're not away. This is easy. If the convo window doesn't |
| 1068 qm = g_new0(struct queued_message, 1); | 1059 qm = g_new0(struct queued_message, 1); |
| 1069 g_snprintf(qm->name, sizeof(qm->name), "%s", name); | 1060 g_snprintf(qm->name, sizeof(qm->name), "%s", name); |
| 1070 qm->message = g_strdup(message); | 1061 qm->message = g_strdup(message); |
| 1071 qm->account = gc->account; | 1062 qm->account = gc->account; |
| 1072 qm->tm = mtime; | 1063 qm->tm = mtime; |
| 1073 qm->flags = GAIM_MESSAGE_RECV | auto_resp; | 1064 qm->flags = msgflags; |
| 1074 qm->len = len; | |
| 1075 unread_message_queue = g_slist_append(unread_message_queue, qm); | 1065 unread_message_queue = g_slist_append(unread_message_queue, qm); |
| 1076 } | 1066 } |
| 1077 else { | 1067 else { |
| 1078 if (cnv == NULL) | 1068 if (cnv == NULL) |
| 1079 cnv = gaim_conversation_new(GAIM_CONV_IM, gc->account, name); | 1069 cnv = gaim_conversation_new(GAIM_CONV_IM, gc->account, name); |
| 1080 | 1070 |
| 1081 gaim_im_write(GAIM_IM(cnv), NULL, message, len, | 1071 gaim_im_write(GAIM_IM(cnv), NULL, message, msgflags, mtime); |
| 1082 GAIM_MESSAGE_RECV | auto_resp, mtime); | |
| 1083 gaim_window_flash(gaim_conversation_get_window(cnv)); | 1072 gaim_window_flash(gaim_conversation_get_window(cnv)); |
| 1084 } | 1073 } |
| 1085 } | 1074 } |
| 1086 | 1075 |
| 1087 g_free(name); | 1076 g_free(name); |
| 1154 if (c != NULL) { | 1143 if (c != NULL) { |
| 1155 | 1144 |
| 1156 char *tmp = g_strdup_printf(_("%s logged in."), | 1145 char *tmp = g_strdup_printf(_("%s logged in."), |
| 1157 gaim_get_buddy_alias(b)); | 1146 gaim_get_buddy_alias(b)); |
| 1158 | 1147 |
| 1159 gaim_conversation_write(c, NULL, tmp, -1, GAIM_MESSAGE_SYSTEM, | 1148 gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, |
| 1160 time(NULL)); | 1149 time(NULL)); |
| 1161 g_free(tmp); | 1150 g_free(tmp); |
| 1162 } | 1151 } |
| 1163 else if (awayqueue && find_queue_total_by_name(b->name)) { | 1152 else if (awayqueue && find_queue_total_by_name(b->name)) { |
| 1164 struct queued_message *qm = g_new0(struct queued_message, 1); | 1153 struct queued_message *qm = g_new0(struct queued_message, 1); |
| 1166 qm->message = g_strdup_printf(_("%s logged in."), | 1155 qm->message = g_strdup_printf(_("%s logged in."), |
| 1167 gaim_get_buddy_alias(b)); | 1156 gaim_get_buddy_alias(b)); |
| 1168 qm->account = gc->account; | 1157 qm->account = gc->account; |
| 1169 qm->tm = time(NULL); | 1158 qm->tm = time(NULL); |
| 1170 qm->flags = GAIM_MESSAGE_SYSTEM; | 1159 qm->flags = GAIM_MESSAGE_SYSTEM; |
| 1171 qm->len = -1; | |
| 1172 message_queue = g_slist_append(message_queue, qm); | 1160 message_queue = g_slist_append(message_queue, qm); |
| 1173 } | 1161 } |
| 1174 } | 1162 } |
| 1175 gaim_sound_play_event(GAIM_SOUND_BUDDY_ARRIVE); | 1163 gaim_sound_play_event(GAIM_SOUND_BUDDY_ARRIVE); |
| 1176 system_log(log_signon, gc, b, OPT_LOG_BUDDY_SIGNON); | 1164 system_log(log_signon, gc, b, OPT_LOG_BUDDY_SIGNON); |
| 1181 if (gaim_prefs_get_bool("/core/conversations/im/show_login")) { | 1169 if (gaim_prefs_get_bool("/core/conversations/im/show_login")) { |
| 1182 if (c != NULL) { | 1170 if (c != NULL) { |
| 1183 | 1171 |
| 1184 char *tmp = g_strdup_printf(_("%s logged out."), | 1172 char *tmp = g_strdup_printf(_("%s logged out."), |
| 1185 gaim_get_buddy_alias(b)); | 1173 gaim_get_buddy_alias(b)); |
| 1186 gaim_conversation_write(c, NULL, tmp, -1, | 1174 gaim_conversation_write(c, NULL, tmp, |
| 1187 GAIM_MESSAGE_SYSTEM, time(NULL)); | 1175 GAIM_MESSAGE_SYSTEM, time(NULL)); |
| 1188 g_free(tmp); | 1176 g_free(tmp); |
| 1189 } else if (awayqueue && find_queue_total_by_name(b->name)) { | 1177 } else if (awayqueue && find_queue_total_by_name(b->name)) { |
| 1190 struct queued_message *qm = g_new0(struct queued_message, 1); | 1178 struct queued_message *qm = g_new0(struct queued_message, 1); |
| 1191 g_snprintf(qm->name, sizeof(qm->name), "%s", b->name); | 1179 g_snprintf(qm->name, sizeof(qm->name), "%s", b->name); |
| 1192 qm->message = g_strdup_printf(_("%s logged out."), | 1180 qm->message = g_strdup_printf(_("%s logged out."), |
| 1193 gaim_get_buddy_alias(b)); | 1181 gaim_get_buddy_alias(b)); |
| 1194 qm->account = gc->account; | 1182 qm->account = gc->account; |
| 1195 qm->tm = time(NULL); | 1183 qm->tm = time(NULL); |
| 1196 qm->flags = GAIM_MESSAGE_SYSTEM; | 1184 qm->flags = GAIM_MESSAGE_SYSTEM; |
| 1197 qm->len = -1; | |
| 1198 message_queue = g_slist_append(message_queue, qm); | 1185 message_queue = g_slist_append(message_queue, qm); |
| 1199 } | 1186 } |
| 1200 } | 1187 } |
| 1201 serv_got_typing_stopped(gc, name); /* obviously not typing */ | 1188 serv_got_typing_stopped(gc, name); /* obviously not typing */ |
| 1202 gaim_sound_play_event(GAIM_SOUND_BUDDY_LEAVE); | 1189 gaim_sound_play_event(GAIM_SOUND_BUDDY_LEAVE); |
| 1574 g_signal_connect(G_OBJECT(button), "clicked", | 1561 g_signal_connect(G_OBJECT(button), "clicked", |
| 1575 G_CALLBACK(url_clicked_cb), url); | 1562 G_CALLBACK(url_clicked_cb), url); |
| 1576 | 1563 |
| 1577 gtk_widget_show_all(window); | 1564 gtk_widget_show_all(window); |
| 1578 | 1565 |
| 1579 gtk_imhtml_append_text(GTK_IMHTML(text), msg, -1, GTK_IMHTML_NO_NEWLINE); | 1566 gtk_imhtml_append_text(GTK_IMHTML(text), msg, GTK_IMHTML_NO_NEWLINE); |
| 1580 } | 1567 } |
| 1581 | 1568 |
