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,
28 int format_date(time_t timestamp
, char *dest
, size_t destlen
)
31 localtime_r(×tamp
, &tm
);
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
);
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);
44 return strftime(dest
, destlen
, "%Y-%m-%d %H:%M:%S %z ", &tm
);
48 void log_event(const UPSINFO
*ups
, int level
, const char *fmt
, ...)
51 char msg
[2 *MAXSTRING
];
55 event_fd
= ups
? ups
->event_fd
: -1;
57 va_start(arg_ptr
, fmt
);
58 avsnprintf(msg
, sizeof(msg
), fmt
, 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
));
71 if (msg
[lm
- 1] != '\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
84 * If the level is negative, the details of file and line number
89 FILE *trace_fd
= NULL
;
92 void logf(const char *fmt
, ...)
95 va_start(arg_ptr
, fmt
);
100 asnprintf(fn
, sizeof(fn
), "./apcupsd.trace");
101 trace_fd
= fopen(fn
, "a+");
104 vfprintf(trace_fd
, fmt
, arg_ptr
);
107 /* Some problem, turn off tracing */
110 } else { /* not tracing */
111 vfprintf(stdout
, fmt
, arg_ptr
);
118 #define FULL_LOCATION 1
119 void d_msg(const char *file
, int line
, int level
, const char *fmt
, ...)
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
);
138 if (level
<= debug_level
) {
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
);
152 va_start(arg_ptr
, fmt
);
153 avsnprintf(buf
+ i
, sizeof(buf
) - i
, (char *)fmt
, arg_ptr
);
161 void hex_dump(int level
, void *data
, unsigned int len
)
163 unsigned int pos
= 0;
164 unsigned char *dat
= (unsigned char *)data
;
166 char temp2
[8+2+16*3+1+16+1];
169 if (debug_level
< level
)
172 Dmsg2(level
, "Dumping %d bytes @ 0x%08x\n", len
, data
);
175 int num
= MIN(16, len
-pos
);
177 for (int i
=0; i
< num
; i
++)
178 ptr
+= sprintf(ptr
, "%02x ", dat
[pos
+i
]);
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
);