annotate Modules/_scproxy.c @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents e332cd95f414
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
1 /*
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
2 * Helper method for urllib to fetch the proxy configuration settings
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
3 * using the SystemConfiguration framework.
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
4 */
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
5 #include <Python.h>
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
6 #include <SystemConfiguration/SystemConfiguration.h>
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
7
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
8 static int32_t
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
9 cfnum_to_int32(CFNumberRef num)
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
10 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
11 int32_t result;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
12
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
13 CFNumberGetValue(num, kCFNumberSInt32Type, &result);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
14 return result;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
15 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
16
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
17 static PyObject*
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
18 cfstring_to_pystring(CFStringRef ref)
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
19 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
20 const char* s;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
21
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
22 s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
23 if (s) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
24 return PyUnicode_DecodeUTF8(
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
25 s, strlen(s), NULL);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
26
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
27 } else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
28 CFIndex len = CFStringGetLength(ref);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
29 Boolean ok;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
30 PyObject* result;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
31 char* buf;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
32
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
33 buf = PyMem_Malloc(len*4);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
34 if (buf == NULL) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
35 PyErr_NoMemory();
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
36 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
37 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
38
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
39 ok = CFStringGetCString(ref,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
40 buf, len * 4,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
41 kCFStringEncodingUTF8);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
42 if (!ok) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
43 PyMem_Free(buf);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
44 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
45 } else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
46 result = PyUnicode_DecodeUTF8(
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
47 buf, strlen(buf), NULL);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
48 PyMem_Free(buf);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
49 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
50 return result;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
51 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
52 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
53
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
54
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
55 static PyObject*
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
56 get_proxy_settings(PyObject* mod __attribute__((__unused__)))
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
57 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
58 CFDictionaryRef proxyDict = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
59 CFNumberRef aNum = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
60 CFArrayRef anArray = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
61 PyObject* result = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
62 PyObject* v;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
63 int r;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
64
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
65 proxyDict = SCDynamicStoreCopyProxies(NULL);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
66 if (!proxyDict) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
67 Py_INCREF(Py_None);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
68 return Py_None;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
69 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
70
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
71 result = PyDict_New();
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
72 if (result == NULL) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
73
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
74 if (&kSCPropNetProxiesExcludeSimpleHostnames != NULL) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
75 aNum = CFDictionaryGetValue(proxyDict,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
76 kSCPropNetProxiesExcludeSimpleHostnames);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
77 if (aNum == NULL) {
62549
7d928029bc0e Merged revisions 82150 via svnmerge from
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61466
diff changeset
78 v = PyBool_FromLong(0);
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
79 } else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
80 v = PyBool_FromLong(cfnum_to_int32(aNum));
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
81 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
82 } else {
64977
e332cd95f414 Fix for issue #9568.
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 62549
diff changeset
83 v = PyBool_FromLong(0);
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
84 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
85
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
86 if (v == NULL) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
87
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
88 r = PyDict_SetItemString(result, "exclude_simple", v);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
89 Py_DECREF(v); v = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
90 if (r == -1) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
91
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
92 anArray = CFDictionaryGetValue(proxyDict,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
93 kSCPropNetProxiesExceptionsList);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
94 if (anArray != NULL) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
95 CFIndex len = CFArrayGetCount(anArray);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
96 CFIndex i;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
97 v = PyTuple_New(len);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
98 if (v == NULL) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
99
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
100 r = PyDict_SetItemString(result, "exceptions", v);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
101 Py_DECREF(v);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
102 if (r == -1) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
103
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
104 for (i = 0; i < len; i++) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
105 CFStringRef aString = NULL;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
106
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
107 aString = CFArrayGetValueAtIndex(anArray, i);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
108 if (aString == NULL) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
109 PyTuple_SetItem(v, i, Py_None);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
110 Py_INCREF(Py_None);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
111 } else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
112 PyObject* t = cfstring_to_pystring(aString);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
113 if (!t) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
114 PyTuple_SetItem(v, i, Py_None);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
115 Py_INCREF(Py_None);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
116 } else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
117 PyTuple_SetItem(v, i, t);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
118 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
119 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
120 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
121 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
122
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
123 CFRelease(proxyDict);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
124 return result;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
125
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
126 error:
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
127 if (proxyDict) CFRelease(proxyDict);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
128 Py_XDECREF(result);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
129 return NULL;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
130 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
131
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
132 static int
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
133 set_proxy(PyObject* proxies, char* proto, CFDictionaryRef proxyDict,
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
134 CFStringRef enabledKey,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
135 CFStringRef hostKey, CFStringRef portKey)
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
136 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
137 CFNumberRef aNum;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
138
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
139 aNum = CFDictionaryGetValue(proxyDict, enabledKey);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
140 if (aNum && cfnum_to_int32(aNum)) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
141 CFStringRef hostString;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
142
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
143 hostString = CFDictionaryGetValue(proxyDict, hostKey);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
144 aNum = CFDictionaryGetValue(proxyDict, portKey);
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
145
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
146 if (hostString) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
147 int r;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
148 PyObject* h = cfstring_to_pystring(hostString);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
149 PyObject* v;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
150 if (h) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
151 if (aNum) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
152 int32_t port = cfnum_to_int32(aNum);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
153 v = PyUnicode_FromFormat("http://%U:%ld",
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
154 h, (long)port);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
155 } else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
156 v = PyUnicode_FromFormat("http://%U", h);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
157 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
158 Py_DECREF(h);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
159 if (!v) return -1;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
160 r = PyDict_SetItemString(proxies, proto,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
161 v);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
162 Py_DECREF(v);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
163 return r;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
164 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
165 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
166
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
167 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
168 return 0;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
169 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
170
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
171
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
172
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
173 static PyObject*
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
174 get_proxies(PyObject* mod __attribute__((__unused__)))
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
175 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
176 PyObject* result = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
177 int r;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
178 CFDictionaryRef proxyDict = NULL;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
179
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
180 proxyDict = SCDynamicStoreCopyProxies(NULL);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
181 if (proxyDict == NULL) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
182 return PyDict_New();
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
183 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
184
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
185 result = PyDict_New();
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
186 if (result == NULL) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
187
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
188 r = set_proxy(result, "http", proxyDict,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
189 kSCPropNetProxiesHTTPEnable,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
190 kSCPropNetProxiesHTTPProxy,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
191 kSCPropNetProxiesHTTPPort);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
192 if (r == -1) goto error;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
193 r = set_proxy(result, "https", proxyDict,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
194 kSCPropNetProxiesHTTPSEnable,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
195 kSCPropNetProxiesHTTPSProxy,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
196 kSCPropNetProxiesHTTPSPort);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
197 if (r == -1) goto error;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
198 r = set_proxy(result, "ftp", proxyDict,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
199 kSCPropNetProxiesFTPEnable,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
200 kSCPropNetProxiesFTPProxy,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
201 kSCPropNetProxiesFTPPort);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
202 if (r == -1) goto error;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
203 r = set_proxy(result, "gopher", proxyDict,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
204 kSCPropNetProxiesGopherEnable,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
205 kSCPropNetProxiesGopherProxy,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
206 kSCPropNetProxiesGopherPort);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
207 if (r == -1) goto error;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
208
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
209 CFRelease(proxyDict);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
210 return result;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
211 error:
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
212 if (proxyDict) CFRelease(proxyDict);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
213 Py_XDECREF(result);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
214 return NULL;
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
215 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
216
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
217 static PyMethodDef mod_methods[] = {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
218 {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
219 "_get_proxy_settings",
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
220 (PyCFunction)get_proxy_settings,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
221 METH_NOARGS,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
222 NULL,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
223 },
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
224 {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
225 "_get_proxies",
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
226 (PyCFunction)get_proxies,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
227 METH_NOARGS,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
228 NULL,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
229 },
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
230 { 0, 0, 0, 0 }
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
231 };
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
232
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
233
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
234
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
235 static struct PyModuleDef mod_module = {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
236 PyModuleDef_HEAD_INIT,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
237 "_scproxy",
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
238 NULL,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
239 -1,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
240 mod_methods,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
241 NULL,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
242 NULL,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
243 NULL,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
244 NULL
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
245 };
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
246
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
247
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
248 #ifdef __cplusplus
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
249 extern "C" {
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
250 #endif
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
251
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
252 PyObject*
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
253 PyInit__scproxy(void)
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
254 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 60705
diff changeset
255 return PyModule_Create(&mod_module);
60705
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
256 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
257
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
258 #ifdef __cplusplus
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
259 }
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
260 #endif
9aac1d3d873d For for issue #7154: Port the code that uses
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
diff changeset
261