+#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
+ struct syslog_data sdata = SYSLOG_DATA_INIT;
+#endif
+ char msgbuf[MSGBUFSIZ];
+ char fmtbuf[MSGBUFSIZ];
+ char *txt = NULL;
+ int pri = LOG_INFO;
+ int saved_errno = errno;
+
+ if (level > log_level)
+ return;
+
+ switch (level) {
+ case SYSLOG_LEVEL_FATAL:
+ if (!log_on_stderr)
+ txt = "fatal";
+ pri = LOG_CRIT;
+ break;
+ case SYSLOG_LEVEL_ERROR:
+ if (!log_on_stderr)
+ txt = "error";
+ pri = LOG_ERR;
+ break;
+ case SYSLOG_LEVEL_INFO:
+ pri = LOG_INFO;
+ break;
+ case SYSLOG_LEVEL_VERBOSE:
+ pri = LOG_INFO;
+ break;
+ case SYSLOG_LEVEL_DEBUG1:
+ txt = "debug1";
+ pri = LOG_DEBUG;
+ break;
+ case SYSLOG_LEVEL_DEBUG2:
+ txt = "debug2";
+ pri = LOG_DEBUG;
+ break;
+ case SYSLOG_LEVEL_DEBUG3:
+ txt = "debug3";
+ pri = LOG_DEBUG;
+ break;
+ default:
+ txt = "internal error";
+ pri = LOG_ERR;
+ break;
+ }
+ if (txt != NULL) {
+ snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
+ vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
+ } else {
+ vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
+ }
+ strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
+ log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
+ if (log_on_stderr) {
+ snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
+ write(STDERR_FILENO, msgbuf, strlen(msgbuf));
+ } else {
+#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
+ openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
+ syslog_r(pri, &sdata, "%.500s", fmtbuf);
+ closelog_r(&sdata);
+#else
+ openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
+ syslog(pri, "%.500s", fmtbuf);
+ closelog();
+#endif
+ }
+ errno = saved_errno;