XEmacs 21.2.28 "Hermes".
[chise/xemacs-chise.git.1] / lib-src / movemail.c
index f345020..941ada9 100644 (file)
@@ -1,35 +1,41 @@
 /* movemail foo bar -- move file foo to file bar,
-   locking file foo the way /bin/mail respects.
+   locking file foo.
    Copyright (C) 1986, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
 
-This file is part of GNU Emacs.
+This file is part of XEmacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
 
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
+along with XEmacs; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+Boston, MA 02111-1307, USA.
 
-/* Important notice: defining MAIL_USE_FLOCK or MAIL_USE_LOCKF *will
-   cause loss of mail* if you do it on a system that does not normally
-   use flock as its way of interlocking access to inbox files.  The
-   setting of MAIL_USE_FLOCK and MAIL_USE_LOCKF *must agree* with the
-   system's own conventions.  It is not a choice that is up to you.
+ Please mail bugs and suggestions to the XEmacs maintainer.
+*/
 
-   So, if your system uses lock files rather than flock, then the only way
-   you can get proper operation is to enable movemail to write lockfiles there.
-   This means you must either give that directory access modes
-   that permit everyone to write lockfiles in it, or you must make movemail
-   a setuid or setgid program.  */
+/* Important notice:
+ *
+ *  You *must* coordinate the locking method used by movemail with that
+ *  used by your mail delivery agent, as well as that of the other mail
+ *  user agents on your system.  movemail allows you to do this at run
+ *  time via the -m flag.  Moreover, it uses a default determined by
+ *  the MAIL_LOCK_DOT, MAIL_LOCK_LOCKF, MAIL_LOCK_FLOCK,
+ *  MAIL_LOCK_LOCKING, and MAIL_LOCK_MMDF preprocessor settings.
+ */
+
+/*
+ * Mike Sperber <sperber@informatik.uni-tuebingen.de> reorganized
+ * everything that has to with locking in December 1999.
+ */
 
 /*
  * Modified January, 1986 by Michael R. Gretzinger (Project Athena)
@@ -55,27 +61,30 @@ Boston, MA 02111-1307, USA.  */
  */
 
 #define NO_SHORTNAMES   /* Tell config not to load remap.h */
-#include <../src/config.h>
+#define DONT_ENCAPSULATE
+#include <config.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/file.h>
 #include <stdio.h>
 #include <errno.h>
+#include "../src/sysfile.h"
 #include "../src/syswait.h"
+#ifndef WINDOWSNT
 #include "../src/systime.h"
+#endif
 #include <stdlib.h>
 #include <string.h>
 #include "getopt.h"
 #ifdef MAIL_USE_POP
 #include "pop.h"
-#include <regex.h>
+#include "../src/regex.h"
 #endif
 
 extern char *optarg;
 extern int optind, opterr;
 
 #ifndef HAVE_STRERROR
-static char * strerror (int errnum);
+char * strerror (int errnum);
 #endif /* HAVE_STRERROR */
 
 #ifdef MSDOS
@@ -103,7 +112,7 @@ static char * strerror (int errnum);
 #include <io.h>
 #endif /* WINDOWSNT */
 
-#if defined (HAVE_UNISTD_H) || defined (USG)
+#if defined (HAVE_UNISTD_H)
 #include <unistd.h>
 #endif /* unistd.h */
 #ifndef F_OK
@@ -113,23 +122,15 @@ static char * strerror (int errnum);
 #define R_OK 4
 #endif /* No F_OK */
 
-#if defined (HAVE_FCNTL_H) || defined (USG)
+#if defined (HAVE_FCNTL_H)
 #include <fcntl.h>
 #endif /* fcntl.h */
 
-#if defined (XENIX) || defined (WINDOWSNT)
+#ifdef HAVE_LOCKING
 #include <sys/locking.h>
 #endif
 
