]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_find.c
First cut AutoPrune
[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, 2002 Kern Sibbald and John Walker
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 as
25    published by the Free Software Foundation; either version 2 of
26    the License, or (at your option) any later version.
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 GNU
31    General Public License for more details.
32
33    You should have received a copy of the GNU General Public
34    License along with this program; if not, write to the Free
35    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
36    MA 02111-1307, USA.
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_find_job_start_time(B_DB *mdb, JOB_DBR *jr, char *stime);
53
54 /* -----------------------------------------------------------------------
55  *
56  *   Bacula specific defines and subroutines
57  *
58  * -----------------------------------------------------------------------
59  */
60
61
62 /* 
63  * Find job start time. Used to find last full save that terminated normally
64  * so we can do Incremental and Differential saves.
65  *
66  * Returns: 0 on failure
67  *          1 on success, jr unchanged, but stime set
68  */
69 int db_find_job_start_time(B_DB *mdb, JOB_DBR *jr, char *stime)
70 {
71    char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
72    int Type, Level;
73    uint32_t JobId, EndId, ClientId;
74    char cType[10], cLevel[10], JobStatus[10];
75    int stat = 0;
76    int found;
77    long addr;
78
79    strcpy(stime, "0000-00-00 00:00:00");   /* default */
80    P(mdb->mutex);
81    if (!bdb_open_jobs_file(mdb)) {
82       V(mdb->mutex);
83       return 0;
84    }
85    fseek(mdb->jobfd, 0L, SEEK_SET);   /* rewind file */
86    /* Linear search through JobStart records
87     */
88
89    while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
90       if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s \
91 StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
92          if (JobId < jr->JobId) {
93             continue;                 /* older not a candidate */
94          }
95          Type = cType[0];
96          Level = cLevel[0];
97          unbash_spaces(Name);
98          unbash_spaces(StartTime);
99          Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
100             Type, Level, Name, StartTime);
101          Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->Type, jr->Level,     
102             jr->Name);
103          /* Differential is since last Full backup */
104          /* Incremental is since last FULL or Incremental or Differential */
105          if (((jr->Level == L_DIFFERENTIAL) && (Type == jr->Type && 
106                Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
107              ((jr->Level == L_INCREMENTAL) && (Type == jr->Type && 
108                (Level == L_FULL || Level == L_INCREMENTAL ||
109                 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
110             addr = ftell(mdb->jobfd);    /* save current location */
111             JobStatus[0] = 0;
112             found = 0;
113             /* Search for matching JobEnd record */
114             while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
115                if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
116                   &EndId, JobStatus, &ClientId) == 3) {
117                   if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
118                      Dmsg0(200, "====found EndJob matching Job\n");
119                      found = 1;
120                      break;
121                   }
122                }
123             }
124             /* Reset for next read */
125             fseek(mdb->jobfd, addr, SEEK_SET);
126             if (found) {
127                strcpy(stime, StartTime);
128                stat = 1;              /* Got a candidate */
129                Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
130                   JobId, Type, Level, Name, StartTime);
131             }
132          }
133       }
134    }
135    V(mdb->mutex);
136    return stat;
137 }
138
139
140 /* 
141  * Find Available Media (Volume) for Pool
142  *
143  * Find a Volume for a given PoolId, MediaType, and VolStatus
144  *
145  * Returns: 0 on failure
146  *          numrows on success
147  */
148 int db_find_next_volume(B_DB *mdb, int item, MEDIA_DBR *mr)
149 {
150    MEDIA_DBR omr;
151    int stat = 0;
152    int index = 0;
153    int len;
154
155    P(mdb->mutex);
156    if (!bdb_open_media_file(mdb)) {
157       V(mdb->mutex);
158       return 0;
159    }
160    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
161    len = sizeof(omr);
162    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
163       if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
164           strcmp(mr->MediaType, omr.MediaType) == 0) {
165          if (!(++index == item)) {    /* looking for item'th entry */
166             Dmsg0(200, "Media record matches, but not index\n");
167             continue;
168          }
169          Dmsg0(200, "Media record matches\n");
170          memcpy(mr, &omr, len);
171          Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
172          stat = 1;
173          break;                       /* found it */
174       }
175    }
176    V(mdb->mutex);
177    return stat;                 
178 }
179
180 int db_find_last_full_verify(B_DB *mdb, JOB_DBR *jr) { return 0; }
181
182
183 #endif /* HAVE_BACULA_DB */