]> git.sur5r.net Git - bacula/bacula/commitdiff
- Implement IBM labels
authorKern Sibbald <kern@sibbald.com>
Sat, 12 Mar 2005 15:40:41 +0000 (15:40 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 12 Mar 2005 15:40:41 +0000 (15:40 +0000)
- Implement EOF and EOV labels at the end of a volume.
- Fix a rather ugly problem with the PoolId not getting
  passed correctly. Now the DIR passes the Pool name and
  Media Type to the SD, who passes them back when requesting
  the next Volume. The DIR then looks up the correct PoolId.
  This takes more time, but always works, AND allows wild
  card Media Types (i.e. the SD can decide).
- The DIR <==> SD protocol has changed.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1885 91ce42f0-d328-0410-95d8-f526ca767f89

14 files changed:
bacula/kernstodo
bacula/src/cats/protos.h
bacula/src/cats/sql_get.c
bacula/src/dird/catreq.c
bacula/src/stored/Makefile.in
bacula/src/stored/acquire.c
bacula/src/stored/ansi_label.c
bacula/src/stored/askdir.c
bacula/src/stored/block.c
bacula/src/stored/dev.c
bacula/src/stored/ebcdic.c
bacula/src/stored/label.c
bacula/src/stored/protos.h
bacula/src/version.h

index 8aa0c2348883053c4438e4a2eef9615b9aa19079..4585e5ad2d7993f236fdf6ce91e6b168b5b68743 100644 (file)
@@ -1,5 +1,5 @@
                     Kern's ToDo List
-                     07 March 2005
+                     11 March 2005
 
 Major development:      
 Project                     Developer
index 0022b75d181e96a090554fdadaca94f31869e060..2712ed76a6a487612800b25279a3eaa98a2e7a90 100644 (file)
@@ -34,8 +34,8 @@
 
 /* sql.c */
 B_DB *db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
-                      const char *db_address, int db_port, const char *db_socket,
-                      int mult_db_connections);
+                       const char *db_address, int db_port, const char *db_socket,
+                       int mult_db_connections);
 int  db_open_database(JCR *jcr, B_DB *db);
 void db_close_database(JCR *jcr, B_DB *db);
 void db_escape_string(char *snew, char *old, int len);
@@ -70,7 +70,7 @@ int db_find_next_volume(JCR *jcr, B_DB *mdb, int index, bool InChanger, MEDIA_DB
 bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel);
 
 /* get.c */
-int db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
+bool db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
 int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames);
index c7fbea4b8bb19c42675716445cd560771524554f..da17f306955e432bc78b904d12f20fae8fa0d782 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Bacula Catalog Database Get record interface routines
  *  Note, these routines generally get a record by id or
- *       by name.  If more logic is involved, the routine
- *       should be in find.c
+ *        by name.  If more logic is involved, the routine
+ *        should be in find.c
  *
  *    Kern Sibbald, March 2000
  *
@@ -33,7 +33,7 @@
 /* The following is necessary so that we do not include
  * the dummy external definition of DB.
  */
-#define __SQL_C                      /* indicate that this is sql.c */
+#define __SQL_C                       /* indicate that this is sql.c */
 
 #include "bacula.h"
 #include "cats.h"
@@ -65,7 +65,7 @@ extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
  * (with attributes) in the database.
  *
  *  Returns: 0 on failure
- *          1 on success with the File record in FILE_DBR
+ *           1 on success with the File record in FILE_DBR
  */
 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
 {
@@ -90,7 +90,7 @@ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr,
 /*
  * Get a File record
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  *
  *  DO NOT use Jmsg in this routine.
  *
@@ -133,21 +133,21 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
       Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows);
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
-           mdb->num_rows);
+            mdb->num_rows);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
-        } else {
-           fdbr->FileId = (FileId_t)str_to_int64(row[0]);
-           bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
-           bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG));
-           stat = 1;
-        }
+         } else {
+            fdbr->FileId = (FileId_t)str_to_int64(row[0]);
+            bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
+            bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG));
+            stat = 1;
+         }
       } else {
          Mmsg2(&mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"),
-           edit_int64(fdbr->PathId, ed1), 
-           edit_int64(fdbr->FilenameId, ed2));
+            edit_int64(fdbr->PathId, ed1), 
+            edit_int64(fdbr->FilenameId, ed2));
       }
       sql_free_result(mdb);
    } else {
@@ -159,7 +159,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
 
 /* Get Filename record
  * Returns: 0 on failure
- *         FilenameId on success
+ *          FilenameId on success
  *
  *   DO NOT use Jmsg in this routine (see notes for get_file_record)
  */
@@ -177,20 +177,20 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"),
-           edit_uint64(mdb->num_rows, ed1), mdb->fname);
+            edit_uint64(mdb->num_rows, ed1), mdb->fname);
          Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-        } else {
-           FilenameId = atoi(row[0]);
-           if (FilenameId <= 0) {
+         } else {
+            FilenameId = atoi(row[0]);
+            if (FilenameId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
-                 mdb->cmd, FilenameId);
-              FilenameId = 0;
-           }
-        }
+                  mdb->cmd, FilenameId);
+               FilenameId = 0;
+            }
+         }
       } else {
          Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname);
       }
@@ -203,7 +203,7 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb)
 
 /* Get path record
  * Returns: 0 on failure
- *         PathId on success
+ *          PathId on success
  *
  *   DO NOT use Jmsg in this routine (see notes for get_file_record)
  */
@@ -227,28 +227,28 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
-           edit_uint64(mdb->num_rows, ed1), mdb->path);
+            edit_uint64(mdb->num_rows, ed1), mdb->path);
          Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       /* Even if there are multiple paths, take the first one */
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-        } else {
-           PathId = atoi(row[0]);
-           if (PathId <= 0) {
+         } else {
+            PathId = atoi(row[0]);
+            if (PathId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %s\n"),
-                 mdb->cmd, edit_int64(PathId, ed1));
-              PathId = 0;
-           } else {
-              /* Cache path */
-              if (PathId != mdb->cached_path_id) {
-                 mdb->cached_path_id = PathId;
-                 mdb->cached_path_len = mdb->pnl;
-                 pm_strcpy(&mdb->cached_path, mdb->path);
-              }
-           }
-        }
+                  mdb->cmd, edit_int64(PathId, ed1));
+               PathId = 0;
+            } else {
+               /* Cache path */
+               if (PathId != mdb->cached_path_id) {
+                  mdb->cached_path_id = PathId;
+                  mdb->cached_path_len = mdb->pnl;
+                  pm_strcpy(&mdb->cached_path, mdb->path);
+               }
+            }
+         }
       } else {
          Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path);
       }
@@ -263,7 +263,7 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
 /*
  * Get Job record for given JobId or Job name
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 {
@@ -281,18 +281,18 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
 "Type,Level,ClientId "
 "FROM Job WHERE JobId=%s", 
-         edit_int64(jr->JobId, ed1));
+          edit_int64(jr->JobId, ed1));
     }
 
    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
       db_unlock(mdb);
-      return 0;                      /* failed */
+      return 0;                       /* failed */
    }
    if ((row = sql_fetch_row(mdb)) == NULL) {
       Mmsg1(&mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1));
       sql_free_result(mdb);
       db_unlock(mdb);
-      return 0;                      /* failed */
+      return 0;                       /* failed */
    }
 
    jr->VolSessionId = str_to_uint64(row[0]);
@@ -317,10 +317,10 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 /*
  * Find VolumeNames for a given JobId
  *  Returns: 0 on error or no Volumes found
- *          number of volumes on success
- *             Volumes are concatenated in VolumeNames
- *             separated by a vertical bar (|) in the order
- *             that they were written.
+ *           number of volumes on success
+ *              Volumes are concatenated in VolumeNames
+ *              separated by a vertical bar (|) in the order
+ *              that they were written.
  *
  *  Returns: number of volumes on success
  */
@@ -346,22 +346,22 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
          Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
