]> git.sur5r.net Git - bacula/bacula/commitdiff
Update from week away
authorKern Sibbald <kern@sibbald.com>
Wed, 17 Dec 2003 18:40:53 +0000 (18:40 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 17 Dec 2003 18:40:53 +0000 (18:40 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@882 91ce42f0-d328-0410-95d8-f526ca767f89

27 files changed:
bacula/autoconf/.cvsignore
bacula/autoconf/config.h.in [deleted file]
bacula/autoconf/configure.in
bacula/configure
bacula/kernstodo
bacula/src/console/Makefile.in
bacula/src/console/authenticate.c
bacula/src/console/conio.c
bacula/src/console/console.c
bacula/src/console/func.h
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/run_conf.c
bacula/src/dird/scheduler.c
bacula/src/dird/ua_output.c
bacula/src/dird/ua_status.c
bacula/src/filed/status.c
bacula/src/lib/btime.c
bacula/src/lib/btime.h
bacula/src/lib/dlist.c
bacula/src/lib/dlist.h
bacula/src/lib/jcr.c
bacula/src/lib/parse_conf.c
bacula/src/lib/parse_conf.h
bacula/src/stored/acquire.c
bacula/src/stored/status.c
bacula/src/version.h

index 71cfdae6ddef9d5022d5458f0bc8cf41f95e874b..0ce96f78a0e99f4b6b3fe3aaf9089451c8b75ad0 100644 (file)
@@ -1 +1,2 @@
 Make.common
+config.h.in
diff --git a/bacula/autoconf/config.h.in b/bacula/autoconf/config.h.in
deleted file mode 100644 (file)
index 0c53e57..0000000
+++ /dev/null
@@ -1,623 +0,0 @@
-/* autoconf/config.h.in.  Generated from autoconf/configure.in by autoheader.  */
-/* ------------------------------------------------------------------------- */
-/* --                     CONFIGURE SPECIFIED FEATURES                    -- */
-/* ------------------------------------------------------------------------- */
-   
-/* Define if you want to use MySQL as Catalog database */
-#undef USE_MYSQL_DB
-
-/* Define if you want SmartAlloc debug code enabled */
-#undef SMARTALLOC
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef daddr_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef major_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef minor_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef ssize_t
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_POSTGRESQL
-
-/* Define if you want to use MySQL */
-#undef HAVE_MYSQL
-
-/* Defined if MySQL thread safe library is present */
-#undef HAVE_THREAD_SAFE_MYSQL
-
-/* Define if you want to use embedded MySQL */
-#undef HAVE_EMBEDDED_MYSQL
-
-/* Define if you want to use SQLite */
-#undef HAVE_SQLITE
-
-/* Define if you want to use Berkeley DB */
-#undef HAVE_BERKELEY_DB
-
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_POSTGRESQL
-
-/* Define if you want to use mSQL */
-#undef HAVE_MSQL
-
-/* Define if you want to use iODBC */
-#undef HAVE_IODBC
-
-/* Define if you want to use unixODBC */
-#undef HAVE_UNIXODBC
-
-/* Define if you want to use Solid SQL Server */
-#undef HAVE_SOLID
-
-/* Define if you want to use OpenLink ODBC (Virtuoso) */
-#undef HAVE_VIRT
-
-/* Define if you want to use EasySoft ODBC */
-#undef HAVE_EASYSOFT
-
-/* Define if you want to use Interbase SQL Server */
-#undef HAVE_IBASE
-
-/* Define if you want to use Oracle 8 SQL Server */
-#undef HAVE_ORACLE8
-
-/* Define if you want to use Oracle 7 SQL Server */
-#undef HAVE_ORACLE7
-
-
-/* ------------------------------------------------------------------------- */
-/* --                     CONFIGURE DETECTED FEATURES                     -- */
-/* ------------------------------------------------------------------------- */
-
-/* Define if you need function prototypes */
-#undef PROTOTYPES
-
-/* Define if you have XPointer typedef */
-#undef HAVE_XPOINTER
-
-/* Define if you have _GNU_SOURCE getpt() */
-#undef HAVE_GETPT
-
-/* Define if you have GCC */
-#undef HAVE_GCC
-
-/* Define if you have the Andrew File System.  */
-#undef AFS
-
-/* Define If you want find -nouser and -nogroup to make tables of
-   used UIDs and GIDs at startup instead of using getpwuid or
-   getgrgid when needed.  Speeds up -nouser and -nogroup unless you
-   are running NIS or Hesiod, which make password and group calls
-   very expensive.  */
-#undef CACHE_IDS
-
-/* Define to use SVR4 statvfs to get filesystem type.  */
-#undef FSTYPE_STATVFS
-
-/* Define to use SVR3.2 statfs to get filesystem type.  */
-#undef FSTYPE_USG_STATFS
-
-/* Define to use AIX3 statfs to get filesystem type.  */
-#undef FSTYPE_AIX_STATFS
-
-/* Define to use 4.3BSD getmntent to get filesystem type.  */
-#undef FSTYPE_MNTENT
-
-/* Define to use 4.4BSD and OSF1 statfs to get filesystem type.  */
-#undef FSTYPE_STATFS
-
-/* Define to use Ultrix getmnt to get filesystem type.  */
-#undef FSTYPE_GETMNT
-
-/* Define to `unsigned long' if <sys/types.h> doesn't define.  */
-#undef dev_t
-
-/* Define to `unsigned long' if <sys/types.h> doesn't define.  */
-#undef ino_t
-
-/* Define to 1 if utime.h exists and declares struct utimbuf.  */
-#undef HAVE_UTIME_H
-
-#if (HAVE_MYSQL||HAVE_POSTGRESQL||HAVE_MSQL||HAVE_IODBC||HAVE_UNIXODBC||HAVE_SOLID||HAVE_VIRT||HAVE_IBASE||HAVE_ORACLE8||HAVE_ORACLE7||HAVE_EASYSOFT)
-#define HAVE_SQL
-#endif
-
-/* Data types */
-#undef HAVE_U_INT
-#undef HAVE_INTXX_T
-#undef HAVE_U_INTXX_T
-#undef HAVE_UINTXX_T
-#undef HAVE_INT64_T
-#undef HAVE_U_INT64_T
-#undef HAVE_INTMAX_T
-#undef HAVE_U_INTMAX_T
-/* Define if you want TCP Wrappers support */
-#undef HAVE_LIBWRAP
-
-/* Define if you have sys/bitypes.h */
-#undef HAVE_SYS_BITYPES_H
-/* Directory for PID files */
-#undef _PATH_BACULA_PIDDIR
-
-/* Define if you have zlib */
-#undef HAVE_LIBZ
-
-/* General libs */
-#undef LIBS
-
-/* File daemon specif libraries */
-#undef FDLIBS
-
-/* Path to Sendmail program */
-#undef SENDMAIL_PATH
-
-/* What kind of signals we have */
-#undef HAVE_POSIX_SIGNALS
-#undef HAVE_BSD_SIGNALS
-#undef HAVE_USG_SIGHOLD
-
-/* Operating systems */
-/* OSes */
-#undef HAVE_LINUX_OS
-#undef HAVE_FREEBSD_OS
-#undef HAVE_NETBSD_OS
-#undef HAVE_OPENBSD_OS
-#undef HAVE_BSDI_OS
-#undef HAVE_HPUX_OS
-#undef HAVE_SUN_OS
-#undef HAVE_IRIX_OS
-#undef HAVE_AIX_OS
-#undef HAVE_SGI_OS
-#undef HAVE_CYGWIN
-#undef HAVE_OSF1_OS
-#undef HAVE_DARWIN_OS
-
-/* Set to correct scanf value for long long int */
-#undef lld
-#undef llu
-
-#undef HAVE_READLINE 
-
-#undef HAVE_GMP
-
-#undef HAVE_CWEB
-
-#undef HAVE_FCHDIR
-
-#undef HAVE_GETOPT_LONG
-
-#undef HAVE_LIBSM
-
-/* Check for thread safe routines */
-#undef HAVE_LOCALTIME_R
-#undef HAVE_READDIR_R
-#undef HAVE_STRERROR_R
-#undef HAVE_GETHOSTBYNAME_R
-
-#undef HAVE_STRTOLL
-#undef HAVE_INET_PTON
-
-#undef HAVE_SOCKLEN_T
-
-#undef HAVE_OLD_SOCKOPT
-#undef HAVE_BIGENDIAN
-
-/* Define to 1 if the `closedir' function returns void instead of `int'. */
-#undef CLOSEDIR_VOID
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
-   systems. This function is required for `alloca.c' support on those systems.
-   */
-#undef CRAY_STACKSEG_END
-
-/* Define to 1 if using `alloca.c'. */
-#undef C_ALLOCA
-
-/* Define to 1 if you have `alloca', as a function or macro. */
-#undef HAVE_ALLOCA
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
-   */
-#undef HAVE_ALLOCA_H
-
-/* Define to 1 if you have the <arpa/nameser.h> header file. */
-#undef HAVE_ARPA_NAMESER_H
-
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
-/* Define to 1 if you have the `chflags' function. */
-#undef HAVE_CHFLAGS
-
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
-   */
-#undef HAVE_DIRENT_H
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
-/* Define to 1 if you have the `fchdir' function. */
-#undef HAVE_FCHDIR
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if your system has a working POSIX `fnmatch' function. */
-#undef HAVE_FNMATCH
-
-/* Define to 1 if you have the `fork' function. */
-#undef HAVE_FORK
-
-/* Define to 1 if you have the `getcwd' function. */
-#undef HAVE_GETCWD
-
-/* Define to 1 if you have the `getdomainname' function. */
-#undef HAVE_GETDOMAINNAME
-
-/* Define to 1 if you have the `gethostbyname_r' function. */
-#undef HAVE_GETHOSTBYNAME_R
-
-/* Define to 1 if you have the `gethostid' function. */
-#undef HAVE_GETHOSTID
-
-/* Define to 1 if you have the `gethostname' function. */
-#undef HAVE_GETHOSTNAME
-
-/* Define to 1 if you have the `getmntent' function. */
-#undef HAVE_GETMNTENT
-
-/* Define to 1 if you have the `getpid' function. */
-#undef HAVE_GETPID
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define to 1 if you have the <grp.h> header file. */
-#undef HAVE_GRP_H
-
-/* Define to 1 if you have the `inet_pton' function. */
-#undef HAVE_INET_PTON
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the `lchown' function. */
-#undef HAVE_LCHOWN
-
-/* Define to 1 if you have the <libc.h> header file. */
-#undef HAVE_LIBC_H
-
-/* Define to 1 if you have the `inet' library (-linet). */
-#undef HAVE_LIBINET
-
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-#undef HAVE_LIBRESOLV
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
-
-/* Define to 1 if you have the `sun' library (-lsun). */
-#undef HAVE_LIBSUN
-
-/* Define to 1 if you have the `xnet' library (-lxnet). */
-#undef HAVE_LIBXNET
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if you have the `localtime_r' function. */
-#undef HAVE_LOCALTIME_R
-
-/* Define to 1 if you have the `lstat' function. */
-#undef HAVE_LSTAT
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <mtio.h> header file. */
-#undef HAVE_MTIO_H
-
-/* Define to 1 if you have the `nanosleep' function. */
-#undef HAVE_NANOSLEEP
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-#undef HAVE_NDIR_H
-
-/* Define to 1 if you have the `putenv' function. */
-#undef HAVE_PUTENV
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#undef HAVE_PWD_H
-
-/* Define to 1 if you have the `readdir_r' function. */
-#undef HAVE_READDIR_R
-
-/* Define to 1 if you have the <resolv.h> header file. */
-#undef HAVE_RESOLV_H
-
-/* Define to 1 if you have the `select' function. */
-#undef HAVE_SELECT
-
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
-/* Define to 1 if you have the `setlocale' function. */
-#undef HAVE_SETLOCALE
-
-/* Define to 1 if you have the `setpgid' function. */
-#undef HAVE_SETPGID
-
-/* Define to 1 if you have the `setpgrp' function. */
-#undef HAVE_SETPGRP
-
-/* Define to 1 if you have the `setsid' function. */
-#undef HAVE_SETSID
-
-/* Define to 1 if you have the `signal' function. */
-#undef HAVE_SIGNAL
-
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#undef HAVE_STDARG_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
-/* Define to 1 if you have the `strerror_r' function. */
-#undef HAVE_STRERROR_R
-
-/* Define to 1 if you have the `strftime' function. */
-#undef HAVE_STRFTIME
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strncmp' function. */
-#undef HAVE_STRNCMP
-
-/* Define to 1 if you have the `strncpy' function. */
-#undef HAVE_STRNCPY
-
-/* Define to 1 if you have the `strtoll' function. */
-#undef HAVE_STRTOLL
-
-/* Define to 1 if `st_blksize' is member of `struct stat'. */
-#undef HAVE_STRUCT_STAT_ST_BLKSIZE
-
-/* Define to 1 if `st_blocks' is member of `struct stat'. */
-#undef HAVE_STRUCT_STAT_ST_BLOCKS
-
-/* Define to 1 if `st_rdev' is member of `struct stat'. */
-#undef HAVE_STRUCT_STAT_ST_RDEV
-
-/* Define to 1 if `tm_zone' is member of `struct tm'. */
-#undef HAVE_STRUCT_TM_TM_ZONE
-
-/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use
-   `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */
-#undef HAVE_ST_BLKSIZE
-
-/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
-   `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
-#undef HAVE_ST_BLOCKS
-
-/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
-   `HAVE_STRUCT_STAT_ST_RDEV' instead. */
-#undef HAVE_ST_RDEV
-
-/* Define to 1 if you have the <sys/byteorder.h> header file. */
-#undef HAVE_SYS_BYTEORDER_H
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
-   */
-#undef HAVE_SYS_DIR_H
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#undef HAVE_SYS_IOCTL_H
-
-/* Define to 1 if you have the <sys/mtio.h> header file. */
-#undef HAVE_SYS_MTIO_H
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
-   */
-#undef HAVE_SYS_NDIR_H
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/sockio.h> header file. */
-#undef HAVE_SYS_SOCKIO_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the `tcgetattr' function. */
-#undef HAVE_TCGETATTR
-
-/* Define to 1 if you have the <termios.h> header file. */
-#undef HAVE_TERMIOS_H
-
-/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
-   `HAVE_STRUCT_TM_TM_ZONE' instead. */
-#undef HAVE_TM_ZONE
-
-/* Define to 1 if you don't have `tm_zone' but do have the external array
-   `tzname'. */
-#undef HAVE_TZNAME
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the <varargs.h> header file. */
-#undef HAVE_VARARGS_H
-
-/* Define to 1 if you have the `vfprintf' function. */
-#undef HAVE_VFPRINTF
-
-/* Define to 1 if you have the `vprintf' function. */
-#undef HAVE_VPRINTF
-
-/* Define to 1 if you have the `vsnprintf' function. */
-#undef HAVE_VSNPRINTF
-
-/* Define to 1 if you have the <zlib.h> header file. */
-#undef HAVE_ZLIB_H
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
-   */
-#undef MAJOR_IN_MKDEV
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
-   <sysmacros.h>. */
-#undef MAJOR_IN_SYSMACROS
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Define to 1 if the `setpgrp' function takes no argument. */
-#undef SETPGRP_VOID
-
-/* The size of a `char', as computed by sizeof. */
-#undef SIZEOF_CHAR
-
-/* The size of a `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* The size of a `int *', as computed by sizeof. */
-#undef SIZEOF_INT_P
-
-/* The size of a `long int', as computed by sizeof. */
-#undef SIZEOF_LONG_INT
-
-/* The size of a `long long int', as computed by sizeof. */
-#undef SIZEOF_LONG_LONG_INT
-
-/* The size of a `short int', as computed by sizeof. */
-#undef SIZEOF_SHORT_INT
-
-/* If using the C implementation of alloca, define if you know the
-   direction of stack growth for your system; otherwise it will be
-   automatically deduced at run-time.
-        STACK_DIRECTION > 0 => grows toward higher addresses
-        STACK_DIRECTION < 0 => grows toward lower addresses
-        STACK_DIRECTION = 0 => direction of growth unknown */
-#undef STACK_DIRECTION
-
-/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
-#undef STAT_MACROS_BROKEN
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-#undef TM_IN_SYS_TIME
-
-/* Define to 1 if the X Window System is missing or not being used. */
-#undef X_DISPLAY_MISSING
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Define to make fseeko etc. visible, on some hosts. */
-#undef _LARGEFILE_SOURCE
-
-/* Define for large files, on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `long' if <sys/types.h> does not define. */
-#undef daddr_t
-
-/* Define to `unsigned long' if <sys/types.h> does not define. */
-#undef dev_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define to `unsigned long' if <sys/types.h> does not define. */
-#undef ino_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef major_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef minor_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef mode_t
-
-/* Define to `long' if <sys/types.h> does not define. */
-#undef off_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-#undef size_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef ssize_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
index 6a1b34bf15c8fcb66b4284f0f7390d90144254b2..4ccd781b3e1eab3fe64502eb31904ea5534e14d6 100644 (file)
@@ -142,8 +142,10 @@ support_mysql=no
 support_sqlite=no
 support_postgresql=no
 support_smartalloc=yes
-support_readline=yes
+support_readline=no
+support_conio=yes
 support_gnome=no
+gnome_version=
 support_static_tools=no
 support_static_fd=no
 support_static_sd=no
@@ -181,10 +183,12 @@ if test x$support_gnome = xyes; then
      AC_SUBST(GNOME_LIBDIR)
      AC_SUBST(GNOME_LIBS)
      GNOME_DIR=src/gnome2-console
+     gnome_version="Version 2.x"
   else
 dnl do 1.4 stuff
-    GNOME_INIT
-    GNOME_DIR=src/gnome-console
+     GNOME_INIT
+     GNOME_DIR=src/gnome-console
+     gnome_version="Version 1.4"
   fi
 fi
 AC_SUBST(GNOME_DIR)
@@ -294,11 +298,34 @@ fi
 AC_SUBST(ALL_DIRS)
 
 # ---------------------------------------------------
-# Check for readline support/directory (default on)
+# Check for conio (Bacula readline substitute)(
+# ---------------------------------------------------
+# this allows you to turn it completely off
+AC_ARG_ENABLE(conio,   
+  [  --disable-conio        disable conio support [enabled]
+                                                     ],
+  [if test x$enableval = xno; then
+    support_conio=no
+  fi])
+
+got_conio="no"
+if test x$support_conio = xyes; then
+   CONS_OBJ="conio.o"
+   CONS_SRC="conio.c"
+   got_conio="yes"
+   AC_CHECK_HEADERS(termcap.h)
+   AC_CHECK_LIB(termcap, tgetent, CONS_LIBS="-ltermcap")
+   support_readline=no
+   AC_DEFINE(HAVE_CONIO, 1, [Set if Bacula conio support enabled]) 
+fi
+
+
+# ---------------------------------------------------
+# Check for readline support/directory (default off)
 # ---------------------------------------------------
 # this allows you to turn it completely off
 AC_ARG_ENABLE(readline,
-  [  --disable-readline      disable readline support [enabled]
+  [  --disable-readline      disable readline support [disable]
                                                      ],
   [if test x$enableval = xno; then
     support_readline=no
@@ -354,7 +381,12 @@ if test x$support_readline = xyes; then
      ]  
    )
 fi
+
+
+
 AC_SUBST(CONS_INC)
+AC_SUBST(CONS_OBJ)
+AC_SUBST(CONS_SRC)
 AC_SUBST(CONS_LIBS)
 AC_SUBST(CONS_LDFLAGS)
 AC_SUBST(READLINE_SRC)
@@ -371,7 +403,7 @@ AC_CHECK_FUNCS(nanosleep)
 
 AC_CHECK_HEADERS(varargs.h)
 
-# End of readline stuff
+# End of readline/conio stuff
 # -----------------------------------------------------------------------
 
 
@@ -820,16 +852,8 @@ AC_SUBST(fd_group)
 # ------------------------------------------------
 BA_CHECK_POSTGRESQL_DB
 
-
-# ------------------------------------------------
-# Bacula check for various SQL database engines
-# ------------------------------------------------
 BA_CHECK_MYSQL_DB
 
-
-# ------------------------------------------------
-# Bacula check for various SQL database engines
-# ------------------------------------------------
 BA_CHECK_SQLITE_DB
 
 AC_SUBST(cats)
@@ -1559,7 +1583,7 @@ cd ..
 chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables
 chmod 755 src/cats/make_postgresql_tables src/cats/drop_postgresql_tables
 chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
-chmod 755 src/cats/create_postgresql_database 
+chmod 755 src/cats/create_postgresql_database
 chmod 755 src/cats/create_mysql_database 
 chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
 chmod 755 src/cats/grant_postgresql_privileges
@@ -1636,21 +1660,22 @@ Configuration on `date`:
   File daemon Port:          ${fd_port}
   Storage daemon Port:       ${sd_port}
 
-  Director User:           ${dir_user}
-  Director Group:          ${dir_group}
-  Storage Daemon User:     ${dir_user}
-  Storage Daemon Group:            ${dir_group}
-  File Daemon User:        ${dir_user}
-  File Daemon Group:       ${dir_group}
+  Director User:             ${dir_user}
+  Director Group:            ${dir_group}
+  Storage Daemon User:       ${dir_user}
+  Storage DaemonGroup:       ${dir_group}
+  File Daemon User:          ${dir_user}
+  File Daemon Group:         ${dir_group}
 
   SQL binaries Directory      ${SQL_BINDIR}
 
   Large file support:        $largefile_support
+  Bacula conio support:       ${got_conio} ${CONS_LIBS}
   readline support:          ${got_readline} ${PRTREADLINE_SRC}
   TCP Wrappers support:       ${TCPW_MSG}
   ZLIB support:              ${have_zlib}
   enable-smartalloc:         ${support_smartalloc} 
-  enable-gnome:              ${support_gnome}
+  enable-gnome:              ${support_gnome} ${gnome_version}
   client-only:               ${build_client_only}
 
   " > config.out
index 3f59b2f5c8844ba8f15b391c500bcef367c0b852..4efdf24bc408a67a5047ed25b54f0adfd8144b62 100755 (executable)
@@ -308,7 +308,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS BUILD_DIR TRUEPRG FALSEPRG build build_cpu build_vendor build_os host host_cpu host_vendor host_os VERSION DATE LSMDATE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB MV RM CP SED AWK ECHO CMP TBL AR OPENSSL MTX PKGCONFIG ARFLAGS MAKE_SHELL LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS HAVE_SUN_OS_TRUE HAVE_SUN_OS_FALSE HAVE_OSF1_OS_TRUE HAVE_OSF1_OS_FALSE HAVE_AIX_OS_TRUE HAVE_AIX_OS_FALSE HAVE_HPUX_OS_TRUE HAVE_HPUX_OS_FALSE HAVE_LINUX_OS_TRUE HAVE_LINUX_OS_FALSE HAVE_FREEBSD_OS_TRUE HAVE_FREEBSD_OS_FALSE HAVE_NETBSD_OS_TRUE HAVE_NETBSD_OS_FALSE HAVE_OPENBSD_OS_TRUE HAVE_OPENBSD_OS_FALSE HAVE_BSDI_OS_TRUE HAVE_BSDI_OS_FALSE HAVE_SGI_OS_TRUE HAVE_SGI_OS_FALSE HAVE_IRIX_OS_TRUE HAVE_IRIX_OS_FALSE HAVE_DARWIN_OS_TRUE HAVE_DARWIN_OS_FALSE INSIDE_GNOME_COMMON_TRUE INSIDE_GNOME_COMMON_FALSE MSGFMT GNOME_INCLUDEDIR GNOMEUI_LIBS GNOME_LIBDIR GNOME_LIBS GNOMEGNORBA_LIBS GTKXMHTML_LIBS ZVT_LIBS GNOME_CONFIG ORBIT_CONFIG ORBIT_IDL HAVE_ORBIT_TRUE HAVE_ORBIT_FALSE ORBIT_CFLAGS ORBIT_LIBS HAVE_GNORBA_TRUE HAVE_GNORBA_FALSE GNORBA_CFLAGS GNORBA_LIBS GNOME_APPLETS_LIBS GNOME_DOCKLETS_LIBS GNOME_CAPPLET_LIBS GNOME_DIR TTOOL_LDFLAGS STATIC_FD STATIC_SD STATIC_DIR STATIC_CONS ALL_DIRS CONS_INC CONS_LIBS CONS_LDFLAGS READLINE_SRC working_dir scriptdir dump_email job_email smtp_host piddir subsysdir baseport dir_port fd_port sd_port dir_password fd_password sd_password dir_user dir_group sd_user sd_group fd_user fd_group SQL_LFLAGS SQL_INCLUDE SQL_BINDIR cats DB_NAME GETCONF ac_ct_GETCONF X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LIBOBJS ALLOCA FDLIBS DEBUG DINCLUDE DLIB DB_LIBS WCFLAGS WLDFLAGS OBJLIST hostname TAPEDRIVE PSCMD WIN32 DISTNAME DISTVER LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS BUILD_DIR TRUEPRG FALSEPRG build build_cpu build_vendor build_os host host_cpu host_vendor host_os VERSION DATE LSMDATE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB MV RM CP SED AWK ECHO CMP TBL AR OPENSSL MTX PKGCONFIG ARFLAGS MAKE_SHELL LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS HAVE_SUN_OS_TRUE HAVE_SUN_OS_FALSE HAVE_OSF1_OS_TRUE HAVE_OSF1_OS_FALSE HAVE_AIX_OS_TRUE HAVE_AIX_OS_FALSE HAVE_HPUX_OS_TRUE HAVE_HPUX_OS_FALSE HAVE_LINUX_OS_TRUE HAVE_LINUX_OS_FALSE HAVE_FREEBSD_OS_TRUE HAVE_FREEBSD_OS_FALSE HAVE_NETBSD_OS_TRUE HAVE_NETBSD_OS_FALSE HAVE_OPENBSD_OS_TRUE HAVE_OPENBSD_OS_FALSE HAVE_BSDI_OS_TRUE HAVE_BSDI_OS_FALSE HAVE_SGI_OS_TRUE HAVE_SGI_OS_FALSE HAVE_IRIX_OS_TRUE HAVE_IRIX_OS_FALSE HAVE_DARWIN_OS_TRUE HAVE_DARWIN_OS_FALSE INSIDE_GNOME_COMMON_TRUE INSIDE_GNOME_COMMON_FALSE MSGFMT GNOME_INCLUDEDIR GNOMEUI_LIBS GNOME_LIBDIR GNOME_LIBS GNOMEGNORBA_LIBS GTKXMHTML_LIBS ZVT_LIBS GNOME_CONFIG ORBIT_CONFIG ORBIT_IDL HAVE_ORBIT_TRUE HAVE_ORBIT_FALSE ORBIT_CFLAGS ORBIT_LIBS HAVE_GNORBA_TRUE HAVE_GNORBA_FALSE GNORBA_CFLAGS GNORBA_LIBS GNOME_APPLETS_LIBS GNOME_DOCKLETS_LIBS GNOME_CAPPLET_LIBS GNOME_DIR TTOOL_LDFLAGS STATIC_FD STATIC_SD STATIC_DIR STATIC_CONS ALL_DIRS CONS_INC CONS_OBJ CONS_SRC CONS_LIBS CONS_LDFLAGS READLINE_SRC working_dir scriptdir dump_email job_email smtp_host piddir subsysdir baseport dir_port fd_port sd_port dir_password fd_password sd_password dir_user dir_group sd_user sd_group fd_user fd_group SQL_LFLAGS SQL_INCLUDE SQL_BINDIR cats DB_NAME GETCONF ac_ct_GETCONF X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LIBOBJS ALLOCA FDLIBS DEBUG DINCLUDE DLIB DB_LIBS WCFLAGS WLDFLAGS OBJLIST hostname TAPEDRIVE PSCMD WIN32 DISTNAME DISTVER LTLIBOBJS'
 ac_subst_files='MCOMMON'
 
 # Initialize some variables set by options.
@@ -863,7 +863,9 @@ Optional Features:
   --enable-static-dir     enable static Director disabled
   --enable-static-cons    enable static Console disabled
   --enable-client-only    build client (File daemon) only disabled
-  --disable-readline      disable readline support enabled
+  --disable-conio           disable conio support enabled
+
+  --disable-readline      disable readline support disable
 
   --disable-largefile     omit support for large files
 
@@ -898,11 +900,6 @@ Which DBMS do you want to use (please select only one):
                           install directory, default is to search through
                           a number of common places for the MySQL files.
 
-Which DBMS do you want to use (please select only one):
-  --with-postgresql=DIR Include PostgreSQL support.  DIR is the PostgreSQL base
-                          install directory, default is to search through
-                          a number of common places for the PostgreSQL files.
-
 Which DBMS do you want to use (please select only one):
   --with-embedded-mysql=DIR Include MySQL support.  DIR is the MySQL base
                           install directory, default is to search through
@@ -4323,8 +4320,10 @@ support_mysql=no
 support_sqlite=no
 support_postgresql=no
 support_smartalloc=yes
-support_readline=yes
+support_readline=no
+support_conio=yes
 support_gnome=no
+gnome_version=
 support_static_tools=no
 support_static_fd=no
 support_static_sd=no
@@ -4361,6 +4360,7 @@ if test x$support_gnome = xyes; then
 
 
      GNOME_DIR=src/gnome2-console
+     gnome_version="Version 2.x"
   else
 
 
@@ -4701,7 +4701,8 @@ echo "${ECHO_T}unknown library" >&6
         fi
 
 
-    GNOME_DIR=src/gnome-console
+     GNOME_DIR=src/gnome-console
+     gnome_version="Version 1.4"
   fi
 fi
 
@@ -4828,20 +4829,22 @@ fi
 
 
 # ---------------------------------------------------
-# Check for readline support/directory (default on)
+# Check for conio (Bacula readline substitute)(
 # ---------------------------------------------------
 # this allows you to turn it completely off
-# Check whether --enable-readline or --disable-readline was given.
-if test "${enable_readline+set}" = set; then
-  enableval="$enable_readline"
+# Check whether --enable-conio or --disable-conio was given.
+if test "${enable_conio+set}" = set; then
+  enableval="$enable_conio"
   if test x$enableval = xno; then
-    support_readline=no
+    support_conio=no
   fi
 fi;
 
-got_readline="no"
-READLINE_SRC=
-if test x$support_readline = xyes; then
+got_conio="no"
+if test x$support_conio = xyes; then
+   CONS_OBJ="conio.o"
+   CONS_SRC="conio.c"
+   got_conio="yes"
    echo "$as_me:$LINENO: checking for ANSI C header files" >&5
 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
 if test "${ac_cv_header_stdc+set}" = set; then
@@ -5066,6 +5069,230 @@ done
 
 
 
+for ac_header in termcap.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+   echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
+echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
+if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_termcap_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_termcap_tgetent=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
+if test $ac_cv_lib_termcap_tgetent = yes; then
+  CONS_LIBS="-ltermcap"
+fi
+
+   support_readline=no
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CONIO 1
+_ACEOF
+
+fi
+
+
+# ---------------------------------------------------
+# Check for readline support/directory (default off)
+# ---------------------------------------------------
+# this allows you to turn it completely off
+# Check whether --enable-readline or --disable-readline was given.
+if test "${enable_readline+set}" = set; then
+  enableval="$enable_readline"
+  if test x$enableval = xno; then
+    support_readline=no
+  fi
+fi;
+
+got_readline="no"
+READLINE_SRC=
+if test x$support_readline = xyes; then
+
 # Check whether --with-readline or --without-readline was given.
 if test "${with_readline+set}" = set; then
   withval="$with_readline"
@@ -5537,6 +5764,11 @@ fi
 
 
 
+
+
+
+
+
 # Minimal stuff for readline Makefile configuration
 MAKE_SHELL=/bin/sh
 
@@ -6201,7 +6433,7 @@ fi
 done
 
 
-# End of readline stuff
+# End of readline/conio stuff
 # -----------------------------------------------------------------------
 
 
@@ -6779,89 +7011,10 @@ fi;
 # ------------------------------------------------
 # Bacula check for various SQL database engines
 # ------------------------------------------------
-
-db_found=no
-echo "$as_me:$LINENO: checking for PostgreSQL support" >&5
-echo $ECHO_N "checking for PostgreSQL support... $ECHO_C" >&6
-
-# Check whether --with-postgresql was given.
-if test "${with_postgresql+set}" = set; then
-  withval="$with_postgresql"
-
-  if test "$withval" != "no"; then
-        if test "$withval" = "yes"; then
-                if test -f /usr/local/postgresql/include/postgresql/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=/usr/local/postgresql/include/postgresql
-                        POSTGRESQL_LIBDIR=/usr/local/postgresql/lib/postgresql
-                        POSTGRESQL_BINDIR=/usr/local/postgresql/bin
-                elif test -f /usr/include/postgresql/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=/usr/include/postgresql
-                        POSTGRESQL_LIBDIR=/usr/lib/postgresql
-                        POSTGRESQL_BINDIR=/usr/bin
-                elif test -f /usr/include/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=/usr/include
-                        POSTGRESQL_LIBDIR=/usr/lib
-                        POSTGRESQL_BINDIR=/usr/bin
-                elif test -f /usr/local/include/postgresql/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=/usr/local/include/postgresql
-                        POSTGRESQL_LIBDIR=/usr/local/lib/postgresql
-                        POSTGRESQL_BINDIR=/usr/local/bin
-                elif test -f /usr/local/include/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=/usr/local/include
-                        POSTGRESQL_LIBDIR=/usr/local/lib
-                        POSTGRESQL_BINDIR=/usr/local/bin
-                else
-                   echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-                   { { echo "$as_me:$LINENO: error: Unable to find libpq-fe.h in standard locations" >&5
-echo "$as_me: error: Unable to find libpq-fe.h in standard locations" >&2;}
-   { (exit 1); exit 1; }; }
-                fi
-        else
-                if test -f $withval/include/postgresql/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=$withval/include/postgresql
-                        POSTGRESQL_LIBDIR=$withval/lib/postgresql
-                        POSTGRESQL_BINDIR=$withval/bin
-                elif test -f $withval/include/libpq-fe.h; then
-                        POSTGRESQL_INCDIR=$withval/include
-                        POSTGRESQL_LIBDIR=$withval/lib
-                        POSTGRESQL_BINDIR=$withval/bin
-                else
-                   echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-                   { { echo "$as_me:$LINENO: error: Invalid PostgreSQL directory $withval - unable to find libpq-fe.h under $withval" >&5
-echo "$as_me: error: Invalid PostgreSQL directory $withval - unable to find libpq-fe.h under $withval" >&2;}
-   { (exit 1); exit 1; }; }
-                fi
-        fi
-    SQL_INCLUDE=-I$POSTGRESQL_INCDIR
-    SQL_LFLAGS="-L$POSTGRESQL_LIBDIR -lpq -lz"
-    SQL_BINDIR=$POSTGRESQL_BINDIR
-
-    cat >>confdefs.h <<\_ACEOF
-#define HAVE_POSTGRESQL 1
-_ACEOF
-
-    echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-    db_found=yes
-    support_postgresql=yes
-    db_name=PostgreSQL
-    DB_NAME=postgresql
-
-  else
-        echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-  fi
-
-else
-
-    echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-
-fi;
+BA_CHECK_POSTGRESQL_DB
 
 
+db_found=no
 echo "$as_me:$LINENO: checking for MySQL support" >&5
 echo $ECHO_N "checking for MySQL support... $ECHO_C" >&6
 
@@ -7040,10 +7193,6 @@ fi;
 
 
 
-# ------------------------------------------------
-# Bacula check for various SQL database engines
-# ------------------------------------------------
-
 db_found=no
 echo "$as_me:$LINENO: checking for SQLite support" >&5
 echo $ECHO_N "checking for SQLite support... $ECHO_C" >&6
@@ -17663,7 +17812,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/make_postgresql_tables src/cats/drop_postgresql_tables src/cats/update_postgresql_tables src/cats/create_postgresql_database src/cats/grant_postgresql_privileges src/cats/make_mysql_tables src/cats/drop_mysql_tables src/cats/update_mysql_tables src/cats/create_mysql_database src/cats/grant_mysql_privileges src/cats/grant_postgresql_privileges src/cats/make_sqlite_tables src/cats/drop_sqlite_tables src/cats/update_sqlite_tables src/cats/create_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/make_bdb_tables src/cats/drop_bdb_tables src/cats/create_bacula_database src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/update_bacula_tables 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/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/make_postgresql_tables src/cats/drop_postgresql_tables src/cats/create_postgresql_database src/cats/grant_postgresql_privileges src/cats/make_mysql_tables src/cats/drop_mysql_tables src/cats/update_mysql_tables src/cats/create_mysql_database src/cats/grant_mysql_privileges src/cats/make_sqlite_tables src/cats/drop_sqlite_tables src/cats/update_sqlite_tables src/cats/create_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/make_bdb_tables src/cats/drop_bdb_tables src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/update_bacula_tables 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
@@ -18235,7 +18384,6 @@ do
   "src/cats/delete_catalog_backup" ) CONFIG_FILES="$CONFIG_FILES src/cats/delete_catalog_backup" ;;
   "src/cats/make_postgresql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_postgresql_tables" ;;
   "src/cats/drop_postgresql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_postgresql_tables" ;;
-  "src/cats/update_postgresql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_postgresql_tables" ;;
   "src/cats/create_postgresql_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_postgresql_database" ;;
   "src/cats/grant_postgresql_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_postgresql_privileges" ;;
   "src/cats/make_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_mysql_tables" ;;
@@ -18253,8 +18401,6 @@ do
   "src/cats/make_bdb_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_bdb_tables" ;;
   "src/cats/drop_bdb_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_bdb_tables" ;;
   "src/cats/make_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_bacula_tables" ;;
-  "src/cats/create_bacula_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_bacula_database" ;;
-  "src/cats/grant_bacula_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_bacula_privileges" ;;
   "src/cats/drop_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_bacula_tables" ;;
   "src/cats/update_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_bacula_tables" ;;
   "src/findlib/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/findlib/Makefile" ;;
@@ -18452,6 +18598,8 @@ s,@STATIC_DIR@,$STATIC_DIR,;t t
 s,@STATIC_CONS@,$STATIC_CONS,;t t
 s,@ALL_DIRS@,$ALL_DIRS,;t t
 s,@CONS_INC@,$CONS_INC,;t t
+s,@CONS_OBJ@,$CONS_OBJ,;t t
+s,@CONS_SRC@,$CONS_SRC,;t t
 s,@CONS_LIBS@,$CONS_LIBS,;t t
 s,@CONS_LDFLAGS@,$CONS_LDFLAGS,;t t
 s,@READLINE_SRC@,$READLINE_SRC,;t t
@@ -19031,7 +19179,7 @@ cd ..
 chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables
 chmod 755 src/cats/make_postgresql_tables src/cats/drop_postgresql_tables
 chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
-chmod 755 src/cats/create_postgresql_database 
+chmod 755 src/cats/create_postgresql_database
 chmod 755 src/cats/create_mysql_database
 chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
 chmod 755 src/cats/grant_postgresql_privileges
@@ -19039,8 +19187,6 @@ chmod 755 src/cats/grant_mysql_privileges
 chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
 chmod 755 src/cats/update_sqlite_tables
 chmod 755 src/cats/make_bacula_tables src/cats/drop_bacula_tables
-chmod 755 src/cats/create_bacula_database
-chmod 755 src/cats/grant_bacula_privileges
 chmod 755 src/cats/update_mysql_tables
 chmod 755 src/cats/update_bacula_tables src/cats/update_mysql_tables
 chmod 755 src/cats/create_sqlite_database
@@ -19110,21 +19256,22 @@ Configuration on `date`:
   File daemon Port:          ${fd_port}
   Storage daemon Port:       ${sd_port}
 
-  Director User:           ${dir_user}
-  Director Group:          ${dir_group}
-  Storage Daemon User:     ${dir_user}
-  Storage Daemon Group:            ${dir_group}
-  File Daemon User:        ${dir_user}
-  File Daemon Group:       ${dir_group}
+  Director User:             ${dir_user}
+  Director Group:            ${dir_group}
+  Storage Daemon User:       ${dir_user}
+  Storage DaemonGroup:       ${dir_group}
+  File Daemon User:          ${dir_user}
+  File Daemon Group:         ${dir_group}
 
   SQL binaries Directory      ${SQL_BINDIR}
 
   Large file support:        $largefile_support
+  Bacula conio support:       ${got_conio} ${CONS_LIBS}
   readline support:          ${got_readline} ${PRTREADLINE_SRC}
   TCP Wrappers support:       ${TCPW_MSG}
   ZLIB support:              ${have_zlib}
   enable-smartalloc:         ${support_smartalloc}
-  enable-gnome:              ${support_gnome}
+  enable-gnome:              ${support_gnome} ${gnome_version}
   client-only:               ${build_client_only}
 
   " > config.out
index 2daed48cbdf35a42c38bc0da9ce25663bf94deb0..196bc740333ebc9718466a1b7cc752d7a08d2b0c 100644 (file)
@@ -46,8 +46,10 @@ For 1.33 Testing/Documentation:
 - Add some examples of job editing codes.
 
 - Document Dan's new --with-dir-user, ... options.
+  See userid.txt
 - Figure out how to use ssh or stunnel to protect Bacula communications.
   Add Dan's work to manual
+  See ssl.txt
 - Add db check test to regression. Test each function like delete,
   purge, ...
 - Add subsections to the Disaster Recovery index section.
index 062028f3f5c4ac556c065915be60948c502964fc..4b2bf38a590088e3519edca9970bc87d5249565d 100644 (file)
@@ -20,8 +20,8 @@ first_rule: all
 dummy:
 
 #
-CONSSRCS = console.c console_conf.c authenticate.c 
-CONSOBJS = console.o console_conf.o authenticate.o 
+CONSSRCS = console.c console_conf.c authenticate.c @CONS_SRC@ 
+CONSOBJS = console.o console_conf.o authenticate.o @CONS_OBJ@
 
 # these are the objects that are changed by the .configure process
 EXTRAOBJS = @OBJLIST@
index b378a0976f84a6b1f544a8ad0f9dce563568d67a..ef679da18266d8966abe49b2e57879e6c8e73fe7 100644 (file)
@@ -33,6 +33,9 @@
 #include "jcr.h"
 
 
+void senditf(char *fmt, ...);
+void sendit(char *buf); 
+
 /* Commands sent to Director */
 static char hello[]    = "Hello %s calling\n";
 
@@ -56,24 +59,23 @@ int authenticate_director(JCR *jcr, DIRRES *director)
 
    if (!cram_md5_get_auth(dir, director->password, ssl_need) || 
        !cram_md5_auth(dir, director->password, ssl_need)) {
-      Pmsg0(-1, _("Director authorization problem.\n"
+      sendit( _("Director authorization problem.\n"
             "Most likely the passwords do not agree.\n"));  
       return 0;
    }
 
    Dmsg1(6, ">dird: %s", dir->msg);
    if (bnet_recv(dir) <= 0) {
-      Pmsg1(-1, "Bad response to Hello command: ERR=%s\n",
+      senditf(_("Bad response to Hello command: ERR=%s\n"),
         bnet_strerror(dir));
-      Pmsg0(-1, "The Director is probably not running.\n");
       return 0;
    }
    Dmsg1(10, "<dird: %s", dir->msg);
    if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) {
-      Pmsg0(-1, "Director rejected Hello command\n");
+      sendit(_("Director rejected Hello command\n"));
       return 0;
    } else {
-      Pmsg1(-1, "%s", dir->msg);
+      sendit(dir->msg);
    }
    return 1;
 }
index f44c72c4f008bfdac7e0a786ca97ed3fd18bc232..6baa57d7c4a9d6477561769c8e10ea974d46d12b 100755 (executable)
@@ -1,10 +1,10 @@
 /*       
-      Generalized consol input/output handler
+      Generalized console input/output handler
       Kern Sibbald, December MMIII
 */
 
 #define BACULA
-#ifdef BACULA
+#ifdef BACULA
 #include "bacula.h"
 #else
 #include <stdio.h>
 #include <ctype.h> 
 #endif
 
+/*
 #include <curses.h>
 #include <term.h>
+*/
+#include <termcap.h>
 #include "func.h"
 
 /* Global functions imported */
@@ -33,17 +36,13 @@ extern char *UP;
 
 static char *t_up = "\n";                    /* scroll up character */
 static char *t_honk = "\007";                /* sound beep */
-static char *t_flag = "+";                   /* mark flag sequence */
-static char *t_norm = " ";                   /* clear mark sequence */
 static char *t_il;                          /* insert line */
 static char *t_dl;                          /* delete line */
 static char *t_cs;                          /* clear screen */
 static char *t_cl;                          /* clear line */
 static int t_width = 79;                    /* terminal width */
 static int t_height = 24;                   /* terminal height */
-static int t_flagl = 1;                     /* # chars for flag */
 static int linsdel_ok = 0;             /* set if term has line insert & delete fncs */
-static short dioflag = 1;                   /* set if ok to use ibm bios calls */
 
 static char *t_cm;                          /* cursor positioning */
 static char *t_ti;                          /* init sequence */
@@ -54,20 +53,10 @@ static char *t_sf;                       /* scroll screen one line up */
 /* Keypad and Function Keys */
 static char *kl;                            /* left key */
 static char *kr;                            /* right */
-static char *ku;
-static char *kd;
+static char *ku;                            /* up */
+static char *kd;                            /* down */
 static char *kh;                            /* home */
 static char *kb;                            /* backspace */
-static char *k0;                            /* function key 10 */
-static char *k1;                            /* function key 1 */
-static char *k2;                            /* function key 2 */
-static char *k3;                            /* function key 3 */
-static char *k4;                            /* function key 4 */
-static char *k5;                            /* function key 5 */
-static char *k6;                            /* function key 6 */
-static char *k7;                            /* function key 7 */
-static char *k8;                            /* function key 8 */
-static char *k9;                            /* function key 9 */
 static char *kD;                            /* delete key */
 static char *kI;                            /* insert */
 static char *kN;                            /* next page */
@@ -75,7 +64,6 @@ static char *kP;                           /* previous page */
 static char *kH;                            /* home */
 static char *kE;                            /* end */
 
-static int use_termcap;
 #ifndef EOS
 #define EOS  '\0'                     /* end of string terminator */
 #endif
@@ -100,6 +88,7 @@ static int num_stab;                      /* size of stab array */
 
 /* Local variables */
 
+static bool old_term_params_set = false;
 static struct termios old_term_params;
 
 /* Maintain lines in a doubly linked circular pool of lines. Each line is
@@ -136,22 +125,23 @@ static void sigintcatcher(int);
 /* Global variables Exported */
 
 static short char_map[600]= {
-   0,                                 F_NXTWRD, /* ^A Next Word */
-   F_SPLIT,  /* ^B Split line */       F_EOI,   /* ^C Quit */
-   F_DELCHR, /* ^D Delete character */ F_EOF,   /* ^E End of file */
-   F_INSCHR, /* ^F Insert character */ F_TABBAK, /* ^G Back tab */
+   0,                                 F_SOL,    /* ^a Line start */
+   F_PRVWRD, /* ^b Previous word */    F_BREAK,  /* ^C break */
+   F_DELCHR, /* ^D Delete character */ F_EOL,   /* ^e End of line */
+   F_CSRRGT, /* ^f Right */           F_TABBAK, /* ^G Back tab */
    F_CSRLFT, /* ^H Left */            F_TAB,    /* ^I Tab */
-   F_CSRDWN, /* ^J Down */            F_CSRUP,  /* ^K Up */
-   F_CSRRGT, /* ^L Right */           F_RETURN, /* ^M Carriage return */
-   F_EOL,    /* ^N End of line */      F_CONCAT, /* ^O Concatenate lines */
-   F_MARK,   /* ^P Set marker */       F_TINS,  /* ^Q Insert character mode */
+   F_CSRDWN, /* ^J Down */            F_DELEOL, /* ^K kill to eol */
+   F_CLRSCRN,/* ^L clear screen */     F_RETURN, /* ^M Carriage return */
+   F_RETURN, /* ^N enter line  */      F_CONCAT, /* ^O Concatenate lines */
+   F_CSRUP,  /* ^P cursor up */        F_TINS,  /* ^Q Insert character mode */
    F_PAGUP,  /* ^R Page up */         F_CENTER, /* ^S Center text */
-   F_PAGDWN, /* ^T Page down */        F_SOL,   /* ^U Line start */
+   F_PAGDWN, /* ^T Page down */        F_DELSOL, /* ^U delete to start of line */
    F_DELWRD, /* ^V Delete word */      F_PRVWRD, /* ^W Previous word */
    F_NXTMCH, /* ^X Next match */       F_DELEOL, /* ^Y Delete to end of line */
-   F_DELLIN, /* ^Z Delete line */      0x1B,    /* ^[=ESC escape */
+   F_BACKGND,/* ^Z Background */       0x1B,    /* ^[=ESC escape */
    F_TENTRY, /* ^\ Entry mode */       F_PASTECB,/* ^]=paste clipboard */
    F_HOME,   /* ^^ Home */            F_ERSLIN, /* ^_ Erase line */
+
    ' ','!','"','#','$','%','&','\047',
    '(',')','*','+','\054','-','.','/',
    '0','1','2','3','4','5','6','7',
@@ -199,11 +189,13 @@ static void t_honk_horn(void);
 static void t_insert_line(void);
 static void t_delete_line(void);
 static void t_clrline(int pos, int width);
-static void t_sendl(char *msg, int len);
-static void t_send(char *msg);
-static void t_char(char c);
+void t_sendl(char *msg, int len);
+void t_send(char *msg);
+void t_char(char c);
+static void asclrs();
+static void ascurs(int y, int x);
 
-static void rawmode(void);
+static void rawmode(FILE *input);
 static void normode(void);
 static int t_getch();
 static void trapctlc();
@@ -213,12 +205,51 @@ static void asdell();
 
 int input_line(char *string, int length);
 
-void con_init(
+void con_init(FILE *input)
 {
-   rawmode();
+   rawmode(input);
    trapctlc();
 }
 
+/*
+ * Zed control keys
+ */
+void con_set_zed_keys(void)
+{
+   char_map[1] = F_NXTWRD; /* ^A Next Word */
+   char_map[2] = F_SPLIT;  /* ^B Split line */
+   char_map[3] = F_EOI;    /* ^C Quit */
+   char_map[4] = F_DELCHR; /* ^D Delete character */
+   char_map[5] = F_EOF;    /* ^E End of file */
+   char_map[6] = F_INSCHR; /* ^F Insert character */
+   char_map[7] = F_TABBAK; /* ^G Back tab */
+   char_map[8] = F_CSRLFT; /* ^H Left */
+   char_map[9] = F_TAB;    /* ^I Tab */
+   char_map[10] = F_CSRDWN; /* ^J Down */
+   char_map[11] = F_CSRUP;  /* ^K Up */
+   char_map[12] = F_CSRRGT; /* ^L Right */
+   char_map[13] = F_RETURN; /* ^M Carriage return */
+   char_map[14] = F_EOL;    /* ^N End of line */
+   char_map[15] = F_CONCAT; /* ^O Concatenate lines */
+   char_map[16] = F_MARK;   /* ^P Set marker */
+   char_map[17] = F_TINS;   /* ^Q Insert character mode */
+   char_map[18] = F_PAGUP;  /* ^R Page up */
+   char_map[19] = F_CENTER; /* ^S Center text */
+   char_map[20] = F_PAGDWN; /* ^T Page down */
+   char_map[21] = F_SOL;    /* ^U Line start */
+   char_map[22] = F_DELWRD; /* ^V Delete word */
+   char_map[23] = F_PRVWRD; /* ^W Previous word */
+   char_map[24] = F_NXTMCH; /* ^X Next match */
+   char_map[25] = F_DELEOL; /* ^Y Delete to end of line */
+   char_map[26] = F_DELLIN; /* ^Z Delete line */
+   /* 27 = ESC */
+   char_map[28] = F_TENTRY; /* ^\ Entry mode */
+   char_map[29] = F_PASTECB;/* ^]=paste clipboard */
+   char_map[30] = F_HOME;   /* ^^ Home */
+   char_map[31] = F_ERSLIN; /* ^_ Erase line */
+
+}
+
 void con_term()
 {
    normode();
@@ -358,7 +389,7 @@ static int
     if (c == F_SCRSIZ) {
        int y, x;
        y = t_gnc() - 0x20;       /* y */
-       x = t_gnc() - 0x20;     /* x */
+       x = t_gnc() - 0x20;       /* x */
        c = input_char();
     }
     return c;
@@ -384,13 +415,16 @@ int
        case F_RETURN:                /* CR */
             t_sendl("\r\n", 2);       /* yes, print it and */
            goto done;                /* get out */
+       case F_CLRSCRN:               /* clear screen */
+          asclrs();
+          t_sendl(curline, cl);
+          ascurs(0, cp);
+          break;
        case F_CSRUP:
-#ifdef xxx
            if (noline) {             /* no line fetched yet */
                getnext();            /* getnext so getprev gets current */
                noline = 0;           /* we now have line */
            }
-#endif
            bstrncpy(curline, getprev(), sizeof(curline));
            prtcur(curline);
            break;
@@ -737,39 +771,45 @@ 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(void)
+/*FCN*/static void rawmode(FILE *input)
 {
    struct termios t;
    static char term_buf[2048];
    static char *term_buffer = term_buf;
    char *termtype = (char *)getenv("TERM");
 
+   /* Make sure we are dealing with a terminal */
+   if (!isatty(fileno(input))) {
+      return;
+   }
    if (tcgetattr(0, &old_term_params) != 0) {
-      printf("Cannot tcgetattr()\n");
+      printf(_("conio: Cannot tcgetattr()\n"));
       exit(1);
    }
+   old_term_params_set = true;
    t = old_term_params;                        
    t.c_cc[VMIN] = 1; /* satisfy read after 1 char */
    t.c_cc[VTIME] = 0;
    t.c_iflag &= ~(BRKINT | IGNPAR | PARMRK | INPCK | 
                  ISTRIP | ICRNL | IXON | IXOFF | INLCR | IGNCR);     
-   t.c_iflag |= IGNBRK;
-   t.c_oflag &= ~(OPOST);    /* no output processing */       
+   t.c_iflag |= IGNBRK | ISIG;
+// t.c_oflag &= ~(OPOST);    /* no output processing */       
+   t.c_oflag |= ONLCR;
    t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON |
-                 ISIG | NOFLSH | TOSTOP);
+                 NOFLSH | TOSTOP);
    tcflush(0, TCIFLUSH);
    if (tcsetattr(0, TCSANOW, &t) == -1) {
       printf("Cannot tcsetattr()\n");
    }
 
-   signal(SIGQUIT, SIG_IGN);
-   signal(SIGHUP, SIG_IGN);
-   signal(SIGSTOP, SIG_IGN);
+// signal(SIGQUIT, SIG_IGN);
+// signal(SIGHUP, SIG_IGN);
+// signal(SIGSTOP, SIG_IGN);
    signal(SIGINT, sigintcatcher);
-   signal(SIGWINCH, SIG_IGN);  
-   signal(SIGQUIT, SIG_IGN);
-   signal(SIGCHLD, SIG_IGN);
-   signal(SIGTSTP, SIG_IGN);
+// signal(SIGWINCH, SIG_IGN);  
+// signal(SIGQUIT, SIG_IGN);
+// signal(SIGCHLD, SIG_IGN);
+// signal(SIGTSTP, SIG_IGN);
 
    if (!termtype) {
       printf("Cannot get terminal type.\n");
@@ -795,17 +835,6 @@ static void add_esc_smap(char *str, int func)
    t_up = (char *)tgetstr("up", &term_buffer);
    t_do = (char *)tgetstr("do", &term_buffer);
    t_sf = (char *)tgetstr("sf", &term_buffer);
-   t_flag = (char *)tgetstr("so", &term_buffer);
-   t_norm = (char *)tgetstr("se", &term_buffer);
-
-   
-
-   dioflag = 1;
-   use_termcap = 1;
-   t_flagl = tgetnum("sg");
-   if (t_flagl < 0) {
-      t_flagl = 0;
-   }
 
    num_stab = MAX_STAB;                 /* get default stab size */
    stab = (stab_t **)malloc(sizeof(stab_t *) * num_stab);
@@ -818,16 +847,6 @@ static void add_esc_smap(char *str, int func)
    kd = (char *)tgetstr("kd", &term_buffer);
    kh = (char *)tgetstr("kh", &term_buffer);
    kb = (char *)tgetstr("kb", &term_buffer);
-   k0 = (char *)tgetstr("k0", &term_buffer);
-   k1 = (char *)tgetstr("k1", &term_buffer);
-   k2 = (char *)tgetstr("k2", &term_buffer);
-   k3 = (char *)tgetstr("k3", &term_buffer);
-   k4 = (char *)tgetstr("k4", &term_buffer);
-   k5 = (char *)tgetstr("k5", &term_buffer);
-   k6 = (char *)tgetstr("k6", &term_buffer);
-   k7 = (char *)tgetstr("k7", &term_buffer);
-   k8 = (char *)tgetstr("k8", &term_buffer);
-   k9 = (char *)tgetstr("k9", &term_buffer);
    kD = (char *)tgetstr("kD", &term_buffer);
    kI = (char *)tgetstr("kI", &term_buffer);
    kN = (char *)tgetstr("kN", &term_buffer);
@@ -854,6 +873,9 @@ static void add_esc_smap(char *str, int func)
    add_esc_smap("[2~",  F_TINS);
    add_esc_smap("[3~",  F_DELCHR);
    add_esc_smap("[4~",  F_EOF);
+   add_esc_smap("f",    F_NXTWRD);
+   add_esc_smap("b",    F_PRVWRD);
+
 
 #ifdef needed
    for (i=301; i<600; i++) {
@@ -866,7 +888,9 @@ static void add_esc_smap(char *str, int func)
 /* Restore tty mode */
 /*FCN*/static void normode()
 {
-   tcsetattr(0, TCSANOW, &old_term_params);
+   if (old_term_params_set) {
+      tcsetattr(0, TCSANOW, &old_term_params);
+   }
 }
 
 /* Get next character from terminal/script file/unget buffer */
@@ -903,13 +927,13 @@ static int window_size(int *height, int *width)   /* /window_size/ */
 #endif
 
 /* Send message to terminal - primitive routine */
-static void
+void
 /*FCN*/t_sendl(char *msg,int len)
 {
     write(1, msg, len);
 }
 
-static void
+void
 /*FCN*/t_send(char *msg)
 {
     if (msg == NULL) {
@@ -918,10 +942,8 @@ static void
     t_sendl(msg, strlen(msg));   /* faster than one char at time */
 }
 
-/* Send single character to terminal - primitive routine -
-   NOTE! don't convert this routine to use the dioflag routines unless
-   those routines are made to simulate a backspace. */
-static void
+/* Send single character to terminal - primitive routine - */
+void
 /*FCN*/t_char(char c)
 {
    write(1, &c, 1);
@@ -980,7 +1002,6 @@ static void asclrl(int pos, int width)
   
 }
 
-#ifdef xxx
 
 /* ASCURS -- Set cursor position */
 static void ascurs(int y, int x)
@@ -996,7 +1017,6 @@ static void asclrs()
    t_send(t_cs);
 }
 
-#endif
 
 
 /* ASINSL -- insert new line after cursor */
index 686ce2e2a05afc1fc1b03604024c55457013a643..586594b4b29e5bd7047c7bcc49594de0d136b687 100644 (file)
@@ -37,18 +37,32 @@ int authenticate_director(JCR *jcr, DIRRES *director);
        
 /* Exported variables */
 
-
 #ifdef HAVE_CYGWIN
 int rl_catch_signals;
 #else
 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
+
 /* Forward referenced functions */
 static void terminate_console(int sig);
 int get_cmd(FILE *input, char *prompt, BSOCK *sock, int sec);
 static int do_outputcmd(FILE *input, BSOCK *UA_sock);
-static void sendit(char *fmt, ...);
+void senditf(char *fmt, ...);
+void sendit(char *buf);
 
 /* Static variables */
 static char *configfile = NULL;
@@ -110,6 +124,15 @@ void got_tin(int sig)
 // printf("Got tin\n");
 }
 
+static int zed_keyscmd(FILE *input, BSOCK *UA_sock)
+{
+   con_set_zed_keys();
+   return 1;
+}
+
+/*
+ * These are the @command
+ */
 struct cmdstruct { char *key; int (*func)(FILE *input, BSOCK *UA_sock); char *help; }; 
 static struct cmdstruct commands[] = {
  { N_("input"),      inputcmd,     _("input from file")},
@@ -120,6 +143,7 @@ static struct cmdstruct commands[] = {
  { N_("time"),       timecmd,      _("print current time")},
  { N_("version"),    versioncmd,   _("print Console's version")},
  { N_("exit"),       quitcmd,      _("exit = quit")},
+ { N_("zed_keyst"),  zed_keyscmd,  _("zed_keys = use zed keys instead of bash keys")},
             };
 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
 
@@ -154,8 +178,7 @@ static int do_a_command(FILE *input, BSOCK *UA_sock)
    if (!found) {
       pm_strcat(&UA_sock->msg, _(": is an illegal command\n"));
       UA_sock->msglen = strlen(UA_sock->msg);
-      fputs(UA_sock->msg, output);
-      fflush(output);
+      sendit(UA_sock->msg);
    }
    return stat;
 }
@@ -182,7 +205,7 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock)
         if (fgets(UA_sock->msg, len, input) == NULL) {
            stat = -1;
         } else {
-            sendit("%s", UA_sock->msg);  /* echo to terminal */
+           sendit(UA_sock->msg);  /* echo to terminal */
            strip_trailing_junk(UA_sock->msg);
            UA_sock->msglen = strlen(UA_sock->msg);
            stat = 1;
@@ -221,7 +244,7 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock)
            at_prompt = FALSE;
         }
         if (!stop) {
-            sendit("%s", UA_sock->msg);
+           sendit(UA_sock->msg);
         }
       }
       if (!stop) {
@@ -328,6 +351,8 @@ 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);
 try_again:
@@ -335,7 +360,7 @@ try_again:
       LockRes();
       ndir = 0;
       for (dir = NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) {
-         fprintf(output, _("%d  %s at %s:%d\n"), 1+ndir++, dir->hdr.name, dir->address,
+         senditf( _("%d  %s at %s:%d\n"), 1+ndir++, dir->hdr.name, dir->address,
            dir->DIRport);
       }
       UnlockRes();
@@ -344,7 +369,7 @@ try_again:
       }
       item = atoi(UA_sock->msg);
       if (item < 0 || item > ndir) {
-         sendit(_("You must enter a number between 1 and %d\n"), ndir);
+         senditf(_("You must enter a number between 1 and %d\n"), ndir);
         goto try_again;
       }
       LockRes();
@@ -361,7 +386,7 @@ try_again:
    }
       
 
-   sendit(_("Connecting to Director %s:%d\n"), dir->address,dir->DIRport);
+   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);
    if (UA_sock == NULL) {
@@ -391,6 +416,7 @@ try_again:
       }
    }
 
