mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
First set of changes to backport the new card code from 2.0.
For compatibility reasons a few new files had to be added. Also added estream-printf as this is now used in app-openpgp.c and provides a better and generic asprintf implementation than the hack we used for the W32 code in ttyio.c. Card code is not yet finished.
This commit is contained in:
parent
b478389753
commit
3459c6b015
37 changed files with 7385 additions and 1694 deletions
|
@ -1,3 +1,20 @@
|
|||
2009-07-21 Werner Koch <wk@g10code.com>
|
||||
|
||||
* ttyio.c (tty_printf): Replace vasprintf by xtryasprintf.
|
||||
(tty_fprintf): Ditto.
|
||||
|
||||
* strgutil.c: Include estream-printf.h.
|
||||
(xasprintf, xtryasprintf): New.
|
||||
(vasprintf, asprintf): Remove.
|
||||
|
||||
* estream-printf.c: New. Taken from libestream.
|
||||
* Makefile.am (libutil_a_SOURCES): Add it.
|
||||
|
||||
* memory.c (trymalloc,trystrdup): New.
|
||||
|
||||
* convert.c: New. Taken from GnuPG 2.0 SVN.
|
||||
* Makefile.am (libutil_a_SOURCES): Add it.
|
||||
|
||||
2009-05-26 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* http.c (send_request): Pass in a STRLIST for additional headers.
|
||||
|
|
|
@ -23,7 +23,8 @@ noinst_LIBRARIES = libutil.a libcompat.a
|
|||
|
||||
libutil_a_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
|
||||
ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c \
|
||||
dotlock.c http.c pka.c membuf.c cert.c \
|
||||
dotlock.c http.c pka.c membuf.c cert.c convert.c \
|
||||
estream-printf.c \
|
||||
$(libcompat_a_SOURCES)
|
||||
|
||||
if USE_SIMPLE_GETTEXT
|
||||
|
|
249
util/convert.c
Normal file
249
util/convert.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/* convert.c - Hex conversion functions.
|
||||
* Copyright (C) 2006, 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
|
||||
|
||||
|
||||
/* Convert STRING consisting of hex characters into its binary
|
||||
representation and store that at BUFFER. BUFFER needs to be of
|
||||
LENGTH bytes. The function checks that the STRING will convert
|
||||
exactly to LENGTH bytes. The string is delimited by either end of
|
||||
string or a white space character. The function returns -1 on
|
||||
error or the length of the parsed string. */
|
||||
int
|
||||
hex2bin (const char *string, void *buffer, size_t length)
|
||||
{
|
||||
int i;
|
||||
const char *s = string;
|
||||
|
||||
for (i=0; i < length; )
|
||||
{
|
||||
if (!hexdigitp (s) || !hexdigitp (s+1))
|
||||
return -1; /* Invalid hex digits. */
|
||||
((unsigned char*)buffer)[i++] = xtoi_2 (s);
|
||||
s += 2;
|
||||
}
|
||||
if (*s && (!isascii (*s) || !isspace (*s)) )
|
||||
return -1; /* Not followed by Nul or white space. */
|
||||
if (i != length)
|
||||
return -1; /* Not of expected length. */
|
||||
if (*s)
|
||||
s++; /* Skip the delimiter. */
|
||||
return s - string;
|
||||
}
|
||||
|
||||
|
||||
/* Convert STRING consisting of hex characters into its binary representation
|
||||
and store that at BUFFER. BUFFER needs to be of LENGTH bytes. The
|
||||
function check that the STRING will convert exactly to LENGTH
|
||||
bytes. Colons inbetween the hex digits are allowed, if one colon
|
||||
has been given a colon is expected very 2 characters. The string
|
||||
is delimited by either end of string or a white space character.
|
||||
The function returns -1 on error or the length of the parsed
|
||||
string. */
|
||||
int
|
||||
hexcolon2bin (const char *string, void *buffer, size_t length)
|
||||
{
|
||||
int i;
|
||||
const char *s = string;
|
||||
int need_colon = 0;
|
||||
|
||||
for (i=0; i < length; )
|
||||
{
|
||||
if (i==1 && *s == ':') /* Skip colons between hex digits. */
|
||||
{
|
||||
need_colon = 1;
|
||||
s++;
|
||||
}
|
||||
else if (need_colon && *s == ':')
|
||||
s++;
|
||||
else if (need_colon)
|
||||
return -1; /* Colon expected. */
|
||||
if (!hexdigitp (s) || !hexdigitp (s+1))
|
||||
return -1; /* Invalid hex digits. */
|
||||
((unsigned char*)buffer)[i++] = xtoi_2 (s);
|
||||
s += 2;
|
||||
}
|
||||
if (*s == ':')
|
||||
return -1; /* Trailing colons are not allowed. */
|
||||
if (*s && (!isascii (*s) || !isspace (*s)) )
|
||||
return -1; /* Not followed by Nul or white space. */
|
||||
if (i != length)
|
||||
return -1; /* Not of expected length. */
|
||||
if (*s)
|
||||
s++; /* Skip the delimiter. */
|
||||
return s - string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
|
||||
{
|
||||
const unsigned char *s;
|
||||
char *p;
|
||||
|
||||
if (!stringbuf)
|
||||
{
|
||||
/* Not really correct for with_colon but we don't care about the
|
||||
one wasted byte. */
|
||||
size_t n = with_colon? 3:2;
|
||||
size_t nbytes = n * length + 1;
|
||||
if (length && (nbytes-1) / n != length)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
stringbuf = xtrymalloc (nbytes);
|
||||
if (!stringbuf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (s = buffer, p = stringbuf; length; length--, s++)
|
||||
{
|
||||
if (with_colon && s != buffer)
|
||||
*p++ = ':';
|
||||
*p++ = tohex ((*s>>4)&15);
|
||||
*p++ = tohex (*s&15);
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
return stringbuf;
|
||||
}
|
||||
|
||||
|
||||
/* Convert LENGTH bytes of data in BUFFER into hex encoding and store
|
||||
that at the provided STRINGBUF. STRINGBUF must be allocated of at
|
||||
least (2*LENGTH+1) bytes or be NULL so that the function mallocs an
|
||||
appropriate buffer. Returns STRINGBUF or NULL on error (which may
|
||||
only occur if STRINGBUF has been NULL and the internal malloc
|
||||
failed). */
|
||||
char *
|
||||
bin2hex (const void *buffer, size_t length, char *stringbuf)
|
||||
{
|
||||
return do_bin2hex (buffer, length, stringbuf, 0);
|
||||
}
|
||||
|
||||
/* Convert LENGTH bytes of data in BUFFER into hex encoding and store
|
||||
that at the provided STRINGBUF. STRINGBUF must be allocated of at
|
||||
least (3*LENGTH+1) bytes or be NULL so that the function mallocs an
|
||||
appropriate buffer. Returns STRINGBUF or NULL on error (which may
|
||||
only occur if STRINGBUF has been NULL and the internal malloc
|
||||
failed). */
|
||||
char *
|
||||
bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
|
||||
{
|
||||
return do_bin2hex (buffer, length, stringbuf, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Convert HEXSTRING consisting of hex characters into string and
|
||||
store that at BUFFER. HEXSTRING is either delimited by end of
|
||||
string or a white space character. The function makes sure that
|
||||
the resulting string in BUFFER is terminated by a Nul character.
|
||||
BUFSIZE is the availabe length of BUFFER; if the converted result
|
||||
plus a possible required Nul character does not fit into this
|
||||
buffer, the function returns NULL and won't change the existing
|
||||
conent of buffer. In-place conversion is possible as long as
|
||||
BUFFER points to HEXSTRING.
|
||||
|
||||
If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but
|
||||
does not store anything. This may be used to find the end of
|
||||
hexstring.
|
||||
|
||||
On sucess the function returns a pointer to the next character
|
||||
after HEXSTRING (which is either end-of-string or a the next white
|
||||
space). If BUFLEN is not NULL the strlen of buffer is stored
|
||||
there; this will even be done if BUFFER has been passed as NULL. */
|
||||
const char *
|
||||
hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
|
||||
{
|
||||
const char *s = hexstring;
|
||||
int idx, count;
|
||||
int need_nul = 0;
|
||||
|
||||
if (buflen)
|
||||
*buflen = 0;
|
||||
|
||||
for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++)
|
||||
;
|
||||
if (*s && (!isascii (*s) || !isspace (*s)) )
|
||||
return NULL; /* Not followed by Nul or white space. */
|
||||
/* We need to append a nul character. However we don't want that if
|
||||
the hexstring already ends with "00". */
|
||||
need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0'));
|
||||
if (need_nul)
|
||||
count++;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
if (count > bufsize)
|
||||
return NULL; /* Too long. */
|
||||
|
||||
for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
|
||||
((unsigned char*)buffer)[idx++] = xtoi_2 (s);
|
||||
if (need_nul)
|
||||
buffer[idx] = 0;
|
||||
}
|
||||
|
||||
if (buflen)
|
||||
*buflen = count - 1;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Same as hex2str but this function allocated a new string. Returns
|
||||
NULL on error. If R_COUNT is not NULL, the number of scanned bytes
|
||||
will be stored there. ERRNO is set on error. */
|
||||
char *
|
||||
hex2str_alloc (const char *hexstring, size_t *r_count)
|
||||
{
|
||||
const char *tail;
|
||||
size_t nbytes;
|
||||
char *result;
|
||||
|
||||
tail = hex2str (hexstring, NULL, 0, &nbytes);
|
||||
if (!tail)
|
||||
{
|
||||
if (r_count)
|
||||
*r_count = 0;
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if (r_count)
|
||||
*r_count = tail - hexstring;
|
||||
result = xtrymalloc (nbytes+1);
|
||||
if (!result)
|
||||
return NULL;
|
||||
if (!hex2str (hexstring, result, nbytes+1, NULL))
|
||||
BUG ();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
2110
util/estream-printf.c
Normal file
2110
util/estream-printf.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -62,6 +62,7 @@
|
|||
#define M_GUARD 1
|
||||
#endif
|
||||
#undef xmalloc
|
||||
#undef xtrymalloc
|
||||
#undef xmalloc_clear
|
||||
#undef xmalloc_secure
|
||||
#undef xmalloc_secure_clear
|
||||
|
@ -69,6 +70,7 @@
|
|||
#undef xfree
|
||||
#undef m_check
|
||||
#undef xstrdup
|
||||
#undef xtrystrdup
|
||||
#define FNAME(a) m_debug_ ##a
|
||||
#define FNAMEX(a) m_debug_ ##a
|
||||
#define FNAMEXM(a) m_debug_ ##a
|
||||
|
@ -444,6 +446,30 @@ FNAMEXM(alloc)( size_t n FNAMEPRT )
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Allocate memory of size n. This function returns NULL if we do not
|
||||
have enough memory. */
|
||||
void *
|
||||
FNAMEX(trymalloc)(size_t n FNAMEPRT)
|
||||
{
|
||||
#ifdef M_GUARD
|
||||
char *p;
|
||||
|
||||
if (!n)
|
||||
n = 1;
|
||||
p = malloc (n + EXTRA_ALIGN+5);
|
||||
if (!p)
|
||||
return NULL;
|
||||
store_len(p,n,0);
|
||||
used_memory += n;
|
||||
p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
|
||||
return p+EXTRA_ALIGN+4;
|
||||
#else
|
||||
/* Mallocing zero bytes is undefined by ISO-C, so we better make
|
||||
sure that it won't happen. */
|
||||
return malloc (n? n: 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************
|
||||
* Allocate memory of size n from the secure memory pool.
|
||||
* This function gives up if we do not have enough memory
|
||||
|
@ -616,6 +642,16 @@ FNAMEX(strdup)( const char *a FNAMEPRT )
|
|||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
FNAMEX(trystrdup)(const char *a FNAMEPRT)
|
||||
{
|
||||
size_t n = strlen (a);
|
||||
char *p = FNAMEX(trymalloc)(n+1 FNAMEARG);
|
||||
if (p)
|
||||
strcpy (p, a);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Wrapper around xmalloc_clear to take the usual 2 arguments of a
|
||||
calloc style function. */
|
||||
|
|
149
util/strgutil.c
149
util/strgutil.c
|
@ -1,6 +1,6 @@
|
|||
/* strgutil.c - string utilities
|
||||
* Copyright (C) 1994, 1998, 1999, 2000, 2001,
|
||||
* 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
* 2003, 2004, 2005, 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -47,6 +47,14 @@
|
|||
#include "memory.h"
|
||||
#include "i18n.h"
|
||||
#include "dynload.h"
|
||||
#include "estream-printf.h"
|
||||
|
||||
/* Our xasprintf replacements are expected to work with our memory
|
||||
allocator. Let's test for this here. */
|
||||
#if !defined(_ESTREAM_PRINTF_MALLOC) || !defined(_ESTREAM_PRINTF_FREE)
|
||||
#error Please define _ESTREAM_PRINTF_MALLOC and _FREE
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef USE_GNUPG_ICONV
|
||||
|
@ -1040,6 +1048,40 @@ utf8_to_native( const char *string, size_t length, int delim )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Same as asprintf but return an allocated buffer suitable to be
|
||||
freed using xfree. This function simply dies on memory failure,
|
||||
thus no extra check is required. */
|
||||
char *
|
||||
xasprintf (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
|
||||
va_start (ap, fmt);
|
||||
if (estream_vasprintf (&buf, fmt, ap) < 0)
|
||||
log_fatal ("estream_asprintf failed: %s\n", strerror (errno));
|
||||
va_end (ap);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Same as above but return NULL on memory failure. */
|
||||
char *
|
||||
xtryasprintf (const char *fmt, ...)
|
||||
{
|
||||
int rc;
|
||||
va_list ap;
|
||||
char *buf;
|
||||
|
||||
va_start (ap, fmt);
|
||||
rc = estream_vasprintf (&buf, fmt, ap);
|
||||
va_end (ap);
|
||||
if (rc < 0)
|
||||
return NULL;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
******** locale insensitive ctype functions ********
|
||||
****************************************************/
|
||||
|
@ -1127,111 +1169,6 @@ strncasecmp( const char *a, const char *b, size_t n )
|
|||
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Like vsprintf but provides a pointer to malloc'd storage, which
|
||||
* must be freed by the caller (xfree). Taken from libiberty as
|
||||
* found in gcc-2.95.2 and a little bit modernized.
|
||||
* FIXME: Write a new CRT for W32.
|
||||
*/
|
||||
int
|
||||
vasprintf (char **result, const char *format, va_list args)
|
||||
{
|
||||
const char *p = format;
|
||||
/* Add one to make sure that it is never zero, which might cause malloc
|
||||
to return NULL. */
|
||||
int total_width = strlen (format) + 1;
|
||||
va_list ap;
|
||||
|
||||
/* this is not really portable but works under Windows */
|
||||
memcpy ( &ap, &args, sizeof (va_list));
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (*p++ == '%')
|
||||
{
|
||||
while (strchr ("-+ #0", *p))
|
||||
++p;
|
||||
if (*p == '*')
|
||||
{
|
||||
++p;
|
||||
total_width += abs (va_arg (ap, int));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *endp;
|
||||
total_width += strtoul (p, &endp, 10);
|
||||
p = endp;
|
||||
}
|
||||
if (*p == '.')
|
||||
{
|
||||
++p;
|
||||
if (*p == '*')
|
||||
{
|
||||
++p;
|
||||
total_width += abs (va_arg (ap, int));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *endp;
|
||||
total_width += strtoul (p, &endp, 10);
|
||||
p = endp;
|
||||
}
|
||||
}
|
||||
while (strchr ("hlL", *p))
|
||||
++p;
|
||||
/* Should be big enough for any format specifier except %s
|
||||
and floats. */
|
||||
total_width += 30;
|
||||
switch (*p)
|
||||
{
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'c':
|
||||
(void) va_arg (ap, int);
|
||||
break;
|
||||
case 'f':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
(void) va_arg (ap, double);
|
||||
/* Since an ieee double can have an exponent of 307, we'll
|
||||
make the buffer wide enough to cover the gross case. */
|
||||
total_width += 307;
|
||||
|
||||
case 's':
|
||||
total_width += strlen (va_arg (ap, char *));
|
||||
break;
|
||||
case 'p':
|
||||
case 'n':
|
||||
(void) va_arg (ap, char *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*result = xmalloc (total_width);
|
||||
if (*result != NULL)
|
||||
return vsprintf (*result, format, args);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asprintf (char **buf, const char *fmt, ...)
|
||||
{
|
||||
int status;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
status = vasprintf (buf, fmt, ap);
|
||||
va_end (ap);
|
||||
return status;
|
||||
}
|
||||
|
||||
const char *
|
||||
w32_strerror (int w32_errno)
|
||||
{
|
||||
|
|
18
util/ttyio.c
18
util/ttyio.c
|
@ -239,13 +239,14 @@ tty_printf( const char *fmt, ... )
|
|||
va_start( arg_ptr, fmt ) ;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
char *buf = NULL;
|
||||
char *buf;
|
||||
int n;
|
||||
DWORD nwritten;
|
||||
|
||||
n = vasprintf(&buf, fmt, arg_ptr);
|
||||
if( !buf )
|
||||
log_bug("vasprintf() failed\n");
|
||||
buf = xtryasprintf(fmt, arg_ptr);
|
||||
if (!buf)
|
||||
log_bug("xtryasprintf() failed\n");
|
||||
n = strlen (buf);
|
||||
|
||||
if (!WriteConsoleA (con.out, buf, n, &nwritten, NULL))
|
||||
log_fatal ("WriteConsole failed: %s", w32_strerror (0));
|
||||
|
@ -286,13 +287,14 @@ tty_fprintf (FILE *fp, const char *fmt, ... )
|
|||
va_start( arg_ptr, fmt ) ;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
char *buf = NULL;
|
||||
char *buf;
|
||||
int n;
|
||||
DWORD nwritten;
|
||||
|
||||
n = vasprintf(&buf, fmt, arg_ptr);
|
||||
if( !buf )
|
||||
log_bug("vasprintf() failed\n");
|
||||
buf = xtryasprintf (fmt, arg_ptr);
|
||||
if (!buf)
|
||||
log_bug ("xtryasprintf() failed\n");
|
||||
n = strlen (buf);
|
||||
|
||||
if (!WriteConsoleA (con.out, buf, n, &nwritten, NULL))
|
||||
log_fatal ("WriteConsole failed: %s", w32_strerror (0));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue