home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / py2s152.zip / Modules / nismodule.c < prev    next >
C/C++ Source or Header  |  1999-06-27  |  7KB  |  379 lines

  1. /***********************************************************
  2.     Written by:
  3.     Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
  4.     Vakgroep Spa,
  5.     Faculteit der Informatica,
  6.     Universiteit Twente,
  7.     Enschede,
  8.     the Netherlands.
  9. ******************************************************************/
  10.  
  11. /* NIS module implementation */
  12.  
  13. #include "Python.h"
  14.  
  15. #include <sys/time.h>
  16. #include <sys/types.h>
  17. #include <rpc/rpc.h>
  18. #include <rpcsvc/yp_prot.h>
  19. #include <rpcsvc/ypclnt.h>
  20.  
  21. #ifdef __sgi
  22. /* This is missing from rpcsvc/ypclnt.h */
  23. extern int yp_get_default_domain();
  24. #endif
  25.  
  26. static PyObject *NisError;
  27.  
  28. static PyObject *
  29. nis_error (err)
  30.     int err;
  31. {
  32.     PyErr_SetString(NisError, yperr_string(err));
  33.     return NULL;
  34. }
  35.  
  36. static struct nis_map {
  37.     char *alias;
  38.     char *map;
  39. } aliases [] = {
  40.     {"passwd",    "passwd.byname"},
  41.     {"group",    "group.byname"},
  42.     {"networks",    "networks.byaddr"},
  43.     {"hosts",    "hosts.byname"},
  44.     {"protocols",    "protocols.bynumber"},
  45.     {"services",    "services.byname"},
  46.     {"aliases",    "mail.aliases"},
  47.     {"ethers",    "ethers.byname"},
  48.     {0L,        0L}
  49. };
  50.  
  51. static char *
  52. nis_mapname (map)
  53.     char *map;
  54. {
  55.     int i;
  56.  
  57.     for (i=0; aliases[i].alias != 0L; i++)
  58.         if (!strcmp (aliases[i].alias, map))
  59.             map = aliases[i].map;
  60.     return map;
  61. }
  62.  
  63. typedef int (*foreachfunc) Py_PROTO((int, char *, int, char *, int, char *));
  64.  
  65. static int
  66. nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
  67.     int instatus;
  68.     char *inkey;
  69.     int inkeylen;
  70.     char *inval;
  71.     int invallen;
  72.     PyObject *indata;
  73. {
  74.     if (instatus == YP_TRUE) {
  75.         PyObject *key = PyString_FromStringAndSize(inkey, inkeylen);
  76.         PyObject *val = PyString_FromStringAndSize(inval, invallen);
  77.         int err;
  78.         if (key == NULL || val == NULL) {
  79.             /* XXX error -- don't know how to handle */
  80.             PyErr_Clear();
  81.             Py_XDECREF(key);
  82.             Py_XDECREF(val);
  83.             return 1;
  84.         }
  85.         err = PyDict_SetItem(indata, key, val);
  86.         Py_DECREF(key);
  87.         Py_DECREF(val);
  88.         if (err != 0) {
  89.             PyErr_Clear();
  90.             return 1;
  91.         }
  92.         return 0;
  93.     }
  94.     return 1;
  95. }
  96.  
  97. static PyObject *
  98. nis_match (self, args)
  99.     PyObject *self;
  100.     PyObject *args;
  101. {
  102.     char *match;
  103.     char *domain;
  104.     int keylen, len;
  105.     char *key, *map;
  106.     int err;
  107.     PyObject *res;
  108.  
  109.     if (!PyArg_Parse(args, "(t#s)", &key, &keylen, &map))
  110.         return NULL;
  111.     if ((err = yp_get_default_domain(&domain)) != 0)
  112.         return nis_error(err);
  113.     Py_BEGIN_ALLOW_THREADS
  114.     map = nis_mapname (map);
  115.     err = yp_match (domain, map, key, keylen, &match, &len);
  116.     Py_END_ALLOW_THREADS
  117.     if (err != 0)
  118.         return nis_error(err);
  119.     res = PyString_FromStringAndSize (match, len);
  120.     free (match);
  121.     return res;
  122. }
  123.  
  124. static PyObject *
  125. nis_cat (self, args)
  126.     PyObject *self;
  127.     PyObject *args;
  128. {
  129.     char *domain;
  130.     char *map;
  131.     struct ypall_callback cb;
  132.     PyObject *cat;
  133.     int err;
  134.  
  135.     if (!PyArg_Parse(args, "s", &map))
  136.         return NULL;
  137.     if ((err = yp_get_default_domain(&domain)) != 0)
  138.         return nis_error(err);
  139.     cat = PyDict_New ();
  140.     if (cat == NULL)
  141.         return NULL;
  142.     cb.foreach = (foreachfunc)nis_foreach;
  143.     cb.data = (char *)cat;
  144.     Py_BEGIN_ALLOW_THREADS
  145.     map = nis_mapname (map);
  146.     err = yp_all (domain, map, &cb);
  147.     Py_END_ALLOW_THREADS
  148.     if (err != 0) {
  149.         Py_DECREF(cat);
  150.         return nis_error(err);
  151.     }
  152.     return cat;
  153. }
  154.  
  155. /* These should be u_long on Sun h/w but not on 64-bit h/w.
  156.    This is not portable to machines with 16-bit ints and no prototypes */
  157. #ifndef YPPROC_MAPLIST
  158. #define YPPROC_MAPLIST    11
  159. #endif
  160. #ifndef YPPROG
  161. #define YPPROG        100004
  162. #endif
  163. #ifndef YPVERS
  164. #define YPVERS        2
  165. #endif
  166.  
  167. typedef char *domainname;
  168. typedef char *mapname;
  169.  
  170. enum nisstat {
  171.     NIS_TRUE = 1,
  172.     NIS_NOMORE = 2,
  173.     NIS_FALSE = 0,
  174.     NIS_NOMAP = -1,
  175.     NIS_NODOM = -2,
  176.     NIS_NOKEY = -3,
  177.     NIS_BADOP = -4,
  178.     NIS_BADDB = -5,
  179.     NIS_YPERR = -6,
  180.     NIS_BADARGS = -7,
  181.     NIS_VERS = -8
  182. };
  183. typedef enum nisstat nisstat;
  184.  
  185. struct nismaplist {
  186.     mapname map;
  187.     struct nismaplist *next;
  188. };
  189. typedef struct nismaplist nismaplist;
  190.  
  191. struct nisresp_maplist {
  192.     nisstat stat;
  193.     nismaplist *maps;
  194. };
  195. typedef struct nisresp_maplist nisresp_maplist;
  196.  
  197. static struct timeval TIMEOUT = { 25, 0 };
  198.  
  199. static
  200. bool_t
  201. nis_xdr_domainname(xdrs, objp)
  202.     XDR *xdrs;
  203.     domainname *objp;
  204. {
  205.     if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
  206.         return (FALSE);
  207.     }
  208.     return (TRUE);
  209. }
  210.  
  211. static
  212. bool_t
  213. nis_xdr_mapname(xdrs, objp)
  214.     XDR *xdrs;
  215.     mapname *objp;
  216. {
  217.     if (!xdr_string(xdrs, objp, YPMAXMAP)) {
  218.         return (FALSE);
  219.     }
  220.     return (TRUE);
  221. }
  222.  
  223. static
  224. bool_t
  225. nis_xdr_ypmaplist(xdrs, objp)
  226.     XDR *xdrs;
  227.     nismaplist *objp;
  228. {
  229.     if (!nis_xdr_mapname(xdrs, &objp->map)) {
  230.         return (FALSE);
  231.     }
  232.     if (!xdr_pointer(xdrs, (char **)&objp->next,
  233.              sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
  234.     {
  235.         return (FALSE);
  236.     }
  237.     return (TRUE);
  238. }
  239.  
  240. static
  241. bool_t
  242. nis_xdr_ypstat(xdrs, objp)
  243.     XDR *xdrs;
  244.     nisstat *objp;
  245. {
  246.     if (!xdr_enum(xdrs, (enum_t *)objp)) {
  247.         return (FALSE);
  248.     }
  249.     return (TRUE);
  250. }
  251.  
  252.  
  253. static
  254. bool_t
  255. nis_xdr_ypresp_maplist(xdrs, objp)
  256.     XDR *xdrs;
  257.     nisresp_maplist *objp;
  258. {
  259.     if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
  260.         return (FALSE);
  261.     }
  262.     if (!xdr_pointer(xdrs, (char **)&objp->maps,
  263.              sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
  264.     {
  265.         return (FALSE);
  266.     }
  267.     return (TRUE);
  268. }
  269.  
  270.  
  271. static
  272. nisresp_maplist *
  273. nisproc_maplist_2(argp, clnt)
  274.     domainname *argp;
  275.     CLIENT *clnt;
  276. {
  277.     static nisresp_maplist res;
  278.  
  279.     memset(&res, 0, sizeof(res));
  280.     if (clnt_call(clnt, YPPROC_MAPLIST,
  281.               (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,
  282.               (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,
  283.               TIMEOUT) != RPC_SUCCESS)
  284.     {
  285.         return (NULL);
  286.     }
  287.     return (&res);
  288. }
  289.  
  290. static
  291. nismaplist *
  292. nis_maplist ()
  293. {
  294.     nisresp_maplist *list;
  295.     char *dom;
  296.     CLIENT *cl, *clnt_create();
  297.     char *server = NULL;
  298.     int mapi = 0;
  299.         int err;
  300.  
  301.     if ((err = yp_get_default_domain (&dom)) != 0) {
  302.         nis_error(err);
  303.         return NULL;
  304.     }
  305.  
  306.     while (!server && aliases[mapi].map != 0L) {
  307.         yp_master (dom, aliases[mapi].map, &server);
  308.         mapi++;
  309.     }
  310.         if (!server) {
  311.             PyErr_SetString(NisError, "No NIS master found for any map");
  312.             return NULL;
  313.         }
  314.     cl = clnt_create(server, YPPROG, YPVERS, "tcp");
  315.     if (cl == NULL) {
  316.         PyErr_SetString(NisError, clnt_spcreateerror(server));
  317.         goto finally;
  318.     }
  319.     list = nisproc_maplist_2 (&dom, cl);
  320.     clnt_destroy(cl);
  321.     if (list == NULL)
  322.         goto finally;
  323.     if (list->stat != NIS_TRUE)
  324.         goto finally;
  325.  
  326.     PyMem_DEL(server);
  327.     return list->maps;
  328.  
  329.   finally:
  330.     PyMem_DEL(server);
  331.     return NULL;
  332. }
  333.  
  334. static PyObject *
  335. nis_maps (self, args)
  336.     PyObject *self;
  337.     PyObject *args;
  338. {
  339.     nismaplist *maps;
  340.     PyObject *list;
  341.  
  342.         if (!PyArg_NoArgs(args))
  343.         return NULL;
  344.     if ((maps = nis_maplist ()) == NULL)
  345.         return NULL;
  346.     if ((list = PyList_New(0)) == NULL)
  347.         return NULL;
  348.     for (maps = maps->next; maps; maps = maps->next) {
  349.         PyObject *str = PyString_FromString(maps->map);
  350.         if (!str || PyList_Append(list, str) < 0)
  351.         {
  352.             Py_DECREF(list);
  353.             list = NULL;
  354.             break;
  355.         }
  356.         Py_DECREF(str);
  357.     }
  358.     /* XXX Shouldn't we free the list of maps now? */
  359.     return list;
  360. }
  361.  
  362. static PyMethodDef nis_methods[] = {
  363.     {"match",    nis_match},
  364.     {"cat",        nis_cat},
  365.     {"maps",    nis_maps},
  366.     {NULL,        NULL}         /* Sentinel */
  367. };
  368.  
  369. void
  370. initnis ()
  371. {
  372.     PyObject *m, *d;
  373.     m = Py_InitModule("nis", nis_methods);
  374.     d = PyModule_GetDict(m);
  375.     NisError = PyErr_NewException("nis.error", NULL, NULL);
  376.     if (NisError != NULL)
  377.         PyDict_SetItemString(d, "error", NisError);
  378. }
  379.