UPS: apcupsd clean sources
[tomato.git] / release / src / router / apcupsd / src / lib / apclog.c
blob3cd8d2b07521f1013dda68a8aea3a5a57e6ec477
1 /*
2 * apclog.c
4 * Logging functions.
5 */
7 /*
8 * Copyright (C) 1996-99 Andre M. Hedrick <andre@suse.com>
9 * Copyright (C) 2000-2005 Kern Sibbald <kern@sibbald.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General
13 * Public License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 * MA 02111-1307, USA.
26 #include "apc.h"
28 int format_date(time_t timestamp, char *dest, size_t destlen)
30 struct tm tm;
31 localtime_r(&timestamp, &tm);
33 #ifdef HAVE_WIN32
34 // Annoyingly, Windows does not properly implement %z (it always spells
35 // out the timezone name) so we need to emulate it manually.
36 int len = strftime(dest, destlen, "%Y-%m-%d %H:%M:%S ", &tm);
37 tzset();
38 unsigned int offset = abs(_timezone) / 60;
39 len += snprintf(dest+len, destlen-len, "%c%02u%02u ",
40 _timezone < 0 ? '+' : '-', // _timezone is UTC-local
41 offset/60, offset%60);
42 return len;
43 #else
44 return strftime(dest, destlen, "%Y-%m-%d %H:%M:%S %z ", &tm);
45 #endif
48 void log_event(const UPSINFO *ups, int level, const char *fmt, ...)
50 va_list arg_ptr;
51 char msg[2 *MAXSTRING];
52 char datetime[100];
53 int event_fd;
55 event_fd = ups ? ups->event_fd : -1;
57 va_start(arg_ptr, fmt);
58 avsnprintf(msg, sizeof(msg), fmt, arg_ptr);
59 va_end(arg_ptr);
61 syslog(level, "%s", msg); /* log the event */
62 Dmsg1(100, "%s\n", msg);
64 /* Write out to our temp file. LOG_INFO is DATA logging, so
65 * do not write it to our temp events file. */
66 if (event_fd >= 0 && level != LOG_INFO) {
67 format_date(time(NULL), datetime, sizeof(datetime));
68 write(event_fd, datetime, strlen(datetime));
70 int lm = strlen(msg);
71 if (msg[lm - 1] != '\n')
72 msg[lm++] = '\n';
74 write(event_fd, msg, lm);
79 * Subroutine prints a debug message if the level number
80 * is less than or equal the debug_level. File and line numbers
81 * are included for more detail if desired, but not currently
82 * printed.
84 * If the level is negative, the details of file and line number
85 * are not printed.
88 int debug_level = 0;
89 FILE *trace_fd = NULL;
90 bool trace = false;
92 void logf(const char *fmt, ...)
94 va_list arg_ptr;
95 va_start(arg_ptr, fmt);
97 if (trace) {
98 if (!trace_fd) {
99 char fn[200];
100 asnprintf(fn, sizeof(fn), "./apcupsd.trace");
101 trace_fd = fopen(fn, "a+");
103 if (trace_fd) {
104 vfprintf(trace_fd, fmt, arg_ptr);
105 fflush(trace_fd);
106 } else {
107 /* Some problem, turn off tracing */
108 trace = false;
110 } else { /* not tracing */
111 vfprintf(stdout, fmt, arg_ptr);
112 fflush(stdout);
115 va_end(arg_ptr);
118 #define FULL_LOCATION 1
119 void d_msg(const char *file, int line, int level, const char *fmt, ...)
121 #ifdef DEBUG
122 char buf[4096];
123 int i, diff;
124 va_list arg_ptr;
125 bool details = true;
126 struct timeval now;
127 const char *my_name = "apcupsd";
128 static struct timeval start = {0,0};
130 if (start.tv_sec == 0 && start.tv_usec == 0)
131 gettimeofday(&start, NULL);
133 if (level < 0) {
134 details = false;
135 level = -level;
138 if (level <= debug_level) {
139 #ifdef FULL_LOCATION
140 if (details) {
141 gettimeofday(&now, NULL);
142 diff = TV_DIFF_MS(start, now);
143 asnprintf(buf, sizeof(buf), "%lu.%03lu %s: %s:%d ",
144 diff/1000, diff%1000, my_name, file, line);
145 i = strlen(buf);
146 } else {
147 i = 0;
149 #else
150 i = 0;
151 #endif
152 va_start(arg_ptr, fmt);
153 avsnprintf(buf + i, sizeof(buf) - i, (char *)fmt, arg_ptr);
154 va_end(arg_ptr);
156 logf("%s", buf);
158 #endif
161 void hex_dump(int level, void *data, unsigned int len)
163 unsigned int pos = 0;
164 unsigned char *dat = (unsigned char *)data;
165 char temp[16*3+1];
166 char temp2[8+2+16*3+1+16+1];
167 char *ptr;
169 if (debug_level < level)
170 return;
172 Dmsg2(level, "Dumping %d bytes @ 0x%08x\n", len, data);
173 while (pos < len)
175 int num = MIN(16, len-pos);
176 ptr = temp;
177 for (int i=0; i < num; i++)
178 ptr += sprintf(ptr, "%02x ", dat[pos+i]);
180 ptr = temp2;
181 ptr += sprintf(temp2, "%08x %-48s ", pos, temp);
183 for (int i=0; i < num; i++)
184 ptr += sprintf(ptr, "%c", isgraph(dat[pos+i]) ? dat[pos+i] : '.');
186 Dmsg1(level, "%s\n", temp2);
187 pos += num;