GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||
GeezerVison is showing lirc.org — LIRC libraries: /home/columbus/software/lirc-doc/lib/lirc_log.c (2bf1f3f 2016-12-21 11:58:02 +0100) Source File
AllClassesFilesFunctionsVariablesTypedefsEnumerationsMacrosModulesPages
lirc_log.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** lircd.c *****************************************************************
3 ****************************************************************************
4 *
5 * lirc_log - simple logging module.
6 *
7 *
8 */
9
16 #ifdef HAVE_CONFIG_H
17 # include <config.h>
18 #endif
19
20
21 #include <errno.h>
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <time.h>
28 #include <pwd.h>
29 #include <unistd.h>
30 #include <limits.h>
31 #include <ctype.h>
32 #include <syslog.h>
33
34 #include "lirc/lirc_log.h"
35
36 #ifndef min
37 #define min(a, b) (a < b ? a : b)
38 #endif
39
40 #define HOSTNAME_LEN 128
41
43
44 char hostname[HOSTNAME_LEN + 1];
45 FILE* lf = NULL;
46
48
50
51 static int use_syslog = 1;
52
53 const char* syslogident = "lircd-" VERSION;
54 const char* logfile = "syslog";
55
56 char progname[128] = { '?', '\0' };
57 static int nodaemon = 0;
58
59 static const int PRIO_LEN = 16;
62 static const char* prio2text(int prio)
63 {
64 switch (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)";
74 }
75 }
76
77
79 {
80 return use_syslog;
81 }
82
83
85 {
86 if (strcmp(s, "syslog") == 0) {
87 use_syslog = 1;
88 } else {
89 logfile = s;
90 use_syslog = 0;
91 }
92 }
93
94
96 {
97 strncpy(progname, _progname, sizeof(progname));
98 nodaemon = _nodaemon;
99 loglevel = level;
100 struct passwd* pw;
101 const char* user;
102
103 if (use_syslog) {
104 if (nodaemon)
105 openlog(syslogident, LOG_CONS | LOG_PID | LOG_PERROR, LOG_LOCAL0);
106 else
107 openlog(syslogident, LOG_CONS | LOG_PID, LOG_LOCAL0);
108 } else {
109 lf = fopen(logfile, "a");
110 if (lf == NULL) {
111 fprintf(stderr, "%s: could not open logfile \"%s\"\n",
112 progname, logfile);
113 perror(progname);
114 return 1;
115 }
116 if (getenv("SUDO_USER") != NULL && geteuid() == 0) {
117 user = getenv("SUDO_USER");
118 user = user == NULL ? "root" : user;
119 pw = getpwnam(user);
120 if (chown(logfile, pw->pw_uid, pw->pw_gid) == -1)
121 perror("Cannot reset log file owner.");
122 }
123 gethostname(hostname, HOSTNAME_LEN);
125 }
126 if (getenv("LIRC_LOGCHANNEL") != NULL) {
128 }
129 if (level != LIRC_NOLOG) {
131 _progname, prio2text(level));
132 }
133 return 0;
134 }
135
136
138 {
139 if (use_syslog) {
140 closelog();
141 return 0;
142 } else if (lf) {
143 return fclose(lf);
144 } else {
145 return 0;
146 }
147 }
148
149
150 int lirc_log_reopen(void)
151 {
152 struct stat s;
153
154 if (use_syslog)
155 /* Don't need to do anything; this is syslogd's task */
156 return 0;
157
159 if (-1 == fstat(fileno(lf), &s)) {
160 perror("Invalid logfile!");
161 return -1;
162 }
163 fclose(lf);
164 lf = fopen(logfile, "a");
165 if (lf == NULL) {
166 /* can't print any error messagees */
167 perror("Can't open logfile");
168 return -1;
169 }
171 if (-1 == fchmod(fileno(lf), s.st_mode)) {
173 logperror(LIRC_WARNING, NULL);
174 }
175 return 0;
176 }
177
178
180 {
182 loglevel = level;
183 return 1;
184 } else {
185 return 0;
186 }
187 }
188
189
191 {
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 },
201 { 0, 0 }
202 };
203
204 char label[128];
205 int i;
206
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]);
211 label[i] = '\0';
212 i = 0;
213 while (options[i].label && strcmp(options[i].label, label) != 0)
214 i += 1;
215 return options[i].label ? options[i].value : -1;
216 }
217
218
220 // Try to parse LIRC_LOGLEVEL in environment, fall back to DEFAULT_LOGLEVEL.
221 {
223 const char* const level = getenv("LIRC_LOGLEVEL");
224
225 if (level != NULL) {
228 } else {
230 }
231 }
232
233
235 {
236 long level = LONG_MAX;
237
238 if (s == NULL || *s == '\0')
239 return LIRC_BADLEVEL;
240 while (isspace(*s) && *s)
241 s++;
242 if (isdigit(*s)) {
243 level = strtol(s, NULL, 10);
245 return LIRC_BADLEVEL;
246 else
247 return level;
248 } else {
249 return symbol2loglevel(s);
250 }
251 }
252
253
255 {
256 char buff[256];
257 va_list ap;
258
259 va_start(ap, format);
260 vsnprintf(buff, sizeof(buff), format, ap);
261 va_end(ap);
262 perror(buff);
263 }
264
265
274 {
275 int save_errno = errno;
276 va_list ap;
277 char buff[PRIO_LEN + strlen(format_str)];
278
279 if (use_syslog) {
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);
284 va_end(ap);
285 } else if (lf) {
286 char* currents;
287 struct timeval tv;
288 struct timezone tz;
289
290 gettimeofday(&tv, &tz);
291 currents = ctime(&tv.tv_sec);
292
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);
298 va_end(ap);
299 fputc('\n', lf);
300 fflush(lf);
301 }
302 errno = save_errno;
303 }
304
311 {
312 char s[256];
313 va_list ap;
314
315 va_start(ap, fmt);
316 vsnprintf(s, sizeof(s), fmt, ap);
317 va_end(ap);
318 if (use_syslog) {
319 if (*s != '\0')
320 syslog(min(7, prio), "%s: %m\n", s);
321 else
322 syslog(min(7, prio), "%m\n");
323 } else {
324 if (*s != '\0')
326 else
328 }
329 }
330
331
333 {
334 const char* home;
335 struct passwd* pw;
336 const char* user;
337 int r;
338
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");
344 if (user == NULL)
345 user = "root";
346 pw = getpwnam(user);
347 snprintf(buffer, size, "%s/.cache", pw->pw_dir);
348 } else {
349 home = getenv("HOME");
350 home = home != NULL ? home : "/tmp";
351 snprintf(buffer, size, "%s/.cache", home);
352 }
353 if (access(buffer, F_OK) != 0) {
354 r = mkdir(buffer, 0777);
355 if (r != 0) {
356 syslog(LOG_WARNING,
357 "Cannot create log directory %s", buffer);
358 syslog(LOG_WARNING, "Falling back to using /tmp");
359 strcpy(buffer, "/tmp");
360 }
361 }
362 strncat(buffer, "/", size - strlen(buffer) - 1);
363 strncat(buffer, basename, size - strlen(buffer) - 1);
364 strncat(buffer, ".log", size - strlen(buffer) - 1);
365 return 0;
366 }
367
368
370 // Dump a byte array as hex code, adding a prefix.
371 {
372 int i;
373 char str[1024];
374 int pos = 0;
375
376 if (prefix != NULL) {
377 strncpy(str, prefix, sizeof(str));
378 pos = strnlen(str, sizeof(str));
379 }
380 if (len > 0) {
381 for (i = 0; i < len; i++) {
382 if (pos + 3 >= sizeof(str))
383 break;
384
385 if (!(i % 8))
386 str[pos++] = ' ';
387
388 sprintf(str + pos, "%02x ", buf[i]);
389
390 pos += 3;
391 }
392 } else {
393 strncpy(str + pos, "NO DATA", sizeof(str));
394 }
396 }
int lirc_log_open(const char *_progname, int _nodaemon, loglevel_t level) Open the log for upcoming logging. Definition: lirc_log.c:95 int lirc_log_close(void) Close the log previosly opened with lirc_log_open(). Definition: lirc_log.c:137 void hexdump(char *prefix, unsigned char *buf, int len) Print prefix + a hex dump of len bytes starting at *buf. Definition: lirc_log.c:369 loglevel_t lirc_log_defaultlevel(void) Get the default level, from environment or hardcoded. Definition: lirc_log.c:219 void logperror(loglevel_t prio, const char *fmt,...) Prints a description of the last error to the log. Definition: lirc_log.c:310 int lirc_log_get_clientlog(const char *basename, char *buffer, ssize_t size) Retrieve a client path for logging according to freedesktop specs. Definition: lirc_log.c:332 loglevel_t string2loglevel(const char *s) Convert a string, either a number or 'info', 'trace1', error etc. Definition: lirc_log.c:234 void logprintf(loglevel_t prio, const char *format_str,...) Write a message to the log. Definition: lirc_log.c:273 void perrorf(const char *format,...) Adds printf-style arguments to perror(3). Definition: lirc_log.c:254
| ||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |