I changed the tleds code to get LED display of net traffic in X.
I added an option '-x' that would if used, open the available X
displays and flask the LEDs.
Bug#50842 now into its seventh year, prevents the NumLock LED from
working, so under X the LEDs work as if the -n option is specified.
The diff file is attached.
Hugo
diff -Naur tleds-1.05beta10-orig/Makefile tleds-1.05beta10/Makefile
--- tleds-1.05beta10-orig/Makefile 2006-10-10 15:20:26.000000000 -0500
+++ tleds-1.05beta10/Makefile 2007-01-08 13:27:21.000000000 -0600
@@ -22,8 +22,8 @@
# in the source code.
tleds: tleds.c Makefile
# Making tleds
- gcc -DNO_X_SUPPORT $(GCCOPTS) -o tleds_20 tleds.c
- gcc -DNO_X_SUPPORT -DKERNEL2_1 $(GCCOPTS) -o tleds_21 tleds.c
+ gcc $(GCCOPTS) -o tleds_20 tleds.c -I /usr/X11R6/include/ -L
/usr/X11R6/lib/ -lX11
+ gcc -DKERNEL2_1 $(GCCOPTS) -o tleds_21 tleds.c -I /usr/X11R6/include/
-L /usr/X11R6/lib/ -lX11
help:
# make help - this.
diff -Naur tleds-1.05beta10-orig/tleds.c tleds-1.05beta10/tleds.c
--- tleds-1.05beta10-orig/tleds.c 2006-10-10 15:20:26.000000000 -0500
+++ tleds-1.05beta10/tleds.c 2007-01-08 13:45:26.000000000 -0600
@@ -43,6 +43,11 @@
* E. Hull (1999-08-20, 1999-05-14) for cleaner shutdown, security fixes to
* the PID handling, use of daemon for backgrounding, and the -n option. */
+/* Modified extensively by HVW (2006-01-08) to eliminate the NO_X_SUPPORT
+ * and use X to flash the LEDs if the -x option is given.
+ * This because in kernel > 2.6.17 LEDs would not work in X without the X
api-use.
+ * The displays are attempted to be opened and are used, all by the daemon. */
+
#define VERSION "1.05beta10"
#define MYNAME "tleds"
@@ -56,13 +61,6 @@
#define KERNEL2_0 1
#endif
-/* If you don't want X stuff. */
-#ifdef NO_X_SUPPORT
-#define REMOVE_X_CODE 1
-#else
-#define REMOVE_X_CODE 0
-#endif
-
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -71,12 +69,7 @@
#include <stdlib.h>
#include <time.h>
#include <signal.h>
-#if (! REMOVE_X_CODE)
#include <X11/Xlib.h>
-#else
-#define LedModeOff 0
-#define LedModeOn 1
-#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -97,6 +90,7 @@
#define KEYBOARDDEVICE "/dev/console"
#define CURRENTTTY "/dev/tty0"
#define MAXVT 64
+#define MAXDISPLAYS 2
#define NETDEVFILENAME "/proc/net/dev"
#define TERMINATESTR "Program (and child) terminated.\n"
#define DEEPSLEEP 10
@@ -128,6 +122,13 @@
ulong detach_vt_leds(int tty, int wantDetach);
char *find_device_line(char *buffer, char *netDeviceName);
inline int find_max_VT();
+
+void opendisplays();
+void closedisplays();
+void changekeyboardcontrol( unsigned long, XKeyboardControl* );
+void xsync( Bool );
+Bool was_at_least_five_secs_ago();
+
pid_t get_old_pid();
pid_t get_own_pid(char *fileName);
int get_sleeptime(int isDefinedByUser, char *interfaceName);
@@ -163,20 +164,17 @@
static char pidFileName[30] = ""; /* 30 should be enough */
static char rootPidFileName[30] = "";
-#if (! REMOVE_X_CODE)
-static Display *myDisplay = NULL;
-
-#else
-static char *myDisplay = NULL;
+static Display *myDisplay[MAXDISPLAYS];
+FILE *stream;
-#endif
static int keyboardDevice = 0;
+static long int last_time;
static char ttyLEDs[MAXVT] =
{};
static ushort previousActive = (ushort) (MAXVT + 1);
static int remindVTcoef = 0;
static int opt_b = FALSE, opt_d = FALSE, opt_h = FALSE, opt_k = FALSE, opt_q
-= FALSE, opt_v = FALSE, opt_V = FALSE, opt_c = FALSE, opt_n = FALSE;
+= FALSE, opt_v = FALSE, opt_V = FALSE, opt_c = FALSE, opt_n = FALSE, opt_x =
FALSE;
static int inled = NUMLOCKLED, outled = SCROLLLOCKLED;
/* The code */
@@ -184,7 +182,7 @@
{
char *interfaceName;
char buffer[MAXLEN];
- ulong ledVal;
+// ulong ledVal;
char *tmpPointer;
char **list;
pid_t pid;
@@ -192,6 +190,10 @@
int wasInDeepSleep;
struct timeval sleeptimeval;
+ int i;
+ for (i=0; i<MAXDISPLAYS; i++)
+ myDisplay[i] = NULL;
+
interfaceName = NULL;
sleeptime = 0;
check_kernel_version(); /* May die here */
@@ -270,26 +272,9 @@
fprintf(stderr, "%s:%s", KEYBOARDDEVICE, TERMINATESTR);
exit(1);
}
- } else { /* EUID not root */
-#if (! REMOVE_X_CODE)
- if (!(myDisplay = XOpenDisplay(NULL)) /* X */
- &&ioctl(0, KDGETLED, &ledVal)) { /* VT */
- perror(
- "tleds: Can't open X DISPLAY on the current host.");
- fprintf(stderr, TERMINATESTR);
- exit(1);
- }
-#else
- if (ioctl(0, KDGETLED, &ledVal)) {
- perror("main: tleds: KDGETLED");
- fprintf(stderr,
- "Error reading current led setting.\n%s\n",
- "Maybe stdin is not a VT?");
- fprintf(stderr, TERMINATESTR);
- exit(1);
- }
-#endif
- }
+ if (opt_x)
+ opendisplays(); /* this will try to open any displays -
no errors to stderr */
+ }
sleeptimeval.tv_sec = (int) ((long) sleeptime * 1000L) / 1000000L;
sleeptimeval.tv_usec = (int) ((long) sleeptime * 1000L) % 1000000L;
remindVTcoef = (int) ((long) REMINDVTDELAY * 1000L / (long) sleeptime);
@@ -432,76 +417,68 @@
static ulong ledReminder = 0x00;
ulong ledVal;
-#if (! REMOVE_X_CODE)
XKeyboardControl values;
-#endif
#ifdef DEBUG
printf("led(%d, %d)\n", led, (int) mode);
#endif
-#if (! REMOVE_X_CODE)
- if (myDisplay) {
- switch (mode) {
- case SET:
- values.led_mode = LedModeOn;
- break;
- case CLEAR:
- values.led_mode = LedModeOff;
- break;
- case TOGGLE:
- values.led_mode = LedModeOn;
- }
+
+ switch (mode) {
+ case SET:
+ values.led_mode = LedModeOn;
+ break;
+ case CLEAR:
+ values.led_mode = LedModeOff;
+ break;
+ case TOGGLE:
+ values.led_mode = LedModeOn;
}
values.led = led;
-#endif
- if (myDisplay) {
-#if (! REMOVE_X_CODE)
- XChangeKeyboardControl(myDisplay, KBLed | KBLedMode, &values);
+ if (opt_x) {
+ changekeyboardcontrol(KBLed | KBLedMode, &values);
if (doAction != DELAYED)
- XSync(myDisplay, FALSE);
-#endif
- } else {
- if (doAction != FINISH) {
- if (ioctl(keyboardDevice, KDGETLED, &ledVal)) {
- perror("led: tleds: KDGETLED");
- exit(1);
- }
- } else {
- ledVal = 0L;
- }
- 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;
- default:
- perror("led: tleds: wrong led-value");
+ xsync(FALSE);
+ }
+ if (doAction != FINISH) {
+ if (ioctl(keyboardDevice, KDGETLED, &ledVal)) {
+ perror("led: tleds: KDGETLED");
exit(1);
}
- if (opt_c && doAction != FINISH) {
- ledVal = correct_caps(ledVal);
+ } else {
+ ledVal = 0L;
+ }
+ 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;
+ default:
+ perror("led: tleds: wrong led-value");
+ exit(1);
+ }
+ if (opt_c && doAction != FINISH) {
+ ledVal = correct_caps(ledVal);
+ }
+ if (doAction) { /* FINISH or NOW */
+ if (doAction == FINISH)
+ ledVal |= ledReminder;
+ if (ioctl(keyboardDevice, KDSETLED, (char) ledVal)) {
+ perror("led: tleds: KDSETLED");
+ exit(1);
}
- if (doAction) { /* FINISH or NOW */
- if (doAction == FINISH)
- ledVal |= ledReminder;
- if (ioctl(keyboardDevice, KDSETLED, (char) ledVal)) {
- perror("led: tleds: KDSETLED");
- exit(1);
- }
- ledReminder = 0x00;
- } else {
+ ledReminder = 0x00;
+ } else {
/* Well, we know from report_traffic(), LED_SCR is processed
later. OK, kludge. */
- ledReminder = ledVal & ~LED_SCR;
- }
+ ledReminder = ledVal & ~LED_SCR;
}
}
@@ -621,12 +598,10 @@
{
if (opt_b && !opt_q)
printf("Bye-Bye !\n");
- if (myDisplay) {
-#if (! REMOVE_X_CODE)
+ if (opt_x) {
clear_led(NUMLOCKLED);
clear_led(SCROLLLOCKLED);
- XCloseDisplay(myDisplay); /* X */
-#endif
+ closedisplays();
}
detach_all_vt_leds(FALSE); /* re-attach */
if (keyboardDevice) /* EUID root - CONSOLE */
@@ -794,7 +769,7 @@
{
int c;
- while (EOF != (c = getopt(argc, argv, "bncd:hkqvV"))) {
+ while (EOF != (c = getopt(argc, argv, "bncd:hkqvxV"))) {
switch (c) {
case 'V':
opt_V = TRUE;
@@ -825,6 +800,9 @@
case 'v':
opt_v = TRUE;
break;
+ case 'x':
+ opt_x = TRUE;
+ break;
default:
opt_h = TRUE;
/* assert(0); */
@@ -902,13 +880,15 @@
printf("Usage: %s [-bchkqv] [-d <update_delay>] <interface_name>\n",
name);
printf("Example: %s -d 300 ppp0\n", name);
- printf("Options:\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+ printf("Options:\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"\t-b\tDon't go to the background.",
"\t-c\tFix the CapsLED in VTs. Only for EUID root.",
"\t-d N\tSet update delay.",
"\t\tN must be between 1 and 10000 (milliseconds)",
"\t-h\tHelp. (this)",
"\t-k\tKill (old) (x)tleds running.",
+ "\t-n\tUse only ScrollLock LED.",
+ "\t-x\tAlso use X to flash LEDs.",
"\t-q\tBe quiet.",
"\t-v\tPrint version information.",
"\t\t(`cat /proc/net/dev` to see your interfaces.)");
@@ -971,6 +951,112 @@
}
/* End (almost) verbatim copy of kbd-0.99's getfd.c */
+
+
+void opendisplays(void)
+{
+// XSetErrorHandler(X_error_handler); // but
these don't do anything for XOpen
+// XSetIOErrorHandler(X_IO_error_handler); // ...
+
+ int std_err = dup(2); // save
the original stderr
+ stream = freopen("/dev/null", "w", stderr);
// now dump the messages
+ int i;
+
+ char displayName[10]; // Try
to open the displays
+ for (i=0; i<MAXDISPLAYS; i++) {
+ sprintf(displayName,":%d.0",i);
+ if ( !myDisplay[i] )
+ if ( NULL == (myDisplay[i] = XOpenDisplay (displayName)) )
+ /*printf("Fail %s\n",displayName);*/
+ ;
+ }
+
+ fclose(stream); //
close the new stderr
+ dup2(std_err,2); // put
it back to the orig
+
+ struct timeval t0;
+ int n;
+
+ if ( (n=gettimeofday(&t0, NULL)) !=0) {
+ fprintf(stderr, "t0 gettimeofday error =%d\n", n);
+ }
+ else
+// printf("t0=%li%s%li%s\n", t0.tv_sec, ".", t0.tv_usec,"sec");
+ last_time = t0.tv_sec; // has
present second in the epoch
+
+}
+
+Bool was_at_least_five_secs_ago()
+{
+
+ struct timeval t0;
+ int n;
+ int long this_time, this_time_m_5;
+
+ if ( (n=gettimeofday(&t0, NULL)) !=0) {
+ fprintf(stderr, "t0 gettimeofday error =%d\n", n);
+ }
+ else {
+// printf("t0=%li%s%li%s\n", t0.tv_sec, ".", t0.tv_usec,"sec");
+ this_time = t0.tv_sec;
+ this_time_m_5 = (int) ((long) this_time - 5);
+ if ( last_time < this_time_m_5 ) {
+ last_time = this_time;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ return FALSE;
+}
+
+void closedisplays(void)
+{
+ int i;
+ for (i=0; i<MAXDISPLAYS; i++)
+ if ( myDisplay[i] )
+ XCloseDisplay(myDisplay[i]); /* X */
+
+}
+
+void changekeyboardcontrol( unsigned long values, XKeyboardControl* myxkbc)
+{
+// are all displays open?
+ int are_open = 0;
+ int i;
+
+ for (i=0; i<MAXDISPLAYS; i++)
+ if ( myDisplay[i] )
+ are_open++;
+
+ if ( (are_open < MAXDISPLAYS) && was_at_least_five_secs_ago() )
+ opendisplays();
+
+ for (i=0; i<MAXDISPLAYS; i++)
+ if ( myDisplay[i] )
+ XChangeKeyboardControl(myDisplay[i], values, myxkbc);
+
+}
+
+void xsync( Bool value )
+{
+// are all displays open?
+ int are_open = 0;
+ int i;
+
+ for (i=0; i<MAXDISPLAYS; i++)
+ if ( myDisplay[i] )
+ are_open++;
+
+ if ( (are_open < MAXDISPLAYS) && was_at_least_five_secs_ago() )
+ opendisplays();
+
+ for (i=0; i<MAXDISPLAYS; i++)
+ if ( myDisplay[i] )
+ XSync(myDisplay[i], value);
+
+}
+
/*
In v2.0.x kernels:
$ cat /proc/net/dev