blob: 24517925c32eb08e8a2cde7f3e63fc0fb20651ac [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;
Victor Stinnerbd303c12013-11-07 23:07:29 +010074 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 }
Victor Stinnerc4f281e2011-10-11 22:11:42 +020093 scriptlen = PyUnicode_GET_LENGTH(scriptobj);
Alexander Belopolskye239d232010-12-08 23:31:48 +000094 if (scriptlen == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 return(NULL);
96 }
Sean Reifscheider13daf122010-04-23 09:29:52 +000097
Victor Stinnerc4f281e2011-10-11 22:11:42 +020098 slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020099 if (slash == -2)
100 return NULL;
101 if (slash != -1) {
Václav Bartošf04750b2020-01-14 18:57:04 +0100102 return PyUnicode_Substring(scriptobj, slash + 1, scriptlen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 } else {
104 Py_INCREF(scriptobj);
105 return(scriptobj);
106 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 return(NULL);
Sean Reifscheider13daf122010-04-23 09:29:52 +0000109}
110
111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112static PyObject *
Sean Reifscheider13daf122010-04-23 09:29:52 +0000113syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds)
Guido van Rossume44e3731994-07-14 13:56:50 +0000114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 long logopt = 0;
116 long facility = LOG_USER;
117 PyObject *new_S_ident_o = NULL;
118 static char *keywords[] = {"ident", "logoption", "facility", 0};
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200119 const char *ident = NULL;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 if (!PyArg_ParseTupleAndKeywords(args, kwds,
122 "|Ull:openlog", keywords, &new_S_ident_o, &logopt, &facility))
123 return NULL;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 if (new_S_ident_o) {
126 Py_INCREF(new_S_ident_o);
Alexander Belopolskye239d232010-12-08 23:31:48 +0000127 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 /* get sys.argv[0] or NULL if we can't for some reason */
130 if (!new_S_ident_o) {
131 new_S_ident_o = syslog_get_argv();
Alexander Belopolskye239d232010-12-08 23:31:48 +0000132 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 Py_XDECREF(S_ident_o);
135 S_ident_o = new_S_ident_o;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not
138 * make a copy, and syslog(3) later uses it. We can't garbagecollect it
139 * If NULL, just let openlog figure it out (probably using C argv[0]).
140 */
Alexander Belopolskye239d232010-12-08 23:31:48 +0000141 if (S_ident_o) {
Serhiy Storchaka06515832016-11-20 09:13:07 +0200142 ident = PyUnicode_AsUTF8(S_ident_o);
Alexander Belopolskye239d232010-12-08 23:31:48 +0000143 if (ident == NULL)
144 return NULL;
145 }
Barry Warsaw43a476a1997-01-09 23:51:21 +0000146
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800147 if (PySys_Audit("syslog.openlog", "sll", ident, logopt, facility) < 0) {
148 return NULL;
149 }
150
Alexander Belopolskye239d232010-12-08 23:31:48 +0000151 openlog(ident, logopt, facility);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 S_log_open = 1;
153
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200154 Py_RETURN_NONE;
Guido van Rossume44e3731994-07-14 13:56:50 +0000155}
156
Barry Warsaw43a476a1997-01-09 23:51:21 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000159syslog_syslog(PyObject * self, PyObject * args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 PyObject *message_object;
162 const char *message;
163 int priority = LOG_INFO;
Guido van Rossume44e3731994-07-14 13:56:50 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 if (!PyArg_ParseTuple(args, "iU;[priority,] message string",
166 &priority, &message_object)) {
167 PyErr_Clear();
168 if (!PyArg_ParseTuple(args, "U;[priority,] message string",
169 &message_object))
170 return NULL;
171 }
Guido van Rossumae94cf21998-05-08 21:52:55 +0000172
Serhiy Storchaka06515832016-11-20 09:13:07 +0200173 message = PyUnicode_AsUTF8(message_object);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 if (message == NULL)
175 return NULL;
Sean Reifscheider13daf122010-04-23 09:29:52 +0000176
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800177 if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) {
178 return NULL;
179 }
180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 /* if log is not opened, open it now */
182 if (!S_log_open) {
183 PyObject *openargs;
Sean Reifscheider13daf122010-04-23 09:29:52 +0000184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 /* Continue even if PyTuple_New fails, because openlog(3) is optional.
186 * So, we can still do loggin in the unlikely event things are so hosed
187 * that we can't do this tuple.
188 */
189 if ((openargs = PyTuple_New(0))) {
190 PyObject *openlog_ret = syslog_openlog(self, openargs, NULL);
191 Py_XDECREF(openlog_ret);
192 Py_DECREF(openargs);
193 }
194 }
Sean Reifscheider13daf122010-04-23 09:29:52 +0000195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 Py_BEGIN_ALLOW_THREADS;
197 syslog(priority, "%s", message);
198 Py_END_ALLOW_THREADS;
199 Py_RETURN_NONE;
Guido van Rossume44e3731994-07-14 13:56:50 +0000200}
201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000203syslog_closelog(PyObject *self, PyObject *unused)
Guido van Rossume44e3731994-07-14 13:56:50 +0000204{
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800205 if (PySys_Audit("syslog.closelog", NULL) < 0) {
206 return NULL;
207 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 if (S_log_open) {
209 closelog();
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200210 Py_CLEAR(S_ident_o);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 S_log_open = 0;
212 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200213 Py_RETURN_NONE;
Guido van Rossume44e3731994-07-14 13:56:50 +0000214}
215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000217syslog_setlogmask(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 long maskpri, omaskpri;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri))
222 return NULL;
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800223 if (PySys_Audit("syslog.setlogmask", "(O)", args ? args : Py_None) < 0) {
224 return NULL;
225 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 omaskpri = setlogmask(maskpri);
227 return PyLong_FromLong(omaskpri);
Guido van Rossume44e3731994-07-14 13:56:50 +0000228}
229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000231syslog_log_mask(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 long mask;
234 long pri;
235 if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri))
236 return NULL;
237 mask = LOG_MASK(pri);
238 return PyLong_FromLong(mask);
Guido van Rossume44e3731994-07-14 13:56:50 +0000239}
240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000242syslog_log_upto(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 long mask;
245 long pri;
246 if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri))
247 return NULL;
248 mask = LOG_UPTO(pri);
249 return PyLong_FromLong(mask);
Guido van Rossume44e3731994-07-14 13:56:50 +0000250}
251
252/* List of functions defined in the module */
253
Guido van Rossumf6971e21994-08-30 12:25:20 +0000254static PyMethodDef syslog_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200255 {"openlog", (PyCFunction)(void(*)(void)) syslog_openlog, METH_VARARGS | METH_KEYWORDS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 {"closelog", syslog_closelog, METH_NOARGS},
257 {"syslog", syslog_syslog, METH_VARARGS},
258 {"setlogmask", syslog_setlogmask, METH_VARARGS},
259 {"LOG_MASK", syslog_log_mask, METH_VARARGS},
260 {"LOG_UPTO", syslog_log_upto, METH_VARARGS},
261 {NULL, NULL, 0}
Guido van Rossume44e3731994-07-14 13:56:50 +0000262};
263
Guido van Rossumae94cf21998-05-08 21:52:55 +0000264/* Initialization function for the module */
Guido van Rossumc1822a41995-10-11 16:15:28 +0000265
Martin v. Löwis1a214512008-06-11 05:26:20 +0000266
267static struct PyModuleDef syslogmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 PyModuleDef_HEAD_INIT,
269 "syslog",
270 NULL,
271 -1,
272 syslog_methods,
273 NULL,
274 NULL,
275 NULL,
276 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000277};
278
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000279PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000280PyInit_syslog(void)
Guido van Rossume44e3731994-07-14 13:56:50 +0000281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 PyObject *m;
Guido van Rossume44e3731994-07-14 13:56:50 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 /* Create the module and add the functions */
285 m = PyModule_Create(&syslogmodule);
286 if (m == NULL)
287 return NULL;
Guido van Rossume44e3731994-07-14 13:56:50 +0000288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 /* Add some symbolic constants to the module */
Guido van Rossumc1822a41995-10-11 16:15:28 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 /* Priorities */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200292 PyModule_AddIntMacro(m, LOG_EMERG);
293 PyModule_AddIntMacro(m, LOG_ALERT);
294 PyModule_AddIntMacro(m, LOG_CRIT);
295 PyModule_AddIntMacro(m, LOG_ERR);
296 PyModule_AddIntMacro(m, LOG_WARNING);
297 PyModule_AddIntMacro(m, LOG_NOTICE);
298 PyModule_AddIntMacro(m, LOG_INFO);
299 PyModule_AddIntMacro(m, LOG_DEBUG);
Guido van Rossumc1822a41995-10-11 16:15:28 +0000300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 /* openlog() option flags */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200302 PyModule_AddIntMacro(m, LOG_PID);
303 PyModule_AddIntMacro(m, LOG_CONS);
304 PyModule_AddIntMacro(m, LOG_NDELAY);
R David Murrayeac09392012-03-29 07:15:45 -0400305#ifdef LOG_ODELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200306 PyModule_AddIntMacro(m, LOG_ODELAY);
R David Murrayeac09392012-03-29 07:15:45 -0400307#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +0000308#ifdef LOG_NOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200309 PyModule_AddIntMacro(m, LOG_NOWAIT);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000310#endif
Guido van Rossumc1822a41995-10-11 16:15:28 +0000311#ifdef LOG_PERROR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200312 PyModule_AddIntMacro(m, LOG_PERROR);
Guido van Rossumc1822a41995-10-11 16:15:28 +0000313#endif
314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 /* Facilities */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200316 PyModule_AddIntMacro(m, LOG_KERN);
317 PyModule_AddIntMacro(m, LOG_USER);
318 PyModule_AddIntMacro(m, LOG_MAIL);
319 PyModule_AddIntMacro(m, LOG_DAEMON);
320 PyModule_AddIntMacro(m, LOG_AUTH);
321 PyModule_AddIntMacro(m, LOG_LPR);
322 PyModule_AddIntMacro(m, LOG_LOCAL0);
323 PyModule_AddIntMacro(m, LOG_LOCAL1);
324 PyModule_AddIntMacro(m, LOG_LOCAL2);
325 PyModule_AddIntMacro(m, LOG_LOCAL3);
326 PyModule_AddIntMacro(m, LOG_LOCAL4);
327 PyModule_AddIntMacro(m, LOG_LOCAL5);
328 PyModule_AddIntMacro(m, LOG_LOCAL6);
329 PyModule_AddIntMacro(m, LOG_LOCAL7);
Guido van Rossume44e3731994-07-14 13:56:50 +0000330
Guido van Rossumae94cf21998-05-08 21:52:55 +0000331#ifndef LOG_SYSLOG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332#define LOG_SYSLOG LOG_DAEMON
Guido van Rossumae94cf21998-05-08 21:52:55 +0000333#endif
334#ifndef LOG_NEWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335#define LOG_NEWS LOG_MAIL
Guido van Rossumae94cf21998-05-08 21:52:55 +0000336#endif
337#ifndef LOG_UUCP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338#define LOG_UUCP LOG_MAIL
Guido van Rossumae94cf21998-05-08 21:52:55 +0000339#endif
340#ifndef LOG_CRON
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341#define LOG_CRON LOG_DAEMON
Guido van Rossumae94cf21998-05-08 21:52:55 +0000342#endif
343
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200344 PyModule_AddIntMacro(m, LOG_SYSLOG);
345 PyModule_AddIntMacro(m, LOG_CRON);
346 PyModule_AddIntMacro(m, LOG_UUCP);
347 PyModule_AddIntMacro(m, LOG_NEWS);
R David Murrayeac09392012-03-29 07:15:45 -0400348
349#ifdef LOG_AUTHPRIV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200350 PyModule_AddIntMacro(m, LOG_AUTHPRIV);
R David Murrayeac09392012-03-29 07:15:45 -0400351#endif
352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 return m;
Guido van Rossume44e3731994-07-14 13:56:50 +0000354}