]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/record_util.c
Backport from BEE
[bacula/bacula] / bacula / src / stored / record_util.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *
18  *   record-util.c -- Utilities for record handling
19  *
20  *            Kern Sibbald, October MMXII
21  *
22  */
23
24 #include "bacula.h"
25 #include "stored.h"
26
27 /*
28  * Convert a FileIndex into a printable
29  *   ASCII string.  Not reentrant.
30  * If the FileIndex is negative, it flags the
31  *   record as a Label, otherwise it is simply
32  *   the FileIndex of the current file.
33  */
34 const char *FI_to_ascii(char *buf, int fi)
35 {
36    if (fi >= 0) {
37       sprintf(buf, "%d", fi);
38       return buf;
39    }
40    switch (fi) {
41    case PRE_LABEL:
42       return "PRE_LABEL";
43    case VOL_LABEL:
44       return "VOL_LABEL";
45    case EOM_LABEL:
46       return "EOM_LABEL";
47    case SOS_LABEL:
48       return "SOS_LABEL";
49    case EOS_LABEL:
50       return "EOS_LABEL";
51    case EOT_LABEL:
52       return "EOT_LABEL";
53       break;
54    case SOB_LABEL:
55       return "SOB_LABEL";
56       break;
57    case EOB_LABEL:
58       return "EOB_LABEL";
59       break;
60    default:
61      sprintf(buf, _("unknown: %d"), fi);
62      return buf;
63    }
64 }
65
66 /*
67  * Convert a Stream ID into a printable
68  * ASCII string.  Not reentrant.
69
70  * A negative stream number represents
71  *   stream data that is continued from a
72  *   record in the previous block.
73  * If the FileIndex is negative, we are
74  *   dealing with a Label, hence the
75  *   stream is the JobId.
76  */
77 const char *stream_to_ascii(char *buf, int stream, int fi)
78 {
79
80    if (fi < 0) {
81       sprintf(buf, "%d", stream);
82       return buf;
83    }
84    if (stream < 0) {
85       stream = -stream;
86       stream &= STREAMMASK_TYPE;
87       /* Stream was negative => all are continuation items */
88       switch (stream) {
89       case STREAM_UNIX_ATTRIBUTES:
90          return "contUATTR";
91       case STREAM_FILE_DATA:
92          return "contDATA";
93       case STREAM_WIN32_DATA:
94          return "contWIN32-DATA";
95       case STREAM_WIN32_GZIP_DATA:
96          return "contWIN32-GZIP";
97       case STREAM_WIN32_COMPRESSED_DATA:
98          return "contWIN32-COMPRESSED";
99       case STREAM_MD5_DIGEST:
100          return "contMD5";
101       case STREAM_SHA1_DIGEST:
102          return "contSHA1";
103       case STREAM_GZIP_DATA:
104          return "contGZIP";
105       case STREAM_COMPRESSED_DATA:
106          return "contCOMPRESSED";
107       case STREAM_UNIX_ATTRIBUTES_EX:
108          return "contUNIX-ATTR-EX";
109       case STREAM_RESTORE_OBJECT:
110          return "contRESTORE-OBJECT";
111       case STREAM_SPARSE_DATA:
112          return "contSPARSE-DATA";
113       case STREAM_SPARSE_GZIP_DATA:
114          return "contSPARSE-GZIP";
115       case STREAM_SPARSE_COMPRESSED_DATA:
116          return "contSPARSE-COMPRESSED";
117       case STREAM_PROGRAM_NAMES:
118          return "contPROG-NAMES";
119       case STREAM_PROGRAM_DATA:
120          return "contPROG-DATA";
121       case STREAM_MACOS_FORK_DATA:
122          return "contMACOS-RSRC";
123       case STREAM_HFSPLUS_ATTRIBUTES:
124          return "contHFSPLUS-ATTR";
125       case STREAM_SHA256_DIGEST:
126          return "contSHA256";
127       case STREAM_SHA512_DIGEST:
128          return "contSHA512";
129       case STREAM_SIGNED_DIGEST:
130          return "contSIGNED-DIGEST";
131       case STREAM_ENCRYPTED_SESSION_DATA:
132          return "contENCRYPTED-SESSION-DATA";
133       case STREAM_ENCRYPTED_FILE_DATA:
134          return "contENCRYPTED-FILE";
135       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
136          return "contENCRYPTED-GZIP";
137       case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
138          return "contENCRYPTED-COMPRESSED";
139       case STREAM_ENCRYPTED_WIN32_DATA:
140          return "contENCRYPTED-WIN32-DATA";
141       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
142          return "contENCRYPTED-WIN32-GZIP";
143       case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
144          return "contENCRYPTED-WIN32-COMPRESSED";
145       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
146          return "contENCRYPTED-MACOS-RSRC";
147       case STREAM_PLUGIN_NAME:
148          return "contPLUGIN-NAME";
149
150       default:
151          sprintf(buf, "%d", -stream);
152          return buf;
153       }
154    }
155
156    switch (stream & STREAMMASK_TYPE) {
157    case STREAM_UNIX_ATTRIBUTES:
158       return "UATTR";
159    case STREAM_FILE_DATA:
160       return "DATA";
161    case STREAM_WIN32_DATA:
162       return "WIN32-DATA";
163    case STREAM_WIN32_GZIP_DATA:
164       return "WIN32-GZIP";
165    case STREAM_WIN32_COMPRESSED_DATA:
166       return "WIN32-COMPRESSED";
167    case STREAM_MD5_DIGEST:
168       return "MD5";
169    case STREAM_SHA1_DIGEST:
170       return "SHA1";
171    case STREAM_GZIP_DATA:
172       return "GZIP";
173    case STREAM_COMPRESSED_DATA:
174       return "COMPRESSED";
175    case STREAM_UNIX_ATTRIBUTES_EX:
176       return "UNIX-ATTR-EX";
177    case STREAM_RESTORE_OBJECT:
178       return "RESTORE-OBJECT";
179    case STREAM_SPARSE_DATA:
180       return "SPARSE-DATA";
181    case STREAM_SPARSE_GZIP_DATA:
182       return "SPARSE-GZIP";
183    case STREAM_SPARSE_COMPRESSED_DATA:
184       return "SPARSE-COMPRESSED";
185    case STREAM_PROGRAM_NAMES:
186       return "PROG-NAMES";
187    case STREAM_PROGRAM_DATA:
188       return "PROG-DATA";
189    case STREAM_PLUGIN_NAME:
190       return "PLUGIN-NAME";
191    case STREAM_MACOS_FORK_DATA:
192       return "MACOS-RSRC";
193    case STREAM_HFSPLUS_ATTRIBUTES:
194       return "HFSPLUS-ATTR";
195    case STREAM_SHA256_DIGEST:
196       return "SHA256";
197    case STREAM_SHA512_DIGEST:
198       return "SHA512";
199    case STREAM_SIGNED_DIGEST:
200       return "SIGNED-DIGEST";
201    case STREAM_ENCRYPTED_SESSION_DATA:
202       return "ENCRYPTED-SESSION-DATA";
203    case STREAM_ENCRYPTED_FILE_DATA:
204       return "ENCRYPTED-FILE";
205    case STREAM_ENCRYPTED_FILE_GZIP_DATA:
206       return "ENCRYPTED-GZIP";
207    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
208       return "ENCRYPTED-COMPRESSED";
209    case STREAM_ENCRYPTED_WIN32_DATA:
210       return "ENCRYPTED-WIN32-DATA";
211    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
212       return "ENCRYPTED-WIN32-GZIP";
213    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
214       return "ENCRYPTED-WIN32-COMPRESSED";
215    case STREAM_ENCRYPTED_MACOS_FORK_DATA:
216       return "ENCRYPTED-MACOS-RSRC";
217
218    default:
219       sprintf(buf, "%d", stream);
220       return buf;
221    }
222 }
223
224 /*
225  * Return a new record entity
226  */
227 DEV_RECORD *new_record(void)
228 {
229    DEV_RECORD *rec;
230
231    rec = (DEV_RECORD *)get_memory(sizeof(DEV_RECORD));
232    memset(rec, 0, sizeof(DEV_RECORD));
233    rec->data = get_pool_memory(PM_MESSAGE);
234    rec->wstate = st_none;
235    rec->rstate = st_none;
236    return rec;
237 }
238
239 void empty_record(DEV_RECORD *rec)
240 {
241    rec->File = rec->Block = 0;
242    rec->VolSessionId = rec->VolSessionTime = 0;
243    rec->FileIndex = rec->Stream = 0;
244    rec->data_len = rec->remainder = 0;
245    rec->state_bits &= ~(REC_PARTIAL_RECORD|REC_BLOCK_EMPTY|REC_NO_MATCH|REC_CONTINUATION);
246    rec->wstate = st_none;
247    rec->rstate = st_none;
248 }
249
250 /*
251  * Free the record entity
252  *
253  */
254 void free_record(DEV_RECORD *rec)
255 {
256    Dmsg0(950, "Enter free_record.\n");
257    if (rec->data) {
258       free_pool_memory(rec->data);
259    }
260    Dmsg0(950, "Data buf is freed.\n");
261    free_pool_memory((POOLMEM *)rec);
262    Dmsg0(950, "Leave free_record.\n");
263 }
264
265 /*
266  * Test if we can write whole record to the block
267  *
268  *  Returns: false on failure
269  *           true  on success (all bytes can be written)
270  */
271 bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
272 {
273    uint32_t remlen;
274
275    remlen = block->buf_len - block->binbuf;
276    if (rec->remainder == 0) {
277       if (remlen >= WRITE_RECHDR_LENGTH) {
278          remlen -= WRITE_RECHDR_LENGTH;
279          rec->remainder = rec->data_len;
280       } else {
281          return false;
282       }
283    } else {
284       return false;
285    }
286    if (rec->remainder > 0 && remlen < rec->remainder) {
287       return false;
288    }
289    return true;
290 }
291
292 uint64_t get_record_address(DEV_RECORD *rec)
293 {
294    return ((uint64_t)rec->File)<<32 | rec->Block;
295 }