reinstate cmd_user, and continue to simplify pop code.
[apps/madmutt.git] / pop.c
diff --git a/pop.c b/pop.c
index 43b8959..c78cebf 100644 (file)
--- a/pop.c
+++ b/pop.c
@@ -69,7 +69,8 @@ typedef struct {
     cmd_status cmd_capa : 2;      /* optional command CAPA */
     cmd_status cmd_stls : 2;      /* optional command STLS */
     cmd_status cmd_uidl : 2;      /* optional command UIDL */
-    cmd_status cmd_top : 2;       /* optional command TOP */
+    cmd_status cmd_top  : 2;      /* optional command TOP  */
+    cmd_status cmd_user : 2;      /* optional command USER */
     unsigned resp_codes : 1;      /* server supports extended response codes */
     unsigned expire : 1;          /* expire is greater than 0 */
     unsigned clear_cache : 1;
@@ -191,7 +192,6 @@ static void pop_logout (CONTEXT * ctx)
 /* }}} */
 /* Authentication {{{ */
 
-/* SASL authenticator */
 static pop_auth_res_t pop_auth_sasl(pop_data_t *pop_data, const char *method)
 {
     sasl_conn_t *saslconn;
@@ -296,7 +296,6 @@ static pop_auth_res_t pop_auth_sasl(pop_data_t *pop_data, const char *method)
     return POP_A_FAILURE;
 }
 
-/* APOP authenticator */
 static pop_auth_res_t pop_auth_apop(pop_data_t *pop_data, const char *method)
 {
     MD5_CTX mdContext;
@@ -330,31 +329,30 @@ static pop_auth_res_t pop_auth_apop(pop_data_t *pop_data, const char *method)
         return POP_A_SUCCESS;
       case PQ_NOT_CONNECTED:
         return POP_A_SOCKET;
-      case PFD_FUNCT_ERROR:
-      case PQ_ERR:
       default:
-        break;
+        mutt_error("%s %s", _("APOP authentication failed."), pop_data->err_msg);
+        mutt_sleep(2);
+        return POP_A_FAILURE;
     }
-
-    mutt_error("%s %s", _("APOP authentication failed."), pop_data->err_msg);
-    mutt_sleep(2);
-
-    return POP_A_FAILURE;
 }
 
-/* USER authenticator */
 static pop_auth_res_t pop_auth_user(pop_data_t *pop_data, const char *method)
 {
     char buf[LONG_STRING];
     pop_query_status ret;
 
-    mutt_message(_("Logging in..."));
+    if (pop_data->cmd_user == CMD_NOT_AVAILABLE)
+        return POP_A_UNAVAIL;
+
+    mutt_message _("Authenticating (USER)...");
     snprintf(buf, sizeof(buf), "USER %s\r\n", pop_data->conn->account.user);
     ret = pop_query(pop_data, buf, sizeof (buf));
 
-    if (ret == PQ_ERR) {
-        snprintf(pop_data->err_msg, sizeof(pop_data->err_msg),
-                 _("Command USER is not supported by server."));
+    if (pop_data->cmd_user == CMD_UNKNOWN) {
+        if (ret == PQ_OK)
+            pop_data->cmd_user = CMD_AVAILABLE;
+        if (ret == PQ_ERR)
+            pop_data->cmd_user = CMD_NOT_AVAILABLE;
     }
 
     if (ret == PQ_OK) {
@@ -369,8 +367,8 @@ static pop_auth_res_t pop_auth_user(pop_data_t *pop_data, const char *method)
       case PQ_NOT_CONNECTED:
         return POP_A_SOCKET;
       default:
-        mutt_error ("%s %s", _("Login failed."), pop_data->err_msg);
-        mutt_sleep (2);
+        mutt_error("%s %s", _("USER authentication failed."), pop_data->err_msg);
+        mutt_sleep(2);
         return POP_A_FAILURE;
     }
 }
@@ -390,8 +388,8 @@ static pop_query_status pop_authenticate (pop_data_t * pop_data)
     };
 
     ACCOUNT *act = &pop_data->conn->account;
-    int attempts = 0, ret = POP_A_UNAVAIL;
     const pop_auth_t *auth;
+    int attempts = 0;
 
     if (mutt_account_getuser(act) || !act->user[0]
     ||  mutt_account_getpass(act) || !act->pass[0])
@@ -416,52 +414,37 @@ static pop_query_status pop_authenticate (pop_data_t * pop_data)
                 if (auth->method && ascii_strcasecmp(auth->method, buf))
                     continue;
 
-                ret = auth->do_auth(pop_data, buf);
-                if (ret == POP_A_SOCKET) {
-                    if (pop_connect(pop_data) == PQ_OK) {
-                        ret = auth->do_auth(pop_data, buf);
-                    } else {
-                        ret = POP_A_FAILURE;
-                    }
-                }
-
-                if (ret != POP_A_UNAVAIL)
+                switch (auth->do_auth(pop_data, buf)) {
+                  case POP_A_SUCCESS:
+                    return PQ_OK;
+                  case POP_A_SOCKET:
+                    return PQ_NOT_CONNECTED;
+                  case POP_A_UNAVAIL:
+                    break;
+                  case POP_A_FAILURE:
                     attempts++;
-                if (ret == POP_A_SUCCESS || ret == POP_A_SOCKET) {
-                    goto ok;
+                    break;
                 }
             }
         }
     } else {
-        /* Fall back to default: any authenticator */
         for (auth = pop_authenticators; auth->do_auth; auth++) {
-            ret = auth->do_auth(pop_data, auth->method);
-            if (ret == POP_A_SOCKET) {
-                if (pop_connect(pop_data) == PQ_OK) {
-                    ret = auth->do_auth(pop_data, auth->method);
-                } else {
-                    ret = POP_A_FAILURE;
-                }
-            }
-
-            if (ret != POP_A_UNAVAIL)
+            switch (auth->do_auth(pop_data, auth->method)) {
+              case POP_A_SUCCESS:
+                return PQ_OK;
+              case POP_A_SOCKET:
+                return PQ_NOT_CONNECTED;
+              case POP_A_UNAVAIL:
+                break;
+              case POP_A_FAILURE:
                 attempts++;
-            if (ret == POP_A_SUCCESS || ret == POP_A_SOCKET)
                 break;
+            }
         }
     }
 
-  ok:
-    switch (ret) {
-      case POP_A_SUCCESS:
-        return PQ_OK;
-      case POP_A_SOCKET:
-        return PQ_NOT_CONNECTED;
-      case POP_A_UNAVAIL:
-        if (!attempts)
-            mutt_error(_("No authenticators available"));
-    }
-
+    if (!attempts)
+        mutt_error(_("No authenticators available"));
     return PQ_ERR;
 }