Logo Search packages:      
Sourcecode: mailleds version File versions

leds.c

#include <unistd.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

#ifdef X_SUPPORT
#include <X11/X.h>
#include <X11/Xlib.h>
#endif

#include "config.h"
#include "mailleds.h"
#include "port.h"

#define TTY_RECOVERABLE_ERROR 8

extern int ct[MAX_CONSOLES];
extern char opt_t, opt_x, *opt_d;
extern int x_leds[3];

#ifdef X_SUPPORT
extern Display *dpy;
extern int ttyfd_X; /*in mailleds.c. filedescr for tty on -x */
extern int uid, euid; /* for changing userid. we run this prog suid root. declarated in mailleds.c */
#endif

extern int kbd_leds, port_leds;
extern sig_atomic_t exit_now;

void set_kbd_leds(leds)
int leds;
{
      int kbd_ledstate, x;
      for (x = 0; ct[x] != -1; x++) {
            kbd_ledstate = get_kbd_leds(ct[x]);
            if (kbd_ledstate == TTY_RECOVERABLE_ERROR)
                  continue;
            poke_kbd_leds(ct[x], leds | kbd_ledstate);
      }
}

void poke_kbd_leds(fd, leds)
int fd, leds;
{
      if (ioctl(fd, KDSETLED, leds)) {
#ifdef DEBUG
            write(2, &"01"[(leds & 0x80) != 0], 1);
#else
            perror("mailleds: ioctl KDSETLED");
            exit(1);
#endif
      }
}

int get_kbd_leds(fd)
int fd;
{
      char ledstate;
      if (ioctl(fd, KDGETLED, &ledstate)) {
            if (errno == EIO)
                  return (TTY_RECOVERABLE_ERROR);
            perror("mailleds: ioctl KDGETLED");
            /* EIO seems to be generated when logouts are happening nearly simultaneously. 
               not serious.  Ignore, and make the other skip the tty. */
            exit(1);
      }
      return (ledstate);
}

#ifdef PARALLEL_SUPPORT
void set_port_leds(port, leds)
int port, leds;
{
      int state;
      state = port_in(port);
      port_out(port, leds | state);
}

void unset_port_leds(port, leds)
int port, leds;
{
      int state;
      state = port_in(port);
      port_out(port, leds ^ state);
}

#endif                        /* PARALLEL_SUPPORT */

#ifdef X_SUPPORT
void set_x_leds(mode)
int mode;
{
      int x, state_X = 0;
      XKeyboardControl kbd;
      kbd.led_mode = mode;
      for (x = 0; x_leds[x]; x++) {
            kbd.led = x_leds[x];
            
            /* catch status: to state_X*/
            ioctl(ttyfd_X, KDGETLED, &state_X); 
            
            /*dennis*/
            if(mode == LedModeOn) {
                  /* now light the leds and the led which is set from beginning by user (eg. user
                     has activated numlock, the LED_NUM must be on, too.
                     This bitwise OR is needed because if kbd_leds only, _all_ leds will be off,
                     then set ONLY kbd_leds on. */
                  ioctl(ttyfd_X, KDSETLED, state_X|kbd_leds);
            }
            else {
                  /* state_X has actual state of leds. All leds that are on. Also the users numlock
                     (see example above). We have to subtract the kbd_leds from state_X. */
                  ioctl(ttyfd_X, KDSETLED, state_X-kbd_leds);
            }
            
            #ifdef DEBUG
            printf("KBLed: %d   KBLedMode%d  kbd_leds%d\n", KBLed, KBLedMode, kbd_leds);
            #endif
            /*dennis end*/
            /* This was set before, but doesn't work. See Debian BTS on bug #122755
               http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=122755
            XChangeKeyboardControl(dpy, KBLed | KBLedMode, &kbd);*/
            
      }
}
#endif

/* theoretically, one of these days the pauses will be command line switches */
void blink_once(on_pause, off_pause)
unsigned long on_pause, off_pause;
{
      if (opt_t)
            set_kbd_leds(kbd_leds);
#ifdef X_SUPPORT
      if (opt_x) {
            /*dpy = XOpenDisplay(opt_d);*/
            setreuid(uid, euid);    /* set uid to root because we run this prog suid root */
            set_x_leds(LedModeOn);
            /*XCloseDisplay(dpy);*/
      }
#endif
#ifdef PARALLEL_SUPPORT
      if (port_leds)
            set_port_leds(LPT_PORT, port_leds);
#endif
      usleep(on_pause);
      if (opt_t)
            set_kbd_leds(0xff);
#ifdef X_SUPPORT
      if (opt_x) {
            /*dpy = XOpenDisplay(opt_d);*/
            set_x_leds(LedModeOff);
            /*XCloseDisplay(dpy);*/
            setreuid(euid, uid);    /* remove root. (security issues) */
      }
#endif
#ifdef PARALLEL_SUPPORT
      if (port_leds)
            unset_port_leds(LPT_PORT, port_leds);
#endif
      usleep(off_pause);
}

void blink_x(on_pause, off_pause, x)
unsigned long on_pause;
unsigned long off_pause;
int x;
{
      for (; x && !exit_now; x--)
            blink_once(on_pause, off_pause);
}

Generated by  Doxygen 1.6.0   Back to index