LCDproc development and user support list

Text archives Help


[Lcdproc] Update to lcdproc-iface 2nd try


Chronological Thread 
  • From: bsdfan AT nurfuerspam.de (Markus Dolze)
  • Subject: [Lcdproc] Update to lcdproc-iface 2nd try
  • Date: Sun May 7 22:28:01 2006

Ok, here is the second try.

In addition to the first patch I moved the statistics gathering part into
machine_*.c files for Linux and FreeBSD. For the other systems I added a
dummy function, which simply returns an error.

It compiles and works on FreeBSD. Please try and test on Linux. If anyone
feels able to add the missing parts for the other operating systems, please
help.

Regards
Markusdiff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/iface.c
./clients/lcdproc/iface.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/iface.c Fri May 5
09:00:42 2006
+++ ./clients/lcdproc/iface.c Sun May 7 23:49:47 2006
@@ -30,29 +30,18 @@
#include <string.h>
#include <time.h>

-#include "iface.h"
-#ifdef NETLCDCLIENT
-#include "sockets.h"
-#else
#include "shared/sockets.h"
#include "shared/debug.h"
#include "shared/report.h"
#include "shared/configfile.h"
#include "main.h"
+#include "util.h"
+#include "iface.h"
+#include "machine.h"
+
#define UNSET_INT -1
#define UNSET_STR "\01"
-#endif //NETLCDCLIENT
-
-
-#ifdef NETLCDCLIENT
-/* Option flags and global variables */

-char *program_name; /* the name the program was run with */
-int port = 13666; /* default port */
-char server[256] = "localhost"; /* default server */
-int daemon_mode = 0; /* by default, no daemon mode */
-int sock = 0; /* socket handler */
-#endif //NETLCDCLIENT

int iface_count = 0; /* number of interfaces */

@@ -75,255 +64,6 @@
};


