#include "lock_maildrop.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>

int lock_maildrop(char * maildrop, uid_t uid, gid_t gid) {
  char * lf;
  int lf_len, i, fd = -1;
  struct stat s_lf;
  char pid_text[30];

  lf_len = strlen(maildrop)+strlen(".lock")+1;
  lf = alloca(lf_len);

  snprintf(pid_text,sizeof(pid_text),"%u",getpid());

  if (lf==NULL) {
    return 0;
  }
  snprintf(lf,lf_len,"%s.lock",maildrop);
  fd = stat(lf,&s_lf);
  if (fd==0) {
    if (time(NULL)-s_lf.st_ctime>10*60) {
      /* stale lockfile */
      unlink(lf);
    }
  }
  for (i=0;i<5;i++) { 
    /* only create file when it doesn't exist */
    fd = open(lf,O_WRONLY|O_EXCL|O_CREAT,0600);
    if (fd < 0)
      sleep(1);
    else
      break;
  }
  if (i==5)
    return 0;
  write(fd,pid_text,strlen(pid_text));
  fchown(fd,uid,gid);
  close(fd);
  return 1;
}

void remove_lock(char * maildrop) {
  int lf_len = strlen(maildrop)+strlen(".lock")+1;
  char * lf = alloca(lf_len);
  if (lf!=NULL) {
    snprintf(lf,lf_len,"%s.lock",maildrop);
    unlink(lf);
  }
}

int lock_fd(int fd) {
  if (lockf(fd,F_LOCK,0)==0)
    return 1;
  return 0;
}

int unlock_fd(int fd) {
  if (lockf(fd,F_ULOCK,0)==0)
    return 1;
  return 0;
}
