diff options
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | conf.c | 2 | ||||
-rw-r--r-- | daemon.c | 2 | ||||
-rw-r--r-- | driver.c | 90 | ||||
-rw-r--r-- | env.c | 2 | ||||
-rw-r--r-- | etrn.c | 2 | ||||
-rw-r--r-- | fetchmail.c | 75 | ||||
-rw-r--r-- | fetchmail.h | 59 | ||||
-rw-r--r-- | fetchmail.man | 50 | ||||
-rw-r--r-- | getpass.c | 22 | ||||
-rw-r--r-- | imap.c | 8 | ||||
-rw-r--r-- | md5ify.c | 3 | ||||
-rw-r--r-- | netrc.c | 7 | ||||
-rw-r--r-- | options.c | 6 | ||||
-rw-r--r-- | rcfile_l.l | 3 | ||||
-rw-r--r-- | rcfile_y.y | 8 | ||||
-rw-r--r-- | rfc822.c | 1 | ||||
-rw-r--r-- | sink.c | 13 | ||||
-rw-r--r-- | smtp.c | 12 | ||||
-rw-r--r-- | smtp.h | 8 | ||||
-rw-r--r-- | socket.c | 50 | ||||
-rw-r--r-- | socket.h | 2 |
22 files changed, 246 insertions, 187 deletions
@@ -1,5 +1,13 @@ Release Notes: +fetchmail-4.6.4 (): +* Code cleanup fixes by Jonathan T. Agnew <jtagnew@amherst.edu>. +* Fix to fetchmailconf to not output empty properties. +* Better instrumentation for the rewrite code -- hopefully this will + enable us to nail Sam Steingold's bug. + +There are 245 people on fetchmail-friends and 304 on fetchmail-announce. + fetchmail-4.6.3 (Tue Oct 20 12:37:25 EDT 1998): * Introduced `debug' verbosity, invocable by -v -v. * Make authentication failures more visible by syslogging them. @@ -23,7 +23,7 @@ /* Python prettyprinting functions */ -static indent_level; +static int indent_level; static void indent(char ic) /* indent current line */ @@ -85,7 +85,7 @@ daemonize (const char *logfile, void (*termhook)(int)) { int fd; pid_t childpid; - RETSIGTYPE sigchld_handler(); + RETSIGTYPE sigchld_handler(int); /* if we are started by init (process 1) via /etc/inittab we needn't bother to detach from our process group context */ @@ -83,7 +83,7 @@ flag peek_capable; /* can we peek for better error recovery? */ int pass; /* how many times have we re-polled? */ int phase; /* where are we, for error-logging purposes? */ -static struct method *protocol; +static const struct method *protocol; static jmp_buf restart; char tag[TAGLEN]; @@ -115,11 +115,11 @@ static void timeout_handler (int signal) static int accept_count, reject_count; -static void map_name(name, ctl, xmit_names) +static void map_name(const char *name, struct query *ctl, struct idlist **xmit_names) /* add given name to xmit_names if it matches declared localnames */ -const char *name; /* name to map */ -struct query *ctl; /* list of permissible aliases */ -struct idlist **xmit_names; /* list of recipient names parsed out */ +/* name: name to map */ +/* ctl: list of permissible aliases */ +/* xmit_names: list of recipient names parsed out */ { const char *lname; int off = 0; @@ -137,11 +137,11 @@ struct idlist **xmit_names; /* list of recipient names parsed out */ } } -void find_server_names(hdr, ctl, xmit_names) +void find_server_names(const char *hdr, struct query *ctl, struct idlist **xmit_names) /* parse names out of a RFC822 header into an ID list */ -const char *hdr; /* RFC822 header in question */ -struct query *ctl; /* list of permissible aliases */ -struct idlist **xmit_names; /* list of recipient names parsed out */ +/* hdr: RFC822 header in question */ +/* ctl: list of permissible aliases */ +/* xmit_names: list of recipient names parsed out */ { if (hdr == (char *)NULL) return; @@ -332,13 +332,13 @@ static int sizeticker; #define EMPTYLINE(s) ((s)[0] == '\r' && (s)[1] == '\n' && (s)[2] == '\0') -static int readheaders(sock, fetchlen, reallen, ctl, num) +static int readheaders(int sock, long fetchlen, long reallen, struct query *ctl, int num) /* read message headers and ship to SMTP or MDA */ -int sock; /* to which the server is connected */ -long fetchlen; /* length of message according to fetch response */ -long reallen; /* length of message according to getsizes */ -struct query *ctl; /* query control record */ -int num; /* index of message */ +/* sock: to which the server is connected */ +/* fetchlen: length of message according to fetch response */ +/* reallen: length of message according to getsizes */ +/* ctl: query control record */ +/* num: index of message */ { struct addrblk { @@ -851,7 +851,7 @@ int num; /* index of message */ if (!run.invisible && n != -1) { /* utter any per-message Received information we need here */ - sprintf(buf, "Received: from %s\n", ctl->server.truename); + sprintf(buf, "Received: from %s\r\n", ctl->server.truename); n = stuffline(ctl, buf); if (n != -1) { @@ -860,7 +860,7 @@ int num; /* index of message */ * but this can be secure information that would be bad * to reveal. */ - sprintf(buf, "\tby fetchmail-%s %s\n", + sprintf(buf, "\tby fetchmail-%s %s\r\n", RELEASE_ID, protocol->name); n = stuffline(ctl, buf); @@ -899,7 +899,7 @@ int num; /* index of message */ * generate a 4-digit year here. */ strftime(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%a, %d %b %Y %H:%M:%S %Z\n", localtime(&now)); + "%a, %d %b %Y %H:%M:%S %Z\r\n", localtime(&now)); #else /* * This is really just a portability fallback, as the @@ -977,7 +977,7 @@ int num; /* index of message */ } - strcat(errmsg, "\n"); + strcat(errmsg, "\r\n"); /* ship out the error line */ stuffline(ctl, errmsg); @@ -995,12 +995,12 @@ int num; /* index of message */ return(headers_ok ? PS_SUCCESS : PS_TRUNCATED); } -static int readbody(sock, ctl, forward, len) +static int readbody(int sock, struct query *ctl, flag forward, int len) /* read and dispose of a message body presented on sock */ -struct query *ctl; /* query control record */ -int sock; /* to which the server is connected */ -int len; /* length of message */ -flag forward; /* TRUE to forward */ +/* ctl: query control record */ +/* sock: to which the server is connected */ +/* len: length of message */ +/* forward: TRUE to forward */ { int linelen; unsigned char buf[MSGBUFSIZE+4]; @@ -1127,7 +1127,7 @@ const char *canonical; /* server name */ #ifdef KERBEROS_V5 int kerberos5_auth(socket, canonical) -/* authernticate to the server host using Kerberos V5 */ +/* authenticate to the server host using Kerberos V5 */ int socket; /* socket to server host */ const char *canonical; /* server name */ { @@ -1306,11 +1306,11 @@ const struct method *proto; /* protocol method table */ #else int sock = -1; #endif /* HAVE_VOLATILE */ - char *msg; - void (*sigsave)(); + const char *msg; + void (*sigsave)(int); struct idlist *current=NULL, *tmp=NULL; - protocol = (struct method *)proto; + protocol = proto; ctl->server.base_protocol = protocol; #ifndef KERBEROS_V4 @@ -1428,28 +1428,30 @@ const struct method *proto; /* protocol method table */ #endif /* INET6 */ { #if !INET6 -#ifndef EHOSTUNREACH -#define EHOSTUNREACH (-1) +#ifdef HAVE_RES_SEARCH + if (errno != 0 && h_errno != 0) + error(0, 0, "fetchmail: internal inconsistency"); #endif - if (outlevel >= O_DEBUG || errno != EHOSTUNREACH) - { - error_build("fetchmail: %s connection to %s failed: ", - protocol->name, ctl->server.pollname); + error_build("fetchmail: %s connection to %s failed", + protocol->name, ctl->server.pollname); #ifdef HAVE_RES_SEARCH + if (h_errno != 0) + { if (h_errno == HOST_NOT_FOUND) - error_complete(0, 0, "host is unknown"); + error_complete(0, 0, ": host is unknown"); else if (h_errno == NO_ADDRESS) - error_complete(0, 0, "name is valid but has no IP address"); + error_complete(0, 0, ": name is valid but has no IP address"); else if (h_errno == NO_RECOVERY) - error_complete(0, 0, "unrecoverable name server error"); + error_complete(0, 0, ": unrecoverable name server error"); else if (h_errno == TRY_AGAIN) - error_complete(0, 0, "temporary name server error"); - else if (h_errno) - error_complete(0, 0, "unknown DNS error %d", h_errno); + error_complete(0, 0, ": temporary name server error"); else -#endif /* HAVE_RES_SEARCH */ - error_complete(0, errno, "local error"); + error_complete(0, 0, ": unknown DNS error %d", h_errno); } +#endif /* HAVE_RES_SEARCH */ + + if (errno != 0) + error_complete(0, errno, ""); #endif /* INET6 */ ok = PS_SOCKET; set_timeout(0); @@ -1952,7 +1954,7 @@ const struct method *proto; /* protocol method table */ SockClose(sock); } - msg = (char *)NULL; /* sacrifice to -Wall */ + msg = (const char *)NULL; /* sacrifice to -Wall */ switch (ok) { case PS_SOCKET: @@ -2091,7 +2093,7 @@ int size; /* length of buffer */ } #if defined(HAVE_STDARG_H) -int gen_transact(int sock, char *fmt, ... ) +int gen_transact(int sock, const char *fmt, ... ) /* assemble command in printf(3) style, send to server, accept a response */ #else int gen_transact(int sock, fmt, va_alist) @@ -100,7 +100,7 @@ char *host_fqdn(void) } -char *showproto(int proto) +const char *showproto(int proto) /* protocol index to protocol name mapping */ { switch (proto) @@ -28,7 +28,7 @@ static int etrn_ok (int sock, char *argbuf) return(ok); } -static int etrn_getrange(int sock, struct query *ctl, char *id, +static int etrn_getrange(int sock, struct query *ctl, const char *id, int *countp, int *newp, int *bytes) /* send ETRN and interpret the response */ { diff --git a/fetchmail.c b/fetchmail.c index e76aae5d..a6b4603d 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -50,19 +50,19 @@ static void dump_params (struct runctl *runp, struct query *, flag implicit); static int query_host(struct query *); /* controls the detail level of status/progress messages written to stderr */ -int outlevel; /* see the O_.* constants above */ +int outlevel; /* see the O_.* constants above */ /* miscellaneous global controls */ -struct runctl run; /* global controls for this run */ -flag nodetach; /* if TRUE, don't detach daemon process */ -flag quitmode; /* if --quit was set */ -flag check_only; /* if --probe was set */ -flag versioninfo; /* emit only version info */ -char *user; /* the name of the invoking user */ -char *home; /* invoking user's home directory */ -char *program_name; /* the name to prefix error messages with */ -flag configdump; /* dump control blocks for configurator */ -char *fetchmailhost; /* either `localhost' or the host FQDN */ +struct runctl run; /* global controls for this run */ +flag nodetach; /* if TRUE, don't detach daemon process */ +flag quitmode; /* if --quit was set */ +flag check_only; /* if --probe was set */ +flag versioninfo; /* emit only version info */ +char *user; /* the name of the invoking user */ +char *home; /* invoking user's home directory */ +char *program_name; /* the name to prefix error messages with */ +flag configdump; /* dump control blocks for configurator */ +const char *fetchmailhost; /* either `localhost' or the host's FQDN */ #if NET_SECURITY void *request = NULL; @@ -75,7 +75,7 @@ static int successes; /* count number of successful polls */ static int lastsig; /* last signal received */ static struct runctl cmd_run; /* global options set from command line */ -static void termhook(); /* forward declaration of exit hook */ +static void termhook(int); /* forward declaration of exit hook */ #if 0 #define SLEEP_WITH_ALARM @@ -107,7 +107,7 @@ int sig; } #endif /* SLEEP_WITH_ALARM */ -RETSIGTYPE donothing(sig) int sig; {signal(sig, donothing); lastsig = sig;} +RETSIGTYPE donothing(int sig) {signal(sig, donothing); lastsig = sig;} #ifdef HAVE_ON_EXIT static void unlockit(int n, void *p) @@ -814,6 +814,9 @@ static int load_params(int argc, char **argv, int optind) if (!strcmp(ctl->server.pollname, argv[optind]) || str_in_list(&ctl->server.akalist, argv[optind], TRUE)) { + /* Is this correct? */ + if(predeclared) + fprintf(stderr,"Warning: multiple mentions of host %s in config file\n",argv[optind]); ctl->active = TRUE; predeclared = TRUE; } @@ -862,6 +865,27 @@ static int load_params(int argc, char **argv, int optind) /* force command-line options */ optmerge(ctl, &cmd_opts, TRUE); + /* this code enables flags to be turned off */ +#define DEFAULT(flag, dflt) if (flag == FLAG_TRUE)\ + flag = TRUE;\ + else if (flag == FLAG_FALSE)\ + flag = FALSE;\ + else\ + flag = (dflt) + DEFAULT(ctl->keep, FALSE); + DEFAULT(ctl->fetchall, FALSE); + DEFAULT(ctl->flush, FALSE); + DEFAULT(ctl->rewrite, TRUE); + DEFAULT(ctl->stripcr, (ctl->mda != (char *)NULL)); + DEFAULT(ctl->forcecr, FALSE); + DEFAULT(ctl->pass8bits, FALSE); + DEFAULT(ctl->dropstatus, FALSE); + DEFAULT(ctl->mimedecode, FALSE); + DEFAULT(ctl->server.dns, TRUE); + DEFAULT(ctl->server.uidl, FALSE); + DEFAULT(ctl->server.checkalias, FALSE); +#undef DEFAULT + /* * DNS support is required for some protocols. * @@ -873,9 +897,9 @@ static int load_params(int argc, char **argv, int optind) * If we're using Kerberos for authentication, we need * the FQDN in order to generate capability keys. */ - if ((ctl->server.protocol == P_ETRN + if (ctl->server.protocol == P_ETRN || ctl->server.preauthenticate == A_KERBEROS_V4 - || ctl->server.preauthenticate == A_KERBEROS_V5)) + || ctl->server.preauthenticate == A_KERBEROS_V5) if (strcmp(fetchmailhost, "localhost") == 0) fetchmailhost = host_fqdn(); @@ -893,27 +917,6 @@ static int load_params(int argc, char **argv, int optind) if (!ctl->localnames) /* for local delivery via SMTP */ save_str_pair(&ctl->localnames, user, NULL); - /* this code enables flags to be turned off */ -#define DEFAULT(flag, dflt) if (flag == FLAG_TRUE)\ - flag = TRUE;\ - else if (flag == FLAG_FALSE)\ - flag = FALSE;\ - else\ - flag = (dflt) - DEFAULT(ctl->keep, FALSE); - DEFAULT(ctl->fetchall, FALSE); - DEFAULT(ctl->flush, FALSE); - DEFAULT(ctl->rewrite, TRUE); - DEFAULT(ctl->stripcr, (ctl->mda != (char *)NULL)); - DEFAULT(ctl->forcecr, FALSE); - DEFAULT(ctl->pass8bits, FALSE); - DEFAULT(ctl->dropstatus, FALSE); - DEFAULT(ctl->mimedecode, FALSE); - DEFAULT(ctl->server.dns, TRUE); - DEFAULT(ctl->server.uidl, FALSE); - DEFAULT(ctl->server.checkalias, FALSE); -#undef DEFAULT - #if !defined(HAVE_GETHOSTBYNAME) || !defined(HAVE_RES_SEARCH) /* can't handle multidrop mailboxes unless we can do DNS lookups */ if (ctl->localnames && ctl->localnames->next && ctl->server.dns) diff --git a/fetchmail.h b/fetchmail.h index f5fb1d41..99a8dfbe 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -2,8 +2,11 @@ * For license terms, see the file COPYING in this directory. */ +/* We need this for HAVE_STDARG_H, etc */ +#include "config.h" + /* constants designating the various supported protocols */ -#define P_AUTO 0 +#define P_AUTO 1 #define P_POP2 2 #define P_POP3 3 #define P_IMAP 4 @@ -98,7 +101,7 @@ struct runctl int poll_interval; flag use_syslog; flag invisible; - char *postmaster; + const char *postmaster; }; struct idlist @@ -121,27 +124,40 @@ struct idlist struct idlist *next; }; +struct query; + struct method /* describe methods for protocol state machine */ { - char *name; /* protocol name */ + const char *name; /* protocol name */ #if INET6 - char *service; + const char *service; #else /* INET6 */ int port; /* service port */ #endif /* INET6 */ flag tagged; /* if true, generate & expect command tags */ flag delimited; /* if true, accept "." message delimiter */ - int (*parse_response)(); /* response_parsing function */ - int (*password_canonify)(); /* canonicalize password */ - int (*getauth)(); /* authorization fetcher */ - int (*getrange)(); /* get message range to fetch */ - int (*getsizes)(); /* get sizes of messages */ - int (*is_old)(); /* check for old message */ - int (*fetch_headers)(); /* fetch FROM headera given message */ - int (*fetch_body)(); /* fetch a given message */ - int (*trail)(); /* eat trailer of a message */ - int (*delete)(); /* delete method */ - int (*logout_cmd)(); /* logout command */ + int (*parse_response)(int, char *); + /* response_parsing function */ + int (*password_canonify)(char *, char *); + /* canonicalize password */ + int (*getauth)(int, struct query *, char *); + /* authorization fetcher */ + int (*getrange)(int, struct query *, const char *, int *, int *, int *); + /* get message range to fetch */ + int (*getsizes)(int, int, int *); + /* get sizes of messages */ + int (*is_old)(int, struct query *, int); + /* check for old message */ + int (*fetch_headers)(int, struct query *, int, int *); + /* fetch FROM headera given message */ + int (*fetch_body)(int, struct query *, int, int *); + /* fetch a given message */ + int (*trail)(int, struct query *, int); + /* eat trailer of a message */ + int (*delete)(int, struct query *, int); + /* delete method */ + int (*logout_cmd)(int, struct query *); + /* logout command */ flag retry; /* can getrange poll for new messages? */ }; @@ -182,7 +198,7 @@ struct hostdata /* shared among all user connections to given server */ #endif /* linux */ /* computed for internal use */ - struct method *base_protocol; /* relevant protocol method table */ + const struct method *base_protocol; /* relevant protocol method table */ int poll_count; /* count of polls so far */ char *queryname; /* name to attempt DNS lookup on */ char *truename; /* "true name" of server host */ @@ -230,7 +246,7 @@ struct query /* internal use -- per-poll state */ flag active; /* should we actually poll this server? */ - char *destaddr; /* destination host for this query */ + const char *destaddr; /* destination host for this query */ int errcount; /* count transient errors in last pass */ int smtp_socket; /* socket descriptor for SMTP connection */ unsigned int uid; /* UID of user to deliver to */ @@ -293,7 +309,8 @@ extern char *user; /* name of invoking user */ extern char *home; /* home directory of invoking user */ extern int pass; /* number of re-polling pass */ extern flag configdump; /* dump control blocks as Python dictionary */ -extern char *fetchmailhost; /* either "localhost" or an FQDN */ +extern const char *fetchmailhost; + /* either "localhost" or an FQDN */ /* prototypes for globally callable functions */ @@ -316,7 +333,7 @@ void set_timeout(int); #if defined(HAVE_STDARG_H) void gen_send (int sock, const char *, ... ); int gen_recv(int sock, char *buf, int size); -int gen_transact (int sock, char *, ... ); +int gen_transact (int sock, const char *, ... ); #else void gen_send (); int gen_recv(); @@ -338,7 +355,7 @@ extern int phase; /* sink.c: forwarding */ int stuffline(struct query *, char *); -int open_sink(struct query*, char*, struct idlist*, long reallen, int*, int*); +int open_sink(struct query*, const char*, struct idlist*, long reallen, int*, int*); void release_sink(struct query *); int close_sink(struct query *, flag); @@ -422,7 +439,7 @@ int daemonize(const char *, void (*)(int)); char *getpassword(char *); void escapes(const char *, char *); char *visbuf(const char *); -char *showproto(int); +const char *showproto(int); void dump_config(struct runctl *runp, struct query *querylist); int is_host_alias(const char *, struct query *); char *host_fqdn(void); diff --git a/fetchmail.man b/fetchmail.man index e98cfd05..c5085183 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -86,8 +86,8 @@ declare them in a .I fetchmailrc file. .PP -Some special options are not covered here, but are documented insttead -in sections on AUTHENTICATION and DAEMON MODE which follows. +Some special options are not covered here, but are documented instead +in sections on AUTHENTICATION and DAEMON MODE which follow. .SS General Options .TP .B \-V, --version @@ -160,14 +160,14 @@ fetchmail will automatically delete messages after successful delivery. .TP .B \-p, \--protocol proto (Keyword: proto[col]) -Specify the protocol to used when communicating with the remote -mailserver. If no protocol is specified, -.I fetchmail -will try each of the supported protocols in turn, terminating after -any successful attempt. +Specify the protocol to use when communicating with the remote +mailserver. If no protocol is specified, the default is AUTO. .I proto may be one of the following: .RS +.IP AUTO +Tries each of the supported protocols in turn, terminating after +any successful attempt. .IP POP2 Post Office Protocol 2 .IP POP3 @@ -237,11 +237,12 @@ Specify a hunt list of hosts to forward mail to (one or more hostnames, comma-separated). In ETRN mode, set the host that the mailserver is asked to ship mail to. Hosts are tried in list order; the first one that is up becomes the forwarding or ETRN target for the -current run. In ETRN mode, the FQDN of the machine running fetchmail -is added to the end of the list as an invisible default; in all other -modes `localhost' is added to the end of the list as an invisible -default. Each hostname may have a '/'-delimited suffix specifying a -port or service to forward to; the default is 25 (or "smtp" under IPv6). +current run. Normally, `localhost' is added to the end of the list as +an invisible default. However, when using ETRN mode or Kerberos +authentication, the FQDN of the machine running fetchmail is added to +the end of the list as an invisible default. Each hostname may have a +'/'-delimited suffix specifying a port or service to forward to; the +default is 25 (or "smtp" under IPv6). .TP .B \-D domain, --smtpaddress domain (Keyword: smtpaddress) @@ -907,7 +908,7 @@ auth[enticate] -A T{ Set preauthentication type (default `password') T} timeout -t T{ -Server inactivity timout in seconds (default 300) +Server inactivity timeout in seconds (default 300) T} envelope -E T{ Specify envelope-address header name @@ -1077,11 +1078,10 @@ following them. .PP All options correspond to the obvious command-line arguments, except the following: `via', `interval', `aka', `is', `to', `dns'/`no dns', -`checkalias'/`no checkalias', -\&`password', \&`preconnect', \&`postconnect', `localdomains', -\&`stripcr'/`no stripcr', \&`forcecr'/`no forcecr', `pass8bits'/`no -pass8bits' `dropstatus/no dropstatus', `mimedecode/no mimedecode', -and `no envelope'. +`checkalias'/`no checkalias', `password', `preconnect', `postconnect', +`localdomains', `stripcr'/`no stripcr', `forcecr'/`no forcecr', +`pass8bits'/`no pass8bits' `dropstatus/no dropstatus', `mimedecode/no +mimedecode', and `no envelope'. .PP The `via' option is for use with ssh, or if you want to have more than one configuration pointing at the same site. If it is present, @@ -1301,14 +1301,14 @@ rather to the list manager (which is less annoying). In multidrop mode, destination headers are processed as follows: First, fetchmail looks for the Received: header (or whichever one is specified by the `envelope' option) to determine the local -recipient adress. If the mail is addressed to more than one recipient, -the Received line won't contain any information regarding recipient adresses. +recipient address. If the mail is addressed to more than one recipient, +the Received line won't contain any information regarding recipient addresses. Then fetchmail looks for the Resent-To:, Resent-Cc:, and Resent-Bcc: lines. If they exists, they should contain the final recipients and have precedence over their To:/Cc:/Bcc: counterparts. If the Resent-* lines doesn't exist, the To:, Cc:, Bcc: and Apparently-To: lines are -looked for. (The presence of a Resent-To: is taken to impluy that the +looked for. (The presence of a Resent-To: is taken to imply that the person referred by the To: address has already received the original copy of the mail). @@ -1455,7 +1455,7 @@ in each message containing a copy of the envelope addresses. This header (when it exists) is often `X-Envelope-To'. Fetchmail's assumption about this can be changed with the -E or `envelope' option. Note that writing an envelope header of this kind exposes the names of -recipients (including blind-copy recopients) to all receivers of the +recipients (including blind-copy recipients) to all receivers of the messages; it is therefore regarded by some administrators as a security/privacy problem. .PP @@ -1568,8 +1568,8 @@ One or more messages were successfully retrieved. There was no mail awaiting retrieval. (There may have been old mail still on the server but not selected for retrieval.) .IP 2 -An error was encountered when attempting to open a socket for the POP -connection. If you don't know what a socket is, don't worry about it -- +An error was encountered when attempting to open a socket to retrieve +mail. If you don't know what a socket is, don't worry about it -- just treat this as an 'unrecoverable error'. .IP 3 The user authentication step failed. This usually means that a bad @@ -1600,7 +1600,7 @@ talking to qpopper or other servers that can respond with "lock busy" or some similar text containing the word "lock". .IP 10 The -.I fetchmail. +.I fetchmail run failed while trying to do an SMTP port open or transaction. .IP 11 Fatal DNS error. Fetchmail encountered an error while performing @@ -54,10 +54,10 @@ static int ttyfd; #endif #endif -void static save_tty_state(); -void static disable_tty_echo(); -void static restore_tty_state(); -static RETSIGTYPE sigint_handler(); +void static save_tty_state(void); +void static disable_tty_echo(void); +void static restore_tty_state(void); +static RETSIGTYPE sigint_handler(int); char *getpassword(prompt) char *prompt; @@ -72,11 +72,11 @@ char *prompt; #endif #else register char *p; - register c; + register int c; FILE *fi; static char pbuf[INPUT_BUF_SIZE]; - RETSIGTYPE (*sig)() = 0; /* initialization pacifies -Wall */ - RETSIGTYPE sigint_handler(); + RETSIGTYPE (*sig)(int) = 0; /* initialization pacifies -Wall */ + RETSIGTYPE sigint_handler(int); int istty = isatty(0); @@ -136,7 +136,7 @@ char *prompt; #endif /* !(defined(HAVE_TCSETATTR) || ... */ } -static void save_tty_state () +static void save_tty_state (void) { #if defined(HAVE_TCSETATTR) tcgetattr(ttyfd, &termb); @@ -152,7 +152,7 @@ static void save_tty_state () #endif } -static void disable_tty_echo() +static void disable_tty_echo(void) { /* turn off echo on the tty */ #if defined(HAVE_TCSETATTR) @@ -169,7 +169,7 @@ static void disable_tty_echo() #endif } -static void restore_tty_state() +static void restore_tty_state(void) { /* restore previous tty echo state */ #if defined(HAVE_TCSETATTR) @@ -186,7 +186,7 @@ static void restore_tty_state() #endif } -static RETSIGTYPE sigint_handler() +static RETSIGTYPE sigint_handler(int signum) { restore_tty_state(); error(1, 0, "\nCaught signal... bailing out."); @@ -44,7 +44,7 @@ extern char *strstr(); /* needed on sysV68 R3V7.1. */ #define IMAP4 0 /* IMAP4 rev 0, RFC1730 */ #define IMAP4rev1 1 /* IMAP4 rev 1, RFC2060 */ -static int count, seen, recent, unseen, deletions,expunged, imap_version; +static int count, seen, recent, unseen, deletions, expunged, imap_version; static char capabilities[MSGBUFSIZE+1]; int imap_ok(int sock, char *argbuf) @@ -113,7 +113,9 @@ int imap_ok(int sock, char *argbuf) strcpy(argbuf, cp); return(PS_SUCCESS); } - else if (strncmp(cp, "BAD", 2) == 0) + else if (strncmp(cp, "BAD", 3) == 0) + return(PS_ERROR); + else if (strncmp(cp, "NO", 2) == 0) return(PS_ERROR); else return(PS_PROTOCOL); @@ -665,7 +667,7 @@ int imap_getauth(int sock, struct query *ctl, char *greeting) return(ok); } - /* else fall through to ourdinary AUTH=LOGIN case */ + /* else fall through to ordinary AUTH=LOGIN case */ } else if (ctl->server.protocol == P_IMAP_K4) { @@ -20,8 +20,7 @@ #include "md5.h" char * -MD5Digest (s) -unsigned char *s; +MD5Digest (unsigned char *s) { int i; MD5_CTX context; @@ -39,9 +39,7 @@ /* Maybe add NEWENTRY to the account information list, LIST. NEWENTRY is set to a ready-to-use netrc_entry, in any event. */ static void -maybe_add_to_list (newentry, list) - netrc_entry **newentry; - netrc_entry **list; +maybe_add_to_list (netrc_entry **newentry, netrc_entry **list) { netrc_entry *a, *l; a = *newentry; @@ -87,7 +85,8 @@ parse_netrc (file) char *file; { FILE *fp; - char buf[POPBUFSIZE+1], *p, *tok, *premature_token; + char buf[POPBUFSIZE+1], *p, *tok; + const char *premature_token; netrc_entry *current, *retval; int ln; @@ -64,7 +64,7 @@ #define LA_CONFIGDUMP 42 #define LA_YYDEBUG 43 -/* options still left: CgGhHjJoORwWxXYz */ +/* options still left: CDgGhHjJoORwWxXYz */ static const char *shortoptions = "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:T:I:M:yw:"; @@ -288,7 +288,9 @@ struct query *ctl; /* option record to be initialized */ case 'p': case LA_PROTOCOL: /* XXX -- should probably use a table lookup here */ - if (strcasecmp(optarg,"pop2") == 0) + if (strcasecmp(optarg,"auto") == 0) + ctl->server.protocol = P_AUTO; + else if (strcasecmp(optarg,"pop2") == 0) ctl->server.protocol = P_POP2; #ifdef SDPS_ENABLE else if (strcasecmp(optarg,"sdps") == 0) @@ -149,7 +149,8 @@ char *tp; /* target buffer for digested string */ if (*cp == '\\' && strchr("0123456789xX", cp[1])) { - char *dp, *hex = "00112233445566778899aAbBcCdDeEfF"; + char *dp; + const char *hex = "00112233445566778899aAbBcCdDeEfF"; int dcount = 0; if (*++cp == 'x' || *cp == 'X') @@ -42,9 +42,9 @@ static int prc_errflag; static struct hostdata *leadentry; static flag trailer; -static void record_current(); -static void user_reset(); -static void reset_server(char *name, int skip); +static void record_current(void); +static void user_reset(void); +static void reset_server(const char *name, int skip); /* using Bison, this arranges that yydebug messages will show actual tokens */ extern char * yytext; @@ -426,7 +426,7 @@ int prc_parse_file (const char *pathname, const flag securecheck) return(PS_SUCCESS); } -static void reset_server(char *name, int skip) +static void reset_server(const char *name, int skip) /* clear the entire global record and initialize it with a new name */ { trailer = FALSE; @@ -12,6 +12,7 @@ #include <stdlib.h> #endif +#include "config.h" #include "fetchmail.h" #define HEADER_END(p) ((p)[0] == '\n' && ((p)[1] != ' ' && (p)[1] != '\t')) @@ -73,7 +73,7 @@ static int smtp_open(struct query *ctl) * What it will affect is the listener's logging. */ struct idlist *idp; - char *id_me = run.invisible ? ctl->server.truename : fetchmailhost; + const char *id_me = run.invisible ? ctl->server.truename : fetchmailhost; int oldphase = phase; errno = 0; @@ -159,7 +159,7 @@ static int smtp_open(struct query *ctl) /* these are shared by open_sink and stuffline */ static FILE *sinkfp; -static RETSIGTYPE (*sigchld)(); +static RETSIGTYPE (*sigchld)(int); int stuffline(struct query *ctl, char *buf) /* ship a line to the given control block's output sink (SMTP server or MDA) */ @@ -235,7 +235,7 @@ int stuffline(struct query *ctl, char *buf) static void sanitize(char *s) /* replace unsafe shellchars by an _ */ { - static char *ok_chars = " 1234567890!@%-_=+:,./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const static char *ok_chars = " 1234567890!@%-_=+:,./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; char *cp; for (cp = s; *(cp += strspn(cp, ok_chars)); /* NO INCREMENT */) @@ -243,7 +243,7 @@ static void sanitize(char *s) } int open_sink(struct query *ctl, - char *return_path, + const char *return_path, struct idlist *xmit_names, long reallen, int *good_addresses, int *bad_addresses) @@ -401,7 +401,8 @@ int open_sink(struct query *ctl, } else { - char *ap, options[MSGBUFSIZE], addr[128]; + const char *ap; + char options[MSGBUFSIZE], addr[128]; /* build a connection to the SMTP listener */ if ((smtp_open(ctl) == -1)) @@ -559,7 +560,7 @@ int open_sink(struct query *ctl, { error(0, 0, "can't even send to %s!", run.postmaster); SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ - return(PS_REFUSED); + return(PS_SMTP); } } @@ -9,16 +9,16 @@ */ #include <stdio.h> -#include <config.h> #include <unistd.h> #include <string.h> #include "fetchmail.h" #include "socket.h" #include "smtp.h" +#include "config.h" struct opt { - char *name; + const char *name; int value; }; @@ -32,7 +32,7 @@ static struct opt extensions[] = char smtp_response[MSGBUFSIZE]; -int SMTP_helo(int sock,char *host) +int SMTP_helo(int sock,const char *host) /* send a "HELO" message to the SMTP listener */ { int ok; @@ -44,7 +44,7 @@ int SMTP_helo(int sock,char *host) return ok; } -int SMTP_ehlo(int sock, char *host, int *opt) +int SMTP_ehlo(int sock, const char *host, int *opt) /* send a "EHLO" message to the SMTP listener, return extension status bits */ { struct opt *hp; @@ -78,7 +78,7 @@ int SMTP_ehlo(int sock, char *host, int *opt) return SM_UNRECOVERABLE; } -int SMTP_from(int sock, char *from, char *opts) +int SMTP_from(int sock, const char *from, const char *opts) /* send a "MAIL FROM:" message to the SMTP listener */ { int ok; @@ -97,7 +97,7 @@ int SMTP_from(int sock, char *from, char *opts) return ok; } -int SMTP_rcpt(int sock, char *to) +int SMTP_rcpt(int sock, const char *to) /* send a "RCPT TO:" message to the SMTP listener */ { int ok; @@ -19,10 +19,10 @@ #define ESMTP_SIZE 0x02 #define ESMTP_ETRN 0x04 -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_helo(int socket,const char *host); +int SMTP_ehlo(int socket,const char *host,int *opt); +int SMTP_from(int socket,const char *from,const char *opts); +int SMTP_rcpt(int socket,const char *to); int SMTP_data(int socket); int SMTP_eom(int socket); int SMTP_rset(int socket); @@ -6,6 +6,7 @@ #include "config.h" #include <stdio.h> +#include <errno.h> #include <string.h> #ifdef HAVE_MEMORY_H #include <memory.h> @@ -27,6 +28,15 @@ #include <varargs.h> #endif #include "socket.h" +#include "fetchmail.h" + +#ifdef HAVE_RES_SEARCH +/* some versions of FreeBSD should declare this but don't */ +extern int h_errno; +#else +/* pretend we have h_errno to avoid some #ifdef's later */ +static int h_errno; +#endif #if NET_SECURITY #include <net/security.h> @@ -46,7 +56,7 @@ int SockOpen(const char *host, const char *service, const char *options) req.ai_socktype = SOCK_STREAM; if (i = getaddrinfo(host, service, &req, &ai)) { - fprintf(stderr, "fetchmail: getaddrinfo(%s.%s): %s(%d)\n", host, service, gai_strerror(i), i); + error(0, 0, "fetchmail: getaddrinfo(%s.%s): %s(%d)", host, service, gai_strerror(i), i); return -1; }; @@ -57,7 +67,7 @@ int SockOpen(const char *host, const char *service, const char *options) if (net_security_strtorequest((char *)options, &request, &requestlen)) goto ret; - i = inner_connect(ai, request, requestlen, NULL,NULL, "fetchmail", NULL); + i = inner_connect(ai, request, requestlen, NULL, NULL, "fetchmail", NULL); if (request) free(request); @@ -71,7 +81,7 @@ ret: return i; }; #else /* INET6 */ -#ifndef INET_ATON +#ifndef HAVE_INET_ATON #ifndef INADDR_NONE #ifdef INADDR_BROADCAST #define INADDR_NONE INADDR_BROADCAST @@ -79,14 +89,14 @@ ret: #define INADDR_NONE -1 #endif #endif -#endif /* INET_ATON */ +#endif /* HAVE_INET_ATON */ int SockOpen(const char *host, int clientPort, const char *options) { int sock; -#ifndef INET_ATON +#ifndef HAVE_INET_ATON unsigned long inaddr; -#endif /* INET_ATON */ +#endif /* HAVE_INET_ATON */ struct sockaddr_in ad; struct hostent *hp; @@ -94,24 +104,32 @@ int SockOpen(const char *host, int clientPort, const char *options) ad.sin_family = AF_INET; /* we'll accept a quad address */ -#ifndef INET_ATON +#ifndef HAVE_INET_ATON inaddr = inet_addr(host); if (inaddr != INADDR_NONE) memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr)); else #else if (!inet_aton(host, &ad.sin_addr)) -#endif /* INET_ATON */ +#endif /* HAVE_INET_ATON */ { hp = gethostbyname(host); + if (hp == NULL) + { + errno = 0; + return -1; + } /* * Add a check to make sure the address has a valid IPv4 or IPv6 * length. This prevents buffer spamming by a broken DNS. */ - if (hp == NULL || (hp->h_length != 4 && hp->h_length != 8)) - return -1; - + if(hp->h_length != 4 && hp->h_length != 8) + { + h_errno = errno = 0; + error(0, 0, "fetchmail: illegal address length received for host %s"); + return -1; + } /* * FIXME: make this work for multihomed hosts. * We're toast if we get back multiple addresses and h_addrs[0] @@ -124,10 +142,16 @@ int SockOpen(const char *host, int clientPort, const char *options) sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) + { + h_errno = 0; return -1; + } if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) { + int olderr = errno; close(sock); + h_errno = 0; + errno = olderr; return -1; } @@ -137,7 +161,7 @@ int SockOpen(const char *host, int clientPort, const char *options) #if defined(HAVE_STDARG_H) -int SockPrintf(int sock, char* format, ...) +int SockPrintf(int sock, const char* format, ...) { #else int SockPrintf(sock,format,va_alist) @@ -228,7 +252,7 @@ int SockClose(int sock) #ifdef MAIN /* - * Use the chargen service to test input beuffering directly. + * Use the chargen service to test input buffering directly. * You may have to uncomment the `chargen' service description in your * inetd.conf (and then SIGHUP inetd) for this to work. */ @@ -38,7 +38,7 @@ Send formatted output to the socket (matches interface of fprintf). Returns number of bytes successfully written. */ #if defined(HAVE_STDARG_H) -int SockPrintf(int sock, char *format, ...) ; +int SockPrintf(int sock, const char *format, ...) ; #else int SockPrintf(); #endif |