Пример #1
0
xht xhash_new(int prime)
{
	xht xnew;
	pool p;

/*    log_debug(ZONE,"creating new hash table of size %d",prime); */

	p = pool_heap(sizeof(_xhn) * prime + sizeof(_xht));
	xnew = pmalloco(p, sizeof(_xht));
	xnew->prime = prime;
	xnew->p = p;
	xnew->zen = pmalloco(p, sizeof(_xhn) * prime);	/* array of xhn size of prime */
	return xnew;
}
Пример #2
0
xdbcache xdb_cache(instance id)
{
    xdbcache newx;

    if(id == NULL)
    {
        fprintf(stderr, "Programming Error: xdb_cache() called with NULL\n");
        return NULL;
    }

    newx = pmalloco(id->p, sizeof(_xdbcache));
    newx->i = id; /* flags it as the top of the ring too */
    newx->next = newx->prev = newx; /* init ring */
    pthread_mutex_init(&(newx->sem),NULL);

    /* register the handler in the instance to filter out xdb results */
    register_phandler(id, o_PRECOND, xdb_results, (void *)newx);

    /* heartbeat to keep a watchful eye on xdb_cache */
    register_beat(10,xdb_thump,(void *)newx);

    register_shutdown_first(xdb_shutdown, (void *)newx);

	pool_cleanup(id->p, xdb_shutdown, (void*)newx);
	
    return newx;
}
Пример #3
0
/* 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);
	}
}
Пример #4
0
/**
 * 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);
}
Пример #5
0
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);
}
Пример #6
0
/* handle a packet from jabberd */
result at_phandler(instance i,dpacket p,void *arg)
{
    int ret;
    ati ti;
    at_mtq_data amd;

    if(i == NULL || p == NULL) 
        return r_ERR;

    ti = (ati)arg;

    switch(p->type)
    {
    case p_NONE:
    case p_NORM:
        log_debug(ZONE, "[AT] we got a packet from jabberd: %s", xmlnode2str(p->x));
        amd = pmalloco(p->p, sizeof(_at_mtq_data));
        amd->jp = jpacket_new(p->x);
        amd->p = p->p;
        amd->ti = ti;

        mtq_send(NULL, p->p, at_parse_packet, (void *)amd);
        return r_DONE;
    default:
        log_debug(ZONE, "[AT] ignoring packet from jabberd: %s", xmlnode2str(p->x));
        return r_PASS;
    }
}
Пример #7
0
xmlnode xdb_file_parse(char *file,pool p)
{
    XML_Parser parser;
    xf_parse xfp;
    char buf[READ_BUF_SIZE];
    int done, fd, len;

    if(NULL == file)
        return NULL;

    fd = open(file,O_RDONLY);
    if(fd < 0)
	  return NULL;

	xfp = pmalloco(p,sizeof(_xf_parse));
	xfp->p = p;

    parser = XML_ParserCreate(NULL);
    XML_SetUserData(parser, xfp);
    XML_SetElementHandler(parser, xdb_file_startElement, xdb_file_endElement);
    XML_SetCharacterDataHandler(parser, xdb_file_charData);
    do{
	  len = read(fd, buf, READ_BUF_SIZE);
	  done = len < READ_BUF_SIZE;
	  if(!XML_Parse(parser, buf, len, done)) done = 1;
    }while(!done);
	
    XML_ParserFree(parser);
    close(fd);
    return xfp->current;
}
Пример #8
0
void mtq_init() {
    mtq mtq = NULL; /* queue */
    mth t = NULL;
    int n,k; 
    pool newp;


	mtq__master = malloc(sizeof(_mtqmaster)); /* happens once, global */
	mtq__master->random = 0;

	/* start MTQ threads */
	for(n=0;n<MTQ_THREADS;n++)  {
	  newp = pool_new();
	  t = pmalloco(newp, sizeof(_mth));
	  t->p = newp;
	  t->mtq = pmalloco(newp,sizeof(_mtq));
	  t->mtq->first = t->mtq->last = NULL;
	  t->mtq->free_first = t->mtq->free_last = NULL;	    
	  t->mtq->users_count = 0;
	  t->mtq->dl = 0;	    
	  t->mtq->length = 0;

	  mtq = t->mtq;
	
	  /* build queue cache */
	  for (k=0;k<MTQ_QUEUE_LONG;k++)  {
		/* mtq->free_last if the first to take from queue*/	
		mtq->queue[k].memory = 0;
		mtq->queue[k].prev   = NULL;
		
		/* if queue is empty */
		if (mtq->free_last == NULL)
		  mtq->free_last = &(mtq->queue[k]);
		else
		  mtq->free_first->prev = &(mtq->queue[k]);
		
		mtq->free_first = &(mtq->queue[k]);
		mtq->length++;
	  }
	  
	  SEM_INIT(t->mtq->sem);
	  COND_INIT(t->mtq->cond);
		
	  pthread_create(&(t->thread), NULL, mtq_main, (void *)t);
	  mtq__master->all[n] = t; /* assign it as available */
	}
}
Пример #9
0
static void _s2s_hosts_expand(s2s_t s2s)
{
    char *realm;
    config_elem_t elem;
    char id[1024];
    int i;

    elem = config_get(s2s->config, "local.id");

    if (elem) for(i = 0; i < elem->nvalues; i++) {
        host_t host = (host_t) pmalloco(xhash_pool(s2s->hosts), sizeof(struct host_st));
        if(!host) {
            log_write(s2s->log, LOG_ERR, "cannot allocate memory for new host, aborting");
            exit(1);
        }

        realm = j_attr((const char **) elem->attrs[i], "realm");

        /* stringprep ids (domain names) so that they are in canonical form */
        strncpy(id, elem->values[i], 1024);
        id[1023] = '\0';
        if (stringprep_nameprep(id, 1024) != 0) {
            log_write(s2s->log, LOG_ERR, "cannot stringprep id %s, aborting", id);
            exit(1);
        }

        host->realm = (realm != NULL) ? realm : pstrdup(xhash_pool(s2s->hosts), id);

        host->host_pemfile = j_attr((const char **) elem->attrs[i], "pemfile");

        host->host_cachain = j_attr((const char **) elem->attrs[i], "cachain");

        host->host_verify_mode = j_atoi(j_attr((const char **) elem->attrs[i], "verify-mode"), 0);

#ifdef HAVE_SSL
        if(host->host_pemfile != NULL) {
            if(s2s->sx_ssl == NULL) {
                s2s->sx_ssl = sx_env_plugin(s2s->sx_env, sx_ssl_init, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode);
                if(s2s->sx_ssl == NULL) {
                    log_write(s2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm);
                    host->host_pemfile = NULL;
                }
            } else {
                if(sx_ssl_server_addcert(s2s->sx_ssl, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode) != 0) {
                    log_write(s2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm);
                    host->host_pemfile = NULL;
                }
            }
        }
#endif

        /* insert into vHosts xhash */
        xhash_put(s2s->hosts, pstrdup(xhash_pool(s2s->hosts), id), host);

        log_write(s2s->log, LOG_NOTICE, "[%s] configured; realm=%s", id, host->realm);
    }
}
Пример #10
0
/** make a new one */
static user_t _user_alloc(sm_t sm, jid_t jid) {
    pool_t p;
    user_t user;

    p = pool_new();

    user = (user_t) pmalloco(p, sizeof(struct user_st));

    user->p = p;
    user->sm = sm;

    user->jid = jid_dup(jid);
    pool_cleanup(p, (void (*)(void *)) jid_free, user->jid);

    /* a place for modules to store stuff */
    user->module_data = (void **) pmalloco(p, sizeof(void *) * sm->mm->nindex);

    return user;
}
Пример #11
0
/* Hostname lookup requested */
void dnsrv_lookup(dns_io d, dpacket p)
{
    dns_packet_list l, lnew;
    xmlnode req;
    char *reqs;

    /* make sure we have a child! */
    if(d->out <= 0)
    {
        deliver_fail(p, "DNS Resolver Error");
        return;
    }

    /* Attempt to lookup this hostname in the packet table */
    l = (dns_packet_list)xhash_get(d->packet_table, p->host);

    /* IF: hashtable has the hostname, a lookup is already pending,
       so push the packet on the top of the list (most recent at the top) */
    if (l != NULL)
    {
         log_debug(ZONE, "dnsrv: Adding lookup request for %s to pending queue.", p->host);
         lnew = pmalloco(p->p, sizeof(_dns_packet_list));
         lnew->packet = p;
         lnew->stamp = time(NULL);
         lnew->next = l;
         xhash_put(d->packet_table, p->host, lnew);
         return;
    }

    /* insert the packet into the packet_table using the hostname
       as the key and send a request to the coprocess */
    log_debug(ZONE, "dnsrv: Creating lookup request queue for %s", p->host);
    l = pmalloco(p->p, sizeof(_dns_packet_list));
    l->packet = p;
    l->stamp  = time(NULL);
    xhash_put(d->packet_table, p->host, l);
    req = xmlnode_new_tag_pool(p->p,"host");
    xmlnode_insert_cdata(req,p->host,-1);

    reqs = xmlnode2str(req);
    log_debug(ZONE, "dnsrv: Transmitting lookup request: %s", reqs);
    pth_write(d->out, reqs, strlen(reqs));
}
Пример #12
0
/* match will find a child in the parent, and either replace (if it's an insert) or remove (if data is NULL) */
int xdb_act(xdbcache xc, jid owner, char *ns, char *act, char *match, xmlnode data)
{
    xdbcache newx;
	pool p;

    if(xc == NULL || owner == NULL || ns == NULL)
    {
        fprintf(stderr,"Programming Error: xdb_set() called with NULL\n");
        return 1;
    }

    
    log_debug(ZONE,"XDB SET");

    /* init this newx */
	p = pool_new();
	newx = pmalloco(p, sizeof(_xdbcache));
    newx->i = xc->i;
    newx->set = 1;
    newx->data = data;
    newx->ns = ns;
    newx->act = act;
    newx->match = match;
    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);


    /* if it didn't actually get set, flag that */
    if(newx->data == NULL) {
	  pool_free(p);
	  return 1;
	}

    xmlnode_free(newx->data);

	pool_free(p);

    return 0;
}
Пример #13
0
os_t os_new(void) {
    pool_t p;
    os_t os;

    p = pool_new();
    os = (os_t) pmalloco(p, sizeof(struct os_st));

    os->p = p;

    return os;
}
Пример #14
0
void js_session_from(session s, jpacket jp)
{
	packet_thread_p pt;
	/* queue the call to child, hide session in packet */
	jp->aux1 = (void *) s;

	pt = pmalloco(jp->p, sizeof(packet_thread_t));
	pt->jp = jp;
	pt->type = 2;
	fast_mtq_send(s->q->mtq, pt);
}
Пример #15
0
/*
 *  js_session_end -- shut down the session
 *
 *  This function gets called when the user disconnects or when the server shuts
 *  down. It changes the user's presence to offline, cleans up the session data
 *  and sends an end spacket
 *
 *  parameters
 *	s -- the session to end
 *	reason -- the reason the session is shutting down (for logging)
 *
 */