-        stat = 0;
+         stat = 0;
       } else {
-        stat = mdb->num_rows;
-        for (i=0; i < stat; i++) {
-           if ((row = sql_fetch_row(mdb)) == NULL) {
+         stat = mdb->num_rows;
+         for (i=0; i < stat; i++) {
+            if ((row = sql_fetch_row(mdb)) == NULL) {
                Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
                Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-              stat = 0;
-              break;
-           } else {
-              if (*VolumeNames[0] != 0) {
+               stat = 0;
+               break;
+            } else {
+               if (*VolumeNames[0] != 0) {
                   pm_strcat(VolumeNames, "|");
-              }
-              pm_strcat(VolumeNames, row[0]);
-           }
-        }
+               }
+               pm_strcat(VolumeNames, row[0]);
+            }
+         }
       }
       sql_free_result(mdb);
    } else {
@@ -374,8 +374,8 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume
 /*
  * Find Volume parameters for a give JobId
  *  Returns: 0 on error or no Volumes found
- *          number of volumes on success
- *          List of Volumes and start/end file/blocks (malloced structure!)
+ *           number of volumes on success
+ *           List of Volumes and start/end file/blocks (malloced structure!)
  *
  *  Returns: number of volumes on success
  */
@@ -393,7 +393,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
 "JobMedia.EndFile,StartBlock,JobMedia.EndBlock"
 " FROM JobMedia,Media WHERE JobMedia.JobId=%s"
 " AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId",
-       edit_int64(JobId, ed1));
+        edit_int64(JobId, ed1));
 
    Dmsg1(130, "VolNam=%s\n", mdb->cmd);
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
@@ -401,29 +401,29 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
          Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
-        stat = 0;
+         stat = 0;
       } else {
-        stat = mdb->num_rows;
-        if (stat > 0) {
-           *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS));
-        }
-        for (i=0; i < stat; i++) {
-           if ((row = sql_fetch_row(mdb)) == NULL) {
+         stat = mdb->num_rows;
+         if (stat > 0) {
+            *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS));
+         }
+         for (i=0; i < stat; i++) {
+            if ((row = sql_fetch_row(mdb)) == NULL) {
                Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
                Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-              stat = 0;
-              break;
-           } else {
-              bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
-              bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
-              Vols[i].FirstIndex = str_to_uint64(row[2]);
-              Vols[i].LastIndex = str_to_uint64(row[3]);
-              Vols[i].StartFile = str_to_uint64(row[4]);
-              Vols[i].EndFile = str_to_uint64(row[5]);
-              Vols[i].StartBlock = str_to_uint64(row[6]);
-              Vols[i].EndBlock = str_to_uint64(row[7]);
-           }
-        }
+               stat = 0;
+               break;
+            } else {
+               bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
+               bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
+               Vols[i].FirstIndex = str_to_uint64(row[2]);
+               Vols[i].LastIndex = str_to_uint64(row[3]);
+               Vols[i].StartFile = str_to_uint64(row[4]);
+               Vols[i].EndFile = str_to_uint64(row[5]);
+               Vols[i].StartBlock = str_to_uint64(row[6]);
+               Vols[i].EndBlock = str_to_uint64(row[7]);
+            }
+         }
       }
       sql_free_result(mdb);
    }
@@ -437,7 +437,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
  * Get the number of pool records
  *
  * Returns: -1 on failure
- *         number on success
+ *          number on success
  */
 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
 {
@@ -455,7 +455,7 @@ int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
  *  The caller must free ids if non-NULL.
  *
  *  Returns 0: on failure
- *         1: on success
+ *          1: on success
  */
 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
 {
@@ -470,11 +470,11 @@ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       *num_ids = sql_num_rows(mdb);
       if (*num_ids > 0) {
-        id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
-        while ((row = sql_fetch_row(mdb)) != NULL) {
-           id[i++] = str_to_uint64(row[0]);
-        }
-        *ids = id;
+         id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
+         while ((row = sql_fetch_row(mdb)) != NULL) {
+            id[i++] = str_to_uint64(row[0]);
+         }
+         *ids = id;
       }
       sql_free_result(mdb);
       stat = 1;
@@ -492,7 +492,7 @@ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
  *  The caller must free ids if non-NULL.
  *
  *  Returns 0: on failure
- *         1: on success
+ *          1: on success
  */
 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
 {
@@ -507,11 +507,11 @@ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       *num_ids = sql_num_rows(mdb);
       if (*num_ids > 0) {
-        id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
-        while ((row = sql_fetch_row(mdb)) != NULL) {
-           id[i++] = str_to_uint64(row[0]);
-        }
-        *ids = id;
+         id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
+         while ((row = sql_fetch_row(mdb)) != NULL) {
+            id[i++] = str_to_uint64(row[0]);
+         }
+         *ids = id;
       }
       sql_free_result(mdb);
       stat = 1;
@@ -530,61 +530,61 @@ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
  * If the PoolId is non-zero, we get its record,
  *  otherwise, we search on the PoolName
  *
- * Returns: 0 on failure
- *         id on success
+ * Returns: false on failure
+ *          true on success
  */
-int db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
+bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
 {
    SQL_ROW row;
-   int stat = 0;
+   bool ok = false;
    char ed1[50];
 
    db_lock(mdb);
-   if (pdbr->PoolId != 0) {              /* find by id */
+   if (pdbr->PoolId != 0) {               /* find by id */
       Mmsg(mdb->cmd,
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,"
 "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "MaxVolBytes,PoolType,LabelType,LabelFormat FROM Pool WHERE Pool.PoolId=%s", 
-        edit_int64(pdbr->PoolId, ed1));
-   } else {                          /* find by name */
+         edit_int64(pdbr->PoolId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd,
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,"
 "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "MaxVolBytes,PoolType,LabelType,LabelFormat FROM Pool WHERE Pool.Name='%s'", 
-        pdbr->Name);
+         pdbr->Name);
    }
 
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        char ed1[30];
+         char ed1[30];
          Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
-           edit_uint64(mdb->num_rows, ed1));
+            edit_uint64(mdb->num_rows, ed1));
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-        } else {
-           pdbr->PoolId = str_to_int64(row[0]);
+         } else {
+            pdbr->PoolId = str_to_int64(row[0]);
             bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
-           pdbr->NumVols = str_to_int64(row[2]);
-           pdbr->MaxVols = str_to_int64(row[3]);
-           pdbr->UseOnce = str_to_int64(row[4]);
-           pdbr->UseCatalog = str_to_int64(row[5]);
-           pdbr->AcceptAnyVolume = str_to_int64(row[6]);
-           pdbr->AutoPrune = str_to_int64(row[7]);
-           pdbr->Recycle = str_to_int64(row[8]);
-           pdbr->VolRetention = str_to_int64(row[9]);
-           pdbr->VolUseDuration = str_to_int64(row[10]);
-           pdbr->MaxVolJobs = str_to_int64(row[11]);
-           pdbr->MaxVolFiles = str_to_int64(row[12]);
-           pdbr->MaxVolBytes = str_to_uint64(row[13]);
+            pdbr->NumVols = str_to_int64(row[2]);
+            pdbr->MaxVols = str_to_int64(row[3]);
+            pdbr->UseOnce = str_to_int64(row[4]);
+            pdbr->UseCatalog = str_to_int64(row[5]);
+            pdbr->AcceptAnyVolume = str_to_int64(row[6]);
+            pdbr->AutoPrune = str_to_int64(row[7]);
+            pdbr->Recycle = str_to_int64(row[8]);
+            pdbr->VolRetention = str_to_int64(row[9]);
+            pdbr->VolUseDuration = str_to_int64(row[10]);
+            pdbr->MaxVolJobs = str_to_int64(row[11]);
+            pdbr->MaxVolFiles = str_to_int64(row[12]);
+            pdbr->MaxVolBytes = str_to_uint64(row[13]);
             bstrncpy(pdbr->PoolType, row[14]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
-           pdbr->LabelType = str_to_int64(row[15]);
+            pdbr->LabelType = str_to_int64(row[15]);
             bstrncpy(pdbr->LabelFormat, row[16]!=NULL?row[16]:"", sizeof(pdbr->LabelFormat));
-           stat = pdbr->PoolId;
-        }
+            ok = true;
+         }
       } else {
          Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
       }
@@ -593,7 +593,7 @@ int db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
       Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
    }
    db_unlock(mdb);
-   return stat;
+   return ok;
 }
 
 /* Get Client Record
@@ -601,7 +601,7 @@ int db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
  *  otherwise, we search on the Client Name
  *
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
 {
@@ -610,12 +610,12 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
    char ed1[50];
 
    db_lock(mdb);
-   if (cdbr->ClientId != 0) {              /* find by id */
+   if (cdbr->ClientId != 0) {               /* find by id */
       Mmsg(mdb->cmd,
 "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention "
 "FROM Client WHERE Client.ClientId=%s", 
-       edit_int64(cdbr->ClientId, ed1));
-   } else {                          /* find by name */
+        edit_int64(cdbr->ClientId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd,
 "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention "
 "FROM Client WHERE Client.Name='%s'", cdbr->Name);
@@ -625,21 +625,21 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"),
-           edit_uint64(mdb->num_rows, ed1));
+            edit_uint64(mdb->num_rows, ed1));
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-        } else {
-           cdbr->ClientId = str_to_int64(row[0]);
+         } else {
+            cdbr->ClientId = str_to_int64(row[0]);
             bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name));
             bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname));
-           cdbr->AutoPrune = str_to_int64(row[3]);
-           cdbr->FileRetention = str_to_int64(row[4]);
-           cdbr->JobRetention = str_to_int64(row[5]);
-           stat = 1;
-        }
+            cdbr->AutoPrune = str_to_int64(row[3]);
+            cdbr->FileRetention = str_to_int64(row[4]);
+            cdbr->JobRetention = str_to_int64(row[5]);
+            stat = 1;
+         }
       } else {
          Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n"));
       }
@@ -655,7 +655,7 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
  * Get Counter Record
  *
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
 {
@@ -674,24 +674,24 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           sql_free_result(mdb);
-           db_unlock(mdb);
-           return 0;
-        }
-        cr->MinValue = atoi(row[0]);
-        cr->MaxValue = atoi(row[1]);
-        cr->CurrentValue = atoi(row[2]);
-        if (row[3]) {
-           bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter));
-        } else {
-           cr->WrapCounter[0] = 0;
-        }
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return 1;
+            sql_free_result(mdb);
+            db_unlock(mdb);
+            return 0;
+         }
+         cr->MinValue = atoi(row[0]);
+         cr->MaxValue = atoi(row[1]);
+         cr->CurrentValue = atoi(row[2]);
+         if (row[3]) {
+            bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter));
+         } else {
+            cr->WrapCounter[0] = 0;
+         }
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return 1;
       }
       sql_free_result(mdb);
    } else {
@@ -707,7 +707,7 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
  *  otherwise, we search on the name
  *
  * Returns: 0 on failure
- *         id on success
+ *          id on success
  */
 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 {
@@ -716,12 +716,12 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    char ed1[50];
 
    db_lock(mdb);
-   if (fsr->FileSetId != 0) {              /* find by id */
+   if (fsr->FileSetId != 0) {               /* find by id */
       Mmsg(mdb->cmd,
            "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet "
            "WHERE FileSetId=%s", 
-          edit_int64(fsr->FileSetId, ed1));
-   } else {                          /* find by name */
+           edit_int64(fsr->FileSetId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd,
            "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
            "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet);
@@ -730,19 +730,19 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        char ed1[30];
+         char ed1[30];
          Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"),
-           edit_uint64(mdb->num_rows, ed1));
-        sql_data_seek(mdb, mdb->num_rows-1);
+            edit_uint64(mdb->num_rows, ed1));
+         sql_data_seek(mdb, mdb->num_rows-1);
       }
       if ((row = sql_fetch_row(mdb)) == NULL) {
          Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
       } else {
-        fsr->FileSetId = str_to_int64(row[0]);
+         fsr->FileSetId = str_to_int64(row[0]);
          bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
          bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5));
          bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime));
-        stat = fsr->FileSetId;
+         stat = fsr->FileSetId;
       }
       sql_free_result(mdb);
    } else {
@@ -757,7 +757,7 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
  * Get the number of Media records
  *
  * Returns: -1 on failure
- *         number on success
+ *          number on success
  */
 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
 {
@@ -777,7 +777,7 @@ int db_get_num_media_records(JCR *jcr, B_DB *mdb)
  *  The caller must free ids if non-NULL.
  *
  *  Returns 0: on failure
- *         1: on success
+ *          1: on success
  */
 int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
 {
@@ -794,11 +794,11 @@ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       *num_ids = sql_num_rows(mdb);
       if (*num_ids > 0) {
-        id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
-        while ((row = sql_fetch_row(mdb)) != NULL) {
-           id[i++] = (uint32_t)atoi(row[0]);
-        }
-        *ids = id;
+         id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
+         while ((row = sql_fetch_row(mdb)) != NULL) {
+            id[i++] = (uint32_t)atoi(row[0]);
+         }
+         *ids = id;
       }
       sql_free_result(mdb);
       stat = 1;
@@ -815,7 +815,7 @@ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_
 /* Get Media Record
  *
  * Returns: 0 on failure
- *         id on success
+ *          id on success
  */
 int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 {
@@ -830,15 +830,15 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       db_unlock(mdb);
       return 1;
    }
-   if (mr->MediaId != 0) {              /* find by id */
+   if (mr->MediaId != 0) {               /* find by id */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
          "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
          "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger,"
          "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId "
          "FROM Media WHERE MediaId=%s", 
-        edit_int64(mr->MediaId, ed1));
-   } else {                          /* find by name */
+         edit_int64(mr->MediaId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
          "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
@@ -852,65 +852,65 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
-           edit_uint64(mdb->num_rows, ed1));
+            edit_uint64(mdb->num_rows, ed1));
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-        } else {
-           /* return values */
-           mr->MediaId = str_to_int64(row[0]);
+         } else {
+            /* return values */
+            mr->MediaId = str_to_int64(row[0]);
             bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
-           mr->VolJobs = str_to_int64(row[2]);
-           mr->VolFiles = str_to_int64(row[3]);
-           mr->VolBlocks = str_to_int64(row[4]);
-           mr->VolBytes = str_to_uint64(row[5]);
-           mr->VolMounts = str_to_int64(row[6]);
-           mr->VolErrors = str_to_int64(row[7]);
-           mr->VolWrites = str_to_int64(row[8]);
-           mr->MaxVolBytes = str_to_uint64(row[9]);
-           mr->VolCapacityBytes = str_to_uint64(row[10]);
+            mr->VolJobs = str_to_int64(row[2]);
+            mr->VolFiles = str_to_int64(row[3]);
+            mr->VolBlocks = str_to_int64(row[4]);
+            mr->VolBytes = str_to_uint64(row[5]);
+            mr->VolMounts = str_to_int64(row[6]);
+            mr->VolErrors = str_to_int64(row[7]);
+            mr->VolWrites = str_to_int64(row[8]);
+            mr->MaxVolBytes = str_to_uint64(row[9]);
+            mr->VolCapacityBytes = str_to_uint64(row[10]);
             bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType));
             bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus));
-           mr->PoolId = str_to_int64(row[13]);
-           mr->VolRetention = str_to_uint64(row[14]);
-           mr->VolUseDuration = str_to_uint64(row[15]);
-           mr->MaxVolJobs = str_to_int64(row[16]);
-           mr->MaxVolFiles = str_to_int64(row[17]);
-           mr->Recycle = str_to_int64(row[18]);
-           mr->Slot = str_to_int64(row[19]);
+            mr->PoolId = str_to_int64(row[13]);
+            mr->VolRetention = str_to_uint64(row[14]);
+            mr->VolUseDuration = str_to_uint64(row[15]);
+            mr->MaxVolJobs = str_to_int64(row[16]);
+            mr->MaxVolFiles = str_to_int64(row[17]);
+            mr->Recycle = str_to_int64(row[18]);
+            mr->Slot = str_to_int64(row[19]);
             bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten));
-           mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten);
+            mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten);
             bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten));
-           mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten);
-           mr->InChanger = str_to_uint64(row[22]);
-           mr->EndFile = str_to_uint64(row[23]);
-           mr->EndBlock = str_to_uint64(row[24]);
-           mr->VolParts = str_to_int64(row[25]);
-           mr->LabelType = str_to_int64(row[26]);
+            mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten);
+            mr->InChanger = str_to_uint64(row[22]);
+            mr->EndFile = str_to_uint64(row[23]);
+            mr->EndBlock = str_to_uint64(row[24]);
+            mr->VolParts = str_to_int64(row[25]);
+            mr->LabelType = str_to_int64(row[26]);
             bstrncpy(mr->cLabelDate, row[27]!=NULL?row[27]:"", sizeof(mr->cLabelDate));
-           mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate);
-           mr->StorageId = str_to_int64(row[28]);
-           stat = mr->MediaId;
-        }
+            mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate);
+            mr->StorageId = str_to_int64(row[28]);
+            stat = mr->MediaId;
+         }
       } else {
-        if (mr->MediaId != 0) {
+         if (mr->MediaId != 0) {
             Mmsg1(&mdb->errmsg, _("Media record MediaId=%s not found.\n"), 
-              edit_int64(mr->MediaId, ed1));
-        } else {
+               edit_int64(mr->MediaId, ed1));
+         } else {
             Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
-                 mr->VolumeName);
-        }
+                  mr->VolumeName);
+         }
       }
       sql_free_result(mdb);
    } else {
       if (mr->MediaId != 0) {
          Mmsg(mdb->errmsg, _("Media record for MediaId=%u not found in Catalog.\n"),
-           mr->MediaId);
+            mr->MediaId);
        } else {
          Mmsg(mdb->errmsg, _("Media record for Vol=%s not found in Catalog.\n"),
-           mr->VolumeName);
+            mr->VolumeName);
    }   }
    db_unlock(mdb);
    return stat;
index 44d26831684afce98c3634996a90d60145e3b191..6baf7d7f50a2765ce240f0d5e7d3e7678c81da81 100644 (file)
@@ -41,7 +41,7 @@
  */
 
 /* Requests from the Storage daemon */
-static char Find_media[] = "CatReq Job=%127s FindMedia=%d PoolId=%lld\n";
+static char Find_media[] = "CatReq Job=%127s FindMedia=%d pool_name=%127s media_type=%127s\n";
 static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d\n";
 
 static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s"
@@ -86,7 +86,7 @@ static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr
       mr->VolParts,
       mr->LabelType);
    unbash_spaces(mr->VolumeName);
-   Dmsg2(400, "Vol Info for %s: %s", jcr->Job, sd->msg);
+   Dmsg2(100, "Vol Info for %s: %s", jcr->Job, sd->msg);
    return stat;
 }
 
@@ -95,9 +95,10 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
    MEDIA_DBR mr, sdmr;
    JOBMEDIA_DBR jm;
    char Job[MAX_NAME_LENGTH];
-   int64_t PoolId;
+   char pool_name[MAX_NAME_LENGTH];
    int index, ok, label, writing;
    POOLMEM *omsg;
+   POOL_DBR pr;
 
    memset(&mr, 0, sizeof(mr));
    memset(&sdmr, 0, sizeof(sdmr));
@@ -106,7 +107,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
    /*
     * Request to find next appendable Volume for this Job
     */
-   Dmsg1(400, "catreq %s", bs->msg);
+   Dmsg1(100, "catreq %s", bs->msg);
    if (!jcr->db) {
       omsg = get_memory(bs->msglen+1);
       pm_strcpy(omsg, bs->msg);
@@ -118,9 +119,14 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
    /*
     * Find next appendable medium for SD
     */
-   if (sscanf(bs->msg, Find_media, &Job, &index, &PoolId) == 3) {
-      mr.PoolId = PoolId;
-      ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
+   if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
+      memset(&pr, 0, sizeof(pr));
+      bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
+      ok = db_get_pool_record(jcr, jcr->db, &pr);
+      if (ok) {
+        mr.PoolId = pr.PoolId;
+        ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
+      }
       /*
        * Send Find Media response to Storage daemon
        */
index bb3165c2dab0d1737931fbe537a104a9106403f1..9bd7b281592d59a997e3435d64ca66c7c5ab74fa 100644 (file)
@@ -22,7 +22,7 @@ SVRSRCS = stored.c ansi_label.c \
          autochanger.c acquire.c append.c \
          askdir.c authenticate.c \
          block.c butil.c dev.c \
-         device.c dircmd.c dvd.c fd_cmds.c job.c \
+         device.c dircmd.c dvd.c ebcdic.c fd_cmds.c job.c \
          label.c match_bsr.c mount.c parse_bsr.c \
          python.c \
          read.c read_record.c record.c \
@@ -31,7 +31,7 @@ SVROBJS = stored.o ansi_label.o \
          autochanger.o acquire.o append.o \
          askdir.o authenticate.o \
          block.o butil.o dev.o \
-         device.o dircmd.o dvd.o fd_cmds.o job.o \
+         device.o dircmd.o dvd.o ebcdic.c fd_cmds.o job.o \
          label.o match_bsr.o mount.o parse_bsr.o \
          python.o \
          read.o read_record.o record.o \
@@ -39,35 +39,35 @@ SVROBJS = stored.o ansi_label.o \
 
 # btape
 TAPESRCS = btape.c block.c butil.c dev.c device.c label.c \
-          ansi_label.c dvd.c \
+          ansi_label.c dvd.c ebcdic.c \
           acquire.c mount.c record.c read_record.c \
           stored_conf.c match_bsr.c parse_bsr.c spool.c
 TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
-          ansi_label.o dvd.o \
+          ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o read_record.o \
           stored_conf.o match_bsr.o parse_bsr.o spool.o
 
 # bls
 BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
-         ansi_label.o dvd.o \
+         ansi_label.o dvd.o ebcdic.o \
          autochanger.o acquire.o mount.o parse_bsr.o record.o  \
          read_record.o stored_conf.o spool.o
 
 # bextract
 BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
-          ansi_label.o dvd.o \
+          ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
           read_record.o stored_conf.o spool.o
 
 # bscan
 SCNOBJS = bscan.o block.o device.o dev.o label.o \
-         ansi_label.o dvd.o \
+         ansi_label.o dvd.o ebcdic.o \
          autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
          butil.o read_record.o stored_conf.o spool.o
 
 # bcopy
 COPYOBJS = bcopy.o block.o device.o dev.o label.o \
-          ansi_label.o dvd.o \
+          ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
           butil.o read_record.o stored_conf.o spool.o
 
index e14ed0f29c34b0b1b09e61611f209155543e4649..f8c9e1679daa523878184cf8702111178bea561f 100644 (file)
@@ -564,6 +564,7 @@ bool release_device(DCR *dcr)
 {
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
+
    lock_device(dev);
    Dmsg1(100, "release_device device is %s\n", dev_is_tape(dev)?"tape":"disk");
 
@@ -600,6 +601,8 @@ bool release_device(DCR *dcr)
         /* Note! do volume update before close, which zaps VolCatInfo */
          Dmsg0(100, "dir_update_vol_info. Release0\n");
         dir_update_volume_info(dcr, false); /* send Volume info to Director */
+         Dmsg0(100, "==== write ansi eof label \n");
+        write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName);
       }
 
       /* If no writers, close if file or !CAP_ALWAYS_OPEN */
index 85fb30538daa35531a174ac0364fea829a5a78dd..0257a43500af22557ad2bd8e8b0a1cf2fcf70b8f 100644 (file)
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
+/* Imported functions */
+void ascii_to_ebcdic(char *dst, char *src, int count);
+void ebcdic_to_ascii(char *dst, char *src, int count);
+
 /* Forward referenced functions */
 static char *ansi_date(time_t td, char *buf);
 static bool same_label_names(char *bacula_name, char *ansi_name);
@@ -58,13 +62,14 @@ int read_ansi_ibm_label(DCR *dcr)
    char label[80];                   /* tape label */
    int stat, i;
    char *VolName = dcr->VolumeName;
+   bool ok = false;
 
    /*
     * Read VOL1, HDR1, HDR2 labels, but ignore the data
     *  If tape read the following EOF mark, on disk do
     *  not read.
     */
-   Dmsg0(000, "Read ansi label.\n");
+   Dmsg0(100, "Read ansi label.\n");
    if (!dev->is_tape()) {
       return VOL_OK;
    }
@@ -79,7 +84,7 @@ int read_ansi_ibm_label(DCR *dcr)
       if (stat < 0) {
         berrno be;
         clrerror_dev(dev, -1);
-         Dmsg1(000, "Read device got: ERR=%s\n", be.strerror());
+         Dmsg1(100, "Read device got: ERR=%s\n", be.strerror());
          Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
            dev->dev_name, be.strerror());
          Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
@@ -89,7 +94,7 @@ int read_ansi_ibm_label(DCR *dcr)
       if (stat == 0) {
         if (dev->at_eof()) {
            dev->state |= ST_EOT;
-            Dmsg0(000, "EOM on ANSI label\n");
+            Dmsg0(100, "EOM on ANSI label\n");
             Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
             return VOL_LABEL_ERROR;   /* at EOM this shouldn't happen */
         } else {
@@ -98,13 +103,25 @@ int read_ansi_ibm_label(DCR *dcr)
       }
       switch (i) {
       case 0:                        /* Want VOL1 label */
-         if (stat != 80 || strncmp("VOL1", label, 4) != 0) {
-            Dmsg0(000, "No VOL1 label\n");
-            Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI label.\n"));
+        if (stat == 80) {
+            if (strncmp("VOL1", label, 4) == 0) {
+              ok = true;
+              dev->label_type = B_ANSI_LABEL;
+           } else {
+              /* Try EBCDIC */
+              ebcdic_to_ascii(label, label, sizeof(label));
+               if (strncmp("VOL1", label, 4) == 0) {
+                 ok = true;;
+                 dev->label_type = B_IBM_LABEL;
+              }
+           }       
+        }
+        if (!ok) {
+            Dmsg0(100, "No VOL1 label\n");
+            Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
            return VOL_NO_LABEL;   /* No ANSI label */
         }
 
-        dev->label_type = B_ANSI_LABEL;
 
         /* Compare Volume Names allow special wild card */
          if (VolName && *VolName && *VolName != '*') { 
@@ -115,58 +132,128 @@ int read_ansi_ibm_label(DCR *dcr)
                  *q++ = *p++;
               }
               *q = 0;
-               Dmsg2(000, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName);
+               Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName);
                Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolName);
               return VOL_NAME_ERROR;
            }
         }
         break;
       case 1:
