]> git.sur5r.net Git - bacula/bacula/commitdiff
restore + SQL editing cleanups
authorKern Sibbald <kern@sibbald.com>
Sat, 7 Dec 2002 17:05:34 +0000 (17:05 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 7 Dec 2002 17:05:34 +0000 (17:05 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@233 91ce42f0-d328-0410-95d8-f526ca767f89

27 files changed:
bacula/kernstodo
bacula/src/cats/bdb_get.c
bacula/src/cats/protos.h
bacula/src/cats/sql_delete.c
bacula/src/cats/sql_find.c
bacula/src/cats/sql_get.c
bacula/src/dird/sql_cmds.c
bacula/src/dird/ua.h
bacula/src/dird/ua_prune.c
bacula/src/dird/ua_purge.c
bacula/src/dird/ua_restore.c
bacula/src/dird/ua_select.c
bacula/src/lib/Makefile.in
bacula/src/lib/edit.c [new file with mode: 0644]
bacula/src/lib/protos.h
bacula/src/lib/util.c
bacula/src/stored/acquire.c
bacula/src/stored/block.c
bacula/src/stored/block.h
bacula/src/stored/bsr.h
bacula/src/stored/match_bsr.c
bacula/src/stored/parse_bsr.c
bacula/src/stored/read_record.c
bacula/src/stored/record.c
bacula/src/stored/record.h
bacula/src/tools/Makefile.in
bacula/src/version.h

index 36180a407100b3d4f817327ff773485ee14c0a25..3dab6db3736de3bebf3ac689b1ca8ee747fe4f95 100644 (file)
@@ -7,10 +7,10 @@ Documentation to do: (a little bit at a time)
 - Document query file format.
 
 Testing to do: (painful)
-- that restore options work in FD.
+- that restore options work in FD (mostly done).
 - that console command line options work
 - blocksize recognition code.
-- Test new BSR code
+- Test new BSR code (mostly done).
 
 
 For 1.28 release:
@@ -21,7 +21,6 @@ For 1.28 release:
 - Get rid of bscan.c:534 error message (one time only).
 - Print some statistics when get EOF on device in bscan -- feedback
   to let user know it is working.
-- Add code to put VolFile in bsr for restore command.
 - Add code to reject whole blocks if not wanted on restore.
 - Add watchdog timeout for child processes start_child_timer()
   end_child_timer();
@@ -621,3 +620,6 @@ Done: (see kernsdone for more)
 - Make BSR accept count (total files to be restored).
 - Add code to fast seek to proper place on tape/file when doing Restore.
 - Replace popen() and pclose() -- fail safe and timeout, no SIG dep.
+- Add code to put VolFile in bsr for restore command.
+- Volumes can be listed multiple times in Restore volume list.
+
index 0b96eb5e1246c1b43a6ebe672af5d21888052118..60dc10c5c0a51e8878114ab2a397cfc02d4d56b2 100644 (file)
@@ -497,5 +497,11 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr)
 int db_get_job_volume_parameters(B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
 { return 0; }
 
+int db_get_client_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
+{ return 0; }
+
+
+int db_get_client_record(B_DB *mdb, CLIENT_DBR *cdbr)
+{ return 0; }
 
 #endif /* HAVE_BACULA_DB */
index a6a19b3828225270d3e00f8d1612dc685291804f..0d38ed6563ac8e6539f815092ab16dfafdd08f7b 100644 (file)
@@ -73,8 +73,10 @@ int db_get_media_record(B_DB *mdb, MEDIA_DBR *mr);
 int db_get_num_media_records(B_DB *mdb);
 int db_get_num_pool_records(B_DB *mdb);
 int db_get_pool_ids(B_DB *mdb, int *num_ids, uint32_t **ids);
+int db_get_client_ids(B_DB *mdb, int *num_ids, uint32_t **ids);
 int db_get_media_ids(B_DB *mdb, int *num_ids, uint32_t **ids);
 int db_get_job_volume_parameters(B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams);
+int db_get_client_record(B_DB *mdb, CLIENT_DBR *cdbr);
 
 
 /* list.c */
index 74076eb651033f17950558fcfbea1c132d62d651..e2a8ee658f45c53c6208f3d3abe889ebcef365fc 100644 (file)
@@ -141,7 +141,7 @@ static int delete_handler(void *ctx, int num_fields, char **row)
       del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
         del->max_ids);
    }
-   del->JobId[del->num_ids++] = (JobId_t)strtod(row[0], NULL);
+   del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]);
    return 0;
 }
 
index 89901505e0c6944418e5264d82b8cbe48e2c0e2c..b0dc4277f4bab372ec96229f590e665e807a17b9 100644 (file)
@@ -235,23 +235,23 @@ ORDER BY MediaId", mr->PoolId, mr->MediaType, mr->VolStatus);
    }
 
    /* Return fields in Media Record */
-   mr->MediaId = atoi(row[0]);
+   mr->MediaId = str_to_int64(row[0]);
    bstrncpy(mr->VolumeName, row[1], sizeof(mr->VolumeName));
-   mr->VolJobs = atoi(row[2]);
-   mr->VolFiles = atoi(row[3]);
-   mr->VolBlocks = atoi(row[4]);
-   mr->VolBytes = (uint64_t)strtod(row[5], NULL);
-   mr->VolMounts = atoi(row[6]);
-   mr->VolErrors = atoi(row[7]);
-   mr->VolWrites = atoi(row[8]);
-   mr->MaxVolBytes = (uint64_t)strtod(row[9], NULL);
-   mr->VolCapacityBytes = (uint64_t)strtod(row[10], NULL);
-   mr->VolRetention = (utime_t)strtod(row[11], NULL);
-   mr->VolUseDuration = (utime_t)strtod(row[12], NULL);
-   mr->MaxVolJobs = atoi(row[13]);
-   mr->MaxVolFiles = atoi(row[14]);
-   mr->Recycle = atoi(row[15]);
-   mr->Slot = atoi(row[16]);
+   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->VolRetention = str_to_uint64(row[11]);
+   mr->VolUseDuration = str_to_uint64(row[12]);
+   mr->MaxVolJobs = str_to_int64(row[13]);
+   mr->MaxVolFiles = str_to_int64(row[14]);
+   mr->Recycle = str_to_int64(row[15]);
+   mr->Slot = str_to_int64(row[16]);
    bstrncpy(mr->cFirstWritten, row[17]!=NULL?row[17]:"", sizeof(mr->cFirstWritten));
 
    sql_free_result(mdb);
index 2bd972912a5e18609eafb2a2c653852576c56744..0e054c5e16907e385e258b357efeaf0b220a8bac 100644 (file)
@@ -185,7 +185,7 @@ File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
         } else {
-           fdbr->FileId = (FileId_t)strtod(row[0], NULL);
+           fdbr->FileId = (FileId_t)str_to_int64(row[0]);
            strncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
            fdbr->LStat[sizeof(fdbr->LStat)] = 0;
            strncpy(fdbr->MD5, row[2], sizeof(fdbr->MD5));
@@ -342,14 +342,14 @@ FROM Job WHERE JobId=%u", jr->JobId);
       return 0;                      /* failed */
    }
 
-   jr->VolSessionId = atol(row[0]);
-   jr->VolSessionTime = atol(row[1]);
+   jr->VolSessionId = str_to_uint64(row[0]);
+   jr->VolSessionTime = str_to_uint64(row[1]);
    jr->PoolId = atoi(row[2]);
    bstrncpy(jr->cStartTime, row[3]!=NULL?row[3]:"", sizeof(jr->cStartTime));
    bstrncpy(jr->cEndTime, row[4]!=NULL?row[4]:"", sizeof(jr->cEndTime));
    jr->JobFiles = atol(row[5]);
-   jr->JobBytes = (uint64_t)strtod(row[6], NULL);
-   jr->JobTDate = (utime_t)strtod(row[7], NULL);
+   jr->JobBytes = str_to_int64(row[6]);
+   jr->JobTDate = str_to_int64(row[7]);
    bstrncpy(jr->Job, row[8]!=NULL?row[8]:"", sizeof(jr->Job));
    jr->JobStatus = (int)*row[9];
    jr->Type = (int)*row[10];
@@ -520,6 +520,44 @@ int db_get_pool_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
    return stat;
 }
 
+/*
+ * This function returns a list of all the Client record ids.
+ *  The caller must free ids if non-NULL.
+ *
+ *  Returns 0: on failure
+ *         1: on success
+ */
+int db_get_client_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
+{
+   SQL_ROW row;
+   int stat = 0;
+   int i = 0;
+   uint32_t *id;
+
+   db_lock(mdb);
+   *ids = NULL;
+   Mmsg(&mdb->cmd, "SELECT ClientId FROM Client");
+   if (QUERY_DB(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;
+      }
+      sql_free_result(mdb);
+      stat = 1;
+   } else {
+      Mmsg(&mdb->errmsg, _("Client id select failed: ERR=%s\n"), sql_strerror(mdb));
+      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
+      stat = 0;
+   }
+   db_unlock(mdb);
+   return stat;
+}
+
+
 
 /* Get Pool Record   
  * If the PoolId is non-zero, we get its record,
@@ -538,7 +576,7 @@ int db_get_pool_record(B_DB *mdb, POOL_DBR *pdbr)
       Mmsg(&mdb->cmd, 
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,\
 AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,\
-MaxVolBytes,PoolType,LabelFormat FROM Pool WHERE Pool.PoolId=%d", pdbr->PoolId);
+MaxVolBytes,PoolType,LabelFormat FROM Pool WHERE Pool.PoolId=%u", pdbr->PoolId);
    } else {                          /* find by name */
       Mmsg(&mdb->cmd, 
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,\
@@ -558,20 +596,20 @@ MaxVolBytes,PoolType,LabelFormat FROM Pool WHERE Pool.Name='%s'", pdbr->Name);
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
-           pdbr->PoolId = atoi(row[0]);
+           pdbr->PoolId = str_to_int64(row[0]);
             bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
-           pdbr->NumVols = atoi(row[2]);
-           pdbr->MaxVols = atoi(row[3]);
-           pdbr->UseOnce = atoi(row[4]);
-           pdbr->UseCatalog = atoi(row[5]);
-           pdbr->AcceptAnyVolume = atoi(row[6]);
-           pdbr->AutoPrune = atoi(row[7]);
-           pdbr->Recycle = atoi(row[8]);
-           pdbr->VolRetention = (utime_t)strtod(row[9], NULL);
-           pdbr->VolUseDuration = (utime_t)strtod(row[10], NULL);
-           pdbr->MaxVolJobs = atoi(row[11]);
-           pdbr->MaxVolFiles = atoi(row[12]);
-           pdbr->MaxVolBytes = (uint64_t)strtod(row[13], NULL);
+           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[13]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
             bstrncpy(pdbr->LabelFormat, row[14]!=NULL?row[15]:"", sizeof(pdbr->LabelFormat));
            stat = pdbr->PoolId;
@@ -583,6 +621,57 @@ MaxVolBytes,PoolType,LabelFormat FROM Pool WHERE Pool.Name='%s'", pdbr->Name);
    return stat;
 }
 
