blob: f6dadf43fac3ae1a389f8664555815b17acb05cb [file] [log] [blame]
Guido van Rossume44e3731994-07-14 13:56:50 +00001/***********************************************************
Guido van Rossumf6971e21994-08-30 12:25:20 +00002Copyright 1994 by Lance Ellinghouse,
3Cathedral City, California Republic, United States of America.
Guido van Rossume44e3731994-07-14 13:56:50 +00004
5 All Rights Reserved
6
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossume44e3731994-07-14 13:56:50 +00009provided that the above copyright notice appear in all copies and that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf6971e21994-08-30 12:25:20 +000011supporting documentation, and that the name of Lance Ellinghouse
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000012not be used in advertising or publicity pertaining to distribution
Guido van Rossumf6971e21994-08-30 12:25:20 +000013of the software without specific, written prior permission.
Guido van Rossume44e3731994-07-14 13:56:50 +000014
Guido van Rossumf6971e21994-08-30 12:25:20 +000015LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
Guido van Rossume44e3731994-07-14 13:56:50 +000016THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL,
18INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
19FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
Guido van Rossumf6971e21994-08-30 12:25:20 +000021WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Guido van Rossume44e3731994-07-14 13:56:50 +000022
23******************************************************************/
24
Guido van Rossumc1822a41995-10-11 16:15:28 +000025/******************************************************************
26
27Revision history:
28
Sean Reifscheider13daf122010-04-23 09:29:52 +0000292010/04/20 (Sean Reifschneider)
30 - Use basename(sys.argv[0]) for the default "ident".
31 - Arguments to openlog() are now keyword args and are all optional.
32 - syslog() calls openlog() if it hasn't already been called.
33
Guido van Rossumae94cf21998-05-08 21:52:55 +0000341998/04/28 (Sean Reifschneider)
35 - When facility not specified to syslog() method, use default from openlog()
36 (This is how it was claimed to work in the documentation)
37 - Potential resource leak of o_ident, now cleaned up in closelog()
38 - Minor comment accuracy fix.
39
Guido van Rossumc1822a41995-10-11 16:15:28 +00004095/06/29 (Steve Clift)
41 - Changed arg parsing to use PyArg_ParseTuple.
42 - Added PyErr_Clear() call(s) where needed.
43 - Fix core dumps if user message contains format specifiers.
Thomas Wouters7e474022000-07-16 12:04:32 +000044 - Change openlog arg defaults to match normal syslog behavior.
Guido van Rossumc1822a41995-10-11 16:15:28 +000045 - Plug memory leak in openlog().
46 - Fix setlogmask() to return previous mask value.
47
48******************************************************************/
49
Guido van Rossume44e3731994-07-14 13:56:50 +000050/* syslog module */
Guido van Rossume44e3731994-07-14 13:56:50 +000051
Guido van Rossuma597dde1995-01-10 20:56:29 +000052#include "Python.h"
Sean Reifscheider13daf122010-04-23 09:29:52 +000053#include "osdefs.h"
Guido van Rossume44e3731994-07-14 13:56:50 +000054
55#include <syslog.h>
56
Guido van Rossumae94cf21998-05-08 21:52:55 +000057/* only one instance, only one syslog, so globals should be ok */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */
Sean Reifscheider7f810cd2010-04-25 06:31:55 +000059static char S_log_open = 0;
Guido van Rossumae94cf21998-05-08 21:52:55 +000060
61
Sean Reifscheider13daf122010-04-23 09:29:52 +000062static PyObject *
63syslog_get_argv(void)
64{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 /* Figure out what to use for as the program "ident" for openlog().
66 * This swallows exceptions and continues rather than failing out,
67 * because the syslog module can still be used because openlog(3)
68 * is optional.
69 */
Sean Reifscheider13daf122010-04-23 09:29:52 +000070
Alexander Belopolskye239d232010-12-08 23:31:48 +000071 Py_ssize_t argv_len, scriptlen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 PyObject *scriptobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020073 Py_ssize_t slash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 PyObject *argv = PySys_GetObject("argv");
Sean Reifscheider13daf122010-04-23 09:29:52 +000075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 if (argv == NULL) {
77 return(NULL);
78 }
Sean Reifscheider13daf122010-04-23 09:29:52 +000079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 argv_len = PyList_Size(argv);
81 if (argv_len == -1) {
82 PyErr_Clear();
83 return(NULL);
84 }
85 if (argv_len == 0) {
86 return(NULL);
87 }
Sean Reifscheider13daf122010-04-23 09:29:52 +000088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 scriptobj = PyList_GetItem(argv, 0);
90 if (!PyUnicode_Check(scriptobj)) {
91 return(NULL);
92 }
Alexander Belopolskye239d232010-12-08 23:31:48 +000093 scriptlen = PyUnicode_GET_SIZE(scriptobj);
94 if (scriptlen == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 return(NULL);
96 }
Sean Reifscheider13daf122010-04-23 09:29:52 +000097
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020098 slash = PyUnicode_FindChar(scriptobj, SEP,
99 0, PyUnicode_GET_LENGTH(scriptobj), -1);
100 if (slash == -2)
101 return NULL;
102 if (slash != -1) {
103 return PyUnicode_Substring(scriptobj, slash,
104 PyUnicode_GET_LENGTH(scriptobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 } else {
106 Py_INCREF(scriptobj);
107 return(scriptobj);
108 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 return(NULL);
Sean Reifscheider13daf122010-04-23 09:29:52 +0000111}
112
113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114static PyObject *
Sean Reifscheider13daf122010-04-23 09:29:52 +0000115syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds)
Guido van Rossume44e3731994-07-14 13:56:50 +0000116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 long logopt = 0;
118 long facility = LOG_USER;
119 PyObject *new_S_ident_o = NULL;
120 static char *keywords[] = {"ident", "logoption", "facility", 0};
Alexander Belopolskye239d232010-12-08 23:31:48 +0000121 char *ident = NULL;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (!PyArg_ParseTupleAndKeywords(args, kwds,
124 "|Ull:openlog", keywords, &new_S_ident_o, &logopt, &facility))
125 return NULL;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 if (new_S_ident_o) {
128 Py_INCREF(new_S_ident_o);
Alexander Belopolskye239d232010-12-08 23:31:48 +0000129 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 /* get sys.argv[0] or NULL if we can't for some reason */
132 if (!new_S_ident_o) {
133 new_S_ident_o = syslog_get_argv();
Alexander Belopolskye239d232010-12-08 23:31:48 +0000134 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 Py_XDECREF(S_ident_o);
137 S_ident_o = new_S_ident_o;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not
140 * make a copy, and syslog(3) later uses it. We can't garbagecollect it
141 * If NULL, just let openlog figure it out (probably using C argv[0]).
142 */
Alexander Belopolskye239d232010-12-08 23:31:48 +0000143 if (S_ident_o) {
144 ident = _PyUnicode_AsString(S_ident_o);
145 if (ident == NULL)
146 return NULL;
147 }
Barry Warsaw43a476a1997-01-09 23:51:21 +0000148
Alexander Belopolskye239d232010-12-08 23:31:48 +0000149 openlog(ident, logopt, facility);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 S_log_open = 1;
151
152 Py_INCREF(Py_None);
153 return Py_None;
Guido van Rossume44e3731994-07-14 13:56:50 +0000154}
155
Barry Warsaw43a476a1997-01-09 23:51:21 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000158syslog_syslog(PyObject * self, PyObject * args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 PyObject *message_object;
161 const char *message;
162 int priority = LOG_INFO;
Guido van Rossume44e3731994-07-14 13:56:50 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 if (!PyArg_ParseTuple(args, "iU;[priority,] message string",
165 &priority, &message_object)) {
166 PyErr_Clear();
167 if (!PyArg_ParseTuple(args, "U;[priority,] message string",
168 &message_object))
169 return NULL;
170 }
Guido van Rossumae94cf21998-05-08 21:52:55 +0000171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 message = _PyUnicode_AsString(message_object);
173 if (message == NULL)
174 return NULL;
Sean Reifscheider13daf122010-04-23 09:29:52 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 /* if log is not opened, open it now */
177 if (!S_log_open) {
178 PyObject *openargs;
Sean Reifscheider13daf122010-04-23 09:29:52 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 /* Continue even if PyTuple_New fails, because openlog(3) is optional.
181 * So, we can still do loggin in the unlikely event things are so hosed
182 * that we can't do this tuple.
183 */
184 if ((openargs = PyTuple_New(0))) {
185 PyObject *openlog_ret = syslog_openlog(self, openargs, NULL);
186 Py_XDECREF(openlog_ret);
187 Py_DECREF(openargs);
188 }
189 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 Py_BEGIN_ALLOW_THREADS;
192 syslog(priority, "%s", message);
193 Py_END_ALLOW_THREADS;
194 Py_RETURN_NONE;
Guido van Rossume44e3731994-07-14 13:56:50 +0000195}
196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000198syslog_closelog(PyObject *self, PyObject *unused)
Guido van Rossume44e3731994-07-14 13:56:50 +0000199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 if (S_log_open) {
201 closelog();
202 Py_XDECREF(S_ident_o);
203 S_ident_o = NULL;
204 S_log_open = 0;
205 }
206 Py_INCREF(Py_None);
207 return Py_None;
Guido van Rossume44e3731994-07-14 13:56:50 +0000208}
209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000211syslog_setlogmask(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 long maskpri, omaskpri;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri))
216 return NULL;
217 omaskpri = setlogmask(maskpri);
218 return PyLong_FromLong(omaskpri);
Guido van Rossume44e3731994-07-14 13:56:50 +0000219}
220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000222syslog_log_mask(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 long mask;
225 long pri;
226 if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri))
227 return NULL;
228 mask = LOG_MASK(pri);
229 return PyLong_FromLong(mask);
Guido van Rossume44e3731994-07-14 13:56:50 +0000230}
231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000233syslog_log_upto(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 long mask;
236 long pri;
237 if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri))
238 return NULL;
239 mask = LOG_UPTO(pri);
240 return PyLong_FromLong(mask);
Guido van Rossume44e3731994-07-14 13:56:50 +0000241}
242
243/* List of functions defined in the module */
244
Guido van Rossumf6971e21994-08-30 12:25:20 +0000245static PyMethodDef syslog_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 {"openlog", (PyCFunction) syslog_openlog, METH_VARARGS | METH_KEYWORDS},
247 {"closelog", syslog_closelog, METH_NOARGS},
248 {"syslog", syslog_syslog, METH_VARARGS},
249 {"setlogmask", syslog_setlogmask, METH_VARARGS},
250 {"LOG_MASK", syslog_log_mask, METH_VARARGS},
251 {"LOG_UPTO", syslog_log_upto, METH_VARARGS},
252 {NULL, NULL, 0}
Guido van Rossume44e3731994-07-14 13:56:50 +0000253};
254
Guido van Rossumae94cf21998-05-08 21:52:55 +0000255/* Initialization function for the module */
Guido van Rossumc1822a41995-10-11 16:15:28 +0000256
Martin v. Löwis1a214512008-06-11 05:26:20 +0000257
258static struct PyModuleDef syslogmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 PyModuleDef_HEAD_INIT,
260 "syslog",
261 NULL,
262 -1,
263 syslog_methods,
264 NULL,
265 NULL,
266 NULL,
267 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000268};
269
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000270PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000271PyInit_syslog(void)
Guido van Rossume44e3731994-07-14 13:56:50 +0000272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 PyObject *m;
Guido van Rossume44e3731994-07-14 13:56:50 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 /* Create the module and add the functions */
276 m = PyModule_Create(&syslogmodule);
277 if (m == NULL)
278 return NULL;
Guido van Rossume44e3731994-07-14 13:56:50 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 /* Add some symbolic constants to the module */
Guido van Rossumc1822a41995-10-11 16:15:28 +0000281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 /* Priorities */
283 PyModule_AddIntConstant(m, "LOG_EMERG", LOG_EMERG);
284 PyModule_AddIntConstant(m, "LOG_ALERT", LOG_ALERT);
285 PyModule_AddIntConstant(m, "LOG_CRIT", LOG_CRIT);
286 PyModule_AddIntConstant(m, "LOG_ERR", LOG_ERR);
287 PyModule_AddIntConstant(m, "LOG_WARNING", LOG_WARNING);
288 PyModule_AddIntConstant(m, "LOG_NOTICE", LOG_NOTICE);
289 PyModule_AddIntConstant(m, "LOG_INFO", LOG_INFO);
290 PyModule_AddIntConstant(m, "LOG_DEBUG", LOG_DEBUG);
Guido van Rossumc1822a41995-10-11 16:15:28 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 /* openlog() option flags */
293 PyModule_AddIntConstant(m, "LOG_PID", LOG_PID);
294 PyModule_AddIntConstant(m, "LOG_CONS", LOG_CONS);
295 PyModule_AddIntConstant(m, "LOG_NDELAY", LOG_NDELAY);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000296#ifdef LOG_NOWAIT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 PyModule_AddIntConstant(m, "LOG_NOWAIT", LOG_NOWAIT);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000298#endif
Guido van Rossumc1822a41995-10-11 16:15:28 +0000299#ifdef LOG_PERROR
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 PyModule_AddIntConstant(m, "LOG_PERROR", LOG_PERROR);
Guido van Rossumc1822a41995-10-11 16:15:28 +0000301#endif
302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 /* Facilities */
304 PyModule_AddIntConstant(m, "LOG_KERN", LOG_KERN);
305 PyModule_AddIntConstant(m, "LOG_USER", LOG_USER);
306 PyModule_AddIntConstant(m, "LOG_MAIL", LOG_MAIL);
307 PyModule_AddIntConstant(m, "LOG_DAEMON", LOG_DAEMON);
308 PyModule_AddIntConstant(m, "LOG_AUTH", LOG_AUTH);
309 PyModule_AddIntConstant(m, "LOG_LPR", LOG_LPR);
310 PyModule_AddIntConstant(m, "LOG_LOCAL0", LOG_LOCAL0);
311 PyModule_AddIntConstant(m, "LOG_LOCAL1", LOG_LOCAL1);
312 PyModule_AddIntConstant(m, "LOG_LOCAL2", LOG_LOCAL2);
313 PyModule_AddIntConstant(m, "LOG_LOCAL3", LOG_LOCAL3);
314 PyModule_AddIntConstant(m, "LOG_LOCAL4", LOG_LOCAL4);
315 PyModule_AddIntConstant(m, "LOG_LOCAL5", LOG_LOCAL5);
316 PyModule_AddIntConstant(m, "LOG_LOCAL6", LOG_LOCAL6);
317 PyModule_AddIntConstant(m, "LOG_LOCAL7", LOG_LOCAL7);
Guido van Rossume44e3731994-07-14 13:56:50 +0000318
Guido van Rossumae94cf21998-05-08 21:52:55 +0000319#ifndef LOG_SYSLOG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320#define LOG_SYSLOG LOG_DAEMON
Guido van Rossumae94cf21998-05-08 21:52:55 +0000321#endif
322#ifndef LOG_NEWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323#define LOG_NEWS LOG_MAIL
Guido van Rossumae94cf21998-05-08 21:52:55 +0000324#endif
325#ifndef LOG_UUCP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326#define LOG_UUCP LOG_MAIL
Guido van Rossumae94cf21998-05-08 21:52:55 +0000327#endif
328#ifndef LOG_CRON
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329#define LOG_CRON LOG_DAEMON
Guido van Rossumae94cf21998-05-08 21:52:55 +0000330#endif
331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 PyModule_AddIntConstant(m, "LOG_SYSLOG", LOG_SYSLOG);
333 PyModule_AddIntConstant(m, "LOG_CRON", LOG_CRON);
334 PyModule_AddIntConstant(m, "LOG_UUCP", LOG_UUCP);
335 PyModule_AddIntConstant(m, "LOG_NEWS", LOG_NEWS);
336 return m;
Guido van Rossume44e3731994-07-14 13:56:50 +0000337}