+        if (dev->label_type == B_IBM_LABEL) {
+           ebcdic_to_ascii(label, label, sizeof(label));
+        }
          if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
-            Dmsg0(000, "No HDR1 label\n");
+            Dmsg0(100, "No HDR1 label\n");
             Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
            return VOL_LABEL_ERROR;
         }
          if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
-            Dmsg1(000, "HD1 not Bacula label. Wanted  BACULA.DATA got %11s\n",
+            Dmsg1(100, "HD1 not Bacula label. Wanted  BACULA.DATA got %11s\n",
               &label[4]);
-            Mmsg1(jcr->errmsg, _("ANSI Volume \"%s\" does not belong to Bacula.\n"),
+            Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
               dev->VolHdr.VolName);
            return VOL_NAME_ERROR;     /* Not a Bacula label */
         }
         break;
       case 2:
+        if (dev->label_type == B_IBM_LABEL) {
+           ebcdic_to_ascii(label, label, sizeof(label));
+        }
          if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
-            Dmsg0(000, "No HDR2 label\n");
-            Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI label.\n"));
+            Dmsg0(100, "No HDR2 label\n");
+            Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
            return VOL_LABEL_ERROR;
         }
         break;
       default:
         if (stat == 0) {
-            Dmsg0(000, "ANSI label OK\n");
+            Dmsg0(100, "ANSI label OK\n");
            return VOL_OK;
         }
+        if (dev->label_type == B_IBM_LABEL) {
+           ebcdic_to_ascii(label, label, sizeof(label));
+        }
          if (stat != 80 || strncmp("HDR", label, 3) != 0) {
-            Dmsg0(000, "Unknown or bad ANSI label record.\n");
-            Mmsg0(jcr->errmsg, _("Unknown or bad ANSI label record.\n"));
+            Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
+            Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
            return VOL_LABEL_ERROR;
         }
         break;
       }
    }
-   Dmsg0(000, "Too many records in ANSI label.\n");
-   Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI label.\n"));
+   Dmsg0(100, "Too many records in ANSI/IBM label.\n");
+   Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
    return VOL_LABEL_ERROR;
 }  
 
+/*
+ * ANSI/IBM VOL1 label
+ *  80 characters blank filled
+ * Pos  count   Function      What Bacula puts
+ * 0-3     4     "VOL1"          VOL1
+ * 4-9    6     Volume name     Volume name
+ * 10-10   1    Access code 
+ * 11-36   26   Unused
+ *
+ * ANSI
+ * 37-50   14   Owner
+ * 51-78   28   reserved
+ * 79      1    ANSI level        3
+ *
+ * IBM
+ * 37-40   4    reserved
+ * 41-50   10   Owner
+ * 51-79   29   reserved
+
+ *
+ *
+ * ANSI/IBM HDR1 label
+ *  80 characters blank filled
+ * Pos  count   Function          What Bacula puts
+ * 0-3     4     "HDR1"               HDR1
+ * 4-20    17   File name           BACULA.DATA
+ * 21-26   6    Volume name          Volume name
+ * 27-30   4    Vol seq num           0001
+ * 31-34   4    file num              0001
+ * 35-38   4    Generation            0001
+ * 39-40   2    Gen version           00
+ * 41-46   6    Create date bYYDDD    yesterday
+ * 47-52   6    Expire date bYYDDD    today
+ * 53-53   1    Access
+ * 54-59   6    Block count           000000
+ * 60-72   13   Software name         Bacula
+ * 73-79   7    Reserved
+
+ * ANSI/IBM HDR2 label
+ *  80 characters blank filled
+ * Pos  count   Function          What Bacula puts
+ * 0-3     4     "HDR2"               HDR2
+ * 4-4    1     Record format        D   (V if IBM) => variable
+ * 5-9    5     Block length         32000
+ * 10-14   5    Rec length           32000
+ * 15-15   1    Density
+ * 16-16   1    Continued 
+ * 17-33   17   Job
+ * 34-35   2    Recording
+ * 36-36   1    cr/lf ctl
+ * 37-37   1    reserved
+ * 38-38   1    Blocked flag
+ * 39-49   11   reserved
+ * 50-51   2    offset
+ * 52-79   28   reserved
+
+ */ 
+
+static const char *labels[] = {"HDR", "EOF", "EOV"};
+
 /*
  * Write an ANSI or IBM 80 character tape label
- *   Assume we are positioned at the beginning of the tape.
+ *   Type determines whether we are writing HDR, EOF, or EOV labels
+ *   Assume we are positioned to write the labels
  *   Returns:  true of OK
  *            false if error
  */
-bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
+bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
 {
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
@@ -191,29 +278,37 @@ bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
    case B_ANSI_LABEL:
    case B_IBM_LABEL:
       ser_declare;
-      Dmsg1(000, "Write ANSI label type=%d\n", label_type);
+      Dmsg1(100, "Write ANSI label type=%d\n", label_type);
       len = strlen(VolName);
       if (len > 6) {
          Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
            VolName);
         return false;
       }
-      memset(label, ' ', sizeof(label));
-      ser_begin(label, sizeof(label));
-      ser_bytes("VOL1", 4);
-      ser_bytes(VolName, len);
-      label[79] = '3';                /* ANSI label flag */
-      /* Write VOL1 label */
-      stat = write(dev->fd, label, sizeof(label));
-      if (stat != sizeof(label)) {
-        berrno be;
-         Jmsg1(jcr, M_FATAL, 0,  _("Could not write ANSI VOL1 label. ERR=%s\n"),
-           be.strerror());
-        return false;
+      if (type == ANSI_VOL_LABEL) {
+        ser_begin(label, sizeof(label));
+         ser_bytes("VOL1", 4);
+        ser_bytes(VolName, len);
+        /* Write VOL1 label */
+        if (label_type == B_IBM_LABEL) {
+           ascii_to_ebcdic(label, label, sizeof(label));
+        } else {
+            label[79] = '3';                /* ANSI label flag */
+        }
+        stat = write(dev->fd, label, sizeof(label));
+        if (stat != sizeof(label)) {
+           berrno be;
+            Jmsg1(jcr, M_FATAL, 0,  _("Could not write ANSI VOL1 label. ERR=%s\n"),
+              be.strerror());
+           return false;
+        }
       }
+
       /* Now construct HDR1 label */
+      memset(label, ' ', sizeof(label));
       ser_begin(label, sizeof(label));
-      ser_bytes("HDR1", 4);
+      ser_bytes(labels[type], 3);
+      ser_bytes("1", 1);
       ser_bytes("BACULA.DATA", 11);            /* Filename field */
       ser_begin(&label[21], sizeof(label)-21); /* fileset field */
       ser_bytes(VolName, len);       /* write Vol Ser No. */
@@ -224,6 +319,9 @@ bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
       ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
       ser_bytes(" 000000Bacula              ", 27);
       /* Write HDR1 label */
+      if (label_type == B_IBM_LABEL) {
+        ascii_to_ebcdic(label, label, sizeof(label));
+      }
       stat = write(dev->fd, label, sizeof(label));
       if (stat != sizeof(label)) {
         berrno be;
@@ -231,11 +329,18 @@ bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
            be.strerror());
         return false;
       }
+
+
       /* Now construct HDR2 label */
       memset(label, ' ', sizeof(label));
       ser_begin(label, sizeof(label));
-      ser_bytes("HDR2F3200032000", 15);
-      /* Write HDR1 label */
+      ser_bytes(labels[type], 3);
+      ser_bytes("2D3200032000", 12);
+      /* Write HDR2 label */
+      if (label_type == B_IBM_LABEL) {
+         label[4] = 'V';
+        ascii_to_ebcdic(label, label, sizeof(label));
+      }
       stat = write(dev->fd, label, sizeof(label));
       if (stat != sizeof(label)) {
         berrno be;
@@ -247,6 +352,16 @@ bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
          Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
         return false;
       }
+      /* If this is an EOF label, we must reposition to before it
+        as Bacula does not support these on read.
+       */
+      if (type == ANSI_EOF_LABEL) {  
+        if (!bsf_dev(dev, 2) || !fsf_dev(dev, 1)) {
+            Jmsg(jcr, M_FATAL, 0, _("Error repositiong after writing ANSI/IBM EOF labels to tape. ERR=%s"), 
+                dev->errmsg);
+           return false;
+        }
+      }
       return true;
    default:
       Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