-#ifdef NETLCDCLIENT
-/*************************************************************************
- * MAIN PROGRAM FUNCTION
- *************************************************************************
- */
-
-int
-main (int argc, char **argv)
-{
-
- IfaceInfo iface[MAX_INTERFACES]; /* interface info */
-
- int len; /* bytes read from server */
-
- char readbuff[MAXMSG]; /* read buffer from server */
-
- unsigned int sleep_time = 1; /* interval between updates (1 second)
*/
-
- int pid; /* child process identificator for daemon mode */
-
- int iface_nmbr; /* loop variable for the interface */
-
- /* Capture signals to exit program cleanly */
- signal(SIGINT, exit_program); /* Ctrl-C */
- signal(SIGTERM, exit_program); /* kill */
- signal(SIGHUP, exit_program); /* kill -HUP */
- signal(SIGKILL, exit_program); /* kill -KILL */
-
- /* get program name from command line */
- program_name = argv[0];
-
- /* parse command line parameters */
- decode_switches (argc, argv);
-
- /* check if any interface name has been introduced */
-
- if (iface_count == 0) {
- /* no one has been introduced, so exit the program showing
help */
- printf("No interface selected, please, use --interface
option\n");
- usage (1);
- }
-
- /* check if we go to daemon mode */
- if (daemon_mode) {
- signal(SIGTTOU, SIG_IGN);
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTSTP, SIG_IGN);
-
- /* create child process */
- pid = fork();
- /* create new session */
- setsid();
- signal(SIGHUP, SIG_IGN);
-
- if (pid != 0) { /* we are the parent process and exit */
- exit(0);
- }
- /* from here, we are the child process */
- }
-
- /* Try to connect to server */
- sock = sock_connect(server, port);
-
- if (sock <= 0) { /* there was some error and exit */
- fprintf(stderr, "Error: Could not connect to %s:%d\n",
server, port);
- exit(0);
- }
-
- /* Say "hello" to server */
- sock_send_string(sock, "hello\n");
-
- /* Wait the server to be prepared */
- usleep(500000);
-
- /* Read server response */
- len = sock_recv(sock, readbuff, MAXMSG);
-
- /* Now we are ready to send commands to server */
-
- /* set initial speed screen with widgets */
- initialize_speed_screen();
-
- /* set initial transfer screen if needed */
- if (transfer_screen) {
- initialize_transfer_screen();
- }
-
- /* initialize all interface structs */
- for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
- iface[iface_nmbr].last_online = 0;
- iface[iface_nmbr].status = down;
- }
-
-
- /* main loop */
- while (1) {
- /* read server responses */
- len = sock_recv(sock, readbuff, MAXMSG);
-
- /* for each interface do */
- for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
- /*read iface_parameter stats */
- if (!get_iface_stats(&iface[iface_nmbr])) {
- /* there was an error, so we exit the loop */
- break;
- }
-
- /* actualize speed values in display */
- actualize_speed_screen(&iface[iface_nmbr],
sleep_time, iface_nmbr);
-
- /* if needed, actualize transfer values in display */
- if (transfer_screen)
- actualize_transfer_screen(&iface[iface_nmbr],
iface_nmbr);
-
- /* Actual values are the old ones in the next loop */
- iface[iface_nmbr].rc_byte_old =
iface[iface_nmbr].rc_byte;
- iface[iface_nmbr].tr_byte_old =
iface[iface_nmbr].tr_byte;
- iface[iface_nmbr].rc_pkt_old =
iface[iface_nmbr].rc_pkt;
- iface[iface_nmbr].tr_pkt_old =
iface[iface_nmbr].tr_pkt;
- }
-
- /* Wait some time to do the main loop again */
- sleep(sleep_time);
- }
-
- /* Before exit the program, close the socket */
- sock_close(sock);
-
- exit (0);
-
-} /* main() */
-
-/*************************************************************************
- * END MAIN PROGRAM FUNCTION
- **************************************************************************/
-
-
-/*************************************************************************
- * Set all the option flags according to the switches specified.
- * Return the index of the first non-option argument.
- *************************************************************************
- */
-
-static int
-decode_switches (int argc, char **argv)
-{
- int c;
-
- while ((c = getopt_long (argc, argv, "i:a:s:p:u:tdhV", \
- long_options,
(int *) 0)) != EOF) {
-
- switch (c) {
- case 'i':
- /* Check number of interfaces introduced */
- if (iface_count >= MAX_INTERFACES) {
- fprintf(stderr, "Too many interfaces
introduced. "
- "Only %d are
supported.\n", MAX_INTERFACES);
- exit(0);
- }
- iface[iface_count].name = strdup(optarg);
- // make alias point to the same string as the
interface name
- iface[iface_count].alias =
iface[iface_count].name;
- iface_count++;
- break;
- case 'a':
- iface[iface_count-1].alias = strdup(optarg);
- break;
- case 's':
- strncpy(server, optarg, sizeof(server));
- server[sizeof(server)-1] = '\0';
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'u':
- /* check for valid values */
- if (strstr(optarg, "byte"))
- strncpy(unit_label, "B",
sizeof(unit_label));
- else if (strstr(optarg, "bit"))
- strncpy(unit_label, "b",
sizeof(unit_label));
- else if (strstr(optarg, "packet"))
- strncpy(unit_label, "pkt",
sizeof(unit_label));
- else {
- fprintf(stderr, "netlcdclient:
argument '%s' for -u parameter is not valid\n", optarg);
- usage(0);
- }
- unit_label[sizeof(unit_label)-1] = '\0';
- break;
- case 't':
- transfer_screen = 1; /* show transfer screen
*/
- break;
- case 'd':
- daemon_mode = 1; /* go to daemon mode */
- break;
- case 'V': /* show version */
- fprintf(stdout, "netlcdclient v%s\n",
VERSION);
- exit(0);
- case 'h': /* show help */
- usage(0);
- exit(0);
- }
- }
-
- return optind;
-
-} /* decode_switches() */
-
-
-/*************************************************************************
- * Show program help and exit.
- *************************************************************************
- */
-
-static void
-usage (int status)
-{
- printf ("\n"
-"netlcdclient v%s for LCDproc, by Luis Llorente\n", VERSION);
- printf ("\n"
-"Usage: %s -i <interface> [-a alias] [ -tdhV ] [ -s server ] [ -p port ] [-u
unit]\n", program_name);
- printf ("\n"
-"Options in []'s are optional.\n"
-" -i , --interface=INTERFACE show INTERFACE statistics\n"
-" -a , --alias=ALIAS alias name for the interface (-a has
to \n"
-" follow -i)\n"
-" -s, --server=SERVER connect to SERVER (default is
localhost)\n"
-" -p, --port=NUMBER connect to specified port number
(default\n"
-" is 13666)\n"
-" -u, --unit=TYPE speed measure unit. Available units
are:\n"
-" byte (default)\n"
-" bit\n"
-" packet\n"
-" -t, --transfer add screen with transferred traffic\n"
-" -d, --daemon run in the background\n"
-" -h, --help display this help and exit\n"
-" -V, --version output version information and exit\n"
-);
- printf("\n"
-"Example:\n"
-" %s -s my.server.org -p 2300 -u bit -i eth0 -a LAN\n", program_name);
-
- exit (status);
-
-} /* usage() */
-
-
-#else
-
-
/* reads and parses configuration file */
static int
iface_process_configfile()
@@ -422,7 +162,7 @@
/* for each interface do */
for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
/*read iface_parameter stats */
- if (!get_iface_stats(&iface[iface_nmbr])) {
+ if (!machine_get_iface_stats(&iface[iface_nmbr])) {
/* there was an error, so we exit the loop */
break;
}
@@ -444,140 +184,6 @@
return 0;
} // End iface_screen()

-#endif //NETLCDCLIENT
-
-/*************************************************************************
- * Read interface statistics from system and store in the struct
- * passed as a pointer. If there are no errors, it returns 1. If errors,
- * returns 0.
- *************************************************************************
- */
-
-int
-get_iface_stats (IfaceInfo *interface)
-{
-#ifdef linux
- FILE *file; /* file handler */
- char buffer[1024]; /* buffer to work with the file */
- static int first_time = 1; /* is it first time we call this
function? */
- char *ch_pointer = NULL; /* pointer to where interface values are in
file */
-
- /* Open the file in read-only mode and parse */
-
- if ((file = fopen(DEVFILE, "r")) != NULL) {
- /* Skip first 2 header lines of file */
- fgets(buffer, sizeof(buffer), file);
- fgets(buffer, sizeof(buffer), file);
-
- /* By default, treat interface as down */
- interface->status = down;
-
- /* Search iface_name and scan values */
- while ((fgets(buffer, sizeof(buffer), file) != NULL)) {
- if (strstr(buffer, interface->name)) {
- /* interface exists */
- interface->status = up; /* is up */
- interface->last_online = time(NULL); /* save
actual time */
-
- /* search ':' and skip over it */
- ch_pointer = strchr(buffer, ':');
- ch_pointer++;
-
- /* Now ch_pointer points to values of
iface_name */
- /* Scan values from here */
- sscanf(ch_pointer, "%lf %lf %*s %*s %*s %*s
%*s %*s %lf %lf",
- &interface->rc_byte,
- &interface->rc_pkt,
- &interface->tr_byte,
- &interface->tr_pkt);
-
- /* if is the first time we call this
function,
- * old values are the same as new so we don't
- * get big speeds when calculating
- */
- if (first_time) {
- interface->rc_byte_old =
interface->rc_byte;
- interface->tr_byte_old =
interface->tr_byte;
- interface->rc_pkt_old =
interface->rc_pkt;
- interface->tr_pkt_old =
interface->tr_pkt;
- first_time = 0; /* now it isn't
first time */
- }
- }
- } /* while */
-
- fclose(file); /* close file */
- return 1; /* everything went OK */
-
- }
- else { /* error when opening the file */
- fprintf(stderr,"Error: Could not open %s\n", DEVFILE);
- return 0; /* something went wrong */
- }
-#endif
-
-#ifdef __FreeBSD__
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <net/if.h>
-#include <net/if_mib.h>
-#include <string.h>
-#include <stdio.h>
-
- static int first_time = 1; /* is it first time we call this
function? */
- int rows;
- int name[6] = {CTL_NET, PF_LINK, NETLINK_GENERIC,
IFMIB_IFDATA, 0, IFDATA_GENERAL};
- size_t len;
- struct ifmibdata ifmd; /* ifmibdata contains the network statistics */
-
- len = sizeof(rows);
- /* get number of interfaces */
- if (sysctlbyname("net.link.generic.system.ifcount", &rows, &len,
NULL, 0) == 0) {
- interface->status = down; /* set status down by default */
-
- len = sizeof(ifmd);
- /* walk through all interfaces in the ifmib table from last
to first */
- for ( ; rows > 0; rows--) {
- name[4] = rows; /* set the interface index */
- /* retrive the ifmibdata for the current index */
- if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) {
- perror("sysctl_read");
- break;
- }
- /* check if its interface name matches */
- if (strcmp(ifmd.ifmd_name, interface->name) == 0) {
- interface->last_online = time(NULL); /*
save actual time */
-
- if ((ifmd.ifmd_flags & IFF_UP) == IFF_UP)
- interface->status = up; /* is up */
-
- interface->rc_byte =
ifmd.ifmd_data.ifi_ibytes;
- interface->tr_byte =
ifmd.ifmd_data.ifi_obytes;
- interface->rc_pkt =
ifmd.ifmd_data.ifi_ipackets;
- interface->tr_pkt =
ifmd.ifmd_data.ifi_opackets;
-
- if (first_time) {
- interface->rc_byte_old =
interface->rc_byte;
- interface->tr_byte_old =
interface->tr_byte;
- interface->rc_pkt_old =
interface->rc_pkt;
- interface->tr_pkt_old =
interface->tr_pkt;
- first_time = 0; /* now it isn't first
time */
- }
- return 1;
- }
- }
- /* if we are here there is no interface with the given name */
- fprintf(stderr, "There is no interface named %s\n",
interface->name);
- return 0;
- } else {
- perror("get_iface_stats");
- return 0;
- }
-
-#endif /* __FreeBSD__ */
-
-} /* get_iface_stats() */

/*************************************************************************
* Send commands to server to add speed screen with all required widgets
@@ -649,72 +255,22 @@
void
format_value (char *buff, double value, char *unit)
{
- float formated_value;
-
- /* if the measure unit is in 'b' (bits), the value passed must
- * be converted to bits (from bytes)
- */
- if (strstr(unit, "b")) {
+ /* Convert bytes to bits, if necessary */
+ if (strstr(unit, "b"))
value *= 8;
- }
-
- /* bytes, bits or packets */
- if (value < 1024) {
- sprintf(buff, "%8ld %s",(long)value, unit);
- return;
- }
-
- /* Kilobytes, Kilobits of Kilopackets */
- if (value < 1000000.0f) {
- if (strstr(unit, "B")) { /* 1 KB = 1024 */
- formated_value = (float) value / 1024.0f;
- }
- else { /* 1 K = 1000 */
- formated_value = (float) value / 1000.0f;
- }
-
- sprintf(buff, "%8.3f K%s", formated_value, unit);
- return;
- }

- /* Megabytes, Megabits or Megapackets */
- if (value < 1000000000.0f) {
- if (strstr(unit, "B")) { /* 1 MB = 1024 KB */
- formated_value = (float) value / 1048576.0f; /* 1024
^ 2 */
- }
- else { /* 1 M = 1000 K */
- formated_value = (float) value / 1000000.0f; /* 1000
^ 2 */
- }
-
- sprintf(buff, "%8.3f M%s", formated_value, unit);
- return;
- }
+ /* If units are bytes, then divide by 2^10, otherwise by 10^3 */
+ char *mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000,
1.0f);

