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