comparison mcabber/mcabber/xmpp.c @ 2345:462f4359391c

Try to simplify handle_messages()
author franky
date Sat, 11 May 2019 23:06:34 +0200
parents 72543547c646
children 7921c8d671c8
comparison
equal deleted inserted replaced
2344:1579ed96d501 2345:462f4359391c
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) {
1184 } else if (!g_strcmp0(carbon_name, "sent")) { 1170 } else if (!g_strcmp0(carbon_name, "sent")) {
1185 #ifdef HAVE_GPGME 1171 #ifdef HAVE_GPGME
1186 char *decrypted_pgp = NULL; 1172 char *decrypted_pgp = NULL;
1187 #endif 1173 #endif
1188 guint encrypted = 0; 1174 guint encrypted = 0;
1189 const char *to= lm_message_node_get_attribute(x, "to"); 1175 const char *to = lm_message_node_get_attribute(x, "to");
1190 if (!to) { 1176 if (!to) {
1191 scr_LogPrint(LPRINT_LOGNORM, "Malformed carbon copy!"); 1177 scr_LogPrint(LPRINT_LOGNORM, "Malformed carbon copy!");
1192 goto handle_messages_return; 1178 goto handle_messages_return;
1193 } 1179 }
1194 g_free(bjid); 1180 g_free(bjid);
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 }