Beispiel #1
0
/*
 * Add, remove or replace the specified flags of the messages.
 */
int
request_store(const char *server, const char *port, const char *user,
    const char *mesg, const char *mode, const char *flags)
{
	int t, r;
	session *s;

	if (!(s = session_find(server, port, user)))
		return -1;

	t = imap_store(s, mesg, mode, flags);
	if ((r = response_generic(s, t)) == -1)
		goto fail;

	if (xstrcasestr(flags, "\\Deleted") && get_option_boolean("expunge"))
		if (response_generic(s, imap_expunge(s)) == -1)
			goto fail;

	return r;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #2
0
/*
 * Process the data that server sent due to IMAP STATUS client request.
 */
int
response_status(session *ssn, int tag, unsigned int *exist,
    unsigned int *recent, unsigned int *unseen)
{
	int r;
	char *s;
	regexp *re;

	if ((r = response_generic(ssn, tag)) == -1)
		return -1;

	re = &responses[DATA_RESPONSE_STATUS];

	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) {
		s = xstrndup(ibuf.data + re->pmatch[1].rm_so,
		    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		re = &responses[DATA_RESPONSE_STATUS_MESSAGES];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*exist = strtol(s + re->pmatch[1].rm_so, NULL, 10);

		re = &responses[DATA_RESPONSE_STATUS_RECENT];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*recent = strtol(s + re->pmatch[1].rm_so, NULL, 10);

		re = &responses[DATA_RESPONSE_STATUS_UNSEEN];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*unseen = strtol(s + re->pmatch[1].rm_so, NULL, 10);

		xfree(s);
	}

	return r;
}
Beispiel #3
0
/*
 * Copy the specified messages to another mailbox.
 */
int
request_copy(const char *server, const char *port, const char *user,
    const char *mesg, const char *mbox)
{
	int t, r;
	session *s;
	const char *m;

	if (!(s = session_find(server, port, user)))
		return -1;

	m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);

	do {
		t = imap_copy(s, mesg, m);
		switch (r = response_generic(s, t)) {
		case STATUS_RESPONSE_TRYCREATE:
			if (create_mailbox(s, mbox) == -1)
				goto fail;
			break;
		case -1:
			goto fail;
			break;
		}
	} while (r == STATUS_RESPONSE_TRYCREATE);

	return r;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #4
0
/*
 * Process the data that server sent due to IMAP FETCH RFC822.SIZE client
 * request.
 */
int
response_fetchsize(session *ssn, int tag, char **size)
{
	int r;
	char *s;
	regexp *re;

	if ((r = response_generic(ssn, tag)) == -1)
		return -1;

	re = &responses[DATA_RESPONSE_FETCH];
	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) { 
		s = xstrndup(ibuf.data + re->pmatch[1].rm_so,
		    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		re = &responses[DATA_RESPONSE_FETCH_SIZE];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*size = xstrndup(s + re->pmatch[1].rm_so,
			    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		xfree(s);
	}

	return r;
}
Beispiel #5
0
/*
 * Process the data that server sent due to IMAP NAMESPACE client request.
 */
int
response_namespace(session *ssn, int tag)
{
	int r, n;
	regexp *re;

	r = response_generic(ssn, tag);
	if (r == -1 || r == STATUS_BYE)
		return r;

	ssn->ns.prefix = NULL;
	ssn->ns.delim = '\0';

	re = &responses[RESPONSE_NAMESPACE];

	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) {
		n = re->pmatch[2].rm_eo - re->pmatch[2].rm_so;
		if (n > 0)
			ssn->ns.prefix = xstrndup(ibuf.data +
			    re->pmatch[2].rm_so, n);
		ssn->ns.delim = *(ibuf.data + re->pmatch[3].rm_so);
	}
	debug("namespace (%d): '%s' '%c'\n", ssn->socket,
	    (ssn->ns.prefix ? ssn->ns.prefix : ""), ssn->ns.delim);

	return r;
}
Beispiel #6
0
/*
 * Rename a mailbox.
 */
int
request_rename(const char *server, const char *port, const char *user,
    const char *oldmbox, const char *newmbox)
{
	int r;
	session *s;
	char *o, *n;

	if (!(s = session_find(server, port, user)))
		return -1;

	o = xstrdup(apply_namespace(oldmbox, s->ns.prefix, s->ns.delim));
	n = xstrdup(apply_namespace(newmbox, s->ns.prefix, s->ns.delim));

	r = response_generic(s, imap_rename(s, o, n));

	xfree(o);
	xfree(n);

	if (r == -1)
		goto fail;

	return r;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #7
0
/*
 * Process the data that server sent due to IMAP FETCH BODYSTRUCTURE client
 * request.
 */
int
response_fetchstructure(session *ssn, int tag, char **structure)
{
	int r;
	char *s;
	regexp *re;

	r = response_generic(ssn, tag);
	if (r == -1 || r == STATUS_BYE)
		return r;

	re = &responses[RESPONSE_FETCH];
	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) { 
		s = xstrndup(ibuf.data + re->pmatch[1].rm_so,
		    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		re = &responses[RESPONSE_FETCH_STRUCTURE];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0)) {
			*structure = xstrndup(s + re->pmatch[1].rm_so,
			    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);
		}
		xfree(s);
	}

	return r;
}
Beispiel #8
0
/*
 * Auxiliary function to create a mailbox.
 */
