#include "config.h"
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <fcntl.h>
#include <signal.h>
#include "fetchmail.h"
#include "i18n.h"
static char *lockfile;
static int lock_acquired;
void lock_setup(void)
{
#define FETCHMAIL_PIDFILE "fetchmail.pid"
if (!getuid()) {
lockfile = (char *)xmalloc(
sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE) + 1);
sprintf(lockfile, "%s/%s", PID_DIR, FETCHMAIL_PIDFILE);
} else {
lockfile = (char *)xmalloc(strlen(fmhome)+sizeof(FETCHMAIL_PIDFILE)+2);
strcpy(lockfile, fmhome);
strcat(lockfile, "/");
if (fmhome == home)
strcat(lockfile, ".");
strcat(lockfile, FETCHMAIL_PIDFILE);
}
#undef FETCHMAIL_PIDFILE
}
#ifdef HAVE_ON_EXIT
static void unlockit(int n, void *p)
#else
static void unlockit(void)
#endif
{
if (lockfile && lock_acquired)
unlink(lockfile);
}
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;
FILE *lockfp;
int bkgd = FALSE;
pid = 0;
if ((lockfp = fopen(lockfile, "r")) != NULL )
{
bkgd = (fscanf(lockfp, "%d %d", &pid, &st) == 2);
if (kill(pid, 0) == -1) {
fprintf(stderr,GT_("fetchmail: removing stale lockfile\n"));
pid = 0;
unlink(lockfile);
}
fclose(lockfp);
}
return(bkgd ? -pid : pid);
}
void lock_assert(void)
{
lock_acquired = TRUE;
}
void lock_or_die(void)
{
int fd;
char tmpbuf[20];
#ifndef O_SYNC
#define O_SYNC 0
#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);
lock_acquired = TRUE;
}
else
{
fprintf(stderr, GT_("fetchmail: lock creation failed.\n"));
exit(PS_EXCLUDE);
}
}
}
void lock_release(void)
{
unlink(lockfile);
}