Advertisement
Guest User

OS X hidden files

a guest
Mar 8th, 2013
911
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2.  
  3. import contextlib
  4. import ctypes
  5.  
  6. cf = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')
  7.  
  8. cf.CFShow.argtypes = [ctypes.c_void_p]
  9. cf.CFShow.restype = None
  10.  
  11. cf.CFRelease.argtypes = [ctypes.c_void_p]
  12. cf.CFRelease.restype = None
  13.  
  14. cf.CFStringCreateWithBytes.argtypes = [ctypes.c_void_p,
  15.                                        ctypes.c_char_p, ctypes.c_long,
  16.                                        ctypes.c_int, ctypes.c_int]
  17. cf.CFStringCreateWithBytes.restype = ctypes.c_void_p
  18.  
  19. cf.CFStringGetMaximumSizeOfFileSystemRepresentation.argtypes = [ctypes.c_void_p]
  20. cf.CFStringGetMaximumSizeOfFileSystemRepresentation.restype = ctypes.c_int
  21.  
  22. cf.CFStringGetFileSystemRepresentation.argtypes = [ctypes.c_void_p,
  23.                                                    ctypes.c_char_p,
  24.                                                    ctypes.c_long]
  25. cf.CFStringGetFileSystemRepresentation.restype = ctypes.c_int
  26.  
  27. cf.CFURLCreateFromFileSystemRepresentation.argtypes = [ctypes.c_void_p,
  28.                                                        ctypes.c_char_p,
  29.                                                        ctypes.c_long,
  30.                                                        ctypes.c_int]
  31. cf.CFURLCreateFromFileSystemRepresentation.restype = ctypes.c_void_p
  32.  
  33. cf.CFURLCopyResourcePropertyForKey.argtypes = [ctypes.c_void_p,
  34.                                                ctypes.c_void_p,
  35.                                                ctypes.c_void_p,
  36.                                                ctypes.c_void_p]
  37. cf.CFURLCopyResourcePropertyForKey.restype = ctypes.c_int
  38.  
  39. cf.CFBooleanGetValue.argtypes = [ctypes.c_void_p]
  40. cf.CFBooleanGetValue.restype = ctypes.c_int
  41.  
  42. cf.CFURLEnumeratorCreateForDirectoryURL.argtypes = [ctypes.c_void_p,
  43.                                                     ctypes.c_void_p,
  44.                                                     ctypes.c_int,
  45.                                                     ctypes.c_void_p]
  46. cf.CFURLEnumeratorCreateForDirectoryURL.restype = ctypes.c_void_p
  47.  
  48.  
  49. cf.CFURLEnumeratorGetNextURL.argtypes = [ctypes.c_void_p,
  50.                                          ctypes.c_void_p,
  51.                                          ctypes.c_void_p]
  52. cf.CFURLEnumeratorGetNextURL.restype = ctypes.c_int
  53.  
  54. cf.CFURLCopyFileSystemPath.argtypes = [ctypes.c_void_p, ctypes.c_int]
  55. cf.CFURLCopyFileSystemPath.restype = ctypes.c_void_p
  56.  
  57. # From CFString.h
  58. # http://www.opensource.apple.com/source/CF/CF-744/CFString.h
  59. # The value has been the same from at least 10.2-10.8.
  60. kCFStringEncodingUTF8 = 0x08000100
  61.  
  62. # Documented here:
  63. # https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFURLEnumeratorRef/Reference/reference.html
  64. kCFURLEnumeratorSkipInvisibles = 1 << 1
  65.  
  66. kCFURLEnumeratorSuccess = 1
  67. kCFURLEnumeratorEnd = 2
  68. kCFURLEnumeratorError = 3
  69. kCFURLEnumeratorDirectoryPostOrderSuccess = 4
  70.  
  71. # Documented here:
  72. # http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFURLRef/Reference/reference.html
  73. kCFURLPOSIXPathStyle = 0
  74.  
  75. # This one is a static CFStringRef.
  76. kCFURLIsHiddenKey = ctypes.c_void_p.in_dll(cf, 'kCFURLIsHiddenKey')
  77.  
  78. @contextlib.contextmanager
  79. def cfreleasing(stuff):
  80.     try:
  81.         yield
  82.     finally:
  83.         for thing in stuff:
  84.             cf.CFRelease(thing)
  85.  
  86. def cfstr_to_unicode(cfstr):
  87.     count = cf.CFStringGetMaximumSizeOfFileSystemRepresentation(cfstr)
  88.     buf = (ctypes.c_char * count)()
  89.     if cf.CFStringGetFileSystemRepresentation(cfstr, buf, count):
  90.         return buf.value.decode('UTF-8')
  91.     raise OSError('CFStringGetFileSystemRepresentation failed')
  92.  
  93. def is_hidden(path):
  94.     if not isinstance(path, bytes):
  95.         path = path.encode('UTF-8')
  96.     stuff = []
  97.     with cfreleasing(stuff):
  98.         url = cf.CFURLCreateFromFileSystemRepresentation(None, path, len(path), False)
  99.         stuff.append(url)
  100.         val = ctypes.c_void_p(0)
  101.         ret = cf.CFURLCopyResourcePropertyForKey(url, kCFURLIsHiddenKey,
  102.                                                  ctypes.addressof(val), None)
  103.         if ret:
  104.             result = cf.CFBooleanGetValue(val)
  105.             stuff.append(val)
  106.             return True if result else False
  107.         # TODO: You could pass a CFErrorRef instead of None, and do all the
  108.         # work to wrap that in a Python exception, etc.
  109.         raise OSError('CFURLCopyResourcePropertyForKey failed')
  110.  
  111. def listdir_skipping_hidden(path):
  112.     if not isinstance(path, bytes):
  113.         path = path.encode('UTF-8')
  114.     stuff = []
  115.     with cfreleasing(stuff):
  116.         url = cf.CFURLCreateFromFileSystemRepresentation(None,
  117.                                                          path, len(path),
  118.                                                          True)
  119.         stuff.append(url)
  120.         enum = cf.CFURLEnumeratorCreateForDirectoryURL(None, url,
  121.                                                        kCFURLEnumeratorSkipInvisibles,
  122.                                                        None)
  123.         stuff.append(enum)
  124.         paths = []
  125.         while True:
  126.             url = ctypes.c_void_p(0)
  127.             ret = cf.CFURLEnumeratorGetNextURL(enum, ctypes.addressof(url), None)
  128.             if ret != kCFURLEnumeratorSuccess:
  129.                 break
  130.             path = cf.CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle)
  131.             stuff.append(path)
  132.             paths.append(cfstr_to_unicode(path))
  133.         return paths
  134.  
  135. if __name__ == '__main__':
  136.     import sys
  137.     for arg in sys.argv[1:]:
  138.         print('{}: {}'.format(arg, is_hidden(arg)))
  139.         if arg[-1] == '/':
  140.             for path in listdir_skipping_hidden(arg):
  141.                 print('  {}'.format(path))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement