]> Pileus Git - ~andy/fetchmail/commitdiff
Merge 'next' branch up to tag 'before-cpp'
authorMatthias Andree <matthias.andree@gmx.de>
Tue, 17 May 2011 21:02:54 +0000 (23:02 +0200)
committerMatthias Andree <matthias.andree@gmx.de>
Tue, 17 May 2011 21:02:54 +0000 (23:02 +0200)
Conflicts:
.gitignore
configure.ac
driver.c
fetchmail.h
imap.c
kerberos.c
socket.c
transact.c

16 files changed:
1  2 
.gitignore
Makefile.am
NEWS
configure.ac
driver.c
fetchmail-FAQ.html
fetchmail.h
fetchmail.man
imap.c
opie.c
options.c
sink.c
smtp.c
socket.c
socket.h
transact.c

diff --cc .gitignore
index 53f325d71059de77cd4073d3fbf5e45a98ce0841,4170b2cb8276cefb6364b473ca1e029f2280d44d..a3b2417822280daa25843f3fbc324770e18e456e
@@@ -1,14 -1,17 +1,10 @@@
--*.o
  *~
--.autotools
--.cproject
--.deps/
--.project
--.rsyncs
 -ABOUT-NLS
 -Makefile
 -Makefile.in
+ \#*#
 +ABOUT-NLS
  aclocal.m4
  autobuild/
  autom4te.cache
++.autotools
  build*
  build*/
  compile
@@@ -22,32 -24,21 +18,39 @@@ config.statu
  config.sub
  configure
  configure.lineno
++.cproject
  cscope.out
  depcomp
++.deps/
  dox/
 +FAQ
 +FEATURES
  fetchmail
- fetchmail-*.tar.*
+ fetchmailconf
 +fetchmail-FAQ.pdf
 +fetchmail-man.html
 +fetchmail.spec
- fetchmailconf
++fetchmail-*.tar.*
++fetchmail-*.tar.xz
  genlsm.sh
++IMAPCapa
  install-sh
  libfm.a
  m4/
 +Mailbox-Names-UTF7.html
 +Makefile
 +Makefile.in
  missing
  mkinstalldirs
 +mxget
  netrc
 +NOTES
++*.o
  po/Makefile
  po/POTFILES
++po/remove-potcdate.sed
  po/stamp-po
++.project
  py-compile
  rcfile_l.c
  rcfile_y.c
@@@ -55,10 -46,20 +58,10 @@@ rcfile_y.
  rfc2047e
  rfc822
  rfc822valid
++.rsyncs
  stamp-h1
  tags
 +TODO
  unmime
  x509_name_match
  ylwrap
- \#*#
 -FAQ
 -FEATURES
 -IMAPCapa
 -Mailbox-Names-UTF7.html
 -NOTES
 -TODO
 -config.cache
 -fetchmail-*.tar.xz
 -fetchmail-FAQ.pdf
 -fetchmail-man.html
 -fetchmail.spec
 -po/remove-potcdate.sed
diff --cc Makefile.am
Simple merge
diff --cc NEWS
index 464fd894fa69291a437ec3fdc4858162776b3d44,7a5d65b42a8bb644aab063fa891c5cd89ec0c104..5dcce315586c96b08106cc5021ce4df804f6e58a
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -51,10 -39,58 +39,60 @@@ removed from a 7.0.0 or newer release.
  * The --bsmtp - mode of operation may be removed in a future release.
  * Given that OpenSSL is severely underdocumented, and needs license exceptions,
    fetchmail may switch to a different SSL library.
 +* SSLv2 support will be removed from a future fetchmail release. It has been
 +  obsolete for more than a decade.
  
  --------------------------------------------------------------------------------
