/* This file is part of libmicrohttpd Copyright (C) 2007 Christian Grothoff libmicrohttpd 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. libmicrohttpd 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 libmicrohttpd; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file curl_version_check.c * @brief verify required cURL version is available to run tests * @author Sagie Amir */ #include "MHD_config.h" #include "platform.h" #include <curl/curl.h> #ifndef WINDOWS #include <unistd.h> #endif static int parse_version_number (const char **s) { int i = 0; char num[17]; while (i < 16 && ((**s >= '0') & (**s <= '9'))) { num[i] = **s; (*s)++; i++; } num[i] = '\0'; return atoi (num); } const char * parse_version_string (const char *s, int *major, int *minor, int *micro) { if (!s) return NULL; *major = parse_version_number (&s); if (*s != '.') return NULL; s++; *minor = parse_version_number (&s); if (*s != '.') return NULL; s++; *micro = parse_version_number (&s); return s; } #if HTTPS_SUPPORT int curl_uses_nss_ssl() { return (strstr(curl_version(), " NSS/") != NULL) ? 0 : -1; } #endif /* * check local libcurl version matches required version */ int curl_check_version (const char *req_version) { const char *ver; const char *curl_ver; #if HTTPS_SUPPORT const char *ssl_ver; const char *req_ssl_ver; #endif int loc_major, loc_minor, loc_micro; int rq_major, rq_minor, rq_micro; ver = curl_version (); #if HAVE_MESSAGES fprintf (stderr, "curl version: %s\n", ver); #endif /* * this call relies on the cURL string to be of the exact following format : * 'libcurl/7.16.4 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/0.6.5' OR * 'libcurl/7.18.2 GnuTLS/2.4.0 zlib/1.2.3.3 libidn/0.6.5' */ curl_ver = strchr (ver, '/'); if (curl_ver == NULL) return -1; curl_ver++; /* Parse version numbers */ if ( (NULL == parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) || (NULL == parse_version_string (curl_ver, &loc_major, &loc_minor, &loc_micro)) ) return -1; /* Compare version numbers. */ if ((loc_major > rq_major || (loc_major == rq_major && loc_minor > rq_minor) || (loc_major == rq_major && loc_minor == rq_minor && loc_micro > rq_micro) || (loc_major == rq_major && loc_minor == rq_minor && loc_micro == rq_micro)) == 0) { fprintf (stderr, "Error: running curl test depends on local libcurl version > %s\n", req_version); return -1; } /* * enforce required gnutls/openssl version. * TODO use curl version string to assert use of gnutls */ #if HTTPS_SUPPORT ssl_ver = strchr (curl_ver, ' '); if (ssl_ver == NULL) return -1; ssl_ver++; if (strncmp ("GnuTLS", ssl_ver, strlen ("GNUtls")) == 0) { ssl_ver = strchr (ssl_ver, '/'); req_ssl_ver = MHD_REQ_CURL_GNUTLS_VERSION; } else if (strncmp ("OpenSSL", ssl_ver, strlen ("OpenSSL")) == 0) { ssl_ver = strchr (ssl_ver, '/'); req_ssl_ver = MHD_REQ_CURL_OPENSSL_VERSION; } else if (strncmp ("NSS", ssl_ver, strlen ("NSS")) == 0) { ssl_ver = strchr (ssl_ver, '/'); req_ssl_ver = MHD_REQ_CURL_NSS_VERSION; } else { fprintf (stderr, "Error: unrecognized curl ssl library\n"); return -1; } if (ssl_ver == NULL) return -1; ssl_ver++; if ( (NULL == parse_version_string (req_ssl_ver, &rq_major, &rq_minor, &rq_micro)) || (NULL == parse_version_string (ssl_ver, &loc_major, &loc_minor, &loc_micro)) ) return -1; if ((loc_major > rq_major || (loc_major == rq_major && loc_minor > rq_minor) || (loc_major == rq_major && loc_minor == rq_minor && loc_micro > rq_micro) || (loc_major == rq_major && loc_minor == rq_minor && loc_micro == rq_micro)) == 0) { fprintf (stderr, "Error: running curl test depends on local libcurl SSL version > %s\n", req_ssl_ver); return -1; } #endif return 0; }