Index: cpusage/cpusage.1
===================================================================
--- cpusage/cpusage.1	(revision 0)
+++ cpusage/cpusage.1	(revision 0)
@@ -0,0 +1,127 @@
+.TH CPUSAGE 1 "20 March 2006"
+
+.SH NAME
+cpusage \- shows CPU usage of the system
+
+.SH SYNOPSIS
+.na
+.B cpusage
+[ 
+.B \-hos 
+] [
+.B \-a | \-l 
+.I limit
+]
+
+.SH AVAILABILITY
+
+As source for Linux and FreeBSD. Tested with Linux 2.4 & 2.6 and FreeBSD 5.
+But adaption to other 
+.SM UNIX's 
+should only be a problem of getting the tics
+counters from the kernel.
+
+Download from: 
+.br 
+http://www.net.informatik.tu-muenchen.de/~schneifa/sources/
+
+.SH DESCRIPTION
+
+This tool reads out the tics counter of the operating system and
+calculates the Percentages spend in each CPU_STATE. This is done twice
+per second. The output is send to standard out. Supplementary the
+minimum, maximum and average percentages are displayed. The recording
+for the average measuring can be limited to start only if the idle value
+drops under a certain limit (set with the \fB-l\fR \fIlimit\fR option) 
+and stops if the idle value returns over that limit again.
+
+The program will execute until a SIGINT is received. This can be done by
+pressing Strg+C in the corresponding shell or by invoking 
+.LP
+.RS
+.B kill -SIGINT 
+.I PID
+.RE
+.LP
+where
+.I PID 
+is the process ID of 
+.B cpusage.
+If your system does not allow to use kill in the described manner, please
+refer to
+.BR kill (1)
+for details.
+
+.SH OPTIONS
+
+.TP 
+.B \-a
+build average over the whole time, same as \fB-l\fR 100
+.TP
+.B \-h
+prints the help
+.TP
+.B \-l \fIlimit\fR
+set limits for average usage snapping
+.TP
+.B \-o
+format the output machine readable (see OUTPUT FORMAT for details)
+.TP
+.B \-s
+run only once and exit. In addition, the summary is not calculated and
+printed.
+
+.SH OUTPUT FORMAT
+
+The output depends on the available information delivered from the kernel
+this can be differ between operating system and even between different
+versions of operating systems (e.g.: Linux 2.4.x and Linux 2.6.x). The
+difference is in the fields the tics are split:
+
+.TP
+.B Linux 2.4.x
+.I user nice system idle
+are available (4 fields)
+.TP
+.B Linux 2.6.x
+.I user nice system idle iowait irq soft_irq
+are available (7 fields)
+.TP 
+.B FreeBSD
+.I user nice system idle interrupt
+are available (5 fields)
+
+The field will be printed in the upon mentioned order. For the example
+outputs FreeBSD was chosen.
+
+.SS Human readable (Default)
+
+Every line consists of the fields each with name:value pairs:
+
+user:   3.0%, nice:   0.0%, system:   0.7%, idle:  68.7%, interrupt: 27.6%,
+
+
+.SS Machine readable (set via the \fB-o\fR option)
+In contrast to the previous output format, only the values are shown
+without the "%" sing:
+
+0.0:0.0:0.0:70.7:29.3
+
+.SH SEE ALSO
+.BR top (1), 
+.BR uptime (1), 
+.BR kill (1)
+
+.SH AUTHOR
+
+Fabian Schneider <fabian@net.in.tum.de>
+
+.SH BUGS
+Please send problems, bugs, questions, desirable enhancements, 
+source code contributions, etc. to:
+.LP
+.RS
+fabian@net.in.tum.de
+.RE
+.LP
+
Index: cpusage/CHANGES
===================================================================
--- cpusage/CHANGES	(revision 0)
+++ cpusage/CHANGES	(revision 0)
@@ -0,0 +1,12 @@
+v0.21 (14 March 2007)
+    * compatibility with cross compile
+
+v0.2 (23 March 2006)
+    * included Patch from Stelios Koroneos <stelios@stelioscellar.com>
+      to enable a single measurement without summary
+    * simplified installation, modified Makefile (man page support)
+    * added a man page
+    * added this ChangeLog
+
+Birth (20 March 2006)
+    * Repository created, from the sources of my diploma thesis.
Index: cpusage/cpusage.c
===================================================================
--- cpusage/cpusage.c	(revision 0)
+++ cpusage/cpusage.c	(revision 0)
@@ -0,0 +1,323 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#else
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
+#ifdef __FreeBSD__
+static void getsysctl(char *, void *, size_t);
+#define CPUSTATES 5
+#define IDLEI 3
+char *cpustatenames[] = {
+        "user", "nice", "system", "idle", "interrupt", NULL
+};
+#endif
+
+#ifdef __Linux24__
+#define CPUSTATES 4
+#define IDLEI 3
+char *cpustatenames[] = {
+        "user", "nice", "system", "idle",  NULL
+};
+#endif
+
+#ifdef __Linux26__
+#define CPUSTATES 7
+#define IDLEI 3
+/* long names:
+ * user - nice - system - idle - iowait - irq - soft irq */
+char *cpustatenames[] = {
+        "us", "ni", "sy", "id", "io", "iq", "siq", NULL
+};
+#endif
+
+#define LIMIT 95
+
+static const char usage[] = 
+    "\n usage: cpusage [ −hos ] [ −a | −l limit ]  \n";
+
+
+static float cpu_perc[CPUSTATES];
+static float cpu_max[CPUSTATES];
+static float cpu_min[CPUSTATES];
+
+int output;
+
+int breakloop;
+
+#ifdef __FreeBSD__
+static void getsysctl (char *name, void *ptr, size_t len) {
+    size_t nlen = len;
+    long save;
+    
+    if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
+            fprintf(stderr, "cpusage: sysctl(%s...) failed: %s\n", name, 
+		strerror(errno));
+	    exit(1);
+    }
+    if (nlen != len) {
+	    fprintf(stderr, "cpusage: sysctl(%s...) expected %lu, got %lu\n",
+		name, (unsigned long)len, (unsigned long)nlen); 
+	    exit(1);
+    }
+   
+    /* swapping idle and interrupt to look like linux */
+    save = ((long*) ptr)[4];
+    ((long*) ptr)[4] = ((long*) ptr)[3];
+    ((long*) ptr)[3] = save;
+}
+#else
+void getSysinfo(unsigned long *ptr, size_t size)
+{
+    char buffer[4096];
+    int fd, len, j;
+	    
+    for (j = 0; j<size; j++)
+	ptr[j]=0;
+
+    fd = open("/proc/stat", O_RDONLY);
+    if(fd<=0)
+	fprintf(stderr, "cpusage: cannot open /proc/stat: ");
+    
+    len = read(fd, buffer, sizeof(buffer)-1);
+    close(fd);
+    buffer[len] = '\0';
+
+#ifdef __Linux26__
+    if ( sscanf(buffer, "cpu %ld %ld %ld %ld %ld %ld %ld", &ptr[0], 
+	    &ptr[1], &ptr[2], &ptr[3], &ptr[4], &ptr[5], &ptr[6]) != 7 ) {
+	fprintf(stderr, "wrong /proc/stat format");
+    }
+#else
+    if ( sscanf(buffer, "cpu %ld %ld %ld %ld", 
+		&ptr[0], &ptr[1], &ptr[2], &ptr[3]) != 4) {
+	fprintf(stderr, "wrong /proc/stat format");
+    }
+#endif
+	    
+}
+#endif
+
+long perc(int cpustates, long *cp_time, long *cp_old, long *cp_diff) {
+
+    int i = 0;
+    long total = 0;
+    
+    for ( i = 0; i < cpustates; i++ ) {
+	cp_diff[i] = cp_time[i] - cp_old[i];
+	total += cp_diff[i];
+    }
+    
+    for ( i = 0; i < cpustates; i++) {
+	cpu_perc[i] = ((float)cp_diff[i]*100.0 / total);
+	/* new max ? */
+	if ( cpu_perc[i] > cpu_max[i] )
+	    cpu_max[i] = cpu_perc[i];
+	/* new min ? */
+	if ( cpu_perc[i] < cpu_min[i] )
+	    cpu_min[i] = cpu_perc[i];
+    }
+   
+    return total;
+}
+
+void print_perc(float *perc, const char *head){
+    int i;
+   
+    /* human readable */
+    if ( (output == 0) && (head != ""))
+	printf("%s: ", head);
+
+    /* machine readable */
+    if ( (output == 1) && (head != ""))
+	printf("%s:", head);
+   
+    if ( output == 0 )
+	printf("%s: %5.1f%%, ", cpustatenames[0], perc[0]);
+    else 
+	printf("%.1f", perc[0]);
+    
+    /* print out calculated information in percentages */
+    for ( i = 1; i < CPUSTATES; i++) {
+	if ( output == 0 )
+	    printf("%s: %5.1f%%, ", cpustatenames[i], perc[i]);
+	else 
+	    printf(":%.1f", perc[i]);
+    }
+    printf("\n");
+}
+
+/* to catch Strg+C when looping */
+void loop_term_handler (int signum) {
+    breakloop = 1;
+}
+
+int main(int argc, char** argv) {
+
+    int i,c,limit;
+    int runonce;  /* run just once and exit */
+    int avg; /* is avg measurement allready running */ 
+    int avg_run; /* did we allready had an avg measurement */
+    static long cp_time1[CPUSTATES];
+    static long cp_time2[CPUSTATES];
+    static long cp_avg_start[CPUSTATES];
+    static long cp_avg_stop[CPUSTATES];
+    static long cp_diff[CPUSTATES];
+
+    struct sigaction sigold, signew;
+    
+    long *old = cp_time2;
+    long *new = cp_time1;
+
+    long total;
+    limit = LIMIT;
+    output = 0; /* 0: human readable; 1: machine readable */
+    runonce = 0; /* 0: run continuesly; 1: run once */
+
+    /* reading commandline options */
+    while (1) {
+	c = getopt(argc, argv, "saohl:");
+	
+	if (c == -1){
+	    break;
+        }
+
+	switch(c){
+        /*run once and exit */
+        case 's':
+           runonce = 1;             
+           break;
+	/* use avg from begin to end -> same as "-l 100" */
+	case 'a':
+	    limit = 100; 
+	    break;
+	case 'o':
+	    output = 1; /* machine readable */ 
+	    break;
+	/* print usage */
+	case 'h':
+	    fprintf(stderr, "cpusage: %s", usage);
+	    exit(0);
+	    break;
+	/* set limit */
+	case 'l':
+	    if ( !(sscanf(optarg, "%d", &limit) == 1) ) {
+		fprintf(stderr, "cpusage: option for -l should be integer (is %s)", optarg); 
+		exit(1);
+	    }
+	    break;
+	}
+    }
+    
+    
+    breakloop = 0;
+
+    for (i=0; i < CPUSTATES; i++){
+	cpu_max[i] = 0;
+	cpu_min[i] = 100;
+    }
+    
+    /* get information */
+#ifdef __FreeBSD__
+    getsysctl("kern.cp_time", new, sizeof(cp_time1));
+#else
+    getSysinfo((unsigned long*)new, CPUSTATES);
+#endif
+
+    /* catch Strg+C when capturing to call pcap_breakloop() */
+    memset(&signew, 0, sizeof(signew));
+    signew.sa_handler = loop_term_handler;
+    if (sigaction(SIGINT, &signew, &sigold) < 0 ){
+	fprintf(stderr, "Could not set signal handler -> exiting");
+    }
+   
+    avg = 0;
+    avg_run = 0;
+    
+    if ( runonce ) {
+        breakloop=1;
+    }
+
+    while(1) {
+	usleep( 500000 );
+
+	if ( new == cp_time1 ) {
+	    new = cp_time2;
+	    old = cp_time1;
+	} else{
+	    new = cp_time1;
+	    old = cp_time2;
+	}
+	
+	/* get information again */
+#ifdef __FreeBSD__
+	getsysctl("kern.cp_time", new, sizeof(cp_time1));
+#else
+	getSysinfo((unsigned long*)new, CPUSTATES);
+#endif
+    
+	/* convert cp_time counts to percentages */
+	total = perc(CPUSTATES, new, old, cp_diff); 
+
+	/* check for avg measurement start */
+	if ( !avg_run && !avg && (cpu_perc[IDLEI] <= limit) ){
+	    avg = 1;
+	    for ( i = 0; i < CPUSTATES; i++ )
+		cp_avg_start[i] = new[i];
+	}
+
+	/* check for avg measurement stop */
+	if ( !avg_run && avg && (cpu_perc[IDLEI] > limit) ){
+	    avg = 0;
+	    for ( i = 0; i < CPUSTATES; i++ )
+		cp_avg_stop[i] = new[i];
+	    avg_run = 1;
+	}
+
+	print_perc(cpu_perc, ""); 
+
+	if (breakloop) {
+	    if (avg) {
+		avg = 0;
+		for ( i = 0; i < CPUSTATES; i++ )
+		    cp_avg_stop[i] = new[i];
+	    }
+	    break;
+	}
+    }
+  
+    /* Set default behaviour when loop is done */
+    if (sigaction(SIGINT, &sigold, &signew) < 0 ){
+	fprintf(stderr, "Could not restore signal handler -> exiting");
+    }
+
+    if ( ! runonce ) {    
+	printf("---Summary----\n");
+	
+	print_perc(cpu_min, "Min");
+
+	print_perc(cpu_max, "Max");
+
+	perc(CPUSTATES, cp_avg_start, cp_avg_stop, cp_diff); 
+
+	print_perc(cpu_perc, "Avg");
+    }
+    
+    return 0;
+}
+
+
+
Index: cpusage/Makefile
===================================================================
--- cpusage/Makefile	(revision 0)
+++ cpusage/Makefile	(revision 0)
@@ -0,0 +1,71 @@
+#LIBS = -lm -L/usr/local/lib -lpcap
+#CFLAGS = -I/usr/local/include
+
+prefix = /usr/local
+
+bindir = ${prefix}/bin
+mandir = ${prefix}/man
+
+#
+# You shouldn't need to edit anything below here.
+#
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+
+OS = $(shell uname -s)
+OS_VER = $(shell uname -r | cut -d. -f1-2)
+
+ifeq ($(OS), FreeBSD)
+    #the following line produces a Warning when running gmake
+    #DEFS = -D__FreeBSD__
+    DEFS := $(nullstring) 
+else
+ifeq ($(OS), Linux)
+    ifeq ($(OS_VER), 2.6)
+	DEFS = -D__Linux26__ -D_BSD_SOURCE=1
+#	CFLAGS += -std=c99
+    endif
+    ifeq ($(OS_VER), 2.4)
+	DEFS = -D__Linux24__ -D_BSD_SOURCE=1
+#	CFLAGS += -std=c99
+    endif
+endif
+endif
+
+.PHONY: clean all manps
+PN = cpusage
+EXE_DIR = DIR/$(PN)/$(PN)
+
+all: $(PN)
+
+$(PN).o: $(PN).c
+ifdef DEFS
+	$(CC) -g -Wall $(CFLAGS) $(DEFS) -c $(PN).c
+else	
+	echo "OS or Version not supported ($(OS) $(OS_VER))"
+endif
+
+$(PN): $(PN).o
+	$(CC) -g $(DEFS) -o $(PN) $(PN).o $(LIBS) 
+
+install: $(PN)  $(PN).1
+	[ -d $(bindir) ] || \
+	    (mkdir -p $(bindir); chmod 755 $(bindir))
+	$(INSTALL_PROGRAM) $(PN) $(bindir)/$(PN)	
+	
+	[ -d $(mandir)/man1 ] || \
+             (mkdir -p $(mandir)/man1; chmod 755 $(mandir)/man1)
+	$(INSTALL_DATA) $(PN).1 $(mandir)/man1/$(PN).1
+		     
+	$(MAKE) clean
+
+(PN).1.gz: $(PN).1
+	groff -t -e -mandoc -Tps $< > $@
+
+manps: $(PN).1.gz
+
+
+clean:  
+	rm -f $(PN).o $(PN)
Index: cpusage/README
===================================================================
--- cpusage/README	(revision 0)
+++ cpusage/README	(revision 0)
@@ -0,0 +1,35 @@
+Building and installing:
+------------------------
+
+    a) download the tarball:
+	http://www.net.in.tum.de/~schneifa/sources/cpusage-0.1.tar.gz
+    
+    b) unpack the tarball:
+	tar -xvzf cpusage-0.1.tar.gz
+
+    c) set the install path:
+	cd cpusage-0.1
+	vim Makefile
+	    - edit the line with the prefix Variable:
+		prefix = /usr/local
+	      to a path which suits you
+    
+    d) build the program:
+	make (please use GNU make if available)
+
+    e) install the program:
+	make install
+
+    f) See man page for the usage and options
+
+Problems: 
+---------
+
+    If you are experiencing problems feel free to change the code or
+    send me an email to fabian_at_net.in.tum.de (substitude "_at_" by
+    the "@" sign).
+
+
+Happy monitoring
+
+20.03.2005 Fabian Schneider 
Index: scripts/graphs.sh
===================================================================
--- scripts/graphs.sh	(revision 821)
+++ scripts/graphs.sh	(working copy)
@@ -11,7 +11,7 @@
 echo `date`
 case $1 in
 	cpu)
-		var="`head -n 1 /proc/stat`"
+		var="`cpusage -s`"
 		echo "$var"
 		;;
 	wan)
Index: Makefile
===================================================================
--- Makefile	(revision 821)
+++ Makefile	(working copy)
@@ -102,7 +102,7 @@
 HTTPSETUPURL:=http://$(HTTPHOST):$(HTTPBINDPORT)/$(HTTPPREFIX)/static/config/setup/install.html
 HTTPSETUPURL:=http://localhost:$(HTTPBINDPORT)/$(HTTPPREFIX)/static/config/setup/install.html
 
-SUBDIRS:=tools
+SUBDIRS:=tools cpusage
 SUBDIRS_CLEAN:=$(SUBDIRS:%=%-clean)
 SUBDIRS_INSTALL:=$(SUBDIRS:%=%-install)
 
