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 - [email protected]
http://mail.python.org/mailman/listinfo/pythonmac-sig