]> git.sur5r.net Git - bacula/bacula/commitdiff
Sort bsr records, use C++ structs, add volatile, fix shell character expansion, make...
authorKern Sibbald <kern@sibbald.com>
Fri, 23 May 2003 17:24:36 +0000 (17:24 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 23 May 2003 17:24:36 +0000 (17:24 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@534 91ce42f0-d328-0410-95d8-f526ca767f89

25 files changed:
bacula/ChangeLog
bacula/autoconf/configure.in
bacula/configure
bacula/kernstodo
bacula/src/cats/cats.h
bacula/src/dird/ua_restore.c
bacula/src/filed/win32/winevents.h
bacula/src/filed/win32/winservice.cpp
bacula/src/filed/win32/winservice.h
bacula/src/filed/win32/winstat.cpp
bacula/src/filed/win32/winstat.h
bacula/src/filed/win32/wintray.h
bacula/src/jcr.h
bacula/src/lib/bpipe.c
bacula/src/lib/bsock.h
bacula/src/lib/util.c
bacula/src/stored/Makefile.in
bacula/src/stored/block.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/mount.c
bacula/src/stored/status.c [new file with mode: 0644]
bacula/src/stored/stored_conf.h
bacula/src/version.h

index cb7065b9362c61a7e623733a0b39fe252024093e..a34e1ce554dbce0503aa03174cfeb40317fc25c6 100644 (file)
@@ -1,4 +1,4 @@
-2003-05-20 Version 1.31 Beta 22May03
+2003-05-22 Version 1.31 Beta 22May03
 - I discovered that C++ permits "prototyping" structures e.g. struct A; is
   a valid statement. This permitted me to eliminate all the void *jcr, in
   favor of JCR *jcr, which pointed out a number of bugs in block.c.
index 0286d742eba544e6409a30c43afbe962f7676bb0..9bb85499aa3197102cb4342fb32c60e2d3280eb1 100644 (file)
@@ -1164,6 +1164,7 @@ aix)
        PSCMD="ps -e -o pid,comm"
        PFILES="${PFILES} \
           platforms/aix/Makefile"
+       TAPEDRIVE="/dev/rmt0.1" 
   ;;     
 alpha)
        DISTVER=`uname -r`
index 52093d7ba09c46af86d03e207364464ee007264e..e0b638c5091cd3b52faa6dac68e630f4088b3bec 100755 (executable)
@@ -9466,6 +9466,7 @@ aix)
        PSCMD="ps -e -o pid,comm"
        PFILES="${PFILES} \
           platforms/aix/Makefile"
+       TAPEDRIVE="/dev/rmt0.1" 
   ;;     
 alpha)
        DISTVER=`uname -r`
index 299e2ca95dd4e17e0b2e79e0df3196e39834be39..8d9fc909a74a95c9585b11c09d7dd3ffb1b591c2 100644 (file)
@@ -25,6 +25,24 @@ Testing to do: (painful)
 - Figure out how to use ssh or stunnel to protect Bacula communications.
 
 For 1.31 release:
+- Add SDWriteSeqNo to SD, and probably Read on FD side.
+- Make sure all restore counters are working correctly in the FD.
+- When all cassettes in magazine are used, got:
+  22-May-2003 18:24 undef-sd: 3304 Autochanger "load slot 1" status is OK.
+  22-May-2003 18:24 undef-sd: NightlySave.2003-05-22_14.08.16 Warning: mount.c:245 Director wanted Volume "TestVolume0009".
+      Current Volume "TestVolume0005" not acceptable because:
+      1998 Volume "TestVolume0005" not Append or Recycle.
+  22-May-2003 18:24 undef-sd: NightlySave.2003-05-22_14.08.16 Error: Autochanger Volume "TestVolume0009" not found in slot 1.
+      Setting slot to zero in catalog.
+  22-May-2003 18:24 undef-sd: Please mount Volume "TestVolume0009" on Storage Device "ARCHIVE 4586" for Job NightlySave.2003-05-22_14
+  .08.16
+  Use "mount" command to release Job.
+  22-May-2003 19:24 undef-sd: Please mount Volume "TestVolume0009" on Storage Device "ARCHIVE 4586" for Job NightlySave.2003-05-22_14
+  .08.16
+  Use "mount" command to release Job.
+
+- SD Bytes Read is wrong.
+- Configure mtx-changer to have correct path to mtx.
 - Look at ALL higher level routines that call block.c to be sure
   they don't expect something in errmsg.
 - Fix Verify VolumeToCatalog to use BSRs -- it is broken.
index 17aaec9146407800b3bb88a42c84b9b17e5b985d..6e5ab105ff6f624ed428d1b61d661dcf9f443bf2 100644 (file)
@@ -279,7 +279,7 @@ typedef uint32_t JobId_t;
  * it also contains fields found in the JobMedia record.
  */
 /* Job record */
