#include #include #include #include #include #define LedModeOff 0 #define LedModeOn 1 #define TERMINATESTR "Program (and child) terminated.\n" #define NUMLOCKLED 1 #define CAPSLOCKLED 2 #define SCROLLLOCKLED 3 #define KEYBOARDDEVICE "/dev/console" typedef enum { CLEAR = 0, SET = 1 } LedMode; void led (int what, LedMode mode); inline void clear_led (int what) { led(what, CLEAR); } inline void set_led (int what) { led(what, SET); } void my_exit (int sig); static int keyboardDevice = 0; int led_num; int main(int argc, char** argv) { int i,num,parent; if (geteuid()) { fprintf(stderr, "led must be run as root!\n"); exit(1); } if (argc!=3) { fprintf(stderr, "led: Wrong number of arguments\n"); exit(1); } led_num=strtol(argv[1], (char **)NULL, 10); num=strtol(argv[2], (char **)NULL, 10); if (num <= 0) exit(0); /* What's the point? */ signal(SIGINT, my_exit); signal(SIGTERM, my_exit); if (! geteuid()) { /* We are running as EUID root - CONSOLE */ if (-1 == (keyboardDevice = open(KEYBOARDDEVICE, O_RDONLY))) { perror(KEYBOARDDEVICE); fprintf(stderr, TERMINATESTR); exit(1); } } while(1) { i = getppid(); /* Check if parent is dead, then go kill your self */ if (i == 1 || kill(i, 0)==(-1)) { exit(0); } for (i = 0; i < num; i++) { set_led(led_num); usleep(100000); clear_led(led_num); usleep(150000); } usleep(500000); } } void my_exit(int sig) { clear_led(led_num); if (keyboardDevice) { /* EUID root - CONSOLE */ close(keyboardDevice); } exit(0); } void led (int led, LedMode mode) { char ledVal; struct { int led_mode; int led; } values; switch (mode) { case SET: values.led_mode = LedModeOn; break; case CLEAR: values.led_mode = LedModeOff; break; } values.led = led; if (ioctl(keyboardDevice, KDGETLED, &ledVal)) { perror("KDGETLED"); exit(1); } switch (led) { case SCROLLLOCKLED: if (mode == SET) ledVal |= LED_SCR; else ledVal &= ~LED_SCR; break; case NUMLOCKLED: if (mode == SET) ledVal |= LED_NUM; else ledVal &= ~LED_NUM; break; case CAPSLOCKLED: if (mode == SET) ledVal |= LED_CAP; else ledVal &= ~LED_CAP; break; default: perror("Invalid led-value"); exit(1); } if (ioctl(keyboardDevice, KDSETLED, ledVal)) { perror ("KDSETLED"); exit(1); } }