/*
This may be too slow because the tree could end up very unbalanced if presented in alphabetical order.
Probably better to switch to C++ and use STL.
Or could hash the strings first.
Or use a balancing data structure.
*/
TREE_T *tree_get(TREE_T *t,char *name)
{
	int x=strcmp(name,t->s);
	if (x==0) return t;
	if (x<0)
	{
		if (!t->lt) t->lt=tree_new(name);
		return tree_get(t->lt,name);
	}
	if (!t->gt) t->gt=tree_new(name);
	return tree_get(t->gt,name);
}
Пример #2
0
static int
queue_ram_envelope_update(uint64_t evpid, const char *buf, size_t len)
{
	struct qr_envelope	*evp;
	struct qr_message	*msg;
	void			*tmp;

	if ((msg = get_message(evpid_to_msgid(evpid))) == NULL)
		return (0);

	if ((evp = tree_get(&msg->envelopes, evpid)) == NULL) {
		log_warn("warn: queue-ram: not found");
		return (0);
	}
	tmp = malloc(len);
	if (tmp == NULL) {
		log_warn("warn: queue-ram: malloc");
		return (0);
	}
	memmove(tmp, buf, len);
	free(evp->buf);
	evp->len = len;
	evp->buf = tmp;
	stat_decrement("queue.ram.envelope.size", evp->len);
	stat_increment("queue.ram.envelope.size", len);
	return (1);
}
Пример #3
0
int ydb_get(YDB ydb, char *key, unsigned short key_sz,
	    char *buf, int buf_sz) {
	struct db *db = (struct db *) ydb;
	assert(db->magic == YDB_STRUCT_MAGIC);
	
	DB_LOCK(db);
	struct item *item = tree_get(db->tree, key, key_sz);
	if(item == NULL)
		goto error;
		
	int needed = item->value_sz + MAX_PADDING + sizeof(struct ydb_value_record);
	if(buf_sz < needed) {
		log_error("ydb_get:buffer too small. is %i, should be at least %i", buf_sz, needed);
		goto error;
	}
	
	int r = loglist_get(db->loglist, item->logno, item->value_offset, item->value_sz, buf, buf_sz);
	if(r < 0)
		goto error;
	
	DB_UNLOCK(db);
	return(r);

error:
	DB_UNLOCK(db);
	return(-1);
}
/* Write all entries in t into the backup tree and free storage*/
void tree_commit(TREE_T *backup,TREE_T *t)
{
	if (t==NULL) return;
	TREE_T *b=tree_get(backup,t->s);
	b->value=t->value;
	tree_commit(backup,t->lt);
	tree_commit(backup,t->gt);
	free(t);
}
Пример #5
0
void ydb_prefetch(YDB ydb, char **keys, unsigned short *key_szs, int items_counter) {
	struct db *db = (struct db *) ydb;
	assert(db->magic == YDB_STRUCT_MAGIC);

	struct item **items_start = (struct item **)malloc(sizeof(struct item_index *) * items_counter);
	struct item **items = items_start;
	DB_LOCK(db);
	int i;
	for(i=0; i < items_counter; i++, keys++, key_szs++) {
		char *key = *keys;
		int key_sz = *key_szs;
		struct item *item = tree_get(db->tree, key, key_sz);
		if(item) {
			*items = item;
			items++;
		}
		
	}
	DB_UNLOCK(db);
	
	int items_sz = items - items_start;
	qsort(items_start, items_sz, sizeof(struct item *), item_cmp);
	
	items = items_start;
	int fd = -1;
	int count = 0;
	int offset = 0;
	for(i=0; i < items_sz; i++, items++) {
		struct item *item = *items;
		
		struct log *log = slot_get(db->loglist, item->logno);
		
		size_t read_size = ROUND_UP(item->value_sz, PADDING) + sizeof(struct ydb_value_record);
		
		/* merge? */
		if(fd == log->fd  &&  (offset + count + 4096) >= item->value_offset) {
			count = (item->value_offset+read_size) - offset;
		}else{
			if(fd != log->fd) {
				/* clear previous fadvices */
				posix_fadvise(log->fd, 0, 0, POSIX_FADV_RANDOM);
			}
			if(fd != -1) {
				posix_fadvise(fd, offset, count, POSIX_FADV_WILLNEED);
			}
			fd = log->fd;
			count = read_size;
			offset = item->value_offset;
		}
	}
	if(fd != -1) {
		posix_fadvise(fd, offset, count, POSIX_FADV_WILLNEED);
	}
	
	free(items_start);
}
Пример #6
0
int tree_add(tree t, void * e)
{
    int boolean = 0;
    boolean = tree_get(t,e) != NULL;
    if (!boolean) {
        t->header = Binary_Tree(t, e, t->header, t->H, &boolean);
        t->size++;
    }
    return !boolean;
}
Пример #7
0
void tree_close(void)
{
	if (shared_tree)
		tree_flush(tree_get());
	shared_tree = NULL;
	if (shared_tree_lock) {
		lock_destroy(shared_tree_lock);
		lock_dealloc(shared_tree_lock);
		shared_tree_lock=0;
	}
}
Пример #8
0
static struct qr_message *
get_message(uint32_t msgid)
{
	struct qr_message	*msg;

        msg = tree_get(&messages, msgid);
        if (msg == NULL)
                log_warn("warn: queue-ram: message not found");

	return (msg);
}
Пример #9
0
char *
build_realname(struct fuse *f, ino_t ino)
{
    struct fuse_vnode *vn;
    char *name = strdup("/");
    char *tmp = NULL;
    int firstshot = 0;

    vn = tree_get(&f->vnode_tree, ino);
    if (!vn || !name) {
        free(name);
        return (NULL);
    }

    while (vn->parent != 0) {
        if (firstshot++)
            asprintf(&tmp, "/%s%s", vn->path, name);
        else
            asprintf(&tmp, "/%s", vn->path);

        if (tmp == NULL) {
            free(name);
            return (NULL);
        }

        free(name);
        name = tmp;
        tmp = NULL;
        vn = tree_get(&f->vnode_tree, vn->parent);

        if (!vn)
            return (NULL);
    }

    if (ino == (ino_t)0)
        DPRINTF("%s: NULL ino\n", __func__);

    DPRINTF("realname %s\n", name);
    return (name);
}
Пример #10
0
/*
 * Linux specific routines
 */
