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_CONS | LOG_PID | LOG_PERROR, LOG_LOCAL0);
   107                         openlog(syslogident, LOG_CONS | 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));
 #define LIRC_MAX_LOGLEVEL
Max loglevel (for validation). 
loglevel_t loglevel
The actual loglevel. 
int lirc_log_open(const char *_progname, int _nodaemon, loglevel_t level)
Open the log for upcoming logging. 
#define log_warn(fmt,...)
Log a warning message. 
logchannel_t
Log channels used to filter messages. 
int lirc_log_close(void)
Close the log previosly opened with lirc_log_open(). 
loglevel_t
The defined loglevels. 
void lirc_log_set_file(const char *s)
Set logfile. 
int lirc_log_use_syslog(void)
Check if log is set up to use syslog or not. 
#define log_trace(fmt,...)
Log a trace message. 
logchannel_t logged_channels
The actual logchannel. 
#define LIRC_MIN_LOGLEVEL
Mix loglevel (for validation). 
#define DEFAULT_LOGLEVEL
Default loglevel (last resort). 
int lirc_log_setlevel(loglevel_t level)
Set the level. 
void hexdump(char *prefix, unsigned char *buf, int len)
Print prefix + a hex dump of len bytes starting at *buf. 
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. 
int lirc_log_get_clientlog(const char *basename, char *buffer, ssize_t size)
Retrieve a client path for logging according to freedesktop specs. 
loglevel_t string2loglevel(const char *s)
Convert a string, either a number or 'info', 'trace1', error etc. 
#define log_info(fmt,...)
Log an info message. 
void logprintf(loglevel_t prio, const char *format_str,...)
Write a message to the log. 
void perrorf(const char *format,...)
Adds printf-style arguments to perror(3).