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

Reply via email to