Esempio n. 1
0
/* Wait for append response. */
int
deliver_imap_waitappend(struct account *a, struct fetch_ctx *fctx,
    struct io *io, char **line)
{
	struct fetch_imap_data	*data = a->data;
	int			 tag;

	for (;;) {
		if (deliver_imap_poll(a, io) != 0) {
			line = NULL;
			return (IMAP_TAG_ERROR);
		}
		if (data->getln(a, fctx, line) != 0) {
			line = NULL;
			return (IMAP_TAG_ERROR);
		}
		if (*line == NULL)
			continue;

		tag = imap_tag(*line);
		if (tag != IMAP_TAG_NONE)
			break;
	}

	if (tag == IMAP_TAG_CONTINUE)
		return (IMAP_TAG_CONTINUE);
	if (tag != data->tag)
		return (IMAP_TAG_ERROR);
	return (tag);
}
Esempio n. 2
0
/* GMail extensions body state. */
int
imap_state_gmext_body(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	struct mail		*m = fctx->mail;
	char			*line, *lb;
	int     	         tag;
	u_int			 n;
	uint64_t		 thrid, msgid;
	size_t			 lblen;

	for (;;) {
		if (imap_getln(a, fctx, IMAP_RAW, &line) != 0)
			return (FETCH_ERROR);
		if (line == NULL)
			return (FETCH_BLOCK);
		tag = imap_tag(line);
		if (tag == IMAP_TAG_NONE)
			break;
		if (tag == data->tag) {
			fctx->state = imap_state_next;
			return (FETCH_MAIL);
		}
		return (FETCH_ERROR);
	}

	if (sscanf(line, "* %u FETCH (X-GM-THRID %llu X-GM-MSGID %llu ", &n,
	    &thrid, &msgid) != 3)
		return (imap_invalid(a, line));
	if ((lb = strstr(line, "X-GM-LABELS")) == NULL)
		return (imap_invalid(a, line));
	if ((lb = strchr(lb, '(')) == NULL)
		return (imap_invalid(a, line));
	lb++; /* drop '(' */
	lblen = strlen(lb);
	if (lblen < 2 || lb[lblen - 1] != ')' || lb[lblen - 2] != ')')
		return (imap_invalid(a, line));
	lblen -= 2; /* drop '))' from the end */

	add_tag(&m->tags, "gmail_msgid", "%llu", msgid);
	add_tag(&m->tags, "gmail_thrid", "%llu", thrid);
	add_tag(&m->tags, "gmail_labels", "%.*s", (int)lblen, lb);

	fctx->state = imap_state_gmext_done;
	return (FETCH_AGAIN);
}
Esempio n. 3
0
/* User state. */
int
imap_state_user(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line;
	int                      tag;

	if (data->capa & IMAP_CAPA_NOSPACE) {
		if (imap_getln(a, fctx, IMAP_CONTINUE, &line) != 0)
			return (FETCH_ERROR);
		if (line == NULL)
			return (FETCH_BLOCK);
	} else {
		for (;;) {
			if (imap_getln(a, fctx, IMAP_RAW, &line) != 0)
				return (FETCH_ERROR);
			if (line == NULL)
				return (FETCH_BLOCK);
			tag = imap_tag(line);
			if (tag == IMAP_TAG_NONE)
				continue;
			if (tag == IMAP_TAG_CONTINUE || tag == data->tag)
				break;
			return (FETCH_ERROR);
		}
		if (tag != IMAP_TAG_CONTINUE) {
			log_debug("%s: didn't accept user (%s); "
			    "trying without space", a->name, line);
			data->capa |= IMAP_CAPA_NOSPACE;
			return (imap_pick_auth(a, fctx));
		}
	}

	if (imap_putln(a, "%s", data->pass) != 0)
		return (FETCH_ERROR);
	fctx->state = imap_state_pass;
	return (FETCH_BLOCK);
}
Esempio n. 4
0
/*
 * Parse line based on type. Returns -1 on error, 0 on success, 1 to ignore
 * this line.
 */
int
imap_parse(struct account *a, int type, char *line)
{
	struct fetch_imap_data	*data = a->data;
	int			 tag;

	if (type == IMAP_RAW)
		return (0);

	tag = imap_tag(line);
	switch (type) {
	case IMAP_TAGGED:
		if (tag == IMAP_TAG_NONE)
			return (1);
		if (tag == IMAP_TAG_CONTINUE)
			goto invalid;
		if (tag != data->tag)
			goto invalid;
		break;
	case IMAP_UNTAGGED:
		if (tag != IMAP_TAG_NONE)
			goto invalid;
		break;
	case IMAP_CONTINUE:
		if (tag == IMAP_TAG_NONE)
			return (1);
		if (tag != IMAP_TAG_CONTINUE)
			goto invalid;
		break;
	}

	return (0);

invalid:
	imap_bad(a, line);
	return (-1);
}