/* CLICK MY LIGHT!!!#@$, light.c */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#ifdef __FreeBSD__
#include <machine/cpufunc.h>
#else
#include <asm/io.h>		/* GNU/Linux */
#endif

#define BASE_ADDRESS    0x378 /* 0x378 is 1st parallel port
                                 0x278 is 2nd parallel port */
#define SLEEP           2     /* Seconds to sleep */

int c;
extern int errno;
                            /*       pin 432  on the parallel port */
unsigned char data_0 = 0;   /* Send 00000000b  OFF    */
unsigned char data_1 = 1;   /* Send 00000001b  ON     */

int On (void);
int Off (void);
int porttest (void);
void usage (char *);

int
main (int argc, char **argv)
{

  if (geteuid () && getuid ())
    {
      fprintf (stderr, "\n\n%s must be run as root to access hardware ports.\n", argv[0]);
      fprintf (stderr, "Leaving...\n\n");
      exit (1);
    }

  if (argc < 2)
    {
      usage (argv[0]);
    }

  while ((c = getopt (argc, argv, "of")) != EOF)
    {
      switch (c)
	{

	case 'o':
	  On ();
	  exit (0);
	case 'f':
	  Off ();
	  exit (0);
	default:
	  usage (argv[0]);
	}
    }

  return (0);
}

int
On (void)
{

  porttest ();

  sleep (SLEEP);

#ifdef __FreeBSD__
  outb (BASE_ADDRESS, data_1);
#else
  outb (data_1, BASE_ADDRESS);
  ioperm (BASE_ADDRESS, 3, 0);
#endif

  return (0);
}

int
Off (void)
{

  porttest ();

  sleep (SLEEP);

#ifdef __FreeBSD__
  outb (BASE_ADDRESS, data_0);
#else
  outb (data_0, BASE_ADDRESS);
  ioperm (BASE_ADDRESS, 3, 0);
#endif

  return (0);
}

int
porttest (void)
{

#ifdef __FreeBSD__
  if (open ("/dev/io", O_RDWR) < 0)
#else
  if (ioperm (BASE_ADDRESS, 3, 1) < 0)
#endif
    {
      fprintf (stderr, "\nERROR: Can not open port 0x%x\n\n", BASE_ADDRESS);
      perror ("port");
      exit (errno);
    }
  return (0);
}

void
usage (char *pname)
{
  fprintf (stderr, "Usage: %s", pname);
  fprintf (stderr, "  -o\tTurns light on\n");
  fprintf (stderr, "\t\t-f\tTurns light off\n");
  exit (1);
}
