1 /*
2  * Debug functions
3  *
4  * Copyright (C) 2018-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <memory.h>
24 #include <types.h>
25 
26 #include "libfsapfs_debug.h"
27 #include "libfsapfs_definitions.h"
28 #include "libfsapfs_libbfio.h"
29 #include "libfsapfs_libcerror.h"
30 #include "libfsapfs_libcnotify.h"
31 #include "libfsapfs_libfdatetime.h"
32 #include "libfsapfs_libfguid.h"
33 #include "libfsapfs_unused.h"
34 
35 #if defined( HAVE_DEBUG_OUTPUT )
36 
37 /* Prints the B-tree flags
38  */
libfsapfs_debug_print_btree_flags(uint32_t btree_flags)39 void libfsapfs_debug_print_btree_flags(
40       uint32_t btree_flags )
41 {
42 	if( ( btree_flags & 0x00000001 ) != 0 )
43 	{
44 		libcnotify_printf(
45 		 "\t(BTREE_UINT64_KEYS)\n" );
46 	}
47 	if( ( btree_flags & 0x00000002 ) != 0 )
48 	{
49 		libcnotify_printf(
50 		 "\t(BTREE_SEQUENTIAL_INSERT)\n" );
51 	}
52 	if( ( btree_flags & 0x00000004 ) != 0 )
53 	{
54 		libcnotify_printf(
55 		 "\t(BTREE_ALLOW_GHOSTS)\n" );
56 	}
57 	if( ( btree_flags & 0x00000008 ) != 0 )
58 	{
59 		libcnotify_printf(
60 		 "\t(BTREE_EPHEMERAL)\n" );
61 	}
62 	if( ( btree_flags & 0x00000010 ) != 0 )
63 	{
64 		libcnotify_printf(
65 		 "\t(BTREE_PHYSICAL)\n" );
66 	}
67 	if( ( btree_flags & 0x00000020 ) != 0 )
68 	{
69 		libcnotify_printf(
70 		 "\t(BTREE_NONPERSISTENT)\n" );
71 	}
72 	if( ( btree_flags & 0x00000040 ) != 0 )
73 	{
74 		libcnotify_printf(
75 		 "\t(BTREE_KV_NONALIGNED)\n" );
76 	}
77 }
78 
79 /* Prints the B-tree node flags
80  */
libfsapfs_debug_print_btree_node_flags(uint16_t btree_node_flags)81 void libfsapfs_debug_print_btree_node_flags(
82       uint16_t btree_node_flags )
83 {
84 	if( ( btree_node_flags & 0x0001 ) != 0 )
85 	{
86 		libcnotify_printf(
87 		 "\tIs root (BTNODE_ROOT)\n" );
88 	}
89 	if( ( btree_node_flags & 0x0002 ) != 0 )
90 	{
91 		libcnotify_printf(
92 		 "\tIs leaf (BTNODE_LEAF)\n" );
93 	}
94 	if( ( btree_node_flags & 0x0004 ) != 0 )
95 	{
96 		libcnotify_printf(
97 		 "\tHas fixed-size entry (BTNODE_FIXED_KV_SIZE)\n" );
98 	}
99 
100 	if( ( btree_node_flags & 0x8000 ) != 0 )
101 	{
102 		libcnotify_printf(
103 		 "\tIn transient state (BTNODE_CHECK_KOFF_INVAL)\n" );
104 	}
105 }
106 
107 /* Prints the checkpoint flags
108  */
libfsapfs_debug_print_checkpoint_flags(uint32_t checkpoint_flags)109 void libfsapfs_debug_print_checkpoint_flags(
110       uint32_t checkpoint_flags )
111 {
112 	if( ( checkpoint_flags & 0x00000001 ) != 0 )
113 	{
114 		libcnotify_printf(
115 		 "\t(CHECKPOINT_MAP_LAST)\n" );
116 	}
117 }
118 
119 /* Prints the container compatible feature flags
120  */
libfsapfs_debug_print_container_compatible_features_flags(uint64_t compatible_features_flags)121 void libfsapfs_debug_print_container_compatible_features_flags(
122       uint64_t compatible_features_flags )
123 {
124 	if( ( compatible_features_flags & 0x0000000000000001 ) != 0 )
125 	{
126 		libcnotify_printf(
127 		 "\t(NX_FEATURE_DEFRAG)\n" );
128 	}
129 	if( ( compatible_features_flags & 0x0000000000000002 ) != 0 )
130 	{
131 		libcnotify_printf(
132 		 "\t(NX_FEATURE_LCFD)\n" );
133 	}
134 }
135 
136 /* Prints the container incompatible feature flags
137  */
libfsapfs_debug_print_container_incompatible_features_flags(uint64_t incompatible_features_flags)138 void libfsapfs_debug_print_container_incompatible_features_flags(
139       uint64_t incompatible_features_flags )
140 {
141 	if( ( incompatible_features_flags & 0x0000000000000001 ) != 0 )
142 	{
143 		libcnotify_printf(
144 		 "\t(NX_INCOMPAT_VERSION1)\n" );
145 	}
146 	if( ( incompatible_features_flags & 0x0000000000000002 ) != 0 )
147 	{
148 		libcnotify_printf(
149 		 "\t(NX_INCOMPAT_VERSION2)\n" );
150 	}
151 
152 	if( ( incompatible_features_flags & 0x0000000000000100 ) != 0 )
153 	{
154 		libcnotify_printf(
155 		 "\t(NX_INCOMPAT_FUSION)\n" );
156 	}
157 }
158 
159 /* Prints the container read-only compatible feature flags
160  */
libfsapfs_debug_print_container_read_only_compatible_features_flags(uint64_t read_only_compatible_features_flags LIBFSAPFS_ATTRIBUTE_UNUSED)161 void libfsapfs_debug_print_container_read_only_compatible_features_flags(
162       uint64_t read_only_compatible_features_flags LIBFSAPFS_ATTRIBUTE_UNUSED )
163 {
164 	LIBFSAPFS_UNREFERENCED_PARAMETER( read_only_compatible_features_flags )
165 
166 	/* Currently there are no container read-only compatible feature flags defined */
167 }
168 
169 /* Prints the directory entry flags
170  */
libfsapfs_debug_print_directory_entry_flags(uint16_t directory_entry_flags)171 void libfsapfs_debug_print_directory_entry_flags(
172       uint16_t directory_entry_flags )
173 {
174 	switch( directory_entry_flags & 0x000f )
175 	{
176 		case 0x0000:
177 			libcnotify_printf(
178 			 "\t(DT_UNKNOWN)\n" );
179 			break;
180 
181 		case 0x0001:
182 			libcnotify_printf(
183 			 "\t(DT_FIFO)\n" );
184 			break;
185 
186 		case 0x0002:
187 			libcnotify_printf(
188 			 "\t(DT_CHR)\n" );
189 			break;
190 
191 		case 0x0004:
192 			libcnotify_printf(
193 			 "\t(DT_DIR)\n" );
194 			break;
195 
196 		case 0x0006:
197 			libcnotify_printf(
198 			 "\t(DT_BLK)\n" );
199 			break;
200 
201 		case 0x0008:
202 			libcnotify_printf(
203 			 "\t(DT_REG)\n" );
204 			break;
205 
206 		case 0x000a:
207 			libcnotify_printf(
208 			 "\t(DT_LNK)\n" );
209 			break;
210 
211 		case 0x000c:
212 			libcnotify_printf(
213 			 "\t(DT_SOCK)\n" );
214 			break;
215 
216 		case 0x000e:
217 			libcnotify_printf(
218 			 "\t(DT_WHT)\n" );
219 			break;
220 
221 		default:
222 			libcnotify_printf(
223 			 "\tUnknown: 0x%04" PRIx16 "\n",
224 			 directory_entry_flags & 0x000f );
225 			break;
226 	}
227 	if( ( directory_entry_flags & 0x0010 ) != 0 )
228 	{
229 		libcnotify_printf(
230 		 "\t(RESERVED_10)\n" );
231 	}
232 }
233 
234 /* Prints the extended attribute flags
235  */
libfsapfs_debug_print_extended_attribute_flags(uint16_t extended_attribute_flags)236 void libfsapfs_debug_print_extended_attribute_flags(
237       uint16_t extended_attribute_flags )
238 {
239 	if( ( extended_attribute_flags & 0x0001 ) != 0 )
240 	{
241 		libcnotify_printf(
242 		 "\t(XATTR_DATA_STREAM)\n" );
243 	}
244 	if( ( extended_attribute_flags & 0x0002 ) != 0 )
245 	{
246 		libcnotify_printf(
247 		 "\t(XATTR_DATA_EMBEDDED)\n" );
248 	}
249 	if( ( extended_attribute_flags & 0x0004 ) != 0 )
250 	{
251 		libcnotify_printf(
252 		 "\t(XATTR_FILE_SYSTEM_OWNED)\n" );
253 	}
254 	if( ( extended_attribute_flags & 0x0008 ) != 0 )
255 	{
256 		libcnotify_printf(
257 		 "\t(XATTR_RESERVED_8)\n" );
258 	}
259 }
260 
261 /* Prints the extended field flags
262  */
libfsapfs_debug_print_extended_field_flags(uint8_t extended_field_flags)263 void libfsapfs_debug_print_extended_field_flags(
264       uint8_t extended_field_flags )
265 {
266 	if( ( extended_field_flags & 0x01 ) != 0 )
267 	{
268 		libcnotify_printf(
269 		 "\t(XF_DATA_DEPENDENT)\n" );
270 	}
271 	if( ( extended_field_flags & 0x02 ) != 0 )
272 	{
273 		libcnotify_printf(
274 		 "\t(XF_DO_NOT_COPY)\n" );
275 	}
276 	if( ( extended_field_flags & 0x04 ) != 0 )
277 	{
278 		libcnotify_printf(
279 		 "\t(XF_RESERVED_4)\n" );
280 	}
281 	if( ( extended_field_flags & 0x08 ) != 0 )
282 	{
283 		libcnotify_printf(
284 		 "\t(XF_CHILDREN_INHERIT)\n" );
285 	}
286 	if( ( extended_field_flags & 0x10 ) != 0 )
287 	{
288 		libcnotify_printf(
289 		 "\t(XF_USER_FIELD)\n" );
290 	}
291 	if( ( extended_field_flags & 0x20 ) != 0 )
292 	{
293 		libcnotify_printf(
294 		 "\t(XF_SYSTEM_FIELD)\n" );
295 	}
296 	if( ( extended_field_flags & 0x40 ) != 0 )
297 	{
298 		libcnotify_printf(
299 		 "\t(XF_RESERVED_40)\n" );
300 	}
301 	if( ( extended_field_flags & 0x80 ) != 0 )
302 	{
303 		libcnotify_printf(
304 		 "\t(XF_RESERVED_80)\n" );
305 	}
306 }
307 
308 /* Prints the inode flags
309  */
libfsapfs_debug_print_inode_flags(uint64_t inode_flags)310 void libfsapfs_debug_print_inode_flags(
311       uint64_t inode_flags )
312 {
313 	if( ( inode_flags & 0x00000001 ) != 0 )
314 	{
315 		libcnotify_printf(
316 		 "\t(INODE_IS_APFS_PRIVATE)\n" );
317 	}
318 	if( ( inode_flags & 0x00000002 ) != 0 )
319 	{
320 		libcnotify_printf(
321 		 "\t(INODE_MAINTAIN_DIR_STATS)\n" );
322 	}
323 	if( ( inode_flags & 0x00000004 ) != 0 )
324 	{
325 		libcnotify_printf(
326 		 "\t(INODE_DIR_STATS_ORIGIN)\n" );
327 	}
328 	if( ( inode_flags & 0x00000008 ) != 0 )
329 	{
330 		libcnotify_printf(
331 		 "\t(INODE_PROT_CLASS_EXPLICIT)\n" );
332 	}
333 	if( ( inode_flags & 0x00000010 ) != 0 )
334 	{
335 		libcnotify_printf(
336 		 "\t(INODE_WAS_CLONED)\n" );
337 	}
338 	if( ( inode_flags & 0x00000020 ) != 0 )
339 	{
340 		libcnotify_printf(
341 		 "\t(INODE_FLAG_UNUSED)\n" );
342 	}
343 	if( ( inode_flags & 0x00000040 ) != 0 )
344 	{
345 		libcnotify_printf(
346 		 "\t(INODE_HAS_SECURITY_EA)\n" );
347 	}
348 	if( ( inode_flags & 0x00000080 ) != 0 )
349 	{
350 		libcnotify_printf(
351 		 "\t(INODE_BEING_TRUNCATED)\n" );
352 	}
353 	if( ( inode_flags & 0x00000100 ) != 0 )
354 	{
355 		libcnotify_printf(
356 		 "\t(INODE_HAS_FINDER_INFO)\n" );
357 	}
358 	if( ( inode_flags & 0x00000200 ) != 0 )
359 	{
360 		libcnotify_printf(
361 		 "\t(INODE_IS_SPARSE)\n" );
362 	}
363 	if( ( inode_flags & 0x00000400 ) != 0 )
364 	{
365 		libcnotify_printf(
366 		 "\t(INODE_WAS_EVER_CLONED)\n" );
367 	}
368 	if( ( inode_flags & 0x00000800 ) != 0 )
369 	{
370 		libcnotify_printf(
371 		 "\t(INODE_ACTIVE_FILE_TRIMMED)\n" );
372 	}
373 	if( ( inode_flags & 0x00001000 ) != 0 )
374 	{
375 		libcnotify_printf(
376 		 "\t(INODE_PINNED_TO_MAIN)\n" );
377 	}
378 	if( ( inode_flags & 0x00002000 ) != 0 )
379 	{
380 		libcnotify_printf(
381 		 "\t(INODE_PINNED_TO_TIER2)\n" );
382 	}
383 	if( ( inode_flags & 0x00004000 ) != 0 )
384 	{
385 		libcnotify_printf(
386 		 "\t(INODE_HAS_RSRC_FORK)\n" );
387 	}
388 	if( ( inode_flags & 0x00008000 ) != 0 )
389 	{
390 		libcnotify_printf(
391 		 "\t(INODE_NO_RSRC_FORK)\n" );
392 	}
393 	if( ( inode_flags & 0x00010000 ) != 0 )
394 	{
395 		libcnotify_printf(
396 		 "\t(INODE_ALLOCATION_SPILLEDOVER)\n" );
397 	}
398 }
399 
400 /* Prints the volume compatible feature flags
401  */
libfsapfs_debug_print_volume_compatible_features_flags(uint64_t compatible_features_flags)402 void libfsapfs_debug_print_volume_compatible_features_flags(
403       uint64_t compatible_features_flags )
404 {
405 	if( ( compatible_features_flags & 0x0000000000000001 ) != 0 )
406 	{
407 		libcnotify_printf(
408 		 "\t(APFS_FEATURE_DEFRAG_PRERELEASE)\n" );
409 	}
410 	if( ( compatible_features_flags & 0x0000000000000002 ) != 0 )
411 	{
412 		libcnotify_printf(
413 		 "\t(APFS_FEATURE_HARDLINK_MAP_RECORDS)\n" );
414 	}
415 	if( ( compatible_features_flags & 0x0000000000000004 ) != 0 )
416 	{
417 		libcnotify_printf(
418 		 "\t(APFS_FEATURE_DEFRAG)\n" );
419 	}
420 }
421 
422 /* Prints the volume flags
423  */
libfsapfs_debug_print_volume_flags(uint64_t volume_flags)424 void libfsapfs_debug_print_volume_flags(
425       uint64_t volume_flags )
426 {
427 	if( ( volume_flags & 0x0000000000000001 ) != 0 )
428 	{
429 		libcnotify_printf(
430 		 "\t(APFS_FS_UNENCRYPTED)\n" );
431 	}
432 	if( ( volume_flags & 0x0000000000000002 ) != 0 )
433 	{
434 		libcnotify_printf(
435 		 "\t(APFS_FS_EFFACEABLE)\n" );
436 	}
437 	if( ( volume_flags & 0x0000000000000004 ) != 0 )
438 	{
439 		libcnotify_printf(
440 		 "\t(APFS_FS_RESERVED_4)\n" );
441 	}
442 	if( ( volume_flags & 0x0000000000000008 ) != 0 )
443 	{
444 		libcnotify_printf(
445 		 "\t(APFS_FS_ONEKEY)\n" );
446 	}
447 	if( ( volume_flags & 0x0000000000000010 ) != 0 )
448 	{
449 		libcnotify_printf(
450 		 "\t(APFS_FS_SPILLEDOVER)\n" );
451 	}
452 	if( ( volume_flags & 0x0000000000000020 ) != 0 )
453 	{
454 		libcnotify_printf(
455 		 "\t(APFS_FS_RUN_SPILLOVER_CLEANER)\n" );
456 	}
457 }
458 
459 /* Prints the volume incompatible feature flags
460  */
libfsapfs_debug_print_volume_incompatible_features_flags(uint64_t incompatible_features_flags)461 void libfsapfs_debug_print_volume_incompatible_features_flags(
462       uint64_t incompatible_features_flags )
463 {
464 	if( ( incompatible_features_flags & 0x0000000000000001 ) != 0 )
465 	{
466 		libcnotify_printf(
467 		 "\t(APFS_INCOMPAT_CASE_INSENSITIVE)\n" );
468 	}
469 	if( ( incompatible_features_flags & 0x0000000000000002 ) != 0 )
470 	{
471 		libcnotify_printf(
472 		 "\t(APFS_INCOMPAT_DATALESS_SNAPS)\n" );
473 	}
474 	if( ( incompatible_features_flags & 0x0000000000000004 ) != 0 )
475 	{
476 		libcnotify_printf(
477 		 "\t(APFS_INCOMPAT_ENC_ROLLED)\n" );
478 	}
479 	if( ( incompatible_features_flags & 0x0000000000000008 ) != 0 )
480 	{
481 		libcnotify_printf(
482 		 "\t(APFS_INCOMPAT_NORMALIZATION_INSENSITIVE)\n" );
483 	}
484 }
485 
486 /* Prints the volume read-only compatible feature flags
487  */
libfsapfs_debug_print_volume_read_only_compatible_features_flags(uint64_t read_only_compatible_features_flags LIBFSAPFS_ATTRIBUTE_UNUSED)488 void libfsapfs_debug_print_volume_read_only_compatible_features_flags(
489       uint64_t read_only_compatible_features_flags LIBFSAPFS_ATTRIBUTE_UNUSED )
490 {
491 	LIBFSAPFS_UNREFERENCED_PARAMETER( read_only_compatible_features_flags )
492 
493 	/* Currently there are no volume read-only compatible feature flags defined */
494 }
495 
496 /* Prints the file system data type
497  */
libfsapfs_debug_print_file_system_data_type(uint8_t file_system_data_type)498 const char *libfsapfs_debug_print_file_system_data_type(
499              uint8_t file_system_data_type )
500 {
501 	switch( file_system_data_type )
502 	{
503 		case 0:
504 			return( "(APFS_TYPE_ANY)" );
505 
506 		case 1:
507 			return( "(APFS_TYPE_SNAP_METADATA)" );
508 
509 		case 2:
510 			return( "(APFS_TYPE_EXTENT)" );
511 
512 		case 3:
513 			return( "(APFS_TYPE_INODE)" );
514 
515 		case 4:
516 			return( "(APFS_TYPE_XATTR)" );
517 
518 		case 5:
519 			return( "(APFS_TYPE_SIBLING_LINK)" );
520 
521 		case 6:
522 			return( "(APFS_TYPE_DSTREAM_ID)" );
523 
524 		case 7:
525 			return( "(APFS_TYPE_CRYPTO_STATE)" );
526 
527 		case 8:
528 			return( "(APFS_TYPE_FILE_EXTENT)" );
529 
530 		case 9:
531 			return( "(APFS_TYPE_DIR_REC)" );
532 
533 		case 10:
534 			return( "(APFS_TYPE_DIR_STATS)" );
535 
536 		case 11:
537 			return( "(APFS_TYPE_SNAP_NAME)" );
538 
539 		case 12:
540 			return( "(APFS_TYPE_SIBLING_MAP)" );
541 	}
542 	return( "Unknown" );
543 }
544 
545 /* Prints the directory record extended field type
546  */
libfsapfs_debug_print_directory_record_extended_field_type(uint8_t extended_field_type)547 const char *libfsapfs_debug_print_directory_record_extended_field_type(
548              uint8_t extended_field_type )
549 {
550 	switch( extended_field_type )
551 	{
552 		case 1:
553 			return( "(DREC_EXT_TYPE_SIBLING_ID)" );
554 	}
555 	return( "Unknown" );
556 }
557 
558 /* Prints the inode extended field type
559  */
libfsapfs_debug_print_inode_extended_field_type(uint8_t extended_field_type)560 const char *libfsapfs_debug_print_inode_extended_field_type(
561              uint8_t extended_field_type )
562 {
563 	switch( extended_field_type )
564 	{
565 		case 1:
566 			return( "(INO_EXT_TYPE_SNAP_XID)" );
567 
568 		case 2:
569 			return( "(INO_EXT_TYPE_DELTA_TREE_OID)" );
570 
571 		case 3:
572 			return( "(INO_EXT_TYPE_DOCUMENT_ID)" );
573 
574 		case 4:
575 			return( "(INO_EXT_TYPE_NAME)" );
576 
577 		case 5:
578 			return( "(INO_EXT_TYPE_PREV_FSIZE)" );
579 
580 		case 6:
581 			return( "(INO_EXT_TYPE_RESERVED_6)" );
582 
583 		case 7:
584 			return( "(INO_EXT_TYPE_FINDER_INFO)" );
585 
586 		case 8:
587 			return( "(INO_EXT_TYPE_DSTREAM)" );
588 
589 		case 9:
590 			return( "(INO_EXT_TYPE_RESERVED_9)" );
591 
592 		case 10:
593 			return( "(INO_EXT_TYPE_DIR_STATS_KEY)" );
594 
595 		case 11:
596 			return( "(INO_EXT_TYPE_FS_UUID)" );
597 
598 		case 12:
599 			return( "(INO_EXT_TYPE_RESERVED_12)" );
600 
601 		case 13:
602 			return( "(INO_EXT_TYPE_SPARSE_BYTES)" );
603 
604 		case 14:
605 			return( "(INO_EXT_TYPE_RDEV)" );
606 	}
607 	return( "Unknown" );
608 }
609 
610 /* Prints a POSIX value
611  * Returns 1 if successful or -1 on error
612  */
libfsapfs_debug_print_posix_time_value(const char * function_name,const char * value_name,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,uint8_t value_type,uint32_t string_format_flags,libcerror_error_t ** error)613 int libfsapfs_debug_print_posix_time_value(
614      const char *function_name,
615      const char *value_name,
616      const uint8_t *byte_stream,
617      size_t byte_stream_size,
618      int byte_order,
619      uint8_t value_type,
620      uint32_t string_format_flags,
621      libcerror_error_t **error )
622 {
623 	char date_time_string[ 32 ];
624 
625 	libfdatetime_posix_time_t *posix_time = NULL;
626 	static char *function                 = "libfsapfs_debug_print_posix_time_value";
627 
628 	if( libfdatetime_posix_time_initialize(
629 	     &posix_time,
630 	     error ) != 1 )
631 	{
632 		libcerror_error_set(
633 		 error,
634 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
635 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
636 		 "%s: unable to create POSIX time.",
637 		 function );
638 
639 		goto on_error;
640 	}
641 	if( libfdatetime_posix_time_copy_from_byte_stream(
642 	     posix_time,
643 	     byte_stream,
644 	     byte_stream_size,
645 	     byte_order,
646 	     value_type,
647 	     error ) != 1 )
648 	{
649 		libcerror_error_set(
650 		 error,
651 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
652 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
653 		 "%s: unable to copy byte stream to POSIX time.",
654 		 function );
655 
656 		goto on_error;
657 	}
658 	if( libfdatetime_posix_time_copy_to_utf8_string(
659 	     posix_time,
660 	     (uint8_t *) date_time_string,
661 	     32,
662 	     string_format_flags,
663 	     error ) != 1 )
664 	{
665 		libcerror_error_set(
666 		 error,
667 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
668 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
669 		 "%s: unable to copy POSIX time to string.",
670 		 function );
671 
672 		goto on_error;
673 	}
674 	libcnotify_printf(
675 	 "%s: %s: %s UTC\n",
676 	 function_name,
677 	 value_name,
678 	 date_time_string );
679 
680 	if( libfdatetime_posix_time_free(
681 	     &posix_time,
682 	     error ) != 1 )
683 	{
684 		libcerror_error_set(
685 		 error,
686 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
687 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
688 		 "%s: unable to free POSIX time.",
689 		 function );
690 
691 		goto on_error;
692 	}
693 	return( 1 );
694 
695 on_error:
696 	if( posix_time != NULL )
697 	{
698 		libfdatetime_posix_time_free(
699 		 &posix_time,
700 		 NULL );
701 	}
702 	return( -1 );
703 }
704 
705 /* Prints a GUID/UUID value
706  * Returns 1 if successful or -1 on error
707  */
libfsapfs_debug_print_guid_value(const char * function_name,const char * value_name,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,uint32_t string_format_flags,libcerror_error_t ** error)708 int libfsapfs_debug_print_guid_value(
709      const char *function_name,
710      const char *value_name,
711      const uint8_t *byte_stream,
712      size_t byte_stream_size,
713      int byte_order,
714      uint32_t string_format_flags,
715      libcerror_error_t **error )
716 {
717         system_character_t guid_string[ 48 ];
718 
719         libfguid_identifier_t *guid = NULL;
720 	static char *function       = "libfsapfs_debug_print_guid_value";
721 
722 	if( libfguid_identifier_initialize(
723 	     &guid,
724 	     error ) != 1 )
725 	{
726 		libcerror_error_set(
727 		 error,
728 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
729 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
730 		 "%s: unable to create GUID.",
731 		 function );
732 
733 		goto on_error;
734 	}
735 	if( libfguid_identifier_copy_from_byte_stream(
736 	     guid,
737 	     byte_stream,
738 	     byte_stream_size,
739 	     byte_order,
740 	     error ) != 1 )
741 	{
742 		libcerror_error_set(
743 		 error,
744 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
745 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
746 		 "%s: unable to copy byte stream to GUID.",
747 		 function );
748 
749 		goto on_error;
750 	}
751 	if( libfguid_identifier_copy_to_utf8_string(
752 	     guid,
753 	     (uint8_t *) guid_string,
754 	     48,
755 	     string_format_flags,
756 	     error ) != 1 )
757 	{
758 		libcerror_error_set(
759 		 error,
760 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
761 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
762 		 "%s: unable to copy GUID to string.",
763 		 function );
764 
765 		goto on_error;
766 	}
767 	libcnotify_printf(
768 	 "%s: %s: %s\n",
769 	 function_name,
770 	 value_name,
771 	 guid_string );
772 
773 	if( libfguid_identifier_free(
774 	     &guid,
775 	     error ) != 1 )
776 	{
777 		libcerror_error_set(
778 		 error,
779 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
780 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
781 		 "%s: unable to free GUID.",
782 		 function );
783 
784 		goto on_error;
785 	}
786 	return( 1 );
787 
788 on_error:
789 	if( guid != NULL )
790 	{
791 		libfguid_identifier_free(
792 		 &guid,
793 		 NULL );
794 	}
795 	return( -1 );
796 }
797 
798 /* Prints the read offsets
799  * Returns 1 if successful or -1 on error
800  */
libfsapfs_debug_print_read_offsets(libbfio_handle_t * file_io_handle,libcerror_error_t ** error)801 int libfsapfs_debug_print_read_offsets(
802      libbfio_handle_t *file_io_handle,
803      libcerror_error_t **error )
804 {
805 	static char *function = "libfsapfs_debug_print_read_offsets";
806 	off64_t offset        = 0;
807 	size64_t size         = 0;
808 	int number_of_offsets = 0;
809 	int offset_iterator   = 0;
810 
811 	if( file_io_handle == NULL )
812 	{
813 		libcerror_error_set(
814 		 error,
815 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
816 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
817 		 "%s: invalid file IO handle.",
818 		 function );
819 
820 		return( -1 );
821 	}
822 	if( libbfio_handle_get_number_of_offsets_read(
823 	     file_io_handle,
824 	     &number_of_offsets,
825 	     error ) != 1 )
826 	{
827 		libcerror_error_set(
828 		 error,
829 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
830 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
831 		 "%s: unable to retrieve number of offsets read.",
832 		 function );
833 
834 		return( -1 );
835 	}
836 	libcnotify_printf(
837 	 "Offsets read:\n" );
838 
839 	for( offset_iterator = 0;
840 	     offset_iterator < number_of_offsets;
841 	     offset_iterator++ )
842 	{
843 		if( libbfio_handle_get_offset_read(
844 		     file_io_handle,
845 		     offset_iterator,
846 		     &offset,
847 		     &size,
848 		     error ) != 1 )
849 		{
850 			libcerror_error_set(
851 			 error,
852 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
853 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
854 			 "%s: unable to retrieve offset: %d.",
855 			 function,
856 			 ( offset_iterator + 1 ) );
857 
858 			return( -1 );
859 		}
860 		libcnotify_printf(
861 		 "%08" PRIi64 " ( 0x%08" PRIx64 " ) - %08" PRIi64 " ( 0x%08" PRIx64 " ) size: %" PRIu64 "\n",
862 		 offset,
863 		 offset,
864 		 offset + (off64_t) size,
865 		 offset + (off64_t) size,
866 		 size );
867 	}
868 	libcnotify_printf(
869 	 "\n" );
870 
871 	return( 1 );
872 }
873 
874 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
875 
876