+/* Get Client Record   
+ * If the ClientId is non-zero, we get its record,
+ *  otherwise, we search on the Client Name
+ *
+ * Returns: 0 on failure
+ *         1 on success 
+ */
+int db_get_client_record(B_DB *mdb, CLIENT_DBR *cdbr)
+{
+   SQL_ROW row;
+   int stat = 0;
+
+   db_lock(mdb);
+   if (cdbr->ClientId != 0) {              /* find by id */
+      Mmsg(&mdb->cmd, 
+"SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention "
+"FROM Client WHERE Client.ClientId=%u", cdbr->ClientId);
+   } else {                          /* find by name */
+      Mmsg(&mdb->cmd, 
+"SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention "
+"FROM Client WHERE Client.Name='%s'", cdbr->Name);
+   }  
+
+   if (QUERY_DB(mdb, mdb->cmd)) {
+      mdb->num_rows = sql_num_rows(mdb);
+      if (mdb->num_rows > 1) {
+        char ed1[30];
+         Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"), 
+           edit_uint64(mdb->num_rows, ed1));
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
+      } else if (mdb->num_rows == 1) {
+        if ((row = sql_fetch_row(mdb)) == NULL) {
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
+        } 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;
+        }
+      }
+      sql_free_result(mdb);
+   }
+   db_unlock(mdb);
+   return stat;
+}
+
+
 /* Get FileSet Record  
  * If the FileSetId is non-zero, we get its record,
  *  otherwise, we search on the name
@@ -729,26 +818,26 @@ FROM Media WHERE VolumeName='%s'", mr->VolumeName);
             Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            /* return values */
-           mr->MediaId = atoi(row[0]);
+           mr->MediaId = str_to_int64(row[0]);
             bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
-           mr->VolJobs = atoi(row[2]);
-           mr->VolFiles = atoi(row[3]);
-           mr->VolBlocks = atoi(row[4]);
-           mr->VolBytes = (uint64_t)strtod(row[5], NULL);
-           mr->VolMounts = atoi(row[6]);
-           mr->VolErrors = atoi(row[7]);
-           mr->VolWrites = atoi(row[8]);
-           mr->MaxVolBytes = (uint64_t)strtod(row[9], NULL);
-           mr->VolCapacityBytes = (uint64_t)strtod(row[10], NULL);
+           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 = atoi(row[13]);
-           mr->VolRetention = (utime_t)strtod(row[14], NULL);
-           mr->VolUseDuration = (utime_t)strtod(row[15], NULL);
-           mr->MaxVolJobs = atoi(row[16]);
-           mr->MaxVolFiles = atoi(row[17]);
-           mr->Recycle = atoi(row[18]);
-           mr->Slot = atoi(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));
            stat = mr->MediaId;
         }
index 5c8b0068715c2e376af7f06f80bae9af3c9f5085..c1bf44d086f7b157074742d76ad8f2d97f00a4a4 100644 (file)
@@ -45,7 +45,7 @@ char *sel_JobMedia = "SELECT JobId FROM JobMedia WHERE MediaId=%u";
 char *select_job =
    "SELECT JobId from Job "    
    "WHERE JobTDate < %s "
-   "AND ClientId=%d "
+   "AND ClientId=%u "
    "AND PurgedFiles=0";
 
 /* Delete temp tables and indexes  */
@@ -70,7 +70,7 @@ char *insert_delcand =
    "INSERT INTO DelCandidates "
    "SELECT JobId, PurgedFiles, FileSetId FROM Job "
    "WHERE JobTDate < %s " 
-   "AND ClientId=%d";
+   "AND ClientId=%u";
 
 /* Select files from the DelCandidates table that have a
  * more recent backup -- i.e. are not the only backup.
@@ -80,7 +80,7 @@ char *select_backup_del =
    "SELECT DelCandidates.JobId "
    "FROM Job,DelCandidates "
    "WHERE Job.JobTDate >= %s "
-   "AND Job.ClientId=%d "
+   "AND Job.ClientId=%u "
    "AND Job.JobType='B' "
    "AND Job.Level='F' "
    "AND Job.JobStatus='T' "
@@ -94,7 +94,7 @@ char *select_verify_del =
    "SELECT DelCandidates.JobId "
    "FROM Job,DelCandidates "
    "WHERE Job.JobTDate >= %s "
-   "AND Job.ClientId=%d "
+   "AND Job.ClientId=%u "
    "AND Job.JobType='V' "
    "AND Job.Level='V' "
    "AND Job.JobStatus='T' "
@@ -108,7 +108,7 @@ char *select_restore_del =
    "SELECT DelCandidates.JobId "
    "FROM Job,DelCandidates "
    "WHERE Job.JobTDate >= %s "
-   "AND Job.ClientId=%d "   
+   "AND Job.ClientId=%u "   
    "AND Job.JobType='R'";
 
 
@@ -169,13 +169,12 @@ char *uar_create_temp =
 
 char *uar_create_temp1 = 
    "CREATE TABLE temp1 (JobId INTEGER UNSIGNED NOT NULL,"
-   "JobTDate BIGINT UNSIGNED,"
-   "ClientId INTEGER UNSIGNED)";
+   "JobTDate BIGINT UNSIGNED)";
 
 char *uar_last_full =
-   "INSERT INTO temp1 SELECT Job.JobId,JobTdate,Job.ClientId "
-   "FROM Client,Job,JobMedia,Media WHERE Client.Name='%s' "
-   "AND Client.ClientId=Job.ClientId "
+   "INSERT INTO temp1 SELECT Job.JobId,JobTdate "
+   "FROM Client,Job,JobMedia,Media WHERE Client.ClientId=%u "
+   "AND Job.ClientId=%u "
    "AND Level='F' AND JobStatus='T' "
    "AND JobMedia.JobId=Job.JobId "
    "AND JobMedia.MediaId=Media.MediaId "
@@ -196,7 +195,7 @@ char *uar_inc =
    "Job.Level,Job.JobFiles,Job.StartTime,Media.VolumeName,JobMedia.StartFile,"
    "Job.VolSessionId,Job.VolSessionTime "
    "FROM Job,JobMedia,Media "
-   "WHERE Job.JobTDate>%d AND Job.ClientId=%u "
+   "WHERE Job.JobTDate>%s AND Job.ClientId=%u "
    "AND JobMedia.JobId=Job.JobId "
    "AND JobMedia.MediaId=Media.MediaId "
    "AND Job.Level='I' AND JobStatus='T' "
@@ -215,7 +214,7 @@ char *uar_sel_all_temp1 = "SELECT * FROM temp1";
 char *uar_sel_fileset = 
    "SELECT FileSet.FileSetId,FileSet.FileSet,FileSet.MD5 FROM Job,"
    "Client,FileSet WHERE Job.FileSetId=FileSet.FileSetId "
-   "AND Job.ClientId=Client.ClientId AND Client.Name='%s' "
+   "AND Job.ClientId=%u AND Client.ClientId=%u "
    "GROUP BY FileSet.FileSetId";
 
 /* Find MediaType used by this Job */
index 1d2b2938c3a53380ecc736bd7d335b4aa9f9109a..98c53dfceace4c8b8d18754376b838adb754c3ef 100644 (file)
@@ -33,19 +33,19 @@ typedef struct s_ua_context {
    JCR *jcr;
    B_DB *db;
    CAT *catalog;
-   POOLMEM *cmd;                      /* return command/name buffer */
-   POOLMEM *args;                     /* command line arguments */
-   char *argk[MAX_ARGS];              /* argument keywords */
-   char *argv[MAX_ARGS];              /* argument values */
-   int argc;                          /* number of arguments */
-   char **prompt;                     /* list of prompts */
-   int max_prompts;                   /* max size of list */
-   int num_prompts;                   /* current number in list */
-   int auto_display_messages;         /* if set, display messages */
+   POOLMEM *cmd;                     /* return command/name buffer */
+   POOLMEM *args;                    /* command line arguments */
+   char *argk[MAX_ARGS];             /* argument keywords */
+   char *argv[MAX_ARGS];             /* argument values */
+   int argc;                         /* number of arguments */
+   char **prompt;                    /* list of prompts */
+   int max_prompts;                  /* max size of list */
+   int num_prompts;                  /* current number in list */
+   int auto_display_messages;        /* if set, display messages */
    int user_notified_msg_pending;     /* set when user notified */
-   int automount;                     /* if set, mount after label */
-   int quit;                          /* if set, quit */
-   int verbose;                       /* set for normal UA verbosity */
+   int automount;                    /* if set, mount after label */
+   int quit;                         /* if set, quit */
+   int verbose;                      /* set for normal UA verbosity */
 } UAContext;
 
 /* ua_cmds.c */
@@ -67,24 +67,26 @@ void prtit(void *ctx, char *msg);
 void bsendmsg(void *sock, char *fmt, ...);
 
 /* ua_select.c */
-STORE   *select_storage_resource(UAContext *ua);
-JOB     *select_job_resource(UAContext *ua);
-JOB     *select_restore_job_resource(UAContext *ua);
-CLIENT  *select_client_resource(UAContext *ua);
+STORE  *select_storage_resource(UAContext *ua);
+JOB    *select_job_resource(UAContext *ua);
+JOB    *select_restore_job_resource(UAContext *ua);
+CLIENT *select_client_resource(UAContext *ua);
 FILESET *select_fileset_resource(UAContext *ua);
-int     select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int     select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int    select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int    select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int    select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
 
-void    start_prompt(UAContext *ua, char *msg);
-void    add_prompt(UAContext *ua, char *prompt);
-int     do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt);
-CAT    *get_catalog_resource(UAContext *ua);           
+void   start_prompt(UAContext *ua, char *msg);
+void   add_prompt(UAContext *ua, char *prompt);
+int    do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt);
+CAT    *get_catalog_resource(UAContext *ua);          
 STORE  *get_storage_resource(UAContext *ua, char *cmd);
-int     get_media_type(UAContext *ua, char *MediaType, int max_media);
-int     get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int    get_media_type(UAContext *ua, char *MediaType, int max_media);
+int    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int    get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
 POOL   *get_pool_resource(UAContext *ua);
 CLIENT *get_client_resource(UAContext *ua);
-int     get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int    get_job_dbr(UAContext *ua, JOB_DBR *jr);
 
 int find_arg_keyword(UAContext *ua, char **list);
 int do_keyword_prompt(UAContext *ua, char *msg, char **list);
index 52a336fa86d09811e6f6b3197a6dc113bfec71b3..994ae3ded8148c3607e4ffa304e4a2f0a798f59b 100644 (file)
@@ -131,8 +131,8 @@ static int job_delete_handler(void *ctx, int num_fields, char **row)
       del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids);
       del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids);
    }
-   del->JobId[del->num_ids] = (JobId_t)strtod(row[0], NULL);
-   del->PurgedFiles[del->num_ids++] = (char)atoi(row[0]);
+   del->JobId[del->num_ids] = (JobId_t)str_to_int64(row[0]);
+   del->PurgedFiles[del->num_ids++] = (char)str_to_int64(row[0]);
    return 0;
 }
 
@@ -148,7 +148,7 @@ static int file_delete_handler(void *ctx, int num_fields, char **row)
       del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
         del->max_ids);
    }
-   del->JobId[del->num_ids++] = (JobId_t)strtod(row[0], NULL);
+   del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]);
    return 0;
 }
 
index e45b89d3340a74a3ecd06cd46166e7920041af29..970872ca509f4b0f0246c3a710da67b8770e2de1 100644 (file)
@@ -132,8 +132,8 @@ static int job_delete_handler(void *ctx, int num_fields, char **row)
       del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids);
       del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids);
    }
-   del->JobId[del->num_ids] = (JobId_t)strtod(row[0], NULL);
-   del->PurgedFiles[del->num_ids++] = (char)atoi(row[0]);
+   del->JobId[del->num_ids] = (JobId_t)str_to_int64(row[0]);
+   del->PurgedFiles[del->num_ids++] = (char)str_to_int64(row[0]);
    return 0;
 }
 
@@ -149,7 +149,7 @@ static int file_delete_handler(void *ctx, int num_fields, char **row)
       del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
         del->max_ids);
    }
-   del->JobId[del->num_ids++] = (JobId_t)strtod(row[0], NULL);
+   del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]);
    return 0;
 }
 
index c85a4aa2ce51d6a66796ecd2b3e36f9d8e4ab2dc..28989903456633a33ea35c0c27a1fb5244f939ae 100644 (file)
@@ -59,10 +59,9 @@ typedef struct s_tree_ctx {
 /* Main structure for obtaining JobIds */
 typedef struct s_jobids {
    utime_t JobTDate;
-   uint32_t ClientId;
    uint32_t TotalFiles;
+   char ClientName[MAX_NAME_LENGTH];
    char JobIds[200];
-   CLIENT *client;
    STORE  *store;
 } JobIds;
 
@@ -80,11 +79,8 @@ typedef struct s_rbsr {
    uint32_t JobId;                   /* JobId this bsr */
    uint32_t VolSessionId;                  
    uint32_t VolSessionTime;
-   uint32_t StartFile;
-   uint32_t EndFile;
-   uint32_t StartBlock;
-   uint32_t EndBlock;
-   char *VolumeName;                 /* Volume name */
+   int     VolCount;                 /* Volume parameter count */
+   VOL_PARAMS *VolParams;            /* Volume, start/end file/blocks */
    RBSR_FINDEX *fi;                  /* File indexes this JobId */
 } RBSR;
 
@@ -255,10 +251,10 @@ int restorecmd(UAContext *ua, char *cmd)
       return 0;
    }
 