int
create_mailbox(session *ssn, const char *mbox)
{
	int r;
	const char *m;

	m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim);

	if ((r = response_generic(ssn, imap_create(ssn, m))) == -1)
		return -1;

	if (get_option_boolean("subscribe"))
		if (response_generic(ssn, imap_subscribe(ssn, m)) == -1)
			return -1;

	return r;
}
Beispiel #9
0
/*
 * Add, remove or replace the specified flags of the messages.
 */
int
request_store(session *ssn, const char *mesg, const char *mode, const char
    *flags)
{
	int t, r;

	TRY(t = send_request(ssn, "UID STORE %s %sFLAGS.SILENT (%s)", mesg, 
	    (!strncasecmp(mode, "add", 3) ? "+" :
	    !strncasecmp(mode, "remove", 6) ? "-" : ""), flags));
	TRY(r = response_generic(ssn, t));

	if (xstrcasestr(flags, "\\Deleted") && get_option_boolean("expunge")) {
		TRY(t = send_request(ssn, "EXPUNGE"));
		TRY(response_generic(ssn, t));
	}

	return r;
}
Beispiel #10
0
/*
 * Reset any inactivity autologout timer on the server.
 */
int
request_noop(session *ssn)
{
	int t, r;

	TRY(t = send_request(ssn, "NOOP"));
	TRY(r = response_generic(ssn, t));

	return r;
}
Beispiel #11
0
/*
 * Remove all messages marked for deletion from selected mailbox.
 */
int
request_expunge(session *ssn)
{
	int t, r;

	TRY(t = send_request(ssn, "EXPUNGE"));
	TRY(r = response_generic(ssn, t));

	return r;
}
Beispiel #12
0
/*
 * Logout from the IMAP server and disconnect from the server.
 */
int
request_logout(session *ssn)
{

	if (response_generic(ssn, send_request(ssn, "LOGOUT")) == -1) {
		session_destroy(ssn);
	} else {
		close_connection(ssn);
		session_destroy(ssn);
	}
	return STATUS_OK;
}
Beispiel #13
0
/*
 * Process the data that server sent due to IMAP SELECT client request.
 */
int
response_select(session *ssn, int tag)
{
	int r;

	if ((r = response_generic(ssn, tag)) == -1)
		return -1;

	if (xstrcasestr(ibuf.data, "[READ-ONLY]"))
		return STATUS_RESPONSE_READONLY;

	return r;
}
Beispiel #14
0
/*
 * Unsubscribe the specified mailbox.
 */