+
    read_and_process_input(stdin, UA_sock);
 
    if (UA_sock) {
@@ -413,6 +439,7 @@ static void terminate_console(int sig)
    }
    already_here = TRUE;
    free_pool_memory(args);
+   con_term();
    if (sig != 0) {
       exit(1);
    }
@@ -491,8 +518,7 @@ get_cmd(FILE *input, char *prompt, BSOCK *sock, int sec)
    int len;  
    if (!stop) {
       if (output == stdout || tee) {
-        fputs(prompt, stdout);
-        fflush(stdout);
+        sendit(prompt);
       }
    }
 again:
@@ -507,6 +533,12 @@ again:
         sleep(1);
         goto again;
       }
+#ifdef HAVE_CONIO
+      if (isatty(fileno(input))) {
+        input_line(sock->msg, len);
+        break;
+      }
+#endif
       if (fgets(sock->msg, len, input) == NULL) {
         return -1;
       }
@@ -521,7 +553,7 @@ again:
 
 static int versioncmd(FILE *input, BSOCK *UA_sock)
 {
-   sendit("Version: " VERSION " (" BDATE ") %s %s %s\n",
+   senditf("Version: " VERSION " (" BDATE ") %s %s %s\n",
       HOST_OS, DISTNAME, DISTVER);
    return 1;
 }
@@ -540,7 +572,7 @@ static int inputcmd(FILE *input, BSOCK *UA_sock)
    }
    fd = fopen(argk[1], "r");
    if (!fd) {
-      sendit(_("Cannot open file %s for input. ERR=%s\n"), 
+      senditf(_("Cannot open file %s for input. ERR=%s\n"), 
         argk[1], strerror(errno));
       return 1; 
    }
@@ -584,7 +616,7 @@ static int do_outputcmd(FILE *input, BSOCK *UA_sock)
    }
    fd = fopen(argk[1], mode);
    if (!fd) {
-      sendit(_("Cannot open file %s for output. ERR=%s\n"), 
+      senditf(_("Cannot open file %s for output. ERR=%s\n"), 
         argk[1], strerror(errno));
       return 1; 
    }
@@ -613,12 +645,14 @@ static int timecmd(FILE *input, BSOCK *UA_sock)
    struct tm tm;
    localtime_r(&ttime, &tm);
    strftime(sdt, sizeof(sdt), "%d-%b-%Y %H:%M:%S", &tm);
-   sendit(sdt);
    sendit("\n");
    return 1;
 }
 
