diff options
Diffstat (limited to 'src')
47 files changed, 5620 insertions, 0 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..c5f77fa --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,44 @@ +## Helder Correia <helder.correia@netcabo.pt> + +bin_PROGRAMS = nload + +nload_SOURCES = \ +	dataframe.h										\ +	device.cpp device.h								\ +	devreader.cpp devreader.h						\ +	devreaderfactory.cpp devreaderfactory.h			\ +	form_field.cpp form_field.h						\ +	graph.cpp graph.h								\ +	main.cpp main.h									\ +	opt_window.cpp opt_window.h						\ +	screen.cpp screen.h								\ +	setting.cpp setting.h							\ +	settingfilter.cpp settingfilter.h               \ +	settingstore.cpp settingstore.h					\ +	statistics.cpp statistics.h						\ +	stringutils.cpp stringutils.h					\ +	traffic_window.cpp traffic_window.h				\ +	window.cpp window.h + +if HAVE_BSD +nload_SOURCES += \ +	devreader-bsd.cpp devreader-bsd.h +endif + +if HAVE_HPUX +nload_SOURCES += \ +	devreader-hpux.cpp devreader-hpux.h +endif + +if HAVE_LINUX +nload_SOURCES += \ +	devreader-linux.cpp devreader-linux.h			\ +	devreader-linux-proc.cpp devreader-linux-proc.h \ +	devreader-linux-sys.cpp devreader-linux-sys.h +endif + +if HAVE_SOLARIS +nload_SOURCES += \ +	devreader-solaris.cpp devreader-solaris.h +endif + diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..52a5278 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,536 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = nload$(EXEEXT) +@HAVE_BSD_TRUE@am__append_1 = \ +@HAVE_BSD_TRUE@	devreader-bsd.cpp devreader-bsd.h + +@HAVE_HPUX_TRUE@am__append_2 = \ +@HAVE_HPUX_TRUE@	devreader-hpux.cpp devreader-hpux.h + +@HAVE_LINUX_TRUE@am__append_3 = \ +@HAVE_LINUX_TRUE@	devreader-linux.cpp devreader-linux.h			\ +@HAVE_LINUX_TRUE@	devreader-linux-proc.cpp devreader-linux-proc.h \ +@HAVE_LINUX_TRUE@	devreader-linux-sys.cpp devreader-linux-sys.h + +@HAVE_SOLARIS_TRUE@am__append_4 = \ +@HAVE_SOLARIS_TRUE@	devreader-solaris.cpp devreader-solaris.h + +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +	$(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__nload_SOURCES_DIST = dataframe.h device.cpp device.h devreader.cpp \ +	devreader.h devreaderfactory.cpp devreaderfactory.h \ +	form_field.cpp form_field.h graph.cpp graph.h main.cpp main.h \ +	opt_window.cpp opt_window.h screen.cpp screen.h setting.cpp \ +	setting.h settingfilter.cpp settingfilter.h settingstore.cpp \ +	settingstore.h statistics.cpp statistics.h stringutils.cpp \ +	stringutils.h traffic_window.cpp traffic_window.h window.cpp \ +	window.h devreader-bsd.cpp devreader-bsd.h devreader-hpux.cpp \ +	devreader-hpux.h devreader-linux.cpp devreader-linux.h \ +	devreader-linux-proc.cpp devreader-linux-proc.h \ +	devreader-linux-sys.cpp devreader-linux-sys.h \ +	devreader-solaris.cpp devreader-solaris.h +@HAVE_BSD_TRUE@am__objects_1 = devreader-bsd.$(OBJEXT) +@HAVE_HPUX_TRUE@am__objects_2 = devreader-hpux.$(OBJEXT) +@HAVE_LINUX_TRUE@am__objects_3 = devreader-linux.$(OBJEXT) \ +@HAVE_LINUX_TRUE@	devreader-linux-proc.$(OBJEXT) \ +@HAVE_LINUX_TRUE@	devreader-linux-sys.$(OBJEXT) +@HAVE_SOLARIS_TRUE@am__objects_4 = devreader-solaris.$(OBJEXT) +am_nload_OBJECTS = device.$(OBJEXT) devreader.$(OBJEXT) \ +	devreaderfactory.$(OBJEXT) form_field.$(OBJEXT) \ +	graph.$(OBJEXT) main.$(OBJEXT) opt_window.$(OBJEXT) \ +	screen.$(OBJEXT) setting.$(OBJEXT) settingfilter.$(OBJEXT) \ +	settingstore.$(OBJEXT) statistics.$(OBJEXT) \ +	stringutils.$(OBJEXT) traffic_window.$(OBJEXT) \ +	window.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ +	$(am__objects_3) $(am__objects_4) +nload_OBJECTS = $(am_nload_OBJECTS) +nload_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ +	-o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ +	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(nload_SOURCES) +DIST_SOURCES = $(am__nload_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INCLUDES = @INCLUDES@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +nload_SOURCES = dataframe.h device.cpp device.h devreader.cpp \ +	devreader.h devreaderfactory.cpp devreaderfactory.h \ +	form_field.cpp form_field.h graph.cpp graph.h main.cpp main.h \ +	opt_window.cpp opt_window.h screen.cpp screen.h setting.cpp \ +	setting.h settingfilter.cpp settingfilter.h settingstore.cpp \ +	settingstore.h statistics.cpp statistics.h stringutils.cpp \ +	stringutils.h traffic_window.cpp traffic_window.h window.cpp \ +	window.h $(am__append_1) $(am__append_2) $(am__append_3) \ +	$(am__append_4) +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .o .obj +$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps) +	@for dep in $?; do \ +	  case '$(am__configure_deps)' in \ +	    *$$dep*) \ +	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ +	        && { if test -f $@; then exit 0; else break; fi; }; \ +	      exit 1;; \ +	  esac; \ +	done; \ +	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ +	$(am__cd) $(top_srcdir) && \ +	  $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +	@case '$?' in \ +	  *config.status*) \ +	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ +	  *) \ +	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ +	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ +	esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure:  $(am__configure_deps) +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4):  $(am__aclocal_m4_deps) +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) +	@$(NORMAL_INSTALL) +	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" +	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ +	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) +nload$(EXEEXT): $(nload_OBJECTS) $(nload_DEPENDENCIES)  +	@rm -f nload$(EXEEXT) +	$(CXXLINK) $(nload_OBJECTS) $(nload_LDADD) $(LIBS) + +mostlyclean-compile: +	-rm -f *.$(OBJEXT) + +distclean-compile: +	-rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader-bsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader-hpux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader-linux-proc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader-linux-sys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader-linux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader-solaris.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devreaderfactory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/form_field.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_window.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setting.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settingfilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settingstore.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statistics.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/traffic_window.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) +	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ +	unique=`for i in $$list; do \ +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +	  done | \ +	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ +	      END { if (nonempty) { for (i in files) print i; }; }'`; \ +	mkid -fID $$unique +tags: TAGS + +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \ +		$(TAGS_FILES) $(LISP) +	set x; \ +	here=`pwd`; \ +	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \ +	unique=`for i in $$list; do \ +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +	  done | \ +	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ +	      END { if (nonempty) { for (i in files) print i; }; }'`; \ +	shift; \ +	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ +	  test -n "$$unique" || unique=$$empty_fix; \ +	  if test $$# -gt 0; then \ +	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +	      "$$@" $$unique; \ +	  else \ +	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +	      $$unique; \ +	  fi; \ +	fi +ctags: CTAGS +CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \ +		$(TAGS_FILES) $(LISP) +	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \ +	unique=`for i in $$list; do \ +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +	  done | \ +	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ +	      END { if (nonempty) { for (i in files) print i; }; }'`; \ +	test -z "$(CTAGS_ARGS)$$unique" \ +	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ +	     $$unique + +GTAGS: +	here=`$(am__cd) $(top_builddir) && pwd` \ +	  && $(am__cd) $(top_srcdir) \ +	  && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: +	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) +	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +	list='$(DISTFILES)'; \ +	  dist_files=`for file in $$list; do echo $$file; done | \ +	  sed -e "s|^$$srcdirstrip/||;t" \ +	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ +	case $$dist_files in \ +	  */*) $(MKDIR_P) `echo "$$dist_files" | \ +			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ +			   sort -u` ;; \ +	esac; \ +	for file in $$dist_files; do \ +	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ +	  if test -d $$d/$$file; then \ +	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ +	    if test -d "$(distdir)/$$file"; then \ +	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +	    fi; \ +	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ +	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ +	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +	    fi; \ +	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ +	  else \ +	    test -f "$(distdir)/$$file" \ +	    || cp -p $$d/$$file "$(distdir)/$$file" \ +	    || exit 1; \ +	  fi; \ +	done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +	for dir in "$(DESTDIR)$(bindir)"; do \ +	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \ +	done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am +	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: +	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +	  `test -z '$(STRIP)' || \ +	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: +	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) +	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: +	@echo "This command is intended for maintainers to use" +	@echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am +	-rm -rf ./$(DEPDIR) +	-rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ +	distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am +	-rm -rf ./$(DEPDIR) +	-rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ +	clean-generic ctags distclean distclean-compile \ +	distclean-generic distclean-tags distdir dvi dvi-am html \ +	html-am info info-am install install-am install-binPROGRAMS \ +	install-data install-data-am install-dvi install-dvi-am \ +	install-exec install-exec-am install-html install-html-am \ +	install-info install-info-am install-man install-pdf \ +	install-pdf-am install-ps install-ps-am install-strip \ +	installcheck installcheck-am installdirs maintainer-clean \ +	maintainer-clean-generic mostlyclean mostlyclean-compile \ +	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ +	uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/dataframe.h b/src/dataframe.h new file mode 100644 index 0000000..3311292 --- /dev/null +++ b/src/dataframe.h @@ -0,0 +1,88 @@ +/*************************************************************************** +                                 dataframe.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DATAFRAME_H +#define DATAFRAME_H + +#include <string> + +class DataFrame +{ +    public: +        DataFrame() +            : m_totalDataIn(0), m_totalDataOut(0), m_totalPacketsIn(0), m_totalPacketsOut(0), +              m_totalErrorsIn(0), m_totalErrorsOut(0), m_totalDropsIn(0), m_totalDropsOut(0), +              m_timeStampSeconds(0), m_timeStampMicroseconds(0), m_valid(false) {} +        ~DataFrame() {} + +        bool isValid() const { return m_valid; } +        void setValid(bool valid) { m_valid = valid; } + +        const std::string& getDeviceName() const { return m_deviceName; } +        void setDeviceName(const std::string& deviceName) { m_deviceName = deviceName; } + +        const std::string& getIpV4() const { return m_ipv4; } +        void setIpV4(const std::string& ipv4) { m_ipv4 = ipv4; } + +        unsigned long long getTotalDataIn() const { return m_totalDataIn; } +        void setTotalDataIn(unsigned long long totalDataIn) { m_totalDataIn = totalDataIn; } + +        unsigned long long getTotalDataOut() const { return m_totalDataOut; } +        void setTotalDataOut(unsigned long long totalDataOut) { m_totalDataOut = totalDataOut; } + +        unsigned long long getTotalPacketsIn() const { return m_totalPacketsIn; } +        void setTotalPacketsIn(unsigned long long totalPacketsIn) { m_totalPacketsIn = totalPacketsIn; } + +        unsigned long long getTotalPacketsOut() const { return m_totalPacketsOut; } +        void setTotalPacketsOut(unsigned long long totalPacketsOut) { m_totalPacketsOut = totalPacketsOut; } + +        unsigned long long getTotalErrorsIn() const { return m_totalErrorsIn; } +        void setTotalErrorsIn(unsigned long long totalErrorsIn) { m_totalErrorsIn = totalErrorsIn; } + +        unsigned long long getTotalErrorsOut() const { return m_totalErrorsOut; } +        void setTotalErrorsOut(unsigned long long totalErrorsOut) { m_totalErrorsOut = totalErrorsOut; } + +        unsigned long long getTotalDropsIn() const { return m_totalDropsIn; } +        void setTotalDropsIn(unsigned long long totalDropsIn) { m_totalDropsIn = totalDropsIn; } + +        unsigned long long getTotalDropsOut() const { return m_totalDropsOut; } +        void setTotalDropsOut(unsigned long long totalDropsOut) { m_totalDropsOut = totalDropsOut; } + +        unsigned long getTimeStampSeconds() const { return m_timeStampSeconds; } +        void setTimeStampSeconds(unsigned long seconds) { m_timeStampSeconds = seconds; } + +        unsigned long getTimeStampMicroseconds() const { return m_timeStampMicroseconds; } +        void setTimeStampMicroseconds(unsigned long microseconds) { m_timeStampMicroseconds = microseconds; } + +    private: +        std::string m_deviceName; +        std::string m_ipv4; +        unsigned long long m_totalDataIn; +        unsigned long long m_totalDataOut; +        unsigned long long m_totalPacketsIn; +        unsigned long long m_totalPacketsOut; +        unsigned long long m_totalErrorsIn; +        unsigned long long m_totalErrorsOut; +        unsigned long long m_totalDropsIn; +        unsigned long long m_totalDropsOut; +        unsigned long m_timeStampSeconds; +        unsigned long m_timeStampMicroseconds; +        bool m_valid; +}; + +#endif + diff --git a/src/device.cpp b/src/device.cpp new file mode 100644 index 0000000..e3d6372 --- /dev/null +++ b/src/device.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** +                                  dev.cpp +                             ------------------- +    begin                : Wed Aug 1 2001 +    copyright            : (C) 2001 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "device.h" +#include "devreader.h" +#include "graph.h" +#include "setting.h" +#include "settingstore.h" +#include "window.h" + +#include <iomanip> + +using namespace std; + +Device::Device(DevReader& devReader) +    : m_deviceNumber(0), m_totalNumberOfDevices(0), m_devReader(devReader) +{ +} + +Device::~Device() +{ +} + +// update the device's data +void Device::update() +{ +    // read current traffic +    DataFrame dataFrame = m_devReader.getNewDataFrame(); + +    if(dataFrame.isValid()) +    { +        /* Depending on the CPU architecture and the OS interface +         * used for reading the device statistics, the counts can +         * overflow. We monitor the overflows and fix them. +         */ +        fixOverflows(dataFrame, m_dataFrameOld); + +        m_deviceStatistics.insertDataFrame(dataFrame); + +        m_deviceGraphIn.update(m_deviceStatistics.getDataInPerSecond()); +        m_deviceGraphOut.update(m_deviceStatistics.getDataOutPerSecond()); + +        m_dataFrameOld = dataFrame; +    } +    else +    { +        m_deviceStatistics.reset(); +        m_deviceGraphIn.resetTrafficData(); +        m_deviceGraphOut.resetTrafficData(); +    } +} + +// print the device's data +void Device::print(Window& window) +{ +    // if device does not exist +    if(!m_deviceStatistics.isValid()) +    { +        // ... print warning message ... +        window.print() << "Device " << m_devReader.getDeviceName() << " (" << (m_deviceNumber + 1) << "/" << m_totalNumberOfDevices << "): does not exist" << endl; +        window.print() << string(window.getWidth(), '=') << endl; +         +        // ... and exit +        return; +    } +     +    // print header +    string ip4 = m_dataFrameOld.getIpV4(); +    if(!ip4.empty()) +        window.print() << "Device " << m_devReader.getDeviceName() << " [" << ip4 << "] (" << (m_deviceNumber + 1) << "/" << m_totalNumberOfDevices << "):" << endl; +    else +        window.print() << "Device " << m_devReader.getDeviceName() << " (" << (m_deviceNumber + 1) << "/" << m_totalNumberOfDevices << "):" << endl; +    window.print() << string(window.getWidth(), '='); +     +    // if graphs should be hidden ... +    if(SettingStore::get("MultipleDevices")) +    { +        window.print() << "Incoming:"; +        window.print(window.getWidth() / 2) << "Outgoing:" << endl; +         +        int statusY = window.getY(); +         +        printStatisticsIn(window, 0, statusY); +        printStatisticsOut(window, window.getWidth() / 2, statusY); +         +        window.print() << endl; +    } +    // ... or not +    else +    { +        // incoming traffic +        window.print() << "Incoming:" << endl; +         +        m_deviceGraphIn.setNumOfBars(window.getWidth() * 2 / 3); +        m_deviceGraphIn.setHeightOfBars((window.getHeight() - window.getY() - 1) / 2); +        m_deviceGraphIn.setMaxDeflection((unsigned long long) SettingStore::get("BarMaxIn") * 1024 / 8); +        m_deviceGraphIn.print(window, 0, window.getY()); +         +        printStatisticsIn(window, window.getWidth() * 2 / 3 + 2, window.getY() - 5); +         +        // outgoing traffic +        window.print() << "Outgoing:" << endl; +         +        m_deviceGraphOut.setNumOfBars(window.getWidth() * 2 / 3); +        m_deviceGraphOut.setHeightOfBars(window.getHeight() - window.getY()); +        m_deviceGraphOut.setMaxDeflection((unsigned long long) SettingStore::get("BarMaxOut") * 1024 / 8); +        m_deviceGraphOut.print(window, 0, window.getY()); +         +        printStatisticsOut(window, window.getWidth() * 2 / 3 + 2, window.getY() - 4); +    } +} + +// set the number identifying the device (for display only) +void Device::setDeviceNumber(int deviceNumber) +{ +    m_deviceNumber = deviceNumber; +} + +// set the total number of shown devices (for display only) +void Device::setTotalNumberOfDevices(int totalNumberOfDevices) +{ +    m_totalNumberOfDevices = totalNumberOfDevices; +} + +void Device::fixOverflows(DataFrame& dataFrame, const DataFrame& dataFrameOld) +{ +    if(!dataFrame.isValid() || !dataFrameOld.isValid()) +        return; + +    dataFrame.setTotalDataIn(fixOverflow(dataFrame.getTotalDataIn(), dataFrameOld.getTotalDataIn())); +    dataFrame.setTotalDataOut(fixOverflow(dataFrame.getTotalDataOut(), dataFrameOld.getTotalDataOut())); +    dataFrame.setTotalPacketsIn(fixOverflow(dataFrame.getTotalPacketsIn(), dataFrameOld.getTotalPacketsIn())); +    dataFrame.setTotalPacketsOut(fixOverflow(dataFrame.getTotalPacketsOut(), dataFrameOld.getTotalPacketsOut())); +    dataFrame.setTotalErrorsIn(fixOverflow(dataFrame.getTotalErrorsIn(), dataFrameOld.getTotalErrorsIn())); +    dataFrame.setTotalErrorsOut(fixOverflow(dataFrame.getTotalErrorsOut(), dataFrameOld.getTotalErrorsOut())); +    dataFrame.setTotalDropsIn(fixOverflow(dataFrame.getTotalDropsIn(), dataFrameOld.getTotalDropsIn())); +    dataFrame.setTotalDropsOut(fixOverflow(dataFrame.getTotalDropsOut(), dataFrameOld.getTotalDropsOut())); +} + +unsigned long long Device::fixOverflow(unsigned long long value, unsigned long long valueOld) +{ +    if(value > 0xffffffffULL) +        return value; + +    if(value < (valueOld & 0xffffffffULL)) +    { +        // overflow happend (again) +        valueOld += 0x100000000ULL; +    } + +    // no overflow happend, keep previous ones +    valueOld &= 0xffffffff00000000ULL; +    value |= valueOld; +    return value; +} + +void Device::printTrafficValue(Window& window, int x, int y, const std::string& description, unsigned long long value) +{ +    Statistics::dataUnit trafficFormat = (Statistics::dataUnit) ((int) SettingStore::get("TrafficFormat")); + +    string unitString = Statistics::getUnitString(trafficFormat, value); +    float unitFactor = Statistics::getUnitFactor(trafficFormat, value); + +    window.print(x, y) << fixed << setprecision(2) << description << ": " << ((float) value / unitFactor) << " " << unitString << "/s" << endl; +} + +void Device::printDataValue(Window& window, int x, int y, const std::string& description, unsigned long long value) +{ +    Statistics::dataUnit dataFormat = (Statistics::dataUnit) ((int) SettingStore::get("DataFormat")); + +    string unitString = Statistics::getUnitString(dataFormat, value); +    float unitFactor = Statistics::getUnitFactor(dataFormat, value); + +    window.print(x, y) << fixed << setprecision(2) << description << ": " << ((float) value / unitFactor) << " " << unitString << endl; +} + +void Device::printStatisticsIn(Window& window, int x, int y) +{ +    // print current traffic +    printTrafficValue(window, x, y, "Curr", m_deviceStatistics.getDataInPerSecond()); +     +    // print average traffic +    printTrafficValue(window, x, y + 1, "Avg", m_deviceStatistics.getDataInAverage()); +     +    // print min traffic since nload start +    printTrafficValue(window, x, y + 2, "Min", m_deviceStatistics.getDataInMin()); +     +    // print max traffic since nload start +    printTrafficValue(window, x, y + 3, "Max", m_deviceStatistics.getDataInMax()); +     +    // print total traffic since last system reboot +    printDataValue(window, x, y + 4, "Ttl", m_deviceStatistics.getDataInTotal()); +} + +void Device::printStatisticsOut(Window& window, int x, int y) +{ +    // print current traffic +    printTrafficValue(window, x, y, "Curr", m_deviceStatistics.getDataOutPerSecond()); +     +    // print average traffic +    printTrafficValue(window, x, y + 1, "Avg", m_deviceStatistics.getDataOutAverage()); +     +    // print min traffic since nload start +    printTrafficValue(window, x, y + 2, "Min", m_deviceStatistics.getDataOutMin()); +     +    // print max traffic since nload start +    printTrafficValue(window, x, y + 3, "Max", m_deviceStatistics.getDataOutMax()); +     +    // print total traffic since last system reboot +    printDataValue(window, x, y + 4, "Ttl", m_deviceStatistics.getDataOutTotal()); +} + diff --git a/src/device.h b/src/device.h new file mode 100644 index 0000000..25d8211 --- /dev/null +++ b/src/device.h @@ -0,0 +1,62 @@ +/*************************************************************************** +                                  device.h +                             ------------------- +    begin                : Wed Aug 1 2001 +    copyright            : (C) 2001 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVICE_H +#define DEVICE_H + +#include "dataframe.h" +#include "graph.h" +#include "statistics.h" + +#include <string> + +class DevReader; +class Window; + +class Device +{ +    public: +        explicit Device(DevReader& devReader); +        ~Device(); + +        void update(); +        void print(Window&); +        void setDeviceNumber(int deviceNumber); +        void setTotalNumberOfDevices(int totalNumberOfDevices); +         +    private: +        void fixOverflows(DataFrame& dataFrame, const DataFrame& dataFrameOld); +        unsigned long long fixOverflow(unsigned long long value, unsigned long long valueOld); + +        void printTrafficValue(Window& window, int x, int y, const std::string& description, unsigned long long value); +        void printDataValue(Window& window, int x, int y, const std::string& description, unsigned long long value); +        void printStatisticsIn(Window& window, int x, int y); +        void printStatisticsOut(Window& window, int x, int y); + +        int m_deviceNumber; +        int m_totalNumberOfDevices; +         +        Statistics m_deviceStatistics; +        Graph m_deviceGraphIn; +        Graph m_deviceGraphOut; + +        DataFrame m_dataFrameOld; +        DevReader& m_devReader; +}; + +#endif + diff --git a/src/devreader-bsd.cpp b/src/devreader-bsd.cpp new file mode 100644 index 0000000..b542704 --- /dev/null +++ b/src/devreader-bsd.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   *  + *                                                                         * + ***************************************************************************/ + +/*************************************************************************** + * Free/Net/OpenBSD specific network code taken out of gkrellm:            * + * Copyright by Bill Wilson <bill@gkrellm.net>                             * + * FreeBSD code by Hajimu Umemoto <ume@mahoroba.org>                       * + * NetBSD code by Anthony Mallet <anthony.mallet@useless-ficus.net>        * + * Hajimu Umemoto merged Free/Net/OpenBSD code                             * + * adapted for nload by Roland Riegel <feedback@roland-riegel.de>          * + ***************************************************************************/ + +#include "devreader-bsd.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <net/if_dl.h> +#include <net/route.h> + +#include <string> +#include <list> + +using namespace std; + +DevReaderBsd::DevReaderBsd(const string& deviceName) +    : DevReader(deviceName) +{ +} + +DevReaderBsd::~DevReaderBsd() +{ +} + +list<string> DevReaderBsd::findAllDevices() +{ +    list<string> interfaceNames; + +    struct if_msghdr *ifm, *nextifm; +    struct sockaddr_dl *sdl; +    char *lim, *next; +    size_t needed; +    int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; +    char *buf = 0; +     +    if(sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) +        return interfaceNames; +             +    buf = (char *) malloc(needed); +    if(buf == NULL) +        return interfaceNames; +             +    if(sysctl(mib, 6, buf, &needed, NULL, 0) < 0) +        return interfaceNames; +             +    lim = buf + needed; +             +    next = buf; +    while(next < lim) +    { +        ifm = (struct if_msghdr *) next; +        if(ifm->ifm_type != RTM_IFINFO) +            break; +                     +        next += ifm->ifm_msglen; +                     +        while(next < lim) +        { +            nextifm = (struct if_msghdr *) next; +            if(nextifm->ifm_type != RTM_NEWADDR) +                break; +            next += nextifm->ifm_msglen; +        } +                     +        sdl = (struct sockaddr_dl *) (ifm + 1); +        if(sdl->sdl_family != AF_LINK) +            continue; +         +        interfaceNames.push_back(string(sdl->sdl_data)); +    } + +    free(buf); + +    return interfaceNames; +} + +void DevReaderBsd::readFromDevice(DataFrame& dataFrame) +{ +    struct if_msghdr *ifm, *nextifm; +    struct sockaddr_dl *sdl; +    char *lim, *next; +    size_t needed; +    int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; +    char *buf = 0; +     +    if(m_deviceName.empty()) +        return; +	 +    do +    { +        if(sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) +            break; +		 +        buf = (char *) malloc(needed); +        if(buf == NULL) +            break; +		 +        if(sysctl(mib, 6, buf, &needed, NULL, 0) < 0) +            break; +		 +        lim = buf + needed; +		 +        next = buf; +        while(next < lim) +        { +            ifm = (struct if_msghdr *) next; +            if(ifm->ifm_type != RTM_IFINFO) +                break; +			 +            next += ifm->ifm_msglen; +			 +            while(next < lim) +            { +                nextifm = (struct if_msghdr *) next; +                if(nextifm->ifm_type != RTM_NEWADDR) +                    break; +                next += nextifm->ifm_msglen; +            } +			 +            if(ifm->ifm_flags & IFF_UP) +            { +                sdl = (struct sockaddr_dl *) (ifm + 1); +                if(sdl->sdl_family != AF_LINK) +                    continue; +                     +                if(strncmp(m_deviceName.c_str(), sdl->sdl_data, sdl->sdl_nlen) == 0) +                { +                    dataFrame.setTotalDataIn(ifm->ifm_data.ifi_ibytes); +                    dataFrame.setTotalDataOut(ifm->ifm_data.ifi_obytes); + +                    dataFrame.setTotalPacketsIn(ifm->ifm_data.ifi_ipackets); +                    dataFrame.setTotalPacketsOut(ifm->ifm_data.ifi_opackets); + +                    dataFrame.setTotalErrorsIn(ifm->ifm_data.ifi_ierrors); +                    dataFrame.setTotalErrorsOut(ifm->ifm_data.ifi_oerrors); + +                    dataFrame.setTotalDropsIn(0); // ifi_iqdrops ? +                    dataFrame.setTotalDropsOut(0); + +                    dataFrame.setValid(true); + +                    break; +                } +            } +        } +    } while(0); +     +    free(buf); +} + diff --git a/src/devreader-bsd.h b/src/devreader-bsd.h new file mode 100644 index 0000000..0907b19 --- /dev/null +++ b/src/devreader-bsd.h @@ -0,0 +1,39 @@ +/*************************************************************************** +                               devreader-bsd.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_BSD_H +#define DEVREADER_BSD_H + +#include "devreader.h" + +#include <string> +#include <list> + +class DevReaderBsd : public DevReader +{ +    public: +        DevReaderBsd(const std::string& deviceName); +        virtual ~DevReaderBsd(); + +        static std::list<std::string> findAllDevices(); +     +    protected: +        void readFromDevice(DataFrame& dataFrame); +}; + +#endif + diff --git a/src/devreader-hpux.cpp b/src/devreader-hpux.cpp new file mode 100644 index 0000000..c1f5403 --- /dev/null +++ b/src/devreader-hpux.cpp @@ -0,0 +1,294 @@ +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   *  + *                                                                         * + ***************************************************************************/ + +/*************************************************************************** + * HP-UX specific network code                                             * + *                                                                         * + * Copyright 1998 by Hewlett-Packard Company                               * + *                                                                         * + * Permission to use, copy, modify, and distribute this                    * + * software and its documentation for any purpose and without              * + * fee is hereby granted, provided that the above copyright                * + * notice appear in all copies and that both that copyright                * + * notice and this permission notice appear in supporting                  * + * documentation, and that the name of Hewlett-Packard Company not         * + * be used in advertising or publicity pertaining to distribution          * + * of the software without specific, written prior permission.             * + * Hewlett-Packard makes no representations about the                      * + * suitability of this software for any purpose.  It is provided           * + * "as is" without express or implied warranty.                            * + *                                                                         * + *                                                                         * + * Modification History:                                                   * + *                                                                         * + * int_stats.c : Get network statistics from the dlpi device               * + * On 10.20 only get a mib_ifEntry, on 11.0 this is followed               * + * by an mib_Dot3StatsEntry. Accessing the latter structure                * + * is left as an exercise for the reader, the struct is defined            * + * in /usr/include/sys/mib.h along with mib_ifEntry.                       * + *                                                                         * + * Author: Jon Dewis, SPP 3/26/98                                          * + * (With ackn to 'lanadmin' source code and streams class notes)           * + *                                                                         * + * 24-June-1998    Add mib3 stats (AJD) when compiling                     * + *                 for 11.0 ensure HP_UX11 macro defined                   * + *                 e.g. cc -o int_stats -DHP_UX11 int_stats.c              * + * 16-Dec-1999     Change to obviate need for lanscan to get               * + *                 nmid - thus assumes any old nmid will do                * + *                 and just iterates thru the 1st 100 possibilities        * + *                 (MAX_NMID). Works on 10.20 and 11.0                     * + * Dec 2003        Modified by Roshan Sequeira roshan.sequeira@hp.com,     * + *                 to get network statistics for the nload port to HP-UX.  * + *                 Original code available at                              * + *                 http://h21007.www2.hp.com/dspp/tech/tech_TechDocumentDetailPage_IDX/1,1701,2599,00.html + *                                                                         * + ***************************************************************************/ + +#include "devreader-hpux.h" +#include "stringutils.h" + +#ifdef HAVE_CONFIG_H +    #include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stropts.h> +#include <sys/dlpi.h> +#include <sys/dlpi_ext.h> +#include <sys/mib.h> + +#include <string> +#include <list> + +using namespace std; + +#define AREA_SIZE 40000 +#define LONG_AREA_SIZE  (AREA_SIZE / sizeof(u_long)) + +static u_long ctrl_area[LONG_AREA_SIZE];        /* for control messages */ +static u_long data_area[LONG_AREA_SIZE];        /* for data messages */ +static u_long ppa_area[LONG_AREA_SIZE];         /* for saving ppa area */ +static struct strbuf ctrl_buf = {AREA_SIZE, 0, (char*) ctrl_area}; +static struct strbuf data_buf = {AREA_SIZE, 0, (char*) data_area}; + +DevReaderHpux::DevReaderHpux(const string& deviceName) +    : DevReader(deviceName) +{ +} + +DevReaderHpux::~DevReaderHpux() +{ +} + +list<string> DevReaderHpux::findAllDevices() +{ +    list<string> devicesFound; +     +    dl_hp_ppa_info_t* ppa_info_temp; +    dl_hp_ppa_req_t* ppa_req; +    dl_hp_ppa_ack_t* ppa_ack; +    dl_attach_req_t* attach_req; +     +    int fd = -1; +    if((fd = open("/dev/dlpi", O_RDWR)) < 0) +    { +        perror("open /dev/dlpi"); +        return devicesFound; +    } +     +    do +    { +        ppa_req = (dl_hp_ppa_req_t*) ctrl_area; +        ppa_ack = (dl_hp_ppa_ack_t*) ctrl_area; +         +        ppa_req->dl_primitive = DL_HP_PPA_REQ; +         +        ctrl_buf.len = sizeof(dl_hp_ppa_req_t); +        if(putmsg(fd, &ctrl_buf, 0, 0) < 0) +        { +            perror("putmsg DL_HP_PPA_REQ"); +            break; +        } +         +        int flags = 0; +        ctrl_area[0] = 0; +         +        if(getmsg(fd, &ctrl_buf, &data_buf, &flags) < 0) +        { +            perror("getmsg DL_HP_PPA_REQ"); +            break; +        } +         +        if(ppa_ack->dl_length == 0) +        { +            fprintf(stderr, "error: no PPAs available\n"); +            break; +        } +         +        // save all the PPA information +        memcpy((u_char*) ppa_area, (u_char*) ctrl_area + ppa_ack->dl_offset, ppa_ack->dl_length); +        int ppa_count = ppa_ack->dl_count; +         +        int count; +        for(count = 0, ppa_info_temp = (dl_hp_ppa_info_t*) ppa_area; count < ppa_count; count++, ppa_info_temp++) +            devicesFound.push_back(string("lan") + toString(ppa_info_temp->dl_ppa)); + +    } while(0); + +    close(fd); + +    return devicesFound; +} + +void DevReaderHpux::readFromDevice(DataFrame& dataFrame) +{ +    dl_get_statistics_req_t* get_statistics_req = (dl_get_statistics_req_t*) ctrl_area; +    dl_get_statistics_ack_t* get_statistics_ack = (dl_get_statistics_ack_t*) ctrl_area; + +    dl_hp_ppa_info_t ppa_info; +    dl_hp_ppa_info_t* ppa_info_temp; +    dl_hp_ppa_req_t* ppa_req; +    dl_hp_ppa_ack_t* ppa_ack; +    dl_attach_req_t* attach_req; +    mib_ifEntry* mib_ptr; +     +    unsigned int ppa = 0; +    int flags = 0, ppa_count = 0, count = 0; +     +    // make sure interface name begins with lan +    if(m_deviceName.length() < 3 || m_deviceName.substr(0, 3) != "lan") +        return; +     +    // get the PPA from the interface name +    ppa = fromString<int>(m_deviceName.substr(3)); +    if(ppa == 0 && m_deviceName != "lan0") +        return; +     +    int fd = -1; +    if((fd = open("/dev/dlpi", O_RDWR)) < 0) +    { +        perror("open /dev/dlpi"); +        return; +    } +     +    do +    { +        ppa_req = (dl_hp_ppa_req_t*) ctrl_area; +        ppa_ack = (dl_hp_ppa_ack_t*) ctrl_area; +         +        ppa_req->dl_primitive = DL_HP_PPA_REQ; +         +        ctrl_buf.len = sizeof(dl_hp_ppa_req_t); +        if(putmsg(fd, &ctrl_buf, 0, 0) < 0) +        { +            perror("putmsg DL_HP_PPA_REQ"); +            break; +        } +         +        flags = 0; +        ctrl_area[0] = 0; +         +        if(getmsg(fd, &ctrl_buf, &data_buf, &flags) < 0) +        { +            perror("getmsg DL_HP_PPA_REQ"); +            break; +        } +         +        if(ppa_ack->dl_length == 0) +        { +            fprintf(stderr, "Error: No PPAs available\n"); +            break; +        } +         +        // save all the PPA information +        memcpy((u_char*) ppa_area, (u_char*) ctrl_area + ppa_ack->dl_offset, ppa_ack->dl_length); +        ppa_count = ppa_ack->dl_count; +         +        bool found = false; +        for(count = 0, ppa_info_temp = (dl_hp_ppa_info_t*) ppa_area; count < ppa_count; count++, ppa_info_temp++) +        { +            if(ppa_info_temp->dl_ppa == ppa) +            { +                found = true; +                break; +            } +        } +        if(!found) +        { +            fprintf(stderr, "error: PPA %d not found\n", ppa); +            break; +        } +         +        attach_req = (dl_attach_req_t*) ctrl_area; +        attach_req->dl_primitive = DL_ATTACH_REQ; +        attach_req->dl_ppa = ppa; +        ctrl_buf.len = sizeof(dl_attach_req_t); +        if(putmsg(fd, &ctrl_buf, 0, 0) < 0) +        { +            perror("putmsg DL_ATTACH_REQ"); +            break; +        } +         +        ctrl_area[0] = 0; +        if(getmsg(fd, &ctrl_buf, &data_buf, &flags) < 0) +        { +            perror("getmsg DL_ATTACH_REQ"); +            break; +        } +        memcpy(&ppa_info, ppa_info_temp, sizeof(ppa_info)); +         +        get_statistics_req->dl_primitive = DL_GET_STATISTICS_REQ; +        ctrl_buf.len = sizeof(dl_get_statistics_req_t); +        flags = 0; +         +        if(putmsg(fd, &ctrl_buf, NULL, 0) < 0) +        { +            perror("putmsg DL_GET_STATISTICS_REQ"); +            break; +        } +         +        if(getmsg(fd, &ctrl_buf, NULL, &flags) < 0) +        { +            perror("getmsg DL_GET_STATISTICS_REQ"); +            break; +        } +        if(get_statistics_ack->dl_primitive != DL_GET_STATISTICS_ACK) +            fprintf(stderr, "error: wrong primitive\n"); + +        mib_ptr = (mib_ifEntry*) ((u_char*) ctrl_area + get_statistics_ack->dl_stat_offset); + +        dataFrame.setTotalDataIn(mib_ptr->ifInOctets); +        dataFrame.setTotalDataOut(mib_ptr->ifOutOctets); + +        dataFrame.setTotalPacketsIn(mib_ptr->ifInUcastPkts + mib_ptr->ifInNUcastPkts); +        dataFrame.setTotalPacketsOut(mib_ptr->ifOutUcastPkts + mib_ptr->ifOutNUcastPkts); + +        dataFrame.setTotalErrorsIn(mib_ptr->ifInErrors); +        dataFrame.setTotalErrorsOut(mib_ptr->ifOutErrors); + +        dataFrame.setTotalDropsIn(mib_ptr->ifInDiscards); +        dataFrame.setTotalDropsOut(mib_ptr->ifOutDiscards); + +        dataFrame.setValid(true); + +    } while(0); + +    close(fd); +} + diff --git a/src/devreader-hpux.h b/src/devreader-hpux.h new file mode 100644 index 0000000..ad57105 --- /dev/null +++ b/src/devreader-hpux.h @@ -0,0 +1,39 @@ +/*************************************************************************** +                              devreader-hpux.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_HPUX_H +#define DEVREADER_HPUX_H + +#include "devreader.h" + +#include <string> +#include <list> + +class DevReaderHpux : public DevReader +{ +    public: +        DevReaderHpux(const std::string& deviceName); +        virtual ~DevReaderHpux(); + +        static std::list<std::string> findAllDevices(); + +    protected: +        void readFromDevice(DataFrame& dataFrame); +}; + +#endif + diff --git a/src/devreader-linux-proc.cpp b/src/devreader-linux-proc.cpp new file mode 100644 index 0000000..2d698b7 --- /dev/null +++ b/src/devreader-linux-proc.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   *  + *                                                                         * + ***************************************************************************/ + +#include "devreader-linux-proc.h" +#include "stringutils.h" + +#include <fstream> +#include <list> +#include <string> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +using namespace std; + +DevReaderLinuxProc::DevReaderLinuxProc(const string& deviceName) +    : DevReader(deviceName) +{ +} + +DevReaderLinuxProc::~DevReaderLinuxProc() +{ +} + +bool DevReaderLinuxProc::isAvailable() +{ +    struct stat procStat; +    if(stat("/proc/net/dev", &procStat) < 0 || ! S_ISREG(procStat.st_mode)) +        return false; + +    return true; +} + +list<string> DevReaderLinuxProc::findAllDevices() +{ +    list<string> interfaceNames; +     +    ifstream fin("/proc/net/dev"); +    if(!fin.is_open()) +        return interfaceNames; +     +    // skip the two header lines +    string line; +    getline(fin, line); +    getline(fin, line); + +    if(!fin.good()) +        return interfaceNames; + +    // read all remaining lines and extract the device name +    while(fin.good()) +    { +        getline(fin, line); +        if(line.empty()) +            continue; + +        string::size_type posEnd = line.find(':'); +        if(posEnd == string::npos) +            continue; + +        interfaceNames.push_back(trim(line.substr(0, posEnd))); +    } +     +    return interfaceNames; +} + +void DevReaderLinuxProc::readFromDevice(DataFrame& dataFrame) +{ +    if(m_deviceName.empty()) +        return; +     +    ifstream fin("/proc/net/dev"); +    if(!fin.is_open()) +        return; +     +    // skip the two header lines +    string line; +    getline(fin, line); +    getline(fin, line); + +    if(!fin.good()) +        return; + +    // search for device +    while(fin.good()) +    { +        getline(fin, line); +        if(line.empty()) +            continue; + +        string::size_type posEnd = line.find(':'); +        if(posEnd == string::npos) +            continue; + +        string interfaceName = trim(line.substr(0, posEnd)); +        if(interfaceName.empty()) +            continue; + +        // check if it is the device we want +        if(m_deviceName != interfaceName) +            continue; + +        // read device data +        unsigned long long bytesIn = 0; +        unsigned long long packetsIn = 0; +        unsigned long long errorsIn = 0; +        unsigned long long dropsIn = 0; +        unsigned long long bytesOut = 0; +        unsigned long long packetsOut = 0; +        unsigned long long errorsOut = 0; +        unsigned long long dropsOut = 0; +        unsigned long long dummy = 0; + +        istringstream sin(trim(line.substr(posEnd + 1))); + +        sin >> bytesIn +            >> packetsIn +            >> errorsIn +            >> dropsIn +            >> dummy +            >> dummy +            >> dummy +            >> dummy +            >> bytesOut +            >> packetsOut +            >> errorsOut +            >> dropsOut; + +        if(sin.fail()) +            break; +         +        dataFrame.setTotalDataIn(bytesIn); +        dataFrame.setTotalDataOut(bytesOut); + +        dataFrame.setTotalPacketsIn(packetsIn); +        dataFrame.setTotalPacketsOut(packetsOut); + +        dataFrame.setTotalErrorsIn(errorsIn); +        dataFrame.setTotalErrorsOut(errorsOut); +         +        dataFrame.setTotalDropsIn(dropsIn); +        dataFrame.setTotalDropsOut(dropsOut); +         +        dataFrame.setValid(true); +         +        break; +    } +} + diff --git a/src/devreader-linux-proc.h b/src/devreader-linux-proc.h new file mode 100644 index 0000000..8e8def6 --- /dev/null +++ b/src/devreader-linux-proc.h @@ -0,0 +1,41 @@ +/*************************************************************************** +                             devreader-linux-proc.h +                             ---------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_LINUX_PROC_H +#define DEVREADER_LINUX_PROC_H + +#include "devreader.h" + +#include <string> +#include <list> + +class DevReaderLinuxProc : public DevReader +{ +    public: +        DevReaderLinuxProc(const std::string& deviceName); +        virtual ~DevReaderLinuxProc(); + +        static bool isAvailable(); +        static std::list<std::string> findAllDevices(); +         +    protected: +        void readFromDevice(DataFrame& dataFrame); +}; + +#endif + + diff --git a/src/devreader-linux-sys.cpp b/src/devreader-linux-sys.cpp new file mode 100644 index 0000000..2fc81fe --- /dev/null +++ b/src/devreader-linux-sys.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   *  + *                                                                         * + ***************************************************************************/ + +#include "devreader-linux-sys.h" + +#include <fstream> +#include <string> +#include <list> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> + +using namespace std; + +DevReaderLinuxSys::DevReaderLinuxSys(const string& deviceName) +    : DevReader(deviceName) +{ +} + +DevReaderLinuxSys::~DevReaderLinuxSys() +{ +} + +bool DevReaderLinuxSys::isAvailable() +{ +    struct stat sysStat; +    if(stat("/sys/class/net", &sysStat) < 0 || ! S_ISDIR(sysStat.st_mode)) +        return false; + +    return true; +} + +list<string> DevReaderLinuxSys::findAllDevices() +{ +    list<string> interfaceNames; +    DIR* sysDir = opendir("/sys/class/net"); +    struct dirent* sysDirEntry = 0; + +    if(!sysDir) +        return interfaceNames; + +    while((sysDirEntry = readdir(sysDir))) +    { +        string interfaceName(sysDirEntry->d_name); +         +        if(interfaceName[0] == '.') +            continue; +                 +        interfaceNames.push_back(interfaceName); +    } + +    closedir(sysDir); + +    return interfaceNames; +} + +void DevReaderLinuxSys::readFromDevice(DataFrame& dataFrame) +{ +    string devPath = "/sys/class/net/"; +    devPath += m_deviceName; +     +    struct stat sysStat; +    if(stat(devPath.c_str(), &sysStat) < 0 || ! S_ISDIR(sysStat.st_mode)) +        return; + +    dataFrame.setTotalDataIn(readULongSysEntry("statistics/rx_bytes")); +    dataFrame.setTotalDataOut(readULongSysEntry("statistics/tx_bytes")); + +    dataFrame.setTotalPacketsIn(readULongSysEntry("statistics/rx_packets")); +    dataFrame.setTotalPacketsOut(readULongSysEntry("statistics/tx_packets")); + +    dataFrame.setTotalErrorsIn(readULongSysEntry("statistics/rx_errors")); +    dataFrame.setTotalErrorsOut(readULongSysEntry("statistics/tx_errors")); +     +    dataFrame.setTotalDropsIn(readULongSysEntry("statistics/rx_dropped")); +    dataFrame.setTotalDropsOut(readULongSysEntry("statistics/tx_dropped")); +     +    dataFrame.setValid(true); +} + +unsigned long long DevReaderLinuxSys::readULongSysEntry(const string& entry) +{ +    string sysEntryPath = "/sys/class/net/"; +    sysEntryPath += m_deviceName; +    sysEntryPath += '/'; +    sysEntryPath += entry; +     +    ifstream sysEntry(sysEntryPath.c_str()); +    if(!sysEntry.is_open()) +        return 0; + +    unsigned long long num = 0; +    sysEntry >> num; +    if(sysEntry.fail()) +        return 0; + +    return num; +} + + diff --git a/src/devreader-linux-sys.h b/src/devreader-linux-sys.h new file mode 100644 index 0000000..c945516 --- /dev/null +++ b/src/devreader-linux-sys.h @@ -0,0 +1,43 @@ +/*************************************************************************** +                             devreader-linux-sys.h +                             --------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_LINUX_SYS_H +#define DEVREADER_LINUX_SYS_H + +#include "devreader.h" + +#include <string> +#include <list> + +class DevReaderLinuxSys : public DevReader +{ +    public: +        DevReaderLinuxSys(const std::string& deviceName); +        virtual ~DevReaderLinuxSys(); + +        static bool isAvailable(); +        static std::list<std::string> findAllDevices(); +         +    protected: +        void readFromDevice(DataFrame& dataFrame); + +    private: +        unsigned long long readULongSysEntry(const std::string& entry); +}; + +#endif + diff --git a/src/devreader-linux.cpp b/src/devreader-linux.cpp new file mode 100644 index 0000000..5b6e9eb --- /dev/null +++ b/src/devreader-linux.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   *  + *                                                                         * + ***************************************************************************/ + +#include "devreader-linux.h" +#include "devreader-linux-proc.h" +#include "devreader-linux-sys.h" + +#include <string> +#include <list> + +using namespace std; + +bool DevReaderLinux::isAvailable() +{ +    return DevReaderLinuxSys::isAvailable() || DevReaderLinuxProc::isAvailable(); +} + +list<string> DevReaderLinux::findAllDevices() +{ +    if(DevReaderLinuxSys::isAvailable()) +        return DevReaderLinuxSys::findAllDevices(); +    else if(DevReaderLinuxProc::isAvailable()) +        return DevReaderLinuxProc::findAllDevices(); +    else +        return list<string>(); +} + diff --git a/src/devreader-linux.h b/src/devreader-linux.h new file mode 100644 index 0000000..4fea735 --- /dev/null +++ b/src/devreader-linux.h @@ -0,0 +1,32 @@ +/*************************************************************************** +                              devreader-linux.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_LINUX_H +#define DEVREADER_LINUX_H + +#include <string> +#include <list> + +class DevReaderLinux +{ +    public: +        static bool isAvailable(); +        static std::list<std::string> findAllDevices(); +}; + +#endif + diff --git a/src/devreader-solaris.cpp b/src/devreader-solaris.cpp new file mode 100644 index 0000000..478b3ca --- /dev/null +++ b/src/devreader-solaris.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   *  + *                                                                         * + ***************************************************************************/ + +/*************************************************************************** + * Solaris specific network code taken out of gkrellm                      * + * Copyright by Bill Wilson <bill@gkrellm.net>                             * + * Solaris code by Daisuke Yabuki <dxy@acm.org>                            * + * adapted for nload by Roland Riegel <feedback@roland-riegel.de>          * + ***************************************************************************/ + +#include "devreader-solaris.h" + +#include <string.h> +#include <kstat.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <string> +#include <list> + +using namespace std; + +DevReaderSolaris::DevReaderSolaris(const string& deviceName) +    : DevReader(deviceName) +{ +} + +DevReaderSolaris::~DevReaderSolaris() +{ +} + +list<string> DevReaderSolaris::findAllDevices() +{ +    list<string> interfaceNames; +    struct if_nameindex* interfaces = if_nameindex(); + +    if(!interfaces) +        return interfaceNames; + +    int i = 0; +    while(interfaces[i].if_name) +    { +        interfaceNames.push_back(string(interfaces[i].if_name)); +        ++i; +    } + +    if_freenameindex(interfaces); + +    return interfaceNames; +} + +void DevReaderSolaris::readFromDevice(DataFrame& dataFrame) +{ +    kstat_ctl_t *kc; +    kstat_t *ksp; +    kstat_named_t *knp; +    char* devName = 0; + +    if(m_deviceName.empty()) +        return; +     +    devName = (char*) malloc(m_deviceName.length() + 1); +    strncpy(devName, m_deviceName.c_str(), m_deviceName.length()); +    devName[m_deviceName.length()] = '\0'; +     +    kc = kstat_open(); +    ksp = kstat_lookup(kc, NULL, -1, devName); +    if(ksp && kstat_read(kc, ksp, NULL) >= 0) +    { +        knp = (kstat_named_t *) kstat_data_lookup(ksp, "rbytes"); +        dataFrame.setTotalDataIn(knp ? knp->value.ui32 : 0); + +        knp = (kstat_named_t *) kstat_data_lookup(ksp, "obytes"); +        dataFrame.setTotalDataOut(knp ? knp->value.ui32 : 0); + +        knp = (kstat_named_t *) kstat_data_lookup(ksp, "ipackets"); +        dataFrame.setTotalPacketsIn(knp ? knp->value.ui32 : 0); +         +        knp = (kstat_named_t *) kstat_data_lookup(ksp, "opackets"); +        dataFrame.setTotalPacketsOut(knp ? knp->value.ui32 : 0); +         +        knp = (kstat_named_t *) kstat_data_lookup(ksp, "ierrors"); +        dataFrame.setTotalErrorsIn(knp ? knp->value.ui32 : 0); +         +        knp = (kstat_named_t *) kstat_data_lookup(ksp, "oerrors"); +        dataFrame.setTotalErrorsOut(knp ? knp->value.ui32 : 0); +         +        dataFrame.setValid(true); +    } + +    kstat_close(kc); +    free(devName); +    devName = 0; +} + diff --git a/src/devreader-solaris.h b/src/devreader-solaris.h new file mode 100644 index 0000000..027c7fa --- /dev/null +++ b/src/devreader-solaris.h @@ -0,0 +1,39 @@ +/*************************************************************************** +                             devreader-solaris.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_SOLARIS_H +#define DEVREADER_SOLARIS_H + +#include "devreader.h" + +#include <string> +#include <list> + +class DevReaderSolaris : public DevReader +{ +    public: +        DevReaderSolaris(const std::string& deviceName); +        virtual ~DevReaderSolaris(); + +        static std::list<std::string> findAllDevices(); + +    protected: +        void readFromDevice(DataFrame& dataFrame); +}; + +#endif + diff --git a/src/devreader.cpp b/src/devreader.cpp new file mode 100644 index 0000000..5006309 --- /dev/null +++ b/src/devreader.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** +                                devreader.cpp +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "devreader.h" + +#include <config.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <time.h> +#include <net/if.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_SOLARIS +    #include <sys/sockio.h> +#endif + +using namespace std; + +DevReader::DevReader(const string& deviceName) +    : m_deviceName(deviceName) +{ +} + +DevReader::~DevReader() +{ +} + +const string& DevReader::getDeviceName() const +{ +    return m_deviceName; +} + +DataFrame DevReader::getNewDataFrame() +{ +    DataFrame deviceData; + +    struct timeval tv; +    gettimeofday(&tv, 0); +     +    readFromDevice(deviceData); +     +    deviceData.setDeviceName(m_deviceName); + +    deviceData.setTimeStampSeconds((unsigned long) tv.tv_sec); +    deviceData.setTimeStampMicroseconds((unsigned long) tv.tv_usec); + +    deviceData.setIpV4(getDeviceIp4Address()); + +    return deviceData; +} + +string DevReader::getDeviceIp4Address() +{ +    struct ifreq ifr; +    int sk; +     +    string deviceIp = ""; +     +    if(m_deviceName.empty()) +        return deviceIp; +     +    /* create a temporary socket: ioctl needs one */ +    if((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) +        return deviceIp; +     +    /* copy the device name into the ifreq structure */ +    strncpy(ifr.ifr_name, m_deviceName.c_str(), IFNAMSIZ - 1); +    ifr.ifr_name[IFNAMSIZ - 1] = 0; +     +    /* make the request */ +    if(!ioctl(sk, SIOCGIFADDR, &ifr)) +    { +        struct sockaddr_in sin; +        memcpy(&sin, &ifr.ifr_addr, sizeof(sin)); +         +        /* only use the IP number if the address family is really IPv4 */ +        if(sin.sin_family == AF_INET) +            deviceIp = inet_ntoa(sin.sin_addr); +    } +     +    /* close the temporary socket */ +    close(sk); +     +    return deviceIp; +} + diff --git a/src/devreader.h b/src/devreader.h new file mode 100644 index 0000000..c4631ce --- /dev/null +++ b/src/devreader.h @@ -0,0 +1,42 @@ +/*************************************************************************** +                                 devreader.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADER_H +#define DEVREADER_H + +#include <string> + +#include "dataframe.h" + +class DevReader +{ +    public: +        DevReader(const std::string& deviceName); +        virtual ~DevReader(); + +        const std::string& getDeviceName() const; +        DataFrame getNewDataFrame(); + +    protected: +        virtual void readFromDevice(DataFrame& dataFrame) = 0; +        std::string getDeviceIp4Address(); +         +        std::string m_deviceName; +}; + +#endif + diff --git a/src/devreaderfactory.cpp b/src/devreaderfactory.cpp new file mode 100644 index 0000000..c2fc656 --- /dev/null +++ b/src/devreaderfactory.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** +                             devreaderfactory.cpp +                             -------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "devreaderfactory.h" + +#include "config.h" + +#include "devreader.h" +#include "devreader-bsd.h" +#include "devreader-hpux.h" +#include "devreader-linux-proc.h" +#include "devreader-linux-sys.h" +#include "devreader-linux.h" +#include "devreader-solaris.h" + +#include <string> +#include <list> +#include <map> + +using namespace std; + +map<string, DevReader*> DevReaderFactory::m_devReaders; +DevReaderFactory DevReaderFactory::m_instance; + +DevReaderFactory::DevReaderFactory() +{ +} + +DevReaderFactory::~DevReaderFactory() +{ +    for(map<string, DevReader*>::const_iterator it = m_devReaders.begin(); it != m_devReaders.end(); ++it) +        delete it->second; + +    m_devReaders.clear(); +} + +int DevReaderFactory::findAllDevices() +{ +#if defined HAVE_BSD +    list<string> interfaceNames = DevReaderBsd::findAllDevices(); +#elif defined HAVE_HPUX +    list<string> interfaceNames = DevReaderHpux::findAllDevices(); +#elif defined HAVE_LINUX +    list<string> interfaceNames = DevReaderLinux::findAllDevices(); +#elif defined HAVE_SOLARIS +    list<string> interfaceNames = DevReaderSolaris::findAllDevices(); +#endif + +    map<string, DevReader*>::iterator devReaderIt = m_devReaders.begin(); +    while(devReaderIt != m_devReaders.end()) +    { +        list<string>::iterator interfaceIt = interfaceNames.begin(); +        list<string>::iterator interfaceItEnd = interfaceNames.end(); +         +        while(*interfaceIt != devReaderIt->first && interfaceIt != interfaceItEnd) +            ++interfaceIt; + +        // delete all devices which disappeared +        if(interfaceIt == interfaceItEnd) +        { +            delete devReaderIt->second; +            m_devReaders.erase(devReaderIt++); +        } +        // delete all entries in the interface name list which we know of already +        else +        { +            interfaceNames.erase(interfaceIt); +            devReaderIt++; +        } +    } +     +    // the interface name list now contains only devices which just appeared in the system +    for(list<string>::const_iterator it = interfaceNames.begin(); it != interfaceNames.end(); ++it) +    { +        DevReader* newReader = createDevReader(*it); +        if(newReader) +            m_devReaders[*it] = newReader; +    } +     +    return m_devReaders.size(); +} + +int DevReaderFactory::getDeviceCount() +{ +    return m_devReaders.size(); +} + +const map<string, DevReader*>& DevReaderFactory::getAllDevReaders() +{ +    return m_devReaders; +} + +DevReader* DevReaderFactory::createDevReader(const string& deviceName) +{ +    DevReader* reader = 0; +     +#if defined HAVE_BSD +    reader = new DevReaderBsd(deviceName); +#elif defined HAVE_HPUX +    reader = new DevReaderHpux(deviceName); +#elif defined HAVE_LINUX +    if(DevReaderLinuxSys::isAvailable()) +        reader = new DevReaderLinuxSys(deviceName); +    else if(DevReaderLinuxProc::isAvailable()) +        reader = new DevReaderLinuxProc(deviceName); +    else +        reader = 0; +#elif defined HAVE_SOLARIS +    reader = new DevReaderSolaris(deviceName); +#endif + +    return reader; +} + diff --git a/src/devreaderfactory.h b/src/devreaderfactory.h new file mode 100644 index 0000000..d9d2e5c --- /dev/null +++ b/src/devreaderfactory.h @@ -0,0 +1,45 @@ +/*************************************************************************** +                             devreaderfactory.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef DEVREADERFACTORY_H +#define DEVREADERFACTORY_H + +#include <string> +#include <map> + +class DevReader; + +class DevReaderFactory +{ +    public: +        DevReaderFactory(); +        ~DevReaderFactory(); + +        static int findAllDevices(); +        static int getDeviceCount(); +         +        static const std::map<std::string, DevReader*>& getAllDevReaders(); + +    private: +        static DevReader* createDevReader(const std::string& deviceName); +         +        static std::map<std::string, DevReader*> m_devReaders; +        static DevReaderFactory m_instance; +}; + +#endif + diff --git a/src/form_field.cpp b/src/form_field.cpp new file mode 100644 index 0000000..03b70f7 --- /dev/null +++ b/src/form_field.cpp @@ -0,0 +1,237 @@ +/*************************************************************************** +                               form_field.cpp +                             ------------------- +    begin                : Tue Jul 30 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "form_field.h" +#include "window.h" + +using namespace std; + +Field::Field(int x, int y, int width, int height) : m_field(0) +{ +    m_field = new_field(height, width, y, x, 0, 0); +    set_field_opts(m_field, field_opts(m_field) | O_BLANK | O_PASSOK); + +    m_enumElementsArray = 0; +} + +Field::~Field() +{ +    setEnumField(vector<string>()); +    free_field(m_field); +} + +void Field::setText(const string& text) +{ +    set_field_buffer(m_field, 0, text.c_str()); +} + +string Field::getText() +{ +    return field_buffer(m_field, 0); +} + +void Field::move(int x, int y) +{ +    move_field(m_field, y, x); +} + +void Field::setVisible(bool new_visible) +{ +    set_field_opts(m_field, new_visible ? field_opts(m_field) | O_VISIBLE : field_opts(m_field) & ~O_VISIBLE); +} + +bool Field::isVisible() +{ +    return (field_opts(m_field) & O_VISIBLE) == O_VISIBLE; +} + +void Field::setEnabled(bool new_enabled) +{ +    set_field_opts(m_field, new_enabled ? field_opts(m_field) | O_ACTIVE : field_opts(m_field) & ~O_ACTIVE); +} + +bool Field::isEnabled() +{ +    return (field_opts(m_field) & O_ACTIVE) == O_ACTIVE; +} + +void Field::setIntegerField(int min, int max) +{ +    set_field_type(m_field, TYPE_INTEGER, 0, min, max); +} + +void Field::setEnumField(const vector<string>& elements) +{ +    if(elements.empty()) +    { +        set_field_type(m_field, TYPE_ALNUM, 0); + +        if(m_enumElementsArray) +            delete[] m_enumElementsArray; +        m_enumElementsArray = 0; + +        m_enumElements.clear(); + +        return; +    } + +    m_enumElements = elements; + +    if(m_enumElementsArray) +        delete[] m_enumElementsArray; +    m_enumElementsArray = new const char*[m_enumElements.size() + 1]; + +    for(vector<string>::const_iterator itElement = m_enumElements.begin(); itElement != m_enumElements.end(); ++itElement) +        m_enumElementsArray[itElement - m_enumElements.begin()] = itElement->c_str(); +    m_enumElementsArray[elements.size()] = 0; + +    set_field_type(m_field, TYPE_ENUM, m_enumElementsArray, 0, 0); +} + +void Field::setFixed(bool new_fixed) +{ +    set_field_opts(m_field, new_fixed ? field_opts(m_field) & ~O_EDIT : field_opts(m_field) | O_EDIT); +} + +bool Field::isFixed() +{ +    return (field_opts(m_field) & O_EDIT) != O_EDIT; +} + +void Field::setFirstOnPage(bool new_newpage) +{ +    set_new_page(m_field, new_newpage); +} + +bool Field::isFirstOnPage() +{ +    return new_page(m_field); +} + +bool operator==(const Field& field1, const Field& field2) +{ +    return field1.m_field == field2.m_field; +} + +bool operator==(const Field& field1, const FIELD* field2) +{ +    return field1.m_field == field2; +} + + +Form::Form(Slots* slots) +    : m_slots(slots), m_form(0), m_visible(false) +{ +} + +Form::~Form() +{ +} + +vector<Field*>& Form::fields() +{ +    return m_fields; +} +     +void Form::show(Window* main_window, SubWindow* sub_window) +{ +    if(m_form) +        return; + +    m_curses_fields = new FIELD* [ m_fields.size() ]; +    vector<Field*>::const_iterator r = m_fields.begin();  +    int i = 0; +    while(r != m_fields.end()) +    { +        m_curses_fields[i] = (*r)->m_field; +        r++; i++; +    } +     +    m_curses_fields[m_fields.size()] = 0; +    m_form = new_form(m_curses_fields); +     +    if(!m_form) +        return; +     +    set_form_userptr(m_form, this); +    set_form_win(m_form, main_window->m_window); +    set_form_sub(m_form, sub_window->m_window); +    set_field_term(m_form, fieldChanged); +     +    post_form(m_form); +     +    m_visible = true; +} + +void Form::hide() +{ +    if(!m_form) +        return; + +    unpost_form(m_form); +    free_form(m_form); +    m_form = 0; +     +    delete[] m_curses_fields; +    m_curses_fields = 0; +     +    m_visible = false; +} + +bool Form::isVisible() +{ +    return m_visible; +} + +void Form::processKey(int key) +{ +    if(m_form) +        form_driver(m_form, key); +} + +int Form::getPage() +{ +    if(!m_form) +        return 0; +    return form_page(m_form); +} + +int Form::getPageCount() +{ +    int pages = 0; +    for(vector<Field*>::const_iterator i = m_fields.begin(); i != m_fields.end(); i++) +    { +        if((*i)->isFirstOnPage()) +            pages++; +    } +    return pages; +} + +void Form::fieldChanged(FORM* form) +{ +    Form* f = (Form*) form_userptr(form); +    if(!f) +        return; + +    if(f->m_slots) +    { +        for(vector<Field*>::const_iterator i = f->m_fields.begin(); i != f->m_fields.end(); ++i) +            if((*i)->m_field == current_field(form)) +                f->m_slots->slot_fieldChanged(*i); +    } +} + diff --git a/src/form_field.h b/src/form_field.h new file mode 100644 index 0000000..7ce2734 --- /dev/null +++ b/src/form_field.h @@ -0,0 +1,110 @@ +/*************************************************************************** +                                form_field.h +                             ------------------- +    begin                : Sat Jul 27 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef FORM_FIELD_H +#define FORM_FIELD_H + +#include <curses.h> +#include <form.h> +#undef clear +#undef erase +#undef refresh + +#include <string> +#include <vector> + +class Window; +class SubWindow; +class Form; + +class Field +{ +    public: +        Field(int x, int y, int width, int height); +        ~Field(); + +        void setText(const std::string& text); +        std::string getText(); +         +        void move(int x, int y); +         +        void setVisible(bool new_visible); +        bool isVisible(); +         +        void setEnabled(bool new_enabled); +        bool isEnabled(); +         +        void setIntegerField(int min, int max); +        void setEnumField(const std::vector<std::string>& elements); +         +        void setFixed(bool new_fixed); +        bool isFixed(); +         +        void setFirstOnPage(bool new_newpage); +        bool isFirstOnPage(); +         +        friend bool operator==(const Field& field1, const Field& field2); +        friend bool operator==(const Field& field1, const FIELD* field2); +         +    private: +        friend class Form; + +        FIELD* m_field; +        std::vector<std::string> m_enumElements; +        const char** m_enumElementsArray; +}; + +class Form +{ +    public: +        class Slots +        { +            public: +                Slots() {} +                virtual ~Slots() {} +                virtual void slot_fieldChanged(Field* field) {} +        }; +         +        Form(Slots* slots = 0); +        ~Form(); +         +        std::vector<Field *>& fields(); +         +        void show(Window* main_window, SubWindow* sub_window); +        void hide(); + +        void processKey(int key); +         +        bool isVisible(); +         +        int getPage(); +        int getPageCount(); +         +    private: +        Slots* m_slots; +         +        FORM* m_form; +        FIELD** m_curses_fields; +        std::vector<Field *> m_fields; + +        bool m_visible; +         +        static void fieldChanged(FORM* form); +}; + +#endif + diff --git a/src/graph.cpp b/src/graph.cpp new file mode 100644 index 0000000..f0b4e8b --- /dev/null +++ b/src/graph.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** +                                 graph.cpp +                             ------------------- +    begin                : Sat Sep 29 2001 +    copyright            : (C) 2001 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "graph.h" +#include "setting.h" +#include "settingstore.h" +#include "window.h" + +using namespace std; + +Graph::Graph() +    : m_heightOfBars(5), m_maxDeflection(10 * 1024 * 1024 / 8) +{ +} + +Graph::~Graph() +{ +} + +// sets the number of the graph's vertical #-bars +void Graph::setNumOfBars(unsigned int numOfBars) +{ +    // vertically resize the graph's value list +    m_values.resize(numOfBars); +} + +// sets the height of the graph's vertical #-bars +void Graph::setHeightOfBars(unsigned int heightOfBars) +{ +    m_heightOfBars = heightOfBars; +} + +void Graph::setMaxDeflection(unsigned long long maxDeflection) +{ +    m_maxDeflection = maxDeflection; +} + +// new traffic measurement has been made => update the graph's value list +void Graph::update(unsigned long long value) +{ +    // [new_value] = Bytes/s +     +    // put new value to the beginning of the list, it becomes the first #-bar +    m_values.push_front(value); + +    // delete the last #-bar of the list, but keep at least one +    if(m_values.size() > 1) +        m_values.pop_back(); +} + +// print the graph with the upper left corner at the coordinates (x, y) +void Graph::print(Window& window, int x, int y) +{ +    window.setXY(x, y); +     +    // cycle through through the lines +    for(unsigned int l = 0; l < m_heightOfBars; l++) +    { +        // for each line cycle through the rows +        for(list<unsigned long long>::reverse_iterator r = m_values.rbegin(); r != m_values.rend() ; r++) +        { +            unsigned long long trafficPerLine = m_maxDeflection / m_heightOfBars; +            unsigned long long lowerLimit = m_maxDeflection * (m_heightOfBars - l - 1) / m_heightOfBars; + +            if(*r < lowerLimit) +            { +                window.print(' '); +            } +            else  +            { +                unsigned long long restOfTraffic = *r - lowerLimit; + +                if(restOfTraffic >= trafficPerLine) +                    window.print('#'); +                else if(restOfTraffic >= trafficPerLine * 7 / 10) +                    window.print('|'); +                else if(restOfTraffic >= trafficPerLine * 3 / 10) +                    window.print('.'); +                else +                    window.print(' '); +            } +        } +        window.print('\n'); +        window.setX(x); +    } +     +} + +// reset all traffic values in the graph to zero +void Graph::resetTrafficData() +{ +    int size = m_values.size(); +    m_values.clear(); +    m_values.resize(size); +} + diff --git a/src/graph.h b/src/graph.h new file mode 100644 index 0000000..1e493b3 --- /dev/null +++ b/src/graph.h @@ -0,0 +1,45 @@ +/*************************************************************************** +                                  graph.h +                             ------------------- +    begin                : Sat Sep 29 2001 +    copyright            : (C) 2001 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef GRAPH_H +#define GRAPH_H + +#include <list> + +class Window; + +class Graph +{ +    public: +        Graph(); +        ~Graph(); +         +        void setNumOfBars(unsigned int numOfBars); +        void setHeightOfBars(unsigned int heightOfBars); +        void setMaxDeflection(unsigned long long maxDeflection); +         +        void update(unsigned long long value); +        void print(Window& window, int x, int y); +        void resetTrafficData(); + +    private: +        unsigned int m_heightOfBars; +        unsigned long long m_maxDeflection; +        std::list<unsigned long long> m_values; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c53e142 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,583 @@ +/*************************************************************************** +                                  main.cpp +                             ------------------- +    begin                : Wed Jul 25 2001 +    copyright            : (C) 2001 - 2012 by Roland Riegel  +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ +/* + * nload + * real time monitor for network traffic + * Copyright (C) 2001 - 2012 Roland Riegel <feedback@roland-riegel.de> + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +    #include <config.h> +#endif + +#include "device.h" +#include "devreader.h" +#include "devreaderfactory.h" +#include "graph.h" +#include "main.h" +#include "screen.h" +#include "setting.h" +#include "settingfilter.h" +#include "settingstore.h" + +#include <cstdlib> +#include <iostream> +#include <string> +#include <vector> + +#include <ctype.h> +#include <time.h> +#include <curses.h> +#include <signal.h> +#include <string.h> +#undef clear +#undef erase +#undef refresh + +#define STANDARD_AVERAGE_WINDOW 300 +#define STANDARD_DATA_FORMAT Statistics::humanReadableByte +#define STANDARD_HIDE_GRAPHS false +#define STANDARD_MAX_DEFLECTION 10240 +#define STANDARD_REFRESH_INTERVAL 500 +#define STANDARD_TRAFFIC_FORMAT Statistics::humanReadableBit + +using namespace std; + +static OptWindow m_optWindow; +static TrafficWindow m_mainWindow; + +static bool quit = false; + +int main(int argc, char *argv[]) +{ +    SettingStore::add(Setting("AverageWindow", "Window length for average (s)", STANDARD_AVERAGE_WINDOW)); +    SettingStore::add(Setting("BarMaxIn", "Max Incoming deflection (kBit/s)", STANDARD_MAX_DEFLECTION)); +    SettingStore::add(Setting("BarMaxOut", "Max Outgoing deflection (kBit/s)", STANDARD_MAX_DEFLECTION)); +    SettingStore::add(Setting("DataFormat", "Unit for data numbers", STANDARD_DATA_FORMAT)); +    SettingStore::add(Setting("Devices", "Devices to show", "all")); +    SettingStore::add(Setting("MultipleDevices", "Show multiple devices", STANDARD_HIDE_GRAPHS)); +    SettingStore::add(Setting("RefreshInterval", "Refresh interval (ms)", STANDARD_REFRESH_INTERVAL)); +    SettingStore::add(Setting("TrafficFormat", "Unit for traffic numbers", STANDARD_TRAFFIC_FORMAT)); + +    SettingStore::get("AverageWindow").pushFilter(new SettingFilterMin(5)); +    SettingStore::get("BarMaxIn").pushFilter(new SettingFilterMin(10)); +    SettingStore::get("BarMaxOut").pushFilter(new SettingFilterMin(10)); +    SettingStore::get("RefreshInterval").pushFilter(new SettingFilterMin(50)); + +    SettingStore::get("Devices").pushFilter(new SettingFilterDefault("all")); +    SettingStore::get("Devices").pushFilter(new SettingFilterExclusive("all")); + +    map<string, string> valueMapping; + +    valueMapping[toString(false)] = "[ ]"; +    valueMapping[toString(true)] = "[x]"; +    SettingStore::get("MultipleDevices").pushFilter(new SettingFilterMap(valueMapping)); +    valueMapping.clear(); + +    valueMapping[toString(Statistics::humanReadableBit)] = "Human Readable (Bit)"; +    valueMapping[toString(Statistics::humanReadableByte)] = "Human Readable (Byte)"; +    valueMapping[toString(Statistics::bit)] = "Bit"; +    valueMapping[toString(Statistics::byte)] = "Byte"; +    valueMapping[toString(Statistics::kiloBit)] = "kBit"; +    valueMapping[toString(Statistics::kiloByte)] = "kByte"; +    valueMapping[toString(Statistics::megaBit)] = "MBit"; +    valueMapping[toString(Statistics::megaByte)] = "MByte"; +    valueMapping[toString(Statistics::gigaBit)] = "GBit"; +    valueMapping[toString(Statistics::gigaByte)] = "GByte"; +    SettingStore::get("TrafficFormat").pushFilter(new SettingFilterMap(valueMapping)); +    SettingStore::get("DataFormat").pushFilter(new SettingFilterMap(valueMapping)); +    valueMapping.clear(); + +    // retrieve home directory +    const char* homeDirArray = getenv("HOME"); +    if(!homeDirArray) +    { +        cerr << "Could not retrieve home directory." << endl; +        exit(1); +    } + +    string homeDir = homeDirArray; +    SettingStore::readFromFile(SYSCONFDIR "/nload.conf"); +    SettingStore::readFromFile(homeDir + "/.nload"); + +    // parse the command line +    bool deleteDevicesRequested = true; +    for(int i = 1; i < argc; i++) +    { +        // does the user want help? +        if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) +        { +            printHelp(false); +            exit(0); +        } +        // has the user set a non-default average time window? +        else if(strcmp(argv[i], "-a") == 0) +        { +            Setting& setting = SettingStore::get("AverageWindow"); +             +            if(i < argc - 1 && isdigit(argv[ i + 1 ][0]) != 0) +            { +                setting = atoi(argv[ i + 1 ]); +                if(setting < 1) +                    setting = STANDARD_AVERAGE_WINDOW; + +                i++; +            } +            else +            { +                cerr << "Wrong argument for the -a parameter." << endl; +                printHelp(true); +                exit(1); +            } +        } +        // has the user set a non-default 100% mark for +        // the incoming bandwidth bar? +        else if(strcmp(argv[i], "-i") == 0) +        { +            Setting& setting = SettingStore::get("BarMaxIn"); +             +            if(i < argc - 1 && isdigit(argv[ i + 1 ][0]) != 0) +            { +                setting = atol(argv[ i + 1 ]); +                if(setting == 0) +                    setting = STANDARD_MAX_DEFLECTION; + +                i++; +            } +            else +            { +                cerr << "Wrong argument for the -i parameter." << endl; +                printHelp(true); +                exit(1); +            } +        } +        // has the user set a non-default 100% mark for +        // the outgoing bandwidth bar? +        else if(strcmp(argv[i], "-o") == 0) +        { +            Setting& setting = SettingStore::get("BarMaxOut"); +             +            if(i < argc - 1 && isdigit(argv[ i + 1 ][0]) != 0) +            { +                setting = atol(argv[ i + 1 ]); +                if(setting == 0) +                    setting = STANDARD_MAX_DEFLECTION; + +                i++; +            } +            else +            { +                cerr << "Wrong argument for the -o parameter." << endl; +                printHelp(true); +                exit(1); +            } +        } +        // has the user set a non-default refresh interval? +        else if(strcmp(argv[i], "-t") == 0) +        { +            Setting& setting = SettingStore::get("RefreshInterval"); +             +            if(i < argc - 1 && isdigit(argv[ i + 1 ][0]) != 0) +            { +                setting = atoi(argv[ i + 1 ]); +                if(setting == 0) +                    setting = STANDARD_REFRESH_INTERVAL; + +                i++; +            } +            else +            { +                cerr << "Wrong argument for the -t parameter." << endl; +                printHelp(true); +                exit(1); +            } +        } +        // has the user set a non-default unit for traffic numbers? +        else if(strcmp(argv[i], "-u") == 0) +        { +            Setting& setting = SettingStore::get("TrafficFormat"); +             +            if(i < argc - 1 && isalpha(argv[ i + 1 ][0]) != 0) +            { +                switch(argv[ i + 1 ][0]) +                { +                    case 'H': +                        setting = Statistics::humanReadableByte; +                        break; +                    case 'h': +                        setting = Statistics::humanReadableBit; +                        break; +                    case 'B': +                        setting = Statistics::byte; +                        break; +                    case 'b': +                        setting = Statistics::bit; +                        break; +                    case 'K': +                        setting = Statistics::kiloByte; +                        break; +                    case 'k': +                        setting = Statistics::kiloBit; +                        break; +                    case 'M': +                        setting = Statistics::megaByte; +                        break; +                    case 'm': +                        setting = Statistics::megaBit; +                        break; +                    case 'G': +                        setting = Statistics::gigaByte; +                        break; +                    case 'g': +                        setting = Statistics::gigaBit; +                        break; +                    default: +                        cerr << "Wrong argument for the -u parameter." << endl; +                        printHelp(true); +                        exit(1); +                } + +                i++; +            } +            else +            { +                cerr << "Wrong argument for the -u parameter." << endl; +                printHelp(true); +                exit(1); +            } +        } +        // has the user set a non-default unit for numbers of amount of data? +        else if(strcmp(argv[i], "-U") == 0) +        { +            Setting& setting = SettingStore::get("DataFormat"); +             +            if(i < argc - 1 && isalpha(argv[ i + 1 ][0]) != 0) +            { +                switch(argv[ i + 1 ][0]) +                { +                    case 'H': +                        setting = Statistics::humanReadableByte; +                        break; +                    case 'h': +                        setting = Statistics::humanReadableBit; +                        break; +                    case 'B': +                        setting = Statistics::byte; +                        break; +                    case 'b': +                        setting = Statistics::bit; +                        break; +                    case 'K': +                        setting = Statistics::kiloByte; +                        break; +                    case 'k': +                        setting = Statistics::kiloBit; +                        break; +                    case 'M': +                        setting = Statistics::megaByte; +                        break; +                    case 'm': +                        setting = Statistics::megaBit; +                        break; +                    case 'G': +                        setting = Statistics::gigaByte; +                        break; +                    case 'g': +                        setting = Statistics::gigaBit; +                        break; +                    default: +                        cerr << "Wrong argument for the -U parameter." << endl; +                        printHelp(true); +                        exit(1); +                } + +                i++; +            } +            else +            { +                cerr << "Wrong argument for the -U parameter." << endl; +                printHelp(true); +                exit(1); +            } +         +        } +        // has the user chosen to display multiple devices and thus not to display graphs? +        else if(strcmp(argv[i], "-m") == 0) +        { +            SettingStore::get("MultipleDevices") = true; +        } +        // obsolete -b option +        else if(strcmp(argv[i], "-b") == 0) +        { +        } +        // obsolete -s option +        else if(strcmp(argv[i], "-s") == 0) +        { +        } +        // assume unknown parameter to be the network device +        else +        { +            Setting& devices = SettingStore::get("Devices"); + +            if(deleteDevicesRequested) +            { +                devices = ""; +                deleteDevicesRequested = false; +            } + +            devices.setThroughFilter(trim(devices.getThroughFilter() + " " + argv[i])); +        } +    } + +    // auto-detect network devices +    DevReaderFactory::findAllDevices(); +    const map<string, DevReader*>& deviceReaders = DevReaderFactory::getAllDevReaders(); + +    // create one instance of the Device class per device +    map<string, Device*> deviceHandlers; +    for(map<string, DevReader*>::const_iterator itDevice = deviceReaders.begin(); itDevice != deviceReaders.end(); ++itDevice) +    { +        Device* device = new Device(*itDevice->second); +        device->update(); + +        deviceHandlers[itDevice->first] = device; +    } + +    init(); + +    while(!quit) +    { +        // wait RefreshInterval milliseconds (in steps of 100 ms) +        struct timespec wantedTime; +        wantedTime.tv_sec = 0; +         +        int restOfRefreshInterval = SettingStore::get("RefreshInterval"); +         +        while(restOfRefreshInterval > 0 && !quit) +        { +            restOfRefreshInterval -= 100; +            wantedTime.tv_nsec = (restOfRefreshInterval >= 0 ? 100 : 100 + restOfRefreshInterval) * 1000000L; +             +            nanosleep(&wantedTime, 0); +             +            // process keyboard +            int key; +            while((key = getch()) != ERR) +            { +                if(m_optWindow.isVisible()) +                { +                    if(key == KEY_F(2)) +                    { +                        m_optWindow.hide(); +                        m_mainWindow.resize(0, 0, Screen::width(), Screen::height()); +                        restOfRefreshInterval = 0; // update the screen +                    } +                    else +                    { +                        m_optWindow.processKey(key); +                    } +                } +                else +                { +                    switch(key) +                    { +                        case KEY_F(2): +                            m_mainWindow.resize(0, Screen::height() / 4, Screen::width(), Screen::height() - Screen::height() / 4); +                            m_optWindow.show(0, 0, Screen::width(), Screen::height() / 4); +                            restOfRefreshInterval = 0; // update the screen +                            break; +                        case KEY_F(5): +                            SettingStore::writeToFile(homeDir + "/.nload"); +                            break; +                        case KEY_F(6): +                            SettingStore::readFromFile("/etc/nload.conf"); +                            SettingStore::readFromFile(homeDir + "/.nload"); +                            break; +                        case 'q': +                        case 'Q': +                            quit = true; +                            break; +                        default: +                            m_mainWindow.processKey(key); +                    } +                } +            } +        } + +        if(quit) +            break; + +        vector<string> devicesRequested = split(trim(SettingStore::get("Devices").getThroughFilter()), " "); +        vector<Device*> devicesToShow; + +        if(!devicesRequested.empty() && devicesRequested.front() != "all") +        { +            // check if requested devices are available +            for(vector<string>::const_iterator itRequested = devicesRequested.begin(); itRequested != devicesRequested.end(); ++itRequested) +            { +                map<string, Device*>::const_iterator itDetectedDevice = deviceHandlers.find(*itRequested); +                if(itDetectedDevice != deviceHandlers.end()) +                    devicesToShow.push_back(itDetectedDevice->second); +            } +        } + +        if(devicesToShow.empty()) +        { +            // use all detected devices +            for(map<string, Device*>::const_iterator itDevice = deviceHandlers.begin(); itDevice != deviceHandlers.end(); ++itDevice) +                devicesToShow.push_back(itDevice->second); +        } + +        // enumerate devices for display +        unsigned int deviceIndex = 0; +        for(vector<Device*>::const_iterator itDevice = devicesToShow.begin(); itDevice != devicesToShow.end(); ++itDevice) +        { +            (*itDevice)->setDeviceNumber(deviceIndex++); +            (*itDevice)->setTotalNumberOfDevices(devicesToShow.size()); +        } + +        // update all devices +        for(map<string, Device*>::const_iterator itDevice = deviceHandlers.begin(); itDevice != deviceHandlers.end(); ++itDevice) +            itDevice->second->update(); + +        // clear the screen +        m_mainWindow.clear(); +         +        // print device data +        m_mainWindow.printTraffic(devicesToShow); +         +        // refresh the screen +        m_mainWindow.refresh(); +         +        if(m_optWindow.isVisible()) +            m_optWindow.refresh(); // always show cursor in option dialog +         +    } + +    finish(); +     +    for(map<string, Device*>::const_iterator itDevice = deviceHandlers.begin(); itDevice != deviceHandlers.end(); ++itDevice) +        delete itDevice->second; +    deviceHandlers.clear(); +     +    return 0; +} + +void init() +{ +    // handle interrrupt signal +    signal(SIGINT, end); +    signal(SIGTERM, end); +    signal(SIGWINCH, terminalResized); +     +    // initialize ncurses +    initscr(); +    keypad(stdscr, true); +    nodelay(stdscr, true); +    noecho(); +    nonl(); +    cbreak(); +     +    // create main window +    m_mainWindow.show(0, 0, Screen::width(), Screen::height()); +} + +void finish() +{ +    // destroy main window +    m_mainWindow.hide(); +     +    // stop ncurses +    endwin(); +} + +void end(int signal) +{ +    quit = true; +} + +void terminalResized(int signal) +{ +    bool optWindowWasVisible = m_optWindow.isVisible(); + +    m_optWindow.hide(); + +    finish();    +    init(); +     +    if(optWindowWasVisible) +    { +        m_mainWindow.resize(0, Screen::height() / 4, Screen::width(), Screen::height() - Screen::height() / 4); +        m_optWindow.show(0, 0, Screen::width(), Screen::height() / 4); +    } +} + +void printHelp(bool error) +{ +    // print disclaimer +    (error ? cerr : cout) +        << "\n" +        << PACKAGE << " version " << VERSION << "\n" +        << "Copyright (C) 2001 - 2012 by Roland Riegel <feedback@roland-riegel.de>\n" +        << PACKAGE << " comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n" +        << "welcome to redistribute it under certain conditions. For more details see the\n" +        << "GNU General Public License Version 2 (http://www.gnu.org/copyleft/gpl.html).\n\n" + +        << "Command line syntax:\n" +        << PACKAGE << " [options] [devices]\n" +        << PACKAGE << " --help|-h\n\n" + +        << "Options:\n" +        << "-a period       Sets the length in seconds of the time window for average\n" +        << "                calculation.\n" +        << "                Default is " << STANDARD_AVERAGE_WINDOW << ".\n" +        << "-i max_scaling  Specifies the 100% mark in kBit/s of the graph indicating the\n" +        << "                incoming bandwidth usage. Ignored if max_scaling is 0 or the\n" +        << "                switch -m is given.\n" +        << "                Default is " << STANDARD_MAX_DEFLECTION << ".\n" +        << "-m              Show multiple devices at a time; no traffic graphs.\n" +        << "-o max_scaling  Same as -i but for the graph indicating the outgoing bandwidth\n" +        << "                usage.\n" +        << "                Default is " << STANDARD_MAX_DEFLECTION << ".\n" +        << "-t interval     Determines the refresh interval of the display in milliseconds.\n" +        << "                Default is " << STANDARD_REFRESH_INTERVAL << ".\n" +        << "-u h|b|k|m|g    Sets the type of unit used for the display of traffic numbers.\n" +        << "   H|B|K|M|G    h: auto, b: Bit/s, k: kBit/s, m: MBit/s etc.\n" +        << "                H: auto, B: Byte/s, K: kByte/s, M: MByte/s etc.\n" +        << "                Default is h.\n" +        << "-U h|b|k|m|g    Same as -u, but for a total amount of data (without \"/s\").\n" +        << "   H|B|K|M|G    Default is H.\n" +        << "devices         Network devices to use.\n" +        << "                Default is to use all auto-detected devices.\n" +        << "--help\n" +        << "-h              Print this help.\n\n" + +        << "example: " << PACKAGE << " -t 200 -i 1024 -o 128 -U M\n\n" + +        << "The options above can also be changed at run time by pressing the 'F2' key.\n" +        << endl; +} + diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..e92e878 --- /dev/null +++ b/src/main.h @@ -0,0 +1,34 @@ +/*************************************************************************** +                                   main.h +                             ------------------- +    begin                : Wed Jul 25 2001 +    copyright            : (C) 2001 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef MAIN_H +#define MAIN_H + +#include "traffic_window.h" +#include "opt_window.h" + +int main(int argc, char *argv[]); + +void init(); +void finish(); +void end(int signal = 0); +void terminalResized(int signal); + +void printHelp(bool error); + +#endif + diff --git a/src/opt_window.cpp b/src/opt_window.cpp new file mode 100644 index 0000000..b8e1a9a --- /dev/null +++ b/src/opt_window.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** +                               opt_window.cpp +                             ------------------- +    begin                : Thu Jan 17 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "opt_window.h" +#include "setting.h" +#include "settingfilter.h" +#include "settingstore.h" +#include "stringutils.h" + +#define BORDER_LEFT 1 +#define BORDER_RIGHT 1 +#define BORDER_TOP 2 +#define BORDER_BOTTOM 1 + +using namespace std; + +OptWindow::OptWindow() +    : Window(), Form::Slots(), m_subWindow(this), m_form(this) +{ +} + +OptWindow::~OptWindow() +{ +    hide(); +} + +// create option window and display the current settings +void OptWindow::show(int x, int y, int width, int height) +{ +    if(m_visible) +        hide(); +     +    Window::show(x, y, width, height); +    m_subWindow.show(BORDER_LEFT, BORDER_TOP, width - BORDER_LEFT - BORDER_RIGHT, height - BORDER_TOP - BORDER_BOTTOM); +     +    const int field_width = m_subWindow.getWidth() / 2; +    int line = 0; + +    map<string, Setting>& settings = SettingStore::getAll(); + +    for(map<string, Setting>::const_iterator itSetting = settings.begin(); itSetting != settings.end(); ++itSetting) +    { +        Field* label = new Field(0, line, field_width, 1); +        Field* field = new Field(field_width, line, field_width, 1); + +        m_labels[label] = itSetting->first; +        m_fields[field] = itSetting->first; + +        m_form.fields().push_back(label); +        m_form.fields().push_back(field); + +        label->setEnabled(false); +        label->setText((itSetting->second.getDescription() + ":").c_str()); +        label->setFirstOnPage(line == 0); + +        field->setText(itSetting->second.getThroughFilter().c_str()); + +        const SettingFilterMap* mappingFilter = (SettingFilterMap*) itSetting->second.findFilterWithId("map"); +        if(mappingFilter) +        { +            const map<string, string>& mapping = mappingFilter->getMap(); + +            vector<string> elements; +            for(map<string, string>::const_iterator itMapping = mapping.begin(); itMapping != mapping.end(); ++itMapping) +                elements.push_back(itMapping->second); + +            field->setEnumField(elements); +            field->setFixed(true); +        } +         +        ++line; +        line %= m_subWindow.getHeight() < 1 ? 1 : m_subWindow.getHeight(); +    } +     +    m_form.show(this, &m_subWindow); +     +    m_visible = true; +} + +// this function is called when a form field changes +void OptWindow::slot_fieldChanged(Field* field) +{ +    map<Field*, string>::const_iterator itField = m_fields.find(field); +    if(itField == m_fields.end()) +        return; + +    map<string, Setting>& settings = SettingStore::getAll(); +    map<string, Setting>::iterator itSetting = settings.find(itField->second); +    if(itSetting == settings.end()) +        return; + +    itSetting->second.setThroughFilter(trim(field->getText())); +    field->setText(itSetting->second.getThroughFilter()); +} + +// hide window and destroy it +void OptWindow::hide() +{ +    m_form.hide(); +    m_form.fields().clear(); +    m_subWindow.hide(); +    Window::hide(); + +    for(map<Field*, string>::const_iterator itLabel = m_labels.begin(); itLabel != m_labels.end(); ++itLabel) +        delete itLabel->first; +    for(map<Field*, string>::const_iterator itField = m_fields.begin(); itField != m_fields.end(); ++itField) +        delete itField->first; + +    m_labels.clear(); +    m_fields.clear(); +     +    m_visible = false; +} + +// process key presses +void OptWindow::processKey(int request) +{ +    if(m_visible) +    { +        switch(request) +        { +            case KEY_LEFT: +                request = REQ_PREV_CHAR; +                break; +            case KEY_RIGHT: +                request = REQ_NEXT_CHAR; +                break; +            case KEY_UP: +                request = REQ_PREV_FIELD; +                break; +            case KEY_DOWN: +            case KEY_ENTER: +            case '\n': +            case '\015': +                request = REQ_NEXT_FIELD; +                break; +            case KEY_DC: +                request = REQ_DEL_CHAR; +                break; +            case KEY_BACKSPACE: +                request = REQ_DEL_PREV; +                break; +            case KEY_PPAGE: +                request = REQ_PREV_CHOICE; +                break; +            case KEY_NPAGE: +            case '\t': +                request = REQ_NEXT_CHOICE; +                break; +            case KEY_HOME: +                request = REQ_BEG_LINE; +                break; +            case KEY_END: +                request = REQ_END_LINE; +                break; +            case '+': +                request = REQ_NEXT_PAGE; +                break; +            case '-': +                request = REQ_PREV_PAGE; +                break; +        } +        m_form.processKey(request); +        refresh(); +    } +} + +void OptWindow::refresh() +{ +    print(0, 0) << "Options:" << endl +                << string(getWidth(), '='); +     +    string navigator = " <-- (-) page " + toString(m_form.getPage() + 1) + "/" + toString(m_form.getPageCount()) + " (+) --> "; +    print(navigator, getWidth() - navigator.length() - 1, 1); +     +    wrefresh(m_window); +    m_subWindow.refresh(); +} + diff --git a/src/opt_window.h b/src/opt_window.h new file mode 100644 index 0000000..01a320a --- /dev/null +++ b/src/opt_window.h @@ -0,0 +1,50 @@ +/*************************************************************************** +                                opt_window.h +                             ------------------- +    begin                : Thu Jan 17 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef OPT_WINDOW_H +#define OPT_WINDOW_H + +#include "window.h" +#include "form_field.h" + +#include <map> +#include <string> + +class OptWindow : public Window, public Form::Slots +{ +    public: +        OptWindow(); +        ~OptWindow(); +         +        void show(int x, int y, int width, int height); +        void hide(); +         +        void refresh(); +         +        void processKey(int request); +        void slot_fieldChanged(Field* field); +         +    private: +        SubWindow m_subWindow; +        Form m_form; + +        std::map<Field*, std::string> m_labels; +        std::map<Field*, std::string> m_fields; +}; + +#endif + diff --git a/src/screen.cpp b/src/screen.cpp new file mode 100644 index 0000000..05e8c00 --- /dev/null +++ b/src/screen.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +                                 screen.cpp +                             ------------------- +    begin                : Thu Nov 25 2003 +    copyright            : (C) 2003 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "screen.h" + +#include <curses.h> +#undef clear +#undef erase +#undef refresh + +int Screen::width() +{ +    int width; +    int height; +    getmaxyx(stdscr, height, width); +    return width; +} + +int Screen::height() +{ +    int width; +    int height; +    getmaxyx(stdscr, height, width); +    return height; +} + +int Screen::x() +{ +    int x; +    int y; +    getyx(stdscr, y, x); +    return x; +} + +int Screen::y() +{ +    int x; +    int y; +    getyx(stdscr, y, x); +    return y; +} + diff --git a/src/screen.h b/src/screen.h new file mode 100644 index 0000000..cf502ca --- /dev/null +++ b/src/screen.h @@ -0,0 +1,32 @@ +/*************************************************************************** +                                  screen.h +                             ------------------- +    begin                : Thu Jul 04 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef SCREEN_H +#define SCREEN_H + +class Screen +{ +    public: +        static int width(); +        static int height(); +         +        static int x(); +        static int y(); +}; + +#endif + diff --git a/src/setting.cpp b/src/setting.cpp new file mode 100644 index 0000000..9e7ed70 --- /dev/null +++ b/src/setting.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** +                                 setting.cpp +                             ------------------- +    begin                : Tue Nov 06 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "setting.h" +#include "settingfilter.h" +#include "stringutils.h" + +#include <istream> +#include <ostream> +#include <sstream> + +using namespace std; + +Setting::~Setting() +{ +    for(list<SettingFilter*>::const_iterator itFilter = m_filters.begin(); itFilter != m_filters.end(); ++itFilter) +        delete *itFilter; +    m_filters.clear(); +} + +void Setting::pushFilter(SettingFilter* filter) +{ +    if(!filter) +        return; + +    m_filters.push_back(filter); +} + +void Setting::popFilter() +{ +    if(m_filters.empty()) +        return; + +    delete m_filters.back(); +    m_filters.pop_back(); +} + +SettingFilter* Setting::findFilterWithId(const string& id) +{ +    for(list<SettingFilter*>::const_iterator itFilter = m_filters.begin(); itFilter != m_filters.end(); ++itFilter) +    { +        if((*itFilter)->getId() == id) +            return *itFilter; +    } + +    return 0; +} + +const SettingFilter* Setting::findFilterWithId(const string& id) const +{ +    for(list<SettingFilter*>::const_iterator itFilter = m_filters.begin(); itFilter != m_filters.end(); ++itFilter) +    { +        if((*itFilter)->getId() == id) +            return *itFilter; +    } + +    return 0; +} + +string Setting::getThroughFilter() const +{ +    string valueCopy = m_value; + +    for(list<SettingFilter*>::const_reverse_iterator itFilter = m_filters.rbegin(); itFilter != m_filters.rend(); ++itFilter) +        (*itFilter)->filterRead(valueCopy); + +    return valueCopy; +} + +bool Setting::setThroughFilter(const string& value) +{ +    string valueCopy = value; + +    for(list<SettingFilter*>::iterator itFilter = m_filters.begin(); itFilter != m_filters.end(); ++itFilter) +    { +        if(!(*itFilter)->filterWrite(valueCopy)) +            return false; +    } + +    m_value = valueCopy; +    return true; +} + +istream& operator>>(istream& in, Setting& setting) +{ +    while(!in.eof()) +    { +        // extract line from stream +        string line; +        getline(in, line); + +        if(in.fail()) +            return in; + +        // strip whitespace +        line = trim(line); + +        // skip empty lines +        if(line.empty()) +            continue; + +        // skip comments +        if(line[0] == '#') +            continue; + +        // split line into id and value +        vector<string> words = splitQuoted(line, "="); + +        if(words.size() < 2 || words[0].empty()) +        { +            in.setstate(ios_base::failbit); +            return in; +        } + +        setting.setId(words[0]); +        setting.setThroughFilter(words[1]); + +        break; +    } + +    return in; +} + +ostream& operator<<(ostream& out, const Setting& setting) +{ +    out << setting.getId() << "=\"" << setting.getThroughFilter() << "\"" << endl; +    return out; +} + + diff --git a/src/setting.h b/src/setting.h new file mode 100644 index 0000000..eef52f5 --- /dev/null +++ b/src/setting.h @@ -0,0 +1,88 @@ +/*************************************************************************** +                                  setting.h +                             ------------------- +    begin                : Tue Nov 06 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef SETTING_H +#define SETTING_H + +#include "stringutils.h" + +#include <iosfwd> +#include <list> +#include <string> + +class SettingFilter; + +class Setting +{ +    public: +        Setting(const std::string& id = "", const std::string& description = "") +            : m_id(id), m_description(description), m_value() {} +        template<class T> +        Setting(const std::string& id, const std::string& description, const T& value) +            : m_id(id), m_description(description), m_value(toString(value)) {} +        ~Setting(); + +        const std::string& getId() const { return m_id; } +        const std::string& getDescription() const { return m_description; } +        const std::string& getValue() const { return m_value; } + +        void setId(const std::string& id) { m_id = id; } +        void setDescription(const std::string& description) { m_description = description; } + +        void pushFilter(SettingFilter* filter); +        void popFilter(); +        SettingFilter* findFilterWithId(const std::string& id); +        const SettingFilter* findFilterWithId(const std::string& id) const; + +        std::string getThroughFilter() const; +        bool setThroughFilter(const std::string& value); + +        template<class T> +        operator T() { return fromString<T>(m_value); } + +        template<class T> +        Setting& operator=(const T& t) { m_value = toString(t); return *this; } + +        template<class T> +        bool operator==(const T& t) const { return toString(t) == m_value; } +        template<class T> +        bool operator!=(const T& t) const { return toString(t) != m_value; } +        template<class T> +        bool operator<(const T& t) const { return fromString<T>(m_value) < t; } +        template<class T> +        bool operator>(const T& t) const { return fromString<T>(m_value) > t; } +        template<class T> +        bool operator<=(const T& t) const { return fromString<T>(m_value) <= t; } +        template<class T> +        bool operator>=(const T& t) const { return fromString<T>(m_value) >= t; } + +        bool operator==(const Setting& s) const { return s.m_value == m_value; } +        bool operator!=(const Setting& s) const { return s.m_value != m_value; } + +    private: +        std::string m_id; +        std::string m_description; +        std::string m_value; + +        std::list<SettingFilter*> m_filters; +}; + +std::istream& operator>>(std::istream& in, Setting& setting); +std::ostream& operator<<(std::ostream& out, const Setting& setting); + +#endif + diff --git a/src/settingfilter.cpp b/src/settingfilter.cpp new file mode 100644 index 0000000..fb7df78 --- /dev/null +++ b/src/settingfilter.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** +                              settingfilter.cpp +                             ------------------- +    begin                : Wed Nov 28 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "settingfilter.h" +#include "stringutils.h" + +using namespace std; + +SettingFilterDefault::SettingFilterDefault(const string& def) +    : m_default(def) +{ +} + +SettingFilterDefault::~SettingFilterDefault() +{ +} + +string SettingFilterDefault::getId() const +{ +    return "default"; +} + +void SettingFilterDefault::setDefault(const string& def) +{ +    m_default = def; +} + +const string& SettingFilterDefault::getDefault() const +{ +    return m_default; +} + +bool SettingFilterDefault::filterWrite(string& valueNew) +{ +    if(valueNew.empty()) +        valueNew = m_default; + +    return true; +} + +void SettingFilterDefault::filterRead(string& value) +{ +} + +SettingFilterExclusive::SettingFilterExclusive(const string& exclusive) +    : m_exclusive(exclusive) +{ +} + +SettingFilterExclusive::~SettingFilterExclusive() +{ +} + +string SettingFilterExclusive::getId() const +{ +    return "exclusive"; +} + +void SettingFilterExclusive::setExclusive(const string& exclusive) +{ +    m_exclusive = exclusive; +} + +const string& SettingFilterExclusive::getExclusive() const +{ +    return m_exclusive; +} + +bool SettingFilterExclusive::filterWrite(string& valueNew) +{ +    substituteExclusive(valueNew); +    return true; +} + +void SettingFilterExclusive::filterRead(string& value) +{ +    substituteExclusive(value); +} + +void SettingFilterExclusive::substituteExclusive(string& value) +{ +    if(value.find(m_exclusive + " ") == 0 || +       value.find(string(" ") + m_exclusive) == value.length() - (m_exclusive.length() + 1) || +       value.find(string(" ") + m_exclusive + " ") != string::npos +      ) +        value = m_exclusive; +} + +SettingFilterMap::SettingFilterMap(const map<string, string>& filterMap) +    : m_filterMap(filterMap) +{ +} + +SettingFilterMap::~SettingFilterMap() +{ +} + +string SettingFilterMap::getId() const +{ +    return "map"; +} + +void SettingFilterMap::setMap(const map<string, string>& filterMap) +{ +    m_filterMap = filterMap; +} + +const map<string, string>& SettingFilterMap::getMap() const +{ +    return m_filterMap; +} + +bool SettingFilterMap::filterWrite(string& valueNew) +{ +    for(map<string, string>::const_iterator itMapping = m_filterMap.begin(); itMapping != m_filterMap.end(); ++itMapping) +    { +        if(itMapping->second == valueNew) +        { +            valueNew = itMapping->first; +            return true; +        } +    } + +    return false; +} + +void SettingFilterMap::filterRead(string& value) +{ +    if(m_filterMap.empty()) +        return; + +    map<string, string>::const_iterator itMapping = m_filterMap.find(value); +    if(itMapping != m_filterMap.end()) +        value = itMapping->second; +} + +SettingFilterMin::SettingFilterMin(int min) +    : m_min(min) +{ +} + +SettingFilterMin::~SettingFilterMin() +{ +} + +string SettingFilterMin::getId() const +{ +    return "min"; +} + +void SettingFilterMin::setMin(int min) +{ +    m_min = min; +} + +int SettingFilterMin::getMin() const +{ +    return m_min; +} + +bool SettingFilterMin::filterWrite(string& valueNew) +{ +    if(fromString<int>(valueNew) < m_min) +        valueNew = toString(m_min); + +    return true; +} + +void SettingFilterMin::filterRead(string& value) +{ +} + +SettingFilterMax::SettingFilterMax(int max) +    : m_max(max) +{ +} + +SettingFilterMax::~SettingFilterMax() +{ +} + +string SettingFilterMax::getId() const +{ +    return "max"; +} + +void SettingFilterMax::setMax(int max) +{ +    m_max = max; +} + +int SettingFilterMax::getMax() const +{ +    return m_max; +} + +bool SettingFilterMax::filterWrite(string& valueNew) +{ +    if(fromString<int>(valueNew) > m_max) +        valueNew = toString(m_max); + +    return true; +} + +void SettingFilterMax::filterRead(string& value) +{ +} + diff --git a/src/settingfilter.h b/src/settingfilter.h new file mode 100644 index 0000000..c306667 --- /dev/null +++ b/src/settingfilter.h @@ -0,0 +1,128 @@ +/*************************************************************************** +                               settingfilter.h +                             ------------------- +    begin                : Wed Nov 28 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef SETTINGFILTER_H +#define SETTINGFILTER_H + +#include <map> +#include <string> + +class SettingFilter +{ +    public: +        virtual ~SettingFilter() {} + +        virtual std::string getId() const = 0; + +        virtual bool filterWrite(std::string& valueNew) = 0; +        virtual void filterRead(std::string& value) = 0; +}; + +class SettingFilterDefault : public SettingFilter +{ +    public: +        SettingFilterDefault(const std::string& def); +        ~SettingFilterDefault(); + +        std::string getId() const; + +        void setDefault(const std::string& def); +        const std::string& getDefault() const; + +        bool filterWrite(std::string& valueNew); +        void filterRead(std::string& value); +         +    private: +        std::string m_default; +}; + +class SettingFilterExclusive : public SettingFilter +{ +    public: +        SettingFilterExclusive(const std::string& exclusive); +        ~SettingFilterExclusive(); + +        std::string getId() const; + +        void setExclusive(const std::string& exclusive); +        const std::string& getExclusive() const; + +        bool filterWrite(std::string& valueNew); +        void filterRead(std::string& value); +         +    private: +        void substituteExclusive(std::string& value); + +        std::string m_exclusive; +}; + +class SettingFilterMap : public SettingFilter +{ +    public: +        SettingFilterMap(const std::map<std::string, std::string>& filterMap); +        ~SettingFilterMap(); + +        std::string getId() const; + +        void setMap(const std::map<std::string, std::string>& filterMap); +        const std::map<std::string, std::string>& getMap() const; + +        bool filterWrite(std::string& valueNew); +        void filterRead(std::string& value); +         +    private: +        std::map<std::string, std::string> m_filterMap; +}; + +class SettingFilterMin : public SettingFilter +{ +    public: +        SettingFilterMin(int min); +        ~SettingFilterMin(); + +        std::string getId() const; + +        void setMin(int min); +        int getMin() const; + +        bool filterWrite(std::string& valueNew); +        void filterRead(std::string& value); +         +    private: +        int m_min; +}; + +class SettingFilterMax : public SettingFilter +{ +    public: +        SettingFilterMax(int max); +        ~SettingFilterMax(); + +        std::string getId() const; + +        void setMax(int max); +        int getMax() const; + +        bool filterWrite(std::string& valueNew); +        void filterRead(std::string& value); +         +    private: +        int m_max; +}; + +#endif + diff --git a/src/settingstore.cpp b/src/settingstore.cpp new file mode 100644 index 0000000..1dcb626 --- /dev/null +++ b/src/settingstore.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** +                              settingstore.cpp +                             ------------------- +    begin                : Tue Nov 06 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "setting.h" +#include "settingstore.h" + +#include <fstream> + +using namespace std; + +map<string, Setting> SettingStore::m_settings; + +Setting& SettingStore::get(const string& key) +{ +    return m_settings[key]; +} + +void SettingStore::add(const Setting& setting) +{ +    m_settings[setting.getId()] = setting; +} + +void SettingStore::remove(const string& key) +{ +    m_settings.erase(key); +} + +bool SettingStore::exists(const string& key) +{ +    return m_settings.find(key) != m_settings.end(); +} + +map<std::string, Setting>& SettingStore::getAll() +{ +    return m_settings; +} + +bool SettingStore::readFromFile(const std::string& file) +{ +    if(file.empty()) +        return false; + +    // open file +    ifstream fin(file.c_str()); +    if(!fin.is_open()) +        return false; + +    // parse file +    while(fin.good()) +    { +        Setting setting; + +        fin >> setting; +        if(setting.getId().empty()) +            break; + +        if(exists(setting.getId())) +            get(setting.getId()).setThroughFilter(setting.getValue()); +        else +            add(setting); +    } + +    return !fin.fail(); +} + +bool SettingStore::writeToFile(const std::string& file) +{ +    if(file.empty()) +        return false; + +    // open file +    ofstream fout(file.c_str()); +    if(!fout.is_open()) +        return false; + +    fout << "Version=\"1\"\n"; + +    // output settings +    for(map<string, Setting>::const_iterator itSetting = m_settings.begin(); itSetting != m_settings.end(); ++itSetting) +        fout << itSetting->second; + +    return fout.good(); +} + diff --git a/src/settingstore.h b/src/settingstore.h new file mode 100644 index 0000000..4fc1ebb --- /dev/null +++ b/src/settingstore.h @@ -0,0 +1,44 @@ +/*************************************************************************** +                               settingstore.h +                             ------------------- +    begin                : Tue Nov 06 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef SETTINGSTORE_H +#define SETTINGSTORE_H + +#include <map> +#include <string> + +class Setting; + +class SettingStore +{ +    public: +        static Setting& get(const std::string& key); +        static void add(const Setting& setting); +        static void remove(const std::string& key); +        static bool exists(const std::string& key); + +        static std::map<std::string, Setting>& getAll(); + +        static bool readFromFile(const std::string& file); +        static bool writeToFile(const std::string& file); + +    private: +        static std::map<std::string, Setting> m_settings; +}; + +#endif + diff --git a/src/statistics.cpp b/src/statistics.cpp new file mode 100644 index 0000000..a983c9c --- /dev/null +++ b/src/statistics.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** +                               statistics.cpp +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "setting.h" +#include "settingstore.h" +#include "statistics.h" + +using namespace std; + +void Statistics::insertDataFrame(const DataFrame& dataFrame) +{ +    if(!dataFrame.isValid()) +        return; + +    m_dataFrames.push_back(dataFrame); + +    unsigned int frameCount = m_dataFrames.size(); +    if(frameCount < 2) +        return; + +    unsigned int averageCount = getAverageWindow(); +    unsigned int secondCount = getSecondWindow(); + +    if(frameCount > averageCount) +    { +        m_dataFrames.erase(m_dataFrames.begin(), m_dataFrames.begin() + (frameCount - averageCount)); +        frameCount = averageCount; +    } + +    vector<DataFrame>::const_reverse_iterator itFrameSecond = m_dataFrames.rbegin(); +    vector<DataFrame>::const_reverse_iterator itFrameAverage = m_dataFrames.rbegin(); + +    if(frameCount > secondCount) +        itFrameSecond += secondCount; +    else +        itFrameSecond += frameCount - 1; + +    if(frameCount > averageCount) +        itFrameAverage += averageCount; +    else +        itFrameAverage += frameCount - 1; + +    calculateAverage(*itFrameSecond, m_dataFrames.back(), m_second); +    calculateAverage(*itFrameAverage, m_dataFrames.back(), m_average); + +    if(frameCount > 2) +        calculateMinMax(m_second, m_min, m_max); +    else +        m_min = m_max = m_second; +} + +void Statistics::reset() +{ +    m_second = DataFrame(); +    m_average = DataFrame(); +    m_min = DataFrame(); +    m_max = DataFrame(); + +    m_dataFrames.clear(); +} + +float Statistics::getUnitFactor(dataUnit unit, unsigned long long value) +{ +    float factor = 1.0 / (unit % 2 == 0 ? 8 : 1); +     +    switch(unit) +    { +        case humanReadableBit: +        case humanReadableByte: +            for(int i = 0; i < 3; ++i) +            { +                if(value / factor < 1024) +                    return factor; + +                factor *= 1024; +            } +            return factor; +        case bit: +        case byte: +            return factor; +        case kiloBit: +        case kiloByte: +            return factor * 1024; +        case megaBit: +        case megaByte: +            return factor * 1024 * 1024; +        case gigaBit: +        case gigaByte: +            return factor * 1024 * 1024 * 1024; +        default: // should never be executed +            return factor; +    } +} + +string Statistics::getUnitString(dataUnit unit, unsigned long long value) +{ +    const string description = (unit % 2 == 0 ? "Bit" : "Byte"); +    const string units[] = { "", "k", "M", "G" }; + +    switch(unit) +    { +        case humanReadableBit: +        case humanReadableByte: +            value *= (unit % 2 == 0 ? 8 : 1); +            for(int i = 0; i < 3; ++i) +            { +                if(value < 1024) +                    return units[i] + description; + +                value /= 1024; +            } +            return units[3] + description; +        case bit: +        case byte: +            return description; +        case kiloBit: +        case kiloByte: +            return 'k' + description; +        case megaBit: +        case megaByte: +            return 'M' + description; +        case gigaBit: +        case gigaByte: +            return 'G' + description; +        default: // should never be executed +            return description; +    } +} + +void Statistics::calculateAverage(const DataFrame& dataFrameFrom, const DataFrame& dataFrameTo, DataFrame& result) +{ +    float timeSpan = (dataFrameTo.getTimeStampSeconds() + dataFrameTo.getTimeStampMicroseconds() / 1000000.0) - +                     (dataFrameFrom.getTimeStampSeconds() + dataFrameFrom.getTimeStampMicroseconds() / 1000000.0); + +    if(timeSpan <= 0) +        return; + +    result.setTotalDataIn((unsigned long long)((dataFrameTo.getTotalDataIn() - dataFrameFrom.getTotalDataIn()) / timeSpan)); +    result.setTotalDataOut((unsigned long long)((dataFrameTo.getTotalDataOut() - dataFrameFrom.getTotalDataOut()) / timeSpan)); +    result.setTotalPacketsIn((unsigned long long)((dataFrameTo.getTotalPacketsIn() - dataFrameFrom.getTotalPacketsIn()) / timeSpan)); +    result.setTotalPacketsOut((unsigned long long)((dataFrameTo.getTotalPacketsOut() - dataFrameFrom.getTotalPacketsOut()) / timeSpan)); +    result.setTotalErrorsIn((unsigned long long)((dataFrameTo.getTotalErrorsIn() - dataFrameFrom.getTotalErrorsIn()) / timeSpan)); +    result.setTotalErrorsOut((unsigned long long)((dataFrameTo.getTotalErrorsOut() - dataFrameFrom.getTotalErrorsOut()) / timeSpan)); +    result.setTotalDropsIn((unsigned long long)((dataFrameTo.getTotalDropsIn() - dataFrameFrom.getTotalDropsIn()) / timeSpan)); +    result.setTotalDropsOut((unsigned long long)((dataFrameTo.getTotalDropsOut() - dataFrameFrom.getTotalDropsOut()) / timeSpan)); +} + +void Statistics::calculateMinMax(const DataFrame& dataFrame, DataFrame& min, DataFrame& max) +{ +    if(dataFrame.getTotalDataIn() < min.getTotalDataIn()) +        min.setTotalDataIn(dataFrame.getTotalDataIn()); +    if(dataFrame.getTotalDataIn() > max.getTotalDataIn()) +        max.setTotalDataIn(dataFrame.getTotalDataIn()); +    if(dataFrame.getTotalDataOut() < min.getTotalDataOut()) +        min.setTotalDataOut(dataFrame.getTotalDataOut()); +    if(dataFrame.getTotalDataOut() > max.getTotalDataOut()) +        max.setTotalDataOut(dataFrame.getTotalDataOut()); + +    if(dataFrame.getTotalPacketsIn() < min.getTotalPacketsIn()) +        min.setTotalPacketsIn(dataFrame.getTotalPacketsIn()); +    if(dataFrame.getTotalPacketsIn() > max.getTotalPacketsIn()) +        max.setTotalPacketsIn(dataFrame.getTotalPacketsIn()); +    if(dataFrame.getTotalPacketsOut() < min.getTotalPacketsOut()) +        min.setTotalPacketsOut(dataFrame.getTotalPacketsOut()); +    if(dataFrame.getTotalPacketsOut() > max.getTotalPacketsOut()) +        max.setTotalPacketsOut(dataFrame.getTotalPacketsOut()); + +    if(dataFrame.getTotalErrorsIn() < min.getTotalErrorsIn()) +        min.setTotalErrorsIn(dataFrame.getTotalErrorsIn()); +    if(dataFrame.getTotalErrorsIn() > max.getTotalErrorsIn()) +        max.setTotalErrorsIn(dataFrame.getTotalErrorsIn()); +    if(dataFrame.getTotalErrorsOut() < min.getTotalErrorsOut()) +        min.setTotalErrorsOut(dataFrame.getTotalErrorsOut()); +    if(dataFrame.getTotalErrorsOut() > max.getTotalErrorsOut()) +        max.setTotalErrorsOut(dataFrame.getTotalErrorsOut()); + +    if(dataFrame.getTotalDropsIn() < min.getTotalDropsIn()) +        min.setTotalDropsIn(dataFrame.getTotalDropsIn()); +    if(dataFrame.getTotalDropsIn() > max.getTotalDropsIn()) +        max.setTotalDropsIn(dataFrame.getTotalDropsIn()); +    if(dataFrame.getTotalDropsOut() < min.getTotalDropsOut()) +        min.setTotalDropsOut(dataFrame.getTotalDropsOut()); +    if(dataFrame.getTotalDropsOut() > max.getTotalDropsOut()) +        max.setTotalDropsOut(dataFrame.getTotalDropsOut()); +} + +unsigned int Statistics::getAverageWindow() +{ +    unsigned int refreshInterval = SettingStore::get("RefreshInterval"); +    unsigned int averageWindow = SettingStore::get("AverageWindow"); + +    return (unsigned int) (1000.0 / refreshInterval * averageWindow); +} + +unsigned int Statistics::getSecondWindow() +{ +    unsigned int refreshInterval = SettingStore::get("RefreshInterval"); +    unsigned int secondWindow = (unsigned int) (1000.0 / refreshInterval); + +    return secondWindow > 0 ? secondWindow : 1; +} + diff --git a/src/statistics.h b/src/statistics.h new file mode 100644 index 0000000..961b7e9 --- /dev/null +++ b/src/statistics.h @@ -0,0 +1,114 @@ +/*************************************************************************** +                               statistics.h +                             ------------------- +    begin                : Fri Nov 16 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef STATISTICS_H +#define STATISTICS_H + +#include "dataframe.h" + +#include <string> +#include <vector> + +class Statistics +{ +    public: +        enum dataUnit +        { +            humanReadableBit = -2, +            humanReadableByte = -1, +            bit = 0, +            byte = 1, +            kiloBit = 2, +            kiloByte = 3, +            megaBit = 4, +            megaByte = 5, +            gigaBit = 6, +            gigaByte = 7 +        }; +         +        Statistics() {} +        ~Statistics() {} + +        static float getUnitFactor(dataUnit unit, unsigned long long value); +        static std::string getUnitString(dataUnit unit, unsigned long long value); +         +        void insertDataFrame(const DataFrame& dataFrame); +        void reset(); + +        bool isValid() const { return !m_dataFrames.empty(); } + +        unsigned long long getDataInTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalDataIn(); } +        unsigned long long getDataOutTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalDataOut(); } +        unsigned long long getPacketsInTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalPacketsIn(); } +        unsigned long long getPacketsOutTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalPacketsOut(); } +        unsigned long long getErrorsInTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalErrorsIn(); } +        unsigned long long getErrorsOutTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalErrorsOut(); } +        unsigned long long getDropsInTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalDropsIn(); } +        unsigned long long getDropsOutTotal() const { return m_dataFrames.empty() ? 0 : m_dataFrames.back().getTotalDropsOut(); } + +        unsigned long long getDataInPerSecond() const { return m_second.getTotalDataIn(); } +        unsigned long long getDataOutPerSecond() const { return m_second.getTotalDataOut(); } +        unsigned long long getPacketsInPerSecond() const { return m_second.getTotalPacketsIn(); } +        unsigned long long getPacketsOutPerSecond() const { return m_second.getTotalPacketsOut(); } +        unsigned long long getErrorsInPerSecond() const { return m_second.getTotalErrorsIn(); } +        unsigned long long getErrorsOutPerSecond() const { return m_second.getTotalErrorsOut(); } +        unsigned long long getDropsInPerSecond() const { return m_second.getTotalDropsIn(); } +        unsigned long long getDropsOutPerSecond() const { return m_second.getTotalDropsOut(); } + +        unsigned long long getDataInAverage() const { return m_average.getTotalDataIn(); } +        unsigned long long getDataOutAverage() const { return m_average.getTotalDataOut(); } +        unsigned long long getPacketsInAverage() const { return m_average.getTotalPacketsIn(); } +        unsigned long long getPacketsOutAverage() const { return m_average.getTotalPacketsOut(); } +        unsigned long long getErrorsInAverage() const { return m_average.getTotalErrorsIn(); } +        unsigned long long getErrorsOutAverage() const { return m_average.getTotalErrorsOut(); } +        unsigned long long getDropsInAverage() const { return m_average.getTotalDropsIn(); } +        unsigned long long getDropsOutAverage() const { return m_average.getTotalDropsOut(); } + +        unsigned long long getDataInMin() const { return m_min.getTotalDataIn(); } +        unsigned long long getDataOutMin() const { return m_min.getTotalDataOut(); } +        unsigned long long getPacketsInMin() const { return m_min.getTotalPacketsIn(); } +        unsigned long long getPacketsOutMin() const { return m_min.getTotalPacketsOut(); } +        unsigned long long getErrorsInMin() const { return m_min.getTotalErrorsIn(); } +        unsigned long long getErrorsOutMin() const { return m_min.getTotalErrorsOut(); } +        unsigned long long getDropsInMin() const { return m_min.getTotalDropsIn(); } +        unsigned long long getDropsOutMin() const { return m_min.getTotalDropsOut(); } + +        unsigned long long getDataInMax() const { return m_max.getTotalDataIn(); } +        unsigned long long getDataOutMax() const { return m_max.getTotalDataOut(); } +        unsigned long long getPacketsInMax() const { return m_max.getTotalPacketsIn(); } +        unsigned long long getPacketsOutMax() const { return m_max.getTotalPacketsOut(); } +        unsigned long long getErrorsInMax() const { return m_max.getTotalErrorsIn(); } +        unsigned long long getErrorsOutMax() const { return m_max.getTotalErrorsOut(); } +        unsigned long long getDropsInMax() const { return m_max.getTotalDropsIn(); } +        unsigned long long getDropsOutMax() const { return m_max.getTotalDropsOut(); } + +    private: +        void calculateAverage(const DataFrame& dataFrameFrom, const DataFrame& dataFrameTo, DataFrame& result); +        void calculateMinMax(const DataFrame& dataFrame, DataFrame& min, DataFrame& max); +        unsigned int getAverageWindow(); +        unsigned int getSecondWindow(); + +        DataFrame m_second; +        DataFrame m_average; +        DataFrame m_min; +        DataFrame m_max; + +        std::vector<DataFrame> m_dataFrames; +}; + +#endif + diff --git a/src/stringutils.cpp b/src/stringutils.cpp new file mode 100644 index 0000000..3d30943 --- /dev/null +++ b/src/stringutils.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** +                               stringutils.cpp +                             ------------------- +    begin                : Tue Nov 06 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "stringutils.h" + +using namespace std; + +string trim(const string& s) +{ +    // find end of whitespace at the beginning +    string::size_type posBegin = s.find_first_not_of(" \011\012\015"); +    if(posBegin == string::npos) +        return string(); + +    // find beginning of whitespace at the end +    string::size_type posEnd = s.find_last_not_of(" \011\012\015"); + +    return s.substr(posBegin, posEnd - posBegin + 1); +} + +vector<string> split(const string& s, const string& separators) +{ +    vector<string> words; +    if(s.empty()) +        return words; + +    string::size_type pos = s.find_first_of(separators); +    string::size_type posOld = 0; +    while(pos != string::npos) +    { +        words.push_back(s.substr(posOld, pos - posOld)); +        posOld = pos + 1; + +        pos = s.find_first_of(separators, posOld); +    } + +    words.push_back(s.substr(posOld)); + +    return words; +} + +vector<string> splitQuoted(const string& s, const string& separators, const string& quotes) +{ +    if(s.empty()) +        return vector<string>(); + +    vector<string> words(1); +    string::size_type pos = s.find_first_of(separators + quotes); +    string::size_type posOld = 0; +    bool quoted = false; + +    while(true) +    { +        words.back() += s.substr(posOld, pos - posOld); +        posOld = pos + 1; + +        if(pos == string::npos) +            return words; + +        if(separators.find(s[pos]) != string::npos) +        { +            // separator found + +            words.push_back(string()); + +            pos = s.find_first_of(separators + quotes, posOld); +        } +        else +        { +            // quote found + +            posOld = pos + 1; + +            quoted = !quoted; + +            if(quoted) +                pos = s.find_first_of(quotes, posOld); +            else +                pos = s.find_first_of(separators + quotes, posOld); +        } +    } +} + diff --git a/src/stringutils.h b/src/stringutils.h new file mode 100644 index 0000000..b181b5e --- /dev/null +++ b/src/stringutils.h @@ -0,0 +1,49 @@ +/*************************************************************************** +                                stringutils.h +                             ------------------- +    begin                : Tue Nov 06 2007 +    copyright            : (C) 2007 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef STRINGUTILS_H +#define STRINGUTILS_H + +#include <sstream> +#include <string> +#include <vector> + +std::string trim(const std::string& s); +std::vector<std::string> split(const std::string& s, const std::string& separators); +std::vector<std::string> splitQuoted(const std::string& s, const std::string& separators, const std::string& quotes = "\""); + +template<class T> +std::string toString(const T& t) +{ +    std::ostringstream stream; +    stream << t; + +    return stream.str(); +} + +template<class T> +T fromString(const std::string& s) +{ +    std::istringstream stream(s); +    T t = T(); +    stream >> t; + +    return t; +} + +#endif + diff --git a/src/templates/cpp_template b/src/templates/cpp_template new file mode 100644 index 0000000..6afef5d --- /dev/null +++ b/src/templates/cpp_template @@ -0,0 +1,16 @@ +/*************************************************************************** +                          |FILENAME|  -  description +                             ------------------- +    begin                : |DATE| +    copyright            : (C) |YEAR| by |AUTHOR| +    email                : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ diff --git a/src/templates/header_template b/src/templates/header_template new file mode 100644 index 0000000..6afef5d --- /dev/null +++ b/src/templates/header_template @@ -0,0 +1,16 @@ +/*************************************************************************** +                          |FILENAME|  -  description +                             ------------------- +    begin                : |DATE| +    copyright            : (C) |YEAR| by |AUTHOR| +    email                : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ diff --git a/src/traffic_window.cpp b/src/traffic_window.cpp new file mode 100644 index 0000000..7296db5 --- /dev/null +++ b/src/traffic_window.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** +                             traffic_window.cpp +                             ------------------- +    begin                : Thu Jul 04 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "device.h" +#include "setting.h" +#include "settingstore.h" +#include "traffic_window.h" + +using namespace std; + +TrafficWindow::TrafficWindow() +    : Window(), m_curDev(0) +{ +} + +TrafficWindow::~TrafficWindow() +{ +} + +void TrafficWindow::processKey(int key) +{ +    switch(key) +    { +        case KEY_RIGHT: +        case KEY_DOWN: +        case KEY_NPAGE: +        case KEY_ENTER: +        case '\n': +        case '\t': +        case '\015': +            m_curDev += showMultipleDevices() ? getHeight() / 9 : 1; +            break; +        case KEY_LEFT: +        case KEY_UP: +        case KEY_PPAGE: +            m_curDev -= showMultipleDevices() ? getHeight() / 9 : 1; +            break; +    } +} + +void TrafficWindow::printTraffic(const vector<Device*>& devices) +{ +    if((unsigned int) m_curDev >= devices.size() || m_curDev < 0) +        m_curDev = 0; + +    // print data of the current device(s) +    if(!showMultipleDevices()) +    { +        devices[m_curDev]->print(*this); +    } +    else +    { +        if((unsigned int) getHeight() / 9 >= devices.size()) +            m_curDev = 0; + +        int i = m_curDev; +        while(getHeight() - getY() >= 9) +        { +            devices[i++]->print(*this); + +            if((unsigned int) i >= devices.size()) +                break; +        } +    } +} + +bool TrafficWindow::showMultipleDevices() +{ +    return SettingStore::get("MultipleDevices"); +} + diff --git a/src/traffic_window.h b/src/traffic_window.h new file mode 100644 index 0000000..1baa246 --- /dev/null +++ b/src/traffic_window.h @@ -0,0 +1,43 @@ +/*************************************************************************** +                              traffic_window.h +                             ------------------- +    begin                : Thu Jul 04 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef TRAFFIC_WINDOW_H +#define TRAFFIC_WINDOW_H + +#include "window.h" + +#include <vector> + +class Device; + +class TrafficWindow : public Window +{ +    public: +        TrafficWindow(); +        ~TrafficWindow(); +         +        void processKey(int key); +        void printTraffic(const std::vector<Device*>& devices); +         +    private: +        bool showMultipleDevices(); +         +        int m_curDev; +}; + +#endif + diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..bfa7701 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,289 @@ +/*************************************************************************** +                                 window.cpp +                             ------------------- +    begin                : Thu Nov 25 2003 +    copyright            : (C) 2003 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include "window.h" + +using namespace std; + +Window::WindowStreamBuf::WindowStreamBuf(Window& window) +    : m_window(window) +{ +} + +Window::WindowStreamBuf::~WindowStreamBuf() +{ +} + +streamsize Window::WindowStreamBuf::xsputn(const char_type* str, streamsize n) +{ +    m_window.print(string(str, n)); +    return n; +} + +Window::WindowStreamBuf::int_type Window::WindowStreamBuf::overflow(int_type c) +{ +    if(c == traits_type::eof()) +        return c; + +    m_window.print((char) c); +    return c; +} + +Window::WindowStream::WindowStream(Window& window) +    : basic_ostream<char>(new WindowStreamBuf(window)) +{ +} + +Window::WindowStream::~WindowStream() +{ +    delete rdbuf(); +} + +Window::Window() + : m_visible(false), m_window(0), m_stream(*this) +{ +} + +Window::~Window() +{ +    hide(); +} + +// create window and display it +void Window::show(int x, int y, int width, int height) +{ +    if(m_window) +        return; +     +    m_window = newwin(height, width, y, x); +    clear(); +    refresh(); +     +    m_visible = true; +} + +// hide window and destroy it +void Window::hide() +{ +    if(!m_window) +        return; +     +    clear(); +    refresh(); +    delwin(m_window); +     +    m_window = 0; +     +    m_visible = false; +} + +// is the window currently visible? +bool Window::isVisible() +{ +    return m_visible; +} + +// refresh window +void Window::refresh() +{ +    if(m_window) +        wrefresh(m_window); +} + +// clear the content of the window +void Window::clear() +{ +    if(m_window) +        wclear(m_window); +} + +// move and resize window +void Window::resize(int x, int y, int width, int height) +{ +    if(!m_window) +        return; + +    wresize(m_window, height, width); +    mvwin(m_window, y, x); +} + +// return current window width +int Window::getWidth() +{ +    if(!m_window) +        return 0; + +    int width, height; +    getmaxyx(m_window, height, width); + +    return width; +} + +// return current window height +int Window::getHeight() +{ +    if(!m_window) +        return 0; + +    int width, height; +    getmaxyx(m_window, height, width); + +    return height; +} + +// return current distance to left screen edge +int Window::getLeft() +{ +    if(!m_window) +        return 0; + +    int x, y; +    getbegyx(m_window, y, x); + +    return x; +} + +// return current distance to top screen edge +int Window::getTop() +{ +    if(!m_window) +        return 0; + +    int x, y; +    getbegyx(m_window, y, x); + +    return y; +} + +// return current cursor position on the x-axis +int Window::getX() +{ +    if(!m_window) +        return 0; + +    int x, y; +    getyx(m_window, y, x); + +    return x; +} + +// return current cursor position on the y-axis +int Window::getY() +{ +    if(!m_window) +        return 0; + +    int x, y; +    getyx(m_window, y, x); + +    return y; +} + +// set current cursor x position +void Window::setX(int new_x) +{ +    if(!m_window) +        return; + +    wmove(m_window, getY(), new_x); +} + +// set current cursor y position +void Window::setY(int new_y) +{ +    if(!m_window) +        return; + +    wmove(m_window, new_y, getX()); +} + +// set current cursor position +void Window::setXY(int new_x, int new_y) +{ +    if(!m_window) +        return; + +    wmove(m_window, new_y, new_x); +} + +// print some text to the window +void Window::print(const string& text, int new_x, int new_y) +{ +    if(!m_window) +        return; +    if(new_x <= -1) +        new_x = getX(); +    if(new_y <= -1) +        new_y = getY(); +     +    mvwaddstr(m_window, new_y, new_x, text.c_str()); +} + +// print a char to the window +void Window::print(char text, int new_x, int new_y) +{ +    if(!m_window) +        return; +    if(new_x <= -1) +        new_x = getX(); +    if(new_y <= -1) +        new_y = getY(); +     +    mvwaddch(m_window, new_y, new_x, text); +} + +// print via stream to window +Window::WindowStream& Window::print(int x, int y) +{ +    if(x <= -1) +        x = getX(); +    if(y <= -1) +        y = getY(); +    setXY(x, y); + +    return m_stream; +} + +SubWindow::SubWindow(Window* parent) + : Window(), m_parent(parent) +{ +} + +SubWindow::~SubWindow() +{ +    hide(); +} + +// return parent window +Window* SubWindow::getParent() +{ +    return m_parent; +} + +// create window and display it +void SubWindow::show(int x, int y, int width, int height) +{ +    if(m_window) +        return; +     +    m_window = derwin(m_parent->m_window, height, width, y, x); +    clear(); +    refresh(); +     +    m_visible = true; +} + diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..fb36b08 --- /dev/null +++ b/src/window.h @@ -0,0 +1,142 @@ +/*************************************************************************** +                                  window.h +                             ------------------- +    begin                : Thu Jul 04 2002 +    copyright            : (C) 2002 - 2012 by Roland Riegel +    email                : feedback@roland-riegel.de + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include <ostream> +#include <streambuf> +#include <string> + +#include <curses.h> +#undef clear +#undef erase +#undef refresh + +class Form; + +class Window +{ +    public: +        class WindowStreamBuf : public std::basic_streambuf<char> +        { +            public: +                WindowStreamBuf(Window& window); +                ~WindowStreamBuf(); + +            protected: +                std::streamsize xsputn(const char_type* str, std::streamsize n); +                int_type overflow(int_type c = traits_type::eof()); + +            private: +                Window& m_window; +        }; + +        class WindowStream : public std::basic_ostream<char> +        { +            public: +                WindowStream(Window& window); +                ~WindowStream(); +        }; + +        Window(); +        virtual ~Window(); +         +        // create window and display it +        virtual void show(int x, int y, int width, int height); +         +        // hide window and destroy it +        virtual void hide(); +         +        // is the window currently visible? +        virtual bool isVisible(); +         +        // refresh window +        virtual void refresh(); +         +        // clear the content of the window +        virtual void clear(); +         +        // move and resize window +        virtual void resize(int x, int y, int width, int height); +         +        // return current window width +        virtual int getWidth(); +         +        // return current window height +        virtual int getHeight(); +         +        // return current distance to left screen edge +        virtual int getLeft(); +         +        // return current distance to top screen edge +        virtual int getTop(); +         +        // return current cursor position on the x-axis +        virtual int getX(); +         +        // return current cursor position on the y-axis +        virtual int getY(); +         +        // set current cursor x position +        virtual void setX(int new_x); +         +        // set current cursor y position +        virtual void setY(int new_y); +         +        // set current cursor position +        virtual void setXY(int new_x, int new_y); +         +        // print some text to the window +        virtual void print(const std::string& text, int new_x = -1, int new_y = -1); +         +        // print a char to the window +        virtual void print(char text, int new_x = -1, int new_y = -1); + +        // print via stream to the window +        virtual WindowStream& print(int x = -1, int y = -1); +         +    protected: +        friend class SubWindow; +        friend class Form; + +        bool m_visible; +        WINDOW* m_window; + +        WindowStream m_stream; +}; + +class SubWindow : public Window +{ +    public: +        SubWindow( Window* parent ); +        ~SubWindow(); +         +        // return parent window +        Window* getParent(); +         +        // create window and display it +        virtual void show(int x, int y, int width, int height); + +    private: +        friend class Form; + +        Window* m_parent; +}; + +#endif + | 
