diff --git a/net-mgmt/pandorafms_agent/Makefile b/net-mgmt/pandorafms_agent/Makefile index 5881d1e..66ba5be 100644 --- a/net-mgmt/pandorafms_agent/Makefile +++ b/net-mgmt/pandorafms_agent/Makefile @@ -40,6 +40,7 @@ post-patch: post-install: @${RM} -f ${STAGEDIR}${LOGDIR}/pandora_agent.log + @${RM} -f ${STAGEDIR}${DATADIR}/collections/.empty @${MKDIR} ${STAGEDIR}${DOCSDIR} .for x in ${PORTDOCS} ${INSTALL_DATA} ${WRKSRC}/${x} ${STAGEDIR}${DOCSDIR} diff --git a/net-mgmt/pandorafms_agent/distinfo b/net-mgmt/pandorafms_agent/distinfo index 6b521f1..6694bac 100644 --- a/net-mgmt/pandorafms_agent/distinfo +++ b/net-mgmt/pandorafms_agent/distinfo @@ -1,2 +1,2 @@ -SHA256 (pandora/pandorafms_agent_unix-5.1.tar.gz) = 9d487573716c088a5121fbb89456000bd39226dbb317ed2d88970f46d4b2bc34 -SIZE (pandora/pandorafms_agent_unix-5.1.tar.gz) = 86100 +SHA256 (pandora/pandorafms_agent_unix-5.1SP1.tar.gz) = b4e4363784a133d4679bdab22c977177ccebc9758e9b6f051d15a7a6a81a7a95 +SIZE (pandora/pandorafms_agent_unix-5.1SP1.tar.gz) = 80277 diff --git a/net-mgmt/pandorafms_agent/files/patch-update b/net-mgmt/pandorafms_agent/files/patch-update deleted file mode 100644 index 3cf74fe..0000000 --- a/net-mgmt/pandorafms_agent/files/patch-update +++ /dev/null @@ -1,1288 +0,0 @@ -Index: ChangeLog -=================================================================== ---- ChangeLog (revision 10314) -+++ ChangeLog (working copy) -@@ -1,3 +1,33 @@ -+2014-08-14 Koichiro Kikuchi -+ -+ * pandora_agent_installer: Fixed symlink source path. -+ -+2014-08-13 Koichiro Kikuchi -+ -+ * FreeBSD/pandora_agent: Small fixes: use proper rc variables, -+ remove obsolete function "set_rcvar" call and use "daemon" command -+ to start pandora_agent. -+ -+ * pandora_agent_installer: Refactored implementation and added -+ "fakeroot" installation support. -+ -+ * plugins/who.sh: Converted to bourne shell script. -+ -+ * pandora_agent_daemon: Small bug fixes and refactorings. -+ -+2014-08-12 Ramon Novoa -+ -+ * pandora_agent: Fixed to make the 'Command Snapshot' feature work. -+ -+2014-08-12 Ramon Novoa -+ -+ * pandora_agent: Trim leading and trailing whitespaces from module names -+ (like policies and windows agents do). -+ -+2014-08-07 Ramon Novoa -+ -+ * pandora_agent_daemon: Fixes the ps call on HP-UX. -+ - 2014-06-04 Koichiro KIKUCHI - - * pandora_agent: Allow spaces in module group names. -Index: pandora_agent_installer -=================================================================== ---- pandora_agent_installer (revision 10314) -+++ pandora_agent_installer (working copy) -@@ -15,49 +15,79 @@ - - FORCE=0 - LOG_TIMESTAMP=`date +"%Y/%m/%d %H:%M:%S"` --PANDORA_HOME=/usr/share/pandora_agent --PANDORA_BIN=/usr/bin/pandora_agent --PANDORA_EXEC_BIN=/usr/bin/pandora_agent_exec --PANDORA_REVENT_BIN=/usr/bin/pandora_revent -+ -+PREFIX=/usr -+if [ "$OS_NAME" = "FreeBSD" ] || [ "$OS_NAME" = "NetBSD" ] -+then -+ PREFIX=/usr/local -+fi -+PANDORA_HOME=$PREFIX/share/pandora_agent -+PANDORA_BIN=$PREFIX/bin/pandora_agent -+PANDORA_EXEC_BIN=$PREFIX/bin/pandora_agent_exec -+PANDORA_REVENT_BIN=$PREFIX/bin/pandora_revent - PANDORA_TEMP=/var/spool/pandora - PANDORA_CFG=/etc/pandora - PANDORA_LOG_DIR=/var/log/pandora - PANDORA_LOG=pandora_agent.log --TENTACLE=/usr/bin/tentacle_client --TENTACLE_SERVER=/usr/bin/tentacle_server --PANDORA_MAN=/usr/share/man -+TENTACLE=$PREFIX/bin/tentacle_client -+TENTACLE_SERVER=$PREFIX/bin/tentacle_server -+PANDORA_MAN=$PREFIX/share/man -+PANDORA_STARTUP=/etc/init.d/pandora_agent_daemon -+DAEMON_SCRIPT=pandora_agent_daemon -+PANDORA_USER="root" -+PANDORA_PERL_PATH="perl" -+WITHOUT_TENTACLE_SERVER=0 -+FAKEROOT=0 - -+# defaults for each platforms -+case $OS_NAME in -+AIX) -+ PANDORA_STARTUP=/etc/rc.pandora_agent_daemon -+ ;; -+HP-UX) -+ PANDORA_STARTUP=/sbin/init.d/pandora_agent_daemon -+ ;; -+FreeBSD) -+ PANDORA_CFG=$PREFIX/etc/pandora -+ PANDORA_MAN=$PREFIX/man -+ PANDORA_STARTUP=$PREFIX/etc/rc.d/pandora_agent -+ DAEMON_SCRIPT=$OS_NAME/pandora_agent -+ PANDORA_PERL_PATH=/usr/local/bin/perl -+ ;; -+NetBSD) -+ PANDORA_CFG=/usr/local/etc/pandora -+ PANDORA_STARTUP=/etc/rc.d/pandora_agent -+ DAEMON_SCRIPT=$OS_NAME/pandora_agent -+ PANDORA_PERL_PATH=/usr/pkg/bin/perl -+ ;; -+esac -+ - MODE=$1 --PANDORA_BASE=`echo $2 | sed -e 's/\/$//'` -+ -+# options -+while : -+do -+ case "$2" in -+ "--no-tentacle-server") WITHOUT_TENTACLE_SERVER=1;; -+ "--fakeroot") FAKEROOT=1;; -+ *) break;; -+ esac -+ shift -+done -+ -+PANDORA_BASE=`echo $2 | sed -e 's|/$||'` - if [ "$3" != "" ] - then - PANDORA_USER=$3 -- if [ "$PANDORA_BASE" = "" ] -+ if [ -z "$PANDORA_BASE" ] - then - echo "When specifying a custom user the agent must be installed to a custom location where that user has write permissions!" - exit 1 - fi --else -- PANDORA_USER="root" - fi - --if [ "$4" != "" ] --then -- PANDORA_PERL_PATH=$4 -- echo $PANDORA_PERL_PATH > PANDORA_PERL_PATH.temp -- sed 's/\//\\\//g' PANDORA_PERL_PATH.temp > PANDORA_PERL_PATH.temp2 -+[ "$4" ] && PANDORA_PERL_PATH=$4 - -- PANDORA_PERL_DECODED_PATH=`cat PANDORA_PERL_PATH.temp2` -- rm PANDORA_PERL_PATH.temp PANDORA_PERL_PATH.temp2 -- #PANDORA_PERL_DECODED_PATH=`echo $PANDORA_PERL_PATH | sed -e "s.\/.\\\\\/.g"` --else -- PANDORA_PERL_PATH="perl" -- if [ "$OS_NAME" = "NetBSD" ] -- then -- PANDORA_PERL_DECODED_PATH="/usr/pkg/bin/perl" -- fi --fi -- - # Check for Perl 5.6.x or higher available - PERL_VERSION=`$PANDORA_PERL_PATH -v | egrep 'v5.6|v5.7|v5.8|v5.9|v5.1[0-9]' | grep perl` - -@@ -69,17 +99,16 @@ - exit 2 - fi - --UNIX_KIND=`uname -s` --if [ -z "`echo Linux HP-UX SunOS AIX Solaris Darwin BSD bsd FreeBSD NetBSD | grep \"$UNIX_KIND\"`" ] -+if [ -z "`echo Linux HP-UX SunOS AIX Solaris Darwin BSD bsd FreeBSD NetBSD | grep \"$OS_NAME\"`" ] - then -- echo "This system: '$UNIX_KIND' is not supported by this script" -+ echo "This system: '$OS_NAME' is not supported by this script" - echo "Please make the install yourself as it's described in documentation" - exit 1 - fi - - - # check for root to do the install --if [ -z "`id | grep \"uid=0(root)\"`" ] -+if [ $FAKEROOT -ne 1 ] && [ -z "`id | grep \"uid=0(root)\"`" ] - then - echo "You need to be root to do the install. Please made a manual install" - echo "if you want to install Pandora FMS agent without root" -@@ -91,7 +120,7 @@ - help () { - echo "Syntax": - echo " " -- echo " ./pandora_agent_installer < --mode > [ destination_path ] [ user_to_run_as ] [custom_perl_path]" -+ echo " ./pandora_agent_installer < --mode > [ --option ] [ destination_path ] [ user_to_run_as ] [custom_perl_path]" - echo " " - echo "Modes:" - echo " " -@@ -99,6 +128,11 @@ - echo " --install To install Pandora FMS Agent on this system" - echo " --uninstall To uninstall/remove Pandora FMS Agent on this System" - echo " " -+ echo "Option:" -+ echo " " -+ echo " --no-tentacle-server Skip tentacle server installation (by default tentalce server installed)" -+ echo " --fakeroot treate \"destination_path\" as root directory" -+ echo " " - echo "Some exaples of how to use the installer:" - echo " " - echo " ./pandora_agent_installer --install" -@@ -110,38 +144,12 @@ - } - - uninstall () { -- OS_NAME=`uname -s` -- - if [ "$OS_NAME" = "Darwin" ] - then - launchctl remove com.pandorafms.pandorafms - rm /Library/LaunchDaemons/com.pandorafms.pandorafms.plist 2> /dev/null - fi - -- -- if [ "$OS_NAME" = "FreeBSD" ] -- then -- PANDORA_HOME=/usr/local/share/pandora_agent -- PANDORA_BIN=/usr/local/bin/pandora_agent -- PANDORA_EXEC_BIN=/usr/local/bin/pandora_agent_exec -- PANDORA_REVENT_BIN=/usr/local/bin/pandora_revent -- PANDORA_CFG=/usr/local/etc/pandora -- TENTACLE=/usr/local/bin/tentacle_client -- TENTACLE_SERVER=/usr/local/bin/tentacle_server -- PANDORA_MAN=/usr/local/man -- fi -- if [ "$OS_NAME" = "NetBSD" ] -- then -- PANDORA_HOME=/usr/local/share/pandora_agent -- PANDORA_BIN=/usr/local/bin/pandora_agent -- PANDORA_EXEC_BIN=/usr/local/bin/pandora_agent_exec -- PANDORA_REVENT_BIN=/usr/local/bin/pandora_revent -- PANDORA_CFG=/usr/local/etc/pandora -- TENTACLE=/usr/local/bin/tentacle_client -- TENTACLE_SERVER=/usr/local/bin/tentacle_server -- PANDORA_MAN=/usr/share/man -- fi -- - echo "Removing Pandora FMS Agent..." - rm -Rf $PANDORA_BASE$PANDORA_BIN 2> /dev/null - rm -Rf $PANDORA_BASE$PANDORA_EXEC_BIN 2> /dev/null -@@ -168,16 +176,19 @@ - rm -Rf $PANDORA_BASE/etc/rc.d/rc?.d/S90pandora_agent_daemon 2> /dev/null - rm -Rf $PANDORA_BASE/etc/rc.d/rc?.d/S90pandora_agent 2> /dev/null - rm -Rf $PANDORA_BASE/usr/local/etc/rc.d/pandora_agent 2> /dev/null -- rm -Rf /etc/init.d/pandora_agent_daemon 2> /dev/null -- rm -Rf /sbin/init.d/pandora_agent_daemon 2> /dev/null -- rm -Rf /etc/rc.pandora_agent_daemon 2> /dev/null -- rm -Rf /etc/rc?.d/S90pandora_agent_daemon 2> /dev/null -- rm -Rf /sbin/rc?.d/S90pandora_agent_daemon 2> /dev/null -- rm -Rf /etc/rc?.d/S90pandora_agent 2> /dev/null -- rm -Rf /sbin/rc?.d/S90pandora_agent 2> /dev/null -- rm -Rf /etc/rc.d/rc?.d/S90pandora_agent_daemon 2> /dev/null -- rm -Rf /etc/rc.d/rc?.d/S90pandora_agent 2> /dev/null -- rm -Rf /usr/local/etc/rc.d/pandora_agent 2> /dev/null -+ if [ $FAKEROOT -ne 1 ] -+ then -+ rm -Rf /etc/init.d/pandora_agent_daemon 2> /dev/null -+ rm -Rf /sbin/init.d/pandora_agent_daemon 2> /dev/null -+ rm -Rf /etc/rc.pandora_agent_daemon 2> /dev/null -+ rm -Rf /etc/rc?.d/S90pandora_agent_daemon 2> /dev/null -+ rm -Rf /sbin/rc?.d/S90pandora_agent_daemon 2> /dev/null -+ rm -Rf /etc/rc?.d/S90pandora_agent 2> /dev/null -+ rm -Rf /sbin/rc?.d/S90pandora_agent 2> /dev/null -+ rm -Rf /etc/rc.d/rc?.d/S90pandora_agent_daemon 2> /dev/null -+ rm -Rf /etc/rc.d/rc?.d/S90pandora_agent 2> /dev/null -+ rm -Rf /usr/local/etc/rc.d/pandora_agent 2> /dev/null -+ fi - - rm -Rf $PANDORA_BASE$PANDORA_HOME 2> /dev/null - rm -Rf $PANDORA_BASE$PANDORA_LOG_DIR 2> /dev/null -@@ -201,36 +212,48 @@ - echo "Done" - } - --install () { -+# -+# install_perl_script [OPTIONS] SRCFILE DESTFILE -+# Install perl script. If PANDORA_PERL_DECODED_PATH is set, path of the perl -+# in shebang line is replaced with PANDORA_PERL_DECODED_PATH value. -+# OPTIONS: -+# -o OWNER owner of the installed script -+# -g GROUP group of the installed script -+# -m PREM mode of the installed script -+# -+install_perl_script () { -+ OWNER=""; GROUP=""; PERM="" -+ while : -+ do -+ case $1 in -+ -o) OWNER=$2;; -+ -g) GROUP=$2;; -+ -m) PERM=$2;; -+ *) break;; -+ esac -+ shift;shift -+ done -+ SRC="$1" -+ DEST="$2" - -- OS_VERSION=`uname -r` -- OS_NAME=`uname -s` -- OLDFILENAMETMP=`date +"%Y-%m-%d"` -- -- if [ "$OS_NAME" = "FreeBSD" ] -+ # do install -+ if echo $PANDORA_PERL_PATH | grep "/" > /dev/null && [ "$PANDORA_PERL_PATH" != "/usr/bin/perl" ] - then -- PANDORA_HOME=/usr/local/share/pandora_agent -- PANDORA_BIN=/usr/local/bin/pandora_agent -- PANDORA_EXEC_BIN=/usr/local/bin/pandora_agent_exec -- PANDORA_REVENT_BIN=/usr/local/bin/pandora_revent -- PANDORA_CFG=/usr/local/etc/pandora -- TENTACLE=/usr/local/bin/tentacle_client -- TENTACLE_SERVER=/usr/local/bin/tentacle_server -- PANDORA_MAN=/usr/local/man -+ sed -e "s:^#\!.*:#\!$PANDORA_PERL_PATH:g" $SRC > $DEST -+ else -+ cp $SRC $DEST - fi - -- if [ "$OS_NAME" = "NetBSD" ] -- then -- PANDORA_HOME=/usr/local/share/pandora_agent -- PANDORA_BIN=/usr/local/bin/pandora_agent -- PANDORA_EXEC_BIN=/usr/local/bin/pandora_agent_exec -- PANDORA_REVENT_BIN=/usr/local/bin/pandora_revent -- PANDORA_CFG=/usr/local/etc/pandora -- TENTACLE=/usr/local/bin/tentacle_client -- TENTACLE_SERVER=/usr/local/bin/tentacle_server -- PANDORA_MAN=/usr/share/man -- fi -+ # set owner, group and permissions -+ [ "$OWNER" ] && chown $OWNER $DEST 2>/dev/null -+ [ "$GROUP" ] && chgrp $GROUP $DEST 2>/dev/null -+ [ "$PERM" ] && chmod $PERM $DEST -+} - -+install () { -+ OS_VERSION=`uname -r` -+ OLDFILENAMETMP=`date +"%Y-%m-%d"` -+ - echo "Detecting Unix distribution: $OS_NAME version $OS_VERSION" - if [ -f $PANDORA_BASE$PANDORA_HOME ] && [ "$FORCE" = "0" ] - then -@@ -253,87 +276,49 @@ - - # Alter dynamically the daemon launcher and setup the new path - # if PANDORA_BASE is customized. -- if [ ! -z "$PANDORA_BASE" ] -+ if [ "$PANDORA_BASE" ] && [ $FAKEROOT -ne 1 ] - then -- if [ "$OS_NAME" = "FreeBSD" ] -- then -- DAEMON_SCRIPT=FreeBSD/pandora_agent -- DAEMON_TEMP=pandora_agent_daemon_temp -- elif [ "$OS_NAME" = "NetBSD" ] -- then -- DAEMON_SCRIPT=NetBSD/pandora_agent -- DAEMON_TEMP=pandora_agent_daemon_temp -- else -- DAEMON_SCRIPT=pandora_agent_daemon -- DAEMON_TEMP=pandora_agent_daemon_temp -- fi -+ DAEMON_TEMP=pandora_agent_daemon_temp - - # Backup the daemon script -- cp -f "$DAEMON_SCRIPT" "$DAEMON_SCRIPT.bak" -+ cp -f "$DAEMON_SCRIPT" "${DAEMON_SCRIPT}.bak" - - AGENT_CFG=$OS_NAME/pandora_agent.conf - AGENT_CFG_TEMP=$OS_NAME/pandora_agent.conf.temp - - # Backup the configuration file -- cp -f "$AGENT_CFG" "$AGENT_CFG.bak" -+ cp -f "$AGENT_CFG" "${AGENT_CFG}.bak" - -- echo $PANDORA_BASE > PANDORA_BASE.temp -- sed 's/\//\\\//g' PANDORA_BASE.temp > PANDORA_BASE.temp2 -- -- PANDORA_BASE_DECODED=`cat PANDORA_BASE.temp2` -- rm PANDORA_BASE.temp PANDORA_BASE.temp2 -- -- if [ "$OS_NAME" = "FreeBSD" -o "$OS_NAME" = "NetBSD" ] -+ if [ "$OS_NAME" = "FreeBSD" ] || [ "$OS_NAME" = "NetBSD" ] - then -- sed -e "s/^PATH\=[.]*/PATH\=$PANDORA_BASE_DECODED\/usr\/local\/bin\:/g" $DAEMON_SCRIPT > $DAEMON_TEMP -+ sed -e "\|^PATH=|s|=|=$PANDORA_BASE$PREFIX/bin:|" \ -+ -e "s|/usr/local/etc/pandora|$PANDORA_BASE$PANDORA_CFG|g" \ -+ -e "s|/usr/local/bin/pandora_agent|$PANDORA_BASE$PANDORA_BIN|g" \ -+ $DAEMON_SCRIPT > $DAEMON_TEMP - mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e "s/^command\=[.]*/command\=$PANDORA_BASE_DECODED/g" $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e 's/^command_args\=\"[.]*/command_args\=\"$PANDORA_BASE_DECODED/g' $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e 's/^required_files\=\"[.]*/required_files\=\"$PANDORA_BASE_DECODED/g' $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT - else -- sed -e "s/^PATH\=[.]*/PATH\=$PANDORA_BASE_DECODED\/usr\/bin\:/g" $DAEMON_SCRIPT > $DAEMON_TEMP -+ sed -e "\|^PATH=|s|=|=$PANDORA_BASE/usr/bin:|" \ -+ -e "\|^PANDORA_PATH=|s|=|=$PANDORA_BASE|" \ -+ -e "\|^LOGFILE=|s|=|=$PANDORA_BASE|" \ -+ -e "\|^DAEMON=|s|=|=$PANDORA_BASE|" \ -+ -e "\|^DAEMON_TENTACLE=|s|=|=$PANDORA_BASE|" \ -+ -e "s/^PANDORA_USER=.*/PANDORA_USER=$PANDORA_USER/" \ -+ $DAEMON_SCRIPT > $DAEMON_TEMP - mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e "s/^PANDORA_PATH\=[.]*/PANDORA_PATH\=$PANDORA_BASE_DECODED/g" $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e "s/^LOGFILE\=[.]*/LOGFILE\=$PANDORA_BASE_DECODED/g" $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e "s/^DAEMON\=[.]*/DAEMON\=$PANDORA_BASE_DECODED/g" $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e "s/^DAEMON_TENTACLE\=[.]*/DAEMON_TENTACLE\=$PANDORA_BASE_DECODED/g" $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT -- -- sed -e "s/^PANDORA_USER\=.*/PANDORA_USER\=$PANDORA_USER/g" $DAEMON_SCRIPT > $DAEMON_TEMP -- mv $DAEMON_TEMP $DAEMON_SCRIPT - fi - -- sed -e "s/^temporal [.]*/temporal $PANDORA_BASE_DECODED/g" $AGENT_CFG > $AGENT_CFG_TEMP -+ sed -e "s|^temporal[ ]*|temporal $PANDORA_BASE|" \ -+ -e "s|^logfile[ ]*|logfile $PANDORA_BASE|" \ -+ $AGENT_CFG > $AGENT_CFG_TEMP - mv $AGENT_CFG_TEMP $AGENT_CFG -- -- sed -e "s/^logfile [.]*/logfile $PANDORA_BASE_DECODED/g" $AGENT_CFG > $AGENT_CFG_TEMP -- mv $AGENT_CFG_TEMP $AGENT_CFG - fi - echo "Creating Pandora FMS Agent home directory at $PANDORA_BASE$PANDORA_HOME" -- if [ ! -z "$PANDORA_BASE" ] -+ if [ "$PANDORA_BASE" ] - then - mkdir -p $PANDORA_BASE 2> /dev/null - mkdir -p $PANDORA_BASE/var/log 2> /dev/null - mkdir -p $PANDORA_BASE/$PANDORA_MAN/man1 2> /dev/null -- if [ "$OS_NAME" = "FreeBSD" -o "$OS_NAME" = "NetBSD" ] -- then -- mkdir -p $PANDORA_BASE/usr/local/bin 2> /dev/null -- else -- mkdir -p $PANDORA_BASE/usr/bin 2> /dev/null -- fi -+ mkdir -p $PANDORA_BASE$PREFIX/bin 2> /dev/null - fi - - mkdir -p $PANDORA_BASE$PANDORA_HOME 2> /dev/null -@@ -344,14 +329,14 @@ - mkdir -p $PANDORA_BASE$PANDORA_TEMP/data_out 2> /dev/null - mkdir -p $PANDORA_BASE$PANDORA_CFG 2> /dev/null - mkdir -p $PANDORA_BASE$PANDORA_LOG_DIR 2> /dev/null -- -+ - # Set the user the agent will run as - if [ "$PANDORA_USER" != "root" ] - then - sed -e "s/.*pandora_user .*/pandora_user $PANDORA_USER/" $AGENT_CFG > $AGENT_CFG_TEMP 2> /dev/null && \ -- mv $AGENT_CFG_TEMP $AGENT_CFG -+ mv $AGENT_CFG_TEMP $AGENT_CFG - chmod 755 pandora_agent_daemon -- chown -R $PANDORA_USER $PANDORA_BASE -+ chown -R $PANDORA_USER $PANDORA_BASE 2>/dev/null - fi - - # Create logfile -@@ -365,32 +350,10 @@ - - # Copying agent and securing it - echo "Copying Pandora FMS Agent to $PANDORA_BASE$PANDORA_BIN..." -+ install_perl_script -m 755 -o $PANDORA_USER -g 0 pandora_agent $PANDORA_BASE$PANDORA_BIN -+ install_perl_script -m 755 -o $PANDORA_USER -g 0 pandora_agent_exec $PANDORA_BASE$PANDORA_EXEC_BIN -+ install_perl_script -m 755 -o $PANDORA_USER -g 0 pandora_revent $PANDORA_BASE$PANDORA_REVENT_BIN - -- if [ "$PANDORA_PERL_DECODED_PATH" != "" ] -- then -- sed -e "s:^#\!.*:#\!$PANDORA_PERL_DECODED_PATH:g" pandora_agent > $PANDORA_BASE$PANDORA_BIN -- else -- cp pandora_agent $PANDORA_BASE$PANDORA_BIN -- fi -- chmod 755 $PANDORA_BASE$PANDORA_BIN -- if [ "$PANDORA_PERL_DECODED_PATH" != "" ] -- then -- sed -e "s:^#\!.*:#\!$PANDORA_PERL_DECODED_PATH:g" pandora_agent_exec > $PANDORA_BASE$PANDORA_EXEC_BIN -- else -- cp pandora_agent_exec $PANDORA_BASE$PANDORA_EXEC_BIN -- fi -- chmod 755 $PANDORA_BASE$PANDORA_EXEC_BIN -- if [ "$PANDORA_PERL_DECODED_PATH" != "" ] -- then -- sed -e "s:^#\!.*:#\!$PANDORA_PERL_DECODED_PATH:g" pandora_revent > $PANDORA_BASE$PANDORA_REVENT_BIN -- else -- cp pandora_revent $PANDORA_BASE$PANDORA_REVENT_BIN -- fi -- chmod 755 $PANDORA_BASE$PANDORA_REVENT_BIN -- chown $PANDORA_USER:0 $PANDORA_BASE$PANDORA_BIN -- chown $PANDORA_USER:0 $PANDORA_BASE$PANDORA_EXEC_BIN -- chown $PANDORA_USER:0 $PANDORA_BASE$PANDORA_REVENT_BIN -- - echo "Copying Pandora FMS Agent configuration file to $PANDORA_BASE$PANDORA_CFG/pandora_agent.conf..." - if [ -f $PANDORA_BASE/$PANDORA_CFG/pandora_agent.conf ] - then -@@ -400,49 +363,36 @@ - - echo "Copying Pandora FMS Agent plugins to $PANDORA_BASE$PANDORA_HOME/plugins..." - -- if [ "$OS_NAME" = "NetBSD" ] -- then -- if [ ! -d $PANDORA_BASE$PANDORA_HOME/plugins ] -+ [ -d $PANDORA_BASE$PANDORA_HOME/plugins ] || mkdir -p $PANDORA_BASE$PANDORA_HOME/plugins >/dev/null 2>&1 -+ for PLUGIN in plugins/* -+ do -+ if grep '^#!.*/perl' $PLUGIN >/dev/null 2>&1 - then -- mkdir -p $PANDORA_BASE$PANDORA_HOME/plugins -+ install_perl_script $PLUGIN $PANDORA_BASE$PANDORA_HOME/$PLUGIN -+ else -+ cp $PLUGIN $PANDORA_BASE$PANDORA_HOME/plugins - fi -- for i in `ls -1 plugins` -- do -- sed s:/usr/bin/perl:/usr/pkg/bin/perl: plugins/$i > plugins/$i.tmp -- cp plugins/$i.tmp $PANDORA_BASE$PANDORA_HOME/plugins/$i -- rm plugins/$i.tmp -- done -- else -- cp -r plugins $PANDORA_BASE$PANDORA_HOME -- fi -- -+ done - chmod -R 700 $PANDORA_BASE$PANDORA_HOME/plugins -- ln -s $PANDORA_BASE$PANDORA_HOME/plugins $PANDORA_BASE$PANDORA_CFG - -+ PANDORA_BASE_REAL="$PANDORA_BASE" -+ [ $FAKEROOT -eq 1 ] && PANDORA_BASE_REAL="" -+ -+ ln -s $PANDORA_BASE_REAL$PANDORA_HOME/plugins $PANDORA_BASE$PANDORA_CFG -+ - echo "Copying Pandora FMS Agent collections to $PANDORA_BASE$PANDORA_HOME/collections..." - cp -r collections $PANDORA_BASE$PANDORA_HOME - chmod -R 700 $PANDORA_BASE$PANDORA_HOME/collections -- ln -s $PANDORA_BASE$PANDORA_HOME/collections $PANDORA_BASE$PANDORA_CFG -+ ln -s $PANDORA_BASE_REAL$PANDORA_HOME/collections $PANDORA_BASE$PANDORA_CFG - -- echo "Copying tentacle server to $PANDORA_BASE$TENTACLE_SERVER" -- if [ "$PANDORA_PERL_DECODED_PATH" != "" ] -- then -- sed -e "s:^#\!.*:#\!$PANDORA_PERL_DECODED_PATH:g" tentacle_server > $PANDORA_BASE$TENTACLE_SERVER -- else -- cp tentacle_server $PANDORA_BASE$TENTACLE_SERVER -- fi -- chmod 755 $PANDORA_BASE$TENTACLE_SERVER -- chown $PANDORA_USER:0 $PANDORA_BASE$TENTACLE_SERVER -+ if [ $WITHOUT_TENTACLE_SERVER -eq 0 ] -+ then -+ echo "Copying tentacle server to $PANDORA_BASE$TENTACLE_SERVER" -+ install_perl_script -m 755 -o $PANDORA_USER -g 0 tentacle_server $PANDORA_BASE$TENTACLE_SERVER -+ fi - - echo "Copying tentacle client to $PANDORA_BASE$TENTACLE" -- if [ "$PANDORA_PERL_DECODED_PATH" != "" ] -- then -- sed -e "s:^#\!.*:#\!$PANDORA_PERL_DECODED_PATH:g" tentacle_client > $PANDORA_BASE$TENTACLE -- else -- cp tentacle_client $PANDORA_BASE$TENTACLE -- fi -- chmod 755 $PANDORA_BASE$TENTACLE -- chown $PANDORA_USER:0 $PANDORA_BASE$TENTACLE -+ install_perl_script -m 755 -o $PANDORA_USER -g 0 tentacle_client $PANDORA_BASE$TENTACLE - - echo "Installing the Pandora Agent and Tentacle Client manuals" - cp man/man1/tentacle_client.1.gz $PANDORA_BASE/$PANDORA_MAN/man1 -@@ -451,14 +401,14 @@ - chmod 644 $PANDORA_BASE/$PANDORA_MAN/man1/pandora_agent.1.gz - - echo "Setting secure permissions and ownership for all Pandora FMS Agent files..." -- chown -R $PANDORA_USER $PANDORA_BASE$PANDORA_HOME -+ chown -R $PANDORA_USER $PANDORA_BASE$PANDORA_HOME 2>/dev/null - chmod -R 700 $PANDORA_BASE$PANDORA_TEMP/data_out - chmod 711 $PANDORA_BASE$PANDORA_LOG_DIR - chmod 640 $PANDORA_BASE$PANDORA_LOG_DIR/$PANDORA_LOG -- chown $PANDORA_USER:0 $PANDORA_BASE$PANDORA_LOG_DIR/$PANDORA_LOG -- if [ "$OS_NAME" = "FreeBSD" -o "$OS_NAME" = "NetBSD" ] -+ chown $PANDORA_USER:0 $PANDORA_BASE$PANDORA_LOG_DIR/$PANDORA_LOG 2>/dev/null -+ if [ "$OS_NAME" = "FreeBSD" ] || [ "$OS_NAME" = "NetBSD" ] - then -- chown $PANDORA_USER:daemon $PANDORA_BASE$PANDORA_TEMP -+ chown $PANDORA_USER:daemon $PANDORA_BASE$PANDORA_TEMP 2>/dev/null - chmod -R 770 $PANDORA_BASE$PANDORA_TEMP - chmod 775 $PANDORA_BASE$PANDORA_TEMP - fi -@@ -467,85 +417,55 @@ - - cp $OS_NAME/pandora_agent.conf $PANDORA_BASE$PANDORA_CFG/pandora_agent.conf - chmod 600 $PANDORA_BASE$PANDORA_CFG/pandora_agent.conf -- chown $PANDORA_USER $PANDORA_BASE$PANDORA_CFG/pandora_agent.conf -+ chown $PANDORA_USER $PANDORA_BASE$PANDORA_CFG/pandora_agent.conf 2>/dev/null - -- if [ "$OS_NAME" = "FreeBSD" -o "$OS_NAME" = "NetBSD" ] -+ echo "Linking start-up daemon script '$DAEMON_SCRIPT' on $OS_NAME"; -+ -+ if [ "$OS_NAME" = "Darwin" ] - then -- echo "Linking start-up daemon script 'pandora_agent' on $OS_NAME"; -+ # Specific service install on Darwin/macOSX -+ launchctl load -F Darwin/com.pandorafms.pandorafms.plist -+ echo "Start Pandora FMS service with 'launchctl start com.pandorafms.pandorafms'" -+ echo "This service has been scheduled to launch on each system startup" - else -- echo "Linking start-up daemon script 'pandora_agent_daemon' on $OS_NAME"; -- fi -+ DESTDIR="" -+ [ "$PANDORA_BASE" ] && [ $FAKEROOT -eq 1 ] && DESTDIR=$PANDORA_BASE - -- if [ "$OS_NAME" = "Darwin" ] -- then -- # Specific service install on Darwin/macOSX -- launchctl load -F Darwin/com.pandorafms.pandorafms.plist -- echo "Start Pandora FMS service with 'launchctl start com.pandorafms.pandorafms'" -- echo "This service has been scheduled to launch on each system startup" -- fi -+ cp $DAEMON_SCRIPT $DESTDIR$PANDORA_STARTUP -+ chmod 755 $DESTDIR$PANDORA_STARTUP -+ chown root:0 $DESTDIR$PANDORA_STARTUP 2>/dev/null - -- if [ "$OS_NAME" = "AIX" ] -- then -- cp pandora_agent_daemon /etc/rc.pandora_agent_daemon -- ln -s /etc/rc.pandora_agent_daemon /etc/rc.d/rc2.d/S90pandora_agent_daemon -- chmod 755 $PANDORA_STARTUP -- chown root:0 $PANDORA_STARTUP -- echo "Pandora FMS agent has been included in /etc/rc.d/rc2.d/S90pandora_agent_daemon" -- fi -- -- if [ $OS_NAME = "HP-UX" ] -- then -- PANDORA_STARTUP=/sbin/init.d/pandora_agent_daemon -- cp pandora_agent_daemon $PANDORA_STARTUP -- ln -s /sbin/init.d/pandora_agent_daemon /sbin/rc3.d/S90pandora_agent_daemon 2> /dev/null -- ln -s /sbin/init.d/pandora_agent_daemon /sbin/rc2.d/S90pandora_agent_daemon 2> /dev/null -- chmod 755 $PANDORA_STARTUP -- chown root:0 $PANDORA_STARTUP -- echo "Pandora FMS agent has been included in /sbin/rcX.d/S90pandora_agent_daemon" -- fi -- -- if [ $OS_NAME = "SunOS" ] -- then -- PANDORA_STARTUP=/etc/init.d/pandora_agent_daemon -- cp pandora_agent_daemon $PANDORA_STARTUP -- ln -s /etc/init.d/pandora_agent_daemon /etc/rc2.d/S90pandora_agent_daemon 2> /dev/null -- chmod 755 $PANDORA_STARTUP -- chown root:0 $PANDORA_STARTUP -- echo "Pandora FMS agent has been included in /etc/rc2.d/S90pandora_agent_daemon" -- fi -- -- if [ $OS_NAME = "Linux" ] -- then -- PANDORA_STARTUP=/etc/init.d/pandora_agent_daemon -- cp pandora_agent_daemon $PANDORA_STARTUP -- if [ -d /etc/rc.d/ ] -+ RCDIRS="" -+ MSG="" -+ if [ "$OS_NAME" = "AIX" ] - then -- ln -s /etc/init.d/pandora_agent_daemon /etc/rc.d/rc2.d/S90pandora_agent 2> /dev/null -- ln -s /etc/init.d/pandora_agent_daemon /etc/rc.d/rc3.d/S90pandora_agent 2> /dev/null -- else -- ln -s /etc/init.d/pandora_agent_daemon /etc/rc2.d/S90pandora_agent 2> /dev/null -- ln -s /etc/init.d/pandora_agent_daemon /etc/rc2.d/S90pandora_agent 2> /dev/null -+ RCDIRS=/etc/rc.d/rc2.d -+ MSG="Pandora FMS agent has been included in $DESTDIR/etc/rc.d/rc2.d/S90pandora_agent_daemon" -+ elif [ "$OS_NAME" = "HP-UX" ] -+ then -+ RCDIRS="/sbin/rc2.d /sbin/rc3.d" -+ MSG="Pandora FMS agent has been included in $DESTDIR/sbin/rcX.d/S90pandora_agent_daemon" -+ elif [ "$OS_NAME" = "SunOS" ] -+ then -+ RCDIRS=/etc/rc2.d -+ MSG="Pandora FMS agent has been included in $DESTDIR/etc/rc2.d/S90pandora_agent_daemon" -+ elif [ "$OS_NAME" = "Linux" ] -+ then -+ if [ -d /etc/rc.d/ ] -+ then -+ RCDIRS="/etc/rc.d/rc2.d /etc/rc.d/rc3.d" -+ else -+ RCDIRS="/etc/rc2.d /etc/rc3.d" -+ fi - fi -- chmod 755 $PANDORA_STARTUP -- chown root:0 $PANDORA_STARTUP -+ [ "$RCDIRS" ] && for RCDIR in $RCDIRS -+ do -+ [ $FAKEROOT -eq 1 ] && [ ! -d $DESTDIR$RCDIR ] && mkdir -p $DESTDIR$RCDIR >/dev/null 2>&1 -+ ln -s $PANDORA_STARTUP $DESTDIR$RCDIR/S90pandora_agent 2> /dev/null -+ done -+ [ "$MSG" ] && echo "$MSG" - fi - -- if [ "$OS_NAME" = "FreeBSD" ] -- then -- PANDORA_STARTUP=/usr/local/etc/rc.d/pandora_agent -- cp FreeBSD/pandora_agent $PANDORA_STARTUP -- chmod 555 $PANDORA_STARTUP -- chown root:wheel $PANDORA_STARTUP -- fi -- -- if [ "$OS_NAME" = "NetBSD" ] -- then -- PANDORA_STARTUP=/etc/rc.d/pandora_agent -- cp NetBSD/pandora_agent $PANDORA_STARTUP -- chmod 555 $PANDORA_STARTUP -- chown root:wheel $PANDORA_STARTUP -- fi -- - echo "Done." - echo " " - echo "You have your startup script ready at $PANDORA_STARTUP" -Index: plugins/who.sh -=================================================================== ---- plugins/who.sh (revision 10314) -+++ plugins/who.sh (working copy) -@@ -1,10 +1,10 @@ --#!/bin/bash -+#!/bin/sh - echo ""; - echo "who"; - echo "async_string"; - echo " 0x01; -+use constant WIN32_SERVICE_RUNNING => 0x04; -+ - my $t_libwrap_installed = eval { require Authen::Libwrap } ? 1 : 0; - - if ($t_libwrap_installed) { -@@ -77,9 +83,8 @@ - : eval { require IO::Socket::INET } ? 'IO::Socket::INET' - : die $@; - --if ($SOCKET_MODULE eq 'IO::Socket::INET') { -- print_log ("IO::Socket::INET6 is not found. IPv6 is disabled."); --} -+# Service name for Win32. -+my $SERVICE_NAME="Tentacle Server"; - - # Program version - our $VERSION = '0.4.0'; -@@ -130,7 +135,7 @@ - my $t_select; - - # Semaphore --my $t_sem; -+my $t_sem :shared; - - # Server socket - my @t_server_sockets; -@@ -197,6 +202,7 @@ - print ("\t-p port\t\tPort to listen on (default $t_port).\n"); - print ("\t-q\t\tQuiet. Do now print error messages.\n"); - print ("\t-r number\tNumber of retries for network opertions (default $t_retries).\n"); -+ print ("\t-S (install|uninstall|run) Manage the win32 service.\n"); - print ("\t-t time\t\tTime-out for network operations in seconds (default ${t_timeout}s).\n"); - print ("\t-v\t\tBe verbose.\n"); - print ("\t-w\t\tPrompt for OpenSSL private key password.\n"); -@@ -241,27 +247,6 @@ - } - - ################################################################################ --## SUB start_win_service --## Turn the current process into a Windows service. --################################################################################ --#sub start_win_service { --# require Win32::Daemon; --# --# # Tell the OS to start the service --# Win32::Daemon::StartService (); --# --# # Wait until the service manager is ready --# while (SERVICE_START_PENDING != Win32::Daemon::State()) { --# sleep (1); --# } --# --# # Tell the service manager we are running --# Win32::Daemon::State (SERVICE_RUNNING); --# --# # Call Win32::Daemon::StopService() when done --#} -- --################################################################################ - ## SUB parse_options - ## Parse command line options and initialize global variables. - ################################################################################ -@@ -271,7 +256,7 @@ - my @t_addresses_tmp; - - # Get options -- if (getopts ('a:c:de:f:hi:k:m:op:qr:s:t:vwx:b:g:T', \%opts) == 0 || defined ($opts{'h'})) { -+ if (getopts ('a:b:c:de:f:g:hi:k:m:op:qr:s:S:t:Tvwx:', \%opts) == 0 || defined ($opts{'h'})) { - print_help (); - exit 1; - } -@@ -467,19 +452,33 @@ - error ("Authen::Libwrap is not installed."); - } - } --} - --################################################################################ --## SUB sigchld_handler --## Handle child process termination. --################################################################################ --sub sigchld_handler { -+ # Win32 service management -+ if (defined ($opts{'S'})) { -+ my $service_action = $opts{'S'}; -+ if ($^O ne 'MSWin32') { -+ error ("Windows services are only available on Win32."); -+ } else { -+ eval "use Win32::Daemon"; -+ die($@) if ($@); - -- while (waitpid(-1, &WNOHANG) > 0) { -- $t_sem->up (); -+ if ($service_action eq 'install') { -+ install_service(); -+ } elsif ($service_action eq 'uninstall') { -+ uninstall_service(); -+ } elsif ($service_action eq 'run') { -+ Win32::Daemon::RegisterCallbacks({ -+ start => \&callback_start, -+ running => \&callback_running, -+ stop => \&callback_stop, -+ }); -+ Win32::Daemon::StartService(); -+ exit 0; -+ } else { -+ error("Unknown action: $service_action"); -+ } -+ } - } -- -- $SIG{CHLD} = \&sigchld_handler; - } - - ################################################################################ -@@ -660,87 +659,86 @@ - } - - ################################################################################ --## SUB accept_connection --## Accept an incoming connection and fork. -+## SUB accept_connections -+## Manage incoming connections. - ################################################################################ --sub accept_connection { -+sub accept_connections { - my $pid; - my $t_server_socket; - -- my @ready = $select->can_read; -+ # Start server -+ start_server (); - -- foreach $t_server_socket (@ready) { -+ # Initialize semaphore -+ $t_sem = Thread::Semaphore->new ($t_max_conn); - -- # Accept connection -- $t_client_socket = $t_server_socket->accept (); -+ while (1) { -+ my @ready = $select->can_read; -+ foreach $t_server_socket (@ready) { - -- if (! defined ($t_client_socket)) { -+ # Accept connection -+ $t_client_socket = $t_server_socket->accept (); - -- # EINTR -- if ($! ne '') { -- next; -+ if (! defined ($t_client_socket)) { -+ next if ($! ne ''); # EINTR -+ error ("accept: $!."); - } - -- error ("accept: $!."); -- } -+ print_log ("Client connected from " . $t_client_socket->sockhost ()); - -- print_log ("Client connected from " . $t_client_socket->sockhost ()); -- -- # Fork and serve the client -- $pid = fork (); -- if (! defined ($pid)) { -- error ("Cannot fork: $!."); -+ # Create a new thread and serve the client -+ $t_sem->down(); -+ my $thr = threads->create(\&serve_client); -+ if (! defined ($thr)) { -+ error ("Error creating thread: $!."); -+ } -+ $thr->detach(); - } -- -- # Child -- if ($pid == 0) { -- -- # We do not need the server socket -- $t_server_socket->close (); - -- if ($t_use_libwrap) { -- if (! hosts_ctl($t_program_name, $t_client_socket)) { -- print_log ("Connection from " . $t_client_socket->sockhost() . " is closed by tcpwrappers."); -- $t_client_socket->close (); -+ usleep (1000); -+ } -+} - -- exit; -- } -- } -- -- # Add client socket to select queue -- $t_select = IO::Select->new (); -- $t_select->add ($t_client_socket); -- -- # Start SSL -- if ($t_ssl == 1) { -- start_ssl (); -- } -+################################################################################ -+## SUB serve_client -+## Serve a connected client. -+################################################################################ -+sub serve_client() { - -- # Authenticate client -- if ($t_pwd ne '') { -- auth_pwd (); -- } -+ if ($t_use_libwrap) { -+ if (! hosts_ctl($t_program_name, $t_client_socket)) { -+ print_log ("Connection from " . $t_client_socket->sockhost() . " is closed by tcpwrappers."); -+ $t_client_socket->close (); -+ $t_sem->up(); -+ return; -+ } -+ } - -- # Check if proxy mode is enable -- if (defined ($t_proxy_ip)) { -- -- serve_proxy_connection (); -+ eval { -+ # Add client socket to select queue -+ $t_select = IO::Select->new (); -+ $t_select->add ($t_client_socket); - -- } else { -- -- serve_connection (); -- } -- -- $t_client_socket->close (); -- -- # Must exit now -- exit; -+ # Start SSL -+ if ($t_ssl == 1) { -+ start_ssl (); - } -+ -+ # Authenticate client -+ if ($t_pwd ne '') { -+ auth_pwd (); -+ } -+ -+ # Check if proxy mode is enable -+ if (defined ($t_proxy_ip)) { -+ serve_proxy_connection (); -+ } else { -+ serve_connection (); -+ } -+ }; - -- # Parent -- $t_client_socket->close (); -- -- } -+ $t_client_socket->close (); -+ $t_sem->up(); - } - - ################################################################################ -@@ -1045,10 +1043,8 @@ - sub error { - - if ($t_quiet == 0) { -- print (STDERR "[err] $_[0]\n"); -+ die("[err] $_[0]\n\n"); - } -- -- exit 1; - } - - ################################################################################ -@@ -1414,6 +1410,91 @@ - } - - ################################################################################ -+## SUB install_service -+## Install the Windows service. -+################################################################################ -+sub install_service() { -+ -+ my $service_path = $0; -+ my $service_params = "-s \"$t_directory\" -S run"; -+ -+ my %service_hash = ( -+ machine => '', -+ name => 'TENTACLESRV', -+ display => $SERVICE_NAME, -+ path => $service_path, -+ user => '', -+ pwd => '', -+ description => 'Tentacle Server http://sourceforge.net/projects/tentacled/', -+ parameters => $service_params -+ ); -+ -+ if (Win32::Daemon::CreateService(\%service_hash)) { -+ print "Successfully added.\n"; -+ exit 0; -+ } else { -+ print "Failed to add service: " . Win32::FormatMessage(Win32::Daemon::GetLastError()) . "\n"; -+ exit 1; -+ } -+} -+ -+################################################################################ -+## SUB uninstall_service -+## Install the Windows service. -+################################################################################ -+sub uninstall_service() { -+ if (Win32::Daemon::DeleteService('', 'TENTACLESRV')) { -+ print "Successfully deleted.\n"; -+ exit 0; -+ } else { -+ print "Failed to delete service: " . Win32::FormatMessage(Win32::Daemon::GetLastError()) . "\n"; -+ exit 1; -+ } -+} -+ -+################################################################################ -+## SUB callback_running -+## Windows service callback function for the running event. -+################################################################################ -+sub callback_running { -+ -+ if (Win32::Daemon::State() == WIN32_SERVICE_RUNNING) { -+ } -+} -+ -+################################################################################ -+## SUB callback_start -+## Windows service callback function for the start event. -+################################################################################ -+sub callback_start { -+ -+ # Accept_connections (); -+ my $thr = threads->create(\&accept_connections); -+ if (!defined($thr)) { -+ Win32::Daemon::State(WIN32_SERVICE_STOPPED); -+ Win32::Daemon::StopService(); -+ return; -+ } -+ $thr->detach(); -+ -+ Win32::Daemon::State(WIN32_SERVICE_RUNNING); -+} -+ -+################################################################################ -+## SUB callback_stop -+## Windows service callback function for the stop event. -+################################################################################ -+sub callback_stop { -+ -+ foreach my $t_server_socket (@t_server_sockets) { -+ $t_server_socket->close (); -+ } -+ -+ Win32::Daemon::State(WIN32_SERVICE_STOPPED); -+ Win32::Daemon::StopService(); -+} -+ -+################################################################################ - # Main - ################################################################################ - -@@ -1444,25 +1525,16 @@ - - # Handle ctr-c - if ($^O eq 'MSWin32') { -+ no warnings; - $SIG{INT2} = \&stop_server; -+ use warnings; - } - else { - $SIG{INT} = \&stop_server; - } - --# Handle SIGCHLD --$SIG{CHLD} = \&sigchld_handler; -- --start_server (); -- --# Initialize semaphore --$t_sem = Thread::Semaphore->new ($t_max_conn); -- - # Accept connections --while (1) { -- $t_sem->down (); -- accept_connection (); --} -+accept_connections(); - - __END__ - -Index: pandora_agent_daemon -=================================================================== ---- pandora_agent_daemon (revision 10314) -+++ pandora_agent_daemon (working copy) -@@ -34,38 +34,39 @@ - OS_NAME=`uname -s` - if [ $OS_NAME = "HP-UX" ] - then -- PANDORA_PID=`ps -ex | grep "$DAEMON $PANDORA_PATH" | grep -v grep | head -1 | awk '{ print $1 }'` -- else -- if [ "$OS_NAME" = "SunOS" ] -+ PANDORA_PID=`ps -ef | grep "/usr/bin/perl $DAEMON" | grep -v grep | awk '{print $2}'` -+ elif [ "$OS_NAME" = "SunOS" ] -+ then -+ ZONENAME_CMD="/bin/zonename" -+ TRUNCATED_DAEMON=`echo "$DAEMON $PANDORA_PATH" | cut -c1-20` -+ if [ -x $ZONENAME_CMD ] - then -- ZONENAME_CMD="/bin/zonename" -- TRUNCATED_DAEMON=`echo "$DAEMON $PANDORA_PATH" | cut -c1-20` -- if [ -x $ZONENAME_CMD ] -- then -- ZONE=`$ZONENAME_CMD` -- else -- ZONE= -- fi -- if [ "$ZONE" = "global" ] -- then -- PANDORA_PID=`ps -f -z global | grep "$TRUNCATED_DAEMON" | grep -v grep | head -1 | awk '{ print $2 }'` -- else -- PANDORA_PID=`ps -Af | grep "$TRUNCATED_DAEMON" | grep -v grep | head -1 | awk '{ print $2 }'` -- fi -- elif [ "$OS_NAME" = "Linux" -a -x /usr/sbin/vzpid ] -+ ZONE=`$ZONENAME_CMD` -+ else -+ ZONE= -+ fi -+ if [ "$ZONE" = "global" ] - then -- for _pid in `ps -Af | grep "$DAEMON $PANDORA_PATH" | grep -v grep | awk '{ print $2 }'` -- do -- _ctid=`/usr/sbin/vzpid $_pid | awk '$1 == '$_pid' { print $2 }'` -- if [ "X$_ctid" = "X0" ] -- then -- PANDORA_PID=$_pid -- break -- fi -- done -+ PANDORA_PID=`ps -f -z global | grep "$TRUNCATED_DAEMON" | grep -v grep | head -1 | awk '{ print $2 }'` - else -- PANDORA_PID=`ps -Af | grep "$DAEMON $PANDORA_PATH" | grep -v grep | head -1 | awk '{ print $2 }'` -+ PANDORA_PID=`ps -Af | grep "$TRUNCATED_DAEMON" | grep -v grep | head -1 | awk '{ print $2 }'` - fi -+ elif [ "$OS_NAME" = "Linux" ] && [ -x /usr/sbin/vzpid ] -+ then -+ # Virtuozzo/OpenVZ -+ local _pid _ctid _pids -+ _pids=`ps -Af | grep "$DAEMON $PANDORA_PATH" | grep -v grep | awk '{ print $2 }'` -+ [ "$_pids" ] && for _pid in $_pids -+ do -+ _ctid=`/usr/sbin/vzpid $_pid | awk '$1 == '$_pid' { print $2 }'` -+ if [ "X$_ctid" = "X0" ] -+ then -+ PANDORA_PID=$_pid -+ break -+ fi -+ done -+ else -+ PANDORA_PID=`ps -Af | grep "$DAEMON $PANDORA_PATH" | grep -v grep | head -1 | awk '{ print $2 }'` - fi - - echo $PANDORA_PID -Index: pandora_agent -=================================================================== ---- pandora_agent (revision 10314) -+++ pandora_agent (working copy) -@@ -343,6 +343,8 @@ - init_module ($module); - } elsif ($line =~ /^\s*module_name\s+(.+)$/) { - $module->{'name'} = $1; -+ $module->{'name'} =~ s/\s+$//g; -+ $module->{'name'} =~ s/^\s+//g; - } elsif ($line =~ /^\s*module_description\s+(.+)$/) { - $module->{'description'} = $1; - } elsif ($line =~ /^\s*module_type\s+(\S+)\s*$/) { -@@ -1727,12 +1729,7 @@ - - # Data list - if ($#data > 0) { -- $Xml .= " \n"; -- foreach my $data_item (@data) { -- chomp ($data_item); -- $Xml .= " \n"; -- } -- $Xml .= " \n"; -+ $Xml .= " \n"; - # Single data - } else { - chomp ($data[0]); -Index: FreeBSD/pandora_agent -=================================================================== ---- FreeBSD/pandora_agent (revision 10314) -+++ FreeBSD/pandora_agent (working copy) -@@ -3,6 +3,7 @@ - # ********************************************************************** - # Pandora FMS Agent Daemon launcher for FreeBSD - # (c) 2010 Junichi Satoh -+# (c) 2014 Koichiro Kikuchi - # - # ********************************************************************** - -@@ -18,7 +19,7 @@ - . "/etc/rc.subr" - - name="pandora_agent" --rcvar=`set_rcvar` -+rcvar=pandora_agent_enable - - # read configuration and set defaults - pandora_agent_enable=${pandora_agent_enable:-"NO"} -@@ -26,22 +27,15 @@ - - PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin - --command=/usr/local/bin/pandora_agent --command_args="/usr/local/etc/pandora &" -- - pidfile=/var/run/$name.pid - required_files="/usr/local/etc/pandora/pandora_agent.conf" --start_postcmd=start_postcmd - stop_postcmd=stop_postcmd - --procname="/usr/bin/perl" -+command=/usr/sbin/daemon -+command_interpreter=/usr/local/bin/perl -+procname=/usr/local/bin/pandora_agent - --start_postcmd() --{ -- sleep 1 -- PANDORA_PID=`pgrep -f -j none $name` -- echo $PANDORA_PID > $pidfile --} -+command_args="-cfp $pidfile $procname /usr/local/etc/pandora" - - stop_postcmd() - { diff --git a/net-mgmt/pandorafms_console/Makefile b/net-mgmt/pandorafms_console/Makefile index d0b5f01..801bd54 100644 --- a/net-mgmt/pandorafms_console/Makefile +++ b/net-mgmt/pandorafms_console/Makefile @@ -50,16 +50,17 @@ post-install: && ${RM} -rf pandora_console_install* *.spec \ extras/check_other_languages.sh.bak \ include/languages/extract_newlines.sh.bak \ - *.sql.bak COPYING ${PORTDOCS} DEBIAN/ + *.sql.bak COPYING ${PORTDOCS} DEBIAN/ \ + attachment/collections/.empty attachment/downloads/.gitignore @cd ${STAGEDIR}${WWWDIR} && ${MV} install.php install.done .if ${PORT_OPTIONS:MDOCS} @${MKDIR} ${STAGEDIR}${DOCSDIR} .for x in ${PORTDOCS} - @${INSTALL_DATA} ${WRKSRC}/${x} ${STAGEDIR}${DOCSDIR} + ${INSTALL_DATA} ${WRKSRC}/${x} ${STAGEDIR}${DOCSDIR} .endfor .endif - @${MKDIR} -p ${STAGEDIR}${PREFIX}/${APACHEETCDIR}/Includes - @${INSTALL_DATA} ${WRKDIR}/pandora_console.conf \ + @${MKDIR} ${STAGEDIR}${PREFIX}/${APACHEETCDIR}/Includes + ${INSTALL_DATA} ${WRKDIR}/pandora_console.conf \ ${STAGEDIR}${PREFIX}/${APACHEETCDIR}/Includes/pandora_console.conf.sample @${LN} -sf ${_LICENSE_DIR}/${LICENSE} ${STAGEDIR}${WWWDIR}/COPYING diff --git a/net-mgmt/pandorafms_console/distinfo b/net-mgmt/pandorafms_console/distinfo index a69eb8f..d59de78 100644 --- a/net-mgmt/pandorafms_console/distinfo +++ b/net-mgmt/pandorafms_console/distinfo @@ -1,2 +1,2 @@ -SHA256 (pandora/pandorafms_console-5.1.tar.gz) = 4f9624f4ddbe416929b3ce47a737073da2ff319f6121454b66140fb2a70c4638 -SIZE (pandora/pandorafms_console-5.1.tar.gz) = 28264905 +SHA256 (pandora/pandorafms_console-5.1SP1.tar.gz) = 5696fef415db22fd0eaffb3d8286eddfe3d123c86bae9a8a4044b7937efb8742 +SIZE (pandora/pandorafms_console-5.1SP1.tar.gz) = 27900949 diff --git a/net-mgmt/pandorafms_console/files/patch-update b/net-mgmt/pandorafms_console/files/patch-update deleted file mode 100644 index 2d0fb9a..0000000 --- a/net-mgmt/pandorafms_console/files/patch-update +++ /dev/null @@ -1,9578 +0,0 @@ -Index: pandoradb_data.sql -=================================================================== ---- pandoradb_data.sql (revision 10314) -+++ pandoradb_data.sql (working copy) -@@ -283,7 +283,7 @@ - -- Dumping data for table `tnews` - -- - --INSERT INTO `tnews` (`id_news`, `author`, `subject`, `text`, `timestamp`) VALUES (1,'admin','Welcome to Pandora FMS 5.0!','This is the new Pandora FMS Console. A lot of new features have been added since last version. Please read the documentation about it, and feel free to test any option.\r\n\r\nThe Pandora FMS Team.',NOW()); -+INSERT INTO `tnews` (`id_news`, `author`, `subject`, `text`, `timestamp`) VALUES (1,'admin','Welcome to Pandora FMS!','This is the Pandora FMS Console. A lot of new features have been added since last version. Please read the documentation about it, and feel free to test any option.\r\n\r\nThe Pandora FMS Team.',NOW()); - INSERT INTO `tnews` (`id_news`, `author`, `subject`, `text`, `timestamp`) VALUES (2,'admin','New Pandora FMS Agent Features','Feel free to test our new features for both Windows and Linux agents: Proxy and Broker modes.',NOW()); - - INSERT INTO tmodule VALUES (1,'Agent module'); -Index: include/functions_clippy.php -=================================================================== ---- include/functions_clippy.php (revision 0) -+++ include/functions_clippy.php (revision 10417) -@@ -0,0 +1,176 @@ -+ -+ -+ ' . -+ '' . -+ html_print_image( -+ "images/clippy_icon.png", -+ true) . -+ '' . -+ ' -+ -+ '; -+ -+ -+ -+ return $return; -+} -+?> -\ No newline at end of file -Index: include/styles/menu.css -=================================================================== ---- include/styles/menu.css (revision 10314) -+++ include/styles/menu.css (working copy) -@@ -81,7 +81,6 @@ - .submenu { - font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif; - margin: 0px 10px 0px 0; -- width: 173px; - } - .submenu li a { - background-color: #222; -@@ -143,10 +142,6 @@ - background-position: 4px 8px; - } - --.menu { -- width: 173px; -- --} - /* Icons specified here */ - #icon_oper-networkconsole { - background-image: url(../../images/op_network.png); -@@ -234,7 +229,6 @@ - #menu_container { - z-index: 3; - position: absolute; -- left: -140px; -+ left: -80px; - background-color: #AAA; -- height: 100%; - } -Index: include/styles/pandora.css -=================================================================== ---- include/styles/pandora.css (revision 10314) -+++ include/styles/pandora.css (working copy) -@@ -278,7 +278,7 @@ - } - - div#menu { -- width: 165px; -+ width: 175px; - float: left; - } - -@@ -291,6 +291,14 @@ - background-color: #274C00; - } - -+.fixed_header { -+ z-index: 9999; -+ position: fixed; -+ left: 0; -+ top: 0; -+ width: 100%; -+} -+ - div#foot { - font-size: 6pt !important; - border-top: solid 2px #222; -@@ -298,7 +306,6 @@ - padding-bottom: 5px; - text-align: center; - background: #333333; -- width: 960px; - height: 38px; - clear: both; - width: auto; -@@ -901,17 +908,10 @@ - padding: 6px 0px; - height: 14px; - } --.titop { -- -moz-border-top-right-radius: 6px; -- -webkit-border-top-right-radius: 6px; -- border-top-right-radius: 6px; -- heigth: 100px; --} - .tit, .titb { - font-weight: bold; - color: #fff; - text-align: center; -- width: 173px; - } - - .suc * { -@@ -1863,12 +1863,10 @@ - div#main { - width: auto; - float: none; -- padding-right: 0px; -- padding-left: 0px; -- padding-top: 0px; -- padding-bottom: 20px; -- margin-left: 182px; -- margin-right: 20px; -+ margin-top: 10px; -+ margin-left: 185px; -+ margin-right: 10px; -+ padding-bottom: 10px; - background: #ECECEC; - min-width: 720px; - } -@@ -2669,7 +2667,7 @@ - margin: 0px !important; - bottom: 0px; - left: 0px; -- z-index: 1020; -+ z-index: 9001; - } - - #shortcut_bar { -@@ -2704,3 +2702,12 @@ - table#policy_modules td * { - display: inline; - } -+ -+ -+.context_help_title { -+ font-weight: bolder; -+ text-align: left; -+} -+.context_help_body { -+ text-align: left; -+} -\ No newline at end of file -Index: include/functions_update_manager.php -=================================================================== ---- include/functions_update_manager.php (revision 10314) -+++ include/functions_update_manager.php (working copy) -@@ -24,11 +24,17 @@ - global $build_version; - global $pandora_version; - -- $license = db_get_value('`value`', 'tupdate_settings', '`key`', -+ $license = db_get_value( -+ db_encapsule_fields_with_same_name_to_instructions('value'), -+ 'tupdate_settings', -+ db_encapsule_fields_with_same_name_to_instructions('key'), - 'customer_key'); - - if (enterprise_installed()) { -- $current_update = db_get_value('`value`', 'tupdate_settings', '`key`', -+ $current_update = db_get_value( -+ db_encapsule_fields_with_same_name_to_instructions('value'), -+ 'tupdate_settings', -+ db_encapsule_fields_with_same_name_to_instructions('key'), - 'current_package_enterprise'); - - $current_update = 0; -@@ -36,7 +42,10 @@ - $current_update = $config['current_package_enterprise']; - } - else { -- $current_update = db_get_value('`value`', 'tupdate_settings', '`key`', -+ $current_update = db_get_value( -+ db_encapsule_fields_with_same_name_to_instructions('value'), -+ 'tupdate_settings', -+ db_encapsule_fields_with_same_name_to_instructions('key'), - 'current_package'); - - $current_update = 0; -@@ -64,10 +73,12 @@ - function rrmdir($dir) { - if (is_dir($dir)) { - $objects = scandir($dir); -+ - foreach ($objects as $object) { - if ($object != "." && $object != "..") { -- if (filetype($dir."/".$object) == "dir") -- rrmdir($dir."/".$object); else unlink($dir."/".$object); -+ if (filetype($dir . "/" . $object) == "dir") -+ rrmdir($dir . "/" . $object); -+ else unlink($dir . "/" . $object); - } - } - reset($objects); -@@ -264,11 +275,13 @@ - return false; - } - else { -- if ($is_ajax) { -- return true; -+ $result = json_decode($result, true); -+ -+ if (empty($result)) { -+ return false; - } - else { -- return false; -+ return true; - } - } - } -@@ -362,8 +375,10 @@ - "/downloads/last_package.tgz"; - - try { -+ rrmdir($config['attachment_store'] . -+ "/downloads/temp_update/pandora_console"); -+ - $phar = new PharData($path_package); -- rrmdir($config['attachment_store'] . "/downloads/temp_update/pandora_console"); - $phar->extractTo($config['attachment_store'] . "/downloads/temp_update"); - } - catch (Exception $e) { -@@ -384,7 +399,14 @@ - array('value' => 50), - array('token' => 'progress_update')); - -- $full_path = $config['attachment_store'] . "/downloads/temp_update/pandora_console"; -+ $path_array = array('downloads', 'temp_update', 'pandora_console'); -+ $full_path = $config['attachment_store']; -+ foreach ($path_array as $directory) { -+ $full_path = $full_path . '/' . $directory; -+ if (!is_dir($full_path)) { -+ mkdir($full_path); -+ } -+ } - - $homedir = $config['homedir']; - -Index: include/functions_groups.php -=================================================================== ---- include/functions_groups.php (revision 10314) -+++ include/functions_groups.php (working copy) -@@ -236,7 +236,7 @@ - * @param integer $parent The id_group parent to search the childrens. - * @param array $groups The groups, its for optimize the querys to DB. - */ --function groups_get_childrens($parent, $groups = null) { -+function groups_get_childrens($parent, $groups = null, $onlyPropagate = false) { - if (empty($groups)) { - $groups = db_get_all_rows_in_table('tgrupo'); - } -@@ -248,7 +248,7 @@ - continue; - } - -- if ($group['propagate']) { -+ if ($group['propagate'] || $onlyPropagate) { - if ($group['parent'] == $parent) { - $return = $return + array($group['id_grupo'] => $group) + groups_get_childrens($group['id_grupo'], $groups); - } -@@ -1531,4 +1531,42 @@ - } - } - } -+ -+/** -+ * Return an array with the groups hierarchy (Recursive) -+ * -+ * @param array Groups array passed by reference -+ * @param mixed The id of the parent to search or false to begin the search from the first hierarchy level -+ * -+ * @return array The groups reordered by its hierarchy -+ */ -+function groups_get_tree(&$groups, $parent = false) { -+ $return = array(); -+ -+ foreach ($groups as $id => $group) { -+ if ($parent === false && (!isset($group['parent']) || $group['parent'] == 0)) { -+ $return[$id] = $group; -+ unset($groups[$id]); -+ $children = groups_get_tree($groups, $id); -+ -+ if (!empty($children)) { -+ $return[$id]['children'] = $children; -+ } -+ } -+ else if ($parent && isset($group['parent']) && $group['parent'] == $parent) { -+ $return[$id] = $group; -+ unset($groups[$id]); -+ $children = groups_get_tree($groups, $id); -+ -+ if (!empty($children)) { -+ $return[$id]['children'] = $children; -+ } -+ } -+ else { -+ continue; -+ } -+ } -+ -+ return $return; -+} - ?> -Index: include/functions_visual_map.php -=================================================================== ---- include/functions_visual_map.php (revision 10314) -+++ include/functions_visual_map.php (working copy) -@@ -114,9 +114,11 @@ - echo '
'; - if ($layoutData['image'] != null) { - if (($width != 0) && ($height != 0)) -- echo html_print_image($img, true, array("class" => "image", "id" => "image_" . $id, "width" => "$width", "height" => "$height", "style" => $borderStyle)); -+ echo html_print_image($img, true, -+ array("class" => "image", "id" => "image_" . $id, "width" => "$width", "height" => "$height", "style" => $borderStyle)); - else -- echo html_print_image($img, true, array("class" => "image", "id" => "image_" . $id, "style" => $borderStyle)); -+ echo html_print_image($img, true, -+ array("class" => "image", "id" => "image_" . $id, "style" => $borderStyle)); - echo '
'; - } - echo io_safe_output($text); -@@ -1299,8 +1301,28 @@ - } - - $img_style = array (); -+ - $img_style["title"] = strip_tags($layout_data["label"]); -+ if ($layout_data['type'] == STATIC_GRAPH) { -+ if ($layout_data['id_agente_modulo'] != 0) { -+ $unit_text = trim(io_safe_output( -+ modules_get_unit($layout_data['id_agente_modulo']))); -+ -+ $value = modules_get_last_value($layout_data['id_agente_modulo']); -+ -+ if (!is_string($value)) { -+ $value = format_for_graph($value, 2); -+ } -+ -+ if (!empty($unit_text)) -+ $value .= " " . $unit_text; -+ -+ $img_style["title"] .= "
" . __("Last value: ") . -+ $value; -+ } -+ } - -+ - if (!empty ($layout_data["width"])) { - $img_style["width"] = $layout_data["width"]; - } -Index: include/ajax/events.php -=================================================================== ---- include/ajax/events.php (revision 10314) -+++ include/ajax/events.php (working copy) -@@ -349,7 +349,13 @@ - } - - $details = events_page_details($event, $server); -- -+ -+ // Juanma (09/05/2014) Fix: Needs to reconnect to node, in previous funct node connection was lost -+ if ($meta) { -+ $server = metaconsole_get_connection_by_id ($server_id); -+ metaconsole_connect($server); -+ } -+ - $custom_fields = events_page_custom_fields($event); - - $custom_data = events_page_custom_data($event); -Index: include/ajax/module.php -=================================================================== ---- include/ajax/module.php (revision 10314) -+++ include/ajax/module.php (working copy) -@@ -23,6 +23,14 @@ - enterprise_include_once ('include/functions_metaconsole.php'); - - $get_plugin_macros = get_parameter('get_plugin_macros'); -+$search_modules = get_parameter('search_modules'); -+$get_module_detail = get_parameter ('get_module_detail', 0); -+$get_module_autocomplete_input = (bool) get_parameter('get_module_autocomplete_input'); -+$add_module_relation = (bool) get_parameter('add_module_relation'); -+$remove_module_relation = (bool) get_parameter('remove_module_relation'); -+$change_module_relation_updates = (bool) get_parameter('change_module_relation_updates'); -+$get_id_tag = (bool) get_parameter('get_id_tag', 0); -+ - if ($get_plugin_macros) { - $id_plugin = get_parameter('id_plugin', 0); - -@@ -37,7 +45,7 @@ - return; - } - --$search_modules = get_parameter('search_modules'); -+ - if ($search_modules) { - $id_agents = json_decode(io_safe_output(get_parameter('id_agents'))); - $filter = get_parameter('q', '') . '%'; -@@ -56,10 +64,9 @@ - return; - } - --$get_module_detail = get_parameter ('get_module_detail', 0); - - if ($get_module_detail) { -- -+ - ui_include_time_picker(); - - ui_require_jquery_file("ui.datepicker-" . get_user_language(), "include/javascript/i18n/"); -@@ -82,6 +89,9 @@ - $conexion = mysql_connect ($server['dbhost'], $server['dbuser'], $server['dbpass']); - $select_db = mysql_select_db ($server['dbname'], $conexion); - } -+ else { -+ $conexion = false; -+ } - - $selection_mode = get_parameter('selection_mode', 'fromnow'); - $date_from = (string) get_parameter ('date_from', date ('Y-m-j')); -@@ -131,15 +141,16 @@ - - html_print_table($formtable); - -- $moduletype_name = modules_get_moduletype_name (modules_get_agentmodule_type ($module_id)); -+ $moduletype_name = modules_get_moduletype_name( -+ modules_get_agentmodule_type($module_id)); - - $offset = (int) get_parameter("offset"); - $block_size = (int) $config["block_size"]; - - $columns = array (); - -- $datetime_from = strtotime ($date_from.' '.$time_from); -- $datetime_to = strtotime ($date_to.' '.$time_to); -+ $datetime_from = strtotime ($date_from . ' ' . $time_from); -+ $datetime_to = strtotime ($date_to . ' ' . $time_to); - - if ($moduletype_name == "log4x") { - $table->width = "100%"; -@@ -222,14 +233,30 @@ - ); - } - -+ - $sql_body = io_safe_output($sql_body); - // Clean all codification characters - - $sql = "SELECT * " . $sql_body; -- $sql_count = "SELECT count(*) " . $sql_body; - -+ switch ($config['dbtype']) { -+ case "mysql": -+ $sql_count = "SELECT count(*) " . $sql_body; -+ break; -+ case "postgresql": -+ $sql_body = str_replace("ORDER BY utimestamp DESC", -+ "GROUP BY utimestamp ORDER BY utimestamp DESC", -+ $sql_body); -+ $sql_count = "SELECT count(DISTINCT utimestamp) " . $sql_body; -+ break; -+ case "oracle": -+ $sql_count = "SELECT count(*) " . $sql_body; -+ break; -+ } -+ - $count = db_get_value_sql ($sql_count, $conexion); - -+ - switch ($config["dbtype"]) { - case "mysql": - $sql .= " LIMIT " . $offset . "," . $block_size; -@@ -337,10 +364,10 @@ - return; - } - --$get_module_autocomplete_input = (bool) get_parameter('get_module_autocomplete_input'); -+ - if ($get_module_autocomplete_input) { - $id_agent = (int) get_parameter("id_agent"); -- -+ - ob_clean(); - if ($id_agent > 0) { - html_print_autocomplete_modules( -@@ -350,7 +377,7 @@ - return; - } - --$add_module_relation = (bool) get_parameter('add_module_relation'); -+ - if ($add_module_relation) { - $result = false; - $id_module_a = (int) get_parameter("id_module_a"); -@@ -384,7 +411,7 @@ - return; - } - --$remove_module_relation = (bool) get_parameter('remove_module_relation'); -+ - if ($remove_module_relation) { - $id_relation = (int) get_parameter("id_relation"); - if ($id_relation > 0) { -@@ -395,23 +422,25 @@ - return; - } - --$change_module_relation_updates = (bool) get_parameter('change_module_relation_updates'); -+ - if ($change_module_relation_updates) { - $id_relation = (int) get_parameter("id_relation"); - if ($id_relation > 0) { - $result = (bool) modules_change_relation_lock($id_relation); - } -+ - echo json_encode($result); - return; - } - --$get_id_tag = (bool) get_parameter('get_id_tag', 0); -+ - if ($get_id_tag) { - $tag_name = get_parameter('tag_name'); -- -+ - if ($tag_name) { - $tag_id = db_get_value('id_tag', 'ttag', 'name', $tag_name); -- } else { -+ } -+ else { - $tag_id = 0; - } - -Index: include/functions_api.php -=================================================================== ---- include/functions_api.php (revision 10314) -+++ include/functions_api.php (working copy) -@@ -757,7 +757,7 @@ - $cascadeProtection = $other['data'][4]; - $intervalSeconds = $other['data'][5]; - $idOS = $other['data'][6]; -- $idServer = $other['data'][7]; -+ $nameServer = $other['data'][7]; - $customId = $other['data'][8]; - $learningMode = $other['data'][9]; - $disabled = $other['data'][10]; -@@ -806,7 +806,8 @@ - $cascadeProtection = $other['data'][4]; - $intervalSeconds = $other['data'][5]; - $idOS = $other['data'][6]; -- $idServer = $other['data'][7]; -+ //$idServer = $other['data'][7]; -+ $nameServer = $other['data'][7]; - $customId = $other['data'][8]; - $learningMode = $other['data'][9]; - $disabled = $other['data'][10]; -@@ -815,12 +816,12 @@ - switch ($config["dbtype"]) { - case "mysql": - $sql1 = 'SELECT name -- FROM tserver WHERE id_server =' . $idServer; -+ FROM tserver WHERE name LIKE "' . $nameServer . '"'; - break; - case "postgresql": - case "oracle": - $sql1 = 'SELECT name -- FROM tserver WHERE id_server =' . $idServer; -+ FROM tserver WHERE name LIKE \'' . $nameServer . '\''; - break; - } - -@@ -2476,7 +2477,7 @@ - if (!$module_values) { - returnError('error_get_module_value_all_agents', 'Error getting module values from all agents.'); - } -- else{ -+ else { - $data = array('type' => 'array', 'data' => $module_values); - - returnData('csv', $data, ';'); -@@ -4856,7 +4857,7 @@ - else { - $return = true; - } -- -+ - $data['type'] = 'string'; - if ($return === false) { - $data['data'] = 0; -@@ -4865,7 +4866,7 @@ - $data['data'] = $return; - } - returnData('string', $data); -- return; -+ return; - } - else { - returnError('error_parameter', 'Error in the parameters.'); -@@ -4900,20 +4901,20 @@ - - - "; -- -+ - $xml = sprintf($xmlTemplate, io_safe_output(get_os_name($agent['id_os'])), - io_safe_output($agent['os_version']), $agent['intervalo'], - io_safe_output($agent['agent_version']), date('Y/m/d H:i:s', $time), - io_safe_output($agent['nombre']), $agent['timezone_offset'], - io_safe_output($agentModule['nombre']), io_safe_output($agentModule['descripcion']), modules_get_type_name($agentModule['id_tipo_modulo']), $data); -- -- -+ -+ - if (false === @file_put_contents($config['remote_config'] . '/' . io_safe_output($agent['nombre']) . '.' . $time . '.data', $xml)) { - returnError('error_file', 'Can save agent data xml.'); - } - else { - returnData('string', array('type' => 'string', 'data' => $xml)); -- return; -+ return; - } - } - } -@@ -6064,7 +6065,7 @@ - $id_agent = agents_get_agent_id($agent_name); - $id_agent_module = db_get_value_filter('id_agente_modulo', 'tagente_modulo', array('id_agente' => $id_agent, 'nombre' => $module_name)); - -- $result = modules_change_disabled($id_agent_module, 1); -+ $result = modules_change_disabled($id_agent_module, 0); - - if ($result === NOERR) { - returnData('string', array('type' => 'string', 'data' => __('Correct module enable'))); -@@ -6665,7 +6666,8 @@ - 'module_lag' => $server["module_lag"], - 'threads' => $server["threads"], - 'queued_modules' => $server["queued_modules"], -- 'keepalive' => $server['keepalive'] -+ 'keepalive' => $server['keepalive'], -+ 'id_server' => $server['id_server'] - ); - - // servers_get_info() returns "servername" for recon server's name. -Index: include/functions_ui.php -=================================================================== ---- include/functions_ui.php (revision 10314) -+++ include/functions_ui.php (working copy) -@@ -1245,7 +1245,13 @@ - } - $output .= "\n\t"; - -+ -+ -+ -+ -+ //////////////////////////////////////////////////////////////////// - //Load CSS -+ //////////////////////////////////////////////////////////////////// - if (empty ($config['css'])) { - $config['css'] = array (); - } -@@ -1270,7 +1276,8 @@ - } - } - -- //First, if user has assigned a skin then try to use css files of skin subdirectory -+ //First, if user has assigned a skin then try to use css files of -+ //skin subdirectory - $isFunctionSkins = enterprise_include_once ('include/functions_skins.php'); - if (!$login_ok) { - if ($isFunctionSkins !== ENTERPRISE_NOT_HOOK) { -@@ -1278,6 +1285,7 @@ - } - } - -+ - $exists_css = false; - if ($login_ok and $isFunctionSkins !== ENTERPRISE_NOT_HOOK) { - //Checks if user's skin is available -@@ -1305,12 +1313,17 @@ - $config['css']); - } - -+ -+ - // Add the jquery UI styles CSS - $config['css']['jquery-UI'] = "include/styles/jquery-ui-1.10.0.custom.css"; -- - // Add the dialog styles CSS - $config['css']['dialog'] = "include/styles/dialog.css"; -+ // Add the dialog styles CSS -+ $config['css']['dialog'] = "include/javascript/introjs.css"; - -+ -+ - //We can't load empty and we loaded (conditionally) ie - $loaded = array ('', 'ie'); - -@@ -1333,25 +1346,34 @@ - $output .= ''."\n\t"; - } - } -+ //////////////////////////////////////////////////////////////////// - //End load CSS -+ //////////////////////////////////////////////////////////////////// - -+ -+ -+ -+ //////////////////////////////////////////////////////////////////// - //Load JS -+ //////////////////////////////////////////////////////////////////// - if (empty ($config['js'])) { - $config['js'] = array (); //If it's empty, false or not init set array to empty just in case - } - -+ - //Pandora specific JavaScript should go first - $config['js'] = array_merge (array ("pandora" => "include/javascript/pandora.js"), $config['js']); -- - //Load base64 javascript library - $config['js']['base64'] = "include/javascript/encode_decode_base64.js"; -- - //Load webchat javascript library - $config['js']['webchat'] = "include/javascript/webchat.js"; -- - //Load qrcode library - $config['js']['qrcode'] = "include/javascript/qrcode.js"; -+ //Load intro.js library (for bubbles and clippy) -+ $config['js']['intro'] = "include/javascript/intro.js"; -+ $config['js']['clippy'] = "include/javascript/clippy.js"; - -+ - //Load other javascript - //We can't load empty - $loaded = array (''); -@@ -1370,9 +1392,15 @@ - $output .= ''."\n\t"; - } - } -+ //////////////////////////////////////////////////////////////////// - //End load JS -+ //////////////////////////////////////////////////////////////////// - -+ -+ -+ //////////////////////////////////////////////////////////////////// - //Load jQuery -+ //////////////////////////////////////////////////////////////////// - if (empty ($config['jquery'])) { - $config['jquery'] = array (); //If it's empty, false or not init set array to empty just in case - } -@@ -1422,8 +1450,13 @@ - $output .= ''."\n\t"; - } - } -+ //////////////////////////////////////////////////////////////////// -+ //End load JQuery -+ //////////////////////////////////////////////////////////////////// - - -+ -+ - if ($config['flash_charts']) { - //Include the javascript for the js charts library - include_once($config["homedir"] . '/include/graphs/functions_flot.php'); -@@ -1576,9 +1609,9 @@ - - // Show GOTO FIRST button - if ($other_class == '') { -- $output .= ' '; -+ $output .= ' '; - } else { -- $output .= " "; -+ $output .= " "; - } - - // Show PREVIOUS button -@@ -1588,9 +1621,9 @@ - $index_page_prev = 0; - - if ($other_class == '') { -- $output .= ''; -+ $output .= ''; - } else { -- $output .= ""; -+ $output .= ""; - } - } - -@@ -1629,13 +1662,12 @@ - // Index_counter stores max of blocks - if (($paginacion_maxima == 1) AND (($index_counter - $i) > 0)) { - $prox_bloque = ($i + ceil ($block_limit / 2)) * $pagination; -- if ($prox_bloque > $count) -- $prox_bloque = ($count -1) - $pagination; -- -+ if ($prox_bloque >= $count) -+ $prox_bloque = (int) (($count - 1) / $pagination) * $pagination; - if ($other_class == '') { -- $output .= ''; -+ $output .= ''; - } else { -- $output .= ""; -+ $output .= ""; - } - $i = $index_counter; - } -@@ -1647,9 +1679,9 @@ - $myoffset = floor (($count - 1) / $pagination) * $pagination; - - if ($other_class == '') { -- $output .= ''; -+ $output .= ''; - } else { -- $output .= ""; -+ $output .= ""; - } - } - -@@ -2268,7 +2300,8 @@ - $buffer .= '' . - ui_print_truncate_text($title, 38); - if ($help != "") -- $buffer .= "
" . ui_print_help_icon ($help, true, '', 'images/help_w.png') . "
"; -+ $buffer .= "
" . -+ ui_print_help_icon ($help, true, '', 'images/help_w.png') . "
"; - $buffer .= '
'; - - if (is_array($options)) { -Index: include/functions.php -=================================================================== ---- include/functions.php (revision 10314) -+++ include/functions.php (working copy) -@@ -768,6 +768,23 @@ - return get_parameter($name, 0); - } - -+function get_cookie($name, $default = '') { -+ if (isset($_COOKIE[$name])) { -+ return $_COOKIE[$name]; -+ } -+ else { -+ return $default; -+ } -+} -+ -+function set_cookie($name, $value) { -+ if (is_null($value)) { -+ unset($_COOKIE[$value]); -+ setcookie($value, null, -1, '/'); -+ } -+ setcookie($name, $value); -+} -+ - /** - * Get a parameter from a request. - * -@@ -1430,9 +1447,11 @@ - * - * @return array SNMP result. - */ --function get_snmpwalk($ip_target, $snmp_version, $snmp_community = '', $snmp3_auth_user = '', -- $snmp3_security_level = '', $snmp3_auth_method = '', $snmp3_auth_pass = '', -- $snmp3_privacy_method = '', $snmp3_privacy_pass = '', $quick_print = 0, $base_oid = "", $snmp_port = '') { -+function get_snmpwalk($ip_target, $snmp_version, $snmp_community = '', -+ $snmp3_auth_user = '', $snmp3_security_level = '', -+ $snmp3_auth_method = '', $snmp3_auth_pass = '', -+ $snmp3_privacy_method = '', $snmp3_privacy_pass = '', -+ $quick_print = 0, $base_oid = "", $snmp_port = '') { - - global $config; - -@@ -1464,7 +1483,7 @@ - else { - $snmpwalk_bin = $config['snmpwalk']; - } -- -+ - switch (PHP_OS) { - case "WIN32": - case "WINNT": -@@ -1480,16 +1499,54 @@ - $rc = 0; - switch ($snmp_version) { - case '3': -- exec ($snmpwalk_bin . ' -m ALL -v 3 -u ' . escapeshellarg($snmp3_auth_user) . ' -A ' . escapeshellarg($snmp3_auth_pass) . ' -l ' . escapeshellarg($snmp3_security_level) . ' -a ' . escapeshellarg($snmp3_auth_method) . ' -x ' . escapeshellarg($snmp3_privacy_method) . ' -X ' . escapeshellarg($snmp3_privacy_pass) . ' ' . escapeshellarg($ip_target) . ' ' . $base_oid . ' 2> ' . $error_redir_dir, $output, $rc); -+ switch ($snmp3_security_level) { -+ case "authNoPriv": -+ $command_str = $snmpwalk_bin . -+ ' -m ALL -v 3' . -+ ' -u ' . escapeshellarg($snmp3_auth_user) . -+ ' -A ' . escapeshellarg($snmp3_auth_pass) . -+ ' -l ' . escapeshellarg($snmp3_security_level) . -+ ' -a ' . escapeshellarg($snmp3_auth_method) . -+ ' ' . escapeshellarg($ip_target) . -+ ' ' . $base_oid . -+ ' 2> ' . $error_redir_dir; -+ break; -+ case "noAuthNoPriv": -+ $command_str = $snmpwalk_bin . -+ ' -m ALL -v 3' . -+ ' -u ' . escapeshellarg($snmp3_auth_user) . -+ ' -l ' . escapeshellarg($snmp3_security_level) . -+ ' ' . escapeshellarg($ip_target) . -+ ' ' . $base_oid . -+ ' 2> ' . $error_redir_dir; -+ break; -+ default: -+ $command_str = $snmpwalk_bin . -+ ' -m ALL -v 3' . -+ ' -u ' . escapeshellarg($snmp3_auth_user) . -+ ' -A ' . escapeshellarg($snmp3_auth_pass) . -+ ' -l ' . escapeshellarg($snmp3_security_level) . -+ ' -a ' . escapeshellarg($snmp3_auth_method) . -+ ' -x ' . escapeshellarg($snmp3_privacy_method) . -+ ' -X ' . escapeshellarg($snmp3_privacy_pass) . -+ ' ' . escapeshellarg($ip_target) . -+ ' ' . $base_oid . -+ ' 2> ' . $error_redir_dir; -+ break; -+ } - break; - case '2': - case '2c': - case '1': - default: -- exec ($snmpwalk_bin . ' -m ALL -v ' . escapeshellarg($snmp_version) . ' -c ' . escapeshellarg($snmp_community) . ' ' . escapeshellarg($ip_target) . ' ' . $base_oid . ' 2> ' . $error_redir_dir, $output, $rc); -+ $command_str = $snmpwalk_bin . ' -m ALL -v ' . escapeshellarg($snmp_version) . ' -c ' . escapeshellarg($snmp_community) . ' ' . escapeshellarg($ip_target) . ' ' . $base_oid . ' 2> ' . $error_redir_dir; - break; - } - -+ //html_debug_print($command_str); -+ -+ exec($command_str, $output, $rc); -+ - // Parse the output of snmpwalk - $snmpwalk = array(); - foreach ($output as $line) { -@@ -2134,4 +2191,29 @@ - return $news; - } - -+ -+/** -+ * Print audit data in CSV format. -+ * -+ * @param array Audit data. -+ * -+ */ -+function print_audit_csv ($data) { -+ global $config; -+ global $graphic_type; -+ -+ $config['ignore_callback'] = true; -+ while (@ob_end_clean ()); -+ -+ header("Content-type: application/octet-stream"); -+ header("Content-Disposition: attachment; filename=audit_log".date("Y-m-d_His").".csv"); -+ header("Pragma: no-cache"); -+ header("Expires: 0"); -+ -+ echo __('User') . ';' . __('Action') . ';' . __('Date') . ';' . __('Source ID') . ';'. __('Comments') ."\n"; -+ foreach ($data as $line) { -+ echo io_safe_output($line['id_usuario']) . ';' . io_safe_output($line['accion']) . ';' . $line['fecha'] . ';' . $line['ip_origen'] . ';'. io_safe_output($line['descripcion']). "\n"; -+ } -+} -+ - ?> -Index: include/functions_agents.php -=================================================================== ---- include/functions_agents.php (revision 10314) -+++ include/functions_agents.php (working copy) -@@ -360,6 +360,11 @@ - } - } - -+ //Fix for postgresql -+ if (empty($filter['id_agente'])) { -+ unset($filter['id_agente']); -+ } -+ - $where = db_format_array_where_clause_sql ($filter, 'AND', ''); - - $where_nogroup = db_format_array_where_clause_sql ($filter_nogroup, 'AND', ''); -@@ -412,6 +417,7 @@ - return $sql; - else - $agents = db_get_all_rows_sql($sql); -+ - break; - case "oracle": - $set = array(); -Index: include/functions_graph.php -=================================================================== ---- include/functions_graph.php (revision 10314) -+++ include/functions_graph.php (working copy) -@@ -102,13 +102,14 @@ - - foreach ($chart_array as $item) { - if ($series_suffix != '') { -- $item['sum'] = $item['sum'.$series_suffix]; -- $item['min'] = $item['min'.$series_suffix]; -- $item['max'] = $item['max'.$series_suffix]; -+ $item['sum'] = $item['sum' . $series_suffix]; -+ $item['min'] = $item['min' . $series_suffix]; -+ $item['max'] = $item['max' . $series_suffix]; - } - - //Get stats for normal graph - if (isset($item['sum']) && $item['sum']) { -+ - //Sum all values later divide by the number of elements - $stats['sum']['avg'] = $stats['sum']['avg'] + $item['sum']; - -@@ -245,6 +246,7 @@ - $is_unknown = $start_unknown; - - // Calculate chart data -+ $last_known = $previous_data; - for ($i = 0; $i < $resolution; $i++) { - $timestamp = $datelimit + ($interval * $i); - -@@ -270,6 +272,7 @@ - $interval_min = $data[$data_i]['datos']; - } - $total += $data[$data_i]['datos']; -+ $last_known = $data[$data_i]['datos']; - $count++; - $data_i++; - } -@@ -399,7 +402,6 @@ - $chart[$timestamp]['sum'.$series_suffix] = $total; - $chart[$timestamp]['min'.$series_suffix] = $interval_min; - } -- $previous_data = $total; - // Compressed data - } - else { -@@ -415,12 +417,12 @@ - } - else { - if ($avg_only) { -- $chart[$timestamp]['sum'.$series_suffix] = $previous_data; -+ $chart[$timestamp]['sum'.$series_suffix] = $last_known; - } - else { -- $chart[$timestamp]['max'.$series_suffix] = $previous_data; -- $chart[$timestamp]['sum'.$series_suffix] = $previous_data; -- $chart[$timestamp]['min'.$series_suffix] = $previous_data; -+ $chart[$timestamp]['max'.$series_suffix] = $last_known; -+ $chart[$timestamp]['sum'.$series_suffix] = $last_known; -+ $chart[$timestamp]['min'.$series_suffix] = $last_known; - } - } - } -@@ -580,7 +582,7 @@ - if (!$projection) { - return fs_error_image (); - } -- else{ -+ else { - return fs_error_image (); - } - } -@@ -1103,6 +1105,7 @@ - $countAvg = 0; - - // Calculate chart data -+ $last_known = $previous_data; - for ($l = 0; $l < $resolution; $l++) { - $countAvg ++; - -@@ -1117,8 +1120,8 @@ - $count = 0; - - // Read data that falls in the current interval -- $interval_min = $previous_data; -- $interval_max = $previous_data; -+ $interval_min = $last_known; -+ $interval_max = $last_known; - while (isset ($data[$j]) && $data[$j]['utimestamp'] >= $timestamp && $data[$j]['utimestamp'] < ($timestamp + $interval)) { - if ($data[$j]['datos'] > $interval_max) { - $interval_max = $data[$j]['datos']; -@@ -1127,6 +1130,7 @@ - $interval_min = $data[$j]['datos']; - } - $total += $data[$j]['datos']; -+ $last_known = $data[$j]['datos']; - $count++; - $j++; - } -@@ -1153,18 +1157,14 @@ - if ($count > 0) { - //$graph_values[$i][$timestamp] = $total * $weight_list[$i]; - $temp_graph_values[$timestamp_short] = $total * $weight_list[$i]; -- -- $previous_data = $total; - } - else { - // Compressed data - if ($uncompressed_module || ($timestamp > time ())) { -- //$graph_values[$i][$timestamp] = 0; - $temp_graph_values[$timestamp_short] = 0; - } - else { -- //$graph_values[$i][$timestamp] = $previous_data * $weight_list[$i]; -- $temp_graph_values[$timestamp_short] = $previous_data * $weight_list[$i]; -+ $temp_graph_values[$timestamp_short] = $last_known * $weight_list[$i]; - } - } - -@@ -1459,16 +1459,19 @@ - $filter['id_agente'] = $id_agent; - } - -- $fields = array('SUM(critical_count) Critical', -- 'SUM(warning_count) Warning', -- 'SUM(normal_count) Normal', -- 'SUM(unknown_count) Unknown'); -+ $fields = array('SUM(critical_count) AS Critical', -+ 'SUM(warning_count) AS Warning', -+ 'SUM(normal_count) AS Normal', -+ 'SUM(unknown_count) AS Unknown'); - - if ($show_not_init) { - $fields[] = 'SUM(notinit_count) "Not init"'; - } - - $data = db_get_row_filter('tagente', $filter, $fields); -+ if (empty($data)) { -+ $data = array(); -+ } - - array_walk($data, 'truncate_negatives'); - -@@ -1796,6 +1799,7 @@ - if ($modules === false) - $modules = array (); - -+ $data = array(); - foreach ($modules as $module) { - $agent_name = agents_get_name ($module['id_agente'], "none"); - -@@ -1816,7 +1820,8 @@ - $water_mark = array('file' => $config['homedir'] . "/images/logo_vertical_water.png", - 'url' => ui_get_full_url("/images/logo_vertical_water.png")); - -- return hbar_graph($config['flash_charts'], $data, $width, $height, array(), -+ return hbar_graph($config['flash_charts'], -+ $data, $width, $height, array(), - array(), "", "", true, "", - $water_mark, - $config['fontpath'], $config['font_size'], false); -@@ -2670,6 +2675,7 @@ - $max_value = 0; - - // Calculate chart data -+ $last_known = $previous_data; - for ($i = 0; $i < $resolution; $i++) { - $timestamp = $datelimit + ($interval * $i); - -@@ -2689,6 +2695,7 @@ - $count++; - } - -+ $last_known = $data[$j]['datos']; - $j++; - } - -@@ -2796,43 +2803,20 @@ - //New code set 0 if there is a 0 - //Please check the incident #665 - //http://192.168.50.2/integria/index.php?sec=incidents&sec2=operation/incidents/incident_dashboard_detail&id=665 -- -- - $chart[$timestamp]['sum'.$series_suffix] = 0; -- $previous_data = 0; -- -- //Old code that make a AVG -- -- //~ if ($avg_only) { -- //~ $chart[$timestamp]['sum'.$series_suffix] = $total; -- //~ } -- //~ else { -- //~ $chart[$timestamp]['sum'.$series_suffix] = $total; -- //~ $chart[$timestamp + 1] = array ('sum'.$series_suffix => 0, -- //~ //'count' => 0, -- //~ //'timestamp_bottom' => $timestamp, -- //~ //'timestamp_top' => $timestamp + $interval, -- //~ 'min'.$series_suffix => 0, -- //~ 'max'.$series_suffix => 0, -- //~ 'event'.$series_suffix => $event_value, -- //~ 'alert'.$series_suffix => $alert_value); -- //~ } -- //~ $previous_data = 0; - } - else if ($zero == 1) { // Just zeros - $chart[$timestamp]['sum'.$series_suffix] = 0; -- $previous_data = 0; - } - else if ($count > 0) { // No zeros - $chart[$timestamp]['sum'.$series_suffix] = $total; -- $previous_data = $total; - } - else { // Compressed data - if ($uncompressed_module || ($timestamp > time ()) || $is_unknown) { - $chart[$timestamp]['sum'.$series_suffix] = 0; - } - else { -- $chart[$timestamp]['sum'.$series_suffix] = $previous_data; -+ $chart[$timestamp]['sum'.$series_suffix] = $last_known; - } - } - -@@ -3279,7 +3263,7 @@ - * @param integer date date - */ - function grafico_modulo_string ($agent_module_id, $period, $show_events, -- $width, $height , $title, $unit_name, $show_alerts, $avg_only = 0, $pure=0, -+ $width, $height , $title, $unit_name, $show_alerts, $avg_only = 0, $pure = 0, - $date = 0, $only_image = false, $homeurl = '', $adapt_key = '', $ttl = 1, $menu = true) { - global $config; - global $graphic_type; -@@ -3381,6 +3365,7 @@ - } - - // Calculate chart data -+ $last_known = $previous_data; - for ($i = 0; $i < $resolution; $i++) { - $timestamp = $datelimit + ($interval * $i); - -@@ -3388,6 +3373,7 @@ - $total = 0; - // Read data that falls in the current interval - while (isset($data[$j]) && isset ($data[$j]) !== null && $data[$j]['utimestamp'] >= $timestamp && $data[$j]['utimestamp'] <= ($timestamp + $interval)) { -+ $last_known = $data[$j]; - $count++; - $j++; - } -@@ -3437,7 +3423,7 @@ - //The order in chart array is very important!!!! - if ($show_events) { - $chart[$timestamp]['event'] = $event_value; -- } -+ } - - if ($show_alerts) { - $chart[$timestamp]['alert'] = $alert_value; -@@ -3449,11 +3435,10 @@ - - if ($count > 0) { - $chart[$timestamp]['sum'] = $count; -- $previous_data = $total; - } - else { - // Compressed data -- $chart[$timestamp]['sum'] = $previous_data; -+ $chart[$timestamp]['sum'] = $last_known; - } - - if (!$avg_only) { -@@ -4106,47 +4091,304 @@ - /** - * Print a solarburst graph with a representation of all the groups, agents, module groups and modules grouped - */ --function graph_monitor_wheel ($data, $unit, $width = 700, $height = 700) { -+function graph_monitor_wheel ($width = 500, $height = 600) { - global $config; - -- $data = array(); -- - include_once ($config['homedir'] . "/include/functions_users.php"); -- //include_once ($config['homedir'] . "/include/functions_groups.php"); -+ include_once ($config['homedir'] . "/include/functions_groups.php"); - include_once ($config['homedir'] . "/include/functions_agents.php"); -- //include_once ($config['homedir'] . "/include/functions_modules.php"); -+ include_once ($config['homedir'] . "/include/functions_modules.php"); - -+ $graph_data = array(); -+ - $groups = users_get_groups(false, "AR", false, true); - -+ $data_groups = array(); - if (!empty($groups)) { -+ $groups_aux = $groups; -+ $data_groups = groups_get_tree($groups_aux); -+ $groups_aux = $groups = null; -+ } -+ -+ if (!empty($data_groups)) { - $filter = array('id_grupo' => array_keys($groups)); - $fields = array('id_agente', 'id_parent', 'id_grupo', 'nombre'); - $agents = agents_get_agents($filter, $fields); - - if (!empty($agents)) { - $agents_id = array(); -+ $agents_aux = array(); - foreach ($agents as $key => $agent) { -- $agents_id[] = $agent['id_agente']; -+ $agents_aux[$agent['id_agente']] = $agent; - } -+ $agents = $agents_aux; -+ $agents_aux = null; - $fields = array('id_agente_modulo', 'id_agente', 'id_module_group', 'nombre'); - - $module_groups = modules_get_modulegroups(); -- $modules = agents_get_modules($agents_id, $fields); -+ $module_groups[0] = __('Not assigned'); -+ $modules = agents_get_modules(array_keys($agents), '*'); - -+ $data_agents = array(); - if (!empty($modules)) { -- -+ foreach ($modules as $key => $module) { -+ $module_id = (int) $module['id_agente_modulo']; -+ $agent_id = (int) $module['id_agente']; -+ $module_group_id = (int) $module['id_module_group']; -+ $module_name = $module['nombre']; -+ $module_status = modules_get_agentmodule_status($module_id); -+ -+ if (!isset($data_agents[$agent_id])) { -+ $data_agents[$agent_id] = array(); -+ $data_agents[$agent_id]['id'] = $agent_id; -+ $data_agents[$agent_id]['name'] = $agents[$agent_id]['nombre']; -+ $data_agents[$agent_id]['group'] = (int) $agents[$agent_id]['id_grupo']; -+ $data_agents[$agent_id]['type'] = 'agent'; -+ $data_agents[$agent_id]['size'] = 30; -+ $data_agents[$agent_id]['children'] = array(); -+ -+ $tooltip_content = __('Agent') . ": " . $data_agents[$agent_id]['name'] . ""; -+ $data_agents[$agent_id]['tooltip_content'] = $tooltip_content; -+ -+ $data_agents[$agent_id]['modules_critical'] = 0; -+ $data_agents[$agent_id]['modules_warning'] = 0; -+ $data_agents[$agent_id]['modules_normal'] = 0; -+ $data_agents[$agent_id]['modules_not_init'] = 0; -+ $data_agents[$agent_id]['modules_not_normal'] = 0; -+ $data_agents[$agent_id]['modules_unknown'] = 0; -+ -+ $data_agents[$agent_id]['color'] = COL_UNKNOWN; -+ -+ unset($agents[$agent_id]); -+ } -+ if (!isset($data_agents[$agent_id]['children'][$module_group_id])) { -+ $data_agents[$agent_id]['children'][$module_group_id] = array(); -+ $data_agents[$agent_id]['children'][$module_group_id]['id'] = $module_group_id; -+ $data_agents[$agent_id]['children'][$module_group_id]['name'] = $module_groups[$module_group_id]; -+ $data_agents[$agent_id]['children'][$module_group_id]['type'] = 'module_group'; -+ $data_agents[$agent_id]['children'][$module_group_id]['size'] = 10; -+ $data_agents[$agent_id]['children'][$module_group_id]['children'] = array(); -+ -+ $tooltip_content = __('Module group') . ": " . $module_groups[$module_group_id] . ""; -+ $data_agents[$agent_id]['children'][$module_group_id]['tooltip_content'] = $tooltip_content; -+ -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_critical'] = 0; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_warning'] = 0; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_normal'] = 0; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_not_init'] = 0; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_not_normal'] = 0; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_unknown'] = 0; -+ -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_UNKNOWN; -+ } -+ -+ switch ($module_status) { -+ case AGENT_MODULE_STATUS_CRITICAL_BAD: -+ case AGENT_MODULE_STATUS_CRITICAL_ALERT: -+ $data_agents[$agent_id]['modules_critical']++; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_critical']++; -+ break; -+ -+ case AGENT_MODULE_STATUS_WARNING: -+ case AGENT_MODULE_STATUS_WARNING_ALERT: -+ $data_agents[$agent_id]['modules_warning']++; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_warning']++; -+ break; -+ -+ case AGENT_MODULE_STATUS_NORMAL: -+ case AGENT_MODULE_STATUS_NORMAL_ALERT: -+ $data_agents[$agent_id]['modules_normal']++; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_normal']++; -+ break; -+ -+ case AGENT_MODULE_STATUS_NOT_INIT: -+ $data_agents[$agent_id]['modules_not_init']++; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_not_init']++; -+ break; -+ -+ case AGENT_MODULE_STATUS_NOT_NORMAL: -+ $data_agents[$agent_id]['modules_not_normal']++; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_not_normal']++; -+ break; -+ -+ case AGENT_MODULE_STATUS_NO_DATA: -+ case AGENT_MODULE_STATUS_UNKNOWN: -+ $data_agents[$agent_id]['modules_unknown']++; -+ $data_agents[$agent_id]['children'][$module_group_id]['modules_unknown']++; -+ break; -+ } -+ -+ if ($data_agents[$agent_id]['modules_critical'] > 0) { -+ $data_agents[$agent_id]['color'] = COL_CRITICAL; -+ } -+ else if ($data_agents[$agent_id]['modules_warning'] > 0) { -+ $data_agents[$agent_id]['color'] = COL_WARNING; -+ } -+ else if ($data_agents[$agent_id]['modules_not_normal'] > 0) { -+ $data_agents[$agent_id]['color'] = COL_WARNING; -+ } -+ else if ($data_agents[$agent_id]['modules_unknown'] > 0) { -+ $data_agents[$agent_id]['color'] = COL_UNKNOWN; -+ } -+ else if ($data_agents[$agent_id]['modules_normal'] > 0) { -+ $data_agents[$agent_id]['color'] = COL_NORMAL; -+ } -+ else { -+ $data_agents[$agent_id]['color'] = COL_NOTINIT; -+ } -+ -+ if ($data_agents[$agent_id]['children'][$module_group_id]['modules_critical'] > 0) { -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_CRITICAL; -+ } -+ else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_warning'] > 0) { -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_WARNING; -+ } -+ else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_not_normal'] > 0) { -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_WARNING; -+ } -+ else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_unknown'] > 0) { -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_UNKNOWN; -+ } -+ else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_normal'] > 0) { -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_NORMAL; -+ } -+ else { -+ $data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_NOTINIT; -+ } -+ -+ $data_module = array(); -+ $data_module['id'] = $module_id; -+ $data_module['name'] = $module_name; -+ $data_module['type'] = 'module'; -+ $data_module['size'] = 10; -+ -+ $tooltip_content = __('Module') . ": " . $module_name . ""; -+ $data_module['tooltip_content'] = $tooltip_content; -+ -+ switch ($module_status) { -+ case AGENT_MODULE_STATUS_CRITICAL_BAD: -+ case AGENT_MODULE_STATUS_CRITICAL_ALERT: -+ $data_module['color'] = COL_CRITICAL; -+ break; -+ -+ case AGENT_MODULE_STATUS_WARNING: -+ case AGENT_MODULE_STATUS_WARNING_ALERT: -+ $data_module['color'] = COL_WARNING; -+ break; -+ -+ case AGENT_MODULE_STATUS_NORMAL: -+ case AGENT_MODULE_STATUS_NORMAL_ALERT: -+ $data_module['color'] = COL_NORMAL; -+ break; -+ -+ case AGENT_MODULE_STATUS_NOT_INIT: -+ $data_module['color'] = COL_NOTINIT; -+ break; -+ -+ case AGENT_MODULE_STATUS_NOT_NORMAL: -+ $data_module['color'] = COL_WARNING; -+ break; -+ -+ case AGENT_MODULE_STATUS_NO_DATA: -+ case AGENT_MODULE_STATUS_UNKNOWN: -+ default: -+ $data_module['color'] = COL_UNKNOWN; -+ break; -+ } -+ -+ $data_agents[$agent_id]['children'][$module_group_id]['children'][] = $data_module; -+ -+ unset($modules[$module_id]); -+ } - } -+ foreach ($agents as $id => $agent) { -+ if (!isset($data_agents[$id])) { -+ $data_agents[$id] = array(); -+ $data_agents[$id]['id'] = (int) $id; -+ $data_agents[$id]['name'] = $agent['nombre']; -+ $data_agents[$id]['type'] = 'agent'; -+ $data_agents[$id]['color'] = COL_NOTINIT; -+ } -+ } -+ $agents = null; - } - } - -+ function iterate_group_array ($groups, &$data_agents) { -+ -+ $data = array(); - -- if (empty ($data)) { -- return fs_error_image (); -+ foreach ($groups as $id => $group) { -+ -+ $group_aux = array(); -+ $group_aux['id'] = (int) $id; -+ $group_aux['name'] = $group['nombre']; -+ $group_aux['parent'] = (int) $group['parent']; -+ $group_aux['type'] = 'group'; -+ $group_aux['size'] = 100; -+ $group_aux['status'] = groups_get_status($id); -+ -+ switch ($group_aux['status']) { -+ case AGENT_STATUS_CRITICAL: -+ $group_aux['color'] = COL_CRITICAL; -+ break; -+ -+ case AGENT_STATUS_WARNING: -+ case AGENT_STATUS_ALERT_FIRED: -+ $group_aux['color'] = COL_WARNING; -+ break; -+ -+ case AGENT_STATUS_NORMAL: -+ $group_aux['color'] = COL_NORMAL; -+ break; -+ -+ case AGENT_STATUS_UNKNOWN: -+ default: -+ $group_aux['color'] = COL_UNKNOWN; -+ break; -+ } -+ -+ $tooltip_content = html_print_image("images/groups_small/" . $group['icon'] . ".png", true) . " " . __('Group') . ": " . $group_aux['name'] . ""; -+ $group_aux['tooltip_content'] = $tooltip_content; -+ -+ if (!isset($group['children'])) -+ $group_aux['children'] = array(); -+ if (!empty($group['children'])) -+ $group_aux['children'] = iterate_group_array($group['children']); -+ -+ $agents = extract_agents_with_group_id($data_agents, (int) $id); -+ -+ if (!empty($agents)) -+ $group_aux['children'] = array_merge($group_aux['children'], $agents); -+ -+ $data[] = $group_aux; -+ } -+ -+ return $data; - } - -+ function extract_agents_with_group_id (&$agents, $group_id) { -+ $valid_agents = array(); -+ foreach ($agents as $id => $agent) { -+ if (isset($agent['group']) && $agent['group'] == $group_id) { -+ $valid_agents[$id] = $agent; -+ unset($agents[$id]); -+ } -+ } -+ if (!empty($valid_agents)) -+ return $valid_agents; -+ else -+ return false; -+ } -+ -+ $graph_data = array('name' => __('Main node'), 'children' => iterate_group_array($data_groups, $data_agents)); -+ -+ if (empty($graph_data['children'])) -+ return fs_error_image(); -+ - include_once($config['homedir'] . "/include/graphs/functions_d3.php"); - -- return d3_tree_map_graph ($data, $width, $height, true); -+ return d3_sunburst_graph ($graph_data, $width, $height, true); - } - - ?> -Index: include/functions_events.php -=================================================================== ---- include/functions_events.php (revision 10314) -+++ include/functions_events.php (working copy) -@@ -162,7 +162,16 @@ - (SELECT ack_utimestamp FROM $table WHERE id_evento = MAX(te.id_evento)) AS ack_utimestamp - FROM $table te - WHERE 1=1 " . $sql_post . " -- GROUP BY estado, evento, id_agentmodule, id_evento, id_agente, id_usuario, id_grupo, estado, timestamp, utimestamp, event_type, id_alert_am, criticity, user_comment, tags, source, id_extra" . $groupby_extra . " -+ GROUP BY estado, evento, id_agentmodule, id_evento, -+ id_agente, id_usuario, id_grupo, estado, -+ timestamp, utimestamp, event_type, id_alert_am, -+ criticity, user_comment, tags, source, id_extra, -+ te.critical_instructions, -+ te.warning_instructions, -+ te.unknown_instructions, -+ te.owner_user, -+ te.ack_utimestamp, -+ te.custom_data " . $groupby_extra . " - ORDER BY timestamp_rep DESC LIMIT " . $pagination . " OFFSET " . $offset; - } - break; -@@ -582,7 +591,7 @@ - - $event_comments_array[] = $comment_for_json; - -- $event_comments = json_encode($event_comments_array); -+ $event_comments = io_json_mb_encode($event_comments_array); - - // Update comment - $ret = db_process_sql_update($event_table, array('user_comment' => $event_comments), array('id_evento' => implode(',', $id_event))); -@@ -2244,6 +2253,7 @@ - $table_comments->class = "alternate rounded_cells"; - - $event_comments = io_safe_output($event["user_comment"]); -+ $event_comments = str_replace("\n", "
", $event_comments); - - // If comments are not stored in json, the format is old - $event_comments_array = json_decode($event_comments, true); -Index: include/graphs/functions_flot.php -=================================================================== ---- include/graphs/functions_flot.php (revision 10314) -+++ include/graphs/functions_flot.php (working copy) -@@ -442,6 +442,7 @@ - - $max = 0; - $i = count($graph_data); -+ $data = array(); - foreach ($graph_data as $label => $values) { - $labels[] = io_safe_output($label); - $i--; -Index: include/graphs/pandora.d3.js -=================================================================== ---- include/graphs/pandora.d3.js (revision 10314) -+++ include/graphs/pandora.d3.js (working copy) -@@ -715,8 +715,11 @@ - .data(partition.nodes(data)) - .enter().append("path") - .attr("d", arc) -- .style("fill", function(d) { return color((d.children ? d : d.parent).name); }) -- .on("click", click); -+ .style("fill", function(d) { return d.color ? d3.rgb(d.color) : color((d.children ? d : d.parent).name); }) -+ .on("click", click) -+ .on("mouseover", over_user) -+ .on("mouseout", out_user) -+ .on("mousemove", move_tooltip); - - function click(d) { - path.transition() -@@ -737,4 +740,68 @@ - : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); }; - }; - } -+ -+ function move_tooltip(d) { -+ var x = d3.event.pageX + 10; -+ var y = d3.event.pageY + 10; -+ -+ $("#tooltip").css('left', x + 'px'); -+ $("#tooltip").css('top', y + 'px'); -+ } -+ -+ function over_user(d) { -+ id = d.id; -+ -+ $("#" + id).css('border', '1px solid black'); -+ $("#" + id).css('z-index', '1'); -+ -+ show_tooltip(d); -+ } -+ -+ function out_user(d) { -+ id = d.id; -+ -+ $("#" + id).css('border', ''); -+ $("#" + id).css('z-index', ''); -+ -+ hide_tooltip(); -+ } -+ -+ function create_tooltip(d, x, y) { -+ var tooltip = (typeof d.tooltip_content != 'undefined') ? d.tooltip_content : d.name; -+ -+ if ($("#tooltip").length == 0) { -+ $(recipient) -+ .append($("
") -+ .attr('id', 'tooltip') -+ .html(tooltip)); -+ } -+ else { -+ $("#tooltip").html(tooltip); -+ } -+ -+ $("#tooltip").attr('style', 'background: #fff;' + -+ 'position: absolute;' + -+ 'display: block;' + -+ 'width: 200px;' + -+ 'text-align: left;' + -+ 'padding: 10px 10px 10px 10px;' + -+ 'z-index: 2;' + -+ "-webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);" + -+ "-moz-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);" + -+ "box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);" + -+ 'left: ' + x + 'px;' + -+ 'top: ' + y + 'px;'); -+ } -+ -+ function show_tooltip(d) { -+ var x = d3.event.pageX + 10; -+ var y = d3.event.pageY + 10; -+ -+ create_tooltip(d, x, y); -+ } -+ -+ function hide_tooltip() { -+ $("#tooltip").hide(); -+ } - } -\ No newline at end of file -Index: include/graphs/fgraph.php -=================================================================== ---- include/graphs/fgraph.php (revision 10314) -+++ include/graphs/fgraph.php (working copy) -@@ -398,11 +398,13 @@ - setup_watermark($water_mark, $water_mark_file, $water_mark_url); - - if ($flash_chart) { -- if ($return){ -- return flot_hcolumn_chart ($chart_data, $width, $height, $water_mark_url); -+ if ($return) { -+ return flot_hcolumn_chart( -+ $chart_data, $width, $height, $water_mark_url); - } -- else{ -- echo flot_hcolumn_chart ($chart_data, $width, $height, $water_mark_url); -+ else { -+ echo flot_hcolumn_chart( -+ $chart_data, $width, $height, $water_mark_url); - } - } - else { -@@ -422,7 +424,7 @@ - - $id_graph = serialize_in_temp($graph, null, $ttl); - -- return ""; -+ return ""; - } - } - -Index: include/db/postgresql.php -=================================================================== ---- include/db/postgresql.php (revision 10314) -+++ include/db/postgresql.php (working copy) -@@ -332,6 +332,9 @@ - else if (is_float ($value) || is_double ($value)) { - $values_str .= sprintf("%f", $value); - } -+ elseif (is_string($value) && (strtoupper($value) === 'NULL')) { -+ $values_str .= "NULL"; -+ } - else { - $values_str .= sprintf("'%s'", $value); - } -@@ -346,6 +349,8 @@ - - $query .= ' VALUES (' . $values_str . ')'; - -+ //html_debug_print($query); -+ - return db_process_sql($query, 'insert_id'); - } - -@@ -362,6 +367,18 @@ - return $str; - } - -+function postgresql_encapsule_fields_with_same_name_to_instructions($field) { -+ $return = $field; -+ -+ if (is_string($return)) { -+ if ($return[0] !== '"') { -+ $return = '"' . $return . '"'; -+ } -+ } -+ -+ return $return; -+} -+ - /** - * Get the first value of the first row of a table in the database from an - * array with filter conditions. -Index: include/db/mysql.php -=================================================================== ---- include/db/mysql.php (revision 10314) -+++ include/db/mysql.php (working copy) -@@ -346,6 +346,18 @@ - return $str; - } - -+function mysql_encapsule_fields_with_same_name_to_instructions($field) { -+ $return = $field; -+ -+ if (is_string($return)) { -+ if ($return[0] !== '`') { -+ $return = '`' . $return . '`'; -+ } -+ } -+ -+ return $return; -+} -+ - /** - * Get the first value of the first row of a table in the database from an - * array with filter conditions. -Index: include/db/oracle.php -=================================================================== ---- include/db/oracle.php (revision 10314) -+++ include/db/oracle.php (working copy) -@@ -254,7 +254,7 @@ - else if ($type[0] == '/INSERT'){ - $query = oci_parse($config['dbconnection'], substr($sql,1)); - } -- else{ -+ else { - $query = oci_parse($config['dbconnection'], $sql); - } - } -@@ -448,6 +448,18 @@ - return str_replace(array('"', "'", '\\'), array('\\"', '\\\'', '\\\\'), $string); - } - -+function oracle_encapsule_fields_with_same_name_to_instructions($field) { -+ $return = $field; -+ -+ if (is_string($return)) { -+ if ($return[0] !== '"') { -+ $return = '"' . $return . '"'; -+ } -+ } -+ -+ return $return; -+} -+ - /** - * Get the first value of the first row of a table in the database from an - * array with filter conditions. -@@ -649,7 +661,7 @@ - else if ($value[0] == '%') { - $query .= sprintf ("%s LIKE '%s'", $field, $value); - } -- else{ -+ else { - $query .= sprintf ("%s = '%s'", $field, $value); - } - } -@@ -997,16 +1009,16 @@ - global $config; - - $type = explode(' ',strtoupper(trim($sql))); -- if ($type[0] == 'SELECT'){ -+ if ($type[0] == 'SELECT') { - $sql = "SELECT count(*) as NUM FROM (" . $sql . ")"; - } - $query = oci_parse($config['dbconnection'], $sql); - oci_execute($query); -- if ($type[0] == 'SELECT'){ -+ if ($type[0] == 'SELECT') { - $row = oci_fetch_assoc($query); - $rows = $row['NUM']; - } -- else{ -+ else { - $rows = oci_num_rows($query); - } - -@@ -1027,13 +1039,19 @@ - */ - function oracle_db_get_all_rows_field_filter ($table, $field, $condition, $order_field = "") { - if (is_int ($condition) || is_bool ($condition)) { -- $sql = sprintf ("SELECT * FROM %s WHERE %s = %d", $table, $field, $condition); -+ $sql = sprintf ("SELECT * -+ FROM %s -+ WHERE %s = %d", $table, $field, $condition); - } - else if (is_float ($condition) || is_double ($condition)) { -- $sql = sprintf ("SELECT * FROM %s WHERE %s = %f", $table, $field, $condition); -+ $sql = sprintf ("SELECT * -+ FROM %s -+ WHERE %s = %f", $table, $field, $condition); - } - else { -- $sql = sprintf ("SELECT * FROM %s WHERE %s = '%s'", $table, $field, $condition); -+ $sql = sprintf ("SELECT * -+ FROM %s -+ WHERE %s = '%s'", $table, $field, $condition); - } - - if ($order_field != "") -Index: include/functions_modules.php -=================================================================== ---- include/functions_modules.php (revision 10314) -+++ include/functions_modules.php (working copy) -@@ -1663,15 +1663,15 @@ - $status = STATUS_AGENT_DOWN; - $last_status = modules_get_agentmodule_last_status($id_agent_module); - switch($last_status) { -- case 0: -+ case AGENT_STATUS_NORMAL: - $title = __('UNKNOWN') . " - " . __('Last status') . - " " . __('NORMAL'); - break; -- case 1: -+ case AGENT_STATUS_CRITICAL: - $title = __('UNKNOWN') . " - " . __('Last status') . - " " . __('CRITICAL'); - break; -- case 2: -+ case AGENT_STATUS_WARNING: - $title = __('UNKNOWN') . " - " . __('Last status') . - " " . __('WARNING'); - break; -Index: include/functions_reporting.php -=================================================================== ---- include/functions_reporting.php (revision 10314) -+++ include/functions_reporting.php (working copy) -@@ -907,6 +907,8 @@ - } - - function reporting_get_stats_servers($tiny = true) { -+ global $config; -+ - $server_performance = servers_get_performance(); - - // Alerts table -@@ -959,7 +961,9 @@ - $tdata[0] = html_print_image('images/network.png', true, array('title' => __('Network modules'), 'width' => '25px')); - $tdata[1] = '' . format_numeric($server_performance ["total_network_modules"]) . ''; - -- $tdata[2] = '' . format_numeric($server_performance ["network_modules_rate"], 2) . ''; -+ $tdata[2] = '' . -+ format_numeric($server_performance ["network_modules_rate"], 2) . -+ ''; - $tdata[3] = html_print_image('images/module.png', true, array('title' => __('Ratio') . ': ' . __('Modules by second'), 'width' => '16px')) . '/sec '; - - $table_srv->rowclass[] = ''; -@@ -1020,8 +1024,23 @@ - $table_srv->rowclass[] = ''; - $table_srv->data[] = $tdata; - -- $system_events = db_get_value_sql('SELECT SQL_NO_CACHE COUNT(id_evento) FROM tevento'); -- -+ -+ switch ($config["dbtype"]) { -+ case "mysql": -+ $system_events = db_get_value_sql( -+ 'SELECT SQL_NO_CACHE COUNT(id_evento) -+ FROM tevento'); -+ break; -+ case "postgresql": -+ case "oracle": -+ $system_events = db_get_value_sql( -+ 'SELECT COUNT(id_evento) -+ FROM tevento'); -+ break; -+ } -+ -+ -+ - $tdata = array(); - $tdata[0] = html_print_image('images/lightning_go.png', true, array('title' => __('Total events'), 'width' => '25px')); - $tdata[1] = '' . format_numeric($system_events) . ''; -@@ -1109,16 +1128,21 @@ - $tdata = array(); - $table_mbs->colspan[count($table_mbs->data)][0] = 4; - $table_mbs->cellstyle[count($table_mbs->data)][0] = 'text-align: center;'; -- $tdata[0] = '
' . graph_agent_status (false, $graph_width, $graph_height, true, true) . '
'; -+ $tdata[0] = '
' . -+ '
' . -+ graph_agent_status(false, $graph_width, $graph_height, true, true) . -+ '
'; - $table_mbs->rowclass[] = ''; - $table_mbs->data[] = $tdata; - } - -- $output = '
-- ' . -- __('Monitors by status') . -- '' . -- html_print_table($table_mbs, true) . '
'; -+ $output = ' -+
-+ ' . -+ __('Monitors by status') . -+ '' . -+ html_print_table($table_mbs, true) . -+ '
'; - - return $output; - } -@@ -3123,9 +3147,29 @@ - } - else { - -- $data[0] = grafico_modulo_sparse($content['id_agent_module'], $content['period'], -- false, $sizgraph_w, $sizgraph_h, '', '', false, true, true, -- $report["datetime"], '', 0, 0, true, true, ui_get_full_url(false) . '/'); -+ $data[0] = grafico_modulo_sparse( -+ $content['id_agent_module'], -+ $content['period'], -+ false, -+ $sizgraph_w, -+ $sizgraph_h, -+ '', -+ '', -+ false, -+ true, -+ true, -+ $report["datetime"], -+ '', -+ 0, -+ 0, -+ true, -+ true, -+ ui_get_full_url(false) . '/', -+ 1, -+ false, -+ '', -+ false, -+ true); - } - - array_push ($table->data, $data); -Index: include/auth/ldap.php -=================================================================== ---- include/auth/ldap.php (revision 10314) -+++ include/auth/ldap.php (working copy) -@@ -65,8 +65,11 @@ - $config["admin_can_make_admin"] = false; - - //Required and optional keys for this function to work --$req_keys = array ("ldap_server", "ldap_base_dn", "ldap_login_attr", "ldap_admin_group_name", "ldap_admin_group_attr", "ldap_admin_group_type", "ldap_user_filter", "ldap_user_attr"); --$opt_keys = array ("ldap_port", "ldap_start_tls", "ldap_version", "ldap_admin_dn", "ldap_admin_pwd"); -+$req_keys = array("ldap_server", "ldap_base_dn", "ldap_login_attr", -+ "ldap_admin_group_name", "ldap_admin_group_attr", -+ "ldap_admin_group_type", "ldap_user_filter", "ldap_user_attr"); -+$opt_keys = array("ldap_port", "ldap_start_tls", "ldap_version", -+ "ldap_admin_dn", "ldap_admin_pwd"); - - global $ldap_cache; //Needs to be globalized because config_process_config () function calls this file first and the variable would be local and subsequently lost - $ldap_cache = array (); -@@ -76,13 +79,15 @@ - //Put each required key in a variable. - foreach ($req_keys as $key) { - if (!isset ($config["auth"][$key])) { -- user_error ("Required key ".$key." not set", E_USER_ERROR); -+ user_error("Required key " . $key . " not set", E_USER_ERROR); - } - } - - // Convert group name to lower case to prevent problems --$config["auth"]["ldap_admin_group_attr"] = strtolower ($config["auth"]["ldap_admin_group_attr"]); --$config["auth"]["ldap_admin_group_type"] = strtolower ($config["auth"]["ldap_admin_group_type"]); -+$config["auth"]["ldap_admin_group_attr"] = -+ strtolower ($config["auth"]["ldap_admin_group_attr"]); -+$config["auth"]["ldap_admin_group_type"] = -+ strtolower ($config["auth"]["ldap_admin_group_type"]); - - foreach ($opt_keys as $key) { - if (!isset ($config["auth"][$key])) { -@@ -122,7 +127,7 @@ - return false; - } - global $config; -- -+ - $profile = db_get_value ("id_usuario", "tusuario_perfil", "id_usuario", $login); - - if ($profile === false && empty ($config["auth"]["create_user_undefined"])) { -@@ -311,7 +316,8 @@ - - $nick = false; - if (ldap_connect_bind ()) { -- $sr = @ldap_search ($ldap_cache["ds"], $config["auth"]["ldap_base_dn"], "(&(".$config["auth"]["ldap_login_attr"]."=".$login.")".$config["auth"]["ldap_user_filter"].")", array_values ($config["auth"]["ldap_user_attr"])); -+ $sr = @ldap_search ($ldap_cache["ds"], -+ io_safe_output($config["auth"]["ldap_base_dn"]), "(&(".io_safe_output($config["auth"]["ldap_login_attr"])."=".$login.")".io_safe_output($config["auth"]["ldap_user_filter"]).")", array_values ($config["auth"]["ldap_user_attr"])); - - if (!$sr) { - $ldap_cache["error"] .= 'Error searching LDAP server: ' . ldap_error ($ldap_cache["ds"]); -@@ -364,7 +370,7 @@ - return $ret; - } - -- $r = @ldap_bind ($ds, $config["auth"]["ldap_login_attr"]."=".$login.",".$config["auth"]["ldap_base_dn"], $password); -+ $r = @ldap_bind ($ds, io_safe_output($config["auth"]["ldap_login_attr"])."=".$login.",".io_safe_output($config["auth"]["ldap_base_dn"]), $password); - if (!$r) { - $ldap_cache["error"] .= 'Invalid login'; - } -@@ -393,7 +399,8 @@ - $time = get_system_time (); - if (ldap_connect_bind ()) { - -- $sr = ldap_search ($ldap_cache["ds"], $config["auth"]["ldap_base_dn"], "(&(".$config["auth"]["ldap_login_attr"]."=".$login.")".$config["auth"]["ldap_user_filter"].")", array_values ($config["auth"]["ldap_user_attr"])); -+ $sr = ldap_search ($ldap_cache["ds"], -+ io_safe_output($config["auth"]["ldap_base_dn"]), "(&(".io_safe_output($config["auth"]["ldap_login_attr"])."=".$login.")".io_safe_output($config["auth"]["ldap_user_filter"]).")", array_values ($config["auth"]["ldap_user_attr"])); - - if (!$sr) { - $ldap_cache["error"] .= 'Error searching LDAP server (load_user): ' . ldap_error( $ldap_cache["ds"] ); -@@ -497,7 +504,7 @@ - $time = get_system_time (); - - if (ldap_connect_bind ()) { -- $sr = @ldap_search ($ldap_cache["ds"], $config["auth"]["ldap_base_dn"], $config["auth"]["ldap_user_filter"], array_values ($config["auth"]["ldap_user_attr"])); -+ $sr = @ldap_search ($ldap_cache["ds"], io_safe_output($config["auth"]["ldap_base_dn"]), io_safe_output($config["auth"]["ldap_user_filter"]), array_values ($config["auth"]["ldap_user_attr"])); - if (!$sr) { - $ldap_cache["error"] .= 'Error searching LDAP server (get_users): ' . ldap_error( $ldap_cache["ds"] ); - } -Index: include/auth/mysql.php -=================================================================== ---- include/auth/mysql.php (revision 10314) -+++ include/auth/mysql.php (working copy) -@@ -512,7 +512,11 @@ - } - } - -- if (strlen($password) == 0 || !@ldap_bind ($ds, $config["ldap_login_attr"]."=".$login.",".$config["ldap_base_dn"], $password)) { -+ if (strlen($password) == 0 || -+ !@ldap_bind($ds, -+ io_safe_output($config["ldap_login_attr"]) . "=" . $login . "," . io_safe_output($config["ldap_base_dn"]), -+ $password)) { -+ - $config["auth_error"] = 'User not found in database or incorrect password'; - @ldap_close ($ds); - -Index: include/functions_networkmap.php -=================================================================== ---- include/functions_networkmap.php (revision 10314) -+++ include/functions_networkmap.php (working copy) -@@ -233,7 +233,8 @@ - $simple = 0, $font_size = 12, $layout = 'radial', $nooverlap = 0, - $zoom = 1, $ranksep = 2.5, $center = 0, $regen = 1, $pure = 0, - $id_networkmap = 0, $show_snmp_modules = 0, $cut_names = true, -- $relative = false, $text_filter = '', $l2_network = false, $ip_mask = null) { -+ $relative = false, $text_filter = '', $l2_network = false, $ip_mask = null, -+ $dont_show_subgroups = false) { - - global $config; - -@@ -262,7 +263,20 @@ - } - - if ($group >= 1) { -- $filter['id_grupo'] = $group; -+ if ($dont_show_subgroups) -+ $filter['id_grupo'] = $group; -+ else { -+ $childrens = groups_get_childrens($group, null, true); -+ if (!empty($childrens)) { -+ $childrens = array_keys($childrens); -+ -+ $filter['id_grupo'] = $childrens; -+ $filter['id_grupo'][] = $group; -+ } -+ else { -+ $filter['id_grupo'] = $group; -+ } -+ } - - //Order by id_parent ascendant for to avoid the bugs - //because the first agents to process in the next -@@ -589,7 +603,13 @@ - } - - // Generate a dot graph definition for graphviz with groups --function networkmap_generate_dot_groups ($pandora_name, $group = 0, $simple = 0, $font_size = 12, $layout = 'radial', $nooverlap = 0, $zoom = 1, $ranksep = 2.5, $center = 0, $regen = 1, $pure = 0, $modwithalerts = 0, $module_group = 0, $hidepolicymodules = 0, $depth = 'all', $id_networkmap = 0, $dont_show_subgroups = 0, $text_filter = '') { -+function networkmap_generate_dot_groups ($pandora_name, $group = 0, -+ $simple = 0, $font_size = 12, $layout = 'radial', $nooverlap = 0, -+ $zoom = 1, $ranksep = 2.5, $center = 0, $regen = 1, $pure = 0, -+ $modwithalerts = 0, $module_group = 0, $hidepolicymodules = 0, -+ $depth = 'all', $id_networkmap = 0, $dont_show_subgroups = 0, -+ $text_filter = '') { -+ - global $config; - - $parents = array(); -@@ -682,7 +702,8 @@ - // Get agents data - $agents = agents_get_agents ($filter, - array ('id_grupo, nombre, id_os, id_agente, -- normal_count, warning_count, critical_count, unknown_count, total_count, notinit_count')); -+ normal_count, warning_count, critical_count, -+ unknown_count, total_count, notinit_count')); - - if ($agents === false) - $agents = array(); -@@ -1427,7 +1448,9 @@ - $values['show_groups'] = $show_groups; - $values['show_modules'] = $show_modules; - -- return @db_process_sql_insert ('tnetwork_map', $values); -+ $values['server_name'] = ""; -+ -+ return @db_process_sql_insert('tnetwork_map', $values); - } - - /** -Index: include/javascript/introjs.css -=================================================================== ---- include/javascript/introjs.css (revision 0) -+++ include/javascript/introjs.css (revision 10417) -@@ -0,0 +1,276 @@ -+.introjs-overlay { -+ position: absolute; -+ z-index: 999999; -+ background-color: #000; -+ opacity: 0; -+ background: -moz-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%); -+ background: -webkit-gradient(radial,center center,0px,center center,100%,color-stop(0%,rgba(0,0,0,0.4)),color-stop(100%,rgba(0,0,0,0.9))); -+ background: -webkit-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%); -+ background: -o-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%); -+ background: -ms-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%); -+ background: radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%); -+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#66000000',endColorstr='#e6000000',GradientType=1); -+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; -+ filter: alpha(opacity=50); -+ -webkit-transition: all 0.3s ease-out; -+ -moz-transition: all 0.3s ease-out; -+ -ms-transition: all 0.3s ease-out; -+ -o-transition: all 0.3s ease-out; -+ transition: all 0.3s ease-out; -+} -+ -+.introjs-fixParent { -+ z-index: auto !important; -+ opacity: 1.0 !important; -+} -+ -+.introjs-showElement, -+tr.introjs-showElement > td, -+tr.introjs-showElement > th { -+ z-index: 9999999 !important; -+} -+ -+.introjs-relativePosition, -+tr.introjs-showElement > td, -+tr.introjs-showElement > th { -+ position: relative; -+} -+ -+.introjs-helperLayer { -+ position: absolute; -+ z-index: 9999998; -+ background-color: #FFF; -+ background-color: rgba(255,255,255,.9); -+ border: 1px solid #777; -+ border: 1px solid rgba(0,0,0,.5); -+ border-radius: 4px; -+ box-shadow: 0 2px 15px rgba(0,0,0,.4); -+ -webkit-transition: all 0.3s ease-out; -+ -moz-transition: all 0.3s ease-out; -+ -ms-transition: all 0.3s ease-out; -+ -o-transition: all 0.3s ease-out; -+ transition: all 0.3s ease-out; -+} -+ -+.introjs-helperNumberLayer { -+ position: absolute; -+ top: -16px; -+ left: -16px; -+ z-index: 9999999999 !important; -+ padding: 2px; -+ font-family: Arial, verdana, tahoma; -+ font-size: 13px; -+ font-weight: bold; -+ color: white; -+ text-align: center; -+ text-shadow: 1px 1px 1px rgba(0,0,0,.3); -+ background: #ff3019; /* Old browsers */ -+ background: -webkit-linear-gradient(top, #ff3019 0%, #cf0404 100%); /* Chrome10+,Safari5.1+ */ -+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ff3019), color-stop(100%, #cf0404)); /* Chrome,Safari4+ */ -+ background: -moz-linear-gradient(top, #ff3019 0%, #cf0404 100%); /* FF3.6+ */ -+ background: -ms-linear-gradient(top, #ff3019 0%, #cf0404 100%); /* IE10+ */ -+ background: -o-linear-gradient(top, #ff3019 0%, #cf0404 100%); /* Opera 11.10+ */ -+ background: linear-gradient(to bottom, #ff3019 0%, #cf0404 100%); /* W3C */ -+ width: 20px; -+ height:20px; -+ line-height: 20px; -+ border: 3px solid white; -+ border-radius: 50%; -+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3019', endColorstr='#cf0404', GradientType=0); /* IE6-9 */ -+ filter: progid:DXImageTransform.Microsoft.Shadow(direction=135, strength=2, color=ff0000); /* IE10 text shadows */ -+ box-shadow: 0 2px 5px rgba(0,0,0,.4); -+} -+ -+.introjs-arrow { -+ border: 5px solid white; -+ content:''; -+ position: absolute; -+} -+.introjs-arrow.top { -+ top: -10px; -+ border-top-color:transparent; -+ border-right-color:transparent; -+ border-bottom-color:white; -+ border-left-color:transparent; -+} -+.introjs-arrow.top-right { -+ top: -10px; -+ right: 10px; -+ border-top-color:transparent; -+ border-right-color:transparent; -+ border-bottom-color:white; -+ border-left-color:transparent; -+} -+.introjs-arrow.top-middle { -+ top: -10px; -+ left: 50%; -+ margin-left: -5px; -+ border-top-color:transparent; -+ border-right-color:transparent; -+ border-bottom-color:white; -+ border-left-color:transparent; -+} -+.introjs-arrow.right { -+ right: -10px; -+ top: 10px; -+ border-top-color:transparent; -+ border-right-color:transparent; -+ border-bottom-color:transparent; -+ border-left-color:white; -+} -+.introjs-arrow.bottom { -+ bottom: -10px; -+ border-top-color:white; -+ border-right-color:transparent; -+ border-bottom-color:transparent; -+ border-left-color:transparent; -+} -+.introjs-arrow.left { -+ left: -10px; -+ top: 10px; -+ border-top-color:transparent; -+ border-right-color:white; -+ border-bottom-color:transparent; -+ border-left-color:transparent; -+} -+ -+.introjs-tooltip { -+ position: absolute; -+ padding: 10px; -+ background-color: white; -+ min-width: 200px; -+ max-width: 300px; -+ border-radius: 3px; -+ box-shadow: 0 1px 10px rgba(0,0,0,.4); -+ -webkit-transition: opacity 0.1s ease-out; -+ -moz-transition: opacity 0.1s ease-out; -+ -ms-transition: opacity 0.1s ease-out; -+ -o-transition: opacity 0.1s ease-out; -+ transition: opacity 0.1s ease-out; -+} -+ -+.introjs-tooltipbuttons { -+ text-align: right; -+} -+ -+/* -+ Buttons style by http://nicolasgallagher.com/lab/css3-github-buttons/ -+ Changed by Afshin Mehrabani -+*/ -+.introjs-button { -+ position: relative; -+ overflow: visible; -+ display: inline-block; -+ padding: 0.3em 0.8em; -+ border: 1px solid #d4d4d4; -+ margin: 0; -+ text-decoration: none; -+ text-shadow: 1px 1px 0 #fff; -+ font: 11px/normal sans-serif; -+ color: #333; -+ white-space: nowrap; -+ cursor: pointer; -+ outline: none; -+ background-color: #ececec; -+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), to(#ececec)); -+ background-image: -moz-linear-gradient(#f4f4f4, #ececec); -+ background-image: -o-linear-gradient(#f4f4f4, #ececec); -+ background-image: linear-gradient(#f4f4f4, #ececec); -+ -webkit-background-clip: padding; -+ -moz-background-clip: padding; -+ -o-background-clip: padding-box; -+ /*background-clip: padding-box;*/ /* commented out due to Opera 11.10 bug */ -+ -webkit-border-radius: 0.2em; -+ -moz-border-radius: 0.2em; -+ border-radius: 0.2em; -+ /* IE hacks */ -+ zoom: 1; -+ *display: inline; -+ margin-top: 10px; -+} -+ -+.introjs-button:hover { -+ border-color: #bcbcbc; -+ text-decoration: none; -+ box-shadow: 0px 1px 1px #e3e3e3; -+} -+ -+.introjs-button:focus, -+.introjs-button:active { -+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ececec), to(#f4f4f4)); -+ background-image: -moz-linear-gradient(#ececec, #f4f4f4); -+ background-image: -o-linear-gradient(#ececec, #f4f4f4); -+ background-image: linear-gradient(#ececec, #f4f4f4); -+} -+ -+/* overrides extra padding on button elements in Firefox */ -+.introjs-button::-moz-focus-inner { -+ padding: 0; -+ border: 0; -+} -+ -+.introjs-skipbutton { -+ margin-right: 5px; -+ color: #7a7a7a; -+} -+ -+.introjs-prevbutton { -+ -webkit-border-radius: 0.2em 0 0 0.2em; -+ -moz-border-radius: 0.2em 0 0 0.2em; -+ border-radius: 0.2em 0 0 0.2em; -+ border-right: none; -+} -+ -+.introjs-nextbutton { -+ -webkit-border-radius: 0 0.2em 0.2em 0; -+ -moz-border-radius: 0 0.2em 0.2em 0; -+ border-radius: 0 0.2em 0.2em 0; -+} -+ -+.introjs-disabled, .introjs-disabled:hover, .introjs-disabled:focus { -+ color: #9a9a9a; -+ border-color: #d4d4d4; -+ box-shadow: none; -+ cursor: default; -+ background-color: #f4f4f4; -+ background-image: none; -+ text-decoration: none; -+} -+ -+.introjs-bullets { -+ text-align: center; -+} -+.introjs-bullets ul { -+ clear: both; -+ margin: 15px auto 0; -+ padding: 0; -+ display: inline-block; -+} -+.introjs-bullets ul li { -+ list-style: none; -+ float: left; -+ margin: 0 2px; -+} -+.introjs-bullets ul li a { -+ display: block; -+ width: 6px; -+ height: 6px; -+ background: #ccc; -+ border-radius: 10px; -+ -moz-border-radius: 10px; -+ -webkit-border-radius: 10px; -+ text-decoration: none; -+} -+.introjs-bullets ul li a:hover { -+ background: #999; -+} -+.introjs-bullets ul li a.active { -+ background: #999; -+} -+.introjsFloatingElement { -+ position: absolute; -+ height: 0; -+ width: 0; -+ left: 50%; -+ top: 50%; -+} -Index: include/javascript/intro.js -=================================================================== ---- include/javascript/intro.js (revision 0) -+++ include/javascript/intro.js (revision 10417) -@@ -0,0 +1,1049 @@ -+/** -+ * Intro.js v0.9.0 -+ * https://github.com/usablica/intro.js -+ * MIT licensed -+ * -+ * Copyright (C) 2013 usabli.ca - A weekend project by Afshin Mehrabani (@afshinmeh) -+ */ -+ -+(function (root, factory) { -+ if (typeof exports === 'object') { -+ // CommonJS -+ factory(exports); -+ } else if (typeof define === 'function' && define.amd) { -+ // AMD. Register as an anonymous module. -+ define(['exports'], factory); -+ } else { -+ // Browser globals -+ factory(root); -+ } -+} (this, function (exports) { -+ //Default config/variables -+ var VERSION = '0.9.0'; -+ -+ /** -+ * IntroJs main class -+ * -+ * @class IntroJs -+ */ -+ function IntroJs(obj) { -+ this._targetElement = obj; -+ -+ this._options = { -+ /* Next button label in tooltip box */ -+ nextLabel: 'Next →', -+ /* Previous button label in tooltip box */ -+ prevLabel: '← Back', -+ /* Skip button label in tooltip box */ -+ skipLabel: 'Skip', -+ /* Done button label in tooltip box */ -+ doneLabel: 'Done', -+ /* Default tooltip box position */ -+ tooltipPosition: 'bottom', -+ /* Next CSS class for tooltip boxes */ -+ tooltipClass: '', -+ /* Close introduction when pressing Escape button? */ -+ exitOnEsc: true, -+ /* Close introduction when clicking on overlay layer? */ -+ exitOnOverlayClick: true, -+ /* Show step numbers in introduction? */ -+ showStepNumbers: true, -+ /* Let user use keyboard to navigate the tour? */ -+ keyboardNavigation: true, -+ /* Show tour control buttons? */ -+ showButtons: true, -+ /* Show tour bullets? */ -+ showBullets: true, -+ /* Scroll to highlighted element? */ -+ scrollToElement: true, -+ /* Set the overlay opacity */ -+ overlayOpacity: 0.8 -+ }; -+ } -+ -+ /** -+ * Initiate a new introduction/guide from an element in the page -+ * -+ * @api private -+ * @method _introForElement -+ * @param {Object} targetElm -+ * @returns {Boolean} Success or not? -+ */ -+ function _introForElement(targetElm) { -+ var introItems = [], -+ self = this; -+ -+ if (this._options.steps) { -+ //use steps passed programmatically -+ var allIntroSteps = []; -+ -+ for (var i = 0, stepsLength = this._options.steps.length; i < stepsLength; i++) { -+ var currentItem = _cloneObject(this._options.steps[i]); -+ //set the step -+ currentItem.step = introItems.length + 1; -+ //use querySelector function only when developer used CSS selector -+ if (typeof(currentItem.element) === 'string') { -+ //grab the element with given selector from the page -+ currentItem.element = document.querySelector(currentItem.element); -+ } -+ -+ //intro without element -+ if (typeof(currentItem.element) === 'undefined' || currentItem.element == null) { -+ var floatingElementQuery = document.querySelector(".introjsFloatingElement"); -+ -+ if (floatingElementQuery == null) { -+ floatingElementQuery = document.createElement('div'); -+ floatingElementQuery.className = 'introjsFloatingElement'; -+ -+ document.body.appendChild(floatingElementQuery); -+ } -+ -+ currentItem.element = floatingElementQuery; -+ currentItem.position = 'floating'; -+ } -+ -+ if (currentItem.element != null) { -+ introItems.push(currentItem); -+ } -+ } -+ -+ } else { -+ //use steps from data-* annotations -+ var allIntroSteps = targetElm.querySelectorAll('*[data-intro]'); -+ //if there's no element to intro -+ if (allIntroSteps.length < 1) { -+ return false; -+ } -+ -+ //first add intro items with data-step -+ for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) { -+ var currentElement = allIntroSteps[i]; -+ var step = parseInt(currentElement.getAttribute('data-step'), 10); -+ -+ if (step > 0) { -+ introItems[step - 1] = { -+ element: currentElement, -+ intro: currentElement.getAttribute('data-intro'), -+ step: parseInt(currentElement.getAttribute('data-step'), 10), -+ tooltipClass: currentElement.getAttribute('data-tooltipClass'), -+ position: currentElement.getAttribute('data-position') || this._options.tooltipPosition -+ }; -+ } -+ } -+ -+ //next add intro items without data-step -+ //todo: we need a cleanup here, two loops are redundant -+ var nextStep = 0; -+ for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) { -+ var currentElement = allIntroSteps[i]; -+ -+ if (currentElement.getAttribute('data-step') == null) { -+ -+ while (true) { -+ if (typeof introItems[nextStep] == 'undefined') { -+ break; -+ } else { -+ nextStep++; -+ } -+ } -+ -+ introItems[nextStep] = { -+ element: currentElement, -+ intro: currentElement.getAttribute('data-intro'), -+ step: nextStep + 1, -+ tooltipClass: currentElement.getAttribute('data-tooltipClass'), -+ position: currentElement.getAttribute('data-position') || this._options.tooltipPosition -+ }; -+ } -+ } -+ } -+ -+ //removing undefined/null elements -+ var tempIntroItems = []; -+ for (var z = 0; z < introItems.length; z++) { -+ introItems[z] && tempIntroItems.push(introItems[z]); // copy non-empty values to the end of the array -+ } -+ -+ introItems = tempIntroItems; -+ -+ //Ok, sort all items with given steps -+ introItems.sort(function (a, b) { -+ return a.step - b.step; -+ }); -+ -+ //set it to the introJs object -+ self._introItems = introItems; -+ -+ //add overlay layer to the page -+ if(_addOverlayLayer.call(self, targetElm)) { -+ //then, start the show -+ _nextStep.call(self); -+ -+ var skipButton = targetElm.querySelector('.introjs-skipbutton'), -+ nextStepButton = targetElm.querySelector('.introjs-nextbutton'); -+ -+ self._onKeyDown = function(e) { -+ if (e.keyCode === 27 && self._options.exitOnEsc == true) { -+ propagate_exit = true; -+ -+ //check if any callback is defined -+ if (self._introExitCallback != undefined) { -+ propagate_exit = self._introExitCallback.call(self); -+ if (typeof(propagate_exit) == "undefined") -+ propagate_exit = true; -+ } -+ -+ //escape key pressed, exit the intro -+ if (propagate_exit) -+ _exitIntro.call(self, targetElm); -+ -+ } else if(e.keyCode === 37) { -+ //left arrow -+ _previousStep.call(self); -+ } else if (e.keyCode === 39 || e.keyCode === 13) { -+ //right arrow or enter -+ _nextStep.call(self); -+ //prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers -+ if(e.preventDefault) { -+ e.preventDefault(); -+ } else { -+ e.returnValue = false; -+ } -+ } -+ }; -+ -+ self._onResize = function(e) { -+ _setHelperLayerPosition.call(self, document.querySelector('.introjs-helperLayer')); -+ }; -+ -+ if (window.addEventListener) { -+ if (this._options.keyboardNavigation) { -+ window.addEventListener('keydown', self._onKeyDown, true); -+ } -+ //for window resize -+ window.addEventListener("resize", self._onResize, true); -+ } else if (document.attachEvent) { //IE -+ if (this._options.keyboardNavigation) { -+ document.attachEvent('onkeydown', self._onKeyDown); -+ } -+ //for window resize -+ document.attachEvent("onresize", self._onResize); -+ } -+ } -+ return false; -+ } -+ -+ /* -+ * makes a copy of the object -+ * @api private -+ * @method _cloneObject -+ */ -+ function _cloneObject(object) { -+ if (object == null || typeof (object) != 'object' || typeof (object.nodeType) != 'undefined') { -+ return object; -+ } -+ var temp = {}; -+ for (var key in object) { -+ temp[key] = _cloneObject(object[key]); -+ } -+ return temp; -+ } -+ /** -+ * Go to specific step of introduction -+ * -+ * @api private -+ * @method _goToStep -+ */ -+ function _goToStep(step) { -+ //because steps starts with zero -+ this._currentStep = step - 2; -+ if (typeof (this._introItems) !== 'undefined') { -+ _nextStep.call(this); -+ } -+ } -+ -+ /** -+ * Go to next step on intro -+ * -+ * @api private -+ * @method _nextStep -+ */ -+ function _nextStep() { -+ this._direction = 'forward'; -+ -+ if (typeof (this._currentStep) === 'undefined') { -+ this._currentStep = 0; -+ } else { -+ ++this._currentStep; -+ } -+ -+ if ((this._introItems.length) <= this._currentStep) { -+ //end of the intro -+ //check if any callback is defined -+ if (typeof (this._introCompleteCallback) === 'function') { -+ this._introCompleteCallback.call(this); -+ } -+ _exitIntro.call(this, this._targetElement); -+ return; -+ } -+ -+ var nextStep = this._introItems[this._currentStep]; -+ if (typeof (this._introBeforeChangeCallback) !== 'undefined') { -+ this._introBeforeChangeCallback.call(this, nextStep.element); -+ } -+ -+ _showElement.call(this, nextStep); -+ } -+ -+ /** -+ * Go to previous step on intro -+ * -+ * @api private -+ * @method _nextStep -+ */ -+ function _previousStep() { -+ this._direction = 'backward'; -+ -+ if (this._currentStep === 0) { -+ return false; -+ } -+ -+ var nextStep = this._introItems[--this._currentStep]; -+ if (typeof (this._introBeforeChangeCallback) !== 'undefined') { -+ this._introBeforeChangeCallback.call(this, nextStep.element); -+ } -+ -+ _showElement.call(this, nextStep); -+ } -+ -+ /** -+ * Exit from intro -+ * -+ * @api private -+ * @method _exitIntro -+ * @param {Object} targetElement -+ */ -+ function _exitIntro(targetElement) { -+ //remove overlay layer from the page -+ var overlayLayer = targetElement.querySelector('.introjs-overlay'); -+ -+ //return if intro already completed or skipped -+ if (overlayLayer == null) { -+ return; -+ } -+ -+ //for fade-out animation -+ overlayLayer.style.opacity = 0; -+ setTimeout(function () { -+ if (overlayLayer.parentNode) { -+ overlayLayer.parentNode.removeChild(overlayLayer); -+ } -+ }, 500); -+ -+ //remove all helper layers -+ var helperLayer = targetElement.querySelector('.introjs-helperLayer'); -+ if (helperLayer) { -+ helperLayer.parentNode.removeChild(helperLayer); -+ } -+ -+ //remove intro floating element -+ var floatingElement = document.querySelector('.introjsFloatingElement'); -+ if (floatingElement) { -+ floatingElement.parentNode.removeChild(floatingElement); -+ } -+ -+ //remove `introjs-showElement` class from the element -+ var showElement = document.querySelector('.introjs-showElement'); -+ if (showElement) { -+ showElement.className = showElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, ''); // This is a manual trim. -+ } -+ -+ //remove `introjs-fixParent` class from the elements -+ var fixParents = document.querySelectorAll('.introjs-fixParent'); -+ if (fixParents && fixParents.length > 0) { -+ for (var i = fixParents.length - 1; i >= 0; i--) { -+ fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, ''); -+ }; -+ } -+ -+ //clean listeners -+ if (window.removeEventListener) { -+ window.removeEventListener('keydown', this._onKeyDown, true); -+ } else if (document.detachEvent) { //IE -+ document.detachEvent('onkeydown', this._onKeyDown); -+ } -+ -+ //set the step to zero -+ this._currentStep = undefined; -+ } -+ -+ /** -+ * Render tooltip box in the page -+ * -+ * @api private -+ * @method _placeTooltip -+ * @param {Object} targetElement -+ * @param {Object} tooltipLayer -+ * @param {Object} arrowLayer -+ */ -+ function _placeTooltip(targetElement, tooltipLayer, arrowLayer, helperNumberLayer) { -+ var tooltipCssClass = '', -+ currentStepObj, -+ tooltipOffset, -+ targetElementOffset; -+ -+ //reset the old style -+ tooltipLayer.style.top = null; -+ tooltipLayer.style.right = null; -+ tooltipLayer.style.bottom = null; -+ tooltipLayer.style.left = null; -+ tooltipLayer.style.marginLeft = null; -+ tooltipLayer.style.marginTop = null; -+ -+ arrowLayer.style.display = 'inherit'; -+ -+ if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) { -+ helperNumberLayer.style.top = null; -+ helperNumberLayer.style.left = null; -+ } -+ -+ //prevent error when `this._currentStep` is undefined -+ if (!this._introItems[this._currentStep]) return; -+ -+ //if we have a custom css class for each step -+ currentStepObj = this._introItems[this._currentStep]; -+ if (typeof (currentStepObj.tooltipClass) === 'string') { -+ tooltipCssClass = currentStepObj.tooltipClass; -+ } else { -+ tooltipCssClass = this._options.tooltipClass; -+ } -+ -+ tooltipLayer.className = ('introjs-tooltip ' + tooltipCssClass).replace(/^\s+|\s+$/g, ''); -+ -+ //custom css class for tooltip boxes -+ var tooltipCssClass = this._options.tooltipClass; -+ -+ currentTooltipPosition = this._introItems[this._currentStep].position; -+ switch (currentTooltipPosition) { -+ case 'top': -+ tooltipLayer.style.left = '15px'; -+ tooltipLayer.style.top = '-' + (_getOffset(tooltipLayer).height + 10) + 'px'; -+ arrowLayer.className = 'introjs-arrow bottom'; -+ break; -+ case 'right': -+ tooltipLayer.style.left = (_getOffset(targetElement).width + 20) + 'px'; -+ arrowLayer.className = 'introjs-arrow left'; -+ break; -+ case 'left': -+ if (this._options.showStepNumbers == true) { -+ tooltipLayer.style.top = '15px'; -+ } -+ tooltipLayer.style.right = (_getOffset(targetElement).width + 20) + 'px'; -+ arrowLayer.className = 'introjs-arrow right'; -+ break; -+ case 'floating': -+ arrowLayer.style.display = 'none'; -+ -+ //we have to adjust the top and left of layer manually for intro items without element -+ tooltipOffset = _getOffset(tooltipLayer); -+ -+ tooltipLayer.style.left = '50%'; -+ tooltipLayer.style.top = '50%'; -+ tooltipLayer.style.marginLeft = '-' + (tooltipOffset.width / 2) + 'px'; -+ tooltipLayer.style.marginTop = '-' + (tooltipOffset.height / 2) + 'px'; -+ -+ if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) { -+ helperNumberLayer.style.left = '-' + ((tooltipOffset.width / 2) + 18) + 'px'; -+ helperNumberLayer.style.top = '-' + ((tooltipOffset.height / 2) + 18) + 'px'; -+ } -+ -+ break; -+ case 'bottom-right-aligned': -+ arrowLayer.className = 'introjs-arrow top-right'; -+ tooltipLayer.style.right = '0px'; -+ tooltipLayer.style.bottom = '-' + (_getOffset(tooltipLayer).height + 10) + 'px'; -+ break; -+ case 'bottom-middle-aligned': -+ targetElementOffset = _getOffset(targetElement); -+ tooltipOffset = _getOffset(tooltipLayer); -+ -+ arrowLayer.className = 'introjs-arrow top-middle'; -+ tooltipLayer.style.left = (targetElementOffset.width / 2 - tooltipOffset.width / 2) + 'px'; -+ tooltipLayer.style.bottom = '-' + (tooltipOffset.height + 10) + 'px'; -+ break; -+ case 'bottom-left-aligned': -+ // Bottom-left-aligned is the same as the default bottom -+ case 'bottom': -+ // Bottom going to follow the default behavior -+ default: -+ tooltipLayer.style.bottom = '-' + (_getOffset(tooltipLayer).height + 10) + 'px'; -+ arrowLayer.className = 'introjs-arrow top'; -+ break; -+ } -+ } -+ -+ /** -+ * Update the position of the helper layer on the screen -+ * -+ * @api private -+ * @method _setHelperLayerPosition -+ * @param {Object} helperLayer -+ */ -+ function _setHelperLayerPosition(helperLayer) { -+ if (helperLayer) { -+ //prevent error when `this._currentStep` in undefined -+ if (!this._introItems[this._currentStep]) return; -+ -+ var currentElement = this._introItems[this._currentStep], -+ elementPosition = _getOffset(currentElement.element), -+ widthHeightPadding = 10; -+ -+ if (currentElement.position == 'floating') { -+ widthHeightPadding = 0; -+ } -+ -+ //set new position to helper layer -+ helperLayer.setAttribute('style', 'width: ' + (elementPosition.width + widthHeightPadding) + 'px; ' + -+ 'height:' + (elementPosition.height + widthHeightPadding) + 'px; ' + -+ 'top:' + (elementPosition.top - 5) + 'px;' + -+ 'left: ' + (elementPosition.left - 5) + 'px;'); -+ } -+ } -+ -+ /** -+ * Show an element on the page -+ * -+ * @api private -+ * @method _showElement -+ * @param {Object} targetElement -+ */ -+ function _showElement(targetElement) { -+ -+ if (typeof (this._introChangeCallback) !== 'undefined') { -+ this._introChangeCallback.call(this, targetElement.element); -+ } -+ -+ var self = this, -+ oldHelperLayer = document.querySelector('.introjs-helperLayer'), -+ elementPosition = _getOffset(targetElement.element); -+ -+ if (oldHelperLayer != null) { -+ var oldHelperNumberLayer = oldHelperLayer.querySelector('.introjs-helperNumberLayer'), -+ oldtooltipLayer = oldHelperLayer.querySelector('.introjs-tooltiptext'), -+ oldArrowLayer = oldHelperLayer.querySelector('.introjs-arrow'), -+ oldtooltipContainer = oldHelperLayer.querySelector('.introjs-tooltip'), -+ skipTooltipButton = oldHelperLayer.querySelector('.introjs-skipbutton'), -+ prevTooltipButton = oldHelperLayer.querySelector('.introjs-prevbutton'), -+ nextTooltipButton = oldHelperLayer.querySelector('.introjs-nextbutton'); -+ -+ //hide the tooltip -+ oldtooltipContainer.style.opacity = 0; -+ -+ if (oldHelperNumberLayer != null) { -+ var lastIntroItem = this._introItems[(targetElement.step - 2 >= 0 ? targetElement.step - 2 : 0)]; -+ -+ if (lastIntroItem != null && (this._direction == 'forward' && lastIntroItem.position == 'floating') || (this._direction == 'backward' && targetElement.position == 'floating')) { -+ oldHelperNumberLayer.style.opacity = 0; -+ } -+ } -+ -+ //set new position to helper layer -+ _setHelperLayerPosition.call(self, oldHelperLayer); -+ -+ //remove `introjs-fixParent` class from the elements -+ var fixParents = document.querySelectorAll('.introjs-fixParent'); -+ if (fixParents && fixParents.length > 0) { -+ for (var i = fixParents.length - 1; i >= 0; i--) { -+ fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, ''); -+ }; -+ } -+ -+ //remove old classes -+ var oldShowElement = document.querySelector('.introjs-showElement'); -+ oldShowElement.className = oldShowElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, ''); -+ //we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation -+ if (self._lastShowElementTimer) { -+ clearTimeout(self._lastShowElementTimer); -+ } -+ self._lastShowElementTimer = setTimeout(function() { -+ //set current step to the label -+ if (oldHelperNumberLayer != null) { -+ oldHelperNumberLayer.innerHTML = targetElement.step; -+ } -+ //set current tooltip text -+ oldtooltipLayer.innerHTML = targetElement.intro; -+ //set the tooltip position -+ _placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer); -+ -+ //change active bullet -+ oldHelperLayer.querySelector('.introjs-bullets li > a.active').className = ''; -+ oldHelperLayer.querySelector('.introjs-bullets li > a[data-stepnumber="' + targetElement.step + '"]').className = 'active'; -+ -+ //show the tooltip -+ oldtooltipContainer.style.opacity = 1; -+ if (oldHelperNumberLayer) oldHelperNumberLayer.style.opacity = 1; -+ }, 350); -+ -+ } else { -+ var helperLayer = document.createElement('div'), -+ arrowLayer = document.createElement('div'), -+ tooltipLayer = document.createElement('div'), -+ tooltipTextLayer = document.createElement('div'), -+ bulletsLayer = document.createElement('div'), -+ buttonsLayer = document.createElement('div'); -+ -+ helperLayer.className = 'introjs-helperLayer'; -+ -+ //set new position to helper layer -+ _setHelperLayerPosition.call(self, helperLayer); -+ -+ //add helper layer to target element -+ this._targetElement.appendChild(helperLayer); -+ -+ arrowLayer.className = 'introjs-arrow'; -+ -+ tooltipTextLayer.className = 'introjs-tooltiptext'; -+ tooltipTextLayer.innerHTML = targetElement.intro; -+ -+ bulletsLayer.className = 'introjs-bullets'; -+ -+ if (this._options.showBullets === false) { -+ bulletsLayer.style.display = 'none'; -+ } -+ -+ var ulContainer = document.createElement('ul'); -+ -+ for (var i = 0, stepsLength = this._introItems.length; i < stepsLength; i++) { -+ var innerLi = document.createElement('li'); -+ var anchorLink = document.createElement('a'); -+ -+ anchorLink.onclick = function() { -+ self.goToStep(this.getAttribute('data-stepnumber')); -+ }; -+ -+ if (i === (targetElement.step-1)) anchorLink.className = "active"; -+ -+ anchorLink.href = 'javascript:void(0);'; -+ anchorLink.innerHTML = " "; -+ anchorLink.setAttribute('data-stepnumber', this._introItems[i].step); -+ -+ innerLi.appendChild(anchorLink); -+ ulContainer.appendChild(innerLi); -+ } -+ -+ bulletsLayer.appendChild(ulContainer); -+ -+ buttonsLayer.className = 'introjs-tooltipbuttons'; -+ if (this._options.showButtons === false) { -+ buttonsLayer.style.display = 'none'; -+ } -+ -+ tooltipLayer.className = 'introjs-tooltip'; -+ tooltipLayer.appendChild(tooltipTextLayer); -+ tooltipLayer.appendChild(bulletsLayer); -+ -+ //add helper layer number -+ if (this._options.showStepNumbers == true) { -+ var helperNumberLayer = document.createElement('span'); -+ helperNumberLayer.className = 'introjs-helperNumberLayer'; -+ helperNumberLayer.innerHTML = targetElement.step; -+ helperLayer.appendChild(helperNumberLayer); -+ } -+ tooltipLayer.appendChild(arrowLayer); -+ helperLayer.appendChild(tooltipLayer); -+ -+ //next button -+ var nextTooltipButton = document.createElement('a'); -+ -+ nextTooltipButton.onclick = function() { -+ if (self._introItems.length - 1 != self._currentStep) { -+ _nextStep.call(self); -+ } -+ }; -+ -+ nextTooltipButton.href = 'javascript:void(0);'; -+ nextTooltipButton.innerHTML = this._options.nextLabel; -+ -+ //previous button -+ var prevTooltipButton = document.createElement('a'); -+ -+ prevTooltipButton.onclick = function() { -+ if (self._currentStep != 0) { -+ _previousStep.call(self); -+ } -+ }; -+ -+ prevTooltipButton.href = 'javascript:void(0);'; -+ prevTooltipButton.innerHTML = this._options.prevLabel; -+ -+ //skip button -+ var skipTooltipButton = document.createElement('a'); -+ skipTooltipButton.className = 'introjs-button introjs-skipbutton'; -+ skipTooltipButton.href = 'javascript:void(0);'; -+ skipTooltipButton.innerHTML = this._options.skipLabel; -+ -+ skipTooltipButton.onclick = function() { -+ propagate_exit = true; -+ -+ if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') { -+ propagate_exit = self._introCompleteCallback.call(self); -+ if (typeof(propagate_exit) == "undefined") -+ propagate_exit = true; -+ } -+ -+ if (self._introItems.length - 1 != self._currentStep && typeof (self._introExitCallback) === 'function') { -+ propagate_exit = self._introExitCallback.call(self); -+ if (typeof(propagate_exit) == "undefined") -+ propagate_exit = true; -+ } -+ -+ if (propagate_exit) -+ _exitIntro.call(self, self._targetElement); -+ }; -+ -+ buttonsLayer.appendChild(skipTooltipButton); -+ -+ //in order to prevent displaying next/previous button always -+ if (this._introItems.length > 1) { -+ buttonsLayer.appendChild(prevTooltipButton); -+ buttonsLayer.appendChild(nextTooltipButton); -+ } -+ -+ tooltipLayer.appendChild(buttonsLayer); -+ -+ //set proper position -+ _placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer); -+ } -+ -+ if (this._currentStep == 0 && this._introItems.length > 1) { -+ prevTooltipButton.className = 'introjs-button introjs-prevbutton introjs-disabled'; -+ nextTooltipButton.className = 'introjs-button introjs-nextbutton'; -+ skipTooltipButton.innerHTML = this._options.skipLabel; -+ } else if (this._introItems.length - 1 == this._currentStep || this._introItems.length == 1) { -+ skipTooltipButton.innerHTML = this._options.doneLabel; -+ prevTooltipButton.className = 'introjs-button introjs-prevbutton'; -+ nextTooltipButton.className = 'introjs-button introjs-nextbutton introjs-disabled'; -+ } else { -+ prevTooltipButton.className = 'introjs-button introjs-prevbutton'; -+ nextTooltipButton.className = 'introjs-button introjs-nextbutton'; -+ skipTooltipButton.innerHTML = this._options.skipLabel; -+ } -+ -+ //Set focus on "next" button, so that hitting Enter always moves you onto the next step -+ nextTooltipButton.focus(); -+ -+ //add target element position style -+ targetElement.element.className += ' introjs-showElement'; -+ -+ var currentElementPosition = _getPropValue(targetElement.element, 'position'); -+ if (currentElementPosition !== 'absolute' && -+ currentElementPosition !== 'relative') { -+ //change to new intro item -+ targetElement.element.className += ' introjs-relativePosition'; -+ } -+ -+ var parentElm = targetElement.element.parentNode; -+ while (parentElm != null) { -+ if (parentElm.tagName.toLowerCase() === 'body') break; -+ -+ //fix The Stacking Contenxt problem. -+ //More detail: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context -+ var zIndex = _getPropValue(parentElm, 'z-index'); -+ var opacity = parseFloat(_getPropValue(parentElm, 'opacity')); -+ var transform = _getPropValue(parentElm, 'transform') || _getPropValue(parentElm, '-webkit-transform') || _getPropValue(parentElm, '-moz-transform') || _getPropValue(parentElm, '-ms-transform') || _getPropValue(parentElm, '-o-transform'); -+ if (/[0-9]+/.test(zIndex) || opacity < 1 || transform !== 'none') { -+ parentElm.className += ' introjs-fixParent'; -+ } -+ -+ parentElm = parentElm.parentNode; -+ } -+ -+ if (!_elementInViewport(targetElement.element) && this._options.scrollToElement === true) { -+ var rect = targetElement.element.getBoundingClientRect(), -+ winHeight=_getWinSize().height, -+ top = rect.bottom - (rect.bottom - rect.top), -+ bottom = rect.bottom - winHeight; -+ -+ //Scroll up -+ if (top < 0 || targetElement.element.clientHeight > winHeight) { -+ window.scrollBy(0, top - 30); // 30px padding from edge to look nice -+ -+ //Scroll down -+ } else { -+ window.scrollBy(0, bottom + 100); // 70px + 30px padding from edge to look nice -+ } -+ } -+ -+ if (typeof (this._introAfterChangeCallback) !== 'undefined') { -+ this._introAfterChangeCallback.call(this, targetElement.element); -+ } -+ } -+ -+ /** -+ * Get an element CSS property on the page -+ * Thanks to JavaScript Kit: http://www.javascriptkit.com/dhtmltutors/dhtmlcascade4.shtml -+ * -+ * @api private -+ * @method _getPropValue -+ * @param {Object} element -+ * @param {String} propName -+ * @returns Element's property value -+ */ -+ function _getPropValue (element, propName) { -+ var propValue = ''; -+ if (element.currentStyle) { //IE -+ propValue = element.currentStyle[propName]; -+ } else if (document.defaultView && document.defaultView.getComputedStyle) { //Others -+ propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName); -+ } -+ -+ //Prevent exception in IE -+ if (propValue && propValue.toLowerCase) { -+ return propValue.toLowerCase(); -+ } else { -+ return propValue; -+ } -+ } -+ -+ /** -+ * Provides a cross-browser way to get the screen dimensions -+ * via: http://stackoverflow.com/questions/5864467/internet-explorer-innerheight -+ * -+ * @api private -+ * @method _getWinSize -+ * @returns {Object} width and height attributes -+ */ -+ function _getWinSize() { -+ if (window.innerWidth != undefined) { -+ return { width: window.innerWidth, height: window.innerHeight }; -+ } else { -+ var D = document.documentElement; -+ return { width: D.clientWidth, height: D.clientHeight }; -+ } -+ } -+ -+ /** -+ * Add overlay layer to the page -+ * http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport -+ * -+ * @api private -+ * @method _elementInViewport -+ * @param {Object} el -+ */ -+ function _elementInViewport(el) { -+ var rect = el.getBoundingClientRect(); -+ -+ return ( -+ rect.top >= 0 && -+ rect.left >= 0 && -+ (rect.bottom+80) <= window.innerHeight && // add 80 to get the text right -+ rect.right <= window.innerWidth -+ ); -+ } -+ -+ /** -+ * Add overlay layer to the page -+ * -+ * @api private -+ * @method _addOverlayLayer -+ * @param {Object} targetElm -+ */ -+ function _addOverlayLayer(targetElm) { -+ var overlayLayer = document.createElement('div'), -+ styleText = '', -+ self = this; -+ -+ //set css class name -+ overlayLayer.className = 'introjs-overlay'; -+ -+ //check if the target element is body, we should calculate the size of overlay layer in a better way -+ if (targetElm.tagName.toLowerCase() === 'body') { -+ styleText += 'top: 0;bottom: 0; left: 0;right: 0;position: fixed;'; -+ overlayLayer.setAttribute('style', styleText); -+ } else { -+ //set overlay layer position -+ var elementPosition = _getOffset(targetElm); -+ if (elementPosition) { -+ styleText += 'width: ' + elementPosition.width + 'px; height:' + elementPosition.height + 'px; top:' + elementPosition.top + 'px;left: ' + elementPosition.left + 'px;'; -+ overlayLayer.setAttribute('style', styleText); -+ } -+ } -+ -+ targetElm.appendChild(overlayLayer); -+ -+ overlayLayer.onclick = function() { -+ if (self._options.exitOnOverlayClick == true) { -+ _exitIntro.call(self, targetElm); -+ -+ //check if any callback is defined -+ if (self._introExitCallback != undefined) { -+ self._introExitCallback.call(self); -+ } -+ } -+ }; -+ -+ setTimeout(function() { -+ styleText += 'opacity: ' + self._options.overlayOpacity.toString() + ';'; -+ overlayLayer.setAttribute('style', styleText); -+ }, 10); -+ -+ return true; -+ } -+ -+ /** -+ * Get an element position on the page -+ * Thanks to `meouw`: http://stackoverflow.com/a/442474/375966 -+ * -+ * @api private -+ * @method _getOffset -+ * @param {Object} element -+ * @returns Element's position info -+ */ -+ function _getOffset(element) { -+ var elementPosition = {}; -+ -+ //set width -+ elementPosition.width = element.offsetWidth; -+ -+ //set height -+ elementPosition.height = element.offsetHeight; -+ -+ //calculate element top and left -+ var _x = 0; -+ var _y = 0; -+ while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) { -+ _x += element.offsetLeft; -+ _y += element.offsetTop; -+ element = element.offsetParent; -+ } -+ //set top -+ elementPosition.top = _y; -+ //set left -+ elementPosition.left = _x; -+ -+ return elementPosition; -+ } -+ -+ /** -+ * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1 -+ * via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically -+ * -+ * @param obj1 -+ * @param obj2 -+ * @returns obj3 a new object based on obj1 and obj2 -+ */ -+ function _mergeOptions(obj1,obj2) { -+ var obj3 = {}; -+ for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } -+ for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } -+ return obj3; -+ } -+ -+ var introJs = function (targetElm) { -+ if (typeof (targetElm) === 'object') { -+ //Ok, create a new instance -+ return new IntroJs(targetElm); -+ -+ } else if (typeof (targetElm) === 'string') { -+ //select the target element with query selector -+ var targetElement = document.querySelector(targetElm); -+ -+ if (targetElement) { -+ return new IntroJs(targetElement); -+ } else { -+ throw new Error('There is no element with given selector.'); -+ } -+ } else { -+ return new IntroJs(document.body); -+ } -+ }; -+ -+ /** -+ * Current IntroJs version -+ * -+ * @property version -+ * @type String -+ */ -+ introJs.version = VERSION; -+ -+ //Prototype -+ introJs.fn = IntroJs.prototype = { -+ clone: function () { -+ return new IntroJs(this); -+ }, -+ setOption: function(option, value) { -+ this._options[option] = value; -+ return this; -+ }, -+ setOptions: function(options) { -+ this._options = _mergeOptions(this._options, options); -+ return this; -+ }, -+ start: function () { -+ _introForElement.call(this, this._targetElement); -+ return this; -+ }, -+ goToStep: function(step) { -+ _goToStep.call(this, step); -+ return this; -+ }, -+ nextStep: function() { -+ _nextStep.call(this); -+ return this; -+ }, -+ previousStep: function() { -+ _previousStep.call(this); -+ return this; -+ }, -+ exit: function() { -+ _exitIntro.call(this, this._targetElement); -+ }, -+ refresh: function() { -+ _setHelperLayerPosition.call(this, document.querySelector('.introjs-helperLayer')); -+ return this; -+ }, -+ onbeforechange: function(providedCallback) { -+ if (typeof (providedCallback) === 'function') { -+ this._introBeforeChangeCallback = providedCallback; -+ } else { -+ throw new Error('Provided callback for onbeforechange was not a function'); -+ } -+ return this; -+ }, -+ onchange: function(providedCallback) { -+ if (typeof (providedCallback) === 'function') { -+ this._introChangeCallback = providedCallback; -+ } else { -+ throw new Error('Provided callback for onchange was not a function.'); -+ } -+ return this; -+ }, -+ onafterchange: function(providedCallback) { -+ if (typeof (providedCallback) === 'function') { -+ this._introAfterChangeCallback = providedCallback; -+ } else { -+ throw new Error('Provided callback for onafterchange was not a function'); -+ } -+ return this; -+ }, -+ oncomplete: function(providedCallback) { -+ if (typeof (providedCallback) === 'function') { -+ this._introCompleteCallback = providedCallback; -+ } else { -+ throw new Error('Provided callback for oncomplete was not a function.'); -+ } -+ return this; -+ }, -+ onexit: function(providedCallback) { -+ if (typeof (providedCallback) === 'function') { -+ this._introExitCallback = providedCallback; -+ } else { -+ throw new Error('Provided callback for onexit was not a function.'); -+ } -+ return this; -+ } -+ }; -+ -+ exports.introJs = introJs; -+ return introJs; -+})); -Index: include/javascript/clippy.js -=================================================================== ---- include/javascript/clippy.js (revision 0) -+++ include/javascript/clippy.js (revision 10417) -@@ -0,0 +1,8 @@ -+function clippy_set_help(help_section) { -+ document.cookie = 'clippy=' + help_section; -+} -+ -+function clippy_go_link_show_help(link, help_section) { -+ document.cookie = 'clippy=' + help_section; -+ window.location.href = link; -+} -\ No newline at end of file -Index: include/functions_servers.php -=================================================================== ---- include/functions_servers.php (revision 10314) -+++ include/functions_servers.php (working copy) -@@ -79,7 +79,9 @@ - $data["avg_interval_remote_modules"] = array(); - $data["avg_interval_local_modules"] = 0; - $data["local_modules_rate"] = 0; -+ $data["network_modules_rate"] = 0; - -+ - if ($config["realtimestats"] == 1) { - $counts = db_get_all_rows_sql ("SELECT tagente_modulo.id_modulo, COUNT(tagente_modulo.id_agente_modulo) modules - FROM tagente_modulo, tagente_estado, tagente -@@ -195,6 +197,8 @@ - $interval_avgs_agents = array(); - } - -+ $interval_avgs = array(); -+ - // Merge with the previous calculated array - foreach($interval_avgs_agents as $iaagents) { - if(!isset($interval_avgs[$iaagents['id_modulo']]['modules'])) { -Index: include/functions_treeview.php -=================================================================== ---- include/functions_treeview.php (revision 10314) -+++ include/functions_treeview.php (working copy) -@@ -468,11 +468,19 @@ - echo ''; - echo ''; -@@ -543,19 +553,25 @@ - else { - $id = $item['_id_']; - } -- -+ - echo ""; - - echo $img . $item['_iconImg_'] ." " . __($item['_name_']) . ' ('; - -- $counts_info = array('total_count' => $item['_num_ok_'] + $item['_num_critical_'] + $item['_num_warning_'] + $item['_num_unknown_'], -- 'normal_count' => $item['_num_ok_'], -- 'critical_count' => $item['_num_critical_'], -- 'warning_count' => $item['_num_warning_'], -- 'unknown_count' => $item['_num_unknown_']); -- -+ $counts_info = array( -+ 'total_count' => $item['_num_ok_'] + -+ $item['_num_critical_'] + -+ $item['_num_warning_'] + -+ $item['_num_unknown_'], -+ 'normal_count' => $item['_num_ok_'], -+ 'critical_count' => $item['_num_critical_'], -+ 'warning_count' => $item['_num_warning_'], -+ 'unknown_count' => $item['_num_unknown_']); -+ -+ - reporting_tiny_stats($counts_info, false, $type); - -+ - echo ') '. ""; - - echo "
"; -@@ -581,7 +597,11 @@ - $avariableGroups = users_get_groups (); - - //Get all groups with agents -- $full_groups = db_get_all_rows_sql("SELECT DISTINCT id_grupo FROM tagente WHERE total_count > 0"); -+ $full_groups = db_get_all_rows_sql(" -+ SELECT DISTINCT id_grupo -+ FROM tagente -+ WHERE total_count > 0"); -+ - if ($full_groups === false) { - return array (); - } -@@ -607,9 +627,12 @@ - switch ($select_status) { - case NORMAL: - foreach ($avariableGroups as $group_name) { -- $id_group = db_get_value_sql('SELECT id_grupo FROM tgrupo where nombre ="' . $group_name . '"'); -+ $id_group = db_get_value_sql(' -+ SELECT id_grupo -+ FROM tgrupo -+ WHERE nombre ="' . $group_name . '"'); - -- $num_ok = groups_agent_ok($id_group); -+ $num_ok = groups_agent_ok($id_group); - - if ($num_ok <= 0) - unset($avariableGroups[$id_group]); -@@ -619,7 +642,10 @@ - break; - case WARNING: - foreach ($avariableGroups as $group_name) { -- $id_group = db_get_value_sql('SELECT id_grupo FROM tgrupo where nombre ="' . $group_name . '"'); -+ $id_group = db_get_value_sql(' -+ SELECT id_grupo -+ FROM tgrupo -+ WHERE nombre ="' . $group_name . '"'); - - $num_warning = groups_agent_warning($id_group); - -@@ -629,7 +655,10 @@ - break; - case CRITICAL: - foreach ($avariableGroups as $group_name) { -- $id_group = db_get_value_sql('SELECT id_grupo FROM tgrupo where nombre ="' . $group_name . '"'); -+ $id_group = db_get_value_sql(' -+ SELECT id_grupo -+ FROM tgrupo -+ WHERE nombre ="' . $group_name . '"'); - - $num_critical = groups_agent_critical($id_group); - -@@ -639,7 +668,10 @@ - break; - case UNKNOWN: - foreach ($avariableGroups as $group_name) { -- $id_group = db_get_value_sql('SELECT id_grupo FROM tgrupo where nombre ="' . $group_name . '"'); -+ $id_group = db_get_value_sql(' -+ SELECT id_grupo -+ FROM tgrupo -+ WHERE nombre ="' . $group_name . '"'); - - $num_unknown = groups_agent_unknown($id_group); - -@@ -656,17 +688,42 @@ - } - - if ($search_free != '') { -- $sql_search = " AND id_grupo IN (SELECT id_grupo FROM tagente -- WHERE tagente.nombre COLLATE utf8_general_ci LIKE '%$search_free%')"; -+ switch ($config['dbtype']) { -+ case "mysql": -+ $sql_search = " AND id_grupo IN ( -+ SELECT id_grupo -+ FROM tagente -+ WHERE tagente.nombre COLLATE utf8_general_ci LIKE '%$search_free%')"; -+ break; -+ case "postgresql": -+ $sql_search = " AND id_grupo IN ( -+ SELECT id_grupo -+ FROM tagente -+ WHERE tagente.nombre LIKE '%$search_free%')"; -+ break; -+ case "oracle": -+ $sql_search = " AND id_grupo IN ( -+ SELECT id_grupo -+ FROM tagente -+ WHERE tagente.nombre COLLATE utf8_general_ci LIKE '%$search_free%')"; -+ break; -+ } - } - else { - $sql_search =''; - } - -+ $order_collate = ""; -+ switch ($config['dbtype']) { -+ case "mysql": -+ $order_collate = "COLLATE utf8_general_ci"; -+ break; -+ } -+ - switch ($type) { -- case 'os': -+ case 'os': - $sql = agents_get_agents(array ( -- 'order' => 'nombre COLLATE utf8_general_ci ASC', -+ 'order' => 'nombre ' . $order_collate . ' ASC', - 'disabled' => 0, - 'status' => $select_status, - 'search' => $sql_search), -@@ -676,7 +733,9 @@ - false, - true); - -- $sql_os = sprintf("SELECT * FROM tconfig_os WHERE id_os IN (%s)", $sql); -+ $sql_os = sprintf("SELECT * -+ FROM tconfig_os -+ WHERE id_os IN (%s)", $sql); - - $list = db_get_all_rows_sql($sql_os); - -@@ -692,17 +751,31 @@ - - switch ($config["dbtype"]) { - case "mysql": -+ $list = db_get_all_rows_sql(" -+ SELECT * -+ FROM tgrupo -+ WHERE nombre IN (" . $stringAvariableGroups . ") $sql_search -+ ORDER BY nombre COLLATE utf8_general_ci ASC"); -+ break; - case "postgresql": -- $list = db_get_all_rows_sql("SELECT * FROM tgrupo WHERE nombre IN (" . $stringAvariableGroups . ") $sql_search ORDER BY nombre COLLATE utf8_general_ci ASC"); -+ $list = db_get_all_rows_sql(" -+ SELECT * -+ FROM tgrupo -+ WHERE nombre IN (" . $stringAvariableGroups . ") $sql_search -+ ORDER BY nombre ASC"); - break; - case "oracle": -- $list = db_get_all_rows_sql("SELECT * FROM tgrupo WHERE dbms_lob.substr(nombre,4000,1) IN (" . $stringAvariableGroups . ") ORDER BY nombre COLLATE utf8_general_ci ASC"); -+ $list = db_get_all_rows_sql(" -+ SELECT * -+ FROM tgrupo -+ WHERE dbms_lob.substr(nombre,4000,1) IN (" . $stringAvariableGroups . ") -+ ORDER BY nombre COLLATE utf8_general_ci ASC"); - break; - } - break; - case 'module_group': - $sql = agents_get_agents(array ( -- 'order' => 'nombre COLLATE utf8_general_ci ASC', -+ 'order' => 'nombre ' . $order_collate . ' ASC', - 'disabled' => 0, - 'status' => $select_status, - 'search' => $sql_search), -@@ -714,8 +787,13 @@ - // Skip agents without modules - $sql .= ' AND tagente.total_count>0'; - -- $sql_module_groups = sprintf("SELECT * FROM tmodule_group -- WHERE id_mg IN (SELECT id_module_group FROM tagente_modulo WHERE id_agente IN (%s))", $sql); -+ $sql_module_groups = sprintf(" -+ SELECT * -+ FROM tmodule_group -+ WHERE id_mg IN ( -+ SELECT id_module_group -+ FROM tagente_modulo -+ WHERE id_agente IN (%s))", $sql); - - - $list = db_get_all_rows_sql($sql_module_groups); -@@ -734,7 +812,8 @@ - $groups = implode(',',$groups_id); - - if ($search_free != '') { -- $sql = "SELECT DISTINCT tpolicies.id, tpolicies.name -+ $sql = " -+ SELECT DISTINCT tpolicies.id, tpolicies.name - FROM tpolicies, tpolicy_modules, - tagente_estado, tagente, tagente_modulo - WHERE -@@ -749,7 +828,7 @@ - tagente.nombre LIKE '%$search_free%' AND - tagente.disabled = 0 AND - tagente_modulo.disabled = 0 -- ORDER BY tpolicies.name COLLATE utf8_general_ci ASC"; -+ ORDER BY tpolicies.name COLLATE utf8_general_ci ASC"; - - $list = db_get_all_rows_sql($sql); - -@@ -825,7 +904,7 @@ - tagente.id_grupo IN ($groups) AND - tagente.disabled = 0 AND - tagente_modulo.disabled = 0 -- ORDER BY tpolicies.name COLLATE utf8_general_ci ASC"); -+ ORDER BY tpolicies.name ' . $order_collate . ' ASC"); - - $element = 0; - switch ($select_status) { -@@ -889,8 +968,28 @@ - } - - if ($search_free != '') { -- $sql_search = " AND t1.id_agente IN (SELECT id_agente FROM tagente -- WHERE nombre COLLATE utf8_general_ci LIKE '%$search_free%')"; -+ switch ($config['dbtype']) { -+ case "mysql": -+ $sql_search = " AND t1.id_agente IN ( -+ SELECT id_agente -+ FROM tagente -+ WHERE nombre COLLATE utf8_general_ci LIKE '%$search_free%')"; -+ break; -+ case "postgresql": -+ $sql_search = " AND t1.id_agente IN ( -+ SELECT id_agente -+ FROM tagente -+ WHERE nombre LIKE '%$search_free%')"; -+ break; -+ case "oracle": -+ $sql_search = " AND t1.id_agente IN ( -+ SELECT id_agente -+ FROM tagente -+ WHERE nombre COLLATE utf8_general_ci LIKE '%$search_free%')"; -+ break; -+ } -+ -+ - } - else { - $sql_search = ''; -@@ -899,7 +998,8 @@ - if ($select_status != -1) - $sql_search .= " AND estado = " . $select_status . " "; - -- $sql_search .= tags_get_acl_tags($config['id_user'], 0, 'AR', 'module_condition', 'AND', 't1'); -+ $sql_search .= tags_get_acl_tags( -+ $config['id_user'], 0, 'AR', 'module_condition', 'AND', 't1'); - - switch ($config["dbtype"]) { - case "mysql": -@@ -915,7 +1015,7 @@ - $sql_search.' - GROUP BY t1.nombre ORDER BY t1.nombre'); - break; -- case "oracle": -+ case "oracle": - $list = db_get_all_rows_sql(' - SELECT dbms_lob.substr(t1.nombre,4000,1) as nombre - FROM tagente_modulo t1, tagente t2, -@@ -950,15 +1050,16 @@ - $search_sql = sprintf(" AND tagente.nombre COLLATE utf8_general_ci LIKE '%%%s%%'", $search_free); - } - -- $sql = "SELECT DISTINCT ttag.name -- FROM ttag, ttag_module, tagente, tagente_modulo -- WHERE ttag.id_tag = ttag_module.id_tag -+ $sql = " -+ SELECT DISTINCT ttag.name -+ FROM ttag, ttag_module, tagente, tagente_modulo -+ WHERE ttag.id_tag = ttag_module.id_tag - AND tagente.id_agente = tagente_modulo.id_agente - AND tagente.disabled = 0 - AND ttag_module.id_agente_modulo = tagente_modulo.id_agente_modulo" . - $search_sql . -- $user_tags_sql . -- " ORDER BY ttag.name COLLATE utf8_general_ci ASC"; -+ $user_tags_sql . " -+ ORDER BY ttag.name ' . $order_collate . ' ASC"; - - $list = db_get_all_rows_sql($sql); - break; -@@ -1054,6 +1155,13 @@ - return false; - } - -+ $order_collate = ""; -+ switch ($config['dbtype']) { -+ case "mysql": -+ $order_collate = "COLLATE utf8_general_ci"; -+ break; -+ } -+ - //TODO CHANGE POLICY ACL FOR TAG ACL - $extra_sql = ''; - if ($extra_sql != '') { -@@ -1062,7 +1170,18 @@ - $groups_sql = implode(', ', $avariableGroupsIds); - - if ($search_free != '') { -- $search_sql = " AND tagente.nombre COLLATE utf8_general_ci LIKE '%$search_free%'"; -+ switch ($config['dbtype']) { -+ case "mysql": -+ $search_sql = " AND tagente.nombre COLLATE utf8_general_ci LIKE '%$search_free%'"; -+ break; -+ case "postgresql": -+ $search_sql = " AND tagente.nombre LIKE '%$search_free%'"; -+ break; -+ case "oracle": -+ $search_sql = " AND tagente.nombre COLLATE utf8_general_ci LIKE '%$search_free%'"; -+ break; -+ } -+ - } - else { - $search_sql = ''; -@@ -1078,14 +1197,14 @@ - } - } - -- $sql = agents_get_agents(array ( -+ $sql = agents_get_agents(array ( - 'id_grupo' => $id, - 'disabled' => 0, - 'status' => $statusSel, - 'search' => $search_sql), - array ('*'), - 'AR', -- array('field' => 'nombre COLLATE utf8_general_ci', 'order' => ' ASC'), -+ array('field' => 'nombre ' . $order_collate, 'order' => ' ASC'), - true); - break; - case 'os': -@@ -1097,7 +1216,7 @@ - 'search' => $search_sql), - array ('*'), - 'AR', -- array('field' => 'nombre COLLATE utf8_general_ci', 'order' => ' ASC'), -+ array('field' => 'nombre ' . $order_collate, 'order' => ' ASC'), - true); - break; - case 'module_group': -@@ -1117,7 +1236,7 @@ - FROM tagente_modulo - WHERE id_module_group = ' . $id . ')'; - -- $sql .= 'ORDER BY nombre COLLATE utf8_general_ci ASC'; -+ $sql .= 'ORDER BY nombre ' . $order_collate . ' ASC'; - - break; - case 'policies': -@@ -1144,7 +1263,7 @@ - AND tagente_estado.utimestamp != 0 - AND tagente_modulo.id_policy_module != 0 - AND tpolicy_modules.id_policy = ' . $id . ' -- group by tagente.id_agente -+ GROUP BY tagente.id_agente - having COUNT(*) > 0)'; - } - else if ($statusSel == 0) { -@@ -1152,11 +1271,12 @@ - // If status filter is NORMAL add void agents - $sql .= " UNION SELECT * FROM tagente - WHERE tagente.disabled = 0 -- AND tagente.id_agente NOT IN (SELECT tagente_estado.id_agente -+ AND tagente.id_agente NOT IN ( -+ SELECT tagente_estado.id_agente - FROM tagente_estado)"; - } - -- $sql .= 'ORDER BY nombre COLLATE utf8_general_ci ASC'; -+ $sql .= 'ORDER BY nombre ' . $order_collate . ' ASC'; - - break; - case 'module': -@@ -1188,7 +1308,7 @@ - ) - ', $name); - -- $sql .= 'ORDER BY nombre COLLATE utf8_general_ci ASC'; -+ $sql .= 'ORDER BY nombre ' . $order_collate . ' ASC'; - - break; - case 'tag': -@@ -1219,7 +1339,8 @@ - - $sql .= ' AND tagente.disabled = 0'. $search_sql; - -- $sql .= ' GROUP BY tagente.id_agente ORDER BY tagente.nombre COLLATE utf8_general_ci ASC'; -+ $sql .= ' GROUP BY tagente.id_agente -+ ORDER BY tagente.nombre ' . $order_collate . ' ASC'; - - break; - } -@@ -1234,25 +1355,36 @@ - // Get SQL for the second tree branch - function treeview_getSecondBranchSQL ($fatherType, $id, $id_father) { - global $config; -+ -+ $order_collate = ""; -+ switch ($config['dbtype']) { -+ case "mysql": -+ $order_collate = "COLLATE utf8_general_ci"; -+ break; -+ } -+ - switch ($fatherType) { - case 'group': - $sql = 'SELECT * - FROM tagente_modulo AS t1 -- INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo -+ INNER JOIN tagente_estado AS t2 -+ ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id; - $sql .= tags_get_acl_tags($config['id_user'], 0, 'AR', 'module_condition', 'AND', 't1'); - break; - case 'os': - $sql = 'SELECT * - FROM tagente_modulo AS t1 -- INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo -+ INNER JOIN tagente_estado AS t2 -+ ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id; - $sql .= tags_get_acl_tags($config['id_user'], 0, 'AR', 'module_condition', 'AND', 't1'); - break; - case 'module_group': - $sql = 'SELECT * - FROM tagente_modulo AS t1 -- INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo -+ INNER JOIN tagente_estado AS t2 -+ ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id . ' AND id_module_group = ' . $id_father; - $sql .= tags_get_acl_tags($config['id_user'], 0, 'AR', 'module_condition', 'AND', 't1'); - break; -@@ -1275,8 +1407,10 @@ - $symbols = ' !"#$%&\'()*+,./:;<=>?@[\\]^{|}~'; - $name = $id_father; - for ($i = 0; $i < strlen($symbols); $i++) { -- $name = str_replace('_articapandora_'.ord(substr($symbols, $i, 1)).'_pandoraartica_', substr($symbols, $i, 1), $name); -- } -+ $name = str_replace('_articapandora_' . -+ ord(substr($symbols, $i, 1)) .'_pandoraartica_', -+ substr($symbols, $i, 1), $name); -+ } - switch ($config["dbtype"]) { - case "mysql": - $sql = 'SELECT * -@@ -1315,8 +1449,9 @@ - break; - } - -- // This line checks for initializated modules or (non-initialized) asyncronous modules -- $sql .= ' AND disabled = 0 AND (utimestamp > 0 OR id_tipo_modulo IN (21,22,23)) ORDER BY nombre COLLATE utf8_general_ci ASC'; -+ // This line checks for initializated modules or (non-initialized) asyncronous modules -+ $sql .= ' AND disabled = 0 AND (utimestamp > 0 OR id_tipo_modulo IN (21,22,23)) -+ ORDER BY nombre ' . $order_collate . ' ASC'; - return $sql; - } - ?> -Index: include/functions_config.php -=================================================================== ---- include/functions_config.php (revision 10314) -+++ include/functions_config.php (working copy) -@@ -182,6 +182,8 @@ - $error_update[] = __('Command Snapshot'); - if (!config_update_value ('server_log_dir', get_parameter('server_log_dir'))) - $error_update[] = __('Server logs directory'); -+ if (!config_update_value ('tutorial_mode', get_parameter('tutorial_mode'))) -+ $error_update[] = __('Tutorial mode'); - break; - case 'enterprise': - if (isset($config['enterprise_installed']) && $config['enterprise_installed'] == 1) { -@@ -433,6 +435,10 @@ - $error_update[] = __('Default icon in GIS'); - if (!config_update_value ('autohidden_menu', get_parameter('autohidden_menu'))) - $error_update[] = __('Autohidden menu'); -+ if (!config_update_value ('fixed_header', get_parameter('fixed_header'))) -+ $error_update[] = __('Fixed header'); -+ if (!config_update_value ('fixed_menu', get_parameter('fixed_menu'))) -+ $error_update[] = __('Fixed menu'); - if (!config_update_value ('paginate_module', get_parameter('paginate_module'))) - $error_update[] = __('Paginate module'); - if (!config_update_value ('graphviz_bin_dir', get_parameter('graphviz_bin_dir'))) -@@ -781,17 +787,31 @@ - // config_update_value ('autoupdate', true); - // } - -- require_once ($config["homedir"]."/include/auth/mysql.php"); -+ require_once ($config["homedir"] . "/include/auth/mysql.php"); - -- // Next is the directory where "/attachment" directory is placed, to upload files stores. -- // This MUST be writtable by http server user, and should be in pandora root. -- // By default, Pandora adds /attachment to this, so by default is the pandora console home dir -+ -+ // Next is the directory where "/attachment" directory is placed, -+ // to upload files stores. This MUST be writtable by http server -+ // user, and should be in pandora root. By default, Pandora adds -+ // /attachment to this, so by default is the pandora console home -+ // dir. - if (!isset ($config['attachment_store'])) { -- config_update_value ( 'attachment_store', $config['homedir'].'/attachment'); -+ config_update_value('attachment_store', -+ $config['homedir'] . '/attachment'); - } -+ else { -+ //Fixed when the user moves the pandora console to another dir -+ //after the first uses. -+ if (!is_dir($config['attachment_store'])) { -+ config_update_value('attachment_store', -+ $config['homedir'] . '/attachment'); -+ } -+ } - -+ - if (!isset ($config['fontpath'])) { -- config_update_value ( 'fontpath', $config['homedir'].'/include/fonts/smallfont.ttf'); -+ config_update_value('fontpath', -+ $config['homedir'] . '/include/fonts/smallfont.ttf'); - } - - if (!isset ($config['style'])) { -@@ -869,7 +889,7 @@ - if (!isset ($config['netflow_nfexpire'])) { - config_update_value ( 'netflow_nfexpire', '/usr/bin/nfexpire'); - } -- -+ - if (!isset ($config['netflow_max_resolution'])) { - config_update_value ( 'netflow_max_resolution', '50'); - } -@@ -877,7 +897,7 @@ - if (!isset ($config['netflow_disable_custom_lvfilters'])) { - config_update_value ( 'netflow_disable_custom_lvfilters', 0); - } -- -+ - if (!isset ($config['netflow_max_lifetime'])) { - config_update_value ( 'netflow_max_lifetime', '5'); - } -@@ -919,13 +939,14 @@ - } - - if (!isset ($config['ldap_base_dn'])) { -- config_update_value ( 'ldap_base_dn', 'ou=People,dc=edu,dc=example,dc=org'); -+ config_update_value('ldap_base_dn', -+ 'ou=People,dc=edu,dc=example,dc=org'); - } - - if (!isset ($config['ldap_login_attr'])) { - config_update_value ( 'ldap_login_attr', 'uid'); - } -- -+ - if (!isset ($config['fallback_local_auth'])) { - config_update_value ( 'fallback_local_auth', '0'); - } -@@ -1030,11 +1051,11 @@ - config_update_value( 'api_password', ''); - } - -- if(defined('METACONSOLE')) { -+ if (defined('METACONSOLE')) { - // Customizable sections (Metaconsole) - enterprise_include_once ('include/functions_enterprise.php'); - $customizable_sections = enterprise_hook('enterprise_get_customizable_sections'); -- -+ - if($customizable_sections != ENTERPRISE_NOT_HOOK) { - foreach($customizable_sections as $k => $v) { - if (!isset ($config[$k])) { -@@ -1050,7 +1071,7 @@ - - if (!isset ($config['relative_path']) && (isset ($_POST['nick']) - || isset ($config['id_user'])) && isset($config['enterprise_installed'])) { -- -+ - $isFunctionSkins = enterprise_include_once ('include/functions_skins.php'); - if ($isFunctionSkins !== ENTERPRISE_NOT_HOOK) { - -@@ -1153,7 +1174,8 @@ - } - - if (!isset($config['custom_report_front_logo'])) { -- config_update_value ('custom_report_front_logo', 'images/pandora_logo_white.jpg'); -+ config_update_value ('custom_report_front_logo', -+ 'images/pandora_logo_white.jpg'); - } - - if (!isset($config['custom_report_front_header'])) { -@@ -1161,7 +1183,8 @@ - } - - if (!isset($config['custom_report_front_firstpage'])) { -- config_update_value ('custom_report_front_firstpage', "<p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;"><img src="" . ui_get_full_url(false, false, false, false) . "/images/pandora_report_logo.png" alt="" width="800" /></p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;"><span style="font-size: xx-large;">(_REPORT_NAME_)</span></p> <p style="text-align: center;"><span style="font-size: large;">(_DATETIME_)</span></p>"); -+ config_update_value ('custom_report_front_firstpage', -+ "<p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;"><img src="" . ui_get_full_url(false, false, false, false) . "/images/pandora_report_logo.png" alt="" width="800" /></p> <p style="text-align: center;">&nbsp;</p> <p style="text-align: center;"><span style="font-size: xx-large;">(_REPORT_NAME_)</span></p> <p style="text-align: center;"><span style="font-size: large;">(_DATETIME_)</span></p>"); - } - - if (!isset($config['custom_report_front_footer'])) { -@@ -1176,6 +1199,10 @@ - config_update_value ('networkmap_max_width', 900); - } - -+ if (!isset($config['tutorial_mode'])) { -+ config_update_value ('tutorial_mode', 'full'); -+ } -+ - /* Finally, check if any value was overwritten in a form */ - config_update_config(); - } -@@ -1312,7 +1339,7 @@ - $config["alert_cnt"]++; - $_SESSION["alert_msg"] .= ui_print_info_message( - array('title' => __("New update of Pandora Console"), -- 'message' => __('There is a new update please go to menu Administration and into extensions go to Update Manager for more details.'), -+ 'message' => __('There is a new update please go to menu Administration and into extensions go to Update Manager for more details.'), - 'no_close' => true, 'force_style' => 'color: #000000 !important'), '', true); - } - } -Index: include/help/clippy/godmode_agentes_modificar_agente.php -=================================================================== ---- include/help/clippy/godmode_agentes_modificar_agente.php (revision 0) -+++ include/help/clippy/godmode_agentes_modificar_agente.php (revision 10417) -@@ -0,0 +1,71 @@ -+ '#clippy', -+ 'intro' => __('I show how to monitoring a server.') -+ ); -+ $helps['monitoring_server_step_1']['steps'][] = array( -+ 'element'=> 'input[name="search"]', -+ 'intro' => __('Please type a agent to save the modules for monitoring a server.') -+ ); -+ $helps['monitoring_server_step_1']['steps'][] = array( -+ 'element'=> 'input[name="srcbutton"]', -+ 'intro' => __('Maybe if you typped correctly the name, you can see the agent.') -+ ); -+ $helps['monitoring_server_step_1']['conf'] = array(); -+ $helps['monitoring_server_step_1']['conf']['showBullets'] = 0; -+ $helps['monitoring_server_step_1']['conf']['showStepNumbers'] = 1; -+ $helps['monitoring_server_step_1']['conf']['next_help'] = 'monitoring_server_step_2'; -+ //================================================================== -+ -+ -+ //================================================================== -+ //Help tour about the monitoring with a ping (step 2) -+ //------------------------------------------------------------------ -+ $helps['monitoring_server_step_2'] = array(); -+ $helps['monitoring_server_step_2']['steps'] = array(); -+ $helps['monitoring_server_step_2']['steps'][] = array( -+ 'element'=> '#clippy', -+ 'intro' => __('Please choose the agent that you have searched.') -+ ); -+ $helps['monitoring_server_step_2']['steps'][] = array( -+ 'element'=> '#agent_list', -+ 'intro' => __('Choose the agent, please click in the name.') -+ ); -+ $helps['monitoring_server_step_2']['conf'] = array(); -+ $helps['monitoring_server_step_2']['conf']['showBullets'] = 0; -+ $helps['monitoring_server_step_2']['conf']['showStepNumbers'] = 0; -+ $helps['monitoring_server_step_2']['conf']['next_help'] = 'monitoring_server_step_3'; -+ //================================================================== -+ -+ clippy_write_javascript_helps_steps($helps, false); -+} -+?> -\ No newline at end of file -Index: include/help/clippy/homepage.php -=================================================================== ---- include/help/clippy/homepage.php (revision 0) -+++ include/help/clippy/homepage.php (revision 10417) -@@ -0,0 +1,105 @@ -+ '#clippy', -+ 'intro' => __('Could I help you?

