symbian-qemu-0.9.1-12/python-2.6.1/Modules/nismodule.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Modules/nismodule.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,447 @@
+/***********************************************************
+    Written by:
+	Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
+	B&O group,
+	Faculteit der Informatica,
+	Universiteit Twente,
+	Enschede,
+	the Netherlands.
+******************************************************************/
+
+/* NIS module implementation */
+
+#include "Python.h"
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+#ifdef __sgi
+/* This is missing from rpcsvc/ypclnt.h */
+extern int yp_get_default_domain(char **);
+#endif
+
+PyDoc_STRVAR(get_default_domain__doc__, 
+"get_default_domain() -> str\n\
+Corresponds to the C library yp_get_default_domain() call, returning\n\
+the default NIS domain.\n");
+
+PyDoc_STRVAR(match__doc__,
+"match(key, map, domain = defaultdomain)\n\
+Corresponds to the C library yp_match() call, returning the value of\n\
+key in the given map. Optionally domain can be specified but it\n\
+defaults to the system default domain.\n");
+
+PyDoc_STRVAR(cat__doc__,
+"cat(map, domain = defaultdomain)\n\
+Returns the entire map as a dictionary. Optionally domain can be\n\
+specified but it defaults to the system default domain.\n");
+
+PyDoc_STRVAR(maps__doc__,
+"maps(domain = defaultdomain)\n\
+Returns an array of all available NIS maps within a domain. If domain\n\
+is not specified it defaults to the system default domain.\n");
+
+static PyObject *NisError;
+
+static PyObject *
+nis_error (int err)
+{
+	PyErr_SetString(NisError, yperr_string(err));
+	return NULL;
+}
+
+static struct nis_map {
+	char *alias;
+	char *map;
+	int  fix;
+} aliases [] = {
+	{"passwd",	"passwd.byname",	0},
+	{"group",	"group.byname",		0},
+	{"networks",	"networks.byaddr",	0},
+	{"hosts",	"hosts.byname",		0},
+	{"protocols",	"protocols.bynumber",	0},
+	{"services",	"services.byname",	0},
+	{"aliases",	"mail.aliases",		1}, /* created with 'makedbm -a' */
+	{"ethers",	"ethers.byname",	0},
+	{0L,		0L,			0}
+};
+
+static char *
+nis_mapname (char *map, int *pfix)
+{
+	int i;
+
+	*pfix = 0;
+	for (i=0; aliases[i].alias != 0L; i++) {
+		if (!strcmp (aliases[i].alias, map)) {
+			*pfix = aliases[i].fix;
+			return aliases[i].map;
+		}
+		if (!strcmp (aliases[i].map, map)) {
+			*pfix = aliases[i].fix;
+			return aliases[i].map;
+		}
+	}
+
+	return map;
+}
+
+#ifdef __APPLE__
+typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *);
+#else
+typedef int (*foreachfunc)(int, char *, int, char *, int, char *);
+#endif
+
+struct ypcallback_data {
+	PyObject	*dict;
+	int			fix;
+	PyThreadState *state;
+};
+
+static int
+nis_foreach (int instatus, char *inkey, int inkeylen, char *inval,
+             int invallen, struct ypcallback_data *indata)
+{
+	if (instatus == YP_TRUE) {
+		PyObject *key;
+		PyObject *val;
+		int err;
+
+		PyEval_RestoreThread(indata->state);
+		if (indata->fix) {
+		    if (inkeylen > 0 && inkey[inkeylen-1] == '\0')
+			inkeylen--;
+		    if (invallen > 0 && inval[invallen-1] == '\0')
+			invallen--;
+		}
+		key = PyString_FromStringAndSize(inkey, inkeylen);
+		val = PyString_FromStringAndSize(inval, invallen);
+		if (key == NULL || val == NULL) {
+			/* XXX error -- don't know how to handle */
+			PyErr_Clear();
+			Py_XDECREF(key);
+			Py_XDECREF(val);
+			return 1;
+		}
+		err = PyDict_SetItem(indata->dict, key, val);
+		Py_DECREF(key);
+		Py_DECREF(val);
+		if (err != 0)
+			PyErr_Clear();
+		indata->state = PyEval_SaveThread();
+		if (err != 0)
+		  	return 1;
+		return 0;
+	}
+	return 1;
+}
+
+static PyObject *
+nis_get_default_domain (PyObject *self)
+{
+	char *domain;
+	int err;
+	PyObject *res;
+
+	if ((err = yp_get_default_domain(&domain)) != 0)
+		return nis_error(err);
+
+	res = PyString_FromStringAndSize (domain, strlen(domain));
+	return res;
+}
+
+static PyObject *
+nis_match (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	char *match;
+	char *domain = NULL;
+	int keylen, len;
+	char *key, *map;
+	int err;
+	PyObject *res;
+	int fix;
+	static char *kwlist[] = {"key", "map", "domain", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict,
+					 "t#s|s:match", kwlist,
+					 &key, &keylen, &map, &domain))
+		return NULL;
+	if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
+		return nis_error(err);
+	map = nis_mapname (map, &fix);
+	if (fix)
+	    keylen++;
+	Py_BEGIN_ALLOW_THREADS
+	err = yp_match (domain, map, key, keylen, &match, &len);
+	Py_END_ALLOW_THREADS
+	if (fix)
+	    len--;
+	if (err != 0)
+		return nis_error(err);
+	res = PyString_FromStringAndSize (match, len);
+	free (match);
+	return res;
+}
+
+static PyObject *
+nis_cat (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	char *domain = NULL;
+	char *map;
+	struct ypall_callback cb;
+	struct ypcallback_data data;
+	PyObject *dict;
+	int err;
+	static char *kwlist[] = {"map", "domain", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat",
+				         kwlist, &map, &domain))
+		return NULL;
+	if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
+		return nis_error(err);
+	dict = PyDict_New ();
+	if (dict == NULL)
+		return NULL;
+	cb.foreach = (foreachfunc)nis_foreach;
+	data.dict = dict;
+	map = nis_mapname (map, &data.fix);
+	cb.data = (char *)&data;
+	data.state = PyEval_SaveThread();
+	err = yp_all (domain, map, &cb);
+	PyEval_RestoreThread(data.state);
+	if (err != 0) {
+		Py_DECREF(dict);
+		return nis_error(err);
+	}
+	return dict;
+}
+
+/* These should be u_long on Sun h/w but not on 64-bit h/w.
+   This is not portable to machines with 16-bit ints and no prototypes */
+#ifndef YPPROC_MAPLIST
+#define YPPROC_MAPLIST	11
+#endif
+#ifndef YPPROG
+#define YPPROG		100004
+#endif
+#ifndef YPVERS
+#define YPVERS		2
+#endif
+
+typedef char *domainname;
+typedef char *mapname;
+
+enum nisstat {
+	NIS_TRUE = 1,
+	NIS_NOMORE = 2,
+	NIS_FALSE = 0,
+	NIS_NOMAP = -1,
+	NIS_NODOM = -2,
+	NIS_NOKEY = -3,
+	NIS_BADOP = -4,
+	NIS_BADDB = -5,
+	NIS_YPERR = -6,
+	NIS_BADARGS = -7,
+	NIS_VERS = -8
+};
+typedef enum nisstat nisstat;
+
+struct nismaplist {
+	mapname map;
+	struct nismaplist *next;
+};
+typedef struct nismaplist nismaplist;
+
+struct nisresp_maplist {
+	nisstat stat;
+	nismaplist *maps;
+};
+typedef struct nisresp_maplist nisresp_maplist;
+
+static struct timeval TIMEOUT = { 25, 0 };
+
+static
+bool_t
+nis_xdr_domainname(XDR *xdrs, domainname *objp)
+{
+	if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_mapname(XDR *xdrs, mapname *objp)
+{
+	if (!xdr_string(xdrs, objp, YPMAXMAP)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp)
+{
+	if (!nis_xdr_mapname(xdrs, &objp->map)) {
+		return (FALSE);
+	}
+	if (!xdr_pointer(xdrs, (char **)&objp->next,
+			 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
+	{
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_ypstat(XDR *xdrs, nisstat *objp)
+{
+	if (!xdr_enum(xdrs, (enum_t *)objp)) {
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+
+static
+bool_t
+nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp)
+{
+	if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
+		return (FALSE);
+	}
+	if (!xdr_pointer(xdrs, (char **)&objp->maps,
+			 sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
+	{
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+
+static
+nisresp_maplist *
+nisproc_maplist_2(domainname *argp, CLIENT *clnt)
+{
+	static nisresp_maplist res;
+
+	memset(&res, 0, sizeof(res));
+	if (clnt_call(clnt, YPPROC_MAPLIST,
+		      (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,
+		      (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,
+		      TIMEOUT) != RPC_SUCCESS)
+	{
+		return (NULL);
+	}
+	return (&res);
+}
+
+static
+nismaplist *
+nis_maplist (char *dom)
+{
+	nisresp_maplist *list;
+	CLIENT *cl;
+	char *server = NULL;
+	int mapi = 0;
+
+	while (!server && aliases[mapi].map != 0L) {
+		yp_master (dom, aliases[mapi].map, &server);
+		mapi++;
+	}
+        if (!server) {
+            PyErr_SetString(NisError, "No NIS master found for any map");
+            return NULL;
+        }
+	cl = clnt_create(server, YPPROG, YPVERS, "tcp");
+	if (cl == NULL) {
+		PyErr_SetString(NisError, clnt_spcreateerror(server));
+		goto finally;
+	}
+	list = nisproc_maplist_2 (&dom, cl);
+	clnt_destroy(cl);
+	if (list == NULL)
+		goto finally;
+	if (list->stat != NIS_TRUE)
+		goto finally;
+
+	free(server);
+	return list->maps;
+
+  finally:
+	free(server);
+	return NULL;
+}
+
+static PyObject *
+nis_maps (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	char *domain = NULL;
+	nismaplist *maps;
+	PyObject *list;
+        int err;
+	static char *kwlist[] = {"domain", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict,
+					 "|s:maps", kwlist, &domain))
+		return NULL;
+	if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) {
+		nis_error(err);
+		return NULL;
+	}
+
+	if ((maps = nis_maplist (domain)) == NULL)
+		return NULL;
+	if ((list = PyList_New(0)) == NULL)
+		return NULL;
+	for (maps = maps; maps; maps = maps->next) {
+		PyObject *str = PyString_FromString(maps->map);
+		if (!str || PyList_Append(list, str) < 0)
+		{
+			Py_DECREF(list);
+			list = NULL;
+			break;
+		}
+		Py_DECREF(str);
+	}
+	/* XXX Shouldn't we free the list of maps now? */
+	return list;
+}
+
+static PyMethodDef nis_methods[] = {
+	{"match",		(PyCFunction)nis_match,
+					METH_VARARGS | METH_KEYWORDS,
+					match__doc__},
+	{"cat",			(PyCFunction)nis_cat,
+					METH_VARARGS | METH_KEYWORDS,
+					cat__doc__},
+	{"maps",		(PyCFunction)nis_maps,
+					METH_VARARGS | METH_KEYWORDS,
+					maps__doc__},
+	{"get_default_domain",	(PyCFunction)nis_get_default_domain,
+ 					METH_NOARGS,
+					get_default_domain__doc__},
+	{NULL,			NULL}		 /* Sentinel */
+};
+
+PyDoc_STRVAR(nis__doc__,
+"This module contains functions for accessing NIS maps.\n");
+
+void
+initnis (void)
+{
+	PyObject *m, *d;
+	m = Py_InitModule3("nis", nis_methods, nis__doc__);
+	if (m == NULL)
+		return;
+	d = PyModule_GetDict(m);
+	NisError = PyErr_NewException("nis.error", NULL, NULL);
+	if (NisError != NULL)
+		PyDict_SetItemString(d, "error", NisError);
+}