/*
* slmon
*
* Copyright (C) 2000, 2001, 2002 Krzysztof Luks <m00se@iq.pl>
*
* This program is distributed under the GPL license. For details see
* COPYING text.
*
* Author: Krzysztof Luks <m00se@iq.pl>
*
* $Date: 2004/06/20 15:56:48 $
* $Revision: 1.2 $
*
*/
#include "defines.h"
#include "stat.h"
#include "draw.h"
#include "signal_handling.h"
#include "rc.h"
void slmon_create_keymaps(void);
void slmon_update_current_keymap(void);
void slmon_mode_help(void);
void slmon_help_exit(void);
void slmon_mode_main(void);
void slmon_mode_netw(void);
void slmon_mode_hist(void);
void slmon_mode_proc(void);
void slmon_increase_gauge(void);
void slmon_increase_cspace(void);
void slmon_increase_rspace(void);
void slmon_decrease_gauge(void);
void slmon_decrease_cspace(void);
void slmon_decrease_rspace(void);
void slmon_fs_up(void);
void slmon_fs_down(void);
void slmon_sort_method(void);
void slmon_proc_up(void);
void slmon_proc_down(void);
void slmon_proc_page_up(void);
void slmon_proc_page_down(void);
void slmon_proc_kill(void);
void slmon_proc_sig(void);
void slmon_change_mem_unit(void);
void slmon_change_fs_unit(void);
void slmon_change_net_unit(void);
void slmon_change_cpu(void);
void slmon_add_iface(void);
void slmon_del_iface(void);
void slmon_iface_up(void);
void slmon_iface_down(void);
int slmon_getkey(void);
#ifdef HAVE_GETOPT_LONG
void slmon_print_version(void);
void slmon_getopt_help(void);
#endif /* !HAVE_GETOPT_LONG */
/*
* Main function
*/
int main(int argc, char **argv)
{
extern int cur_cpu;
SLang_Key_Type *key;
#ifdef HAVE_GETOPT_LONG
int c;
#endif /* !HAVE_GETOPT_LONG */
glibtop_cpu gcpu;
/* Variables initialization */
cur_cpu = 0;
conf.mem = 2;
conf.fs = 0;
conf.net = 1;
conf.gauge_len = 30;
conf.fs_first = 0;
conf.fs_max = 4;
conf.proc_first = 0;
conf.proc_curr = 0;
conf.iface_count = 0;
conf.iface_first = 0;
conf.iface = NULL;
conf.sort_func = slmon_cmp_pid_asc;
fnord = 0;
pos = 0;
rspace = 3;
cspace = 7;
redraw = 1;
mode = MODE_M;
do_bold = 0; /* Disable bold by default */
height = 1000; /* FIXME is there a better way? */
update_time = 490000;
col_norm = "green";
col_valu = "yellow";
col_stat = "yellow";
col_stba = "blue";
col_back = "default";
col_gra1 = "blue";
col_gra2 = "brightblue";
col_gra3 = "white";
slmon_read_conf();
#if defined HAVE_GETOPT_LONG
while ((c =
getopt_long(argc, argv, "vhm:f:n:d:u:", slmon_options,
NULL)) != -1)
switch (c) {
case 'v':
slmon_print_version();
cleanup(0);
break;
case 'h':
slmon_getopt_help();
cleanup(0);
conf.mem = 1;
break;
case 'm':
switch (tolower(optarg[0])) {
case 'b':
conf.mem = 0;
break;
case 'k':
conf.mem = 1;
break;
case 'm':
conf.mem = 2;
break;
case 'g':
conf.mem = 3;
break;
default:
fprintf(stderr, "Wrong unit!\n");
}
break;
case 'f':
switch (tolower(optarg[0])) {
case 'k':
conf.fs = 0;
break;
case 'm':
conf.fs = 1;
break;
case 'g':
conf.fs = 2;
break;
default:
fprintf(stderr, "Wrong unit!\n");
}
break;
case 'n':
switch (tolower(optarg[0])) {
case 'b':
conf.net = 0;
break;
case 'k':
conf.net = 1;
break;
case 'm':
conf.net = 2;
break;
case 'g':
conf.net = 3;
break;
default:
fprintf(stderr, "Wrong unit!\n");
}
break;
case 'd':
switch (tolower(optarg[0])) {
case 'm':
mode = MODE_M;
break;
case 'p':
mode = MODE_P;
break;
case 'n':
mode = MODE_N;
break;
case 'h':
mode = MODE_H;
break;
default:
fprintf(stderr, "Wrong mode!\n");
cleanup(-1);
}
break;
case 'u':
update_time = (unsigned long) (atof(optarg) * 1000000.0);
update_time -= (unsigned long) 10000;
break;
default:
fprintf(stderr, "Wrong option!\n");
cleanup(-1);
}
#endif /* !HAVE_GETOPT_LONG */
init_slang(); /* S-Lang initialisation, blablabla */
init_signals();
slmon_create_keymaps();
slmon_update_current_keymap();
slmon_clear_screen(7);
glibtop_init(); /* libgtop initialisation */
glibtop_get_cpu(&gcpu);
conf.cpus = glibtop_global_server->ncpu;
conf.freq = gcpu.frequency;
/* Main loop */
while (1) {
draw_status();
switch (mode) {
case MODE_H:
draw_mode_h();
break;
case MODE_M:
draw_mode_g();
break;
case MODE_N:
draw_mode_n();
break;
case MODE_P:
draw_mode_p();
break;
case MODE_X:
draw_mode_x();
break;
default:
fprintf(stderr, "Wrong mode!!!!\n");
}
print_keys(mode);
SLsmg_refresh();
fnord++;
fnord %= 2;
usleep(update_time); /* This should be: 0.5s - SLang_input_pending time */
while (SLang_input_pending(-1)) {
key = SLang_do_key(conf.map, slmon_getkey);
if ((key != NULL) && (key->type != 0))
if (key->type == SLKEY_F_INTRINSIC)
(void (*)(void)) key->f.f();
}
}
cleanup(0);
}
void slmon_create_keymaps(void)
{
SLKeyMap_List_Type *km;
/* default keymap */
km = SLang_create_keymap("slmon_default", NULL);
SLkm_define_key("q", (FVOID_STAR) cleanup, km);
SLkm_define_key("?", (FVOID_STAR) slmon_mode_help, km);
SLkm_define_key("m", (FVOID_STAR) slmon_mode_main, km);
SLkm_define_key("p", (FVOID_STAR) slmon_mode_proc, km);
SLkm_define_key("h", (FVOID_STAR) slmon_mode_hist, km);
SLkm_define_key("n", (FVOID_STAR) slmon_mode_netw, km);
/* histogram mode */
conf.map_h = SLang_create_keymap("slmon_h_map", km);
SLkm_define_key("h", (FVOID_STAR) slmon_change_cpu, conf.map_h);
SLkm_define_key("=", (FVOID_STAR) slmon_decrease_cspace, conf.map_h);
SLkm_define_key("+", (FVOID_STAR) slmon_decrease_rspace, conf.map_h);
SLkm_define_key("-", (FVOID_STAR) slmon_increase_cspace, conf.map_h);
SLkm_define_key("_", (FVOID_STAR) slmon_increase_rspace, conf.map_h);
/* main mode */
conf.map_g = SLang_create_keymap("slmon_m_map", km);
SLkm_define_key("u", (FVOID_STAR) slmon_change_mem_unit, conf.map_g);
SLkm_define_key("U", (FVOID_STAR) slmon_change_fs_unit, conf.map_g);
SLkm_define_key("=", (FVOID_STAR) slmon_increase_gauge, conf.map_g);
SLkm_define_key("-", (FVOID_STAR) slmon_decrease_gauge, conf.map_g);
SLkm_define_key("\033[A", (FVOID_STAR) slmon_fs_up, conf.map_g); /* up arrow */
SLkm_define_key("\033[B", (FVOID_STAR) slmon_fs_down, conf.map_g); /* down arrow */
/* network mode */
conf.map_n = SLang_create_keymap("slmon_n_map", km);
SLkm_define_key("u", (FVOID_STAR) slmon_change_net_unit, conf.map_n);
SLkm_define_key("n", (FVOID_STAR) slmon_add_iface, conf.map_n);
SLkm_define_key("d", (FVOID_STAR) slmon_del_iface, conf.map_n);
SLkm_define_key("\033[A", (FVOID_STAR) slmon_iface_up, conf.map_n); /* up arrow */
SLkm_define_key("\033[B", (FVOID_STAR) slmon_iface_down, conf.map_n); /* down arrow */
/* processes mode */
conf.map_p = SLang_create_keymap("slmon_p_map", km);
SLkm_define_key("A", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("a", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("S", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("s", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("D", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("d", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("F", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("f", (FVOID_STAR) slmon_sort_method, conf.map_p);
SLkm_define_key("k", (FVOID_STAR) slmon_proc_kill, conf.map_p);
SLkm_define_key("K", (FVOID_STAR) slmon_proc_sig, conf.map_p);
SLkm_define_key("\033[A", (FVOID_STAR) slmon_proc_up, conf.map_p); /* up arrow */
SLkm_define_key("\033[B", (FVOID_STAR) slmon_proc_down, conf.map_p); /* down arrow */
SLkm_define_key("\033[5~", (FVOID_STAR) slmon_proc_page_up, conf.map_p); /* page up */
SLkm_define_key("\033[6~", (FVOID_STAR) slmon_proc_page_down, conf.map_p); /* page down */
/* help mode */
conf.map_x = SLang_create_keymap("slmon_x_map", km);
SLkm_define_key(" ", (FVOID_STAR) slmon_help_exit, conf.map_x);
SLkm_define_key("^M", (FVOID_STAR) slmon_help_exit, conf.map_x);
}
void slmon_update_current_keymap(void)
{
switch (mode) {
case MODE_H:
conf.map = conf.map_h;
break;
case MODE_M:
conf.map = conf.map_g;
break;
case MODE_N:
conf.map = conf.map_n;
break;
case MODE_P:
conf.map = conf.map_p;
break;
case MODE_X:
conf.map = conf.map_x;
break;
}
}
/*
* Change mode
*/
void slmon_mode_help(void)
{
if (mode != MODE_X) {
last_mode = mode;
mode = MODE_X;
pos = 0;
redraw = 1;
slmon_update_current_keymap();
slmon_clear_screen(7);
}
}
void slmon_help_exit(void)
{
mode = last_mode;
pos = 0;
redraw = 1;
slmon_update_current_keymap();
slmon_clear_screen(7);
}
void slmon_mode_netw(void)
{
if (mode != MODE_N) {
mode = MODE_N;
pos = 0;
redraw = 1;
slmon_update_current_keymap();
slmon_clear_screen(7);
}
}
void slmon_mode_main(void)
{
if (mode != MODE_M) {
mode = MODE_M;
pos = 0;
redraw = 1;
slmon_update_current_keymap();
slmon_clear_screen(7);
}
}
void slmon_mode_hist(void)
{
if (mode != MODE_H) {
mode = MODE_H;
pos = 0;
redraw = 1;
slmon_update_current_keymap();
slmon_clear_screen(7);
}
}
void slmon_mode_proc(void)
{
if (mode != MODE_P) {
mode = MODE_P;
pos = 0;
redraw = 1;
slmon_update_current_keymap();
slmon_clear_screen(7);
}
}
/*
* Handle increase events
*/
/* FIXME: need to set some sane limits */
void slmon_increase_gauge(void)
{
conf.gauge_len++;
pos = 0;
redraw = 1;
SLsmg_cls();
}
void slmon_increase_cspace(void)
{
cspace++;
pos = 0;
redraw = 1;
SLsmg_cls();
}
void slmon_increase_rspace(void)
{
rspace++;
pos = 0;
redraw = 1;
SLsmg_cls();
}
/*
* Handle decrease events
*/
void slmon_decrease_gauge(void)
{
if (--conf.gauge_len < 1)
conf.gauge_len = 1;
pos = 0;
redraw = 1;
SLsmg_cls();
}
void slmon_decrease_cspace(void)
{
if (--cspace < 1)
cspace = 1;
pos = 0;
redraw = 1;
SLsmg_cls();
}
void slmon_decrease_rspace(void)
{
if (--rspace < 2)
rspace = 2;
pos = 0;
redraw = 1;
SLsmg_cls();
}
void slmon_fs_up(void)
{
if (conf.fs_first > 0)
conf.fs_first--;
}
void slmon_fs_down(void)
{
conf.fs_first++;
}
void slmon_sort_method(void)
{
char key = (char) SLang_Last_Key_Char;
switch(key) {
case 'a':
conf.sort_func = slmon_cmp_pid_desc;
break;
case 'A':
conf.sort_func = slmon_cmp_pid_asc;
break;
case 's':
conf.sort_func = slmon_cmp_pcpu_desc;
break;
case 'S':
conf.sort_func = slmon_cmp_pcpu_asc;
break;
case 'd':
conf.sort_func = slmon_cmp_pmem_desc;
break;
case 'D':
conf.sort_func = slmon_cmp_pmem_asc;
break;
case 'f':
conf.sort_func = slmon_cmp_user_desc;
break;
case 'F':
conf.sort_func = slmon_cmp_user_asc;
break;
}
}
void slmon_proc_up(void)
{
conf.proc_first--;
conf.proc_curr--;
}
void slmon_proc_down(void)
{
conf.proc_curr++;
if(conf.proc_curr >= SLtt_Screen_Rows - 6)
conf.proc_first++;
}
void slmon_proc_page_up(void)
{
conf.proc_first -= 10;
conf.proc_curr -= 10;
}
void slmon_proc_page_down(void)
{
conf.proc_first += 10;
conf.proc_curr += 10;
}
void slmon_proc_kill(void)
{
int pid;
pid = plist[conf.proc_curr].pid;
kill(pid, SIGTERM);
}
void slmon_proc_sig(void)
{
int pid, sig, pos = 0;
char key, tmp[10] = {0};
pid = plist[conf.proc_curr].pid;
while(1) {
slmon_status_msg("Kill process %d with signal: %s", pid, tmp);
key = slmon_getkey();
if(!isdigit(key))
break;
if(pos + 1 < 10)
tmp[pos++] = key;
}
/* If last pressed key wasn't return, it means that user entered
too long pid... So we'll exit just in case. */
if(key != '\r')
return;
sig = atoi(tmp);
kill(pid, sig);
}
/*
* Change memory units
*/
void slmon_change_mem_unit(void)
{
conf.mem++;
conf.mem %= 3;
}
/*
* Change filesystem units
*/
void slmon_change_fs_unit(void)
{
conf.fs++;
conf.fs %= 3;
}
/*
* Change network units
*/
void slmon_change_net_unit(void)
{
conf.net++;
conf.net %= 4;
}
/*
* Change current cpu
*/
void slmon_change_cpu(void)
{
if (mode == MODE_H) {
cur_cpu++;
cur_cpu %= conf.cpus + 1;
clear_histogram();
pos = 0;
redraw = 1;
}
}
/*
* Add network interface
*/
void slmon_add_iface(void)
{
int pos = 0;
char key, tmp[37] = {0};
do {
slmon_status_msg("Add interface: %s", tmp);
key = slmon_getkey();
tmp[pos++] = key;
} while(pos < 36 && key != '\r');
/* If last pressed key wasn't enter, it means that user entered
too long string. We won't try to add this interface then. */
if(key != '\r')
return;
tmp[pos - 1] = '\0'; /* get rid of that enter */
slmon_net_append(conf.iface, tmp);
}
/*
* Delete network interface
*/
void slmon_del_iface(void)
{
int pos = 0;
char key, tmp[37] = {0};
do {
slmon_status_msg("Delete interface: %s", tmp);
key = slmon_getkey();
tmp[pos++] = key;
} while(pos < 36 && key != '\r');
/* If last pressed key wasn't enter, it means that user entered
too long string. We won't try to add this interface then. */
if(key != '\r')
return;
tmp[pos - 1] = '\0'; /* get rid of that enter */
slmon_net_remove(conf.iface, tmp);
}
/*
* I scroll up...
*/
void slmon_iface_up(void)
{
if(conf.iface_first > 0)
conf.iface_first--;
}
/*
* I scroll down...
*/
void slmon_iface_down(void)
{
if(conf.iface_first < conf.iface_count)
conf.iface_first++;
}
/*
* Simple wrapper to SLang_getkey()
*/
int slmon_getkey(void)
{
int ch;
ch = SLang_getkey();
return ch;
}
/*
* Print version and copying info to stdout
*/
void slmon_print_version(void)
{
printf("%s %s\n", PACKAGE, VERSION);
printf("Copyright (C) 2000, 2001, 2002 - Krzysztof Luks <m00se@iq.pl>\n\n");
printf
(" This program is free software; you can redistribute it and/or modify\n");
printf
(" it under the terms of the GNU General Public License as published by\n");
printf
(" the Free Software Foundation; either version 2 of the License, or\n");
printf(" (at your option) any later version.\n\n");
printf
(" This program is distributed in the hope that it will be useful,\n");
printf
(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
printf
(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
printf(" GNU General Public License for more details.\n\n");
printf
(" You should have received a copy of the GNU General Public License\n");
printf
(" along with this program; if not, write to the Free Software\n");
printf
(" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
}
#ifdef HAVE_GETOPT_LONG
/*
* Brief usage information
*/
void slmon_getopt_help(void)
{
printf("Usage: slmon [OPTION...]\n");
printf
(" -v, --version Display version and copying information\n");
printf(" -h, --help This help message\n");
printf(" -f, --fs-unit=[kmg] Specify filesystem usage unit\n");
printf(" -m, --mem-unit=[bkmg] Specify memory usage unit\n");
printf(" -n, --net-unit=[bkmg] Specify network traffic unit\n");
printf(" b=bytes, k=kbytes, m=mbytes, g=gbytes\n");
printf(" -d, --mode=[mpnh] Start in mode 'M'\n");
printf(" m=main, p=process, n=network, h=histogram\n");
printf(" -u, --update=<seconds> Specify update interval in seconds\n");
printf("\n");
}
#endif /* !HAVE_GETOPT_LONG */
syntax highlighted by Code2HTML, v. 0.9.1