1 /* This file is part of gacopyz.
2 Copyright (C) 2006-2021 Sergey Poznyakoff
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <gacopyz_priv.h>
18
19 void (*__gacopyz_log_printer)(int, char *, va_list) =
20 gacopyz_syslog_log_printer;
21
22 /* Logging */
23 void
gacopyz_syslog_log_printer(int level,char * fmt,va_list ap)24 gacopyz_syslog_log_printer(int level, char *fmt, va_list ap)
25 {
26 switch (level) {
27 case SMI_LOG_PROTO:
28 case SMI_LOG_DEBUG:
29 level = LOG_DEBUG;
30 break;
31 case SMI_LOG_INFO:
32 level = LOG_INFO;
33 break;
34 case SMI_LOG_WARN:
35 level = LOG_WARNING;
36 break;
37 case SMI_LOG_ERR:
38 level = LOG_ERR;
39 break;
40
41 case SMI_LOG_FATAL:
42 default:
43 level = LOG_EMERG;
44 }
45 vsyslog(level, fmt, ap); /* FIXME: if absent? */
46 }
47
48 static char *level_name[] = {
49 "PROTO",
50 "DEBUG",
51 "INFO",
52 "WARN",
53 "ERR",
54 "FATAL"
55 };
56
57 int
gacopyz_string_to_log_level(const char * str)58 gacopyz_string_to_log_level(const char *str)
59 {
60 int i;
61 for (i = 0; i < sizeof level_name / sizeof level_name[0]; i++)
62 if (strcasecmp (str, level_name[i]) == 0)
63 return i;
64 return -1;
65 }
66
67 const char *
gacopyz_log_level_to_string(int level)68 gacopyz_log_level_to_string(int level)
69 {
70 if (level < 0 || level > sizeof level_name / sizeof level_name[0])
71 return NULL;
72 return level_name[level];
73 }
74
75 void
gacopyz_stderr_log_printer(int level,char * fmt,va_list ap)76 gacopyz_stderr_log_printer(int level, char *fmt, va_list ap)
77 {
78 fprintf(stderr, "Gacopyz %s: ", gacopyz_log_level_to_string(level));
79 vfprintf(stderr, fmt, ap);
80 fprintf(stderr, "\n");
81 }
82
83
84 void
gacopyz_log(int level,char * fmt,...)85 gacopyz_log(int level, char *fmt, ...)
86 {
87 va_list ap;
88 va_start(ap, fmt);
89 __gacopyz_log_printer(level, fmt, ap);
90 va_end(ap);
91 }
92
93 void
gacopyz_io_log(gacopyz_iod_t iod,int level,char * fmt,...)94 gacopyz_io_log(gacopyz_iod_t iod, int level, char *fmt, ...)
95 {
96 if (iod->logmask & SMI_LOG_MASK(level)) {
97 va_list ap;
98 va_start(ap, fmt);
99 __gacopyz_log_printer(level, fmt, ap);
100 va_end(ap);
101 }
102 }
103
104 size_t
gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE],const char * buf,size_t size)105 gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf, size_t size)
106 {
107 char *p = vbuf;
108 char *q = vbuf + 51;
109 int i;
110 size_t j = 0;
111
112 for (i = 0; i < 16; i++) {
113 unsigned c;
114 if (j < size) {
115 c = *(const unsigned char*)buf++;
116 j++;
117 } else
118 c = 0;
119 sprintf(p, "%02X ", c);
120 p += 3;
121 *q++ = isprint(c) ? c : '.';
122 if (i == 7) {
123 *p++ = ' ';
124 *q++ = ' ';
125 }
126 }
127 *p++ = ' ';
128 *p = ' ';
129 *q = 0;
130 return j;
131 }
132
133 void
gacopyz_logdump(int level,const char * pfx,const char * buf,size_t size)134 gacopyz_logdump(int level, const char *pfx, const char *buf, size_t size)
135 {
136 char vbuf[GACOPYZ_VBUFSIZE];
137
138 while (size) {
139 size_t rd = gacopyz_format_vbuf(vbuf, buf, size);
140 gacopyz_log(level, "%s: %s", pfx, vbuf);
141 size -= rd;
142 buf += rd;
143 }
144 }
145
146 void
gacopyz_io_logdump(gacopyz_iod_t iod,const char * pfx,const char * buf,size_t size)147 gacopyz_io_logdump(gacopyz_iod_t iod, const char *pfx,
148 const char *buf, size_t size)
149 {
150 if (iod->logmask & SMI_LOG_MASK(SMI_LOG_PROTO))
151 gacopyz_logdump(SMI_LOG_PROTO, pfx, buf, size);
152 else if (iod->logmask & SMI_LOG_MASK(SMI_LOG_DEBUG))
153 gacopyz_log(SMI_LOG_DEBUG, "%s", pfx);
154 }
155
156 void
gacopyz_set_logger(void (* logger)(int,char *,va_list))157 gacopyz_set_logger(void (*logger)(int, char *, va_list))
158 {
159 __gacopyz_log_printer = logger;
160 }
161