Thanks Nicholas,
The general CF rule is that if you use a function named *Get*, then you don't need to CFRelease; if you use a function named *Copy* or *Create*, you do. So, what you've written looks fine.
With that in mind one further modification seems to be necessary. Take three attached.
~ Daniel
def getproxies_internetconfig(): """Return a dictionary of scheme -> proxy server URL mappings. This function has 'internetconfig' in its name for historical reasons only. It now uses the more modern 'SystemConfiguration' to obtain its result. """ from ctypes import cdll, byref, c_int, create_string_buffer from ctypes.util import find_library sc = cdll.LoadLibrary(find_library("SystemConfiguration")) if not sc: return {} def CStringFromCFString(value): length = sc.CFStringGetLength(value) + 1 buff = create_string_buffer(length) sc.CFStringGetCString(value, buff, length, 0) return buff.value def CFNumberToInt32(cfnum): val = c_int() sc.CFNumberGetValue(cfnum, kCFNumberSInt32Type, byref(val)) return val.value kCFNumberSInt32Type = 3 kSCPropNetProxiesHTTPEnable = sc.CFStringCreateWithCString(0, "HTTPEnable", 0) kSCPropNetProxiesHTTPProxy = sc.CFStringCreateWithCString(0, "HTTPProxy", 0) kSCPropNetProxiesHTTPPort = sc.CFStringCreateWithCString(0, "HTTPPort", 0) proxies = {} proxyDict = sc.SCDynamicStoreCopyProxies(None) try: # HTTP: enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPEnable) if sc.CFBooleanGetValue(enabled): proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPProxy) proxy = CStringFromCFString(proxy) port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPPort) port = CFNumberToInt32(port) proxies["http"] = "http://%s:%i" % (proxy, port) # FTP: XXXX To be done. # Gopher: XXXX To be done. finally: sc.CFRelease(proxyDict) sc.CFRelease(kSCPropNetProxiesHTTPEnable) sc.CFRelease(kSCPropNetProxiesHTTPProxy) sc.CFRelease(kSCPropNetProxiesHTTPPort) return proxies def getproxies_internetconfig_ic(): """Return a dictionary of scheme -> proxy server URL mappings. By convention the mac uses Internet Config to store proxies. An HTTP proxy, for instance, is stored under the HttpProxy key. """ from ctypes import cdll, byref, c_void_p, c_int, c_long, create_string_buffer from ctypes.util import find_library ic = cdll.LoadLibrary(find_library("Internet_Config")) if not ic: return {} proxies = {} icReadOnlyPerm = 1 icinst = c_void_p(None) attr = c_int(0) ic.ICStart(byref(icinst), 0) ic.ICBegin(icinst, icReadOnlyPerm) try: # HTTP: bsize = c_long(255) buff = create_string_buffer(255) error = ic.ICGetPref(icinst, "\x0cUseHTTPProxy", byref(attr), byref(buff), byref(bsize)) useHTTPProxy = not error and ord(buff[0]) if useHTTPProxy: bsize = c_long(255) error = ic.ICGetPref(icinst, "\rHTTPProxyHost", byref(attr), byref(buff), byref(bsize)) if not error and bsize.value > 0: # not sure why there's an extra character on the beginning of buff proxies["http"] = "http://" + buff.value[1:bsize.value] # FTP: XXXX To be done. # Gopher: XXXX To be done. finally: ic.ICEnd(icinst) ic.ICStop(icinst) return proxies def getproxies_internetconfig_original(): """Return a dictionary of scheme -> proxy server URL mappings. By convention the mac uses Internet Config to store proxies. An HTTP proxy, for instance, is stored under the HttpProxy key. """ try: import ic except ImportError: return {} try: config = ic.IC() except ic.error: return {} proxies = {} # HTTP: if 'UseHTTPProxy' in config and config['UseHTTPProxy']: try: value = config['HTTPProxyHost'] except ic.error: pass else: proxies['http'] = 'http://%s' % value # FTP: XXXX To be done. # Gopher: XXXX To be done. return proxies class CtypesLogger(object): def __init__(self, lib): self.lib = lib def __getattr__(self, name): class c_func_wrapper(object): def __init__(self, func, name): self.__dict__["func"] = func self.__dict__["name"] = name def __getattr__(self, name): return getattr(self.func, name) def __setattr__(self, name, value): setattr(self.func, name, value) def __call__(self, *args): result = self.func(*args) print "%s%s -> %s" % (self.name, args, result) return result return c_func_wrapper(getattr(self.lib, name), name) def test1(): from ctypes import cdll, byref, c_void_p, c_int, c_long, create_string_buffer from ctypes.util import find_library ic = cdll.LoadLibrary(find_library("Internet_Config")) #ic = CtypesLogger(ic) icReadOnlyPerm = 1 icinst = c_void_p(None) attr = c_int(0) ic.ICStart(byref(icinst), 0) ic.ICBegin(icinst, icReadOnlyPerm) try: bsize = c_long(255) buff = create_string_buffer(255) result = ic.ICGetPref(icinst, "\x0cUseHTTPProxy", byref(attr), byref(buff), byref(bsize)) print "%r %s" % (ord(buff[0]), bsize) bsize = c_long(255) result = ic.ICGetPref(icinst, "\rHTTPProxyHost", byref(attr), byref(buff), byref(bsize)) print "%r %s" % (buff.value, bsize) finally: ic.ICEnd(icinst) ic.ICStop(icinst) #ic.DisposeHandle(handle) def test2(): from ctypes import cdll, byref, cast, c_char, c_void_p, c_int, c_long, create_string_buffer from ctypes.util import find_library sc = cdll.LoadLibrary(find_library("SystemConfiguration")) #sc = CtypesLogger(sc) def create_cfstringref(cstr): return sc.CFStringCreateWithCString(0, cstr, 0) kCFNumberSInt32Type = 3 kSCPropNetProxiesHTTPEnable = create_cfstringref("HTTPEnable") kSCPropNetProxiesHTTPProxy = create_cfstringref("HTTPProxy") kSCPropNetProxiesHTTPPort = create_cfstringref("HTTPPort") def CStringFromCFString(value): length = sc.CFStringGetLength(value) + 1 buff = create_string_buffer(length) sc.CFStringGetCString(value, buff, length, 0) return buff.value def CFNumberToInt32(cfnum): val = c_int() sc.CFNumberGetValue(cfnum, kCFNumberSInt32Type, byref(val)) return val.value proxyDict = sc.SCDynamicStoreCopyProxies(None) try: num = sc.CFDictionaryGetCount(proxyDict) pointer_array_type = c_void_p * num keys = pointer_array_type() vals = pointer_array_type() sc.CFDictionaryGetKeysAndValues(proxyDict, keys, vals) for i in xrange(num): key = CStringFromCFString(keys[i]) print "%r = %r" % (key, vals[i]) enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPEnable) if sc.CFBooleanGetValue(enabled): proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPProxy) proxy = CStringFromCFString(proxy) port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPPort) port = CFNumberToInt32(port) #print CStringFromCFString(val) finally: sc.CFRelease(proxyDict) # icReadOnlyPerm = 1 # icinst = c_void_p(None) # attr = c_int(0) # ic.ICStart(byref(icinst), 0) # ic.ICBegin(icinst, icReadOnlyPerm) # try: # bsize = c_long(255) # buff = create_string_buffer(255) # result = ic.ICGetPref(icinst, "\x0cUseHTTPProxy", byref(attr), byref(buff), byref(bsize)) # print "%r %s" % (ord(buff[0]), bsize) # # bsize = c_long(255) # result = ic.ICGetPref(icinst, "\rHTTPProxyHost", byref(attr), byref(buff), byref(bsize)) # print "%r %s" % (buff.value, bsize) # # finally: # ic.ICEnd(icinst) # ic.ICStop(icinst) # #ic.DisposeHandle(handle) test2() print getproxies_internetconfig()
_______________________________________________ Pythonmac-SIG maillist - Pythonmac-SIG@python.org http://mail.python.org/mailman/listinfo/pythonmac-sig