2 * Bacula Catalog Database Get record interface routines
3 * Note, these routines generally get a record by id or
4 * by name. If more logic is involved, the routine
7 * Bacula Catalog Database routines written specifically
8 * for Bacula. Note, these routines are VERY dumb and
9 * do not provide all the functionality of an SQL database.
10 * The purpose of these routines is to ensure that Bacula
11 * can limp along if no real database is loaded on the
14 * Kern Sibbald, January MMI
20 Copyright (C) 2001-2006 Kern Sibbald
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License
24 version 2 as amended with additional clauses defined in the
25 file LICENSE in the main source directory.
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 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 */
49 /* -----------------------------------------------------------------------
51 * Bacula specific defines and subroutines
53 * -----------------------------------------------------------------------
58 * Get Job record for given JobId
59 * Returns: 0 on failure
63 bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
72 if (jr->JobId == 0 && jr->Name[0] == 0) { /* he wants # of Job records */
73 jr->JobId = mdb->control.JobId;
77 Dmsg0(200, "Open Jobs\n");
78 if (!bdb_open_jobs_file(mdb)) {
82 fseek(mdb->jobfd, 0L, SEEK_SET); /* rewind file */
84 /* Linear search through Job records
87 while (fread(&ojr, len, 1, mdb->jobfd) > 0) {
88 /* If id not zero, search by Id */
90 if (jr->JobId == ojr.JobId) {
94 } else if (strcmp(jr->Job, ojr.Job) == 0) {
96 Dmsg1(200, "Found Job: %s\n", ojr.Job);
99 rec_addr = ftell(mdb->jobfd); /* save start next record */
102 /* Found desired record, now return it */
103 memcpy(jr, &ojr, len);
104 jr->rec_addr = rec_addr;
106 Dmsg2(200, "Found job record: JobId=%d Job=%s",
111 strcpy(mdb->errmsg, "Job record not found.\n");
114 Dmsg1(200, "Return job stat=%d\n", stat);
120 * Get the number of pool records
122 * Returns: -1 on failure
125 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
130 stat = mdb->control.PoolId;
136 * This function returns a list of all the Pool record ids.
137 * The caller must free ids if non-NULL.
139 * Returns 0: on failure
142 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
151 if (!bdb_open_pools_file(mdb)) {
155 fseek(mdb->poolfd, 0L, SEEK_SET); /* rewind file */
156 /* Linear search through Pool records
159 *num_ids = mdb->control.PoolId;
160 id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
161 while (fread(&opr, len, 1, mdb->poolfd) > 0) {
162 id[i++] = opr.PoolId;
172 * If the PoolId is non-zero, we get its record,
173 * otherwise, we search on the PoolName
175 * Returns: false on failure
178 bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
186 Dmsg0(200, "Open pools\n");
187 if (!bdb_open_pools_file(mdb)) {
191 fseek(mdb->poolfd, 0L, SEEK_SET); /* rewind file */
193 /* Linear search through Pool records
196 while (fread(&opr, len, 1, mdb->poolfd) > 0) {
197 /* If id not zero, search by Id */
198 if (pr->PoolId != 0) {
199 if (pr->PoolId == opr.PoolId) {
203 } else if (strcmp(pr->Name, opr.Name) == 0) {
205 Dmsg1(200, "Found pool: %s\n", opr.Name);
208 rec_addr = ftell(mdb->poolfd); /* save start next record */
211 /* Found desired record, now return it */
212 memcpy(pr, &opr, len);
213 pr->rec_addr = rec_addr;
214 Dmsg3(200, "Found pool record: PoolId=%d Name=%s PoolType=%s\n",
215 opr.PoolId, opr.Name, opr.PoolType);
219 strcpy(mdb->errmsg, "Pool record not found.\n");
226 * Get the number of Media records
228 * Returns: -1 on failure
231 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
236 stat = mdb->control.MediaId;
242 * This function returns a list of all the Media record ids
243 * for a specified PoolId
244 * The caller must free ids if non-NULL.
246 * Returns false: on failure
249 bool db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
258 if (!bdb_open_media_file(mdb)) {
262 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
263 /* Linear search through Pool records
266 if (mdb->control.MediaId == 0) {
270 *num_ids = mdb->control.MediaId;
271 id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
272 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
273 if (PoolId == omr.MediaId) {
274 id[i++] = omr.MediaId;
284 * If the MediaId is non-zero, we get its record,
285 * otherwise, we search on the MediaName
287 * Returns: false on failure
290 bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
298 if (!bdb_open_media_file(mdb)) {
301 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
303 /* Linear search through Media records
306 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
307 if (omr.MediaId == 0) {
308 continue; /* deleted record */
310 Dmsg1(200, "VolName=%s\n", omr.VolumeName);
311 /* If id not zero, search by Id */
312 if (mr->MediaId != 0) {
313 Dmsg1(200, "MediaId=%d\n", mr->MediaId);
314 if (mr->MediaId == omr.MediaId) {
318 } else if (strcmp(mr->VolumeName, omr.VolumeName) == 0) {
322 rec_addr = ftell(mdb->mediafd); /* save start next record */
325 /* Found desired record, now return it */
326 memcpy(mr, &omr, len);
327 mr->rec_addr = rec_addr;
328 Dmsg3(200, "Found media record: MediaId=%d Name=%s MediaType=%s\n",
329 omr.MediaId, omr.VolumeName, mr->MediaType);
333 strcpy(mdb->errmsg, "Could not find requested Media record.\n");
341 * Find VolumeNames for a give JobId
342 * Returns: 0 on error or no Volumes found
343 * number of volumes on success
344 * Volumes are concatenated in VolumeNames
345 * separated by a vertical bar (|).
347 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
355 if (!bdb_open_jobmedia_file(mdb)) {
359 if (!bdb_open_media_file(mdb)) {
366 fseek(mdb->jobmediafd, 0L, SEEK_SET); /* rewind the file */
367 while (fread(&jm, jmlen, 1, mdb->jobmediafd) > 0) {
368 if (jm.JobId == JobId) {
369 /* Now look up VolumeName in Media file given MediaId */
370 fseek(mdb->mediafd, 0L, SEEK_SET);
371 while (fread(&mr, mrlen, 1, mdb->mediafd) > 0) {
372 if (jm.MediaId == mr.MediaId) {
373 if (*VolumeNames[0] != 0) { /* if not first name, */
374 pm_strcat(VolumeNames, "|"); /* add separator */
376 pm_strcat(VolumeNames, mr.VolumeName); /* add Volume Name */
383 strcpy(mdb->errmsg, "No Volumes found.\n");
391 * If the ClientId is non-zero, we get its record,
392 * otherwise, we search on the Name
394 * Returns: 0 on failure
397 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
404 if (!bdb_open_client_file(mdb)) {
408 fseek(mdb->clientfd, 0L, SEEK_SET); /* rewind file */
410 * Linear search through Client records
413 while (fread(&lcr, len, 1, mdb->clientfd)) {
414 /* If id not zero, search by Id */
415 if (cr->ClientId != 0) {
416 if (cr->ClientId != lcr.ClientId) {
420 } else if (strcmp(cr->Name, lcr.Name) != 0) {
421 continue; /* not found */
423 memcpy(cr, &lcr, len);
425 Dmsg2(200, "Found Client record: ClientId=%d Name=%s\n",
426 lcr.ClientId, lcr.Name);
430 strcpy(mdb->errmsg, "Client record not found.\n");
437 * Get FileSet Record (We read the FILESET_DBR structure)
438 * If the FileSetId is non-zero, we get its record,
439 * otherwise, we search on the FileSet (its name).
441 * Returns: 0 on failure
444 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
450 if (!bdb_open_fileset_file(mdb)) {
454 fseek(mdb->filesetfd, 0L, SEEK_SET); /* rewind file */
456 * Linear search through FileSet records
458 while (fread(&lfsr, sizeof(lfsr), 1, mdb->filesetfd) > 0) {
459 /* If id not zero, search by Id */
460 if (fsr->FileSetId != 0) {
461 if (fsr->FileSetId != lfsr.FileSetId) {
464 /* Search by Name & MD5 */
465 } else if (strcmp(fsr->FileSet, lfsr.FileSet) != 0 ||
466 strcmp(fsr->MD5, lfsr.MD5) != 0) {
467 continue; /* not found */
469 /* Found desired record, now return it */
470 memcpy(fsr, &lfsr, sizeof(lfsr));
471 stat = fsr->FileSetId;
472 Dmsg2(200, "Found FileSet record: FileSetId=%d FileSet=%s\n",
473 lfsr.FileSetId, lfsr.FileSet);
477 strcpy(mdb->errmsg, "FileSet record not found.\n");
485 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
488 int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
491 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
494 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
498 #endif /* HAVE_BACULA_DB */