]> Pileus Git - ~andy/fetchmail/blobdiff - lock.c
Update.
[~andy/fetchmail] / lock.c
diff --git a/lock.c b/lock.c
index 5780c05622670f86406ba5ffbe6e93fcd9363f87..5d41c587e645496d55fddf7f4c93a947fddd7bf7 100644 (file)
--- a/lock.c
+++ b/lock.c
@@ -6,13 +6,18 @@
 #include "config.h"
 
 #include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h> /* strcat() */
+#endif
 #if defined(STDC_HEADERS)
 #include <stdlib.h>
 #endif
 #if defined(HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
+#include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
 
 #include "fetchmail.h"
 #include "i18n.h"
@@ -25,12 +30,14 @@ void lock_setup(void)
 {
     /* set up to do lock protocol */
 #define        FETCHMAIL_PIDFILE       "fetchmail.pid"
-    if (!getuid()) {
-       xalloca(lockfile, char *,
-               sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE));
-       sprintf(lockfile, "%s/%s", PID_DIR, FETCHMAIL_PIDFILE);
+    if (getuid() == ROOT_UID) {
+       lockfile = (char *)xmalloc(
+               sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE) + 1);
+       strcpy(lockfile, PID_DIR);
+       strcat(lockfile, "/");
+       strcat(lockfile, FETCHMAIL_PIDFILE);
     } else {
-       xalloca(lockfile, char *, strlen(fmhome) + sizeof(FETCHMAIL_PIDFILE) + 2);
+       lockfile = (char *)xmalloc(strlen(fmhome)+sizeof(FETCHMAIL_PIDFILE)+2);
        strcpy(lockfile, fmhome);
        strcat(lockfile, "/");
         if (fmhome == home)
@@ -40,11 +47,7 @@ void lock_setup(void)
 #undef FETCHMAIL_PIDFILE
 }
 
-#ifdef HAVE_ON_EXIT
-static void unlockit(int n, void *p)
-#else
 static void unlockit(void)
-#endif
 /* must-do actions for exit (but we can't count on being able to do malloc) */
 {
     if (lockfile && lock_acquired)
@@ -57,28 +60,43 @@ void lock_dispose(void)
 #ifdef HAVE_ATEXIT
     atexit(unlockit);
 #endif
-#ifdef HAVE_ON_EXIT
-    on_exit(unlockit, (char *)NULL);
-#endif
 }
 
 int lock_state(void)
 {
-    int        pid, st;
+    int                pid, st;
     FILE       *lockfp;
     int                bkgd = FALSE;
 
-    pid = 0;
-    if ((lockfp = fopen(lockfile, "r")) != NULL )
+    if ((lockfp = fopen(lockfile, "r")) != NULL)
     {
-       bkgd = (fscanf(lockfp, "%d %d", &pid, &st) == 2);
+       int args = fscanf(lockfp, "%d %d", &pid, &st);
+       bkgd = (args == 2);
+
+       if (ferror(lockfp)) {
+           fprintf(stderr, GT_("fetchmail: error reading lockfile \"%s\": %s\n"),
+                   lockfile, strerror(errno));
+           exit(PS_EXCLUDE);
+       }
 
-       if (kill(pid, 0) == -1) {
-           fprintf(stderr,_("fetchmail: removing stale lockfile\n"));
+       if (args == 0 || kill(pid, 0) == -1) {
            pid = 0;
-           unlink(lockfile);
+           if (unlink(lockfile)) {
+              if (errno != ENOENT) {
+                  perror(lockfile);
+              }
+           } else {
+               fprintf(stderr,GT_("fetchmail: removing stale lockfile\n"));
+           }
+       }
+       fclose(lockfp); /* not checking should be safe, file mode was "r" */
+    } else {
+       pid = 0;
+       if (errno != ENOENT) {
+           fprintf(stderr, GT_("fetchmail: error opening lockfile \"%s\": %s\n"),
+                   lockfile, strerror(errno));
+           exit(PS_EXCLUDE);
        }
-       fclose(lockfp); /* not checking should be safe, file mode was "r" */
     }
 
     return(bkgd ? -pid : pid);
@@ -94,37 +112,37 @@ void lock_or_die(void)
 /* get a lock on a given host or exit */
 {
     int fd;
-    char       tmpbuf[20];
+    char       tmpbuf[50];
 
-#ifndef O_SYNC
-#define O_SYNC 0       /* use it if we have it */
-#endif
-    if (!lock_acquired)
-    {
-      if ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_SYNC, 0666)) != -1)
-      {
-         sprintf(tmpbuf,"%d", getpid());
-         write(fd, tmpbuf, strlen(tmpbuf));
-         if (run.poll_interval)
-         {
-             sprintf(tmpbuf," %d", run.poll_interval);
-             write(fd, tmpbuf, strlen(tmpbuf));
-         }
-         close(fd);    /* should be safe, fd was opened with O_SYNC */
-         lock_acquired = TRUE;
-      }
-      else
-      {
-         fprintf(stderr,       _("fetchmail: lock creation failed.\n"));
-         exit(PS_EXCLUDE);
-      }
+    if (!lock_acquired) {
+       int e = 0;
+
+       if ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, 0666)) != -1) {
+           snprintf(tmpbuf, sizeof(tmpbuf), "%ld\n", (long)getpid());
+           if (write(fd, tmpbuf, strlen(tmpbuf)) < strlen(tmpbuf)) e = 1;
+           if (run.poll_interval)
+           {
+               snprintf(tmpbuf, sizeof(tmpbuf), "%d\n", run.poll_interval);
+               if (write(fd, tmpbuf, strlen(tmpbuf)) < strlen(tmpbuf)) e = 1;
+           }
+           if (fsync(fd)) e = 1;
+           if (close(fd)) e = 1;
+       } else {
+           e = 1;
+       }
+       if (e == 0) {
+           lock_acquired = TRUE;
+       } else {
+           perror(lockfile);
+           fprintf(stderr, GT_("fetchmail: lock creation failed.\n"));
+           exit(PS_EXCLUDE);
+       }
     }
 }
 
-void lock_release(void)
+void fm_lock_release(void)
 /* release a lock on a given host */
 {
     unlink(lockfile);
 }
-
 /* lock.c ends here */