magic.py 6.4 KB

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