From ae6036d20814ee3d72b46c83a75a27ae0b147e72 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 29 Dec 2003 17:03:36 +0000 Subject: [PATCH] new devel_bacula + fixes to conio/console git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@966 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/Makefile.in | 4 +- bacula/autoconf/configure.in | 3 +- bacula/configure | 5 +- bacula/scripts/.cvsignore | 1 + bacula/scripts/bacula.in | 48 +++--- bacula/scripts/devel_bacula.in | 273 +++++++++++++++++++++++++++++++++ bacula/src/console/conio.c | 123 +++++++++------ bacula/src/console/conio.h | 32 ++++ bacula/src/console/console.c | 112 +++++++------- bacula/src/lib/message.c | 56 +++---- bacula/src/lib/signal.c | 11 +- 11 files changed, 511 insertions(+), 157 deletions(-) create mode 100755 bacula/scripts/devel_bacula.in create mode 100644 bacula/src/console/conio.h diff --git a/bacula/Makefile.in b/bacula/Makefile.in index b268cc01d8..c242ef036e 100755 --- a/bacula/Makefile.in +++ b/bacula/Makefile.in @@ -62,6 +62,7 @@ configure: autoconf/configure.in autoconf/aclocal.m4 autoconf/acconfig.h autocon old-configure: autoconf/configure.in autoconf/aclocal.m4 autoconf/acconfig.h cd $(srcdir); + ${RMF} -f config.cache config.log config.out config.status src/config.h autoconf --include=$(srcdir)/autoconf \ autoconf/configure.in > configure chmod 755 configure @@ -73,6 +74,7 @@ config.status: autoconf/config.h.in: autoconf/configure.in autoconf/acconfig.h cd $(srcdir); + ${RMF} -f config.cache config.log config.out config.status src/config.h autoheader --prepend-include=$(srcdir)/autoconf \ autoconf/configure.in > autoconf/config.h.in chmod 644 autoconf/config.h.in @@ -120,7 +122,7 @@ Makefiles: $(SHELL) config.status (cd scripts; \ chmod 755 startmysql stopmysql bacula fd startit stopit btraceback; \ - chmod 755 mtx-changer bconsole gconsole) + chmod 755 mtx-changer bconsole gconsole devel_bacula) (cd src/cats; \ chmod 755 create_bacula_database update_bacula_tables make_bacula_tables; \ diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index 950aa42602..4a1901d9bf 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -1541,6 +1541,7 @@ AC_OUTPUT([autoconf/Make.common \ scripts/bconsole \ scripts/gconsole \ scripts/bacula \ + scripts/devel_bacula \ scripts/fd \ scripts/Makefile \ scripts/logrotate \ @@ -1608,7 +1609,7 @@ AC_OUTPUT([autoconf/Make.common \ cd scripts chmod 755 startmysql stopmysql bacula startit stopit btraceback mtx-changer -chmod 755 bconsole gconsole mtx-changer +chmod 755 bconsole gconsole mtx-changer devel_bacula cd .. c=src/cats diff --git a/bacula/configure b/bacula/configure index e92bb4103f..d8fd023fca 100755 --- a/bacula/configure +++ b/bacula/configure @@ -18041,7 +18041,7 @@ if test "x${subsysdir}" = "x${sbindir}" ; then exit 1 fi - ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/fd scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/mtx-changer doc/Makefile src/Makefile src/host.h src/console/Makefile src/console/bconsole.conf src/gnome-console/Makefile src/gnome-console/gnome-console.conf src/gnome2-console/Makefile src/gnome2-console/gnome-console.conf src/tconsole/Makefile src/dird/Makefile src/dird/bacula-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bacula-sd.conf src/filed/Makefile src/filed/bacula-fd.conf src/filed/win32/Makefile src/cats/Makefile src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_postgresql_database src/cats/update_postgresql_tables src/cats/make_postgresql_tables src/cats/grant_postgresql_privileges src/cats/drop_postgresql_tables src/cats/drop_postgresql_database src/cats/create_mysql_database src/cats/update_mysql_tables src/cats/make_mysql_tables src/cats/grant_mysql_privileges src/cats/drop_mysql_tables src/cats/drop_mysql_database src/cats/create_sqlite_database src/cats/update_sqlite_tables src/cats/make_sqlite_tables src/cats/grant_sqlite_privileges src/cats/drop_sqlite_tables src/cats/drop_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/update_bdb_tables src/cats/make_bdb_tables src/cats/grant_bdb_privileges src/cats/drop_bdb_tables src/cats/drop_bdb_database src/cats/create_bacula_database src/cats/update_bacula_tables src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/drop_bacula_database src/findlib/Makefile src/tools/Makefile $PFILES" + ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/devel_bacula scripts/fd scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/mtx-changer doc/Makefile src/Makefile src/host.h src/console/Makefile src/console/bconsole.conf src/gnome-console/Makefile src/gnome-console/gnome-console.conf src/gnome2-console/Makefile src/gnome2-console/gnome-console.conf src/tconsole/Makefile src/dird/Makefile src/dird/bacula-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bacula-sd.conf src/filed/Makefile src/filed/bacula-fd.conf src/filed/win32/Makefile src/cats/Makefile src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_postgresql_database src/cats/update_postgresql_tables src/cats/make_postgresql_tables src/cats/grant_postgresql_privileges src/cats/drop_postgresql_tables src/cats/drop_postgresql_database src/cats/create_mysql_database src/cats/update_mysql_tables src/cats/make_mysql_tables src/cats/grant_mysql_privileges src/cats/drop_mysql_tables src/cats/drop_mysql_database src/cats/create_sqlite_database src/cats/update_sqlite_tables src/cats/make_sqlite_tables src/cats/grant_sqlite_privileges src/cats/drop_sqlite_tables src/cats/drop_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/update_bdb_tables src/cats/make_bdb_tables src/cats/grant_bdb_privileges src/cats/drop_bdb_tables src/cats/drop_bdb_database src/cats/create_bacula_database src/cats/update_bacula_tables src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/drop_bacula_database src/findlib/Makefile src/tools/Makefile $PFILES" ac_config_commands="$ac_config_commands default" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -18584,6 +18584,7 @@ do "scripts/bconsole" ) CONFIG_FILES="$CONFIG_FILES scripts/bconsole" ;; "scripts/gconsole" ) CONFIG_FILES="$CONFIG_FILES scripts/gconsole" ;; "scripts/bacula" ) CONFIG_FILES="$CONFIG_FILES scripts/bacula" ;; + "scripts/devel_bacula" ) CONFIG_FILES="$CONFIG_FILES scripts/devel_bacula" ;; "scripts/fd" ) CONFIG_FILES="$CONFIG_FILES scripts/fd" ;; "scripts/Makefile" ) CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "scripts/logrotate" ) CONFIG_FILES="$CONFIG_FILES scripts/logrotate" ;; @@ -19415,7 +19416,7 @@ fi cd scripts chmod 755 startmysql stopmysql bacula startit stopit btraceback mtx-changer -chmod 755 bconsole gconsole mtx-changer +chmod 755 bconsole gconsole mtx-changer devel_bacula cd .. c=src/cats diff --git a/bacula/scripts/.cvsignore b/bacula/scripts/.cvsignore index 14f7a0855d..14bb392752 100644 --- a/bacula/scripts/.cvsignore +++ b/bacula/scripts/.cvsignore @@ -4,6 +4,7 @@ bacula.desktop bacula.desktop.gnome1 bacula.desktop.gnome2 bconsole +devel_bacula gconsole mtx-changer Makefile diff --git a/bacula/scripts/bacula.in b/bacula/scripts/bacula.in index 1fbd1a98ee..0ca89a1d68 100755 --- a/bacula/scripts/bacula.in +++ b/bacula/scripts/bacula.in @@ -11,14 +11,22 @@ PSCMD="@PSCMD@" -BACBIN=@sbindir@ -BACCFG=@sysconfdir@ +# All these are not *really* needed but it makes it +# easier to "steal" this code for the development +# environment where they are different. +# +BACFDBIN=@sbindir@ +BACFDCFG=@sysconfdir@ +BACSDBIN=@sbindir@ +BACSDCFG=@sysconfdir@ +BACDIRBIN=@sbindir@ +BACDIRCFG=@sysconfdir@ PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ -DIR_PORT=9101 -FD_PORT=9102 -SD_PORT=9103 +DIR_PORT=@dir_port@ +FD_PORT=@fd_port@ +SD_PORT=@sd_port@ DIR_USER=@dir_user@ DIR_GROUP=@dir_group@ @@ -181,7 +189,7 @@ failure() { case "$1" in start) - [ -x ${BACBIN}/bacula-sd ] && { + [ -x ${BACSDBIN}/bacula-sd ] && { echo "Starting the Storage daemon" OPTIONS='' if [ "${SD_USER}" != '' ]; then @@ -192,10 +200,10 @@ case "$1" in OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi - ${BACBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACCFG}/bacula-sd.conf + ${BACSDBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/bacula-sd.conf } - [ -x ${BACBIN}/bacula-fd ] && { + [ -x ${BACFDBIN}/bacula-fd ] && { echo "Starting the File daemon" OPTIONS='' if [ "${FD_USER}" != '' ]; then @@ -206,10 +214,10 @@ case "$1" in OPTIONS="${OPTIONS} -g ${FD_GROUP}" fi - ${BACBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACCFG}/bacula-fd.conf + ${BACFDBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/bacula-fd.conf } - [ -x ${BACBIN}/bacula-dir ] && { + [ -x ${BACDIRBIN}/bacula-dir ] && { sleep 2 echo "Starting the Director daemon" OPTIONS='' @@ -221,25 +229,25 @@ case "$1" in OPTIONS="${OPTIONS} -g ${DIR_GROUP}" fi - ${BACBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACCFG}/bacula-dir.conf + ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf } ;; stop) # Stop the FD first so that SD will fail jobs and update catalog - [ -x ${BACBIN}/bacula-fd ] && { + [ -x ${BACFDBIN}/bacula-fd ] && { echo "Stopping the File daemon" - killproc ${BACBIN}/bacula-fd ${FD_PORT} + killproc ${BACFDBIN}/bacula-fd ${FD_PORT} } - [ -x ${BACBIN}/bacula-sd ] && { + [ -x ${BACSDBIN}/bacula-sd ] && { echo "Stopping the Storage daemon" - killproc ${BACBIN}/bacula-sd ${SD_PORT} + killproc ${BACSDBIN}/bacula-sd ${SD_PORT} } - [ -x ${BACBIN}/bacula-dir ] && { + [ -x ${BACDIRBIN}/bacula-dir ] && { echo "Stopping the Director daemon" - killproc ${BACBIN}/bacula-dir ${DIR_PORT} + killproc ${BACDIRBIN}/bacula-dir ${DIR_PORT} } echo ;; @@ -251,9 +259,9 @@ case "$1" in ;; status) - [ -x ${BACBIN}/bacula-sd ] && status ${BACBIN}/bacula-sd ${SD_PORT} - [ -x ${BACBIN}/bacula-fd ] && status ${BACBIN}/bacula-fd ${FD_PORT} - [ -x ${BACBIN}/bacula-dir ] && status ${BACBIN}/bacula-dir ${DIR_PORT} + [ -x ${BACSDBIN}/bacula-sd ] && status ${BACSDBIN}/bacula-sd ${SD_PORT} + [ -x ${BACFDBIN}/bacula-fd ] && status ${BACFDBIN}/bacula-fd ${FD_PORT} + [ -x ${BACDIRBIN}/bacula-dir ] && status ${BACDIRBIN}/bacula-dir ${DIR_PORT} ;; *) diff --git a/bacula/scripts/devel_bacula.in b/bacula/scripts/devel_bacula.in new file mode 100755 index 0000000000..9b833bb1fa --- /dev/null +++ b/bacula/scripts/devel_bacula.in @@ -0,0 +1,273 @@ +#! /bin/sh +# +# bacula This shell script takes care of starting and stopping +# the bacula daemons. +# +# It runs with different ports than the production version, +# and using the current development enviornment. +# +# This is pretty much watered down version of the RedHat script +# that works on Solaris as well as Linux, but it won't work everywhere. +# +# description: It comes by night and sucks the vital essence from your computers. +# + +PSCMD="@PSCMD@" +pwd=`pwd` + +BACDIRBIN=${pwd}/src/dird +BACDIRCFG=${pwd}/src/dird +BACFDBIN=${pwd}/src/filed +BACFDCFG=${pwd}/src/filed +BACSDBIN=${pwd}/src/stored +BACSDCFG=${pwd}/src/stored +PIDDIR=@piddir@ +SUBSYSDIR=@subsysdir@ + +# Use non-production ports +DIR_PORT=8101 +FD_PORT=8102 +SD_PORT=8103 + +DIR_USER=@dir_user@ +DIR_GROUP=@dir_group@ +FD_USER=@fd_user@ +FD_GROUP=@fd_group@ +SD_USER=@sd_user@ +SD_GROUP=@sd_group@ + +# A function to stop a program. +killproc() { + RC=0 + # Test syntax. + if [ $# = 0 ]; then + echo "Usage: killproc {program} [signal]" + return 1 + fi + + notset=0 + # check for third arg to be kill level + if [ "$3" != "" ] ; then + killlevel=$3 + else + notset=1 + killlevel="-9" + fi + + # Get base program name + base=`basename $1` + + # Find pid. + pid=`pidofproc $base $2` + + # Kill it. + if [ "$pid" != "" ] ; then + if [ "$notset" = "1" ] ; then + if ps -p $pid>/dev/null 2>&1; then + # TERM first, then KILL if not dead + kill -TERM $pid 2>/dev/null + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 3 + if ps -p $pid >/dev/null 2>&1 ; then + kill -KILL $pid 2>/dev/null + fi + fi + fi + fi + ps -p $pid >/dev/null 2>&1 + RC=$? + [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" + # RC=$((! $RC)) + # use specified level only + else + if ps -p $pid >/dev/null 2>&1; then + kill $killlevel $pid 2>/dev/null + RC=$? + [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" + fi + fi + else + failure "$base shutdown" + fi + # Remove pid file if any. + if [ "$notset" = "1" ]; then + rm -f ${PIDDIR}/$base.$2.pid + fi + return $RC +} + +# A function to find the pid of a program. +pidofproc() { + pid="" + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: pidofproc {program}" + return 1 + fi + + # Get base program name + base=`basename $1` + + # First try PID file + if [ -f ${PIDDIR}/$base.$2.pid ] ; then + pid=`head -1 ${PIDDIR}/$base.$2.pid` + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + fi + + # Next try "pidof" + if [ -x /sbin/pidof ] ; then + pid=`/sbin/pidof $1` + fi + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + + # Finally try to extract it from ps + ${PSCMD} | grep $1 | awk '{ print $1 }' | tr '\n' ' ' + return 0 +} + +status() { + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: status {program}" + return 1 + fi + + # Get base program name + base=`basename $1` + + # First try "pidof" + if [ -x /sbin/pidof ] ; then + pid=`/sbin/pidof $1` + fi + if [ "$pid" != "" ] ; then + echo "$base (pid $pid) is running..." + return 0 + else + pid=`${PSCMD} | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } + { if ((prog == $2) || (("(" prog ")") == $2) || + (("[" prog "]") == $2) || + ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` + if [ "$pid" != "" ] ; then + echo "$base (pid $pid) is running..." + return 0 + fi + fi + + # Next try the PID files + if [ -f ${PIDDIR}/$base.$2.pid ] ; then + pid=`head -1 ${PIDDIR}/$base.$2.pid` + if [ "$pid" != "" ] ; then + echo "$base dead but pid file exists" + return 1 + fi + fi + # See if the subsys lock exists + if [ -f ${SUBSYSDIR}/$base ] ; then + echo "$base dead but subsys locked" + return 2 + fi + echo "$base is stopped" + return 3 +} + +success() { + return 0 +} + +failure() { + rc=$? + return $rc +} + +case "$1" in + start) + [ -x ${BACSDBIN}/bacula-sd ] && { + echo "Starting the Storage daemon" + OPTIONS='' + if [ "${SD_USER}" != '' ]; then + OPTIONS="${OPTIONS} -u ${SD_USER}" + fi + + if [ "${SD_GROUP}" != '' ]; then + OPTIONS="${OPTIONS} -g ${SD_GROUP}" + fi + + ${BACSDBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/stored.conf + } + + [ -x ${BACFDBIN}/bacula-fd ] && { + echo "Starting the File daemon" + OPTIONS='' + if [ "${FD_USER}" != '' ]; then + OPTIONS="${OPTIONS} -u ${FD_USER}" + fi + + if [ "${FD_GROUP}" != '' ]; then + OPTIONS="${OPTIONS} -g ${FD_GROUP}" + fi + + ${BACFDBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/filed.conf + } + + [ -x ${BACDIRBIN}/bacula-dir ] && { + sleep 2 + echo "Starting the Director daemon" + OPTIONS='' + if [ "${DIR_USER}" != '' ]; then + OPTIONS="${OPTIONS} -u ${DIR_USER}" + fi + + if [ "${DIR_GROUP}" != '' ]; then + OPTIONS="${OPTIONS} -g ${DIR_GROUP}" + fi + + ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf + } + ;; + + stop) + # Stop the FD first so that SD will fail jobs and update catalog + [ -x ${BACFDBIN}/bacula-fd ] && { + echo "Stopping the File daemon" + killproc ${BACFDBIN}/bacula-fd ${FD_PORT} + } + + [ -x ${BACSDBIN}/bacula-sd ] && { + echo "Stopping the Storage daemon" + killproc ${BACSDBIN}/bacula-sd ${SD_PORT} + } + + [ -x ${BACDIRBIN}/bacula-dir ] && { + echo "Stopping the Director daemon" + killproc ${BACDIRBIN}/bacula-dir ${DIR_PORT} + } + echo + ;; + + restart) + $0 stop + sleep 5 + $0 start + ;; + + status) + [ -x ${BACSDBIN}/bacula-sd ] && status ${BACSDBIN}/bacula-sd ${SD_PORT} + [ -x ${BACFDBIN}/bacula-fd ] && status ${BACFDBIN}/bacula-fd ${FD_PORT} + [ -x ${BACDIRBIN}/bacula-dir ] && status ${BACDIRBIN}/bacula-dir ${DIR_PORT} + ;; + + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac +exit 0 diff --git a/bacula/src/console/conio.c b/bacula/src/console/conio.c index 0e50af0334..d40aef88bb 100755 --- a/bacula/src/console/conio.c +++ b/bacula/src/console/conio.c @@ -1,35 +1,62 @@ /* - Generalized console input/output handler - Kern Sibbald, December MMIII + Generalized console input/output handler + A maintanable replacement for readline() + + Kern Sibbald, December MMIII + + This code is in part derived from code that I wrote in + 1981, so some of it is a bit old and could use a cleanup. + */ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker -#define BACULA -#ifdef BACULA -#include "bacula.h" -#else + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + */ + + +#ifdef TEST_PROGRAM #include #include #include #include #include #include +#else + +/* We are in Bacula */ +#include "bacula.h" + #endif #include #include #include "func.h" -/* Global functions imported */ - - -extern char *getenv(char *); - -static void add_smap(char *str, int func); /* From termios library */ extern char *BC; extern char *UP; +/* Forward referenced functions */ +static void sigintcatcher(int); +static void add_smap(char *str, int func); + + /* Global variables */ static char *t_up = "\n"; /* scroll up character */ @@ -84,8 +111,6 @@ typedef struct s_stab { static stab_t **stab = NULL; /* array of stabs by length */ static int num_stab; /* size of stab array */ -/* Local variables */ - static bool old_term_params_set = false; static struct termios old_term_params; @@ -117,10 +142,6 @@ static int first = 1; static int mode_insert = 0; static int mode_wspace = 1; /* words separated by spaces */ -/* Forward referenced functions */ -static void sigintcatcher(int); - -/* Global variables Exported */ static short char_map[600]= { 0, F_SOL, /* ^a Line start */ @@ -196,15 +217,17 @@ static void ascurs(int y, int x); static void rawmode(FILE *input); static void normode(void); static int t_getch(); -static void trapctlc(); static void asclrl(int pos, int width); static void asinsl(); static void asdell(); int input_line(char *string, int length); - +void con_term(); +void trapctlc(); + void con_init(FILE *input) { + atexit(con_term); rawmode(input); trapctlc(); } @@ -253,10 +276,10 @@ void con_term() normode(); } -#ifndef BACULA +#ifdef TEST_PROGRAM /* * Guarantee that the string is properly terminated */ -static char *bstrncpy(char *dest, const char *src, int maxlen) +char *bstrncpy(char *dest, const char *src, int maxlen) { strncpy(dest, src, maxlen-1); dest[maxlen-1] = 0; @@ -371,7 +394,7 @@ static void add_smap(char *str, int func) /* Get the next character from the terminal - performs table lookup on the character to do the desired translation */ static int -/*FCN*/input_char() +input_char() { int c; @@ -397,7 +420,7 @@ static int /* Get a complete input line */ int -/*FCN*/input_line(char *string, int length) +input_line(char *string, int length) { char curline[200]; /* edit buffer */ int noline; @@ -520,7 +543,7 @@ done: /* Insert a space at the current cursor position */ static void -/*FCN*/insert_space(char *curline, int curline_len) +insert_space(char *curline, int curline_len) { int i; @@ -537,7 +560,7 @@ static void /* Move cursor forward keeping characters under it */ static void -/*FCN*/forward(int i,char *str, int str_len) +forward(int i,char *str, int str_len) { while (i--) { if (cp > str_len) { @@ -555,7 +578,7 @@ static void /* Backup cursor keeping characters under it */ static void -/*FCN*/backup(int i) +backup(int i) { for ( ;i && cp; i--,cp--) t_char('\010'); @@ -563,7 +586,7 @@ static void /* Delete the character under the cursor */ static void -/*FCN*/delchr(int cnt, char *curline, int line_len) +delchr(int cnt, char *curline, int line_len) { register int i; @@ -582,7 +605,7 @@ static void /* Determine if character is part of a word */ static int -/*FCN*/iswordc(char c) +iswordc(char c) { if (mode_wspace) return !isspace(c); @@ -595,7 +618,7 @@ static int /* Return number of characters to get to next word */ static int -/*FCN*/next_word(char *ldb_buf) +next_word(char *ldb_buf) { int ncp; @@ -609,7 +632,7 @@ static int /* Return number of characters to get to previous word */ static int -/*FCN*/prev_word(char *ldb_buf) +prev_word(char *ldb_buf) { int ncp, i; @@ -634,7 +657,7 @@ static int /* Display new current line */ static void -/*FCN*/prtcur(char *str) +prtcur(char *str) { backup(cp); t_clrline(0,t_width); @@ -645,7 +668,7 @@ static void /* Initialize line pool. Split pool into two pieces. */ static void -/*FCN*/poolinit() +poolinit() { slptr = lptr = (struct lstr *)pool; lptr->nextl = lptr; @@ -658,7 +681,7 @@ static void /* Return pointer to next line in the pool and advance current line pointer */ static char * -/*FCN*/getnext() +getnext() { do { /* find next used line */ lptr = lptr->nextl; @@ -668,7 +691,7 @@ static char * /* Return pointer to previous line in the pool */ static char * -/*FCN*/getprev() +getprev() { do { /* find previous used line */ lptr = lptr->prevl; @@ -677,7 +700,7 @@ static char * } static void -/*FCN*/putline(char *newl, int newlen) +putline(char *newl, int newlen) { struct lstr *nptr; /* points to next line */ char *p; @@ -717,7 +740,7 @@ static void #ifdef DEBUGOUT static void -/*FCN*/dump(struct lstr *ptr, char *msg) +dump(struct lstr *ptr, char *msg) { printf("%s buf=%x nextl=%x prevl=%x len=%d used=%d\n", msg,ptr,ptr->nextl,ptr->prevl,ptr->len,ptr->used); @@ -729,28 +752,28 @@ static void /* Honk horn on terminal */ static void -/*FCN*/t_honk_horn() +t_honk_horn() { t_send(t_honk); } /* Insert line on terminal */ static void -/*FCN*/t_insert_line() +t_insert_line() { asinsl(); } /* Delete line from terminal */ static void -/*FCN*/t_delete_line() +t_delete_line() { asdell(); } /* clear line from pos to width */ static void -/*FCN*/t_clrline(int pos, int width) +t_clrline(int pos, int width) { asclrl(pos, width); /* clear to end of line */ } @@ -769,7 +792,7 @@ static void add_esc_smap(char *str, int func) mode in which all characters can be read as they are entered. CBREAK mode is not sufficient. */ -/*FCN*/static void rawmode(FILE *input) +static void rawmode(FILE *input) { struct termios t; static char term_buf[2048]; @@ -799,6 +822,7 @@ static void add_esc_smap(char *str, int func) printf("Cannot tcsetattr()\n"); } + /* Defaults, the main program can override these */ signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); // signal(SIGSTOP, SIG_IGN); @@ -883,16 +907,17 @@ static void add_esc_smap(char *str, int func) /* Restore tty mode */ -/*FCN*/static void normode() +static void normode() { if (old_term_params_set) { tcsetattr(0, TCSANOW, &old_term_params); + old_term_params_set = false; } } /* Get next character from terminal/script file/unget buffer */ static int -/*FCN*/t_gnc() +t_gnc() { return t_getch(); } @@ -922,13 +947,13 @@ static int window_size(int *height, int *width) /* /window_size/ */ /* Send message to terminal - primitive routine */ void -/*FCN*/t_sendl(char *msg,int len) +t_sendl(char *msg,int len) { write(1, msg, len); } void -/*FCN*/t_send(char *msg) +t_send(char *msg) { if (msg == NULL) { return; @@ -938,7 +963,7 @@ void /* Send single character to terminal - primitive routine - */ void -/*FCN*/t_char(char c) +t_char(char c) { write(1, &c, 1); } @@ -947,7 +972,7 @@ void static int brkflg = 0; /* set on user break */ /* Routine to return true if user types break */ -/*FCN*/int usrbrk() +int usrbrk() { return brkflg; } @@ -968,7 +993,7 @@ static void sigintcatcher(int sig) /* Trap Ctl-C */ -/*FCN*/void trapctlc() +void trapctlc() { signal(SIGINT, sigintcatcher); } diff --git a/bacula/src/console/conio.h b/bacula/src/console/conio.h new file mode 100644 index 0000000000..93533f5cb5 --- /dev/null +++ b/bacula/src/console/conio.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + */ +#ifndef __CONIO_H +#define __CONIO_H +extern int input_line(char *line, int len); +extern void con_init(FILE *input); +extern void con_term(); +extern void con_set_zed_keys(); +extern void t_sendl(char *buf, int len); +extern void t_send(char *buf); +extern void t_char(char c); +extern int usrbrk(void); +extern void clrbrk(void); +extern void trapctlc(void); +#endif diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 04e4ecd1a3..51f49961d0 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -30,11 +30,18 @@ #include "bacula.h" #include "console_conf.h" #include "jcr.h" - -/* Imported functions */ -int authenticate_director(JCR *jcr, DIRRES *director); - +#ifdef HAVE_CONIO +#include "conio.h" +#else +#define con_init(x) +#define con_term() +#define con_set_zed_keys(); +#define trapctlc() +#define clrbrk() +#define usrbrk() 0 +#endif + /* Exported variables */ #ifdef HAVE_CYGWIN @@ -43,19 +50,10 @@ int rl_catch_signals; extern int rl_catch_signals; #endif -#ifdef HAVE_CONIO -extern int input_line(char *line, int len); -extern void con_init(FILE *input); -extern void con_term(); -extern void con_set_zed_keys(); -extern void t_sendl(char *buf, int len); -extern void t_send(char *buf); -extern void t_char(char c); -#else -#define con_init(x) -#define con_term() -#define con_set_zed_keys(); -#endif +/* Imported functions */ +int authenticate_director(JCR *jcr, DIRRES *director); + + /* Forward referenced functions */ static void terminate_console(int sig); @@ -69,13 +67,14 @@ static char *configfile = NULL; static BSOCK *UA_sock = NULL; static DIRRES *dir; static FILE *output = stdout; -int tee = 0; /* output to output and stdout */ -static int stop = FALSE; +static bool tee = false; /* output to output and stdout */ +static bool stop = false; static int argc; static POOLMEM *args; static char *argk[MAX_CMD_ARGS]; static char *argv[MAX_CMD_ARGS]; + /* Command prototypes */ static int versioncmd(FILE *input, BSOCK *UA_sock); static int inputcmd(FILE *input, BSOCK *UA_sock); @@ -99,27 +98,24 @@ static void usage() " -t test - read configuration and exit\n" " -? print this message.\n" "\n"), HOST_OS, DISTNAME, DISTVER); - - exit(1); } - -void got_stop(int sig) +void got_sigstop(int sig) { - stop = TRUE; + stop = true; } -void got_continue(int sig) +void got_sigcontinue(int sig) { - stop = FALSE; + stop = false; } -void got_tout(int sig) +void got_sigtout(int sig) { // printf("Got tout\n"); } -void got_tin(int sig) +void got_sigtin(int sig) { // printf("Got tin\n"); } @@ -187,7 +183,7 @@ static int do_a_command(FILE *input, BSOCK *UA_sock) static void read_and_process_input(FILE *input, BSOCK *UA_sock) { char *prompt = "*"; - int at_prompt = FALSE; + bool at_prompt = false; int tty_input = isatty(fileno(input)); int stat; @@ -196,13 +192,14 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) prompt = ""; } else { prompt = "*"; - at_prompt = TRUE; + at_prompt = true; } if (tty_input) { stat = get_cmd(input, prompt, UA_sock, 30); + clrbrk(); } else { int len = sizeof_pool_memory(UA_sock->msg) - 1; - if (fgets(UA_sock->msg, len, input) == NULL) { + if (fgets(UA_sock->msg, len, input) == NULL || usrbrk()) { stat = -1; } else { sendit(UA_sock->msg); /* echo to terminal */ @@ -212,7 +209,7 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) } } if (stat < 0) { - break; /* error */ + break; /* error or interrupt */ } else if (stat == 0) { /* timeout */ if (strcmp(prompt, "*") == 0) { bnet_fsend(UA_sock, ".messages"); @@ -241,9 +238,10 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) if (!stop) { sendit("\n"); } - at_prompt = FALSE; + at_prompt = false; } - if (!stop) { + /* Suppress output if running in background or user hit ctl-c */ + if (!stop && !usrbrk()) { sendit(UA_sock->msg); } } @@ -254,7 +252,7 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) break; /* error or term */ } else if (stat == BNET_SIGNAL) { if (UA_sock->msglen == BNET_PROMPT) { - at_prompt = TRUE; + at_prompt = true; } Dmsg1(100, "Got poll %s\n", bnet_sig_to_ascii(UA_sock)); } @@ -270,8 +268,8 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) int main(int argc, char *argv[]) { int ch, i, ndir, item; - int no_signals = FALSE; - int test_config = FALSE; + bool no_signals = false; + bool test_config = false; JCR jcr; init_stack_dump(); @@ -280,6 +278,7 @@ int main(int argc, char *argv[]) init_msg(NULL, NULL); working_directory = "/tmp"; args = get_pool_memory(PM_FNAME); + con_init(stdin); while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) { switch (ch) { @@ -298,17 +297,18 @@ int main(int argc, char *argv[]) break; case 's': /* turn off signals */ - no_signals = TRUE; + no_signals = true; break; case 't': - test_config = TRUE; + test_config = true; break; case '?': default: usage(); - + con_term(); + exit(1); } } argc -= optind; @@ -317,14 +317,19 @@ int main(int argc, char *argv[]) if (!no_signals) { init_signals(terminate_console); } + + /* Override Bacula default signals */ signal(SIGCHLD, SIG_IGN); - signal(SIGTSTP, got_stop); - signal(SIGCONT, got_continue); - signal(SIGTTIN, got_tin); - signal(SIGTTOU, got_tout); + signal(SIGTSTP, got_sigstop); + signal(SIGCONT, got_sigcontinue); + signal(SIGTTIN, got_sigtin); + signal(SIGTTOU, got_sigtout); + trapctlc(); if (argc) { usage(); + con_term(); + exit(1); } if (configfile == NULL) { @@ -335,11 +340,12 @@ int main(int argc, char *argv[]) LockRes(); ndir = 0; - for (dir=NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) { + foreach_res(dir, R_DIRECTOR) { ndir++; } UnlockRes(); if (ndir == 0) { + con_term(); Emsg1(M_ERROR_TERM, 0, _("No Director resource defined in %s\n\ Without that I don't how to speak to the Director :-(\n"), configfile); } @@ -351,7 +357,6 @@ Without that I don't how to speak to the Director :-(\n"), configfile); memset(&jcr, 0, sizeof(jcr)); - con_init(stdin); if (ndir > 1) { UA_sock = init_bsock(NULL, 0, "", "", 0); @@ -359,7 +364,7 @@ try_again: sendit(_("Available Directors:\n")); LockRes(); ndir = 0; - for (dir = NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) { + foreach_res(dir, R_DIRECTOR) { senditf( _("%d %s at %s:%d\n"), 1+ndir++, dir->hdr.name, dir->address, dir->DIRport); } @@ -385,7 +390,6 @@ try_again: UnlockRes(); } - senditf(_("Connecting to Director %s:%d\n"), dir->address,dir->DIRport); UA_sock = bnet_connect(NULL, 5, 15, "Director daemon", dir->address, NULL, dir->DIRport, 0); @@ -404,6 +408,7 @@ try_again: sendit(_("Enter a period to cancel a command.\n")); + /* Run commands in ~/.bconsolerc if any */ char *env = getenv("HOME"); if (env) { FILE *fd; @@ -416,7 +421,6 @@ try_again: } } - read_and_process_input(stdin, UA_sock); if (UA_sock) { @@ -581,15 +585,17 @@ static int inputcmd(FILE *input, BSOCK *UA_sock) return 1; } +/* Send output to both termina and specified file */ static int teecmd(FILE *input, BSOCK *UA_sock) { - tee = 1; + tee = true; return do_outputcmd(input, UA_sock); } +/* Send output to specified "file" */ static int outputcmd(FILE *input, BSOCK *UA_sock) { - tee = 0; + tee = false; return do_outputcmd(input, UA_sock); } @@ -607,7 +613,7 @@ static int do_outputcmd(FILE *input, BSOCK *UA_sock) if (output != stdout) { fclose(output); output = stdout; - tee = 0; + tee = false; } return 1; } @@ -665,7 +671,7 @@ void senditf(char *fmt,...) void sendit(char *buf) { -#ifdef HAVE_CONIO +#ifdef xHAVE_CONIO if (output == stdout || tee) { char *p, *q; /* diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 43367c9f30..19031f5c18 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -878,32 +878,32 @@ e_msg(char *file, int line, int type, int level, char *fmt,...) return; /* no destination */ } switch (type) { - case M_ABORT: - len = sprintf(buf, "%s: ABORTING due to ERROR in %s:%d\n", - my_name, file, line); - break; - case M_ERROR_TERM: - len = sprintf(buf, "%s: ERROR TERMINATION at %s:%d\n", - my_name, file, line); - break; - case M_FATAL: - if (level == -1) /* skip details */ - len = sprintf(buf, "%s: Fatal Error because: ", my_name); - else - len = sprintf(buf, "%s: Fatal Error at %s:%d because:\n", my_name, file, line); - break; - case M_ERROR: - if (level == -1) /* skip details */ - len = sprintf(buf, "%s: Error: ", my_name); - else - len = sprintf(buf, "%s: Error in %s:%d ", my_name, file, line); - break; - case M_WARNING: - len = sprintf(buf, "%s: Warning: ", my_name); - break; - default: - len = sprintf(buf, "%s: ", my_name); - break; + case M_ABORT: + len = sprintf(buf, "%s: ABORTING due to ERROR in %s:%d\n", + my_name, file, line); + break; + case M_ERROR_TERM: + len = sprintf(buf, "%s: ERROR TERMINATION at %s:%d\n", + my_name, file, line); + break; + case M_FATAL: + if (level == -1) /* skip details */ + len = sprintf(buf, "%s: Fatal Error because: ", my_name); + else + len = sprintf(buf, "%s: Fatal Error at %s:%d because:\n", my_name, file, line); + break; + case M_ERROR: + if (level == -1) /* skip details */ + len = sprintf(buf, "%s: Error: ", my_name); + else + len = sprintf(buf, "%s: Error in %s:%d ", my_name, file, line); + break; + case M_WARNING: + len = sprintf(buf, "%s: Warning: ", my_name); + break; + default: + len = sprintf(buf, "%s: ", my_name); + break; } va_start(arg_ptr, fmt); @@ -917,7 +917,7 @@ e_msg(char *file, int line, int type, int level, char *fmt,...) p[0] = 0; /* generate segmentation violation */ } if (type == M_ERROR_TERM) { - _exit(1); + exit(1); } } @@ -1011,7 +1011,7 @@ Jmsg(JCR *jcr, int type, int level, char *fmt,...) p[0] = 0; /* generate segmentation violation */ } if (type == M_ERROR_TERM) { - _exit(1); + exit(1); } } diff --git a/bacula/src/lib/signal.c b/bacula/src/lib/signal.c index 4561f4664c..89151fb5bd 100644 --- a/bacula/src/lib/signal.c +++ b/bacula/src/lib/signal.c @@ -60,17 +60,22 @@ static pid_t main_pid = 0; */ static void signal_handler(int sig) { - static int already_dead = FALSE; + static int already_dead = 0; - if (already_dead) { + /* If we come back more than once, get out fast! */ + if (already_dead > 1) { _exit(1); } + /* If we come back once, take normal exit */ + if (already_dead) { + exit(1); + } Dmsg1(200, "sig=%d\n", sig); /* Ignore certain signals */ if (sig == SIGCHLD || sig == SIGUSR2) { return; } - already_dead = sig; + already_dead++; if (sig == SIGTERM) { Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name); } else { -- 2.39.2