2 * Bacula Catalog Database Find record interface routines
4 * Note, generally, these routines are more complicated
5 * that a simple search by name or id. Such simple
8 * Bacula Catalog Database routines written specifically
9 * for Bacula. Note, these routines are VERY dumb and
10 * do not provide all the functionality of an SQL database.
11 * The purpose of these routines is to ensure that Bacula
12 * can limp along if no real database is loaded on the
15 * Kern Sibbald, January MMI
21 Copyright (C) 2001-2006 Kern Sibbald
23 This program is free software; you can redistribute it and/or
24 modify it under the terms of the GNU General Public License
25 version 2 as amended with additional clauses defined in the
26 file LICENSE in the main source directory.
28 This program is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 the file LICENSE for additional details.
35 /* The following is necessary so that we do not include
36 * the dummy external definition of DB.
38 #define __SQL_C /* indicate that this is sql.c */
46 /* Forward referenced functions */
48 /* -----------------------------------------------------------------------
50 * Bacula specific defines and subroutines
52 * -----------------------------------------------------------------------
57 * Find job start time. Used to find last full save that terminated normally
58 * so we can do Incremental and Differential saves.
60 * Returns: 0 on failure
61 * 1 on success, jr unchanged, but stime set
63 bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
65 char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
67 uint32_t JobId, EndId, ClientId;
68 char cType[10], cLevel[10], JobStatus[10];
73 pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */
74 if (!bdb_open_jobs_file(mdb)) {
78 fseek(mdb->jobfd, 0L, SEEK_SET); /* rewind file */
79 /* Linear search through JobStart records
82 while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
83 if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s "
84 "StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
85 if (JobId < jr->JobId) {
86 continue; /* older not a candidate */
91 unbash_spaces(StartTime);
92 Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
93 Type, Level, Name, StartTime);
94 Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->JobType, jr->JobLevel,
96 /* Differential is since last Full backup */
97 /* Incremental is since last FULL or Incremental or Differential */
98 if (((jr->JobLevel == L_DIFFERENTIAL) && (Type == jr->JobType &&
99 Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
100 ((jr->JobLevel == L_INCREMENTAL) && (Type == jr->JobType &&
101 (Level == L_FULL || Level == L_INCREMENTAL ||
102 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
103 addr = ftell(mdb->jobfd); /* save current location */
106 /* Search for matching JobEnd record */
107 while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
108 if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
109 &EndId, JobStatus, &ClientId) == 3) {
110 if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
111 Dmsg0(200, "====found EndJob matching Job\n");
117 /* Reset for next read */
118 fseek(mdb->jobfd, addr, SEEK_SET);
120 pm_strcpy(stime, StartTime);
121 Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
122 JobId, Type, Level, Name, StartTime);
133 * Find Available Media (Volume) for Pool
135 * Find a Volume for a given PoolId, MediaType, and VolStatus
137 * Note! this does not correctly implement InChanger.
139 * Returns: 0 on failure
143 db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr)
151 if (!bdb_open_media_file(mdb)) {
155 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
157 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
158 if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
159 strcmp(mr->MediaType, omr.MediaType) == 0) {
160 if (!(++index == item)) { /* looking for item'th entry */
161 Dmsg0(200, "Media record matches, but not index\n");
164 Dmsg0(200, "Media record matches\n");
165 memcpy(mr, &omr, len);
166 Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
168 break; /* found it */
176 db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr)
180 db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
184 #endif /* HAVE_BACULA_DB */