]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/verify_vol.c
Tweak debug
[bacula/bacula] / bacula / src / filed / verify_vol.c
1 /*
2  *  Bacula File Daemon  verify-vol.c Verify files on a Volume
3  *    versus attributes in Catalog
4  *
5  *    Kern Sibbald, July MMII
6  *
7  *   Version $Id$
8  *
9  */
10 /*
11    Bacula® - The Network Backup Solution
12
13    Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
14
15    The main author of Bacula is Kern Sibbald, with contributions from
16    many others, a complete list can be found in the file AUTHORS.
17    This program is Free Software; you can redistribute it and/or
18    modify it under the terms of version two of the GNU General Public
19    License as published by the Free Software Foundation and included
20    in the file LICENSE.
21
22    This program is distributed in the hope that it will be useful, but
23    WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25    General Public License for more details.
26
27    You should have received a copy of the GNU General Public License
28    along with this program; if not, write to the Free Software
29    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30    02110-1301, USA.
31
32    Bacula® is a registered trademark of Kern Sibbald.
33    The licensor of Bacula is the Free Software Foundation Europe
34    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
35    Switzerland, email:ftf@fsfeurope.org.
36 */
37
38 #include "bacula.h"
39 #include "filed.h"
40
41 /* Data received from Storage Daemon */
42 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
43
44 /* Forward referenced functions */
45
46
47 /*
48  * Verify attributes of the requested files on the Volume
49  *
50  */
51 void do_verify_volume(JCR *jcr)
52 {
53    BSOCK *sd, *dir;
54    POOLMEM *fname;                    /* original file name */
55    POOLMEM *lname;                    /* link name */
56    int32_t stream;
57    uint32_t size;
58    uint32_t VolSessionId, VolSessionTime, file_index;
59    uint32_t record_file_index;
60    char digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
61    int type, stat;
62
63    sd = jcr->store_bsock;
64    if (!sd) {
65       Jmsg(jcr, M_FATAL, 0, _("Storage command not issued before Verify.\n"));
66       set_jcr_job_status(jcr, JS_FatalError);
67       return;
68    }
69    dir = jcr->dir_bsock;
70    set_jcr_job_status(jcr, JS_Running);
71
72    LockRes();
73    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
74    UnlockRes();
75    uint32_t buf_size;
76    if (client) {
77       buf_size = client->max_network_buffer_size;
78    } else {
79       buf_size = 0;                   /* use default */
80    }
81    if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
82       set_jcr_job_status(jcr, JS_FatalError);
83       return;
84    }
85    jcr->buf_size = sd->msglen;
86
87    fname = get_pool_memory(PM_FNAME);
88    lname = get_pool_memory(PM_FNAME);
89
90    /*
91     * Get a record from the Storage daemon
92     */
93    while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
94       /*
95        * First we expect a Stream Record Header
96        */
97       if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
98           &stream, &size) != 5) {
99          Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
100          goto bail_out;
101       }
102       Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
103
104       /*
105        * Now we expect the Stream Data
106        */
107       if (bget_msg(sd) < 0) {
108          Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
109          goto bail_out;
110       }
111       if (size != ((uint32_t)sd->msglen)) {
112          Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
113          goto bail_out;
114       }
115       Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
116
117       /* File Attributes stream */
118       switch (stream) {
119       case STREAM_UNIX_ATTRIBUTES:
120       case STREAM_UNIX_ATTRIBUTES_EX:
121          char *ap, *lp, *fp;
122
123          Dmsg0(400, "Stream=Unix Attributes.\n");
124
125          if ((int)sizeof_pool_memory(fname) < sd->msglen) {
126             fname = realloc_pool_memory(fname, sd->msglen + 1);
127          }
128
129          if ((int)sizeof_pool_memory(lname) < sd->msglen) {
130             lname = realloc_pool_memory(lname, sd->msglen + 1);
131          }
132          *fname = 0;
133          *lname = 0;
134
135          /*
136           * An Attributes record consists of:
137           *    File_index
138           *    Type   (FT_types)
139           *    Filename
140           *    Attributes
141           *    Link name (if file linked i.e. FT_LNK)
142           *    Extended Attributes (if Win32)
143           */
144          if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
145             Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg);
146             Dmsg0(0, "\nError scanning header\n");
147             goto bail_out;
148          }
149          Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
150          if (record_file_index != file_index) {
151             Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
152                file_index, record_file_index);
153             Dmsg0(0, "File index error\n");
154             goto bail_out;
155          }
156          ap = sd->msg;
157          while (*ap++ != ' ')         /* skip record file index */
158             ;
159          while (*ap++ != ' ')         /* skip type */
160             ;
161          /* Save filename and position to attributes */
162          fp = fname;
163          while (*ap != 0) {
164             *fp++  = *ap++;           /* copy filename to fname */
165          }
166          *fp = *ap++;                 /* terminate filename & point to attribs */
167
168          Dmsg1(200, "Attr=%s\n", ap);
169          /* Skip to Link name */
170          if (type == FT_LNK || type == FT_LNKSAVED) {
171             lp = ap;
172             while (*lp++ != 0) {
173                ;
174             }
175             pm_strcat(lname, lp);        /* "save" link name */
176          } else {
177             *lname = 0;
178          }
179          jcr->lock();
180          jcr->JobFiles++;
181          jcr->num_files_examined++;
182          pm_strcpy(jcr->last_fname, fname); /* last file examined */
183          jcr->unlock();
184
185          /*
186           * Send file attributes to Director
187           *   File_index
188           *   Stream
189           *   Verify Options
190           *   Filename (full path)
191           *   Encoded attributes
192           *   Link name (if type==FT_LNK)
193           * For a directory, link is the same as fname, but with trailing
194           * slash. For a linked file, link is the link.
195           */
196          /* Send file attributes to Director */
197          Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname);
198          if (type == FT_LNK || type == FT_LNKSAVED) {
199             stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
200                           STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
201                           0, ap, 0, lname, 0);
202          } else {
203             stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
204                           STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
205                           0, ap, 0, 0);
206          }
207          Dmsg2(200, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
208          if (!stat) {
209             Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
210             goto bail_out;
211          }
212          break;
213
214       case STREAM_MD5_DIGEST:
215          bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_MD5_SIZE, true);
216          Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, digest);
217          bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_DIGEST, digest,
218                     jcr->JobFiles);
219          Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
220          break;
221
222       case STREAM_SHA1_DIGEST:
223          bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA1_SIZE, true);
224          Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, digest);
225          bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_DIGEST,
226                     digest, jcr->JobFiles);
227          Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
228          break;
229
230       case STREAM_SHA256_DIGEST:
231          bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA256_SIZE, true);
232          Dmsg2(400, "send inx=%d SHA256=%s\n", jcr->JobFiles, digest);
233          bnet_fsend(dir, "%d %d %s *SHA256-%d*", jcr->JobFiles, STREAM_SHA256_DIGEST,
234                     digest, jcr->JobFiles);
235          Dmsg2(20, "bfiled>bdird: SHA256 len=%d: msg=%s\n", dir->msglen, dir->msg);
236          break;
237
238       case STREAM_SHA512_DIGEST:
239          bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA512_SIZE, true);
240          Dmsg2(400, "send inx=%d SHA512=%s\n", jcr->JobFiles, digest);
241          bnet_fsend(dir, "%d %d %s *SHA512-%d*", jcr->JobFiles, STREAM_SHA512_DIGEST,
242                     digest, jcr->JobFiles);
243          Dmsg2(20, "bfiled>bdird: SHA512 len=%d: msg=%s\n", dir->msglen, dir->msg);
244          break;
245
246       /* Ignore everything else */
247       default:
248          break;
249
250       } /* end switch */
251    } /* end while bnet_get */
252    set_jcr_job_status(jcr, JS_Terminated);
253    goto ok_out;
254
255 bail_out:
256    set_jcr_job_status(jcr, JS_ErrorTerminated);
257
258 ok_out:
259    if (jcr->compress_buf) {
260       free(jcr->compress_buf);
261       jcr->compress_buf = NULL;
262    }
263    free_pool_memory(fname);
264    free_pool_memory(lname);
265    Dmsg2(050, "End Verify-Vol. Files=%d Bytes=%" lld "\n", jcr->JobFiles,
266       jcr->JobBytes);
267 }