xref: /PHP-8.4/main/php_syslog.c (revision d46dea16)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | https://www.php.net/license/3_01.txt                                 |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Author: Philip Prindeville <philipp@redfish-solutions.com>           |
14    +----------------------------------------------------------------------+
15 */
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include "php.h"
21 #include "php_syslog.h"
22 
23 #include "zend.h"
24 #include "zend_smart_string.h"
25 
26 /*
27  * The SCO OpenServer 5 Development System (not the UDK)
28  * defines syslog to std_syslog.
29  */
30 
31 #ifdef HAVE_STD_SYSLOG
32 #define syslog std_syslog
33 #endif
34 
php_syslog_str(int priority,const zend_string * message)35 PHPAPI void php_syslog_str(int priority, const zend_string* message)
36 {
37 	smart_string sbuf = {0};
38 
39 	if (PG(syslog_filter) == PHP_SYSLOG_FILTER_RAW) {
40 		/* Just send it directly to the syslog */
41 		syslog(priority, "%s", ZSTR_VAL(message));
42 		return;
43 	}
44 
45 	/* We use < because we don't want the final NUL byte to be converted to '\x00' */
46 	for (size_t i = 0; i < ZSTR_LEN(message); ++i) {
47 		unsigned char c = ZSTR_VAL(message)[i];
48 
49 		/* check for NVT ASCII only unless test disabled */
50 		if (((0x20 <= c) && (c <= 0x7e))) {
51 			smart_string_appendc(&sbuf, c);
52 		} else if ((c >= 0x80) && (PG(syslog_filter) != PHP_SYSLOG_FILTER_ASCII)) {
53 			smart_string_appendc(&sbuf, c);
54 		} else if (c == '\n') {
55 			/* Smart string is not NUL terminated */
56 			syslog(priority, "%.*s", (int)sbuf.len, sbuf.c);
57 			smart_string_reset(&sbuf);
58 		} else if ((c < 0x20) && (PG(syslog_filter) == PHP_SYSLOG_FILTER_ALL)) {
59 			smart_string_appendc(&sbuf, c);
60 		} else {
61 			static const char xdigits[] = "0123456789abcdef";
62 
63 			smart_string_appendl(&sbuf, "\\x", 2);
64 			smart_string_appendc(&sbuf, xdigits[c >> 4]);
65 			smart_string_appendc(&sbuf, xdigits[c & 0xf]);
66 		}
67 	}
68 
69 	/* Smart string is not NUL terminated */
70 	syslog(priority, "%.*s", (int)sbuf.len, sbuf.c);
71 	smart_string_free(&sbuf);
72 }
73 
php_openlog(const char * ident,int option,int facility)74 void php_openlog(const char *ident, int option, int facility)
75 {
76 	openlog(ident, option, facility);
77 	PG(have_called_openlog) = 1;
78 }
79 
php_closelog(void)80 void php_closelog(void)
81 {
82 	closelog();
83 	PG(have_called_openlog) = 0;
84 }
85 
86 #ifdef PHP_WIN32
php_syslog(int priority,const char * format,...)87 PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
88 {
89 	va_list args;
90 
91 	/*
92 	 * don't rely on openlog() being called by syslog() if it's
93 	 * not already been done; call it ourselves and pass the
94 	 * correct parameters!
95 	 */
96 	if (!PG(have_called_openlog)) {
97 		php_openlog(PG(syslog_ident), 0, PG(syslog_facility));
98 	}
99 
100 	va_start(args, format);
101 	vsyslog(priority, format, args);
102 	va_end(args);
103 }
104 /* }}} */
105 #else
php_syslog(int priority,const char * format,...)106 PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
107 {
108 	zend_string *fbuf = NULL;
109 	va_list args;
110 
111 	/*
112 	 * don't rely on openlog() being called by syslog() if it's
113 	 * not already been done; call it ourselves and pass the
114 	 * correct parameters!
115 	 */
116 	if (!PG(have_called_openlog)) {
117 		php_openlog(PG(syslog_ident), 0, PG(syslog_facility));
118 	}
119 
120 	va_start(args, format);
121 	fbuf = zend_vstrpprintf(0, format, args);
122 	va_end(args);
123 
124 	php_syslog_str(priority, fbuf);
125 
126 	zend_string_release(fbuf);
127 }
128 /* }}} */
129 #endif
130