int
request_unsubscribe(session *ssn, const char *mbox)
{
	int t, r;
	const char *m;

	m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim);

	TRY(t = send_request(ssn, "UNSUBSCRIBE \"%s\"", m));
	TRY(r = response_generic(ssn, t));

	return r;
}
Beispiel #15
0
/*
 * Delete the specified mailbox.
 */
int
request_delete(session *ssn, const char *mbox)
{
	int t, r;
	const char *m;

	m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim);

	TRY(t = send_request(ssn, "DELETE \"%s\"", m));
	TRY(r = response_generic(ssn, t));

	return r;
}
Beispiel #16
0
/*
 * Append supplied message to the specified mailbox.
 */
int
request_append(session *ssn, const char *mbox, const char *mesg, size_t
    mesglen, const char *flags, const char *date)
{
	int t, r;
	const char *m;

	m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim);

	TRY(t = send_request(ssn, "APPEND \"%s\"%s%s%s%s%s%s {%d}", m,
	    (flags ? " (" : ""), (flags ? flags : ""),
	    (flags ? ")" : ""), (date ? " \"" : ""),
	    (date ? date : ""), (date ? "\"" : ""), mesglen));
	TRY(r = response_continuation(ssn, t));
	if (r == STATUS_CONTINUE) {
		TRY(send_continuation(ssn, mesg, mesglen)); 
		TRY(r = response_generic(ssn, t));
	}

	if (r == STATUS_TRYCREATE) {
		TRY(t = send_request(ssn, "CREATE \"%s\"", m));
		TRY(response_generic(ssn, t));
		if (get_option_boolean("subscribe")) {
			TRY(t = send_request(ssn, "SUBSCRIBE \"%s\"", m));
			TRY(response_generic(ssn, t));
		}
		TRY(t = send_request(ssn, "APPEND \"%s\"%s%s%s%s%s%s {%d}", m,
		    (flags ? " (" : ""), (flags ? flags : ""),
		    (flags ? ")" : ""), (date ? " \"" : ""),
		    (date ? date : ""), (date ? "\"" : ""), mesglen));
		TRY(r = response_continuation(ssn, t));
		if (r == STATUS_CONTINUE) {
			TRY(send_continuation(ssn, mesg, mesglen)); 
			TRY(r = response_generic(ssn, t));
		}
	}

	return r;
}
Beispiel #17
0
/*
 * Copy the specified messages to another mailbox.
 */
int
request_copy(session *ssn, const char *mesg, const char *mbox)
{
	int t, r;
	const char *m;

	m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim);

	TRY(t = send_request(ssn, "UID COPY %s \"%s\"", mesg, m));
	TRY(r = response_generic(ssn, t));
	if (r == STATUS_TRYCREATE) {
		TRY(t = send_request(ssn, "CREATE \"%s\"", m));
		TRY(response_generic(ssn, t));
		if (get_option_boolean("subscribe")) {
			TRY(t = send_request(ssn, "SUBSCRIBE \"%s\"", m));
			TRY(response_generic(ssn, t));
		}
		TRY(t = send_request(ssn, "UID COPY %s \"%s\"", mesg, m));
		TRY(r = response_generic(ssn, t));
	}

	return r;
}
Beispiel #18
0
/*
 * Process the data that server sent due to IMAP SELECT client request.
 */
int
response_select(session *ssn, int tag)
{
	int r;

	r = response_generic(ssn, tag);
	if (r == -1 || r == STATUS_BYE)
		return r;

	if (xstrcasestr(ibuf.data, "[READ-ONLY]"))
		return STATUS_READONLY;

	return r;
}
Beispiel #19
0
/*
 * Rename a mailbox.
 */
int
request_rename(session *ssn, const char *oldmbox, const char *newmbox)
{
	int t, r;
	char *o, *n;

	o = xstrdup(apply_namespace(oldmbox, ssn->ns.prefix, ssn->ns.delim));
	n = xstrdup(apply_namespace(newmbox, ssn->ns.prefix, ssn->ns.delim));

	TRY(t = send_request(ssn, "RENAME \"%s\" \"%s\"", o, n));
	TRY(r = response_generic(ssn, t));

	return r;
}
Beispiel #20
0
/*
 * Close examined/selected mailbox.
 */
