/* * 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/24 19:38:35 $ * $Revision: 1.3 $ * */ #include "stat.h" /* * Calculate count'th cpu usage. */ int cpu_calc(int count) { int value; double t = 0, i = 0; glibtop_cpu cpu; glibtop_get_cpu(&cpu); if (count == 0) { t = ((unsigned long) cpu.total) ? ((double) cpu.total) : 1.0; i = ((unsigned long) cpu.idle) ? ((double) cpu.idle) : 1.0; } else { t = ((unsigned long) cpu.xcpu_total[count - 1]) ? ((double) cpu. xcpu_total[count - 1]) : 1.0; i = ((unsigned long) cpu. xcpu_idle[count - 1]) ? ((double) cpu.xcpu_idle[count - 1]) : 1.0; } t /= conf.freq; i /= conf.freq; value = (int) ((t - i - l[count].totallast) * 100) / ((t - i - l[count].totallast) + (i - l[count].idlelast)); if (value > 100) /* FIXME: is this really needed? */ value = 100; l[count].totallast = t - i; l[count].idlelast = i; return value; } /* * Get system uptime */ void get_uptime(int *days, int *hours, int *minutes, int *seconds) { double total; glibtop_uptime up; glibtop_get_uptime(&up); total = up.uptime; *seconds = (int) total % 60; total /= 60.0; *minutes = (int) total % 60; total /= 60.0; *hours = (int) total % 24; total /= 24.0; *days = (int) total; } /* * Count users logged in on the system */ int users(void) { int count = 0; #ifdef HAVE_UTMP struct utmp *ut; setutent(); while ((ut = getutent()) != NULL) if (ut->ut_type == USER_PROCESS) count++; endutent(); #endif /* !HAVE_UTMP */ return count; } /* * Make cption for graph etc. Return pointer to that string */ char *cpu_caption(int num) { char *t = calloc(20, 1); if (num == 0) { strcpy(t, "Total CPU usage"); } else { sprintf(t, "CPU%d usage", num); } return t; } slmon_proc *slmon_get_proclist(int *len) { slmon_proc *result = NULL; glibtop_proclist plist; glibtop_proc_state pstate; glibtop_proc_mem pmem; glibtop_proc_args pargs; glibtop_proc_time ptime; glibtop_uptime upt; glibtop_mem mem; struct passwd *pwd; unsigned *pids; int i, j, num = 0, tmp; float p_total, p_time; char *args1; /* we can't get process's controlling tty singe libgtop doesn't support * this :( */ pids = glibtop_get_proclist(&plist, 0, 0); if(pids) { glibtop_get_uptime(&upt); glibtop_get_mem(&mem); num = plist.number; result = (slmon_proc *) malloc(num * sizeof(slmon_proc)); for(i = 0; i < num; i++) { result[i].pid = pids[i]; glibtop_get_proc_state(&pstate, pids[i]); glibtop_get_proc_mem(&pmem, pids[i]); glibtop_get_proc_time(&ptime, pids[i]); p_time = (float) (upt.uptime * 100 - ptime.start_time) / conf.freq; p_total = (float) (ptime.utime + ptime.stime) / 10.0; result[i].pcpu = p_total * 100 / p_time; result[i].pmem = pmem.rss * 1000 / mem.total; result[i].state = pstate.state; args1 = glibtop_get_proc_args(&pargs, pids[i], 0); if (args1) { result[i].args = (char *) malloc(pargs.size + 1); memcpy(result[i].args, args1, pargs.size); result[i].args[pargs.size] = '\0'; for (j = 0; j < pargs.size; j++) if (result[i].args[j] == '\0') result[i].args[j] = ' '; g_free(args1); } else { tmp = strlen(pstate.cmd) * sizeof(char); result[i].args = (char *) malloc(tmp+1); result[i].args = calloc(tmp + 1, 1); } result[i].vsz = (int) pmem.vsize >> 10; result[i].rss = (int) pmem.rss >> 10; pwd = getpwuid(pstate.uid); tmp = strlen(pwd->pw_name) * sizeof(char); result[i].user = (char *) malloc(tmp + 1); result[i].user = calloc(tmp + 1, 1); } g_free(pids); } memcpy(len, &num, sizeof(int)); return result; } int slmon_cmp_pcpu_asc(const void *one, const void *two) { slmon_proc *tmp1, *tmp2; tmp1 = (slmon_proc *) one; tmp2 = (slmon_proc *) two; return tmp1->pcpu - tmp2->pcpu; } int slmon_cmp_pcpu_desc(const void *one, const void *two) { return slmon_cmp_pcpu_asc(two, one); } int slmon_cmp_pmem_asc(const void *one, const void *two) { slmon_proc *tmp1, *tmp2; tmp1 = (slmon_proc *) one; tmp2 = (slmon_proc *) two; return tmp1->pmem - tmp2->pmem; } int slmon_cmp_pmem_desc(const void *one, const void *two) { return slmon_cmp_pmem_asc(two, one); } int slmon_cmp_pid_asc(const void *one, const void *two) { /* this function is pretty useless since glibtop_get_proclist() already returns processes sorted by pid */ slmon_proc *tmp1, *tmp2; tmp1 = (slmon_proc *) one; tmp2 = (slmon_proc *) two; return tmp1->pid - tmp2->pid; } int slmon_cmp_pid_desc(const void *one, const void *two) { /* this one isn't useless though ;) */ return slmon_cmp_pid_asc(two, one); } int slmon_cmp_user_asc(const void *one, const void *two) { slmon_proc *tmp1, *tmp2; tmp1 = (slmon_proc *) one; tmp2 = (slmon_proc *) two; return strcmp(tmp1->user , tmp2->user); } int slmon_cmp_user_desc(const void *one, const void *two) { return slmon_cmp_user_asc(two, one); } void slmon_update_net_throughput(char *name, long in, long out) { struct slmon_net *tmp; const size_t len = strlen(name); tmp = conf.iface; while(tmp != NULL) { if(!strncmp(name, tmp->name, len)) { tmp->last_in = in; tmp->last_out = out; return; } tmp = tmp->next; } } struct slmon_net *slmon_net_new(void) { struct slmon_net *tmp; tmp = (struct slmon_net *) malloc(sizeof(struct slmon_net)); tmp->name = NULL; tmp->next = tmp->prev = NULL; return tmp; } struct slmon_net *slmon_net_append(struct slmon_net *l, char *name) { struct slmon_net *j, *tmp; int len; tmp = slmon_net_new(); len = strlen(name); tmp->name = calloc(len + 1, 1); memcpy(tmp->name, name, len); tmp->last_in = tmp->last_out = 0; if(l != NULL) { j = (struct slmon_net *) slmon_net_find(l, name); if(j != NULL) { slmon_net_free(tmp); return l; } j = (struct slmon_net *) slmon_net_last(l); j->next = tmp; tmp->prev = j; conf.iface_count++; return l; } else return tmp; } struct slmon_net *slmon_net_remove(struct slmon_net * l, char *name) { struct slmon_net *j, *tmp; j = l; if(!strcmp(j->name, name)) { l = j->next; l->prev = NULL; free(j); conf.iface_count--; return l; } while(j->next != NULL) { j = j->next; if(!strcmp(j->name, name)) { j->prev->next = j->next; j->next->prev = j->prev; free(j); break; } } } void slmon_net_free(struct slmon_net * l) { struct slmon_net *j; j = l->next; free(l); while(j != NULL) { j = l->next; free(l); } } struct slmon_net *slmon_net_last(struct slmon_net *l) { struct slmon_net *tmp = l; if(tmp != NULL) while(tmp->next != NULL) tmp = tmp->next; return tmp; } struct slmon_net *slmon_net_find(struct slmon_net *l, char *name) { struct slmon_net *j; j = l; while(j != NULL) { if(!strcmp(name, j->name)) break; j = j->next; } return j; }