@@ -271,6 +271,7 @@ typedef enum Groupchat_Closest {
271
271
272
272
static int add_to_closest (Group_Chats * g_c , uint32_t groupnumber , const uint8_t * real_pk , const uint8_t * temp_pk )
273
273
{
274
+ // TODO(zugz): this can be const. Similarly throughout the file.
274
275
Group_c * g = get_group_c (g_c , groupnumber );
275
276
276
277
if (!g ) {
@@ -1033,19 +1034,26 @@ int add_groupchat(Group_Chats *g_c, uint8_t type)
1033
1034
return groupnumber ;
1034
1035
}
1035
1036
1036
- /* Delete a groupchat from the chats array.
1037
+ static int group_leave (const Group_Chats * g_c , uint32_t groupnumber );
1038
+
1039
+ /* Delete a groupchat from the chats array, informing the group first as
1040
+ * appropriate.
1037
1041
*
1038
1042
* return 0 on success.
1039
1043
* return -1 if groupnumber is invalid.
1040
1044
*/
1041
- int del_groupchat (Group_Chats * g_c , uint32_t groupnumber )
1045
+ int del_groupchat (Group_Chats * g_c , uint32_t groupnumber , bool leave_permanently )
1042
1046
{
1043
1047
Group_c * g = get_group_c (g_c , groupnumber );
1044
1048
1045
1049
if (!g ) {
1046
1050
return -1 ;
1047
1051
}
1048
1052
1053
+ if (leave_permanently ) {
1054
+ group_leave (g_c , groupnumber );
1055
+ }
1056
+
1049
1057
for (uint32_t i = 0 ; i < MAX_GROUP_CONNECTIONS ; ++ i ) {
1050
1058
if (g -> close [i ].type == GROUPCHAT_CLOSE_NONE ) {
1051
1059
continue ;
@@ -1071,82 +1079,115 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber)
1071
1079
return wipe_group_chat (g_c , groupnumber );
1072
1080
}
1073
1081
1074
- /* Copy the public key of peernumber who is in groupnumber to pk.
1075
- * pk must be CRYPTO_PUBLIC_KEY_SIZE long.
1082
+ /* Copy the public key of (frozen, if frozen is true) peernumber who is in
1083
+ * groupnumber to pk. pk must be CRYPTO_PUBLIC_KEY_SIZE long.
1076
1084
*
1077
1085
* return 0 on success
1078
1086
* return -1 if groupnumber is invalid.
1079
1087
* return -2 if peernumber is invalid.
1080
1088
*/
1081
- int group_peer_pubkey (const Group_Chats * g_c , uint32_t groupnumber , int peernumber , uint8_t * pk )
1089
+ int group_peer_pubkey (const Group_Chats * g_c , uint32_t groupnumber , int peernumber , uint8_t * pk , bool frozen )
1082
1090
{
1083
1091
Group_c * g = get_group_c (g_c , groupnumber );
1084
1092
1085
1093
if (!g ) {
1086
1094
return -1 ;
1087
1095
}
1088
1096
1089
- if ((uint32_t )peernumber >= g -> numpeers ) {
1097
+ const Group_Peer * list = frozen ? g -> frozen : g -> group ;
1098
+ const uint32_t num = frozen ? g -> numfrozen : g -> numpeers ;
1099
+
1100
+ if ((uint32_t )peernumber >= num ) {
1090
1101
return -2 ;
1091
1102
}
1092
1103
1093
- memcpy (pk , g -> group [peernumber ].real_pk , CRYPTO_PUBLIC_KEY_SIZE );
1104
+ memcpy (pk , list [peernumber ].real_pk , CRYPTO_PUBLIC_KEY_SIZE );
1094
1105
return 0 ;
1095
1106
}
1096
1107
1097
1108
/*
1098
- * Return the size of peernumber's name.
1109
+ * Return the size of (frozen, if frozen is true) peernumber's name.
1099
1110
*
1100
1111
* return -1 if groupnumber is invalid.
1101
1112
* return -2 if peernumber is invalid.
1102
1113
*/
1103
- int group_peername_size (const Group_Chats * g_c , uint32_t groupnumber , int peernumber )
1114
+ int group_peername_size (const Group_Chats * g_c , uint32_t groupnumber , int peernumber , bool frozen )
1104
1115
{
1105
1116
Group_c * g = get_group_c (g_c , groupnumber );
1106
1117
1107
1118
if (!g ) {
1108
1119
return -1 ;
1109
1120
}
1110
1121
1111
- if ((uint32_t )peernumber >= g -> numpeers ) {
1122
+ const Group_Peer * list = frozen ? g -> frozen : g -> group ;
1123
+ const uint32_t num = frozen ? g -> numfrozen : g -> numpeers ;
1124
+
1125
+ if ((uint32_t )peernumber >= num ) {
1112
1126
return -2 ;
1113
1127
}
1114
1128
1115
- if (g -> group [peernumber ].nick_len == 0 ) {
1129
+ if (list [peernumber ].nick_len == 0 ) {
1116
1130
return 0 ;
1117
1131
}
1118
1132
1119
- return g -> group [peernumber ].nick_len ;
1133
+ return list [peernumber ].nick_len ;
1120
1134
}
1121
1135
1122
- /* Copy the name of peernumber who is in groupnumber to name.
1123
- * name must be at least MAX_NAME_LENGTH long.
1136
+ /* Copy the name of (frozen, if frozen is true) peernumber who is in
1137
+ * groupnumber to name. name must be at least MAX_NAME_LENGTH long.
1124
1138
*
1125
1139
* return length of name if success
1126
1140
* return -1 if groupnumber is invalid.
1127
1141
* return -2 if peernumber is invalid.
1128
1142
*/
1129
- int group_peername (const Group_Chats * g_c , uint32_t groupnumber , int peernumber , uint8_t * name )
1143
+ int group_peername (const Group_Chats * g_c , uint32_t groupnumber , int peernumber , uint8_t * name , bool frozen )
1130
1144
{
1131
1145
Group_c * g = get_group_c (g_c , groupnumber );
1132
1146
1133
1147
if (!g ) {
1134
1148
return -1 ;
1135
1149
}
1136
1150
1137
- if ((uint32_t )peernumber >= g -> numpeers ) {
1151
+ const Group_Peer * list = frozen ? g -> frozen : g -> group ;
1152
+ const uint32_t num = frozen ? g -> numfrozen : g -> numpeers ;
1153
+
1154
+ if ((uint32_t )peernumber >= num ) {
1138
1155
return -2 ;
1139
1156
}
1140
1157
1141
- if (g -> group [peernumber ].nick_len == 0 ) {
1158
+ if (list [peernumber ].nick_len == 0 ) {
1142
1159
return 0 ;
1143
1160
}
1144
1161
1145
- memcpy (name , g -> group [peernumber ].nick , g -> group [peernumber ].nick_len );
1146
- return g -> group [peernumber ].nick_len ;
1162
+ memcpy (name , list [peernumber ].nick , list [peernumber ].nick_len );
1163
+ return list [peernumber ].nick_len ;
1147
1164
}
1148
1165
1149
- /* List all the peers in the group chat.
1166
+ /* Copy last active timestamp of frozennumber who is in groupnumber to
1167
+ * last_active.
1168
+ *
1169
+ * return 0 on success.
1170
+ * return -1 if groupnumber is invalid.
1171
+ * return -2 if frozennumber is invalid.
1172
+ */
1173
+ int group_frozen_last_active (const Group_Chats * g_c , uint32_t groupnumber , int peernumber ,
1174
+ uint64_t * last_active )
1175
+ {
1176
+ Group_c * g = get_group_c (g_c , groupnumber );
1177
+
1178
+ if (!g ) {
1179
+ return -1 ;
1180
+ }
1181
+
1182
+ if ((uint32_t )peernumber >= g -> numfrozen ) {
1183
+ return -2 ;
1184
+ }
1185
+
1186
+ * last_active = g -> frozen [peernumber ].last_active ;
1187
+ return 0 ;
1188
+ }
1189
+
1190
+ /* List all the (frozen, if frozen is true) peers in the group chat.
1150
1191
*
1151
1192
* Copies the names of the peers to the name[length][MAX_NAME_LENGTH] array.
1152
1193
*
@@ -1157,35 +1198,38 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber,
1157
1198
* return -1 on failure.
1158
1199
*/
1159
1200
int group_names (const Group_Chats * g_c , uint32_t groupnumber , uint8_t names [][MAX_NAME_LENGTH ], uint16_t lengths [],
1160
- uint16_t length )
1201
+ uint16_t length , bool frozen )
1161
1202
{
1162
1203
Group_c * g = get_group_c (g_c , groupnumber );
1163
1204
1164
1205
if (!g ) {
1165
1206
return -1 ;
1166
1207
}
1167
1208
1209
+ const uint32_t num = frozen ? g -> numfrozen : g -> numpeers ;
1210
+
1168
1211
unsigned int i ;
1169
1212
1170
- for (i = 0 ; i < g -> numpeers && i < length ; ++ i ) {
1171
- lengths [i ] = group_peername (g_c , groupnumber , i , names [i ]);
1213
+ for (i = 0 ; i < num && i < length ; ++ i ) {
1214
+ lengths [i ] = group_peername (g_c , groupnumber , i , names [i ], frozen );
1172
1215
}
1173
1216
1174
1217
return i ;
1175
1218
}
1176
1219
1177
- /* Return the number of peers in the group chat on success.
1220
+ /* Return the number of (frozen, if frozen is true) peers in the group chat on
1221
+ * success.
1178
1222
* return -1 if groupnumber is invalid.
1179
1223
*/
1180
- int group_number_peers (const Group_Chats * g_c , uint32_t groupnumber )
1224
+ int group_number_peers (const Group_Chats * g_c , uint32_t groupnumber , bool frozen )
1181
1225
{
1182
1226
Group_c * g = get_group_c (g_c , groupnumber );
1183
1227
1184
1228
if (!g ) {
1185
1229
return -1 ;
1186
1230
}
1187
1231
1188
- return g -> numpeers ;
1232
+ return frozen ? g -> numfrozen : g -> numpeers ;
1189
1233
}
1190
1234
1191
1235
/* return 1 if the peernumber corresponds to ours.
@@ -1597,18 +1641,18 @@ static int group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const u
1597
1641
}
1598
1642
1599
1643
/* send message to announce leaving group
1600
- * return true on success
1601
- * return false on failure
1644
+ * return 0 on success
1645
+ * return -1 on failure
1602
1646
*/
1603
- bool group_leave (const Group_Chats * g_c , uint32_t groupnumber )
1647
+ static int group_leave (const Group_Chats * g_c , uint32_t groupnumber )
1604
1648
{
1605
1649
Group_c * g = get_group_c (g_c , groupnumber );
1606
1650
1607
1651
if (!g ) {
1608
- return false ;
1652
+ return -1 ;
1609
1653
}
1610
1654
1611
- return group_kill_peer_send (g_c , groupnumber , g -> peer_number ) == 0 ;
1655
+ return group_kill_peer_send (g_c , groupnumber , g -> peer_number );
1612
1656
}
1613
1657
1614
1658
@@ -2900,7 +2944,7 @@ void send_name_all_groups(Group_Chats *g_c)
2900
2944
}
2901
2945
}
2902
2946
2903
- #define SAVED_PEER_SIZE_CONSTANT (2 * CRYPTO_PUBLIC_KEY_SIZE + 2 + 1)
2947
+ #define SAVED_PEER_SIZE_CONSTANT (2 * CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint16_t) + sizeof(uint64_t) + 1)
2904
2948
2905
2949
static uint32_t saved_peer_size (const Group_Peer * peer )
2906
2950
{
@@ -2918,6 +2962,9 @@ static uint8_t *save_peer(const Group_Peer *peer, uint8_t *data)
2918
2962
host_to_lendian_bytes16 (data , peer -> peer_number );
2919
2963
data += sizeof (uint16_t );
2920
2964
2965
+ host_to_lendian_bytes64 (data , peer -> last_active );
2966
+ data += sizeof (uint64_t );
2967
+
2921
2968
* data = peer -> nick_len ;
2922
2969
++ data ;
2923
2970
@@ -3098,6 +3145,9 @@ static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data,
3098
3145
lendian_bytes_to_host16 (& peer -> peer_number , data );
3099
3146
data += sizeof (uint16_t );
3100
3147
3148
+ lendian_bytes_to_host64 (& peer -> last_active , data );
3149
+ data += sizeof (uint64_t );
3150
+
3101
3151
peer -> nick_len = * data ;
3102
3152
++ data ;
3103
3153
@@ -3189,7 +3239,7 @@ void do_groupchats(Group_Chats *g_c, void *userdata)
3189
3239
void kill_groupchats (Group_Chats * g_c )
3190
3240
{
3191
3241
for (uint16_t i = 0 ; i < g_c -> num_chats ; ++ i ) {
3192
- del_groupchat (g_c , i );
3242
+ del_groupchat (g_c , i , false );
3193
3243
}
3194
3244
3195
3245
m_callback_conference_invite (g_c -> m , nullptr );
0 commit comments