INN commit: trunk (innd/python.c nnrpd/python.c)

INN Commit Russ_Allbery at isc.org
Sun Jun 22 09:28:07 UTC 2008


    Date: Sunday, June 22, 2008 @ 02:28:06
  Author: iulius
Revision: 7888

Add more comments and prettify existing ones.
Fix a few typos.

Modified:
  trunk/innd/python.c
  trunk/nnrpd/python.c

----------------+
 innd/python.c  |   74 +++++++++----
 nnrpd/python.c |  299 ++++++++++++++++++++++++++++++-------------------------
 2 files changed, 219 insertions(+), 154 deletions(-)

Modified: innd/python.c
===================================================================
--- innd/python.c	2008-06-22 07:57:28 UTC (rev 7887)
+++ innd/python.c	2008-06-22 09:28:06 UTC (rev 7888)
@@ -1,7 +1,7 @@
 /*  $Id$
 **
-**  Embed Python in the style of innd's Tcl and Perl stuff.
-** 
+**  Embed Python in the style of innd's Perl stuff.
+**
 **  Written by G.J. Andruk <meowing at banet.net> patterned after Tcl/Perl work
 **  by Bob Heiney and Christophe Wolfhugel and a whole bunch of other people
 **  mentioned in the docs and sources for the other filters.
@@ -18,24 +18,24 @@
 #include "innd.h"
 
 
-#if defined(DO_PYTHON)
+#ifdef DO_PYTHON
 
-/* Python redefines _POSIX_C_SOURCE, so undef it to suppress warnings. */
+/*  Python redefines _POSIX_C_SOURCE, so undef it to suppress warnings. */
 #undef _POSIX_C_SOURCE
 #include "Python.h"
 
 bool		PythonFilterActive;
-char		*filterPath;	/* this gets set in art.c */
+char		*filterPath;	/* This gets set in art.c. */
 PyObject	*PYFilterObject = NULL;
 PyObject	*PYFilterModule = NULL;
 
-/* article filter bits and pieces */
+/*  Article filter bits and pieces. */
 PyObject	*PYheaders = NULL;
 PyObject	**PYheaditem;
 PyObject	**PYheadkey;
 PyObject	*PYpathkey, *PYlineskey, *PYbodykey;
 
-/* external functions */
+/*  External functions. */
 PyObject	*msgid_method = NULL;
 PyObject	*art_method = NULL;
 PyObject	*mode_method = NULL;
@@ -56,8 +56,9 @@
 }
 
 
+
 /*
-**  Front end for PYfilter()
+**  Front end for PYfilter().
 */
 const char *
 PYcontrol(char **av)
@@ -82,6 +83,7 @@
 }
 
 
+
 /*
 **  Reject articles we don't like.
 */
@@ -129,21 +131,22 @@
 	*buf = '\0';
     Py_XDECREF(result);
 
-    /* Clean up after ourselves */
+    /* Clean up after ourselves. */
     PyDict_Clear(PYheaders);
     for (i = 0; i < hdrnum; i++)
 	if (PYheaditem[i] != Py_None) {
 	    Py_DECREF(PYheaditem[i]);
         }
 
-    if (*buf != '\0') 
+    if (*buf != '\0')
 	return buf;
     return NULL;
 }
 
 
+
 /*
-**  Refuse message IDs offered thru CHECK or IHAVE that we don't like.
+**  Refuse Message-IDs offered through CHECK or IHAVE that we don't like.
 */
 char *
 PYmidfilter(char *messageID, int msglen)
@@ -162,7 +165,7 @@
 	*buf = '\0';
     Py_XDECREF(result);
 
-    if (*buf != '\0') 
+    if (*buf != '\0')
 	return buf;
     return NULL;
 }
@@ -215,6 +218,7 @@
     PyObject	*result = NULL;
     PyObject	*temp;
 
+    /* set_filter_hook method should return a pointer to innd auth object. */
     if (PyArg_ParseTuple(args, (char *) "O:set_filter_hook", &temp)) {
 	Py_XINCREF(temp);
 	Py_XDECREF(PYFilterObject);
@@ -222,6 +226,8 @@
 	Py_INCREF(Py_None);
 	result = Py_None;
     }
+
+    /* Return a pointer to innd auth method. */
     return result;
 }
 
@@ -299,7 +305,7 @@
 
 
 /*
-**  Get a newsgroup's status flag (j, m, n, x, y, =other.group)
+**  Get a newsgroup's status flag (j, m, n, x, y, =other.group).
 */
 static PyObject *
 PY_newsgroup(PyObject *self UNUSED, PyObject *args)
@@ -334,6 +340,7 @@
 }
 
 