+ fetchmail-7.0.0 (not yet released):
+ NOTE THIS IS AN ALPHA RELEASE THAT HAS NOT BEEN THOROUGHLY TESTED!
+ # MAJOR CHANGES
+ * The UIDL handler code is now much faster, especially noticable with lots of
+   mail kept on a POP3 server. Where the 6.3.X code was of O(n^2) complexity,
+   we're down to O(n log n).
+   Contributed by Rainer Weikusat, MAD Partners Ltd./MSS GmbH.
+ * The POP3 code now always uses UIDL, except if "fetchall" is in effect.
+   Fixes BerliOS Bug #16172.
+ # FEATURES ADDED
+ * Fetchmail can now retrieve credentials from PWMD. This needs to be enabled at
+   compile-time and requires run-time configuration. See README.PWMD for details.
+   Contributed by Ben Kibbey, author of libpwmd and pwmd.
+ * Fetchmail now supports a retrieve-error command line or rcfile option that
+   takes exactly one argument, abort (default), continue or markseen.  This
+   specifies the policy used by fetchmail to handle messages whose bodies
+   fail to be retrieved due to server errors.  Both the continue and markseen
+   options will skip the message with errors and allow the session to
+   continue so that subsequent messages can be retrieved.  The markseen
+   option will also mark the message with errors as seen.
+   The default policy is to abort the session whenever a server error occurs.
+   Contributed by Craig Brown.
+ # REMOVED FEATURES
+ * IMAP2 protocol support was removed.
+ * POP2 protocol support was removed.
+ * RPOP (not actually a protocol, but a variant of POP3) was removed
+ * POP3: the uidl option has been removed. It is always on.
+ * POP3: LAST is no longer used. It was removed from POP3 in 1994, and it could
+   cause mail loss when the connection was interrupted or if clients besides
+   fetchmail polled the mailbox.
+ * Trio was removed, fetchmail expects reasonable stdio.h quality levels.
+ * Support for systems that do not conform to C89 and POSIX 2001 was removed,
+   this means that BeOS, EMX, NeXTSTEP quirks are no longer worked around.
+ * The MX and host alias DNS lookups that fetchmail performs in multidrop mode
+   have been removed. They were based on the mistaken assumption that the
+   IMAP/POP3 server was also the MX server, which is rarely the case.  They have
+   never supported IPv6 (including IPv6-mapped IPv4) either.
+   Non-DNS based alias keywords such as "aka" remain.
+ * Kerberos IV support was removed.
+ # CHANGES
+ * A foreground fetchmail can now accept a few more options while another copy is
+   running in the background.
+ --------------------------------------------------------------------------------
  
  fetchmail-6.3.20 (not yet released):
  
diff --cc configure.ac
index 533f239ace8bdb894dfa4fbd56eff626ef22ef57,26f82f79167459bfe2fd11e1ab773f133f374e38..eeba174ac279c690ef08d0d2444dc74324e17277
@@@ -9,7 -9,7 +9,7 @@@ dnl Process this file with autoconf to 
  dnl
  
  dnl XXX - if bumping version here, check fetchmail.man, too!
- AC_INIT([fetchmail],[6.3.20-pre1],[fetchmail-users@lists.berlios.de])
 -AC_INIT([fetchmail],[7.0.0-alpha1],[fetchmail-devel@lists.berlios.de])
++AC_INIT([fetchmail],[6.4.0-alpha1],[fetchmail-devel@lists.berlios.de])
  AC_CONFIG_SRCDIR([fetchmail.h])
  AC_CONFIG_HEADERS([config.h])
  AC_CONFIG_LIBOBJ_DIR([.])
