X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/bf83d8d38bc9a0f3b3574eb6641b619e68d7a796..a85c067ba6c6940512cf57ec213277a370d87e70:/src/src/exim_lock.c diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c index 0c60ce107..1a54a92ad 100644 --- a/src/src/exim_lock.c +++ b/src/src/exim_lock.c @@ -1,5 +1,3 @@ -/* $Cambridge: exim/src/src/exim_lock.c,v 1.4 2010/05/29 12:11:48 pdp Exp $ */ - /* A program to lock a file exactly as Exim would, for investigation of interlocking problems. @@ -11,6 +9,9 @@ Options: -fcntl use fcntl() lock Default is -fcntl -lockfile. Argument: the name of the lock file + +Copyright (c) The Exim Maintainers 2016 - 2021 +SPDX-License-Identifier: GPL-2.0-only */ #include "os.h" @@ -38,7 +39,7 @@ in sys/file.h. */ #endif -typedef int BOOL; +typedef unsigned BOOL; #define FALSE 0 #define TRUE 1 @@ -72,6 +73,10 @@ the other stuff in os.c, so force the other macros to omit it. */ #define FIND_RUNNING_INTERFACES #endif +#ifndef OS_GET_DNS_RESOLVER_RES + #define OS_GET_DNS_RESOLVER_RES +#endif + #include "../src/os.c" @@ -83,7 +88,6 @@ the other stuff in os.c, so force the other macros to omit it. */ static void sigalrm_handler(int sig) { -sig = sig; /* Keep picky compilers happy */ sigalrm_seen = TRUE; } @@ -173,7 +177,7 @@ int fd = -1; int hd = -1; int md = -1; int yield = 0; -int now = time(NULL); +time_t now = time(NULL); BOOL use_lockfile = FALSE; BOOL use_fcntl = FALSE; BOOL use_flock = FALSE; @@ -183,7 +187,8 @@ BOOL quiet = FALSE; BOOL restore_times = FALSE; char *filename; char *lockname = NULL, *hitchname = NULL; -char *primary_hostname, *command; +char *primary_hostname; +const char *command; struct utsname s; char buffer[256]; char tempname[256]; @@ -213,7 +218,7 @@ for (i = 1; i < argc; i++) else usage(); } -if (quiet) verbose = 0; +if (quiet) verbose = FALSE; /* Can't use flock() if the OS doesn't provide it */ @@ -297,8 +302,10 @@ if (use_lockfile) lockname = malloc(len + 8); sprintf(lockname, "%s.lock", filename); hitchname = malloc(len + 32 + (int)strlen(primary_hostname)); + + /* Presumably, this must match appendfile.c */ sprintf(hitchname, "%s.%s.%08x.%08x", lockname, primary_hostname, - now, (int)getpid()); + (unsigned int)now, (unsigned int)getpid()); if (verbose) printf("exim_lock: lockname = %s\n hitchname = %s\n", lockname, @@ -317,7 +324,7 @@ for (j = 0; j < lock_retries; j++) if (use_lockfile) { - int rc; + int rc, rc2; if (verbose) printf("exim_lock: creating lock file\n"); hd = open(hitchname, O_WRONLY | O_CREAT | O_EXCL, 0440); if (hd < 0) @@ -329,11 +336,12 @@ for (j = 0; j < lock_retries; j++) /* Apply hitching post algorithm. */ - if ((rc = link(hitchname, lockname)) != 0) fstat(hd, &statbuf); + if ((rc = link(hitchname, lockname)) != 0) + rc2 = fstat(hd, &statbuf); (void)close(hd); unlink(hitchname); - if (rc != 0 && statbuf.st_nlink != 2) + if (rc != 0 && (rc2 != 0 || statbuf.st_nlink != 2)) { printf("exim_lock: failed to link hitching post to lock file\n"); hd = -1; @@ -349,8 +357,7 @@ for (j = 0; j < lock_retries; j++) /* Open the file for writing. */ - fd = open(filename, O_RDWR + O_APPEND); - if (fd < 0) + if ((fd = open(filename, O_RDWR + O_APPEND)) < 0) { printf("exim_lock: failed to open %s for writing: %s\n", filename, strerror(errno)); @@ -369,7 +376,6 @@ for (j = 0; j < lock_retries; j++) a timeout changes it to blocking. */ if (!use_mbx && (use_fcntl || use_flock)) - { if (apply_lock(fd, F_WRLCK, use_fcntl, lock_fcntl_timeout, use_flock, lock_flock_timeout) >= 0) { @@ -380,8 +386,8 @@ for (j = 0; j < lock_retries; j++) } break; } - else goto RETRY; /* Message already output */ - } + else + goto RETRY; /* Message already output */ /* Lock using MBX rules. This is complicated and is documented with the source of the c-client library that goes with Pine and IMAP. What has to @@ -578,14 +584,41 @@ else if (restore_times) { struct stat strestore; +#ifdef EXIM_HAVE_FUTIMENS + int fd = open(filename, O_RDWR); /* use fd for both get & restore */ + struct timespec tt[2]; + + if (fd < 0) + { + printf("open '%s': %s\n", filename, strerror(errno)); + yield = 1; + goto CLEAN_UP; + } + if (fstat(fd, &strestore) != 0) + { + printf("fstat '%s': %s\n", filename, strerror(errno)); + yield = 1; + close(fd); + goto CLEAN_UP; + } + i = system(command); + tt[0] = strestore.st_atim; + tt[1] = strestore.st_mtim; + (void) futimens(fd, tt); + (void) close(fd); +#else struct utimbuf ut; + stat(filename, &strestore); - (void)system(command); + i = system(command); ut.actime = strestore.st_atime; ut.modtime = strestore.st_mtime; utime(filename, &ut); +#endif } -else (void)system(command); +else i = system(command); + +if(i && !quiet) printf("warning: nonzero status %d\n", i); /* Remove the locks and exit. Unlink the /tmp file if we can get an exclusive lock on the mailbox. This should be a non-blocking lock call, as there is no