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, 2002 Kern Sibbald and John Walker
23 This program is free software; you can redistribute it and/or
24 modify it under the terms of the GNU General Public License as
25 published by the Free Software Foundation; either version 2 of
26 the License, or (at your option) any later version.
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 GNU
31 General Public License for more details.
33 You should have received a copy of the GNU General Public
34 License along with this program; if not, write to the Free
35 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
40 /* The following is necessary so that we do not include
41 * the dummy external definition of DB.
43 #define __SQL_C /* indicate that this is sql.c */
51 /* Forward referenced functions */
52 int db_find_job_start_time(B_DB *mdb, JOB_DBR *jr, char *stime);
54 /* -----------------------------------------------------------------------
56 * Bacula specific defines and subroutines
58 * -----------------------------------------------------------------------
63 * Find job start time. Used to find last full save that terminated normally
64 * so we can do Incremental and Differential saves.
66 * Returns: 0 on failure
67 * 1 on success, jr unchanged, but stime set
69 int db_find_job_start_time(B_DB *mdb, JOB_DBR *jr, char *stime)
71 char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
73 uint32_t JobId, EndId, ClientId;
74 char cType[10], cLevel[10], JobStatus[10];
79 strcpy(stime, "0000-00-00 00:00:00"); /* default */
81 if (!bdb_open_jobs_file(mdb)) {
85 fseek(mdb->jobfd, 0L, SEEK_SET); /* rewind file */
86 /* Linear search through JobStart records
89 while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
90 if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s \
91 StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
92 if (JobId < jr->JobId) {
93 continue; /* older not a candidate */
98 unbash_spaces(StartTime);
99 Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
100 Type, Level, Name, StartTime);
101 Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->Type, jr->Level,
103 /* Differential is since last Full backup */
104 /* Incremental is since last FULL or Incremental or Differential */
105 if (((jr->Level == L_DIFFERENTIAL) && (Type == jr->Type &&
106 Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
107 ((jr->Level == L_INCREMENTAL) && (Type == jr->Type &&
108 (Level == L_FULL || Level == L_INCREMENTAL ||
109 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
110 addr = ftell(mdb->jobfd); /* save current location */
113 /* Search for matching JobEnd record */
114 while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
115 if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
116 &EndId, JobStatus, &ClientId) == 3) {
117 if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
118 Dmsg0(200, "====found EndJob matching Job\n");
124 /* Reset for next read */
125 fseek(mdb->jobfd, addr, SEEK_SET);
127 strcpy(stime, StartTime);
128 stat = 1; /* Got a candidate */
129 Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
130 JobId, Type, Level, Name, StartTime);
141 * Find Available Media (Volume) for Pool
143 * Find a Volume for a given PoolId, MediaType, and VolStatus
145 * Returns: 0 on failure
148 int db_find_next_volume(B_DB *mdb, int item, MEDIA_DBR *mr)
156 if (!bdb_open_media_file(mdb)) {
160 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
162 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
163 if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
164 strcmp(mr->MediaType, omr.MediaType) == 0) {
165 if (!(++index == item)) { /* looking for item'th entry */
166 Dmsg0(200, "Media record matches, but not index\n");
169 Dmsg0(200, "Media record matches\n");
170 memcpy(mr, &omr, len);
171 Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
173 break; /* found it */
180 int db_find_last_full_verify(B_DB *mdb, JOB_DBR *jr) { return 0; }
183 #endif /* HAVE_BACULA_DB */