-static void sendit(char *fmt,...)
+/*
+ * Send a line to the output file and or the terminal
+ */
+void senditf(char *fmt,...)
 {
     char buf[3000];
     va_list arg_ptr;
@@ -626,9 +660,38 @@ static void sendit(char *fmt,...)
     va_start(arg_ptr, fmt);
     bvsnprintf(buf, sizeof(buf), (char *)fmt, arg_ptr);
     va_end(arg_ptr);
+    sendit(buf);
+}
+
+void sendit(char *buf)
+{
+#ifdef HAVE_CONIO
+    if (output == stdout || tee) {
+       char *p, *q;    
+       /*
+        * Here, we convert every \n into \r\n because the
+       *  terminal is in raw mode when we are using 
+       *  conio.
+       */
+       for (p=q=buf; (p=strchr(q, '\n')); ) {
+         if (p-q > 0) {
+            t_sendl(q, p-q);
+         }
+          t_sendl("\r\n", 2);
+          q = ++p;                    /* point after \n */
+       }
+       if (*q) {
+         t_send(q);
+       }
+    }
+    if (output != stdout) {
+       fputs(buf, output);
+    }
+#else
     fputs(buf, output);
     if (tee) {
        fputs(buf, stdout);
     }
     fflush(stdout);
+#endif
 }