-#ifdef MAIL_USE_LOCKF
-#define MAIL_USE_SYSTEM_LOCK
-#endif
-
-#ifdef MAIL_USE_FLOCK
-#define MAIL_USE_SYSTEM_LOCK
-#endif
-
-#ifdef MAIL_USE_MMDF
+#ifdef HAVE_MMDF
 extern int lk_open (), lk_close ();
 #endif
 
@@ -141,13 +142,15 @@ extern int lk_open (), lk_close ();
 
 static void fatal (char *, char*);
 static void error (char *, char *, char *);
+static void usage(int);
 static void pfatal_with_name (char *);
 static void pfatal_and_delete (char *);
 static char *concat (char *, char *, char *);
 static long *xmalloc (unsigned int);
 #ifdef MAIL_USE_POP
 static int popmail (char *, char *, char *);
-static int pop_retr (popserver server, int msgno, int (*action)(), void *arg);
+static int pop_retr (popserver server, int msgno,
+                    int (*action)(char *, FILE *), FILE *arg);
 static int mbx_write (char *, FILE *);
 static int mbx_delimit_begin (FILE *);
 static int mbx_delimit_end (FILE *);
@@ -156,9 +159,6 @@ static int pop_search_top (popserver server, int msgno, int lines,
                           struct re_pattern_buffer* regexp);
 #endif
 
-/* Nonzero means this is name of a lock file to delete on fatal error.  */
-char *delete_lockname;
-
 int verbose=0;
 #ifdef MAIL_USE_POP
 int reverse=0;
@@ -180,10 +180,35 @@ struct option longopts[] =
   { "regex",                   required_argument,         NULL,        'r'     },
   { "match-lines",             required_argument,         NULL,        'l'     },
 #endif
+  { "lock-method",             required_argument,         NULL,        'm'     },
+  { "help",                    no_argument,               NULL,        'h'     },
   { "verbose",                         no_argument,               NULL,        'v'     },
   { 0 }
 };
 
+#define DOTLOCKING     0
+#define FLOCKING       1
+#define LOCKFING       2
+#define MMDF                   3
+#define LOCKING         4
+
+#if defined(MAIL_LOCK_FLOCK) && defined(HAVE_FLOCK)
+#define DEFAULT_LOCKING FLOCKING
+#elif defined(MAIL_LOCK_LOCKF) && defined(HAVE_LOCKF)
+#define DEFAULT_LOCKING LOCKFING
+#elif defined(MAIL_LOCK_MMDF) && defined(HAVE_MMDF)
+#define DEFAULT_LOCKING MMDF
+#elif defined(MAIL_LOCK_LOCKING) && defined(HAVE_LOCKING)
+#define DEFAULT_LOCKING LOCKING
+#else
+#define DEFAULT_LOCKING DOTLOCKING
+#endif
+
+static void lock_dot(char *);
+static void unlock_dot(char *);
+static int parse_lock_method(char *);
+static char *unparse_lock_method(int);
+
 int
 main (int argc, char *argv[])
 {
@@ -194,23 +219,23 @@ main (int argc, char *argv[])
   int status;
 #endif
 
-#ifndef MAIL_USE_SYSTEM_LOCK
-  struct stat st;
-  long now;
-  int tem;
-  char *lockname, *p;
-  char *tempname;
-  int desc;
-#endif /* not MAIL_USE_SYSTEM_LOCK */
+  int lock_method = DEFAULT_LOCKING;
 
-  delete_lockname = 0;
+  char *maybe_lock_env;
+
+  maybe_lock_env = getenv("EMACSLOCKMETHOD");
+  if (maybe_lock_env)
+    {
+      printf("maybe-lock_env: %s\n", maybe_lock_env);
+      lock_method = parse_lock_method(maybe_lock_env);
+    }
 
-  while (1)
+  for (;;)
     {
 #ifdef MAIL_USE_POP
-      char* optstring = "i:o:p:l:r:xvk";
+      char* optstring = "i:o:m:p:l:r:xvhk";
 #else
-      char* optstring = "i:o:v";
+      char* optstring = "i:o:m:vh";
 #endif
       int opt = getopt_long (argc, argv, optstring, longopts, 0);
   
@@ -251,7 +276,16 @@ main (int argc, char *argv[])
          regexp_pattern = compile_regex (optarg);
          break;
 #endif
-       case 'v':               verbose = 1;    break;
+
+       case 'm':
+         lock_method = parse_lock_method(optarg);
+         break;
+       case 'h':
+         usage(lock_method);
+         exit(0);
+       case 'v':
+         verbose = 1;
+         break;
        }
     }
 
