]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_find.c
kes Cancel storage daemon in all cases where FD reports error. This
[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    Bacula® - The Network Backup Solution
21
22    Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
23
24    The main author of Bacula is Kern Sibbald, with contributions from
25    many others, a complete list can be found in the file AUTHORS.
26    This program is Free Software; you can redistribute it and/or
27    modify it under the terms of version two of the GNU General Public
28    License as published by the Free Software Foundation and included
29    in the file LICENSE.
30
31    This program is distributed in the hope that it will be useful, but
32    WITHOUT ANY WARRANTY; without even the implied warranty of
33    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34    General Public License for more details.
35
36    You should have received a copy of the GNU General Public License
37    along with this program; if not, write to the Free Software
38    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
39    02110-1301, USA.
40
41    Bacula® is a registered trademark of John Walker.
42    The licensor of Bacula is the Free Software Foundation Europe
43    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
44    Switzerland, email:ftf@fsfeurope.org.
45 */
46
47 /* The following is necessary so that we do not include
48  * the dummy external definition of DB.
49  */
50 #define __SQL_C                       /* indicate that this is sql.c */
51
52 #include "bacula.h"
53 #include "cats.h"
54 #include "bdb.h"
55
56 #ifdef HAVE_BACULA_DB
57
58 /* Forward referenced functions */
59
60 /* -----------------------------------------------------------------------
61  *
62  *   Bacula specific defines and subroutines
63  *
64  * -----------------------------------------------------------------------
65  */
66
67
68 /*
69  * Find job start time. Used to find last full save that terminated normally
70  * so we can do Incremental and Differential saves.
71  *
72  * Returns: 0 on failure
73  *          1 on success, jr unchanged, but stime set
74  */
75 bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
76 {
77    char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
78    int Type, Level;
79    uint32_t JobId, EndId, ClientId;
80    char cType[10], cLevel[10], JobStatus[10];
81    bool found = false;
82    long addr;
83
84    db_lock(mdb);
85    pm_strcpy(stime, "0000-00-00 00:00:00");   /* default */
86    if (!bdb_open_jobs_file(mdb)) {
87       db_unlock(mdb);
88       return 0;
89    }
90    fseek(mdb->jobfd, 0L, SEEK_SET);   /* rewind file */
91    /* Linear search through JobStart records
92     */
93
94    while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
95       if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s "
96 "StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
97          if (JobId < jr->JobId) {
98             continue;                 /* older not a candidate */
99          }
100          Type = cType[0];
101          Level = cLevel[0];
102          unbash_spaces(Name);
103          unbash_spaces(StartTime);
104          Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
105             Type, Level, Name, StartTime);
106          Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->JobType, jr->JobLevel,
107             jr->Name);
108          /* Differential is since last Full backup */
109          /* Incremental is since last FULL or Incremental or Differential */
110          if (((jr->JobLevel == L_DIFFERENTIAL) && (Type == jr->JobType &&
111                Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
112              ((jr->JobLevel == L_INCREMENTAL) && (Type == jr->JobType &&
113                (Level == L_FULL || Level == L_INCREMENTAL ||
114                 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
115             addr = ftell(mdb->jobfd);    /* save current location */
116             JobStatus[0] = 0;
117             found = false;
118             /* Search for matching JobEnd record */
119             while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
120                if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
121                   &EndId, JobStatus, &ClientId) == 3) {
122                   if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
123                      Dmsg0(200, "====found EndJob matching Job\n");
124                      found = true;
125                      break;
126                   }
127                }
128             }
129             /* Reset for next read */
130             fseek(mdb->jobfd, addr, SEEK_SET);
131             if (found) {
132                pm_strcpy(stime, StartTime);
133                Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
134                   JobId, Type, Level, Name, StartTime);
135             }
136          }
137       }
138    }
139    db_unlock(mdb);
140    return found;
141 }
142
143
144 /*
145  * Find Available Media (Volume) for Pool
146  *
147  * Find a Volume for a given PoolId, MediaType, and VolStatus
148  *
149  *   Note! this does not correctly implement InChanger.
150  *
151  * Returns: 0 on failure
152  *          numrows on success
153  */
154 int
155 db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr)
156 {
157    MEDIA_DBR omr;
158    int stat = 0;
159    int index = 0;
160    int len;
161
162    db_lock(mdb);
163    if (!bdb_open_media_file(mdb)) {
164       db_unlock(mdb);
165       return 0;
166    }
167    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
168    len = sizeof(omr);
169    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
170       if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
171           strcmp(mr->MediaType, omr.MediaType) == 0) {
172          if (!(++index == item)) {    /* looking for item'th entry */
173             Dmsg0(200, "Media record matches, but not index\n");
174             continue;
175          }
176          Dmsg0(200, "Media record matches\n");
177          memcpy(mr, &omr, len);
178          Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
179          stat = 1;
180          break;                       /* found it */
181       }
182    }
183    db_unlock(mdb);
184    return stat;
185 }
186
187 bool
188 db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr)
189 { return false; }
190
191 bool
192 db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
193 { return false; }
194
195
196 #endif /* HAVE_BACULA_DB */