I am Pandorin, the annoying clippy for Pandora. You could follow my advices for to make common and basic tasks in Pandora.') . -+ '
-+
' . -+ html_print_image('images/pandorin.png', true) . -+ '
-+
' -+ ); -+ $helps['homepage']['steps'][] = array( -+ 'element'=> '#clippy', -+ 'intro' => __('What task do you want to do?') . '

' . -+ '' . -+ '
'. -+ html_print_checkbox_extended -+ ('clippy_is_annoying', 1, $clippy_is_annoying, false, -+ 'set_clippy_annoying()', '', true) . -+ __('Please the clippy is annoying, I don\'t want see.') . -+ '
' -+ ); -+ $helps['homepage']['conf'] = array(); -+ $helps['homepage']['conf']['showBullets'] = 0; -+ $helps['homepage']['conf']['showStepNumbers'] = 0; -+ $helps['homepage']['conf']['name_obj_tour'] = 'intro_homepage'; -+ $helps['homepage']['conf']['other_js'] = " -+ function show_clippy() { -+ intro_homepage.start(); -+ } -+ -+ function set_clippy_annoying() { -+ checked = $('input[name=\'clippy_is_annoying\']').is(':checked'); -+ intro_homepage.exit(); -+ -+ if (checked) { -+ document.cookie = 'clippy_is_annoying=1'; -+ } -+ else { -+ document.cookie = 'clippy_is_annoying=0'; -+ } -+ } -+ "; -+ if ($config['logged']) { -+ $helps['homepage']['conf']['autostart'] = true; -+ } -+ else { -+ $helps['homepage']['conf']['autostart'] = false; -+ } -+ -+ if ($config["tutorial_mode"] == 'on_demand') { -+ $helps['homepage']['conf']['autostart'] = false; -+ } -+ -+ if ($clippy_is_annoying === 1) { -+ $helps['homepage']['conf']['autostart'] = false; -+ } -+ -+ //================================================================== -+ -+ clippy_write_javascript_helps_steps($helps); -+} -+?> -\ No newline at end of file -Index: include/help/clippy/godmode_agentes_configurar_agente.php -=================================================================== ---- include/help/clippy/godmode_agentes_configurar_agente.php (revision 0) -+++ include/help/clippy/godmode_agentes_configurar_agente.php (revision 10417) -@@ -0,0 +1,126 @@ -+ '#clippy', -+ 'intro' => __('Now you must go to modules, don\'t worry I teach you.') -+ ); -+ $helps['monitoring_server_step_3']['steps'][] = array( -+ 'element'=> "img[alt='Modules']", -+ 'intro' => __('Please click in this tab.') -+ ); -+ $helps['monitoring_server_step_3']['conf'] = array(); -+ $helps['monitoring_server_step_3']['conf']['showBullets'] = 0; -+ $helps['monitoring_server_step_3']['conf']['showStepNumbers'] = 0; -+ $helps['monitoring_server_step_3']['conf']['next_help'] = 'monitoring_server_step_4'; -+ //================================================================== -+ -+ -+ //================================================================== -+ //Help tour about the monitoring with a ping (step 4) -+ //------------------------------------------------------------------ -+ $helps['monitoring_server_step_4'] = array(); -+ $helps['monitoring_server_step_4']['steps'] = array(); -+ $helps['monitoring_server_step_4']['steps'][] = array( -+ 'element'=> '#clippy', -+ 'intro' => __('Now you must create the module, don\'t worry I teach you.') -+ ); -+ $helps['monitoring_server_step_4']['steps'][] = array( -+ 'element'=> "#moduletype", -+ 'intro' => __('Choose the network server module.') -+ ); -+ $helps['monitoring_server_step_4']['steps'][] = array( -+ 'element'=> "input[name='updbutton']", -+ 'intro' => __('And click in this button.') -+ ); -+ $helps['monitoring_server_step_4']['conf'] = array(); -+ $helps['monitoring_server_step_4']['conf']['showBullets'] = 0; -+ $helps['monitoring_server_step_4']['conf']['showStepNumbers'] = 0; -+ $helps['monitoring_server_step_4']['conf']['next_help'] = 'monitoring_server_step_5'; -+ //================================================================== -+ -+ -+ //================================================================== -+ //Help tour about the monitoring with a ping (step 5) -+ //------------------------------------------------------------------ -+ $helps['monitoring_server_step_5'] = array(); -+ $helps['monitoring_server_step_5']['steps'] = array(); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> '#clippy', -+ 'intro' => __('Now you must create the module, don\'t worry I teach you.') -+ ); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> '#clippy', -+ 'intro' => __('We are going to fill the form.') -+ ); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> "#network_component_group", -+ 'intro' => __('Please choose the Network Management.') -+ ); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> "#network_component", -+ 'intro' => __('And choose the component with the name "Host Alive".') -+ ); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> "input[name='name']", -+ 'intro' => __('You can change the name.') -+ ); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> "input[name='ip_target']", -+ 'intro' => __('Check if this IP is the address of your machine.') -+ ); -+ $helps['monitoring_server_step_5']['steps'][] = array( -+ 'element'=> "input[name='crtbutton']", -+ 'intro' => __('And only to finish it is clicking this button.') -+ ); -+ $helps['monitoring_server_step_5']['conf'] = array(); -+ $helps['monitoring_server_step_5']['conf']['showBullets'] = 0; -+ $helps['monitoring_server_step_5']['conf']['showStepNumbers'] = 0; -+ $helps['monitoring_server_step_5']['conf']['next_help'] = 'monitoring_server_step_6'; -+ //================================================================== -+ -+ -+ //================================================================== -+ //Help tour about the monitoring with a ping (step 6) -+ //------------------------------------------------------------------ -+ $helps['monitoring_server_step_6'] = array(); -+ $helps['monitoring_server_step_6']['steps'] = array(); -+ $helps['monitoring_server_step_6']['steps'][] = array( -+ 'element'=> '#clippy', -+ 'intro' => __('Now, your module is just created.
And the status color is blue.
This meaning of blue status is the module is not executed for first time.
In the next seconds if there is not a problem, the status color will change to red or green.') -+ ); -+ $helps['monitoring_server_step_6']['conf'] = array(); -+ $helps['monitoring_server_step_6']['conf']['showBullets'] = 0; -+ $helps['monitoring_server_step_6']['conf']['showStepNumbers'] = 0; -+ //================================================================== -+ -+ -+ clippy_write_javascript_helps_steps($helps, false); -+} -+?> -\ No newline at end of file -Index: include/help/clippy/module_unknow.php -=================================================================== ---- include/help/clippy/module_unknow.php (revision 0) -+++ include/help/clippy/module_unknow.php (revision 10417) -@@ -0,0 +1,55 @@ -+ '{clippy}', //The template to replace with the autogenerate id -+ 'intro' => '
'; - -+ -+ - if (! defined ('METACONSOLE')) { -+ - $list = treeview_getData ($type); -+ - } - else { -- $servers = db_get_all_rows_sql ("SELECT * FROM tmetaconsole_setup WHERE disabled = 0"); -+ $servers = db_get_all_rows_sql (" -+ SELECT * -+ FROM tmetaconsole_setup -+ WHERE disabled = 0"); -+ - if ($servers === false) { - $servers = array(); - } -@@ -502,6 +510,8 @@ - metaconsole_restore_db(); - } - -+ -+ - if ($list === false) { - ui_print_error_message(__('There aren\'t agents in this agrupation')); - echo '
' . -+ '' . -+ '' . -+ '' . -+ '' . -+ '' . -+ '' . -+ '
' . -+ __('You have unknown modules in this agent.') . -+ '
' . -+ __('Unknown modules are modules which receive data normally at least in one occassion, but at this time are not receving data. Please check our troubleshoot help page to help you determine why you have unknown modules.') . -+ ui_print_help_icon ('context_module_unknow', true, '', 'images/help_w.png') . -+ '
' -+ ); -+ $helps['module_unknow']['conf'] = array(); -+ $helps['module_unknow']['conf']['autostart'] = false; -+ $helps['module_unknow']['conf']['showBullets'] = 0; -+ $helps['module_unknow']['conf']['showStepNumbers'] = 0; -+ $helps['module_unknow']['conf']['name_obj_tour'] = '{clippy_obj}'; -+ //================================================================== -+ -+ clippy_write_javascript_helps_steps($helps, true); -+} -+?> -\ No newline at end of file -Index: include/help/en/help_context_module_unknow.php -=================================================================== ---- include/help/en/help_context_module_unknow.php (revision 0) -+++ include/help/en/help_context_module_unknow.php (revision 10417) -@@ -0,0 +1,24 @@ -+ -+