@@ -268,17 +302,19 @@ main (int argc, char *argv[])
     
   if (!inname || !outname)
     {
-      fprintf (stderr, "Usage: movemail [-rvxk] [-l lines ] [-i] inbox [-o] destfile [[-p] POP-password]\n");
+      usage(lock_method);
       exit(1);
     }
 
-#ifdef MAIL_USE_MMDF
-  mmdf_init (argv[0]);
+#ifdef HAVE_MMDF
+  if (lock_method == MMDF)
+    mmdf_init (argv[0]);
 #endif
 
   if (*outname == 0)
     fatal ("Destination file name is empty", 0);
 
+  VERBOSE(("checking access to output file\n"));
   /* Check access to output file.  */
   if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0)
     pfatal_with_name (outname);
@@ -305,7 +341,9 @@ main (int argc, char *argv[])
       exit (retcode);
     }
 
+#ifndef WINDOWSNT
   setuid (getuid ());
+#endif
 #endif /* MAIL_USE_POP */
 
 #ifndef DISABLE_DIRECT_ACCESS
@@ -314,121 +352,83 @@ main (int argc, char *argv[])
   if (access (inname, R_OK | W_OK) != 0)
     pfatal_with_name (inname);
 
-#ifndef MAIL_USE_MMDF
-#ifndef MAIL_USE_SYSTEM_LOCK
-  /* Use a lock file named after our first argument with .lock appended:
-     If it exists, the mail file is locked.  */
-  /* Note: this locking mechanism is *required* by the mailer
-     (on systems which use it) to prevent loss of mail.
-
-     On systems that use a lock file, extracting the mail without locking
-     WILL occasionally cause loss of mail due to timing errors!
-
-     So, if creation of the lock file fails
-     due to access permission on the mail spool directory,
-     you simply MUST change the permission
-     and/or make movemail a setgid program
-     so it can create lock files properly.
-
-     You might also wish to verify that your system is one
-     which uses lock files for this purpose.  Some systems use other methods.
-
-     If your system uses the `flock' system call for mail locking,
-     define MAIL_USE_SYSTEM_LOCK in config.h or the s-*.h file
-     and recompile movemail.  If the s- file for your system
-     should define MAIL_USE_SYSTEM_LOCK but does not, send a bug report
-     to bug-gnu-emacs@prep.ai.mit.edu so we can fix it.  */
-
-  lockname = concat (inname, ".lock", "");
-  tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1);
-  strcpy (tempname, inname);
-  p = tempname + strlen (tempname);
-  while (p != tempname && !IS_DIRECTORY_SEP (p[-1]))
-    p--;
-  *p = 0;
-  strcpy (p, "EXXXXXX");
-  mktemp (tempname);
-  unlink (tempname);
 
-  while (1)
+  if (fork () == 0)
     {
-      /* Create the lock file, but not under the lock file name.  */
-      /* Give up if cannot do that.  */
-      desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666);
-      if (desc < 0)
-       {
-         char *message = (char *) xmalloc (strlen (tempname) + 50);
-         sprintf (message, "%s--see source file lib-src/movemail.c",
-                  tempname);
-         pfatal_with_name (message);
-       }
-      close (desc);
+      setuid (getuid ());
 