index 6de50c0ce15b997314c0700d3d94b76371339379..e096c9cb19294c88571e07214f766429a81ef712 100755 (executable)
@@ -1,81 +1,85 @@
 /* Definitions of internal function codes */
 
 /* Functions that work on current line */
-#define F_CSRRGT   301               /* cursor right */
-#define F_CSRLFT   302               /* cursor left */
-#define F_ERSCHR   303               /* erase character */
-#define F_INSCHR   304               /* insert character */
-#define F_DELCHR   305               /* delete next character character */
-#define F_SOL     306                /* go to start of line */
-#define F_EOL     307                /* go to end of line */
-#define F_DELEOL   308               /* delete to end of line */
-#define F_NXTWRD   309               /* go to next word */
-#define F_PRVWRD   310               /* go to previous word */
-#define F_DELWRD   311               /* delete word */
-#define F_ERSLIN   312               /* erase line */
-#define F_TAB     313                /* tab */
-#define F_TABBAK   314               /* tab backwards */
-#define F_DELSOL   315               /* delete from start of line to cursor */
-#define F_LEFT40   316               /* move cursor left 40 cols */
-#define F_RIGHT40  317               /* move cursor right 40 cols */
-#define F_CASE    318                /* change case of next char advance csr */
-#define F_CENTERL  319               /* center line */
+#define F_CSRRGT   301                /* cursor right */
+#define F_CSRLFT   302                /* cursor left */
+#define F_ERSCHR   303                /* erase character */
+#define F_INSCHR   304                /* insert character */
+#define F_DELCHR   305                /* delete next character character */
+#define F_SOL      306                /* go to start of line */
+#define F_EOL      307                /* go to end of line */
+#define F_DELEOL   308                /* delete to end of line */
+#define F_NXTWRD   309                /* go to next word */
+#define F_PRVWRD   310                /* go to previous word */
+#define F_DELWRD   311                /* delete word */
+#define F_ERSLIN   312                /* erase line */
+#define F_TAB      313                /* tab */
+#define F_TABBAK   314                /* tab backwards */
+#define F_DELSOL   315                /* delete from start of line to cursor */
+#define F_LEFT40   316                /* move cursor left 40 cols */
+#define F_RIGHT40  317                /* move cursor right 40 cols */
+#define F_CASE     318                /* change case of next char advance csr */
+#define F_CENTERL  319                /* center line */
 
 /* Functions that move the cursor line or work on groups of lines */
-#define F_CSRDWN   401               /* cursor down */
-#define F_CSRUP    402               /* cursor up */
-#define F_HOME    403                /* home cursor */
-#define F_EOF     404                /* go to end of file */
-#define F_PAGDWN   405               /* page down */
-#define F_PAGUP    406               /* page up */
-#define F_CENTER   407               /* center cursor on screen */
-#define F_SPLIT    408               /* split line at cursor */
-#define F_DELLIN   409               /* delete line */
-#define F_CONCAT   410               /* concatenate next line to current */
-#define F_RETURN   411               /* carriage return */
-#define F_NXTMCH   412               /* next match */
-#define F_DWN5    413                /* cursor down 5 lines */
-#define F_UP5     414                /* cursor up 5 lines */
-#define F_PUSH    415                /* push current location */
-#define F_POP     416                /* pop previous location */
-#define F_PAREN    417               /* find matching paren */
-#define F_POPVIEW  418               /* pop to saved view */
-#define F_OOPS    419                /* restore last oops buffer */
-#define F_PARENB   420               /* find matching paren backwards */
-#define F_BOTSCR   421               /* cursor to bottom of screen */
-#define F_TOPSCR   422               /* cursor to top of screen */
-#define F_TOPMARK  423               /* cursor to top marker line */
-#define F_BOTMARK  424               /* cursor to bottom marker line */
-#define F_CPYMARK  425               /* copy marked lines */
-#define F_MOVMARK  426               /* move marked lines */
-#define F_DELMARK  427               /* delete marked lines */
-#define F_SHFTLEFT 428               /* shift marked text left one char */
-#define F_SHFTRIGHT 429              /* shift marked text right one char */
+#define F_CSRDWN   401                /* cursor down */
+#define F_CSRUP    402                /* cursor up */
+#define F_HOME     403                /* home cursor */
+#define F_EOF      404                /* go to end of file */
+#define F_PAGDWN   405                /* page down */
+#define F_PAGUP    406                /* page up */
+#define F_CENTER   407                /* center cursor on screen */
+#define F_SPLIT    408                /* split line at cursor */
+#define F_DELLIN   409                /* delete line */
+#define F_CONCAT   410                /* concatenate next line to current */
+#define F_RETURN   411                /* carriage return */
+#define F_NXTMCH   412                /* next match */
+#define F_DWN5     413                /* cursor down 5 lines */
+#define F_UP5      414                /* cursor up 5 lines */
+#define F_PUSH     415                /* push current location */
+#define F_POP      416                /* pop previous location */
+#define F_PAREN    417                /* find matching paren */
+#define F_POPVIEW  418                /* pop to saved view */
+#define F_OOPS     419                /* restore last oops buffer */
+#define F_PARENB   420                /* find matching paren backwards */
+#define F_BOTSCR   421                /* cursor to bottom of screen */
+#define F_TOPSCR   422                /* cursor to top of screen */
+#define F_TOPMARK  423                /* cursor to top marker line */
+#define F_BOTMARK  424                /* cursor to bottom marker line */
+#define F_CPYMARK  425                /* copy marked lines */
+#define F_MOVMARK  426                /* move marked lines */
+#define F_DELMARK  427                /* delete marked lines */
+#define F_SHFTLEFT 428                /* shift marked text left one char */
+#define F_SHFTRIGHT 429               /* shift marked text right one char */
 
 /* Miscellaneous */
-#define F_ESCAPE   501               /* escape character */
-#define F_ESC     501                /* escape character */
-#define F_EOI     502                /* end of input */
-#define F_TENTRY   503               /* toggle entry mode */
-#define F_TINS    504                /* toggle insert mode */
-#define F_MARK    505                /* set marker on lines */
-#define F_CRESC    506               /* carriage return, escape */
+#define F_ESCAPE   501                /* escape character */
+#define F_ESC      501                /* escape character */
+#define F_EOI      502                /* end of input */
+#define F_TENTRY   503                /* toggle entry mode */
+#define F_TINS     504                /* toggle insert mode */
+#define F_MARK     505                /* set marker on lines */
+#define F_CRESC    506                /* carriage return, escape */
 #define F_MACDEF   507                /* begin "macro" definition */
 #define F_MACEND   508                /* end "macro" definition */
-#define F_ZAPESC   509               /* clear screen, escape */
-#define F_CLRMARK  510               /* clear marked text */
-#define F_MARKBLK  511               /* mark blocks */
-#define F_MARKCHR  512               /* mark characters */
-#define F_HOLD    513                /* hold line */
-#define F_DUP     514                /* duplicate line */
-#define F_CHANGE   515               /* apply last change command */
-#define F_RCHANGE  516               /* reverse last change command */
-#define F_NXTFILE  517               /* next file */
-#define F_INCLUDE  518               /* include */
-#define F_FORMAT   519               /* format paragraph */
-#define F_HELP    520                /* help */
-#define F_JUSTIFY  521               /* justify paragraph */
-#define F_SAVE    522                /* save file -- not implemented */
-#define F_MOUSEI   523               /* mouse input coming -- not completed */
-#define F_SCRSIZ   524               /* Screen size coming */
-#define F_PASTECB  525               /* Paste clipboard */
+#define F_ZAPESC   509                /* clear screen, escape */
+#define F_CLRMARK  510                /* clear marked text */
+#define F_MARKBLK  511                /* mark blocks */
+#define F_MARKCHR  512                /* mark characters */
+#define F_HOLD     513                /* hold line */
+#define F_DUP      514                /* duplicate line */
+#define F_CHANGE   515                /* apply last change command */
+#define F_RCHANGE  516                /* reverse last change command */
+#define F_NXTFILE  517                /* next file */
+#define F_INCLUDE  518                /* include */
+#define F_FORMAT   519                /* format paragraph */
+#define F_HELP     520                /* help */
+#define F_JUSTIFY  521                /* justify paragraph */
+#define F_SAVE     522                /* save file -- not implemented */
+#define F_MOUSEI   523                /* mouse input coming -- not completed */
+#define F_SCRSIZ   524                /* Screen size coming */
+#define F_PASTECB  525                /* Paste clipboard */
+#define F_CLRSCRN  526                /* Clear the screen */
+#define F_CRNEXT   527                /* Send line, get next line */
+#define F_BREAK    528                /* Break */
+#define F_BACKGND  529                /* go into background */
index 76bebefc411fa0e29794a73dc4901e4d61885b08..2b4bc137867bfc1037fa3c2cf4115ffc5bc1ade7 100644 (file)
@@ -8,14 +8,14 @@
  *   1. The generic lexical scanner in lib/lex.c and lib/lex.h
  *
  *   2. The generic config  scanner in lib/parse_config.c and 
- *      lib/parse_config.h.
- *      These files contain the parser code, some utility
- *      routines, and the common store routines (name, int,
- *      string).
+ *     lib/parse_config.h.
+ *     These files contain the parser code, some utility
+ *     routines, and the common store routines (name, int,
+ *     string).
  *
  *   3. The daemon specific file, which contains the Resource
- *      definitions as well as any specific store routines
- *      for the resource records.
+ *     definitions as well as any specific store routines
+ *     for the resource records.
  *
  *     Kern Sibbald, January MM
  *
@@ -84,7 +84,7 @@ int  res_all_size = sizeof(res_all);
 /* 
  *    Director Resource
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items dir_items[] = {
    {"name",        store_name,     ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0},
@@ -108,7 +108,7 @@ static struct res_items dir_items[] = {
 /* 
  *    Console Resource
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items con_items[] = {
    {"name",        store_name,     ITEM(res_con.hdr.name), 0, ITEM_REQUIRED, 0},
@@ -122,7 +122,7 @@ static struct res_items con_items[] = {
 /* 
  *    Client or File daemon resource
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 
 static struct res_items cli_items[] = {
@@ -144,7 +144,7 @@ static struct res_items cli_items[] = {
 
 /* Storage daemon resource
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items store_items[] = {
    {"name",        store_name,     ITEM(res_store.hdr.name),   0, ITEM_REQUIRED, 0},
@@ -167,7 +167,7 @@ static struct res_items store_items[] = {
 /* 
  *    Catalog Resource Directives
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items cat_items[] = {
    {"name",     store_name,     ITEM(res_cat.hdr.name),    0, ITEM_REQUIRED, 0},
@@ -187,7 +187,7 @@ static struct res_items cat_items[] = {
 /* 
  *    Job Resource Directives
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items job_items[] = {
    {"name",     store_name,    ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0},
@@ -203,6 +203,7 @@ static struct res_items job_items[] = {
    {"pool",     store_res,     ITEM(res_job.pool),     R_POOL, 0, 0},
    {"client",   store_res,     ITEM(res_job.client),   R_CLIENT, 0, 0},
    {"fileset",  store_res,     ITEM(res_job.fileset),  R_FILESET, 0, 0},
+   {"jobdefs",  store_defs,    ITEM(res_job),          R_JOB, 0, 0},
    {"verifyjob",  store_res,   ITEM(res_job.verify_job), R_JOB, 0, 0},
    {"where",    store_dir,     ITEM(res_job.RestoreWhere), 0, 0, 0},
    {"replace",  store_replace, ITEM(res_job.replace), 0, ITEM_DEFAULT, REPLACE_ALWAYS},
@@ -231,20 +232,20 @@ static struct res_items job_items[] = {
 
 /* FileSet resource
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items fs_items[] = {
    {"name",        store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,  ITEM(res_fs.hdr.desc), 0, 0, 0},
    {"include",     store_inc,  NULL,                  0, ITEM_NO_EQUALS, 0},
    {"exclude",     store_inc,  NULL,                  1, ITEM_NO_EQUALS, 0},
-   {NULL,          NULL,       NULL,                  0, 0, 0} 
+   {NULL,         NULL,       NULL,                  0, 0, 0} 
 };
 
 /* Schedule -- see run_conf.c */
 /* Schedule
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items sch_items[] = {
    {"name",     store_name,  ITEM(res_sch.hdr.name), 0, ITEM_REQUIRED, 0},
@@ -255,7 +256,7 @@ static struct res_items sch_items[] = {
 
 /* Group resource -- not implemented
  *
- *   name          handler     value                 code flags    default_value
+ *   name         handler     value                 code flags    default_value
  */
 static struct res_items group_items[] = {
    {"name",        store_name, ITEM(res_group.hdr.name), 0, ITEM_REQUIRED, 0},
@@ -265,7 +266,7 @@ static struct res_items group_items[] = {
 
 /* Pool resource
  *
- *   name             handler     value                        code flags default_value
+ *   name            handler     value                        code flags default_value
  */
 static struct res_items pool_items[] = {
    {"name",            store_name,    ITEM(res_pool.hdr.name),      0, ITEM_REQUIRED, 0},
@@ -293,7 +294,7 @@ static struct res_items pool_items[] = {
 
 /* 
  * Counter Resource
- *   name             handler     value                        code flags default_value
+ *   name            handler     value                        code flags default_value
  */
 static struct res_items counter_items[] = {
    {"name",            store_name,    ITEM(res_counter.hdr.name),        0, ITEM_REQUIRED, 0},
@@ -316,12 +317,13 @@ extern struct res_items msgs_items[];
  *  NOTE!!! keep it in the same order as the R_codes
  *    or eliminate all resources[rindex].name
  *
- *  name             items        rcode        res_head
+ *  name            items        rcode        res_head
  */
 struct s_res resources[] = {
    {"director",      dir_items,   R_DIRECTOR,  NULL},
    {"client",        cli_items,   R_CLIENT,    NULL},
    {"job",           job_items,   R_JOB,       NULL},
+   {"jobdefs",       job_items,   R_JOBDEFS,   NULL},
    {"storage",       store_items, R_STORAGE,   NULL},
    {"catalog",       cat_items,   R_CATALOG,   NULL},
    {"schedule",      sch_items,   R_SCHEDULE,  NULL},
@@ -331,13 +333,13 @@ struct s_res resources[] = {
    {"messages",      msgs_items,  R_MSGS,      NULL},
    {"counter",       counter_items, R_COUNTER, NULL},
    {"console",       con_items,   R_CONSOLE,   NULL},
-   {NULL,            NULL,        0,           NULL}
+   {NULL,           NULL,        0,           NULL}
 };
 
 
 /* Keywords (RHS) permitted in Job Level records   
  *
- *   level_name      level              job_type
+ *   level_name      level             job_type
  */
 struct s_jl joblevels[] = {
    {"Full",          L_FULL,            JT_BACKUP},
@@ -352,19 +354,19 @@ struct s_jl joblevels[] = {
    {"Data",          L_VERIFY_DATA,     JT_VERIFY},
    {" ",             L_NONE,            JT_ADMIN},
    {" ",             L_NONE,            JT_RESTORE},
-   {NULL,            0}
+   {NULL,           0}
 };
 
 /* Keywords (RHS) permitted in Job type records   
  *
- *   type_name       job_type
+ *   type_name      job_type
  */
 struct s_jt jobtypes[] = {
    {"backup",        JT_BACKUP},
    {"admin",         JT_ADMIN},
    {"verify",        JT_VERIFY},
    {"restore",       JT_RESTORE},
-   {NULL,            0}
+   {NULL,           0}
 };
 
 
@@ -373,7 +375,7 @@ static struct s_kw BakVerFields[] = {
    {"client",        'C'},
    {"fileset",       'F'},
    {"level",         'L'}, 
-   {NULL,            0}
+   {NULL,           0}
 };
 
 /* Keywords (RHS) permitted in Restore records */
@@ -384,7 +386,7 @@ static struct s_kw RestoreFields[] = {
    {"where",         'W'},            /* root of restore */
    {"replace",       'R'},            /* replacement options */
    {"bootstrap",     'B'},            /* bootstrap file */
-   {NULL,              0}
+   {NULL,             0}
 };
 
 /* Options permitted in Restore replace= */
@@ -393,7 +395,7 @@ struct s_kw ReplaceOptions[] = {
    {"ifnewer",        REPLACE_IFNEWER},
    {"ifolder",        REPLACE_IFOLDER},
    {"never",          REPLACE_NEVER},
-   {NULL,               0}
+   {NULL,              0}
 };
 
 char *level_to_str(int level)
@@ -405,8 +407,8 @@ char *level_to_str(int level)
    sprintf(level_no, "%d", level);    /* default if not found */
    for (i=0; joblevels[i].level_name; i++) {
       if (level == joblevels[i].level) {
-         str = joblevels[i].level_name;
-         break;
+        str = joblevels[i].level_name;
+        break;
       }
    }
    return str;
@@ -423,90 +425,92 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       sendit(sock, "No %s resource defined\n", res_to_str(type));
       return;
    }
-   if (type < 0) {                    /* no recursion */
+   if (type < 0) {                   /* no recursion */
       type = - type;
       recurse = false;
    }
    switch (type) {
    case R_DIRECTOR:
       sendit(sock, "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n", 
-         reshdr->name, res->res_dir.MaxConcurrentJobs, 
-         edit_uint64(res->res_dir.FDConnectTimeout, ed1),
-         edit_uint64(res->res_dir.SDConnectTimeout, ed2));
+        reshdr->name, res->res_dir.MaxConcurrentJobs, 
+        edit_uint64(res->res_dir.FDConnectTimeout, ed1),
+        edit_uint64(res->res_dir.SDConnectTimeout, ed2));
       if (res->res_dir.query_file) {
          sendit(sock, "   query_file=%s\n", res->res_dir.query_file);
       }
       if (res->res_dir.messages) {
          sendit(sock, "  --> ");
-         dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock);
+        dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock);
       }
       break;
    case R_CONSOLE:
       sendit(sock, "Console: name=%s SSL=%d\n", 
-         res->res_con.hdr.name, res->res_con.enable_ssl);
+        res->res_con.hdr.name, res->res_con.enable_ssl);
       break;
    case R_COUNTER:
       if (res->res_counter.WrapCounter) {
          sendit(sock, "Counter: name=%s min=%d max=%d cur=%d wrapcntr=%s\n",
-            res->res_counter.hdr.name, res->res_counter.MinValue, 
-            res->res_counter.MaxValue, res->res_counter.CurrentValue,
-            res->res_counter.WrapCounter->hdr.name);
+           res->res_counter.hdr.name, res->res_counter.MinValue, 
+           res->res_counter.MaxValue, res->res_counter.CurrentValue,
+           res->res_counter.WrapCounter->hdr.name);
       } else {
          sendit(sock, "Counter: name=%s min=%d max=%d\n",
-            res->res_counter.hdr.name, res->res_counter.MinValue, 
-            res->res_counter.MaxValue);
+           res->res_counter.hdr.name, res->res_counter.MinValue, 
+           res->res_counter.MaxValue);
       }
       if (res->res_counter.Catalog) {
          sendit(sock, "  --> ");
-         dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock);
+        dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock);
       }
       break;
 
    case R_CLIENT:
       sendit(sock, "Client: name=%s address=%s FDport=%d MaxJobs=%u\n",
-         res->res_client.hdr.name, res->res_client.address, res->res_client.FDport,
-         res->res_client.MaxConcurrentJobs);
+        res->res_client.hdr.name, res->res_client.address, res->res_client.FDport,
+        res->res_client.MaxConcurrentJobs);
       sendit(sock, "      JobRetention=%s FileRetention=%s AutoPrune=%d\n",
-         edit_utime(res->res_client.JobRetention, ed1), 
-         edit_utime(res->res_client.FileRetention, ed2),
-         res->res_client.AutoPrune);
+        edit_utime(res->res_client.JobRetention, ed1), 
+        edit_utime(res->res_client.FileRetention, ed2),
+        res->res_client.AutoPrune);
       if (res->res_client.catalog) {
          sendit(sock, "  --> ");
-         dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
+        dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
       }
       break;
    case R_STORAGE:
       sendit(sock, "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n\
       DeviceName=%s MediaType=%s\n",
-         res->res_store.hdr.name, res->res_store.address, res->res_store.SDport,
-         res->res_store.MaxConcurrentJobs,
-         res->res_store.dev_name, res->res_store.media_type);
+        res->res_store.hdr.name, res->res_store.address, res->res_store.SDport,
+        res->res_store.MaxConcurrentJobs,
+        res->res_store.dev_name, res->res_store.media_type);
       break;
    case R_CATALOG:
       sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n\
       db_user=%s\n",
