]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_get.c
Update comments and echo to indicate this script is for upgrading version
[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    Bacula® - The Network Backup Solution
20
21    Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
22
23    The main author of Bacula is Kern Sibbald, with contributions from
24    many others, a complete list can be found in the file AUTHORS.
25    This program is Free Software; you can redistribute it and/or
26    modify it under the terms of version two of the GNU General Public
27    License as published by the Free Software Foundation plus additions
28    that are listed in the file LICENSE.
29
30    This program is distributed in the hope that it will be useful, but
31    WITHOUT ANY WARRANTY; without even the implied warranty of
32    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33    General Public License for more details.
34
35    You should have received a copy of the GNU General Public License
36    along with this program; if not, write to the Free Software
37    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38    02110-1301, USA.
39
40    Bacula® is a registered trademark of John Walker.
41    The licensor of Bacula is the Free Software Foundation Europe
42    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
43    Switzerland, email:ftf@fsfeurope.org.
44 */
45
46
47 /* The following is necessary so that we do not include
48  * the dummy external definition of DB.
49  */
50 #define __SQL_C                       /* indicate that this is sql.c */
51
52 #include "bacula.h"
53 #include "cats.h"
54 #include "bdb.h"
55
56 #ifdef HAVE_BACULA_DB
57
58 /* Forward referenced functions */
59
60
61 /* -----------------------------------------------------------------------
62  *
63  *   Bacula specific defines and subroutines
64  *
65  * -----------------------------------------------------------------------
66  */
67
68
69 /*
70  * Get Job record for given JobId
71  * Returns: 0 on failure
72  *          1 on success
73  */
74
75 bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
76 {
77    JOB_DBR ojr;
78    faddr_t rec_addr;
79    int found = 0;
80    int stat = 0;
81    int len;
82
83    db_lock(mdb);
84    if (jr->JobId == 0 && jr->Name[0] == 0) { /* he wants # of Job records */
85       jr->JobId = mdb->control.JobId;
86       db_unlock(mdb);
87       return 1;
88    }
89    Dmsg0(200, "Open Jobs\n");
90    if (!bdb_open_jobs_file(mdb)) {
91       db_unlock(mdb);
92       return 0;
93    }
94    fseek(mdb->jobfd, 0L, SEEK_SET);   /* rewind file */
95    rec_addr = 0;
96    /* Linear search through Job records
97     */
98    len = sizeof(ojr);
99    while (fread(&ojr, len, 1, mdb->jobfd) > 0) {
100       /* If id not zero, search by Id */
101       if (jr->JobId != 0) {
102          if (jr->JobId == ojr.JobId) {
103            found = 1;
104          }
105       /* Search by Job */
106       } else if (strcmp(jr->Job, ojr.Job) == 0) {
107          found = 1;
108          Dmsg1(200, "Found Job: %s\n", ojr.Job);
109       }
110       if (!found) {
111          rec_addr = ftell(mdb->jobfd); /* save start next record */
112          continue;
113       }
114       /* Found desired record, now return it */
115       memcpy(jr, &ojr, len);
116       jr->rec_addr = rec_addr;
117       stat = ojr.JobId;
118       Dmsg2(200, "Found job record: JobId=%d Job=%s",
119          ojr.JobId, ojr.Job);
120       break;
121    }
122    if (!found) {
123       strcpy(mdb->errmsg, "Job record not found.\n");
124    }
125    db_unlock(mdb);
126    Dmsg1(200, "Return job stat=%d\n", stat);
127    return stat;
128 }
129
130
131 /*
132  * Get the number of pool records
133  *
134  * Returns: -1 on failure
135  *          number on success
136  */
137 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
138 {
139    int stat = 0;
140
141    db_lock(mdb);
142    stat = mdb->control.PoolId;
143    db_unlock(mdb);
144    return stat;
145 }
146
147 /*
148  * This function returns a list of all the Pool record ids.
149  *  The caller must free ids if non-NULL.
150  *
151  *  Returns 0: on failure
152  *          1: on success
153  */
154 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
155 {
156    int i = 0;
157    uint32_t *id;
158    POOL_DBR opr;
159    int len;
160
161    db_lock(mdb);
162    *ids = NULL;
163    if (!bdb_open_pools_file(mdb)) {
164       db_unlock(mdb);
165       return 0;
166    }
167    fseek(mdb->poolfd, 0L, SEEK_SET);   /* rewind file */
168    /* Linear search through Pool records
169     */
170    len = sizeof(opr);
171    *num_ids = mdb->control.PoolId;
172    id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
173    while (fread(&opr, len, 1, mdb->poolfd) > 0) {
174       id[i++] = opr.PoolId;
175    }
176    *ids = id;
177    db_unlock(mdb);
178    return 1;
179 }
180
181
182 /*
183  * Get Pool Record
184  * If the PoolId is non-zero, we get its record,
185  *  otherwise, we search on the PoolName
186  *
187  * Returns: false on failure
188  *          true on success
189  */
190 bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
191 {
192    POOL_DBR opr;
193    faddr_t rec_addr;
194    bool found = false;
195    int len;
196
197    db_lock(mdb);
198    Dmsg0(200, "Open pools\n");
199    if (!bdb_open_pools_file(mdb)) {
200       db_unlock(mdb);
201       return false;
202    }
203    fseek(mdb->poolfd, 0L, SEEK_SET);   /* rewind file */
204    rec_addr = 0;
205    /* Linear search through Pool records
206     */
207    len = sizeof(opr);
208    while (fread(&opr, len, 1, mdb->poolfd) > 0) {
209       /* If id not zero, search by Id */
210       if (pr->PoolId != 0) {
211          if (pr->PoolId == opr.PoolId) {
212            found = true;
213          }
214       /* Search by Name */
215       } else if (strcmp(pr->Name, opr.Name) == 0) {
216          found = true;
217          Dmsg1(200, "Found pool: %s\n", opr.Name);
218       }
219       if (!found) {
220          rec_addr = ftell(mdb->poolfd); /* save start next record */
221          continue;
222       }
223       /* Found desired record, now return it */
224       memcpy(pr, &opr, len);
225       pr->rec_addr = rec_addr;
226       Dmsg3(200, "Found pool record: PoolId=%d Name=%s PoolType=%s\n",
227          opr.PoolId, opr.Name, opr.PoolType);
228       break;
229    }
230    if (!found) {
231       strcpy(mdb->errmsg, "Pool record not found.\n");
232    }
233    db_unlock(mdb);
234    return found;
235 }
236
237 /*
238  * Get the number of Media records
239  *
240  * Returns: -1 on failure
241  *          number on success
242  */
243 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
244 {
245    int stat = 0;
246
247    db_lock(mdb);
248    stat = mdb->control.MediaId;
249    db_unlock(mdb);
250    return stat;
251 }
252
253 /*
254  * This function returns a list of all the Media record ids
255  *  for a specified PoolId
256  *  The caller must free ids if non-NULL.
257  *
258  *  Returns false: on failure
259  *          true:  on success
260  */
261 bool db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
262 {
263    int i = 0;
264    uint32_t *id;
265    MEDIA_DBR omr;
266    int len;
267
268    db_lock(mdb);
269    *ids = NULL;
270    if (!bdb_open_media_file(mdb)) {
271       db_unlock(mdb);
272       return false;
273    }
274    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
275    /* Linear search through Pool records
276     */
277    len = sizeof(omr);
278    if (mdb->control.MediaId == 0) {
279       db_unlock(mdb);
280       return false;
281    }
282    *num_ids = mdb->control.MediaId;
283    id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
284    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
285       if (PoolId == omr.MediaId) {
286          id[i++] = omr.MediaId;
287       }
288    }
289    *ids = id;
290    db_unlock(mdb);
291    return true;
292 }
293
294 /*
295  * Get Media Record
296  * If the MediaId is non-zero, we get its record,
297  *  otherwise, we search on the MediaName
298  *
299  * Returns: false on failure
300  *          true on success
301  */
302 bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
303 {
304    faddr_t rec_addr;
305    bool found = false;
306    int len;
307    MEDIA_DBR omr;
308
309    db_lock(mdb);
310    if (!bdb_open_media_file(mdb)) {
311       goto get_out;
312    }
313    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
314    rec_addr = 0;
315    /* Linear search through Media records
316     */
317    len = sizeof(omr);
318    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
319       if (omr.MediaId == 0) {
320          continue;                    /* deleted record */
321       }
322       Dmsg1(200, "VolName=%s\n", omr.VolumeName);
323       /* If id not zero, search by Id */
324       if (mr->MediaId != 0) {
325          Dmsg1(200, "MediaId=%d\n", mr->MediaId);
326          if (mr->MediaId == omr.MediaId) {
327            found = true;
328          }
329       /* Search by Name */
330       } else if (strcmp(mr->VolumeName, omr.VolumeName) == 0) {
331          found = true;
332       }
333       if (!found) {
334          rec_addr = ftell(mdb->mediafd); /* save start next record */
335          continue;
336       }
337       /* Found desired record, now return it */
338       memcpy(mr, &omr, len);
339       mr->rec_addr = rec_addr;
340       Dmsg3(200, "Found media record: MediaId=%d Name=%s MediaType=%s\n",
341          omr.MediaId, omr.VolumeName, mr->MediaType);
342       break;
343    }
344    if (!found) {
345       strcpy(mdb->errmsg, "Could not find requested Media record.\n");
346    }
347 get_out:
348    db_unlock(mdb);
349    return found;
350 }
351
352 /*
353  * Find VolumeNames for a give JobId
354  *  Returns: 0 on error or no Volumes found
355  *           number of volumes on success
356  *              Volumes are concatenated in VolumeNames
357  *              separated by a vertical bar (|).
358  */
359 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
360 {
361    int found = 0;
362    JOBMEDIA_DBR jm;
363    MEDIA_DBR mr;
364    int jmlen, mrlen;
365
366    db_lock(mdb);
367    if (!bdb_open_jobmedia_file(mdb)) {
368       db_unlock(mdb);
369       return 0;
370    }
371    if (!bdb_open_media_file(mdb)) {
372       db_unlock(mdb);
373       return 0;
374    }
375    jmlen = sizeof(jm);
376    mrlen = sizeof(mr);
377    *VolumeNames[0] = 0;
378    fseek(mdb->jobmediafd, 0L, SEEK_SET); /* rewind the file */
379    while (fread(&jm, jmlen, 1, mdb->jobmediafd) > 0) {
380       if (jm.JobId == JobId) {
381          /* Now look up VolumeName in Media file given MediaId */
382          fseek(mdb->mediafd, 0L, SEEK_SET);
383          while (fread(&mr, mrlen, 1, mdb->mediafd) > 0) {
384             if (jm.MediaId == mr.MediaId) {
385                if (*VolumeNames[0] != 0) {      /* if not first name, */
386                   pm_strcat(VolumeNames, "|");  /* add separator */
387                }
388                pm_strcat(VolumeNames, mr.VolumeName); /* add Volume Name */
389                found++;
390             }
391          }
392       }
393    }
394    if (!found) {
395       strcpy(mdb->errmsg, "No Volumes found.\n");
396    }
397    db_unlock(mdb);
398    return found;
399 }
400
401 /*
402  * Get Client Record
403  * If the ClientId is non-zero, we get its record,
404  *  otherwise, we search on the Name
405  *
406  * Returns: 0 on failure
407  *          id on success
408  */
409 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
410 {
411    CLIENT_DBR lcr;
412    int len;
413    int stat = 0;
414
415    db_lock(mdb);
416    if (!bdb_open_client_file(mdb)) {
417       db_unlock(mdb);
418       return 0;
419    }
420    fseek(mdb->clientfd, 0L, SEEK_SET);   /* rewind file */
421    /*
422     * Linear search through Client records
423     */
424    len = sizeof(lcr);
425    while (fread(&lcr, len, 1, mdb->clientfd)) {
426       /* If id not zero, search by Id */
427       if (cr->ClientId != 0) {
428          if (cr->ClientId != lcr.ClientId) {
429             continue;
430          }
431       /* Search by Name */
432       } else if (strcmp(cr->Name, lcr.Name) != 0) {
433          continue;                 /* not found */
434       }
435       memcpy(cr, &lcr, len);
436       stat = lcr.ClientId;
437       Dmsg2(200, "Found Client record: ClientId=%d Name=%s\n",
438             lcr.ClientId, lcr.Name);
439       break;
440    }
441    if (!stat) {
442       strcpy(mdb->errmsg, "Client record not found.\n");
443    }
444    db_unlock(mdb);
445    return stat;
446 }
447
448 /*
449  * Get FileSet Record   (We read the FILESET_DBR structure)
450  * If the FileSetId is non-zero, we get its record,
451  *  otherwise, we search on the FileSet (its name).
452  *
453  * Returns: 0 on failure
454  *          id on success
455  */
456 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
457 {
458    FILESET_DBR lfsr;
459    int stat = 0;
460
461    db_lock(mdb);
462    if (!bdb_open_fileset_file(mdb)) {
463       db_unlock(mdb);
464       return 0;
465    }
466    fseek(mdb->filesetfd, 0L, SEEK_SET);   /* rewind file */
467    /*
468     * Linear search through FileSet records
469     */
470    while (fread(&lfsr, sizeof(lfsr), 1, mdb->filesetfd) > 0) {
471       /* If id not zero, search by Id */
472       if (fsr->FileSetId != 0) {
473          if (fsr->FileSetId != lfsr.FileSetId) {
474             continue;
475          }
476       /* Search by Name & MD5 */
477       } else if (strcmp(fsr->FileSet, lfsr.FileSet) != 0 ||
478                  strcmp(fsr->MD5, lfsr.MD5) != 0) {
479          continue;                 /* not found */
480       }
481       /* Found desired record, now return it */
482       memcpy(fsr, &lfsr, sizeof(lfsr));
483       stat = fsr->FileSetId;
484       Dmsg2(200, "Found FileSet record: FileSetId=%d FileSet=%s\n",
485             lfsr.FileSetId, lfsr.FileSet);
486       break;
487    }
488    if (!stat) {
489       strcpy(mdb->errmsg, "FileSet record not found.\n");
490    }
491    db_unlock(mdb);
492    return stat;
493 }
494
495
496
497 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
498 { return 0; }
499
500 int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
501 { return 0; }
502
503 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
504 { return 0; }
505
506 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
507 { return 0; }
508
509
510 #endif /* HAVE_BACULA_DB */