void js_session_end(session s, char *reason)
{
	session cur;		/* used to iterate over the user's session list
				   when removing the session from the list */

	/* ignore illegal calls */
	if (s == NULL || s->exit_flag == 1 || reason == NULL)
		return;

	/* so it doesn't get freed */
	THREAD_INC(s->u->ref);

	/* log the reason the session ended */
	log_debug("end %d '%s'", s, reason);

	/* flag the session to exit ASAP */
	s->exit_flag = 1;

	/* make sure we're not the primary session */
	s->priority = -129;

	/* presence will be updated in _js_session_end to be shore that
	   only session thread is changing this value  */

	/*
	 * remove this session from the user's session list --
	 * first check if this session is at the head of the list
	 */
	SEM_LOCK(s->u->sem);
	if (s == s->u->sessions) {
		/* yup, just bump up the next session */
		s->u->sessions = s->next;

	} else {

		/* no, we have to traverse the list to find it */
		for (cur = s->u->sessions; cur->next != s;
		     cur = cur->next);
		cur->next = s->next;

	}

	s->u->scount--;
	SEM_UNLOCK(s->u->sem);

	/* end */
	{
		packet_thread_p pt;
		pt = pmalloco(s->p, sizeof(packet_thread_t));
		pt->s = s;
		pt->type = 1;
		fast_mtq_send(s->q->mtq, pt);
	}
}
Пример #16
0
jqueue_t jqueue_new(void) {
	pool_t p;
	jqueue_t q;

	p = pool_new();
	q = (jqueue_t)pmalloco(p, sizeof(struct _jqueue_st));

	q->p = p;
	q->init_time = time(NULL);

	return q;
}
Пример #17
0
/* 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;
}
Пример #18
0
jid jid_user(jid a)
{
    jid ret;

    if(a == NULL || a->resource == NULL) return a;

    ret = pmalloco(a->p,sizeof(struct jid_struct));
    ret->p = a->p;
    ret->user = a->user;
    ret->server = a->server;

    return ret;
}
Пример #19
0
jid jid_new(pool p, const char *idstr)
{
    char *server, *resource, *type, *str;
    jid id;

    if(p == NULL || idstr == NULL || *idstr == '\0')
        return NULL;

    /* user@server/resource */

    str = pstrdup(p, idstr);

    id = pmalloco(p,sizeof(struct jid_struct));
    id->p = p;

    resource = strstr(str,"/");
    if(resource != NULL)
    {
        *resource = '\0';
        ++resource;
        if(*resource != '\0')
            id->resource = resource;
    }else{
        resource = str + strlen(str); /* point to end */
    }

    type = strstr(str,":");
    if(type != NULL && type < resource)
    {
        *type = '\0';
        ++type;
        str = type; /* ignore the type: prefix */
    }

    server = strstr(str,"@");
    if(server == NULL || server > resource)
    { /* if there's no @, it's just the server address */
        id->server = str;
    }else{
        *server = '\0';
        ++server;
        id->server = server;
        if(*str != '\0')
            id->user = str;
    }

    return jid_safe(id);
}
Пример #20
0
xhn _xhash_node_new(xht h, int index)
{
	xhn n;
	int i = index % h->prime;

	/* get existing empty one */
	for (n = &h->zen[i]; n != NULL; n = n->next)
		if (n->key == NULL)
			return n;

	/* overflowing, new one! */
	n = pmalloco(h->p, sizeof(_xhn));
	n->next = h->zen[i].next;
	h->zen[i].next = n;
	return n;
}
Пример #21
0
/**
 * callback, that gets called if a new session is establisched, registers all session oriented callbacks
 *
 * This callback is responsible for initializing a new instance of the _modpres structure, that holds
 * the list of entites that know that a user is available.
 *
 * @param m the mapi structure
 * @param arg the list of JabberIDs that get a bcc of all presences
 * @return always M_PASS
 */