int
request_close(session *ssn)
{
	int t, r;

	TRY(t = send_request(ssn, "CLOSE"));
	TRY(r = response_generic(ssn, t));

	if (r == STATUS_OK && ssn->selected) {
		xfree(ssn->selected);
		ssn->selected = NULL;
	}

	return r;
}
Beispiel #21
0
/*
 * Process the data that server sent due to IMAP AUTHENTICATE client request.
 */
int
response_authenticate(session *ssn, int tag, unsigned char **cont)
{
	int r;
	regexp *re;

	re = &responses[DATA_RESPONSE_AUTHENTICATE];

	if ((r = response_generic(ssn, tag)) == STATUS_RESPONSE_CONTINUE &&
	    !regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0))
		*cont = (unsigned char *)xstrndup(ibuf.data + re->pmatch[1].rm_so,
		    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

	return r;
}
Beispiel #22
0
/*
 * Process the data that server sent due to IMAP CAPABILITY client request.
 */
int
response_capability(session *ssn, int tag)
{
	int r;
	char *s;
	regexp *re;

	r = response_generic(ssn, tag);
	if (r == -1 || r == STATUS_BYE)
		return r;

	ssn->protocol = PROTOCOL_NONE;

	re = &responses[RESPONSE_CAPABILITY];

	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) {
		s = xstrndup(ibuf.data + re->pmatch[1].rm_so,
		    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		if (xstrcasestr(s, "IMAP4rev1"))
			ssn->protocol = PROTOCOL_IMAP4REV1;
		else if (xstrcasestr(s, "IMAP4"))
			ssn->protocol = PROTOCOL_IMAP4;
		else {
			error("server supports neither the IMAP4rev1 nor the "
			    "IMAP4 protocol\n");
			return -1;
		}

		ssn->capabilities = CAPABILITY_NONE;

		if (xstrcasestr(s, "NAMESPACE"))
			ssn->capabilities |= CAPABILITY_NAMESPACE;
		if (xstrcasestr(s, "AUTH=CRAM-MD5"))
			ssn->capabilities |= CAPABILITY_CRAMMD5;
		if (xstrcasestr(s, "STARTTLS"))
			ssn->capabilities |= CAPABILITY_STARTTLS;
		if (xstrcasestr(s, "CHILDREN"))
			ssn->capabilities |= CAPABILITY_CHILDREN;

		if (xstrcasestr(s, "IDLE"))
			ssn->capabilities |= CAPABILITY_IDLE;

		xfree(s);
	}

	return r;
}
Beispiel #23
0
/*
 * Logout from the IMAP server and disconnect from the server.
 */
int
request_logout(const char *server, const char *port, const char *user)
{
	int r;
	session *s;

	if (!(s = session_find(server, port, user)))
		return -1;

	r = response_generic(s, imap_logout(s));

	close_connection(s);
	session_destroy(s);

	return r;
}
Beispiel #24
0
/*
 * Append supplied message to the specified mailbox.
 */
int
request_append(const char *server, const char *port, const char *user,
    const char *mbox, const char *mesg, size_t mesglen, const char *flags,
    const char *date)
{
	int t, r;
	session *s;
	const char *m;

	if (!(s = session_find(server, port, user)))
		return -1;

	m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);

	do {
		if ((t = imap_append(s, m, flags, date, mesglen)) == -1)
			goto fail;
		if ((r = response_continuation(s)) == -1)
			goto fail;

		switch (r) {
		case STATUS_RESPONSE_CONTINUE:
			if (imap_continuation(s, mesg, mesglen) == -1)
				goto fail;
			if ((r = response_generic(s, t)) == -1)
				goto fail;
			break;
		case STATUS_RESPONSE_TRYCREATE:
			if (create_mailbox(s, mbox) == -1)
				goto fail;
			break;
		case -1:
			goto fail;
			break;
		}
	} while (r == STATUS_RESPONSE_TRYCREATE);

	return r;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #25
