void aim_transport(instance i, xmlnode x) { ati ti; xmlnode config; char *eightbitcode, *utf8code = "UTF-8", *latin1code = "CP1252"; ti = pmalloco(i->p, sizeof(_ati)); ti->i = i; ti->xc = xdb_cache(i); log_notice(i->id, "AIM-Transport starting up for instance %s...", i->id); config = xdb_get(ti->xc, jid_new(xmlnode_pool(x), "config@-internal"), "jabber:config:aimtrans"); ti->vcard = xmlnode_new_tag_pool(i->p,"vCard"); xmlnode_put_attrib(ti->vcard,"xmlns",NS_VCARD); xmlnode_insert_node(ti->vcard,xmlnode_get_firstchild(xmlnode_get_tag(config,"vCard"))); ti->start_time = time(NULL); ti->session__list=xhash_new(101); ti->iq__callbacks = xhash_new(23); ti->pending__buddies = xhash_new(101); /* The aim.exe binary should not be necessary any more. */ ti->aimbinarydir = pstrdup(i->p, xmlnode_get_tag_data(config, "aimbinarydir")); eightbitcode = pstrdup(i->p, xmlnode_get_tag_data(config, "charset")); if( eightbitcode == NULL ) { log_notice( i->id, "Charset is not specified, using CP1252" ); eightbitcode = latin1code; } xmlnode_free(config); fromutf8 = iconv_open(eightbitcode, utf8code); if(fromutf8 == (iconv_t)(-1)) { log_error(i->id, "Conversion from %s to %s is not supported", utf8code, eightbitcode); raise(SIGINT); } toutf8 = iconv_open(utf8code, eightbitcode); if(toutf8 == (iconv_t)(-1)) { log_error(i->id, "Conversion from %s to %s is not supported", eightbitcode, utf8code); raise(SIGINT); } ti->send_buf = NULL; ti->modname = NULL; pth_mutex_init(&ti->buddies_mutex); at_init_iqcbs(ti); register_phandler(i, o_DELIVER, at_phandler, ti); pool_cleanup(i->p, at_shutdown, (void*)i); }
mreturn mod_browse_reply(mapi m, void *arg) { xmlnode browse, ns, cur; session s; if (m->packet->type != JPACKET_IQ) return M_IGNORE; if (!NSCHECK(m->packet->iq, NS_BROWSE)) return M_PASS; /* first, is this a valid request? */ switch (jpacket_subtype(m->packet)) { case JPACKET__RESULT: case JPACKET__ERROR: return M_PASS; case JPACKET__SET: js_bounce(m->si, m->packet->x, TERROR_NOTALLOWED); return M_HANDLED; } log_debug("handling query for user %s", m->user->user); /* get this dudes browse info */ browse = mod_browse_get(m, m->packet->to); /* insert the namespaces */ ns = xdb_get(m->si->xc, m->packet->to, NS_XDBNSLIST); for (cur = xmlnode_get_firstchild(ns); cur != NULL; cur = xmlnode_get_nextsibling(cur)) if (xmlnode_get_attrib(cur, "type") == NULL) xmlnode_insert_tag_node(browse, cur); /* only include the generic <ns>foo</ns> */ xmlnode_free(ns); /* include any connected resources if there's a s10n from them */ if (js_trust(m->user, m->packet->from)) { SEM_LOCK(m->user->sem); for (s = m->user->sessions; s != NULL; s = s->next) { /* if(s->priority < 0) continue; *** include all resources I guess */ if (xmlnode_get_tag (browse, spools(m->packet->p, "?jid=", jid_full(s->id), m->packet->p)) != NULL) continue; /* already in the browse result */ cur = xmlnode_insert_tag(browse, "user"); xmlnode_put_attrib(cur, "type", "client"); xmlnode_put_attrib(cur, "jid", jid_full(s->id)); } SEM_UNLOCK(m->user->sem); } /* XXX include iq:filter forwards */ jutil_iqresult(m->packet->x); jpacket_reset(m->packet); xmlnode_insert_tag_node(m->packet->x, browse); js_deliver(m->si, m->packet); xmlnode_free(browse); return M_HANDLED; }
/** * init the module, register callbacks * * builds a list of JabberIDs where presences should be blind carbon copied to. * (Enclosing each in a <bcc/> element, which are contained in one <presence/> * element in the session manager configuration.) * * registers mod_presence_session() as a callback, that gets notified on new sessions * and mod_presence_deliver() as a callback to deliver presence stanzas locally. * * @param si the session manager instance */ JSM_FUNC void mod_presence(jsmi si) { xmlnode cfg = js_config(si, "presence"); modpres_conf conf = (modpres_conf) pmalloco(si->p, sizeof(_modpres_conf)); log_debug("init"); for (cfg = xmlnode_get_firstchild(cfg); cfg != NULL; cfg = xmlnode_get_nextsibling(cfg)) { char *element_name = NULL; if (xmlnode_get_type(cfg) != NTYPE_TAG) continue; element_name = xmlnode_get_name(cfg); if (j_strcmp(element_name, "bcc") == 0) { if (conf->bcc == NULL) conf->bcc = jid_new(si->p, xmlnode_get_data(cfg)); else jid_append(conf->bcc, jid_new(si->p, xmlnode_get_data(cfg))); } else if (j_strcmp(element_name, "presence2xdb") == 0) { conf->pres_to_xdb++; } } js_mapi_register(si, e_DELIVER, mod_presence_deliver, NULL); js_mapi_register(si, e_SESSION, mod_presence_session, (void *) conf); }
result dnsrv_deliver(instance i, dpacket p, void* args) { dns_io di = (dns_io)args; xmlnode c; int timeout = di->cache_timeout; char *ip; jid to; /* if we get a route packet, it has to be to *us* and have the child as the real packet */ if(p->type == p_ROUTE) { if(j_strcmp(p->host,i->id) != 0 || (to = jid_new(p->p,xmlnode_get_attrib(xmlnode_get_firstchild(p->x),"to"))) == NULL) return r_ERR; p->x=xmlnode_get_firstchild(p->x); p->id = to; p->host = to->server; } /* Ensure this packet doesn't already have an IP */ if(xmlnode_get_attrib(p->x, "ip") || xmlnode_get_attrib(p->x, "iperror")) { log_notice(p->host, "dropping looping dns lookup request: %s", xmlnode2str(p->x)); xmlnode_free(p->x); return r_DONE; } /* try the cache first */ if((c = xhash_get(di->cache_table, p->host)) != NULL) { /* if there's no IP, cached failed lookup, time those out 10 times faster! (weird, I know, *shrug*) */ if((ip = xmlnode_get_attrib(c,"ip")) == NULL) timeout = timeout / 10; if((time(NULL) - (int)xmlnode_get_vattrib(c,"t")) > timeout) { /* timed out of the cache, lookup again */ xmlnode_free(c); xhash_zap(di->cache_table,p->host); }else{ /* yay, send back right from the cache */ dnsrv_resend(p->x, ip, xmlnode_get_attrib(c,"to")); return r_DONE; } } dnsrv_lookup(di, p); return r_DONE; }
/* loop through both a and b comparing everything, attribs, cdata, children, etc */ int xmlnode_cmp(xmlnode a, xmlnode b) { int ret = 0; while(1) { if(a == NULL && b == NULL) return 0; if(a == NULL || b == NULL) return -1; if(xmlnode_get_type(a) != xmlnode_get_type(b)) return -1; switch(xmlnode_get_type(a)) { case NTYPE_ATTRIB: ret = j_strcmp(xmlnode_get_name(a), xmlnode_get_name(b)); if(ret != 0) return -1; ret = j_strcmp(xmlnode_get_data(a), xmlnode_get_data(b)); if(ret != 0) return -1; break; case NTYPE_TAG: ret = j_strcmp(xmlnode_get_name(a), xmlnode_get_name(b)); if(ret != 0) return -1; ret = xmlnode_cmp(xmlnode_get_firstattrib(a), xmlnode_get_firstattrib(b)); if(ret != 0) return -1; ret = xmlnode_cmp(xmlnode_get_firstchild(a), xmlnode_get_firstchild(b)); if(ret != 0) return -1; break; case NTYPE_CDATA: ret = j_strcmp(xmlnode_get_data(a), xmlnode_get_data(b)); if(ret != 0) return -1; } a = xmlnode_get_nextsibling(a); b = xmlnode_get_nextsibling(b); } }
int main(){ xmlnode point; xmlnode conf; conf=xmlnode_file("./test.xml"); point=conf; printf("\n"); printf("Tagname is %s.\n", xmlnode_get_name(point)); printf("Data is \"%s\"\n", xmlnode_get_data(point)); printf("Type is %d.\n", xmlnode_get_type(point)); point = xmlnode_get_firstchild(point); printf("\n"); printf("Tagname is %s.\n", xmlnode_get_name(point)); printf("Data is \"%s\"\n", xmlnode_get_data(point)); printf("Type is %d.\n", xmlnode_get_type(point)); point = xmlnode_get_nextsibling(point); printf("\n"); printf("Tagname is %s.\n", xmlnode_get_name(point)); printf("Data is %s.\n", xmlnode_get_data(point)); printf("Type is %d.\n", xmlnode_get_type(point)); point = xmlnode_get_nextsibling(point); printf("\n"); printf("Tagname is %s.\n", xmlnode_get_name(point)); printf("Data is %s.\n", xmlnode_get_data(point)); printf("Type is %d.\n", xmlnode_get_type(point)); point = xmlnode_get_nextsibling(point); printf("\n"); printf("Tagname is %s.\n", xmlnode_get_name(point)); printf("Data is %s.\n", xmlnode_get_data(point)); printf("Type is %d.\n", xmlnode_get_type(point)); point = xmlnode_get_nextsibling(point); /* point = xmlnode_get_nextsibling(point); point = xmlnode_get_firstchild(point); point = xmlnode_get_nextsibling(xmlnode_get_parent(point)); */ xmlnode_free(conf); } /* END MAIN */
xmlnode xmlnode_insert_tag_node(xmlnode parent, xmlnode node) { xmlnode child; child = xmlnode_insert_tag(parent, xmlnode_get_name(node)); if (xmlnode_has_attribs(node)) xmlnode_insert_node(child, xmlnode_get_firstattrib(node)); if (xmlnode_has_children(node)) xmlnode_insert_node(child, xmlnode_get_firstchild(node)); return child; }
/* blocks until namespace is retrieved, host must map back to this service! */ xmlnode xdb_get(xdbcache xc, jid owner, char *ns) { xdbcache newx; xmlnode x; pool p; if(xc == NULL || owner == NULL || ns == NULL) { fprintf(stderr,"Programming Error: xdb_get() called with NULL\n"); return NULL; } log_debug(ZONE,"XDB GET"); /* init this newx */ p = pool_new(); newx = pmalloco(p, sizeof(_xdbcache)); newx->i = xc->i; newx->set = 0; newx->data = NULL; newx->ns = ns; newx->owner = owner; newx->sent = time(NULL); newx->preblock = 0; /* flag */ pthread_mutex_lock(&(xc->sem)); newx->id = xc->id++; newx->next = xc->next; newx->prev = xc; newx->next->prev = newx; xc->next = newx; pthread_mutex_unlock(&(xc->sem)); /* send it on it's way */ xdb_deliver(xc->i, newx,0); /* if it hasn't already returned, we should block here until it returns */ while (newx->preblock != 1) usleep(10); /* newx.data is now the returned xml packet */ /* return the xmlnode inside <xdb>...</xdb> */ for(x = xmlnode_get_firstchild(newx->data); x != NULL && xmlnode_get_type(x) != NTYPE_TAG; x = xmlnode_get_nextsibling(x)); /* there were no children (results) to the xdb request, free the packet */ if(x == NULL) xmlnode_free(newx->data); pool_free(p); return x; }
xmlnode jutil_iqresult(xmlnode x) { xmlnode cur; jutil_tofrom(x); xmlnode_put_attrib(x,"type","result"); /* hide all children of the iq, they go back empty */ for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur)) xmlnode_hide(cur); return x; }
char* xmlnode_get_data(xmlnode node) { if(xmlnode_get_type(node) == NTYPE_TAG) /* loop till we find a CDATA in the children */ for(node = xmlnode_get_firstchild(node); node != NULL; node = xmlnode_get_nextsibling(node)) if(xmlnode_get_type(node) == NTYPE_CDATA) break; if(node == NULL) return NULL; /* check for a dirty node w/ unassembled cdata chunks */ if(xmlnode_get_type(node->next) == NTYPE_CDATA) _xmlnode_merge(node); return node->data; }
static spool _xmlnode2spool(xmlnode node) { spool s; int level=0,dir=0; xmlnode tmp; if(!node || xmlnode_get_type(node)!=NTYPE_TAG) return NULL; s = spool_new(xmlnode_pool(node)); if(!s) return(NULL); while(1) { if(dir==0) { if(xmlnode_get_type(node) == NTYPE_TAG) { if(xmlnode_has_children(node)) { _xmlnode_tag2str(s,node,1); node = xmlnode_get_firstchild(node); level++; continue; }else{ _xmlnode_tag2str(s,node,0); } }else{ spool_add(s,strescape(xmlnode_pool(node),xmlnode_get_data(node))); } } tmp = xmlnode_get_nextsibling(node); if(!tmp) { node = xmlnode_get_parent(node); level--; if(level>=0) _xmlnode_tag2str(s,node,2); if(level<1) break; dir = 1; }else{ node = tmp; dir = 0; } } return s; }
xmlnode xmlnode_dup_pool(pool p, xmlnode x) { xmlnode x2; if(x == NULL) return NULL; x2 = xmlnode_new_tag_pool(p, xmlnode_get_name(x)); if (xmlnode_has_attribs(x)) xmlnode_insert_node(x2, xmlnode_get_firstattrib(x)); if (xmlnode_has_children(x)) xmlnode_insert_node(x2, xmlnode_get_firstchild(x)); return x2; }
mreturn mod_browse_server(mapi m, void *arg) { xmlnode browse, query, x; if (m->packet->type != JPACKET_IQ) return M_IGNORE; if (jpacket_subtype(m->packet) != JPACKET__GET || !NSCHECK(m->packet->iq, NS_BROWSE) || m->packet->to->resource != NULL) return M_PASS; /* get data from the config file */ if ((browse = js_config(m->si, "browse")) == NULL) return M_PASS; log_debug("handling browse query"); /* build the result IQ */ query = xmlnode_insert_tag(jutil_iqresult(m->packet->x), "service"); xmlnode_put_attrib(query, "xmlns", NS_BROWSE); xmlnode_put_attrib(query, "type", "jabber"); xmlnode_put_attrib(query, "jid", m->packet->to->server); xmlnode_put_attrib(query, "name", xmlnode_get_data(js_config(m->si, "vCard/FN"))); /* pull name from the server vCard */ /* copy in the configured services */ xmlnode_insert_node(query, xmlnode_get_firstchild(browse)); /* list the admin stuff */ if (js_admin_jid(m->si, jid_user(m->packet->from), ADMIN_READ)) { x = xmlnode_insert_tag(query, "item"); xmlnode_put_attrib(x, "jid", spools(xmlnode_pool(x), m->packet->to->server, "/admin", xmlnode_pool(x))); xmlnode_put_attrib(x, "name", "Online Users"); xmlnode_insert_cdata(xmlnode_insert_tag(query, "ns"), NS_ADMIN, -1); } jpacket_reset(m->packet); js_deliver(m->si, m->packet); return M_HANDLED; }
/* we should be last in the list of modules */ JSM_FUNC void mod_log(jsmi si) { xmlnode cfg = js_config(si, "archive"); jid svcs = NULL; log_debug("mod_log init"); /* look for archiving service too */ for (cfg = xmlnode_get_firstchild(cfg); cfg != NULL; cfg = xmlnode_get_nextsibling(cfg)) { if (xmlnode_get_type(cfg) != NTYPE_TAG || j_strcmp(xmlnode_get_name(cfg), "service") != 0) continue; if (svcs == NULL) svcs = jid_new(si->p, xmlnode_get_data(cfg)); else jid_append(svcs, jid_new(si->p, xmlnode_get_data(cfg))); } js_mapi_register(si, e_SESSION, mod_log_session, (void *) svcs); }
mreturn mod_browse_set(mapi m, void *arg) { xmlnode browse, cur; jid id, to; if (m->packet->type != JPACKET_IQ) return M_IGNORE; if (!NSCHECK(m->packet->iq, NS_BROWSE) || jpacket_subtype(m->packet) != JPACKET__SET) return M_PASS; if (m->packet->to != NULL) return M_PASS; /* if its to someone other than ourselves */ log_debug("handling set request %s", xmlnode2str(m->packet->iq)); /* no to implies to ourselves */ if (m->packet->to != NULL) to = m->packet->to; else to = m->user->id; /* if we set to a resource, we need to make sure that resource's browse is in the users browse */ if (to->resource != NULL) { browse = mod_browse_get(m, to); /* get our browse info */ xmlnode_hide_attrib(browse, "xmlns"); /* don't need a ns as a child */ for (cur = xmlnode_get_firstchild(browse); cur != NULL; cur = xmlnode_get_nextsibling(cur)) xmlnode_hide(cur); /* erase all children */ xdb_act(m->si->xc, m->user->id, NS_BROWSE, "insert", spools(m->packet->p, "?jid=", jid_full(to), m->packet->p), browse); /* insert and match replace */ xmlnode_free(browse); } /* get the id of the new browse item */ if ((cur = xmlnode_get_firstchild(m->packet->iq)) == NULL || (id = jid_new(m->packet->p, xmlnode_get_attrib(cur, "jid"))) == NULL) { js_bounce(m->si, m->packet->x, TERROR_NOTACCEPTABLE); return M_HANDLED; } /* insert the new item into the resource it was sent to */ xmlnode_hide_attrib(cur, "xmlns"); /* just in case, to make sure it inserts */ if (xdb_act (m->si->xc, to, NS_BROWSE, "insert", spools(m->packet->p, "?jid=", jid_full(id), m->packet->p), cur)) { js_bounce(m->si, m->packet->x, TERROR_UNAVAIL); return M_HANDLED; } /* if the new data we're inserting is to one of our resources, update that resource's browse */ if (jid_cmpx(m->user->id, id, JID_USER | JID_SERVER) == 0 && id->resource != NULL) { /* get the old */ browse = mod_browse_get(m, id); /* transform the new one into the old one */ xmlnode_put_attrib(cur, "xmlns", NS_BROWSE); xmlnode_insert_node(cur, xmlnode_get_firstchild(browse)); xdb_set(m->si->xc, id, NS_BROWSE, cur); /* replace the resource's browse w/ this one */ xmlnode_free(browse); } /* send response to the user */ jutil_iqresult(m->packet->x); jpacket_reset(m->packet); js_session_to(m->s, m->packet); return M_HANDLED; }
/* any thread */ result js_packet(instance i, dpacket p, void *arg) { jsmi si = (jsmi) arg; jpacket jp = NULL; session s = NULL; packet_thread_p pt; udata u; char *type, *authto; log_debug("incoming packet %s", xmlnode2str(p->x)); /* if this is a routed packet */ if (p->type == p_ROUTE) { type = xmlnode_get_attrib(p->x, "type"); /* new session requests */ if (j_strcmp(type, "session") == 0) { js_session_new_mtq(si, p); return r_DONE; } /* get the internal jpacket */ if (xmlnode_get_firstchild(p->x) != NULL) /* XXX old libjabber jpacket_new() wasn't null safe, this is just safety */ jp = jpacket_new(xmlnode_get_firstchild(p->x)); /* auth/reg requests */ if (jp != NULL && j_strcmp(type, "auth") == 0) { /* check and see if we're configured to forward auth packets for processing elsewhere */ if ((authto = xmlnode_get_data(js_config(si, "auth"))) != NULL) { xmlnode_put_attrib(p->x, "oto", xmlnode_get_attrib(p->x, "to")); /* preserve original to */ xmlnode_put_attrib(p->x, "to", authto); deliver(dpacket_new(p->x), i); return r_DONE; } /* internally, hide the route to/from addresses on the authreg request */ xmlnode_put_attrib(jp->x, "to", xmlnode_get_attrib(p->x, "to")); xmlnode_put_attrib(jp->x, "from", xmlnode_get_attrib(p->x, "from")); xmlnode_put_attrib(jp->x, "route", xmlnode_get_attrib(p->x, "type")); jpacket_reset(jp); jp->aux1 = (void *) si; pt = pmalloco(jp->p, sizeof(packet_thread_t)); pt->jp = jp; fast_mtq_send(si->mtq_authreg, pt); return r_DONE; } /* if it's an error */ if (j_strcmp(type, "error") == 0) { /* look for users online */ u = js_user(si, p->id, 1); if (u == NULL) { /* if this was a message, it should have been delievered to that session, store offline */ if (jp != NULL && jp->type == JPACKET_MESSAGE) { pt = pmalloco(jp->p, sizeof (packet_thread_t)); pt->jp = jp; fast_mtq_send(si->mtq_deliver, pt); return r_DONE; } xmlnode_free(p->x); return r_DONE; /* log_notice(p->host, "Bouncing packet intended for nonexistant user: %s", xmlnode2str(p->x)); deliver_fail(dpacket_new(p->x), "Invalid User"); return r_DONE; */ } if (p->id->resource != NULL) { SEM_LOCK(u->sem); for (s = u->sessions; s != NULL; s = s->next) if (j_strcmp (p->id->resource, s->route->resource) == 0) break; SEM_UNLOCK(u->sem); if (s != NULL) { s->sid = NULL; /* they generated the error, no use in sending there anymore! */ js_session_end(s, "Disconnected"); } } else { session temp; /* a way to boot an entire user off */ SEM_LOCK(u->sem); for (s = u->sessions; s != NULL;) { temp = s; s = s->next; js_session_end_nosem(temp, "Removed"); } u->pass = NULL; /* so they can't log back in */ SEM_UNLOCK(u->sem); xmlnode_free(p->x); THREAD_DEC(u->ref); return r_DONE; } THREAD_DEC(u->ref); /* if this was a message, it should have been delievered to that session, store offline */ if (jp != NULL && jp->type == JPACKET_MESSAGE) { pt = pmalloco(jp->p, sizeof(packet_thread_t)); pt->jp = jp; fast_mtq_send(si->mtq_deliver, pt); return r_DONE; } /* drop and return */ if (xmlnode_get_firstchild(p->x) != NULL) log_notice(p->host, "Dropping a bounced session packet to %s", jid_full(p->id)); xmlnode_free(p->x); return r_DONE; } /* uhh, empty packet, *shrug* */ if (jp == NULL) { log_notice(p->host, "Dropping an invalid or empty route packet: %s", xmlnode2str(p->x), jid_full(p->id)); xmlnode_free(p->x); return r_DONE; } /* ============================================================== */ /* attempt to locate the session by matching the special resource */ u = js_user(si, p->id, 1); if (u == NULL) { /* only when route packet to users not online */ pt = pmalloco(p->p, sizeof(packet_thread_t)); pt->p = p; pt->jp = jp; fast_mtq_send(si->mtq_deliver, pt); return r_DONE; } /* user is online :) */ SEM_LOCK(u->sem); for (s = u->sessions; s != NULL; s = s->next) if (j_strcmp(p->id->resource, s->route->resource) == 0) break; SEM_UNLOCK(u->sem); THREAD_DEC(u->ref); if (s != NULL) { /* just pass to the session normally */ js_session_from(s, jp); return r_DONE; } log_notice(p->host, "Bouncing %s packet intended for session %s", xmlnode_get_name(jp->x), jid_full(p->id)); deliver_fail(dpacket_new(p->x), "Invalid Session"); return r_DONE; } /* normal server-server packet, should we make sure it's not spoofing us? if so, if ghash_get(p->to->server) then bounce w/ security error */ jp = jpacket_new(p->x); if (jp == NULL) { log_warn(p->host, "Dropping invalid incoming packet: %s", xmlnode2str(p->x)); xmlnode_free(p->x); return r_DONE; } pt = pmalloco(jp->p, sizeof(packet_thread_t)); pt->jp = jp; fast_mtq_send(si->mtq_deliver, pt); return r_DONE; }
/** Start up transport. Read configuration, register callbacks. */ void icqtrans(instance i, xmlnode x) { iti ti; pool p = i->p; xmlnode config; xmlnode cur; int check; log_debug(ZONE,"ICQ Transport, initializing for section '%s'",i->id); /* create new transport instance */ ti = pmalloco(p,sizeof(_iti)); ti->i = i; ti->xc = xdb_cache(i); config = xdb_get(ti->xc,jid_new(xmlnode_pool(x),"config@-internal"),"jabber:config:icqtrans"); if (config == NULL) { log_error(i->id,"Configuration not found!"); return; } ti->registration_instructions = pstrdup(p,xmlnode_get_tag_data(config,"instructions")); if (ti->registration_instructions == NULL) { log_debug(i->id,"Registration instructions not found"); } ti->search_instructions = pstrdup(p,xmlnode_get_tag_data(config,"search")); if (ti->search_instructions == NULL) { log_debug(i->id,"Search instructions not found"); } ti->charset = pstrdup(p,xmlnode_get_tag_data(config,"charset")); if (ti->charset == NULL) { log_debug(i->id,"Charset not specified, set default to %s ",DEFAULT_CHARSET); ti->charset = pstrdup(p,DEFAULT_CHARSET); } _ucs2utf = iconv_open("UTF-8","UCS-2BE"); _win2utf = iconv_open("UTF-8",ti->charset); if (_win2utf==(iconv_t)-1) { ti->charset = pstrdup(p,DEFAULT_CHARSET); _win2utf = iconv_open("UTF-8",ti->charset); if (_win2utf==(iconv_t)-1) { log_error(i->id,"Charset error!"); return; } } _utf2win = iconv_open(ti->charset,"UTF-8"); if (_utf2win ==(iconv_t)-1) { ti->charset = pstrdup(p,DEFAULT_CHARSET); _utf2win = iconv_open(ti->charset,"UTF-8"); if (_utf2win ==(iconv_t)-1) { log_error(i->id,"Charset error!"); return; } } log_notice("config","charset %s",ti->charset); ti->msg_chat = xmlnode_get_tag(config,"chat") ? 1 : 0; if (ti->msg_chat) { log_notice("config","chat messages enabled"); } ti->web_aware = xmlnode_get_tag(config,"web") ? 1 : 0; if (ti->web_aware) { log_notice("config","web presence enabled"); } ti->own_roster = xmlnode_get_tag(config,"own_roster") ? 1 : 0; if (ti->own_roster) { log_notice("config","JIT will use own roster"); } ti->no_jabber_roster = xmlnode_get_tag(config,"no_jabber_roster") ? 1 : 0; if (ti->no_jabber_roster) { log_notice("config","JIT willn't get users from jabber roster"); } ti->no_x_data = xmlnode_get_tag(config,"no_xdata") ? 1 : 0; if (ti->no_x_data) { log_notice("config","JIT will not use xdata"); } cur = xmlnode_get_tag(config,"sms"); if (cur) { ti->sms_id = pstrdup(p,xmlnode_get_tag_data(cur,"host")); if (ti->sms_id) { ti->sms_show = jit_show2status(xmlnode_get_tag_data(cur,"show")); if (ti->sms_show==ICQ_STATUS_NOT_IN_LIST) { ti->sms_show = ICQ_STATUS_ONLINE; } log_notice("config","sms host %s show: %d",ti->sms_id,ti->sms_show); ti->sms_status = pstrdup(p,xmlnode_get_tag_data(cur,"status")); if (ti->sms_status) { log_debug(ZONE,"sms st %s ",ti->sms_status); } ti->sms_name = pstrdup(p,xmlnode_get_tag_data(cur,"name")); if (ti->sms_name) { log_debug(ZONE,"sms name %s",ti->sms_name); } } } ti->count_file = pstrdup(p,xmlnode_get_tag_data(config,"user_count_file")); if (ti->count_file == NULL) { ti->count_file = "icqcount"; } log_notice("config","Using %s as count log file",ti->count_file); for (cur = xmlnode_get_firstchild(xmlnode_get_tag(config,"server")); cur != NULL; cur = xmlnode_get_nextsibling(cur)) { char * port; char * host; if (xmlnode_get_type(cur) != NTYPE_TAG) continue; if ((port = xmlnode_get_attrib(cur,"port")) == NULL) continue; if ((host = xmlnode_get_data(cur)) == NULL) continue; ti->auth_hosts[ti->auth_hosts_count] = pstrdup(p,host); ti->auth_ports[ti->auth_hosts_count] = j_atoi(port,5190); log_debug(ZONE,"Host %s port %d at pos %d", ti->auth_hosts[ti->auth_hosts_count], ti->auth_ports[ti->auth_hosts_count], ti->auth_hosts_count); ti->auth_hosts_count++; if (ti->auth_hosts_count >= MAX_AUTH_HOSTS) break; } if (ti->auth_hosts_count == 0) { log_alert("err","No hosts to auth icq client !. Using default"); ti->auth_hosts[ti->auth_hosts_count] = pstrdup(p,"205.188.179.233"); ti->auth_ports[ti->auth_hosts_count] = 5190; ti->auth_hosts_count++; } /* add queue for unknown packets */ ti->q = mtq_new(i->p); ti->sessions = wpxhash_new(j_atoi(xmlnode_get_tag_data(config,"prime"),509)); ti->sessions_alt = wpxhash_new(j_atoi(xmlnode_get_tag_data(config,"prime"),509)); SEM_INIT(ti->sessions_sem); ti->vcard = xmlnode_new_tag_pool(p,"vCard"); xmlnode_put_attrib(ti->vcard,"xmlns",NS_VCARD); xmlnode_insert_node(ti->vcard,xmlnode_get_firstchild(xmlnode_get_tag(config,"vCard"))); /* default 5 hours */ ti->session_timeout = j_atoi(xmlnode_get_tag_data(config,"session_timeout"),18000); log_notice("config","session_timeout in sec : %d",ti->session_timeout); ti->reconnect = j_atoi(xmlnode_get_tag_data(config,"reconnects"),0); log_notice("config","Number of reconnects for session %d",ti->reconnect); check = j_atoi(xmlnode_get_tag_data(config,"session_check"),10); log_notice("config","JIT will check session every %d sec",check); // ti->admin = xmlnode_dup(xmlnode_get_tag(config,"admin")); ti->start = time(NULL); /* Register callbacks */ register_phandler(i,o_DELIVER,it_receive,(void *) ti); register_shutdown(it_shutdown,(void *) ti); /* Start up heartbeat thread */ register_beat(check,it_sessions_check,(void *) ti); xmlnode_free(config); }
mreturn mod_agents_agents(mapi m) { xmlnode ret, retq, agents, cur, a, cur2; /* get data from the config file */ agents = js_config(m->si, "browse"); /* if we don't have anything to say, bounce */ if (agents == NULL) return M_PASS; log_debug("handling agents query"); /* build the result IQ */ ret = jutil_iqresult(m->packet->x); retq = xmlnode_insert_tag(ret, "query"); xmlnode_put_attrib(retq, "xmlns", NS_AGENTS); /* parse the new browse data into old agents format */ for (cur = xmlnode_get_firstchild(agents); cur != NULL; cur = xmlnode_get_nextsibling(cur)) { if (xmlnode_get_type(cur) != NTYPE_TAG) continue; /* generic <agent> part */ a = xmlnode_insert_tag(retq, "agent"); xmlnode_put_attrib(a, "jid", xmlnode_get_attrib(cur, "jid")); xmlnode_insert_cdata(xmlnode_insert_tag(a, "name"), xmlnode_get_attrib(cur, "name"), -1); xmlnode_insert_cdata(xmlnode_insert_tag(a, "service"), xmlnode_get_attrib(cur, "type"), -1); if (j_strcmp(xmlnode_get_name(cur), "conference") == 0) xmlnode_insert_tag(a, "groupchat"); /* map the included <ns>'s in browse to the old agent flags */ for (cur2 = xmlnode_get_firstchild(cur); cur2 != NULL; cur2 = xmlnode_get_nextsibling(cur2)) { if (j_strcmp(xmlnode_get_name(cur2), "ns") != 0) continue; if (j_strcmp (xmlnode_get_data(cur2), "jabber:iq:register") == 0) xmlnode_insert_tag(a, "register"); if (j_strcmp (xmlnode_get_data(cur2), "jabber:iq:search") == 0) xmlnode_insert_tag(a, "search"); if (j_strcmp (xmlnode_get_data(cur2), "jabber:iq:gateway") == 0) xmlnode_insert_cdata(xmlnode_insert_tag (a, "transport"), "Enter ID", -1); } } jpacket_reset(m->packet); if (m->s != NULL) { /* XXX null session hack! */ xmlnode_put_attrib(m->packet->x, "from", m->packet->from->server); js_session_to(m->s, m->packet); } else { js_deliver(m->si, m->packet); } return M_HANDLED; }
User *user_load(const char *jid){ char *fn,*njid; xmlnode xml,tag,t; char *uin,*ujid,*name,*password,*email,*locale; char *status; int last_sys_msg=0,invisible=0,friends_only=0,ignore_unknown=0; unsigned int file_format_version=0; SubscriptionType subscribe; User *u; GList *contacts; char *p; char *data; uin=ujid=name=password=email=NULL; debug(L_("Loading user '%s'"),jid); fn=jid_normalized(jid,0); if (fn==NULL){ g_warning(L_("Bad JID: %s"),jid); return NULL; } errno=0; xml=xmlnode_file(fn); if (xml==NULL){ debug(L_("Couldn't read or parse '%s': %s"),fn,errno?g_strerror(errno):N_("XML parse error")); g_free(fn); return NULL; } g_free(fn); tag=xmlnode_get_tag(xml,"version"); if (tag!=NULL) { p=xmlnode_get_attrib(tag,"file_format"); if (p!=NULL) file_format_version=(unsigned int)strtol(p,NULL,16); } tag=xmlnode_get_tag(xml,"jid"); if (tag!=NULL) { ujid=xmlnode_get_data(tag); subscribe=get_subscribe(tag, file_format_version); } if (ujid==NULL){ g_warning(L_("Couldn't find JID in %s's file"),jid); return NULL; } tag=xmlnode_get_tag(xml,"uin"); if (tag!=NULL) uin=xmlnode_get_data(tag); if (uin==NULL){ g_warning(L_("Couldn't find UIN in %s's file"),jid); return NULL; } tag=xmlnode_get_tag(xml,"password"); if (tag!=NULL) password=xmlnode_get_data(tag); if (password==NULL){ g_warning(L_("Couldn't find password in %s's file"),jid); return NULL; } tag=xmlnode_get_tag(xml,"email"); if (tag!=NULL) email=xmlnode_get_data(tag); tag=xmlnode_get_tag(xml,"name"); if (tag!=NULL) name=xmlnode_get_data(tag); tag=xmlnode_get_tag(xml,"last_sys_msg"); if (tag!=NULL){ data=xmlnode_get_data(tag); if (data!=NULL) last_sys_msg=atoi(data); } tag=xmlnode_get_tag(xml,"friendsonly"); if (tag!=NULL) friends_only=1; tag=xmlnode_get_tag(xml,"invisible"); if (tag!=NULL) invisible=1; tag=xmlnode_get_tag(xml,"ignore_unknown"); if (tag!=NULL) ignore_unknown=1; tag=xmlnode_get_tag(xml,"locale"); if (tag!=NULL) locale=xmlnode_get_data(tag); else locale=NULL; tag=xmlnode_get_tag(xml,"status"); if (tag!=NULL) { status=xmlnode_get_data(tag); if (status==NULL) status=""; } else status=NULL; tag=xmlnode_get_tag(xml,"userlist"); contacts=NULL; if (tag!=NULL){ Contact *c; for(t=xmlnode_get_firstchild(tag);t;t=xmlnode_get_nextsibling(t)){ char *node_name; node_name=xmlnode_get_name(t); if (!node_name) continue; if (!strcmp(node_name,"uin")){ char *d; int uin; d=xmlnode_get_data(t); if (d==NULL) continue; uin=atoi(d); if (uin<=0) continue; c=g_new0(Contact,1); c->status=-1; c->uin=uin; contacts=g_list_append(contacts,c); continue; } if (!strcmp(node_name,"contact")){ char *d; int uin; d=xmlnode_get_attrib(t,"uin"); if (d==NULL) continue; uin=atoi(d); if (uin<=0) continue; c=g_new0(Contact,1); c->status=-1; c->uin=uin; d=xmlnode_get_attrib(t,"ignored"); if (d!=NULL && d[0]!='\000') c->ignored=1; else c->ignored=0; d=xmlnode_get_attrib(t,"blocked"); if (d!=NULL && d[0]!='\000') c->blocked=1; else c->blocked=0; c->subscribe=get_subscribe(t, file_format_version); contacts=g_list_append(contacts,c); } } } u=g_new0(User,1); u->uin=atoi(uin); u->jid=g_strdup(jid); p=strchr(u->jid,'/'); if (p) *p=0; u->password=g_strdup(password); u->last_sys_msg=last_sys_msg; u->friends_only=friends_only; u->invisible=invisible; u->ignore_unknown=ignore_unknown; u->locale=g_strdup(locale); u->status=g_strdup(from_utf8(status)); u->contacts=contacts; xmlnode_free(xml); g_assert(users_jid!=NULL); njid=jid_normalized(u->jid,0); g_assert(njid!=NULL); g_hash_table_insert(users_jid,(gpointer)njid,(gpointer)u); u->confirmed=1; u->subscribe=subscribe; return u; }
mreturn mod_stats_server(mapi m, void *arg) { xmlnode cur; int i; if (m->packet->type != JPACKET_IQ) return M_IGNORE; if (jpacket_subtype(m->packet) != JPACKET__GET) return M_PASS; if (!NSCHECK(m->packet->iq, NS_STATS)) return M_PASS; if (m->packet->to->resource) return M_PASS; /* get data from the config file */ i = 0; if (xmlnode_get_tag(js_config(m->si, "stats"), "allow_all") != NULL) i = 1; log_debug("handling stats get %s", jid_full(m->packet->from)); /* check if admin */ if ((i == 0) && (!js_admin_jid(m->si, jid_user(m->packet->from), ADMIN_READ))) { jutil_error(m->packet->x, TERROR_AUTH); jpacket_reset(m->packet); js_deliver(m->si, m->packet); return M_HANDLED; } /* check if any stat have given iq query */ cur = xmlnode_get_firstchild(m->packet->iq); for (; cur != NULL; cur = xmlnode_get_nextsibling(cur)) { if (xmlnode_get_type(cur) != NTYPE_TAG) continue; break; } if (cur != NULL) cur = xmlnode_get_firstchild(m->packet->iq); jutil_tofrom(m->packet->x); xmlnode_put_attrib(m->packet->x, "type", "result"); /* return available stats */ if (!cur) { for (i = 0; available_stats[i]; i++) { xmlnode_put_attrib(xmlnode_insert_tag (m->packet->iq, "stat"), "name", available_stats[i]); } jpacket_reset(m->packet); js_deliver(m->si, m->packet); return M_HANDLED; } /* return server stats */ /* cur is already first stat */ for (; cur != NULL; cur = xmlnode_get_nextsibling(cur)) { char *name; char buf[31]; int found; if (xmlnode_get_type(cur) != NTYPE_TAG) continue; if (j_strcmp(xmlnode_get_name(cur), "stat") != 0) continue; name = xmlnode_get_attrib(cur, "name"); if (!name) continue; log_debug("get stats for %s", name); found = 0; for (i = 0; available_stats[i]; i++) { if (j_strcmp(available_stats[i], name) != 0) continue; log_debug("stats for %s", name); /* give stats */ found = 1; /* time/uptime */ if (j_strcmp(name, "time/uptime") == 0) { snprintf(buf, 30, "%d", time(NULL) - m->si->stats->started); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "seconds"); } /* users/online */ if (j_strcmp(name, "users/online") == 0) { snprintf(buf, 30, "%d", m->si->stats->sessioncount); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "users"); } if (j_strcmp(name, "users/max_online_today") == 0) { snprintf(buf, 30, "%d", m->si->stats->session_max_today); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "users"); } if (j_strcmp(name, "users/max_online_yesterday") == 0) { snprintf(buf, 30, "%d", m->si->stats-> session_max_yesterday); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "users"); } if (j_strcmp(name, "users/registered_today") == 0) { snprintf(buf, 30, "%d", m->si->stats-> users_registered_today); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "users"); } if (j_strcmp(name, "users/registered_from_start") == 0) { snprintf(buf, 30, "%d", m->si->stats-> users_registered_from_start); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "users"); } if (j_strcmp(name, "bandwidth/packets-in") == 0) { snprintf(buf, 30, "%lu", m->si->stats->packets_in); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "packets"); } if (j_strcmp(name, "bandwidth/packets-out") == 0) { snprintf(buf, 30, "%lu", m->si->stats->packets_out); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "packets"); } #ifndef WIN32 if (j_strcmp(name, "memory/usage") == 0) { long mem = get_memory_usage(); if (mem > 0) { snprintf(buf, 30, "%lu", mem); xmlnode_put_attrib(cur, "value", buf); xmlnode_put_attrib(cur, "units", "bytes"); } else found = 0; } #endif break; } if (found <= 0) { xmlnode err; err = xmlnode_insert_tag(cur, "error"); xmlnode_put_attrib(err, "code", "404"); xmlnode_insert_cdata(err, "Not Found", -1); } } jpacket_reset(m->packet); js_deliver(m->si, m->packet); return M_HANDLED; }
/* blocks until namespace is retrieved, host must map back to this service! */ xmlnode xdb_get(xdbcache xc, jid owner, char *ns) { xdbrequest_p cur; xmlnode x; struct timeval tv; if (xc->shutdown) return NULL; if (xc == NULL || owner == NULL || ns == NULL) { if (ns) { log_alert("xdb_get", "Programming Error: xdb_get() called with NULL ns: %s\n", ns); } else { log_alert("xdb_get", "Programming Error: xdb_get() called with NULL ns: NULL\n"); } if (owner) { log_alert("owner", "%s", jid_full(owner)); } return NULL; } log_debug("XDB GET"); /* init this newx */ cur = malloc(sizeof(xdbrequest_t)); memset(cur, 0, sizeof(xdbrequest_t)); // cur->set = 0; // cur->data = NULL; cur->ns = ns; cur->owner = owner; gettimeofday(&tv, NULL); cur->sent = tv.tv_sec; SEM_LOCK(xc->sem); cur->id = xc->id++; cur->next = xc->first; xc->first = cur; SEM_UNLOCK(xc->sem); /* send it on it's way */ xdb_deliver(xc->i, cur, 0); cur->external = 1; /* if it hasn't already returned, we should block here until it returns */ while (cur->preblock != 1) usleep(10); /* newx.data is now the returned xml packet */ /* return the xmlnode inside <xdb>...</xdb> */ for (x = xmlnode_get_firstchild(cur->data); x != NULL && xmlnode_get_type(x) != NTYPE_TAG; x = xmlnode_get_nextsibling(x)); /* there were no children (results) to the xdb request, free the packet */ if (x == NULL) xmlnode_free(cur->data); free(cur); return x; }
int sessions_init(){ char *proxy_ip,*proxy_username,*proxy_password,*proxy_http_only; char *p,*r; int port; int i; xmlnode parent,tag; GgServer *server; stream_add_destroy_handler(sessions_stream_destroyed); sessions_jid=g_hash_table_new(g_str_hash,g_str_equal); if (!sessions_jid) return -1; i=config_load_int("conn_timeout",0); if (i>0) conn_timeout=i; i=config_load_int("pong_timeout",0); if (i>0) pong_timeout=i; i=config_load_int("ping_interval",0); if (i>0) ping_interval=i; i=config_load_int("reconnect",0); if (i>0) reconnect=i; i=config_load_int("server_cutoff",0); if (i>0) cutoff=i; i=config_load_int("server_cutoff_timeout",0); if (i>0) cutoff_timeout=i; tag = xmlnode_get_tag(config, "ignore_system_messages"); if (!tag) { ignore_system_messages = ISM_IGNORE_NONE; } else { r=xmlnode_get_attrib(tag, "which"); if (r && !g_strcasecmp(r,"html")) { ignore_system_messages = ISM_IGNORE_HTML; } else { ignore_system_messages = ISM_IGNORE_ALL; } } parent=xmlnode_get_tag(config,"servers"); if (parent && xmlnode_has_children(parent)){ gg_servers=NULL; for(tag=xmlnode_get_firstchild(parent); tag!=NULL; tag=xmlnode_get_nextsibling(tag)){ if(xmlnode_get_type(tag) != NTYPE_TAG) continue; p=xmlnode_get_name(tag); if (strcmp(p, "hub")==0){ server=g_new(GgServer, 1); server->port=1; gg_servers=g_list_append(gg_servers, server); } else if (strcmp(p, "server")==0){ server=g_new(GgServer, 1); server->error_count=0; r=xmlnode_get_attrib(tag, "port"); if (r) server->port=atoi(r); else server->port=8074; r=xmlnode_get_data(tag); if(inet_aton(r, &server->addr)) gg_servers=g_list_append(gg_servers, server); } else continue; r=xmlnode_get_attrib(tag, "tls"); if (r && !g_strcasecmp(r,"no")) server->tls=0; else server->tls=1; } } else{ server=g_new(GgServer, 1); server->port=1; server->tls=0; gg_servers=g_list_append(gg_servers, server); server=g_new(GgServer, 1); server->error_count=0; inet_aton("217.17.45.145", &server->addr); server->port=8074; server->tls=0; gg_servers=g_list_append(gg_servers, server); } proxy_ip=config_load_string("proxy/ip"); if (!proxy_ip) return 0; port=config_load_int("proxy/port",0); if (port<=0) return 0; proxy_username=config_load_string("proxy/username"); proxy_password=config_load_string("proxy/password"); tag=xmlnode_get_tag(config,"proxy"); proxy_http_only=xmlnode_get_attrib(tag,"http_only"); g_message(L_("Using proxy: http://%s:%i"),proxy_ip,port); gg_proxy_enabled=1; gg_proxy_host=proxy_ip; gg_proxy_port=port; if (proxy_username && proxy_password){ gg_proxy_username=proxy_username; gg_proxy_password=proxy_password; } if (proxy_http_only && strcmp(proxy_http_only,"no")){ gg_proxy_http_only=1; } return 0; }
int xdbsql_roomoutcast_set(XdbSqlDatas * self, const char *room, xmlnode data) { xmlnode query; /* the query for this function */ xmlnode x, x2; /* used to iterate through the rules */ query_def qd; /* the query definition */ XdbSqlResult *result; /* return from query */ char *data_userid = NULL; char *data_reason = NULL; char *data_responsibleid = NULL; char *data_responsiblenick = NULL; const char *querystring; char *name; if (!room) { /* the room was not specified - we have to bug off */ log_error(NULL, "[xdbsql_roomoutcast_set] room not specified"); return 0; } if (!data) { return roomoutcast_purge(self, room); } /* Get the query definition. */ query = xdbsql_query_get(self, "roomoutcast-set"); if (!query) { log_error(NULL, "--!!-- WTF? roomoutcast-set query not found?"); return 0; } /* Purge any existing roomconfig data. */ roomoutcast_purge(self, room); for (x = xmlnode_get_firstchild(data); x; x = xmlnode_get_nextsibling(x)) { qd = xdbsql_querydef_init(self, query); xdbsql_querydef_setvar(qd, "room", room); data_userid = data_reason = data_responsibleid = data_responsiblenick = NULL; name = xmlnode_get_name(x); if (j_strcmp(name, "item") == 0) { data_userid = xmlnode_get_attrib(x, "jid"); for (x2 = xmlnode_get_firstchild(x); x2; x2 = xmlnode_get_nextsibling(x2)) { name = xmlnode_get_name(x2); if (j_strcmp(name, "reason") == 0) { data_responsibleid = xmlnode_get_attrib(x2, "actor"); data_responsiblenick = xmlnode_get_attrib(x2, "nick"); data_reason = GET_CHILD_DATA(x2); } } } if (data_userid && *data_userid) xdbsql_querydef_setvar(qd, "userid", data_userid); if (data_reason && *data_reason) xdbsql_querydef_setvar(qd, "reason", data_reason); if (data_responsibleid && *data_responsibleid) xdbsql_querydef_setvar(qd, "responsibleid", data_responsibleid); if (data_responsiblenick && *data_responsiblenick) xdbsql_querydef_setvar(qd, "responsiblenick", data_responsiblenick); querystring = xdbsql_querydef_finalize(qd); result = sqldb_query(self, querystring); xdbsql_querydef_free(qd); if (!result) log_error(NULL, "[xdbsql_roomoutcast_set] query failed : %s", sqldb_error(self)); else sqldb_free_result(result); } return 1; }