49 if(item->
name != NULL)
50 free((
void*)item->
name);
52 for(i = 0; i < item->
ngroups; i++)
53 free((
void*)item->
groups[i]);
82 o = os_object_new(os);
84 os_object_put(o,
"jid",
jid_full(item->
jid), os_type_STRING);
86 if(item->
name != NULL)
87 os_object_put(o,
"name", item->
name, os_type_STRING);
89 os_object_put(o,
"to", &item->
to, os_type_BOOLEAN);
90 os_object_put(o,
"from", &item->
from, os_type_BOOLEAN);
91 os_object_put(o,
"ask", &item->
ask, os_type_INTEGER);
95 storage_replace(user->
sm->
st,
"roster-items",
jid_user(user->
jid), filter, os);
100 storage_delete(user->
sm->
st,
"roster-groups",
jid_user(user->
jid), filter);
106 for(i = 0; i < item->
ngroups; i++) {
107 o = os_object_new(os);
109 os_object_put(o,
"jid",
jid_full(item->
jid), os_type_STRING);
110 os_object_put(o,
"group", item->
groups[i], os_type_STRING);
113 storage_replace(user->
sm->
st,
"roster-groups",
jid_user(user->
jid), filter, os);
128 if(item->
to && item->
from)
141 else if(item->
ask == 2)
144 if(item->
name != NULL)
147 for(i = 0; i < item->
ngroups; i++)
159 for(scan = user->
sessions; scan != NULL; scan = scan->
next)
180 int ns, elem, ret, items = -1;
189 if(pkt->
from != NULL)
211 if (ret == st_SUCCESS && items >= mroster->
maxitems)
300 buf = (
char *) malloc(
sizeof(
char) * 128);
301 sprintf(buf,
"%d", item->
ver);
314 int attr, ns, i, ret, items = -1;
356 snprintf(filter, 4096,
"(jid=%zu:%s)", strlen(
jid_full(jid)),
jid_full(jid));
371 nad_set_attr(push->nad, elem, -1,
"subscription",
"remove", 6);
395 if (ret == st_SUCCESS && items >= mroster->
maxitems)
419 if(item->name != NULL) {
420 free((
void*)item->name);
426 item->name = (
const char *) malloc(
sizeof(
char) * (
NAD_AVAL_L(pkt->
nad, attr) + 1));
432 if(item->groups != NULL)
434 for(i = 0; i < item->ngroups; i++)
435 free((
void*)item->groups[i]);
449 item->groups = (
const char **) realloc(item->groups,
sizeof(
char *) * (item->ngroups + 1));
451 item->groups[item->ngroups] = (
const char *) malloc(
sizeof(
char) * (
NAD_CDATA_L(pkt->
nad, elem) + 1));
460 log_debug(
ZONE,
"added %s to roster (to %d from %d ask %d name %s ngroups %d)",
jid_full(item->jid), item->to, item->from, item->ask, item->name, item->ngroups);
487 int elem, attr, ver = 0;
518 buf = (
char *) malloc(
sizeof(
char) * (
NAD_AVAL_L(pkt->
nad, attr) + 1));
541 if(elem >= 0 && attr >= 0) {
542 buf = (
char *) malloc(
sizeof(
char) * 128);
543 sprintf(buf,
"%d", rw->
ver);
664 if(user->
top != NULL)
692 if(user->
top != NULL)
749 if(storage_get(user->
sm->
st,
"roster-items",
jid_user(user->
jid), NULL, &os) == st_SUCCESS) {
750 if(os_iter_first(os))
752 o = os_iter_object(os);
754 if(os_object_get_str(os, o,
"jid", &str)) {
759 if(item->
jid == NULL) {
764 if(os_object_get_str(os, o,
"name", &str))
765 item->
name = strdup(str);
767 os_object_get_bool(os, o,
"to", &item->
to);
768 os_object_get_bool(os, o,
"from", &item->
from);
769 os_object_get_int(os, o,
"ask", &item->
ask);
770 os_object_get_int(os, o,
"object-sequence", &item->
ver);
782 log_debug(
ZONE,
"added %s to roster (to %d from %d ask %d ver %d name %s)",
786 }
while(os_iter_next(os));
792 if(storage_get(user->
sm->
st,
"roster-groups",
jid_user(user->
jid), NULL, &os) == st_SUCCESS) {
793 if(os_iter_first(os))
795 o = os_iter_object(os);
797 if(os_object_get_str(os, o,
"jid", &str)) {
800 if(item != NULL && os_object_get_str(os, o,
"group", &str)) {
808 }
while(os_iter_next(os));
821 storage_delete(mi->
sm->
st,
"roster-items",
jid_user(jid), NULL);
822 storage_delete(mi->
sm->
st,
"roster-groups",
jid_user(jid), NULL);
835 if(mod->
init)
return 0;
static void _roster_get_walker(const char *id, int idlen, void *val, void *arg)
build the iq:roster packet from the hash
user_t user
user this session belongs to
xht roster
roster for this user (key is full jid of item, value is item_t)
static void _roster_set_item(pkt_t pkt, int elem, sess_t sess, mod_instance_t mi)
pkt_type_t type
packet type
jid_t jid
session jid (user@host/res)
data structures and prototypes for the session manager
int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
#define NAD_CDATA_L(N, E)
static mod_ret_t _roster_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt)
our main handler for packets arriving from a session
const char * jid_user(jid_t jid)
expand and return the user
const char * jid_full(jid_t jid)
expand and return the full
jid_t jid_new(const char *id, int len)
make a new jid
pkt_t pkt_tofrom(pkt_t pkt)
swap a packet's to and from attributes
single instance of a module in a chain
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
config_t config
config context
int init
number of times the module intialiser has been called
int ask
pending subscription (0 == none, 1 == subscribe, 2 == unsubscribe)
void ** module_data
per-session module data
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
pkt_t pkt_dup(pkt_t pkt, const char *to, const char *from)
duplicate pkt, replacing addresses
int j_atoi(const char *a, int def)
void pkt_id_new(pkt_t pkt)
create an id value for new iq packets
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
static void _roster_save_item(user_t user, item_t item)
int(* user_load)(mod_instance_t mi, user_t user)
user-load handler
sess_t next
next session (in a list of sessions)
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
sess_t top
top priority session
void pool_cleanup(pool_t p, pool_cleanup_t f, void *arg)
public cleanup utils, insert in a way that they are run FIFO, before mem frees
static int _roster_push(user_t user, pkt_t pkt, int mod_index)
push this packet to all sessions except the given one
pool_t p
memory pool this user is allocated off
sess_t sessions
list of action sessions
module_t mod
module that this is an instance of
jid_t from
packet addressing (not used for routing)
void * private
module private data
packet summary data wrapper
storage_t st
storage subsystem
nad_t nad
nad of the entire packet
void jid_free(jid_t jid)
free a jid
#define stanza_err_RESOURCE_CONSTRAINT
mod_ret_t(* in_sess)(mod_instance_t mi, sess_t sess, pkt_t pkt)
in-sess handler
void xhash_put(xht h, const char *key, void *val)
static void _roster_freeuser_walker(const char *key, int keylen, void *val, void *arg)
free a single roster item
static int _roster_user_load(mod_instance_t mi, user_t user)
load the roster from the database
#define stanza_err_BAD_REQUEST
int ngroups
number of groups in groups array
const char ** groups
groups this item is in
void pkt_id(pkt_t src, pkt_t dest)
convenience - copy the packet id from src to dest
static void _roster_user_delete(mod_instance_t mi, jid_t jid)
void pkt_router(pkt_t pkt)
void xhash_zap(xht h, const char *key)
static void _roster_freeuser(user_t user)
free the roster
DLLEXPORT int module_init(mod_instance_t mi, const char *arg)
void feature_register(sm_t sm, const char *feature)
register a feature
static mod_ret_t _roster_in_sess_s10n(mod_instance_t mi, sess_t sess, pkt_t pkt)
struct _roster_walker_st * roster_walker_t
struct item_st * item_t
roster items
void(* user_delete)(mod_instance_t mi, jid_t jid)
user-delete handler
packet was unhandled, should be passed to the next module
packet was handled (and freed)
There is one instance of this struct per user who is logged in to this c2s instance.
struct _mod_roster_st * mod_roster_t
void xhash_walk(xht h, xhash_walker w, void *arg)
void(* free)(module_t mod)
called when module is freed
int from
subscription to this item (they get presence FROM us, they send presence TO us)
static void _roster_free(module_t mod)
void nad_drop_elem(nad_t nad, int elem)
remove an element (and its subelements)
mod_ret_t(* pkt_user)(mod_instance_t mi, user_t user, pkt_t pkt)
pkt-user handler
void pres_roster(sess_t sess, item_t item)
send presence based on roster changes
#define stanza_err_NOT_ACCEPTABLE
jid_t jid_dup(jid_t jid)
duplicate a jid
jid_t jid
user jid (user@host)
void * xhash_get(xht h, const char *key)
static void _roster_insert_item(pkt_t pkt, item_t item, int elem)
insert a roster item into this pkt, starting at elem
const char * config_get_one(config_t c, const char *key, int num)
get config value n for this key
int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val)
get a matching attr on this elem, both name and optional val
pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from)
static mod_ret_t _roster_pkt_user(mod_instance_t mi, user_t user, pkt_t pkt)
handle incoming s10ns
mod_ret_t
module return values
void pkt_sess(pkt_t pkt, sess_t sess)
int sm_storage_rate_limit(sm_t sm, const char *owner)
int ver
roster item version number
const char * name
display name
static void _roster_update_walker(const char *id, int idlen, void *val, void *arg)
push roster XEP-0237 updates to client
route_type_t rtype
type of enclosing route