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