/* cleanutmp.c
   chown root.utmp cleanutmp
   chmod 2711 cleanutmp
 */

#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "lib.h"

void ops(int n, const char *s0, const char *s1) {
  write(2,s0,str_len(s0));
  write(2,s1,str_len(s1));
  write(2,"\n",1);
  _exit(n);
}

#ifdef USE_LIBC_UTMP
int main () {
  struct utmp_type *ut, u;
  setutent();

  while (f_getutent()) {
    if (ut->ut_type != USER_PROCESS) continue;
    if (kill(ut->ut_pid, 0) && errno == ESRCH) {
      u = *ut;
      u.ut_type = DEAD_PROCESS;
      u.ut_tv.tv_sec = time(0);

      f_setutent();
      if (0==f_pututline(&u))
	ops(2,"error writing to: ", Utmp_File);
      f_updwtmp(Wtmp_File, &u);
    }
  }
  f_endutent();
  return 0;
}

#else
int main() {
  int fd,wfd;
  struct utmp_type ut[1];
  off_t pos=0;

  if ((fd = open(Utmp_File,O_RDWR)) <0 &&
      (fd = open(Utmp_File,O_RDONLY)) <0)
    ops(1,"error opening: ", Utmp_File);

  while (utmp_io(fd,ut,F_RDLCK)) {
    pos += UTMP_SIZE;
    if (ut->ut_type != USER_PROCESS) continue;
    if (kill(ut->ut_pid, 0) && errno == ESRCH) {
      ut->ut_type = DEAD_PROCESS;
      ut->ut_tv.tv_sec = time(0);

      pos -= UTMP_SIZE;
      if (lseek(fd, pos, SEEK_SET) != pos || 
	  !utmp_io(fd,ut,F_WRLCK))
	ops(2,"error writing to: ", Utmp_File);
      pos += UTMP_SIZE;
      
      wfd=open(Wtmp_File, O_WRONLY|O_APPEND);
      write(wfd, ut, UTMP_SIZE);
      close(wfd);
    }
  }
  close(fd);
  return 0;
}
#endif
