├── .gitignore ├── COPYING ├── Makefile.am ├── README ├── autogen ├── compile ├── conf ├── Makefile.am └── main.cpp ├── configure.ac ├── get-istatserver.sh ├── readme.md ├── resource ├── Makefile.am ├── istatserver.1 ├── istatserver.conf ├── istatserver.conf.5 ├── istatserver_generated.conf ├── rc.d │ └── istatserver ├── systemd │ └── istatserver.service └── upstart │ └── istatserver.conf └── src ├── Argument.cpp ├── Argument.h ├── Avahi.cpp ├── Avahi.h ├── Certificate.cpp ├── Certificate.h ├── Clientset.cpp ├── Clientset.h ├── Conf.cpp ├── Conf.h ├── Daemon.cpp ├── Daemon.h ├── Database.cpp ├── Database.h ├── Makefile.am ├── Responses.cpp ├── Responses.h ├── Socket.cpp ├── Socket.h ├── Socketset.cpp ├── Socketset.h ├── Stats.cpp ├── Stats.h ├── System.h ├── Utility.cpp ├── Utility.h ├── main.cpp ├── main.h └── stats ├── StatBase.cpp ├── StatBase.h ├── StatsActivity.cpp ├── StatsActivity.h ├── StatsBattery.cpp ├── StatsBattery.h ├── StatsCPU.cpp ├── StatsCPU.h ├── StatsDisks.cpp ├── StatsDisks.h ├── StatsLoad.cpp ├── StatsLoad.h ├── StatsMemory.cpp ├── StatsMemory.h ├── StatsNetwork.cpp ├── StatsNetwork.h ├── StatsProcesses.cpp ├── StatsProcesses.h ├── StatsSensors.cpp ├── StatsSensors.h ├── StatsUptime.cpp └── StatsUptime.h /.gitignore: -------------------------------------------------------------------------------- 1 | ._* 2 | config.h 3 | config.log 4 | config.status 5 | config.guess 6 | config.sub 7 | configure 8 | config.h.in 9 | Makefile 10 | Makefile.in 11 | autom4te.cache 12 | aclocal.m4 13 | depcomp 14 | missing 15 | install-sh 16 | stamp-h1 17 | stamp-h2 18 | .deps 19 | .libs 20 | *.o 21 | *.lo 22 | *.exe 23 | *.so 24 | *.la 25 | *.a 26 | .DS_Store 27 | .DS_Store? 28 | .Spotlight-V100 29 | .Trashes 30 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | /* 2 | * Redistribution and use in source and binary forms, with or without 3 | * modification, are permitted provided that the following conditions are met: 4 | * 5 | * 1. Redistributions of source code must retain the above copyright 6 | * notice, this list of conditions and the following disclaimer. 7 | * 8 | * 2. Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * 12 | * 3. The name of the copyright holder may not be used to endorse or promote 13 | * products derived from this software without specific prior written 14 | * permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | * 27 | */ 28 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = . src conf resource 2 | 3 | EXTRA_DIST = README COPYING autogen 4 | 5 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | About iStat Server 2 | 3 | iStat Server is a system monitoring daemon that is used in conjunction with iStat View for iOS (https://bjango.com/ios/istat/) and iStat View for macOS (https://bjango.com/mac/istat/) to remotely monitor computers. 4 | 5 | 6 | Supported OSs 7 | - Linux 8 | - FreeBSD, DragonFly BSD, OpenBSD, NetBSD and other BSD based OSs 9 | - AIX 10 | - Solaris 11 | - HP-UX (Still in development and not tested) 12 | 13 | 14 | Requirements 15 | - C and C++ compilers such as gcc and g++. 16 | - Auto tools (autoconf and automake). 17 | - OpenSSL/libssl + development libraries. 18 | - sqlite3 + development libraries. 19 | - libxml2 + development libraries. 20 | 21 | Optional Libraries 22 | - libavahi + development libraries. 23 | - lm_sensors/libsensors4 + development libraries. 24 | 25 | We have a package guide available to help you install all the required packages for your OS - https://github.com/bjango/istatserverlinux/wiki/Package-Guide 26 | 27 | 28 | Building and starting iStat Server 29 | - cd /path/to/istatserver 30 | - ./autogen 31 | - ./configure 32 | - make 33 | - sudo make install 34 | - sudo /usr/local/bin/istatserver -d (daemon mode) 35 | 36 | A default passcode is generated on install. It can be found in the preference file, which is generally located at /usr/local/etc/istatserver/istatserver.conf. iStat View will ask for this passcode the first time you connect to your computer. 37 | 38 | 39 | Upgrading iStat Server 40 | Upgrades follow the same process as standard installs. Please stop istatserver if its running then run the normal build process. 41 | 42 | 43 | Example boot scripts for rc.d, upstart and system are located inside the resources folder. You may need to customize these depending on your OS 44 | 45 | Starting with systemd 46 | - sudo cp ./resource/systemd/istatserver.service /etc/systemd/system/istatserver.service 47 | - sudo service istatserver start 48 | 49 | Starting with upstart 50 | - sudo cp ./resource/upstart/istatserver.conf /etc/init/istatserver.conf 51 | - sudo start istatserver 52 | 53 | Starting with rc.d 54 | - sudo cp ./resource/rc.d/istatserver /etc/rc.d/istatserver 55 | - sudo /etc/rc.d/istatserver start 56 | -------------------------------------------------------------------------------- /autogen: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Jazzio Labs Autotools support (modified for istatserver) 4 | 5 | # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Mo McRoberts. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions 9 | # are met: 10 | # 1. Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # 2. Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # 3. The names of the author(s) of this software may not be used to endorse 16 | # or promote products derived from this software without specific prior 17 | # written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 | # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 21 | # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | # AUTHORS OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | AUTOHEADER26=${AUTOHEADER26-autoheader} 31 | ACLOCAL110=${ACLOCAL110-aclocal} 32 | AUTOMAKE110=${AUTOMAKE110-automake} 33 | AUTOCONF26=${AUTOCONF26-autoconf} 34 | 35 | appname="$0" 36 | srcdir="`pwd`" 37 | 38 | fail() { 39 | echo "$appname: $*" >&2 40 | exit 1 41 | } 42 | 43 | oprogress() { 44 | echo ">>> $*" 45 | } 46 | progress() { 47 | echo " +> $*" 48 | } 49 | 50 | test -r "$srcdir/configure.ac" || fail "Cannot find configure.ac in $srcdir" 51 | 52 | oprogress "Generating files in $srcdir" 53 | progress "Generating aclocal.m4" 54 | ${ACLOCAL110} || exit 55 | 56 | if egrep '^AC_CONFIG_HEADER' "$srcdir/configure.ac" >/dev/null ; then 57 | progress "Generating config.h.in" 58 | ${AUTOHEADER26} || exit 59 | fi 60 | if egrep "^AM_INIT_AUTOMAKE" "$srcdir/configure.ac" >/dev/null ; then 61 | progress "Generating Makefile.in from Makefile.am" 62 | ${AUTOMAKE110} --add-missing --copy || exit 63 | fi 64 | 65 | progress "Generating configure script" 66 | ${AUTOCONF26} || exit 67 | 68 | rm -rf autom4te.cache 69 | -------------------------------------------------------------------------------- /compile: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Wrapper for compilers which do not understand '-c -o'. 3 | 4 | scriptversion=2012-10-14.11; # UTC 5 | 6 | # Copyright (C) 1999-2013 Free Software Foundation, Inc. 7 | # Written by Tom Tromey . 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | # This file is maintained in Automake, please report 28 | # bugs to or send patches to 29 | # . 30 | 31 | nl=' 32 | ' 33 | 34 | # We need space, tab and new line, in precisely that order. Quoting is 35 | # there to prevent tools from complaining about whitespace usage. 36 | IFS=" "" $nl" 37 | 38 | file_conv= 39 | 40 | # func_file_conv build_file lazy 41 | # Convert a $build file to $host form and store it in $file 42 | # Currently only supports Windows hosts. If the determined conversion 43 | # type is listed in (the comma separated) LAZY, no conversion will 44 | # take place. 45 | func_file_conv () 46 | { 47 | file=$1 48 | case $file in 49 | / | /[!/]*) # absolute file, and not a UNC file 50 | if test -z "$file_conv"; then 51 | # lazily determine how to convert abs files 52 | case `uname -s` in 53 | MINGW*) 54 | file_conv=mingw 55 | ;; 56 | CYGWIN*) 57 | file_conv=cygwin 58 | ;; 59 | *) 60 | file_conv=wine 61 | ;; 62 | esac 63 | fi 64 | case $file_conv/,$2, in 65 | *,$file_conv,*) 66 | ;; 67 | mingw/*) 68 | file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` 69 | ;; 70 | cygwin/*) 71 | file=`cygpath -m "$file" || echo "$file"` 72 | ;; 73 | wine/*) 74 | file=`winepath -w "$file" || echo "$file"` 75 | ;; 76 | esac 77 | ;; 78 | esac 79 | } 80 | 81 | # func_cl_dashL linkdir 82 | # Make cl look for libraries in LINKDIR 83 | func_cl_dashL () 84 | { 85 | func_file_conv "$1" 86 | if test -z "$lib_path"; then 87 | lib_path=$file 88 | else 89 | lib_path="$lib_path;$file" 90 | fi 91 | linker_opts="$linker_opts -LIBPATH:$file" 92 | } 93 | 94 | # func_cl_dashl library 95 | # Do a library search-path lookup for cl 96 | func_cl_dashl () 97 | { 98 | lib=$1 99 | found=no 100 | save_IFS=$IFS 101 | IFS=';' 102 | for dir in $lib_path $LIB 103 | do 104 | IFS=$save_IFS 105 | if $shared && test -f "$dir/$lib.dll.lib"; then 106 | found=yes 107 | lib=$dir/$lib.dll.lib 108 | break 109 | fi 110 | if test -f "$dir/$lib.lib"; then 111 | found=yes 112 | lib=$dir/$lib.lib 113 | break 114 | fi 115 | if test -f "$dir/lib$lib.a"; then 116 | found=yes 117 | lib=$dir/lib$lib.a 118 | break 119 | fi 120 | done 121 | IFS=$save_IFS 122 | 123 | if test "$found" != yes; then 124 | lib=$lib.lib 125 | fi 126 | } 127 | 128 | # func_cl_wrapper cl arg... 129 | # Adjust compile command to suit cl 130 | func_cl_wrapper () 131 | { 132 | # Assume a capable shell 133 | lib_path= 134 | shared=: 135 | linker_opts= 136 | for arg 137 | do 138 | if test -n "$eat"; then 139 | eat= 140 | else 141 | case $1 in 142 | -o) 143 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 144 | eat=1 145 | case $2 in 146 | *.o | *.[oO][bB][jJ]) 147 | func_file_conv "$2" 148 | set x "$@" -Fo"$file" 149 | shift 150 | ;; 151 | *) 152 | func_file_conv "$2" 153 | set x "$@" -Fe"$file" 154 | shift 155 | ;; 156 | esac 157 | ;; 158 | -I) 159 | eat=1 160 | func_file_conv "$2" mingw 161 | set x "$@" -I"$file" 162 | shift 163 | ;; 164 | -I*) 165 | func_file_conv "${1#-I}" mingw 166 | set x "$@" -I"$file" 167 | shift 168 | ;; 169 | -l) 170 | eat=1 171 | func_cl_dashl "$2" 172 | set x "$@" "$lib" 173 | shift 174 | ;; 175 | -l*) 176 | func_cl_dashl "${1#-l}" 177 | set x "$@" "$lib" 178 | shift 179 | ;; 180 | -L) 181 | eat=1 182 | func_cl_dashL "$2" 183 | ;; 184 | -L*) 185 | func_cl_dashL "${1#-L}" 186 | ;; 187 | -static) 188 | shared=false 189 | ;; 190 | -Wl,*) 191 | arg=${1#-Wl,} 192 | save_ifs="$IFS"; IFS=',' 193 | for flag in $arg; do 194 | IFS="$save_ifs" 195 | linker_opts="$linker_opts $flag" 196 | done 197 | IFS="$save_ifs" 198 | ;; 199 | -Xlinker) 200 | eat=1 201 | linker_opts="$linker_opts $2" 202 | ;; 203 | -*) 204 | set x "$@" "$1" 205 | shift 206 | ;; 207 | *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) 208 | func_file_conv "$1" 209 | set x "$@" -Tp"$file" 210 | shift 211 | ;; 212 | *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) 213 | func_file_conv "$1" mingw 214 | set x "$@" "$file" 215 | shift 216 | ;; 217 | *) 218 | set x "$@" "$1" 219 | shift 220 | ;; 221 | esac 222 | fi 223 | shift 224 | done 225 | if test -n "$linker_opts"; then 226 | linker_opts="-link$linker_opts" 227 | fi 228 | exec "$@" $linker_opts 229 | exit 1 230 | } 231 | 232 | eat= 233 | 234 | case $1 in 235 | '') 236 | echo "$0: No command. Try '$0 --help' for more information." 1>&2 237 | exit 1; 238 | ;; 239 | -h | --h*) 240 | cat <<\EOF 241 | Usage: compile [--help] [--version] PROGRAM [ARGS] 242 | 243 | Wrapper for compilers which do not understand '-c -o'. 244 | Remove '-o dest.o' from ARGS, run PROGRAM with the remaining 245 | arguments, and rename the output as expected. 246 | 247 | If you are trying to build a whole package this is not the 248 | right script to run: please start by reading the file 'INSTALL'. 249 | 250 | Report bugs to . 251 | EOF 252 | exit $? 253 | ;; 254 | -v | --v*) 255 | echo "compile $scriptversion" 256 | exit $? 257 | ;; 258 | cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) 259 | func_cl_wrapper "$@" # Doesn't return... 260 | ;; 261 | esac 262 | 263 | ofile= 264 | cfile= 265 | 266 | for arg 267 | do 268 | if test -n "$eat"; then 269 | eat= 270 | else 271 | case $1 in 272 | -o) 273 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 274 | # So we strip '-o arg' only if arg is an object. 275 | eat=1 276 | case $2 in 277 | *.o | *.obj) 278 | ofile=$2 279 | ;; 280 | *) 281 | set x "$@" -o "$2" 282 | shift 283 | ;; 284 | esac 285 | ;; 286 | *.c) 287 | cfile=$1 288 | set x "$@" "$1" 289 | shift 290 | ;; 291 | *) 292 | set x "$@" "$1" 293 | shift 294 | ;; 295 | esac 296 | fi 297 | shift 298 | done 299 | 300 | if test -z "$ofile" || test -z "$cfile"; then 301 | # If no '-o' option was seen then we might have been invoked from a 302 | # pattern rule where we don't need one. That is ok -- this is a 303 | # normal compilation that the losing compiler can handle. If no 304 | # '.c' file was seen then we are probably linking. That is also 305 | # ok. 306 | exec "$@" 307 | fi 308 | 309 | # Name of file we expect compiler to create. 310 | cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` 311 | 312 | # Create the lock directory. 313 | # Note: use '[/\\:.-]' here to ensure that we don't use the same name 314 | # that we are using for the .o file. Also, base the name on the expected 315 | # object file name, since that is what matters with a parallel build. 316 | lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d 317 | while true; do 318 | if mkdir "$lockdir" >/dev/null 2>&1; then 319 | break 320 | fi 321 | sleep 1 322 | done 323 | # FIXME: race condition here if user kills between mkdir and trap. 324 | trap "rmdir '$lockdir'; exit 1" 1 2 15 325 | 326 | # Run the compile. 327 | "$@" 328 | ret=$? 329 | 330 | if test -f "$cofile"; then 331 | test "$cofile" = "$ofile" || mv "$cofile" "$ofile" 332 | elif test -f "${cofile}bj"; then 333 | test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" 334 | fi 335 | 336 | rmdir "$lockdir" 337 | exit $ret 338 | 339 | # Local Variables: 340 | # mode: shell-script 341 | # sh-indentation: 2 342 | # eval: (add-hook 'write-file-hooks 'time-stamp) 343 | # time-stamp-start: "scriptversion=" 344 | # time-stamp-format: "%:y-%02m-%02d.%02H" 345 | # time-stamp-time-zone: "UTC" 346 | # time-stamp-end: "; # UTC" 347 | # End: 348 | -------------------------------------------------------------------------------- /conf/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_PROGRAMS = istatserverconf 2 | istatserverconf_SOURCES = main.cpp 3 | -------------------------------------------------------------------------------- /conf/main.cpp: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | # include "config.h" 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #ifdef HAVE_ERRNO_H 11 | # include "errno.h" 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | int 24 | main(int argc, char **argv) 25 | { 26 | static FILE * fp = NULL; 27 | 28 | char buf[1024]; 29 | 30 | vector lines; 31 | vector lines_old; 32 | 33 | bool generatePasscode = false; 34 | bool added_disk_labels = false; 35 | 36 | string argument; 37 | int c; 38 | for (c = 1; c < argc; c++) 39 | { 40 | argument = string(argv[c]); 41 | 42 | if (argument == "-p") 43 | { 44 | generatePasscode = true; 45 | } 46 | } 47 | 48 | string path_old = string(CONFIG_PATH) + "istatserver.conf.old"; 49 | fp = fopen(path_old.c_str(), "r"); 50 | if(fp) 51 | { 52 | while (fgets(buf, sizeof(buf), fp)){ 53 | string line = string(buf); 54 | lines_old.push_back(line); 55 | } 56 | fclose(fp); 57 | fp = NULL; 58 | } 59 | 60 | string path = string(CONFIG_PATH) + "istatserver.conf"; 61 | if (!(fp = fopen(path.c_str(), "r"))) return 0; 62 | 63 | while (fgets(buf, sizeof(buf), fp)) 64 | { 65 | string line = string(buf); 66 | 67 | bool found_old_line = false; 68 | if(lines_old.size() > 0) 69 | { 70 | if(line.find("disk_rename_label") != std::string::npos) 71 | { 72 | string key = line.substr(0, line.find(" ")); 73 | 74 | if(!added_disk_labels) 75 | { 76 | for (vector::iterator cur = lines_old.begin(); cur < lines_old.end(); ++cur) 77 | { 78 | if((*cur).find("disk_rename_label") != std::string::npos) 79 | { 80 | lines.push_back((*cur)); 81 | } 82 | } 83 | } 84 | found_old_line = true; 85 | added_disk_labels = true; 86 | } 87 | else if(line.length() > 0 && line.substr(0, 1) != "#") 88 | { 89 | string::size_type pos = line.find_first_of(" \t"); 90 | if(pos != std::string::npos) 91 | { 92 | string key = line.substr(0, pos); 93 | 94 | if(key == "server_code" && generatePasscode == true) 95 | { 96 | srand(time(NULL)); 97 | int c = (rand()%88888) + 10000; 98 | 99 | stringstream code; 100 | code << c; 101 | 102 | cout << "generating passcode" << endl; 103 | 104 | line = "server_code " + code.str() + "\n"; 105 | } 106 | else 107 | { 108 | for (vector::iterator cur = lines_old.begin(); cur < lines_old.end(); ++cur) 109 | { 110 | if((*cur).find(key) == 0) 111 | { 112 | lines.push_back((*cur)); 113 | found_old_line = true; 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | 121 | if(!found_old_line) 122 | { 123 | if(line.length() > 0 && line.substr(0, 1) != "#") 124 | { 125 | string::size_type pos = line.find_first_of(" \t"); 126 | if(pos != std::string::npos) 127 | { 128 | string key = line.substr(0, pos); 129 | 130 | if(key == "server_code" && generatePasscode == true) 131 | { 132 | srand(time(NULL)); 133 | int c = (rand()%88888) + 10000; 134 | 135 | stringstream code; 136 | code << c; 137 | 138 | cout << "generating passcode" << endl; 139 | 140 | line = "server_code " + code.str() + "\n"; 141 | } 142 | } 143 | } 144 | 145 | if(!found_old_line) 146 | lines.push_back(line); 147 | } 148 | } 149 | 150 | if(lines.size() > 0) 151 | { 152 | string new_path = string(CONFIG_PATH) + "istatserver.conf"; 153 | ofstream out(new_path.c_str()); 154 | 155 | for (vector::iterator cur = lines.begin(); cur < lines.end(); ++cur) 156 | { 157 | //cout << (*cur); 158 | out << (*cur); 159 | } 160 | 161 | out.close(); 162 | } 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /get-istatserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # This script is meant for quick & easy install via: 5 | # $ curl -fsSL https://raw.githubusercontent.com/bjango/istatserverlinux/master/get-istatserver.sh 6 | # $ sh get-istatserver.sh 7 | # 8 | 9 | command_exists() { 10 | command -v "$@" > /dev/null 2>&1 11 | } 12 | 13 | get_distribution() { 14 | lsb_dist="" 15 | 16 | if [ -r /etc/os-release ]; then 17 | lsb_dist="$(. /etc/os-release && echo "$ID")" 18 | else 19 | lsb_dist="$(uname)" 20 | fi 21 | 22 | echo "$lsb_dist" 23 | } 24 | 25 | get_distribution_like() { 26 | lsb_dist_like="" 27 | 28 | if [ -r /etc/os-release ]; then 29 | lsb_dist_like="$(. /etc/os-release && echo "$ID_LIKE")" 30 | fi 31 | 32 | echo "$lsb_dist_like" 33 | } 34 | 35 | we_did_it() { 36 | if command_exists istatserver && [ -e /usr/local/etc/istatserver/istatserver.conf ]; then 37 | ( 38 | set -x 39 | $sh_c 'istatserver -v' 40 | ) || true 41 | fi 42 | 43 | echo 44 | echo "Perfetto, you got yourself a brand new iStat Server." 45 | echo 46 | echo "You can now run it as a daemon using the following command:" 47 | echo " sudo /usr/local/bin/istatserver -d" 48 | echo 49 | echo "The istatserver config file is located at" 50 | echo " /usr/local/etc/istatserver/istatserver.conf" 51 | echo 52 | echo "iStat View will ask for a passcode the first time you connect." 53 | echo "You can edit this passcode in the istatserver config file." 54 | echo 55 | echo "Here is your current passcode" 56 | grep -w /usr/local/etc/istatserver/istatserver.conf -e server_code | grep -v "#" | sed -e "s/server_code//g" | sed -e 's/[ \t]//g' 57 | echo 58 | echo "Make sure to take a look at the documentation at:" 59 | echo "https://bjango.com/help/istat3/istatserverlinux/" 60 | echo 61 | echo "Learn how to run istatserver at boot:" 62 | echo "https://github.com/bjango/istatserverlinux#starting-istat-server-at-boot" 63 | echo 64 | } 65 | 66 | istat_pls() { 67 | echo "# Executing iStat Server for Linux install script" 68 | 69 | user="$(id -un 2>/dev/null || true)" 70 | 71 | sh_c='sh -c' 72 | if [ "$user" != 'root' ]; then 73 | if command_exists sudo; then 74 | sh_c='sudo -E sh -c' 75 | else 76 | if command_exists su; then 77 | sh_c='su -c' 78 | else 79 | echo "Error: this installer needs the ability to run commands as root." 80 | echo "We are unable to find either 'sudo' or 'su' available to make this happen." 81 | exit 1 82 | fi 83 | fi 84 | fi 85 | 86 | # Some platform detection 87 | lsb_dist=$( get_distribution ) 88 | lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" 89 | 90 | lsb_dist_like=$( get_distribution_like ) 91 | lsb_dist_like="$(echo "$lsb_dist_like" | tr '[:upper:]' '[:lower:]')" 92 | 93 | 94 | # Check if OS is supported or find what OS it is like and try that instead 95 | case "$lsb_dist" in 96 | ubuntu|debian|raspbian|linuxmint|elementary|centos|fedora|freebsd|dragonfly|netbsd|solus|arch|opensuse|manjaro|slackware|sabayon|gentoo) 97 | ;; 98 | *) 99 | case "$lsb_dist_like" in 100 | ubuntu|debian) 101 | lsb_dist="ubuntu"; 102 | ;; 103 | fedora) 104 | lsb_dist="fedora"; 105 | ;; 106 | freebsd) 107 | lsb_dist="freebsd"; 108 | ;; 109 | arch) 110 | lsb_dist="arch"; 111 | ;; 112 | opensuse) 113 | lsb_dist="opensuse"; 114 | ;; 115 | esac 116 | esac 117 | 118 | 119 | # Run setup for each distribution accordingly 120 | 121 | echo "Installing required packages" 122 | 123 | case "$lsb_dist" in 124 | ubuntu|debian|raspbian|linuxmint|elementary) 125 | $sh_c "apt-get update -qq > /dev/null" 126 | $sh_c "apt-get install -y -qq curl g++ autoconf autogen libxml2-dev libssl-dev libsqlite3-dev libsensors4-dev libavahi-common-dev libavahi-client-dev > /dev/null" 127 | ;; 128 | centos|fedora) 129 | if [ -r /bin/dnf ]; then 130 | $sh_c "dnf -q -y install curl autoconf automake gcc-c++ libxml2-devel openssl-devel sqlite-devel lm_sensors lm_sensors-devel avahi-devel > /dev/null" 131 | else 132 | $sh_c "yum -q -y install curl autoconf automake gcc-c++ libxml2-devel openssl-devel sqlite-devel lm_sensors lm_sensors-devel avahi-devel > /dev/null" 133 | fi 134 | ;; 135 | freebsd|dragonfly) 136 | $sh_c "env ASSUME_ALWAYS_YES=YES pkg install curl autoconf automake openssl sqlite > /dev/null" 137 | ;; 138 | solus) 139 | $sh_c "eopkg install -y -c system.devel > /dev/null" 140 | $sh_c "eopkg install -y curl openssl-devel sqlite3-devel lm_sensors-devel > /dev/null" 141 | ;; 142 | opensuse) 143 | $sh_c "zypper install -y gcc-c++ libxml2-devel autoconf automake curl openssl-devel sqlite3-devel > /dev/null" 144 | ;; 145 | #openbsd) 146 | # $sh_c "pkg_add -I automake-1.9.6p12 autoconf-2.69p2 > /dev/null" 147 | # ;; 148 | arch|manjaro) 149 | $sh_c "pacman -S --noconfirm automake autoconf openssl sqlite > /dev/null || :" 150 | ;; 151 | netbsd) 152 | $sh_c "pkg_add -I automake autoconf > /dev/null || :" 153 | ;; 154 | slackware) 155 | $sh_c "slackpkg -batch=on -default_answer=y install automake autoconf gcc-g++ curl lm_sensors > /dev/null || :" 156 | ;; 157 | sabayon|gentoo) 158 | $sh_c "emerge --ask=n automake autoconf gcc curl > /dev/null || :" 159 | ;; 160 | *) 161 | echo "unsupported OS"; 162 | exit 1 163 | ;; 164 | esac 165 | 166 | if [ -r ./istatserverlinux ]; then 167 | $sh_c "rm -r ./istatserverlinux" 168 | fi 169 | 170 | echo "Downloading istatserver" 171 | $sh_c "curl -fsSL https://github.com/bjango/istatserverlinux/archive/master.tar.gz -o istatserverlinux.tar.gz" 172 | 173 | echo "Extracting istatserver" 174 | $sh_c "tar -zxf istatserverlinux.tar.gz" 175 | $sh_c "mv istatserverlinux-* istatserverlinux" 176 | 177 | echo "Building istatserver" 178 | $sh_c "cd istatserverlinux && ./autogen > /dev/null" 179 | $sh_c "cd istatserverlinux && ./configure > /dev/null" 180 | $sh_c "cd istatserverlinux && make > /dev/null" 181 | $sh_c "cd istatserverlinux && make install > /dev/null" 182 | 183 | echo "Cleaning up" 184 | $sh_c "rm -r ./istatserverlinux > /dev/null" 185 | $sh_c "rm ./istatserverlinux.tar.gz > /dev/null" 186 | we_did_it 187 | exit 0 188 | } 189 | 190 | istat_pls 191 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # iStat Server 2 | 3 | iStat Server is a system monitoring daemon that is used in conjunction with [iStat View for iOS](https://bjango.com/ios/istat/) and [iStat View for macOS](https://bjango.com/mac/istat/) to remotely monitor computers. 4 | 5 | ----- 6 | 7 | ### Quick Install 8 | ``` 9 | curl -fsSL https://raw.githubusercontent.com/bjango/istatserverlinux/master/get-istatserver.sh -o istatserverlinux.sh && sh istatserverlinux.sh 10 | ``` 11 | 12 | Quick install will install and update any required packages. If you do not want packages installed or updated automatically then please perform a manual install using the instructions below 13 | 14 | ----- 15 | 16 | ### Supported OSs 17 | - Linux 18 | - FreeBSD, DragonFly BSD, OpenBSD, NetBSD and other BSD based OSs 19 | - AIX 20 | - Solaris 21 | - HP-UX (Still in development and not tested) 22 | 23 | ----- 24 | 25 | ### Requirements 26 | - C and C++ compilers such as gcc and g++. 27 | - Auto tools (autoconf and automake). 28 | - OpenSSL/libssl + development libraries. 29 | - sqlite3 + development libraries. 30 | - libxml2 + development libraries. 31 | 32 | We have a [package guide available](https://github.com/bjango/istatserverlinux/wiki/Package-Guide) to help you install all the required packages for your OS. 33 | 34 | ----- 35 | 36 | ### Building and starting iStat Server 37 | - [Download](https://github.com/bjango/istatserverlinux/archive/master.tar.gz) and decompress source 38 | - cd /path/to/istatserver 39 | - ./autogen 40 | - ./configure 41 | - make 42 | - sudo make install 43 | - sudo /usr/local/bin/istatserver -d (daemon mode) 44 | 45 | 46 | A 5 digit passcode is generated by the install script. It can be found in the preference file, which is generally located at **/usr/local/etc/istatserver/istatserver.conf**. iStat View will ask for this passcode the first time you connect to your computer. 47 | 48 | ----- 49 | 50 | ### Upgrading iStat Server 51 | Upgrades follow the same process as standard installs. Please stop istatserver if it is running then run the normal build process. 52 | 53 | ----- 54 | 55 | ### Starting iStat Server at boot 56 | iStat Server does not install any scripts to start itself at boot. Sample scripts for rc.d, upstart and systemd are included in the resources directory. You may need to customize them depending on your OS. 57 | 58 | ### Starting with systemd 59 | - sudo cp ./resource/systemd/istatserver.service /etc/systemd/system/istatserver.service 60 | - sudo service istatserver start 61 | 62 | ### Starting with upstart 63 | - sudo cp ./resource/upstart/istatserver.conf /etc/init/istatserver.conf 64 | - sudo start istatserver 65 | 66 | ### Starting with rc.d 67 | - sudo cp ./resource/rc.d/istatserver /etc/rc.d/istatserver 68 | - sudo /etc/rc.d/istatserver start 69 | 70 | ----- 71 | 72 | iStat Server is based on [istatd](https://github.com/tiwilliam/istatd) by William Tisäter. 73 | 74 | ----- 75 | 76 | ``` 77 | ::::::::: ::::::: :::: :::: ::: :::::::: :::::::: 78 | :+: :+: :+: :+: :+: :+:+: :+: :+: :+: :+: :+: 79 | +:+ +:+ +:+ +:+ +:+ :+:+:+ +:+ +:+ +:+ +:+ 80 | +#++:++#+ +#+ +#++:++#++: +#+ +:+ +#+ :#: +#+ +:+ 81 | +#+ +#+ +#+ +#+ +#+ +#+ +#+#+# +#+ +#+# +#+ +#+ 82 | #+# #+# #+# #+# #+# #+# #+# #+#+# #+# #+# #+# #+# 83 | ######### ##### ### ### ### #### ######## ######## 84 | ``` 85 | -------------------------------------------------------------------------------- /resource/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | dist_man_MANS = istatserver.1 istatserver.conf.5 3 | EXTRA_DIST = istatserver.conf istatserver_generated.conf systemd upstart rc.d 4 | 5 | #dist_sysconf_DATA = istatserver.conf 6 | 7 | MKDIR=/bin/mkdir 8 | MV=/bin/mv 9 | ADDUSER=/usr/sbin/useradd 10 | ADDGROUP=/usr/sbin/groupadd 11 | ADDUSERPW=/usr/sbin/pw 12 | MKGROUP=/usr/bin/mkgroup 13 | OLD_CONFIG_FILE = $(sysconfdir)/istat.conf 14 | DEFAULT_CONFIG_FILE = $(sysconfdir)/istatserver/istatserver.conf 15 | DEFAULT_CONFIG_FILE_MV = $(sysconfdir)/istatserver/istatserver.conf.old 16 | DEFAULT_CONFIG_GENERATED_FILE = $(sysconfdir)/istatserver/istatserver_generated.conf 17 | CERT_FILE = $(sysconfdir)/istatserver/cert.pem 18 | KEY_FILE = $(sysconfdir)/istatserver/key.pem 19 | CACHE_FILE = $(sysconfdir)/istatserver/clients.dat 20 | 21 | install-exec-hook: 22 | @if test -f "$(ADDUSERPW)" ; then \ 23 | $(ADDUSERPW) groupadd istat >/dev/null 2>&1 || true ; \ 24 | $(ADDUSERPW) useradd istat -g istat >/dev/null 2>&1 || true ; \ 25 | fi 26 | 27 | @if test -f "$(ADDGROUP)" ; then \ 28 | $(ADDGROUP) istat >/dev/null 2>&1 || true ; \ 29 | fi 30 | 31 | @if test -f "$(MKGROUP)" ; then \ 32 | $(MKGROUP) istat >/dev/null 2>&1 || true ; \ 33 | fi 34 | 35 | @if test -f "$(ADDUSER)" ; then \ 36 | $(ADDUSER) --system -g istat istat >/dev/null 2>&1 || true ; \ 37 | $(ADDUSER) -g istat istat >/dev/null 2>&1 || true ; \ 38 | fi 39 | 40 | $(MKDIR) -p "$(DESTDIR)$(sysconfdir)"; 41 | $(MKDIR) -p "$(DESTDIR)$(sysconfdir)/istatserver/" 42 | $(MKDIR) -p "/var/run/istatserver" || true ; 43 | chown istat:istat "/var/run/istatserver" || true ; 44 | chown istat:istat "$(DESTDIR)$(sysconfdir)/istatserver/" || true ; 45 | chmod 755 "$(DESTDIR)$(sysconfdir)/istatserver/" || true ; 46 | 47 | @if test -f "$(DESTDIR)$(OLD_CONFIG_FILE)" ; then \ 48 | $(MV) "$(DESTDIR)$(OLD_CONFIG_FILE)" "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; \ 49 | fi 50 | 51 | @if test -f "/var/cache/istat/clients.dat" ; then \ 52 | $(MV) "/var/cache/istat/clients.dat" "$(DESTDIR)$(sysconfdir)/istatserver/clients.dat" ; \ 53 | chown istat:istat "$(DESTDIR)$(sysconfdir)/istatserver/clients.dat" || true ; \ 54 | fi 55 | 56 | @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; then \ 57 | $(MV) "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" "$(DESTDIR)$(DEFAULT_CONFIG_FILE_MV)" ; \ 58 | $(INSTALL_DATA) "$(srcdir)/istatserver.conf" "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ 59 | echo "$@ running conf updater"; \ 60 | ../conf/istatserverconf || true ; \ 61 | rm "$(DESTDIR)$(DEFAULT_CONFIG_FILE_MV)" || true ; \ 62 | chown istat:istat "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" || true ; \ 63 | else \ 64 | echo "$(INSTALL_DATA) istatserver.conf $(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ 65 | $(INSTALL_DATA) "$(srcdir)/istatserver.conf" "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ 66 | echo "$@ running conf updater and generating passcode"; \ 67 | ../conf/istatserverconf -p || true ; \ 68 | chown istat:istat "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" || true ; \ 69 | fi 70 | 71 | @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_GENERATED_FILE)" ; then \ 72 | echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_CONFIG_GENERATED_FILE)" ; \ 73 | else \ 74 | echo "$(INSTALL_DATA) istatserver_generated.conf $(DESTDIR)$(DEFAULT_CONFIG_GENERATED_FILE)"; \ 75 | $(INSTALL_DATA) "$(srcdir)/istatserver_generated.conf" "$(DESTDIR)$(DEFAULT_CONFIG_GENERATED_FILE)"; \ 76 | fi 77 | 78 | uninstall-hook: 79 | @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_GENERATED_FILE)" ; then \ 80 | rm "$(DESTDIR)$(DEFAULT_CONFIG_GENERATED_FILE)"; \ 81 | fi 82 | 83 | @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; then \ 84 | rm "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ 85 | fi 86 | 87 | @if test -f "$(DESTDIR)$(CERT_FILE)" ; then \ 88 | rm "$(DESTDIR)$(CERT_FILE)"; \ 89 | fi 90 | 91 | @if test -f "$(DESTDIR)$(KEY_FILE)" ; then \ 92 | rm "$(DESTDIR)$(KEY_FILE)"; \ 93 | fi 94 | 95 | @if test -f "$(DESTDIR)$(CACHE_FILE)" ; then \ 96 | rm "$(DESTDIR)$(CACHE_FILE)"; \ 97 | fi 98 | -------------------------------------------------------------------------------- /resource/istatserver.1: -------------------------------------------------------------------------------- 1 | .Dd 2009-05-17 2 | .Dt istatserver 1 3 | .Os 4 | .Sh NAME 5 | .Nm istatserver 6 | .Nd system monitoring daemon 7 | .Sh SYNOPSIS 8 | .Nm 9 | .Op Fl c Ar config 10 | .Op Fl a Ar address 11 | .Op Fl p Ar port 12 | .Op Fl d 13 | 14 | .Sh DESCRIPTION 15 | .Nm 16 | is a system monitoring daemon that collects and stores performance monitoring data. 17 | You can then use iStat for iOS and iStat for macOS to remotely monitor your computer. 18 | 19 | .Sh OPTIONS 20 | .Bl -tag -width -indent-three 21 | .It Fl v 22 | Print version number 23 | .It Fl d 24 | Run in the process in background 25 | .It Fl a Ar address 26 | Listen for network connections on this address 27 | .It Fl p Ar port 28 | Listen for network connections on this port 29 | .It Fl u Ar user 30 | User to run daemon as 31 | .It Fl g Ar group 32 | Group to run daemon as 33 | .It Fl -pid Ar path 34 | Custom pid file location 35 | .It Fl -clear-sessions 36 | Reset list of authorized devices. 37 | .It Fl -verify 38 | Verify sqlite history database. 39 | .El 40 | .Pp 41 | .Sh FILES 42 | /usr/local/etc/istatserver/istatserver.conf 43 | .Pp 44 | Configuration for passcode, server port and more. 45 | .El 46 | .Sh SEE ALSO 47 | .Xr istatserver.conf 5 48 | -------------------------------------------------------------------------------- /resource/istatserver.conf: -------------------------------------------------------------------------------- 1 | # 2 | # istatserver.conf: Configuration for istatserver 3 | # 4 | 5 | # server_code is a 5 digit number by default but it can be anything you like including text 6 | server_code 12345 7 | 8 | # network_addr 127.0.0.1 9 | # network_port 5109 10 | # server_user istat 11 | # server_group istat 12 | # server_socket /tmp/istatserver.sock 13 | # server_pid /var/run/istatserver.pid 14 | 15 | # Set to 1 if you want to disable sqlite history storage. 16 | disable_history_storage 0 17 | 18 | # Set to 1 if you want to disable disk filtering based on mount path. 19 | disk_disable_filtering 0 20 | 21 | # Set to 1 if you want to use mount path as label instead of the device name. 22 | disk_mount_path_label 1 23 | 24 | # Set custom disk label. Will override all other labels. 25 | # disk_rename_label /dev/sda1 "root" 26 | # disk_rename_label /home "home" 27 | 28 | # End of file 29 | -------------------------------------------------------------------------------- /resource/istatserver.conf.5: -------------------------------------------------------------------------------- 1 | .Dd 2009-05-17 2 | .Dt istatserver.conf 5 3 | .Os 4 | .Sh NAME 5 | .Nm istatserver.conf 6 | .Nd configuration file for istatserver 7 | 8 | .Sh OPTIONS 9 | .Bl -tag -width -indent-three 10 | .It network_addr 11 | Address to bind (default: 0.0.0.0) 12 | 13 | .It network_port 14 | Port to bind (default: 5109) 15 | 16 | .It server_code 17 | Lock code needed when connecting to the server for the first time. 18 | 19 | .It server_socket 20 | Location of the unix socket. (default: /tmp/istatserver.sock) 21 | 22 | .It server_pid 23 | Location of the pid. (default: /var/run/istatserver.pid) 24 | 25 | .It server_user 26 | User to switch to when entering daemon mode. It's not recommended to use high privilaged users like root due to security reasons. Defaults to root if the user doesn't exist. (default: istat) 27 | 28 | .It server_group 29 | Group to switch to when entering daemon mode. Defaults to root if the group doesn't exist. (default: istat) 30 | 31 | .It disable_history_storage 32 | Set to 1 if you want to disable history storage (not recommended unless you have very limited disk space). 33 | 34 | 35 | .It disk_disable_filtering 36 | Set to 1 if you want to disable all mount path based disk filtering (excludes filesystems that you are unlikely to want to monitor). 37 | 38 | .It disk_mount_path_label 39 | Set to 1 if you want to use mount path as label instead of the device name. 40 | .It disk_rename_label 41 | Set custom disk label. Will override all other labels. You can use either the device name or mount path: 42 | 43 | disk_rename_label /dev/sda1 "root" 44 | 45 | disk_rename_label /home "home" 46 | .El 47 | .Sh SEE ALSO 48 | .Xr istatserver 1 49 | -------------------------------------------------------------------------------- /resource/istatserver_generated.conf: -------------------------------------------------------------------------------- 1 | # 2 | # istatserver_generated.conf: Configuration for istatserver 3 | # this file is generated by istatserver 4 | # do not modify 5 | 6 | -------------------------------------------------------------------------------- /resource/rc.d/istatserver: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | 4 | # PROVIDE: istatserver 5 | # REQUIRE: FILESYSTEMS NETWORKING netif 6 | # KEYWORD: shutdown 7 | 8 | . /etc/rc.subr 9 | 10 | name="istatserver" 11 | command="/usr/local/bin/istatserver" 12 | rcvar="istatserver_enable" 13 | command_args="-d" 14 | 15 | load_rc_config $name 16 | run_rc_command "$1" 17 | -------------------------------------------------------------------------------- /resource/systemd/istatserver.service: -------------------------------------------------------------------------------- 1 | # 2 | # istatserver daemon service unit file 3 | # 4 | 5 | [Unit] 6 | Description=System monitoring daemon for remote monitoring with iStat for iOS or iStat for macOS 7 | Documentation=man:istatserver(1) 8 | After=network.target 9 | 10 | [Service] 11 | ExecStart=/usr/local/bin/istatserver -d 12 | Restart=on-abort 13 | RestartSec=5 14 | Type=forking 15 | 16 | [Install] 17 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /resource/upstart/istatserver.conf: -------------------------------------------------------------------------------- 1 | # istatserver 2 | 3 | description "istatserver daemon" 4 | author "Bjango" 5 | 6 | start on (local-filesystems and net-device-up IFACE!=lo) 7 | stop on shutdown 8 | 9 | expect daemon 10 | expect fork 11 | respawn 12 | respawn limit 99 5 13 | 14 | script 15 | exec /usr/local/bin/istatserver -d 16 | end script 17 | -------------------------------------------------------------------------------- /src/Argument.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | #include "Argument.h" 36 | 37 | using namespace std; 38 | 39 | ArgumentSet::ArgumentSet(int argc, char ** argv) 40 | { 41 | int c; 42 | Argument temp; 43 | string argument, value; 44 | 45 | for (c = 1; c < argc; c++) 46 | { 47 | argument = string(argv[c]); 48 | 49 | if (argument.substr(0, 1) == "-") 50 | { 51 | // Handle long options 52 | if (argument.substr(1, 1) == "-") 53 | { 54 | // Is this a toggle flag or a flag with value? 55 | if (argument.find_first_of("=") < string::npos) 56 | { 57 | temp.value = argument.substr(argument.find_first_of("=") + 1); 58 | temp.argument = argument.substr(2, argument.find_first_of("=") - 2); 59 | } 60 | else 61 | { 62 | temp.value = "1"; 63 | temp.argument = argument.substr(2); 64 | } 65 | } 66 | else 67 | { 68 | if ((c + 1) < argc) 69 | value = string(argv[c + 1]); 70 | else 71 | value = "1"; 72 | 73 | if (value.substr(0, 1) == "-") 74 | value = "1"; 75 | 76 | argument = argument.substr(1); 77 | 78 | temp.value = value; 79 | temp.argument = argument; 80 | } 81 | 82 | this->args.push_back(temp); 83 | } 84 | } 85 | } 86 | 87 | bool ArgumentSet::is_set(const string & arg) 88 | { 89 | for (vector::iterator i = args.begin(); i != args.end(); i++) 90 | { 91 | if (i->argument == arg) 92 | if (i->value != "") 93 | return 1; 94 | } 95 | 96 | return 0; 97 | } 98 | 99 | string ArgumentSet::get(const string & arg, const std::string & val) 100 | { 101 | for (vector::iterator i = args.begin(); i != args.end(); i++) 102 | { 103 | if (i->argument == arg) 104 | return i->value; 105 | } 106 | 107 | return val; 108 | } 109 | -------------------------------------------------------------------------------- /src/Argument.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _ARGUMENT_H 33 | #define _ARGUMENT_H 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | class Argument 40 | { 41 | public: 42 | std::string value; 43 | std::string argument; 44 | }; 45 | 46 | class ArgumentSet 47 | { 48 | public: 49 | ArgumentSet(int argc, char ** argv); 50 | 51 | bool is_set(const std::string & arg); 52 | std::string get(const std::string & arg, const std::string & val = ""); 53 | 54 | private: 55 | std::vector args; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/Avahi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifdef HAVE_CONFIG_H 33 | # include "config.h" 34 | #endif 35 | 36 | #ifdef HAVE_LIBAVAHI_CLIENT 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include "Avahi.h" 48 | #include 49 | 50 | using namespace std; 51 | 52 | static AvahiEntryGroup *avahiGroup = NULL; 53 | static AvahiClient* avahiClient = NULL; 54 | static AvahiThreadedPoll* avahiThread = NULL; 55 | 56 | void AvahiGroupCallback(AvahiEntryGroup *_avahiGroup, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) 57 | { 58 | assert(_avahiGroup == avahiGroup || avahiGroup == NULL); 59 | avahiGroup = _avahiGroup; 60 | switch (state) 61 | { 62 | case AVAHI_ENTRY_GROUP_ESTABLISHED: 63 | { 64 | cout << "avahi successfully established" << endl; 65 | } 66 | break; 67 | case AVAHI_ENTRY_GROUP_COLLISION: 68 | case AVAHI_ENTRY_GROUP_FAILURE: 69 | { 70 | cout << "avahi entry group failure: " << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(avahiGroup))) << endl; 71 | } 72 | break; 73 | case AVAHI_ENTRY_GROUP_UNCOMMITED: 74 | case AVAHI_ENTRY_GROUP_REGISTERING: 75 | { 76 | } 77 | break; 78 | } 79 | return; 80 | } 81 | 82 | void AvahiCreateService(AvahiClient *avahiClient, AvahiPublisher *publisher) 83 | { 84 | assert(avahiClient); 85 | if (!avahiGroup) 86 | { 87 | avahiGroup = avahi_entry_group_new(avahiClient, AvahiGroupCallback, NULL); 88 | if (!avahiGroup) 89 | { 90 | cout << "avahi_entry_group_new() failed: " << avahi_strerror(avahi_client_errno(avahiClient)) << endl; 91 | return; 92 | } 93 | } 94 | if (avahi_entry_group_is_empty(avahiGroup)) 95 | { 96 | AvahiStringList *txt = NULL; 97 | txt = avahi_string_list_add_pair(txt, "name", publisher->name.c_str()); 98 | txt = avahi_string_list_add_pair(txt, "model", ""); 99 | 100 | char buffer [8]; 101 | int n = sprintf(buffer, "%d", publisher->protocol); 102 | if(n > 0){ 103 | txt = avahi_string_list_add_pair(txt, "protocol", buffer); 104 | } 105 | 106 | char platformBuffer [8]; 107 | n = sprintf(platformBuffer, "%d", publisher->platform); 108 | if(n > 0){ 109 | txt = avahi_string_list_add_pair(txt, "platform", platformBuffer); 110 | } 111 | 112 | int ret = avahi_entry_group_add_service_strlst( 113 | avahiGroup, 114 | AVAHI_IF_UNSPEC, 115 | AVAHI_PROTO_UNSPEC, 116 | (AvahiPublishFlags)0, 117 | publisher->uuid.c_str(), 118 | "_istatserver._tcp", 119 | "local.", 120 | NULL, 121 | publisher->port, 122 | txt 123 | ); 124 | if (ret < 0) 125 | { 126 | cout << "avahi_entry_group_add_service() failed: " << avahi_strerror(ret) << endl; 127 | return; 128 | } 129 | ret = avahi_entry_group_commit(avahiGroup); 130 | if (ret < 0) 131 | { 132 | cout << "avahi_entry_group_commit() failed: " << avahi_strerror(ret) << endl; 133 | return; 134 | } 135 | } 136 | return; 137 | } 138 | 139 | void AvahiCallback(AvahiClient *avahiClient, AvahiClientState state, void *data) 140 | { 141 | assert(avahiClient); 142 | 143 | AvahiPublisher *publisher = static_cast(data); 144 | 145 | switch (state) 146 | { 147 | case AVAHI_CLIENT_S_RUNNING: 148 | { 149 | AvahiCreateService(avahiClient, publisher); 150 | } 151 | break; 152 | case AVAHI_CLIENT_FAILURE: 153 | { 154 | cout << "avahi client failure: " << avahi_strerror(avahi_client_errno(avahiClient)) << endl; 155 | } 156 | break; 157 | case AVAHI_CLIENT_S_COLLISION: 158 | case AVAHI_CLIENT_S_REGISTERING: 159 | { 160 | if (avahiGroup) 161 | avahi_entry_group_reset(avahiGroup); 162 | } 163 | break; 164 | case AVAHI_CLIENT_CONNECTING: 165 | { 166 | } 167 | break; 168 | } 169 | } 170 | 171 | void AvahiPublisher::stop() 172 | { 173 | if(avahiClient == NULL) 174 | return; 175 | 176 | cout << "Closing avahi" << endl; 177 | avahi_client_free(avahiClient); 178 | } 179 | 180 | int AvahiPublisher::publish_service() 181 | { 182 | avahiThread = avahi_threaded_poll_new(); /* lost to never be found.. */ 183 | if (!avahiThread) 184 | { 185 | cout << "avahi_threaded_poll_new failed" << endl; 186 | return -1; 187 | } 188 | int error; 189 | avahiClient = avahi_client_new( 190 | avahi_threaded_poll_get(avahiThread), 191 | (AvahiClientFlags)0, 192 | AvahiCallback, 193 | this, 194 | &error 195 | ); 196 | if (!avahiClient) 197 | { 198 | cout << "avahi_client_new failed: " << avahi_strerror(error) << endl; 199 | return -1; 200 | } 201 | if (avahi_threaded_poll_start(avahiThread) < 0) 202 | { 203 | cout << "avahi_threaded_poll_start failed" << endl; 204 | return -1; 205 | } 206 | return 0; 207 | } 208 | 209 | #endif 210 | 211 | -------------------------------------------------------------------------------- /src/Avahi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "config.h" 33 | 34 | #ifdef HAVE_LIBAVAHI_CLIENT 35 | 36 | #ifndef _AVAHI_H 37 | #define _AVAHI_H 38 | 39 | class AvahiPublisher 40 | { 41 | public: 42 | int port; 43 | int platform; 44 | std::string name; 45 | std::string uuid; 46 | int protocol; 47 | int publish_service(); 48 | void stop(); 49 | }; 50 | #endif 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /src/Certificate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "Certificate.h" 33 | #include 34 | #include 35 | 36 | using namespace std; 37 | 38 | /* Generates a 2048-bit RSA key. */ 39 | EVP_PKEY * generate_key() 40 | { 41 | /* Allocate memory for the EVP_PKEY structure. */ 42 | EVP_PKEY * pkey = EVP_PKEY_new(); 43 | if(!pkey) 44 | { 45 | std::cerr << "Unable to create EVP_PKEY structure." << std::endl; 46 | return NULL; 47 | } 48 | 49 | /* Generate the RSA key and assign it to pkey. */ 50 | RSA * rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL); 51 | if(!EVP_PKEY_assign_RSA(pkey, rsa)) 52 | { 53 | std::cerr << "Unable to generate 2048-bit RSA key." << std::endl; 54 | EVP_PKEY_free(pkey); 55 | return NULL; 56 | } 57 | 58 | /* The key has been generated, return it. */ 59 | return pkey; 60 | } 61 | 62 | /* Generates a self-signed x509 certificate. */ 63 | X509 * generate_x509(EVP_PKEY * pkey) 64 | { 65 | /* Allocate memory for the X509 structure. */ 66 | X509 * x509 = X509_new(); 67 | if(!x509) 68 | { 69 | std::cerr << "Unable to create X509 structure." << std::endl; 70 | return NULL; 71 | } 72 | 73 | /* Set the serial number. */ 74 | ASN1_INTEGER_set(X509_get_serialNumber(x509), 1); 75 | 76 | /* This certificate is valid from now until exactly one year from now. */ 77 | X509_gmtime_adj(X509_get_notBefore(x509), 0); 78 | X509_gmtime_adj(X509_get_notAfter(x509), 31536000L); 79 | 80 | /* Set the public key for our certificate. */ 81 | X509_set_pubkey(x509, pkey); 82 | 83 | /* We want to copy the subject name to the issuer name. */ 84 | X509_NAME * name = X509_get_subject_name(x509); 85 | 86 | /* Set the country code and common name. */ 87 | X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"CA", -1, -1, 0); 88 | X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"istatd", -1, -1, 0); 89 | X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"localhost", -1, -1, 0); 90 | 91 | /* Now set the issuer name. */ 92 | X509_set_issuer_name(x509, name); 93 | 94 | /* Actually sign the certificate with our key. */ 95 | if(!X509_sign(x509, pkey, EVP_sha1())) 96 | { 97 | std::cerr << "Error signing certificate." << std::endl; 98 | X509_free(x509); 99 | return NULL; 100 | } 101 | 102 | return x509; 103 | } 104 | 105 | bool write_to_disk(EVP_PKEY * pkey, X509 * x509) 106 | { 107 | /* Open the PEM file for writing the key to disk. */ 108 | string privateKeyPath = string(CONFIG_PATH) + "key.pem"; 109 | FILE * pkey_file = fopen(privateKeyPath.c_str(), "wb"); 110 | if(!pkey_file) 111 | { 112 | std::cerr << "Unable to open \"key.pem\" for writing." << std::endl; 113 | return false; 114 | } 115 | 116 | /* Write the key to disk. */ 117 | bool ret = PEM_write_PrivateKey(pkey_file, pkey, NULL, NULL, 0, NULL, NULL); 118 | fclose(pkey_file); 119 | 120 | if(!ret) 121 | { 122 | std::cerr << "Unable to write private key to disk." << std::endl; 123 | return false; 124 | } 125 | 126 | /* Open the PEM file for writing the certificate to disk. */ 127 | string certPath = string(CONFIG_PATH) + "cert.pem"; 128 | FILE * x509_file = fopen(certPath.c_str(), "wb"); 129 | if(!x509_file) 130 | { 131 | std::cerr << "Unable to open \"cert.pem\" for writing." << std::endl; 132 | return false; 133 | } 134 | 135 | /* Write the certificate to disk. */ 136 | ret = PEM_write_X509(x509_file, x509); 137 | fclose(x509_file); 138 | 139 | if(!ret) 140 | { 141 | std::cerr << "Unable to write certificate to disk." << std::endl; 142 | return false; 143 | } 144 | 145 | return true; 146 | } 147 | 148 | int createSSLCertificate() 149 | { 150 | /* Generate the key. */ 151 | std::cout << "Generating RSA key..." << std::endl; 152 | 153 | EVP_PKEY * pkey = generate_key(); 154 | if(!pkey) 155 | return 1; 156 | 157 | /* Generate the certificate. */ 158 | std::cout << "Generating x509 certificate..." << std::endl; 159 | 160 | X509 * x509 = generate_x509(pkey); 161 | if(!x509) 162 | { 163 | EVP_PKEY_free(pkey); 164 | return 1; 165 | } 166 | 167 | /* Write the private key and certificate out to disk. */ 168 | std::cout << "Writing key and certificate to disk..." << std::endl; 169 | 170 | bool ret = write_to_disk(pkey, x509); 171 | EVP_PKEY_free(pkey); 172 | X509_free(x509); 173 | 174 | if(ret) 175 | { 176 | std::cout << "Success!" << std::endl; 177 | return 0; 178 | } 179 | 180 | return 1; 181 | } 182 | -------------------------------------------------------------------------------- /src/Certificate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "config.h" 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | int createSSLCertificate(); 41 | -------------------------------------------------------------------------------- /src/Clientset.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include "Utility.h" 42 | #include "Clientset.h" 43 | #include 44 | 45 | using namespace std; 46 | 47 | void ClientSet::authenticate(string uuid) 48 | { 49 | authenticatedClients.push_back(uuid); 50 | save_cache(); 51 | } 52 | 53 | int ClientSet::is_authenticated(string _duuid) 54 | { 55 | for (vector::const_iterator search = authenticatedClients.begin(); search != authenticatedClients.end(); ++search) 56 | { 57 | if (*search == _duuid) 58 | { 59 | return 1; 60 | } 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | void ClientSet::clear_cache(void) 67 | { 68 | if (this->cache_dir.length()) 69 | { 70 | stringstream path; 71 | string cache_file = "clients.dat"; 72 | path << this->cache_dir << cache_file; 73 | 74 | if (check_file_exist(path.str())) 75 | { 76 | if (unlink(path.str().c_str()) == 0) 77 | { 78 | cout << "Successfully cleared all sessions." << endl; 79 | } 80 | else 81 | { 82 | cout << "Could not clear sessions in '" << path.str() << "': " << strerror(errno) << endl; 83 | } 84 | } 85 | } 86 | } 87 | 88 | void ClientSet::save_cache(void) 89 | { 90 | if (this->cache_dir.length()) 91 | { 92 | stringstream path; 93 | string cache_file = "clients.dat"; 94 | path << this->cache_dir << cache_file; 95 | 96 | ofstream out(path.str().c_str()); 97 | chmod(path.str().c_str(), 0600); 98 | 99 | if (!out) 100 | { 101 | cout << "Could not create file '" << path.str() << "': " << strerror(errno) << endl; 102 | return; 103 | } 104 | for (vector::const_iterator search = authenticatedClients.begin(); search != authenticatedClients.end(); ++search) 105 | { 106 | string uuid = *search; 107 | out << uuid << endl; 108 | } 109 | 110 | out.close(); 111 | } 112 | } 113 | 114 | void ClientSet::read_cache(const std::string & _cache_dir) 115 | { 116 | string line; 117 | stringstream path; 118 | vector array; 119 | string cache_file = "clients.dat"; 120 | 121 | this->cache_dir = _cache_dir; 122 | path << this->cache_dir << cache_file; 123 | 124 | ifstream cache(path.str().c_str()); 125 | 126 | if (cache.good()) 127 | { 128 | while (getline(cache, line)) 129 | { 130 | if (line.length()) 131 | { 132 | array = explode(line, ":"); 133 | 134 | if(array.size() > 1){ 135 | if (array.size() < 3) continue; 136 | 137 | if(to_int(array[2]) == 1) 138 | authenticatedClients.push_back(array[1]); 139 | } else { 140 | authenticatedClients.push_back(line); 141 | } 142 | } 143 | } 144 | } 145 | else 146 | { 147 | // Ignore no such file errors, we will create the file upon save 148 | if (errno != ENOENT) 149 | cout << "Could not read cache file '" << path.str() << "': " << strerror(errno) << endl; 150 | } 151 | 152 | cache.close(); 153 | } 154 | -------------------------------------------------------------------------------- /src/Clientset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _CLIENTSET_H 33 | #define _CLIENTSET_H 34 | 35 | #include 36 | #include 37 | 38 | //#include "socketset.h" 39 | 40 | class ClientSet 41 | { 42 | public: 43 | // void operator += (Client & _client); 44 | void authenticate(std::string _duuid); 45 | // Client *get_client(int _socket); 46 | int is_authenticated(std::string _duuid); 47 | // void init_session(int _socket, int protocol); 48 | int length(void); 49 | void clear_cache(void); 50 | void save_cache(void); 51 | void read_cache(const std::string & cachedir); 52 | 53 | private: 54 | std::string cache_dir; 55 | std::vector authenticatedClients; 56 | // std::vector clients; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/Conf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "Conf.h" 43 | #include "Utility.h" 44 | 45 | using namespace std; 46 | 47 | unsigned int Property::get_array_size() 48 | { 49 | return array.size(); 50 | } 51 | 52 | std::string Property::get_array(unsigned int _index) 53 | { 54 | if (_index < array.size()) 55 | return array[_index]; 56 | 57 | return ""; 58 | } 59 | 60 | void Config::parse() 61 | { 62 | Property property; 63 | unsigned int num = 1; 64 | vector array; 65 | string::size_type pos; 66 | string var, val, line; 67 | 68 | ifstream config(filename.c_str()); 69 | 70 | if (config.good()) 71 | { 72 | while (getline(config, line)) 73 | { 74 | // Remove whitespace and comments 75 | remove_junk(line); 76 | 77 | // Okey we got something to analyze... 78 | if (line.length()) 79 | { 80 | pos = line.find_first_of(" \t"); 81 | var = line.substr(0, pos); 82 | val = trim(line.substr(pos)); 83 | 84 | property.var = var; 85 | property.val = val; 86 | 87 | // Parse arrays 88 | if (val[0] == ARRAY_CHAR_BEG && val[val.length() - 1] == ARRAY_CHAR_END) 89 | { 90 | val = trim(val.substr(1, val.length() - 2)); 91 | array = explode(val, " \t"); 92 | 93 | property.val = ""; 94 | property.array = array; 95 | } 96 | 97 | properties.push_back(property); 98 | } 99 | 100 | // Count lines for syntax error 101 | num++; 102 | } 103 | 104 | config.close(); 105 | } 106 | else 107 | { 108 | cout << "Could not read configuration from " << filename << ": " << strerror(errno) << endl; 109 | config.close(); 110 | exit(1); 111 | } 112 | } 113 | 114 | void Config::validate() 115 | { 116 | if (properties.size()) 117 | { 118 | /* 119 | if (this->get("server_addr") != "") cout << "Validating server_addr: " << this->get("server_addr") << endl; 120 | if (this->get("server_port") != "") cout << "Validating server_port: " << this->get("server_port") << endl; 121 | if (this->get("server_code") != "") cout << "Validating server_code: " << this->get("server_code") << endl; 122 | if (this->get("server_pid") != "") cout << "Validating server_pid: " << this->get("server_pid") << endl; 123 | if (this->get("server_socket") != "") cout << "Validating server_socket: " << this->get("server_socket") << endl; 124 | */ 125 | } 126 | } 127 | 128 | void Config::remove_junk(string & _line) 129 | { 130 | string::size_type pos; 131 | 132 | // Remove whitespace 133 | _line = trim(_line); 134 | 135 | // Remove comments 136 | if ((pos = _line.find_first_of(COMMENT_CHAR)) != string::npos) 137 | { 138 | _line = _line.substr(0, pos); 139 | } 140 | } 141 | 142 | bool Config::is_set(const string & _var) 143 | { 144 | for (vector::iterator i = properties.begin(); i != properties.end(); i++) 145 | { 146 | if (i->var == _var) 147 | if (i->val != "") 148 | return 1; 149 | } 150 | 151 | return 0; 152 | } 153 | 154 | string Config::get(const string & _var, const std::string & _default) 155 | { 156 | for (vector::iterator i = properties.begin(); i != properties.end(); i++) 157 | { 158 | if (i->var == _var) 159 | return i->val; 160 | } 161 | 162 | return _default; 163 | } 164 | 165 | vector Config::get_array(const string & _var) 166 | { 167 | vector temp; 168 | 169 | for (vector::iterator i = properties.begin(); i != properties.end(); i++) 170 | { 171 | if (i->var == _var) 172 | temp.push_back(i->val); 173 | } 174 | 175 | return temp; 176 | } 177 | 178 | Property Config::get_property(const string & _var) 179 | { 180 | Property null; 181 | 182 | null.val = ""; 183 | null.var = ""; 184 | 185 | for (vector::iterator i = properties.begin(); i != properties.end(); i++) 186 | { 187 | if (i->var == _var) 188 | return (*i); 189 | } 190 | 191 | return null; 192 | } 193 | -------------------------------------------------------------------------------- /src/Conf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _CONF_H 33 | #define _CONF_H 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #define COMMENT_CHAR '#' 40 | #define ARRAY_CHAR_BEG '(' 41 | #define ARRAY_CHAR_END ')' 42 | 43 | class Property 44 | { 45 | public: 46 | std::string var; 47 | std::string val; 48 | std::vector array; 49 | 50 | unsigned int get_array_size(); 51 | std::string get_array(unsigned int _index); 52 | }; 53 | 54 | class Config 55 | { 56 | public: 57 | Config(const std::string & _filename) : filename(_filename) {} 58 | 59 | void parse(); 60 | void validate(); 61 | bool is_set(const std::string & _var); 62 | std::string get(const std::string & _var, const std::string & _default = ""); 63 | std::vector get_array(const std::string & _var); 64 | Property get_property(const std::string & _var); 65 | 66 | private: 67 | void remove_junk(std::string & _line); 68 | 69 | std::string filename; 70 | std::vector properties; 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/Daemon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include "main.h" 45 | #include "Daemon.h" 46 | #include "Utility.h" 47 | 48 | #ifdef HAVE_CONFIG_H 49 | # include "config.h" 50 | #endif 51 | 52 | using namespace std; 53 | 54 | #ifdef HAVE_LIBAVAHI_CLIENT 55 | static AvahiPublisher avahiPublisher; 56 | #endif 57 | 58 | void Daemon::create(bool _back, const string &_user, const string &_group) 59 | { 60 | uid_t uid; 61 | gid_t gid; 62 | ofstream out; 63 | string piddir; 64 | unsigned int pid; 65 | string::size_type pos; 66 | 67 | // Obtain new process group 68 | setsid(); 69 | 70 | // Translate user from configuration to uid 71 | if ((uid = get_uid_from_str(_user)) == (uid_t) -1) 72 | { 73 | cout << "Warning! Cannot get uid for username " << _user << ", will run as current user." << endl; 74 | uid = get_current_uid(); 75 | } 76 | 77 | // Translate group from configuration to gid 78 | if ((gid = get_gid_from_str(_group)) == (gid_t) -1) 79 | { 80 | cout << "Warning! Cannot get gid for group " << _group << ", will run as current group." << endl; 81 | gid = get_current_gid(); 82 | } 83 | 84 | #ifdef USE_MEM_KVM 85 | gid = get_gid_from_str("kmem"); 86 | #endif 87 | 88 | // Create pid directory if it does not exist 89 | pos = pidfile.find_last_of("/"); 90 | if (pos != string::npos) 91 | { 92 | piddir = pidfile.substr(0, pidfile.find_last_of("/")); 93 | 94 | if (check_dir_exist(piddir) == 0 && pidfile.length()) 95 | { 96 | create_directory(piddir, 0755); 97 | if(chown(piddir.c_str(), uid, 0)){} 98 | } 99 | } 100 | 101 | // Only change owner if we want to change the pidfile 102 | if (pidfile.length()) 103 | { 104 | out.open(pidfile.c_str()); 105 | 106 | if (!out) 107 | { 108 | cout << "Could not create pid file " << pidfile << ": " << strerror(errno) << endl; 109 | exit(1); 110 | } 111 | 112 | chmod(pidfile.c_str(), 0644); 113 | if(chown(pidfile.c_str(), uid, gid)){} 114 | } 115 | 116 | // Drop root privileges now, if we were run that way 117 | if (geteuid() == 0) 118 | { 119 | if (uid || gid) 120 | { 121 | if (setgid(gid) != 0) 122 | cout << "Could not switch to group " << _group << ": " << 123 | strerror(errno) << endl; 124 | if (setuid(uid) != 0) 125 | cout << "Could not switch to user " << _user << ": " << 126 | strerror(errno) << endl; 127 | } 128 | else 129 | { 130 | cout << "WARNING: istatd set to run as root in istat.conf! " 131 | "Not recommended." << endl; 132 | } 133 | } 134 | else { 135 | cout << "Ignoring server_{user,group} settings, wasn't run as root." << endl; 136 | } 137 | 138 | if (_back) 139 | { 140 | if ((pid = fork()) > 0) 141 | { 142 | // cout << "Entering standalone mode with pid " << pid << endl; 143 | exit(0); 144 | } 145 | 146 | close(STDIN_FILENO); 147 | close(STDOUT_FILENO); 148 | close(STDERR_FILENO); 149 | 150 | sleep(1); 151 | } 152 | 153 | if (pidfile.length()) 154 | { 155 | out << getpid() << '\n'; 156 | out.close(); 157 | } 158 | 159 | // Create UNIX socket 160 | int unix_socket; 161 | socklen_t length; 162 | struct sockaddr_un local; 163 | 164 | if ((unix_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 165 | { 166 | cout << "Could not create UNIX socket file " << sockfile << ": " << strerror(errno) << endl; 167 | exit(1); 168 | } 169 | 170 | local.sun_family = AF_UNIX; 171 | 172 | strcpy(local.sun_path, sockfile.c_str()); 173 | unlink(local.sun_path); 174 | 175 | length = offsetof(struct sockaddr_un, sun_path) + strlen(sockfile.c_str()); 176 | 177 | if (::bind(unix_socket, (struct sockaddr *) &local, length) == -1) 178 | { 179 | cout << "Could not bind UNIX socket: " << strerror(errno) << endl; 180 | exit(1); 181 | } 182 | 183 | if (listen(unix_socket, 5) == -1) 184 | { 185 | cout << "Could not listen to UNIX socket: " << strerror(errno) << endl; 186 | exit(1); 187 | } 188 | } 189 | 190 | void Daemon::publish(int port, int protocol, string name, string uuid, int platform) 191 | { 192 | #ifdef HAVE_LIBAVAHI_CLIENT 193 | 194 | if(name.length() == 0 || uuid.length() == 0) 195 | return; 196 | 197 | avahiPublisher.port = port; 198 | avahiPublisher.name = name; 199 | avahiPublisher.uuid = uuid; 200 | avahiPublisher.platform = platform; 201 | avahiPublisher.protocol = protocol; 202 | avahiPublisher.publish_service(); 203 | #endif 204 | } 205 | 206 | void Daemon::destroy() 207 | { 208 | #ifdef HAVE_LIBAVAHI_CLIENT 209 | avahiPublisher.stop(); 210 | #endif 211 | 212 | int ret; 213 | ofstream out; 214 | 215 | ret = unlink(pidfile.c_str()); 216 | 217 | if (ret == -1) 218 | { 219 | // Empty pid file if we can't remove it 220 | out.open(pidfile.c_str()); 221 | 222 | if (out.good()) 223 | { 224 | out << ""; 225 | out.close(); 226 | } 227 | } 228 | 229 | unlink(sockfile.c_str()); 230 | 231 | exit(0); 232 | } 233 | 234 | void SignalResponder::destroy() 235 | { 236 | //cout << endl << "Shutting down and saving clients." << endl; 237 | 238 | this->stats->close(); 239 | this->sockets->close(); 240 | this->listener->close(); 241 | this->unixdaemon->destroy(); 242 | } 243 | 244 | void SignalResponder::on_sigint() 245 | { 246 | this->destroy(); 247 | } 248 | 249 | void SignalResponder::on_sigterm() 250 | { 251 | this->stats->finalize(); 252 | this->destroy(); 253 | } 254 | 255 | void SignalResponder::on_sighup() 256 | { 257 | cout << "Placeholder for reloading config." << endl; 258 | } 259 | -------------------------------------------------------------------------------- /src/Daemon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _DAEMON_H 33 | #define _DAEMON_H 34 | 35 | #include 36 | #include 37 | 38 | #include "Socket.h" 39 | #include "Socketset.h" 40 | #include "Clientset.h" 41 | #include "Stats.h" 42 | #include "Avahi.h" 43 | 44 | class Daemon 45 | { 46 | public: 47 | Daemon(const std::string &_pidfile, const std::string &_sockfile) : pidfile(_pidfile), sockfile(_sockfile) {} 48 | 49 | void create(bool _back, const std::string &_user, const std::string &_group); 50 | void destroy(); 51 | void publish(int port, int protocol, std::string name, std::string uuid, int platform); 52 | private: 53 | std::string pidfile; 54 | std::string sockfile; 55 | }; 56 | 57 | class SignalResponder 58 | { 59 | public: 60 | SignalResponder(SocketSet *_sockets, Socket *_listener, Daemon *_unixdaemon, Stats *_stats) : listener(_listener), sockets(_sockets), unixdaemon(_unixdaemon), stats(_stats) {} 61 | 62 | void destroy(); 63 | void on_sigint(); 64 | void on_sigterm(); 65 | void on_sighup(); 66 | 67 | private: 68 | Socket * listener; 69 | SocketSet * sockets; 70 | Daemon * unixdaemon; 71 | Stats * stats; 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/Database.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "Database.h" 33 | #include 34 | 35 | using namespace std; 36 | 37 | #ifdef USE_SQLITE 38 | 39 | bool Database::verify() 40 | { 41 | sqlite3_stmt *statement = 0; 42 | bool valid = true; 43 | int rc = sqlite3_prepare_v2(_db, "PRAGMA integrity_check", -1, &statement, 0); 44 | if(SQLITE_OK == rc) 45 | { 46 | int success = sqlite3_step(statement); 47 | string value; 48 | switch (success) { 49 | case SQLITE_ERROR: 50 | case SQLITE_MISUSE: 51 | case SQLITE_DONE: 52 | case SQLITE_BUSY: 53 | cout << "Error verifying database" << endl; 54 | break; 55 | case SQLITE_CORRUPT: 56 | cout << "Error verifying database - Corrupt" << endl; 57 | valid = false; 58 | break; 59 | case SQLITE_ROW: 60 | value = string((char *)sqlite3_column_text(statement, 0)); 61 | 62 | if(value == "ok") 63 | { 64 | cout << "Database valid" << endl; 65 | } 66 | else 67 | { 68 | cout << "Database invalid - " << value << endl; 69 | valid = false; 70 | } 71 | break; 72 | default: 73 | break; 74 | } 75 | 76 | sqlite3_finalize(statement); 77 | } 78 | else 79 | { 80 | cout << "Unable to verify database" << endl; 81 | } 82 | return valid; 83 | } 84 | 85 | void DatabaseItem::prepare(string sql, sqlite3 *db) 86 | { 87 | _statement = 0; 88 | int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &_statement, 0); 89 | if(SQLITE_OK != rc) 90 | { 91 | _statement = NULL; 92 | return; 93 | } 94 | } 95 | 96 | void DatabaseItem::finalize() 97 | { 98 | if(_statement == NULL) 99 | return; 100 | 101 | sqlite3_finalize(_statement); 102 | _statement = NULL; 103 | } 104 | 105 | int DatabaseItem::query() 106 | { 107 | int rc = sqlite3_step(_statement); 108 | finalize(); 109 | return rc; 110 | } 111 | 112 | int DatabaseItem::next() 113 | { 114 | int rc = sqlite3_step(_statement); 115 | if (rc != SQLITE_ROW) 116 | { 117 | finalize(); 118 | return 0; 119 | } 120 | 121 | if(columnNames.empty()) 122 | { 123 | int columnCount = sqlite3_column_count(_statement); 124 | for (int i = 0; i < columnCount; ++i) 125 | { 126 | const char* pName = sqlite3_column_name(_statement, i); 127 | columnNames[pName] = i; 128 | } 129 | } 130 | 131 | return 1; 132 | } 133 | 134 | double DatabaseItem::doubleForColumn(string column) 135 | { 136 | const DatabaseColumnNames::const_iterator iIndex = columnNames.find(column); 137 | if (iIndex == columnNames.end()) 138 | { 139 | return 0; 140 | } 141 | double value = sqlite3_column_double(_statement, (*iIndex).second); 142 | if(isnan(value)) 143 | value = 0; 144 | 145 | return value; 146 | } 147 | 148 | string DatabaseItem::stringForColumn(string column) 149 | { 150 | const DatabaseColumnNames::const_iterator iIndex = columnNames.find(column); 151 | if (iIndex == columnNames.end()) 152 | { 153 | return 0; 154 | } 155 | 156 | string value = string((char *)sqlite3_column_text(_statement, (*iIndex).second)); 157 | return value; 158 | } 159 | 160 | int DatabaseItem::executeUpdate() 161 | { 162 | if(_statement == NULL) 163 | return 0; 164 | 165 | int rc = sqlite3_step(_statement); 166 | finalize(); 167 | 168 | return (rc == SQLITE_DONE || rc == SQLITE_OK); 169 | } 170 | 171 | void Database::init() 172 | { 173 | string path = string(CONFIG_PATH) + "istatserver.db"; 174 | int rc = sqlite3_open(path.c_str(), &_db); 175 | if(rc != SQLITE_OK) 176 | { 177 | cout << "Unable to open database" << endl; 178 | enabled = 0; 179 | } 180 | else 181 | { 182 | cout << "Opened database" << endl; 183 | enabled = 1; 184 | } 185 | } 186 | 187 | void Database::close() 188 | { 189 | sqlite3_close(_db); 190 | cout << "Closed database" << endl; 191 | } 192 | 193 | DatabaseItem Database::databaseItem(string sql) 194 | { 195 | DatabaseItem item; 196 | item.prepare(sql, _db); 197 | return item; 198 | } 199 | 200 | int Database::beginTransaction() 201 | { 202 | DatabaseItem query; 203 | query.prepare("begin exclusive transaction", _db); 204 | query.query(); 205 | return 0; 206 | } 207 | 208 | int Database::commit() 209 | { 210 | DatabaseItem query; 211 | query.prepare("commit transaction", _db); 212 | query.query(); 213 | return 0; 214 | } 215 | 216 | int Database::tableExists(string name) 217 | { 218 | stringstream sql; 219 | sql << "select name from sqlite_master where type='table' and lower(name) = ?"; 220 | 221 | DatabaseItem query; 222 | query.prepare(sql.str(), _db); 223 | 224 | sqlite3_bind_text(query._statement, 1, name.c_str(), -1, SQLITE_STATIC); 225 | 226 | if(query.next()) 227 | { 228 | query.finalize(); 229 | return 1; 230 | } 231 | return 0; 232 | } 233 | 234 | bool Database::columnExists(string column, string table) 235 | { 236 | stringstream sql; 237 | sql << "pragma table_info('" << table << "')"; 238 | 239 | DatabaseItem query; 240 | query.prepare(sql.str(), _db); 241 | 242 | while(query.next()) 243 | { 244 | if(query.stringForColumn("name") == column) 245 | return true; 246 | } 247 | return false; 248 | } 249 | 250 | #endif 251 | -------------------------------------------------------------------------------- /src/Database.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "config.h" 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #ifdef USE_SQLITE 41 | 42 | #include 43 | 44 | #ifndef _DATABASE_H 45 | #define _DATABASE_H 46 | class DatabaseItem 47 | { 48 | private: 49 | typedef std::map DatabaseColumnNames; 50 | 51 | public: 52 | int executeUpdate(); 53 | void prepare(std::string sql, sqlite3 *db); 54 | int next(); 55 | int query(); 56 | void finalize(); 57 | double doubleForColumn(std::string column); 58 | std::string stringForColumn(std::string column); 59 | sqlite3_stmt* _statement; 60 | DatabaseColumnNames columnNames; 61 | int result; 62 | }; 63 | class Database 64 | { 65 | public: 66 | sqlite3 *_db; 67 | int enabled; 68 | void init(); 69 | bool verify(); 70 | void close(); 71 | int beginTransaction(); 72 | int commit(); 73 | DatabaseItem databaseItem(std::string sql); 74 | int tableExists(std::string name); 75 | bool columnExists(std::string column, std::string table); 76 | }; 77 | 78 | #endif 79 | #endif 80 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = 2 | 3 | bin_PROGRAMS = istatserver 4 | 5 | istatserver_SOURCES = \ 6 | ./main.h ./main.cpp \ 7 | ./Conf.h ./Conf.cpp \ 8 | ./Avahi.h ./Avahi.cpp \ 9 | ./Argument.h ./Argument.cpp \ 10 | ./Socket.h ./Socket.cpp \ 11 | ./Clientset.h ./Clientset.cpp \ 12 | ./Responses.h ./Responses.cpp \ 13 | ./Daemon.h ./Daemon.cpp \ 14 | ./Stats.h ./Stats.cpp \ 15 | ./Socketset.h ./Socketset.cpp \ 16 | ./Utility.h ./Utility.cpp \ 17 | ./Certificate.h ./Certificate.cpp \ 18 | ./Database.h ./Database.cpp \ 19 | ./stats/StatBase.h ./stats/StatBase.cpp\ 20 | ./stats/StatsCPU.h ./stats/StatsCPU.cpp\ 21 | ./stats/StatsMemory.h ./stats/StatsMemory.cpp\ 22 | ./stats/StatsSensors.h ./stats/StatsSensors.cpp\ 23 | ./stats/StatsLoad.h ./stats/StatsLoad.cpp\ 24 | ./stats/StatsNetwork.h ./stats/StatsNetwork.cpp\ 25 | ./stats/StatsDisks.h ./stats/StatsDisks.cpp\ 26 | ./stats/StatsUptime.h ./stats/StatsUptime.cpp\ 27 | ./stats/StatsActivity.h ./stats/StatsActivity.cpp\ 28 | ./stats/StatsBattery.h ./stats/StatsBattery.cpp\ 29 | ./stats/StatsProcesses.h ./stats/StatsProcesses.cpp\ 30 | System.h 31 | -------------------------------------------------------------------------------- /src/Responses.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _RESPONSES_H 33 | #define _RESPONSES_H 34 | 35 | #include "config.h" 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "Stats.h" 43 | #include "System.h" 44 | 45 | std::string isr_create_header(); 46 | std::string isr_accept_code(); 47 | std::string isr_reject_code(); 48 | std::string isr_accept_connection(); 49 | std::string isr_serverinfo(int session, int auth, std::string uuid, bool historyEnabled); 50 | 51 | bool shouldAddKey(int index, std::string key, std::vector keys, std::vector *added); 52 | std::string keyForIndex(std::string uuid, int index); 53 | 54 | std::string isr_multiple_data(xmlNodePtr node, Stats *stats); 55 | std::string isr_cpu_data(xmlNodePtr node, Stats *stats); 56 | std::string isr_network_data(int index, long sampleID, StatsNetwork stats, std::vector keys, std::vector *added); 57 | std::string isr_disk_data(int index, long sampleID, StatsDisks stats, std::vector keys, std::vector *added); 58 | std::string isr_uptime_data(long uptime); 59 | std::string isr_loadavg_data(xmlNodePtr node, Stats *stats); 60 | std::string isr_memory_data(xmlNodePtr node, Stats *stats); 61 | std::string isr_fan_data(std::vector *_data, long _init); 62 | std::string isr_temp_data(std::vector *_data, long _init); 63 | std::string isr_sensor_data(int index, long sampleID, StatsSensors stats, std::vector keys, std::vector *added); 64 | std::string isr_activity_data(int index, long sampleID, StatsActivity stats, std::vector keys, std::vector *added); 65 | std::string isr_battery_data(int index, long sampleID, StatsBattery stats, std::vector keys, std::vector *added); 66 | std::string isr_process_data(int index, long sampleID, StatsProcesses stats, std::vector keys, std::vector *added); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/Socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SOCKET_H 33 | #define _SOCKET_H 34 | 35 | #include "config.h" 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "Clientset.h" 43 | #include "Conf.h" 44 | #include "Stats.h" 45 | #include "Responses.h" 46 | 47 | #include "Certificate.h" 48 | 49 | class Socket 50 | { 51 | public: 52 | Socket(const std::string & _address, unsigned int _port) : listener(true), port(_port), address(_address) {} 53 | Socket(int _socket, std::string _address, unsigned int _port) : secure(false), socket(_socket), listener(false), port(_port), address(_address) {} 54 | 55 | int get_id() { return socket; } 56 | bool get_listener() { return listener; } 57 | unsigned int get_port() { return port; } 58 | std::string get_address() { return address; } 59 | std::string get_description(); 60 | int send(std::string data); 61 | int receive(ClientSet * _clients, Config * _config, Stats * _stats); 62 | Socket accept(); 63 | int listen(); 64 | 65 | void initClient(int s); 66 | void startReading(); 67 | void close(); 68 | 69 | int startSSL(); 70 | SSL *ssl; 71 | SSL_CTX *sslContext; 72 | 73 | std::string _serverUUID; 74 | std::string _uuid; 75 | std::string _name; 76 | long _session; 77 | int _protocol; 78 | int _sslEnabled; 79 | bool isServer; 80 | double lastRequest; 81 | std::string readbuf; 82 | bool secure; 83 | bool debugLogging; 84 | 85 | private: 86 | int socket; 87 | bool listener; 88 | unsigned int port; 89 | std::string address; 90 | void parse(std::string _data, ClientSet * _clients, Config * _config, Stats * _stats); 91 | }; 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/Socketset.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include "Socketset.h" 42 | 43 | using namespace std; 44 | 45 | SocketSet::SocketSet() 46 | { 47 | highest = 0; 48 | 49 | FD_ZERO(&socketset); 50 | } 51 | 52 | void SocketSet::operator += (Socket & _socket) 53 | { 54 | if (_socket.get_id() > highest) 55 | highest = _socket.get_id(); 56 | 57 | connections.push_back(_socket); 58 | FD_SET(_socket.get_id(), &socketset); 59 | } 60 | 61 | void SocketSet::operator -= (Socket & _socket) 62 | { 63 | cout << _socket.get_description() << " Disconnected." << endl; 64 | 65 | FD_CLR(_socket.get_id(), &socketset); 66 | 67 | if(fcntl(_socket.get_id(), F_GETFD) != -1) 68 | ::close(_socket.get_id()); 69 | 70 | for (std::vector::iterator eraser = connections.begin(); eraser != connections.end(); ++eraser) 71 | { 72 | if ((*eraser).get_id() == _socket.get_id()) 73 | { 74 | connections.erase(eraser); 75 | 76 | break; 77 | } 78 | } 79 | 80 | if (_socket.get_id() == highest) 81 | { 82 | highest = 0; 83 | 84 | for (std::vector::iterator higher = connections.begin(); higher != connections.end(); ++higher) 85 | { 86 | if (highest < (*higher).get_id()) 87 | { 88 | highest = (*higher).get_id(); 89 | } 90 | } 91 | } 92 | } 93 | 94 | bool SocketSet::operator == (Socket & _socket) 95 | { 96 | return FD_ISSET(_socket.get_id(), &readyset); 97 | } 98 | 99 | Socket & SocketSet::get_ready() 100 | { 101 | for (vector::iterator ready = connections.begin(); ready != connections.end(); ++ready) 102 | { 103 | if (FD_ISSET((*ready).get_id(), &readyset)) 104 | { 105 | return *ready; 106 | } 107 | } 108 | 109 | return connections.front(); 110 | } 111 | 112 | Socket & SocketSet::get_socket(int _socket) 113 | { 114 | for (vector::iterator ready = connections.begin(); ready != connections.end(); ++ready) 115 | { 116 | if ((*ready).get_id() == _socket) 117 | { 118 | return *ready; 119 | } 120 | } 121 | 122 | return connections.front(); 123 | } 124 | 125 | int SocketSet::get_status(int _timeout) 126 | { 127 | int result; 128 | timeval timeout; 129 | 130 | timeout.tv_sec = _timeout; 131 | timeout.tv_usec = 0; 132 | 133 | readyset = socketset; 134 | 135 | if (_timeout > 0) 136 | result = select(highest + 1, &readyset, NULL, NULL, &timeout); 137 | else 138 | result = select(highest + 1, &readyset, NULL, NULL, NULL); 139 | 140 | return result; 141 | } 142 | 143 | void SocketSet::send(const string & _data) 144 | { 145 | for (vector::iterator socket = connections.begin(); socket != connections.end(); ++socket) 146 | { 147 | if (!(*socket).get_listener()) (*socket).send(_data); 148 | } 149 | } 150 | 151 | void SocketSet::close() 152 | { 153 | for (vector::iterator socket = connections.begin(); socket != connections.end(); ++socket) 154 | { 155 | ::close((*socket).get_id()); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/Socketset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SOCKETSET_H 33 | #define _SOCKETSET_H 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "Socket.h" 41 | 42 | class SocketSet 43 | { 44 | public: 45 | SocketSet(); 46 | 47 | void operator += (Socket & _socket); 48 | void operator -= (Socket & _socket); 49 | bool operator == (Socket & _socket); 50 | 51 | Socket & get_ready(); 52 | Socket & get_socket(int _socket); 53 | int get_status(int _timeout = 0); 54 | void send(const std::string & _data); 55 | void close(); 56 | std::vector connections; 57 | 58 | private: 59 | int highest; 60 | fd_set readyset; 61 | fd_set socketset; 62 | }; 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/Stats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "Utility.h" 39 | 40 | #include "Stats.h" 41 | #include "System.h" 42 | #include 43 | #include 44 | 45 | #ifdef HAVE_CONFIG_H 46 | # include "config.h" 47 | #endif 48 | 49 | using namespace std; 50 | 51 | void* start_stats_thread(void*); 52 | void* start_stats_thread(void*a) 53 | { 54 | Stats *s = static_cast(a); 55 | s->startStats(); 56 | return 0; 57 | } 58 | 59 | void Stats::finalize() 60 | { 61 | #ifdef USE_SQLITE 62 | if(historyEnabled == true) 63 | { 64 | _database.beginTransaction(); 65 | insertDatabaseItems(&cpuStats); 66 | insertDatabaseItems(&loadStats); 67 | insertDatabaseItems(&memoryStats); 68 | insertDatabaseItems(&activityStats); 69 | insertDatabaseItems(&sensorStats); 70 | insertDatabaseItems(&networkStats); 71 | insertDatabaseItems(&diskStats); 72 | _database.commit(); 73 | } 74 | #endif 75 | } 76 | 77 | void Stats::close() 78 | { 79 | #ifdef USE_SQLITE 80 | if(historyEnabled == true) 81 | { 82 | sqlite3_interrupt(_database._db); 83 | } 84 | #endif 85 | } 86 | 87 | void Stats::prepare() 88 | { 89 | #ifdef HAVE_LIBKSTAT 90 | if(NULL == (ksh = kstat_open())) 91 | { 92 | cout << "unable to open kstat " << strerror(errno) << endl; 93 | return; 94 | } else { 95 | cpuStats.ksh = ksh; 96 | memoryStats.ksh = ksh; 97 | loadStats.ksh = ksh; 98 | networkStats.ksh = ksh; 99 | uptimeStats.ksh = ksh; 100 | activityStats.ksh = ksh; 101 | } 102 | #endif 103 | 104 | #ifdef HAVE_LIBKVM 105 | kvm_t *kd; 106 | #if defined(__NetBSD__) || defined(__OpenBSD__) 107 | if ((kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open")) != NULL) 108 | #else 109 | if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) != NULL) 110 | #endif 111 | { 112 | cpuStats.kd = kd; 113 | loadStats.kd = kd; 114 | memoryStats.kd = kd; 115 | activityStats.kd = kd; 116 | sensorStats.kd = kd; 117 | networkStats.kd = kd; 118 | diskStats.kd = kd; 119 | batteryStats.kd = kd; 120 | processStats.kd = kd; 121 | } 122 | #endif 123 | } 124 | 125 | void Stats::startStats() 126 | { 127 | #ifdef USE_SQLITE 128 | if(historyEnabled == true) 129 | { 130 | _database.init(); 131 | _database.verify(); 132 | cpuStats._database = _database; 133 | loadStats._database = _database; 134 | memoryStats._database = _database; 135 | activityStats._database = _database; 136 | sensorStats._database = _database; 137 | networkStats._database = _database; 138 | diskStats._database = _database; 139 | batteryStats._database = _database; 140 | } 141 | cpuStats.historyEnabled = historyEnabled; 142 | loadStats.historyEnabled = historyEnabled; 143 | memoryStats.historyEnabled = historyEnabled; 144 | activityStats.historyEnabled = historyEnabled; 145 | sensorStats.historyEnabled = historyEnabled; 146 | networkStats.historyEnabled = historyEnabled; 147 | diskStats.historyEnabled = historyEnabled; 148 | batteryStats.historyEnabled = historyEnabled; 149 | #endif 150 | 151 | cpuStats.debugLogging = debugLogging; 152 | loadStats.debugLogging = debugLogging; 153 | memoryStats.debugLogging = debugLogging; 154 | activityStats.debugLogging = debugLogging; 155 | sensorStats.debugLogging = debugLogging; 156 | networkStats.debugLogging = debugLogging; 157 | diskStats.debugLogging = debugLogging; 158 | batteryStats.debugLogging = debugLogging; 159 | 160 | if(debugLogging) 161 | cout << "Initiating cpu" << endl; 162 | cpuStats.init(); 163 | 164 | if(debugLogging) 165 | cout << "Initiating load" << endl; 166 | loadStats.init(); 167 | 168 | if(debugLogging) 169 | cout << "Initiating memory" << endl; 170 | memoryStats.init(); 171 | 172 | if(debugLogging) 173 | cout << "Initiating activity" << endl; 174 | activityStats.init(); 175 | 176 | if(debugLogging) 177 | cout << "Initiating sensors" << endl; 178 | sensorStats.init(); 179 | 180 | if(debugLogging) 181 | cout << "Initiating network" << endl; 182 | networkStats.init(); 183 | 184 | if(debugLogging) 185 | cout << "Initiating disks" << endl; 186 | diskStats.init(); 187 | 188 | if(debugLogging) 189 | cout << "Initiating battery" << endl; 190 | batteryStats.init(); 191 | 192 | if(debugLogging) 193 | cout << "Initiating processes" << endl; 194 | processStats.init(); 195 | 196 | if(debugLogging) 197 | cout << "Init complete" << endl; 198 | 199 | processStats.aixEntitlement = cpuStats.aixEntitlement; 200 | 201 | if(debugLogging) 202 | cout << "Updating cpu" << endl; 203 | cpuStats.update(sampleID); 204 | 205 | if(debugLogging) 206 | cout << "Updating memory" << endl; 207 | memoryStats.update(sampleID); 208 | 209 | if(debugLogging) 210 | cout << "Updating load" << endl; 211 | loadStats.update(sampleID); 212 | 213 | if(debugLogging) 214 | cout << "Updating sensors" << endl; 215 | sensorStats.update(sampleID); 216 | 217 | if(debugLogging) 218 | cout << "Updating network" << endl; 219 | networkStats.update(sampleID); 220 | 221 | if(debugLogging) 222 | cout << "Updating disks" << endl; 223 | diskStats.update(sampleID); 224 | 225 | if(debugLogging) 226 | cout << "Updating activity" << endl; 227 | activityStats.update(sampleID); 228 | 229 | if(debugLogging) 230 | cout << "Updating battery" << endl; 231 | batteryStats.update(sampleID); 232 | 233 | if(debugLogging) 234 | cout << "Updating processes" << endl; 235 | processStats.update(sampleID, 0); 236 | 237 | activityStats.ready = 1; 238 | sensorStats.ready = 1; 239 | networkStats.ready = 1; 240 | diskStats.ready = 1; 241 | batteryStats.ready = 1; 242 | 243 | if(debugLogging) 244 | cout << "Updating network addresses" << endl; 245 | networkStats.updateAddresses(); 246 | 247 | if(debugLogging) 248 | cout << "Initital loading complete" << endl; 249 | 250 | 251 | updateTime = get_current_time(); 252 | double next = ceil(updateTime) - updateTime; 253 | updateTime = ceil(updateTime); 254 | nextIPAddressTime = 0;//updateTime + 600; 255 | double nextQueueTime = updateTime + 60; 256 | 257 | updateNextTimes(updateTime); 258 | usleep(next * 1000000); 259 | 260 | while(1){ 261 | pthread_mutex_lock(&lock); 262 | update_system_stats(); 263 | if(get_current_time() >= nextIPAddressTime) 264 | { 265 | nextIPAddressTime = updateTime + 600; 266 | networkStats.updateAddresses(); 267 | } 268 | pthread_mutex_unlock(&lock); 269 | 270 | double now = get_current_time(); 271 | double next = updateTime + 1; 272 | double interval = next - now; 273 | if(interval < 0) 274 | { 275 | interval = ceil(now) < now; 276 | next = ceil(now); 277 | } 278 | else if(interval > 2) 279 | { 280 | double n = next; 281 | while(n < now) 282 | { 283 | cpuStats.tickSample(); 284 | loadStats.tickSample(); 285 | memoryStats.tickSample(); 286 | activityStats.tickSample(); 287 | sensorStats.tickSample(); 288 | networkStats.tickSample(); 289 | diskStats.tickSample(); 290 | batteryStats.tickSample(); 291 | n += 1; 292 | } 293 | interval = ceil(now) < now; 294 | next = ceil(now); 295 | } 296 | 297 | updateTime = next; 298 | 299 | if(get_current_time() >= nextQueueTime) 300 | { 301 | #ifdef USE_SQLITE 302 | if(debugLogging) 303 | cout << "Running database queue" << endl; 304 | cpuStats.removeOldSamples(); 305 | loadStats.removeOldSamples(); 306 | memoryStats.removeOldSamples(); 307 | activityStats.removeOldSamples(); 308 | sensorStats.removeOldSamples(); 309 | networkStats.removeOldSamples(); 310 | diskStats.removeOldSamples(); 311 | 312 | _database.beginTransaction(); 313 | insertDatabaseItems(&cpuStats); 314 | insertDatabaseItems(&loadStats); 315 | insertDatabaseItems(&memoryStats); 316 | insertDatabaseItems(&activityStats); 317 | insertDatabaseItems(&sensorStats); 318 | insertDatabaseItems(&networkStats); 319 | insertDatabaseItems(&diskStats); 320 | _database.commit(); 321 | if(debugLogging) 322 | cout << "Database queue complete" << endl; 323 | #endif 324 | // nextQueueTime = now + 60; 325 | nextQueueTime = now + 300; 326 | } 327 | 328 | updateNextTimes(updateTime); 329 | 330 | usleep(interval * 1000000); 331 | } 332 | } 333 | 334 | void Stats::start() 335 | { 336 | updateTime = 0; 337 | pthread_mutex_init(&lock, NULL); 338 | pthread_create(&_thread, NULL, start_stats_thread, (void*)this); 339 | } 340 | 341 | void Stats::update_system_stats() 342 | { 343 | #ifdef HAVE_LIBKSTAT 344 | kstat_chain_update(ksh); 345 | #endif 346 | 347 | sampleID++; 348 | 349 | cpuStats.prepareUpdate(); 350 | loadStats.prepareUpdate(); 351 | memoryStats.prepareUpdate(); 352 | activityStats.prepareUpdate(); 353 | sensorStats.prepareUpdate(); 354 | networkStats.prepareUpdate(); 355 | 356 | // not updated 357 | processStats.prepareUpdate(); 358 | 359 | if(debugLogging) 360 | cout << "Updating cpu" << endl; 361 | cpuStats.update(sampleID); 362 | 363 | if(debugLogging) 364 | cout << "Updating load" << endl; 365 | loadStats.update(sampleID); 366 | 367 | if(debugLogging) 368 | cout << "Updating memory" << endl; 369 | memoryStats.update(sampleID); 370 | 371 | if(debugLogging) 372 | cout << "Updating network" << endl; 373 | networkStats.update(sampleID); 374 | 375 | if(debugLogging) 376 | cout << "Updating activity" << endl; 377 | activityStats.update(sampleID); 378 | 379 | if(debugLogging) 380 | cout << "Updating processes" << endl; 381 | processStats.update(sampleID, cpuStats.ticks); 382 | 383 | processStats.finishUpdate(); 384 | 385 | if((sampleID % 3) == 0) 386 | { 387 | batteryStats.prepareUpdate(); 388 | diskStats.prepareUpdate(); 389 | sensorStats.prepareUpdate(); 390 | 391 | if(debugLogging) 392 | cout << "Updating battery" << endl; 393 | batteryStats.update(sampleID); 394 | 395 | if(debugLogging) 396 | cout << "Updating disks" << endl; 397 | diskStats.update(sampleID); 398 | 399 | if(debugLogging) 400 | cout << "Updating sensors" << endl; 401 | sensorStats.update(sampleID); 402 | } 403 | else 404 | { 405 | sensorStats.tick(); 406 | diskStats.tick(); 407 | batteryStats.tick(); 408 | } 409 | 410 | #ifdef USE_SQLITE 411 | if(historyEnabled == true) 412 | { 413 | if(debugLogging) 414 | cout << "Updating history" << endl; 415 | 416 | cpuStats.updateHistory(); 417 | loadStats.updateHistory(); 418 | memoryStats.updateHistory(); 419 | activityStats.updateHistory(); 420 | sensorStats.updateHistory(); 421 | networkStats.updateHistory(); 422 | diskStats.updateHistory(); 423 | } 424 | #endif 425 | if(debugLogging) 426 | cout << "Updating complete" << endl; 427 | } 428 | 429 | #ifdef USE_SQLITE 430 | void Stats::insertDatabaseItems(StatsBase *collector) 431 | { 432 | for (vector::iterator cur = collector->databaseQueue.begin(); cur != collector->databaseQueue.end(); ++cur) 433 | { 434 | (*cur).executeUpdate(); 435 | } 436 | collector->databaseQueue.clear(); 437 | } 438 | #endif 439 | 440 | void Stats::updateNextTimes(double t) 441 | { 442 | cpuStats.sampleIndex[0].nextTime = t; 443 | loadStats.sampleIndex[0].nextTime = t; 444 | memoryStats.sampleIndex[0].nextTime = t; 445 | activityStats.sampleIndex[0].nextTime = t; 446 | sensorStats.sampleIndex[0].nextTime = t; 447 | networkStats.sampleIndex[0].nextTime = t; 448 | diskStats.sampleIndex[0].nextTime = t; 449 | batteryStats.sampleIndex[0].nextTime = t; 450 | /* 451 | processStats.sampleIndex[0].nextTime = t; 452 | */ 453 | } 454 | 455 | long Stats::uptime() 456 | { 457 | return uptimeStats.getUptime(); 458 | } 459 | -------------------------------------------------------------------------------- /src/Stats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _STATS_H 33 | #define _STATS_H 34 | 35 | #include "config.h" 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | #include "System.h" 43 | #include "stats/StatsCPU.h" 44 | #include "stats/StatsSensors.h" 45 | #include "stats/StatsMemory.h" 46 | #include "stats/StatsLoad.h" 47 | #include "stats/StatsNetwork.h" 48 | #include "stats/StatsDisks.h" 49 | #include "stats/StatsUptime.h" 50 | #include "stats/StatsActivity.h" 51 | #include "stats/StatsBattery.h" 52 | #include "stats/StatsProcesses.h" 53 | 54 | #ifdef HAVE_KSTAT_H 55 | # include 56 | #endif 57 | 58 | #ifdef USE_SQLITE 59 | #include "Database.h" 60 | #endif 61 | 62 | class Stats 63 | { 64 | public: 65 | void prepare(); 66 | void start(); 67 | void startStats(); 68 | void update_system_stats(); 69 | void updateNextTimes(double t); 70 | void close(); 71 | void finalize(); 72 | 73 | std::vector get_battery_history(long _pos); 74 | long uptime(); 75 | long long sampleID; 76 | pthread_mutex_t lock; 77 | 78 | bool historyEnabled; 79 | bool debugLogging; 80 | 81 | #ifdef USE_SQLITE 82 | Database _database; 83 | void insertDatabaseItems(StatsBase *collector); 84 | #endif 85 | 86 | StatsCPU cpuStats; 87 | StatsSensors sensorStats; 88 | StatsMemory memoryStats; 89 | StatsLoad loadStats; 90 | StatsNetwork networkStats; 91 | StatsDisks diskStats; 92 | StatsUptime uptimeStats; 93 | StatsActivity activityStats; 94 | StatsBattery batteryStats; 95 | StatsProcesses processStats; 96 | 97 | private: 98 | #ifdef HAVE_LIBKSTAT 99 | kstat_ctl_t *ksh; 100 | #endif 101 | pthread_t _thread; 102 | double updateTime; 103 | double nextIPAddressTime; 104 | }; 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/System.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _SYSTEM_H 33 | #define _SYSTEM_H 34 | 35 | #include 36 | #include 37 | 38 | #define SERVER_VERSION 3.03 39 | #define SERVER_BUILD 105 40 | #define PROTOCOL_VERSION 3 41 | #define HISTORY_SIZE 600 42 | 43 | struct load_data 44 | { 45 | float one, two, three; 46 | long long sampleID; 47 | double time; 48 | bool empty; 49 | }; 50 | 51 | struct cpu_data 52 | { 53 | double u, n, s, i, io, ent, phys; 54 | long long sampleID; 55 | double time; 56 | bool empty; 57 | }; 58 | 59 | #define memory_value_total 0 60 | #define memory_value_free 1 61 | #define memory_value_used 2 62 | #define memory_value_active 3 63 | #define memory_value_inactive 4 64 | #define memory_value_cached 5 65 | #define memory_value_swapused 6 66 | #define memory_value_swaptotal 7 67 | #define memory_value_swapout 8 68 | #define memory_value_swapin 9 69 | #define memory_value_buffer 10 70 | #define memory_value_wired 11 71 | #define memory_value_ex 12 72 | #define memory_value_file 13 73 | #define memory_value_virtualtotal 14 74 | #define memory_value_virtualactive 15 75 | 76 | #define memory_values_count 16 77 | 78 | struct sample_data 79 | { 80 | long long sampleID; 81 | double time; 82 | }; 83 | 84 | struct mem_data 85 | { 86 | double values[memory_values_count]; 87 | long long sampleID; 88 | double time; 89 | bool empty; 90 | }; 91 | 92 | struct activity_data 93 | { 94 | long long sampleID; 95 | double r, w; 96 | double rIOPS, wIOPS; 97 | double time; 98 | bool empty; 99 | }; 100 | 101 | struct net_data 102 | { 103 | long long sampleID; 104 | double u, d; 105 | double time; 106 | bool empty; 107 | }; 108 | 109 | struct disk_data 110 | { 111 | long long sampleID; 112 | float p; 113 | double t, u, f; 114 | double time; 115 | bool empty; 116 | }; 117 | 118 | struct sensor_data 119 | { 120 | long long sampleID; 121 | double value; 122 | double time; 123 | bool empty; 124 | }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/Utility.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "Utility.h" 46 | 47 | using namespace std; 48 | 49 | #ifdef HAVE_KSTAT_H 50 | 51 | unsigned long long ksgetull(kstat_named_t *kn) 52 | { 53 | switch(kn->data_type) 54 | { 55 | # ifdef KSTAT_DATA_INT32 56 | case KSTAT_DATA_INT32: return kn->value.i32; 57 | case KSTAT_DATA_UINT32: return kn->value.ui32; 58 | case KSTAT_DATA_INT64: return kn->value.i64; 59 | case KSTAT_DATA_UINT64: return kn->value.ui64; 60 | # else 61 | case KSTAT_DATA_LONG: return kn->value.l; 62 | case KSTAT_DATA_ULONG: return kn->value.ul; 63 | case KSTAT_DATA_LONGLONG: return kn->value.ll; 64 | case KSTAT_DATA_ULONGLONG: return kn->value.ull; 65 | # endif 66 | default: 67 | return (unsigned long long) -1; 68 | } 69 | } 70 | #endif 71 | 72 | int serverPlatform() 73 | { 74 | int platform = 2; 75 | 76 | #if defined(__sun) && defined(__SVR4) 77 | platform = 3; 78 | #endif 79 | 80 | #if defined(__FreeBSD__) || defined(__FreeBSD) 81 | platform = 4; 82 | #endif 83 | 84 | #if defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) 85 | platform = 6; 86 | #endif 87 | 88 | #if defined(__NetBSD__) || defined(__NetBSD) 89 | platform = 8; 90 | #endif 91 | 92 | #if defined(__OpenBSD__) || defined(__OPENBSD) 93 | platform = 9; 94 | #endif 95 | 96 | #if defined(__DragonFly__) 97 | platform = 10; 98 | #endif 99 | 100 | return platform; 101 | } 102 | 103 | double get_current_time() 104 | { 105 | struct timeval tp; 106 | gettimeofday(&tp, NULL); 107 | return (double)tp.tv_sec + ((double)tp.tv_usec / 1000000.f); 108 | } 109 | 110 | string get_current_time_string() 111 | { 112 | struct timeval tp; 113 | gettimeofday(&tp, NULL); 114 | 115 | double t = (double)tp.tv_sec + ((double)tp.tv_usec / 1000000.f); 116 | char buffer[32]; 117 | snprintf(buffer, sizeof(buffer), "%.4f", t); 118 | 119 | return string(buffer); 120 | } 121 | 122 | uid_t get_current_uid() 123 | { 124 | return geteuid(); 125 | } 126 | 127 | gid_t get_current_gid() 128 | { 129 | return getegid(); 130 | } 131 | 132 | uid_t get_uid_from_str(const string &_user) 133 | { 134 | struct passwd * ent; 135 | 136 | if(!(ent = getpwnam(_user.c_str()))) 137 | { 138 | return -1; 139 | } 140 | 141 | return(ent->pw_uid); 142 | } 143 | 144 | uid_t get_gid_from_str(const string &_group) 145 | { 146 | struct group * ent; 147 | 148 | if(!(ent = getgrnam(_group.c_str()))) 149 | { 150 | return -1; 151 | } 152 | 153 | return(ent->gr_gid); 154 | } 155 | 156 | int get_file_owner(const string &_file) 157 | { 158 | struct stat stats; 159 | 160 | stat(_file.c_str(), &stats); 161 | 162 | return stats.st_uid; 163 | } 164 | 165 | int pid_dead(int _pid) 166 | { 167 | // Return 1 if process is dead 168 | if (waitpid(_pid, NULL, WNOHANG) != 0) 169 | return 1; 170 | 171 | return 0; 172 | } 173 | 174 | int check_dir_exist(const string &_dir) 175 | { 176 | struct stat stats; 177 | 178 | // Return 1 if dir exists 179 | if (stat(_dir.c_str(), &stats) == 0 && S_ISDIR(stats.st_mode) == 1) 180 | return 1; 181 | 182 | return 0; 183 | } 184 | 185 | int check_file_exist(const string &_file) 186 | { 187 | struct stat stats; 188 | 189 | // Return 1 if file exists 190 | if (stat(_file.c_str(), &stats) == 0 && S_ISREG(stats.st_mode) == 1) 191 | return 1; 192 | 193 | return 0; 194 | } 195 | 196 | string trim(const string & source, const char *_delim) 197 | { 198 | string result(source); 199 | string::size_type index = result.find_last_not_of(_delim); 200 | 201 | if (index != string::npos) 202 | result.erase(++index); 203 | 204 | index = result.find_first_not_of(_delim); 205 | 206 | if (index != string::npos) 207 | result.erase(0, index); 208 | else 209 | result.erase(); 210 | 211 | return result; 212 | } 213 | 214 | vector split(const string &_str, const string _delim) 215 | { 216 | vector v; 217 | string str_elem(""); 218 | std::string::size_type ui_cur_pos, ui_last_pos = 0; 219 | 220 | // Check for empty string 221 | if (_str.empty()) return v; 222 | 223 | ui_cur_pos = _str.find_first_of(_delim.c_str(), ui_last_pos); 224 | 225 | while(ui_cur_pos != _str.npos) 226 | { 227 | str_elem = _str.substr(ui_last_pos, ui_cur_pos-ui_last_pos); 228 | v.push_back(str_elem); 229 | 230 | ui_last_pos = ui_cur_pos + 1; 231 | ui_cur_pos = _str.find_first_of(_delim.c_str(), ui_last_pos); 232 | } 233 | 234 | // Handle last substring - if any 235 | if(_str.length() != ui_last_pos) 236 | { 237 | str_elem = _str.substr(ui_last_pos, _str.length()-ui_last_pos); 238 | v.push_back(str_elem); 239 | } 240 | 241 | return v; 242 | } 243 | 244 | vector explode(string _source, const string &_delim) 245 | { 246 | vector ret; 247 | string splitted_part; 248 | unsigned int i, no_match = 0; 249 | string::size_type pos, split_pos; 250 | 251 | // Loop array string until we can't find more delimiters 252 | while (no_match < _delim.length()) 253 | { 254 | no_match = 0; 255 | split_pos = string::npos; 256 | 257 | // Find first occuring splitter 258 | for (i = 0; i < _delim.length(); i++) 259 | { 260 | pos = _source.find(_delim[i], 0); 261 | 262 | if (pos == string::npos) no_match++; 263 | if (pos < split_pos) split_pos = pos; 264 | } 265 | 266 | // Be nice to things wrapped with quotes 267 | if (_source[0] == '"' && _source.substr(1).find_first_of("\"") != string::npos) 268 | { 269 | split_pos = _source.substr(1).find_first_of("\"") + 2; 270 | } 271 | 272 | // One value from the array 273 | splitted_part = _source.substr(0, split_pos); 274 | 275 | // Save the value if it's not empty 276 | if (splitted_part != "") 277 | { 278 | ret.push_back(splitted_part); 279 | } 280 | 281 | // Remove value from string 282 | _source.erase(0, split_pos + 1); 283 | } 284 | 285 | return ret; 286 | } 287 | 288 | int create_directory(const string &_dir, mode_t _mask) 289 | { 290 | if (mkdir(_dir.c_str(), _mask) < 0) 291 | return -1; 292 | 293 | return 0; 294 | } 295 | -------------------------------------------------------------------------------- /src/Utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _UTILITY_H 33 | #define _UTILITY_H 34 | 35 | #include "config.h" 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #ifdef HAVE_SYS_PARAM_H 42 | # include 43 | #endif 44 | 45 | #ifdef HAVE_SYS_STAT_H 46 | # include 47 | #endif 48 | 49 | #ifdef HAVE_SYS_TYPES_H 50 | # include 51 | #endif 52 | 53 | #ifdef HAVE_SYS_TIME_H 54 | # include 55 | #endif 56 | 57 | #ifdef HAVE_KSTAT_H 58 | # include 59 | #endif 60 | 61 | #ifdef HAVE_KSTAT_H 62 | unsigned long long ksgetull(kstat_named_t *kn); 63 | #endif 64 | 65 | uid_t get_current_uid(); 66 | gid_t get_current_gid(); 67 | uid_t get_uid_from_str(const std::string & _user); 68 | gid_t get_gid_from_str(const std::string & _group); 69 | int get_file_owner(const std::string & _file); 70 | int pid_dead(int _pid); 71 | int check_dir_exist(const std::string & _dir); 72 | int check_file_exist(const std::string & _file); 73 | int create_directory(const std::string &_dir, mode_t _mask); 74 | double get_current_time(); 75 | int serverPlatform(); 76 | std::string get_current_time_string(); 77 | 78 | std::string trim(const std::string & _source, const char * _delims = " \t\r\n"); 79 | std::vector split(const std::string &_str, const std::string _delim); 80 | std::vector explode(std::string _str, const std::string &_delim = " "); 81 | 82 | template double to_double(const T &_val) 83 | { 84 | double n; 85 | std::stringstream buffer; 86 | buffer << _val; 87 | buffer >> n; 88 | return n; 89 | } 90 | 91 | template int to_int(const T &_val) 92 | { 93 | int n; 94 | std::stringstream buffer; 95 | buffer << _val; 96 | buffer >> n; 97 | return n; 98 | } 99 | 100 | template std::string to_ascii(const T &_val) 101 | { 102 | std::ostringstream buffer; 103 | for (std::string::const_iterator i = _val.begin(); i != _val.end(); i++) buffer << static_cast(*i); 104 | return buffer.str(); 105 | } 106 | 107 | template std::string to_string(const T &_val) 108 | { 109 | std::ostringstream buffer; 110 | buffer << _val; 111 | return buffer.str(); 112 | } 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _MAIN_H 33 | #define _MAIN_H 34 | 35 | #include 36 | #include "Certificate.h" 37 | 38 | void handler(int _signal); 39 | void GenerateGuid(char *guidStr); 40 | SSL_CTX* InitServerCTX(void); 41 | void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile); 42 | DH *get_dh2236(); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/stats/StatBase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | using namespace std; 35 | 36 | void StatsBase::tickSample() 37 | { 38 | sampleIndex[0].sampleID = sampleIndex[0].sampleID + 1; 39 | } 40 | 41 | void StatsBase::tick() 42 | { 43 | sampleIndex[0].time = sampleIndex[0].nextTime; 44 | } 45 | 46 | void StatsBase::prepareUpdate() 47 | { 48 | sampleIndex[0].time = sampleIndex[0].nextTime; 49 | sampleIndex[0].sampleID = sampleIndex[0].sampleID + 1; 50 | } 51 | 52 | void StatsBase::initShared() 53 | { 54 | int x; 55 | int storageIndexes[9] = {0, 0, 1, 1, 2, 2, 2, 2, 0}; 56 | int intervals[9] = {1, 6, 144, 1008, 4320, 12960, 25920, 52560, 300}; 57 | for(x=0;x<8;x++){ 58 | sampleIndex[x].time = 0; 59 | sampleIndex[x].nextTime = 0; 60 | sampleIndex[x].sampleID = 1; 61 | sampleIndex[x].interval = intervals[x]; 62 | sampleIndex[x].historyIndex = storageIndexes[x]; 63 | } 64 | ready = 1; 65 | session = 0; 66 | } 67 | 68 | #ifdef USE_SQLITE 69 | string StatsBase::tableAtIndex(int index) 70 | { 71 | string tables[8] = {"", "hour", "day", "week", "month", "threemonth", "sixmonth", "year" }; 72 | return tables[index]; 73 | } 74 | 75 | double StatsBase::sampleIdForTable(string table) 76 | { 77 | string sql = "select sample from " + table + " order by sample desc limit 1"; 78 | DatabaseItem query = _database.databaseItem(sql); 79 | 80 | if(query.next()) 81 | { 82 | double value = sqlite3_column_double(query._statement, 0); 83 | query.finalize(); 84 | return value; 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | void StatsBase::fillGaps() 91 | { 92 | fillGapsAtIndex(1); 93 | fillGapsAtIndex(2); 94 | fillGapsAtIndex(3); 95 | fillGapsAtIndex(4); 96 | fillGapsAtIndex(5); 97 | fillGapsAtIndex(6); 98 | fillGapsAtIndex(7); 99 | } 100 | 101 | void StatsBase::fillGapsAtIndex(int index) 102 | { 103 | double now = get_current_time(); 104 | 105 | if (sampleIndex[index].nextTime == 0) { 106 | sampleIndex[index].nextTime = ceil(now) + sampleIndex[index].interval; 107 | sampleIndex[index].time = sampleIndex[index].nextTime - sampleIndex[index].interval; 108 | 109 | InsertInitialSample(index, sampleIndex[index].time, sampleIndex[index].sampleID); 110 | return; 111 | } 112 | 113 | if (sampleIndex[index].nextTime < now) 114 | { 115 | while (sampleIndex[index].nextTime < now) 116 | { 117 | sampleIndex[index].nextTime = sampleIndex[index].nextTime + sampleIndex[index].interval; 118 | sampleIndex[index].sampleID = sampleIndex[index].sampleID + 1; 119 | } 120 | } 121 | } 122 | 123 | int StatsBase::InsertInitialSample(int index, double t, long long sampleID) 124 | { 125 | string table = databasePrefix + tableAtIndex(index); 126 | if (databaseType == 1) 127 | table += "_id"; 128 | 129 | string sql = "insert into " + table + " (sample, time, empty) values(?, ?, 1)"; 130 | 131 | DatabaseItem dbItem = _database.databaseItem(sql); 132 | sqlite3_bind_double(dbItem._statement, 1, (double)sampleID); 133 | sqlite3_bind_double(dbItem._statement, 2, t); 134 | dbItem.executeUpdate(); 135 | 136 | return 0; 137 | } 138 | 139 | void StatsBase::removeOldSamples() 140 | { 141 | int x; 142 | for(x=1;x<8;x++) 143 | { 144 | if (databaseType == 1) 145 | { 146 | string table = databasePrefix + tableAtIndex(x) + "_id"; 147 | string sql = "delete from " + table + " WHERE sample < ?"; 148 | DatabaseItem dbItem = _database.databaseItem(sql); 149 | sqlite3_bind_double(dbItem._statement, 1, sampleIndex[x].sampleID - 600); 150 | databaseQueue.push_back(dbItem); 151 | } 152 | string table = databasePrefix + tableAtIndex(x); 153 | string sql = "delete from " + table + " WHERE sample < ?"; 154 | DatabaseItem dbItem = _database.databaseItem(sql); 155 | sqlite3_bind_double(dbItem._statement, 1, sampleIndex[x].sampleID - 600); 156 | databaseQueue.push_back(dbItem); 157 | } 158 | } 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /src/stats/StatBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _STATBASE_H 33 | #define _STATBASE_H 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "config.h" 50 | #include "System.h" 51 | #include "Utility.h" 52 | 53 | // needed for solaris 54 | #define _STRUCTURED_PROC 1 55 | 56 | #ifdef HAVE_SENSORS_SENSORS_H 57 | # include 58 | #endif 59 | 60 | #ifdef HAVE_SYS_PROCFS_H 61 | #include 62 | #endif 63 | 64 | #ifdef HAVE_DIRENT_H 65 | #include 66 | #endif 67 | 68 | #ifdef HAVE_PROCFS_H 69 | #include 70 | #endif 71 | 72 | #ifdef HAVE_PROCINFO_H 73 | #include 74 | #endif 75 | 76 | #ifdef HAVE_KVM_H 77 | # include 78 | #endif 79 | 80 | #ifdef HAVE_SYS_USER_H 81 | #include 82 | #endif 83 | 84 | #ifdef HAVE_SYS_SOCKET_H 85 | # include 86 | #endif 87 | 88 | #ifdef HAVE_NET_IF_H 89 | # include 90 | #endif 91 | 92 | #ifdef HAVE_NET_IF_MIB_H 93 | # include 94 | #endif 95 | 96 | #ifdef HAVE_NETINET_IN_H 97 | #include 98 | #endif 99 | 100 | #ifdef HAVE_GETIFADDRS 101 | #include 102 | #include 103 | 104 | #ifndef AF_LINK 105 | #define AF_LINK AF_PACKET 106 | #endif 107 | #endif 108 | 109 | #ifdef HAVE_INET_COMMON_H 110 | #include 111 | #endif 112 | 113 | #ifdef HAVE_SYS_SOCKIO_H 114 | #include 115 | #endif 116 | 117 | #ifdef HAVE_SYS_SWAP_H 118 | # include 119 | #endif 120 | 121 | #ifdef HAVE_UVM_UVM_EXTERN_H 122 | # include 123 | #endif 124 | 125 | #ifdef TIME_WITH_SYS_TIME 126 | # include 127 | # include 128 | #elif defined(HAVE_SYS_TIME_H) 129 | # include 130 | #else 131 | # include 132 | #endif 133 | 134 | #ifdef HAVE_SYS_VMMETER_H 135 | # include 136 | #endif 137 | 138 | #ifdef HAVE_SYS_MNTTAB_H 139 | # include 140 | #endif 141 | 142 | #ifdef HAVE_SYS_STATVFS_H 143 | # include 144 | #elif defined(HAVE_SYS_STATFS_H) 145 | # include 146 | #endif 147 | 148 | #ifdef HAVE_SYS_MOUNT_H 149 | # include 150 | #endif 151 | 152 | #ifdef HAVE_MNTENT_H 153 | # include 154 | #endif 155 | 156 | #ifdef HAVE_PATHS_H 157 | # include 158 | #endif 159 | 160 | #ifdef HAVE_SYS_RESOURCE_H 161 | # include 162 | #endif 163 | 164 | #ifdef HAVE_SYS_SCHED_H 165 | # include 166 | #endif 167 | 168 | #ifdef HAVE_SYS_PROCESSOR_H 169 | # include 170 | #endif 171 | 172 | #ifdef HAVE_SYS_SYSINFO_H 173 | # include 174 | #endif 175 | 176 | #ifdef HAVE_DIRENT_H 177 | #include 178 | #endif 179 | 180 | #ifdef HAVE_SYS_IOCTL_H 181 | # include 182 | #endif 183 | 184 | #ifdef HAVE_MACHINE_APMVAR_H 185 | #include 186 | #endif 187 | 188 | #ifdef HAVE_DEV_ACPICA_ACPIIO_H 189 | #include 190 | #endif 191 | 192 | #ifdef HAVE_SYS_SYSCTL_H 193 | # include 194 | #endif 195 | 196 | #if defined(HAVE_DEVSTAT) || defined(HAVE_DEVSTAT_ALT) 197 | #include 198 | #endif 199 | 200 | #ifdef HAVE_KSTAT_H 201 | # include 202 | #endif 203 | 204 | #ifdef HAVE_PATHS_H 205 | # include 206 | #endif 207 | 208 | #ifdef HAVE_ERRNO_H 209 | # include 210 | #endif 211 | 212 | #ifdef HAVE_SYS_LOADAVG_H 213 | # include 214 | #endif 215 | 216 | #ifdef HAVE_SYS_TYPES_H 217 | # include 218 | #endif 219 | 220 | #ifdef HAVE_SYS_PARAM_H 221 | # include 222 | #endif 223 | 224 | #ifdef HAVE_SYS_PROC_H 225 | # include 226 | #endif 227 | 228 | #ifdef HAVE_LIBPERFSTAT_H 229 | # include 230 | #endif 231 | 232 | #ifdef HAVE_SYS_PSTAT_H 233 | # include 234 | #endif 235 | 236 | #ifdef HAVE_SYS_DK_H 237 | # include 238 | #endif 239 | 240 | #ifdef HAVE_SYS_DLPI_H 241 | # include 242 | #endif 243 | 244 | #ifdef HAVE_SYS_DLPI_EXT_H 245 | # include 246 | #endif 247 | 248 | #ifdef HAVE_SYS_MIB_H 249 | # include 250 | #endif 251 | 252 | #ifdef HAVE_SYS_STROPTS_H 253 | # include 254 | #endif 255 | 256 | #ifdef HAVE_SYS_DISK_H 257 | # include 258 | #endif 259 | 260 | #ifdef HAVE_SYS_DKSTAT_H 261 | # include 262 | #endif 263 | 264 | #ifdef USE_SQLITE 265 | #include "Database.h" 266 | #endif 267 | 268 | class StatsBase 269 | { 270 | typedef struct sampleindexconfig { 271 | long long sampleID; 272 | double time; 273 | double nextTime; 274 | double interval; 275 | int historyIndex; 276 | } sampleindexconfig_t; 277 | 278 | public: 279 | void prepareUpdate(); 280 | void tick(); 281 | void tickSample(); 282 | struct sampleindexconfig sampleIndex[8]; 283 | void initShared(); 284 | int ready; 285 | long session; 286 | bool historyEnabled; 287 | bool debugLogging; 288 | 289 | #ifdef HAVE_LIBKVM 290 | kvm_t *kd; 291 | #endif 292 | 293 | #ifdef USE_SQLITE 294 | std::vector databaseQueue; 295 | Database _database; 296 | int databaseType; 297 | std::string databasePrefix; 298 | void fillGaps(); 299 | void fillGapsAtIndex(int index); 300 | std::string tableAtIndex(int index); 301 | int InsertInitialSample(int index, double time, long long sampleID); 302 | double sampleIdForTable(std::string table); 303 | void loadPreviousSamples(); 304 | void removeOldSamples(); 305 | #endif 306 | }; 307 | #endif 308 | -------------------------------------------------------------------------------- /src/stats/StatsActivity.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | # include "config.h" 33 | 34 | #include "StatBase.h" 35 | 36 | #ifndef _STATSACTIVITY_H 37 | #define _STATSACTIVITY_H 38 | 39 | class activity_info 40 | { 41 | public: 42 | bool active; 43 | bool is_new; 44 | unsigned int id; 45 | unsigned long long last_r; 46 | unsigned long long last_w; 47 | unsigned long long last_rIOPS; 48 | unsigned long long last_wIOPS; 49 | 50 | std::string device; 51 | std::vector mounts; 52 | std::deque samples[8]; 53 | }; 54 | 55 | class StatsActivity : public StatsBase 56 | { 57 | public: 58 | void update(long long sampleID); 59 | void init(); 60 | void prepareUpdate(); 61 | void createDisk(std::string key); 62 | void processDisk(std::string key, long long sampleID, unsigned long long read, unsigned long long write, unsigned long long reads, unsigned long long writes); 63 | 64 | void _init(); 65 | #ifdef USE_SQLITE 66 | void updateHistory(); 67 | activity_data historyItemAtIndex(int index, activity_info item); 68 | void loadPreviousSamples(); 69 | void loadPreviousSamplesAtIndex(int index); 70 | #endif 71 | 72 | std::vector _items; 73 | std::deque samples[8]; 74 | 75 | #ifdef HAVE_LIBKSTAT 76 | kstat_ctl_t *ksh; 77 | #endif 78 | }; 79 | #endif 80 | -------------------------------------------------------------------------------- /src/stats/StatsBattery.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatsBattery.h" 33 | 34 | using namespace std; 35 | 36 | #if defined(USE_BATTERY_APM) 37 | 38 | #ifndef APM_BATT_ABSENT 39 | #define APM_BATT_ABSENT APM_BATTERY_ABSENT 40 | #endif 41 | 42 | void StatsBattery::init() 43 | { 44 | _init(); 45 | 46 | int fd = open("/dev/apm", O_RDONLY); 47 | if(fd == -1) 48 | return; 49 | createBattery("apm", "", ""); 50 | } 51 | 52 | void StatsBattery::update(long long sampleID) 53 | { 54 | if(_items.size() == 0) 55 | return; 56 | 57 | int fd = open("/dev/apm", O_RDONLY); 58 | if(fd == -1) 59 | return; 60 | 61 | int state = BatteryStateUnknown; 62 | int source = BatterySourceAC; 63 | int present = 1; 64 | int percentage = -1; 65 | float t = 0; 66 | 67 | struct apm_power_info info; 68 | if (ioctl(fd, APM_IOC_GETPOWER, &info) == 0) 69 | { 70 | if(info.battery_life == 255) 71 | percentage = 100; 72 | else 73 | percentage = info.battery_life; 74 | 75 | if(info.battery_state == APM_BATT_CHARGING) 76 | { 77 | if(percentage == 100) 78 | state = BatteryStateCharged; 79 | else 80 | state = BatteryStateCharging; 81 | } 82 | else if(info.battery_state == APM_BATT_UNKNOWN || info.battery_state == APM_BATT_ABSENT) 83 | { 84 | 85 | } 86 | else 87 | { 88 | state = BatteryStateDraining; 89 | } 90 | 91 | if(info.ac_state == APM_AC_ON) 92 | { 93 | if(percentage == 100) 94 | state = BatteryStateCharged; 95 | else 96 | state = BatteryStateCharging; 97 | source = BatterySourceAC; 98 | } 99 | else 100 | source = BatterySourceBattery; 101 | 102 | if(info.minutes_left > 0 && info.minutes_left < 0xFFFF) 103 | t = info.minutes_left; 104 | 105 | int timeRemaining = t; 106 | 107 | for (vector::iterator cur = _items.begin(); cur != _items.end(); ++cur) 108 | { 109 | (*cur).state = state; 110 | (*cur).source = source; 111 | (*cur).present = present; 112 | (*cur).percentage = percentage; 113 | (*cur).timeRemaining = timeRemaining; 114 | } 115 | } 116 | close(fd); 117 | } 118 | 119 | #elif defined(USE_BATTERY_ACPI) && defined(HAVE_SYSCTLBYNAME) 120 | 121 | #ifndef UNKNOWN_CAP 122 | #define UNKNOWN_CAP 0xffffffff 123 | #endif 124 | 125 | #ifndef UNKNOWN_VOLTAGE 126 | #define UNKNOWN_VOLTAGE 0xffffffff 127 | #endif 128 | 129 | void StatsBattery::init() 130 | { 131 | _init(); 132 | 133 | int batteries; 134 | size_t len = sizeof(batteries); 135 | 136 | if (sysctlbyname("hw.acpi.battery.units", &batteries, &len, NULL, 0) >= 0) 137 | { 138 | int x; 139 | for(x=0;x::iterator cur = _items.begin(); cur != _items.end(); ++cur) 156 | { 157 | union acpi_battery_ioctl_arg battio; 158 | battio.unit = atoi((*cur).key.c_str()); 159 | if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) == -1) 160 | { 161 | (*cur).active = false; 162 | continue; 163 | } 164 | 165 | int state = BatteryStateUnknown; 166 | int source = BatterySourceAC; 167 | int present = 1; 168 | int cycles = 0; 169 | int percentage = -1; 170 | int capacityDesign = 0; 171 | int capacityFull = 0; 172 | int capacityNow = 0; 173 | int capacityRate = 0; 174 | int voltage = 0; 175 | float health = 0; 176 | float t = 0; 177 | 178 | if (battio.bif.dcap != UNKNOWN_CAP) 179 | capacityDesign = battio.bif.dcap; 180 | 181 | if (battio.bif.lfcap != UNKNOWN_CAP) 182 | capacityFull = battio.bif.lfcap; 183 | 184 | 185 | battio.unit = atoi((*cur).key.c_str()); 186 | if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1) 187 | { 188 | (*cur).active = false; 189 | continue; 190 | } 191 | 192 | (*cur).active = true; 193 | 194 | int acline = 0; 195 | ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acline); 196 | 197 | if (battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT) 198 | { 199 | if (battio.battinfo.cap != -1) 200 | percentage = battio.battinfo.cap; 201 | 202 | if(acline == 1) 203 | { 204 | source = BatterySourceAC; 205 | 206 | if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING) 207 | state = BatteryStateCharging; 208 | else 209 | { 210 | if(percentage == 100) 211 | state = BatteryStateCharged; 212 | else 213 | state = BatteryStateCharging; 214 | } 215 | } 216 | else 217 | { 218 | source = BatterySourceBattery; 219 | state = BatteryStateDraining; 220 | } 221 | 222 | if (battio.battinfo.min != -1) 223 | t = battio.battinfo.min; 224 | } 225 | 226 | battio.unit = atoi((*cur).key.c_str()); 227 | if (ioctl(acpifd, ACPIIO_BATT_GET_BST, &battio) != -1) 228 | { 229 | if (battio.bst.state != ACPI_BATT_STAT_NOT_PRESENT) { 230 | if (battio.bst.volt != UNKNOWN_VOLTAGE) 231 | voltage = battio.bst.volt; 232 | } 233 | } 234 | 235 | /* 236 | if(percentage == -1) 237 | { 238 | if(capacityFull > 0 && capacityNow > 0) 239 | percentage = (capacityNow / capacityFull) * 100; 240 | else 241 | percentage = 0; 242 | }*/ 243 | 244 | if(capacityDesign > 0 && capacityFull > 0) 245 | health = ((float)capacityFull / (float)capacityDesign) * 100; 246 | 247 | int timeRemaining = t; 248 | 249 | (*cur).state = state; 250 | (*cur).source = source; 251 | (*cur).present = present; 252 | (*cur).cycles = cycles; 253 | (*cur).percentage = percentage; 254 | (*cur).capacityDesign = capacityDesign; 255 | (*cur).capacityFull = capacityFull; 256 | (*cur).capacityNow = capacityNow; 257 | (*cur).capacityRate = capacityRate; 258 | (*cur).voltage = voltage; 259 | (*cur).timeRemaining = timeRemaining; 260 | (*cur).health = health; 261 | } 262 | 263 | close(acpifd); 264 | } 265 | 266 | #elif defined(USE_BATTERY_PROCFS) 267 | 268 | bool StatsBattery::fileExists(string path) 269 | { 270 | FILE * fp = NULL; 271 | 272 | if (!(fp = fopen(path.c_str(), "r"))) 273 | { 274 | return false; 275 | } 276 | 277 | fclose(fp); 278 | return true; 279 | } 280 | 281 | void StatsBattery::init() 282 | { 283 | _init(); 284 | 285 | DIR *dpdf; 286 | struct dirent *epdf; 287 | 288 | vector adapters; 289 | vector batteries; 290 | string directory = string("/sys/class/power_supply/"); 291 | 292 | dpdf = opendir(directory.c_str()); 293 | if (dpdf != NULL){ 294 | while ((epdf = readdir(dpdf))){ 295 | string file = string(epdf->d_name); 296 | if(file.find("A") == 0) 297 | { 298 | string path = directory; 299 | adapters.push_back(path.append(string(epdf->d_name))); 300 | } 301 | if(file.find("BAT") == 0) 302 | { 303 | string path = directory; 304 | batteries.push_back(path.append(string(epdf->d_name))); 305 | } 306 | } 307 | } 308 | 309 | if(batteries.size() > 0) 310 | { 311 | for (vector::iterator curbat = batteries.begin(); curbat != batteries.end(); ++curbat) 312 | { 313 | string uevent = (*curbat); 314 | uevent = uevent.append("/uevent"); 315 | if(!fileExists(uevent)) 316 | continue; 317 | 318 | string batterysuffix = (*curbat).substr(3, (*curbat).length() - 3); 319 | 320 | string adapterpath = string(""); 321 | if(batterysuffix.length() > 0 && adapters.size() > 0) 322 | { 323 | for (vector::iterator curadapter = adapters.begin(); curadapter != adapters.end(); ++curadapter) 324 | { 325 | string adaptersuffix = (*curadapter).substr((*curadapter).length() - batterysuffix.length(), batterysuffix.length()); 326 | if(batterysuffix == adaptersuffix) 327 | { 328 | adapterpath = (*curadapter); 329 | break; 330 | } 331 | } 332 | } 333 | 334 | createBattery((*curbat), uevent, adapterpath); 335 | } 336 | } 337 | closedir(dpdf); 338 | } 339 | 340 | void StatsBattery::update(long long sampleID) 341 | { 342 | if(_items.size() == 0) 343 | return; 344 | 345 | for (vector::iterator cur = _items.begin(); cur != _items.end(); ++cur) 346 | { 347 | FILE * fp = NULL; 348 | char buf[512]; 349 | 350 | if (!(fp = fopen((*cur).path.c_str(), "r"))) 351 | { 352 | (*cur).present = 0; 353 | continue; 354 | } 355 | 356 | (*cur).active = true; 357 | 358 | int state = BatteryStateUnknown; 359 | int source = BatterySourceAC; 360 | int present = 1; 361 | int cycles = 0; 362 | int percentage = -1; 363 | int capacityDesign = 0; 364 | int capacityFull = 0; 365 | int capacityNow = 0; 366 | int capacityRate = 0; 367 | int voltage = 0; 368 | float health = 0; 369 | 370 | char charbuf[128]; 371 | 372 | while (fgets(buf, sizeof(buf), fp)) 373 | { 374 | sscanf(buf, "POWER_SUPPLY_PRESENT=%d", &present); 375 | sscanf(buf, "POWER_SUPPLY_CYCLE_COUNT=%d", &cycles); 376 | sscanf(buf, "POWER_SUPPLY_CAPACITY=%d", &percentage); 377 | sscanf(buf, "POWER_SUPPLY_ENERGY_FULL_DESIGN=%d", &capacityDesign); 378 | sscanf(buf, "POWER_SUPPLY_ENERGY_FULL=%d", &capacityFull); 379 | sscanf(buf, "POWER_SUPPLY_ENERGY_NOW=%d", &capacityNow); 380 | sscanf(buf, "POWER_SUPPLY_POWER_NOW=%d", &capacityRate); 381 | sscanf(buf, "POWER_SUPPLY_VOLTAGE_NOW=%d", &voltage); 382 | 383 | if(sscanf(buf, "POWER_SUPPLY_STATUS=%s", charbuf) == 1) 384 | { 385 | string status = string(charbuf); 386 | if(status.find("Charging") == 0) 387 | { 388 | source = BatterySourceAC; 389 | state = BatteryStateCharging; 390 | } 391 | else if(status.find("Discharging") == 0) 392 | { 393 | source = BatterySourceBattery; 394 | state = BatteryStateDraining; 395 | } 396 | else if(status.find("Charged") == 0) 397 | { 398 | source = BatterySourceAC; 399 | state = BatteryStateCharged; 400 | } 401 | else 402 | { 403 | source = BatterySourceAC; 404 | state = BatteryStateCharged; 405 | } 406 | } 407 | } 408 | 409 | 410 | if(percentage == -1) 411 | { 412 | if(capacityFull > 0 && capacityNow > 0) 413 | percentage = (capacityNow / capacityFull) * 100; 414 | else 415 | percentage = 0; 416 | } 417 | 418 | if(percentage > 100) 419 | percentage = 100; 420 | 421 | float t = 0; 422 | if(state == BatteryStateCharging) 423 | { 424 | int remainingUntilFull = capacityFull - capacityNow; 425 | t = 0; 426 | if(remainingUntilFull > 0 && capacityRate > 0) 427 | t = ((float)remainingUntilFull / capacityRate); 428 | } 429 | else if(state == BatteryStateDraining) 430 | { 431 | t = 0; 432 | if(capacityNow > 0 && capacityRate > 0) 433 | t = ((float)capacityNow / capacityRate); 434 | } 435 | 436 | int timeRemaining = t * 60; 437 | 438 | if(capacityDesign > 0 && capacityFull > 0) 439 | health = ((float)capacityFull / (float)capacityDesign) * 100; 440 | 441 | (*cur).state = state; 442 | (*cur).source = source; 443 | (*cur).present = present; 444 | (*cur).cycles = cycles; 445 | (*cur).percentage = percentage; 446 | (*cur).capacityDesign = capacityDesign; 447 | (*cur).capacityFull = capacityFull; 448 | (*cur).capacityNow = capacityNow; 449 | (*cur).capacityRate = capacityRate; 450 | (*cur).voltage = voltage; 451 | (*cur).timeRemaining = timeRemaining; 452 | (*cur).health = health; 453 | 454 | fclose(fp); 455 | } 456 | } 457 | 458 | #else 459 | 460 | void StatsBattery::init() 461 | { 462 | _init(); 463 | } 464 | 465 | void StatsBattery::update(long long sampleID) 466 | { 467 | } 468 | 469 | #endif 470 | 471 | void StatsBattery::_init() 472 | { 473 | initShared(); 474 | ready = 1; 475 | } 476 | 477 | void StatsBattery::prepareUpdate() 478 | { 479 | StatsBase::prepareUpdate(); 480 | 481 | if(_items.size() > 0) 482 | { 483 | for (vector::iterator cur = _items.begin(); cur != _items.end(); ++cur) 484 | { 485 | (*cur).active = false; 486 | } 487 | } 488 | } 489 | 490 | void StatsBattery::createBattery(string key, string batterypath, string adapterpath) 491 | { 492 | if(_items.size() > 0) 493 | { 494 | for (vector::iterator cur = _items.begin(); cur != _items.end(); ++cur) 495 | { 496 | battery_info interface = *cur; 497 | if (interface.key == key) 498 | { 499 | return; 500 | } 501 | } 502 | } 503 | 504 | battery_info battery; 505 | battery.key = key; 506 | battery.path = batterypath; 507 | battery.adapterpath = adapterpath; 508 | 509 | _items.insert(_items.begin(), battery); 510 | } 511 | -------------------------------------------------------------------------------- /src/stats/StatsBattery.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSBATTERY_H 35 | #define _STATSBATTERY_H 36 | 37 | #define BatteryStateUnknown -1 38 | #define BatteryStateCharged 0 39 | #define BatteryStateCharging 1 40 | #define BatteryStateDraining 2 41 | #define BatteryStateNotCharging 3 42 | #define BatteryStateNA 4 43 | 44 | #define BatterySourceBattery 0 45 | #define BatterySourceAC 1 46 | 47 | class battery_info 48 | { 49 | public: 50 | bool active; 51 | long long sampleID; 52 | std::string key; 53 | std::string path; 54 | std::string adapterpath; 55 | 56 | int state; 57 | int source; 58 | int present; 59 | int cycles; 60 | int percentage; 61 | int capacityDesign; 62 | int capacityFull; 63 | int capacityNow; 64 | int capacityRate; 65 | int voltage; 66 | int timeRemaining; 67 | float health; 68 | // std::vector history; 69 | }; 70 | 71 | class StatsBattery : public StatsBase 72 | { 73 | public: 74 | void update(long long sampleID); 75 | void init(); 76 | void _init(); 77 | bool fileExists(std::string path); 78 | std::vector _items; 79 | void createBattery(std::string key, std::string batterypath, std::string adapterpath); 80 | void prepareUpdate(); 81 | }; 82 | #endif 83 | -------------------------------------------------------------------------------- /src/stats/StatsCPU.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSCPU_H 35 | #define _STATSCPU_H 36 | 37 | class StatsCPU : public StatsBase 38 | { 39 | public: 40 | void _init(); 41 | void init(); 42 | void update(long long sampleID); 43 | void processSample(long long sampleID, unsigned long long user, unsigned long long nice, unsigned long long kernel, unsigned long long idle, unsigned long long wait, unsigned long long total); 44 | #ifdef USE_SQLITE 45 | void updateHistory(); 46 | cpu_data historyItemAtIndex(int index); 47 | void loadPreviousSamples(); 48 | void loadPreviousSamplesAtIndex(int index); 49 | #endif 50 | 51 | std::deque samples[8]; 52 | 53 | #ifdef PST_MAX_CPUSTATES 54 | unsigned long long last_ticks[PST_MAX_CPUSTATES]; 55 | #elif defined(CPUSTATES) 56 | unsigned long long last_ticks[CPUSTATES]; 57 | #else 58 | unsigned long long last_ticks[5]; 59 | #endif 60 | unsigned long long last_ticks_lpar[5]; 61 | unsigned long long last_time; 62 | double ticks; 63 | int cpu_count; 64 | bool hasLpar; 65 | double aixEntitlement; 66 | 67 | #ifdef HAVE_LIBKSTAT 68 | kstat_ctl_t *ksh; 69 | #endif 70 | 71 | #ifdef USE_CPU_PROCFS 72 | bool hasIOWait; 73 | #endif 74 | }; 75 | #endif 76 | -------------------------------------------------------------------------------- /src/stats/StatsDisks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSDISKS_H 35 | #define _STATSDISKS_H 36 | 37 | class disk_info 38 | { 39 | public: 40 | bool active; 41 | bool is_new; 42 | unsigned int id; 43 | std::string uuid; 44 | std::string label; 45 | std::string name; 46 | std::string key; 47 | std::string displayName; 48 | double last_update; 49 | std::deque samples[8]; 50 | }; 51 | class StatsDisks : public StatsBase 52 | { 53 | public: 54 | int useMountPaths; 55 | int disableFiltering; 56 | void update(long long sampleID); 57 | int sensorType(int type); 58 | void prepareUpdate(); 59 | void init(); 60 | std::vector _items; 61 | void createDisk(std::string key); 62 | void processDisk(char *name, char *mount, char *type); 63 | int get_sizes(const char *dev, struct disk_data *data); 64 | int should_ignore_type(char *type); 65 | int should_ignore_mount(char *mount); 66 | std::vector customNames; 67 | 68 | void loadHistoryForDisk(disk_info *disk); 69 | #ifdef USE_SQLITE 70 | void updateHistory(); 71 | disk_data historyItemAtIndex(int index, disk_info item); 72 | void loadPreviousSamples(); 73 | void loadPreviousSamplesAtIndex(int index); 74 | #endif 75 | 76 | std::deque samples[8]; 77 | }; 78 | #endif 79 | -------------------------------------------------------------------------------- /src/stats/StatsLoad.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatsLoad.h" 33 | 34 | using namespace std; 35 | 36 | #ifdef USE_LOAD_HPUX 37 | 38 | void StatsLoad::update(long long sampleID) 39 | { 40 | struct pst_dynamic pstat_dynamic; 41 | if (pstat_getdynamic(&pstat_dynamic, sizeof(pstat_dynamic), 1, 0) == -1) { 42 | return; 43 | } 44 | 45 | struct load_data load; 46 | load.one = pstat_dynamic.psd_avg_1_min; 47 | load.two = pstat_dynamic.psd_avg_5_min; 48 | load.three = pstat_dynamic.psd_avg_15_min; 49 | 50 | addSample(load, sampleID); 51 | } /*USE_LOAD_HPUX*/ 52 | 53 | #elif defined(USE_LOAD_PERFSTAT) 54 | 55 | void StatsLoad::update(long long sampleID) 56 | { 57 | struct load_data load; 58 | perfstat_cpu_total_t cpustats; 59 | perfstat_cpu_total(NULL, &cpustats, sizeof cpustats, 1); 60 | load.one = cpustats.loadavg[0]/(float)(1< HISTORY_SIZE) samples[0].pop_back(); 136 | } 137 | 138 | #ifdef USE_SQLITE 139 | void StatsLoad::loadPreviousSamples() 140 | { 141 | loadPreviousSamplesAtIndex(1); 142 | loadPreviousSamplesAtIndex(2); 143 | loadPreviousSamplesAtIndex(3); 144 | loadPreviousSamplesAtIndex(4); 145 | loadPreviousSamplesAtIndex(5); 146 | loadPreviousSamplesAtIndex(6); 147 | loadPreviousSamplesAtIndex(7); 148 | } 149 | 150 | void StatsLoad::loadPreviousSamplesAtIndex(int index) 151 | { 152 | string table = databasePrefix + tableAtIndex(index); 153 | double sampleID = sampleIdForTable(table); 154 | 155 | string sql = "select * from " + table + " where sample >= @sample order by sample asc limit 602"; 156 | DatabaseItem query = _database.databaseItem(sql); 157 | sqlite3_bind_double(query._statement, 1, sampleID - 602); 158 | 159 | while(query.next()) 160 | { 161 | load_data sample; 162 | sample.one = query.doubleForColumn("one"); 163 | sample.two = query.doubleForColumn("five"); 164 | sample.three = query.doubleForColumn("fifteen"); 165 | sample.sampleID = (long long)query.doubleForColumn("sample"); 166 | sample.time = query.doubleForColumn("time"); 167 | samples[index].insert(samples[index].begin(), sample); 168 | } 169 | if(samples[index].size() > 0) 170 | { 171 | sampleIndex[index].sampleID = samples[index][0].sampleID; 172 | sampleIndex[index].time = samples[index][0].time; 173 | sampleIndex[index].nextTime = sampleIndex[index].time + sampleIndex[index].interval; 174 | } 175 | } 176 | 177 | void StatsLoad::updateHistory() 178 | { 179 | int x; 180 | for (x = 1; x < 8; x++) 181 | { 182 | if(sampleIndex[0].time >= sampleIndex[x].nextTime) 183 | { 184 | double now = get_current_time(); 185 | double earlistTime = now - (HISTORY_SIZE * sampleIndex[x].interval); 186 | while(sampleIndex[x].nextTime < now) 187 | { 188 | sampleIndex[x].sampleID = sampleIndex[x].sampleID + 1; 189 | sampleIndex[x].time = sampleIndex[x].nextTime; 190 | sampleIndex[x].nextTime = sampleIndex[x].nextTime + sampleIndex[x].interval; 191 | 192 | if(sampleIndex[x].time < earlistTime) 193 | continue; 194 | 195 | load_data sample = historyItemAtIndex(x); 196 | 197 | samples[x].push_front(sample); 198 | if (samples[x].size() > HISTORY_SIZE) samples[x].pop_back(); 199 | 200 | if(sample.empty) 201 | continue; 202 | 203 | string table = databasePrefix + tableAtIndex(x); 204 | string sql = "insert into " + table + " (empty, sample, time, one, five, fifteen) values(?, ?, ?, ?, ?, ?)"; 205 | 206 | DatabaseItem dbItem = _database.databaseItem(sql); 207 | sqlite3_bind_int(dbItem._statement, 1, 0); 208 | sqlite3_bind_double(dbItem._statement, 2, (double)sample.sampleID); 209 | sqlite3_bind_double(dbItem._statement, 3, sample.time); 210 | sqlite3_bind_double(dbItem._statement, 4, sample.one); 211 | sqlite3_bind_double(dbItem._statement, 5, sample.two); 212 | sqlite3_bind_double(dbItem._statement, 6, sample.three); 213 | databaseQueue.push_back(dbItem); 214 | } 215 | } 216 | } 217 | } 218 | 219 | load_data StatsLoad::historyItemAtIndex(int index) 220 | { 221 | std::deque from = samples[sampleIndex[index].historyIndex]; 222 | double minimumTime = sampleIndex[index].time - sampleIndex[index].interval; 223 | double maximumTime = sampleIndex[index].time; 224 | if(sampleIndex[index].historyIndex == 0) 225 | maximumTime += 0.99; 226 | 227 | double load1 = 0; 228 | double load5 = 0; 229 | double load15 = 0; 230 | load_data sample; 231 | 232 | int count = 0; 233 | if(from.size() > 0) 234 | { 235 | for (deque::iterator cur = from.begin(); cur != from.end(); ++cur) 236 | { 237 | if ((*cur).time > maximumTime) 238 | continue; 239 | 240 | if ((*cur).time < minimumTime) 241 | break; 242 | 243 | load1 += (*cur).one; 244 | load5 += (*cur).two; 245 | load15 += (*cur).three; 246 | count++; 247 | } 248 | if (count > 0) 249 | { 250 | load1 /= count; 251 | load15 /= count; 252 | load15 /= count; 253 | } 254 | } 255 | 256 | sample.one = load1; 257 | sample.two = load15; 258 | sample.three = load15; 259 | 260 | sample.sampleID = sampleIndex[index].sampleID; 261 | sample.time = sampleIndex[index].time; 262 | sample.empty = false; 263 | if(count == 0) 264 | sample.empty = true; 265 | 266 | return sample; 267 | } 268 | #endif 269 | -------------------------------------------------------------------------------- /src/stats/StatsLoad.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSLOAD_H 35 | #define _STATSLOAD_H 36 | 37 | class StatsLoad : public StatsBase 38 | { 39 | public: 40 | void update(long long sampleID); 41 | void addSample(load_data data, long long sampleID); 42 | std::deque samples[8]; 43 | 44 | void init(); 45 | #ifdef USE_SQLITE 46 | void updateHistory(); 47 | load_data historyItemAtIndex(int index); 48 | void loadPreviousSamples(); 49 | void loadPreviousSamplesAtIndex(int index); 50 | #endif 51 | 52 | #ifdef HAVE_LIBKSTAT 53 | kstat_ctl_t *ksh; 54 | #endif 55 | }; 56 | #endif 57 | -------------------------------------------------------------------------------- /src/stats/StatsMemory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSMEMORY_H 35 | #define _STATSMEMORY_H 36 | 37 | class StatsMemory : public StatsBase 38 | { 39 | public: 40 | void update(long long sampleID); 41 | void addSample(mem_data data, long long sampleID); 42 | void prepareSample(mem_data* data); 43 | std::deque samples[8]; 44 | 45 | std::deque databaseKeys; 46 | std::deque databaseMap; 47 | 48 | void _init(); 49 | void init(); 50 | #ifdef USE_SQLITE 51 | void updateHistory(); 52 | mem_data historyItemAtIndex(int index); 53 | void loadPreviousSamples(); 54 | void loadPreviousSamplesAtIndex(int index); 55 | #endif 56 | 57 | #if defined(USE_MEM_SYSCTL) 58 | void updateSwap(mem_data* data); 59 | #endif 60 | 61 | #ifdef HAVE_LIBKSTAT 62 | kstat_ctl_t *ksh; 63 | void get_swp_data(struct mem_data * _mem); 64 | #endif 65 | }; 66 | #endif 67 | -------------------------------------------------------------------------------- /src/stats/StatsNetwork.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSNETWORK_H 35 | #define _STATSNETWORK_H 36 | 37 | class network_info 38 | { 39 | public: 40 | bool active; 41 | unsigned int id; 42 | unsigned long long last_up; 43 | unsigned long long last_down; 44 | 45 | std::vector addresses; 46 | std::string device; 47 | double last_update; 48 | 49 | std::deque samples[8]; 50 | }; 51 | 52 | class StatsNetwork : public StatsBase 53 | { 54 | public: 55 | void update(long long sampleID); 56 | void init(); 57 | std::vector _items; 58 | void createInterface(std::string key); 59 | void processInterface(std::string key, long long sampleID, unsigned long long upload, unsigned long long download); 60 | void updateAddresses(); 61 | void prepareUpdate(); 62 | #ifdef HAVE_LIBKSTAT 63 | kstat_ctl_t *ksh; 64 | std::vector interfaces(); 65 | #endif 66 | 67 | void _init(); 68 | #ifdef USE_SQLITE 69 | void updateHistory(); 70 | net_data historyItemAtIndex(int index, network_info item); 71 | void loadPreviousSamples(); 72 | void loadPreviousSamplesAtIndex(int index); 73 | #endif 74 | 75 | std::deque samples[8]; 76 | 77 | #ifdef USE_NET_SYSCTL 78 | int get_ifcount(); 79 | #endif 80 | }; 81 | #endif 82 | -------------------------------------------------------------------------------- /src/stats/StatsProcesses.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _AIXVERSION_610 35 | int getprocs64 (struct procentry64 *procsinfo, int sizproc, struct fdsinfo64 *fdsinfo, int sizfd, pid_t *index, int count); 36 | #endif 37 | 38 | #ifndef _STATSPROCESSES_H 39 | #define _STATSPROCESSES_H 40 | 41 | class process_info 42 | { 43 | public: 44 | bool exists; 45 | bool is_new; 46 | double cpu; 47 | unsigned long long io_read; 48 | unsigned long long io_write; 49 | unsigned long long io_read_total; 50 | unsigned long long io_write_total; 51 | unsigned long memory; 52 | double cpuTime; 53 | double lastClockTime; 54 | long threads; 55 | int pid; 56 | long long sampleID; 57 | char name[128]; 58 | }; 59 | class StatsProcesses : public StatsBase 60 | { 61 | public: 62 | void update(long long sampleID, double ticks); 63 | void prepareUpdate(); 64 | void init(); 65 | std::vector _items; 66 | void createProcess(int pid); 67 | void processProcess(int pid, long long sampleID); 68 | 69 | long threadCount; 70 | long processCount; 71 | double aixEntitlement; 72 | 73 | #ifdef USE_PROCESSES_PROCFS 74 | std::string nameFromCmd(int pid, std::string name); 75 | std::string nameFromStatus(int pid); 76 | std::vector componentsFromString(std::string input, char seperator); 77 | #endif 78 | 79 | void finishUpdate(); 80 | }; 81 | #endif 82 | -------------------------------------------------------------------------------- /src/stats/StatsSensors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSSENSORS_H 35 | #define _STATSSENSORS_H 36 | 37 | class sensor_info 38 | { 39 | public: 40 | int id; 41 | std::string key; 42 | double last_update; 43 | double lowestValue; 44 | double highestValue; 45 | bool recordedValueChanged; 46 | 47 | int kind; 48 | std::string label; 49 | unsigned int chip; 50 | unsigned int sensor; 51 | int method; 52 | 53 | std::deque samples[8]; 54 | }; 55 | 56 | class StatsSensors : public StatsBase 57 | { 58 | public: 59 | void init(); 60 | void _init(); 61 | void init_dev_cpu(); 62 | void init_qnap(); 63 | void init_acpi_thermal(); 64 | void init_acpi_freq(); 65 | #ifdef HAVE_LIBSENSORS 66 | void init_libsensors(); 67 | #endif 68 | 69 | void update(long long sampleID); 70 | void update_qnap(long long sampleID); 71 | void update_dev_cpu(long long sampleID); 72 | void update_acpi_thermal(long long sampleID); 73 | void update_acpi_freq(long long sampleID); 74 | #ifdef HAVE_LIBSENSORS 75 | void update_libsensors(long long sampleID); 76 | #endif 77 | 78 | std::vector _items; 79 | int createSensor(std::string key); 80 | void processSensor(std::string key, long long sampleID, double value); 81 | 82 | 83 | #ifdef HAVE_LIBSENSORS 84 | bool libsensors_ready; 85 | #if SENSORS_API_VERSION >= 0x0400 /* libsensor 4 */ 86 | int sensorType(int type); 87 | #endif 88 | #endif 89 | 90 | #ifdef USE_SQLITE 91 | void updateHistory(); 92 | sensor_data historyItemAtIndex(int index, sensor_info item); 93 | void loadPreviousSamples(); 94 | void loadPreviousSamplesAtIndex(int index); 95 | #endif 96 | 97 | std::deque samples[8]; 98 | }; 99 | #endif 100 | -------------------------------------------------------------------------------- /src/stats/StatsUptime.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatsUptime.h" 33 | 34 | using namespace std; 35 | 36 | #if defined(USE_UPTIME_HPUX) 37 | 38 | long StatsUptime::getUptime() 39 | { 40 | struct pst_static pstat_static; 41 | if (pstat_getstatic(&pstat_static, sizeof(pstat_static), 1, 0) == -1) { 42 | return; 43 | } 44 | return time(NULL) - pstat_static.boot_time; 45 | } 46 | 47 | #elif defined(HAVE_LIBKSTAT) && defined(USE_UPTIME_KSTAT) 48 | 49 | long StatsUptime::getUptime() 50 | { 51 | kstat_t *ksp; 52 | kstat_named_t *kn; 53 | static time_t boottime; 54 | 55 | if(0 == boottime) 56 | { 57 | kstat_chain_update(ksh); 58 | if(NULL == (ksp = kstat_lookup(ksh, (char*)"unix", -1, (char*)"system_misc"))) return -1; 59 | if(-1 == kstat_read(ksh, ksp, NULL)) return -1; 60 | if(NULL == (kn = (kstat_named_t *) kstat_data_lookup(ksp, (char*)"boot_time"))) return -1; 61 | boottime = (time_t) ksgetull(kn); 62 | } 63 | return time(NULL) - boottime; 64 | } 65 | 66 | /*USE_UPTIME_KSTAT*/ 67 | # elif defined(USE_UPTIME_PROCFS) 68 | 69 | long StatsUptime::getUptime() 70 | { 71 | long uptime; 72 | FILE * fp = NULL; 73 | 74 | if (!(fp = fopen("/proc/uptime", "r"))) return -1; 75 | 76 | if(1 != fscanf(fp, "%ld", &uptime)) 77 | { 78 | return -1; 79 | } 80 | 81 | fclose(fp); 82 | 83 | return uptime; 84 | } 85 | 86 | #elif defined(USE_UPTIME_PERFSTAT) 87 | 88 | long StatsUptime::getUptime() 89 | { 90 | perfstat_cpu_total_t cpustats; 91 | if (perfstat_cpu_total(NULL, &cpustats, sizeof cpustats, 1)!=1) 92 | return 0; 93 | 94 | int hertz = sysconf(_SC_CLK_TCK); 95 | if (hertz <= 0) 96 | hertz = HZ; 97 | 98 | return cpustats.lbolt / hertz; 99 | }/*USE_UPTIME_PERFSTAT*/ 100 | 101 | #elif defined(USE_UPTIME_GETTIME) 102 | 103 | long StatsUptime::getUptime() 104 | { 105 | struct timespec tp; 106 | 107 | tp.tv_sec = 0; 108 | tp.tv_nsec = 0; 109 | 110 | clock_gettime(CLOCK_UPTIME, &tp); 111 | 112 | return (long)(tp.tv_sec); 113 | }/*USE_UPTIME_GETTIME*/ 114 | 115 | #elif defined(USE_UPTIME_SYSCTL) 116 | 117 | long StatsUptime::getUptime() 118 | { 119 | struct timeval tm; 120 | time_t now; 121 | int mib[2]; 122 | size_t size; 123 | 124 | mib[0] = CTL_KERN; 125 | mib[1] = KERN_BOOTTIME; 126 | size = sizeof(tm); 127 | now = time(NULL); 128 | if(-1 != sysctl(mib, 2, &tm, &size, NULL, 0) && 0 != tm.tv_sec) 129 | { 130 | return (long)(now - tm.tv_sec); 131 | } 132 | return 0; 133 | } 134 | #else 135 | 136 | long StatsUptime::getUptime() 137 | { 138 | return 0; 139 | } 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /src/stats/StatsUptime.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Bjango Pty Ltd. All rights reserved. 3 | * Copyright 2010 William Tisäter. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * 3. The name of the copyright holder may not be used to endorse or promote 16 | * products derived from this software without specific prior written 17 | * permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL WILLIAM TISÄTER BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "StatBase.h" 33 | 34 | #ifndef _STATSUPTIME_H 35 | #define _STATSUPTIME_H 36 | 37 | class StatsUptime 38 | { 39 | public: 40 | long getUptime(); 41 | 42 | #ifdef HAVE_LIBKSTAT 43 | kstat_ctl_t *ksh; 44 | #endif 45 | }; 46 | #endif 47 | --------------------------------------------------------------------------------