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