mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-08-03 09:06:21 +00:00
WIP: Added last activity request and response
This commit is contained in:
@@ -695,6 +695,23 @@ static struct cmd_t command_defs[] =
|
|||||||
"/disco info myfriend@server.com/laptop")
|
"/disco info myfriend@server.com/laptop")
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "/lastactivity",
|
||||||
|
cmd_lastactivity, parse_args, 0, 1, NULL,
|
||||||
|
CMD_TAGS(
|
||||||
|
CMD_TAG_PRESENCE)
|
||||||
|
CMD_SYN(
|
||||||
|
"/lastactivity [<jid>]")
|
||||||
|
CMD_DESC(
|
||||||
|
"Send a last activity query to the supplied JID, omitting the JID will send the query to your server.")
|
||||||
|
CMD_ARGS(
|
||||||
|
{ "<jid>", "The JID of the entity to which the query will be sent." })
|
||||||
|
CMD_EXAMPLES(
|
||||||
|
"/lastactivity",
|
||||||
|
"/lastactivity alice@securechat.org",
|
||||||
|
"/lastactivity alice@securechat.org/laptop",
|
||||||
|
"/lastactivity someserver.com")
|
||||||
|
},
|
||||||
|
|
||||||
{ "/nick",
|
{ "/nick",
|
||||||
cmd_nick, parse_args_with_freetext, 1, 1, NULL,
|
cmd_nick, parse_args_with_freetext, 1, 1, NULL,
|
||||||
CMD_TAGS(
|
CMD_TAGS(
|
||||||
|
|||||||
@@ -3261,6 +3261,31 @@ cmd_disco(ProfWin *window, const char * const command, gchar **args)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cmd_lastactivity(ProfWin *window, const char * const command, gchar **args)
|
||||||
|
{
|
||||||
|
jabber_conn_status_t conn_status = jabber_get_connection_status();
|
||||||
|
|
||||||
|
if (conn_status != JABBER_CONNECTED) {
|
||||||
|
cons_show("You are not currenlty connected.");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args[0] == NULL) {
|
||||||
|
Jid *jidp = jid_create(jabber_get_fulljid());
|
||||||
|
GString *jid = g_string_new(jidp->domainpart);
|
||||||
|
|
||||||
|
iq_last_activity_request(jid->str);
|
||||||
|
|
||||||
|
g_string_free(jid, TRUE);
|
||||||
|
jid_destroy(jidp);
|
||||||
|
} else {
|
||||||
|
iq_last_activity_request(args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
cmd_nick(ProfWin *window, const char * const command, gchar **args)
|
cmd_nick(ProfWin *window, const char * const command, gchar **args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ gboolean cmd_connect(ProfWin *window, const char * const command, gchar **args);
|
|||||||
gboolean cmd_tls(ProfWin *window, const char * const command, gchar **args);
|
gboolean cmd_tls(ProfWin *window, const char * const command, gchar **args);
|
||||||
gboolean cmd_decline(ProfWin *window, const char * const command, gchar **args);
|
gboolean cmd_decline(ProfWin *window, const char * const command, gchar **args);
|
||||||
gboolean cmd_disco(ProfWin *window, const char * const command, gchar **args);
|
gboolean cmd_disco(ProfWin *window, const char * const command, gchar **args);
|
||||||
|
gboolean cmd_lastactivity(ProfWin *window, const char * const command, gchar **args);
|
||||||
gboolean cmd_disconnect(ProfWin *window, const char * const command, gchar **args);
|
gboolean cmd_disconnect(ProfWin *window, const char * const command, gchar **args);
|
||||||
gboolean cmd_dnd(ProfWin *window, const char * const command, gchar **args);
|
gboolean cmd_dnd(ProfWin *window, const char * const command, gchar **args);
|
||||||
gboolean cmd_flash(ProfWin *window, const char * const command, gchar **args);
|
gboolean cmd_flash(ProfWin *window, const char * const command, gchar **args);
|
||||||
|
|||||||
@@ -730,3 +730,28 @@ sv_ev_certfail(const char * const errormsg, const char * const certname, const c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sv_ev_lastactivity_response(const char * const from, const int seconds, const char * const msg)
|
||||||
|
{
|
||||||
|
Jid *jidp = jid_create(from);
|
||||||
|
|
||||||
|
if (!jidp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// full jid or bare jid
|
||||||
|
if (jidp->resourcepart || jidp->localpart) {
|
||||||
|
if (msg) {
|
||||||
|
cons_show("%s last active %d, status: %s", from, seconds, msg);
|
||||||
|
} else {
|
||||||
|
cons_show("%s last active %d", from, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// domain only
|
||||||
|
} else {
|
||||||
|
cons_show("%s uptime %d seconds", from, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
jid_destroy(jidp);
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,5 +88,6 @@ void sv_ev_roster_update(const char * const barejid, const char * const name,
|
|||||||
void sv_ev_roster_received(void);
|
void sv_ev_roster_received(void);
|
||||||
int sv_ev_certfail(const char * const errormsg, const char * const certname, const char * const certfp,
|
int sv_ev_certfail(const char * const errormsg, const char * const certname, const char * const certfp,
|
||||||
const char * const notbefore, const char * const notafter);
|
const char * const notbefore, const char * const notafter);
|
||||||
|
void sv_ev_lastactivity_response(const char * const from, const int seconds, const char * const msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ jid_create(const gchar * const str)
|
|||||||
gchar *slashp = g_utf8_strchr(trimmed, -1, '/');
|
gchar *slashp = g_utf8_strchr(trimmed, -1, '/');
|
||||||
gchar *domain_start = trimmed;
|
gchar *domain_start = trimmed;
|
||||||
|
|
||||||
|
|
||||||
if (atp) {
|
if (atp) {
|
||||||
result->localpart = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, atp));
|
result->localpart = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, atp));
|
||||||
domain_start = atp + 1;
|
domain_start = atp + 1;
|
||||||
|
|||||||
119
src/xmpp/iq.c
119
src/xmpp/iq.c
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#ifdef HAVE_LIBMESODE
|
#ifdef HAVE_LIBMESODE
|
||||||
@@ -76,6 +76,8 @@ static int _version_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const
|
|||||||
static int _version_result_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_info_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 _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
|
static int _last_activity_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
|
static int _last_activity_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 _room_info_response_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_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);
|
static int _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
@@ -108,6 +110,8 @@ iq_add_handlers(void)
|
|||||||
HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_GET, _disco_items_get_handler);
|
HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_GET, _disco_items_get_handler);
|
||||||
HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_RESULT, _disco_items_result_handler);
|
HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_RESULT, _disco_items_result_handler);
|
||||||
|
|
||||||
|
HANDLE("jabber:iq:last", STANZA_TYPE_GET, _last_activity_get_handler);
|
||||||
|
|
||||||
HANDLE(STANZA_NS_VERSION, STANZA_TYPE_GET, _version_get_handler);
|
HANDLE(STANZA_NS_VERSION, STANZA_TYPE_GET, _version_get_handler);
|
||||||
|
|
||||||
HANDLE(STANZA_NS_PING, STANZA_TYPE_GET, _ping_get_handler);
|
HANDLE(STANZA_NS_PING, STANZA_TYPE_GET, _ping_get_handler);
|
||||||
@@ -189,6 +193,22 @@ iq_disco_info_request(gchar *jid)
|
|||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iq_last_activity_request(gchar *jid)
|
||||||
|
{
|
||||||
|
xmpp_conn_t * const conn = connection_get_conn();
|
||||||
|
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||||
|
char *id = create_unique_id("lastactivity");
|
||||||
|
xmpp_stanza_t *iq = stanza_create_last_activity_iq(ctx, id, jid);
|
||||||
|
|
||||||
|
xmpp_id_handler_add(conn, _last_activity_response_handler, id, NULL);
|
||||||
|
|
||||||
|
free(id);
|
||||||
|
|
||||||
|
xmpp_send(conn, iq);
|
||||||
|
xmpp_stanza_release(iq);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iq_room_info_request(const char * const room, gboolean display_result)
|
iq_room_info_request(const char * const room, gboolean display_result)
|
||||||
{
|
{
|
||||||
@@ -209,6 +229,8 @@ iq_room_info_request(const char * const room, gboolean display_result)
|
|||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
iq_send_caps_request_for_jid(const char * const to, const char * const id,
|
iq_send_caps_request_for_jid(const char * const to, const char * const id,
|
||||||
const char * const node, const char * const ver)
|
const char * const node, const char * const ver)
|
||||||
@@ -1065,6 +1087,46 @@ _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_last_activity_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||||
|
void * const userdata)
|
||||||
|
{
|
||||||
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
|
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||||
|
|
||||||
|
/*
|
||||||
|
<iq from='juliet@capulet.com/balcony'
|
||||||
|
id='last2'
|
||||||
|
to='romeo@montague.net/orchard'
|
||||||
|
type='result'>
|
||||||
|
<query xmlns='jabber:iq:last' seconds='123'/>
|
||||||
|
</iq>
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (from) {
|
||||||
|
int idls_secs = ui_get_idle_time() / 1000;
|
||||||
|
char str[50];
|
||||||
|
sprintf(str, "%d", idls_secs);
|
||||||
|
|
||||||
|
xmpp_stanza_t *response = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_name(response, STANZA_NAME_IQ);
|
||||||
|
xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza));
|
||||||
|
xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from);
|
||||||
|
xmpp_stanza_set_type(response, STANZA_TYPE_RESULT);
|
||||||
|
|
||||||
|
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_attribute(query, STANZA_ATTR_XMLNS, "jabber:iq:last");
|
||||||
|
xmpp_stanza_set_attribute(query, "seconds", str);
|
||||||
|
|
||||||
|
xmpp_stanza_add_child(response, query);
|
||||||
|
xmpp_send(conn, response);
|
||||||
|
|
||||||
|
xmpp_stanza_release(query);
|
||||||
|
xmpp_stanza_release(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
_disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||||
@@ -1489,6 +1551,61 @@ _room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stan
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_last_activity_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||||
|
void * const userdata)
|
||||||
|
{
|
||||||
|
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||||
|
if (!from) {
|
||||||
|
cons_show_error("Invalid last activity response received.");
|
||||||
|
log_info("Received last activity response with no from attribute.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *type = xmpp_stanza_get_type(stanza);
|
||||||
|
|
||||||
|
// handle error responses
|
||||||
|
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||||
|
char *error_message = stanza_get_error_message(stanza);
|
||||||
|
if (from) {
|
||||||
|
cons_show_error("Last activity request failed for %s: %s", from, error_message);
|
||||||
|
} else {
|
||||||
|
cons_show_error("Last activity request failed: %s", error_message);
|
||||||
|
}
|
||||||
|
free(error_message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
cons_show_error("Invalid last activity response received.");
|
||||||
|
log_info("Received last activity response with no query element.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *seconds_str = xmpp_stanza_get_attribute(query, "seconds");
|
||||||
|
if (!seconds_str) {
|
||||||
|
cons_show_error("Invalid last activity response received.");
|
||||||
|
log_info("Received last activity response with no seconds attribute.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int seconds = atoi(seconds_str);
|
||||||
|
if (seconds < 0) {
|
||||||
|
cons_show_error("Invalid last activity response received.");
|
||||||
|
log_info("Received last activity response with negative value.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *msg = xmpp_stanza_get_text(query);
|
||||||
|
|
||||||
|
sv_ev_lastactivity_response(from, seconds, msg);
|
||||||
|
|
||||||
|
xmpp_free(connection_get_ctx(), msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
_disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||||
void * const userdata)
|
void * const userdata)
|
||||||
|
|||||||
@@ -965,6 +965,25 @@ stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char * const id,
|
|||||||
return iq;
|
return iq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmpp_stanza_t *
|
||||||
|
stanza_create_last_activity_iq(xmpp_ctx_t *ctx, const char * const id, const char * const to)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
|
||||||
|
xmpp_stanza_set_type(iq, STANZA_TYPE_GET);
|
||||||
|
xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, to);
|
||||||
|
xmpp_stanza_set_id(iq, id);
|
||||||
|
|
||||||
|
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
|
||||||
|
xmpp_stanza_set_ns(query, "jabber:iq:last");
|
||||||
|
|
||||||
|
xmpp_stanza_add_child(iq, query);
|
||||||
|
xmpp_stanza_release(query);
|
||||||
|
|
||||||
|
return iq;
|
||||||
|
}
|
||||||
|
|
||||||
xmpp_stanza_t *
|
xmpp_stanza_t *
|
||||||
stanza_create_room_config_submit_iq(xmpp_ctx_t *ctx, const char * const room, DataForm *form)
|
stanza_create_room_config_submit_iq(xmpp_ctx_t *ctx, const char * const room, DataForm *form)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ xmpp_stanza_t* stanza_create_ping_iq(xmpp_ctx_t *ctx, const char * const target)
|
|||||||
xmpp_stanza_t* stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const id,
|
xmpp_stanza_t* stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const id,
|
||||||
const char * const to, const char * const node);
|
const char * const to, const char * const node);
|
||||||
|
|
||||||
|
xmpp_stanza_t* stanza_create_last_activity_iq(xmpp_ctx_t *ctx, const char * const id,
|
||||||
|
const char * const to);
|
||||||
|
|
||||||
xmpp_stanza_t* stanza_create_invite(xmpp_ctx_t *ctx, const char * const room,
|
xmpp_stanza_t* stanza_create_invite(xmpp_ctx_t *ctx, const char * const room,
|
||||||
const char * const contact, const char * const reason, const char * const password);
|
const char * const contact, const char * const reason, const char * const password);
|
||||||
xmpp_stanza_t* stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const room,
|
xmpp_stanza_t* stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const room,
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ void iq_send_software_version(const char * const fulljid);
|
|||||||
void iq_room_list_request(gchar *conferencejid);
|
void iq_room_list_request(gchar *conferencejid);
|
||||||
void iq_disco_info_request(gchar *jid);
|
void iq_disco_info_request(gchar *jid);
|
||||||
void iq_disco_items_request(gchar *jid);
|
void iq_disco_items_request(gchar *jid);
|
||||||
|
void iq_last_activity_request(gchar *jid);
|
||||||
void iq_set_autoping(int seconds);
|
void iq_set_autoping(int seconds);
|
||||||
void iq_confirm_instant_room(const char * const room_jid);
|
void iq_confirm_instant_room(const char * const room_jid);
|
||||||
void iq_destroy_room(const char * const room_jid);
|
void iq_destroy_room(const char * const room_jid);
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ void iq_room_kick_occupant(const char * const room, const char * const nick, con
|
|||||||
void iq_room_role_set(const char * const room, const char * const nick, char *role,
|
void iq_room_role_set(const char * const room, const char * const nick, char *role,
|
||||||
const char * const reason) {}
|
const char * const reason) {}
|
||||||
void iq_room_role_list(const char * const room, char *role) {}
|
void iq_room_role_list(const char * const room, char *role) {}
|
||||||
|
void iq_last_activity_request(gchar *jid) {}
|
||||||
|
|
||||||
// caps functions
|
// caps functions
|
||||||
Capabilities* caps_lookup(const char * const jid)
|
Capabilities* caps_lookup(const char * const jid)
|
||||||
|
|||||||
Reference in New Issue
Block a user