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