diff options
author | Sam Roberts <sroberts@uniserve.com> | 2002-03-02 02:05:39 +0000 |
---|---|---|
committer | Sam Roberts <sroberts@uniserve.com> | 2002-03-02 02:05:39 +0000 |
commit | e5248b7951ced462159a14e5852884f9b21b1a91 (patch) | |
tree | 5ca35adfc640e0f9fb83d4481b5340faf7686cbe /dotlock | |
parent | 86b9cd5d3455bd36e9ba4b8fa3c99c9a5ccafc3c (diff) | |
download | mailutils-e5248b7951ced462159a14e5852884f9b21b1a91.tar.gz mailutils-e5248b7951ced462159a14e5852884f9b21b1a91.tar.bz2 |
dotlock - setgid program to dot lock a file, modelled on mutt_dotlock.
Diffstat (limited to 'dotlock')
-rw-r--r-- | dotlock/.cvsignore | 7 | ||||
-rw-r--r-- | dotlock/Makefile.am | 13 | ||||
-rw-r--r-- | dotlock/dotlock.c | 173 |
3 files changed, 193 insertions, 0 deletions
diff --git a/dotlock/.cvsignore b/dotlock/.cvsignore new file mode 100644 index 000000000..9f1380769 --- /dev/null +++ b/dotlock/.cvsignore @@ -0,0 +1,7 @@ +dotlock +Makefile +Makefile.in +.gdbinit +.deps +.libs +_* diff --git a/dotlock/Makefile.am b/dotlock/Makefile.am new file mode 100644 index 000000000..b904cdeea --- /dev/null +++ b/dotlock/Makefile.am @@ -0,0 +1,13 @@ +AUTOMAKE_OPTIONS = ../lib/ansi2knr +INCLUDES =-I$(srcdir) -I$(top_srcdir)/lib -I$(top_srcdir)/include -I$(top_srcdir)/libmu_scm @ARGPINCS@ + +bin_PROGRAMS = dotlock +#dotlock_SOURCES = dotlock.c + +dotlock_LDADD = ../mailbox/libmailbox.la @ARGPLIBS@ ../lib/libmailutils.la + +install-exec-hook: + for i in $(bin_PROGRAMS); do\ + chown root:mail $(DESTDIR)$(bindir)/$$i;\ + chmod 2755 $(DESTDIR)$(bindir)/$$i;\ + done diff --git a/dotlock/dotlock.c b/dotlock/dotlock.c new file mode 100644 index 000000000..7a17cc456 --- /dev/null +++ b/dotlock/dotlock.c @@ -0,0 +1,173 @@ +/* GNU mailutils - a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> + +#include <argp.h> + +#include <mailutils/errno.h> +#include <mailutils/locker.h> + +#define MU_DL_EX_OK 0 +#define MU_DL_EX_ERROR 1 +#define MU_DL_EX_EXIST 3 + +const char *argp_program_version = "GNU dotlock (" PACKAGE ") " VERSION; +const char *argp_program_bug_address = "<bug-mailutils@gnu.org>"; +static char doc[] = + "GNU dotlock -- lock mail spool files" + "\v" + "Returns 0 on success, 3 if the locking the file fails because" + " it's already locked, and 1 if some other kind of error occurred." + ; +static char args_doc[] = "FILE"; +error_t argp_err_exit_status = MU_DL_EX_ERROR; + +static struct argp_option options[] = { + {"unlock", 'u', NULL, 0, + "Unlock", 0}, + + {"force", 'f', "MINUTES", OPTION_ARG_OPTIONAL, + "Forcibly break an existing lock older than a certain time", 0}, + + {"retry", 'r', "RETRIES", OPTION_ARG_OPTIONAL, + "Retry the lock a few times", 0}, + + {"debug", 'd', NULL, 0, + "Print details of failure reasons to stderr", 0}, + + {NULL, 0, NULL, 0, NULL, 0} +}; + +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +static struct argp argp = { + options, + parse_opt, + args_doc, + doc, +}; + +static const char *file; +static int unlock; +static int flags; +static int retries; +static int force; +static int debug; + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'd': + debug = 1; + break; + + case 'u': + unlock = 1; + break; + + case 'r': + if (arg) + { + retries = atoi (arg); + if (retries == 0) + argp_error (state, "RETRIES must be greater than 0"); + } + flags |= MU_LOCKER_RETRY; + break; + + case 'f': + if (arg) + { + force = atoi (arg); + if (force == 0) + argp_error (state, "MINUTES must be greater than 0"); + force *= 60; + } + flags |= MU_LOCKER_TIME; + break; + + case ARGP_KEY_ARG: + if (file) + argp_error (state, "only one FILE can be specified"); + file = arg; + break; + + case ARGP_KEY_NO_ARGS: + argp_error (state, "FILE must be specified"); + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + locker_t locker = 0; + int err = 0; + + argp_parse (&argp, argc, argv, 0, NULL, NULL); + + if ((err = locker_create (&locker, file, flags))) + { + if (debug) + fprintf (stderr, "locker create failed: %s\n", mu_errstring (err)); + return MU_DL_EX_ERROR; + } + + locker_set_flags (locker, flags); + + if (force != 0) + locker_set_expire_time (locker, force); + + if (retries != 0) + locker_set_retries (locker, retries); + + if (unlock) + err = locker_remove_lock (locker); + else + err = locker_lock (locker); + + locker_destroy (&locker); + + if (debug && err) + fprintf (stderr, "%slocking %s failed: %s\n", + unlock ? "un" : "", file, mu_errstring (err)); + + switch (err) + { + case 0: + err = MU_DL_EX_OK; + break; + case MU_ERR_LOCK_CONFLICT: + err = MU_DL_EX_EXIST; + break; + default: + err = MU_DL_EX_ERROR; + break; + } + + return err; +} |