mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
dirmngr: Allow command VERSIONCHECK to handle 3 part version numbers.
* dirmngr/server.c (parse_version_string): Add arg MICRO and set it. (cmp_version): Extend to handle the MICRO part. (confucius_mktmpdir): Rename to my_mktmpdir. (my_mktmpdir): xstrconcat does not fail; use strconcat. (fetch_into_tmpdir): Improve error checking. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
7983f87587
commit
b120f358c2
118
dirmngr/server.c
118
dirmngr/server.c
@ -2342,6 +2342,10 @@ cmd_reloaddirmngr (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
|
||||
/* This function parses the first portion of the version number S and
|
||||
* stores it in *NUMBER. On success, this function returns a pointer
|
||||
* into S starting with the first character, which is not part of the
|
||||
* initial number portion; on failure, NULL is returned. */
|
||||
static const char*
|
||||
parse_version_number (const char *s, int *number)
|
||||
{
|
||||
@ -2359,8 +2363,16 @@ parse_version_number (const char *s, int *number)
|
||||
}
|
||||
|
||||
|
||||
/* This function breaks up the complete string-representation of the
|
||||
* version number S, which is of the following struture: <major
|
||||
* number>.<minor number>[.<micro number>]<patch level>. The major,
|
||||
* minor and micro number components will be stored in *MAJOR, *MINOR
|
||||
* and *MICRO. If MICRO is not given 0 is used instead.
|
||||
*
|
||||
* On success, the last component, the patch level, will be returned;
|
||||
* on failure, NULL will be returned. */
|
||||
static const char *
|
||||
parse_version_string (const char *s, int *major, int *minor)
|
||||
parse_version_string (const char *s, int *major, int *minor, int *micro)
|
||||
{
|
||||
s = parse_version_number (s, major);
|
||||
if (!s || *s != '.')
|
||||
@ -2369,18 +2381,23 @@ parse_version_string (const char *s, int *major, int *minor)
|
||||
s = parse_version_number (s, minor);
|
||||
if (!s)
|
||||
return NULL;
|
||||
if (*s == '.')
|
||||
{
|
||||
s++;
|
||||
s = parse_version_number (s, micro);
|
||||
if (!s)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
micro = 0;
|
||||
return s; /* Patchlevel. */
|
||||
}
|
||||
|
||||
/* Class Confucius.
|
||||
|
||||
"Don't worry that other people don't know you;
|
||||
worry that you don't know other people." Analects--1.16. */
|
||||
|
||||
/* Create temporary directory with mode 0700. Returns a dynamically
|
||||
allocated string with the filename of the directory. */
|
||||
* allocated string with the filename of the directory. */
|
||||
static char *
|
||||
confucius_mktmpdir (void)
|
||||
my_mktmpdir (void)
|
||||
{
|
||||
char *name, *p;
|
||||
|
||||
@ -2388,19 +2405,22 @@ confucius_mktmpdir (void)
|
||||
if (!p || !*p)
|
||||
p = "/tmp";
|
||||
if (p[strlen (p) - 1] == '/')
|
||||
name = xstrconcat (p, "gpg-XXXXXX", NULL);
|
||||
name = strconcat (p, "gpg-XXXXXX", NULL);
|
||||
else
|
||||
name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
|
||||
name = strconcat (p, "/", "gpg-XXXXXX", NULL);
|
||||
if (!name || !gnupg_mkdtemp (name))
|
||||
{
|
||||
int saveerr = errno;
|
||||
log_error (_("can't create temporary directory '%s': %s\n"),
|
||||
name?name:"", strerror (errno));
|
||||
name, strerror (saveerr));
|
||||
gpg_err_set_errno (saveerr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/* Sets result to -1 if version a is less than b, 0 if the versions are equal
|
||||
* and 1 otherwise. Patch levels are compared as strings. */
|
||||
static gpg_error_t
|
||||
@ -2408,21 +2428,27 @@ cmp_version (const char *a, const char *b, int *result)
|
||||
{
|
||||
int a_major, b_major;
|
||||
int a_minor, b_minor;
|
||||
int a_micro, b_micro;
|
||||
const char *a_patch, *b_patch;
|
||||
|
||||
if (!a || !b || !result)
|
||||
return GPG_ERR_EINVAL;
|
||||
return gpg_error (GPG_ERR_EINVAL);
|
||||
|
||||
a_patch = parse_version_string (a, &a_major, &a_minor);
|
||||
b_patch = parse_version_string (b, &b_major, &b_minor);
|
||||
a_patch = parse_version_string (a, &a_major, &a_minor, &a_micro);
|
||||
b_patch = parse_version_string (b, &b_major, &b_minor, &b_micro);
|
||||
|
||||
if (!a_patch || !b_patch)
|
||||
return GPG_ERR_EINVAL;
|
||||
return gpg_error (GPG_ERR_EINVAL);
|
||||
|
||||
if (a_major == b_major)
|
||||
{
|
||||
if (a_minor == b_minor)
|
||||
*result = strcmp (a_patch, b_patch);
|
||||
{
|
||||
if (a_micro == b_micro)
|
||||
*result = strcmp (a_patch, b_patch);
|
||||
else
|
||||
*result = a_micro - b_minor;
|
||||
}
|
||||
else
|
||||
*result = a_minor - b_minor;
|
||||
}
|
||||
@ -2432,25 +2458,26 @@ cmp_version (const char *a, const char *b, int *result)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
fetch_into_tmpdir (ctrl_t ctrl, const char* url, estream_t* strm_out,
|
||||
char** path)
|
||||
fetch_into_tmpdir (ctrl_t ctrl, const char *url, estream_t *strm_out,
|
||||
char **path)
|
||||
{
|
||||
gpg_error_t err;
|
||||
char* filename = NULL;
|
||||
char* dirname = NULL;
|
||||
estream_t file;
|
||||
estream_t strm;
|
||||
size_t len = 0;
|
||||
char *filename = NULL;
|
||||
char *dirname = NULL;
|
||||
estream_t file = NULL;
|
||||
estream_t strm = NULL;
|
||||
size_t len, nwritten;
|
||||
char buf[1024];
|
||||
|
||||
if (!strm_out || !path || !url)
|
||||
{
|
||||
err = (GPG_ERR_INV_ARG);
|
||||
err = gpg_error (GPG_ERR_INV_ARG);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
dirname = confucius_mktmpdir ();
|
||||
dirname = my_mktmpdir ();
|
||||
if (!dirname)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
@ -2465,39 +2492,60 @@ fetch_into_tmpdir (ctrl_t ctrl, const char* url, estream_t* strm_out,
|
||||
}
|
||||
|
||||
file = es_fopen (filename, "w+");
|
||||
if (!file)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if ((err = ks_http_fetch (ctrl, url, &strm)))
|
||||
goto leave;
|
||||
|
||||
while (!es_read (strm, buf, sizeof buf, &len))
|
||||
for (;;)
|
||||
{
|
||||
if (es_read (strm, buf, sizeof buf, &len))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error reading '%s': %s\n",
|
||||
es_fname_get (strm), gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
break;
|
||||
if ((err = es_write (file, buf, len, NULL)))
|
||||
if (es_write (file, buf, len, &nwritten))
|
||||
{
|
||||
log_error ("error writing message to pipe: %s\n", gpg_strerror (err));
|
||||
es_free (strm);
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error writing '%s': %s\n", filename, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
else if (len != nwritten)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_EIO);
|
||||
log_error ("error writing '%s': %s\n", filename, "short write");
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
es_rewind (file);
|
||||
es_fclose (strm);
|
||||
*strm_out = file;
|
||||
err = 0;
|
||||
file = NULL;
|
||||
|
||||
if (path)
|
||||
{
|
||||
*path = dirname;
|
||||
dirname = NULL;
|
||||
*path = dirname;
|
||||
dirname = NULL;
|
||||
}
|
||||
|
||||
leave:
|
||||
leave:
|
||||
es_fclose (file);
|
||||
es_fclose (strm);
|
||||
xfree (dirname);
|
||||
xfree (filename);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static const char hlp_versioncheck[] =
|
||||
"VERSIONCHECK <name> <version>"
|
||||
"\n"
|
||||
@ -2510,8 +2558,8 @@ cmd_versioncheck (assuan_context_t ctx, char *line)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
char* name;
|
||||
char* version;
|
||||
char *name;
|
||||
char *version;
|
||||
size_t name_len;
|
||||
char *cmd_fields[2];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user