]> granicus.if.org Git - curl/commitdiff
pop3: Added support for additional pop3 commands
authorSteve Holme <steve_holme@hotmail.com>
Sat, 31 Mar 2012 17:46:22 +0000 (18:46 +0100)
committerSteve Holme <steve_holme@hotmail.com>
Sat, 31 Mar 2012 17:46:22 +0000 (18:46 +0100)
This feature allows the user to specify and use additional POP3
commands such as UIDL and DELE via libcurl's CURLOPT_CUSTOMREQUEST or
curl's -X command line option.

lib/pop3.c
lib/pop3.h

index 25d22bd35137480216672c271bd7512c07720e04..44db3a474ddc95fd3e1c022d669d3d01702bfb1a 100644 (file)
@@ -89,6 +89,7 @@
 
 /* Local API functions */
 static CURLcode pop3_parse_url_path(struct connectdata *conn);
+static CURLcode pop3_parse_custom_request(struct connectdata *conn);
 static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
 static CURLcode pop3_do(struct connectdata *conn, bool *done);
 static CURLcode pop3_done(struct connectdata *conn,
@@ -502,10 +503,14 @@ static CURLcode pop3_list(struct connectdata *conn)
     struct FTP *pop3 = conn->data->state.proto.pop3;
     pop3->transfer = FTPTRANSFER_INFO;
 
-    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "LIST %s", pop3c->mailbox);
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
+                           (pop3c->custom && pop3c->custom[0] != '\0' ?
+                            pop3c->custom : "LIST"), pop3c->mailbox);
   }
   else
-    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "LIST");
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp,
+                           (pop3c->custom && pop3c->custom[0] != '\0' ?
+                            pop3c->custom : "LIST"));
 
   if(result)
     return result;
@@ -521,7 +526,9 @@ static CURLcode pop3_retr(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
 
-  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "RETR %s", pop3c->mailbox);
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
+                         (pop3c->custom && pop3c->custom[0] != '\0' ?
+                          pop3c->custom : "RETR"), pop3c->mailbox);
   if(result)
     return result;
 
@@ -730,7 +737,9 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
     result = status;         /* use the already set error code */
   }
 
+  /* Clear our variables for the next connection */
   Curl_safefree(pop3c->mailbox);
+  Curl_safefree(pop3c->custom);
 
   /* Clear the transfer mode for the next connection */
   pop3->transfer = FTPTRANSFER_BODY;
@@ -817,10 +826,16 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done)
   if(retcode)
     return retcode;
 
+  /* Parse the URL path */
   retcode = pop3_parse_url_path(conn);
   if(retcode)
     return retcode;
 
+  /* Parse the custom request */
+  retcode = pop3_parse_custom_request(conn);
+  if(retcode)
+    return retcode;
+
   retcode = pop3_regular_transfer(conn, done);
 
   return retcode;
@@ -890,15 +905,30 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
   struct SessionHandle *data = conn->data;
   const char *path = data->state.path;
 
-  /* url decode the path and use this mailbox */
+  /* URL decode the path and use this mailbox */
   return Curl_urldecode(data, path, 0, &pop3c->mailbox, NULL, TRUE);
 }
 
+static CURLcode pop3_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct SessionHandle *data = conn->data;
+  const char *custom = conn->data->set.str[STRING_CUSTOMREQUEST];
+
+  /* URL decode the custom request */
+  if(custom)
+    result = Curl_urldecode(data, custom, 0, &pop3c->custom, NULL, TRUE);
+
+  return result;
+}
+
 /* call this when the DO phase has completed */
 static CURLcode pop3_dophase_done(struct connectdata *conn,
                                   bool connected)
 {
   struct FTP *pop3 = conn->data->state.proto.pop3;
+
   (void)connected;
 
   if(pop3->transfer != FTPTRANSFER_BODY)
@@ -983,6 +1013,7 @@ static CURLcode pop3_setup_connection(struct connectdata * conn)
       return CURLE_UNSUPPORTED_PROTOCOL;
 #endif
     }
+
     /*
      * We explicitly mark this connection as persistent here as we're doing
      * POP3 over HTTP and thus we accidentally avoid setting this value
index 59c0839c6e3add1bd7348d42b784e7cbd4581e7c..3071a6eb8ace22b6e2fc7b50e56a77cbca4c1187 100644 (file)
@@ -42,7 +42,8 @@ typedef enum {
    struct */
 struct pop3_conn {
   struct pingpong pp;
-  char *mailbox;     /* what to RETR */
+  char *mailbox;     /* message id */
+  char *custom;      /* custom request */
   size_t eob;        /* number of bytes of the EOB (End Of Body) that has been
                         received thus far */
   size_t strip;      /* number of bytes from the start to ignore as non-body */