mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
This commit was manufactured by cvs2svn to create branch
'GNUPG-1-9-BRANCH'.
This commit is contained in:
parent
eba8c18657
commit
9ca4830a5b
76 changed files with 34899 additions and 0 deletions
219
common/ChangeLog
Normal file
219
common/ChangeLog
Normal file
|
@ -0,0 +1,219 @@
|
|||
2003-07-15 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* simple-pwquery.c, simple-pwquery.h: New; moved from ../agent.
|
||||
* Makefile.am (libsimple_pwquery_a_LIBADD): New.
|
||||
|
||||
2003-06-25 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_to_assuan_status): Directly map 0 to 0.
|
||||
|
||||
2003-06-17 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* gettime.c (scan_isodatestr,add_days_to_timestamp,strtimevalue)
|
||||
(strtimestamp,asctimestamp): New. Code taken from gnupg 1.3.2
|
||||
mischelp.c.
|
||||
|
||||
* yesno.c: New. Code taken from gnupg 1.3.2 mischelp.c
|
||||
|
||||
* miscellaneous.c: New.
|
||||
|
||||
* util.h: Include utf8conf.h
|
||||
|
||||
2003-06-16 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* gettime.c (make_timestamp): New.
|
||||
|
||||
* ttyio.c: New. Taken from gnupg 1.2.
|
||||
* ttyio.h: Move from ../include.
|
||||
|
||||
2003-06-13 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* util.h (seterr): Removed macro.
|
||||
(xmalloc_secure,xcalloc_secure): New.
|
||||
|
||||
2003-06-11 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* iobuf.c (iobuf_writebyte,iobuf_write): Return error code from
|
||||
iobuf_flush.
|
||||
(iobuf_writestr): Ditto.
|
||||
|
||||
2003-06-10 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* iobuf.c, iobuf.h: New. Taken from current gnupg 1.3 CVS. Run
|
||||
indent on it and adjusted error handling to libgpg-error style.
|
||||
Replaced IOBUF by iobuf_t. Renamed malloc functions.
|
||||
|
||||
2003-06-04 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* errors.h: Removed all error codes. We keep the status codes for
|
||||
now.
|
||||
* Makefile.am: Do not create errors.c anymore; remove it from the
|
||||
sources.
|
||||
|
||||
* maperror.c: Don't include error.h. Change all error codes to
|
||||
libgpg-error style.
|
||||
(map_assuan_err): Changed to new Assuan error code convention.
|
||||
(map_to_assuan_status): Likewise.
|
||||
(map_gcry_err,map_kbx_err): Not needed. For now dummy functions.
|
||||
|
||||
* membuf.c, membuf.h: New. Code taken from ../sm/call-agent.h.
|
||||
* Makefile.am: Added above.
|
||||
|
||||
2003-04-29 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* util.h (fopencokokie): Removed prototype and struct.
|
||||
|
||||
* fopencookie.c: Removed.
|
||||
|
||||
* maperror.c: Use system assuan.h
|
||||
|
||||
2002-10-31 Neal H. Walfield <neal@g10code.de>
|
||||
|
||||
* isascii.c: New file.
|
||||
* putc_unlocked.c: Likewise.
|
||||
|
||||
2002-10-28 Neal H. Walfield <neal@g10code.de>
|
||||
|
||||
* signal.c (caught_fatal_sig): Remove superfluous zero
|
||||
initializer.
|
||||
(caught_sigusr1): Likewise.
|
||||
|
||||
2002-09-04 Neal H. Walfield <neal@g10code.de>
|
||||
|
||||
* vasprintf.c (vasprintf) [va_copy]: Use va_copy.
|
||||
[!va_copy && __va_copy]: Use __va_copy.
|
||||
[!va_copy && !__va_copy]: Only now fall back to using memcpy.
|
||||
|
||||
2002-08-21 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* errors.h: Added STATUS_IMPORT_PROBLEM.
|
||||
|
||||
2002-08-20 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* vasprintf.c: Hack to handle NULL for %s.
|
||||
|
||||
2002-08-09 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* signal.c: New. Taken from GnuPG 1.1.91.
|
||||
|
||||
2002-07-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* util.h (_IO_cookie_io_functions_t): Fixed typo. Noted by
|
||||
Richard Lefebvre.
|
||||
|
||||
2002-07-22 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* fseeko.c, ftello.c: New.
|
||||
|
||||
2002-06-28 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_to_assuan_status): Map more errorcodes to Bad
|
||||
Certificate.
|
||||
|
||||
2002-06-26 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_to_assuan_status): Map EOF to No_Data_Available.
|
||||
|
||||
2002-06-10 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* errors.h (gnupg_error_token): Add new prototype.
|
||||
(STATUS_ERROR): New.
|
||||
|
||||
* mkerrtok: New.
|
||||
* Makefile.am: Use it to create the new error token function.
|
||||
|
||||
2002-06-04 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_to_assuan_status): Map Bad_CA_Certificate.
|
||||
|
||||
2002-05-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* no-pth.c, Makefile.am: Removed.
|
||||
|
||||
2002-05-22 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* mkdtemp.c: Replaced byte by unsigned char because it is no longer
|
||||
defined in gcrypt.h.
|
||||
|
||||
2002-05-21 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_gcry_err): Add libgcrypt's new S-expression errors.
|
||||
(map_ksba_err): Add a few mappings.
|
||||
|
||||
2002-05-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* gettime.c: New.
|
||||
|
||||
2002-05-03 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* errors.h: Added STARUS_EXPSIG and STATUS_EXPKEYSIG.
|
||||
|
||||
2002-04-15 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* cryptmiss.c: New.
|
||||
|
||||
2002-02-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c: Add more assuan<->gnupg mappings.
|
||||
|
||||
2002-02-12 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* fopencookie.c: Dummy function.
|
||||
|
||||
* vasprintf.c: New. Taken from binutils-2.9.1 and dropped all non
|
||||
ANSI-C stuff. Merged with asprintf version.
|
||||
|
||||
* no-pth.c: New.
|
||||
|
||||
2002-01-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* mkdtemp.c: Copied from gnupg-1.0.6c and changed to use libgcrypt.
|
||||
|
||||
2002-01-19 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* sysutils.c: New. This is the misc.c file from gnupg 1.0.6 with
|
||||
the OpenPGP stuff removed.
|
||||
* sysutils.h: New.
|
||||
|
||||
2002-01-15 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c: Add mapping for Not_Trusted.
|
||||
|
||||
2002-01-11 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_assuan_err): Codes for CRL
|
||||
|
||||
2002-01-08 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* util.h (spacep): New.
|
||||
|
||||
2002-01-02 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_to_assuan_status): New. Merged from ../agent
|
||||
and ../sm.
|
||||
|
||||
2001-12-20 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* maperror.c (map_gcry_err): Add some mappings.
|
||||
|
||||
2001-12-18 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* Makefile.am (AM_CPPFLAGS): Include flags for gcrypt and ksba
|
||||
|
||||
2001-12-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* util.h (digitp, hexdigitp): New ctype like macros.
|
||||
(atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New.
|
||||
|
||||
|
||||
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
modifications, as long as this notice is preserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
58
common/Makefile.am
Normal file
58
common/Makefile.am
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Makefile for common gnupg modules
|
||||
# Copyright (C) 2001, 2003 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
EXTRA_DIST = mkerrors mkerrtok
|
||||
#INCLUDES =
|
||||
|
||||
noinst_LIBRARIES = libcommon.a libsimple-pwquery.a
|
||||
|
||||
AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS)
|
||||
|
||||
libcommon_a_SOURCES = \
|
||||
util.h i18n.h \
|
||||
errors.h \
|
||||
maperror.c \
|
||||
sysutils.c sysutils.h \
|
||||
cryptmiss.c \
|
||||
gettime.c \
|
||||
yesno.c \
|
||||
miscellaneous.c \
|
||||
membuf.c membuf.h \
|
||||
iobuf.c iobuf.h \
|
||||
ttyio.c ttyio.h \
|
||||
signal.c
|
||||
|
||||
|
||||
libcommon_a_LIBADD = @LIBOBJS@
|
||||
|
||||
libsimple_pwquery_a_SOURCES = \
|
||||
simple-pwquery.c simple-pwquery.h
|
||||
|
||||
libsimple_pwquery_a_LIBADD = @LIBOBJS@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
11
common/README
Normal file
11
common/README
Normal file
|
@ -0,0 +1,11 @@
|
|||
Stuff used by several modules of GnuPG.
|
||||
|
||||
These directories use it:
|
||||
|
||||
gpg
|
||||
sm
|
||||
agent
|
||||
|
||||
These directories don't use it:
|
||||
|
||||
kbx
|
110
common/errors.h
Normal file
110
common/errors.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* errors.h - Globally used error codes
|
||||
* Copyright (C) 2001 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef GNUPG_COMMON_ERRORS_H
|
||||
#define GNUPG_COMMON_ERRORS_H
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* Status codes - fixme: should go into another file */
|
||||
enum {
|
||||
STATUS_ENTER,
|
||||
STATUS_LEAVE,
|
||||
STATUS_ABORT,
|
||||
STATUS_GOODSIG,
|
||||
STATUS_BADSIG,
|
||||
STATUS_ERRSIG,
|
||||
STATUS_BADARMOR,
|
||||
STATUS_RSA_OR_IDEA,
|
||||
STATUS_SIGEXPIRED,
|
||||
STATUS_KEYREVOKED,
|
||||
STATUS_TRUST_UNDEFINED,
|
||||
STATUS_TRUST_NEVER,
|
||||
STATUS_TRUST_MARGINAL,
|
||||
STATUS_TRUST_FULLY,
|
||||
STATUS_TRUST_ULTIMATE,
|
||||
|
||||
STATUS_SHM_INFO,
|
||||
STATUS_SHM_GET,
|
||||
STATUS_SHM_GET_BOOL,
|
||||
STATUS_SHM_GET_HIDDEN,
|
||||
|
||||
STATUS_NEED_PASSPHRASE,
|
||||
STATUS_VALIDSIG,
|
||||
STATUS_SIG_ID,
|
||||
STATUS_ENC_TO,
|
||||
STATUS_NODATA,
|
||||
STATUS_BAD_PASSPHRASE,
|
||||
STATUS_NO_PUBKEY,
|
||||
STATUS_NO_SECKEY,
|
||||
STATUS_NEED_PASSPHRASE_SYM,
|
||||
STATUS_DECRYPTION_FAILED,
|
||||
STATUS_DECRYPTION_OKAY,
|
||||
STATUS_MISSING_PASSPHRASE,
|
||||
STATUS_GOOD_PASSPHRASE,
|
||||
STATUS_GOODMDC,
|
||||
STATUS_BADMDC,
|
||||
STATUS_ERRMDC,
|
||||
STATUS_IMPORTED,
|
||||
STATUS_IMPORT_PROBLEM,
|
||||
STATUS_IMPORT_RES,
|
||||
STATUS_FILE_START,
|
||||
STATUS_FILE_DONE,
|
||||
STATUS_FILE_ERROR,
|
||||
|
||||
STATUS_BEGIN_DECRYPTION,
|
||||
STATUS_END_DECRYPTION,
|
||||
STATUS_BEGIN_ENCRYPTION,
|
||||
STATUS_END_ENCRYPTION,
|
||||
|
||||
STATUS_DELETE_PROBLEM,
|
||||
STATUS_GET_BOOL,
|
||||
STATUS_GET_LINE,
|
||||
STATUS_GET_HIDDEN,
|
||||
STATUS_GOT_IT,
|
||||
STATUS_PROGRESS,
|
||||
STATUS_SIG_CREATED,
|
||||
STATUS_SESSION_KEY,
|
||||
STATUS_NOTATION_NAME,
|
||||
STATUS_NOTATION_DATA,
|
||||
STATUS_POLICY_URL,
|
||||
STATUS_BEGIN_STREAM,
|
||||
STATUS_END_STREAM,
|
||||
STATUS_KEY_CREATED,
|
||||
STATUS_USERID_HIN,
|
||||
STATUS_UNEXPECTED,
|
||||
STATUS_INV_RECP,
|
||||
STATUS_NO_RECP,
|
||||
STATUS_ALREADY_SIGNED,
|
||||
|
||||
STATUS_EXPSIG,
|
||||
STATUS_EXPKEYSIG,
|
||||
|
||||
STATUS_TRUNCATED,
|
||||
STATUS_ERROR
|
||||
};
|
||||
|
||||
|
||||
/*-- errors.c (build by mkerror and mkerrtok) --*/
|
||||
const char *gnupg_strerror (int err);
|
||||
const char *gnupg_error_token (int err);
|
||||
|
||||
|
||||
#endif /*GNUPG_COMMON_ERRORS_H*/
|
250
common/gettime.c
Normal file
250
common/gettime.c
Normal file
|
@ -0,0 +1,250 @@
|
|||
/* gettime.c - Wrapper for time functions
|
||||
* Copyright (C) 1998, 2002 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static unsigned long timewarp;
|
||||
static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode;
|
||||
|
||||
/* Wrapper for the time(3). We use this here so we can fake the time
|
||||
for tests */
|
||||
time_t
|
||||
gnupg_get_time ()
|
||||
{
|
||||
time_t current = time (NULL);
|
||||
if (timemode == NORMAL)
|
||||
return current;
|
||||
else if (timemode == FROZEN)
|
||||
return timewarp;
|
||||
else if (timemode == FUTURE)
|
||||
return current + timewarp;
|
||||
else
|
||||
return current - timewarp;
|
||||
}
|
||||
|
||||
/* set the time to NEWTIME so that gnupg_get_time returns a time
|
||||
starting with this one. With FREEZE set to 1 the returned time
|
||||
will never change. Just for completeness, a value of (time_t)-1
|
||||
for NEWTIME gets you back to rality. Note that this is obviously
|
||||
not thread-safe but this is not required. */
|
||||
void
|
||||
gnupg_set_time (time_t newtime, int freeze)
|
||||
{
|
||||
time_t current = time (NULL);
|
||||
|
||||
if ( newtime == (time_t)-1 || current == newtime)
|
||||
{
|
||||
timemode = NORMAL;
|
||||
timewarp = 0;
|
||||
}
|
||||
else if (freeze)
|
||||
{
|
||||
timemode = FROZEN;
|
||||
timewarp = current;
|
||||
}
|
||||
else if (newtime > current)
|
||||
{
|
||||
timemode = FUTURE;
|
||||
timewarp = newtime - current;
|
||||
}
|
||||
else
|
||||
{
|
||||
timemode = PAST;
|
||||
timewarp = current - newtime;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true when we are in timewarp mode */
|
||||
int
|
||||
gnupg_faked_time_p (void)
|
||||
{
|
||||
return timemode;
|
||||
}
|
||||
|
||||
|
||||
/* This function is used by gpg because OpenPGP defines the timestamp
|
||||
as an unsigned 32 bit value. */
|
||||
u32
|
||||
make_timestamp (void)
|
||||
{
|
||||
time_t t = gnupg_get_time ();
|
||||
|
||||
if (t == (time_t)-1)
|
||||
log_fatal ("gnupg_get_time() failed\n");
|
||||
return (u32)t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Scan a date string and return a timestamp.
|
||||
* The only supported format is "yyyy-mm-dd"
|
||||
* Returns 0 for an invalid date.
|
||||
*/
|
||||
u32
|
||||
scan_isodatestr( const char *string )
|
||||
{
|
||||
int year, month, day;
|
||||
struct tm tmbuf;
|
||||
time_t stamp;
|
||||
int i;
|
||||
|
||||
if( strlen(string) != 10 || string[4] != '-' || string[7] != '-' )
|
||||
return 0;
|
||||
for( i=0; i < 4; i++ )
|
||||
if( !digitp (string+i) )
|
||||
return 0;
|
||||
if( !digitp (string+5) || !digitp(string+6) )
|
||||
return 0;
|
||||
if( !digitp(string+8) || !digitp(string+9) )
|
||||
return 0;
|
||||
year = atoi(string);
|
||||
month = atoi(string+5);
|
||||
day = atoi(string+8);
|
||||
/* some basic checks */
|
||||
if( year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 )
|
||||
return 0;
|
||||
memset( &tmbuf, 0, sizeof tmbuf );
|
||||
tmbuf.tm_mday = day;
|
||||
tmbuf.tm_mon = month-1;
|
||||
tmbuf.tm_year = year - 1900;
|
||||
tmbuf.tm_isdst = -1;
|
||||
stamp = mktime( &tmbuf );
|
||||
if( stamp == (time_t)-1 )
|
||||
return 0;
|
||||
return stamp;
|
||||
}
|
||||
|
||||
|
||||
u32
|
||||
add_days_to_timestamp( u32 stamp, u16 days )
|
||||
{
|
||||
return stamp + days*86400L;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return a string with a time value in the form: x Y, n D, n H
|
||||
*/
|
||||
|
||||
const char *
|
||||
strtimevalue( u32 value )
|
||||
{
|
||||
static char buffer[30];
|
||||
unsigned int years, days, hours, minutes;
|
||||
|
||||
value /= 60;
|
||||
minutes = value % 60;
|
||||
value /= 60;
|
||||
hours = value % 24;
|
||||
value /= 24;
|
||||
days = value % 365;
|
||||
value /= 365;
|
||||
years = value;
|
||||
|
||||
sprintf(buffer,"%uy%ud%uh%um", years, days, hours, minutes );
|
||||
if( years )
|
||||
return buffer;
|
||||
if( days )
|
||||
return strchr( buffer, 'y' ) + 1;
|
||||
return strchr( buffer, 'd' ) + 1;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Note: this function returns GMT
|
||||
*/
|
||||
const char *
|
||||
strtimestamp( u32 stamp )
|
||||
{
|
||||
static char buffer[11+5];
|
||||
struct tm *tp;
|
||||
time_t atime = stamp;
|
||||
|
||||
if (atime < 0) {
|
||||
strcpy (buffer, "????" "-??" "-??");
|
||||
}
|
||||
else {
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d",
|
||||
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Note: this function returns local time
|
||||
*/
|
||||
const char *
|
||||
asctimestamp( u32 stamp )
|
||||
{
|
||||
static char buffer[50];
|
||||
#if defined (HAVE_STRFTIME) && defined (HAVE_NL_LANGINFO)
|
||||
static char fmt[50];
|
||||
#endif
|
||||
struct tm *tp;
|
||||
time_t atime = stamp;
|
||||
|
||||
if (atime < 0) {
|
||||
strcpy (buffer, "????" "-??" "-??");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
tp = localtime( &atime );
|
||||
#ifdef HAVE_STRFTIME
|
||||
#if defined(HAVE_NL_LANGINFO)
|
||||
mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 );
|
||||
if( strstr( fmt, "%Z" ) == NULL )
|
||||
strcat( fmt, " %Z");
|
||||
strftime( buffer, DIM(buffer)-1, fmt, tp );
|
||||
#else
|
||||
/* fixme: we should check whether the locale appends a " %Z"
|
||||
* These locales from glibc don't put the " %Z":
|
||||
* fi_FI hr_HR ja_JP lt_LT lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN
|
||||
*/
|
||||
strftime( buffer, DIM(buffer)-1, "%c %Z", tp );
|
||||
#endif
|
||||
buffer[DIM(buffer)-1] = 0;
|
||||
#else
|
||||
mem2str( buffer, asctime(tp), DIM(buffer) );
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
2415
common/iobuf.c
Normal file
2415
common/iobuf.c
Normal file
File diff suppressed because it is too large
Load diff
170
common/iobuf.h
Normal file
170
common/iobuf.h
Normal file
|
@ -0,0 +1,170 @@
|
|||
/* iobuf.h - I/O buffer
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef GNUPG_COMMON_IOBUF_H
|
||||
#define GNUPG_COMMON_IOBUF_H
|
||||
|
||||
#include "../include/types.h" /* fixme: should be moved elsewhere. */
|
||||
|
||||
|
||||
#define DBG_IOBUF iobuf_debug_mode
|
||||
|
||||
|
||||
#define IOBUFCTRL_INIT 1
|
||||
#define IOBUFCTRL_FREE 2
|
||||
#define IOBUFCTRL_UNDERFLOW 3
|
||||
#define IOBUFCTRL_FLUSH 4
|
||||
#define IOBUFCTRL_DESC 5
|
||||
#define IOBUFCTRL_CANCEL 6
|
||||
#define IOBUFCTRL_USER 16
|
||||
|
||||
typedef struct iobuf_struct *iobuf_t;
|
||||
|
||||
/* fixme: we should hide most of this stuff */
|
||||
struct iobuf_struct
|
||||
{
|
||||
int use; /* 1 input , 2 output, 3 temp */
|
||||
off_t nlimit;
|
||||
off_t nbytes; /* used together with nlimit */
|
||||
off_t ntotal; /* total bytes read (position of stream) */
|
||||
int nofast; /* used by the iobuf_get() */
|
||||
void *directfp;
|
||||
struct
|
||||
{
|
||||
size_t size; /* allocated size */
|
||||
size_t start; /* number of invalid bytes at the begin of the buffer */
|
||||
size_t len; /* currently filled to this size */
|
||||
byte *buf;
|
||||
}
|
||||
d;
|
||||
int filter_eof;
|
||||
int error;
|
||||
int (*filter) (void *opaque, int control,
|
||||
iobuf_t chain, byte * buf, size_t * len);
|
||||
void *filter_ov; /* value for opaque */
|
||||
int filter_ov_owner;
|
||||
char *real_fname;
|
||||
iobuf_t chain; /* next iobuf used for i/o if any
|
||||
(passed to filter) */
|
||||
int no, subno;
|
||||
const char *desc;
|
||||
void *opaque; /* can be used to hold any information
|
||||
this value is copied to all
|
||||
instances */
|
||||
struct
|
||||
{
|
||||
size_t size; /* allocated size */
|
||||
size_t start; /* number of invalid bytes at the
|
||||
begin of the buffer */
|
||||
size_t len; /* currently filled to this size */
|
||||
byte *buf;
|
||||
}
|
||||
unget;
|
||||
};
|
||||
|
||||
#ifndef EXTERN_UNLESS_MAIN_MODULE
|
||||
#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
|
||||
#define EXTERN_UNLESS_MAIN_MODULE extern
|
||||
#else
|
||||
#define EXTERN_UNLESS_MAIN_MODULE
|
||||
#endif
|
||||
#endif
|
||||
EXTERN_UNLESS_MAIN_MODULE int iobuf_debug_mode;
|
||||
|
||||
void iobuf_enable_special_filenames (int yes);
|
||||
iobuf_t iobuf_alloc (int use, size_t bufsize);
|
||||
iobuf_t iobuf_temp (void);
|
||||
iobuf_t iobuf_temp_with_content (const char *buffer, size_t length);
|
||||
iobuf_t iobuf_open (const char *fname);
|
||||
iobuf_t iobuf_fdopen (int fd, const char *mode);
|
||||
iobuf_t iobuf_sockopen (int fd, const char *mode);
|
||||
iobuf_t iobuf_create (const char *fname);
|
||||
iobuf_t iobuf_append (const char *fname);
|
||||
iobuf_t iobuf_openrw (const char *fname);
|
||||
int iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval);
|
||||
int iobuf_close (iobuf_t iobuf);
|
||||
int iobuf_cancel (iobuf_t iobuf);
|
||||
|
||||
int iobuf_push_filter (iobuf_t a, int (*f) (void *opaque, int control,
|
||||
iobuf_t chain, byte * buf,
|
||||
size_t * len), void *ov);
|
||||
int iobuf_push_filter2 (iobuf_t a,
|
||||
int (*f) (void *opaque, int control, iobuf_t chain,
|
||||
byte * buf, size_t * len), void *ov,
|
||||
int rel_ov);
|
||||
int iobuf_flush (iobuf_t a);
|
||||
void iobuf_clear_eof (iobuf_t a);
|
||||
#define iobuf_set_error(a) do { (a)->error = 1; } while(0)
|
||||
#define iobuf_error(a) ((a)->error)
|
||||
|
||||
void iobuf_set_limit (iobuf_t a, off_t nlimit);
|
||||
|
||||
off_t iobuf_tell (iobuf_t a);
|
||||
int iobuf_seek (iobuf_t a, off_t newpos);
|
||||
|
||||
int iobuf_readbyte (iobuf_t a);
|
||||
int iobuf_read (iobuf_t a, byte * buf, unsigned buflen);
|
||||
unsigned iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
|
||||
unsigned *length_of_buffer, unsigned *max_length);
|
||||
int iobuf_peek (iobuf_t a, byte * buf, unsigned buflen);
|
||||
int iobuf_writebyte (iobuf_t a, unsigned c);
|
||||
int iobuf_write (iobuf_t a, byte * buf, unsigned buflen);
|
||||
int iobuf_writestr (iobuf_t a, const char *buf);
|
||||
|
||||
void iobuf_flush_temp (iobuf_t temp);
|
||||
int iobuf_write_temp (iobuf_t a, iobuf_t temp);
|
||||
size_t iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen);
|
||||
void iobuf_unget_and_close_temp (iobuf_t a, iobuf_t temp);
|
||||
|
||||
off_t iobuf_get_filelength (iobuf_t a);
|
||||
#define IOBUF_FILELENGTH_LIMIT 0xffffffff
|
||||
const char *iobuf_get_real_fname (iobuf_t a);
|
||||
const char *iobuf_get_fname (iobuf_t a);
|
||||
|
||||
void iobuf_set_block_mode (iobuf_t a, size_t n);
|
||||
void iobuf_set_partial_block_mode (iobuf_t a, size_t len);
|
||||
int iobuf_in_block_mode (iobuf_t a);
|
||||
|
||||
int iobuf_translate_file_handle (int fd, int for_write);
|
||||
|
||||
|
||||
/* get a byte form the iobuf; must check for eof prior to this function
|
||||
* this function returns values in the range 0 .. 255 or -1 to indicate EOF
|
||||
* iobuf_get_noeof() does not return -1 to indicate EOF, but masks the
|
||||
* returned value to be in the range 0 ..255.
|
||||
*/
|
||||
#define iobuf_get(a) \
|
||||
( ((a)->nofast || (a)->d.start >= (a)->d.len )? \
|
||||
iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) )
|
||||
#define iobuf_get_noeof(a) (iobuf_get((a))&0xff)
|
||||
|
||||
/* write a byte to the iobuf and return true on write error
|
||||
* This macro does only write the low order byte
|
||||
*/
|
||||
#define iobuf_put(a,c) iobuf_writebyte(a,c)
|
||||
|
||||
#define iobuf_where(a) "[don't know]"
|
||||
#define iobuf_id(a) ((a)->no)
|
||||
|
||||
#define iobuf_get_temp_buffer(a) ( (a)->d.buf )
|
||||
#define iobuf_get_temp_length(a) ( (a)->d.len )
|
||||
#define iobuf_is_temp(a) ( (a)->use == 3 )
|
||||
|
||||
#endif /*GNUPG_COMMON_IOBUF_H*/
|
157
common/maperror.c
Normal file
157
common/maperror.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* maperror.c - Error mapping
|
||||
* Copyright (C) 2001, 2002 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ksba.h>
|
||||
#include <assuan.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "errors.h"
|
||||
|
||||
/* Note: we might want to wrap this in a macro to get our hands on
|
||||
the line and file where the error occured */
|
||||
int
|
||||
map_ksba_err (int err)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case -1:
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case KSBA_Out_Of_Core: err = GPG_ERR_ENOMEM; break;
|
||||
case KSBA_Invalid_Value: err = GPG_ERR_INV_VALUE; break;
|
||||
case KSBA_Not_Implemented: err = GPG_ERR_NOT_IMPLEMENTED; break;
|
||||
case KSBA_Conflict: err = GPG_ERR_CONFLICT; break;
|
||||
case KSBA_Read_Error: err = GPG_ERR_EIO; break;
|
||||
case KSBA_Write_Error: err = GPG_ERR_EIO; break;
|
||||
case KSBA_No_Data: err = GPG_ERR_NO_DATA; break;
|
||||
case KSBA_Bug: err = GPG_ERR_BUG; break;
|
||||
case KSBA_Unsupported_Algorithm: err = GPG_ERR_UNSUPPORTED_ALGORITHM; break;
|
||||
case KSBA_Invalid_Index: err = GPG_ERR_INV_INDEX; break;
|
||||
case KSBA_Invalid_Sexp: err = GPG_ERR_INV_SEXP; break;
|
||||
case KSBA_Unknown_Sexp: err = GPG_ERR_UNKNOWN_SEXP; break;
|
||||
|
||||
default:
|
||||
err = GPG_ERR_GENERAL;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
map_gcry_err (int err)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
map_kbx_err (int err)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Map Assuan error code ERR to an GPG_ERR_ code. We need to
|
||||
distinguish between genuine (and legacy) Assuan error codes and
|
||||
application error codes shared with all GnuPG modules. The rule is
|
||||
simple: All errors with a gpg_err_source of UNKNOWN are genuine
|
||||
Assuan codes all others are passed verbatim through. */
|
||||
gpg_error_t
|
||||
map_assuan_err (int err)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
|
||||
if (gpg_err_source (err))
|
||||
return err;
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case -1: ec = GPG_ERR_EOF; break;
|
||||
case 0: ec = 0; break;
|
||||
|
||||
case ASSUAN_Canceled: ec = GPG_ERR_CANCELED; break;
|
||||
case ASSUAN_Invalid_Index: ec = GPG_ERR_INV_INDEX; break;
|
||||
|
||||
case ASSUAN_Not_Implemented: ec = GPG_ERR_NOT_IMPLEMENTED; break;
|
||||
case ASSUAN_Server_Fault: ec = GPG_ERR_ASSUAN_SERVER_FAULT; break;
|
||||
case ASSUAN_No_Public_Key: ec = GPG_ERR_NO_PUBKEY; break;
|
||||
case ASSUAN_No_Secret_Key: ec = GPG_ERR_NO_SECKEY; break;
|
||||
|
||||
case ASSUAN_Cert_Revoked: ec = GPG_ERR_CERT_REVOKED; break;
|
||||
case ASSUAN_No_CRL_For_Cert: ec = GPG_ERR_NO_CRL_KNOWN; break;
|
||||
case ASSUAN_CRL_Too_Old: ec = GPG_ERR_CRL_TOO_OLD; break;
|
||||
|
||||
case ASSUAN_Not_Trusted: ec = GPG_ERR_NOT_TRUSTED; break;
|
||||
|
||||
case ASSUAN_Card_Error: ec = GPG_ERR_CARD; break;
|
||||
case ASSUAN_Invalid_Card: ec = GPG_ERR_INV_CARD; break;
|
||||
case ASSUAN_No_PKCS15_App: ec = GPG_ERR_NO_PKCS15_APP; break;
|
||||
case ASSUAN_Card_Not_Present: ec= GPG_ERR_CARD_NOT_PRESENT; break;
|
||||
case ASSUAN_Not_Confirmed: ec = GPG_ERR_NOT_CONFIRMED; break;
|
||||
case ASSUAN_Invalid_Id: ec = GPG_ERR_INV_ID; break;
|
||||
|
||||
default:
|
||||
ec = err < 100? GPG_ERR_ASSUAN_SERVER_FAULT : GPG_ERR_ASSUAN;
|
||||
break;
|
||||
}
|
||||
return gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, ec);
|
||||
}
|
||||
|
||||
/* Map GPG_xERR_xx error codes to Assuan status codes */
|
||||
int
|
||||
map_to_assuan_status (int rc)
|
||||
{
|
||||
gpg_err_code_t ec = gpg_err_code (rc);
|
||||
gpg_err_source_t es = gpg_err_source (rc);
|
||||
|
||||
if (!rc)
|
||||
return 0;
|
||||
if (!es)
|
||||
{
|
||||
es = GPG_ERR_SOURCE_USER_4; /* This should not happen, but we
|
||||
need to make sure to pass a new
|
||||
Assuan errorcode along. */
|
||||
log_debug ("map_to_assuan_status called with no error source\n");
|
||||
}
|
||||
|
||||
if (ec == -1)
|
||||
ec = GPG_ERR_NO_DATA; /* That used to be ASSUAN_No_Data_Available. */
|
||||
|
||||
return gpg_err_make (es, ec);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
89
common/membuf.c
Normal file
89
common/membuf.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/* membuf.c - A simple implementation of a dynamic buffer
|
||||
* Copyright (C) 2001, 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "membuf.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/* A simple implementation of a dynamic buffer. Use init_membuf() to
|
||||
create a buffer, put_membuf to append bytes and get_membuf to
|
||||
release and return the buffer. Allocation errors are detected but
|
||||
only returned at the final get_membuf(), this helps not to clutter
|
||||
the code with out of core checks. */
|
||||
|
||||
void
|
||||
init_membuf (membuf_t *mb, int initiallen)
|
||||
{
|
||||
mb->len = 0;
|
||||
mb->size = initiallen;
|
||||
mb->out_of_core = 0;
|
||||
mb->buf = xtrymalloc (initiallen);
|
||||
if (!mb->buf)
|
||||
mb->out_of_core = errno;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_membuf (membuf_t *mb, const void *buf, size_t len)
|
||||
{
|
||||
if (mb->out_of_core)
|
||||
return;
|
||||
|
||||
if (mb->len + len >= mb->size)
|
||||
{
|
||||
char *p;
|
||||
|
||||
mb->size += len + 1024;
|
||||
p = xtryrealloc (mb->buf, mb->size);
|
||||
if (!p)
|
||||
{
|
||||
mb->out_of_core = errno;
|
||||
return;
|
||||
}
|
||||
mb->buf = p;
|
||||
}
|
||||
memcpy (mb->buf + mb->len, buf, len);
|
||||
mb->len += len;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
get_membuf (membuf_t *mb, size_t *len)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (mb->out_of_core)
|
||||
{
|
||||
xfree (mb->buf);
|
||||
mb->buf = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = mb->buf;
|
||||
*len = mb->len;
|
||||
mb->buf = NULL;
|
||||
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
|
||||
return p;
|
||||
}
|
41
common/membuf.h
Normal file
41
common/membuf.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* membuf.h - A simple implementation of a dynamic buffer
|
||||
* Copyright (C) 2001, 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef GNUPG_COMMON_MEMBUF_H
|
||||
#define GNUPG_COMMON_MEMBUF_H
|
||||
|
||||
/* The definition of the structure is private, we only need it here,
|
||||
so it can be allocated on the stack. */
|
||||
struct private_membuf_s {
|
||||
size_t len;
|
||||
size_t size;
|
||||
char *buf;
|
||||
int out_of_core;
|
||||
};
|
||||
|
||||
typedef struct private_membuf_s membuf_t;
|
||||
|
||||
|
||||
void init_membuf (membuf_t *mb, int initiallen);
|
||||
void put_membuf (membuf_t *mb, const void *buf, size_t len);
|
||||
void *get_membuf (membuf_t *mb, size_t *len);
|
||||
|
||||
|
||||
#endif /*GNUPG_COMMON_MEMBUF_H*/
|
126
common/miscellaneous.c
Normal file
126
common/miscellaneous.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/* miscellaneous.c - Stuff not fitting elsewhere
|
||||
* Copyright (C) 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "iobuf.h"
|
||||
|
||||
/* Decide whether the filename is stdout or a real filename and return
|
||||
* an appropriate string. */
|
||||
const char *
|
||||
print_fname_stdout (const char *s)
|
||||
{
|
||||
if( !s || (*s == '-' && !s[1]) )
|
||||
return "[stdout]";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Decide whether the filename is stdin or a real filename and return
|
||||
* an appropriate string. */
|
||||
const char *
|
||||
print_fname_stdin (const char *s)
|
||||
{
|
||||
if( !s || (*s == '-' && !s[1]) )
|
||||
return "[stdin]";
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
print_string( FILE *fp, const byte *p, size_t n, int delim )
|
||||
{
|
||||
print_sanitized_buffer (fp, p, n, delim);
|
||||
}
|
||||
|
||||
void
|
||||
print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim )
|
||||
{
|
||||
print_sanitized_utf8_buffer (fp, p, n, delim);
|
||||
}
|
||||
|
||||
void
|
||||
print_utf8_string( FILE *fp, const byte *p, size_t n )
|
||||
{
|
||||
print_utf8_string2 (fp, p, n, 0);
|
||||
}
|
||||
|
||||
char *
|
||||
make_printable_string( const byte *p, size_t n, int delim )
|
||||
{
|
||||
return sanitize_buffer (p, n, delim);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if the file is compressed.
|
||||
*/
|
||||
int
|
||||
is_file_compressed (const char *s, int *ret_rc)
|
||||
{
|
||||
iobuf_t a;
|
||||
byte buf[4];
|
||||
int i, rc = 0;
|
||||
|
||||
struct magic_compress_s {
|
||||
size_t len;
|
||||
byte magic[4];
|
||||
} magic[] = {
|
||||
{ 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
|
||||
{ 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
|
||||
{ 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
|
||||
};
|
||||
|
||||
if ( !s || (*s == '-' && !s[1]) || !ret_rc )
|
||||
return 0; /* We can't check stdin or no file was given */
|
||||
|
||||
a = iobuf_open( s );
|
||||
if ( a == NULL ) {
|
||||
*ret_rc = gpg_error_from_errno (errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( iobuf_get_filelength( a ) < 4 ) {
|
||||
*ret_rc = 0;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if ( iobuf_read( a, buf, 4 ) == -1 ) {
|
||||
*ret_rc = a->error;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
for ( i = 0; i < DIM( magic ); i++ ) {
|
||||
if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) {
|
||||
*ret_rc = 0;
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
iobuf_close( a );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
486
common/simple-pwquery.c
Normal file
486
common/simple-pwquery.c
Normal file
|
@ -0,0 +1,486 @@
|
|||
/* simple-pwquery.c - A simple password query cleint for gpg-agent
|
||||
* Copyright (C) 2002 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/* This module is intended as a standalone client implementation to
|
||||
gpg-agent's GET_PASSPHRASE command. In particular it does not use
|
||||
the Assuan library and can only cope with an already running
|
||||
gpg-agent. Some stuff is configurable in the header file. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#define SIMPLE_PWQUERY_IMPLEMENTATION 1
|
||||
#include "simple-pwquery.h"
|
||||
|
||||
#if defined(SPWQ_USE_LOGGING) && !defined(HAVE_JNLIB_LOGGING)
|
||||
# undef SPWQ_USE_LOGGING
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
#define _(a) (a)
|
||||
#endif
|
||||
|
||||
#if !defined (hexdigitp) && !defined (xtoi_2)
|
||||
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
|
||||
#define hexdigitp(a) (digitp (a) \
|
||||
|| (*(a) >= 'A' && *(a) <= 'F') \
|
||||
|| (*(a) >= 'a' && *(a) <= 'f'))
|
||||
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
||||
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||
#endif
|
||||
|
||||
|
||||
/* Write NBYTES of BUF to file descriptor FD. */
|
||||
static int
|
||||
writen (int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
size_t nleft = nbytes;
|
||||
int nwritten;
|
||||
|
||||
while (nleft > 0)
|
||||
{
|
||||
nwritten = write( fd, buf, nleft );
|
||||
if (nwritten < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
nwritten = 0;
|
||||
else {
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error ("write failed: %s\n", strerror (errno));
|
||||
#endif
|
||||
return SPWQ_IO_ERROR;
|
||||
}
|
||||
}
|
||||
nleft -= nwritten;
|
||||
buf = (const char*)buf + nwritten;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Read an entire line and return number of bytes read. */
|
||||
static int
|
||||
readline (int fd, char *buf, size_t buflen)
|
||||
{
|
||||
size_t nleft = buflen;
|
||||
char *p;
|
||||
int nread = 0;
|
||||
|
||||
while (nleft > 0)
|
||||
{
|
||||
int n = read (fd, buf, nleft);
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return -(SPWQ_IO_ERROR);
|
||||
}
|
||||
else if (!n)
|
||||
{
|
||||
return -(SPWQ_PROTOCOL_ERROR); /* incomplete line */
|
||||
}
|
||||
p = buf;
|
||||
nleft -= n;
|
||||
buf += n;
|
||||
nread += n;
|
||||
|
||||
for (; n && *p != '\n'; n--, p++)
|
||||
;
|
||||
if (n)
|
||||
{
|
||||
break; /* at least one full line available - that's enough.
|
||||
This function is just a simple implementation, so
|
||||
it is okay to forget about pending bytes */
|
||||
}
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
|
||||
/* Send an option to the agent */
|
||||
static int
|
||||
agent_send_option (int fd, const char *name, const char *value)
|
||||
{
|
||||
char buf[200];
|
||||
int nread;
|
||||
char *line;
|
||||
int i;
|
||||
|
||||
line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2);
|
||||
if (!line)
|
||||
return SPWQ_OUT_OF_CORE;
|
||||
strcpy (stpcpy (stpcpy (stpcpy (
|
||||
stpcpy (line, "OPTION "), name), "="), value), "\n");
|
||||
i = writen (fd, line, strlen (line));
|
||||
spwq_free (line);
|
||||
if (i)
|
||||
return i;
|
||||
|
||||
/* get response */
|
||||
nread = readline (fd, buf, DIM(buf)-1);
|
||||
if (nread < 0)
|
||||
return -nread;
|
||||
if (nread < 3)
|
||||
return SPWQ_PROTOCOL_ERROR;
|
||||
|
||||
if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n'))
|
||||
return 0; /* okay */
|
||||
|
||||
return SPWQ_ERR_RESPONSE;
|
||||
}
|
||||
|
||||
|
||||
/* Send all available options to the agent. */
|
||||
static int
|
||||
agent_send_all_options (int fd)
|
||||
{
|
||||
char *dft_display = NULL;
|
||||
char *dft_ttyname = NULL;
|
||||
char *dft_ttytype = NULL;
|
||||
int rc = 0;
|
||||
|
||||
dft_display = getenv ("DISPLAY");
|
||||
if (dft_display)
|
||||
{
|
||||
if ((rc = agent_send_option (fd, "display", dft_display)))
|
||||
return rc;
|
||||
}
|
||||
|
||||
dft_ttyname = getenv ("GPG_TTY");
|
||||
if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
|
||||
dft_ttyname = ttyname (0);
|
||||
if (dft_ttyname && *dft_ttyname)
|
||||
{
|
||||
if ((rc=agent_send_option (fd, "ttyname", dft_ttyname)))
|
||||
return rc;
|
||||
}
|
||||
|
||||
dft_ttytype = getenv ("TERM");
|
||||
if (dft_ttyname && dft_ttytype)
|
||||
{
|
||||
if ((rc = agent_send_option (fd, "ttytype", dft_ttytype)))
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SETLOCALE)
|
||||
{
|
||||
char *old_lc = NULL;
|
||||
char *dft_lc = NULL;
|
||||
|
||||
#if defined(LC_CTYPE)
|
||||
old_lc = setlocale (LC_CTYPE, NULL);
|
||||
if (old_lc)
|
||||
{
|
||||
char *p = spwq_malloc (strlen (old_lc)+1);
|
||||
if (!p)
|
||||
return SPWQ_OUT_OF_CORE;
|
||||
strcpy (p, old_lc);
|
||||
old_lc = p;
|
||||
}
|
||||
dft_lc = setlocale (LC_CTYPE, "");
|
||||
if (dft_ttyname && dft_lc)
|
||||
rc = agent_send_option (fd, "lc-ctype", dft_lc);
|
||||
if (old_lc)
|
||||
{
|
||||
setlocale (LC_CTYPE, old_lc);
|
||||
spwq_free (old_lc);
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
#endif
|
||||
|
||||
#if defined(LC_MESSAGES)
|
||||
old_lc = setlocale (LC_MESSAGES, NULL);
|
||||
if (old_lc)
|
||||
{
|
||||
char *p = spwq_malloc (strlen (old_lc)+1);
|
||||
if (!p)
|
||||
return SPWQ_OUT_OF_CORE;
|
||||
strcpy (p, old_lc);
|
||||
old_lc = p;
|
||||
}
|
||||
dft_lc = setlocale (LC_MESSAGES, "");
|
||||
if (dft_ttyname && dft_lc)
|
||||
rc = agent_send_option (fd, "lc-messages", dft_lc);
|
||||
if (old_lc)
|
||||
{
|
||||
setlocale (LC_MESSAGES, old_lc);
|
||||
spwq_free (old_lc);
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
#endif /*HAVE_SETLOCALE*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Try to open a connection to the agent, send all options and return
|
||||
the file descriptor for the connection. Return -1 in case of
|
||||
error. */
|
||||
static int
|
||||
agent_open (int *rfd)
|
||||
{
|
||||
int rc;
|
||||
int fd;
|
||||
char *infostr, *p;
|
||||
struct sockaddr_un client_addr;
|
||||
size_t len;
|
||||
int prot;
|
||||
char line[200];
|
||||
int nread;
|
||||
|
||||
*rfd = -1;
|
||||
infostr = getenv ( "GPG_AGENT_INFO" );
|
||||
if ( !infostr )
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error (_("gpg-agent is not available in this session\n"));
|
||||
#endif
|
||||
return SPWQ_NO_AGENT;
|
||||
}
|
||||
|
||||
if ( !(p = strchr ( infostr, ':')) || p == infostr
|
||||
|| (p-infostr)+1 >= sizeof client_addr.sun_path )
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error ( _("malformed GPG_AGENT_INFO environment variable\n"));
|
||||
#endif
|
||||
return SPWQ_NO_AGENT;
|
||||
}
|
||||
*p++ = 0;
|
||||
|
||||
while (*p && *p != ':')
|
||||
p++;
|
||||
prot = *p? atoi (p+1) : 0;
|
||||
if ( prot != 1)
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error (_("gpg-agent protocol version %d is not supported\n"),prot);
|
||||
#endif
|
||||
return SPWQ_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error ("can't create socket: %s\n", strerror(errno) );
|
||||
#endif
|
||||
return SPWQ_SYS_ERROR;
|
||||
}
|
||||
|
||||
memset (&client_addr, 0, sizeof client_addr);
|
||||
client_addr.sun_family = AF_UNIX;
|
||||
strcpy (client_addr.sun_path, infostr);
|
||||
len = (offsetof (struct sockaddr_un, sun_path)
|
||||
+ strlen(client_addr.sun_path) + 1);
|
||||
|
||||
if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1)
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno));
|
||||
#endif
|
||||
close (fd );
|
||||
return SPWQ_IO_ERROR;
|
||||
}
|
||||
|
||||
nread = readline (fd, line, DIM(line));
|
||||
if (nread < 3 || !(line[0] == 'O' && line[1] == 'K'
|
||||
&& (line[2] == '\n' || line[2] == ' ')) )
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error ( _("communication problem with gpg-agent\n"));
|
||||
#endif
|
||||
close (fd );
|
||||
return SPWQ_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
rc = agent_send_all_options (fd);
|
||||
if (rc)
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error (_("problem setting the gpg-agent options\n"));
|
||||
#endif
|
||||
close (fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*rfd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Copy text to BUFFER and escape as required. Return a poiinter to
|
||||
the end of the new buffer. NOte that BUFFER must be large enough
|
||||
to keep the entire text; allocataing it 3 times the size of TEXT
|
||||
is sufficient. */
|
||||
static char *
|
||||
copy_and_escape (char *buffer, const char *text)
|
||||
{
|
||||
int i;
|
||||
char *p = buffer;
|
||||
|
||||
for (i=0; text[i]; i++)
|
||||
{
|
||||
if (text[i] < ' ' || text[i] == '+')
|
||||
{
|
||||
sprintf (p, "%%%02X", text[i]);
|
||||
p += 3;
|
||||
}
|
||||
else if (text[i] == ' ')
|
||||
*p++ = '+';
|
||||
else
|
||||
*p++ = text[i];
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Ask the gpg-agent for a passphrase and present the user with a
|
||||
DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text.
|
||||
If a CACHEID is not NULL it is used to locate the passphrase in in
|
||||
the cache and store it under this ID. If ERRORCODE is not NULL it
|
||||
should point a variable receiving an errorcode; thsi errocode might
|
||||
be 0 if the user canceled the operation. The function returns NULL
|
||||
to indicate an error. */
|
||||
char *
|
||||
simple_pwquery (const char *cacheid,
|
||||
const char *tryagain,
|
||||
const char *prompt,
|
||||
const char *description,
|
||||
int *errorcode)
|
||||
{
|
||||
int fd = -1;
|
||||
int nread;
|
||||
char *result = NULL;
|
||||
char *pw = NULL;
|
||||
char *p;
|
||||
int rc, i;
|
||||
|
||||
rc = agent_open (&fd);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
if (!cacheid)
|
||||
cacheid = "X";
|
||||
if (!tryagain)
|
||||
tryagain = "X";
|
||||
if (!prompt)
|
||||
prompt = "X";
|
||||
if (!description)
|
||||
description = "X";
|
||||
|
||||
{
|
||||
char *line;
|
||||
/* We allocate 3 times the needed space so that there is enough
|
||||
space for escaping. */
|
||||
line = spwq_malloc (15
|
||||
+ 3*strlen (cacheid) + 1
|
||||
+ 3*strlen (tryagain) + 1
|
||||
+ 3*strlen (prompt) + 1
|
||||
+ 3*strlen (description) + 1
|
||||
+ 2);
|
||||
if (!line)
|
||||
{
|
||||
rc = SPWQ_OUT_OF_CORE;
|
||||
goto leave;
|
||||
}
|
||||
strcpy (line, "GET_PASSPHRASE ");
|
||||
p = line+15;
|
||||
p = copy_and_escape (p, cacheid);
|
||||
*p++ = ' ';
|
||||
p = copy_and_escape (p, tryagain);
|
||||
*p++ = ' ';
|
||||
p = copy_and_escape (p, prompt);
|
||||
*p++ = ' ';
|
||||
p = copy_and_escape (p, description);
|
||||
*p++ = '\n';
|
||||
rc = writen (fd, line, p - line);
|
||||
spwq_free (line);
|
||||
if (rc)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* get response */
|
||||
pw = spwq_secure_malloc (500);
|
||||
nread = readline (fd, pw, 499);
|
||||
if (nread < 0)
|
||||
{
|
||||
rc = -nread;
|
||||
goto leave;
|
||||
}
|
||||
if (nread < 3)
|
||||
{
|
||||
rc = SPWQ_PROTOCOL_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ')
|
||||
{ /* we got a passphrase - convert it back from hex */
|
||||
size_t pwlen = 0;
|
||||
|
||||
for (i=3; i < nread && hexdigitp (pw+i); i+=2)
|
||||
pw[pwlen++] = xtoi_2 (pw+i);
|
||||
pw[pwlen] = 0; /* make a C String */
|
||||
result = pw;
|
||||
pw = NULL;
|
||||
}
|
||||
else if (nread > 7 && !memcmp (pw, "ERR 111", 7)
|
||||
&& (pw[7] == ' ' || pw[7] == '\n') )
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_info (_("canceled by user\n") );
|
||||
#endif
|
||||
*errorcode = 0; /* canceled */
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef SPWQ_USE_LOGGING
|
||||
log_error (_("problem with the agent\n"));
|
||||
#endif
|
||||
rc = SPWQ_ERR_RESPONSE;
|
||||
}
|
||||
|
||||
leave:
|
||||
if (errorcode)
|
||||
*errorcode = rc;
|
||||
if (fd != -1)
|
||||
close (fd);
|
||||
if (pw)
|
||||
spwq_free (pw);
|
||||
return result;
|
||||
}
|
69
common/simple-pwquery.h
Normal file
69
common/simple-pwquery.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* simple-pwquery.c - A simple password query cleint for gpg-agent
|
||||
* Copyright (C) 2002 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef SIMPLE_PWQUERY_H
|
||||
#define SIMPLE_PWQUERY_H
|
||||
|
||||
#ifdef SIMPLE_PWQUERY_IMPLEMENTATION /* Begin configuration stuff. */
|
||||
|
||||
/* Include whatever files you need. */
|
||||
#include <gcrypt.h>
|
||||
#include "../jnlib/logging.h"
|
||||
|
||||
/* Try to write error message using the standard log mechanism. The
|
||||
current implementation requires that the HAVE_JNLIB_LOGGING is also
|
||||
defined. */
|
||||
#define SPWQ_USE_LOGGING 1
|
||||
|
||||
/* Memory allocation functions used by the implementation. Note, that
|
||||
the returned value is expected to be freed with
|
||||
spwq_secure_free. */
|
||||
#define spwq_malloc(a) gcry_malloc (a)
|
||||
#define spwq_free(a) gcry_free (a)
|
||||
#define spwq_secure_malloc(a) gcry_malloc_secure (a)
|
||||
#define spwq_secure_free(a) gcry_free (a)
|
||||
|
||||
|
||||
#endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */
|
||||
|
||||
|
||||
/* Ask the gpg-agent for a passphrase and present the user with a
|
||||
DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text.
|
||||
If a CACHEID is not NULL it is used to locate the passphrase in in
|
||||
the cache and store it under this ID. If ERRORCODE is not NULL it
|
||||
should point a variable receiving an errorcode; this errocode might
|
||||
be 0 if the user canceled the operation. The function returns NULL
|
||||
to indicate an error. */
|
||||
char *simple_pwquery (const char *cacheid,
|
||||
const char *tryagain,
|
||||
const char *prompt,
|
||||
const char *description,
|
||||
int *errorcode);
|
||||
|
||||
|
||||
#define SPWQ_OUT_OF_CORE 1
|
||||
#define SPWQ_IO_ERROR 2
|
||||
#define SPWQ_PROTOCOL_ERROR 3
|
||||
#define SPWQ_ERR_RESPONSE 4
|
||||
#define SPWQ_NO_AGENT 5
|
||||
#define SPWQ_SYS_ERROR 6
|
||||
#define SPWQ_GENERAL_ERROR 7
|
||||
|
||||
#endif /*SIMPLE_PWQUERY_H*/
|
508
common/ttyio.c
Normal file
508
common/ttyio.c
Normal file
|
@ -0,0 +1,508 @@
|
|||
/* ttyio.c - tty i/O functions
|
||||
* Copyright (C) 1998,1999,2000,2001,2002,2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_TCGETATTR
|
||||
#include <termios.h>
|
||||
#else
|
||||
#ifdef HAVE_TERMIO_H
|
||||
/* simulate termios with termio */
|
||||
#include <termio.h>
|
||||
#define termios termio
|
||||
#define tcsetattr ioctl
|
||||
#define TCSAFLUSH TCSETAF
|
||||
#define tcgetattr(A,B) ioctl(A,TCGETA,B)
|
||||
#define HAVE_TCGETATTR
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __MINGW32__ /* use the odd Win32 functions */
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_TCGETATTR
|
||||
#error mingw32 and termios
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
#define CONTROL_D ('D' - 'A' + 1)
|
||||
|
||||
#ifdef __MINGW32__ /* use the odd Win32 functions */
|
||||
static struct {
|
||||
HANDLE in, out;
|
||||
} con;
|
||||
#define DEF_INPMODE (ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT \
|
||||
|ENABLE_PROCESSED_INPUT )
|
||||
#define HID_INPMODE (ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT )
|
||||
#define DEF_OUTMODE (ENABLE_WRAP_AT_EOL_OUTPUT|ENABLE_PROCESSED_OUTPUT)
|
||||
|
||||
#else /* yeah, we have a real OS */
|
||||
static FILE *ttyfp = NULL;
|
||||
#endif
|
||||
|
||||
static int initialized;
|
||||
static int last_prompt_len;
|
||||
static int batchmode;
|
||||
static int no_terminal;
|
||||
|
||||
#ifdef HAVE_TCGETATTR
|
||||
static struct termios termsave;
|
||||
static int restore_termios;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* This is a wrapper around ttyname so that we can use it even when
|
||||
the standard streams are redirected. It figures the name out the
|
||||
first time and returns it in a statically allocated buffer. */
|
||||
const char *
|
||||
tty_get_ttyname (void)
|
||||
{
|
||||
static char *name;
|
||||
|
||||
/* On a GNU system ctermid() always return /dev/tty, so this does
|
||||
not make much sense - however if it is ever changed we do the
|
||||
Right Thing now. */
|
||||
#ifdef HAVE_CTERMID
|
||||
static int got_name;
|
||||
|
||||
if (!got_name)
|
||||
{
|
||||
const char *s;
|
||||
s = ctermid (NULL);
|
||||
if (s)
|
||||
name = strdup (s);
|
||||
got_name = 1;
|
||||
}
|
||||
#endif
|
||||
/* Assume the staandrd tty on memory error or when tehre is no
|
||||
certmid. */
|
||||
return name? name : "/dev/tty";
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_TCGETATTR
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
if( restore_termios ) {
|
||||
restore_termios = 0; /* do it prios in case it is interrupted again */
|
||||
if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
|
||||
log_error("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
init_ttyfp(void)
|
||||
{
|
||||
if( initialized )
|
||||
return;
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.bInheritHandle = TRUE;
|
||||
con.out = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
&sa, OPEN_EXISTING, 0, 0 );
|
||||
if( con.out == INVALID_HANDLE_VALUE )
|
||||
log_fatal("open(CONOUT$) failed: rc=%d", (int)GetLastError() );
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.bInheritHandle = TRUE;
|
||||
con.in = CreateFileA( "CONIN$", GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
&sa, OPEN_EXISTING, 0, 0 );
|
||||
if( con.in == INVALID_HANDLE_VALUE )
|
||||
log_fatal("open(CONIN$) failed: rc=%d", (int)GetLastError() );
|
||||
}
|
||||
SetConsoleMode(con.in, DEF_INPMODE );
|
||||
SetConsoleMode(con.out, DEF_OUTMODE );
|
||||
|
||||
#elif defined(__EMX__)
|
||||
ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
|
||||
#else
|
||||
ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
|
||||
if( !ttyfp ) {
|
||||
log_error("cannot open `%s': %s\n", tty_get_ttyname (),
|
||||
strerror(errno) );
|
||||
exit(2);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_TCGETATTR
|
||||
atexit( cleanup );
|
||||
#endif
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
tty_batchmode( int onoff )
|
||||
{
|
||||
int old = batchmode;
|
||||
if( onoff != -1 )
|
||||
batchmode = onoff;
|
||||
return old;
|
||||
}
|
||||
|
||||
int
|
||||
tty_no_terminal(int onoff)
|
||||
{
|
||||
int old = no_terminal;
|
||||
no_terminal = onoff ? 1 : 0;
|
||||
return old;
|
||||
}
|
||||
|
||||
void
|
||||
tty_printf( const char *fmt, ... )
|
||||
{
|
||||
va_list arg_ptr;
|
||||
|
||||
if (no_terminal)
|
||||
return;
|
||||
|
||||
if( !initialized )
|
||||
init_ttyfp();
|
||||
|
||||
va_start( arg_ptr, fmt ) ;
|
||||
#ifdef __MINGW32__
|
||||
{
|
||||
char *buf = NULL;
|
||||
int n;
|
||||
DWORD nwritten;
|
||||
|
||||
n = vasprintf(&buf, fmt, arg_ptr);
|
||||
if( !buf )
|
||||
log_bug("vasprintf() failed\n");
|
||||
|
||||
if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) )
|
||||
log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
|
||||
if( n != nwritten )
|
||||
log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten );
|
||||
last_prompt_len += n;
|
||||
xfree (buf);
|
||||
}
|
||||
#else
|
||||
last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
|
||||
fflush(ttyfp);
|
||||
#endif
|
||||
va_end(arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Print a string, but filter all control characters out.
|
||||
*/
|
||||
void
|
||||
tty_print_string( byte *p, size_t n )
|
||||
{
|
||||
if (no_terminal)
|
||||
return;
|
||||
|
||||
if( !initialized )
|
||||
init_ttyfp();
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* not so effective, change it if you want */
|
||||
for( ; n; n--, p++ )
|
||||
if( iscntrl( *p ) ) {
|
||||
if( *p == '\n' )
|
||||
tty_printf("\\n");
|
||||
else if( !*p )
|
||||
tty_printf("\\0");
|
||||
else
|
||||
tty_printf("\\x%02x", *p);
|
||||
}
|
||||
else
|
||||
tty_printf("%c", *p);
|
||||
#else
|
||||
for( ; n; n--, p++ )
|
||||
if( iscntrl( *p ) ) {
|
||||
putc('\\', ttyfp);
|
||||
if( *p == '\n' )
|
||||
putc('n', ttyfp);
|
||||
else if( !*p )
|
||||
putc('0', ttyfp);
|
||||
else
|
||||
fprintf(ttyfp, "x%02x", *p );
|
||||
}
|
||||
else
|
||||
putc(*p, ttyfp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
tty_print_utf8_string2( byte *p, size_t n, size_t max_n )
|
||||
{
|
||||
size_t i;
|
||||
char *buf;
|
||||
|
||||
if (no_terminal)
|
||||
return;
|
||||
|
||||
/* we can handle plain ascii simpler, so check for it first */
|
||||
for(i=0; i < n; i++ ) {
|
||||
if( p[i] & 0x80 )
|
||||
break;
|
||||
}
|
||||
if( i < n ) {
|
||||
buf = utf8_to_native( p, n, 0 );
|
||||
if( max_n && (strlen( buf ) > max_n )) {
|
||||
buf[max_n] = 0;
|
||||
}
|
||||
/*(utf8 conversion already does the control character quoting)*/
|
||||
tty_printf("%s", buf );
|
||||
xfree( buf );
|
||||
}
|
||||
else {
|
||||
if( max_n && (n > max_n) ) {
|
||||
n = max_n;
|
||||
}
|
||||
tty_print_string( p, n );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tty_print_utf8_string( byte *p, size_t n )
|
||||
{
|
||||
tty_print_utf8_string2( p, n, 0 );
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
do_get( const char *prompt, int hidden )
|
||||
{
|
||||
char *buf;
|
||||
#ifndef __riscos__
|
||||
byte cbuf[1];
|
||||
#endif
|
||||
int c, n, i;
|
||||
|
||||
if( batchmode ) {
|
||||
log_error("Sorry, we are in batchmode - can't get input\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (no_terminal) {
|
||||
log_error("Sorry, no terminal at all requested - can't get input\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if( !initialized )
|
||||
init_ttyfp();
|
||||
|
||||
last_prompt_len = 0;
|
||||
tty_printf( "%s", prompt );
|
||||
buf = xmalloc((n=50));
|
||||
i = 0;
|
||||
|
||||
#ifdef __MINGW32__ /* windoze version */
|
||||
if( hidden )
|
||||
SetConsoleMode(con.in, HID_INPMODE );
|
||||
|
||||
for(;;) {
|
||||
DWORD nread;
|
||||
|
||||
if( !ReadConsoleA( con.in, cbuf, 1, &nread, NULL ) )
|
||||
log_fatal("ReadConsole failed: rc=%d", (int)GetLastError() );
|
||||
if( !nread )
|
||||
continue;
|
||||
if( *cbuf == '\n' )
|
||||
break;
|
||||
|
||||
if( !hidden )
|
||||
last_prompt_len++;
|
||||
c = *cbuf;
|
||||
if( c == '\t' )
|
||||
c = ' ';
|
||||
else if( c > 0xa0 )
|
||||
; /* we don't allow 0xa0, as this is a protected blank which may
|
||||
* confuse the user */
|
||||
else if( iscntrl(c) )
|
||||
continue;
|
||||
if( !(i < n-1) ) {
|
||||
n += 50;
|
||||
buf = xrealloc (buf, n);
|
||||
}
|
||||
buf[i++] = c;
|
||||
}
|
||||
|
||||
if( hidden )
|
||||
SetConsoleMode(con.in, DEF_INPMODE );
|
||||
|
||||
#elif defined(__riscos__)
|
||||
do {
|
||||
c = riscos_getchar();
|
||||
if (c == 0xa || c == 0xd) { /* Return || Enter */
|
||||
c = (int) '\n';
|
||||
} else if (c == 0x8 || c == 0x7f) { /* Backspace || Delete */
|
||||
if (i>0) {
|
||||
i--;
|
||||
if (!hidden) {
|
||||
last_prompt_len--;
|
||||
fputc(8, ttyfp);
|
||||
fputc(32, ttyfp);
|
||||
fputc(8, ttyfp);
|
||||
fflush(ttyfp);
|
||||
}
|
||||
} else {
|
||||
fputc(7, ttyfp);
|
||||
fflush(ttyfp);
|
||||
}
|
||||
continue;
|
||||
} else if (c == (int) '\t') { /* Tab */
|
||||
c = ' ';
|
||||
} else if (c > 0xa0) {
|
||||
; /* we don't allow 0xa0, as this is a protected blank which may
|
||||
* confuse the user */
|
||||
} else if (iscntrl(c)) {
|
||||
continue;
|
||||
}
|
||||
if(!(i < n-1)) {
|
||||
n += 50;
|
||||
buf = xrealloc (buf, n);
|
||||
}
|
||||
buf[i++] = c;
|
||||
if (!hidden) {
|
||||
last_prompt_len++;
|
||||
fputc(c, ttyfp);
|
||||
fflush(ttyfp);
|
||||
}
|
||||
} while (c != '\n');
|
||||
i = (i>0) ? i-1 : 0;
|
||||
#else /* unix version */
|
||||
if( hidden ) {
|
||||
#ifdef HAVE_TCGETATTR
|
||||
struct termios term;
|
||||
|
||||
if( tcgetattr(fileno(ttyfp), &termsave) )
|
||||
log_fatal("tcgetattr() failed: %s\n", strerror(errno) );
|
||||
restore_termios = 1;
|
||||
term = termsave;
|
||||
term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
if( tcsetattr( fileno(ttyfp), TCSAFLUSH, &term ) )
|
||||
log_fatal("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* fixme: How can we avoid that the \n is echoed w/o disabling
|
||||
* canonical mode - w/o this kill_prompt can't work */
|
||||
while( read(fileno(ttyfp), cbuf, 1) == 1 && *cbuf != '\n' ) {
|
||||
if( !hidden )
|
||||
last_prompt_len++;
|
||||
c = *cbuf;
|
||||
if( c == CONTROL_D )
|
||||
log_info("control d found\n");
|
||||
if( c == '\t' )
|
||||
c = ' ';
|
||||
else if( c > 0xa0 )
|
||||
; /* we don't allow 0xa0, as this is a protected blank which may
|
||||
* confuse the user */
|
||||
else if( iscntrl(c) )
|
||||
continue;
|
||||
if( !(i < n-1) ) {
|
||||
n += 50;
|
||||
buf = xrealloc (buf, n );
|
||||
}
|
||||
buf[i++] = c;
|
||||
}
|
||||
if( *cbuf != '\n' ) {
|
||||
buf[0] = CONTROL_D;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
|
||||
if( hidden ) {
|
||||
#ifdef HAVE_TCGETATTR
|
||||
if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
|
||||
log_error("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
restore_termios = 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* end unix version */
|
||||
buf[i] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
tty_get( const char *prompt )
|
||||
{
|
||||
return do_get( prompt, 0 );
|
||||
}
|
||||
|
||||
char *
|
||||
tty_get_hidden( const char *prompt )
|
||||
{
|
||||
return do_get( prompt, 1 );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tty_kill_prompt()
|
||||
{
|
||||
if ( no_terminal )
|
||||
return;
|
||||
|
||||
if( !initialized )
|
||||
init_ttyfp();
|
||||
|
||||
if( batchmode )
|
||||
last_prompt_len = 0;
|
||||
if( !last_prompt_len )
|
||||
return;
|
||||
#ifdef __MINGW32__
|
||||
tty_printf("\r%*s\r", last_prompt_len, "");
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
putc('\r', ttyfp);
|
||||
for(i=0; i < last_prompt_len; i ++ )
|
||||
putc(' ', ttyfp);
|
||||
putc('\r', ttyfp);
|
||||
fflush(ttyfp);
|
||||
}
|
||||
#endif
|
||||
last_prompt_len = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
tty_get_answer_is_yes( const char *prompt )
|
||||
{
|
||||
int yes;
|
||||
char *p = tty_get( prompt );
|
||||
tty_kill_prompt();
|
||||
yes = answer_is_yes(p);
|
||||
xfree(p);
|
||||
return yes;
|
||||
}
|
40
common/ttyio.h
Normal file
40
common/ttyio.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* ttyio.h
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifndef GNUPG_COMMON_TTYIO_H
|
||||
#define GNUPG_COMMON_TTYIO_H
|
||||
|
||||
const char *tty_get_ttyname (void);
|
||||
int tty_batchmode (int onoff);
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
|
||||
void tty_printf (const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
|
||||
#else
|
||||
void tty_printf (const char *fmt, ... );
|
||||
#endif
|
||||
void tty_print_string (unsigned char *p, size_t n);
|
||||
void tty_print_utf8_string (unsigned char *p, size_t n);
|
||||
void tty_print_utf8_string2 (unsigned char *p, size_t n, size_t max_n);
|
||||
char *tty_get (const char *prompt);
|
||||
char *tty_get_hidden (const char *prompt);
|
||||
void tty_kill_prompt (void);
|
||||
int tty_get_answer_is_yes (const char *prompt);
|
||||
int tty_no_terminal (int onoff);
|
||||
|
||||
|
||||
#endif /*GNUPG_COMMON_TTYIO_H*/
|
120
common/util.h
Normal file
120
common/util.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* util.h - Utility functions for Gnupg
|
||||
* Copyright (C) 2001, 2002, 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef GNUPG_COMMON_UTIL_H
|
||||
#define GNUPG_COMMON_UTIL_H
|
||||
|
||||
#include <gcrypt.h> /* We need this for the memory function protos. */
|
||||
#include <time.h> /* We need time_t. */
|
||||
#include <gpg-error.h> /* we need gpg-error_t. */
|
||||
|
||||
/* to pass hash functions to libksba we need to cast it */
|
||||
#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
|
||||
|
||||
/* get all the stuff from jnlib */
|
||||
#include "../jnlib/logging.h"
|
||||
#include "../jnlib/argparse.h"
|
||||
#include "../jnlib/stringhelp.h"
|
||||
#include "../jnlib/mischelp.h"
|
||||
#include "../jnlib/strlist.h"
|
||||
#include "../jnlib/dotlock.h"
|
||||
#include "../jnlib/utf8conv.h"
|
||||
|
||||
/* handy malloc macros - use only them */
|
||||
#define xtrymalloc(a) gcry_malloc ((a))
|
||||
#define xtrycalloc(a,b) gcry_calloc ((a),(b))
|
||||
#define xtryrealloc(a,b) gcry_realloc ((a),(b))
|
||||
#define xtrystrdup(a) gcry_strdup ((a))
|
||||
#define xfree(a) gcry_free ((a))
|
||||
|
||||
#define xmalloc(a) gcry_xmalloc ((a))
|
||||
#define xmalloc_secure(a) gcry_xmalloc_secure ((a))
|
||||
#define xcalloc(a,b) gcry_xcalloc ((a),(b))
|
||||
#define xcalloc_secure(a,b) gcry_xcalloc_secure ((a),(b))
|
||||
#define xrealloc(a,b) gcry_xrealloc ((a),(b))
|
||||
#define xstrdup(a) gcry_xstrdup ((a))
|
||||
|
||||
/*-- maperror.c --*/
|
||||
int map_ksba_err (int err);
|
||||
int map_gcry_err (int err);
|
||||
int map_kbx_err (int err);
|
||||
gpg_error_t map_assuan_err (int err);
|
||||
int map_to_assuan_status (int rc);
|
||||
|
||||
/*-- gettime.c --*/
|
||||
time_t gnupg_get_time (void);
|
||||
void gnupg_set_time (time_t newtime, int freeze);
|
||||
int gnupg_faked_time_p (void);
|
||||
u32 make_timestamp (void);
|
||||
u32 scan_isodatestr (const char *string);
|
||||
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
||||
const char *strtimevalue (u32 stamp);
|
||||
const char *strtimestamp (u32 stamp); /* GMT */
|
||||
const char *asctimestamp (u32 stamp); /* localized */
|
||||
|
||||
/*-- signal.c --*/
|
||||
void gnupg_init_signals (int mode, void (*fast_cleanup)(void));
|
||||
void gnupg_pause_on_sigusr (int which);
|
||||
void gnupg_block_all_signals (void);
|
||||
void gnupg_unblock_all_signals (void);
|
||||
|
||||
/*-- yesno.c --*/
|
||||
int answer_is_yes (const char *s);
|
||||
int answer_is_yes_no_default (const char *s, int def_answer);
|
||||
int answer_is_yes_no_quit (const char *s);
|
||||
|
||||
|
||||
/*-- miscellaneous.c --*/
|
||||
const char *print_fname_stdout (const char *s);
|
||||
const char *print_fname_stdin (const char *s);
|
||||
void print_string (FILE *fp, const byte *p, size_t n, int delim);
|
||||
void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim);
|
||||
void print_utf8_string (FILE *fp, const byte *p, size_t n);
|
||||
char *make_printable_string (const byte *p, size_t n, int delim);
|
||||
|
||||
int is_file_compressed (const char *s, int *ret_rc);
|
||||
|
||||
|
||||
/*-- replacement functions from funcname.c --*/
|
||||
#if !HAVE_VASPRINTF
|
||||
#include <stdarg.h>
|
||||
int vasprintf (char **result, const char *format, va_list *args);
|
||||
int asprintf (char **result, const char *format, ...);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*-- some macros to replace ctype ones and avoid locale problems --*/
|
||||
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
|
||||
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
|
||||
#define hexdigitp(a) (digitp (a) \
|
||||
|| (*(a) >= 'A' && *(a) <= 'F') \
|
||||
|| (*(a) >= 'a' && *(a) <= 'f'))
|
||||
/* the atoi macros assume that the buffer has only valid digits */
|
||||
#define atoi_1(p) (*(p) - '0' )
|
||||
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
|
||||
#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
|
||||
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
||||
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||
|
||||
|
||||
|
||||
#endif /*GNUPG_COMMON_UTIL_H*/
|
96
common/yesno.c
Normal file
96
common/yesno.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* yesno.c - Yes/No questions
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "util.h"
|
||||
|
||||
int
|
||||
answer_is_yes_no_default( const char *s, int def_answer )
|
||||
{
|
||||
const char *long_yes = _("yes");
|
||||
const char *short_yes = _("yY");
|
||||
const char *long_no = _("no");
|
||||
const char *short_no = _("nN");
|
||||
|
||||
/* Note: we have to use the local dependent strcasecmp here */
|
||||
if( !strcasecmp(s, long_yes ) )
|
||||
return 1;
|
||||
if( *s && strchr( short_yes, *s ) && !s[1] )
|
||||
return 1;
|
||||
/* test for no strings to catch ambiguities for the next test */
|
||||
if( !strcasecmp(s, long_no ) )
|
||||
return 0;
|
||||
if( *s && strchr( short_no, *s ) && !s[1] )
|
||||
return 0;
|
||||
/* test for the english version (for those who are used to type yes) */
|
||||
if( !ascii_strcasecmp(s, "yes" ) )
|
||||
return 1;
|
||||
if( *s && strchr( "yY", *s ) && !s[1] )
|
||||
return 1;
|
||||
return def_answer;
|
||||
}
|
||||
|
||||
int
|
||||
answer_is_yes( const char *s )
|
||||
{
|
||||
return answer_is_yes_no_default(s,0);
|
||||
}
|
||||
|
||||
/****************
|
||||
* Return 1 for yes, -1 for quit, or 0 for no
|
||||
*/
|
||||
int
|
||||
answer_is_yes_no_quit( const char *s )
|
||||
{
|
||||
const char *long_yes = _("yes");
|
||||
const char *long_no = _("no");
|
||||
const char *long_quit = _("quit");
|
||||
const char *short_yes = _("yY");
|
||||
const char *short_no = _("nN");
|
||||
const char *short_quit = _("qQ");
|
||||
|
||||
/* Note: We have to use the locale dependent strcasecmp */
|
||||
if( !strcasecmp(s, long_no ) )
|
||||
return 0;
|
||||
if( !strcasecmp(s, long_yes ) )
|
||||
return 1;
|
||||
if( !strcasecmp(s, long_quit ) )
|
||||
return -1;
|
||||
if( *s && strchr( short_no, *s ) && !s[1] )
|
||||
return 0;
|
||||
if( *s && strchr( short_yes, *s ) && !s[1] )
|
||||
return 1;
|
||||
if( *s && strchr( short_quit, *s ) && !s[1] )
|
||||
return -1;
|
||||
/* but not here */
|
||||
if( !ascii_strcasecmp(s, "yes" ) )
|
||||
return 1;
|
||||
if( !ascii_strcasecmp(s, "quit" ) )
|
||||
return -1;
|
||||
if( *s && strchr( "yY", *s ) && !s[1] )
|
||||
return 1;
|
||||
if( *s && strchr( "qQ", *s ) && !s[1] )
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue