
/* dl module */

#include "Python.h"

#include <dlfcn.h>

#ifdef __VMS
#include <unistd.h>
#endif

#ifndef RTLD_LAZY
#define RTLD_LAZY 1
#endif

typedef void *PyUnivPtr;
typedef struct {
	PyObject_HEAD
	PyUnivPtr *dl_handle;
} dlobject;

static PyTypeObject Dltype;

static PyObject *Dlerror;

static PyObject *
newdlobject(PyUnivPtr *handle)
{
	dlobject *xp;
	xp = PyObject_New(dlobject, &Dltype);
	if (xp == NULL)
		return NULL;
	xp->dl_handle = handle;
	return (PyObject *)xp;
}

static void
dl_dealloc(dlobject *xp)
{
	if (xp->dl_handle != NULL)
		dlclose(xp->dl_handle);
	PyObject_Del(xp);
}

static PyObject *
dl_close(dlobject *xp)
{
	if (xp->dl_handle != NULL) {
		dlclose(xp->dl_handle);
		xp->dl_handle = NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
dl_sym(dlobject *xp, PyObject *args)
{
	char *name;
	PyUnivPtr *func;
	if (PyString_Check(args)) {
		name = PyString_AS_STRING(args);
	} else {
		PyErr_Format(PyExc_TypeError, "expected string, found %.200s",
			     Py_TYPE(args)->tp_name);
		return NULL;
	}
	func = dlsym(xp->dl_handle, name);
	if (func == NULL) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	return PyInt_FromLong((long)func);
}

static PyObject *
dl_call(dlobject *xp, PyObject *args)
{
	PyObject *name;
	long (*func)(long, long, long, long, long,
                     long, long, long, long, long);
	long alist[10];
	long res;
	Py_ssize_t i;
	Py_ssize_t n = PyTuple_Size(args);
	if (n < 1) {
		PyErr_SetString(PyExc_TypeError, "at least a name is needed");
		return NULL;
	}
	name = PyTuple_GetItem(args, 0);
	if (!PyString_Check(name)) {
		PyErr_SetString(PyExc_TypeError,
				"function name must be a string");
		return NULL;
	}
	func = (long (*)(long, long, long, long, long, 
                         long, long, long, long, long)) 
          dlsym(xp->dl_handle, PyString_AsString(name));
	if (func == NULL) {
		PyErr_SetString(PyExc_ValueError, dlerror());
		return NULL;
	}
	if (n-1 > 10) {
		PyErr_SetString(PyExc_TypeError,
				"too many arguments (max 10)");
		return NULL;
	}
	for (i = 1; i < n; i++) {
		PyObject *v = PyTuple_GetItem(args, i);
		if (PyInt_Check(v))
			alist[i-1] = PyInt_AsLong(v);
		else if (PyString_Check(v))
			alist[i-1] = (long)PyString_AsString(v);
		else if (v == Py_None)
			alist[i-1] = (long) ((char *)NULL);
		else {
			PyErr_SetString(PyExc_TypeError,
				   "arguments must be int, string or None");
			return NULL;
		}
	}
	for (; i <= 10; i++)
		alist[i-1] = 0;
	res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
		      alist[5], alist[6], alist[7], alist[8], alist[9]);
	return PyInt_FromLong(res);
}

static PyMethodDef dlobject_methods[] = {
	{"call",	(PyCFunction)dl_call, METH_VARARGS},
	{"sym", 	(PyCFunction)dl_sym, METH_O},
	{"close",	(PyCFunction)dl_close, METH_NOARGS},
	{NULL,  	NULL}			 /* Sentinel */
};

static PyObject *
dl_getattr(dlobject *xp, char *name)
{
	return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
}


static PyTypeObject Dltype = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"dl.dl",		/*tp_name*/
	sizeof(dlobject),	/*tp_basicsize*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)dl_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)dl_getattr,/*tp_getattr*/
	0,			/*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
	0,			/*tp_hash*/
};

static PyObject *
dl_open(PyObject *self, PyObject *args)
{
	char *name;
	int mode;
	PyUnivPtr *handle;
	if (sizeof(int) != sizeof(long) ||
	    sizeof(long) != sizeof(char *)) {
		PyErr_SetString(PyExc_SystemError,
 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
		return NULL;
	}

	if (PyArg_ParseTuple(args, "z:open", &name))
		mode = RTLD_LAZY;
	else {
		PyErr_Clear();
		if (!PyArg_ParseTuple(args, "zi:open", &name, &mode))
			return NULL;
#ifndef RTLD_NOW
		if (mode != RTLD_LAZY) {
			PyErr_SetString(PyExc_ValueError, "mode must be 1");
			return NULL;
		}
#endif
	}
	handle = dlopen(name, mode);
	if (handle == NULL) {
		char *errmsg = dlerror();
		if (!errmsg)
			errmsg = "dlopen() error";
		PyErr_SetString(Dlerror, errmsg);
		return NULL;
	}
#ifdef __VMS
	/*   Under OpenVMS dlopen doesn't do any check, just save the name
	 * for later use, so we have to check if the file is readable,
	 * the name can be a logical or a file from SYS$SHARE.
	 */
	if (access(name, R_OK)) {
		char fname[strlen(name) + 20];
		strcpy(fname, "SYS$SHARE:");
		strcat(fname, name);
		strcat(fname, ".EXE");
		if (access(fname, R_OK)) {
			dlclose(handle);
			PyErr_SetString(Dlerror,
				"File not found or protection violation");
			return NULL;
		}
	}
#endif
	return newdlobject(handle);
}

static PyMethodDef dl_methods[] = {
	{"open",	dl_open, METH_VARARGS},
	{NULL,		NULL}		/* sentinel */
};

/* From socketmodule.c
 * Convenience routine to export an integer value.
 *
 * Errors are silently ignored, for better or for worse...
 */
static void
insint(PyObject *d, char *name, int value)
{
	PyObject *v = PyInt_FromLong((long) value);
	if (!v || PyDict_SetItemString(d, name, v))
		PyErr_Clear();

	Py_XDECREF(v);
}

PyMODINIT_FUNC
initdl(void)
{
	PyObject *m, *d, *x;

    if (PyErr_WarnPy3k("the dl module has been removed in "
                        "Python 3.0; use the ctypes module instead", 2) < 0)
        return;    

	/* Initialize object type */
	Py_TYPE(&Dltype) = &PyType_Type;

	/* Create the module and add the functions */
	m = Py_InitModule("dl", dl_methods);
	if (m == NULL)
		return;

	/* Add some symbolic constants to the module */
	d = PyModule_GetDict(m);
	Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
	PyDict_SetItemString(d, "error", x);
	x = PyInt_FromLong((long)RTLD_LAZY);
	PyDict_SetItemString(d, "RTLD_LAZY", x);
#define INSINT(X)    insint(d,#X,X)
#ifdef RTLD_NOW
        INSINT(RTLD_NOW);
#endif
#ifdef RTLD_NOLOAD
        INSINT(RTLD_NOLOAD);
#endif
#ifdef RTLD_GLOBAL
        INSINT(RTLD_GLOBAL);
#endif
#ifdef RTLD_LOCAL
        INSINT(RTLD_LOCAL);
#endif
#ifdef RTLD_PARENT
        INSINT(RTLD_PARENT);
#endif
#ifdef RTLD_GROUP
        INSINT(RTLD_GROUP);
#endif
#ifdef RTLD_WORLD
        INSINT(RTLD_WORLD);
#endif
#ifdef RTLD_NODELETE
        INSINT(RTLD_NODELETE);
#endif
}