+
 /*
 **  Return an article header to the external module as a string.  We
 **  don't use a buffer object here because that would make it harder,
@@ -366,6 +373,7 @@
 }
 
 
+
 /*
 **  Return a whole article to the external module as a string.
 */
@@ -411,10 +419,12 @@
     int		msglen;
     int		priority;
 
+    /* Get loglevel and message. */
     if (!PyArg_ParseTuple(args, (char *) "s#s#",
 			  &loglevel, &levellen, &logmsg, &msglen))
 	return NULL;
 
+    /* Assign syslog priority by abbreviated names. */
     switch (*loglevel) {
     default:		priority = LOG_NOTICE ;
     case 'd': case 'D': priority = LOG_DEBUG ;		break;
@@ -426,13 +436,16 @@
     case 'a': case 'A': priority = LOG_ALERT ;		break;
     }
 
+    /* Log the message. */
     syslog(priority, "python: %s", logmsg);
 
+    /* Return None. */
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 
+
 /*
 **  Compute a hash digest for a string.
 */
@@ -452,7 +465,7 @@
     if (lines > 0) {
 	worksize = insize;
 
-	/* chop leading whitespace */
+	/* Chop leading whitespace. */
 	for (p=instring ; worksize>0 && isspace(*p) ; p++) {
 	    if (*p == '\n')
 		lines--;
@@ -460,15 +473,15 @@
 	}
 	wpos = p;
 
-	/* and trailing */
+	/* And trailing. */
 	for (p=&wpos[worksize] ; worksize>0 && isspace(*p) ; p--) {
 	    if (*p == '\n')
 		lines--;
 	    worksize--;
 	}
 
-	/* chop last 3 lines if we have >= 5.  From above chop the
-	 * last line has no CR so we use 1 less here. */
+	/* Chop last 3 lines if we have >= 5.  From above chop the
+	 * last line which has no CR so we use 1 less here. */
 	if (lines >= 4) {
 	    for (i=0, p=wpos+worksize ; i<2 ; p--)
 		if (*p == '\n')
@@ -506,6 +519,7 @@
 }
 
 
+
 /*
 **  Make the internal INN module's functions visible to Python.  Python
 **  annoyingly doesn't use const where appropriate in its structure
@@ -529,6 +543,7 @@
 };
 
 
+
 /*
 **  This runs when innd shuts down.
 */
@@ -553,13 +568,20 @@
 PYdefonemethod(PyObject **methptr, const char *methname)
 {
     Py_XDECREF(*methptr);
+
+    /* Get a pointer to given method. */
     *methptr = PyObject_GetAttrString(PYFilterObject, (char *) methname);
+
+    /* See if such method is defined. */
     if (*methptr == NULL)
 	syslog(L_NOTICE, "python method %s not found", methname);
-    else if (PyCallable_Check(*methptr) == 0) {
+    else {
+        /* See if it is callable. */
+        if (PyCallable_Check(*methptr) == 0) {
 	syslog(L_ERROR, "python object %s found but not a function", methname);
 	Py_DECREF(*methptr);
 	*methptr = NULL;
+        }
     }
 }
 
@@ -648,20 +670,26 @@
     const ARTHEADER *hp;
     size_t hdrcount;
 
+    /* Add path for nnrpd module.  The environment variable PYTHONPATH
+     * does it; one can also append innconf->pathfilter to sys.path once
+     * Python has been initialized. */
     setenv("PYTHONPATH", innconf->pathfilter, 1);
+
+    /* Load up the interpreter ;-O */
     Py_Initialize();
 
-    /* It makes Python sad when its stdout and stderr are closed. */
+    /* It makes Python sad when its stdout or stderr are closed. */
     if ((fileno(stdout) == -1) || (fileno(stderr) == -1))
 	PyRun_SimpleString
 	    ("import sys; sys.stdout=sys.stderr=open('/dev/null', 'a')");
 
+    /* See if Python initialized OK. */
     if (!Py_IsInitialized ()) {
 	syslog(L_ERROR, "python interpreter NOT initialized");
 	return;
     }
-    syslog(L_NOTICE, "python interpreter initialized OK");
 
+    /* Build a module interface to certain INN functions. */
     Py_InitModule((char *) "INN", INNPyMethods);
 
     PYFilterModule = PyImport_ImportModule((char *) INN_PATH_PYTHON_STARTUP_M);
@@ -678,8 +706,8 @@
     }
 
     /* Grab space for these so we aren't forever recreating them.  We also
-       put the body and the line count into PYheaditem, so it needs to be
-       two elements longer than the total number of headers. */
+     * cut the body and the line count into PYheaditem, so it needs to be
+     * two elements longer than the total number of headers. */
     PYheaders = PyDict_New();
     hdrcount = ARRAY_END(ARTheaders) - ARTheaders;
     PYheaditem = xmalloc((hdrcount + 2) * sizeof(PyObject *));
@@ -691,6 +719,8 @@
     PYpathkey = PyString_InternFromString("Path");
     PYlineskey = PyString_InternFromString("__LINES__");
     PYbodykey = PyString_InternFromString("__BODY__");
+
+    syslog(L_NOTICE, "python interpreter initialized OK");
 }
 
 #endif /* defined(DO_PYTHON) */