-   if (ji.client) {
+   if (ji.ClientName[0]) {
       Mmsg(&ua->cmd, 
          "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\"",
-         job->hdr.name, ji.client->hdr.name, ji.store?ji.store->hdr.name:"",
+         job->hdr.name, ji.ClientName, ji.store?ji.store->hdr.name:"",
         working_directory);
    } else {
       Mmsg(&ua->cmd, 
@@ -284,8 +280,9 @@ int restorecmd(UAContext *ua, char *cmd)
 static int user_select_jobids(UAContext *ua, JobIds *ji)
 {
    char fileset_name[MAX_NAME_LENGTH];
-   char *p;
+   char *p, ed1[50];
    FILESET_DBR fsr;
+   CLIENT_DBR cr;
    JobId_t JobId;
    JOB_DBR jr;
    POOLMEM *query;
@@ -351,16 +348,21 @@ static int user_select_jobids(UAContext *ua, JobIds *ji)
             bsendmsg(ua, "%s\n", db_strerror(ua->db));
         }
         /*
-         * Select Client 
+         * Select Client from the Catalog
          */
-        if (!(ji->client = get_client_resource(ua))) {
+        memset(&cr, 0, sizeof(cr));
+        if (!get_client_dbr(ua, &cr)) {
+           free_pool_memory(query);
+           db_sql_query(ua->db, uar_del_temp, NULL, NULL);
+           db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
            return 0;
         }
+        bstrncpy(ji->ClientName, cr.Name, sizeof(ji->ClientName));
 
         /*
          * Select FileSet 
          */
-        Mmsg(&query, uar_sel_fileset, ji->client->hdr.name);
+        Mmsg(&query, uar_sel_fileset, cr.ClientId, cr.ClientId);
          start_prompt(ua, _("The defined FileSet resources are:\n"));
         if (!db_sql_query(ua->db, query, fileset_handler, (void *)ua)) {
             bsendmsg(ua, "%s\n", db_strerror(ua->db));
@@ -368,6 +370,8 @@ static int user_select_jobids(UAContext *ua, JobIds *ji)
          if (do_prompt(ua, _("Select FileSet resource"), 
                       fileset_name, sizeof(fileset_name)) < 0) {
            free_pool_memory(query);
+           db_sql_query(ua->db, uar_del_temp, NULL, NULL);
+           db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
            return 0;
         }
         fsr.FileSetId = atoi(fileset_name);  /* Id is first part of name */
@@ -378,7 +382,7 @@ static int user_select_jobids(UAContext *ua, JobIds *ji)
         }
 
         /* Find JobId of last Full backup for this client, fileset */
-        Mmsg(&query, uar_last_full, ji->client->hdr.name, fsr.FileSetId);
+        Mmsg(&query, uar_last_full, cr.ClientId, cr.ClientId, fsr.FileSetId);
         if (!db_sql_query(ua->db, query, NULL, NULL)) {
             bsendmsg(ua, "%s\n", db_strerror(ua->db));
         }
@@ -393,7 +397,7 @@ static int user_select_jobids(UAContext *ua, JobIds *ji)
             bsendmsg(ua, "%s\n", db_strerror(ua->db));
         }
         /* Now find all Incremental Jobs */
-        Mmsg(&query, uar_inc, (uint32_t)ji->JobTDate, ji->ClientId, fsr.FileSetId);
+        Mmsg(&query, uar_inc, edit_uint64(ji->JobTDate, ed1), cr.ClientId, fsr.FileSetId);
         if (!db_sql_query(ua->db, query, NULL, NULL)) {
             bsendmsg(ua, "%s\n", db_strerror(ua->db));
         }
@@ -487,8 +491,7 @@ static int last_full_handler(void *ctx, int num_fields, char **row)
 {
    JobIds *ji = (JobIds *)ctx;
 
-   ji->JobTDate = atoi(row[1]);
-   ji->ClientId = atoi(row[2]);
+   ji->JobTDate = strtoll(row[1], NULL, 10);
 
    return 0;
 }
@@ -644,8 +647,8 @@ static void free_bsr(RBSR *bsr)
    if (bsr) {
       free_findex(bsr->fi);
       free_bsr(bsr->next);
-      if (bsr->VolumeName) {
-        free(bsr->VolumeName);
+      if (bsr->VolParams) {
+        free(bsr->VolParams);
       }
       free(bsr);
    }
@@ -658,8 +661,6 @@ static void free_bsr(RBSR *bsr)
 static int complete_bsr(UAContext *ua, RBSR *bsr)
 {
    JOB_DBR jr;
-   VOL_PARAMS *VolParams;
-   int count = 0;
 
    if (bsr) {
       memset(&jr, 0, sizeof(jr));
@@ -670,17 +671,14 @@ static int complete_bsr(UAContext *ua, RBSR *bsr)
       }
       bsr->VolSessionId = jr.VolSessionId;
       bsr->VolSessionTime = jr.VolSessionTime;
-      if ((count=db_get_job_volume_parameters(ua->db, bsr->JobId, &VolParams)) == 0) {
+      if ((bsr->VolCount=db_get_job_volume_parameters(ua->db, bsr->JobId, 
+          &(bsr->VolParams))) == 0) {
          bsendmsg(ua, _("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
-        free((char *)VolParams);
+        if (bsr->VolParams) {
+           free(bsr->VolParams);
+        }
         return 0;
       }
-      bsr->VolumeName = bstrdup(VolParams[0].VolumeName);
-      bsr->StartFile  = VolParams[0].StartFile;
-      bsr->EndFile    = VolParams[0].EndFile;
-      bsr->StartBlock = VolParams[0].StartBlock;
-      bsr->EndBlock   = VolParams[0].EndBlock;
-      free((char *)VolParams);
       return complete_bsr(ua, bsr->next);
    }
    return 1;
@@ -709,11 +707,18 @@ static int write_bsr_file(UAContext *ua, RBSR *bsr)
    fclose(fd);
    bsendmsg(ua, _("Bootstrap records written to %s\n"), fname);
    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) {
-      if (nbsr->VolumeName) {
-         bsendmsg(ua, "   %s\n", nbsr->VolumeName);
+      for (int i=0; i < nbsr->VolCount; i++) {
+        add_prompt(ua, nbsr->VolParams[i].VolumeName);
       }
    }
+   for (int i=1; i < ua->num_prompts; i++) {
+      bsendmsg(ua, "   %s\n", ua->prompt[i]);
+      free(ua->prompt[i]);
+   }
+   ua->num_prompts = 0;
    bsendmsg(ua, "\n");
    free_pool_memory(fname);
    return stat;
@@ -722,13 +727,16 @@ static int write_bsr_file(UAContext *ua, RBSR *bsr)
 static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
 {
    if (bsr) {
-      if (bsr->VolumeName) {
-         fprintf(fd, "Volume=\"%s\"\n", bsr->VolumeName);
+      for (int i=0; i < bsr->VolCount; i++) {
+         fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+         fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
+         fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
+         fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile, 
+                bsr->VolParams[i].EndFile);
+         fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
+                bsr->VolParams[i].EndBlock);
+        write_findex(ua, bsr->fi, fd);
       }
-      fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
-      fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-      fprintf(fd, "VolFile=%u-%u\n", bsr->StartFile, bsr->EndFile);
-      write_findex(ua, bsr->fi, fd);
       write_bsr(ua, bsr->next, fd);
    }
 }
@@ -736,12 +744,16 @@ static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
 static void print_bsr(UAContext *ua, RBSR *bsr)
 {
    if (bsr) {
-      if (bsr->VolumeName) {
-         bsendmsg(ua, "Volume=\"%s\"\n", bsr->VolumeName);
+      for (int i=0; i < bsr->VolCount; i++) {
+         bsendmsg(ua, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+         bsendmsg(ua, "VolSessionId=%u\n", bsr->VolSessionId);
+         bsendmsg(ua, "VolSessionTime=%u\n", bsr->VolSessionTime);
+         bsendmsg(ua, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile, 
+                 bsr->VolParams[i].EndFile);
+         bsendmsg(ua, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
+                 bsr->VolParams[i].EndBlock);
+        print_findex(ua, bsr->fi);
       }
-      bsendmsg(ua, "VolSessionId=%u\n", bsr->VolSessionId);
-      bsendmsg(ua, "VolSessionTime=%u\n", bsr->VolSessionTime);
-      print_findex(ua, bsr->fi);
       print_bsr(ua, bsr->next);
    }
 }
index 0e982291e1644ff06ef2cc38b070d36b7bd51426..25aaa746c10fda4e79e6971280e03e07c6b59dbc 100644 (file)
@@ -254,6 +254,92 @@ CLIENT *get_client_resource(UAContext *ua)
    return select_client_resource(ua);
 }
 
+/* Scan what the user has entered looking for:
+ * 
+ *  client=<client-name>
+ *
+ *  if error or not found, put up a list of client DBRs
+ *  to choose from.
+ *
+ *   returns: 0 on error
+ *           1 on success and fills in CLIENT_DBR
+ */
+int get_client_dbr(UAContext *ua, CLIENT_DBR *cr)
+{
+   int i;
+
+   if (cr->Name[0]) {                /* If name already supplied */
+      if (db_get_client_record(ua->db, cr)) {
+        return 1;
+      }
+      bsendmsg(ua, _("Could not find Client %s: ERR=%s"), cr->Name, db_strerror(ua->db));
+   }
+   for (i=1; i<ua->argc; i++) {
+      if (strcasecmp(ua->argk[i], _("client")) == 0 && ua->argv[i]) {
+        bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name));
+        if (!db_get_client_record(ua->db, cr)) {
+            bsendmsg(ua, _("Could not find Client %s: ERR=%s"), ua->argv[i],
+                    db_strerror(ua->db));
+           cr->ClientId = 0;
+           break;
+        }
+        return 1;
+      }
+   }
+   if (!select_client_dbr(ua, cr)) {  /* try once more by proposing a list */
+      return 0;
+   }
+   return 1;
+}
+
+/*
+ * Select a Client record from the catalog
+ *  Returns 1 on success
+ *         0 on failure
+ */
+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
+{
+   CLIENT_DBR ocr;
+   char name[MAX_NAME_LENGTH];
+   int num_clients, i;
+   uint32_t *ids; 
+
+
+   cr->ClientId = 0;
+   if (!db_get_client_ids(ua->db, &num_clients, &ids)) {
+      bsendmsg(ua, _("Error obtaining client ids. ERR=%s\n"), db_strerror(ua->db));
+      return 0;
+   }
+   if (num_clients <= 0) {
+      bsendmsg(ua, _("No clients defined. Run a job to create one.\n"));
+      return 0;
+   }
+     
+   start_prompt(ua, _("Defined Clients:\n"));
+   for (i=0; i < num_clients; i++) {
+      ocr.ClientId = ids[i];
+      if (!db_get_client_record(ua->db, &ocr)) {
+        continue;
+      }
+      add_prompt(ua, ocr.Name);
+   }
+   free(ids);
+   if (do_prompt(ua, _("Select the Client"), name, sizeof(name)) < 0) {
+      return 0;
+   }
+   memset(&ocr, 0, sizeof(ocr));
+   bstrncpy(ocr.Name, name, sizeof(ocr.Name));
+
+   if (!db_get_client_record(ua->db, &ocr)) {
+      bsendmsg(ua, _("Could not find Client %s: ERR=%s"), name, db_strerror(ua->db));
+      return 0;
+   }
+   memcpy(cr, &ocr, sizeof(ocr));
+   return 1;
+}
+
+
+
 /* Scan what the user has entered looking for:
  * 
  *  pool=<pool-name>   
@@ -262,7 +348,7 @@ CLIENT *get_client_resource(UAContext *ua)
  *  to choose from.
  *
  *   returns: 0 on error
- *           poolid on success and fills in POOL_DBR
+ *           1 on success and fills in POOL_DBR
  */
 int get_pool_dbr(UAContext *ua, POOL_DBR *pr)
 {
@@ -289,7 +375,7 @@ int get_pool_dbr(UAContext *ua, POOL_DBR *pr)
    if (!select_pool_dbr(ua, pr)) {  /* try once more */
       return 0;
    }
-   return pr->PoolId;
+   return 1;
 }
 
 /*
@@ -325,7 +411,7 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
    if (do_prompt(ua, _("Select the Pool"), name, sizeof(name)) < 0) {
       return 0;
    }
-   memset(&opr, 0, sizeof(pr));
+   memset(&opr, 0, sizeof(opr));
    bstrncpy(opr.Name, name, sizeof(opr.Name));
 
    if (!db_get_pool_record(ua->db, &opr)) {
@@ -333,7 +419,7 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
       return 0;
    }
    memcpy(pr, &opr, sizeof(opr));
-   return opr.PoolId;
+   return 1;
 }
 
 /*
index 6375186ee0f0ddbeabc6616f0a2c8afe0c033a6a..1cc8a4b6b332ec41fd6e316297b2f69f1a27881f 100644 (file)
@@ -33,7 +33,7 @@ dummy:
 
 LIBSRCS = alloc.c base64.c bmisc.c bnet.c bnet_server.c \
          bpipe.c bshm.c btime.c \
-         cram-md5.c crc32.c daemon.c fnmatch.c \
+         cram-md5.c crc32.c daemon.c edit.c fnmatch.c \
          hmac.c idcache.c jcr.c lex.c  \
          md5.c message.c mem_pool.c parse_conf.c \
          queue.c rwlock.c serial.c \
@@ -43,7 +43,7 @@ LIBSRCS = alloc.c base64.c bmisc.c bnet.c bnet_server.c \
 
 LIBOBJS = alloc.o base64.o bmisc.o bnet.o bnet_server.o \
          bpipe.o bshm.o btime.o \
-         cram-md5.o crc32.o daemon.o fnmatch.o \
+         cram-md5.o crc32.o daemon.o edit.o fnmatch.o \
          hmac.o idcache.o jcr.o lex.o  \
          md5.o message.o mem_pool.o parse_conf.o \
          queue.o rwlock.o serial.o \
diff --git a/bacula/src/lib/edit.c b/bacula/src/lib/edit.c
new file mode 100644 (file)
index 0000000..cf9b044
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ *   edit.c  edit string to ascii, and ascii to internal 
+ * 
+ *    Kern Sibbald, December MMII
+ *
+ *   Version $Id$
+ */
+
+/*
+   Copyright (C) 2000, 2001, 2002 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"
+
+/* We assume ASCII input and don't worry about overflow */
+uint64_t str_to_uint64(char *str) 
+{
+   register char *p = str;
+   register uint64_t value = 0;
+
+   while (B_ISSPACE(*p)) {
+      p++;
+   }
+   if (*p == '+') {
+      p++;
+   }
+   while (B_ISDIGIT(*p)) {
+      value = value * 10 + *p - '0';
+      p++;
+   }
+   return value;
+}
+
+int64_t str_to_int64(char *str) 
+{
+   register char *p = str;
+   register int64_t value;
+   int negative = FALSE;
+
+   while (B_ISSPACE(*p)) {
+      p++;
+   }
+   if (*p == '+') {
+      p++;
+   } else if (*p == '-') {
+      negative = TRUE;
+      p++;
+   }
+   value = str_to_uint64(p);
+   if (negative) {
+      value = -value;
+   }
+   return value;
+}
+
+
+
+/*
+ * Edit an integer number with commas, the supplied buffer
+ * must be at least 27 bytes long.  The incoming number
+ * is always widened to 64 bits.
+ */
+char *edit_uint64_with_commas(uint64_t val, char *buf)
+{
+   sprintf(buf, "%" lld, val);
+   return add_commas(buf, buf);
+}
+
+/*
+ * Edit an integer number, the supplied buffer
+ * must be at least 27 bytes long.  The incoming number
+ * is always widened to 64 bits.
+ */
+char *edit_uint64(uint64_t val, char *buf)
+{
+   sprintf(buf, "%" lld, val);
+   return buf;
+}
+
+
+/*
+ * Convert a string duration to utime_t (64 bit seconds)
+ * Returns 0: if error
+          1: if OK, and value stored in value
+ */
+int duration_to_utime(char *str, utime_t *value)
+{
+   int i, ch, len;
+   double val;
+   static int  mod[] = {'*', 's', 'n', 'h', 'd', 'w', 'm', 'q', 'y', 0};
+   static int mult[] = {1,    1,  60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, 
+                 60*60*24*91, 60*60*24*365};
+
+   /* Look for modifier */
+   len = strlen(str);
+   ch = str[len - 1];
+   i = 0;
+   if (B_ISALPHA(ch)) {
+      if (B_ISUPPER(ch)) {
+        ch = tolower(ch);
+      }
+      while (mod[++i] != 0) {
+        if (ch == mod[i]) {
+           len--;
+           str[len] = 0; /* strip modifier */
+           break;
+        }
+      }
+   }
+   if (mod[i] == 0 || !is_a_number(str)) {
+      return 0;
+   }
+   val = strtod(str, NULL);
+   if (errno != 0 || val < 0) {
+      return 0;
+   }
+   *value = (utime_t)(val * mult[i]);
+   return 1;
+
+}
+
+/*
+ * Edit a utime "duration" into ASCII
+ */
+char *edit_utime(utime_t val, char *buf)
+{
+   char mybuf[30];
+   static int mult[] = {60*60*24*365, 60*60*24*30, 60*60*24, 60*60, 60};
+   static char *mod[]  = {"year",  "month",  "day", "hour", "min"};
+   int i;
+   uint32_t times;
+
+   *buf = 0;
+   for (i=0; i<5; i++) {
+      times = val / mult[i];
+      if (times > 0) {
+        val = val - (utime_t)times * mult[i];
+         sprintf(mybuf, "%d %s%s ", times, mod[i], times>1?"s":"");
+        strcat(buf, mybuf);
+      }
+   }
+   if (val == 0 && strlen(buf) == 0) {    
+      strcat(buf, "0 secs");
+   } else if (val != 0) {
+      sprintf(mybuf, "%d sec%s", (uint32_t)val, val>1?"s":"");
+      strcat(buf, mybuf);
+   }
+   return buf;
+}
+
+/*
+ * Convert a size size in bytes to uint64_t
+ * Returns 0: if error
+          1: if OK, and value stored in value
+ */
+int size_to_uint64(char *str, int str_len, uint64_t *rtn_value)
+{
+   int i, ch;
+   double value;
+   int mod[]  = {'*', 'k', 'm', 'g', 0}; /* first item * not used */
+   uint64_t mult[] = {1,            /* byte */
+                     1024,          /* kilobyte */
+                     1048576,       /* megabyte */
+                     1073741824};   /* gigabyte */
+
+#ifdef we_have_a_compiler_that_works
+   int mod[]  = {'*', 'k', 'm', 'g', 't', 0};
+   uint64_t mult[] = {1,            /* byte */
+                     1024,          /* kilobyte */
+                     1048576,       /* megabyte */
+                     1073741824,    /* gigabyte */
+                     1099511627776};/* terabyte */
+#endif
+
+   Dmsg0(400, "Enter sized to uint64\n");
+
+   /* Look for modifier */
+   ch = str[str_len - 1];
+   i = 0;
+   if (B_ISALPHA(ch)) {
+      if (B_ISUPPER(ch)) {
+        ch = tolower(ch);
+      }
+      while (mod[++i] != 0) {
+        if (ch == mod[i]) {
+           str_len--;
+           str[str_len] = 0; /* strip modifier */
+           break;
+        }
+      }
+   }
+   if (mod[i] == 0 || !is_a_number(str)) {
+      return 0;
+   }
+   Dmsg3(400, "size str=:%s: %f i=%d\n", str, strtod(str, NULL), i);
+
+   value = (uint64_t)strtod(str, NULL);
+   Dmsg1(400, "Int value = %d\n", (int)value);
+   if (errno != 0 || value < 0) {
+      return 0;
+   }
+   *rtn_value = (uint64_t)(value * mult[i]);
+   Dmsg2(400, "Full value = %f %" lld "\n", strtod(str, NULL) * mult[i],
+       value *mult[i]);
+   return 1;
+}
+
+/*
+ * Check if specified string is a number or not.
+ *  Taken from SQLite, cool, thanks.
+ */
+int is_a_number(const char *n)
+{
+   int digit_seen = 0;
+
+   if( *n == '-' || *n == '+' ) {
+      n++;
+   }
+   while (B_ISDIGIT(*n)) {
+      digit_seen = 1;
+      n++;
+   }
+   if (digit_seen && *n == '.') {
+      n++;
+      while (B_ISDIGIT(*n)) { n++; }
+   }
+   if (digit_seen && (*n == 'e' || *n == 'E')
+       && (B_ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && B_ISDIGIT(n[2])))) {
+      n += 2;                        /* skip e- or e+ or e digit */
+      while (B_ISDIGIT(*n)) { n++; }
+   }
+   return digit_seen && *n==0;
+}
+
+/*
+ * Add commas to a string, which is presumably
+ * a number.  
+ */
+char *add_commas(char *val, char *buf)
+{
+   int len, nc;
+   char *p, *q;
+   int i;
+
+   if (val != buf) {
+      strcpy(buf, val);
+   }
+   len = strlen(buf);
+   if (len < 1) {
+      len = 1;
+   }
+   nc = (len - 1) / 3;
+   p = buf+len;
+   q = p + nc;
+   *q-- = *p--;
+   for ( ; nc; nc--) {
+      for (i=0; i < 3; i++) {
+         *q-- = *p--;
+      }
+      *q-- = ',';
+   }   
+   return buf;
+}
index d82ffab399d86f5fc0895b92cbb5997635a58969..d996455aec74c6d4f3bb3d82497f42c3185ec416 100644 (file)
  */
 
 /* base64.c */
-void      base64_init            (void);
-int       to_base64              (intmax_t value, char *where);
-int       from_base64            (intmax_t *value, char *where);
-int       bin_to_base64          (char *buf, char *bin, int len);
+void     base64_init            (void);
+int      to_base64              (intmax_t value, char *where);
+int      from_base64            (intmax_t *value, char *where);
+int      bin_to_base64          (char *buf, char *bin, int len);
 
 /* bmisc.c */
-char     *bstrncpy               (char *dest, const char *src, int maxlen);
-char     *bstrncat               (char *dest, const char *src, int maxlen);
-void     *b_malloc               (char *file, int line, size_t size);
+char    *bstrncpy               (char *dest, const char *src, int maxlen);
+char    *bstrncat               (char *dest, const char *src, int maxlen);
+void    *b_malloc               (char *file, int line, size_t size);
 #ifndef DEBUG
-void     *bmalloc                (size_t size);
+void    *bmalloc                (size_t size);
 #endif
-void     *brealloc               (void *buf, size_t size);
-void     *bcalloc                (size_t size1, size_t size2);
-int       bsnprintf              (char *str, size_t size, const  char  *format, ...);
-int       bvsnprintf             (char *str, size_t size, const char  *format, va_list ap);
-int       pool_sprintf           (char *pool_buf, char *fmt, ...);
-void      create_pid_file        (char *dir, char *progname, int port);
-int       delete_pid_file        (char *dir, char *progname, int port);
+void    *brealloc               (void *buf, size_t size);
+void    *bcalloc                (size_t size1, size_t size2);
+int      bsnprintf              (char *str, size_t size, const  char  *format, ...);
+int      bvsnprintf             (char *str, size_t size, const char  *format, va_list ap);
+int      pool_sprintf           (char *pool_buf, char *fmt, ...);
+void     create_pid_file        (char *dir, char *progname, int port);
+int      delete_pid_file        (char *dir, char *progname, int port);
 
 
 /* bnet.c */
-int32_t    bnet_recv             (BSOCK *bsock);
-int        bnet_send             (BSOCK *bsock);
-int        bnet_fsend              (BSOCK *bs, char *fmt, ...);
-int        bnet_set_buffer_size    (BSOCK *bs, uint32_t size, int rw);
-int        bnet_sig                (BSOCK *bs, int sig);
-BSOCK *    bnet_connect            (void *jcr, int retry_interval,
-               int max_retry_time, char *name, char *host, char *service, 
-               int port, int verbose);
-int        bnet_wait_data         (BSOCK *bsock, int sec);
-void       bnet_close            (BSOCK *bsock);
-BSOCK *    init_bsock            (void *jcr, int sockfd, char *who, char *ip, int port);
-BSOCK *    dup_bsock             (BSOCK *bsock);
-void       term_bsock            (BSOCK *bsock);
-char *     bnet_strerror         (BSOCK *bsock);
-char *     bnet_sig_to_ascii     (BSOCK *bsock);
-int        bnet_wait_data        (BSOCK *bsock, int sec);
-int        bnet_despool          (BSOCK *bsock);
-int        is_bnet_stop          (BSOCK *bsock);
-int        is_bnet_error         (BSOCK *bsock);
+int32_t    bnet_recv            (BSOCK *bsock);
+int       bnet_send             (BSOCK *bsock);
+int       bnet_fsend              (BSOCK *bs, char *fmt, ...);
+int       bnet_set_buffer_size    (BSOCK *bs, uint32_t size, int rw);
+int       bnet_sig                (BSOCK *bs, int sig);
+BSOCK *    bnet_connect           (void *jcr, int retry_interval,
+              int max_retry_time, char *name, char *host, char *service, 
+              int port, int verbose);
+int       bnet_wait_data         (BSOCK *bsock, int sec);
+void      bnet_close            (BSOCK *bsock);
+BSOCK *    init_bsock           (void *jcr, int sockfd, char *who, char *ip, int port);
+BSOCK *    dup_bsock            (BSOCK *bsock);
+void      term_bsock            (BSOCK *bsock);
+char *    bnet_strerror         (BSOCK *bsock);
+char *    bnet_sig_to_ascii     (BSOCK *bsock);
+int       bnet_wait_data        (BSOCK *bsock, int sec);
+int       bnet_despool          (BSOCK *bsock);
+int       is_bnet_stop          (BSOCK *bsock);
+int       is_bnet_error         (BSOCK *bsock);
 
 
 /* cram-md5.c */
 int cram_md5_get_auth(BSOCK *bs, char *password);
 int cram_md5_auth(BSOCK *bs, char *password);
 void hmac_md5(uint8_t* text, int text_len, uint8_t*  key,
-              int key_len, uint8_t *hmac);
+             int key_len, uint8_t *hmac);
 
 /* crc32.c */
 uint32_t bcrc32(uint8_t *buf, int len);
 
 /* daemon.c */
-void     daemon_start            ();
+void    daemon_start            ();
+
+/* edit.c */
+uint64_t        str_to_uint64(char *str);
+int64_t         str_to_int64(char *str);
+char *          edit_uint64_with_commas   (uint64_t val, char *buf);
+char *          add_commas              (char *val, char *buf);
+char *          edit_uint64             (uint64_t val, char *buf);
+int             duration_to_utime       (char *str, utime_t *value);
+int             size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
+char            *edit_utime             (utime_t val, char *buf);
+int             is_a_number             (const char *num);
 
 /* lex.c */
-LEX *     lex_close_file         (LEX *lf);
-LEX *     lex_open_file          (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
-int       lex_get_char           (LEX *lf);
-void      lex_unget_char         (LEX *lf);
-char *    lex_tok_to_str         (int token);
-int       lex_get_token          (LEX *lf, int expect);
+LEX *    lex_close_file         (LEX *lf);
+LEX *    lex_open_file          (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
+int      lex_get_char           (LEX *lf);
+void     lex_unget_char         (LEX *lf);
+char *   lex_tok_to_str         (int token);
+int      lex_get_token          (LEX *lf, int expect);
 
 /* message.c */
-void       my_name_is            (int argc, char *argv[], char *name);
-void       init_msg              (void *jcr, MSGS *msg);
-void       term_msg              (void);
-void       close_msg             (void *jcr);
-void       add_msg_dest          (MSGS *msg, int dest, int type, char *where, char *dest_code);
-void       rem_msg_dest          (MSGS *msg, int dest, int type, char *where);
-void       Jmsg                  (void *jcr, int type, int level, char *fmt, ...);
-void       dispatch_message      (void *jcr, int type, int level, char *buf);
-void       init_console_msg      (char *wd);
-void       free_msgs_res         (MSGS *msgs);
-int        open_spool_file       (void *jcr, BSOCK *bs);
-int        close_spool_file      (void *vjcr, BSOCK *bs);
+void      my_name_is            (int argc, char *argv[], char *name);
+void      init_msg              (void *jcr, MSGS *msg);
+void      term_msg              (void);
+void      close_msg             (void *jcr);
+void      add_msg_dest          (MSGS *msg, int dest, int type, char *where, char *dest_code);
+void      rem_msg_dest          (MSGS *msg, int dest, int type, char *where);
+void      Jmsg                  (void *jcr, int type, int level, char *fmt, ...);
+void      dispatch_message      (void *jcr, int type, int level, char *buf);
+void      init_console_msg      (char *wd);
+void      free_msgs_res         (MSGS *msgs);
+int       open_spool_file       (void *jcr, BSOCK *bs);
+int       close_spool_file      (void *vjcr, BSOCK *bs);
 
 
 /* bnet_server.c */
-void       bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, 
-                   void handle_client_request(void *bsock));
-void             bnet_server             (int port, void handle_client_request(BSOCK *bsock));
-int              net_connect             (int port);
-BSOCK *          bnet_bind               (int port);
-BSOCK *          bnet_accept             (BSOCK *bsock, char *who);
+void      bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, 
+                  void handle_client_request(void *bsock));
+void            bnet_server             (int port, void handle_client_request(BSOCK *bsock));
+int             net_connect             (int port);
+BSOCK *         bnet_bind               (int port);
+BSOCK *         bnet_accept             (BSOCK *bsock, char *who);
 
 /* signal.c */
-void             init_signals             (void terminate(int sig));
-void             init_stack_dump          (void);
+void            init_signals             (void terminate(int sig));
+void            init_stack_dump          (void);
 
 /* util.c */
-void             lcase                   (char *str);
-void             bash_spaces             (char *str);
-void             unbash_spaces           (char *str);
-void             strip_trailing_junk     (char *str);
-void             strip_trailing_slashes  (char *dir);
-int              skip_spaces             (char **msg);
-int              skip_nonspaces          (char **msg);
-int              fstrsch                 (char *a, char *b);
-char *           encode_time             (time_t time, char *buf);
-char *           encode_mode             (mode_t mode, char *buf);
-char *           edit_uint64_with_commas   (uint64_t val, char *buf);
-char *           add_commas              (char *val, char *buf);
-char *           edit_uint64             (uint64_t val, char *buf);
-int              do_shell_expansion      (char *name);
-int              is_a_number             (const char *num);
-int              is_buf_zero             (char *buf, int len);
-int              duration_to_utime       (char *str, utime_t *value);
-int              size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
-char             *edit_utime             (utime_t val, char *buf);
-void             jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
-void             pm_strcat               (POOLMEM **pm, char *str);
-void             pm_strcpy               (POOLMEM **pm, char *str);
-int              run_program             (char *prog, int wait, POOLMEM *results);
-char *           job_type_to_str         (int type);
-char *           job_status_to_str       (int stat);
-char *           job_level_to_str        (int level);
-void             makeSessionKey          (char *key, char *seed, int mode);
-BPIPE *          open_bpipe(char *prog, int wait, char *mode);
-int              close_wpipe(BPIPE *bpipe);
-int              close_bpipe(BPIPE *bpipe);
+void            lcase                   (char *str);
+void            bash_spaces             (char *str);
+void            unbash_spaces           (char *str);
+void            strip_trailing_junk     (char *str);
+void            strip_trailing_slashes  (char *dir);
+int             skip_spaces             (char **msg);
+int             skip_nonspaces          (char **msg);
+int             fstrsch                 (char *a, char *b);
+char *          encode_time             (time_t time, char *buf);
+char *          encode_mode             (mode_t mode, char *buf);
+int             do_shell_expansion      (char *name);
+int             is_buf_zero             (char *buf, int len);
+void            jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
+void            pm_strcat               (POOLMEM **pm, char *str);
+void            pm_strcpy               (POOLMEM **pm, char *str);
+int             run_program             (char *prog, int wait, POOLMEM *results);
+char *          job_type_to_str         (int type);
+char *          job_status_to_str       (int stat);
+char *          job_level_to_str        (int level);
+void            makeSessionKey          (char *key, char *seed, int mode);
+BPIPE *         open_bpipe(char *prog, int wait, char *mode);
+int             close_wpipe(BPIPE *bpipe);
+int             close_bpipe(BPIPE *bpipe);
 
 
 /* watchdog.c */
index cc0da0539ca861ab415d6df97cf66d665d3fbc3e..2c6940aa91994af6929be0c4907e500241d7771e 100644 (file)
@@ -60,214 +60,6 @@ int is_buf_zero(char *buf, int len)
    return 1;
 }
 
-/*
- * Convert a string duration to utime_t (64 bit seconds)
- * Returns 0: if error
-          1: if OK, and value stored in value
- */
-int duration_to_utime(char *str, utime_t *value)
-{
-   int i, ch, len;
-   double val;
-   static int  mod[] = {'*', 's', 'n', 'h', 'd', 'w', 'm', 'q', 'y', 0};
-   static int mult[] = {1,    1,  60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, 
-                 60*60*24*91, 60*60*24*365};
-
-   /* Look for modifier */
-   len = strlen(str);
-   ch = str[len - 1];
-   i = 0;
-   if (B_ISALPHA(ch)) {
-      if (B_ISUPPER(ch)) {
-        ch = tolower(ch);
-      }
-      while (mod[++i] != 0) {
-        if (ch == mod[i]) {
-           len--;
-           str[len] = 0; /* strip modifier */
-           break;
-        }
-      }
-   }
-   if (mod[i] == 0 || !is_a_number(str)) {
-      return 0;
-   }
-   val = strtod(str, NULL);
-   if (errno != 0 || val < 0) {
-      return 0;
-   }
-   *value = (utime_t)(val * mult[i]);
-   return 1;
-
-}
-
-/*
- * Edit a utime "duration" into ASCII
- */
-char *edit_utime(utime_t val, char *buf)
-{
-   char mybuf[30];
-   static int mult[] = {60*60*24*365, 60*60*24*30, 60*60*24, 60*60, 60};
-   static char *mod[]  = {"year",  "month",  "day", "hour", "min"};
-   int i;
-   uint32_t times;
-
-   *buf = 0;
-   for (i=0; i<5; i++) {
-      times = val / mult[i];
-      if (times > 0) {
-        val = val - (utime_t)times * mult[i];
-         sprintf(mybuf, "%d %s%s ", times, mod[i], times>1?"s":"");
-        strcat(buf, mybuf);
-      }
-   }
-   if (val == 0 && strlen(buf) == 0) {    
-      strcat(buf, "0 secs");
-   } else if (val != 0) {
-      sprintf(mybuf, "%d sec%s", (uint32_t)val, val>1?"s":"");
-      strcat(buf, mybuf);
-   }
-   return buf;
-}
-
-/*
- * Convert a size size in bytes to uint64_t
- * Returns 0: if error
-          1: if OK, and value stored in value
- */
-int size_to_uint64(char *str, int str_len, uint64_t *rtn_value)
-{
-   int i, ch;
-   double value;
-   int mod[]  = {'*', 'k', 'm', 'g', 0}; /* first item * not used */
-   uint64_t mult[] = {1,            /* byte */
-                     1024,          /* kilobyte */
-                     1048576,       /* megabyte */
-                     1073741824};   /* gigabyte */
-
-#ifdef we_have_a_compiler_that_works
-   int mod[]  = {'*', 'k', 'm', 'g', 't', 0};
-   uint64_t mult[] = {1,            /* byte */
-                     1024,          /* kilobyte */
-                     1048576,       /* megabyte */
-                     1073741824,    /* gigabyte */
-                     1099511627776};/* terabyte */
-#endif
-
-   Dmsg0(400, "Enter sized to uint64\n");
-
-   /* Look for modifier */
-   ch = str[str_len - 1];
-   i = 0;
-   if (B_ISALPHA(ch)) {
-      if (B_ISUPPER(ch)) {
-        ch = tolower(ch);
-      }
-      while (mod[++i] != 0) {
-        if (ch == mod[i]) {
-           str_len--;
-           str[str_len] = 0; /* strip modifier */
-           break;
-        }
-      }
-   }
-   if (mod[i] == 0 || !is_a_number(str)) {
-      return 0;
-   }
-   Dmsg3(400, "size str=:%s: %f i=%d\n", str, strtod(str, NULL), i);
-
-   value = (uint64_t)strtod(str, NULL);
-   Dmsg1(400, "Int value = %d\n", (int)value);
-   if (errno != 0 || value < 0) {
-      return 0;
-   }
-   *rtn_value = (uint64_t)(value * mult[i]);
-   Dmsg2(400, "Full value = %f %" lld "\n", strtod(str, NULL) * mult[i],
-       value *mult[i]);
-   return 1;
-}
-
-/*
- * Check if specified string is a number or not.
- *  Taken from SQLite, cool, thanks.
- */
-int is_a_number(const char *n)
-{
-   int digit_seen = 0;
-
-   if( *n == '-' || *n == '+' ) {
-      n++;
-   }
-   while (B_ISDIGIT(*n)) {
-      digit_seen = 1;
-      n++;
-   }
-   if (digit_seen && *n == '.') {
-      n++;
-      while (B_ISDIGIT(*n)) { n++; }
-   }
-   if (digit_seen && (*n == 'e' || *n == 'E')
-       && (B_ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && B_ISDIGIT(n[2])))) {
-      n += 2;                        /* skip e- or e+ or e digit */
-      while (B_ISDIGIT(*n)) { n++; }
-   }
-   return digit_seen && *n==0;
-}
-
-
-/*
- * Edit an integer number with commas, the supplied buffer
- * must be at least 27 bytes long.  The incoming number
- * is always widened to 64 bits.
- */
-char *edit_uint64_with_commas(uint64_t val, char *buf)
-{
-   sprintf(buf, "%" lld, val);
-   return add_commas(buf, buf);
-}
-
-/*
- * Edit an integer number, the supplied buffer
- * must be at least 27 bytes long.  The incoming number
- * is always widened to 64 bits.
- */
-char *edit_uint64(uint64_t val, char *buf)
-{
-   sprintf(buf, "%" lld, val);
-   return buf;
-}
-
-
-/*
- * Add commas to a string, which is presumably
- * a number.  
- */
-char *add_commas(char *val, char *buf)
-{
-   int len, nc;
-   char *p, *q;
-   int i;
-
-   if (val != buf) {
-      strcpy(buf, val);
-   }
-   len = strlen(buf);
-   if (len < 1) {
-      len = 1;
-   }
-   nc = (len - 1) / 3;
-   p = buf+len;
-   q = p + nc;
-   *q-- = *p--;
-   for ( ; nc; nc--) {
-      for (i=0; i < 3; i++) {
-         *q-- = *p--;
-      }
-      *q-- = ',';
-   }   
-   return buf;
-}
-
 
 /* Convert a string in place to lower case */
 void lcase(char *str)
index a96519ad227e5e8fe0c7da47af4371ab6f33761a..59418bc86ad4d97c6d24ba3acd765477aa6b6c6e 100644 (file)
@@ -127,7 +127,7 @@ default_path:
    attach_jcr_to_device(dev, jcr);    /* attach jcr to device */
    stat = 1;                         /* good return */
    if ((dev->state & ST_TAPE) && vol->start_file > 0) {
-      Dmsg1(100, "====== Got start_file = %d\n", vol->start_file);
+      Dmsg1(200, "====== Got start_file = %d\n", vol->start_file);
       fsf_dev(dev, vol->start_file);
    }
 
index fdbc19097a02f3b15e75df44ffde024327081daa..c28a7b944d5140211a27c00cbf93fe48bbafc644 100644 (file)
@@ -113,6 +113,7 @@ DEV_BLOCK *new_block(DEVICE *dev)
    } else {
       block->buf_len = dev->max_block_size;
    }
