#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"
{
/* 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)
#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)
#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);
/* 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 */