diff --git a/NEWS b/NEWS index df6a5dcc..44eeca79 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,11 @@ Noteworthy changes in version 1.1.0 (unreleased) indicates if a key can be used for qualified signatures according to local government regulations. + * You can associate a filename with a data object using the new + gpgme_data_set_filename() function. This filename will be stored + in the output when encrypting or signing the data and will be + returned when decrypting or verifying the output data. + * Interface changes relative to the 1.0.3 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_set_engine_info NEW @@ -40,11 +45,12 @@ gpgme_ctx_set_engine_info NEW gpgme_recipient_t NEW gpgme_decrypt_result_t EXTENDED: New field recipients. gpgme_verify_result_t EXTENDED: New fields pubkey_algo, hash_algo. -gpgme_decrypt_result_t EXTENDED: New field file_name. -gpgme_verify_result_t EXTENDED: New field file_name. +gpgme_decrypt_result_t EXTENDED: New field plaintext_filename. +gpgme_verify_result_t EXTENDED: New field plaintext_filename. GPGME_STATUS_PLAINTEXT NEW gpgme_key_t EXTENDED: New field is_qualified. gpgme_subkey_t EXTENDED: New field is_qualified. +gpgme_data_set_filename NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/ChangeLog b/doc/ChangeLog index 46ee86e1..681ed9b2 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,8 @@ 2005-09-30 Marcus Brinkmann + * gpgme.texi (Data Buffer I/O Operations, Data Buffer Meta-Data): + New subsections. + * gpgme.texi: Replace plaintext_filename with file_name. * gpgme.texi (Key Management): Document is_qualified. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index e0f7b770..44cdcbb1 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -153,6 +153,11 @@ Creating Data Buffers * File Based Data Buffers:: Creating file based data buffers. * Callback Based Data Buffers:: Creating callback based data buffers. +Manipulating Data Buffers + +* Data Buffer I/O Operations:: I/O operations on data buffers. +* Data Buffer Meta-Data:: Meta-data manipulation of data buffers. + Contexts * Creating Contexts:: Creating new @acronym{GPGME} contexts. @@ -1716,7 +1721,24 @@ be returned to the user, the function will return @code{NULL}. @node Manipulating Data Buffers @section Manipulating Data Buffers -@cindex data buffere, manipulation +@cindex data buffer, manipulation + +Data buffers contain data and meta-data. The following operations can +be used to manipulate both. + + +@menu +* Data Buffer I/O Operations:: I/O operations on data buffers. +* Data Buffer Meta-Data:: Meta-data manipulation of data buffers. +@end menu + + +@node Data Buffer I/O Operations +@subsection Data Buffer I/O Operations +@cindex data buffer, I/O operations +@cindex data buffer, read +@cindex data buffer, write +@cindex data buffer, seek @deftypefun ssize_t gpgme_data_read (@w{gpgme_data_t @var{dh}}, @w{void *@var{buffer}}, @w{size_t @var{length}}) The function @code{gpgme_data_read} reads up to @var{length} bytes @@ -1783,9 +1805,39 @@ The function @code{gpgme_data_rewind} is equivalent to: @end example @end deftypefun -@c -@c gpgme_data_encoding_t -@c + + + +@node Data Buffer Meta-Data +@subsection Data Buffer Meta-Data +@cindex data buffer, meta-data +@cindex data buffer, file name +@cindex data buffer, encoding + +@deftypefun char *gpgme_data_get_file_name (@w{gpgme_data_t @var{dh}}) +The function @code{gpgme_data_get_file_name} returns a pointer to a +string containing the file name associated with the data object. The +file name will be stored in the output when encrypting or signing the +data and will be returned to the user when decrypting or verifying the +output data. + +If no error occurs, the string containing the file name is returned. +Otherwise, @code{NULL} will be returned. +@end deftypefun + + +@deftypefun gpgme_error_t gpgme_data_set_file_name (@w{gpgme_data_t @var{dh}}, @w{const char *@var{file_name}}) +The function @code{gpgme_data_set_file_name} sets the file name +associated with the data object. The file name will be stored in the +output when encrypting or signing the data and will be returned to the +user when decrypting or verifying the output data. + +The function returns the error code @code{GPG_ERR_INV_VALUE} if +@var{dh} is not a valid pointer and @code{GPG_ERR_ENOMEM} if not +enough memory is available. +@end deftypefun + + @deftp {Data type} {enum gpgme_data_encoding_t} @tindex gpgme_data_encoding_t The @code{gpgme_data_encoding_t} type specifies the encoding of a diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 71d02e98..6ec0bfd2 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,5 +1,15 @@ 2005-09-30 Marcus Brinkmann + * data.h (struct gpgme_data): New member file_name. + * data.c (gpgme_data_set_filename): New function. + (_gpgme_data_release): Free DH->filename if necessary. + (gpgme_data_get_filename): New function. + * rungpg.c (gpg_encrypt): Set filename option. + (gpg_encrypt_sign): Likewise. + (gpg_sign): Likewise. + * libgpgme.vers (GPGME_1.1): Add gpgme_data_set_file_name and + gpgme_data_get_file_name. + * decrpyt.c, verify.c, gpgme.h: Replace plaintext_filename with file_name. diff --git a/gpgme/data.c b/gpgme/data.c index 144dc863..3f38bd32 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -57,8 +57,12 @@ _gpgme_data_new (gpgme_data_t *r_dh, struct _gpgme_data_cbs *cbs) void _gpgme_data_release (gpgme_data_t dh) { - if (dh) - free (dh); + if (!dh) + return; + + if (dh->file_name) + free (dh->file_name); + free (dh); } @@ -167,6 +171,36 @@ gpgme_data_set_encoding (gpgme_data_t dh, gpgme_data_encoding_t enc) return 0; } + +/* Set the file name associated with the data object with handle DH to + FILE_NAME. */ +gpgme_error_t +gpgme_data_set_file_name (gpgme_data_t dh, const char *file_name) +{ + if (!dh) + return gpg_error (GPG_ERR_INV_VALUE); + + if (dh->file_name) + free (dh->file_name); + + dh->file_name = strdup (file_name); + if (!dh->file_name) + return gpg_error_from_errno (errno); + + return 0; +} + +/* Get the file name associated with the data object with handle DH, + or NULL if there is none. */ +char * +gpgme_data_get_file_name (gpgme_data_t dh) +{ + if (!dh) + return NULL; + + return dh->file_name; +} + /* Functions to support the wait interface. */ diff --git a/gpgme/data.h b/gpgme/data.h index feb4a60a..80eeae8b 100644 --- a/gpgme/data.h +++ b/gpgme/data.h @@ -77,6 +77,9 @@ struct gpgme_data char pending[BUFFER_SIZE]; int pending_len; + /* File name of the data object. */ + char *file_name; + union { /* For gpgme_data_new_from_fd. */ diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index be75e724..f0f27d9b 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -952,6 +952,14 @@ gpgme_data_encoding_t gpgme_data_get_encoding (gpgme_data_t dh); gpgme_error_t gpgme_data_set_encoding (gpgme_data_t dh, gpgme_data_encoding_t enc); +/* Get the filename associated with the data object with handle DH, or + NULL if there is none. */ +char *gpgme_data_get_file_name (gpgme_data_t dh); + +/* Set the filename associated with the data object with handle DH to + FILE_NAME. */ +gpgme_error_t gpgme_data_set_file_name (gpgme_data_t dh, + const char *file_name); /* Create a new data buffer which retrieves the data from the callback diff --git a/gpgme/libgpgme.vers b/gpgme/libgpgme.vers index ec7f6b98..4735f49b 100644 --- a/gpgme/libgpgme.vers +++ b/gpgme/libgpgme.vers @@ -27,6 +27,9 @@ GPGME_1.1 { gpgme_ctx_get_engine_info; gpgme_ctx_set_engine_info; + + gpgme_data_set_file_name; + gpgme_data_get_file_name; }; diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 66d1bda6..86710a0d 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -1339,6 +1339,13 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, err = add_arg (gpg, "-"); if (!err) err = add_data (gpg, ciph, 1, 1); + if (gpgme_data_get_file_name (plain)) + { + if (!err) + err = add_arg (gpg, "--set-filename"); + if (!err) + err = add_arg (gpg, gpgme_data_get_file_name (plain)); + } if (!err) err = add_arg (gpg, "--"); if (!err) @@ -1384,6 +1391,13 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], err = add_arg (gpg, "-"); if (!err) err = add_data (gpg, ciph, 1, 1); + if (gpgme_data_get_file_name (plain)) + { + if (!err) + err = add_arg (gpg, "--set-filename"); + if (!err) + err = add_arg (gpg, gpgme_data_get_file_name (plain)); + } if (!err) err = add_arg (gpg, "--"); if (!err) @@ -1595,6 +1609,14 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out, if (!err) err = append_args_from_signers (gpg, ctx); + if (gpgme_data_get_file_name (in)) + { + if (!err) + err = add_arg (gpg, "--set-filename"); + if (!err) + err = add_arg (gpg, gpgme_data_get_file_name (in)); + } + /* Tell the gpg object about the data. */ if (!err) err = add_data (gpg, in, 0, 0); diff --git a/tests/ChangeLog b/tests/ChangeLog index 3932be39..94645929 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2005-09-30 Marcus Brinkmann + + * gpg/Makefile.am (TESTS): Add t-filename. + * gpg/t-filename.c: New file. + 2005-09-23 Werner Koch * gpg/t-support.h (init_gpgme) [W32]: Don't use LC_MESSAGES. diff --git a/tests/gpg/Makefile.am b/tests/gpg/Makefile.am index 7301240e..0fa03492 100644 --- a/tests/gpg/Makefile.am +++ b/tests/gpg/Makefile.am @@ -28,7 +28,8 @@ noinst_HEADERS = t-support.h TESTS = t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers \ t-decrypt t-verify t-decrypt-verify \ t-export t-import t-trustlist t-eventloop t-edit \ - t-keylist t-keylist-sig t-thread1 t-wait t-encrypt-large + t-keylist t-keylist-sig t-thread1 t-wait t-encrypt-large \ + t-file-name CLEANFILES = secring.gpg pubring.gpg trustdb.gpg DISTCLEANFILES = pubring.gpg~ random_seed diff --git a/tests/gpg/t-file-name.c b/tests/gpg/t-file-name.c new file mode 100644 index 00000000..eb20fc03 --- /dev/null +++ b/tests/gpg/t-file-name.c @@ -0,0 +1,99 @@ +/* t-file-name.c - Regression test. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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. */ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "t-support.h" + +#define TESTNAME "abcde12345" + + +int +main (int argc, char *argv[]) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t in, out; + gpgme_key_t key[2] = { NULL, NULL }; + gpgme_decrypt_result_t result; + char *agent_info; + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_armor (ctx, 1); + + agent_info = getenv("GPG_AGENT_INFO"); + if (!(agent_info && strchr (agent_info, ':'))) + gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); + + err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0); + fail_if_err (err); + + err = gpgme_data_set_file_name (in, TESTNAME); + fail_if_err (err); + + err = gpgme_data_new (&out); + fail_if_err (err); + + err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734", + &key[0], 0); + fail_if_err (err); + + err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + fail_if_err (err); + + gpgme_data_release (in); + err = gpgme_data_new (&in); + fail_if_err (err); + + err = gpgme_data_seek (out, 0, SEEK_SET); + fail_if_err (err); + + err = gpgme_op_decrypt (ctx, out, in); + fail_if_err (err); + result = gpgme_op_decrypt_result (ctx); + + if (strcmp (TESTNAME, result->file_name)) + { + fprintf (stderr, "%s:%i: Unexpected result file name: %s\n", + __FILE__, __LINE__, + result->file_name ? "(null)" : result->file_name); + exit (1); + } + + gpgme_key_unref (key[0]); + gpgme_data_release (in); + gpgme_data_release (out); + gpgme_release (ctx); + return 0; +}