mirror of
https://github.com/profanity-im/profanity.git
synced 2024-11-03 19:37:16 -05:00
Merge branch 'master' into pgp
This commit is contained in:
commit
c1eceebcba
@ -1878,7 +1878,7 @@ cmd_info(gchar **args, struct cmd_help_t help)
|
||||
}
|
||||
} else {
|
||||
ProfMucWin *mucwin = wins_get_current_muc();
|
||||
iq_room_info_request(mucwin->roomjid);
|
||||
iq_room_info_request(mucwin->roomjid, TRUE);
|
||||
ui_show_room_info(mucwin);
|
||||
return TRUE;
|
||||
}
|
||||
|
27
src/muc.c
27
src/muc.c
@ -62,6 +62,7 @@ typedef struct _muc_room_t {
|
||||
Autocomplete jid_ac;
|
||||
GHashTable *nick_changes;
|
||||
gboolean roster_received;
|
||||
muc_member_type_t member_type;
|
||||
} ChatRoom;
|
||||
|
||||
GHashTable *rooms = NULL;
|
||||
@ -177,6 +178,7 @@ muc_join(const char * const room, const char * const nick,
|
||||
new_room->roster_received = FALSE;
|
||||
new_room->pending_nick_change = FALSE;
|
||||
new_room->autojoin = autojoin;
|
||||
new_room->member_type = MUC_MEMBER_TYPE_UNKNOWN;
|
||||
|
||||
g_hash_table_insert(rooms, strdup(room), new_room);
|
||||
}
|
||||
@ -208,6 +210,19 @@ muc_set_requires_config(const char * const room, gboolean val)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
muc_set_features(const char * const room, GSList *features)
|
||||
{
|
||||
ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
|
||||
if (chat_room && features) {
|
||||
if (g_slist_find_custom(features, "muc_membersonly", (GCompareFunc)g_strcmp0)) {
|
||||
chat_room->member_type = MUC_MEMBER_TYPE_MEMBERS_ONLY;
|
||||
} else {
|
||||
chat_room->member_type = MUC_MEMBER_TYPE_PUBLIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if the user is currently in the room
|
||||
*/
|
||||
@ -763,6 +778,18 @@ muc_set_affiliation(const char * const room, const char * const affiliation)
|
||||
}
|
||||
}
|
||||
|
||||
muc_member_type_t
|
||||
muc_member_type(const char * const room)
|
||||
{
|
||||
ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
|
||||
if (chat_room) {
|
||||
return chat_room->member_type;
|
||||
} else {
|
||||
return MUC_MEMBER_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_free_room(ChatRoom *room)
|
||||
{
|
||||
|
10
src/muc.h
10
src/muc.h
@ -56,6 +56,12 @@ typedef enum {
|
||||
MUC_AFFILIATION_OWNER
|
||||
} muc_affiliation_t;
|
||||
|
||||
typedef enum {
|
||||
MUC_MEMBER_TYPE_UNKNOWN,
|
||||
MUC_MEMBER_TYPE_PUBLIC,
|
||||
MUC_MEMBER_TYPE_MEMBERS_ONLY
|
||||
} muc_member_type_t;
|
||||
|
||||
typedef struct _muc_occupant_t {
|
||||
char *nick;
|
||||
char *jid;
|
||||
@ -76,6 +82,8 @@ gboolean muc_autojoin(const char * const room);
|
||||
|
||||
GList* muc_rooms(void);
|
||||
|
||||
void muc_set_features(const char * const room, GSList *features);
|
||||
|
||||
char* muc_nick(const char * const room);
|
||||
char* muc_password(const char * const room);
|
||||
|
||||
@ -134,4 +142,6 @@ void muc_set_affiliation(const char * const room, const char * const affiliation
|
||||
char *muc_role_str(const char * const room);
|
||||
char *muc_affiliation_str(const char * const room);
|
||||
|
||||
muc_member_type_t muc_member_type(const char * const room);
|
||||
|
||||
#endif
|
||||
|
@ -162,9 +162,12 @@ handle_disco_info(const char *from, GSList *identities, GSList *features)
|
||||
}
|
||||
|
||||
void
|
||||
handle_room_disco_info(const char * const room, GSList *identities, GSList *features)
|
||||
handle_room_disco_info(const char * const room, GSList *identities, GSList *features, gboolean display)
|
||||
{
|
||||
ui_show_room_disco_info(room, identities, features);
|
||||
muc_set_features(room, features);
|
||||
if (display) {
|
||||
ui_show_room_disco_info(room, identities, features);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -697,6 +700,9 @@ handle_muc_self_online(const char * const room, const char * const nick, gboolea
|
||||
} else {
|
||||
ui_room_join(room, TRUE);
|
||||
}
|
||||
|
||||
iq_room_info_request(room, FALSE);
|
||||
|
||||
muc_invites_remove(room);
|
||||
muc_roster_set_complete(room);
|
||||
|
||||
|
@ -58,7 +58,7 @@ void handle_room_message(const char * const room_jid, const char * const nick,
|
||||
const char * const message);
|
||||
void handle_room_join_error(const char * const room, const char * const err);
|
||||
void handle_room_info_error(const char * const room, const char * const error);
|
||||
void handle_room_disco_info(const char * const room, GSList *identities, GSList *features);
|
||||
void handle_room_disco_info(const char * const room, GSList *identities, GSList *features, gboolean display);
|
||||
void handle_room_affiliation_list_result_error(const char * const room, const char * const affiliation,
|
||||
const char * const error);
|
||||
void handle_room_affiliation_list(const char * const room, const char * const affiliation, GSList *jids);
|
||||
|
118
src/xmpp/iq.c
118
src/xmpp/iq.c
@ -58,11 +58,17 @@
|
||||
|
||||
#define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_IQ, type, ctx)
|
||||
|
||||
typedef struct p_room_info_data_t {
|
||||
char *room;
|
||||
gboolean display;
|
||||
} ProfRoomInfoData;
|
||||
|
||||
static int _error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _ping_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _version_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||
@ -178,14 +184,18 @@ iq_disco_info_request(gchar *jid)
|
||||
}
|
||||
|
||||
void
|
||||
iq_room_info_request(gchar *room)
|
||||
iq_room_info_request(const char * const room, gboolean display_result)
|
||||
{
|
||||
xmpp_conn_t * const conn = connection_get_conn();
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
char *id = create_unique_id("room_disco_info");
|
||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, room, NULL);
|
||||
|
||||
xmpp_id_handler_add(conn, _disco_info_response_handler, id, room);
|
||||
ProfRoomInfoData *cb_data = malloc(sizeof(ProfRoomInfoData));
|
||||
cb_data->room = strdup(room);
|
||||
cb_data->display = display_result;
|
||||
|
||||
xmpp_id_handler_add(conn, _room_info_response_handler, id, cb_data);
|
||||
|
||||
free(id);
|
||||
|
||||
@ -1337,6 +1347,82 @@ _item_destroy(DiscoItem *item)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
{
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
ProfRoomInfoData *cb_data = (ProfRoomInfoData *)userdata;
|
||||
log_info("Received diso#info response for room: %s", cb_data->room);
|
||||
|
||||
// handle error responses
|
||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||
if (cb_data->display) {
|
||||
char *error_message = stanza_get_error_message(stanza);
|
||||
handle_room_info_error(cb_data->room, error_message);
|
||||
free(error_message);
|
||||
}
|
||||
free(cb_data->room);
|
||||
free(cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||
|
||||
if (query != NULL) {
|
||||
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
||||
GSList *identities = NULL;
|
||||
GSList *features = NULL;
|
||||
while (child != NULL) {
|
||||
const char *stanza_name = xmpp_stanza_get_name(child);
|
||||
if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) {
|
||||
const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR);
|
||||
if (var != NULL) {
|
||||
features = g_slist_append(features, strdup(var));
|
||||
}
|
||||
} else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) {
|
||||
const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME);
|
||||
const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE);
|
||||
const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY);
|
||||
|
||||
if ((name != NULL) || (category != NULL) || (type != NULL)) {
|
||||
DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t));
|
||||
|
||||
if (name != NULL) {
|
||||
identity->name = strdup(name);
|
||||
} else {
|
||||
identity->name = NULL;
|
||||
}
|
||||
if (category != NULL) {
|
||||
identity->category = strdup(category);
|
||||
} else {
|
||||
identity->category = NULL;
|
||||
}
|
||||
if (type != NULL) {
|
||||
identity->type = strdup(type);
|
||||
} else {
|
||||
identity->type = NULL;
|
||||
}
|
||||
|
||||
identities = g_slist_append(identities, identity);
|
||||
}
|
||||
}
|
||||
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
handle_room_disco_info(cb_data->room, identities, features, cb_data->display);
|
||||
|
||||
g_slist_free_full(features, free);
|
||||
g_slist_free_full(identities, (GDestroyNotify)_identity_destroy);
|
||||
}
|
||||
|
||||
free(cb_data->room);
|
||||
free(cb_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
@ -1344,27 +1430,16 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta
|
||||
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
|
||||
char *room = NULL;
|
||||
if (userdata) {
|
||||
room = (char *) userdata;
|
||||
log_info("Received diso#info response for room: %s", room);
|
||||
if (from) {
|
||||
log_info("Received diso#info response from: %s", from);
|
||||
} else {
|
||||
room = NULL;
|
||||
if (from) {
|
||||
log_info("Received diso#info response from: %s", from);
|
||||
} else {
|
||||
log_info("Received diso#info response");
|
||||
}
|
||||
log_info("Received diso#info response");
|
||||
}
|
||||
|
||||
// handle error responses
|
||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||
char *error_message = stanza_get_error_message(stanza);
|
||||
if (room) {
|
||||
handle_room_info_error(room, error_message);
|
||||
} else {
|
||||
handle_disco_info_error(from, error_message);
|
||||
}
|
||||
handle_disco_info_error(from, error_message);
|
||||
free(error_message);
|
||||
return 0;
|
||||
}
|
||||
@ -1413,16 +1488,13 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
if (room) {
|
||||
handle_room_disco_info(room, identities, features);
|
||||
} else {
|
||||
handle_disco_info(from, identities, features);
|
||||
}
|
||||
handle_disco_info(from, identities, features);
|
||||
|
||||
g_slist_free_full(features, free);
|
||||
g_slist_free_full(identities, (GDestroyNotify)_identity_destroy);
|
||||
}
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -232,7 +232,16 @@ message_send_invite(const char * const roomjid, const char * const contact,
|
||||
{
|
||||
xmpp_conn_t * const conn = connection_get_conn();
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *stanza = stanza_create_invite(ctx, roomjid, contact, reason);
|
||||
xmpp_stanza_t *stanza;
|
||||
|
||||
muc_member_type_t member_type = muc_member_type(roomjid);
|
||||
if (member_type == MUC_MEMBER_TYPE_PUBLIC) {
|
||||
log_debug("Sending direct invite to %s, for %s", contact, roomjid);
|
||||
stanza = stanza_create_invite(ctx, roomjid, contact, reason);
|
||||
} else {
|
||||
log_debug("Sending mediated invite to %s, for %s", contact, roomjid);
|
||||
stanza = stanza_create_mediated_invite(ctx, roomjid, contact, reason);
|
||||
}
|
||||
|
||||
xmpp_send(conn, stanza);
|
||||
xmpp_stanza_release(stanza);
|
||||
|
@ -440,6 +440,46 @@ stanza_create_invite(xmpp_ctx_t *ctx, const char * const room,
|
||||
return message;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *
|
||||
stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const room,
|
||||
const char * const contact, const char * const reason)
|
||||
{
|
||||
xmpp_stanza_t *message, *x, *invite;
|
||||
|
||||
message = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(message, STANZA_NAME_MESSAGE);
|
||||
xmpp_stanza_set_attribute(message, STANZA_ATTR_TO, room);
|
||||
char *id = create_unique_id(NULL);
|
||||
xmpp_stanza_set_id(message, id);
|
||||
free(id);
|
||||
|
||||
x = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(x, STANZA_NAME_X);
|
||||
xmpp_stanza_set_ns(x, STANZA_NS_MUC_USER);
|
||||
|
||||
invite = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(invite, STANZA_NAME_INVITE);
|
||||
xmpp_stanza_set_attribute(invite, STANZA_ATTR_TO, contact);
|
||||
|
||||
if (reason != NULL) {
|
||||
xmpp_stanza_t *reason_st = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(reason_st, STANZA_NAME_REASON);
|
||||
xmpp_stanza_t *reason_txt = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_text(reason_txt, reason);
|
||||
xmpp_stanza_add_child(reason_st, reason_txt);
|
||||
xmpp_stanza_release(reason_txt);
|
||||
xmpp_stanza_add_child(invite, reason_st);
|
||||
xmpp_stanza_release(reason_st);
|
||||
}
|
||||
|
||||
xmpp_stanza_add_child(x, invite);
|
||||
xmpp_stanza_release(invite);
|
||||
xmpp_stanza_add_child(message, x);
|
||||
xmpp_stanza_release(x);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *
|
||||
stanza_create_room_join_presence(xmpp_ctx_t * const ctx,
|
||||
const char * const full_room_jid, const char * const passwd)
|
||||
|
@ -217,6 +217,8 @@ xmpp_stanza_t* stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const i
|
||||
|
||||
xmpp_stanza_t* stanza_create_invite(xmpp_ctx_t *ctx, const char * const room,
|
||||
const char * const contact, const char * const reason);
|
||||
xmpp_stanza_t* stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const room,
|
||||
const char * const contact, const char * const reason);
|
||||
|
||||
gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza);
|
||||
|
||||
|
@ -192,7 +192,7 @@ void iq_send_caps_request_for_jid(const char * const to, const char * const id,
|
||||
const char * const node, const char * const ver);
|
||||
void iq_send_caps_request_legacy(const char * const to, const char * const id,
|
||||
const char * const node, const char * const ver);
|
||||
void iq_room_info_request(gchar *room);
|
||||
void iq_room_info_request(const char * const room, gboolean display_result);
|
||||
void iq_room_affiliation_list(const char * const room, char *affiliation);
|
||||
void iq_room_affiliation_set(const char * const room, const char * const jid, char *affiliation,
|
||||
const char * const reason);
|
||||
|
@ -151,7 +151,7 @@ void iq_send_caps_request_for_jid(const char * const to, const char * const id,
|
||||
const char * const node, const char * const ver) {}
|
||||
void iq_send_caps_request_legacy(const char * const to, const char * const id,
|
||||
const char * const node, const char * const ver) {}
|
||||
void iq_room_info_request(gchar *room) {}
|
||||
void iq_room_info_request(const char * const room, gboolean display) {}
|
||||
void iq_room_affiliation_list(const char * const room, char *affiliation) {}
|
||||
void iq_room_affiliation_set(const char * const room, const char * const jid, char *affiliation,
|
||||
const char * const reason) {}
|
||||
|
Loading…
Reference in New Issue
Block a user