/* lockname.c: -*- C -*-  Functions for file locking. */

/* Copyright (c) 1996 Brian J. Fox
   Author: Brian J. Fox (bfox@ai.mit.edu) Thu Jan 16 08:41:39 1997. 

   This file is part of <Meta-HTML>(tm), a system for the rapid deployment
   of Internet and Intranet applications via the use of the Meta-HTML
   language.

   Copyright (c) 1995, 1996, Brian J. Fox (bfox@ai.mit.edu).
   Copyright (c) 1996, Universal Access Inc. (http://www.ua.com).

   Meta-HTML is free software; you can redistribute it and/or modify
   it under the terms of the UAI Free Software License as published
   by Universal Access Inc.; either version 1, 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
   UAI Free Software License for more details.

   You should have received a copy of the UAI Free Software License
   along with this program; if you have not, you may obtain one by
   writing to:

   Universal Access Inc.
   129 El Paseo Court
   Santa Barbara, CA
   93101  */

#include "mhtmlstd.h"

/* Return a hash code for NAME. */
static int
hashname (char *name)
{
  register unsigned int i, j;

  for (i = 0, j = 0; name[i] != '\0'; i++)
    j = (j << 2) +  name[i];

  return ((j & ~(0xffffffff << 31)) % 107);
}

char *
db_lockname (char *name)
{
  static char lockname[1024];

  if (name == (char *)NULL)
    return ((char *)NULL);
  else
    {
      int hashcode = hashname (name);
      char *tail = strrchr (name, '/');

      if (tail == (char *)NULL)
	tail = name;
      else
	tail++;

      sprintf (lockname, "/tmp/%08X-%s.LOCK", hashcode, tail);
      return (lockname);
    }
}

#if !defined (HAVE_FLOCK)
int
LOCKFILE (int fd)
{
  struct flock f;
  f.l_type = F_WRLCK;
  f.l_whence = SEEK_SET;
  f.l_start = (long) 0;
  f.l_len = (long) 0;
  return (fcntl (fd, F_SETLKW, &f));
}

#if defined (Solaris) || defined (hpux)
int
READLOCKFILE (int fd)
{
  struct flock f;
  f.l_type = F_WRLCK;
  f.l_whence = SEEK_SET;
  f.l_start = (long) 0;
  f.l_len = (long) 0;
  return (fcntl (fd, F_SETLKW, &f));
}
#else
int
READLOCKFILE (int fd)
{
  struct flock f;
  f.l_type = F_RDLCK;
  f.l_whence = SEEK_SET;
  f.l_start = (long) 0;
  f.l_len = (long) 0;
  return (fcntl (fd, F_SETLKW, &f));
}
#endif /* !Solaris */

int
UNLOCKFILE (int fd)
{
  struct flock f;
  f.l_type = F_UNLCK;
  f.l_whence = SEEK_SET;
  f.l_start = (long) 0;
  f.l_len = (long) 0;
  return (fcntl (fd, F_SETLK, &f));
}
#endif /* !HAVE_FLOCK */