- /* Gigabytes, Gigabits or Gigapackets */
- if (value < 1000000000000.0f) {
- if (strstr(unit, "B")) { /* 1 GB = 1024 MB */
- formated_value = (float) value / 1073741824.0f; /*
1024 ^ 3 */
- }
- else { /* 1 G = 1000 M */
- formated_value = (float) value / 1000000000.0f; /*
1000 ^ 3 */
- }
-
- sprintf(buff, "%8.3f G%s", formated_value, unit);
- return;
- }
+ /* Formatting rules:
+ * - if original value was < 1000, output decimal value only
+ * - otherwise format with 3 precision
+ */
+ if (mag[0] == 0)
+ sprintf(buff, "%8ld %s", (long) value, unit);
+ else
+ sprintf(buff, "%7.3f %s%s", value, mag, unit);

- /* Terabytes, Terabits or Terapackets */
- if (value >= 1000000000000.0f) {
- if (strstr(unit, "B")) { /* 1 TB = 1024 GB */
- formated_value = (float) value / 1099511627776.0f; /*
1024 ^ 4 */
- }
- else { /* 1 T = 1000 G */
- formated_value = (float) value / 1000000000000.0f; /*
1000 ^ 4 */
- }
-
- sprintf(buff, "%8.3f T%s", formated_value, unit);
- return;
- }
} /* format_value() */

