/* * slmon * * Copyright (C) 2000, 2001, 2002 Krzysztof Luks * * This program is distributed under the GPL license. For details see * COPYING text. * * Author: Krzysztof Luks * * $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 \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= Specify update interval in seconds\n"); printf("\n"); } #endif /* !HAVE_GETOPT_LONG */