#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <linux/kd.h>
#include <fcntl.h>
#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);
}
}
syntax highlighted by Code2HTML, v. 0.9.1