/*************************************************************************
@@ -726,97 +282,23 @@
void
format_value_multi_interface (char *buff, double value, char *unit)
{
- char mybuff[20]; /* temp buffer */
- float formated_value;
-
- /* if the measure unit is in 'b' (bits), the value passed must
- * be converted to bits (from bytes)
- */
- if (strstr(unit, "b")) {
+ if (strstr(unit, "b"))
value *= 8;
- }
-
- /* bytes, bits or packets */
- if (value < 1000) {
- sprintf(buff, "%3ld ", (long)value);
- return;
- }
-
- /* Kilobytes, Kilobits of Kilopackets */
- if (value < 1000000) {
- if (strstr(unit, "B")) { /* 1 KB = 1024 */
- formated_value = (float) value / 1024.0f;
- }
- else { /* 1 K = 1000 */
- formated_value = (float) value / 1000.0f;
- }
-
- sprintf(mybuff, "%3.1f", formated_value);
- if (mybuff[2] != '.') {
- sprintf(buff, "%.3sK", mybuff);
- }
- else {
- sprintf(buff, " %.2sK", mybuff);
- }
- return;
- }

- /* Megabytes, Megabits or Megapackets */
- if (value < 1000000000.0f) {
- if (strstr(unit, "B")) { /* 1 MB = 1024 KB */
- formated_value = (float) value / 1048576.0f; /* 1024
^ 2 */
- }
- else { /* 1 M = 1000 K */
- formated_value = (float) value / 1000000.0f; /* 1000
^ 2 */
- }
-
- sprintf(mybuff, "%3.1f", formated_value);
- if (mybuff[2] != '.') {
- sprintf(buff, "%.3sM", mybuff);
- }
- else {
- sprintf(buff, " %.2sM", mybuff);
- }
- return;
- }
+ char *mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000,
1.0f);

