home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / pippy-0.6beta-src.tar.gz / pippy-0.6beta-src.tar / pippy-0.6beta-src / src / Modules / nismodule.c < prev    next >
C/C++ Source or Header  |  2000-12-21  |  8KB  |  409 lines

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