summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
authorKarl Heuer <kwzh@gnu.org>1997-12-04 06:44:56 +0000
committerKarl Heuer <kwzh@gnu.org>1997-12-04 06:44:56 +0000
commitb2cb860bfb34d4ed3b7336dcbd12cef163e3f8d1 (patch)
treed00fcf040dcba0e988938490ed59eeab55c73e72 /lib-src
parent35587e31d300e3c2b1f2c57b486e4f419dda5984 (diff)
downloademacs-b2cb860bfb34d4ed3b7336dcbd12cef163e3f8d1.tar.gz
Allow messages retrieved from the POP
server to contain embedded nulls.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/movemail.c9
-rw-r--r--lib-src/pop.c176
-rw-r--r--lib-src/pop.h3
3 files changed, 116 insertions, 72 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c
index b7b51d35061..e010d6f9806 100644
--- a/lib-src/movemail.c
+++ b/lib-src/movemail.c
@@ -795,12 +795,12 @@ pop_retr (server, msgno, arg)
return (NOTOK);
}
- while (! (ret = pop_retrieve_next (server, &line)))
+ while ((ret = pop_retrieve_next (server, &line)) >= 0)
{
if (! line)
break;
- if (mbx_write (line, arg) != OK)
+ if (mbx_write (line, ret, arg) != OK)
{
strcpy (Errmsg, strerror (errno));
pop_close (server);
@@ -826,8 +826,9 @@ pop_retr (server, msgno, arg)
&& (a[4] == ' '))
int
-mbx_write (line, mbf)
+mbx_write (line, len, mbf)
char *line;
+ int len;
FILE *mbf;
{
#ifdef MOVEMAIL_QUOTE_POP_FROM_LINES
@@ -844,7 +845,7 @@ mbx_write (line, mbf)
line++;
len--;
}
- if (fputs (line, mbf) == EOF)
+ if (fwrite (line, 1, len, mbf) != len)
return (NOTOK);
if (fputc (0x0a, mbf) == EOF)
return (NOTOK);
diff --git a/lib-src/pop.c b/lib-src/pop.c
index 16823baa1d4..d74d16fa6d2 100644
--- a/lib-src/pop.c
+++ b/lib-src/pop.c
@@ -130,16 +130,24 @@ extern int h_errno;
#endif
#endif
-static int socket_connection (/* char *, int */);
-static char *getline (/* popserver */);
-static int sendline (/* popserver, char * */);
-static int fullwrite (/* int, char *, int */);
-static int getok (/* popserver */);
+#ifndef _P
+# ifdef __STDC__
+# define _P(a) a
+# else
+# define _P(a) ()
+# endif /* __STDC__ */
+#endif /* ! __P */
+
+static int socket_connection _P((char *, int));
+static int 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 (/* popserver */);
+static int gettermination _P((popserver));
#endif
-static void pop_trash (/* popserver */);
-static char *find_crlf (/* char * */);
+static void pop_trash _P((popserver));
+static char *find_crlf _P((char *, int));
#define ERROR_MAX 80 /* a pretty arbitrary size */
#define POP_PORT 110
@@ -373,7 +381,7 @@ pop_stat (server, count, size)
return (-1);
}
- if (sendline (server, "STAT") || (! (fromserver = getline (server))))
+ if (sendline (server, "STAT") || (getline (server, &fromserver) < 0))
return (-1);
if (strncmp (fromserver, "+OK ", 4))
@@ -469,7 +477,7 @@ pop_list (server, message, IDs, sizes)
free ((char *) *sizes);
return (-1);
}
- if (! (fromserver = getline (server)))
+ if (getline (server, &fromserver) < 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
@@ -514,7 +522,7 @@ pop_list (server, message, IDs, sizes)
}
for (i = 0; i < how_many; i++)
{
- if (pop_multi_next (server, &fromserver))
+ if (pop_multi_next (server, &fromserver) <= 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
@@ -533,7 +541,7 @@ pop_list (server, message, IDs, sizes)
}
(*sizes)[i] = atoi (fromserver);
}
- if (pop_multi_next (server, &fromserver))
+ if (pop_multi_next (server, &fromserver) < 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
@@ -563,17 +571,21 @@ pop_list (server, message, IDs, sizes)
* markfrom
* If true, then mark the string "From " at the beginning
* of lines with '>'.
+ * msg_buf Output parameter to which a buffer containing the
+ * message is assigned.
*
- * Return value: A string pointing to the message, if successful, or
- * null with pop_error set if not.
+ * 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.
*
* Side effects: May kill connection on error.
*/
-char *
-pop_retrieve (server, message, markfrom)
+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;
@@ -582,15 +594,15 @@ pop_retrieve (server, message, markfrom)
if (server->in_multi)
{
strcpy (pop_error, "In multi-line query in pop_retrieve");
- return (0);
+ return (-1);
}
if (pop_list (server, message, &IDs, &sizes))
- return (0);
+ return (-1);
if (pop_retrieve_first (server, message, &fromserver))
{
- return (0);
+ return (-1);
}
/*
@@ -608,17 +620,16 @@ pop_retrieve (server, message, markfrom)
{
strcpy (pop_error, "Out of memory in pop_retrieve");
pop_retrieve_flush (server);
- return (0);
+ return (-1);
}
- while (! (ret = pop_retrieve_next (server, &fromserver)))
+ while ((ret = pop_retrieve_next (server, &fromserver)) >= 0)
{
- int linesize;
-
if (! fromserver)
{
ptr[cp] = '\0';
- return (ptr);
+ *msg_buf = ptr;
+ return (cp);
}
if (markfrom && fromserver[0] == 'F' && fromserver[1] == 'r' &&
fromserver[2] == 'o' && fromserver[3] == 'm' &&
@@ -632,23 +643,19 @@ pop_retrieve (server, message, markfrom)
{
strcpy (pop_error, "Out of memory in pop_retrieve");
pop_retrieve_flush (server);
- return (0);
+ return (-1);
}
fromcount = 0;
}
ptr[cp++] = '>';
}
- linesize = strlen (fromserver);
- bcopy (fromserver, &ptr[cp], linesize);
- cp += linesize;
+ bcopy (fromserver, &ptr[cp], ret);
+ cp += ret;
ptr[cp++] = '\n';
}
- if (ret)
- {
- free (ptr);
- return (0);
- }
+ free (ptr);
+ return (-1);
}
int
@@ -661,6 +668,14 @@ pop_retrieve_first (server, message, response)
return (pop_multi_first (server, pop_error, response));
}
+/*
+ Returns a negative number on error, 0 to indicate that the data has
+ all been read (i.e., the server has returned a "." termination
+ line), or a positive number indicating the number of bytes in the
+ returned buffer (which is null-terminated and may contain embedded
+ nulls, but the returned bytecount doesn't include the final null).
+ */
+
int
pop_retrieve_next (server, line)
popserver server;
@@ -686,6 +701,14 @@ pop_top_first (server, message, lines, response)
return (pop_multi_first (server, pop_error, response));
}
+/*
+ Returns a negative number on error, 0 to indicate that the data has
+ all been read (i.e., the server has returned a "." termination
+ line), or a positive number indicating the number of bytes in the
+ returned buffer (which is null-terminated and may contain embedded
+ nulls, but the returned bytecount doesn't include the final null).
+ */
+
int
pop_top_next (server, line)
popserver server;
@@ -714,7 +737,7 @@ pop_multi_first (server, command, response)
return (-1);
}
- if (sendline (server, command) || (! (*response = getline (server))))
+ if (sendline (server, command) || (getline (server, response) < 0))
{
return (-1);
}
@@ -738,12 +761,22 @@ pop_multi_first (server, command, response)
}
}
+/*
+ Read the next line of data from SERVER and place a pointer to it
+ into LINE. Return -1 on error, 0 if there are no more lines to read
+ (i.e., the server has returned a line containing only "."), or a
+ positive number indicating the number of bytes in the LINE buffer
+ (not including the final null). The data in that buffer may contain
+ embedded nulls, but does not contain the final CRLF. When returning
+ 0, LINE is set to null. */
+
int
pop_multi_next (server, line)
popserver server;
char **line;
{
char *fromserver;
+ int ret;
if (! server->in_multi)
{
@@ -751,8 +784,7 @@ pop_multi_next (server, line)
return (-1);
}
- fromserver = getline (server);
- if (! fromserver)
+ if ((ret = getline (server, &fromserver)) < 0)
{
return (-1);
}
@@ -768,13 +800,13 @@ pop_multi_next (server, line)
else
{
*line = fromserver + 1;
- return (0);
+ return (ret - 1);
}
}
else
{
*line = fromserver;
- return (0);
+ return (ret);
}
}
@@ -783,21 +815,20 @@ pop_multi_flush (server)
popserver server;
{
char *line;
+ int ret;
if (! server->in_multi)
{
return (0);
}
- while (! pop_multi_next (server, &line))
+ while ((ret = pop_multi_next (server, &line)))
{
- if (! line)
- {
- return (0);
- }
+ if (ret < 0)
+ return (-1);
}
- return (-1);
+ return (0);
}
/* Function: pop_delete
@@ -888,7 +919,7 @@ pop_last (server)
if (sendline (server, "LAST"))
return (-1);
- if (! (fromserver = getline (server)))
+ if (getline (server, &fromserver) < 0)
return (-1);
if (! strncmp (fromserver, "-ERR", 4))
@@ -1234,16 +1265,22 @@ socket_connection (host, flags)
* Arguments:
* server The server from which to get the line of text.
*
- * Returns: A non-null pointer if successful, or a null pointer on any
- * error, with an error message copied into pop_error.
+ * Returns: The number of characters in the line, which is returned in
+ * LINE, not including the final null. A return value of 0
+ * indicates a blank line. A negative return value indicates an
+ * error (in which case the contents of LINE are undefined. In
+ * case of error, an error message is copied into pop_error.
*
* Notes: The line returned is overwritten with each call to getline.
*
* Side effects: Closes the connection on error.
+ *
+ * THE RETURNED LINE MAY CONTAIN EMBEDDED NULLS!
*/
-static char *
-getline (server)
+static int
+getline (server, line)
popserver server;
+ char **line;
{
#define GETLINE_ERROR "Error reading from server: "
@@ -1252,7 +1289,8 @@ getline (server)
if (server->data)
{
- char *cp = find_crlf (server->buffer + server->buffer_index);
+ char *cp = find_crlf (server->buffer + server->buffer_index,
+ server->data);
if (cp)
{
int found;
@@ -1266,8 +1304,11 @@ getline (server)
server->buffer_index += data_used;
if (pop_debug)
+ /* Embedded nulls will truncate this output prematurely,
+ but that's OK because it's just for debugging anyway. */
fprintf (stderr, "<<< %s\n", server->buffer + found);
- return (server->buffer + found);
+ *line = server->buffer + found;
+ return (data_used - 2);
}
else
{
@@ -1302,7 +1343,7 @@ getline (server)
{
strcpy (pop_error, "Out of memory in getline");
pop_trash (server);
- return (0);
+ return (-1);
}
}
ret = RECV (server->file, server->buffer + server->data,
@@ -1313,13 +1354,13 @@ getline (server)
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (GETLINE_ERROR));
pop_trash (server);
- return (0);
+ return (-1);
}
else if (ret == 0)
{
strcpy (pop_error, "Unexpected EOF from server in getline");
pop_trash (server);
- return (0);
+ return (-1);
}
else
{
@@ -1327,7 +1368,8 @@ getline (server)
server->data += ret;
server->buffer[server->data] = '\0';
- cp = find_crlf (server->buffer + search_offset);
+ cp = find_crlf (server->buffer + search_offset,
+ server->data - search_offset);
if (cp)
{
int data_used = (cp + 2) - server->buffer;
@@ -1337,7 +1379,8 @@ getline (server)
if (pop_debug)
fprintf (stderr, "<<< %s\n", server->buffer);
- return (server->buffer);
+ *line = server->buffer;
+ return (data_used - 2);
}
/* As above, the "- 1" here is to account for the fact that
we may have read a CR without its accompanying LF. */
@@ -1442,7 +1485,7 @@ getok (server)
{
char *fromline;
- if (! (fromline = getline (server)))
+ if (getline (server, &fromline) < 0)
{
return (-1);
}
@@ -1481,8 +1524,7 @@ gettermination (server)
{
char *fromserver;
- fromserver = getline (server);
- if (! fromserver)
+ if (getline (server, &fromserver) < 0)
return (-1);
if (strcmp (fromserver, "."))
@@ -1555,18 +1597,18 @@ pop_trash (server)
#endif
}
-/* Return a pointer to the first CRLF in IN_STRING,
- or 0 if it does not contain one. */
+/* Return a pointer to the first CRLF in IN_STRING, which can contain
+ embedded nulls and has LEN characters in it not including the final
+ null, or 0 if it does not contain one. */
static char *
-find_crlf (in_string)
+find_crlf (in_string, len)
char *in_string;
+ int len;
{
- while (1)
+ while (len--)
{
- if (! *in_string)
- return (0);
- else if (*in_string == '\r')
+ if (*in_string == '\r')
{
if (*++in_string == '\n')
return (in_string - 1);
@@ -1574,7 +1616,7 @@ find_crlf (in_string)
else
in_string++;
}
- /* NOTREACHED */
+ return (0);
}
#endif /* MAIL_USE_POP */
diff --git a/lib-src/pop.h b/lib-src/pop.h
index 9121425661a..cfd333ccafc 100644
--- a/lib-src/pop.h
+++ b/lib-src/pop.h
@@ -59,7 +59,8 @@ extern popserver pop_open _ARGS((char *host, char *username, char *password,
extern int pop_stat _ARGS((popserver server, int *count, int *size));
extern int pop_list _ARGS((popserver server, int message, int **IDs,
int **size));
-extern char *pop_retrieve _ARGS((popserver server, int message, int markfrom));
+extern int pop_retrieve _ARGS((popserver server, int message, int markfrom,
+ char **));
extern int pop_retrieve_first _ARGS((popserver server, int message,
char **response));
extern int pop_retrieve_next _ARGS((popserver server, char **line));