cleanup iface.c (thanks M. Dolze)

This commit is contained in:
marschap
2006-05-07 17:32:35 +00:00
parent 08bb695d8d
commit c6a1f841a7
15 changed files with 132 additions and 528 deletions
+32 -438
View File
@@ -30,30 +30,18 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "iface.h"
#ifdef NETLCDCLIENT
#include "sockets.h"
#else
#include "shared/sockets.h" #include "shared/sockets.h"
#include "shared/debug.h" #include "shared/debug.h"
#include "shared/report.h" #include "shared/report.h"
#include "shared/configfile.h" #include "shared/configfile.h"
#include "main.h" #include "main.h"
#include "util.h"
#include "iface.h"
#define UNSET_INT -1 #define UNSET_INT -1
#define UNSET_STR "\01" #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 */ int iface_count = 0; /* number of interfaces */
char unit_label[10] = "B"; /* default unit label is Bytes */ char unit_label[10] = "B"; /* default unit label is Bytes */
@@ -75,255 +63,6 @@ static struct option const long_options[] =
}; };
#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 */ /* reads and parses configuration file */
static int static int
iface_process_configfile() iface_process_configfile()
@@ -444,7 +183,6 @@ iface_screen(int rep, int display, int *flags_ptr)
return 0; return 0;
} // End iface_screen() } // End iface_screen()
#endif //NETLCDCLIENT
/************************************************************************* /*************************************************************************
* Read interface statistics from system and store in the struct * Read interface statistics from system and store in the struct
@@ -510,7 +248,7 @@ get_iface_stats (IfaceInfo *interface)
} }
else { /* error when opening the file */ else { /* error when opening the file */
fprintf(stderr,"Error: Could not open %s\n", DEVFILE); report(RPT_CRIT, "Error: Could not open %s\n", DEVFILE);
return 0; /* something went wrong */ return 0; /* something went wrong */
} }
#endif #endif
@@ -542,7 +280,7 @@ get_iface_stats (IfaceInfo *interface)
name[4] = rows; /* set the interface index */ name[4] = rows; /* set the interface index */
/* retrive the ifmibdata for the current index */ /* retrive the ifmibdata for the current index */
if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) { if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) {
perror("sysctl_read"); report(RPT_ERR, "Reading ifmibdata failed");
break; break;
} }
/* check if its interface name matches */ /* check if its interface name matches */
@@ -568,10 +306,10 @@ get_iface_stats (IfaceInfo *interface)
} }
} }
/* if we are here there is no interface with the given name */ /* if we are here there is no interface with the given name */
fprintf(stderr, "There is no interface named %s\n", interface->name); report(RPT_CRIT, "There is no interface named %s", interface->name);
return 0; return 0;
} else { } else {
perror("get_iface_stats"); report(RPT_CRIT, "Reading interface count via sysctl failed");
return 0; return 0;
} }
@@ -649,72 +387,22 @@ initialize_speed_screen(void)
void void
format_value (char *buff, double value, char *unit) format_value (char *buff, double value, char *unit)
{ {
float formated_value; /* Convert bytes to bits, if necessary */
if (strstr(unit, "b"))
/* if the measure unit is in 'b' (bits), the value passed must
* be converted to bits (from bytes)
*/
if (strstr(unit, "b")) {
value *= 8; value *= 8;
}
/* bytes, bits or packets */ /* If units are bytes, then divide by 2^10, otherwise by 10^3 */
if (value < 1024) { char *mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000, 1.0f);
/* 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); sprintf(buff, "%8ld %s", (long) value, unit);
return; else
} sprintf(buff, "%7.3f %s%s", value, mag, unit);
/* 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;
}
/* 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;
}
/* 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() */ } /* format_value() */
/************************************************************************* /*************************************************************************
@@ -726,97 +414,23 @@ format_value (char *buff, double value, char *unit)
void void
format_value_multi_interface (char *buff, double value, char *unit) format_value_multi_interface (char *buff, double value, char *unit)
{ {
char mybuff[20]; /* temp buffer */ if (strstr(unit, "b"))
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")) {
value *= 8; value *= 8;
}
/* bytes, bits or packets */ char *mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000, 1.0f);
if (value < 1000) {
sprintf(buff, "%3ld ", (long)value);
return;
}
/* Kilobytes, Kilobits of Kilopackets */ /* Formatting rules:
if (value < 1000000) { * - if original value was < 1000, output decimal value only
if (strstr(unit, "B")) { /* 1 KB = 1024 */ * - with 1 precision if <10
formated_value = (float) value / 1024.0f; * - decimal value with magnitude otherwise
} */
else { /* 1 K = 1000 */ if (mag[0] == 0)
formated_value = (float) value / 1000.0f; sprintf(buff, "%4ld", (long) value);
} else if (value < 10)
sprintf(buff, "%3.1f%s", value, mag);
else
sprintf(buff, "%3.f%s", value, mag);
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;
}
/* 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;
}
/* 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() */ } /* format_value_multi_interface() */
/************************************************************************* /*************************************************************************
@@ -1032,23 +646,3 @@ actualize_transfer_screen(IfaceInfo *iface, int index)
} }
} }
} /* actualize_transfer_screen() */ } /* 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
-11
View File
@@ -61,12 +61,6 @@ IfaceInfo iface[MAX_INTERFACES]; /* interface info */
/* Functions prototipes */ /* 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 */ /* read interface stats from /proc/net/dev */
int get_iface_stats (IfaceInfo *interface); int get_iface_stats (IfaceInfo *interface);
@@ -92,9 +86,4 @@ void actualize_speed_screen (IfaceInfo *iface, unsigned int interval, int index)
/* actualize widgets values in transfer screen */ /* actualize widgets values in transfer screen */
void actualize_transfer_screen (IfaceInfo *iface, int index); void actualize_transfer_screen (IfaceInfo *iface, int index);
#ifdef NETLCDCLIENT
/* exit the program cleanly */
void exit_program (int val);
#endif //NETLCDCLIENT
#endif #endif
+3 -3
View File
@@ -139,9 +139,9 @@ int set_mode(int shortname, char *longname, int state)
(0 == strcasecmp(longname, sequence[k].longname))) || (0 == strcasecmp(longname, sequence[k].longname))) ||
(toupper(shortname) == sequence[k].which)) { (toupper(shortname) == sequence[k].which)) {
if (!state) { if (!state) {
/* clean both the active and inititialized bits since we delete the screen */ /* clean both the active and initialized bits since we delete the screen */
sequence[k].flags &= (~ACTIVE & ~INITIALIZED); sequence[k].flags &= (~ACTIVE & ~INITIALIZED);
/* delte the screen if we are connected */ /* delete the screen if we are connected */
if (sock >= 0) { if (sock >= 0) {
sock_printf(sock, "screen_del %c\n", sequence[k].which); sock_printf(sock, "screen_del %c\n", sequence[k].which);
} }
@@ -262,7 +262,7 @@ main(int argc, char **argv)
int state = (*argv[i] == '!') ? 0 : 1; int state = (*argv[i] == '!') ? 0 : 1;
char *name = (state) ? argv[i] : argv[i]+1; char *name = (state) ? argv[i] : argv[i]+1;
int shortname = (strlen(name) == 1) ? name[0] : '\0'; int shortname = (strlen(name) == 1) ? name[0] : '\0';
fprintf(stderr, "%s%s\n", (state) ? "" : "!", name); // debug: fprintf(stderr, "%s%s\n", (state) ? "" : "!", name);
int found = set_mode(shortname, name, state); int found = set_mode(shortname, name, state);
if (!found) { if (!found) {
+29 -11
View File
@@ -35,25 +35,16 @@ char *
sprintf_memory(char *dst, double value, double roundlimit) sprintf_memory(char *dst, double value, double roundlimit)
{ {
if (dst != NULL) { if (dst != NULL) {
static char *units[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y", NULL };
int offs = 0;
char *format = "%.1f%s"; char *format = "%.1f%s";
if ((roundlimit <= 0.0) || (roundlimit > 1.0)) char *unit = convert_double(&value, 1024, roundlimit);
roundlimit = 0.5;
while (units[offs] != NULL) {
if (value <= 1024 * roundlimit)
break;
offs++;
value /= 1024;
}
if (value < 100) if (value < 100)
format = "%.2f%s"; format = "%.2f%s";
if (value < 10) if (value < 10)
format = "%.3f%s"; format = "%.3f%s";
sprintf(dst, format, value, units[offs]); sprintf(dst, format, value, unit);
} }
return dst; return dst;
} }
@@ -72,4 +63,31 @@ sprintf_percent(char *dst, double percent)
return dst; 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 */ /* EOF */
+3
View File
@@ -40,6 +40,9 @@ char *sprintf_memory(char *dst, double value, double roundlimit);
/** print a percentage value to a given string */ /** print a percentage value to a given string */
char *sprintf_percent(char *dst, double percent); 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 */ #endif /* LCDPROC_UTIL_H */
/* EOF */ /* EOF */