On Sun, Jul 28, 2013 at 06:11:39PM +0200, Markus Teich wrote: > Am 2013-07-27 18:27, schrieb Martti Kühne: > >On Mon, Jul 22, 2013 at 3:17 PM, Markus Teich > ><[email protected]> wrote: > >> > >>rx_now=0 > >>tx_now=0 > >>for i in /sys/class/net/*; do > >> if [[ -d "$i" && ${i##*/} != "lo" ]]; then > >> if [[ -f "$i/statistics/rx_bytes" ]]; then > >> rx_now=($rx_now+`cat $i/statistics/rx_bytes`) > >> fi > >> if [[ -f "$i/statistics/tx_bytes" ]]; then > >> tx_now=($tx_now+`cat $i/statistics/tx_bytes`) > >> fi > >> fi > >>done > >>let rx_rate=($rx_now-$rx_old) > >>let tx_rate=($tx_now-$tx_old) > >> > >Might I ask what shell dialect is that written in? O_o > > Bash patched together with some stackoverflow answers. > It probably is not beautiful, but it works for me until I finally have > the time to write it in C. :/
I included some changes suggested by Markus in a rewrite of the netusage functions for dwmstatus (attached; including an adapted dwmstatus-Makefile for convenience). Comments and criticism is welcome. I will try to push a change request to the suckless sites git repo if nobody threats to neuter my hamster over the code I wrote... Cheers, Silvan
#define _BSD_SOURCE
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <X11/Xlib.h>
char *tzargentina = "America/Buenos_Aires";
char *tzutc = "UTC";
char *tzberlin = "Europe/Berlin";
static Display *dpy;
char *
smprintf(char *fmt, ...)
{
va_list fmtargs;
char *ret;
int len;
va_start(fmtargs, fmt);
len = vsnprintf(NULL, 0, fmt, fmtargs);
va_end(fmtargs);
ret = malloc(++len);
if (ret == NULL) {
perror("malloc");
exit(1);
}
va_start(fmtargs, fmt);
vsnprintf(ret, len, fmt, fmtargs);
va_end(fmtargs);
return ret;
}
void
settz(char *tzname)
{
setenv("TZ", tzname, 1);
}
int
parse_netdev(unsigned long long int *receivedabs, unsigned long long int *sentabs)
{
char buf[255];
char *datastart;
static int bufsize;
int rval;
FILE *devfd;
unsigned long long int receivedacc, sentacc;
bufsize = 255;
devfd = fopen("/proc/net/dev", "r");
rval = 1;
// Ignore the first two lines of the file
fgets(buf, bufsize, devfd);
fgets(buf, bufsize, devfd);
while (fgets(buf, bufsize, devfd)) {
if ((datastart = strstr(buf, "lo:")) == NULL) {
datastart = strstr(buf, ":");
// With thanks to the conky project at http://conky.sourceforge.net/
sscanf(datastart + 1, "%llu %*d %*d %*d %*d %*d %*d %*d %llu",\
&receivedacc, &sentacc);
*receivedabs += receivedacc;
*sentabs += sentacc;
rval = 0;
}
}
fclose(devfd);
return rval;
}
void
calculate_speed(char *speedstr, unsigned long long int newval, unsigned long long int oldval)
{
double speed;
speed = (newval - oldval) / 1024.0;
if (speed > 1024.0) {
speed /= 1024.0;
sprintf(speedstr, "%.3f MB/s", speed);
} else {
sprintf(speedstr, "%.2f KB/s", speed);
}
}
char *
get_netusage(unsigned long long int *rec, unsigned long long int *sent)
{
unsigned long long int newrec, newsent;
newrec = newsent = 0;
char downspeedstr[15], upspeedstr[15];
static char retstr[42];
int retval;
retval = parse_netdev(&newrec, &newsent);
if (retval) {
fprintf(stdout, "Error when parsing /proc/net/dev file.\n");
exit(1);
}
calculate_speed(downspeedstr, newrec, *rec);
calculate_speed(upspeedstr, newsent, *sent);
sprintf(retstr, "down: %s up: %s", downspeedstr, upspeedstr);
*rec = newrec;
*sent = newsent;
return retstr;
}
char *
mktimes(char *fmt, char *tzname)
{
char buf[129];
time_t tim;
struct tm *timtm;
bzero(buf, sizeof(buf));
settz(tzname);
tim = time(NULL);
timtm = localtime(&tim);
if (timtm == NULL) {
perror("localtime");
exit(1);
}
if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) {
fprintf(stderr, "strftime == 0\n");
exit(1);
}
return smprintf("%s", buf);
}
void
setstatus(char *str)
{
XStoreName(dpy, DefaultRootWindow(dpy), str);
XSync(dpy, False);
}
char *
loadavg(void)
{
double avgs[3];
if (getloadavg(avgs, 3) < 0) {
perror("getloadavg");
exit(1);
}
return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]);
}
int
main(void)
{
char *status;
char *avgs;
char *tmar;
char *tmutc;
char *tmbln;
char *netstats;
static unsigned long long int rec, sent;
if (!(dpy = XOpenDisplay(NULL))) {
fprintf(stderr, "dwmstatus: cannot open display.\n");
return 1;
}
parse_netdev(&rec, &sent);
for (;;sleep(1)) {
avgs = loadavg();
tmar = mktimes("%H:%M", tzargentina);
tmutc = mktimes("%H:%M", tzutc);
tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin);
netstats = get_netusage(&rec, &sent);
status = smprintf("[L: %s|N: %s|A: %s|U: %s|%s]",
avgs, netstats, tmar, tmutc, tmbln);
setstatus(status);
free(avgs);
free(tmar);
free(tmutc);
free(tmbln);
free(status);
}
XCloseDisplay(dpy);
return 0;
}
# See LICENSE file for copyright and license details.
include config.mk
SRC = ${NAME}.c
OBJ = ${SRC:.c=.o}
all: options ${NAME}
options:
@echo ${NAME} build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.mk
${NAME}: ${OBJ}
@echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
@echo cleaning
@rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz
dist: clean
@echo creating dist tarball
@mkdir -p ${NAME}-${VERSION}
@cp -R Makefile config.mk LICENSE \
${SRC} ${NAME}-${VERSION}
@tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION}
@gzip ${NAME}-${VERSION}.tar
@rm -rf ${NAME}-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f ${NAME} ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
.PHONY: all options clean dist install uninstall
NAME = dwmstatus-netusage
VERSION = 1.2
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# includes and libs
INCS = -I. -I/usr/include -I${X11INC}
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\"
CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
#CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -g ${LIBS}
#LDFLAGS = -s ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
# compiler and linker
CC = cc
pgp0n5W3dEW9R.pgp
Description: PGP signature
