Blame sysdeps/linux/ppp.c

Packit d37888
/* Copyright (C) 1998-99 Martin Baulig
Packit d37888
   This file is part of LibGTop 1.0.
Packit d37888
Packit d37888
   Contributed by Martin Baulig <martin@home-of-linux.org>, October 1998.
Packit d37888
Packit d37888
   LibGTop is free software; you can redistribute it and/or modify it
Packit d37888
   under the terms of the GNU General Public License as published by
Packit d37888
   the Free Software Foundation; either version 2 of the License,
Packit d37888
   or (at your option) any later version.
Packit d37888
Packit d37888
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit d37888
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit d37888
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit d37888
   for more details.
Packit d37888
Packit d37888
   You should have received a copy of the GNU General Public License
Packit d37888
   along with LibGTop; see the file COPYING. If not, write to the
Packit d37888
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d37888
   Boston, MA 02110-1301, USA.
Packit d37888
*/
Packit d37888
Packit d37888
#include <config.h>
Packit d37888
#include <glibtop.h>
Packit d37888
#include <glibtop/error.h>
Packit d37888
#include <glibtop/ppp.h>
Packit d37888
Packit d37888
#include <sys/ioctl.h>
Packit d37888
#include <sys/stat.h>
Packit d37888
#include <fcntl.h>
Packit d37888
Packit d37888
#include <ctype.h>
Packit d37888
Packit d37888
#include <glib.h>
Packit d37888
Packit d37888
#ifdef HAVE_ISDN_H
Packit d37888
#include <linux/isdn.h>
Packit d37888
#else
Packit d37888
#define ISDN_MAX_CHANNELS 64
Packit d37888
#define IIOCGETCPS  _IO('I',21)
Packit d37888
#endif /* HAVE_ISDN_H */
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_ppp =
Packit d37888
(1L << GLIBTOP_PPP_STATE) + (1L << GLIBTOP_PPP_BYTES_IN) +
Packit d37888
(1L << GLIBTOP_PPP_BYTES_OUT);
Packit d37888
Packit d37888
/* Init function. */
Packit d37888
Packit d37888
void
Packit d37888
_glibtop_init_ppp_s (glibtop *server)
Packit d37888
{
Packit d37888
	server->sysdeps.ppp = _glibtop_sysdeps_ppp;
Packit d37888
}
Packit d37888
Packit d37888
static gboolean
Packit d37888
get_ISDN_stats (glibtop *server, int *in, int *out)
Packit d37888
{
Packit d37888
	unsigned long isdn_stats[2 * ISDN_MAX_CHANNELS], *ptr;
Packit d37888
	int fd;
Packit d37888
Packit d37888
	*in = *out = 0;
Packit d37888
Packit d37888
	fd = open ("/dev/isdninfo", O_RDONLY);
Packit d37888
	if (fd < 0) {
Packit d37888
		return FALSE;
Packit d37888
	}
Packit d37888
Packit d37888
	if ((ioctl (fd, IIOCGETCPS, isdn_stats) < 0) && (errno != 0)) {
Packit d37888
		close(fd);
Packit d37888
		return FALSE;
Packit d37888
	}
Packit d37888
Packit d37888
	for (ptr = isdn_stats;
Packit d37888
	     ptr != (isdn_stats + G_N_ELEMENTS(isdn_stats));
Packit d37888
	     /* NOOP */) {
Packit d37888
		*in  += *ptr++; *out += *ptr++;
Packit d37888
	}
Packit d37888
Packit d37888
	close (fd);
Packit d37888
	return TRUE;
Packit d37888
}
Packit d37888
Packit d37888
static gboolean is_ISDN_on (glibtop *server, int *online)
Packit d37888
{
Packit d37888
	FILE *f = NULL;
Packit d37888
	char buffer [BUFSIZ], *p;
Packit d37888
	int i;
Packit d37888
Packit d37888
	/* Perhaps I should try to explain this code a little bit.
Packit d37888
	 *
Packit d37888
	 * ------------------------------------------------------------
Packit d37888
	 * This is from the manpage of isdninfo(4):
Packit d37888
	 *
Packit d37888
	 * DESCRIPTION
Packit d37888
	 *   /dev/isdninfo  is  a character device with major number 45
Packit d37888
	 *   and minor number 255.  It delivers status information from
Packit d37888
	 *   the Linux ISDN subsystem to user level.
Packit d37888
	 *
Packit d37888
	 * DATA FORMAT
Packit d37888
	 *   When  reading  from this device, the current status of the
Packit d37888
	 *   Linux ISDN subsystem is delivered in 6 lines of text. Each
Packit d37888
	 *   line  starts  with  a  tag  string followed by a colon and
Packit d37888
	 *   whitespace. After that the status values are appended sep-
Packit d37888
	 *   arated by whitespace.
Packit d37888
	 *
Packit d37888
	 *   flags  is the tag of line 5. In this line for every driver
Packit d37888
	 *          slot, it's B-Channel status is shown. If no  driver
Packit d37888
	 *          is  registered  in a slot, a ? is shown.  For every
Packit d37888
	 *          established B-Channel of the driver, a bit  is  set
Packit d37888
	 *          in  the  shown value. The driver's first channel is
Packit d37888
	 *          mapped to bit 0, the second channel to bit 1 and so
Packit d37888
	 *          on.
Packit d37888
	 * ------------------------------------------------------------
Packit d37888
	 *
Packit d37888
	 * So we open /dev/isdninfo, discard the first four lines of text
Packit d37888
	 * and then check whether we have something that is not `0' or `?'
Packit d37888
	 * in one of the flags fields.
Packit d37888
	 *
Packit d37888
	 * Sounds complicated, but I don't see any other way to check whether
Packit d37888
	 * we are connected. Also, this is the method some other ISDN tools
Packit d37888
	 * for Linux use.
Packit d37888
	 *
Packit d37888
	 * Martin
Packit d37888
	 */
Packit d37888
Packit d37888
	f = fopen ("/dev/isdninfo", "r");
Packit d37888
Packit d37888
	if (!f) return FALSE;
Packit d37888
Packit d37888
	for (i = 0; i < 5; i++) {
Packit d37888
		if (fgets (buffer, BUFSIZ, f) == NULL) {
Packit d37888
			fclose (f);
Packit d37888
			return FALSE;
Packit d37888
		}
Packit d37888
	}
Packit d37888
Packit d37888
	if (strncmp (buffer, "flags:", 6)) {
Packit d37888
		fclose (f);
Packit d37888
		return FALSE;
Packit d37888
	}
Packit d37888
Packit d37888
	p = buffer+6;
Packit d37888
Packit d37888
	while (*p) {
Packit d37888
		char *end = p;
Packit d37888
Packit d37888
		if (isspace (*p)) {
Packit d37888
			p++;
Packit d37888
			continue;
Packit d37888
		}
Packit d37888
Packit d37888
		for (end = p; *end && !isspace (*end); end++)
Packit d37888
			;
Packit d37888
Packit d37888
		if (*end == 0)
Packit d37888
			break;
Packit d37888
		else
Packit d37888
			*end = 0;
Packit d37888
Packit d37888
		if (!strcmp (p, "?") || !strcmp (p, "0")) {
Packit d37888
			p = end+1;
Packit d37888
			continue;
Packit d37888
		}
Packit d37888
Packit d37888
		fclose (f);
Packit d37888
Packit d37888
		*online = TRUE;
Packit d37888
		return TRUE;
Packit d37888
	}
Packit d37888
Packit d37888
	fclose (f);
Packit d37888
Packit d37888
	*online = FALSE;
Packit d37888
	return TRUE;
Packit d37888
}
Packit d37888
Packit d37888
/* Provides PPP/ISDN information. */
Packit d37888
Packit d37888
void
Packit d37888
glibtop_get_ppp_s (glibtop *server, glibtop_ppp *buf, unsigned short device)
Packit d37888
{
Packit d37888
	int in, out, online;
Packit d37888
Packit d37888
	memset (buf, 0, sizeof (glibtop_ppp));
Packit d37888
Packit d37888
	if (is_ISDN_on (server, &online)) {
Packit d37888
		buf->state = online ? GLIBTOP_PPP_STATE_ONLINE :
Packit d37888
			GLIBTOP_PPP_STATE_HANGUP;
Packit d37888
		buf->flags |= (1L << GLIBTOP_PPP_STATE);
Packit d37888
	}
Packit d37888
Packit d37888
	if (get_ISDN_stats (server, &in, &out)) {
Packit d37888
		buf->bytes_in = in;
Packit d37888
		buf->bytes_out = out;
Packit d37888
		buf->flags |= (1L << GLIBTOP_PPP_BYTES_IN) |
Packit d37888
			(1L << GLIBTOP_PPP_BYTES_OUT);
Packit d37888
	}
Packit d37888
}