1 /*
2 * Python object wrapper of libfsext_file_entry_t
3 *
4 * Copyright (C) 2010-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 <narrow_string.h>
24 #include <types.h>
25
26 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
27 #include <stdlib.h>
28 #endif
29
30 #include "pyfsext_datetime.h"
31 #include "pyfsext_error.h"
32 #include "pyfsext_extended_attribute.h"
33 #include "pyfsext_extended_attributes.h"
34 #include "pyfsext_file_entries.h"
35 #include "pyfsext_file_entry.h"
36 #include "pyfsext_integer.h"
37 #include "pyfsext_libcerror.h"
38 #include "pyfsext_libfsext.h"
39 #include "pyfsext_python.h"
40 #include "pyfsext_unused.h"
41
42 PyMethodDef pyfsext_file_entry_object_methods[] = {
43
44 { "is_empty",
45 (PyCFunction) pyfsext_file_entry_is_empty,
46 METH_NOARGS,
47 "is_empty() -> Boolean or None\n"
48 "\n"
49 "Determines if the file entry is empty." },
50
51 { "get_inode_number",
52 (PyCFunction) pyfsext_file_entry_get_inode_number,
53 METH_NOARGS,
54 "get_inode_number() -> Integer\n"
55 "\n"
56 "Retrieves the inode number." },
57
58 { "get_access_time",
59 (PyCFunction) pyfsext_file_entry_get_access_time,
60 METH_NOARGS,
61 "get_access_time() -> Datetime\n"
62 "\n"
63 "Retrieves the access date and time." },
64
65 { "get_access_time_as_integer",
66 (PyCFunction) pyfsext_file_entry_get_access_time_as_integer,
67 METH_NOARGS,
68 "get_access_time_as_integer() -> Integer or None\n"
69 "\n"
70 "Retrieves the access date and time as a 64-bit integer containing a POSIX timestamp value." },
71
72 { "get_creation_time",
73 (PyCFunction) pyfsext_file_entry_get_creation_time,
74 METH_NOARGS,
75 "get_creation_time() -> Datetime\n"
76 "\n"
77 "Retrieves the creation date and time." },
78
79 { "get_creation_time_as_integer",
80 (PyCFunction) pyfsext_file_entry_get_creation_time_as_integer,
81 METH_NOARGS,
82 "get_creation_time_as_integer() -> Integer or None\n"
83 "\n"
84 "Retrieves the creation date and time as a 64-bit integer containing a POSIX timestamp value." },
85
86 { "get_inode_change_time",
87 (PyCFunction) pyfsext_file_entry_get_inode_change_time,
88 METH_NOARGS,
89 "get_inode_change_time() -> Datetime\n"
90 "\n"
91 "Retrieves the inode change time date and time." },
92
93 { "get_inode_change_time_as_integer",
94 (PyCFunction) pyfsext_file_entry_get_inode_change_time_as_integer,
95 METH_NOARGS,
96 "get_inode_change_time_as_integer() -> Integer or None\n"
97 "\n"
98 "Retrieves the inode change time date and time as a 64-bit integer containing a POSIX timestamp value." },
99
100 { "get_modification_time",
101 (PyCFunction) pyfsext_file_entry_get_modification_time,
102 METH_NOARGS,
103 "get_modification_time() -> Datetime\n"
104 "\n"
105 "Retrieves the modification date and time." },
106
107 { "get_modification_time_as_integer",
108 (PyCFunction) pyfsext_file_entry_get_modification_time_as_integer,
109 METH_NOARGS,
110 "get_modification_time_as_integer() -> Integer or None\n"
111 "\n"
112 "Retrieves the modification date and time as a 64-bit integer containing a POSIX timestamp value." },
113
114 { "get_deletion_time",
115 (PyCFunction) pyfsext_file_entry_get_deletion_time,
116 METH_NOARGS,
117 "get_deletion_time() -> Datetime\n"
118 "\n"
119 "Retrieves the deletion date and time." },
120
121 { "get_deletion_time_as_integer",
122 (PyCFunction) pyfsext_file_entry_get_deletion_time_as_integer,
123 METH_NOARGS,
124 "get_deletion_time_as_integer() -> Integer or None\n"
125 "\n"
126 "Retrieves the deletion date and time as a 32-bit integer containing a POSIX timestamp value." },
127
128 { "get_file_mode",
129 (PyCFunction) pyfsext_file_entry_get_file_mode,
130 METH_NOARGS,
131 "get_file_mode() -> Integer\n"
132 "\n"
133 "Retrieves the file mode." },
134
135 { "get_number_of_links",
136 (PyCFunction) pyfsext_file_entry_get_number_of_links,
137 METH_NOARGS,
138 "get_number_of_links() -> Integer\n"
139 "\n"
140 "Retrieves the number of (hard) links." },
141
142 { "get_owner_identifier",
143 (PyCFunction) pyfsext_file_entry_get_owner_identifier,
144 METH_NOARGS,
145 "get_owner_identifier() -> Integer\n"
146 "\n"
147 "Retrieves the owner identifier." },
148
149 { "get_group_identifier",
150 (PyCFunction) pyfsext_file_entry_get_group_identifier,
151 METH_NOARGS,
152 "get_group_identifier() -> Integer\n"
153 "\n"
154 "Retrieves the group identifier." },
155
156 { "get_name",
157 (PyCFunction) pyfsext_file_entry_get_name,
158 METH_NOARGS,
159 "get_name() -> Unicode string or None\n"
160 "\n"
161 "Retrieves the name." },
162
163 { "get_symbolic_link_target",
164 (PyCFunction) pyfsext_file_entry_get_symbolic_link_target,
165 METH_NOARGS,
166 "get_symbolic_link_target() -> Unicode string or None\n"
167 "\n"
168 "Returns the symbolic link target." },
169
170 { "get_number_of_extended_attributes",
171 (PyCFunction) pyfsext_file_entry_get_number_of_extended_attributes,
172 METH_NOARGS,
173 "get_number_of_extended_attributes() -> Integer\n"
174 "\n"
175 "Retrieves the number of extended attributes." },
176
177 { "get_extended_attribute",
178 (PyCFunction) pyfsext_file_entry_get_extended_attribute,
179 METH_VARARGS | METH_KEYWORDS,
180 "get_extended_attribute(extended_attribute_index) -> Object\n"
181 "\n"
182 "Retrieves the extended attribute specified by the index." },
183
184 { "get_number_of_sub_file_entries",
185 (PyCFunction) pyfsext_file_entry_get_number_of_sub_file_entries,
186 METH_NOARGS,
187 "get_number_of_sub_file_entries() -> Integer\n"
188 "\n"
189 "Retrieves the number of sub file entries." },
190
191 { "get_sub_file_entry",
192 (PyCFunction) pyfsext_file_entry_get_sub_file_entry,
193 METH_VARARGS | METH_KEYWORDS,
194 "get_sub_file_entry(sub_file_entry_index) -> Object\n"
195 "\n"
196 "Retrieves the sub file entry for the specific index specified by the index." },
197
198 { "get_sub_file_entry_by_name",
199 (PyCFunction) pyfsext_file_entry_get_sub_file_entry_by_name,
200 METH_VARARGS | METH_KEYWORDS,
201 "get_sub_file_entry_by_name(name) -> Object or None\n"
202 "\n"
203 "Retrieves the sub file entry for an UTF-8 encoded name specified by the name." },
204
205 { "read_buffer",
206 (PyCFunction) pyfsext_file_entry_read_buffer,
207 METH_VARARGS | METH_KEYWORDS,
208 "read_buffer(size) -> Binary string\n"
209 "\n"
210 "Reads a buffer of data at the current offset." },
211
212 { "read_buffer_at_offset",
213 (PyCFunction) pyfsext_file_entry_read_buffer_at_offset,
214 METH_VARARGS | METH_KEYWORDS,
215 "read_buffer_at_offset(size, offset) -> Binary string\n"
216 "\n"
217 "Reads a buffer of data at a specific offset." },
218
219 { "seek_offset",
220 (PyCFunction) pyfsext_file_entry_seek_offset,
221 METH_VARARGS | METH_KEYWORDS,
222 "seek_offset(offset, whence) -> None\n"
223 "\n"
224 "Seeks an offset within the data." },
225
226 { "get_offset",
227 (PyCFunction) pyfsext_file_entry_get_offset,
228 METH_NOARGS,
229 "get_offset() -> Integer\n"
230 "\n"
231 "Retrieves the current offset of the data." },
232
233 { "read",
234 (PyCFunction) pyfsext_file_entry_read_buffer,
235 METH_VARARGS | METH_KEYWORDS,
236 "read(size) -> Binary string\n"
237 "\n"
238 "Reads a buffer of data at the current offset." },
239
240 { "seek",
241 (PyCFunction) pyfsext_file_entry_seek_offset,
242 METH_VARARGS | METH_KEYWORDS,
243 "seek(offset, whence) -> None\n"
244 "\n"
245 "Seeks an offset within the data." },
246
247 { "tell",
248 (PyCFunction) pyfsext_file_entry_get_offset,
249 METH_NOARGS,
250 "tell() -> Integer\n"
251 "\n"
252 "Retrieves the current offset of the data." },
253
254 { "get_size",
255 (PyCFunction) pyfsext_file_entry_get_size,
256 METH_NOARGS,
257 "get_size() -> Integer\n"
258 "\n"
259 "Retrieves the size of the data." },
260
261 { "get_number_of_extents",
262 (PyCFunction) pyfsext_file_entry_get_number_of_extents,
263 METH_NOARGS,
264 "get_number_of_extents() -> Integer\n"
265 "\n"
266 "Retrieves the number of extents of the data." },
267
268 /* Sentinel */
269 { NULL, NULL, 0, NULL }
270 };
271
272 PyGetSetDef pyfsext_file_entry_object_get_set_definitions[] = {
273
274 { "inode_number",
275 (getter) pyfsext_file_entry_get_inode_number,
276 (setter) 0,
277 "The inode number.",
278 NULL },
279
280 { "access_time",
281 (getter) pyfsext_file_entry_get_access_time,
282 (setter) 0,
283 "The access date and time.",
284 NULL },
285
286 { "creation_time",
287 (getter) pyfsext_file_entry_get_creation_time,
288 (setter) 0,
289 "The creation date and time.",
290 NULL },
291
292 { "inode_change_time",
293 (getter) pyfsext_file_entry_get_inode_change_time,
294 (setter) 0,
295 "The inode change time date and time.",
296 NULL },
297
298 { "modification_time",
299 (getter) pyfsext_file_entry_get_modification_time,
300 (setter) 0,
301 "The modification date and time.",
302 NULL },
303
304 { "deletion_time",
305 (getter) pyfsext_file_entry_get_deletion_time,
306 (setter) 0,
307 "The deletion date and time.",
308 NULL },
309
310 { "file_mode",
311 (getter) pyfsext_file_entry_get_file_mode,
312 (setter) 0,
313 "The file mode.",
314 NULL },
315
316 { "number_of_links",
317 (getter) pyfsext_file_entry_get_number_of_links,
318 (setter) 0,
319 "The number of (hard) links.",
320 NULL },
321
322 { "owner_identifier",
323 (getter) pyfsext_file_entry_get_owner_identifier,
324 (setter) 0,
325 "The owner identifier.",
326 NULL },
327
328 { "group_identifier",
329 (getter) pyfsext_file_entry_get_group_identifier,
330 (setter) 0,
331 "The group identifier.",
332 NULL },
333
334 { "name",
335 (getter) pyfsext_file_entry_get_name,
336 (setter) 0,
337 "The name.",
338 NULL },
339
340 { "symbolic_link_target",
341 (getter) pyfsext_file_entry_get_symbolic_link_target,
342 (setter) 0,
343 "The symbolic link target.",
344 NULL },
345
346 { "number_of_extended_attributes",
347 (getter) pyfsext_file_entry_get_number_of_extended_attributes,
348 (setter) 0,
349 "The number of extended attributes.",
350 NULL },
351
352 { "extended_attributes",
353 (getter) pyfsext_file_entry_get_extended_attributes,
354 (setter) 0,
355 "The extended attributes.",
356 NULL },
357
358 { "number_of_sub_file_entries",
359 (getter) pyfsext_file_entry_get_number_of_sub_file_entries,
360 (setter) 0,
361 "The number of sub file entries.",
362 NULL },
363
364 { "sub_file_entries",
365 (getter) pyfsext_file_entry_get_sub_file_entries,
366 (setter) 0,
367 "The sub file entry for the specific indexes.",
368 NULL },
369
370 { "size",
371 (getter) pyfsext_file_entry_get_size,
372 (setter) 0,
373 "The size of the data.",
374 NULL },
375
376 { "number_of_extents",
377 (getter) pyfsext_file_entry_get_number_of_extents,
378 (setter) 0,
379 "The number of extents of the data.",
380 NULL },
381
382 /* Sentinel */
383 { NULL, NULL, NULL, NULL, NULL }
384 };
385
386 PyTypeObject pyfsext_file_entry_type_object = {
387 PyVarObject_HEAD_INIT( NULL, 0 )
388
389 /* tp_name */
390 "pyfsext.file_entry",
391 /* tp_basicsize */
392 sizeof( pyfsext_file_entry_t ),
393 /* tp_itemsize */
394 0,
395 /* tp_dealloc */
396 (destructor) pyfsext_file_entry_free,
397 /* tp_print */
398 0,
399 /* tp_getattr */
400 0,
401 /* tp_setattr */
402 0,
403 /* tp_compare */
404 0,
405 /* tp_repr */
406 0,
407 /* tp_as_number */
408 0,
409 /* tp_as_sequence */
410 0,
411 /* tp_as_mapping */
412 0,
413 /* tp_hash */
414 0,
415 /* tp_call */
416 0,
417 /* tp_str */
418 0,
419 /* tp_getattro */
420 0,
421 /* tp_setattro */
422 0,
423 /* tp_as_buffer */
424 0,
425 /* tp_flags */
426 Py_TPFLAGS_DEFAULT,
427 /* tp_doc */
428 "pyfsext file entry object (wraps libfsext_file_entry_t)",
429 /* tp_traverse */
430 0,
431 /* tp_clear */
432 0,
433 /* tp_richcompare */
434 0,
435 /* tp_weaklistoffset */
436 0,
437 /* tp_iter */
438 0,
439 /* tp_iternext */
440 0,
441 /* tp_methods */
442 pyfsext_file_entry_object_methods,
443 /* tp_members */
444 0,
445 /* tp_getset */
446 pyfsext_file_entry_object_get_set_definitions,
447 /* tp_base */
448 0,
449 /* tp_dict */
450 0,
451 /* tp_descr_get */
452 0,
453 /* tp_descr_set */
454 0,
455 /* tp_dictoffset */
456 0,
457 /* tp_init */
458 (initproc) pyfsext_file_entry_init,
459 /* tp_alloc */
460 0,
461 /* tp_new */
462 0,
463 /* tp_free */
464 0,
465 /* tp_is_gc */
466 0,
467 /* tp_bases */
468 NULL,
469 /* tp_mro */
470 NULL,
471 /* tp_cache */
472 NULL,
473 /* tp_subclasses */
474 NULL,
475 /* tp_weaklist */
476 NULL,
477 /* tp_del */
478 0
479 };
480
481 /* Creates a new file entry object
482 * Returns a Python object if successful or NULL on error
483 */
pyfsext_file_entry_new(libfsext_file_entry_t * file_entry,PyObject * parent_object)484 PyObject *pyfsext_file_entry_new(
485 libfsext_file_entry_t *file_entry,
486 PyObject *parent_object )
487 {
488 pyfsext_file_entry_t *pyfsext_file_entry = NULL;
489 static char *function = "pyfsext_file_entry_new";
490
491 if( file_entry == NULL )
492 {
493 PyErr_Format(
494 PyExc_ValueError,
495 "%s: invalid file entry.",
496 function );
497
498 return( NULL );
499 }
500 /* PyObject_New does not invoke tp_init
501 */
502 pyfsext_file_entry = PyObject_New(
503 struct pyfsext_file_entry,
504 &pyfsext_file_entry_type_object );
505
506 if( pyfsext_file_entry == NULL )
507 {
508 PyErr_Format(
509 PyExc_MemoryError,
510 "%s: unable to initialize file entry.",
511 function );
512
513 goto on_error;
514 }
515 pyfsext_file_entry->file_entry = file_entry;
516 pyfsext_file_entry->parent_object = parent_object;
517
518 if( pyfsext_file_entry->parent_object != NULL )
519 {
520 Py_IncRef(
521 pyfsext_file_entry->parent_object );
522 }
523 return( (PyObject *) pyfsext_file_entry );
524
525 on_error:
526 if( pyfsext_file_entry != NULL )
527 {
528 Py_DecRef(
529 (PyObject *) pyfsext_file_entry );
530 }
531 return( NULL );
532 }
533
534 /* Initializes a file entry object
535 * Returns 0 if successful or -1 on error
536 */
pyfsext_file_entry_init(pyfsext_file_entry_t * pyfsext_file_entry)537 int pyfsext_file_entry_init(
538 pyfsext_file_entry_t *pyfsext_file_entry )
539 {
540 static char *function = "pyfsext_file_entry_init";
541
542 if( pyfsext_file_entry == NULL )
543 {
544 PyErr_Format(
545 PyExc_ValueError,
546 "%s: invalid file entry.",
547 function );
548
549 return( -1 );
550 }
551 /* Make sure libfsext file entry is set to NULL
552 */
553 pyfsext_file_entry->file_entry = NULL;
554
555 PyErr_Format(
556 PyExc_NotImplementedError,
557 "%s: initialize of file entry not supported.",
558 function );
559
560 return( -1 );
561 }
562
563 /* Frees a file entry object
564 */
pyfsext_file_entry_free(pyfsext_file_entry_t * pyfsext_file_entry)565 void pyfsext_file_entry_free(
566 pyfsext_file_entry_t *pyfsext_file_entry )
567 {
568 struct _typeobject *ob_type = NULL;
569 libcerror_error_t *error = NULL;
570 static char *function = "pyfsext_file_entry_free";
571 int result = 0;
572
573 if( pyfsext_file_entry == NULL )
574 {
575 PyErr_Format(
576 PyExc_ValueError,
577 "%s: invalid file entry.",
578 function );
579
580 return;
581 }
582 ob_type = Py_TYPE(
583 pyfsext_file_entry );
584
585 if( ob_type == NULL )
586 {
587 PyErr_Format(
588 PyExc_ValueError,
589 "%s: missing ob_type.",
590 function );
591
592 return;
593 }
594 if( ob_type->tp_free == NULL )
595 {
596 PyErr_Format(
597 PyExc_ValueError,
598 "%s: invalid ob_type - missing tp_free.",
599 function );
600
601 return;
602 }
603 if( pyfsext_file_entry->file_entry != NULL )
604 {
605 Py_BEGIN_ALLOW_THREADS
606
607 result = libfsext_file_entry_free(
608 &( pyfsext_file_entry->file_entry ),
609 &error );
610
611 Py_END_ALLOW_THREADS
612
613 if( result != 1 )
614 {
615 pyfsext_error_raise(
616 error,
617 PyExc_MemoryError,
618 "%s: unable to free libfsext file entry.",
619 function );
620
621 libcerror_error_free(
622 &error );
623 }
624 }
625 if( pyfsext_file_entry->parent_object != NULL )
626 {
627 Py_DecRef(
628 pyfsext_file_entry->parent_object );
629 }
630 ob_type->tp_free(
631 (PyObject*) pyfsext_file_entry );
632 }
633
634 /* Determines if the file entry is
635 * Returns a Python object if successful or NULL on error
636 */
pyfsext_file_entry_is_empty(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)637 PyObject *pyfsext_file_entry_is_empty(
638 pyfsext_file_entry_t *pyfsext_file_entry,
639 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
640 {
641 libcerror_error_t *error = NULL;
642 static char *function = "pyfsext_file_entry_is_empty";
643 int result = 0;
644
645 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
646
647 if( pyfsext_file_entry == NULL )
648 {
649 PyErr_Format(
650 PyExc_ValueError,
651 "%s: invalid file entry.",
652 function );
653
654 return( NULL );
655 }
656 Py_BEGIN_ALLOW_THREADS
657
658 result = libfsext_file_entry_is_empty(
659 pyfsext_file_entry->file_entry,
660 &error );
661
662 Py_END_ALLOW_THREADS
663
664 if( result == -1 )
665 {
666 pyfsext_error_raise(
667 error,
668 PyExc_IOError,
669 "%s: unable to determine if file entry is .",
670 function );
671
672 libcerror_error_free(
673 &error );
674
675 return( NULL );
676 }
677 if( result != 0 )
678 {
679 Py_IncRef(
680 (PyObject *) Py_True );
681
682 return( Py_True );
683 }
684 Py_IncRef(
685 (PyObject *) Py_False );
686
687 return( Py_False );
688 }
689
690 /* Retrieves the inode number
691 * Returns a Python object if successful or NULL on error
692 */
pyfsext_file_entry_get_inode_number(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)693 PyObject *pyfsext_file_entry_get_inode_number(
694 pyfsext_file_entry_t *pyfsext_file_entry,
695 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
696 {
697 PyObject *integer_object = NULL;
698 libcerror_error_t *error = NULL;
699 static char *function = "pyfsext_file_entry_get_inode_number";
700 uint32_t value_32bit = 0;
701 int result = 0;
702
703 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
704
705 if( pyfsext_file_entry == NULL )
706 {
707 PyErr_Format(
708 PyExc_ValueError,
709 "%s: invalid file entry.",
710 function );
711
712 return( NULL );
713 }
714 Py_BEGIN_ALLOW_THREADS
715
716 result = libfsext_file_entry_get_inode_number(
717 pyfsext_file_entry->file_entry,
718 &value_32bit,
719 &error );
720
721 Py_END_ALLOW_THREADS
722
723 if( result != 1 )
724 {
725 pyfsext_error_raise(
726 error,
727 PyExc_IOError,
728 "%s: unable to retrieve inode number.",
729 function );
730
731 libcerror_error_free(
732 &error );
733
734 return( NULL );
735 }
736 integer_object = PyLong_FromUnsignedLong(
737 (unsigned long) value_32bit );
738
739 return( integer_object );
740 }
741
742 /* Retrieves the access date and time
743 * Returns a Python object if successful or NULL on error
744 */
pyfsext_file_entry_get_access_time(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)745 PyObject *pyfsext_file_entry_get_access_time(
746 pyfsext_file_entry_t *pyfsext_file_entry,
747 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
748 {
749 PyObject *datetime_object = NULL;
750 libcerror_error_t *error = NULL;
751 static char *function = "pyfsext_file_entry_get_access_time";
752 int64_t posix_time = 0;
753 int result = 0;
754
755 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
756
757 if( pyfsext_file_entry == NULL )
758 {
759 PyErr_Format(
760 PyExc_ValueError,
761 "%s: invalid file entry.",
762 function );
763
764 return( NULL );
765 }
766 Py_BEGIN_ALLOW_THREADS
767
768 result = libfsext_file_entry_get_access_time(
769 pyfsext_file_entry->file_entry,
770 &posix_time,
771 &error );
772
773 Py_END_ALLOW_THREADS
774
775 if( result == -1 )
776 {
777 pyfsext_error_raise(
778 error,
779 PyExc_IOError,
780 "%s: unable to retrieve access date and time.",
781 function );
782
783 libcerror_error_free(
784 &error );
785
786 return( NULL );
787 }
788 else if( result == 0 )
789 {
790 Py_IncRef(
791 Py_None );
792
793 return( Py_None );
794 }
795 datetime_object = pyfsext_datetime_new_from_posix_time_in_micro_seconds(
796 posix_time / 1000 );
797
798 return( datetime_object );
799 }
800
801 /* Retrieves the access date and time as an integer
802 * Returns a Python object if successful or NULL on error
803 */
pyfsext_file_entry_get_access_time_as_integer(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)804 PyObject *pyfsext_file_entry_get_access_time_as_integer(
805 pyfsext_file_entry_t *pyfsext_file_entry,
806 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
807 {
808 PyObject *integer_object = NULL;
809 libcerror_error_t *error = NULL;
810 static char *function = "pyfsext_file_entry_get_access_time_as_integer";
811 int64_t posix_time = 0;
812 int result = 0;
813
814 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
815
816 if( pyfsext_file_entry == NULL )
817 {
818 PyErr_Format(
819 PyExc_ValueError,
820 "%s: invalid file entry.",
821 function );
822
823 return( NULL );
824 }
825 Py_BEGIN_ALLOW_THREADS
826
827 result = libfsext_file_entry_get_access_time(
828 pyfsext_file_entry->file_entry,
829 &posix_time,
830 &error );
831
832 Py_END_ALLOW_THREADS
833
834 if( result == -1 )
835 {
836 pyfsext_error_raise(
837 error,
838 PyExc_IOError,
839 "%s: unable to retrieve access date and time.",
840 function );
841
842 libcerror_error_free(
843 &error );
844
845 return( NULL );
846 }
847 else if( result == 0 )
848 {
849 Py_IncRef(
850 Py_None );
851
852 return( Py_None );
853 }
854 integer_object = pyfsext_integer_signed_new_from_64bit(
855 posix_time );
856
857 return( integer_object );
858 }
859
860 /* Retrieves the creation date and time
861 * Returns a Python object if successful or NULL on error
862 */
pyfsext_file_entry_get_creation_time(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)863 PyObject *pyfsext_file_entry_get_creation_time(
864 pyfsext_file_entry_t *pyfsext_file_entry,
865 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
866 {
867 PyObject *datetime_object = NULL;
868 libcerror_error_t *error = NULL;
869 static char *function = "pyfsext_file_entry_get_creation_time";
870 int64_t posix_time = 0;
871 int result = 0;
872
873 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
874
875 if( pyfsext_file_entry == NULL )
876 {
877 PyErr_Format(
878 PyExc_ValueError,
879 "%s: invalid file entry.",
880 function );
881
882 return( NULL );
883 }
884 Py_BEGIN_ALLOW_THREADS
885
886 result = libfsext_file_entry_get_creation_time(
887 pyfsext_file_entry->file_entry,
888 &posix_time,
889 &error );
890
891 Py_END_ALLOW_THREADS
892
893 if( result == -1 )
894 {
895 pyfsext_error_raise(
896 error,
897 PyExc_IOError,
898 "%s: unable to retrieve creation date and time.",
899 function );
900
901 libcerror_error_free(
902 &error );
903
904 return( NULL );
905 }
906 else if( result == 0 )
907 {
908 Py_IncRef(
909 Py_None );
910
911 return( Py_None );
912 }
913 datetime_object = pyfsext_datetime_new_from_posix_time_in_micro_seconds(
914 posix_time / 1000 );
915
916 return( datetime_object );
917 }
918
919 /* Retrieves the creation date and time as an integer
920 * Returns a Python object if successful or NULL on error
921 */
pyfsext_file_entry_get_creation_time_as_integer(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)922 PyObject *pyfsext_file_entry_get_creation_time_as_integer(
923 pyfsext_file_entry_t *pyfsext_file_entry,
924 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
925 {
926 PyObject *integer_object = NULL;
927 libcerror_error_t *error = NULL;
928 static char *function = "pyfsext_file_entry_get_creation_time_as_integer";
929 int64_t posix_time = 0;
930 int result = 0;
931
932 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
933
934 if( pyfsext_file_entry == NULL )
935 {
936 PyErr_Format(
937 PyExc_ValueError,
938 "%s: invalid file entry.",
939 function );
940
941 return( NULL );
942 }
943 Py_BEGIN_ALLOW_THREADS
944
945 result = libfsext_file_entry_get_creation_time(
946 pyfsext_file_entry->file_entry,
947 &posix_time,
948 &error );
949
950 Py_END_ALLOW_THREADS
951
952 if( result == -1 )
953 {
954 pyfsext_error_raise(
955 error,
956 PyExc_IOError,
957 "%s: unable to retrieve creation date and time.",
958 function );
959
960 libcerror_error_free(
961 &error );
962
963 return( NULL );
964 }
965 else if( result == 0 )
966 {
967 Py_IncRef(
968 Py_None );
969
970 return( Py_None );
971 }
972 integer_object = pyfsext_integer_signed_new_from_64bit(
973 posix_time );
974
975 return( integer_object );
976 }
977
978 /* Retrieves the inode change time date and time
979 * Returns a Python object if successful or NULL on error
980 */
pyfsext_file_entry_get_inode_change_time(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)981 PyObject *pyfsext_file_entry_get_inode_change_time(
982 pyfsext_file_entry_t *pyfsext_file_entry,
983 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
984 {
985 PyObject *datetime_object = NULL;
986 libcerror_error_t *error = NULL;
987 static char *function = "pyfsext_file_entry_get_inode_change_time";
988 int64_t posix_time = 0;
989 int result = 0;
990
991 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
992
993 if( pyfsext_file_entry == NULL )
994 {
995 PyErr_Format(
996 PyExc_ValueError,
997 "%s: invalid file entry.",
998 function );
999
1000 return( NULL );
1001 }
1002 Py_BEGIN_ALLOW_THREADS
1003
1004 result = libfsext_file_entry_get_inode_change_time(
1005 pyfsext_file_entry->file_entry,
1006 &posix_time,
1007 &error );
1008
1009 Py_END_ALLOW_THREADS
1010
1011 if( result == -1 )
1012 {
1013 pyfsext_error_raise(
1014 error,
1015 PyExc_IOError,
1016 "%s: unable to retrieve inode change time date and time.",
1017 function );
1018
1019 libcerror_error_free(
1020 &error );
1021
1022 return( NULL );
1023 }
1024 else if( result == 0 )
1025 {
1026 Py_IncRef(
1027 Py_None );
1028
1029 return( Py_None );
1030 }
1031 datetime_object = pyfsext_datetime_new_from_posix_time_in_micro_seconds(
1032 posix_time / 1000 );
1033
1034 return( datetime_object );
1035 }
1036
1037 /* Retrieves the inode change time date and time as an integer
1038 * Returns a Python object if successful or NULL on error
1039 */
pyfsext_file_entry_get_inode_change_time_as_integer(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1040 PyObject *pyfsext_file_entry_get_inode_change_time_as_integer(
1041 pyfsext_file_entry_t *pyfsext_file_entry,
1042 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1043 {
1044 PyObject *integer_object = NULL;
1045 libcerror_error_t *error = NULL;
1046 static char *function = "pyfsext_file_entry_get_inode_change_time_as_integer";
1047 int64_t posix_time = 0;
1048 int result = 0;
1049
1050 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1051
1052 if( pyfsext_file_entry == NULL )
1053 {
1054 PyErr_Format(
1055 PyExc_ValueError,
1056 "%s: invalid file entry.",
1057 function );
1058
1059 return( NULL );
1060 }
1061 Py_BEGIN_ALLOW_THREADS
1062
1063 result = libfsext_file_entry_get_inode_change_time(
1064 pyfsext_file_entry->file_entry,
1065 &posix_time,
1066 &error );
1067
1068 Py_END_ALLOW_THREADS
1069
1070 if( result == -1 )
1071 {
1072 pyfsext_error_raise(
1073 error,
1074 PyExc_IOError,
1075 "%s: unable to retrieve inode change time date and time.",
1076 function );
1077
1078 libcerror_error_free(
1079 &error );
1080
1081 return( NULL );
1082 }
1083 else if( result == 0 )
1084 {
1085 Py_IncRef(
1086 Py_None );
1087
1088 return( Py_None );
1089 }
1090 integer_object = pyfsext_integer_signed_new_from_64bit(
1091 posix_time );
1092
1093 return( integer_object );
1094 }
1095
1096 /* Retrieves the modification date and time
1097 * Returns a Python object if successful or NULL on error
1098 */
pyfsext_file_entry_get_modification_time(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1099 PyObject *pyfsext_file_entry_get_modification_time(
1100 pyfsext_file_entry_t *pyfsext_file_entry,
1101 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1102 {
1103 PyObject *datetime_object = NULL;
1104 libcerror_error_t *error = NULL;
1105 static char *function = "pyfsext_file_entry_get_modification_time";
1106 int64_t posix_time = 0;
1107 int result = 0;
1108
1109 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1110
1111 if( pyfsext_file_entry == NULL )
1112 {
1113 PyErr_Format(
1114 PyExc_ValueError,
1115 "%s: invalid file entry.",
1116 function );
1117
1118 return( NULL );
1119 }
1120 Py_BEGIN_ALLOW_THREADS
1121
1122 result = libfsext_file_entry_get_modification_time(
1123 pyfsext_file_entry->file_entry,
1124 &posix_time,
1125 &error );
1126
1127 Py_END_ALLOW_THREADS
1128
1129 if( result == -1 )
1130 {
1131 pyfsext_error_raise(
1132 error,
1133 PyExc_IOError,
1134 "%s: unable to retrieve modification date and time.",
1135 function );
1136
1137 libcerror_error_free(
1138 &error );
1139
1140 return( NULL );
1141 }
1142 else if( result == 0 )
1143 {
1144 Py_IncRef(
1145 Py_None );
1146
1147 return( Py_None );
1148 }
1149 datetime_object = pyfsext_datetime_new_from_posix_time_in_micro_seconds(
1150 posix_time / 1000 );
1151
1152 return( datetime_object );
1153 }
1154
1155 /* Retrieves the modification date and time as an integer
1156 * Returns a Python object if successful or NULL on error
1157 */
pyfsext_file_entry_get_modification_time_as_integer(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1158 PyObject *pyfsext_file_entry_get_modification_time_as_integer(
1159 pyfsext_file_entry_t *pyfsext_file_entry,
1160 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1161 {
1162 PyObject *integer_object = NULL;
1163 libcerror_error_t *error = NULL;
1164 static char *function = "pyfsext_file_entry_get_modification_time_as_integer";
1165 int64_t posix_time = 0;
1166 int result = 0;
1167
1168 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1169
1170 if( pyfsext_file_entry == NULL )
1171 {
1172 PyErr_Format(
1173 PyExc_ValueError,
1174 "%s: invalid file entry.",
1175 function );
1176
1177 return( NULL );
1178 }
1179 Py_BEGIN_ALLOW_THREADS
1180
1181 result = libfsext_file_entry_get_modification_time(
1182 pyfsext_file_entry->file_entry,
1183 &posix_time,
1184 &error );
1185
1186 Py_END_ALLOW_THREADS
1187
1188 if( result == -1 )
1189 {
1190 pyfsext_error_raise(
1191 error,
1192 PyExc_IOError,
1193 "%s: unable to retrieve modification date and time.",
1194 function );
1195
1196 libcerror_error_free(
1197 &error );
1198
1199 return( NULL );
1200 }
1201 else if( result == 0 )
1202 {
1203 Py_IncRef(
1204 Py_None );
1205
1206 return( Py_None );
1207 }
1208 integer_object = pyfsext_integer_signed_new_from_64bit(
1209 posix_time );
1210
1211 return( integer_object );
1212 }
1213
1214 /* Retrieves the deletion date and time
1215 * Returns a Python object if successful or NULL on error
1216 */
pyfsext_file_entry_get_deletion_time(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1217 PyObject *pyfsext_file_entry_get_deletion_time(
1218 pyfsext_file_entry_t *pyfsext_file_entry,
1219 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1220 {
1221 PyObject *datetime_object = NULL;
1222 libcerror_error_t *error = NULL;
1223 static char *function = "pyfsext_file_entry_get_deletion_time";
1224 int32_t posix_time = 0;
1225 int result = 0;
1226
1227 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1228
1229 if( pyfsext_file_entry == NULL )
1230 {
1231 PyErr_Format(
1232 PyExc_ValueError,
1233 "%s: invalid file entry.",
1234 function );
1235
1236 return( NULL );
1237 }
1238 Py_BEGIN_ALLOW_THREADS
1239
1240 result = libfsext_file_entry_get_deletion_time(
1241 pyfsext_file_entry->file_entry,
1242 &posix_time,
1243 &error );
1244
1245 Py_END_ALLOW_THREADS
1246
1247 if( result == -1 )
1248 {
1249 pyfsext_error_raise(
1250 error,
1251 PyExc_IOError,
1252 "%s: unable to retrieve deletion date and time.",
1253 function );
1254
1255 libcerror_error_free(
1256 &error );
1257
1258 return( NULL );
1259 }
1260 else if( result == 0 )
1261 {
1262 Py_IncRef(
1263 Py_None );
1264
1265 return( Py_None );
1266 }
1267 datetime_object = pyfsext_datetime_new_from_posix_time(
1268 posix_time );
1269
1270 return( datetime_object );
1271 }
1272
1273 /* Retrieves the deletion date and time as an integer
1274 * Returns a Python object if successful or NULL on error
1275 */
pyfsext_file_entry_get_deletion_time_as_integer(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1276 PyObject *pyfsext_file_entry_get_deletion_time_as_integer(
1277 pyfsext_file_entry_t *pyfsext_file_entry,
1278 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1279 {
1280 PyObject *integer_object = NULL;
1281 libcerror_error_t *error = NULL;
1282 static char *function = "pyfsext_file_entry_get_deletion_time_as_integer";
1283 int32_t posix_time = 0;
1284 int result = 0;
1285
1286 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1287
1288 if( pyfsext_file_entry == NULL )
1289 {
1290 PyErr_Format(
1291 PyExc_ValueError,
1292 "%s: invalid file entry.",
1293 function );
1294
1295 return( NULL );
1296 }
1297 Py_BEGIN_ALLOW_THREADS
1298
1299 result = libfsext_file_entry_get_deletion_time(
1300 pyfsext_file_entry->file_entry,
1301 &posix_time,
1302 &error );
1303
1304 Py_END_ALLOW_THREADS
1305
1306 if( result == -1 )
1307 {
1308 pyfsext_error_raise(
1309 error,
1310 PyExc_IOError,
1311 "%s: unable to retrieve deletion date and time.",
1312 function );
1313
1314 libcerror_error_free(
1315 &error );
1316
1317 return( NULL );
1318 }
1319 else if( result == 0 )
1320 {
1321 Py_IncRef(
1322 Py_None );
1323
1324 return( Py_None );
1325 }
1326 integer_object = PyLong_FromLong(
1327 (long) posix_time );
1328
1329 return( integer_object );
1330 }
1331
1332 /* Retrieves the file mode
1333 * Returns a Python object if successful or NULL on error
1334 */
pyfsext_file_entry_get_file_mode(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1335 PyObject *pyfsext_file_entry_get_file_mode(
1336 pyfsext_file_entry_t *pyfsext_file_entry,
1337 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1338 {
1339 PyObject *integer_object = NULL;
1340 libcerror_error_t *error = NULL;
1341 static char *function = "pyfsext_file_entry_get_file_mode";
1342 uint16_t file_mode = 0;
1343 int result = 0;
1344
1345 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1346
1347 if( pyfsext_file_entry == NULL )
1348 {
1349 PyErr_Format(
1350 PyExc_ValueError,
1351 "%s: invalid file entry.",
1352 function );
1353
1354 return( NULL );
1355 }
1356 Py_BEGIN_ALLOW_THREADS
1357
1358 result = libfsext_file_entry_get_file_mode(
1359 pyfsext_file_entry->file_entry,
1360 &file_mode,
1361 &error );
1362
1363 Py_END_ALLOW_THREADS
1364
1365 if( result != 1 )
1366 {
1367 pyfsext_error_raise(
1368 error,
1369 PyExc_IOError,
1370 "%s: unable to retrieve file mode.",
1371 function );
1372
1373 libcerror_error_free(
1374 &error );
1375
1376 return( NULL );
1377 }
1378 #if PY_MAJOR_VERSION >= 3
1379 integer_object = PyLong_FromLong(
1380 (long) file_mode );
1381 #else
1382 integer_object = PyInt_FromLong(
1383 (long) file_mode );
1384 #endif
1385 return( integer_object );
1386 }
1387
1388 /* Retrieves the number of (hard) links
1389 * Returns a Python object if successful or NULL on error
1390 */
pyfsext_file_entry_get_number_of_links(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1391 PyObject *pyfsext_file_entry_get_number_of_links(
1392 pyfsext_file_entry_t *pyfsext_file_entry,
1393 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1394 {
1395 PyObject *integer_object = NULL;
1396 libcerror_error_t *error = NULL;
1397 static char *function = "pyfsext_file_entry_get_number_of_links";
1398 uint16_t number_of_links = 0;
1399 int result = 0;
1400
1401 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1402
1403 if( pyfsext_file_entry == NULL )
1404 {
1405 PyErr_Format(
1406 PyExc_ValueError,
1407 "%s: invalid file entry.",
1408 function );
1409
1410 return( NULL );
1411 }
1412 Py_BEGIN_ALLOW_THREADS
1413
1414 result = libfsext_file_entry_get_number_of_links(
1415 pyfsext_file_entry->file_entry,
1416 &number_of_links,
1417 &error );
1418
1419 Py_END_ALLOW_THREADS
1420
1421 if( result != 1 )
1422 {
1423 pyfsext_error_raise(
1424 error,
1425 PyExc_IOError,
1426 "%s: unable to retrieve number of (hard) links.",
1427 function );
1428
1429 libcerror_error_free(
1430 &error );
1431
1432 return( NULL );
1433 }
1434 #if PY_MAJOR_VERSION >= 3
1435 integer_object = PyLong_FromLong(
1436 (long) number_of_links );
1437 #else
1438 integer_object = PyInt_FromLong(
1439 (long) number_of_links );
1440 #endif
1441 return( integer_object );
1442 }
1443
1444 /* Retrieves the owner identifier
1445 * Returns a Python object if successful or NULL on error
1446 */
pyfsext_file_entry_get_owner_identifier(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1447 PyObject *pyfsext_file_entry_get_owner_identifier(
1448 pyfsext_file_entry_t *pyfsext_file_entry,
1449 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1450 {
1451 PyObject *integer_object = NULL;
1452 libcerror_error_t *error = NULL;
1453 static char *function = "pyfsext_file_entry_get_owner_identifier";
1454 uint32_t value_32bit = 0;
1455 int result = 0;
1456
1457 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1458
1459 if( pyfsext_file_entry == NULL )
1460 {
1461 PyErr_Format(
1462 PyExc_ValueError,
1463 "%s: invalid file entry.",
1464 function );
1465
1466 return( NULL );
1467 }
1468 Py_BEGIN_ALLOW_THREADS
1469
1470 result = libfsext_file_entry_get_owner_identifier(
1471 pyfsext_file_entry->file_entry,
1472 &value_32bit,
1473 &error );
1474
1475 Py_END_ALLOW_THREADS
1476
1477 if( result != 1 )
1478 {
1479 pyfsext_error_raise(
1480 error,
1481 PyExc_IOError,
1482 "%s: unable to retrieve owner identifier.",
1483 function );
1484
1485 libcerror_error_free(
1486 &error );
1487
1488 return( NULL );
1489 }
1490 integer_object = PyLong_FromUnsignedLong(
1491 (unsigned long) value_32bit );
1492
1493 return( integer_object );
1494 }
1495
1496 /* Retrieves the group identifier
1497 * Returns a Python object if successful or NULL on error
1498 */
pyfsext_file_entry_get_group_identifier(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1499 PyObject *pyfsext_file_entry_get_group_identifier(
1500 pyfsext_file_entry_t *pyfsext_file_entry,
1501 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1502 {
1503 PyObject *integer_object = NULL;
1504 libcerror_error_t *error = NULL;
1505 static char *function = "pyfsext_file_entry_get_group_identifier";
1506 uint32_t value_32bit = 0;
1507 int result = 0;
1508
1509 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1510
1511 if( pyfsext_file_entry == NULL )
1512 {
1513 PyErr_Format(
1514 PyExc_ValueError,
1515 "%s: invalid file entry.",
1516 function );
1517
1518 return( NULL );
1519 }
1520 Py_BEGIN_ALLOW_THREADS
1521
1522 result = libfsext_file_entry_get_group_identifier(
1523 pyfsext_file_entry->file_entry,
1524 &value_32bit,
1525 &error );
1526
1527 Py_END_ALLOW_THREADS
1528
1529 if( result != 1 )
1530 {
1531 pyfsext_error_raise(
1532 error,
1533 PyExc_IOError,
1534 "%s: unable to retrieve group identifier.",
1535 function );
1536
1537 libcerror_error_free(
1538 &error );
1539
1540 return( NULL );
1541 }
1542 integer_object = PyLong_FromUnsignedLong(
1543 (unsigned long) value_32bit );
1544
1545 return( integer_object );
1546 }
1547
1548 /* Retrieves the name
1549 * Returns a Python object if successful or NULL on error
1550 */
pyfsext_file_entry_get_name(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1551 PyObject *pyfsext_file_entry_get_name(
1552 pyfsext_file_entry_t *pyfsext_file_entry,
1553 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1554 {
1555 PyObject *string_object = NULL;
1556 libcerror_error_t *error = NULL;
1557 uint8_t *name = NULL;
1558 const char *errors = NULL;
1559 static char *function = "pyfsext_file_entry_get_name";
1560 size_t name_size = 0;
1561 int result = 0;
1562
1563 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1564
1565 if( pyfsext_file_entry == NULL )
1566 {
1567 PyErr_Format(
1568 PyExc_ValueError,
1569 "%s: invalid file entry.",
1570 function );
1571
1572 return( NULL );
1573 }
1574 Py_BEGIN_ALLOW_THREADS
1575
1576 result = libfsext_file_entry_get_utf8_name_size(
1577 pyfsext_file_entry->file_entry,
1578 &name_size,
1579 &error );
1580
1581 Py_END_ALLOW_THREADS
1582
1583 if( result == -1 )
1584 {
1585 pyfsext_error_raise(
1586 error,
1587 PyExc_IOError,
1588 "%s: unable to retrieve name size.",
1589 function );
1590
1591 libcerror_error_free(
1592 &error );
1593
1594 goto on_error;
1595 }
1596 else if( ( result == 0 )
1597 || ( name_size == 0 ) )
1598 {
1599 Py_IncRef(
1600 Py_None );
1601
1602 return( Py_None );
1603 }
1604 name = (uint8_t *) PyMem_Malloc(
1605 sizeof( uint8_t ) * name_size );
1606
1607 if( name == NULL )
1608 {
1609 PyErr_Format(
1610 PyExc_IOError,
1611 "%s: unable to create name.",
1612 function );
1613
1614 goto on_error;
1615 }
1616 Py_BEGIN_ALLOW_THREADS
1617
1618 result = libfsext_file_entry_get_utf8_name(
1619 pyfsext_file_entry->file_entry,
1620 name,
1621 name_size,
1622 &error );
1623
1624 Py_END_ALLOW_THREADS
1625
1626 if( result != 1 )
1627 {
1628 pyfsext_error_raise(
1629 error,
1630 PyExc_IOError,
1631 "%s: unable to retrieve name.",
1632 function );
1633
1634 libcerror_error_free(
1635 &error );
1636
1637 goto on_error;
1638 }
1639 /* Pass the string length to PyUnicode_DecodeUTF8
1640 * otherwise it makes the end of string character is part
1641 * of the string
1642 */
1643 string_object = PyUnicode_DecodeUTF8(
1644 (char *) name,
1645 (Py_ssize_t) name_size - 1,
1646 errors );
1647
1648 PyMem_Free(
1649 name );
1650
1651 return( string_object );
1652
1653 on_error:
1654 if( name != NULL )
1655 {
1656 PyMem_Free(
1657 name );
1658 }
1659 return( NULL );
1660 }
1661
1662 /* Retrieves the symbolic link target
1663 * Returns a Python object if successful or NULL on error
1664 */
pyfsext_file_entry_get_symbolic_link_target(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1665 PyObject *pyfsext_file_entry_get_symbolic_link_target(
1666 pyfsext_file_entry_t *pyfsext_file_entry,
1667 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1668 {
1669 libcerror_error_t *error = NULL;
1670 PyObject *string_object = NULL;
1671 const char *errors = NULL;
1672 uint8_t *target = NULL;
1673 static char *function = "pyfsext_file_entry_get_symbolic_link_target";
1674 size_t target_size = 0;
1675 int result = 0;
1676
1677 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1678
1679 if( pyfsext_file_entry == NULL )
1680 {
1681 PyErr_Format(
1682 PyExc_TypeError,
1683 "%s: invalid file entry.",
1684 function );
1685
1686 return( NULL );
1687 }
1688 Py_BEGIN_ALLOW_THREADS
1689
1690 result = libfsext_file_entry_get_utf8_symbolic_link_target_size(
1691 pyfsext_file_entry->file_entry,
1692 &target_size,
1693 &error );
1694
1695 Py_END_ALLOW_THREADS
1696
1697 if( result == -1 )
1698 {
1699 pyfsext_error_raise(
1700 error,
1701 PyExc_IOError,
1702 "%s: unable to retrieve symbolic link target size.",
1703 function );
1704
1705 libcerror_error_free(
1706 &error );
1707
1708 goto on_error;
1709 }
1710 else if( ( result == 0 )
1711 || ( target_size == 0 ) )
1712 {
1713 Py_IncRef(
1714 Py_None );
1715
1716 return( Py_None );
1717 }
1718 target = (uint8_t *) PyMem_Malloc(
1719 sizeof( uint8_t ) * target_size );
1720
1721 if( target == NULL )
1722 {
1723 PyErr_Format(
1724 PyExc_IOError,
1725 "%s: unable to create target.",
1726 function );
1727
1728 goto on_error;
1729 }
1730 Py_BEGIN_ALLOW_THREADS
1731
1732 result = libfsext_file_entry_get_utf8_symbolic_link_target(
1733 pyfsext_file_entry->file_entry,
1734 target,
1735 target_size,
1736 &error );
1737
1738 Py_END_ALLOW_THREADS
1739
1740 if( result != 1 )
1741 {
1742 pyfsext_error_raise(
1743 error,
1744 PyExc_IOError,
1745 "%s: unable to retrieve symbolic link target.",
1746 function );
1747
1748 libcerror_error_free(
1749 &error );
1750
1751 goto on_error;
1752 }
1753 /* Pass the string length to PyUnicode_DecodeUTF8
1754 * otherwise it makes the end of string character is part
1755 * of the string
1756 */
1757 string_object = PyUnicode_DecodeUTF8(
1758 (char *) target,
1759 (Py_ssize_t) target_size - 1,
1760 errors );
1761
1762 PyMem_Free(
1763 target );
1764
1765 return( string_object );
1766
1767 on_error:
1768 if( target != NULL )
1769 {
1770 PyMem_Free(
1771 target );
1772 }
1773 return( NULL );
1774 }
1775
1776 /* Retrieves the number of extended attributes
1777 * Returns a Python object if successful or NULL on error
1778 */
pyfsext_file_entry_get_number_of_extended_attributes(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1779 PyObject *pyfsext_file_entry_get_number_of_extended_attributes(
1780 pyfsext_file_entry_t *pyfsext_file_entry,
1781 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1782 {
1783 PyObject *integer_object = NULL;
1784 libcerror_error_t *error = NULL;
1785 static char *function = "pyfsext_file_entry_get_number_of_extended_attributes";
1786 int number_of_extended_attributes = 0;
1787 int result = 0;
1788
1789 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1790
1791 if( pyfsext_file_entry == NULL )
1792 {
1793 PyErr_Format(
1794 PyExc_ValueError,
1795 "%s: invalid file entry.",
1796 function );
1797
1798 return( NULL );
1799 }
1800 Py_BEGIN_ALLOW_THREADS
1801
1802 result = libfsext_file_entry_get_number_of_extended_attributes(
1803 pyfsext_file_entry->file_entry,
1804 &number_of_extended_attributes,
1805 &error );
1806
1807 Py_END_ALLOW_THREADS
1808
1809 if( result != 1 )
1810 {
1811 pyfsext_error_raise(
1812 error,
1813 PyExc_IOError,
1814 "%s: unable to retrieve .",
1815 function );
1816
1817 libcerror_error_free(
1818 &error );
1819
1820 return( NULL );
1821 }
1822 #if PY_MAJOR_VERSION >= 3
1823 integer_object = PyLong_FromLong(
1824 (long) number_of_extended_attributes );
1825 #else
1826 integer_object = PyInt_FromLong(
1827 (long) number_of_extended_attributes );
1828 #endif
1829 return( integer_object );
1830 }
1831
1832 /* Retrieves a specific extended attribute by index
1833 * Returns a Python object if successful or NULL on error
1834 */
pyfsext_file_entry_get_extended_attribute_by_index(PyObject * pyfsext_file_entry,int extended_attribute_index)1835 PyObject *pyfsext_file_entry_get_extended_attribute_by_index(
1836 PyObject *pyfsext_file_entry,
1837 int extended_attribute_index )
1838 {
1839 PyObject *extended_attribute_object = NULL;
1840 libcerror_error_t *error = NULL;
1841 libfsext_extended_attribute_t *extended_attribute = NULL;
1842 static char *function = "pyfsext_file_entry_get_extended_attribute_by_index";
1843 int result = 0;
1844
1845 if( pyfsext_file_entry == NULL )
1846 {
1847 PyErr_Format(
1848 PyExc_ValueError,
1849 "%s: invalid file entry.",
1850 function );
1851
1852 return( NULL );
1853 }
1854 Py_BEGIN_ALLOW_THREADS
1855
1856 result = libfsext_file_entry_get_extended_attribute_by_index(
1857 ( (pyfsext_file_entry_t *) pyfsext_file_entry )->file_entry,
1858 extended_attribute_index,
1859 &extended_attribute,
1860 &error );
1861
1862 Py_END_ALLOW_THREADS
1863
1864 if( result != 1 )
1865 {
1866 pyfsext_error_raise(
1867 error,
1868 PyExc_IOError,
1869 "%s: unable to retrieve : %d.",
1870 function,
1871 extended_attribute_index );
1872
1873 libcerror_error_free(
1874 &error );
1875
1876 goto on_error;
1877 }
1878 extended_attribute_object = pyfsext_extended_attribute_new(
1879 extended_attribute,
1880 pyfsext_file_entry );
1881
1882 if( extended_attribute_object == NULL )
1883 {
1884 PyErr_Format(
1885 PyExc_MemoryError,
1886 "%s: unable to create extended attribute object.",
1887 function );
1888
1889 goto on_error;
1890 }
1891 return( extended_attribute_object );
1892
1893 on_error:
1894 if( extended_attribute != NULL )
1895 {
1896 libfsext_extended_attribute_free(
1897 &extended_attribute,
1898 NULL );
1899 }
1900 return( NULL );
1901 }
1902
1903 /* Retrieves a specific extended attribute
1904 * Returns a Python object if successful or NULL on error
1905 */
pyfsext_file_entry_get_extended_attribute(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments,PyObject * keywords)1906 PyObject *pyfsext_file_entry_get_extended_attribute(
1907 pyfsext_file_entry_t *pyfsext_file_entry,
1908 PyObject *arguments,
1909 PyObject *keywords )
1910 {
1911 PyObject *extended_attribute_object = NULL;
1912 static char *keyword_list[] = { "extended_attribute_index", NULL };
1913 int extended_attribute_index = 0;
1914
1915 if( PyArg_ParseTupleAndKeywords(
1916 arguments,
1917 keywords,
1918 "i",
1919 keyword_list,
1920 &extended_attribute_index ) == 0 )
1921 {
1922 return( NULL );
1923 }
1924 extended_attribute_object = pyfsext_file_entry_get_extended_attribute_by_index(
1925 (PyObject *) pyfsext_file_entry,
1926 extended_attribute_index );
1927
1928 return( extended_attribute_object );
1929 }
1930
1931 /* Retrieves a sequence and iterator object for the extended attributes
1932 * Returns a Python object if successful or NULL on error
1933 */
pyfsext_file_entry_get_extended_attributes(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1934 PyObject *pyfsext_file_entry_get_extended_attributes(
1935 pyfsext_file_entry_t *pyfsext_file_entry,
1936 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
1937 {
1938 PyObject *sequence_object = NULL;
1939 libcerror_error_t *error = NULL;
1940 static char *function = "pyfsext_file_entry_get_extended_attributes";
1941 int number_of_extended_attributes = 0;
1942 int result = 0;
1943
1944 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
1945
1946 if( pyfsext_file_entry == NULL )
1947 {
1948 PyErr_Format(
1949 PyExc_ValueError,
1950 "%s: invalid file entry.",
1951 function );
1952
1953 return( NULL );
1954 }
1955 Py_BEGIN_ALLOW_THREADS
1956
1957 result = libfsext_file_entry_get_number_of_extended_attributes(
1958 pyfsext_file_entry->file_entry,
1959 &number_of_extended_attributes,
1960 &error );
1961
1962 Py_END_ALLOW_THREADS
1963
1964 if( result != 1 )
1965 {
1966 pyfsext_error_raise(
1967 error,
1968 PyExc_IOError,
1969 "%s: unable to retrieve number of extended attributes.",
1970 function );
1971
1972 libcerror_error_free(
1973 &error );
1974
1975 return( NULL );
1976 }
1977 sequence_object = pyfsext_extended_attributes_new(
1978 (PyObject *) pyfsext_file_entry,
1979 &pyfsext_file_entry_get_extended_attribute_by_index,
1980 number_of_extended_attributes );
1981
1982 if( sequence_object == NULL )
1983 {
1984 pyfsext_error_raise(
1985 error,
1986 PyExc_MemoryError,
1987 "%s: unable to create sequence object.",
1988 function );
1989
1990 return( NULL );
1991 }
1992 return( sequence_object );
1993 }
1994
1995 /* Retrieves the number of sub file entries
1996 * Returns a Python object if successful or NULL on error
1997 */
pyfsext_file_entry_get_number_of_sub_file_entries(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)1998 PyObject *pyfsext_file_entry_get_number_of_sub_file_entries(
1999 pyfsext_file_entry_t *pyfsext_file_entry,
2000 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
2001 {
2002 PyObject *integer_object = NULL;
2003 libcerror_error_t *error = NULL;
2004 static char *function = "pyfsext_file_entry_get_number_of_sub_file_entries";
2005 int number_of_sub_file_entries = 0;
2006 int result = 0;
2007
2008 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
2009
2010 if( pyfsext_file_entry == NULL )
2011 {
2012 PyErr_Format(
2013 PyExc_ValueError,
2014 "%s: invalid file entry.",
2015 function );
2016
2017 return( NULL );
2018 }
2019 Py_BEGIN_ALLOW_THREADS
2020
2021 result = libfsext_file_entry_get_number_of_sub_file_entries(
2022 pyfsext_file_entry->file_entry,
2023 &number_of_sub_file_entries,
2024 &error );
2025
2026 Py_END_ALLOW_THREADS
2027
2028 if( result != 1 )
2029 {
2030 pyfsext_error_raise(
2031 error,
2032 PyExc_IOError,
2033 "%s: unable to retrieve number of sub file entries.",
2034 function );
2035
2036 libcerror_error_free(
2037 &error );
2038
2039 return( NULL );
2040 }
2041 #if PY_MAJOR_VERSION >= 3
2042 integer_object = PyLong_FromLong(
2043 (long) number_of_sub_file_entries );
2044 #else
2045 integer_object = PyInt_FromLong(
2046 (long) number_of_sub_file_entries );
2047 #endif
2048 return( integer_object );
2049 }
2050
2051 /* Retrieves a specific sub file entry for the specific index by index
2052 * Returns a Python object if successful or NULL on error
2053 */
pyfsext_file_entry_get_sub_file_entry_by_index(PyObject * pyfsext_file_entry,int sub_file_entry_index)2054 PyObject *pyfsext_file_entry_get_sub_file_entry_by_index(
2055 PyObject *pyfsext_file_entry,
2056 int sub_file_entry_index )
2057 {
2058 PyObject *file_entry_object = NULL;
2059 libcerror_error_t *error = NULL;
2060 libfsext_file_entry_t *sub_file_entry = NULL;
2061 static char *function = "pyfsext_file_entry_get_sub_file_entry_by_index";
2062 int result = 0;
2063
2064 if( pyfsext_file_entry == NULL )
2065 {
2066 PyErr_Format(
2067 PyExc_ValueError,
2068 "%s: invalid file entry.",
2069 function );
2070
2071 return( NULL );
2072 }
2073 Py_BEGIN_ALLOW_THREADS
2074
2075 result = libfsext_file_entry_get_sub_file_entry_by_index(
2076 ( (pyfsext_file_entry_t *) pyfsext_file_entry )->file_entry,
2077 sub_file_entry_index,
2078 &sub_file_entry,
2079 &error );
2080
2081 Py_END_ALLOW_THREADS
2082
2083 if( result != 1 )
2084 {
2085 pyfsext_error_raise(
2086 error,
2087 PyExc_IOError,
2088 "%s: unable to retrieve sub file entry for the specific index: %d.",
2089 function,
2090 sub_file_entry_index );
2091
2092 libcerror_error_free(
2093 &error );
2094
2095 goto on_error;
2096 }
2097 file_entry_object = pyfsext_file_entry_new(
2098 sub_file_entry,
2099 ( (pyfsext_file_entry_t *) pyfsext_file_entry )->parent_object );
2100
2101 if( file_entry_object == NULL )
2102 {
2103 PyErr_Format(
2104 PyExc_MemoryError,
2105 "%s: unable to create sub file entry object.",
2106 function );
2107
2108 goto on_error;
2109 }
2110 return( file_entry_object );
2111
2112 on_error:
2113 if( sub_file_entry != NULL )
2114 {
2115 libfsext_file_entry_free(
2116 &sub_file_entry,
2117 NULL );
2118 }
2119 return( NULL );
2120 }
2121
2122 /* Retrieves a specific sub file entry for the specific index
2123 * Returns a Python object if successful or NULL on error
2124 */
pyfsext_file_entry_get_sub_file_entry(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments,PyObject * keywords)2125 PyObject *pyfsext_file_entry_get_sub_file_entry(
2126 pyfsext_file_entry_t *pyfsext_file_entry,
2127 PyObject *arguments,
2128 PyObject *keywords )
2129 {
2130 PyObject *file_entry_object = NULL;
2131 static char *keyword_list[] = { "sub_file_entry_index", NULL };
2132 int sub_file_entry_index = 0;
2133
2134 if( PyArg_ParseTupleAndKeywords(
2135 arguments,
2136 keywords,
2137 "i",
2138 keyword_list,
2139 &sub_file_entry_index ) == 0 )
2140 {
2141 return( NULL );
2142 }
2143 file_entry_object = pyfsext_file_entry_get_sub_file_entry_by_index(
2144 (PyObject *) pyfsext_file_entry,
2145 sub_file_entry_index );
2146
2147 return( file_entry_object );
2148 }
2149
2150 /* Retrieves a sequence and iterator object for the sub file entries
2151 * Returns a Python object if successful or NULL on error
2152 */
pyfsext_file_entry_get_sub_file_entries(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)2153 PyObject *pyfsext_file_entry_get_sub_file_entries(
2154 pyfsext_file_entry_t *pyfsext_file_entry,
2155 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
2156 {
2157 PyObject *sequence_object = NULL;
2158 libcerror_error_t *error = NULL;
2159 static char *function = "pyfsext_file_entry_get_sub_file_entries";
2160 int number_of_sub_file_entries = 0;
2161 int result = 0;
2162
2163 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
2164
2165 if( pyfsext_file_entry == NULL )
2166 {
2167 PyErr_Format(
2168 PyExc_ValueError,
2169 "%s: invalid file entry.",
2170 function );
2171
2172 return( NULL );
2173 }
2174 Py_BEGIN_ALLOW_THREADS
2175
2176 result = libfsext_file_entry_get_number_of_sub_file_entries(
2177 pyfsext_file_entry->file_entry,
2178 &number_of_sub_file_entries,
2179 &error );
2180
2181 Py_END_ALLOW_THREADS
2182
2183 if( result != 1 )
2184 {
2185 pyfsext_error_raise(
2186 error,
2187 PyExc_IOError,
2188 "%s: unable to retrieve number of sub file entries.",
2189 function );
2190
2191 libcerror_error_free(
2192 &error );
2193
2194 return( NULL );
2195 }
2196 sequence_object = pyfsext_file_entries_new(
2197 (PyObject *) pyfsext_file_entry,
2198 &pyfsext_file_entry_get_sub_file_entry_by_index,
2199 number_of_sub_file_entries );
2200
2201 if( sequence_object == NULL )
2202 {
2203 pyfsext_error_raise(
2204 error,
2205 PyExc_MemoryError,
2206 "%s: unable to create sequence object.",
2207 function );
2208
2209 return( NULL );
2210 }
2211 return( sequence_object );
2212 }
2213
2214 /* Retrieves the sub file entry for an UTF-8 encoded name specified by the name
2215 * Returns a Python object if successful or NULL on error
2216 */
pyfsext_file_entry_get_sub_file_entry_by_name(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments,PyObject * keywords)2217 PyObject *pyfsext_file_entry_get_sub_file_entry_by_name(
2218 pyfsext_file_entry_t *pyfsext_file_entry,
2219 PyObject *arguments,
2220 PyObject *keywords )
2221 {
2222 PyObject *file_entry_object = NULL;
2223 libcerror_error_t *error = NULL;
2224 libfsext_file_entry_t *sub_file_entry = NULL;
2225 static char *function = "pyfsext_file_entry_get_sub_file_entry_by_name";
2226 static char *keyword_list[] = { "name", NULL };
2227 char *utf8_name = NULL;
2228 size_t utf8_name_length = 0;
2229 int result = 0;
2230
2231 if( pyfsext_file_entry == NULL )
2232 {
2233 PyErr_Format(
2234 PyExc_ValueError,
2235 "%s: invalid file entry.",
2236 function );
2237
2238 return( NULL );
2239 }
2240 if( PyArg_ParseTupleAndKeywords(
2241 arguments,
2242 keywords,
2243 "s",
2244 keyword_list,
2245 &utf8_name ) == 0 )
2246 {
2247 goto on_error;
2248 }
2249 utf8_name_length = narrow_string_length(
2250 utf8_name );
2251
2252 Py_BEGIN_ALLOW_THREADS
2253
2254 result = libfsext_file_entry_get_sub_file_entry_by_utf8_name(
2255 pyfsext_file_entry->file_entry,
2256 (uint8_t *) utf8_name,
2257 utf8_name_length,
2258 &sub_file_entry,
2259 &error );
2260
2261 Py_END_ALLOW_THREADS
2262
2263 if( result == -1 )
2264 {
2265 pyfsext_error_raise(
2266 error,
2267 PyExc_IOError,
2268 "%s: unable to retrieve sub file entry for an UTF-8 encoded name.",
2269 function );
2270
2271 libcerror_error_free(
2272 &error );
2273
2274 goto on_error;
2275 }
2276 else if( result == 0 )
2277 {
2278 Py_IncRef(
2279 Py_None );
2280
2281 return( Py_None );
2282 }
2283 file_entry_object = pyfsext_file_entry_new(
2284 sub_file_entry,
2285 pyfsext_file_entry->parent_object );
2286
2287 if( file_entry_object == NULL )
2288 {
2289 PyErr_Format(
2290 PyExc_MemoryError,
2291 "%s: unable to create sub file entry object.",
2292 function );
2293
2294 goto on_error;
2295 }
2296 return( file_entry_object );
2297
2298 on_error:
2299 if( sub_file_entry != NULL )
2300 {
2301 libfsext_file_entry_free(
2302 &sub_file_entry,
2303 NULL );
2304 }
2305 return( NULL );
2306 }
2307
2308 /* Reads data at the current offset into a buffer
2309 * Returns a Python object if successful or NULL on error
2310 */
pyfsext_file_entry_read_buffer(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments,PyObject * keywords)2311 PyObject *pyfsext_file_entry_read_buffer(
2312 pyfsext_file_entry_t *pyfsext_file_entry,
2313 PyObject *arguments,
2314 PyObject *keywords )
2315 {
2316 PyObject *integer_object = NULL;
2317 PyObject *string_object = NULL;
2318 libcerror_error_t *error = NULL;
2319 char *buffer = NULL;
2320 static char *function = "pyfsext_file_entry_read_buffer";
2321 static char *keyword_list[] = { "size", NULL };
2322 ssize_t read_count = 0;
2323 int64_t read_size = 0;
2324 int result = 0;
2325
2326 if( pyfsext_file_entry == NULL )
2327 {
2328 PyErr_Format(
2329 PyExc_ValueError,
2330 "%s: invalid file entry.",
2331 function );
2332
2333 return( NULL );
2334 }
2335 if( PyArg_ParseTupleAndKeywords(
2336 arguments,
2337 keywords,
2338 "|O",
2339 keyword_list,
2340 &integer_object ) == 0 )
2341 {
2342 return( NULL );
2343 }
2344 if( integer_object == NULL )
2345 {
2346 result = 0;
2347 }
2348 else
2349 {
2350 result = PyObject_IsInstance(
2351 integer_object,
2352 (PyObject *) &PyLong_Type );
2353
2354 if( result == -1 )
2355 {
2356 pyfsext_error_fetch_and_raise(
2357 PyExc_RuntimeError,
2358 "%s: unable to determine if integer object is of type long.",
2359 function );
2360
2361 return( NULL );
2362 }
2363 #if PY_MAJOR_VERSION < 3
2364 else if( result == 0 )
2365 {
2366 PyErr_Clear();
2367
2368 result = PyObject_IsInstance(
2369 integer_object,
2370 (PyObject *) &PyInt_Type );
2371
2372 if( result == -1 )
2373 {
2374 pyfsext_error_fetch_and_raise(
2375 PyExc_RuntimeError,
2376 "%s: unable to determine if integer object is of type int.",
2377 function );
2378
2379 return( NULL );
2380 }
2381 }
2382 #endif
2383 }
2384 if( result != 0 )
2385 {
2386 if( pyfsext_integer_signed_copy_to_64bit(
2387 integer_object,
2388 &read_size,
2389 &error ) != 1 )
2390 {
2391 pyfsext_error_raise(
2392 error,
2393 PyExc_ValueError,
2394 "%s: unable to convert integer object into read size.",
2395 function );
2396
2397 libcerror_error_free(
2398 &error );
2399
2400 return( NULL );
2401 }
2402 }
2403 else if( ( integer_object == NULL )
2404 || ( integer_object == Py_None ) )
2405 {
2406 Py_BEGIN_ALLOW_THREADS
2407
2408 result = libfsext_file_entry_get_size(
2409 pyfsext_file_entry->file_entry,
2410 (size64_t *) &read_size,
2411 &error );
2412
2413 Py_END_ALLOW_THREADS
2414
2415 if( result != 1 )
2416 {
2417 pyfsext_error_raise(
2418 error,
2419 PyExc_IOError,
2420 "%s: unable to retrieve size.",
2421 function );
2422
2423 libcerror_error_free(
2424 &error );
2425
2426 return( NULL );
2427 }
2428 }
2429 else
2430 {
2431 PyErr_Format(
2432 PyExc_TypeError,
2433 "%s: unsupported integer object type.",
2434 function );
2435
2436 return( NULL );
2437 }
2438 if( read_size == 0 )
2439 {
2440 #if PY_MAJOR_VERSION >= 3
2441 string_object = PyBytes_FromString(
2442 "" );
2443 #else
2444 string_object = PyString_FromString(
2445 "" );
2446 #endif
2447 return( string_object );
2448 }
2449 if( read_size < 0 )
2450 {
2451 PyErr_Format(
2452 PyExc_ValueError,
2453 "%s: invalid read size value less than zero.",
2454 function );
2455
2456 return( NULL );
2457 }
2458 /* Make sure the data fits into a memory buffer
2459 */
2460 if( ( read_size > (int64_t) INT_MAX )
2461 || ( read_size > (int64_t) SSIZE_MAX ) )
2462 {
2463 PyErr_Format(
2464 PyExc_ValueError,
2465 "%s: invalid argument read size value exceeds maximum.",
2466 function );
2467
2468 return( NULL );
2469 }
2470 #if PY_MAJOR_VERSION >= 3
2471 string_object = PyBytes_FromStringAndSize(
2472 NULL,
2473 (Py_ssize_t) read_size );
2474
2475 buffer = PyBytes_AsString(
2476 string_object );
2477 #else
2478 /* Note that a size of 0 is not supported
2479 */
2480 string_object = PyString_FromStringAndSize(
2481 NULL,
2482 (Py_ssize_t) read_size );
2483
2484 buffer = PyString_AsString(
2485 string_object );
2486 #endif
2487 Py_BEGIN_ALLOW_THREADS
2488
2489 read_count = libfsext_file_entry_read_buffer(
2490 pyfsext_file_entry->file_entry,
2491 (uint8_t *) buffer,
2492 (size_t) read_size,
2493 &error );
2494
2495 Py_END_ALLOW_THREADS
2496
2497 if( read_count == -1 )
2498 {
2499 pyfsext_error_raise(
2500 error,
2501 PyExc_IOError,
2502 "%s: unable to read data.",
2503 function );
2504
2505 libcerror_error_free(
2506 &error );
2507
2508 Py_DecRef(
2509 (PyObject *) string_object );
2510
2511 return( NULL );
2512 }
2513 /* Need to resize the string here in case read_size was not fully read.
2514 */
2515 #if PY_MAJOR_VERSION >= 3
2516 if( _PyBytes_Resize(
2517 &string_object,
2518 (Py_ssize_t) read_count ) != 0 )
2519 #else
2520 if( _PyString_Resize(
2521 &string_object,
2522 (Py_ssize_t) read_count ) != 0 )
2523 #endif
2524 {
2525 Py_DecRef(
2526 (PyObject *) string_object );
2527
2528 return( NULL );
2529 }
2530 return( string_object );
2531 }
2532
2533 /* Reads data at a specific offset into a buffer
2534 * Returns a Python object if successful or NULL on error
2535 */
pyfsext_file_entry_read_buffer_at_offset(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments,PyObject * keywords)2536 PyObject *pyfsext_file_entry_read_buffer_at_offset(
2537 pyfsext_file_entry_t *pyfsext_file_entry,
2538 PyObject *arguments,
2539 PyObject *keywords )
2540 {
2541 PyObject *integer_object = NULL;
2542 PyObject *string_object = NULL;
2543 libcerror_error_t *error = NULL;
2544 char *buffer = NULL;
2545 static char *function = "pyfsext_file_entry_read_buffer_at_offset";
2546 static char *keyword_list[] = { "size", "offset", NULL };
2547 ssize_t read_count = 0;
2548 off64_t read_offset = 0;
2549 int64_t read_size = 0;
2550 int result = 0;
2551
2552 if( pyfsext_file_entry == NULL )
2553 {
2554 PyErr_Format(
2555 PyExc_ValueError,
2556 "%s: invalid file entry.",
2557 function );
2558
2559 return( NULL );
2560 }
2561 if( PyArg_ParseTupleAndKeywords(
2562 arguments,
2563 keywords,
2564 "OL",
2565 keyword_list,
2566 &integer_object,
2567 &read_offset ) == 0 )
2568 {
2569 return( NULL );
2570 }
2571 result = PyObject_IsInstance(
2572 integer_object,
2573 (PyObject *) &PyLong_Type );
2574
2575 if( result == -1 )
2576 {
2577 pyfsext_error_fetch_and_raise(
2578 PyExc_RuntimeError,
2579 "%s: unable to determine if integer object is of type long.",
2580 function );
2581
2582 return( NULL );
2583 }
2584 #if PY_MAJOR_VERSION < 3
2585 else if( result == 0 )
2586 {
2587 PyErr_Clear();
2588
2589 result = PyObject_IsInstance(
2590 integer_object,
2591 (PyObject *) &PyInt_Type );
2592
2593 if( result == -1 )
2594 {
2595 pyfsext_error_fetch_and_raise(
2596 PyExc_RuntimeError,
2597 "%s: unable to determine if integer object is of type int.",
2598 function );
2599
2600 return( NULL );
2601 }
2602 }
2603 #endif
2604 if( result != 0 )
2605 {
2606 if( pyfsext_integer_signed_copy_to_64bit(
2607 integer_object,
2608 &read_size,
2609 &error ) != 1 )
2610 {
2611 pyfsext_error_raise(
2612 error,
2613 PyExc_ValueError,
2614 "%s: unable to convert integer object into read size.",
2615 function );
2616
2617 libcerror_error_free(
2618 &error );
2619
2620 return( NULL );
2621 }
2622 }
2623 else
2624 {
2625 PyErr_Format(
2626 PyExc_TypeError,
2627 "%s: unsupported integer object type.",
2628 function );
2629
2630 return( NULL );
2631 }
2632 if( read_size == 0 )
2633 {
2634 #if PY_MAJOR_VERSION >= 3
2635 string_object = PyBytes_FromString(
2636 "" );
2637 #else
2638 string_object = PyString_FromString(
2639 "" );
2640 #endif
2641 return( string_object );
2642 }
2643 if( read_size < 0 )
2644 {
2645 PyErr_Format(
2646 PyExc_ValueError,
2647 "%s: invalid read size value less than zero.",
2648 function );
2649
2650 return( NULL );
2651 }
2652 /* Make sure the data fits into a memory buffer
2653 */
2654 if( ( read_size > (int64_t) INT_MAX )
2655 || ( read_size > (int64_t) SSIZE_MAX ) )
2656 {
2657 PyErr_Format(
2658 PyExc_ValueError,
2659 "%s: invalid argument read size value exceeds maximum.",
2660 function );
2661
2662 return( NULL );
2663 }
2664 if( read_offset < 0 )
2665 {
2666 PyErr_Format(
2667 PyExc_ValueError,
2668 "%s: invalid read offset value less than zero.",
2669 function );
2670
2671 return( NULL );
2672 }
2673 #if PY_MAJOR_VERSION >= 3
2674 string_object = PyBytes_FromStringAndSize(
2675 NULL,
2676 (Py_ssize_t) read_size );
2677
2678 buffer = PyBytes_AsString(
2679 string_object );
2680 #else
2681 /* Note that a size of 0 is not supported
2682 */
2683 string_object = PyString_FromStringAndSize(
2684 NULL,
2685 (Py_ssize_t) read_size );
2686
2687 buffer = PyString_AsString(
2688 string_object );
2689 #endif
2690 Py_BEGIN_ALLOW_THREADS
2691
2692 read_count = libfsext_file_entry_read_buffer_at_offset(
2693 pyfsext_file_entry->file_entry,
2694 (uint8_t *) buffer,
2695 (size_t) read_size,
2696 (off64_t) read_offset,
2697 &error );
2698
2699 Py_END_ALLOW_THREADS
2700
2701 if( read_count == -1 )
2702 {
2703 pyfsext_error_raise(
2704 error,
2705 PyExc_IOError,
2706 "%s: unable to read data.",
2707 function );
2708
2709 libcerror_error_free(
2710 &error );
2711
2712 Py_DecRef(
2713 (PyObject *) string_object );
2714
2715 return( NULL );
2716 }
2717 /* Need to resize the string here in case read_size was not fully read.
2718 */
2719 #if PY_MAJOR_VERSION >= 3
2720 if( _PyBytes_Resize(
2721 &string_object,
2722 (Py_ssize_t) read_count ) != 0 )
2723 #else
2724 if( _PyString_Resize(
2725 &string_object,
2726 (Py_ssize_t) read_count ) != 0 )
2727 #endif
2728 {
2729 Py_DecRef(
2730 (PyObject *) string_object );
2731
2732 return( NULL );
2733 }
2734 return( string_object );
2735 }
2736
2737 /* Seeks a certain offset
2738 * Returns a Python object if successful or NULL on error
2739 */
pyfsext_file_entry_seek_offset(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments,PyObject * keywords)2740 PyObject *pyfsext_file_entry_seek_offset(
2741 pyfsext_file_entry_t *pyfsext_file_entry,
2742 PyObject *arguments,
2743 PyObject *keywords )
2744 {
2745 libcerror_error_t *error = NULL;
2746 static char *function = "pyfsext_file_entry_seek_offset";
2747 static char *keyword_list[] = { "offset", "whence", NULL };
2748 off64_t offset = 0;
2749 int whence = 0;
2750
2751 if( pyfsext_file_entry == NULL )
2752 {
2753 PyErr_Format(
2754 PyExc_ValueError,
2755 "%s: invalid file entry.",
2756 function );
2757
2758 return( NULL );
2759 }
2760 if( PyArg_ParseTupleAndKeywords(
2761 arguments,
2762 keywords,
2763 "L|i",
2764 keyword_list,
2765 &offset,
2766 &whence ) == 0 )
2767 {
2768 return( NULL );
2769 }
2770 Py_BEGIN_ALLOW_THREADS
2771
2772 offset = libfsext_file_entry_seek_offset(
2773 pyfsext_file_entry->file_entry,
2774 offset,
2775 whence,
2776 &error );
2777
2778 Py_END_ALLOW_THREADS
2779
2780 if( offset == -1 )
2781 {
2782 pyfsext_error_raise(
2783 error,
2784 PyExc_IOError,
2785 "%s: unable to seek offset.",
2786 function );
2787
2788 libcerror_error_free(
2789 &error );
2790
2791 return( NULL );
2792 }
2793 Py_IncRef(
2794 Py_None );
2795
2796 return( Py_None );
2797 }
2798
2799 /* Retrieves the current offset of the data
2800 * Returns a Python object if successful or NULL on error
2801 */
pyfsext_file_entry_get_offset(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)2802 PyObject *pyfsext_file_entry_get_offset(
2803 pyfsext_file_entry_t *pyfsext_file_entry,
2804 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
2805 {
2806 PyObject *integer_object = NULL;
2807 libcerror_error_t *error = NULL;
2808 static char *function = "pyfsext_file_entry_get_offset";
2809 off64_t offset = 0;
2810 int result = 0;
2811
2812 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
2813
2814 if( pyfsext_file_entry == NULL )
2815 {
2816 PyErr_Format(
2817 PyExc_ValueError,
2818 "%s: invalid file entry.",
2819 function );
2820
2821 return( NULL );
2822 }
2823 Py_BEGIN_ALLOW_THREADS
2824
2825 result = libfsext_file_entry_get_offset(
2826 pyfsext_file_entry->file_entry,
2827 &offset,
2828 &error );
2829
2830 Py_END_ALLOW_THREADS
2831
2832 if( result == -1 )
2833 {
2834 pyfsext_error_raise(
2835 error,
2836 PyExc_IOError,
2837 "%s: unable to retrieve current offset of the data.",
2838 function );
2839
2840 libcerror_error_free(
2841 &error );
2842
2843 return( NULL );
2844 }
2845 else if( result == 0 )
2846 {
2847 Py_IncRef(
2848 Py_None );
2849
2850 return( Py_None );
2851 }
2852 integer_object = pyfsext_integer_signed_new_from_64bit(
2853 (int64_t) offset );
2854
2855 return( integer_object );
2856 }
2857
2858 /* Retrieves the size of the data
2859 * Returns a Python object if successful or NULL on error
2860 */
pyfsext_file_entry_get_size(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)2861 PyObject *pyfsext_file_entry_get_size(
2862 pyfsext_file_entry_t *pyfsext_file_entry,
2863 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
2864 {
2865 PyObject *integer_object = NULL;
2866 libcerror_error_t *error = NULL;
2867 static char *function = "pyfsext_file_entry_get_size";
2868 size64_t size = 0;
2869 int result = 0;
2870
2871 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
2872
2873 if( pyfsext_file_entry == NULL )
2874 {
2875 PyErr_Format(
2876 PyExc_ValueError,
2877 "%s: invalid file entry.",
2878 function );
2879
2880 return( NULL );
2881 }
2882 Py_BEGIN_ALLOW_THREADS
2883
2884 result = libfsext_file_entry_get_size(
2885 pyfsext_file_entry->file_entry,
2886 &size,
2887 &error );
2888
2889 Py_END_ALLOW_THREADS
2890
2891 if( result != 1 )
2892 {
2893 pyfsext_error_raise(
2894 error,
2895 PyExc_IOError,
2896 "%s: failed to retrieve size of the data.",
2897 function );
2898
2899 libcerror_error_free(
2900 &error );
2901
2902 return( NULL );
2903 }
2904 integer_object = pyfsext_integer_unsigned_new_from_64bit(
2905 (uint64_t) size );
2906
2907 return( integer_object );
2908 }
2909
2910 /* Retrieves the number of extents of the data
2911 * Returns a Python object if successful or NULL on error
2912 */
pyfsext_file_entry_get_number_of_extents(pyfsext_file_entry_t * pyfsext_file_entry,PyObject * arguments PYFSEXT_ATTRIBUTE_UNUSED)2913 PyObject *pyfsext_file_entry_get_number_of_extents(
2914 pyfsext_file_entry_t *pyfsext_file_entry,
2915 PyObject *arguments PYFSEXT_ATTRIBUTE_UNUSED )
2916 {
2917 PyObject *integer_object = NULL;
2918 libcerror_error_t *error = NULL;
2919 static char *function = "pyfsext_file_entry_get_number_of_extents";
2920 int number_of_extents = 0;
2921 int result = 0;
2922
2923 PYFSEXT_UNREFERENCED_PARAMETER( arguments )
2924
2925 if( pyfsext_file_entry == NULL )
2926 {
2927 PyErr_Format(
2928 PyExc_ValueError,
2929 "%s: invalid file entry.",
2930 function );
2931
2932 return( NULL );
2933 }
2934 Py_BEGIN_ALLOW_THREADS
2935
2936 result = libfsext_file_entry_get_number_of_extents(
2937 pyfsext_file_entry->file_entry,
2938 &number_of_extents,
2939 &error );
2940
2941 Py_END_ALLOW_THREADS
2942
2943 if( result != 1 )
2944 {
2945 pyfsext_error_raise(
2946 error,
2947 PyExc_IOError,
2948 "%s: unable to retrieve number of extents of the data.",
2949 function );
2950
2951 libcerror_error_free(
2952 &error );
2953
2954 return( NULL );
2955 }
2956 #if PY_MAJOR_VERSION >= 3
2957 integer_object = PyLong_FromLong(
2958 (long) number_of_extents );
2959 #else
2960 integer_object = PyInt_FromLong(
2961 (long) number_of_extents );
2962 #endif
2963 return( integer_object );
2964 }
2965
2966