Esempio n. 1
0
File: imap4.c Progetto: m8rge/dbmail
static void imap_handle_continue(ImapSession *session)
{
	if (session->state < CLIENTSTATE_LOGOUT) {
		if (session->buff && p_string_len(session->buff) > 0) {
			int e = 0;
			if ((e = ci_write(session->ci, "%s", (char *)p_string_str(session->buff))) < 0) {
				int serr = errno;
				TRACE(TRACE_DEBUG,"ci_write returned error [%s]", strerror(serr));
				imap_handle_abort(session);
				return;
			}
			dbmail_imap_session_buff_clear(session);
		}
		if (p_string_len(session->ci->write_buffer) > session->ci->write_buffer_offset)
			ci_write(session->ci, NULL);
		if (session->command_state == TRUE)
			imap_session_reset(session);
	} else {
		dbmail_imap_session_buff_clear(session);
	}				

	// handle buffered pending input
	if (p_string_len(session->ci->read_buffer) > 0)
		imap_handle_input(session);
}
Esempio n. 2
0
int p_xml_key_append (struct str_xml_key **record, char *key, char *value) {
	struct str_xml_key *singleton;
	size_t length;
	int result = pippolo_true;
	p_string_trim(key);
	p_string_trim(value);
	if ((key) && (value)) {
		if ((singleton = (struct str_xml_key *) pippolo_malloc(sizeof(str_xml_key)))) {
			length = p_string_len(value)+1;
			if ((singleton->value = (char *) pippolo_malloc(length))) {
				snprintf(singleton->value, length, "%s", value);
				length = p_string_len(key)+1;
				if ((singleton->key = (char *) pippolo_malloc(length))) {
					snprintf(singleton->key, length, "%s", key);
					singleton->next = *record;
					*record = singleton;
				} else
					pippolo_kill("out of memory, I'm dying bleaaargh");
			} else
				pippolo_kill("out of memory, I'm dying bleaaargh");
		} else
			pippolo_kill("out of memory, I'm dying bleaaargh");
	}
	return result;
}
Esempio n. 3
0
File: imap4.c Progetto: m8rge/dbmail
/* 
 * only the main thread may write to the network event
 * worker threads must use an async queue
 */
