/*
 *	Copyright 1988 by Rayan S. Zachariassen, all rights reserved.
 *	This will be free software, but only when it is finished.
 */

/*
 * Common routine to fiddle control file tag characters.
 */

#include <stdio.h>
#include "hostenv.h"
#include <sys/file.h>
#include "mail.h"
#include "ta.h"

#ifndef	L_SET
#define	L_SET	0
#endif	/* L_SET */

int
lockaddr(fd, map, offset, was, new)
	int	fd;
	char	*map;
	long	offset;
	char	was;
	char	new;
{
	char	lockbuf[1+_CFTAG_RCPTPIDSIZE+1];
	int	newlock = 0;

	if (map) {
	  /* MMAP()ed block helps.. */
	  memcpy(lockbuf,map+offset,sizeof(lockbuf));
	} else {
	  if (lseek(fd, offset, L_SET) < 0L) {
	    warning("lockaddr: lseek() failure");
	    return 0;
	  }
	  if (read(fd, lockbuf, sizeof(lockbuf)) != sizeof(lockbuf)) {
	    warning("lockaddr: read() failure");
	    return 0;
	  }
	}
	newlock = ((lockbuf[1] == ' ') ||
		   (lockbuf[1] >= '0' && lockbuf[1] <= '9'));
	if (lockbuf[0] == was) {
	  if (!map && lseek(fd, offset, L_SET) < 0L) {
	    warning("lockaddr: lseek() failure 2");
	    return 0;
	  }
	  lockbuf[0] = new;
	  if (newlock) {
	    if (new == _CFTAG_LOCK) {
	      /* Mark the lock with client process-id */
	      sprintf(lockbuf+1,"%*d",_CFTAG_RCPTPIDSIZE,getpid());
	      if (map)
		memcpy(map+offset, lockbuf, _CFTAG_RCPTPIDSIZE+1);
	      else if (write(fd,lockbuf,
			     _CFTAG_RCPTPIDSIZE+1) != _CFTAG_RCPTPIDSIZE+1)
		return 0;
	    } else {
	      /* Clear the lock location */
	      sprintf(lockbuf+1,"%*s",_CFTAG_RCPTPIDSIZE,"");
	      if (map)
		memcpy(map+offset, lockbuf, _CFTAG_RCPTPIDSIZE+1);
	      else if (write(fd,lockbuf,
			     _CFTAG_RCPTPIDSIZE+1) != _CFTAG_RCPTPIDSIZE+1)
		return 0;
	    }
	  }
	  return 1;
	}
	warning("lockaddr: expected '%c' found '%c'\n", was, new);
	return 0;
}

