1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "setup.h"
24
25#include <string.h>
26#include <stdio.h>
27
28#include <curl/curl.h>
29#include "urldata.h"
30#include "sslgen.h"
31
32#define _MPRINTF_REPLACE /* use the internal *printf() functions */
33#include <curl/mprintf.h>
34
35#ifdef USE_ARES
36#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
37     (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
38#    define CARES_STATICLIB
39#  endif
40#  include <ares.h>
41#endif
42
43#ifdef USE_LIBIDN
44#include <stringprep.h>
45#endif
46
47#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
48#include <iconv.h>
49#endif
50
51#ifdef USE_LIBRTMP
52#include <librtmp/rtmp.h>
53#endif
54
55#ifdef USE_LIBSSH2
56#include <libssh2.h>
57#endif
58
59#ifdef HAVE_LIBSSH2_VERSION
60/* get it run-time if possible */
61#define CURL_LIBSSH2_VERSION libssh2_version(0)
62#else
63/* use build-time if run-time not possible */
64#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
65#endif
66
67char *curl_version(void)
68{
69  static char version[200];
70  char *ptr=version;
71  size_t len;
72  size_t left = sizeof(version);
73  strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION );
74  len = strlen(ptr);
75  left -= len;
76  ptr += len;
77
78  if(left > 1) {
79    len = Curl_ssl_version(ptr + 1, left - 1);
80
81    if(len > 0) {
82      *ptr = ' ';
83      left -= ++len;
84      ptr += len;
85    }
86  }
87
88#ifdef HAVE_LIBZ
89  len = snprintf(ptr, left, " zlib/%s", zlibVersion());
90  left -= len;
91  ptr += len;
92#endif
93#ifdef USE_ARES
94  /* this function is only present in c-ares, not in the original ares */
95  len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
96  left -= len;
97  ptr += len;
98#endif
99#ifdef USE_LIBIDN
100  if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
101    len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
102    left -= len;
103    ptr += len;
104  }
105#endif
106#ifdef USE_WIN32_IDN
107  len = snprintf(ptr, left, " IDN-Windows-native");
108  left -= len;
109  ptr += len;
110#endif
111#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
112#ifdef _LIBICONV_VERSION
113  len = snprintf(ptr, left, " iconv/%d.%d",
114                 _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
115#else
116  /* version unknown */
117  len = snprintf(ptr, left, " iconv");
118#endif /* _LIBICONV_VERSION */
119  left -= len;
120  ptr += len;
121#endif
122#ifdef USE_LIBSSH2
123  len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
124  left -= len;
125  ptr += len;
126#endif
127#ifdef USE_LIBRTMP
128  {
129    char suff[2];
130    if(RTMP_LIB_VERSION & 0xff) {
131      suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
132      suff[1] = '\0';
133    }
134    else
135      suff[0] = '\0';
136
137    len = snprintf(ptr, left, " librtmp/%d.%d%s",
138      RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, suff);
139/*
140  If another lib version is added below this one, this code would
141  also have to do:
142
143    left -= len;
144    ptr += len;
145*/
146  }
147#endif
148
149  return version;
150}
151
152/* data for curl_version_info
153
154   Keep the list sorted alphabetically. It is also written so that each
155   protocol line has its own #if line to make things easier on the eye.
156 */
157
158static const char * const protocols[] = {
159#ifndef CURL_DISABLE_DICT
160  "dict",
161#endif
162#ifndef CURL_DISABLE_FILE
163  "file",
164#endif
165#ifndef CURL_DISABLE_FTP
166  "ftp",
167#endif
168#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
169  "ftps",
170#endif
171#ifndef CURL_DISABLE_GOPHER
172  "gopher",
173#endif
174#ifndef CURL_DISABLE_HTTP
175  "http",
176#endif
177#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
178  "https",
179#endif
180#ifndef CURL_DISABLE_IMAP
181  "imap",
182#endif
183#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)
184  "imaps",
185#endif
186#ifndef CURL_DISABLE_LDAP
187  "ldap",
188#if !defined(CURL_DISABLE_LDAPS) && \
189    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
190     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
191  "ldaps",
192#endif
193#endif
194#ifndef CURL_DISABLE_POP3
195  "pop3",
196#endif
197#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)
198  "pop3s",
199#endif
200#ifdef USE_LIBRTMP
201  "rtmp",
202#endif
203#ifndef CURL_DISABLE_RTSP
204  "rtsp",
205#endif
206#ifdef USE_LIBSSH2
207  "scp",
208#endif
209#ifdef USE_LIBSSH2
210  "sftp",
211#endif
212#ifndef CURL_DISABLE_SMTP
213  "smtp",
214#endif
215#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)
216  "smtps",
217#endif
218#ifndef CURL_DISABLE_TELNET
219  "telnet",
220#endif
221#ifndef CURL_DISABLE_TFTP
222  "tftp",
223#endif
224
225  NULL
226};
227
228static curl_version_info_data version_info = {
229  CURLVERSION_NOW,
230  LIBCURL_VERSION,
231  LIBCURL_VERSION_NUM,
232  OS, /* as found by configure or set by hand at build-time */
233  0 /* features is 0 by default */
234#ifdef ENABLE_IPV6
235  | CURL_VERSION_IPV6
236#endif
237#ifdef HAVE_KRB4
238  | CURL_VERSION_KERBEROS4
239#endif
240#ifdef USE_SSL
241  | CURL_VERSION_SSL
242#endif
243#ifdef USE_NTLM
244  | CURL_VERSION_NTLM
245#endif
246#ifdef USE_WINDOWS_SSPI
247  | CURL_VERSION_SSPI
248#endif
249#ifdef HAVE_LIBZ
250  | CURL_VERSION_LIBZ
251#endif
252#ifdef USE_HTTP_NEGOTIATE
253  | CURL_VERSION_GSSNEGOTIATE
254#endif
255#ifdef DEBUGBUILD
256  | CURL_VERSION_DEBUG
257#endif
258#ifdef CURLDEBUG
259  | CURL_VERSION_CURLDEBUG
260#endif
261#ifdef CURLRES_ASYNCH
262  | CURL_VERSION_ASYNCHDNS
263#endif
264#ifdef HAVE_SPNEGO
265  | CURL_VERSION_SPNEGO
266#endif
267#if (CURL_SIZEOF_CURL_OFF_T > 4) && \
268    ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) )
269  | CURL_VERSION_LARGEFILE
270#endif
271#if defined(CURL_DOES_CONVERSIONS)
272  | CURL_VERSION_CONV
273#endif
274#if defined(USE_TLS_SRP)
275  | CURL_VERSION_TLSAUTH_SRP
276#endif
277  ,
278  NULL, /* ssl_version */
279  0,    /* ssl_version_num, this is kept at zero */
280  NULL, /* zlib_version */
281  protocols,
282  NULL, /* c-ares version */
283  0,    /* c-ares version numerical */
284  NULL, /* libidn version */
285  0,    /* iconv version */
286  NULL, /* ssh lib version */
287};
288
289curl_version_info_data *curl_version_info(CURLversion stamp)
290{
291#ifdef USE_LIBSSH2
292  static char ssh_buffer[80];
293#endif
294
295#ifdef USE_SSL
296  static char ssl_buffer[80];
297  Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
298  version_info.ssl_version = ssl_buffer;
299#endif
300
301#ifdef HAVE_LIBZ
302  version_info.libz_version = zlibVersion();
303  /* libz left NULL if non-existing */
304#endif
305#ifdef USE_ARES
306  {
307    int aresnum;
308    version_info.ares = ares_version(&aresnum);
309    version_info.ares_num = aresnum;
310  }
311#endif
312#ifdef USE_LIBIDN
313  /* This returns a version string if we use the given version or later,
314     otherwise it returns NULL */
315  version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
316  if(version_info.libidn)
317    version_info.features |= CURL_VERSION_IDN;
318#elif defined(USE_WIN32_IDN)
319  version_info.features |= CURL_VERSION_IDN;
320#endif
321
322#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
323#ifdef _LIBICONV_VERSION
324  version_info.iconv_ver_num = _LIBICONV_VERSION;
325#else
326  /* version unknown */
327  version_info.iconv_ver_num = -1;
328#endif /* _LIBICONV_VERSION */
329#endif
330
331#ifdef USE_LIBSSH2
332  snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
333  version_info.libssh_version = ssh_buffer;
334#endif
335
336  (void)stamp; /* avoid compiler warnings, we don't use this */
337
338  return &version_info;
339}
340