987 buddylist_defer_build(); |
987 buddylist_defer_build(); |
988 scr_update_roster(); |
988 scr_update_roster(); |
989 goto gotmessage_return; |
989 goto gotmessage_return; |
990 } |
990 } |
991 |
991 |
|
992 if (subject && LM_MESSAGE_SUB_TYPE_GROUPCHAT == type) { |
|
993 // Room topic |
|
994 GSList *roombuddy; |
|
995 gchar *mbuf; |
|
996 // Set the new topic |
|
997 roombuddy = roster_find(bjid, jidsearch, 0); |
|
998 if (roombuddy) |
|
999 buddy_settopic(roombuddy->data, subject); |
|
1000 // Display inside the room window |
|
1001 if (!rname) { |
|
1002 // No specific resource (this is certainly history) |
|
1003 if (*subject) |
|
1004 mbuf = g_strdup_printf("The topic has been set to: %s", subject); |
|
1005 else |
|
1006 mbuf = g_strdup_printf("The topic has been cleared"); |
|
1007 } else { |
|
1008 if (*subject) |
|
1009 mbuf = g_strdup_printf("%s has set the topic to: %s", rname, subject); |
|
1010 else |
|
1011 mbuf = g_strdup_printf("%s has cleared the topic", rname); |
|
1012 } |
|
1013 scr_WriteIncomingMessage(bjid, mbuf, timestamp, |
|
1014 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); |
|
1015 if (settings_opt_get_int("log_muc_conf")) |
|
1016 hlog_write_message(bjid, 0, -1, mbuf); |
|
1017 g_free(mbuf); |
|
1018 // The topic is displayed in the chat status line, so refresh now. |
|
1019 scr_update_chat_status(TRUE); |
|
1020 } |
|
1021 |
992 // We don't call the message_in hook if 'block_unsubscribed' is true and |
1022 // We don't call the message_in hook if 'block_unsubscribed' is true and |
993 // this is a regular message from an unsubscribed user. |
1023 // this is a regular message from an unsubscribed user. |
994 // System messages (from our server) are allowed. |
1024 // System messages (from our server) are allowed. |
995 if (settings_opt_get_int("block_unsubscribed") && |
1025 if (settings_opt_get_int("block_unsubscribed") && |
996 (roster_gettype(bjid) != ROSTER_TYPE_ROOM) && |
1026 (roster_gettype(bjid) != ROSTER_TYPE_ROOM) && |
1050 |
1080 |
1051 static LmHandlerResult handle_messages(LmMessageHandler *handler, |
1081 static LmHandlerResult handle_messages(LmMessageHandler *handler, |
1052 LmConnection *connection, |
1082 LmConnection *connection, |
1053 LmMessage *m, gpointer user_data) |
1083 LmMessage *m, gpointer user_data) |
1054 { |
1084 { |
1055 const char *p, *from=lm_message_get_from(m); |
1085 const char *from = lm_message_get_from(m); |
1056 char *bjid, *res; |
1086 char *bjid, *res; |
1057 LmMessageNode *x; |
1087 LmMessageNode *x; |
1058 const char *body = NULL; |
1088 const char *body = NULL; |
1059 const char *enc = NULL; |
1089 const char *enc = NULL; |
1060 const char *subject = NULL; |
1090 const char *subject = NULL; |
1061 time_t timestamp = 0L; |
1091 time_t timestamp = 0L; |
1062 LmMessageSubType mstype; |
1092 LmMessageSubType mstype; |
1063 gboolean skip_process = FALSE; |
|
1064 LmMessageNode *ns_signed = NULL; |
1093 LmMessageNode *ns_signed = NULL; |
1065 |
1094 |
1066 mstype = lm_message_get_sub_type(m); |
1095 if (!from) { |
1067 |
1096 scr_LogPrint(LPRINT_DEBUG, "handle_messages: message with missing from attribute"); |
1068 body = lm_message_node_get_child_value(m->node, "body"); |
1097 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; |
1069 |
1098 } |
1070 x = lm_message_node_find_xmlns(m->node, NS_ENCRYPTED); |
|
1071 if (x && (p = lm_message_node_get_value(x)) != NULL) |
|
1072 enc = p; |
|
1073 |
|
1074 // Get the bare-JID/room (bjid) and the resource/nickname (res) |
1099 // Get the bare-JID/room (bjid) and the resource/nickname (res) |
1075 bjid = g_strdup(lm_message_get_from(m)); |
1100 bjid = g_strdup(from); |
1076 res = strchr(bjid, JID_RESOURCE_SEPARATOR); |
1101 res = strchr(bjid, JID_RESOURCE_SEPARATOR); |
1077 if (res) *res++ = 0; |
1102 if (res) *res++ = 0; |
1078 |
1103 |
|
1104 mstype = lm_message_get_sub_type(m); |
1079 // Timestamp? |
1105 // Timestamp? |
1080 timestamp = lm_message_node_get_timestamp(m->node); |
1106 timestamp = lm_message_node_get_timestamp(m->node); |
1081 |
|
1082 p = lm_message_node_get_child_value(m->node, "subject"); |
|
1083 if (p != NULL) { |
|
1084 if (mstype != LM_MESSAGE_SUB_TYPE_GROUPCHAT) { |
|
1085 // Chat message |
|
1086 subject = p; |
|
1087 } else { |
|
1088 // Room topic |
|
1089 GSList *roombuddy; |
|
1090 gchar *mbuf; |
|
1091 const gchar *subj = p; |
|
1092 // Set the new topic |
|
1093 roombuddy = roster_find(bjid, jidsearch, 0); |
|
1094 if (roombuddy) |
|
1095 buddy_settopic(roombuddy->data, subj); |
|
1096 // Display inside the room window |
|
1097 if (!res) { |
|
1098 // No specific resource (this is certainly history) |
|
1099 if (*subj) |
|
1100 mbuf = g_strdup_printf("The topic has been set to: %s", subj); |
|
1101 else |
|
1102 mbuf = g_strdup_printf("The topic has been cleared"); |
|
1103 } else { |
|
1104 if (*subj) |
|
1105 mbuf = g_strdup_printf("%s has set the topic to: %s", res, subj); |
|
1106 else |
|
1107 mbuf = g_strdup_printf("%s has cleared the topic", res); |
|
1108 } |
|
1109 scr_WriteIncomingMessage(bjid, mbuf, timestamp, |
|
1110 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); |
|
1111 if (settings_opt_get_int("log_muc_conf")) |
|
1112 hlog_write_message(bjid, 0, -1, mbuf); |
|
1113 g_free(mbuf); |
|
1114 // The topic is displayed in the chat status line, so refresh now. |
|
1115 scr_update_chat_status(TRUE); |
|
1116 } |
|
1117 } |
|
1118 |
1107 |
1119 if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) { |
1108 if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) { |
1120 x = lm_message_node_get_child(m->node, "error"); |
1109 x = lm_message_node_get_child(m->node, "error"); |
1121 display_server_error(x, from); |
1110 display_server_error(x, from); |
1122 #ifdef XEP0085 |
1111 #ifdef XEP0085 |
1152 "Could not read carbon message! Please file a bug."); |
1141 "Could not read carbon message! Please file a bug."); |
1153 goto handle_messages_return; |
1142 goto handle_messages_return; |
1154 } |
1143 } |
1155 |
1144 |
1156 xenc = lm_message_node_find_xmlns(x, NS_ENCRYPTED); |
1145 xenc = lm_message_node_find_xmlns(x, NS_ENCRYPTED); |
1157 if (xenc && (p = lm_message_node_get_value(xenc)) != NULL) |
1146 if (xenc) |
1158 enc = p; |
1147 enc = lm_message_node_get_value(xenc); |
1159 |
1148 |
1160 body = lm_message_node_get_child_value(x, "body"); |
1149 body = lm_message_node_get_child_value(x, "body"); |
1161 subject = lm_message_node_get_child_value(x, "subject"); |
1150 subject = lm_message_node_get_child_value(x, "subject"); |
1162 if (body && *body && !subject) |
1151 ns_signed = lm_message_node_find_xmlns(x, NS_SIGNED); |
1163 ns_signed = lm_message_node_find_xmlns(x, NS_SIGNED); |
|
1164 else |
|
1165 skip_process = TRUE; |
|
1166 |
1152 |
1167 // Parse a message that is send to one of our other resources |
1153 // Parse a message that is send to one of our other resources |
1168 if (!g_strcmp0(carbon_name, "received")) { |
1154 if (!g_strcmp0(carbon_name, "received")) { |
1169 from = lm_message_node_get_attribute(x, "from"); |
1155 from = lm_message_node_get_attribute(x, "from"); |
1170 if (!from) { |
1156 if (!from) { |
1221 g_free(decrypted_pgp); |
1207 g_free(decrypted_pgp); |
1222 #endif |
1208 #endif |
1223 goto handle_messages_return; |
1209 goto handle_messages_return; |
1224 } |
1210 } |
1225 } else { // Not a Carbon |
1211 } else { // Not a Carbon |
|
1212 subject = lm_message_node_get_child_value(m->node, "subject"); |
|
1213 body = lm_message_node_get_child_value(m->node, "body"); |
|
1214 x = lm_message_node_find_xmlns(m->node, NS_ENCRYPTED); |
|
1215 if (x) |
|
1216 enc = lm_message_node_get_value(x); |
1226 ns_signed = lm_message_node_find_xmlns(m->node, NS_SIGNED); |
1217 ns_signed = lm_message_node_find_xmlns(m->node, NS_SIGNED); |
1227 } |
1218 } |
1228 |
1219 |
1229 // Do not process the message if some fields are missing |
1220 // Only process messages that have a body or a subject |
1230 if (!from || (!body && !subject)) |
1221 if (body || subject) { |
1231 skip_process = TRUE; |
|
1232 |
|
1233 if (!skip_process) { |
|
1234 gotmessage(mstype, from, body, enc, subject, timestamp, |
1222 gotmessage(mstype, from, body, enc, subject, timestamp, |
1235 ns_signed, carbons); |
1223 ns_signed, carbons); |
1236 } |
1224 } |
1237 |
1225 |
1238 // We're done if it was a Carbon forwarded message |
1226 // Handle XEP 184 |
1239 if (carbons) |
1227 { |
1240 goto handle_messages_return; |
1228 LmMessageNode *xep184 = lm_message_node_find_xmlns(m->node, NS_RECEIPTS); |
1241 |
1229 if (xep184) { |
1242 // Report received message if message delivery receipt was requested |
1230 if(!g_strcmp0("request", xep184->name) && |
1243 if (lm_message_node_get_child(m->node, "request") && |
1231 (roster_getsubscription(bjid) & sub_from)) { |
1244 (roster_getsubscription(bjid) & sub_from)) { |
1232 // Report received message if message delivery receipt was requested |
1245 const gchar *mid; |
1233 const gchar *mid; |
1246 LmMessageNode *y; |
1234 LmMessageNode *y; |
1247 LmMessage *rcvd = lm_message_new(from, LM_MESSAGE_TYPE_MESSAGE); |
1235 LmMessage *rcvd = lm_message_new(from, LM_MESSAGE_TYPE_MESSAGE); |
1248 mid = lm_message_get_id(m); |
1236 mid = lm_message_get_id(m); |
1249 // For backward compatibility (XEP184 < v.1.1): |
1237 // For backward compatibility (XEP184 < v.1.1): |
1250 lm_message_node_set_attribute(rcvd->node, "id", mid); |
1238 lm_message_node_set_attribute(rcvd->node, "id", mid); |
1251 y = lm_message_node_add_child(rcvd->node, "received", NULL); |
1239 y = lm_message_node_add_child(rcvd->node, "received", NULL); |
1252 lm_message_node_set_attribute(y, "xmlns", NS_RECEIPTS); |
1240 lm_message_node_set_attribute(y, "xmlns", NS_RECEIPTS); |
1253 lm_message_node_set_attribute(y, "id", mid); |
1241 lm_message_node_set_attribute(y, "id", mid); |
1254 lm_connection_send(connection, rcvd, NULL); |
1242 lm_connection_send(connection, rcvd, NULL); |
1255 lm_message_unref(rcvd); |
1243 lm_message_unref(rcvd); |
1256 } |
1244 } else if(!g_strcmp0("received", xep184->name)) { |
1257 |
1245 // receipt acknowledged |
1258 { // xep184 receipt confirmation |
1246 const char *id = lm_message_node_get_attribute(xep184, "id"); |
1259 LmMessageNode *received = lm_message_node_get_child(m->node, "received"); |
1247 // This is for backward compatibility; if the remote client didn't add |
1260 if (received && !g_strcmp0(lm_message_node_get_attribute(received, "xmlns"), |
1248 // the id as an attribute of the 'received' tag, we use the message id: |
1261 NS_RECEIPTS)) { |
1249 if (!id) |
1262 char *jid = jidtodisp(from); |
1250 id = lm_message_get_id(m); |
1263 const char *id = lm_message_node_get_attribute(received, "id"); |
1251 scr_remove_receipt_flag(bjid, id); |
1264 // This is for backward compatibility; if the remote client didn't add |
|
1265 // the id as an attribute of the 'received' tag, we use the message id: |
|
1266 if (!id) |
|
1267 id = lm_message_get_id(m); |
|
1268 scr_remove_receipt_flag(jid, id); |
|
1269 g_free(jid); |
|
1270 |
1252 |
1271 #ifdef MODULES_ENABLE |
1253 #ifdef MODULES_ENABLE |
1272 { |
1254 { |
1273 hk_arg_t args[] = { |
1255 hk_arg_t args[] = { |
1274 { "jid", from }, |
1256 { "jid", from }, |
1275 { NULL, NULL }, |
1257 { NULL, NULL }, |
1276 }; |
1258 }; |
1277 hk_run_handlers("hook-mdr-received", args); |
1259 hk_run_handlers("hook-mdr-received", args); |
|
1260 } |
|
1261 #endif |
1278 } |
1262 } |
1279 #endif |
1263 } |
1280 } |
1264 } |
1281 } |
1265 |
1282 |
1266 { |
1283 if (from) { |
1267 LmMessageNode *muc_message = lm_message_node_find_xmlns(m->node, NS_MUC_USER); |
1284 x = lm_message_node_find_xmlns(m->node, NS_MUC_USER); |
1268 if (muc_message && !strcmp(muc_message->name, "x")) |
1285 if (x && !strcmp(x->name, "x")) |
1269 got_muc_message(from, muc_message, timestamp); |
1286 got_muc_message(from, x, timestamp); |
1270 } |
1287 |
1271 |
1288 x = lm_message_node_find_xmlns(m->node, NS_X_CONFERENCE); |
1272 { |
1289 |
1273 LmMessageNode *muc_invite = lm_message_node_find_xmlns(m->node, NS_X_CONFERENCE); |
1290 if (x && !strcmp(x->name, "x")) { |
1274 |
1291 const char *jid = lm_message_node_get_attribute(x, "jid"); |
1275 if (muc_invite && !strcmp(muc_invite->name, "x")) { |
|
1276 const char *jid = lm_message_node_get_attribute(muc_invite, "jid"); |
1292 if (jid) { |
1277 if (jid) { |
1293 const char *reason = lm_message_node_get_attribute(x, "reason"); |
1278 const char *reason = lm_message_node_get_attribute(muc_invite, "reason"); |
1294 const char *password = lm_message_node_get_attribute(x, "password"); |
1279 const char *password = lm_message_node_get_attribute(muc_invite, "password"); |
1295 // We won't send decline stanzas as it is a Direct Invitation |
1280 // We won't send decline stanzas as it is a Direct Invitation |
1296 got_invite(from, jid, reason, password, FALSE); |
1281 got_invite(from, jid, reason, password, FALSE); |
1297 } |
1282 } |
1298 } |
1283 } |
1299 } |
1284 } |