0
/*
 * Remove all messages marked for deletion from selected mailbox.
 */
int
request_expunge(const char *server, const char *port, const char *user)
{
	int r;
	session *s;

	if (!(s = session_find(server, port, user)))
		return -1;

	if ((r = response_generic(s, imap_expunge(s))) == -1)
		goto fail;

	return r;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #26
0
/*
 * Process the data that server sent due to IMAP EXAMINE client request.
 */
int
response_examine(session *ssn, int tag, unsigned int *exist,
    unsigned int *recent)
{
	int r;
	regexp *re;

	if ((r = response_generic(ssn, tag)) == -1)
		return -1;

	re = &responses[DATA_RESPONSE_EXAMINE_EXISTS];
	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0))
		*exist = strtol(ibuf.data + re->pmatch[1].rm_so, NULL, 10);

	re = &responses[DATA_RESPONSE_EXAMINE_RECENT];
	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0))
		*recent = strtol(ibuf.data + re->pmatch[1].rm_so, NULL, 10);

	return r;
}
Beispiel #27
0
int
request_idle(session *ssn, char **event)
{
	int t, r, ri;

	if (!(ssn->capabilities & CAPABILITY_IDLE))
		return STATUS_BAD;

	do {
		ri = 0;

		TRY(t = send_request(ssn, "IDLE"));
		TRY(r = response_continuation(ssn, t));
		if (r == STATUS_CONTINUE) {
			TRY(ri = response_idle(ssn, t, event));
			TRY(send_continuation(ssn, "DONE", strlen("DONE")));
			TRY(r = response_generic(ssn, t));
		}
	} while (ri == STATUS_TIMEOUT);

	return r;
}
Beispiel #28
0
int
request_idle(const char *server, const char *port, const char *user)
{
	int t, rg, ri;
	session *s;

	if (!(s = session_find(server, port, user)))
		return -1;


	if (!(s->capabilities & CAPABILITY_IDLE))
		return -1;

	do {
		ri = 0;

		t = imap_idle(s);

		if ((rg = response_continuation(s)) == -1)
			goto fail;

		if (rg == STATUS_RESPONSE_CONTINUE) {
			if ((ri = response_idle(s, t)) == -1)
				goto fail;

			imap_done(s);

			if ((rg = response_generic(s, t)) == -1)
				goto fail;
		}
	} while (ri == STATUS_RESPONSE_TIMEOUT);

	return rg;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #29
0
/*
 * Unsubscribe the specified mailbox.
 */
int
request_unsubscribe(const char *server, const char *port, const char *user,
    const char *mbox)
{
	int r;
	session *s;
	const char *m;

	if (!(s = session_find(server, port, user)))
		return -1;

	m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);

	if ((r = response_generic(s, imap_unsubscribe(s, m))) == -1)
		goto fail;

	return r;
fail:
	close_connection(s);
	session_destroy(s);

	return -1;
}
Beispiel #30
0
/*
 * Process the data that server sent due to IMAP FETCH FAST client request.
 */
int
response_fetchfast(session *ssn, int tag, char **flags, char **date,
    char **size)
{
	int r;
	char *s;
	regexp *re;

	r = response_generic(ssn, tag);
	if (r == -1 || r == STATUS_BYE)
		return r;

	re = &responses[RESPONSE_FETCH];
	if (!regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)) { 
		s = xstrndup(ibuf.data + re->pmatch[1].rm_so,
		    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		re = &responses[RESPONSE_FETCH_FLAGS];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*flags = xstrndup(s + re->pmatch[1].rm_so,
			    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		re = &responses[RESPONSE_FETCH_DATE];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*date = xstrndup(s + re->pmatch[1].rm_so,
			    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		re = &responses[RESPONSE_FETCH_SIZE];
		if (!regexec(re->preg, s, re->nmatch, re->pmatch, 0))
			*size = xstrndup(s + re->pmatch[1].rm_so,
			    re->pmatch[1].rm_eo - re->pmatch[1].rm_so);

		xfree(s);
	}

	return r;
}