aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kbx/keybox-defs.h1
-rw-r--r--kbx/keybox-init.c1
-rw-r--r--kbx/keybox-update.c24
3 files changed, 21 insertions, 5 deletions
diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index 51ba8cd0e..32622a632 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -77,6 +77,7 @@ struct keybox_handle {
KB_NAME kb;
int secret; /* this is for a secret keybox */
estream_t fp;
+ int update_mode; /* FP is in update mode ("r+b"). */
int eof;
int error;
int ephemeral;
diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c
index 48af5c7a1..a5b7baec0 100644
--- a/kbx/keybox-init.c
+++ b/kbx/keybox-init.c
@@ -255,6 +255,7 @@ _keybox_close_file (KEYBOX_HANDLE hd)
{
es_fclose (roverhd->fp);
roverhd->fp = NULL;
+ roverhd->update_mode = 0;
}
}
log_assert (!hd->fp);
diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index 273265635..fd37ee5b3 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -509,6 +509,7 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
size_t flag_pos, flag_size;
const unsigned char *buffer;
size_t length;
+ gpgrt_off_t save_off;
(void)idx; /* Not yet used. */
@@ -535,11 +536,18 @@ 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 ();
+ if (!hd->fp || !hd->update_mode)
+ {
+ _keybox_close_file (hd);
+ fp = es_fopen (hd->kb->fname, "r+b");
+ if (!fp)
+ return gpg_error_from_syserror ();
+ hd->update_mode = 1;
+ }
+ else
+ fp = hd->fp;
+ save_off = es_ftello (fp);
ec = 0;
if (es_fseeko (fp, off, SEEK_SET))
ec = gpg_err_code_from_syserror ();
@@ -566,12 +574,18 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
}
}
- if (es_fclose (fp))
+ if (es_fflush (fp))
{
if (!ec)
ec = gpg_err_code_from_syserror ();
}
+ /* Get back to the last offset or close the file on error. */
+ if (save_off == (gpgrt_off_t)(-1) || es_fseeko (fp, save_off, SEEK_SET))
+ {
+ _keybox_close_file (hd);
+ }
+
return gpg_error (ec);
}