-      tem = link (tempname, lockname);
-      unlink (tempname);
-      if (tem >= 0)
-       break;
-      sleep (1);
+      VERBOSE(("opening input file\n"));
 
-      /* If lock file is five minutes old, unlock it.
-        Five minutes should be good enough to cope with crashes
-        and wedgitude, and long enough to avoid being fooled
-        by time differences between machines.  */
-      if (stat (lockname, &st) >= 0)
+      switch (lock_method)
        {
-         now = time (0);
-         if (st.st_ctime < now - 300)
-           unlink (lockname);
+       case DOTLOCKING:
+         indesc = open (inname, O_RDONLY);
+         break;
+#ifdef HAVE_LOCKF
+       case LOCKFING:
+         indesc = open (inname, O_RDWR);
+         break;
+#endif
+#ifdef HAVE_FLOCK
+       case FLOCKING:
+         indesc = open (inname, O_RDWR);
+         break;
+#endif
+#ifdef HAVE_LOCKING
+       case LOCKING:
+         indesc = open (inname, O_RDWR);
+         break;
+#endif
+#ifdef HAVE_MMDF
+       case MMDF:
+         indesc = lk_open (inname, O_RDONLY, 0, 0, 10);
+         break;
+#endif
+       default: abort();
        }
-    }
-
-  delete_lockname = lockname;
-#endif /* not MAIL_USE_SYSTEM_LOCK */
-#endif /* not MAIL_USE_MMDF */
-
-  if (fork () == 0)
-    {
-      setuid (getuid ());
-
-#ifndef MAIL_USE_MMDF
-#ifdef MAIL_USE_SYSTEM_LOCK
-      indesc = open (inname, O_RDWR);
-#else  /* if not MAIL_USE_SYSTEM_LOCK */
-      indesc = open (inname, O_RDONLY);
-#endif /* not MAIL_USE_SYSTEM_LOCK */
-#else  /* MAIL_USE_MMDF */
-      indesc = lk_open (inname, O_RDONLY, 0, 0, 10);
-#endif /* MAIL_USE_MMDF */
 
       if (indesc < 0)
        pfatal_with_name (inname);
 
-#if defined (BSD) || defined (XENIX)
+#ifdef HAVE_UMASK      
       /* In case movemail is setuid to root, make sure the user can
         read the output file.  */
-      /* This is desirable for all systems
-        but I don't want to assume all have the umask system call */
       umask (umask (0) & 0333);
-#endif /* BSD or Xenix */
+#endif
+
       outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666);
       if (outdesc < 0)
        pfatal_with_name (outname);
-#ifdef MAIL_USE_SYSTEM_LOCK
-#ifdef MAIL_USE_LOCKF
-      if (lockf (indesc, F_LOCK, 0) < 0) pfatal_with_name (inname);
-#else /* not MAIL_USE_LOCKF */
-#ifdef XENIX
-      if (locking (indesc, LK_RLCK, 0L) < 0) pfatal_with_name (inname);
-#else
-#ifdef WINDOWSNT
-      if (locking (indesc, LK_RLCK, -1L) < 0) pfatal_with_name (inname);
-#else
-      if (flock (indesc, LOCK_EX) < 0) pfatal_with_name (inname);
+
+      VERBOSE(("locking input file\n"));
+
+      switch (lock_method)
+       {
+#ifdef HAVE_LOCKF
+       case LOCKFING:
+         if (lockf (indesc, F_LOCK, 0) < 0)
+           pfatal_with_name (inname);
+         break;
+#endif
+#ifdef HAVE_FLOCK
+       case FLOCKING:
+         if (flock (indesc, LOCK_EX) < 0)
+           pfatal_with_name (inname);
+         break;
 #endif
+#ifdef HAVE_LOCKING
+       case LOCKING:
+         if (locking (indesc, LK_RLCK, -1L) < 0)
+           pfatal_with_name (inname);
+         break;
 #endif
-#endif /* not MAIL_USE_LOCKF */
-#endif /* MAIL_USE_SYSTEM_LOCK */
+       case DOTLOCKING:
+         lock_dot(inname);
+         break;
+       }
 