mreturn mod_presence_session(mapi m, void *arg)
{
	modpres_conf conf = (modpres_conf) arg;
	modpres mp;

	/* track our session stuff */
	mp = pmalloco(m->s->p, sizeof(_modpres));
	//    mp->A = jid_user(m->s->id);
	mp->A = m->s->uid;
	mp->conf = conf;	/* no no, it's ok, these live longer than us */

	js_mapi_session(es_IN, m->s, mod_presence_in, mp);
	js_mapi_session(es_OUT, m->s, mod_presence_avails, mp);	/* must come first, it passes, _out handles */
	js_mapi_session(es_OUT, m->s, mod_presence_out, mp);
	js_mapi_session(es_END, m->s, mod_presence_avails_end, mp);

	return M_PASS;
}
Пример #22
0
result base_file_config(instance id, xmlnode x, void *arg)
{
    basefile bf;
        
    if(id == NULL)
    {
        log_debug(ZONE,"base_file_config validating configuration");

        if (xmlnode_get_data(x) == NULL)
        {
            log_debug(ZONE,"base_file_config error: no filename provided.");
            xmlnode_put_attrib(x,"error","'file' tag must contain a filename to write to");
            return r_ERR;
        }
        return r_PASS;
    }

    log_debug(ZONE,"base_file configuring instance %s",id->id);

    if(id->type != p_LOG)
    {
        log_alert(NULL,"ERROR in instance %s: <file>..</file> element only allowed in log sections", id->id);
        return r_ERR;
    }

    bf = pmalloco(id->p,sizeof(_basefile));
    bf->filename = pstrdup(id->p,xmlnode_get_data(x));
    bf->yesterday.tm_mday = -1;
    bf->last_time = 0;
    bf->f = NULL;
    pthread_mutex_init(&(bf->sem),NULL);

    /* Register a handler for this instance... */
    register_phandler(id, o_DELIVER, base_file_deliver, (void*)bf);

    pool_cleanup(id->p, _base_file_shutdown, (void*)bf);
    
    return r_DONE;
}
Пример #23
0
/* returns a valid nick from the list, x is the first <nick>foo</nick> xmlnode, checks siblings */
char *con_room_nick(cnr room, cnu user, xmlnode x)
{
  char *nick = NULL;
  xmlnode cur;
  int count = 1;

  if(room == NULL || user == NULL) 
  {
    log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE);
    return NULL;
  }

  log_debug(NAME, "[%s] looking for valid nick in room %s from starter %s", FZONE, jid_full(room->id), xmlnode2str(x));

  /* make-up-a-nick phase */
  if(x == NULL)
  {
    nick = pmalloco(user->p, j_strlen(user->realid->user) + 10);
    log_debug(NAME, "[%s] Malloc: Nick = %d", FZONE, j_strlen(user->realid->user) + 10);

    sprintf(nick, "%s", user->realid->user);
    while(g_hash_table_lookup(room->local, nick) != NULL)
      sprintf(nick, "%s%d", user->realid->user,count++);
    return nick;
  }

  /* scan the list */
  for(cur = x; cur != NULL; cur = xmlnode_get_nextsibling(cur))
  {
    if(j_strcmp(xmlnode_get_name(cur),"nick") == 0 && (nick = xmlnode_get_data(cur)) != NULL)
      if(g_hash_table_lookup(room->local, nick) == NULL)
        break;
  }

  if(is_registered(room->master, jid_full(jid_user(user->realid)), nick) == -1)
    nick = NULL;

  return nick;
}
Пример #24
0
os_object_t os_object_new(os_t os) {
    os_object_t o;

    log_debug(ZONE, "creating new object");

    o = (os_object_t) pmalloco(os->p, sizeof(struct os_object_st));
    o->os = os;

    o->hash = xhash_new(51);

    /* make sure that the hash gets freed when the os pool gets freed */
    pool_cleanup(os->p, (pool_cleanup_t) xhash_free, (void *)(o->hash) );

    /* insert at the end, we have to preserve order */
    o->prev = os->tail;
    if(os->tail != NULL) os->tail->next = o;
    os->tail = o;
    if(os->head == NULL) os->head = o;
    
    os->count++;

    return o;
}
Пример #25
0
void os_object_put(os_object_t o, const char *key, const void *val, os_type_t type) {
    os_field_t osf;
    nad_t nad;

    log_debug(ZONE, "adding field %s (val %x type %d) to object", key, val, type);

    osf = pmalloco(o->os->p, sizeof(struct os_field_st));
    osf->key = pstrdup(o->os->p, key);

    switch(type) {
        case os_type_BOOLEAN:
        case os_type_INTEGER:
            osf->val = (void *) (intptr_t) (* (int *) val);
            break;

        case os_type_STRING:
            osf->val = (void *) pstrdup(o->os->p, (char *) val);
            break;

        case os_type_NAD:
            nad = nad_copy((nad_t) val);

            /* make sure that the nad gets freed when the os pool gets freed */
            pool_cleanup(o->os->p, (pool_cleanup_t) nad_free, (void *) nad);

            osf->val = (void *) nad;
            break;

        case os_type_UNKNOWN:
            break;
    }

    osf->type = type;

    xhash_put(o->hash, osf->key, (void *) osf);
}
Пример #26
0
Файл: xmlnode.c Проект: bcy/muc
/* Internal routines */
static xmlnode _xmlnode_new(pool p, const char* name, unsigned int type)
{
    xmlnode result = NULL;
    if (type > NTYPE_LAST)
        return NULL;

    if (type != NTYPE_CDATA && name == NULL)
        return NULL;

    if (p == NULL)
    {
        p = pool_heap(1*1024);
    }

    /* Allocate & zero memory */
    result = (xmlnode)pmalloco(p, sizeof(_xmlnode));

    /* Initialize fields */
    if (type != NTYPE_CDATA)
        result->name = pstrdup(p,name);
    result->type = type;
    result->p = p;
    return result;
}
Пример #27
0
xdbcache xdb_cache(instance id)
{
	xdbcache xc;

	if (id == NULL) {
		log_alert("xdb",
			  "Programming Error: xdb_cache() called with NULL\n");
		return NULL;
	}

	xc = pmalloco(id->p, sizeof(_xdbcache));
	xc->i = id;		/* flags it as the top of the ring too */
	xc->first = NULL;	/* init ring */
	SEM_INIT(xc->sem);

	/* register the handler in the instance to filter out xdb results */
	register_phandler(id, o_PRECOND, xdb_results, (void *) xc);

	/* heartbeat to keep a watchful eye on xdb_cache */
	register_beat(10, xdb_thump, (void *) xc);

	register_shutdown_first(xdb_shutdown, (void *) xc);
	return xc;
}
Пример #28
0
/*
 *  js_session_new -- creates a new session, registers the resource for it
 *
 *  Sets up all the data associated with the new session, then send it a
 *  start spacket, which basically notifies all modules about the new session
 *
 *  returns
 *	a pointer to the new session
 */
