]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb_find.c
Use rentrant mysql lib, eliminate race in sql_list, Win32 streams, misc see kes-1.31
[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-2003 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
53 /* -----------------------------------------------------------------------
54  *
55  *   Bacula specific defines and subroutines
56  *
57  * -----------------------------------------------------------------------
58  */
59
60
61 /* 
62  * Find job start time. Used to find last full save that terminated normally
63  * so we can do Incremental and Differential saves.
64  *
65  * Returns: 0 on failure
66  *          1 on success, jr unchanged, but stime set
67  */
68 int db_find_job_start_time(void *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
69 {
70    char cmd[MAXSTRING], Name[MAX_NAME_LENGTH], StartTime[MAXSTRING];
71    int Type, Level;
72    uint32_t JobId, EndId, ClientId;
73    char cType[10], cLevel[10], JobStatus[10];
74    int stat = 0;
75    int found;
76    long addr;
77
78    db_lock(mdb);
79    pm_strcpy(stime, "0000-00-00 00:00:00");   /* default */
80    if (!bdb_open_jobs_file(mdb)) {
81       db_unlock(mdb);
82       return 0;
83    }
84    fseek(mdb->jobfd, 0L, SEEK_SET);   /* rewind file */
85    /* Linear search through JobStart records
86     */
87
88    while (fgets(cmd, sizeof(cmd), mdb->jobfd)) {
89       if (sscanf(cmd, "JobStart JobId=%d Name=%127s Type=%1s Level=%1s \
90 StartTime=%100s", &JobId, Name, cType, cLevel, StartTime) == 5) {
91          if (JobId < jr->JobId) {
92             continue;                 /* older not a candidate */
93          }
94          Type = cType[0];
95          Level = cLevel[0];
96          unbash_spaces(Name);
97          unbash_spaces(StartTime);
98          Dmsg4(200, "Got Type=%c Level=%c Name=%s StartTime=%s\n",
99             Type, Level, Name, StartTime);
100          Dmsg3(200, "Want Type=%c Level=%c Name=%s\n", jr->Type, jr->Level,     
101             jr->Name);
102          /* Differential is since last Full backup */
103          /* Incremental is since last FULL or Incremental or Differential */
104          if (((jr->Level == L_DIFFERENTIAL) && (Type == jr->Type && 
105                Level == L_FULL && strcmp(Name, jr->Name) == 0)) ||
106              ((jr->Level == L_INCREMENTAL) && (Type == jr->Type && 
107                (Level == L_FULL || Level == L_INCREMENTAL ||
108                 Level == L_DIFFERENTIAL) && strcmp(Name, jr->Name) == 0))) {
109             addr = ftell(mdb->jobfd);    /* save current location */
110             JobStatus[0] = 0;
111             found = 0;
112             /* Search for matching JobEnd record */
113             while (!found && fgets(cmd, sizeof(cmd), mdb->jobfd)) {
114                if (sscanf(cmd, "JobEnd JobId=%d JobStatus=%1s ClientId=%d",
115                   &EndId, JobStatus, &ClientId) == 3) {
116                   if (EndId == JobId && *JobStatus == 'T' && ClientId == jr->ClientId) {
117                      Dmsg0(200, "====found EndJob matching Job\n");
118                      found = 1;
119                      break;
120                   }
121                }
122             }
123             /* Reset for next read */
124             fseek(mdb->jobfd, addr, SEEK_SET);
125             if (found) {
126                pm_strcpy(stime, StartTime);
127                stat = 1;              /* Got a candidate */
128                Dmsg5(200, "Got candidate JobId=%d Type=%c Level=%c Name=%s StartTime=%s\n",
129                   JobId, Type, Level, Name, StartTime);
130             }
131          }
132       }
133    }
134    db_unlock(mdb);
135    return stat;
136 }
137
138
139 /* 
140  * Find Available Media (Volume) for Pool
141  *
142  * Find a Volume for a given PoolId, MediaType, and VolStatus
143  *
144  * Returns: 0 on failure
145  *          numrows on success
146  */
147 int db_find_next_volume(void *jcr, B_DB *mdb, int item, MEDIA_DBR *mr)
148 {
149    MEDIA_DBR omr;
150    int stat = 0;
151    int index = 0;
152    int len;
153
154    db_lock(mdb);
155    if (!bdb_open_media_file(mdb)) {
156       db_unlock(mdb);
157       return 0;
158    }
159    fseek(mdb->mediafd, 0L, SEEK_SET);   /* rewind file */
160    len = sizeof(omr);
161    while (fread(&omr, len, 1, mdb->mediafd) > 0) {
162       if (mr->PoolId == omr.PoolId && strcmp(mr->VolStatus, omr.VolStatus) == 0 &&
163           strcmp(mr->MediaType, omr.MediaType) == 0) {
164          if (!(++index == item)) {    /* looking for item'th entry */
165             Dmsg0(200, "Media record matches, but not index\n");
166             continue;
167          }
168          Dmsg0(200, "Media record matches\n");
169          memcpy(mr, &omr, len);
170          Dmsg1(200, "Findnextvol MediaId=%d\n", mr->MediaId);
171          stat = 1;
172          break;                       /* found it */
173       }
174    }
175    db_unlock(mdb);
176    return stat;                 
177 }
178
179 int db_find_last_jobid(void *jcr, B_DB *mdb, JOB_DBR *jr) { return 0; }
180
181
182 #endif /* HAVE_BACULA_DB */