/* pop.c: client routines for talking to a POP3-protocol post-office server
- Copyright (c) 1991, 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1996, 1997, 1999, 2002, 2003, 2004,
+ 2005, 2006 Free Software Foundation, Inc.
Written by Jonathan Kamens, jik@security.ov.com.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
#define NO_SHORTNAMES /* Tell config not to load remap.h */
-#include <../src/config.h>
+#include <config.h>
#else
#define MAIL_USE_POP
#endif
# ifdef HAVE_KRB5_H
# include <krb5.h>
# endif
-# ifdef HAVE_DES_H
-# include <des.h>
-# else
-# ifdef HAVE_KERBEROSIV_DES_H
-# include <kerberosIV/des.h>
-# else
-# ifdef HAVE_KERBEROS_DES_H
-# include <kerberos/des.h>
-# endif
-# endif
-# endif
# ifdef HAVE_KRB_H
# include <krb.h>
# else
#endif
#endif
-#ifndef _P
+#ifndef __P
# ifdef __STDC__
-# define _P(a) a
+# define __P(a) a
# else
-# define _P(a) ()
+# define __P(a) ()
# endif /* __STDC__ */
#endif /* ! __P */
-static int socket_connection _P((char *, int));
-static int pop_getline _P((popserver, char **));
-static int sendline _P((popserver, char *));
-static int fullwrite _P((int, char *, int));
-static int getok _P((popserver));
+static int socket_connection __P((char *, int));
+static int pop_getline __P((popserver, char **));
+static int sendline __P((popserver, char *));
+static int fullwrite __P((int, char *, int));
+static int getok __P((popserver));
#if 0
-static int gettermination _P((popserver));
+static int gettermination __P((popserver));
#endif
-static void pop_trash _P((popserver));
-static char *find_crlf _P((char *, int));
+static void pop_trash __P((popserver));
+static char *find_crlf __P((char *, int));
#define ERROR_MAX 160 /* a pretty arbitrary size, but needs
to be bigger than the original
#define KPOP_PORT 1109
#define POP_SERVICE "pop3" /* we don't want the POP2 port! */
#ifdef KERBEROS
-#define KPOP_SERVICE "kpop"
+#define KPOP_SERVICE "kpop" /* never used: look for 20060515 to see why */
#endif
char pop_error[ERROR_MAX];
#else
#define DONT_NEED_PASSWORD 0
#endif
-
+
if ((! password) && (! DONT_NEED_PASSWORD))
{
if (! (flags & POP_NO_GETPASS))
return (0);
}
}
- if (password)
+ if (password) /* always true, detected 20060515 */
flags |= POP_NO_KERBEROS;
else
- password = username;
+ password = username; /* dead code, detected 20060515 */
+ /** "kpop" service is never used: look for 20060515 to see why **/
sock = socket_connection (host, flags);
if (sock == -1)
free ((char *) server);
return (0);
}
-
+
server->file = sock;
server->data = 0;
server->buffer_index = 0;
strcpy (pop_error, "In multi-line query in pop_stat");
return (-1);
}
-
+
if (sendline (server, "STAT") || (pop_getline (server, &fromserver) < 0))
return (-1);
}
*count = atoi (&fromserver[4]);
-
+
fromserver = index (&fromserver[4], ' ');
if (! fromserver)
{
* of lines with '>'.
* msg_buf Output parameter to which a buffer containing the
* message is assigned.
- *
+ *
* Return value: The number of bytes in msg_buf, which may contain
* embedded nulls, not including its final null, or -1 on error
* with pop_error set.
free (ptr);
return (-1);
-}
+}
int
pop_retrieve_first (server, message, response)
popserver server;
{
char *fromserver;
-
+
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_last");
* Arguments:
* host The host to which to connect.
* flags Option flags.
- *
+ *
* Return value: A file descriptor indicating the connection, or -1
* indicating failure, in which case an error has been copied
* into pop_error.
}
#endif
- do
- {
- hostent = gethostbyname (host);
- try_count++;
- if ((! hostent) && ((h_errno != TRY_AGAIN) || (try_count == 5)))
- {
- strcpy (pop_error, "Could not determine POP server's address");
- return (-1);
- }
- } while (! hostent);
-
bzero ((char *) &addr, sizeof (addr));
addr.sin_family = AF_INET;
+ /** "kpop" service is never used: look for 20060515 to see why **/
#ifdef KERBEROS
service = (flags & POP_NO_KERBEROS) ? POP_SERVICE : KPOP_SERVICE;
#else
}
else
{
+ /** "kpop" service is never used: look for 20060515 to see why **/
#ifdef KERBEROS
addr.sin_port = htons ((flags & POP_NO_KERBEROS) ?
POP_PORT : KPOP_PORT);
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (POP_SOCKET_ERROR));
return (-1);
-
+
}
+ do
+ {
+ hostent = gethostbyname (host);
+ try_count++;
+ if ((! hostent) && ((h_errno != TRY_AGAIN) || (try_count == 5)))
+ {
+ strcpy (pop_error, "Could not determine POP server's address");
+ return (-1);
+ }
+ } while (! hostent);
+
while (*hostent->h_addr_list)
{
bcopy (*hostent->h_addr_list, (char *) &addr.sin_addr,
}
#define CONNECT_ERROR "Could not connect to POP server: "
-
+
if (! *hostent->h_addr_list)
{
CLOSESOCKET (sock);
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (CONNECT_ERROR));
return (-1);
-
+
}
#ifdef KERBEROS
if ((rem = krb5_auth_con_init (kcontext, &auth_context)))
goto krb5error;
-
+
if (rem = krb5_cc_default (kcontext, &ccdef))
goto krb5error;
CLOSESOCKET (sock);
return (-1);
}
-#else /* ! KERBEROS5 */
+#else /* ! KERBEROS5 */
ticket = (KTEXT) malloc (sizeof (KTEXT_ST));
realhost = strdup (hostent->h_name);
rem = krb_sendauth (0L, sock, ticket, "pop", realhost,
found = server->buffer_index;
data_used = (cp + 2) - server->buffer - found;
-
+
*cp = '\0'; /* terminate the string to be returned */
server->data -= data_used;
server->buffer_index += data_used;
char *cp;
server->data += ret;
server->buffer[server->data] = '\0';
-
+
cp = find_crlf (server->buffer + search_offset,
server->data - search_offset);
if (cp)
{
#define SENDLINE_ERROR "Error writing to POP server: "
int ret;
-
- ret = fullwrite (server->file, line, strlen (line));
- if (ret >= 0)
- { /* 0 indicates that a blank line was written */
- ret = fullwrite (server->file, "\r\n", 2);
- }
+ char *buf;
+
+ /* Combine the string and the CR-LF into one buffer. Otherwise, two
+ reasonable network stack optimizations, Nagle's algorithm and
+ delayed acks, combine to delay us a fraction of a second on every
+ message we send. (Movemail writes line without \r\n, client
+ kernel sends packet, server kernel delays the ack to see if it
+ can combine it with data, movemail writes \r\n, client kernel
+ waits because it has unacked data already in its outgoing queue,
+ client kernel eventually times out and sends.)
+
+ This can be something like 0.2s per command, which can add up
+ over a few dozen messages, and is a big chunk of the time we
+ spend fetching mail from a server close by. */
+ buf = alloca (strlen (line) + 3);
+ strcpy (buf, line);
+ strcat (buf, "\r\n");
+ ret = fullwrite (server->file, buf, strlen (buf));
if (ret < 0)
{
*
* Arguments:
* server The server to read from.
- *
+ *
* Returns: 0 for success, else for failure and puts error in pop_error.
*
* Side effects: On failure, may make the connection unusable.
pop_trash (server);
return (-1);
}
-}
+}
#if 0
/*
* Changes made to the maildrop since the session was started (or
* since the last pop_reset) may be lost.
*/
-void
+void
pop_close (server)
popserver server;
{
}
#endif /* MAIL_USE_POP */
+
+/* arch-tag: ceb37041-b7ad-49a8-a63d-286618b8367d
+ (do not change this comment) */