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
19 Copyright (C) 2001-2006 Kern Sibbald
21 This program is free software; you can redistribute it and/or
22 modify it under the terms of the GNU General Public License
23 version 2 as amended with additional clauses defined in the
24 file LICENSE in the main source directory.
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
29 the file LICENSE for additional details.
34 /* The following is necessary so that we do not include
35 * the dummy external definition of DB.
37 #define __SQL_C /* indicate that this is sql.c */
45 /* Forward referenced functions */
48 /* -----------------------------------------------------------------------
50 * Bacula specific defines and subroutines
52 * -----------------------------------------------------------------------
57 * Get Job record for given JobId
58 * Returns: 0 on failure
62 int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
71 if (jr->JobId == 0 && jr->Name[0] == 0) { /* he wants # of Job records */
72 jr->JobId = mdb->control.JobId;
76 Dmsg0(200, "Open Jobs\n");
77 if (!bdb_open_jobs_file(mdb)) {
81 fseek(mdb->jobfd, 0L, SEEK_SET); /* rewind file */
83 /* Linear search through Job records
86 while (fread(&ojr, len, 1, mdb->jobfd) > 0) {
87 /* If id not zero, search by Id */
89 if (jr->JobId == ojr.JobId) {
93 } else if (strcmp(jr->Job, ojr.Job) == 0) {
95 Dmsg1(200, "Found Job: %s\n", ojr.Job);
98 rec_addr = ftell(mdb->jobfd); /* save start next record */
101 /* Found desired record, now return it */
102 memcpy(jr, &ojr, len);
103 jr->rec_addr = rec_addr;
105 Dmsg2(200, "Found job record: JobId=%d Job=%s",
110 strcpy(mdb->errmsg, "Job record not found.\n");
113 Dmsg1(200, "Return job stat=%d\n", stat);
119 * Get the number of pool records
121 * Returns: -1 on failure
124 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
129 stat = mdb->control.PoolId;
135 * This function returns a list of all the Pool record ids.
136 * The caller must free ids if non-NULL.
138 * Returns 0: on failure
141 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
150 if (!bdb_open_pools_file(mdb)) {
154 fseek(mdb->poolfd, 0L, SEEK_SET); /* rewind file */
155 /* Linear search through Pool records
158 *num_ids = mdb->control.PoolId;
159 id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
160 while (fread(&opr, len, 1, mdb->poolfd) > 0) {
161 id[i++] = opr.PoolId;
171 * If the PoolId is non-zero, we get its record,
172 * otherwise, we search on the PoolName
174 * Returns: false on failure
177 bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
185 Dmsg0(200, "Open pools\n");
186 if (!bdb_open_pools_file(mdb)) {
190 fseek(mdb->poolfd, 0L, SEEK_SET); /* rewind file */
192 /* Linear search through Pool records
195 while (fread(&opr, len, 1, mdb->poolfd) > 0) {
196 /* If id not zero, search by Id */
197 if (pr->PoolId != 0) {
198 if (pr->PoolId == opr.PoolId) {
202 } else if (strcmp(pr->Name, opr.Name) == 0) {
204 Dmsg1(200, "Found pool: %s\n", opr.Name);
207 rec_addr = ftell(mdb->poolfd); /* save start next record */
210 /* Found desired record, now return it */
211 memcpy(pr, &opr, len);
212 pr->rec_addr = rec_addr;
213 Dmsg3(200, "Found pool record: PoolId=%d Name=%s PoolType=%s\n",
214 opr.PoolId, opr.Name, opr.PoolType);
218 strcpy(mdb->errmsg, "Pool record not found.\n");
225 * Get the number of Media records
227 * Returns: -1 on failure
230 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
235 stat = mdb->control.MediaId;
241 * This function returns a list of all the Media record ids
242 * for a specified PoolId
243 * The caller must free ids if non-NULL.
245 * Returns false: on failure
248 bool db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
257 if (!bdb_open_media_file(mdb)) {
261 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
262 /* Linear search through Pool records
265 if (mdb->control.MediaId == 0) {
269 *num_ids = mdb->control.MediaId;
270 id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
271 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
272 if (PoolId == omr.MediaId) {
273 id[i++] = omr.MediaId;
283 * If the MediaId is non-zero, we get its record,
284 * otherwise, we search on the MediaName
286 * Returns: false on failure
289 bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
297 if (!bdb_open_media_file(mdb)) {
300 fseek(mdb->mediafd, 0L, SEEK_SET); /* rewind file */
302 /* Linear search through Media records
305 while (fread(&omr, len, 1, mdb->mediafd) > 0) {
306 if (omr.MediaId == 0) {
307 continue; /* deleted record */
309 Dmsg1(200, "VolName=%s\n", omr.VolumeName);
310 /* If id not zero, search by Id */
311 if (mr->MediaId != 0) {
312 Dmsg1(200, "MediaId=%d\n", mr->MediaId);
313 if (mr->MediaId == omr.MediaId) {
317 } else if (strcmp(mr->VolumeName, omr.VolumeName) == 0) {
321 rec_addr = ftell(mdb->mediafd); /* save start next record */
324 /* Found desired record, now return it */
325 memcpy(mr, &omr, len);
326 mr->rec_addr = rec_addr;
327 Dmsg3(200, "Found media record: MediaId=%d Name=%s MediaType=%s\n",
328 omr.MediaId, omr.VolumeName, mr->MediaType);
332 strcpy(mdb->errmsg, "Could not find requested Media record.\n");
340 * Find VolumeNames for a give JobId
341 * Returns: 0 on error or no Volumes found
342 * number of volumes on success
343 * Volumes are concatenated in VolumeNames
344 * separated by a vertical bar (|).
346 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
354 if (!bdb_open_jobmedia_file(mdb)) {
358 if (!bdb_open_media_file(mdb)) {
365 fseek(mdb->jobmediafd, 0L, SEEK_SET); /* rewind the file */
366 while (fread(&jm, jmlen, 1, mdb->jobmediafd) > 0) {
367 if (jm.JobId == JobId) {
368 /* Now look up VolumeName in Media file given MediaId */
369 fseek(mdb->mediafd, 0L, SEEK_SET);
370 while (fread(&mr, mrlen, 1, mdb->mediafd) > 0) {
371 if (jm.MediaId == mr.MediaId) {
372 if (*VolumeNames[0] != 0) { /* if not first name, */
373 pm_strcat(VolumeNames, "|"); /* add separator */
375 pm_strcat(VolumeNames, mr.VolumeName); /* add Volume Name */
382 strcpy(mdb->errmsg, "No Volumes found.\n");
390 * If the ClientId is non-zero, we get its record,
391 * otherwise, we search on the Name
393 * Returns: 0 on failure
396 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
403 if (!bdb_open_client_file(mdb)) {
407 fseek(mdb->clientfd, 0L, SEEK_SET); /* rewind file */
409 * Linear search through Client records
412 while (fread(&lcr, len, 1, mdb->clientfd)) {
413 /* If id not zero, search by Id */
414 if (cr->ClientId != 0) {
415 if (cr->ClientId != lcr.ClientId) {
419 } else if (strcmp(cr->Name, lcr.Name) != 0) {
420 continue; /* not found */
422 memcpy(cr, &lcr, len);
424 Dmsg2(200, "Found Client record: ClientId=%d Name=%s\n",
425 lcr.ClientId, lcr.Name);
429 strcpy(mdb->errmsg, "Client record not found.\n");
436 * Get FileSet Record (We read the FILESET_DBR structure)
437 * If the FileSetId is non-zero, we get its record,
438 * otherwise, we search on the FileSet (its name).
440 * Returns: 0 on failure
443 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
449 if (!bdb_open_fileset_file(mdb)) {
453 fseek(mdb->filesetfd, 0L, SEEK_SET); /* rewind file */
455 * Linear search through FileSet records
457 while (fread(&lfsr, sizeof(lfsr), 1, mdb->filesetfd) > 0) {
458 /* If id not zero, search by Id */
459 if (fsr->FileSetId != 0) {
460 if (fsr->FileSetId != lfsr.FileSetId) {
463 /* Search by Name & MD5 */
464 } else if (strcmp(fsr->FileSet, lfsr.FileSet) != 0 ||
465 strcmp(fsr->MD5, lfsr.MD5) != 0) {
466 continue; /* not found */
468 /* Found desired record, now return it */
469 memcpy(fsr, &lfsr, sizeof(lfsr));
470 stat = fsr->FileSetId;
471 Dmsg2(200, "Found FileSet record: FileSetId=%d FileSet=%s\n",
472 lfsr.FileSetId, lfsr.FileSet);
476 strcpy(mdb->errmsg, "FileSet record not found.\n");
484 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
487 int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
490 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
493 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
497 #endif /* HAVE_BACULA_DB */