From b113394658bbaa292ca8f6e9c1c4382e2f4235cd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 26 Jan 1998 22:09:01 +0000 Subject: [PATCH] added initial i18n stuff --- Makefile.am | 2 +- Makefile.in | 8 +- README | 53 ++++++++ TODO | 10 +- acconfig.h | 16 +++ config.h.in | 94 ++++++++++++++ configure.in | 300 ++++++++++++++++++++++++++++++++++++++++++-- g10/Makefile.am | 4 +- g10/Makefile.in | 10 +- g10/OPTIONS | 6 + g10/export.c | 47 +++++++ g10/g10.c | 167 +++++++++++++++---------- g10/getkey.c | 102 ++++++++++++--- g10/main.h | 2 + g10/options.h | 2 +- g10/pkclist.c | 21 ++-- include/distfiles | 2 + include/errors.h | 1 + include/i18n.h | 37 ++++++ include/util.h | 1 + po/Makefile.in.in | 209 +++++++++++++++++++++++++++++++ po/POTFILES.in | 14 +++ po/de.po | 308 ++++++++++++++++++++++++++++++++++++++++++++++ util/argparse.c | 3 +- util/errors.c | 1 + util/strgutil.c | 25 ++++ 26 files changed, 1318 insertions(+), 127 deletions(-) create mode 100644 g10/export.c create mode 100644 include/i18n.h create mode 100644 po/Makefile.in.in create mode 100644 po/POTFILES.in create mode 100644 po/de.po diff --git a/Makefile.am b/Makefile.am index dea36e96a..a2a1d87cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = util mpi cipher tools g10 +SUBDIRS = util mpi cipher tools po intl g10 EXTRA_DIST = VERSION diff --git a/Makefile.in b/Makefile.in index ff5231486..41e1626ef 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,15 +38,15 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ -SUBDIRS = util mpi cipher tools g10 +SUBDIRS = util mpi cipher tools po intl g10 EXTRA_DIST = VERSION ACCONFIG = acconfig.h CONFIG_HEADER_IN = config.h.in mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = ./config.h -DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ -Makefile.in NEWS README TODO acconfig.h config.h.in configure \ -configure.in stamp-h.in +DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL \ +Makefile.am Makefile.in NEWS README TODO acconfig.h config.h.in \ +configure configure.in stamp-h.in PACKAGE = @PACKAGE@ diff --git a/README b/README index 4aa3f6e1a..91d3ac983 100644 --- a/README +++ b/README @@ -160,6 +160,59 @@ Ditto, but sign the file with the user id "Suttner" + How to Specify a UserID + ----------------------- + There are several ways to specify a userID, here are some examples: + + * Only by the short keyid (prepend a zero if it start with A..F): + + "234567C4" + "0F34E556E" + "01347A56A" + + * By a complete keyid: + + "234AABBCC34567C4" + "0F323456784E56EAB" + "01AB3FED1347A5612" + + * By a fingerprint (not yet implemented): + + "1234343434343434C434343434343434" + "123434343434343C3434343434343734349A3434" + "0E12343434343434343434EAB3484343434343434" + + The first one is MD5 the others are ripemd160 or sha1. + + * By an exact string (not yet implemented): + + "=Heinrich Heine " + + * By an email address: + + "" + + This can be used by a keyserver instead of a substring to + find this key faster. + + * By the Local ID (from the trustdb): + + "#34" + + This can be used by a MUA to specify an exact key after selecting + a key from G10 (by the use of a special option or an extra utility) + + + * Or by the usual substring: + + "Heine" + "*Heine" + + The '*' indicates substring search explicitly. + + + + Batch mode ---------- If you use the option "--batch", G10 runs in non-interactive mode and diff --git a/TODO b/TODO index 65079b605..283e72cc9 100644 --- a/TODO +++ b/TODO @@ -25,21 +25,13 @@ * complete cipher/cast.c * complete cipher/dsa.c - * define a standard way to specify keyid/userid and other stuff - to identify a user. We could look at the first character and - say: If it's a digit, a keyid follows (need to add a zero in - case the keyid starts with A..F); if it is a left angle bracket, - this is a email address and should be used, all others are substrings - of the userid. - [can be handles in get_pubkey_by_name()] - * armor has now some problems. * add g10 stuff to Mutt's pgpinvoke.c * Burn the buffers used by fopen(). - * bug: g10/trustdb.c#build_sigrecs caled to often by do_list_path + * bug: g10/trustdb.c#build_sigrecs called to often by do_list_path and remove the bad kludge. Maybe we should put all sigs into the trustdb and mark them as valid/invalid/nopubkey, and how do we check, that we have a self-signature -> put this stuff into a kind of directory diff --git a/acconfig.h b/acconfig.h index 3f83ef1b3..728d4d1eb 100644 --- a/acconfig.h +++ b/acconfig.h @@ -26,6 +26,22 @@ #undef M_DEBUG #undef VERSION #undef PACKAGE +#undef G10_LOCALEDIR + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +#undef HAVE_STPCPY + #undef BIG_ENDIAN_HOST #undef LITTLE_ENDIAN_HOST diff --git a/config.h.in b/config.h.in index 94550ccf5..fb816095b 100644 --- a/config.h.in +++ b/config.h.in @@ -23,27 +23,70 @@ +/* Define if using alloca.c. */ +#undef C_ALLOCA + /* Define to empty if the keyword does not work. */ #undef const +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF /* Define as __inline if that's what the C compiler calls it. */ #undef inline +/* Define to `long' if doesn't define. */ +#undef off_t + /* Define to `unsigned' if doesn't define. */ #undef size_t +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS #undef M_DEBUG #undef VERSION #undef PACKAGE +#undef G10_LOCALEDIR + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +#undef HAVE_STPCPY #undef BIG_ENDIAN_HOST #undef LITTLE_ENDIAN_HOST @@ -72,12 +115,39 @@ /* The number of bytes in a unsigned short. */ #undef SIZEOF_UNSIGNED_SHORT +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + /* Define if you have the rand function. */ #undef HAVE_RAND +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + /* Define if you have the stpcpy function. */ #undef HAVE_STPCPY +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strchr function. */ +#undef HAVE_STRCHR + /* Define if you have the strerror function. */ #undef HAVE_STRERROR @@ -90,12 +160,36 @@ /* Define if you have the tcgetattr function. */ #undef HAVE_TCGETATTR +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + /* Define if you have the header file. */ #undef HAVE_UNISTD_H +/* Define if you have the header file. */ +#undef HAVE_VALUES_H + /* Define if you have the header file. */ #undef HAVE_ZLIB_H +/* Define if you have the i library (-li). */ +#undef HAVE_LIBI + +/* Define if you have the intl library (-lintl). */ +#undef HAVE_LIBINTL + /* The AC_CHECK_SIZEOF() fails for some machines. * we provide some fallback values here */ diff --git a/configure.in b/configure.in index 39e87761b..b9b8ccdc0 100644 --- a/configure.in +++ b/configure.in @@ -8,12 +8,27 @@ AC_CONFIG_AUX_DIR(scripts) AC_CONFIG_HEADER(config.h) +if test "x$exec_prefix" = xNONE ; then + if test "x$prefix" = xNONE ; then + g10_prefix="$ac_default_prefix" + else + g10_prefix="$prefix" + fi +else + g10_prefix="$exec_prefix" +fi + + VERSION=`cat $srcdir/VERSION` PACKAGE=g10 +ALL_LINGUAS="de" +G10_LOCALEDIR="$g10_prefix/share/locale" AC_SUBST(VERSION) AC_SUBST(PACKAGE) +AC_SUBST(G10_LOCALEDIR) AC_DEFINE_UNQUOTED(VERSION, "$VERSION") AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") +AC_DEFINE_UNQUOTED(G10_LOCALEDIR, "$G10_LOCALEDIR") AC_ARG_ENABLE(m-debug, [ --enable-m-debug Enable debugging of memory allocation]) @@ -22,6 +37,250 @@ if test "$enableval" = y || test "$enableval" = yes; then fi CFLAGS="-g -Wall" +g10_ln_sources= +g10_ln_dests= + + + +dnl BEGIN=========================== +dnl FIXME: move this to aclocal.m4 +AC_PREREQ(2.5) + +AC_DEFUN(md_TYPE_PTRDIFF_T, + [AC_CACHE_CHECK([for ptrdiff_t], ac_cv_type_ptrdiff_t, + [AC_TRY_COMPILE(stddef.h, [ptrdiff_t p], ac_cv_type_ptrdiff_t=yes, + ac_cv_type_ptrdiff_t=no)]) + if test $ac_cv_type_ptrdiff_t = yes; then + AC_DEFINE(HAVE_PTRDIFF_T) + fi +]) + +AC_DEFUN(md_PATH_PROG, + [AC_PATH_PROG($1,$2,$3)dnl + if echo $$1 | grep openwin > /dev/null; then + echo "WARNING: Do not use OpenWin's $2. (Better remove it.) >&AC_FD_MSG" + ac_cv_path_$1=$2 + $1=$2 + fi +]) + + +dnl --------------------------------------------------------- ## +dnl Use AC_PROG_INSTALL, supplementing it with INSTALL_SCRIPT ## +dnl substitution. ## +dnl --------------------------------------------------------- ## + +AC_DEFUN(fp_PROG_INSTALL, +[AC_PROG_INSTALL +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL} -m 755' +AC_SUBST(INSTALL_SCRIPT)dnl +]) + +dnl Check NLS options + +AC_DEFUN(ud_LC_MESSAGES, + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], ud_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + ud_cv_val_LC_MESSAGES=yes, ud_cv_val_LC_MESSAGES=no)]) + if test $ud_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES) + fi + fi]) + +AC_DEFUN(ud_WITH_NLS, + [AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + nls_cv_use_nls=$enableval, nls_cv_use_nls=yes) + AC_MSG_RESULT($nls_cv_use_nls) + + dnl If we use NLS figure out what method + if test "$nls_cv_use_nls" = "yes"; then + AC_DEFINE(ENABLE_NLS) + AC_MSG_CHECKING([for explicitly using GNU gettext]) + AC_ARG_WITH(gnu-gettext, + [ --with-gnu-gettext use the GNU gettext library], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + if test "$nls_cv_force_use_gnu_gettext" = "yes"; then + nls_cv_use_gnu_gettext=yes + else + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + AC_CHECK_LIB(intl, main) + AC_CHECK_LIB(i, main) + CATOBJEXT=NONE + AC_CHECK_FUNC(gettext, + [AC_DEFINE(HAVE_GETTEXT) + md_PATH_PROG(MSGFMT, msgfmt, no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + md_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + md_PATH_PROG(XGETTEXT, xgettext, xgettext) + CATOBJEXT=.mo + INSTOBJEXT=.mo + DATADIRNAME=lib + fi]) + + if test "$CATOBJEXT" = "NONE"; then + dnl No gettext in C library. Try catgets next. + AC_CHECK_FUNC(catgets, + [AC_DEFINE(HAVE_CATGETS) + INTLOBJS="\$(CATOBJS)" + AC_PATH_PROG(GENCAT, gencat, no)dnl + if test "$GENCAT" != "no"; then + AC_PATH_PROGS(GMSGFMT, [gmsgfmt msgfmt], msgfmt) + md_PATH_PROG(XGETTEXT, xgettext, xgettext) + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS="../intl/libintl.a" + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi]) + fi + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + md_PATH_PROG(MSGFMT, msgfmt, msgfmt) + md_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + md_PATH_PROG(XGETTEXT, xgettext, xgettext) + AC_SUBST(MSGFMT) + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS="../intl/libintl.a" + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + # We need to process the intl/ and po/ directory. + INTLSUB=intl + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(INTLSUB) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(ud_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([limits.h locale.h nl_types.h malloc.h string.h unistd.h values.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY) + fi + + ud_LC_MESSAGES + ud_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux and the normal X/Open format + test -d intl || mkdir intl + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +dnl END======================== + dnl some additional macros dnl WK_MSG_PRINT(STRING) @@ -44,8 +303,6 @@ fi ]) - - dnl AC_CANONICAL_SYSTEM AC_MSG_CHECKING(cached information) @@ -91,13 +348,14 @@ dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(unistd.h) +ud_GNU_GETTEXT + dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T - dnl autoconf doesn't support a default value for AC_C_BIGENDIAN dnl so here is the modified version if test "$cross_compiling" = yes; then @@ -181,8 +439,14 @@ else ac_cv_mpi_config_done="" if test -f $srcdir/mpi/config.links ; then . $srcdir/mpi/config.links + if test "x$g10_ln_sources" = "x"; then + g10_ln_sources="$mpi_ln_src" + g10_ln_dests="$mpi_ln_dst" + else + g10_ln_sources="$g10_ln_sources $mpi_ln_src" + g10_ln_dests="$g10_ln_dests $mpi_ln_dst" + fi ac_cv_mpi_extra_asm_modules="$mpi_extra_modules" - AC_LINK_FILES( ${mpi_ln_src}, ${mpi_ln_dst} ) ac_cv_mpi_config_done="yes" AC_MSG_RESULT(done) else @@ -223,11 +487,25 @@ fi AC_SUBST(CIPHER_EXTRA_OBJS) AC_SUBST(CIPHER_EXTRA_DIST) -AC_OUTPUT([ Makefile \ - util/Makefile \ - mpi/Makefile \ - cipher/Makefile \ - g10/Makefile \ - tools/Makefile \ -], [echo timestamp > stamp-h ] ) +if test "x$g10_ln_sources" = "x"; then + g10_ln_sources="$nls_cv_header_libgt" + g10_ln_dests="$nls_cv_header_intl" +else + g10_ln_sources="$g10_ln_sources $nls_cv_header_libgt" + g10_ln_dests="$g10_ln_dests $nls_cv_header_intl" +fi + +AC_LINK_FILES($g10_ln_sources,$g10_ln_dests) + + +AC_OUTPUT([ +Makefile +intl/Makefile +po/Makefile.in +util/Makefile +mpi/Makefile +cipher/Makefile +g10/Makefile +tools/Makefile +],[echo timestamp >stamp-h; sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile]) diff --git a/g10/Makefile.am b/g10/Makefile.am index 5c22b4b7e..ec432e049 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -41,11 +41,13 @@ g10_SOURCES = g10.c \ seskey.c \ sign.c \ import.c \ + export.c \ comment.c \ sig-check.c -LDADD = -L ../cipher -L ../mpi -L ../util -lcipher -lmpi -lutil +LDADD = -L ../cipher -L ../mpi -L ../util -L ../intl \ + -lcipher -lmpi -lutil -lintl $(PROGRAMS): ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a diff --git a/g10/Makefile.in b/g10/Makefile.in index 1212499da..ec99a5bc2 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -79,10 +79,12 @@ g10_SOURCES = g10.c \ seskey.c \ sign.c \ import.c \ + export.c \ comment.c \ sig-check.c -LDADD = -L ../cipher -L ../mpi -L ../util -lcipher -lmpi -lutil +LDADD = -L ../cipher -L ../mpi -L ../util -L ../intl \ + -lcipher -lmpi -lutil -lintl mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = ../config.h PROGRAMS = $(bin_PROGRAMS) @@ -104,7 +106,7 @@ g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \ free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o keygen.o \ mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o rsa.o \ openfile.o keyid.o trustdb.o parse-packet.o passphrase.o plaintext.o \ -pubkey-enc.o seckey-cert.o seskey.o sign.o import.o comment.o \ +pubkey-enc.o seckey-cert.o seskey.o sign.o import.o export.o comment.o \ sig-check.o EXTRA_g10_SOURCES = g10_LDADD = $(LDADD) @@ -124,8 +126,8 @@ DEP_FILES = $(srcdir)/.deps/armor.P $(srcdir)/.deps/build-packet.P \ $(srcdir)/.deps/cipher.P $(srcdir)/.deps/comment.P \ $(srcdir)/.deps/compress.P $(srcdir)/.deps/elg.P \ $(srcdir)/.deps/encode.P $(srcdir)/.deps/encr-data.P \ -$(srcdir)/.deps/free-packet.P $(srcdir)/.deps/g10.P \ -$(srcdir)/.deps/getkey.P $(srcdir)/.deps/import.P \ +$(srcdir)/.deps/export.P $(srcdir)/.deps/free-packet.P \ +$(srcdir)/.deps/g10.P $(srcdir)/.deps/getkey.P $(srcdir)/.deps/import.P \ $(srcdir)/.deps/kbnode.P $(srcdir)/.deps/keygen.P \ $(srcdir)/.deps/keyid.P $(srcdir)/.deps/mainproc.P \ $(srcdir)/.deps/mdfilter.P $(srcdir)/.deps/openfile.P \ diff --git a/g10/OPTIONS b/g10/OPTIONS index 684abd2d9..ed91fcf50 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -42,6 +42,12 @@ encrypt # (Can be combined with a "sign") # encrypt data +export +# Either export all keys from all keyrings (default keyrings and +# those registered via option "keyring"), or if at least one name is +# given, those of the givename. The new keyring is written to stdout +# or to the file given with option "output" + fingerprint # show the fingerprints, diff --git a/g10/export.c b/g10/export.c new file mode 100644 index 000000000..d45c1285f --- /dev/null +++ b/g10/export.c @@ -0,0 +1,47 @@ +/* export.c + * Copyright (c) 1998 by Werner Koch (dd9jn) + * + * This file is part of G10. + * + * G10 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. + * + * G10 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 +#include +#include +#include +#include +#include + +#include "options.h" +#include "packet.h" +#include "errors.h" +#include "keydb.h" +#include "memory.h" +#include "util.h" + + +/**************** + * Make a new keyring from all internal keyrings (if no user is given) + * or for all selected users. + */ +int +export_pubkeys( STRLIST users ) +{ + log_fatal("Not yet implemented"); + return 0; +} + + diff --git a/g10/g10.c b/g10/g10.c index b9ce92564..73cb147b0 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -37,12 +37,14 @@ #include "filter.h" #include "trustdb.h" #include "ttyio.h" +#include "i18n.h" + enum cmd_values { aNull = 0, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr, aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig, aKMode, aKModeC, aChangePass, aImport, aListTrustDB, - aListTrustPath, + aListTrustPath, aExport, aTest }; @@ -67,34 +69,51 @@ strusage( int level ) break; case 2: case 12: p = - "Syntax: g10 [options] [files]\n" - "sign, check, encrypt or decrypt\n" - "default operation depends on the input data\n"; break; + _("Syntax: g10 [options] [files]\n" + "sign, check, encrypt or decrypt\n" + "default operation depends on the input data\n"); break; case 26: - p = "Please report bugs to .\n"; + p = _("Please report bugs to .\n"); break; - case 30: p = "" - #ifndef HAVE_ZLIB_H + #if !defined(HAVE_ZLIB_H) && defined(HAVE_RSA_CIPHER) + case 30: p = _( " NOTE: This version is compiled without ZLIB support;\n" " you are not able to process compresssed data!\n" - #endif - #ifdef HAVE_RSA_CIPHER "WARNING: This version has RSA support! Your are not allowed to\n" - " use it inside the Unites States before Sep 30, 2000!\n" + " use it inside the Unites States before Sep 30, 2000!\n" ); + #elif !defined(HAVE_ZLIB_H) + case 30: p = _( + " NOTE: This version is compiled without ZLIB support;\n" + " you are not able to process compresssed data!\n"); + #elif defined(HAVE_RSA_CIPHER) + case 30: p = _( + "WARNING: This version has RSA support! Your are not allowed to\n" + " use it inside the Unites States before Sep 30, 2000!\n" ); + #else + case 30: p = ""; #endif - ; break; default: p = default_strusage(level); } return p; } +static void +i18n_init(void) +{ + #ifdef HAVE_LIBINTL + setlocale( LC_MESSAGES, "" ); + bindtextdomain( PACKAGE, G10_LOCALEDIR ); + textdomain( PACKAGE ); + #endif +} + static void wrong_args( const char *text) { - fputs("Usage: g10 [options] ",stderr); + fputs(_("Usage: g10 [options] "),stderr); fputs(text,stderr); putc('\n',stderr); exit(2); @@ -130,7 +149,7 @@ set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ) else if( cmd == aKMode && new_cmd == aSym ) cmd = aKModeC; else { - log_error("conflicting commands\n"); + log_error(_("conflicting commands\n")); exit(2); } @@ -142,57 +161,58 @@ int main( int argc, char **argv ) { static ARGPARSE_OPTS opts[] = { - { 'a', "armor", 0, "create ascii armored output"}, - { 'v', "verbose", 0, "verbose" }, - { 'z', NULL, 1, "set compress level (0 disables)" }, - { 'n', "dry-run", 0, "don't make any changes" }, - { 'c', "symmetric", 0, "do only a symmetric encryption" }, - { 'o', "output", 2, "use as output file" }, - { 500, "batch", 0, "batch mode: never ask" }, - { 501, "yes", 0, "assume yes on most questions"}, - { 502, "no", 0, "assume no on most questions"}, - { 503, "gen-key", 0, "generate a new key pair" }, - { 504, "add-key", 0, "add key to the public keyring" }, - { 505, "delete-key",0, "remove key from public keyring" }, - { 506, "sign-key" ,0, "make a signature on a key in the keyring" }, - { 507, "store", 0, "store only" }, - { 508, "check-key" ,0, "check signatures on a key in the keyring" }, - { 509, "keyring" ,2, "add this keyring to the list of keyrings" }, - { 's', "sign", 0, "make a signature"}, - { 't', "textmode", 0, "use canonical text mode"}, - { 'b', "detach-sign", 0, "make a detached signature"}, - { 'e', "encrypt", 0, "encrypt data" }, - { 'd', "decrypt", 0, "decrypt data (default)" }, - { 'u', "local-user",2, "use this user-id to sign or decrypt" }, - { 'r', "remote-user", 2, "use this user-id for encryption" }, - { 'k', NULL , 0, "list keys" }, - { 510, "debug" ,4|16, "set debugging flags" }, - { 511, "debug-all" ,0, "enable full debugging"}, - { 512, "cache-all" ,0, "hold everything in memory"}, + { 'a', "armor", 0, N_("create ascii armored output")}, + { 'v', "verbose", 0, N_("verbose") }, + { 'z', NULL, 1, N_("set compress level (0 disables)") }, + { 'n', "dry-run", 0, N_("don't make any changes") }, + { 'c', "symmetric", 0, N_("do only a symmetric encryption")}, + { 'o', "output", 2, N_("use as output file")}, + { 500, "batch", 0, N_("batch mode: never ask")}, + { 501, "yes", 0, N_("assume yes on most questions")}, + { 502, "no", 0, N_("assume no on most questions")}, + { 503, "gen-key", 0, N_("generate a new key pair")}, + { 504, "add-key", 0, N_("add key to the public keyring")}, + { 505, "delete-key",0, N_("remove key from public keyring")}, + { 506, "sign-key" ,0, N_("make a signature on a key in the keyring")}, + { 507, "store", 0, N_("store only")}, + { 508, "check-key" ,0, N_("check signatures on a key in the keyring")}, + { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, + { 's', "sign", 0, N_("make a signature")}, + { 't', "textmode", 0, N_("use canonical text mode")}, + { 'b', "detach-sign", 0, N_("make a detached signature")}, + { 'e', "encrypt", 0, N_("encrypt data")}, + { 'd', "decrypt", 0, N_("decrypt data (default)")}, + { 'u', "local-user",2, N_("use this user-id to sign or decrypt")}, + { 'r', "remote-user", 2, N_("use this user-id for encryption")}, + { 'k', NULL , 0, N_("list keys")}, + { 510, "debug" ,4|16, N_("set debugging flags")}, + { 511, "debug-all" ,0, N_("enable full debugging")}, + /* { 512 unused */ { 513, "gen-prime" , 0, "\r" }, { 514, "test" , 0, "\r" }, - { 515, "fingerprint", 0, "show the fingerprints"}, - { 516, "print-mds" , 0, "print all message digests"}, - { 517, "secret-keyring" ,2, "add this secret keyring to the list" }, - { 518, "options" , 2, "read options from file" }, + { 515, "fingerprint", 0, N_("show the fingerprints")}, + { 516, "print-mds" , 0, N_("print all message digests")}, + { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")}, + { 518, "options" , 2, N_("read options from file")}, { 519, "no-armor", 0, "\r"}, { 520, "no-default-keyring", 0, "\r" }, - { 521, "list-packets",0,"list only the sequence of packets"}, + { 521, "list-packets",0,N_("list only the sequence of packets")}, { 522, "no-greeting", 0, "\r" }, { 523, "passphrase-fd",1, "\r" }, - { 524, "edit-sig" ,0, "edit a key signature" }, - { 525, "change-passphrase", 0, "change the passphrase of your secret keyring"}, + { 524, "edit-sig" ,0, N_("edit a key signature")}, + { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")}, { 526, "no-verbose", 0, "\r"}, - { 527, "cipher-algo", 2 , "select default cipher algorithm" }, - { 528, "pubkey-algo", 2 , "select default puplic key algorithm" }, - { 529, "digest-algo", 2 , "select default message digest algorithm" }, - { 530, "import", 0 , "put public keys into the trustdb" }, + { 527, "cipher-algo", 2 , N_("select default cipher algorithm")}, + { 528, "pubkey-algo", 2 , N_("select default puplic key algorithm")}, + { 529, "digest-algo", 2 , N_("select default message digest algorithm")}, + { 530, "import", 0 , N_("put public keys into the trustdb")}, { 531, "list-trustdb",0 , "\r"}, { 532, "quick-random", 0, "\r"}, { 533, "list-trust-path",0, "\r"}, - { 534, "no-comment", 0, "do not write comment packets"}, - { 535, "completes_needed", 1, "(default is 1)"}, - { 536, "marginals_needed", 1, "(default is 3)"}, + { 534, "no-comment", 0, N_("do not write comment packets")}, + { 535, "completes-needed", 1, N_("(default is 1)")}, + { 536, "marginals-needed", 1, N_("(default is 3)")}, + { 537, "export", 0, N_("export all or the given keys") }, {0} }; ARGPARSE_ARGS pargs; @@ -217,6 +237,7 @@ main( int argc, char **argv ) enum cmd_values cmd = 0; + i18n_init(); opt.compress = -1; /* defaults to standard compress level */ opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL; @@ -256,15 +277,15 @@ main( int argc, char **argv ) if( !configfp ) { if( default_config ) { if( parse_verbose > 1 ) - log_info("note: no default option file '%s'\n", configname ); + log_info(_("note: no default option file '%s'\n"), configname ); } else - log_fatal("option file '%s': %s\n", + log_fatal(_("option file '%s': %s\n"), configname, strerror(errno) ); m_free(configname); configname = NULL; } if( parse_verbose > 1 ) - log_info("reading options from '%s'\n", configname ); + log_info(_("reading options from '%s'\n"), configname ); default_config = 0; } @@ -306,7 +327,7 @@ main( int argc, char **argv ) case 509: add_keyring(pargs.r.ret_str); nrings++; break; case 510: opt.debug |= pargs.r.ret_ulong; break; case 511: opt.debug = ~0; break; - case 512: opt.cache_all = 1; break; + /* case 512: */ case 513: set_cmd( &cmd, aPrimegen); break; case 514: set_cmd( &cmd, aTest); break; case 515: opt.fingerprint = 1; break; @@ -344,6 +365,7 @@ main( int argc, char **argv ) case 534: opt.no_comment=1; break; case 535: opt.completes_needed = pargs.r.ret_int; break; case 536: opt.marginals_needed = pargs.r.ret_int; break; + case 537: set_cmd( &cmd, aExport); break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -355,23 +377,23 @@ main( int argc, char **argv ) } m_free( configname ); configname = NULL; if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) { - log_error("selected cipher algorithm is invalid\n"); + log_error(_("selected cipher algorithm is invalid\n")); errors++; } if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) { - log_error("selected pubkey algorithm is invalid\n"); + log_error(_("selected pubkey algorithm is invalid\n")); errors++; } if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) ) { - log_error("selected digest algorithm is invalid\n"); + log_error(_("selected digest algorithm is invalid\n")); errors++; } if( opt.completes_needed < 1 ) { - log_error("completes_needed must be greater than 0\n"); + log_error(_("completes-needed must be greater than 0\n")); errors++; } if( opt.marginals_needed < 2 ) { - log_error("marginals_needed must be greater than 1\n"); + log_error(_("marginals-needed must be greater than 1\n")); errors++; } if( errors ) @@ -435,7 +457,7 @@ main( int argc, char **argv ) default: rc = init_trustdb(1); break; } if( rc ) - log_error("failed to initialize the TrustDB: %s\n", g10_errstr(rc)); + log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc)); switch( cmd ) { @@ -527,7 +549,7 @@ main( int argc, char **argv ) while( (s=get_keyring(seq++)) ) { if( !(a = iobuf_open(s)) ) { - log_error("can't open '%s'\n", s); + log_error(_("can't open '%s'\n"), s); continue; } if( seq > 1 ) @@ -544,7 +566,7 @@ main( int argc, char **argv ) } else if( argc == 1) { /* list the given keyring */ if( !(a = iobuf_open(fname)) ) - log_fatal("can't open '%s'\n", fname_print); + log_fatal(_("can't open '%s'\n"), fname_print); proc_packets( a ); iobuf_close(a); } @@ -603,6 +625,15 @@ main( int argc, char **argv ) } break; + case aExport: + sl = NULL; + for( ; argc; argc--, argv++ ) + add_to_strlist( &sl, *argv ); + export_pubkeys( sl ); + free_strlist(sl); + break; + + case aListTrustDB: if( !argc ) list_trustdb(NULL); @@ -614,7 +645,7 @@ main( int argc, char **argv ) case aListTrustPath: if( argc != 2 ) - wrong_args("--list-trust-path "); + wrong_args("--list-trust-path [-- -] "); list_trust_path( atoi(*argv), argv[1] ); break; @@ -624,7 +655,7 @@ main( int argc, char **argv ) if( argc > 1 ) usage(1); if( !(a = iobuf_open(fname)) ) - log_fatal("can't open '%s'\n", fname_print); + log_fatal(_("can't open '%s'\n"), fname_print); if( !opt.no_armor ) { /* push the armor filter, so it can peek at the input data */ memset( &afx, 0, sizeof afx); diff --git a/g10/getkey.c b/g10/getkey.c index b1cb64a29..eea9b6beb 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "util.h" #include "packet.h" #include "memory.h" @@ -215,15 +216,6 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid ) STRLIST sl; - if( opt.cache_all && !pkc_cache ) { - log_info("reading all entries ...\n"); - for(sl = keyrings; sl; sl = sl->next ) - if( !scan_keyring( NULL, NULL, NULL, sl->d ) ) - goto leave; - log_info("cached %d entries\n", pkc_cache_entries); - } - - /* lets see wether we checked the keyid already */ for( kl = unknown_keyids; kl; kl = kl->next ) if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] ) @@ -273,6 +265,19 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid ) * first pubkey certificate which has the given name in a user_id. * if pkc has the pubkey algo set, the function will only return * a pubkey with that algo. + * + * - If the username starts with 8,9,16 or 17 hex-digits (the first one + * must be in the range 0..9), this is considered a keyid; depending + * on the length a short or complete one. + * - If the username starts with 32,33,40 or 41 hex-digits (the first one + * must be in the range 0..9), this is considered a fingerprint. + * (Not yet implemented) + * - If the username starts with a left angle, we assume it is a complete + * email address and look only at this part. + * - If the userid start with an '=' an exact compare is done; this may + * also follow the keyid in which case both parts are matched. + * (Not yet implemented) + * */ int get_pubkey_byname( PKT_public_cert *pkc, const char *name ) @@ -280,6 +285,58 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name ) int internal = 0; int rc = 0; STRLIST sl; + const char *s; + u32 keyid[2] = {0}; /* init to avoid compiler warning */ + int use_keyid=0; + + /* check what kind of name it is */ + for(s = name; *s && isspace(*s); s++ ) + ; + if( isdigit( *s ) ) { /* a keyid */ + int i; + char buf[9]; + + for(i=0; isxdigit(s[i]); i++ ) + ; + if( s[i] && !isspace(s[i]) ) /* not terminated by EOS or blank*/ + rc = G10ERR_INV_USER_ID; + else if( i == 8 || (i == 9 && *s == '0') ) { /* short keyid */ + if( i==9 ) + s++; + keyid[1] = strtoul( s, NULL, 16 ); + use_keyid++; + } + else if( i == 16 || (i == 17 && *s == '0') ) { /* complete keyid */ + if( i==17 ) + s++; + mem2str(buf, s, 9 ); + keyid[0] = strtoul( buf, NULL, 16 ); + keyid[1] = strtoul( s+8, NULL, 16 ); + return get_pubkey( pkc, keyid ); + } + else + rc = G10ERR_INV_USER_ID; + } + else if( *s == '<' ) { /* an email address */ + /* for now handled like a substring */ + /* a keyserver might use this for quicker access */ + } + else if( *s == '=' ) { /* exact search */ + rc = G10ERR_INV_USER_ID; /* nox yet implemented */ + } + else if( *s == '#' ) { /* use local id */ + rc = G10ERR_INV_USER_ID; /* nox yet implemented */ + } + else if( *s == '*' ) { /* substring search */ + name++; + } + else if( !*s ) /* empty string */ + rc = G10ERR_INV_USER_ID; + + if( rc ) + goto leave; + + if( !pkc ) { pkc = m_alloc_clear( sizeof *pkc ); @@ -288,9 +345,14 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name ) /* 2. Try to get it from the keyrings */ for(sl = keyrings; sl; sl = sl->next ) - if( !scan_keyring( pkc, NULL, name, sl->d ) ) - goto leave; - + if( use_keyid ) { + if( !scan_keyring( pkc, keyid, name, sl->d ) ) + goto leave; + } + else { + if( !scan_keyring( pkc, NULL, name, sl->d ) ) + goto leave; + } /* 3. Try to get it from a key server */ /* 4. not found: store it for future reference */ @@ -363,6 +425,9 @@ get_seckey_byname( PKT_secret_cert *skc, const char *name, int unprotect ) /**************** * scan the keyring and look for either the keyid or the name. + * If both, keyid and name are given, look for keyid but use only + * the low word of it (name is only used as a flag to indicate this mode + * of operation). */ static int scan_keyring( PKT_public_cert *pkc, u32 *keyid, @@ -375,11 +440,11 @@ scan_keyring( PKT_public_cert *pkc, u32 *keyid, int save_mode; u32 akeyid[2]; PKT_public_cert *last_pk = NULL; + int shortkeyid; - assert( !keyid || !name ); - - if( opt.cache_all && (name || keyid) ) - return G10ERR_NO_PUBKEY; + shortkeyid = keyid && name; + if( shortkeyid ) + name = NULL; /* not used anymore */ if( !(a = iobuf_open( filename ) ) ) { log_debug("scan_keyring: can't open '%s'\n", filename ); @@ -388,6 +453,8 @@ scan_keyring( PKT_public_cert *pkc, u32 *keyid, if( !DBG_CACHE ) ; + else if( shortkeyid ) + log_debug("scan_keyring %s for %08lx\n", filename, keyid[1] ); else if( name ) log_debug("scan_keyring %s for '%s'\n", filename, name ); else if( keyid ) @@ -410,7 +477,8 @@ scan_keyring( PKT_public_cert *pkc, u32 *keyid, case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_RSA: keyid_from_pkc( pkt.pkt.public_cert, akeyid ); - if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) { + if( (shortkeyid || akeyid[0] == keyid[0]) + && akeyid[1] == keyid[1] ) { copy_public_cert( pkc, pkt.pkt.public_cert ); found++; } diff --git a/g10/main.h b/g10/main.h index 273e7a823..5a76173a1 100644 --- a/g10/main.h +++ b/g10/main.h @@ -79,6 +79,8 @@ void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ); /*-- import.c --*/ int import_pubkeys( const char *filename ); +/*-- export.c --*/ +int export_pubkeys( STRLIST users ); #endif /*G10_MAIN_H*/ diff --git a/g10/options.h b/g10/options.h index ed0cc6579..89388f14e 100644 --- a/g10/options.h +++ b/g10/options.h @@ -31,7 +31,7 @@ struct { int answer_yes; /* answer yes on most questions */ int answer_no; /* answer no on most questions */ int check_sigs; /* check key signatures */ - int cache_all; + int reserved1; int fingerprint; /* list fingerprints */ int list_sigs; /* list signatures */ int no_armor; diff --git a/g10/pkclist.c b/g10/pkclist.c index 5381ac301..411435f60 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -33,6 +33,7 @@ #include "util.h" #include "trustdb.h" #include "ttyio.h" +#include "i18n.h" /**************** * Returns true if a ownertrust has changed. @@ -61,14 +62,14 @@ query_ownertrust( ulong lid ) return 0; } - tty_printf("No ownertrust defined for %lu:\n" - "%4u%c/%08lX %s \"", lid, + tty_printf(_("No ownertrust defined for %lu:\n" + "%4u%c/%08lX %s \""), lid, nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ), (ulong)keyid[1], datestr_from_pkc( pkc ) ); p = get_user_id( keyid, &n ); tty_print_string( p, n ), m_free(p); - tty_printf("\"\n\n" + tty_printf(_("\"\n\n" "Please decide in how far do you trust this user to\n" "correctly sign other users keys (looking at his passport,\n" "checking the fingerprints from different sources ...)?\n\n" @@ -76,19 +77,19 @@ query_ownertrust( ulong lid ) " 2 = I do NOT trust\n" " 3 = I trust marginally\n" " 4 = I trust fully\n" -" s = please show me more informations\n\n" ); +" s = please show me more informations\n\n") ); for(;;) { - p = tty_get("Your decision? "); + p = tty_get(_("Your decision? ")); trim_spaces(p); tty_kill_prompt(); if( *p && p[1] ) ; else if( *p == '?' ) { - tty_printf( + tty_printf(_( "It's up to you to assign a value here; this value will never be exported\n" "to any 3rd party. We need it to implement the web-of-trust; it has nothing\n" -"to do with the (implicitly created) web-of-certificates.\n"); +"to do with the (implicitly created) web-of-certificates.\n")); } else if( !p[1] && (*p >= '1' && *p <= '4') ) { unsigned trust; @@ -104,7 +105,7 @@ query_ownertrust( ulong lid ) break; } else if( *p == 's' || *p == 'S' ) { - tty_printf("You will see a list of signators etc. here\n"); + tty_printf(_("You will see a list of signators etc. here\n")); } m_free(p); p = NULL; } @@ -128,8 +129,8 @@ add_ownertrust( PKT_public_cert *pkc ) int any=0; tty_printf( -"Could not find a valid trust path to the key. Lets see, wether we\n" -"can assign some missing owner trust values.\n\n"); +_("Could not find a valid trust path to the key. Lets see, wether we\n" + "can assign some missing owner trust values.\n\n")); rc = query_trust_record( pkc ); if( rc ) { diff --git a/include/distfiles b/include/distfiles index 342530c4e..d847316f2 100644 --- a/include/distfiles +++ b/include/distfiles @@ -6,3 +6,5 @@ mpi.h ttyio.h types.h util.h +i18n.h + diff --git a/include/errors.h b/include/errors.h index 305a147e8..fcae69ec4 100644 --- a/include/errors.h +++ b/include/errors.h @@ -54,5 +54,6 @@ #define G10ERR_INV_KEYRING 32 #define G10ERR_TRUSTDB 33 /* a problem with the trustdb */ #define G10ERR_BAD_CERT 34 /* bad certicate */ +#define G10ERR_INV_USER_ID 35 #endif /*G10_ERRORS_H*/ diff --git a/include/i18n.h b/include/i18n.h new file mode 100644 index 000000000..a75f3c40f --- /dev/null +++ b/include/i18n.h @@ -0,0 +1,37 @@ +/* i18n.h + * Copyright (c) 1998 by Werner Koch (dd9jn) + * + * This file is part of G10. + * + * G10 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. + * + * G10 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 G10_I18N_H +#define G10_I18N_H + +#ifdef HAVE_LIBINTL + #include + #define _(a) gettext (a) + #ifdef gettext_noop + #define N_(a) gettext_noop (a) + #else + #define N_(a) (a) + #endif +#else + #define _(a) (a) + #define N_(a) (a) +#endif + +#endif /*G10_I18N_H*/ diff --git a/include/util.h b/include/util.h index fe834e1a2..962efa503 100644 --- a/include/util.h +++ b/include/util.h @@ -111,6 +111,7 @@ void free_strlist( STRLIST sl ); #define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0) void add_to_strlist( STRLIST *list, const char *string ); char *memistr( char *buf, size_t buflen, const char *sub ); +char *mem2str( char *, const void *, size_t); char *trim_spaces( char *string ); int string_count_chr( const char *string, int c ); diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 000000000..49a7b1c45 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,209 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995 Free Software Foundation, Inc. +# +# This program 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, or (at your option) +# any later version. +# +# This program 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. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = $(prefix)/share/gettext +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +TUPDATE = tupdate + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = cat-id-tbl.c +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \ +stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(TUPDATE) $(srcdir)/$(PACKAGE).pot $< > $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: cat-id-tbl.c $(CATALOGS) + +$(PACKAGE).pot: $(POTFILES) + $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=$(srcdir)/POTFILES.in + if cmp -s $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; then \ + rm -f $(PACKAGE).po; \ + else \ + rm -f $(srcdir)/$(PACKAGE).pot \ + && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; \ + fi + +cat-id-tbl.c: stamp-cat-id +stamp-cat-id: $(PACKAGE).pot + rm -f cat-id-tbl.tmp.c + sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ + | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp.c + if cmp -s cat-id-tbl.tmp.c $(srcdir)/cat-id-tbl.c; then \ + rm cat-id-tbl.tmp.c; \ + else \ + echo cat-id-tbl.c changed; \ + rm -f $(srcdir)/cat-id-tbl.c; \ + mv cat-id-tbl.tmp.c $(srcdir)/cat-id-tbl.c; \ + fi + cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id + + +install: install-exec install-data +install-exec: +install-data: all + $(top_srcdir)/scripts/mkinstalldirs $(datadir) + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + if test "`echo $$cat | sed 's/.*\(\..*\)/\1/'`" = ".gmo"; then \ + destdir=$(gnulocaledir); \ + else \ + destdir=$(localedir); \ + fi; \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + $(top_srcdir)/scripts/mkinstalldirs $$dir; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + fi; \ + done + +# This installation goal is only used in GNU gettext. Packages which +# only use the library should use install instead. +install-src: install + $(top_srcdir)/scripts/mkinstalldirs $(gettextsrcdir) + cd $(srcdir) && \ + $(INSTALL_DATA) Makefile.in.in $(gettextsrcdir)/po-Makefile.in.in + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + done + rm -f $(gettextsrcdir)/po-Makefile.in.in + +check: all + +cat-id-tbl.o: ../intl/libgettext.h + +TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp.c + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist dist-gettext: update-po $(DISTFILES) + for file in $(DISTFILES); do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + if $(TUPDATE) $(PACKAGE).pot $$lang.old.po > $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "tupdate for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" \ + -e '$$s/\(.*\) \\/\1/' < $(srcdir)/POTFILES.in > POTFILES ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 000000000..fe5d39422 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,14 @@ +# List of source files containing translatable strings for G10. +# Copyright (c) 1998 by Werner Koch (dd9jn) + +# utility + +# cipher + + +# main program + +g10/g10.c +g10/pkclist.c + + diff --git a/po/de.po b/po/de.po new file mode 100644 index 000000000..a62cf145b --- /dev/null +++ b/po/de.po @@ -0,0 +1,308 @@ +msgid "" +msgstr "" +"Date: 1998-01-26 22:08:36+0100\n" +"From: Werner Koch \n" +"Content-Type: text/plain; charset=\n" +"Xgettext-Options: --default-domain=g10 --directory=.. --add-comments --keyword=_ --keyword=N_ --files-from=./POTFILES.in\n" +"Files: g10/g10.c g10/pkclist.c\n" + +#: g10/g10.c:77 +msgid "Please report bugs to .\n" +msgstr "Berichte über Wanzen bitte an .\n" + +#: g10/g10.c:82 +msgid "" +" NOTE: This version is compiled without ZLIB support;\n" +" you are not able to process compresssed data!\n" +"WARNING: This version has RSA support! Your are not allowed to\n" +" use it inside the Unites States before Sep 30, 2000!\n" +msgstr "" +"Achtung: Komprimierte Daten können nicht bearbeiten werden,\n" +" da auf diesem System ZLIN nicht installiert ist!\n" +" (RSA Verfahren ist vorhanden.)\n" + +#: g10/g10.c:88 +msgid "" +" NOTE: This version is compiled without ZLIB support;\n" +" you are not able to process compresssed data!\n" +msgstr "" +"Achtung: Komprimierte Daten können nicht bearbeiten werden,\n" +" da auf diesem System ZLIB nicht installiert ist!\n" + +#: g10/g10.c:92 +msgid "" +"WARNING: This version has RSA support! Your are not allowed to\n" +" use it inside the Unites States before Sep 30, 2000!\n" +msgstr "" +" (RSA Verfahren ist vorhanden.)\n" + +#: g10/g10.c:109 +msgid "Usage: g10 [options] " +msgstr "Aufruf: g10 [Opeionen] " + +#: g10/g10.c:145 +msgid "conflicting commands\n" +msgstr "" + +#: g10/g10.c:157 +msgid "create ascii armored output" +msgstr "Ausgabe mit ASCII Armor versehen" + +#: g10/g10.c:158 +msgid "verbose" +msgstr "detailierte Informationen" + +#: g10/g10.c:159 +msgid "set compress level (0 disables)" +msgstr "Kompressionspegel sethen (aussschalten mit 0)" + +#: g10/g10.c:160 +msgid "don't make any changes" +msgstr "Keine wirklichen Änderungen durchführen" + +#: g10/g10.c:168 +msgid "do only a symmetric encryption" +msgstr "" + +#: g10/g10.c:169 +msgid "use as output file" +msgstr "" + +#: g10/g10.c:170 +msgid "batch mode: never ask" +msgstr "" + +#: g10/g10.c:171 +msgid "assume yes on most questions" +msgstr "" + +#: g10/g10.c:172 +msgid "assume no on most questions" +msgstr "" + +#: g10/g10.c:173 +msgid "generate a new key pair" +msgstr "" + +#: g10/g10.c:174 +msgid "add key to the public keyring" +msgstr "" + +#: g10/g10.c:175 +msgid "remove key from public keyring" +msgstr "Key entfernen" + +#: g10/g10.c:176 +msgid "make a signature on a key in the keyring" +msgstr "key signieren" + +#: g10/g10.c:177 +msgid "store only" +msgstr "" + +#: g10/g10.c:178 +msgid "check signatures on a key in the keyring" +msgstr " " + +#: g10/g10.c:179 +msgid "add this keyring to the list of keyrings" +msgstr "" + +#: g10/g10.c:180 +msgid "make a signature" +msgstr "" + +#: g10/g10.c:181 +msgid "use canonical text mode" +msgstr "" + +#: g10/g10.c:182 +msgid "make a detached signature" +msgstr "" + +#: g10/g10.c:183 +msgid "encrypt data" +msgstr "" + +#: g10/g10.c:184 +msgid "decrypt data (default)" +msgstr "" + +#: g10/g10.c:185 +msgid "use this user-id to sign or decrypt" +msgstr "" + +#: g10/g10.c:186 +msgid "use this user-id for encryption" +msgstr "" + +#: g10/g10.c:187 +msgid "list keys" +msgstr "" + +#: g10/g10.c:188 +msgid "set debugging flags" +msgstr "" + +#: g10/g10.c:189 +msgid "enable full debugging" +msgstr "" + +#: g10/g10.c:193 +msgid "show the fingerprints" +msgstr "" + +#: g10/g10.c:194 +msgid "print all message digests" +msgstr "" + +#: g10/g10.c:195 +msgid "add this secret keyring to the list" +msgstr "" + +#: g10/g10.c:196 +msgid "read options from file" +msgstr "" + +#: g10/g10.c:199 +msgid "list only the sequence of packets" +msgstr "" + +#: g10/g10.c:202 +msgid "edit a key signature" +msgstr "" + +#: g10/g10.c:203 +msgid "change the passphrase of your secret keyring" +msgstr "" + +#: g10/g10.c:205 +msgid "select default cipher algorithm" +msgstr "" + +#: g10/g10.c:206 +msgid "select default puplic key algorithm" +msgstr "" + +#: g10/g10.c:207 +msgid "select default message digest algorithm" +msgstr "" + +#: g10/g10.c:208 +msgid "put public keys into the trustdb" +msgstr "" + +#: g10/g10.c:212 +msgid "do not write comment packets" +msgstr "" + +#: g10/g10.c:213 +msgid "(default is 1)" +msgstr "" + +#: g10/g10.c:214 +msgid "(default is 3)" +msgstr "" + +#: g10/g10.c:215 +msgid "export all or the given keys" +msgstr "" + +#: g10/g10.c:280 +msgid "note: no default option file '%s'\n" +msgstr "" + +#: g10/g10.c:283 +msgid "option file '%s': %s\n" +msgstr "" + +#: g10/g10.c:288 +msgid "reading options from '%s'\n" +msgstr "" + +#: g10/g10.c:380 +msgid "selected cipher algorithm is invalid\n" +msgstr "" + +#: g10/g10.c:384 +msgid "selected pubkey algorithm is invalid\n" +msgstr "" + +#: g10/g10.c:388 +msgid "selected digest algorithm is invalid\n" +msgstr "" + +#: g10/g10.c:392 +msgid "completes-needed must be greater than 0\n" +msgstr "" + +#: g10/g10.c:396 +msgid "marginals-needed must be greater than 1\n" +msgstr "" + +#: g10/g10.c:460 +msgid "failed to initialize the TrustDB: %s\n" +msgstr "" + +#: g10/g10.c:552 g10/g10.c:569 g10/g10.c:658 +msgid "can't open '%s'\n" +msgstr "" + +#: g10/pkclist.c:65 +msgid "" +"No ownertrust defined for %lu:\n" +"%4u%c/%08lX %s \"" +msgstr "" + +#: g10/pkclist.c:72 +msgid "" +"\"\n" +"\n" +"Please decide in how far do you trust this user to\n" +"correctly sign other users keys (looking at his passport,\n" +"checking the fingerprints from different sources ...)?\n" +"\n" +" 1 = Don't know\n" +" 2 = I do NOT trust\n" +" 3 = I trust marginally\n" +" 4 = I trust fully\n" +" s = please show me more informations\n" +"\n" +msgstr "" +"\"\n" +"\n" +"Bitte entscheiden Sie, in wieweit Sie diesem User zutrauen,\n" +"eines anderen Users Key korrekt zu signieren (Vergleich mit dem Paß,\n" +"vergleichen der Fingerprints aus unterschiedlichen Quellen ...)?\n" +"\n" +" 1 = Weiß nicht so recht\n" +" 2 = Neeh, dem traue ich das nicht zu\n" +" 3 = Ich vertraue ihm normalerweise\n" +" 4 = Ich vertraue ihm immer\n" +" s = Bitte weitere Information anzeigen\n" +"\n" + +#: g10/pkclist.c:83 +msgid "Your decision? " +msgstr "Ihre Auswahl? " + +#: g10/pkclist.c:90 +msgid "" +"It's up to you to assign a value here; this value will never be exported\n" +"to any 3rd party. We need it to implement the web-of-trust; it has nothing\n" +"to do with the (implicitly created) web-of-certificates.\n" +msgstr "" + +#: g10/pkclist.c:108 +msgid "You will see a list of signators etc. here\n" +msgstr "" + +#: g10/pkclist.c:132 +msgid "" +"Could not find a valid trust path to the key. Lets see, wether we\n" +"can assign some missing owner trust values.\n" +"\n" +msgstr "" +"Ein gültiger Trust Path konnte für diesen Key nicht gefunden werden.\n" +"Mal sehen ob wir now weitere Ownertrust Werte zuordnen können.\n" +"\n" diff --git a/util/argparse.c b/util/argparse.c index 89c873ce0..09c820a72 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -27,6 +27,7 @@ #include #include "util.h" +#include "i18n.h" /********************************* @@ -544,7 +545,7 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags ) indent += 10; puts("Options:"); for(i=0; opts[i].short_opt; i++ ) { - s = opts[i].description; + s = _(opts[i].description); if( s && *s== '\r' ) /* hide this line */ continue; if( opts[i].short_opt < 256 ) diff --git a/util/errors.c b/util/errors.c index b6024cb99..79a96d698 100644 --- a/util/errors.c +++ b/util/errors.c @@ -66,6 +66,7 @@ g10_errstr( int err ) X(SIG_CLASS ,"Unknown signature class") X(TRUSTDB ,"TrustDB error") X(BAD_CERT ,"Bad certificate") + X(INV_USER_ID ,"malformed user id") default: p = buf; sprintf(buf, "g10err=%d", err); break; } diff --git a/util/strgutil.c b/util/strgutil.c index cb80c57ab..286e90237 100644 --- a/util/strgutil.c +++ b/util/strgutil.c @@ -73,6 +73,31 @@ memistr( char *buf, size_t buflen, const char *sub ) return NULL ; } +/**************** + * Wie strncpy(), aber es werden maximal n-1 zeichen kopiert und ein + * '\0' angehängt. Ist n = 0, so geschieht nichts, ist Destination + * gleich NULL, so wird via m_alloc Speicher besorgt, ist dann nicht + * genügend Speicher vorhanden, so bricht die funktion ab. + */ +char * +mem2str( char *dest , const void *src , size_t n ) +{ + char *d; + const char *s; + + if( n ) { + if( !dest ) + dest = m_alloc( n ) ; + d = dest; + s = src ; + for(n--; n && *s; n-- ) + *d++ = *s++; + *d = '\0' ; + } + + return dest ; +} + /**************** * remove leading and trailing white spaces