diff options
-rw-r--r-- | driver.c | 206 | ||||
-rw-r--r-- | etrn.c | 12 | ||||
-rw-r--r-- | fetchmail.c | 12 | ||||
-rw-r--r-- | fetchmail.h | 8 | ||||
-rw-r--r-- | imap.c | 52 | ||||
-rw-r--r-- | pop2.c | 22 | ||||
-rw-r--r-- | pop3.c | 48 | ||||
-rw-r--r-- | rcfile_y.y | 2 | ||||
-rw-r--r-- | smtp.c | 59 | ||||
-rw-r--r-- | smtp.h | 18 | ||||
-rw-r--r-- | socket.c | 56 | ||||
-rw-r--r-- | socket.h | 10 |
12 files changed, 251 insertions, 254 deletions
@@ -354,16 +354,16 @@ char *parse_received(struct query *ctl, char *bufp) } #endif /* HAVE_RES_SEARCH */ -static FILE *smtp_open(struct query *ctl) +int smtp_open(struct query *ctl) /* try to open a socket to the appropriate SMTP server for this query */ { struct idlist *idp; /* maybe it's time to close the socket in order to force delivery */ - if (ctl->batchlimit && ctl->smtp_sockfp && batchcount++ == ctl->batchlimit) + if (ctl->batchlimit && (ctl->smtp_socket != -1) && batchcount++ == ctl->batchlimit) { - fclose(ctl->smtp_sockfp); - ctl->smtp_sockfp = (FILE *)NULL; + close(ctl->smtp_socket); + ctl->smtp_socket = -1; batchcount = 0; } @@ -382,12 +382,12 @@ static FILE *smtp_open(struct query *ctl) */ /* if no socket to this host is already set up, try to open ESMTP */ - if (ctl->smtp_sockfp == (FILE *)NULL) + if (ctl->smtp_socket == -1) { - if ((ctl->smtp_sockfp = SockOpen(idp->id,SMTP_PORT))==(FILE *)NULL) + if ((ctl->smtp_socket = SockOpen(idp->id,SMTP_PORT)) == -1) continue; - else if (SMTP_ok(ctl->smtp_sockfp) != SM_OK - || SMTP_ehlo(ctl->smtp_sockfp, + else if (SMTP_ok(ctl->smtp_socket) != SM_OK + || SMTP_ehlo(ctl->smtp_socket, ctl->server.names->id, &ctl->server.esmtp_options) != SM_OK) { @@ -395,8 +395,8 @@ static FILE *smtp_open(struct query *ctl) * RFC 1869 warns that some listeners hang up on a failed EHLO, * so it's safest not to assume the socket will still be good. */ - fclose(ctl->smtp_sockfp); - ctl->smtp_sockfp = (FILE *)NULL; + close(ctl->smtp_socket); + ctl->smtp_socket = -1; } else { @@ -406,15 +406,15 @@ static FILE *smtp_open(struct query *ctl) } /* if opening for ESMTP failed, try SMTP */ - if (ctl->smtp_sockfp == (FILE *)NULL) + if (ctl->smtp_socket == -1) { - if ((ctl->smtp_sockfp = SockOpen(idp->id,SMTP_PORT))==(FILE *)NULL) + if ((ctl->smtp_socket = SockOpen(idp->id,SMTP_PORT)) == -1) continue; - else if (SMTP_ok(ctl->smtp_sockfp) != SM_OK - || SMTP_helo(ctl->smtp_sockfp, ctl->server.names->id) != SM_OK) + else if (SMTP_ok(ctl->smtp_socket) != SM_OK + || SMTP_helo(ctl->smtp_socket, ctl->server.names->id) != SM_OK) { - fclose(ctl->smtp_sockfp); - ctl->smtp_sockfp = (FILE *)NULL; + close(ctl->smtp_socket); + ctl->smtp_socket = -1; } else { @@ -424,12 +424,12 @@ static FILE *smtp_open(struct query *ctl) } } - return(ctl->smtp_sockfp); + return(ctl->smtp_socket); } -static int gen_readmsg(sockfp, len, delimited, ctl, realname) +static int gen_readmsg(sock, len, delimited, ctl, realname) /* read message content and ship to SMTP or MDA */ -FILE *sockfp; /* to which the server is connected */ +int sock; /* to which the server is connected */ long len; /* length of message */ int delimited; /* does the protocol use a message delimiter? */ struct query *ctl; /* query control record */ @@ -468,7 +468,7 @@ char *realname; /* real name of host */ line = xmalloc(sizeof(buf)); line[0] = '\0'; do { - if (!SockGets(buf, sizeof(buf)-1, sockfp)) + if (SockRead(sock, buf, sizeof(buf)-1) == -1) return(PS_SOCKET); /* lines may not be properly CRLF terminated; fix this for qmail */ @@ -491,7 +491,7 @@ char *realname; /* real name of host */ break; } while /* we may need to grab RFC822 continuations */ - ((ch = SockPeek(sockfp)) == ' ' || ch == '\t'); + ((ch = SockPeek(sock)) == ' ' || ch == '\t'); /* write the message size dots */ n = strlen(line); @@ -724,7 +724,7 @@ char *realname; /* real name of host */ int smtperr; /* build a connection to the SMTP listener */ - if (!ctl->mda && ((sinkfp = smtp_open(ctl)) == NULL)) + if (!ctl->mda && (smtp_open(ctl) == -1)) { free_str_list(&xmit_names); error(0, -1, "SMTP connect to %s failed", @@ -779,7 +779,7 @@ char *realname; /* real name of host */ ap = return_path; else if (from_offs == -1 || !(ap = nxtaddr(headers + from_offs))) ap = user; - if (SMTP_from(sinkfp, ap, options) != SM_OK) + if (SMTP_from(ctl->smtp_socket, ap, options) != SM_OK) { int smtperr = atoi(smtp_response); @@ -817,8 +817,7 @@ char *realname; /* real name of host */ * a future retrieval cycle. */ delete_ok = FALSE; - sinkfp = (FILE *)NULL; - SMTP_rset(sockfp); /* required by RFC1870 */ + SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ goto skiptext; case 552: /* message exceeds fixed maximum message size */ @@ -827,12 +826,11 @@ char *realname; /* real name of host */ * ESMTP server. Don't try to ship the message, * and allow it to be deleted. */ - sinkfp = (FILE *)NULL; - SMTP_rset(sockfp); /* required by RFC1870 */ + SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ goto skiptext; default: /* retry with invoking user's address */ - if (SMTP_from(sinkfp, user, options) != SM_OK) + if (SMTP_from(ctl->smtp_socket, user, options) != SM_OK) { error(0, -1, "SMTP error: %s", smtp_response); if (return_path) @@ -854,7 +852,7 @@ char *realname; /* real name of host */ */ for (idp = xmit_names; idp; idp = idp->next) if (idp->val.num == XMIT_ACCEPT) - if (SMTP_rcpt(sinkfp, idp->id) == SM_OK) + if (SMTP_rcpt(ctl->smtp_socket, idp->id) == SM_OK) good_addresses++; else { @@ -863,7 +861,7 @@ char *realname; /* real name of host */ error(0, 0, "SMTP listener doesn't like recipient address `%s'", idp->id); } - if (!good_addresses && SMTP_rcpt(sinkfp, user) != SM_OK) + if (!good_addresses && SMTP_rcpt(ctl->smtp_socket, user) != SM_OK) { error(0, 0, "can't even send to calling user!"); @@ -873,7 +871,7 @@ char *realname; /* real name of host */ } /* tell it we're ready to send data */ - SMTP_data(sinkfp); + SMTP_data(ctl->smtp_socket); skiptext:; if (return_path) @@ -898,7 +896,7 @@ char *realname; /* real name of host */ if (ctl->mda) n = fwrite(headers, 1, strlen(headers), sinkfp); else - n = SockWrite(headers, 1, strlen(headers), sinkfp); + n = SockWrite(ctl->smtp_socket, headers, strlen(headers)); if (n < 0) { @@ -989,21 +987,21 @@ char *realname; /* real name of host */ if (ctl->mda) fwrite(errmsg, sizeof(char), strlen(errmsg), sinkfp); else - SockWrite(errmsg, sizeof(char), strlen(errmsg), sinkfp); + SockWrite(ctl->smtp_socket, errmsg, strlen(errmsg)); } } free_str_list(&xmit_names); /* issue the delimiter line */ - if (sinkfp) + if (sinkfp && ctl->mda) + fputc('\n', sinkfp); + else if (ctl->smtp_socket != -1) { - if (ctl->mda) - fputc('\n', sinkfp); - else if (ctl->stripcr) - SockWrite("\n", sizeof(char), 1, sinkfp); + if (ctl->stripcr) + SockWrite(ctl->smtp_socket, "\n", 1); else - SockWrite("\r\n", sizeof(char), 2, sinkfp); + SockWrite(ctl->smtp_socket, "\r\n", 2); } /* @@ -1013,7 +1011,7 @@ char *realname; /* real name of host */ /* pass through the text lines */ while (delimited || remaining > 0) { - if (!SockGets(buf, sizeof(buf)-1, sockfp)) + if (SockRead(sock, buf, sizeof(buf)-1) == -1) return(PS_SOCKET); set_timeout(ctl->server.timeout); @@ -1048,45 +1046,44 @@ char *realname; /* real name of host */ break; /* ship out the text line */ - if (sinkfp) + + /* SMTP byte-stuffing */ + if (*buf == '.') + if (sinkfp && ctl->mda) + fputs(".", sinkfp); + else if (ctl->smtp_socket != -1) + SockWrite(ctl->smtp_socket, buf, 1); + + /* we may need to strip carriage returns */ + if (ctl->stripcr) { - /* SMTP byte-stuffing */ - if (*buf == '.') - if (ctl->mda) - fputs(".", sinkfp); - else - SockWrite(buf, 1, 1, sinkfp); + char *sp, *tp; - /* we may need to strip carriage returns */ - if (ctl->stripcr) - { - char *sp, *tp; + for (sp = tp = buf; *sp; sp++) + if (*sp != '\r') + *tp++ = *sp; + *tp = '\0'; + } - for (sp = tp = buf; *sp; sp++) - if (*sp != '\r') - *tp++ = *sp; - *tp = '\0'; - } + /* ship the text line */ + n = 0; + if (sinkfp && ctl->mda) + n = fwrite(buf, 1, strlen(buf), sinkfp); + else if (ctl->smtp_socket != -1) + n = SockWrite(ctl->smtp_socket, buf, strlen(buf)); - /* ship the text line */ + if (n < 0) + { + error(0, errno, "writing message text"); if (ctl->mda) - n = fwrite(buf, 1, strlen(buf), sinkfp); - else if (sinkfp) - n = SockWrite(buf, 1, strlen(buf), sinkfp); - - if (n < 0) { - error(0, errno, "writing message text"); - if (ctl->mda) - { - pclose(sinkfp); - signal(SIGCHLD, sigchld); - } - return(PS_IOERR); + pclose(sinkfp); + signal(SIGCHLD, sigchld); } - else if (outlevel == O_VERBOSE) - fputc('*', stderr); + return(PS_IOERR); } + else if (outlevel == O_VERBOSE) + fputc('*', stderr); } /* @@ -1109,10 +1106,10 @@ char *realname; /* real name of host */ return(PS_IOERR); } } - else if (sinkfp) + else if (ctl->smtp_socket != -1) { /* write message terminator */ - if (SMTP_eom(sinkfp) != SM_OK) + if (SMTP_eom(ctl->smtp_socket) != SM_OK) { error(0, -1, "SMTP listener refused delivery"); ctl->errcount++; @@ -1221,7 +1218,8 @@ const struct method *proto; /* protocol method table */ { char buf [POPBUFSIZE+1]; int *msgsizes, len, num, count, new, deletions = 0; - FILE *sockfp; + int sock, port; + /* execute pre-initialization command, if any */ if (ctl->preconnect && (ok = system(ctl->preconnect))) { @@ -1232,8 +1230,8 @@ const struct method *proto; /* protocol method table */ } /* open a socket to the mail server */ - if (!(sockfp = SockOpen(ctl->server.names->id, - ctl->server.port ? ctl->server.port : protocol->port))) + port = ctl->server.port ? ctl->server.port : protocol->port; + if ((sock = SockOpen(ctl->server.names->id, port)) == -1) { #ifndef EHOSTUNREACH #define EHOSTUNREACH (-1) @@ -1247,7 +1245,7 @@ const struct method *proto; /* protocol method table */ #ifdef KERBEROS_V4 if (ctl->server.authenticate == A_KERBEROS_V4) { - ok = kerberos_auth(fileno(sockfp), ctl->server.canonical_name); + ok = kerberos_auth(sock, ctl->server.canonical_name); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1255,7 +1253,7 @@ const struct method *proto; /* protocol method table */ #endif /* KERBEROS_V4 */ /* accept greeting message from mail server */ - ok = (protocol->parse_response)(sockfp, buf); + ok = (protocol->parse_response)(sock, buf); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1339,7 +1337,7 @@ const struct method *proto; /* protocol method table */ if (protocol->getauth) { shroud = ctl->password; - ok = (protocol->getauth)(sockfp, ctl, buf); + ok = (protocol->getauth)(sock, ctl, buf); shroud = (char *)NULL; if (ok == PS_ERROR) ok = PS_AUTHFAIL; @@ -1354,7 +1352,7 @@ const struct method *proto; /* protocol method table */ } /* compute number of messages and number of new messages waiting */ - ok = (protocol->getrange)(sockfp, ctl, &count, &new); + ok = (protocol->getrange)(sock, ctl, &count, &new); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1389,7 +1387,7 @@ const struct method *proto; /* protocol method table */ { msgsizes = (int *)alloca(sizeof(int) * count); - ok = (proto->getsizes)(sockfp, count, msgsizes); + ok = (proto->getsizes)(sock, count, msgsizes); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1437,7 +1435,7 @@ const struct method *proto; /* protocol method table */ { int toolarge = msgsizes && (msgsizes[num-1] > ctl->limit); int fetch_it = ctl->fetchall || - (!toolarge && (force_retrieval || !(protocol->is_old && (protocol->is_old)(sockfp,ctl,num)))); + (!toolarge && (force_retrieval || !(protocol->is_old && (protocol->is_old)(sock,ctl,num)))); int suppress_delete = FALSE; /* we may want to reject this message if it's old */ @@ -1453,7 +1451,7 @@ const struct method *proto; /* protocol method table */ else { /* request a message */ - ok = (protocol->fetch)(sockfp, ctl, num, &len); + ok = (protocol->fetch)(sock, ctl, num, &len); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1470,7 +1468,7 @@ const struct method *proto; /* protocol method table */ } /* read the message and ship it to the output sink */ - ok = gen_readmsg(sockfp, + ok = gen_readmsg(sock, len, protocol->delimited, ctl, @@ -1484,7 +1482,7 @@ const struct method *proto; /* protocol method table */ /* tell the server we got it OK and resynchronize */ if (protocol->trail) { - ok = (protocol->trail)(sockfp, ctl, num); + ok = (protocol->trail)(sock, ctl, num); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1510,7 +1508,7 @@ const struct method *proto; /* protocol method table */ deletions++; if (outlevel > O_SILENT) error_complete(0, 0, " flushed"); - ok = (protocol->delete)(sockfp, ctl, num); + ok = (protocol->delete)(sock, ctl, num); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1524,28 +1522,28 @@ const struct method *proto; /* protocol method table */ break; } - ok = gen_transact(sockfp, protocol->exit_cmd); + ok = gen_transact(sock, protocol->exit_cmd); if (ok == 0) ok = (fetches > 0) ? PS_SUCCESS : PS_NOMAIL; set_timeout(0); - fclose(sockfp); + close(sock); goto closeUp; } else { - ok = gen_transact(sockfp, protocol->exit_cmd); + ok = gen_transact(sock, protocol->exit_cmd); if (ok == 0) ok = PS_NOMAIL; set_timeout(0); - fclose(sockfp); + close(sock); goto closeUp; } cleanUp: set_timeout(ctl->server.timeout); if (ok != 0 && ok != PS_SOCKET) - gen_transact(sockfp, protocol->exit_cmd); + gen_transact(sock, protocol->exit_cmd); set_timeout(0); - fclose(sockfp); + close(sock); } switch (ok) @@ -1585,12 +1583,12 @@ closeUp: } #if defined(HAVE_STDARG_H) -void gen_send(FILE *sockfp, char *fmt, ... ) +void gen_send(int sock, char *fmt, ... ) /* assemble command in printf(3) style and send to the server */ #else -void gen_send(sockfp, fmt, va_alist) +void gen_send(sock, fmt, va_alist) /* assemble command in printf(3) style and send to the server */ -FILE *sockfp; /* socket to which server is connected */ +int sock; /* socket to which server is connected */ const char *fmt; /* printf-style format */ va_dcl #endif @@ -1612,7 +1610,7 @@ va_dcl va_end(ap); strcat(buf, "\r\n"); - SockWrite(buf, 1, strlen(buf), sockfp); + SockWrite(sock, buf, strlen(buf)); if (outlevel == O_VERBOSE) { @@ -1633,13 +1631,13 @@ va_dcl } } -int gen_recv(sockfp, buf, size) +int gen_recv(sock, buf, size) /* get one line of input from the server */ -FILE *sockfp; /* socket to which server is connected */ +int sock; /* socket to which server is connected */ char *buf; /* buffer to receive input */ int size; /* length of buffer */ { - if (!SockGets(buf, size, sockfp)) + if (SockRead(sock, buf, size) == -1) return(PS_SOCKET); else { @@ -1654,12 +1652,12 @@ int size; /* length of buffer */ } #if defined(HAVE_STDARG_H) -int gen_transact(FILE *sockfp, char *fmt, ... ) +int gen_transact(int sock, char *fmt, ... ) /* assemble command in printf(3) style, send to server, accept a response */ #else -int gen_transact(sockfp, fmt, va_alist) +int gen_transact(int sock, fmt, va_alist) /* assemble command in printf(3) style, send to server, accept a response */ -FILE *sockfp; /* socket to which server is connected */ +int sock; /* socket to which server is connected */ const char *fmt; /* printf-style format */ va_dcl #endif @@ -1682,7 +1680,7 @@ va_dcl va_end(ap); strcat(buf, "\r\n"); - SockWrite(buf, 1, strlen(buf), sockfp); + SockWrite(sock, buf, strlen(buf)); if (outlevel == O_VERBOSE) { @@ -1703,7 +1701,7 @@ va_dcl } /* we presume this does its own response echoing */ - ok = (protocol->parse_response)(sockfp, buf); + ok = (protocol->parse_response)(sock, buf); set_timeout(mytimeout); return(ok); @@ -10,26 +10,26 @@ #include "smtp.h" #include "socket.h" -static int etrn_ok (FILE *sockfp, char *argbuf) +static int etrn_ok (int sock, char *argbuf) /* parse command response */ { int ok; char buf [POPBUFSIZE+1]; - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); if (ok == SM_UNRECOVERABLE) return(PS_PROTOCOL); else return(ok); } -static int etrn_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) +static int etrn_getrange(int sock, struct query *ctl, int*countp, int*newp) /* send ETRN and interpret the response */ { int ok, opts; char buf [POPBUFSIZE+1]; - if ((ok = SMTP_ehlo(sockfp, ctl->server.names->id, &opts))) + if ((ok = SMTP_ehlo(sock, ctl->server.names->id, &opts))) { error(0, 0, "%s's SMTP listener does not support ESMTP", ctl->server.names->id); @@ -45,8 +45,8 @@ static int etrn_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) *countp = *newp = -1; /* make sure we don't enter the fetch loop */ /* ship the actual poll and get the response */ - gen_send(sockfp, "ETRN %s", ctl->smtphost); - if (ok = gen_recv(sockfp, buf, sizeof(buf))) + gen_send(sock, "ETRN %s", ctl->smtphost); + if (ok = gen_recv(sock, buf, sizeof(buf))) return(ok); /* this switch includes all the response codes described in RFC1985 */ diff --git a/fetchmail.c b/fetchmail.c index fefa06d6..7befcce9 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -463,11 +463,11 @@ int main (int argc, char **argv) * deliver it until the input socket is closed. */ for (ctl = querylist; ctl; ctl = ctl->next) - if (ctl->smtp_sockfp) + if (ctl->smtp_socket != -1) { - SMTP_quit(ctl->smtp_sockfp); - fclose(ctl->smtp_sockfp); - ctl->smtp_sockfp = (FILE *)NULL; + SMTP_quit(ctl->smtp_socket); + close(ctl->smtp_socket); + ctl->smtp_socket = -1; } /* @@ -712,8 +712,8 @@ void termhook(int sig) else /* terminate all SMTP connections cleanly */ for (ctl = querylist; ctl; ctl = ctl->next) - if (ctl->smtp_sockfp != (FILE *)NULL) - SMTP_quit(ctl->smtp_sockfp); + if (ctl->smtp_socket != -1) + SMTP_quit(ctl->smtp_socket); if (!check_only) write_saved_lists(querylist, idfile); diff --git a/fetchmail.h b/fetchmail.h index 10597a6a..3dc569a3 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -126,7 +126,7 @@ struct query int active; int errcount; /* count transient errors in last pass */ struct query *next; /* next query control block in chain */ - FILE *smtp_sockfp; /* socket descriptor for SMTP connection */ + int smtp_socket; /* socket descriptor for SMTP connection */ unsigned int uid; /* UID of user to deliver to */ char digest [DIGESTLEN]; /* md5 digest buffer */ }; @@ -189,9 +189,9 @@ void error_init(int foreground); void error (int status, int errnum, const char *format, ...); void error_build (const char *format, ...); void error_complete (int status, int errnum, const char *format, ...); -void gen_send (FILE *sockfp, char *, ... ); -int gen_recv(FILE *sockfp, char *buf, int size); -int gen_transact (FILE *sockfp, char *, ... ); +void gen_send (int sock, char *, ... ); +int gen_recv(int sock, char *buf, int size); +int gen_transact (int sock, char *, ... ); #else void error (); void error_build (); @@ -25,7 +25,7 @@ extern char *strstr(); /* needed on sysV68 R3V7.1. */ static int count, seen, recent, unseen, deletecount, imap_version; -int imap_ok (FILE *sockfp, char *argbuf) +int imap_ok (int sock, char *argbuf) /* parse command response */ { char buf [POPBUFSIZE+1]; @@ -34,7 +34,7 @@ int imap_ok (FILE *sockfp, char *argbuf) do { int ok; - if (ok = gen_recv(sockfp, buf, sizeof(buf))) + if (ok = gen_recv(sock, buf, sizeof(buf))) return(ok); /* interpret untagged status responses */ @@ -76,13 +76,13 @@ int imap_ok (FILE *sockfp, char *argbuf) } } -int imap_getauth(FILE *sockfp, struct query *ctl, char *buf) +int imap_getauth(int sock, struct query *ctl, char *buf) /* apply for connection authorization */ { char rbuf [POPBUFSIZE+1]; /* try to get authorized */ - int ok = gen_transact(sockfp, + int ok = gen_transact(sock, "LOGIN %s \"%s\"", ctl->remotename, ctl->password); @@ -90,8 +90,8 @@ int imap_getauth(FILE *sockfp, struct query *ctl, char *buf) return(ok); /* probe to see if we're running IMAP4 and can use RFC822.PEEK */ - gen_send(sockfp, "CAPABILITY"); - if (ok = gen_recv(sockfp, rbuf, sizeof(rbuf))) + gen_send(sock, "CAPABILITY"); + if (ok = gen_recv(sock, rbuf, sizeof(rbuf))) return(ok); if (strstr(rbuf, "BAD")) { @@ -117,14 +117,14 @@ int imap_getauth(FILE *sockfp, struct query *ctl, char *buf) return(PS_SUCCESS); } -static int imap_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) +static int imap_getrange(int sock, struct query *ctl, int*countp, int*newp) /* get range of messages to be fetched */ { int ok; /* find out how many messages are waiting */ recent = unseen = 0; - ok = gen_transact(sockfp, + ok = gen_transact(sock, "SELECT %s", ctl->mailbox ? ctl->mailbox : "INBOX"); if (ok != 0) @@ -147,17 +147,17 @@ static int imap_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) return(PS_SUCCESS); } -static int imap_getsizes(FILE *sockfp, int count, int *sizes) +static int imap_getsizes(int sock, int count, int *sizes) /* capture the sizes of all messages */ { char buf [POPBUFSIZE+1]; - gen_send(sockfp, "FETCH 1:%d RFC822.SIZE", count); - while (SockGets(buf, sizeof(buf), sockfp)) + gen_send(sock, "FETCH 1:%d RFC822.SIZE", count); + while (SockRead(sock, buf, sizeof(buf))) { int num, size, ok; - if (ok = gen_recv(sockfp, buf, sizeof(buf))) + if (ok = gen_recv(sock, buf, sizeof(buf))) return(ok); if (strstr(buf, "OK")) break; @@ -170,7 +170,7 @@ static int imap_getsizes(FILE *sockfp, int count, int *sizes) return(PS_SUCCESS); } -static int imap_is_old(FILE *sockfp, struct query *ctl, int number) +static int imap_is_old(int sock, struct query *ctl, int number) /* is the given message old? */ { int ok; @@ -178,13 +178,13 @@ static int imap_is_old(FILE *sockfp, struct query *ctl, int number) /* expunges change the fetch numbers */ number -= deletecount; - if ((ok = gen_transact(sockfp, "FETCH %d FLAGS", number)) != 0) + if ((ok = gen_transact(sock, "FETCH %d FLAGS", number)) != 0) return(PS_ERROR); return(seen); } -static int imap_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) +static int imap_fetch(int sock, struct query *ctl, int number, int *lenp) /* request nth message */ { char buf [POPBUFSIZE+1], *fetch; @@ -207,20 +207,20 @@ static int imap_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) { case IMAP4rev1: /* RFC 2060 */ if (!ctl->keep) - gen_send(sockfp, "FETCH %d BODY.PEEK[]", number); + gen_send(sock, "FETCH %d BODY.PEEK[]", number); else - gen_send(sockfp, "FETCH %d BODY", number); + gen_send(sock, "FETCH %d BODY", number); break; case IMAP4: /* RFC 1730 */ if (!ctl->keep) - gen_send(sockfp, "FETCH %d RFC822.PEEK", number); + gen_send(sock, "FETCH %d RFC822.PEEK", number); else - gen_send(sockfp, "FETCH %d RFC822", number); + gen_send(sock, "FETCH %d RFC822", number); break; default: /* RFC 1176 */ - gen_send(sockfp, "FETCH %d RFC822", number); + gen_send(sock, "FETCH %d RFC822", number); break; } @@ -228,7 +228,7 @@ static int imap_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) do { int ok; - if (ok = gen_recv(sockfp, buf, sizeof(buf))) + if (ok = gen_recv(sock, buf, sizeof(buf))) return(ok); } while /* third token can be "RFC822" or "BODY[]" */ @@ -240,7 +240,7 @@ static int imap_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) return(PS_SUCCESS); } -static int imap_trail(FILE *sockfp, struct query *ctl, int number) +static int imap_trail(int sock, struct query *ctl, int number) /* discard tail of FETCH response after reading message text */ { char buf [POPBUFSIZE+1]; @@ -248,10 +248,10 @@ static int imap_trail(FILE *sockfp, struct query *ctl, int number) /* expunges change the fetch numbers */ /* number -= deletecount; */ - return(gen_recv(sockfp, buf, sizeof(buf))); + return(gen_recv(sock, buf, sizeof(buf))); } -static int imap_delete(FILE *sockfp, struct query *ctl, int number) +static int imap_delete(int sock, struct query *ctl, int number) /* set delete flag for given message */ { int ok; @@ -263,7 +263,7 @@ static int imap_delete(FILE *sockfp, struct query *ctl, int number) * Use SILENT if possible as a minor throughput optimization. * Note: this has been dropped from IMAP4rev1. */ - if ((ok = gen_transact(sockfp, + if ((ok = gen_transact(sock, imap_version == IMAP4 ? "STORE %d +FLAGS.SILENT (\\Deleted)" : "STORE %d +FLAGS (\\Deleted)", @@ -275,7 +275,7 @@ static int imap_delete(FILE *sockfp, struct query *ctl, int number) * so that a line hit during a long session won't result in lots of * messages being fetched again during the next session. */ - if ((ok = gen_transact(sockfp, "EXPUNGE"))) + if ((ok = gen_transact(sock, "EXPUNGE"))) return(ok); deletecount++; @@ -16,7 +16,7 @@ static int pound_arg, equal_arg; -int pop2_ok (FILE *sockfp, char *argbuf) +int pop2_ok (int sock, char *argbuf) /* parse POP2 command response */ { int ok; @@ -24,7 +24,7 @@ int pop2_ok (FILE *sockfp, char *argbuf) pound_arg = equal_arg = -1; - if ((ok = gen_recv(sockfp, buf, sizeof(buf))) == 0) + if ((ok = gen_recv(sock, buf, sizeof(buf))) == 0) { if (buf[0] == '+') ok = 0; @@ -50,15 +50,15 @@ int pop2_ok (FILE *sockfp, char *argbuf) return(ok); } -int pop2_getauth(FILE *sockfp, struct query *ctl, char *buf) +int pop2_getauth(int sock, struct query *ctl, char *buf) /* apply for connection authorization */ { - return(gen_transact(sockfp, + return(gen_transact(sock, "HELO %s %s", ctl->remotename, ctl->password)); } -static int pop2_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) +static int pop2_getrange(int sock, struct query *ctl, int*countp, int*newp) /* get range of messages to be fetched */ { /* @@ -71,7 +71,7 @@ static int pop2_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) /* maybe the user wanted a non-default folder */ if (ctl->mailbox) { - int ok = gen_transact(sockfp, "FOLD %s", ctl->mailbox); + int ok = gen_transact(sock, "FOLD %s", ctl->mailbox); if (ok != 0) return(ok); @@ -85,26 +85,26 @@ static int pop2_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) return(0); } -static int pop2_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) +static int pop2_fetch(int sock, struct query *ctl, int number, int *lenp) /* request nth message */ { int ok; *lenp = 0; - ok = gen_transact(sockfp, "READ %d", number); + ok = gen_transact(sock, "READ %d", number); if (ok) return(0); *lenp = equal_arg; - gen_send(sockfp, "RETR"); + gen_send(sock, "RETR"); return(ok); } -static int pop2_trail(FILE *sockfp, struct query *ctl, int number) +static int pop2_trail(int sock, struct query *ctl, int number) /* send acknowledgement for message data */ { - return(gen_transact(sockfp, ctl->keep ? "ACKS" : "ACKD")); + return(gen_transact(sock, ctl->keep ? "ACKS" : "ACKD")); } const static struct method pop2 = @@ -25,14 +25,14 @@ extern char *strstr(); /* needed on sysV68 R3V7.1. */ static int last; -int pop3_ok (FILE *sockfp, char *argbuf) +int pop3_ok (int sock, char *argbuf) /* parse command response */ { int ok; char buf [POPBUFSIZE+1]; char *bufp; - if ((ok = gen_recv(sockfp, buf, sizeof(buf))) == 0) + if ((ok = gen_recv(sock, buf, sizeof(buf))) == 0) { bufp = buf; if (*bufp == '+' || *bufp == '-') @@ -58,7 +58,7 @@ int pop3_ok (FILE *sockfp, char *argbuf) return(ok); } -int pop3_getauth(FILE *sockfp, struct query *ctl, char *greeting) +int pop3_getauth(int sock, struct query *ctl, char *greeting) /* apply for connection authorization */ { /* build MD5 digest from greeting timestamp + password */ @@ -96,24 +96,24 @@ int pop3_getauth(FILE *sockfp, struct query *ctl, char *greeting) switch (ctl->server.protocol) { case P_POP3: - if ((gen_transact(sockfp, "USER %s", ctl->remotename)) != 0) + if ((gen_transact(sock, "USER %s", ctl->remotename)) != 0) PROTOCOL_ERROR - if ((gen_transact(sockfp, "PASS %s", ctl->password)) != 0) + if ((gen_transact(sock, "PASS %s", ctl->password)) != 0) PROTOCOL_ERROR break; case P_APOP: - if ((gen_transact(sockfp, "APOP %s %s", + if ((gen_transact(sock, "APOP %s %s", ctl->remotename, ctl->digest)) != 0) PROTOCOL_ERROR break; case P_RPOP: - if ((gen_transact(sockfp,"USER %s", ctl->remotename)) != 0) + if ((gen_transact(sock,"USER %s", ctl->remotename)) != 0) PROTOCOL_ERROR - if ((gen_transact(sockfp, "RPOP %s", ctl->password)) != 0) + if ((gen_transact(sock, "RPOP %s", ctl->password)) != 0) PROTOCOL_ERROR break; @@ -125,7 +125,7 @@ int pop3_getauth(FILE *sockfp, struct query *ctl, char *greeting) return(0); } -static int pop3_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) +static int pop3_getrange(int sock, struct query *ctl, int*countp, int*newp) /* get range of messages to be fetched */ { int ok; @@ -135,8 +135,8 @@ static int pop3_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) ctl->newsaved = (struct idlist *)NULL; /* get the total message count */ - gen_send(sockfp, "STAT"); - ok = pop3_ok(sockfp, buf); + gen_send(sock, "STAT"); + ok = pop3_ok(sock, buf); if (ok == 0) sscanf(buf,"%d %*d", countp); else @@ -154,8 +154,8 @@ static int pop3_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) char id [IDLEN+1]; if (!ctl->server.uidl) { - gen_send(sockfp,"LAST"); - ok = pop3_ok(sockfp, buf); + gen_send(sock, "LAST"); + ok = pop3_ok(sock, buf); } else ok = 1; if (ok == 0) @@ -167,14 +167,14 @@ static int pop3_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) else { /* grab the mailbox's UID list */ - if ((ok = gen_transact(sockfp, "UIDL")) != 0) + if ((ok = gen_transact(sock, "UIDL")) != 0) PROTOCOL_ERROR else { int num; *newp = 0; - while ((ok = gen_recv(sockfp, buf, sizeof(buf))) == 0) + while ((ok = gen_recv(sock, buf, sizeof(buf))) == 0) { if (buf[0] == '.') break; @@ -194,18 +194,18 @@ static int pop3_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp) return(0); } -static int pop3_getsizes(FILE *sockfp, int count, int *sizes) +static int pop3_getsizes(int sock, int count, int *sizes) /* capture the sizes of all messages */ { int ok; - if ((ok = gen_transact(sockfp, "LIST")) != 0) + if ((ok = gen_transact(sock, "LIST")) != 0) return(ok); else { char buf [POPBUFSIZE+1]; - while ((ok = gen_recv(sockfp, buf, sizeof(buf))) == 0) + while ((ok = gen_recv(sock, buf, sizeof(buf))) == 0) { int num, size; @@ -221,7 +221,7 @@ static int pop3_getsizes(FILE *sockfp, int count, int *sizes) } } -static int pop3_is_old(FILE *sockfp, struct query *ctl, int num) +static int pop3_is_old(int sock, struct query *ctl, int num) /* is the given message old? */ { if (!ctl->oldsaved) @@ -232,14 +232,14 @@ static int pop3_is_old(FILE *sockfp, struct query *ctl, int num) str_find (&ctl->newsaved, num))); } -static int pop3_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) +static int pop3_fetch(int sock, struct query *ctl, int number, int *lenp) /* request nth message */ { int ok; char buf [POPBUFSIZE+1], *cp; - gen_send(sockfp, "RETR %d", number); - if ((ok = pop3_ok(sockfp, buf)) != 0) + gen_send(sock, "RETR %d", number); + if ((ok = pop3_ok(sock, buf)) != 0) return(ok); /* look for "nnn octets" -- there may or may not be preceding cruft */ if ((cp = strstr(buf, " octets")) == (char *)NULL) @@ -253,10 +253,10 @@ static int pop3_fetch(FILE *sockfp, struct query *ctl, int number, int *lenp) return(0); } -static int pop3_delete(FILE *sockfp, struct query *ctl, int number) +static int pop3_delete(int sock, struct query *ctl, int number) /* delete a given message */ { - return(gen_transact(sockfp, "DELE %d", number)); + return(gen_transact(sock, "DELE %d", number)); } const static struct method pop3 = @@ -330,6 +330,7 @@ static int reset_server(char *name, int skip) return(FALSE); memset(¤t,'\0',sizeof(current)); + current.smtp_socket = -1; save_str(¤t.server.names, -1, name); current.server.skip = skip; return(TRUE); @@ -350,6 +351,7 @@ static void user_reset(void) save = current.server; memset(¤t, '\0', sizeof(current)); + current.smtp_socket = -1; current.server = save; } @@ -33,33 +33,32 @@ static struct opt extensions[] = char smtp_response[MSGBUFSIZE]; -int SMTP_helo(FILE *sockfp,char *host) +int SMTP_helo(int sock,char *host) /* send a "HELO" message to the SMTP listener */ { int ok; - SockPrintf(sockfp,"HELO %s\r\n", host); + SockPrintf(sock,"HELO %s\r\n", host); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> HELO %s", host); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_ehlo(FILE *sockfp, char *host, int *opt) +int SMTP_ehlo(int sock, char *host, int *opt) /* send a "EHLO" message to the SMTP listener, return extension status bits */ { int ok; - char *ip; struct opt *hp; - SockPrintf(sockfp,"EHLO %s\r\n", host); + SockPrintf(sock,"EHLO %s\r\n", host); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> EHLO %s", host); *opt = 0; - while ((ip = SockGets(smtp_response, sizeof(smtp_response)-1, sockfp))) + while ((SockRead(sock, smtp_response, sizeof(smtp_response)-1)) != -1) { - int n = strlen(ip); + int n = strlen(smtp_response); if (smtp_response[strlen(smtp_response)-1] == '\n') smtp_response[strlen(smtp_response)-1] = '\0'; @@ -81,7 +80,7 @@ int SMTP_ehlo(FILE *sockfp, char *host, int *opt) return SM_UNRECOVERABLE; } -int SMTP_from(FILE *sockfp, char *from, char *opts) +int SMTP_from(int sock, char *from, char *opts) /* send a "MAIL FROM:" message to the SMTP listener */ { int ok; @@ -91,81 +90,79 @@ int SMTP_from(FILE *sockfp, char *from, char *opts) sprintf(buf, "MAIL FROM:<%s>", from); if (opts) strcat(buf, opts); - SockPrintf(sockfp,"%s\r\n", buf); + SockPrintf(sock,"%s\r\n", buf); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> %s", buf); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_rcpt(FILE *sockfp, char *to) +int SMTP_rcpt(int sock, char *to) /* send a "RCPT TO:" message to the SMTP listener */ { int ok; - SockPrintf(sockfp,"RCPT TO:<%s>\r\n", to); + SockPrintf(sock,"RCPT TO:<%s>\r\n", to); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> RCPT TO:<%s>", to); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_data(FILE *sockfp) +int SMTP_data(int sock) /* send a "DATA" message to the SMTP listener */ { int ok; - SockPrintf(sockfp,"DATA\r\n"); + SockPrintf(sock,"DATA\r\n"); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> DATA"); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_rset(FILE *sockfp) +int SMTP_rset(int sock) /* send a "RSET" message to the SMTP listener */ { int ok; - SockPrintf(sockfp,"RSET\r\n"); + SockPrintf(sock,"RSET\r\n"); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> RSET"); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_quit(FILE *sockfp) +int SMTP_quit(int sock) /* send a "QUIT" message to the SMTP listener */ { int ok; - SockPrintf(sockfp,"QUIT\r\n"); + SockPrintf(sock,"QUIT\r\n"); if (outlevel == O_VERBOSE) error(0, 0, "SMTP> QUIT"); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_eom(FILE *sockfp) +int SMTP_eom(int sock) /* send a message data terminator to the SMTP listener */ { int ok; - SockPrintf(sockfp,".\r\n"); + SockPrintf(sock,".\r\n"); if (outlevel == O_VERBOSE) error(0, 0, "SMTP>. (EOM)"); - ok = SMTP_ok(sockfp); + ok = SMTP_ok(sock); return ok; } -int SMTP_ok(FILE *sockfp) +int SMTP_ok(int sock) /* returns status of SMTP connection */ { - char *ip; - - while ((ip = SockGets(smtp_response, sizeof(smtp_response)-1, sockfp))) + while ((SockRead(sock, smtp_response, sizeof(smtp_response)-1)) != -1) { - int n = strlen(ip); + int n = strlen(smtp_response); if (smtp_response[strlen(smtp_response)-1] == '\n') smtp_response[strlen(smtp_response)-1] = '\0'; @@ -19,15 +19,15 @@ #define ESMTP_SIZE 0x02 #define ESMTP_ETRN 0x04 -int SMTP_helo(FILE *sockfp,char *host); -int SMTP_ehlo(FILE *sockfp,char *host,int *opt); -int SMTP_from(FILE *sockfp,char *from,char *opts); -int SMTP_rcpt(FILE *sockfp,char *to); -int SMTP_data(FILE *sockfp); -int SMTP_eom(FILE *sockfp); -int SMTP_rset(FILE *sockfp); -int SMTP_quit(FILE *sockfp); -int SMTP_ok(FILE *sockfp); +int SMTP_helo(int socket,char *host); +int SMTP_ehlo(int socket,char *host,int *opt); +int SMTP_from(int socket,char *from,char *opts); +int SMTP_rcpt(int socket,char *to); +int SMTP_data(int socket); +int SMTP_eom(int socket); +int SMTP_rset(int socket); +int SMTP_quit(int socket); +int SMTP_ok(int socket); extern char smtp_response[MSGBUFSIZE]; @@ -38,7 +38,7 @@ #include <memory.h> #endif -FILE *SockOpen(char *host, int clientPort) +int SockOpen(char *host, int clientPort) { int sock; unsigned long inaddr; @@ -55,30 +55,30 @@ FILE *SockOpen(char *host, int clientPort) { hp = gethostbyname(host); if (hp == NULL) - return (FILE *)NULL; + return -1; memcpy(&ad.sin_addr, hp->h_addr, hp->h_length); } ad.sin_port = htons(clientPort); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) - return (FILE *)NULL; + return -1; if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) { close(sock); - return (FILE *)NULL; + return -1; } - return fdopen(sock, "r+"); + return(sock); } #if defined(HAVE_STDARG_H) -int SockPrintf(FILE *sockfp, char* format, ...) +int SockPrintf(int sock, char* format, ...) { #else -int SockPrintf(sockfp,format,va_alist) -FILE *sockfp; +int SockPrintf(sock,format,va_alist) +int sock; char *format; va_dcl { #endif @@ -93,18 +93,17 @@ va_dcl { #endif vsprintf(buf, format, ap); va_end(ap); - return SockWrite(buf, 1, strlen(buf), sockfp); + return SockWrite(sock, buf, strlen(buf)); } -int SockWrite(char *buf, int size, int len, FILE *sockfp) +int SockWrite(int sock, char *buf, int len) { int n, wrlen = 0; - len *= size; while (len) { - n = write(fileno(sockfp), buf, len); + n = write(sock, buf, len); if (n <= 0) return -1; len -= n; @@ -114,40 +113,41 @@ int SockWrite(char *buf, int size, int len, FILE *sockfp) return wrlen; } -char *SockGets(char *buf, int len, FILE *sockfp) +int SockRead(int sock, char *buf, int len) { char *p, *bp = buf; int n; if (--len < 1) - return NULL; + return(-1); do { /* return value of 0 is EOF, < 0 is error */ - if ((n = recv(fileno(sockfp), bp, len, MSG_PEEK)) <= 0) - return NULL; + if ((n = recv(sock, bp, len, MSG_PEEK)) <= 0) + return(-1); if ((p = memchr(bp, '\n', n)) != NULL) { - if (read(fileno(sockfp), bp, ++p - bp) == -1) - return NULL; + if (read(sock, bp, ++p - bp) == -1) + return(-1); *p = '\0'; - return buf; + return strlen(buf); } - if ((n = read(fileno(sockfp), bp, n)) == -1) - return NULL; + if ((n = read(sock, bp, n)) == -1) + return(-1); bp += n; len -= n; - } while (len); + } while + (len); *bp = '\0'; - return buf; + return strlen(buf); } -int SockPeek(FILE *sockfp) +int SockPeek(int sock) /* peek at the next socket character without actually reading it */ { int n; char ch; - if ((n = recv(fileno(sockfp), &ch, 1, MSG_PEEK)) == -1) + if ((n = recv(sock, &ch, 1, MSG_PEEK)) == -1) return -1; else return(ch); @@ -161,11 +161,11 @@ int SockPeek(FILE *sockfp) */ main() { - FILE *fp = SockOpen("localhost", 19); + int sock = SockOpen("localhost", 19); char buf[80]; - while (SockGets(buf, sizeof(buf)-1, fp)) - SockWrite(buf, 1, strlen(buf), stdout); + while (SockRead(sock, buf, sizeof(buf)-1)) + SockWrite(1, buf, strlen(buf)); } #endif /* MAIN */ @@ -8,7 +8,7 @@ #define SOCKET__ /* Create a new client socket; returns (FILE *)NULL on error */ -FILE *SockOpen(char *host, int clientPort); +int SockOpen(char *host, int clientPort); /* Get a string terminated by an '\n' (matches interface of fgets). @@ -16,25 +16,25 @@ Pass it a valid socket, a buffer for the string, and the length of the buffer (including the trailing \0) returns buffer on success, NULL on failure. */ -char *SockGets(char *buf, int len, FILE *sockfp); +int SockRead(int sock, char *buf, int len); /* * Peek at the next socket character without actually reading it. */ -int SockPeek(FILE *sockfp); +int SockPeek(int sock); /* Write a chunk of bytes to the socket (matches interface of fwrite). Returns number of bytes successfully written. */ -int SockWrite(char *buf, int size, int nels, FILE *sockfp); +int SockWrite(int sock, char *buf, int size); /* Send formatted output to the socket (matches interface of fprintf). Returns number of bytes successfully written. */ #if defined(HAVE_STDARG_H) -int SockPrintf(FILE *sockfp, char *format, ...) ; +int SockPrintf(int sock, char *format, ...) ; #else int SockPrintf(); #endif |