blob: 37eaebc975c850f6f26ffbecdc34fbfcc06ffb17 [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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Reifscheiderf6ce3cb2010-04-23 08:31:55 +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 Reifscheiderf6ce3cb2010-04-23 08:31:55 +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 Pitrouc83ea132010-05-09 14:46:46 +000058static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */
Sean Reifscheiderca2e6122010-04-25 06:31:23 +000059static char S_log_open = 0;
Guido van Rossumae94cf21998-05-08 21:52:55 +000060
61
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +000062static PyObject *
63syslog_get_argv(void)
64{
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Reifscheiderf6ce3cb2010-04-23 08:31:55 +000070
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 Py_ssize_t argv_len;
72 PyObject *scriptobj;
73 char *atslash;
74 PyObject *argv = PySys_GetObject("argv");
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +000075
Antoine Pitrouc83ea132010-05-09 14:46:46 +000076 if (argv == NULL) {
77 return(NULL);
78 }
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +000079
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Reifscheiderf6ce3cb2010-04-23 08:31:55 +000088
Antoine Pitrouc83ea132010-05-09 14:46:46 +000089 scriptobj = PyList_GetItem(argv, 0);
90 if (!PyString_Check(scriptobj)) {
91 return(NULL);
92 }
93 if (PyString_GET_SIZE(scriptobj) == 0) {
94 return(NULL);
95 }
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +000096
Antoine Pitrouc83ea132010-05-09 14:46:46 +000097 atslash = strrchr(PyString_AsString(scriptobj), SEP);
98 if (atslash) {
99 return(PyString_FromString(atslash + 1));
100 } else {
101 Py_INCREF(scriptobj);
102 return(scriptobj);
103 }
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000104
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000105 return(NULL);
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000106}
107
108
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000109static PyObject *
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000110syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds)
Guido van Rossume44e3731994-07-14 13:56:50 +0000111{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000112 long logopt = 0;
113 long facility = LOG_USER;
114 PyObject *new_S_ident_o = NULL;
115 static char *keywords[] = {"ident", "logoption", "facility", 0};
Guido van Rossumc1822a41995-10-11 16:15:28 +0000116
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000117 if (!PyArg_ParseTupleAndKeywords(args, kwds,
118 "|Sll:openlog", keywords, &new_S_ident_o, &logopt, &facility))
119 return NULL;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000120
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000121 if (new_S_ident_o) { Py_INCREF(new_S_ident_o); }
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000122
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000123 /* get sys.argv[0] or NULL if we can't for some reason */
124 if (!new_S_ident_o) {
125 new_S_ident_o = syslog_get_argv();
126 }
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000127
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000128 Py_XDECREF(S_ident_o);
129 S_ident_o = new_S_ident_o;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000130
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000131 /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not
132 * make a copy, and syslog(3) later uses it. We can't garbagecollect it
133 * If NULL, just let openlog figure it out (probably using C argv[0]).
134 */
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000135
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000136 openlog(S_ident_o ? PyString_AsString(S_ident_o) : NULL, logopt, facility);
137 S_log_open = 1;
Barry Warsaw43a476a1997-01-09 23:51:21 +0000138
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000139 Py_INCREF(Py_None);
140 return Py_None;
Guido van Rossume44e3731994-07-14 13:56:50 +0000141}
142
Barry Warsaw43a476a1997-01-09 23:51:21 +0000143
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000144static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000145syslog_syslog(PyObject * self, PyObject * args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000146{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000147 char *message;
148 int priority = LOG_INFO;
Guido van Rossume44e3731994-07-14 13:56:50 +0000149
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000150 if (!PyArg_ParseTuple(args, "is;[priority,] message string",
151 &priority, &message)) {
152 PyErr_Clear();
153 if (!PyArg_ParseTuple(args, "s;[priority,] message string",
154 &message))
155 return NULL;
156 }
Guido van Rossumae94cf21998-05-08 21:52:55 +0000157
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000158 /* if log is not opened, open it now */
159 if (!S_log_open) {
160 PyObject *openargs;
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000161
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000162 /* Continue even if PyTuple_New fails, because openlog(3) is optional.
163 * So, we can still do loggin in the unlikely event things are so hosed
164 * that we can't do this tuple.
165 */
166 if ((openargs = PyTuple_New(0))) {
167 PyObject *openlog_ret = syslog_openlog(self, openargs, NULL);
168 Py_XDECREF(openlog_ret);
169 Py_DECREF(openargs);
170 }
171 }
Sean Reifscheiderf6ce3cb2010-04-23 08:31:55 +0000172
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000173 Py_BEGIN_ALLOW_THREADS;
174 syslog(priority, "%s", message);
175 Py_END_ALLOW_THREADS;
176 Py_INCREF(Py_None);
177 return Py_None;
Guido van Rossume44e3731994-07-14 13:56:50 +0000178}
179
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000180static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +0000181syslog_closelog(PyObject *self, PyObject *unused)
Guido van Rossume44e3731994-07-14 13:56:50 +0000182{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000183 if (S_log_open) {
184 closelog();
185 Py_XDECREF(S_ident_o);
186 S_ident_o = NULL;
187 S_log_open = 0;
188 }
189 Py_INCREF(Py_None);
190 return Py_None;
Guido van Rossume44e3731994-07-14 13:56:50 +0000191}
192
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000193static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000194syslog_setlogmask(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000195{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000196 long maskpri, omaskpri;
Guido van Rossumc1822a41995-10-11 16:15:28 +0000197
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000198 if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri))
199 return NULL;
200 omaskpri = setlogmask(maskpri);
201 return PyInt_FromLong(omaskpri);
Guido van Rossume44e3731994-07-14 13:56:50 +0000202}
203
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000204static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000205syslog_log_mask(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000206{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000207 long mask;
208 long pri;
209 if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri))
210 return NULL;
211 mask = LOG_MASK(pri);
212 return PyInt_FromLong(mask);
Guido van Rossume44e3731994-07-14 13:56:50 +0000213}
214
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000216syslog_log_upto(PyObject *self, PyObject *args)
Guido van Rossume44e3731994-07-14 13:56:50 +0000217{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000218 long mask;
219 long pri;
220 if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri))
221 return NULL;
222 mask = LOG_UPTO(pri);
223 return PyInt_FromLong(mask);
Guido van Rossume44e3731994-07-14 13:56:50 +0000224}
225
226/* List of functions defined in the module */
227
Guido van Rossumf6971e21994-08-30 12:25:20 +0000228static PyMethodDef syslog_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000229 {"openlog", (PyCFunction) syslog_openlog, METH_VARARGS | METH_KEYWORDS},
230 {"closelog", syslog_closelog, METH_NOARGS},
231 {"syslog", syslog_syslog, METH_VARARGS},
232 {"setlogmask", syslog_setlogmask, METH_VARARGS},
233 {"LOG_MASK", syslog_log_mask, METH_VARARGS},
234 {"LOG_UPTO", syslog_log_upto, METH_VARARGS},
235 {NULL, NULL, 0}
Guido van Rossume44e3731994-07-14 13:56:50 +0000236};
237
Guido van Rossumae94cf21998-05-08 21:52:55 +0000238/* Initialization function for the module */
Guido van Rossumc1822a41995-10-11 16:15:28 +0000239
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000240PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000241initsyslog(void)
Guido van Rossume44e3731994-07-14 13:56:50 +0000242{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000243 PyObject *m;
Guido van Rossume44e3731994-07-14 13:56:50 +0000244
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000245 /* Create the module and add the functions */
246 m = Py_InitModule("syslog", syslog_methods);
247 if (m == NULL)
248 return;
Guido van Rossume44e3731994-07-14 13:56:50 +0000249
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000250 /* Add some symbolic constants to the module */
Guido van Rossumc1822a41995-10-11 16:15:28 +0000251
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000252 /* Priorities */
253 PyModule_AddIntConstant(m, "LOG_EMERG", LOG_EMERG);
254 PyModule_AddIntConstant(m, "LOG_ALERT", LOG_ALERT);
255 PyModule_AddIntConstant(m, "LOG_CRIT", LOG_CRIT);
256 PyModule_AddIntConstant(m, "LOG_ERR", LOG_ERR);
257 PyModule_AddIntConstant(m, "LOG_WARNING", LOG_WARNING);
258 PyModule_AddIntConstant(m, "LOG_NOTICE", LOG_NOTICE);
259 PyModule_AddIntConstant(m, "LOG_INFO", LOG_INFO);
260 PyModule_AddIntConstant(m, "LOG_DEBUG", LOG_DEBUG);
Guido van Rossumc1822a41995-10-11 16:15:28 +0000261
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000262 /* openlog() option flags */
263 PyModule_AddIntConstant(m, "LOG_PID", LOG_PID);
264 PyModule_AddIntConstant(m, "LOG_CONS", LOG_CONS);
265 PyModule_AddIntConstant(m, "LOG_NDELAY", LOG_NDELAY);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000266#ifdef LOG_NOWAIT
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000267 PyModule_AddIntConstant(m, "LOG_NOWAIT", LOG_NOWAIT);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000268#endif
Guido van Rossumc1822a41995-10-11 16:15:28 +0000269#ifdef LOG_PERROR
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000270 PyModule_AddIntConstant(m, "LOG_PERROR", LOG_PERROR);
Guido van Rossumc1822a41995-10-11 16:15:28 +0000271#endif
272
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000273 /* Facilities */
274 PyModule_AddIntConstant(m, "LOG_KERN", LOG_KERN);
275 PyModule_AddIntConstant(m, "LOG_USER", LOG_USER);
276 PyModule_AddIntConstant(m, "LOG_MAIL", LOG_MAIL);
277 PyModule_AddIntConstant(m, "LOG_DAEMON", LOG_DAEMON);
278 PyModule_AddIntConstant(m, "LOG_AUTH", LOG_AUTH);
279 PyModule_AddIntConstant(m, "LOG_LPR", LOG_LPR);
280 PyModule_AddIntConstant(m, "LOG_LOCAL0", LOG_LOCAL0);
281 PyModule_AddIntConstant(m, "LOG_LOCAL1", LOG_LOCAL1);
282 PyModule_AddIntConstant(m, "LOG_LOCAL2", LOG_LOCAL2);
283 PyModule_AddIntConstant(m, "LOG_LOCAL3", LOG_LOCAL3);
284 PyModule_AddIntConstant(m, "LOG_LOCAL4", LOG_LOCAL4);
285 PyModule_AddIntConstant(m, "LOG_LOCAL5", LOG_LOCAL5);
286 PyModule_AddIntConstant(m, "LOG_LOCAL6", LOG_LOCAL6);
287 PyModule_AddIntConstant(m, "LOG_LOCAL7", LOG_LOCAL7);
Guido van Rossume44e3731994-07-14 13:56:50 +0000288
Guido van Rossumae94cf21998-05-08 21:52:55 +0000289#ifndef LOG_SYSLOG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000290#define LOG_SYSLOG LOG_DAEMON
Guido van Rossumae94cf21998-05-08 21:52:55 +0000291#endif
292#ifndef LOG_NEWS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293#define LOG_NEWS LOG_MAIL
Guido van Rossumae94cf21998-05-08 21:52:55 +0000294#endif
295#ifndef LOG_UUCP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000296#define LOG_UUCP LOG_MAIL
Guido van Rossumae94cf21998-05-08 21:52:55 +0000297#endif
298#ifndef LOG_CRON
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299#define LOG_CRON LOG_DAEMON
Guido van Rossumae94cf21998-05-08 21:52:55 +0000300#endif
301
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000302 PyModule_AddIntConstant(m, "LOG_SYSLOG", LOG_SYSLOG);
303 PyModule_AddIntConstant(m, "LOG_CRON", LOG_CRON);
304 PyModule_AddIntConstant(m, "LOG_UUCP", LOG_UUCP);
305 PyModule_AddIntConstant(m, "LOG_NEWS", LOG_NEWS);
Guido van Rossume44e3731994-07-14 13:56:50 +0000306}