+      VERBOSE(("copying input file to output file\n"));
+           
       {
        char buf[1024];
 
@@ -447,7 +447,7 @@ main (int argc, char *argv[])
          }
       }
 
-#ifdef BSD
+#ifdef HAVE_FSYNC
       if (fsync (outdesc) < 0)
        pfatal_and_delete (outname);
 #endif
@@ -456,31 +456,29 @@ main (int argc, char *argv[])
       if (close (outdesc) != 0)
        pfatal_and_delete (outname);
 
-#ifdef MAIL_USE_SYSTEM_LOCK
-#if defined (STRIDE) || defined (XENIX) || defined (WINDOWSNT)
-      /* Stride, xenix have file locking, but no ftruncate.  This mess will do. */
-      close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666));
-#else
-      ftruncate (indesc, 0L);
-#endif /* STRIDE or XENIX */
-#endif /* MAIL_USE_SYSTEM_LOCK */
+      VERBOSE(("deleting or truncating input file\n"));
 
-#ifdef MAIL_USE_MMDF
-      lk_close (indesc, 0, 0, 0);
+      switch (lock_method)
+       {
+       case LOCKFING:
+       case FLOCKING:
+       case LOCKING:
+#ifdef HAVE_FTRUNCATE
+         ftruncate (indesc, 0L);
 #else
-      close (indesc);
+         close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666));
 #endif
-
-#ifndef MAIL_USE_SYSTEM_LOCK
-      /* Delete the input file; if we can't, at least get rid of its
-        contents.  */
-#ifdef MAIL_UNLINK_SPOOL
-      /* This is generally bad to do, because it destroys the permissions
-        that were set on the file.  Better to just empty the file.  */
-      if (unlink (inname) < 0 && errno != ENOENT)
-#endif /* MAIL_UNLINK_SPOOL */
-       creat (inname, 0600);
-#endif /* not MAIL_USE_SYSTEM_LOCK */
+         close (indesc);
+         break;
+#ifdef HAVE_MMDF
+       case MMDF:
+         lk_close (indesc, 0, 0, 0);
+         break;
+#endif
+       case DOTLOCKING:
+         creat (inname, 0600);
+         break;
+       }
 
       exit (0);
     }
@@ -491,22 +489,162 @@ main (int argc, char *argv[])
   else if (WEXITSTATUS (status) != 0)
     exit (WEXITSTATUS (status));
 
-#if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK)
-  unlink (lockname);
-#endif /* not MAIL_USE_MMDF and not MAIL_USE_SYSTEM_LOCK */
+  if (lock_method == DOTLOCKING)
+    unlock_dot(inname);
 
-#endif /* ! DISABLE_DIRECT_ACCESS */
+#endif /* not DISABLE_DIRECT_ACCESS */
 
   return 0;
 }
