Added missing files and fixed stuff from the recent merged. I did only
[gpgme.git] / assuan / assuan-util.c
1 /* assuan-util.c - Utility functions for Assuan 
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005 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 #include <errno.h>
27
28 #include "assuan-defs.h"
29
30 static void *(*alloc_func)(size_t n) = malloc;
31 static void *(*realloc_func)(void *p, size_t n) = realloc;
32 static void (*free_func)(void*) = free;
33
34 void
35 assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
36                           void *(*new_realloc_func)(void *p, size_t n),
37                           void (*new_free_func)(void*) )
38 {
39   alloc_func        = new_alloc_func;
40   realloc_func      = new_realloc_func;
41   free_func         = new_free_func;
42 }
43
44 void *
45 _assuan_malloc (size_t n)
46 {
47   return alloc_func (n);
48 }
49
50 void *
51 _assuan_realloc (void *a, size_t n)
52 {
53   return realloc_func (a, n);
54 }
55
56 void *
57 _assuan_calloc (size_t n, size_t m)
58 {
59   void *p;
60   size_t nbytes;
61     
62   nbytes = n * m;
63   if (m && nbytes / m != n) 
64     {
65       errno = ENOMEM;
66       return NULL;
67     }
68
69   p = _assuan_malloc (nbytes);
70   if (p)
71     memset (p, 0, nbytes);
72   return p;
73 }
74
75 void
76 _assuan_free (void *p)
77 {
78   if (p)
79     free_func (p);
80 }
81
82 \f
83 /* Store the error in the context so that the error sending function
84   can take out a descriptive text.  Inside the assuan code, use the
85   macro set_error instead of this function. */
86 int
87 assuan_set_error (assuan_context_t ctx, int err, const char *text)
88 {
89   ctx->err_no = err;
90   ctx->err_str = text;
91   return err;
92 }
93
94 void
95 assuan_set_pointer (assuan_context_t ctx, void *pointer)
96 {
97   if (ctx)
98     ctx->user_pointer = pointer;
99 }
100
101 void *
102 assuan_get_pointer (assuan_context_t ctx)
103 {
104   return ctx? ctx->user_pointer : NULL;
105 }
106
107
108 void
109 assuan_set_log_stream (assuan_context_t ctx, FILE *fp)
110 {
111   if (ctx)
112     {
113       if (ctx->log_fp)
114         fflush (ctx->log_fp);
115       ctx->log_fp = fp;
116       _assuan_set_default_log_stream (fp);
117     }
118 }
119
120
121 void
122 assuan_begin_confidential (assuan_context_t ctx)
123 {
124   if (ctx)
125     {
126       ctx->confidential = 1;
127     }
128 }
129
130 void
131 assuan_end_confidential (assuan_context_t ctx)
132 {
133   if (ctx)
134     {
135       ctx->confidential = 0;
136     }
137 }
138
139
140
141 /* For context CTX, set the flag FLAG to VALUE.  Values for flags
142    are usually 1 or 0 but certain flags might allow for other values;
143    see the description of the type assuan_flag_t for details. */
144 void
145 assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value)
146 {
147   if (!ctx)
148     return;
149   switch (flag)
150     {
151     case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break;
152     }
153 }
154
155 /* Return the VALUE of FLAG in context CTX. */ 
156 int
157 assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag)
158 {
159   if (!ctx)
160     return 0;
161   switch (flag)
162     {
163     case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid;
164     }
165   return 0;
166 }
167
168
169 /* Dump a possibly binary string (used for debugging).  Distinguish
170    ascii text from binary and print it accordingly.  */
171 void
172 _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
173 {
174   const unsigned char *s;
175   int n;
176
177   for (n=length,s=buffer; n; n--, s++)
178     if  ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80))
179       break;
180
181   s = buffer;
182   if (!n && *s != '[')
183     fwrite (buffer, length, 1, fp);
184   else
185     {
186 #ifdef HAVE_FLOCKFILE
187       flockfile (fp);
188 #endif
189       putc_unlocked ('[', fp);
190       for (n=0; n < length; n++, s++)
191           fprintf (fp, " %02x", *s);
192       putc_unlocked (' ', fp);
193       putc_unlocked (']', fp);
194 #ifdef HAVE_FUNLOCKFILE
195       funlockfile (fp);
196 #endif
197     }
198 }
199
200 /* Log a user supplied string.  Escapes non-printable before
201    printing.  */
202 void
203 _assuan_log_sanitized_string (const char *string)
204 {
205   const unsigned char *s = string;
206   FILE *fp = assuan_get_assuan_log_stream ();
207
208   if (! *s)
209     return;
210
211 #ifdef HAVE_FLOCKFILE
212   flockfile (fp);
213 #endif
214
215   for (; *s; s++)
216     {
217       int c = 0;
218
219       switch (*s)
220         {
221         case '\r':
222           c = 'r';
223           break;
224
225         case '\n':
226           c = 'n';
227           break;
228
229         case '\f':
230           c = 'f';
231           break;
232
233         case '\v':
234           c = 'v';
235           break;
236
237         case '\b':
238           c = 'b';
239           break;
240
241         default:
242           if ((isascii (*s) && isprint (*s)) || (*s >= 0x80))
243             putc_unlocked (*s, fp);
244           else
245             {
246               putc_unlocked ('\\', fp);
247               fprintf (fp, "x%02x", *s);
248             }
249         }
250
251       if (c)
252         {
253           putc_unlocked ('\\', fp);
254           putc_unlocked (c, fp);
255         }
256     }
257
258 #ifdef HAVE_FUNLOCKFILE
259   funlockfile (fp);
260 #endif
261 }
262