diff --git a/.travis.yml b/.travis.yml index d51d2186..0bfeb0ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_install: - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then brew install gd sqlite check ; fi script: - - CFLAGS='-Wall -Wextra -g' ./configure && make check ; if [ "$?" -ne "0" ]; then egrep '^Running suite' -A1000 test-suite.log ; false ; else ./vnstatd --version ; fi + - CFLAGS='-Wall -Wextra -g' ./configure && make check ; if [ "$?" -ne "0" ]; then egrep '^Running suite' -A1000 test-suite.log ; false ; else ./vnstat --version ; fi notifications: email: diff --git a/Makefile.am b/Makefile.am index 74a24728..58359c5e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,13 +4,24 @@ dist_man_MANS = man/vnstat.1 man/vnstat.conf.5 man/vnstatd.1 man/vnstati.1 EXTRA_DIST = cfg examples UPGRADE CHANGES FAQ INSTALL_BSD INSTALL_OSX UNINSTALL -#bin_PROGRAMS = vnstat +bin_PROGRAMS = vnstat sbin_PROGRAMS = vnstatd #if HAVE_LIBGD #bin_PROGRAMS += vnstati #endif #vnstati_LDADD = $(IMAGELIBS) +vnstat_SOURCES = src/vnstat.c src/vnstat.h \ + src/ifinfo.c src/ifinfo.h \ + src/dbsql.c src/dbsql.h \ + src/common.c src/common.h \ + src/misc.c src/misc.h \ + src/cfg.c src/cfg.h \ + src/ibw.c src/ibw.h \ + src/fs.c src/fs.h \ + src/id.c src/id.h \ + src/traffic.c src/traffic.h + #vnstat_SOURCES = src/vnstat.c src/vnstat.h \ # src/ifinfo.c src/ifinfo.h \ # src/dbsql.c src/dbsql.h \ diff --git a/Makefile.in b/Makefile.in index af9716e0..fb298744 100644 --- a/Makefile.in +++ b/Makefile.in @@ -78,6 +78,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +bin_PROGRAMS = vnstat$(EXEEXT) sbin_PROGRAMS = vnstatd$(EXEEXT) @HAVE_CHECK_TRUE@TESTS = check_vnstat$(EXEEXT) @HAVE_CHECK_TRUE@check_PROGRAMS = check_vnstat$(EXEEXT) @@ -97,9 +98,9 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(man5dir)" -PROGRAMS = $(sbin_PROGRAMS) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" +PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) am__check_vnstat_SOURCES_DIST = tests/vnstat_tests.c \ tests/vnstat_tests.h tests/common_tests.c tests/common_tests.h \ tests/database_tests.c tests/database_tests.h \ @@ -142,6 +143,12 @@ check_vnstat_OBJECTS = $(am_check_vnstat_OBJECTS) check_vnstat_DEPENDENCIES = check_vnstat_LINK = $(CCLD) $(check_vnstat_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_vnstat_OBJECTS = src/vnstat.$(OBJEXT) src/ifinfo.$(OBJEXT) \ + src/dbsql.$(OBJEXT) src/common.$(OBJEXT) src/misc.$(OBJEXT) \ + src/cfg.$(OBJEXT) src/ibw.$(OBJEXT) src/fs.$(OBJEXT) \ + src/id.$(OBJEXT) src/traffic.$(OBJEXT) +vnstat_OBJECTS = $(am_vnstat_OBJECTS) +vnstat_LDADD = $(LDADD) am_vnstatd_OBJECTS = src/vnstatd.$(OBJEXT) src/ifinfo.$(OBJEXT) \ src/dbsql.$(OBJEXT) src/dbaccess.$(OBJEXT) \ src/datacache.$(OBJEXT) src/common.$(OBJEXT) \ @@ -181,8 +188,9 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(check_vnstat_SOURCES) $(vnstatd_SOURCES) -DIST_SOURCES = $(am__check_vnstat_SOURCES_DIST) $(vnstatd_SOURCES) +SOURCES = $(check_vnstat_SOURCES) $(vnstat_SOURCES) $(vnstatd_SOURCES) +DIST_SOURCES = $(am__check_vnstat_SOURCES_DIST) $(vnstat_SOURCES) \ + $(vnstatd_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -583,6 +591,17 @@ EXTRA_DIST = cfg examples UPGRADE CHANGES FAQ INSTALL_BSD INSTALL_OSX UNINSTALL #bin_PROGRAMS += vnstati #endif #vnstati_LDADD = $(IMAGELIBS) +vnstat_SOURCES = src/vnstat.c src/vnstat.h \ + src/ifinfo.c src/ifinfo.h \ + src/dbsql.c src/dbsql.h \ + src/common.c src/common.h \ + src/misc.c src/misc.h \ + src/cfg.c src/cfg.h \ + src/ibw.c src/ibw.h \ + src/fs.c src/fs.h \ + src/id.c src/id.h \ + src/traffic.c src/traffic.h + #vnstat_SOURCES = src/vnstat.c src/vnstat.h \ # src/ifinfo.c src/ifinfo.h \ @@ -692,6 +711,64 @@ $(top_srcdir)/src/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) distclean-hdr: -rm -f src/config.h src/stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +installcheck-binPROGRAMS: $(bin_PROGRAMS) + bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \ + 2>c$${pid}_.err &2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) @@ -813,15 +890,11 @@ src/check_vnstat-id.$(OBJEXT): src/$(am__dirstamp) \ check_vnstat$(EXEEXT): $(check_vnstat_OBJECTS) $(check_vnstat_DEPENDENCIES) $(EXTRA_check_vnstat_DEPENDENCIES) @rm -f check_vnstat$(EXEEXT) $(AM_V_CCLD)$(check_vnstat_LINK) $(check_vnstat_OBJECTS) $(check_vnstat_LDADD) $(LIBS) -src/vnstatd.$(OBJEXT): src/$(am__dirstamp) \ +src/vnstat.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/ifinfo.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/dbsql.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) -src/dbaccess.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/datacache.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) src/common.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/misc.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) @@ -829,6 +902,18 @@ src/cfg.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/ibw.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/fs.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/id.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/traffic.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +vnstat$(EXEEXT): $(vnstat_OBJECTS) $(vnstat_DEPENDENCIES) $(EXTRA_vnstat_DEPENDENCIES) + @rm -f vnstat$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(vnstat_OBJECTS) $(vnstat_LDADD) $(LIBS) +src/vnstatd.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dbaccess.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/datacache.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) src/daemon.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) @@ -866,6 +951,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ifinfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/traffic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vnstat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vnstatd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/check_vnstat-common_tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/check_vnstat-config_tests.Po@am__quote@ @@ -1753,7 +1840,7 @@ check: check-recursive all-am: Makefile $(PROGRAMS) $(MANS) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -1795,8 +1882,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive -clean-am: clean-checkPROGRAMS clean-generic clean-local \ - clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-local clean-sbinPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1824,7 +1911,7 @@ install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-sbinPROGRAMS +install-exec-am: install-binPROGRAMS install-sbinPROGRAMS install-html: install-html-recursive @@ -1844,7 +1931,7 @@ install-ps: install-ps-recursive install-ps-am: -installcheck-am: installcheck-sbinPROGRAMS +installcheck-am: installcheck-binPROGRAMS installcheck-sbinPROGRAMS maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1865,7 +1952,8 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-man uninstall-sbinPROGRAMS +uninstall-am: uninstall-binPROGRAMS uninstall-man \ + uninstall-sbinPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook uninstall-man: uninstall-man1 uninstall-man5 @@ -1875,24 +1963,26 @@ uninstall-man: uninstall-man1 uninstall-man5 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-TESTS check-am check-local clean \ - clean-checkPROGRAMS clean-cscope clean-generic clean-local \ - clean-sbinPROGRAMS cscope cscopelist-am ctags ctags-am dist \ - dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-compile \ - distclean-generic distclean-hdr distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-data-hook install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-man1 install-man5 \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-sbinPROGRAMS install-strip installcheck \ - installcheck-am installcheck-sbinPROGRAMS installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ - ps ps-am recheck tags tags-am uninstall uninstall-am \ - uninstall-hook uninstall-man uninstall-man1 uninstall-man5 \ - uninstall-sbinPROGRAMS + clean-binPROGRAMS clean-checkPROGRAMS clean-cscope \ + clean-generic clean-local clean-sbinPROGRAMS cscope \ + cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-compile distclean-generic \ + distclean-hdr distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-data-hook install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-man5 install-pdf install-pdf-am install-ps \ + install-ps-am install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installcheck-binPROGRAMS \ + installcheck-sbinPROGRAMS installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-hook uninstall-man \ + uninstall-man1 uninstall-man5 uninstall-sbinPROGRAMS #check_vnstat_SOURCES += src/cfg.c src/cfg.h \ diff --git a/README.md b/README.md index 4407d374..61a5d96c 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,14 @@ configurable durations. Yearly and 5 minute resolution statistics are also plann ##### Overall status - * only daemon is being compiled * alpha version with working daemon implementation * some sanity checks may be missing or disabled + * vnstat (console output) lacks most database features + * `-l` / `--live` and `-tr` / `--traffic` are available + * implemented database dependent features + * `--create` + * `--delete` + * vnstati (image output) is disabled * not ready to replace vnStat 1.x due to lack of outputs ##### Done diff --git a/src/dbshow.c b/src/dbshow.c index 5162b407..6235e4e2 100644 --- a/src/dbshow.c +++ b/src/dbshow.c @@ -1,14 +1,15 @@ #include "common.h" +#include "dbsql.h" #include "misc.h" #include "dbshow.h" void showdb(int qmode) { - if (data.totalrx+data.totaltx==0 && data.totalrxk+data.totaltxk==0 && qmode!=4) { +/* if (data.totalrx+data.totaltx==0 && data.totalrxk+data.totaltxk==0 && qmode!=4) { printf(" %s: Not enough data available yet.\n", data.interface); return; } - +*/ switch(qmode) { case 0: showsummary(); @@ -1009,6 +1010,7 @@ void showoneline(void) printf("%s\n", getvalue(data.totalrx+data.totaltx, data.totalrxk+data.totaltxk, 1, 1)); } +/* void exportdb(void) { int i; @@ -1044,53 +1046,41 @@ void exportdb(void) printf("h;%d;%u;%"PRIu64";%"PRIu64"\n", i, (unsigned int)data.hour[i].date, data.hour[i].rx, data.hour[i].tx); } } +*/ -int showbar(uint64_t rx, int rxk, uint64_t tx, int txk, uint64_t max, int len) +int showbar(uint64_t rx, uint64_t tx, uint64_t max, int len) { int i, l; - if (rxk>=1024) { - rx+=rxk/1024; - rxk-=(rxk/1024)*1024; - } - - if (txk>=1024) { - tx+=txk/1024; - txk-=(txk/1024)*1024; + if ( (rx + tx) < max) { + len = ( (rx + tx) / (float)max ) * len; + } else if ((rx + tx) > max) { + return 0; } - rx=(rx*1024)+rxk; - tx=(tx*1024)+txk; - - if ((rx+tx)max) { + if (len <= 0) { return 0; } - if (len>0) { - printf(" "); + printf(" "); - if (tx>rx) { - l=rintf((rx/(float)(rx+tx)*len)); - - for (i=0;i rx) { + l=rintf((rx/(float)(rx+tx)*len)); + for (i=0; i #include "common.h" #include "ifinfo.h" #include "traffic.h" -#include "dbxml.h" -#include "dbjson.h" -#include "dbshow.h" -#include "dbaccess.h" -#include "dbmerge.h" +#include "dbsql.h" +//#include "dbxml.h" +//#include "dbjson.h" +//#include "dbshow.h" +//#include "dbmerge.h" #include "misc.h" #include "cfg.h" #include "ibw.h" +#include "fs.h" #include "vnstat.h" int main(int argc, char *argv[]) { int i, currentarg; DIR *dir = NULL; - struct dirent *di = NULL; PARAMS p; initparams(&p); @@ -100,6 +100,7 @@ int main(int argc, char *argv[]) { currentarg++; continue; } else if ((strcmp(argv[currentarg],"--nick"))==0) { + /* TODO: implementation for nick change missing */ if (currentarg+1 1 || cfg.rateunit < 0) { printf("Error: Invalid parameter \"%d\" for --rateunit.\n", cfg.rateunit); @@ -254,9 +253,6 @@ int main(int argc, char *argv[]) { if (debug) printf("Rateunit changed: %d\n", cfg.rateunit); } - } else if (strcmp(argv[currentarg],"--enable")==0) { - p.active=1; - p.query=0; } else if ((strcmp(argv[currentarg],"-tr")==0) || (strcmp(argv[currentarg],"--traffic")==0)) { if (currentarg+1\n", getversion()); return 0; - } else if ((strcmp(argv[currentarg],"-r")==0) || (strcmp(argv[currentarg],"--reset")==0)) { - p.reset=1; - p.query=0; - } else if (strcmp(argv[currentarg],"--sync")==0) { - p.sync=1; - p.query=0; } else { printf("Unknown parameter \"%s\". Use --help for help.\n",argv[currentarg]); return 1; @@ -320,24 +303,28 @@ int main(int argc, char *argv[]) { } - /* check if the database dir exists and if it contains files */ + /* open database and see if it contains any interfaces */ if (!p.traffic && !p.livetraffic) { if ((dir=opendir(p.dirname))!=NULL) { if (debug) printf("Dir OK\n"); - while ((di=readdir(dir))) { - if ((di->d_name[0]=='.') || (strcmp(di->d_name, DATABASEFILE)==0)) { - continue; + closedir(dir); + strncpy_nt(cfg.dbdir, p.dirname, 512); + if (!db_open(0)) { + if (errno != ENOENT) { + printf("Error: Unable to open database \"%s/%s\": %s\n", p.dirname, DATABASEFILE, strerror(errno)); + return 1; + } else { + p.query = 0; } - strncpy_nt(p.definterface, di->d_name, 32); - p.files++; } + p.ifcount = db_getinterfacecount(); if (debug) - printf("%d file(s) found\n", p.files); - if (p.files>1) { + printf("%d interface(s) found\n", p.ifcount); + + if (p.ifcount > 1) { strncpy_nt(p.definterface, cfg.iface, 32); } - closedir(dir); } else { printf("Error: Unable to open database directory \"%s\": %s\n", p.dirname, strerror(errno)); if (errno==ENOENT) { @@ -358,24 +345,20 @@ int main(int argc, char *argv[]) { p.interface[31]='\0'; /* parameter handlers */ - handledbmerge(&p); - handlecounterreset(&p); - handleimport(&p); - handlecountersync(&p); + /* TODO: remove those that aren't needed */ + //handledbmerge(&p); + //handlecounterreset(&p); + //handleimport(&p); handledelete(&p); - handlecleartop10(&p); - handlerebuildtotal(&p); - handleenabledisable(&p); handlecreate(&p); - handleupdate(&p); handleshowdatabases(&p); handletrafficmeters(&p); /* show something if nothing was shown previously */ - if (!p.query && !p.update && !p.create && !p.reset && !p.sync && p.active==-1 && !p.cleartop && !p.rebuildtotal && !p.traffic && !p.livetraffic) { + if (!p.query && !p.create && p.active==-1 && !p.traffic && !p.livetraffic) { /* give more help if there's no database */ - if (p.files==0) { + if (p.ifcount == 0) { getiflist(&p.ifacelist, 1); printf("No database found, nothing to do. Use --help for help.\n\n"); printf("A new database can be created with the following command:\n"); @@ -394,6 +377,7 @@ int main(int argc, char *argv[]) { /* cleanup */ ibwflush(); + db_close(); return 0; } @@ -405,19 +389,13 @@ void initparams(PARAMS *p) disableprints = 0; /* let prints be visible */ p->create = 0; - p->update = 0; p->query = 1; - p->newdb = 0; - p->reset = 0; - p->sync = 0; - p->merged = 0; - p->savemerged = 0; + //p->merged = 0; + //p->savemerged = 0; p->import = 0; p->active = -1; - p->files = 0; + p->ifcount = 0; p->force = 0; - p->cleartop = 0; - p->rebuildtotal = 0; p->traffic = 0; p->livetraffic = 0; p->defaultiface = 1; @@ -429,22 +407,6 @@ void initparams(PARAMS *p) p->xmlmode = 'a'; } -int synccounters(const char *iface, const char *dirname) -{ - readdb(iface, dirname, 0); - if (!getifinfo(iface)) { - printf("Error: Unable to sync unavailable interface \"%s\".", iface); - return 0; - } - - /* set counters to current without counting traffic */ - data.currx = ifinfo.rx; - data.curtx = ifinfo.tx; - - writedb(iface, dirname, 0); - return 1; -} - void showhelp(PARAMS *p) { printf(" vnStat %s by Teemu Toivola \n\n", getversion()); @@ -456,7 +418,6 @@ void showhelp(PARAMS *p) printf(" -w, --weeks show weeks\n"); printf(" -t, --top10 show top 10 days\n"); printf(" -s, --short use short output\n"); - printf(" -u, --update update database\n"); printf(" -i, --iface select interface (default: %s)\n", p->definterface); printf(" -?, --help short help\n"); printf(" -v, --version show version\n"); @@ -469,6 +430,10 @@ void showhelp(PARAMS *p) void showlonghelp(PARAMS *p) { + /* TODO: update */ + /* --create could be replaced with --add as it adds the interface to the database */ + /* --delete could be similarly replaced with --remove */ + printf(" vnStat %s by Teemu Toivola \n\n", getversion()); printf(" Query:\n"); @@ -481,22 +446,22 @@ void showlonghelp(PARAMS *p) printf(" -s, --short use short output\n"); printf(" -ru, --rateunit swap configured rate unit\n"); printf(" --oneline show simple parseable format\n"); - printf(" --exportdb dump database in text format\n"); - printf(" --importdb import previously exported database\n"); - printf(" --json show database in json format\n"); - printf(" --xml show database in xml format\n"); + //printf(" --exportdb dump database in text format\n"); + //printf(" --importdb import previously exported database\n"); + //printf(" --json show database in json format\n"); + //printf(" --xml show database in xml format\n"); printf(" Modify:\n"); printf(" --create create database\n"); printf(" --delete delete database\n"); - printf(" -u, --update update database\n"); - printf(" -r, --reset reset interface counters\n"); - printf(" --sync sync interface counters\n"); - printf(" --enable enable interface\n"); - printf(" --disable disable interface\n"); + //printf(" -u, --update update database\n"); + //printf(" -r, --reset reset interface counters\n"); + //printf(" --sync sync interface counters\n"); + //printf(" --enable enable interface\n"); + //printf(" --disable disable interface\n"); printf(" --nick set a nickname for interface\n"); - printf(" --cleartop clear the top 10\n"); - printf(" --rebuildtotal rebuild total transfers from months\n"); + //printf(" --cleartop clear the top 10\n"); + //printf(" --rebuildtotal rebuild total transfers from months\n"); printf(" Misc:\n"); printf(" -i, --iface select interface (default: %s)\n", p->definterface); @@ -510,7 +475,7 @@ void showlonghelp(PARAMS *p) printf(" --dbdir select database directory\n"); printf(" --locale set locale\n"); printf(" --config select config file\n"); - printf(" --savemerged save merged database to current directory\n"); + //printf(" --savemerged save merged database to current directory\n"); printf(" --showconfig dump config file with current settings\n"); printf(" --testkernel check if the kernel is broken\n"); printf(" --longhelp display this help\n\n"); @@ -518,46 +483,7 @@ void showlonghelp(PARAMS *p) printf("See also \"man vnstat\".\n"); } -void handledbmerge(PARAMS *p) -{ - /* db merge */ - if (p->query && strstr(p->interface, "+")) { - if (mergedb(p->interface, p->dirname)) { - p->files = p->merged = 1; - } else { - exit(EXIT_FAILURE); - } - } - - /* save merged database */ - if (p->merged && p->savemerged) { - data.lastupdated = 0; - if (writedb("mergeddb", ".", 2)) { - printf("Database saved as \"mergeddb\" in the current directory.\n"); - } - exit(EXIT_SUCCESS); - } -} - -void handlecounterreset(PARAMS *p) -{ - if (!p->reset) { - return; - } - - if (!p->force && !spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - readdb(p->interface, p->dirname, 0); - data.currx=0; - data.curtx=0; - writedb(p->interface, p->dirname, 0); - if (debug) - printf("Counters reseted for \"%s\"\n", data.interface); -} - -void handleimport(PARAMS *p) +/*void handleimport(PARAMS *p) { if (!p->import) { return; @@ -584,31 +510,14 @@ void handleimport(PARAMS *p) printf("Error: validation of imported database failed.\n"); exit(EXIT_FAILURE); } - /* set boot time to zero in order to force counter sync */ + // set boot time to zero in order to force counter sync data.btime = 0; strncpy_nt(data.interface, p->interface, 32); if (writedb(p->interface, p->dirname, 1)) { printf("Database import for \"%s\" completed.\n", data.interface); } exit(EXIT_SUCCESS); -} - -void handlecountersync(PARAMS *p) -{ - if (!p->sync) { - return; - } - - if (!p->force && !spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - if (!synccounters(p->interface, p->dirname)) { - exit(EXIT_FAILURE); - } - if (debug) - printf("Counters synced for \"%s\"\n", data.interface); -} +}*/ void handledelete(PARAMS *p) { @@ -616,104 +525,32 @@ void handledelete(PARAMS *p) return; } - if (!p->force) { - printf("Warning:\nThe current option would delete the database for \"%s\".\n", p->interface); - printf("Use --force in order to really do that.\n"); + if (!db_getinterfacecountbyname(p->interface)) { + printf("Error: Interface \"%s\" not found in database.\n", p->interface); exit(EXIT_FAILURE); } - if (checkdb(p->interface, p->dirname)) { - if (removedb(p->interface, p->dirname)) { - printf("Database for interface \"%s\" deleted.\n", p->interface); - printf("The interface will no longer be monitored. Use --create\n"); - printf("if monitoring the interface is again needed.\n"); - exit(EXIT_SUCCESS); - } else { - printf("Error: Deleting database for interface \"%s\" failed.\n", p->interface); - exit(EXIT_FAILURE); - } - } else { - printf("Error: No database found for interface \"%s\".\n", p->interface); - exit(EXIT_FAILURE); - } -} - -void handlecleartop10(PARAMS *p) -{ - if (!p->cleartop) { - return; - } - - if (!p->force && !spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - if (p->force) { - cleartop10(p->interface, p->dirname); - p->query=0; - } else { - printf("Warning:\nThe current option would clear the top 10 for \"%s\".\n", p->interface); + if (!p->force) { + printf("Warning:\nThe current option would delete all data\nabout interface \"%s\" from the database.\n", p->interface); printf("Use --force in order to really do that.\n"); exit(EXIT_FAILURE); } -} - -void handlerebuildtotal(PARAMS *p) -{ - if (!p->rebuildtotal) { - return; - } - if (!spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - if (p->force) { - rebuilddbtotal(p->interface, p->dirname); - p->query=0; + if (db_removeinterface(p->interface)) { + printf("Interface \"%s\" deleted from database.\n", p->interface); + printf("The interface will no longer be monitored. Use --create\n"); + printf("if monitoring the interface is again needed.\n"); + exit(EXIT_SUCCESS); } else { - printf("Warning:\nThe current option would rebuild total tranfers for \"%s\".\n", p->interface); - printf("Use --force in order to really do that.\n"); + printf("Error: Deleting interface \"%s\" from database failed.\n", p->interface); exit(EXIT_FAILURE); } } -void handleenabledisable(PARAMS *p) -{ - /* enable & disable */ - if (p->active==1) { - if (!p->force && !spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - p->newdb=readdb(p->interface, p->dirname, 0); - if (!data.active && !p->newdb) { - data.active=1; - writedb(p->interface, p->dirname, 0); - if (debug) - printf("Interface \"%s\" enabled.\n", data.interface); - } else if (!p->newdb) { - printf("Interface \"%s\" is already enabled.\n", data.interface); - } - } else if (p->active==0) { - if (!p->force && !spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - p->newdb=readdb(p->interface, p->dirname, 0); - if (data.active && !p->newdb) { - data.active=0; - writedb(p->interface, p->dirname, 0); - if (debug) - printf("Interface \"%s\" disabled.\n", data.interface); - } else if (!p->newdb) { - printf("Interface \"%s\" is already disabled.\n", data.interface); - } - } -} - void handlecreate(PARAMS *p) { + char dbfile[512]; + if (!p->create) { return; } @@ -723,6 +560,11 @@ void handlecreate(PARAMS *p) exit(EXIT_FAILURE); } + if (db_getinterfacecountbyname(p->interface)) { + printf("Error: Interface \"%s\" already exists in the database.\n", p->interface); + exit(EXIT_FAILURE); + } + if (!p->force && !getifinfo(p->interface)) { getiflist(&p->ifacelist, 1); printf("Only available interfaces can be added for monitoring.\n\n"); @@ -731,139 +573,28 @@ void handlecreate(PARAMS *p) exit(EXIT_FAILURE); } - if (checkdb(p->interface, p->dirname)) { - printf("Error: Database for interface \"%s\" already exists.\n", p->interface); - exit(EXIT_FAILURE); - } - - if (!p->force && !spacecheck(p->dirname)) { - printf("Error: Not enough free diskspace available.\n"); - exit(EXIT_FAILURE); - } - - printf("Creating database for interface \"%s\"...\n", p->interface); - initdb(); - strncpy_nt(data.interface, p->interface, 32); - strncpy_nt(data.nick, p->interface, 32); - if (writedb(p->interface, p->dirname, 1)) { - printf("\nRestart the vnStat daemon if it is currently running in order to start monitoring \"%s\".\n", p->interface); - } -} - -void handleupdate(PARAMS *p) -{ - DIR *dir = NULL; - struct dirent *di = NULL; - time_t current; - - if (!p->update) { - return; - } - - current = time(NULL); - - /* check that there's some free diskspace left */ if (!p->force && !spacecheck(p->dirname)) { printf("Error: Not enough free diskspace available.\n"); exit(EXIT_FAILURE); } - /* update every file if -i isn't specified */ - if (p->defaultiface) { - - if ((dir=opendir(p->dirname))==NULL) { - return; - } - - p->files=0; - while ((di=readdir(dir))) { - - /* ignore backup files, '.' and '..' dirs */ - if ((di->d_name[0]=='.') || (strcmp(di->d_name, DATABASEFILE)==0)) { - continue; - } - - p->files++; - strncpy_nt(p->interface, di->d_name, 32); - if (debug) - printf("\nProcessing file \"%s/%s\"...\n", p->dirname, p->interface); - p->newdb=readdb(p->interface, p->dirname, 0); - - if (!data.active) { - if (debug) - printf("Disabled interface \"%s\" not updated.\n", data.interface); - continue; - } - - /* skip interface if not available */ - if (!getifinfo(data.interface)) { - if (debug) - printf("Interface \"%s\" not available, skipping.\n", data.interface); - continue; - } - parseifinfo(p->newdb); - - /* check that the time is correct */ - if ((current>=data.lastupdated) || p->force) { - writedb(p->interface, p->dirname, p->newdb); - } else { - /* print error if previous update is more than 6 hours in the future */ - /* otherwise do nothing */ - if (data.lastupdated>=(current+21600)) { - printf("Error: The previous update was after the current date.\n\n"); - printf("Previous update: %s", (char*)asctime(localtime(&data.lastupdated))); - printf(" Current time: %s\n", (char*)asctime(localtime(¤t))); - printf("Use --force to override this message.\n"); - exit(EXIT_FAILURE); - } else { - if (debug) - printf("\"%s\" not updated, %s > %s.\n", data.interface, (char*)asctime(localtime(&data.lastupdated)), (char*)asctime(localtime(¤t))); - } - } - } - - closedir(dir); - if (p->files==0) { - /* no database found */ - p->update=0; + snprintf(dbfile, 512, "%s/%s", p->dirname, DATABASEFILE); + if (!fileexists(dbfile)) { + /* database file doesn't exist so it can't be open either, try to create it */ + printf("Database doesn't exist, creating...\n"); + if (!db_open(1)) { + printf("Error: Unable to open database \"%s/%s\": %s\n", p->dirname, DATABASEFILE, strerror(errno)); + exit(EXIT_FAILURE); } + /* do file ownwership fixing if possible and needed */ + matchdbownerwithdirowner(p->dirname); + } - /* update only selected file */ + printf("Adding interface \"%s\" for monitoring to database...\n", p->interface); + if (db_addinterface(p->interface)) { + printf("\nRestart the vnStat daemon if it is currently running in order to start monitoring \"%s\".\n", p->interface); } else { - p->newdb=readdb(p->interface, p->dirname, 0); - - if (!data.active) { - if (debug) - printf("Disabled interface \"%s\" not updated.\n", data.interface); - return; - } - - if (!p->force && !getifinfo(data.interface)) { - getiflist(&p->ifacelist, 1); - printf("Only available interfaces can be added for monitoring.\n\n"); - printf("The following interfaces are currently available:\n %s\n", p->ifacelist); - free(p->ifacelist); - exit(EXIT_FAILURE); - } - parseifinfo(p->newdb); - if ((current>=data.lastupdated) || p->force) { - if (strcmp(p->nick, "none")!=0) - strncpy_nt(data.nick, p->nick, 32); - writedb(p->interface, p->dirname, p->newdb); - } else { - /* print error if previous update is more than 6 hours in the future */ - /* otherwise do nothing */ - if (data.lastupdated>=(current+21600)) { - printf("Error: The previous update was after the current date.\n\n"); - printf("Previous update: %s", (char*)asctime(localtime(&data.lastupdated))); - printf(" Current time: %s\n", (char*)asctime(localtime(¤t))); - printf("Use --force to override this message.\n"); - exit(EXIT_FAILURE); - } else { - if (debug) - printf("\"%s\" not updated, %s > %s.\n", data.interface, (char*)asctime(localtime(&data.lastupdated)), (char*)asctime(localtime(¤t))); - } - } + printf("Error: Adding interface \"%s\" to database failed: %s\n", p->interface, strerror(errno)); } } @@ -884,10 +615,10 @@ void handleshowdatabases(PARAMS *p) } /* show all interfaces if -i isn't specified */ - if (p->files==0) { + if (p->ifcount==0) { /* printf("No database found.\n"); */ p->query=0; - } else if ((cfg.qmode==0 || cfg.qmode==8 || cfg.qmode==10) && (p->files>1)) { + } else if ((cfg.qmode==0 || cfg.qmode==8 || cfg.qmode==10) && (p->ifcount>1)) { if (cfg.qmode==0) { if (cfg.ostyle!=0) { @@ -895,11 +626,11 @@ void handleshowdatabases(PARAMS *p) } else { printf("\n rx / tx / total\n"); } - } else if (cfg.qmode==8) { +/* } else if (cfg.qmode==8) { xmlheader(); } else if (cfg.qmode==10) { jsonheader(); - } +*/ } if ((dir=opendir(p->dirname))==NULL) { return; } @@ -910,26 +641,28 @@ void handleshowdatabases(PARAMS *p) strncpy_nt(p->interface, di->d_name, 32); if (debug) printf("\nProcessing file \"%s/%s\"...\n", p->dirname, p->interface); - p->newdb=readdb(p->interface, p->dirname, p->force); +/* p->newdb=readdb(p->interface, p->dirname, p->force); if (p->newdb) { continue; - } + }*/ if (cfg.qmode==0) { - showdb(5); - } else if (cfg.qmode==8) { + /* TODO */ + printf(" == query not implemented ==\n"); + //showdb(5); +/* } else if (cfg.qmode==8) { showxml(p->xmlmode); } else if (cfg.qmode==10) { showjson(dbcount, p->jsonmode); - } +*/ } dbcount++; } closedir(dir); - if (cfg.qmode==8) { +/* if (cfg.qmode==8) { xmlfooter(); } else if (cfg.qmode==10) { jsonfooter(); } - +*/ /* show in qmode if there's only one file or qmode!=0 */ } else { showoneinterface(p, p->definterface); @@ -938,12 +671,11 @@ void handleshowdatabases(PARAMS *p) void showoneinterface(PARAMS *p, const char *interface) { - if (!p->merged) { - p->newdb=readdb(interface, p->dirname, p->force); - } - if (p->newdb) { + if (!db_getinterfacecountbyname(p->interface)) { + p->query = 0; return; } + if (cfg.qmode==5) { if (cfg.ostyle!=0) { printf("\n rx / tx / total / estimated\n"); @@ -952,8 +684,11 @@ void showoneinterface(PARAMS *p, const char *interface) } } if (cfg.qmode!=8 && cfg.qmode!=10) { - showdb(cfg.qmode); - } else if (cfg.qmode==8) { + /* TODO */ + printf(" == one query not implemented ==\n"); + printf("input: %d - %d, %s\n", p->query, cfg.qmode, interface); + //showdb(cfg.qmode); +/* } else if (cfg.qmode==8) { xmlheader(); showxml(p->xmlmode); xmlfooter(); @@ -961,7 +696,7 @@ void showoneinterface(PARAMS *p, const char *interface) jsonheader(); showjson(0, p->jsonmode); jsonfooter(); - } +*/ } } void handletrafficmeters(PARAMS *p) diff --git a/src/vnstat.h b/src/vnstat.h index 181e03c6..ab36b12e 100644 --- a/src/vnstat.h +++ b/src/vnstat.h @@ -2,27 +2,20 @@ #define VNSTAT_H typedef struct { - int update, query, newdb, reset, sync, merged, savemerged, import; - int create, active, files, force, cleartop, rebuildtotal, traffic; + int query, import; + int create, active, ifcount, force, traffic; int livetraffic, defaultiface, delete, livemode; char interface[32], dirname[512], nick[32], filename[512]; char definterface[32], cfgfile[512], *ifacelist, jsonmode, xmlmode; } PARAMS; void initparams(PARAMS *p); -int synccounters(const char *iface, const char *dirname); void showhelp(PARAMS *p); void showlonghelp(PARAMS *p); -void handledbmerge(PARAMS *p); -void handlecounterreset(PARAMS *p); -void handleimport(PARAMS *p); -void handlecountersync(PARAMS *p); +//void handledbmerge(PARAMS *p); +//void handleimport(PARAMS *p); void handledelete(PARAMS *p); -void handlecleartop10(PARAMS *p); -void handlerebuildtotal(PARAMS *p); -void handleenabledisable(PARAMS *p); void handlecreate(PARAMS *p); -void handleupdate(PARAMS *p); void handleshowdatabases(PARAMS *p); void showoneinterface(PARAMS *p, const char *interface); void handletrafficmeters(PARAMS *p); diff --git a/tests/dbsql_tests.c b/tests/dbsql_tests.c index 9e9c67e6..a9cf008b 100644 --- a/tests/dbsql_tests.c +++ b/tests/dbsql_tests.c @@ -364,6 +364,67 @@ START_TEST(db_addinterface_can_not_add_same_interface_twice) } END_TEST +START_TEST(db_removeinterface_knows_if_interface_exists) +{ + int ret; + + defaultcfg(); + + ret = db_open(1); + ck_assert_int_eq(ret, 1); + + ret = db_removeinterface("eth0"); + ck_assert_int_eq(ret, 0); + ret = db_removeinterface("nothing"); + ck_assert_int_eq(ret, 0); + ret = db_removeinterface(""); + ck_assert_int_eq(ret, 0); + + ret = db_close(); + ck_assert_int_eq(ret, 1); +} +END_TEST + +START_TEST(db_removeinterface_can_remove_interfaces) +{ + int ret; + + defaultcfg(); + + ret = db_open(1); + ck_assert_int_eq(ret, 1); + + ret = db_addinterface("eth0"); + ck_assert_int_eq(ret, 1); + ret = db_addinterface("eth1"); + ck_assert_int_eq(ret, 1); + ret = db_addinterface("eth2"); + ck_assert_int_eq(ret, 1); + + ck_assert_int_eq(db_getinterfacecount(), 3); + ck_assert_int_eq(db_getinterfacecountbyname("eth0"), 1); + ck_assert_int_eq(db_getinterfacecountbyname("eth1"), 1); + ck_assert_int_eq(db_getinterfacecountbyname("eth2"), 1); + ck_assert_int_eq(db_getinterfacecountbyname("eth3"), 0); + + ret = db_removeinterface("eth1"); + ck_assert_int_eq(ret, 1); + ret = db_removeinterface("nothing"); + ck_assert_int_eq(ret, 0); + ret = db_removeinterface(""); + ck_assert_int_eq(ret, 0); + + ck_assert_int_eq(db_getinterfacecount(), 2); + ck_assert_int_eq(db_getinterfacecountbyname("eth0"), 1); + ck_assert_int_eq(db_getinterfacecountbyname("eth1"), 0); + ck_assert_int_eq(db_getinterfacecountbyname("eth2"), 1); + ck_assert_int_eq(db_getinterfacecountbyname("eth3"), 0); + + ret = db_close(); + ck_assert_int_eq(ret, 1); +} +END_TEST + START_TEST(db_getinterfacecount_counts_interfaces) { uint64_t ret; @@ -684,6 +745,8 @@ void add_dbsql_tests(Suite *s) tcase_add_test(tc_dbsql, db_addinterface_fails_with_no_open_db); tcase_add_test(tc_dbsql, db_addinterface_can_add_interfaces); tcase_add_test(tc_dbsql, db_addinterface_can_not_add_same_interface_twice); + tcase_add_test(tc_dbsql, db_removeinterface_knows_if_interface_exists); + tcase_add_test(tc_dbsql, db_removeinterface_can_remove_interfaces); tcase_add_test(tc_dbsql, db_getcounters_with_no_interface); tcase_add_test(tc_dbsql, db_setcounters_with_no_interface); tcase_add_test(tc_dbsql, db_interface_info_manipulation);