-\f
+
+static void
+usage(int lock_method)
+{
+  printf ("Usage: movemail [-rvxkh] [-l lines ] [-m method ] [-i] inbox [-o] destfile [[-p] POP-password]\n");
+  printf("where method is one of: dot");
+#ifdef HAVE_LOCKF
+  printf(", lockf");
+#endif
+#ifdef HAVE_FLOCK
+  printf(", flock");
+#endif
+#ifdef HAVE_MMDF
+  printf(", mmdf");
+#endif
+#ifdef HAVE_LOCKING
+  printf(", locking");
+#endif
+  printf("\nDefault is: %s\n", unparse_lock_method(lock_method));
+  
+}
+
+static char *
+unparse_lock_method(int lock_method)
+{
+  switch (lock_method)
+    {
+    case DOTLOCKING: return "dot";
+    case FLOCKING:   return "flock";
+    case LOCKFING:   return "lockf";
+    case LOCKING:    return "locking";
+    case MMDF:       return "mmdf";
+    default: abort();return 0;
+    }
+}
+
+static int
+parse_lock_method(char *method_name)
+{
+  if (!strcmp("dot", method_name) || !strcmp("file", method_name))
+    return DOTLOCKING;
+#ifdef HAVE_LOCKF
+  else if (!strcmp("lockf", method_name))
+    return LOCKFING;
+#endif
+#ifdef HAVE_FLOCK
+  else if (!strcmp("flock", method_name))
+    return FLOCKING;
+#endif
+#ifdef HAVE_MMDF
+  else if (!strcmp("mmdf", method_name))
+    return MMDF;
+#endif
+#ifdef HAVE_LOCKING
+  else if (!strcmp("locking", method_name))
+    return LOCKING;
+#endif
+  else
+    fatal("invalid lock method: %s", method_name);
+  return 0; /* unreached */
+}
+
+static char *
+dot_filename(char *filename)
+{
+  return concat (filename, ".lock", "");
+}
+
+static char *dotlock_filename = NULL;
+
+static void
+lock_dot(char *filename)
+{
+  struct stat st;
+  long now;
+  int tem;
+  char *lockname, *p;
+  char *tempname;
+  int desc;
+
+  dotlock_filename = (char *) xmalloc(strlen(filename) + 1);
+
+  /* Use a lock file named after our first argument with .lock appended:
+     If it exists, the mail file is locked. */
+
+  lockname = dot_filename(filename);
+  tempname = (char *) xmalloc (strlen (filename) + strlen ("EXXXXXX") + 1);
+  strcpy (tempname, filename);
+  p = tempname + strlen (tempname);
+  while (p != tempname && !IS_DIRECTORY_SEP (p[-1]))
+    p--;
+  *p = 0;
+  strcpy (p, "EXXXXXX");
+  mktemp (tempname);
+  unlink (tempname);
+
+  for (;;)
+    {
+      /* Create the lock file, but not under the lock file name.  */
+      /* Give up if cannot do that.  */
+      desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666);
+      if (desc < 0)
+       {
+         char *message = (char *) xmalloc (strlen (tempname) + 50);
+         sprintf (message, "%s--see source file lib-src/movemail.c",
+                  tempname);
+         pfatal_with_name (message);
+       }
+      close (desc);
+
+      tem = link (tempname, lockname);
+      unlink (tempname);
+      if (tem >= 0)
+       break;
+      sleep (1);
+
+      /* If lock file is five minutes old, unlock it.
+        Five minutes should be good enough to cope with crashes
+        and wedgitude, and long enough to avoid being fooled
+        by time differences between machines.  */
+      if (stat (lockname, &st) >= 0)
+       {
+         now = time (0);
+         if (st.st_ctime < now - 300)
+           unlink (lockname);
+       }
+    }
+  strcpy(dotlock_filename, filename);
+}
+
+static void
+unlock_dot(char *filename)
+{
+  unlink(dot_filename(filename));
+}
+
+static void
+maybe_unlock_dot(void)
+{
+  if (dotlock_filename)
+    unlock_dot(dotlock_filename);
+}
+
 /* Print error message and exit.  */
 
 static void
 fatal (char *s1, char *s2)
 {
-  if (delete_lockname)
-    unlink (delete_lockname);
+  maybe_unlock_dot();
   error (s1, s2, NULL);
   exit (1);
 }
@@ -562,7 +700,7 @@ xmalloc (unsigned int size)
     fatal ("virtual memory exhausted", 0);
   return result;
 }
-\f
+
 /* This is the guts of the interface to the Post Office Protocol.  */
 
 #ifdef MAIL_USE_POP
@@ -599,7 +737,7 @@ popmail (char *user, char *outfile, char *password)
   FILE *mbf;
   popserver server;
 
