Ruby  1.9.3p547(2014-05-14revision45962)
syslog.c
Go to the documentation of this file.
1 /*
2  * UNIX Syslog extension for Ruby
3  * Amos Gouaux, University of Texas at Dallas
4  * <amos+ruby@utdallas.edu>
5  * Documented by mathew <meta@pobox.com>
6  *
7  * $RoughId: syslog.c,v 1.21 2002/02/25 12:21:17 knu Exp $
8  * $Id: syslog.c 44754 2014-01-30 03:49:07Z usa $
9  */
10 
11 #include "ruby/ruby.h"
12 #include "ruby/util.h"
13 #include <syslog.h>
14 
15 #ifdef PRIsVALUE
16 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
17 # define RB_OBJ_STRING(obj) (obj)
18 #else
19 # define PRIsVALUE "s"
20 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
21 # define RB_OBJ_STRING(obj) StringValueCStr(obj)
22 #endif
23 
24 /* Syslog class */
26 static const char *syslog_ident = NULL;
27 static int syslog_options = -1, syslog_facility = -1, syslog_mask = -1;
28 static int syslog_opened = 0;
29 
30 /* Package helper routines */
31 static void syslog_write(int pri, int argc, VALUE *argv)
32 {
33  VALUE str;
34 
35  rb_secure(4);
36  if (argc < 1) {
37  rb_raise(rb_eArgError, "no log message supplied");
38  }
39 
40  if (!syslog_opened) {
41  rb_raise(rb_eRuntimeError, "must open syslog before write");
42  }
43 
44  str = rb_f_sprintf(argc, argv);
45 
46  syslog(pri, "%s", RSTRING_PTR(str));
47 }
48 
49 /* Closes the syslog facility.
50  * Raises a runtime exception if it is not open.
51  */
53 {
54  rb_secure(4);
55  if (!syslog_opened) {
56  rb_raise(rb_eRuntimeError, "syslog not opened");
57  }
58 
59  closelog();
60 
61  free((void *)syslog_ident);
64  syslog_opened = 0;
65 
66  return Qnil;
67 }
68 
69 /* call-seq:
70  * open(ident, options, facility) => syslog
71  *
72  * :yields: syslog
73  *
74  * Open the syslog facility.
75  * Raises a runtime exception if it is already open.
76  *
77  * Can be called with or without a code block. If called with a block, the
78  * Syslog object created is passed to the block.
79  *
80  * If the syslog is already open, raises a RuntimeError.
81  *
82  * +ident+ is a String which identifies the calling program.
83  *
84  * +options+ is the logical OR of any of the following:
85  *
86  * LOG_CONS:: If there is an error while sending to the system logger,
87  * write directly to the console instead.
88  *
89  * LOG_NDELAY:: Open the connection now, rather than waiting for the first
90  * message to be written.
91  *
92  * LOG_NOWAIT:: Don't wait for any child processes created while logging
93  * messages. (Has no effect on Linux.)
94  *
95  * LOG_ODELAY:: Opposite of LOG_NDELAY; wait until a message is sent before
96  * opening the connection. (This is the default.)
97  *
98  * LOG_PERROR:: Print the message to stderr as well as sending it to syslog.
99  * (Not in POSIX.1-2001.)
100  *
101  * LOG_PID:: Include the current process ID with each message.
102  *
103  * +facility+ describes the type of program opening the syslog, and is
104  * the logical OR of any of the following which are defined for the host OS:
105  *
106  * LOG_AUTH:: Security or authorization. Deprecated, use LOG_AUTHPRIV
107  * instead.
108  *
109  * LOG_AUTHPRIV:: Security or authorization messages which should be kept
110  * private.
111  *
112  * LOG_CONSOLE:: System console message.
113  *
114  * LOG_CRON:: System task scheduler (cron or at).
115  *
116  * LOG_DAEMON:: A system daemon which has no facility value of its own.
117  *
118  * LOG_FTP:: An FTP server.
119  *
120  * LOG_KERN:: A kernel message (not sendable by user processes, so not of
121  * much use to Ruby, but listed here for completeness).
122  *
123  * LOG_LRP:: Line printer subsystem.
124  *
125  * LOG_MAIL:: Mail delivery or transport subsystem.
126  *
127  * LOG_NEWS:: Usenet news system.
128  *
129  * LOG_NTP:: Network Time Protocol server.
130  *
131  * LOG_SECURITY:: General security message.
132  *
133  * LOG_SYSLOG:: Messages generated internally by syslog.
134  *
135  * LOG_USER:: Generic user-level message.
136  *
137  * LOG_UUCP:: UUCP subsystem.
138  *
139  * LOG_LOCAL0 to LOG_LOCAL7:: Locally-defined facilities.
140  *
141  * Example:
142  *
143  * Syslog.open("webrick", Syslog::LOG_PID,
144  * Syslog::LOG_DAEMON | Syslog::LOG_LOCAL3)
145  *
146  */
147 static VALUE mSyslog_open(int argc, VALUE *argv, VALUE self)
148 {
149  VALUE ident, opt, fac;
150 
151  if (syslog_opened) {
152  rb_raise(rb_eRuntimeError, "syslog already open");
153  }
154 
155  rb_scan_args(argc, argv, "03", &ident, &opt, &fac);
156 
157  if (NIL_P(ident)) {
158  ident = rb_gv_get("$0");
159  }
160  SafeStringValue(ident);
161  syslog_ident = strdup(RSTRING_PTR(ident));
162 
163  if (NIL_P(opt)) {
164  syslog_options = LOG_PID | LOG_CONS;
165  } else {
166  syslog_options = NUM2INT(opt);
167  }
168 
169  if (NIL_P(fac)) {
170  syslog_facility = LOG_USER;
171  } else {
172  syslog_facility = NUM2INT(fac);
173  }
174 
176 
177  syslog_opened = 1;
178 
179  setlogmask(syslog_mask = setlogmask(0));
180 
181  /* be like File.new.open {...} */
182  if (rb_block_given_p()) {
183  rb_ensure(rb_yield, self, mSyslog_close, self);
184  }
185 
186  return self;
187 }
188 
189 /* call-seq:
190  * reopen(ident, options, facility) => syslog
191  *
192  * :yields: syslog
193  *
194  * Closes and then reopens the syslog.
195  *
196  * Arguments are the same as for open().
197  */
199 {
200  mSyslog_close(self);
201 
202  return mSyslog_open(argc, argv, self);
203 }
204 
205 /* call-seq:
206  * opened?
207  *
208  * Returns true if the syslog is open.
209  */
211 {
212  return syslog_opened ? Qtrue : Qfalse;
213 }
214 
215 /* Returns the identity string used in the last call to open()
216  */
218 {
220 }
221 
222 /* Returns the options bitmask used in the last call to open()
223  */
225 {
227 }
228 
229 /* Returns the facility number used in the last call to open()
230  */
232 {
234 }
235 
236 /* Returns the log priority mask in effect. The mask is not reset by opening
237  * or closing syslog.
238  */
240 {
242 }
243 
244 /* call-seq:
245  * mask=(priority_mask)
246  *
247  * Sets the log priority mask. A method LOG_UPTO is defined to make it easier
248  * to set mask values. Example:
249  *
250  * Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)
251  *
252  * Alternatively, specific priorities can be selected and added together using
253  * binary OR. Example:
254  *
255  * Syslog.mask = Syslog::LOG_MASK(Syslog::LOG_ERR) | Syslog::LOG_MASK(Syslog::LOG_CRIT)
256  *
257  * The priority mask persists through calls to open() and close().
258  */
259 static VALUE mSyslog_set_mask(VALUE self, VALUE mask)
260 {
261  rb_secure(4);
262  if (!syslog_opened) {
263  rb_raise(rb_eRuntimeError, "must open syslog before setting log mask");
264  }
265 
266  setlogmask(syslog_mask = NUM2INT(mask));
267 
268  return mask;
269 }
270 
271 /* call-seq:
272  * log(priority, format_string, *format_args)
273  *
274  * Log a message with the specified priority. Example:
275  *
276  * Syslog.log(Syslog::LOG_CRIT, "Out of disk space")
277  * Syslog.log(Syslog::LOG_CRIT, "User %s logged in", ENV['USER'])
278  *
279  * The priority levels, in descending order, are:
280  *
281  * LOG_EMERG:: System is unusable
282  * LOG_ALERT:: Action needs to be taken immediately
283  * LOG_CRIT:: A critical condition has occurred
284  * LOG_ERR:: An error occurred
285  * LOG_WARNING:: Warning of a possible problem
286  * LOG_NOTICE:: A normal but significant condition occurred
287  * LOG_INFO:: Informational message
288  * LOG_DEBUG:: Debugging information
289  *
290  * Each priority level also has a shortcut method that logs with it's named priority.
291  * As an example, the two following statements would produce the same result:
292  *
293  * Syslog.log(Syslog::LOG_ALERT, "Out of memory")
294  * Syslog.alert("Out of memory")
295  *
296  * Format strings are as for printf/sprintf, except that in addition %m is
297  * replaced with the error message string that would be returned by
298  * strerror(errno).
299  *
300  */
301 static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
302 {
303  VALUE pri;
304 
305  if (argc < 2) {
306  rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", argc);
307  }
308 
309  argc--;
310  pri = *argv++;
311 
312  if (!FIXNUM_P(pri)) {
313  rb_raise(rb_eTypeError, "type mismatch: %"PRIsVALUE" given", RB_OBJ_CLASSNAME(pri));
314  }
315 
316  syslog_write(FIX2INT(pri), argc, argv);
317 
318  return self;
319 }
320 
321 /* Returns an inspect() string summarizing the object state.
322  */
324 {
325  Check_Type(self, T_MODULE);
326 
327  if (!syslog_opened)
328  return rb_sprintf("<#%s: opened=false>", rb_class2name(self));
329 
330  return rb_sprintf("<#%s: opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>",
331  rb_class2name(self),
332  syslog_ident,
335  syslog_mask);
336 }
337 
338 /* Returns self, for backward compatibility.
339  */
341 {
342  return self;
343 }
344 
345 #define define_syslog_shortcut_method(pri, name) \
346 static VALUE mSyslog_##name(int argc, VALUE *argv, VALUE self) \
347 { \
348  syslog_write((pri), argc, argv); \
349 \
350  return self; \
351 }
352 
353 #ifdef LOG_EMERG
354 define_syslog_shortcut_method(LOG_EMERG, emerg)
355 #endif
356 #ifdef LOG_ALERT
357 define_syslog_shortcut_method(LOG_ALERT, alert)
358 #endif
359 #ifdef LOG_CRIT
360 define_syslog_shortcut_method(LOG_CRIT, crit)
361 #endif
362 #ifdef LOG_ERR
364 #endif
365 #ifdef LOG_WARNING
366 define_syslog_shortcut_method(LOG_WARNING, warning)
367 #endif
368 #ifdef LOG_NOTICE
369 define_syslog_shortcut_method(LOG_NOTICE, notice)
370 #endif
371 #ifdef LOG_INFO
372 define_syslog_shortcut_method(LOG_INFO, info)
373 #endif
374 #ifdef LOG_DEBUG
376 #endif
377 
378 /* call-seq:
379  * LOG_MASK(priority_level) => priority_mask
380  *
381  * Generates a mask bit for a priority level. See #mask=
382  */
384 {
385  return INT2FIX(LOG_MASK(NUM2INT(pri)));
386 }
387 
388 /* call-seq:
389  * LOG_UPTO(priority_level) => priority_mask
390  *
391  * Generates a mask value for priority levels at or below the level specified.
392  * See #mask=
393  */
395 {
396  return INT2FIX(LOG_UPTO(NUM2INT(pri)));
397 }
398 
399 /* The syslog package provides a Ruby interface to the POSIX system logging
400  * facility.
401  *
402  * Syslog messages are typically passed to a central logging daemon.
403  * The daemon may filter them; route them into different files (usually
404  * found under /var/log); place them in SQL databases; forward
405  * them to centralized logging servers via TCP or UDP; or even alert the
406  * system administrator via email, pager or text message.
407  *
408  * Unlike application-level logging via Logger or Log4r, syslog is designed
409  * to allow secure tamper-proof logging.
410  *
411  * The syslog protocol is standardized in RFC 5424.
412  */
414 {
415  mSyslog = rb_define_module("Syslog");
416 
417  /* Document-module: Syslog::Constants
418  *
419  * Module holding Syslog constants. See Syslog::log and Syslog::open for
420  * constant descriptions.
421  */
423 
425 
430 
434 
439 
442 
445 
448 
449 #define rb_define_syslog_const(id) \
450  rb_define_const(mSyslogConstants, #id, INT2NUM(id))
451 
452  /* Various options when opening log */
453 #ifdef LOG_PID
454  rb_define_syslog_const(LOG_PID);
455 #endif
456 #ifdef LOG_CONS
457  rb_define_syslog_const(LOG_CONS);
458 #endif
459 #ifdef LOG_ODELAY
460  rb_define_syslog_const(LOG_ODELAY); /* deprecated */
461 #endif
462 #ifdef LOG_NDELAY
463  rb_define_syslog_const(LOG_NDELAY);
464 #endif
465 #ifdef LOG_NOWAIT
466  rb_define_syslog_const(LOG_NOWAIT); /* deprecated */
467 #endif
468 #ifdef LOG_PERROR
469  rb_define_syslog_const(LOG_PERROR);
470 #endif
471 
472  /* Various syslog facilities */
473 #ifdef LOG_AUTH
474  rb_define_syslog_const(LOG_AUTH);
475 #endif
476 #ifdef LOG_AUTHPRIV
477  rb_define_syslog_const(LOG_AUTHPRIV);
478 #endif
479 #ifdef LOG_CONSOLE
480  rb_define_syslog_const(LOG_CONSOLE);
481 #endif
482 #ifdef LOG_CRON
483  rb_define_syslog_const(LOG_CRON);
484 #endif
485 #ifdef LOG_DAEMON
486  rb_define_syslog_const(LOG_DAEMON);
487 #endif
488 #ifdef LOG_FTP
489  rb_define_syslog_const(LOG_FTP);
490 #endif
491 #ifdef LOG_KERN
492  rb_define_syslog_const(LOG_KERN);
493 #endif
494 #ifdef LOG_LPR
495  rb_define_syslog_const(LOG_LPR);
496 #endif
497 #ifdef LOG_MAIL
498  rb_define_syslog_const(LOG_MAIL);
499 #endif
500 #ifdef LOG_NEWS
501  rb_define_syslog_const(LOG_NEWS);
502 #endif
503 #ifdef LOG_NTP
504  rb_define_syslog_const(LOG_NTP);
505 #endif
506 #ifdef LOG_SECURITY
507  rb_define_syslog_const(LOG_SECURITY);
508 #endif
509 #ifdef LOG_SYSLOG
510  rb_define_syslog_const(LOG_SYSLOG);
511 #endif
512 #ifdef LOG_USER
513  rb_define_syslog_const(LOG_USER);
514 #endif
515 #ifdef LOG_UUCP
516  rb_define_syslog_const(LOG_UUCP);
517 #endif
518 #ifdef LOG_LOCAL0
519  rb_define_syslog_const(LOG_LOCAL0);
520 #endif
521 #ifdef LOG_LOCAL1
522  rb_define_syslog_const(LOG_LOCAL1);
523 #endif
524 #ifdef LOG_LOCAL2
525  rb_define_syslog_const(LOG_LOCAL2);
526 #endif
527 #ifdef LOG_LOCAL3
528  rb_define_syslog_const(LOG_LOCAL3);
529 #endif
530 #ifdef LOG_LOCAL4
531  rb_define_syslog_const(LOG_LOCAL4);
532 #endif
533 #ifdef LOG_LOCAL5
534  rb_define_syslog_const(LOG_LOCAL5);
535 #endif
536 #ifdef LOG_LOCAL6
537  rb_define_syslog_const(LOG_LOCAL6);
538 #endif
539 #ifdef LOG_LOCAL7
540  rb_define_syslog_const(LOG_LOCAL7);
541 #endif
542 
543 #define rb_define_syslog_shortcut(name) \
544  rb_define_module_function(mSyslog, #name, mSyslog_##name, -1)
545 
546  /* Various syslog priorities and the shortcut methods */
547 #ifdef LOG_EMERG
548  rb_define_syslog_const(LOG_EMERG);
550 #endif
551 #ifdef LOG_ALERT
552  rb_define_syslog_const(LOG_ALERT);
554 #endif
555 #ifdef LOG_CRIT
556  rb_define_syslog_const(LOG_CRIT);
558 #endif
559 #ifdef LOG_ERR
560  rb_define_syslog_const(LOG_ERR);
562 #endif
563 #ifdef LOG_WARNING
564  rb_define_syslog_const(LOG_WARNING);
565  rb_define_syslog_shortcut(warning);
566 #endif
567 #ifdef LOG_NOTICE
568  rb_define_syslog_const(LOG_NOTICE);
570 #endif
571 #ifdef LOG_INFO
572  rb_define_syslog_const(LOG_INFO);
574 #endif
575 #ifdef LOG_DEBUG
576  rb_define_syslog_const(LOG_DEBUG);
578 #endif
579 }
#define NUM2INT(x)
Definition: ruby.h:536
VALUE rb_f_sprintf(int, const VALUE *)
Definition: sprintf.c:433
#define T_MODULE
Definition: ruby.h:416
#define Qtrue
Definition: ruby.h:366
static VALUE mSyslog_isopen(VALUE self)
Definition: syslog.c:210
VALUE rb_eTypeError
Definition: error.c:467
static VALUE mSyslog_reopen(int argc, VALUE *argv, VALUE self)
Definition: syslog.c:198
static VALUE INT2NUM(int v)
Definition: ruby.h:981
#define rb_define_syslog_const(id)
#define RSTRING_PTR(string)
Definition: generator.h:42
static int syslog_opened
Definition: syslog.c:28
#define Check_Type(v, t)
Definition: ruby.h:459
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1574
static void syslog_write(int pri, int argc, VALUE *argv)
Definition: syslog.c:31
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:663
static VALUE mSyslog_instance(VALUE self)
Definition: syslog.c:340
#define FIXNUM_P(f)
Definition: ruby.h:338
static VALUE mSyslog_ident(VALUE self)
Definition: syslog.c:217
static VALUE mSyslogConstants_LOG_MASK(VALUE klass, VALUE pri)
Definition: syslog.c:383
VALUE rb_gv_get(const char *)
Definition: variable.c:730
static int syslog_mask
Definition: syslog.c:27
int rb_block_given_p(void)
Definition: eval.c:604
VALUE rb_eRuntimeError
Definition: error.c:466
#define NIL_P(v)
Definition: ruby.h:374
static VALUE mSyslog
Definition: syslog.c:25
int argc
Definition: ruby.c:120
#define Qfalse
Definition: ruby.h:365
#define rb_define_syslog_shortcut(name)
static const char * syslog_ident
Definition: syslog.c:26
void Init_syslog()
Definition: syslog.c:413
int err
Definition: win32.c:78
static VALUE mSyslog_close(VALUE self)
Definition: syslog.c:52
static int syslog_facility
Definition: syslog.c:27
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1358
VALUE rb_yield(VALUE)
Definition: vm_eval.c:781
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1203
static VALUE mSyslog_facility(VALUE self)
Definition: syslog.c:231
#define strdup(s)
Definition: util.h:69
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1416
#define Qnil
Definition: ruby.h:367
static int syslog_options
Definition: syslog.c:27
#define debug(x)
Definition: _sdbm.c:56
unsigned long VALUE
Definition: ruby.h:88
const char * rb_class2name(VALUE)
Definition: variable.c:311
#define FIX2INT(x)
Definition: ruby.h:538
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:737
static VALUE mSyslog_inspect(VALUE self)
Definition: syslog.c:323
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:607
static VALUE mSyslogConstants
Definition: syslog.c:25
#define INT2FIX(i)
Definition: ruby.h:225
#define RB_OBJ_CLASSNAME(obj)
Definition: syslog.c:20
static VALUE mSyslog_set_mask(VALUE self, VALUE mask)
Definition: syslog.c:259
static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
Definition: syslog.c:301
#define SafeStringValue(v)
Definition: ruby.h:472
void rb_secure(int)
Definition: safe.c:79
static VALUE mSyslog_open(int argc, VALUE *argv, VALUE self)
Definition: syslog.c:147
VALUE rb_define_module(const char *name)
Definition: class.c:587
#define NULL
Definition: _sdbm.c:107
#define define_syslog_shortcut_method(pri, name)
Definition: syslog.c:345
VALUE rb_str_new2(const char *)
static VALUE mSyslogConstants_LOG_UPTO(VALUE klass, VALUE pri)
Definition: syslog.c:394
free(psz)
VALUE rb_eArgError
Definition: error.c:468
static VALUE mSyslog_get_mask(VALUE self)
Definition: syslog.c:239
#define PRIsVALUE
Definition: syslog.c:19
static VALUE mSyslog_options(VALUE self)
Definition: syslog.c:224
char ** argv
Definition: ruby.c:121