typo: use one instead instead of two
[python.git] / Mac / Modules / _scproxy.c
blob003f6a483f09a677629da51a2ee4b5ab3d49f87b
1 /*
2 * Helper method for urllib to fetch the proxy configuration settings
3 * using the SystemConfiguration framework.
4 */
5 #include <Python.h>
6 #include <SystemConfiguration/SystemConfiguration.h>
8 static int32_t
9 cfnum_to_int32(CFNumberRef num)
11 int32_t result;
13 CFNumberGetValue(num, kCFNumberSInt32Type, &result);
14 return result;
17 static PyObject*
18 cfstring_to_pystring(CFStringRef ref)
20 const char* s;
22 s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8);
23 if (s) {
24 return PyString_FromString(s);
26 } else {
27 CFIndex len = CFStringGetLength(ref);
28 Boolean ok;
29 PyObject* result;
30 result = PyString_FromStringAndSize(NULL, len*4);
32 ok = CFStringGetCString(ref,
33 PyString_AS_STRING(result),
34 PyString_GET_SIZE(result),
35 kCFStringEncodingUTF8);
36 if (!ok) {
37 Py_DECREF(result);
38 return NULL;
39 } else {
40 _PyString_Resize(&result,
41 strlen(PyString_AS_STRING(result)));
43 return result;
48 static PyObject*
49 get_proxy_settings(PyObject* mod __attribute__((__unused__)))
51 CFDictionaryRef proxyDict = NULL;
52 CFNumberRef aNum = NULL;
53 CFArrayRef anArray = NULL;
54 PyObject* result = NULL;
55 PyObject* v;
56 int r;
58 proxyDict = SCDynamicStoreCopyProxies(NULL);
59 if (!proxyDict) {
60 Py_INCREF(Py_None);
61 return Py_None;
64 result = PyDict_New();
65 if (result == NULL) goto error;
67 aNum = CFDictionaryGetValue(proxyDict,
68 kSCPropNetProxiesExcludeSimpleHostnames);
69 if (aNum == NULL) {
70 v = PyBool_FromLong(0);
71 } else {
72 v = PyBool_FromLong(cfnum_to_int32(aNum));
74 if (v == NULL) goto error;
76 r = PyDict_SetItemString(result, "exclude_simple", v);
77 Py_DECREF(v); v = NULL;
78 if (r == -1) goto error;
80 anArray = CFDictionaryGetValue(proxyDict,
81 kSCPropNetProxiesExceptionsList);
82 if (anArray != NULL) {
83 CFIndex len = CFArrayGetCount(anArray);
84 CFIndex i;
85 v = PyTuple_New(len);
86 if (v == NULL) goto error;
88 r = PyDict_SetItemString(result, "exceptions", v);
89 Py_DECREF(v);
90 if (r == -1) goto error;
92 for (i = 0; i < len; i++) {
93 CFStringRef aString = NULL;
95 aString = CFArrayGetValueAtIndex(anArray, i);
96 if (aString == NULL) {
97 PyTuple_SetItem(v, i, Py_None);
98 Py_INCREF(Py_None);
99 } else {
100 PyObject* t = cfstring_to_pystring(aString);
101 if (!t) {
102 PyTuple_SetItem(v, i, Py_None);
103 Py_INCREF(Py_None);
104 } else {
105 PyTuple_SetItem(v, i, t);
111 CFRelease(proxyDict);
112 return result;
114 error:
115 if (proxyDict) CFRelease(proxyDict);
116 Py_XDECREF(result);
117 return NULL;
120 static int
121 set_proxy(PyObject* proxies, char* proto, CFDictionaryRef proxyDict,
122 CFStringRef enabledKey,
123 CFStringRef hostKey, CFStringRef portKey)
125 CFNumberRef aNum;
127 aNum = CFDictionaryGetValue(proxyDict, enabledKey);
128 if (aNum && cfnum_to_int32(aNum)) {
129 CFStringRef hostString;
131 hostString = CFDictionaryGetValue(proxyDict, hostKey);
132 aNum = CFDictionaryGetValue(proxyDict, portKey);
134 if (hostString) {
135 int r;
136 PyObject* h = cfstring_to_pystring(hostString);
137 PyObject* v;
138 if (h) {
139 if (aNum) {
140 int32_t port = cfnum_to_int32(aNum);
141 v = PyString_FromFormat("http://%s:%ld",
142 PyString_AS_STRING(h),
143 (long)port);
144 } else {
145 v = PyString_FromFormat("http://%s",
146 PyString_AS_STRING(h));
148 Py_DECREF(h);
149 if (!v) return -1;
150 r = PyDict_SetItemString(proxies, proto,
152 Py_DECREF(v);
153 return r;
158 return 0;
163 static PyObject*
164 get_proxies(PyObject* mod __attribute__((__unused__)))
166 PyObject* result = NULL;
167 int r;
168 CFDictionaryRef proxyDict = NULL;
170 proxyDict = SCDynamicStoreCopyProxies(NULL);
171 if (proxyDict == NULL) {
172 return PyDict_New();
175 result = PyDict_New();
176 if (result == NULL) goto error;
178 r = set_proxy(result, "http", proxyDict,
179 kSCPropNetProxiesHTTPEnable,
180 kSCPropNetProxiesHTTPProxy,
181 kSCPropNetProxiesHTTPPort);
182 if (r == -1) goto error;
183 r = set_proxy(result, "https", proxyDict,
184 kSCPropNetProxiesHTTPSEnable,
185 kSCPropNetProxiesHTTPSProxy,
186 kSCPropNetProxiesHTTPSPort);
187 if (r == -1) goto error;
188 r = set_proxy(result, "ftp", proxyDict,
189 kSCPropNetProxiesFTPEnable,
190 kSCPropNetProxiesFTPProxy,
191 kSCPropNetProxiesFTPPort);
192 if (r == -1) goto error;
193 r = set_proxy(result, "gopher", proxyDict,
194 kSCPropNetProxiesGopherEnable,
195 kSCPropNetProxiesGopherProxy,
196 kSCPropNetProxiesGopherPort);
197 if (r == -1) goto error;
199 CFRelease(proxyDict);
200 return result;
201 error:
202 if (proxyDict) CFRelease(proxyDict);
203 Py_XDECREF(result);
204 return NULL;
207 static PyMethodDef mod_methods[] = {
209 "_get_proxy_settings",
210 (PyCFunction)get_proxy_settings,
211 METH_NOARGS,
212 NULL,
215 "_get_proxies",
216 (PyCFunction)get_proxies,
217 METH_NOARGS,
218 NULL,
220 { 0, 0, 0, 0 }
223 void init_scproxy(void)
225 (void)Py_InitModule4("_scproxy", mod_methods, NULL, NULL, PYTHON_API_VERSION);