diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Modules/nismodule.c --- /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 + B&O group, + Faculteit der Informatica, + Universiteit Twente, + Enschede, + the Netherlands. +******************************************************************/ + +/* NIS module implementation */ + +#include "Python.h" + +#include +#include +#include +#include +#include + +#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); +}