@@ -280,7 +395,10 @@ static bool same_label_names(char *bacula_name, char *ansi_name)
    return false;
 }
 
-
+/*
+ * ANSI date
+ *  ' 'YYDDD
+ */
 static char *ansi_date(time_t td, char *buf)
 {
    struct tm *tm;
index 1166452d4e5c442486cd9005ecfd77ab8cec80b8..bc361fbde2f7f1f60ad7b73a1c12346a17f6a97e 100644 (file)
@@ -30,7 +30,7 @@
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
 /* Requests sent to the Director */
-static char Find_media[]   = "CatReq Job=%s FindMedia=%d PoolId=%s\n";
+static char Find_media[]   = "CatReq Job=%s FindMedia=%d pool_name=%s media_type=%s\n";
 static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n";
 static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s"
    " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u"
@@ -232,7 +232,6 @@ bool dir_find_next_appendable_volume(DCR *dcr)
 {
     JCR *jcr = dcr->jcr;
     BSOCK *dir = jcr->dir_bsock;
-    char ed1[50];
     JCR *njcr;
 
     Dmsg0(200, "dir_find_next_appendable_volume\n");
@@ -242,7 +241,11 @@ bool dir_find_next_appendable_volume(DCR *dcr)
      *  drive, so we continue looking for a not in use Volume.
      */
     for (int vol_index=1;  vol_index < 3; vol_index++) {
-       bnet_fsend(dir, Find_media, jcr->Job, vol_index, edit_int64(dcr->PoolId, ed1));
+       bash_spaces(dcr->media_type);
+       bash_spaces(dcr->pool_name);
+       bnet_fsend(dir, Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type);
+       unbash_spaces(dcr->media_type);
+       unbash_spaces(dcr->pool_name);
        Dmsg1(100, ">dird: %s", dir->msg);
        if (do_get_volume_info(dcr)) {
           Dmsg2(300, "JobId=%d got possible Vol=%s\n", jcr->JobId, dcr->VolumeName);
@@ -401,7 +404,7 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec)
    ser_uint32(rec->data_len);
    ser_bytes(rec->data, rec->data_len);
    dir->msglen = ser_length(dir->msg);
-   Dmsg1(100, ">dird: %s", dir->msg);
+   Dmsg1(1800, ">dird: %s\n", dir->msg);    /* Attributes */
    return bnet_send(dir);
 }
 
index e2c5b69990fb5849d85b6584eee64637b2ed742c..14d29d3bf5e8829a8e75c5a54016cd8025326b86 100644 (file)
@@ -688,6 +688,10 @@ static bool terminate_writing_volume(DCR *dcr)
    /* Set new file/block parameters for current dcr */
    set_new_file_parameters(dcr);
 
+   if (ok) {
+      ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolName);
+   }
+
    if (ok && dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) {  /* end the tape */
       dev->VolCatInfo.VolCatErrors++;
       /* This may not be fatal since we already wrote an EOF */
index a9f826ad873f470dd47342025cca4e9986131b44..5d8d4c6a8b706957f7f833b2d91eb8f558b2c4a8 100644 (file)
@@ -526,27 +526,27 @@ void DEVICE::set_eot()
 
 /*
  * Position device to end of medium (end of data)
- *  Returns: 1 on succes
- *          0 on error
+ *  Returns: true  on succes
+ *          false on error
  */
-int
+bool
 eod_dev(DEVICE *dev)
 {
    struct mtop mt_com;
    struct mtget mt_stat;
-   int stat = 0;
+   bool ok = true;
    off_t pos;
 
    Dmsg0(29, "eod_dev\n");
    if (dev->at_eot()) {
-      return 1;
+      return true;
    }
    dev->state &= ~(ST_EOF);  /* remove EOF flags */
    dev->block_num = dev->file = 0;
    dev->file_size = 0;
    dev->file_addr = 0;
    if (dev->state & (ST_FIFO | ST_PROG)) {
-      return 1;
+      return true;
    }
    if (!dev->is_tape()) {
       pos = lseek_dev(dev, (off_t)0, SEEK_END);
@@ -554,13 +554,13 @@ eod_dev(DEVICE *dev)
       if (pos >= 0) {
         update_pos_dev(dev);
         dev->state |= ST_EOT;
-        return 1;
+        return true;
       }
       dev->dev_errno = errno;
       berrno be;
       Mmsg2(&dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
             dev->dev_name, be.strerror());
-      return 0;
+      return false;
    }
 #ifdef MTEOM
    if (dev_cap(dev, CAP_FASTFSF) && !dev_cap(dev, CAP_EOM)) {
@@ -568,7 +568,7 @@ eod_dev(DEVICE *dev)
       /* If unknown position, rewind */
       if (!dev_get_os_pos(dev, &mt_stat)) {
        if (!rewind_dev(dev)) {
-         return 0;
+         return false;
        }
       }
       mt_com.mt_op = MTFSF;
@@ -589,14 +589,14 @@ eod_dev(DEVICE *dev)
         mt_com.mt_count = 1;
       }
 
-      if ((stat=ioctl(dev->fd, MTIOCTOP, (char *)&mt_com)) < 0) {
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
         berrno be;
         clrerror_dev(dev, mt_com.mt_op);
          Dmsg1(50, "ioctl error: %s\n", be.strerror());
         update_pos_dev(dev);
          Mmsg2(&dev->errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"),
            dev->dev_name, be.strerror());
-        return 0;
+        return false;
       }
 
       if (!dev_get_os_pos(dev, &mt_stat)) {
@@ -604,12 +604,11 @@ eod_dev(DEVICE *dev)
         clrerror_dev(dev, -1);
          Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
            dev->dev_name, be.strerror());
-        return 0;
+        return false;
       }
       Dmsg2(100, "EOD file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno);
       dev->set_eof();
       dev->file = mt_stat.mt_fileno;
-
    } else {
 #else
    {
@@ -618,7 +617,7 @@ eod_dev(DEVICE *dev)
        * Rewind then use FSF until EOT reached
        */
       if (!rewind_dev(dev)) {
-        return 0;
+        return false;
       }
       /*
        * Move file by file to the end of the tape
@@ -628,7 +627,7 @@ eod_dev(DEVICE *dev)
          Dmsg0(200, "eod_dev: doing fsf 1\n");
         if (!fsf_dev(dev, 1)) {
             Dmsg0(200, "fsf_dev error.\n");
-           return 0;
+           return false;
         }
         /*
          * Avoid infinite loop. ***FIXME*** possibly add code
@@ -642,8 +641,7 @@ eod_dev(DEVICE *dev)
               dev->set_eof();
               dev->file = mt_stat.mt_fileno;
            }
-           stat = 0;
-           break;                    /* we are not progressing, bail out */
+           return false;
         }
       }
    }
@@ -655,7 +653,7 @@ eod_dev(DEVICE *dev)
    if (dev_cap(dev, CAP_BSFATEOM)) {
       struct mtget mt_stat;
       /* Backup over EOF */
-      stat = bsf_dev(dev, 1);
+      ok = bsf_dev(dev, 1);
       /* If BSF worked and fileno is known (not -1), set file */
       if (dev_get_os_pos(dev, &mt_stat)) {
          Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno);
@@ -665,10 +663,17 @@ eod_dev(DEVICE *dev)
       }
    } else {
       update_pos_dev(dev);                  /* update position */
-      stat = 1;
+   }
+   /* If this is an ANSI or IBM labeled tape we must 
+    *  backspace over EOF label
+    */
+   if (dev->label_type != B_BACULA_LABEL) {
+      if (!bsf_dev(dev, 2) || !fsf_dev(dev, 1)) {
+        ok = false;
+      }
    }
    Dmsg1(200, "EOD dev->file=%d\n", dev->file);
-   return stat;
+   return ok;
 }
 
 /*
index faa8c8ba48edca4330f0d20638f1ee218153e140..d127e838feca3910bfb0b7a7938398b8522dd462 100644 (file)
@@ -144,7 +144,7 @@ static char to_ebcdic_table[256] = {
 /*
  * Convert from ASCII to EBCDIC 
  */
