diff options
Diffstat (limited to 'kbx')
-rw-r--r-- | kbx/Makefile.in | 21 | ||||
-rw-r--r-- | kbx/keybox-defs.h | 8 | ||||
-rw-r--r-- | kbx/keybox-dump.c | 4 | ||||
-rw-r--r-- | kbx/keybox-init.c | 126 | ||||
-rw-r--r-- | kbx/keybox-search.c | 30 | ||||
-rw-r--r-- | kbx/keybox-update.c | 129 | ||||
-rw-r--r-- | kbx/keybox.h | 1 |
7 files changed, 218 insertions, 101 deletions
diff --git a/kbx/Makefile.in b/kbx/Makefile.in index c3a58cb..483d677 100644 --- a/kbx/Makefile.in +++ b/kbx/Makefile.in @@ -148,17 +148,16 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ - $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ - $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/npth.m4 $(top_srcdir)/m4/ntbtls.m4 \ - $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ - $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ksba.m4 $(top_srcdir)/m4/lcmessage.m4 \ + $(top_srcdir)/m4/ldap.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libassuan.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/npth.m4 \ + $(top_srcdir)/m4/ntbtls.m4 $(top_srcdir)/m4/pkg.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socklen.m4 \ + $(top_srcdir)/m4/sys_socket_h.m4 $(top_srcdir)/m4/tar-ustar.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 2751b4b..eafcf2c 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -139,6 +139,14 @@ typedef struct _keybox_openpgp_info *keybox_openpgp_info_t; /* } keybox_opt; */ /*-- keybox-init.c --*/ + +#define KEYBOX_LL_OPEN_READ 0 +#define KEYBOX_LL_OPEN_UPDATE 1 +#define KEYBOX_LL_OPEN_CREATE 2 +gpg_error_t _keybox_ll_open (estream_t *rfp, const char *fname, + unsigned int mode); +gpg_error_t _keybox_ll_close (estream_t fp); + void _keybox_close_file (KEYBOX_HANDLE hd); diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index 3e66b72..3bf63c9 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -810,6 +810,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) gpg_error_t tmperr = gpg_error_from_syserror (); fprintf (outfp, "error allocating array for '%s': %s\n", filename, strerror(errno)); + if (fp != es_stdin) + es_fclose (fp); return tmperr; } dupitems_count = 0; @@ -834,6 +836,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) fprintf (outfp, "error reallocating array for '%s': %s\n", filename, strerror(errno)); free (dupitems); + if (fp != es_stdin) + es_fclose (fp); return tmperr; } dupitems = tmp; diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index f07ba8d..1318e3e 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -28,8 +28,26 @@ #include "../common/sysutils.h" #include "../common/mischelp.h" +#ifdef HAVE_W32_SYSTEM +# define DEFAULT_LL_BUFFER_SIZE 128 +#else +# define DEFAULT_LL_BUFFER_SIZE 64 +#endif + +static unsigned int ll_buffer_size = DEFAULT_LL_BUFFER_SIZE; + static KB_NAME kb_names; +/* This object is used to mahe setvbuf buffers. We use a short arary + * to be able to reuse already allocated buffers. */ +struct stream_buffer_s +{ + int inuse; /* True if used by a stream. */ + size_t bufsize; + char *buf; +}; +static struct stream_buffer_s stream_buffers[5]; + /* Register a filename for plain keybox files. Returns 0 on success, * GPG_ERR_EEXIST if it has already been registered, or another error @@ -85,6 +103,16 @@ keybox_is_writable (void *token) } +/* Change the default buffering to KBYTES KiB; using 0 uses the syste + * buffers. This function must be called early. */ +void +keybox_set_buffersize (unsigned int kbytes, int reserved) +{ + (void)reserved; + /* Round down to 8k multiples. */ + ll_buffer_size = (kbytes + 7)/8 * 8; +} + static KEYBOX_HANDLE do_keybox_new (KB_NAME resource, int secret, int for_openpgp) @@ -180,7 +208,7 @@ keybox_release (KEYBOX_HANDLE hd) _keybox_release_blob (hd->saved_found.blob); if (hd->fp) { - es_fclose (hd->fp); + _keybox_ll_close (hd->fp); hd->fp = NULL; } xfree (hd->word_match.name); @@ -236,6 +264,100 @@ keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes) } +/* Low-level open function to be used for keybox files. This function + * also manages custom buffering. On success 0 is returned and a new + * file pointer stored at RFP; on error an error code is returned and + * NULL is stored at RFP. MODE is one of + * KEYBOX_LL_OPEN_READ(0) := fopen mode is "rb" + * KEYBOX_LL_OPEN_UPDATE := fopen mode is "r+b" + * KEYBOX_LL_OPEN_CREATE := fopen mode is "wb" + */ +gpg_error_t +_keybox_ll_open (estream_t *rfp, const char *fname, unsigned int mode) +{ + estream_t fp; + int i; + size_t bufsize; + + *rfp = NULL; + + fp = es_fopen (fname, + mode == KEYBOX_LL_OPEN_CREATE + ? "wb,sysopen,sequential" : + mode == KEYBOX_LL_OPEN_UPDATE + ? "r+b,sysopen,sequential" : + "rb,sysopen,sequential"); + if (!fp) + return gpg_error_from_syserror (); + + if (ll_buffer_size) + { + for (i=0; i < DIM (stream_buffers); i++) + if (!stream_buffers[i].inuse) + { + /* There is a free slot - we can use a larger buffer. */ + stream_buffers[i].inuse = 1; + if (!stream_buffers[i].buf) + { + bufsize = ll_buffer_size * 1024; + stream_buffers[i].buf = xtrymalloc (bufsize); + if (stream_buffers[i].buf) + stream_buffers[i].bufsize = bufsize; + else + { + log_info ("can't allocate a large buffer for a kbx file;" + " using default\n"); + stream_buffers[i].inuse = 0; + } + } + + if (stream_buffers[i].buf) + { + es_setvbuf (fp, stream_buffers[i].buf, _IOFBF, + stream_buffers[i].bufsize); + es_opaque_set (fp, stream_buffers + i); + } + break; + } + } + + *rfp = fp; + return 0; +} + + +/* Wrapper around es_fclose to be used for file opened with + * _keybox_ll_open. */ +gpg_error_t +_keybox_ll_close (estream_t fp) +{ + gpg_error_t err; + struct stream_buffer_s *sbuf; + int i; + + if (!fp) + return 0; + + sbuf = ll_buffer_size? es_opaque_get (fp) : NULL; + if (es_fclose (fp)) + err = gpg_error_from_syserror (); + else + err = 0; + if (sbuf) + { + for (i=0; i < DIM (stream_buffers); i++) + if (stream_buffers + i == sbuf) + break; + log_assert (i < DIM (stream_buffers)); + stream_buffers[i].inuse = 0; + } + + + return err; +} + + + /* Close the file of the resource identified by HD. For consistent results this function closes the files of all handles pointing to the resource identified by HD. */ @@ -253,7 +375,7 @@ _keybox_close_file (KEYBOX_HANDLE hd) { if (roverhd->fp) { - es_fclose (roverhd->fp); + _keybox_ll_close (roverhd->fp); roverhd->fp = NULL; } } diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 263a166..b1aee9e 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -777,28 +777,12 @@ release_sn_array (struct sn_array_s *array, size_t size) } -/* Helper to open the file. */ -static gpg_error_t -open_file (KEYBOX_HANDLE hd) -{ - - hd->fp = es_fopen (hd->kb->fname, "rb"); - if (!hd->fp) - { - hd->error = gpg_error_from_syserror (); - return hd->error; - } - - return 0; -} - - /* - - The search API - -*/ + * + * The search API + * + */ gpg_error_t keybox_search_reset (KEYBOX_HANDLE hd) @@ -822,7 +806,7 @@ keybox_search_reset (KEYBOX_HANDLE hd) { /* Ooops. Seek did not work. Close so that the search will * open the file again. */ - es_fclose (hd->fp); + _keybox_ll_close (hd->fp); hd->fp = NULL; } #endif @@ -901,7 +885,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, if (!hd->fp) { - rc = open_file (hd); + rc = _keybox_ll_open (&hd->fp, hd->kb->fname, 0); if (rc) { xfree (sn_array); @@ -1310,7 +1294,7 @@ keybox_seek (KEYBOX_HANDLE hd, off_t offset) return 0; } - err = open_file (hd); + err = _keybox_ll_open (&hd->fp, hd->kb->fname, 0); if (err) return err; } diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index 6e45f3d..15b5dbf 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -78,10 +78,9 @@ create_tmp_file (const char *template, err = keybox_tmp_names (template, 0, r_bakfname, r_tmpfname); if (!err) { - *r_fp = es_fopen (*r_tmpfname, "wb"); - if (!*r_fp) + err = _keybox_ll_open (r_fp, *r_tmpfname, KEYBOX_LL_OPEN_CREATE); + if (err) { - err = gpg_error_from_syserror (); xfree (*r_tmpfname); *r_tmpfname = NULL; xfree (*r_bakfname); @@ -174,31 +173,32 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, if ((ec = gnupg_access (fname, W_OK))) return gpg_error (ec); - fp = es_fopen (fname, "rb"); - if (mode == FILECOPY_INSERT && !fp && errno == ENOENT) + rc = _keybox_ll_open (&fp, fname, 0); + if (mode == FILECOPY_INSERT && gpg_err_code (rc) == GPG_ERR_ENOENT) { /* Insert mode but file does not exist: - Create a new keybox file. */ - newfp = es_fopen (fname, "wb"); - if (!newfp ) - return gpg_error_from_syserror (); + * Create a new keybox file. */ + rc = _keybox_ll_open (&newfp, fname, KEYBOX_LL_OPEN_CREATE); + if (rc) + return rc; rc = _keybox_write_header_blob (newfp, for_openpgp); if (rc) { - es_fclose (newfp); + _keybox_ll_close (newfp); return rc; } rc = _keybox_write_blob (blob, newfp, NULL); if (rc) { - es_fclose (newfp); + _keybox_ll_close (newfp); return rc; } - if ( es_fclose (newfp) ) - return gpg_error_from_syserror (); + rc = _keybox_ll_close (newfp); + if (rc) + return rc; /* if (chmod( fname, S_IRUSR | S_IWUSR )) */ /* { */ @@ -218,7 +218,7 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); if (rc) { - es_fclose (fp); + _keybox_ll_close (fp); goto leave; } @@ -242,16 +242,16 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, if (es_fwrite (buffer, nread, 1, newfp) != 1) { rc = gpg_error_from_syserror (); - es_fclose (fp); - es_fclose (newfp); + _keybox_ll_close (fp); + _keybox_ll_close (newfp); goto leave; } } if (es_ferror (fp)) { rc = gpg_error_from_syserror (); - es_fclose (fp); - es_fclose (newfp); + _keybox_ll_close (fp); + _keybox_ll_close (newfp); goto leave; } } @@ -275,16 +275,16 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, if (es_fwrite (buffer, nread, 1, newfp) != 1) { rc = gpg_error_from_syserror (); - es_fclose (fp); - es_fclose (newfp); + _keybox_ll_close (fp); + _keybox_ll_close (newfp); goto leave; } } if (es_ferror (fp)) { rc = gpg_error_from_syserror (); - es_fclose (fp); - es_fclose (newfp); + _keybox_ll_close (fp); + _keybox_ll_close (newfp); goto leave; } @@ -292,9 +292,9 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, rc = _keybox_read_blob (NULL, fp, NULL); if (rc) { - es_fclose (fp); - es_fclose (newfp); - return rc; + _keybox_ll_close (fp); + _keybox_ll_close (newfp); + goto leave; } } @@ -304,9 +304,9 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, rc = _keybox_write_blob (blob, newfp, NULL); if (rc) { - es_fclose (fp); - es_fclose (newfp); - return rc; + _keybox_ll_close (fp); + _keybox_ll_close (newfp); + goto leave; } } @@ -318,32 +318,30 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, if (es_fwrite (buffer, nread, 1, newfp) != 1) { rc = gpg_error_from_syserror (); - es_fclose (fp); - es_fclose (newfp); + _keybox_ll_close (fp); + _keybox_ll_close (newfp); goto leave; } } if (es_ferror (fp)) { rc = gpg_error_from_syserror (); - es_fclose (fp); - es_fclose (newfp); + _keybox_ll_close (fp); + _keybox_ll_close (newfp); goto leave; } } /* Close both files. */ - if (es_fclose(fp)) - { - rc = gpg_error_from_syserror (); - es_fclose (newfp); - goto leave; - } - if (es_fclose(newfp)) + rc = _keybox_ll_close (fp); + if (rc) { - rc = gpg_error_from_syserror (); + _keybox_ll_close (newfp); goto leave; } + rc = _keybox_ll_close (newfp); + if (rc) + goto leave; rc = rename_tmp_file (bakfname, tmpfname, fname, secret); @@ -491,6 +489,7 @@ keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, int keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value) { + gpg_error_t err; off_t off; const char *fname; estream_t fp; @@ -525,9 +524,10 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value) off += flag_pos; _keybox_close_file (hd); - fp = es_fopen (hd->kb->fname, "r+b"); - if (!fp) - return gpg_error_from_syserror (); + + err = _keybox_ll_open (&fp, fname, KEYBOX_LL_OPEN_UPDATE); + if (err) + return err; ec = 0; if (es_fseeko (fp, off, SEEK_SET)) @@ -555,10 +555,11 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value) } } - if (es_fclose (fp)) + err = _keybox_ll_close (fp); + if (err) { if (!ec) - ec = gpg_err_code_from_syserror (); + ec = gpg_err_code (err); } return gpg_error (ec); @@ -572,7 +573,7 @@ keybox_delete (KEYBOX_HANDLE hd) off_t off; const char *fname; estream_t fp; - int rc; + int rc, rc2; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -590,9 +591,9 @@ keybox_delete (KEYBOX_HANDLE hd) off += 4; _keybox_close_file (hd); - fp = es_fopen (hd->kb->fname, "r+b"); - if (!fp) - return gpg_error_from_syserror (); + rc = _keybox_ll_open (&fp, hd->kb->fname, KEYBOX_LL_OPEN_UPDATE); + if (rc) + return rc; if (es_fseeko (fp, off, SEEK_SET)) rc = gpg_error_from_syserror (); @@ -601,10 +602,11 @@ keybox_delete (KEYBOX_HANDLE hd) else rc = 0; - if (es_fclose (fp)) + rc2 = _keybox_ll_close (fp); + if (rc2) { if (!rc) - rc = gpg_error_from_syserror (); + rc = rc2; } return rc; @@ -617,7 +619,7 @@ int keybox_compress (KEYBOX_HANDLE hd) { gpg_err_code_t ec; - int read_rc, rc; + int read_rc, rc, rc2; const char *fname; estream_t fp, newfp; char *bakfname = NULL; @@ -645,14 +647,11 @@ keybox_compress (KEYBOX_HANDLE hd) if ((ec = gnupg_access (fname, W_OK))) return gpg_error (ec); - fp = es_fopen (fname, "rb"); - if (!fp && errno == ENOENT) + rc = _keybox_ll_open (&fp, fname, 0); + if (gpg_err_code (rc) == GPG_ERR_ENOENT) return 0; /* Ready. File has been deleted right after the access above. */ - if (!fp) - { - rc = gpg_error_from_syserror (); - return rc; - } + if (rc) + return rc; /* A quick test to see if we need to compress the file at all. We schedule a compress run after 3 hours. */ @@ -668,7 +667,7 @@ keybox_compress (KEYBOX_HANDLE hd) if ( (last_maint + 3*3600) > make_timestamp () ) { - es_fclose (fp); + _keybox_ll_close (fp); _keybox_release_blob (blob); return 0; /* Compress run not yet needed. */ } @@ -682,7 +681,7 @@ keybox_compress (KEYBOX_HANDLE hd) rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); if (rc) { - es_fclose (fp); + _keybox_ll_close (fp); return rc;; } @@ -771,10 +770,10 @@ keybox_compress (KEYBOX_HANDLE hd) rc = read_rc; /* Close both files. */ - if (es_fclose(fp) && !rc) - rc = gpg_error_from_syserror (); - if (es_fclose(newfp) && !rc) - rc = gpg_error_from_syserror (); + if ((rc2 = _keybox_ll_close (fp)) && !rc) + rc = rc2; + if ((rc2 = _keybox_ll_close (newfp)) && !rc) + rc = rc2; /* Rename or remove the temporary file. */ if (rc || !any_changes) diff --git a/kbx/keybox.h b/kbx/keybox.h index f90ea1c..adfa5a8 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -66,6 +66,7 @@ typedef enum /*-- keybox-init.c --*/ gpg_error_t keybox_register_file (const char *fname, int secret, void **r_token); +void keybox_set_buffersize (unsigned int kbytes, int reserved); int keybox_is_writable (void *token); KEYBOX_HANDLE keybox_new_openpgp (void *token, int secret); |