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