122347Spst/* unlock.c: The opieunlock() library function.
222347Spst
329964Sache%%% portions-copyright-cmetz-96
492906SmarkmPortions of this software are Copyright 1996-1999 by Craig Metz, All Rights
522347SpstReserved. The Inner Net License Version 2 applies to these portions of
622347Spstthe software.
722347SpstYou should have received a copy of the license with this software. If
822347Spstyou didn't get a copy, you may request one from <license@inner.net>.
922347Spst
1022347SpstPortions of this software are Copyright 1995 by Randall Atkinson and Dan
1122347SpstMcDonald, All Rights Reserved. All Rights under this copyright are assigned
1222347Spstto the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
1322347SpstLicense Agreement applies to this software.
1422347Spst
1522347Spst        History:
1622347Spst
1729964Sache	Modified by cmetz for OPIE 2.31. Bug fix.
1822347Spst	Modified by cmetz for OPIE 2.3. Do refcounts whether or not
1922347Spst            we actually lock. Fixed USER_LOCKING=0 case.
2022347Spst	Modified by cmetz for OPIE 2.22. Added reference count support.
2122347Spst	    Changed lock filename/refcount symbol names to better indicate
2222347Spst	    that they're not user serviceable.
2322347Spst	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration.
2422347Spst            Check for read() == -1. ifdef around unistd.h.
2522347Spst        Created at NRL for OPIE 2.2 from opiesubr2.c
2622347Spst*/
2722347Spst#include "opie_cfg.h"
2822347Spst#include <string.h>
2922347Spst#if HAVE_UNISTD_H
3022347Spst#include <unistd.h>
3122347Spst#endif /* HAVE_UNISTD_H */
3222347Spst#include <fcntl.h>
3322347Spst#include "opie.h"
3422347Spst
3522347Spstextern int __opie_lockrefcount;
3622347Spst#if USER_LOCKING
3722347Spstextern char *__opie_lockfilename;
3822347Spst#endif /* USER_LOCKING */
3922347Spst
4022347Spst/*
4122347Spst  Just remove the lock, right?
4222347Spst  Well, not exactly -- we need to make sure it's ours.
4322347Spst*/
4422347Spstint opieunlock FUNCTION_NOARGS
4522347Spst{
4622347Spst#if USER_LOCKING
4722347Spst  int fh, rval = -1, pid, t, i;
4822347Spst  char buffer[128], *c, *c2;
4922347Spst
5022347Spst  if (--__opie_lockrefcount > 0)
5122347Spst    return 0;
5222347Spst
5322347Spst  if (!__opie_lockfilename)
5422347Spst    return -1;
5522347Spst
5622347Spst  if (!(fh = open(__opie_lockfilename, O_RDWR, 0600)))
5722347Spst    goto unlockret;
5822347Spst
5922347Spst  if ((i = read(fh, buffer, sizeof(buffer))) < 0)
6022347Spst    goto unlockret;
6122347Spst
6222347Spst  buffer[sizeof(buffer) - 1] = 0;
6322347Spst  buffer[i - 1] = 0;
6422347Spst
6522347Spst  if (!(c = strchr(buffer, '\n')))
6622347Spst    goto unlockret;
6722347Spst
6822347Spst  *(c++) = 0;
6922347Spst
7022347Spst  if (!(c2 = strchr(c, '\n')))
7122347Spst    goto unlockret;
7222347Spst
7322347Spst  *(c2++) = 0;
7422347Spst
7522347Spst  if (!(pid = atoi(buffer)))
7622347Spst    goto unlockret;
7722347Spst
7822347Spst  if (!(t = atoi(c)))
7922347Spst    goto unlockret;
8022347Spst
8129964Sache  if ((pid != getpid()) && (time(0) <= OPIE_LOCK_TIMEOUT + t) && (!kill(pid, 0))) {
8222347Spst    rval = 1;
8322347Spst    goto unlockret1;
8422347Spst  }
8522347Spst
8622347Spst  rval = 0;
8722347Spst
8822347Spstunlockret:
8922347Spst  unlink(__opie_lockfilename);
9022347Spst
9122347Spstunlockret1:
9222347Spst  if (fh)
9322347Spst    close(fh);
9422347Spst  free(__opie_lockfilename);
9522347Spst  __opie_lockfilename = NULL;
9622347Spst  return rval;
9722347Spst#else /* USER_LOCKING */
9822347Spst  if (__opie_lockrefcount-- > 0)
9922347Spst    return 0;
10022347Spst
10122347Spst  return -1;
10222347Spst#endif /* USER_LOCKING */
10322347Spst}
104