components/python/python26/Python26-09-ucred.patch
changeset 115 c360825c3a3f
parent 114 6cc95ec7b1bb
child 116 ae6a90899b42
equal deleted inserted replaced
114:6cc95ec7b1bb 115:c360825c3a3f
     1 diff --git Python-2.6.4/Modules/ucred.c Python-2.6.4/Modules/ucred.c
       
     2 new file mode 100644
       
     3 --- /dev/null
       
     4 +++ Python-2.6.4/Modules/ucred.c
       
     5 @@ -0,0 +1,391 @@
       
     6 +/*
       
     7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     8 + * of this software and associated documentation files (the "Software"), to
       
     9 + * deal in the Software without restriction, including without limitation the
       
    10 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
       
    11 + * sell copies of the Software, and to permit persons to whom the Software is
       
    12 + * furnished to do so, subject to the following conditions:
       
    13 + *
       
    14 + * The above copyright notice and this permission notice shall be included in
       
    15 + * all copies or substantial portions of the Software.
       
    16 + *
       
    17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       
    20 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
       
    22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
       
    23 + * DEALINGS IN THE SOFTWARE.
       
    24 + *
       
    25 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
       
    26 + * Use is subject to license terms.
       
    27 + */
       
    28 +
       
    29 +#include <Python.h>
       
    30 +
       
    31 +#include <stdio.h>
       
    32 +#include <priv.h>
       
    33 +#include <ucred.h>
       
    34 +#include <ctype.h>
       
    35 +#include <tsol/label.h>
       
    36 +
       
    37 +typedef struct {
       
    38 +	PyObject_HEAD
       
    39 +	ucred_t *ucred;
       
    40 +} pyucred_t;
       
    41 +
       
    42 +#define pyucred_getlongid(name, type)				\
       
    43 +	static PyObject *					\
       
    44 +	pyucred_get##name(pyucred_t *uc)			\
       
    45 +	{ 							\
       
    46 +		type val;					\
       
    47 +								\
       
    48 +		if (uc->ucred == NULL) {			\
       
    49 +			errno = EINVAL;				\
       
    50 +			PyErr_SetFromErrno(PyExc_OSError);	\
       
    51 +			return (NULL);				\
       
    52 +		}						\
       
    53 +								\
       
    54 +		if ((val = ucred_get##name(uc->ucred)) == -1) {	\
       
    55 +			PyErr_SetFromErrno(PyExc_OSError);	\
       
    56 +			return (NULL);				\
       
    57 +		}						\
       
    58 +								\
       
    59 +		return (Py_BuildValue("l", (long)val));		\
       
    60 +	}
       
    61 +
       
    62 +pyucred_getlongid(euid, uid_t)
       
    63 +pyucred_getlongid(ruid, uid_t)
       
    64 +pyucred_getlongid(suid, uid_t)
       
    65 +pyucred_getlongid(egid, gid_t)
       
    66 +pyucred_getlongid(rgid, gid_t)
       
    67 +pyucred_getlongid(sgid, gid_t)
       
    68 +pyucred_getlongid(pid, pid_t)
       
    69 +pyucred_getlongid(projid, projid_t)
       
    70 +pyucred_getlongid(zoneid, zoneid_t)
       
    71 +
       
    72 +static PyObject *
       
    73 +pyucred_getgroups(pyucred_t *uc)
       
    74 +{
       
    75 +	const gid_t *groups;
       
    76 +	PyObject *list;
       
    77 +	int len;
       
    78 +	int i;
       
    79 +
       
    80 +	if (uc->ucred == NULL) {
       
    81 +		errno = EINVAL;
       
    82 +		PyErr_SetFromErrno(PyExc_OSError);
       
    83 +		return (NULL);
       
    84 +	}
       
    85 +
       
    86 +	if ((len = ucred_getgroups(uc->ucred, &groups)) == -1) {
       
    87 +		PyErr_SetFromErrno(PyExc_OSError);
       
    88 +		return (NULL);
       
    89 +	}
       
    90 +
       
    91 +	if ((list = PyList_New(len)) == NULL)
       
    92 +		return (NULL);
       
    93 +
       
    94 +	for (i = 0; i < len; i++) {
       
    95 +		PyObject *gid = Py_BuildValue("l", (long)groups[i]);
       
    96 +		if (PyList_SetItem(list, i, gid) == -1)
       
    97 +			return (NULL);
       
    98 +	}
       
    99 +
       
   100 +	return (list);
       
   101 +}
       
   102 +
       
   103 +static PyObject *
       
   104 +pyucred_getlabel(pyucred_t *uc)
       
   105 +{
       
   106 +	m_label_t *label;
       
   107 +	PyObject *ret;
       
   108 +	char *str;
       
   109 +
       
   110 +	if (uc->ucred == NULL) {
       
   111 +		errno = EINVAL;
       
   112 +		PyErr_SetFromErrno(PyExc_OSError);
       
   113 +		return (NULL);
       
   114 +	}
       
   115 +
       
   116 +	label = ucred_getlabel(uc->ucred);
       
   117 +	if (label == NULL)
       
   118 +		return (Py_BuildValue("s", ""));
       
   119 +
       
   120 +	if (label_to_str(label, &str, M_LABEL, DEF_NAMES) == -1) {
       
   121 +		PyErr_SetFromErrno(PyExc_OSError);
       
   122 +		return (NULL);
       
   123 +	}
       
   124 +
       
   125 +	ret = Py_BuildValue("s", str);
       
   126 +	free(str);
       
   127 +	return (ret);
       
   128 +}
       
   129 +
       
   130 +static PyObject *
       
   131 +pyucred_getpflags(pyucred_t *uc, PyObject *args, PyObject *kwargs)
       
   132 +{
       
   133 +	static char *kwlist[] = { "flags", NULL };
       
   134 +	uint_t flags;
       
   135 +
       
   136 +	if (uc->ucred == NULL) {
       
   137 +		errno = EINVAL;
       
   138 +		PyErr_SetFromErrno(PyExc_OSError);
       
   139 +		return (NULL);
       
   140 +	}
       
   141 +
       
   142 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
       
   143 +	    &flags))
       
   144 +		return (NULL);
       
   145 +
       
   146 +	if ((flags = ucred_getpflags(uc->ucred, flags)) == (uint_t)-1) {
       
   147 +		PyErr_SetFromErrno(PyExc_OSError);
       
   148 +		return (NULL);
       
   149 +	}
       
   150 +
       
   151 +	return (Py_BuildValue("i", flags));
       
   152 +}
       
   153 +
       
   154 +static PyObject *
       
   155 +pyucred_has_priv(pyucred_t *uc, PyObject *args, PyObject *kwargs)
       
   156 +{
       
   157 +	static char *kwlist[] = { "set", "priv", NULL };
       
   158 +	const priv_set_t *privs;
       
   159 +	const char *set;
       
   160 +	const char *priv;
       
   161 +
       
   162 +	if (uc->ucred == NULL) {
       
   163 +		errno = EINVAL;
       
   164 +		PyErr_SetFromErrno(PyExc_OSError);
       
   165 +		return (NULL);
       
   166 +	}
       
   167 +
       
   168 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist,
       
   169 +	    &set, &priv))
       
   170 +		return (NULL);
       
   171 +
       
   172 +	if ((privs = ucred_getprivset(uc->ucred, set)) == NULL) {
       
   173 +		PyErr_SetFromErrno(PyExc_OSError);
       
   174 +		return (NULL);
       
   175 +	}
       
   176 +
       
   177 +	if (priv_ismember(privs, priv)) {
       
   178 +		Py_INCREF(Py_True);
       
   179 +		return Py_True;
       
   180 +	}
       
   181 +
       
   182 +	Py_INCREF(Py_False);
       
   183 +	return Py_False;
       
   184 +}
       
   185 +
       
   186 +PyDoc_STRVAR(pyucred_getlabel_doc,
       
   187 +    "getlabel() -> string\n"
       
   188 +    "\n"
       
   189 +    "Return the Trusted Extensions label string, or an "
       
   190 +    "empty string if not available. The label string is "
       
   191 +    "converted using the default name and M_LABEL (human-readable). "
       
   192 +    "Raises OSError. See label_to_str(3TSOL).");
       
   193 +PyDoc_STRVAR(pyucred_getpflags_doc,
       
   194 +    "getpflags(flags) -> int\n"
       
   195 +    "\n"
       
   196 +    "Return the values of the specified privilege flags.");
       
   197 +PyDoc_STRVAR(pyucred_has_priv_doc,
       
   198 +    "has_priv(set, priv) -> bool\n"
       
   199 +    "\n"
       
   200 +    "Return true if the given privilege is set in the "
       
   201 +    "specified set. Raises OSError if the set or privilege is "
       
   202 +    "invalid, or a problem occurs.\n"
       
   203 +    "\n"
       
   204 +    "Currently, the following privilege sets are defined, as "
       
   205 +    "described in privileges(5):\n"
       
   206 +    "\n"
       
   207 +    "Effective\n"
       
   208 +    "Permitted\n"
       
   209 +    "Inheritable\n"
       
   210 +    "Limit\n");
       
   211 +
       
   212 +static PyMethodDef pyucred_methods[] = {
       
   213 +	{ "geteuid", (PyCFunction)pyucred_geteuid, METH_NOARGS,
       
   214 +	    "Return the effective user ID." },
       
   215 +	{ "getruid", (PyCFunction)pyucred_getruid, METH_NOARGS,
       
   216 +	    "Return the real user ID." },
       
   217 +	{ "getsuid", (PyCFunction)pyucred_getsuid, METH_NOARGS,
       
   218 +	    "Return the saved user ID." },
       
   219 +	{ "getegid", (PyCFunction)pyucred_getegid, METH_NOARGS,
       
   220 +	    "Return the effective group ID." },
       
   221 +	{ "getrgid", (PyCFunction)pyucred_getrgid, METH_NOARGS,
       
   222 +	    "Return the real group ID." },
       
   223 +	{ "getsgid", (PyCFunction)pyucred_getsgid, METH_NOARGS,
       
   224 +	    "Return the saved group ID." },
       
   225 +	{ "getpid", (PyCFunction)pyucred_getpid, METH_NOARGS,
       
   226 +	    "Return the effective user ID." },
       
   227 +	{ "getprojid", (PyCFunction)pyucred_getprojid, METH_NOARGS,
       
   228 +	    "Return the project ID." },
       
   229 +	{ "getzoneid", (PyCFunction)pyucred_getzoneid, METH_NOARGS,
       
   230 +	    "Return the zone ID." },
       
   231 +	{ "getgroups", (PyCFunction)pyucred_getgroups, METH_NOARGS,
       
   232 +	    "Return a list of group IDs." },
       
   233 +	{ "getlabel", (PyCFunction)pyucred_getlabel, METH_NOARGS,
       
   234 +	    pyucred_getlabel_doc },
       
   235 +	{ "getpflags", (PyCFunction)pyucred_getpflags,
       
   236 +	    METH_VARARGS|METH_KEYWORDS, pyucred_getpflags_doc },
       
   237 +	{ "has_priv", (PyCFunction)pyucred_has_priv,
       
   238 +	    METH_VARARGS|METH_KEYWORDS, pyucred_has_priv_doc },
       
   239 +	{ NULL }
       
   240 +};
       
   241 +
       
   242 +static int
       
   243 +pyucred_init(PyObject *self, PyObject *args, PyObject *kwargs)
       
   244 +{
       
   245 +	pyucred_t *uc = (pyucred_t *)self;
       
   246 +	uc->ucred = NULL;
       
   247 +	return (0);
       
   248 +}
       
   249 +
       
   250 +static void
       
   251 +pyucred_dealloc(PyObject *self)
       
   252 +{
       
   253 +	pyucred_t *uc = (pyucred_t *)self;
       
   254 +	if (uc->ucred != NULL)
       
   255 +		ucred_free(uc->ucred);
       
   256 +	self->ob_type->tp_free(self);
       
   257 +}
       
   258 +
       
   259 +static PyTypeObject pyucred_type = {
       
   260 +	PyObject_HEAD_INIT(NULL)
       
   261 +	0,                         /*ob_size*/
       
   262 +	"ucred.ucred",             /*tp_name*/
       
   263 +	sizeof (pyucred_t),        /*tp_basicsize*/
       
   264 +	0,                         /*tp_itemsize*/
       
   265 +	pyucred_dealloc,           /*tp_dealloc*/
       
   266 +	0,                         /*tp_print*/
       
   267 +	0,                         /*tp_getattr*/
       
   268 +	0,                         /*tp_setattr*/
       
   269 +	0,                         /*tp_compare*/
       
   270 +	0,                         /*tp_repr*/
       
   271 +	0,                         /*tp_as_number*/
       
   272 +	0,                         /*tp_as_sequence*/
       
   273 +	0,                         /*tp_as_mapping*/
       
   274 +	0,                         /*tp_hash */
       
   275 +	0,                         /*tp_call*/
       
   276 +	0,                         /*tp_str*/
       
   277 +	0,                         /*tp_getattro*/
       
   278 +	0,                         /*tp_setattro*/
       
   279 +	0,                         /*tp_as_buffer*/
       
   280 +	Py_TPFLAGS_DEFAULT,        /*tp_flags*/
       
   281 +	"user credentials",        /*tp_doc */
       
   282 +	0,		           /* tp_traverse */
       
   283 +	0,		           /* tp_clear */
       
   284 +	0,		           /* tp_richcompare */
       
   285 +	0,		           /* tp_weaklistoffset */
       
   286 +	0,		           /* tp_iter */
       
   287 +	0,		           /* tp_iternext */
       
   288 +	pyucred_methods,           /* tp_methods */
       
   289 +	0,                         /* tp_members */
       
   290 +	0,                         /* tp_getset */
       
   291 +	0,                         /* tp_base */
       
   292 +	0,                         /* tp_dict */
       
   293 +	0,                         /* tp_descr_get */
       
   294 +	0,                         /* tp_descr_set */
       
   295 +	0,                         /* tp_dictoffset */
       
   296 +	(initproc)pyucred_init,    /* tp_init */
       
   297 +	0,                         /* tp_alloc */
       
   298 +	0,                         /* tp_new */
       
   299 +};
       
   300 +
       
   301 +static PyObject *
       
   302 +pyucred_new(const ucred_t *uc)
       
   303 +{
       
   304 +	pyucred_t *self;
       
   305 +
       
   306 +	self = (pyucred_t *)PyObject_CallObject((PyObject *)&pyucred_type, NULL);
       
   307 +
       
   308 +	if (self == NULL)
       
   309 +		return (NULL);
       
   310 +
       
   311 +	self->ucred = (ucred_t *)uc;
       
   312 +
       
   313 +	return ((PyObject *)self);
       
   314 +}
       
   315 +
       
   316 +static PyObject *
       
   317 +pyucred_get(PyObject *o, PyObject *args, PyObject *kwargs)
       
   318 +{
       
   319 +	static char *kwlist[] = { "pid", NULL };
       
   320 +	ucred_t *ucred = NULL;
       
   321 +	int pid;
       
   322 +
       
   323 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
       
   324 +	    &pid))
       
   325 +		return (NULL);
       
   326 +
       
   327 +	ucred = ucred_get(pid);
       
   328 +
       
   329 +	if (ucred == NULL) {
       
   330 +		PyErr_SetFromErrno(PyExc_OSError);
       
   331 +		return (NULL);
       
   332 +	}
       
   333 +
       
   334 +	return (pyucred_new(ucred));
       
   335 +}
       
   336 +
       
   337 +static PyObject *
       
   338 +pyucred_getpeer(PyObject *o, PyObject *args, PyObject *kwargs)
       
   339 +{
       
   340 +	static char *kwlist[] = { "fd", NULL };
       
   341 +	ucred_t *ucred = NULL;
       
   342 +	int fd;
       
   343 +
       
   344 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
       
   345 +	    &fd))
       
   346 +		return (NULL);
       
   347 +
       
   348 +	if (getpeerucred(fd, &ucred) == -1) {
       
   349 +		PyErr_SetFromErrno(PyExc_OSError);
       
   350 +		return (NULL);
       
   351 +	}
       
   352 +
       
   353 +	return (pyucred_new(ucred));
       
   354 +}
       
   355 +
       
   356 +PyDoc_STRVAR(pyucred_get_doc,
       
   357 +    "get(pid) -> ucred\n"
       
   358 +    "\n"
       
   359 +    "Return the credentials of the specified process ID. "
       
   360 +    "Raises OSError. See ucred_get(3C).");
       
   361 +PyDoc_STRVAR(pyucred_getpeer_doc,
       
   362 +    "getpeer(fd) -> ucred\n"
       
   363 +    "\n"
       
   364 +    "Return the credentials of the peer endpoint of a "
       
   365 +    "connection-oriented socket (SOCK_STREAM) or STREAM fd "
       
   366 +    "at the time the endpoint was created or the connection "
       
   367 +    "was established. Raises OSError. See getpeerucred(3C).");
       
   368 +
       
   369 +static struct PyMethodDef pyucred_module_methods[] = {
       
   370 +	{ "get", (PyCFunction) pyucred_get,
       
   371 +	  METH_VARARGS|METH_KEYWORDS, pyucred_get_doc },
       
   372 +	{ "getpeer", (PyCFunction) pyucred_getpeer,
       
   373 +	  METH_VARARGS|METH_KEYWORDS, pyucred_getpeer_doc },
       
   374 +	{ NULL, NULL, 0, NULL }
       
   375 +};
       
   376 +
       
   377 +PyDoc_STRVAR(pyucred_module_doc,
       
   378 +    "This module provides an interface to the user credential access "
       
   379 +    "methods, obtainable either by process ID or file descriptor.");
       
   380 +   
       
   381 +PyMODINIT_FUNC
       
   382 +initucred(void)
       
   383 +{
       
   384 +	PyObject *m;
       
   385 +
       
   386 +	m = Py_InitModule3("ucred", pyucred_module_methods,
       
   387 +	    pyucred_module_doc);
       
   388 +
       
   389 +	pyucred_type.tp_new = PyType_GenericNew;
       
   390 +	if (PyType_Ready(&pyucred_type) < 0)
       
   391 +		return;
       
   392 +
       
   393 +	Py_INCREF(&pyucred_type);
       
   394 +
       
   395 +	PyModule_AddObject(m, "ucred", (PyObject *)&pyucred_type);
       
   396 +}
       
   397 diff --git Python-2.6.4/setup.py Python-2.6.4/setup.py
       
   398 --- Python-2.6.4/setup.py
       
   399 +++ Python-2.6.4/setup.py
       
   400 @@ -1277,6 +1277,13 @@
       
   401          else:
       
   402              missing.append('dl')
       
   403  
       
   404 +        # ucred module (Solaris)
       
   405 +        ucred_inc = find_file('ucred.h', [], inc_dirs)
       
   406 +        tsol_inc = find_file('tsol/label.h', [], inc_dirs)
       
   407 +        if ucred_inc is not None and tsol_inc is not None:
       
   408 +            exts.append( Extension('ucred', ['ucred.c'],
       
   409 +                                   libraries = ['tsol']) )
       
   410 +
       
   411          # Thomas Heller's _ctypes module
       
   412          self.detect_ctypes(inc_dirs, lib_dirs)
       
   413  
       
   414 diff --git Python-2.6.4/setup.py.orig Python-2.6.4/setup.py.orig
       
   415 new file mode 100644
       
   416 --- /dev/null
       
   417 +++ Python-2.6.4/setup.py.orig
       
   418 @@ -0,0 +1,1958 @@
       
   419 +# Autodetecting setup.py script for building the Python extensions
       
   420 +#
       
   421 +
       
   422 +__version__ = "$Revision: 75282 $"
       
   423 +
       
   424 +import sys, os, imp, re, optparse
       
   425 +from glob import glob
       
   426 +from platform import machine as platform_machine
       
   427 +
       
   428 +from distutils import log
       
   429 +from distutils import sysconfig
       
   430 +from distutils import text_file
       
   431 +from distutils.errors import *
       
   432 +from distutils.core import Extension, setup
       
   433 +from distutils.command.build_ext import build_ext
       
   434 +from distutils.command.install import install
       
   435 +from distutils.command.install_lib import install_lib
       
   436 +
       
   437 +# This global variable is used to hold the list of modules to be disabled.
       
   438 +disabled_module_list = []
       
   439 +
       
   440 +def add_dir_to_list(dirlist, dir):
       
   441 +    """Add the directory 'dir' to the list 'dirlist' (at the front) if
       
   442 +    1) 'dir' is not already in 'dirlist'
       
   443 +    2) 'dir' actually exists, and is a directory."""
       
   444 +    if dir is not None and os.path.isdir(dir) and dir not in dirlist:
       
   445 +        dirlist.insert(0, dir)
       
   446 +
       
   447 +def find_file(filename, std_dirs, paths):
       
   448 +    """Searches for the directory where a given file is located,
       
   449 +    and returns a possibly-empty list of additional directories, or None
       
   450 +    if the file couldn't be found at all.
       
   451 +
       
   452 +    'filename' is the name of a file, such as readline.h or libcrypto.a.
       
   453 +    'std_dirs' is the list of standard system directories; if the
       
   454 +        file is found in one of them, no additional directives are needed.
       
   455 +    'paths' is a list of additional locations to check; if the file is
       
   456 +        found in one of them, the resulting list will contain the directory.
       
   457 +    """
       
   458 +
       
   459 +    # Check the standard locations
       
   460 +    for dir in std_dirs:
       
   461 +        f = os.path.join(dir, filename)
       
   462 +        if os.path.exists(f): return []
       
   463 +
       
   464 +    # Check the additional directories
       
   465 +    for dir in paths:
       
   466 +        f = os.path.join(dir, filename)
       
   467 +        if os.path.exists(f):
       
   468 +            return [dir]
       
   469 +
       
   470 +    # Not found anywhere
       
   471 +    return None
       
   472 +
       
   473 +def find_library_file(compiler, libname, std_dirs, paths):
       
   474 +    result = compiler.find_library_file(std_dirs + paths, libname)
       
   475 +    if result is None:
       
   476 +        return None
       
   477 +
       
   478 +    # Check whether the found file is in one of the standard directories
       
   479 +    dirname = os.path.dirname(result)
       
   480 +    for p in std_dirs:
       
   481 +        # Ensure path doesn't end with path separator
       
   482 +        p = p.rstrip(os.sep)
       
   483 +        if p == dirname:
       
   484 +            return [ ]
       
   485 +
       
   486 +    # Otherwise, it must have been in one of the additional directories,
       
   487 +    # so we have to figure out which one.
       
   488 +    for p in paths:
       
   489 +        # Ensure path doesn't end with path separator
       
   490 +        p = p.rstrip(os.sep)
       
   491 +        if p == dirname:
       
   492 +            return [p]
       
   493 +    else:
       
   494 +        assert False, "Internal error: Path not found in std_dirs or paths"
       
   495 +
       
   496 +def module_enabled(extlist, modname):
       
   497 +    """Returns whether the module 'modname' is present in the list
       
   498 +    of extensions 'extlist'."""
       
   499 +    extlist = [ext for ext in extlist if ext.name == modname]
       
   500 +    return len(extlist)
       
   501 +
       
   502 +def find_module_file(module, dirlist):
       
   503 +    """Find a module in a set of possible folders. If it is not found
       
   504 +    return the unadorned filename"""
       
   505 +    list = find_file(module, [], dirlist)
       
   506 +    if not list:
       
   507 +        return module
       
   508 +    if len(list) > 1:
       
   509 +        log.info("WARNING: multiple copies of %s found"%module)
       
   510 +    return os.path.join(list[0], module)
       
   511 +
       
   512 +class PyBuildExt(build_ext):
       
   513 +
       
   514 +    def __init__(self, dist):
       
   515 +        build_ext.__init__(self, dist)
       
   516 +        self.failed = []
       
   517 +
       
   518 +    def build_extensions(self):
       
   519 +
       
   520 +        # Detect which modules should be compiled
       
   521 +        missing = self.detect_modules()
       
   522 +
       
   523 +        # Remove modules that are present on the disabled list
       
   524 +        extensions = [ext for ext in self.extensions
       
   525 +                      if ext.name not in disabled_module_list]
       
   526 +        # move ctypes to the end, it depends on other modules
       
   527 +        ext_map = dict((ext.name, i) for i, ext in enumerate(extensions))
       
   528 +        if "_ctypes" in ext_map:
       
   529 +            ctypes = extensions.pop(ext_map["_ctypes"])
       
   530 +            extensions.append(ctypes)
       
   531 +        self.extensions = extensions
       
   532 +
       
   533 +        # Fix up the autodetected modules, prefixing all the source files
       
   534 +        # with Modules/ and adding Python's include directory to the path.
       
   535 +        (srcdir,) = sysconfig.get_config_vars('srcdir')
       
   536 +        if not srcdir:
       
   537 +            # Maybe running on Windows but not using CYGWIN?
       
   538 +            raise ValueError("No source directory; cannot proceed.")
       
   539 +
       
   540 +        # Figure out the location of the source code for extension modules
       
   541 +        # (This logic is copied in distutils.test.test_sysconfig,
       
   542 +        # so building in a separate directory does not break test_distutils.)
       
   543 +        moddir = os.path.join(os.getcwd(), srcdir, 'Modules')
       
   544 +        moddir = os.path.normpath(moddir)
       
   545 +        srcdir, tail = os.path.split(moddir)
       
   546 +        srcdir = os.path.normpath(srcdir)
       
   547 +        moddir = os.path.normpath(moddir)
       
   548 +
       
   549 +        moddirlist = [moddir]
       
   550 +        incdirlist = ['./Include']
       
   551 +
       
   552 +        # Platform-dependent module source and include directories
       
   553 +        platform = self.get_platform()
       
   554 +        if platform in ('darwin', 'mac') and ("--disable-toolbox-glue" not in
       
   555 +            sysconfig.get_config_var("CONFIG_ARGS")):
       
   556 +            # Mac OS X also includes some mac-specific modules
       
   557 +            macmoddir = os.path.join(os.getcwd(), srcdir, 'Mac/Modules')
       
   558 +            moddirlist.append(macmoddir)
       
   559 +            incdirlist.append('./Mac/Include')
       
   560 +
       
   561 +        alldirlist = moddirlist + incdirlist
       
   562 +
       
   563 +        # Fix up the paths for scripts, too
       
   564 +        self.distribution.scripts = [os.path.join(srcdir, filename)
       
   565 +                                     for filename in self.distribution.scripts]
       
   566 +
       
   567 +        # Python header files
       
   568 +        headers = glob("Include/*.h") + ["pyconfig.h"]
       
   569 +
       
   570 +        for ext in self.extensions[:]:
       
   571 +            ext.sources = [ find_module_file(filename, moddirlist)
       
   572 +                            for filename in ext.sources ]
       
   573 +            if ext.depends is not None:
       
   574 +                ext.depends = [find_module_file(filename, alldirlist)
       
   575 +                               for filename in ext.depends]
       
   576 +            else:
       
   577 +                ext.depends = []
       
   578 +            # re-compile extensions if a header file has been changed
       
   579 +            ext.depends.extend(headers)
       
   580 +
       
   581 +            ext.include_dirs.append( '.' ) # to get config.h
       
   582 +            for incdir in incdirlist:
       
   583 +                ext.include_dirs.append( os.path.join(srcdir, incdir) )
       
   584 +
       
   585 +            # If a module has already been built statically,
       
   586 +            # don't build it here
       
   587 +            if ext.name in sys.builtin_module_names:
       
   588 +                self.extensions.remove(ext)
       
   589 +
       
   590 +        if platform != 'mac':
       
   591 +            # Parse Modules/Setup and Modules/Setup.local to figure out which
       
   592 +            # modules are turned on in the file.
       
   593 +            remove_modules = []
       
   594 +            for filename in ('Modules/Setup', 'Modules/Setup.local'):
       
   595 +                input = text_file.TextFile(filename, join_lines=1)
       
   596 +                while 1:
       
   597 +                    line = input.readline()
       
   598 +                    if not line: break
       
   599 +                    line = line.split()
       
   600 +                    remove_modules.append(line[0])
       
   601 +                input.close()
       
   602 +
       
   603 +            for ext in self.extensions[:]:
       
   604 +                if ext.name in remove_modules:
       
   605 +                    self.extensions.remove(ext)
       
   606 +
       
   607 +        # When you run "make CC=altcc" or something similar, you really want
       
   608 +        # those environment variables passed into the setup.py phase.  Here's
       
   609 +        # a small set of useful ones.
       
   610 +        compiler = os.environ.get('CC')
       
   611 +        args = {}
       
   612 +        # unfortunately, distutils doesn't let us provide separate C and C++
       
   613 +        # compilers
       
   614 +        if compiler is not None:
       
   615 +            (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS')
       
   616 +            args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
       
   617 +        self.compiler.set_executables(**args)
       
   618 +
       
   619 +        build_ext.build_extensions(self)
       
   620 +
       
   621 +        longest = max([len(e.name) for e in self.extensions])
       
   622 +        if self.failed:
       
   623 +            longest = max(longest, max([len(name) for name in self.failed]))
       
   624 +
       
   625 +        def print_three_column(lst):
       
   626 +            lst.sort(key=str.lower)
       
   627 +            # guarantee zip() doesn't drop anything
       
   628 +            while len(lst) % 3:
       
   629 +                lst.append("")
       
   630 +            for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]):
       
   631 +                print "%-*s   %-*s   %-*s" % (longest, e, longest, f,
       
   632 +                                              longest, g)
       
   633 +
       
   634 +        if missing:
       
   635 +            print
       
   636 +            print "Failed to find the necessary bits to build these modules:"
       
   637 +            print_three_column(missing)
       
   638 +            print ("To find the necessary bits, look in setup.py in"
       
   639 +                   " detect_modules() for the module's name.")
       
   640 +            print
       
   641 +
       
   642 +        if self.failed:
       
   643 +            failed = self.failed[:]
       
   644 +            print
       
   645 +            print "Failed to build these modules:"
       
   646 +            print_three_column(failed)
       
   647 +            print
       
   648 +
       
   649 +    def build_extension(self, ext):
       
   650 +
       
   651 +        if ext.name == '_ctypes':
       
   652 +            if not self.configure_ctypes(ext):
       
   653 +                return
       
   654 +
       
   655 +        try:
       
   656 +            build_ext.build_extension(self, ext)
       
   657 +        except (CCompilerError, DistutilsError), why:
       
   658 +            self.announce('WARNING: building of extension "%s" failed: %s' %
       
   659 +                          (ext.name, sys.exc_info()[1]))
       
   660 +            self.failed.append(ext.name)
       
   661 +            return
       
   662 +        # Workaround for Mac OS X: The Carbon-based modules cannot be
       
   663 +        # reliably imported into a command-line Python
       
   664 +        if 'Carbon' in ext.extra_link_args:
       
   665 +            self.announce(
       
   666 +                'WARNING: skipping import check for Carbon-based "%s"' %
       
   667 +                ext.name)
       
   668 +            return
       
   669 +
       
   670 +        if self.get_platform() == 'darwin' and (
       
   671 +                sys.maxint > 2**32 and '-arch' in ext.extra_link_args):
       
   672 +            # Don't bother doing an import check when an extension was
       
   673 +            # build with an explicit '-arch' flag on OSX. That's currently
       
   674 +            # only used to build 32-bit only extensions in a 4-way
       
   675 +            # universal build and loading 32-bit code into a 64-bit
       
   676 +            # process will fail.
       
   677 +            self.announce(
       
   678 +                'WARNING: skipping import check for "%s"' %
       
   679 +                ext.name)
       
   680 +            return
       
   681 +
       
   682 +        # Workaround for Cygwin: Cygwin currently has fork issues when many
       
   683 +        # modules have been imported
       
   684 +        if self.get_platform() == 'cygwin':
       
   685 +            self.announce('WARNING: skipping import check for Cygwin-based "%s"'
       
   686 +                % ext.name)
       
   687 +            return
       
   688 +        ext_filename = os.path.join(
       
   689 +            self.build_lib,
       
   690 +            self.get_ext_filename(self.get_ext_fullname(ext.name)))
       
   691 +        try:
       
   692 +            imp.load_dynamic(ext.name, ext_filename)
       
   693 +        except ImportError, why:
       
   694 +            self.failed.append(ext.name)
       
   695 +            self.announce('*** WARNING: renaming "%s" since importing it'
       
   696 +                          ' failed: %s' % (ext.name, why), level=3)
       
   697 +            assert not self.inplace
       
   698 +            basename, tail = os.path.splitext(ext_filename)
       
   699 +            newname = basename + "_failed" + tail
       
   700 +            if os.path.exists(newname):
       
   701 +                os.remove(newname)
       
   702 +            os.rename(ext_filename, newname)
       
   703 +
       
   704 +            # XXX -- This relies on a Vile HACK in
       
   705 +            # distutils.command.build_ext.build_extension().  The
       
   706 +            # _built_objects attribute is stored there strictly for
       
   707 +            # use here.
       
   708 +            # If there is a failure, _built_objects may not be there,
       
   709 +            # so catch the AttributeError and move on.
       
   710 +            try:
       
   711 +                for filename in self._built_objects:
       
   712 +                    os.remove(filename)
       
   713 +            except AttributeError:
       
   714 +                self.announce('unable to remove files (ignored)')
       
   715 +        except:
       
   716 +            exc_type, why, tb = sys.exc_info()
       
   717 +            self.announce('*** WARNING: importing extension "%s" '
       
   718 +                          'failed with %s: %s' % (ext.name, exc_type, why),
       
   719 +                          level=3)
       
   720 +            self.failed.append(ext.name)
       
   721 +
       
   722 +    def get_platform(self):
       
   723 +        # Get value of sys.platform
       
   724 +        for platform in ['cygwin', 'beos', 'darwin', 'atheos', 'osf1']:
       
   725 +            if sys.platform.startswith(platform):
       
   726 +                return platform
       
   727 +        return sys.platform
       
   728 +
       
   729 +    def detect_modules(self):
       
   730 +        if sys.platform != 'sunos5':
       
   731 +            # Ensure that /usr/local is always used
       
   732 +            add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
       
   733 +            add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
       
   734 +        # Add paths specified in the environment variables LDFLAGS and
       
   735 +        # CPPFLAGS for header and library files.
       
   736 +        # We must get the values from the Makefile and not the environment
       
   737 +        # directly since an inconsistently reproducible issue comes up where
       
   738 +        # the environment variable is not set even though the value were passed
       
   739 +        # into configure and stored in the Makefile (issue found on OS X 10.3).
       
   740 +        for env_var, arg_name, dir_list in (
       
   741 +                ('LDFLAGS', '-R', self.compiler.runtime_library_dirs),
       
   742 +                ('LDFLAGS', '-L', self.compiler.library_dirs),
       
   743 +                ('CPPFLAGS', '-I', self.compiler.include_dirs)):
       
   744 +            env_val = sysconfig.get_config_var(env_var)
       
   745 +            if env_val:
       
   746 +                # To prevent optparse from raising an exception about any
       
   747 +                # options in env_val that it doesn't know about we strip out
       
   748 +                # all double dashes and any dashes followed by a character
       
   749 +                # that is not for the option we are dealing with.
       
   750 +                #
       
   751 +                # Please note that order of the regex is important!  We must
       
   752 +                # strip out double-dashes first so that we don't end up with
       
   753 +                # substituting "--Long" to "-Long" and thus lead to "ong" being
       
   754 +                # used for a library directory.
       
   755 +                env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1],
       
   756 +                                 ' ', env_val)
       
   757 +                parser = optparse.OptionParser()
       
   758 +                # Make sure that allowing args interspersed with options is
       
   759 +                # allowed
       
   760 +                parser.allow_interspersed_args = True
       
   761 +                parser.error = lambda msg: None
       
   762 +                parser.add_option(arg_name, dest="dirs", action="append")
       
   763 +                options = parser.parse_args(env_val.split())[0]
       
   764 +                if options.dirs:
       
   765 +                    for directory in reversed(options.dirs):
       
   766 +                        add_dir_to_list(dir_list, directory)
       
   767 +
       
   768 +        if os.path.normpath(sys.prefix) != '/usr':
       
   769 +            add_dir_to_list(self.compiler.library_dirs,
       
   770 +                            sysconfig.get_config_var("LIBDIR"))
       
   771 +            add_dir_to_list(self.compiler.include_dirs,
       
   772 +                            sysconfig.get_config_var("INCLUDEDIR"))
       
   773 +
       
   774 +        try:
       
   775 +            have_unicode = unicode
       
   776 +        except NameError:
       
   777 +            have_unicode = 0
       
   778 +
       
   779 +        # lib_dirs and inc_dirs are used to search for files;
       
   780 +        # if a file is found in one of those directories, it can
       
   781 +        # be assumed that no additional -I,-L directives are needed.
       
   782 +        lib_dirs = self.compiler.library_dirs + [
       
   783 +            '/lib64', '/usr/lib64',
       
   784 +            '/lib', '/usr/lib',
       
   785 +            ]
       
   786 +        inc_dirs = self.compiler.include_dirs + ['/usr/include']
       
   787 +        exts = []
       
   788 +        missing = []
       
   789 +
       
   790 +        config_h = sysconfig.get_config_h_filename()
       
   791 +        config_h_vars = sysconfig.parse_config_h(open(config_h))
       
   792 +
       
   793 +        platform = self.get_platform()
       
   794 +        (srcdir,) = sysconfig.get_config_vars('srcdir')
       
   795 +
       
   796 +        # Check for AtheOS which has libraries in non-standard locations
       
   797 +        if platform == 'atheos':
       
   798 +            lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
       
   799 +            lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
       
   800 +            inc_dirs += ['/system/include', '/atheos/autolnk/include']
       
   801 +            inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
       
   802 +
       
   803 +        # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
       
   804 +        if platform in ['osf1', 'unixware7', 'openunix8']:
       
   805 +            lib_dirs += ['/usr/ccs/lib']
       
   806 +
       
   807 +        if platform == 'darwin':
       
   808 +            # This should work on any unixy platform ;-)
       
   809 +            # If the user has bothered specifying additional -I and -L flags
       
   810 +            # in OPT and LDFLAGS we might as well use them here.
       
   811 +            #   NOTE: using shlex.split would technically be more correct, but
       
   812 +            # also gives a bootstrap problem. Let's hope nobody uses directories
       
   813 +            # with whitespace in the name to store libraries.
       
   814 +            cflags, ldflags = sysconfig.get_config_vars(
       
   815 +                    'CFLAGS', 'LDFLAGS')
       
   816 +            for item in cflags.split():
       
   817 +                if item.startswith('-I'):
       
   818 +                    inc_dirs.append(item[2:])
       
   819 +
       
   820 +            for item in ldflags.split():
       
   821 +                if item.startswith('-L'):
       
   822 +                    lib_dirs.append(item[2:])
       
   823 +
       
   824 +        # Check for MacOS X, which doesn't need libm.a at all
       
   825 +        math_libs = ['m']
       
   826 +        if platform in ['darwin', 'beos', 'mac']:
       
   827 +            math_libs = []
       
   828 +
       
   829 +        # XXX Omitted modules: gl, pure, dl, SGI-specific modules
       
   830 +
       
   831 +        #
       
   832 +        # The following modules are all pretty straightforward, and compile
       
   833 +        # on pretty much any POSIXish platform.
       
   834 +        #
       
   835 +
       
   836 +        # Some modules that are normally always on:
       
   837 +        exts.append( Extension('_weakref', ['_weakref.c']) )
       
   838 +
       
   839 +        # array objects
       
   840 +        exts.append( Extension('array', ['arraymodule.c']) )
       
   841 +        # complex math library functions
       
   842 +        exts.append( Extension('cmath', ['cmathmodule.c'],
       
   843 +                               libraries=math_libs) )
       
   844 +
       
   845 +        # math library functions, e.g. sin()
       
   846 +        exts.append( Extension('math',  ['mathmodule.c'],
       
   847 +                               libraries=math_libs) )
       
   848 +        # fast string operations implemented in C
       
   849 +        exts.append( Extension('strop', ['stropmodule.c']) )
       
   850 +        # time operations and variables
       
   851 +        exts.append( Extension('time', ['timemodule.c'],
       
   852 +                               libraries=math_libs) )
       
   853 +        exts.append( Extension('datetime', ['datetimemodule.c', 'timemodule.c'],
       
   854 +                               libraries=math_libs) )
       
   855 +        # fast iterator tools implemented in C
       
   856 +        exts.append( Extension("itertools", ["itertoolsmodule.c"]) )
       
   857 +        # code that will be builtins in the future, but conflict with the
       
   858 +        #  current builtins
       
   859 +        exts.append( Extension('future_builtins', ['future_builtins.c']) )
       
   860 +        # random number generator implemented in C
       
   861 +        exts.append( Extension("_random", ["_randommodule.c"]) )
       
   862 +        # high-performance collections
       
   863 +        exts.append( Extension("_collections", ["_collectionsmodule.c"]) )
       
   864 +        # bisect
       
   865 +        exts.append( Extension("_bisect", ["_bisectmodule.c"]) )
       
   866 +        # heapq
       
   867 +        exts.append( Extension("_heapq", ["_heapqmodule.c"]) )
       
   868 +        # operator.add() and similar goodies
       
   869 +        exts.append( Extension('operator', ['operator.c']) )
       
   870 +        # Python 3.0 _fileio module
       
   871 +        exts.append( Extension("_fileio", ["_fileio.c"]) )
       
   872 +        # Python 3.0 _bytesio module
       
   873 +        exts.append( Extension("_bytesio", ["_bytesio.c"]) )
       
   874 +        # _functools
       
   875 +        exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
       
   876 +        # _json speedups
       
   877 +        exts.append( Extension("_json", ["_json.c"]) )
       
   878 +        # Python C API test module
       
   879 +        exts.append( Extension('_testcapi', ['_testcapimodule.c'],
       
   880 +                               depends=['testcapi_long.h']) )
       
   881 +        # profilers (_lsprof is for cProfile.py)
       
   882 +        exts.append( Extension('_hotshot', ['_hotshot.c']) )
       
   883 +        exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
       
   884 +        # static Unicode character database
       
   885 +        if have_unicode:
       
   886 +            exts.append( Extension('unicodedata', ['unicodedata.c']) )
       
   887 +        else:
       
   888 +            missing.append('unicodedata')
       
   889 +        # access to ISO C locale support
       
   890 +        data = open('pyconfig.h').read()
       
   891 +        m = re.search(r"#s*define\s+WITH_LIBINTL\s+1\s*", data)
       
   892 +        if m is not None:
       
   893 +            locale_libs = ['intl']
       
   894 +        else:
       
   895 +            locale_libs = []
       
   896 +        if platform == 'darwin':
       
   897 +            locale_extra_link_args = ['-framework', 'CoreFoundation']
       
   898 +        else:
       
   899 +            locale_extra_link_args = []
       
   900 +
       
   901 +
       
   902 +        exts.append( Extension('_locale', ['_localemodule.c'],
       
   903 +                               libraries=locale_libs,
       
   904 +                               extra_link_args=locale_extra_link_args) )
       
   905 +
       
   906 +        # Modules with some UNIX dependencies -- on by default:
       
   907 +        # (If you have a really backward UNIX, select and socket may not be
       
   908 +        # supported...)
       
   909 +
       
   910 +        # fcntl(2) and ioctl(2)
       
   911 +        exts.append( Extension('fcntl', ['fcntlmodule.c']) )
       
   912 +        if platform not in ['mac']:
       
   913 +            # pwd(3)
       
   914 +            exts.append( Extension('pwd', ['pwdmodule.c']) )
       
   915 +            # grp(3)
       
   916 +            exts.append( Extension('grp', ['grpmodule.c']) )
       
   917 +            # spwd, shadow passwords
       
   918 +            if (config_h_vars.get('HAVE_GETSPNAM', False) or
       
   919 +                    config_h_vars.get('HAVE_GETSPENT', False)):
       
   920 +                exts.append( Extension('spwd', ['spwdmodule.c']) )
       
   921 +            else:
       
   922 +                missing.append('spwd')
       
   923 +        else:
       
   924 +            missing.extend(['pwd', 'grp', 'spwd'])
       
   925 +
       
   926 +        # select(2); not on ancient System V
       
   927 +        exts.append( Extension('select', ['selectmodule.c']) )
       
   928 +
       
   929 +        # Fred Drake's interface to the Python parser
       
   930 +        exts.append( Extension('parser', ['parsermodule.c']) )
       
   931 +
       
   932 +        # cStringIO and cPickle
       
   933 +        exts.append( Extension('cStringIO', ['cStringIO.c']) )
       
   934 +        exts.append( Extension('cPickle', ['cPickle.c']) )
       
   935 +
       
   936 +        # Memory-mapped files (also works on Win32).
       
   937 +        if platform not in ['atheos', 'mac']:
       
   938 +            exts.append( Extension('mmap', ['mmapmodule.c']) )
       
   939 +        else:
       
   940 +            missing.append('mmap')
       
   941 +
       
   942 +        # Lance Ellinghaus's syslog module
       
   943 +        if platform not in ['mac']:
       
   944 +            # syslog daemon interface
       
   945 +            exts.append( Extension('syslog', ['syslogmodule.c']) )
       
   946 +        else:
       
   947 +            missing.append('syslog')
       
   948 +
       
   949 +        # George Neville-Neil's timing module:
       
   950 +        # Deprecated in PEP 4 http://www.python.org/peps/pep-0004.html
       
   951 +        # http://mail.python.org/pipermail/python-dev/2006-January/060023.html
       
   952 +        #exts.append( Extension('timing', ['timingmodule.c']) )
       
   953 +
       
   954 +        #
       
   955 +        # Here ends the simple stuff.  From here on, modules need certain
       
   956 +        # libraries, are platform-specific, or present other surprises.
       
   957 +        #
       
   958 +
       
   959 +        # Multimedia modules
       
   960 +        # These don't work for 64-bit platforms!!!
       
   961 +        # These represent audio samples or images as strings:
       
   962 +
       
   963 +        # Operations on audio samples
       
   964 +        # According to #993173, this one should actually work fine on
       
   965 +        # 64-bit platforms.
       
   966 +        exts.append( Extension('audioop', ['audioop.c']) )
       
   967 +
       
   968 +        # Disabled on 64-bit platforms
       
   969 +        if sys.maxint != 9223372036854775807L:
       
   970 +            # Operations on images
       
   971 +            exts.append( Extension('imageop', ['imageop.c']) )
       
   972 +        else:
       
   973 +            missing.extend(['imageop'])
       
   974 +
       
   975 +        # readline
       
   976 +        do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
       
   977 +        if platform == 'darwin': # and os.uname()[2] < '9.':
       
   978 +            # MacOSX 10.4 has a broken readline. Don't try to build
       
   979 +            # the readline module unless the user has installed a fixed
       
   980 +            # readline package
       
   981 +            # FIXME: The readline emulation on 10.5 is better, but the
       
   982 +            # readline module doesn't compile out of the box.
       
   983 +            if find_file('readline/rlconf.h', inc_dirs, []) is None:
       
   984 +                do_readline = False
       
   985 +        if do_readline:
       
   986 +            if sys.platform == 'darwin':
       
   987 +                # In every directory on the search path search for a dynamic
       
   988 +                # library and then a static library, instead of first looking
       
   989 +                # for dynamic libraries on the entiry path.
       
   990 +                # This way a staticly linked custom readline gets picked up
       
   991 +                # before the (broken) dynamic library in /usr/lib.
       
   992 +                readline_extra_link_args = ('-Wl,-search_paths_first',)
       
   993 +            else:
       
   994 +                readline_extra_link_args = ()
       
   995 +
       
   996 +            readline_libs = ['readline']
       
   997 +            if self.compiler.find_library_file(lib_dirs,
       
   998 +                                                 'ncursesw'):
       
   999 +                readline_libs.append('ncursesw')
       
  1000 +            elif self.compiler.find_library_file(lib_dirs,
       
  1001 +                                                 'ncurses'):
       
  1002 +                readline_libs.append('ncurses')
       
  1003 +            elif self.compiler.find_library_file(lib_dirs, 'curses'):
       
  1004 +                readline_libs.append('curses')
       
  1005 +            elif self.compiler.find_library_file(lib_dirs +
       
  1006 +                                               ['/usr/lib/termcap'],
       
  1007 +                                               'termcap'):
       
  1008 +                readline_libs.append('termcap')
       
  1009 +            exts.append( Extension('readline', ['readline.c'],
       
  1010 +                                   library_dirs=['/usr/lib/termcap'],
       
  1011 +                                   extra_link_args=readline_extra_link_args,
       
  1012 +                                   libraries=readline_libs) )
       
  1013 +        else:
       
  1014 +            missing.append('readline')
       
  1015 +
       
  1016 +        if platform not in ['mac']:
       
  1017 +            # crypt module.
       
  1018 +
       
  1019 +            if self.compiler.find_library_file(lib_dirs, 'crypt'):
       
  1020 +                libs = ['crypt']
       
  1021 +            else:
       
  1022 +                libs = []
       
  1023 +            exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
       
  1024 +        else:
       
  1025 +            missing.append('crypt')
       
  1026 +
       
  1027 +        # CSV files
       
  1028 +        exts.append( Extension('_csv', ['_csv.c']) )
       
  1029 +
       
  1030 +        # socket(2)
       
  1031 +        socket_libs = []
       
  1032 +        if self.compiler.find_library_file(lib_dirs,
       
  1033 +                                           'socket'):
       
  1034 +            socket_libs.append('socket')
       
  1035 +        if self.compiler.find_library_file(lib_dirs,
       
  1036 +                                           'nsl'):
       
  1037 +            socket_libs.append('nsl')
       
  1038 +        if self.compiler.find_library_file(lib_dirs,
       
  1039 +                                           'resolv'):
       
  1040 +            socket_libs.append('resolv')
       
  1041 +        exts.append( Extension('_socket', ['socketmodule.c'],
       
  1042 +                               depends = ['socketmodule.h'],
       
  1043 +                               libraries = socket_libs) )
       
  1044 +        # Detect SSL support for the socket module (via _ssl)
       
  1045 +        search_for_ssl_incs_in = [
       
  1046 +                              '/usr/sfw/include',
       
  1047 +                              '/usr/contrib/ssl/include/'
       
  1048 +                             ]
       
  1049 +        ssl_incs = find_file('openssl/ssl.h', inc_dirs,
       
  1050 +                             search_for_ssl_incs_in
       
  1051 +                             )
       
  1052 +        if ssl_incs is not None:
       
  1053 +            krb5_h = find_file('krb5.h', inc_dirs,
       
  1054 +                               ['/usr/kerberos/include'])
       
  1055 +            if krb5_h:
       
  1056 +                ssl_incs += krb5_h
       
  1057 +        if sys.maxint == 2147483647L:
       
  1058 +            sfw_libdir = '/usr/sfw/lib';
       
  1059 +        else:
       
  1060 +            sfw_libdir = '/usr/sfw/lib/64';
       
  1061 +        ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
       
  1062 +                                     [sfw_libdir,
       
  1063 +                                      '/usr/contrib/ssl/lib/'
       
  1064 +                                     ] )
       
  1065 +
       
  1066 +        if (ssl_incs is not None and
       
  1067 +            ssl_libs is not None):
       
  1068 +            exts.append( Extension('_ssl', ['_ssl.c'],
       
  1069 +                                   include_dirs = ssl_incs,
       
  1070 +                                   library_dirs = ssl_libs,
       
  1071 +				   runtime_library_dirs = ssl_libs,
       
  1072 +                                   libraries = ['ssl', 'crypto'],
       
  1073 +                                   depends = ['socketmodule.h']), )
       
  1074 +        else:
       
  1075 +            missing.append('_ssl')
       
  1076 +
       
  1077 +        # find out which version of OpenSSL we have
       
  1078 +        openssl_ver = 0
       
  1079 +        openssl_ver_re = re.compile(
       
  1080 +            '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
       
  1081 +        for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in:
       
  1082 +            name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
       
  1083 +            if os.path.isfile(name):
       
  1084 +                try:
       
  1085 +                    incfile = open(name, 'r')
       
  1086 +                    for line in incfile:
       
  1087 +                        m = openssl_ver_re.match(line)
       
  1088 +                        if m:
       
  1089 +                            openssl_ver = eval(m.group(1))
       
  1090 +                            break
       
  1091 +                except IOError:
       
  1092 +                    pass
       
  1093 +
       
  1094 +            # first version found is what we'll use (as the compiler should)
       
  1095 +            if openssl_ver:
       
  1096 +                break
       
  1097 +
       
  1098 +        #print 'openssl_ver = 0x%08x' % openssl_ver
       
  1099 +
       
  1100 +        if (ssl_incs is not None and
       
  1101 +            ssl_libs is not None and
       
  1102 +            openssl_ver >= 0x00907000):
       
  1103 +            # The _hashlib module wraps optimized implementations
       
  1104 +            # of hash functions from the OpenSSL library.
       
  1105 +            exts.append( Extension('_hashlib', ['_hashopenssl.c'],
       
  1106 +                                   include_dirs = ssl_incs,
       
  1107 +                                   library_dirs = ssl_libs,
       
  1108 +                                   libraries = ['ssl', 'crypto']) )
       
  1109 +            # these aren't strictly missing since they are unneeded.
       
  1110 +            #missing.extend(['_sha', '_md5'])
       
  1111 +        else:
       
  1112 +            # The _sha module implements the SHA1 hash algorithm.
       
  1113 +            exts.append( Extension('_sha', ['shamodule.c']) )
       
  1114 +            # The _md5 module implements the RSA Data Security, Inc. MD5
       
  1115 +            # Message-Digest Algorithm, described in RFC 1321.  The
       
  1116 +            # necessary files md5.c and md5.h are included here.
       
  1117 +            exts.append( Extension('_md5',
       
  1118 +                            sources = ['md5module.c', 'md5.c'],
       
  1119 +                            depends = ['md5.h']) )
       
  1120 +            missing.append('_hashlib')
       
  1121 +
       
  1122 +        if (openssl_ver < 0x00908000):
       
  1123 +            # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
       
  1124 +            exts.append( Extension('_sha256', ['sha256module.c']) )
       
  1125 +            exts.append( Extension('_sha512', ['sha512module.c']) )
       
  1126 +
       
  1127 +        # Modules that provide persistent dictionary-like semantics.  You will
       
  1128 +        # probably want to arrange for at least one of them to be available on
       
  1129 +        # your machine, though none are defined by default because of library
       
  1130 +        # dependencies.  The Python module anydbm.py provides an
       
  1131 +        # implementation independent wrapper for these; dumbdbm.py provides
       
  1132 +        # similar functionality (but slower of course) implemented in Python.
       
  1133 +
       
  1134 +        # Sleepycat^WOracle Berkeley DB interface.
       
  1135 +        #  http://www.oracle.com/database/berkeley-db/db/index.html
       
  1136 +        #
       
  1137 +        # This requires the Sleepycat^WOracle DB code. The supported versions
       
  1138 +        # are set below.  Visit the URL above to download
       
  1139 +        # a release.  Most open source OSes come with one or more
       
  1140 +        # versions of BerkeleyDB already installed.
       
  1141 +
       
  1142 +        max_db_ver = (4, 7)
       
  1143 +        min_db_ver = (3, 3)
       
  1144 +        db_setup_debug = False   # verbose debug prints from this script?
       
  1145 +
       
  1146 +        def allow_db_ver(db_ver):
       
  1147 +            """Returns a boolean if the given BerkeleyDB version is acceptable.
       
  1148 +
       
  1149 +            Args:
       
  1150 +              db_ver: A tuple of the version to verify.
       
  1151 +            """
       
  1152 +            if not (min_db_ver <= db_ver <= max_db_ver):
       
  1153 +                return False
       
  1154 +            # Use this function to filter out known bad configurations.
       
  1155 +            if (4, 6) == db_ver[:2]:
       
  1156 +                # BerkeleyDB 4.6.x is not stable on many architectures.
       
  1157 +                arch = platform_machine()
       
  1158 +                if arch not in ('i386', 'i486', 'i586', 'i686',
       
  1159 +                                'x86_64', 'ia64'):
       
  1160 +                    return False
       
  1161 +            return True
       
  1162 +
       
  1163 +        def gen_db_minor_ver_nums(major):
       
  1164 +            if major == 4:
       
  1165 +                for x in range(max_db_ver[1]+1):
       
  1166 +                    if allow_db_ver((4, x)):
       
  1167 +                        yield x
       
  1168 +            elif major == 3:
       
  1169 +                for x in (3,):
       
  1170 +                    if allow_db_ver((3, x)):
       
  1171 +                        yield x
       
  1172 +            else:
       
  1173 +                raise ValueError("unknown major BerkeleyDB version", major)
       
  1174 +
       
  1175 +        # construct a list of paths to look for the header file in on
       
  1176 +        # top of the normal inc_dirs.
       
  1177 +        db_inc_paths = [
       
  1178 +            '/usr/include/db4',
       
  1179 +            '/usr/local/include/db4',
       
  1180 +            '/opt/sfw/include/db4',
       
  1181 +            '/usr/include/db3',
       
  1182 +            '/usr/local/include/db3',
       
  1183 +            '/opt/sfw/include/db3',
       
  1184 +            # Fink defaults (http://fink.sourceforge.net/)
       
  1185 +            '/sw/include/db4',
       
  1186 +            '/sw/include/db3',
       
  1187 +        ]
       
  1188 +        # 4.x minor number specific paths
       
  1189 +        for x in gen_db_minor_ver_nums(4):
       
  1190 +            db_inc_paths.append('/usr/include/db4%d' % x)
       
  1191 +            db_inc_paths.append('/usr/include/db4.%d' % x)
       
  1192 +            db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
       
  1193 +            db_inc_paths.append('/usr/local/include/db4%d' % x)
       
  1194 +            db_inc_paths.append('/pkg/db-4.%d/include' % x)
       
  1195 +            db_inc_paths.append('/opt/db-4.%d/include' % x)
       
  1196 +            # MacPorts default (http://www.macports.org/)
       
  1197 +            db_inc_paths.append('/opt/local/include/db4%d' % x)
       
  1198 +        # 3.x minor number specific paths
       
  1199 +        for x in gen_db_minor_ver_nums(3):
       
  1200 +            db_inc_paths.append('/usr/include/db3%d' % x)
       
  1201 +            db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x)
       
  1202 +            db_inc_paths.append('/usr/local/include/db3%d' % x)
       
  1203 +            db_inc_paths.append('/pkg/db-3.%d/include' % x)
       
  1204 +            db_inc_paths.append('/opt/db-3.%d/include' % x)
       
  1205 +
       
  1206 +        # Add some common subdirectories for Sleepycat DB to the list,
       
  1207 +        # based on the standard include directories. This way DB3/4 gets
       
  1208 +        # picked up when it is installed in a non-standard prefix and
       
  1209 +        # the user has added that prefix into inc_dirs.
       
  1210 +        std_variants = []
       
  1211 +        for dn in inc_dirs:
       
  1212 +            std_variants.append(os.path.join(dn, 'db3'))
       
  1213 +            std_variants.append(os.path.join(dn, 'db4'))
       
  1214 +            for x in gen_db_minor_ver_nums(4):
       
  1215 +                std_variants.append(os.path.join(dn, "db4%d"%x))
       
  1216 +                std_variants.append(os.path.join(dn, "db4.%d"%x))
       
  1217 +            for x in gen_db_minor_ver_nums(3):
       
  1218 +                std_variants.append(os.path.join(dn, "db3%d"%x))
       
  1219 +                std_variants.append(os.path.join(dn, "db3.%d"%x))
       
  1220 +
       
  1221 +        db_inc_paths = std_variants + db_inc_paths
       
  1222 +        db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)]
       
  1223 +
       
  1224 +        db_ver_inc_map = {}
       
  1225 +
       
  1226 +        class db_found(Exception): pass
       
  1227 +        try:
       
  1228 +            # See whether there is a Sleepycat header in the standard
       
  1229 +            # search path.
       
  1230 +            for d in inc_dirs + db_inc_paths:
       
  1231 +                f = os.path.join(d, "db.h")
       
  1232 +                if db_setup_debug: print "db: looking for db.h in", f
       
  1233 +                if os.path.exists(f):
       
  1234 +                    f = open(f).read()
       
  1235 +                    m = re.search(r"#define\WDB_VERSION_MAJOR\W(\d+)", f)
       
  1236 +                    if m:
       
  1237 +                        db_major = int(m.group(1))
       
  1238 +                        m = re.search(r"#define\WDB_VERSION_MINOR\W(\d+)", f)
       
  1239 +                        db_minor = int(m.group(1))
       
  1240 +                        db_ver = (db_major, db_minor)
       
  1241 +
       
  1242 +                        # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug
       
  1243 +                        if db_ver == (4, 6):
       
  1244 +                            m = re.search(r"#define\WDB_VERSION_PATCH\W(\d+)", f)
       
  1245 +                            db_patch = int(m.group(1))
       
  1246 +                            if db_patch < 21:
       
  1247 +                                print "db.h:", db_ver, "patch", db_patch,
       
  1248 +                                print "being ignored (4.6.x must be >= 4.6.21)"
       
  1249 +                                continue
       
  1250 +
       
  1251 +                        if ( (not db_ver_inc_map.has_key(db_ver)) and
       
  1252 +                            allow_db_ver(db_ver) ):
       
  1253 +                            # save the include directory with the db.h version
       
  1254 +                            # (first occurrence only)
       
  1255 +                            db_ver_inc_map[db_ver] = d
       
  1256 +                            if db_setup_debug:
       
  1257 +                                print "db.h: found", db_ver, "in", d
       
  1258 +                        else:
       
  1259 +                            # we already found a header for this library version
       
  1260 +                            if db_setup_debug: print "db.h: ignoring", d
       
  1261 +                    else:
       
  1262 +                        # ignore this header, it didn't contain a version number
       
  1263 +                        if db_setup_debug:
       
  1264 +                            print "db.h: no version number version in", d
       
  1265 +
       
  1266 +            db_found_vers = db_ver_inc_map.keys()
       
  1267 +            db_found_vers.sort()
       
  1268 +
       
  1269 +            while db_found_vers:
       
  1270 +                db_ver = db_found_vers.pop()
       
  1271 +                db_incdir = db_ver_inc_map[db_ver]
       
  1272 +
       
  1273 +                # check lib directories parallel to the location of the header
       
  1274 +                db_dirs_to_check = [
       
  1275 +                    db_incdir.replace("include", 'lib64'),
       
  1276 +                    db_incdir.replace("include", 'lib'),
       
  1277 +                ]
       
  1278 +                db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check)
       
  1279 +
       
  1280 +                # Look for a version specific db-X.Y before an ambiguoius dbX
       
  1281 +                # XXX should we -ever- look for a dbX name?  Do any
       
  1282 +                # systems really not name their library by version and
       
  1283 +                # symlink to more general names?
       
  1284 +                for dblib in (('db-%d.%d' % db_ver),
       
  1285 +                              ('db%d%d' % db_ver),
       
  1286 +                              ('db%d' % db_ver[0])):
       
  1287 +                    dblib_file = self.compiler.find_library_file(
       
  1288 +                                    db_dirs_to_check + lib_dirs, dblib )
       
  1289 +                    if dblib_file:
       
  1290 +                        dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ]
       
  1291 +                        raise db_found
       
  1292 +                    else:
       
  1293 +                        if db_setup_debug: print "db lib: ", dblib, "not found"
       
  1294 +
       
  1295 +        except db_found:
       
  1296 +            if db_setup_debug:
       
  1297 +                print "bsddb using BerkeleyDB lib:", db_ver, dblib
       
  1298 +                print "bsddb lib dir:", dblib_dir, " inc dir:", db_incdir
       
  1299 +            db_incs = [db_incdir]
       
  1300 +            dblibs = [dblib]
       
  1301 +            # We add the runtime_library_dirs argument because the
       
  1302 +            # BerkeleyDB lib we're linking against often isn't in the
       
  1303 +            # system dynamic library search path.  This is usually
       
  1304 +            # correct and most trouble free, but may cause problems in
       
  1305 +            # some unusual system configurations (e.g. the directory
       
  1306 +            # is on an NFS server that goes away).
       
  1307 +            exts.append(Extension('_bsddb', ['_bsddb.c'],
       
  1308 +                                  depends = ['bsddb.h'],
       
  1309 +                                  library_dirs=dblib_dir,
       
  1310 +                                  runtime_library_dirs=dblib_dir,
       
  1311 +                                  include_dirs=db_incs,
       
  1312 +                                  libraries=dblibs))
       
  1313 +        else:
       
  1314 +            if db_setup_debug: print "db: no appropriate library found"
       
  1315 +            db_incs = None
       
  1316 +            dblibs = []
       
  1317 +            dblib_dir = None
       
  1318 +            missing.append('_bsddb')
       
  1319 +
       
  1320 +        # The sqlite interface
       
  1321 +        sqlite_setup_debug = False   # verbose debug prints from this script?
       
  1322 +
       
  1323 +        # We hunt for #define SQLITE_VERSION "n.n.n"
       
  1324 +        # We need to find >= sqlite version 3.0.8
       
  1325 +        sqlite_incdir = sqlite_libdir = None
       
  1326 +        sqlite_inc_paths = [ '/usr/include',
       
  1327 +                             '/usr/include/sqlite',
       
  1328 +                             '/usr/include/sqlite3',
       
  1329 +                             '/usr/local/include',
       
  1330 +                             '/usr/local/include/sqlite',
       
  1331 +                             '/usr/local/include/sqlite3',
       
  1332 +                           ]
       
  1333 +        MIN_SQLITE_VERSION_NUMBER = (3, 0, 8)
       
  1334 +        MIN_SQLITE_VERSION = ".".join([str(x)
       
  1335 +                                    for x in MIN_SQLITE_VERSION_NUMBER])
       
  1336 +
       
  1337 +        # Scan the default include directories before the SQLite specific
       
  1338 +        # ones. This allows one to override the copy of sqlite on OSX,
       
  1339 +        # where /usr/include contains an old version of sqlite.
       
  1340 +        for d in inc_dirs + sqlite_inc_paths:
       
  1341 +            f = os.path.join(d, "sqlite3.h")
       
  1342 +            if os.path.exists(f):
       
  1343 +                if sqlite_setup_debug: print "sqlite: found %s"%f
       
  1344 +                incf = open(f).read()
       
  1345 +                m = re.search(
       
  1346 +                    r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"(.*)"', incf)
       
  1347 +                if m:
       
  1348 +                    sqlite_version = m.group(1)
       
  1349 +                    sqlite_version_tuple = tuple([int(x)
       
  1350 +                                        for x in sqlite_version.split(".")])
       
  1351 +                    if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER:
       
  1352 +                        # we win!
       
  1353 +                        if sqlite_setup_debug:
       
  1354 +                            print "%s/sqlite3.h: version %s"%(d, sqlite_version)
       
  1355 +                        sqlite_incdir = d
       
  1356 +                        break
       
  1357 +                    else:
       
  1358 +                        if sqlite_setup_debug:
       
  1359 +                            print "%s: version %d is too old, need >= %s"%(d,
       
  1360 +                                        sqlite_version, MIN_SQLITE_VERSION)
       
  1361 +                elif sqlite_setup_debug:
       
  1362 +                    print "sqlite: %s had no SQLITE_VERSION"%(f,)
       
  1363 +
       
  1364 +        if sqlite_incdir:
       
  1365 +            sqlite_dirs_to_check = [
       
  1366 +                os.path.join(sqlite_incdir, '..', 'lib64'),
       
  1367 +                os.path.join(sqlite_incdir, '..', 'lib'),
       
  1368 +                os.path.join(sqlite_incdir, '..', '..', 'lib64'),
       
  1369 +                os.path.join(sqlite_incdir, '..', '..', 'lib'),
       
  1370 +            ]
       
  1371 +            sqlite_libfile = self.compiler.find_library_file(
       
  1372 +                                sqlite_dirs_to_check + lib_dirs, 'sqlite3')
       
  1373 +            if sqlite_libfile:
       
  1374 +                sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))]
       
  1375 +
       
  1376 +        if sqlite_incdir and sqlite_libdir:
       
  1377 +            sqlite_srcs = ['_sqlite/cache.c',
       
  1378 +                '_sqlite/connection.c',
       
  1379 +                '_sqlite/cursor.c',
       
  1380 +                '_sqlite/microprotocols.c',
       
  1381 +                '_sqlite/module.c',
       
  1382 +                '_sqlite/prepare_protocol.c',
       
  1383 +                '_sqlite/row.c',
       
  1384 +                '_sqlite/statement.c',
       
  1385 +                '_sqlite/util.c', ]
       
  1386 +
       
  1387 +            sqlite_defines = []
       
  1388 +            if sys.platform != "win32":
       
  1389 +                sqlite_defines.append(('MODULE_NAME', '"sqlite3"'))
       
  1390 +            else:
       
  1391 +                sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
       
  1392 +
       
  1393 +
       
  1394 +            if sys.platform == 'darwin':
       
  1395 +                # In every directory on the search path search for a dynamic
       
  1396 +                # library and then a static library, instead of first looking
       
  1397 +                # for dynamic libraries on the entiry path.
       
  1398 +                # This way a staticly linked custom sqlite gets picked up
       
  1399 +                # before the dynamic library in /usr/lib.
       
  1400 +                sqlite_extra_link_args = ('-Wl,-search_paths_first',)
       
  1401 +            else:
       
  1402 +                sqlite_extra_link_args = ()
       
  1403 +
       
  1404 +            exts.append(Extension('_sqlite3', sqlite_srcs,
       
  1405 +                                  define_macros=sqlite_defines,
       
  1406 +                                  include_dirs=["Modules/_sqlite",
       
  1407 +                                                sqlite_incdir],
       
  1408 +                                  library_dirs=sqlite_libdir,
       
  1409 +                                  runtime_library_dirs=sqlite_libdir,
       
  1410 +                                  extra_link_args=sqlite_extra_link_args,
       
  1411 +                                  libraries=["sqlite3",]))
       
  1412 +        else:
       
  1413 +            missing.append('_sqlite3')
       
  1414 +
       
  1415 +        # Look for Berkeley db 1.85.   Note that it is built as a different
       
  1416 +        # module name so it can be included even when later versions are
       
  1417 +        # available.  A very restrictive search is performed to avoid
       
  1418 +        # accidentally building this module with a later version of the
       
  1419 +        # underlying db library.  May BSD-ish Unixes incorporate db 1.85
       
  1420 +        # symbols into libc and place the include file in /usr/include.
       
  1421 +        #
       
  1422 +        # If the better bsddb library can be built (db_incs is defined)
       
  1423 +        # we do not build this one.  Otherwise this build will pick up
       
  1424 +        # the more recent berkeleydb's db.h file first in the include path
       
  1425 +        # when attempting to compile and it will fail.
       
  1426 +        f = "/usr/include/db.h"
       
  1427 +        if os.path.exists(f) and not db_incs:
       
  1428 +            data = open(f).read()
       
  1429 +            m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data)
       
  1430 +            if m is not None:
       
  1431 +                # bingo - old version used hash file format version 2
       
  1432 +                ### XXX this should be fixed to not be platform-dependent
       
  1433 +                ### but I don't have direct access to an osf1 platform and
       
  1434 +                ### seemed to be muffing the search somehow
       
  1435 +                libraries = platform == "osf1" and ['db'] or None
       
  1436 +                if libraries is not None:
       
  1437 +                    exts.append(Extension('bsddb185', ['bsddbmodule.c'],
       
  1438 +                                          libraries=libraries))
       
  1439 +                else:
       
  1440 +                    exts.append(Extension('bsddb185', ['bsddbmodule.c']))
       
  1441 +            else:
       
  1442 +                missing.append('bsddb185')
       
  1443 +        else:
       
  1444 +            missing.append('bsddb185')
       
  1445 +
       
  1446 +        # The standard Unix dbm module:
       
  1447 +        if platform not in ['cygwin']:
       
  1448 +            if find_file("ndbm.h", inc_dirs, []) is not None:
       
  1449 +                # Some systems have -lndbm, others don't
       
  1450 +                if self.compiler.find_library_file(lib_dirs, 'ndbm'):
       
  1451 +                    ndbm_libs = ['ndbm']
       
  1452 +                else:
       
  1453 +                    ndbm_libs = []
       
  1454 +                exts.append( Extension('dbm', ['dbmmodule.c'],
       
  1455 +                                       define_macros=[('HAVE_NDBM_H',None)],
       
  1456 +                                       libraries = ndbm_libs ) )
       
  1457 +            elif self.compiler.find_library_file(lib_dirs, 'gdbm'):
       
  1458 +                gdbm_libs = ['gdbm']
       
  1459 +                if self.compiler.find_library_file(lib_dirs, 'gdbm_compat'):
       
  1460 +                    gdbm_libs.append('gdbm_compat')
       
  1461 +                if find_file("gdbm/ndbm.h", inc_dirs, []) is not None:
       
  1462 +                    exts.append( Extension(
       
  1463 +                        'dbm', ['dbmmodule.c'],
       
  1464 +                        define_macros=[('HAVE_GDBM_NDBM_H',None)],
       
  1465 +                        libraries = gdbm_libs ) )
       
  1466 +                elif find_file("gdbm-ndbm.h", inc_dirs, []) is not None:
       
  1467 +                    exts.append( Extension(
       
  1468 +                        'dbm', ['dbmmodule.c'],
       
  1469 +                        define_macros=[('HAVE_GDBM_DASH_NDBM_H',None)],
       
  1470 +                        libraries = gdbm_libs ) )
       
  1471 +                else:
       
  1472 +                    missing.append('dbm')
       
  1473 +            elif db_incs is not None:
       
  1474 +                exts.append( Extension('dbm', ['dbmmodule.c'],
       
  1475 +                                       library_dirs=dblib_dir,
       
  1476 +                                       runtime_library_dirs=dblib_dir,
       
  1477 +                                       include_dirs=db_incs,
       
  1478 +                                       define_macros=[('HAVE_BERKDB_H',None),
       
  1479 +                                                      ('DB_DBM_HSEARCH',None)],
       
  1480 +                                       libraries=dblibs))
       
  1481 +            else:
       
  1482 +                missing.append('dbm')
       
  1483 +
       
  1484 +        # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
       
  1485 +        if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
       
  1486 +            exts.append( Extension('gdbm', ['gdbmmodule.c'],
       
  1487 +                                   libraries = ['gdbm'] ) )
       
  1488 +        else:
       
  1489 +            missing.append('gdbm')
       
  1490 +
       
  1491 +        # Unix-only modules
       
  1492 +        if platform not in ['mac', 'win32']:
       
  1493 +            # Steen Lumholt's termios module
       
  1494 +            exts.append( Extension('termios', ['termios.c']) )
       
  1495 +            # Jeremy Hylton's rlimit interface
       
  1496 +            if platform not in ['atheos']:
       
  1497 +                exts.append( Extension('resource', ['resource.c']) )
       
  1498 +            else:
       
  1499 +                missing.append('resource')
       
  1500 +
       
  1501 +            # Sun yellow pages. Some systems have the functions in libc.
       
  1502 +            if platform not in ['cygwin', 'atheos', 'qnx6']:
       
  1503 +                if (self.compiler.find_library_file(lib_dirs, 'nsl')):
       
  1504 +                    libs = ['nsl']
       
  1505 +                else:
       
  1506 +                    libs = []
       
  1507 +                exts.append( Extension('nis', ['nismodule.c'],
       
  1508 +                                       libraries = libs) )
       
  1509 +            else:
       
  1510 +                missing.append('nis')
       
  1511 +        else:
       
  1512 +            missing.extend(['nis', 'resource', 'termios'])
       
  1513 +
       
  1514 +        # Curses support, requiring the System V version of curses, often
       
  1515 +        # provided by the ncurses library.
       
  1516 +        curses_lib_dirs = []
       
  1517 +        curses_inc_dirs = []
       
  1518 +        if platform == 'sunos5':
       
  1519 +            # look for ncurses in /usr/gnu on Solaris
       
  1520 +            curses_inc_dirs.append('/usr/include/ncurses')
       
  1521 +            curses_lib_dirs.append('/usr/gnu/lib')
       
  1522 +            curses_lib_dirs.append('/usr/gnu/lib/amd64')
       
  1523 +            curses_lib_dirs.append('/usr/gnu/lib/sparcv9')
       
  1524 +        panel_library = 'panel'
       
  1525 +        if (self.compiler.find_library_file(lib_dirs, 'ncursesw')):
       
  1526 +            curses_libs = ['ncursesw']
       
  1527 +            # Bug 1464056: If _curses.so links with ncursesw,
       
  1528 +            # _curses_panel.so must link with panelw.
       
  1529 +            panel_library = 'panelw'
       
  1530 +            exts.append( Extension('_curses', ['_cursesmodule.c'],
       
  1531 +                                   libraries = curses_libs) )
       
  1532 +        elif (self.compiler.find_library_file(lib_dirs + curses_lib_dirs, 'ncurses')):
       
  1533 +            curses_libs = ['ncurses']
       
  1534 +            exts.append( Extension('_curses', ['_cursesmodule.c'],
       
  1535 +                                   libraries = curses_libs,
       
  1536 +                                   library_dirs = curses_lib_dirs,
       
  1537 +                                   runtime_library_dirs = curses_lib_dirs,
       
  1538 +                                   include_dirs = curses_inc_dirs ) )
       
  1539 +        elif (self.compiler.find_library_file(lib_dirs, 'curses')
       
  1540 +              and platform != 'darwin'):
       
  1541 +                # OSX has an old Berkeley curses, not good enough for
       
  1542 +                # the _curses module.
       
  1543 +            if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
       
  1544 +                curses_libs = ['curses', 'terminfo']
       
  1545 +            elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
       
  1546 +                curses_libs = ['curses', 'termcap']
       
  1547 +            else:
       
  1548 +                curses_libs = ['curses']
       
  1549 +
       
  1550 +            exts.append( Extension('_curses', ['_cursesmodule.c'],
       
  1551 +                                   libraries = curses_libs) )
       
  1552 +        else:
       
  1553 +            missing.append('_curses')
       
  1554 +
       
  1555 +        # If the curses module is enabled, check for the panel module
       
  1556 +        if (module_enabled(exts, '_curses') and
       
  1557 +            self.compiler.find_library_file(lib_dirs + curses_lib_dirs, panel_library)):
       
  1558 +            exts.append( Extension('_curses_panel', ['_curses_panel.c'],
       
  1559 +                                   libraries = [panel_library] + curses_libs,
       
  1560 +                                   include_dirs = curses_inc_dirs,
       
  1561 +                                   library_dirs = curses_lib_dirs,
       
  1562 +                                   runtime_library_dirs = curses_lib_dirs ) )
       
  1563 +        else:
       
  1564 +            missing.append('_curses_panel')
       
  1565 +
       
  1566 +        # Andrew Kuchling's zlib module.  Note that some versions of zlib
       
  1567 +        # 1.1.3 have security problems.  See CERT Advisory CA-2002-07:
       
  1568 +        # http://www.cert.org/advisories/CA-2002-07.html
       
  1569 +        #
       
  1570 +        # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
       
  1571 +        # patch its zlib 1.1.3 package instead of upgrading to 1.1.4.  For
       
  1572 +        # now, we still accept 1.1.3, because we think it's difficult to
       
  1573 +        # exploit this in Python, and we'd rather make it RedHat's problem
       
  1574 +        # than our problem <wink>.
       
  1575 +        #
       
  1576 +        # You can upgrade zlib to version 1.1.4 yourself by going to
       
  1577 +        # http://www.gzip.org/zlib/
       
  1578 +        zlib_inc = find_file('zlib.h', [], inc_dirs)
       
  1579 +        have_zlib = False
       
  1580 +        if zlib_inc is not None:
       
  1581 +            zlib_h = zlib_inc[0] + '/zlib.h'
       
  1582 +            version = '"0.0.0"'
       
  1583 +            version_req = '"1.1.3"'
       
  1584 +            fp = open(zlib_h)
       
  1585 +            while 1:
       
  1586 +                line = fp.readline()
       
  1587 +                if not line:
       
  1588 +                    break
       
  1589 +                if line.startswith('#define ZLIB_VERSION'):
       
  1590 +                    version = line.split()[2]
       
  1591 +                    break
       
  1592 +            if version >= version_req:
       
  1593 +                if (self.compiler.find_library_file(lib_dirs, 'z')):
       
  1594 +                    if sys.platform == "darwin":
       
  1595 +                        zlib_extra_link_args = ('-Wl,-search_paths_first',)
       
  1596 +                    else:
       
  1597 +                        zlib_extra_link_args = ()
       
  1598 +                    exts.append( Extension('zlib', ['zlibmodule.c'],
       
  1599 +                                           libraries = ['z'],
       
  1600 +                                           extra_link_args = zlib_extra_link_args))
       
  1601 +                    have_zlib = True
       
  1602 +                else:
       
  1603 +                    missing.append('zlib')
       
  1604 +            else:
       
  1605 +                missing.append('zlib')
       
  1606 +        else:
       
  1607 +            missing.append('zlib')
       
  1608 +
       
  1609 +        # Helper module for various ascii-encoders.  Uses zlib for an optimized
       
  1610 +        # crc32 if we have it.  Otherwise binascii uses its own.
       
  1611 +        if have_zlib:
       
  1612 +            extra_compile_args = ['-DUSE_ZLIB_CRC32']
       
  1613 +            libraries = ['z']
       
  1614 +            extra_link_args = zlib_extra_link_args
       
  1615 +        else:
       
  1616 +            extra_compile_args = []
       
  1617 +            libraries = []
       
  1618 +            extra_link_args = []
       
  1619 +        exts.append( Extension('binascii', ['binascii.c'],
       
  1620 +                               extra_compile_args = extra_compile_args,
       
  1621 +                               libraries = libraries,
       
  1622 +                               extra_link_args = extra_link_args) )
       
  1623 +
       
  1624 +        # Gustavo Niemeyer's bz2 module.
       
  1625 +        if (self.compiler.find_library_file(lib_dirs, 'bz2')):
       
  1626 +            if sys.platform == "darwin":
       
  1627 +                bz2_extra_link_args = ('-Wl,-search_paths_first',)
       
  1628 +            else:
       
  1629 +                bz2_extra_link_args = ()
       
  1630 +            exts.append( Extension('bz2', ['bz2module.c'],
       
  1631 +                                   libraries = ['bz2'],
       
  1632 +                                   extra_link_args = bz2_extra_link_args) )
       
  1633 +        else:
       
  1634 +            missing.append('bz2')
       
  1635 +
       
  1636 +        # Interface to the Expat XML parser
       
  1637 +        #
       
  1638 +        # Expat was written by James Clark and is now maintained by a
       
  1639 +        # group of developers on SourceForge; see www.libexpat.org for
       
  1640 +        # more information.  The pyexpat module was written by Paul
       
  1641 +        # Prescod after a prototype by Jack Jansen.  The Expat source
       
  1642 +        # is included in Modules/expat/.  Usage of a system
       
  1643 +        # shared libexpat.so/expat.dll is not advised.
       
  1644 +        #
       
  1645 +        # More information on Expat can be found at www.libexpat.org.
       
  1646 +        #
       
  1647 +        expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')
       
  1648 +        define_macros = [
       
  1649 +            ('HAVE_EXPAT_CONFIG_H', '1'),
       
  1650 +        ]
       
  1651 +
       
  1652 +        exts.append(Extension('pyexpat',
       
  1653 +                              define_macros = define_macros,
       
  1654 +                              include_dirs = [expatinc],
       
  1655 +                              sources = ['pyexpat.c',
       
  1656 +                                         'expat/xmlparse.c',
       
  1657 +                                         'expat/xmlrole.c',
       
  1658 +                                         'expat/xmltok.c',
       
  1659 +                                         ],
       
  1660 +                              ))
       
  1661 +
       
  1662 +        # Fredrik Lundh's cElementTree module.  Note that this also
       
  1663 +        # uses expat (via the CAPI hook in pyexpat).
       
  1664 +
       
  1665 +        if os.path.isfile(os.path.join(srcdir, 'Modules', '_elementtree.c')):
       
  1666 +            define_macros.append(('USE_PYEXPAT_CAPI', None))
       
  1667 +            exts.append(Extension('_elementtree',
       
  1668 +                                  define_macros = define_macros,
       
  1669 +                                  include_dirs = [expatinc],
       
  1670 +                                  sources = ['_elementtree.c'],
       
  1671 +                                  ))
       
  1672 +        else:
       
  1673 +            missing.append('_elementtree')
       
  1674 +
       
  1675 +        # Hye-Shik Chang's CJKCodecs modules.
       
  1676 +        if have_unicode:
       
  1677 +            exts.append(Extension('_multibytecodec',
       
  1678 +                                  ['cjkcodecs/multibytecodec.c']))
       
  1679 +            for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
       
  1680 +                exts.append(Extension('_codecs_%s' % loc,
       
  1681 +                                      ['cjkcodecs/_codecs_%s.c' % loc]))
       
  1682 +        else:
       
  1683 +            missing.append('_multibytecodec')
       
  1684 +            for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
       
  1685 +                missing.append('_codecs_%s' % loc)
       
  1686 +
       
  1687 +        # Dynamic loading module
       
  1688 +        if sys.maxint == 0x7fffffff:
       
  1689 +            # This requires sizeof(int) == sizeof(long) == sizeof(char*)
       
  1690 +            dl_inc = find_file('dlfcn.h', [], inc_dirs)
       
  1691 +            if (dl_inc is not None) and (platform not in ['atheos']):
       
  1692 +                exts.append( Extension('dl', ['dlmodule.c']) )
       
  1693 +            else:
       
  1694 +                missing.append('dl')
       
  1695 +        else:
       
  1696 +            missing.append('dl')
       
  1697 +
       
  1698 +        # Thomas Heller's _ctypes module
       
  1699 +        self.detect_ctypes(inc_dirs, lib_dirs)
       
  1700 +
       
  1701 +        # Richard Oudkerk's multiprocessing module
       
  1702 +        if platform == 'win32':             # Windows
       
  1703 +            macros = dict()
       
  1704 +            libraries = ['ws2_32']
       
  1705 +
       
  1706 +        elif platform == 'darwin':          # Mac OSX
       
  1707 +            macros = dict(
       
  1708 +                HAVE_SEM_OPEN=1,
       
  1709 +                HAVE_SEM_TIMEDWAIT=0,
       
  1710 +                HAVE_FD_TRANSFER=1,
       
  1711 +                HAVE_BROKEN_SEM_GETVALUE=1
       
  1712 +                )
       
  1713 +            libraries = []
       
  1714 +
       
  1715 +        elif platform == 'cygwin':          # Cygwin
       
  1716 +            macros = dict(
       
  1717 +                HAVE_SEM_OPEN=1,
       
  1718 +                HAVE_SEM_TIMEDWAIT=1,
       
  1719 +                HAVE_FD_TRANSFER=0,
       
  1720 +                HAVE_BROKEN_SEM_UNLINK=1
       
  1721 +                )
       
  1722 +            libraries = []
       
  1723 +
       
  1724 +        elif platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'):
       
  1725 +            # FreeBSD's P1003.1b semaphore support is very experimental
       
  1726 +            # and has many known problems. (as of June 2008)
       
  1727 +            macros = dict(                  # FreeBSD
       
  1728 +                HAVE_SEM_OPEN=0,
       
  1729 +                HAVE_SEM_TIMEDWAIT=0,
       
  1730 +                HAVE_FD_TRANSFER=1,
       
  1731 +                )
       
  1732 +            libraries = []
       
  1733 +
       
  1734 +        elif platform.startswith('openbsd'):
       
  1735 +            macros = dict(                  # OpenBSD
       
  1736 +                HAVE_SEM_OPEN=0,            # Not implemented
       
  1737 +                HAVE_SEM_TIMEDWAIT=0,
       
  1738 +                HAVE_FD_TRANSFER=1,
       
  1739 +                )
       
  1740 +            libraries = []
       
  1741 +
       
  1742 +        elif platform.startswith('netbsd'):
       
  1743 +            macros = dict(                  # at least NetBSD 5
       
  1744 +                HAVE_SEM_OPEN=1,
       
  1745 +                HAVE_SEM_TIMEDWAIT=0,
       
  1746 +                HAVE_FD_TRANSFER=1,
       
  1747 +                HAVE_BROKEN_SEM_GETVALUE=1
       
  1748 +                )
       
  1749 +            libraries = []
       
  1750 +
       
  1751 +        else:                                   # Linux and other unices
       
  1752 +            macros = dict(
       
  1753 +                HAVE_SEM_OPEN=1,
       
  1754 +                HAVE_SEM_TIMEDWAIT=1,
       
  1755 +                HAVE_FD_TRANSFER=1
       
  1756 +                )
       
  1757 +            libraries = ['rt']
       
  1758 +
       
  1759 +        if platform == 'win32':
       
  1760 +            multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
       
  1761 +                                     '_multiprocessing/semaphore.c',
       
  1762 +                                     '_multiprocessing/pipe_connection.c',
       
  1763 +                                     '_multiprocessing/socket_connection.c',
       
  1764 +                                     '_multiprocessing/win32_functions.c'
       
  1765 +                                   ]
       
  1766 +
       
  1767 +        else:
       
  1768 +            multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
       
  1769 +                                     '_multiprocessing/socket_connection.c'
       
  1770 +                                   ]
       
  1771 +
       
  1772 +            if macros.get('HAVE_SEM_OPEN', False):
       
  1773 +                multiprocessing_srcs.append('_multiprocessing/semaphore.c')
       
  1774 +
       
  1775 +        multiproc_libs = []
       
  1776 +        if platform == 'sunos5':
       
  1777 +            multiproc_libs = [ "xnet" ]
       
  1778 +
       
  1779 +        exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
       
  1780 +                                 define_macros=macros.items(),
       
  1781 +                                 libraries=multiproc_libs,
       
  1782 +                                 include_dirs=["Modules/_multiprocessing"]))
       
  1783 +        # End multiprocessing
       
  1784 +
       
  1785 +
       
  1786 +        # Platform-specific libraries
       
  1787 +        if platform == 'linux2':
       
  1788 +            # Linux-specific modules
       
  1789 +            exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
       
  1790 +        else:
       
  1791 +            missing.append('linuxaudiodev')
       
  1792 +
       
  1793 +        if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
       
  1794 +                        'freebsd7', 'freebsd8'):
       
  1795 +            exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
       
  1796 +        else:
       
  1797 +            missing.append('ossaudiodev')
       
  1798 +
       
  1799 +        if platform == 'sunos5':
       
  1800 +            # SunOS specific modules
       
  1801 +            exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
       
  1802 +        else:
       
  1803 +            missing.append('sunaudiodev')
       
  1804 +
       
  1805 +        if platform == 'darwin':
       
  1806 +            # _scproxy
       
  1807 +            exts.append(Extension("_scproxy", [os.path.join(srcdir, "Mac/Modules/_scproxy.c")],
       
  1808 +                extra_link_args= [
       
  1809 +                    '-framework', 'SystemConfiguration',
       
  1810 +                    '-framework', 'CoreFoundation'
       
  1811 +                ]))
       
  1812 +
       
  1813 +
       
  1814 +        if platform == 'darwin' and ("--disable-toolbox-glue" not in
       
  1815 +                sysconfig.get_config_var("CONFIG_ARGS")):
       
  1816 +
       
  1817 +            if os.uname()[2] > '8.':
       
  1818 +                # We're on Mac OS X 10.4 or later, the compiler should
       
  1819 +                # support '-Wno-deprecated-declarations'. This will
       
  1820 +                # surpress deprecation warnings for the Carbon extensions,
       
  1821 +                # these extensions wrap the Carbon APIs and even those
       
  1822 +                # parts that are deprecated.
       
  1823 +                carbon_extra_compile_args = ['-Wno-deprecated-declarations']
       
  1824 +            else:
       
  1825 +                carbon_extra_compile_args = []
       
  1826 +
       
  1827 +            # Mac OS X specific modules.
       
  1828 +            def macSrcExists(name1, name2=''):
       
  1829 +                if not name1:
       
  1830 +                    return None
       
  1831 +                names = (name1,)
       
  1832 +                if name2:
       
  1833 +                    names = (name1, name2)
       
  1834 +                path = os.path.join(srcdir, 'Mac', 'Modules', *names)
       
  1835 +                return os.path.exists(path)
       
  1836 +
       
  1837 +            def addMacExtension(name, kwds, extra_srcs=[]):
       
  1838 +                dirname = ''
       
  1839 +                if name[0] == '_':
       
  1840 +                    dirname = name[1:].lower()
       
  1841 +                cname = name + '.c'
       
  1842 +                cmodulename = name + 'module.c'
       
  1843 +                # Check for NNN.c, NNNmodule.c, _nnn/NNN.c, _nnn/NNNmodule.c
       
  1844 +                if macSrcExists(cname):
       
  1845 +                    srcs = [cname]
       
  1846 +                elif macSrcExists(cmodulename):
       
  1847 +                    srcs = [cmodulename]
       
  1848 +                elif macSrcExists(dirname, cname):
       
  1849 +                    # XXX(nnorwitz): If all the names ended with module, we
       
  1850 +                    # wouldn't need this condition.  ibcarbon is the only one.
       
  1851 +                    srcs = [os.path.join(dirname, cname)]
       
  1852 +                elif macSrcExists(dirname, cmodulename):
       
  1853 +                    srcs = [os.path.join(dirname, cmodulename)]
       
  1854 +                else:
       
  1855 +                    raise RuntimeError("%s not found" % name)
       
  1856 +
       
  1857 +                # Here's the whole point:  add the extension with sources
       
  1858 +                exts.append(Extension(name, srcs + extra_srcs, **kwds))
       
  1859 +
       
  1860 +            # Core Foundation
       
  1861 +            core_kwds = {'extra_compile_args': carbon_extra_compile_args,
       
  1862 +                         'extra_link_args': ['-framework', 'CoreFoundation'],
       
  1863 +                        }
       
  1864 +            addMacExtension('_CF', core_kwds, ['cf/pycfbridge.c'])
       
  1865 +            addMacExtension('autoGIL', core_kwds)
       
  1866 +
       
  1867 +
       
  1868 +
       
  1869 +            # Carbon
       
  1870 +            carbon_kwds = {'extra_compile_args': carbon_extra_compile_args,
       
  1871 +                           'extra_link_args': ['-framework', 'Carbon'],
       
  1872 +                          }
       
  1873 +            CARBON_EXTS = ['ColorPicker', 'gestalt', 'MacOS', 'Nav',
       
  1874 +                           'OSATerminology', 'icglue',
       
  1875 +                           # All these are in subdirs
       
  1876 +                           '_AE', '_AH', '_App', '_CarbonEvt', '_Cm', '_Ctl',
       
  1877 +                           '_Dlg', '_Drag', '_Evt', '_File', '_Folder', '_Fm',
       
  1878 +                           '_Help', '_Icn', '_IBCarbon', '_List',
       
  1879 +                           '_Menu', '_Mlte', '_OSA', '_Res', '_Qd', '_Qdoffs',
       
  1880 +                           '_Scrap', '_Snd', '_TE',
       
  1881 +                          ]
       
  1882 +            for name in CARBON_EXTS:
       
  1883 +                addMacExtension(name, carbon_kwds)
       
  1884 +
       
  1885 +            # Workaround for a bug in the version of gcc shipped with Xcode 3.
       
  1886 +            # The _Win extension should build just like the other Carbon extensions, but
       
  1887 +            # this actually results in a hard crash of the linker.
       
  1888 +            #
       
  1889 +            if '-arch ppc64' in cflags and '-arch ppc' in cflags:
       
  1890 +                win_kwds = {'extra_compile_args': carbon_extra_compile_args + ['-arch', 'i386', '-arch', 'ppc'],
       
  1891 +                               'extra_link_args': ['-framework', 'Carbon', '-arch', 'i386', '-arch', 'ppc'],
       
  1892 +                           }
       
  1893 +                addMacExtension('_Win', win_kwds)
       
  1894 +            else:
       
  1895 +                addMacExtension('_Win', carbon_kwds)
       
  1896 +
       
  1897 +
       
  1898 +            # Application Services & QuickTime
       
  1899 +            app_kwds = {'extra_compile_args': carbon_extra_compile_args,
       
  1900 +                        'extra_link_args': ['-framework','ApplicationServices'],
       
  1901 +                       }
       
  1902 +            addMacExtension('_Launch', app_kwds)
       
  1903 +            addMacExtension('_CG', app_kwds)
       
  1904 +
       
  1905 +            exts.append( Extension('_Qt', ['qt/_Qtmodule.c'],
       
  1906 +                        extra_compile_args=carbon_extra_compile_args,
       
  1907 +                        extra_link_args=['-framework', 'QuickTime',
       
  1908 +                                     '-framework', 'Carbon']) )
       
  1909 +
       
  1910 +
       
  1911 +        self.extensions.extend(exts)
       
  1912 +
       
  1913 +        # Call the method for detecting whether _tkinter can be compiled
       
  1914 +        self.detect_tkinter(inc_dirs, lib_dirs)
       
  1915 +
       
  1916 +        if '_tkinter' not in [e.name for e in self.extensions]:
       
  1917 +            missing.append('_tkinter')
       
  1918 +
       
  1919 +        return missing
       
  1920 +
       
  1921 +    def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
       
  1922 +        # The _tkinter module, using frameworks. Since frameworks are quite
       
  1923 +        # different the UNIX search logic is not sharable.
       
  1924 +        from os.path import join, exists
       
  1925 +        framework_dirs = [
       
  1926 +            '/Library/Frameworks',
       
  1927 +            '/System/Library/Frameworks/',
       
  1928 +            join(os.getenv('HOME'), '/Library/Frameworks')
       
  1929 +        ]
       
  1930 +
       
  1931 +        # Find the directory that contains the Tcl.framework and Tk.framework
       
  1932 +        # bundles.
       
  1933 +        # XXX distutils should support -F!
       
  1934 +        for F in framework_dirs:
       
  1935 +            # both Tcl.framework and Tk.framework should be present
       
  1936 +            for fw in 'Tcl', 'Tk':
       
  1937 +                if not exists(join(F, fw + '.framework')):
       
  1938 +                    break
       
  1939 +            else:
       
  1940 +                # ok, F is now directory with both frameworks. Continure
       
  1941 +                # building
       
  1942 +                break
       
  1943 +        else:
       
  1944 +            # Tk and Tcl frameworks not found. Normal "unix" tkinter search
       
  1945 +            # will now resume.
       
  1946 +            return 0
       
  1947 +
       
  1948 +        # For 8.4a2, we must add -I options that point inside the Tcl and Tk
       
  1949 +        # frameworks. In later release we should hopefully be able to pass
       
  1950 +        # the -F option to gcc, which specifies a framework lookup path.
       
  1951 +        #
       
  1952 +        include_dirs = [
       
  1953 +            join(F, fw + '.framework', H)
       
  1954 +            for fw in 'Tcl', 'Tk'
       
  1955 +            for H in 'Headers', 'Versions/Current/PrivateHeaders'
       
  1956 +        ]
       
  1957 +
       
  1958 +        # For 8.4a2, the X11 headers are not included. Rather than include a
       
  1959 +        # complicated search, this is a hard-coded path. It could bail out
       
  1960 +        # if X11 libs are not found...
       
  1961 +        include_dirs.append('/usr/X11R6/include')
       
  1962 +        frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
       
  1963 +
       
  1964 +        # All existing framework builds of Tcl/Tk don't support 64-bit
       
  1965 +        # architectures.
       
  1966 +        cflags = sysconfig.get_config_vars('CFLAGS')[0]
       
  1967 +        archs = re.findall('-arch\s+(\w+)', cflags)
       
  1968 +        fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,))
       
  1969 +        detected_archs = []
       
  1970 +        for ln in fp:
       
  1971 +            a = ln.split()[-1]
       
  1972 +            if a in archs:
       
  1973 +                detected_archs.append(ln.split()[-1])
       
  1974 +        fp.close()
       
  1975 +
       
  1976 +        for a in detected_archs:
       
  1977 +            frameworks.append('-arch')
       
  1978 +            frameworks.append(a)
       
  1979 +
       
  1980 +        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
       
  1981 +                        define_macros=[('WITH_APPINIT', 1)],
       
  1982 +                        include_dirs = include_dirs,
       
  1983 +                        libraries = [],
       
  1984 +                        extra_compile_args = frameworks[2:],
       
  1985 +                        extra_link_args = frameworks,
       
  1986 +                        )
       
  1987 +        self.extensions.append(ext)
       
  1988 +        return 1
       
  1989 +
       
  1990 +
       
  1991 +    def detect_tkinter(self, inc_dirs, lib_dirs):
       
  1992 +        # The _tkinter module.
       
  1993 +
       
  1994 +        # Rather than complicate the code below, detecting and building
       
  1995 +        # AquaTk is a separate method. Only one Tkinter will be built on
       
  1996 +        # Darwin - either AquaTk, if it is found, or X11 based Tk.
       
  1997 +        platform = self.get_platform()
       
  1998 +        if (platform == 'darwin' and
       
  1999 +            self.detect_tkinter_darwin(inc_dirs, lib_dirs)):
       
  2000 +            return
       
  2001 +
       
  2002 +        # Assume we haven't found any of the libraries or include files
       
  2003 +        # The versions with dots are used on Unix, and the versions without
       
  2004 +        # dots on Windows, for detection by cygwin.
       
  2005 +        added_lib_dirs = []
       
  2006 +        tcl_tk_lib_dirs = ['/usr/sfw/lib']
       
  2007 +        tcl_tk_inc_dirs = ['/usr/sfw/include']
       
  2008 +        tcllib = tklib = tcl_includes = tk_includes = None
       
  2009 +        for version in ['8.5', '85', '8.4', '84', '8.3', '83', '8.2',
       
  2010 +                        '82', '8.1', '81', '8.0', '80']:
       
  2011 +            tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version, tcl_tk_lib_dirs)
       
  2012 +            tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version, tcl_tk_lib_dirs)
       
  2013 +            if tklib and tcllib:
       
  2014 +                # Exit the loop when we've found the Tcl/Tk libraries
       
  2015 +                break
       
  2016 +
       
  2017 +            tklib = self.compiler.find_library_file(tcl_tk_lib_dirs, 'tk' + version)
       
  2018 +            tcllib = self.compiler.find_library_file(tcl_tk_lib_dirs, 'tcl' + version)
       
  2019 +            if tklib and tcllib:
       
  2020 +                # found the libs in a non-standard dir
       
  2021 +                added_lib_dirs.append(os.path.dirname(tcllib))
       
  2022 +                # Exit the loop when we've found the Tcl/Tk libraries
       
  2023 +                break
       
  2024 +
       
  2025 +        # Now check for the header files
       
  2026 +        if tklib and tcllib:
       
  2027 +            # Check for the include files on Debian and {Free,Open}BSD, where
       
  2028 +            # they're put in /usr/include/{tcl,tk}X.Y
       
  2029 +            dotversion = version
       
  2030 +            if '.' not in dotversion and "bsd" in sys.platform.lower():
       
  2031 +                # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a,
       
  2032 +                # but the include subdirs are named like .../include/tcl8.3.
       
  2033 +                dotversion = dotversion[:-1] + '.' + dotversion[-1]
       
  2034 +            tcl_include_sub = []
       
  2035 +            tk_include_sub = []
       
  2036 +            for dir in inc_dirs:
       
  2037 +                tcl_include_sub += [dir + os.sep + "tcl" + dotversion]
       
  2038 +                tk_include_sub += [dir + os.sep + "tk" + dotversion]
       
  2039 +            tcl_include_sub += tcl_tk_inc_dirs
       
  2040 +            tk_include_sub += tcl_include_sub
       
  2041 +            tcl_includes = find_file('tcl.h', inc_dirs, tcl_include_sub)
       
  2042 +            tk_includes = find_file('tk.h', inc_dirs, tk_include_sub)
       
  2043 +
       
  2044 +        if (tcllib is None or tklib is None or
       
  2045 +            tcl_includes is None or tk_includes is None):
       
  2046 +            self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2)
       
  2047 +            return
       
  2048 +
       
  2049 +        # OK... everything seems to be present for Tcl/Tk.
       
  2050 +
       
  2051 +        include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
       
  2052 +        for dir in tcl_includes + tk_includes:
       
  2053 +            if dir not in include_dirs:
       
  2054 +                include_dirs.append(dir)
       
  2055 +
       
  2056 +        # Check for various platform-specific directories
       
  2057 +        if platform == 'sunos5':
       
  2058 +            include_dirs.append('/usr/openwin/include')
       
  2059 +            added_lib_dirs.append('/usr/openwin/lib')
       
  2060 +        elif os.path.exists('/usr/X11R6/include'):
       
  2061 +            include_dirs.append('/usr/X11R6/include')
       
  2062 +            added_lib_dirs.append('/usr/X11R6/lib64')
       
  2063 +            added_lib_dirs.append('/usr/X11R6/lib')
       
  2064 +        elif os.path.exists('/usr/X11R5/include'):
       
  2065 +            include_dirs.append('/usr/X11R5/include')
       
  2066 +            added_lib_dirs.append('/usr/X11R5/lib')
       
  2067 +        else:
       
  2068 +            # Assume default location for X11
       
  2069 +            include_dirs.append('/usr/X11/include')
       
  2070 +            added_lib_dirs.append('/usr/X11/lib')
       
  2071 +
       
  2072 +        # If Cygwin, then verify that X is installed before proceeding
       
  2073 +        if platform == 'cygwin':
       
  2074 +            x11_inc = find_file('X11/Xlib.h', [], include_dirs)
       
  2075 +            if x11_inc is None:
       
  2076 +                return
       
  2077 +
       
  2078 +        # Check for BLT extension
       
  2079 +        if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
       
  2080 +                                           'BLT8.0'):
       
  2081 +            defs.append( ('WITH_BLT', 1) )
       
  2082 +            libs.append('BLT8.0')
       
  2083 +        elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
       
  2084 +                                           'BLT'):
       
  2085 +            defs.append( ('WITH_BLT', 1) )
       
  2086 +            libs.append('BLT')
       
  2087 +
       
  2088 +        # Add the Tcl/Tk libraries
       
  2089 +        libs.append('tk'+ version)
       
  2090 +        libs.append('tcl'+ version)
       
  2091 +
       
  2092 +        if platform in ['aix3', 'aix4']:
       
  2093 +            libs.append('ld')
       
  2094 +
       
  2095 +        # Finally, link with the X11 libraries (not appropriate on cygwin)
       
  2096 +        if platform != "cygwin":
       
  2097 +            libs.append('X11')
       
  2098 +
       
  2099 +        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
       
  2100 +                        define_macros=[('WITH_APPINIT', 1)] + defs,
       
  2101 +                        include_dirs = include_dirs,
       
  2102 +                        libraries = libs,
       
  2103 +                        library_dirs = added_lib_dirs,
       
  2104 +                        runtime_library_dirs = added_lib_dirs
       
  2105 +                        )
       
  2106 +        self.extensions.append(ext)
       
  2107 +
       
  2108 +##         # Uncomment these lines if you want to play with xxmodule.c
       
  2109 +##         ext = Extension('xx', ['xxmodule.c'])
       
  2110 +##         self.extensions.append(ext)
       
  2111 +
       
  2112 +        # XXX handle these, but how to detect?
       
  2113 +        # *** Uncomment and edit for PIL (TkImaging) extension only:
       
  2114 +        #       -DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
       
  2115 +        # *** Uncomment and edit for TOGL extension only:
       
  2116 +        #       -DWITH_TOGL togl.c \
       
  2117 +        # *** Uncomment these for TOGL extension only:
       
  2118 +        #       -lGL -lGLU -lXext -lXmu \
       
  2119 +
       
  2120 +    def configure_ctypes_darwin(self, ext):
       
  2121 +        # Darwin (OS X) uses preconfigured files, in
       
  2122 +        # the Modules/_ctypes/libffi_osx directory.
       
  2123 +        (srcdir,) = sysconfig.get_config_vars('srcdir')
       
  2124 +        ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
       
  2125 +                                                  '_ctypes', 'libffi_osx'))
       
  2126 +        sources = [os.path.join(ffi_srcdir, p)
       
  2127 +                   for p in ['ffi.c',
       
  2128 +                             'x86/darwin64.S',
       
  2129 +                             'x86/x86-darwin.S',
       
  2130 +                             'x86/x86-ffi_darwin.c',
       
  2131 +                             'x86/x86-ffi64.c',
       
  2132 +                             'powerpc/ppc-darwin.S',
       
  2133 +                             'powerpc/ppc-darwin_closure.S',
       
  2134 +                             'powerpc/ppc-ffi_darwin.c',
       
  2135 +                             'powerpc/ppc64-darwin_closure.S',
       
  2136 +                             ]]
       
  2137 +
       
  2138 +        # Add .S (preprocessed assembly) to C compiler source extensions.
       
  2139 +        self.compiler.src_extensions.append('.S')
       
  2140 +
       
  2141 +        include_dirs = [os.path.join(ffi_srcdir, 'include'),
       
  2142 +                        os.path.join(ffi_srcdir, 'powerpc')]
       
  2143 +        ext.include_dirs.extend(include_dirs)
       
  2144 +        ext.sources.extend(sources)
       
  2145 +        return True
       
  2146 +
       
  2147 +    def configure_ctypes(self, ext):
       
  2148 +        if not self.use_system_libffi:
       
  2149 +            if sys.platform == 'darwin':
       
  2150 +                return self.configure_ctypes_darwin(ext)
       
  2151 +
       
  2152 +            (srcdir,) = sysconfig.get_config_vars('srcdir')
       
  2153 +            ffi_builddir = os.path.join(self.build_temp, 'libffi')
       
  2154 +            ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
       
  2155 +                                         '_ctypes', 'libffi'))
       
  2156 +            ffi_configfile = os.path.join(ffi_builddir, 'fficonfig.py')
       
  2157 +
       
  2158 +            from distutils.dep_util import newer_group
       
  2159 +
       
  2160 +            config_sources = [os.path.join(ffi_srcdir, fname)
       
  2161 +                              for fname in os.listdir(ffi_srcdir)
       
  2162 +                              if os.path.isfile(os.path.join(ffi_srcdir, fname))]
       
  2163 +            if self.force or newer_group(config_sources,
       
  2164 +                                         ffi_configfile):
       
  2165 +                from distutils.dir_util import mkpath
       
  2166 +                mkpath(ffi_builddir)
       
  2167 +                config_args = []
       
  2168 +
       
  2169 +                # Pass empty CFLAGS because we'll just append the resulting
       
  2170 +                # CFLAGS to Python's; -g or -O2 is to be avoided.
       
  2171 +                cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
       
  2172 +                      % (ffi_builddir, ffi_srcdir, " ".join(config_args))
       
  2173 +
       
  2174 +                res = os.system(cmd)
       
  2175 +                if res or not os.path.exists(ffi_configfile):
       
  2176 +                    print "Failed to configure _ctypes module"
       
  2177 +                    return False
       
  2178 +
       
  2179 +            fficonfig = {}
       
  2180 +            execfile(ffi_configfile, globals(), fficonfig)
       
  2181 +            ffi_srcdir = os.path.join(fficonfig['ffi_srcdir'], 'src')
       
  2182 +
       
  2183 +            # Add .S (preprocessed assembly) to C compiler source extensions.
       
  2184 +            self.compiler.src_extensions.append('.S')
       
  2185 +
       
  2186 +            include_dirs = [os.path.join(ffi_builddir, 'include'),
       
  2187 +                            ffi_builddir, ffi_srcdir]
       
  2188 +            extra_compile_args = fficonfig['ffi_cflags'].split()
       
  2189 +
       
  2190 +            ext.sources.extend(fficonfig['ffi_sources'])
       
  2191 +            ext.include_dirs.extend(include_dirs)
       
  2192 +            ext.extra_compile_args.extend(extra_compile_args)
       
  2193 +        return True
       
  2194 +
       
  2195 +    def detect_ctypes(self, inc_dirs, lib_dirs):
       
  2196 +        self.use_system_libffi = False
       
  2197 +        include_dirs = []
       
  2198 +        extra_compile_args = []
       
  2199 +        extra_link_args = []
       
  2200 +        sources = ['_ctypes/_ctypes.c',
       
  2201 +                   '_ctypes/callbacks.c',
       
  2202 +                   '_ctypes/callproc.c',
       
  2203 +                   '_ctypes/stgdict.c',
       
  2204 +                   '_ctypes/cfield.c',
       
  2205 +                   '_ctypes/malloc_closure.c']
       
  2206 +        depends = ['_ctypes/ctypes.h']
       
  2207 +
       
  2208 +        if sys.platform == 'darwin':
       
  2209 +            sources.append('_ctypes/darwin/dlfcn_simple.c')
       
  2210 +            extra_compile_args.append('-DMACOSX')
       
  2211 +            include_dirs.append('_ctypes/darwin')
       
  2212 +# XXX Is this still needed?
       
  2213 +##            extra_link_args.extend(['-read_only_relocs', 'warning'])
       
  2214 +
       
  2215 +        elif sys.platform == 'sunos5':
       
  2216 +            # XXX This shouldn't be necessary; it appears that some
       
  2217 +            # of the assembler code is non-PIC (i.e. it has relocations
       
  2218 +            # when it shouldn't. The proper fix would be to rewrite
       
  2219 +            # the assembler code to be PIC.
       
  2220 +            # This only works with GCC; the Sun compiler likely refuses
       
  2221 +            # this option. If you want to compile ctypes with the Sun
       
  2222 +            # compiler, please research a proper solution, instead of
       
  2223 +            # finding some -z option for the Sun compiler.
       
  2224 +            extra_link_args.append('-mimpure-text')
       
  2225 +
       
  2226 +        elif sys.platform.startswith('hp-ux'):
       
  2227 +            extra_link_args.append('-fPIC')
       
  2228 +
       
  2229 +        ext = Extension('_ctypes',
       
  2230 +                        include_dirs=include_dirs,
       
  2231 +                        extra_compile_args=extra_compile_args,
       
  2232 +                        extra_link_args=extra_link_args,
       
  2233 +                        libraries=[],
       
  2234 +                        sources=sources,
       
  2235 +                        depends=depends)
       
  2236 +        ext_test = Extension('_ctypes_test',
       
  2237 +                             sources=['_ctypes/_ctypes_test.c'])
       
  2238 +        self.extensions.extend([ext, ext_test])
       
  2239 +
       
  2240 +        if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):
       
  2241 +            return
       
  2242 +
       
  2243 +        if sys.platform == 'darwin':
       
  2244 +            # OS X 10.5 comes with libffi.dylib; the include files are
       
  2245 +            # in /usr/include/ffi
       
  2246 +            inc_dirs.append('/usr/include/ffi')
       
  2247 +
       
  2248 +        ffi_inc = find_file('ffi.h', [], inc_dirs)
       
  2249 +        if ffi_inc is not None:
       
  2250 +            ffi_h = ffi_inc[0] + '/ffi.h'
       
  2251 +            fp = open(ffi_h)
       
  2252 +            while 1:
       
  2253 +                line = fp.readline()
       
  2254 +                if not line:
       
  2255 +                    ffi_inc = None
       
  2256 +                    break
       
  2257 +                if line.startswith('#define LIBFFI_H'):
       
  2258 +                    break
       
  2259 +        ffi_lib = None
       
  2260 +        if ffi_inc is not None:
       
  2261 +            for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
       
  2262 +                if (self.compiler.find_library_file(lib_dirs, lib_name)):
       
  2263 +                    ffi_lib = lib_name
       
  2264 +                    break
       
  2265 +
       
  2266 +        if ffi_inc and ffi_lib:
       
  2267 +            ext.include_dirs.extend(ffi_inc)
       
  2268 +            ext.libraries.append(ffi_lib)
       
  2269 +            self.use_system_libffi = True
       
  2270 +
       
  2271 +
       
  2272 +class PyBuildInstall(install):
       
  2273 +    # Suppress the warning about installation into the lib_dynload
       
  2274 +    # directory, which is not in sys.path when running Python during
       
  2275 +    # installation:
       
  2276 +    def initialize_options (self):
       
  2277 +        install.initialize_options(self)
       
  2278 +        self.warn_dir=0
       
  2279 +
       
  2280 +class PyBuildInstallLib(install_lib):
       
  2281 +    # Do exactly what install_lib does but make sure correct access modes get
       
  2282 +    # set on installed directories and files. All installed files with get
       
  2283 +    # mode 644 unless they are a shared library in which case they will get
       
  2284 +    # mode 755. All installed directories will get mode 755.
       
  2285 +
       
  2286 +    so_ext = sysconfig.get_config_var("SO")
       
  2287 +
       
  2288 +    def install(self):
       
  2289 +        outfiles = install_lib.install(self)
       
  2290 +        self.set_file_modes(outfiles, 0644, 0755)
       
  2291 +        self.set_dir_modes(self.install_dir, 0755)
       
  2292 +        return outfiles
       
  2293 +
       
  2294 +    def set_file_modes(self, files, defaultMode, sharedLibMode):
       
  2295 +        if not self.is_chmod_supported(): return
       
  2296 +        if not files: return
       
  2297 +
       
  2298 +        for filename in files:
       
  2299 +            if os.path.islink(filename): continue
       
  2300 +            mode = defaultMode
       
  2301 +            if filename.endswith(self.so_ext): mode = sharedLibMode
       
  2302 +            log.info("changing mode of %s to %o", filename, mode)
       
  2303 +            if not self.dry_run: os.chmod(filename, mode)
       
  2304 +
       
  2305 +    def set_dir_modes(self, dirname, mode):
       
  2306 +        if not self.is_chmod_supported(): return
       
  2307 +        os.path.walk(dirname, self.set_dir_modes_visitor, mode)
       
  2308 +
       
  2309 +    def set_dir_modes_visitor(self, mode, dirname, names):
       
  2310 +        if os.path.islink(dirname): return
       
  2311 +        log.info("changing mode of %s to %o", dirname, mode)
       
  2312 +        if not self.dry_run: os.chmod(dirname, mode)
       
  2313 +
       
  2314 +    def is_chmod_supported(self):
       
  2315 +        return hasattr(os, 'chmod')
       
  2316 +
       
  2317 +SUMMARY = """
       
  2318 +Python is an interpreted, interactive, object-oriented programming
       
  2319 +language. It is often compared to Tcl, Perl, Scheme or Java.
       
  2320 +
       
  2321 +Python combines remarkable power with very clear syntax. It has
       
  2322 +modules, classes, exceptions, very high level dynamic data types, and
       
  2323 +dynamic typing. There are interfaces to many system calls and
       
  2324 +libraries, as well as to various windowing systems (X11, Motif, Tk,
       
  2325 +Mac, MFC). New built-in modules are easily written in C or C++. Python
       
  2326 +is also usable as an extension language for applications that need a
       
  2327 +programmable interface.
       
  2328 +
       
  2329 +The Python implementation is portable: it runs on many brands of UNIX,
       
  2330 +on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
       
  2331 +listed here, it may still be supported, if there's a C compiler for
       
  2332 +it. Ask around on comp.lang.python -- or just try compiling Python
       
  2333 +yourself.
       
  2334 +"""
       
  2335 +
       
  2336 +CLASSIFIERS = """
       
  2337 +Development Status :: 6 - Mature
       
  2338 +License :: OSI Approved :: Python Software Foundation License
       
  2339 +Natural Language :: English
       
  2340 +Programming Language :: C
       
  2341 +Programming Language :: Python
       
  2342 +Topic :: Software Development
       
  2343 +"""
       
  2344 +
       
  2345 +def main():
       
  2346 +    # turn off warnings when deprecated modules are imported
       
  2347 +    import warnings
       
  2348 +    warnings.filterwarnings("ignore",category=DeprecationWarning)
       
  2349 +    setup(# PyPI Metadata (PEP 301)
       
  2350 +          name = "Python",
       
  2351 +          version = sys.version.split()[0],
       
  2352 +          url = "http://www.python.org/%s" % sys.version[:3],
       
  2353 +          maintainer = "Guido van Rossum and the Python community",
       
  2354 +          maintainer_email = "[email protected]",
       
  2355 +          description = "A high-level object-oriented programming language",
       
  2356 +          long_description = SUMMARY.strip(),
       
  2357 +          license = "PSF license",
       
  2358 +          classifiers = filter(None, CLASSIFIERS.split("\n")),
       
  2359 +          platforms = ["Many"],
       
  2360 +
       
  2361 +          # Build info
       
  2362 +          cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall,
       
  2363 +                      'install_lib':PyBuildInstallLib},
       
  2364 +          # The struct module is defined here, because build_ext won't be
       
  2365 +          # called unless there's at least one extension module defined.
       
  2366 +          ext_modules=[Extension('_struct', ['_struct.c'])],
       
  2367 +
       
  2368 +          # Scripts to install
       
  2369 +          scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle',
       
  2370 +                     'Tools/scripts/2to3',
       
  2371 +                     'Lib/smtpd.py']
       
  2372 +        )
       
  2373 +
       
  2374 +# --install-platlib
       
  2375 +if __name__ == '__main__':
       
  2376 +    main()
       
  2377 
       
  2378 diff --git Python-2.6.4/Lib/test/ucredtext.py Python-2.6.4/Lib/test/ucredtext.py
       
  2379 new file mode 100644
       
  2380 --- /dev/null	2011-02-12 03:14:16.000000000 -0600
       
  2381 +++ Python-2.6.4/Lib/test/ucredtest.py	2011-01-20 13:52:42.945657919 -0600
       
  2382 @@ -0,0 +1,45 @@
       
  2383 +#!/usr/bin/python2.6
       
  2384 +
       
  2385 +import ucred
       
  2386 +import os
       
  2387 +
       
  2388 +uc = ucred.get(os.getpid())
       
  2389 +
       
  2390 +print "pid = %d" % uc.getpid()
       
  2391 +print "euid = %d" % uc.geteuid()
       
  2392 +print "ruid = %d" % uc.getruid()
       
  2393 +print "suid = %d" % uc.getsuid()
       
  2394 +print "egid = %d" % uc.getegid()
       
  2395 +print "rgid = %d" % uc.getrgid()
       
  2396 +print "sgid = %d" % uc.getsgid()
       
  2397 +print "zoneid = %d" % uc.getzoneid()
       
  2398 +print "projid = %d" % uc.getprojid()
       
  2399 +print "groups = %s" % uc.getgroups()
       
  2400 +print "label = %s" % uc.getlabel()
       
  2401 +
       
  2402 +print "getpflags(0x1) = %d" % uc.getpflags(0x1)
       
  2403 +print "getpflags(0x2) = %d" % uc.getpflags(0x2)
       
  2404 +print "has_priv(Effective, proc_fork) = %d" % uc.has_priv("Effective", "proc_fork")
       
  2405 +print "has_priv(Permitted, proc_fork) = %d" % uc.has_priv("Permitted", "proc_fork")
       
  2406 +print "has_priv(Inheritable, proc_fork) = %d" % uc.has_priv("Inheritable", "proc_fork")
       
  2407 +print "has_priv(Limit, file_setid) = %d" % uc.has_priv("Limit", "file_setid")
       
  2408 +print "has_priv(Effective, file_setid) = %d" % uc.has_priv("Effective", "file_setid")
       
  2409 +try:
       
  2410 +    uc.has_priv("Effective", "proc_bork")
       
  2411 +except OSError, e:
       
  2412 +    print e
       
  2413 +try:
       
  2414 +    uc.has_priv("Defective", "proc_fork")
       
  2415 +except OSError, e:
       
  2416 +    print e
       
  2417 +try:
       
  2418 +    uc.has_priv("Defective", "proc_bork")
       
  2419 +except OSError, e:
       
  2420 +    print e
       
  2421 +
       
  2422 +del uc
       
  2423 +uc = ucred.ucred()
       
  2424 +try:
       
  2425 +    uc.getpid()
       
  2426 +except OSError, e:
       
  2427 +    print e