-asci_to_ebcdic(char *dst, char *src, int count)
+void ascii_to_ebcdic(char *dst, char *src, int count)
 {
    while (count--) {
       *dst++ = to_ebcdic_table[0377 & *src++];
@@ -155,9 +155,9 @@ asci_to_ebcdic(char *dst, char *src, int count)
 /*
  * Convert from EBCDIC to ASCII
  */
-ebcdic_to_ascii(char *dst, char *src, int count)
+void ebcdic_to_ascii(char *dst, char *src, int count)
 {
    while (count--) {
-      *dst++ = to_asci_table[0377 & *src++];
+      *dst++ = to_ascii_table[0377 & *src++];
    }
 }
index 907ee187b5e952da475389042adb5726acb51fc2..fa5dafffb965f9609acc44ecc63e98b080411a82 100644 (file)
@@ -392,7 +392,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
         rewind_dev(dev);
         goto bail_out;
       }
-   } else if (!write_ansi_ibm_label(dcr, VolName)) {
+   } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) {
       goto bail_out;
    }
 
@@ -478,7 +478,7 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
            rewind_dev(dev);
            return false;
         }
-      } else if (!write_ansi_ibm_label(dcr, dev->VolHdr.VolName)) {
+      } else if (!write_ansi_ibm_labels (dcr, ANSI_VOL_LABEL, dev->VolHdr.VolName)) {
         return false;
       }
 
index 6ec0b722ea789ab047538ed141a2d506e9635503..73b7fb96e11529d2fe4448fe965014874986c753 100644 (file)
 uint32_t new_VolSessionId();
 
 /* From acquire.c */
-bool     reserve_device_for_append(JCR *jcr, DEVICE *dev);
-DCR     *acquire_device_for_append(JCR *jcr, DEVICE *dev);
-bool     reserve_device_for_read(JCR *jcr, DEVICE *dev);
-DCR     *acquire_device_for_read(JCR *jcr, DEVICE *dev);
-bool     release_device(DCR *dcr);
-DCR     *new_dcr(JCR *jcr, DEVICE *dev);
-void     free_dcr(DCR *dcr);
+bool    reserve_device_for_append(JCR *jcr, DEVICE *dev);
+DCR    *acquire_device_for_append(JCR *jcr, DEVICE *dev);
+bool    reserve_device_for_read(JCR *jcr, DEVICE *dev);
+DCR    *acquire_device_for_read(JCR *jcr, DEVICE *dev);
+bool    release_device(DCR *dcr);
+DCR    *new_dcr(JCR *jcr, DEVICE *dev);
+void    free_dcr(DCR *dcr);
 
 /* From askdir.c */
 enum get_vol_info_rw {
    GET_VOL_INFO_FOR_WRITE,
    GET_VOL_INFO_FOR_READ
 };
-bool    dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
-bool    dir_find_next_appendable_volume(DCR *dcr);
-bool    dir_update_volume_info(DCR *dcr, bool label);
-bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
-bool    dir_ask_sysop_to_mount_volume(DCR *dcr);
-bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
-bool    dir_send_job_status(JCR *jcr);
-bool    dir_create_jobmedia_record(DCR *dcr);
-bool    dir_update_device(JCR *jcr, DEVICE *dev);
-bool    dir_update_changer(JCR *jcr, AUTOCHANGER *changer);
+bool   dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
+bool   dir_find_next_appendable_volume(DCR *dcr);
+bool   dir_update_volume_info(DCR *dcr, bool label);
+bool   dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
+bool   dir_ask_sysop_to_mount_volume(DCR *dcr);
+bool   dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
+bool   dir_send_job_status(JCR *jcr);
+bool   dir_create_jobmedia_record(DCR *dcr);
+bool   dir_update_device(JCR *jcr, DEVICE *dev);
+bool   dir_update_changer(JCR *jcr, AUTOCHANGER *changer);
 
 /* authenticate.c */
-int     authenticate_director(JCR *jcr);
-int     authenticate_filed(JCR *jcr);
+int    authenticate_director(JCR *jcr);
+int    authenticate_filed(JCR *jcr);
 
 /* From autochanger.c */
-int      autoload_device(DCR *dcr, int writing, BSOCK *dir);
-bool     autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd);
-void     mark_volume_not_inchanger(DCR *dcr);
-char    *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
+int     autoload_device(DCR *dcr, int writing, BSOCK *dir);
+bool    autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd);
+void    mark_volume_not_inchanger(DCR *dcr);
+char   *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
 
 /* From block.c */
-void    dump_block(DEV_BLOCK *b, const char *msg);
+void   dump_block(DEV_BLOCK *b, const char *msg);
 DEV_BLOCK *new_block(DEVICE *dev);
 DEV_BLOCK *dup_block(DEV_BLOCK *eblock);
-void    init_block_write(DEV_BLOCK *block);
-void    empty_block(DEV_BLOCK *block);
-void    free_block(DEV_BLOCK *block);
-bool    write_block_to_device(DCR *dcr);
-bool    write_block_to_dev(DCR *dcr);
-void    print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
-void    ser_block_header(DEV_BLOCK *block);
+void   init_block_write(DEV_BLOCK *block);
+void   empty_block(DEV_BLOCK *block);
+void   free_block(DEV_BLOCK *block);
+bool   write_block_to_device(DCR *dcr);
+bool   write_block_to_dev(DCR *dcr);
+void   print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void   ser_block_header(DEV_BLOCK *block);
 
 #define CHECK_BLOCK_NUMBERS    true
 #define NO_BLOCK_NUMBER_CHECK  false
-bool    read_block_from_device(DCR *dcr, bool check_block_numbers);
-bool    read_block_from_dev(DCR *dcr, bool check_block_numbers);
+bool   read_block_from_device(DCR *dcr, bool check_block_numbers);
+bool   read_block_from_dev(DCR *dcr, bool check_block_numbers);
 
 /* From butil.c -- utilities for SD tool programs */
-void    print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
+void   print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
 JCR    *setup_jcr(const char *name, char *dev_name, BSR *bsr,
-                  const char *VolumeName, int mode);
-void    display_tape_error_status(JCR *jcr, DEVICE *dev);
+                 const char *VolumeName, int mode);
+void   display_tape_error_status(JCR *jcr, DEVICE *dev);
 
 
 /* From dev.c */
-DEVICE  *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
-int      open_dev(DEVICE *dev, char *VolName, int mode);
-off_t    lseek_dev(DEVICE *dev, off_t offset, int whence);
-int      open_first_part(DEVICE *dev);
-int      open_next_part(DEVICE *dev);
-int      open_guess_name_dev(DEVICE *dev);
-void     close_dev(DEVICE *dev);
-void     force_close_dev(DEVICE *dev);
-bool     truncate_dev(DEVICE *dev);
-void     term_dev(DEVICE *dev);
-char *   strerror_dev(DEVICE *dev);
-void     clrerror_dev(DEVICE *dev, int func);
-bool     update_pos_dev(DEVICE *dev);
-bool     rewind_dev(DEVICE *dev);
-bool     load_dev(DEVICE *dev);
-bool     offline_dev(DEVICE *dev);
-int      flush_dev(DEVICE *dev);
-int      weof_dev(DEVICE *dev, int num);
-int      write_block(DEVICE *dev);
+DEVICE *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
+int     open_dev(DEVICE *dev, char *VolName, int mode);
+off_t   lseek_dev(DEVICE *dev, off_t offset, int whence);
+int     open_first_part(DEVICE *dev);
+int     open_next_part(DEVICE *dev);
+int     open_guess_name_dev(DEVICE *dev);
+void    close_dev(DEVICE *dev);
+void    force_close_dev(DEVICE *dev);
+bool    truncate_dev(DEVICE *dev);
+void    term_dev(DEVICE *dev);
+char *  strerror_dev(DEVICE *dev);
+void    clrerror_dev(DEVICE *dev, int func);
+bool    update_pos_dev(DEVICE *dev);
+bool    rewind_dev(DEVICE *dev);
+bool    load_dev(DEVICE *dev);
+bool    offline_dev(DEVICE *dev);
+int     flush_dev(DEVICE *dev);
+int     weof_dev(DEVICE *dev, int num);
+int     write_block(DEVICE *dev);
 uint32_t status_dev(DEVICE *dev);
-int      eod_dev(DEVICE *dev);
-bool     fsf_dev(DEVICE *dev, int num);
-bool     fsr_dev(DEVICE *dev, int num);
-bool     bsf_dev(DEVICE *dev, int num);
-bool     bsr_dev(DEVICE *dev, int num);
-void     attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void     detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR     *next_attached_jcr(DEVICE *dev, JCR *jcr);
-bool     dev_can_write(DEVICE *dev);
-bool     offline_or_rewind_dev(DEVICE *dev);
-bool     reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
-void     init_dev_wait_timers(DEVICE *dev);
-bool     double_dev_wait_time(DEVICE *dev);
+bool    eod_dev(DEVICE *dev);
+bool    fsf_dev(DEVICE *dev, int num);
+bool    fsr_dev(DEVICE *dev, int num);
+bool    bsf_dev(DEVICE *dev, int num);
+bool    bsr_dev(DEVICE *dev, int num);
+void    attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void    detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR    *next_attached_jcr(DEVICE *dev, JCR *jcr);
+bool    dev_can_write(DEVICE *dev);
+bool    offline_or_rewind_dev(DEVICE *dev);
+bool    reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
+void    init_dev_wait_timers(DEVICE *dev);
+bool    double_dev_wait_time(DEVICE *dev);
 
 /* Get info about device */