-         res->res_cat.hdr.name, NPRT(res->res_cat.db_address),
-         res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user));
+        res->res_cat.hdr.name, NPRT(res->res_cat.db_address),
+        res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user));
       break;
    case R_JOB:
-      sendit(sock, "Job: name=%s JobType=%d level=%s Priority=%d MaxJobs=%u\n", 
-         res->res_job.hdr.name, res->res_job.JobType, 
-         level_to_str(res->res_job.level), res->res_job.Priority,
-         res->res_job.MaxConcurrentJobs);
+   case R_JOBDEFS:
+      sendit(sock, "%s: name=%s JobType=%d level=%s Priority=%d MaxJobs=%u\n", 
+         type == R_JOB ? "Job" : "JobDefs",
+        res->res_job.hdr.name, res->res_job.JobType, 
+        level_to_str(res->res_job.level), res->res_job.Priority,
+        res->res_job.MaxConcurrentJobs);
       sendit(sock, "     Resched=%d Times=%d Interval=%s\n",
-          res->res_job.RescheduleOnError, res->res_job.RescheduleTimes,
-          edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1));
+         res->res_job.RescheduleOnError, res->res_job.RescheduleTimes,
+         edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1));
       if (res->res_job.client) {
          sendit(sock, "  --> ");
-         dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock);
+        dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock);
       }
       if (res->res_job.fileset) {
          sendit(sock, "  --> ");
-         dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock);
+        dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock);
       }
       if (res->res_job.schedule) {
          sendit(sock, "  --> ");
-         dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock);
+        dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock);
       }
       if (res->res_job.RestoreWhere) {
          sendit(sock, "  --> Where=%s\n", NPRT(res->res_job.RestoreWhere));
@@ -528,113 +532,122 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       }
       if (res->res_job.storage) {
          sendit(sock, "  --> ");
-         dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
+        dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
       }
       if (res->res_job.pool) {
          sendit(sock, "  --> ");
-         dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock);
+        dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock);
       } else {
          sendit(sock, "!!! No Pool resource\n");
       }
       if (res->res_job.verify_job) {
          sendit(sock, "  --> ");
-         dump_resource(-R_JOB, (RES *)res->res_job.verify_job, sendit, sock);
+        dump_resource(-type, (RES *)res->res_job.verify_job, sendit, sock);
       }
       break;
       if (res->res_job.messages) {
          sendit(sock, "  --> ");
-         dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock);
+        dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock);
       }
       break;
    case R_FILESET:
       sendit(sock, "FileSet: name=%s\n", res->res_fs.hdr.name);
       for (int i=0; i<res->res_fs.num_includes; i++) {
-         INCEXE *incexe = res->res_fs.include_items[i];
-         for (int j=0; j<incexe->name_list.size(); j++) {
+        INCEXE *incexe = res->res_fs.include_items[i];
+        for (int j=0; j<incexe->name_list.size(); j++) {
             sendit(sock, "      Inc: %s\n", incexe->name_list.get(j));
-         }
+        }
       }
       for (int i=0; i<res->res_fs.num_excludes; i++) {
-         INCEXE *incexe = res->res_fs.exclude_items[i];
-         for (int j=0; j<incexe->name_list.size(); j++) {
+        INCEXE *incexe = res->res_fs.exclude_items[i];
+        for (int j=0; j<incexe->name_list.size(); j++) {
             sendit(sock, "      Exc: %s\n", incexe->name_list.get(j));
-         }
+        }
       }
       break;
    case R_SCHEDULE:
       if (res->res_sch.run) {
-         int i;
-         RUN *run = res->res_sch.run;
-         char buf[1000], num[10];
+        int i;
+        RUN *run = res->res_sch.run;
+        char buf[1000], num[10];
          sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
-         if (!run) {
-            break;
-         }
+        if (!run) {
+           break;
+        }
 next_run:
          sendit(sock, "  --> Run Level=%s\n", level_to_str(run->level));
          bstrncpy(buf, "      hour=", sizeof(buf));
-         for (i=0; i<24; i++) {
-            if (bit_is_set(i, run->hour)) {
+        for (i=0; i<24; i++) {
+           if (bit_is_set(i, run->hour)) {
                sprintf(num, "%d ", i);
-               bstrncat(buf, num, sizeof(buf));
-            }
-         }
-         strcat(buf, "\n");
-         sendit(sock, buf);
-         strcpy(buf, "      mday=");
-         for (i=0; i<31; i++) {
-            if (bit_is_set(i, run->mday)) {
+              bstrncat(buf, num, sizeof(buf));
+           }
+        }
+         bstrncat(buf, "\n", sizeof(buf));
+        sendit(sock, buf);
+         bstrncpy(buf, "      mday=", sizeof(buf));
+        for (i=0; i<31; i++) {
+           if (bit_is_set(i, run->mday)) {
                sprintf(num, "%d ", i+1);
-               strcat(buf, num);
-            }
-         }
-         strcat(buf, "\n");
-         sendit(sock, buf);
-         strcpy(buf, "      month=");
-         for (i=0; i<12; i++) {
-            if (bit_is_set(i, run->month)) {
+              bstrncat(buf, num, sizeof(buf));
+           }
+        }
+         bstrncat(buf, "\n", sizeof(buf));
+        sendit(sock, buf);
+         bstrncpy(buf, "      month=", sizeof(buf));
+        for (i=0; i<12; i++) {
+           if (bit_is_set(i, run->month)) {
                sprintf(num, "%d ", i+1);
-               strcat(buf, num);
-            }
-         }
-         strcat(buf, "\n");
-         sendit(sock, buf);
-         strcpy(buf, "      wday=");
-         for (i=0; i<7; i++) {
-            if (bit_is_set(i, run->wday)) {
+              bstrncat(buf, num, sizeof(buf));
+           }
+        }
+         bstrncat(buf, "\n", sizeof(buf));
+        sendit(sock, buf);
+         bstrncpy(buf, "      wday=", sizeof(buf));
+        for (i=0; i<7; i++) {
+           if (bit_is_set(i, run->wday)) {
                sprintf(num, "%d ", i+1);
-               strcat(buf, num);
-            }
-         }
-         strcat(buf, "\n");
-         sendit(sock, buf);
-         strcpy(buf, "      wpos=");
-         for (i=0; i<5; i++) {
-            if (bit_is_set(i, run->wpos)) {
+              bstrncat(buf, num, sizeof(buf));
+           }
+        }
+         bstrncat(buf, "\n", sizeof(buf));
+        sendit(sock, buf);
+         bstrncpy(buf, "      wom=", sizeof(buf));
+        for (i=0; i<5; i++) {
+           if (bit_is_set(i, run->wom)) {
                sprintf(num, "%d ", i+1);
-               strcat(buf, num);
-            }
-         }
-         strcat(buf, "\n");
-         sendit(sock, buf);
+              bstrncat(buf, num, sizeof(buf));
+           }
+        }
+         bstrncat(buf, "\n", sizeof(buf));
+        sendit(sock, buf);
+         bstrncpy(buf, "      woy=", sizeof(buf));
+        for (i=0; i<54; i++) {
+           if (bit_is_set(i, run->woy)) {
+               sprintf(num, "%d ", i);
+              bstrncat(buf, num, sizeof(buf));
+           }
+        }
+         bstrncat(buf, "\n", sizeof(buf));
+        sendit(sock, buf);
          sendit(sock, "      mins=%d\n", run->minute);
-         if (run->pool) {
+        if (run->pool) {
             sendit(sock, "     --> ");
-            dump_resource(-R_POOL, (RES *)run->pool, sendit, sock);
-         }
-         if (run->storage) {
+           dump_resource(-R_POOL, (RES *)run->pool, sendit, sock);
+        }
+        if (run->storage) {
             sendit(sock, "     --> ");
-            dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock);
-         }
-         if (run->msgs) {
+           dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock);
+        }
+        if (run->msgs) {
             sendit(sock, "     --> ");
-            dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock);
-         }
-         /* If another Run record is chained in, go print it */
-         if (run->next) {
-            run = run->next;
-            goto next_run;
-         }
+           dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock);
+        }
+        /* If another Run record is chained in, go print it */
+        if (run->next) {
+           run = run->next;
+           goto next_run;
+        }
       } else {
          sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
       }
@@ -644,22 +657,22 @@ next_run:
       break;
    case R_POOL:
       sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name,
-              res->res_pool.pool_type);
+             res->res_pool.pool_type);
       sendit(sock, "      use_cat=%d use_once=%d acpt_any=%d cat_files=%d\n",
-              res->res_pool.use_catalog, res->res_pool.use_volume_once,
-              res->res_pool.accept_any_volume, res->res_pool.catalog_files);
+             res->res_pool.use_catalog, res->res_pool.use_volume_once,
+             res->res_pool.accept_any_volume, res->res_pool.catalog_files);
       sendit(sock, "      max_vols=%d auto_prune=%d VolRetention=%s\n",
-              res->res_pool.max_volumes, res->res_pool.AutoPrune,
-              edit_utime(res->res_pool.VolRetention, ed1));
+             res->res_pool.max_volumes, res->res_pool.AutoPrune,
+             edit_utime(res->res_pool.VolRetention, ed1));
       sendit(sock, "      VolUse=%s recycle=%d LabelFormat=%s\n", 
-              edit_utime(res->res_pool.VolUseDuration, ed1),
-              res->res_pool.Recycle,
-              NPRT(res->res_pool.label_format));
+             edit_utime(res->res_pool.VolUseDuration, ed1),
+             res->res_pool.Recycle,
+             NPRT(res->res_pool.label_format));
       sendit(sock, "      CleaningPrefix=%s\n",
-              NPRT(res->res_pool.cleaning_prefix));
+             NPRT(res->res_pool.cleaning_prefix));
       sendit(sock, "      recyleOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n",
-              res->res_pool.purge_oldest_volume, 
-              res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles);
+             res->res_pool.purge_oldest_volume, 
+             res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles);
       break;
    case R_MSGS:
       sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
@@ -726,140 +739,141 @@ void free_resource(int type)
    switch (type) {
    case R_DIRECTOR:
       if (res->res_dir.working_directory) {
-         free(res->res_dir.working_directory);
+        free(res->res_dir.working_directory);
       }
       if (res->res_dir.pid_directory) {
-         free(res->res_dir.pid_directory);
+        free(res->res_dir.pid_directory);
       }
       if (res->res_dir.subsys_directory) {
-         free(res->res_dir.subsys_directory);
+        free(res->res_dir.subsys_directory);
       }
       if (res->res_dir.password) {
-         free(res->res_dir.password);
+        free(res->res_dir.password);
       }
       if (res->res_dir.query_file) {
-         free(res->res_dir.query_file);
+        free(res->res_dir.query_file);
       }
       if (res->res_dir.DIRaddr) {
-         free(res->res_dir.DIRaddr);
+        free(res->res_dir.DIRaddr);
       }
       break;
    case R_COUNTER:
        break;
    case R_CONSOLE:
       if (res->res_con.password) {
-         free(res->res_con.password);
+        free(res->res_con.password);
       }
       break;
    case R_CLIENT:
       if (res->res_client.address) {
-         free(res->res_client.address);
+        free(res->res_client.address);
       }
       if (res->res_client.password) {
-         free(res->res_client.password);
+        free(res->res_client.password);
       }
       break;
    case R_STORAGE:
       if (res->res_store.address) {
-         free(res->res_store.address);
+        free(res->res_store.address);
       }
       if (res->res_store.password) {
-         free(res->res_store.password);
+        free(res->res_store.password);
       }
       if (res->res_store.media_type) {
-         free(res->res_store.media_type);
+        free(res->res_store.media_type);
       }
       if (res->res_store.dev_name) {
-         free(res->res_store.dev_name);
+        free(res->res_store.dev_name);
       }
       break;
    case R_CATALOG:
       if (res->res_cat.db_address) {
-         free(res->res_cat.db_address);
+        free(res->res_cat.db_address);
       }
       if (res->res_cat.db_socket) {
-         free(res->res_cat.db_socket);
+        free(res->res_cat.db_socket);
       }
       if (res->res_cat.db_user) {
-         free(res->res_cat.db_user);
+        free(res->res_cat.db_user);
       }
       if (res->res_cat.db_name) {
-         free(res->res_cat.db_name);
+        free(res->res_cat.db_name);
       }
       if (res->res_cat.db_password) {
-         free(res->res_cat.db_password);
+        free(res->res_cat.db_password);
       }
       break;
    case R_FILESET:
       if ((num=res->res_fs.num_includes)) {
-         while (--num >= 0) {   
-            free_incexe(res->res_fs.include_items[num]);
-         }
-         free(res->res_fs.include_items);
+        while (--num >= 0) {   
+           free_incexe(res->res_fs.include_items[num]);
+        }
+        free(res->res_fs.include_items);
       }
       res->res_fs.num_includes = 0;
       if ((num=res->res_fs.num_excludes)) {
-         while (--num >= 0) {   
-            free_incexe(res->res_fs.exclude_items[num]);
-         }
-         free(res->res_fs.exclude_items);
+        while (--num >= 0) {   
+           free_incexe(res->res_fs.exclude_items[num]);
+        }
+        free(res->res_fs.exclude_items);
       }
       res->res_fs.num_excludes = 0;
       break;
    case R_POOL:
       if (res->res_pool.pool_type) {
-         free(res->res_pool.pool_type);
+        free(res->res_pool.pool_type);
       }
       if (res->res_pool.label_format) {
-         free(res->res_pool.label_format);
+        free(res->res_pool.label_format);
       }
       if (res->res_pool.cleaning_prefix) {
-         free(res->res_pool.cleaning_prefix);
+        free(res->res_pool.cleaning_prefix);
       }
       break;
    case R_SCHEDULE:
       if (res->res_sch.run) {
-         RUN *nrun, *next;
-         nrun = res->res_sch.run;
-         while (nrun) {
-            next = nrun->next;
-            free(nrun);
-            nrun = next;
-         }
+        RUN *nrun, *next;
+        nrun = res->res_sch.run;
+        while (nrun) {
+           next = nrun->next;
+           free(nrun);
+           nrun = next;
+        }
       }
       break;
    case R_JOB:
+   case R_JOBDEFS:
       if (res->res_job.RestoreWhere) {
-         free(res->res_job.RestoreWhere);
+        free(res->res_job.RestoreWhere);
       }
       if (res->res_job.RestoreBootstrap) {
-         free(res->res_job.RestoreBootstrap);
+        free(res->res_job.RestoreBootstrap);
       }
       if (res->res_job.WriteBootstrap) {
-         free(res->res_job.WriteBootstrap);
+        free(res->res_job.WriteBootstrap);
       }
       if (res->res_job.RunBeforeJob) {
-         free(res->res_job.RunBeforeJob);
+        free(res->res_job.RunBeforeJob);
       }
       if (res->res_job.RunAfterJob) {
-         free(res->res_job.RunAfterJob);
+        free(res->res_job.RunAfterJob);
       }
       if (res->res_job.RunAfterFailedJob) {
-         free(res->res_job.RunAfterFailedJob);
+        free(res->res_job.RunAfterFailedJob);
       }
       if (res->res_job.ClientRunBeforeJob) {
-         free(res->res_job.ClientRunBeforeJob);
+        free(res->res_job.ClientRunBeforeJob);
       }
       if (res->res_job.ClientRunAfterJob) {
-         free(res->res_job.ClientRunAfterJob);
+        free(res->res_job.ClientRunAfterJob);
       }
       break;
    case R_MSGS:
       if (res->res_msgs.mail_cmd) {
-         free(res->res_msgs.mail_cmd);
+        free(res->res_msgs.mail_cmd);
       }
       if (res->res_msgs.operator_cmd) {
-         free(res->res_msgs.operator_cmd);
+        free(res->res_msgs.operator_cmd);
       }
       free_msgs_res((MSGS *)res);  /* free message resource */
       res = NULL;
@@ -897,10 +911,10 @@ void save_resource(int type, struct res_items *items, int pass)
     */
    for (i=0; items[i].name; i++) {
       if (items[i].flags & ITEM_REQUIRED) {
-            if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
+           if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
                Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n",
-                 items[i].name, resources[rindex]);
-             }
+                items[i].name, resources[rindex]);
+            }
       }
       /* If this triggers, take a look at lib/parse_conf.h */
       if (i >= MAX_RES_ITEMS) {
@@ -923,84 +937,85 @@ void save_resource(int type, struct res_items *items, int pass)
       case R_POOL:
       case R_MSGS:
       case R_FILESET:
-         break;
+        break;
 
       /* Resources containing another resource */
       case R_DIRECTOR:
-         if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) {
+        if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name);
-         }
-         res->res_dir.messages = res_all.res_dir.messages;
-         break;
+        }
+        res->res_dir.messages = res_all.res_dir.messages;
+        break;
       case R_JOB:
-         if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) {
-            Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", res_all.res_dir.hdr.name);
-         }
-         res->res_job.messages   = res_all.res_job.messages;
-         res->res_job.schedule   = res_all.res_job.schedule;
-         res->res_job.client     = res_all.res_job.client;
-         res->res_job.fileset    = res_all.res_job.fileset;
-         res->res_job.storage    = res_all.res_job.storage;
-         res->res_job.pool       = res_all.res_job.pool;
-         res->res_job.verify_job = res_all.res_job.verify_job;
-         if (res->res_job.JobType == 0) {
+        if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) {
+            Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", 
+                 res_all.res_dir.hdr.name);
+        }
+        res->res_job.messages   = res_all.res_job.messages;
+        res->res_job.schedule   = res_all.res_job.schedule;
+        res->res_job.client     = res_all.res_job.client;
+        res->res_job.fileset    = res_all.res_job.fileset;
+        res->res_job.storage    = res_all.res_job.storage;
+        res->res_job.pool       = res_all.res_job.pool;
+        res->res_job.verify_job = res_all.res_job.verify_job;
+        if (res->res_job.JobType == 0) {
             Emsg1(M_ERROR_TERM, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name);
-         }
-         if (res->res_job.level != 0) {
-            int i;
-            for (i=0; joblevels[i].level_name; i++) {
-               if (joblevels[i].level == res->res_job.level &&
-                   joblevels[i].job_type == res->res_job.JobType) {
-                  i = 0;
-                  break;
-               }
-            }
-            if (i != 0) {
+        }
+        if (res->res_job.level != 0) {
+           int i;
+           for (i=0; joblevels[i].level_name; i++) {
+              if (joblevels[i].level == res->res_job.level &&
+                  joblevels[i].job_type == res->res_job.JobType) {
+                 i = 0;
+                 break;
+              }
+           }
+           if (i != 0) {
                Emsg1(M_ERROR_TERM, 0, "Inappropriate level specified in Job resource %s\n", 
-                  res_all.res_dir.hdr.name);
-            }
-         }
-         break;
+                 res_all.res_dir.hdr.name);
+           }
+        }
+        break;
       case R_COUNTER:
-         if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
+        if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Counter resource %s\n", res_all.res_counter.hdr.name);
-         }
-         res->res_counter.Catalog = res_all.res_counter.Catalog;
-         res->res_counter.WrapCounter = res_all.res_counter.WrapCounter;
-         break;
+        }
+        res->res_counter.Catalog = res_all.res_counter.Catalog;
+        res->res_counter.WrapCounter = res_all.res_counter.WrapCounter;
+        break;
 
       case R_CLIENT:
-         if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) {
+        if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Client resource %s\n", res_all.res_client.hdr.name);
-         }
-         res->res_client.catalog = res_all.res_client.catalog;
-         break;
+        }
+        res->res_client.catalog = res_all.res_client.catalog;
+        break;
       case R_SCHEDULE:
-         /* Schedule is a bit different in that it contains a RUN record
+        /* Schedule is a bit different in that it contains a RUN record
           * chain which isn't a "named" resource. This chain was linked
-          * in by run_conf.c during pass 2, so here we jam the pointer 
-          * into the Schedule resource.                         
-          */
-         if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) {
+         * in by run_conf.c during pass 2, so here we jam the pointer 
+         * into the Schedule resource.                         
+         */
+        if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Schedule resource %s\n", res_all.res_client.hdr.name);
-         }
-         res->res_sch.run = res_all.res_sch.run;
-         break;
+        }
+        res->res_sch.run = res_all.res_sch.run;
+        break;
       default:
          Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type);
-         error = 1;
-         break;
+        error = 1;
+        break;
       }
       /* Note, the resource name was already saved during pass 1,
        * so here, we can just release it.
        */
       if (res_all.res_dir.hdr.name) {
-         free(res_all.res_dir.hdr.name);
-         res_all.res_dir.hdr.name = NULL;
+        free(res_all.res_dir.hdr.name);
+        res_all.res_dir.hdr.name = NULL;
       }
       if (res_all.res_dir.hdr.desc) {
-         free(res_all.res_dir.hdr.desc);
-         res_all.res_dir.hdr.desc = NULL;
+        free(res_all.res_dir.hdr.desc);
+        res_all.res_dir.hdr.desc = NULL;
       }
       return;
    }
@@ -1025,6 +1040,7 @@ void save_resource(int type, struct res_items *items, int pass)
       size = sizeof(CAT);
       break;
    case R_JOB:
+   case R_JOBDEFS:
       size = sizeof(JOB);
       break;
    case R_FILESET:
@@ -1056,22 +1072,22 @@ void save_resource(int type, struct res_items *items, int pass)
       res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       if (!resources[rindex].res_head) {
-         resources[rindex].res_head = (RES *)res; /* store first entry */
+        resources[rindex].res_head = (RES *)res; /* store first entry */
          Dmsg3(200, "Inserting first %s res: %s index=%d\n", res_to_str(type),
-               res->res_dir.hdr.name, rindex);
+              res->res_dir.hdr.name, rindex);
       } else {
-         RES *next;
-         /* Add new res to end of chain */
-         for (next=resources[rindex].res_head; next->next; next=next->next) {
-            if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
-               Emsg2(M_ERROR_TERM, 0,
+        RES *next;
+        /* Add new res to end of chain */
+        for (next=resources[rindex].res_head; next->next; next=next->next) {
+           if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+              Emsg2(M_ERROR_TERM, 0,
                   _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
-                  resources[rindex].name, res->res_dir.hdr.name);
-            }
-         }
-         next->next = (RES *)res;
+                 resources[rindex].name, res->res_dir.hdr.name);
+           }
+        }
+        next->next = (RES *)res;
          Dmsg4(200, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type),
-               res->res_dir.hdr.name, rindex, pass);
+              res->res_dir.hdr.name, rindex, pass);
       }
    }
 }
@@ -1088,9 +1104,9 @@ static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
    /* Store the type both pass 1 and pass 2 */
    for (i=0; jobtypes[i].type_name; i++) {
       if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) {
-         ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
-         i = 0;
-         break;
+        ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
+        i = 0;
+        break;
       }
    }
    if (i != 0) {
@@ -1112,9 +1128,9 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass)
    /* Store the level pass 2 so that type is defined */
    for (i=0; joblevels[i].level_name; i++) {
       if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
-         ((JOB *)(item->value))->level = joblevels[i].level;
-         i = 0;
-         break;
+        ((JOB *)(item->value))->level = joblevels[i].level;
+        i = 0;
+        break;
       }
    }
    if (i != 0) {
@@ -1131,9 +1147,9 @@ static void store_replace(LEX *lc, struct res_items *item, int index, int pass)
    /* Scan Replacement options */
    for (i=0; ReplaceOptions[i].name; i++) {
       if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
-         *(int *)(item->value) = ReplaceOptions[i].token;
-         i = 0;
-         break;
+        *(int *)(item->value) = ReplaceOptions[i].token;
+        i = 0;
+        break;
       }
    }
    if (i != 0) {
@@ -1170,59 +1186,59 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass)
       }
       Dmsg1(190, "Got keyword: %s\n", lc->str);
       for (i=0; BakVerFields[i].name; i++) {
-         if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
-            found = true;
-            if (lex_get_token(lc, T_ALL) != T_EQUALS) {
+        if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
+           found = true;
+           if (lex_get_token(lc, T_ALL) != T_EQUALS) {
                scan_err1(lc, "Expected an equals, got: %s", lc->str);
-            }
-            token = lex_get_token(lc, T_NAME);
+           }
+           token = lex_get_token(lc, T_NAME);
             Dmsg1(190, "Got value: %s\n", lc->str);
-            switch (BakVerFields[i].token) {
+           switch (BakVerFields[i].token) {
             case 'C':
-               /* Find Client Resource */
-               if (pass == 2) {
-                  res = GetResWithName(R_CLIENT, lc->str);
-                  if (res == NULL) {
+              /* Find Client Resource */
+              if (pass == 2) {
+                 res = GetResWithName(R_CLIENT, lc->str);
+                 if (res == NULL) {
                      scan_err1(lc, "Could not find specified Client Resource: %s",
-                                lc->str);
-                  }
-                  res_all.res_job.client = (CLIENT *)res;
-               }
-               break;
+                               lc->str);
+                 }
+                 res_all.res_job.client = (CLIENT *)res;
+              }
+              break;
             case 'F':
-               /* Find FileSet Resource */
-               if (pass == 2) {
-                  res = GetResWithName(R_FILESET, lc->str);
-                  if (res == NULL) {
+              /* Find FileSet Resource */
+              if (pass == 2) {
+                 res = GetResWithName(R_FILESET, lc->str);
+                 if (res == NULL) {
                      scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
-                                 lc->str);
-                  }
-                  res_all.res_job.fileset = (FILESET *)res;
-               }
-               break;
+                                lc->str);
+                 }
+                 res_all.res_job.fileset = (FILESET *)res;
+              }
+              break;
             case 'L':
-               /* Get level */
-               for (i=0; joblevels[i].level_name; i++) {
-                  if (joblevels[i].job_type == item->code && 
-                       strcasecmp(lc->str, joblevels[i].level_name) == 0) {
-                     ((JOB *)(item->value))->level = joblevels[i].level;
-                     i = 0;
-                     break;
-                  }
-               }
-               if (i != 0) {
+              /* Get level */
+              for (i=0; joblevels[i].level_name; i++) {
+                 if (joblevels[i].job_type == item->code && 
+                      strcasecmp(lc->str, joblevels[i].level_name) == 0) {
+                    ((JOB *)(item->value))->level = joblevels[i].level;
+                    i = 0;
+                    break;
+                 }
+              }
+              if (i != 0) {
                   scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
-               }
-               break;
-            } /* end switch */
-            break;
-         } /* end if strcmp() */
+              }
+              break;
+           } /* end switch */
+           break;
+        } /* end if strcmp() */
       } /* end for */
       if (!found) {
          scan_err1(lc, "%s not a valid Backup/verify keyword", lc->str);
       }
    } /* end while */
-   lc->options = options;             /* reset original options */
+   lc->options = options;            /* reset original options */
    set_bit(index, res_all.hdr.item_present);
 }
 
@@ -1251,91 +1267,91 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass)
       }
       for (i=0; RestoreFields[i].name; i++) {
          Dmsg1(190, "Restore kw=%s\n", lc->str);
-         if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
-            found = true;
-            if (lex_get_token(lc, T_ALL) != T_EQUALS) {
+        if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
+           found = true;
+           if (lex_get_token(lc, T_ALL) != T_EQUALS) {
                scan_err1(lc, "Expected an equals, got: %s", lc->str);
-            }
-            token = lex_get_token(lc, T_ALL);
+           }
+           token = lex_get_token(lc, T_ALL);
             Dmsg1(190, "Restore value=%s\n", lc->str);
-            switch (RestoreFields[i].token) {
+           switch (RestoreFields[i].token) {
             case 'B':
-               /* Bootstrap */
-               if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+              /* Bootstrap */
+              if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
                   scan_err1(lc, "Expected a Restore bootstrap file, got: %s", lc->str);
-               }
-               if (pass == 1) {
-                  res_all.res_job.RestoreBootstrap = bstrdup(lc->str);
-               }
-               break;
+              }
+              if (pass == 1) {
+                 res_all.res_job.RestoreBootstrap = bstrdup(lc->str);
+              }
+              break;
             case 'C':
-               /* Find Client Resource */
-               if (pass == 2) {
-                  res = GetResWithName(R_CLIENT, lc->str);
-                  if (res == NULL) {
+              /* Find Client Resource */
+              if (pass == 2) {
+                 res = GetResWithName(R_CLIENT, lc->str);
+                 if (res == NULL) {
                      scan_err1(lc, "Could not find specified Client Resource: %s",
-                                lc->str);
-                  }
-                  res_all.res_job.client = (CLIENT *)res;
-               }
-               break;
+                               lc->str);
+                 }
+                 res_all.res_job.client = (CLIENT *)res;
+              }
+              break;
             case 'F':
-               /* Find FileSet Resource */
-               if (pass == 2) {
-                  res = GetResWithName(R_FILESET, lc->str);
-                  if (res == NULL) {
+              /* Find FileSet Resource */
+              if (pass == 2) {
+                 res = GetResWithName(R_FILESET, lc->str);
+                 if (res == NULL) {
                      scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
-                                 lc->str);
-                  }
-                  res_all.res_job.fileset = (FILESET *)res;
-               }
-               break;
+                                lc->str);
+                 }
+                 res_all.res_job.fileset = (FILESET *)res;
+              }
+              break;
             case 'J':
-               /* JobId */
-               if (token != T_NUMBER) {
+              /* JobId */
+              if (token != T_NUMBER) {
                   scan_err1(lc, "expected an integer number, got: %s", lc->str);
-               }
-               errno = 0;
-               res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0);
+              }
+              errno = 0;
+              res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0);
                Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId);
-               if (errno != 0) {
+              if (errno != 0) {
                   scan_err1(lc, "expected an integer number, got: %s", lc->str);
-               }
-               break;
+              }
+              break;
             case 'W':
-               /* Where */
-               if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+              /* Where */
+              if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
                   scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str);
-               }
-               if (pass == 1) {
-                  res_all.res_job.RestoreWhere = bstrdup(lc->str);
-               }
-               break;
+              }
+              if (pass == 1) {
+                 res_all.res_job.RestoreWhere = bstrdup(lc->str);
+              }
+              break;
             case 'R':
-               /* Replacement options */
-               if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+              /* Replacement options */
+              if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
                   scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
-               }
-               /* Fix to scan Replacement options */
-               for (i=0; ReplaceOptions[i].name; i++) {
-                  if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
-                      ((JOB *)(item->value))->replace = ReplaceOptions[i].token;
-                     i = 0;
-                     break;
-                  }
-               }
-               if (i != 0) {
+              }
+              /* Fix to scan Replacement options */
+              for (i=0; ReplaceOptions[i].name; i++) {
+                 if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
+                     ((JOB *)(item->value))->replace = ReplaceOptions[i].token;
+                    i = 0;
+                    break;
+                 }
+              }
+              if (i != 0) {
                   scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
-               }
-               break;
-            } /* end switch */
-            break;
-         } /* end if strcmp() */
+              }
+              break;
+           } /* end switch */
+           break;
+        } /* end if strcmp() */
       } /* end for */
       if (!found) {
          scan_err1(lc, "%s not a valid Restore keyword", lc->str);
       }
    } /* end while */
-   lc->options = options;             /* reset original options */
+   lc->options = options;            /* reset original options */
    set_bit(index, res_all.hdr.item_present);
 }
index 417b56c4879ae6afd1b0de8d40c08fca9221b10e..bec790248cc1c57ab16355c269f9cb80f04ce73e 100644 (file)
@@ -44,8 +44,9 @@
 #define R_MSGS                1010
 #define R_COUNTER             1011
 #define R_CONSOLE             1012
+#define R_JOBDEFS             1013
 