- /* Gigabytes, Gigabits or Gigapackets */
- if (value < 1000000000000.0f) {
- if (strstr(unit, "B")) { /* 1 GB = 1024 MB */
- formated_value = (float) value / 1073741824.0f; /*
1024 ^ 3 */
- }
- else { /* 1 G = 1000 M */
- formated_value = (float) value / 1000000000.0f; /*
1000 ^ 3 */
- }
-
- sprintf(mybuff, "%3.1f", formated_value);
- if (mybuff[2] != '.') {
- sprintf(buff, "%.3sG", mybuff);
- }
- else {
- sprintf(buff, " %.2sG", mybuff);
- }
- return;
- }
+ /* Formatting rules:
+ * - if original value was < 1000, output decimal value only
+ * - with 1 precision if <10
+ * - decimal value with magnitude otherwise
+ */
+ if (mag[0] == 0)
+ sprintf(buff, "%4ld", (long) value);
+ else if (value < 10)
+ sprintf(buff, "%3.1f%s", value, mag);
+ else
+ sprintf(buff, "%3.f%s", value, mag);

- /* Terabytes, Terabits or Terapackets */
- if (value >= 1000000000000.0f) {
- if (strstr(unit, "B")) { /* 1 TB = 1024 GB */
- formated_value = (float) value / 1099511627776.0f; /*
1024 ^ 4 */
- }
- else { /* 1 T = 1000 G */
- formated_value = (float) value / 1000000000000.0f; /*
1000 ^ 4 */
- }
-
- sprintf(mybuff, "%3.1f", formated_value);
- if (mybuff[2] != '.') {
- sprintf(buff, "%.3sT", mybuff);
- }
- else {
- sprintf(buff, " %.2sT", mybuff);
- }
- return;
- }
} /* format_value_multi_interface() */

/*************************************************************************
@@ -1032,23 +514,3 @@
}
}
} /* actualize_transfer_screen() */
-
-#ifdef NETLCDCLIENT
-/*************************************************************************
- * Exit the program in a clean way
- *************************************************************************
- */
-void
-exit_program (int val)
-{
- /* check if socket is open and close it */
- if (sock != 0) {
- sock_close(sock);
- }
-
- fprintf(stderr, "\nExiting netlcdclient....\n");
-
- exit(0);
-
-} /* exit_program() */
-#endif //NETLCDCLIENT
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/iface.h
./clients/lcdproc/iface.h
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/iface.h Fri Apr 28
10:01:40 2006
+++ ./clients/lcdproc/iface.h Sun May 7 23:50:02 2006
@@ -12,48 +12,10 @@


#include <time.h>
-
-#define DEVFILE "/proc/net/dev" /* file to read statistics from */
-
-/* status definitions */
-
-typedef enum {
- down = 0,
- up = 1,
-} IfaceStatus;
+#include "machine.h"

#define MAX_INTERFACES 3 /* max number of interfaces in multi-interface
mode */

