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