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
19 Copyright (C) 2001, 2002 Kern Sibbald and John Walker
21 This program is free software; you can redistribute it and/or
22 modify it under the terms of the GNU General Public License as
23 published by the Free Software Foundation; either version 2 of
24 the License, or (at your option) any later version.
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 General Public License for more details.
31 You should have received a copy of the GNU General Public
32 License along with this program; if not, write to the Free
33 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
38 /* The following is necessary so that we do not include
39 * the dummy external definition of DB.
41 #define __SQL_C /* indicate that this is sql.c */
49 /* Forward referenced functions */
50 int db_find_job_start_time(B_DB *mdb, JOB_DBR *jr, char *stime);
52 /* -----------------------------------------------------------------------
54 * Bacula specific defines and subroutines
56 * -----------------------------------------------------------------------
61 * Find job start time. Used to find last full save that terminated normally
62 * so we can do Incremental and Differential saves.
64 * Returns: 0 on failure
65 * 1 on success, jr unchanged, but stime set
67 int db_find_job_start_time(B_DB *mdb, JOB_DBR *jr, char *stime)
69 char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
71 uint32_t JobId, EndId, ClientId;
72 char cType[10], cLevel[10], JobStatus[10];
77 strcpy(stime, "0000-00-00 00:00:00"); /* default */
79 if (!bdb_open_jobs_file(mdb)) {
83 fseek(mdb->jobfd, 0L, SEEK_SET); /* rewind file */
84 /* Linear search through JobStart records
87 while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
88 if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s \
89 StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
90 if (JobId < jr->JobId) {
91 continue; /* older not a candidate */
96 unbash_spaces(StartTime);
97 Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
98 Type, Level, Name, StartTime);
99 Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->Type, jr->Level,
101 /* Differential is since last Full backup */
102 /* Incremental is since last FULL or Incremental or Differential */
103 if (((jr->Level == L_DIFFERENTIAL) && (Type == jr->Type &&
104 Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
105 ((jr->Level == L_INCREMENTAL) && (Type == jr->Type &&
106 (Level == L_FULL || Level == L_INCREMENTAL ||
107 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
108 addr = ftell(mdb->jobfd); /* save current location */
111 /* Search for matching JobEnd record */
112 while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
113 if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
114 &EndId, JobStatus, &ClientId) == 3) {
115 if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
116 Dmsg0(200, "====found EndJob matching Job\n");
122 /* Reset for next read */
123 fseek(mdb->jobfd, addr, SEEK_SET);
125 strcpy(stime, StartTime);
126 stat = 1; /* Got a candidate */
127 Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
128 JobId, Type, Level, Name, StartTime);
139 * Find Available Media (Volume) for Pool
141 * Find a Volume for a given PoolId, MediaType, and VolStatus
143 * Returns: 0 on failure
146 int db_find_next_volume(B_DB *mdb, int item, MEDIA_DBR *mr)
154 if (!bdb_open_media_file(mdb)) {
158 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
160 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
161 if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
162 strcmp(mr->MediaType, omr.MediaType) == 0) {
163 if (!(++index == item)) { /* looking for item'th entry */
164 Dmsg0(200, "Media record matches, but not index\n");
167 Dmsg0(200, "Media record matches\n");
168 memcpy(mr, &omr, len);
169 Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
171 break; /* found it */
178 int db_find_last_full_verify(B_DB *mdb, JOB_DBR *jr) { return 0; }
181 #endif /* HAVE_BACULA_DB */