[PATCH] modemlights, ISDN and providers with long phone numbers



Hi John, hi list,

the attached patch fixes a bug in modemlights which causes connections via
ISDN to providers with longer phone numbers not to be recognized as on.
This happens with kernel 2.4 and/or glibc 2.2 (dont nail me on this
combination, it's just what I use).

Explanation:

is_ISDN_on() uses multiple subsequent calls to fgets() on /dev/isdninfo.
This apparently doesn't work in the aforementioned case and by strace()ing
around a bit, I saw that only 1024 bytes of /dev/isdninfo is read(). With
my combination, if you read() from isdninfo with a size less than the size
of its contents, nothing will be read() :-(. I don't know whether this is
wilful or a bug(*), but the attached patch works around this by directly
using open(), read() instead of fopen(), fread().

(*) I guess it is wilful because such accesses should be atomic somehow.

It would be nice to have this in the next release of gnome-applets, be it
1.2.5 or 1.4.0.

Nils
-- 
 Nils Philippsen / Berliner Straße 39 / D-71229 Leonberg // +49.7152.209647
nils wombat dialup fht-esslingen de / nils redhat de / nils fht-esslingen de
   The use of COBOL cripples the mind; its teaching should, therefore, be
   regarded as a criminal offence.                  -- Edsger W. Dijkstra
--- gnome-applets-1.2.4/modemlights/ChangeLog.k24glibc22	Sun Jan 21 18:29:55 2001
+++ gnome-applets-1.2.4/modemlights/ChangeLog	Sun Jan 21 18:34:56 2001
@@ -1,3 +1,8 @@
+2001-01-21  Nils Philippsen <nils wombat dialup fht-esslingen de>
+
+	* modemlights.c (is_ISDN_on): fix to work with Linux kernel 2.4,
+	glibc 2.2 and providers with long phone numbers
+
 2000-04-25  Fatih Demir	<kabalak gmx net>
 	
 	* modemlights_applet.desktop : Added [tr] section . 
--- gnome-applets-1.2.4/modemlights/modemlights.c.k24glibc22	Thu May  4 14:24:02 2000
+++ gnome-applets-1.2.4/modemlights/modemlights.c	Sun Jan 21 19:30:45 2001
@@ -39,6 +39,7 @@
 #ifdef __linux__
 #include <linux/isdn.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include <fcntl.h>
 
 static unsigned long *isdn_stats = NULL;
@@ -199,31 +200,60 @@
 	 * for Linux use.
 	 *
 	 * Martin
+	 *
+	 * ---
+	 *
+	 * With Linux kernel 2.4, glibc 2.2 (*) and certain providers with
+	 * long phone numbers, the contents of /dev/isdninfo can be more than
+	 * 1024 bytes and not be properly processed by multiple subsequent
+	 * fgets()'s, so we (try to atomically) read() BUFSIZE bytes into
+	 * buffer[] and process this instead of /dev/isdninfo directly.
+	 *
+	 * (*): dont't nail me on this combination
+	 *
+	 * Nils
 	 */
 
-	FILE *f = 0;
 	char buffer [BUFSIZ], *p;
 	int i;
+	int fd;
+	int length;
 
-	f = fopen("/dev/isdninfo", "r");
+	fd = open ("/dev/isdninfo", O_RDONLY | O_NDELAY);
 
-	if (!f) return FALSE;
+	if (fd < 0) {
+		perror ("/dev/isdninfo");
+		return FALSE;
+	}
 
-	for (i = 0; i < 5; i++) {
-		if (fgets (buffer, BUFSIZ, f) == NULL) {
-			fclose (f);
+	if ((length = read (fd, buffer, BUFSIZ - 1)) < 0) {
+		perror ("/dev/isdninfo");
+		close (fd);
+		return FALSE;
+	}
+
+	buffer[length+1] = (char)0;
+
+	p = buffer;
+
+	/* Seek for the fifth line */
+	for (i = 1; i < 5; i++) {
+		if ((p = strchr (p, '\n')) == NULL) {
+			close (fd);
 			return FALSE;
 		}
+		p++;
 	}
 
-	if (strncmp (buffer, "flags:", 6)) {
-		fclose (f);
+	/* *p is the first character of the fifth line now */
+	if (strncmp (p, "flags:", 6)) {
+		close (fd);
 		return FALSE;
 	}
 
-	p = buffer+6;
+	p += 6;
 
-	while (*p) {
+	while (*p && (*p != '\n')) {
 		char *end = p;
 
 		if (isspace (*p)) {
@@ -244,12 +274,11 @@
 			continue;
 		}
 
-		fclose (f);
-
+		close (fd);
 		return TRUE;
 	}
 
-	fclose (f);
+	close (fd);
 
 	return FALSE;
 #else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]