2005-03-24 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / assuan / assuan-util.c
1 /* assuan-util.c - Utility functions for Assuan 
2  *      Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Assuan.
5  *
6  * Assuan is free software; you can redistribute it and/or modify it
7  * 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  * Assuan is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 
19  */
20
21 #include <config.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #include "assuan-defs.h"
28
29 static void *(*alloc_func)(size_t n) = malloc;
30 static void *(*realloc_func)(void *p, size_t n) = realloc;
31 static void (*free_func)(void*) = free;
32
33 void
34 assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
35                           void *(*new_realloc_func)(void *p, size_t n),
36                           void (*new_free_func)(void*) )
37 {
38   alloc_func        = new_alloc_func;
39   realloc_func      = new_realloc_func;
40   free_func         = new_free_func;
41 }
42
43 void *
44 _assuan_malloc (size_t n)
45 {
46   return alloc_func (n);
47 }
48
49 void *
50 _assuan_realloc (void *a, size_t n)
51 {
52   return realloc_func (a, n);
53 }
54
55 void *
56 _assuan_calloc (size_t n, size_t m)
57 {
58   void *p = _assuan_malloc (n*m);
59   if (p)
60     memset (p, 0, n* m);
61   return p;
62 }
63
64 void
65 _assuan_free (void *p)
66 {
67   if (p)
68     free_func (p);
69 }
70
71 \f
72 /* Store the error in the context so that the error sending function
73   can take out a descriptive text.  Inside the assuan code, use the
74   macro set_error instead of this function. */
75 int
76 assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text)
77 {
78   ctx->err_no = err;
79   ctx->err_str = text;
80   return err;
81 }
82
83 void
84 assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer)
85 {
86   if (ctx)
87     ctx->user_pointer = pointer;
88 }
89
90 void *
91 assuan_get_pointer (ASSUAN_CONTEXT ctx)
92 {
93   return ctx? ctx->user_pointer : NULL;
94 }
95
96
97 void
98 assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp)
99 {
100   if (ctx)
101     {
102       if (ctx->log_fp)
103         fflush (ctx->log_fp);
104       ctx->log_fp = fp;
105     }
106 }
107
108
109 void
110 assuan_begin_confidential (ASSUAN_CONTEXT ctx)
111 {
112   if (ctx)
113     {
114       ctx->confidential = 1;
115     }
116 }
117
118 void
119 assuan_end_confidential (ASSUAN_CONTEXT ctx)
120 {
121   if (ctx)
122     {
123       ctx->confidential = 0;
124     }
125 }
126
127 /* Dump a possibly binary string (used for debugging).  Distinguish
128    ascii text from binary and print it accordingly.  */
129 void
130 _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
131 {
132   const unsigned char *s;
133   int n;
134
135   for (n=length,s=buffer; n; n--, s++)
136     if  (!isascii (*s) || iscntrl (*s) || !isprint (*s))
137       break;
138
139   s = buffer;
140   if (!n && *s != '[')
141     fwrite (buffer, length, 1, fp);
142   else
143     {
144 #ifdef HAVE_FLOCKFILE
145       flockfile (fp);
146 #endif
147       putc_unlocked ('[', fp);
148       for (n=0; n < length; n++, s++)
149           fprintf (fp, " %02x", *s);
150       putc_unlocked (' ', fp);
151       putc_unlocked (']', fp);
152 #ifdef HAVE_FUNLOCKFILE
153       funlockfile (fp);
154 #endif
155     }
156 }
157
158 /* Log a user supplied string.  Escapes non-printable before
159    printing.  */
160 void
161 _assuan_log_sanitized_string (const char *string)
162 {
163   const unsigned char *s = string;
164   FILE *fp = assuan_get_assuan_log_stream ();
165
166   if (! *s)
167     return;
168
169 #ifdef HAVE_FLOCKFILE
170   flockfile (fp);
171 #endif
172
173   for (; *s; s++)
174     {
175       int c = 0;
176
177       switch (*s)
178         {
179         case '\r':
180           c = 'r';
181           break;
182
183         case '\n':
184           c = 'n';
185           break;
186
187         case '\f':
188           c = 'f';
189           break;
190
191         case '\v':
192           c = 'v';
193           break;
194
195         case '\b':
196           c = 'b';
197           break;
198
199         default:
200           if (isascii (*s) && isprint (*s))
201             putc_unlocked (*s, fp);
202           else
203             {
204               putc_unlocked ('\\', fp);
205               fprintf (fp, "x%02x", *s);
206             }
207         }
208
209       if (c)
210         {
211           putc_unlocked ('\\', fp);
212           putc_unlocked (c, fp);
213         }
214     }
215
216 #ifdef HAVE_FUNLOCKFILE
217   funlockfile (fp);
218 #endif
219 }