Fixed an fopen problem on Windows Vista.

This commit is contained in:
Werner Koch 2009-06-03 17:24:24 +00:00
parent 323cca8041
commit dac70ca2fd
6 changed files with 70 additions and 74 deletions

View File

@ -1,3 +1,13 @@
2009-06-03 Werner Koch <wk@g10code.com>
* protect-tool.c: Include estream.h.
(store_private_key): Replace stdio streams by estream functions
for a portable use of the "x" mode.
* trustlist.c: Include estream.h.
(agent_marktrusted): Repalce stdio stream by estream functions.
* protect-tool.c (store_private_key): Use bin2hex.
2009-06-02 Werner Koch <wk@g10code.com> 2009-06-02 Werner Koch <wk@g10code.com>
* gpg-agent.c (main): Run pth_kill after fork. Fixes bug#1066. * gpg-agent.c (main): Run pth_kill after fork. Fixes bug#1066.

View File

@ -44,6 +44,7 @@
#include "i18n.h" #include "i18n.h"
#include "get-passphrase.h" #include "get-passphrase.h"
#include "sysutils.h" #include "sysutils.h"
#include "estream.h"
enum cmd_and_opt_values enum cmd_and_opt_values
@ -1199,18 +1200,15 @@ static int
store_private_key (const unsigned char *grip, store_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force) const void *buffer, size_t length, int force)
{ {
int i;
char *fname; char *fname;
FILE *fp; estream_t fp;
char hexgrip[40+4+1]; char hexgrip[40+4+1];
for (i=0; i < 20; i++) bin2hex (grip, 20, hexgrip);
sprintf (hexgrip+2*i, "%02X", grip[i]);
strcpy (hexgrip+40, ".key");
fname = make_filename (opt_homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); fname = make_filename (opt_homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
if (force) if (force)
fp = fopen (fname, "wb"); fp = es_fopen (fname, "wb");
else else
{ {
if (!access (fname, F_OK)) if (!access (fname, F_OK))
@ -1224,9 +1222,9 @@ store_private_key (const unsigned char *grip,
xfree (fname); xfree (fname);
return opt_no_fail_on_exist? 0 : -1; return opt_no_fail_on_exist? 0 : -1;
} }
fp = fopen (fname, "wbx"); /* FIXME: the x is a GNU extension - let /* FWIW: Under Windows Vista the standard fopen in the msvcrt
configure check whether this actually fails if the "x" GNU extension is used. */
works */ fp = es_fopen (fname, "wbx");
} }
if (!fp) if (!fp)
@ -1236,15 +1234,15 @@ store_private_key (const unsigned char *grip,
return -1; return -1;
} }
if (fwrite (buffer, length, 1, fp) != 1) if (es_fwrite (buffer, length, 1, fp) != 1)
{ {
log_error ("error writing `%s': %s\n", fname, strerror (errno)); log_error ("error writing `%s': %s\n", fname, strerror (errno));
fclose (fp); es_fclose (fp);
remove (fname); remove (fname);
xfree (fname); xfree (fname);
return -1; return -1;
} }
if ( fclose (fp) ) if (es_fclose (fp))
{ {
log_error ("error closing `%s': %s\n", fname, strerror (errno)); log_error ("error closing `%s': %s\n", fname, strerror (errno));
remove (fname); remove (fname);

View File

@ -31,6 +31,7 @@
#include "agent.h" #include "agent.h"
#include <assuan.h> /* fixme: need a way to avoid assuan calls here */ #include <assuan.h> /* fixme: need a way to avoid assuan calls here */
#include "i18n.h" #include "i18n.h"
#include "estream.h"
/* A structure to store the information from the trust file. */ /* A structure to store the information from the trust file. */
@ -552,7 +553,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
gpg_error_t err = 0; gpg_error_t err = 0;
char *desc; char *desc;
char *fname; char *fname;
FILE *fp; estream_t fp;
char *fprformatted; char *fprformatted;
char *nameformatted; char *nameformatted;
int is_disabled; int is_disabled;
@ -691,7 +692,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
fname = make_filename (opt.homedir, "trustlist.txt", NULL); fname = make_filename (opt.homedir, "trustlist.txt", NULL);
if ( access (fname, F_OK) && errno == ENOENT) if ( access (fname, F_OK) && errno == ENOENT)
{ {
fp = fopen (fname, "wx"); /* Warning: "x" is a GNU extension. */ fp = es_fopen (fname, "wx");
if (!fp) if (!fp)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
@ -702,10 +703,10 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
xfree (nameformatted); xfree (nameformatted);
return err; return err;
} }
fputs (headerblurb, fp); es_fputs (headerblurb, fp);
fclose (fp); es_fclose (fp);
} }
fp = fopen (fname, "a+"); fp = es_fopen (fname, "a+");
if (!fp) if (!fp)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
@ -718,22 +719,22 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
} }
/* Append the key. */ /* Append the key. */
fputs ("\n# ", fp); es_fputs ("\n# ", fp);
xfree (nameformatted); xfree (nameformatted);
nameformatted = reformat_name (name, "\n# "); nameformatted = reformat_name (name, "\n# ");
if (!nameformatted || strchr (name, '\n')) if (!nameformatted || strchr (name, '\n'))
{ {
/* Note that there should never be a LF in NAME but we better /* Note that there should never be a LF in NAME but we better
play safe and print a sanitized version in this case. */ play safe and print a sanitized version in this case. */
print_sanitized_string (fp, name, 0); es_write_sanitized (fp, name, strlen (name), NULL, NULL);
} }
else else
fputs (nameformatted, fp); es_fputs (nameformatted, fp);
fprintf (fp, "\n%s%s %c\n", yes_i_trust?"":"!", fprformatted, flag); es_fprintf (fp, "\n%s%s %c\n", yes_i_trust?"":"!", fprformatted, flag);
if (ferror (fp)) if (es_ferror (fp))
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
if (fclose (fp)) if (es_fclose (fp))
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
agent_reload_trustlist (); agent_reload_trustlist ();

