changeset 1059:d805c2f1d6a9 HEAD

Support for CAPA command (rfc2449).
author Timo Sirainen <tss@iki.fi>
date Thu, 30 Jan 2003 21:52:39 +0200
parents 3b8fb7bf7ecc
children d051d031fc09
files src/pop3-login/client-authenticate.c src/pop3-login/client-authenticate.h src/pop3-login/client.c src/pop3/Makefile.am src/pop3/capability.h src/pop3/client.c src/pop3/commands.c
diffstat 7 files changed, 62 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/pop3-login/client-authenticate.c	Thu Jan 30 21:01:40 2003 +0200
+++ b/src/pop3-login/client-authenticate.c	Thu Jan 30 21:52:39 2003 +0200
@@ -10,10 +10,43 @@
 #include "str.h"
 #include "auth-connection.h"
 #include "../auth/auth-mech-desc.h"
+#include "../pop3/capability.h"
 #include "client.h"
 #include "client-authenticate.h"
 #include "master.h"
 
+static enum auth_mech auth_mechs = 0;
+static char *auth_mechs_capability = NULL;
+
+int cmd_capa(struct pop3_client *client, const char *args __attr_unused__)
+{
+	string_t *str;
+	int i;
+
+	if (auth_mechs != available_auth_mechs) {
+		auth_mechs = available_auth_mechs;
+		i_free(auth_mechs_capability);
+
+		str = t_str_new(128);
+
+		str_append(str, "SASL");
+		for (i = 0; i < AUTH_MECH_COUNT; i++) {
+			if ((auth_mechs & auth_mech_desc[i].mech) &&
+			    auth_mech_desc[i].name != NULL) {
+				str_append_c(str, ' ');
+				str_append(str, auth_mech_desc[i].name);
+			}
+		}
+
+		auth_mechs_capability = i_strdup(str_c(str));
+	}
+
+	client_send_line(client, t_strconcat("+OK\r\n" POP3_CAPABILITY_REPLY,
+					     auth_mechs_capability,
+					     "\r\n.", NULL));
+	return TRUE;
+}
+
 static struct auth_mech_desc *auth_mech_find(const char *name)
 {
 	int i;
--- a/src/pop3-login/client-authenticate.h	Thu Jan 30 21:01:40 2003 +0200
+++ b/src/pop3-login/client-authenticate.h	Thu Jan 30 21:52:39 2003 +0200
@@ -1,6 +1,7 @@
 #ifndef __CLIENT_AUTHENTICATE_H
 #define __CLIENT_AUTHENTICATE_H
 
+int cmd_capa(struct pop3_client *client, const char *args);
 int cmd_user(struct pop3_client *client, const char *args);
 int cmd_pass(struct pop3_client *client, const char *args);
 int cmd_auth(struct pop3_client *client, const char *args);
--- a/src/pop3-login/client.c	Thu Jan 30 21:01:40 2003 +0200
+++ b/src/pop3-login/client.c	Thu Jan 30 21:52:39 2003 +0200
@@ -104,6 +104,8 @@
 				  const char *args)
 {
 	cmd = str_ucase(t_strdup_noconst(cmd));
+	if (strcmp(cmd, "CAPA") == 0)
+		return cmd_capa(client, args);
 	if (strcmp(cmd, "USER") == 0)
 		return cmd_user(client, args);
 	if (strcmp(cmd, "PASS") == 0)
--- a/src/pop3/Makefile.am	Thu Jan 30 21:01:40 2003 +0200
+++ b/src/pop3/Makefile.am	Thu Jan 30 21:52:39 2003 +0200
@@ -30,6 +30,7 @@
 	main.c
 
 noinst_HEADERS = \
+	capability.h \
 	client.h \
 	commands.h \
 	common.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pop3/capability.h	Thu Jan 30 21:52:39 2003 +0200
@@ -0,0 +1,13 @@
+#ifndef __POP3_CAPABILITY_H
+#define __POP3_CAPABILITY_H
+
+#define POP3_CAPABILITY_REPLY \
+	"CAPA\r\n" \
+	"TOP\r\n" \
+	"USER\r\n" \
+	"UIDL\r\n" \
+	"RESP-CODES\r\n"
+
+/* + SASL */
+
+#endif
--- a/src/pop3/client.c	Thu Jan 30 21:01:40 2003 +0200
+++ b/src/pop3/client.c	Thu Jan 30 21:52:39 2003 +0200
@@ -99,7 +99,7 @@
 		}
 	}
 
-	client_send_line(client, "-ERR Couldn't sync mailbox.");
+	client_send_line(client, "-ERR [IN-USE] Couldn't sync mailbox.");
 	return FALSE;
 }
 
--- a/src/pop3/commands.c	Thu Jan 30 21:01:40 2003 +0200
+++ b/src/pop3/commands.c	Thu Jan 30 21:52:39 2003 +0200
@@ -6,6 +6,7 @@
 #include "str.h"
 #include "message-size.h"
 #include "mail-storage.h"
+#include "capability.h"
 #include "commands.h"
 
 #define MSGS_BITMASK_SIZE(client) \
@@ -84,6 +85,12 @@
 	return args;
 }
 
+static int cmd_capa(struct client *client, const char *args __attr_unused__)
+{
+	client_send_line(client, "+OK\r\n"POP3_CAPABILITY_REPLY".");
+	return TRUE;
+}
+
 static int cmd_dele(struct client *client, const char *args)
 {
 	unsigned int msgnum;
@@ -401,6 +408,10 @@
 	while (*args == ' ') args++;
 
 	switch (*name) {
+	case 'C':
+		if (strcmp(name, "CAPA") == 0)
+			return cmd_capa(client, args);
+		break;
 	case 'D':
 		if (strcmp(name, "DELE") == 0)
 			return cmd_dele(client, args);