Unknown modules in Pandora

-+

-+You may have unknown modules for many reasons. Unknown module is a special status for a module/monitor which means “I dont have recent data for this monitor and I should have data”. A monitor goes to unknown status when doesnt receive nothing in at least its interval (for example, 300 seconds) multiplied by two, in this case, if you doesn't receive nothing in ten minutes, monitor goes to unknown. -+

-+

-+These are a few cases where you can get unknown modules: -+

-+
    -+
  • Your pandora server is down. Restart it, dont forget to check /var/log/pandora/pandora_server.log to see why was down.
  • -+
  • Your tentacle server is down, and cannot get data from your Pandora FMS agents installed in your remote servers.
  • -+
  • You have a network problem between your agents and your server.
  • -+
  • Your pandora fms agent is stopped and is not sending information to your server.
  • -+
  • Your network is down, or the remote device you are trying to ask is down or changed it's IP address (for example for numerical SNMP remote queries).
  • -+
  • Your agent is reporting a badly synchronized date. Means reports a timedate in the past and that messup everything.
  • -+
  • The script / module before works now doesn't, that can be because something is happing in the agent, check it out.
  • -+
-+

-+Sometimes UNKNOWN status can be useful to monitor, so you can setup alerts on UNKNOWN status to warn you about that. -+

