1 /*
2 * Python object wrapper of libvslvm_logical_volume_t
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 <types.h>
24
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28
29 #include "pyvslvm_error.h"
30 #include "pyvslvm_integer.h"
31 #include "pyvslvm_libcerror.h"
32 #include "pyvslvm_libvslvm.h"
33 #include "pyvslvm_logical_volume.h"
34 #include "pyvslvm_python.h"
35 #include "pyvslvm_segment.h"
36 #include "pyvslvm_segments.h"
37 #include "pyvslvm_unused.h"
38 #include "pyvslvm_volume_group.h"
39
40 PyMethodDef pyvslvm_logical_volume_object_methods[] = {
41
42 /* Functions to access the logical volume data */
43
44 { "read_buffer",
45 (PyCFunction) pyvslvm_logical_volume_read_buffer,
46 METH_VARARGS | METH_KEYWORDS,
47 "read_buffer(size) -> String\n"
48 "\n"
49 "Reads a buffer of data." },
50
51 { "read_buffer_at_offset",
52 (PyCFunction) pyvslvm_logical_volume_read_buffer_at_offset,
53 METH_VARARGS | METH_KEYWORDS,
54 "read_buffer_at_offset(size, offset) -> String\n"
55 "\n"
56 "Reads a buffer of data at a specific offset." },
57
58 { "seek_offset",
59 (PyCFunction) pyvslvm_logical_volume_seek_offset,
60 METH_VARARGS | METH_KEYWORDS,
61 "seek_offset(offset, whence) -> None\n"
62 "\n"
63 "Seeks an offset within the data." },
64
65 { "get_offset",
66 (PyCFunction) pyvslvm_logical_volume_get_offset,
67 METH_NOARGS,
68 "get_offset() -> Integer\n"
69 "\n"
70 "Retrieves the current offset within the data." },
71
72 /* Some Pythonesque aliases */
73
74 { "read",
75 (PyCFunction) pyvslvm_logical_volume_read_buffer,
76 METH_VARARGS | METH_KEYWORDS,
77 "read(size) -> String\n"
78 "\n"
79 "Reads a buffer of data." },
80
81 { "seek",
82 (PyCFunction) pyvslvm_logical_volume_seek_offset,
83 METH_VARARGS | METH_KEYWORDS,
84 "seek(offset, whence) -> None\n"
85 "\n"
86 "Seeks an offset within the data." },
87
88 { "tell",
89 (PyCFunction) pyvslvm_logical_volume_get_offset,
90 METH_NOARGS,
91 "tell() -> Integer\n"
92 "\n"
93 "Retrieves the current offset within the data." },
94
95 /* Functions to access the logical volume values */
96
97 { "get_size",
98 (PyCFunction) pyvslvm_logical_volume_get_size,
99 METH_NOARGS,
100 "get_size() -> Integer\n"
101 "\n"
102 "Retrieves the size of the volume." },
103
104 { "get_name",
105 (PyCFunction) pyvslvm_logical_volume_get_name,
106 METH_NOARGS,
107 "get_name() -> Unicode string or None\n"
108 "\n"
109 "Retrieves the name." },
110
111 { "get_identifier",
112 (PyCFunction) pyvslvm_logical_volume_get_identifier,
113 METH_NOARGS,
114 "get_identifier() -> Unicode string or None\n"
115 "\n"
116 "Retrieves the identifier." },
117
118 /* Functions to access the segments */
119
120 { "get_number_of_segments",
121 (PyCFunction) pyvslvm_logical_volume_get_number_of_segments,
122 METH_NOARGS,
123 "get_number_of_segments() -> Integer\n"
124 "\n"
125 "Retrieves the number of segments." },
126
127 { "get_segment",
128 (PyCFunction) pyvslvm_logical_volume_get_segment,
129 METH_VARARGS | METH_KEYWORDS,
130 "get_segment(segment_index) -> Object or None\n"
131 "\n"
132 "Retrieves a specific segment." },
133
134 { "get_segments",
135 (PyCFunction) pyvslvm_logical_volume_get_segments,
136 METH_VARARGS | METH_KEYWORDS,
137 "get_segments() -> Object\n"
138 "\n"
139 "Retrieves a sequence object of the segments." },
140
141 /* Sentinel */
142 { NULL, NULL, 0, NULL }
143 };
144
145 PyGetSetDef pyvslvm_logical_volume_object_get_set_definitions[] = {
146
147 { "size",
148 (getter) pyvslvm_logical_volume_get_size,
149 (setter) 0,
150 "The volume size.",
151 NULL },
152
153 { "name",
154 (getter) pyvslvm_logical_volume_get_name,
155 (setter) 0,
156 "The name.",
157 NULL },
158
159 { "identifier",
160 (getter) pyvslvm_logical_volume_get_identifier,
161 (setter) 0,
162 "The identifier.",
163 NULL },
164
165 { "number_of_segments",
166 (getter) pyvslvm_logical_volume_get_number_of_segments,
167 (setter) 0,
168 "The number of segments.",
169 NULL },
170
171 { "segments",
172 (getter) pyvslvm_logical_volume_get_segments,
173 (setter) 0,
174 "The segments.",
175 NULL },
176
177 /* Sentinel */
178 { NULL, NULL, NULL, NULL, NULL }
179 };
180
181 PyTypeObject pyvslvm_logical_volume_type_object = {
182 PyVarObject_HEAD_INIT( NULL, 0 )
183
184 /* tp_name */
185 "pyvslvm.logical_volume",
186 /* tp_basicsize */
187 sizeof( pyvslvm_logical_volume_t ),
188 /* tp_itemsize */
189 0,
190 /* tp_dealloc */
191 (destructor) pyvslvm_logical_volume_free,
192 /* tp_print */
193 0,
194 /* tp_getattr */
195 0,
196 /* tp_setattr */
197 0,
198 /* tp_compare */
199 0,
200 /* tp_repr */
201 0,
202 /* tp_as_number */
203 0,
204 /* tp_as_sequence */
205 0,
206 /* tp_as_mapping */
207 0,
208 /* tp_hash */
209 0,
210 /* tp_call */
211 0,
212 /* tp_str */
213 0,
214 /* tp_getattro */
215 0,
216 /* tp_setattro */
217 0,
218 /* tp_as_buffer */
219 0,
220 /* tp_flags */
221 Py_TPFLAGS_DEFAULT,
222 /* tp_doc */
223 "pyvslvm logical volume object (wraps libvslvm_logical_volume_t)",
224 /* tp_traverse */
225 0,
226 /* tp_clear */
227 0,
228 /* tp_richcompare */
229 0,
230 /* tp_weaklistoffset */
231 0,
232 /* tp_iter */
233 0,
234 /* tp_iternext */
235 0,
236 /* tp_methods */
237 pyvslvm_logical_volume_object_methods,
238 /* tp_members */
239 0,
240 /* tp_getset */
241 pyvslvm_logical_volume_object_get_set_definitions,
242 /* tp_base */
243 0,
244 /* tp_dict */
245 0,
246 /* tp_descr_get */
247 0,
248 /* tp_descr_set */
249 0,
250 /* tp_dictoffset */
251 0,
252 /* tp_init */
253 (initproc) pyvslvm_logical_volume_init,
254 /* tp_alloc */
255 0,
256 /* tp_new */
257 0,
258 /* tp_free */
259 0,
260 /* tp_is_gc */
261 0,
262 /* tp_bases */
263 NULL,
264 /* tp_mro */
265 NULL,
266 /* tp_cache */
267 NULL,
268 /* tp_subclasses */
269 NULL,
270 /* tp_weaklist */
271 NULL,
272 /* tp_del */
273 0
274 };
275
276 /* Creates a new logical volume object
277 * Returns a Python object if successful or NULL on error
278 */
pyvslvm_logical_volume_new(libvslvm_logical_volume_t * logical_volume,pyvslvm_volume_group_t * volume_group_object)279 PyObject *pyvslvm_logical_volume_new(
280 libvslvm_logical_volume_t *logical_volume,
281 pyvslvm_volume_group_t *volume_group_object )
282 {
283 pyvslvm_logical_volume_t *pyvslvm_logical_volume = NULL;
284 static char *function = "pyvslvm_logical_volume_new";
285
286 if( logical_volume == NULL )
287 {
288 PyErr_Format(
289 PyExc_TypeError,
290 "%s: invalid logical volume.",
291 function );
292
293 return( NULL );
294 }
295 pyvslvm_logical_volume = PyObject_New(
296 struct pyvslvm_logical_volume,
297 &pyvslvm_logical_volume_type_object );
298
299 if( pyvslvm_logical_volume == NULL )
300 {
301 PyErr_Format(
302 PyExc_MemoryError,
303 "%s: unable to initialize logical volume.",
304 function );
305
306 goto on_error;
307 }
308 if( pyvslvm_logical_volume_init(
309 pyvslvm_logical_volume ) != 0 )
310 {
311 PyErr_Format(
312 PyExc_MemoryError,
313 "%s: unable to initialize logical volume.",
314 function );
315
316 goto on_error;
317 }
318 pyvslvm_logical_volume->logical_volume = logical_volume;
319 pyvslvm_logical_volume->volume_group_object = volume_group_object;
320
321 Py_IncRef(
322 (PyObject *) pyvslvm_logical_volume->volume_group_object );
323
324 return( (PyObject *) pyvslvm_logical_volume );
325
326 on_error:
327 if( pyvslvm_logical_volume != NULL )
328 {
329 Py_DecRef(
330 (PyObject *) pyvslvm_logical_volume );
331 }
332 return( NULL );
333 }
334
335 /* Initializes a logical volume object
336 * Returns 0 if successful or -1 on error
337 */
pyvslvm_logical_volume_init(pyvslvm_logical_volume_t * pyvslvm_logical_volume)338 int pyvslvm_logical_volume_init(
339 pyvslvm_logical_volume_t *pyvslvm_logical_volume )
340 {
341 static char *function = "pyvslvm_logical_volume_init";
342
343 if( pyvslvm_logical_volume == NULL )
344 {
345 PyErr_Format(
346 PyExc_TypeError,
347 "%s: invalid logical volume.",
348 function );
349
350 return( -1 );
351 }
352 /* Make sure libvslvm logical volume is set to NULL
353 */
354 pyvslvm_logical_volume->logical_volume = NULL;
355
356 return( 0 );
357 }
358
359 /* Frees a logical volume object
360 */
pyvslvm_logical_volume_free(pyvslvm_logical_volume_t * pyvslvm_logical_volume)361 void pyvslvm_logical_volume_free(
362 pyvslvm_logical_volume_t *pyvslvm_logical_volume )
363 {
364 libcerror_error_t *error = NULL;
365 struct _typeobject *ob_type = NULL;
366 static char *function = "pyvslvm_logical_volume_free";
367
368 if( pyvslvm_logical_volume == NULL )
369 {
370 PyErr_Format(
371 PyExc_TypeError,
372 "%s: invalid logical volume.",
373 function );
374
375 return;
376 }
377 if( pyvslvm_logical_volume->logical_volume == NULL )
378 {
379 PyErr_Format(
380 PyExc_TypeError,
381 "%s: invalid logical volume - missing libvslvm logical volume.",
382 function );
383
384 return;
385 }
386 ob_type = Py_TYPE(
387 pyvslvm_logical_volume );
388
389 if( ob_type == NULL )
390 {
391 PyErr_Format(
392 PyExc_ValueError,
393 "%s: missing ob_type.",
394 function );
395
396 return;
397 }
398 if( ob_type->tp_free == NULL )
399 {
400 PyErr_Format(
401 PyExc_ValueError,
402 "%s: invalid ob_type - missing tp_free.",
403 function );
404
405 return;
406 }
407 if( libvslvm_logical_volume_free(
408 &( pyvslvm_logical_volume->logical_volume ),
409 &error ) != 1 )
410 {
411 pyvslvm_error_raise(
412 error,
413 PyExc_IOError,
414 "%s: unable to free libvslvm logical volume.",
415 function );
416
417 libcerror_error_free(
418 &error );
419 }
420 if( pyvslvm_logical_volume->volume_group_object != NULL )
421 {
422 Py_DecRef(
423 (PyObject *) pyvslvm_logical_volume->volume_group_object );
424 }
425 ob_type->tp_free(
426 (PyObject*) pyvslvm_logical_volume );
427 }
428
429 /* Reads data at the current offset into a buffer
430 * Returns a Python object if successful or NULL on error
431 */
pyvslvm_logical_volume_read_buffer(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments,PyObject * keywords)432 PyObject *pyvslvm_logical_volume_read_buffer(
433 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
434 PyObject *arguments,
435 PyObject *keywords )
436 {
437 libcerror_error_t *error = NULL;
438 PyObject *string_object = NULL;
439 static char *function = "pyvslvm_logical_volume_read_buffer";
440 static char *keyword_list[] = { "size", NULL };
441 char *buffer = NULL;
442 ssize_t read_count = 0;
443 int read_size = -1;
444
445 if( pyvslvm_logical_volume == NULL )
446 {
447 PyErr_Format(
448 PyExc_TypeError,
449 "%s: invalid pyvslvm logical volume.",
450 function );
451
452 return( NULL );
453 }
454 if( PyArg_ParseTupleAndKeywords(
455 arguments,
456 keywords,
457 "|i",
458 keyword_list,
459 &read_size ) == 0 )
460 {
461 return( NULL );
462 }
463 if( read_size < 0 )
464 {
465 PyErr_Format(
466 PyExc_ValueError,
467 "%s: invalid argument read size value less than zero.",
468 function );
469
470 return( NULL );
471 }
472 /* Make sure the data fits into the memory buffer
473 */
474 if( read_size > INT_MAX )
475 {
476 PyErr_Format(
477 PyExc_ValueError,
478 "%s: invalid argument read size value exceeds maximum.",
479 function );
480
481 return( NULL );
482 }
483 #if PY_MAJOR_VERSION >= 3
484 string_object = PyBytes_FromStringAndSize(
485 NULL,
486 read_size );
487
488 buffer = PyBytes_AsString(
489 string_object );
490 #else
491 string_object = PyString_FromStringAndSize(
492 NULL,
493 read_size );
494
495 buffer = PyString_AsString(
496 string_object );
497 #endif
498 Py_BEGIN_ALLOW_THREADS
499
500 read_count = libvslvm_logical_volume_read_buffer(
501 pyvslvm_logical_volume->logical_volume,
502 (uint8_t *) buffer,
503 (size_t) read_size,
504 &error );
505
506 Py_END_ALLOW_THREADS
507
508 if( read_count <= -1 )
509 {
510 pyvslvm_error_raise(
511 error,
512 PyExc_IOError,
513 "%s: unable to read data.",
514 function );
515
516 libcerror_error_free(
517 &error );
518
519 Py_DecRef(
520 (PyObject *) string_object );
521
522 return( NULL );
523 }
524 /* Need to resize the string here in case read_size was not fully read.
525 */
526 #if PY_MAJOR_VERSION >= 3
527 if( _PyBytes_Resize(
528 &string_object,
529 (Py_ssize_t) read_count ) != 0 )
530 #else
531 if( _PyString_Resize(
532 &string_object,
533 (Py_ssize_t) read_count ) != 0 )
534 #endif
535 {
536 Py_DecRef(
537 (PyObject *) string_object );
538
539 return( NULL );
540 }
541 return( string_object );
542 }
543
544 /* Reads data at a specific offset
545 * Returns a Python object if successful or NULL on error
546 */
pyvslvm_logical_volume_read_buffer_at_offset(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments,PyObject * keywords)547 PyObject *pyvslvm_logical_volume_read_buffer_at_offset(
548 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
549 PyObject *arguments,
550 PyObject *keywords )
551 {
552 libcerror_error_t *error = NULL;
553 PyObject *string_object = NULL;
554 static char *function = "pyvslvm_logical_volume_read_buffer_at_offset";
555 static char *keyword_list[] = { "size", "offset", NULL };
556 char *buffer = NULL;
557 off64_t read_offset = 0;
558 ssize_t read_count = 0;
559 int read_size = 0;
560
561 if( pyvslvm_logical_volume == NULL )
562 {
563 PyErr_Format(
564 PyExc_TypeError,
565 "%s: invalid pyvslvm logical volume.",
566 function );
567
568 return( NULL );
569 }
570 if( PyArg_ParseTupleAndKeywords(
571 arguments,
572 keywords,
573 "i|L",
574 keyword_list,
575 &read_size,
576 &read_offset ) == 0 )
577 {
578 return( NULL );
579 }
580 if( read_size < 0 )
581 {
582 PyErr_Format(
583 PyExc_ValueError,
584 "%s: invalid argument read size value less than zero.",
585 function );
586
587 return( NULL );
588 }
589 /* Make sure the data fits into the memory buffer
590 */
591 if( read_size > INT_MAX )
592 {
593 PyErr_Format(
594 PyExc_ValueError,
595 "%s: invalid argument read size value exceeds maximum.",
596 function );
597
598 return( NULL );
599 }
600 if( read_offset < 0 )
601 {
602 PyErr_Format(
603 PyExc_ValueError,
604 "%s: invalid argument read offset value less than zero.",
605 function );
606
607 return( NULL );
608 }
609 /* Make sure the data fits into the memory buffer
610 */
611 #if PY_MAJOR_VERSION >= 3
612 string_object = PyBytes_FromStringAndSize(
613 NULL,
614 read_size );
615
616 buffer = PyBytes_AsString(
617 string_object );
618 #else
619 string_object = PyString_FromStringAndSize(
620 NULL,
621 read_size );
622
623 buffer = PyString_AsString(
624 string_object );
625 #endif
626 Py_BEGIN_ALLOW_THREADS
627
628 read_count = libvslvm_logical_volume_read_buffer_at_offset(
629 pyvslvm_logical_volume->logical_volume,
630 (uint8_t *) buffer,
631 (size_t) read_size,
632 (off64_t) read_offset,
633 &error );
634
635 Py_END_ALLOW_THREADS
636
637 if( read_count <= -1 )
638 {
639 pyvslvm_error_raise(
640 error,
641 PyExc_IOError,
642 "%s: unable to read data.",
643 function );
644
645 libcerror_error_free(
646 &error );
647
648 Py_DecRef(
649 (PyObject *) string_object );
650
651 return( NULL );
652 }
653 /* Need to resize the string here in case read_size was not fully read.
654 */
655 #if PY_MAJOR_VERSION >= 3
656 if( _PyBytes_Resize(
657 &string_object,
658 (Py_ssize_t) read_count ) != 0 )
659 #else
660 if( _PyString_Resize(
661 &string_object,
662 (Py_ssize_t) read_count ) != 0 )
663 #endif
664 {
665 Py_DecRef(
666 (PyObject *) string_object );
667
668 return( NULL );
669 }
670 return( string_object );
671 }
672
673 /* Seeks a certain offset in the data
674 * Returns a Python object if successful or NULL on error
675 */
pyvslvm_logical_volume_seek_offset(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments,PyObject * keywords)676 PyObject *pyvslvm_logical_volume_seek_offset(
677 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
678 PyObject *arguments,
679 PyObject *keywords )
680 {
681 libcerror_error_t *error = NULL;
682 static char *function = "pyvslvm_logical_volume_seek_offset";
683 static char *keyword_list[] = { "offset", "whence", NULL };
684 off64_t offset = 0;
685 int whence = 0;
686
687 if( pyvslvm_logical_volume == NULL )
688 {
689 PyErr_Format(
690 PyExc_TypeError,
691 "%s: invalid pyvslvm logical volume.",
692 function );
693
694 return( NULL );
695 }
696 if( PyArg_ParseTupleAndKeywords(
697 arguments,
698 keywords,
699 "L|i",
700 keyword_list,
701 &offset,
702 &whence ) == 0 )
703 {
704 return( NULL );
705 }
706 Py_BEGIN_ALLOW_THREADS
707
708 offset = libvslvm_logical_volume_seek_offset(
709 pyvslvm_logical_volume->logical_volume,
710 offset,
711 whence,
712 &error );
713
714 Py_END_ALLOW_THREADS
715
716 if( offset == -1 )
717 {
718 pyvslvm_error_raise(
719 error,
720 PyExc_IOError,
721 "%s: unable to seek offset.",
722 function );
723
724 libcerror_error_free(
725 &error );
726
727 return( NULL );
728 }
729 Py_IncRef(
730 Py_None );
731
732 return( Py_None );
733 }
734
735 /* Retrieves the current offset in the data
736 * Returns a Python object if successful or NULL on error
737 */
pyvslvm_logical_volume_get_offset(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)738 PyObject *pyvslvm_logical_volume_get_offset(
739 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
740 PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
741 {
742 libcerror_error_t *error = NULL;
743 PyObject *integer_object = NULL;
744 static char *function = "pyvslvm_logical_volume_get_offset";
745 off64_t current_offset = 0;
746 int result = 0;
747
748 PYVSLVM_UNREFERENCED_PARAMETER( arguments )
749
750 if( pyvslvm_logical_volume == NULL )
751 {
752 PyErr_Format(
753 PyExc_TypeError,
754 "%s: invalid logical volume.",
755 function );
756
757 return( NULL );
758 }
759 Py_BEGIN_ALLOW_THREADS
760
761 result = libvslvm_logical_volume_get_offset(
762 pyvslvm_logical_volume->logical_volume,
763 ¤t_offset,
764 &error );
765
766 Py_END_ALLOW_THREADS
767
768 if( result != 1 )
769 {
770 pyvslvm_error_raise(
771 error,
772 PyExc_IOError,
773 "%s: unable to retrieve offset.",
774 function );
775
776 libcerror_error_free(
777 &error );
778
779 return( NULL );
780 }
781 integer_object = pyvslvm_integer_signed_new_from_64bit(
782 (int64_t) current_offset );
783
784 return( integer_object );
785 }
786
787 /* Retrieves the size
788 * Returns a Python object if successful or NULL on error
789 */
pyvslvm_logical_volume_get_size(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)790 PyObject *pyvslvm_logical_volume_get_size(
791 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
792 PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
793 {
794 libcerror_error_t *error = NULL;
795 PyObject *integer_object = NULL;
796 static char *function = "pyvslvm_logical_volume_get_size";
797 size64_t size = 0;
798 int result = 0;
799
800 PYVSLVM_UNREFERENCED_PARAMETER( arguments )
801
802 if( pyvslvm_logical_volume == NULL )
803 {
804 PyErr_Format(
805 PyExc_TypeError,
806 "%s: invalid logical volume.",
807 function );
808
809 return( NULL );
810 }
811 Py_BEGIN_ALLOW_THREADS
812
813 result = libvslvm_logical_volume_get_size(
814 pyvslvm_logical_volume->logical_volume,
815 &size,
816 &error );
817
818 Py_END_ALLOW_THREADS
819
820 if( result != 1 )
821 {
822 pyvslvm_error_raise(
823 error,
824 PyExc_IOError,
825 "%s: failed to retrieve size.",
826 function );
827
828 libcerror_error_free(
829 &error );
830
831 return( NULL );
832 }
833 integer_object = pyvslvm_integer_unsigned_new_from_64bit(
834 (uint64_t) size );
835
836 return( integer_object );
837 }
838
839 /* Retrieves the name
840 * Returns a Python object if successful or NULL on error
841 */
pyvslvm_logical_volume_get_name(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)842 PyObject *pyvslvm_logical_volume_get_name(
843 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
844 PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
845 {
846 libcerror_error_t *error = NULL;
847 PyObject *string_object = NULL;
848 char *name = NULL;
849 const char *errors = NULL;
850 static char *function = "pyvslvm_logical_volume_get_name";
851 size_t name_size = 0;
852 int result = 0;
853
854 PYVSLVM_UNREFERENCED_PARAMETER( arguments )
855
856 if( pyvslvm_logical_volume == NULL )
857 {
858 PyErr_Format(
859 PyExc_TypeError,
860 "%s: invalid logical volume.",
861 function );
862
863 return( NULL );
864 }
865 Py_BEGIN_ALLOW_THREADS
866
867 result = libvslvm_logical_volume_get_name_size(
868 pyvslvm_logical_volume->logical_volume,
869 &name_size,
870 &error );
871
872 Py_END_ALLOW_THREADS
873
874 if( result == -1 )
875 {
876 pyvslvm_error_raise(
877 error,
878 PyExc_IOError,
879 "%s: unable to retrieve name size.",
880 function );
881
882 libcerror_error_free(
883 &error );
884
885 goto on_error;
886 }
887 else if( ( result == 0 )
888 || ( name_size == 0 ) )
889 {
890 Py_IncRef(
891 Py_None );
892
893 return( Py_None );
894 }
895 name = (char *) PyMem_Malloc(
896 sizeof( char ) * name_size );
897
898 if( name == NULL )
899 {
900 PyErr_Format(
901 PyExc_IOError,
902 "%s: unable to create name.",
903 function );
904
905 goto on_error;
906 }
907 Py_BEGIN_ALLOW_THREADS
908
909 result = libvslvm_logical_volume_get_name(
910 pyvslvm_logical_volume->logical_volume,
911 name,
912 name_size,
913 &error );
914
915 Py_END_ALLOW_THREADS
916
917 if( result != 1 )
918 {
919 pyvslvm_error_raise(
920 error,
921 PyExc_IOError,
922 "%s: unable to retrieve name.",
923 function );
924
925 libcerror_error_free(
926 &error );
927
928 goto on_error;
929 }
930 /* Pass the string length to PyUnicode_DecodeUTF8
931 * otherwise it makes the end of string character is part
932 * of the string
933 */
934 string_object = PyUnicode_DecodeUTF8(
935 name,
936 (Py_ssize_t) name_size - 1,
937 errors );
938
939 PyMem_Free(
940 name );
941
942 return( string_object );
943
944 on_error:
945 if( name != NULL )
946 {
947 PyMem_Free(
948 name );
949 }
950 return( NULL );
951 }
952
953 /* Retrieves the identifier
954 * Returns a Python object if successful or NULL on error
955 */
pyvslvm_logical_volume_get_identifier(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)956 PyObject *pyvslvm_logical_volume_get_identifier(
957 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
958 PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
959 {
960 libcerror_error_t *error = NULL;
961 PyObject *string_object = NULL;
962 char *identifier = NULL;
963 const char *errors = NULL;
964 static char *function = "pyvslvm_logical_volume_get_identifier";
965 size_t identifier_size = 0;
966 int result = 0;
967
968 PYVSLVM_UNREFERENCED_PARAMETER( arguments )
969
970 if( pyvslvm_logical_volume == NULL )
971 {
972 PyErr_Format(
973 PyExc_TypeError,
974 "%s: invalid logical volume.",
975 function );
976
977 return( NULL );
978 }
979 Py_BEGIN_ALLOW_THREADS
980
981 result = libvslvm_logical_volume_get_identifier_size(
982 pyvslvm_logical_volume->logical_volume,
983 &identifier_size,
984 &error );
985
986 Py_END_ALLOW_THREADS
987
988 if( result == -1 )
989 {
990 pyvslvm_error_raise(
991 error,
992 PyExc_IOError,
993 "%s: unable to retrieve identifier size.",
994 function );
995
996 libcerror_error_free(
997 &error );
998
999 goto on_error;
1000 }
1001 else if( ( result == 0 )
1002 || ( identifier_size == 0 ) )
1003 {
1004 Py_IncRef(
1005 Py_None );
1006
1007 return( Py_None );
1008 }
1009 identifier = (char *) PyMem_Malloc(
1010 sizeof( char ) * identifier_size );
1011
1012 if( identifier == NULL )
1013 {
1014 PyErr_Format(
1015 PyExc_IOError,
1016 "%s: unable to create identifier.",
1017 function );
1018
1019 goto on_error;
1020 }
1021 Py_BEGIN_ALLOW_THREADS
1022
1023 result = libvslvm_logical_volume_get_identifier(
1024 pyvslvm_logical_volume->logical_volume,
1025 identifier,
1026 identifier_size,
1027 &error );
1028
1029 Py_END_ALLOW_THREADS
1030
1031 if( result != 1 )
1032 {
1033 pyvslvm_error_raise(
1034 error,
1035 PyExc_IOError,
1036 "%s: unable to retrieve identifier.",
1037 function );
1038
1039 libcerror_error_free(
1040 &error );
1041
1042 goto on_error;
1043 }
1044 /* Pass the string length to PyUnicode_DecodeUTF8
1045 * otherwise it makes the end of string character is part
1046 * of the string
1047 */
1048 string_object = PyUnicode_DecodeUTF8(
1049 identifier,
1050 (Py_ssize_t) identifier_size - 1,
1051 errors );
1052
1053 PyMem_Free(
1054 identifier );
1055
1056 return( string_object );
1057
1058 on_error:
1059 if( identifier != NULL )
1060 {
1061 PyMem_Free(
1062 identifier );
1063 }
1064 return( NULL );
1065 }
1066
1067 /* Retrieves the number of segments
1068 * Returns a Python object if successful or NULL on error
1069 */
pyvslvm_logical_volume_get_number_of_segments(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)1070 PyObject *pyvslvm_logical_volume_get_number_of_segments(
1071 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
1072 PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
1073 {
1074 libcerror_error_t *error = NULL;
1075 PyObject *integer_object = NULL;
1076 static char *function = "pyvslvm_logical_volume_get_number_of_segments";
1077 int number_of_segments = 0;
1078 int result = 0;
1079
1080 PYVSLVM_UNREFERENCED_PARAMETER( arguments )
1081
1082 if( pyvslvm_logical_volume == NULL )
1083 {
1084 PyErr_Format(
1085 PyExc_TypeError,
1086 "%s: invalid logical volume.",
1087 function );
1088
1089 return( NULL );
1090 }
1091 Py_BEGIN_ALLOW_THREADS
1092
1093 result = libvslvm_logical_volume_get_number_of_segments(
1094 pyvslvm_logical_volume->logical_volume,
1095 &number_of_segments,
1096 &error );
1097
1098 Py_END_ALLOW_THREADS
1099
1100 if( result != 1 )
1101 {
1102 pyvslvm_error_raise(
1103 error,
1104 PyExc_IOError,
1105 "%s: unable to retrieve number of segments.",
1106 function );
1107
1108 libcerror_error_free(
1109 &error );
1110
1111 return( NULL );
1112 }
1113 #if PY_MAJOR_VERSION >= 3
1114 integer_object = PyLong_FromLong(
1115 (long) number_of_segments );
1116 #else
1117 integer_object = PyInt_FromLong(
1118 (long) number_of_segments );
1119 #endif
1120 return( integer_object );
1121 }
1122
1123 /* Retrieves a specific segment by index
1124 * Returns a Python object if successful or NULL on error
1125 */
pyvslvm_logical_volume_get_segment_by_index(PyObject * pyvslvm_logical_volume,int segment_index)1126 PyObject *pyvslvm_logical_volume_get_segment_by_index(
1127 PyObject *pyvslvm_logical_volume,
1128 int segment_index )
1129 {
1130 libcerror_error_t *error = NULL;
1131 libvslvm_segment_t *segment = NULL;
1132 PyObject *segment_object = NULL;
1133 static char *function = "pyvslvm_logical_volume_get_segment_by_index";
1134 int result = 0;
1135
1136 if( pyvslvm_logical_volume == NULL )
1137 {
1138 PyErr_Format(
1139 PyExc_TypeError,
1140 "%s: invalid logical volume.",
1141 function );
1142
1143 return( NULL );
1144 }
1145 Py_BEGIN_ALLOW_THREADS
1146
1147 result = libvslvm_logical_volume_get_segment(
1148 ( (pyvslvm_logical_volume_t *) pyvslvm_logical_volume )->logical_volume,
1149 segment_index,
1150 &segment,
1151 &error );
1152
1153 Py_END_ALLOW_THREADS
1154
1155 if( result != 1 )
1156 {
1157 pyvslvm_error_raise(
1158 error,
1159 PyExc_IOError,
1160 "%s: unable to retrieve segment: %d.",
1161 function,
1162 segment_index );
1163
1164 libcerror_error_free(
1165 &error );
1166
1167 goto on_error;
1168 }
1169 segment_object = pyvslvm_segment_new(
1170 segment,
1171 (pyvslvm_logical_volume_t *) pyvslvm_logical_volume );
1172
1173 if( segment_object == NULL )
1174 {
1175 PyErr_Format(
1176 PyExc_MemoryError,
1177 "%s: unable to create segment object.",
1178 function );
1179
1180 goto on_error;
1181 }
1182 return( segment_object );
1183
1184 on_error:
1185 if( segment != NULL )
1186 {
1187 libvslvm_segment_free(
1188 &segment,
1189 NULL );
1190 }
1191 return( NULL );
1192 }
1193
1194 /* Retrieves a specific segment
1195 * Returns a Python object if successful or NULL on error
1196 */
pyvslvm_logical_volume_get_segment(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments,PyObject * keywords)1197 PyObject *pyvslvm_logical_volume_get_segment(
1198 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
1199 PyObject *arguments,
1200 PyObject *keywords )
1201 {
1202 PyObject *segment_object = NULL;
1203 static char *keyword_list[] = { "segment_index", NULL };
1204 int segment_index = 0;
1205
1206 if( PyArg_ParseTupleAndKeywords(
1207 arguments,
1208 keywords,
1209 "i",
1210 keyword_list,
1211 &segment_index ) == 0 )
1212 {
1213 return( NULL );
1214 }
1215 segment_object = pyvslvm_logical_volume_get_segment_by_index(
1216 (PyObject *) pyvslvm_logical_volume,
1217 segment_index );
1218
1219 return( segment_object );
1220 }
1221
1222 /* Retrieves a segments sequence and iterator object for the segments
1223 * Returns a Python object if successful or NULL on error
1224 */
pyvslvm_logical_volume_get_segments(pyvslvm_logical_volume_t * pyvslvm_logical_volume,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)1225 PyObject *pyvslvm_logical_volume_get_segments(
1226 pyvslvm_logical_volume_t *pyvslvm_logical_volume,
1227 PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
1228 {
1229 libcerror_error_t *error = NULL;
1230 PyObject *segments_object = NULL;
1231 static char *function = "pyvslvm_logical_volume_get_segments";
1232 int number_of_segments = 0;
1233 int result = 0;
1234
1235 PYVSLVM_UNREFERENCED_PARAMETER( arguments )
1236
1237 if( pyvslvm_logical_volume == NULL )
1238 {
1239 PyErr_Format(
1240 PyExc_TypeError,
1241 "%s: invalid logical volume.",
1242 function );
1243
1244 return( NULL );
1245 }
1246 Py_BEGIN_ALLOW_THREADS
1247
1248 result = libvslvm_logical_volume_get_number_of_segments(
1249 pyvslvm_logical_volume->logical_volume,
1250 &number_of_segments,
1251 &error );
1252
1253 Py_END_ALLOW_THREADS
1254
1255 if( result != 1 )
1256 {
1257 pyvslvm_error_raise(
1258 error,
1259 PyExc_IOError,
1260 "%s: unable to retrieve number of segments.",
1261 function );
1262
1263 libcerror_error_free(
1264 &error );
1265
1266 return( NULL );
1267 }
1268 segments_object = pyvslvm_segments_new(
1269 (PyObject *) pyvslvm_logical_volume,
1270 &pyvslvm_logical_volume_get_segment_by_index,
1271 number_of_segments );
1272
1273 if( segments_object == NULL )
1274 {
1275 PyErr_Format(
1276 PyExc_MemoryError,
1277 "%s: unable to create segments object.",
1278 function );
1279
1280 return( NULL );
1281 }
1282 return( segments_object );
1283 }
1284
1285