/*
 * Halt		Stop the system running.
 *		It re-enables CTRL-ALT-DEL, so that a hard reboot can
 *		be done. If called as reboot, it will reboot the system.
 *
 * Usage:	halt [-n] [-w] [-d]
 *		-n: don't sync before halting the system
 *		-w: only write a wtmp reboot record and exit.
 *		-d: don't write a wtmp record.
 *
 *		Reboot and halt are both this program. Reboot
 *		is just a link to halt.
 *
 * Author:	Miquel van Smoorenburg, miquels@drinkel.nl.mugnet.org
 *
 * Version:	1.5,  31-Jan-1994
 *
 */

#include <sys/types.h>
#include <stdlib.h>
#include <utmp.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#include <getopt.h>

char *Version = "@(#) halt 1.4 30-Dec-1993 MvS";
char *progname;

/*
 * Send usage message.
 */
void usage()
{
  fprintf(stderr, "usage: %s [-n] [-w] [-d]\n", progname);
  exit(1);
}

/*
 * Main program.
 * Write a wtmp entry and reboot cq. halt.
 */
int main(argc, argv)
int argc;
char **argv;
{
  struct utmp wtmp;
  int fd;
  time_t t;
  int do_reboot = 0;
  int do_sync = 1;
  int do_wtmp = 1;
  int do_nothing = 0;
  int c;

  /* Find out who we are */
  if ((progname = strrchr(argv[0], '/')) != NULL)
  	progname++;
  else
  	progname = argv[0];
  	
  if (geteuid() != 0) {
	fprintf(stderr, "%s: must be superuser.\n", progname);
	exit(1);
  }

  if (!strcmp(progname, "reboot")) do_reboot = 1;

  /* Get flags */
  while((c = getopt(argc, argv, ":dnw")) != EOF) {
	switch(c) {
		case 'n':
			do_sync = 0;
			do_wtmp = 0;
			break;
		case 'w':
			do_nothing = 1;
			break;
		case 'd':
			do_wtmp = 0;
			break;
		default:
			usage();
	}
  }
  if (argc != optind) usage();

  /* Record the fact that we're going down */
  if (do_wtmp && (fd = open(WTMP_FILE, O_WRONLY|O_APPEND)) >= 0) {
  	time(&t);
  	strcpy(wtmp.ut_user, "shutdown");
  	strcpy(wtmp.ut_line, "~");
  	strcpy(wtmp.ut_id,  "~~");
  	wtmp.ut_pid = 0;
  	wtmp.ut_type = RUN_LVL;
  	wtmp.ut_time = t;
  	write(fd, (char *)&wtmp, sizeof(wtmp));
  	close(fd);
  }

  /* Exit if all we wanted to do was write a wtmp record. */
  if (do_nothing) exit(0);

  if (do_sync) {
	sync();
	sleep(2);
  }

  if (do_reboot) {
	reboot(0xfee1dead, 672274793, 0x01234567);
  } else {
	/* Turn on hard reboot, CTRL-ALT-DEL will reboot now */
	reboot(0xfee1dead, 672274793, 0x89ABCDEF);
	/* And halt the system. */
	kill(-1, SIGTSTP);
	kill(-1, SIGSTOP);
	kill(0, SIGSTOP);
  }
  /* Never happens. */
  exit(0);
}
