+++ /dev/null
-Index: src/dird/dird_conf.c
-===================================================================
---- src/dird/dird_conf.c (révision 7525)
-+++ src/dird/dird_conf.c (copie de travail)
-@@ -509,6 +509,16 @@
- {NULL, 0}
- };
-
-+char *CAT::display(POOLMEM *dst) {
-+ Mmsg(dst,"catalog=%s\ndb_name=%s\ndb_driver=%s\ndb_user=%s\n"
-+ "db_password=%s\ndb_address=%s\ndb_port=%i\n"
-+ "db_socket=%s\n",
-+ name(), NPRTB(db_name),
-+ NPRTB(db_driver), NPRTB(db_user), NPRTB(db_password),
-+ NPRTB(db_address), db_port, NPRTB(db_socket));
-+ return dst;
-+}
-+
- const char *level_to_str(int level)
- {
- int i;
-Index: src/dird/dird_conf.h
-===================================================================
---- src/dird/dird_conf.h (révision 7525)
-+++ src/dird/dird_conf.h (copie de travail)
-@@ -236,6 +236,7 @@
-
- /* Methods */
- char *name() const;
-+ char *display(POOLMEM *dst); /* Get catalog information */
- };
-
- inline char *CAT::name() const { return hdr.name; }
-Index: src/baconfig.h
-===================================================================
---- src/baconfig.h (révision 7525)
-+++ src/baconfig.h (copie de travail)
-@@ -79,7 +79,8 @@
-
- /* Allow printing of NULL pointers */
- #define NPRT(x) (x)?(x):_("*None*")
--
-+#define NPRTB(x) (x)?(x):""
-+
- #if defined(HAVE_WIN32)
-
- #define WIN32_REPARSE_POINT 1
-Index: src/tools/dbcheck.c
-===================================================================
---- src/tools/dbcheck.c (révision 7525)
-+++ src/tools/dbcheck.c (copie de travail)
-@@ -100,14 +100,14 @@
- static void do_interactive_mode();
- static bool yes_no(const char *prompt);
-
--
- static void usage()
- {
- fprintf(stderr,
--"Usage: dbcheck [-c config] [-C catalog name] [-d debug_level] <working-directory> <bacula-database> <user> <password> [<dbhost>] [<dbport>]\n"
-+"Usage: dbcheck [-c config ] [-B] [-C catalog name] [-d debug_level] <working-directory> <bacula-database> <user> <password> [<dbhost>] [<dbport>]\n"
- " -b batch mode\n"
- " -C catalog name in the director conf file\n"
- " -c Director conf filename\n"
-+" -B print catalog configuration and exit\n"
- " -d <nn> set debug level to <nn>\n"
- " -dt print timestamp in debug output\n"
- " -f fix inconsistencies\n"
-@@ -121,6 +121,7 @@
- int ch;
- const char *user, *password, *db_name, *dbhost;
- int dbport = 0;
-+ bool print_catalog=false;
- char *configfile = NULL;
- char *catalogname = NULL;
- char *endptr;
-@@ -136,8 +137,12 @@
- memset(&name_list, 0, sizeof(name_list));
-
-
-- while ((ch = getopt(argc, argv, "bc:C:d:fv?")) != -1) {
-+ while ((ch = getopt(argc, argv, "bc:C:d:fvB?")) != -1) {
- switch (ch) {
-+ case 'B':
-+ print_catalog = true; /* get catalog information from config */
-+ break;
-+
- case 'b': /* batch */
- batch = true;
- break;
-@@ -215,6 +220,16 @@
- exit(1);
- }
- set_working_directory(director->working_directory);
-+
-+ /* Print catalog information and exit (-B) */
-+ if (print_catalog) {
-+ POOLMEM *buf = get_pool_memory(PM_MESSAGE);
-+ printf("%sdb_type=%s\nworking_dir=%s\n", catalog->display(buf),
-+ db_get_type(), working_directory);
-+ free_pool_memory(buf);
-+ exit(0);
-+ }
-+
- db_name = catalog->db_name;
- user = catalog->db_user;
- password = catalog->db_password;
+++ /dev/null
-/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
-
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation, which is
- listed in the file LICENSE.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of John Walker.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-*/
-
-/*
-
-Device {
- Name = Drive-1 #
- Maximum File Size = 800M
- Maximum Volume Size = 3G
- Device Type = TAPE
- Archive Device = /tmp/fake
- Media Type = DLT-8000
- AutomaticMount = yes; # when device opened, read it
- AlwaysOpen = yes;
- RemovableMedia = yes;
- RandomAccess = no;
-}
-
- Block description :
-
- block {
- int32 size;
- void *data;
- }
-
- EOF description :
-
- EOF {
- int32 size=0;
- }
-
-
- */
-
-#include "bacula.h" /* define 64bit file usage */
-#include "stored.h"
-
-#ifdef USE_FAKETAPE
-#include "faketape.h"
-
-static int dbglevel = 10;
-#define FILE_OFFSET 30
-faketape *ftape_list[FTAPE_MAX_DRIVE];
-
-static faketape *get_tape(int fd)
-{
- ASSERT(fd >= 0);
-
- if (fd >= FTAPE_MAX_DRIVE) {
- /* error */
- return NULL;
- }
-
- return ftape_list[fd];
-}
-
-static bool put_tape(faketape *ftape)
-{
- ASSERT(ftape != NULL);
-
- int fd = ftape->get_fd();
- if (fd >= FTAPE_MAX_DRIVE) {
- /* error */
- return false;
- }
- ftape_list[fd] = ftape;
- return true;
-}
-
-void faketape_debug(int level)
-{
- dbglevel = level;
-}
-
-/****************************************************************/
-/* theses function will replace open/read/write/close/ioctl
- * in bacula core
- */
-int faketape_open(const char *pathname, int flags)
-{
- ASSERT(pathname != NULL);
-
- int fd;
- faketape *tape = new faketape();
- fd = tape->open(pathname, flags);
- if (fd > 0) {
- put_tape(tape);
- }
- return fd;
-}
-
-int faketape_read(int fd, void *buffer, unsigned int count)
-{
- faketape *tape = get_tape(fd);
- ASSERT(tape != NULL);
- return tape->read(buffer, count);
-}
-
-int faketape_write(int fd, const void *buffer, unsigned int count)
-{
- faketape *tape = get_tape(fd);
- ASSERT(tape != NULL);
- return tape->write(buffer, count);
-}
-
-int faketape_close(int fd)
-{
- faketape *tape = get_tape(fd);
- ASSERT(tape != NULL);
- tape->close();
- delete tape;
- return 0;
-}
-
-int faketape_ioctl(int fd, unsigned long int request, ...)
-{
- va_list argp;
- int result=0;
-
- faketape *t = get_tape(fd);
- if (!t) {
- errno = EBADF;
- return -1;
- }
-
- va_start(argp, request);
-
- if (request == MTIOCTOP) {
- result = t->tape_op(va_arg(argp, mtop *));
- } else if (request == MTIOCGET) {
- result = t->tape_get(va_arg(argp, mtget *));
- } else if (request == MTIOCPOS) {
- result = t->tape_pos(va_arg(argp, mtpos *));
- } else {
- errno = ENOTTY;
- result = -1;
- }
- va_end(argp);
-
- return result;
-}
-
-/****************************************************************/
-
-int faketape::tape_op(struct mtop *mt_com)
-{
- int result=0;
-
- if (!online) {
- errno = ENOMEDIUM;
- return -1;
- }
-
- switch (mt_com->mt_op)
- {
- case MTRESET:
- case MTNOP:
- case MTSETDRVBUFFER:
- break;
-
- default:
- case MTRAS1:
- case MTRAS2:
- case MTRAS3:
- case MTSETDENSITY:
- errno = ENOTTY;
- result = -1;
- break;
-
- case MTFSF: /* Forward space over mt_count filemarks. */
- result = fsf(mt_com->mt_count);
- break;
-
- case MTBSF: /* Backward space over mt_count filemarks. */
- result = bsf(mt_com->mt_count);
- break;
-
- case MTFSR: /* Forward space over mt_count records (tape blocks). */
-/*
- file number = 1
- block number = 0
-
- file number = 1
- block number = 1
-
- mt: /dev/lto2: Erreur d'entree/sortie
-
- file number = 2
- block number = 0
-*/
- /* tester si on se trouve a la fin du fichier */
- result = fsr(mt_com->mt_count);
- break;
-
- case MTBSR: /* Backward space over mt_count records (tape blocks). */
- result = bsr(mt_com->mt_count);
- break;
-
- case MTWEOF: /* Write mt_count filemarks. */
- result = weof(mt_com->mt_count);
- break;
-
- case MTREW: /* Rewind. */
- Dmsg0(dbglevel, "rewind faketape\n");
- atEOF = atEOD = false;
- atBOT = true;
- current_file = 0;
- current_block = 0;
- seek_file();
- break;
-
- case MTOFFL: /* put tape offline */
- result = offline();
- break;
-
- case MTRETEN: /* Re-tension tape. */
- result = 0;
- break;
-
- case MTBSFM: /* not used by bacula */
- errno = EIO;
- result = -1;
- break;
-
- case MTFSFM: /* not used by bacula */
- errno = EIO;
- result = -1;
- break;
-
- case MTEOM:/* Go to the end of the recorded media (for appending files). */
-/*
- file number = 3
- block number = -1
-*/
- /* Can be at EOM */
- atBOT = false;
- atEOF = false;
- atEOD = true;
- atEOT = false;
-
- current_file = last_file;
- current_block = -1;
- seek_file();
- break;
-
- case MTERASE: /* not used by bacula */
- atEOD = true;
- atEOF = false;
- atEOT = false;
-
- current_file = 0;
- current_block = -1;
- seek_file();
- truncate_file();
- break;
-
- case MTSETBLK:
- break;
-
- case MTSEEK:
- break;
-
- case MTTELL:
- break;
-
- case MTFSS:
- break;
-
- case MTBSS:
- break;
-
- case MTWSM:
- break;
-
- case MTLOCK:
- break;
-
- case MTUNLOCK:
- break;
-
- case MTLOAD:
- break;
-
- case MTUNLOAD:
- break;
-
- case MTCOMPRESSION:
- break;
-
- case MTSETPART:
- break;
-
- case MTMKPART:
- break;
- }
-
- return result == 0 ? 0 : -1;
-}
-
-int faketape::tape_get(struct mtget *mt_get)
-{
- int density = 1;
- int block_size = 1024;
-
- mt_get->mt_type = MT_ISSCSI2;
- mt_get->mt_blkno = current_block;
- mt_get->mt_fileno = current_file;
-
- mt_get->mt_resid = -1;
-// pos_info.PartitionBlockValid ? pos_info.Partition : (ULONG)-1;
-
- /* TODO */
- mt_get->mt_dsreg =
- ((density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK) |
- ((block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK);
-
-
- mt_get->mt_gstat = 0x00010000; /* Immediate report mode.*/
-
- if (atEOF) {
- mt_get->mt_gstat |= 0x80000000; // GMT_EOF
- }
-
- if (atBOT) {
- mt_get->mt_gstat |= 0x40000000; // GMT_BOT
- }
- if (atEOT) {
- mt_get->mt_gstat |= 0x20000000; // GMT_EOT
- }
-
- if (atEOD) {
- mt_get->mt_gstat |= 0x08000000; // GMT_EOD
- }
-
- if (0) { //WriteProtected) {
- mt_get->mt_gstat |= 0x04000000; // GMT_WR_PROT
- }
-
- if (online) {
- mt_get->mt_gstat |= 0x01000000; // GMT_ONLINE
- } else {
- mt_get->mt_gstat |= 0x00040000; // GMT_DR_OPEN
- }
- mt_get->mt_erreg = 0;
-
- return 0;
-}
-
-int faketape::tape_pos(struct mtpos *mt_pos)
-{
- if (current_block >= 0) {
- mt_pos->mt_blkno = current_block;
- return 0;
- }
-
- return -1;
-}
-
-/*
- * This function try to emulate the append only behavior
- * of a tape. When you wrote something, data after the
- * current position are discarded.
- */
-int faketape::truncate_file()
-{
- Dmsg2(dbglevel, "truncate %i:%i\n", current_file, current_block);
- ftruncate(fd, lseek(fd, 0, SEEK_CUR));
- last_file = current_file;
- atEOD=true;
- return 0;
-}
-
-faketape::faketape()
-{
- fd = -1;
-
- atEOF = false;
- atBOT = false;
- atEOT = false;
- atEOD = false;
- online = false;
- inplace = false;
- needEOF = false;
-
- file_size = 0;
- last_file = 0;
- current_file = 0;
- current_block = -1;
- current_pos = 0;
-
- max_block = 1024*1024*1024*1024*8;
-
-}
-
-faketape::~faketape()
-{
-}
-
-int faketape::get_fd()
-{
- return this->fd;
-}
-
-/*
- * TODO: check if after a write op, and other tape op put a EOF
- */
-int faketape::write(const void *buffer, unsigned int count)
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- ASSERT(count > 0);
- ASSERT(buffer);
-
- unsigned int nb;
- Dmsg3(dbglevel, "write len=%i %i:%i\n", count, current_file,current_block);
-
- if (atEOT) {
- Dmsg0(dbglevel, "write nothing, EOT !\n");
- errno = ENOSPC;
- return -1;
- }
-
- if (!inplace) {
- seek_file();
- }
-
- if (!atEOD) { /* if not at the end of the data */
- truncate_file();
- }
-
- if (current_block != -1) {
- current_block++;
- }
-
- atBOT = false;
- atEOF = false;
- atEOD = true; /* End of data */
-
- needEOF = true; /* next operation need EOF mark */
-
-// if ((count + file_size) > max_size) {
-// Dmsg2(dbglevel,
-// "EOT writing only %i of %i requested\n",
-// max_size - file_size, count);
-// count = max_size - file_size;
-// atEOT = true;
-// }
-
- uint32_t size = count;
- ::write(fd, &size, sizeof(uint32_t));
- nb = ::write(fd, buffer, count);
-
- file_size += sizeof(uint32_t) + nb;
-
- if (nb != count) {
- atEOT = true;
- Dmsg2(dbglevel,
- "Not enough space writing only %i of %i requested\n",
- nb, count);
- }
-
- return nb;
-}
-
-int faketape::weof(int count)
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- Dmsg3(dbglevel, "Writing EOF %i:%i last=%i\n",
- current_file, current_block,last_file);
- if (atEOT) {
- errno = ENOSPC;
- current_block = -1;
- return -1;
- }
- needEOF = false;
- truncate_file(); /* nothing after this point */
-
- /* TODO: check this */
- current_file += count;
- current_block = 0;
-
- uint32_t c=0;
- seek_file();
- ::write(fd, &c, sizeof(uint32_t));
- seek_file();
-
- atEOD = false;
- atBOT = false;
- atEOF = true;
-
- return 0;
-}
-
-int faketape::fsf(int count)
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- ASSERT(fd >= 0);
-/*
- * 1 0 -> fsf -> 2 0 -> fsf -> 2 -1
- */
- check_eof();
-
- int ret;
- if (atEOT) {
- current_block = -1;
- return -1;
- }
-
- atBOT = atEOF = false;
- Dmsg3(dbglevel+1, "fsf %i+%i <= %i\n", current_file, count, last_file);
-
- if ((current_file + count) <= last_file) {
- current_file += count;
- current_block = 0;
- ret = 0;
- } else {
- Dmsg0(dbglevel, "Try to FSF after EOT\n");
- current_file = last_file ;
- current_block = -1;
- atEOD=true;
- ret = -1;
- }
- seek_file();
- return ret;
-}
-
-int faketape::fsr(int count)
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- ASSERT(fd >= 0);
-
- int i,nb, ret=0;
- off_t where=0;
- uint32_t s;
- Dmsg3(dbglevel, "fsr %i:%i count=%i\n", current_file,current_block, count);
-
- check_eof();
-
- if (atEOT) {
- errno = EIO;
- current_block = -1;
- return -1;
- }
-
- if (atEOD) {
- errno = EIO;
- return -1;
- }
-
- atBOT = atEOF = false;
-
- /* check all block record */
- for(i=0; (i < count) && !atEOF ; i++) {
- nb = ::read(fd, &s, sizeof(uint32_t)); /* get size of next block */
- if (nb == sizeof(uint32_t) && s) {
- current_block++;
- where = lseek(fd, s, SEEK_CUR); /* seek after this block */
- } else {
- Dmsg4(dbglevel, "read EOF %i:%i nb=%i s=%i\n",
- current_file, current_block, nb,s);
- errno = EIO;
- ret = -1;
- if (current_file < last_file) {
- current_block = 0;
- current_file++;
- seek_file();
- }
- atEOF = true; /* stop the loop */
- }
- }
-
- find_maxfile(); /* refresh stats */
-
- if (where == file_size) {
- atEOD = true;
- }
- return ret;
-}
-
-int faketape::bsr(int count)
-{
- Dmsg2(dbglevel, "bsr current_block=%i count=%i\n",
- current_block, count);
-
- ASSERT(online);
- ASSERT(current_file >= 0);
- ASSERT(count == 1);
- ASSERT(fd >= 0);
-
- check_eof();
-
- if (!count) {
- return 0;
- }
-
- int ret=0;
- int last_f=0;
- int last_b=0;
-
- off_t last=-1, last2=-1;
- off_t orig = lseek(fd, 0, SEEK_CUR);
- int orig_f = current_file;
- int orig_b = current_block;
-
- current_block=0;
- seek_file();
-
- do {
- if (!atEOF) {
- last2 = last;
- last = lseek(fd, 0, SEEK_CUR);
- last_f = current_file;
- last_b = current_block;
- Dmsg5(dbglevel, "EOF=%i last=%lli orig=%lli %i:%i\n",
- atEOF, last, orig, current_file, current_block);
- }
- ret = fsr(1);
- } while ((lseek(fd, 0, SEEK_CUR) < orig) && (ret == 0));
-
- if (last2 > 0 && atEOF) { /* we take the previous position */
- lseek(fd, last2, SEEK_SET);
- current_file = last_f;
- current_block = last_b - 1;
- Dmsg3(dbglevel, "set offset2=%lli %i:%i\n",
- last, current_file, current_block);
-
- } else if (last > 0) {
- lseek(fd, last, SEEK_SET);
- current_file = last_f;
- current_block = last_b;
- Dmsg3(dbglevel, "set offset=%lli %i:%i\n",
- last, current_file, current_block);
- } else {
- lseek(fd, orig, SEEK_SET);
- current_file = orig_f;
- current_block = orig_b;
- return -1;
- }
-
- Dmsg2(dbglevel, "bsr %i:%i\n", current_file, current_block);
- atEOT = atEOF = atEOD = false;
-
- return 0;
-}
-
-int faketape::bsf(int count)
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- Dmsg3(dbglevel, "bsf %i:%i count=%i\n", current_file, current_block, count);
- int ret = 0;
-
- check_eof();
- atBOT = atEOF = atEOT = atEOD = false;
-
- if (current_file - count < 0) {
- current_file = 0;
- current_block = 0;
- atBOT = true;
- errno = EIO;
- ret = -1;
- } else {
- current_file = current_file - count + 1;
- current_block = -1;
- seek_file();
- current_file--;
- /* go just before last EOF */
- lseek(fd, lseek(fd, 0, SEEK_CUR) - sizeof(uint32_t), SEEK_SET);
- }
- return ret;
-}
-
-/*
- * Put faketape in offline mode
- */
-int faketape::offline()
-{
- close();
-
- atEOF = false; /* End of file */
- atEOT = false; /* End of tape */
- atEOD = false; /* End of data */
- atBOT = false; /* Begin of tape */
- online = false;
-
- current_file = -1;
- current_block = -1;
- last_file = -1;
- return 0;
-}
-
-int faketape::close()
-{
- check_eof();
- ::close(fd);
- fd = -1;
- return 0;
-}
-/*
- **rb
- **status
- * EOF Bacula status: file=2 block=0
- * Device status: EOF ONLINE IM_REP_EN file=2 block=0
- **rb
- **status
- * EOD EOF Bacula status: file=2 block=0
- * Device status: EOD ONLINE IM_REP_EN file=2 block=-1
- *
- */
-
-int faketape::read(void *buffer, unsigned int count)
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- unsigned int nb;
- uint32_t s;
-
- Dmsg2(dbglevel, "read %i:%i\n", current_file, current_block);
-
- if (atEOT || atEOD) {
- return 0;
- }
-
- if (atEOF) {
- current_file++;
- current_block=0;
- inplace = false;
- atEOF = false;
- }
-
- if (!inplace) {
- seek_file();
- }
-
- atEOD = atBOT = false;
- current_block++;
-
- nb = ::read(fd, &s, sizeof(uint32_t));
- if (nb <= 0) {
- atEOF = true;
- return 0;
- }
- if (s > count) { /* not enough buffer to read block */
- Dmsg2(dbglevel, "Need more buffer to read next block %i > %i\n",s,count);
- lseek(fd, s, SEEK_CUR);
- errno = ENOMEM;
- return -1;
- }
- if (!s) { /* EOF */
- atEOF = true;
- lseek(fd, lseek(fd, 0, SEEK_CUR) - sizeof(uint32_t), SEEK_SET);
- return 0;
- }
- nb = ::read(fd, buffer, s);
- if (s != nb) {
- atEOF = true;
- if (current_file == last_file) {
- atEOD = true;
- current_block = -1;
- }
- Dmsg0(dbglevel, "EOF during reading\n");
- }
- return nb;
-}
-
-int faketape::open(const char *pathname, int uflags)
-{
- Dmsg2(dbglevel, "faketape::open(%s, %i)\n", pathname, uflags);
-
- online = true; /* assume that drive contains a tape */
-
- struct stat statp;
- if (stat(pathname, &statp) != 0) {
- Dmsg1(dbglevel, "Can't stat on %s\n", pathname);
- if (uflags & O_NONBLOCK) {
- online = false;
- fd = ::open("/dev/null", O_CREAT | O_RDWR | O_LARGEFILE, 0600);
- }
- } else {
- fd = ::open(pathname, O_CREAT | O_RDWR | O_LARGEFILE, 0600);
- }
-
- if (fd < 0) {
- errno = ENOMEDIUM;
- return -1;
- }
-
- /* open volume descriptor and get this->fd */
- find_maxfile();
-
- current_block = 0;
- current_file = 0;
- needEOF = false;
- inplace = true;
- atBOT = true;
- atEOT = atEOD = false;
-
- return fd;
-}
-
-/*
- * read volume to get the last file number
- */
-int faketape::find_maxfile()
-{
- struct stat statp;
- if (fstat(fd, &statp) != 0) {
- return 0;
- }
- last_file = statp.st_size>>FILE_OFFSET;
- file_size = statp.st_size;
-
- current_pos = lseek(fd, 0, SEEK_CUR); /* get current position */
- Dmsg3(dbglevel+1, "last_file=%i file_size=%u current_pos=%i\n",
- last_file, file_size, current_pos);
-
- return last_file;
-}
-
-int faketape::seek_file()
-{
- ASSERT(online);
- ASSERT(current_file >= 0);
- Dmsg2(dbglevel, "seek_file %i:%i\n", current_file, current_block);
-
- off_t pos = ((off_t)current_file)<<FILE_OFFSET;
- if(lseek(fd, pos, SEEK_SET) == -1) {
- return -1;
- }
- last_file = (last_file > current_file)?last_file:current_file;
- if (current_block > 0) {
- fsr(current_block);
- }
- inplace = true;
-
- return 0;
-}
-
-void faketape::dump()
-{
- Dmsg0(dbglevel+1, "===================\n");
- Dmsg2(dbglevel, "file:block = %i:%i\n", current_file, current_block);
- Dmsg1(dbglevel+1, "last_file=%i\n", last_file);
- Dmsg1(dbglevel+1, "file_size=%i\n", file_size);
- Dmsg4(dbglevel+1, "EOF=%i EOT=%i EOD=%i BOT=%i\n",
- atEOF, atEOT, atEOD, atBOT);
-}
-
-#endif /* USE_FAKETAPE */
+++ /dev/null
-/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
-
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation, which is
- listed in the file LICENSE.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of John Walker.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-*/
-/*
- * faketape.h - Emulate the Linux st (scsi tape) driver on file.
- * for regression and bug hunting purpose
- *
- */
-
-#ifndef FAKETAPE_H
-#define FAKETAPE_H
-
-#include <stdarg.h>
-#include <stddef.h>
-#include "bacula.h"
-
-#ifdef USE_FAKETAPE
-
-#define FTAPE_MAX_DRIVE 50
-
-/*
- * Theses functions will replace open/read/write
- */
-int faketape_open(const char *pathname, int flags);
-int faketape_read(int fd, void *buffer, unsigned int count);
-int faketape_write(int fd, const void *buffer, unsigned int count);
-int faketape_close(int fd);
-int faketape_ioctl(int fd, unsigned long int request, ...);
-void faketape_debug(int level);
-
-class faketape {
-private:
- int fd; /* Our file descriptor */
-
- off_t file_size; /* size */
- off_t max_block;
-
- bool atEOF; /* End of file */
- bool atEOT; /* End of media */
- bool atEOD; /* End of data */
- bool atBOT; /* Begin of tape */
- bool online; /* volume online */
- bool inplace; /* have to seek before writing ? */
- bool needEOF; /* check if last operation need eof */
-
- int32_t last_file; /* last file of the volume */
- int32_t current_file; /* max 65000 files */
- int32_t current_block; /* max 4G blocks of 1KB */
- off_t current_pos; /* current position in stream */
-
- void destroy();
- int find_maxfile();
- int offline();
- int truncate_file();
- int seek_file();
- void check_eof() { if(needEOF) weof(1);};
-
-public:
- int fsf(int count);
- int fsr(int count);
- int weof(int count);
- int bsf(int count);
- int bsr(int count);
-
- faketape();
- ~faketape();
-
- int get_fd();
- void dump();
- int open(const char *pathname, int flags);
- int read(void *buffer, unsigned int count);
- int write(const void *buffer, unsigned int count);
- int close();
-
- int tape_op(struct mtop *mt_com);
- int tape_get(struct mtget *mt_com);
- int tape_pos(struct mtpos *mt_com);
-};
-
-#endif /* USE_FAKETAPE */
-#endif /* !FAKETAPE_H */
+++ /dev/null
-Index: src/baconfig.h
-===================================================================
---- src/baconfig.h (révision 7044)
-+++ src/baconfig.h (copie de travail)
-@@ -91,7 +91,6 @@
- #define tape_read win32_tape_read
- #define tape_write win32_tape_write
- #define tape_close win32_tape_close
--#define IS_TAPE(x) S_ISCHR(x)
-
- #define sbrk(x) 0
-
-@@ -117,21 +116,11 @@
-
- #define OSDependentInit()
-
--#if defined(USE_FAKETAPE)
--# define tape_open faketape_open
--# define tape_ioctl faketape_ioctl
--# define tape_read faketape_read
--# define tape_write faketape_write
--# define tape_close faketape_close
--# define IS_TAPE(x) S_ISREG(x)
--#else /* UNIX && !FAKETAPE */
--# define tape_open ::open
--# define tape_ioctl ::ioctl
--# define tape_read ::read
--# define tape_write ::write
--# define tape_close ::close
--# define IS_TAPE(x) S_ISCHR(x)
--#endif
-+#define tape_open ::open
-+#define tape_ioctl ::ioctl
-+#define tape_read ::read
-+#define tape_write ::write
-+#define tape_close ::close
-
- #endif /* HAVE_WIN32 */
-
-Index: src/stored/stored_conf.c
-===================================================================
---- src/stored/stored_conf.c (révision 7044)
-+++ src/stored/stored_conf.c (copie de travail)
-@@ -213,6 +213,7 @@
- {"dvd", B_DVD_DEV},
- {"fifo", B_FIFO_DEV},
- {"vtl", B_VTL_DEV},
-+ {"faketape", B_FAKETAPE_DEV},
- {NULL, 0}
- };
-
-Index: src/stored/dev.c
-===================================================================
---- src/stored/dev.c (révision 7044)
-+++ src/stored/dev.c (copie de travail)
-@@ -123,10 +123,17 @@
- }
- if (S_ISDIR(statp.st_mode)) {
- device->dev_type = B_FILE_DEV;
-- } else if (IS_TAPE(statp.st_mode)) { /* char device or fake tape */
-+ } else if (S_ISCHR(statp.st_mode)) {
- device->dev_type = B_TAPE_DEV;
- } else if (S_ISFIFO(statp.st_mode)) {
- device->dev_type = B_FIFO_DEV;
-+#ifdef USE_FAKETAPE
-+ /* must set DeviceType = Faketape
-+ * in normal mode, autodetection is disabled
-+ */
-+ } else if (S_ISREG(statp.st_mode)) {
-+ device->dev_type = B_FAKETAPE_DEV;
-+#endif
- } else if (!(device->cap_bits & CAP_REQMOUNT)) {
- Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory\n"
- " or have RequiresMount=yes for DVD. st_mode=%x\n"),
-@@ -162,6 +169,7 @@
- dev->drive_index = device->drive_index;
- dev->autoselect = device->autoselect;
- dev->dev_type = device->dev_type;
-+ dev->init_backend();
- if (dev->is_tape()) { /* No parts on tapes */
- dev->max_part_size = 0;
- } else {
-@@ -264,6 +272,38 @@
- return dev;
- }
-
-+void DEVICE::init_backend()
-+{
-+
-+#ifdef USE_FAKETAPE
-+ /* in this mode, force FAKETAPE driver */
-+ dev_type = (dev_type == B_TAPE_DEV)?B_FAKETAPE_DEV:dev_type;
-+#endif
-+
-+ if (is_faketape()) {
-+ d_open = faketape_open;
-+ d_write = faketape_write;
-+ d_close = faketape_close;
-+ d_ioctl = faketape_ioctl;
-+ d_read = faketape_read;
-+ dev_type = B_TAPE_DEV; /* do exactly as real tape */
-+
-+ } else if (is_tape()) {
-+ d_open = tape_open;
-+ d_write = tape_write;
-+ d_close = tape_close;
-+ d_ioctl = tape_ioctl;
-+ d_read = tape_read;
-+
-+ } else {
-+ d_open = ::open;
-+ d_write = ::write;
-+ d_close = ::close;
-+ d_ioctl = ::ioctl;
-+ d_read = ::read;
-+ }
-+}
-+
- /*
- * Open the device with the operating system and
- * initialize buffer pointers.
-@@ -285,11 +325,7 @@
- if (openmode == omode) {
- return m_fd;
- } else {
-- if (is_tape()) {
-- tape_close(m_fd);
-- } else {
-- ::close(m_fd);
-- }
-+ d_close(m_fd);
- clear_opened();
- Dmsg0(100, "Close fd for mode change.\n");
- preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
-@@ -369,7 +405,7 @@
- #if defined(HAVE_WIN32)
-
- /* Windows Code */
-- if ((m_fd = tape_open(dev_name, mode)) < 0) {
-+ if ((m_fd = d_open(dev_name, mode)) < 0) {
- dev_errno = errno;
- }
-
-@@ -379,7 +415,7 @@
- /* If busy retry each second for max_open_wait seconds */
- for ( ;; ) {
- /* Try non-blocking open */
-- m_fd = tape_open(dev_name, mode+O_NONBLOCK);
-+ m_fd = d_open(dev_name, mode+O_NONBLOCK);
- if (m_fd < 0) {
- berrno be;
- dev_errno = errno;
-@@ -391,10 +427,10 @@
- mt_com.mt_op = MTREW;
- mt_com.mt_count = 1;
- /* rewind only if dev is a tape */
-- if (is_tape() && (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
-+ if (is_tape() && (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
- berrno be;
- dev_errno = errno; /* set error status from rewind */
-- tape_close(m_fd);
-+ d_close(m_fd);
- clear_opened();
- Dmsg2(100, "Rewind error on %s close: ERR=%s\n", print_name(),
- be.bstrerror(dev_errno));
-@@ -404,8 +440,8 @@
- }
- } else {
- /* Got fd and rewind worked, so we must have medium in drive */
-- tape_close(m_fd);
-- m_fd = tape_open(dev_name, mode); /* open normally */
-+ d_close(m_fd);
-+ m_fd = d_open(dev_name, mode); /* open normally */
- if (m_fd < 0) {
- berrno be;
- dev_errno = errno;
-@@ -689,7 +725,7 @@
- be.bstrerror());
- Dmsg1(100, "open failed: %s", errmsg);
- /* Use system close() */
-- ::close(m_fd);
-+ d_close(m_fd);
- clear_opened();
- } else {
- part_size = filestat.st_size;
-@@ -733,7 +769,7 @@
- * retrying every 5 seconds.
- */
- for (i=max_rewind_wait; ; i -= 5) {
-- if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- clrerror(MTREW);
- if (i == max_rewind_wait) {
-@@ -747,7 +783,7 @@
- */
- if (first && dcr) {
- int open_mode = openmode;
-- tape_close(m_fd);
-+ d_close(m_fd);
- clear_opened();
- open(dcr, open_mode);
- if (m_fd < 0) {
-@@ -887,7 +923,7 @@
- mt_com.mt_count = 1;
- }
-
-- if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- clrerror(mt_com.mt_op);
- Dmsg1(50, "ioctl error: %s\n", be.bstrerror());
-@@ -1031,7 +1067,7 @@
- stat |= BMT_TAPE;
- Pmsg0(-20,_(" Bacula status:"));
- Pmsg2(-20,_(" file=%d block=%d\n"), dev->file, dev->block_num);
-- if (tape_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
- berrno be;
- dev->dev_errno = errno;
- Mmsg2(dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
-@@ -1158,7 +1194,7 @@
- dev->file_addr = 0;
- mt_com.mt_op = MTLOAD;
- mt_com.mt_count = 1;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- dev->dev_errno = errno;
- Mmsg2(dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
-@@ -1189,7 +1225,7 @@
- unlock_door();
- mt_com.mt_op = MTOFFL;
- mt_com.mt_count = 1;
-- if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"),
-@@ -1264,7 +1300,7 @@
- int my_errno = 0;
- mt_com.mt_op = MTFSF;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) {
- my_errno = errno; /* save errno */
- } else if ((os_file=get_os_tape_file()) < 0) {
-@@ -1345,7 +1381,7 @@
- }
-
- Dmsg0(100, "Doing MTFSF\n");
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) { /* error => EOT */
- berrno be;
- set_eot();
-@@ -1419,7 +1455,7 @@
- file_size = 0;
- mt_com.mt_op = MTBSF;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) {
- berrno be;
- clrerror(MTBSF);
-@@ -1459,7 +1495,7 @@
- Dmsg1(100, "fsr %d\n", num);
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat == 0) {
- clear_eof();
- block_num += num;
-@@ -1518,7 +1554,7 @@
- clear_eot();
- mt_com.mt_op = MTBSR;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) {
- berrno be;
- clrerror(MTBSR);
-@@ -1534,7 +1570,7 @@
- struct mtop mt_com;
- mt_com.mt_op = MTLOCK;
- mt_com.mt_count = 1;
-- tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- #endif
- }
-
-@@ -1544,7 +1580,7 @@
- struct mtop mt_com;
- mt_com.mt_op = MTUNLOCK;
- mt_com.mt_count = 1;
-- tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- #endif
- }
-
-@@ -1656,7 +1692,7 @@
- clear_eot();
- mt_com.mt_op = MTWEOF;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat == 0) {
- block_num = 0;
- file += num;
-@@ -1787,7 +1823,7 @@
- /* Found on Solaris */
- #ifdef MTIOCLRERR
- {
-- tape_ioctl(m_fd, MTIOCLRERR);
-+ d_ioctl(m_fd, MTIOCLRERR);
- Dmsg0(200, "Did MTIOCLRERR\n");
- }
- #endif
-@@ -1800,7 +1836,7 @@
- union mterrstat mt_errstat;
- Dmsg2(200, "Doing MTIOCERRSTAT errno=%d ERR=%s\n", dev_errno,
- be.bstrerror(dev_errno));
-- tape_ioctl(m_fd, MTIOCERRSTAT, (char *)&mt_errstat);
-+ d_ioctl(m_fd, MTIOCERRSTAT, (char *)&mt_errstat);
- }
- #endif
-
-@@ -1811,7 +1847,7 @@
- mt_com.mt_op = MTCSE;
- mt_com.mt_count = 1;
- /* Clear any error condition on the tape */
-- tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- Dmsg0(200, "Did MTCSE\n");
- }
- #endif
-@@ -1848,10 +1884,8 @@
- case B_VTL_DEV:
- case B_TAPE_DEV:
- unlock_door();
-- tape_close(m_fd);
-- break;
- default:
-- ::close(m_fd);
-+ d_close(m_fd);
- }
-
- /* Clean up device packet so it can be reused */
-@@ -2251,11 +2285,7 @@
-
- get_timer_count();
-
-- if (this->is_tape()) {
-- read_len = tape_read(m_fd, buf, len);
-- } else {
-- read_len = ::read(m_fd, buf, len);
-- }
-+ read_len = d_read(m_fd, buf, len);
-
- last_tick = get_timer_count();
-
-@@ -2276,11 +2306,7 @@
-
- get_timer_count();
-
-- if (this->is_tape()) {
-- write_len = tape_write(m_fd, buf, len);
-- } else {
-- write_len = ::write(m_fd, buf, len);
-- }
-+ write_len = d_write(m_fd, buf, len);
-
- last_tick = get_timer_count();
-
-@@ -2306,7 +2332,7 @@
- struct mtget mt_stat;
-
- if (has_cap(CAP_MTIOCGET) &&
-- tape_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) {
-+ d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) {
- return mt_stat.mt_fileno;
- }
- return -1;
-@@ -2431,7 +2457,7 @@
- mt_com.mt_op = MTSETBLK;
- mt_com.mt_count = 0;
- Dmsg0(100, "Set block size to zero\n");
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETBLK);
- }
- }
-@@ -2447,7 +2473,7 @@
- mt_com.mt_count |= MT_ST_FAST_MTEOM;
- }
- Dmsg0(100, "MTSETDRVBUFFER\n");
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETDRVBUFFER);
- }
- }
-@@ -2461,13 +2487,13 @@
- dev->min_block_size == 0) { /* variable block mode */
- mt_com.mt_op = MTSETBSIZ;
- mt_com.mt_count = 0;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETBSIZ);
- }
- /* Get notified at logical end of tape */
- mt_com.mt_op = MTEWARN;
- mt_com.mt_count = 1;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTEWARN);
- }
- }
-@@ -2480,7 +2506,7 @@
- dev->min_block_size == 0) { /* variable block mode */
- mt_com.mt_op = MTSETBSIZ;
- mt_com.mt_count = 0;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETBSIZ);
- }
- }
-@@ -2491,7 +2517,7 @@
- } else {
- neof = 1;
- }
-- if (tape_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
- berrno be;
- dev->dev_errno = errno; /* save errno */
- Mmsg2(dev->errmsg, _("Unable to set eotmodel on device %s: ERR=%s\n"),
-@@ -2508,7 +2534,7 @@
- dev->min_block_size == 0) { /* variable block mode */
- mt_com.mt_op = MTSRSZ;
- mt_com.mt_count = 0;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSRSZ);
- }
- }
-@@ -2520,7 +2546,7 @@
- {
- Dmsg0(100, "dev_get_os_pos\n");
- return dev->has_cap(CAP_MTIOCGET) &&
-- tape_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 &&
-+ dev->d_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 &&
- mt_stat->mt_fileno >= 0;
- }
-
-Index: src/stored/faketape.c
-===================================================================
---- src/stored/faketape.c (révision 7044)
-+++ src/stored/faketape.c (copie de travail)
-@@ -101,7 +101,7 @@
- /* theses function will replace open/read/write/close/ioctl
- * in bacula core
- */
--int faketape_open(const char *pathname, int flags)
-+int faketape_open(const char *pathname, int flags, ...)
- {
- ASSERT(pathname != NULL);
-
-Index: src/stored/dev.h
-===================================================================
---- src/stored/dev.h (révision 7044)
-+++ src/stored/dev.h (copie de travail)
-@@ -95,7 +95,8 @@
- B_TAPE_DEV,
- B_DVD_DEV,
- B_FIFO_DEV,
-- B_VTL_DEV
-+ B_FAKETAPE_DEV, /* change to B_TAPE_DEV after init */
-+ B_VTL_DEV
- };
-
- /* Generic status bits returned from status_dev() */
-@@ -312,6 +313,7 @@
- int is_fifo() const { return dev_type == B_FIFO_DEV; }
- int is_dvd() const { return dev_type == B_DVD_DEV; }
- int is_vtl() const { return dev_type == B_VTL_DEV; }
-+ int is_faketape() const { return dev_type == B_FAKETAPE_DEV; }
- int is_open() const { return m_fd >= 0; }
- int is_offline() const { return state & ST_OFFLINE; }
- int is_labeled() const { return state & ST_LABEL; }
-@@ -421,6 +423,14 @@
- uint32_t get_block_num() const { return block_num; };
- int fd() const { return m_fd; };
-
-+ /* low level operations */
-+ void init_backend();
-+ int (*d_open)(const char *pathname, int flags, ...);
-+ int (*d_read)(int fd, void *buffer, unsigned int count);
-+ int (*d_write)(int fd, const void *buffer, unsigned int count);
-+ int (*d_close)(int fd);
-+ int (*d_ioctl)(int fd, unsigned long int request, ...);
-+
- /*
- * Locking and blocking calls
- */
-Index: src/stored/faketape.h
-===================================================================
---- src/stored/faketape.h (révision 7044)
-+++ src/stored/faketape.h (copie de travail)
-@@ -45,7 +45,7 @@
- /*
- * Theses functions will replace open/read/write
- */
--int faketape_open(const char *pathname, int flags);
-+int faketape_open(const char *pathname, int flags, ...);
- int faketape_read(int fd, void *buffer, unsigned int count);
- int faketape_write(int fd, const void *buffer, unsigned int count);
- int faketape_close(int fd);
+++ /dev/null
-Index: src/baconfig.h
-===================================================================
---- src/baconfig.h (revision 7116)
-+++ src/baconfig.h (working copy)
-@@ -86,12 +86,6 @@
- void InitWinAPIWrapper();
-
- #define OSDependentInit() InitWinAPIWrapper()
--#define tape_open win32_tape_open
--#define tape_ioctl win32_tape_ioctl
--#define tape_read win32_tape_read
--#define tape_write win32_tape_write
--#define tape_close win32_tape_close
--#define IS_TAPE(x) S_ISCHR(x)
-
- #define sbrk(x) 0
-
-@@ -117,22 +111,6 @@
-
- #define OSDependentInit()
-
--#if defined(USE_FAKETAPE)
--# define tape_open faketape_open
--# define tape_ioctl faketape_ioctl
--# define tape_read faketape_read
--# define tape_write faketape_write
--# define tape_close faketape_close
--# define IS_TAPE(x) S_ISREG(x)
--#else /* UNIX && !FAKETAPE */
--# define tape_open ::open
--# define tape_ioctl ::ioctl
--# define tape_read ::read
--# define tape_write ::write
--# define tape_close ::close
--# define IS_TAPE(x) S_ISCHR(x)
--#endif
--
- #endif /* HAVE_WIN32 */
-
-
-Index: src/stored/stored.h
-===================================================================
---- src/stored/stored.h (revision 7116)
-+++ src/stored/stored.h (working copy)
-@@ -78,10 +78,9 @@
- int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
- #endif
-
--#ifdef USE_FAKETAPE
--# include "faketape.h"
--#endif
-+#include "faketape.h"
-
-+
- /* Daemon globals from stored.c */
- extern STORES *me; /* "Global" daemon resource */
- extern bool forge_on; /* proceed inspite of I/O errors */
-Index: src/stored/stored_conf.c
-===================================================================
---- src/stored/stored_conf.c (revision 7116)
-+++ src/stored/stored_conf.c (working copy)
-@@ -213,6 +213,7 @@
- {"dvd", B_DVD_DEV},
- {"fifo", B_FIFO_DEV},
- {"vtl", B_VTL_DEV},
-+ {"faketape", B_FAKETAPE_DEV},
- {NULL, 0}
- };
-
-Index: src/stored/btape.c
-===================================================================
---- src/stored/btape.c (revision 7116)
-+++ src/stored/btape.c (working copy)
-@@ -2504,11 +2504,7 @@
- Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
- for ( ;; ) {
- *p = block_num;
-- if (dev->is_tape()) {
-- stat = tape_write(dev->fd(), block->buf, block->buf_len);
-- } else {
-- stat = write(dev->fd(), block->buf, block->buf_len);
-- }
-+ stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
- if (stat == (int)block->buf_len) {
- if ((block_num++ % 100) == 0) {
- printf("+");
-Index: src/stored/dev.c
-===================================================================
---- src/stored/dev.c (revision 7116)
-+++ src/stored/dev.c (working copy)
-@@ -123,10 +123,17 @@
- }
- if (S_ISDIR(statp.st_mode)) {
- device->dev_type = B_FILE_DEV;
-- } else if (IS_TAPE(statp.st_mode)) { /* char device or fake tape */
-+ } else if (S_ISCHR(statp.st_mode)) {
- device->dev_type = B_TAPE_DEV;
- } else if (S_ISFIFO(statp.st_mode)) {
- device->dev_type = B_FIFO_DEV;
-+#ifdef USE_FAKETAPE
-+ /* must set DeviceType = Faketape
-+ * in normal mode, autodetection is disabled
-+ */
-+ } else if (S_ISREG(statp.st_mode)) {
-+ device->dev_type = B_FAKETAPE_DEV;
-+#endif
- } else if (!(device->cap_bits & CAP_REQMOUNT)) {
- Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory\n"
- " or have RequiresMount=yes for DVD. st_mode=%x\n"),
-@@ -162,6 +169,7 @@
- dev->drive_index = device->drive_index;
- dev->autoselect = device->autoselect;
- dev->dev_type = device->dev_type;
-+ dev->init_backend();
- if (dev->is_tape()) { /* No parts on tapes */
- dev->max_part_size = 0;
- } else {
-@@ -264,6 +272,34 @@
- return dev;
- }
-
-+/* Choose the right backend */
-+void DEVICE::init_backend()
-+{
-+ if (is_faketape()) {
-+ d_open = faketape_open;
-+ d_write = faketape_write;
-+ d_close = faketape_close;
-+ d_ioctl = faketape_ioctl;
-+ d_read = faketape_read;
-+
-+#ifdef HAVE_WIN32
-+ } else if (is_tape()) {
-+ d_open = win32_tape_open;
-+ d_write = win32_tape_write;
-+ d_close = win32_tape_close;
-+ d_ioctl = win32_tape_ioctl;
-+ d_read = win32_tape_read;
-+#endif
-+
-+ } else {
-+ d_open = ::open;
-+ d_write = ::write;
-+ d_close = ::close;
-+ d_ioctl = ::ioctl;
-+ d_read = ::read;
-+ }
-+}
-+
- /*
- * Open the device with the operating system and
- * initialize buffer pointers.
-@@ -285,11 +321,7 @@
- if (openmode == omode) {
- return m_fd;
- } else {
-- if (is_tape()) {
-- tape_close(m_fd);
-- } else {
-- ::close(m_fd);
-- }
-+ d_close(m_fd);
- clear_opened();
- Dmsg0(100, "Close fd for mode change.\n");
- preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
-@@ -368,7 +400,7 @@
- #if defined(HAVE_WIN32)
-
- /* Windows Code */
-- if ((m_fd = tape_open(dev_name, mode)) < 0) {
-+ if ((m_fd = d_open(dev_name, mode)) < 0) {
- dev_errno = errno;
- }
-
-@@ -378,7 +410,7 @@
- /* If busy retry each second for max_open_wait seconds */
- for ( ;; ) {
- /* Try non-blocking open */
-- m_fd = tape_open(dev_name, mode+O_NONBLOCK);
-+ m_fd = d_open(dev_name, mode+O_NONBLOCK);
- if (m_fd < 0) {
- berrno be;
- dev_errno = errno;
-@@ -390,10 +422,10 @@
- mt_com.mt_op = MTREW;
- mt_com.mt_count = 1;
- /* rewind only if dev is a tape */
-- if (is_tape() && (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
-+ if (is_tape() && (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
- berrno be;
- dev_errno = errno; /* set error status from rewind */
-- tape_close(m_fd);
-+ d_close(m_fd);
- clear_opened();
- Dmsg2(100, "Rewind error on %s close: ERR=%s\n", print_name(),
- be.bstrerror(dev_errno));
-@@ -403,8 +435,8 @@
- }
- } else {
- /* Got fd and rewind worked, so we must have medium in drive */
-- tape_close(m_fd);
-- m_fd = tape_open(dev_name, mode); /* open normally */
-+ d_close(m_fd);
-+ m_fd = d_open(dev_name, mode); /* open normally */
- if (m_fd < 0) {
- berrno be;
- dev_errno = errno;
-@@ -688,7 +720,7 @@
- be.bstrerror());
- Dmsg1(100, "open failed: %s", errmsg);
- /* Use system close() */
-- ::close(m_fd);
-+ d_close(m_fd);
- clear_opened();
- } else {
- part_size = filestat.st_size;
-@@ -732,7 +764,7 @@
- * retrying every 5 seconds.
- */
- for (i=max_rewind_wait; ; i -= 5) {
-- if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- clrerror(MTREW);
- if (i == max_rewind_wait) {
-@@ -746,7 +778,7 @@
- */
- if (first && dcr) {
- int open_mode = openmode;
-- tape_close(m_fd);
-+ d_close(m_fd);
- clear_opened();
- open(dcr, open_mode);
- if (m_fd < 0) {
-@@ -886,7 +918,7 @@
- mt_com.mt_count = 1;
- }
-
-- if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- clrerror(mt_com.mt_op);
- Dmsg1(50, "ioctl error: %s\n", be.bstrerror());
-@@ -1030,7 +1062,7 @@
- stat |= BMT_TAPE;
- Pmsg0(-20,_(" Bacula status:"));
- Pmsg2(-20,_(" file=%d block=%d\n"), dev->file, dev->block_num);
-- if (tape_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
- berrno be;
- dev->dev_errno = errno;
- Mmsg2(dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
-@@ -1157,7 +1189,7 @@
- dev->file_addr = 0;
- mt_com.mt_op = MTLOAD;
- mt_com.mt_count = 1;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- dev->dev_errno = errno;
- Mmsg2(dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
-@@ -1188,7 +1220,7 @@
- unlock_door();
- mt_com.mt_op = MTOFFL;
- mt_com.mt_count = 1;
-- if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"),
-@@ -1263,7 +1295,7 @@
- int my_errno = 0;
- mt_com.mt_op = MTFSF;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) {
- my_errno = errno; /* save errno */
- } else if ((os_file=get_os_tape_file()) < 0) {
-@@ -1344,7 +1376,7 @@
- }
-
- Dmsg0(100, "Doing MTFSF\n");
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) { /* error => EOT */
- berrno be;
- set_eot();
-@@ -1418,7 +1450,7 @@
- file_size = 0;
- mt_com.mt_op = MTBSF;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) {
- berrno be;
- clrerror(MTBSF);
-@@ -1458,7 +1490,7 @@
- Dmsg1(100, "fsr %d\n", num);
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat == 0) {
- clear_eof();
- block_num += num;
-@@ -1517,7 +1549,7 @@
- clear_eot();
- mt_com.mt_op = MTBSR;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat < 0) {
- berrno be;
- clrerror(MTBSR);
-@@ -1533,7 +1565,7 @@
- struct mtop mt_com;
- mt_com.mt_op = MTLOCK;
- mt_com.mt_count = 1;
-- tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- #endif
- }
-
-@@ -1543,7 +1575,7 @@
- struct mtop mt_com;
- mt_com.mt_op = MTUNLOCK;
- mt_com.mt_count = 1;
-- tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- #endif
- }
-
-@@ -1668,7 +1700,7 @@
- clear_eot();
- mt_com.mt_op = MTWEOF;
- mt_com.mt_count = num;
-- stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- if (stat == 0) {
- block_num = 0;
- file += num;
-@@ -1799,7 +1831,7 @@
- /* Found on Solaris */
- #ifdef MTIOCLRERR
- {
-- tape_ioctl(m_fd, MTIOCLRERR);
-+ d_ioctl(m_fd, MTIOCLRERR);
- Dmsg0(200, "Did MTIOCLRERR\n");
- }
- #endif
-@@ -1812,7 +1844,7 @@
- union mterrstat mt_errstat;
- Dmsg2(200, "Doing MTIOCERRSTAT errno=%d ERR=%s\n", dev_errno,
- be.bstrerror(dev_errno));
-- tape_ioctl(m_fd, MTIOCERRSTAT, (char *)&mt_errstat);
-+ d_ioctl(m_fd, MTIOCERRSTAT, (char *)&mt_errstat);
- }
- #endif
-
-@@ -1823,7 +1855,7 @@
- mt_com.mt_op = MTCSE;
- mt_com.mt_count = 1;
- /* Clear any error condition on the tape */
-- tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
-+ d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- Dmsg0(200, "Did MTCSE\n");
- }
- #endif
-@@ -1860,10 +1892,8 @@
- case B_VTL_DEV:
- case B_TAPE_DEV:
- unlock_door();
-- tape_close(m_fd);
-- break;
- default:
-- ::close(m_fd);
-+ d_close(m_fd);
- }
-
- /* Clean up device packet so it can be reused */
-@@ -2262,11 +2292,7 @@
-
- get_timer_count();
-
-- if (this->is_tape()) {
-- read_len = tape_read(m_fd, buf, len);
-- } else {
-- read_len = ::read(m_fd, buf, len);
-- }
-+ read_len = d_read(m_fd, buf, len);
-
- last_tick = get_timer_count();
-
-@@ -2287,11 +2313,7 @@
-
- get_timer_count();
-
-- if (this->is_tape()) {
-- write_len = tape_write(m_fd, buf, len);
-- } else {
-- write_len = ::write(m_fd, buf, len);
-- }
-+ write_len = d_write(m_fd, buf, len);
-
- last_tick = get_timer_count();
-
-@@ -2317,7 +2339,7 @@
- struct mtget mt_stat;
-
- if (has_cap(CAP_MTIOCGET) &&
-- tape_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) {
-+ d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) {
- return mt_stat.mt_fileno;
- }
- return -1;
-@@ -2442,7 +2464,7 @@
- mt_com.mt_op = MTSETBLK;
- mt_com.mt_count = 0;
- Dmsg0(100, "Set block size to zero\n");
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETBLK);
- }
- }
-@@ -2458,7 +2480,7 @@
- mt_com.mt_count |= MT_ST_FAST_MTEOM;
- }
- Dmsg0(100, "MTSETDRVBUFFER\n");
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETDRVBUFFER);
- }
- }
-@@ -2472,13 +2494,13 @@
- dev->min_block_size == 0) { /* variable block mode */
- mt_com.mt_op = MTSETBSIZ;
- mt_com.mt_count = 0;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETBSIZ);
- }
- /* Get notified at logical end of tape */
- mt_com.mt_op = MTEWARN;
- mt_com.mt_count = 1;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTEWARN);
- }
- }
-@@ -2491,7 +2513,7 @@
- dev->min_block_size == 0) { /* variable block mode */
- mt_com.mt_op = MTSETBSIZ;
- mt_com.mt_count = 0;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSETBSIZ);
- }
- }
-@@ -2502,7 +2524,7 @@
- } else {
- neof = 1;
- }
-- if (tape_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
- berrno be;
- dev->dev_errno = errno; /* save errno */
- Mmsg2(dev->errmsg, _("Unable to set eotmodel on device %s: ERR=%s\n"),
-@@ -2519,7 +2541,7 @@
- dev->min_block_size == 0) { /* variable block mode */
- mt_com.mt_op = MTSRSZ;
- mt_com.mt_count = 0;
-- if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
-+ if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
- dev->clrerror(MTSRSZ);
- }
- }
-@@ -2531,7 +2553,7 @@
- {
- Dmsg0(100, "dev_get_os_pos\n");
- return dev->has_cap(CAP_MTIOCGET) &&
-- tape_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 &&
-+ dev->d_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 &&
- mt_stat->mt_fileno >= 0;
- }
-
-Index: src/stored/faketape.c
-===================================================================
---- src/stored/faketape.c (revision 7116)
-+++ src/stored/faketape.c (working copy)
-@@ -60,7 +60,6 @@
- #include "bacula.h" /* define 64bit file usage */
- #include "stored.h"
-
--#ifdef USE_FAKETAPE
- #include "faketape.h"
-
- static int dbglevel = 100;
-@@ -992,4 +991,3 @@
- atEOF, atEOT, atEOD, atBOT);
- }
-
--#endif /* USE_FAKETAPE */
-Index: src/stored/dev.h
-===================================================================
---- src/stored/dev.h (revision 7116)
-+++ src/stored/dev.h (working copy)
-@@ -95,7 +95,8 @@
- B_TAPE_DEV,
- B_DVD_DEV,
- B_FIFO_DEV,
-- B_VTL_DEV
-+ B_FAKETAPE_DEV, /* change to B_TAPE_DEV after init */
-+ B_VTL_DEV
- };
-
- /* Generic status bits returned from status_dev() */
-@@ -307,11 +308,13 @@
- int is_autochanger() const { return capabilities & CAP_AUTOCHANGER; }
- int requires_mount() const { return capabilities & CAP_REQMOUNT; }
- int is_removable() const { return capabilities & CAP_REM; }
-- int is_tape() const { return dev_type == B_TAPE_DEV; }
-+ int is_tape() const { return (dev_type == B_TAPE_DEV ||
-+ dev_type == B_FAKETAPE_DEV); }
- int is_file() const { return dev_type == B_FILE_DEV; }
- int is_fifo() const { return dev_type == B_FIFO_DEV; }
- int is_dvd() const { return dev_type == B_DVD_DEV; }
- int is_vtl() const { return dev_type == B_VTL_DEV; }
-+ int is_faketape() const { return dev_type == B_FAKETAPE_DEV; }
- int is_open() const { return m_fd >= 0; }
- int is_offline() const { return state & ST_OFFLINE; }
- int is_labeled() const { return state & ST_LABEL; }
-@@ -426,6 +429,14 @@
- uint32_t get_block_num() const { return block_num; };
- int fd() const { return m_fd; };
-
-+ /* low level operations */
-+ void init_backend();
-+ int (*d_open)(const char *pathname, int flags, ...);
-+ int (*d_read)(int fd, void *buffer, unsigned int count);
-+ int (*d_write)(int fd, const void *buffer, unsigned int count);
-+ int (*d_close)(int fd);
-+ int (*d_ioctl)(int fd, unsigned long int request, ...);
-+
- /*
- * Locking and blocking calls
- */
-Index: src/stored/faketape.h
-===================================================================
---- src/stored/faketape.h (revision 7116)
-+++ src/stored/faketape.h (working copy)
-@@ -38,8 +38,6 @@
- #include <stddef.h>
- #include "bacula.h"
-
--#ifdef USE_FAKETAPE
--
- #define FTAPE_MAX_DRIVE 50
-
- /*
-@@ -85,7 +83,7 @@
- void check_eof() { if(needEOF) weof();};
- void update_pos();
- bool read_fm(FT_READ_FM_MODE readfirst);
-- void set_eot() { eot_count=0; atEOT=true;};
-+ void set_eot() { atEOT=true;};
-
- public:
- int fsf();
-@@ -109,5 +107,4 @@
- int tape_pos(struct mtpos *mt_com);
- };
-
--#endif /* USE_FAKETAPE */
- #endif /* !FAKETAPE_H */
-Index: src/version.h
-===================================================================
---- src/version.h (revision 7116)
-+++ src/version.h (working copy)
-@@ -62,7 +62,7 @@
- * run regress test.
- */
- #ifdef DEVELOPER
--//#define USE_FAKETAPE
-+#define USE_FAKETAPE
- #endif
-
- /*
+++ /dev/null
-Index: src/dird/fd_cmds.c
-===================================================================
---- src/dird/fd_cmds.c (révision 6169)
-+++ src/dird/fd_cmds.c (copie de travail)
-@@ -527,7 +527,8 @@
- RUNSCRIPT *cmd;
- bool launch_before_cmd = false;
- POOLMEM *ehost = get_pool_memory(PM_FNAME);
-- int result;
-+ int result, cmd_type;
-+ char *c, *command;
-
- Dmsg0(120, "bdird: sending runscripts to fd\n");
-
-@@ -537,29 +538,33 @@
- Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
-
- if (strcmp(ehost, jcr->client->name()) == 0) {
-- pm_strcpy(msg, cmd->command);
-- bash_spaces(msg);
-+ foreach_alist(c, cmd->commands) {
-+ cmd->get_command(c, &cmd_type, &command);
-+ if (cmd_type == SHELL_CMD) {
-+ pm_strcpy(msg, command);
-+ bash_spaces(msg);
-
-- Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
-+ Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
-
-- /* TODO: remove this with bacula 1.42 */
-- if (cmd->old_proto) {
-- result = send_runscript_with_old_proto(jcr, cmd->when, msg);
-+ /* TODO: remove this with bacula 1.42 */
-+ if (cmd->old_proto) {
-+ result = send_runscript_with_old_proto(jcr, cmd->when, msg);
-+
-+ } else {
-+ fd->fsend(runscript, cmd->on_success,
-+ cmd->on_failure,
-+ cmd->fail_on_error,
-+ cmd->when,
-+ msg);
-
-- } else {
-- fd->fsend(runscript, cmd->on_success,
-- cmd->on_failure,
-- cmd->fail_on_error,
-- cmd->when,
-- msg);
--
-- result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
-- launch_before_cmd = true;
-+ result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
-+ launch_before_cmd = true;
-+ }
-+ if (!result) {
-+ goto bail_out;
-+ }
-+ }
- }
--
-- if (!result) {
-- goto bail_out;
-- }
- }
- /* TODO : we have to play with other client */
- /*
-@@ -567,7 +572,7 @@
- send command to an other client
- }
- */
-- }
-+ }
- }
-
- /* Tell the FD to execute the ClientRunBeforeJob */
-Index: src/dird/dird_conf.c
-===================================================================
---- src/dird/dird_conf.c (révision 6169)
-+++ src/dird/dird_conf.c (copie de travail)
-@@ -651,16 +651,19 @@
- }
- }
- if (res->res_job.RunScripts) {
-- RUNSCRIPT *script;
-- foreach_alist(script, res->res_job.RunScripts) {
-- sendit(sock, _(" --> RunScript\n"));
-- sendit(sock, _(" --> Command=%s\n"), NPRT(script->command));
-- sendit(sock, _(" --> Target=%s\n"), NPRT(script->target));
-- sendit(sock, _(" --> RunOnSuccess=%u\n"), script->on_success);
-- sendit(sock, _(" --> RunOnFailure=%u\n"), script->on_failure);
-- sendit(sock, _(" --> FailJobOnError=%u\n"), script->fail_on_error);
-- sendit(sock, _(" --> RunWhen=%u\n"), script->when);
-- }
-+ char *c;
-+ RUNSCRIPT *script;
-+ foreach_alist(script, res->res_job.RunScripts) {
-+ sendit(sock, _(" --> RunScript\n"));
-+ foreach_alist(c, script->commands) {
-+ sendit(sock, _(" --> Command=%s\n"), NPRT(c));
-+ }
-+ sendit(sock, _(" --> Target=%s\n"), NPRT(script->target));
-+ sendit(sock, _(" --> RunOnSuccess=%u\n"), script->on_success);
-+ sendit(sock, _(" --> RunOnFailure=%u\n"), script->on_failure);
-+ sendit(sock, _(" --> FailJobOnError=%u\n"), script->fail_on_error);
-+ sendit(sock, _(" --> RunWhen=%u\n"), script->when);
-+ }
- }
- if (res->res_job.pool) {
- sendit(sock, _(" --> "));
-@@ -1724,14 +1727,14 @@
- }
-
- /*
-- * Store a runscript->command as a string
-+ * Store a runscript->commands as a alist(char + string)
- */
- static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
- {
- lex_get_token(lc, T_STRING);
-
- if (pass == 2) {
-- ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
-+ ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
- }
- scan_to_eol(lc);
- }
-@@ -1745,7 +1748,7 @@
- RUNSCRIPT *script = new_runscript();
- script->set_job_code_callback(job_code_callback_filesetname);
-
-- script->set_command(lc->str);
-+ script->add_command(lc->str);
-
- /* TODO: remove all script->old_proto with bacula 1.42 */
-
-@@ -1873,7 +1876,7 @@
- }
-
- if (pass == 2) {
-- if (res_runscript.command == NULL) {
-+ if (res_runscript.commands == NULL) {
- scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
- "command", "runscript");
- }
-@@ -1886,7 +1889,7 @@
- RUNSCRIPT *script = new_runscript();
- memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
- script->set_job_code_callback(job_code_callback_filesetname);
--
-+
- if (*runscripts == NULL) {
- *runscripts = New(alist(10, not_owned_by_alist));
- }
-Index: src/filed/job.c
-===================================================================
---- src/filed/job.c (révision 6169)
-+++ src/filed/job.c (copie de travail)
-@@ -481,7 +481,7 @@
-
- /* Run the command now */
- script = new_runscript();
-- script->set_command(cmd);
-+ script->add_command(cmd);
- script->when = SCRIPT_Before;
- ok = script->run(jcr, "ClientRunBeforeJob");
- free_runscript(script);
-@@ -529,7 +529,7 @@
- unbash_spaces(msg);
-
- cmd = new_runscript();
-- cmd->set_command(msg);
-+ cmd->add_command(msg);
- cmd->on_success = true;
- cmd->on_failure = false;
- cmd->when = SCRIPT_After;
-@@ -567,7 +567,7 @@
- cmd->fail_on_error = fail_on_error;
- unbash_spaces(msg);
-
-- cmd->set_command(msg);
-+ cmd->add_command(msg);
- cmd->debug();
- jcr->RunScripts->append(cmd);
-
-Index: src/lib/runscript.h
-===================================================================
---- src/lib/runscript.h (révision 6169)
-+++ src/lib/runscript.h (copie de travail)
-@@ -62,8 +62,8 @@
- };
-
- enum {
-- SHELL_CMD = 1,
-- CONSOLE_CMD = 2
-+ SHELL_CMD = '|',
-+ CONSOLE_CMD = '@'
- };
-
- /*
-@@ -71,10 +71,9 @@
- */
- class RUNSCRIPT {
- public:
-- POOLMEM *command; /* command string */
-+ alist *commands; /* list of command/console string */
- POOLMEM *target; /* host target */
- int when; /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
-- int cmd_type; /* Command type -- Shell, Console */
- char level; /* Base|Full|Incr...|All (NYI) */
- bool on_success; /* execute command on job success (After) */
- bool on_failure; /* execute command on job failure (After) */
-@@ -86,19 +85,22 @@
-
- bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
- bool can_run_at_level(int JobLevel) { return true;}; /* TODO */
-- void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
-+ void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
-+ void get_command(const char *cmd, int *cmd_type, char **cmd);
- void set_target(const POOLMEM *client_name);
- void reset_default(bool free_string = false);
-- bool is_local(); /* true if running on local host */
-+ bool is_local(const char *cmd); /* true if running on local host */
- void debug();
-+ void set_job_code_callback(job_code_callback_t job_code_callback);
-
-- void set_job_code_callback(job_code_callback_t job_code_callback);
-+private:
-+ bool run_command(const char *cmd, JCR *job, const char *name="");
- };
-
- /* create new RUNSCRIPT (set all value to 0) */
- RUNSCRIPT *new_runscript();
-
--/* create new RUNSCRIPT from an other */
-+/* create new RUNSCRIPT from an other (deep copy) */
- RUNSCRIPT *copy_runscript(RUNSCRIPT *src);
-
- /* launch each script from runscripts*/
-Index: src/lib/runscript.c
-===================================================================
---- src/lib/runscript.c (révision 6169)
-+++ src/lib/runscript.c (copie de travail)
-@@ -59,15 +59,18 @@
-
- void RUNSCRIPT::reset_default(bool free_strings)
- {
-- if (free_strings && command) {
-- free_pool_memory(command);
-+ char *c;
-+ if (free_strings && commands) {
-+ foreach_alist(c, commands) {
-+ free_pool_memory(c);
-+ }
-+ delete commands;
- }
- if (free_strings && target) {
- free_pool_memory(target);
- }
--
- target = NULL;
-- command = NULL;
-+ commands = NULL;
- on_success = true;
- on_failure = false;
- fail_on_error = true;
-@@ -83,10 +86,16 @@
- RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
- memcpy(dst, src, sizeof(RUNSCRIPT));
-
-- dst->command = NULL;
-+ dst->commands = New(alist(5, not_owned_by_alist));
-+ char *c;
-+ POOLMEM *m;
-+ foreach_alist(c, src->commands) {
-+ m = get_pool_memory(PM_FNAME);
-+ pm_strcpy(m, c);
-+ dst->commands->append(m);
-+ }
-+
- dst->target = NULL;
--
-- dst->set_command(src->command, src->cmd_type);
- dst->set_target(src->target);
-
- return dst;
-@@ -95,9 +104,12 @@
- void free_runscript(RUNSCRIPT *script)
- {
- Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
--
-- if (script->command) {
-- free_pool_memory(script->command);
-+ POOLMEM *c;
-+ if (script->commands) {
-+ foreach_alist(c, script->commands) {
-+ free_pool_memory(c);
-+ }
-+ delete script->commands;
- }
- if (script->target) {
- free_pool_memory(script->target);
-@@ -108,66 +120,25 @@
- int run_scripts(JCR *jcr, alist *runscripts, const char *label)
- {
- Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
--
-- RUNSCRIPT *script;
-- bool runit;
-
-- int when;
--
-- if (strstr(label, NT_("Before"))) {
-- when = SCRIPT_Before;
-- } else {
-- when = SCRIPT_After;
-- }
--
- if (runscripts == NULL) {
- Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
- return 0;
- }
--
-+
-+ RUNSCRIPT *script;
- foreach_alist(script, runscripts) {
-- Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
-- runit = false;
--
-- if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
-- if ((script->on_success
-- && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
-- || (script->on_failure && job_canceled(jcr))
-- )
-- {
-- Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n",
-- script->command, script->on_success, script->on_failure,
-- jcr->JobStatus );
-- runit = true;
-- }
-- }
--
-- if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
-- if ((script->on_success && (jcr->JobStatus == JS_Terminated))
-- || (script->on_failure && job_canceled(jcr))
-- )
-- {
-- Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n",
-- script->command, script->on_success, script->on_failure,
-- jcr->JobStatus );
-- runit = true;
-- }
-- }
--
-- if (!script->is_local()) {
-- runit = false;
-- }
--
-- /* we execute it */
-- if (runit) {
-- script->run(jcr, label);
-- }
-+ script->run(jcr, label);
- }
- return 1;
- }
-
--bool RUNSCRIPT::is_local()
-+bool RUNSCRIPT::is_local(const char *c)
- {
-+ if (c[0] == CONSOLE_CMD) {
-+ return true;
-+ }
-+
- if (!target || (strcmp(target, "") == 0)) {
- return true;
- } else {
-@@ -175,23 +146,31 @@
- }
- }
-
--/* set this->command to cmd */
--void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
-+/* set add cmd to this->commands alist */
-+void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
- {
-- Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
-+ Dmsg2(500, "runscript: setting command = %s type=%i\n", NPRT(cmd), acmd_type);
-
- if (!cmd) {
- return;
- }
-
-- if (!command) {
-- command = get_pool_memory(PM_FNAME);
-+ if (!commands) {
-+ commands = New(alist(5, not_owned_by_alist));
- }
-
-- pm_strcpy(command, cmd);
-- cmd_type = acmd_type;
-+ POOLMEM *c = get_pool_memory(PM_FNAME);
-+ Mmsg(c, "%c%s", acmd_type, cmd);
-+ commands->append(c);
- }
-
-+/* command = ( SHELL_CMD | CONSOLE_CMD ) command */
-+void RUNSCRIPT::get_command(const char* command, int *acmd_type, char **cmd)
-+{
-+ *acmd_type = (int) command[0];
-+ *cmd = (char *)command + 1;
-+}
-+
- /* set this->target to client_name */
- void RUNSCRIPT::set_target(const POOLMEM *client_name)
- {
-@@ -210,14 +189,70 @@
-
- bool RUNSCRIPT::run(JCR *jcr, const char *name)
- {
-- Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
-+ char *c;
-+ bool runit;
-+
-+ int when;
-+
-+ if (strstr(name, NT_("Before"))) {
-+ when = SCRIPT_Before;
-+ } else {
-+ when = SCRIPT_After;
-+ }
-+
-+ foreach_alist(c, this->commands) {
-+ Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
-+ runit = false;
-+
-+ if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
-+ if ((this->on_success
-+ && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
-+ || (this->on_failure && job_canceled(jcr))
-+ )
-+ {
-+ Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n",
-+ c, this->on_success, this->on_failure,
-+ jcr->JobStatus );
-+ runit = true;
-+ }
-+ }
-+
-+ if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
-+ if ((this->on_success && (jcr->JobStatus == JS_Terminated))
-+ || (this->on_failure && job_canceled(jcr))
-+ )
-+ {
-+ Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n",
-+ c, this->on_success, this->on_failure,
-+ jcr->JobStatus );
-+ runit = true;
-+ }
-+ }
-+
-+ if (!this->is_local(c)) {
-+ runit = false;
-+ }
-+
-+ /* we execute it */
-+ if (runit) {
-+ this->run_command(c, jcr, name);
-+ }
-+ }
-+ return 1;
-+}
-+
-+/* run a command from the list */
-+bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
-+{
- POOLMEM *ecmd = get_pool_memory(PM_FNAME);
-- int status;
-+ int status, cmd_type;
- BPIPE *bpipe;
-- char line[MAXSTRING];
-+ char line[MAXSTRING], *cmd;
-
-- ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
-- Dmsg1(100, "runscript: running '%s'...\n", ecmd);
-+ this->get_command(command, &cmd_type, &cmd);
-+ ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
-+
-+ Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
- Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"),
- cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
-
-@@ -278,9 +313,12 @@
-
- void RUNSCRIPT::debug()
- {
-+ char *c;
- Dmsg0(200, "runscript: debug\n");
- Dmsg0(200, _(" --> RunScript\n"));
-- Dmsg1(200, _(" --> Command=%s\n"), NPRT(command));
-+ foreach_alist(c, commands) {
-+ Dmsg1(200, _(" --> Command=%s\n"), NPRT(c));
-+ }
- Dmsg1(200, _(" --> Target=%s\n"), NPRT(target));
- Dmsg1(200, _(" --> RunOnSuccess=%u\n"), on_success);
- Dmsg1(200, _(" --> RunOnFailure=%u\n"), on_failure);
+++ /dev/null
-Index: src/dird/dird_conf.c
-===================================================================
---- src/dird/dird_conf.c (révision 6586)
-+++ src/dird/dird_conf.c (copie de travail)
-@@ -1772,7 +1772,11 @@
- lex_get_token(lc, T_STRING);
-
- if (pass == 2) {
-- ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
-+ Dmsg2(1, "runscript cmd=%s type=%c\n", lc->str, item->code);
-+ POOLMEM *c = get_pool_memory(PM_FNAME);
-+ pm_strcpy(c, lc->str);
-+ ((RUNSCRIPT*) item->value)->commands->prepend(c);
-+ ((RUNSCRIPT*) item->value)->commands->prepend((void *)item->code);
- }
- scan_to_eol(lc);
- }
-@@ -1874,7 +1878,8 @@
- */
- static void store_runscript(LEX *lc, RES_ITEM *item, int index, int pass)
- {
-- int token, i;
-+ char *c;
-+ int token, i, t;
- alist **runscripts = (alist **)(item->value) ;
-
- Dmsg1(200, "store_runscript: begin store_runscript pass=%i\n", pass);
-@@ -1887,6 +1892,10 @@
- scan_err1(lc, _("Expecting open brace. Got %s"), lc->str);
- }
-
-+ if (pass == 2) {
-+ res_runscript.commands = New(alist(10, not_owned_by_alist));
-+ }
-+
- while ((token = lex_get_token(lc, T_SKIP_EOL)) != T_EOF) {
- if (token == T_EOB) {
- break;
-@@ -1914,26 +1923,25 @@
- }
-
- if (pass == 2) {
-- if (res_runscript.command == NULL) {
-- scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
-- "command", "runscript");
-- }
--
- /* run on client by default */
- if (res_runscript.target == NULL) {
- res_runscript.set_target("%c");
- }
--
-- RUNSCRIPT *script = new_runscript();
-- memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
-- script->set_job_code_callback(job_code_callback_filesetname);
--
- if (*runscripts == NULL) {
-- *runscripts = New(alist(10, not_owned_by_alist));
-+ *runscripts = New(alist(10, not_owned_by_alist));
- }
--
-- (*runscripts)->append(script);
-- script->debug();
-+ while ((c=(char*)res_runscript.commands->pop()) != NULL) {
-+ t = (int) res_runscript.commands->pop();
-+ RUNSCRIPT *script = new_runscript();
-+ memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
-+ script->set_job_code_callback(job_code_callback_filesetname);
-+ script->set_command(c, t);
-+
-+ (*runscripts)->append(script);
-+ script->debug();
-+ }
-+ delete res_runscript.commands;
-+ res_runscript.commands = NULL;
- }
-
- scan_to_eol(lc);
-Index: src/lib/runscript.h
-===================================================================
---- src/lib/runscript.h (révision 6586)
-+++ src/lib/runscript.h (copie de travail)
-@@ -62,8 +62,8 @@
- };
-
- enum {
-- SHELL_CMD = 1,
-- CONSOLE_CMD = 2
-+ SHELL_CMD = '|',
-+ CONSOLE_CMD = '@'
- };
-
- /*
-@@ -83,7 +83,7 @@
- bool old_proto; /* used by old 1.3X protocol */
- job_code_callback_t job_code_callback;
- /* Optional callback function passed to edit_job_code */
--
-+ alist *commands; /* Use during parsing */
- bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
- bool can_run_at_level(int JobLevel) { return true;}; /* TODO */
- void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
+++ /dev/null
-Index: myconf.h
-===================================================================
---- myconf.h (revision 7238)
-+++ myconf.h (working copy)
-@@ -206,13 +206,18 @@
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <sys/mman.h>
- #include <sys/time.h>
--#include <sys/times.h>
- #include <fcntl.h>
- #include <dirent.h>
-+
-+#ifdef HAVE_WIN32
-+#include "compat.h"
-+#else
-+#include <sys/mman.h>
-+#include <sys/times.h>
- #include <regex.h>
- #include <glob.h>
-+#endif
-
- #if TCUSEPTHREAD
- #include <pthread.h>
-Index: tcutil.c
-===================================================================
---- tcutil.c (revision 7238)
-+++ tcutil.c (working copy)
-@@ -17,7 +17,6 @@
- #include "tcutil.h"
- #include "myconf.h"
-
--
- /*************************************************************************************************
- * basic utilities
- *************************************************************************************************/
-@@ -3333,6 +3332,7 @@
-
- /* Lock a file. */
- bool tclock(int fd, bool ex, bool nb){
-+#ifndef HAVE_WIN32
- assert(fd >= 0);
- struct flock lock;
- memset(&lock, 0, sizeof(struct flock));
-@@ -3344,6 +3344,7 @@
- while(fcntl(fd, nb ? F_SETLK : F_SETLKW, &lock) == -1){
- if(errno != EINTR) return false;
- }
-+#endif
- return true;
- }
-
+++ /dev/null
---- Makefile 2008-06-27 17:15:12.000000000 +0200
-+++ Makefile.mingw 2008-06-27 17:15:04.000000000 +0200
-@@ -22,7 +22,7 @@
- # Targets
- HEADERFILES = tcutil.h tchdb.h tcbdb.h tcadb.h
- LIBRARYFILES = libtokyocabinet.a libtokyocabinet.so.3.6.0 libtokyocabinet.so.3 libtokyocabinet.so
--LIBOBJFILES = tcutil.o tchdb.o tcbdb.o tcadb.o myconf.o
-+LIBOBJFILES = tcutil.o tchdb.o tcbdb.o tcadb.o myconf.o compat.o
- COMMANDFILES = tcutest tcumttest tcucodec tchtest tchmttest tchmgr tcbtest tcbmttest tcbmgr tcatest tcamgr
- MAN1FILES = tcutest.1 tcumttest.1 tcucodec.1 tchtest.1 tchmttest.1 tchmgr.1 tcbtest.1 tcbmttest.1 tcbmgr.1 tcatest.1 tcamgr.1
- MAN3FILES = tokyocabinet.3 tcutil.3 tcxstr.3 tclist.3 tcmap.3 tcmdb.3 tcmpool.3 tchdb.3 tcbdb.3 tcadb.3
-@@ -45,17 +45,17 @@
-
- # Building configuration
- CC = i586-mingw32msvc-gcc
--CPPFLAGS = -I. -I$(INCLUDEDIR) -L/home/eric/include -L/usr/local/include -DNDEBUG -D_GNU_SOURCE=1 -UNDEBUG \
-+CPPFLAGS = -I. -I$(INCLUDEDIR) -I/home/eric/include -L/usr/local/include -DNDEBUG -D_GNU_SOURCE=1 -UNDEBUG \
- -D_TC_PREFIX="\"$(prefix)\"" -D_TC_INCLUDEDIR="\"$(INCLUDEDIR)\"" \
- -D_TC_LIBDIR="\"$(LIBDIR)\"" -D_TC_BINDIR="\"$(BINDIR)\"" -D_TC_LIBEXECDIR="\"$(LIBEXECDIR)\"" \
- -D_TC_APPINC="\"-I$(INCLUDEDIR)\"" -D_TC_APPLIBS="\"-L$(LIBDIR) -ltokyocabinet -lm \""
--CFLAGS = -std=c99 -Wall -fPIC -pedantic -fsigned-char -g
-+CFLAGS = --std=c99 -Wall -pedantic -fsigned-char -g -DHAVE_WIN32
- LDFLAGS = -L. -L$(LIBDIR) -L/home/eric/lib -L/usr/local/lib -static
--LIBS = -lm
-+LIBS = -lm -lz -lpthreadGCE
- LDENV = LD_RUN_PATH=/lib:/usr/lib:$(LIBDIR):$(HOME)/lib:/usr/local/lib:$(LIBDIR):.
- RUNENV = LD_LIBRARY_PATH=.:/lib:/usr/lib:$(LIBDIR):$(HOME)/lib:/usr/local/lib:$(LIBDIR)
- POSTCMD = true
--NO_ECHO = @
-+NO_ECHO =
-
-
- #================================================================
-@@ -447,47 +447,47 @@
- ln -f -s libtokyocabinet.$(LIBVER).$(LIBREV).0.dylib $@
-
-
--tcutest : tcutest.o $(LIBRARYFILES)
-+tcutest.exe : tcutest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcumttest : tcumttest.o $(LIBRARYFILES)
-+tcumttest.exe : tcumttest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcucodec : tcucodec.o $(LIBRARYFILES)
-+tcucodec.exe : tcucodec.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tchtest : tchtest.o $(LIBRARYFILES)
-+tchtest.exe : tchtest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tchmttest : tchmttest.o $(LIBRARYFILES)
-+tchmttest.exe : tchmttest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tchmgr : tchmgr.o $(LIBRARYFILES)
-+tchmgr.exe : tchmgr.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcbtest : tcbtest.o $(LIBRARYFILES)
-+tcbtest.exe : tcbtest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcbmttest : tcbmttest.o $(LIBRARYFILES)
-+tcbmttest.exe : tcbmttest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcbmgr : tcbmgr.o $(LIBRARYFILES)
-+tcbmgr.exe : tcbmgr.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcatest : tcatest.o $(LIBRARYFILES)
-+tcatest.exe : tcatest.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
--tcamgr : tcamgr.o $(LIBRARYFILES)
-+tcamgr.exe : tcamgr.o $(LIBRARYFILES)
- $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS)
-
-
+++ /dev/null
-/*
- export LD_LIBRARY_PATH=/home/eric/dev/bacula/tcdb/lib/
- g++ -I/home/eric/dev/bacula/tcdb/include -o tt -L /home/eric/dev/bacula/tcdb/lib/ -ltokyocabinet -lz -lpthread -lm tcdbtest.c
-
-./tt $(wc -l src.txt2) 0
-
- */
-
-#include <tcutil.h>
-#include <tchdb.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <signal.h>
-
-#define NITEMS 5000000
-
-
-
-void atend()
-{
- unlink("casket.hdb");
-}
-
-int64_t get_current_time()
-{
- struct timeval tv;
- if (gettimeofday(&tv, NULL) != 0) {
- tv.tv_sec = (long)time(NULL); /* fall back to old method */
- tv.tv_usec = 0;
- }
- return (int64_t)tv.tv_sec * 1000000 + (int64_t)tv.tv_usec;
-}
-
-typedef struct PrivateCurFile {
- char *fname; /* not stored with tchdb mode */
- time_t ctime;
- time_t mtime;
- bool seen;
-} CurFile;
-
-int main(int argc, char **argv)
-{
- CurFile elt;
- FILE *fp, *res;
- TCHDB *hdb;
- int ecode;
- char *key;
- int value;
- int i=0;
- char save_key[512];
- char line[512];
- int64_t ctime, ttime;;
- char result[200];
-
- if (argc != 4) {
- fprintf(stderr, "Usage: tt count file cache %i\n");
- exit(1);
- }
-
- atexit(atend);
- signal(15, exit);
- signal(2, exit);
-
- snprintf(result, sizeof(result), "result.%i.csv", getpid());
- res = fopen(result, "w");
-
- /* create the object */
- hdb = tchdbnew();
-
- if (atoi(argv[3]) > 0) {
- tchdbsetcache(hdb, atoi(argv[3]));
- }
- fprintf(res, "cache;%i\n", atoi(argv[3]));
-
- /*
- * apow : 128 (size of stat hash field)
- */
- int opt=HDBTLARGE | HDBTTCBS;
- tchdbtune(hdb, atoll(argv[1]), 7, 16, opt);
- fprintf(res, "bucket;%lli\n", atoll(argv[1]));
- fprintf(res, "compress;%i\n", opt);
-
- /* open the database */
- if(!tchdbopen(hdb, "casket.hdb", HDBOWRITER | HDBOCREAT)){
- ecode = tchdbecode(hdb);
- fprintf(stderr, "open error: %s\n", tchdberrmsg(ecode));
- }
-
- ctime = get_current_time();
-
- /* fill hash with real data (find / > src.txt) */
- fp = fopen(argv[2], "r");
- if (!fp) {
- fprintf(stderr, "open %s file error\n", argv[2]);
- exit (1);
- }
- while (fgets(line, sizeof(line), fp)) {
- if (!tchdbputasync(hdb, line, strlen(line)+1, &elt, sizeof(elt))) {
- ecode = tchdbecode(hdb);
- fprintf(stderr, "put error: %s\n", tchdberrmsg(ecode));
- }
- if (i++ == 99) {
- strcpy(save_key, line);
- }
- }
- fclose(fp);
-
- ttime= get_current_time();
- fprintf(res, "nbelt;%u\n", i);
-
- fprintf(stderr, "loading %i file into hash database in %ims\n",
- i, (ttime - ctime)/1000);
- fprintf(res, "load;%i\n", (ttime - ctime)/1000);
-
-
- /* retrieve records */
- value = tchdbget3(hdb, save_key, strlen(save_key)+1, &elt, sizeof(elt));
- if(value == -1){
- ecode = tchdbecode(hdb);
- fprintf(stderr, "get error: %s\n", tchdberrmsg(ecode));
- }
-
- /* retrieve all records and mark them as seen */
- i=0;
- fp = fopen(argv[2], "r");
- if (!fp) {
- fprintf(stderr, "open %s file error\n", argv[2]);
- exit (1);
- }
- while (fgets(line, sizeof(line), fp)) {
- if (i++ != 200) {
- value = tchdbget3(hdb, line, strlen(line)+1, &elt, sizeof(elt));
- if (value > 0) {
- elt.seen=1;
- if (!tchdbputasync(hdb, line, strlen(line)+1, &elt, sizeof(elt))) {
- ecode = tchdbecode(hdb);
- fprintf(stderr, "put error: %s\n", tchdberrmsg(ecode));
- }
- } else {
- fprintf(stderr, "can't find %s in hash\n", line);
- }
- }
- }
- fclose(fp);
-
- ctime = get_current_time();
- fprintf(stderr, "marking as seen in %ims\n", (ctime - ttime)/1000);
- fprintf(res, "seen;%i\n", (ctime - ttime)/1000);
-
- /* traverse records */
- tchdbiterinit(hdb);
- while((key = tchdbiternext2(hdb)) != NULL){
- value = tchdbget3(hdb, key, strlen(key)+1, &elt, sizeof(elt));
- if (value > 0) {
- elt.seen=1; // check seen element
- } else {
- fprintf(stderr, "can't find %s in hash\n", line);
- }
- }
-
- ttime = get_current_time();
- fprintf(stderr, "checking not seen in %ims\n", (ttime - ctime)/1000);
- fprintf(res, "walk;%i\n", (ttime - ctime)/1000);
-
- /* close the database */
- if(!tchdbclose(hdb)){
- ecode = tchdbecode(hdb);
- fprintf(stderr, "close error: %s\n", tchdberrmsg(ecode));
- }
-
- /* delete the object */
- tchdbdel(hdb);
- struct stat statp;
- stat("casket.hdb", &statp);
- fprintf(res, "size;%lli\n", statp.st_size);
- unlink("casket.hdb");
- fclose(res);
- return 0;
-}