liblockfile-1.09/0000755000175000017500000000000011620533512013276 5ustar mikevsmikevsliblockfile-1.09/autoconf.h.in0000644000175000017500000000137507254561501015707 0ustar mikevsmikevs/* autoconf.h.in. Generated automatically from configure.in by autoheader. */ /* acconfig.h - template used by autoheader to create config.h.in config.h.in - used by autoconf to create config.h config.h - created by autoconf; contains defines generated by autoconf */ /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Is the mailspool group writable */ #undef MAILGROUP /* Define if you have the utime function. */ #undef HAVE_UTIME /* Define if you have the utimes function. */ #undef HAVE_UTIMES /* Define if you have the header file. */ #undef HAVE_GETOPT_H /* Define if you have the header file. */ #undef HAVE_PATHS_H /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H liblockfile-1.09/dotlockfile.10000644000175000017500000001037711620533241015666 0ustar mikevsmikevs.TH DOTLOCKFILE 1 "September 8, 2009" "" "Cistron Utilities" .SH NAME dotlockfile \- Utility to manage lockfiles .SH SYNOPSIS .B /usr/bin/dotlockfile .RB [ \-l .RB [ \-r .IR retries ] .RB | \-u | \-t | \-c ] .RB [ \-p ] .RB [ \-m | lockfile ] .SH DESCRIPTION .B dotlockfile is a command line utility to reliably create, test and remove lockfiles. It creates lockfiles .I reliably on local and NFS filesystems, because the crucial steps of testing for a preexisting lockfile and creating it are performed .I atomically by a .I single call to .IR link (2). Manpage .IR lockfile_create (3) describes the used algorithm. .PP .B dotlockfile is installed with attribute .BI SETGID \ mail and thus can also be used to lock and unlock mailboxes .I even if the mailspool directory is only writable by group mail. .PP The name .B dotlockfile comes from the way mailboxes are locked for updates on a lot of UNIX systems. A lockfile is created with the same filename as the mailbox but with the string "\fI.lock\fR" appended. .PP The names .B dotlock and .B lockfile were already taken \- hence the name \fBdotlockfile\fR \fI:)\fR. .SH OPTIONS .IP "\fB\-l\fR" Create a lockfile if no preexisting valid lockfile is found, else wait and retry according to option \fB\-r\fR. This option is the default. A lockfile is treated as valid, .br \[bu]\ \ if it holds the .I process\-id of a running process, .br \[bu]\ \ or if it does not hold any .I process\-id and has been touched less than 5\ minutes ago (timestamp is younger than 5\ minutes). .IP "\fB\-r retries\fR" The number of times .B dotlockfile retries to acquire the lock if it failed the first time before giving up. The initial sleep after failing to acquire the lock is 5\ seconds. After each retry the sleep intervall is increased incrementally by 5\ seconds up to a maximum sleep of 60\ seconds between tries. The default number of retries is 5. To try only once, use "\fB\-r 0\fR". To try indefinitely, use "\fB\-r -1\fR". .IP "\fB\-u\fR" Remove a lockfile. .IP "\fB\-t\fR" Touch an existing lockfile (update the timestamp). Useful for lockfiles on NFS filesystems. For lockfiles on local filesystems the .B \-p option is preferable. .IP "\fB\-c\fR" For debugging only: Check for the existence of a \fIvalid\fR lockfile. Note: Testing for a preexisting lockfile and writing of the lockfile .I must be done by the .I same "\fBdotlockfile \-l\fR" or "\fBdotlockfile \-m\fR" command, else the lockfile creation cannot be reliable. .IP "\fB\-p\fR" Write the .I process\-id of the calling process into the lockfile. Also when testing for an existing lockfile, check the contents for the .I process\-id of a running process to verify if the lockfile is still valid. Obviously useful only for lockfiles on local filesystems. .IP "\fB\-m\fR" Lock or unlock the current users mailbox. The path to the mailbox is the default system mailspool directory (usually .IR /var/mail ) with the username as gotten from .IR getpwuid () appended. If the environment variable .I $MAIL is set, that is used instead. Then the string "\fI.lock\fR" is appended to get the name of the actual lockfile. .IP lockfile The lockfile to be created or removed. Must not be specified, if the \fB\-m\fR option is in effect. .SH RETURN\ VALUE Zero on success, and non\-zero on failure. For the \fB\-c\fR option, sucess means that a valid lockfile is already present. When locking (the default, or with the \fB\-l\fR option) .B dotlockfile returns the same values as the library function .IR lockfile_create (3). Unlocking a non\-existant lockfile is not an error. .SH NOTES The lockfile is created exactly as named on the command line. The extension "\fI.lock\fR" is \fInot\fR automatically appended. .PP This utility is a lot like the .IR lockfile (1) utility included with .IR procmail , and the .IR mutt_dotlock (1) utility included with .IR mutt . However the command\-line arguments differ, and so does the return status. It is believed, that .I dotlockfile is the most flexible implementation, since it automatically detects when it needs to use priviliges to lock a mailbox, and does it safely. .PP The above mentioned .IR lockfile_create (3) manpage is present in the .I liblockfile\-dev package. .SH BUGS None known. .SH SEE\ ALSO .IR lockfile_create (3), .IR maillock (3) .SH AUTHOR Miquel van Smoorenburg, miquels@cistron.nl liblockfile-1.09/maillock.h.in0000644000175000017500000000155107666643456015701 0ustar mikevsmikevs/* * Copyright (C) 1999 Miquel van Smoorenburg * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * On Debian GNU/Linux systems, the complete text of the GNU Library * General Public License can be found in `/usr/doc/copyright/LGPL'. * You can also find a copy on the GNU website at http://www.gnu.org/ */ #ifndef _MAILLOCK_H #define _MAILLOCK_H #ifdef __cplusplus extern "C" { #endif #ifndef _PATH_MAILDIR @PATHMAILDIR@ #endif #define MAILDIR (_PATH_MAILDIR "/") /* * Prototypes. */ int maillock(const char *name, int retries); void touchlock(); void mailunlock(); #ifdef __cplusplus } #endif #include #endif /* _MAILLOCK_H */ liblockfile-1.09/lockfile.c0000644000175000017500000002475411603642442015252 0ustar mikevsmikevs/* * lockfile.c Safely creates a lockfile, also over NFS. * This file also holds the implementation for * the Svr4 maillock functions. * * Version: @(#)lockfile.c 1.06 04-Jun-2004 miquels@cistron.nl * * Copyright (C) Miquel van Smoorenburg 1997,1998,1999,2004. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. */ #include "autoconf.h" #include #if HAVE_SYS_PARAM_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UTIME #include #endif #ifdef LIB static char *mlockfile; static int islocked = 0; #endif #ifndef LIB extern int check_sleep(int); #endif #if !defined(LIB) || defined(MAILGROUP) /* * See if we can write to the directory. * Returns: -1 fail * 0 OK writable */ #ifdef LIB static #endif int eaccess_write(char *fn, gid_t gid, struct stat *st) { struct stat tmp; uid_t uid = geteuid(); gid_t *aux; int n, i; if (st == NULL) st = &tmp; if (stat(fn, st) != 0) return -1; errno = EPERM; if (uid == 0) return 0; if (st->st_uid == uid) return (st->st_mode & 0200) ? 0 : -1; if (st->st_gid == gid) return (st->st_mode & 0020) ? 0 : -1; if ((n = getgroups(0, NULL)) > 0) { aux = malloc(n * sizeof(gid_t)); if (aux && getgroups(n, aux) == 0) { for (i = 0; i < n; i++) if (st->st_gid == aux[i]) { free(aux); return (st->st_mode & 0020) ? 0 : -1; } } free(aux); } return (st->st_mode & 0002) ? 0 : -1; } #endif #if defined(LIB) && defined(MAILGROUP) /* * Can we write to the directory of the lockfile ? */ static int need_extern(const char *file) { gid_t egid = getegid(); struct stat st; static gid_t mailgid = -1; char *dir; char *p; int ret; /* * Find directory. */ if ((dir = (char *)malloc(strlen(file) + 1)) == NULL) return L_ERROR; strcpy(dir, file); if ((p = strrchr(dir, '/')) != NULL) *p = 0; else strcpy(dir, "."); if (eaccess_write(dir, egid, NULL) >= 0) { free(dir); return 0; } /* * See if accessible for group mail. We find out what * "group mail" is by statting LOCKPROG, that saves us * from having to call getgrgid() in a library. */ if (mailgid == (gid_t)-1) { if (stat(LOCKPROG, &st) < 0 || !(st.st_mode & S_ISGID)) return 0; mailgid = st.st_gid; } ret = eaccess_write(dir, mailgid, NULL) >= 0; free (dir); return ret; } /* * Call external program to do the actual locking. */ static int do_extern(char *opt, const char *lockfile, int retries, int flags) { sigset_t set, oldset; char buf[4]; pid_t pid, n; int st; /* * Block SIGCHLD. The main program might have installed * handlers we don't want to call. */ sigemptyset(&set); sigaddset(&set, SIGCHLD); sigprocmask(SIG_BLOCK, &set, &oldset); /* * Fork, execute locking program and wait. */ if ((pid = fork()) < 0) return L_ERROR; if (pid == 0) { sprintf(buf, "%d", retries % 1000); execl(LOCKPROG, LOCKPROG, opt, "-r", buf, "-q", (flags & L_PID) ? "-p" : "-N", lockfile, NULL); _exit(L_ERROR); } /* * Wait for return status - do something appropriate * if program died or returned L_ERROR. */ while ((n = waitpid(pid, &st, 0)) != pid) if (n < 0 && errno != EINTR) break; if (!sigismember(&oldset, SIGCHLD)) sigprocmask(SIG_UNBLOCK, &set, NULL); if (n < 0) return L_ERROR; if (!WIFEXITED(st) || WEXITSTATUS(st) == L_ERROR) { errno = EINTR; return L_ERROR; } return WEXITSTATUS(st); } #endif /* * Create a lockfile. */ #ifdef LIB static #endif int lockfile_create_save_tmplock(const char *lockfile, char *tmplock, int tmplocksz, int retries, int flags) { struct stat st, st1; char sysname[256]; char buf[8]; char *p; int sleeptime = 0; int statfailed = 0; int fd; int i, e, len; int dontsleep = 1; int tries = retries + 1; #ifdef MAXPATHLEN /* * Safety measure. */ if (strlen(lockfile) + 32 > MAXPATHLEN) { errno = ENAMETOOLONG; return L_ERROR; } #endif if (strlen(lockfile) + 32 + 1 > tmplocksz) { errno = EINVAL; return L_ERROR; } #if defined(LIB) && defined(MAILGROUP) if (need_extern(lockfile)) return do_extern("-l", lockfile, retries, flags); #endif /* * Create a temp lockfile (hopefully unique) and write * either our pid/ppid in it, or 0\0 for svr4 compatibility. */ if (gethostname(sysname, sizeof(sysname)) < 0) return L_ERROR; if ((p = strchr(sysname, '.')) != NULL) *p = 0; /* strcpy is safe: length-check above, limited at sprintf below */ strcpy(tmplock, lockfile); if ((p = strrchr(tmplock, '/')) == NULL) p = tmplock; else p++; sprintf(p, ".lk%05d%x%s", (int)getpid(), (int)time(NULL) & 15, sysname); i = umask(022); fd = open(tmplock, O_WRONLY|O_CREAT|O_EXCL, 0644); e = errno; umask(i); if (fd < 0) { tmplock[0] = 0; errno = e; return L_TMPLOCK; } if (flags & (L_PID | L_PPID)) { sprintf(buf, "%d\n", (flags & L_PID) ? (int)getpid() : (int)getppid()); p = buf; len = strlen(buf); } else { p = "0\n"; len = 2; } i = write(fd, p, len); e = errno; if (close(fd) != 0) { e = errno; i = -1; } if (i != len) { unlink(tmplock); tmplock[0] = 0; errno = i < 0 ? e : EAGAIN; return L_TMPWRITE; } /* * Now try to link the temporary lock to the lock. */ for (i = 0; i < tries && tries > 0; i++) { if (!dontsleep) { sleeptime += 5; if (sleeptime > 60) sleeptime = 60; #ifdef LIB sleep(sleeptime); #else if ((e = check_sleep(sleeptime)) != 0) { unlink(tmplock); tmplock[0] = 0; return e; } #endif } dontsleep = 0; /* * Now lock by linking the tempfile to the lock. * * KLUDGE: some people say the return code of * link() over NFS can't be trusted. * EXTRA FIX: the value of the nlink field * can't be trusted (may be cached). */ (void)link(tmplock, lockfile); if (lstat(tmplock, &st1) < 0) { tmplock[0] = 0; return L_ERROR; /* Can't happen */ } if (lstat(lockfile, &st) < 0) { if (statfailed++ > 5) { /* * Normally, this can't happen; either * another process holds the lockfile or * we do. So if this error pops up * repeatedly, just exit... */ e = errno; (void)unlink(tmplock); tmplock[0] = 0; errno = e; return L_MAXTRYS; } continue; } /* * See if we got the lock. */ if (st.st_rdev == st1.st_rdev && st.st_ino == st1.st_ino) { (void)unlink(tmplock); tmplock[0] = 0; return L_SUCCESS; } statfailed = 0; /* * If there is a lockfile and it is invalid, * remove the lockfile. */ if (lockfile_check(lockfile, flags) == -1) { unlink(lockfile); dontsleep = 1; /* * If the lockfile was invalid, then the first * try wasn't valid either - make sure we * try at least once more. */ if (tries == 1) tries++; } } (void)unlink(tmplock); tmplock[0] = 0; errno = EAGAIN; return L_MAXTRYS; } int lockfile_create(const char *lockfile, int retries, int flags) { char *tmplock; int l, r, e; l = strlen(lockfile)+32+1; if ((tmplock = (char *)malloc(l)) == NULL) return L_ERROR; tmplock[0] = 0; r = lockfile_create_save_tmplock(lockfile, tmplock, l, retries, flags); e = errno; free(tmplock); errno = e; return r; } /* * See if a valid lockfile is present. * Returns 0 if so, -1 if not. */ int lockfile_check(const char *lockfile, int flags) { struct stat st, st2; char buf[16]; time_t now; pid_t pid; int fd, len, r; if (stat(lockfile, &st) < 0) return -1; /* * Get the contents and mtime of the lockfile. */ time(&now); pid = 0; if ((fd = open(lockfile, O_RDONLY)) >= 0) { /* * Try to use 'atime after read' as now, this is * the time of the filesystem. Should not get * confused by 'atime' or 'noatime' mount options. */ len = 0; if (fstat(fd, &st) == 0 && (len = read(fd, buf, sizeof(buf))) >= 0 && fstat(fd, &st2) == 0 && st.st_atime != st2.st_atime) now = st.st_atime; close(fd); if (len > 0 && (flags & (L_PID|L_PPID))) { buf[len] = 0; pid = atoi(buf); } } if (pid > 0) { /* * If we have a pid, see if the process * owning the lockfile is still alive. */ r = kill(pid, 0); if (r == 0 || errno == EPERM) return 0; if (r < 0 && errno == ESRCH) return -1; /* EINVAL - FALLTHRU */ } /* * Without a pid in the lockfile, the lock * is valid if it is newer than 5 mins. */ if (now < st.st_mtime + 300) return 0; return -1; } /* * Remove a lock. */ int lockfile_remove(const char *lockfile) { #if defined(LIB) && defined(MAILGROUP) if (need_extern(lockfile)) return do_extern("-u", lockfile, 0, 0); #endif return (unlink(lockfile) < 0 && errno != ENOENT) ? -1 : 0; } /* * Touch a lock. */ int lockfile_touch(const char *lockfile) { #ifdef HAVE_UTIME return utime(lockfile, NULL); #else return utimes(lockfile, NULL); #endif } #ifdef LIB /* * Lock a mailfile. This looks a lot like the SVR4 function. * Arguments: lusername, retries. */ int maillock(const char *name, int retries) { char *p, *mail; char *newlock; int i, e; int len, newlen; if (islocked) return 0; #ifdef MAXPATHLEN if (strlen(name) + sizeof(MAILDIR) + 6 > MAXPATHLEN) { errno = ENAMETOOLONG; return L_NAMELEN; } #endif /* * If $MAIL is for the same username as "name" * then use $MAIL instead. */ len = strlen(name)+strlen(MAILDIR)+6; mlockfile = (char *)malloc(len); if (!mlockfile) return L_ERROR; sprintf(mlockfile, "%s%s.lock", MAILDIR, name); if ((mail = getenv("MAIL")) != NULL) { if ((p = strrchr(mail, '/')) != NULL) p++; else p = mail; if (strcmp(p, name) == 0) { newlen = strlen(mail)+6; #ifdef MAXPATHLEN if (newlen > MAXPATHLEN) { errno = ENAMETOOLONG; return L_NAMELEN; } #endif if (newlen > len) { newlock = (char *)realloc (mlockfile, newlen); if (newlock == NULL) { e = errno; free (mlockfile); mlockfile = NULL; errno = e; return L_ERROR; } mlockfile = newlock; } sprintf(mlockfile, "%s.lock", mail); } } i = lockfile_create(mlockfile, retries, 0); if (i == 0) islocked = 1; return i; } void mailunlock(void) { if (!islocked) return; lockfile_remove(mlockfile); free (mlockfile); islocked = 0; } void touchlock(void) { lockfile_touch(mlockfile); } #endif liblockfile-1.09/COPYRIGHT0000644000175000017500000000265211620531737014605 0ustar mikevsmikevs Liblockfile is (c) Copyright 1999-2011 Miquel van Smoorenburg. Changes submitted by other people in the form of patches remain under their copyright but are licensed under the same conditions as liblockfile. See the ChangeLog file for details. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. On Debian GNU/Linux systems, the complete text of the GNU Lesser General Public License can be found in `/usr/share/common-licenses/LGPL-2'. You can also find a copy on the GNU website at http://www.gnu.org/ Dotlockfile is (c) Copyright 1999-2011 Miquel van Smoorenburg. Changes submitted by other people in the form of patches remain under their copyright but are licensed under the same conditions as dotlockfile. See the ChangeLog file for details. This program 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 of the License, or (at your option) any later version. On Debian GNU/Linux systems, the complete text of the GNU Library General Public License can be found in `/usr/share/common-licenses/LGPL-2'. You can also find a copy on the GNU website at http://www.gnu.org/ liblockfile-1.09/lockfile.h0000644000175000017500000000267507254561500015257 0ustar mikevsmikevs/* * Copyright (C) 1999 Miquel van Smoorenburg * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * On Debian GNU/Linux systems, the complete text of the GNU Library * General Public License can be found in `/usr/doc/copyright/LGPL'. * You can also find a copy on the GNU website at http://www.gnu.org/ */ #ifndef _LOCKFILE_H #define _LOCKFILE_H #ifdef __cplusplus extern "C" { #endif /* * Prototypes. */ int lockfile_create(const char *lockfile, int retries, int flags); int lockfile_remove(const char *lockfile); int lockfile_touch(const char *lockfile); int lockfile_check(const char *lockfile, int flags); /* * Return values for lockfile_create() */ #define L_SUCCESS 0 /* Lockfile created */ #define L_NAMELEN 1 /* Recipient name too long */ #define L_TMPLOCK 2 /* Error creating tmp lockfile */ #define L_TMPWRITE 3 /* Can't write pid int tmp lockfile */ #define L_MAXTRYS 4 /* Failed after max. number of attempts */ #define L_ERROR 5 /* Unknown error; check errno */ #define L_MANLOCK 6 /* Cannot set mandatory lock on tempfile */ /* * Flag values for lockfile_create() */ #define L_PID 16 /* Put PID in lockfile */ #define L_PPID 32 /* Put PPID in lockfile */ #ifdef __cplusplus } #endif #endif /* _LOCKFILE_H */ liblockfile-1.09/configure.in0000644000175000017500000000426007254561501015620 0ustar mikevsmikevsAC_INIT(lockfile.c) AC_CONFIG_HEADER(autoconf.h) AC_REVISION($Revision: 1.0 $)dnl dnl Check for GNU cc AC_PROG_CC dnl Set Default CFLAGS if test "$GCC" = "yes"; then CFLAGS="$CFLAGS -Wall -D_GNU_SOURCE" fi TARGETS="static" INSTALL_TARGETS="install_static" dnl extra argument: --enable-shared AC_MSG_CHECKING(build shared libs) AC_ARG_ENABLE(shared, [ --enable-shared Build shared libraries], [ case "$enableval" in no) SHARED=no ;; *) SHARED=yes CFLAGS="$CFLAGS -fPIC -D_REENTRANT" TARGETS="shared" INSTALL_TARGETS="install_shared" ;; esac ], SHARED=no ) AC_SUBST(SHARED) AC_MSG_RESULT($SHARED) dnl extra argument: --with-libnfslock nfslockdir="$libdir" AC_MSG_CHECKING(build libnfslock) AC_ARG_WITH(libnfslock, [ --with-libnfslock[=DIR] Build libnfslock (and install in DIR)], [ case "$withval" in no) LIBNFSLOCK=no ;; *) test "$withval" != "no" && nfslockdir="$withval" LIBNFSLOCK=yes TARGETS="$TARGETS nfslib" INSTALL_TARGETS="$INSTALL_TARGETS install_nfslib" ;; esac ], LIBNFSLOCK=no ) AC_SUBST(LIBNFSLOCK) AC_MSG_RESULT($LIBNFSLOCK) dnl extra argument: --with-mailgroup[=mail] AC_ARG_WITH(mailgroup, [ --with-mailgroup[=group] Run setgid (mail) to write to the mailspool], [ case "$withval" in yes) MAILGROUP="mail" ;; *) MAILGROUP="$withval" ;; esac ] ) if test "$MAILGROUP" != ""; then AC_DEFINE_UNQUOTED(MAILGROUP, "$MAILGROUP") fi AC_SUBST(MAILGROUP) dnl Find ldconfig. AC_PATH_PROG(LDCONFIG, ldconfig,, $PATH:/sbin:/usr/sbin) dnl Check for headers AC_HEADER_STDC AC_CHECK_HEADERS( \ getopt.h \ paths.h \ sys/param.h ) AC_CHECK_FUNCS( \ utime \ utimes \ ) if test "$ac_cv_header_paths_h" != "yes"; then dnl Find out where the mail spool is. AC_MSG_CHECKING(location of your mail spool) MAILSPOOL=/var/spool/mail for dir in /var/mail /var/spool/mail /usr/mail /usr/spool/mail do if test -d $dir; then MAILSPOOL=$dir break fi done PATHMAILDIR="#define _PATH_MAILDIR \"$MAILSPOOL\"" AC_MSG_RESULT($MAILSPOOL) else PATHMAILDIR="#include " fi AC_SUBST(PATHMAILDIR) AC_SUBST(TARGETS) AC_SUBST(INSTALL_TARGETS) AC_SUBST(nfslockdir) AC_OUTPUT(\ ./Makefile \ ./maillock.h \ ) liblockfile-1.09/dotlockfile.c0000644000175000017500000001572411604364723015762 0ustar mikevsmikevs/* * dotlockfile.c Command line version of liblockfile. * Runs setgid mail so is able to lock mailboxes * as well. Liblockfile can call this command. * * Version: @(#)dotlockfile.c 1.1 15-May-2003 miquels@cistron.nl * * Copyright (C) Miquel van Smoorenburg 1999,2003 * * This program 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 * of the License, or (at your option) any later version. */ #include "autoconf.h" #include #if HAVE_SYS_PARAM_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_H #include #endif #ifndef HAVE_GETOPT_H extern int getopt(); extern char *optarg; extern int optind; #endif extern int eaccess_write(char *, gid_t, struct stat *); extern int lockfile_create_save_tmplock(const char *lockfile, char *tmplock, int tmplocksz, int retries, int flags); char *tmplock; /* * If we got SIGINT, SIGQUIT, SIGHUP, remove the * tempfile and re-raise the signal. */ void got_signal(int sig) { if (tmplock && tmplock[0]) unlink(tmplock); signal(sig, SIG_DFL); raise(sig); } /* * Install signal handler only if the signal was * not ignored already. */ int set_signal(int sig, void (*handler)(int)) { struct sigaction sa; if (sigaction(sig, NULL, &sa) < 0) return -1; if (sa.sa_handler == SIG_IGN) return 0; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; return sigaction(sig, &sa, NULL); } /* * Sleep for an amout of time while regulary checking if * our parent is still alive. */ int check_sleep(int sleeptime) { int i; static int ppid = 0; if (ppid == 0) ppid = getppid(); for (i = 0; i < sleeptime; i += 5) { sleep(5); if (kill(ppid, 0) < 0 && errno == ESRCH) return L_ERROR; } return 0; } /* * Is this a lock for a mailbox? We check if the filename * is in ..../USERNAME.lock format, and if we own the file * that we want to lock. */ int ismaillock(char *lockfile, char *username) { struct stat st; char *p; char tmp[1024]; int len; sprintf(tmp, "%.120s.lock", username); if ((p = strrchr(lockfile, '/')) != NULL) p++; else p = lockfile; if (strcmp(p, tmp) != 0) return 0; len = strlen(lockfile); if (len > sizeof(tmp) || len < 5) return 0; strncpy(tmp, lockfile, len - 5); tmp[len - 5] = 0; if (stat(tmp, &st) != 0 || st.st_uid != geteuid()) return 0; return 1; } /* * Split a filename up in file and directory. */ int fn_split(char *fn, char **fn_p, char **dir_p) { static char *buf = NULL; char *p; if (buf) free (buf); buf = (char *) malloc (strlen (fn) + 1); if (! buf) return L_ERROR; strcpy(buf, fn); if ((p = strrchr(buf, '/')) != NULL) { *p++ = 0; *fn_p = p; *dir_p = buf; } else { *fn_p = fn; *dir_p = "."; } return L_SUCCESS; } /* * Return name of lockfile for mail. */ char *mlockname(char *user) { static char *buf = NULL; char *e; if (buf) free(buf); e = getenv("MAIL"); if (e) { buf = (char *)malloc(strlen(e)+6); if (!buf) return NULL; sprintf(buf, "%s.lock", e); } else { buf = (char *)malloc(strlen(MAILDIR)+strlen(user)+6); if (!buf) return NULL; sprintf(buf, "%s%s.lock", MAILDIR, user); } return buf; } /* * Print usage mesage and exit. */ void usage(void) { fprintf(stderr, "Usage: dotlockfile [-l [-r retries] |-u|-t|-c] [-p] [-m|lockfile]\n"); exit(1); } int main(int argc, char **argv) { struct passwd *pwd; struct stat st, st2; gid_t gid; char *dir, *file, *lockfile = NULL; int c, r, l; int retries = 5; int flags = 0; int unlock = 0; int check = 0; int quiet = 0; int touch = 0; set_signal(SIGINT, got_signal); set_signal(SIGQUIT, got_signal); set_signal(SIGHUP, got_signal); set_signal(SIGTERM, got_signal); set_signal(SIGPIPE, got_signal); /* * Get username for mailbox-locks. */ if ((pwd = getpwuid(getuid())) == NULL) { fprintf(stderr, "dotlockfile: You don't exist. Go away.\n"); return L_ERROR; } /* * Process the options. */ while ((c = getopt(argc, argv, "qpNr:mluct")) != EOF) switch(c) { case 'q': quiet = 1; break; case 'p': flags |= L_PPID; break; case 'N': /* NOP */ break; case 'r': retries = atoi(optarg); if (retries <= 0 && retries != -1 && strcmp(optarg, "0") != 0) { fprintf(stderr, "dotlockfile: -r %s: invalid argument\n", optarg); return L_ERROR; } if (retries == -1) { /* 4000 years */ retries = 2147483647; } break; case 'm': lockfile = mlockname(pwd->pw_name); if (!lockfile) { perror("dotlockfile"); return L_ERROR; } break; case 'l': /* default: lock */ break; case 'u': unlock = 1; break; case 'c': check = 1; break; case 't': touch = 1; break; default: usage(); break; } /* * Need a lockfile, ofcourse. */ if (lockfile && optind < argc) usage(); if (lockfile == NULL) { if (optind != argc - 1) usage(); lockfile = argv[optind]; } #ifdef MAXPATHLEN if (strlen(lockfile) >= MAXPATHLEN) { fprintf(stderr, "dotlockfile: %s: name too long\n", lockfile); return L_NAMELEN; } #endif /* * See if we can write into the lock directory. */ r = fn_split(lockfile, &file, &dir); if (r != L_SUCCESS) { perror("dotlockfile"); return L_ERROR; } gid = getgid(); if (eaccess_write(dir, gid, &st) < 0) { if (errno == ENOENT) { enoent: if (!quiet) fprintf(stderr, "dotlockfile: %s: no such directory\n", dir); return L_TMPLOCK; } if ((r = eaccess_write(dir, getegid(), &st) < 0) && errno == ENOENT) goto enoent; if (r < 0 || !ismaillock(lockfile, pwd->pw_name)) { if (!quiet) fprintf(stderr, "dotlockfile: %s: permission denied\n", lockfile); return L_TMPLOCK; } } else setgid(gid); /* * Now we should be able to chdir() to the lock directory. * When we stat("."), it should be the same as at the * eaccess_write() check or someone played symlink() games on us. */ if (chdir(dir) < 0 || stat(".", &st2) < 0) { if (!quiet) fprintf(stderr, "dotlockfile: %s: cannot access directory\n", dir); return L_TMPLOCK; } if (st.st_ino != st2.st_ino || st.st_dev != st2.st_dev) { if (!quiet) fprintf(stderr, "dotlockfile: %s: directory changed underneath us!\n", dir); return L_TMPLOCK; } /* * Simple check for a valid lockfile ? */ if (check) return (lockfile_check(file, flags) < 0) ? 1 : 0; /* * Touch lock ? */ if (touch) return (lockfile_touch(file) < 0) ? 1 : 0; /* * Remove lockfile? */ if (unlock) return (lockfile_remove(file) == 0) ? 0 : 1; /* * No, lock. */ l = strlen(file) + 32 + 1; tmplock = malloc(l); if (tmplock == NULL) { perror("malloc"); exit(L_ERROR); } return lockfile_create_save_tmplock(file, tmplock, l, retries, flags); } liblockfile-1.09/Makefile.in0000644000175000017500000000375011603624034015351 0ustar mikevsmikevs# # Makefile.in Makefile for the liblockfile package # # version: @(#)Makefile.in 1.01 16-Apr-1999 miquels@cistron.nl # VER = 1.0 NVER = 0.1 CFLAGS = @CFLAGS@ -I. LDFLAGS = @LDFLAGS@ CC = @CC@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ mandir = @mandir@ nfslockdir = @nfslockdir@ includedir = @includedir@ MAILGROUP = @MAILGROUP@ all: @TARGETS@ install: @INSTALL_TARGETS@ static: liblockfile.a dotlockfile shared: liblockfile.so dotlockfile nfslib: nfslock.so.$(VER) liblockfile.a: lockfile.o $(AR) rv liblockfile.a lockfile.o liblockfile.so: liblockfile.a $(CC) -fPIC -shared -Wl,-soname,liblockfile.so.1 \ -o liblockfile.so lockfile.o -lc nfslock.so.$(VER): nfslock.o $(CC) -fPIC -shared -Wl,-soname,nfslock.so.0 \ -o nfslock.so.$(NVER) nfslock.o dotlockfile: dotlockfile.o xlockfile.o $(CC) $(LDFLAGS) -o dotlockfile dotlockfile.o xlockfile.o lockfile.o: lockfile.c $(CC) $(CFLAGS) -DLIB -DLOCKPROG=\"$(bindir)/dotlockfile\" \ -c lockfile.c xlockfile.o: lockfile.c $(CC) $(CFLAGS) -c lockfile.c -o xlockfile.o install_static: static install_common install -m 644 liblockfile.a $(ROOT)$(libdir) install_shared: shared install_common install -m 755 liblockfile.so \ $(ROOT)$(libdir)/liblockfile.so.$(VER) ln -s liblockfile.so.$(VER) $(ROOT)$(libdir)/liblockfile.so if test "$(ROOT)" = ""; then @LDCONFIG@; fi install_common: install -m 644 lockfile.h maillock.h $(ROOT)$(includedir) if [ "$(MAILGROUP)" != "" ]; then\ install -g $(MAILGROUP) -m 2755 dotlockfile $(ROOT)$(bindir);\ else \ install -g root -m 755 dotlockfile $(ROOT)$(bindir); \ fi install -m 644 *.1 $(ROOT)$(mandir)/man1 install -m 644 *.3 $(ROOT)$(mandir)/man3 install_nfslib: nfslib install -m 755 nfslock.so.$(VER) $(ROOT)$(nfslockdir) if test "$(ROOT)" = ""; then @LDCONFIG@; fi clean: rm -f *.a *.o *.so *.so.* dotlockfile distclean: clean rm -f Makefile autoconf.h maillock.h \ config.cache config.log config.status liblockfile-1.09/configure0000755000175000017500000013430507254561501015222 0ustar mikevsmikevs#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-shared Build shared libraries" ac_help="$ac_help --with-libnfslock[=DIR] Build libnfslock (and install in DIR)" ac_help="$ac_help --with-mailgroup[=group] Run setgid (mail) to write to the mailspool" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=lockfile.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # From configure.in Revision: 1.0 # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:536: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:566: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:617: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:649: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 660 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:691: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:696: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:724: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi if test "$GCC" = "yes"; then CFLAGS="$CFLAGS -Wall -D_GNU_SOURCE" fi TARGETS="static" INSTALL_TARGETS="install_static" echo $ac_n "checking build shared libs""... $ac_c" 1>&6 echo "configure:764: checking build shared libs" >&5 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" case "$enableval" in no) SHARED=no ;; *) SHARED=yes CFLAGS="$CFLAGS -fPIC -D_REENTRANT" TARGETS="shared" INSTALL_TARGETS="install_shared" ;; esac else SHARED=no fi echo "$ac_t""$SHARED" 1>&6 nfslockdir="$libdir" echo $ac_n "checking build libnfslock""... $ac_c" 1>&6 echo "configure:789: checking build libnfslock" >&5 # Check whether --with-libnfslock or --without-libnfslock was given. if test "${with_libnfslock+set}" = set; then withval="$with_libnfslock" case "$withval" in no) LIBNFSLOCK=no ;; *) test "$withval" != "no" && nfslockdir="$withval" LIBNFSLOCK=yes TARGETS="$TARGETS nfslib" INSTALL_TARGETS="$INSTALL_TARGETS install_nfslib" ;; esac else LIBNFSLOCK=no fi echo "$ac_t""$LIBNFSLOCK" 1>&6 # Check whether --with-mailgroup or --without-mailgroup was given. if test "${with_mailgroup+set}" = set; then withval="$with_mailgroup" case "$withval" in yes) MAILGROUP="mail" ;; *) MAILGROUP="$withval" ;; esac fi if test "$MAILGROUP" != ""; then cat >> confdefs.h <&6 echo "configure:837: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_LDCONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$LDCONFIG" in /*) ac_cv_path_LDCONFIG="$LDCONFIG" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_LDCONFIG="$LDCONFIG" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH:/sbin:/usr/sbin" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_LDCONFIG="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi LDCONFIG="$ac_cv_path_LDCONFIG" if test -n "$LDCONFIG"; then echo "$ac_t""$LDCONFIG" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:871: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:892: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:909: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:926: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:951: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:964: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_hdr in \ getopt.h \ paths.h \ sys/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1063: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1073: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in \ utime \ utimes \ do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1106: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done if test "$ac_cv_header_paths_h" != "yes"; then echo $ac_n "checking location of your mail spool""... $ac_c" 1>&6 echo "configure:1162: checking location of your mail spool" >&5 MAILSPOOL=/var/spool/mail for dir in /var/mail /var/spool/mail /usr/mail /usr/spool/mail do if test -d $dir; then MAILSPOOL=$dir break fi done PATHMAILDIR="#define _PATH_MAILDIR \"$MAILSPOOL\"" echo "$ac_t""$MAILSPOOL" 1>&6 else PATHMAILDIR="#include " fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "\ ./Makefile \ ./maillock.h \ autoconf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@SHARED@%$SHARED%g s%@LIBNFSLOCK@%$LIBNFSLOCK%g s%@MAILGROUP@%$MAILGROUP%g s%@LDCONFIG@%$LDCONFIG%g s%@CPP@%$CPP%g s%@PATHMAILDIR@%$PATHMAILDIR%g s%@TARGETS@%$TARGETS%g s%@INSTALL_TARGETS@%$INSTALL_TARGETS%g s%@nfslockdir@%$nfslockdir%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 liblockfile-1.09/README0000644000175000017500000000252607260602010014156 0ustar mikevsmikevs README for liblockfile This library implements a number of functions found in -lmail on SysV systems. These functions are designed to lock the standard mailboxes in /var/mail (or wherever the system puts them). In additions, this library adds a number of functions to create, manage and remove generic lockfiles. The lockfiles are created by this library in an NFS-safe manner, that is by using a tempfile and using link(2) to create the lockfile. It works around several defects in NFS servers to make sure the lockfile is created atomically. The locking strategy is compatible with other well-written NFS-safe programs that create lockfiles - such as procmail, exim and mutt. If you are trying to lock a mailbox in a directory writable for group mail, the locking functions will call a helper application which runs setgid to do the actual locking. The helper application "dotlockfile" can also be used directly, for example for use in shellscripts. This means a program such as a MUA doesn't need to be setgid mail anymore to be able to lock the mailbox. See the included manualpages for more info: Function Manpage ======== ======= maillock, mailunlock, touchlock - maillock.3 lockfile_create, lockfile_remove, lockfile_touch, lockfile_check - lockfile_create.3 README 1.00 17-Apr-1999 Miquel van Smoorenburg liblockfile-1.09/Changelog0000644000175000017500000002164411611560462015123 0ustar mikevsmikevsliblockfile (1.09) * Update path to full license in the COPYRIGHT file (Anibal Monsalve Salazar) * Remove debug code from lockfile_create(): The lockfile_create-function still contains some debug code, which considers a lock stale after 10 seconds instead of 5 minutes. As the documentation suggests refreshing the lock every 60 seconds, programs might lose the lock unexpectedly. Found while researching debian bug #505278. (Wolfram Sang ) * Updated dotlockfile manpage and updated dotlockfile usage message. Fixes debian bug 493462 (Roland Eggner ) * Change 'ar' in Makefile.in to '$(AR)' (for cross builds). Fixes debian bug 562937 (Wolfram Sang ) * Clean up temporary lockfile if lockfile(1) was interrupted. * dotlockfile now also allows you to create a lockfile in a group-writable-by-one-of-your-auxilary-groups directory * dotlockfile: -r-1 now retries indefinitely (well, 4000 years) * remove ppsh macro in dotlockfile.1, replace with standard .SH (Iain Calder ) -- Miquel van Smoorenburg Wed, 20 Jul 2011 15:54:58 +0200 liblockfile (1.08) * When not writing a pid into the lockfile, write "0\n" as placeholder instead of "0\0" (bug reported by Rob Browning ) * lockfile_check() did the following: - open lockfile - read from it - stat file and get atime as 'now' this gets the 'now' time from the filesystem so comparisations to mtime work even if the clock of the remote file server is off. However this doesn't work with noatime / relatime, so now we stat the lockfile both before and after the read and use atime only if it differs before and after. * Copy Changelog from debian/changelog now that the package isn't native anymore since 1.07 -- Miquel van Smoorenburg Thu, 24 Jul 2008 22:40:34 +0200 liblockfile (1.07-1) unstable; urgency=low * Fixed "liblockfile1: option -u is duplicated". Closes: #416271 -- Anibal Monsalve Salazar Sat, 05 Apr 2008 12:14:10 +1000 liblockfile (1.06.2) unstable; urgency=low * Non-maintainer upload. * Rename eaccess() to eaccess_write() as eaccess is now a glibc function. Patch by Colin Watson. Closes: #392779. -- Aurelien Jarno Sun, 03 Jun 2007 19:28:33 +0200 liblockfile (1.06.1) unstable; urgency=low * Non-maintainer upload. * Remove postinst and prerm scripts, completing the /usr/doc tarnsition. Closes: #322790 -- Joey Hess Tue, 10 Jan 2006 01:21:31 -0500 liblockfile (1.06) unstable; urgency=low * Fix manpage - fd = open("/var/mail/USER.lock") should be fd = open("/var/mail/USER"); * Remove extraneous free() from lockfile.c (closes: #217740) * If the existing lockfile is not valid, the first try isn't really valid either - in that case, even if we want to try locking just once, try once more. (closes: #217741) -- Miquel van Smoorenburg Fri, 4 Jun 2004 17:16:04 +0200 liblockfile (1.05) unstable; urgency=low * Fix "does not give a valid preprocessing token" cpp problem (closes: #194823) -- Miquel van Smoorenburg Mon, 2 Jun 2003 14:27:58 +0200 liblockfile (1.04) unstable; urgency=low * Dynamically allocate filename memory, do not use MAXPATHLEN sized static buffers (closes: #144129, #105973) * Make the '-c' option of dotlockfile(1) actually work (closes: #103998) * Dotlockfile '-r' arg error checking * Note in manpages that unlocking a non-existant file is not an error. * Note in dotlockfile manpage that the lockfile_create manpage is in the liblockfile-dev package. * Update COPYRIGHT file (closes: #178200) * Don't sleep for 5 seconds when we removed an invalid lockfile (closes: #131316) * This upload will force a rebuild with current binutils (closes: #176340) * Add symlinks for manpages (closes: #99546) * Add static library liblockfile.a to liblockfile-dev (closes: #183817) * Actually handle 'retries' as number of *re*tries everywhere, not the number of tries. * Document that the default number of retries in dotlockfile is 5. * Add a '-t' (touchlock) option to dotlockfile (closes: #41791) -- Miquel van Smoorenburg Thu, 15 May 2003 16:29:32 +0200 liblockfile (1.03) unstable; urgency=low * Some more manpage updates * Set priority for liblockfile1 to "important" (closes: #92551) -- Miquel van Smoorenburg Fri, 6 Apr 2001 09:53:32 +0200 liblockfile (1.02) unstable; urgency=low * Maintainer upload (closes: #87488, #80753, #87670, #48886, #50564, #57890, #80601) * Added section to manpages that explains that you need to flush the actual file being locked after locking (closes: #43491) -- Miquel van Smoorenburg Thu, 29 Mar 2001 00:55:55 +0200 liblockfile (1.01.2) unstable; urgency=low * Non-Maintainer Upload for Bug Squashing Party. * Fix typo in postrm, closes: #87670. * Removed *~ from sources. -- Jordi Mallach Sat, 17 Mar 2001 05:09:54 +0100 liblockfile (1.01.1) unstable; urgency=low * NMU for bugsquashing day. * Updated man pages and usr/doc dir to FHS, Closes: #80753 (serious) * Only run ldconfig in postinst if the package is being configured. * Run ldconfig in the postrm on removal. * Fixed shlibs file perms, Closes: #50564, #57890 * Fixed descriptions, Closes: #80601 * Fixed man page typo, Closes: #48886 * Lintian clean except the warning about the setgid binary. -- Joey Hess Sat, 24 Feb 2001 13:55:27 -0800 liblockfile (1.01) unstable; urgency=low * Fix "clean" target in debian/rules * Fixes bugs: #39813: Liblockfile failes to build because of missing Makefile #39864: liblockfile_1.0(unstable): can't clean already empty tree -- Miquel van Smoorenburg Mon, 21 Jun 1999 19:47:17 +0200 liblockfile (1.0) unstable; urgency=low * Added autoconf to the distribution so that this package might be used outside Debian and even outside Linux. * New soname for liblockfile; API change. * Included command-line utility "dotlockfile" (setgid mail) and manpage * library can call "dotlockfile" to do the actual locking - mailprograms do not need to be setgid mail anymore! * Doesn't include libnfslock anymore * Fixes: #29572: liblockfile0 bad packaging -- Miquel van Smoorenburg Sat, 5 Jun 1999 17:19:30 +0200 liblockfile (0.1-6) frozen unstable; urgency=high * Fixed libnfslock to work together with mutt's mutt_dotlock. This has high urgency because otherwise mutt won't be able to lock your mailbox 95% of the time. -- Miquel van Smoorenburg Wed, 2 Dec 1998 17:39:54 +0100 liblockfile (0.1-5) unstable; urgency=low * Added L_MANLOCK define for compatibility , it's not actually used. * Fixes bugs: #21925 liblockfile man page is inaccurate #27275 liblockfile0: wishlist "user" argument for mailunlock and touchlock. -- Miquel van Smoorenburg Mon, 5 Oct 1998 12:35:42 +0200 liblockfile (0.1-4) unstable; urgency=low * Fixes: #13974: liblockfile-dev: maillock(3) mentions other manpages, that are not #18521: liblockfile-dev should not include /usr/lib/liblockfile.so #19042: liblockfile-dev: Overlap with liblockfile0 #18527: liblockfile0: liblockfile0 include .so link in liblockfile-dev #19041: liblockfile0: Overlap with liblockfle-dev and no conflict #19108: liblockfile0 has incorrect shlibs listed #18607: libnfslock: postinst and prerm scripts fail if ld.so.preload only #18913: libnfslock: package description -- Miquel van Smoorenburg Sun, 8 Mar 1998 22:41:49 +0100 liblockfile (0.1-3) unstable; urgency=low * Added version in name for nfslock.so (now nfslock.so.0.1) * Added shlibs file for nfslock * Add missing symlinks Fixes: #14413: /usr/doc/$(PACKAGE)/copyright should not be compressed #17693: liblockfile0 has executabnle changelog.gz #16489: liblockfile0 lacks dependency information #14155: lockfile_create could ignore some errors #14423: /usr/doc/$(PACKAGE)/copyright should not be compressed #15220: liblockfile-dev changelog is executable #14412: /usr/doc/$(PACKAGE)/copyright should not be compressed -- Miquel van Smoorenburg Thu, 19 Feb 1998 23:15:01 +0100 liblockfile (0.1-2) unstable; urgency=low * Compiled with libc6 and with -lc * Compile with -D_REENTRANT and -D_GNU_SOURCE * Apart from returning the L_XXX values, also set errno to something resonable. * Reckognize common NFS lockfiles from mailx -- Miquel van Smoorenburg Wed, 24 Sep 1997 12:52:44 +0200 liblockfile (0.1-1) unstable; urgency=low * First Debian release. -- Miquel van Smoorenburg Sun, 6 Jul 1997 16:04:55 +0200 liblockfile-1.09/nfslock.c0000644000175000017500000001070707254561501015115 0ustar mikevsmikevs/* * nfslock.c This file contains code to do a safe open(file, O_EXCL, ..) * over NFS. That's especially useful for mailspools shared over * NFS, until all MTAs and MUAs use code similar to that here. * * You just compile this file into a shared library and * put it in /lib as nfslock.so. Then add the line * "/lib/nfslock.so" to /etc/ld.so.preload. That's all. * * To compile: cc -fPIC -shared -o nfslock.so nfslock.c * * Version: @(#)nfslock.c 1.20 30-Nov-1998 miquels@cistron.nl * */ #include "autoconf.h" #include #include #include #include #include #include #include #include #ifndef __linux__ # error This is really only meant for Linux systems, sorry. #endif extern int __libc_open(const char *, int, ...); static struct utsname uts; /* * See if the directory where is certain file is in * is located on an NFS mounted volume. */ static int is_nfs(const char *file) { char dir[1024]; char *s; struct stat st; strncpy(dir, file, sizeof(dir)); if ((s = strrchr(dir, '/')) != NULL) *s = 0; else strcpy(dir, "."); if (stat(dir, &st) < 0) return 0; return ((st.st_dev & 0xFF00) == 0); } /* * See if this is a temporary file of Exim/procmail/qpopper. * In that case, we do not run the special algorithm. */ static int istmplock(const char *file) { char *p, *s; int len, i; if ((p = strrchr(file, '/')) != NULL) p++; else p = (char *)file; /* Our own temp files. */ if (strncmp(p, ".nfs", 4) == 0) return 1; /* Qpopper. */ if (strncmp(p, ".locktmp", 8) == 0) return 1; /* liblockfile. */ if (strncmp(p, ".lk", 3) == 0) return 1; #if 1 /* Procmail is hard to detect... */ if (strncmp(p, "_", 1) == 0) return 1; #endif /* I see this on our local mail spool often */ if (*(s = p) == '.') { s++; while(*s && *s != '.') s++; if (*s == '.') { s++; while(*s && ((*s >= '0' && *s <= '9') || (*s >= 'a' && *s <= 'f'))) s++; if (*s == 0) return 1; } } /* Exim. */ len = strlen(p); if (len > 18) { s = p - 18; if (s[0] == '.' && s[8] == '.') { for(i = 0; i < 18; i++) { if (i == 0 || i == 8) continue; if ((s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'f')) continue; i = -1; break; } if (i > 0) return 1; } } /* Mutt. */ if ((s = strrchr(p, '.')) != NULL && s[1] >= '0' && s[1] <= '9') if (atoi(s+1) == getpid()) return 1; /* Doesn't look like a temp lockfile */ return 0; } /* * Put our process ID into a string. */ static void putpid(char *s) { static char pidstr[6]; pid_t pid; int i; if (pidstr[0] == 0) { pid = getpid(); for(i = 0; i < 5; i++) { pidstr[4 - i] = (pid % 10) + '0'; pid /= 10; } pidstr[5] = 0; } strcpy(s, pidstr); } int open(const char *file, int flags, ...) { char tmp[1024]; char *s; int mode, i, e, error; va_list ap; struct stat st1, st2; if (!(flags & O_CREAT)) return __libc_open(file, flags); va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); /* * NFS has no atomic creat-if-not-exist (O_EXCL) but we * can emulate it by creating the file under a temporary * name and then renaming it to the final destination. */ if ((flags & O_EXCL) && !istmplock(file) && is_nfs(file)) { /* * Try to make a unique temp name, network-wide. */ if (strlen(file) > sizeof(tmp) - 16) { errno = ENAMETOOLONG; return -1; } strcpy(tmp, file); if ((s = strrchr(tmp, '/')) != NULL) s++; else s = tmp; *s = 0; strcpy(s, ".nfs"); if (uts.nodename[0] == 0) uname(&uts); for(i = 0; i < 5 && uts.nodename[i] && uts.nodename[i] != '.'; i++) s[4 + i] = uts.nodename[i]; putpid(s + 4 + i); if ((i = __libc_open(tmp, flags, mode)) < 0) return i; /* * We don't just check the result code from link() * but we stat() both files as well to see if they're * the same just to be sure. */ error = link(tmp, file); e = errno; if (error < 0) { (void)unlink(tmp); close(i); errno = e; return error; } error = stat(tmp, &st1); e = errno; (void)unlink(tmp); if (error < 0) { close(i); errno = e; return -1; } if (stat(file, &st2) < 0) { close(i); errno = e; return -1; } if (st1.st_ino != st2.st_ino) { close(i); errno = EEXIST; return -1; } return i; } return __libc_open(file, flags, mode); } int creat(const char *file, mode_t mode) { return open(file, O_CREAT|O_WRONLY|O_TRUNC, mode); } liblockfile-1.09/lockfile_create.30000644000175000017500000001537310060106567016511 0ustar mikevsmikevs.TH LOCKFILE_CREATE 3 "04 June 2004" "Linux Manpage" "Linux Programmer's Manual" .SH NAME lockfile_create, lockfile_remove, lockfile_touch, lockfile_check \- manage lockfiles .SH SYNOPSIS .B #include .sp .BI "cc [ "flag " ... ] "file " ... -llockfile [ "library " ] " .sp .BI "int lockfile_create( const char *" lockfile ", int " retrycnt ", int " flags " );" .br .BI "int lockfile_remove( const char *" lockfile " );" .br .BI "int lockfile_touch( const char *" lockfile " );" .br .BI "int lockfile_check( const char *" lockfile ", int " flags " );" .SH DESCRIPTION The .B lockfile_create function creates a lockfile in an NFS safe way. .PP If flags is set to .B L_PID then lockfile_create will not only check for an existing lockfile, but it will read the contents as well to see if it contains a process id in ASCII. If so, the lockfile is only valid if that process still exists. .PP If the lockfile is on a shared filesystem, it might have been created by a process on a remote host. Thus the process-id checking is useless and the L_PID flag should not be set. In this case, there is no good way to see if a lockfile is stale. Therefore if the lockfile is older then 5 minutes, it will be removed. That is why the .B lockfile_touch function is provided: while holding the lock, it needs to be refreshed regulary (every minute or so) by calling .B lockfile_touch "() ". .PP The .B lockfile_check function checks if a valid lockfile is already present without trying to create a new lockfile. .PP Finally the .B lockfile_remove function removes the lockfile. .SH RETURN VALUES .B lockfile_create returns one of the following status codes: .nf #define L_SUCCESS 0 /* Lockfile created */ #define L_NAMELEN 1 /* Recipient name too long (> 13 chars) */ #define L_TMPLOCK 2 /* Error creating tmp lockfile */ #define L_TMPWRITE 3 /* Can't write pid int tmp lockfile */ #define L_MAXTRYS 4 /* Failed after max. number of attempts */ #define L_ERROR 5 /* Unknown error; check errno */ .fi .PP .B lockfile_check returns 0 if a valid lockfile is present. If no lockfile or no valid lockfile is present, -1 is returned. .PP .B lockfile_touch and .B lockfile_remove return 0 on success. On failure -1 is returned and .I errno is set appropriately. It is not an error to lockfile_remove() a non-existing lockfile. .SH ALGORITHM The algorithm that is used to create a lockfile in an atomic way, even over NFS, is as follows: .IP 1 A unique file is created. In printf format, the name of the file is .lk%05d%x%s. The first argument (%05d) is the current process id. The second argument (%x) consists of the 4 minor bits of the value returned by \fItime\fP(2). The last argument is the system hostname. .IP 2 Then the lockfile is created using \fIlink\fP(2). The return value of \fIlink\fP is ignored. .IP 3 Now the lockfile is \fIstat\fP()ed. If the stat fails, we go to step \fI6\fP. .IP 4 The \fIstat\fP value of the lockfile is compared with that of the temporary file. If they are the same, we have the lock. The temporary file is deleted and a value of 0 (success) is returned to the caller. .IP 5 A check is made to see if the existing lockfile is a valid one. If it isn't valid, the stale lockfile is deleted. .IP 6 Before retrying, we sleep for \fIn\fP seconds. \fIn\fP is initially 5 seconds, but after every retry 5 extra seconds is added up to a maximum of 60 seconds (an incremental backoff). Then we go to step \fI2\fP up to \fIretries\fP times. .PP .SH REMOTE FILE SYSTEMS AND THE KERNEL ATTRIBUTE CACHE .PP These functions do not lock a file - they \fIgenerate\fP a \fIlockfile\fP. However in a lot of cases, such as Unix mailboxes, all concerned programs accessing the mailboxes agree on the fact that the presence of .lock means that is locked. .PP If you are using .B lockfile_create to create a lock on a file that resides on a remote server, and you already have that file open, you need to flush the NFS attribute cache after locking. This is needed to prevent the following scenario: .PP .PD 0 .TP 3 o open /var/mail/USERNAME .TP 3 o attributes, such as size, inode, etc are now cached in the kernel! .TP 3 o meanwhile, another remote system appends data to /var/mail/USERNAME .TP 3 o grab lock using lockfile_create() .TP 3 o seek to end of file .TP 3 o write data .PD 1 .PP Now the end of the file really isn't the end of the file - the kernel cached the attributes on open, and st_size is not the end of the file anymore. So after locking the file, you need to tell the kernel to flush the NFS file attribute cache. .PP The only .I portable way to do this is the POSIX .I fcntl() file locking primitives - locking a file using .I fcntl() has the fortunate side-effect of invalidating the NFS file attribute cache of the kernel. .PP .B lockfile_create() cannot do this for you for two reasons. One, it just creates a lockfile- it doesn't know which file you are actually trying to lock! Two, even if it could deduce the file you're locking from the filename, by just opening and closing it, it would invalidate any existing POSIX locks the program might already have on that file (yes, POSIX locking semantics are insane!). .PP So basically what you need to do is something like this: .nf fd = open("/var/mail/USER"); .. program code .. lockfile_create("/var/mail/USER.lock", x, y); /* Invalidate NFS attribute cache using POSIX locks */ if (lockf(fd, F_TLOCK, 0) == 0) lockf(fd, F_ULOCK, 0); .fi You have to be careful with this if you're putting this in an existing program that might already be using fcntl(), flock() or lockf() locking- you might invalidate existing locks. .PP There is also a non-portable way. A lot of NFS operations return the updated attributes - and the Linux kernel actually uses these to update the attribute cache. One of these operations is .B chmod(2). .PP So stat()ing a file and then chmod()ing it to st.st_mode will not actually change the file, nor will it interfere with any locks on the file, but it will invalidate the attribute cache. The equivalent to use from a shell script would be .nf chmod u=u /var/mail/USER .fi .SH PERMISSIONS If you are on a system that has a mail spool directory that is only writable by a special group (usually "mail") you cannot create a lockfile directly in the mailspool directory without special permissions. .PP Lockfile_create and lockfile_remove check if the lockfile ends in $USERNAME.lock, and if the directory the lockfile is writable by group "mail". If so, an external set group-id mail executable (\fIdotlockfile\fP(1) ) is spawned to do the actual locking / unlocking. .SH FILES /usr/lib/liblockfile.so.1 .SH AUTHOR Miquel van Smoorenburg .SH "SEE ALSO" .BR dotlockfile "(1), " maillock "(3), " touchlock " (3), " mailunlock (3) liblockfile-1.09/liblockfile.lsm0000644000175000017500000000140411604365323016276 0ustar mikevsmikevsBegin3 Title: liblockfile - a lockfile library Version: 1.09 Entered-Date: 04JUL2011 Description: liblockfile is a library that contains NFS-safe locking functions. It also contains an implementation of the SVR4 maillock() functions. The functions in liblockfile can lock and unlock mailboxes even if special priviliges are needed by calling an external setgid-mail utility called `dotlockfile'. That utility can also be used stand-alone. Author: miquels@cistron.nl (Miquel van Smoorenburg) Primary-Site: ftp.cistron.nl /pub/people/miquels/software 32K liblockfile-1.09.tar.gz Alternate-Site: ftp.debian.org /debian/pool/main/libl/liblockfile 32K liblockfile_1.09.orig.tar.gz Copying-Policy: LGPL,GPL Keywords: locking mail dotlock dotlockfile library End liblockfile-1.09/maillock.30000644000175000017500000000465607260602121015166 0ustar mikevsmikevs.TH MAILOCK 3 "28 March 2001" "Linux Manpage" "Linux Programmer's Manual" .SH NAME maillock, mailunlock, touchlock \- manage mailbox lockfiles .SH SYNOPSIS .B #include .sp .BI "cc [ "flag " ... ] "file " ... -llockfile [ "library " ] " .sp .BI "int maillock( const char *" user ", int " retrycnt " );" .br .BI "void mailunlock( "void " );" .br .BI "void touchlock( "void " );" .SH DESCRIPTION The .B maillock function tries to create a lockfile for the users mailbox in an NFS-safe (or resistant) way. The algorithm is documented in .BR lockfile_create "(3)". .PP The mailbox is typically located in .B /var/mail. The name of the lockfile then becomes .B /var/mail/USERNAME.lock. If the environment variable \fI$MAIL\fP is set, and it ends with the same username as the username passed to \fBmaillock\fP(), then that file is taken as the mailbox to lock instead. .PP There is no good way to see if a lockfile is stale. Therefore if the lockfile is older then 5 minutes, it will be removed. That is why the .B touchlock function is provided: while holding the lock, it needs to be refreshed regulary (every minute or so) by calling .B touchlock "() ". .PP Finally the .B mailunlock function removes the lockfile. .SH RETURN VALUES .B maillock returns one of the following status codes: .nf #define L_SUCCESS 0 /* Lockfile created */ #define L_NAMELEN 1 /* Recipient name too long (> 13 chars) */ #define L_TMPLOCK 2 /* Error creating tmp lockfile */ #define L_TMPWRITE 3 /* Can't write pid int tmp lockfile */ #define L_MAXTRYS 4 /* Failed after max. number of attempts */ #define L_ERROR 5 /* Unknown error; check errno */ .fi .SH NOTES These functions are not thread safe. If you need thread safe functions, or you need to lock other mailbox (like) files that are not in the standard location, use .BR lockfile_create "(3)" instead. .PP These functions call .BR lockfile_create "(3)" to do the work. That function might spawn a set group-id executable to do the actual locking if the current process doesn't have enough priviliges. .PP There are some issues with flushing the kernels attribute cache if you are using NFS - see the .I lockfile_create(3) manpage. .SH FILES /var/mail/user.lock, .br /usr/lib/liblockfile.so.1 .SH AUTHOR Miquel van Smoorenburg .SH "SEE ALSO" .BR lockfile_create "(3), " lockfile_touch " (3), " lockfile_remove (3) liblockfile-1.09/acconfig.h0000644000175000017500000000040007254561501015221 0ustar mikevsmikevs/* acconfig.h - template used by autoheader to create config.h.in config.h.in - used by autoconf to create config.h config.h - created by autoconf; contains defines generated by autoconf */ @TOP@ /* Is the mailspool group writable */ #undef MAILGROUP