-\ No newline at end of file -Index: include/help/en/help_snmp_alert_field1.php -=================================================================== ---- include/help/en/help_snmp_alert_field1.php (revision 10314) -+++ include/help/en/help_snmp_alert_field1.php (working copy) -@@ -14,10 +14,10 @@ -

- You can use these macros in FieldX (1-10) of any alert -

--_DATA_: Full trap
--_AGENT_: Agent name
--_IP_: IP Address
--_TIMESTAMP_: Trap date
--_SNMP_OID_: Trap OID
--_SNMP_VALUE_: Trap OID value
-+_data_: Full trap
-+_agent_: Agent name
-+_address_: IP Address
-+_timestamp_: Trap date
-+_snmp_oid_: Trap OID
-+_snmp_value_: Trap OID value
-

-Index: include/help/es/help_snmp_alert_field1.php -=================================================================== ---- include/help/es/help_snmp_alert_field1.php (revision 10314) -+++ include/help/es/help_snmp_alert_field1.php (working copy) -@@ -14,10 +14,10 @@ -

- Puede usar esas macros en los campos FieldX (1-10) de cualquier alerta. -

--_DATA_: Trap entero
--_AGENT_: Nombre del Agente
--_IP_: Dirección IP
--_TIMESTAMP_: Fecha trap
--_SNMP_OID_: OID del trap
--_SNMP_VALUE_: Valor del OID del trap
-+_data_: Trap entero
-+_agent_: Nombre del Agente
-+_address_: Dirección IP
-+_timestamp_: Fecha trap
-+_snmp_oid_: OID del trap
-+_snmp_value_: Valor del OID del trap
-

