mreturn mod_log_archiver(mapi m, void *arg) { jid svcs = (jid) arg; xmlnode x; char ts[101]; struct tm now; unsigned long ltime; if (m->packet->type != JPACKET_MESSAGE) return M_IGNORE; log_debug("archiving message"); /* get a copy wrapped w/ a route and stamp it w/ a type='archive' (why not?) */ x = xmlnode_wrap(xmlnode_dup(m->packet->x), "route"); xmlnode_put_attrib(x, "type", "archive"); /* Mark the route with an direction attribute */ switch (m->e) { case es_IN: xmlnode_put_attrib(x, "direction", "in"); break; case es_OUT: xmlnode_put_attrib(x, "direction", "out"); break; } /* Mark the route with a timeStamp attribute */ time(<ime); #ifdef WIN32 now = *localtime(<ime); #else localtime_r(<ime, &now); #endif strftime((char *) ts, 100, "%m/%d/%Y %H:%M:%S", &now); xmlnode_put_attrib(x, "stamp", ts); /* if there's more than one service, copy to the others */ for (; svcs->next != NULL; svcs = svcs->next) { xmlnode_put_attrib(x, "to", jid_full(svcs)); deliver(dpacket_new(xmlnode_dup(x)), NULL); } /* send off to the last (or only) one */ xmlnode_put_attrib(x, "to", jid_full(svcs)); deliver(dpacket_new(x), NULL); return M_PASS; }
Request * add_request(RequestType type,const char *from,const char *to, const char *id,xmlnode query, void *data, Stream *stream){ Request *r; Session *s; r=g_new0(Request,1); r->type=type; r->id=g_strdup(id); r->from=g_strdup(from); if (to) r->to=g_strdup(to); else r->to=NULL; if (query) r->query=xmlnode_dup(query); else r->query=NULL; r->stream=stream; if (type==RT_VCARD || type==RT_SEARCH || type==RT_CHANGE) { s=session_get_by_jid(from, stream,0); if (s==NULL) return NULL; r->hash=id_counter++; gg_pubdir50_seq_set((gg_pubdir50_t)data, r->hash); gg_pubdir50(s->ggs, (gg_pubdir50_t)data); g_hash_table_insert(lookups, &r->hash, r); } requests=g_list_append(requests,r); return r; }
void con_room_sendwalk(gpointer key, gpointer data, gpointer arg) { xmlnode x = (xmlnode)arg; cnu to = (cnu)data; cnu from; xmlnode output; if(x == NULL || to == NULL) { log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE); return; } if (to->remote == 1) return; from = (cnu)xmlnode_get_vattrib(x,"cnu"); if(j_strcmp(xmlnode_get_name(x),"presence") == 0) { output = add_extended_presence(from, to, x, NULL, NULL, NULL); if(jid_cmp(to->realid,from->realid)==0) //own presence { add_status_code(output, STATUS_MUC_OWN_PRESENCE); } con_user_send(to, from, output); } else { con_user_send(to, from, xmlnode_dup(x)); /* Need to send duplicate */ } }
/* thread safe with sem */ mreturn mod_presence_deliver(mapi m, void *arg) { session cur; if (m->packet->type != JPACKET_PRESENCE) return M_IGNORE; log_debug("deliver phase"); /* only if we HAVE a user, and it was sent to ONLY the user@server, and there is at least one session available */ if (m->user != NULL && m->packet->to->resource == NULL && js_session_primary_all_sem(m->user) != NULL) { log_debug("broadcasting to %s", m->user->user); /* broadcast */ for (cur = m->user->sessions; cur != NULL; cur = cur->next) { if (cur->priority < -128) continue; js_session_to(cur, jpacket_new(xmlnode_dup(m->packet->x))); } SEM_UNLOCK(m->user->sem); if (jpacket_subtype(m->packet) != JPACKET__PROBE) { /* probes get handled by the offline thread as well? */ xmlnode_free(m->packet->x); return M_HANDLED; } } return M_PASS; }
/* session thread */ mreturn mod_presence_in(mapi m, void *arg) { modpres mp = (modpres) arg; xmlnode pres; if (m->packet->type != JPACKET_PRESENCE) return M_IGNORE; log_debug("incoming filter for %s", jid_full(m->s->id)); if (jpacket_subtype(m->packet) == JPACKET__PROBE) { /* reply with our presence */ if (m->s->presence == NULL) { log_debug("probe from %s and no presence to return", jid_full(m->packet->from)); } else if (!mp->invisible && js_trust(m->user, m->packet->from) && !_mod_presence_search(m->packet->from, mp->I)) { /* compliment of I in T */ log_debug("got a probe, responding to %s", jid_full(m->packet->from)); pres = xmlnode_dup(m->s->presence); xmlnode_put_attrib(pres, "to", jid_full(m->packet->from)); js_session_from(m->s, jpacket_new(pres)); } else if (mp->invisible && js_trust(m->user, m->packet->from) && _mod_presence_search(m->packet->from, mp->A)) { /* when invisible, intersection of A and T */ log_debug("got a probe when invisible, responding to %s", jid_full(m->packet->from)); pres = jutil_presnew(JPACKET__AVAILABLE, jid_full(m->packet->from), NULL); js_session_from(m->s, jpacket_new(pres)); } else { log_debug("%s attempted to probe by someone not qualified", jid_full(m->packet->from)); } xmlnode_free(m->packet->x); return M_HANDLED; } if (jid_cmp(m->packet->from, m->s->id) == 0) { /* this is our presence, don't send to ourselves */ xmlnode_free(m->packet->x); return M_HANDLED; } /* if a presence packet bounced, remove from the A list */ if (jpacket_subtype(m->packet) == JPACKET__ERROR) mp->A = _mod_presence_whack(m->packet->from, mp->A); /* doh! this is a user, they should see invisibles as unavailables */ if (jpacket_subtype(m->packet) == JPACKET__INVISIBLE) xmlnode_put_attrib(m->packet->x, "type", "unavailable"); return M_PASS; }
void _mod_presence_broadcast_trusted(session s, jid notify, xmlnode x) { jid cur; xmlnode pres; for (cur = notify; cur != NULL; cur = cur->next) { if (!js_istrusted(s->u, cur)) continue; /* perform insersection search, must be in both */ s->c_out++; pres = xmlnode_dup(x); xmlnode_put_attrib(pres, "to", jid_full(cur)); /* send it to POSTOUT for filter purposes */ js_post_out_main(s, jpacket_new(pres)); } }
Session * session_create(User *user,const char *jid,const char *req_id, const xmlnode query,struct stream_s *stream,int delay_login){ Session *s; char *njid; g_message(L_("Creating session for '%s'"),jid); njid=jid_normalized(jid,0); if (njid==NULL){ g_message(L_("Bad JID: '%s'"),jid); return NULL; } g_assert(user!=NULL); if (user->deleted){ g_message(L_("User deleted: '%s'"),user->jid); return NULL; } s=g_new0(Session,1); s->user=user; user_ref(user); s->gg_status=-1; s->jid=g_strdup(jid); if (req_id) s->req_id=g_strdup(req_id); s->query=xmlnode_dup(query); s->current_server=g_list_first(gg_servers); s->g_pollfd.fd=-1; if (!delay_login && session_try_login(s)){ session_destroy(s); return NULL; } s->s=stream; g_assert(sessions_jid!=NULL); g_hash_table_insert(sessions_jid,(gpointer)njid,(gpointer)s); return s; }
/* session thread */ mreturn mod_presence_out(mapi m, void *arg) { xmlnode pnew, delay, pold; modpres mp = (modpres) arg; session cur = NULL; int oldpri, newpri; char *priority; if (m->packet->type != JPACKET_PRESENCE) return M_IGNORE; if (m->packet->to != NULL || jpacket_subtype(m->packet) == JPACKET__PROBE || jpacket_subtype(m->packet) == JPACKET__ERROR) return M_PASS; log_debug("new presence from %s of %s", jid_full(m->s->id), xmlnode2str(m->packet->x)); /* pre-existing conditions (no, we are not an insurance company) */ oldpri = m->s->priority; /* check that the priority is in the valid range */ priority = xmlnode_get_tag_data(m->packet->x, "priority"); if (priority == NULL) { newpri = 0; } else { newpri = j_atoi(priority, 0); if (newpri < -128 || newpri > 127) { log_notice("mod_presence", "got presence with invalid priority value from %s", jid_full(m->s->id)); xmlnode_free(m->packet->x); return M_HANDLED; } } /* invisible mode is special, don't you wish you were special too? */ if (jpacket_subtype(m->packet) == JPACKET__INVISIBLE) { log_debug("handling invisible mode request"); /* if we get this and we're available, it means go unavail first then reprocess this packet, nifty trick :) */ if (oldpri >= -128) { js_session_from(m->s, jpacket_new(jutil_presnew (JPACKET__UNAVAILABLE, NULL, xmlnode_get_tag_data(m->packet->x,"status") ))); js_session_from(m->s, m->packet); return M_HANDLED; } /* now, pretend we come online :) */ /* (this is the handling of the reinjected invisible presence * or an initial invisible presence) */ mp->invisible = 1; mod_presence_roster(m, NULL); /* send out probes to users we are subscribed to */ m->s->priority = newpri; /* store presence in xdb? */ if (mp->conf->pres_to_xdb > 0) mod_presence_store(m); xmlnode_free(m->packet->x); /* we do not broadcast invisible presences without a to attribute */ return M_HANDLED; } /* our new presence */ pnew = xmlnode_dup(m->packet->x); /* store presence in xdb? */ if (mp->conf->pres_to_xdb > 0) mod_presence_store(m); /* stamp the sessions presence */ delay = xmlnode_insert_tag(pnew, "x"); xmlnode_put_attrib(delay, "xmlns", NS_DELAY); xmlnode_put_attrib(delay, "from", jid_full(m->s->id)); xmlnode_put_attrib(delay, "stamp", jutil_timestamp()); /* our old presence */ pold = m->s->presence; m->s->presence = pnew; m->s->priority = jutil_priority(pnew); log_debug("presence oldp %d newp %d", oldpri, m->s->priority); /* if we're going offline now, let everyone know */ if (m->s->priority < -128) { /* jutil_priority returns -129 in case the "type" attribute is missing */ if (!mp->invisible) /* bcc's don't get told if we were invisible */ _mod_presence_broadcast(m->s, mp->conf->bcc, m->packet->x, NULL); _mod_presence_broadcast(m->s, mp->A, m->packet->x, NULL); _mod_presence_broadcast(m->s, mp->I, m->packet->x, NULL); /* reset vars */ mp->invisible = 0; mp->A->next = NULL; mp->I = NULL; xmlnode_free(m->packet->x); xmlnode_free(pold); return M_HANDLED; } /* available presence updates, intersection of A and T */ if (oldpri >= -128 && !mp->invisible) { _mod_presence_broadcast_trusted(m->s, mp->A, m->packet->x); xmlnode_free(m->packet->x); xmlnode_free(pold); return M_HANDLED; } /* at this point we're coming out of the closet */ mp->invisible = 0; /* make sure we get notified for any presence about ourselves */ /* XXX: the following is the original code: it caused existing presences * to be stamped several times and the presence to be sent out twice. pnew = jutil_presnew(JPACKET__PROBE,jid_full(m->s->uid),NULL); xmlnode_put_attrib(pnew,"from",jid_full(m->s->uid)); js_session_from(m->s, jpacket_new(pnew)); */ /* XXX: I think this should be okay as well: */ /* send us all presences of our other resources */ for (cur = m->user->sessions; cur != NULL; cur = cur->next) { pool pool_for_existing_presence = NULL; xmlnode duplicated_presence = NULL; jpacket packet = NULL; /* skip our own session (and sanity check) */ if (cur == m->s || cur->presence == NULL) { continue; } /* send the presence to us: we need a new pool as js_session_to() will free the packet's pool */ pool_for_existing_presence = pool_new(); duplicated_presence = xmlnode_dup_pool(pool_for_existing_presence, cur->presence); xmlnode_put_attrib(duplicated_presence, "to", jid_full(m->user->id)); packet = jpacket_new(duplicated_presence); js_session_to(m->s, packet); } /* probe s10ns and populate A */ mod_presence_roster(m, mp->A); /* we broadcast this baby! */ _mod_presence_broadcast(m->s, mp->conf->bcc, m->packet->x, NULL); _mod_presence_broadcast(m->s, mp->A, m->packet->x, NULL); xmlnode_free(m->packet->x); xmlnode_free(pold); return M_HANDLED; }