Modified: nnrpd/python.c
===================================================================
--- nnrpd/python.c	2008-06-22 07:57:28 UTC (rev 7887)
+++ nnrpd/python.c	2008-06-22 09:28:06 UTC (rev 7888)
@@ -1,12 +1,13 @@
 /*  $Id$
 **
-**  python.c: Embed Python in the style of nnrpd's TCL and Perl stuff
-**            (authentication and authorization hooks only at this point).
-** 
+**  python.c:  Embed Python in the style of nnrpd's Perl stuff
+**             (authentication, authorization and dynamic hooks
+**             only at this point).
+**
 **  Written by Ilya Etingof <ilya at glas.net>, 1999.
 **
 **  This code bases on Python work for innd filtering done by
-**  G.J. Andruk <meowing at banet.net>. Also it borrows some ideas from
+**  G.J. Andruk <meowing at banet.net>.  Also it borrows some ideas from
 **  TCL/Perl work done by Bob Heiney and Christophe Wolfhugel.
 */
 
@@ -17,27 +18,28 @@
 #include "nnrpd.h"
 #include "inn/hashtab.h"
 
-#if defined(DO_PYTHON)
 
-/* Python redefines _POSIX_C_SOURCE, so undef it to suppress warnings. */
+#ifdef DO_PYTHON
+
+/*  Python redefines _POSIX_C_SOURCE, so undef it to suppress warnings. */
 #undef _POSIX_C_SOURCE
 #include "Python.h"
 
-/* values relate name of hook to array index */
+/*  Values relate name of hook to array index. */
 #define PYTHONauthen           1
 #define PYTHONaccess           2
 #define PYTHONdynamic          3
 
 #define PYTHONtypes_max        4
 
-/* values relate type of method to array index */
+/*  Values relate type of method to array index. */
 #define PYTHONmain             1
 #define PYTHONinit             2
 #define PYTHONclose            3
 
 #define PYTHONmethods_max      4
 
-/* key names for attributes dictionary */
+/*  Key names for attributes dictionary. */
 #define PYTHONhostname         "hostname"
 #define PYTHONipaddress        "ipaddress"
 #define PYTHONport             "port"
@@ -49,18 +51,18 @@
 #define PYTHONtype             "type"
 #define PYTHONnewsgroup        "newsgroup"
 
-/* Max number of items in dictionary to pass to auth methods */
+/*  Max number of items in dictionary to pass to auth methods. */
 #define	_PY_MAX_AUTH_ITEM	10
 
 
-/* Pointers to external Python objects */
+/*  Pointers to external Python objects. */
 PyObject	*PYAuthObject = NULL;
 
-/* Dictionary of params to pass to authentication methods */
+/*  Dictionary of params to pass to authentication methods. */
 PyObject	*PYauthinfo = NULL;
 PyObject	**PYauthitem = NULL;
 
-/* Forward declaration */
+/*  Forward declaration. */
 static PyObject *PY_set_auth_hook(PyObject *dummy, PyObject *args);
 void PY_load_python(void);
 PyObject* PY_setup(int type, int method, char *file);
@@ -69,26 +71,28 @@
 static void file_free(void *p);
 static void file_trav(void *data, void* null);
 
-bool   PythonLoaded = false;
+bool PythonLoaded = false;
 
-/* structure for storage of attributes for a module file */
+/*  Structure for storage of attributes for a module file. */
 typedef struct PyFile {
-  char          *file;  
+  char          *file;
   bool          loaded[PYTHONtypes_max];
   PyObject	*procs[PYTHONtypes_max][PYTHONmethods_max];
 } PyFile;
 
-/* hash for storing files */
+/*  Hash for storing files. */
 struct hash *files;
 
-/* for passing the dynamic module filename from perm.c */
-char*    dynamic_file;
+/*  For passing the dynamic module filename from perm.c. */
+char* dynamic_file;
 