-/* Struct for interface values (transmision, reception, etc..) */
-
-typedef struct iface_info
-{
- /* interface name and alias (=display name) */
- char *name;
- char *alias;
-
- IfaceStatus status;
-
- time_t last_online;
-
- /* received bytes */
- double rc_byte;
- double rc_byte_old;
-
- /* transmited bytes */
- double tr_byte;
- double tr_byte_old;
-
- /* received packets */
- double rc_pkt;
- double rc_pkt_old;
-
- /* transmited packets */
- double tr_pkt;
- double tr_pkt_old;
-} IfaceInfo;
-
-
int iface_screen (int rep, int display, int *flags_ptr);
IfaceInfo iface[MAX_INTERFACES]; /* interface info */

@@ -61,15 +23,6 @@
/* Functions prototipes */
/************************/

-/* show usage options */
-static void usage (int status);
-
-/* parse command line parameters */
-static int decode_switches (int argc, char **argv);
-
-/* read interface stats from /proc/net/dev */
-int get_iface_stats (IfaceInfo *interface);
-
/* send initial commands to server to add the speed screen */
void initialize_speed_screen (void);

@@ -91,10 +44,5 @@

/* actualize widgets values in transfer screen */
void actualize_transfer_screen (IfaceInfo *iface, int index);
-
-#ifdef NETLCDCLIENT
-/* exit the program cleanly */
-void exit_program (int val);
-#endif //NETLCDCLIENT

#endif
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine.h
./clients/lcdproc/machine.h
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine.h Wed Dec 24
20:47:55 2003
+++ ./clients/lcdproc/machine.h Sun May 7 23:28:07 2006
@@ -27,6 +27,40 @@
int number;
} procinfo_type;

+/* status definitions for network interfaces */
+typedef enum {
+ down = 0,
+ up = 1,
+} IfaceStatus;
+
+/* Struct for network interface values (transmision, reception, etc..) */
+typedef struct iface_info
+{
+ /* interface name and alias (=display name) */
+ char *name;
+ char *alias;
+
+ IfaceStatus status;
+
+ time_t last_online;
+
+ /* received bytes */
+ double rc_byte;
+ double rc_byte_old;
+
+ /* transmited bytes */
+ double tr_byte;
+ double tr_byte_old;
+
+ /* received packets */
+ double rc_pkt;
+ double rc_pkt_old;
+
+ /* transmited packets */
+ double tr_pkt;
+ double tr_pkt_old;
+} IfaceInfo;
+
int machine_init();
int machine_close();

@@ -38,5 +72,7 @@
int machine_get_procs(LinkedList *procs);
int machine_get_smpload(load_type *result, int *numcpus);
int machine_get_uptime(double *up, double *idle);
+int machine_get_iface_stats (IfaceInfo *interface);
+

#endif /* _lcdproc_machine_h_ */
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_Darwin.c
./clients/lcdproc/machine_Darwin.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_Darwin.c Fri
Apr 28 09:00:32 2006
+++ ./clients/lcdproc/machine_Darwin.c Sun May 7 23:53:33 2006
@@ -428,4 +428,11 @@
return(FALSE);
}

+/* Get network statistics */
+int machine_get_iface_stats (IfaceInfo *interface)
+{
+ /* Implementation missing */
+ return 0;
+}
+
#endif /* __APPLE__ */
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_FreeBSD.c
./clients/lcdproc/machine_FreeBSD.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_FreeBSD.c Fri
Apr 28 09:00:32 2006
+++ ./clients/lcdproc/machine_FreeBSD.c Sun May 7 23:35:21 2006
@@ -48,6 +48,9 @@
#include <machine/apm_bios.h>
#include <kvm.h>
#include <errno.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_mib.h>

#include "main.h"
#include "machine.h"
@@ -415,5 +418,64 @@

