diff options
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r-- | toxcore/Messenger.c | 538 |
1 files changed, 23 insertions, 515 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 99b95f67..edb34364 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -492,10 +492,6 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length) | |||
492 | for (i = 0; i < m->numfriends; ++i) | 492 | for (i = 0; i < m->numfriends; ++i) |
493 | m->friendlist[i].name_sent = 0; | 493 | m->friendlist[i].name_sent = 0; |
494 | 494 | ||
495 | for (i = 0; i < m->numchats; i++) | ||
496 | if (m->chats[i] != NULL) | ||
497 | set_nick(m->chats[i], name, length); /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
498 | |||
499 | return 0; | 495 | return 0; |
500 | } | 496 | } |
501 | 497 | ||
@@ -1015,459 +1011,47 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_ | |||
1015 | 1011 | ||
1016 | /**********GROUP CHATS************/ | 1012 | /**********GROUP CHATS************/ |
1017 | 1013 | ||
1018 | /* return 1 if the groupnumber is not valid. | ||
1019 | * return 0 if the groupnumber is valid. | ||
1020 | */ | ||
1021 | static uint8_t groupnumber_not_valid(const Messenger *m, int groupnumber) | ||
1022 | { | ||
1023 | if ((unsigned int)groupnumber >= m->numchats) | ||
1024 | return 1; | ||
1025 | |||
1026 | if (m->chats == NULL) | ||
1027 | return 1; | ||
1028 | |||
1029 | if (m->chats[groupnumber] == NULL) | ||
1030 | return 1; | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | /* returns valid ip port of connected friend on success | ||
1037 | * returns zeroed out IP_Port on failure | ||
1038 | */ | ||
1039 | static IP_Port get_friend_ipport(const Messenger *m, int32_t friendnumber) | ||
1040 | { | ||
1041 | IP_Port zero; | ||
1042 | memset(&zero, 0, sizeof(zero)); | ||
1043 | |||
1044 | if (friend_not_valid(m, friendnumber)) | ||
1045 | return zero; | ||
1046 | |||
1047 | int crypt_id = m->friendlist[friendnumber].crypt_connection_id; | ||
1048 | |||
1049 | uint8_t direct_connected; | ||
1050 | |||
1051 | if (crypto_connection_status(m->net_crypto, crypt_id, &direct_connected) != CRYPTO_CONN_ESTABLISHED) | ||
1052 | return zero; | ||
1053 | |||
1054 | if (direct_connected == 0) | ||
1055 | return zero; | ||
1056 | |||
1057 | return m->net_crypto->crypto_connections[crypt_id].ip_port; | ||
1058 | } | ||
1059 | |||
1060 | /* returns the group number of the chat with public key group_public_key. | ||
1061 | * returns -1 on failure. | ||
1062 | */ | ||
1063 | static int group_num(const Messenger *m, const uint8_t *group_public_key) | ||
1064 | { | ||
1065 | uint32_t i; | ||
1066 | |||
1067 | for (i = 0; i < m->numchats; ++i) { | ||
1068 | if (m->chats[i] != NULL) | ||
1069 | if (id_equal(m->chats[i]->self_public_key, group_public_key)) | ||
1070 | return i; | ||
1071 | } | ||
1072 | |||
1073 | return -1; | ||
1074 | } | ||
1075 | 1014 | ||
1076 | /* Set the callback for group invites. | 1015 | /* Set the callback for group invites. |
1077 | * | 1016 | * |
1078 | * Function(Messenger *m, int32_t friendnumber, uint8_t *group_public_key, void *userdata) | 1017 | * Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number) |
1079 | */ | 1018 | */ |
1080 | void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, void *), | 1019 | void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number) |
1081 | void *userdata) | ||
1082 | { | 1020 | { |
1083 | m->group_invite = function; | 1021 | m->group_invite = function; |
1084 | m->group_invite_userdata = userdata; | 1022 | m->group_invite_number = number; |
1085 | } | 1023 | } |
1086 | 1024 | ||
1087 | /* Set the callback for group messages. | 1025 | /* Set the callback for group messages. |
1088 | * | 1026 | * |
1089 | * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) | 1027 | * Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number) |
1090 | */ | 1028 | */ |
1091 | void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *), | 1029 | void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number) |
1092 | void *userdata) | ||
1093 | { | 1030 | { |
1094 | m->group_message = function; | 1031 | m->group_message = function; |
1095 | m->group_message_userdata = userdata; | 1032 | m->group_message_number = number; |
1096 | } | 1033 | } |
1097 | 1034 | ||
1098 | /* Set the callback for group actions. | 1035 | /* Send a group invite packet. |
1099 | * | 1036 | * |
1100 | * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) | 1037 | * return 1 on success |
1101 | */ | 1038 | * return 0 on failure |
1102 | void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *), | ||
1103 | void *userdata) | ||
1104 | { | ||
1105 | m->group_action = function; | ||
1106 | m->group_action_userdata = userdata; | ||
1107 | } | ||
1108 | |||
1109 | /* Set callback function for peer name list changes. | ||
1110 | * | ||
1111 | * It gets called every time the name list changes(new peer/name, deleted peer) | ||
1112 | * Function(Tox *tox, int groupnumber, void *userdata) | ||
1113 | */ | ||
1114 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), | ||
1115 | void *userdata) | ||
1116 | { | ||
1117 | m->group_namelistchange = function; | ||
1118 | m->group_namelistchange_userdata = userdata; | ||
1119 | } | ||
1120 | |||
1121 | static int get_chat_num(const Messenger *m, const Group_Chat *chat) | ||
1122 | { | ||
1123 | uint32_t i; | ||
1124 | |||
1125 | for (i = 0; i < m->numchats; ++i) { //TODO: remove this | ||
1126 | if (m->chats[i] == chat) | ||
1127 | return i; | ||
1128 | } | ||
1129 | |||
1130 | return -1; | ||
1131 | } | ||
1132 | |||
1133 | static void group_message_function(Group_Chat *chat, int peer_number, const uint8_t *message, uint16_t length, | ||
1134 | void *userdata) | ||
1135 | { | ||
1136 | Messenger *m = userdata; | ||
1137 | int i = get_chat_num(m, chat); | ||
1138 | |||
1139 | if (i == -1) | ||
1140 | return; | ||
1141 | |||
1142 | uint8_t message_terminated[length + 1]; | ||
1143 | memcpy(message_terminated, message, length); | ||
1144 | message_terminated[length] = 0; /* Force NULL terminator */ | ||
1145 | |||
1146 | if (m->group_message) | ||
1147 | (*m->group_message)(m, i, peer_number, message_terminated, length, m->group_message_userdata); | ||
1148 | } | ||
1149 | |||
1150 | static void group_action_function(Group_Chat *chat, int peer_number, const uint8_t *action, uint16_t length, | ||
1151 | void *userdata) | ||
1152 | { | ||
1153 | Messenger *m = userdata; | ||
1154 | int i = get_chat_num(m, chat); | ||
1155 | |||
1156 | if (i == -1) | ||
1157 | return; | ||
1158 | |||
1159 | uint8_t action_terminated[length + 1]; | ||
1160 | memcpy(action_terminated, action, length); | ||
1161 | action_terminated[length] = 0; /* Force NULL terminator */ | ||
1162 | |||
1163 | if (m->group_action) | ||
1164 | (*m->group_action)(m, i, peer_number, action_terminated, length, m->group_action_userdata); | ||
1165 | } | ||
1166 | |||
1167 | static void group_namelistchange_function(Group_Chat *chat, int peer, uint8_t change, void *userdata) | ||
1168 | { | ||
1169 | Messenger *m = userdata; | ||
1170 | int i = get_chat_num(m, chat); | ||
1171 | |||
1172 | if (i == -1) | ||
1173 | return; | ||
1174 | |||
1175 | if (m->group_namelistchange) | ||
1176 | (*m->group_namelistchange)(m, i, peer, change, m->group_namelistchange_userdata); | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | /* Creates a new groupchat and puts it in the chats array. | ||
1181 | * | ||
1182 | * return group number on success. | ||
1183 | * return -1 on failure. | ||
1184 | */ | ||
1185 | int add_groupchat(Messenger *m) | ||
1186 | { | ||
1187 | uint32_t i; | ||
1188 | |||
1189 | for (i = 0; i < m->numchats; ++i) { | ||
1190 | if (m->chats[i] == NULL) { | ||
1191 | Group_Chat *newchat = new_groupchat(m->net); | ||
1192 | |||
1193 | if (newchat == NULL) | ||
1194 | return -1; | ||
1195 | |||
1196 | callback_groupmessage(newchat, &group_message_function, m); | ||
1197 | callback_groupaction(newchat, &group_action_function, m); | ||
1198 | callback_namelistchange(newchat, &group_namelistchange_function, m); | ||
1199 | /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
1200 | set_nick(newchat, m->name, m->name_length); | ||
1201 | m->chats[i] = newchat; | ||
1202 | return i; | ||
1203 | } | ||
1204 | } | ||
1205 | |||
1206 | Group_Chat **temp; | ||
1207 | temp = realloc(m->chats, sizeof(Group_Chat *) * (m->numchats + 1)); | ||
1208 | |||
1209 | if (temp == NULL) | ||
1210 | return -1; | ||
1211 | |||
1212 | m->chats = temp; | ||
1213 | temp[m->numchats] = new_groupchat(m->net); | ||
1214 | |||
1215 | if (temp[m->numchats] == NULL) | ||
1216 | return -1; | ||
1217 | |||
1218 | callback_groupmessage(temp[m->numchats], &group_message_function, m); | ||
1219 | callback_groupaction(temp[m->numchats], &group_action_function, m); | ||
1220 | callback_namelistchange(temp[m->numchats], &group_namelistchange_function, m); | ||
1221 | /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
1222 | set_nick(temp[m->numchats], m->name, m->name_length); | ||
1223 | ++m->numchats; | ||
1224 | return (m->numchats - 1); | ||
1225 | } | ||
1226 | |||
1227 | /* Delete a groupchat from the chats array. | ||
1228 | * | ||
1229 | * return 0 on success. | ||
1230 | * return -1 if failure. | ||
1231 | */ | ||
1232 | int del_groupchat(Messenger *m, int groupnumber) | ||
1233 | { | ||
1234 | if ((unsigned int)groupnumber >= m->numchats) | ||
1235 | return -1; | ||
1236 | |||
1237 | if (m->chats == NULL) | ||
1238 | return -1; | ||
1239 | |||
1240 | if (m->chats[groupnumber] == NULL) | ||
1241 | return -1; | ||
1242 | |||
1243 | kill_groupchat(m->chats[groupnumber]); | ||
1244 | m->chats[groupnumber] = NULL; | ||
1245 | |||
1246 | uint32_t i; | ||
1247 | |||
1248 | for (i = m->numchats; i != 0; --i) { | ||
1249 | if (m->chats[i - 1] != NULL) | ||
1250 | break; | ||
1251 | } | ||
1252 | |||
1253 | m->numchats = i; | ||
1254 | |||
1255 | if (i == 0) { | ||
1256 | free(m->chats); | ||
1257 | m->chats = NULL; | ||
1258 | } else { | ||
1259 | Group_Chat **temp = realloc(m->chats, sizeof(Group_Chat *) * i); | ||
1260 | |||
1261 | if (temp != NULL) | ||
1262 | m->chats = temp; | ||
1263 | } | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | /* Copy the name of peernumber who is in groupnumber to name. | ||
1269 | * name must be at least MAX_NICK_BYTES long. | ||
1270 | * | ||
1271 | * return length of name if success | ||
1272 | * return -1 if failure | ||
1273 | */ | ||
1274 | int m_group_peername(const Messenger *m, int groupnumber, int peernumber, uint8_t *name) | ||
1275 | { | ||
1276 | if ((unsigned int)groupnumber >= m->numchats) | ||
1277 | return -1; | ||
1278 | |||
1279 | if (m->chats == NULL) | ||
1280 | return -1; | ||
1281 | |||
1282 | if (m->chats[groupnumber] == NULL) | ||
1283 | return -1; | ||
1284 | |||
1285 | return group_peername(m->chats[groupnumber], peernumber, name); | ||
1286 | } | ||
1287 | |||
1288 | /* Store the fact that we invited a specific friend. | ||
1289 | */ | ||
1290 | static void group_store_friendinvite(Messenger *m, int32_t friendnumber, int groupnumber) | ||
1291 | { | ||
1292 | /* Add 1 to the groupchat number because 0 (default value in invited_groups) is a valid groupchat number */ | ||
1293 | m->friendlist[friendnumber].invited_groups[m->friendlist[friendnumber].invited_groups_num % MAX_INVITED_GROUPS] = | ||
1294 | groupnumber + 1; | ||
1295 | ++m->friendlist[friendnumber].invited_groups_num; | ||
1296 | } | ||
1297 | |||
1298 | /* return 1 if that friend was invited to the group | ||
1299 | * return 0 if the friend was not or error. | ||
1300 | */ | ||
1301 | static uint8_t group_invited(const Messenger *m, int32_t friendnumber, int groupnumber) | ||
1302 | { | ||
1303 | |||
1304 | uint32_t i; | ||
1305 | uint16_t num = MAX_INVITED_GROUPS; | ||
1306 | |||
1307 | if (MAX_INVITED_GROUPS > m->friendlist[friendnumber].invited_groups_num) | ||
1308 | num = m->friendlist[friendnumber].invited_groups_num; | ||
1309 | |||
1310 | for (i = 0; i < num; ++i) { | ||
1311 | if (m->friendlist[friendnumber].invited_groups[i] == groupnumber + 1) { | ||
1312 | return 1; | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | /* invite friendnumber to groupnumber | ||
1320 | * return 0 on success | ||
1321 | * return -1 on failure | ||
1322 | */ | ||
1323 | int invite_friend(Messenger *m, int32_t friendnumber, int groupnumber) | ||
1324 | { | ||
1325 | if (friend_not_valid(m, friendnumber) || (unsigned int)groupnumber >= m->numchats) | ||
1326 | return -1; | ||
1327 | |||
1328 | if (m->chats == NULL) | ||
1329 | return -1; | ||
1330 | |||
1331 | if (m->friendlist[friendnumber].status == NOFRIEND || m->chats[groupnumber] == NULL) | ||
1332 | return -1; | ||
1333 | |||
1334 | group_store_friendinvite(m, friendnumber, groupnumber); | ||
1335 | |||
1336 | if (write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, m->chats[groupnumber]->self_public_key, | ||
1337 | crypto_box_PUBLICKEYBYTES, 0) == 0) | ||
1338 | return -1; | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1343 | |||
1344 | /* Join a group (you need to have been invited first.) | ||
1345 | * | ||
1346 | * returns group number on success | ||
1347 | * returns -1 on failure. | ||
1348 | */ | ||
1349 | int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_group_public_key) | ||
1350 | { | ||
1351 | if (friend_not_valid(m, friendnumber)) | ||
1352 | return -1; | ||
1353 | |||
1354 | uint8_t data[crypto_box_PUBLICKEYBYTES * 2]; | ||
1355 | int groupnum = add_groupchat(m); | ||
1356 | |||
1357 | if (groupnum == -1) | ||
1358 | return -1; | ||
1359 | |||
1360 | IP_Port friend_ip = get_friend_ipport(m, friendnumber); | ||
1361 | |||
1362 | if (friend_ip.ip.family == 0) { | ||
1363 | del_groupchat(m, groupnum); | ||
1364 | return -1; | ||
1365 | } | ||
1366 | |||
1367 | id_copy(data, friend_group_public_key); | ||
1368 | id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key); | ||
1369 | |||
1370 | if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data), 0)) { | ||
1371 | chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber), | ||
1372 | friend_group_public_key); //TODO: check if ip returned is zero? | ||
1373 | return groupnum; | ||
1374 | } | ||
1375 | |||
1376 | del_groupchat(m, groupnum); | ||
1377 | return -1; | ||
1378 | } | ||
1379 | |||
1380 | |||
1381 | /* send a group message | ||
1382 | * return 0 on success | ||
1383 | * return -1 on failure | ||
1384 | */ | ||
1385 | int group_message_send(const Messenger *m, int groupnumber, const uint8_t *message, uint32_t length) | ||
1386 | { | ||
1387 | if (groupnumber_not_valid(m, groupnumber)) | ||
1388 | return -1; | ||
1389 | |||
1390 | if (group_sendmessage(m->chats[groupnumber], message, length) > 0) | ||
1391 | return 0; | ||
1392 | |||
1393 | return -1; | ||
1394 | } | ||
1395 | |||
1396 | /* send a group action | ||
1397 | * return 0 on success | ||
1398 | * return -1 on failure | ||
1399 | */ | ||
1400 | int group_action_send(const Messenger *m, int groupnumber, const uint8_t *action, uint32_t length) | ||
1401 | { | ||
1402 | if (groupnumber_not_valid(m, groupnumber)) | ||
1403 | return -1; | ||
1404 | |||
1405 | if (group_sendaction(m->chats[groupnumber], action, length) > 0) | ||
1406 | return 0; | ||
1407 | |||
1408 | return -1; | ||
1409 | } | ||
1410 | |||
1411 | /* Return the number of peers in the group chat on success. | ||
1412 | * return -1 on failure | ||
1413 | */ | 1039 | */ |
1414 | int group_number_peers(const Messenger *m, int groupnumber) | 1040 | int send_group_invite_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) |
1415 | { | 1041 | { |
1416 | if (groupnumber_not_valid(m, groupnumber)) | 1042 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, data, length, 0); |
1417 | return -1; | ||
1418 | |||
1419 | return group_numpeers(m->chats[groupnumber]); | ||
1420 | } | 1043 | } |
1421 | 1044 | ||
1422 | /* List all the peers in the group chat. | 1045 | /* Send a group message packet. |
1423 | * | ||
1424 | * Copies the names of the peers to the name[length][MAX_NICK_BYTES] array. | ||
1425 | * | 1046 | * |
1426 | * Copies the lengths of the names to lengths[length] | 1047 | * return 1 on success |
1427 | * | 1048 | * return 0 on failure |
1428 | * returns the number of peers on success. | ||
1429 | * | ||
1430 | * return -1 on failure. | ||
1431 | */ | 1049 | */ |
1432 | int group_names(const Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[], | 1050 | int send_group_message_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) |
1433 | uint16_t length) | ||
1434 | { | ||
1435 | if (groupnumber_not_valid(m, groupnumber)) | ||
1436 | return -1; | ||
1437 | |||
1438 | return group_client_names(m->chats[groupnumber], names, lengths, length); | ||
1439 | } | ||
1440 | |||
1441 | static int handle_group(void *object, IP_Port source, const uint8_t *packet, uint32_t length) | ||
1442 | { | 1051 | { |
1443 | Messenger *m = object; | 1052 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_MESSAGE_GROUPCHAT, data, length, 0); |
1444 | |||
1445 | if (length < crypto_box_PUBLICKEYBYTES + 1) { | ||
1446 | return 1; | ||
1447 | } | ||
1448 | |||
1449 | uint32_t i; | ||
1450 | |||
1451 | for (i = 0; i < m->numchats; ++i) { | ||
1452 | if (m->chats[i] == NULL) | ||
1453 | continue; | ||
1454 | |||
1455 | if (id_equal(packet + 1, m->chats[i]->self_public_key)) | ||
1456 | return handle_groupchatpacket(m->chats[i], source, packet, length); | ||
1457 | } | ||
1458 | |||
1459 | return 1; | ||
1460 | } | 1053 | } |
1461 | 1054 | ||
1462 | static void do_allgroupchats(Messenger *m) | ||
1463 | { | ||
1464 | uint32_t i; | ||
1465 | |||
1466 | for (i = 0; i < m->numchats; ++i) { | ||
1467 | if (m->chats[i] != NULL) | ||
1468 | do_groupchat(m->chats[i]); | ||
1469 | } | ||
1470 | } | ||
1471 | 1055 | ||
1472 | /****************FILE SENDING*****************/ | 1056 | /****************FILE SENDING*****************/ |
1473 | 1057 | ||
@@ -2061,21 +1645,13 @@ Messenger *new_messenger(Messenger_Options *options) | |||
2061 | set_nospam(&(m->fr), random_int()); | 1645 | set_nospam(&(m->fr), random_int()); |
2062 | set_filter_function(&(m->fr), &friend_already_added, m); | 1646 | set_filter_function(&(m->fr), &friend_already_added, m); |
2063 | 1647 | ||
2064 | networking_registerhandler(m->net, NET_PACKET_GROUP_CHATS, &handle_group, m); | ||
2065 | |||
2066 | return m; | 1648 | return m; |
2067 | } | 1649 | } |
2068 | 1650 | ||
2069 | /* Run this before closing shop. */ | 1651 | /* Run this before closing shop. */ |
2070 | void kill_messenger(Messenger *m) | 1652 | void kill_messenger(Messenger *m) |
2071 | { | 1653 | { |
2072 | /* FIXME TODO: ideally cleanupMessenger will mirror initMessenger. | 1654 | uint32_t i; |
2073 | * This requires the other modules to expose cleanup functions. | ||
2074 | */ | ||
2075 | uint32_t i, numchats = m->numchats; | ||
2076 | |||
2077 | for (i = 0; i < numchats; ++i) | ||
2078 | del_groupchat(m, i); | ||
2079 | 1655 | ||
2080 | kill_onion(m->onion); | 1656 | kill_onion(m->onion); |
2081 | kill_onion_announce(m->onion_a); | 1657 | kill_onion_announce(m->onion_a); |
@@ -2599,30 +2175,21 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
2599 | } | 2175 | } |
2600 | 2176 | ||
2601 | case PACKET_ID_INVITE_GROUPCHAT: { | 2177 | case PACKET_ID_INVITE_GROUPCHAT: { |
2602 | if (data_length != crypto_box_PUBLICKEYBYTES) | 2178 | if (data_length == 0) |
2603 | break; | 2179 | break; |
2604 | 2180 | ||
2605 | if (m->group_invite) | 2181 | if (m->group_invite) |
2606 | (*m->group_invite)(m, i, data, m->group_invite_userdata); | 2182 | (*m->group_invite)(m, i, temp, len, m->group_invite_number); |
2607 | 2183 | ||
2608 | break; | 2184 | break; |
2609 | } | 2185 | } |
2610 | 2186 | ||
2611 | case PACKET_ID_JOIN_GROUPCHAT: { | 2187 | case PACKET_ID_MESSAGE_GROUPCHAT: { |
2612 | if (data_length != crypto_box_PUBLICKEYBYTES * 2) | 2188 | if (data_length == 0) |
2613 | break; | ||
2614 | |||
2615 | int groupnum = group_num(m, data); | ||
2616 | |||
2617 | if (groupnum == -1) | ||
2618 | break; | ||
2619 | |||
2620 | if (!group_invited(m, i, groupnum)) | ||
2621 | break; | 2189 | break; |
2622 | 2190 | ||
2623 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); | 2191 | if (m->group_message) |
2624 | /* This is just there to speedup joining. */ | 2192 | (*m->group_message)(m, i, temp, len, m->group_message_number); |
2625 | chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES); | ||
2626 | break; | 2193 | break; |
2627 | } | 2194 | } |
2628 | 2195 | ||
@@ -2902,7 +2469,6 @@ void do_messenger(Messenger *m) | |||
2902 | do_net_crypto(m->net_crypto); | 2469 | do_net_crypto(m->net_crypto); |
2903 | do_onion_client(m->onion_c); | 2470 | do_onion_client(m->onion_c); |
2904 | do_friends(m); | 2471 | do_friends(m); |
2905 | do_allgroupchats(m); | ||
2906 | LANdiscovery(m); | 2472 | LANdiscovery(m); |
2907 | 2473 | ||
2908 | #ifdef LOGGING | 2474 | #ifdef LOGGING |
@@ -2913,16 +2479,6 @@ void do_messenger(Messenger *m) | |||
2913 | Assoc_status(m->dht->assoc); | 2479 | Assoc_status(m->dht->assoc); |
2914 | #endif | 2480 | #endif |
2915 | 2481 | ||
2916 | if (m->numchats > 0) { | ||
2917 | size_t c; | ||
2918 | |||
2919 | for (c = 0; c < m->numchats; c++) { | ||
2920 | if (m->chats[c]) | ||
2921 | Assoc_status(m->chats[c]->assoc); | ||
2922 | } | ||
2923 | } | ||
2924 | |||
2925 | |||
2926 | lastdump = unix_time(); | 2482 | lastdump = unix_time(); |
2927 | uint32_t client, last_pinged; | 2483 | uint32_t client, last_pinged; |
2928 | 2484 | ||
@@ -3429,51 +2985,3 @@ int get_friendlist(const Messenger *m, int32_t **out_list, uint32_t *out_list_le | |||
3429 | 2985 | ||
3430 | return 0; | 2986 | return 0; |
3431 | } | 2987 | } |
3432 | |||
3433 | /* Return the number of chats in the instance m. | ||
3434 | * You should use this to determine how much memory to allocate | ||
3435 | * for copy_chatlist. */ | ||
3436 | uint32_t count_chatlist(const Messenger *m) | ||
3437 | { | ||
3438 | uint32_t ret = 0; | ||
3439 | uint32_t i; | ||
3440 | |||
3441 | for (i = 0; i < m->numchats; i++) { | ||
3442 | if (m->chats[i]) { | ||
3443 | ret++; | ||
3444 | } | ||
3445 | } | ||
3446 | |||
3447 | return ret; | ||
3448 | } | ||
3449 | |||
3450 | /* Copy a list of valid chat IDs into the array out_list. | ||
3451 | * If out_list is NULL, returns 0. | ||
3452 | * Otherwise, returns the number of elements copied. | ||
3453 | * If the array was too small, the contents | ||
3454 | * of out_list will be truncated to list_size. */ | ||
3455 | uint32_t copy_chatlist(const Messenger *m, int *out_list, uint32_t list_size) | ||
3456 | { | ||
3457 | if (!out_list) | ||
3458 | return 0; | ||
3459 | |||
3460 | if (m->numchats == 0) { | ||
3461 | return 0; | ||
3462 | } | ||
3463 | |||
3464 | uint32_t i; | ||
3465 | uint32_t ret = 0; | ||
3466 | |||
3467 | for (i = 0; i < m->numchats; i++) { | ||
3468 | if (ret >= list_size) { | ||
3469 | break; /* Abandon ship */ | ||
3470 | } | ||
3471 | |||
3472 | if (m->chats[i]) { | ||
3473 | out_list[ret] = i; | ||
3474 | ret++; | ||
3475 | } | ||
3476 | } | ||
3477 | |||
3478 | return ret; | ||
3479 | } | ||