27
27
28
28
#define RPL_WHOISKEYVALUE 760
29
29
#define RPL_KEYVALUE 761
30
- #define RPL_METADATAEND 762
31
30
#define RPL_KEYNOTSET 766
32
31
#define RPL_METADATASUBOK 770
33
32
#define RPL_METADATAUNSUBOK 771
36
35
37
36
#define STR_RPL_WHOISKEYVALUE /* 760 */ "%s %s %s :%s"
38
37
#define STR_RPL_KEYVALUE /* 761 */ "%s %s %s :%s"
39
- #define STR_RPL_METADATAEND /* 762 */ ":end of metadata"
40
38
#define STR_RPL_KEYNOTSET /* 766 */ "%s %s :no matching key"
41
39
#define STR_RPL_METADATASUBOK /* 770 */ ":%s"
42
40
#define STR_RPL_METADATAUNSUBOK /* 771 */ ":%s"
@@ -113,6 +111,36 @@ module
113
111
#define USER_METADATA (client ) moddata_client(client, metadataUser).ptr
114
112
#define CHANNEL_METADATA (channel ) moddata_channel(channel, metadataChannel).ptr
115
113
114
+
115
+ #if defined(__GNUC__ )
116
+ #define PUSH_IGNORE_ADDRESS \
117
+ _Pragma("GCC diagnostic push") \
118
+ _Pragma("GCC diagnostic ignored \"-Waddress\"")
119
+ #define POP_IGNORE_ADDRESS \
120
+ _Pragma("GCC diagnostic pop")
121
+ #else
122
+ #define PUSH_IGNORE_ADDRESS
123
+ #define POP_IGNORE_ADDRESS
124
+ #endif
125
+
126
+ #define batched (func , client , batch_id , ...) \
127
+ { \
128
+ MessageTag *mtags = NULL; \
129
+ MessageTag *m; \
130
+ PUSH_IGNORE_ADDRESS /* -Waddress warns when batch_id is an array */ \
131
+ if (!BadPtr (batch_id )) \
132
+ POP_IGNORE_ADDRESS \
133
+ { \
134
+ mtags = safe_alloc (sizeof (MessageTag )); \
135
+ mtags -> name = strdup ("batch" ); \
136
+ mtags -> value = strdup (batchid ); \
137
+ } \
138
+ func (client , mtags , ##__VA_ARGS__ ); \
139
+ if (mtags ) \
140
+ free_message_tags (mtags ); \
141
+ }
142
+
143
+
116
144
struct metadata {
117
145
char * name ;
118
146
char * value ;
@@ -161,8 +189,8 @@ void metadata_free_list(struct metadata *metadata, const char *whose, Client *cl
161
189
struct metadata_moddata_user * metadata_prepare_user_moddata (Client * user );
162
190
void metadata_set_channel (Channel * channel , const char * key , const char * value , Client * client );
163
191
void metadata_set_user (Client * user , const char * key , const char * value , Client * client );
164
- void metadata_send_channel (Channel * channel , const char * key , Client * client );
165
- void metadata_send_user (Client * user , const char * key , Client * client );
192
+ void metadata_send_channel (Channel * channel , const char * key , Client * client , const char * batchid );
193
+ void metadata_send_user (Client * user , const char * key , Client * client , const char * batchid );
166
194
int metadata_subscribe (const char * key , Client * client , int remove );
167
195
void metadata_clear_channel (Channel * channel , Client * client );
168
196
void metadata_clear_user (Client * user , Client * client );
@@ -915,7 +943,7 @@ int metadata_subscribe(const char *key, Client *client, int remove)
915
943
return 0 ;
916
944
}
917
945
918
- void metadata_send_channel (Channel * channel , const char * key , Client * client )
946
+ void metadata_send_channel (Channel * channel , const char * key , Client * client , const char * batchid )
919
947
{
920
948
struct metadata * metadata ;
921
949
int found = 0 ;
@@ -924,15 +952,15 @@ void metadata_send_channel(Channel *channel, const char *key, Client *client)
924
952
if (!strcasecmp (key , metadata -> name ))
925
953
{
926
954
found = 1 ;
927
- sendnumeric ( client , RPL_KEYVALUE , channel -> name , key , "*" , metadata -> value );
955
+ batched ( sendtaggednumeric , client , batchid , RPL_KEYVALUE , channel -> name , key , "*" , metadata -> value );
928
956
break ;
929
957
}
930
958
}
931
959
if (!found )
932
- sendnumeric ( client , RPL_KEYNOTSET , channel -> name , key );
960
+ batched ( sendtaggednumeric , client , batchid , RPL_KEYNOTSET , channel -> name , key );
933
961
}
934
962
935
- void metadata_send_user (Client * user , const char * key , Client * client )
963
+ void metadata_send_user (Client * user , const char * key , Client * client , const char * batchid )
936
964
{
937
965
if (!user )
938
966
user = client ;
@@ -946,12 +974,12 @@ void metadata_send_user(Client *user, const char *key, Client *client)
946
974
if (!strcasecmp (key , metadata -> name ))
947
975
{
948
976
found = 1 ;
949
- sendnumeric ( client , RPL_KEYVALUE , user -> name , key , "*" , metadata -> value );
977
+ batched ( sendtaggednumeric , client , batchid , RPL_KEYVALUE , user -> name , key , "*" , metadata -> value );
950
978
break ;
951
979
}
952
980
}
953
981
if (!found )
954
- sendnumeric ( client , RPL_KEYNOTSET , user -> name , key );
982
+ batched ( sendtaggednumeric , client , batchid , RPL_KEYNOTSET , user -> name , key );
955
983
}
956
984
957
985
void metadata_clear_channel (Channel * channel , Client * client )
@@ -987,20 +1015,33 @@ void metadata_send_subscribtions(Client *client)
987
1015
void metadata_send_all_for_channel (Channel * channel , Client * client )
988
1016
{
989
1017
struct metadata * metadata ;
1018
+ char batchid [BATCHLEN + 1 ];
1019
+
1020
+ generate_batch_id (batchid );
1021
+
1022
+ sendto_one (client , NULL , ":%s BATCH +%s metadata" , me .name , batchid );
990
1023
for (metadata = CHANNEL_METADATA (channel ); metadata ; metadata = metadata -> next )
991
- sendnumeric (client , RPL_KEYVALUE , channel -> name , metadata -> name , "*" , metadata -> value );
1024
+ batched (sendtaggednumeric , client , batchid , RPL_KEYVALUE , channel -> name , metadata -> name , "*" , metadata -> value );
1025
+ sendto_one (client , NULL , ":%s BATCH -%s" , me .name , batchid );
992
1026
}
993
1027
994
1028
void metadata_send_all_for_user (Client * user , Client * client )
995
1029
{
996
1030
struct metadata * metadata ;
1031
+ char batchid [BATCHLEN + 1 ];
1032
+
1033
+ generate_batch_id (batchid );
1034
+
997
1035
if (!user )
998
1036
user = client ;
999
1037
struct metadata_moddata_user * moddata = USER_METADATA (user );
1000
- if (!moddata )
1001
- return ;
1002
- for (metadata = moddata -> metadata ; metadata ; metadata = metadata -> next )
1003
- sendnumeric (client , RPL_KEYVALUE , user -> name , metadata -> name , "*" , metadata -> value );
1038
+
1039
+ sendto_one (client , NULL , ":%s BATCH +%s metadata" , me .name , batchid );
1040
+ if (moddata ) {
1041
+ for (metadata = moddata -> metadata ; metadata ; metadata = metadata -> next )
1042
+ batched (sendtaggednumeric , client , batchid , RPL_KEYVALUE , user -> name , metadata -> name , "*" , metadata -> value );
1043
+ }
1044
+ sendto_one (client , NULL , ":%s BATCH -%s" , me .name , batchid );
1004
1045
}
1005
1046
1006
1047
int metadata_key_valid (const char * key )
@@ -1065,6 +1106,7 @@ CMD_FUNC(cmd_metadata_local)
1065
1106
const char * value = NULL ;
1066
1107
int keyindex = 3 - 1 ;
1067
1108
char * channame ;
1109
+ char batchid [BATCHLEN - 1 ];
1068
1110
1069
1111
CHECKPARAMSCNT_OR_DIE (2 , return );
1070
1112
@@ -1076,21 +1118,24 @@ CMD_FUNC(cmd_metadata_local)
1076
1118
CHECKREGISTERED_OR_DIE (client , return );
1077
1119
CHECKPARAMSCNT_OR_DIE (3 , return );
1078
1120
PROCESS_TARGET_OR_DIE (target , user , channel , return );
1121
+ generate_batch_id (batchid );
1122
+ sendto_one (client , NULL , ":%s BATCH +%s metadata" , me .name , batchid );
1079
1123
FOR_EACH_KEY (keyindex , parc , parv )
1080
1124
{
1081
1125
if (metadata_check_perms (user , channel , client , key , MODE_GET ))
1082
1126
{
1083
1127
if (!metadata_key_valid (key ))
1084
1128
{
1085
- sendto_one ( client , NULL , STR_FAIL_INVALID_KEY , me .name , key );
1129
+ batched ( sendto_one , client , batchid , STR_FAIL_INVALID_KEY , me .name , key );
1086
1130
continue ;
1087
1131
}
1088
1132
if (channel )
1089
- metadata_send_channel (channel , key , client );
1133
+ metadata_send_channel (channel , key , client , batchid );
1090
1134
else
1091
- metadata_send_user (user , key , client );
1135
+ metadata_send_user (user , key , client , batchid );
1092
1136
}
1093
1137
}
1138
+ sendto_one (client , NULL , ":%s BATCH -%s" , me .name , batchid );
1094
1139
} else if (!strcasecmp (cmd , "LIST" ))
1095
1140
{ /* we're just not sending anything if there are no permissions */
1096
1141
CHECKREGISTERED_OR_DIE (client , return );
@@ -1102,7 +1147,6 @@ CMD_FUNC(cmd_metadata_local)
1102
1147
else
1103
1148
metadata_send_all_for_user (user , client );
1104
1149
}
1105
- sendnumeric (client , RPL_METADATAEND );
1106
1150
} else if (!strcasecmp (cmd , "SET" ))
1107
1151
{
1108
1152
CHECKPARAMSCNT_OR_DIE (3 , return );
@@ -1134,7 +1178,6 @@ CMD_FUNC(cmd_metadata_local)
1134
1178
else
1135
1179
metadata_clear_user (user , client );
1136
1180
}
1137
- sendnumeric (client , RPL_METADATAEND );
1138
1181
} else if (!strcasecmp (cmd , "SUB" ))
1139
1182
{
1140
1183
PROCESS_TARGET_OR_DIE (target , user , channel , return );
@@ -1150,7 +1193,6 @@ CMD_FUNC(cmd_metadata_local)
1150
1193
continue ;
1151
1194
}
1152
1195
}
1153
- sendnumeric (client , RPL_METADATAEND );
1154
1196
} else if (!strcasecmp (cmd , "UNSUB" ))
1155
1197
{
1156
1198
CHECKREGISTERED_OR_DIE (client , return );
@@ -1167,12 +1209,10 @@ CMD_FUNC(cmd_metadata_local)
1167
1209
continue ;
1168
1210
}
1169
1211
}
1170
- sendnumeric (client , RPL_METADATAEND );
1171
1212
} else if (!strcasecmp (cmd , "SUBS" ))
1172
1213
{
1173
1214
CHECKREGISTERED_OR_DIE (client , return );
1174
1215
metadata_send_subscribtions (client );
1175
- sendnumeric (client , RPL_METADATAEND );
1176
1216
} else if (!strcasecmp (cmd , "SYNC" ))
1177
1217
{ /* the SYNC command is ignored, as we're using events to send out the queue - only validate the params */
1178
1218
CHECKREGISTERED_OR_DIE (client , return );
0 commit comments