]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_find.c
Replace explicit checks for "/" with calls to IsPathSeparator, strchr with first_path...
[bacula/bacula] / bacula / src / cats / bdb_find.c
1 /*
2  * Bacula Catalog Database Find record interface routines
3  *
4  *  Note, generally, these routines are more complicated
5  *        that a simple search by name or id. Such simple
6  *        request are in get.c
7  *
8  * Bacula Catalog Database routines written specifically
9  *  for Bacula.  Note, these routines are VERY dumb and
10  *  do not provide all the functionality of an SQL database.
11  *  The purpose of these routines is to ensure that Bacula
12  *  can limp along if no real database is loaded on the
13  *  system.
14  *
15  *    Kern Sibbald, January MMI
16  *
17  *    Version $Id$
18  */
19
20 /*
21    Copyright (C) 2001-2006 Kern Sibbald
22
23    This program is free software; you can redistribute it and/or
24    modify it under the terms of the GNU General Public License
25    version 2 as amended with additional clauses defined in the
26    file LICENSE in the main source directory.
27
28    This program is distributed in the hope that it will be useful,
29    but WITHOUT ANY WARRANTY; without even the implied warranty of
30    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
31    the file LICENSE for additional details.
32
33  */
34
35 /* The following is necessary so that we do not include
36  * the dummy external definition of DB.
37  */
38 #define __SQL_C                       /* indicate that this is sql.c */
39
40 #include "bacula.h"
41 #include "cats.h"
42 #include "bdb.h"
43
44 #ifdef HAVE_BACULA_DB
45
46 /* Forward referenced functions */
47
48 /* -----------------------------------------------------------------------
49  *
50  *   Bacula specific defines and subroutines
51  *
52  * -----------------------------------------------------------------------
53  */
54
55
56 /*
57  * Find job start time. Used to find last full save that terminated normally
58  * so we can do Incremental and Differential saves.
59  *
60  * Returns: 0 on failure
61  *          1 on success, jr unchanged, but stime set
62  */
63 bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
64 {
65    char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
66    int Type, Level;
67    uint32_t JobId, EndId, ClientId;
68    char cType[10], cLevel[10], JobStatus[10];
69    bool found = false;
70    long addr;
71
72    db_lock(mdb);
73    pm_strcpy(stime, "0000-00-00 00:00:00");   /* default */
74    if (!bdb_open_jobs_file(mdb)) {
75       db_unlock(mdb);
76       return 0;
77    }
78    fseek(mdb->jobfd, 0L, SEEK_SET);   /* rewind file */
79    /* Linear search through JobStart records
80     */
81
82    while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
83       if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s "
84 "StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
85          if (JobId < jr->JobId) {
86             continue;                 /* older not a candidate */
87          }
88          Type = cType[0];
89          Level = cLevel[0];
90          unbash_spaces(Name);
91          unbash_spaces(StartTime);
92          Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
93             Type, Level, Name, StartTime);
94          Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->JobType, jr->JobLevel,
95             jr->Name);
96          /* Differential is since last Full backup */
97          /* Incremental is since last FULL or Incremental or Differential */
98          if (((jr->JobLevel == L_DIFFERENTIAL) && (Type == jr->JobType &&
99                Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
100              ((jr->JobLevel == L_INCREMENTAL) && (Type == jr->JobType &&
101                (Level == L_FULL || Level == L_INCREMENTAL ||
102                 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
103             addr = ftell(mdb->jobfd);    /* save current location */
104             JobStatus[0] = 0;
105             found = false;
106             /* Search for matching JobEnd record */
107             while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
108                if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
109                   &EndId, JobStatus, &ClientId) == 3) {
110                   if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
111                      Dmsg0(200, "====found EndJob matching Job\n");
112                      found = true;
113                      break;
114                   }
115                }
116             }
117             /* Reset for next read */
118             fseek(mdb->jobfd, addr, SEEK_SET);
119             if (found) {
120                pm_strcpy(stime, StartTime);
121                Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
122                   JobId, Type, Level, Name, StartTime);
123             }
124          }
125       }
126    }
127    db_unlock(mdb);
128    return found;
129 }
130
131
132 /*
133  * Find Available Media (Volume) for Pool
134  *
135  * Find a Volume for a given PoolId, MediaType, and VolStatus
136  *
137  *   Note! this does not correctly implement InChanger.
138  *
139  * Returns: 0 on failure
140  *          numrows on success
141  */
142 int
143 db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr)
144 {
145    MEDIA_DBR omr;
146    int stat = 0;
147    int index = 0;
148    int len;
149
150    db_lock(mdb);
151    if (!bdb_open_media_file(mdb)) {
152       db_unlock(mdb);
153       return 0;
154    }
155    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
156    len = sizeof(omr);
157    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
158       if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
159           strcmp(mr->MediaType, omr.MediaType) == 0) {
160          if (!(++index == item)) {    /* looking for item'th entry */
161             Dmsg0(200, "Media record matches, but not index\n");
162             continue;
163          }
164          Dmsg0(200, "Media record matches\n");
165          memcpy(mr, &omr, len);
166          Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
167          stat = 1;
168          break;                       /* found it */
169       }
170    }
171    db_unlock(mdb);
172    return stat;
173 }
174
175 bool
176 db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr)
177 { return false; }
178
179 bool
180 db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
181 { return false; }
182
183
184 #endif /* HAVE_BACULA_DB */