-typedef struct {
+struct JOB_DBR {
    JobId_t JobId;
    char Job[MAX_NAME_LENGTH];         /* Job unique name */
    char Name[MAX_NAME_LENGTH];        /* Job base name */
@@ -315,13 +315,13 @@ typedef struct {
    char cEndTime[MAX_TIME_LENGTH];
    /* Extra stuff not in DB */
    faddr_t rec_addr;
-} JOB_DBR;
+};
 
 /* Job Media information used to create the media records
  * for each Volume used for the job.
  */
 /* JobMedia record */
-typedef struct {
+struct JOBMEDIA_DBR {
    uint32_t JobMediaId;               /* record id */
    JobId_t  JobId;                    /* JobId */
    uint32_t MediaId;                  /* MediaId */
@@ -331,10 +331,11 @@ typedef struct {
    uint32_t EndFile;                  /* End file on Volume */
    uint32_t StartBlock;               /* start block on tape */
    uint32_t EndBlock;                 /* last block */
-} JOBMEDIA_DBR;
+};
+
 
 /* Volume Parameter structure */
-typedef struct {
+struct VOL_PARAMS {
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    uint32_t FirstIndex;               /* First index this Volume */
    uint32_t LastIndex;                /* Last index this Volume */
@@ -342,14 +343,14 @@ typedef struct {
    uint32_t EndFile;                  /* End file on Volume */
    uint32_t StartBlock;               /* start block on tape */
    uint32_t EndBlock;                 /* last block */
-} VOL_PARAMS;
+};
 
 
 /* Attributes record -- NOT same as in database because
  *  in general, this "record" creates multiple database
  *  records (e.g. pathname, filename, fileattributes).
  */
-typedef struct {
+struct ATTR_DBR {
    char *fname;                       /* full path & filename */
    char *link;                        /* link if any */
    char *attr;                        /* attributes statp */
@@ -360,11 +361,11 @@ typedef struct {
    uint32_t PathId;
    uint32_t FilenameId;
    FileId_t FileId;
-} ATTR_DBR;
+};
 
 
 /* File record -- same format as database */
-typedef struct {
+struct FILE_DBR {
    FileId_t FileId;
    uint32_t FileIndex;
    JobId_t  JobId;
@@ -375,10 +376,10 @@ typedef struct {
 /*   int Status; */
    char SIG[50];
    int SigType;                       /* NO_SIG/MD5_SIG/SHA1_SIG */
-} FILE_DBR;
+};
 
 /* Pool record -- same format as database */
-typedef struct {
+struct POOL_DBR {
    uint32_t PoolId;
    char Name[MAX_NAME_LENGTH];        /* Pool name */
    uint32_t NumVols;                  /* total number of volumes */
@@ -397,10 +398,10 @@ typedef struct {
    char LabelFormat[MAX_NAME_LENGTH];
    /* Extra stuff not in DB */
    faddr_t rec_addr;
-} POOL_DBR;
+};
 
 /* Media record -- same as the database */
-typedef struct {
+struct MEDIA_DBR {
    uint32_t MediaId;                  /* Unique volume id */
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    char MediaType[MAX_NAME_LENGTH];   /* Media type */
@@ -433,24 +434,24 @@ typedef struct {
    char    cFirstWritten[MAX_TIME_LENGTH];  /* FirstWritten returned from DB */
    char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
    char    cLabelData[MAX_TIME_LENGTH];  /* LabelData returned from DB */
-} MEDIA_DBR;
+};
 
 /* Client record -- same as the database */
-typedef struct {
+struct CLIENT_DBR {
    uint32_t ClientId;                 /* Unique Client id */
    int AutoPrune;
    utime_t FileRetention;
    utime_t JobRetention;
    char Name[MAX_NAME_LENGTH];        /* Client name */
    char Uname[256];                   /* Uname for client */
-} CLIENT_DBR;
+};
 
 /* FileSet record -- same as the database */
-typedef struct {
+struct FILESET_DBR {
    uint32_t FileSetId;                /* Unique FileSet id */
    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
    char MD5[50];                      /* MD5 signature of include/exclude */
-} FILESET_DBR;
+};
 
 
 #include "protos.h"
index c687b1b4e2d18b4f6888f892c8704cfa8357e7c6..c8d60d57e1f0f26f928b7f33f6a63319f9966ee0 100644 (file)
@@ -47,49 +47,56 @@ extern char *uar_sel_all_temp1, *uar_sel_fileset, *uar_mediatype;
 
 
 /* Context for insert_tree_handler() */
-typedef struct s_tree_ctx {
+struct TREE_CTX {
    TREE_ROOT *root;                  /* root */
    TREE_NODE *node;                  /* current node */
    TREE_NODE *avail_node;            /* unused node last insert */
    int cnt;                          /* count for user feedback */
    UAContext *ua;
-} TREE_CTX;
+};
 
 /* Main structure for obtaining JobIds */
-typedef struct s_jobids {
+struct JobIds {
    utime_t JobTDate;
    uint32_t TotalFiles;
    char ClientName[MAX_NAME_LENGTH];
    char JobIds[200];
    STORE  *store;
-} JobIds;
+};
 
 
-/* FileIndex entry in bootstrap record */
-typedef struct s_rbsr_findex {
-   struct s_rbsr_findex *next;
+/* FileIndex entry in restore bootstrap record */
+struct RBSR_FINDEX {
+   RBSR_FINDEX *next;
    int32_t findex;
    int32_t findex2;
-} RBSR_FINDEX;
-
-/* Restore bootstrap record -- not the real one, but useful here */
-typedef struct s_rbsr {
-   struct s_rbsr *next;              /* next JobId */
+};
+
+/* 
+ * Restore bootstrap record -- not the real one, but useful here   
+ *  The restore bsr is a chain of BSR records (linked by next).
+ *  Each BSR represents a single JobId, and within it, it
+ *    contains a linked list of file indexes for that JobId.
+ *    The complete_bsr() routine, will then add all the volumes
+ *    on which the Job is stored to the BSR.
+ */
+struct RBSR {
+   RBSR *next;                       /* next JobId */
    uint32_t JobId;                   /* JobId this bsr */
    uint32_t VolSessionId;                  
    uint32_t VolSessionTime;
    int     VolCount;                 /* Volume parameter count */
    VOL_PARAMS *VolParams;            /* Volume, start/end file/blocks */
    RBSR_FINDEX *fi;                  /* File indexes this JobId */
-} RBSR;
+};
 
-typedef struct s_name_ctx {
+struct NAME_LIST {
    char **name;                      /* list of names */
    int num_ids;                      /* ids stored */
    int max_ids;                      /* size of array */
    int num_del;                      /* number deleted */
    int tot_ids;                      /* total to process */
-} NAME_LIST;
+};
 
 #define MAX_ID_LIST_LEN 1000000
 
@@ -113,6 +120,7 @@ static void print_name_list(UAContext *ua, NAME_LIST *name_list);
 static int unique_name_list_handler(void *ctx, int num_fields, char **row);
 static void free_name_list(NAME_LIST *name_list);
 static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, JobIds *ji);
+static RBSR *sort_bsr(RBSR *bsr);
 
 
 /*
@@ -274,7 +282,7 @@ int restorecmd(UAContext *ua, char *cmd)
    if (where) {
       Mmsg(&ua->cmd, 
           "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
-          "where=\"%s\"",
+          " where=\"%s\"",
           job->hdr.name, ji.ClientName, ji.store?ji.store->hdr.name:"",
          working_directory, where);
    } else {
@@ -719,7 +727,6 @@ static int write_bsr_file(UAContext *ua, RBSR *bsr)
    FILE *fd;
    POOLMEM *fname = get_pool_memory(PM_MESSAGE);
    int stat;
-   RBSR *nbsr;
 
    Mmsg(&fname, "%s/restore.bsr", working_directory);
    fd = fopen(fname, "w+");
@@ -729,14 +736,19 @@ static int write_bsr_file(UAContext *ua, RBSR *bsr)
       free_pool_memory(fname);
       return 0;
    }
+   /* Sort the bsr chain */
+   bsr = sort_bsr(bsr);
+   /* Write them to file */
    write_bsr(ua, bsr, fd);
    stat = !ferror(fd);
    fclose(fd);
    bsendmsg(ua, _("Bootstrap records written to %s\n"), fname);
+
+   /* Tell the user what he will need to mount */
    bsendmsg(ua, _("\nThe restore job will require the following Volumes:\n"));
    /* Create Unique list of Volumes using prompt list */
    start_prompt(ua, "");
-   for (nbsr=bsr; nbsr; nbsr=nbsr->next) {
+   for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) {
       for (int i=0; i < nbsr->VolCount; i++) {
         add_prompt(ua, nbsr->VolParams[i].VolumeName);
       }
@@ -751,6 +763,40 @@ static int write_bsr_file(UAContext *ua, RBSR *bsr)
    return stat;
 }
 
+int comp_vol_params(const void *v1, const void *v2)
+{
+   VOL_PARAMS *vol1 = (VOL_PARAMS *)v1;
+   VOL_PARAMS *vol2 = (VOL_PARAMS *)v2;
+
+   if (vol1->FirstIndex < vol2->FirstIndex) {
+      return -1;
+   } else if (vol1->FirstIndex > vol2->FirstIndex) {
+      return 1;
+   } else {
+      return 0;
+   }
+}
+
+/*
+ * First sort the bsr chain, then sort the VolParams   
+ */
+static RBSR *sort_bsr(RBSR *bsr)
+{
+   if (!bsr) {
+      return bsr;
+   }
+   /* ****FIXME**** sort the bsr chain */
+   /* Sort the VolParams for each bsr */
+   for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) {
+      if (nbsr->VolCount > 1) {
+         Dmsg1(100, "VolCount=%d\n", nbsr->VolCount);
+        qsort((void *)nbsr->VolParams, nbsr->VolCount, sizeof(VOL_PARAMS), 
+              comp_vol_params);
+      }
+   }
+   return bsr;
+}
+
 static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
 {
    if (bsr) {
index 466760b3c76d39b676918f780c8dfc60b9db813e..a28d66e124b1b547efe8a64047487aebfe1f45de 100755 (executable)
@@ -1,21 +1,22 @@
 /* Object implementing the Events dialog for Bacula */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.
  */
 
 
index aa6bcafffcccdd18beebe890758bf776bd6a0c19..98cb4140dde1bbca04e49eacabd40cc4a9c32b2a 100755 (executable)
@@ -1,6 +1,6 @@
 //  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
 //
-//  This file is part of the VNC system.
+//  This file was part of the VNC system.
 //
 //  The VNC system is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
index 274799505619fd32e2ef983c57f5f1569a024ec3..589f94a54cc8726c7bb8cf2a2c7c1ebf624da6b0 100755 (executable)
@@ -1,6 +1,6 @@
 //  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
 //
-//  This file is part of the ups system.
+//  This file was part of the ups system.
 //
 //  The ups system is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
index f9415dfa0492ebf20f6d24792913305c15afe3a0..79da6dcc7ed8ecbdd3c68c82dd3e90aa6e2e9737 100755 (executable)
@@ -44,8 +44,8 @@ void
 bacStatus::Show(BOOL show)
 {
    if (show && !visible) {
-         DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_STATUS), NULL,
-             (DLGPROC)DialogProc, (LONG)this);
+      DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_STATUS), NULL,
+          (DLGPROC)DialogProc, (LONG)this);
    }
 }
 
index 008ad56e44bcda22009e55c0dddeedde2e197c12..e5c29a859ba31b96ae3efab82d70f1949576283e 100755 (executable)
@@ -3,22 +3,23 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.
  */
 
 
index 34b422a518124649aa4528b8703648b114376d73..0b210282af26938249d50cc99bcdf9a9b3698efb 100755 (executable)
@@ -1,6 +1,6 @@
 //  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
 //
-//  This file is part of the VNC system.
+//  This file was part of the VNC system.
 //
 //  The VNC system is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
index 4a2d72b174be030163ab9686be2f30a010609437..02bc36c4f9dff2b114e7059f60cd95f7f352b6c1 100644 (file)
@@ -92,7 +92,7 @@ struct JCR {
    BSOCK *store_bsock;                /* Storage connection socket */
    BSOCK *file_bsock;                 /* File daemon connection socket */
    JCR_free_HANDLER *daemon_free_jcr; /* Local free routine */
-   int use_count;                     /* use count */
+   volatile int use_count;            /* use count */
    POOLMEM *errmsg;                   /* edited error message */
    char Job[MAX_NAME_LENGTH];         /* Unique name of this Job */
    uint32_t JobId;                    /* Director's JobId */
@@ -103,7 +103,7 @@ struct JCR {
    uint64_t JobBytes;                 /* Number of bytes processed this job */
    uint64_t ReadBytes;                /* Bytes read -- before compression */
    uint32_t Errors;                   /* Number of non-fatal errors */
-   int JobStatus;                     /* ready, running, blocked, terminated */ 
+   volatile int JobStatus;            /* ready, running, blocked, terminated */ 
    int JobType;                       /* backup, restore, verify ... */
    int JobLevel;                      /* Job level */
    int authenticated;                 /* set when client authenticated */
@@ -126,7 +126,7 @@ struct JCR {
    pthread_t SD_msg_chan;             /* Message channel thread id */
    pthread_cond_t term_wait;          /* Wait for job termination */
    workq_ele_t *work_item;            /* Work queue item if scheduled */
-   int msg_thread_done;               /* Set when Storage message thread terms */
+   volatile int msg_thread_done;      /* Set when Storage message thread terms */
    BSOCK *ua;                         /* User agent */
    JOB *job;                          /* Job resource */
    STORE *store;                      /* Storage resource */
@@ -135,8 +135,8 @@ struct JCR {
    FILESET *fileset;                  /* FileSet resource */
    CAT *catalog;                      /* Catalog resource */
    MSGS *messages;                    /* Default message handler */
-   int SDJobStatus;                   /* Storage Job Status */
-   int FDJobStatus;                   /* File daemon Job Status */
+   volatile int SDJobStatus;          /* Storage Job Status */
+   volatile int FDJobStatus;          /* File daemon Job Status */
    int mode;                          /* manual/auto run */
    B_DB *db;                          /* database pointer */
    uint32_t MediaId;                  /* DB record IDs associated with this job */
@@ -180,7 +180,7 @@ struct JCR {
    uint32_t StartBlock;
    uint32_t EndBlock;
    pthread_t heartbeat_id;            /* id of heartbeat thread */
-   BSOCK *hb_bsock;                   /* duped SD socket */
+   volatile BSOCK *hb_bsock;          /* duped SD socket */
 #endif /* FILE_DAEMON */
 
 
index 975c5f6896f5efbec918dbbc07091f58a9f6c8f7..577fc4d188e60656a361e21e7893a69a3c318d8a 100644 (file)
@@ -78,7 +78,7 @@ BPIPE *open_bpipe(char *prog, int wait, char *mode)
    }
    /* Start worker process */
    switch (bpipe->worker_pid = fork()) {
-   case -1:
+   case -1:                          /* error */
       free(bpipe);
       return NULL;
 
index 5ca7d1ad7ec34dc70d434aa35d982bae38344205..92aa2596c5fad3e5fe090291aa6329fc80ca5cbc 100644 (file)
 
  */
 
-typedef struct s_bsock {
+struct BSOCK {
    uint64_t read_seqno;               /* read sequence number */
-   uint32_t in_msg_no;                /* intput message number */
+   uint32_t in_msg_no;                /* input message number */
    uint32_t out_msg_no;               /* output message number */
    int fd;                            /* socket file descriptor */
    int32_t msglen;                    /* message length */
    int port;                          /* desired port */
-   int errors;                        /* set if errors on socket */
-   int suppress_error_msgs;           /* set to suppress error messages */
+   volatile int errors;               /* set if errors on socket */
+   volatile int suppress_error_msgs;  /* set to suppress error messages */
    int b_errno;                       /* bsock errno */
-   time_t timer_start;                /* time started read/write */
-   int timed_out;                     /* timed out in read/write */
-   int timeout;                       /* time out after this value */
-   int terminated;                    /* set when BNET_TERMINATE arrives */
+   volatile time_t timer_start;       /* time started read/write */
+   volatile int timed_out;            /* timed out in read/write */
+   volatile int timeout;              /* time out after this value */
+   volatile int terminated;           /* set when BNET_TERMINATE arrives */
    int duped;                         /* set if duped BSOCK */
    POOLMEM *msg;                      /* message pool buffer */
    char *who;                         /* Name of daemon to which we are talking */
    char *host;                        /* Host name/IP */
    POOLMEM *errmsg;                   /* edited error message (to be implemented) */
    RES *res;                          /* Resource to which we are connected */
-   struct s_bsock *next;              /* next BSOCK if duped */
+   BSOCK *next;                       /* next BSOCK if duped */
    int spool;                         /* set for spooling */
    FILE *spool_fd;                    /* spooling file */
    JCR *jcr;                          /* jcr or NULL for error msgs */
-} BSOCK;
+};      
 
 /* Signal definitions for use in bnet_sig() */
 #define BNET_EOD         -1           /* End of data stream, new data may follow */
index 1d1b5258172a5a2f673146cd22940a517093b260..4433febb4f2e559190200a67100d50aeff7c6774 100644 (file)
@@ -440,10 +440,15 @@ int do_shell_expansion(char *name, int name_len)
           if ((shellcmd = getenv("SHELL")) == NULL) {
              shellcmd = "/bin/sh";
          }
-         close(1); dup(pfd[1]);          /* attach pipes to stdin and stdout */
+#ifdef xxx
+         close(1); dup(pfd[1]);          /* attach pipes to stdout and stderr */
          close(2); dup(pfd[1]);
          for (i = 3; i < 32; i++)        /* close everything else */
             close(i);
+#endif
+         close(pfd[0]);                  /* close stdin */
+         dup2(pfd[1], 1);                /* attach to stdout */
+         dup2(pfd[1], 2);                /* and stderr */
           strcpy(echout, "echo ");        /* form echo command */
          bstrncat(echout, name, sizeof(echout));
           execl(shellcmd, shellcmd, "-c", echout, NULL); /* give to shell */
@@ -452,7 +457,10 @@ int do_shell_expansion(char *name, int name_len)
        default:                          /* parent */
          /* read output from child */
          echout[0] = 0;
-         i = read(pfd[0], echout, sizeof echout);
+         do {
+            i = read(pfd[0], echout, sizeof echout);
+         } while (i == -1 && errno == EINTR); 
+
          if (i > 0) {
             echout[--i] = 0;                /* set end of string */
             /* look for first line. */
index 753f91b1623947960b7bf2bc13ccc249ad3b0475..df205d0487612423045f536f356138e415708fc6 100644 (file)
@@ -23,13 +23,13 @@ SVRSRCS = stored.c autochanger.c acquire.c append.c \
          block.c dev.c \
          device.c dircmd.c fd_cmds.c job.c \
          label.c match_bsr.c parse_bsr.c \
-         read.c record.c stored_conf.c mount.c
+         read.c record.c status.c stored_conf.c mount.c
 SVROBJS = stored.o autochanger.o acquire.o append.o \
          askdir.o authenticate.o \
          block.o dev.o \
          device.o dircmd.o fd_cmds.o job.o \
          label.o match_bsr.o mount.o parse_bsr.o \
-         read.o record.o stored_conf.o
+         read.o record.o status.o stored_conf.o
 
 # btape
 TAPESRCS = btape.c block.c butil.c dev.c device.c label.c \
index c95096aa0f9e1cf036dc47ca400746849bf85621..6ca1575d83b4f456bbb1006f774991a4778d27e4 100644 (file)
@@ -395,7 +395,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
         wlen, stat, dev->dev_errno, strerror(dev->dev_errno));
 
       if (stat == -1) {
-         Jmsg2(jcr, M_ERROR, 0, _("Write error on device %s. ERR=%s.\n"), 
+         Jmsg(jcr, M_ERROR, 0, _("Write error on device %s. ERR=%s.\n"), 
            dev->dev_name, strerror(dev->dev_errno));
       } else {
          Jmsg3(jcr, M_INFO, 0, _("End of media on device %s. Write of %u bytes got %d.\n"), 
index 98eada35dc8e7caea1cac003c8a7489540073d23..d7f5e56a9dce8309a99edb5b60c7b685307a1568 100644 (file)
@@ -521,7 +521,7 @@ status_dev(DEVICE *dev, uint32_t *status)
 
    if (dev->state & (ST_EOT | ST_WEOT)) {
       stat |= BMT_EOD;
-      Dmsg0(-20, " EOD");
+      Dmsg0(-20, " EOD-");
    }
    if (dev->state & ST_EOF) {
       stat |= BMT_EOF;
@@ -558,7 +558,7 @@ status_dev(DEVICE *dev, uint32_t *status)
       }
       if (GMT_EOD(mt_stat.mt_gstat)) {
         stat |= BMT_EOD;
-         Dmsg0(-20, " EOD");
+         Dmsg0(-20, " EOD+");
       }
       if (GMT_WR_PROT(mt_stat.mt_gstat)) {
         stat |= BMT_WR_PROT;
@@ -1191,25 +1191,22 @@ term_dev(DEVICE *dev)
 }
 
 
-/* To make following two functions more readable */
-
-#define attached_jcrs ((JCR *)(dev->attached_jcrs))
 
 void attach_jcr_to_device(DEVICE *dev, JCR *jcr)
 {
-   jcr->prev_dev = NULL;
-   jcr->next_dev = attached_jcrs;
-   if (attached_jcrs) {
-      attached_jcrs->prev_dev = jcr;
+   jcr->prev_dev = (JCR *)NULL;
+   jcr->next_dev = dev->attached_jcrs;
+   if (dev->attached_jcrs) {
+      dev->attached_jcrs->prev_dev = jcr;
    }
-   attached_jcrs = jcr;
+   dev->attached_jcrs = jcr;
    Dmsg1(100, "Attached Job %s\n", jcr->Job);
 }
 
 void detach_jcr_from_device(DEVICE *dev, JCR *jcr)
 {
    if (!jcr->prev_dev) {
-      attached_jcrs = jcr->next_dev;
+      dev->attached_jcrs = jcr->next_dev;
    } else {
       jcr->prev_dev->next_dev = jcr->next_dev;
    }
@@ -1222,8 +1219,8 @@ void detach_jcr_from_device(DEVICE *dev, JCR *jcr)
 
 JCR *next_attached_jcr(DEVICE *dev, JCR *jcr)
 {
-   if (jcr == NULL) {
-      return attached_jcrs;
+   if (jcr == (JCR *)NULL) {
+      return dev->attached_jcrs;
    }
    return jcr->next_dev;
 }
index 515ef7df096b1628be4fd5101e658128b5338c86..449fd78994d9ebc8492b7ade521ec422d21a0929 100644 (file)
@@ -139,12 +139,13 @@ typedef struct s_steal_lock {
    int               dev_blocked;     /* state */
 } bsteal_lock_t;
 
+struct DEVRES;                        /* Device resource defined in stored_conf.h */
 
 /* Device structure definition */
-typedef struct s_device {
-   struct s_device *next;             /* pointer to next open device */
-   struct s_device *prev;             /* pointer to prev open device */
-   void *attached_jcrs;               /* attached JCR list */
+struct DEVICE {
+   DEVICE *next;                      /* pointer to next open device */
+   DEVICE *prev;                      /* pointer to prev open device */
+   JCR *attached_jcrs;              /* attached JCR list */
    pthread_mutex_t mutex;             /* access control */
    pthread_cond_t wait;               /* thread wait variable */
    pthread_cond_t wait_next_vol;      /* wait for tape to be mounted */
@@ -173,44 +174,15 @@ typedef struct s_device {
    uint32_t max_rewind_wait;          /* max secs to allow for rewind */
    uint32_t max_open_wait;            /* max secs to allow for open */
    uint32_t max_open_vols;            /* max simultaneous open volumes */
-   void *device;                      /* pointer to Device Resource */
+   DEVRES *device;                    /* pointer to Device Resource */
    btimer_id tid;                     /* timer id */
 
    VOLUME_CAT_INFO VolCatInfo;        /* Volume Catalog Information */
    VOLUME_LABEL VolHdr;               /* Actual volume label */
 
-} DEVICE;
+};
 
 
-
-
-#ifdef SunOS
-#define DEFAULT_TAPE_DRIVE "/dev/rmt/0cbn"
-#endif
-#ifdef AIX
-#define DEFAULT_TAPE_DRIVE "/dev/rmt0.1"
-#endif
-#ifdef SGI
-#define DEFAULT_TAPE_DRIVE "/dev/tps0d4nr"
-#endif
-#ifdef Linux
-#define DEFAULT_TAPE_DRIVE "/dev/nst0"
-#endif
-#ifdef OSF
-#define DEFAULT_TAPE_DRIVE "/dev/nrmt0"
-#endif
-#ifdef HPUX
-#define DEFAULT_TAPE_DRIVE "/dev/rmt/0hnb"
-#endif
-#ifdef FreeBSD
-#define DEFAULT_TAPE_DRIVE "/dev/nrst0"
-#endif
-
-/* Default default */
-#ifndef DEFAULT_TAPE_DRIVE
-#define DEFAULT_TAPE_DRIVE "/dev/nst0"
-#endif
-
 /* Get some definition of function to position
  *  to the end of the medium in MTEOM. System
  *  dependent. Arrgggg!
index a62a3157361f30c7b608f09617579b4d65c4fd25..433940f7a2f109397b1504365c9231b125322e09 100644 (file)
@@ -59,6 +59,7 @@ static char OKsetdebug[]   = "3000 OK setdebug=%d\n";
 /* Imported functions */
 extern void terminate_child();
 extern int job_cmd(JCR *jcr);
+extern int status_cmd(JCR *sjcr);
 
 /* Forward referenced functions */
 static int label_cmd(JCR *jcr);
@@ -67,13 +68,11 @@ static int setdebug_cmd(JCR *jcr);
 static int cancel_cmd(JCR *cjcr);
 static int mount_cmd(JCR *jcr);
 static int unmount_cmd(JCR *jcr);
-static int status_cmd(JCR *sjcr);
 static int autochanger_cmd(JCR *sjcr);
 static int do_label(JCR *jcr, int relabel);
 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
                               char *newname, char *poolname, 
                               int Slot, int relabel);
-static void send_blocked_status(JCR *jcr, DEVICE *dev);
 
 struct s_cmds {
    char *cmd;
@@ -666,157 +665,6 @@ static int unmount_cmd(JCR *jcr)
    return 1;
 }
 
-/*
- * Status command from Director
- */
-static int status_cmd(JCR *jcr)
-{
-   DEVRES *device;
-   DEVICE *dev;
-   int found, bps, sec, bpb;
-   BSOCK *user = jcr->dir_bsock;
-   char dt[MAX_TIME_LENGTH];
-   char b1[30], b2[30], b3[30];
-
-   bnet_fsend(user, "\n%s Version: " VERSION " (" BDATE ")\n", my_name);
-   bstrftime(dt, sizeof(dt), daemon_start_time);
-   bnet_fsend(user, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
-        last_job.NumJobs == 1 ? "" : "s");
-   if (last_job.NumJobs > 0) {
-      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);
-   }
-
-   LockRes();
-   for (device=NULL;  (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
-      for (dev=device->dev; dev; dev=dev->next) {
-        if (dev->state & ST_OPENED) {
-           if (dev->state & ST_LABEL) {
-               bnet_fsend(user, _("Device %s is mounted with Volume \"%s\"\n"), 
-                 dev_name(dev), dev->VolHdr.VolName);
-           } else {
-               bnet_fsend(user, _("Device %s open but no Bacula volume is mounted.\n"), dev_name(dev));
-           }
-           send_blocked_status(jcr, dev);
-           if (dev->state & ST_APPEND) {
-              bpb = dev->VolCatInfo.VolCatBlocks;
-              if (bpb <= 0) {
-                 bpb = 1;
-              }
-              bpb = dev->VolCatInfo.VolCatBytes / bpb;
-               bnet_fsend(user, _("    Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2), 
-                 edit_uint64_with_commas(bpb, b3));
-           } else {  /* reading */
-              bpb = dev->VolCatInfo.VolCatReads;
-              if (bpb <= 0) {
-                 bpb = 1;
-              }
-              bpb = dev->VolCatInfo.VolCatRBytes / bpb;
-               bnet_fsend(user, _("    Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2), 
-                 edit_uint64_with_commas(bpb, b3));
-           }
-            bnet_fsend(user, _("    Positioned at File=%s Block=%s\n"), 
-              edit_uint64_with_commas(dev->file, b1),
-              edit_uint64_with_commas(dev->block_num, b2));
-
-        } else {
-            bnet_fsend(user, _("Device %s is not open.\n"), dev_name(dev));
-           send_blocked_status(jcr, dev);
-        }
-      }
-   }
-   UnlockRes();
-
-   found = 0;
-   lock_jcr_chain();
-   /* NOTE, we reuse a calling argument jcr. Be warned! */ 
-   for (jcr=NULL; (jcr=get_next_jcr(jcr)); ) {
-      if (jcr->JobStatus == JS_WaitFD) {
-         bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-           job_type_to_str(jcr->JobType), jcr->Job);
-      }
-      if (jcr->device) {
-         bnet_fsend(user, _("%s %s job %s is using device %s volume %s\n"), 
-                  job_level_to_str(jcr->JobLevel),
-                  job_type_to_str(jcr->JobType),
-                  jcr->Job, jcr->device->device_name,
-                  jcr->VolumeName);
-        sec = time(NULL) - jcr->run_time;
-        if (sec <= 0) {
-           sec = 1;
-        }
-        bps = jcr->JobBytes / sec;
-         bnet_fsend(user, _("    Files=%s Bytes=%s Bytes/sec=%s\n"), 
-           edit_uint64_with_commas(jcr->JobFiles, b1),
-           edit_uint64_with_commas(jcr->JobBytes, b2),
-           edit_uint64_with_commas(bps, b3));
-        found = 1;
-#ifdef DEBUG
-        if (jcr->file_bsock) {
-            bnet_fsend(user, "    FDReadSeqNo=%" lld " fd=%d\n", 
-              jcr->file_bsock->read_seqno, jcr->file_bsock->fd);
-        } else {
-            bnet_fsend(user, "    FDSocket closed\n");
-        }
-#endif
-      }
-      free_locked_jcr(jcr);
-   }
-   unlock_jcr_chain();
-   if (!found) {
-      bnet_fsend(user, _("No jobs running.\n"));
-   }
-
-#ifdef full_status
-   bnet_fsend(user, "\n\n");
-   dump_resource(R_DEVICE, resources[R_DEVICE-r_first].res_head, sendit, user);
-#endif
-   bnet_fsend(user, "====\n");
-
-   bnet_sig(user, BNET_EOD);
-   return 1;
-}
-
-static void send_blocked_status(JCR *jcr, DEVICE *dev) 
-{
-   BSOCK *user = jcr->dir_bsock;
-
-   switch (dev->dev_blocked) {
-      case BST_UNMOUNTED:
-         bnet_fsend(user, _("    Device is BLOCKED. User unmounted.\n"));
-        break;
-      case BST_UNMOUNTED_WAITING_FOR_SYSOP:
-         bnet_fsend(user, _("    Device is BLOCKED. User unmounted during wait for media/mount.\n"));
-        break;
-      case BST_WAITING_FOR_SYSOP:
-        if (jcr->JobStatus == JS_WaitMount) {
-            bnet_fsend(user, _("    Device is BLOCKED waiting for mount.\n"));
-        } else {
-            bnet_fsend(user, _("    Device is BLOCKED waiting for appendable media.\n"));
-        }
-        break;
-      case BST_DOING_ACQUIRE:
-         bnet_fsend(user, _("    Device is being initialized.\n"));
-        break;
-      case BST_WRITING_LABEL:
-         bnet_fsend(user, _("    Device is blocked labeling a Volume.\n"));
-        break;
-      default:
-        break;
-   }
-}
 
 /*
  * Autochanger command from Director
index eb37ee80fb09f5162f754983c0109604099476f1..e02f791944c982fe6acfa71d0512847a951b0a4d 100644 (file)
@@ -306,6 +306,7 @@ mount_error:
       dev->VolCatInfo.VolCatFiles = 0;
       dev->VolCatInfo.VolCatErrors = 0;
       dev->VolCatInfo.VolCatBlocks = 0;
+      dev->VolCatInfo.VolCatRBytes = 0;
       if (recycle) {
         dev->VolCatInfo.VolCatMounts++;  
         dev->VolCatInfo.VolCatRecycles++;
diff --git a/bacula/src/stored/status.c b/bacula/src/stored/status.c
new file mode 100644 (file)
index 0000000..53401ed
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *  This file handles the status command
+ *
+ *     Kern Sibbald, May MMIII
+ *
+ *   Version $Id$
+ *  
+ */
+/*
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "stored.h"
+
+/* Exported variables */
+
+/* Imported variables */
+extern BSOCK *filed_chan;
+extern int r_first, r_last;
+extern struct s_res resources[];
+extern char my_name[];
+extern time_t daemon_start_time;
+extern struct s_last_job last_job;
+
+/* Static variables */
+
+
+/* Forward referenced functions */
+static void send_blocked_status(JCR *jcr, DEVICE *dev);
+
+
+/*
+ * Status command from Director
+ */
+int status_cmd(JCR *jcr)
+{
+   DEVRES *device;
+   DEVICE *dev;
+   int found, bps, sec, bpb;
+   BSOCK *user = jcr->dir_bsock;
+   char dt[MAX_TIME_LENGTH];
+   char b1[30], b2[30], b3[30];
+
+   bnet_fsend(user, "\n%s Version: " VERSION " (" BDATE ")\n", my_name);
+   bstrftime(dt, sizeof(dt), daemon_start_time);
+   bnet_fsend(user, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs,
+        last_job.NumJobs == 1 ? "" : "s");
+   if (last_job.NumJobs > 0) {
+      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);
+   }
+
+   LockRes();
+   for (device=NULL;  (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
+      for (dev=device->dev; dev; dev=dev->next) {
+        if (dev->state & ST_OPENED) {
+           if (dev->state & ST_LABEL) {
+               bnet_fsend(user, _("Device %s is mounted with Volume \"%s\"\n"), 
+                 dev_name(dev), dev->VolHdr.VolName);
+           } else {
+               bnet_fsend(user, _("Device %s open but no Bacula volume is mounted.\n"), dev_name(dev));
+           }
+           send_blocked_status(jcr, dev);
+           if (dev->state & ST_APPEND) {
+              bpb = dev->VolCatInfo.VolCatBlocks;
+              if (bpb <= 0) {
+                 bpb = 1;
+              }
+              bpb = dev->VolCatInfo.VolCatBytes / bpb;
+               bnet_fsend(user, _("    Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
+                 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
+                 edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2), 
+                 edit_uint64_with_commas(bpb, b3));
+           } else {  /* reading */
+              bpb = dev->VolCatInfo.VolCatReads;
+              if (bpb <= 0) {
+                 bpb = 1;
+              }
+              bpb = dev->VolCatInfo.VolCatRBytes / bpb;
+               bnet_fsend(user, _("    Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"),
+                 edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
+                 edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2), 
+                 edit_uint64_with_commas(bpb, b3));
+           }
+            bnet_fsend(user, _("    Positioned at File=%s Block=%s\n"), 
+              edit_uint64_with_commas(dev->file, b1),
+              edit_uint64_with_commas(dev->block_num, b2));
+
+        } else {
+            bnet_fsend(user, _("Device %s is not open.\n"), dev_name(dev));
+           send_blocked_status(jcr, dev);
+        }
+      }
+   }
+   UnlockRes();
+
+   found = 0;
+   lock_jcr_chain();
+   /* NOTE, we reuse a calling argument jcr. Be warned! */ 
+   for (jcr=NULL; (jcr=get_next_jcr(jcr)); ) {
+      if (jcr->JobStatus == JS_WaitFD) {
+         bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
+           job_type_to_str(jcr->JobType), jcr->Job);
+      }
+      if (jcr->device) {
+         bnet_fsend(user, _("%s %s job %s is using device %s volume %s\n"), 
+                  job_level_to_str(jcr->JobLevel),
+                  job_type_to_str(jcr->JobType),
+                  jcr->Job, jcr->device->device_name,
+                  jcr->VolumeName);
+        sec = time(NULL) - jcr->run_time;
+        if (sec <= 0) {
+           sec = 1;
+        }
+        bps = jcr->JobBytes / sec;
+         bnet_fsend(user, _("    Files=%s Bytes=%s Bytes/sec=%s\n"), 
+           edit_uint64_with_commas(jcr->JobFiles, b1),
+           edit_uint64_with_commas(jcr->JobBytes, b2),
+           edit_uint64_with_commas(bps, b3));
+        found = 1;
+#ifdef DEBUG
+        if (jcr->file_bsock) {
+            bnet_fsend(user, "    FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n", 
+              edit_uint64_with_commas(jcr->file_bsock->read_seqno, b1),
+              jcr->file_bsock->in_msg_no, jcr->file_bsock->out_msg_no,
+              jcr->file_bsock->fd);
+        } else {
+            bnet_fsend(user, "    FDSocket closed\n");
+        }
+#endif
+      }
+      free_locked_jcr(jcr);
+   }
+   unlock_jcr_chain();
+   if (!found) {
+      bnet_fsend(user, _("No jobs running.\n"));
+   }
+
+#ifdef full_status
+   bnet_fsend(user, "\n\n");
+   dump_resource(R_DEVICE, resources[R_DEVICE-r_first].res_head, sendit, user);
+#endif
+   bnet_fsend(user, "====\n");
+
+   bnet_sig(user, BNET_EOD);
+   return 1;
+}
+
+static void send_blocked_status(JCR *jcr, DEVICE *dev) 
+{
+   BSOCK *user = jcr->dir_bsock;
+
+   switch (dev->dev_blocked) {
+   case BST_UNMOUNTED:
+      bnet_fsend(user, _("    Device is BLOCKED. User unmounted.\n"));
+      break;
+   case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+      bnet_fsend(user, _("    Device is BLOCKED. User unmounted during wait for media/mount.\n"));
+      break;
+   case BST_WAITING_FOR_SYSOP:
+      if (jcr->JobStatus == JS_WaitMount) {
+         bnet_fsend(user, _("    Device is BLOCKED waiting for mount.\n"));
+      } else {
+         bnet_fsend(user, _("    Device is BLOCKED waiting for appendable media.\n"));
+      }
+      break;
+   case BST_DOING_ACQUIRE:
+      bnet_fsend(user, _("    Device is being initialized.\n"));
+      break;
+   case BST_WRITING_LABEL:
+      bnet_fsend(user, _("    Device is blocked labeling a Volume.\n"));
+      break;
+   default:
+      break;
+}
+}
index 91d2560896fe73aec009991d096bed244c0f7128..9dcd977b1eb65fe81288327c5776d2857a39ca38 100644 (file)
 #define R_BACKUP                      3024
 
 /* Definition of the contents of each Resource */
-struct s_res_dir {
+struct DIRRES {
    RES   hdr;
 
    char *password;                    /* Director password */
    char *address;                     /* Director IP address or zero */
    int enable_ssl;                    /* Use SSL with this Director */
 };
-typedef struct s_res_dir DIRRES;
 
 
 /* Storage daemon "global" definitions */
@@ -69,7 +68,7 @@ struct s_res_store {
 typedef struct s_res_store STORES;
 
 /* Device specific definitions */
-struct s_res_dev {
+struct DEVRES {
    RES   hdr;
 
    char *media_type;                  /* User assigned media type */
@@ -90,13 +89,11 @@ struct s_res_dev {
    int64_t volume_capacity;           /* advisory capacity */
    DEVICE *dev;                       /* Pointer to phyical dev -- set at runtime */
 };
-typedef struct s_res_dev DEVRES;
-
-union u_res {
-   struct s_res_dir     res_dir;
-   struct s_res_store   res_store;
-   struct s_res_dev     res_dev;
-   struct s_res_msgs    res_msgs;
-   RES hdr;
+
+union URES {
+   DIRRES res_dir;
+   STORES res_store;
+   DEVRES res_dev;
+   MSGS   res_msgs;
+   RES    hdr;
 };
-typedef union u_res URES;
index 87157f7780d31266ed904bc0124d4c278ad1239a..6e82990dd3b5cf4ffa388553cb8346610789d13d 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.31"
 #define VSTRING "1"
-#define BDATE   "22 May 2003"
-#define LSMDATE "22May03"
+#define BDATE   "23 May 2003"
+#define LSMDATE "23May03"
 
 /* Debug flags */
 #define DEBUG 1