]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_get.c
Replace explicit checks for "/" with calls to IsPathSeparator, strchr with first_path...
[bacula/bacula] / bacula / src / cats / bdb_get.c
1 /*
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
5  *        should be in find.c
6  *
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
12  *  system.
13  *
14  *    Kern Sibbald, January MMI
15  *
16  *    Version $Id$
17  */
18
19 /*
20    Copyright (C) 2001-2006 Kern Sibbald
21
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.
26
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.
31
32  */
33
34
35 /* The following is necessary so that we do not include
36  * the dummy external definition of DB.
37  */
38 #define __SQL_C                       /* indicate that this is sql.c */
39
40 #include "bacula.h"
41 #include "cats.h"
42 #include "bdb.h"
43
44 #ifdef HAVE_BACULA_DB
45
46 /* Forward referenced functions */
47
48
49 /* -----------------------------------------------------------------------
50  *
51  *   Bacula specific defines and subroutines
52  *
53  * -----------------------------------------------------------------------
54  */
55
56
57 /*
58  * Get Job record for given JobId
59  * Returns: 0 on failure
60  *          1 on success
61  */
62
63 bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
64 {
65    JOB_DBR ojr;
66    faddr_t rec_addr;
67    int found = 0;
68    int stat = 0;
69    int len;
70
71    db_lock(mdb);
72    if (jr->JobId == 0 && jr->Name[0] == 0) { /* he wants # of Job records */
73       jr->JobId = mdb->control.JobId;
74       db_unlock(mdb);
75       return 1;
76    }
77    Dmsg0(200, "Open Jobs\n");
78    if (!bdb_open_jobs_file(mdb)) {
79       db_unlock(mdb);
80       return 0;
81    }
82    fseek(mdb->jobfd, 0L, SEEK_SET);   /* rewind file */
83    rec_addr = 0;
84    /* Linear search through Job records
85     */
86    len = sizeof(ojr);
87    while (fread(&ojr, len, 1, mdb->jobfd) > 0) {
88       /* If id not zero, search by Id */
89       if (jr->JobId != 0) {
90          if (jr->JobId == ojr.JobId) {
91            found = 1;
92          }
93       /* Search by Job */
94       } else if (strcmp(jr->Job, ojr.Job) == 0) {
95          found = 1;
96          Dmsg1(200, "Found Job: %s\n", ojr.Job);
97       }
98       if (!found) {
99          rec_addr = ftell(mdb->jobfd); /* save start next record */
100          continue;
101       }
102       /* Found desired record, now return it */
103       memcpy(jr, &ojr, len);
104       jr->rec_addr = rec_addr;
105       stat = ojr.JobId;
106       Dmsg2(200, "Found job record: JobId=%d Job=%s",
107          ojr.JobId, ojr.Job);
108       break;
109    }
110    if (!found) {
111       strcpy(mdb->errmsg, "Job record not found.\n");
112    }
113    db_unlock(mdb);
114    Dmsg1(200, "Return job stat=%d\n", stat);
115    return stat;
116 }
117
118
119 /*
120  * Get the number of pool records
121  *
122  * Returns: -1 on failure
123  *          number on success
124  */
125 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
126 {
127    int stat = 0;
128
129    db_lock(mdb);
130    stat = mdb->control.PoolId;
131    db_unlock(mdb);
132    return stat;
133 }
134
135 /*
136  * This function returns a list of all the Pool record ids.
137  *  The caller must free ids if non-NULL.
138  *
139  *  Returns 0: on failure
140  *          1: on success
141  */
142 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
143 {
144    int i = 0;
145    uint32_t *id;
146    POOL_DBR opr;
147    int len;
148
149    db_lock(mdb);
150    *ids = NULL;
151    if (!bdb_open_pools_file(mdb)) {
152       db_unlock(mdb);
153       return 0;
154    }
155    fseek(mdb->poolfd, 0L, SEEK_SET);   /* rewind file */
156    /* Linear search through Pool records
157     */
158    len = sizeof(opr);
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;
163    }
164    *ids = id;
165    db_unlock(mdb);
166    return 1;
167 }
168
169
170 /*
171  * Get Pool Record
172  * If the PoolId is non-zero, we get its record,
173  *  otherwise, we search on the PoolName
174  *
175  * Returns: false on failure
176  *          true on success
177  */
178 bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
179 {
180    POOL_DBR opr;
181    faddr_t rec_addr;
182    bool found = false;
183    int len;
184
185    db_lock(mdb);
186    Dmsg0(200, "Open pools\n");
187    if (!bdb_open_pools_file(mdb)) {
188       db_unlock(mdb);
189       return false;
190    }
191    fseek(mdb->poolfd, 0L, SEEK_SET);   /* rewind file */
192    rec_addr = 0;
193    /* Linear search through Pool records
194     */
195    len = sizeof(opr);
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) {
200            found = true;
201          }
202       /* Search by Name */
203       } else if (strcmp(pr->Name, opr.Name) == 0) {
204          found = true;
205          Dmsg1(200, "Found pool: %s\n", opr.Name);
206       }
207       if (!found) {
208          rec_addr = ftell(mdb->poolfd); /* save start next record */
209          continue;
210       }
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);
216       break;
217    }
218    if (!found) {
219       strcpy(mdb->errmsg, "Pool record not found.\n");
220    }
221    db_unlock(mdb);
222    return found;
223 }
224
225 /*
226  * Get the number of Media records
227  *
228  * Returns: -1 on failure
229  *          number on success
230  */
231 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
232 {
233    int stat = 0;
234
235    db_lock(mdb);
236    stat = mdb->control.MediaId;
237    db_unlock(mdb);
238    return stat;
239 }
240
241 /*
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.
245  *
246  *  Returns false: on failure
247  *          true:  on success
248  */
249 bool db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
250 {
251    int i = 0;
252    uint32_t *id;
253    MEDIA_DBR omr;
254    int len;
255
256    db_lock(mdb);
257    *ids = NULL;
258    if (!bdb_open_media_file(mdb)) {
259       db_unlock(mdb);
260       return false;
261    }
262    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
263    /* Linear search through Pool records
264     */
265    len = sizeof(omr);
266    if (mdb->control.MediaId == 0) {
267       db_unlock(mdb);
268       return false;
269    }
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;
275       }
276    }
277    *ids = id;
278    db_unlock(mdb);
279    return true;
280 }
281
282 /*
283  * Get Media Record
284  * If the MediaId is non-zero, we get its record,
285  *  otherwise, we search on the MediaName
286  *
287  * Returns: false on failure
288  *          true on success
289  */
290 bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
291 {
292    faddr_t rec_addr;
293    bool found = false;
294    int len;
295    MEDIA_DBR omr;
296
297    db_lock(mdb);
298    if (!bdb_open_media_file(mdb)) {
299       goto get_out;
300    }
301    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
302    rec_addr = 0;
303    /* Linear search through Media records
304     */
305    len = sizeof(omr);
306    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
307       if (omr.MediaId == 0) {
308          continue;                    /* deleted record */
309       }
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) {
315            found = true;
316          }
317       /* Search by Name */
318       } else if (strcmp(mr->VolumeName, omr.VolumeName) == 0) {
319          found = true;
320       }
321       if (!found) {
322          rec_addr = ftell(mdb->mediafd); /* save start next record */
323          continue;
324       }
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);
330       break;
331    }
332    if (!found) {
333       strcpy(mdb->errmsg, "Could not find requested Media record.\n");
334    }
335 get_out:
336    db_unlock(mdb);
337    return found;
338 }
339
340 /*
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 (|).
346  */
347 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
348 {
349    int found = 0;
350    JOBMEDIA_DBR jm;
351    MEDIA_DBR mr;
352    int jmlen, mrlen;
353
354    db_lock(mdb);
355    if (!bdb_open_jobmedia_file(mdb)) {
356       db_unlock(mdb);
357       return 0;
358    }
359    if (!bdb_open_media_file(mdb)) {
360       db_unlock(mdb);
361       return 0;
362    }
363    jmlen = sizeof(jm);
364    mrlen = sizeof(mr);
365    *VolumeNames[0] = 0;
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 */
375                }
376                pm_strcat(VolumeNames, mr.VolumeName); /* add Volume Name */
377                found++;
378             }
379          }
380       }
381    }
382    if (!found) {
383       strcpy(mdb->errmsg, "No Volumes found.\n");
384    }
385    db_unlock(mdb);
386    return found;
387 }
388
389 /*
390  * Get Client Record
391  * If the ClientId is non-zero, we get its record,
392  *  otherwise, we search on the Name
393  *
394  * Returns: 0 on failure
395  *          id on success
396  */
397 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
398 {
399    CLIENT_DBR lcr;
400    int len;
401    int stat = 0;
402
403    db_lock(mdb);
404    if (!bdb_open_client_file(mdb)) {
405       db_unlock(mdb);
406       return 0;
407    }
408    fseek(mdb->clientfd, 0L, SEEK_SET);   /* rewind file */
409    /*
410     * Linear search through Client records
411     */
412    len = sizeof(lcr);
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) {
417             continue;
418          }
419       /* Search by Name */
420       } else if (strcmp(cr->Name, lcr.Name) != 0) {
421          continue;                 /* not found */
422       }
423       memcpy(cr, &lcr, len);
424       stat = lcr.ClientId;
425       Dmsg2(200, "Found Client record: ClientId=%d Name=%s\n",
426             lcr.ClientId, lcr.Name);
427       break;
428    }
429    if (!stat) {
430       strcpy(mdb->errmsg, "Client record not found.\n");
431    }
432    db_unlock(mdb);
433    return stat;
434 }
435
436 /*
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).
440  *
441  * Returns: 0 on failure
442  *          id on success
443  */
444 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
445 {
446    FILESET_DBR lfsr;
447    int stat = 0;
448
449    db_lock(mdb);
450    if (!bdb_open_fileset_file(mdb)) {
451       db_unlock(mdb);
452       return 0;
453    }
454    fseek(mdb->filesetfd, 0L, SEEK_SET);   /* rewind file */
455    /*
456     * Linear search through FileSet records
457     */
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) {
462             continue;
463          }
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 */
468       }
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);
474       break;
475    }
476    if (!stat) {
477       strcpy(mdb->errmsg, "FileSet record not found.\n");
478    }
479    db_unlock(mdb);
480    return stat;
481 }
482
483
484
485 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
486 { return 0; }
487
488 int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
489 { return 0; }
490
491 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
492 { return 0; }
493
494 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
495 { return 0; }
496
497
498 #endif /* HAVE_BACULA_DB */