diff --cc driver.c
index 500f9eb2fb1d889993126384bab097eb5191a4e2,672b34445e55a10702ff7311666b08a2978a4bdf..6d0053253390f89c3bb8d7ce39f24fbaca2c72ec
+++ b/driver.c
@@@ -130,78 -109,19 +109,13 @@@ static void timeout_handler (int signal
  static int cleanupSockClose (int fd)
  /* close sockets in maximum CLEANUP_TIMEOUT seconds during cleanup */
  {
 -    int scerror;
 -    SIGHANDLERTYPE alrmsave;
 -    alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
 -    set_timeout(CLEANUP_TIMEOUT);
 -    scerror = SockClose(fd);
 -    set_timeout(0);
 -    set_signal_handler(SIGALRM, alrmsave);
 -    return (scerror);
 +    (void)SockTimeout(fd, CLEANUP_TIMEOUT); /* ignore errors */
 +    return SockClose(fd);
  }
  
- #ifdef KERBEROS_V4
- static int kerberos_auth(socket, canonical, principal) 
- /* authenticate to the server host using Kerberos V4 */
- int socket;           /* socket to server host */
- char *canonical;      /* server name */
- char *principal;
- {
-     KTEXT ticket;
-     MSG_DAT msg_data;
-     CREDENTIALS cred;
-     Key_schedule schedule;
-     int rem;
-     char * prin_copy = (char *) NULL;
-     char * prin = (char *) NULL;
-     char * inst = (char *) NULL;
-     char * realm = (char *) NULL;
-     if (principal != (char *)NULL && *principal)
-     {
-         char *cp;
-         prin = prin_copy = xstrdup(principal);
-       for (cp = prin_copy; *cp && *cp != '.'; ++cp)
-           ;
-       if (*cp)
-       {
-           *cp++ = '\0';
-           inst = cp;
-           while (*cp && *cp != '@')
-               ++cp;
-           if (*cp)
-           {
-               *cp++ = '\0';
-               realm = cp;
-           }
-       }
-     }
-   
-     ticket = xmalloc(sizeof (KTEXT_ST));
-     rem = (krb_sendauth (0L, socket, ticket,
-                        prin ? prin : "pop",
-                        inst ? inst : canonical,
-                        realm ? realm : ((char *) (krb_realmofhost (canonical))),
-                        ((unsigned long) 0),
-                        (&msg_data),
-                        (&cred),
-                        (schedule),
-                        ((struct sockaddr_in *) 0),
-                        ((struct sockaddr_in *) 0),
-                        "KPOPV0.1"));
-     free(ticket);
-     if (prin_copy)
-     {
-         free(prin_copy);
-     }
-     if (rem != KSUCCESS)
-     {
-       report(stderr, GT_("kerberos error %s\n"), (krb_get_err_text (rem)));
-       return (PS_AUTHFAIL);
-     }
-     return (0);
- }
- #endif /* KERBEROS_V4 */
  #ifdef KERBEROS_V5
- static int kerberos5_auth(socket, canonical)
- /* authenticate to the server host using Kerberos V5 */
- int socket;             /* socket to server host */
- const char *canonical;  /* server name */
+ /** authenticate to the server host using Kerberos V5 */
+ static int kerberos5_auth(int socket /** socket to server host */, const char *canonical /** server name */)
  {
      krb5_error_code retval;
      krb5_context context;
Simple merge
diff --cc fetchmail.h
Simple merge
diff --cc fetchmail.man
Simple merge
diff --cc imap.c
index bdda1656d6f258d1f0820b9aa7133e5d85cc7f96,867ce0084458ad4ba4ec0a403f0fb14b610da185..5e76801cf02b5acb39efe60c43e39d6d835d430c
--- 1/imap.c
--- 2/imap.c
+++ b/imap.c
@@@ -767,11 -731,12 +731,11 @@@ static int imap_search(int sock, struc
       * higher and only when keeping mails. This flag will have an
       * effect only when user has marked some unread mails for deletion
       * using another e-mail client. */
-     flag skipdeleted = (imap_version >= IMAP4) && ctl->keep;
+     flag skipdeleted = ctl->keep;
      const char *undeleted;
  
 -    /* Skip range search if there are less than or equal to
 -     * IMAP_SEARCH_MAX mails. */
 -    flag skiprangesearch = (count <= IMAP_SEARCH_MAX);
 +    /* structure to keep the end portion of the incomplete response */
 +    struct RecvSplit rs;
  
      /* startcount is higher than count so that if there are no
       * unseen messages, imap_getsizes() will not need to do
diff --cc opie.c
Simple merge
diff --cc options.c
Simple merge
diff --cc sink.c
Simple merge
diff --cc smtp.c
Simple merge
diff --cc socket.c
index 4088e74f968e63b3caf0170ef0688b6087432504,26eb792fca8341d4befbdc0fb4cf7395160a6708..5039ac5ff8cdc974c9e1c7a9ae8a86bffdd1e50e
+++ b/socket.c
@@@ -202,40 -165,7 +169,39 @@@ static int handle_plugin(const char *ho
      (void) close(fds[0]);
      return fds[1];
  }
- #endif /* HAVE_SOCKETPAIR */
  
 +static int setsocktimeout(int sock, int which, int timeout) {
 +    struct timeval tv;
 +    int rc;
 +
 +    tv.tv_sec = timeout;
 +    tv.tv_usec = 0;
 +    rc = setsockopt(sock, SOL_SOCKET, which, &tv, sizeof(tv));
 +    if (rc) {
 +      report(stderr, GT_("setsockopt(%d, SOL_SOCKET) failed: %s"), sock, strerror(errno));
 +    }
 +    return rc;
 +}
 +
 +/** Configure socket options such as send/receive timeout at the socket
 + * level, to avoid network-induced stalls. \return 0 for success, 1 for
 + * error.
 + */
 +int SockTimeout(int sock, int timeout)
 +{
 +    int err = 0;
 +
 +    if (setsocktimeout(sock, SO_RCVTIMEO, timeout)) err = 1;
 +    if (setsocktimeout(sock, SO_SNDTIMEO, timeout)) err = 1;
 +    return err;
 +}
 +
 +/** Set socket to SO_KEEPALIVE. \return 0 for success. */
 +int SockKeepalive(int sock) {
 +    int keepalive = 1;
 +    return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof keepalive);
 +}
 +
  int UnixOpen(const char *path)
  {
      int sock = -1;
@@@ -376,16 -299,9 +340,13 @@@ int SockOpen(const char *host, const ch
      return i;
  }
  
++<<<<<<< HEAD
 +#if defined(HAVE_STDARG_H)
++=======
++>>>>>>> before-cpp
  int SockPrintf(int sock, const char* format, ...)
  {
- #else
- int SockPrintf(sock,format,va_alist)
- int sock;
- char *format;
- va_dcl {
- #endif
      va_list ap;
      char buf[8192];
  
diff --cc socket.h
Simple merge
diff --cc transact.c
index f55bdee2bfdad35e5c01ef55c6266058b7f63b68,1480e76417002cac68a2f67e9dcbe406a032dcf2..0f0cd35378a4c4f5f053b8db9093562e899a1d52
@@@ -9,26 -9,11 +9,12 @@@
  #include  <stdio.h>
  #include  <string.h>
  #include  <ctype.h>
- #ifdef HAVE_MEMORY_H
- #include  <memory.h>
- #endif /* HAVE_MEMORY_H */
- #if defined(STDC_HEADERS)
  #include  <stdlib.h>
- #endif
- #if defined(HAVE_UNISTD_H)
  #include <unistd.h>
- #endif
- #if defined(HAVE_STDARG_H)
  #include  <stdarg.h>
- #else
- #include  <varargs.h>
- #endif
  #include <limits.h>
 +#include <assert.h>
  
- #ifdef HAVE_NET_SOCKET_H
- #include <net/socket.h>
- #endif
  #include <sys/socket.h>
  #include <netdb.h>
  #include "fm_md5.h"
@@@ -1522,15 -1471,8 +1481,10 @@@ static void enshroud(char *buf
      }
  }
  
- #if defined(HAVE_STDARG_H)
 -void gen_send(int sock, const char *fmt, ... )
 -/* assemble command in printf(3) style and send to the server */
 +/** assemble command in printf(3) style and send to the server */
- void gen_send(int sock, const char *fmt, ... )
- #else
- void gen_send(sock, fmt, va_alist)
- int sock;             /** socket to which server is connected */
- const char *fmt;      /** printf-style format */
- va_dcl
- #endif
++void gen_send(int sock/** socket to which server is connected */,
++            const char *fmt /** printf-style format */,
++            ...)
  {
      char buf [MSGBUFSIZE+1];
      va_list ap;
@@@ -1586,152 -1521,19 +1536,147 @@@ int gen_recv(int sock  /** socket to wh
      else
      {
        set_timeout(0);
 -      if (buf[strlen(buf)-1] == '\n')
 -          buf[strlen(buf)-1] = '\0';
 -      if (buf[strlen(buf)-1] == '\r')
 -          buf[strlen(buf)-1] = '\0';
 +      n = strlen(buf);
 +      if (n > 0 && buf[n-1] == '\n')
 +          buf[--n] = '\0';
 +      if (n > 0 && buf[n-1] == '\r')
 +          buf[--n] = '\0';
        if (outlevel >= O_MONITOR)
            report(stdout, "%s< %s\n", protocol->name, buf);
 +      return(PS_SUCCESS);
 +    }
 +}
 +
 +/** \addtogroup gen_recv_split
 + * @{
 + * gen_recv_split() splits the response from a server which is too
 + * long to fit into the buffer into multiple lines. If the prefix is
 + * set as "MY FEATURES" and the response from the server is too long
 + * to fit in the buffer, as in:
 + *
 + *   "MY FEATURES ABC DEF GHI JKLMNOPQRS TU VWX YZ"
 + *
 + * Repeated calls to gen_recv_split() may return:
 + *
 + *   "MY FEATURES ABC DEF GHI"
 + *   "MY FEATURES JKLMNOPQRS"
 + *   "MY FEATURES TU VWX YZ"
 + *
 + * A response not beginning with the prefix "MY FEATURES" will not be
 + * split.
 + *
 + * To use:
 + * - Declare a variable of type struct RecvSplit
 + * - Call gen_recv_split_init() once
 + * - Call gen_recv_split() in a loop, preferably with the same buffer
 + *   size as the "buf" array in struct RecvSplit
 + */
 +
 +static void overrun(const char *f, size_t l) __attribute__((noreturn));
 +
 +/** Internal error report function. If this happens, the calling site
 + * needs to be adjusted to set a shorter prefix, or the prefix capacity
 + * needs to be raised in struct RecvSplit. */
 +static void overrun(const char *f, size_t l)
 +{
 +    report(stderr, GT_("Buffer too small. This is a bug in the caller of %s:%lu.\n"), f, (unsigned long)l);
 +    abort();
 +}
 +
 +/** Initialize \a rs for later use by gen_recv_split. */
 +void gen_recv_split_init (const char *prefix /** prefix to match/repeat */,
 +      struct RecvSplit *rs /** structure to be initialized */)
 +{
 +    if (strlcpy(rs->prefix, prefix, sizeof(rs->prefix)) > sizeof(rs->prefix))
 +      overrun(__FILE__, __LINE__);
 +    rs->cached = 0;
 +    rs->buf[0] = '\0';
 +}
 +
 +/** Function to split replies at blanks, and duplicate prefix.
 + * gen_recv_split_init() must be called before this can be used. */
 +int gen_recv_split(int sock  /** socket to which server is connected */,
 +           char *buf /** buffer to receive input */,
 +           int size  /** length of buffer, must be the same for all calls */,
 +           struct RecvSplit *rs /** cached information across calls */)
 +{
 +    size_t n = 0;
 +    int foundnewline = 0;
 +    char *p;
 +    int oldphase = phase;     /* we don't have to be re-entrant */
 +
 +    assert(size > 0);
 +
 +    /* if this is not our first call, prepare the buffer */
 +    if (rs->cached)
 +    {
 +      /*
 +       * if this condition is not met, we lose data
 +       * because the cached data does not fit into the buffer.
 +       * this cannot happen if size is the same throughout all calls.
 +       */
 +      assert(strlen(rs->prefix) + strlen(rs->buf) + 1 <= (size_t)size);
 +
 +      if ((strlcpy(buf, rs->prefix, size) >= (size_t)size)
 +              || (strlcat(buf, rs->buf, size) >= (size_t)size)) {
 +          overrun(__FILE__, __LINE__);
 +      }
 +
 +      n = strlen(buf);
 +      /* clear the cache for the next call */
 +      rs->cached = 0;
 +      rs->buf[0] = '\0';
 +    }
 +
 +    if ((size_t)size > n) {
 +      int rr;
 +
 +      phase = SERVER_WAIT;
 +      set_timeout(mytimeout);
 +      rr = SockRead(sock, buf + n, size - n);
 +      set_timeout(0);
        phase = oldphase;
 +      if (rr == -1)
 +          return PS_SOCKET;
 +    }
 +
 +    n = strlen(buf);
 +    if (n > 0 && buf[n-1] == '\n')
 +    {
 +      buf[--n] = '\0';
 +      foundnewline = 1;
 +    }
 +    if (n > 0 && buf[n-1] == '\r')
 +      buf[--n] = '\0';
 +
 +    if (foundnewline                          /* we have found a complete line */
 +      || strncasecmp(buf, rs->prefix, strlen(rs->prefix))     /* mismatch in prefix */
 +      || !(p = strrchr(buf, ' '))             /* no space found in response */
 +      || p < buf + strlen(rs->prefix))        /* space is at the wrong location */
 +    {
 +      if (outlevel >= O_MONITOR)
 +          report(stdout, "%s< %s\n", protocol->name, buf);
        return(PS_SUCCESS);
      }
 +
 +    /* we are ready to cache some information now. */
 +    rs->cached = 1;
 +    if (strlcpy(rs->buf, p, sizeof(rs->buf)) >= sizeof(rs->buf)) {
 +      overrun(__FILE__, __LINE__);
 +    }
 +    *p = '\0'; /* chop off what we've cached */
 +    if (outlevel >= O_MONITOR)
 +      report(stdout, "%s< %s\n", protocol->name, buf);
 +    if (outlevel >= O_DEBUG)
 +      report(stdout, "%s< %s%s...\n", protocol->name, rs->prefix, rs->buf);
 +    return(PS_SUCCESS);
  }
 +/** @} */
  
- #if defined(HAVE_STDARG_H)
--int gen_transact(int sock, const char *fmt, ... )
- #else
- int gen_transact(int sock, fmt, va_alist)
- int sock;             /** socket to which server is connected */
- const char *fmt;      /** printf-style format */
- va_dcl
- #endif
 -/* assemble command in printf(3) style, send to server, accept a response */
 +/** assemble command in printf(3) style, send to server, fetch a response */
++int gen_transact(int sock      /** socket to which server is connected */,
++               const char *fmt /** printf-style format */,
++               ...)
  {
      int ok;
      char buf [MSGBUFSIZE+1];