-char *   dev_vol_name(DEVICE *dev);
+char *  dev_vol_name(DEVICE *dev);
 uint32_t dev_block(DEVICE *dev);
 uint32_t dev_file(DEVICE *dev);
-bool     dev_is_tape(DEVICE *dev);
+bool    dev_is_tape(DEVICE *dev);
 
 /* From device.c */
-bool     open_device(DCR *dcr);
-bool     first_open_device(DEVICE *dev);
-bool     fixup_device_block_write_error(DCR *dcr);
-void     _lock_device(const char *file, int line, DEVICE *dev);
-void     _unlock_device(const char *file, int line, DEVICE *dev);
-void     _block_device(const char *file, int line, DEVICE *dev, int state);
-void     _unblock_device(const char *file, int line, DEVICE *dev);
-void     _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
-void     _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
-void     set_new_volume_parameters(DCR *dcr);
-void     set_new_file_parameters(DCR *dcr);
-bool     device_is_unmounted(DEVICE *dev);
-void     dev_lock(DEVICE *dev);
-void     dev_unlock(DEVICE *dev);
+bool    open_device(DCR *dcr);
+bool    first_open_device(DEVICE *dev);
+bool    fixup_device_block_write_error(DCR *dcr);
+void    _lock_device(const char *file, int line, DEVICE *dev);
+void    _unlock_device(const char *file, int line, DEVICE *dev);
+void    _block_device(const char *file, int line, DEVICE *dev, int state);
+void    _unblock_device(const char *file, int line, DEVICE *dev);
+void    _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
+void    _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
+void    set_new_volume_parameters(DCR *dcr);
+void    set_new_file_parameters(DCR *dcr);
+bool    device_is_unmounted(DEVICE *dev);
+void    dev_lock(DEVICE *dev);
+void    dev_unlock(DEVICE *dev);
 const char *edit_blocked_reason(DEVICE *dev);
 
 /* From dircmd.c */
-void     *handle_connection_request(void *arg);
+void    *handle_connection_request(void *arg);
 
 
 /* From fd_cmds.c */
-void     run_job(JCR *jcr);
-bool     bootstrap_cmd(JCR *jcr);
+void    run_job(JCR *jcr);
+bool    bootstrap_cmd(JCR *jcr);
 
 /* From job.c */
-void     stored_free_jcr(JCR *jcr);
-void     connection_from_filed(void *arg);
-void     handle_filed_connection(BSOCK *fd, char *job_name);
+void    stored_free_jcr(JCR *jcr);
+void    connection_from_filed(void *arg);
+void    handle_filed_connection(BSOCK *fd, char *job_name);
 
 /* From label.c */
-int      read_dev_volume_label(DCR *dcr);
-int      read_dev_volume_label_guess(DCR *dcr, bool write);
-void     create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
-void     create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
-bool     write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
-bool     write_ansi_ibm_label(DCR *dcr, const char *VolName);
-int      read_ansi_ibm_label(DCR *dcr);
-bool     write_session_label(DCR *dcr, int label);
-bool     write_volume_label_to_block(DCR *dcr);
-bool     rewrite_volume_label(DCR *dcr, bool recycle);
-void     dump_volume_label(DEVICE *dev);
-void     dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-bool     unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-bool     unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int     read_dev_volume_label(DCR *dcr);
+int     read_dev_volume_label_guess(DCR *dcr, bool write);
+void    create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
+void    create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
+bool    write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
+#define ANSI_VOL_LABEL 0
+#define ANSI_EOF_LABEL 1
+#define ANSI_EOV_LABEL 2
+bool    write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName);
+int     read_ansi_ibm_label(DCR *dcr);
+bool    write_session_label(DCR *dcr, int label);
+bool    write_volume_label_to_block(DCR *dcr);
+bool    rewrite_volume_label(DCR *dcr, bool recycle);
+void    dump_volume_label(DEVICE *dev);
+void    dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+bool    unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+bool    unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
 
 /* From match_bsr.c */
-int      match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
-              SESSION_LABEL *sesrec);
-int      match_bsr_block(BSR *bsr, DEV_BLOCK *block);
-void     position_bsr_block(BSR *bsr, DEV_BLOCK *block);
-BSR     *find_next_bsr(BSR *root_bsr, DEVICE *dev);
-bool     match_set_eof(BSR *bsr, DEV_RECORD *rec);
+int     match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
+             SESSION_LABEL *sesrec);
+int     match_bsr_block(BSR *bsr, DEV_BLOCK *block);
+void    position_bsr_block(BSR *bsr, DEV_BLOCK *block);
+BSR    *find_next_bsr(BSR *root_bsr, DEVICE *dev);
+bool    match_set_eof(BSR *bsr, DEV_RECORD *rec);
 
 /* From mount.c */
-bool     mount_next_write_volume(DCR *dcr, bool release);
-bool     mount_next_read_volume(DCR *dcr);
-void     release_volume(DCR *ddr);
-void     mark_volume_in_error(DCR *dcr);
+bool    mount_next_write_volume(DCR *dcr, bool release);
+bool    mount_next_read_volume(DCR *dcr);
+void    release_volume(DCR *ddr);
+void    mark_volume_in_error(DCR *dcr);
 
 /* From parse_bsr.c */
-BSR     *parse_bsr(JCR *jcr, char *lf);
-void     dump_bsr(BSR *bsr, bool recurse);
-void     free_bsr(BSR *bsr);
+BSR    *parse_bsr(JCR *jcr, char *lf);
+void    dump_bsr(BSR *bsr, bool recurse);
+void    free_bsr(BSR *bsr);
 VOL_LIST *new_vol();
-int      add_vol(JCR *jcr, VOL_LIST *vol);
-void     free_vol_list(JCR *jcr);
-void     create_vol_list(JCR *jcr);
+int     add_vol(JCR *jcr, VOL_LIST *vol);
+void    free_vol_list(JCR *jcr);
+void    create_vol_list(JCR *jcr);
 
 /* From record.c */
 const char *FI_to_ascii(int fi);
 const char *stream_to_ascii(int stream, int fi);
-bool        write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool        can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool        read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool       write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool       can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool       read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
 DEV_RECORD *new_record();
-void        free_record(DEV_RECORD *rec);
-void        empty_record(DEV_RECORD *rec);
+void       free_record(DEV_RECORD *rec);
+void       empty_record(DEV_RECORD *rec);
 
 /* From read_record.c */
 bool read_records(DCR *dcr,
@@ -212,12 +215,12 @@ bool read_records(DCR *dcr,
        bool mount_cb(DCR *dcr));
 
 /* From spool.c */
-bool    begin_data_spool          (DCR *dcr);
-bool    discard_data_spool        (DCR *dcr);
-bool    commit_data_spool         (DCR *dcr);
-bool    are_attributes_spooled    (JCR *jcr);
-bool    begin_attribute_spool     (JCR *jcr);
-bool    discard_attribute_spool   (JCR *jcr);
-bool    commit_attribute_spool    (JCR *jcr);
-bool    write_block_to_spool_file (DCR *dcr);
-void    list_spool_stats          (BSOCK *bs);
+bool   begin_data_spool          (DCR *dcr);
+bool   discard_data_spool        (DCR *dcr);
+bool   commit_data_spool         (DCR *dcr);
+bool   are_attributes_spooled    (JCR *jcr);
+bool   begin_attribute_spool     (JCR *jcr);
+bool   discard_attribute_spool   (JCR *jcr);
+bool   commit_attribute_spool    (JCR *jcr);
+bool   write_block_to_spool_file (DCR *dcr);
+void   list_spool_stats          (BSOCK *bs);
index a6797f12ad1e91fc75375625ab9d4fbd23e1e211..254b637364bb2d054458a711fc7130c20048eb62 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.6"
-#define BDATE   "11 March 2005"
-#define LSMDATE "11Mar05"
+#define VERSION "1.37.7"
+#define BDATE   "12 March 2005"
+#define LSMDATE "12Mar05"
 
 /* Debug flags */
 #undef  DEBUG