-  VERBOSE(("opening server\r"));
+  VERBOSE(("opening server\n"));
   server = pop_open (0, user, password, POP_NO_GETPASS);
   if (! server)
     {
@@ -607,7 +745,7 @@ popmail (char *user, char *outfile, char *password)
       return (1);
     }
 
-  VERBOSE(("stat'ing messages\r"));
+  VERBOSE(("stat'ing messages\n"));
   if (pop_stat (server, &nmsgs, &nbytes))
     {
       error (pop_error, NULL, NULL);
@@ -632,8 +770,8 @@ popmail (char *user, char *outfile, char *password)
       error ("Error in open: %s, %s", strerror (errno), outfile);
       return (1);
     }
-#ifndef __CYGWIN32__
-  fchown (mbfi, getuid (), -1);
+#if !defined(__CYGWIN32__) && !defined(WINDOWSNT)
+  fchown (mbfi, getuid (), (gid_t) -1);
 #endif
 
   if ((mbf = fdopen (mbfi, "wb")) == NULL)
@@ -648,13 +786,13 @@ popmail (char *user, char *outfile, char *password)
   for (idx = 0; idx < nmsgs; idx++)
     {
       i = reverse ? nmsgs - idx : idx + 1;
-      VERBOSE(("checking message %d     \r", i));
+      VERBOSE(("checking message %d     \n", i));
       
       if (!regexp_pattern 
          || 
          pop_search_top (server, i, match_lines, regexp_pattern) == POP_RETRIEVED)
        {
-         VERBOSE(("retrieving message %d     \r", i));
+         VERBOSE(("retrieving message %d     \n", i));
           mbx_delimit_begin (mbf);
          if (pop_retr (server, i, mbx_write, mbf) != POP_RETRIEVED)
            {
@@ -683,7 +821,7 @@ popmail (char *user, char *outfile, char *password)
    *      directories have lost mail when over quota because these checks were
    *      not made in previous versions of movemail. */
 
-#ifdef BSD
+#ifdef HAVE_FSYNC
   if (fsync (mbfi) < 0)
     {
       error ("Error in fsync: %s", strerror (errno), NULL);
@@ -703,7 +841,7 @@ popmail (char *user, char *outfile, char *password)
        {
          if (retrieved_list[i] == 1)
            {
-             VERBOSE(("deleting message %d     \r", i));
+             VERBOSE(("deleting message %d     \n", i));
              if (pop_delete (server, i))
                {
                  error (pop_error, NULL, NULL);
@@ -725,7 +863,7 @@ popmail (char *user, char *outfile, char *password)
 }
 
 static int
-pop_retr (popserver server, int msgno, int (*action)(), void *arg)
+pop_retr (popserver server, int msgno, int (*action)(char *, FILE *), FILE *arg)
 {
   char *line;
   int ret;
@@ -847,7 +985,7 @@ mbx_delimit_end (FILE *mbf)
 /* Turn a name, which is an ed-style (but Emacs syntax) regular
    expression, into a real regular expression by compiling it. */
 static struct re_pattern_buffer*
-compile_regex (char* regexp_pattern)
+compile_regex (char* pattern)
 {
   char *err;
   struct re_pattern_buffer *patbuf=0;
@@ -858,7 +996,7 @@ compile_regex (char* regexp_pattern)
   patbuf->buffer = NULL;
   patbuf->allocated = 0;
 
-  err = (char*) re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
+  err = (char*) re_compile_pattern (pattern, strlen (pattern), patbuf);
   if (err != NULL)
     {
       error ("%s while compiling pattern", err, NULL);
@@ -871,9 +1009,9 @@ compile_regex (char* regexp_pattern)
 
 
 #endif /* MAIL_USE_POP */
-\f
+
 #ifndef HAVE_STRERROR
-static char *
+char *
 strerror (int errnum)
 {
   extern char *sys_errlist[];