/src/p11-kit/common/message.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2011 Collabora Ltd |
3 | | * Copyright (c) 2012 Stef Walter |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * |
9 | | * * Redistributions of source code must retain the above |
10 | | * copyright notice, this list of conditions and the |
11 | | * following disclaimer. |
12 | | * * Redistributions in binary form must reproduce the |
13 | | * above copyright notice, this list of conditions and |
14 | | * the following disclaimer in the documentation and/or |
15 | | * other materials provided with the distribution. |
16 | | * * The names of contributors to this software may not be |
17 | | * used to endorse or promote products derived from this |
18 | | * software without specific prior written permission. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
23 | | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
24 | | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
25 | | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
26 | | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
27 | | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
28 | | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
29 | | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF |
30 | | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
31 | | * DAMAGE. |
32 | | * |
33 | | * |
34 | | * CONTRIBUTORS |
35 | | * Stef Walter <stef@thewalter.net> |
36 | | */ |
37 | | |
38 | | #include "config.h" |
39 | | |
40 | | /* |
41 | | * Oh god. glibc is nasty. Changes behavior and definitions of POSIX |
42 | | * functions to completely different signatures depending on defines |
43 | | */ |
44 | | #define _POSIX_C_SOURCE 200112L |
45 | | |
46 | | #include "compat.h" |
47 | | #define P11_DEBUG_FLAG P11_DEBUG_LIB |
48 | | #include "debug.h" |
49 | | #include "message.h" |
50 | | |
51 | | #include <assert.h> |
52 | | #include <errno.h> |
53 | | #ifdef HAVE_LOCALE_H |
54 | | #include <locale.h> |
55 | | #endif |
56 | | #include <stdarg.h> |
57 | | #include <stdlib.h> |
58 | | #include <stdio.h> |
59 | | #include <string.h> |
60 | | |
61 | | bool p11_print_messages = false; |
62 | | |
63 | | #ifdef HAVE_STRERROR_L |
64 | | locale_t p11_message_locale = (locale_t) 0; |
65 | | #endif |
66 | | |
67 | | static char * |
68 | | default_message_storage (void) |
69 | 0 | { |
70 | 0 | static char message[P11_MESSAGE_MAX] = { 0, }; |
71 | 0 | return message; |
72 | 0 | } |
73 | | |
74 | | /* Function pointer declared in message.h as extern */ |
75 | | char * (* p11_message_storage) (void) = default_message_storage; |
76 | | |
77 | | void |
78 | | p11_message_store (const char* msg, |
79 | | size_t length) |
80 | 16 | { |
81 | 16 | char *buffer; |
82 | | |
83 | | /* |
84 | | * p11_message_storage() is called to get a storage location for |
85 | | * the last message. It defaults to a globally allocated buffer |
86 | | * but is overridden in library.c with a function that returns |
87 | | * per thread buffers. |
88 | | * |
89 | | * The returned value is P11_MESSAGE_MAX bytes long |
90 | | */ |
91 | 16 | buffer = p11_message_storage (); |
92 | | |
93 | 16 | if (length > P11_MESSAGE_MAX - 1) |
94 | 0 | length = P11_MESSAGE_MAX - 1; |
95 | | |
96 | 16 | if (buffer != NULL) { |
97 | 16 | memcpy (buffer, msg, length); |
98 | 16 | buffer[length] = 0; |
99 | 16 | } |
100 | 16 | } |
101 | | |
102 | | void |
103 | | p11_message_err (int errnum, |
104 | | const char* msg, |
105 | | ...) |
106 | 0 | { |
107 | 0 | char buffer[P11_MESSAGE_MAX]; |
108 | 0 | char strerr[P11_MESSAGE_MAX]; |
109 | 0 | va_list va; |
110 | 0 | size_t length; |
111 | |
|
112 | 0 | va_start (va, msg); |
113 | 0 | length = vsnprintf (buffer, P11_MESSAGE_MAX - 1, msg, va); |
114 | 0 | va_end (va); |
115 | | |
116 | | /* Was it truncated? */ |
117 | 0 | if (length > P11_MESSAGE_MAX - 1) |
118 | 0 | length = P11_MESSAGE_MAX - 1; |
119 | 0 | buffer[length] = 0; |
120 | |
|
121 | 0 | snprintf (strerr, sizeof (strerr), "Unknown error %d", errnum); |
122 | 0 | #ifdef HAVE_STRERROR_L |
123 | 0 | if (p11_message_locale != (locale_t) 0) |
124 | 0 | strncpy (strerr, strerror_l (errnum, p11_message_locale), sizeof (strerr)); |
125 | | #else |
126 | | strerror_r (errnum, strerr, sizeof (strerr)); |
127 | | #endif |
128 | 0 | strerr[P11_MESSAGE_MAX - 1] = 0; |
129 | |
|
130 | 0 | p11_message ("%s: %s", buffer, strerr); |
131 | 0 | } |
132 | | |
133 | | void |
134 | | p11_message (const char* msg, |
135 | | ...) |
136 | 16 | { |
137 | 16 | char buffer[P11_MESSAGE_MAX]; |
138 | 16 | va_list va; |
139 | 16 | size_t length; |
140 | | |
141 | 16 | va_start (va, msg); |
142 | 16 | length = vsnprintf (buffer, P11_MESSAGE_MAX - 1, msg, va); |
143 | 16 | va_end (va); |
144 | | |
145 | | /* Was it truncated? */ |
146 | 16 | if (length > P11_MESSAGE_MAX - 1) |
147 | 0 | length = P11_MESSAGE_MAX - 1; |
148 | 16 | buffer[length] = 0; |
149 | | |
150 | | /* If printing is not disabled, just print out */ |
151 | 16 | if (p11_print_messages) |
152 | 0 | fprintf (stderr, "p11-kit: %s\n", buffer); |
153 | 16 | else |
154 | 16 | p11_debug_message (P11_DEBUG_LIB, "message: %s", buffer); |
155 | 16 | p11_message_store (buffer, length); |
156 | 16 | } |
157 | | |
158 | | void |
159 | | p11_message_quiet (void) |
160 | 0 | { |
161 | 0 | p11_print_messages = false; |
162 | 0 | } |
163 | | |
164 | | void |
165 | | p11_message_loud (void) |
166 | 0 | { |
167 | 0 | p11_print_messages = true; |
168 | 0 | } |
169 | | |
170 | | const char * |
171 | | p11_message_last (void) |
172 | 0 | { |
173 | 0 | char *buffer; |
174 | 0 | buffer = p11_message_storage (); |
175 | 0 | return buffer && buffer[0] ? buffer : NULL; |
176 | 0 | } |
177 | | |
178 | | void |
179 | | p11_message_clear (void) |
180 | 32 | { |
181 | 32 | char *buffer; |
182 | 32 | buffer = p11_message_storage (); |
183 | 32 | if (buffer != NULL) |
184 | 32 | buffer[0] = 0; |
185 | 32 | } |