View File

@ -1,3 +1,7 @@
2009-06-03 Werner Koch <wk@g10code.com>
* estream.c (es_convert_mode): Rewrite and support the "x" flag.
2009-05-28 David Shaw <dshaw@jabberwocky.com> 2009-05-28 David Shaw <dshaw@jabberwocky.com>
From 1.4: From 1.4:

View File

@ -897,67 +897,49 @@ static es_cookie_io_functions_t estream_functions_file =
}; };
/* Stream primitives. */
static int static int
es_convert_mode (const char *mode, unsigned int *modeflags) es_convert_mode (const char *mode, unsigned int *modeflags)
{ {
unsigned int omode, oflags;
/* FIXME: We need to allow all mode flags permutations. */ switch (*mode)
struct {
{ case 'r':
const char *mode; omode = O_RDONLY;
unsigned int flags; oflags = 0;
} mode_flags[] = { { "r",
O_RDONLY },
{ "rb",
O_RDONLY | O_BINARY },
{ "w",
O_WRONLY | O_TRUNC | O_CREAT },
{ "wb",
O_WRONLY | O_TRUNC | O_CREAT | O_BINARY },
{ "a",
O_WRONLY | O_APPEND | O_CREAT },
{ "ab",
O_WRONLY | O_APPEND | O_CREAT | O_BINARY },
{ "r+",
O_RDWR },
{ "rb+",
O_RDWR | O_BINARY },
{ "r+b",
O_RDONLY | O_WRONLY | O_BINARY },
{ "w+",
O_RDWR | O_TRUNC | O_CREAT },
{ "wb+",
O_RDWR | O_TRUNC | O_CREAT | O_BINARY },
{ "w+b",
O_RDWR | O_TRUNC | O_CREAT | O_BINARY },
{ "a+",
O_RDWR | O_CREAT | O_APPEND },
{ "ab+",
O_RDWR | O_CREAT | O_APPEND | O_BINARY },
{ "a+b",
O_RDWR | O_CREAT | O_APPEND | O_BINARY }
};
unsigned int i;
int err;
for (i = 0; i < DIM (mode_flags); i++)
if (! strcmp (mode_flags[i].mode, mode))
break; break;
if (i == DIM (mode_flags)) case 'w':
{ omode = O_WRONLY;
oflags = O_TRUNC | O_CREAT;
break;
case 'a':
omode = O_WRONLY;
oflags = O_APPEND | O_CREAT;
break;
default:
errno = EINVAL; errno = EINVAL;
err = -1; return -1;
} }
else for (mode++; *mode; mode++)
{ {
err = 0; switch (*mode)
*modeflags = mode_flags[i].flags; {
case '+':
omode = O_RDWR;
break;
case 'b':
oflags |= O_BINARY;
break;
case 'x':
oflags |= O_EXCL;
break;
default: /* Ignore unknown flags. */
break;
}
} }
return err; *modeflags = (omode | oflags);
return 0;
} }

View File

@ -195,6 +195,7 @@ get_manufacturer (unsigned int no)
case 0x0004: return "Wewid AB"; case 0x0004: return "Wewid AB";
case 0x0005: return "ZeitControl"; case 0x0005: return "ZeitControl";
case 0x002A: return "Magrathea";
/* 0x00000 and 0xFFFF are defined as test cards per spec, /* 0x00000 and 0xFFFF are defined as test cards per spec,
0xFFF00 to 0xFFFE are assigned for use with randomly created 0xFFF00 to 0xFFFE are assigned for use with randomly created
serial numbers. */ serial numbers. */