]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/cats.h
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / cats / cats.h
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *  Catalog DB header file
21  *
22  *  Written by Kern E. Sibbald
23  *
24  *  Anyone who accesses the database will need to include
25  *   this file.
26  */
27
28 #ifndef __CATS_H_
29 #define __CATS_H_ 1
30
31 /*
32    Here is how database versions work.
33
34    While I am working on a new release with database changes, the
35    update scripts are in the src/cats directory under the names
36    update_xxx_tables.in.  Most of the time, I make database updates
37    in one go and immediately update the version, but not always.  If
38    there are going to be several updates as is the case with version
39    1.37, then I will often forgo changing the version until the last
40    update otherwise I will end up with too many versions and a lot
41    of confusion.
42
43    When I am pretty sure there will be no more updates, I will
44    change the version from 8 to 9 (in the present case), and when I
45    am 100% sure there will be no more changes, the update script
46    will be copied to the updatedb directory with the correct name
47    (in the present case 8 to 9).
48  */
49
50 /* Current database version number for all drivers */
51 #define BDB_VERSION 16
52
53 typedef void (DB_LIST_HANDLER)(void *, const char *);
54 typedef int (DB_RESULT_HANDLER)(void *, int, char **);
55
56 /* What kind of database we have */
57 typedef enum {
58    SQL_TYPE_MYSQL      = 0,
59    SQL_TYPE_POSTGRESQL = 1,
60    SQL_TYPE_SQLITE3    = 2,
61    SQL_TYPE_UNKNOWN    = 99
62 } SQL_DBTYPE;
63
64 /* What kind of driver we have */
65 typedef enum {
66    SQL_DRIVER_TYPE_MYSQL      = 0,
67    SQL_DRIVER_TYPE_POSTGRESQL = 1,
68    SQL_DRIVER_TYPE_SQLITE3    = 2
69 } SQL_DRIVER;
70
71
72 /* ==============================================================
73  *
74  *  What follows are definitions that are used "globally" for all
75  *   the different SQL engines and both inside and external to the
76  *   cats directory.
77  */
78
79 #define faddr_t long
80
81 /*
82  * Generic definition of a sql_row.
83  */
84 typedef char **SQL_ROW;
85
86 /*
87  * Generic definition of a a sql_field.
88  */
89 typedef struct sql_field {
90    char *name;                        /* name of column */
91    int max_length;                    /* max length */
92    uint32_t type;                     /* type */
93    uint32_t flags;                    /* flags */
94 } SQL_FIELD;
95
96
97 /*
98  * Structure used when calling db_get_query_ids()
99  *  allows the subroutine to return a list of ids.
100  */
101 class dbid_list : public SMARTALLOC {
102 public:
103    DBId_t *DBId;                      /* array of DBIds */
104    char *PurgedFiles;                 /* Array of PurgedFile flags */
105    int num_ids;                       /* num of ids actually stored */
106    int max_ids;                       /* size of id array */
107    int num_seen;                      /* number of ids processed */
108    int tot_ids;                       /* total to process */
109
110    dbid_list();                       /* in sql.c */
111    ~dbid_list();                      /* in sql.c */
112 };
113
114 /* Job information passed to create job record and update
115  * job record at end of job. Note, although this record
116  * contains all the fields found in the Job database record,
117  * it also contains fields found in the JobMedia record.
118  */
119 /* Job record */
120 struct JOB_DBR {
121    JobId_t JobId;
122    char Job[MAX_NAME_LENGTH];         /* Job unique name */
123    char Name[MAX_NAME_LENGTH];        /* Job base name */
124    int JobType;                       /* actually char(1) */
125    int JobLevel;                      /* actually char(1) */
126    int JobStatus;                     /* actually char(1) */
127    DBId_t ClientId;                   /* Id of client */
128    DBId_t PoolId;                     /* Id of pool */
129    DBId_t FileSetId;                  /* Id of FileSet */
130    DBId_t PriorJobId;                 /* Id of migrated (prior) job */
131    time_t SchedTime;                  /* Time job scheduled */
132    time_t StartTime;                  /* Job start time */
133    time_t EndTime;                    /* Job termination time of orig job */
134    time_t RealEndTime;                /* Job termination time of this job */
135    utime_t JobTDate;                  /* Backup time/date in seconds */
136    uint32_t VolSessionId;
137    uint32_t VolSessionTime;
138    uint32_t JobFiles;
139    uint32_t JobErrors;
140    uint32_t JobMissingFiles;
141    uint64_t JobBytes;
142    uint64_t ReadBytes;
143    int PurgedFiles;
144    int HasBase;
145
146    /* Note, FirstIndex, LastIndex, Start/End File and Block
147     * are only used in the JobMedia record.
148     */
149    uint32_t FirstIndex;               /* First index this Volume */
150    uint32_t LastIndex;                /* Last index this Volume */
151    uint32_t StartFile;
152    uint32_t EndFile;
153    uint32_t StartBlock;
154    uint32_t EndBlock;
155
156    char cSchedTime[MAX_TIME_LENGTH];
157    char cStartTime[MAX_TIME_LENGTH];
158    char cEndTime[MAX_TIME_LENGTH];
159    char cRealEndTime[MAX_TIME_LENGTH];
160    /* Extra stuff not in DB */
161    int     order;                     /* 0 ASC, 1 DESC */
162    int     limit;                     /* limit records to display */
163    faddr_t rec_addr;
164    uint32_t FileIndex;                /* added during Verify */
165
166    int     CorrNbJob;                 /* used by dbd_get_job_statistics() */
167    int     CorrJobBytes;              /* used by dbd_get_job_statistics() */
168    int     CorrJobFiles;              /* used by dbd_get_job_statistics() */
169 };
170
171 /* Job Media information used to create the media records
172  * for each Volume used for the job.
173  */
174 /* JobMedia record */
175 struct JOBMEDIA_DBR {
176    DBId_t JobMediaId;                 /* record id */
177    JobId_t  JobId;                    /* JobId */
178    DBId_t MediaId;                    /* MediaId */
179    uint32_t FirstIndex;               /* First index this Volume */
180    uint32_t LastIndex;                /* Last index this Volume */
181    uint32_t StartFile;                /* File for start of data */
182    uint32_t EndFile;                  /* End file on Volume */
183    uint32_t StartBlock;               /* start block on tape */
184    uint32_t EndBlock;                 /* last block */
185 };
186
187
188 /* Volume Parameter structure */
189 struct VOL_PARAMS {
190    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
191    char MediaType[MAX_NAME_LENGTH];   /* Media Type */
192    char Storage[MAX_NAME_LENGTH];     /* Storage name */
193    uint32_t VolIndex;                 /* Volume seqence no. */
194    uint32_t FirstIndex;               /* First index this Volume */
195    uint32_t LastIndex;                /* Last index this Volume */
196    int32_t Slot;                      /* Slot */
197    uint64_t StartAddr;                /* Start address */
198    uint64_t EndAddr;                  /* End address */
199    int32_t InChanger;                 /* InChanger flag */
200 };
201
202
203 /* Attributes record -- NOT same as in database because
204  *  in general, this "record" creates multiple database
205  *  records (e.g. pathname, filename, fileattributes).
206  */
207 struct ATTR_DBR {
208    char *fname;                       /* full path & filename */
209    char *link;                        /* link if any */
210    char *attr;                        /* attributes statp */
211    uint32_t FileIndex;
212    uint32_t Stream;
213    uint32_t FileType;
214    uint32_t DeltaSeq;
215    JobId_t  JobId;
216    DBId_t ClientId;
217    DBId_t PathId;
218    DBId_t FilenameId;
219    FileId_t FileId;
220    char *Digest;
221    int DigestType;
222 };
223
224 struct ROBJECT_DBR {
225    char *object_name;
226    char *object;
227    char *plugin_name;
228    char *JobIds;
229    uint32_t object_len;
230    uint32_t object_full_len;
231    uint32_t object_index;
232    int32_t  object_compression;
233    uint32_t FileIndex;
234    uint32_t Stream;
235    uint32_t FileType;
236    JobId_t  JobId;
237    DBId_t RestoreObjectId;
238 };
239
240
241 /* File record -- same format as database */
242 struct FILE_DBR {
243    FileId_t FileId;
244    uint32_t FileIndex;
245    uint32_t FileIndex2;
246    JobId_t  JobId;
247    DBId_t FilenameId;
248    DBId_t PathId;
249    JobId_t  MarkId;
250    uint32_t DeltaSeq;
251    char LStat[256];
252    char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
253    int DigestType;                    /* NO_SIG/MD5_SIG/SHA1_SIG */
254 };
255
256 /* Pool record -- same format as database */
257 struct POOL_DBR {
258    DBId_t PoolId;
259    char Name[MAX_NAME_LENGTH];        /* Pool name */
260    uint32_t NumVols;                  /* total number of volumes */
261    uint32_t MaxVols;                  /* max allowed volumes */
262    int32_t LabelType;                 /* Bacula/ANSI/IBM */
263    int32_t UseOnce;                   /* set to use once only */
264    int32_t UseCatalog;                /* set to use catalog */
265    int32_t AcceptAnyVolume;           /* set to accept any volume sequence */
266    int32_t AutoPrune;                 /* set to prune automatically */
267    int32_t Recycle;                   /* default Vol recycle flag */
268    uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
269    utime_t  VolRetention;             /* retention period in seconds */
270    utime_t  CacheRetention;           /* cache retention period in seconds */   
271    utime_t  VolUseDuration;           /* time in secs volume can be used */
272    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
273    uint32_t MaxVolFiles;              /* Max files on Volume */
274    uint64_t MaxVolBytes;              /* Max bytes on Volume */
275    DBId_t RecyclePoolId;              /* RecyclePool destination when media is purged */
276    DBId_t ScratchPoolId;              /* ScratchPool source when media is needed */
277    char PoolType[MAX_NAME_LENGTH];
278    char LabelFormat[MAX_NAME_LENGTH];
279    /* Extra stuff not in DB */
280    faddr_t rec_addr;
281 };
282
283 class DEVICE_DBR {
284 public:
285    DBId_t DeviceId;
286    char Name[MAX_NAME_LENGTH];        /* Device name */
287    DBId_t MediaTypeId;                /* MediaType */
288    DBId_t StorageId;                  /* Storage id if autochanger */
289    uint32_t DevMounts;                /* Number of times mounted */
290    uint32_t DevErrors;                /* Number of read/write errors */
291    uint64_t DevReadBytes;             /* Number of bytes read */
292    uint64_t DevWriteBytes;            /* Number of bytew written */
293    uint64_t DevReadTime;              /* time spent reading volume */
294    uint64_t DevWriteTime;             /* time spent writing volume */
295    uint64_t DevReadTimeSincCleaning;  /* read time since cleaning */
296    uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
297    time_t   CleaningDate;             /* time last cleaned */
298    utime_t  CleaningPeriod;           /* time between cleanings */
299 };
300
301 class STORAGE_DBR {
302 public:
303    DBId_t StorageId;
304    char Name[MAX_NAME_LENGTH];        /* Device name */
305    int AutoChanger;                   /* Set if autochanger */
306
307    /* Not in database */
308    bool created;                      /* set if created by db_create ... */
309 };
310
311 class MEDIATYPE_DBR {
312 public:
313    DBId_t MediaTypeId;
314    char MediaType[MAX_NAME_LENGTH];   /* MediaType string */
315    int ReadOnly;                      /* Set if read-only */
316 };
317
318 /* Media record -- same as the database */
319 class MEDIA_DBR {
320 public:
321    MEDIA_DBR() { memset(this, 0, sizeof(MEDIA_DBR)); };
322    ~MEDIA_DBR() {  };
323    void clear() { memset(this, 0, sizeof(MEDIA_DBR)); };
324    void copy(MEDIA_DBR *omr) { memcpy(this, omr, sizeof(MEDIA_DBR)); sid_group = NULL; };
325
326    DBId_t MediaId;                    /* Unique volume id */
327    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
328    char MediaType[MAX_NAME_LENGTH];   /* Media type */
329    DBId_t PoolId;                     /* Pool id */
330    time_t   FirstWritten;             /* Time Volume first written this usage */
331    time_t   LastWritten;              /* Time Volume last written */
332    time_t   LabelDate;                /* Date/Time Volume labeled */
333    time_t   InitialWrite;             /* Date/Time Volume first written */
334    int32_t  LabelType;                /* Label (Bacula/ANSI/IBM) */
335    uint32_t VolJobs;                  /* number of jobs on this medium */
336    uint32_t VolFiles;                 /* Number of files */
337    uint32_t VolBlocks;                /* Number of blocks */
338    uint32_t VolParts;                 /* Number of cache parts */
339    uint32_t VolCloudParts;            /* Number of cloud parts */
340    uint32_t VolMounts;                /* Number of times mounted */
341    uint32_t VolErrors;                /* Number of read/write errors */
342    uint64_t VolWrites;                /* Number of writes */
343    uint64_t VolReads;                 /* Number of reads */
344    uint64_t VolBytes;                 /* Number of bytes written */
345    uint64_t VolABytes;                /* Size of aligned volume */
346    uint64_t VolHoleBytes;             /* The size of Holes */
347    uint32_t VolHoles;                 /* Number of holes */
348    uint32_t VolType;                  /* Device type of where Volume labeled */
349    uint64_t MaxVolBytes;              /* Max bytes to write to Volume */
350    uint64_t VolCapacityBytes;         /* capacity estimate */
351    uint64_t LastPartBytes;            /* Bytes in last part */
352    uint64_t VolReadTime;              /* time spent reading volume */
353    uint64_t VolWriteTime;             /* time spent writing volume */
354    utime_t  VolRetention;             /* Volume retention in seconds */
355    utime_t  CacheRetention;           /* Cache retention period in second */
356    utime_t  VolUseDuration;           /* time in secs volume can be used */
357    uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
358    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
359    uint32_t MaxVolFiles;              /* Max files on Volume */
360    int32_t  Recycle;                  /* recycle yes/no */
361    int32_t  Slot;                     /* slot in changer */
362    int32_t  Enabled;                  /* 0=disabled, 1=enabled, 2=archived */
363    int32_t  InChanger;                /* Volume currently in changer */
364    DBId_t   StorageId;                /* Storage record Id */
365    uint32_t EndFile;                  /* Last file on volume */
366    uint32_t EndBlock;                 /* Last block on volume */
367    uint32_t RecycleCount;             /* Number of times recycled */
368    char     VolStatus[20];            /* Volume status */
369    DBId_t   DeviceId;                 /* Device where Vol last written */
370    DBId_t   LocationId;               /* Where Volume is -- user defined */
371    DBId_t   ScratchPoolId;            /* Where to move if scratch */
372    DBId_t   RecyclePoolId;            /* Where to move when recycled */
373    /* Extra stuff not in DB */
374    faddr_t rec_addr;                  /* found record address */
375    /* Since the database returns times as strings, this is how we pass
376     *   them back.
377     */
378    char    cFirstWritten[MAX_TIME_LENGTH]; /* FirstWritten returned from DB */
379    char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
380    char    cLabelDate[MAX_TIME_LENGTH];    /* LabelData returned from DB */
381    char    cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
382    char   *exclude_list;                   /* Optionnal exclude list for db_find_next_volume() */
383    char   *sid_group;                 /* Storageid group string */
384    char    sid[30];                   /* edited StorageId */
385    bool    set_first_written;
386    bool    set_label_date;
387 };
388
389 /* Client record -- same as the database */
390 struct CLIENT_DBR {
391    DBId_t ClientId;                   /* Unique Client id */
392    int AutoPrune;
393    utime_t FileRetention;
394    utime_t JobRetention;
395    char Name[MAX_NAME_LENGTH];        /* Client name */
396    char Uname[256];                   /* Uname for client */
397 };
398
399 /* Counter record as in database */
400 struct COUNTER_DBR {
401    char Counter[MAX_NAME_LENGTH];
402    int32_t MinValue;
403    int32_t MaxValue;
404    int32_t CurrentValue;
405    char WrapCounter[MAX_NAME_LENGTH];
406 };
407
408
409 /* FileSet record -- same as the database */
410 struct FILESET_DBR {
411    DBId_t FileSetId;                  /* Unique FileSet id */
412    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
413    char MD5[50];                      /* MD5 signature of include/exclude */
414    time_t CreateTime;                 /* date created */
415    /*
416     * This is where we return CreateTime
417     */
418    char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
419    /* Not in DB but returned by db_create_fileset() */
420    bool created;                      /* set when record newly created */
421 };
422
423 class SNAPSHOT_DBR {
424 public:
425    SNAPSHOT_DBR() {
426       memset(this, 0, sizeof(SNAPSHOT_DBR));
427    };
428    ~SNAPSHOT_DBR() {
429       reset();
430    };
431    void debug(int level) {
432       Dmsg8(DT_SNAPSHOT|level,
433             "Snapshot      %s:\n"
434             "  Volume:     %s\n"
435             "  Device:     %s\n"
436             "  Id:         %d\n"
437             "  FileSet:    %s\n"
438             "  CreateDate: %s\n"
439             "  Client:     %s\n"
440             "  Type:       %s\n",
441             Name, NPRT(Volume), NPRT(Device), SnapshotId,
442             FileSet, CreateDate, Client, Type);
443    };
444    char *as_arg(POOLMEM **out) {
445       bash_spaces(Name);
446       bash_spaces(Type);
447
448       if (Volume) {
449          bash_spaces(Volume);
450       }
451       if (Device) {
452          bash_spaces(Device);
453       }
454
455       Mmsg(out, "name=%s volume=%s device=%s tdate=%d type=%s",
456            Name, NPRTB(Volume), NPRTB(Device), CreateTDate, Type);
457
458       unbash_spaces(Name);
459       unbash_spaces(Type);
460       if (Volume) {
461          unbash_spaces(Volume);
462       }
463       if (Device) {
464          unbash_spaces(Device);
465       }
466       return *out;
467    };
468    void reset() {
469       if (need_to_free) {
470          if (Volume) {
471             free(Volume);
472          }
473          if (Device) {
474             free(Device);
475          }
476          if (errmsg) {
477             free(errmsg);
478          }
479          errmsg = Volume = Device = NULL;
480       }
481       need_to_free = false;
482    };
483    bool    need_to_free;             /* Need to free the internal memory */
484    /* Used when searching snapshots */
485    char    created_after[MAX_TIME_LENGTH];
486    char    created_before[MAX_TIME_LENGTH];
487    bool    expired;                 /* Look for CreateTDate > (NOW - Retention) */
488    bool    sorted_client;           /* Results sorted by Client, SnapshotId */
489    int     status;                  /* Status of the snapshot */
490
491    DBId_t  SnapshotId;              /* Unique Snapshot ID */
492    DBId_t  JobId;                   /* Related JobId */
493    DBId_t  FileSetId;               /* FileSetId if any */
494    DBId_t  ClientId;                /* From which client this snapshot comes */
495    char    Name[MAX_NAME_LENGTH];   /* Snapshot Name */
496    char    FileSet[MAX_NAME_LENGTH];/* FileSet name if any */
497    char    Client[MAX_NAME_LENGTH]; /* Client name */
498    char    Type[MAX_NAME_LENGTH];   /* zfs, btrfs, lvm, netapp, */
499    char    Comment[MAX_NAME_LENGTH];/* Comment */
500    char    CreateDate[MAX_TIME_LENGTH]; /* Create date as string */
501    time_t  CreateTDate;             /* Create TDate (in sec, since epoch) */
502    char   *Volume;                  /* Volume taken in snapshot */
503    char   *Device;                  /* Device, Pool, Directory, ...  */
504    char   *errmsg;                  /* Error associated with a snapshot */
505    utime_t Retention;               /* Number of second before pruning the snapshot */
506    uint64_t Size;                   /* Snapshot Size */
507 };
508
509 /* Call back context for getting a 32/64 bit value from the database */
510 class db_int64_ctx {
511 public:
512    int64_t value;                     /* value returned */
513    int count;                         /* number of values seen */
514
515    db_int64_ctx() : value(0), count(0) {};
516    ~db_int64_ctx() {};
517 private:
518    db_int64_ctx(const db_int64_ctx&);            /* prohibit pass by value */
519    db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */
520 };
521
522 /* Call back context for getting a list of comma separated strings from the
523  * database
524  */
525 class db_list_ctx {
526 public:
527    POOLMEM *list;                     /* list */
528    int count;                         /* number of values seen */
529
530    db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
531    ~db_list_ctx() { free_pool_memory(list); list = NULL; }
532    void reset() { *list = 0; count = 0;}
533    void add(const db_list_ctx &str) {
534       if (str.count > 0) {
535          if (*list) {
536             pm_strcat(list, ",");
537          }
538          pm_strcat(list, str.list);
539          count += str.count;
540       }
541    }
542    void add(const char *str) {
543       if (count > 0) {
544          pm_strcat(list, ",");
545       }
546       pm_strcat(list, str);
547       count++;
548    }
549 private:
550    db_list_ctx(const db_list_ctx&);            /* prohibit pass by value */
551    db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
552 };
553
554 /* sql_query flags */
555 #define QF_STORE_RESULT 0x01
556  
557 /* sql_list.c */
558 enum e_list_type {
559    HORZ_LIST,                   /* list */
560    VERT_LIST,                   /* llist */
561    ARG_LIST,                    /* key1=v1 key2=v2 key3=v3 */
562    FAILED_JOBS,
563    INCOMPLETE_JOBS
564 };
565  
566 #include "bdb.h"
567 #include "protos.h"
568 #include "jcr.h"
569 #include "sql_cmds.h"
570
571
572 /* Object used in db_list_xxx function */
573 class LIST_CTX {
574 public:
575    char line[256];              /* Used to print last dash line */
576    int32_t num_rows;
577
578    e_list_type type;            /* Vertical/Horizontal */
579    DB_LIST_HANDLER *send;       /* send data back */
580    bool once;                   /* Used to print header one time */
581    void *ctx;                   /* send() user argument */
582    BDB *mdb;
583    JCR *jcr;
584
585    void empty() {
586       once = false;
587       line[0] = '\0';
588    }
589
590    void send_dashes() {
591       if (*line) {
592          send(ctx, line);
593       }
594    }
595
596    LIST_CTX(JCR *j, BDB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
597       line[0] = '\0';
598       once = false;
599       num_rows = 0;
600       type = t;
601       send = h;
602       ctx = c;
603       jcr = j;
604       mdb = m;
605    }
606 };
607
608 /* Functions exported by sql.c for use within the cats directory. */
609 int list_result(void *vctx, int cols, char **row);
610 int list_result(JCR *jcr, BDB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
611 int get_sql_record_max(JCR *jcr, BDB *mdb);
612 void list_dashes(BDB *mdb, DB_LIST_HANDLER *send, void *ctx);
613
614 void print_dashes(BDB *mdb);
615 void print_result(BDB *mdb);
616 int QueryDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
617 int InsertDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
618 int DeleteDB(const char *file, int line, JCR *jcr, BDB *db, char *delete_cmd);
619 void split_path_and_file(JCR *jcr, BDB *mdb, const char *fname);
620
621 #endif  /* __CATS_H_ */