2 Bacula® - The Network Backup Solution
4 Copyright (C) 2003-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.
17 * Bacula low level File I/O routines. This routine simulates
18 * open(), read(), write(), and close(), but using native routines.
19 * I.e. on Windows, we use Windows APIs.
21 * Kern Sibbald, April MMIII
28 const int dbglvl = 200;
30 int (*plugin_bopen)(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode) = NULL;
31 int (*plugin_bclose)(BFILE *bfd) = NULL;
32 ssize_t (*plugin_bread)(BFILE *bfd, void *buf, size_t count) = NULL;
33 ssize_t (*plugin_bwrite)(BFILE *bfd, void *buf, size_t count) = NULL;
34 boffset_t (*plugin_blseek)(BFILE *bfd, boffset_t offset, int whence) = NULL;
38 #include <sys/paths.h>
41 #if !defined(HAVE_FDATASYNC)
46 void pause_msg(const char *file, const char *func, int line, const char *msg)
50 bsnprintf(buf, sizeof(buf), "%s:%s:%d %s", file, func, line, msg);
52 bsnprintf(buf, sizeof(buf), "%s:%s:%d", file, func, line);
54 MessageBox(NULL, buf, "Pause", MB_OK);
58 /* ===============================================================
60 * U N I X AND W I N D O W S
62 * ===============================================================
65 bool is_win32_stream(int stream)
68 case STREAM_WIN32_DATA:
69 case STREAM_WIN32_GZIP_DATA:
70 case STREAM_WIN32_COMPRESSED_DATA:
71 case STREAM_ENCRYPTED_WIN32_DATA:
72 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
73 case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
79 const char *stream_to_ascii(int stream)
83 switch (stream & STREAMMASK_TYPE) {
84 case STREAM_UNIX_ATTRIBUTES:
85 return _("Unix attributes");
86 case STREAM_FILE_DATA:
87 return _("File data");
88 case STREAM_MD5_DIGEST:
89 return _("MD5 digest");
90 case STREAM_GZIP_DATA:
91 return _("GZIP data");
92 case STREAM_COMPRESSED_DATA:
93 return _("Compressed data");
94 case STREAM_UNIX_ATTRIBUTES_EX:
95 return _("Extended attributes");
96 case STREAM_SPARSE_DATA:
97 return _("Sparse data");
98 case STREAM_SPARSE_GZIP_DATA:
99 return _("GZIP sparse data");
100 case STREAM_SPARSE_COMPRESSED_DATA:
101 return _("Compressed sparse data");
102 case STREAM_PROGRAM_NAMES:
103 return _("Program names");
104 case STREAM_PROGRAM_DATA:
105 return _("Program data");
106 case STREAM_SHA1_DIGEST:
107 return _("SHA1 digest");
108 case STREAM_WIN32_DATA:
109 return _("Win32 data");
110 case STREAM_WIN32_GZIP_DATA:
111 return _("Win32 GZIP data");
112 case STREAM_WIN32_COMPRESSED_DATA:
113 return _("Win32 compressed data");
114 case STREAM_MACOS_FORK_DATA:
115 return _("MacOS Fork data");
116 case STREAM_HFSPLUS_ATTRIBUTES:
117 return _("HFS+ attribs");
118 case STREAM_UNIX_ACCESS_ACL:
119 return _("Standard Unix ACL attribs");
120 case STREAM_UNIX_DEFAULT_ACL:
121 return _("Default Unix ACL attribs");
122 case STREAM_SHA256_DIGEST:
123 return _("SHA256 digest");
124 case STREAM_SHA512_DIGEST:
125 return _("SHA512 digest");
126 case STREAM_SIGNED_DIGEST:
127 return _("Signed digest");
128 case STREAM_ENCRYPTED_FILE_DATA:
129 return _("Encrypted File data");
130 case STREAM_ENCRYPTED_WIN32_DATA:
131 return _("Encrypted Win32 data");
132 case STREAM_ENCRYPTED_SESSION_DATA:
133 return _("Encrypted session data");
134 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
135 return _("Encrypted GZIP data");
136 case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
137 return _("Encrypted compressed data");
138 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
139 return _("Encrypted Win32 GZIP data");
140 case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
141 return _("Encrypted Win32 Compressed data");
142 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
143 return _("Encrypted MacOS fork data");
144 case STREAM_PLUGIN_NAME:
145 return _("Plugin Name");
146 case STREAM_PLUGIN_DATA:
147 return _("Plugin Data");
148 case STREAM_RESTORE_OBJECT:
149 return _("Restore Object");
150 case STREAM_ACL_AIX_TEXT:
151 return _("AIX Specific ACL attribs");
152 case STREAM_ACL_DARWIN_ACCESS_ACL:
153 return _("Darwin Specific ACL attribs");
154 case STREAM_ACL_FREEBSD_DEFAULT_ACL:
155 return _("FreeBSD Specific Default ACL attribs");
156 case STREAM_ACL_FREEBSD_ACCESS_ACL:
157 return _("FreeBSD Specific Access ACL attribs");
158 case STREAM_ACL_HPUX_ACL_ENTRY:
159 return _("HPUX Specific ACL attribs");
160 case STREAM_ACL_IRIX_DEFAULT_ACL:
161 return _("Irix Specific Default ACL attribs");
162 case STREAM_ACL_IRIX_ACCESS_ACL:
163 return _("Irix Specific Access ACL attribs");
164 case STREAM_ACL_LINUX_DEFAULT_ACL:
165 return _("Linux Specific Default ACL attribs");
166 case STREAM_ACL_LINUX_ACCESS_ACL:
167 return _("Linux Specific Access ACL attribs");
168 case STREAM_ACL_TRU64_DEFAULT_ACL:
169 return _("TRU64 Specific Default ACL attribs");
170 case STREAM_ACL_TRU64_ACCESS_ACL:
171 return _("TRU64 Specific Access ACL attribs");
172 case STREAM_ACL_SOLARIS_ACLENT:
173 return _("Solaris Specific POSIX ACL attribs");
174 case STREAM_ACL_SOLARIS_ACE:
175 return _("Solaris Specific NFSv4/ZFS ACL attribs");
176 case STREAM_ACL_AFS_TEXT:
177 return _("AFS Specific ACL attribs");
178 case STREAM_ACL_AIX_AIXC:
179 return _("AIX Specific POSIX ACL attribs");
180 case STREAM_ACL_AIX_NFS4:
181 return _("AIX Specific NFSv4 ACL attribs");
182 case STREAM_ACL_FREEBSD_NFS4_ACL:
183 return _("FreeBSD Specific NFSv4/ZFS ACL attribs");
184 case STREAM_ACL_HURD_DEFAULT_ACL:
185 return _("GNU Hurd Specific Default ACL attribs");
186 case STREAM_ACL_HURD_ACCESS_ACL:
187 return _("GNU Hurd Specific Access ACL attribs");
188 case STREAM_XATTR_HURD:
189 return _("GNU Hurd Specific Extended attribs");
190 case STREAM_XATTR_IRIX:
191 return _("IRIX Specific Extended attribs");
192 case STREAM_XATTR_TRU64:
193 return _("TRU64 Specific Extended attribs");
194 case STREAM_XATTR_AIX:
195 return _("AIX Specific Extended attribs");
196 case STREAM_XATTR_OPENBSD:
197 return _("OpenBSD Specific Extended attribs");
198 case STREAM_XATTR_SOLARIS_SYS:
199 return _("Solaris Specific Extensible attribs or System Extended attribs");
200 case STREAM_XATTR_SOLARIS:
201 return _("Solaris Specific Extended attribs");
202 case STREAM_XATTR_DARWIN:
203 return _("Darwin Specific Extended attribs");
204 case STREAM_XATTR_FREEBSD:
205 return _("FreeBSD Specific Extended attribs");
206 case STREAM_XATTR_LINUX:
207 return _("Linux Specific Extended attribs");
208 case STREAM_XATTR_NETBSD:
209 return _("NetBSD Specific Extended attribs");
211 sprintf(buf, "%d", stream);
212 return (const char *)buf;
217 * Convert a 64 bit little endian to a big endian
219 void int64_LE2BE(int64_t* pBE, const int64_t v)
221 /* convert little endian to big endian */
222 if (htonl(1) != 1L) { /* no work if on little endian machine */
223 memcpy(pBE, &v, sizeof(int64_t));
226 uint8_t rv[sizeof(int64_t)];
227 uint8_t *pv = (uint8_t *) &v;
229 for (i = 0; i < 8; i++) {
232 memcpy(pBE, &rv, sizeof(int64_t));
237 * Convert a 32 bit little endian to a big endian
239 void int32_LE2BE(int32_t* pBE, const int32_t v)
241 /* convert little endian to big endian */
242 if (htonl(1) != 1L) { /* no work if on little endian machine */
243 memcpy(pBE, &v, sizeof(int32_t));
246 uint8_t rv[sizeof(int32_t)];
247 uint8_t *pv = (uint8_t *) &v;
249 for (i = 0; i < 4; i++) {
252 memcpy(pBE, &rv, sizeof(int32_t));
258 * Read a BackupRead block and pull out the file data
260 bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize)
262 /* pByte contains the buffer
263 dwSize the len to be processed. function assumes to be
264 called in successive incremental order over the complete
265 BackupRead stream beginning at pos 0 and ending at the end.
268 PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT* pContext = &(bfd->win32DecompContext);
269 bool bContinue = false;
270 int64_t dwDataOffset = 0;
273 /* Win32 Stream Header size without name of stream.
274 * = sizeof (WIN32_STREAM_ID)- sizeof(WCHAR*);
276 int32_t dwSizeHeader = 20;
279 if (pContext->liNextHeader >= dwSize) {
280 dwDataLen = dwSize-dwDataOffset;
281 bContinue = false; /* 1 iteration is enough */
283 dwDataLen = pContext->liNextHeader-dwDataOffset;
284 bContinue = true; /* multiple iterations may be necessary */
288 /* copy block of real DATA */
289 if (pContext->bIsInData) {
290 if (bwrite(bfd, ((char *)pBuffer)+dwDataOffset, dwDataLen) != (ssize_t)dwDataLen)
294 if (pContext->liNextHeader < dwSize) {/* is a header in this block ? */
295 int32_t dwOffsetTarget;
296 int32_t dwOffsetSource;
298 if (pContext->liNextHeader < 0) {
299 /* start of header was before this block, so we
300 * continue with the part in the current block
302 dwOffsetTarget = -pContext->liNextHeader;
305 /* start of header is inside of this block */
307 dwOffsetSource = pContext->liNextHeader;
310 int32_t dwHeaderPartLen = dwSizeHeader-dwOffsetTarget;
311 bool bHeaderIsComplete;
313 if (dwHeaderPartLen <= dwSize-dwOffsetSource) {
314 /* header (or rest of header) is completely available
317 bHeaderIsComplete = true;
319 /* header will continue in next block */
320 bHeaderIsComplete = false;
321 dwHeaderPartLen = dwSize-dwOffsetSource;
324 /* copy the available portion of header to persistent copy */
325 memcpy(((char *)&pContext->header_stream)+dwOffsetTarget, ((char *)pBuffer)+dwOffsetSource, dwHeaderPartLen);
327 /* recalculate position of next header */
328 if (bHeaderIsComplete) {
329 /* convert stream name size (32 bit little endian) to machine type */
331 int32_LE2BE (&dwNameSize, pContext->header_stream.dwStreamNameSize);
332 dwDataOffset = dwNameSize+pContext->liNextHeader+dwSizeHeader;
334 /* convert stream size (64 bit little endian) to machine type */
335 int64_LE2BE (&(pContext->liNextHeader), pContext->header_stream.Size);
336 pContext->liNextHeader += dwDataOffset;
338 pContext->bIsInData = pContext->header_stream.dwStreamId == WIN32_BACKUP_DATA;
339 if (dwDataOffset == dwSize)
342 /* stop and continue with next block */
344 pContext->bIsInData = false;
349 /* set "NextHeader" relative to the beginning of the next block */
350 pContext->liNextHeader-= dwSize;
358 /* ===============================================================
362 * ===============================================================
365 void binit(BFILE *bfd)
367 memset(bfd, 0, sizeof(BFILE));
372 bool have_win32_api()
374 return false; /* no can do */
378 * Enables using the Backup API (win32_data).
379 * Returns true if function worked
380 * Returns false if failed (i.e. do not have Backup API on this machine)
383 bool set_win32_backup(BFILE *bfd)
385 return false; /* no can do */
390 bool set_portable_backup(BFILE *bfd)
392 return true; /* no problem */
396 * Return true if we are writing in portable format
397 * return false if not
400 bool is_portable_backup(BFILE *bfd)
402 return true; /* portable by definition */
406 bool set_prog(BFILE *bfd, char *prog, JCR *jcr)
412 bool set_cmd_plugin(BFILE *bfd, JCR *jcr)
414 bfd->cmd_plugin = true;
420 * This code is running on a non-Win32 machine
423 bool is_restore_stream_supported(int stream)
425 /* No Win32 backup on this machine */
428 case STREAM_GZIP_DATA:
429 case STREAM_SPARSE_GZIP_DATA:
430 case STREAM_WIN32_GZIP_DATA:
433 case STREAM_COMPRESSED_DATA:
434 case STREAM_SPARSE_COMPRESSED_DATA:
435 case STREAM_WIN32_COMPRESSED_DATA:
436 case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
437 case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
439 #ifndef HAVE_DARWIN_OS
440 case STREAM_MACOS_FORK_DATA:
441 case STREAM_HFSPLUS_ATTRIBUTES:
447 case STREAM_GZIP_DATA:
448 case STREAM_SPARSE_GZIP_DATA:
449 case STREAM_WIN32_GZIP_DATA:
452 case STREAM_COMPRESSED_DATA:
453 case STREAM_SPARSE_COMPRESSED_DATA:
454 case STREAM_WIN32_COMPRESSED_DATA:
455 case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
456 case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
458 case STREAM_WIN32_DATA:
459 case STREAM_UNIX_ATTRIBUTES:
460 case STREAM_FILE_DATA:
461 case STREAM_MD5_DIGEST:
462 case STREAM_UNIX_ATTRIBUTES_EX:
463 case STREAM_SPARSE_DATA:
464 case STREAM_PROGRAM_NAMES:
465 case STREAM_PROGRAM_DATA:
466 case STREAM_SHA1_DIGEST:
468 case STREAM_SHA256_DIGEST:
469 case STREAM_SHA512_DIGEST:
472 case STREAM_SIGNED_DIGEST:
473 case STREAM_ENCRYPTED_FILE_DATA:
474 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
475 case STREAM_ENCRYPTED_WIN32_DATA:
476 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
478 #ifdef HAVE_DARWIN_OS
479 case STREAM_MACOS_FORK_DATA:
480 case STREAM_HFSPLUS_ATTRIBUTES:
482 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
483 #endif /* HAVE_CRYPTO */
484 #endif /* HAVE_DARWIN_OS */
485 case 0: /* compatibility with old tapes */
493 int bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
495 if (bfd->cmd_plugin && plugin_bopen) {
496 Dmsg1(400, "call plugin_bopen fname=%s\n", fname);
497 bfd->fid = plugin_bopen(bfd, fname, flags, mode);
498 Dmsg2(400, "Plugin bopen fid=%d file=%s\n", bfd->fid, fname);
502 /* Normal file open */
503 Dmsg1(dbglvl, "open file %s\n", fname);
505 /* We use fnctl to set O_NOATIME if requested to avoid open error */
506 bfd->fid = open(fname, flags & ~O_NOATIME, mode);
508 /* Set O_NOATIME if possible */
509 if (bfd->fid != -1 && flags & O_NOATIME) {
510 int oldflags = fcntl(bfd->fid, F_GETFL, 0);
511 if (oldflags == -1) {
516 int ret = fcntl(bfd->fid, F_SETFL, oldflags | O_NOATIME);
517 /* EPERM means setting O_NOATIME was not allowed */
518 if (ret == -1 && errno != EPERM) {
526 bfd->m_flags = flags;
528 bfd->total_bytes = 0;
529 Dmsg1(400, "Open file %d\n", bfd->fid);
532 bfd->win32DecompContext.bIsInData = false;
533 bfd->win32DecompContext.liNextHeader = 0;
535 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
536 if (bfd->fid != -1 && flags & O_RDONLY) {
537 int stat = posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_WILLNEED);
538 Dmsg2(400, "Did posix_fadvise on %s stat=%d\n", fname, stat);
545 #ifdef HAVE_DARWIN_OS
546 /* Open the resource fork of a file. */
547 int bopen_rsrc(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
551 rsrc_fname = get_pool_memory(PM_FNAME);
552 pm_strcpy(rsrc_fname, fname);
553 pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
554 bopen(bfd, rsrc_fname, flags, mode);
555 free_pool_memory(rsrc_fname);
560 int bopen_rsrc(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
568 int bclose(BFILE *bfd)
572 Dmsg1(400, "Close file %d\n", bfd->fid);
574 if (bfd->fid == -1) {
577 if (bfd->cmd_plugin && plugin_bclose) {
578 stat = plugin_bclose(bfd);
580 bfd->cmd_plugin = false;
583 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
584 if (bfd->m_flags & O_RDONLY) {
585 fdatasync(bfd->fid); /* sync the file */
586 /* Tell OS we don't need it any more */
587 posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_DONTNEED);
591 /* Close normal file */
592 stat = close(bfd->fid);
595 bfd->cmd_plugin = false;
600 ssize_t bread(BFILE *bfd, void *buf, size_t count)
604 if (bfd->cmd_plugin && plugin_bread) {
605 return plugin_bread(bfd, buf, count);
608 stat = read(bfd->fid, buf, count);
612 bfd->total_bytes += stat;
618 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
622 if (bfd->cmd_plugin && plugin_bwrite) {
623 return plugin_bwrite(bfd, buf, count);
625 stat = write(bfd->fid, buf, count);
629 bfd->total_bytes += stat;
635 bool is_bopen(BFILE *bfd)
637 return bfd->fid >= 0;
641 boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
645 if (bfd->cmd_plugin && plugin_bwrite) {
646 return plugin_blseek(bfd, offset, whence);
648 pos = (boffset_t)lseek(bfd->fid, offset, whence);