Esempio n. 1
0
T p_string_new(Mempool_T pool, const char * s)
{
	T S;
	assert(pool);
	assert(s);
	size_t l = strlen(s);
	S = mempool_pop(pool, sizeof(*S));
	S->pool = pool;
	S->len = l;
	S->str = (char *)mempool_pop(S->pool, SIZE(S));
	memcpy(S->str, s, l);
	S->used = l;
	return S;
}
Esempio n. 2
0
T Capa_new(Mempool_T pool)
{
	Field_T val;
        char maxcapa[MAX_CAPASIZE];
	T A;
	A = mempool_pop(pool, sizeof(*A));
	A->pool = pool;
	char **v, **h;

	memset(&maxcapa,0,sizeof(maxcapa));

	GETCONFIGVALUE("capability", "IMAP", val);
	if (strlen(val) > 0)
		strncpy((char *)maxcapa, val, MAX_CAPASIZE-1);
	else
		strncpy((char *)maxcapa, IMAP_CAPABILITY_STRING, MAX_CAPASIZE-1);

	A->max_set = p_list_new(A->pool);
	A->current_set = p_list_new(A->pool);

	h = v = g_strsplit(maxcapa, " ", -1);
	while (*v) {
		String_T S = p_string_new(A->pool, *v++);
		A->max_set = p_list_append(A->max_set, S);
		A->current_set = p_list_append(A->current_set, S);
		assert(A->current_set);
	}

	g_strfreev(h);

	A->dirty = TRUE;
	return A;
}
Esempio n. 3
0
static gboolean mailbox_build_recent(uint64_t *uid, MessageInfo *msginfo, T M)
{
	if (msginfo->flags[IMAP_FLAG_RECENT]) {
		uint64_t *copy = mempool_pop(M->pool, sizeof(uint64_t));
		*copy = *uid;
		g_tree_insert(M->recent_queue, copy, copy);
	}
	return FALSE;
}
Esempio n. 4
0
static int filter_range(gpointer key, gpointer value, gpointer data)
{                       
	uint64_t *k, *v;   
	struct filter_range_helper *d = (struct filter_range_helper *)data;

	if (*(uint64_t *)key < d->min) return FALSE; // skip
	if (*(uint64_t *)key > d->max) return TRUE; // done

	k = mempool_pop(small_pool, sizeof(uint64_t));
	v = mempool_pop(small_pool, sizeof(uint64_t));

	*k = *(uint64_t *)key;
	*v = *(uint64_t *)value;

	if (d->uid)     
		g_tree_insert(d->a, k, v);
	else            
		g_tree_insert(d->a, v, k);

	return FALSE;   
}                       
Esempio n. 5
0
T MailboxState_new(Mempool_T pool, uint64_t id)
{
	T M; Connection_T c;
	volatile int t = DM_SUCCESS;
	gboolean freepool = FALSE;

	if (! pool) {
		pool = mempool_open();
		freepool = TRUE;
	}

	M = mempool_pop(pool, sizeof(*M));
	M->pool = pool;
	M->freepool = freepool;

	if (! id) return M;

	M->id = id;
	M->recent_queue = g_tree_new((GCompareFunc)ucmp);
	M->keywords     = g_tree_new_full((GCompareDataFunc)_compare_data,NULL,g_free,NULL);

	c = db_con_get();
	TRY
		db_begin_transaction(c); // we need read-committed isolation
		state_load_metadata(M, c);
		state_load_messages(M, c);
	CATCH(SQLException)
		LOG_SQLERROR;
		t = DM_EQUERY;
	FINALLY
		db_commit_transaction(c);
		db_con_close(c);
	END_TRY;

	if (t == DM_EQUERY) {
		TRACE(TRACE_ERR, "Error opening mailbox");
		MailboxState_free(&M);
	}

	return M;
}
Esempio n. 6
0
GTree * MailboxState_get_set(MailboxState_T M, const char *set, gboolean uid)
{
	GTree *inset, *a, *b;
	GList *sets = NULL;
	GString *t;
	uint64_t lo = 0, hi = 0;
	gboolean error = FALSE;

	if (uid)
		inset = MailboxState_getIds(M);
	else
		inset = MailboxState_getMsn(M);

	a = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL, (GDestroyNotify)uint64_free, (GDestroyNotify)uint64_free);
	b = g_tree_new_full((GCompareDataFunc)ucmpdata,NULL, (GDestroyNotify)uint64_free, (GDestroyNotify)uint64_free);

	if (! uid) {
		lo = 1;
		hi = MailboxState_getExists(M);
	} else {
		GList *ids = g_tree_keys(inset);
		if (ids) {
			ids = g_list_last(ids);
			hi = *((uint64_t *)ids->data);
			ids = g_list_first(ids);
			lo = *((uint64_t *)ids->data);
			g_list_free(g_list_first(ids));
		}
	}

	t = g_string_new(set);
	sets = g_string_split(t,",");
	g_string_free(t,TRUE);

	sets = g_list_first(sets);
	while(sets) {
		uint64_t l = 0, r = 0;
		
		char *rest = (char *)sets->data;

		if (strlen(rest) < 1) break;

		if (g_tree_nnodes(inset) == 0) { // empty box
			if (rest[0] == '*') {
				uint64_t *k = mempool_pop(small_pool, sizeof(uint64_t));
				uint64_t *v = mempool_pop(small_pool, sizeof(uint64_t));

				*k = 1;
				*v = MailboxState_getUidnext(M);

				g_tree_insert(b, k, v);
			} else {
				if (! (l = dm_strtoull(sets->data, &rest, 10))) {
					error = TRUE;
					break;
				}
				if (rest[0]) {
					if (rest[0] != ':') {
						error = TRUE;
						break;
					}
					rest++;
					if ((rest[0] != '*') && (! dm_strtoull(rest, NULL, 10))) {
						error = TRUE;
						break;
					}
				}
				uint64_t *k = mempool_pop(small_pool, sizeof(uint64_t));
				uint64_t *v = mempool_pop(small_pool, sizeof(uint64_t));

				*k = 1;
				*v = MailboxState_getUidnext(M);

				g_tree_insert(b, k, v);
			}
		} else {
			if (rest[0] == '*') {
				l = hi;
				r = l;
				if (strlen(rest) > 1)
					rest++;
			} else {
				if (! (l = dm_strtoull(sets->data,&rest,10))) {
					error = TRUE;
					break;
				}

				if (l == 0xffffffff) l = hi; // outlook

				l = max(l,lo);
				r = l;
			}
			
			if (rest[0]==':') {
				if (strlen(rest)>1) rest++;
				if (rest[0] == '*') r = hi;
				else {
					if (! (r = dm_strtoull(rest,NULL,10))) {
						error = TRUE;
						break;
					}

					if (r == 0xffffffff) r = hi; // outlook
				}
				
				if (!r) break;
			}
		
			if (! (l && r)) break;

			find_range(inset, min(l,r), max(l,r), a, uid);

			if (g_tree_merge(b,a,IST_SUBSEARCH_OR)) {
				error = TRUE;
				TRACE(TRACE_ERR, "cannot compare null trees");
				break;
			}
		}

		if (! g_list_next(sets)) break;
		sets = g_list_next(sets);
	}

	g_list_destroy(sets);

	if (a) g_tree_destroy(a);

	if (error) {
		g_tree_destroy(b);
		b = NULL;
		TRACE(TRACE_DEBUG, "return NULL");
	}

	return b;
}
Esempio n. 7
0
File: pop3.c Progetto: skeyby/dbmail
static int db_createsession(uint64_t user_idnr, ClientSession_T * session)
{
    Connection_T c;
    ResultSet_T r;
    volatile int t = DM_SUCCESS;
    struct message *tmpmessage;
    int message_counter = 0;
    const char *query_result;
    uint64_t mailbox_idnr;
    INIT_QUERY;

    if (db_find_create_mailbox("INBOX", BOX_DEFAULT, user_idnr, &mailbox_idnr) < 0) {
        TRACE(TRACE_NOTICE, "find_create INBOX for user [%" PRIu64 "] failed, exiting..", user_idnr);
        return DM_EQUERY;
    }

    g_return_val_if_fail(mailbox_idnr > 0, DM_EQUERY);

    /* query is < MESSAGE_STATUS_DELETE  because we don't want deleted
     * messages
     */
    snprintf(query, DEF_QUERYSIZE-1,
             "SELECT pm.messagesize, msg.message_idnr, msg.status, "
             "msg.unique_id FROM %smessages msg, %sphysmessage pm "
             "WHERE msg.mailbox_idnr = %" PRIu64 " "
             "AND msg.status < %d "
             "AND msg.physmessage_id = pm.id "
             "ORDER BY msg.message_idnr ASC",DBPFX,DBPFX,
             mailbox_idnr, MESSAGE_STATUS_DELETE);

    c = db_con_get();
    TRY
    r = db_query(c, query);

    session->totalmessages = 0;
    session->totalsize = 0;

    /* messagecounter is total message, +1 tot end at message 1 */
    message_counter = 1;

    /* filling the list */
    TRACE(TRACE_DEBUG, "adding items to list");
    while (db_result_next(r)) {
        tmpmessage = mempool_pop(session->pool, sizeof(struct message));
        /* message size */
        tmpmessage->msize = db_result_get_u64(r,0);
        /* real message id */
        tmpmessage->realmessageid = db_result_get_u64(r,1);
        /* message status */
        tmpmessage->messagestatus = db_result_get_u64(r,2);
        /* virtual message status */
        tmpmessage->virtual_messagestatus = tmpmessage->messagestatus;
        /* unique id */
        query_result = db_result_get(r,3);
        if (query_result)
            strncpy(tmpmessage->uidl, query_result, UID_SIZE-1);

        session->totalmessages++;
        session->totalsize += tmpmessage->msize;
        tmpmessage->messageid = (uint64_t) message_counter;

        session->messagelst = p_list_append(session->messagelst, tmpmessage);

        message_counter++;
    }
    CATCH(SQLException)
    LOG_SQLERROR;
    t = DM_EQUERY;
    FINALLY
    db_con_close(c);
    END_TRY;

    if (t == DM_EQUERY) return t;
    if (message_counter == 1) {
        /* there are no messages for this user */
        return DM_EGENERAL;
    }

    TRACE(TRACE_DEBUG, "adding succesful");

    /* setting all virtual values */
    session->virtual_totalmessages = session->totalmessages;
    session->virtual_totalsize = session->totalsize;

    return DM_EGENERAL;
}
Esempio n. 8
0
File: imap4.c Progetto: m8rge/dbmail
void imap_handle_input(ImapSession *session)
{
	char buffer[MAX_LINESIZE];
	char *alloc_buf = NULL;
	uint64_t alloc_size = 0;
	int l, result;

	assert(session && session->ci && session->ci->write_buffer);

	// first flush the output buffer
	if (p_string_len(session->ci->write_buffer)) {
		TRACE(TRACE_DEBUG,"[%p] write buffer not empty", session);
		ci_write(session->ci, NULL);
	}

	// nothing left to handle
	if (p_string_len(session->ci->read_buffer) == 0) {
		TRACE(TRACE_DEBUG,"[%p] read buffer empty", session);
		return;
	}

	// command in progress
	if (session->command_state == FALSE && session->parser_state == TRUE) {
		TRACE(TRACE_DEBUG,"[%p] command in-progress", session);
		return;
	}

	// reset if we're done with the previous command
	if (session->command_state == TRUE)
		imap_session_reset(session);


	// Read in a line at a time if we don't have a string literal size defined
	// Otherwise read in rbuff_size amount of data
	while (TRUE) {
		char *input = NULL;
		FREE_ALLOC_BUF
		memset(buffer, 0, sizeof(buffer));

		if (session->ci->rbuff_size <= 0) {
			l = ci_readln(session->ci, buffer);
		} else {
			alloc_size = session->ci->rbuff_size+1;
			alloc_buf = mempool_pop(session->pool, alloc_size);
			l = ci_read(session->ci, alloc_buf, session->ci->rbuff_size);
		}

		if (l == 0) break; // done

		if (session->error_count >= MAX_FAULTY_RESPONSES) {
			imap_session_printf(session, "* BYE [TRY RFC]\r\n");
			imap_handle_abort(session);
			break;
		}

		// session is in a IDLE loop
		if (session->command_type == IMAP_COMM_IDLE  && session->command_state == IDLE) { 
			if (strlen(buffer) > 4 && strncasecmp(buffer,"DONE",4)==0)
				imap_session_printf(session, "%s OK IDLE terminated\r\n", session->tag);
			else
				imap_session_printf(session,"%s BAD Expecting DONE\r\n", session->tag);

			session->command_state = TRUE; // done
			imap_session_reset(session);

			continue;
		}

		if (alloc_buf != NULL)
			input = alloc_buf;
		else
			input = buffer;

		if (! imap4_tokenizer(session, input)) {
			FREE_ALLOC_BUF
			continue;
		}

		if ( session->parser_state < 0 ) {
			imap_session_printf(session, "%s BAD parse error\r\n", session->tag);
			imap_handle_retry(session);
			break;
		}

		if ( session->parser_state ) {
			result = imap4(session);
			TRACE(TRACE_DEBUG,"imap4 returned [%d]", result);
			if (result || (session->command_type == IMAP_COMM_IDLE && session->command_state == IDLE)) { 
				imap_handle_exit(session, result);
			}
			break;
		}

		if (session->state == CLIENTSTATE_ERROR) {
			TRACE(TRACE_NOTICE, "session->state: ERROR. abort");
			break;
		}
	}