2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
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.
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.
14 Bacula® is a registered trademark of Kern Sibbald.
18 * record-util.c -- Utilities for record handling
20 * Kern Sibbald, October MMXII
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.
34 const char *FI_to_ascii(char *buf, int fi)
37 sprintf(buf, "%d", fi);
61 sprintf(buf, _("unknown: %d"), fi);
67 * Convert a Stream ID into a printable
68 * ASCII string. Not reentrant.
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.
77 const char *stream_to_ascii(char *buf, int stream, int fi)
81 sprintf(buf, "%d", stream);
86 stream &= STREAMMASK_TYPE;
87 /* Stream was negative => all are continuation items */
89 case STREAM_UNIX_ATTRIBUTES:
91 case STREAM_FILE_DATA:
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:
101 case STREAM_SHA1_DIGEST:
103 case STREAM_GZIP_DATA:
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:
127 case STREAM_SHA512_DIGEST:
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";
151 sprintf(buf, "%d", -stream);
156 switch (stream & STREAMMASK_TYPE) {
157 case STREAM_UNIX_ATTRIBUTES:
159 case STREAM_FILE_DATA:
161 case STREAM_WIN32_DATA:
163 case STREAM_WIN32_GZIP_DATA:
165 case STREAM_WIN32_COMPRESSED_DATA:
166 return "WIN32-COMPRESSED";
167 case STREAM_MD5_DIGEST:
169 case STREAM_SHA1_DIGEST:
171 case STREAM_GZIP_DATA:
173 case STREAM_COMPRESSED_DATA:
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:
187 case STREAM_PROGRAM_DATA:
189 case STREAM_PLUGIN_NAME:
190 return "PLUGIN-NAME";
191 case STREAM_MACOS_FORK_DATA:
193 case STREAM_HFSPLUS_ATTRIBUTES:
194 return "HFSPLUS-ATTR";
195 case STREAM_SHA256_DIGEST:
197 case STREAM_SHA512_DIGEST:
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";
219 sprintf(buf, "%d", stream);
225 * Return a new record entity
227 DEV_RECORD *new_record(void)
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;
239 void empty_record(DEV_RECORD *rec)
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;
251 * Free the record entity
254 void free_record(DEV_RECORD *rec)
256 Dmsg0(950, "Enter free_record.\n");
258 free_pool_memory(rec->data);
260 Dmsg0(950, "Data buf is freed.\n");
261 free_pool_memory((POOLMEM *)rec);
262 Dmsg0(950, "Leave free_record.\n");
266 * Test if we can write whole record to the block
268 * Returns: false on failure
269 * true on success (all bytes can be written)
271 bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
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;
286 if (rec->remainder > 0 && remlen < rec->remainder) {
292 uint64_t get_record_address(DEV_RECORD *rec)
294 return ((uint64_t)rec->File)<<32 | rec->Block;