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