Fixed card key generation of gpg2.
[gnupg.git] / common / miscellaneous.c
1 /* miscellaneous.c - Stuff not fitting elsewhere
2  *      Copyright (C) 2003, 2006 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <errno.h>
23
24 #define JNLIB_NEED_LOG_LOGV
25 #include "util.h"
26 #include "iobuf.h"
27 #include "i18n.h"
28
29
30 /* Used by libgcrypt for logging.  */
31 static void
32 my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
33 {
34   /* Map the log levels.  */
35   switch (level)
36     {
37     case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
38     case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
39     case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
40     case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
41     case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
42     case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
43     case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
44     default:            level = JNLIB_LOG_ERROR; break;  
45     }
46   log_logv (level, fmt, arg_ptr);
47 }
48
49
50 /* This function is called by libgcrypt on a fatal error.  */
51 static void
52 my_gcry_fatalerror_handler (void *opaque, int rc, const char *text)
53 {
54   log_fatal ("libgcrypt problem: %s\n", text ? text : gpg_strerror (rc));
55   abort ();
56 }
57
58
59 /* This function is called by libgcrypt if it ran out of core and
60    there is no way to return that error to the caller.  We do our own
61    function here to make use of our logging functions. */
62 static int
63 my_gcry_outofcore_handler (void *opaque, size_t req_n, unsigned int flags)
64 {
65   static int been_here;  /* Used to protect against recursive calls. */
66
67   if (!been_here)
68     {
69       been_here = 1;
70       if ( (flags & 1) )
71         log_fatal (_("out of core in secure memory "
72                      "while allocating %lu bytes"), (unsigned long)req_n);
73       else
74         log_fatal (_("out of core while allocating %lu bytes"),
75                    (unsigned long)req_n);
76     }
77   return 0; /* Let libgcrypt call its own fatal error handler.
78                Actually this will turn out to be
79                my_gcry_fatalerror_handler. */
80 }
81
82
83 /* Setup libgcrypt to use our own logging functions.  Should be used
84    early at startup. */
85 void
86 setup_libgcrypt_logging (void)
87 {
88   gcry_set_log_handler (my_gcry_logger, NULL);
89   gcry_set_fatalerror_handler (my_gcry_fatalerror_handler, NULL);
90   gcry_set_outofcore_handler (my_gcry_outofcore_handler, NULL);
91 }
92
93
94
95 /* Decide whether the filename is stdout or a real filename and return
96  * an appropriate string.  */
97 const char *
98 print_fname_stdout (const char *s)
99 {
100     if( !s || (*s == '-' && !s[1]) )
101         return "[stdout]";
102     return s;
103 }
104
105
106 /* Decide whether the filename is stdin or a real filename and return
107  * an appropriate string.  */
108 const char *
109 print_fname_stdin (const char *s)
110 {
111     if( !s || (*s == '-' && !s[1]) )
112         return "[stdin]";
113     return s;
114 }
115
116 /* fixme: Globally replace it by print_sanitized_buffer. */
117 void
118 print_string( FILE *fp, const byte *p, size_t n, int delim )
119 {
120   print_sanitized_buffer (fp, p, n, delim);
121 }
122
123 void
124 print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim )
125 {
126   print_sanitized_utf8_buffer (fp, p, n, delim);
127 }
128
129 void
130 print_utf8_string( FILE *fp, const byte *p, size_t n )
131 {
132     print_utf8_string2 (fp, p, n, 0);
133 }
134
135 /* Write LENGTH bytes of BUFFER to FP as a hex encoded string.
136    RESERVED must be 0. */
137 void
138 print_hexstring (FILE *fp, const void *buffer, size_t length, int reserved)
139 {
140 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
141   const unsigned char *s;
142
143   for (s = buffer; length; s++, length--)
144     {
145       putc ( tohex ((*s>>4)&15), fp);
146       putc ( tohex (*s&15), fp);
147     }
148 #undef tohex
149 }
150
151 char *
152 make_printable_string (const void *p, size_t n, int delim )
153 {
154   return sanitize_buffer (p, n, delim);
155 }
156
157
158
159 /*
160  * Check if the file is compressed.
161  */
162 int
163 is_file_compressed (const char *s, int *ret_rc)
164 {
165     iobuf_t a;
166     byte buf[4];
167     int i, rc = 0;
168     int overflow;
169
170     struct magic_compress_s {
171         size_t len;
172         byte magic[4];
173     } magic[] = {
174         { 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
175         { 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
176         { 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
177     };
178     
179     if ( iobuf_is_pipe_filename (s) || !ret_rc )
180         return 0; /* We can't check stdin or no file was given */
181
182     a = iobuf_open( s );
183     if ( a == NULL ) {
184         *ret_rc = gpg_error_from_syserror ();
185         return 0;
186     }
187
188     if ( iobuf_get_filelength( a, &overflow ) < 4 && !overflow) {
189         *ret_rc = 0;
190         goto leave;
191     }
192
193     if ( iobuf_read( a, buf, 4 ) == -1 ) {
194         *ret_rc = a->error;
195         goto leave;
196     }
197
198     for ( i = 0; i < DIM( magic ); i++ ) {
199         if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) {
200             *ret_rc = 0;
201             rc = 1;
202             break;
203         }
204     }
205
206 leave:    
207     iobuf_close( a );
208     return rc;
209 }
210
211
212 /* Try match against each substring of multistr, delimited by | */
213 int
214 match_multistr (const char *multistr,const char *match)
215 {
216   do
217     {
218       size_t seglen = strcspn (multistr,"|");
219       if (!seglen)
220         break;
221       /* Using the localized strncasecmp! */
222       if (strncasecmp(multistr,match,seglen)==0)
223         return 1;
224       multistr += seglen;
225       if (*multistr == '|')
226         multistr++;
227     }
228   while (*multistr);
229
230   return 0;
231 }
232
233