result base_to_deliver(instance id, dpacket p, void *arg) { char *log_data = xmlnode_get_data(p->x); char *subject; xmlnode message; if (log_data == NULL) return r_ERR; message = xmlnode_new_tag("message"); xmlnode_insert_cdata(xmlnode_insert_tag(message, "body"), log_data, -1); subject = spools(xmlnode_pool(message), "Log Packet from ", xmlnode_get_attrib(p->x, "from"), xmlnode_pool(message)); xmlnode_insert_cdata(xmlnode_insert_tag(message, "thread"), shahash(subject), -1); xmlnode_insert_cdata(xmlnode_insert_tag(message, "subject"), subject, -1); xmlnode_put_attrib(message, "from", xmlnode_get_attrib(p->x, "from")); xmlnode_put_attrib(message, "to", (char *) arg); deliver(dpacket_new(message), id); pool_free(p->p); return r_DONE; }
int xmlnode2file(char *file, xmlnode node) { char *doc, *ftmp; int fd, i; if(file == NULL || node == NULL) return -1; ftmp = spools(xmlnode_pool(node),file,".t.m.p",xmlnode_pool(node)); fd = open(ftmp, O_CREAT | O_WRONLY | O_TRUNC, 0600); if(fd < 0) return -1; doc = xmlnode2str(node); i = write(fd,doc,strlen(doc)); if(i < 0) return -1; close(fd); if(rename(ftmp,file) < 0) { unlink(ftmp); return -1; } return 1; }
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; }
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); }
result base_to_config(instance id, xmlnode x, void *arg) { if (id == NULL) { jid j = jid_new(xmlnode_pool(x), xmlnode_get_data(x)); log_debug("base_to_config validating configuration\n"); if (j == NULL) { xmlnode_put_attrib(x, "error", "'to' tag must contain a jid to send log data to"); log_debug("Invalid Configuration for base_to"); return r_ERR; } return r_PASS; } log_debug("base_to configuring instance %s", id->id); if (id->type != p_LOG) { log_alert(NULL, "ERROR in instance %s: <to>..</to> element only allowed in log sections", id->id); return r_ERR; } register_phandler(id, o_DELIVER, base_to_deliver, (void *) xmlnode_get_data(x)); return r_DONE; }
/* actually deliver the xdb request */ void xdb_deliver(instance i, xdbcache xc, int another_thread) { xmlnode x; char ids[15]; x = xmlnode_new_tag("xdb"); if(xc->set) { xmlnode_put_attrib(x,"type","set"); xmlnode_insert_tag_node(x,xc->data); /* copy in the data */ if(xc->act != NULL) xmlnode_put_attrib(x,"action",xc->act); if(xc->match != NULL) xmlnode_put_attrib(x,"match",xc->match); } else { xmlnode_put_attrib(x,"type","get"); } xmlnode_put_attrib(x,"to",jid_full(xc->owner)); xmlnode_put_attrib(x,"from",i->id); xmlnode_put_attrib(x,"ns",xc->ns); sprintf(ids,"%d",xc->id); xmlnode_put_attrib(x,"id",ids); /* to track response */ if (another_thread) { xdb_resend cur = pmalloco(xmlnode_pool(x),sizeof(_xdb_resend)); cur->x = x; cur->i = i; mtq_send(NULL,NULL,resend_xdb,(void *)cur); } else { deliver(dpacket_new(x), i); } }
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; }
xmlnode xmlnode_wrap(xmlnode x,const char *wrapper) { xmlnode wrap; if(x==NULL||wrapper==NULL) return NULL; wrap=xmlnode_new_tag_pool(xmlnode_pool(x),wrapper); if(wrap==NULL) return NULL; wrap->firstchild=x; wrap->lastchild=x; x->parent=wrap; return wrap; }
jpacket jpacket_new(xmlnode x) { jpacket p; if(x == NULL) return NULL; p = pmalloc(xmlnode_pool(x),sizeof(_jpacket)); p->x = x; return jpacket_reset(p); }
static xmlnode _xmlnode_append_sibling(xmlnode lastsibling, const char* name, unsigned int type) { xmlnode result; result = _xmlnode_new(xmlnode_pool(lastsibling), name, type); if (result != NULL) { /* Setup sibling pointers */ result->prev = lastsibling; lastsibling->next = result; } return result; }
jpacket jpacket_reset(jpacket p) { char *val; xmlnode x; x = p->x; memset(p,0,sizeof(_jpacket)); p->x = x; p->p = xmlnode_pool(x); if(strcmp(xmlnode_get_name(x),"message") == 0) { p->type = JPACKET_MESSAGE; }else if(strcmp(xmlnode_get_name(x),"presence") == 0) { p->type = JPACKET_PRESENCE; val = xmlnode_get_attrib(x, "type"); if(val == NULL) p->subtype = JPACKET__AVAILABLE; else if(strcmp(val,"unavailable") == 0) p->subtype = JPACKET__UNAVAILABLE; else if(strcmp(val,"probe") == 0) p->subtype = JPACKET__PROBE; else if(strcmp(val,"error") == 0) p->subtype = JPACKET__ERROR; else if(strcmp(val,"invisible") == 0) p->subtype = JPACKET__INVISIBLE; else if(*val == 's' || *val == 'u') p->type = JPACKET_S10N; else p->type = JPACKET_UNKNOWN; }else if(strcmp(xmlnode_get_name(x),"iq") == 0) { p->type = JPACKET_IQ; p->iq = xmlnode_get_tag(x,"?xmlns"); p->iqns = xmlnode_get_attrib(p->iq,"xmlns"); } /* set up the jids if any, flag packet as unknown if they are unparseable */ val = xmlnode_get_attrib(x,"to"); if(val != NULL) if((p->to = jid_new(p->p, val)) == NULL) p->type = JPACKET_UNKNOWN; val = xmlnode_get_attrib(x,"from"); if(val != NULL) if((p->from = jid_new(p->p, val)) == NULL) p->type = JPACKET_UNKNOWN; return p; }
void at_auth_subscribe(ati ti, jpacket jp) { /* Here we actually subscribe to the user */ xmlnode x; jid jnew; x = xmlnode_new_tag("presence"); jnew = jid_new(xmlnode_pool(x), ti->i->id); jid_set(jnew, "registered", JID_RESOURCE); log_debug(ZONE, "[AIM] Subscribing to %s presence\n", jid_full(jp->from)); xmlnode_put_attrib(x, "to", jid_full(jp->from)); xmlnode_put_attrib(x, "from", jid_full(jnew)); xmlnode_put_attrib(x, "type", "subscribe"); at_deliver(ti,x); return; }
/* Browse for members of a room */ void con_room_browsewalk(gpointer key, gpointer data, gpointer arg) { jid userjid; cnu user = (cnu)data; xmlnode q = (xmlnode)arg; xmlnode xml; if(user == NULL || q == NULL) { log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE); return; } xml = xmlnode_insert_tag(q, "item"); userjid = jid_new(xmlnode_pool(xml), jid_full(user->room->id)); jid_set(userjid, user->localid->resource, JID_RESOURCE); xmlnode_put_attrib(xml, "category", "user"); xmlnode_put_attrib(xml, "type", "client"); xmlnode_put_attrib(xml, "name", user->localid->resource); xmlnode_put_attrib(xml, "jid", jid_full(userjid)); }
static void _xmlnode_tag2str(spool s, xmlnode node, int flag) { xmlnode tmp; if(flag==0 || flag==1) { spooler(s,"<",xmlnode_get_name(node),s); tmp = xmlnode_get_firstattrib(node); while(tmp) { spooler(s," ",xmlnode_get_name(tmp),"='",strescape(xmlnode_pool(node),xmlnode_get_data(tmp)),"'",s); tmp = xmlnode_get_nextsibling(tmp); } if(flag==0) spool_add(s,"/>"); else spool_add(s,">"); } else { spooler(s,"</",xmlnode_get_name(node),">",s); } }
void con_get_affiliate_list(gpointer key, gpointer data, gpointer arg) { xmlnode node; cnr room; taffil affiliation; jid userid; char *actor; char *reason; xmlnode result = (xmlnode)arg; xmlnode item = (xmlnode)data; if(result == NULL || item == NULL) { log_warn(NAME, "[%s] Aborting: NULL attribute(s) - <%s>", FZONE, (char *) key); return; } actor = xmlnode_get_attrib(item, "actor"); reason = xmlnode_get_data(item); room = (cnr)xmlnode_get_vattrib(result ,"cnr"); node = xmlnode_insert_tag(result, "item"); userid = jid_new(xmlnode_pool(node), key); xmlnode_put_attrib(node, "jid", key); affiliation = affiliation_level(room, userid); xmlnode_put_attrib(node, "affiliation", affiliation.msg); if(reason != NULL) xmlnode_insert_cdata(xmlnode_insert_tag(node, "reason"), reason, -1); if(actor != NULL) xmlnode_insert_cdata(xmlnode_insert_tag(node, "actor"), actor, -1); }
void con_get_role_list(gpointer key, gpointer data, gpointer arg) { xmlnode node; xmlnode result; taffil affiliation; trole role; jid userid; cnr room; result = (xmlnode)arg; if(result == NULL) { log_warn(NAME, "[%s] Aborting: NULL result - <%s>", FZONE, (char*) key); return; } room = (cnr)xmlnode_get_vattrib(result ,"cnr"); if(room == NULL) { log_warn(NAME, "[%s] Aborting: NULL room - <%s>", FZONE, (char*) key); return; } node = xmlnode_insert_tag(result, "item"); userid = jid_new(xmlnode_pool(node), key); xmlnode_put_attrib(node, "jid", key); affiliation = affiliation_level(room, userid); role = role_level(room, userid); xmlnode_put_attrib(node, "role", role.msg); xmlnode_put_attrib(node, "affiliation", affiliation.msg); }
/** 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); }
/* Handles logging for each room, simply returning if logfile is not defined */ void con_room_log(cnr room, char *nick, char *message) { time_t t; xmlnode xml; jid user; char *output; char timestr[80]; size_t timelen = 79; FILE *logfile; pool p; if(message == NULL || room == NULL) { log_warn(NAME, "[%s] ERR: Aborting - NULL reference found - ", FZONE); return; } logfile = room->logfile; if(logfile == NULL) { log_debug(NAME, "[%s] Logging not enabled for this room", FZONE); return; } p = pool_heap(1024); /* nicked from mod_time */ t = time(NULL); if(room->logformat == LOG_XHTML) strftime(timestr, timelen, "<a name=\"t%H:%M:%S\" href=\"#t%H:%M:%S\">[%H:%M:%S]</a>", localtime(&t)); else strftime(timestr, timelen, "[%H:%M:%S]", localtime(&t)); if(room->logformat == LOG_XML) { xml = jutil_msgnew("groupchat", jid_full(room->id) , NULL, strescape(p, message)); user = jid_new(xmlnode_pool(xml), jid_full(room->id)); jid_set(user, strescape(p, nick), JID_RESOURCE); xmlnode_put_attrib(xml, "from", jid_full(user)); jutil_delay(xml, NULL); fprintf(logfile, "%s\n", xmlnode2str(xml)); xmlnode_free(xml); } else if(room->logformat == LOG_XHTML) { if(nick) { if(j_strncmp(message, "/me ", 4) == 0) { output = extractAction(_con_room_xhtml_strescape(p, message), p); fprintf(logfile, "<span class=\"time\">%s</span> * <span class=\"nick\">%s</span>%s<br />\n", timestr, strescape(p, nick), output); } else { fprintf(logfile, "<span class=\"time\">%s</span> <<span class=\"nick\">%s</span>> %s<br />\n", timestr, strescape(p, nick), _con_room_xhtml_strescape(p, message)); } } else { fprintf(logfile, "<span class=\"time\">%s</span> --- %s<br />\n", timestr, message); } } else { if(nick) { if(j_strncmp(message, "/me ", 4) == 0) { output = extractAction(message, p); fprintf(logfile, "%s * %s%s\n", timestr, nick, output); } else { fprintf(logfile, "%s <%s> %s\n", timestr, nick, message); } } else { fprintf(logfile, "%s --- %s\n", timestr, message); } } fflush(logfile); pool_free(p); return; }
void con_room_send_invite(cnu sender, xmlnode node) { xmlnode result; xmlnode element; xmlnode invite; xmlnode pass; char *body, *user, *reason, *inviter; cnr room; pool p; if(sender == NULL || node == NULL) { log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE); return; } log_debug(NAME, "[%s] Sending room invite", FZONE); room = sender->room; invite = xmlnode_get_tag(node, "invite"); user = xmlnode_get_attrib(invite, "to"); reason = xmlnode_get_tag_data(invite, "reason"); p = xmlnode_pool(node); if(room->visible == 1) { inviter = jid_full(sender->realid); } else { inviter = jid_full(sender->localid); } xmlnode_put_attrib(invite, "from", inviter); xmlnode_hide_attrib(invite, "to"); if(reason == NULL) { reason = spools(p, "None given", p); } body = spools(p, "You have been invited to the ", jid_full(room->id), " room by ", inviter, "\nReason: ", reason, p); result = jutil_msgnew("normal", user , "Invitation", body); xmlnode_put_attrib(result, "from", jid_full(room->id)); xmlnode_insert_node(result, node); if(room->secret != NULL) { pass = xmlnode_get_tag(result, "x"); xmlnode_insert_cdata(xmlnode_insert_tag(pass, "password"), room->secret, -1); } element = xmlnode_insert_tag(result, "x"); xmlnode_put_attrib(element, "jid", jid_full(room->id)); xmlnode_put_attrib(element, "xmlns", NS_X_CONFERENCE); xmlnode_insert_cdata(element, reason, -1); log_debug(NAME, "[%s] >>>%s<<<", FZONE, xmlnode2str(result)); deliver(dpacket_new(result), NULL); return; }
void dnsrv(instance i, xmlnode x) { xdbcache xc = NULL; xmlnode config = NULL; xmlnode iternode = NULL; dns_resend_list tmplist = NULL; /* Setup a struct to hold dns_io handles */ dns_io di; di = pmalloco(i->p, sizeof(_dns_io)); di->mempool = i->p; /* Load config from xdb */ xc = xdb_cache(i); config = xdb_get(xc, jid_new(xmlnode_pool(x), "config@-internal"), "jabber:config:dnsrv"); /* Build a list of services/resend hosts */ iternode = xmlnode_get_lastchild(config); while (iternode != NULL) { if (j_strcmp("resend", xmlnode_get_name(iternode)) != 0) { iternode = xmlnode_get_prevsibling(iternode); continue; } /* Allocate a new list node */ tmplist = pmalloco(di->mempool, sizeof(_dns_resend_list)); tmplist->service = pstrdup(di->mempool, xmlnode_get_attrib(iternode, "service")); tmplist->host = pstrdup(di->mempool, xmlnode_get_data(iternode)); /* Insert this node into the list */ tmplist->next = di->svclist; di->svclist = tmplist; /* Move to next child */ iternode = xmlnode_get_prevsibling(iternode); } log_debug(ZONE, "dnsrv debug: %s\n", xmlnode2str(config)); /* Setup the hash of dns_packet_list */ di->packet_table = xhash_new(j_atoi(xmlnode_get_attrib(config,"queuemax"),101)); di->packet_timeout = j_atoi(xmlnode_get_attrib(config,"queuetimeout"),60); register_beat(di->packet_timeout, dnsrv_beat_packets, (void *)di); /* Setup the internal hostname cache */ di->cache_table = xhash_new(j_atoi(xmlnode_get_attrib(config,"cachemax"),1999)); di->cache_timeout = j_atoi(xmlnode_get_attrib(config,"cachetimeout"),3600); /* 1 hour dns cache? XXX would be nice to get the right value from dns! */ xmlnode_free(config); /* spawn a thread that get's forked, and wait for it since it sets up the fd's */ pth_join(pth_spawn(PTH_ATTR_DEFAULT,(void*)dnsrv_thread,(void*)di),NULL); if(di->pid < 0) { log_error(i->id,"dnsrv failed to start, unable to fork and/or create pipes"); return; } /* Start IO thread */ pth_spawn(PTH_ATTR_DEFAULT, dnsrv_process_io, di); /* Register an incoming packet handler */ register_phandler(i, o_DELIVER, dnsrv_deliver, (void*)di); /* register a cleanup function */ pool_cleanup(i->p, dnsrv_shutdown, (void*)di); }