return(n);
}
+
+/*************************************************************************
+ * Read interface statistics from system and store in the struct
+ * passed as a pointer. If there are no errors, it returns 1. If errors,
+ * returns 0.
+ *************************************************************************
+ */
+int machine_get_iface_stats (IfaceInfo *interface)
+{
+ static int first_time = 1; /* is it first time we call this
function? */
+ int rows;
+ int name[6] = {CTL_NET, PF_LINK, NETLINK_GENERIC,
IFMIB_IFDATA, 0, IFDATA_GENERAL};
+ size_t len;
+ struct ifmibdata ifmd; /* ifmibdata contains the network statistics */
+
+ len = sizeof(rows);
+ /* get number of interfaces */
+ if (sysctlbyname("net.link.generic.system.ifcount", &rows, &len,
NULL, 0) == 0) {
+ interface->status = down; /* set status down by default */
+
+ len = sizeof(ifmd);
+ /* walk through all interfaces in the ifmib table from last
to first */
+ for ( ; rows > 0; rows--) {
+ name[4] = rows; /* set the interface index */
+ /* retrive the ifmibdata for the current index */
+ if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) {
+ perror("read sysctl");
+ break;
+ }
+ /* check if its interface name matches */
+ if (strcmp(ifmd.ifmd_name, interface->name) == 0) {
+ interface->last_online = time(NULL); /*
save actual time */
+
+ if ((ifmd.ifmd_flags & IFF_UP) == IFF_UP)
+ interface->status = up; /* is up */
+
+ interface->rc_byte =
ifmd.ifmd_data.ifi_ibytes;
+ interface->tr_byte =
ifmd.ifmd_data.ifi_obytes;
+ interface->rc_pkt =
ifmd.ifmd_data.ifi_ipackets;
+ interface->tr_pkt =
ifmd.ifmd_data.ifi_opackets;
+
+ if (first_time) {
+ interface->rc_byte_old =
interface->rc_byte;
+ interface->tr_byte_old =
interface->tr_byte;
+ interface->rc_pkt_old =
interface->rc_pkt;
+ interface->tr_pkt_old =
interface->tr_pkt;
+ first_time = 0; /* now it isn't first
time */
+ }
+ return 1;
+ }
+ }
+ /* if we are here there is no interface with the given name */
+ return 0;
+ } else {
+ perror("read sysctlbyname");
+ return 0;
+ }
+} /* get_iface_stats() */
+

#endif /* __FreeBSD__ */
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_Linux.c
./clients/lcdproc/machine_Linux.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_Linux.c Fri
Apr 28 09:00:32 2006
+++ ./clients/lcdproc/machine_Linux.c Sun May 7 23:49:35 2006
@@ -34,6 +34,7 @@
#include "shared/LL.h"

#define MAX_CPUS 8
+#define DEVFILE "/proc/net/dev" /* file to read network statistics from */

static int batt_fd;
static int load_fd;
@@ -511,5 +512,72 @@

return(TRUE);
}
+
+
+/*************************************************************************
+ * Read interface statistics from system and store in the struct
+ * passed as a pointer. If there are no errors, it returns 1. If errors,
+ * returns 0.
+ *************************************************************************
+ */
+int machine_get_iface_stats (IfaceInfo *interface)
+{
+ FILE *file; /* file handler */
+ char buffer[1024]; /* buffer to work with the file */
+ static int first_time = 1; /* is it first time we call this
function? */
+ char *ch_pointer = NULL; /* pointer to where interface values are in
file */
+
+ /* Open the file in read-only mode and parse */
+
+ if ((file = fopen(DEVFILE, "r")) != NULL) {
+ /* Skip first 2 header lines of file */
+ fgets(buffer, sizeof(buffer), file);
+ fgets(buffer, sizeof(buffer), file);
+
+ /* By default, treat interface as down */
+ interface->status = down;
+
+ /* Search iface_name and scan values */
+ while ((fgets(buffer, sizeof(buffer), file) != NULL)) {
+ if (strstr(buffer, interface->name)) {
+ /* interface exists */
+ interface->status = up; /* is up */
+ interface->last_online = time(NULL); /* save
actual time */
+
+ /* search ':' and skip over it */
+ ch_pointer = strchr(buffer, ':');
+ ch_pointer++;
+
+ /* Now ch_pointer points to values of
iface_name */
+ /* Scan values from here */
+ sscanf(ch_pointer, "%lf %lf %*s %*s %*s %*s
%*s %*s %lf %lf",
+ &interface->rc_byte,
+ &interface->rc_pkt,
+ &interface->tr_byte,
+ &interface->tr_pkt);
+
+ /* if is the first time we call this
function,
+ * old values are the same as new so we don't
+ * get big speeds when calculating
+ */
+ if (first_time) {
+ interface->rc_byte_old =
interface->rc_byte;
+ interface->tr_byte_old =
interface->tr_byte;
+ interface->rc_pkt_old =
interface->rc_pkt;
+ interface->tr_pkt_old =
interface->tr_pkt;
+ first_time = 0; /* now it isn't
first time */
+ }
+ }
+ } /* while */
+
+ fclose(file); /* close file */
+ return 1; /* everything went OK */
+
+ }
+ else { /* error when opening the file */
+ perror("Error: Could not open DEVFILE");
+ return 0; /* something went wrong */
+ }
+} /* get_iface_stats() */