+
+
 /*
-** Authenticate connecting host by username&password.
+**  Authenticate connecting host by username&password.
 **
-** Return NNTP reply code as returned by Python method or -1 if method
-** is not defined.
+**  Return NNTP reply code as returned by Python method or -1 if method
+**  is not defined.
 */
 int
 PY_authenticate(char* file, char *Username, char *Password, char *errorstring,
@@ -102,38 +106,38 @@
     PY_load_python();
     proc = PY_setup(PYTHONauthen, PYTHONmain, file);
 
-    /* Return if authentication method is not defined */
+    /* Return if authentication method is not defined. */
     if (proc == NULL)
         return -1;
 
-    /* Initialize PythonAuthObject with connect method specific items */
+    /* Initialize PythonAuthObject with connect method specific items. */
     authnum = 0;
 
-    /* Client hostname */
+    /* Client hostname. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.host, strlen(Client.host));
     PyDict_SetItemString(PYauthinfo, PYTHONhostname, PYauthitem[authnum++]);
 
-    /* Client IP number */
+    /* Client IP number. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.ip, strlen(Client.ip));
     PyDict_SetItemString(PYauthinfo, PYTHONipaddress, PYauthitem[authnum++]);
 
-    /* Client port number */
+    /* Client port number. */
     PYauthitem[authnum] = PyInt_FromLong(Client.port);
     PyDict_SetItemString(PYauthinfo, PYTHONport, PYauthitem[authnum++]);
 
-    /* Server interface the connection comes to */
+    /* Server interface the connection comes to. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.serverhost, strlen(Client.serverhost));
     PyDict_SetItemString(PYauthinfo, PYTHONinterface, PYauthitem[authnum++]);
 
-    /* Server IP number */
+    /* Server IP number. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.serverip, strlen(Client.serverip));
     PyDict_SetItemString(PYauthinfo, PYTHONintipaddr, PYauthitem[authnum++]);
 
-    /* Server port number */
+    /* Server port number. */
     PYauthitem[authnum] = PyInt_FromLong(Client.serverport);
     PyDict_SetItemString(PYauthinfo, PYTHONintport, PYauthitem[authnum++]);
 
-    /* Username if known */
+    /* Username if known. */
     if (Username == NULL) {
         PYauthitem[authnum] = Py_None;
     } else {
@@ -141,7 +145,7 @@
     }
     PyDict_SetItemString(PYauthinfo, PYTHONuser, PYauthitem[authnum++]);
 
-    /* Password if known */
+    /* Password if known. */
     if (Password == NULL) {
         PYauthitem[authnum] = Py_None;
     } else {
@@ -149,11 +153,13 @@
     }
     PyDict_SetItemString(PYauthinfo, PYTHONpass, PYauthitem[authnum++]);
 
-    /* Now invoke authenticate method and see if it likes this user */
+    /*
+    ** Now invoke authenticate method and see if it likes this user.
+    **/
     result = PyObject_CallFunction(proc, (char *) "O", PYauthinfo);
 
-    /* Check the response */
-    if (result == NULL || !PyTuple_Check(result) 
+    /* Check the response. */
+    if (result == NULL || !PyTuple_Check(result)
         || ((PyTuple_Size(result) != 2) && (PyTuple_Size(result) != 3)))
     {
         syslog(L_ERROR, "python authenticate method returned wrong result");
@@ -161,10 +167,10 @@
 	ExitWithStats(1, true);
     }
 
-    /* Get the NNTP response code */
+    /* Get the NNTP response code. */
     item = PyTuple_GetItem(result, 0);
 
-    /* Check the item */
+    /* Check the item. */
     if (!PyInt_Check(item))
     {
         syslog(L_ERROR, "python authenticate method returned bad NNTP response code");
@@ -172,13 +178,13 @@
 	ExitWithStats(1, true);
     }
 
-    /* Store the code */
+    /* Store the code. */
     code = PyInt_AS_LONG(item);
 
-    /* Get the error string */
+    /* Get the error string. */
     item = PyTuple_GetItem(result, 1);
 
-    /* Check the item */
+    /* Check the item. */
     if (!PyString_Check(item))
     {
         syslog(L_ERROR, "python authenticate method returned bad error string");
@@ -186,47 +192,51 @@
 	ExitWithStats(1, true);
     }
 
-    /* Store error string */
+    /* Store error string. */
     temp = PyString_AS_STRING(item);
     strlcpy(errorstring, temp, BIG_BUFFER);
     
     if (PyTuple_Size(result) == 3) {
         
-        /* Get the username string */
+        /* Get the username string. */
         item = PyTuple_GetItem(result, 2);
         
-        /* Check the item */
+        /* Check the item. */
         if (!PyString_Check(item)) {
             syslog(L_ERROR, "python authenticate method returned bad username string");
             Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ERR_ACCESS);
             ExitWithStats(1, true);
         }
 
-        /* Store user string */
+        /* Store user string. */
         temp = PyString_AS_STRING(item);
         strlcpy(newUser, temp, BIG_BUFFER);
     }
 
-    /* Clean up the dictionary object */
+    /* Clean up the dictionary object. */
     PyDict_Clear(PYauthinfo);
 
-    /* Clean up dictionary items */
+    /* Clean up dictionary items. */
     for (i = 0; i < authnum; i++) {
         if (PYauthitem[i] != Py_None) {
             Py_DECREF(PYauthitem[i]);
         }
     }
 
-    /* Log auth result */
+    /* Log auth result. */
     syslog(L_NOTICE, "python authenticate method succeeded, return code %d, error string %s", code, errorstring);
 
-    /* Return response code */
+    /* Return response code. */
     return code;
 }
 
