#ifdef HAVE_CONFIG_H
#define NO_SHORTNAMES
#include <../src/config.h>
#else
#define MAIL_USE_POP
#endif
#ifdef MAIL_USE_POP
#ifdef HAVE_CONFIG_H
#undef open
#undef read
#undef write
#undef close
#endif
#include <sys/types.h>
#ifdef WINDOWSNT
#include "ntlib.h"
#include <winsock.h>
#undef SOCKET_ERROR
#define RECV(s,buf,len,flags) recv(s,buf,len,flags)
#define SEND(s,buf,len,flags) send(s,buf,len,flags)
#define CLOSESOCKET(s) closesocket(s)
#else
#include <netinet/in.h>
#include <sys/socket.h>
#define RECV(s,buf,len,flags) read(s,buf,len)
#define SEND(s,buf,len,flags) write(s,buf,len)
#define CLOSESOCKET(s) close(s)
#endif
#include <pop.h>
#ifdef sun
#include <malloc.h>
#endif
#ifdef HESIOD
#include <hesiod.h>
extern struct servent *hes_getservbyname ();
#endif
#include <pwd.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#ifdef STDC_HEADERS
#include <string.h>
#define index strchr
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef KERBEROS
# 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
# ifdef HAVE_KERBEROSIV_KRB_H
# include <kerberosIV/krb.h>
# else
# ifdef HAVE_KERBEROS_KRB_H
# include <kerberos/krb.h>
# endif
# endif
# endif
# ifdef HAVE_COM_ERR_H
# include <com_err.h>
# endif
#endif
#ifdef KERBEROS
#ifndef KERBEROS5
extern int krb_sendauth ();
extern char *krb_realmofhost ();
#endif
#endif
#ifndef WINDOWSNT
#if !defined(HAVE_H_ERRNO) || !defined(HAVE_CONFIG_H)
extern int h_errno;
#endif
#endif
#ifndef _P
# ifdef __STDC__
# define _P(a) a
# else
# define _P(a) ()
# endif
#endif
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));
#endif
static void pop_trash _P((popserver));
static char *find_crlf _P((char *, int));
#define ERROR_MAX 80
#define POP_PORT 110
#define KPOP_PORT 1109
#ifdef WINDOWSNT
#define POP_SERVICE "pop3"
#else
#define POP_SERVICE "pop"
#endif
#ifdef KERBEROS
#define KPOP_SERVICE "kpop"
#endif
char pop_error[ERROR_MAX];
int pop_debug = 0;
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
popserver
pop_open (host, username, password, flags)
char *host;
char *username;
char *password;
int flags;
{
int sock;
popserver server;
if (! username)
{
username = getenv ("USER");
if (! (username && *username))
{
username = getlogin ();
if (! (username && *username))
{
struct passwd *passwd;
passwd = getpwuid (getuid ());
if (passwd && passwd->pw_name && *passwd->pw_name)
{
username = passwd->pw_name;
}
else
{
strcpy (pop_error, "Could not determine username");
return (0);
}
}
}
}
if (! host)
{
host = getenv ("MAILHOST");
}
#ifdef HESIOD
if ((! host) && (! (flags & POP_NO_HESIOD)))
{
struct hes_postoffice *office;
office = hes_getmailhost (username);
if (office && office->po_type && (! strcmp (office->po_type, "POP"))
&& office->po_name && *office->po_name && office->po_host
&& *office->po_host)
{
host = office->po_host;
username = office->po_name;
}
}
#endif
#ifdef MAILHOST
if (! host)
{
host = MAILHOST;
}
#endif
if (! host)
{
strcpy (pop_error, "Could not determine POP server");
return (0);
}
#ifdef KERBEROS
#define DONT_NEED_PASSWORD (! (flags & POP_NO_KERBEROS))
#else
#define DONT_NEED_PASSWORD 0
#endif
if ((! password) && (! DONT_NEED_PASSWORD))
{
if (! (flags & POP_NO_GETPASS))
{
password = getpass ("Enter POP password:");
}
if (! password)
{
strcpy (pop_error, "Could not determine POP password");
return (0);
}
}
if (password)
flags |= POP_NO_KERBEROS;
else
password = username;
sock = socket_connection (host, flags);
if (sock == -1)
return (0);
server = (popserver) malloc (sizeof (struct _popserver));
if (! server)
{
strcpy (pop_error, "Out of memory in pop_open");
return (0);
}
server->buffer = (char *) malloc (GETLINE_MIN);
if (! server->buffer)
{
strcpy (pop_error, "Out of memory in pop_open");
free ((char *) server);
return (0);
}
server->file = sock;
server->data = 0;
server->buffer_index = 0;
server->buffer_size = GETLINE_MIN;
server->in_multi = 0;
server->trash_started = 0;
if (getok (server))
return (0);
if (strlen (username) > ERROR_MAX - 6)
{
pop_close (server);
strcpy (pop_error,
"Username too long; recompile pop.c with larger ERROR_MAX");
return (0);
}
sprintf (pop_error, "USER %s", username);
if (sendline (server, pop_error) || getok (server))
{
return (0);
}
if (strlen (password) > ERROR_MAX - 6)
{
pop_close (server);
strcpy (pop_error,
"Password too long; recompile pop.c with larger ERROR_MAX");
return (0);
}
sprintf (pop_error, "PASS %s", password);
if (sendline (server, pop_error) || getok (server))
{
return (0);
}
return (server);
}
int
pop_stat (server, count, size)
popserver server;
int *count;
int *size;
{
char *fromserver;
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_stat");
return (-1);
}
if (sendline (server, "STAT") || (pop_getline (server, &fromserver) < 0))
return (-1);
if (strncmp (fromserver, "+OK ", 4))
{
if (0 == strncmp (fromserver, "-ERR", 4))
{
strncpy (pop_error, fromserver, ERROR_MAX);
}
else
{
strcpy (pop_error,
"Unexpected response from POP server in pop_stat");
pop_trash (server);
}
return (-1);
}
*count = atoi (&fromserver[4]);
fromserver = index (&fromserver[4], ' ');
if (! fromserver)
{
strcpy (pop_error,
"Badly formatted response from server in pop_stat");
pop_trash (server);
return (-1);
}
*size = atoi (fromserver + 1);
return (0);
}
int
pop_list (server, message, IDs, sizes)
popserver server;
int message;
int **IDs;
int **sizes;
{
int how_many, i;
char *fromserver;
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_list");
return (-1);
}
if (message)
how_many = 1;
else
{
int count, size;
if (pop_stat (server, &count, &size))
return (-1);
how_many = count;
}
*IDs = (int *) malloc ((how_many + 1) * sizeof (int));
*sizes = (int *) malloc ((how_many + 1) * sizeof (int));
if (! (*IDs && *sizes))
{
strcpy (pop_error, "Out of memory in pop_list");
return (-1);
}
if (message)
{
sprintf (pop_error, "LIST %d", message);
if (sendline (server, pop_error))
{
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
if (pop_getline (server, &fromserver) < 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
if (strncmp (fromserver, "+OK ", 4))
{
if (! strncmp (fromserver, "-ERR", 4))
strncpy (pop_error, fromserver, ERROR_MAX);
else
{
strcpy (pop_error,
"Unexpected response from server in pop_list");
pop_trash (server);
}
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
(*IDs)[0] = atoi (&fromserver[4]);
fromserver = index (&fromserver[4], ' ');
if (! fromserver)
{
strcpy (pop_error,
"Badly formatted response from server in pop_list");
pop_trash (server);
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
(*sizes)[0] = atoi (fromserver);
(*IDs)[1] = (*sizes)[1] = 0;
return (0);
}
else
{
if (pop_multi_first (server, "LIST", &fromserver))
{
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
for (i = 0; i < how_many; i++)
{
if (pop_multi_next (server, &fromserver) <= 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
(*IDs)[i] = atoi (fromserver);
fromserver = index (fromserver, ' ');
if (! fromserver)
{
strcpy (pop_error,
"Badly formatted response from server in pop_list");
free ((char *) *IDs);
free ((char *) *sizes);
pop_trash (server);
return (-1);
}
(*sizes)[i] = atoi (fromserver);
}
if (pop_multi_next (server, &fromserver) < 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
else if (fromserver)
{
strcpy (pop_error,
"Too many response lines from server in pop_list");
free ((char *) *IDs);
free ((char *) *sizes);
return (-1);
}
(*IDs)[i] = (*sizes)[i] = 0;
return (0);
}
}
int
pop_retrieve (server, message, markfrom, msg_buf)
popserver server;
int message;
int markfrom;
char **msg_buf;
{
int *IDs, *sizes, bufsize, fromcount = 0, cp = 0;
char *ptr, *fromserver;
int ret;
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_retrieve");
return (-1);
}
if (pop_list (server, message, &IDs, &sizes))
return (-1);
if (pop_retrieve_first (server, message, &fromserver))
{
return (-1);
}
bufsize = sizes[0] + (markfrom ? 5 : 0);
ptr = (char *)malloc (bufsize);
free ((char *) IDs);
free ((char *) sizes);
if (! ptr)
{
strcpy (pop_error, "Out of memory in pop_retrieve");
pop_retrieve_flush (server);
return (-1);
}
while ((ret = pop_retrieve_next (server, &fromserver)) >= 0)
{
if (! fromserver)
{
ptr[cp] = '\0';
*msg_buf = ptr;
return (cp);
}
if (markfrom && fromserver[0] == 'F' && fromserver[1] == 'r' &&
fromserver[2] == 'o' && fromserver[3] == 'm' &&
fromserver[4] == ' ')
{
if (++fromcount == 5)
{
bufsize += 5;
ptr = (char *)realloc (ptr, bufsize);
if (! ptr)
{
strcpy (pop_error, "Out of memory in pop_retrieve");
pop_retrieve_flush (server);
return (-1);
}
fromcount = 0;
}
ptr[cp++] = '>';
}
bcopy (fromserver, &ptr[cp], ret);
cp += ret;
ptr[cp++] = '\n';
}
free (ptr);
return (-1);
}
int
pop_retrieve_first (server, message, response)
popserver server;
int message;
char **response;
{
sprintf (pop_error, "RETR %d", message);
return (pop_multi_first (server, pop_error, response));
}
int
pop_retrieve_next (server, line)
popserver server;
char **line;
{
return (pop_multi_next (server, line));
}
int
pop_retrieve_flush (server)
popserver server;
{
return (pop_multi_flush (server));
}
int
pop_top_first (server, message, lines, response)
popserver server;
int message, lines;
char **response;
{
sprintf (pop_error, "TOP %d %d", message, lines);
return (pop_multi_first (server, pop_error, response));
}
int
pop_top_next (server, line)
popserver server;
char **line;
{
return (pop_multi_next (server, line));
}
int
pop_top_flush (server)
popserver server;
{
return (pop_multi_flush (server));
}
int
pop_multi_first (server, command, response)
popserver server;
char *command;
char **response;
{
if (server->in_multi)
{
strcpy (pop_error,
"Already in multi-line query in pop_multi_first");
return (-1);
}
if (sendline (server, command) || (pop_getline (server, response) < 0))
{
return (-1);
}
if (0 == strncmp (*response, "-ERR", 4))
{
strncpy (pop_error, *response, ERROR_MAX);
return (-1);
}
else if (0 == strncmp (*response, "+OK", 3))
{
for (*response += 3; **response == ' '; (*response)++) ;
server->in_multi = 1;
return (0);
}
else
{
strcpy (pop_error,
"Unexpected response from server in pop_multi_first");
return (-1);
}
}
int
pop_multi_next (server, line)
popserver server;
char **line;
{
char *fromserver;
int ret;
if (! server->in_multi)
{
strcpy (pop_error, "Not in multi-line query in pop_multi_next");
return (-1);
}
if ((ret = pop_getline (server, &fromserver)) < 0)
{
return (-1);
}
if (fromserver[0] == '.')
{
if (! fromserver[1])
{
*line = 0;
server->in_multi = 0;
return (0);
}
else
{
*line = fromserver + 1;
return (ret - 1);
}
}
else
{
*line = fromserver;
return (ret);
}
}
int
pop_multi_flush (server)
popserver server;
{
char *line;
int ret;
if (! server->in_multi)
{
return (0);
}
while ((ret = pop_multi_next (server, &line)))
{
if (ret < 0)
return (-1);
}
return (0);
}
int
pop_delete (server, message)
popserver server;
int message;
{
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_delete");
return (-1);
}
sprintf (pop_error, "DELE %d", message);
if (sendline (server, pop_error) || getok (server))
return (-1);
return (0);
}
int
pop_noop (server)
popserver server;
{
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_noop");
return (-1);
}
if (sendline (server, "NOOP") || getok (server))
return (-1);
return (0);
}
int
pop_last (server)
popserver server;
{
char *fromserver;
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_last");
return (-1);
}
if (sendline (server, "LAST"))
return (-1);
if (pop_getline (server, &fromserver) < 0)
return (-1);
if (! strncmp (fromserver, "-ERR", 4))
{
strncpy (pop_error, fromserver, ERROR_MAX);
return (-1);
}
else if (strncmp (fromserver, "+OK ", 4))
{
strcpy (pop_error, "Unexpected response from server in pop_last");
pop_trash (server);
return (-1);
}
else
{
return (atoi (&fromserver[4]));
}
}
int
pop_reset (server)
popserver server;
{
if (pop_retrieve_flush (server))
{
return (-1);
}
if (sendline (server, "RSET") || getok (server))
return (-1);
return (0);
}
int
pop_quit (server)
popserver server;
{
int ret = 0;
if (server->file >= 0)
{
if (pop_retrieve_flush (server))
{
ret = -1;
}
if (sendline (server, "QUIT") || getok (server))
{
ret = -1;
}
close (server->file);
}
if (server->buffer)
free (server->buffer);
free ((char *) server);
return (ret);
}
#ifdef WINDOWSNT
static int have_winsock = 0;
#endif
static int
socket_connection (host, flags)
char *host;
int flags;
{
struct hostent *hostent;
struct servent *servent;
struct sockaddr_in addr;
char found_port = 0;
char *service;
int sock;
#ifdef KERBEROS
#ifdef KERBEROS5
krb5_error_code rem;
krb5_context kcontext = 0;
krb5_auth_context auth_context = 0;
krb5_ccache ccdef;
krb5_principal client, server;
krb5_error *err_ret;
register char *cp;
#else
KTEXT ticket;
MSG_DAT msg_data;
CREDENTIALS cred;
Key_schedule schedule;
int rem;
char *realhost;
#endif
#endif
int try_count = 0;
#ifdef WINDOWSNT
{
WSADATA winsockData;
if (WSAStartup (0x101, &winsockData) == 0)
have_winsock = 1;
}
#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;
#ifdef KERBEROS
service = (flags & POP_NO_KERBEROS) ? POP_SERVICE : KPOP_SERVICE;
#else
service = POP_SERVICE;
#endif
#ifdef HESIOD
if (! (flags & POP_NO_HESIOD))
{
servent = hes_getservbyname (service, "tcp");
if (servent)
{
addr.sin_port = servent->s_port;
found_port = 1;
}
}
#endif
if (! found_port)
{
servent = getservbyname (service, "tcp");
if (servent)
{
addr.sin_port = servent->s_port;
}
else
{
#ifdef KERBEROS
addr.sin_port = htons ((flags & POP_NO_KERBEROS) ?
POP_PORT : KPOP_PORT);
#else
addr.sin_port = htons (POP_PORT);
#endif
}
}
#define POP_SOCKET_ERROR "Could not create socket for POP connection: "
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
strcpy (pop_error, POP_SOCKET_ERROR);
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (POP_SOCKET_ERROR));
return (-1);
}
while (*hostent->h_addr_list)
{
bcopy (*hostent->h_addr_list, (char *) &addr.sin_addr,
hostent->h_length);
if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
break;
hostent->h_addr_list++;
}
#define CONNECT_ERROR "Could not connect to POP server: "
if (! *hostent->h_addr_list)
{
CLOSESOCKET (sock);
strcpy (pop_error, CONNECT_ERROR);
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (CONNECT_ERROR));
return (-1);
}
#ifdef KERBEROS
#define KRB_ERROR "Kerberos error connecting to POP server: "
if (! (flags & POP_NO_KERBEROS))
{
#ifdef KERBEROS5
if ((rem = krb5_init_context (&kcontext)))
{
krb5error:
if (auth_context)
krb5_auth_con_free (kcontext, auth_context);
if (kcontext)
krb5_free_context (kcontext);
strcpy (pop_error, KRB_ERROR);
strncat (pop_error, error_message (rem),
ERROR_MAX - sizeof(KRB_ERROR));
CLOSESOCKET (sock);
return (-1);
}
if ((rem = krb5_auth_con_init (kcontext, &auth_context)))
goto krb5error;
if (rem = krb5_cc_default (kcontext, &ccdef))
goto krb5error;
if (rem = krb5_cc_get_principal (kcontext, ccdef, &client))
goto krb5error;
for (cp = hostent->h_name; *cp; cp++)
{
if (isupper (*cp))
{
*cp = tolower (*cp);
}
}
if (rem = krb5_sname_to_principal (kcontext, hostent->h_name,
POP_SERVICE, FALSE, &server))
goto krb5error;
rem = krb5_sendauth (kcontext, &auth_context,
(krb5_pointer) &sock, "KPOPV1.0", client, server,
AP_OPTS_MUTUAL_REQUIRED,
0,
0,
ccdef,
&err_ret,
0,
0);
krb5_free_principal (kcontext, server);
if (rem)
{
if (err_ret && err_ret->text.length)
{
strcpy (pop_error, KRB_ERROR);
strncat (pop_error, error_message (rem),
ERROR_MAX - sizeof (KRB_ERROR));
strncat (pop_error, " [server says '",
ERROR_MAX - strlen (pop_error) - 1);
strncat (pop_error, err_ret->text.data,
min (ERROR_MAX - strlen (pop_error) - 1,
err_ret->text.length));
strncat (pop_error, "']",
ERROR_MAX - strlen (pop_error) - 1);
}
else
{
strcpy (pop_error, KRB_ERROR);
strncat (pop_error, error_message (rem),
ERROR_MAX - sizeof (KRB_ERROR));
}
if (err_ret)
krb5_free_error (kcontext, err_ret);
krb5_auth_con_free (kcontext, auth_context);
krb5_free_context (kcontext);
CLOSESOCKET (sock);
return (-1);
}
#else
ticket = (KTEXT) malloc (sizeof (KTEXT_ST));
realhost = strdup (hostent->h_name);
rem = krb_sendauth (0L, sock, ticket, "pop", realhost,
(char *) krb_realmofhost (realhost),
(unsigned long) 0, &msg_data, &cred, schedule,
(struct sockaddr_in *) 0,
(struct sockaddr_in *) 0,
"KPOPV0.1");
free ((char *) ticket);
free (realhost);
if (rem != KSUCCESS)
{
strcpy (pop_error, KRB_ERROR);
strncat (pop_error, krb_err_txt[rem],
ERROR_MAX - sizeof (KRB_ERROR));
CLOSESOCKET (sock);
return (-1);
}
#endif
}
#endif
return (sock);
}
static int
pop_getline (server, line)
popserver server;
char **line;
{
#define GETLINE_ERROR "Error reading from server: "
int ret;
int search_offset = 0;
if (server->data)
{
char *cp = find_crlf (server->buffer + server->buffer_index,
server->data);
if (cp)
{
int found;
int data_used;
found = server->buffer_index;
data_used = (cp + 2) - server->buffer - found;
*cp = '\0';
server->data -= data_used;
server->buffer_index += data_used;
if (pop_debug)
fprintf (stderr, "<<< %s\n", server->buffer + found);
*line = server->buffer + found;
return (data_used - 2);
}
else
{
bcopy (server->buffer + server->buffer_index,
server->buffer, server->data);
search_offset = server->data - 1;
server->buffer_index = 0;
}
}
else
{
server->buffer_index = 0;
}
while (1)
{
if (server->data == server->buffer_size - 1)
{
server->buffer_size += GETLINE_INCR;
server->buffer = (char *)realloc (server->buffer, server->buffer_size);
if (! server->buffer)
{
strcpy (pop_error, "Out of memory in pop_getline");
pop_trash (server);
return (-1);
}
}
ret = RECV (server->file, server->buffer + server->data,
server->buffer_size - server->data - 1, 0);
if (ret < 0)
{
strcpy (pop_error, GETLINE_ERROR);
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (GETLINE_ERROR));
pop_trash (server);
return (-1);
}
else if (ret == 0)
{
strcpy (pop_error, "Unexpected EOF from server in pop_getline");
pop_trash (server);
return (-1);
}
else
{
char *cp;
server->data += ret;
server->buffer[server->data] = '\0';
cp = find_crlf (server->buffer + search_offset,
server->data - search_offset);
if (cp)
{
int data_used = (cp + 2) - server->buffer;
*cp = '\0';
server->data -= data_used;
server->buffer_index = data_used;
if (pop_debug)
fprintf (stderr, "<<< %s\n", server->buffer);
*line = server->buffer;
return (data_used - 2);
}
search_offset += ret - 1;
}
}
}
static int
sendline (server, line)
popserver server;
char *line;
{
#define SENDLINE_ERROR "Error writing to POP server: "
int ret;
ret = fullwrite (server->file, line, strlen (line));
if (ret >= 0)
{
ret = fullwrite (server->file, "\r\n", 2);
}
if (ret < 0)
{
pop_trash (server);
strcpy (pop_error, SENDLINE_ERROR);
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (SENDLINE_ERROR));
return (ret);
}
if (pop_debug)
fprintf (stderr, ">>> %s\n", line);
return (0);
}
static int
fullwrite (fd, buf, nbytes)
int fd;
char *buf;
int nbytes;
{
char *cp;
int ret = 0;
cp = buf;
while (nbytes && ((ret = SEND (fd, cp, nbytes, 0)) > 0))
{
cp += ret;
nbytes -= ret;
}
return (ret);
}
static int
getok (server)
popserver server;
{
char *fromline;
if (pop_getline (server, &fromline) < 0)
{
return (-1);
}
if (! strncmp (fromline, "+OK", 3))
return (0);
else if (! strncmp (fromline, "-ERR", 4))
{
strncpy (pop_error, fromline, ERROR_MAX);
pop_error[ERROR_MAX-1] = '\0';
return (-1);
}
else
{
strcpy (pop_error,
"Unexpected response from server; expecting +OK or -ERR");
pop_trash (server);
return (-1);
}
}
#if 0
static int
gettermination (server)
popserver server;
{
char *fromserver;
if (pop_getline (server, &fromserver) < 0)
return (-1);
if (strcmp (fromserver, "."))
{
strcpy (pop_error,
"Unexpected response from server in gettermination");
pop_trash (server);
return (-1);
}
return (0);
}
#endif
void
pop_close (server)
popserver server;
{
pop_trash (server);
free ((char *) server);
return;
}
static void
pop_trash (server)
popserver server;
{
if (server->file >= 0)
{
if (server->trash_started)
return;
server->trash_started = 1;
sendline (server, "RSET");
sendline (server, "QUIT");
CLOSESOCKET (server->file);
server->file = -1;
if (server->buffer)
{
free (server->buffer);
server->buffer = 0;
}
}
#ifdef WINDOWSNT
if (have_winsock)
WSACleanup ();
#endif
}
static char *
find_crlf (in_string, len)
char *in_string;
int len;
{
while (len--)
{
if (*in_string == '\r')
{
if (*++in_string == '\n')
return (in_string - 1);
}
else
in_string++;
}
return (0);
}
#endif