@@ -44,12 +44,42 @@ PyDoc_STRVAR(maps__doc__,
4444Returns an array of all available NIS maps within a domain. If domain\n\
4545is not specified it defaults to the system default domain.\n" );
4646
47- static PyObject * NisError ;
47+ typedef struct {
48+ PyObject * nis_error ;
49+ } nis_state ;
50+
51+ static inline nis_state *
52+ get_nis_state (PyObject * module )
53+ {
54+ void * state = PyModule_GetState (module );
55+ assert (state != NULL );
56+ return (nis_state * )state ;
57+ }
58+
59+ static int
60+ nis_clear (PyObject * m )
61+ {
62+ Py_CLEAR (get_nis_state (m )-> nis_error );
63+ return 0 ;
64+ }
65+
66+ static int
67+ nis_traverse (PyObject * m , visitproc visit , void * arg )
68+ {
69+ Py_VISIT (get_nis_state (m )-> nis_error );
70+ return 0 ;
71+ }
72+
73+ static void
74+ nis_free (void * m )
75+ {
76+ nis_clear ((PyObject * ) m );
77+ }
4878
4979static PyObject *
50- nis_error ( int err )
80+ nis_error ( nis_state * state , int err )
5181{
52- PyErr_SetString (NisError , yperr_string (err ));
82+ PyErr_SetString (state -> nis_error , yperr_string (err ));
5383 return NULL ;
5484}
5585
@@ -70,7 +100,7 @@ static struct nis_map {
70100};
71101
72102static char *
73- nis_mapname (char * map , int * pfix )
103+ nis_mapname (char * map , int * pfix )
74104{
75105 int i ;
76106
@@ -98,7 +128,7 @@ struct ypcallback_data {
98128};
99129
100130static int
101- nis_foreach (int instatus , char * inkey , int inkeylen , char * inval ,
131+ nis_foreach (int instatus , char * inkey , int inkeylen , char * inval ,
102132 int invallen , struct ypcallback_data * indata )
103133{
104134 if (instatus == YP_TRUE ) {
@@ -137,21 +167,22 @@ nis_foreach (int instatus, char *inkey, int inkeylen, char *inval,
137167}
138168
139169static PyObject *
140- nis_get_default_domain (PyObject * self , PyObject * Py_UNUSED (ignored ))
170+ nis_get_default_domain (PyObject * module , PyObject * Py_UNUSED (ignored ))
141171{
142172 char * domain ;
143173 int err ;
144174 PyObject * res ;
145-
146- if ((err = yp_get_default_domain (& domain )) != 0 )
147- return nis_error (err );
175+ nis_state * state = get_nis_state (module );
176+ if ((err = yp_get_default_domain (& domain )) != 0 ) {
177+ return nis_error (state , err );
178+ }
148179
149180 res = PyUnicode_FromStringAndSize (domain , strlen (domain ));
150181 return res ;
151182}
152183
153184static PyObject *
154- nis_match (PyObject * self , PyObject * args , PyObject * kwdict )
185+ nis_match (PyObject * module , PyObject * args , PyObject * kwdict )
155186{
156187 char * match ;
157188 char * domain = NULL ;
@@ -165,18 +196,22 @@ nis_match (PyObject *self, PyObject *args, PyObject *kwdict)
165196
166197 if (!PyArg_ParseTupleAndKeywords (args , kwdict ,
167198 "Us|s:match" , kwlist ,
168- & ukey , & map , & domain ))
199+ & ukey , & map , & domain )) {
169200 return NULL ;
170- if ((bkey = PyUnicode_EncodeFSDefault (ukey )) == NULL )
201+ }
202+ if ((bkey = PyUnicode_EncodeFSDefault (ukey )) == NULL ) {
171203 return NULL ;
204+ }
172205 /* check for embedded null bytes */
173206 if (PyBytes_AsStringAndSize (bkey , & key , & keylen ) == -1 ) {
174207 Py_DECREF (bkey );
175208 return NULL ;
176209 }
210+
211+ nis_state * state = get_nis_state (module );
177212 if (!domain && ((err = yp_get_default_domain (& domain )) != 0 )) {
178213 Py_DECREF (bkey );
179- return nis_error (err );
214+ return nis_error (state , err );
180215 }
181216 map = nis_mapname (map , & fix );
182217 if (fix )
@@ -187,15 +222,16 @@ nis_match (PyObject *self, PyObject *args, PyObject *kwdict)
187222 Py_DECREF (bkey );
188223 if (fix )
189224 len -- ;
190- if (err != 0 )
191- return nis_error (err );
225+ if (err != 0 ) {
226+ return nis_error (state , err );
227+ }
192228 res = PyUnicode_DecodeFSDefaultAndSize (match , len );
193229 free (match );
194230 return res ;
195231}
196232
197233static PyObject *
198- nis_cat (PyObject * self , PyObject * args , PyObject * kwdict )
234+ nis_cat (PyObject * module , PyObject * args , PyObject * kwdict )
199235{
200236 char * domain = NULL ;
201237 char * map ;
@@ -206,10 +242,13 @@ nis_cat (PyObject *self, PyObject *args, PyObject *kwdict)
206242 static char * kwlist [] = {"map" , "domain" , NULL };
207243
208244 if (!PyArg_ParseTupleAndKeywords (args , kwdict , "s|s:cat" ,
209- kwlist , & map , & domain ))
245+ kwlist , & map , & domain )) {
210246 return NULL ;
211- if (!domain && ((err = yp_get_default_domain (& domain )) != 0 ))
212- return nis_error (err );
247+ }
248+ nis_state * state = get_nis_state (module );
249+ if (!domain && ((err = yp_get_default_domain (& domain )) != 0 )) {
250+ return nis_error (state , err );
251+ }
213252 dict = PyDict_New ();
214253 if (dict == NULL )
215254 return NULL ;
@@ -222,7 +261,7 @@ nis_cat (PyObject *self, PyObject *args, PyObject *kwdict)
222261 PyEval_RestoreThread (data .state );
223262 if (err != 0 ) {
224263 Py_DECREF (dict );
225- return nis_error (err );
264+ return nis_error (state , err );
226265 }
227266 return dict ;
228267}
@@ -352,7 +391,7 @@ nisproc_maplist_2(domainname *argp, CLIENT *clnt)
352391
353392static
354393nismaplist *
355- nis_maplist ( char * dom )
394+ nis_maplist ( nis_state * state , char * dom )
356395{
357396 nisresp_maplist * list ;
358397 CLIENT * cl ;
@@ -364,12 +403,12 @@ nis_maplist (char *dom)
364403 mapi ++ ;
365404 }
366405 if (!server ) {
367- PyErr_SetString (NisError , "No NIS master found for any map" );
406+ PyErr_SetString (state -> nis_error , "No NIS master found for any map" );
368407 return NULL ;
369408 }
370409 cl = clnt_create (server , YPPROG , YPVERS , "tcp" );
371410 if (cl == NULL ) {
372- PyErr_SetString (NisError , clnt_spcreateerror (server ));
411+ PyErr_SetString (state -> nis_error , clnt_spcreateerror (server ));
373412 goto finally ;
374413 }
375414 list = nisproc_maplist_2 (& dom , cl );
@@ -388,7 +427,7 @@ nis_maplist (char *dom)
388427}
389428
390429static PyObject *
391- nis_maps (PyObject * self , PyObject * args , PyObject * kwdict )
430+ nis_maps (PyObject * module , PyObject * args , PyObject * kwdict )
392431{
393432 char * domain = NULL ;
394433 nismaplist * maps ;
@@ -397,17 +436,22 @@ nis_maps (PyObject *self, PyObject *args, PyObject *kwdict)
397436 static char * kwlist [] = {"domain" , NULL };
398437
399438 if (!PyArg_ParseTupleAndKeywords (args , kwdict ,
400- "|s:maps" , kwlist , & domain ))
439+ "|s:maps" , kwlist , & domain )) {
401440 return NULL ;
441+ }
442+
443+ nis_state * state = get_nis_state (module );
402444 if (!domain && ((err = yp_get_default_domain (& domain )) != 0 )) {
403- nis_error (err );
445+ nis_error (state , err );
404446 return NULL ;
405447 }
406448
407- if ((maps = nis_maplist ( domain )) == NULL )
449+ if ((maps = nis_maplist ( state , domain )) == NULL ) {
408450 return NULL ;
409- if ((list = PyList_New (0 )) == NULL )
451+ }
452+ if ((list = PyList_New (0 )) == NULL ) {
410453 return NULL ;
454+ }
411455 for (; maps ; maps = maps -> next ) {
412456 PyObject * str = PyUnicode_FromString (maps -> map );
413457 if (!str || PyList_Append (list , str ) < 0 )
@@ -439,31 +483,45 @@ static PyMethodDef nis_methods[] = {
439483 {NULL , NULL } /* Sentinel */
440484};
441485
486+ static int
487+ nis_exec (PyObject * module )
488+ {
489+ nis_state * state = get_nis_state (module );
490+ state -> nis_error = PyErr_NewException ("nis.error" , NULL , NULL );
491+ if (state -> nis_error == NULL ) {
492+ return -1 ;
493+ }
494+
495+ Py_INCREF (state -> nis_error );
496+ if (PyModule_AddObject (module , "error" , state -> nis_error ) < 0 ) {
497+ Py_DECREF (state -> nis_error );
498+ return -1 ;
499+ }
500+ return 0 ;
501+ }
502+
503+ static PyModuleDef_Slot nis_slots [] = {
504+ {Py_mod_exec , nis_exec },
505+ {0 , NULL }
506+ };
507+
442508PyDoc_STRVAR (nis__doc__ ,
443509"This module contains functions for accessing NIS maps.\n" );
444510
445511static struct PyModuleDef nismodule = {
446512 PyModuleDef_HEAD_INIT ,
447- "nis" ,
448- nis__doc__ ,
449- -1 ,
450- nis_methods ,
451- NULL ,
452- NULL ,
453- NULL ,
454- NULL
513+ . m_name = "nis" ,
514+ . m_doc = nis__doc__ ,
515+ . m_size = sizeof ( nis_state ) ,
516+ . m_methods = nis_methods ,
517+ . m_traverse = nis_traverse ,
518+ . m_clear = nis_clear ,
519+ . m_free = nis_free ,
520+ . m_slots = nis_slots ,
455521};
456522
457523PyMODINIT_FUNC
458524PyInit_nis (void )
459525{
460- PyObject * m , * d ;
461- m = PyModule_Create (& nismodule );
462- if (m == NULL )
463- return NULL ;
464- d = PyModule_GetDict (m );
465- NisError = PyErr_NewException ("nis.error" , NULL , NULL );
466- if (NisError != NULL )
467- PyDict_SetItemString (d , "error" , NisError );
468- return m ;
526+ return PyModuleDef_Init (& nismodule );
469527}
0 commit comments