+
+
 /*
-** Create an access group based on the values returned by the script in file
+**  Create an access group based on the values returned by the script in file.
 **
+**  The access_vec vector is set.
+**  If the access group cannot be generated, the connection is closed.
 */
 void
 PY_access(char* file, struct vector *access_vec, char *Username)
@@ -239,64 +249,64 @@
     PY_load_python();
     proc = PY_setup(PYTHONaccess, PYTHONmain, file);
 
-    /* Exit if access method is not defined */
+    /* Exit if access method is not defined. */
     if (proc == NULL) {
         syslog(L_ERROR, "python access method not defined");
  	Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ERR_ACCESS);
  	ExitWithStats(1, true);
      }
  
-    /* Initialize PythonAuthObject with group method specific items */
+    /* Initialize PythonAuthObject with group method specific items. */
     authnum = 0;
 
-    /* Client hostname */
+    /* Client hostname. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.host, strlen(Client.host));
     PyDict_SetItemString(PYauthinfo, PYTHONhostname, PYauthitem[authnum++]);
 
-    /* Client IP number */
+    /* Client IP number. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.ip, strlen(Client.ip));
     PyDict_SetItemString(PYauthinfo, PYTHONipaddress, PYauthitem[authnum++]);
 
-    /* Client port number */
+    /* Client port number. */
     PYauthitem[authnum] = PyInt_FromLong(Client.port);
     PyDict_SetItemString(PYauthinfo, PYTHONport, PYauthitem[authnum++]);
 
-    /* Server interface the connection comes to */
+    /* Server interface the connection comes to. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.serverhost, strlen(Client.serverhost));
     PyDict_SetItemString(PYauthinfo, PYTHONinterface, PYauthitem[authnum++]);
 
-    /* Server IP number */
+    /* Server IP number. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.serverip, strlen(Client.serverip));
     PyDict_SetItemString(PYauthinfo, PYTHONintipaddr, PYauthitem[authnum++]);
 
-    /* Server port number */
+    /* Server port number. */
     PYauthitem[authnum] = PyInt_FromLong(Client.serverport);
     PyDict_SetItemString(PYauthinfo, PYTHONintport, PYauthitem[authnum++]);
 
-    /* Username */
+    /* Username. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Username, strlen(Username));
     PyDict_SetItemString(PYauthinfo, PYTHONuser, PYauthitem[authnum++]);
  
-    /* Password is not known */
+    /* Password is not known. */
     PYauthitem[authnum] = Py_None;
     PyDict_SetItemString(PYauthinfo, PYTHONpass, PYauthitem[authnum++]);
 
     /*
-     * Now invoke newsgroup access method
-     */
+    ** Now invoke newsgroup access method.
+    **/
     result = PyObject_CallFunction(proc, (char *) "O", PYauthinfo);
 
-    /* Check the response */
+    /* Check the response. */
     if (result == NULL || result == Py_None || !PyDict_Check(result)) {
-        syslog(L_ERROR, "python access method returned wrong result - expected a dictionary");
+        syslog(L_ERROR, "python access method returned wrong result -- expected a dictionary");
 	Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ERR_ACCESS);
 	ExitWithStats(1, true);
      }
  
-    /* resize vector to dictionary length */
+    /* Resize vector to dictionary length. */
     vector_resize(access_vec, PyDict_Size(result) - 1);
 
-    /* store dict values in proper format in access vector */
+    /* Store dict values in proper format in access vector. */
     i = 0;
     buffer = xmalloc(BIG_BUFFER);
 
@@ -321,22 +331,25 @@
     }
 
     free(buffer);
- 
-    /* Clean up the dictionary object */
+
+    /* Clean up the dictionary object. */
     PyDict_Clear(PYauthinfo);
-    /* Clean up dictionary items */
+
+    /* Clean up dictionary items. */
     for (i = 0; i < authnum; i++) {
         if (PYauthitem[i] != Py_None) {
             Py_DECREF(PYauthitem[i]);
 	}
     }
 
-    /* Log auth result */
+    /* Log auth result. */
     syslog(L_NOTICE, "python access method succeeded");
 }
 
+
+
 /*
-** Initialize dynamic access control code
+**  Initialize dynamic access control code.
 */
 
 void
@@ -347,12 +360,13 @@
 }
 
 