static int64_t imap_session_printf(ImapSession * session, char * message, ...)
{
        va_list ap, cp;
        uint64_t l;
	int e = 0;

	p_string_truncate(session->buff, 0);

        assert(message);
        va_start(ap, message);
	va_copy(cp, ap);
        p_string_append_vprintf(session->buff, message, cp);
        va_end(cp);
        va_end(ap);

	if ((e = ci_write(session->ci, (char *)p_string_str(session->buff))) < 0) {
		TRACE(TRACE_DEBUG, "ci_write failed [%d]", e);
		imap_handle_abort(session);
		return e;
	}

        l = p_string_len(session->buff);
	p_string_truncate(session->buff, 0);

        return (int64_t)l;
}
Esempio n. 4
0
File: imap4.c Progetto: m8rge/dbmail
void imap_cb_read(void *arg)
{
	ImapSession *session = (ImapSession *) arg;

	ci_read_cb(session->ci);

	uint64_t have = p_string_len(session->ci->read_buffer);
	uint64_t need = session->ci->rbuff_size;

	int enough = (need>0?(have >= need):(have >= 0));
	int state;
       
	PLOCK(session->ci->lock);
	state = session->ci->client_state;
	PUNLOCK(session->ci->lock);

	TRACE(TRACE_DEBUG,"state [%d] enough %d: %" PRIu64 "/%" PRIu64 "", state, enough, have, need);

	if (state & CLIENT_ERR) {
		imap_session_bailout(session);
	} else if (state & CLIENT_EOF) {
		ci_cork(session->ci);
		if (enough)
			imap_handle_input(session);
		else
			imap_session_bailout(session);
	} else if (have > 0)
		imap_handle_input(session);
}
Esempio n. 5
0
size_t p_network_write (int hook, char *buffer) {
	size_t result = 0, size = p_string_len(buffer);
	int length = (int)size;
	if (hook != pippolo_null_socket) {
		if (_p_endian_check() != pippolo_default_endian)
			pippolo_swap(length);
		if ((pippolo_intro == write(hook, &length, pippolo_intro))) {
			if ((result = write(hook, buffer, size)))
				pippolo_log(ELOG_COMMUNICATIONS, "writing message to token %d: %s", hook, buffer);
		}
	}
	return result;
}
Esempio n. 6
0
int _p_xml_draw (FILE *stream, str_xml_node *root, int deep) {
	int result = pippolo_true, index;
	struct str_xml_key *backup;
	struct str_xml_node *childrens;
	if (root) {
		if (p_string_len(root->label) > 0) {
			for (index = 0; index < deep; index++)
				fprintf(stream, "\t");
			fprintf(stream, "<%s", root->label);
			backup = root->keys;
			while (backup) {
				fprintf(stream, " %s=%s", backup->key, backup->value);
				backup = backup->next;
			}
			fprintf(stream, ">");
		}
		if (root->value)
			fprintf(stream, "%s", root->value);
		if (root->children) {
			childrens = root->children;
			fprintf(stream, "\n");
			while (childrens) {
				if (!(result = _p_xml_draw(stream, childrens, deep+1)))
					break;
				childrens = childrens->next;
			}
		}
		if (p_string_len(root->label) > 0) {
			if ((root->children))
				for (index = 0; index < deep; index++)
					fprintf(stream, "\t");
			fprintf(stream, "</%s>", root->label);
		}
	}
	fprintf(stream, "\n");
	return result;
}
Esempio n. 7
0
int _p_xml_string (char **string, str_xml_node *root) {
	int result = pippolo_true;
	struct str_xml_key *backup;
	struct str_xml_node *childrens;
	if (root) {
		if (p_string_len(root->label) > 0) {
			pippolo_append(*string, "<");
			pippolo_append(*string, root->label);
			backup = root->keys;
			while (backup) {
				pippolo_append(*string, " ");
				pippolo_append(*string, backup->key);
				pippolo_append(*string, "=");
				pippolo_append(*string, backup->value);
				backup = backup->next;
			}
			pippolo_append(*string, ">");
		}
		if (root->value)
			pippolo_append(*string, root->value);
		if (root->children) {
			childrens = root->children;
			while (childrens) {
				if (!(result = _p_xml_string(string, childrens)))
					break;
				childrens = childrens->next;
			}
		}
		if (p_string_len(root->label) > 0) {
			pippolo_append(*string, "</");
			pippolo_append(*string, root->label);
			pippolo_append(*string, ">");
		}
	}
	return result;
}
Esempio n. 8
0
void tims_cb_write(void *arg)
{
	ClientSession_T *session = (ClientSession_T *)arg;
	int state = session->state;

	TRACE(TRACE_DEBUG, "[%p] state: [%d]", session, state);

	switch(state) {
		case CLIENTSTATE_QUIT_QUEUED:
		case CLIENTSTATE_QUIT:
			break;
		default:
			if (p_string_len(session->ci->write_buffer) > session->ci->write_buffer_offset) {
				ci_write(session->ci,NULL);
				break;
			}
			session->handle_input(session);
			break;
	}
}
Esempio n. 9
0
File: pop3.c Progetto: skeyby/dbmail
static void pop3_handle_input(void *arg)
{
    char buffer[MAX_LINESIZE];	/* connection buffer */
    ClientSession_T *session = (ClientSession_T *)arg;

    if (p_string_len(session->ci->write_buffer)) {
        ci_write(session->ci, NULL);
        return;
    }

    memset(buffer, 0, sizeof(buffer));
    if (ci_readln(session->ci, buffer) == 0)
        return;

    ci_cork(session->ci);
    if (pop3(session, buffer) <= 0) {
        client_session_bailout(&session);
        return;
    }
    ci_uncork(session->ci);
}
Esempio n. 10
0
int _p_xml_analyze (struct str_xml_node **root, str_token_node *node, enum enum_xml_action action) {
	struct str_xml_node *current = *root, *singleton;
	struct str_token_node *key = NULL;
	int result = pippolo_true, passed;
	size_t length;
	enum enum_xml_action next = action;
	while (node) {
		passed = pippolo_false;
		if (node->token[0] == '<') {
			if (node->length > 1) {
				if ((node->token[1] == '/') || (node->token[1] == '?')) {
					next = EXML_ACTIONS_JUMP;
					passed = pippolo_true;
				}
			} else {
				next = EXML_ACTIONS_TITLE;
				passed = pippolo_true;
			}
		} else if (node->token[0] == '/') {
			if (node->length > 1) {
				if (node->token[1] == '>') {
					if (current)
						current = current->father;
					next = EXML_ACTIONS_CVALUE;
					passed = pippolo_true;
				}
			}
		} else if (node->token[0] == '>') {
			if (next == EXML_ACTIONS_JUMP)
				if (current)
					current = current->father;
			next = EXML_ACTIONS_CVALUE;
			passed = pippolo_true;
		}
		if ((!passed) && (action != EXML_ACTIONS_JUMP)) {
			switch (next) {
				case EXML_ACTIONS_TITLE:
					if (p_xml_node_allocate(&singleton)) {
						singleton->father = current;
						length = p_string_len(node->token)+1;
						if ((singleton->label = (char *) pippolo_malloc(length))) {
							snprintf(singleton->label, length, "%s", node->token);
							if ((*root)) {
								if (current) {
									if (current->children)
										singleton->next = current->children;
									current->children = singleton;
								}
							} else
								*root = singleton;
							current = singleton;
						} else
							pippolo_kill("out of memory, I'm dying bleaaargh");
					} else
						pippolo_kill("out of memory, I'm dying bleaaargh");
					next = EXML_ACTIONS_KEY;
					break;
				case EXML_ACTIONS_KEY:
					key = node;
					next = EXML_ACTIONS_KVALUE;
					break;
				case EXML_ACTIONS_KVALUE:
					if ((current) && (key)) {
						if (p_string_cmp(node->token, "=") != 0) {
							result = p_xml_key_append(&(current->keys), key->token, node->token);
							next = EXML_ACTIONS_KEY;
							key = NULL;
						}
					}
					break;
				case EXML_ACTIONS_CVALUE:
					if (current)
						pippolo_append(current->value, node->token);
				default:
					break;

			}
		}
		node = node->next;
	}
	return result;
}
Esempio n. 11
0
int tims_tokenizer(ClientSession_T *session, char *buffer)
{
	int command_type = 0;
	char *command, *value = NULL;

	if (! session->command_type) {

		command = buffer;

		strip_crlf(command);
		g_strstrip(command);
		if (! strlen(command)) return FALSE; /* ignore empty commands */

		value = strstr(command, " ");	/* look for the separator */

		if (value != NULL) {
			*value++ = '\0';	/* set a \0 on the command end and skip space */
			if (strlen(value) == 0)
				value = NULL;	/* no value specified */
		}

		for (command_type = TIMS_LOUT; command_type < TIMS_END; command_type++)
			if (strcasecmp(command, commands[command_type]) == 0)
				break;

		/* commands that are allowed to have no arguments */
		if ((value == NULL) && !(command_type <= TIMS_LIST) && (command_type < TIMS_END))
			return tims_error(session, "NO \"This command requires an argument.\"\r\n");

		TRACE (TRACE_DEBUG, "command [%s] value [%s]\n", command, value);
		session->command_type = command_type;
	}

	if (session->ci->rbuff_size) {
		size_t l = strlen(buffer);
		size_t n = min(session->ci->rbuff_size, l);
		p_string_append_len(session->rbuff, buffer, n);
		session->ci->rbuff_size -= n;
		if (! session->ci->rbuff_size) {
			String_T s = p_string_new(session->pool, p_string_str(session->rbuff));
			session->args = p_list_append(session->args, s);
			p_string_printf(session->rbuff, "%s", "");
			session->parser_state = TRUE;
		}
		TRACE(TRACE_DEBUG, "state [%d], size [%" PRIu64 "]", session->parser_state, session->ci->rbuff_size);
		return session->parser_state;
	}

	if (value) {
		char *s = value;
		int i = 0;
		char p = 0, c = 0;
		gboolean inquote = FALSE;
		String_T t = p_string_new(session->pool, "");
		while ((c = s[i++])) {
			if (inquote) {
				if (c == '"' && p != '\\') {
					session->args = p_list_append(session->args, t);
					t = p_string_new(session->pool, "");
					inquote = FALSE;
				} else {
					p_string_append_len(t, &c, 1);
				}
				p = c;
				continue;
			}
			if (c == '"' && p != '\\') {
				inquote = TRUE;
				p = c;
				continue;
			}
			if (c == ' ' && p != '\\') {
				p = c;
				continue;
			}
			if (c == '{') { // a literal...
				session->ci->rbuff_size = strtoull(s+i, NULL, 10);
				return FALSE;
			}
			p_string_append_len(t, &c, 1);
			p = c;
		}
		if (p_string_len(t)) {
			session->args = p_list_append(session->args, t);
		} else {
			p_string_free(t, TRUE);
		}
	} 
	session->parser_state = TRUE;
	
	session->args = p_list_first(session->args);
	while (session->args) {
		String_T s = p_list_data(session->args);
		if (! s)
			break;
		TRACE(TRACE_DEBUG,"arg: [%s]", (char *)p_string_str(s));			
		if (! p_list_next(session->args))
			break;
		session->args = p_list_next(session->args);
	}
	TRACE(TRACE_DEBUG, "[%p] cmd [%d], state [%d] [%s]", session, session->command_type, session->parser_state, buffer);

	return session->parser_state;
}
Esempio n. 12
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;
		}
	}