71c6003713ed15fae3d91b5427db69ce66c15408
[libgcrypt.git] / src / misc.c
1 /* misc.c
2  * Copyright (C) 1999, 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <unistd.h>
26
27 #include "g10lib.h"
28 #include "secmem.h"
29
30 static int verbosity_level = 0;
31
32 static void (*fatal_error_handler)(void*,int, const char*) = NULL;
33 static void *fatal_error_handler_value = 0;
34 static void (*log_handler)(void*,int, const char*, va_list) = NULL;
35 static void *log_handler_value = 0;
36
37 static const char *(*user_gettext_handler)( const char * ) = NULL;
38
39 void
40 gcry_set_gettext_handler( const char *(*f)(const char*) )
41 {
42     user_gettext_handler = f;
43 }
44
45
46 const char *
47 _gcry_gettext( const char *key )
48 {
49     if( user_gettext_handler )
50         return user_gettext_handler( key );
51     /* FIXME: switch the domain to gnupg and restore later */
52     return key;
53 }
54
55 void
56 gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
57 {
58     fatal_error_handler_value = value;
59     fatal_error_handler = fnc;
60 }
61
62 static void
63 write2stderr( const char *s )
64 {
65     write( 2, s, strlen(s) );
66 }
67
68 /*
69  * This function is called for fatal errors.  A caller might want to
70  * set his own handler because this function simply calls abort().
71  */
72 void
73 _gcry_fatal_error (int rc, const char *text)
74 {
75   if ( !text ) /* get a default text */
76     text = gpg_strerror (rc);
77
78   if (fatal_error_handler && !fips_mode () )
79     fatal_error_handler (fatal_error_handler_value, rc, text);
80
81   fips_signal_fatal_error (text);
82   write2stderr("\nFatal error: ");
83   write2stderr(text);
84   write2stderr("\n");
85   _gcry_secmem_term ();
86   abort ();
87 }
88
89 void
90 gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
91                                                             void *opaque )
92 {
93     log_handler = f;
94     log_handler_value = opaque;
95 }
96
97 void
98 _gcry_set_log_verbosity( int level )
99 {
100     verbosity_level = level;
101 }
102
103 int
104 _gcry_log_verbosity( int level )
105 {
106     return verbosity_level >= level;
107 }
108
109 /****************
110  * This is our log function which prints all log messages to stderr or
111  * using the function defined with gcry_set_log_handler().
112  */
113 static void
114 _gcry_logv( int level, const char *fmt, va_list arg_ptr )
115 {
116   if (log_handler)
117     log_handler (log_handler_value, level, fmt, arg_ptr);
118   else 
119     {
120       switch (level) 
121         {
122         case GCRY_LOG_CONT:  break;
123         case GCRY_LOG_INFO:  break;
124         case GCRY_LOG_WARN:  break;
125         case GCRY_LOG_ERROR: break;
126         case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break;
127         case GCRY_LOG_BUG:   fputs("Ohhhh jeeee: ", stderr); break;
128         case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break;
129         default: fprintf(stderr,"[Unknown log level %d]: ", level ); break;
130         }
131       vfprintf(stderr,fmt,arg_ptr) ;
132     }
133   
134   if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG )
135     {
136       fips_signal_fatal_error ("internal error (fatal or bug)");
137       _gcry_secmem_term ();
138       abort ();
139     }
140 }
141
142
143 void
144 _gcry_log( int level, const char *fmt, ... )
145 {
146     va_list arg_ptr ;
147
148     va_start( arg_ptr, fmt ) ;
149     _gcry_logv( level, fmt, arg_ptr );
150     va_end(arg_ptr);
151 }
152
153
154 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
155 void
156 _gcry_bug( const char *file, int line, const char *func )
157 {
158     _gcry_log( GCRY_LOG_BUG,
159              ("... this is a bug (%s:%d:%s)\n"), file, line, func );
160     abort(); /* never called, but it makes the compiler happy */
161 }
162 #else
163 void
164 _gcry_bug( const char *file, int line )
165 {
166     _gcry_log( GCRY_LOG_BUG,
167              _("you found a bug ... (%s:%d)\n"), file, line);
168     abort(); /* never called, but it makes the compiler happy */
169 }
170 #endif
171
172 void
173 _gcry_log_info( const char *fmt, ... )
174 {
175     va_list arg_ptr ;
176
177     va_start( arg_ptr, fmt ) ;
178     _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
179     va_end(arg_ptr);
180 }
181
182 int
183 _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
184 {
185     va_list arg_ptr;
186
187     (void)fp;
188     va_start( arg_ptr, fmt ) ;
189     _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
190     va_end(arg_ptr);
191     return 0;
192 }
193
194 void
195 _gcry_log_error( const char *fmt, ... )
196 {
197     va_list arg_ptr ;
198
199     va_start( arg_ptr, fmt ) ;
200     _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr );
201     va_end(arg_ptr);
202 }
203
204
205 void
206 _gcry_log_fatal( const char *fmt, ... )
207 {
208     va_list arg_ptr ;
209
210     va_start( arg_ptr, fmt ) ;
211     _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr );
212     va_end(arg_ptr);
213     abort(); /* never called, but it makes the compiler happy */
214 }
215
216 void
217 _gcry_log_bug( const char *fmt, ... )
218 {
219     va_list arg_ptr ;
220
221     va_start( arg_ptr, fmt ) ;
222     _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr );
223     va_end(arg_ptr);
224     abort(); /* never called, but it makes the compiler happy */
225 }
226
227 void
228 _gcry_log_debug( const char *fmt, ... )
229 {
230     va_list arg_ptr ;
231
232     va_start( arg_ptr, fmt ) ;
233     _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr );
234     va_end(arg_ptr);
235 }
236
237 void
238 _gcry_log_printf (const char *fmt, ...)
239 {
240   va_list arg_ptr;
241   
242   if (fmt) 
243     {
244       va_start( arg_ptr, fmt ) ;
245       _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr);
246       va_end(arg_ptr);
247     }
248 }
249
250 void
251 _gcry_burn_stack (int bytes)
252 {
253     char buf[64];
254     
255     wipememory (buf, sizeof buf);
256     bytes -= sizeof buf;
257     if (bytes > 0)
258         _gcry_burn_stack (bytes);
259 }