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