diff -Nru geoipupdate-2.4.0/bin/base64.c geoipupdate-2.5.0/bin/base64.c --- geoipupdate-2.4.0/bin/base64.c 2017-05-24 15:04:20.000000000 +0000 +++ geoipupdate-2.5.0/bin/base64.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,575 +0,0 @@ -/* base64.c -- Encode binary data using printable characters. - Copyright (C) 1999-2001, 2004-2006, 2009-2012 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -/* Written by Simon Josefsson. Partially adapted from GNU MailUtils - * (mailbox/filter_trans.c, as of 2004-11-28). Improved by review - * from Paul Eggert, Bruno Haible, and Stepan Kasal. - * - * See also RFC 4648 . - * - * Be careful with error checking. Here is how you would typically - * use these functions: - * - * bool ok = base64_decode_alloc (in, inlen, &out, &outlen); - * if (!ok) - * FAIL: input was not valid base64 - * if (out == NULL) - * FAIL: memory allocation error - * OK: data in OUT/OUTLEN - * - * size_t outlen = base64_encode_alloc (in, inlen, &out); - * if (out == NULL && outlen == 0 && inlen != 0) - * FAIL: input too long - * if (out == NULL) - * FAIL: memory allocation error - * OK: data in OUT/OUTLEN. - * - */ - -/* Get prototype. */ -#include "base64.h" - -/* Get malloc. */ -#include - -/* Get UCHAR_MAX. */ -#include - -#include - -/* C89 compliant way to cast 'char' to 'unsigned char'. */ -static unsigned char -to_uchar(char ch) -{ - return ch; -} - -/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN. - If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as - possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero - terminate the output buffer. */ -void -base64_encode(const char *restrict in, size_t inlen, - char *restrict out, size_t outlen) -{ - static const char b64str[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - while (inlen && outlen) { - *out++ = b64str[(to_uchar(in[0]) >> 2) & 0x3f]; - if (!--outlen) { - break; - } - *out++ = b64str[((to_uchar(in[0]) << 4) - + (--inlen ? to_uchar(in[1]) >> 4 : 0)) - & 0x3f]; - if (!--outlen) { - break; - } - *out++ = - (inlen - ? b64str[((to_uchar(in[1]) << 2) - + (--inlen ? to_uchar(in[2]) >> 6 : 0)) - & 0x3f] - : '='); - if (!--outlen) { - break; - } - *out++ = inlen ? b64str[to_uchar(in[2]) & 0x3f] : '='; - if (!--outlen) { - break; - } - if (inlen) { - inlen--; - } - if (inlen) { - in += 3; - } - } - - if (outlen) { - *out = '\0'; - } -} - -/* Allocate a buffer and store zero terminated base64 encoded data - from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e., - the length of the encoded data, excluding the terminating zero. On - return, the OUT variable will hold a pointer to newly allocated - memory that must be deallocated by the caller. If output string - length would overflow, 0 is returned and OUT is set to NULL. If - memory allocation failed, OUT is set to NULL, and the return value - indicates length of the requested memory block, i.e., - BASE64_LENGTH(inlen) + 1. */ -size_t -base64_encode_alloc(const char *in, size_t inlen, char **out) -{ - size_t outlen = 1 + BASE64_LENGTH(inlen); - - /* Check for overflow in outlen computation. - * - * If there is no overflow, outlen >= inlen. - * - * If the operation (inlen + 2) overflows then it yields at most +1, so - * outlen is 0. - * - * If the multiplication overflows, we lose at least half of the - * correct value, so the result is < ((inlen + 2) / 3) * 2, which is - * less than (inlen + 2) * 0.66667, which is less than inlen as soon as - * (inlen > 4). - */ - if (inlen > outlen) { - *out = NULL; - return 0; - } - - *out = malloc(outlen); - if (!*out) { - return outlen; - } - - base64_encode(in, inlen, *out, outlen); - - return outlen - 1; -} - -/* With this approach this file works independent of the charset used - (think EBCDIC). However, it does assume that the characters in the - Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX - 1003.1-2001 require that char and unsigned char are 8-bit - quantities, though, taking care of that problem. But this may be a - potential problem on non-POSIX C99 platforms. - - IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_" - as the formal parameter rather than "x". */ -#define B64(_) \ - ((_) == 'A' ? 0 \ - : (_) == 'B' ? 1 \ - : (_) == 'C' ? 2 \ - : (_) == 'D' ? 3 \ - : (_) == 'E' ? 4 \ - : (_) == 'F' ? 5 \ - : (_) == 'G' ? 6 \ - : (_) == 'H' ? 7 \ - : (_) == 'I' ? 8 \ - : (_) == 'J' ? 9 \ - : (_) == 'K' ? 10 \ - : (_) == 'L' ? 11 \ - : (_) == 'M' ? 12 \ - : (_) == 'N' ? 13 \ - : (_) == 'O' ? 14 \ - : (_) == 'P' ? 15 \ - : (_) == 'Q' ? 16 \ - : (_) == 'R' ? 17 \ - : (_) == 'S' ? 18 \ - : (_) == 'T' ? 19 \ - : (_) == 'U' ? 20 \ - : (_) == 'V' ? 21 \ - : (_) == 'W' ? 22 \ - : (_) == 'X' ? 23 \ - : (_) == 'Y' ? 24 \ - : (_) == 'Z' ? 25 \ - : (_) == 'a' ? 26 \ - : (_) == 'b' ? 27 \ - : (_) == 'c' ? 28 \ - : (_) == 'd' ? 29 \ - : (_) == 'e' ? 30 \ - : (_) == 'f' ? 31 \ - : (_) == 'g' ? 32 \ - : (_) == 'h' ? 33 \ - : (_) == 'i' ? 34 \ - : (_) == 'j' ? 35 \ - : (_) == 'k' ? 36 \ - : (_) == 'l' ? 37 \ - : (_) == 'm' ? 38 \ - : (_) == 'n' ? 39 \ - : (_) == 'o' ? 40 \ - : (_) == 'p' ? 41 \ - : (_) == 'q' ? 42 \ - : (_) == 'r' ? 43 \ - : (_) == 's' ? 44 \ - : (_) == 't' ? 45 \ - : (_) == 'u' ? 46 \ - : (_) == 'v' ? 47 \ - : (_) == 'w' ? 48 \ - : (_) == 'x' ? 49 \ - : (_) == 'y' ? 50 \ - : (_) == 'z' ? 51 \ - : (_) == '0' ? 52 \ - : (_) == '1' ? 53 \ - : (_) == '2' ? 54 \ - : (_) == '3' ? 55 \ - : (_) == '4' ? 56 \ - : (_) == '5' ? 57 \ - : (_) == '6' ? 58 \ - : (_) == '7' ? 59 \ - : (_) == '8' ? 60 \ - : (_) == '9' ? 61 \ - : (_) == '+' ? 62 \ - : (_) == '/' ? 63 \ - : -1) - -static const signed char b64[0x100] = { - B64(0), B64(1), B64(2), B64(3), - B64(4), B64(5), B64(6), B64(7), - B64(8), B64(9), B64(10), B64(11), - B64(12), B64(13), B64(14), B64(15), - B64(16), B64(17), B64(18), B64(19), - B64(20), B64(21), B64(22), B64(23), - B64(24), B64(25), B64(26), B64(27), - B64(28), B64(29), B64(30), B64(31), - B64(32), B64(33), B64(34), B64(35), - B64(36), B64(37), B64(38), B64(39), - B64(40), B64(41), B64(42), B64(43), - B64(44), B64(45), B64(46), B64(47), - B64(48), B64(49), B64(50), B64(51), - B64(52), B64(53), B64(54), B64(55), - B64(56), B64(57), B64(58), B64(59), - B64(60), B64(61), B64(62), B64(63), - B64(64), B64(65), B64(66), B64(67), - B64(68), B64(69), B64(70), B64(71), - B64(72), B64(73), B64(74), B64(75), - B64(76), B64(77), B64(78), B64(79), - B64(80), B64(81), B64(82), B64(83), - B64(84), B64(85), B64(86), B64(87), - B64(88), B64(89), B64(90), B64(91), - B64(92), B64(93), B64(94), B64(95), - B64(96), B64(97), B64(98), B64(99), - B64(100), B64(101), B64(102), B64(103), - B64(104), B64(105), B64(106), B64(107), - B64(108), B64(109), B64(110), B64(111), - B64(112), B64(113), B64(114), B64(115), - B64(116), B64(117), B64(118), B64(119), - B64(120), B64(121), B64(122), B64(123), - B64(124), B64(125), B64(126), B64(127), - B64(128), B64(129), B64(130), B64(131), - B64(132), B64(133), B64(134), B64(135), - B64(136), B64(137), B64(138), B64(139), - B64(140), B64(141), B64(142), B64(143), - B64(144), B64(145), B64(146), B64(147), - B64(148), B64(149), B64(150), B64(151), - B64(152), B64(153), B64(154), B64(155), - B64(156), B64(157), B64(158), B64(159), - B64(160), B64(161), B64(162), B64(163), - B64(164), B64(165), B64(166), B64(167), - B64(168), B64(169), B64(170), B64(171), - B64(172), B64(173), B64(174), B64(175), - B64(176), B64(177), B64(178), B64(179), - B64(180), B64(181), B64(182), B64(183), - B64(184), B64(185), B64(186), B64(187), - B64(188), B64(189), B64(190), B64(191), - B64(192), B64(193), B64(194), B64(195), - B64(196), B64(197), B64(198), B64(199), - B64(200), B64(201), B64(202), B64(203), - B64(204), B64(205), B64(206), B64(207), - B64(208), B64(209), B64(210), B64(211), - B64(212), B64(213), B64(214), B64(215), - B64(216), B64(217), B64(218), B64(219), - B64(220), B64(221), B64(222), B64(223), - B64(224), B64(225), B64(226), B64(227), - B64(228), B64(229), B64(230), B64(231), - B64(232), B64(233), B64(234), B64(235), - B64(236), B64(237), B64(238), B64(239), - B64(240), B64(241), B64(242), B64(243), - B64(244), B64(245), B64(246), B64(247), - B64(248), B64(249), B64(250), B64(251), - B64(252), B64(253), B64(254), B64(255) -}; - -#if UCHAR_MAX == 255 -# define uchar_in_range(c) true -#else -# define uchar_in_range(c) ((c) <= 255) -#endif - -/* Return true if CH is a character from the Base64 alphabet, and - false otherwise. Note that '=' is padding and not considered to be - part of the alphabet. */ -bool -isbase64(char ch) -{ - return uchar_in_range(to_uchar(ch)) && 0 <= b64[to_uchar(ch)]; -} - -/* Initialize decode-context buffer, CTX. */ -void -base64_decode_ctx_init(struct base64_decode_context *ctx) -{ - ctx->i = 0; -} - -/* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and - none of those four is a newline, then return *IN. Otherwise, copy up to - 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at - index CTX->i and setting CTX->i to reflect the number of bytes copied, - and return CTX->buf. In either case, advance *IN to point to the byte - after the last one processed, and set *N_NON_NEWLINE to the number of - verified non-newline bytes accessible through the returned pointer. */ -static char * -get_4(struct base64_decode_context *ctx, - char const *restrict *in, char const *restrict in_end, - size_t *n_non_newline) -{ - if (ctx->i == 4) { - ctx->i = 0; - } - - if (ctx->i == 0) { - char const *t = *in; - if (4 <= in_end - *in && memchr(t, '\n', 4) == NULL) { - /* This is the common case: no newline. */ - *in += 4; - *n_non_newline = 4; - return (char *)t; - } - } - - { - /* Copy non-newline bytes into BUF. */ - char const *p = *in; - while (p < in_end) { - char c = *p++; - if (c != '\n') { - ctx->buf[ctx->i++] = c; - if (ctx->i == 4) { - break; - } - } - } - - *in = p; - *n_non_newline = ctx->i; - return ctx->buf; - } -} - -#define return_false \ - do \ - { \ - *outp = out; \ - return false; \ - } \ - while (false) - -/* Decode up to four bytes of base64-encoded data, IN, of length INLEN - into the output buffer, *OUT, of size *OUTLEN bytes. Return true if - decoding is successful, false otherwise. If *OUTLEN is too small, - as many bytes as possible are written to *OUT. On return, advance - *OUT to point to the byte after the last one written, and decrement - *OUTLEN to reflect the number of bytes remaining in *OUT. */ -static bool -decode_4(char const *restrict in, size_t inlen, - char *restrict *outp, size_t *outleft) -{ - char *out = *outp; - if (inlen < 2) { - return false; - } - - if (!isbase64(in[0]) || !isbase64(in[1])) { - return false; - } - - if (*outleft) { - *out++ = ((b64[to_uchar(in[0])] << 2) - | (b64[to_uchar(in[1])] >> 4)); - --*outleft; - } - - if (inlen == 2) { - return_false; - } - - if (in[2] == '=') { - if (inlen != 4) { - return_false; - } - - if (in[3] != '=') { - return_false; - } - }else { - if (!isbase64(in[2])) { - return_false; - } - - if (*outleft) { - *out++ = (((b64[to_uchar(in[1])] << 4) & 0xf0) - | (b64[to_uchar(in[2])] >> 2)); - --*outleft; - } - - if (inlen == 3) { - return_false; - } - - if (in[3] == '=') { - if (inlen != 4) { - return_false; - } - }else { - if (!isbase64(in[3])) { - return_false; - } - - if (*outleft) { - *out++ = (((b64[to_uchar(in[2])] << 6) & 0xc0) - | b64[to_uchar(in[3])]); - --*outleft; - } - } - } - - *outp = out; - return true; -} - -/* Decode base64-encoded input array IN of length INLEN to output array - OUT that can hold *OUTLEN bytes. The input data may be interspersed - with newlines. Return true if decoding was successful, i.e. if the - input was valid base64 data, false otherwise. If *OUTLEN is too - small, as many bytes as possible will be written to OUT. On return, - *OUTLEN holds the length of decoded bytes in OUT. Note that as soon - as any non-alphabet, non-newline character is encountered, decoding - is stopped and false is returned. If INLEN is zero, then process - only whatever data is stored in CTX. - - Initially, CTX must have been initialized via base64_decode_ctx_init. - Subsequent calls to this function must reuse whatever state is recorded - in that buffer. It is necessary for when a quadruple of base64 input - bytes spans two input buffers. - - If CTX is NULL then newlines are treated as garbage and the input - buffer is processed as a unit. */ - -bool -base64_decode_ctx(struct base64_decode_context *ctx, - const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen) -{ - size_t outleft = *outlen; - bool ignore_newlines = ctx != NULL; - bool flush_ctx = false; - unsigned int ctx_i = 0; - - if (ignore_newlines) { - ctx_i = ctx->i; - flush_ctx = inlen == 0; - } - - - while (true) { - size_t outleft_save = outleft; - if (ctx_i == 0 && !flush_ctx) { - while (true) { - /* Save a copy of outleft, in case we need to re-parse this - block of four bytes. */ - outleft_save = outleft; - if (!decode_4(in, inlen, &out, &outleft)) { - break; - } - - in += 4; - inlen -= 4; - } - } - - if (inlen == 0 && !flush_ctx) { - break; - } - - /* Handle the common case of 72-byte wrapped lines. - This also handles any other multiple-of-4-byte wrapping. */ - if (inlen && *in == '\n' && ignore_newlines) { - ++in; - --inlen; - continue; - } - - /* Restore OUT and OUTLEFT. */ - out -= outleft_save - outleft; - outleft = outleft_save; - - { - char const *in_end = in + inlen; - char const *non_nl; - - if (ignore_newlines) { - non_nl = get_4(ctx, &in, in_end, &inlen); - } else{ - non_nl = in; /* Might have nl in this case. */ - - } - /* If the input is empty or consists solely of newlines (0 non-newlines), - then we're done. Likewise if there are fewer than 4 bytes when not - flushing context and not treating newlines as garbage. */ - if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines)) { - inlen = 0; - break; - } - if (!decode_4(non_nl, inlen, &out, &outleft)) { - break; - } - - inlen = in_end - in; - } - } - - *outlen -= outleft; - - return inlen == 0; -} - -/* Allocate an output buffer in *OUT, and decode the base64 encoded - data stored in IN of size INLEN to the *OUT buffer. On return, the - size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL, - if the caller is not interested in the decoded length. *OUT may be - NULL to indicate an out of memory error, in which case *OUTLEN - contains the size of the memory block needed. The function returns - true on successful decoding and memory allocation errors. (Use the - *OUT and *OUTLEN parameters to differentiate between successful - decoding and memory error.) The function returns false if the - input was invalid, in which case *OUT is NULL and *OUTLEN is - undefined. */ -bool -base64_decode_alloc_ctx(struct base64_decode_context *ctx, - const char *in, size_t inlen, char **out, - size_t *outlen) -{ - /* This may allocate a few bytes too many, depending on input, - but it's not worth the extra CPU time to compute the exact size. - The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the - input ends with "=" and minus another 1 if the input ends with "==". - Dividing before multiplying avoids the possibility of overflow. */ - size_t needlen = 3 * (inlen / 4) + 3; - - *out = malloc(needlen); - if (!*out) { - return true; - } - - if (!base64_decode_ctx(ctx, in, inlen, *out, &needlen)) { - free(*out); - *out = NULL; - return false; - } - - if (outlen) { - *outlen = needlen; - } - - return true; -} diff -Nru geoipupdate-2.4.0/bin/base64.h geoipupdate-2.5.0/bin/base64.h --- geoipupdate-2.4.0/bin/base64.h 2016-01-21 18:40:11.000000000 +0000 +++ geoipupdate-2.5.0/bin/base64.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -/* base64.h -- Encode binary data using printable characters. - Copyright (C) 2004-2006, 2009-2012 Free Software Foundation, Inc. - Written by Simon Josefsson. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef BASE64_H -# define BASE64_H - -/* Get size_t. */ -# include - -/* Get bool. */ -# include - -# ifdef __cplusplus -extern "C" { -# endif - -/* This uses that the expression (n+(k-1))/k means the smallest - integer >= n/k, i.e., the ceiling of n/k. */ -# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4) - -struct base64_decode_context { - unsigned int i; - char buf[4]; -}; - -extern bool isbase64(char ch); - -extern void base64_encode(const char *restrict in, size_t inlen, - char *restrict out, size_t outlen); - -extern size_t base64_encode_alloc(const char *in, size_t inlen, char **out); - -extern void base64_decode_ctx_init(struct base64_decode_context *ctx); - -extern bool base64_decode_ctx(struct base64_decode_context *ctx, - const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen); - -extern bool base64_decode_alloc_ctx(struct base64_decode_context *ctx, - const char *in, size_t inlen, - char **out, size_t *outlen); - -#define base64_decode(in, inlen, out, outlen) \ - base64_decode_ctx(NULL, in, inlen, out, outlen) - -#define base64_decode_alloc(in, inlen, out, outlen) \ - base64_decode_alloc_ctx(NULL, in, inlen, out, outlen) - -# ifdef __cplusplus -} -# endif - -#endif /* BASE64_H */ diff -Nru geoipupdate-2.4.0/bin/edition_s.c geoipupdate-2.5.0/bin/edition_s.c --- geoipupdate-2.4.0/bin/edition_s.c 1970-01-01 00:00:00.000000000 +0000 +++ geoipupdate-2.5.0/bin/edition_s.c 2017-10-30 14:38:24.000000000 +0000 @@ -0,0 +1,48 @@ + +#include "geoipupdate.h" +#include +#include + +int edition_count(geoipupdate_s *gu) { + int cnt = 0; + for (edition_s *p = gu->license.first; p; p = p->next) { + cnt++; + } + return cnt; +} + +void edition_delete_all(geoipupdate_s *gu) { + edition_s *next, *current; + + for (next = gu->license.first; (current = next);) { + next = current->next; + edition_delete(current); + } +} + +void edition_insert_once(geoipupdate_s *gu, const char *edition_id) { + edition_s **next = &gu->license.first; + for (; *next; next = &(*next)->next) { + if (strcmp((*next)->edition_id, edition_id) == 0) { + return; + } + } + *next = edition_new(edition_id); + say_if(gu->verbose, "Insert edition_id %s\n", edition_id); +} + +edition_s *edition_new(const char *edition_id) { + edition_s *p = xmalloc(sizeof(edition_s)); + p->edition_id = strdup(edition_id); + exit_if(NULL == p->edition_id, + "Unable to allocate memory for edition ID.\n"); + p->next = NULL; + return p; +} + +void edition_delete(edition_s *p) { + if (p) { + free(p->edition_id); + } + free(p); +} diff -Nru geoipupdate-2.4.0/bin/functions.c geoipupdate-2.5.0/bin/functions.c --- geoipupdate-2.4.0/bin/functions.c 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/bin/functions.c 2017-10-30 14:38:24.000000000 +0000 @@ -9,20 +9,38 @@ #include #include #include -#include #include +#include #include -static ssize_t read_file(char const * const, void * const, - size_t const); +static ssize_t read_file(char const *const, void *const, size_t const); + +// Return the length of the given string in bytes. Look at at most maxlen +// bytes. +// +// This is intended to behave like strnlen(3). We don't use strnlen(3) as it is +// not part of C99. +size_t gu_strnlen(char const *const s, size_t const maxlen) { + if (!s) { + return 0; + } + + char const *ptr = s; + size_t n = 0; + while (*ptr != '\0' && n < maxlen) { + n++; + ptr++; + } + + return n; +} // Check whether the file looks like a valid gzip file. // // We open it and read in a small amount. We do this so we can check its header. // // Return true if it is. -bool is_valid_gzip_file(char const * const file) -{ +bool is_valid_gzip_file(char const *const file) { if (file == NULL || strlen(file) == 0) { fprintf(stderr, "is_valid_gzip_file: %s\n", strerror(EINVAL)); return false; @@ -30,7 +48,7 @@ size_t const bufsz = 2; - uint8_t * const buf = calloc(bufsz, sizeof(uint8_t)); + uint8_t *const buf = calloc(bufsz, sizeof(uint8_t)); if (buf == NULL) { fprintf(stderr, "is_valid_gzip_file: %s\n", strerror(errno)); return false; @@ -44,8 +62,8 @@ } if ((size_t const)sz != bufsz) { - fprintf(stderr, "%s is not a valid gzip file (due to file size)\n", - file); + fprintf( + stderr, "%s is not a valid gzip file (due to file size)\n", file); free(buf); return false; } @@ -72,8 +90,7 @@ // exactly 8 KiB. The useful portion may fall short of 8 KiB. // // The caller is responsible for the returned memory. -char * slurp_file(char const * const file) -{ +char *slurp_file(char const *const file) { if (file == NULL || strlen(file) == 0) { fprintf(stderr, "slurp_file: %s\n", strerror(EINVAL)); return NULL; @@ -81,7 +98,7 @@ size_t sz = 8193; - char * const buf = calloc(sz, sizeof(char)); + char *const buf = calloc(sz, sizeof(char)); if (buf == NULL) { fprintf(stderr, "slurp_file: %s\n", strerror(errno)); return NULL; @@ -102,9 +119,8 @@ // Return how many bytes we read. -1 if there was an error. // // The buffer may or may not contain a string. It may be binary data. -static ssize_t read_file(char const * const file, void * const buf, - size_t const bufsz) -{ +static ssize_t +read_file(char const *const file, void *const buf, size_t const bufsz) { if (file == NULL || strlen(file) == 0 || buf == NULL || bufsz == 0) { fprintf(stderr, "read_file: %s\n", strerror(EINVAL)); return -1; @@ -117,8 +133,10 @@ int const fd = open(file, O_RDONLY); if (fd == -1) { - fprintf(stderr, "read_file: Can't open file: %s: %s\n", - file, strerror(errno)); + fprintf(stderr, + "read_file: Can't open file: %s: %s\n", + file, + strerror(errno)); return -1; } @@ -140,14 +158,16 @@ return -1; } - ssize_t const read_bytes = read(fd, buf + total_read_bytes, - bytes_left_to_read); + ssize_t const read_bytes = + read(fd, buf + total_read_bytes, bytes_left_to_read); if (read_bytes < 0) { if (errno == EINTR) { retries_remaining--; continue; } - fprintf(stderr, "read_file: Error reading from %s: %s\n", file, + fprintf(stderr, + "read_file: Error reading from %s: %s\n", + file, strerror(errno)); close(fd); return -1; @@ -169,8 +189,10 @@ } if (close(fd) != 0) { - fprintf(stderr, "read_file: Error closing file: %s: %s\n", - file, strerror(errno)); + fprintf(stderr, + "read_file: Error closing file: %s: %s\n", + file, + strerror(errno)); return -1; } @@ -181,15 +203,15 @@ #include +static void test_gu_strnlen(void); static void test_is_valid_gzip_file(void); static void test_slurp_file(void); static void test_read_file(void); -static char * get_temporary_filename(void); -static void write_file(char const * const, void const * const, - size_t const); +static char *get_temporary_filename(void); +static void write_file(char const *const, void const *const, size_t const); -int main(void) -{ +int main(void) { + test_gu_strnlen(); test_is_valid_gzip_file(); test_slurp_file(); test_read_file(); @@ -197,13 +219,68 @@ return 0; } -static void test_is_valid_gzip_file(void) -{ - char * const filename = get_temporary_filename(); +static void test_gu_strnlen(void) { + struct test_case { + char const *const s; + size_t const maxlen; + size_t const output; + bool const skip_strnlen; + }; + + struct test_case const tests[] = { + { + .s = "test", .maxlen = 4, .output = 4, .skip_strnlen = false, + }, + { + .s = "test", .maxlen = 5, .output = 4, .skip_strnlen = false, + }, + { + .s = "test", .maxlen = 6, .output = 4, .skip_strnlen = false, + }, + { + .s = "test", .maxlen = 14, .output = 4, .skip_strnlen = false, + }, + { + .s = "test", .maxlen = 2, .output = 2, .skip_strnlen = false, + }, + { + .s = "test", .maxlen = 0, .output = 0, .skip_strnlen = false, + }, + { + .s = "", .maxlen = 4, .output = 0, .skip_strnlen = false, + }, + { + .s = "", .maxlen = 0, .output = 0, .skip_strnlen = false, + }, + { + .s = NULL, .maxlen = 0, .output = 0, .skip_strnlen = false, + }, + { + .s = NULL, + .maxlen = 10, + .output = 0, + // segfaults strnlen + .skip_strnlen = true, + }, + }; + + for (size_t i = 0; i < sizeof tests / sizeof tests[0]; i++) { + struct test_case const test = tests[i]; + size_t const output = gu_strnlen(test.s, test.maxlen); + assert(output == test.output); + if (test.skip_strnlen) { + continue; + } + assert(output == strnlen(test.s, test.maxlen)); + } +} + +static void test_is_valid_gzip_file(void) { + char *const filename = get_temporary_filename(); assert(filename != NULL); // A buffer to work with. - uint8_t buf[4] = { 0 }; + uint8_t buf[4] = {0}; // Test: File does not exist. @@ -256,20 +333,19 @@ free(filename); } -static void test_slurp_file(void) -{ - char * const filename = get_temporary_filename(); +static void test_slurp_file(void) { + char *const filename = get_temporary_filename(); assert(filename != NULL); // Test: File does not exist. - char * const contents_0 = slurp_file(filename); + char *const contents_0 = slurp_file(filename); assert(contents_0 == NULL); // Test: File is zero size. write_file(filename, "", 0); - char * const contents_1 = slurp_file(filename); + char *const contents_1 = slurp_file(filename); assert(contents_1 != NULL); assert(strlen(contents_1) == 0); free(contents_1); @@ -277,22 +353,22 @@ // Test: File has a short string. write_file(filename, "hello", strlen("hello")); - char * const contents_2 = slurp_file(filename); + char *const contents_2 = slurp_file(filename); assert(contents_2 != NULL); assert(strcmp(contents_2, "hello") == 0); free(contents_2); // Test: File is oversize. - char contents[8194] = { 0 }; + char contents[8194] = {0}; memset(contents, 'a', 8193); write_file(filename, contents, strlen(contents)); - char expected[8193] = { 0 }; + char expected[8193] = {0}; memset(expected, 'a', 8192); - char * const contents_3 = slurp_file(filename); + char *const contents_3 = slurp_file(filename); assert(contents_3 != NULL); assert(strcmp(contents_3, expected) == 0); free(contents_3); @@ -302,14 +378,13 @@ free(filename); } -static void test_read_file(void) -{ - char * const filename = get_temporary_filename(); +static void test_read_file(void) { + char *const filename = get_temporary_filename(); assert(filename != NULL); // Make a buffer to work with. size_t const bufsz = 32; - char * const buf = calloc(bufsz, sizeof(char)); + char *const buf = calloc(bufsz, sizeof(char)); assert(buf != NULL); // Test: The file does not exist. @@ -357,11 +432,10 @@ free(buf); } -static char * get_temporary_filename(void) -{ +static char *get_temporary_filename(void) { size_t const sz = 64; - char * const filename = calloc(sz, sizeof(char)); + char *const filename = calloc(sz, sizeof(char)); assert(filename != NULL); strcat(filename, "/tmp/test-file-XXXXXX"); @@ -374,9 +448,9 @@ return filename; } -static void write_file(char const * const path, void const * const contents, - size_t const sz) -{ +static void write_file(char const *const path, + void const *const contents, + size_t const sz) { assert(path != NULL); assert(strlen(path) != 0); assert(contents != NULL); diff -Nru geoipupdate-2.4.0/bin/functions.h geoipupdate-2.5.0/bin/functions.h --- geoipupdate-2.4.0/bin/functions.h 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/bin/functions.h 2017-10-30 14:38:24.000000000 +0000 @@ -2,8 +2,10 @@ #define _GEOIPUPDATE_FUNCTIONS_H #include +#include -bool is_valid_gzip_file(char const * const); -char * slurp_file(char const * const); +size_t gu_strnlen(char const *const, size_t const); +bool is_valid_gzip_file(char const *const); +char *slurp_file(char const *const); #endif diff -Nru geoipupdate-2.4.0/bin/geoipupdate.c geoipupdate-2.5.0/bin/geoipupdate.c --- geoipupdate-2.4.0/bin/geoipupdate.c 2017-05-25 19:56:31.000000000 +0000 +++ geoipupdate-2.5.0/bin/geoipupdate.c 2017-10-30 14:38:24.000000000 +0000 @@ -1,5 +1,5 @@ -#include "functions.h" #include "geoipupdate.h" +#include "functions.h" #include "md5.h" #include @@ -13,10 +13,11 @@ #include #include #include +#include #include #define ZERO_MD5 ("00000000000000000000000000000000") -#define say(fmt, ...) say_if(1, fmt, ## __VA_ARGS__) +#define say(fmt, ...) say_if(1, fmt, ##__VA_ARGS__) enum gu_status { GU_OK = 0, @@ -32,32 +33,32 @@ static void *xcalloc(size_t, size_t); static void *xrealloc(void *, size_t); static void usage(void); -static int parse_opts(geoipupdate_s *, int, char *const []); +static int parse_opts(geoipupdate_s *, int, char *const[]); static ssize_t my_getline(char **, size_t *, FILE *); static int parse_license_file(geoipupdate_s *); -static char * join_path(char const * const, char const * const); -static int acquire_run_lock(geoipupdate_s const * const); +static char *join_path(char const *const, char const *const); +static int acquire_run_lock(geoipupdate_s const *const); static int md5hex(const char *, char *); static void common_req(CURL *, geoipupdate_s *); -static size_t get_expected_file_md5(char *, size_t, size_t, - char *); -static void download_to_file(geoipupdate_s *, const char *, - const char *, char *); +static size_t get_expected_file_md5(char *, size_t, size_t, void *); +static void +download_to_file(geoipupdate_s *, const char *, const char *, char *); +static long get_server_time(geoipupdate_s *); static size_t mem_cb(void *, size_t, size_t, void *); static in_mem_s *in_mem_s_new(void); static void in_mem_s_delete(in_mem_s *); static in_mem_s *get(geoipupdate_s *, const char *); -static void md5hex_license_ipaddr(geoipupdate_s *, const char *, - char *); +static void md5hex_license_ipaddr(geoipupdate_s *, const char *, char *); static int update_database_general_all(geoipupdate_s *); static int update_database_general(geoipupdate_s *, const char *); static int update_country_database(geoipupdate_s *); -static int gunzip_and_replace(geoipupdate_s const * const, - char const * const, char const * const, - char const * const); +static int gunzip_and_replace(geoipupdate_s const *const, + char const *const, + char const *const, + char const *const, + long); -void exit_unless(int expr, const char *fmt, ...) -{ +void exit_unless(int expr, const char *fmt, ...) { va_list ap; if (expr) { return; @@ -68,8 +69,7 @@ exit(1); } -static void xasprintf(char **ptr, const char *fmt, ...) -{ +static void xasprintf(char **ptr, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int rc = vasprintf(ptr, fmt, ap); @@ -77,8 +77,7 @@ exit_if(rc == -1, "Out of memory\n"); } -void say_if(int expr, const char *fmt, ...) -{ +void say_if(int expr, const char *fmt, ...) { va_list ap; if (!expr) { return; @@ -88,89 +87,87 @@ va_end(ap); } -static void *xcalloc(size_t nmemb, size_t size) -{ +static void *xcalloc(size_t nmemb, size_t size) { void *ptr = calloc(nmemb, size); exit_if(!ptr, "Out of memory\n"); return ptr; } -void *xmalloc(size_t size) -{ +void *xmalloc(size_t size) { void *ptr = malloc(size); exit_if(!ptr, "Out of memory\n"); return ptr; } -static void *xrealloc(void *ptr, size_t size) -{ +static void *xrealloc(void *ptr, size_t size) { void *mem = realloc(ptr, size); exit_if(mem == NULL, "Out of memory\n"); return mem; } -static void usage(void) -{ +static void usage(void) { fprintf( stderr, "Usage: geoipupdate [-Vhv] [-f license_file] [-d custom directory]\n\n" " -d DIR store downloaded files in DIR\n" - " -f FILE use configuration found in FILE (see GeoIP.conf(5) man page)\n" + " -f FILE use configuration found in FILE (see GeoIP.conf(5) man " + "page)\n" " -h display this help text\n" " -v use verbose output\n" - " -V display the version and exit\n" - ); + " -V display the version and exit\n"); } -static int parse_opts(geoipupdate_s * gu, int argc, char *const argv[]) -{ +static int parse_opts(geoipupdate_s *gu, int argc, char *const argv[]) { int c; opterr = 0; while ((c = getopt(argc, argv, "Vvhf:d:")) != -1) { switch (c) { - case 'V': - puts(PACKAGE_STRING); - exit(0); - case 'v': - gu->verbose = 1; - break; - case 'd': - free(gu->database_dir); - gu->database_dir = strdup(optarg); - exit_if(NULL == gu->database_dir, + case 'V': + puts(PACKAGE_STRING); + exit(0); + case 'v': + gu->verbose = 1; + break; + case 'd': + free(gu->database_dir); + gu->database_dir = strdup(optarg); + exit_if( + NULL == gu->database_dir, "Unable to allocate memory for database directory path."); - // The database directory in the config file is ignored if we use -d - gu->do_not_overwrite_database_directory = 1; - break; - case 'f': - free(gu->license_file); - gu->license_file = strdup(optarg); - exit_if(NULL == gu->license_file, - "Unable to allocate memory for license file path.\n"); - break; - case 'h': - default: - usage(); - exit(1); - case '?': - if (optopt == 'f' || optopt == 'd') { - fprintf(stderr, "Option -%c requires an argument.\n", optopt); - } else if (isprint(optopt)) { - fprintf(stderr, "Unknown option `-%c'.\n", optopt); - } else{ - fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); - } - exit(1); + // The database directory in the config file is ignored if we + // use -d + gu->do_not_overwrite_database_directory = 1; + break; + case 'f': + free(gu->license_file); + gu->license_file = strdup(optarg); + exit_if(NULL == gu->license_file, + "Unable to allocate memory for license file path.\n"); + break; + case 'h': + default: + usage(); + exit(1); + case '?': + if (optopt == 'f' || optopt == 'd') { + fprintf( + stderr, "Option -%c requires an argument.\n", optopt); + } else if (isprint(optopt)) { + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + } else { + fprintf( + stderr, "Unknown option character `\\x%x'.\n", optopt); + } + exit(1); } } return GU_OK; } -int main(int argc, char *const argv[]) -{ +int main(int argc, char *const argv[]) { struct stat st; int err = GU_ERROR; curl_global_init(CURL_GLOBAL_DEFAULT); @@ -179,8 +176,10 @@ parse_opts(gu, argc, argv); if (parse_license_file(gu)) { exit_unless(stat(gu->database_dir, &st) == 0, - "%s does not exist\n", gu->database_dir); - exit_unless(S_ISDIR(st.st_mode), "%s is not a directory\n", + "%s does not exist\n", + gu->database_dir); + exit_unless(S_ISDIR(st.st_mode), + "%s is not a directory\n", gu->database_dir); // Note: access(2) checks only the real UID/GID. This is probably // okay, but we could perform more complex checks using the stat @@ -188,7 +187,8 @@ // open the file, and avoid potential race issues where permissions // change between now and then. exit_unless(access(gu->database_dir, W_OK) == 0, - "%s is not writable\n", gu->database_dir); + "%s is not writable\n", + gu->database_dir); if (acquire_run_lock(gu) != 0) { geoipupdate_s_delete(gu); @@ -196,9 +196,9 @@ return GU_ERROR; } - err = (gu->license.user_id == NO_USER_ID) - ? update_country_database(gu) - : update_database_general_all(gu); + err = (gu->license.account_id == NO_ACCOUNT_ID) + ? update_country_database(gu) + : update_database_general_all(gu); } geoipupdate_s_delete(gu); } @@ -206,21 +206,19 @@ return err ? GU_ERROR : GU_OK; } -static ssize_t my_getline(char ** linep, size_t * linecapp, FILE * stream) -{ +static ssize_t my_getline(char **linep, size_t *linecapp, FILE *stream) { #if defined HAVE_GETLINE return getline(linep, linecapp, stream); #elif defined HAVE_FGETS // Unbelievable, but OS X 10.6 Snow Leopard did not provide getline - char * p = fgets(*linep, *linecapp, stream); + char *p = fgets(*linep, *linecapp, stream); return p == NULL ? -1 : strlen(p); #else #error Your OS is not supported #endif } -static int parse_license_file(geoipupdate_s * up) -{ +static int parse_license_file(geoipupdate_s *up) { say_if(up->verbose, "%s\n", PACKAGE_STRING); FILE *fh = fopen(up->license_file, "rb"); exit_unless(!!fh, "Can't open license file %s\n", up->license_file); @@ -236,32 +234,41 @@ if (*strt == '#') { continue; } - if (sscanf(strt, "UserId %d", &up->license.user_id) == 1) { - say_if(up->verbose, "UserId %d\n", up->license.user_id); + if (sscanf(strt, "UserId %d", &up->license.account_id) == 1) { + say_if(up->verbose, "UserId %d\n", up->license.account_id); continue; } - if (sscanf(strt, "LicenseKey %12s", - &up->license.license_key[0]) == 1) { + if (sscanf(strt, "AccountID %d", &up->license.account_id) == 1) { + say_if(up->verbose, "AccountID %d\n", up->license.account_id); + continue; + } + if (sscanf(strt, "LicenseKey %12s", &up->license.license_key[0]) == 1) { say_if(up->verbose, "LicenseKey %s\n", up->license.license_key); continue; } char *p, *last; if ((p = strtok_r(strt, sep, &last))) { - if (!strcmp(p, "ProductIds")) { + if (!strcmp(p, "ProductIds") || !strcmp(p, "EditionIDs")) { while ((p = strtok_r(NULL, sep, &last))) { - product_insert_once(up, p); + edition_insert_once(up, p); } + } else if (!strcmp(p, "PreserveFileTimes")) { + p = strtok_r(NULL, sep, &last); + exit_if(NULL == p || + (0 != strcmp(p, "0") && 0 != strcmp(p, "1")), + "PreserveFileTimes must be 0 or 1\n"); + up->preserve_file_times = atoi(p); } else if (!strcmp(p, "SkipPeerVerification")) { p = strtok_r(NULL, sep, &last); - exit_if(NULL == p - || (0 != strcmp(p, "0") && 0 != strcmp(p, "1")), + exit_if(NULL == p || + (0 != strcmp(p, "0") && 0 != strcmp(p, "1")), "SkipPeerVerification must be 0 or 1\n"); up->skip_peer_verification = atoi(p); } else if (!strcmp(p, "Protocol")) { p = strtok_r(NULL, sep, &last); - exit_if(NULL == p || (0 != strcmp(p, "http") - && 0 != strcmp(p, "https")), + exit_if(NULL == p || + (0 != strcmp(p, "http") && 0 != strcmp(p, "https")), "Protocol must be http or https\n"); free(up->proto); up->proto = strdup(p); @@ -270,7 +277,7 @@ } else if (!strcmp(p, "SkipHostnameVerification")) { p = strtok_r(NULL, sep, &last); exit_if(NULL == p || - (0 != strcmp(p, "0") && 0 != strcmp(p, "1")), + (0 != strcmp(p, "0") && 0 != strcmp(p, "1")), "SkipHostnameVerification must be 0 or 1\n"); up->skip_hostname_verification = atoi(p); } else if (!strcmp(p, "Host")) { @@ -283,18 +290,16 @@ } else if (!strcmp(p, "DatabaseDirectory")) { if (!up->do_not_overwrite_database_directory) { p = strtok_r(NULL, sep, &last); - exit_if(NULL == p, - "DatabaseDirectory must be defined\n"); + exit_if(NULL == p, "DatabaseDirectory must be defined\n"); free(up->database_dir); up->database_dir = strdup(p); - exit_if( - NULL == up->database_dir, - "Unable to allocate memory for database directory path.\n"); + exit_if(NULL == up->database_dir, + "Unable to allocate memory for database directory " + "path.\n"); } } else if (!strcmp(p, "Proxy")) { p = strtok_r(NULL, sep, &last); - exit_if(NULL == p, - "Proxy must be defined 1.2.3.4:12345\n"); + exit_if(NULL == p, "Proxy must be defined 1.2.3.4:12345\n"); free(up->proxy); up->proxy = strdup(p); exit_if(NULL == up->proxy, @@ -309,8 +314,7 @@ "Unable to allocate memory for proxy credentials.\n"); } else if (!strcmp(p, "LockFile")) { p = strtok_r(NULL, sep, &last); - exit_if(NULL == p, - "LockFile must be a file path\n"); + exit_if(NULL == p, "LockFile must be a file path\n"); // We could check the value looks like a path, but trying to use // it will fail if it isn't. free(up->lock_file); @@ -335,8 +339,9 @@ free(buffer); exit_if(-1 == fclose(fh), "Error closing stream: %s", strerror(errno)); say_if(up->verbose, - "Read in license key %s\nNumber of product ids %d\n", - up->license_file, product_count(up)); + "Read in license key %s\nNumber of edition IDs %d\n", + up->license_file, + edition_count(up)); return 1; } @@ -347,10 +352,9 @@ // // TODO: This function performs no validation on the given inputs beyond that // they are present. -static char * join_path(char const * const dir, char const * const file) -{ +static char *join_path(char const *const dir, char const *const file) { size_t sz = -1; - char * path = NULL; + char *path = NULL; if (dir == NULL || strlen(dir) == 0 || file == NULL || strlen(file) == 0) { fprintf(stderr, "join_path: %s\n", strerror(EINVAL)); @@ -393,8 +397,7 @@ // file (releasing our lock), then that other instance acquires a lock. At the // same time, another instance runs and creates the file anew and also acquires // a lock. -static int acquire_run_lock(geoipupdate_s const * const gu) -{ +static int acquire_run_lock(geoipupdate_s const *const gu) { int fd = -1; struct flock fl; int i = 0; @@ -408,7 +411,9 @@ fd = open(gu->lock_file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { - fprintf(stderr, "Unable to open lock file %s: %s\n", gu->lock_file, + fprintf(stderr, + "Unable to open lock file %s: %s\n", + gu->lock_file, strerror(errno)); return 1; } @@ -428,20 +433,23 @@ } // Something else went wrong. Abort. - fprintf(stderr, "Unable to acquire lock on %s: %s\n", gu->lock_file, + fprintf(stderr, + "Unable to acquire lock on %s: %s\n", + gu->lock_file, strerror(errno)); close(fd); return 1; } - fprintf(stderr, "Unable to acquire lock on %s: Gave up after %d attempts\n", - gu->lock_file, i); + fprintf(stderr, + "Unable to acquire lock on %s: Gave up after %d attempts\n", + gu->lock_file, + i); close(fd); return 1; } -static int md5hex(const char *fname, char *hex_digest) -{ +static int md5hex(const char *fname, char *hex_digest) { int bsize = 1024; unsigned char buffer[bsize], digest[16]; @@ -455,8 +463,9 @@ } struct stat st; - exit_unless(stat(fname, &st) == 0 - && S_ISREG(st.st_mode), "%s is not a file\n", fname); + exit_unless(stat(fname, &st) == 0 && S_ISREG(st.st_mode), + "%s is not a file\n", + fname); md5_init(&context); while ((len = fread(buffer, 1, bsize, fh)) > 0) { @@ -471,26 +480,32 @@ return 1; } -static void common_req(CURL * curl, geoipupdate_s * gu) -{ +static void common_req(CURL *curl, geoipupdate_s *gu) { curl_easy_setopt(curl, CURLOPT_USERAGENT, GEOIP_USERAGENT); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - // CURLOPT_TCP_KEEPALIVE appeared in 7.25. It is a typedef enum, not a - // macro so we resort to version detection. +// CURLOPT_TCP_KEEPALIVE appeared in 7.25. It is a typedef enum, not a +// macro so we resort to version detection. #if LIBCURL_VERSION_NUM >= 0x071900 - curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); #endif if (!strcasecmp(gu->proto, "https")) { - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, - gu->skip_peer_verification != 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, - gu->skip_hostname_verification != 0); + curl_easy_setopt(curl, + CURLOPT_SSL_VERIFYPEER, + (long)(gu->skip_peer_verification != 0)); + curl_easy_setopt(curl, + CURLOPT_SSL_VERIFYHOST, + (long)(gu->skip_hostname_verification != 0)); + } + + if (gu->preserve_file_times) { + curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); } if (gu->proxy_user_password && strlen(gu->proxy_user_password)) { - say_if(gu->verbose, "Use proxy_user_password: %s\n", + say_if(gu->verbose, + "Use proxy_user_password: %s\n", gu->proxy_user_password); curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, gu->proxy_user_password); } @@ -500,9 +515,11 @@ } } -static size_t get_expected_file_md5(char *buffer, size_t size, size_t nitems, - char *md5) -{ +static size_t get_expected_file_md5(char *buffer, + size_t size, + size_t nitems, + void *userdata) { + char *md5 = (char *)userdata; size_t total_size = size * nitems; if (strncasecmp(buffer, "X-Database-MD5:", 15) == 0 && total_size > 48) { char *start = buffer + 16; @@ -522,9 +539,10 @@ // TODO(wstorey@maxmind.com): Return boolean/int whether we succeeded rather // than exiting. Beyond being cleaner and easier to test, it will allow us to // clean up after ourselves better. -static void download_to_file(geoipupdate_s * gu, const char *url, - const char *fname, char *expected_file_md5) -{ +static void download_to_file(geoipupdate_s *gu, + const char *url, + const char *fname, + char *expected_file_md5) { FILE *f = fopen(fname, "wb"); if (f == NULL) { fprintf(stderr, "Can't open %s: %s\n", fname, strerror(errno)); @@ -547,7 +565,8 @@ exit_unless(res == CURLE_OK, "curl_easy_perform() failed: %s\nConnect to %s\n", - curl_easy_strerror(res), url); + curl_easy_strerror(res), + url); long status = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); @@ -564,7 +583,7 @@ status, url); // The response should contain a message containing exactly why. - char * const message = slurp_file(fname); + char *const message = slurp_file(fname); if (message) { fprintf(stderr, "%s\n", message); free(message); @@ -577,7 +596,7 @@ // In this case, the server must have told us the current MD5 hash of the // database we asked for. - if (strnlen(expected_file_md5, 33) != 32) { + if (gu_strnlen(expected_file_md5, 33) != 32) { fprintf(stderr, "Did not receive a valid expected database MD5 from server\n"); unlink(fname); @@ -585,8 +604,17 @@ } } -static size_t mem_cb(void *contents, size_t size, size_t nmemb, void *userp) -{ +// Retrieve the server file time for the previous HTTP request. +static long get_server_time(geoipupdate_s *gu) { + CURL *curl = gu->curl; + long filetime = -1; + if (curl != NULL) { + curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); + } + return filetime; +} + +static size_t mem_cb(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; if (realsize == 0) { @@ -603,24 +631,21 @@ return realsize; } -static in_mem_s *in_mem_s_new(void) -{ +static in_mem_s *in_mem_s_new(void) { in_mem_s *mem = (in_mem_s *)xmalloc(sizeof(in_mem_s)); mem->ptr = (char *)xcalloc(1, 1); mem->size = 0; return mem; } -static void in_mem_s_delete(in_mem_s * mem) -{ +static void in_mem_s_delete(in_mem_s *mem) { if (mem) { free(mem->ptr); free(mem); } } -static in_mem_s *get(geoipupdate_s * gu, const char *url) -{ +static in_mem_s *get(geoipupdate_s *gu, const char *url) { in_mem_s *mem = in_mem_s_new(); say_if(gu->verbose, "url: %s\n", url); @@ -632,14 +657,16 @@ CURLcode res = curl_easy_perform(curl); exit_unless(res == CURLE_OK, "curl_easy_perform() failed: %s\nConnect to %s\n", - curl_easy_strerror(res), url); + curl_easy_strerror(res), + url); long status = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); - exit_if( status < 200 || status >= 300, - "Received an unexpected HTTP status code of %ld from %s", - status, url); + exit_if(status < 200 || status >= 300, + "Received an unexpected HTTP status code of %ld from %s", + status, + url); return mem; } @@ -648,13 +675,14 @@ // // This hash is suitable for the challenge parameter for downloading from the // /update_secure endpoint. -static void md5hex_license_ipaddr(geoipupdate_s * gu, const char *client_ipaddr, - char *new_digest_str) -{ +static void md5hex_license_ipaddr(geoipupdate_s *gu, + const char *client_ipaddr, + char *new_digest_str) { unsigned char digest[16]; MD5_CONTEXT context; md5_init(&context); - md5_write(&context, (unsigned char *)gu->license.license_key, + md5_write(&context, + (unsigned char *)gu->license.license_key, strlen(gu->license.license_key)); md5_write(&context, (unsigned char *)client_ipaddr, strlen(client_ipaddr)); md5_final(&context); @@ -664,19 +692,21 @@ } } -static int update_database_general(geoipupdate_s * gu, const char *product_id) -{ +static int update_database_general(geoipupdate_s *gu, const char *edition_id) { char *url = NULL, *geoip_filename = NULL, *geoip_gz_filename = NULL, - *client_ipaddr = NULL; - char hex_digest[33] = { 0 }, hex_digest2[33] = { 0 }; + *client_ipaddr = NULL; + char hex_digest[33] = {0}, hex_digest2[33] = {0}; // Get the filename. - xasprintf(&url, "%s://%s/app/update_getfilename?product_id=%s", - gu->proto, gu->host, product_id); + xasprintf(&url, + "%s://%s/app/update_getfilename?product_id=%s", + gu->proto, + gu->host, + edition_id); in_mem_s *mem = get(gu, url); free(url); if (mem->size == 0) { - fprintf(stderr, "product_id %s not found\n", product_id); + fprintf(stderr, "edition_id %s not found\n", edition_id); in_mem_s_delete(mem); return GU_ERROR; } @@ -712,14 +742,19 @@ say_if(gu->verbose, "md5hex_digest2 (challenge): %s\n", hex_digest2); // Download. - xasprintf( - &url, - "%s://%s/app/update_secure?db_md5=%s&challenge_md5=%s&user_id=%d&edition_id=%s", - gu->proto, gu->host, hex_digest, hex_digest2, - gu->license.user_id, product_id); + xasprintf(&url, + "%s://%s/app/" + "update_secure?db_md5=%s&challenge_md5=%s&user_id=%d&edition_id=%" + "s", + gu->proto, + gu->host, + hex_digest, + hex_digest2, + gu->license.account_id, + edition_id); xasprintf(&geoip_gz_filename, "%s.gz", geoip_filename); - char expected_file_md5[33] = { 0 }; + char expected_file_md5[33] = {0}; download_to_file(gu, url, geoip_gz_filename, expected_file_md5); free(url); @@ -734,8 +769,12 @@ return GU_OK; } - int rc = gunzip_and_replace(gu, geoip_gz_filename, geoip_filename, - expected_file_md5); + long filetime = -1; + if (gu->preserve_file_times) { + filetime = get_server_time(gu); + } + int rc = gunzip_and_replace( + gu, geoip_gz_filename, geoip_filename, expected_file_md5, filetime); free(geoip_gz_filename); free(geoip_filename); @@ -743,20 +782,17 @@ return rc; } -static int update_database_general_all(geoipupdate_s * gu) -{ +static int update_database_general_all(geoipupdate_s *gu) { int err = 0; - for (product_s ** next = &gu->license.first; *next; next = - &(*next)->next) { - err |= update_database_general(gu, (*next)->product_id); + for (edition_s **next = &gu->license.first; *next; next = &(*next)->next) { + err |= update_database_general(gu, (*next)->edition_id); } return err; } -static int update_country_database(geoipupdate_s * gu) -{ +static int update_country_database(geoipupdate_s *gu) { char *geoip_filename = NULL, *geoip_gz_filename = NULL, *url = NULL; - char hex_digest[33] = { 0 }; + char hex_digest[33] = {0}; xasprintf(&geoip_filename, "%s/GeoIP.dat", gu->database_dir); xasprintf(&geoip_gz_filename, "%s/GeoIP.dat.gz", gu->database_dir); @@ -768,9 +804,12 @@ xasprintf(&url, "%s://%s/app/update?license_key=%s&md5=%s", - gu->proto, gu->host, &gu->license.license_key[0], hex_digest); + gu->proto, + gu->host, + &gu->license.license_key[0], + hex_digest); - char expected_file_md5[33] = { 0 }; + char expected_file_md5[33] = {0}; download_to_file(gu, url, geoip_gz_filename, expected_file_md5); free(url); @@ -785,8 +824,12 @@ return GU_OK; } - int rc = gunzip_and_replace(gu, geoip_gz_filename, geoip_filename, - expected_file_md5); + long filetime = -1; + if (gu->preserve_file_times) { + filetime = get_server_time(gu); + } + int rc = gunzip_and_replace( + gu, geoip_gz_filename, geoip_filename, expected_file_md5, filetime); free(geoip_gz_filename); free(geoip_filename); @@ -806,16 +849,16 @@ // // We also remove the gzip file once we successfully decompress and move the // new database into place. -static int gunzip_and_replace(geoipupdate_s const * const gu, - char const * const gzipfile, - char const * const geoip_filename, - char const * const expected_file_md5) -{ - if (gu == NULL || - gu->database_dir == NULL || strlen(gu->database_dir) == 0 || - gzipfile == NULL || strlen(gzipfile) == 0 || - geoip_filename == NULL || strlen(geoip_filename) == 0 || - expected_file_md5 == NULL || strlen(expected_file_md5) == 0) { +static int gunzip_and_replace(geoipupdate_s const *const gu, + char const *const gzipfile, + char const *const geoip_filename, + char const *const expected_file_md5, + long filetime) { + if (gu == NULL || gu->database_dir == NULL || + strlen(gu->database_dir) == 0 || gzipfile == NULL || + strlen(gzipfile) == 0 || geoip_filename == NULL || + strlen(geoip_filename) == 0 || expected_file_md5 == NULL || + strlen(expected_file_md5) == 0) { fprintf(stderr, "gunzip_and_replace: %s\n", strerror(EINVAL)); return GU_ERROR; } @@ -838,7 +881,7 @@ exit_if(fhw == NULL, "Can't open %s\n", file_path_test); size_t const bsize = 8192; - char * const buffer = calloc(bsize, sizeof(char)); + char *const buffer = calloc(bsize, sizeof(char)); if (!buffer) { fprintf(stderr, "gunzip_and_replace: %s\n", strerror(errno)); free(file_path_test); @@ -847,7 +890,7 @@ return GU_ERROR; } - for (;; ) { + for (;;) { int amt = gzread(gz_fh, buffer, bsize); if (amt == 0) { // EOF @@ -858,29 +901,46 @@ "Gzip write error\n"); } exit_if(-1 == fclose(fhw), "Error closing stream: %s", strerror(errno)); - exit_if(gzclose(gz_fh) != Z_OK, "Gzip read error while closing from %s\n", + exit_if(gzclose(gz_fh) != Z_OK, + "Gzip read error while closing from %s\n", gzipfile); free(buffer); - char actual_md5[33] = { 0 }; + char actual_md5[33] = {0}; md5hex(file_path_test, actual_md5); exit_if(strncasecmp(actual_md5, expected_file_md5, 32), "MD5 of new database (%s) does not match expected MD5 (%s)", - actual_md5, expected_file_md5); + actual_md5, + expected_file_md5); say_if(gu->verbose, "Rename %s to %s\n", file_path_test, geoip_filename); int err = rename(file_path_test, geoip_filename); exit_if(err, "Rename %s to %s failed\n", file_path_test, geoip_filename); + if (gu->preserve_file_times && filetime > 0) { + struct utimbuf utb; + utb.modtime = utb.actime = (time_t)filetime; + err = utime(geoip_filename, &utb); + exit_if(err, + "Setting timestamp of %s to %ld failed: %s\n", + geoip_filename, + filetime, + strerror(errno)); + } + // fsync directory to ensure the rename is durable int dirfd = open(gu->database_dir, O_DIRECTORY); - exit_if(-1 == dirfd, "Error opening database directory: %s", - strerror(errno)); - exit_if(-1 == fsync(dirfd), "Error syncing database directory: %s", + exit_if( + -1 == dirfd, "Error opening database directory: %s", strerror(errno)); + exit_if(-1 == fsync(dirfd), + "Error syncing database directory: %s", strerror(errno)); - exit_if(-1 == close(dirfd), "Error closing database directory: %s", + exit_if(-1 == close(dirfd), + "Error closing database directory: %s", strerror(errno)); - exit_if(-1 == unlink(gzipfile), "Error unlinking %s: %s", gzipfile, + exit_if(-1 == unlink(gzipfile), + "Error unlinking %s: %s", + gzipfile, strerror(errno)); free(file_path_test); diff -Nru geoipupdate-2.4.0/bin/geoipupdate.h geoipupdate-2.5.0/bin/geoipupdate.h --- geoipupdate-2.4.0/bin/geoipupdate.h 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/bin/geoipupdate.h 2017-10-30 14:38:24.000000000 +0000 @@ -1,19 +1,19 @@ #ifndef GEOIPUPDATE_H -# define GEOIPUPDATE_H (1) +#define GEOIPUPDATE_H (1) -#include #include +#include -typedef struct product_s { - char *product_id; - struct product_s *next; -} product_s; +typedef struct edition_s { + char *edition_id; + struct edition_s *next; +} edition_s; typedef struct { - int user_id; + int account_id; char license_key[13]; - product_s *first; + edition_s *first; } license_s; typedef struct { @@ -22,35 +22,36 @@ // user might change these before geoipupdate_s_init int skip_peer_verification; int skip_hostname_verification; + int preserve_file_times; int do_not_overwrite_database_directory; - char * license_file; - char * database_dir; - char * host; - char * proto; - char * proxy; // 1.2.3.4, 1.2.3.4:1234 - char * proxy_user_password; // user:pwd - char * lock_file; // Path to a global runtime lock file. + char *license_file; + char *database_dir; + char *host; + char *proto; + char *proxy; // 1.2.3.4, 1.2.3.4:1234 + char *proxy_user_password; // user:pwd + char *lock_file; // Path to a global runtime lock file. int verbose; - CURL * curl; + CURL *curl; } geoipupdate_s; -geoipupdate_s * geoipupdate_s_new(void); -void geoipupdate_s_delete(geoipupdate_s * gu); -void product_delete_all(geoipupdate_s * gu); - -int product_count(geoipupdate_s * gu); -void product_insert_once(geoipupdate_s * gu, const char *product_id); -product_s *product_new(const char *product_id); -void product_delete(product_s * p); +geoipupdate_s *geoipupdate_s_new(void); +void geoipupdate_s_delete(geoipupdate_s *gu); +void edition_delete_all(geoipupdate_s *gu); + +int edition_count(geoipupdate_s *gu); +void edition_insert_once(geoipupdate_s *gu, const char *edition_id); +edition_s *edition_new(const char *edition_id); +void edition_delete(edition_s *p); void exit_unless(int expr, const char *fmt, ...); void say_if(int expr, const char *fmt, ...); void *xmalloc(size_t size); -# define NO_USER_ID (-1) -# define GEOIP_USERAGENT "geoipupdate/" VERSION +#define NO_ACCOUNT_ID (-1) +#define GEOIP_USERAGENT "geoipupdate/" VERSION -#define exit_if(expr, ...) exit_unless(!(expr), ## __VA_ARGS__) +#define exit_if(expr, ...) exit_unless(!(expr), ##__VA_ARGS__) #endif diff -Nru geoipupdate-2.4.0/bin/geoipupdate-pureperl.pl geoipupdate-2.5.0/bin/geoipupdate-pureperl.pl --- geoipupdate-2.4.0/bin/geoipupdate-pureperl.pl 2016-01-21 18:40:11.000000000 +0000 +++ geoipupdate-2.5.0/bin/geoipupdate-pureperl.pl 2017-10-30 14:38:24.000000000 +0000 @@ -86,24 +86,24 @@ or die "Error opening GeoIP Configuration file $opts{f}\n"; print "Opened License file $opts{f}\n" if $opts{v}; -my ( $user_id, $license_key, @product_ids ); +my ( $account_id, $license_key, @edition_ids ); { local $_; while (<$fh>) { next if /^\s*#/; # skip comments - /^\s*UserId\s+(\d+)/ and $user_id = $1, next; + /^\s*(?:AccountID|UserId)\s+(\d+)/ and $account_id = $1, next; /^\s*LicenseKey\s+(\S{12})/ and $license_key = $1, next; - /^\s*ProductIds(?>\s+)([A-Za-z\-_0-9 ]+)/ - and push( @product_ids, split( /\s+/, $1 ) ), next; + /^\s*(?:ProductIds|EditionIDs)(?>\s+)([A-Za-z\-_0-9 ]+)/ + and push( @edition_ids, split( /\s+/, $1 ) ), next; } } if ( $opts{v} ) { - print "User id $user_id\n" if $user_id; + print "Account ID $account_id\n" if $account_id; print "Read in license key $license_key\n"; - print "Product ids @product_ids\n"; + print "Edition IDs @edition_ids\n"; } my $err_cnt = 0; @@ -120,15 +120,15 @@ } }; -if ($user_id) { - for my $product_id (@product_ids) { +if ($account_id) { + for my $edition_id (@edition_ids) { - # update the databases using the user id string, - # the license key string and the product id for each database + # update the databases using the account id string, + # the license key string and the edition id for each database eval { GeoIP_update_database_general( - $user_id, $license_key, - $product_id, $opts{v} + $account_id, $license_key, + $edition_id, $opts{v} ); }; $print_on_error->($@); @@ -145,9 +145,9 @@ exit( $err_cnt > 0 ? 1 : 0 ); sub GeoIP_update_database_general { - my ( $user_id, $license_key, $product_id, $verbose, $client_ipaddr ) = @_; + my ( $account_id, $license_key, $edition_id, $verbose, $client_ipaddr ) = @_; my $u = URI->new("$proto://$update_host/app/update_getfilename"); - $u->query_form( product_id => $product_id ); + $u->query_form( product_id => $edition_id ); print 'Send request ' . $u->as_string, "\n" if ($verbose); my $res = $ua->request( GET $u->as_string, Host => $update_host ); @@ -186,8 +186,8 @@ $u->query_form( db_md5 => shift, challenge_md5 => $hex_digest2, - user_id => $user_id, - edition_id => $product_id + user_id => $account_id, + edition_id => $edition_id ); print 'Send request ' . $u->as_string, "\n" if ($verbose); return $ua->request( GET $u->as_string, Host => $update_host ); diff -Nru geoipupdate-2.4.0/bin/geoipupdate_s.c geoipupdate-2.5.0/bin/geoipupdate_s.c --- geoipupdate-2.4.0/bin/geoipupdate_s.c 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/bin/geoipupdate_s.c 2017-10-30 14:38:24.000000000 +0000 @@ -1,10 +1,9 @@ #include "geoipupdate.h" -#include #include +#include -geoipupdate_s *geoipupdate_s_new(void) -{ +geoipupdate_s *geoipupdate_s_new(void) { size_t size = sizeof(geoipupdate_s); geoipupdate_s *gu = xmalloc(size); memset(gu, 0, size); @@ -22,12 +21,10 @@ "Unable to allocate memory for request protocol.\n"); gu->host = strdup("updates.maxmind.com"); - exit_if(NULL == gu->host, - "Unable to allocate memory for update host.\n"); + exit_if(NULL == gu->host, "Unable to allocate memory for update host.\n"); gu->proxy = strdup(""); - exit_if(NULL == gu->proxy, - "Unable to allocate memory for proxy host.\n"); + exit_if(NULL == gu->proxy, "Unable to allocate memory for proxy host.\n"); gu->proxy_user_password = strdup(""); exit_if(NULL == gu->proxy_user_password, @@ -38,20 +35,18 @@ "Unable to allocate memory for lock file path.\n"); gu->verbose = 0; - gu->license.user_id = NO_USER_ID; + gu->license.account_id = NO_ACCOUNT_ID; gu->license.license_key[12] = 0; gu->curl = curl_easy_init(); - exit_if(NULL == gu->curl, - "Unable to initialize curl.\n"); + exit_if(NULL == gu->curl, "Unable to initialize curl.\n"); return gu; } -void geoipupdate_s_delete(geoipupdate_s * gu) -{ +void geoipupdate_s_delete(geoipupdate_s *gu) { if (gu) { - product_delete_all(gu); + edition_delete_all(gu); free(gu->license_file); free(gu->database_dir); free(gu->proto); @@ -65,4 +60,3 @@ free(gu); } } - diff -Nru geoipupdate-2.4.0/bin/Makefile.am geoipupdate-2.5.0/bin/Makefile.am --- geoipupdate-2.4.0/bin/Makefile.am 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/bin/Makefile.am 2017-10-30 14:38:24.000000000 +0000 @@ -6,9 +6,8 @@ geoipupdate_SOURCES = \ geoipupdate.c geoipupdate.h \ md5.c md5.h \ - base64.c base64.h \ geoipupdate_s.c \ - product_s.c \ + edition_s.c \ types.h \ functions.c functions.h geoipupdate_LDFLAGS = diff -Nru geoipupdate-2.4.0/bin/Makefile.in geoipupdate-2.5.0/bin/Makefile.in --- geoipupdate-2.4.0/bin/Makefile.in 2017-05-25 20:10:04.000000000 +0000 +++ geoipupdate-2.5.0/bin/Makefile.in 2017-10-30 14:40:35.000000000 +0000 @@ -110,7 +110,7 @@ am__v_lt_0 = --silent am__v_lt_1 = am_geoipupdate_OBJECTS = geoipupdate.$(OBJEXT) md5.$(OBJEXT) \ - base64.$(OBJEXT) geoipupdate_s.$(OBJEXT) product_s.$(OBJEXT) \ + geoipupdate_s.$(OBJEXT) edition_s.$(OBJEXT) \ functions.$(OBJEXT) geoipupdate_OBJECTS = $(am_geoipupdate_OBJECTS) geoipupdate_DEPENDENCIES = @@ -507,9 +507,8 @@ geoipupdate_SOURCES = \ geoipupdate.c geoipupdate.h \ md5.c md5.h \ - base64.c base64.h \ geoipupdate_s.c \ - product_s.c \ + edition_s.c \ types.h \ functions.c functions.h @@ -624,13 +623,12 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edition_s.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functions_test-functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoipupdate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoipupdate_s.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_s.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff -Nru geoipupdate-2.4.0/bin/md5.c geoipupdate-2.5.0/bin/md5.c --- geoipupdate-2.4.0/bin/md5.c 2017-05-24 23:23:57.000000000 +0000 +++ geoipupdate-2.5.0/bin/md5.c 2017-10-30 14:38:24.000000000 +0000 @@ -22,10 +22,10 @@ /* Written by Ulrich Drepper , 1995. */ /* Heavily modified for GnuPG by */ +#include #include #include #include -#include #include "types.h" @@ -34,15 +34,18 @@ #endif //#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define wipememory2(_ptr, _set, _len) \ - do { volatile char *_vptr = \ - (volatile char *)(_ptr); \ - size_t _vlen = (_len); \ - while (_vlen) { *_vptr = (_set); \ - _vptr++; _vlen--; \ - } } while (0) +#define wipememory2(_ptr, _set, _len) \ + do { \ + volatile char *_vptr = (volatile char *)(_ptr); \ + size_t _vlen = (_len); \ + while (_vlen) { \ + *_vptr = (_set); \ + _vptr++; \ + _vlen--; \ + } \ + } while (0) #define wipememory(_ptr, _len) wipememory2(_ptr, 0, _len) -#define rol(x, n) ( ((x) << (n)) | ((x) >> (32 - (n))) ) +#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) typedef struct { u32 A, B, C, D; /* chaining variables */ @@ -51,10 +54,7 @@ int count; } MD5_CONTEXT; - -void -md5_init( MD5_CONTEXT *ctx ) -{ +void md5_init(MD5_CONTEXT *ctx) { ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; @@ -64,9 +64,6 @@ ctx->count = 0; } - - - /* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). */ @@ -76,9 +73,7 @@ #define FH(b, c, d) (b ^ c ^ d) #define FI(b, c, d) (c ^ (b | ~d)) -static void -burn_stack(int bytes) -{ +static void burn_stack(int bytes) { char buf[128]; wipememory(buf, sizeof buf); @@ -88,15 +83,12 @@ } } - - /**************** * transform n*64 bytes */ static void -/*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/ -transform( MD5_CONTEXT *ctx, byte *data ) -{ + /*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/ + transform(MD5_CONTEXT *ctx, byte *data) { u32 correct_words[16]; u32 A = ctx->A; u32 B = ctx->B; @@ -105,29 +97,27 @@ u32 *cwp = correct_words; #ifdef BIG_ENDIAN_HOST - { int i; - byte *p2, *p1; - for (i = 0, p1 = data, p2 = (byte *)correct_words; i < 16; i++, p2 += - 4) { - p2[3] = *p1++; - p2[2] = *p1++; - p2[1] = *p1++; - p2[0] = *p1++; - } + { + int i; + byte *p2, *p1; + for (i = 0, p1 = data, p2 = (byte *)correct_words; i < 16; + i++, p2 += 4) { + p2[3] = *p1++; + p2[2] = *p1++; + p2[1] = *p1++; + p2[0] = *p1++; + } } #else - memcpy( correct_words, data, 64 ); + memcpy(correct_words, data, 64); #endif - -#define OP(a, b, c, d, s, T) \ - do \ - { \ - a += FF(b, c, d) + (*cwp++) + T; \ - a = rol(a, s); \ - a += b; \ - } \ - while (0) +#define OP(a, b, c, d, s, T) \ + do { \ + a += FF(b, c, d) + (*cwp++) + T; \ + a = rol(a, s); \ + a += b; \ + } while (0) /* Before we start, one word about the strange constants. They are defined in RFC 1321 as @@ -154,14 +144,12 @@ OP(B, C, D, A, 22, 0x49b40821); #undef OP -#define OP(f, a, b, c, d, k, s, T) \ - do \ - { \ - a += f(b, c, d) + correct_words[k] + T; \ - a = rol(a, s); \ - a += b; \ - } \ - while (0) +#define OP(f, a, b, c, d, k, s, T) \ + do { \ + a += f(b, c, d) + correct_words[k] + T; \ + a = rol(a, s); \ + a += b; \ + } while (0) /* Round 2. */ OP(FG, A, B, C, D, 1, 5, 0xf61e2562); @@ -224,17 +212,13 @@ ctx->D += D; } - - /* The routine updates the message-digest context to * account for the presence of each of the characters inBuf[0..inLen-1] * in the message whose digest is being computed. */ -void -md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen) -{ +void md5_write(MD5_CONTEXT *hd, byte *inbuf, size_t inlen) { if (hd->count == 64) { /* flush the buffer */ - transform( hd, hd->buf ); + transform(hd, hd->buf); burn_stack(80 + 6 * sizeof(void *)); hd->count = 0; hd->nblocks++; @@ -246,14 +230,14 @@ for (; inlen && hd->count < 64; inlen--) { hd->buf[hd->count++] = *inbuf++; } - md5_write( hd, NULL, 0 ); + md5_write(hd, NULL, 0); if (!inlen) { return; } } while (inlen >= 64) { - transform( hd, inbuf ); + transform(hd, inbuf); hd->count = 0; hd->nblocks++; inlen -= 64; @@ -270,13 +254,12 @@ * Returns 16 bytes representing the digest. */ -void -md5_final( MD5_CONTEXT *hd ) -{ +void md5_final(MD5_CONTEXT *hd) { u32 t, msb, lsb; byte *p; - md5_write(hd, NULL, 0); /* flush */; + md5_write(hd, NULL, 0); /* flush */ + ; t = hd->nblocks; /* multiply by 64 to make a byte count */ @@ -284,7 +267,7 @@ msb = t >> 26; /* add the count */ t = lsb; - if ( (lsb += hd->count) < t) { + if ((lsb += hd->count) < t) { msb++; } /* multiply by 8 to make a bit count */ @@ -293,18 +276,19 @@ msb <<= 3; msb |= t >> 29; - if (hd->count < 56) { /* enough room */ - hd->buf[hd->count++] = 0x80; /* pad */ + if (hd->count < 56) { /* enough room */ + hd->buf[hd->count++] = 0x80; /* pad */ while (hd->count < 56) { hd->buf[hd->count++] = 0; /* pad */ } - }else { /* need one extra block */ - hd->buf[hd->count++] = 0x80; /* pad character */ + } else { /* need one extra block */ + hd->buf[hd->count++] = 0x80; /* pad character */ while (hd->count < 64) { hd->buf[hd->count++] = 0; } - md5_write(hd, NULL, 0); /* flush */; - memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + md5_write(hd, NULL, 0); /* flush */ + ; + memset(hd->buf, 0, 56); /* fill next block with zeroes */ } /* append the 64 bit count */ hd->buf[56] = lsb; @@ -315,21 +299,28 @@ hd->buf[61] = msb >> 8; hd->buf[62] = msb >> 16; hd->buf[63] = msb >> 24; - transform( hd, hd->buf ); + transform(hd, hd->buf); burn_stack(80 + 6 * sizeof(void *)); p = hd->buf; #ifdef BIG_ENDIAN_HOST -#define X(a) \ - do { *p++ = hd->a; *p++ = hd->a >> 8; \ - *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while (0) +#define X(a) \ + do { \ + *p++ = hd->a; \ + *p++ = hd->a >> 8; \ + *p++ = hd->a >> 16; \ + *p++ = hd->a >> 24; \ + } while (0) #else /* little endian */ -#define X(a) do { *(u32 *)p = hd->a; p += 4; } while (0) +#define X(a) \ + do { \ + *(u32 *)p = hd->a; \ + p += 4; \ + } while (0) #endif X(A); X(B); X(C); X(D); #undef X - } diff -Nru geoipupdate-2.4.0/bin/md5.h geoipupdate-2.5.0/bin/md5.h --- geoipupdate-2.4.0/bin/md5.h 2016-01-21 18:40:11.000000000 +0000 +++ geoipupdate-2.5.0/bin/md5.h 2017-10-30 14:38:24.000000000 +0000 @@ -28,13 +28,12 @@ #include "types.h" typedef struct { - u32 A, B, C, D; /* chaining variables */ + u32 A, B, C, D; /* chaining variables */ u32 nblocks; byte buf[64]; int count; } MD5_CONTEXT; -void md5_init( MD5_CONTEXT *ctx ); -void md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen); -void md5_final( MD5_CONTEXT *hd ); - +void md5_init(MD5_CONTEXT *ctx); +void md5_write(MD5_CONTEXT *hd, byte *inbuf, size_t inlen); +void md5_final(MD5_CONTEXT *hd); diff -Nru geoipupdate-2.4.0/bin/product_s.c geoipupdate-2.5.0/bin/product_s.c --- geoipupdate-2.4.0/bin/product_s.c 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/bin/product_s.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ - -#include "geoipupdate.h" -#include -#include - -int product_count(geoipupdate_s * gu) -{ - int cnt = 0; - for (product_s * p = gu->license.first; p; p = p->next) { - cnt++; - } - return cnt; -} - -void product_delete_all(geoipupdate_s * gu) -{ - product_s *next, *current; - - for (next = gu->license.first; (current = next); ) { - next = current->next; - product_delete(current); - } -} - -void product_insert_once(geoipupdate_s * gu, const char *product_id) -{ - product_s **next = &gu->license.first; - for (; *next; next = &(*next)->next) { - if (strcmp((*next)->product_id, product_id) == 0) { - return; - } - } - *next = product_new(product_id); - say_if(gu->verbose, "Insert product_id %s\n", product_id); - -} - -product_s *product_new(const char *product_id) -{ - product_s *p = xmalloc(sizeof(product_s)); - p->product_id = strdup(product_id); - exit_if(NULL == p->product_id, - "Unable to allocate memory for product ID.\n"); - p->next = NULL; - return p; -} - -void product_delete(product_s * p) -{ - if (p) { - free(p->product_id); - } - free(p); -} diff -Nru geoipupdate-2.4.0/bin/types.h geoipupdate-2.5.0/bin/types.h --- geoipupdate-2.4.0/bin/types.h 2016-01-21 18:40:11.000000000 +0000 +++ geoipupdate-2.5.0/bin/types.h 2017-10-30 14:38:24.000000000 +0000 @@ -41,11 +41,10 @@ #define SIZEOF_UNSIGNED_LONG 4 #endif - #include #ifndef HAVE_BYTE_TYPEDEF -#undef byte /* maybe there is a macro with this name */ +#undef byte /* maybe there is a macro with this name */ #ifndef __riscos__ typedef unsigned char byte; #else @@ -58,19 +57,19 @@ #endif #ifndef HAVE_USHORT_TYPEDEF -#undef ushort /* maybe there is a macro with this name */ +#undef ushort /* maybe there is a macro with this name */ typedef unsigned short ushort; #define HAVE_USHORT_TYPEDEF #endif #ifndef HAVE_ULONG_TYPEDEF -#undef ulong /* maybe there is a macro with this name */ +#undef ulong /* maybe there is a macro with this name */ typedef unsigned long ulong; #define HAVE_ULONG_TYPEDEF #endif #ifndef HAVE_U16_TYPEDEF -#undef u16 /* maybe there is a macro with this name */ +#undef u16 /* maybe there is a macro with this name */ #if SIZEOF_UNSIGNED_INT == 2 typedef unsigned int u16; #elif SIZEOF_UNSIGNED_SHORT == 2 @@ -82,7 +81,7 @@ #endif #ifndef HAVE_U32_TYPEDEF -#undef u32 /* maybe there is a macro with this name */ +#undef u32 /* maybe there is a macro with this name */ #if SIZEOF_UNSIGNED_INT == 4 typedef unsigned int u32; #elif SIZEOF_UNSIGNED_LONG == 4 @@ -99,22 +98,22 @@ * Solaris and IRIX. */ #ifndef HAVE_U64_TYPEDEF -#undef u64 /* maybe there is a macro with this name */ +#undef u64 /* maybe there is a macro with this name */ #if SIZEOF_UINT64_T == 8 typedef uint64_t u64; #define U64_C(c) (UINT64_C(c)) #define HAVE_U64_TYPEDEF #elif SIZEOF_UNSIGNED_INT == 8 typedef unsigned int u64; -#define U64_C(c) (c ## U) +#define U64_C(c) (c##U) #define HAVE_U64_TYPEDEF #elif SIZEOF_UNSIGNED_LONG == 8 typedef unsigned long u64; -#define U64_C(c) (c ## UL) +#define U64_C(c) (c##UL) #define HAVE_U64_TYPEDEF #elif SIZEOF_UNSIGNED_LONG_LONG == 8 typedef unsigned long long u64; -#define U64_C(c) (c ## ULL) +#define U64_C(c) (c##ULL) #define HAVE_U64_TYPEDEF #endif #endif @@ -135,6 +134,6 @@ struct string_list *next; unsigned int flags; char d[1]; -} *STRLIST; +} * STRLIST; #endif /*G10_TYPES_H*/ diff -Nru geoipupdate-2.4.0/ChangeLog.md geoipupdate-2.5.0/ChangeLog.md --- geoipupdate-2.4.0/ChangeLog.md 2017-05-25 20:09:09.000000000 +0000 +++ geoipupdate-2.5.0/ChangeLog.md 2017-10-30 14:39:26.000000000 +0000 @@ -1,6 +1,26 @@ GeoIP Update Change Log ======================= +2.5.0 (2017-10-30) +------------------ + +* Replace use of strnlen() due to lack of universal availability. First + reported by Bill Cole. GitHub issue #71. +* Document the `LockFile` option in the `GeoIP.conf` man page. GitHub + issue #64. +* Remove unused base64 library. PR by Mikhail Teterin. GitHub PR #68. +* Add the new configuration option `PreserveFileTimes`. If set, + the downloaded files will get the same modification times as + their original on the server. Default is `0` (unset). + PR by Rainer Jung. GitHub PR #63. +* Use the correct types when calling `curl_easy_setopt()`. This fixes + warnings generated by libcurl's `typecheck-gcc.h`. PR by Michael + Kaufmann. GitHub PR #61. +* In `GeoIP.conf`, the `UserId` option was renamed to `AccountID` and the + `ProductIds` option was renamed to `EditionIDs`. The old options will + continue to work, but upgrading to the new names is recommended for + forward compatibility. + 2.4.0 (2017-05-25) ------------------ diff -Nru geoipupdate-2.4.0/conf/GeoIP.conf.default geoipupdate-2.5.0/conf/GeoIP.conf.default --- geoipupdate-2.4.0/conf/GeoIP.conf.default 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/conf/GeoIP.conf.default 2017-10-30 14:38:24.000000000 +0000 @@ -2,19 +2,15 @@ # on setting up geoipupdate, including information on how to download a # pre-filled GeoIP.conf file. -# Enter your user ID and license key below. These are available from +# Enter your account ID and license key below. These are available from # https://www.maxmind.com/en/my_license_key. If you are only using free -# GeoLite databases, you make leave the 0 values. -UserId 0 +# GeoLite databases, you may leave the 0 values. +AccountID 0 LicenseKey 000000000000 -# Enter the product IDs of the databases you would like to update. -# Multiple product IDs are separated by spaces. -ProductIds GeoLite2-Country GeoLite2-City - -# The following are for the GeoLite Legacy databases. To update them, -# uncomment. -# ProductIds 506 517 533 GeoLite-Legacy-IPv6-Country GeoLite-Legacy-IPv6-City +# Enter the edition IDs of the databases you would like to update. +# Multiple edition IDs are separated by spaces. +EditionIDs GeoLite2-Country GeoLite2-City # The remaining settings are OPTIONAL. @@ -43,6 +39,10 @@ # Defaults to "0". # SkipPeerVerification 0 +# Whether to preserve modification times of files downloaded from the server. +# Defaults to "0". +# PreserveFileTimes 0 + # The lock file to use. This ensures only one geoipupdate process can run at a # time. # Defaults to ".geoipupdate.lock" under the DatabaseDirectory. diff -Nru geoipupdate-2.4.0/configure geoipupdate-2.5.0/configure --- geoipupdate-2.4.0/configure 2017-05-25 20:10:04.000000000 +0000 +++ geoipupdate-2.5.0/configure 2017-10-30 14:40:34.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for geoipupdate 2.4.0. +# Generated by GNU Autoconf 2.69 for geoipupdate 2.5.0. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='geoipupdate' PACKAGE_TARNAME='geoipupdate' -PACKAGE_VERSION='2.4.0' -PACKAGE_STRING='geoipupdate 2.4.0' +PACKAGE_VERSION='2.5.0' +PACKAGE_STRING='geoipupdate 2.5.0' PACKAGE_BUGREPORT='support@maxmind.com' PACKAGE_URL='' @@ -1325,7 +1325,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures geoipupdate 2.4.0 to adapt to many kinds of systems. +\`configure' configures geoipupdate 2.5.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1396,7 +1396,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of geoipupdate 2.4.0:";; + short | recursive ) echo "Configuration of geoipupdate 2.5.0:";; esac cat <<\_ACEOF @@ -1506,7 +1506,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -geoipupdate configure 2.4.0 +geoipupdate configure 2.5.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1983,7 +1983,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by geoipupdate $as_me 2.4.0, which was +It was created by geoipupdate $as_me 2.5.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4217,7 +4217,7 @@ # Define the identity of the package. PACKAGE='geoipupdate' - VERSION='2.4.0' + VERSION='2.5.0' cat >>confdefs.h <<_ACEOF @@ -13282,7 +13282,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by geoipupdate $as_me 2.4.0, which was +This file was extended by geoipupdate $as_me 2.5.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13339,7 +13339,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -geoipupdate config.status 2.4.0 +geoipupdate config.status 2.5.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru geoipupdate-2.4.0/configure.ac geoipupdate-2.5.0/configure.ac --- geoipupdate-2.4.0/configure.ac 2017-05-25 20:10:01.000000000 +0000 +++ geoipupdate-2.5.0/configure.ac 2017-10-30 14:40:31.000000000 +0000 @@ -1,6 +1,6 @@ dnl AM_CONFIG_HEADER(config.h) -AC_INIT([geoipupdate], [2.4.0],[support@maxmind.com],[geoipupdate]) +AC_INIT([geoipupdate], [2.5.0],[support@maxmind.com],[geoipupdate]) AC_GNU_SOURCE AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_SRCDIR([bin/geoipupdate.c]) diff -Nru geoipupdate-2.4.0/debian/changelog geoipupdate-2.5.0/debian/changelog --- geoipupdate-2.4.0/debian/changelog 2017-08-04 20:04:05.000000000 +0000 +++ geoipupdate-2.5.0/debian/changelog 2017-12-27 03:59:43.000000000 +0000 @@ -1,3 +1,21 @@ +geoipupdate (2.5.0-1) unstable; urgency=medium + + * New upstream release. + * Adjust the long description to mention that this package can be used for + the free GeoLite editions. + * Ship a default /etc/GeoIP.conf, with GeoLite2 databases enabled and + references to GeoLite Legacy databases. + * Ship a default /etc/cron.d/geoipupdate that runs geoiupdate on a weekly + basis. + * Stop shipping an empty /usr/share/GeoIP, as that path is not used by this + package. This was introduced erroneously by upstream in 2.4.0. + * Remove Breaks/Conflicts with a pre-jessie version of geoip-bin (1.6.1-1). + * Bump Standards-Version to 4.1.2, no changes needed. + * Remove bin/base64.{c,h} from debian/copyright, not included with upstream + anymore. + + -- Faidon Liambotis Wed, 27 Dec 2017 05:59:43 +0200 + geoipupdate (2.4.0-1) unstable; urgency=medium * New upstream release. diff -Nru geoipupdate-2.4.0/debian/control geoipupdate-2.5.0/debian/control --- geoipupdate-2.4.0/debian/control 2017-08-04 20:04:05.000000000 +0000 +++ geoipupdate-2.5.0/debian/control 2017-12-27 03:59:43.000000000 +0000 @@ -5,7 +5,7 @@ Build-Depends: debhelper (>= 10), zlib1g-dev, libcurl4-gnutls-dev -Standards-Version: 4.0.0 +Standards-Version: 4.1.2 Homepage: http://dev.maxmind.com/geoip/geoipupdate/ Vcs-Git: https://anonscm.debian.org/git/collab-maint/geoipupdate.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/geoipupdate.git @@ -13,11 +13,9 @@ Package: geoipupdate Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: geoip-bin (<< 1.6.1-1) -Replaces: geoip-bin (<< 1.6.1-1) -Suggests: geoip-bin, mmdb-bin +Suggests: mmdb-bin, geoip-bin Description: MaxMind GeoIP/GeoIP2 database updates The GeoIP Update program performs automatic updates of GeoIP2 and GeoIP Legacy - binary databases, as supplied by MaxMind. These are typically paid products; - for the free GeoLite databases, the packages geoip-database or - geoip-database-contrib can be installed instead. + binary databases, as supplied by MaxMind. These may be MaxMind's paid + products, or their GeoLite variants that are less accurate but freely + available to everyone without a subscription or registration. diff -Nru geoipupdate-2.4.0/debian/copyright geoipupdate-2.5.0/debian/copyright --- geoipupdate-2.4.0/debian/copyright 2017-08-04 20:04:05.000000000 +0000 +++ geoipupdate-2.5.0/debian/copyright 2017-12-27 02:50:44.000000000 +0000 @@ -6,7 +6,7 @@ Copyright: 2013-2014 MaxMind, Inc. License: GPL-2+ -Files: bin/base64.c bin/base64.h bin/md5.c bin/md5.h +Files: bin/md5.c bin/md5.h Copyright: 1995-2012 Free Software Foundation, Inc. License: GPL-2+ diff -Nru geoipupdate-2.4.0/debian/cron.d geoipupdate-2.5.0/debian/cron.d --- geoipupdate-2.4.0/debian/cron.d 1970-01-01 00:00:00.000000000 +0000 +++ geoipupdate-2.5.0/debian/cron.d 2017-12-27 03:25:07.000000000 +0000 @@ -0,0 +1,9 @@ +# Regular cron job for the geoipupdate package, used to update GeoIP databases +# +# According to MaxMind: "The GeoIP2 and GeoIP Legacy Country and City databases +# are updated every Tuesday. The GeoIP2 ISP, GeoIP Legacy ISP and Organization +# databases are updated every one to two weeks. All other databases are updated +# on the first Tuesday of each month." + +# m h dom mon dow user command +47 6 * * 3 root test -x /usr/bin/geoipupdate && /usr/bin/geoipupdate diff -Nru geoipupdate-2.4.0/debian/gbp.conf geoipupdate-2.5.0/debian/gbp.conf --- geoipupdate-2.4.0/debian/gbp.conf 2017-08-04 20:04:05.000000000 +0000 +++ geoipupdate-2.5.0/debian/gbp.conf 2017-12-27 02:50:44.000000000 +0000 @@ -1,6 +1,6 @@ -[buildpackage] +[DEFAULT] upstream-tree=tag debian-branch=debian upstream-tag = v%(version)s no-create-orig = True -prebuild = rm -f .travis.yml README.dev.md dev-bin/release.sh dev-bin/ppa-release.sh +prebuild = rm -f .travis.yml .clang-format README.dev.md dev-bin/* diff -Nru geoipupdate-2.4.0/debian/GeoIP.conf geoipupdate-2.5.0/debian/GeoIP.conf --- geoipupdate-2.4.0/debian/GeoIP.conf 1970-01-01 00:00:00.000000000 +0000 +++ geoipupdate-2.5.0/debian/GeoIP.conf 2017-12-27 03:25:07.000000000 +0000 @@ -0,0 +1,25 @@ +# Please see http://dev.maxmind.com/geoip/geoipupdate/ for instructions +# on setting up geoipupdate, including information on how to download a +# pre-filled GeoIP.conf, if you are a MaxMind subscriber. +# +# You can also have a look at GeoIP.conf(5) ("man GeoIP.conf") for a +# comprehensive list of configuration options. + +# Enter your account ID and license key below. These are available from +# https://www.maxmind.com/en/my_license_key. If you are only using free +# GeoLite databases, you may leave the 0 values. +AccountID 0 +LicenseKey 000000000000 + +# Enter the edition IDs of the databases you would like to update. +# Multiple edition IDs are separated by spaces. +# +# Include one or more of the following edition IDs: +# * GeoLite2-City - GeoLite 2 City +# * GeoLite2-Country - GeoLite2 Country +# * GeoLite-Legacy-IPv6-City - GeoLite Legacy IPv6 City +# * GeoLite-Legacy-IPv6-Country - GeoLite Legacy IPv6 Country +# * 506 - GeoLite Legacy Country +# * 517 - GeoLite Legacy ASN +# * 533 - GeoLite Legacy City +EditionIDs GeoLite2-Country GeoLite2-City diff -Nru geoipupdate-2.4.0/debian/install geoipupdate-2.5.0/debian/install --- geoipupdate-2.4.0/debian/install 1970-01-01 00:00:00.000000000 +0000 +++ geoipupdate-2.5.0/debian/install 2017-12-27 03:25:07.000000000 +0000 @@ -0,0 +1 @@ +debian/GeoIP.conf etc/ diff -Nru geoipupdate-2.4.0/debian/rules geoipupdate-2.5.0/debian/rules --- geoipupdate-2.4.0/debian/rules 2017-08-04 20:04:05.000000000 +0000 +++ geoipupdate-2.5.0/debian/rules 2017-12-27 03:53:24.000000000 +0000 @@ -14,3 +14,4 @@ dh_auto_install rm -rf debian/geoipupdate/etc rm -f debian/geoipupdate/usr/share/doc/geoipupdate/* + rmdir debian/geoipupdate/usr/share/GeoIP diff -Nru geoipupdate-2.4.0/man/GeoIP.conf.5.in geoipupdate-2.5.0/man/GeoIP.conf.5.in --- geoipupdate-2.4.0/man/GeoIP.conf.5.in 2014-06-02 16:32:00.000000000 +0000 +++ geoipupdate-2.5.0/man/GeoIP.conf.5.in 2017-10-30 14:38:24.000000000 +0000 @@ -1,4 +1,4 @@ -.TH GeoIP.conf 5 "25 Sep 2013" +.TH GeoIP.conf 5 "26 Oct 2017" .UC 4 .SH NAME GeoIP.conf - Configuration file for geoipupdate @@ -17,15 +17,17 @@ .PP .SS Required settings: .TP -.B UserId -Your MaxMind user ID. +.B AccountID +Your MaxMind account ID. This was formerly known as +.BR UserId ". .TP .B LicenseKey Your case-sensitive MaxMind license key. .TP -.B ProductIds -List of product IDs. Product IDs may consist of letters, digits, and dashes -(e.g., "GeoIP2-City", "106"). +.B EditionIDs +List of database edition IDs. Edition IDs may consist of letters, digits, and +dashes (e.g., "GeoIP2-City", "106"). Note: this was formerly called +.BR ProductIds ". .PP .SS Optional settings: .PP @@ -52,11 +54,22 @@ .TP .B SkipPeerVerification Skip peer verification when using -.BR https ". Valid values are " 0 " and " 1 ". The default is " 0 ". +.BR https ". Valid values are " 0 " or " 1 ". The default is " 0 ". .TP .B SkipHostnameVerification Skip the host name verification when using -.BR https ". This option is either " 0 " and " 1 ". The default is " 0 ". +.BR https ". This option is either " 0 " or " 1 ". The default is " 0 ". +.TP +.B PreserveFileTimes +Whether to preserve modification times of files downloaded from the server. +This option is either +.BR 0 " or " 1 ". The default is " 0 ". +.TP +.B LockFile +The lock file to use. This ensures only one +.B geoipupdate +process can run at a time. The default is +.BR .geoipupdate.lock " under the " DatabaseDirectory . .SH FILES .PP .TP diff -Nru geoipupdate-2.4.0/README.md geoipupdate-2.5.0/README.md --- geoipupdate-2.4.0/README.md 2017-05-25 17:18:27.000000000 +0000 +++ geoipupdate-2.5.0/README.md 2017-10-26 21:30:50.000000000 +0000 @@ -22,11 +22,19 @@ ## Installing From Source File To install this from the source package, you will need a C compiler, Make, -the zlib library and headers, and the curl library and headers. On Debian -or Ubuntu, you can install these dependencies by running: +the zlib library and headers, and the curl library and headers. + +On Debian or Ubuntu, you can install these +dependencies by running: $ sudo apt-get install build-essential libcurl4-openssl-dev zlib1g-dev +On Centos 7 or RHEL 7, you can install these +dependencies by running: + + $ sudo yum groupinstall 'Development Tools' + $ sudo yum install libcurl-devel + Once you have the necessary dependencies, run the following commands: $ ./configure