]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_get.c
1.19 24Apr02
[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
17 /*
18    Copyright (C) 2001, 2002 Kern Sibbald and John Walker
19
20    This program is free software; you can redistribute it and/or
21    modify it under the terms of the GNU General Public License as
22    published by the Free Software Foundation; either version 2 of
23    the License, or (at your option) any later version.
24
25    This program is distributed in the hope that it will be useful,
26    but WITHOUT ANY WARRANTY; without even the implied warranty of
27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28    General Public License for more details.
29
30    You should have received a copy of the GNU General Public
31    License along with this program; if not, write to the Free
32    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
33    MA 02111-1307, USA.
34
35  */
36
37
38 /* The following is necessary so that we do not include
39  * the dummy external definition of DB.
40  */
41 #define __SQL_C                       /* indicate that this is sql.c */
42
43 #include "bacula.h"
44 #include "cats.h"
45 #include "bdb.h"
46
47 #ifdef HAVE_BACULA_DB
48
49 /* Forward referenced functions */
50 int db_get_media_record(B_DB *mdb, MEDIA_DBR *mr);
51 int db_get_pool_record(B_DB *mdb, POOL_DBR *pr);
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(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    P(mdb->mutex);
77    if (jr->JobId == 0 && jr->Name[0] == 0) { /* he wants # of Job records */
78       jr->JobId = mdb->control.JobId;
79       V(mdb->mutex);
80       return 1;
81    }
82    Dmsg0(200, "Open Jobs\n");
83    if (!bdb_open_jobs_file(mdb)) {
84       V(mdb->mutex);
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    V(mdb->mutex);
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(B_DB *mdb)
131 {
132    int stat = 0;
133
134    P(mdb->mutex);
135    stat = mdb->control.PoolId;
136    V(mdb->mutex);
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(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    P(mdb->mutex);
155    *ids = NULL;
156    if (!bdb_open_pools_file(mdb)) {
157       V(mdb->mutex);
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    V(mdb->mutex);
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: 0 on failure
181  *          id on success 
182  */
183 int db_get_pool_record(B_DB *mdb, POOL_DBR *pr)
184 {
185    POOL_DBR opr;
186    faddr_t rec_addr;
187    int found = 0;
188    int stat = 0;
189    int len;
190
191    P(mdb->mutex);
192    Dmsg0(200, "Open pools\n");
193    if (!bdb_open_pools_file(mdb)) {
194       V(mdb->mutex);
195       return 0;
196    }
197    fseek(mdb->poolfd, 0L, SEEK_SET);   /* rewind file */
198    rec_addr = 0;
199    /* Linear search through Pool records
200     */
201    len = sizeof(opr);
202    while (fread(&opr, len, 1, mdb->poolfd) > 0) {
203       /* If id not zero, search by Id */
204       if (pr->PoolId != 0) {
205          if (pr->PoolId == opr.PoolId) {
206            found = 1;
207          }
208       /* Search by Name */
209       } else if (strcmp(pr->Name, opr.Name) == 0) {
210          found = 1;
211          Dmsg1(200, "Found pool: %s\n", opr.Name);
212       }
213       if (!found) {
214          rec_addr = ftell(mdb->poolfd); /* save start next record */
215          continue;
216       }
217       /* Found desired record, now return it */
218       memcpy(pr, &opr, len);
219       pr->rec_addr = rec_addr;
220       stat = opr.PoolId;
221       Dmsg3(200, "Found pool record: PoolId=%d Name=%s PoolType=%s\n",
222          opr.PoolId, opr.Name, opr.PoolType);
223       break;
224    }
225    if (!found) {
226       strcpy(mdb->errmsg, "Pool record not found.\n");
227    }
228    V(mdb->mutex);
229    Dmsg1(200, "Return pool stat=%d\n", stat);
230    return stat;
231 }
232
233 /* 
234  * Get the number of Media records
235  *
236  * Returns: -1 on failure
237  *          number on success
238  */
239 int db_get_num_media_records(B_DB *mdb)
240 {
241    int stat = 0;
242
243    P(mdb->mutex);
244    stat = mdb->control.MediaId;
245    V(mdb->mutex);
246    return stat;
247 }
248
249 /*
250  * This function returns a list of all the Media record ids.
251  *  The caller must free ids if non-NULL.
252  *
253  *  Returns 0: on failure
254  *          1: on success
255  */
256 int db_get_media_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
257 {
258    int i = 0;
259    uint32_t *id;
260    MEDIA_DBR omr;
261    int len;
262
263    P(mdb->mutex);
264    *ids = NULL;
265    if (!bdb_open_media_file(mdb)) {
266       V(mdb->mutex);
267       return 0;
268    }
269    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
270    /* Linear search through Pool records
271     */
272    len = sizeof(omr);
273    *num_ids = mdb->control.MediaId;
274    id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
275    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
276       id[i++] = omr.MediaId;
277    }
278    *ids = id;
279    V(mdb->mutex);
280    return 1;
281 }
282
283 /* 
284  * Get Media Record   
285  * If the MediaId is non-zero, we get its record,
286  *  otherwise, we search on the MediaName
287  *
288  * Returns: 0 on failure
289  *          id on success 
290  */
291 int db_get_media_record(B_DB *mdb, MEDIA_DBR *mr)
292 {
293    faddr_t rec_addr;
294    int found = 0;
295    int stat = 0;
296    int len;
297    MEDIA_DBR omr;
298
299    P(mdb->mutex);
300    if (!bdb_open_media_file(mdb)) {
301       V(mdb->mutex);
302       return 0;
303    }
304    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
305    rec_addr = 0;
306    /* Linear search through Media records
307     */
308    len = sizeof(omr);
309    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
310       if (omr.MediaId == 0) {
311          continue;                    /* deleted record */
312       }
313       Dmsg1(200, "VolName=%s\n", omr.VolumeName);
314       /* If id not zero, search by Id */
315       if (mr->MediaId != 0) {
316          Dmsg1(200, "MediaId=%d\n", mr->MediaId);
317          if (mr->MediaId == omr.MediaId) {
318            found = 1;
319          }
320       /* Search by Name */
321       } else if (strcmp(mr->VolumeName, omr.VolumeName) == 0) {
322          found = 1;
323       }
324       if (!found) {
325          rec_addr = ftell(mdb->mediafd); /* save start next record */
326          continue;
327       }
328       /* Found desired record, now return it */
329       memcpy(mr, &omr, len);
330       mr->rec_addr = rec_addr;
331       stat = omr.MediaId;
332       Dmsg3(200, "Found media record: MediaId=%d Name=%s MediaType=%s\n",
333          omr.MediaId, omr.VolumeName, mr->MediaType);
334       break;
335    }
336    if (stat == 0) {
337       strcpy(mdb->errmsg, "Could not find requested Media record.\n");
338    }
339    V(mdb->mutex);
340    return stat;
341 }
342
343 /*
344  * Find VolumeNames for a give JobId
345  *  Returns: 0 on error or no Volumes found
346  *           number of volumes on success
347  *              Volumes are concatenated in VolumeNames
348  *              separated by a vertical bar (|).
349  */
350 int db_get_job_volume_names(B_DB *mdb, uint32_t JobId, char *VolumeNames)
351 {
352    int found = 0;
353    JOBMEDIA_DBR jm;
354    MEDIA_DBR mr;
355    int jmlen, mrlen;
356
357    P(mdb->mutex);
358    if (!bdb_open_jobmedia_file(mdb)) {
359       V(mdb->mutex);
360       return 0;
361    }
362    if (!bdb_open_media_file(mdb)) {
363       V(mdb->mutex);
364       return 0;
365    }
366    jmlen = sizeof(jm);
367    mrlen = sizeof(mr);
368    *VolumeNames = 0;
369    fseek(mdb->jobmediafd, 0L, SEEK_SET); /* rewind the file */
370    while (fread(&jm, jmlen, 1, mdb->jobmediafd) > 0) {
371       if (jm.JobId == JobId) {
372          /* Now look up VolumeName in Media file given MediaId */
373          fseek(mdb->mediafd, 0L, SEEK_SET);
374          while (fread(&mr, mrlen, 1, mdb->mediafd) > 0) {
375             if (jm.MediaId == mr.MediaId) {
376                if (*VolumeNames != 0) {         /* if not first name, */
377                   strcat(VolumeNames, "|");     /* add separator */
378                }
379                strcat(VolumeNames, mr.VolumeName); /* add Volume Name */
380                found++;
381             }
382          }
383       }
384    }
385    if (!found) {
386       strcpy(mdb->errmsg, "No Volumes found.\n");
387    }
388    V(mdb->mutex);
389    return found; 
390 }
391
392 /* 
393  * Get Client Record   
394  * If the ClientId is non-zero, we get its record,
395  *  otherwise, we search on the Name
396  *
397  * Returns: 0 on failure
398  *          id on success 
399  */
400 int db_get_client_record(B_DB *mdb, CLIENT_DBR *cr)
401 {
402    CLIENT_DBR lcr;
403    int len;
404    int stat = 0;
405
406    P(mdb->mutex);
407    if (!bdb_open_client_file(mdb)) {
408       V(mdb->mutex);
409       return 0;
410    }
411    fseek(mdb->clientfd, 0L, SEEK_SET);   /* rewind file */
412    /*
413     * Linear search through Client records
414     */
415    len = sizeof(lcr);
416    while (fread(&lcr, len, 1, mdb->clientfd)) {
417       /* If id not zero, search by Id */
418       if (cr->ClientId != 0) {
419          if (cr->ClientId != lcr.ClientId) {
420             continue;
421          }
422       /* Search by Name */
423       } else if (strcmp(cr->Name, lcr.Name) != 0) {
424          continue;                 /* not found */
425       }
426       memcpy(cr, &lcr, len);
427       stat = lcr.ClientId;
428       Dmsg2(200, "Found Client record: ClientId=%d Name=%s\n", 
429             lcr.ClientId, lcr.Name);
430       break;
431    }
432    if (!stat) {
433       strcpy(mdb->errmsg, "Client record not found.\n");
434    }
435    V(mdb->mutex);
436    return stat;
437 }
438
439 /* 
440  * Get FileSet Record   (We read the FILESET_DBR structure)
441  * If the FileSetId is non-zero, we get its record,
442  *  otherwise, we search on the FileSet (its name).
443  *
444  * Returns: 0 on failure
445  *          id on success 
446  */
447 int db_get_fileset_record(B_DB *mdb, FILESET_DBR *fsr)
448 {
449    FILESET_DBR lfsr;
450    int stat = 0;
451
452    P(mdb->mutex);
453    if (!bdb_open_fileset_file(mdb)) {
454       V(mdb->mutex);
455       return 0;
456    }
457    fseek(mdb->filesetfd, 0L, SEEK_SET);   /* rewind file */
458    /*
459     * Linear search through FileSet records
460     */
461    while (fread(&lfsr, sizeof(lfsr), 1, mdb->filesetfd) > 0) {
462       /* If id not zero, search by Id */
463       if (fsr->FileSetId != 0) {
464          if (fsr->FileSetId != lfsr.FileSetId) {
465             continue;
466          }
467       /* Search by Name & MD5 */
468       } else if (strcmp(fsr->FileSet, lfsr.FileSet) != 0 ||
469                  strcmp(fsr->MD5, lfsr.MD5) != 0) {
470          continue;                 /* not found */
471       }
472       /* Found desired record, now return it */
473       memcpy(fsr, &lfsr, sizeof(lfsr));
474       stat = fsr->FileSetId;
475       Dmsg2(200, "Found FileSet record: FileSetId=%d FileSet=%s\n", 
476             lfsr.FileSetId, lfsr.FileSet);
477       break;
478    }
479    if (!stat) {
480       strcpy(mdb->errmsg, "FileSet record not found.\n");
481    }
482    V(mdb->mutex);
483    return stat;
484 }
485
486
487
488 int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr) 
489 { return 0; }
490
491
492
493 #endif /* HAVE_BACULA_DB */