+   block->dev = dev;
    block->block_len = block->buf_len;  /* default block size */
    block->buf = get_memory(block->buf_len); 
    if (block->buf == NULL) {
index 90f10a06ddc7d86328806857b1823a031d2cdbd3..bb9e72a9d964d4aa4397e4dfda4d0083beab00e1 100644 (file)
@@ -84,6 +84,7 @@
  */
 typedef struct s_dev_block {
    struct s_dev_block *next;          /* pointer to next one */
+   void *dev;                         /* pointer to device (DEVICE not defined yet) */
    /* binbuf is the number of bytes remaining
     * in the buffer. For writes, it is bytes not yet written.
     * For reads, it is remaining bytes not yet read.
index 7a86787b89b1f05baae383f6e0695ae0912ea0cc..39acdd562450dd5a416c4673720ed5fffddd78ef 100644 (file)
@@ -47,10 +47,10 @@ typedef struct s_vol_list VOL_LIST;
 
 /*
  * !!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- * !!!                                               !!!
- * !!!   All records must have a pointer to          !!!
- * !!!   the next item as the first item defined.    !!!
- * !!!                                               !!!
+ * !!!                                              !!!
+ * !!!  All records must have a pointer to          !!!
+ * !!!  the next item as the first item defined.    !!!
+ * !!!                                              !!!
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
@@ -68,27 +68,35 @@ typedef struct s_bsr_sessid {
    struct s_bsr_sessid *next;
    uint32_t sessid;
    uint32_t sessid2;
-   int done;                          /* local done */
+   int done;                         /* local done */
 } BSR_SESSID;
 
 typedef struct s_bsr_sesstime {
    struct s_bsr_sesstime *next;
    uint32_t sesstime;
-   int done;                          /* local done */
+   int done;                         /* local done */
 } BSR_SESSTIME;
 
 typedef struct s_bsr_volfile {
    struct s_bsr_volfile *next;
-   uint32_t sfile;                    /* start file */
-   uint32_t efile;                    /* end file */
-   int done;                          /* local done */
+   uint32_t sfile;                   /* start file */
+   uint32_t efile;                   /* end file */
+   int done;                         /* local done */
 } BSR_VOLFILE;
 
+typedef struct s_bsr_volblock {
+   struct s_bsr_volblock *next;
+   uint32_t sblock;                  /* start block */
+   uint32_t eblock;                  /* end block */
+   int done;                         /* local done */
+} BSR_VOLBLOCK;
+
+
 typedef struct s_bsr_findex {
    struct s_bsr_findex *next;
-   int32_t findex;                    /* start file index */
-   int32_t findex2;                   /* end file index */
-   int done;                          /* local done */
+   int32_t findex;                   /* start file index */
+   int32_t findex2;                  /* end file index */
+   int done;                         /* local done */
 } BSR_FINDEX;
 
 typedef struct s_bsr_jobid {
@@ -115,27 +123,28 @@ typedef struct s_bsr_job {
 
 typedef struct s_bsr_stream {
    struct s_bsr_stream *next;
-   int32_t stream;                    /* stream desired */
+   int32_t stream;                   /* stream desired */
 } BSR_STREAM;
 
 typedef struct s_bsr {
-   struct s_bsr *next;                /* pointer to next one */
-   int           done;                /* set when everything found */
-   BSR_VOLUME   *volume;
-   int32_t       Slot;                /* Slot */
-   uint32_t      count;               /* count of files to restore this bsr */
-   uint32_t      found;               /* count of restored files this bsr */
-   BSR_VOLFILE  *volfile;
+   struct s_bsr *next;               /* pointer to next one */
+   int          done;                /* set when everything found */
+   BSR_VOLUME  *volume;
+   int32_t      Slot;                /* Slot */
+   uint32_t     count;               /* count of files to restore this bsr */
+   uint32_t     found;               /* count of restored files this bsr */
+   BSR_VOLFILE *volfile;
+   BSR_VOLBLOCK *volblock;
    BSR_SESSTIME *sesstime;
-   BSR_SESSID   *sessid;
-   BSR_JOBID    *JobId;
-   BSR_JOB      *job;
-   BSR_CLIENT   *client;
-   BSR_FINDEX   *FileIndex;
-   BSR_JOBTYPE  *JobType;
+   BSR_SESSID  *sessid;
+   BSR_JOBID   *JobId;
+   BSR_JOB     *job;
+   BSR_CLIENT  *client;
+   BSR_FINDEX  *FileIndex;
+   BSR_JOBTYPE *JobType;
    BSR_JOBLEVEL *JobLevel;
-   BSR_STREAM   *stream;
-// FF_PKT *ff;                        /* include/exclude */
+   BSR_STREAM  *stream;
+// FF_PKT *ff;                       /* include/exclude */
 } BSR;
 
 
index aa564d0c347688d07955b81a8b114f8c1f17029a..da72874d597e6ed28b4b619d78842790f4220a6f 100755 (executable)
@@ -85,10 +85,9 @@ static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
    if (!match_volume(bsr, bsr->volume, volrec, 1)) {
       goto no_match;
    }
-   /* Not yet working */
-// if (!match_volfile(bsr, bsr->volfile, rec, 1)) {
-//    goto no_match;
-// }
+   if (!match_volfile(bsr, bsr->volfile, rec, 1)) {
+      goto no_match;
+   }
    if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
       goto no_match;
    }
@@ -222,6 +221,12 @@ static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, int do
    if (!volfile) {
       return 1;                      /* no specification matches all */
    }
+   /* For the moment, these tests work only with tapes. */
+   if (!(rec->state & REC_ISTAPE)) {
+      return 1;                      /* All File records OK for this match */
+   }
+// Dmsg3(000, "match_volfile: sfile=%d efile=%d recfile=%d\n",
+//            volfile->sfile, volfile->efile, rec->File);
    if (volfile->sfile <= rec->File && volfile->efile >= rec->File) {
       return 1;
    }
index 3cc924e8c0bbc60849bc93a9b968ca8b041c399f..270747760047d0f0fd5321863a11266ad20ee2d8 100755 (executable)
@@ -41,6 +41,7 @@ static BSR *store_joblevel(LEX *lc, BSR *bsr);
 static BSR *store_findex(LEX *lc, BSR *bsr);
 static BSR *store_sessid(LEX *lc, BSR *bsr);
 static BSR *store_volfile(LEX *lc, BSR *bsr);
+static BSR *store_volblock(LEX *lc, BSR *bsr);
 static BSR *store_sesstime(LEX *lc, BSR *bsr);
 static BSR *store_include(LEX *lc, BSR *bsr);
 static BSR *store_exclude(LEX *lc, BSR *bsr);
@@ -69,6 +70,7 @@ struct kw_items items[] = {
    {"include", store_include},
    {"exclude", store_exclude},
    {"volfile", store_volfile},
+   {"volblock", store_volblock},
    {"stream",  store_stream},
    {"slot",    store_slot},
    {NULL, NULL}
@@ -399,6 +401,41 @@ static BSR *store_volfile(LEX *lc, BSR *bsr)
 }
 
 
+/*
+ * Routine to handle Volume start/end Block  
+ */
+static BSR *store_volblock(LEX *lc, BSR *bsr)
+{
+   int token;
+   BSR_VOLBLOCK *volblock;
+
+   for (;;) {
+      token = lex_get_token(lc, T_PINT32_RANGE);
+      if (token == T_ERROR) {
+        return NULL;
+      }
+      volblock = (BSR_VOLBLOCK *)malloc(sizeof(BSR_VOLBLOCK));
+      memset(volblock, 0, sizeof(BSR_VOLBLOCK));
+      volblock->sblock = lc->pint32_val;
+      volblock->eblock = lc->pint32_val2;
+      /* Add it to the end of the chain */
+      if (!bsr->volblock) {
+        bsr->volblock = volblock;
+      } else {
+        /* Add to end of chain */
+        BSR_VOLBLOCK *bs = bsr->volblock;
+        for ( ;bs->next; bs=bs->next)
+           {  }
+        bs->next = volblock;
+      }
+      token = lex_get_token(lc, T_ALL);
+      if (token != T_COMMA) {
+        break;
+      }
+   }
+   return bsr;
+}
+
 
 static BSR *store_sessid(LEX *lc, BSR *bsr)
 {
@@ -528,6 +565,15 @@ void dump_volfile(BSR_VOLFILE *volfile)
    }
 }
 
+void dump_volblock(BSR_VOLBLOCK *volblock)
+{
+   if (volblock) {
+      Dmsg2(-1, "VolBlock    : %u-%u\n", volblock->sblock, volblock->eblock);
+      dump_volblock(volblock->next);
+   }
+}
+
+
 void dump_findex(BSR_FINDEX *FileIndex)
 {
    if (FileIndex) {
@@ -613,6 +659,7 @@ void dump_bsr(BSR *bsr)
    dump_sessid(bsr->sessid);
    dump_sesstime(bsr->sesstime);
    dump_volfile(bsr->volfile);
+   dump_volblock(bsr->volblock);
    dump_client(bsr->client);
    dump_jobid(bsr->JobId);
    dump_job(bsr->job);
@@ -654,6 +701,7 @@ void free_bsr(BSR *bsr)
    free_bsr_item((BSR *)bsr->sessid);
    free_bsr_item((BSR *)bsr->sesstime);
    free_bsr_item((BSR *)bsr->volfile);
+   free_bsr_item((BSR *)bsr->volblock);
    free_bsr_item((BSR *)bsr->JobId);
    free_bsr_item((BSR *)bsr->job);
    free_bsr_item((BSR *)bsr->FileIndex);
index de5d6050b3d9b2cf14bb96f880468b6112afd4ff..85b9b44add9f4bea2ed2240e82d6ade4339f8500 100644 (file)
@@ -87,7 +87,6 @@ int read_records(JCR *jcr,  DEVICE *dev,
            read_block_from_device(dev, block);
            read_record_from_block(block, trec);
            get_session_record(dev, trec, &sessrec);
-           trec->File = dev->file;
            record_cb(jcr, dev, block, trec);
            free_record(trec);
            goto next_record;
@@ -118,7 +117,6 @@ next_record:
                  block->BlockNumber, rec->remainder);
            break;
         }
-        rec->File = dev->file;
          Dmsg3(10, "read-OK. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
                  block->BlockNumber, rec->remainder);
         /*
index 410daa54f55ed3b65e967bd4b58150ae02c23058..e55a514997081303b52560a6624f477ae287057e 100644 (file)
@@ -359,9 +359,14 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
 
    remlen = block->binbuf;
    rec->Block = block->BlockNumber;
+   rec->File = ((DEVICE *)block->dev)->file;
 
-   /* Clear state flags */
+   /* Clear state flags */      
    rec->state = 0;
+   if (((DEVICE *)block->dev)->state & ST_TAPE) {
+      rec->state |= REC_ISTAPE;
+   }
+
 
    /* 
     * Get the header. There is always a full header,
index 3000a037ea5c3c4787288895eec294dc7c971361..4824ecc34f1f28d36e47d04a854059bb96b28b34 100644 (file)
@@ -65,6 +65,7 @@
 #define REC_BLOCK_EMPTY      0x04     /* not enough data in block */
 #define REC_NO_MATCH         0x08     /* No match on continuation data */
 #define REC_CONTINUATION     0x10     /* Continuation record found */
+#define REC_ISTAPE           0x20     /* Set if device is tape */
 
 #define is_partial_record(r) ((r)->state & REC_PARTIAL_RECORD)
 #define is_block_empty(r)    ((r)->state & REC_BLOCK_EMPTY)
index 260003d734247a3fdcf0ad73c5a2f6fe7ed25697..0edf9b9ce04f172821cd286871e638950fe5595b 100644 (file)
@@ -44,7 +44,7 @@ smtp: smtp.o ../lib/libbac.a
        $(CXX) $(LDFLAGS) -L../lib -o $@ smtp.o -lbac -lm $(LIBS) $(DLIB)
 
 dbcheck: dbcheck.o ../lib/libbac.a ../cats/libsql.a
-       $(CXX) $(LDFLAGS) -L../lib -L../cats -o $@ dbcheck.o -lbac -lsql -lm $(LIBS) $(DB_LIBS)
+       $(CXX) $(LDFLAGS) -L../lib -L../cats -o $@ dbcheck.o -lsql -lbac -lm $(LIBS) $(DB_LIBS)
 
 testfind: ../findlib/libfind.a ../lib/libbac.a $(FINDOBJS)
        $(CXX) -g $(LDFLAGS) -L. -L../lib -L../findlib -o $@ $(FINDOBJS) \
index 031ebb90cd932fed2823a6f6ef31c411b080e7be..3846672ee1fa4e1e059e45a187dac5594f02a29b 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.28"
 #define VSTRING "1"
-#define DATE    "2 December 2002"
-#define LSMDATE "02Dec02"
+#define DATE    "4 December 2002"
+#define LSMDATE "04Dec02"
 
 /* Debug flags */
 #define DEBUG 1