]> Pileus Git - ~andy/fetchmail/blobdiff - fetchmail.c
Julian Haight's changes.
[~andy/fetchmail] / fetchmail.c
index 3cd8c0d693b639ff179a58560ca5e1819fad1786..dd83b671fdbb26a51a86dfa710555c9d88733324 100644 (file)
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>  /* needed for Sun 4.1.2 */
 #ifdef HAVE_SETRLIMIT
 #include <sys/resource.h>
 #endif /* HAVE_SETRLIMIT */
 #include <sys/utsname.h>
 
+#ifdef HAVE_NET_SOCKET_H
+#include <net/socket.h>
+#endif
 #ifdef HAVE_GETHOSTBYNAME
 #include <netdb.h>
 #endif /* HAVE_GETHOSTBYNAME */
@@ -38,6 +42,7 @@
 #include <hesiod.h>
 #endif
 
+#include "getopt.h"
 #include "fetchmail.h"
 #include "tunable.h"
 #include "smtp.h"
@@ -64,6 +69,7 @@ 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 *fmhome;              /* fetchmail'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 */
@@ -124,6 +130,7 @@ int main(int argc, char **argv)
     netrc_entry *netrc_list;
     char *netrc_file, *tmpbuf;
     pid_t pid;
+    int lastsig = 0;
 
 #ifdef __FreeBSD__
     dropprivs();
@@ -151,8 +158,8 @@ int main(int argc, char **argv)
     }
 
 #define IDFILE_NAME    ".fetchids"
-    run.idfile = (char *) xmalloc(strlen(home)+sizeof(IDFILE_NAME)+1);
-    strcpy(run.idfile, home);
+    run.idfile = (char *) xmalloc(strlen(fmhome)+sizeof(IDFILE_NAME)+2);
+    strcpy(run.idfile, fmhome);
     strcat(run.idfile, "/");
     strcat(run.idfile, IDFILE_NAME);
   
@@ -236,7 +243,12 @@ int main(int argc, char **argv)
     /* logging should be set up early in case we were restarted from exec */
     if (run.use_syslog)
     {
+#if defined(LOG_MAIL)
        openlog(program_name, LOG_PID, LOG_MAIL);
+#else
+       /* Assume BSD4.2 openlog with two arguments */
+       openlog(program_name, LOG_PID);
+#endif
        report_init(-1);
     }
     else
@@ -250,9 +262,11 @@ int main(int argc, char **argv)
                sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE));
        sprintf(tmpbuf, "%s/%s", PID_DIR, FETCHMAIL_PIDFILE);
     } else {
-       xalloca(tmpbuf, char *, strlen(home) + sizeof(FETCHMAIL_PIDFILE) + 2);
-       strcpy(tmpbuf, home);
-       strcat(tmpbuf, "/.");
+       xalloca(tmpbuf, char *, strlen(fmhome) + sizeof(FETCHMAIL_PIDFILE) + 2);
+       strcpy(tmpbuf, fmhome);
+       strcat(tmpbuf, "/");
+        if (fmhome == home)
+          strcat(tmpbuf, ".");
        strcat(tmpbuf, FETCHMAIL_PIDFILE);
     }
 #undef FETCHMAIL_PIDFILE
@@ -274,7 +288,7 @@ int main(int argc, char **argv)
 
 #define        NETRC_FILE      ".netrc"
     /* parse the ~/.netrc file (if present) for future password lookups. */
-    xalloca(netrc_file, char *, strlen (home) + sizeof(NETRC_FILE) + 1);
+    xalloca(netrc_file, char *, strlen(home) + sizeof(NETRC_FILE) + 2);
     strcpy (netrc_file, home);
     strcat (netrc_file, "/");
     strcat (netrc_file, NETRC_FILE);
@@ -484,7 +498,7 @@ int main(int argc, char **argv)
                        strlen(ctl->server.pollname) + 1);
                (void) sprintf(tmpbuf, password_prompt,
                               ctl->remotename, ctl->server.pollname);
-               ctl->password = xstrdup((char *)getpassword(tmpbuf));
+               ctl->password = xstrdup((char *)fm_getpassword(tmpbuf));
            }
     }
 
@@ -620,8 +634,11 @@ int main(int argc, char **argv)
                }
 
 #if (defined(linux) && !INET6_ENABLE) || defined(__FreeBSD__)
-               /* interface_approve() does its own error logging */
-               if (!interface_approve(&ctl->server))
+               /*
+                * Don't do monitoring if we were woken by a signal.
+                * Note that interface_approve() does its own error logging.
+                */
+               if (!interface_approve(&ctl->server, !lastsig))
                    continue;
 #endif /* (defined(linux) && !INET6_ENABLE) || defined(__FreeBSD__) */
 
