34 #include "lirc/lirc_log.h" 
   37 #define min(a, b) (a < b ? a : b) 
   40 #define HOSTNAME_LEN 128 
   44 char hostname[HOSTNAME_LEN + 1];
 
   51 static int use_syslog = 1;
 
   53 const char* syslogident = 
"lircd-" VERSION;
 
   54 const char* logfile = 
"syslog";
 
   56 char progname[128] = { 
'?', 
'\0' };
 
   57 static int nodaemon = 0;
 
   59 static const int PRIO_LEN = 16; 
 
   62 static const char* prio2text(
int prio)
 
   65         case LIRC_DEBUG:        
return "Debug";
 
   66         case LIRC_NOTICE:       
return "Notice";
 
   67         case LIRC_INFO:         
return "Info";
 
   68         case LIRC_WARNING:      
return "Warning";
 
   69         case LIRC_ERROR:        
return "Error";
 
   70         case LIRC_TRACE:        
return "Trace";
 
   71         case LIRC_TRACE1:       
return "Trace1";
 
   72         case LIRC_TRACE2:       
return "Trace2";
 
   73         default:                
return "(Bad prio)";
 
   86         if (strcmp(s, 
"syslog") == 0) {
 
   97         strncpy(progname, _progname, 
sizeof(progname));
 
  105                         openlog(syslogident, LOG_PID | LOG_PERROR, LOG_LOCAL0);
 
  107                         openlog(syslogident, LOG_PID, LOG_LOCAL0);
 
  109                 lf = fopen(logfile, 
"a");
 
  111                         fprintf(stderr, 
"%s: could not open logfile \"%s\"\n",
 
  116                 if (getenv(
"SUDO_USER") != NULL && geteuid() == 0) {
 
  117                         user = getenv(
"SUDO_USER");
 
  118                         user = user == NULL ? 
"root" : user;
 
  120                         if (chown(logfile, pw->pw_uid, pw->pw_gid) == -1)
 
  121                                 perror(
"Cannot reset log file owner.");
 
  123                 gethostname(hostname, HOSTNAME_LEN);
 
  124                 log_warn(
"------------------------ Log re-opened ----------------------------");
 
  126         if (getenv(
"LIRC_LOGCHANNEL") != NULL) {
 
  129         if (level != LIRC_NOLOG) {
 
  130                 logprintf(level, 
"%s:  Opening log, level: %s",
 
  131                           _progname, prio2text(level));
 
  150 int lirc_log_reopen(
void)
 
  159         if (-1 == fstat(fileno(lf), &s)) {
 
  160                 perror(
"Invalid logfile!");
 
  164         lf = fopen(logfile, 
"a");
 
  167                 perror(
"Can't open logfile");
 
  171         if (-1 == fchmod(fileno(lf), s.st_mode)) {
 
  172                 log_warn(
"could not set file permissions");
 
  190 static loglevel_t symbol2loglevel(
const char* levelstring)
 
  192         static const struct { 
const char* label; 
int value; } options[] = {
 
  193                 { 
"TRACE2",  LIRC_TRACE2  },
 
  194                 { 
"TRACE1",  LIRC_TRACE1  },
 
  195                 { 
"TRACE",   LIRC_TRACE   },
 
  196                 { 
"DEBUG",   LIRC_DEBUG   },
 
  197                 { 
"INFO",    LIRC_INFO    },
 
  198                 { 
"NOTICE",  LIRC_NOTICE  },
 
  199                 { 
"WARNING", LIRC_WARNING },
 
  200                 { 
"ERROR",   LIRC_ERROR   },
 
  207         if (levelstring == NULL || !*levelstring)
 
  208                 return LIRC_BADLEVEL;
 
  209         for (i = 0; i < 
sizeof(label) && levelstring[i]; i += 1)
 
  210                 label[i] = toupper(levelstring[i]);
 
  213         while (options[i].label && strcmp(options[i].label, label) != 0)
 
  215         return options[i].label ? options[i].value : -1;
 
  223         const char* 
const level = getenv(
"LIRC_LOGLEVEL");
 
  236         long level = LONG_MAX;
 
  238         if (s == NULL || *s == 
'\0')
 
  239                 return LIRC_BADLEVEL;
 
  240         while (isspace(*s) && *s)
 
  243                 level = strtol(s, NULL, 10);
 
  245                         return LIRC_BADLEVEL;
 
  249                 return symbol2loglevel(s);
 
  259         va_start(ap, format);
 
  260         vsnprintf(buff, 
sizeof(buff), format, ap);
 
  275         int save_errno = errno;
 
  277         char buff[PRIO_LEN + strlen(format_str)];
 
  280                 snprintf(buff, 
sizeof(buff),
 
  281                          "%s: %s", prio2text(prio), format_str);
 
  282                 va_start(ap, format_str);
 
  283                 vsyslog(min(7, prio), buff, ap);
 
  290                 gettimeofday(&tv, &tz);
 
  291                 currents = ctime(&tv.tv_sec);
 
  293                 fprintf(lf, 
"%15.15s.%06ld %s %s: ",
 
  294                         currents + 4, (
long) tv.tv_usec, hostname, progname);
 
  295                 fprintf(lf, 
"%s: ", prio2text(prio));
 
  296                 va_start(ap, format_str);
 
  297                 vfprintf(lf, format_str, ap);
 
  316         vsnprintf(s, 
sizeof(s), fmt, ap);
 
  320                         syslog(min(7, prio), 
"%s: %m\n", s);
 
  322                         syslog(min(7, prio), 
"%m\n");
 
  325                         logprintf(prio, 
"%s: %s", s, strerror(errno));
 
  339         if (getenv(
"XDG_CACHE_HOME") != NULL) {
 
  340                 strncpy(buffer, getenv(
"XDG_CACHE_HOME"), size);
 
  341                 buffer[size - 1] = 
'\0';
 
  342         } 
else if (getenv(
"SUDO_USER") != NULL && geteuid() == 0) {
 
  343                 user = getenv(
"SUDO_USER");
 
  347                 snprintf(buffer, size, 
"%s/.cache", pw->pw_dir);
 
  349                 home = getenv(
"HOME");
 
  350                 home = home != NULL ? home : 
"/tmp";
 
  351                 snprintf(buffer, size, 
"%s/.cache", home);
 
  353         if (access(buffer, F_OK) != 0) {
 
  354                 r = mkdir(buffer, 0777);
 
  357                                "Cannot create log directory %s", buffer);
 
  358                         syslog(LOG_WARNING, 
"Falling back to using /tmp");
 
  359                         strcpy(buffer, 
"/tmp");
 
  362         strncat(buffer, 
"/", size - strlen(buffer) - 1);
 
  363         strncat(buffer, basename, size - strlen(buffer) - 1);
 
  364         strncat(buffer, 
".log", size - strlen(buffer) - 1);
 
  369 void hexdump(
char* prefix, 
unsigned char* buf, 
int len)
 
  376         if (prefix != NULL) {
 
  377                 strncpy(str, prefix, 
sizeof(str));
 
  378                 pos = strnlen(str, 
sizeof(str));
 
  381                 for (i = 0; i < len; i++) {
 
  382                         if (pos + 3 >= 
sizeof(str))
 
  388                         sprintf(str + pos, 
"%02x ", buf[i]);
 
  393                 strncpy(str + pos, 
"NO DATA", 
sizeof(str));
 
loglevel_t loglevel
The actual loglevel.
int lirc_log_use_syslog(void)
Check if log is set up to use syslog or not.
void logprintf(loglevel_t prio, const char *format_str,...)
Write a message to the log.
loglevel_t string2loglevel(const char *s)
Convert a string, either a number or 'info', 'trace1', error etc.
void lirc_log_set_file(const char *s)
Set logfile.
void hexdump(char *prefix, unsigned char *buf, int len)
Print prefix + a hex dump of len bytes starting at *buf.
int lirc_log_open(const char *_progname, int _nodaemon, loglevel_t level)
Open the log for upcoming logging.
int lirc_log_setlevel(loglevel_t level)
Set the level.
int lirc_log_get_clientlog(const char *basename, char *buffer, ssize_t size)
Retrieve a client path for logging according to freedesktop specs.
logchannel_t logged_channels
The actual logchannel.
void perrorf(const char *format,...)
Adds printf-style arguments to perror(3).
int lirc_log_close(void)
Close the log previosly opened with lirc_log_open().
loglevel_t lirc_log_defaultlevel(void)
Get the default level, from environment or hardcoded.
void logperror(loglevel_t prio, const char *fmt,...)
Prints a description of the last error to the log.
#define log_trace(fmt,...)
Log a trace message.
loglevel_t
The defined loglevels.
#define log_info(fmt,...)
Log an info message.
#define LIRC_MIN_LOGLEVEL
Mix loglevel (for validation).
#define LIRC_MAX_LOGLEVEL
Max loglevel (for validation).
logchannel_t
Log channels used to filter messages.
#define DEFAULT_LOGLEVEL
Default loglevel (last resort).
#define log_warn(fmt,...)
Log a warning message.