+
 /*
-** Determine dynamic user access rights to a given newsgroup.
+**  Determine dynamic user access rights to a given newsgroup.
 **
-** Return 0 if requested privelege is granted or positive value
-** and a reply_message pointer initialized with reply message.
-** Return negative value if dynamic method is not defined.
+**  Return 0 if the requested privilege is granted or a positive value
+**  and a reply_message pointer initialized with reply message.
+**  Return negative value if dynamic method is not defined.
 */
 int
 PY_dynamic(char *Username, char *NewsGroup, int PostFlag, char **reply_message)
@@ -365,97 +379,99 @@
     PY_load_python();
     proc = PY_setup(PYTHONdynamic, PYTHONmain, dynamic_file);
 
-    /* Return if dynamic method is not defined */
+    /* Return if dynamic method is not defined. */
     if (proc == NULL)
         return -1;
 
-    /* Initialize PythonAuthObject with group method specific items */
+    /* Initialize PythonAuthObject with group method specific items. */
     authnum = 0;
 
-    /* Client hostname */
+    /* Client hostname. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.host, strlen(Client.host));
     PyDict_SetItemString(PYauthinfo, PYTHONhostname, PYauthitem[authnum++]);
 
-    /* Client IP number */
+    /* Client IP number. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.ip, strlen(Client.ip));
     PyDict_SetItemString(PYauthinfo, PYTHONipaddress, PYauthitem[authnum++]);
 
-    /* Client port number */
+    /* Client port number. */
     PYauthitem[authnum] = PyInt_FromLong(Client.port);
     PyDict_SetItemString(PYauthinfo, PYTHONport, PYauthitem[authnum++]);
 
-    /* Server interface the connection comes to */
+    /* Server interface the connection comes to. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.serverhost, strlen(Client.serverhost));
     PyDict_SetItemString(PYauthinfo, PYTHONinterface, PYauthitem[authnum++]);
 
-    /* Server IP number */
+    /* Server IP number. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Client.serverip, strlen(Client.serverip));
     PyDict_SetItemString(PYauthinfo, PYTHONintipaddr, PYauthitem[authnum++]);
 
-    /* Server port number */
+    /* Server port number. */
     PYauthitem[authnum] = PyInt_FromLong(Client.serverport);
     PyDict_SetItemString(PYauthinfo, PYTHONintport, PYauthitem[authnum++]);
     
-    /* Username */
+    /* Username. */
     PYauthitem[authnum] = PyBuffer_FromMemory(Username, strlen(Username));
     PyDict_SetItemString(PYauthinfo, PYTHONuser, PYauthitem[authnum++]);
     
-    /* Password is not known */
+    /* Password is not known. */
     PYauthitem[authnum] = Py_None;
     PyDict_SetItemString(PYauthinfo, PYTHONpass, PYauthitem[authnum++]);
 
-    /* Assign authentication type */
+    /* Assign authentication type. */
     PYauthitem[authnum] =
         PyBuffer_FromMemory((char *)(PostFlag ? "post" : "read"), 4);
     PyDict_SetItemString(PYauthinfo, PYTHONtype, PYauthitem[authnum++]);
  
-    /* Newsgroup user tries to access */
+    /* Newsgroup user tries to access. */
     PYauthitem[authnum] = PyBuffer_FromMemory(NewsGroup, strlen(NewsGroup));
     PyDict_SetItemString(PYauthinfo, PYTHONnewsgroup,  PYauthitem[authnum++]);
     
     /*
-     * Now invoke newsgroup dynamic access method and see if
-     * it likes this user to access this newsgroup.
-     */
+    ** Now invoke newsgroup dynamic access method and see if
+    ** it likes this user to access this newsgroup.
+    **/
     result = PyObject_CallFunction(proc, (char *) "O", PYauthinfo);
 
-    /* Check the response */
+    /* Check the response. */
     if (result == NULL || (result != Py_None && !PyString_Check(result)))
     {
-        syslog(L_ERROR, "python dyanmic method (%s access) returned wrong result", PostFlag ? "post" : "read");
+        syslog(L_ERROR, "python dynamic method (%s access) returned wrong result", PostFlag ? "post" : "read");
 	Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ERR_ACCESS);
 	ExitWithStats(1, false);
     }
 
-    /* Get the response string */
+    /* Get the response string. */
     if (result == Py_None) {
         string = NULL;
     } else {
         temp = PyString_AS_STRING(result);
         string = xstrdup(temp);
     }
-    /* Clean up the dictionary object */
+
+    /* Clean up the dictionary object. */
     PyDict_Clear(PYauthinfo);
 
-    /* Clean up dictionary items */
+    /* Clean up dictionary items. */
     for (i = 0; i < authnum; i++) {
         if (PYauthitem[i] != Py_None) {
             Py_DECREF(PYauthitem[i]);
         }
     }
 
