/*
* 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/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;
}
syntax highlighted by Code2HTML, v. 0.9.1