Previous Next Contents

8. User EnhancementsReverse-engineering cables and hacking powerd.c

Try to get documentation for the cables that your UPS seller supplies. In particular find out:

You then need to hack powerd.c appropriately.

If you have trouble getting the above information, or just want to check it (a good idea) the following program might help. It's a hacked version of powerd.c. It allows you to set the necessary port flags from the command line and then monitors the port, displaying the control lines every second. I used it as "upscheck /dev/cua1 2" (for example) to set the 2nd bit (DTR) and to clear the other bits. The number base 2 indicates which bits to set, so for example to set bits 1, 2 and 3, (and clear the others) use 7. See the code for details.

Here's the (untested) upscheck.c program. It's untested because I edited the version I originally used to make it clearer, and can't test the new version at the moment.


/*
 * upscheck     Check how UPS & computer communicate.
 *
 * Usage:       upscheck <device> <bits to set>
 *              For example, upscheck /dev/cua4 4 to set bit 3 &
 *              monitor /dev/cua4.
 *
 * Author:      Harvey J. Stein <hjstein@math.huji.ac.il>
 *              (but really just a minor modification of Miquel van
 *              Smoorenburg's <miquels@drinkel.nl.mugnet.org> powerd.c
 *
 * Version:     1.0 19940802
 *
 */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

/* Main program. */
int main(int argc, char **argv)
{
  int fd;

/*  These TIOCM_* parameters are defined in <linux/termios.h>, which  */
/*  is indirectly included here.                                      */
  int dtr_bit = TIOCM_DTR;
  int rts_bit = TIOCM_RTS;
  int set_bits;
  int flags;
  int status, oldstat = -1;
  int count = 0;
  int pc;

  if (argc < 2) {
        fprintf(stderr, "Usage: upscheck <device> <bits-to-set>\n");
        exit(1);
  }

  /* Open monitor device. */
  if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
    fprintf(stderr, "upscheck: %s: %s\n", argv[1], sys_errlist[errno]);
    exit(1);}

  /* Get the bits to set from the command line. */
  sscanf(argv[2], "%d", &set_bits);

  while (1) {
    /* Set the command line specified bits (& only the command line */
    /* specified bits).                                             */
    ioctl(fd, TIOCMSET, &set_bits);
    fprintf(stderr, "Setting %o.\n", set_bits);

    sleep(1);

    /* Get the current line bits */
    ioctl(fd, TIOCMGET, &flags);
    fprintf(stderr, "Flags are %o.\n", flags);

/*  Fiddle here by changing TIOCM_CTS to some other TIOCM until    */
/*  this program detects that the power goes out when you yank     */
/*  the plug on the UPS.  Then you'll know how to modify powerd.c. */
    if (flags & TIOCM_CTS) 
      {
        pc = 0 ;
        fprintf(stderr, "power is up.\n");
      }
    else 
      { 
        pc = pc + 1 ; 
        fprintf(stderr, "power is down.\n");
      }
    }

  close(fd);
}


Previous Next Contents