-    /* Log auth result */
+    /* Log auth result. */
     syslog(L_NOTICE, "python dynamic method (%s access) succeeded, refusion string: %s", PostFlag ? "post" : "read", string == NULL ? "<empty>" : string);
 
-    /* Initialize reply string */
+    /* Initialize reply string. */
     if (reply_message != NULL)
         *reply_message = string;
     
-    /* Return result */
+    /* Return result. */
     return string == NULL ? 0 : 1;
 }
 
 
+
 /*
 **  This runs when nnrpd shuts down.  If Python is closed and reopened
 **  in the same process, files and dynamic_file are reused so they
@@ -475,15 +491,17 @@
     }
 }
 
+
+
 /*
-** Traversal function for PY_close_python
+**  Traversal function for PY_close_python.
 */
 void
 file_trav(void *data, void* null UNUSED)
 {
     PyFile *fp = data;
     int j;
-    PyObject	*result, *func;
+    PyObject *result, *func;
 
     for (j = 1; j < PYTHONtypes_max; j++) {
         if (fp->loaded[j] != false) {
@@ -496,6 +514,8 @@
     }
 }
 
+
+
 /*
 **  Python's syslog module isn't compiled in by default.  It's easier
 **  to do it this way, and the switch block looks pretty in a color
@@ -510,12 +530,12 @@
     int         msglen;
     int         priority;
 
-    /* Get loglevel and message */
+    /* Get loglevel and message. */
     if (!PyArg_ParseTuple(args, (char *) "s#s#", &loglevel, &levellen,
                           &logmsg, &msglen))
         return NULL;
 
-    /* Assign syslog priority by abbreviated names */
+    /* Assign syslog priority by abbreviated names. */
     switch (*loglevel) {
     default:		priority = LOG_NOTICE ;
     case 'd': case 'D': priority = LOG_DEBUG ;		break;
@@ -527,15 +547,16 @@
     case 'a': case 'A': priority = LOG_ALERT ;		break;
     }
 
-    /* Log the message */
+    /* Log the message. */
     syslog(priority, "python: %s", logmsg);
 
-    /* Return None */
+    /* Return None. */
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 
+
 /*
 **  Make the internal nnrpd module's functions visible to Python.  Python
 **  annoyingly doesn't use const where appropriate in its structure
@@ -552,6 +573,7 @@
 };
 
 
+
 /*
 **  Called by the external module so it can register itself with nnrpd.
 */
@@ -561,7 +583,7 @@
     PyObject    *result = NULL;
     PyObject    *temp;
 
-    /* set_auth_hook method should return a pointer to nnrpd auth object */
+    /* Set_auth_hook method should return a pointer to nnrpd auth object. */
     if (PyArg_ParseTuple(args, (char *) "O:set_auth_hook", &temp)) {
         Py_XINCREF(temp);
         Py_XDECREF(PYAuthObject);
@@ -570,46 +592,49 @@
         result = Py_None;
     }
 
-    /* Return a pointer to nnrpd auth method */
+    /* Return a pointer to nnrpd auth method. */
     return result;
 }
 
