1 /*
2  * Info handle
3  *
4  * Copyright (C) 2014-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 <file_stream.h>
24 #include <memory.h>
25 #include <narrow_string.h>
26 #include <system_string.h>
27 #include <types.h>
28 #include <wide_string.h>
29 
30 #include "byte_size_string.h"
31 #include "info_handle.h"
32 #include "vslvmtools_libbfio.h"
33 #include "vslvmtools_libcerror.h"
34 #include "vslvmtools_libclocale.h"
35 #include "vslvmtools_libvslvm.h"
36 
37 #if !defined( LIBVSLVM_HAVE_BFIO )
38 
39 LIBVSLVM_EXTERN \
40 int libvslvm_handle_open_file_io_handle(
41      libvslvm_handle_t *handle,
42      libbfio_handle_t *file_io_handle,
43      int access_flags,
44      libvslvm_error_t **error );
45 
46 LIBVSLVM_EXTERN \
47 int libvslvm_handle_open_physical_volume_files_file_io_pool(
48      libvslvm_handle_t *handle,
49      libbfio_pool_t *file_io_pool,
50      libcerror_error_t **error );
51 
52 #endif /* !defined( LIBVSLVM_HAVE_BFIO ) */
53 
54 #define INFO_HANDLE_NOTIFY_STREAM		stdout
55 
56 /* Copies a string of a decimal value to a 64-bit value
57  * Returns 1 if successful or -1 on error
58  */
vslvmtools_system_string_copy_from_64_bit_in_decimal(const system_character_t * string,size_t string_size,uint64_t * value_64bit,libcerror_error_t ** error)59 int vslvmtools_system_string_copy_from_64_bit_in_decimal(
60      const system_character_t *string,
61      size_t string_size,
62      uint64_t *value_64bit,
63      libcerror_error_t **error )
64 {
65 	static char *function              = "vslvmtools_system_string_copy_from_64_bit_in_decimal";
66 	size_t string_index                = 0;
67 	system_character_t character_value = 0;
68 	uint8_t maximum_string_index       = 20;
69 	int8_t sign                        = 1;
70 
71 	if( string == NULL )
72 	{
73 		libcerror_error_set(
74 		 error,
75 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
76 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
77 		 "%s: invalid string.",
78 		 function );
79 
80 		return( -1 );
81 	}
82 	if( string_size > (size_t) SSIZE_MAX )
83 	{
84 		libcerror_error_set(
85 		 error,
86 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
87 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
88 		 "%s: invalid string size value exceeds maximum.",
89 		 function );
90 
91 		return( -1 );
92 	}
93 	if( value_64bit == NULL )
94 	{
95 		libcerror_error_set(
96 		 error,
97 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99 		 "%s: invalid value 64-bit.",
100 		 function );
101 
102 		return( -1 );
103 	}
104 	*value_64bit = 0;
105 
106 	if( string[ string_index ] == (system_character_t) '-' )
107 	{
108 		string_index++;
109 		maximum_string_index++;
110 
111 		sign = -1;
112 	}
113 	else if( string[ string_index ] == (system_character_t) '+' )
114 	{
115 		string_index++;
116 		maximum_string_index++;
117 	}
118 	while( string_index < string_size )
119 	{
120 		if( string[ string_index ] == 0 )
121 		{
122 			break;
123 		}
124 		if( string_index > (size_t) maximum_string_index )
125 		{
126 			libcerror_error_set(
127 			 error,
128 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
129 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
130 			 "%s: string too large.",
131 			 function );
132 
133 			return( -1 );
134 		}
135 		*value_64bit *= 10;
136 
137 		if( ( string[ string_index ] >= (system_character_t) '0' )
138 		 && ( string[ string_index ] <= (system_character_t) '9' ) )
139 		{
140 			character_value = (system_character_t) ( string[ string_index ] - (system_character_t) '0' );
141 		}
142 		else
143 		{
144 			libcerror_error_set(
145 			 error,
146 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
147 			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
148 			 "%s: unsupported character value: %" PRIc_SYSTEM " at index: %d.",
149 			 function,
150 			 string[ string_index ],
151 			 string_index );
152 
153 			return( -1 );
154 		}
155 		*value_64bit += character_value;
156 
157 		string_index++;
158 	}
159 	if( sign == -1 )
160 	{
161 		*value_64bit *= (uint64_t) -1;
162 	}
163 	return( 1 );
164 }
165 
166 /* Creates an info handle
167  * Make sure the value info_handle is referencing, is set to NULL
168  * Returns 1 if successful or -1 on error
169  */
info_handle_initialize(info_handle_t ** info_handle,libcerror_error_t ** error)170 int info_handle_initialize(
171      info_handle_t **info_handle,
172      libcerror_error_t **error )
173 {
174 	static char *function = "info_handle_initialize";
175 
176 	if( info_handle == NULL )
177 	{
178 		libcerror_error_set(
179 		 error,
180 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
182 		 "%s: invalid info handle.",
183 		 function );
184 
185 		return( -1 );
186 	}
187 	if( *info_handle != NULL )
188 	{
189 		libcerror_error_set(
190 		 error,
191 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
192 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
193 		 "%s: invalid info handle value already set.",
194 		 function );
195 
196 		return( -1 );
197 	}
198 	*info_handle = memory_allocate_structure(
199 	                info_handle_t );
200 
201 	if( *info_handle == NULL )
202 	{
203 		libcerror_error_set(
204 		 error,
205 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
206 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
207 		 "%s: unable to create info handle.",
208 		 function );
209 
210 		goto on_error;
211 	}
212 	if( memory_set(
213 	     *info_handle,
214 	     0,
215 	     sizeof( info_handle_t ) ) == NULL )
216 	{
217 		libcerror_error_set(
218 		 error,
219 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
220 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
221 		 "%s: unable to clear info handle.",
222 		 function );
223 
224 		memory_free(
225 		 *info_handle );
226 
227 		*info_handle = NULL;
228 
229 		return( -1 );
230 	}
231 /* TODO control maximum number of handles */
232 	if( libbfio_pool_initialize(
233 	     &( ( *info_handle )->physical_volume_file_io_pool ),
234 	     0,
235 	     0,
236 	     error ) != 1 )
237 	{
238 		libcerror_error_set(
239 		 error,
240 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
241 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
242 		 "%s: unable to initialize physical volume file IO pool.",
243 		 function );
244 
245 		goto on_error;
246 	}
247 	if( libvslvm_handle_initialize(
248 	     &( ( *info_handle )->input_handle ),
249 	     error ) != 1 )
250 	{
251 		libcerror_error_set(
252 		 error,
253 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
254 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
255 		 "%s: unable to initialize input handle.",
256 		 function );
257 
258 		goto on_error;
259 	}
260 	( *info_handle )->notify_stream = INFO_HANDLE_NOTIFY_STREAM;
261 
262 	return( 1 );
263 
264 on_error:
265 	if( *info_handle != NULL )
266 	{
267 		if( ( *info_handle )->physical_volume_file_io_pool != NULL )
268 		{
269 			libbfio_pool_free(
270 			 &( ( *info_handle )->physical_volume_file_io_pool ),
271 			 NULL );
272 		}
273 		memory_free(
274 		 *info_handle );
275 
276 		*info_handle = NULL;
277 	}
278 	return( -1 );
279 }
280 
281 /* Frees an info handle
282  * Returns 1 if successful or -1 on error
283  */
info_handle_free(info_handle_t ** info_handle,libcerror_error_t ** error)284 int info_handle_free(
285      info_handle_t **info_handle,
286      libcerror_error_t **error )
287 {
288 	static char *function = "info_handle_free";
289 	int result            = 1;
290 
291 	if( info_handle == NULL )
292 	{
293 		libcerror_error_set(
294 		 error,
295 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
296 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
297 		 "%s: invalid info handle.",
298 		 function );
299 
300 		return( -1 );
301 	}
302 	if( *info_handle != NULL )
303 	{
304 		if( libvslvm_handle_free(
305 		     &( ( *info_handle )->input_handle ),
306 		     error ) != 1 )
307 		{
308 			libcerror_error_set(
309 			 error,
310 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
311 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
312 			 "%s: unable to free input handle.",
313 			 function );
314 
315 			result = -1;
316 		}
317 		if( libbfio_pool_free(
318 		     &( ( *info_handle )->physical_volume_file_io_pool ),
319 		     error ) != 1 )
320 		{
321 			libcerror_error_set(
322 			 error,
323 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
324 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
325 			 "%s: unable to free physical volume file IO pool.",
326 			 function );
327 
328 			result = -1;
329 		}
330 		memory_free(
331 		 *info_handle );
332 
333 		*info_handle = NULL;
334 	}
335 	return( result );
336 }
337 
338 /* Signals the info handle to abort
339  * Returns 1 if successful or -1 on error
340  */
info_handle_signal_abort(info_handle_t * info_handle,libcerror_error_t ** error)341 int info_handle_signal_abort(
342      info_handle_t *info_handle,
343      libcerror_error_t **error )
344 {
345 	static char *function = "info_handle_signal_abort";
346 
347 	if( info_handle == NULL )
348 	{
349 		libcerror_error_set(
350 		 error,
351 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
352 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
353 		 "%s: invalid info handle.",
354 		 function );
355 
356 		return( -1 );
357 	}
358 	info_handle->abort = 1;
359 
360 	if( info_handle->input_handle != NULL )
361 	{
362 		if( libvslvm_handle_signal_abort(
363 		     info_handle->input_handle,
364 		     error ) != 1 )
365 		{
366 			libcerror_error_set(
367 			 error,
368 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
369 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
370 			 "%s: unable to signal input handle to abort.",
371 			 function );
372 
373 			return( -1 );
374 		}
375 	}
376 	return( 1 );
377 }
378 
379 /* Sets the volume offset
380  * Returns 1 if successful or -1 on error
381  */
info_handle_set_volume_offset(info_handle_t * info_handle,const system_character_t * string,libcerror_error_t ** error)382 int info_handle_set_volume_offset(
383      info_handle_t *info_handle,
384      const system_character_t *string,
385      libcerror_error_t **error )
386 {
387 	static char *function = "info_handle_set_volume_offset";
388 	size_t string_length  = 0;
389 	uint64_t value_64bit  = 0;
390 
391 	if( info_handle == NULL )
392 	{
393 		libcerror_error_set(
394 		 error,
395 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
396 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
397 		 "%s: invalid info handle.",
398 		 function );
399 
400 		return( -1 );
401 	}
402 	string_length = system_string_length(
403 	                 string );
404 
405 	if( vslvmtools_system_string_copy_from_64_bit_in_decimal(
406 	     string,
407 	     string_length + 1,
408 	     &value_64bit,
409 	     error ) != 1 )
410 	{
411 		libcerror_error_set(
412 		 error,
413 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
414 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
415 		 "%s: unable to copy string to 64-bit decimal.",
416 		 function );
417 
418 		return( -1 );
419 	}
420 	info_handle->volume_offset = (off64_t) value_64bit;
421 
422 	return( 1 );
423 }
424 
425 /* Opens the input
426  * Returns 1 if successful or -1 on error
427  */
info_handle_open_input(info_handle_t * info_handle,const system_character_t * filename,libcerror_error_t ** error)428 int info_handle_open_input(
429      info_handle_t *info_handle,
430      const system_character_t *filename,
431      libcerror_error_t **error )
432 {
433 	libbfio_handle_t *file_io_handle = NULL;
434 	static char *function            = "info_handle_open_input";
435 	size_t filename_length           = 0;
436 	int entry_index                  = 0;
437 
438 	if( info_handle == NULL )
439 	{
440 		libcerror_error_set(
441 		 error,
442 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
443 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
444 		 "%s: invalid info handle.",
445 		 function );
446 
447 		return( -1 );
448 	}
449 	if( libbfio_file_range_initialize(
450 	     &file_io_handle,
451 	     error ) != 1 )
452 	{
453 		libcerror_error_set(
454 		 error,
455 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
456 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
457 		 "%s: unable to initialize file IO handle.",
458 		 function );
459 
460 		goto on_error;
461 	}
462 	filename_length = system_string_length(
463 	                   filename );
464 
465 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
466 	if( libbfio_file_range_set_name_wide(
467 	     file_io_handle,
468 	     filename,
469 	     filename_length,
470 	     error ) != 1 )
471 #else
472 	if( libbfio_file_range_set_name(
473 	     file_io_handle,
474 	     filename,
475 	     filename_length,
476 	     error ) != 1 )
477 #endif
478 	{
479 		libcerror_error_set(
480 		 error,
481 		 LIBCERROR_ERROR_DOMAIN_IO,
482 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
483 		 "%s: unable to open set file name.",
484 		 function );
485 
486 		goto on_error;
487 	}
488 	if( libbfio_file_range_set(
489 	     file_io_handle,
490 	     info_handle->volume_offset,
491 	     0,
492 	     error ) != 1 )
493 	{
494 		libcerror_error_set(
495 		 error,
496 		 LIBCERROR_ERROR_DOMAIN_IO,
497 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
498 		 "%s: unable to open set volume offset.",
499 		 function );
500 
501 		goto on_error;
502 	}
503 	if( libvslvm_handle_open_file_io_handle(
504 	     info_handle->input_handle,
505 	     file_io_handle,
506 	     LIBVSLVM_OPEN_READ,
507 	     error ) != 1 )
508 	{
509 		libcerror_error_set(
510 		 error,
511 		 LIBCERROR_ERROR_DOMAIN_IO,
512 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
513 		 "%s: unable to open input handle.",
514 		 function );
515 
516 		goto on_error;
517 	}
518 	if( libbfio_pool_append_handle(
519 	     info_handle->physical_volume_file_io_pool,
520 	     &entry_index,
521 	     file_io_handle,
522 	     LIBBFIO_OPEN_READ,
523 	     error ) != 1 )
524 	{
525 		libcerror_error_set(
526 		 error,
527 		 LIBCERROR_ERROR_DOMAIN_IO,
528 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
529 		 "%s: unable to open input handle.",
530 		 function );
531 
532 		goto on_error;
533 	}
534 	/* The takes over management of the file IO handle
535 	 */
536 	file_io_handle = NULL;
537 
538 /* TODO determine if the first file is a metadata only file and change filenames accordingly
539  */
540 	if( libvslvm_handle_open_physical_volume_files_file_io_pool(
541 	     info_handle->input_handle,
542 	     info_handle->physical_volume_file_io_pool,
543 	     error ) != 1 )
544 	{
545 		libcerror_error_set(
546 		 error,
547 		 LIBCERROR_ERROR_DOMAIN_IO,
548 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
549 		 "%s: unable to open physical volume files.",
550 		 function );
551 
552 		goto on_error;
553 	}
554 	return( 1 );
555 
556 on_error:
557 	if( file_io_handle != NULL )
558 	{
559 		libbfio_handle_free(
560 		 &file_io_handle,
561 		 NULL );
562 	}
563 	return( -1 );
564 }
565 
566 /* Closes the input
567  * Returns the 0 if succesful or -1 on error
568  */
info_handle_close_input(info_handle_t * info_handle,libcerror_error_t ** error)569 int info_handle_close_input(
570      info_handle_t *info_handle,
571      libcerror_error_t **error )
572 {
573 	static char *function = "info_handle_close_input";
574 
575 	if( info_handle == NULL )
576 	{
577 		libcerror_error_set(
578 		 error,
579 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
580 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
581 		 "%s: invalid info handle.",
582 		 function );
583 
584 		return( -1 );
585 	}
586 	if( libvslvm_handle_close(
587 	     info_handle->input_handle,
588 	     error ) != 0 )
589 	{
590 		libcerror_error_set(
591 		 error,
592 		 LIBCERROR_ERROR_DOMAIN_IO,
593 		 LIBCERROR_IO_ERROR_CLOSE_FAILED,
594 		 "%s: unable to close input handle.",
595 		 function );
596 
597 		return( -1 );
598 	}
599 	return( 0 );
600 }
601 
602 /* Prints the volume group information
603  * Returns 1 if successful or -1 on error
604  */
info_handle_volume_group_fprint(info_handle_t * info_handle,libvslvm_volume_group_t * volume_group,libcerror_error_t ** error)605 int info_handle_volume_group_fprint(
606      info_handle_t *info_handle,
607      libvslvm_volume_group_t *volume_group,
608      libcerror_error_t **error )
609 {
610 	system_character_t extent_size_string[ 16 ];
611 
612 	libvslvm_logical_volume_t *logical_volume   = NULL;
613 	libvslvm_physical_volume_t *physical_volume = NULL;
614 	static char *function                       = "info_handle_volume_group_fprint";
615 	char *value_string                          = NULL;
616 	size64_t extent_size                        = 0;
617 	size_t value_string_size                    = 0;
618 	uint32_t value_32bit                        = 0;
619 	int number_of_logical_volumes               = 0;
620 	int number_of_physical_volumes              = 0;
621 	int result                                  = 0;
622 	int volume_index                            = 0;
623 
624 	if( info_handle == NULL )
625 	{
626 		libcerror_error_set(
627 		 error,
628 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
629 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
630 		 "%s: invalid info handle.",
631 		 function );
632 
633 		return( -1 );
634 	}
635 	fprintf(
636 	 info_handle->notify_stream,
637 	 "Volume Group (VG):\n" );
638 
639 	if( libvslvm_volume_group_get_name_size(
640 	     volume_group,
641 	     &value_string_size,
642 	     error ) != 1 )
643 	{
644 		libcerror_error_set(
645 		 error,
646 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
647 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
648 		 "%s: unable to retrieve name size.",
649 		 function );
650 
651 		goto on_error;
652 	}
653 	else if( value_string_size > 0 )
654 	{
655 		if( value_string_size > (size_t) SSIZE_MAX )
656 		{
657 			libcerror_error_set(
658 			 error,
659 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
660 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
661 			 "%s: invalid parent value string size value exceeds maximum.",
662 			 function );
663 
664 			goto on_error;
665 		}
666 		value_string = narrow_string_allocate(
667 		                value_string_size );
668 
669 		if( value_string == NULL )
670 		{
671 			libcerror_error_set(
672 			 error,
673 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
674 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
675 			 "%s: unable to create name string.",
676 			 function );
677 
678 			goto on_error;
679 		}
680 		if( libvslvm_volume_group_get_name(
681 		     volume_group,
682 		     value_string,
683 		     value_string_size,
684 		     error ) != 1 )
685 		{
686 			libcerror_error_set(
687 			 error,
688 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
689 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
690 			 "%s: unable to retrieve name.",
691 			 function );
692 
693 			goto on_error;
694 		}
695 		fprintf(
696 		 info_handle->notify_stream,
697 		 "\tName:\t\t\t\t\t%" PRIs_SYSTEM "\n",
698 		 value_string );
699 
700 		memory_free(
701 		 value_string );
702 
703 		value_string = NULL;
704 	}
705 	if( libvslvm_volume_group_get_identifier_size(
706 	     volume_group,
707 	     &value_string_size,
708 	     error ) != 1 )
709 	{
710 		libcerror_error_set(
711 		 error,
712 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
713 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
714 		 "%s: unable to retrieve identifier size.",
715 		 function );
716 
717 		goto on_error;
718 	}
719 	else if( value_string_size > 0 )
720 	{
721 		if( value_string_size > (size_t) SSIZE_MAX )
722 		{
723 			libcerror_error_set(
724 			 error,
725 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
726 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
727 			 "%s: invalid parent value string size value exceeds maximum.",
728 			 function );
729 
730 			goto on_error;
731 		}
732 		value_string = narrow_string_allocate(
733 		                value_string_size );
734 
735 		if( value_string == NULL )
736 		{
737 			libcerror_error_set(
738 			 error,
739 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
740 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
741 			 "%s: unable to create identifier string.",
742 			 function );
743 
744 			goto on_error;
745 		}
746 		if( libvslvm_volume_group_get_identifier(
747 		     volume_group,
748 		     value_string,
749 		     value_string_size,
750 		     error ) != 1 )
751 		{
752 			libcerror_error_set(
753 			 error,
754 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
755 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
756 			 "%s: unable to retrieve identifier.",
757 			 function );
758 
759 			goto on_error;
760 		}
761 		fprintf(
762 		 info_handle->notify_stream,
763 		 "\tIdentifier:\t\t\t\t%" PRIs_SYSTEM "\n",
764 		 value_string );
765 
766 		memory_free(
767 		 value_string );
768 
769 		value_string = NULL;
770 	}
771 	if( libvslvm_volume_group_get_sequence_number(
772 	     volume_group,
773 	     &value_32bit,
774 	     error ) != 1 )
775 	{
776 		libcerror_error_set(
777 		 error,
778 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
779 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
780 		 "%s: unable to retrive sequence number.",
781 		 function );
782 
783 		goto on_error;
784 	}
785 	fprintf(
786 	 info_handle->notify_stream,
787 	 "\tSequence number:\t\t\t%" PRIu32 "\n",
788 	 value_32bit );
789 
790 	if( libvslvm_volume_group_get_extent_size(
791 	     volume_group,
792 	     &extent_size,
793 	     error ) != 1 )
794 	{
795 		libcerror_error_set(
796 		 error,
797 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
798 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
799 		 "%s: unable to retrieve extent size.",
800 		 function );
801 
802 		goto on_error;
803 	}
804 	result = byte_size_string_create(
805 	          extent_size_string,
806 	          16,
807 	          extent_size,
808 	          BYTE_SIZE_STRING_UNIT_MEBIBYTE,
809 	          NULL );
810 
811 	if( result == 1 )
812 	{
813 		fprintf(
814 		 info_handle->notify_stream,
815 		 "\tExtent size:\t\t\t\t%" PRIs_SYSTEM " (%" PRIu64 " bytes)\n",
816 		 extent_size_string,
817 		 extent_size );
818 	}
819 	else
820 	{
821 		fprintf(
822 		 info_handle->notify_stream,
823 		 "\tExtent size:\t\t\t\t%" PRIu64 " bytes\n",
824 		 extent_size );
825 	}
826 	if( libvslvm_volume_group_get_number_of_physical_volumes(
827 	     volume_group,
828 	     &number_of_physical_volumes,
829 	     error ) != 1 )
830 	{
831 		libcerror_error_set(
832 		 error,
833 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
834 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
835 		 "%s: unable to retrieve number of physical volumes.",
836 		 function );
837 
838 		goto on_error;
839 	}
840 	fprintf(
841 	 info_handle->notify_stream,
842 	 "\tNumber of physical volumes:\t\t%d\n",
843 	 number_of_physical_volumes );
844 
845 	if( libvslvm_volume_group_get_number_of_logical_volumes(
846 	     volume_group,
847 	     &number_of_logical_volumes,
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 number of logical volumes.",
855 		 function );
856 
857 		goto on_error;
858 	}
859 	fprintf(
860 	 info_handle->notify_stream,
861 	 "\tNumber of logical volumes:\t\t%d\n",
862 	 number_of_logical_volumes );
863 
864 	fprintf(
865 	 info_handle->notify_stream,
866 	 "\n" );
867 
868 	for( volume_index = 0;
869 	     volume_index < number_of_physical_volumes;
870 	     volume_index++ )
871 	{
872 		if( libvslvm_volume_group_get_physical_volume(
873 		     volume_group,
874 		     volume_index,
875 		     &physical_volume,
876 		     error ) != 1 )
877 		{
878 			libcerror_error_set(
879 			 error,
880 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
881 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
882 			 "%s: unable to retrieve physical volume: %d.",
883 			 function,
884 			 volume_index );
885 
886 			goto on_error;
887 		}
888 		if( info_handle_physical_volume_fprint(
889 		     info_handle,
890 		     volume_index,
891 		     physical_volume,
892 		     error ) != 1 )
893 		{
894 			libcerror_error_set(
895 			 error,
896 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
897 			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
898 			 "%s: unable to print physical volume: %d information.",
899 			 function,
900 			 volume_index );
901 
902 			goto on_error;
903 		}
904 		if( libvslvm_physical_volume_free(
905 		     &physical_volume,
906 		     error ) != 1 )
907 		{
908 			libcerror_error_set(
909 			 error,
910 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
911 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
912 			 "%s: unable to free physical volume: %d.",
913 			 function,
914 			 volume_index );
915 
916 			goto on_error;
917 		}
918 	}
919 	for( volume_index = 0;
920 	     volume_index < number_of_logical_volumes;
921 	     volume_index++ )
922 	{
923 		if( libvslvm_volume_group_get_logical_volume(
924 		     volume_group,
925 		     volume_index,
926 		     &logical_volume,
927 		     error ) != 1 )
928 		{
929 			libcerror_error_set(
930 			 error,
931 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
932 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
933 			 "%s: unable to retrieve logical volume: %d.",
934 			 function,
935 			 volume_index );
936 
937 			goto on_error;
938 		}
939 		if( info_handle_logical_volume_fprint(
940 		     info_handle,
941 		     volume_index,
942 		     logical_volume,
943 		     error ) != 1 )
944 		{
945 			libcerror_error_set(
946 			 error,
947 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
948 			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
949 			 "%s: unable to print logical volume: %d information.",
950 			 function,
951 			 volume_index );
952 
953 			goto on_error;
954 		}
955 		if( libvslvm_logical_volume_free(
956 		     &logical_volume,
957 		     error ) != 1 )
958 		{
959 			libcerror_error_set(
960 			 error,
961 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
962 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
963 			 "%s: unable to free logical volume: %d.",
964 			 function,
965 			 volume_index );
966 
967 			goto on_error;
968 		}
969 	}
970 	return( 1 );
971 
972 on_error:
973 	if( logical_volume != NULL )
974 	{
975 		libvslvm_logical_volume_free(
976 		 &logical_volume,
977 		 NULL );
978 	}
979 	if( physical_volume != NULL )
980 	{
981 		libvslvm_physical_volume_free(
982 		 &physical_volume,
983 		 NULL );
984 	}
985 	if( value_string != NULL )
986 	{
987 		memory_free(
988 		 value_string );
989 	}
990 	return( -1 );
991 }
992 
993 /* Prints the physcial volume information
994  * Returns 1 if successful or -1 on error
995  */
info_handle_physical_volume_fprint(info_handle_t * info_handle,int physical_volume_index,libvslvm_physical_volume_t * physical_volume,libcerror_error_t ** error)996 int info_handle_physical_volume_fprint(
997      info_handle_t *info_handle,
998      int physical_volume_index,
999      libvslvm_physical_volume_t *physical_volume,
1000      libcerror_error_t **error )
1001 {
1002 	system_character_t volume_size_string[ 16 ];
1003 
1004 	static char *function    = "info_handle_physical_volume_fprint";
1005 	char *value_string       = NULL;
1006 	size64_t volume_size     = 0;
1007 	size_t value_string_size = 0;
1008 	int result               = 0;
1009 
1010 	if( info_handle == NULL )
1011 	{
1012 		libcerror_error_set(
1013 		 error,
1014 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1015 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1016 		 "%s: invalid info handle.",
1017 		 function );
1018 
1019 		return( -1 );
1020 	}
1021 	fprintf(
1022 	 info_handle->notify_stream,
1023 	 "Physical Volume (PV): %d\n",
1024 	 physical_volume_index + 1 );
1025 
1026 	if( libvslvm_physical_volume_get_name_size(
1027 	     physical_volume,
1028 	     &value_string_size,
1029 	     error ) != 1 )
1030 	{
1031 		libcerror_error_set(
1032 		 error,
1033 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1034 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1035 		 "%s: unable to retrieve name size.",
1036 		 function );
1037 
1038 		goto on_error;
1039 	}
1040 	else if( value_string_size > 0 )
1041 	{
1042 		if( value_string_size > (size_t) SSIZE_MAX )
1043 		{
1044 			libcerror_error_set(
1045 			 error,
1046 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1047 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1048 			 "%s: invalid parent value string size value exceeds maximum.",
1049 			 function );
1050 
1051 			goto on_error;
1052 		}
1053 		value_string = narrow_string_allocate(
1054 		                value_string_size );
1055 
1056 		if( value_string == NULL )
1057 		{
1058 			libcerror_error_set(
1059 			 error,
1060 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1061 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1062 			 "%s: unable to create name string.",
1063 			 function );
1064 
1065 			goto on_error;
1066 		}
1067 		if( libvslvm_physical_volume_get_name(
1068 		     physical_volume,
1069 		     value_string,
1070 		     value_string_size,
1071 		     error ) != 1 )
1072 		{
1073 			libcerror_error_set(
1074 			 error,
1075 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1076 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1077 			 "%s: unable to retrieve name.",
1078 			 function );
1079 
1080 			goto on_error;
1081 		}
1082 		fprintf(
1083 		 info_handle->notify_stream,
1084 		 "\tName:\t\t\t\t\t%" PRIs_SYSTEM "\n",
1085 		 value_string );
1086 
1087 		memory_free(
1088 		 value_string );
1089 
1090 		value_string = NULL;
1091 	}
1092 	if( libvslvm_physical_volume_get_identifier_size(
1093 	     physical_volume,
1094 	     &value_string_size,
1095 	     error ) != 1 )
1096 	{
1097 		libcerror_error_set(
1098 		 error,
1099 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1100 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1101 		 "%s: unable to retrieve identifier size.",
1102 		 function );
1103 
1104 		goto on_error;
1105 	}
1106 	else if( value_string_size > 0 )
1107 	{
1108 		if( value_string_size > (size_t) SSIZE_MAX )
1109 		{
1110 			libcerror_error_set(
1111 			 error,
1112 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1113 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1114 			 "%s: invalid parent value string size value exceeds maximum.",
1115 			 function );
1116 
1117 			goto on_error;
1118 		}
1119 		value_string = narrow_string_allocate(
1120 		                value_string_size );
1121 
1122 		if( value_string == NULL )
1123 		{
1124 			libcerror_error_set(
1125 			 error,
1126 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1127 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1128 			 "%s: unable to create identifier string.",
1129 			 function );
1130 
1131 			goto on_error;
1132 		}
1133 		if( libvslvm_physical_volume_get_identifier(
1134 		     physical_volume,
1135 		     value_string,
1136 		     value_string_size,
1137 		     error ) != 1 )
1138 		{
1139 			libcerror_error_set(
1140 			 error,
1141 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1142 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1143 			 "%s: unable to retrieve identifier.",
1144 			 function );
1145 
1146 			goto on_error;
1147 		}
1148 		fprintf(
1149 		 info_handle->notify_stream,
1150 		 "\tIdentifier:\t\t\t\t%" PRIs_SYSTEM "\n",
1151 		 value_string );
1152 
1153 		memory_free(
1154 		 value_string );
1155 
1156 		value_string = NULL;
1157 	}
1158 	if( libvslvm_physical_volume_get_device_path_size(
1159 	     physical_volume,
1160 	     &value_string_size,
1161 	     error ) != 1 )
1162 	{
1163 		libcerror_error_set(
1164 		 error,
1165 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1166 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1167 		 "%s: unable to retrieve device path size.",
1168 		 function );
1169 
1170 		goto on_error;
1171 	}
1172 	else if( value_string_size > 0 )
1173 	{
1174 		if( value_string_size > (size_t) SSIZE_MAX )
1175 		{
1176 			libcerror_error_set(
1177 			 error,
1178 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1179 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1180 			 "%s: invalid parent value string size value exceeds maximum.",
1181 			 function );
1182 
1183 			goto on_error;
1184 		}
1185 		value_string = narrow_string_allocate(
1186 		                value_string_size );
1187 
1188 		if( value_string == NULL )
1189 		{
1190 			libcerror_error_set(
1191 			 error,
1192 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1193 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1194 			 "%s: unable to create device path string.",
1195 			 function );
1196 
1197 			goto on_error;
1198 		}
1199 		if( libvslvm_physical_volume_get_device_path(
1200 		     physical_volume,
1201 		     value_string,
1202 		     value_string_size,
1203 		     error ) != 1 )
1204 		{
1205 			libcerror_error_set(
1206 			 error,
1207 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1208 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1209 			 "%s: unable to retrieve device path.",
1210 			 function );
1211 
1212 			goto on_error;
1213 		}
1214 		fprintf(
1215 		 info_handle->notify_stream,
1216 		 "\tDevice path:\t\t\t\t%" PRIs_SYSTEM "\n",
1217 		 value_string );
1218 
1219 		memory_free(
1220 		 value_string );
1221 
1222 		value_string = NULL;
1223 	}
1224 	if( libvslvm_physical_volume_get_size(
1225 	     physical_volume,
1226 	     &volume_size,
1227 	     error ) != 1 )
1228 	{
1229 		libcerror_error_set(
1230 		 error,
1231 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1232 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1233 		 "%s: unable to retrieve size.",
1234 		 function );
1235 
1236 		goto on_error;
1237 	}
1238 	result = byte_size_string_create(
1239 	          volume_size_string,
1240 	          16,
1241 	          volume_size,
1242 	          BYTE_SIZE_STRING_UNIT_MEBIBYTE,
1243 	          NULL );
1244 
1245 	if( result == 1 )
1246 	{
1247 		fprintf(
1248 		 info_handle->notify_stream,
1249 		 "\tVolume size:\t\t\t\t%" PRIs_SYSTEM " (%" PRIu64 " bytes)\n",
1250 		 volume_size_string,
1251 		 volume_size );
1252 	}
1253 	else
1254 	{
1255 		fprintf(
1256 		 info_handle->notify_stream,
1257 		 "\tVolume size:\t\t\t\t%" PRIu64 " bytes\n",
1258 		 volume_size );
1259 	}
1260 	fprintf(
1261 	 info_handle->notify_stream,
1262 	 "\n" );
1263 
1264 	return( 1 );
1265 
1266 on_error:
1267 	if( value_string != NULL )
1268 	{
1269 		memory_free(
1270 		 value_string );
1271 	}
1272 	return( -1 );
1273 }
1274 
1275 /* Prints the logical volume information
1276  * Returns 1 if successful or -1 on error
1277  */
info_handle_logical_volume_fprint(info_handle_t * info_handle,int logical_volume_index,libvslvm_logical_volume_t * logical_volume,libcerror_error_t ** error)1278 int info_handle_logical_volume_fprint(
1279      info_handle_t *info_handle,
1280      int logical_volume_index,
1281      libvslvm_logical_volume_t *logical_volume,
1282      libcerror_error_t **error )
1283 {
1284 	libvslvm_segment_t *segment = NULL;
1285 	static char *function       = "info_handle_logical_volume_fprint";
1286 	char *value_string          = NULL;
1287 	size_t value_string_size    = 0;
1288 	int number_of_segments      = 0;
1289 	int segment_index           = 0;
1290 
1291 	if( info_handle == NULL )
1292 	{
1293 		libcerror_error_set(
1294 		 error,
1295 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1296 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1297 		 "%s: invalid info handle.",
1298 		 function );
1299 
1300 		return( -1 );
1301 	}
1302 	fprintf(
1303 	 info_handle->notify_stream,
1304 	 "Logical Volume (LV): %d\n",
1305 	 logical_volume_index + 1 );
1306 
1307 	if( libvslvm_logical_volume_get_name_size(
1308 	     logical_volume,
1309 	     &value_string_size,
1310 	     error ) != 1 )
1311 	{
1312 		libcerror_error_set(
1313 		 error,
1314 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1315 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1316 		 "%s: unable to retrieve name size.",
1317 		 function );
1318 
1319 		goto on_error;
1320 	}
1321 	else if( value_string_size > 0 )
1322 	{
1323 		if( value_string_size > (size_t) SSIZE_MAX )
1324 		{
1325 			libcerror_error_set(
1326 			 error,
1327 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1328 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1329 			 "%s: invalid parent value string size value exceeds maximum.",
1330 			 function );
1331 
1332 			goto on_error;
1333 		}
1334 		value_string = narrow_string_allocate(
1335 		                value_string_size );
1336 
1337 		if( value_string == NULL )
1338 		{
1339 			libcerror_error_set(
1340 			 error,
1341 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1342 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1343 			 "%s: unable to create name string.",
1344 			 function );
1345 
1346 			goto on_error;
1347 		}
1348 		if( libvslvm_logical_volume_get_name(
1349 		     logical_volume,
1350 		     value_string,
1351 		     value_string_size,
1352 		     error ) != 1 )
1353 		{
1354 			libcerror_error_set(
1355 			 error,
1356 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1357 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1358 			 "%s: unable to retrieve name.",
1359 			 function );
1360 
1361 			goto on_error;
1362 		}
1363 		fprintf(
1364 		 info_handle->notify_stream,
1365 		 "\tName:\t\t\t\t\t%" PRIs_SYSTEM "\n",
1366 		 value_string );
1367 
1368 		memory_free(
1369 		 value_string );
1370 
1371 		value_string = NULL;
1372 	}
1373 	if( libvslvm_logical_volume_get_identifier_size(
1374 	     logical_volume,
1375 	     &value_string_size,
1376 	     error ) != 1 )
1377 	{
1378 		libcerror_error_set(
1379 		 error,
1380 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1381 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1382 		 "%s: unable to retrieve identifier size.",
1383 		 function );
1384 
1385 		goto on_error;
1386 	}
1387 	else if( value_string_size > 0 )
1388 	{
1389 		if( value_string_size > (size_t) SSIZE_MAX )
1390 		{
1391 			libcerror_error_set(
1392 			 error,
1393 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1394 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1395 			 "%s: invalid parent value string size value exceeds maximum.",
1396 			 function );
1397 
1398 			goto on_error;
1399 		}
1400 		value_string = narrow_string_allocate(
1401 		                value_string_size );
1402 
1403 		if( value_string == NULL )
1404 		{
1405 			libcerror_error_set(
1406 			 error,
1407 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1408 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1409 			 "%s: unable to create identifier string.",
1410 			 function );
1411 
1412 			goto on_error;
1413 		}
1414 		if( libvslvm_logical_volume_get_identifier(
1415 		     logical_volume,
1416 		     value_string,
1417 		     value_string_size,
1418 		     error ) != 1 )
1419 		{
1420 			libcerror_error_set(
1421 			 error,
1422 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1423 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1424 			 "%s: unable to retrieve identifier.",
1425 			 function );
1426 
1427 			goto on_error;
1428 		}
1429 		fprintf(
1430 		 info_handle->notify_stream,
1431 		 "\tIdentifier:\t\t\t\t%" PRIs_SYSTEM "\n",
1432 		 value_string );
1433 
1434 		memory_free(
1435 		 value_string );
1436 
1437 		value_string = NULL;
1438 	}
1439 	if( libvslvm_logical_volume_get_number_of_segments(
1440 	     logical_volume,
1441 	     &number_of_segments,
1442 	     error ) != 1 )
1443 	{
1444 		libcerror_error_set(
1445 		 error,
1446 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1447 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1448 		 "%s: unable to retrieve number of segments.",
1449 		 function );
1450 
1451 		goto on_error;
1452 	}
1453 	fprintf(
1454 	 info_handle->notify_stream,
1455 	 "\tNumber of segments:\t\t\t%d\n",
1456 	 number_of_segments );
1457 
1458 	for( segment_index = 0;
1459 	     segment_index < number_of_segments;
1460 	     segment_index++ )
1461 	{
1462 		if( libvslvm_logical_volume_get_segment(
1463 		     logical_volume,
1464 		     segment_index,
1465 		     &segment,
1466 		     error ) != 1 )
1467 		{
1468 			libcerror_error_set(
1469 			 error,
1470 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1471 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1472 			 "%s: unable to retrieve segment: %d.",
1473 			 function,
1474 			 segment_index );
1475 
1476 			goto on_error;
1477 		}
1478 		if( info_handle_segment_fprint(
1479 		     info_handle,
1480 		     segment_index,
1481 		     segment,
1482 		     error ) != 1 )
1483 		{
1484 			libcerror_error_set(
1485 			 error,
1486 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1487 			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1488 			 "%s: unable to print segment: %d information.",
1489 			 function,
1490 			 segment_index );
1491 
1492 			goto on_error;
1493 		}
1494 		if( libvslvm_segment_free(
1495 		     &segment,
1496 		     error ) != 1 )
1497 		{
1498 			libcerror_error_set(
1499 			 error,
1500 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1501 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1502 			 "%s: unable to free segment: %d.",
1503 			 function,
1504 			 segment_index );
1505 
1506 			goto on_error;
1507 		}
1508 	}
1509 	return( 1 );
1510 
1511 on_error:
1512 	if( segment != NULL )
1513 	{
1514 		libvslvm_segment_free(
1515 		 &segment,
1516 		 NULL );
1517 	}
1518 	if( value_string != NULL )
1519 	{
1520 		memory_free(
1521 		 value_string );
1522 	}
1523 	if( value_string != NULL )
1524 	{
1525 		memory_free(
1526 		 value_string );
1527 	}
1528 	return( -1 );
1529 }
1530 
1531 /* Prints the segment information
1532  * Returns 1 if successful or -1 on error
1533  */
info_handle_segment_fprint(info_handle_t * info_handle,int segment_index,libvslvm_segment_t * segment,libcerror_error_t ** error)1534 int info_handle_segment_fprint(
1535      info_handle_t *info_handle,
1536      int segment_index,
1537      libvslvm_segment_t *segment,
1538      libcerror_error_t **error )
1539 {
1540 	system_character_t segment_size_string[ 16 ];
1541 
1542 	libvslvm_stripe_t *stripe = NULL;
1543 	static char *function     = "info_handle_segment_fprint";
1544 	off64_t segment_offset    = 0;
1545 	size64_t segment_size     = 0;
1546 	int number_of_stripes     = 0;
1547 	int result                = 0;
1548 	int stripe_index          = 0;
1549 
1550 	if( info_handle == NULL )
1551 	{
1552 		libcerror_error_set(
1553 		 error,
1554 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1555 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1556 		 "%s: invalid info handle.",
1557 		 function );
1558 
1559 		return( -1 );
1560 	}
1561 	fprintf(
1562 	 info_handle->notify_stream,
1563 	 "\tSegment: %d\n",
1564 	 segment_index + 1 );
1565 
1566 	if( libvslvm_segment_get_offset(
1567 	     segment,
1568 	     &segment_offset,
1569 	     error ) != 1 )
1570 	{
1571 		libcerror_error_set(
1572 		 error,
1573 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1574 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1575 		 "%s: unable to retrieve offset.",
1576 		 function );
1577 
1578 		goto on_error;
1579 	}
1580 	fprintf(
1581 	 info_handle->notify_stream,
1582 	 "\t\tOffset:\t\t\t\t0x%08" PRIx64 " (%" PRIi64 ")\n",
1583 	 segment_offset,
1584 	 segment_offset );
1585 
1586 	if( libvslvm_segment_get_size(
1587 	     segment,
1588 	     &segment_size,
1589 	     error ) != 1 )
1590 	{
1591 		libcerror_error_set(
1592 		 error,
1593 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1594 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1595 		 "%s: unable to retrieve size.",
1596 		 function );
1597 
1598 		goto on_error;
1599 	}
1600 	result = byte_size_string_create(
1601 	          segment_size_string,
1602 	          16,
1603 	          segment_size,
1604 	          BYTE_SIZE_STRING_UNIT_MEBIBYTE,
1605 	          NULL );
1606 
1607 	if( result == 1 )
1608 	{
1609 		fprintf(
1610 		 info_handle->notify_stream,
1611 		 "\t\tSize:\t\t\t\t%" PRIs_SYSTEM " (%" PRIu64 " bytes)\n",
1612 		 segment_size_string,
1613 		 segment_size );
1614 	}
1615 	else
1616 	{
1617 		fprintf(
1618 		 info_handle->notify_stream,
1619 		 "\t\tSize:\t\t\t\t%" PRIu64 " bytes\n",
1620 		 segment_size );
1621 	}
1622 	if( libvslvm_segment_get_number_of_stripes(
1623 	     segment,
1624 	     &number_of_stripes,
1625 	     error ) != 1 )
1626 	{
1627 		libcerror_error_set(
1628 		 error,
1629 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1630 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1631 		 "%s: unable to retrieve number of stripes.",
1632 		 function );
1633 
1634 		goto on_error;
1635 	}
1636 	fprintf(
1637 	 info_handle->notify_stream,
1638 	 "\t\tNumber of stripes:\t\t%d\n",
1639 	 number_of_stripes );
1640 
1641 	for( stripe_index = 0;
1642 	     stripe_index < number_of_stripes;
1643 	     stripe_index++ )
1644 	{
1645 		if( libvslvm_segment_get_stripe(
1646 		     segment,
1647 		     stripe_index,
1648 		     &stripe,
1649 		     error ) != 1 )
1650 		{
1651 			libcerror_error_set(
1652 			 error,
1653 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1654 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1655 			 "%s: unable to retrieve stripe: %d.",
1656 			 function,
1657 			 stripe_index );
1658 
1659 			goto on_error;
1660 		}
1661 		if( info_handle_stripe_fprint(
1662 		     info_handle,
1663 		     stripe_index,
1664 		     stripe,
1665 		     error ) != 1 )
1666 		{
1667 			libcerror_error_set(
1668 			 error,
1669 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1670 			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1671 			 "%s: unable to print stripe: %d information.",
1672 			 function,
1673 			 stripe_index );
1674 
1675 			goto on_error;
1676 		}
1677 		if( libvslvm_stripe_free(
1678 		     &stripe,
1679 		     error ) != 1 )
1680 		{
1681 			libcerror_error_set(
1682 			 error,
1683 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1684 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1685 			 "%s: unable to free stripe: %d.",
1686 			 function,
1687 			 stripe_index );
1688 
1689 			goto on_error;
1690 		}
1691 	}
1692 	return( 1 );
1693 
1694 on_error:
1695 	if( stripe != NULL )
1696 	{
1697 		libvslvm_stripe_free(
1698 		 &stripe,
1699 		 NULL );
1700 	}
1701 	return( -1 );
1702 }
1703 
1704 /* Prints the stripe information
1705  * Returns 1 if successful or -1 on error
1706  */
info_handle_stripe_fprint(info_handle_t * info_handle,int stripe_index,libvslvm_stripe_t * stripe,libcerror_error_t ** error)1707 int info_handle_stripe_fprint(
1708      info_handle_t *info_handle,
1709      int stripe_index,
1710      libvslvm_stripe_t *stripe,
1711      libcerror_error_t **error )
1712 {
1713 	static char *function    = "info_handle_stripe_fprint";
1714 	char *value_string       = NULL;
1715 	size_t value_string_size = 0;
1716 	off64_t data_area_offset = 0;
1717 
1718 	if( info_handle == NULL )
1719 	{
1720 		libcerror_error_set(
1721 		 error,
1722 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1723 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1724 		 "%s: invalid info handle.",
1725 		 function );
1726 
1727 		return( -1 );
1728 	}
1729 	fprintf(
1730 	 info_handle->notify_stream,
1731 	 "\t\tStripe: %d\n",
1732 	 stripe_index + 1 );
1733 
1734 	if( libvslvm_stripe_get_physical_volume_name_size(
1735 	     stripe,
1736 	     &value_string_size,
1737 	     error ) != 1 )
1738 	{
1739 		libcerror_error_set(
1740 		 error,
1741 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1742 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1743 		 "%s: unable to retrieve physical volume name size.",
1744 		 function );
1745 
1746 		goto on_error;
1747 	}
1748 	else if( value_string_size > 0 )
1749 	{
1750 		if( value_string_size > (size_t) SSIZE_MAX )
1751 		{
1752 			libcerror_error_set(
1753 			 error,
1754 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1755 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1756 			 "%s: invalid parent value string size value exceeds maximum.",
1757 			 function );
1758 
1759 			goto on_error;
1760 		}
1761 		value_string = narrow_string_allocate(
1762 		                value_string_size );
1763 
1764 		if( value_string == NULL )
1765 		{
1766 			libcerror_error_set(
1767 			 error,
1768 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1769 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1770 			 "%s: unable to create physical volume name string.",
1771 			 function );
1772 
1773 			goto on_error;
1774 		}
1775 		if( libvslvm_stripe_get_physical_volume_name(
1776 		     stripe,
1777 		     value_string,
1778 		     value_string_size,
1779 		     error ) != 1 )
1780 		{
1781 			libcerror_error_set(
1782 			 error,
1783 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1784 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1785 			 "%s: unable to retrieve physical volume name.",
1786 			 function );
1787 
1788 			goto on_error;
1789 		}
1790 		fprintf(
1791 		 info_handle->notify_stream,
1792 		 "\t\t\tPhysical volume:\t%" PRIs_SYSTEM "\n",
1793 		 value_string );
1794 
1795 		memory_free(
1796 		 value_string );
1797 
1798 		value_string = NULL;
1799 	}
1800 	if( libvslvm_stripe_get_data_area_offset(
1801 	     stripe,
1802 	     &data_area_offset,
1803 	     error ) != 1 )
1804 	{
1805 		libcerror_error_set(
1806 		 error,
1807 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1808 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1809 		 "%s: unable to retrieve data area offset.",
1810 		 function );
1811 
1812 		goto on_error;
1813 	}
1814 	fprintf(
1815 	 info_handle->notify_stream,
1816 	 "\t\t\tData area offset:\t0x%08" PRIx64 " (%" PRIi64 ")\n",
1817 	 data_area_offset,
1818 	 data_area_offset );
1819 
1820 	fprintf(
1821 	 info_handle->notify_stream,
1822 	 "\n" );
1823 
1824 	return( 1 );
1825 
1826 on_error:
1827 	if( value_string != NULL )
1828 	{
1829 		memory_free(
1830 		 value_string );
1831 	}
1832 	return( -1 );
1833 }
1834 
1835 /* Prints the information
1836  * Returns 1 if successful or -1 on error
1837  */
info_handle_fprint(info_handle_t * info_handle,libcerror_error_t ** error)1838 int info_handle_fprint(
1839      info_handle_t *info_handle,
1840      libcerror_error_t **error )
1841 {
1842 	libvslvm_volume_group_t *volume_group = NULL;
1843 	static char *function                 = "info_handle_fprint";
1844 
1845 	if( info_handle == NULL )
1846 	{
1847 		libcerror_error_set(
1848 		 error,
1849 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1850 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1851 		 "%s: invalid info handle.",
1852 		 function );
1853 
1854 		return( -1 );
1855 	}
1856 	fprintf(
1857 	 info_handle->notify_stream,
1858 	 "Linux Logical Volume Manager (LVM) information:\n" );
1859 
1860 	if( libvslvm_handle_get_volume_group(
1861 	     info_handle->input_handle,
1862 	     &volume_group,
1863 	     error ) != 1 )
1864 	{
1865 		libcerror_error_set(
1866 		 error,
1867 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1868 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1869 		 "%s: unable to retrieve volume group.",
1870 		 function );
1871 
1872 		goto on_error;
1873 	}
1874 	if( info_handle_volume_group_fprint(
1875 	     info_handle,
1876 	     volume_group,
1877 	     error ) != 1 )
1878 	{
1879 		libcerror_error_set(
1880 		 error,
1881 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1882 		 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1883 		 "%s: unable to print volume group information.",
1884 		 function );
1885 
1886 		goto on_error;
1887 	}
1888 	if( libvslvm_volume_group_free(
1889 	     &volume_group,
1890 	     error ) != 1 )
1891 	{
1892 		libcerror_error_set(
1893 		 error,
1894 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1895 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1896 		 "%s: unable to free volume group.",
1897 		 function );
1898 
1899 		goto on_error;
1900 	}
1901 	return( 1 );
1902 
1903 on_error:
1904 	if( volume_group != NULL )
1905 	{
1906 		libvslvm_volume_group_free(
1907 		 &volume_group,
1908 		 NULL );
1909 	}
1910 	return( -1 );
1911 }
1912 
1913