#endif /* linux */
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_NetBSD.c
./clients/lcdproc/machine_NetBSD.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_NetBSD.c Fri
Apr 28 09:00:32 2006
+++ ./clients/lcdproc/machine_NetBSD.c Sun May 7 23:53:52 2006
@@ -370,5 +370,12 @@
return(TRUE);
}

+/* Get network statistics */
+int machine_get_iface_stats (IfaceInfo *interface)
+{
+ /* Implementation missing */
+ return 0;
+}
+
#endif /* __NetBSD__ */

diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_OpenBSD.c
./clients/lcdproc/machine_OpenBSD.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_OpenBSD.c Fri
Apr 28 09:00:32 2006
+++ ./clients/lcdproc/machine_OpenBSD.c Sun May 7 23:54:11 2006
@@ -378,4 +378,11 @@
return(TRUE);
}

+/* Get network statistics */
+int machine_get_iface_stats (IfaceInfo *interface)
+{
+ /* Implementation missing */
+ return 0;
+}
+
#endif /* __OpenBSD__ */
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_SunOS.c
./clients/lcdproc/machine_SunOS.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/machine_SunOS.c Sun
Feb 19 09:00:11 2006
+++ ./clients/lcdproc/machine_SunOS.c Sun May 7 23:54:23 2006
@@ -439,5 +439,12 @@
return(TRUE);
}

+/* Get network statistics */
+int machine_get_iface_stats (IfaceInfo *interface)
+{
+ /* Implementation missing */
+ return 0;
+}
+
#endif /* sun */

diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/util.c
./clients/lcdproc/util.c
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/util.c Fri Apr 28
09:00:32 2006
+++ ./clients/lcdproc/util.c Sun May 7 15:55:39 2006
@@ -35,25 +35,16 @@
sprintf_memory(char *dst, double value, double roundlimit)
{
if (dst != NULL) {
- static char *units[] = { "", "k", "M", "G", "T", "P", "E",
"Z", "Y", NULL };
- int offs = 0;
char *format = "%.1f%s";

- if ((roundlimit <= 0.0) || (roundlimit > 1.0))
- roundlimit = 0.5;
+ char *unit = convert_double(&value, 1024, roundlimit);

- while (units[offs] != NULL) {
- if (value <= 1024 * roundlimit)
- break;
- offs++;
- value /= 1024;
- }
if (value < 100)
format = "%.2f%s";
if (value < 10)
format = "%.3f%s";

- sprintf(dst, format, value, units[offs]);
+ sprintf(dst, format, value, unit);
}
return dst;
}
@@ -70,6 +61,33 @@
sprintf(dst, "%.1f%%", (percent >= 0) ? percent : 0);
}
return dst;
+}
+
+/** converts a value with unit value
+ * does not do formatting
+ * base : should be 1000 for decimal and 1024 for binary units
+ * roundlimit : set < 1.0 if precision of original input value is not
sufficient
+ */
+char *
+convert_double(double *value, int base, double roundlimit)
+{
+ static char *units[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y",
NULL };
+ int off = 0;
+
+ if ((roundlimit <= 0.0) || (roundlimit > 1.0))
+ roundlimit = 0.5;
+
+ /* Get value's order of magnitude */
+ while (units[off] != NULL) {
+ /* Note: the check for 1000 is to idenfity the number of
+ * characters in the output needed, not to decide if to scale
value.
+ */
+ if (*value < 1000 * roundlimit)
+ break;
+ off++;
+ *value /= base;
+ }
+ return units[off];
}

/* EOF */
diff -r -u ../lcdproc-CVS-current-20060506/clients/lcdproc/util.h
./clients/lcdproc/util.h
--- ../lcdproc-CVS-current-20060506/clients/lcdproc/util.h Sun May 22
17:28:05 2005
+++ ./clients/lcdproc/util.h Sun May 7 15:55:39 2006
@@ -40,6 +40,9 @@
/** print a percentage value to a given string */
char *sprintf_percent(char *dst, double percent);

+/** converts value into power-of-x representation */
+char *convert_double(double *value, int base, double roundlimit);
+
#endif /* LCDPROC_UTIL_H */

/* EOF */



Archive powered by MHonArc 2.6.18.

Top of page