-Index: include/help/ja/help_snmp_alert_field1.php -=================================================================== ---- include/help/ja/help_snmp_alert_field1.php (revision 10314) -+++ include/help/ja/help_snmp_alert_field1.php (working copy) -@@ -7,10 +7,17 @@ -

- - データフィールドがある場合、アラートでそれを利用する必要があります。この目的のために、特別な _snmp_fX_ というマクロを利用できます。これらのマクロは、SNMP トラップアラート以外では無効です。 -- -+

- メッセージを生成するには、フィールド1に次のような設定をします。 -- --Chassis Alert: _snmp_f2_ in device _snmp_f1_ -- --これらのマクロは、任意のアラートのフィールドX (1 から 10) で利用できます。 -+

-+ Chassis Alert: _snmp_f2_ in device _snmp_f1_ -+

-+任意のアラートのフィールドX (1 から 10) で以下のマクロを利用できます。 -+

-+_data_: トラップ全体
-+_agent_: エージェント名
-+_address_: IP アドレス
-+_timestamp_: トラップのタイムスタンプ
-+_snmp_oid_: トラップの OID
-+_snmp_value_: トラップ OID の値
-

-Index: include/config_process.php -=================================================================== ---- include/config_process.php (revision 10314) -+++ include/config_process.php (working copy) -@@ -247,4 +247,30 @@ - // cases (reverse proxy, others ports...). - //====================================================================== - $config["homeurl"] = ui_get_full_url(false); -+ -+ -+//====================================================================== -+// Get the version of DB manager -+//====================================================================== -+switch ($config["dbtype"]) { -+ case "mysql": -+ if (!isset($config['quote_string'])) { -+ $config['db_quote_string'] = "\""; -+ } -+ break; -+ case "postgresql": -+ if (!isset($config['dbversion'])) { -+ $result = db_get_sql("select version();"); -+ $result_chunks = explode(" ", $result); -+ -+ $config['dbversion'] = $result_chunks[1]; -+ } -+ if (!isset($config['quote_string'])) { -+ $config['db_quote_string'] = "'"; -+ } -+ break; -+ case "oracle": -+ break; -+} -+//====================================================================== - ?> -Index: include/functions_db.php -=================================================================== ---- include/functions_db.php (revision 10314) -+++ include/functions_db.php (working copy) -@@ -65,7 +65,8 @@ - if ($return === false) { - if ($critical) { - $login_screen = 'error_authconfig'; -- require($config['homeurl'] . '/general/error_screen.php'); -+ -+ require($config['homedir'] . '/general/error_screen.php'); - exit; - } - else if ($error == 0) { -@@ -108,6 +109,22 @@ - } - } - -+function db_encapsule_fields_with_same_name_to_instructions($field) { -+ global $config; -+ -+ switch ($config["dbtype"]) { -+ case "mysql": -+ return mysql_encapsule_fields_with_same_name_to_instructions($field); -+ break; -+ case "postgresql": -+ return postgresql_encapsule_fields_with_same_name_to_instructions($field); -+ break; -+ case "oracle": -+ return oracle_encapsule_fields_with_same_name_to_instructions($field); -+ break; -+ } -+} -+ - /** - * Adds an audit log entry (new function in 3.0) - * -Index: include/functions_extensions.php -=================================================================== ---- include/functions_extensions.php (revision 10314) -+++ include/functions_extensions.php (working copy) -@@ -99,11 +99,11 @@ - $dir = ENTERPRISE_DIR.'/'.EXTENSIONS_DIR; - - if (file_exists ($dir)) -- $handle = @opendir ($dir); -+ $handle = @opendir ($dir); - - if (empty ($handle)) - return; -- -+ - $file = readdir ($handle); - $extensions = array (); - $ignores = array ('.', '..'); -@@ -117,6 +117,10 @@ - $file = readdir ($handle); - continue; - } -+ -+ if ($file == "update_manager.php") -+ continue; -+ - $extension['file'] = $file; - $extension['operation_menu'] = ''; - $extension['godmode_menu'] = ''; -Index: ChangeLog -=================================================================== ---- ChangeLog (revision 10314) -+++ ChangeLog (working copy) -@@ -1,3 +1,425 @@ -+2014-08-14 Koichiro Kikuchi -+ -+ * pandora_console_install: Refactored code and added "fakeroot" -+ installation support. -+ -+2014-08-13 Junichi Satoh -+ -+ * pandoradb.sql: Fixed sql error with MySQL 5.6 when NO_ZERO_DATE -+ SQL mode is enabled. -+ -+2014-08-13 Junichi Satoh -+ -+ * mobile/operation/events.php: Improved to show event comment. -+ -+2014-08-12 Miguel de Dios -+ -+ * index.php, operation/agentes/ver_agente.php, -+ operation/agentes/estado_monitores.php, general/header.php, -+ include/functions_clippy.php, include/functions_ui.php, -+ include/help/en/help_context_module_unknow.php, -+ include/help/clippy/module_unknow.php, include/styles/pandora.css, -+ include/javascript/intro.js: added first version of context help -+ interactive. -+ -+2014-08-12 Miguel de Dios -+ -+ * include/functions_modules.php: killed some unicorns and magic -+ numbers into the function "modules_get_status". -+ -+2014-08-12 Miguel de Dios -+ -+ * images/clippy_icon.png, images/pandorin.png, -+ include/help/clippy/homepage.php, general/header.php: yes there is -+ a octopus another time in Pandora. -+ -+2014-08-12 Miguel de Dios -+ -+ * include/functions_clippy.php, -+ include/help/clippy/godmode_agentes_modificar_agente.php, -+ include/help/clippy/godmode_agentes_configurar_agente.php: fixed the -+ execution of help tour when never it started. Sorry the clippy is -+ less annoying. -+ -+2014-08-12 Miguel de Dios -+ -+ * include/functions_clippy.php: changed to modal version. -+ -+ * include/javascript/intro.js: added feature to avoid the exit, and -+ the pull request to original repository is solicited too -+ (https://github.com/usablica/intro.js/pull/311). -+ -+2014-08-12 Miguel de Dios -+ -+ * general/header.php, godmode/setup/setup_general.php, -+ include/functions_clippy.php, include/functions_config.php, -+ include/help/clippy/homepage.php: wip in the clippy. -+ -+2014-08-12 Sancho Lerena -+ -+ * pandoradb_data.sql: No more "welcome to Pandora FMS 5.0" -+ removed version code to allow the same text for next releases -+ :-) -+ -+2014-08-11 Miguel de Dios -+ -+ * include/help/clippy/godmode_agentes_modificar_agente.php, -+ include/help/clippy/homepage.php, -+ include/help/clippy/godmode_agentes_configurar_agente.php, -+ include/functions_clippy.php: wip in the clippy. -+ -+2014-08-11 Vanessa Gil -+ -+ * godmode/agentes/agent_template.php: Fixed bug in FF -+ threshold to apply a template module. Ticket #871. -+ -+2014-08-11 Vanessa Gil -+ -+ * godmode/agentes/agent_conf_gis.php: Altitude coordinate by -+ default. Fixed bug #766. -+ -+2014-08-08 Miguel de Dios -+ -+ * include/functions.php, -+ include/help/clippy/godmode_agentes_modificar_agente.php, -+ include/help/clippy/homepage.php, -+ include/help/clippy/godmode_agentes_configurar_agente.php, -+ include/javascript/intro.js, -+ include/javascript/introjs.css, -+ include/javascript/clippy.js, -+ include/functions_ui.php, -+ include/functions_clippy.php, -+ index.php, -+ general/header.php: first version of the new feature a annoying -+ clippy such as the lovely micro$oft mascot. -+ -+2014-08-07 Alejandro Gallardo -+ -+ * pandoradb.sql, -+ extras/pandoradb_migrate_5.0.x_to_5.1.mysql.sql, -+ extras/pandoradb_migrate_5.0.x_to_5.1.oracle.sql, -+ extras/pandoradb_migrate_5.0.x_to_5.1.postgreSQL.sql: -+ Modified the decimal precision of the column "post_process" -+ for the table 'tagente_modulo' (Ticket #1124). -+ -+2014-08-06 Sancho Lerena -+ -+ * extras/pandoradb_migrate_5.0.x_to_5.1.mysql.sql, -+ pandoradb.sql: Fixed bug introduced in commit 9604 -+ altering tagente_modulo.post_process double precission -+ making conversion from bytes to megabytes impossible -+ (0,00000095367432). Pending to fix also the interface for -+ module creation/edition which also fails. This is critical -+ for SP1 release :( -+ -+2014-08-05 Alejandro Gallardo -+ -+ * general/main_menu.php: Improved the submenus state -+ persistence functionality. -+ -+2014-08-05 Alejandro Gallardo -+ -+ * general/main_menu.php: Fixed the menu position when -+ it's fixed and the header's not. -+ -+ * include/functions_graph.php, -+ include/graphs/pandora.d3.js: Added colors to the elements -+ depending on their status on the functions 'sunburst' and -+ 'graph_monitor_wheel'. -+ -+ * include/styles/pandora.css: Fixed the z-index of the -+ shortcut bar. -+ -+2014-08-04 Alejandro Gallardo -+ -+ * general/header.php: Now the header can be configured -+ to be fixed at the top. -+ -+ * general/main_menu.php: Now the menu can be configured -+ to be fixed at the left. -+ -+ * godmode/setup/setup_visuals.php, -+ include/functions_config.php: Added new options to -+ enable the fixed header and menu. -+ -+ * include/styles/menu.css, -+ include/styles/pandora.css: Changes on the menu styles. -+ -+ -+2014-08-04 Miguel de Dios -+ -+ * include/functions_config.php, -+ include/functions_update_manager.php: some fixes into the update -+ manager. -+ -+2014-08-04 Alejandro Gallardo -+ -+ * general/main_menu.php: Now the submenus opened by the -+ user remain opened when navigating through Pandora FMS. -+ -+2014-08-04 Miguel de Dios -+ -+ * include/config_process.php: added global config var for the -+ quote strings (for example, PostgreSQL). -+ -+2014-08-03 Junichi Satoh -+ -+ * include/functions_ui.php: Fixed that the fast forward and the going -+ to the last of pagination doesn't work in the modal window for module -+ data display. -+ And fixed incorrect offset calculation for the fast forward. -+ -+2014-08-02 Junichi Satoh -+ -+ * operation/agentes/estado_monitores.php: Fixed that module data -+ display does not work correctly when time range mode is selected -+ and paginated. -+ -+2014-08-02 Junichi Satoh -+ -+ * operation/agentes/estado_agente.php: Fixed sql error. -+ -+2014-08-01 Miguel de Dios -+ -+ * godmode/agentes/planned_downtime.editor.php: fixed the acl. -+ -+ MERGED FROM THE BRANCH 5.0 -+ -+2014-07-31 Miguel de Dios -+ -+ * include/functions_networkmap.php, include/functions_graph.php, -+ include/db/postgresql.php, include/db/oracle.php, -+ include/functions_api.php, extensions/agents_alerts.php, -+ operation/search_main.php, operation/search_agents.getdata.php, -+ operation/agentes/status_monitor.php, -+ operation/agentes/networkmap.topology.php, -+ operation/agentes/ver_agente.php, -+ operation/search_modules.getdata.php, operation/search_results.php, -+ operation/events/events_list.php, -+ godmode/alerts/alert_list.builder.php, -+ godmode/alerts/configure_alert_template.php, -+ godmode/modules/manage_network_components_form.php, -+ godmode/reporting/reporting_builder.php, -+ godmode/reporting/map_builder.php: tiny fixes for the improve the -+ support of postgreSQL databases. -+ -+2014-07-30 Miguel de Dios -+ -+ * include/ajax/module.php: tiny fixes for the improve the support of -+ postgreSQL databases. -+ -+2014-07-30 Miguel de Dios -+ -+ * godmode/servers/manage_recontask.php, -+ godmode/servers/manage_recontask_form.php, -+ include/functions_treeview.php, include/ajax/module.php, -+ include/functions_reporting.php, include/db/postgresql.php, -+ include/functions_servers.php, operation/agentes/estado_agente.php, -+ operation/tree.php: tiny fixes for the improve -+ the support of postgreSQL databases. -+ -+2014-07-29 Miguel de Dios -+ -+ * include/functions_graph.php, include/functions_reporting.php, -+ operation/agentes/estado_monitores.php: tiny fixes for the improve -+ the support of postgreSQL databases. -+ -+2014-07-29 Junichi Satoh -+ -+ * include/functions_events.php: Fixed a bug that event's comment -+ is not shown when it includes newline. -+ -+2014-07-28 Junichi Satoh -+ -+ * operation/agentes/estado_agente.php: Fixed sql error. -+ -+2014-07-24 Miguel de Dios -+ -+ * operation/snmpconsole/snmp_view.php, -+ operation/events/events_list.php, operation/incidents/incident.php, -+ extensions/files_repo.php, -+ extensions/files_repo/sql/files_repo.postgreSQL.sql, -+ extensions/files_repo/functions_files_repo.php, -+ extensions/files_repo/files_repo_list.php, -+ godmode/agentes/modificar_agente.php, -+ godmode/snmpconsole/snmp_alert.php, godmode/db/db_info.php, -+ include/functions_graph.php, include/functions_db.php, -+ include/db/postgresql.php, include/db/oracle.php, -+ include/db/mysql.php, include/functions_update_manager.php, -+ include/functions_events.php, include/graphs/functions_flot.php, -+ include/graphs/fgraph.php: tiny fixes for the improve the support of -+ postgreSQL databases. -+ -+2014-07-23 Miguel de Dios -+ -+ * extensions/module_groups.php, extensions/agents_alerts.php, -+ include/functions_agents.php, operation/agentes/exportdata.php: tiny -+ fixes for the improve the support of postgreSQL databases. -+ -+ * include/functions_db.php: fix blank screen when the connection -+ fail, now it shows the error message again. -+ -+2014-07-23 Miguel de Dios -+ -+ * include/config_process.php, operation/agentes/status_monitor.php, -+ operation/agentes/estado_generalagente.php, -+ operation/agentes/estado_agente.php: tiny fixes for the improve the -+ support of postgreSQL databases. -+ -+2014-07-23 Miguel de Dios -+ -+ * include/functions_servers.php, include/functions_reporting.php: -+ tiny fixes for the improve the support of postgreSQL databases. -+ -+2014-07-23 Miguel de Dios -+ -+ * operation/agentes/estado_generalagente.php: fixed the show the -+ agent access box when the agent is new without data. -+ -+ INCIDENT: #1078 -+ -+2014-07-23 Miguel de Dios -+ -+ * godmode/agentes/agent_wizard.snmp_explorer.php, -+ godmode/agentes/module_manager_editor_plugin.php: some fixes for -+ the snmp version 3. -+ -+2014-07-22 Juan Manuel Ramon -+ -+ * include/ajax/events.php: Fixed custom fields view in -+ metaconsole event extended view. -+ -+ This is my last commit for Pandora guys! Bye ;-) -+ -+2014-07-22 Miguel de Dios -+ -+ * godmode/agentes/agent_wizard.snmp_explorer.php, -+ include/functions.php: some fixes for the snmp v3. -+ -+2014-07-22 Miguel de Dios -+ -+ * godmode/agentes/agent_manager.php: fixed to show the QR code image -+ in the creation of a new agent. -+ -+2014-07-21 Miguel de Dios -+ -+ * pandoradb.postgreSQL.sql: fixed the SQL. -+ -+2014-07-18 Miguel de Dios -+ -+ * include/functions_graph.php, include/functions_reporting.php: -+ fixed to show the unknown graph in simple graph. -+ -+ INCIDENT: #1035 -+ -+2014-07-17 Miguel de Dios -+ -+ * include/auth/ldap.php, include/auth/mysql.php: fixed the -+ parameters with white spaces. -+ -+ INCIDENT: #1063 -+ -+2014-07-17 Miguel de Dios -+ -+ * include/functions_groups.php: added parameter to avoid the check -+ the propagation in the function "groups_get_childrens". -+ -+ * include/functions_networkmap.php, -+ operation/agentes/networkmap.php, -+ operation/agentes/networkmap.topology.php: added feature to show the -+ agents in subgroups (or not). -+ -+ INCIDENT: #1018 -+ -+2014-07-14 Vanessa Gil -+ -+ * godmode/admin_access_log.php -+ include/functions.php: Added export to csv. -+ -+ * godmode/audit_log_csv.php: Added file. -+ -+2014-07-10 Miguel de Dios -+ -+ * include/functions_api.php: fixed the call "set_update_agent" -+ because before the call get the id_server but this data never -+ was translated to name_server. And added id_server into the call -+ "get_pandora_servers" in the last position. -+ -+2014-07-10 Miguel de Dios -+ -+ * include/functions_api.php: restored the parameter name server in -+ the api call "set_new_agent", thanks KOSAKA. -+ -+2014-07-10 Junichi Satoh -+ -+ * include/help/ja/help_snmp_alert_field1.php: Updated help. -+ -+2014-07-09 Mario Pulido -+ -+ * include/help/ja/help_snmp_alert_field1.php: Added macros snmp alert help -+ -+2014-07-09 Junichi Satoh -+ -+ * include/help/ja/help_snmp_alert_field1.php: Updated help. -+ -+2014-07-09 Junichi Satoh -+ -+ * include/functions_events.php, operation/events/events.php, -+ operation/events/events_list.php: Replaced json_encode() -+ with io_json_mb_encode() to avoid invalid encoding with multi-byte -+ characters. -+ -+2014-07-08 Mario Pulido -+ -+ * include/help/en/help_snmp_alert_field1.php, -+ include/help/es/help_snmp_alert_field1.php: Change macros snmp alert help -+ -+2014-07-08 Hirofumi Kosaka -+ -+ * include/functions_api.php: Fixed that 'set enable_module' -+ had not worked. -+ -+ MERGED FROM BRANCH 5.0 -+ -+2014-07-07 Miguel de Dios -+ -+ * include/functions_visual_map.php: show in the tooltip of -+ "static graph" the last value of module. -+ -+ INCIDENT: #1014 -+ -+2014-07-07 Miguel de Dios -+ -+ * godmode/setup/license.php: fixed the white screen. -+ -+ INCIDENT: #996 -+ -+2014-07-07 Miguel de Dios -+ -+ * operation/agentes/alerts_status.php: fixed the pagination with -+ the column sorted. -+ -+ INCIDENT: #977 -+ -+2014-07-04 Alejandro Gallardo -+ -+ * index.php: Now the shortcut bar isn't loaded while -+ the pandora console is in fullscreen mode. -+ -+2014-07-04 Ramon Novoa -+ -+ * include/functions_graph.php: When drawing charts, propagate the last value -+ in the database instead of the value of the last interval (which is the -+ average value for that interval). -+ -+ * operation/agentes/estado_monitores.php: Show events for boolean modules by default. -+ -+2014-07-04 Miguel de Dios -+ -+ * include/functions_config.php, include/functions_extensions.php: -+ fixed the show old update manager and set the correct link in the -+ header warning message to update manager. -+ - 2014-06-30 Koichiro KIKUCHI - - * operation/agentes/estado_monitores.php, -Index: pandoradb.sql -=================================================================== ---- pandoradb.sql (revision 10314) -+++ pandoradb.sql (working copy) -@@ -203,7 +203,7 @@ - `plugin_pass` text, - `plugin_parameter` text, - `id_plugin` int(10) default '0', -- `post_process` double default NULL, -+ `post_process` double(18,15) default 0, - `prediction_module` bigint(14) default '0', - `max_timeout` int(4) unsigned default '0', - `max_retries` int(4) unsigned default '0', -@@ -490,7 +490,7 @@ - CREATE TABLE IF NOT EXISTS `talert_special_days` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `id_group` INT(10) NOT NULL DEFAULT 0, -- `date` date NOT NULL DEFAULT '0000-00-00', -+ `date` date NOT NULL DEFAULT '1970-01-01', - `same_day` enum('monday','tuesday','wednesday','thursday','friday','saturday','sunday') NOT NULL DEFAULT 'sunday', - `description` text, - PRIMARY KEY (`id`) -Index: pandoradb.postgreSQL.sql -=================================================================== ---- pandoradb.postgreSQL.sql (revision 10314) -+++ pandoradb.postgreSQL.sql (working copy) -@@ -26,7 +26,8 @@ - - --\c "pandora" - --CREATE OR REPLACE LANGUAGE plpgsql; -+-- For previous PostgreSQL version 9.0 -+CREATE LANGUAGE plpgsql; - - CREATE OR REPLACE FUNCTION unix_timestamp(TIMESTAMP without time zone = CURRENT_TIMESTAMP) RETURNS double precision AS 'SELECT ceil(date_part(''epoch'', $1)); ' LANGUAGE SQL; - -@@ -240,10 +241,10 @@ - "disabled_types_event" TEXT default '', - "module_macros" TEXT default '', - "min_ff_event_normal" INTEGER default 0, -- "min_ff_event_warning" INTEGER default 0, -- "min_ff_event_critical" INTEGER default 0, -- "each_ff" SMALLINT default 0, -- "ff_timeout" INTEGER unsigned default 0 -+ "min_ff_event_warning" INTEGER default 0, -+ "min_ff_event_critical" INTEGER default 0, -+ "each_ff" SMALLINT default 0, -+ "ff_timeout" INTEGER default 0 - ); - CREATE INDEX "tagente_modulo_id_agente_idx" ON "tagente_modulo"("id_agente"); - CREATE INDEX "tagente_modulo_id_tipo_modulo_idx" ON "tagente_modulo"("id_tipo_modulo"); -@@ -1595,7 +1596,7 @@ - -- ----------------------------------------------------- - -- Table `tevent_response` - -- ----------------------------------------------------- --CREATE TABLE IF NOT EXISTS "tevent_response" ( -+CREATE TABLE "tevent_response" ( - "id" SERIAL NOT NULL PRIMARY KEY, - "name" varchar(600) NOT NULL default '', - "description" TEXT, -@@ -1611,7 +1612,7 @@ - -- --------------------------------------------------------------------- - -- Table "tcategory" - -- --------------------------------------------------------------------- --CREATE TABLE IF NOT EXISTS "tcategory" ( -+CREATE TABLE "tcategory" ( - "id" SERIAL NOT NULL PRIMARY KEY, - "name" varchar(600) NOT NULL default '' - ); -Index: pandora_console_install -=================================================================== ---- pandora_console_install (revision 10314) -+++ pandora_console_install (working copy) -@@ -11,92 +11,103 @@ - - PI_VERSION=4.0 - FORCE=0 -+DESTDIR="" - LOG_TIMESTAMP=`date +"%Y/%m/%d %H:%M:%S"` - MODE=$1 - -+# -+# set_global_vars -+# Check platform and set DISTRO, OS_VERSION, WWWUSER, WWWGROUP, WWWROOT, -+# PANDORA_HOME and PANDORA_HOME_GROUP. -+# -+set_global_vars () { -+ DISTRO="GENERIC" - --get_distro () { -- -- OS_NAME=`uname -s` -- -- # Get Linux Distro type and version -- if [ -f "/etc/SuSE-release" ] -- then -- OS_VERSION=`cat /etc/SuSE-release | grep VERSION | cut -f 3 -d " "` -- LINUX_DISTRO=SUSE -- else -- if [ -f "/etc/lsb-release" ] && [ ! -f "/etc/redhat-release" ] -+ case `uname -s` in -+ Linux) -+ # Get Linux Distro type and version -+ if [ -f "/etc/SuSE-release" ] - then -+ OS_VERSION=`cat /etc/SuSE-release | grep VERSION | cut -f 3 -d " "` -+ DISTRO=SUSE -+ elif [ -f "/etc/lsb-release" ] && [ ! -f "/etc/redhat-release" ] -+ then - OS_VERSION=`cat /etc/lsb-release | grep DISTRIB_RELEASE | cut -f 2 -d "="` -- LINUX_DISTRO=UBUNTU -+ DISTRO=UBUNTU - OS_VERSION="UBUNTU $OS_VERSION" -- else -- if [ -f "/etc/debian_version" ] -- then -- OS_VERSION=`cat /etc/debian_version` -- OS_VERSION="DEBIAN $OS_VERSION" -- LINUX_DISTRO=DEBIAN -- else -- if [ -f "/etc/fedora-release" ] -- then -- OS_VERSION=`cat /etc/fedora-release | cut -f 4 -d " "` -- OS_VERSION="FEDORA $OS_VERSION" -- LINUX_DISTRO=FEDORA -- else -- if [ -f "/etc/redhat-release" ] -- then -- LINUX_DISTRO=RHEL_CENTOS -- else -- if [ "$OS_NAME" = "FreeBSD" ] -- then -- LINUX_DISTRO=FreeBSD -- else -- if [ "$OS_NAME" = "NetBSD" ] -- then -- LINUX_DISTRO=NetBSD -- else -- LINUX_DISTRO=GENERIC -- fi -- fi -- OS_VERSION=`uname -r` -- fi -- fi -- fi -+ elif [ -f "/etc/debian_version" ] -+ then -+ OS_VERSION=`cat /etc/debian_version` -+ OS_VERSION="DEBIAN $OS_VERSION" -+ DISTRO=DEBIAN -+ elif [ -f "/etc/fedora-release" ] -+ then -+ OS_VERSION=`cat /etc/fedora-release | cut -f 4 -d " "` -+ OS_VERSION="FEDORA $OS_VERSION" -+ DISTRO=FEDORA -+ elif [ -f "/etc/redhat-release" ] -+ then -+ DISTRO=RHEL_CENTOS - fi -+ case $DISTRO in -+ SUSE) -+ WWWUSER=wwwrun -+ WWWGROUP=www -+ PANDORA_HOME_GROUP=root -+ WWWROOT=/srv/www/htdocs -+ ;; -+ UBUNTU|DEBIAN) -+ WWWUSER=www-data -+ WWWGROUP=www-data -+ WWWROOT=/var/www -+ ;; -+ FEDORA|RHEL_CENTOS) -+ WWWUSER=apache -+ WWWGROUP=apache -+ WWWROOT=/var/www/html -+ ;; -+ esac -+ ;; -+ FreeBSD) -+ DISTRO=FreeBSD -+ WWWUSER=www -+ WWWGROUP=www -+ WWWROOT=/usr/local/www -+ -+ local apache -+ for apache in apache24 apache22 -+ do -+ [ ! -d $WWWROOT/$apache ] && continue -+ WWWROOT=$WWWROOT/$apache/data -+ break -+ done -+ ;; -+ NetBSD) -+ DISTRO=NetBSD -+ WWWUSER=www -+ WWWGROUP=www -+ WWWROOT=/usr/pkg/share/httpd/htdocs -+ ;; -+ esac -+ -+ # backward compatible defaults (Assuming SUSE) -+ if [ "$DISTRO" = GENERIC ] -+ then -+ WWWUSER=wwwrun -+ WWWGROUP=www -+ WWWROOT=/srv/www/htdocs -+ PANDORA_HOME_GROUP=root - fi -- echo $LINUX_DISTRO -+ # Use WWWGROUP as default for PANDORA_HOME_GROUP -+ : ${PANDORA_HOME_GROUP:=$WWWGROUP} -+ -+ OS_VERSION=`uname -r` -+ PANDORA_HOME="$WWWROOT/pandora_console" - } - - uninstall () { -- DISTRO=`get_distro` -+ set_global_vars - -- if [ "$DISTRO" = "UBUNTU" ] -- then -- PANDORA_HOME=/var/www/pandora_console -- else -- if [ "$DISTRO" = "RHEL_CENTOS" ] -- then -- PANDORA_HOME=/var/www/html/pandora_console -- else -- if [ "$DISTRO" = "FEDORA" ] -- then -- PANDORA_HOME=/var/www/html/pandora_console -- else -- if [ "$DISTRO" = "FreeBSD" ] -- then -- PANDORA_HOME="/usr/local/www/data/pandora_console /usr/local/www/apache24/data/pandora_console /usr/local/www/apache22/data/pandora_console" -- else -- if [ "$DISTRO" = "NetBSD" ] -- then -- PANDORA_HOME="/usr/pkg/share/httpd/htdocs/pandora_console" -- else -- PANDORA_HOME=/srv/www/htdocs/pandora_console -- fi -- fi -- fi -- fi -- fi -- - echo "Removing Pandora FMS Console" - rm -Rf $PANDORA_HOME - echo "You need to drop manually pandora database from your Database server" -@@ -104,81 +115,43 @@ - } - - install () { -+ set_global_vars - -- DISTRO=`get_distro` - OLDFILENAMETMP=`date +"%Y-%m-%d"` -- -- if [ "$DISTRO" = "UBUNTU" ] -- then -- PANDORA_HOME=/var/www/pandora_console -- PANDORA_CONF=$PANDORA_HOME/include/config.php -- else -- if [ "$DISTRO" = "RHEL_CENTOS" ] -- then -- PANDORA_HOME=/var/www/html/pandora_console -- PANDORA_CONF=$PANDORA_HOME/include/config.php -- else -- if [ "$DISTRO" = "FEDORA" ] -- then -- PANDORA_HOME=/var/www/html/pandora_console -- PANDORA_CONF=$PANDORA_HOME/include/config.php -- else -- if [ "$DISTRO" = "FreeBSD" ] -- then -- if [ -d /usr/local/www/apache24 ] -- then -- PANDORA_HOME=/usr/local/www/apache24/data/pandora_console -- else -- if [ -d /usr/local/www/apache22 ] -- then -- PANDORA_HOME=/usr/local/www/apache22/data/pandora_console -- else -- PANDORA_HOME=/usr/local/www/data/pandora_console -- fi -- fi -- PANDORA_CONF=$PANDORA_HOME/include/config.php -- else -- if [ "$DISTRO" = "NetBSD" ] -- then -- PANDORA_HOME=/usr/pkg/share/httpd/htdocs/pandora_console -- PANDORA_CONF=$PANDORA_HOME/include/config.php -- else -- PANDORA_HOME=/srv/www/htdocs/pandora_console -- PANDORA_CONF=$PANDORA_HOME/include/config.php -- fi -- fi -- fi -- fi -- fi -+ PANDORA_CONF=$PANDORA_HOME/include/config.php - - echo "Detecting operating system: $DISTRO" - -- if [ -f $PANDORA_HOME ] && [ "$FORCE" = "0" ] -+ if [ -f $DESTDIR$PANDORA_HOME ] && [ "$FORCE" = "0" ] - then - echo "Seems that default dir already exists. Please use --force to" -- echo "force installer to install on $PANDORA_HOME" -+ echo "force installer to install on $DESTDIR$PANDORA_HOME" - exit - else -- echo "Checking default dir $PANDORA_HOME..." -+ echo "Checking default dir $DESTDIR$PANDORA_HOME..." - fi - -- # Create directories -- echo "Creating Pandora FMS Console home directory at $PANDORA_HOME ..." -- mkdir -p $PANDORA_HOME 2> /dev/null -- -- # Copying Pandora FMS console -- echo "Copying Pandora FMS Console to $PANDORA_HOME.." -- cp -R * $PANDORA_HOME -- chmod -R u+rwX,g+rX,g-w,o-rwx $PANDORA_HOME -- -- -- # Creating 'pandora' user -+ # Check and create 'pandora' user if needed - id pandora 2> /dev/null - if [ $? -eq 0 ]; then - echo " " - echo "User pandora does exist, skipping this step" -+ elif [ "$DESTDIR" ] -+ then -+ # don't create user with "fakeroot" installation -+ echo "User 'pandora' does not exist. All chown operations may fail." -+ echo "You should manualy set proper ownership to $DESTDIR$PANDORA_HOME and $DESTDIR$PANDORA_SPOOL if it's required." -+ echo - else -- echo "Creating 'pandora' user" -+ echo "Are you sure we can create a standard 'pandora' user locally? [y/N]" -+ read AREYOUSURE -+ if [ "$AREYOUSURE" != "y" ] -+ then -+ echo "Please create the 'pandora' user manually according to your authentication scheme, then start again the installation" -+ echo "Aborting..." -+ exit 1 -+ fi -+ # creating user - if [ "$DISTRO" = "FreeBSD" ] - then - echo "pandora:41121:::::Pandora FMS:/home/pandora:/usr/sbin/nologin:" | adduser -f - -w no 2> /dev/null -@@ -190,46 +163,31 @@ - fi - fi - -- if [ ! -d /var/spool/pandora ] -- then -- mkdir -p /var/spool/pandora -- fi -+ # Create directories -+ echo "Creating Pandora FMS Console home directory at $DESTDIR$PANDORA_HOME ..." -+ mkdir -p $DESTDIR$PANDORA_HOME 2> /dev/null - -+ # Copying Pandora FMS console -+ echo "Copying Pandora FMS Console to $DESTDIR$PANDORA_HOME.." -+ cp -R * $DESTDIR$PANDORA_HOME -+ chmod -R u+rwX,g+rX,g-w,o-rwx $DESTDIR$PANDORA_HOME -+ -+ # prepare /var/spool/pandora/data_in and sub directories -+ for subdir in collections conf md5 netflow -+ do -+ [ ! -d $DESTDIR/var/spool/pandora/data_in/$subdir ] && mkdir -p $DESTDIR/var/spool/pandora/data_in/$subdir -+ done -+ - #Ownership -- if [ "$DISTRO" = "UBUNTU" ] -- then -- chown -R www-data:root $PANDORA_HOME -- chown -R pandora:www-data /var/spool/pandora/ -- else -- if [ "$DISTRO" = "RHEL_CENTOS" ] -- then -- chown -R apache:apache $PANDORA_HOME -- chown -R pandora:apache /var/spool/pandora/ -- else -- if [ "$DISTRO" = "FEDORA" ] -- then -- chown -R apache:apache $PANDORA_HOME -- chown -R pandora:apache /var/spool/pandora/ -- else -- if [ "$DISTRO" = "FreeBSD" -o "$DISTRO" = "NetBSD" ] -- then -- chown -R www:www $PANDORA_HOME -- chown -R pandora:www /var/spool/pandora/ -- else -- # Assuming SUSE -- chown -R wwwrun:root $PANDORA_HOME -- chown -R pandora:www /var/spool/pandora/ -- fi -- fi -- fi -- fi -+ chown -R $WWWUSER:$PANDORA_HOME_GROUP $DESTDIR$PANDORA_HOME 2> /dev/null -+ chown -R pandora:$WWWGROUP $DESTDIR/var/spool/pandora/ 2> /dev/null - - echo "Setting secure permissions for Pandora FMS spool dir..." -- chmod -R u+rwX,g+rwX,o-rwx /var/spool/pandora/ -+ chmod -R u+rwX,g+rwX,o-rwx $DESTDIR/var/spool/pandora/ - - echo "Done." - echo " " -- echo "You have your Pandora FMS console installed on $PANDORA_HOME." -+ echo "You have your Pandora FMS console installed on $DESTDIR$PANDORA_HOME." - echo " " - echo "Now you can setup your Pandora FMS console and install" - echo "database using a browser and point to: " -@@ -240,17 +198,40 @@ - } - - help () { -+ echo "Syntax": -+ echo -+ echo " ./pandora_console_install < --mode > [ --option ]" -+ echo " " -+ echo "Modes:" -+ echo - echo " --force-install To force installation if already installed on this system" - echo " --install To install Pandora FMS Console on this system" -- echo " " -+ echo " --uninstall To uninstall/remove Pandora FMS Console on this System" -+ echo -+ echo "Option:" -+ echo -+ echo " --destdir DIR Specify root directory for \"fakeroot\" installation" -+ echo - } - - # Script banner at start - echo " " --echo "Pandora FMS Console Installer $PI_VERSION (c) 2008-2011 ArticaST" -+echo "Pandora FMS Console Installer $PI_VERSION (c) 2008-2014 ArticaST" - echo "This program is licensed under GPL2 Terms. http://pandorafms.com" - echo " " - -+# parse option -+if [ "$2" = "--destdir" ] -+then -+ if [ -z "$3" ] -+ then -+ echo '"--datadir" option requires an argument' -+ help -+ exit 1 -+ fi -+ DESTDIR="$3" -+fi -+ - case "$MODE" in - - '--force-install') -Index: index.php -=================================================================== ---- index.php (revision 10314) -+++ index.php (working copy) -@@ -355,6 +355,7 @@ - * Load here, because if not, some extensions not load well, I don't why. - */ - -+$config['logged'] = false; - extensions_load_extensions ($config['extensions']); - if ($process_login) { - /* Call all extensions login function */ -@@ -376,6 +377,8 @@ - - //Set the initial global counter for chat. - users_get_last_global_counter('session'); -+ -+ $config['logged'] = true; - } - - //Get old parameters before navigation. -@@ -562,7 +565,9 @@ - require("general/logon_ok.php"); - } - } -- require("general/shortcut_bar.php"); -+ if ($config["pure"] == 0) { -+ require("general/shortcut_bar.php"); -+ } - } - - if ($config["pure"] == 0) { -@@ -583,6 +588,11 @@ - require ("general/footer.php"); - echo ''; - } -+ -+/// Clippy function -+require_once('include/functions_clippy.php'); -+clippy_start($sec2); -+ - while (@ob_end_flush ()); - - db_print_database_debug (); -Index: extensions/agents_alerts.php -=================================================================== ---- extensions/agents_alerts.php (revision 10314) -+++ extensions/agents_alerts.php (working copy) -@@ -172,13 +172,18 @@ - echo "".html_print_image("images/darrowleft.png",true, array('title' => __('Previous templates')))." "; - } - -+ $templates_raw = array(); - if (!empty($templates)) { - $sql = sprintf('SELECT id, name -- FROM talert_templates WHERE id IN (%s)',implode(',',array_keys($templates))); -+ FROM talert_templates -+ WHERE id IN (%s)',implode(',',array_keys($templates))); - - $templates_raw = db_get_all_rows_sql($sql); - } - -+ if (empty($templates_raw)) -+ $templates_raw = array(); -+ - $alerts = array(); - $ntemplates = 0; - foreach ($templates_raw as $temp) { -@@ -225,7 +230,7 @@ - if($anyfired) { - $cellstyle = 'background:'.COL_ALERTFIRED.';'; - } -- -+ - echo ' '; - - $uniqid = uniqid(); -@@ -266,9 +271,12 @@ - $data[0] = modules_get_agentmodule_name ($alert['id_agent_module']); - - $actions = alerts_get_alert_agent_module_actions ($alert['id']); -- -- $actionDefault = db_get_value_sql("SELECT id_alert_action FROM talert_templates WHERE id = " . $alert['id_alert_template']); - -+ $actionDefault = db_get_value_sql(" -+ SELECT id_alert_action -+ FROM talert_templates -+ WHERE id = " . $alert['id_alert_template']); -+ - $actionText = ''; - - if (!empty($actions)) { -@@ -284,10 +292,13 @@ - } - else { - if (!empty($actionDefault)) { -- $actionText = db_get_sql ("SELECT name FROM talert_actions WHERE id = $actionDefault"). " (".__("Default") . ")"; -+ $actionText = db_get_sql ("SELECT name -+ FROM talert_actions -+ WHERE id = $actionDefault") . -+ " (" . __("Default") . ")"; - } - } -- -+ - $data[1] = $actionText; - $data[2] = ui_print_timestamp ($alert["last_fired"], true); - -Index: extensions/files_repo/sql/files_repo.postgreSQL.sql -=================================================================== ---- extensions/files_repo/sql/files_repo.postgreSQL.sql (revision 10314) -+++ extensions/files_repo/sql/files_repo.postgreSQL.sql (working copy) -@@ -1,2 +1,2 @@ --CREATE TABLE IF NOT EXISTS "tfiles_repo" ("id" SERIAL NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "description" VARCHAR(500) NULL default '', "hash" VARCHAR(8) NULL default ''); --CREATE TABLE IF NOT EXISTS "tfiles_repo_group" ("id" SERIAL NOT NULL PRIMARY KEY, "id_file" INTEGER NOT NULL REFERENCES tfiles_repo("id") ON DELETE CASCADE, "id_group" INTEGER NOT NULL); -+CREATE TABLE "tfiles_repo" ("id" SERIAL NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "description" VARCHAR(500) NULL default '', "hash" VARCHAR(8) NULL default ''); -+CREATE TABLE "tfiles_repo_group" ("id" SERIAL NOT NULL PRIMARY KEY, "id_file" INTEGER NOT NULL REFERENCES tfiles_repo("id") ON DELETE CASCADE, "id_group" INTEGER NOT NULL); -Index: extensions/files_repo/functions_files_repo.php -=================================================================== ---- extensions/files_repo/functions_files_repo.php (revision 10314) -+++ extensions/files_repo/functions_files_repo.php (working copy) -@@ -125,31 +125,33 @@ - - function files_repo_get_files ($filter = false, $count = false) { - global $config; -- -+ - // Don't use the realpath for the download links! - $files_repo_path = io_safe_output($config['attachment_store'])."/files_repo"; -- -- $sql = "SELECT * FROM tfiles_repo " . db_format_array_where_clause_sql($filter, "AND", "WHERE"); -+ -+ $sql = "SELECT * -+ FROM tfiles_repo -+ " . db_format_array_where_clause_sql($filter, "AND", "WHERE"); - $files = db_get_all_rows_sql($sql); -- -+ - if ($files === false) - $files = array(); -- -+ - $user_groups = files_repo_get_user_groups($config['id_user']); -- -+ - $files_data = array(); - foreach ($files as $file) { -- -+ - $file_groups = files_repo_get_file_groups($file['id']); - $permission = files_repo_check_file_acl ($file['id'], $config['id_user'], $file_groups, $user_groups); - if (!$permission) { - continue; - } -- -+ - $data = array(); - $data['name'] = $file['name']; - $data['description'] = $file['description']; -- $data['location'] = $files_repo_path."/".$file['id']."_".$data['name']; -+ $data['location'] = $files_repo_path . "/" . $file['id']."_".$data['name']; - // Size in bytes - $data['size'] = filesize($data['location']); - // Last modification time in unix timestamp -@@ -158,7 +160,7 @@ - $data['hash'] = $file['hash']; - $files_data[$file['id']] = $data; - } -- -+ - if ($count) { - $files_data = count($files_data); - } -Index: extensions/files_repo/files_repo_list.php -=================================================================== ---- extensions/files_repo/files_repo_list.php (revision 10314) -+++ extensions/files_repo/files_repo_list.php (working copy) -@@ -17,16 +17,19 @@ - - global $config; - --$full_extensions_dir = $config['homedir']."/".EXTENSIONS_DIR."/"; --require_once ($full_extensions_dir."files_repo/functions_files_repo.php"); -+$full_extensions_dir = $config['homedir'] . "/" . EXTENSIONS_DIR . "/"; -+require_once ($full_extensions_dir . -+ "files_repo/functions_files_repo.php"); - - $offset = (int) get_parameter('offset'); - $filter = array(); - $filter['limit'] = $config['block_size']; - $filter['offset'] = $offset; - $filter['order'] = array('field' => 'id', 'order' => 'DESC'); -+ - $files = files_repo_get_files($filter); - -+ - if (!empty($files)) { - - echo "
"; -Index: extensions/module_groups.php -=================================================================== ---- extensions/module_groups.php (revision 10314) -+++ extensions/module_groups.php (working copy) -@@ -141,7 +141,8 @@ - GROUP BY estado"; - break; - case "postgresql": -- $sql = "SELECT COUNT(id_agente) AS count, case utimestamp when 0 then 5 else estado end as estado -+ $sql = "SELECT COUNT(id_agente) AS count, -+ case utimestamp when 0 then 5 else estado end as estado - FROM tagente_estado - WHERE id_agente IN - (SELECT id_agente FROM tagente WHERE id_grupo = %d AND disabled = 0) -@@ -149,7 +150,7 @@ - (SELECT id_agente_modulo - FROM tagente_modulo - WHERE id_module_group = %d AND disabled = 0 AND delete_pending = 0) -- GROUP BY estado"; -+ GROUP BY estado, utimestamp"; - break; - case "oracle": - $sql = "SELECT COUNT(id_agente) AS count, case when utimestamp = 0 then 5 else estado end estado -@@ -185,7 +186,8 @@ - //Metaobject use in html_print_table - $table = null; - $table->align[0] = 'right'; //Align to right the first column. -- $table->style[0] = 'color: #ffffff; background-color: #778866; font-weight: bolder;'; -+ $table->style[0] = 'color: #ffffff; '. -+ 'background-color: #778866; font-weight: bolder;'; - $table->head = $head; - $table->width = '98%'; - -@@ -201,7 +203,7 @@ - - foreach ($modelGroups as $idModelGroup => $modelGroup) { - $fired = false; -- $query = sprintf($sql,$idAgentGroup, $idModelGroup); -+ $query = sprintf($sql, $idAgentGroup, $idModelGroup); - - $rowsDB = db_get_all_rows_sql ($query); - -Index: extensions/files_repo.php -=================================================================== ---- extensions/files_repo.php (revision 10314) -+++ extensions/files_repo.php (working copy) -@@ -18,12 +18,14 @@ - function pandora_files_repo_install () { - global $config; - -+ - if (isset($config['files_repo_installed'])) { - if ($config['files_repo_installed'] == 1) { - return; - } - } -- -+ -+ - $full_extensions_dir = $config['homedir']."/".EXTENSIONS_DIR."/"; - $full_sql_dir = $full_extensions_dir."files_repo/sql/"; - -@@ -40,6 +42,7 @@ - break; - } - -+ - foreach ($sentences as $sentence) { - if (trim ($sentence) == "") - continue; -@@ -61,22 +64,22 @@ - - switch ($config["dbtype"]) { - case "mysql": -- db_process_sql ('DROP TABLE `tfiles_repo_group`'); -- db_process_sql ('DROP TABLE `tfiles_repo`'); -- db_process_sql ('DELETE FROM `tconfig` -- WHERE `token` LIKE "files_repo_%"'); -+ db_process_sql('DROP TABLE `tfiles_repo_group`'); -+ db_process_sql('DROP TABLE `tfiles_repo`'); -+ db_process_sql('DELETE FROM `tconfig` -+ WHERE `token` LIKE "files_repo_%"'); - break; - case "postgresql": -- db_process_sql ('DROP TABLE `tfiles_repo_group`'); -- db_process_sql ('DROP TABLE `tfiles_repo`'); -- db_process_sql ('DELETE FROM "tconfig" -- WHERE "token" LIKE \'files_repo_%\''); -+ db_process_sql('DROP TABLE "tfiles_repo_group"'); -+ db_process_sql('DROP TABLE "tfiles_repo"'); -+ db_process_sql('DELETE FROM "tconfig" -+ WHERE "token" LIKE \'files_repo_%\''); - break; - case "oracle": -- db_process_sql ('DROP TABLE `tfiles_repo_group`'); -- db_process_sql ('DROP TABLE `tfiles_repo`'); -- db_process_sql ('DELETE FROM tconfig -- WHERE token LIKE \'files_repo_%\''); -+ db_process_sql('DROP TABLE "tfiles_repo_group"'); -+ db_process_sql('DROP TABLE "tfiles_repo"'); -+ db_process_sql('DELETE FROM tconfig -+ WHERE token LIKE \'files_repo_%\''); - break; - } - -@@ -86,11 +89,11 @@ - - function pandora_files_repo_godmode () { - global $config; -- -+ - if (!isset($config['files_repo_installed']) || !$config['files_repo_installed']) { - ui_print_error_message(__('Extension not installed')); - } -- -+ - // ACL Check - check_login (); - if (! check_acl ($config['id_user'], 0, "PM")) { -@@ -98,37 +101,41 @@ - require ("general/noaccess.php"); - return; - } -- -+ - // Header tabs - $godmode['text'] = '' - . html_print_image ("images/setup.png", true, array ("title" => __('Administration view'))) - . ""; - $godmode['godmode'] = 1; - $godmode['active'] = 1; -- -+ - $operation['text'] = '' - . html_print_image ("images/operation.png", true, array ("title" => __('Operation view'))) - . ""; - $operation['operation'] = 1; -- -+ - $onheader = array('godmode' => $godmode, 'operation' => $operation); - // Header - ui_print_page_header (__("Files repository manager"), "images/extensions.png", false, "", true, $onheader); -- -+ - $full_extensions_dir = $config['homedir']."/".EXTENSIONS_DIR."/"; -- require_once ($full_extensions_dir."files_repo/functions_files_repo.php"); -- -+ require_once ($full_extensions_dir . "files_repo/functions_files_repo.php"); -+ - // Directory files_repo check - if (!files_repo_check_directory(true)) { - return; - } -- -+ -+ $server_content_length = 0; -+ if (isset($_SERVER['CONTENT_LENGTH'])) -+ $server_content_length = $_SERVER['CONTENT_LENGTH']; -+ - // Check for an anoying error that causes the $_POST and $_FILES arrays - // were empty if the file is larger than the post_max_size -- if (intval($_SERVER['CONTENT_LENGTH']) > 0 && empty($_POST)) { -+ if (intval($server_content_length) > 0 && empty($_POST)) { - ui_print_error_message(__('The file exceeds the maximum size')); - } -- -+ - // GET and POST parameters - $file_id = (int) get_parameter ("file_id"); - $add_file = (bool) get_parameter ("add_file"); -@@ -144,7 +151,7 @@ - $description = mb_substr($description, 0, 200, "UTF-8"); - } - $description = io_safe_input($description); -- -+ - if ($add_file) { - $result = files_repo_add_file("upfile", $description, $groups, $public); - } elseif ($update_file) { -@@ -163,7 +170,7 @@ - } - $file_id = 0; - } -- -+ - // FORM - require ($full_extensions_dir."files_repo/files_repo_form.php"); - if (!$file_id) { -@@ -175,7 +182,7 @@ - - function pandora_files_repo_operation () { - global $config; -- -+ - // Header tabs - $onheader = array(); - if (check_acl($config['id_user'], 0, "PM")) { -@@ -194,18 +201,19 @@ - } - // Header - ui_print_page_header (__("Files repository"), "images/extensions.png", false, "", false, $onheader); -- -+ - $full_extensions_dir = $config['homedir']."/".EXTENSIONS_DIR."/"; - require_once ($full_extensions_dir."files_repo/functions_files_repo.php"); -- -+ - // Directory files_repo check - if (!files_repo_check_directory(true)) { - return; - } -- -+ - // LIST - $full_extensions_dir = $config['homedir']."/".EXTENSIONS_DIR."/"; -- require ($full_extensions_dir."files_repo/files_repo_list.php"); -+ -+ require ($full_extensions_dir . "files_repo/files_repo_list.php"); - } - - extensions_add_operation_menu_option(__('Files repository'), null, null, "v1r1"); -Index: operation/incidents/incident.php -=================================================================== ---- operation/incidents/incident.php (revision 10314) -+++ operation/incidents/incident.php (working copy) -@@ -25,7 +25,8 @@ - } - - // Header --ui_print_page_header (__('Incident management'), "images/book_edit.png", false, "", false, ""); -+ui_print_page_header (__('Incident management'), -+ "images/book_edit.png", false, "", false, ""); - - // Take input parameters - -@@ -197,7 +198,7 @@ - ORDER BY actualizacion DESC OFFSET ".$offset." LIMIT ".$config["block_size"]; - $count_sql = "SELECT count(*) FROM tincidencia WHERE - id_grupo IN (".implode (",",array_keys ($groups)).")".$filter; -- breka; -+ break; - } - - $result = db_get_all_rows_sql ($sql); -@@ -250,11 +251,14 @@ - $agents_incidents = array(); - } - --foreach ($agents_incidents as $agent_incident){ -+$result_agent_incidents = array(); -+foreach ($agents_incidents as $agent_incident) { - $result_agent_incidents[$agent_incident['id_agente']] = $agent_incident['nombre']; - } - --html_print_select ($result_agent_incidents, "agent_search", $agent_search, 'javascript:this.form.submit();', __('All agents'), "", false, false, false, "w155"); -+html_print_select ($result_agent_incidents, "agent_search", -+ $agent_search, 'javascript:this.form.submit();', __('All agents'), -+ "", false, false, false, "w155"); - - echo ''; - -Index: operation/tree.php -=================================================================== ---- operation/tree.php (revision 10314) -+++ operation/tree.php (working copy) -@@ -72,7 +72,7 @@ - } - if ($printAlertsTable) { - $id_module = get_parameter('id_module'); -- -+ - if (defined ('METACONSOLE')) { - $server = metaconsole_get_connection ($server_name); - metaconsole_connect($server); -@@ -86,7 +86,7 @@ - } - if ($printModuleTable) { - $id_module = get_parameter('id_module'); -- -+ - if (defined ('METACONSOLE')) { - $server = metaconsole_get_connection ($server_name); - metaconsole_connect($server); -@@ -139,7 +139,8 @@ - } - $avariableGroups = users_get_groups(); - $avariableGroupsIds = array_keys($avariableGroups); -- $sql = treeview_getFirstBranchSQL ($type, $id, $avariableGroupsIds, $statusSel, $search_free); -+ $sql = treeview_getFirstBranchSQL ($type, $id, -+ $avariableGroupsIds, $statusSel, $search_free); - if ($sql === false) { - $server_rows = array (); - } -@@ -437,7 +438,7 @@ - "id=" . $row["id_agente_modulo"]; - } - echo "". html_print_image ("images/binary.png", true, array ("style" => 'vertical-align: middle;', "border" => "0" )) . ""; -- -+ - echo " "; - - $nmodule_alerts = db_get_value_sql(sprintf("SELECT count(*) FROM talert_template_modules WHERE id_agent_module = %s", $row["id_agente_modulo"])); -@@ -525,35 +526,44 @@ - } - - $module_tab = array('text' => "" -- . html_print_image ("images/brick.png", true, array ("title" => __('Modules'))) . "", 'active' => $activeTab == "module"); -+ . html_print_image("images/brick.png", -+ true, -+ array("title" => __('Modules'))) . "", -+ 'active' => $activeTab == "module"); - - $tags_tab = array('text' => "" -- . html_print_image ("images/tag.png", true, array ("title" => __('Tags'))) . "", 'active' => $activeTab == "tag"); -- -+ . html_print_image("images/tag.png", -+ true, -+ array("title" => __('Tags'))) . "", -+ 'active' => $activeTab == "tag"); -+ - switch ($activeTab) { - case 'group': -- $order = __('groups'); -+ $order = __('groups'); - break; - case 'module_group': -- $order = __('module groups'); -+ $order = __('module groups'); - break; - case 'policies': -- $order = __('policies'); -+ $order = __('policies'); - break; - case 'module': -- $order = __('modules'); -+ $order = __('modules'); - break; - case 'os': -- $order = __('OS'); -+ $order = __('OS'); - break; - case 'tag': -- $order = __('tags'); -+ $order = __('tags'); - break; - } - - if (! defined ('METACONSOLE')) { - $onheader = array('tag' => $tags_tab, 'os' => $os_tab, 'group' => $group_tab, 'module_group' => $module_group_tab, 'policies' => $policies_tab, 'module' => $module_tab); -- ui_print_page_header (__('Tree view')." - ".__('Sort the agents by ') .$order, "images/extensions.png", false, "", false, $onheader); -+ ui_print_page_header( -+ __('Tree view') . " - " . __('Sort the agents by ') . $order, -+ "images/extensions.png", -+ false, "", false, $onheader); - } - else { - -@@ -569,7 +579,7 @@ - if ($config['enable_tags_tree']) { - $allowed_tabs[] = 'tag'; - } -- -+ - if (!in_array($activeTab, $allowed_tabs)) { - db_pandora_audit("HACK Attempt", - "Trying to access to not allowed tab on tree view"); -@@ -577,17 +587,19 @@ - exit; - } - // End of tab check -- -+ - $group_tab = array('text' => "" - . html_print_image ("images/group.png", true, array ("title" => __('Groups'))) . "", - 'active' => $activeTab == "group"); - - $subsections['group'] = $group_tab; -- -- if($config['enable_tags_tree']) { -- $tags_tab = array('text' => "" -- . html_print_image ("images/tag.png", true, array ("title" => __('Tags'))) . "", 'active' => $activeTab == "tag"); - -+ if ($config['enable_tags_tree']) { -+ $tags_tab = array( -+ 'text' => "" . -+ html_print_image ("images/tag.png", true, array ("title" => __('Tags'))) . "", -+ 'active' => $activeTab == "tag"); -+ - $subsections['tag'] = $tags_tab; - } - -@@ -649,6 +661,7 @@ - - treeview_printTree($activeTab); - -+ - enterprise_hook('close_meta_frame'); - - ui_include_time_picker(); -@@ -672,10 +685,14 @@ - * id_father int use in js and ajax php, its useful when you have a two subtrees with same agent for diferent each one - */ - function loadSubTree(type, div_id, less_branchs, id_father, server_name) { -- hiddenDiv = $('#tree_div'+id_father+'_'+type+'_'+div_id).attr('hiddenDiv'); -- loadDiv = $('#tree_div'+id_father+'_'+type+'_'+div_id).attr('loadDiv'); -- pos = parseInt($('#tree_image'+id_father+'_'+type+'_'+div_id).attr('pos_tree')); -+ hiddenDiv = $('#tree_div' + id_father + '_' + type + '_' + div_id) -+ .attr('hiddenDiv'); -+ loadDiv = $('#tree_div' + id_father + '_' + type + '_' + div_id) -+ .attr('loadDiv'); - -+ pos = parseInt($('#tree_image' + id_father + '_' + type + '_' + div_id) -+ .attr('pos_tree')); -+ - //If has yet ajax request running - if (loadDiv == 2) - return; -@@ -683,8 +700,10 @@ - if (loadDiv == 0) { - - //Put an spinner to simulate loading process -- $('#tree_div'+id_father+'_'+type+'_'+div_id).html(""); -- $('#tree_div'+id_father+'_'+type+'_'+div_id).show('normal'); -+ $('#tree_div' + id_father + '_' + type + '_' + div_id) -+ .html(""); -+ $('#tree_div' + id_father + '_' + type + '_' + div_id) -+ .show('normal'); - - $('#tree_div'+id_father+'_'+type+'_'+div_id).attr('loadDiv', 2); - $.ajax({ -Index: operation/search_modules.getdata.php -=================================================================== ---- operation/search_modules.getdata.php (revision 10314) -+++ operation/search_modules.getdata.php (working copy) -@@ -108,7 +108,7 @@ - ) - ) - ) AND -- t1.nombre COLLATE utf8_general_ci LIKE \'%' . $stringSearchSQL . '%\' OR -+ t1.nombre LIKE \'%' . $stringSearchSQL . '%\' OR - t3.nombre LIKE \'%' . $stringSearchSQL . '%\''; - break; - case "oracle": -Index: operation/search_main.php -=================================================================== ---- operation/search_main.php (revision 10314) -+++ operation/search_main.php (working copy) -@@ -44,6 +44,7 @@ - $table->style[9] = 'font-weight: bold; text-align: center;'; - $table->style[10] = 'font-weight: bold; text-align: center;'; - $table->style[11] = 'font-weight: bold; text-align: center;'; -+$table->style[13] = 'font-weight: bold; text-align: center;'; - - $table->data[0][0] = html_print_image ("images/agent.png", true, array ("title" => __('Agents found'))); - $table->data[0][1] = "" . -Index: operation/events/events_list.php -=================================================================== ---- operation/events/events_list.php (revision 10314) -+++ operation/events/events_list.php (working copy) -@@ -52,7 +52,7 @@ - $event_filter['tag_with'] = base64_encode(io_safe_output($event_filter['tag_with'])); - $event_filter['tag_without'] = base64_encode(io_safe_output($event_filter['tag_without'])); - -- echo json_encode($event_filter); -+ echo io_json_mb_encode($event_filter); - } - - // Saves an event filter -@@ -69,8 +69,8 @@ - $values['event_view_hr'] = get_parameter('event_view_hr'); - $values['id_user_ack'] = get_parameter('id_user_ack'); - $values['group_rep'] = get_parameter('group_rep'); -- $values['tag_with'] = get_parameter('tag_with', json_encode(array())); -- $values['tag_without'] = get_parameter('tag_without', json_encode(array())); -+ $values['tag_with'] = get_parameter('tag_with', io_json_mb_encode(array())); -+ $values['tag_without'] = get_parameter('tag_without', io_json_mb_encode(array())); - $values['filter_only_alert'] = get_parameter('filter_only_alert'); - $values['id_group_filter'] = get_parameter('id_group_filter'); - -@@ -97,8 +97,8 @@ - $values['event_view_hr'] = get_parameter('event_view_hr'); - $values['id_user_ack'] = get_parameter('id_user_ack'); - $values['group_rep'] = get_parameter('group_rep'); -- $values['tag_with'] = get_parameter('tag_with', json_encode(array())); -- $values['tag_without'] = get_parameter('tag_without', json_encode(array())); -+ $values['tag_with'] = get_parameter('tag_with', io_json_mb_encode(array())); -+ $values['tag_without'] = get_parameter('tag_without', io_json_mb_encode(array())); - $values['filter_only_alert'] = get_parameter('filter_only_alert'); - $values['id_group_filter'] = get_parameter('id_group_filter'); - -@@ -116,7 +116,7 @@ - if ($get_event_filters) { - $event_filter = events_get_event_filter_select(); - -- echo json_encode($event_filter); -+ echo io_json_mb_encode($event_filter); - } - - return; -@@ -195,14 +195,14 @@ - $table->class = 'databox'; - $table->styleTable = 'font-weight: bold; color: #555; text-align:left;'; - $table->style[0] = 'width: 50%; width:50%;'; -- -+ - $data = array(); - $table->rowid[0] = 'update_save_selector'; - $data[0] = html_print_radio_button('filter_mode', 'new', '', true, true) . __('New filter') . '

'; - $data[1] = html_print_radio_button('filter_mode', 'update', '', false, true) . __('Update filter') . '

'; - $table->data[] = $data; - $table->rowclass[] = ''; -- -+ - $data = array(); - $table->rowid[1] = 'save_filter_row1'; - $data[0] = __('Filter name') . '
'; -@@ -212,7 +212,7 @@ - $data[1] .= html_print_select_groups($config["id_user"], "ER", users_can_manage_group_all(), 'id_group', $id_group, '', '', 0, true, false, false, 'w130'); - $table->data[] = $data; - $table->rowclass[] = ''; -- -+ - $data = array(); - $table->rowid[2] = 'save_filter_row2'; - $data[0] = html_print_submit_button (__('Save filter'), 'save_filter', false, 'class="sub upd"', true); -@@ -220,18 +220,18 @@ - $table->cellstyle[2][0] = 'text-align:right;'; - $table->data[] = $data; - $table->rowclass[] = ''; -- -+ - $data = array(); - $table->rowid[3] = 'update_filter_row1'; - $data[0] = __("Overwrite filter") . '
'; - # Fix : Only admin user can see filters of group ALL for update - $_filters_update = events_get_event_filter_select(false); -- -+ - $data[0] .= html_print_select ($_filters_update, "overwrite_filter", '', '', '', 0, true); - $data[1] = html_print_submit_button (__('Update filter'), 'update_filter', false, 'class="sub upd"', true); - $table->data[] = $data; - $table->rowclass[] = ''; -- -+ - html_print_table($table); - unset($table); - echo ''; -@@ -340,7 +340,7 @@ - if ($open_filter) { - $events_filter .= html_print_input_hidden('open_filter', 'true', true); - } --else{ -+else { - $events_filter .= html_print_input_hidden('open_filter', 'false', true); - } - -@@ -414,8 +414,18 @@ - $table_advanced->rowclass[] = ''; - - $data = array(); --$data[0] = '
' . __('Events with following tags') . '' . html_print_table($tabletags_with, true) . '
'; --$data[1] = '
' . __('Events without following tags') . '' . html_print_table($tabletags_without, true) . '
'; -+$data[0] = '
' . -+ '' . -+ __('Events with following tags') . -+ '' . -+ html_print_table($tabletags_with, true) . -+ '
'; -+$data[1] = '
' . -+ '' . -+ __('Events without following tags') . -+ '' . -+ html_print_table($tabletags_without, true) . -+ '
'; - $table_advanced->data[] = $data; - $table_advanced->rowclass[] = ''; - -@@ -536,9 +546,15 @@ - - //Extract the events by filter (or not) from db - $result = db_get_all_rows_sql ($sql); -+ - } - else { -- $result = events_get_events_grouped($sql_post, $offset, $pagination, $meta, $history); -+ $result = events_get_events_grouped( -+ $sql_post, -+ $offset, -+ $pagination, -+ $meta, -+ $history); - } - - if (!empty($result)) { -Index: operation/events/events.php -=================================================================== ---- operation/events/events.php (revision 10314) -+++ operation/events/events.php (working copy) -@@ -172,7 +172,7 @@ - $return = array('fired' => 0); - } - -- echo json_encode($return); -+ echo io_json_mb_encode($return); - } - - return; -Index: operation/search_agents.getdata.php -=================================================================== ---- operation/search_agents.getdata.php (revision 10314) -+++ operation/search_agents.getdata.php (working copy) -@@ -173,7 +173,7 @@ - AND ( - t1.nombre LIKE '%%" . $stringSearchSQL . "%%' OR - t2.nombre LIKE '%%" . $stringSearchSQL . "%%' OR -- t1.direction LIKE '%%" . $stringSearchSQL . "%%' -+ t1.direccion LIKE '%%" . $stringSearchSQL . "%%' - ) - "; - break; -Index: operation/search_results.php -=================================================================== ---- operation/search_results.php (revision 10314) -+++ operation/search_results.php (working copy) -@@ -58,7 +58,9 @@ - - if ($searchMain) { - $main_tab = array('text' => "
" -- . html_print_image ("images/zoom_mc.png", true, array ("title" => __('Global search'))) . "", 'active' => $searchTab == "main"); -+ . html_print_image ("images/zoom_mc.png", true, -+ array ("title" => __('Global search'))) . "", -+ 'active' => $searchTab == "main"); - } - else { - $main_tab = ''; -@@ -66,7 +68,9 @@ - - if ($searchAgents) { - $agents_tab = array('text' => "" -- . html_print_image ("images/op_monitoring.png", true, array ("title" => __('Agents'))) . "", 'active' => $searchTab == "agents"); -+ . html_print_image ("images/op_monitoring.png", true, -+ array ("title" => __('Agents'))) . "", -+ 'active' => $searchTab == "agents"); - } - else { - $agents_tab = ''; -@@ -74,7 +78,9 @@ - - if ($searchUsers) { - $users_tab = array('text' => "" -- . html_print_image ("images/op_workspace.png", true, array ("title" => __('Users'))) . "", 'active' => $searchTab == "users"); -+ . html_print_image ("images/op_workspace.png", true, -+ array ("title" => __('Users'))) . "", -+ 'active' => $searchTab == "users"); - } - else { - $users_tab = ''; -@@ -82,7 +88,9 @@ - - if ($searchAlerts) { - $alerts_tab = array('text' => "" -- . html_print_image ("images/op_alerts.png", true, array ("title" => __('Alerts'))) . "", 'active' => $searchTab == "alerts"); -+ . html_print_image ("images/op_alerts.png", true, -+ array ("title" => __('Alerts'))) . "", -+ 'active' => $searchTab == "alerts"); - } - else { - $alerts_tab = ''; -@@ -90,7 +98,9 @@ - - if ($searchGraphs) { - $graphs_tab = array('text' => "" -- . html_print_image ("images/chart.png", true, array ("title" => __('Graphs'))) . "", 'active' => $searchTab == "graphs"); -+ . html_print_image ("images/chart.png", true, -+ array ("title" => __('Graphs'))) . "", -+ 'active' => $searchTab == "graphs"); - } - else { - $graphs_tab = ''; -@@ -98,7 +108,9 @@ - - if ($searchReports) { - $reports_tab = array('text' => "" -- . html_print_image ("images/op_reporting.png", true, array ("title" => __('Reports'))) . "", 'active' => $searchTab == "reports"); -+ . html_print_image ("images/op_reporting.png", true, -+ array ("title" => __('Reports'))) . "", -+ 'active' => $searchTab == "reports"); - } - else { - $reports_tab = ''; -@@ -106,7 +118,9 @@ - - if ($searchMaps) { - $maps_tab = array('text' => "" -- . html_print_image ("images/visual_console.png", true, array ("title" => __('Maps'))) . "", 'active' => $searchTab == "maps"); -+ . html_print_image ("images/visual_console.png", true, -+ array ("title" => __('Maps'))) . "", -+ 'active' => $searchTab == "maps"); - } - else { - $maps_tab = ''; -@@ -114,7 +128,9 @@ - - if ($searchModules) { - $modules_tab = array('text' => "" -- . html_print_image ("images/brick.png", true, array ("title" => __('Modules'))) . "", 'active' => $searchTab == "modules"); -+ . html_print_image ("images/brick.png", true, -+ array ("title" => __('Modules'))) . "", -+ 'active' => $searchTab == "modules"); - } - else { - $modules_tab = ''; -@@ -135,6 +151,7 @@ - switch ($searchTab) { - case 'main': - $only_count = true; -+ - require_once('search_agents.getdata.php'); - require_once('search_agents.php'); - require_once('search_users.getdata.php'); -Index: operation/agentes/status_monitor.php -=================================================================== ---- operation/agentes/status_monitor.php (revision 10314) -+++ operation/agentes/status_monitor.php (working copy) -@@ -14,8 +14,6 @@ - // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - // GNU General Public License for more details. - -- -- - // Load global vars - global $config; - -@@ -45,6 +43,8 @@ - ui_meta_print_header(__("Monitor view")); - } - -+ -+ - $ag_freestring = get_parameter ('ag_freestring'); - $ag_modulename = (string) get_parameter ('ag_modulename'); - if (!defined('METACONSOLE')) { -@@ -101,9 +101,13 @@ - - $sql_conditions = " AND tagente_modulo.disabled = 0 AND tagente.disabled = 0"; - -+if (is_numeric($ag_group)) { -+ $id_ag_group = 0; -+} -+else { -+ $id_ag_group = db_get_value('id_grupo', 'tgrupo', 'nombre', $ag_group); -+} - --$id_ag_group = db_get_value('id_grupo', 'tgrupo', 'nombre', $ag_group); -- - // Agent group selector - if (!defined('METACONSOLE')) { - if ($ag_group > 0 && check_acl ($config["id_user"], $ag_group, "AR")) { -@@ -123,6 +127,7 @@ - $sql_conditions_group = " AND tagente.id_grupo IN (".$user_groups.")"; - } - } -+ - // Module group - if (defined('METACONSOLE')) { - if ($modulegroup != '-1') -@@ -198,7 +203,7 @@ - WHERE ttag_module.id_tag IN (SELECT id_tag FROM ttag where name LIKE '%" . $tag_filter . "%') - )"; - } -- else{ -+ else { - $sql_conditions .= " AND tagente_modulo.id_agente_modulo IN ( - SELECT ttag_module.id_agente_modulo - FROM ttag_module -@@ -310,7 +315,9 @@ - if (defined('METACONSOLE')) { - - // For each server defined and not disabled: -- $servers = db_get_all_rows_sql ("SELECT * FROM tmetaconsole_setup WHERE disabled = 0"); -+ $servers = db_get_all_rows_sql ("SELECT * -+ FROM tmetaconsole_setup -+ WHERE disabled = 0"); - - if ($servers === false) - $servers = array(); -@@ -727,8 +734,15 @@ - LIMIT ".$offset.",".$limit_sql; - break; - case "postgresql": -+ if (strstr($config['dbversion'], "8.4") !== false) { -+ $string_agg = "array_to_string(array_agg(ttag.name), ',')"; -+ } -+ else { -+ $string_agg = "STRING_AGG(ttag.name, ',')"; -+ } -+ - $sql = "SELECT -- (SELECT STRING_AGG(ttag.name, ',') -+ (SELECT " . $string_agg . " - FROM ttag - WHERE ttag.id_tag IN ( - SELECT ttag_module.id_tag -@@ -760,7 +774,10 @@ - tagente_modulo.critical_instructions, - tagente_modulo.warning_instructions, - tagente_modulo.unknown_instructions, -- tagente_estado.utimestamp AS utimestamp".$sql_form . $sql_conditions_all." LIMIT " . $limit_sql . " OFFSET " . $offset; -+ tagente_estado.utimestamp AS utimestamp" . -+ $sql_from . -+ $sql_conditions_all . -+ " LIMIT " . $limit_sql . " OFFSET " . $offset; - break; - case "oracle": - $set = array(); -@@ -799,7 +816,9 @@ - tagente_modulo.critical_instructions, - tagente_modulo.warning_instructions, - tagente_modulo.unknown_instructions, -- tagente_estado.utimestamp AS utimestamp" . $sql_form . $sql_conditions_all; -+ tagente_estado.utimestamp AS utimestamp" . -+ $sql_from . -+ $sql_conditions_all; - $sql = oracle_recode_query ($sql, $set); - break; - } -Index: operation/agentes/alerts_status.php -=================================================================== ---- operation/agentes/alerts_status.php (revision 10314) -+++ operation/agentes/alerts_status.php (working copy) -@@ -258,7 +258,8 @@ - - - $alerts = array(); --$options_simple = array('offset' => $offset_simple, 'limit' => $config['block_size'], 'order' => $order); -+$options_simple = array('offset' => $offset_simple, -+ 'limit' => $config['block_size'], 'order' => $order); - - $filter_alert = array(); - if($filter_standby == 'standby_on') { -@@ -322,11 +323,11 @@ - } - - if ($tab != null) { -- $url = $url.'&tab='.$tab; -+ $url = $url.'&tab=' . $tab; - } - - if ($pure) { -- $url .= '&pure='.$pure; -+ $url .= '&pure=' . $pure; - } - - // Filter form -@@ -345,13 +346,17 @@ - if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) { - if ($print_agent) { - if (!defined('METACONSOLE')) { -- $table->head[0] = "" . __('P.') . ""; -+ $table->head[0] = "" . -+ __('P.') . ""; - } - -- $table->head[1] = "" . __('S.') . ""; -+ $table->head[1] = "" . -+ __('S.') . ""; - - if (!defined('METACONSOLE')) { -- $table->head[2] = "" . __('F.') . ""; -+ $table->head[2] = -+ "" . -+ __('F.') . ""; - } - - $table->head[3] = __('Agent'); -@@ -481,6 +486,12 @@ - } - } - -+ -+if ($sortField) { -+ $url .= '&sort_field=' . $sortField; -+ $url .= '&sort=' . $sort; -+} -+ - $table->data = array (); - - $rowPair = true; -@@ -496,9 +507,10 @@ - } - - if (!empty ($table->data)) { -- echo '
'; -+ echo ''; - -- ui_pagination ($countAlertsSimple, $url, $offset_simple, 0, false, 'offset_simple'); -+ ui_pagination ($countAlertsSimple, $url, $offset_simple, 0, false, -+ 'offset_simple'); - html_print_table ($table); - - if (!defined('METACONSOLE')) { -Index: operation/agentes/estado_generalagente.php -=================================================================== ---- operation/agentes/estado_generalagente.php (revision 10314) -+++ operation/agentes/estado_generalagente.php (working copy) -@@ -255,7 +255,7 @@ - else { - $data[1] = __('Enabled'); - } -- -+ - $table_data->data[] = $data; - } - -@@ -323,7 +323,7 @@ - WHERE estado IN (0,1) - AND id_agent=$id_agente - ORDER BY actualizacion DESC"); -- -+ - if ($last_incident != false) { - - $table_incident->id = 'agent_incident_main'; -@@ -333,10 +333,10 @@ - $table_incident->class = 'databox'; - $table_incident->style[0] = 'width: 30%;'; - $table_incident->style[1] = 'width: 70%;'; -- -+ - $table_incident->head[0] = ' ' . '' .__('Active incident on this agent') .''. ''; - $table_incident->head_colspan[0] = 2; -- -+ - $data = array(); - $data[0] = '' . __('Author') . ''; - $data[1] = $last_incident["id_creator"]; -@@ -391,20 +391,20 @@ - $table_interface->head_colspan = array(); - $table_interface->head_colspan[0] = 4; - $table_interface->data = array(); -- -+ - foreach ($modules as $key => $module) { -- -+ - // Trying to get the interface name from the module name - if (preg_match ("/_(.+)$/", (string)$module['nombre'], $matches)) { - if ($matches[1]) { - $interface_name = $matches[1]; -- -+ - $module_id = $module['id_agente_modulo']; - $db_status = modules_get_agentmodule_status($module_id); - $module_value = modules_get_last_value ($module_id); - modules_get_status($module_id, $db_status, $module_value, $status, $title); - $status = ui_print_status_image($status, $title, true); -- -+ - $ip_target = "--"; - // Trying to get something like an IP from the description - if (preg_match ("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", (string)$module['descripcion'], $matches) || -@@ -421,7 +421,7 @@ - $description = $matches[0]; - } - } -- -+ - $data = array(); - $data[0] = "" . $interface_name . ""; - $data[1] = $status; -@@ -432,7 +432,7 @@ - } - } - unset($modules); -- -+ - // This javascript piece of code is used to make expandible the body of the table - ?> - -Index: general/header.php -=================================================================== ---- general/header.php (revision 10314) -+++ general/header.php (working copy) -@@ -58,10 +58,16 @@ - $table->cellspacing = 0; - $table->head = array (); - $table->data = array (); -- $table->style[0] = $table->style[1] = $table->style[3] = -- $table->style[4] = $table->style[5] = -- $table->style[6] = $table->style[8] = -- $table->style[9] = $table->style['qr'] = -+ $table->style[0] = -+ $table->style['clippy'] = -+ $table->style[1] = -+ $table->style[3] = -+ $table->style[4] = -+ $table->style[5] = -+ $table->style[6] = -+ $table->style[8] = -+ $table->style[9] = -+ $table->style['qr'] = - 'width: 22px; text-align:center; height: 22px; padding-right: 9px;'; - $table->style[7] = 'width: 20px; padding-right: 9px;'; - $table->style['searchbar'] = 'width: 180px; min-width: 180px;'; -@@ -122,11 +128,26 @@ - - data[0][0] = $servers_link_open . $servers_check_img . $servers_link_close; -+ if ($config['tutorial_mode'] !== 'expert') { -+ $table->data[0]['clippy'] = -+ '' . -+ html_print_image( -+ "images/clippy_icon.png", -+ true, -+ array("id" => 'clippy', -+ "class" => 'clippy', -+ "alt" => __('Clippy'), -+ 'title' => __('Clippy'))) . -+ ''; -+ } - - -+ $table->data[0][0] = $servers_link_open . -+ $servers_check_img . $servers_link_close; - - -+ -+ - //======= Autorefresh code ============================= - $autorefresh_txt = ''; - $autorefresh_additional = ''; -@@ -303,8 +324,19 @@ - - '; - - echo ''; -@@ -71,11 +72,13 @@ - $table->data[4][1] = html_print_input_text('expires', $license['license_mode'], '', 10, 255, true, true); - - html_print_table ($table); --echo '
'; --html_print_input_hidden ('update_settings', 1); --html_print_submit_button (__('Validate'), 'update_button', false, 'class="sub upd"'); --html_print_button(__('Request new license'), '', false, 'generate_request_code()', 'class="ui-button-dialog ui-widget ui-state-default ui-corner-all ui-button-text-only sub next"'); --echo '
'; -+if (enterprise_installed()) { -+ echo '
'; -+ html_print_input_hidden ('update_settings', 1); -+ html_print_submit_button (__('Validate'), 'update_button', false, 'class="sub upd"'); -+ html_print_button(__('Request new license'), '', false, 'generate_request_code()', 'class="ui-button-dialog ui-widget ui-state-default ui-corner-all ui-button-text-only sub next"'); -+ echo '
'; -+} - echo '
'; - echo '