1267843Sdelphij#!/usr/bin/env python 2267843Sdelphij''' 3267843SdelphijPython bindings for libmagic 4267843Sdelphij''' 5267843Sdelphij 6267843Sdelphijimport ctypes 7267843Sdelphij 8267843Sdelphijfrom ctypes import * 9267843Sdelphijfrom ctypes.util import find_library 10267843Sdelphij 11267843Sdelphij 12267843Sdelphijdef _init(): 13267843Sdelphij """ 14267843Sdelphij Loads the shared library through ctypes and returns a library 15267843Sdelphij L{ctypes.CDLL} instance 16267843Sdelphij """ 17267843Sdelphij return ctypes.cdll.LoadLibrary(find_library('magic')) 18267843Sdelphij 19267843Sdelphij_libraries = {} 20267843Sdelphij_libraries['magic'] = _init() 21267843Sdelphij 22267843Sdelphij# Flag constants for open and setflags 23267843SdelphijMAGIC_NONE = NONE = 0 24267843SdelphijMAGIC_DEBUG = DEBUG = 1 25267843SdelphijMAGIC_SYMLINK = SYMLINK = 2 26267843SdelphijMAGIC_COMPRESS = COMPRESS = 4 27267843SdelphijMAGIC_DEVICES = DEVICES = 8 28267843SdelphijMAGIC_MIME_TYPE = MIME_TYPE = 16 29267843SdelphijMAGIC_CONTINUE = CONTINUE = 32 30267843SdelphijMAGIC_CHECK = CHECK = 64 31267843SdelphijMAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128 32267843SdelphijMAGIC_RAW = RAW = 256 33267843SdelphijMAGIC_ERROR = ERROR = 512 34267843SdelphijMAGIC_MIME_ENCODING = MIME_ENCODING = 1024 35267843SdelphijMAGIC_MIME = MIME = 1040 36267843SdelphijMAGIC_APPLE = APPLE = 2048 37267843Sdelphij 38267843SdelphijMAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096 39267843SdelphijMAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192 40267843SdelphijMAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384 41267843SdelphijMAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768 42267843SdelphijMAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536 43267843SdelphijMAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072 44267843SdelphijMAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144 45267843SdelphijMAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576 46267843SdelphijMAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152 47267843Sdelphij 48267843SdelphijMAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824 49267843Sdelphij 50267843Sdelphij 51267843Sdelphijclass magic_set(Structure): 52267843Sdelphij pass 53267843Sdelphijmagic_set._fields_ = [] 54267843Sdelphijmagic_t = POINTER(magic_set) 55267843Sdelphij 56267843Sdelphij_open = _libraries['magic'].magic_open 57267843Sdelphij_open.restype = magic_t 58267843Sdelphij_open.argtypes = [c_int] 59267843Sdelphij 60267843Sdelphij_close = _libraries['magic'].magic_close 61267843Sdelphij_close.restype = None 62267843Sdelphij_close.argtypes = [magic_t] 63267843Sdelphij 64267843Sdelphij_file = _libraries['magic'].magic_file 65267843Sdelphij_file.restype = c_char_p 66267843Sdelphij_file.argtypes = [magic_t, c_char_p] 67267843Sdelphij 68267843Sdelphij_descriptor = _libraries['magic'].magic_descriptor 69267843Sdelphij_descriptor.restype = c_char_p 70267843Sdelphij_descriptor.argtypes = [magic_t, c_int] 71267843Sdelphij 72267843Sdelphij_buffer = _libraries['magic'].magic_buffer 73267843Sdelphij_buffer.restype = c_char_p 74267843Sdelphij_buffer.argtypes = [magic_t, c_void_p, c_size_t] 75267843Sdelphij 76267843Sdelphij_error = _libraries['magic'].magic_error 77267843Sdelphij_error.restype = c_char_p 78267843Sdelphij_error.argtypes = [magic_t] 79267843Sdelphij 80267843Sdelphij_setflags = _libraries['magic'].magic_setflags 81267843Sdelphij_setflags.restype = c_int 82267843Sdelphij_setflags.argtypes = [magic_t, c_int] 83267843Sdelphij 84267843Sdelphij_load = _libraries['magic'].magic_load 85267843Sdelphij_load.restype = c_int 86267843Sdelphij_load.argtypes = [magic_t, c_char_p] 87267843Sdelphij 88267843Sdelphij_compile = _libraries['magic'].magic_compile 89267843Sdelphij_compile.restype = c_int 90267843Sdelphij_compile.argtypes = [magic_t, c_char_p] 91267843Sdelphij 92267843Sdelphij_check = _libraries['magic'].magic_check 93267843Sdelphij_check.restype = c_int 94267843Sdelphij_check.argtypes = [magic_t, c_char_p] 95267843Sdelphij 96267843Sdelphij_list = _libraries['magic'].magic_list 97267843Sdelphij_list.restype = c_int 98267843Sdelphij_list.argtypes = [magic_t, c_char_p] 99267843Sdelphij 100267843Sdelphij_errno = _libraries['magic'].magic_errno 101267843Sdelphij_errno.restype = c_int 102267843Sdelphij_errno.argtypes = [magic_t] 103267843Sdelphij 104267843Sdelphij 105267843Sdelphijclass Magic(object): 106267843Sdelphij def __init__(self, ms): 107267843Sdelphij self._magic_t = ms 108267843Sdelphij 109267843Sdelphij def close(self): 110267843Sdelphij """ 111267843Sdelphij Closes the magic database and deallocates any resources used. 112267843Sdelphij """ 113267843Sdelphij _close(self._magic_t) 114267843Sdelphij 115267843Sdelphij def file(self, filename): 116267843Sdelphij """ 117267843Sdelphij Returns a textual description of the contents of the argument passed 118267843Sdelphij as a filename or None if an error occurred and the MAGIC_ERROR flag 119267843Sdelphij is set. A call to errno() will return the numeric error code. 120267843Sdelphij """ 121267843Sdelphij try: # attempt python3 approach first 122267843Sdelphij if isinstance(filename, bytes): 123267843Sdelphij bi = filename 124267843Sdelphij else: 125267843Sdelphij bi = bytes(filename, 'utf-8') 126267843Sdelphij return str(_file(self._magic_t, bi), 'utf-8') 127267843Sdelphij except: 128267843Sdelphij return _file(self._magic_t, filename.encode('utf-8')) 129267843Sdelphij 130267843Sdelphij def descriptor(self, fd): 131267843Sdelphij """ 132267843Sdelphij Like the file method, but the argument is a file descriptor. 133267843Sdelphij """ 134267843Sdelphij return _descriptor(self._magic_t, fd) 135267843Sdelphij 136267843Sdelphij def buffer(self, buf): 137267843Sdelphij """ 138267843Sdelphij Returns a textual description of the contents of the argument passed 139267843Sdelphij as a buffer or None if an error occurred and the MAGIC_ERROR flag 140267843Sdelphij is set. A call to errno() will return the numeric error code. 141267843Sdelphij """ 142267843Sdelphij try: # attempt python3 approach first 143267843Sdelphij return str(_buffer(self._magic_t, buf, len(buf)), 'utf-8') 144267843Sdelphij except: 145267843Sdelphij return _buffer(self._magic_t, buf, len(buf)) 146267843Sdelphij 147267843Sdelphij def error(self): 148267843Sdelphij """ 149267843Sdelphij Returns a textual explanation of the last error or None 150267843Sdelphij if there was no error. 151267843Sdelphij """ 152267843Sdelphij try: # attempt python3 approach first 153267843Sdelphij return str(_error(self._magic_t), 'utf-8') 154267843Sdelphij except: 155267843Sdelphij return _error(self._magic_t) 156267843Sdelphij 157267843Sdelphij def setflags(self, flags): 158267843Sdelphij """ 159267843Sdelphij Set flags on the magic object which determine how magic checking 160267843Sdelphij behaves; a bitwise OR of the flags described in libmagic(3), but 161267843Sdelphij without the MAGIC_ prefix. 162267843Sdelphij 163267843Sdelphij Returns -1 on systems that don't support utime(2) or utimes(2) 164267843Sdelphij when PRESERVE_ATIME is set. 165267843Sdelphij """ 166267843Sdelphij return _setflags(self._magic_t, flags) 167267843Sdelphij 168267843Sdelphij def load(self, filename=None): 169267843Sdelphij """ 170267843Sdelphij Must be called to load entries in the colon separated list of database 171267843Sdelphij files passed as argument or the default database file if no argument 172267843Sdelphij before any magic queries can be performed. 173267843Sdelphij 174267843Sdelphij Returns 0 on success and -1 on failure. 175267843Sdelphij """ 176267843Sdelphij return _load(self._magic_t, filename) 177267843Sdelphij 178267843Sdelphij def compile(self, dbs): 179267843Sdelphij """ 180267843Sdelphij Compile entries in the colon separated list of database files 181267843Sdelphij passed as argument or the default database file if no argument. 182267843Sdelphij Returns 0 on success and -1 on failure. 183267843Sdelphij The compiled files created are named from the basename(1) of each file 184267843Sdelphij argument with ".mgc" appended to it. 185267843Sdelphij """ 186267843Sdelphij return _compile(self._magic_t, dbs) 187267843Sdelphij 188267843Sdelphij def check(self, dbs): 189267843Sdelphij """ 190267843Sdelphij Check the validity of entries in the colon separated list of 191267843Sdelphij database files passed as argument or the default database file 192267843Sdelphij if no argument. 193267843Sdelphij Returns 0 on success and -1 on failure. 194267843Sdelphij """ 195267843Sdelphij return _check(self._magic_t, dbs) 196267843Sdelphij 197267843Sdelphij def list(self, dbs): 198267843Sdelphij """ 199267843Sdelphij Check the validity of entries in the colon separated list of 200267843Sdelphij database files passed as argument or the default database file 201267843Sdelphij if no argument. 202267843Sdelphij Returns 0 on success and -1 on failure. 203267843Sdelphij """ 204267843Sdelphij return _list(self._magic_t, dbs) 205267843Sdelphij 206267843Sdelphij def errno(self): 207267843Sdelphij """ 208267843Sdelphij Returns a numeric error code. If return value is 0, an internal 209267843Sdelphij magic error occurred. If return value is non-zero, the value is 210267843Sdelphij an OS error code. Use the errno module or os.strerror() can be used 211267843Sdelphij to provide detailed error information. 212267843Sdelphij """ 213267843Sdelphij return _errno(self._magic_t) 214267843Sdelphij 215267843Sdelphij 216267843Sdelphijdef open(flags): 217267843Sdelphij """ 218267843Sdelphij Returns a magic object on success and None on failure. 219267843Sdelphij Flags argument as for setflags. 220267843Sdelphij """ 221267843Sdelphij return Magic(_open(flags)) 222