@@ -697,8 +714,6 @@ int main(int argc, char **argv)
         */
        if (run.poll_interval)
        {
-           int lastsig;
-
            /* 
             * Because passwords can expire, it may happen that *all*
             * hosts are now out of the loop due to authfail
@@ -725,7 +740,7 @@ int main(int argc, char **argv)
 
            /*
             * OK, now pause util it's time for the next poll cycle.
-            * A TRUE return indicates we received a wakeup signal;
+            * A nonzero return indicates we received a wakeup signal;
             * unwedge all servers in case the problem has been
             * manually repaired.
             */
@@ -759,15 +774,14 @@ int main(int argc, char **argv)
 static void list_merge(struct idlist **dstl, struct idlist **srcl, int force)
 {
     /*
-     * If force is off, modify h2 fields only when they're empty (treat h1
-     * as defaults).  If force is on, modify each h2 field whenever h1
-     * is nonempty (treat h1 as an override).  
+     * If force is off, modify dstl fields only when they're empty (treat srcl
+     * as defaults).  If force is on, modify each dstl field whenever scrcl
+     * is nonempty (treat srcl as an override).  
      */
-    if (force ? !!srcl : !dstl)
+    if (force ? !!*srcl : !*dstl)
     {
        struct idlist *cpl = copy_str_list(*srcl);
 
-       free_str_list(dstl);
        append_str_list(dstl, &cpl);
     }
 }
@@ -817,6 +831,7 @@ static void optmerge(struct query *h2, struct query *h1, int force)
     FLAG_MERGE(bsmtp);
     FLAG_MERGE(listener);
     FLAG_MERGE(smtpaddress);
+    FLAG_MERGE(smtpname);
     FLAG_MERGE(preconnect);
     FLAG_MERGE(postconnect);
 
@@ -1109,9 +1124,9 @@ static int load_params(int argc, char **argv, int optind)
                ctl->server.truename = xstrdup(leadname);
            }
 #ifdef HAVE_GETHOSTBYNAME
-           else if (ctl->server.preauthenticate==A_KERBEROS_V4 ||
+           else if (!configdump && (ctl->server.preauthenticate==A_KERBEROS_V4 ||
                ctl->server.preauthenticate==A_KERBEROS_V5 ||
-               (ctl->server.dns && MULTIDROP(ctl)))
+                     (ctl->server.dns && MULTIDROP(ctl))))
            {
                struct hostent  *namerec;
 
@@ -1129,8 +1144,40 @@ static int load_params(int argc, char **argv, int optind)
                    ctl->server.truename=xstrdup((char *)namerec->h_name);
            }
 #endif /* HAVE_GETHOSTBYNAME */
-           else
-               ctl->server.truename = xstrdup(ctl->server.queryname);
+           else {
+#ifdef HAVE_GETHOSTBYNAME
+             struct hostent    *namerec;
+
+             /* <fetchmail@mail.julianhaight.com>
+                Get the host's IP, so we can report it like this:
+
+                Received: from hostname [10.0.0.1]
+
+                do we actually need to gethostbyname to find the IP?
+                it seems like it would be faster to do this later, when
+                we are actually resolving the hostname for a connection,
+                but I ain't that smart, so I don't know where to make
+                the change later..
+             */
+             errno = 0;
+             namerec = gethostbyname(ctl->server.queryname);
+             if (namerec == (struct hostent *)NULL)
+               {
+                 report(stderr,
+                        _("couldn't find canonical DNS name of %s\n"),
+                        ctl->server.pollname);
+                 exit(PS_DNS);
+               }
+             else {
+               ctl->server.truename=xstrdup((char *)namerec->h_name);
+               ctl->server.trueaddr=xmalloc(namerec->h_length);
+               memcpy(ctl->server.trueaddr, 
+                      namerec->h_addr_list[0],
+                      namerec->h_length);
+             }
+#endif /* HAVE_GETHOSTBYNAME */
+             ctl->server.truename = xstrdup(ctl->server.queryname);
+           }
 
            /* if no folders were specified, set up the null one as default */
            if (!ctl->mailboxes)
@@ -1701,11 +1748,11 @@ static void dump_params (struct runctl *runp,
 #endif
 
        if (ctl->server.plugin)
-           printf(_("  Server connections will be mode via plugin %s (--plugin %s).\n"), ctl->server.plugin, ctl->server.plugin);
+           printf(_("  Server connections will be made via plugin %s (--plugin %s).\n"), ctl->server.plugin, ctl->server.plugin);
        else if (outlevel >= O_VERBOSE)
            printf(_("  No plugin command specified.\n"));
        if (ctl->server.plugout)
-           printf(_("  Listener connections will be mode via plugout %s (--plugout %s).\n"), ctl->server.plugout, ctl->server.plugout);
+           printf(_("  Listener connections will be made via plugout %s (--plugout %s).\n"), ctl->server.plugout, ctl->server.plugout);
        else if (outlevel >= O_VERBOSE)
            printf(_("  No plugout command specified.\n"));