]>
code.delx.au - gnu-emacs/blob - lib-src/pop.c
1 /* pop.c: client routines for talking to a POP3-protocol post-office server
2 Copyright (c) 1991,1993 Free Software Foundation, Inc.
3 Written by Jonathan Kamens, jik@security.ov.com.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #define NO_SHORTNAMES /* Tell config not to load remap.h */
22 #include <../src/config.h>
26 #include <sys/types.h>
27 #include <netinet/in.h>
28 #include <sys/socket.h>
37 * It really shouldn't be necessary to put this declaration here, but
38 * the version of hesiod.h that Athena has installed in release 7.2
39 * doesn't declare this function; I don't know if the 7.3 version of
42 extern struct servent
*hes_getservbyname (/* char *, char * */);
53 #include <krb5/krb5.h>
54 #include <krb5/ext-proto.h>
58 extern char *getenv (/* char * */);
59 extern char *getlogin (/* void */);
60 extern char *getpass (/* char * */);
61 extern char *strerror (/* int */);
64 extern int krb_sendauth (/* long, int, KTEXT, char *, char *, char *,
65 u_long, MSG_DAT *, CREDENTIALS *, Key_schedule,
66 struct sockaddr_in *, struct sockaddr_in *,
68 extern char *krb_realmofhost (/* char * */);
75 static int socket_connection (/* char *, int */);
76 static char *getline (/* popserver */);
77 static int sendline (/* popserver, char * */);
78 static int fullwrite (/* int, char *, int */);
79 static int getok (/* popserver */);
81 static int gettermination (/* popserver */);
83 static void pop_trash (/* popserver */);
85 static char *my_strstr ();
87 #define ERROR_MAX 80 /* a pretty arbitrary size */
89 #define KPOP_PORT 1109
90 #define POP_SERVICE "pop"
93 #define KPOP_SERVICE "k5pop";
95 #define KPOP_SERVICE "kpop"
99 char pop_error
[ERROR_MAX
];
103 #define min(a,b) (((a) < (b)) ? (a) : (b))
107 * Function: pop_open (char *host, char *username, char *password,
110 * Purpose: Establishes a connection with a post-office server, and
111 * completes the authorization portion of the session.
114 * host The server host with which the connection should be
115 * established. Optional. If omitted, internal
116 * heuristics will be used to determine the server host,
119 * The username of the mail-drop to access. Optional.
120 * If omitted, internal heuristics will be used to
121 * determine the username, if possible.
123 * The password to use for authorization. If omitted,
124 * internal heuristics will be used to determine the
125 * password, if possible.
126 * flags A bit mask containing flags controlling certain
127 * functions of the routine. Valid flags are defined in
130 * Return value: Upon successful establishment of a connection, a
131 * non-null popserver will be returned. Otherwise, null will be
132 * returned, and the string variable pop_error will contain an
133 * explanation of the error.
136 pop_open (host
, username
, password
, flags
)
145 /* Determine the user name */
148 username
= getenv ("USER");
149 if (! (username
&& *username
))
151 username
= getlogin ();
152 if (! (username
&& *username
))
154 struct passwd
*passwd
;
155 passwd
= getpwuid (getuid ());
156 if (passwd
&& passwd
->pw_name
&& *passwd
->pw_name
)
158 username
= passwd
->pw_name
;
162 strcpy (pop_error
, "Could not determine username");
170 * Determine the mail host.
175 host
= getenv ("MAILHOST");
179 if ((! host
) && (! (flags
& POP_NO_HESIOD
)))
181 struct hes_postoffice
*office
;
182 office
= hes_getmailhost (username
);
183 if (office
&& office
->po_type
&& (! strcmp (office
->po_type
, "POP"))
184 && office
->po_name
&& *office
->po_name
&& office
->po_host
187 host
= office
->po_host
;
188 username
= office
->po_name
;
202 strcpy (pop_error
, "Could not determine POP server");
206 /* Determine the password */
208 #define DONT_NEED_PASSWORD (! (flags & POP_NO_KERBEROS))
210 #define DONT_NEED_PASSWORD 0
213 if ((! password
) && (! DONT_NEED_PASSWORD
))
215 if (! (flags
& POP_NO_GETPASS
))
217 password
= getpass ("Enter POP password:");
221 strcpy (pop_error
, "Could not determine POP password");
226 flags
|= POP_NO_KERBEROS
;
230 sock
= socket_connection (host
, flags
);
234 server
= (popserver
) malloc (sizeof (struct _popserver
));
237 strcpy (pop_error
, "Out of memory in pop_open");
240 server
->buffer
= (char *) malloc (GETLINE_MIN
);
241 if (! server
->buffer
)
243 strcpy (pop_error
, "Out of memory in pop_open");
244 free ((char *) server
);
250 server
->buffer_index
= 0;
251 server
->buffer_size
= GETLINE_MIN
;
252 server
->in_multi
= 0;
258 * I really shouldn't use the pop_error variable like this, but....
260 if (strlen (username
) > ERROR_MAX
- 6)
264 "Username too long; recompile pop.c with larger ERROR_MAX");
267 sprintf (pop_error
, "USER %s", username
);
269 if (sendline (server
, pop_error
) || getok (server
))
274 if (strlen (password
) > ERROR_MAX
- 6)
278 "Password too long; recompile pop.c with larger ERROR_MAX");
281 sprintf (pop_error
, "PASS %s", password
);
283 if (sendline (server
, pop_error
) || getok (server
))
294 * Purpose: Issue the STAT command to the server and return (in the
295 * value parameters) the number of messages in the maildrop and
296 * the total size of the maildrop.
298 * Return value: 0 on success, or non-zero with an error in pop_error
301 * Side effects: On failure, may make further operations on the
302 * connection impossible.
305 pop_stat (server
, count
, size
)
312 if (server
->in_multi
)
314 strcpy (pop_error
, "In multi-line query in pop_stat");
318 if (sendline (server
, "STAT") || (! (fromserver
= getline (server
))))
321 if (strncmp (fromserver
, "+OK ", 4))
323 if (0 == strncmp (fromserver
, "-ERR", 4))
325 strncpy (pop_error
, fromserver
, ERROR_MAX
);
330 "Unexpected response from POP server in pop_stat");
336 *count
= atoi (&fromserver
[4]);
338 fromserver
= index (&fromserver
[4], ' ');
342 "Badly formatted response from server in pop_stat");
347 *size
= atoi (fromserver
+ 1);
355 * Purpose: Performs the POP "list" command and returns (in value
356 * parameters) two malloc'd zero-terminated arrays -- one of
357 * message IDs, and a parallel one of sizes.
360 * server The pop connection to talk to.
361 * message The number of the one message about which to get
362 * information, or 0 to get information about all
365 * Return value: 0 on success, non-zero with error in pop_error on
368 * Side effects: On failure, may make further operations on the
369 * connection impossible.
372 pop_list (server
, message
, IDs
, sizes
)
381 if (server
->in_multi
)
383 strcpy (pop_error
, "In multi-line query in pop_list");
392 if (pop_stat (server
, &count
, &size
))
397 *IDs
= (int *) malloc ((how_many
+ 1) * sizeof (int));
398 *sizes
= (int *) malloc ((how_many
+ 1) * sizeof (int));
399 if (! (*IDs
&& *sizes
))
401 strcpy (pop_error
, "Out of memory in pop_list");
407 sprintf (pop_error
, "LIST %d", message
);
408 if (sendline (server
, pop_error
))
410 free ((char *) *IDs
);
411 free ((char *) *sizes
);
414 if (! (fromserver
= getline (server
)))
416 free ((char *) *IDs
);
417 free ((char *) *sizes
);
420 if (strncmp (fromserver
, "+OK ", 4))
422 if (! strncmp (fromserver
, "-ERR", 4))
423 strncpy (pop_error
, fromserver
, ERROR_MAX
);
427 "Unexpected response from server in pop_list");
430 free ((char *) *IDs
);
431 free ((char *) *sizes
);
434 (*IDs
)[0] = atoi (&fromserver
[4]);
435 fromserver
= index (&fromserver
[4], ' ');
439 "Badly formatted response from server in pop_list");
441 free ((char *) *IDs
);
442 free ((char *) *sizes
);
445 (*sizes
)[0] = atoi (fromserver
);
446 (*IDs
)[1] = (*sizes
)[1] = 0;
451 if (pop_multi_first (server
, "LIST", &fromserver
))
453 free ((char *) *IDs
);
454 free ((char *) *sizes
);
457 for (i
= 0; i
< how_many
; i
++)
459 if (pop_multi_next (server
, &fromserver
))
461 free ((char *) *IDs
);
462 free ((char *) *sizes
);
465 (*IDs
)[i
] = atoi (fromserver
);
466 fromserver
= index (fromserver
, ' ');
470 "Badly formatted response from server in pop_list");
471 free ((char *) *IDs
);
472 free ((char *) *sizes
);
476 (*sizes
)[i
] = atoi (fromserver
);
478 if (pop_multi_next (server
, &fromserver
))
480 free ((char *) *IDs
);
481 free ((char *) *sizes
);
487 "Too many response lines from server in pop_list");
488 free ((char *) *IDs
);
489 free ((char *) *sizes
);
492 (*IDs
)[i
] = (*sizes
)[i
] = 0;
498 * Function: pop_retrieve
500 * Purpose: Retrieve a specified message from the maildrop.
503 * server The server to retrieve from.
504 * message The message number to retrieve.
506 * If true, then mark the string "From " at the beginning
509 * Return value: A string pointing to the message, if successful, or
510 * null with pop_error set if not.
512 * Side effects: May kill connection on error.
515 pop_retrieve (server
, message
, markfrom
)
520 int *IDs
, *sizes
, bufsize
, fromcount
= 0, cp
= 0;
521 char *ptr
, *fromserver
;
524 if (server
->in_multi
)
526 strcpy (pop_error
, "In multi-line query in pop_retrieve");
530 if (pop_list (server
, message
, &IDs
, &sizes
))
533 if (pop_retrieve_first (server
, message
, &fromserver
))
539 * The "5" below is an arbitrary constant -- I assume that if
540 * there are "From" lines in the text to be marked, there
541 * probably won't be more than 5 of them. If there are, I
542 * allocate more space for them below.
544 bufsize
= sizes
[0] + (markfrom
? 5 : 0);
545 ptr
= malloc (bufsize
);
547 free ((char *) sizes
);
551 strcpy (pop_error
, "Out of memory in pop_retrieve");
552 pop_retrieve_flush (server
);
556 while (! (ret
= pop_retrieve_next (server
, &fromserver
)))
565 if (markfrom
&& fromserver
[0] == 'F' && fromserver
[1] == 'r' &&
566 fromserver
[2] == 'o' && fromserver
[3] == 'm' &&
567 fromserver
[4] == ' ')
569 if (++fromcount
== 5)
572 ptr
= realloc (ptr
, bufsize
);
575 strcpy (pop_error
, "Out of memory in pop_retrieve");
576 pop_retrieve_flush (server
);
583 linesize
= strlen (fromserver
);
584 bcopy (fromserver
, &ptr
[cp
], linesize
);
597 pop_retrieve_first (server
, message
, response
)
602 sprintf (pop_error
, "RETR %d", message
);
603 return (pop_multi_first (server
, pop_error
, response
));
607 pop_retrieve_next (server
, line
)
611 return (pop_multi_next (server
, line
));
615 pop_retrieve_flush (server
)
618 return (pop_multi_flush (server
));
622 pop_top_first (server
, message
, lines
, response
)
627 sprintf (pop_error
, "TOP %d %d", message
, lines
);
628 return (pop_multi_first (server
, pop_error
, response
));
632 pop_top_next (server
, line
)
636 return (pop_multi_next (server
, line
));
640 pop_top_flush (server
)
643 return (pop_multi_flush (server
));
647 pop_multi_first (server
, command
, response
)
652 if (server
->in_multi
)
655 "Already in multi-line query in pop_multi_first");
659 if (sendline (server
, command
) || (! (*response
= getline (server
))))
664 if (0 == strncmp (*response
, "-ERR", 4))
666 strncpy (pop_error
, *response
, ERROR_MAX
);
669 else if (0 == strncmp (*response
, "+OK", 3))
671 for (*response
+= 3; **response
== ' '; (*response
)++) /* empty */;
672 server
->in_multi
= 1;
678 "Unexpected response from server in pop_multi_first");
684 pop_multi_next (server
, line
)
690 if (! server
->in_multi
)
692 strcpy (pop_error
, "Not in multi-line query in pop_multi_next");
696 fromserver
= getline (server
);
702 if (fromserver
[0] == '.')
707 server
->in_multi
= 0;
712 *line
= fromserver
+ 1;
724 pop_multi_flush (server
)
729 if (! server
->in_multi
)
734 while (! pop_multi_next (server
, &line
))
745 /* Function: pop_delete
747 * Purpose: Delete a specified message.
750 * server Server from which to delete the message.
751 * message Message to delete.
753 * Return value: 0 on success, non-zero with error in pop_error
757 pop_delete (server
, message
)
761 if (server
->in_multi
)
763 strcpy (pop_error
, "In multi-line query in pop_delete");
767 sprintf (pop_error
, "DELE %d", message
);
769 if (sendline (server
, pop_error
) || getok (server
))
778 * Purpose: Send a noop command to the server.
781 * server The server to send to.
783 * Return value: 0 on success, non-zero with error in pop_error
786 * Side effects: Closes connection on error.
792 if (server
->in_multi
)
794 strcpy (pop_error
, "In multi-line query in pop_noop");
798 if (sendline (server
, "NOOP") || getok (server
))
807 * Purpose: Find out the highest seen message from the server.
812 * Return value: If successful, the highest seen message, which is
813 * greater than or equal to 0. Otherwise, a negative number with
814 * the error explained in pop_error.
816 * Side effects: Closes the connection on error.
824 if (server
->in_multi
)
826 strcpy (pop_error
, "In multi-line query in pop_last");
830 if (sendline (server
, "LAST"))
833 if (! (fromserver
= getline (server
)))
836 if (! strncmp (fromserver
, "-ERR", 4))
838 strncpy (pop_error
, fromserver
, ERROR_MAX
);
841 else if (strncmp (fromserver
, "+OK ", 4))
843 strcpy (pop_error
, "Unexpected response from server in pop_last");
849 return (atoi (&fromserver
[4]));
854 * Function: pop_reset
856 * Purpose: Reset the server to its initial connect state
861 * Return value: 0 for success, non-0 with error in pop_error
864 * Side effects: Closes the connection on error.
870 if (pop_retrieve_flush (server
))
875 if (sendline (server
, "RSET") || getok (server
))
884 * Purpose: Quit the connection to the server,
887 * server The server to quit.
889 * Return value: 0 for success, non-zero otherwise with error in
892 * Side Effects: The popserver passed in is unuseable after this
893 * function is called, even if an error occurs.
901 if (server
->file
>= 0)
903 if (pop_retrieve_flush (server
))
908 if (sendline (server
, "QUIT") || getok (server
))
913 close (server
->file
);
917 free (server
->buffer
);
918 free ((char *) server
);
924 * Function: socket_connection
926 * Purpose: Opens the network connection with the mail host, without
927 * doing any sort of I/O with it or anything.
930 * host The host to which to connect.
931 * flags Option flags.
933 * Return value: A file descriptor indicating the connection, or -1
934 * indicating failure, in which case an error has been copied
938 socket_connection (host
, flags
)
942 struct hostent
*hostent
;
943 struct servent
*servent
;
944 struct sockaddr_in addr
;
952 krb5_principal client
, server
;
959 Key_schedule schedule
;
962 #endif /* KERBEROS */
968 hostent
= gethostbyname (host
);
970 if ((! hostent
) && ((h_errno
!= TRY_AGAIN
) || (try_count
== 5)))
972 strcpy (pop_error
, "Could not determine POP server's address");
977 bzero ((char *) &addr
, sizeof (addr
));
978 addr
.sin_family
= AF_INET
;
981 service
= (flags
& POP_NO_KERBEROS
) ? POP_SERVICE
: KPOP_SERVICE
;
983 service
= POP_SERVICE
;
987 if (! (flags
& POP_NO_HESIOD
))
989 servent
= hes_getservbyname (service
, "tcp");
992 addr
.sin_port
= servent
->s_port
;
999 servent
= getservbyname (service
, "tcp");
1002 addr
.sin_port
= servent
->s_port
;
1007 addr
.sin_port
= htons ((flags
& POP_NO_KERBEROS
) ?
1008 POP_PORT
: KPOP_PORT
);
1010 addr
.sin_port
= htons (POP_PORT
);
1015 #define SOCKET_ERROR "Could not create socket for POP connection: "
1017 sock
= socket (PF_INET
, SOCK_STREAM
, 0);
1020 strcpy (pop_error
, SOCKET_ERROR
);
1021 strncat (pop_error
, strerror (errno
),
1022 ERROR_MAX
- sizeof (SOCKET_ERROR
));
1027 while (*hostent
->h_addr_list
)
1029 bcopy (*hostent
->h_addr_list
, (char *) &addr
.sin_addr
,
1031 if (! connect (sock
, (struct sockaddr
*) &addr
, sizeof (addr
)))
1033 hostent
->h_addr_list
++;
1036 #define CONNECT_ERROR "Could not connect to POP server: "
1038 if (! *hostent
->h_addr_list
)
1040 (void) close (sock
);
1041 strcpy (pop_error
, CONNECT_ERROR
);
1042 strncat (pop_error
, strerror (errno
),
1043 ERROR_MAX
- sizeof (CONNECT_ERROR
));
1049 #define KRB_ERROR "Kerberos error connecting to POP server: "
1050 if (! (flags
& POP_NO_KERBEROS
))
1055 if (rem
= krb5_cc_default (&ccdef
))
1058 strcpy (pop_error
, KRB_ERROR
);
1059 strncat (pop_error
, error_message (rem
),
1060 ERROR_MAX
- sizeof(KRB_ERROR
));
1061 (void) close (sock
);
1065 if (rem
= krb5_cc_get_principal (ccdef
, &client
))
1070 for (cp
= hostent
->h_name
; *cp
; cp
++)
1074 *cp
= tolower (*cp
);
1078 if (rem
= krb5_sname_to_principal (hostent
->h_name
, POP_SERVICE
,
1084 rem
= krb5_sendauth ((krb5_pointer
) &sock
, "KPOPV1.0", client
, server
,
1085 AP_OPTS_MUTUAL_REQUIRED
,
1086 0, /* no checksum */
1087 0, /* no creds, use ccache instead */
1089 0, /* don't need seq # */
1090 0, /* don't need subsession key */
1092 0); /* don't need reply */
1093 krb5_free_principal (server
);
1096 if (err_ret
&& err_ret
->text
.length
)
1098 strcpy (pop_error
, KRB_ERROR
);
1099 strncat (pop_error
, error_message (rem
),
1100 ERROR_MAX
- sizeof (KRB_ERROR
));
1101 strncat (pop_error
, " [server says '",
1102 ERROR_MAX
- strlen (pop_error
) - 1);
1103 strncat (pop_error
, err_ret
->text
.data
,
1104 min (ERROR_MAX
- strlen (pop_error
) - 1,
1105 err_ret
->text
.length
));
1106 strncat (pop_error
, "']",
1107 ERROR_MAX
- strlen (pop_error
) - 1);
1111 strcpy (pop_error
, KRB_ERROR
);
1112 strncat (pop_error
, error_message (rem
),
1113 ERROR_MAX
- sizeof (KRB_ERROR
));
1116 krb5_free_error (err_ret
);
1118 (void) close (sock
);
1122 ticket
= (KTEXT
) malloc (sizeof (KTEXT_ST
));
1123 rem
= krb_sendauth (0L, sock
, ticket
, "pop", hostent
->h_name
,
1124 (char *) krb_realmofhost (hostent
->h_name
),
1125 (unsigned long) 0, &msg_data
, &cred
, schedule
,
1126 (struct sockaddr_in
*) 0,
1127 (struct sockaddr_in
*) 0,
1129 free ((char *) ticket
);
1130 if (rem
!= KSUCCESS
)
1132 strcpy (pop_error
, KRB_ERROR
);
1133 strncat (pop_error
, krb_err_txt
[rem
],
1134 ERROR_MAX
- sizeof (KRB_ERROR
));
1135 (void) close (sock
);
1140 #endif /* KERBEROS */
1143 } /* socket_connection */
1148 * Purpose: Get a line of text from the connection and return a
1149 * pointer to it. The carriage return and linefeed at the end of
1150 * the line are stripped, but periods at the beginnings of lines
1151 * are NOT dealt with in any special way.
1154 * server The server from which to get the line of text.
1156 * Returns: A non-null pointer if successful, or a null pointer on any
1157 * error, with an error message copied into pop_error.
1159 * Notes: The line returned is overwritten with each call to getline.
1161 * Side effects: Closes the connection on error.
1167 #define GETLINE_ERROR "Error reading from server: "
1173 char *cp
= my_strstr (server
->buffer
+ server
->buffer_index
, "\r\n");
1179 found
= server
->buffer_index
;
1180 data_used
= (cp
+ 2) - server
->buffer
- found
;
1182 *cp
= '\0'; /* terminate the string to be returned */
1183 server
->data
-= data_used
;
1184 server
->buffer_index
+= data_used
;
1187 fprintf (stderr
, "<<< %s\n", server
->buffer
+ found
);
1188 return (server
->buffer
+ found
);
1192 bcopy (server
->buffer
+ server
->buffer_index
,
1193 server
->buffer
, server
->data
);
1194 server
->buffer_index
= 0;
1199 server
->buffer_index
= 0;
1204 if (server
->data
== server
->buffer_size
)
1206 server
->buffer_size
+= GETLINE_INCR
;
1207 server
->buffer
= realloc (server
->buffer
, server
->buffer_size
);
1208 if (! server
->buffer
)
1210 strcpy (pop_error
, "Out of memory in getline");
1215 ret
= read (server
->file
, server
->buffer
+ server
->data
,
1216 server
->buffer_size
- server
->data
- 1);
1219 strcpy (pop_error
, GETLINE_ERROR
);
1220 strncat (pop_error
, strerror (errno
),
1221 ERROR_MAX
- sizeof (GETLINE_ERROR
));
1227 strcpy (pop_error
, "Unexpected EOF from server in getline");
1234 server
->data
+= ret
;
1235 server
->buffer
[server
->data
] = '\0';
1237 cp
= my_strstr (server
->buffer
, "\r\n");
1240 int data_used
= (cp
+ 2) - server
->buffer
;
1242 server
->data
-= data_used
;
1243 server
->buffer_index
= data_used
;
1246 fprintf (stderr
, "<<< %s\n", server
->buffer
);
1247 return (server
->buffer
);
1256 * Function: sendline
1258 * Purpose: Sends a line of text to the POP server. The line of text
1259 * passed into this function should NOT have the carriage return
1260 * and linefeed on the end of it. Periods at beginnings of lines
1261 * will NOT be treated specially by this function.
1264 * server The server to which to send the text.
1265 * line The line of text to send.
1267 * Return value: Upon successful completion, a value of 0 will be
1268 * returned. Otherwise, a non-zero value will be returned, and
1269 * an error will be copied into pop_error.
1271 * Side effects: Closes the connection on error.
1274 sendline (server
, line
)
1278 #define SENDLINE_ERROR "Error writing to POP server: "
1281 ret
= fullwrite (server
->file
, line
, strlen (line
));
1283 { /* 0 indicates that a blank line was written */
1284 ret
= fullwrite (server
->file
, "\r\n", 2);
1290 strcpy (pop_error
, SENDLINE_ERROR
);
1291 strncat (pop_error
, strerror (errno
),
1292 ERROR_MAX
- sizeof (SENDLINE_ERROR
));
1297 fprintf (stderr
, ">>> %s\n", line
);
1303 * Procedure: fullwrite
1305 * Purpose: Just like write, but keeps trying until the entire string
1308 * Return value: Same as write. Pop_error is not set.
1311 fullwrite (fd
, buf
, nbytes
)
1320 while ((ret
= write (fd
, cp
, nbytes
)) > 0)
1332 * Purpose: Reads a line from the server. If the return indicator is
1333 * positive, return with a zero exit status. If not, return with
1334 * a negative exit status.
1337 * server The server to read from.
1339 * Returns: 0 for success, else for failure and puts error in pop_error.
1341 * Side effects: On failure, may make the connection unuseable.
1349 if (! (fromline
= getline (server
)))
1354 if (! strncmp (fromline
, "+OK", 3))
1356 else if (! strncmp (fromline
, "-ERR", 4))
1358 strncpy (pop_error
, fromline
, ERROR_MAX
);
1359 pop_error
[ERROR_MAX
-1] = '\0';
1365 "Unexpected response from server; expecting +OK or -ERR");
1373 * Function: gettermination
1375 * Purpose: Gets the next line and verifies that it is a termination
1376 * line (nothing but a dot).
1378 * Return value: 0 on success, non-zero with pop_error set on error.
1380 * Side effects: Closes the connection on error.
1383 gettermination (server
)
1388 fromserver
= getline (server
);
1392 if (strcmp (fromserver
, "."))
1395 "Unexpected response from server in gettermination");
1405 * Function pop_close
1407 * Purpose: Close a pop connection, sending a "RSET" command to try to
1408 * preserve any changes that were made and a "QUIT" command to
1409 * try to get the server to quit, but ignoring any responses that
1412 * Side effects: The server is unuseable after this function returns.
1413 * Changes made to the maildrop since the session was started (or
1414 * since the last pop_reset) may be lost.
1421 free ((char *) server
);
1427 * Function: pop_trash
1429 * Purpose: Like pop_close or pop_quit, but doesn't deallocate the
1430 * memory associated with the server. It is legal to call
1431 * pop_close or pop_quit after this function has been called.
1437 if (server
->file
>= 0)
1439 sendline (server
, "RSET");
1440 sendline (server
, "QUIT");
1442 close (server
->file
);
1446 free (server
->buffer
);
1452 /* Search in STRING for an occurrence of SUBSTRING
1453 and return a pointer to that occurrence.
1454 Return 0 if SUBSTRING does not occur in STRING. */
1457 my_strstr (string
, substring
)
1458 char *string
, *substring
;
1464 if (!strcmp (p
, substring
))
1471 #endif /* MAIL_USE_POP */