1 /*
2 * Copyright (c) 2011 Collabora Ltd.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
11 * * Redistributions in binary form must reproduce the
12 * above copyright notice, this list of conditions and
13 * the following disclaimer in the documentation and/or
14 * other materials provided with the distribution.
15 * * The names of contributors to this software may not be
16 * used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30 * DAMAGE.
31 *
32 *
33 * CONTRIBUTORS
34 * Stef Walter <stef@memberwebs.com>
35 */
36
37 #include "config.h"
38
39 #include "compat.h"
40 #include "debug.h"
41
42 #include <assert.h>
43 #ifdef HAVE_LOCALE_H
44 #include <locale.h>
45 #endif
46 #include <stdio.h>
47 #include <stdarg.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <unistd.h>
51
52 #define P11_DEBUG_MESSAGE_MAX 512
53
54 struct DebugKey {
55 const char *name;
56 int value;
57 };
58
59 static struct DebugKey debug_keys[] = {
60 { "lib", P11_DEBUG_LIB },
61 { "conf", P11_DEBUG_CONF },
62 { "uri", P11_DEBUG_URI },
63 { "proxy", P11_DEBUG_PROXY },
64 { "trust", P11_DEBUG_TRUST },
65 { "tool", P11_DEBUG_TOOL },
66 { "rpc", P11_DEBUG_RPC },
67 { 0, }
68 };
69
70 static bool debug_strict = false;
71
72 /* global variable exported in debug.h */
73 int p11_debug_current_flags = ~0;
74
75 #ifdef HAVE_STRERROR_L
76 extern locale_t p11_message_locale;
77 #endif
78
79 static int
parse_environ_flags(void)80 parse_environ_flags (void)
81 {
82 const char *env;
83 int result = 0;
84 const char *p;
85 const char *q;
86 int i;
87
88 env = secure_getenv ("P11_KIT_STRICT");
89 if (env && env[0] != '\0')
90 debug_strict = true;
91
92 env = getenv ("P11_KIT_DEBUG");
93 if (!env)
94 return 0;
95
96 if (strcmp (env, "all") == 0) {
97 for (i = 0; debug_keys[i].name; i++)
98 result |= debug_keys[i].value;
99
100 } else if (strcmp (env, "help") == 0) {
101 fprintf (stderr, "Supported debug values:");
102 for (i = 0; debug_keys[i].name; i++)
103 fprintf (stderr, " %s", debug_keys[i].name);
104 fprintf (stderr, "\n");
105
106 } else {
107 p = env;
108 while (*p) {
109 q = strpbrk (p, ":;, \t");
110 if (!q)
111 q = p + strlen (p);
112
113 for (i = 0; debug_keys[i].name; i++) {
114 if (q - p == strlen (debug_keys[i].name) &&
115 strncmp (debug_keys[i].name, p, q - p) == 0)
116 result |= debug_keys[i].value;
117 }
118
119 p = q;
120 if (*p)
121 p++;
122 }
123 }
124
125 return result;
126 }
127
128 void
p11_debug_init(void)129 p11_debug_init (void)
130 {
131 p11_debug_current_flags = parse_environ_flags ();
132 }
133
134 void
p11_debug_message(int flag,const char * format,...)135 p11_debug_message (int flag,
136 const char *format, ...)
137 {
138 va_list args;
139
140 if (flag & p11_debug_current_flags) {
141 fprintf (stderr, "(p11-kit:%d) ", getpid());
142 va_start (args, format);
143 vfprintf (stderr, format, args);
144 va_end (args);
145 fprintf (stderr, "\n");
146 }
147 }
148
149 void
p11_debug_message_err(int flag,int errnum,const char * format,...)150 p11_debug_message_err (int flag,
151 int errnum,
152 const char *format, ...)
153 {
154 va_list args;
155 char strerr[P11_DEBUG_MESSAGE_MAX];
156
157 if (flag & p11_debug_current_flags) {
158 fprintf (stderr, "(p11-kit:%d) ", getpid());
159 va_start (args, format);
160 vfprintf (stderr, format, args);
161 va_end (args);
162
163 snprintf (strerr, sizeof (strerr), "Unknown error %d", errnum);
164 #ifdef HAVE_STRERROR_L
165 if (p11_message_locale != (locale_t) 0)
166 strncpy (strerr, strerror_l (errnum, p11_message_locale), sizeof (strerr));
167 #else
168 strerror_r (errnum, strerr, sizeof (strerr));
169 #endif
170 strerr[P11_DEBUG_MESSAGE_MAX - 1] = 0;
171 fprintf (stderr, ": %s\n", strerr);
172 }
173 }
174
175 void
p11_debug_precond(const char * format,...)176 p11_debug_precond (const char *format,
177 ...)
178 {
179 va_list va;
180
181 va_start (va, format);
182 vfprintf (stderr, format, va);
183 va_end (va);
184
185 #ifdef __COVERITY__
186 fprintf (stderr, "ignoring P11_KIT_STRICT under coverity: %d", (int)debug_strict);
187 #else
188 if (debug_strict)
189 #endif
190 abort ();
191 }
192