void plinnames_collect(TABLE tab) {
     char *basename;

     plinnames_sysfiles = tree_create();
     plinnames_readalldir("/proc/sys", plinnames_sysfiles);
     tree_traverse(plinnames_sysfiles) {
	  table_addemptyrow(tab);
	  table_replacecurrentcell(tab, "value", 
				   tree_get(plinnames_sysfiles));
	  table_replacecurrentcell(tab, "name", 
				   tree_getkey(plinnames_sysfiles));
	  basename = strrchr(tree_getkey(plinnames_sysfiles), '/');
	  if (basename)
	       basename++;
	  else
	       basename = tree_getkey(plinnames_sysfiles);
	  table_replacecurrentcell(tab, "vname", basename);
	  table_freeondestroy(tab, tree_getkey(plinnames_sysfiles));
	  table_freeondestroy(tab, tree_get(plinnames_sysfiles));
     }
     tree_destroy(plinnames_sysfiles);
}
 void keyValue(char a[][30] ,int n) {
	int i;
	TREE_T *root=tree_new("m for root");
	TREE_T *backup=tree_load();
	for(i=0;i<n;i++)
	{
		char *p=a[i];
		int value;
		char name[MAXN+1];
		TREE_T *t;
		switch(p[0])
		{
		case 'S':
			sscanf(p,"SET %s %d",&name,&value);
			t=tree_get(root,name);
			t->value=value;
			break;
		case 'G':
			sscanf(p,"GET %s",&name);
			t=tree_has(root,name);
			if (!t)
				t=tree_get(backup,name);
			printf("%d\n",t->value);
			break;
		case 'R':
			tree_free(root);
			root=tree_new("m for root");
			break;
		case 'C':
			tree_commit(backup,root);
			root=tree_new("m for root");
			break;
		default:
			assert(0);
		}
	}
	tree_free(root);
	tree_save(backup);
}
Пример #12
0
static void
queue_envelope_cache_update(struct envelope *e)
{
	struct envelope *cached;

	if ((cached = tree_get(&evpcache_tree, e->id)) == NULL) {
		queue_envelope_cache_add(e);
		stat_increment("queue.evpcache.update.missed", 1);
	} else {
		TAILQ_REMOVE(&evpcache_list, cached, entry);
		*cached = *e;
		TAILQ_INSERT_HEAD(&evpcache_list, cached, entry);
		stat_increment("queue.evpcache.update.hit", 1);
	}
}
Пример #13
0
node_t *find_empty_key(tree_t *tree, int *hand, node_t *node)
{
	int key;
/*
	int max = (tree == &(queue_tree))? 49156:MAX_AUTO_ID;

	for (key = *hand + 1; key <= max; key++) {
*/
	for (key = *hand + 1; key <= MAX_AUTO_ID; key++) {
		if (!tree_get(tree, key)) {
			*hand = key;
			return tree_put(tree, key, node);
		}
	}
/* TODO test */
	for (key = MIN_AUTO_ID; key < *hand; key++) {
		if (!tree_get(tree, key)) {
			*hand = key;
			return tree_put(tree, key, node);
		}
	}

	return NULL;
}
Пример #14
0
static int
queue_ram_message_commit(uint32_t msgid, const char *path)
{
	struct qr_message	*msg;
	struct stat		 sb;
	size_t			 n;
	FILE			*f;
	int			 ret;

	if ((msg = tree_get(&messages, msgid)) == NULL) {
		log_warnx("warn: queue-ram: msgid not found");
		return (0);
	}

	f = fopen(path, "rb");
	if (f == NULL) {
		log_warn("warn: queue-ram: fopen: %s", path);
		return (0);
	}
	if (fstat(fileno(f), &sb) == -1) {
		log_warn("warn: queue-ram: fstat");
		fclose(f);
		return (0);
	}

	msg->len = sb.st_size;
	msg->buf = malloc(msg->len);
	if (msg->buf == NULL) {
		log_warn("warn: queue-ram: malloc");
		fclose(f);
		return (0);
	}

	ret = 0;
	n = fread(msg->buf, 1, msg->len, f);
	if (ferror(f))
		log_warn("warn: queue-ram: fread");
	else if ((off_t)n != sb.st_size)
		log_warnx("warn: queue-ram: bad read");
	else {
		ret = 1;
		stat_increment("queue.ram.message.size", msg->len);
	}
	fclose(f);

	return (ret);
}
Пример #15
0
// This method should be locked
void_p map_get(map m, void_p key) {
	pthread_mutex_lock(m->mutex);
	data * finder = (data*) malloc(sizeof(struct data));
	finder->key = key;
	c_index = m->comparer_index;
	data * d = (data *)tree_get(m->t, finder);
	free(finder);
	if (d != NULL) {
		pthread_mutex_unlock(m->mutex);
		return d->value;
	}
	else {
		pthread_mutex_unlock(m->mutex);
		return NULL;
	}

}
Пример #16
0
int
queue_envelope_load(uint64_t evpid, struct envelope *ep)
{
	const char	*e;
	char		 evpbuf[sizeof(struct envelope)];
	size_t		 evplen;
	struct envelope	*cached;

	if ((env->sc_queue_flags & QUEUE_EVPCACHE) &&
	    (cached = tree_get(&evpcache_tree, evpid))) {
		*ep = *cached;
		stat_increment("queue.evpcache.load.hit", 1);
		return (1);
	}

	ep->id = evpid;
	profile_enter("queue_envelope_load");
	evplen = handler_envelope_load(ep->id, evpbuf, sizeof evpbuf);
	profile_leave();

	log_trace(TRACE_QUEUE,
	    "queue-backend: queue_envelope_load(%016"PRIx64") -> %zu",
	    evpid, evplen);

	if (evplen == 0)
		return (0);

	if (queue_envelope_load_buffer(ep, evpbuf, evplen)) {
		if ((e = envelope_validate(ep)) == NULL) {
			ep->id = evpid;
			if (env->sc_queue_flags & QUEUE_EVPCACHE) {
				queue_envelope_cache_add(ep);
				stat_increment("queue.evpcache.load.missed", 1);
			}
			return (1);
		}
		log_debug("debug: invalid envelope %016" PRIx64 ": %s",
		    ep->id, e);
	}

	(void)queue_message_corrupt(evpid_to_msgid(evpid));
	return (0);
}
Пример #17
0
static int
queue_ram_message_fd_r(uint32_t msgid)
{
	struct qr_message	*msg;
	size_t			 n;
	FILE			*f;
	int			 fd, fd2;

	if ((msg = tree_get(&messages, msgid)) == NULL) {
		log_warnx("warn: queue-ram: not found");
		return (-1);
	}

	fd = mktmpfile();
	if (fd == -1) {
		log_warn("warn: queue-ram: mktmpfile");
		return (-1);
	}

	fd2 = dup(fd);
	if (fd2 == -1) {
		log_warn("warn: queue-ram: dup");
		close(fd);
		return (-1);
	}
	f = fdopen(fd2, "w");
	if (f == NULL) {
		log_warn("warn: queue-ram: fdopen");
		close(fd);
		close(fd2);
		return (-1);
	}
	n = fwrite(msg->buf, 1, msg->len, f);
	if (n != msg->len) {
		log_warn("warn: queue-ram: write");
		close(fd);
		fclose(f);
		return (-1);
	}
	fclose(f);
	lseek(fd, 0, SEEK_SET);
	return (fd);
}
Пример #18
0
static int
queue_ram_envelope_load(uint64_t evpid, char *buf, size_t len)
{
	struct qr_envelope	*evp;
	struct qr_message	*msg;

	if ((msg = get_message(evpid_to_msgid(evpid))) == NULL)
		return (0);

	if ((evp = tree_get(&msg->envelopes, evpid)) == NULL) {
		log_warn("warn: queue-ram: not found");
		return (0);
	}
	if (len < evp->len) {
		log_warnx("warn: queue-ram: buffer too small");
		return (0);
	}
	memmove(buf, evp->buf, evp->len);
	return (evp->len);
}
Пример #19
0
static ssize_t addrs_get(backend_t *chain, request_t *request){
	ssize_t           ret;
	data_t           *temp;
	off_t             def_real_offset;
	unsigned int      def_block_vid;
	unsigned int      def_block_size;
	off_t            *o_real_offset = &def_real_offset;
	unsigned int     *o_block_vid   = &def_block_vid;
	unsigned int     *o_block_size  = &def_block_size;
	block_info        block;
	off_t             r_virt_key;
	uint32_t          r_block_vid;
	hash_t           *r_virt_key, *r_block_vid;
	addrs_userdata   *data = (addrs_userdata *)chain->userdata;
	
	temp = hash_find_typed(request, TYPE_OFFT,  HK(real_offset));
	if(temp != NULL) o_real_offset = data_value_ptr(temp);
	temp = hash_find_typed(request, TYPE_UINT32T, HK(block_vid));
	if(temp != NULL) o_block_vid   = data_value_ptr(temp);
	temp = hash_find_typed(request, TYPE_UINT32T, HK(block_size));
	if(temp != NULL) o_block_size  = data_value_ptr(temp);
	
	if(hash_find(request, HK(blocks)) == NULL){
		hash_data_copy(ret, TYPE_OFFT, r_virt_key, request, HK(offset)); if(ret != 0) return warning("no offset supplied");
		
		if(tree_get(data->tree, r_virt_key, o_block_vid, o_real_offset) != 0)
			return -EFAULT;
	}else{
		hash_data_copy(ret, TYPE_UINT32T, r_block_vid, request, HK(block_vid)); if(ret != 0) return warning("no block_vid supplied");
		
		if(tree_get_block(data->tree, r_block_vid, &block) != 0)
			return -EFAULT;
		
		*o_real_offset = (off_t)(block.real_block_off);
		*o_block_size  = (unsigned int)(block.size);
	}
	return 0;
}
Пример #20
0
int tree_swap(struct tree_item *root)
{
	struct tree *new_tree, *old_tree;

	new_tree = tree_alloc();
	if (NULL == new_tree)
		return -1;

	new_tree->root = root;

	/* Save old tree */
	old_tree = tree_get();

	/* Critical - swap trees */
	lock_get(shared_tree_lock);
	*shared_tree = new_tree;
	lock_release(shared_tree_lock);

	/* Flush old tree */
	tree_flush(old_tree);

	return 0;
}
Пример #21
0
/* ARGSUSED */
static void
control_accept(int listenfd, short event, void *arg)
{
	int			 connfd;
	socklen_t		 len;
	struct sockaddr_un	 sun;
	struct ctl_conn		*c;
	size_t			*count;
	uid_t			 euid;
	gid_t			 egid;

	if (getdtablesize() - getdtablecount() < CONTROL_FD_RESERVE)
		goto pause;

	len = sizeof(sun);
	if ((connfd = accept(listenfd, (struct sockaddr *)&sun, &len)) == -1) {
		if (errno == ENFILE || errno == EMFILE)
			goto pause;
		if (errno == EINTR || errno == EWOULDBLOCK ||
		    errno == ECONNABORTED)
			return;
		fatal("control_accept: accept");
	}

	session_socket_blockmode(connfd, BM_NONBLOCK);

	if (getpeereid(connfd, &euid, &egid) == -1)
		fatal("getpeereid");

	count = tree_get(&ctl_count, euid);
	if (count == NULL) {
		count = xcalloc(1, sizeof *count, "control_accept");
		tree_xset(&ctl_count, euid, count);
	}

	if (*count == CONTROL_MAXCONN_PER_CLIENT) {
		close(connfd);
		log_warnx("warn: too many connections to control socket "
		    "from user with uid %lu", (unsigned long int)euid);
		return;
	}
	(*count)++;

	c = xcalloc(1, sizeof(*c), "control_accept");
	c->euid = euid;
	c->egid = egid;
	c->id = ++connid;
	c->mproc.proc = PROC_CLIENT;
	c->mproc.handler = control_dispatch_ext;
	c->mproc.data = c;
	mproc_init(&c->mproc, connfd);
	mproc_enable(&c->mproc);
	tree_xset(&ctl_conns, c->id, c);

	stat_backend->increment("control.session", 1);
	return;

pause:
	log_warnx("warn: ctl client limit hit, disabling new connections");
	event_del(&control_state.ev);
}
Пример #22
0
/*
 * Carry out aggregation on a complete data set held in a table
 * This is an alternative entry point to the class that does not need
 * the setting up of a session.
 * The table should identify keys, time, sequence and duration in the 
 * standard way as defined by FHA spec.
 * Returns a TABLE of results compliant to the FHA spec, _time will be
 * set to the last time of the dataset, _seq to 0. _dur is not set
 * The result is independent of dataset's memory allocation, sothe caller
 * needs to run table_destroy() to free its memory.
 * Returns NULL if there is an error, if dataset is NULL or if there
 * was insufficent data.
 */
TABLE cascade_aggregate(enum cascade_fn func, 	/* aggregation function */
			TABLE dataset		/* multi-sample, multi-key
						 * dataset in a table */ )
{
     TREE *inforow, *keyvals, *databykey, *colnames;
     char *keycol, *colname, *tmpstr, *type;
     int duration, haskey=0;
     TABLE itab, result;
     TABSET tset;
     ITREE *col;
     double val, tmpval1, tmpval2;
     time_t t1, t2, tdiff;

     /* assert special cases */
     if ( ! dataset ) {
          elog_printf(DIAG, "no dataset given to aggregate");
          return NULL;
     }
     if (table_nrows(dataset) == 0) {
          elog_printf(DIAG, "no rows to aggregate in dataset");
     }
     if ( ! table_hascol(dataset, "_time")) {
          tmpstr = table_outheader(dataset);
          elog_printf(ERROR, "attempting to aggregate a table without _time "
		      "column (columns: %s)", tmpstr);
	  nfree(tmpstr);
          return NULL;
     }

     /* find any keys that might exist */
     inforow = table_getinforow(dataset, "key");
     if (inforow) {
          keycol = tree_search(inforow, "1", 2);
	  if (keycol) {
	       keyvals = table_uniqcolvals(dataset, keycol, NULL);
	       if (keyvals) {
		    /* separate the combined data set into ones of
		     * separate keys */
		    haskey++;
		    databykey = tree_create();
		    tset = tableset_create(dataset);
		    tree_traverse(keyvals) {
		         /* select out the data */
		         tableset_reset(tset);
			 tableset_where(tset, keycol, eq, 
					tree_getkey(keyvals));
			 itab = tableset_into(tset);
		         tree_add(databykey, tree_getkey(keyvals), itab);
		    }
		    tableset_destroy(tset);
	       }
	       tree_destroy(keyvals);
	  }
	  tree_destroy(inforow);
     }

     /* if there were no keys found, pretend that we have a single one */
     if ( ! haskey ) {
          databykey = tree_create();
	  tree_add(databykey, "nokey", dataset);
     }

     /* find the time span and duration of the dataset */
     table_first(dataset);
     if (table_hascol(dataset, "_dur"))
          duration = strtol(table_getcurrentcell(dataset, "_dur"), NULL, 10);
     else
          duration = 0;
     t1 = strtol(table_getcurrentcell(dataset, "_time"), NULL, 10);
     table_last(dataset);
     t2 = strtol(table_getcurrentcell(dataset, "_time"), NULL, 10);
     tdiff = t2-t1+duration;

     /* go over the keyed table and apply our operators to each column 
      * in turn */
     result = table_create_fromdonor(dataset);
     table_addcol(result, "_seq", NULL);	/* make col before make row */
     table_addcol(result, "_time", NULL);
     table_addcol(result, "_dur", NULL);
     tree_traverse(databykey) {
          table_addemptyrow(result);
          itab = tree_get(databykey);
	  colnames = table_getheader(itab);
	  tree_traverse(colnames) {
	       colname = tree_getkey(colnames);
	       if ( ! table_hascol(result, colname)) {
		     tmpstr = xnstrdup(colname);
		     table_addcol(result, tmpstr, NULL);
		     table_freeondestroy(result, tmpstr);
	       }
	       col = table_getcol(itab, colname);
	       type = table_getinfocell(itab, "type", colname);
	       if (type && strcmp(type, "str") == 0) {
		    /* string value: report the last one */
		    itree_last(col);
		    table_replacecurrentcell(result, colname, itree_get(col));
	       } else if (strcmp(colname, "_dur") == 0) {
		    /* _dur: use the last value, can treat as string */
		    itree_last(col);
		    table_replacecurrentcell(result, "_dur", itree_get(col));
	       } else if (strcmp(colname, "_seq") == 0) {
		    /* _seq: only one result is produced so must be 0 */
		    table_replacecurrentcell(result, "_seq", "0");
	       } else if (strcmp(colname, "_time") == 0) {
		    /* _time: use the last value, can treat as string */
		    itree_last(col);
		    table_replacecurrentcell(result, "_time", itree_get(col));
	       } else {
		    /* numeric value: treat as a float and report it */
		    switch (func) {
		    case CASCADE_AVG:
		         /* average of column's values */
		         val = 0.0;
			 itree_traverse(col)
			      val += atof( itree_get(col) );
			 val = val / itree_n(col);
			 break;
		    case CASCADE_MIN:
		         /* minimum of column's values */
		         val = DBL_MAX;
			 itree_traverse(col) {
			      tmpval1 = atof( itree_get(col) );
			      if (tmpval1 < val)
				   val = tmpval1;
			 }
			 break;
		    case CASCADE_MAX:
		         /* maximum of column's values */
		         val = DBL_MIN;
			 itree_traverse(col) {
			      tmpval1 = atof( itree_get(col) );
			      if (tmpval1 > val)
				   val = tmpval1;
			 }
			 break;
		    case CASCADE_SUM:
		         /* sum of column's values */
		         val = 0.0;
			 itree_traverse(col)
			      val += atof( itree_get(col) );
			 break;
		    case CASCADE_LAST:
		         /* last value */
		         itree_last(col);
			 val = atof( itree_get(col) );
			 break;
		    case CASCADE_FIRST:
		         /* last value */
		         itree_first(col);
			 val = atof( itree_get(col) );
			 break;
		    case CASCADE_DIFF:
		         /* the difference in values of first and last */
		         itree_first(col);
			 tmpval1 = atof( itree_get(col) );
			 itree_last(col);
			 tmpval2 = atof( itree_get(col) );
			 val = tmpval2 - tmpval1;
			 break;
		    case CASCADE_RATE:
		         /* difference in values (as CASCADE_DIFF) then 
			  * divided by the number of seconds in the set  */
		         itree_first(col);
			 tmpval1 = atof( itree_get(col) );
			 itree_last(col);
			 tmpval2 = atof( itree_get(col) );
			 val = tmpval2 - tmpval1;
			 val = val / tdiff;
			 break;
		    }
		    /* save the floating point value */
		    table_replacecurrentcell_alloc(result, colname, 
						   util_ftoa(val));
	       }
	       itree_destroy(col);
	  }
	  /* make sure that there are values for the special columns */
	  if ( ! table_hascol(dataset, "_time"))
	       table_replacecurrentcell(result, "_time", 
					util_decdatetime(time(NULL)));
	  if ( ! table_hascol(dataset, "_seq"))
	       table_replacecurrentcell(result, "_seq", "0");
	  if ( ! table_hascol(dataset, "_dur"))
	       table_replacecurrentcell(result, "_dur", "0");
     }

     /* clear up */
     if (haskey) {
          tree_traverse(databykey) {
	       itab = tree_get(databykey);
	       table_destroy(itab);
	  }
     }
     tree_destroy(databykey);

     return result;
}
Пример #23
0
void tree_close(void)
{
	tree_flush(tree_get());
}
Пример #24
0
static void
control_imsg(struct mproc *p, struct imsg *imsg)
{
	struct ctl_conn		*c;
	struct stat_value	 val;
	struct msg		 m;
	const char		*key;
	const void		*data;
	size_t			 sz;

	if (p->proc == PROC_PONY) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_SMTP_SESSION:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			m_compose(&c->mproc, IMSG_CTL_OK, 0, 0, imsg->fd,
			    NULL, 0);
			return;
		}
	}
	if (p->proc == PROC_SCHEDULER) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_OK:
		case IMSG_CTL_FAIL:
		case IMSG_CTL_LIST_MESSAGES:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			imsg->hdr.peerid = 0;
			m_forward(&c->mproc, imsg);
			return;
		}
	}
	if (p->proc == PROC_QUEUE) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_LIST_ENVELOPES:
		case IMSG_CTL_DISCOVER_EVPID:
		case IMSG_CTL_DISCOVER_MSGID:
		case IMSG_CTL_UNCORRUPT_MSGID:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			m_forward(&c->mproc, imsg);
			return;
		}
	}
	if (p->proc == PROC_PONY) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_OK:
		case IMSG_CTL_FAIL:
		case IMSG_CTL_MTA_SHOW_HOSTS:
		case IMSG_CTL_MTA_SHOW_RELAYS:
		case IMSG_CTL_MTA_SHOW_ROUTES:
		case IMSG_CTL_MTA_SHOW_HOSTSTATS:
		case IMSG_CTL_MTA_SHOW_BLOCK:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			imsg->hdr.peerid = 0;
			m_forward(&c->mproc, imsg);
			return;
		}
	}

	switch (imsg->hdr.type) {
	case IMSG_STAT_INCREMENT:
		m_msg(&m, imsg);
		m_get_string(&m, &key);
		m_get_data(&m, &data, &sz);
		m_end(&m);
		memmove(&val, data, sz);
		if (stat_backend)
			stat_backend->increment(key, val.u.counter);
		control_digest_update(key, val.u.counter, 1);
		return;
	case IMSG_STAT_DECREMENT:
		m_msg(&m, imsg);
		m_get_string(&m, &key);
		m_get_data(&m, &data, &sz);
		m_end(&m);
		memmove(&val, data, sz);
		if (stat_backend)
			stat_backend->decrement(key, val.u.counter);
		control_digest_update(key, val.u.counter, 0);
		return;
	case IMSG_STAT_SET:
		m_msg(&m, imsg);
		m_get_string(&m, &key);
		m_get_data(&m, &data, &sz);
		m_end(&m);
		memmove(&val, data, sz);
		if (stat_backend)
			stat_backend->set(key, &val);
		return;
	}

	errx(1, "control_imsg: unexpected %s imsg",
	    imsg_to_str(imsg->hdr.type));
}
Пример #25
0
void
mta_imsg(struct imsgev *iev, struct imsg *imsg)
{
	struct mta_route	*route;
	struct mta_batch2	*batch;
	struct mta_task		*task;
	struct envelope		*e;
	struct ssl		*ssl;
	uint64_t		 id;

	if (iev->proc == PROC_QUEUE) {
		switch (imsg->hdr.type) {

		case IMSG_BATCH_CREATE:
			id = *(uint64_t*)(imsg->data);
			batch = xmalloc(sizeof *batch, "mta_batch");
			batch->id = id;
			tree_init(&batch->tasks);
			tree_xset(&batches, batch->id, batch);
			log_trace(TRACE_MTA,
			    "mta: batch:%016" PRIx64 " created", batch->id);
			return;

		case IMSG_BATCH_APPEND:
			e = xmemdup(imsg->data, sizeof *e, "mta:envelope");
			route = mta_route_for(e);
			batch = tree_xget(&batches, e->batch_id);

			if ((task = tree_get(&batch->tasks, route->id)) == NULL) {
				log_trace(TRACE_MTA, "mta: new task for %s",
				    mta_route_to_text(route));
				task = xmalloc(sizeof *task, "mta_task");
				TAILQ_INIT(&task->envelopes);
				task->route = route;
				tree_xset(&batch->tasks, route->id, task);
				task->msgid = evpid_to_msgid(e->id);
				task->sender = e->sender;
				route->refcount += 1;
			}

			/* Technically, we could handle that by adding a msg
			 * level, but the batch sent by the scheduler should
			 * be valid.
			 */
			if (task->msgid != evpid_to_msgid(e->id))
				errx(1, "msgid mismatch in batch");

			/* XXX honour route->maxrcpt */
			TAILQ_INSERT_TAIL(&task->envelopes, e, entry);
			stat_increment("mta.envelope", 1);
			log_debug("mta: received evp:%016" PRIx64 " for <%s@%s>",
			    e->id, e->dest.user, e->dest.domain);
			return;

		case IMSG_BATCH_CLOSE:
			id = *(uint64_t*)(imsg->data);
			batch = tree_xpop(&batches, id);
			log_trace(TRACE_MTA, "mta: batch:%016" PRIx64 " closed",
			    batch->id);
			/* for all tasks, queue them on there route */
			while (tree_poproot(&batch->tasks, &id, (void**)&task)) {
				if (id != task->route->id)
					errx(1, "route id mismatch!");
				task->route->refcount -= 1;
				task->route->ntask += 1;
				TAILQ_INSERT_TAIL(&task->route->tasks, task, entry);
				stat_increment("mta.task", 1);
				mta_route_drain(task->route);
			}
			free(batch);
			return;

		case IMSG_QUEUE_MESSAGE_FD:
			mta_session_imsg(iev, imsg);
			return;
		}
	}

	if (iev->proc == PROC_LKA) {
		switch (imsg->hdr.type) {
		case IMSG_LKA_SECRET:
		case IMSG_DNS_HOST:
		case IMSG_DNS_HOST_END:
		case IMSG_DNS_PTR:
			mta_session_imsg(iev, imsg);
			return;
		}
	}

	if (iev->proc == PROC_PARENT) {
		switch (imsg->hdr.type) {
		case IMSG_CONF_START:
			if (env->sc_flags & SMTPD_CONFIGURING)
				return;
			env->sc_flags |= SMTPD_CONFIGURING;
			env->sc_ssl = xcalloc(1, sizeof *env->sc_ssl, "mta:sc_ssl");
			return;

		case IMSG_CONF_SSL:
			if (!(env->sc_flags & SMTPD_CONFIGURING))
				return;
			ssl = xmemdup(imsg->data, sizeof *ssl, "mta:ssl");
			ssl->ssl_cert = xstrdup((char*)imsg->data + sizeof *ssl,
			    "mta:ssl_cert");
			ssl->ssl_key = xstrdup((char*)imsg->data +
			    sizeof *ssl + ssl->ssl_cert_len, "mta:ssl_key");
			SPLAY_INSERT(ssltree, env->sc_ssl, ssl);
			return;

		case IMSG_CONF_END:
			if (!(env->sc_flags & SMTPD_CONFIGURING))
				return;
			env->sc_flags &= ~SMTPD_CONFIGURING;
			return;

		case IMSG_CTL_VERBOSE:
			log_verbose(*(int *)imsg->data);
			return;
		}
	}

	errx(1, "mta_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
Пример #26
0
injection_t * injection_get(const process_t * process, const injectable_t * injectable) {
    return tree_get(&process->injections, (tree_key_t) injectable);
}