/*
 * dumpacct.c 
 *
 * A small program to print out what is stored in /var/adm/acct file
 *
 * This is released under GPL.
 *
 * 
 * Usage: dumpacct [acct_file]
 * If no file is given, dumpacct reads from stdin.
 *
 * Output format:
 *
 *  ac->ac_comm     tty   uid   gid  flag  exit utime stime ctime
 *  accton        65535     0     0     2     0 0.00 0.00 Sun Jul  9 05:18:39
 *
 * Fields are:
 * ac->ac_comm   name of executed command
 * tty           tty in number format; 8 most significant bits
 *               represent major number and 8 least significant bits
 *               represent minor number. 65535 as tty means that
 *               command didn't have a controlling tty
 * uid           user's effective user id
 * gid           user's effective group id
 * flag          flag bits. 1: process forked child(s), 2: process
 *               used superuser privileges, 4 process dumped core,
 *               8 process were killed by a signal.
 * exit          process' exit status
 * utime         process' execution time in user space in seconds
 * stime         process' execution time in kernel space in seconds
 * ctime         process' startup time (wall clock time)
 *
 *
 * Author: Juha Virtanen, <juha.virtanen@hut.fi>
 * Last time modified on 9th July 1995
 */

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <linux/acct.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
  struct acct ac[sizeof (struct acct)];
  FILE *fp;
  int fd;
  char filename[FILENAME_MAX+1];

  if (argc == 1)
   {
     if ((fd = dup (0)) < 0)
      {
	fprintf (stderr, "dup error");
	exit (1);
      }
     if ((fp = fdopen (fd, "rb")) == NULL)
      {
	if (ferror (fp))
	 {
	   fprintf (stderr, "could not reopen stdin");
	   exit (1);
	 }
      }
   }
  else
   {
     strcpy (filename, argv[1]);
     if ((fp = fopen (filename, "rb")) == NULL)
      {
	if (ferror (fp))
	 {
	   fprintf (stderr, "could not open %s", filename);
	   exit (1);
	 }
      }
/*     fprintf (stderr, "opened %s\n", filename); */
   }

  fprintf (stdout, "%-*.*s %5s %5s %5s %5s %5s %5s %5s %.19s\n", 
	   ((int) sizeof (ac->ac_comm)),
	   ((int) sizeof (ac->ac_comm)), "ac->ac_comm",
	   "tty", "uid", "gid",
	   "flag", "exit",
	   "utime", "stime",
	   "ctime");

  while (fread ((void *) ac, sizeof (struct acct), 1, fp))
   {
     fprintf (stdout, "%-*.*s %5d %5hd %5hd %5d %5ld %5.2f %5.2f %.19s\n", 
	      ((int) sizeof (ac->ac_comm)), 
	      ((int) sizeof (ac->ac_comm)), ac->ac_comm,
	      ac->ac_tty, ac->ac_uid, ac-> ac_gid,
	      (int) ac->ac_flag, ac->ac_exitcode,
	      (double) ac->ac_utime / (double) AHZ,
	      (double) ac->ac_stime / (double) AHZ,
	      ctime(&ac->ac_btime)); 
   }

  return 0;
}