session js_session_new(jsmi si, dpacket dp)
{
	pool p;
	session s, cur;
	udata u;
	int i;
	char routeres[10];

	/* screen out illegal calls */
	if (dp == NULL || dp->id->user == NULL || dp->id->resource == NULL
	    || xmlnode_get_attrib(dp->x, "from") == NULL)
		return NULL;

	if ((u = js_user(si, dp->id, 0)) == NULL)
		return NULL;

	if (u->scount >= MAX_USER_SESSIONS) {
		THREAD_DEC(u->ref);
		return NULL;
	}


	log_debug("session_create %s", jid_full(dp->id));

	/* create session */
	p = pool_heap(1024);
	s = pmalloco(p, sizeof(struct session_struct));
	s->p = p;
	s->si = si;

	/* save authorative remote session id */
	s->sid = jid_new(p, xmlnode_get_attrib(dp->x, "from"));

	/* session identity */
	s->id = jid_new(p, jid_full(dp->id));
	/* id bez resource */
	s->uid = jid_user(s->id);
	s->route = jid_new(p, jid_full(dp->id));
	snprintf(routeres, 9, "%X", s);
	jid_set(s->route, routeres, JID_RESOURCE);
	s->res = pstrdup(p, dp->id->resource);
	s->u = u;

	jid_full(s->sid);
	jid_full(s->uid);
	jid_full(s->id);
	jid_full(s->route);

	{
		register char *text;
		text = xmlnode_get_attrib(dp->x, "ip");
		if (text) {
			s->ip =
			    pstrdup(s->p, xmlnode_get_attrib(dp->x, "ip"));
			xmlnode_hide_attrib(dp->x, "ip");
		} else
			s->ip = "none";
	}

	/* default settings */
	s->exit_flag = 0;
	s->roster = 0;
	s->priority = -129;
	s->presence = jutil_presnew(JPACKET__UNAVAILABLE, NULL, NULL);
	xmlnode_put_attrib(s->presence, "from", jid_full(s->id));
	s->c_in = s->c_out = 0;

	for (i = 0; i < es_LAST; i++)
		s->events[i] = NULL;

	SEM_LOCK(u->sem);

	if (u->sessions != NULL) {
		s->q = get_mtq_queue(si, u->sessions->q);

		for (cur = u->sessions; cur != NULL; cur = cur->next)
			if (j_strcmp(dp->id->resource, cur->res) == 0)
				js_session_end_nosem(cur,
						     "Replaced by new connection");
	} else {
		s->q = get_mtq_queue(si, NULL);
	}

	/* make sure we're linked with the user */
	s->next = s->u->sessions;
	s->u->sessions = s;
	s->u->scount++;

	SEM_UNLOCK(u->sem);

	/* session start */
	{
		packet_thread_p pt;
		pt = malloc(sizeof(packet_thread_t));
		pt->s = s;
		pt->type = 0;
		fast_mtq_send(s->q->mtq, pt);
	}

	THREAD_DEC(u->ref);
	return s;
}
Пример #29
0
/* simple utility for concat strings */
char *xdb_file_full(int create, pool p, char *spl, char *host, char *file, char *ext)
{
    struct stat s;
    int lenf = strlen(file);
    int lenh = strlen(host);
    int lens = strlen(spl);
    int lene = strlen(ext);
    int index;
    char xdb_file[lenf+10];
    char xdb_path[20];
    char *full = pmalloco(p,lens+lenh+lenf+lene+15);

    memcpy(full,spl,lens);
    index = lens;
    full[index] = '/';
    index++;

    memcpy(full+index,host,lenh);
    index += lenh;
    full[index] = '/';
    index++;

    memcpy(xdb_file,file,lenf);
    xdb_file[lenf]='.';
    memcpy(xdb_file+lenf+1,ext,lene);
    xdb_file[lenf+lene+1] = 0;

    generate_dir(xdb_file,xdb_path,20);

    memcpy(full+index,xdb_path+1,5);
    index+=5;

    /* check dir */
    if (stat(full,&s) == 0) {
      full[index] = '/';
      index++;
      memcpy(full+index,xdb_file,lenf+lene+2);
      return full;
    }

	/* if GET why create */
    if (!create) {
	  return NULL;
	}

    /* try to create directory */
    index = lens+lenh+1;
    full[index] = 0;
    
	/* create host */
    if (stat(full,&s) < 0) {
      mkdir(full, S_IRWXU);
    }
    
    full[index] = '/';
    index+=3;
    full[index] = 0;


	/* create 1 dir */
    if (stat(full,&s) < 0) {
      mkdir(full, S_IRWXU);
    }

    full[index] = '/';
    index+=3;
    full[index] = 0;

	/* create 2 dir */
    if (stat(full,&s) < 0) {
      mkdir(full, S_IRWXU);
    }

    full[index] = '/';
    index++;
    memcpy(full+index,xdb_file,lenf+lene+2);

    return full;
}
Пример #30
0
static st_filter_t _storage_filter(pool_t p, const char *f, int len) {
    char *c, *key, *val, *sub;
    int vallen;
    st_filter_t res, sf;
    
    if(f[0] != '(' && f[len] != ')')
        return NULL;

    /* key/value pair */

    /* if value is numeric, then represented as is.                                      */
    /* if value is string, it is preceded by length: e.g. "key=5:abcde"                  */
    /* (needed to pass values which include a closing bracket ')', e.g. in resourcenames */

    if(isalpha(f[1])) {
        key = strdup(f+1);

        c = strchr(key, '=');
        if(c == NULL) {
		free(key);
		return NULL;
	}
        *c = '\0'; c++;

        val = c;

	/* decide whether number or string by checking for ':' before ')' */

        while (*c != ':' && *c != ')' && *c)
           c++;

        if (!*c) {
		free(key);
		return NULL;
	}

        if (*c == ':') {
                /* string */
                *c = '\0';
                vallen = atoi(val);
                c++;
                val = c;
                c += vallen;
        }

        *c = '\0';
        log_debug(ZONE, "extracted key %s val %s", key, val);

        res = pmalloco(p, sizeof(struct st_filter_st));
        res->p = p;

        res->type = st_filter_type_PAIR;
        res->key = pstrdup(p, key);
        res->val = pstrdup(p, val);

	free(key);
        return res;
    }

    /* operator */
    if(f[1] != '&' && f[1] != '|' && f[1] != '!')
        return NULL;

    res = pmalloco(p, sizeof(struct st_filter_st));
    res->p = p;

    switch(f[1]) {
        case '&': res->type = st_filter_type_AND; break;
        case '|': res->type = st_filter_type_OR; break;
        case '!': res->type = st_filter_type_NOT; break;
    }

    /* remove const for now, we will not change the string */
    c = (char *) &f[2];
    while(*c == '(') {
        sub = c;
        c = strchr(sub, ')');
        c++;

        sf = _storage_filter(p, (const char *) sub, c - sub);

        sf->next = res->sub;
        res->sub = sf;
    }

    return res;
}