+
+
 /*
-** Load the Python interpreter
+**  Load the Python interpreter.
 */
 void
 PY_load_python(void)
 {
     if (!PythonLoaded) {
-        /* add path for nnrpd module */    
+        /* Add path for nnrpd module.  The environment variable PYTHONPATH
+        ** does it; one can also append innconf->pathfilter to sys.path once
+        ** Python has been initialized.
+        **/
         setenv("PYTHONPATH", innconf->pathfilter, 1);
 
         /* Load up the interpreter ;-O */
         Py_Initialize();
     
-        /* It makes Python sad when its stdout and stderr are closed. */
-        if (feof(stdout) || feof(stderr))
+        /* It makes Python sad when its stdout or stderr are closed. */
+        if ((fileno(stdout) == -1) || (fileno(stderr) == -1))
             PyRun_SimpleString("import sys; sys.stdout=sys.stderr=open('/dev/null', 'a')");
    
-        /* See if Python initialized OK */
-        if (!Py_IsInitialized ()) {
+        /* See if Python initialized OK. */
+        if (!Py_IsInitialized()) {
             syslog(L_ERROR, "python interpreter NOT initialized");
             return;
         }
 
-
-        /* Build a module interface to certain nnrpd functions */
+        /* Build a module interface to certain nnrpd functions. */
         Py_InitModule((char *) "nnrpd", nnrpdPyMethods);
 
         /*
         ** Grab space for authinfo dictionary so we aren't forever
         ** recreating them.
-        */
+        **/
         PYauthinfo = PyDict_New();
         PYauthitem = xcalloc(_PY_MAX_AUTH_ITEM, sizeof(PyObject *));
 
-        /* create hash to store file attributes */
-        
+        /* Create hash to store file attributes. */
         files = hash_create(4, hash_string, file_key,
                             file_equal, file_free);
 
@@ -619,6 +644,8 @@
     }
 }
 
+
+
 /*
 **  Check that a method exists and is callable.	 Set up a pointer to
 **  the corresponding PyObject, or NULL if not found.
@@ -630,14 +657,14 @@
 
     methptr = &fp->procs[type][method];
 
-    /* Get a pointer to given method */
+    /* Get a pointer to given method. */
     *methptr = PyObject_GetAttrString(PYAuthObject, (char *) methname);
 
-    /* See if such method is defined */
+    /* See if such method is defined. */
     if (*methptr == NULL)
         syslog(L_NOTICE, "python method %s not found", methname);
     else {
-        /* See if it is callable */
+        /* See if it is callable. */
         if (PyCallable_Check(*methptr) == 0) {
 	    syslog(L_ERROR, "python object %s found but not a function", methname);
 	    Py_DECREF(*methptr);
@@ -647,6 +674,7 @@
 }
 
 
+
 /*
 **  Look up all the known python methods and set up
 **  pointers to them so that we could call them from nnrpd.
@@ -654,35 +682,36 @@
 static void
 PYdefmethods(PyFile *fp)
 {
-    /* Get a reference to authenticate() method */
+    /* Get a reference to authenticate() method. */
     PYdefonemethod(fp, PYTHONauthen, PYTHONmain, "authenticate");
 
-    /* Get a reference to authen_init() method */
+    /* Get a reference to authen_init() method. */
     PYdefonemethod(fp, PYTHONauthen, PYTHONinit, "authen_init");
     
-    /* Get a reference to authen_close() method */
+    /* Get a reference to authen_close() method. */
     PYdefonemethod(fp, PYTHONauthen, PYTHONclose, "authen_close");
 
-    /* Get a reference to access() method */
+    /* Get a reference to access() method. */
     PYdefonemethod(fp, PYTHONaccess, PYTHONmain, "access");
     
-    /* Get a reference to access_init() method */
+    /* Get a reference to access_init() method. */
     PYdefonemethod(fp, PYTHONaccess, PYTHONinit, "access_init");
     
-    /* Get a reference to access_close() method */
+    /* Get a reference to access_close() method. */
     PYdefonemethod(fp, PYTHONaccess, PYTHONclose, "access_close");
     
-    /* Get a reference to dynamic() method */
+    /* Get a reference to dynamic() method. */
     PYdefonemethod(fp, PYTHONdynamic, PYTHONmain, "dynamic");
     
-    /* Get a reference to dynamic_init() method */
+    /* Get a reference to dynamic_init() method. */
     PYdefonemethod(fp, PYTHONdynamic, PYTHONinit, "dynamic_init");
     
-    /* Get a reference to dynamic_close() method */
+    /* Get a reference to dynamic_close() method. */
     PYdefonemethod(fp, PYTHONdynamic, PYTHONclose, "dynamic_close");
 }
 
 
+
 /*
 **  Called when a python hook is needed -- this gets the scripts hooked in.
 */
@@ -693,7 +722,7 @@
     PyFile *fp;
     PyObject    *result;
 
-    /* check to see if this file is in files */
+    /* Check to see if this file is in files. */
     if (!(hash_lookup(files, file))) {
         fp = xmalloc(sizeof(PyFile));
         fp->file = xstrdup(file);
@@ -702,17 +731,17 @@
             fp->loaded[i] = false;
         }
         
-        /* Load up external module */
+        /* Load up external module. */
         (void) PyImport_ImportModule(file);
 
-        /* See if nnrpd auth object is defined in auth module */
+        /* See if nnrpd auth object is defined in auth module. */
         if (PYAuthObject == NULL) {
             syslog(L_ERROR, "python auth object is not defined");
             Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ERR_ACCESS);
             PY_close_python();
             ExitWithStats(1, false);
         } else {
-            /* Set up pointers to known Python methods */
+            /* Set up pointers to known Python methods. */
             PYdefmethods(fp);
         }
         hash_insert(files, file, fp);
@@ -729,6 +758,8 @@
     return NULL;
 }
 
+
+
 /*
 **  Return the key (filename) from a file struct, used by the hash table.
 */
@@ -740,6 +771,8 @@
     return f->file;
 }
 
+
+
 /*
 **  Check to see if a provided key matches the key of a PyFile struct,
 **  used by the hash table.
@@ -753,6 +786,8 @@
     return strcmp(key, f->file) == 0;
 }
 
+
+
 /*
 **  Free a file, used by the hash table.
 */



More information about the inn-committers mailing list