along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
+#include <talloc.h>
+#include "replace.h"
#include "system/filesys.h"
#include "system/syslog.h"
-#include "lib/util/time_basic.h"
+#include "system/locale.h"
+#include "time_basic.h"
+#include "close_low_fd.h"
+#include "memory.h"
+#include "samba_util.h" /* LIST_SEP */
+#include "debug.h"
/* define what facility to use for syslog */
#ifndef SYSLOG_FACILITY
/* -------------------------------------------------------------------------- **
* Defines...
- *
- * FORMAT_BUFR_MAX - Index of the last byte of the format buffer;
- * format_bufr[FORMAT_BUFR_MAX] should always be reserved
- * for a terminating null byte.
*/
+/*
+ * format_bufr[FORMAT_BUFR_SIZE - 1] should always be reserved
+ * for a terminating null byte.
+ */
#define FORMAT_BUFR_SIZE 1024
-#define FORMAT_BUFR_MAX (FORMAT_BUFR_SIZE - 1)
/* -------------------------------------------------------------------------- **
* This module implements Samba's debugging utility.
.fd = 2 /* stderr by default */
};
+#ifdef WITH_SYSLOG
+static int debug_level_to_priority(int level)
+{
+ /*
+ * map debug levels to syslog() priorities note that not all
+ * DEBUG(0, ...) calls are necessarily errors
+ */
+ static const int priority_map[4] = {
+ LOG_ERR, /* 0 */
+ LOG_WARNING, /* 1 */
+ LOG_NOTICE, /* 2 */
+ LOG_INFO, /* 3 */
+ };
+ int priority;
+
+ if( level >= ARRAY_SIZE(priority_map) || level < 0)
+ priority = LOG_DEBUG;
+ else
+ priority = priority_map[level];
+
+ return priority;
+}
+#endif
+
/* -------------------------------------------------------------------------- **
* External variables.
*/
unsigned int i;
/* prepare strings */
for (i = 0; i < debug_num_classes; i++) {
- buf = talloc_asprintf_append(buf,
+ buf = talloc_asprintf_append(buf,
"%s:%d%s",
classname_table[i],
DEBUGLEVEL_CLASS[i],
Utility to translate names to debug class index's (public version).
****************************************************************************/
-int debug_lookup_classname(const char *classname)
+static int debug_lookup_classname(const char *classname)
{
int ndx;
}
/****************************************************************************
- parse the debug levels from smbcontrol. Example debug level parameter:
- printdrivers:7
+ Parse the debug levels from smb.conf. Example debug level string:
+ 3 tdb:5 printdrivers:7
+ Note: the 1st param has no "name:" preceeding it.
****************************************************************************/
-static bool debug_parse_params(char **params)
+bool debug_parse_levels(const char *params_str)
{
- int i, ndx;
+ size_t str_len = strlen(params_str);
+ char str[str_len+1];
+ char *tok, *saveptr;
+ int i;
- if (!params)
- return false;
+ /* Just in case */
+ debug_init();
+
+ memcpy(str, params_str, str_len+1);
+
+ tok = strtok_r(str, LIST_SEP, &saveptr);
+ if (tok == NULL) {
+ return true;
+ }
/* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
* v.s. "all:10", this is the traditional way to set DEBUGLEVEL
*/
- if (isdigit((int)params[0][0])) {
- DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
- i = 1; /* start processing at the next params */
+ if (isdigit(tok[0])) {
+ DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(tok);
+ tok = strtok_r(NULL, LIST_SEP, &saveptr);
} else {
DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
- i = 0; /* DBGC_ALL not specified OR class name was included */
}
/* Array is debug_num_classes long */
- for (ndx = DBGC_ALL; ndx < debug_num_classes; ndx++) {
- DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL_CLASS[DBGC_ALL];
+ for (i = DBGC_ALL+1; i < debug_num_classes; i++) {
+ DEBUGLEVEL_CLASS[i] = DEBUGLEVEL_CLASS[DBGC_ALL];
}
- /* Fill in new debug class levels */
- for (; params[i]; i++) {
+ while (tok != NULL) {
bool ok;
- ok = debug_parse_param(params[i]);
+ ok = debug_parse_param(tok);
if (!ok) {
DEBUG(0,("debug_parse_params: unrecognized debug "
- "class name or format [%s]\n", params[i]));
+ "class name or format [%s]\n", tok));
return false;
}
- }
-
- return true;
-}
-
-/****************************************************************************
- Parse the debug levels from smb.conf. Example debug level string:
- 3 tdb:5 printdrivers:7
- Note: the 1st param has no "name:" preceeding it.
-****************************************************************************/
-
-bool debug_parse_levels(const char *params_str)
-{
- char **params;
- bool ok;
-
- /* Just in case */
- debug_init();
-
- params = str_list_make(NULL, params_str, NULL);
- ok = debug_parse_params(params);
- if (ok) {
- debug_dump_status(5);
+ tok = strtok_r(NULL, LIST_SEP, &saveptr);
}
- TALLOC_FREE(params);
- return ok;
+ debug_dump_status(5);
+
+ return true;
}
/* setup for logging of talloc warnings */
state.logtype = new_logtype;
}
if (prog_name) {
+ const char *p = strrchr(prog_name, '/');
+
+ if (p) {
+ prog_name = p + 1;
+ }
+
state.prog_name = prog_name;
}
reopen_logs_internal();
if (state.logtype == DEBUG_FILE) {
#ifdef WITH_SYSLOG
- const char *p = strrchr(prog_name, '/');
- if (p)
- prog_name = p + 1;
#ifdef LOG_DAEMON
- openlog( prog_name, LOG_PID, SYSLOG_FACILITY );
+ openlog(state.prog_name, LOG_PID, SYSLOG_FACILITY );
#else
/* for old systems that have no facility codes. */
- openlog( prog_name, LOG_PID );
+ openlog(state.prog_name, LOG_PID );
#endif
#endif
}
}
}
+static void debug_callback_log(const char *msg, int msg_level)
+{
+ size_t msg_len = strlen(msg);
+ char msg_copy[msg_len];
+
+ if ((msg_len > 0) && (msg[msg_len-1] == '\n')) {
+ memcpy(msg_copy, msg, msg_len-1);
+ msg_copy[msg_len-1] = '\0';
+ msg = msg_copy;
+ }
+
+ state.callback(state.callback_private, msg_level, msg);
+}
+
/**************************************************************************
reopen the log files
note that we now do this unconditionally
log_overflow = false;
ret = false;
} else {
+ smb_set_close_on_exec(new_fd);
old_fd = state.fd;
state.fd = new_fd;
debug_close_fd(old_fd);
at the logfile. There really isn't much
that can be done on such a fundamental
failure... */
- close_low_fds(false, false, true);
+ close_low_fd(2);
}
}
(void)reopen_logs_internal();
if (state.fd > 2 && (fstat(state.fd, &st) == 0
&& st.st_size > maxlog)) {
- char *name = NULL;
-
- if (asprintf(&name, "%s.old", state.debugf ) < 0) {
- return;
- }
+ char name[strlen(state.debugf) + 5];
+
+ snprintf(name, sizeof(name), "%s.old", state.debugf);
+
(void)rename(state.debugf, name);
-
+
if (!reopen_logs_internal()) {
/* We failed to reopen a log - continue using the old name. */
(void)rename(name, state.debugf);
}
- SAFE_FREE(name);
}
}
*/
int fd = open( "/dev/console", O_WRONLY, 0);
if (fd != -1) {
+ smb_set_close_on_exec(fd);
state.fd = fd;
DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
state.debugf ));
debug_count++;
if (state.logtype == DEBUG_CALLBACK) {
- size_t msg_len = strlen(msg);
- char msg_copy[msg_len];
-
- if ((msg_len > 0) && (msg[msg_len-1] == '\n')) {
- memcpy(msg_copy, msg, msg_len-1);
- msg_copy[msg_len-1] = '\0';
- msg = msg_copy;
- }
-
- state.callback(state.callback_private, current_msg_level, msg);
+ debug_callback_log(msg, current_msg_level);
goto done;
}
if(fd == -1) {
goto done;
}
+ smb_set_close_on_exec(fd);
state.fd = fd;
}
}
#ifdef WITH_SYSLOG
if( current_msg_level < state.settings.syslog ) {
- /* map debug levels to syslog() priorities
- * note that not all DEBUG(0, ...) calls are
- * necessarily errors */
- static const int priority_map[4] = {
- LOG_ERR, /* 0 */
- LOG_WARNING, /* 1 */
- LOG_NOTICE, /* 2 */
- LOG_INFO, /* 3 */
- };
- int priority;
-
- if( current_msg_level >= ARRAY_SIZE(priority_map) || current_msg_level < 0)
- priority = LOG_DEBUG;
- else
- priority = priority_map[current_msg_level];
+ int priority = debug_level_to_priority(current_msg_level);
/*
* Specify the facility to interoperate with other syslog
}
/* If there's room, copy the character to the format buffer. */
- if( format_pos < FORMAT_BUFR_MAX )
+ if (format_pos < FORMAT_BUFR_SIZE - 1)
format_bufr[format_pos++] = msg[i];
/* If a newline is encountered, print & restart. */
/* If the buffer is full dump it out, reset it, and put out a line
* continuation indicator.
*/
- if( format_pos >= FORMAT_BUFR_MAX ) {
+ if (format_pos >= FORMAT_BUFR_SIZE - 1) {
bufr_print();
(void)Debug1( " +>\n" );
}
}
GetTimeOfDay(&tv);
- timeval_str_buf(&tv, state.settings.debug_hires_timestamp, &tvbuf);
+ timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp,
+ &tvbuf);
hs_len = snprintf(header_str, sizeof(header_str), "[%s, %2d",
tvbuf.buf, level);
***************************************************************************/
- bool dbgtext( const char *format_str, ... )
+static inline bool __dbgtext_va(const char *format_str, va_list ap) PRINTF_ATTRIBUTE(1,0);
+static inline bool __dbgtext_va(const char *format_str, va_list ap)
{
- va_list ap;
char *msgbuf = NULL;
bool ret = true;
int res;
- va_start(ap, format_str);
res = vasprintf(&msgbuf, format_str, ap);
- va_end(ap);
-
if (res != -1) {
format_debug_text(msgbuf);
} else {
SAFE_FREE(msgbuf);
return ret;
}
+
+bool dbgtext_va(const char *format_str, va_list ap)
+{
+ return __dbgtext_va(format_str, ap);
+}
+
+bool dbgtext(const char *format_str, ... )
+{
+ va_list ap;
+ bool ret;
+
+ va_start(ap, format_str);
+ ret = __dbgtext_va(format_str, ap);
+ va_end(ap);
+
+ return ret;
+}