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