-#define R_LAST                R_CONSOLE
+#define R_LAST                R_JOBDEFS    
 
 /*
  * Some resource attributes
@@ -172,7 +173,6 @@ struct STORE {
 
 /*
  *   Job Resource
- *
  */
 struct JOB {
    RES   hdr;
@@ -348,5 +348,6 @@ struct RUN {
    char mday[nbytes_for_bits(31)];    /* bit set for each day of month */
    char month[nbytes_for_bits(12)];   /* bit set for each month */
    char wday[nbytes_for_bits(7)];     /* bit set for each day of the week */
-   char wpos[nbytes_for_bits(5)];     /* week position */
+   char wom[nbytes_for_bits(5)];      /* week of month */
+   char woy[nbytes_for_bits(54)];     /* week of year */
 };
index 15ba907004702751f50f3e42f5e773f5f1e305f5..66fafec301403240ae131b9a79fc454203cf3395 100644 (file)
@@ -47,7 +47,8 @@ enum e_state {
    s_weekly,
    s_monthly,
    s_hourly,
-   s_wpos,                           /* 1st, 2nd, ...*/
+   s_wom,                          /* 1st, 2nd, ...*/
+   s_woy,                          /* week of year w00 - w53 */
 };  
 
 struct s_keyw {
@@ -105,43 +106,45 @@ static struct s_keyw keyw[] = {
   {N_("monthly"),    s_monthly, 0},
   {N_("hourly"),     s_hourly,  0},
 
-  {N_("1st"),        s_wpos,    0},
-  {N_("2nd"),        s_wpos,    1},
-  {N_("3rd"),        s_wpos,    2},
-  {N_("4th"),        s_wpos,    3},
-  {N_("5th"),        s_wpos,    4},
-
-  {N_("first"),      s_wpos,    0},
-  {N_("second"),     s_wpos,    1},
-  {N_("third"),      s_wpos,    2},
-  {N_("fourth"),     s_wpos,    3},
-  {N_("fifth"),      s_wpos,    4},
+  {N_("1st"),        s_wom,     0},
+  {N_("2nd"),        s_wom,     1},
+  {N_("3rd"),        s_wom,     2},
+  {N_("4th"),        s_wom,     3},
+  {N_("5th"),        s_wom,     4},
+
+  {N_("first"),      s_wom,     0},
+  {N_("second"),     s_wom,     1},
+  {N_("third"),      s_wom,     2},
+  {N_("fourth"),     s_wom,     3},
+  {N_("fifth"),      s_wom,     4},
   {NULL,        s_none,    0}
 };
 
-static int have_hour, have_mday, have_wday, have_month, have_wpos;
-static int have_at;
+static bool have_hour, have_mday, have_wday, have_month, have_wom;
+static bool have_at, have_woy;
 static RUN lrun;
 
 static void clear_defaults()
 {
-   have_hour = have_mday = have_wday = have_month = have_wpos = TRUE;
+   have_hour = have_mday = have_wday = have_month = have_wom = have_woy = true;
    clear_bit(0,lrun.hour);
    clear_bits(0, 30, lrun.mday);
    clear_bits(0, 6, lrun.wday);
    clear_bits(0, 11, lrun.month);
-   clear_bits(0, 4, lrun.wpos);
+   clear_bits(0, 4, lrun.wom);
+   clear_bits(0, 53, lrun.woy);
 }
 
 static void set_defaults()
 {
-   have_hour = have_mday = have_wday = have_month = have_wpos = FALSE;
-   have_at = FALSE;
+   have_hour = have_mday = have_wday = have_month = have_wom = have_woy = false;
+   have_at = false;
    set_bit(0,lrun.hour);
    set_bits(0, 30, lrun.mday);
    set_bits(0, 6, lrun.wday);
    set_bits(0, 11, lrun.month);
-   set_bits(0, 4, lrun.wpos);
+   set_bits(0, 4, lrun.wom);
+   set_bits(0, 53, lrun.woy);
 }
 
 
@@ -170,7 +173,8 @@ static struct s_kw RunFields[] = {
  */
 void store_run(LEX *lc, struct res_items *item, int index, int pass)
 {
-   int i, j, found;
+   int i, j;
+   bool found;
    int token, state, state2 = 0, code = 0, code2 = 0;
    int options = lc->options;
    RUN **run = (RUN **)(item->value);  
@@ -185,12 +189,12 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
    memset(&lrun, 0, sizeof(RUN));
 
    /* scan for Job level "full", "incremental", ... */
-   for (found=TRUE; found; ) {
-      found = FALSE;
+   for (found=true; found; ) {
+      found = false;
       token = lex_get_token(lc, T_NAME);
       for (i=0; RunFields[i].name; i++) {
         if (strcasecmp(lc->str, RunFields[i].name) == 0) {
-           found = TRUE;
+           found = true;
            if (lex_get_token(lc, T_ALL) != T_EQUALS) {
                scan_err1(lc, "Expected an equals, got: %s", lc->str);
               /* NOT REACHED */ 
@@ -268,7 +272,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         if (strcasecmp(lc->str, joblevels[j].level_name) == 0) {
            lrun.level = joblevels[j].level;
            lrun.job_type = joblevels[j].job_type;
-           found = TRUE;
+           found = true;
            break;
         }
       }
@@ -302,6 +306,15 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            state = s_time;
            break;
         }
+         if (lc->str_len == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') &&
+            is_an_integer(lc->str+1)) {
+           code = atoi(lc->str+1);
+           if (code < 0 || code > 53) {
+               scan_err0(lc, _("Week number out of range (0-53)"));
+           }
+           state = s_woy;            /* week of year */
+           break;
+        }
         /* everything else must be a keyword */
         for (i=0; keyw[i].name; i++) {
            if (strcasecmp(lc->str, keyw[i].name) == 0) {
@@ -330,14 +343,14 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         if (!have_mday) {
            clear_bits(0, 30, lrun.mday);
            clear_bits(0, 6, lrun.wday);
-           have_mday = TRUE;
+           have_mday = true;
         }
         set_bit(code, lrun.mday);
         break;
       case s_month:               /* month of year */
         if (!have_month) {
            clear_bits(0, 11, lrun.month);
-           have_month = TRUE;
+           have_month = true;
         }
         set_bit(code, lrun.month);
         break;
@@ -345,16 +358,23 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         if (!have_wday) {
            clear_bits(0, 6, lrun.wday);
            clear_bits(0, 30, lrun.mday);
-           have_wday = TRUE;
+           have_wday = true;
         }
         set_bit(code, lrun.wday);
         break;
-      case s_wpos:                /* Week position 1st, ... */
-        if (!have_wpos) {
-           clear_bits(0, 4, lrun.wpos);
-           have_wpos = TRUE;
+      case s_wom:                 /* Week of month 1st, ... */
+        if (!have_wom) {
+           clear_bits(0, 4, lrun.wom);
+           have_wom = true;
         }
-        set_bit(code, lrun.wpos);
+        set_bit(code, lrun.wom);
+        break;
+      case s_woy:
+        if (!have_woy) {
+           clear_bits(0, 53, lrun.woy);
+           have_woy = true;
+        }
+        set_bit(code, lrun.woy);
         break;
       case s_time:                /* time */
         if (!have_at) {
@@ -394,10 +414,10 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         }
         set_bit(code, lrun.hour);
         lrun.minute = code2;
-        have_hour = TRUE;
+        have_hour = true;
         break;
       case s_at:
-        have_at = TRUE;
+        have_at = true;
         break;
       case s_range:
          p = strchr(lc->str, '-');
@@ -416,7 +436,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            if (!have_mday) {
               clear_bits(0, 30, lrun.mday);
               clear_bits(0, 6, lrun.wday);
-              have_mday = TRUE;
+              have_mday = true;
            }
            if (code < code2) {
               set_bits(code, code2, lrun.mday);
@@ -426,7 +446,28 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            }
            break;
         }
-
+        /* Check for week of year range */
+        if (strlen(lc->str) == 3 && strlen(p) == 3 &&
+             (lc->str[0] == 'w' || lc->str[0] == 'W') &&
+             (p[0] == 'w' || p[0] == 'W') &&
+            is_an_integer(lc->str+1) && is_an_integer(p+1)) {
+           code = atoi(lc->str+1);
+           code2 = atoi(p+1);
+           if (code < 0 || code > 53 || code2 < 0 || code2 > 53) {
+               scan_err0(lc, _("Week number out of range (0-53)"));
+           }
+           if (!have_woy) {
+              clear_bits(0, 53, lrun.woy);
+              have_woy = true;
+           }
+           if (code < code2) {
+              set_bits(code, code2, lrun.woy);
+           } else {
+              set_bits(code, 53, lrun.woy);
+              set_bits(0, code2, lrun.woy);
+           }
+           break;
+        }
         /* lookup first half of keyword range (week days or months) */
         lcase(lc->str);
         for (i=0; keyw[i].name; i++) {
@@ -437,7 +478,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
               break;
            }
         }
-        if (i != 0 || (state != s_month && state != s_wday && state != s_wpos)) {
+        if (i != 0 || (state != s_month && state != s_wday && state != s_wom)) {
             scan_err0(lc, _("Invalid month, week or position day range"));
            /* NOT REACHED */
         }
@@ -460,7 +501,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            if (!have_wday) {
               clear_bits(0, 6, lrun.wday);
               clear_bits(0, 30, lrun.mday);
-              have_wday = TRUE;
+              have_wday = true;
            }
            if (code < code2) {
               set_bits(code, code2, lrun.wday);
@@ -471,7 +512,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         } else if (state == s_month) {
            if (!have_month) {
               clear_bits(0, 30, lrun.month);
-              have_month = TRUE;
+              have_month = true;
            }
            if (code < code2) {
               set_bits(code, code2, lrun.month);
@@ -482,15 +523,15 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            }
         } else {
            /* Must be position */
-           if (!have_wpos) {
-              clear_bits(0, 4, lrun.wpos);
-              have_wpos = TRUE;
+           if (!have_wom) {
+              clear_bits(0, 4, lrun.wom);
+              have_wom = true;
            }
            if (code < code2) {
-              set_bits(code, code2, lrun.wpos);
+              set_bits(code, code2, lrun.wom);
            } else {
-              set_bits(code, 4, lrun.wpos);
-              set_bits(0, code2, lrun.wpos);
+              set_bits(code, 4, lrun.wom);
+              set_bits(0, code2, lrun.wom);
            }
         }                      
         break;
@@ -499,24 +540,28 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         set_bits(0, 23, lrun.hour);
         set_bits(0, 30, lrun.mday);
         set_bits(0, 11, lrun.month);
-        set_bits(0, 4, lrun.wpos);
+        set_bits(0, 4, lrun.wom);
+        set_bits(0, 53, lrun.woy);
         break;
       case s_weekly:
         clear_defaults();
         set_bit(0, lrun.wday);
         set_bits(0, 11, lrun.month);
-        set_bits(0, 4, lrun.wpos);
+        set_bits(0, 4, lrun.wom);
+        set_bits(0, 53, lrun.woy);
         break;
       case s_daily:
         clear_defaults();
         set_bits(0, 30, lrun.mday);
         set_bits(0, 11, lrun.month);
-        set_bits(0, 4,  lrun.wpos);
+        set_bits(0, 4,  lrun.wom);
+        set_bits(0, 53, lrun.woy);
         break;
       case s_monthly:
         clear_defaults();
         set_bits(0, 11, lrun.month);
-        set_bits(0, 4,  lrun.wpos);
+        set_bits(0, 4,  lrun.wom);
+        set_bits(0, 53, lrun.woy);
         break;
       default:
          scan_err0(lc, _("Unexpected run state\n"));
index 5633fb3294da4e9445060eb61f00ad9f39c8a410..65ac9ada47881cfb9284a6b2943cb85bdea1eb05 100644 (file)
@@ -5,7 +5,7 @@
  *     and waits around until it is time to 
  *     fire them up.
  *
- *     Kern Sibbald, May MM
+ *     Kern Sibbald, May MM, revised December MMIII
  *
  *   Version $Id$
  */
@@ -42,46 +42,45 @@ static void add_job(JOB *job, RUN *run, time_t now, time_t runtime);
 /* Imported variables */
 
 /* Local variables */
-typedef struct {
+struct job_item {  
    RUN *run;
    JOB *job;
    time_t runtime;
-} RUNJOB;
+   dlink link;                       /* link for list */
+};             
 
-static int num_runjobs;              /* total jobs found by find_runs() */
-static int rem_runjobs;              /* jobs remaining to be processed */
-static int max_runjobs;              /* max jobs in runjobs array */
-static RUNJOB *runjobs;              /* array of jobs to be run */
+/* List of jobs to be run. They were scheduled in this hour or the next */
+static dlist *jobs_to_run;              /* list of jobs to be run */
 
+/* Time interval in secs to sleep if nothing to be run */
+#define NEXT_CHECK_SECS 60
 
 /*********************************************************************
  *
  *        Main Bacula Scheduler
  *
  */
-JCR *wait_for_next_job(char *job_to_run)
+JCR *wait_for_next_job(char *one_shot_job_to_run)
 {
    JCR *jcr;
    JOB *job;
    RUN *run;
    time_t now, runtime, nexttime;
-   int jobindex, i;
-   static int first = TRUE;
+   static bool first = true;
    char dt[MAX_TIME_LENGTH];
+   job_item *next_job = NULL;
 
    Dmsg0(200, "Enter wait_for_next_job\n");
    if (first) {
-      first = FALSE;
-      max_runjobs = 10;
-      runjobs = (RUNJOB *) malloc(sizeof(RUNJOB) * max_runjobs);
-      num_runjobs = 0;
-      rem_runjobs = 0;
-      if (job_to_run) {              /* one shot */
-        job = (JOB *)GetResWithName(R_JOB, job_to_run);
+      first = false;
+      /* Create scheduled jobs list */
+      jobs_to_run = new dlist(next_job, &next_job->link);
+      if (one_shot_job_to_run) {           /* one shot */
+        job = (JOB *)GetResWithName(R_JOB, one_shot_job_to_run);
         if (!job) {
-            Emsg1(M_ABORT, 0, _("Job %s not found\n"), job_to_run);
+            Emsg1(M_ABORT, 0, _("Job %s not found\n"), one_shot_job_to_run);
         }
-         Dmsg1(5, "Found job_to_run %s\n", job_to_run);
+         Dmsg1(5, "Found one_shot_job_to_run %s\n", one_shot_job_to_run);
         jcr = new_jcr(sizeof(JCR), dird_free_jcr);
         set_jcr_defaults(jcr, job);
         return jcr;
@@ -90,12 +89,12 @@ JCR *wait_for_next_job(char *job_to_run)
    /* Wait until we have something in the
     * next hour or so.
     */
-   while (rem_runjobs == 0) {
+   while (jobs_to_run->size() == 0) {
       find_runs();
-      if (rem_runjobs > 0) {
+      if (jobs_to_run->size() > 0) {
         break;
       }
-      bmicrosleep(60, 0);            /* recheck once per minute */
+      bmicrosleep(NEXT_CHECK_SECS, 0); /* recheck once per minute */
    }
 
    /* 
@@ -106,23 +105,25 @@ JCR *wait_for_next_job(char *job_to_run)
     */
    time(&now);
    nexttime = now + 60 * 60 * 24;     /* a much later time */
-   jobindex = -1;
    bstrftime(dt, sizeof(dt), now);
-   Dmsg2(400, "jobs=%d. Now is %s\n", rem_runjobs, dt);
-   for (i=0; i<num_runjobs; i++) {
-      runtime = runjobs[i].runtime;
+   Dmsg2(400, "jobs=%d. Now is %s\n", jobs_to_run->size(), dt);
+   next_job = NULL;
+   for (job_item *je=NULL; (je=(job_item *)jobs_to_run->next(je)); ) {
+      runtime = je->runtime;
       if (runtime > 0 && runtime < nexttime) { /* find minimum time job */
         nexttime = runtime;
-        jobindex = i;
+        next_job = je;
       }
-#ifdef xxxx_debug
+
+#define xxxx_debug
+#ifdef xxxx_debug
       if (runtime > 0) {
-        bstrftime(dt, sizeof(dt), runjobs[i].runtime);  
-         Dmsg2(100, "    %s run %s\n", dt, runjobs[i].job->hdr.name);
+        bstrftime(dt, sizeof(dt), next_job->runtime);  
+         Dmsg2(100, "    %s run %s\n", dt, next_job->job->hdr.name);
       }
 #endif
    }
-   if (jobindex < 0) {               /* we really should have something now */
+   if (!next_job) {               /* we really should have something now */
       Emsg0(M_ABORT, 0, _("Scheduler logic error\n"));
    }
 
@@ -136,11 +137,10 @@ JCR *wait_for_next_job(char *job_to_run)
       }
       bmicrosleep(twait, 0);
    }
-   run = runjobs[jobindex].run;
-   job = runjobs[jobindex].job;
-   runjobs[jobindex].runtime = 0;     /* remove from list */
+   run = next_job->run;              /* pick up needed values */
+   job = next_job->job;
+   jobs_to_run->remove(next_job);       /* remove from list */
    run->last_run = now;              /* mark as run */
-   rem_runjobs--;                    /* decrement count of remaining jobs */
 
    jcr = new_jcr(sizeof(JCR), dird_free_jcr);
    ASSERT(job);
@@ -170,42 +170,57 @@ JCR *wait_for_next_job(char *job_to_run)
  */
 void term_scheduler()
 {
-   if (runjobs) {                    /* free allocated memory */
-      free(runjobs);
-      runjobs = NULL;
-      max_runjobs = 0;
+   /* Release all queued job entries to be run */
+   for (void *je=NULL; (je=jobs_to_run->next(je)); ) {
+      free(je);
    }
+   delete jobs_to_run;
 }
 
-
 /*         
- * Find all jobs to be run this hour
- * and the next hour.
+ * Find all jobs to be run this hour and the next hour.
  */
 static void find_runs()
 {
-   time_t now, runtime;
+   time_t now, next_hour, runtime;
    RUN *run;
    JOB *job;
    SCHED *sched;
    struct tm tm;
-   int hour, next_hour, minute, mday, wday, month, wpos;
+   int minute;
+   int hour, mday, wday, month, wom, woy;
+   /* Items corresponding to above at the next hour */
+   int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy, nh_year;
 
    Dmsg0(200, "enter find_runs()\n");
-   num_runjobs = 0;
 
+   
+   /* compute values for time now */
    now = time(NULL);
    localtime_r(&now, &tm);
-   
    hour = tm.tm_hour;
-   next_hour = hour + 1;
-   if (next_hour > 23)
-      next_hour -= 24;
    minute = tm.tm_min;
    mday = tm.tm_mday - 1;
    wday = tm.tm_wday;
    month = tm.tm_mon;
-   wpos = (tm.tm_mday - 1) / 7; 
+   wom = tm_wom(tm.tm_mday, tm.tm_wday);  /* get week of month */
+   woy = tm_woy(now);                    /* get week of year */
+
+   /* 
+    * Compute values for next hour from now.
+    * We do this to be sure we don't miss a job while
+    * sleeping.
+    */
+   next_hour = now + 3600;  
+   localtime_r(&next_hour, &tm);
+   nh_hour = tm.tm_hour;
+   minute = tm.tm_min;
+   nh_mday = tm.tm_mday - 1;
+   nh_wday = tm.tm_wday;
+   nh_month = tm.tm_mon;
+   nh_year  = tm.tm_year;
+   nh_wom = tm_wom(tm.tm_mday, tm.tm_wday);  /* get week of month */
+   nh_woy = tm_woy(now);                    /* get week of year */
 
    /* Loop through all jobs */
    LockRes();
@@ -215,36 +230,44 @@ static void find_runs()
         continue;                    /* no, skip this job */
       }
       for (run=sched->run; run; run=run->next) {
+        bool run_now, run_nh;
 
-        /* Find runs scheduled in this our or in the
-         * next hour (we may be one second before the next hour).
+        /* Find runs scheduled between now and the next
+         * check time (typically 60 seconds)
          */
-        if ((bit_is_set(hour, run->hour) || bit_is_set(next_hour, run->hour)) &&
-            (bit_is_set(mday, run->mday) || bit_is_set(wday, run->wday)) && 
-            bit_is_set(month, run->month) && bit_is_set(wpos, run->wpos)) {
+        run_now = bit_is_set(hour, run->hour) &&
+           (bit_is_set(mday, run->mday) || bit_is_set(wday, run->wday)) &&
+           bit_is_set(month, run->month) &&
+           bit_is_set(wom, run->wom) &&
+           bit_is_set(woy, run->woy);
+
+        run_nh = bit_is_set(nh_hour, run->hour) &&
+           (bit_is_set(nh_mday, run->mday) || bit_is_set(nh_wday, run->wday)) &&
+           bit_is_set(nh_month, run->month) &&
+           bit_is_set(nh_wom, run->wom) &&
+           bit_is_set(nh_woy, run->woy);
 
-           /* find time (time_t) job is to be run */
-           localtime_r(&now, &tm);
-           tm.tm_min = run->minute;
-           tm.tm_sec = 0;
-           if (bit_is_set(hour, run->hour)) {
-              runtime = mktime(&tm);
-              add_job(job, run, now, runtime);
-           }
-           if (bit_is_set(next_hour, run->hour)) {
-              tm.tm_hour++;
-              if (tm.tm_hour > 23) {
-                 tm.tm_hour = 0;
-              }
-              runtime = mktime(&tm);
-              add_job(job, run, now, runtime);
-           }
+        /* find time (time_t) job is to be run */
+        localtime_r(&now, &tm);      /* reset tm structure */
+        tm.tm_min = run->minute;     /* set run minute */
+        tm.tm_sec = 0;               /* zero secs */
+        if (run_now) {
+           runtime = mktime(&tm);
+           add_job(job, run, now, runtime);
+        }
+        /* If job is to be run in the next hour schedule it */
+        if (run_nh) {
+           /* Set correct values */
+           tm.tm_hour = nh_hour;
+           tm.tm_mday = nh_mday;
+           tm.tm_mon = nh_month;
+           tm.tm_year = nh_year;
+           runtime = mktime(&tm);
+           add_job(job, run, now, runtime);
         }
       }  
    }
-
    UnlockRes();
-   rem_runjobs = num_runjobs;
    Dmsg0(200, "Leave find_runs()\n");
 }
 
@@ -257,16 +280,11 @@ static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
    if ((runtime - run->last_run < 61) || (runtime+59 < now)) {
       return;
    }
-
-   /* Make sure array is big enough */
-   if (num_runjobs == max_runjobs) {
-      max_runjobs += 10;
-      runjobs = (RUNJOB *)realloc(runjobs, sizeof(RUNJOB) * max_runjobs);
-      if (!runjobs)
-         Emsg0(M_ABORT, 0, _("Out of memory\n"));
-   } 
    /* accept to run this job */
-   runjobs[num_runjobs].run = run;
-   runjobs[num_runjobs].job = job;
-   runjobs[num_runjobs++].runtime = runtime; /* when to run it */
+   job_item *je = (job_item *)malloc(sizeof(job_item));
+   je->run = run;
+   je->job = job;
+   je->runtime = runtime;
+   /* ***FIXME**** (enhancement) insert by sorted runtime */
+   jobs_to_run->append(je);
 }
index b2ec0eee23ff2f064ac6ceabccb3c8aa73428d06..f7c6edd4403a87493945e556ce8d09987e034ec9 100644 (file)
@@ -438,7 +438,8 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
    time_t now, tomorrow;
    SCHED *sched;
    struct tm tm;
-   int mday, wday, month, wpos, tmday, twday, tmonth, twpos, i, hour;
+   int mday, wday, month, wom, tmday, twday, tmonth, twom, i, hour;
+   int woy, twoy;
    int tod, tom;
 
    Dmsg0(200, "enter find_runs()\n");
@@ -453,7 +454,8 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
    mday = tm.tm_mday - 1;
    wday = tm.tm_wday;
    month = tm.tm_mon;
-   wpos = (tm.tm_mday - 1) / 7;
+   wom = tm_wom(tm.tm_mday, tm.tm_wday);
+   woy = tm_woy(now);
 
    /* Break down tomorrow into components */
    tomorrow = now + 60 * 60 * 24;
@@ -461,7 +463,8 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
    tmday = tm.tm_mday - 1;
    twday = tm.tm_wday;
    tmonth = tm.tm_mon;
-   twpos  = (tm.tm_mday - 1) / 7;
+   twom  = tm_wom(tm.tm_mday, tm.tm_wday);
+   twoy  = tm_woy(tomorrow);
 
    if (run == NULL) {
       run = sched->run;
@@ -473,10 +476,12 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
        * Find runs in next 24 hours
        */
       tod = (bit_is_set(mday, run->mday) || bit_is_set(wday, run->wday)) && 
-            bit_is_set(month, run->month) && bit_is_set(wpos, run->wpos);
+            bit_is_set(month, run->month) && bit_is_set(wom, run->wom) &&
+            bit_is_set(woy, run->woy);
 
       tom = (bit_is_set(tmday, run->mday) || bit_is_set(twday, run->wday)) &&
-            bit_is_set(tmonth, run->month) && bit_is_set(twpos, run->wpos);
+            bit_is_set(tmonth, run->month) && bit_is_set(twom, run->wom) &&
+            bit_is_set(twoy, run->woy);
 
       Dmsg2(200, "tod=%d tom=%d\n", tod, tom);
       if (tod) {                  /* Jobs scheduled today (next 24 hours) */
index 36410af26146ad90dfa4f7c6f1d614db133fbd4d..00a4f8ae37d30ed1bc67528518471aea9f69ac3d 100644 (file)
@@ -197,6 +197,7 @@ static void do_director_status(UAContext *ua, char *cmd)
    bsendmsg(ua, "%s Version: " VERSION " (" BDATE ") %s %s %s\n", my_name,
            HOST_OS, DISTNAME, DISTVER);
    bstrftime(dt, sizeof(dt), daemon_start_time);
+   strcpy(dt+7, dt+9);    /* cut century */
    bsendmsg(ua, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
         last_job.NumJobs == 1 ? "" : "s");
    /*
@@ -314,6 +315,7 @@ static void prt_runtime(UAContext *ua, JOB *job, int level, time_t runtime, POOL
       }
    }
    bstrftime(dt, sizeof(dt), runtime);
+   strcpy(dt+7, dt+9);    /* cut century */
    switch (job->JobType) {
    case JT_ADMIN:
    case JT_RESTORE:
@@ -385,6 +387,7 @@ static void list_running_jobs(UAContext *ua)
    for (jcr=NULL; (jcr=get_next_jcr(jcr)); njobs++) {
       if (jcr->JobId == 0) {     /* this is us */
         bstrftime(dt, sizeof(dt), jcr->start_time);
+        strcpy(dt+7, dt+9);     /* cut century */
          bsendmsg(ua, _("Console connected at %s\n"), dt);
         njobs--;
       }
@@ -528,14 +531,14 @@ static void list_terminated_jobs(UAContext *ua)
    char dt[MAX_TIME_LENGTH], b1[30], b2[30];
    char level[10];
 
-   if (last_job.NumJobs == 0) {
+   if (last_jobs->size() == 0) {
       bsendmsg(ua, _("No Terminated Jobs.\n"));
       return;
    }
    lock_last_jobs_list();
    struct s_last_job *je;
    bsendmsg(ua, _("\nTerminated Jobs:\n"));
-   bsendmsg(ua, _("Level   Files        Bytes Status   Finished        Name \n"));
+   bsendmsg(ua, _(" JobId  Level   Files        Bytes Status   Finished        Name \n"));
    bsendmsg(ua, _("====================================================================\n"));
    for (je=NULL; (je=(s_last_job *)last_jobs->next(je)); ) {
       char JobName[MAX_NAME_LENGTH];
@@ -582,7 +585,8 @@ static void list_terminated_jobs(UAContext *ua)
            *p = 0;
         }
       }
-      bsendmsg(ua, _("%-4s %8s %12s %-7s  %-8s %s\n"), 
+      bsendmsg(ua, _("%6d  %-4s %8s %12s %-7s  %-8s %s\n"), 
+        je->JobId,
         level, 
         edit_uint64_with_commas(je->JobFiles, b1),
         edit_uint64_with_commas(je->JobBytes, b2), 
index 806a98d70c183ea9be2a15382ada5f1a592cbc83..9c4aa0deffa385e0062a5ac40128291cd740a6c6 100755 (executable)
@@ -60,6 +60,7 @@ static void do_status(void sendit(char *msg, int len, void *sarg), void *arg)
              HOST_OS, DISTNAME, DISTVER);
    sendit(msg, len, arg);
    bstrftime(dt, sizeof(dt), daemon_start_time);
+   strcpy(dt+7, dt+9);               /* cut century */
    len = Mmsg(&msg, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
         last_job.NumJobs == 1 ? "" : "s");
    sendit(msg, len, arg);
@@ -89,6 +90,7 @@ static void do_status(void sendit(char *msg, int len, void *sarg), void *arg)
       lock_last_jobs_list();
       for (je=NULL; (je=(s_last_job *)last_jobs->next(je)); ) {
         bstrftime(dt, sizeof(dt), je->end_time);
+        strcpy(dt+7, dt+9);            /* cut century */
          len = Mmsg(&msg, _("Last Job %s finished at %s\n"), je->Job, dt);
         sendit(msg, len, arg);
 
@@ -109,6 +111,7 @@ static void do_status(void sendit(char *msg, int len, void *sarg), void *arg)
    lock_jcr_chain();
    for (njcr=NULL; (njcr=get_next_jcr(njcr)); ) {
       bstrftime(dt, sizeof(dt), njcr->start_time);
+      strcpy(dt+7, dt+9);            /* cut century */
       if (njcr->JobId == 0) {
          len = Mmsg(&msg, _("Director connected at: %s\n"), dt);
       } else {
@@ -178,7 +181,7 @@ static void list_terminated_jobs(void *arg)
    lock_last_jobs_list();
    msg =  _("\nTerminated Jobs:\n"); 
    sendit(msg, strlen(msg), arg);
-   msg =  _("Level   Files        Bytes Status   Finished        Name \n");
+   msg =  _(" JobId  Level   Files        Bytes Status   Finished        Name \n");
    sendit(msg, strlen(msg), arg);
    msg = _("====================================================================\n"); 
    sendit(msg, strlen(msg), arg);
@@ -228,7 +231,8 @@ static void list_terminated_jobs(void *arg)
            *p = 0;
         }
       }
-      bsnprintf(buf, sizeof(buf), _("%-4s %8s %12s %-7s  %-8s %s\n"), 
+      bsnprintf(buf, sizeof(buf), _("%6d  %-4s %8s %12s %-7s  %-8s %s\n"), 
+        je->JobId,
         level, 
         edit_uint64_with_commas(je->JobFiles, b1),
         edit_uint64_with_commas(je->JobBytes, b2), 
index 97e4fe829d133f52af381ec692959f8e89c9a117..8cd302f472a1338acbdd1f8896102f9719ec1f74 100644 (file)
@@ -120,6 +120,58 @@ utime_t btime_to_utime(btime_t bt)
    return (utime_t)(bt/1000000);
 }
 
+/*
+ * Return the week of the month, base 0 (wpos)
+ *   given tm_mday and tm_wday. Value returned
+ *   can be from 0 to 4 => week1, ... week5
+ */
+int tm_wom(int mday, int wday)
+{
+   int fs;                      /* first sunday */
+   fs = (mday%7) - wday;
+   if (fs <= 0) {
+      fs += 7;
+   }
+   if (mday <= fs) {
+//    Dmsg2(100, "wom=0 wday=%d <= fs=%d\n", wday, fs);
+      return 0;
+   }
+   int wom = 1 + (mday - fs - 1) / 7;
+// Dmsg3(100, "wom=%d wday=%d fs=%d\n", wom, wday, fs);
+   return wom;
+}  
+
+/*
+ * Given a Unix date return the week of the year.
+ * The returned value can be 0-53.  Officially
+ * the weeks are numbered from 1 to 53 where week1
+ * is the week in which the first Thursday of the
+ * year occurs (alternatively, the week which contains
+ * the 4th of January).  We return 0, if the week of the
+ * year does not fall in the current year.
+ */
+int tm_woy(time_t stime)
+{
+   int woy, fty, tm_yday;
+   time_t time4;
+   struct tm tm;
+   memset(&tm, 0, sizeof(struct tm));
+   localtime_r(&stime, &tm);
+   tm_yday = tm.tm_yday;
+   tm.tm_mon = 0;
+   tm.tm_mday = 4;
+   time4 = mktime(&tm);
+   localtime_r(&time4, &tm);
+   fty = 1 - tm.tm_wday;
+   if (fty <= 0) {
+      fty += 7;
+   }
+   woy = tm_yday - fty + 4;
+   if (woy < 0) {
+      return 0;
+   }
+   return 1 + woy / 7;
+}
 
 /* Deprecated. Do not use. */
 void get_current_time(struct date_time *dt)
index a35756947e5aceb9891cefe7dafc7e0bb02328fe..9dfc88b8b24b4880aed7fd38360dc3216d9028cf 100644 (file)
@@ -3,14 +3,6 @@
 
   See btime.c for defintions.
 
-  The following is deprecated:
-    Time and date structures and functions.
-    Date and time are always represented internally
-    as 64 bit floating point Julian day numbers and
-    fraction.  The day number and fraction are kept
-    as separate quantities to avoid round-off of
-    day fraction. John Walker
-
      Version $Id$
 
  */
@@ -44,6 +36,9 @@ extern btime_t get_current_btime(void);
 extern time_t btime_to_unix(btime_t bt);   /* bacula time to epoch time */
 extern utime_t btime_to_utime(btime_t bt); /* bacula time to utime_t */
 
+extern int tm_wom(int mday, int wday);
+extern int tm_woy(time_t stime);
+
 extern char *bstrftime(char *dt, int maxlen, utime_t tim);
 extern char *bstrutime(char *dt, int maxlen, utime_t tim);
 extern utime_t str_to_utime(char *str);
index 15307bc3b357c98b47aff71bba1dea525cac0342..03d74717d8c1b2dcd4f8a8200bc33467c643a919 100644 (file)
@@ -48,6 +48,7 @@ void dlist::append(void *item)
    if (head == NULL) {               /* if empty list, */
       head = item;                   /* item is head as well */
    }
+   num_items++;
 }
 
 /*
@@ -64,6 +65,7 @@ void dlist::prepend(void *item)
    if (tail == NULL) {               /* if empty list, */                    
       tail = item;                   /* item is tail too */
    }
+   num_items++;
 }
 
 void dlist::insert_before(void *item, void *where)      
@@ -80,6 +82,7 @@ void dlist::insert_before(void *item, void *where)
    if (head == where) {
       head = item;
    }
+   num_items++;
 }
 
 void dlist::insert_after(void *item, void *where)      
@@ -96,6 +99,7 @@ void dlist::insert_after(void *item, void *where)
    if (tail == where) {
       tail = item;
    }
+   num_items++;
 }
 
 
@@ -122,6 +126,7 @@ void dlist::remove(void *item)
       xitem = ilink->prev;
       ((dlink *)((char *)xitem+loffset))->next = ilink->next;
    }
+   num_items--;
 }
 
 void * dlist::next(void *item)
@@ -141,7 +146,7 @@ void * dlist::prev(void *item)
 }
 
 
-/* Destroy the list and its contents */
+/* Destroy the list contents */
 void dlist::destroy()
 {
    for (void *n=head; n; ) {
@@ -149,6 +154,7 @@ void dlist::destroy()
       free(n);
       n = ni;
    }
+   num_items = 0;
 }
 
 
index 84121b1c2c38a7e517a4e867a663c0ed90b3d5ba..0b4a154789a049cc3553c47558f639f83a628ff7 100644 (file)
@@ -39,6 +39,7 @@ class dlist {
    void *head;
    void *tail;
    int loffset;
+   int num_items;
 public:
    dlist(void *item, void *link);
    void init(void *item, void *link);
@@ -48,6 +49,7 @@ public:
    void insert_after(void *item, void *where);
    void remove(void *item);
    bool empty();
+   int  size();
    void *next(void *item);
    void *prev(void *item);
    void destroy();
@@ -66,6 +68,7 @@ inline void dlist::init(void *item, void *link)
 {
    head = tail = NULL;
    loffset = (char *)link - (char *)item;
+   num_items = 0;
 }
 
 /* Constructor */
@@ -78,6 +81,12 @@ inline bool dlist::empty()
 {
    return head == NULL;
 }
+
+inline int dlist::size()
+{
+   return num_items;
+}
+
    
 inline void * dlist::operator new(size_t)
 {
index 0eb07274d81c01e5f4cb60a51bd4bc9f0f00002b..6936b63854bcb2a0e727367be5041f360ba38e1c 100755 (executable)
@@ -35,10 +35,11 @@ extern void timeout_handler(int sig);
 
 struct s_last_job last_job;    /* last job run by this daemon */
 dlist *last_jobs;
-static int num_last_jobs = 0;
 #define MAX_LAST_JOBS 10
 
 static JCR *jobs = NULL;             /* pointer to JCR chain */
+
+/* Mutex for locking various jcr chains while updating */
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 void init_last_jobs_list()
@@ -227,24 +228,23 @@ void free_jcr(JCR *jcr)
       return;
    }
    remove_jcr(jcr);
-   V(mutex);
 
    Dmsg1(200, "End job=%d\n", jcr->JobId);
    if (jcr->daemon_free_jcr) {
       jcr->daemon_free_jcr(jcr);      /* call daemon free routine */
    }
+
    free_common_jcr(jcr);
 
-   P(mutex);
    /* Keep list of last jobs, but not Console where JobId==0 */
    if (last_job.JobId > 0) {
       je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
       memcpy((char *)je, (char *)&last_job, sizeof(last_job));
       last_jobs->append(je);
-      if (++num_last_jobs > MAX_LAST_JOBS) {
+      if (last_jobs->size() > MAX_LAST_JOBS) {
         last_jobs->remove(last_jobs->first());
-        num_last_jobs--;
       }
+      last_job.JobId = 0;            /* zap last job */
    }
    close_msg(NULL);                  /* flush any daemon messages */
    V(mutex);
index 5a390915c92ed92314e94c9879dab8dc704209dd..87f0ceb21f3800bfd4b13db9d460f8dc63e2f863 100755 (executable)
@@ -345,8 +345,6 @@ void store_strname(LEX *lc, struct res_items *item, int index, int pass)
    set_bit(index, res_all.hdr.item_present);
 }
 
-
-
 /* Store a string at specified address */
 void store_str(LEX *lc, struct res_items *item, int index, int pass)
 {
@@ -414,7 +412,7 @@ void store_res(LEX *lc, struct res_items *item, int index, int pass)
    if (pass == 2) {
      res = GetResWithName(item->code, lc->str);
      if (res == NULL) {
-        scan_err3(lc, "Could not find Resource %s referenced on line %d : %s\n"
+        scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n")
           lc->str, lc->line_no, lc->line);
      }
      *(item->value) = (char *)res;
@@ -423,6 +421,32 @@ void store_res(LEX *lc, struct res_items *item, int index, int pass)
    set_bit(index, res_all.hdr.item_present);
 }
 
+/* Store default values for Resource from xxxDefs
+ * If we are in pass 2, do a lookup of the 
+ * resource and store everything not explicitly set
+ * in main resource.
+ *
+ * Note, here item points to the main resource (e.g. Job, not
+ *  the jobdefs, which we look up).
+ */
+void store_defs(LEX *lc, struct res_items *item, int index, int pass)
+{
+   RES *res;
+
+   lex_get_token(lc, T_NAME);
+   if (pass == 2) {
+     res = GetResWithName(item->code, lc->str);
+     if (res == NULL) {
+        scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"), 
+          lc->str, lc->line_no, lc->line);
+     }
+     /* for each item not set, we copy the field from item */
+     /* ***FIXME **** add code */
+   }
+   scan_to_eol(lc);
+}
+
+
 
 /* Store an integer at specified address */
 void store_int(LEX *lc, struct res_items *item, int index, int pass)
index 1227d0a937e30272fa8ccf23372dd4d8ea1299f6..6b07b0afa69e1651c02401d481142262f5911caf 100644 (file)
@@ -124,3 +124,4 @@ void store_int64(LEX *lc, struct res_items *item, int index, int pass);
 void store_yesno(LEX *lc, struct res_items *item, int index, int pass);
 void store_time(LEX *lc, struct res_items *item, int index, int pass);
 void store_size(LEX *lc, struct res_items *item, int index, int pass);
+void store_defs(LEX *lc, struct res_items *item, int index, int pass);
index 5cfb31bb6f5570efc2ea0a71a5c6ecd005b181bf..4aadbd93ec55037775f9041286c0f01aab09d9be 100644 (file)
@@ -40,8 +40,9 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  */
 int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 {
-   int stat = 0;
-   int tape_previously_mounted;
+   bool vol_ok = false;
+   bool tape_previously_mounted;
+   bool tape_initially_mounted;
    VOL_LIST *vol;
    int autochanger = 0;
    int i;
@@ -54,14 +55,17 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    block_device(dev, BST_DOING_ACQUIRE);
    unlock_device(dev);
 
-   tape_previously_mounted = dev_state(dev, ST_READ) || dev_state(dev, ST_APPEND);
-
    if (dev_state(dev, ST_READ) || dev->num_writers > 0) {
       Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"), 
            dev_name(dev), jcr->JobId);
       goto get_out;
    }
 
+   tape_previously_mounted = dev_state(dev, ST_READ) || 
+                            dev_state(dev, ST_APPEND) ||
+                            dev_state(dev, ST_LABEL);
+   tape_initially_mounted = tape_previously_mounted;
+
    /* Find next Volume, if any */
    vol = jcr->VolList;
    if (!vol) {
@@ -93,11 +97,15 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
         }
          Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
       }
+      /****FIXME***** do not reread label if ioctl() says we are
+       *  correctly possitioned.  Possibly have way user can turn
+       *  this optimization (to be implemented) off.
+       */
       dev->state &= ~ST_LABEL;          /* force reread of label */
       Dmsg0(200, "calling read-vol-label\n");
       switch (read_dev_volume_label(jcr, dev, block)) {
       case VOL_OK:
-        stat = 1;
+        vol_ok = true;
         break;                    /* got it */
       case VOL_IO_ERROR:
         /*
@@ -109,10 +117,16 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
             Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);                         
         }
         goto default_path;
+      case VOL_NAME_ERROR:
+        if (tape_initially_mounted) {
+           tape_initially_mounted = false;
+           goto default_path;
+        }
+        /* Fall through */
       default:
          Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
 default_path:
-        tape_previously_mounted = 1;
+        tape_previously_mounted = true;
          Dmsg0(200, "dir_get_volume_info\n");
         if (!dir_get_volume_info(jcr, GET_VOL_INFO_FOR_READ)) { 
             Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
@@ -135,12 +149,13 @@ default_path:
       } /* end switch */
       break;
    } /* end for loop */
-   if (stat == 0) {
+   if (!vol_ok) {
       Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device \"%s\".\n"),
            dev_name(dev));
       goto get_out;
    }
 
+   dev->state &= ~ST_APPEND;
    dev->state |= ST_READ;
    attach_jcr_to_device(dev, jcr);    /* attach jcr to device */
    Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
@@ -150,7 +165,7 @@ get_out:
    P(dev->mutex); 
    unblock_device(dev);
    V(dev->mutex);
-   return stat;
+   return vol_ok;
 }
 
 /*
@@ -296,45 +311,33 @@ int release_device(JCR *jcr, DEVICE *dev)
    } else if (dev->num_writers > 0) {
       dev->num_writers--;
       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
-      if (dev->num_writers == 0) {
-        /* If we are the only writer, write EOF after job */
-        if (dev_state(dev, ST_LABEL)) {
-            Dmsg0(100, "dir_create_jobmedia_record. Release\n");
-           if (!dir_create_jobmedia_record(jcr)) {
-               Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
-              jcr->VolCatInfo.VolCatName, jcr->Job);
-           }
-           if (dev_can_write(dev)) {
-              weof_dev(dev, 1);
-           }
-           dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
-           dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
-           /* Note! do volume update before close, which zaps VolCatInfo */
-            Dmsg0(100, "dir_update_vol_info. Release0\n");
-           dir_update_volume_info(jcr, dev, 0); /* send Volume info to Director */
-        }
-
-        if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) {
-           offline_or_rewind_dev(dev);
-           close_dev(dev);
-        }
-      } else if (dev_state(dev, ST_LABEL)) {
+      if (dev_state(dev, ST_LABEL)) {
          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
         if (!dir_create_jobmedia_record(jcr)) {
             Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
-              jcr->VolCatInfo.VolCatName, jcr->Job);
+           jcr->VolCatInfo.VolCatName, jcr->Job);
+        }
+        /* If no more writers, write an EOF */
+        if (!dev->num_writers && dev_can_write(dev)) {
+           weof_dev(dev, 1);
         }
-         Dmsg0(100, "dir_update_vol_info. Release1\n");
         dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
         dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
+        /* Note! do volume update before close, which zaps VolCatInfo */
+         Dmsg0(100, "dir_update_vol_info. Release0\n");
         dir_update_volume_info(jcr, dev, 0); /* send Volume info to Director */
       }
+
+      if (!dev->num_writers && (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN))) {
+        offline_or_rewind_dev(dev);
+        close_dev(dev);
+      }
    } else {
       Jmsg2(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s, Volume \"%s\" not in use.\n"), 
            dev_name(dev), NPRT(jcr->VolumeName));
    }
    detach_jcr_from_device(dev, jcr);
-   if (dev->prev && !dev_state(dev, ST_READ) && dev->num_writers == 0) {
+   if (dev->prev && !dev_state(dev, ST_READ) && !dev->num_writers) {
       P(mutex);
       unlock_device(dev);
       dev->prev->next = dev->next;    /* dechain */
index f1b775f6f457ad48f945edce5c6875cb0380cfbd..c98d7e74d21b1b06c8b23d3d1eea45f26d043941 100644 (file)
@@ -64,6 +64,7 @@ int status_cmd(JCR *jcr)
    bnet_fsend(user, "\n%s Version: " VERSION " (" BDATE ") %s %s %s\n", my_name,
              HOST_OS, DISTNAME, DISTVER);
    bstrftime(dt, sizeof(dt), daemon_start_time);
+   strcpy(dt+7, dt+9);               /* cut century */
    bnet_fsend(user, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
         last_job.NumJobs == 1 ? "" : "s");
 
@@ -71,18 +72,6 @@ int status_cmd(JCR *jcr)
     * List terminated jobs
     */
    list_terminated_jobs(user);
-#ifdef xxx
-      char termstat[30];
-
-      bstrftime(dt, sizeof(dt), last_job.end_time);
-      bnet_fsend(user, _("Last Job %s finished at %s\n"), last_job.Job, dt);
-
-      jobstatus_to_ascii(last_job.JobStatus, termstat, sizeof(termstat));
-      bnet_fsend(user, _("  Files=%s Bytes=%s Termination Status=%s\n"), 
-          edit_uint64_with_commas(last_job.JobFiles, b1),
-          edit_uint64_with_commas(last_job.JobBytes, b2),
-          termstat);
-#endif
 
    /*
     * List devices
@@ -268,7 +257,7 @@ static void list_terminated_jobs(void *arg)
    lock_last_jobs_list();
    msg =  _("\nTerminated Jobs:\n"); 
    sendit(msg, strlen(msg), arg);
-   msg =  _("Level   Files        Bytes Status   Finished        Name \n");
+   msg =  _(" JobId  Level   Files        Bytes Status   Finished        Name \n");
    sendit(msg, strlen(msg), arg);
    msg = _("====================================================================\n"); 
    sendit(msg, strlen(msg), arg);
@@ -318,7 +307,8 @@ static void list_terminated_jobs(void *arg)
            *p = 0;
         }
       }
-      bsnprintf(buf, sizeof(buf), _("%-4s %8s %12s %-7s  %-8s %s\n"), 
+      bsnprintf(buf, sizeof(buf), _("%6d  %-4s %8s %12s %-7s  %-8s %s\n"), 
+        je->JobId,
         level, 
         edit_uint64_with_commas(je->JobFiles, b1),
         edit_uint64_with_commas(je->JobBytes, b2), 
index 1e07e29ede5c78c25ab1dc8adf39c80bc6c89d91..9adea43eeba3c4aec10b41ba4eb4b5dfe9f35347 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.33"
 #define VSTRING "1"
-#define BDATE   "08 Dec 2003"
-#define LSMDATE "08Dec03"
+#define BDATE   "17 Dec 2003"
+#define LSMDATE "17Dec03"
 
 /* Debug flags */
 #undef  DEBUG