1#!/usr/bin/env python 2''' 3Python bindings for libmagic 4''' 5 6import ctypes 7 8from ctypes import * 9from ctypes.util import find_library 10 11 12def _init(): 13 """ 14 Loads the shared library through ctypes and returns a library 15 L{ctypes.CDLL} instance 16 """ 17 return ctypes.cdll.LoadLibrary(find_library('magic')) 18 19_libraries = {} 20_libraries['magic'] = _init() 21 22# Flag constants for open and setflags 23MAGIC_NONE = NONE = 0 24MAGIC_DEBUG = DEBUG = 1 25MAGIC_SYMLINK = SYMLINK = 2 26MAGIC_COMPRESS = COMPRESS = 4 27MAGIC_DEVICES = DEVICES = 8 28MAGIC_MIME_TYPE = MIME_TYPE = 16 29MAGIC_CONTINUE = CONTINUE = 32 30MAGIC_CHECK = CHECK = 64 31MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128 32MAGIC_RAW = RAW = 256 33MAGIC_ERROR = ERROR = 512 34MAGIC_MIME_ENCODING = MIME_ENCODING = 1024 35MAGIC_MIME = MIME = 1040 36MAGIC_APPLE = APPLE = 2048 37 38MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096 39MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192 40MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384 41MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768 42MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536 43MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072 44MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144 45MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576 46MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152 47 48MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824 49 50 51class magic_set(Structure): 52 pass 53magic_set._fields_ = [] 54magic_t = POINTER(magic_set) 55 56_open = _libraries['magic'].magic_open 57_open.restype = magic_t 58_open.argtypes = [c_int] 59 60_close = _libraries['magic'].magic_close 61_close.restype = None 62_close.argtypes = [magic_t] 63 64_file = _libraries['magic'].magic_file 65_file.restype = c_char_p 66_file.argtypes = [magic_t, c_char_p] 67 68_descriptor = _libraries['magic'].magic_descriptor 69_descriptor.restype = c_char_p 70_descriptor.argtypes = [magic_t, c_int] 71 72_buffer = _libraries['magic'].magic_buffer 73_buffer.restype = c_char_p 74_buffer.argtypes = [magic_t, c_void_p, c_size_t] 75 76_error = _libraries['magic'].magic_error 77_error.restype = c_char_p 78_error.argtypes = [magic_t] 79 80_setflags = _libraries['magic'].magic_setflags 81_setflags.restype = c_int 82_setflags.argtypes = [magic_t, c_int] 83 84_load = _libraries['magic'].magic_load 85_load.restype = c_int 86_load.argtypes = [magic_t, c_char_p] 87 88_compile = _libraries['magic'].magic_compile 89_compile.restype = c_int 90_compile.argtypes = [magic_t, c_char_p] 91 92_check = _libraries['magic'].magic_check 93_check.restype = c_int 94_check.argtypes = [magic_t, c_char_p] 95 96_list = _libraries['magic'].magic_list 97_list.restype = c_int 98_list.argtypes = [magic_t, c_char_p] 99 100_errno = _libraries['magic'].magic_errno 101_errno.restype = c_int 102_errno.argtypes = [magic_t] 103 104 105class Magic(object): 106 def __init__(self, ms): 107 self._magic_t = ms 108 109 def close(self): 110 """ 111 Closes the magic database and deallocates any resources used. 112 """ 113 _close(self._magic_t) 114 115 def file(self, filename): 116 """ 117 Returns a textual description of the contents of the argument passed 118 as a filename or None if an error occurred and the MAGIC_ERROR flag 119 is set. A call to errno() will return the numeric error code. 120 """ 121 try: # attempt python3 approach first 122 if isinstance(filename, bytes): 123 bi = filename 124 else: 125 bi = bytes(filename, 'utf-8') 126 return str(_file(self._magic_t, bi), 'utf-8') 127 except: 128 return _file(self._magic_t, filename.encode('utf-8')) 129 130 def descriptor(self, fd): 131 """ 132 Like the file method, but the argument is a file descriptor. 133 """ 134 return _descriptor(self._magic_t, fd) 135 136 def buffer(self, buf): 137 """ 138 Returns a textual description of the contents of the argument passed 139 as a buffer or None if an error occurred and the MAGIC_ERROR flag 140 is set. A call to errno() will return the numeric error code. 141 """ 142 try: # attempt python3 approach first 143 return str(_buffer(self._magic_t, buf, len(buf)), 'utf-8') 144 except: 145 return _buffer(self._magic_t, buf, len(buf)) 146 147 def error(self): 148 """ 149 Returns a textual explanation of the last error or None 150 if there was no error. 151 """ 152 try: # attempt python3 approach first 153 return str(_error(self._magic_t), 'utf-8') 154 except: 155 return _error(self._magic_t) 156 157 def setflags(self, flags): 158 """ 159 Set flags on the magic object which determine how magic checking 160 behaves; a bitwise OR of the flags described in libmagic(3), but 161 without the MAGIC_ prefix. 162 163 Returns -1 on systems that don't support utime(2) or utimes(2) 164 when PRESERVE_ATIME is set. 165 """ 166 return _setflags(self._magic_t, flags) 167 168 def load(self, filename=None): 169 """ 170 Must be called to load entries in the colon separated list of database 171 files passed as argument or the default database file if no argument 172 before any magic queries can be performed. 173 174 Returns 0 on success and -1 on failure. 175 """ 176 return _load(self._magic_t, filename) 177 178 def compile(self, dbs): 179 """ 180 Compile entries in the colon separated list of database files 181 passed as argument or the default database file if no argument. 182 Returns 0 on success and -1 on failure. 183 The compiled files created are named from the basename(1) of each file 184 argument with ".mgc" appended to it. 185 """ 186 return _compile(self._magic_t, dbs) 187 188 def check(self, dbs): 189 """ 190 Check the validity of entries in the colon separated list of 191 database files passed as argument or the default database file 192 if no argument. 193 Returns 0 on success and -1 on failure. 194 """ 195 return _check(self._magic_t, dbs) 196 197 def list(self, dbs): 198 """ 199 Check the validity of entries in the colon separated list of 200 database files passed as argument or the default database file 201 if no argument. 202 Returns 0 on success and -1 on failure. 203 """ 204 return _list(self._magic_t, dbs) 205 206 def errno(self): 207 """ 208 Returns a numeric error code. If return value is 0, an internal 209 magic error occurred. If return value is non-zero, the value is 210 an OS error code. Use the errno module or os.strerror() can be used 211 to provide detailed error information. 212 """ 213 return _errno(self._magic_t) 214 215 216def open(flags): 217 """ 218 Returns a magic object on success and None on failure. 219 Flags argument as for setflags. 220 """ 221 return Magic(_open(flags)) 222