From 7275bbb31efb8d678d82cc4a2d5fdef28dff9acc Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Fri, 20 Jul 2018 19:44:44 +0200 Subject: [PATCH 1/9] Squashed 'libs/ODBC-Specification/' content from commit 51d4b3a git-subtree-dir: libs/ODBC-Specification git-subtree-split: 51d4b3a197a9333a7c8a7685c17c462df5e29cc7 --- ODBC 4.0.md | 1377 +++++++++++++++++++++ README.md | 21 + Windows/inc/sql.h | 941 ++++++++++++++ Windows/inc/sqlext.h | 2437 +++++++++++++++++++++++++++++++++++++ Windows/inc/sqltypes.h | 355 ++++++ Windows/inc/sqlucode.h | 1009 +++++++++++++++ contribution-agreement.md | 44 + license.txt | 16 + 8 files changed, 6200 insertions(+) create mode 100644 ODBC 4.0.md create mode 100644 README.md create mode 100644 Windows/inc/sql.h create mode 100644 Windows/inc/sqlext.h create mode 100644 Windows/inc/sqltypes.h create mode 100644 Windows/inc/sqlucode.h create mode 100644 contribution-agreement.md create mode 100644 license.txt diff --git a/ODBC 4.0.md b/ODBC 4.0.md new file mode 100644 index 00000000..a04224f5 --- /dev/null +++ b/ODBC 4.0.md @@ -0,0 +1,1377 @@ +ODBC 4.0 Specification += + +Table of Contents + + +- [1 Overview](#1-overview) +- [2 Compatibility with ODBC 3.x](#2-compatibility-with-odbc-3x) + - [2.1 ODBC 3.x Errata](#21-odbc-3x-errata) +- [3 Design](#3-design) + - [3.1 Private Drivers](#31-private-drivers) + - [3.2 Web Authorization](#32-web-authorization) + - [3.3 SQL Syntax Support](#33-sql-syntax-support) + - [3.4 String Format](#34-string-format) + - [3.5 Schema Inference](#35-schema-inference) + - [3.6 Getting Data during Fetch](#36-getting-data-during-fetch) + - [3.7 Variable Typed Columns](#37-variable-typed-columns) + - [3.8 Variable Length Columns](#38-variable-length-columns) + - [3.9 Dynamic Columns](#39-dynamic-columns) + - [3.10 Structured Columns](#310-structured-columns) + - [3.11 Collection-valued Columns](#311-collection-valued-columns) + - [3.12 New SQL C types](#312-new-sql-c-types) +- [4 Change Tracking](#4-change-tracking) +- [5 Compatibility](#5-compatibility) + - [5.1 ODBC 3.x Clients](#51-odbc-3x-clients) + - [5.2 ODBC 3.x Drivers](#52-odbc-3x-drivers) + - [5.3 ODBC 4.0 Drivers](#53-odbc-40-drivers) + - [5.4 ODBC 4.0 Clients](#54-odbc-40-clients) + - [5.5 ODBC 4.0 Driver Manager](#55-odbc-40-driver-manager) +- [6 New Functions](#6-new-functions) + - [6.1 SQLNextColumn](#61-sqlnextcolumn) + - [6.2 SQLGetNestedHandle](#62-sqlgetnestedhandle) + - [6.3 SQLStructuredTypes](#63-sqlstructuredtypes) + - [6.4 SQLStructuredTypeColumns](#64-sqlstructuredtypecolumns) + +# 1 Overview + +ODBC is a widely adopted, standard, client-side API that works well for relational (i.e., tabular) data. However, many types of today's data may not fit well into a relational model. ODBC 4.0 defines extensions to support non-relational concepts such as: + +1. Dynamic columns (columns not defined in schema) +2. Structured columns +3. Collection-valued columns +4. Untyped/Varying typed columns + +In addition, general enhancements are added in order to improve interoperability of generic ODBC clients across diverse data sources, including enhanced discovery, authentication, syntax, and capability reporting. + +# 2 Compatibility with ODBC 3.x + +ODBC 3.x is a relational API. Existing clients expect data to be modeled, queried, represented and updated relationally. + +In order to be advertised as an ODBC 3.x driver, and returned from the control panel/driver manager, drivers must be 100% compatible with ODBC 3.x. Such drivers must expose a relational view of the data through the standard schema functions (SQLTables, SQLColumns, etc.) and continue to support standard Entry SQL-92 operations against this flattened view. + +The flattened view may not be comprehensive (there may be data not available through the relational view, data modeled as strings representing structured content of a particular format, the data may not be updatable through that view, etc.) but existing ODBC 3.x clients must be able to meaningfully interact with the data. + +The convenience to existing clients of representing hierarchical data through a relational lens sacrifices fidelity. Applications that specify a value for the `SQL_ATTR_ODBC_VERSION` environment attribute of 4.x or greater may see a hierarchical structure containing row, collection, and variant-typed data values. + +For more information on compatibility, see [Section 5, Compatibility](#5-compatibility) + +# 2.1 ODBC 3.x Errata +The following errata are not intended to describe new functionality but to clarify apply to clarify existing expected ODBC behavior. + +## 2.1.1 Types of Data Supported by SQLGetData +While the current ODBC Specification calls out the use of *TargetType* for specifying the type of data to be retrieved in SQLGetData, which may differ from the type in the APD or ARD, it is not clear that, when retrieving string or binary data in parts, the same C data type should be specified for each part. + +## 2.1.1 SQLGetData and Variable Length Data +The current ODBC Specification states the following: + +> When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength and assumes the buffer is large enough to hold the data. It is therefore important for the application to allocate a large enough buffer for fixed-length data or the driver will write past the end of the buffer. + +In this context, "fixed-length data" refers to "non-character or binary data". As described in "Retrieving Variable-Length Data In Parts", SQLGetData can be used to retrieve any character or binary data in pieces, and drivers should always respect BufferLength when writing string or binary data. + +## 2.1.2 Use of Substitution Character +Drivers should use a substitution character (HEX 1A), rather than raise an exception, if a character is not available in the target codepage. Clients should be aware of this behavior, for example, when attempting to round-trip values. + +# 3 Design + +ODBC 4.0 is extended to support common features across all types of data sources, as well as specific new features to support new schema concepts. + +# 3.1 Private Drivers + +Drivers registered through the ODBC setup utility are available to all applications. All applications using the driver use the same version of the driver. + +ODBC 4.0 enables applications to use their own private drivers. Such drivers are not visible to other applications and may support different versions from applications using the same driver. + +Private drivers are not registered using the ODBC setup utility. The new `SQL_ATTR_PRIVATE_DRIVER_PATH` environment attribute specifies a path which will be implicitly checked for private drivers. By default, this path is set by appending "ODBC Drivers" to the path provided by [GetModuleFileName](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197) with a NULL hModule. Each private driver is represented in that directory by an .ini file whose name is the *driver-name* with the “.ini” suffix. + +The .ini file follows the [windows .ini file format](https://en.wikipedia.org/wiki/INI_file). It is a text file whose first line is a section header containing the name of the driver, enclosed in square brackets, and followed by keyword=value pairs, one per line. Valid keyword-value pairs are the [subkeys](https://msdn.microsoft.com/en-us/library/ms709431(v=vs.85).aspx) allowed for the driver specific section under ODBCINST.INI, along with a new “ApplicationKey” key-value pair which, if specified, is passed by the driver manager to the driver in a call to SetEnvAttr with the new `SQL_ATTR_APPLICATION_KEY` attribute. The driver developer can use this to validate that the calling application is permitted to use the driver, for example, by using a signed hash of the application’s publisher validated against the calling application at runtime. + +SQLDrivers enumerates the drivers registered under the ODBCINST.INI registry key as well as the drivers bin-deployed within the current application’s install directory as described above. The *DriverAttributes* returned by SQLDrivers for a bin-deployed driver is the set of key-value pairs read from the corresponding .ini file. + +This expanded set of drivers is also available in the data source configuration dialog for creating new DSNs. + +SQLDataSources filters the set of DSNs based on the underlying driver, enumerating only those data sources whose driver is available to the application. This also restricts the list of available data sources that are enumerated in the data source connection dialog. + +When resolving a driver for a registered DSN, the Driver Manager first looks to the Driver keyword within the named DSN that is a direct child of the ODBC.INI subkey. If this string matches the name of a directory under the current “ODBC Drivers” directory, then the driver is loaded according to the .ini file defined in that directory. Otherwise, the Driver Manager looks for a registry entry under the “Drivers” section within ODBCINST.INI. Failing that, the Driver Manager treats the string as a file path and attempts to load the driver using that path. + +This allows bin-deployed drivers to work like any other driver from the application’s perspective, including the creation of DSNs, and allows DSNs to be shared across applications that each have their own copy of the driver. + +## 3.2 Web Authorization + +Applications can connect to drivers that require web-based authentication through SQLDriverConnect or SQLBrowseConnect. + +### 3.2.1 Web Authorization Flow with SQLDriverConnect + +Applications can connect to services requiring web authentication by calling SQLDriverConnect. + +If the input connection string contains the required information (for example, access token, scope, refresh token, and expiration, as appropriate) in addition to any driver-specific properties, and the access token has not expired, no additional information should be required. If a provided access token has expired and the connection string contains a refresh token, the driver attempts to refresh the connection using the supplied refresh token. If the access token has expired and the connection string does not contain a refresh token, SQLDriverConnect fails as described in [Token Expiration](#324-token-expiration). + +Applications that don’t have a complete connection string, but are willing to allow drivers to pop up dialogs to obtain necessary information from the user, can call SQLDriverConnect, specifying a DriverCompletion value of `SQL_DRIVER_PROMPT`, `SQL_DRIVER_COMPLETE`, or `SQL_DRIVER_COMPLETE_REQUIRED`. + +When SQLDriverConnect is called with a DriverCompletion value other than `SQL_DRIVER_NOPROMPT`, drivers that require web authentication not present in the input connection string conduct the necessary authentication flow, including presenting browser windows as necessary, and return to the application a completed connection string containing driver-specific properties, an access token, scope (as appropriate) and, if the access token has an expiration, the expiration (as an ISO 8601 datetime with timezone) and refresh token: + + "Auth_AccessToken=xxx;Auth_Expires=xxx;Auth_RefreshToken=xxx;Auth_Scope=ZZZ;Prop1=xxx;" + +This connection string contains all the information necessary to be used in a subsequent call to SQLDriverConnect or SQLBrowseConnect to reconnect to the service. Note that this connection string may contain sensitive information and should be protected by the application. + +### 3.2.2 Web-based Authentication Flow with SQLBrowseConnect + +Applications that are unable to allow drivers to pop up dialogs can call SQLBrowseConnect to connect to the service. + +SQLBrowseConnect provides an iterative dialog between the driver and the application where the application passes in an initial input connection string. If the connection string contains sufficient information to connect, the driver responds with `SQL_SUCCESS` and an output connection string containing the complete set of connection attributes used. + +If the initial input connection string does not contain sufficient information to connect to the source, the driver responds with `SQL_NEED_DATA` and an output connection string specifying informational attributes for the application (such as the authorization url) as well as required attributes to be specified in a subsequent call to SQLBrowseConnect. Attribute names returned by SQLBrowseConnect may include a colon followed by a localized identifier, and the value of the requested attribute is either a single question mark or a comma-separated list of valid values (optionally including localized identifiers) enclosed in curly braces. Optional attributes are returned preceded with an asterix (`*`). + +In a Web-based authentication scenario, if SQLBrowseConnect is called with an input connection string containing an access token that has not expired, along with any other required properties, no additional information should be required. If the access token has expired and the connection string contains a refresh token, the driver attempts to refresh the connection using the supplied refresh token. + +If SQLBrowseConnect is called without an access token, with an expired access token and the driver is unable to refresh the token, or with other required information missing, SQLBrowseConnect returns with `SQL_NEED_DATA`. + +In cases where different authentication methods may be supported, the driver can initially return an OutConnectionString allowing the application to select from an enumerated set of authentication methods. + + "Auth_Type={OAuth_1.0, OAuth_2.0}" + +Common keywords for `Auth_Type` include “`Basic`”, “`Integrated`”, “`OAuth_1.0`”, “`OAuth_2.0`”, and “`None`”. Drivers should use these keywords for the corresponding authentication types, where supported, and may specify other driver-specific authentication types. + +In order to specify an authentication method, the application calls SQLBrowseConnect with a connection string specifying one of those allowed authentication methods, and SQLBrowseConnect returns an output connection string requesting the connection attributes required for that particular choice. + +For OAuth 2.0, SQLBrowseConnect returns an OutConnectionString requesting a redirect uri, along with a client ID, a client secret, and a scope, as required, along with any required provider-specific properties. + + "Auth_BaseRedirectUri:Redirect Uri=?;Auth_Client_ID:ClientID=?;Auth_Client_Secret:Client Secret=?;*Auth_Scope:Scope={XXX:xxx,YYY:yyy,ZZZ:zzz}" + +If the service supports scopes but the driver is unable to enumerate those scopes, it simply returns a question mark (?) as the value for `Auth_Scope` in the output connection string: + + "Auth_BaseRedirectUri:Redirect Uri=?;Auth_Client_ID:ClientID=?;Auth_Client_Secret:Client Secret=?;*Auth_Scope:Scope=?" + +For an OAuth 1.0, the output connection string would also ask for `Auth_Realm` and `Auth_Token_Secret`. + + "Auth_BaseRedirectUri:Redirect Uri=?;Auth_Client_ID:ClientID=?;Auth_Client_Secret:Client Secret=?;*Auth_Scope:Scope=?;Auth_Realm:Realm=?;Auth_Token_Secret:Token Secret=?" + +The application next calls SQLBrowseConnect with a connection string containing the redirect uri, the client ID, and client secret, along with scope, realm, and token secret, as appropriate: + + "Auth_BaseRedirectUri=https://abc.com/auth;Auth_Client_ID=myapp;Auth_Client_Secret=xyz;Auth_Scope=ZZZ" + +The driver responds with a connection string containing the authorization url and requesting the final redirect uri. For the best client UI experience, the output connection string should also include suggested window height and width (in pixels) for the browser window: + + “AuthorizationUrl=xxx;Auth_WindowHeight=xxx;Auth_WindowWidth=xxx;Auth_CompletedRedirectUri=?” + +The application navigates the browser to the Url specified by the authorization url. Auth flow is complete once the browser reaches the redirect uri. + +At that point, the application calls SQLBrowseConnect again, supplying the completed redirect uri (including any query string parameters). The driver uses the query string parameters returned in this uri to complete any additional flow required and returns `SQL_SUCCESS` with an OutConnectionString containing driver-specific properties, an access token, and scope, expiration (as an ISO 8601 datetime with timezone), and refresh token as appropriate: + + "Auth_AccessToken=xxx;Auth_Expires=xxx;Auth_RefreshToken=xxx;Auth_Scope=ZZZ;Prop1=xxx; " + +This connection string contains all the information necessary to be used in a subsequent call to SQLDriverConnect or SQLBrowseConnect to reconnect to the service. Note that this connection string may contain sensitive information and should be protected by the application. + +### 3.2.3 New Connection Keywords + +ODBC 4.0 defines the following new Connection string key/value pairs: + +#### 3.2.3.1 `Auth_Type` + +`Auth_Type` defines common types of authentication. Drivers that support multiple types of authentication can request `Auth_Type` in the output connection string returned by BrowseConnect in order to allow the client to select from an enumerated list of authentication mechanisms. + +While the driver can return custom values, the following common values should be used where applicable: + + **Keyword** | **Description** +-------------|--------------- + `None` | No authentication is required; the driver supports anonymous access + `Basic` | Basic authentication using User ID (UID) and Password (PWD) is supported by the driver + `Trusted` | The driver supports connecting using trusted (i.e., Kerberos or NTLM) Authentication. + `OAuth_1.0` | The driver supports an OAuth 1.0 authentication flow, as described in [Web Authorization](#32-web-authorization). + `OAuth_2.0` | The driver supports an OAuth 2.0 authentication flow, as described in [Web Authorization](#32-web-authorization) + `LDAP` | The driver supports authentication through LDAP + +#### 3.2.3.2 `Auth_BaseRedirectUri` + +In a [Web Authorization Flow](#32-web-authorization), the driver may request the application to provide a Uri to be called when the authentication completes. This is typically a URI to an endpoint supported by the application. The driver will construct an [AuthorizationUrl](#3233-authorizationurl) using this callback URL. + +#### 3.2.3.3 `AuthorizationUrl` + +In a [Web Authorization Flow](#32-web-authorization), the driver may provide an AuthorizationUrl that the application must invoke in order to initiate the authorization. + +#### 3.2.3.4 `Auth_CompletedRedirectUri` + +In a [Web Authorization Flow](#32-web-authorization), the driver may ask for a CompletedRedirectUri that is the result of invoking the AuthorizationUrl. This CompletedRedirectUri will generally contain information, i.e. through query string parameters, used by the driver to complete the authorization flow. + +#### 3.2.3.5 `Auth_Client_ID`, `Auth_Client_Secret` + +In a [Web Authorization Flow](#32-web-authorization), the driver may request a Client ID and Client Secret from the application. This information is typically used to construct the [AuthorizationUrl](#3233-authorizationurl) used to initiate authorization. + +#### 3.2.3.6 `Auth_Scope` + +In a [Web Authorization Flow](#32-web-authorization), the driver may request a Scope from the application. The driver may provide an enumerated list of known scopes that the application can pick from, or may allow the application to provide an arbitrary scope. This information is typically used to construct the [AuthorizationUrl](#3233-authorizationurl) used to initiate authorization. + +#### 3.2.3.7 `Auth_Realm` + +In a [OAuth 1.0 Authorization Flow](#32-web-authorization), the driver may request a Realm from the application. This information is typically used to construct the [AuthorizationUrl](#3233-authorizationurl) used to initiate authorization. + +#### 3.2.3.8 `Auth_Token_Secret`. + +In a [OAuth 1.0 Authorization Flow](#32-web-authorization), the driver may request a Secret from the application. This information is typically used to construct the [AuthorizationUrl](#3233-authorizationurl) used to initiate authorization. + +#### 3.2.3.9 `Auth_WindowHeight`, `Auth_WindowWidth` + +In a [Web Authorization Flow](#32-web-authorization), the application may have to provide a window (i.e., through a browser) to collect input from the user. The driver may provide WindowHeight and WindowWidth keywords in the output query string, for example along with the [AuthorizationUrl](#3233-authorizationurl), as hints to the application as to the size of the window to present to the user. + +### 3.2.4 Token Expiration + +Applications can determine whether or not the access token has expired by calling SQLGetConnectAttr with the `SQL_ATTR_CONNECTION_DEAD` attribute. As this connection attribute is also used by the Driver Manager in connection pooling, getting this attribute is performance critical and the driver SHOULD NOT make a round trip to determine the status of the connection, but should return `SQL_CD_TRUE` if it has previously determined that the connection is dead. + +If [SQL_ATTR_REFRESH_CONNECTION](#3252-sql-attr-refresh-connection) is `SQL_REFRESH_MANUAL`, or the driver is unable to refresh the token, attempting to call an operation that requires a connection after the access token has expired returns `SQL_ERROR` with a SQLState value of 08006 (Connection Failure). Applications can attempt to refresh the connection by calling SQLSetConnectAttr with `SQL_ATTR_REFRESH_CONNECTION` and, if successful, retry the failed operation. If refreshing the connection fails, the application must close the connection (resulting in any dependent statement or descriptor handles being implicitly freed) and start over. + +### 3.2.5 Token Refresh + +Access tokens can be refreshed automatically by the driver, or manually by the application. + +#### 3.2.5.1 `SQL_ATTR_CREDENTIALS` + +Applications can retrieve the current connection information, including (for web authorization scenarios) the current access token, along with refresh token and expiration, as appropriate, by calling SQLGetConnectAttr for the new `SQL_ATTR_CREDENTIALS` connection attribute. + +Applications can update credentials by calling SQLSetConnectAttr for `SQL_ATTR_CREDENTIALS` and specifying the value retrieved in a previous call to GetConnectionAttr for `SQL_ATTR_CREDENTIALS` to the same data source. + +This information returned by `SQL_ATTR_CREDENTIALS` is an encoding of the necessary connection information sufficient to create a new connection to the same source by passing to SQLDriverConnect or SQLBrowseConnect, or enable refreshing credentials for the same source by calling SQLSetConnectAttr with the new `SQL_ATTR_CREDENTIALS` connection attribute. + +Note that, while drivers should encode sensitive information within the string, applications should treat the credentials as sensitive information. + +#### 3.2.5.2 `SQL_ATTR_REFRESH_CONNECTION` + +A new connection attribute, `SQL_ATTR_REFRESH_CONNECTION`, is added to allow applications to control how and when drivers refresh a connection. + +If `SQL_ATTR_REFRESH_CONNECTION` is `SQL_REFRESH_AUTO` (the default), the driver attempts to automatically refresh connections (i.e., access token) as required, using the current value of `SQL_ATTR_CREDENTIALS`. Upon successful refresh, the value of `SQL_ATTR_CREDENTIALS` is updated with the new credentials (i.e., access token, and refresh token and expiration, as appropriate.) + +If `SQL_ATTR_CONNECTION` is set to `SQL_REFRESH_NOW`, the driver attempts to refresh the connection (i.e., access token) using the current value of `SQL_ATTR_CREDENTIALS`. Upon successful refresh, the value of `SQL_ATTR_CREDENTIALS` is updated with the new credentials (i.e., access token, and refresh token and expiration, as appropriate.) Setting `SQL_ATTR_CONNECTION` to `SQL_REFRESH_NOW` does an immediate refresh of the connection but does not change the persisted value of connection option. Drivers may, but are not required to, return `SQL_SUCCESS_WITH_INFO` and `01S02`, Optional Value Changed, since the value of `SQL_ATTR_REFRESH_CONNECTION` is not actually changed to the specified value. + +If `SQL_ATTR_REFRESH_CONNECTION` is set to `SQL_REFRESH_MANUAL`, the driver should not attempt to automatically refresh access tokens. + +## 3.3 SQL Syntax Support + +ODBC is designed as an API to provide a common way to connect to, describe, execute a command, and retrieve results from a relational store. ODBC relies on ANSI/ISO SQL to provide a common grammar across relational stores, and supplies a way to report levels of conformance and support for optional syntax elements. + +### 3.3.1 SQL Compliance + +Drivers that support ANSI SQL syntax must follow SQL semantics for that syntax or fail the request. + +### 3.3.2 String escaping + +As per ANSI, a single-quote character within a string literal is escaped by a single-quote character. Drivers must translate double-single quotes to whatever is the native syntax for an escaped single quote. + +### 3.3.3 Nesting Escape Clauses + +Drivers should support nesting of escape clauses, as appropriate (for example, using an escape clause within an expression passed to a scalar function). + +### 3.3.4 SQL Syntax Capabilities + +ODBC Drivers report supported SQL syntax through SQLGetInfo. The following SQLGetInfo information types and values are added to help drivers describe support for additional SQL constructs + +#### 3.3.4.1 Binary Functions + +ODBC 4.0 drivers may support the [canonical string functions](https://msdn.microsoft.com/en-us/library/ms710249(v=vs.85).aspx) against binary strings. + +##### 3.3.4.1.1 `SQL_BINARY_FUNCTIONS` + +A new SQLGetInfo *information type,* `SQL_BINARY_FUNCTIONS`, is added to allow a server to report which of the string functions can be used with binary strings. + +The following new bitmask values may be returned from `SQL_BINARY_FUNCTIONS`: + +`SQL_FN_BIN_BIT_LENGTH`, `SQL_FN_BIN_CONCAT`, `SQL_FN_BIN_INSERT`, `SQL_FN_BIN_LTRIM`, `SQL_FN_BIN_OCTET_LENGTH`, `SQL_FN_BIN_POSITION`, `SQL_FN_BIN_RTRIM`, `SQL_FN_BIN_SUBSTRING` + +Note: Each of these is defined with the same value as their existing `SQL_FN_STR` counterpart. + +##### 3.3.4.1.2 `SQL_ISO_BINARY_FUNCTIONS` + +A new GetInfo *information type*, `SQL_ISO_BINARY_FUNCTIONS`, is added to allow a server to report which of the ANSI SQL Binary functions can be used. + +The following bitmasks are used to determine which string functions are supported. Their values are the same as their `SQL_SFF` counterparts for `SQL_SQLSTRING_FUNCTIONS`. + +`SQL_SBF_CONVERT`, `SQL_SBF_SUBSTRING`, `SQL_SBF_TRIM_BOTH`, `SQL_SBF_TRIM_LEADING`, `SQL_SBF_TRIM_TRAILING`, `SQL_SBF_OVERLAY`, `SQL_SBF_LENGTH`, `SQL_SBF_POSITION`, `SQL_SBF_CONCAT` + +#### 3.3.4.2 `SQL_ISO_STRING_FUNCTIONS` + +A new SQLGetInfo *information type*, `SQL_ISO_STRING_FUNCTIONS`, is added to allow a server to report which of the ANSI SQL String functions can be used. Its value is equal to the existing `SQL_SQL92_STRING_FUNCTIONS`. Values are the existing `SQL_SSF` values from `SQL_SQL92_STRING_FUNCTIONS`, plus the following values: + +`SQL_SSF_OVERLAY`, `SQL_SSF_LENGTH`, `SQL_SSF_POSITION`, `SQL_SSF_CONCAT` + +#### 3.3.4.3 `SQL_SQL92` Equivalents + +The following SQLGetInfo *information type*s are defined equivalent to existing `SQL_SQL92` defines, but not specific to SQL92: + + SQL_ISO_DATETIME_FUNCTIONS = SQL_SQL92_DATETIME_FUNCTIONS + SQL_ISO_FOREIGN_KEY_DELETE_RULE = SQL_SQL92_FOREIGN_KEY_DELETE_RULE + SQL_ISO_FOREIGN_KEY_UPDATE_RULE = SQL_SQL92_FOREIGN_KEY_UPDATE_RULE + SQL_ISO_GRANT = SQL_SQL92_GRANT + SQL_ISO_NUMERIC_VALUE_FUNCTIONS = SQL_SQL92_NUMERIC_VALUE_FUNCTIONS + SQL_ISO_PREDICATES = SQL_SQL92_PREDICATES + SQL_ISO_RELATIONAL_JOIN_OPERATORS = SQL_SQL92_RELATIONAL_JOIN_OPERATORS + SQL_ISO_REVOKE = SQL_SQL92_REVOKE + SQL_ISO_ROW_VALUE_CONSTRUCTOR = SQL_SQL92_ROW_VALUE_CONSTRUCTOR + SQL_ISO_VALUE_EXPRESSIONS = SQL_SQL92_VALUE_EXPRESSIONS + +#### 3.3.4.4 Added `SQL_AGGREGATION_FUNCTIONS` bitmasks + +The following bitmasks are added to `SQL_AGGREGATION_FUNCTIONS` to advertise support for additional ANSI SQL-defined aggregation functions: + +| **BitMask** | **ANSI SQL Function** | +|-----------------------|-----------------------| +| `SQL_AF_EVERY` | EVERY | +| `SQL_AF_ANY` | ANY | +| `SQL_AF_STDEV_OP` | STDEV\_OP | +| `SQL_AF_STDEV_SAMP` | STDEV\_SAMP | +| `SQL_AF_VAR_SAMP` | VAR\_SAMP | +| `SQL_AF_VAR_POP` | VAR\_POP | +| `SQL_AF_ARRAY_AGG` | ARRAY\_AGG | +| `SQL_AF_COLLECT` | COLLECT | +| `SQL_AF_FUSION` | FUSION | +| `SQL_AF_INTERSECTION` | INTERSECTION | + +`SQL_AF_EVERY` is a synonym for the current `SQL_AF_ALL`. + +#### 3.3.4.5 Added Scalar Function bitmasks + +Todo… + +### 3.3.5 Language Extensions + +For common constructs that are not part of SQL-92 (i.e., outer joins, function execution, datetime literals), ODBC defines escape clauses as a way to embed functionality within native commands that can easily be scanned, tweaked, and then passed-through to the back-end. These escape clauses provide a level of interoperability for basic operations while allowing clients familiar with a native syntax to leverage constructs within that syntax. + +The following new ODBC escape clauses are added to the ODBC grammar. These clauses are not dependent upon the version of ODBC; applications determine support for the clauses through SQLGetInfo. + +#### 3.3.5.1 Limit Clause + +Interactive applications typically need a way to “preview” results, for example by showing the first n rows. Applications may also “page” by selecting the next n rows after skipping m. + +Different databases support this through different syntax (top, first, skip, start, fetch first, limit, etc.) ANSI SQL 2003 defines window functions for defining a `ROW_NUMBER` that can then be filtered on and then selected out. + +ODBC adds a new *ODBC-limit-escape*, defined as follows: + +*ODBC-limit-escape* ::= +     *ODBC-esc-initiator* limit \[*skip-value comma*\] *take-value ODBC-esc-terminator* + +Where *skip-value* is an integer specifying the number of rows to skip and *take-value* is an integer specifying the number of rows to return. + +The optional *ODBC-limit-escape* clause immediately follows the *order-by-clause*, if present. + +For example: + +>Select \* from table {limit 10} + +would fetch the first ten rows of the table, while + +>Select \* from table {limit 20,10} + +would skip twenty rows and then fetch the next ten. + +Drivers advertise support for this escape clause through the new `SQL_LIMIT_ESCAPE_CLAUSE` *InfoType*. The value of the `SQL_LIMIT_ESCAPE_CLAUSE` is a bitmask made up of the following values: + +* **SQL\_LC\_NONE** = 0x00000000L – the driver has no support for the limit escape clause +* **SQL\_LC\_TAKE** = 0x00000001L - the driver supports only the take portion of the limit escape clause +* **SQL\_LC\_TAKE\_AND\_SKIP** = 0x00000003L – the driver supports both take and skip in the limit escape clause + +#### 3.3.5.2 Selecting Inserted Updated and Deleted Values + +The *ODBC-return-escape* clause returns a table containing information from inserted, updated, and deleted records: + +*ODBC-return-escape* ::= +     *ODBC-esc-initiator* return *select-list* from '*vendor-dml-statement*' *ODBC-esc-terminator* + +For Inserts and Updates, the returned values are the values of the affected rows following the insert or update operation. For delete operations, the returned values represent the values of the rows at the time they were deleted. + +If no rows are affected by the statement, an empty result is returned. + +For example, the following statement returns a table containing the columns named "OrderId", "Item" and "Total" of a newly inserted row: + +> {return OrderId, Item, Total from 'INSERT INTO Orders(Item, Price, Quantity) VALUES (''San Juan Islands Map'',24,2)'} + +The following statement retrieves the new total of all rows with ids above 10 that were updated: + +> {return total from 'UPDATE table SET amount=amount\*10 WHERE id > 10'} + +The *ODBC-return-escape* should not be used as a nested query within another statement. + +Single quotation marks within *vendor-dml-statement* must be doubled. The driver replaces two adjacent single quotations marks within the dml statement with a single quotation mark. A single quotation mark terminates the dml statement. + +If an array of parameter values is specified, then whether there is a result set for each set of parameter values or a single result that merges the results from each set of parameter values is defined by the `SQL_PARAM_ARRAY_SELECTS` SQLGetInfo *InfoType*. + +If multiple rows are specified in an INSERT INTO...VALUES statement, or an array of parameter values are specified, then the order of rows returned matches the order of values specified. In all other cases, the order of returned rows is indeterminate. + +The driver may limit the columns in the select-list to include only the best row id columns returned by SQLSpecialColumns, as specified in the `SQL_RETURN_ESCAPE_CLAUSE` *InfoType*. + +If the application requests columns that don't exist in the row and [`SQL_ATTR_DYNAMIC_COLUMNS`](#391-SQL_ATTR_DYNAMIC_COLUMNS) is *false*, or the driver only supports returning row id columns and the client specifies non-row id columns in the *select-list*, the driver returns `42S22` Column not found. + +Drivers advertise support for this escape clause through the `SQL_RETURN_ESCAPE_CLAUSE` *InfoType* whose value is a bitmask made up of the following values. + +| Value | Description | +|--------------------------------|---------------------------------------------------------------------| +| `SQL_RC_NONE` = 0 | The driver has no support for the return escape clause | +| `SQL_RC_INSERT_SINGLE_ROWID` | The driver supports returning row id fields for a single row from an INSERT INTO...VALUES statement | +| `SQL_RC_INSERT_SINGLE_ANY` | The driver supports returning any fields for a single row from an INSERT INTO...VALUES statement | +| `SQL_RC_INSERT_MULTIPLE_ROWID` | The driver supports returning row id fields for multiple rows from an INSERT INTO...VALUES statement | +| `SQL_RC_INSERT_MULTIPLE_ANY` | The driver supports returning any fields for multiple rows from an INSERT INTO...VALUES statement | +| `SQL_RC_INSERT_SELECT_ROWID` | The driver supports returning row id fields from an INSERT INTO...SELECT statement | +| `SQL_RC_INSERT_SELECT_ANY` | The driver supports returning any fields from an INSERT INTO...SELECT statement | +| `SQL_RC_UPDATE_ROWID` | The driver supports returning row id fields from an UPDATE statement | +| `SQL_RC_UPDATE_ANY` | The driver supports returning any fields from a UPDATE statement | +| `SQL_RC_DELETE_ROWID` | The driver supports returning row id fields from a DELETE statement | +| `SQL_RC_DELETE_ANY` | The driver supports returning any fields from a DELETE statement | +| `SQL_RC_SELECT_INTO_ROWID` | The driver supports returning row id fields from a SELECT INTO statement | +| `SQL_RC_SELECT_INTO_ANY` | The driver supports returning any fields from a SELECT INTO statement | + +#### 3.3.5.3 Format Clause + +The *ODBC-format-escape* clause enables clients to return results as a JSON-formatted string. + +*ODBC-format-escape* ::= *ODBC-esc-initiator* RETURNING *data-type* *json-format-clause* *ODBC-esc-terminator* + +*json-format-clause* ::= FORMAT JSON \[ENCODING {UTF8 | UTF16 | UTF32}\] + +For results returned as JSON, *data-type* must be a character string or binary type. If ENCODING is specified, then *data-type* must be a binary type. + +Drivers advertise support for this escape clause through the `SQL_FORMAT_ESCAPE_CLAUSE` *InfoType* whose value is a bitmask made up of the following values. + +| Value | Description | +|------------------------------------|-------------------------------------------------------------------| +| `SQL_FC_NONE` = 0x00000000L | The driver has no support for the format escape clause | +| `SQL_FC_JSON` = 0x00000001L | The driver supports returning results as a JSON character string | +| `SQL_FC_JSON_BINARY` = 0x00000002L | The driver supports returning results as a JSON binary string | + +#### 3.3.5.4 Native Syntax + +ODBC clients use the `SQL_NOSCAN` statement attribute to specify that the command text is in a native syntax and should not be parsed by the driver. In this case, the entire statement must be in a native syntax and escape clauses must not be used as the driver will not scan the statement but instead pass it directly to the server. + +The *ODBC-native-escape* clause enables clients to embed native syntax within a SQL92 statement: + +*ODBC-native-escape* ::= *ODBC-esc-initiator* native '*command-text*' \[*passing-clause*\] \[*results-clause*\] *ODBC-esc-terminator* + +*passing-clause* ::= PASSING ( *argument-definition* \[, *argument-definition*\]… ) + +*argument-definition* ::= *argument-value* \[(*native-type*\)] \[AS *identifier*\] + +*argument-value* ::= *literal* | *parameter-marker* | *expression* + +*results-clause* ::= *columns-clause* | *scalar-returning-clause* + +*columns-clause* ::= COLUMNS ( *field-definition* \[, *field-definition*\]… ) + +*scalar-returning-clause* ::= RETURNING *type* \[*json-format-clause*\] + +*type* ::= {*data-type* | ROW ( *field-definition* \[, *field-definition*\]… ) } \[ARRAY | MULTISET\] + +*field-definition* ::= *field-name type* + +Where *command-text* is a textual query in the native language of the service, and *native-type* is the native type of the argument. If *native-type* is not provided, the driver should attempt to use a default type (generally string) which may fail if the native syntax is unable to perform the necessary conversion. + +Whether arguments in the *passing-clause* must be named is dependent upon the underlying native syntax. + +The *results-clause* is required for retrieving results from the native syntax and when embedding the native syntax in place of a query expression within a standard SQL statement. + +If *json-format-clause* is specified, *type* must be a string or binary type. + +Single quotation marks within the native syntax must be doubled. The driver replaces two adjacent single quotations marks within the native syntax with a single quotation mark. A single quotation mark terminates the native command text. + +Drivers advertise support for this escape clause through the new `SQL_NATIVE_ESCAPE_CLAUSE` *InfoType* whose value is the character string “`Y`” if the escape clause is supported; “`N`” otherwise. + +#### 3.3.5.5 Refresh Schema + +The *ODBC-refresh-schema-escape* clause to enable clients to request that schema be refreshed, defined as follows: + +*ODBC-refresh-schema-escape* ::= +     *ODBC-esc-initiator* refresh \[*sql-identifier*\[, *sql-identifier*\]\*\] *ODBC-esc-terminator* + +The optional list of sql-identifiers provide a hint to the driver as to the specific objects from the information schema objects (tables, udts, etc.) that should be refreshed. The driver is always allowed to refresh additional schema objects, particularly in the case where the tables/udts/etc are virtualized based on a non-relational view. + +#### 3.3.6 SAFECONVERT + +The SAFECONVERT function, which can be invoked using the function escape clause, safely converts an expression to a given type. + +SAFECONVERT ( *value-exp*, *data-type* ) + +The result of the SAFECONVERT function is the value of *value-exp* converted to *data-type*, where *data-type* is one of the keywords listed for the CONVERT function. If the value of *value-exp* cannot be converted to *data-type*, the result is null. + +The SAFECONVERT function supports the same set of conversions as the CONVERT function (as reported by SQLGetInfo). + +#### 3.3.7 TYPEOF + +The TYPEOF function, which can be invoked using the function escape clause, returns the type name of an expression. + +TYPEOF ( *value-exp* ) + +#### 3.3.8 SQLTYPEOF + +The SQLTYPEOF function, which can be invoked using the function escape clause, returns the canonical SQLTYPE name of an expression, which can be used in [SAFECONVERT](#336-SAFECONVERT). + +SQLTYPEOF ( *value-exp* ) + +#### 3.3.9 SAFECAST + +The SAFECAST function, which can be invoked using the function escape clause, allows an expression to be treated as the specified user-defined or datasource-specific type. + +SAFECAST ( *value-exp*, *data-type-name* ) + +The result of the SAFECAST function is the value of *value-exp* converted to *data-type-name*, where *data-type-name* is datasource-specific type, or the fully qualified name of a user defined or structural type. If the value of *value-exp* cannot be converted to *data-type-name*, the result is null. + +### 3.3.10 Added Reserved Words + +The following are added to the list of ODBC reserved words: + +* ARRAY +* MULTISET +* ROW + +## 3.4 String Format + +A new SQLCHAR\*-valued descriptor field, `SQL_DESC_MIME_TYPE`, is added to \[ALL\] descriptors to specify the format of a field or parameter whose `SQL_DESC_TYPE` specifies a string or binary type. The value of this descriptor field is the mime type of the data (i.e., application/json, application/xml,…), or an empty string if the field or parameter is not a string or binary type, or if the format is not known. + +## 3.5 Schema Inference + +Schema can be inferred over a schema-less source, such as a JSON, XML, or CSV document, to expose a standard relational view over the data. + +### 3.5.1 `SQL_SCHEMA_INFERENCE` GetInfo + +Drivers that support schema inference return `SQL_TRUE` when an application calls SQLGetInfo with the new `SQL_SCHEMA_INFERENCE` *InfoType*. + +### 3.5.2 `SQL_ATTR_INFERENCE_ACCURACY` Connection Attribute + +A new connection attribute, `SQL_ATTR_INFERENCE_ACCURACY`, whose value is an integer between 1-100, is added to support schema inference by the driver. + +Setting this attribute to 100 means that all rows should be read in order to ensure that the inference is accurate for every row in the result. + +Setting this attribute to zero specifies that the driver should not infer schema. In this case, a driver that does not have an explicit way to determine schema returns an empty result when calling SQLColumns, and every column is treated as a [dynamic column](#39-dynamic_columns). Applications can then do their own sampling of the data, and can impose column types in their queries using CONVERT. + +A value between 1 and 99 gives an approximate estimation of the quality of the inference. The driver may adjust the number of rows sampled, the method of sampling, or how specific of a type or length to infer based on this setting. + +Setting this attribute (including setting to its current value) forces the driver to re-infer schema. + +Attempting to get or set this attribute for drivers that do not support schema inference returns `SQL_ERROR` with a diagnostic code of HYC00, Optional feature not implemented. + +## 3.6 Getting Data during Fetch + +In ODBC 3.x, applications read large data values by placing them at the end of the select list and calling SQLGetData after all bound columns have been populated. + +Applications can efficiently retrieve large data values (such as potentially large string or binary values, nested collections, and structured columns) that appear in any order by setting the [`SQL_DESC_DATA_AT_FETCH`](#361-sql_desc_data_at_fetch-descriptor-field) descriptor field to `SQL_TRUE` for columns to be retrieved as they become available during the fetch operation. The application is notified during the fetch operation when data-at-fetch columns are available to be retrieved via SQLGetData, or a nested statement handle for nested collections and structured columns. + +In order to be notified when an unbound column is available to be retrieved during the fetch operation: + +1. The application binds all columns to be fetched directly into bound buffers. Binding a column automatically sets the `SQL_DESC_DATA_AT_FETCH` value to `SQL_FALSE`. + +2. For each column to be retrieved at fetch time, the application calls SQLSetDescField, specifying `SQL_DESC_DATA_AT_FETCH` with a value of `SQL_TRUE`. Setting `SQL_DESC_DATA_AT_FETCH` to `SQL_TRUE` for a column automatically unbinds the column by setting the `TargetValuePtr` to null. + +3. For nullable columns, the application sets `SQL_DESC_INDICATOR_PTR` so that the driver can signal a null value for the column. + +4. The application calls SQLFetch/SQLFetchScroll + - Driver begins populating the bindings + - Driver returns `SQL_DATA_AVAILABLE` from SQLFetch/SQLFetchScroll to signal data-at-fetch columns are available. + - Calling SQLCloseCursor (or SQLFreeStmt(SQL_CLOSE)) in the `DATA_AVAILABLE` state cancels the fetch operation and closes the cursor. + +5. The application calls SQLNextColumn to find out which column is available. Applications must not assume that the columns are returned in any particular order. + - Driver returns the ordinal of the available column + - For rowset sizes greater than 1, the row for which the column is available can be determined through the `SQL_ATTR_ROWS_FETCHED_PTR` statement attribute. The driver must populate the rows of a given column in order, but the client cannot assume that any other columns have been populated until the entire fetch sequence has completed and the initial fetch or a subsequent call to SQLNextColumn returns a value other than `SQL_DATA_AVAILABLE`. + - The following operations are valid in a `SQL_DATA_AVAILABLE` state. For any other operations on a statement handle in the `SQL_DATA_AVAILABLE` case, the DM returns HY010, function sequence error. + - Changing binding information in the ARD for the current column* + - Calling SQLGetData for the current column* (if not structured or a nested collection) + - Calling SQLGetNestedHandle for the current column* (if structured or a nested collection) + - Attempting to fetch from a nested handle associated with the current column* + - Calling SQLCloseCursor + - Calling SQLNextColumn + - Calling SQLFetch/SQLFetchScroll + - Calling SQLDescribeCol/SQLGetDescField/SQLGetDescRecord + + *The Driver Manager returns SQLState 07009, Invalid descriptor index, if the application attempts to call SQLBindCol, SQLSetDescField, SQLSetDescRecord in the `DATA_AVAILABLE` case for a column other than the current column, or if SQLGetData or SQLGetNestedHandle is called for a column other than the current column and the driver does not support SQL_GD_ANY_ORDER. + - Applications SHOULD NOT change the offset value indicated by SQL_DESC_BIND_OFFSET_PTR while in a `SQL_DATA_AVAILABLE` state. As the driver can populate columns and indicators in any order until the fetch operations completes, changing this value while in a `SQL_DATA_AVAILABLE` state has indeterminate affects. + +6. The app can update the binding information for the current column only, which will used when populating subsequent rows for the given column. Note that changing the binding has no affect on previously populated rows. + +7. App typically retrieves the data for the current column by calling SQLGetData, or by reading data from the nested handle, as appropriate. + +8. App calls [SQLNextColumn](#61-sqlnextcolumn) to continue fetching the current row + - Any nested handles on the same statement are closed, unless [`SQL_GD_CONCURRENT`](#361-sql_gd_concurrent-bit-for-sql_getdata_extensions) is specified (in which case any nested handles are closed upon the next call to fetch or close cursor on the parent statement handle.) + - Driver returns `SQL_DATA_AVAILABLE`, along with the ordinal of the next column available to be retrieved, if additional columns are available + - Driver returns `SQL_SUCCESS` or `SQL_SUCCESS_WITH_INFO` when all bound or data-at-fetch columns have been retrieved. The application must not assume any bindings or diagnostic information associated with the fetch has been populated until SQLNextColumn returns `SQL_SUCCESS` or `SQL_SUCCESS_WITH_INFO`, or `SQL_ERROR`. + +9. App can call SQLGetData, or retrieve nested data, for additional columns beyond the last column retrieved, or subject to the ordering constraints of the driver. + +### 3.6.1 `SQL_DESC_DATA_AT_FETCH` descriptor field + +A new application row descriptor (ARD) field, `SQL_DESC_DATA_AT_FETCH`, is added to specify that a column is to be retrieved through a `SQL_DATA_AVAILABLE` state at fetch time. + +- `SQL_FALSE` (default) specifies that the driver will return data for the column directly to the application's buffer if a binding is specified +- `SQL_TRUE` specifies that the driver will return `SQL_DATA_AVAILABLE` when reading the column. Setting `SQL_DESC_DATA_AT_FETCH` to `SQL_TRUE` for a column automatically unbinds the column by setting the `TargetValuePtr` to null. + +Binding a column (through SQLBindCol or by setting the `SQL_DESC_DATA_PTR` to a non-null value) sets the `SQL_DESC_DATA_AT_FETCH` value to `SQL_FALSE`. + +For nullable columns, clients should also specify *SQL\_DESC\_INDICATOR\_PTR* for the driver to indicate that the value of the data-at-fetch parameter is null. If *SQL\_DESC\_INDICATOR\_PTR* is not specified for a column whose value is null, the driver returns an error with SQLState `22002`, Indicator variable required but not supplied. + +### 3.6.2 `SQL_GD_CONCURRENT` bit for `SQL_GETDATA_EXTENSIONS` + +A new SQL GetData Extension, `SQL_GD_CONCURRENT`, is added. + +If the driver reports `SQL_GD_CONCURRENT`, fetching partial data from one column (using SQLGetData) or on a nested statement handle does not affect the position or state of any other column or nested handle. If the driver specifies `SQL_GD_ANY_ORDER` and does not specify `SQL_GD_CONCURRENT`, calling SQLGetData or retrieving data from a nested handle resets the position of any columns previously fetched using SQLGetData to the beginning and closes the cursor (but does not automatically free the hstmt) of any previously fetched nested columns for this row. + +Note that SQL_GD_CONCURRENT does not imply that the driver supports multiple concurrent asynchronous requests associated with the same parent statement handle. The root statement handle defines the scope for concurrent asynchronous operations. + +## 3.7 Variable Typed Columns +Variable typed columns are columns whose type is unknown or may change on a row-by-row basis. + +### 3.7.1 Schema Extensions for Variable Typed Columns + +Columns whose type may vary across rows are described to ODBC 4.0 clients using the `SQL_VARIANT_TYPE` value for `DATA_TYPE` and `SQL_DATA_TYPE` in SQLColumns, and for the `SQL_DESC_TYPE` and `SQL_DESC_CONCISE_TYPE` descriptor fields when describing a result prior to fetching the first row. The `SQL_VARIANT_TYPE` data type must not be used in SQLColumns, or returned in a parameter or row descriptor, for ODBC 3.5 and earlier clients. + +### 3.7.2 Query Extensions for Variable Typed Columns + +Variable typed columns used in expressions should first be cast to an appropriate operand type. The [SAFECONVERT](#336-safeconvert) canonical function can be used to safely cast the variable typed column to the expected type, or null if the column cannot be cast to the expected type. + +The [TYPEOF](#337-TYPEOF) canonical function can be used to get the type name returned by a given expression. + +The [SQLTYPEOF](#338-SQLTYPEOF) canonical function can be used to get the name of the SQLTYPE returned by a given expression, which can be used in SAFECONVERT. + +### 3.7.3 Response Extensions for Variable Typed Columns + +The application can attempt to set the type information in the IRD to an "expected" type. Drivers SHOULD accept setting the IRD for variable type columns but MAY return an error if the type information for the column is a known, fixed type. + +As data is read for a row, the IRD for each variable typed column is updated to reflect the actual type information for the current row. Columns whose `SQL_DESC_TYPE` or `SQL_DESC_CONCISE_TYPE` descriptor fields indicate `SQL_VARIANT_TYPE` are updated to reflect the actual type of the data to be read. + +Depending on the value of [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-sql_attr_type_exception_behavior), if the descriptor is changed by the driver when reading a column the driver may return `SQL_METADATA_CHANGED`. + +Upon receiving `SQL_METADATA_CHANGED`, the application can call SQLNextColumn to determine the index of the column that has changed, get the current information for that column, adjust bindings for the subsequent fetches of the current column only (including setting the IRD to the "expected" type), and can call SQLGetData or SQLGetHandle, as appropriate for the type of the column. Any changes to the descriptor record persist for future uses of that descriptor across rows. + +Note that SQLGetData starts at the beginning of the value and reads sequentially until all bytes have been consumed. If a conversion failure occurs after the first call to SQLGetData, the rest of the data for that column will not be retrievable. + +The application calls SQLNextColumn to continue fetching values for any remaining columns in the row. The application must not assume any bindings or diagnostic information associated with the fetch have been populated until SQLNextColumn returns `SQL_SUCCESS` or `SQL_SUCCESS_WITH_INFO`, or `SQL_ERROR`. + +Output parameters that are bound with a type of `SQL_VARIANT_TYPE` MUST be bound as data-at-exec parameters. When executing a statement that contains data-at-exec output parameters, the driver returns `SQL_PARAM_DATA_AVAILABLE`. The application calls SQLParamData to find out which parameter is available and then calls SQLGetData or SQLGetNestedHandle for that parameter, as appropriate. + +#### 3.7.3.1 `SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR` + +`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR` is a `SQLUSMALLINT` value that allows the client to control how type exceptions occur when retrieving bound values. It does not affect SQLGetData. + +* **SQL\_TE\_ERROR** – (Default) Return an error if the data value is incompatible with the bound type. +* **SQL\_TE\_CONTINUE** – Set the `str_type_or_ind_ptr` value (if not null) to `SQL_TYPE_EXCEPTION` if the data value is incompatible with the bound type and continue, or error if `str_type_or_ind_ptr` is a null pointer. +* **SQL\_TE\_REPORT\_EXCEPTION** – Set the `str_type_or_ind_ptr` value (if not null) to `SQL_TYPE_EXCEPTION` if the data value is incompatible with the bound type and return `SQL_METADATA_CHANGED`. The application can retrieve the value for the column using SQLGetData or SQLGetNestedHandle, as appropriate. SQLGetNestedHandle will always return a fresh statement handle for a structured- or collection-valued column whose IRD has changed. The application can update the binding for this column which will used when populating subsequent rows for the given column. Changing binding information has no affect on previously fetched values. +* **SQL\_TE\_REPORT\_ALL** – Set the `str_type_or_ind_ptr` value (if not null) to `SQL_TYPE_EXCEPTION` and return `SQL_METADATA_CHANGED` if the data value is incompatible with the bound type, or if the type information in the IRD (for rows) or IPD (for parameters) has changed. The application can retrieve the value for the column using SQLGetData or SQLGetNestedHandle, as appropriate. The application can update the binding for this column which will used when populating subsequent rows for the given column. Changing binding information has no affect on previously fetched values. + +### 3.7.4 Write Extensions for Variable Typed Columns + +Applications can use the CONVERT scalar function to specify a SQL_TYPE to be used when setting the value for a variable-typed column in an INSERT or UPDATE statement. In the absence of a CONVERT, the driver will store the value in an appropriate type given the value specified in the INSERT or UPDATE statement for the variable-typed column. + +Applications can pass variable-typed parameters at execute time by setting the ParameterType in SQLBindParameter, or `SQL_DESC_TYPE` in the IPD, to `SQL_VARIANT_TYPE`, and `StrLen_or_IndPtr` to indicate `SQL_DATA_AT_EXEC`. + +After calling SQLExecute or SQLExecDirect, the driver returns `SQL_NEED_DATA` for any data-at-exec input parameters. The application calls SQLParamData to discover which parameter the driver is ready to process. + +For input data-at-exec parameters, the application fills in the IPD to specify the type of the parameter (including the SQL_DESC_TYPE_NAME for UDTs) and calls SQLPutData or SQLGetNestedHandle, as appropriate, to send the information for the current parameter. + +The application calls SQLParamData to continue processing any remaining parameters, using the information in the IPD but ignoring any bound value if SQPutData or SQLGetNestedHandle has been called for this parameter. + +### 3.7.5 Data Definition Extensions for Variable Typed Columns + +Clients can call SQLGetTypeInfo with a *DataType* value of `SQL_VARIANT_TYPE` to determine the implementation-specific name of any types that can be used to hold variable-typed data. + +## 3.8 Variable Length Columns + +ODBC 4.0 drivers report the expected size of string and binary columns in SQLColumns. Applications generally base the allocation of bound buffers on this size. + +In some cases, the size of the data may exceed the length of the bound buffer. In this case, the application has the option of ignoring the extra data as in ODBC 3.x (the driver returns 01004, String data right truncated) or having the driver return `SQL_MORE_DATA` at fetch time, based on the value of the [`SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR`](#381-sql_attr_length_exception_behavior) statement attribute. + +When the length of data exceeds the bound buffer for string or binary data, and the application has set `SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR` to `SQL_LE_REPORT`, the driver populates as much data as fits in the allocated buffer, sets `str_len_or_ind_ptr` to indicate the total amount of data available, if known, or `SQL_NO_TOTAL` if the driver does not know how much additional data is to be written, and returns `SQL_MORE_DATA`. The application then calls SQLNextColumn in order to determine the column of partially fetched data. At this point the application can call SQLGetData in order to retrieve the remainder of the string or binary data. The application calls SQLNextColumn in order to continue processing additional columns. + +### 3.8.1 `SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR` + +The new `SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR` is a `SQL_USMALLINT` value that allows the client to control how string and binary overflows are handled when retrieving bound values. + +* **SQL\_LE\_CONTINUE** – (Default) For string or binary values larger than the bound buffer length, set the `str_type_or_ind_ptr` value to the total length available, if known, otherwise `SQL_NO_TOTAL`. When the driver completes fetching the row/executing the statement it will return `SQL_SUCCESS_WITH_INFO` with a `SQLSTATE` of `01004`, String data, right truncated. +* **SQL\_LE\_REPORT** – Return `SQL_MORE_DATA` when the string or binary value of a row or parameter does not fit the bound buffer. The application can use SQLNextColumn to determine the column with additional data available, and can call SQLGetData to retrieve the remainder of the column/output parameter using the `SQL_ARD_TYPE` or `SQL_APD_TYPE` (or the equivalent C type), as appropriate. The application then calls SQLNextColumn or SQLParamData, as appropriate, to continue processing. + +## 3.9 Dynamic Columns + +Columns that are known and consistent across rows are exposed in SQLColumns. Applications can bind to these columns in the regular way. + +ODBC is extended to support dynamic columns (columns not returned in SQLColumns). The set of such “Dynamic” columns may vary in order, type, or existence from row to row. + +Dynamic columns are discovered by the application when retrieving results. + +A table may be entirely unschematized (in which case SQLColumns returns an empty result set) or partially schematized (in which case SQLColumns returns the columns that are known and consistent across rows). + +### 3.9.1 `SQL_ATTR_DYNAMIC_COLUMNS` Statement Attribute + +The new `SQL_ATTR_DYNAMIC_COLUMNS` statement attribute controls whether or not additional, dynamic columns may be returned for unbounded select results. + +The default for this statement attribute is *False*. + +Data sources with fixed schemas always return *False* for this value. Attempting to set this value for such a data source returns `SQL_SUCCESS_WITH_INFO` with a diagnostic code of 01S02, Option Value Changed, and reading this value will continue to return *False*. + +If set to *True*, SQLFetch, SQLFetchScroll and SQL_NextColumn return `SQL_DATA_AVAILABLE` if new columns are discovered/added to the IRD while retrieving results. + +If `SQL_ATTR_DYNAMIC_COLUMNS` is *True*, then bound columns in the ARD that don’t apply to the current row have their `len_or_ind_ptr` set to `SQL_DATA_UNAVAILABLE`. If `SQL_ATTR_DYNAMIC_COLUMNS` is *False*, then only known columns are allowed in a select list and only known columns are returned when \* is specified. + +Applications may change `SQL_ATTR_DYNAMIC_COLUMNS` from to *True* to *False* at any time to ignore dynamic columns. Attempting to change `SQL_ATTR_DYNAMIC_COLUMNS` from *False* to *True* on a statement handle with an open cursor results in HY010, Function Sequence Error (raised by the Driver Manager). + +### 3.9.2 Schema Extensions for Dynamic Columns + +If [`SQL_ATTR_DYNAMIC_COLUMNS`](#391-SQL_ATTR_DYNAMIC_COLUMNS) is *True*, tables that support properties not defined in SQLColumns are returned from SQLTables using the new `“OPEN TABLE”` table type. If `SQL_ATTR_DYNAMIC_COLUMNS` is *False*, such tables are returned with a table type of `"TABLE"`. + +### 3.9.3 Query Extensions for Dynamic Columns + +A fully explicit select-list (i.e., anything that doesn't contain \*) imposes a structure on the results. Such results only contain the specified columns. When `SQL_ATTR_DYNAMIC_COLUMNS` is *True*, a select list that includes \* also includes any dynamic (unschematized) columns. Dynamic columns must be explicitly included in the select-list in order to be referenced by name or ordinal in the order-by clause. + +Structured columns specified in a select list implicitly select all columns (declared and dynamic) of the structured type. + +For OPEN TABLEs, any valid identifier for the driver is allowed as a column reference in a SQL Statement (select-list, expression in a where-clause, etc.). If more than one column-source is in scope, any references to unschematized columns MUST be qualified with the row source. Columns that aren’t defined for a particular row are considered null in evaluating the expression. Such columns in a select list or an expression are treated as [variable typed columns](#37-Variable-Typed-Columns). + +For tables not reported as open (including all tables for pre-ODBC 4.0 clients), it remains an error to reference an undefined column. + +### 3.9.4 Response Extensions for Dynamic Columns + +Result descriptor functions (SQLNumResultCols, SQLDescribeCol, SQLColAttribute(s), SqlGetDescField/Rec) called before the first call to SQLFetch/SQLFetchScroll describe the known/fixed schema columns (i.e., those explicitly selected, or those defined in schema if \* is specified in the select list). After that, these functions reflect the columns discovered so far. The driver appends records to the IRD as the application reads data to describe dynamic columns not explicitly selected or defined in schema. Once discovered, a column is added to the IRD for the lifetime of the IRD. + +#### 3.9.4.1 Retrieving Dynamic Columns + +If `SQL_ATTR_DYNAMIC_COLUMNS` is set to *True*, the driver can return dynamic columns as data-at-fetch columns when fetching a row. + +Dynamic (unschematized) columns are identified by name. If the driver encounters a dynamic column that does not match the name of an existing unschematized IRD record not previously used for this row, the driver: + +1. Creates a new IRD record for the column; this becomes a new, unbound column in the result. The application must bind the column, or set the [`SQL_DESC_DATA_AT_FETCH`](#361-sql_desc_data_at_fetch-descriptor-field) descriptor field to `SQL_TRUE`, in order to retrieve the value in subsequent calls to SQLFetch. +Once added to the IRD, dynamic columns become "known columns". If the type and length information for a known dynamic column changes on subsequent rows, the driver should use the same IRD record and return SQL_METADATA_CHANGED based on the [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR). Note, however, that applications must continue to be prepared to deal with multiple IRD records with the same name, and the driver must create a new IRD record if a dynamic column with the same name has already been returned for the current row. +Once added, the descriptor fields are a permanent part of the descriptor until it is freed. + +2. Returns `SQL_DATA_AVAILABLE` from SQLFetch or SQLFetchScroll + + 1. Application calls [SQLNextColumn](#61-sqlnextcolumn) to retrieve the ordinal of the descriptor record that describes the column. + + 2. The application optionally retrieves the data using SQLGetData or a nested handle, as appropriate. + + 3. The application can optionally bind the column which will used when populating subsequent rows for the given column. Note that changing binding information has no affect on previously fetched values. + + 3. Application calls SQLNextColumn to continue fetching the current row. + +Once discovered, dynamic columns can be bound like any other column. If a bound dynamic column does not exist for a row, the driver sets its `str_len_or_indicator_ptr` to `SQL_DATA_UNAVAILABLE`. If `str_len_or_indicator_ptr` is null for such a bound dynamic column that doesn't exist for the current row, SQLFetch, SQLFetchScroll, or SQLNextColumn returns an error (22002, Indicator variable required but not supplied). + +If the driver returns `SQL_DATA_AVAILABLE`, the application must not assume that any bound columns have been populated, regardless of their ordinal, or that any diagnostic information associated with the fetch has been populated, until the entire fetch operation completes with `SQL_SUCCESS` or `SQL_SUCCESS_WITH_INFO`, or `SQL_ERROR`. + +### 3.9.5 Write Extensions for Dynamic Columns + +Open Tables may support inserting or updating dynamic columns. + +To create/update dynamic columns, clients can specify column names outside of those returned in SQLColumns in the column list for an insert/update statement. An Insert or Update statement that specifies an unschematized column adds a dynamic column for that row in the table. Setting the value of a dynamic column to null removes that column from that row. + +## 3.10 Structured Columns + +ODBC 4.0 adds support for structured columns. + +The ability to report structured columns leverages the extensible type facility supported in ODBC 3.8 and greater. If a client has not called SQLSetEnvAttr with `SQL_ATTR_ODBC_VERSION` attribute set to `ODBC_OV_ODBC3_80` or greater, then the server must not return the `SQL_ROW` or `SQL_UDT` values in the `DATA_TYPE` or `SQL_DATA_TYPE` column descriptions, or `SQL_DESC_TYPE` or `SQL_DESC_CONCISE_TYPE` in any row or parameter descriptor. In this case the server may either flatten the structured value into multiple columns, create a join table containing the nested results, return the nested results as a string, or omit the nested results, as appropriate for the data source. + +### 3.10.1 Schema Extensions for Structured Columns + +Structured columns may have a named type, whose structure can be described in [SQLStructuredTypeColumns](#64-sqlstructuredtypecolumns). + +Structured columns with no backing type can be described by passing a path as the `TABLE_NAME` to SQLColumns, or the `UDT_NAME` to SQLStructuredTypeColumns. The dot-separated path starts with the table or named structural type name in which the anonymous type is used, can traverse an arbitrary number of `SQL_ROW` columns, and must terminate on a column whose type is `SQL_ROW`. Any identifiers in the path containing the dot character (.) must be quoted using the appropriate identifier quote character. Clients must assume that instances of structured columns with no backing type may include undeclared ([dynamic](#39-dynamic-columns)) columns. + +The following columns are added, in order, to the set of columns returned by SQLColumns when requested by ODBC 4.0 or greater applications: + +| **Column name** | **Column number** | **Data type** | **Comments** | +|---------------------|---------------|---------------|---------------------------------------------------------| +| `CHAR_SET_CAT` | 19 | Varchar | Catalog of the Character set for the column, or null. | +| `CHAR_SET_SCHEM` | 20 | Varchar | Schema of the Character set for the column, or null. | +| `CHAR_SET_NAME` | 21 | Varchar | Character set name for the column, or null. | +| `COLLATION_CAT` | 22 | Varchar | Catalog of the Collation for the column, or null. | +| `COLLATION_SCHEM` | 23 | Varchar | Schema of the Collation for the column, or null. | +| `COLLATION_NAME` | 24 | Varchar | Name of the Collation for the column, or null. | +| `UDT_CAT` | 25 | Varchar | Catalog of the structured type if the column is a UDT, otherwise null. | +| `UDT_SCHEM` | 26 | Varchar | Schema of the structured type if the column is a UDT, otherwise null. | +| `UDT_NAME` | 27 | Varchar | Name of the structured type if the column is a UDT, otherwise null. | + +The first six are set to null if not supported by the driver. The last three can be passed to SQLStructuredTypeColumns to describe the columns of a UDT, and are null for `DATA_TYPE`/`SQL_DATA_TYPE` values other than `SQL_UDT`. + +### 3.10.2 Query Extensions for Structured Columns + +Referencing a structured column by name references the entire structured column. + +For example: + +> Select EmpID, Address from Employee + +would return a result with two columns; one named “EmpID” containing the employee ID, and one named “Address” containing the address as a structured column. + +A subset of the properties for a structural type can be selected by following the reference to the structural column with a comma-separate list of properties, enclosed in parenthesis. + +For example: + +> Select EmpID, Address(Region,Country) from Employee + +would return a result with two columns; one named “EmpID” containing the employee ID, and one named “Address” containing only the Region and Country columns from the Address column. This is equivalent to the following query: + +> Select EmpID, ROW(Region, Country) as Address +> from Employee + +Two structured values are comparable if, and only if, they have the same structural members. For two structured values *SV1* and *SV2*. *SV1 = SV2* is true if every member *m1* in *SV1* equals the corresponding member *m2* in *SV2*, otherwise *SV1 = SV2* is false. *SV1 < SV2* is true if *SV1 != SV2* and every member *m1* in *SV1* is less than or equal to the corresponding member *m2* in *SV2*, otherwise *SV1 < SV2* is false. + +It is generally not possible to order by structured values, although it is possible to order by primitive members of a structural value. + +Individual members of a structured column may be referenced as the name of the structured column, followed by a single dot (.), followed by the name of the member. This naming schema is recursive (i.e., when referencing a member of a structured member that is itself a member of a structured member. + +For example: + +> Select EmpID, Address.Region, Address.Country from Employee + +would return a result with three columns; one named “EmpID” containing the employee id, one named “Address.Region” containing the region member of the employee’s address, and one named “Address.Country” containing the country member from the employee’s address. + +### 3.10.3 Response Extensions for Structured Columns + +To retrieve structured result columns, the client specifies [`SQL_DESC_DATA_AT_FETCH`](#36-getting-data-during-fetch) for the column before calling SQLFetch or SQLFetchScroll. + +For non-null values, the driver returns `SQL_DATA_AVAILABLE` for the structured column, at which time the can client call [SQLGetNestedHandle](#62-sqlgetnestedhandle) to obtain a statement handle (HSTMT) on which the nested results can be described, bound, and fetched using the appropriate standard ODBC function calls. Structural columns not specified as `SQL_DATA_AT_FETCH` are not returned by the driver. Attempting to return a structural value for a bound column results in a type exception, which may be handled according to the value of [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-sql_attr_type_exception_behavior). + +For null values, the driver sets `SQL_DESC_INDICATOR_PTR` to `SQL_NULL_VALUE`. If `SQL_DESC_INDICATOR_PTR `is not specified for a structured column whose value is null, the driver returns an error with SQLState `22002`, Indicator variable required but not supplied. + +#### 3.10.3.1 Result Descriptors for structured columns + +For structured columns with named types, the value of the `SQL_DESC_TYPE` or `SQL_DESC_CONCISE_TYPE` descriptor fields is `SQL_UDT` and the `TYPE_NAME` attribute returns the qualified name of the type. + +Additional descriptor fields can be used to describe UDTs in results: + +* `SQL_DESC_USER_DEFINED_TYPE_CATALOG` +* `SQL_DESC_USER_DEFINED_TYPE_SCHEMA` +* `SQL_DESC_USER_DEFINED_TYPE_NAME` + +Note: ANSI also defines `USER_DEFINED_TYPE_CODE` (1045) with a value of “`DISTINCT`” (1) or “`STRUCTURED`” (2). + +For structured columns not described by a named type, the value of the `SQL_DESC_TYPE` or `SQL_DESC_CONCISE_TYPE` descriptor fields is `SQL_ROW`. + +Calling GetNestedHandle for an unnamed structured column returns a statement handle with descriptor fields describing any known columns of the nested column. + +### 3.10.4 Write Extensions for Structured Columns + +Clients may specify the value for a member of a structured column in an INSERT or UPDATE statement by referencing the member directly. For Example: + +> UPDATE Employee SET FullName.FirstName = 'John', FullName.LastName='Smith' + +Dynamic columns can similarly be added to structured columns defined as open, for example: + +> UPDATE Employee SET FullName.Foo = 'Bar' + +Alternatively, clients may specify the value of a structured column in an INSERT or UPDATE statement using the *row-value-constructor* defined as follows: + +*row-value-constructor* ::= +ROW *left-paren value-expression* \[*comma* *value-expression*\]… *right-paren* + +For example: + +> UPDATE Employee SET FullName = ROW('John', 'Smith') + +All members must be specified in the order they occur in the definition of the structured type being updated. To update a subset of properties, a column-list can be added to the structured column: + +> UPDATE Employee SET FullName(FirstName, LastName) = ROW('John', 'Smith') + +In this case, the order of the members of the row-value-constructor must match the order of columns in the column-list applied to the structured column. + +Appending a column-list to the structured column can also be used to add dynamic columns to the structured column, for example, the following statements add a “Foo” member to the FullName column: + +> UPDATE Employee SET FullName(Foo) = ROW('Bar') + +> UPDATE Employee SET FullName(FirstName, Foo) = ROW('John', 'Bar') + +Side note: ANSI has two forms; one that is prefixed with “ROW” and can have one or more elements, and one that is not prefixed and must have at least two elements. + +Alternatively, clients can use a typed-constructor. + +*typed-value-constructor* ::= +*type-name* *left-paren value-expression* \[*comma* *value-expression*\]… *right-paren* + +All members must be specified in the order they occur in the definition of the structured type being updated. + +For example: + +> UPDATE Employee SET FullName = FULLNAME('John','Smith') + +Clients may update an individual member within a structured column by referencing that member in the set list of an update statement. + +For example: + +> UPDATE Employee SET Address.Country = ‘USA' + +#### 3.10.4.1 Passing structured parameters at execute time + +Structured parameters can be passed to the driver at execute time. + +To pass a structured parameter at execute time: + +1. The application calls SQLBindParameter (or equivalent SQLDescField/SQLDescRec), specifying the following: + - ValueType is `SQL_C_DEFAULT` (sets `SQL_DESC_TYPE`/`SQL_DESC_CONCISE_TYPE` in APD) + - ParameterType is `SQL_ROW` or `SQL_UDT` (sets `SQL_DESC_TYPE`/`SQL_DESC_CONCISE_TYPE` in IPD) + - For SQL_UDT, must set descriptor fields to specify: + - `USER_DEFINED_TYPE_CATALOG` + - `USER_DEFINED_TYPE_NAME` + - `USER_DEFINED_TYPE_SCHEMA` + - ParameterValuePtr is set to a 32bit value identifying the parameter (passed back to the app from SQLParamData when data is needed for this parameter) + - `StrLen_or_IndPtr` is set to a buffer containing `SQL_DATA_AT_EXEC` +2. The application calls SQLExecute or SQLExecDirect + - Driver returns `SQL_NEED_DATA`. +3. The application calls SQLParamData to find out which param the driver is asking about. + - Driver returns `SQL_NEED_DATA` and passes back value from ParameterValuePtr. +4. To specify a null or a default parameter value, the application calls SQLPutData with `str_len_or_ind` set to `SQL_NULL_DATA` or `SQL_DEFAULT_PARAM`, respectively, followed by SQLParamData to progress to the next parameter. +5. For a non-null structured parameter, the application calls SQLGetNestedHandle for the specified parameter + - Driver returns a nested statement handle +6. The application calls SQLBindParameter/SQLSetDescField to bind the nested parameters as named parameters. + - Individual property names are specified by setting the `SQL_DESC_NAME` attribute in the Implementation Parameter Descriptor (Driver sets `SQL_DESC_UNNAMED` to `SQL_NAMED`) +7. The application sets the appropriate values in the buffer and calls SQLExecute on the nested handle to send the row + - Driver returns `SQL_NEED_DATA` if there are any data-at-execute parameters on the nested handle +8. The application calls SQLParamData to indicate it has sent all of the data for the parameter + - If the parameter is a structured- or collection-valued parameter whose value was set through a nested statement handle, calling SQLParamData implicitly frees that handle + - Driver returns `SQL_NEED_DATA` if there are any remaining data-at-execute parameters. + +### 3.10.5 Data Definition Extensions for Structured Columns + +Structured types may be defined using the CREATE TYPE escape clause, as follows: + +{ CREATE \[Open\] TYPE *type\_name* (*column-identifier data-type* \[*,column-identifier data-type*\]...) } + +For example: + +> {CREATE OPEN TYPE FULLNAME(Firstname varchar(25), LastName varchar (25))} + +These types can be enumerated through the [SQLStructuredTypes](#63-sqlstructuredtypes) schema function. Their structure is described through [SQLStructuredTypeColumns](#64-sqlstructuredtypecolumns). + +Structured columns can be created within a table using a named structural type or by using the ROW clause: + +> CREATE TABLE Employees(FullName ROW(FirstName varchar(25), +LastName varchar(25)), Address ADDRESS) + +## 3.11 Collection-valued Columns + +ODBC adds support for collection-valued columns. + +The ability to report collection-valued columns leverages the extensible type facility supported in ODBC 3.8 and greater. If a client has not called SQLSetEnvAttr with `SQL_ATTR_ODBC_VERSION` attribute set to `ODBC_OV_ODBC3_80` or greater, then the server must not return the `SQL_ARRAY` or `SQL_MULTISET` values in the `DATA_TYPE` columns or descriptor fields. In this case the server may either flatten the array values into multiple columns, create a join table containing the nested results, return the nested results as a string, or omit the nested results, as appropriate for the data source. + +### 3.11.1 Schema Extensions for Collection-valued Columns + +Collection-valued table columns are described in SQLColumns. Collection-valued result columns are described through SQLColAttribute(s)/SqlDescribeCol/SqlGetDescField. + +Collection-valued columns may be ordered or unordered. + +#### 3.11.1.1 Describing Collections using SQLColumns + +For ordered array-valued columns, the value of the `DATA_TYPE` attributes is `SQL_ARRAY`. For unordered array-valued columns, the value of the `DATA_TYPE` attributes is `SQL_MULTISET`. + +The remaining columns, including the `SQL_DATA_TYPE`, describe the type of the element within the collection. + +Additionally, clients may get the type of a collection-valued column by passing the name of the collection-valued column appended with “[]” (repeated, for nested collections), as the column name in SQLColumns/SQLStructuredTypeColumns. + +### 3.11.2 Query Extensions for Collections + +The following query constructs are added in support of collections. + +#### 3.11.2.1 Array Element Reference + +Individual members of an array may be referenced using the *array-element-reference* expression. + +*array-element-reference* ::= +*array-value-expression left-bracket numeric-value-expression right-bracket* + +where *numeric-value-expression* yields an integer greater than zero and less than or equal to the number of elements in *array-value-expression*. + +For example: + +> Select EmpID, PhoneNumbers\[1\] from Employee + +returns the employee ids along with their first phone number. + +Since multisets are not ordered, their members cannot be individually referenced. + +Note that some data sources may use a bracketed string following a field name in the select list as a shortcut for aliasing the field. For fields representing arrays, if the bracketed value is a number the driver must ensure that it is used as an index, not as an alias. + +#### 3.11.2.2 UNNEST + +The ANSI SQL *unnest-operator* expands the collection into multiple rows. + +*unnest-operator* ::= +UNNEST *left-paren collection-value-expression right-paren* + +The result of the *unnest-operator* is a derived table that can then be used with a correlation + +For example: + +> Select P.Name, Child.Name +> From People P, Unnest(P.Children) as Child + +would return a row each child for each person containing the person’s name and child’s name. + +If the type of the collection is variant, or the Unnest operator references a dynamic column of an open type, then the Unnest operator returns null for rows in which the column is not defined. + +### 3.11.3 Response Extensions for Collection-valued Columns + +To retrieve collection-valued result columns, the client specifies [`SQL_DESC_DATA_AT_FETCH`](#36-getting-data-during-fetch) for the column before calling SQLFetch or SQLFetchScroll. + +The driver returns `SQL_DATA_AVAILABLE` for non-null collection-valued columns, at which time the client can call [SQLGetNestedHandle](#62-sqlgetnestedhandle) to obtain a statement handle (HSTMT) on which the nested results can be described, bound, and fetched using the appropriate standard ODBC function calls. Collection-valued columns not specified as data-at-fetch are not returned by the driver. Attempting to return a collection-value for a bound column results in a type exception, which may be handled according to the value of [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-sql_attr_type_exception_behavior). + +For null collection values, the driver sets `SQL_DESC_INDICATOR_PTR` to `SQL_NULL_VALUE`. If `SQL_DESC_INDICATOR_PTR `is not specified for a collection typed column whose value is null, the driver returns an error with SQLState `22002`, Indicator variable required but not supplied. + +For typed collections of scalar values, the nested statement handle contains a single descriptor record that describes the scalar value. + +For typed collections of [structured values](#310-structured-columns), the nested statement handle describes the columns of the structured value. + +For typed collections of [collections](#311-collection-valued-columns), the nested statement contains a single descriptor record on which the application calls [SQLGetNestedHandle](#62-sqlgetnestedhandle) in order to get a statement handle for each nested collection. + +For collections of [variable typed values](#37-variable-typed-columns), the nested statement contains a single descriptor record describing the variable value. If the type of that value changes from a previous row, a type exception may be raised and handled according to the value of [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-sql_attr_type_exception_behavior). For structured or collection-valued members within a variable-typed collection, the application calls [SQLGetNestedHandle](#62-sqlgetnestedhandle) in order to retrieve a statement handle on which to describe and retrieve the values of the structured or collection-valued member. + +### 3.11.4 Write Extensions for Collection-valued Columns + +Clients may specify the value of an array-valued column in an INSERT or UPDATE statement using the *array-value-constructor* defined as follows: + +*array-value-constructor* ::= +ARRAY *left-paren value-expression* \[*comma* *value-expression*\]\* *right-paren* + +*multiset-value-constructor* ::= +MULTISET *left-paren value-expression* \[*comma* *value-expression*\]\* *right-paren* + +Multisets and arrays are treated as atomic values when updating. That is, the array or multiset can be replaced in whole, but individual members cannot be added, removed, or updated. + +Clients may update an individual member within an array-valued value through the use of the *array-element-reference* expression. + +### 3.11.5 Data Definition Extensions for Collection-valued Columns + +Ordered collection-valued columns are defined using the array column type: + +*array-column-type* ::= *data-type* ARRAY \[ *left-bracket maximum-cardinality right-bracket* \] + +For example: + +> CREATE TABLE Employee(FullName FULLNAME, Address ADDRESS, PhoneNumbers varchar(25) ARRAY\[10\] ) + +Unordered collection-valued columns are defined using the MULTISET column type : + +*multiset-column-type* ::= *data-type* MULTISET + +For example: + +> CREATE TABLE Employee(FullName FULLNAME, Address ADDRESS, PhoneNumbers varchar(25) MULTISET ) + +#### 3.11.5.1 Passing collection-valued parameters at execute time + +Collection-valued parameters can be passed to the driver at execute time. + +To pass an array-valued parameter at execute time, the application: + +1. Application binds the parameter, specifying the following: + - ValueType is `SQL_C_DEFAULT` (sets `SQL_DESC_TYPE`/`SQL_DESC_CONCISE_TYPE` in APD) + - ParameterType is `SQL_ARRAY` or `SQL_MULTISET` (sets `SQL_DESC_TYPE`/`SQL_DESC_CONCISE_TYPE` in IPD) + - Sets the `SQL_DESC_SUBTYPE` of the IPD to the type of the array or multiset, if known + - For SQL_UDT sets descriptor fields to specify: + - `USER_DEFINED_TYPE_CATALOG` + - `USER_DEFINED_TYPE_SCHEMA` + - `USER_DEFINED_TYPE_NAME` + - ParameterValuePtr is set to a 32bit value identifying the parameter (passed back to the app from SQLParamData when data is needed for this parameter) + - StrLen_or_IndPtr is set to a buffer containing `SQL_DATA_AT_EXEC` +2. Application calls SQLPrepare/SQLExecute or SQLExecDirect + - Driver returns `SQL_NEED_DATA`. +3. Application calls SQLParamData to find out which param the driver is asking about. + - Driver returns `SQL_NEED_DATA` and passes back value from ParameterValuePtr. +4. To specify a null value, a default value, or an empty array, the application calls SQLPutData with `str_len_or_ind` set to `SQL_NULL_DATA`, `SQL_DEFAULT_PARAM`, or `SQL_EMPTY_ARRAY`, respectively, followed by SQLParamData to progress to the next parameter. +5. To specify a non-empty array, the application calls GetNestedHandle for the specified parameter + - Driver returns a nested statement handle +6. Application calls BindParameter/SetDescField to bind the nested columns. + - Individual column names are specified by setting the `SQL_DESC_NAME` attribute in the Implementation Parameter Descriptor. +7. Application sets the appropriate values in the buffer and calls SQLExecute on the nested handle to send the row of data + - Driver returns `SQL_NEED_DATA` if there are any data-at-execute parameters on the nested handle +8. Application repeats step 7 for each nested row +9. Application calls SQLParamData to indicate it has sent all of the data for the parameter + - Driver returns `SQL_NEED_DATA` if there are any remaining data-at-execute parameters. + +# 3.12 New ODBC C typedefs +New C-language typedefs are added for binding time values with fractional seconds. + +# 3.12.1 New `SQL_C_TYPE_TIME_WITH_FRACTIONAL_SECONDS` +A new `SQL_C_TYPE_TIME_WITH_FRACTIONAL_SECONDS` is added for binding to a c time type that includes fractional seconds. + +A corresponding new struct is added for returning time values with fractional seconds: + + typedef struct tagTIME_WITH_FRACTIONAL_SECONDS_STRUCT + { + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; + } TIME_WITH_FRACTIONAL_SECONDS_STRUCT; + +4.x drivers must support binding to either the `SQL_C_TYPE_TIME` (without fractional seconds) or `SQL_C_TYPE_TIME_WITH_FRACTIONAL_SECONDS` (with fractional seconds). 4.0 clients should not specify +`SQL_C_TYPE_TIME_WITH_FRACTIONAL_SECONDS` against a 3.x driver. + +If an application specifies `SQL_C_DEFAULT` for a time value, then the driver must assume `SQL_C_TYPE_TIME` and not include fractional seconds. + +# 3.12.2 New `SQL_C_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS` +A new `SQL_C_TYPE_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS` is added for binding to a c time with timezone type that includes fractional seconds. + +A new struct is added for returning time with timezone values with fractional seconds: + + typedef struct tagTIME_WITH_TIMEZONE_FRACTIONAL_SECONDS_STRUCT + { + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; + SQLSMALLINT timezone_hours; + SQLUSMALLINT timezone_minutes; + } TIME_WITH_TIMEZONE_FRACTIONAL_SECONDS_STRUCT; + +4.x drivers must support binding to either the `SQL_C_TYPE_TIME_WITH_TIMEZONE` (without fractional seconds) or `SQL_C_TYPE_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS` (with fractional seconds). 4.0 clients should not specify +`SQL_C_TYPE_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS` against a 3.x driver. + +If an application specifies `SQL_C_DEFAULT` for a time value, then the driver must assume `SQL_C_TYPE_TIME_WITH_TIMEZONE` and not include fractional seconds. + +# 4 Change Tracking + +##NOTE: This section of the specification is in a very early form; it is incomplete and subject to change or removal. + +A number of data sources support the ability to determine changes from a certain point. + +ODBC 4.0 provides common functions that services can use to expose this information. + +ODBC adds a new *ODBC-supports-change-tracking-escape* that returns 1 if a given table supports change tracking, otherwise 0: + +*ODBC-supports-change-tracking-escape* ::= +     *ODBC-esc-initiator* trackschanges(*tablename*) *ODBC-esc-terminator* + +Where *tablename* is the unqualified, partially qualified, or fully qualified name of the table. + +ODBC adds a new *ODBC-changeversion-escape* for getting the current change version (timestamp, version, or other high-water mark) defined as follows: + +*ODBC-changeversion-escape* ::= +     *ODBC-esc-initiator* changeversion(*tablename*) *ODBC-esc-terminator* + +The value returned by the *ODBC-changeversion-escape* is a binary value that can be passed to the *ODBC-changes-escape* to retrieve the latest values of any rows that have changed since the specified time: + +*ODBC-changes-escape* ::= +     *ODBC-esc-initiator* changes(*tablename, changeversion*) *ODBC-esc-terminator* + +The *ODBC-changes-escape* returns all rows from the specified *tablename* that have changed since the specified *changeversion*. The first column of the result is named “ColumnStatus” and contains the value “I” if the row is new since the specified changeversion, “U” if it has been updated since the specified changeversion, and “D” if it has been deleted since the specified change version. The additional columns of the result are the columns of the base table. Deleted rows must contain the “ColumnStatus” column, as well as any columns identified as `BEST_ROWID` and ROWVER from SQLSpecialColumns. + +# 5 Compatibility +ODBC 4.0 drivers support ODBC 3.x clients by defaulting to a relational view for applications that specify an ODBC version of 2.x or 3.x through the `SQL_ATTR_ODBC_VERSION` environment attribute. + +Certain ODBC 4.0 behavior may still available to an application that declares an ODBC version of 3.x, but it must be explicitly opted into by the application, for example, by setting new attributes. + +## 5.1 ODBC 3.x Clients +Clients that specify a `SQL_ATTR_ODBC_VERSION` environment attribute value representing ODBC 2.x or 3.x can still use escape clauses, connection keywords, Infotypes, and attributes specified in this document, as supported by the driver. Where available, clients should query the corresponding InfoType to ensure support or be prepared for corresponding errors. + +The Driver Manager raises `IM001`, Driver does not support this function, if a client attempts to specify data-at-fetch columns against drivers that report an ODBC 2.x or ODBC 3.x `ODBC_DRIVER_VERSION` InfoType. + +## 5.2 ODBC 3.x Drivers +ODBC 3.x drivers can support ODBC 4.0 escape clauses, connection keywords, infotypes, and attributes, as well as added columns to the catalog functions, without reporting ODBC 4.0 support, but must not utilize `SQL_VARIANT`, `SQL_ROW`, `SQL_UDT`, `SQL_ARRAY`, or `SQL_MULTISET` data types in schema functions or descriptor functions. + +## 5.3 ODBC 4.0 Clients +ODBC 4.0 Clients must not utilize the new `SQL_C_TYPE_TIME_WITH_FRACTIONAL_SECONDS` or `SQL_C_TYPE_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS` types. + +## 5.4 ODBC 4.0 Drivers +In order to report support for ODBC 4.0, a driver: + +1. Must return `SQL_OV_ODBC4` from SQLGetInfo with `SQL_ODBC_DRIVER_VERSION` fInfoType +2. Must support data-at-fetch columns, and SQLNextColumn for retrieving the currently available column +3. Must support `SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR` to control how binary and string overflows are handled +4. Must support `SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR` to control how type exceptions are handled +5. Must support a `SQL_ATTR_DYNAMIC_COLUMNS` value of *False* to ignore dynamic columns +6. Must support binding `SQL_TIME` values to either the `SQL_C_TYPE_TIME` (without fractional seconds) or `SQL_C_TYPE_TIME_WITH_FRACTIONAL_SECONDS` (with fractional seconds) +7. Must support binding `SQL_TIME_WITH_TIMEZONE` values to either the `SQL_C_TYPE_TIME_WITH_TIMEZONE` (without fractional seconds) or `SQL_C_TYPE_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS` (with fractional seconds). +7. If `SQL_ATTR_ODBC_VERSION` environment attribute indicates an ODBC 2.x or 3.x version: + 1. Must not utilize `SQL_VARIANT`, `SQL_ROW`, `SQL_UDT`, `SQL_ARRAY`, or `SQL_MULTISET` in schema or descriptor functions + +In addition, if the driver supports `SQL_ROW`, `SQL_UDT`, `SQL_ARRAY`, or `SQL_MULTISET` columns, it must: + +8. Support SQLGetNestedHandle, for retrieving a handle to read or write the nested value + +In addition, if the driver supports `SQL_UDT`, it must: + +9. Support SQLStructuredTypes +10. Support SQLStructuredTypeColumns + +## 5.5 ODBC 4.0 Driver Manager +The ODBC 4.0 Driver Manager will map the following InfoTypes and attributes for 2.x and 3.x drivers: + +| **InfoType/Attribute** | **Behavior** | +|--------------------------------------|------------------------------------------------------------| +| `SQL_SCHEMA_INFERENCE` | If not supported by the driver, SQLGetInfo returns `FALSE` | +| `SQL_ATTR_DYNAMIC_COLUMNS` | If not supported by the driver, SQLGetStmtAttr returns *False* and SQLSetStmtAttr returns `SQL_SUCCESS_WITH_INFO` with a diagnostic code of 01S02. | +| `SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR` | If not supported by the driver, SQLGetStmtAttr returns `SQL_LE_CONTINUE` and SQLSetStmtAttr with a value other than `SQL_LE_CONTINUE` returns `SQL_ERROR` with a diagnostic code of `HYC00`, Optional feature not implemented | +| `SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR` | If not supported by the driver, SQLGetStmtAttr returns SQL_TE_ERROR and SQLSetStmtAttr with a value other than `SQL_TE_ERROR` returns `SQL_ERROR` with a diagnostic code of `HYC00`, Optional feature not implemented | + +# 6 New Functions +The following functions are added in ODBC 4.0. + +## 6.1 SQLNextColumn + +The application calls SQLNextColumn in order to retrieve the column of data currently available to be read. + + SQLRETURN SQLNextColumn( + SQLHSTMT StatementHandle, + SQLUSMALLINT* Col_or_Param_Num); + +SQLNextColumn can first be called only after SQLFetch or SQLFetchScroll returns `SQL_DATA_AVAILABLE`, `SQL_METADATA_CHANGED`, or `SQL_MORE_DATA`, and as long as SQLNextColumn continues to return one of these values. + +The Driver Manager returns `HY010`, Function Sequence Error under the following conditions: + +1. The specified StatementHandle was not in the executed state. + +2. SQLFetch or SQLFetschScroll have not been called on the executed statement. + +3. The most recent call to SQLFetch, SQLFetchScroll, or SQLNextColumn on this statement handle did not return `SQL_DATA_AVAILABLE`, `SQL_METADATA_CHANGED`, or `SQL_MORE_DATA` + +4. There is an asynchronously executing function called on this statement handle, or the connection associated with this statement handle, that has not completed. + +The driver manager returns `HY010`, Function sequence error, from SQLSetPos if the most recent call to SQLFetch, SQLFetchScroll, or SQLNextColumn returned `SQL_DATA_AVAILABLE`. + +### 6.1.1 Usage + +While fetching a row that contains a column whose `SQL_DESC_DATA_AT_FETCH` descriptor is set to `SQL_TRUE`, when reading a dynamic column while [`SQL_ATTR_DYNAMIC_COLUMNS`](#391-SQL_ATTR_DYNAMIC_COLUMNS) is *True*, or when encountering a length or type exception, depending on the value of [`SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR`](#381-SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR) and [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR), respectively, the driver returns `SQL_DATA_AVAILABLE`, `SQL_METADATA_CHANGED`, or `SQL_MORE_DATA`, and the application calls SQLNextColumn in order to determine the ordinal of the next available column to be read. + +The application can use the returned `Col_or_Param_Num` to retrieve information about the available column or parameter, but must not change descriptor information relative to the descriptor header record or any descriptor records not associated with the returned `Col_or_Param_Num`. + +Once all columns have been processed, SQLNextColumn returns `SQL_SUCCESS` or `SQL_SUCCESS_WITH_INFO` with any valid SQLState from SQLFetch/SQLFetchScroll. + +Calling SQLNextColumn with a null pointer for `Col_or_Param_Num` populates any remaining bound columns, skipping any data-at-fetch columns within the rowset. Dynamic columns are added to the descriptor as unbound columns and do not result in `SQL_DATA_AVAILABLE`. Any length exceptions are treated as `SQL_LE_CONTINUE`. If [`SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR`](#3731-SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR) is `SQL_TE_ERROR` then an error is returned if any data values within the rowset are incompatible with their bound types, otherwise any type exceptions are treated as `SQL_TE_CONTINUE`. + +Calling SQLFetch or SQLFetchScroll continues to the next rowset, adding any dynamic columns to the descriptor as unbound columns but otherwise skipping any data-at-fetch columns and ignoring type or length exceptions within the current rowset. + +## 6.2 SQLGetNestedHandle + +SQLGetNestedHandle is called in to retrieve a handle for reading or writing structured or collection-valued columns and parameters. + + SQLRETURN SQLGetNestedHandle( + SQLHSTMT ParentStatementHandle, + SQLUSMALLINT Col_or_Param_Num, + SQLHSTMT* OutputChildStatementHandle); + +SQLGetNestedHandle can be called for columns containing nested collections or structured columns once the ParentStatementHandle is in a prepared or executed state. The nested handle can be used to fetch data once the ParentStatementHandle is in the executed state and the driver returns `SQL_DATA_AVAILABLE` for the particular column, and may allow fetching data at other times depending upon `SQL_GETDATA_EXTENSIONS`. + +The Driver Manager returns HY001 under the following condition: + +1. The Driver Manager was unable to allocate memory for the specified handle + +The Driver Manager returns HY003, Program type out of range, under the following condition: + +1. The argument `Col_or_Param_Num` was 0. + +The Driver Manager returns HY009, Invalid use of a null pointer under the following condition: + +1. The argument OutputChildStatementHandle was a null pointer. + +The Driver Manager returns HY010, Function Sequence Error under the following conditions: + +1. The specified StatementHandle was not in a prepared or executed state. + +2. There is an asynchronously executing function called on this statement handle, or the connection associated with this statement handle, that has not completed. + +The Driver Manager returns HY117, Connection is suspended due to unknown transaction state if the connection is in a suspended state. + +The driver manager returns IM001, Driver does not support this function, under the following condition: + +1. The driver associated with StatementHandle does not support the function. + +### 6.2.1 Usage + +Applications call SQLGetNestedHandle in order obtain a nested statement handle representing rows or output parameters whose `SQL_DESC_TYPE` and `SQL_DESC_CONCISE_TYPE` descriptor fields indicate "SQL_UDT", "SQL_ROW", "SQL_ARRAY", or "SQL_MULTISET". + +Nested statement handles can be used to describe results once the parent statement handle is in the prepared or executed state. Applications can fetch data from the nested statement handle once the driver returns `SQL_DATA_AVAILABLE` for the particular column, and may allow fetching data at other times depending upon `SQL_GETDATA_EXTENSIONS`. + +Fetching results from a handle returned by SQLGetNestedHandle has the same sequencing restrictions as SQLGetData. Drivers report relaxed sequencing rules for both SQLGetData and fetching results from a nested statement handle through `SQL_GET_DATA_EXTENSIONS`. Unless `SQL_GET_DATA_EXTENSIONS` specifies `SQL_GD_ANY_ORDER`, Fetch/GetData must only be called on the handle associated with the most recent call to SQLNextColumn. + +After calling SQLGetNestedHandle, the application can use the returned ChildStatementHandle to describe and fetch results for that nested content. + +Calling SQLCloseCursor on the nested handle closes the child cursor for the current parent row. + +Multiple calls to SQLGetNestedHandle for the same `ParentStatementHandle`, `Col_or_Param_Num`, and `SQL_DESC_CONCISE_TYPE` return the same ChildStatementHandle (including any added/modified descriptor fields) unless that handle has been freed, in which case the next call to SQLGetNestedHandle for that `ParentStatementHandle`, `Col_or_Param_Num`, and `SQL_DESC_CONCISE_TYPE` combination returns a fresh statement handle with default values appropriate for the current row. + +Unless the [SQL_GD_CONCURRENT](#361-SQL_GD_CONCURRENT-bit-for-sql_getdata_extensions) bit within SQL_GETDATA_EXTENSIONS is specified, a subsequent call to retrieve data using SQLGetData, SQLFetch, SQLFetchScroll, or SQLNextColumn on the parent handle or a different nested statement handle implicitly closes the statement handle. If `SQL_GD_CONCURRENT` is specified, a subsequent call to retrieve data on the child statement handle does not affect any other statement handle. + +Closing a statement handle implicitly closes and frees all child statement handles. + +Calling SQLGetNestedHandle for a non-structured or collection valued column, or calling SQLGetData on a structured or collection-valued column, returns `SQL_ERROR` with SQLState `07009`, Invalid descriptor index. + +TODO: describe output parameters. Do we need a new InputOutputType, or do we use the existing `SQL_PARAM_[INPUT_]OUTPUT_STREAM`? + +## 6.3 SQLStructuredTypes + +SQLStructuredTypes enumerates named structural types. + + SQLRETURN SQLStructuredTypes( + SQLHSTMT StatementHandle, + SQLCHAR * CatalogName, + SQLSMALLINT NameLength1, + SQLCHAR * SchemaName, + SQLSMALLINT NameLength2, + SQLCHAR * TypeName, + SQLSMALLINT NameLength3); + +The driver manager enforces the same sequencing and validity checks as in SQLTables. In particular: + +The Driver Manager returns `HY010`, Function Sequence Error under the following conditions: + +1. There is an asynchronously executing function called on this statement handle, or the connection associated with this statement handle, that has not completed. + +2. **SQLExecute**, **SQLExecDirect**, or **SQLMoreResults** was called for the *StatementHandle* and returned `SQL_PARAM_DATA_AVAILABLE`. This function was called before data was retrieved for all streamed parameters + +3. **SQLExecute**, **SQLExecDirect**, **SQLBulkOperations**, or **SQLSetPos** was called for the *StatementHandle* and returned `SQL_NEED_DATA`. This function was called before data was sent for all data-at-execution parameters or columns. + +The Driver Manager returns `HY090` under the following conditions: + +1. The value of one of the length arguments was less than 0 but not equal to `SQL_NTS`. + +2. The value of one of the name length arguments exceeded the maximum length value for the corresponding name. + +The Driver Manager returns `HY117`, Connection is suspended due to unknown transaction state, if the connection is in a suspended state. + +The driver manager returns `IM001`, Driver does not support this function, under the following condition: + +1. The driver associated with StatementHandle does not support the function. + +### 6.3.1 Usage + +The result of SQLStructuredTypes mirrors the result of SQLTables: + +| **Column name** | **Column number** | **Data type** | **Comments** | +|-----------------|-------------------|---------------|---------------------------------------------------------------------------| +| `UDT_CAT` | 1 | Varchar | Catalog name. See `TABLE_CAT` in SQLTables. | +| `UDT_SCHEM` | 2 | Varchar | Schema name See `TABLE_SCHEM` in SQLTables. | +| `UDT_NAME` | 3 | Varchar | Structured Type name. | +| `UDT_TYPE` | 4 | Varchar | UDT Type name; "TYPE", "`OPEN TYPE`", or a data source–specific type name. | +| REMARKS | 5 | Varchar | A description of the Structured Type. | + +# 6.4 SQLStructuredTypeColumns + +SQLStructuredTypeColumns describes the columns of a named structural type. + + SQLRETURN SQLStructuredTypeColumns( + SQLHSTMT StatementHandle, + SQLCHAR * CatalogName, + SQLSMALLINT NameLength1, + SQLCHAR * SchemaName, + SQLSMALLINT NameLength2, + SQLCHAR * TypeName, + SQLSMALLINT NameLength3, + SQLCHAR * ColumnName, + SQLSMALLINT NameLength4); + +The result of SQLStructuredTypeColumns mirrors the result of SQLColumns: + +| **Column name** | **Column number** | **Data type** | **Comments** | +|---------------------|---------------|---------------|---------------------------------------------------------| +| `UDT_CAT` | 1 | Varchar | Catalog name; NULL if not applicable to the data source. | +| `UDT_SCHEM` | 2 | Varchar | Schema name; NULL if not applicable to the data source. | +| `UDT_NAME` | 3 | Varchar not NULL | Structured Type name. | +| `COLUMN_NAME` | 4 | Varchar not NULL | Column name. The driver returns an empty string for a column that does not have a name. | +| `DATA_TYPE` | 5 | Smallint not NULL | SQL data type. See `DATA_TYPE` column in SQLColumns. | +| `TYPE_NAME` | 6 | Varchar not NULL | Data source–dependent data type name | +| `COLUMN_SIZE` | 7 | Integer | Size of the column. See `COLUMN_SIZE` column in SQLColumns. | +| `BUFFER_LENGTH` | 8 | Integer | The length in bytes of data transferred on an SQLGetData, SQLFetch, or SQLFetchScroll operation if `SQL_C_DEFAULT` is specified. | +| `DECIMAL_DIGITS` | 9 | Smallint | See `DECIMAL_DIGITS` in SQLColumns. | +| `NUM_PREC_RADIX` | 10 | Smallint | See NUM_PREC_RADIX in SQLColumns. | +| `NULLABLE` | 11 | Smallint not NULL | See `NULLABLE` in SQLColumns. | +| `REMARKS` | 12 | Varchar | A description of the column. | +| `COLUMN_DEF` | 13 | Varchar | The default value of the column. See the `COLUMN_DEF` column in SQLColumns. | +| `SQL_DATA_TYPE` | 14 | Smallint not NULL | See `SQL_DATA_TYPE` in SQLColumns. | +| `SQL_DATETIME_SUB` | 15 | Smallint | See `SQL_DATETIME_SUB` in SQLColumns. | +| `CHAR_OCTET_LENGTH` | 16 | Integer | The maximum length in bytes of a character or binary data type column. | +| `ORDINAL_POSITION` | 17 | Integer not NULL | The ordinal position of the column in the structured type. The first column in the UDT is number 1. | +| `IS_NULLABLE` | 18 | Varchar | See `IS_NULLABLE` in SQLColumns. | +| `CHAR_SET_CAT` | 19 | Varchar | Catalog of the Character set for the column, or null. | +| `CHAR_SET_SCHEM` | 20 | Varchar | Schema of the Character set for the column, or null. | +| `CHAR_SET_NAME` | 21 | Varchar | Character set name for the column, or null. | +| `COLLATION_CAT` | 22 | Varchar | Catalog of the Collation for the column, or null. | +| `COLLATION_SCHEM` | 23 | Varchar | Schema of the Collation for the column, or null. | +| `COLLATION_NAME` | 24 | Varchar | Name of the Collation for the column, or null. | +| `UDT_CAT` | 25 | Varchar | Catalog of the structured type if the column is a UDT, otherwise null. | +| `UDT_SCHEM` | 26 | Varchar | Schema of the structured type if the column is a UDT, otherwise null. | +| `UDT_NAME` | 27 | Varchar | Name of the structured type if the column is a UDT, otherwise null. | diff --git a/README.md b/README.md new file mode 100644 index 00000000..5db782d2 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Microsoft ODBC 4.0 Specification + +## Introduction +Microsoft ODBC is a widely adopted, standard, client-side API for accessing data. + +Microsoft ODBC version 4.0 is a new version of ODBC for modern data sources that adds support for features such as: + 1. Private drivers + 2. Additional capability reporting + 3. Language extensions through additional SQL Escape Clauses1) Semi-structured data – Tables whose schema may not be defined or may change on a row-by-row basis + 4. Hierarchical Data – Data with nested structure (structured fields, lists) + 5. Web Authentication model + + +## Contributing to Microsoft ODBC Specification +Contributions to the Microsoft ODBC Specification are welcome and encouraged. + +**IMPORTANT** By participating in this project you agree to abide by the terms of the [Contribution Agreement][contribution-agreement]. + + +[contribution-agreement]: https://github.com/Microsoft/ODBC-Specification/blob/master/contribution-agreement.md + diff --git a/Windows/inc/sql.h b/Windows/inc/sql.h new file mode 100644 index 00000000..8e724efb --- /dev/null +++ b/Windows/inc/sql.h @@ -0,0 +1,941 @@ +/******************************************************** +* * +* Copyright (C) Microsoft. All rights reserved. * +* * +********************************************************/ + +//----------------------------------------------------------------------------- +// File: sql.h +// +// Contents: This is the the main include for ODBC Core functions. +// +// Comments: preconditions: #include "windows.h" +// +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __SQL +#define __SQL + +#include + +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + +/* +* ODBCVER Default to ODBC version number (0x0380). To exclude +* definitions introduced in version 3.8 (or above) +* #define ODBCVER 0x0351 before #including +*/ +#ifndef ODBCVER +#define ODBCVER 0x0380 +#endif + +#ifndef __SQLTYPES +#include "sqltypes.h" +#endif + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* special length/indicator values */ +#define SQL_NULL_DATA (-1) +#define SQL_DATA_AT_EXEC (-2) + +/* return values from functions */ +#define SQL_SUCCESS 0 +#define SQL_SUCCESS_WITH_INFO 1 +#if (ODBCVER >= 0x0300) +#define SQL_NO_DATA 100 +#endif + +#if (ODBCVER >= 0x0380) +#define SQL_PARAM_DATA_AVAILABLE 101 +#endif + +#define SQL_ERROR (-1) +#define SQL_INVALID_HANDLE (-2) + +#define SQL_STILL_EXECUTING 2 +#define SQL_NEED_DATA 99 + +/* test for SQL_SUCCESS or SQL_SUCCESS_WITH_INFO */ +#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) + +/* flags for null-terminated string */ +#define SQL_NTS (-3) +#define SQL_NTSL (-3L) + +/* maximum message length */ +#define SQL_MAX_MESSAGE_LENGTH 512 + +/* date/time length constants */ +#if (ODBCVER >= 0x0300) +#define SQL_DATE_LEN 10 +#define SQL_TIME_LEN 8 /* add P+1 if precision is nonzero */ +#define SQL_TIMESTAMP_LEN 19 /* add P+1 if precision is nonzero */ +#endif + +/* handle type identifiers */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_ENV 1 +#define SQL_HANDLE_DBC 2 +#define SQL_HANDLE_STMT 3 +#define SQL_HANDLE_DESC 4 +#endif + +/* environment attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_OUTPUT_NTS 10001 +#endif + +/* connection attributes */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_AUTO_IPD 10001 +#define SQL_ATTR_METADATA_ID 10014 +#endif /* ODBCVER >= 0x0300 */ + +/* statement attributes */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_APP_ROW_DESC 10010 +#define SQL_ATTR_APP_PARAM_DESC 10011 +#define SQL_ATTR_IMP_ROW_DESC 10012 +#define SQL_ATTR_IMP_PARAM_DESC 10013 +#define SQL_ATTR_CURSOR_SCROLLABLE (-1) +#define SQL_ATTR_CURSOR_SENSITIVITY (-2) +#endif + +/* SQL_ATTR_CURSOR_SCROLLABLE values */ +#if (ODBCVER >= 0x0300) +#define SQL_NONSCROLLABLE 0 +#define SQL_SCROLLABLE 1 +#endif /* ODBCVER >= 0x0300 */ + +/* identifiers of fields in the SQL descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_COUNT 1001 +#define SQL_DESC_TYPE 1002 +#define SQL_DESC_LENGTH 1003 +#define SQL_DESC_OCTET_LENGTH_PTR 1004 +#define SQL_DESC_PRECISION 1005 +#define SQL_DESC_SCALE 1006 +#define SQL_DESC_DATETIME_INTERVAL_CODE 1007 +#define SQL_DESC_NULLABLE 1008 +#define SQL_DESC_INDICATOR_PTR 1009 +#define SQL_DESC_DATA_PTR 1010 +#define SQL_DESC_NAME 1011 +#define SQL_DESC_UNNAMED 1012 +#define SQL_DESC_OCTET_LENGTH 1013 +#define SQL_DESC_ALLOC_TYPE 1099 +#endif + +#if (ODBCVER >= 0x0400) +#define SQL_DESC_CHARACTER_SET_CATALOG 1018 +#define SQL_DESC_CHARACTER_SET_SCHEMA 1019 +#define SQL_DESC_CHARACTER_SET_NAME 1020 +#define SQL_DESC_COLLATION_CATALOG 1015 +#define SQL_DESC_COLLATION_SCHEMA 1016 +#define SQL_DESC_COLLATION_NAME 1017 +#define SQL_DESC_USER_DEFINED_TYPE_CATALOG 1026 +#define SQL_DESC_USER_DEFINED_TYPE_SCHEMA 1027 +#define SQL_DESC_USER_DEFINED_TYPE_NAME 1028 +#endif /* ODBCVER >= 0x0400 */ + +/* identifiers of fields in the diagnostics area */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_RETURNCODE 1 +#define SQL_DIAG_NUMBER 2 +#define SQL_DIAG_ROW_COUNT 3 +#define SQL_DIAG_SQLSTATE 4 +#define SQL_DIAG_NATIVE 5 +#define SQL_DIAG_MESSAGE_TEXT 6 +#define SQL_DIAG_DYNAMIC_FUNCTION 7 +#define SQL_DIAG_CLASS_ORIGIN 8 +#define SQL_DIAG_SUBCLASS_ORIGIN 9 +#define SQL_DIAG_CONNECTION_NAME 10 +#define SQL_DIAG_SERVER_NAME 11 +#define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12 +#endif + +/* dynamic function codes */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_ALTER_DOMAIN 3 +#define SQL_DIAG_ALTER_TABLE 4 +#define SQL_DIAG_CALL 7 +#define SQL_DIAG_CREATE_ASSERTION 6 +#define SQL_DIAG_CREATE_CHARACTER_SET 8 +#define SQL_DIAG_CREATE_COLLATION 10 +#define SQL_DIAG_CREATE_DOMAIN 23 +#define SQL_DIAG_CREATE_INDEX (-1) +#define SQL_DIAG_CREATE_SCHEMA 64 +#define SQL_DIAG_CREATE_TABLE 77 +#define SQL_DIAG_CREATE_TRANSLATION 79 +#define SQL_DIAG_CREATE_VIEW 84 +#define SQL_DIAG_DELETE_WHERE 19 +#define SQL_DIAG_DROP_ASSERTION 24 +#define SQL_DIAG_DROP_CHARACTER_SET 25 +#define SQL_DIAG_DROP_COLLATION 26 +#define SQL_DIAG_DROP_DOMAIN 27 +#define SQL_DIAG_DROP_INDEX (-2) +#define SQL_DIAG_DROP_SCHEMA 31 +#define SQL_DIAG_DROP_TABLE 32 +#define SQL_DIAG_DROP_TRANSLATION 33 +#define SQL_DIAG_DROP_VIEW 36 +#define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38 +#define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81 +#define SQL_DIAG_GRANT 48 +#define SQL_DIAG_INSERT 50 +#define SQL_DIAG_REVOKE 59 +#define SQL_DIAG_SELECT_CURSOR 85 +#define SQL_DIAG_UNKNOWN_STATEMENT 0 +#define SQL_DIAG_UPDATE_WHERE 82 +#endif /* ODBCVER >= 0x0300 */ + +/* SQL data type codes */ +#define SQL_UNKNOWN_TYPE 0 +#define SQL_CHAR 1 +#define SQL_NUMERIC 2 +#define SQL_DECIMAL 3 +#define SQL_INTEGER 4 +#define SQL_SMALLINT 5 +#define SQL_FLOAT 6 +#define SQL_REAL 7 +#define SQL_DOUBLE 8 +#if (ODBCVER >= 0x0300) +#define SQL_DATETIME 9 +#endif +#define SQL_VARCHAR 12 + +#if (ODBCVER >= 0x0400) +#define SQL_VARIANT_TYPE SQL_UNKNOWN_TYPE +#define SQL_UDT 17 +#define SQL_ROW 19 +#define SQL_ARRAY 50 +#define SQL_MULTISET 55 +#endif /* ODBCVER >= 0x0400 */ + +/* One-parameter shortcuts for date/time data types */ +#if (ODBCVER >= 0x0300) +#define SQL_TYPE_DATE 91 +#define SQL_TYPE_TIME 92 +#define SQL_TYPE_TIMESTAMP 93 +#endif +#if (ODBCVER >= 0x0400) +#define SQL_TYPE_TIME_WITH_TIMEZONE 94 +#define SQL_TYPE_TIMESTAMP_WITH_TIMEZONE 95 +#endif /* ODBCVER >= 0x0400 */ + +/* Statement attribute values for cursor sensitivity */ +#if (ODBCVER >= 0x0300) +#define SQL_UNSPECIFIED 0 +#define SQL_INSENSITIVE 1 +#define SQL_SENSITIVE 2 +#endif + +/* GetTypeInfo() request for all data types */ +#define SQL_ALL_TYPES 0 + +/* Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() */ +#if (ODBCVER >= 0x0300) +#define SQL_DEFAULT 99 +#endif + +/* SQLSQLLEN GetData() code indicating that the application row descriptor + * specifies the data type + */ +#if (ODBCVER >= 0x0300) +#define SQL_ARD_TYPE (-99) +#endif + +#if (ODBCVER >= 0x0380) +#define SQL_APD_TYPE (-100) +#endif + +/* SQL date/time type subcodes */ +#if (ODBCVER >= 0x0300) +#define SQL_CODE_DATE 1 +#define SQL_CODE_TIME 2 +#define SQL_CODE_TIMESTAMP 3 +#endif + +#if (ODBCVER >= 0x0400) +#define SQL_CODE_TIME_WITH_TIMEZONE 4 +#define SQL_CODE_TIMESTAMP_WITH_TIMEZONE 5 +#endif /* ODBCVER >= 0x0400 */ + +/* CLI option values */ +#if (ODBCVER >= 0x0300) +#define SQL_FALSE 0 +#define SQL_TRUE 1 +#endif + +/* values of NULLABLE field in descriptor */ +#define SQL_NO_NULLS 0 +#define SQL_NULLABLE 1 + +/* Value returned by SQLGetTypeInfo() to denote that it is + * not known whether or not a data type supports null values. + */ +#define SQL_NULLABLE_UNKNOWN 2 + +/* Values returned by SQLGetTypeInfo() to show WHERE clause + * supported + */ +#if (ODBCVER >= 0x0300) +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 +#endif + +/* values of UNNAMED field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 +#endif + +/* values of ALLOC_TYPE field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 +#endif + +/* FreeStmt() options */ +#define SQL_CLOSE 0 +#define SQL_DROP 1 +#define SQL_UNBIND 2 +#define SQL_RESET_PARAMS 3 + +/* Codes used for FetchOrientation in SQLFetchScroll(), + and in SQLDataSources() +*/ +#define SQL_FETCH_NEXT 1 +#define SQL_FETCH_FIRST 2 + +/* Other codes used for FetchOrientation in SQLFetchScroll() */ +#define SQL_FETCH_LAST 3 +#define SQL_FETCH_PRIOR 4 +#define SQL_FETCH_ABSOLUTE 5 +#define SQL_FETCH_RELATIVE 6 + +/* SQLEndTran() options */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1 + +/* null handles returned by SQLAllocHandle() */ +#define SQL_NULL_HENV 0 +#define SQL_NULL_HDBC 0 +#define SQL_NULL_HSTMT 0 +#if (ODBCVER >= 0x0300) +#define SQL_NULL_HDESC 0 +#endif + +/* null handle used in place of parent handle when allocating HENV */ +#if (ODBCVER >= 0x0300) +#define SQL_NULL_HANDLE 0L +#endif + +/* Values that may appear in the result set of SQLSpecialColumns() */ +#define SQL_SCOPE_CURROW 0 +#define SQL_SCOPE_TRANSACTION 1 +#define SQL_SCOPE_SESSION 2 + +#define SQL_PC_UNKNOWN 0 +#if (ODBCVER >= 0x0300) +#define SQL_PC_NON_PSEUDO 1 +#endif +#define SQL_PC_PSEUDO 2 + +/* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ +#if (ODBCVER >= 0x0300) +#define SQL_ROW_IDENTIFIER 1 +#endif + +/* Reserved values for UNIQUE argument of SQLStatistics() */ +#define SQL_INDEX_UNIQUE 0 +#define SQL_INDEX_ALL 1 + +/* Values that may appear in the result set of SQLStatistics() */ +#define SQL_INDEX_CLUSTERED 1 +#define SQL_INDEX_HASHED 2 +#define SQL_INDEX_OTHER 3 + +/* SQLGetFunctions() values to identify ODBC APIs */ +#define SQL_API_SQLALLOCCONNECT 1 +#define SQL_API_SQLALLOCENV 2 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLE 1001 +#endif +#define SQL_API_SQLALLOCSTMT 3 +#define SQL_API_SQLBINDCOL 4 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLBINDPARAM 1002 +#endif +#define SQL_API_SQLCANCEL 5 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLCLOSECURSOR 1003 +#define SQL_API_SQLCOLATTRIBUTE 6 +#endif +#define SQL_API_SQLCOLUMNS 40 +#define SQL_API_SQLCONNECT 7 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLCOPYDESC 1004 +#endif +#define SQL_API_SQLDATASOURCES 57 +#define SQL_API_SQLDESCRIBECOL 8 +#define SQL_API_SQLDISCONNECT 9 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLENDTRAN 1005 +#endif +#define SQL_API_SQLERROR 10 +#define SQL_API_SQLEXECDIRECT 11 +#define SQL_API_SQLEXECUTE 12 +#define SQL_API_SQLFETCH 13 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLFETCHSCROLL 1021 +#endif +#define SQL_API_SQLFREECONNECT 14 +#define SQL_API_SQLFREEENV 15 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLFREEHANDLE 1006 +#endif +#define SQL_API_SQLFREESTMT 16 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETCONNECTATTR 1007 +#endif +#define SQL_API_SQLGETCONNECTOPTION 42 +#define SQL_API_SQLGETCURSORNAME 17 +#define SQL_API_SQLGETDATA 43 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETDESCFIELD 1008 +#define SQL_API_SQLGETDESCREC 1009 +#define SQL_API_SQLGETDIAGFIELD 1010 +#define SQL_API_SQLGETDIAGREC 1011 +#define SQL_API_SQLGETENVATTR 1012 +#endif +#define SQL_API_SQLGETFUNCTIONS 44 +#define SQL_API_SQLGETINFO 45 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETSTMTATTR 1014 +#endif +#define SQL_API_SQLGETSTMTOPTION 46 +#define SQL_API_SQLGETTYPEINFO 47 +#define SQL_API_SQLNUMRESULTCOLS 18 +#define SQL_API_SQLPARAMDATA 48 +#define SQL_API_SQLPREPARE 19 +#define SQL_API_SQLPUTDATA 49 +#define SQL_API_SQLROWCOUNT 20 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETCONNECTATTR 1016 +#endif +#define SQL_API_SQLSETCONNECTOPTION 50 +#define SQL_API_SQLSETCURSORNAME 21 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETDESCFIELD 1017 +#define SQL_API_SQLSETDESCREC 1018 +#define SQL_API_SQLSETENVATTR 1019 +#endif +#define SQL_API_SQLSETPARAM 22 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETSTMTATTR 1020 +#endif +#define SQL_API_SQLSETSTMTOPTION 51 +#define SQL_API_SQLSPECIALCOLUMNS 52 +#define SQL_API_SQLSTATISTICS 53 +#define SQL_API_SQLTABLES 54 +#define SQL_API_SQLTRANSACT 23 +#if (ODBCVER >= 0x0380) +#define SQL_API_SQLCANCELHANDLE 1550 +#define SQL_API_SQLCOMPLETEASYNC 1551 + +#endif + +/* Information requested by SQLGetInfo() */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#endif +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN 32 +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN 34 +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +#define SQL_SCROLL_CONCURRENCY 43 +#define SQL_TXN_CAPABLE 46 +#define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE +#define SQL_USER_NAME 47 +#define SQL_TXN_ISOLATION_OPTION 72 +#define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION +#define SQL_INTEGRITY 73 +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN +#if (ODBCVER >= 0x0300) +#define SQL_OJ_CAPABILITIES 115 +#define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +#define SQL_XOPEN_CLI_YEAR 10000 +#define SQL_CURSOR_SENSITIVITY 10001 +#define SQL_DESCRIBE_PARAMETER 10002 +#define SQL_CATALOG_NAME 10003 +#define SQL_COLLATION_SEQ 10004 +#define SQL_MAX_IDENTIFIER_LEN 10005 +#define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0200) +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#endif /* ODBCVER >= 0x0200 */ + +#if (ODBCVER >= 0x0300) +#define SQL_AT_ADD_CONSTRAINT 0x00000008L + +/* The following bitmasks are ODBC extensions and defined in sqlext.h +*#define SQL_AT_COLUMN_SINGLE 0x00000020L +*#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +*#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +*#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +*#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +*#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +*#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +*#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +*#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +*#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +*#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +*#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +*#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +*/ +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_ASYNC_MODE values */ +#if (ODBCVER >= 0x0300) +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 +#endif + +/* SQL_CURSOR_COMMIT_BEHAVIOR values */ +#define SQL_CB_DELETE 0 +#define SQL_CB_CLOSE 1 +#define SQL_CB_PRESERVE 2 + +/* SQL_FETCH_DIRECTION bitmasks */ +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L + +/* SQL_GETDATA_EXTENSIONS bitmasks */ +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + +/* SQL_IDENTIFIER_CASE values */ +#define SQL_IC_UPPER 1 +#define SQL_IC_LOWER 2 +#define SQL_IC_SENSITIVE 3 +#define SQL_IC_MIXED 4 + +/* SQL_OJ_CAPABILITIES bitmasks */ +/* NB: this means 'outer join', not what you may be thinking */ + + +#if (ODBCVER >= 0x0201) +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L +#endif + +/* SQL_SCROLL_CONCURRENCY bitmasks */ +#define SQL_SCCO_READ_ONLY 0x00000001L +#define SQL_SCCO_LOCK 0x00000002L +#define SQL_SCCO_OPT_ROWVER 0x00000004L +#define SQL_SCCO_OPT_VALUES 0x00000008L + +/* SQL_TXN_CAPABLE values */ +#define SQL_TC_NONE 0 +#define SQL_TC_DML 1 +#define SQL_TC_ALL 2 +#define SQL_TC_DDL_COMMIT 3 +#define SQL_TC_DDL_IGNORE 4 + +/* SQL_TXN_ISOLATION_OPTION bitmasks */ +#define SQL_TXN_READ_UNCOMMITTED 0x00000001L +#define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED +#define SQL_TXN_READ_COMMITTED 0x00000002L +#define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED +#define SQL_TXN_REPEATABLE_READ 0x00000004L +#define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ +#define SQL_TXN_SERIALIZABLE 0x00000008L +#define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE + +/* SQL_NULL_COLLATION values */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLAllocConnect(SQLHENV EnvironmentHandle, + _Out_ SQLHDBC *ConnectionHandle); + +SQLRETURN SQL_API SQLAllocEnv(_Out_ SQLHENV *EnvironmentHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, _Out_ SQLHANDLE *OutputHandle); +#endif + +SQLRETURN SQL_API SQLAllocStmt(SQLHDBC ConnectionHandle, + _Out_ SQLHSTMT *StatementHandle); + +SQLRETURN SQL_API SQLBindCol(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, + _Inout_updates_opt_(_Inexpressible_(BufferLength)) SQLPOINTER TargetValue, + SQLLEN BufferLength, _Inout_opt_ SQLLEN *StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) +__declspec(deprecated("ODBC API: SQLBindParam is deprecated. Please use SQLBindParameter instead.")) +SQLRETURN SQL_API SQLBindParam(SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); +#endif + +SQLRETURN SQL_API SQLCancel(SQLHSTMT StatementHandle); + +#if (ODBCVER >= 0x0380) +SQLRETURN SQL_API SQLCancelHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle); +#endif // ODBCVER >= 0x0380 + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT StatementHandle); + +#ifdef _WIN64 +SQLRETURN SQL_API SQLColAttribute (SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, + _Out_writes_bytes_opt_(BufferLength) SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, + _Out_opt_ SQLSMALLINT *StringLength, _Out_opt_ SQLLEN *NumericAttribute); +#else +SQLRETURN SQL_API SQLColAttribute (SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, + _Out_writes_bytes_opt_(BufferLength) SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, + _Out_opt_ SQLSMALLINT *StringLength, _Out_opt_ SQLPOINTER NumericAttribute); +#endif +#endif + + +SQLRETURN SQL_API SQLColumns(SQLHSTMT StatementHandle, + _In_reads_opt_(NameLength1) SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + _In_reads_opt_(NameLength2) SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + _In_reads_opt_(NameLength3) SQLCHAR *TableName, SQLSMALLINT NameLength3, + _In_reads_opt_(NameLength4) SQLCHAR *ColumnName, SQLSMALLINT NameLength4); + +#if (ODBCVER >= 0x0380) +SQLRETURN SQL_API SQLCompleteAsync(SQLSMALLINT HandleType, + SQLHANDLE Handle, + _Out_ RETCODE* AsyncRetCodePtr); +#endif + +SQLRETURN SQL_API SQLConnect(SQLHDBC ConnectionHandle, + _In_reads_(NameLength1) SQLCHAR *ServerName, SQLSMALLINT NameLength1, + _In_reads_(NameLength2) SQLCHAR *UserName, SQLSMALLINT NameLength2, + _In_reads_(NameLength3) SQLCHAR *Authentication, SQLSMALLINT NameLength3); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle, + SQLHDESC TargetDescHandle); +#endif + +SQLRETURN SQL_API SQLDataSources(SQLHENV EnvironmentHandle, + SQLUSMALLINT Direction, _Out_writes_opt_(BufferLength1) SQLCHAR *ServerName, + SQLSMALLINT BufferLength1, _Out_opt_ SQLSMALLINT *NameLength1Ptr, + _Out_writes_opt_(BufferLength2) SQLCHAR *Description, SQLSMALLINT BufferLength2, + _Out_opt_ SQLSMALLINT *NameLength2Ptr); + +SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, _Out_writes_opt_(BufferLength) SQLCHAR *ColumnName, + SQLSMALLINT BufferLength, _Out_opt_ SQLSMALLINT *NameLength, + _Out_opt_ SQLSMALLINT *DataType, _Out_opt_ SQLULEN *ColumnSize, + _Out_opt_ SQLSMALLINT *DecimalDigits, _Out_opt_ SQLSMALLINT *Nullable); + +SQLRETURN SQL_API SQLDisconnect(SQLHDBC ConnectionHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT CompletionType); +#endif + +SQLRETURN SQL_API SQLError(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, + _Out_writes_(6) SQLCHAR *Sqlstate, _Out_opt_ SQLINTEGER *NativeError, + _Out_writes_opt_(BufferLength) SQLCHAR *MessageText, SQLSMALLINT BufferLength, + _Out_opt_ SQLSMALLINT *TextLength); + +SQLRETURN SQL_API SQLExecDirect +( + SQLHSTMT StatementHandle, + _In_reads_opt_(TextLength) SQLCHAR* StatementText, + SQLINTEGER TextLength +); + +SQLRETURN SQL_API SQLExecute(SQLHSTMT StatementHandle); + +SQLRETURN SQL_API SQLFetch(SQLHSTMT StatementHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, SQLLEN FetchOffset); +#endif + +SQLRETURN SQL_API SQLFreeConnect(SQLHDBC ConnectionHandle); + +SQLRETURN SQL_API SQLFreeEnv(SQLHENV EnvironmentHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle); +#endif + +SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT StatementHandle, + SQLUSMALLINT Option); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, _Out_writes_opt_(_Inexpressible_(BufferLength)) SQLPOINTER Value, + SQLINTEGER BufferLength, _Out_opt_ SQLINTEGER *StringLengthPtr); +__declspec(deprecated("ODBC API: SQLGetConnectOption is deprecated. Please use SQLGetConnectAttr instead.")) +#endif + +SQLRETURN SQL_API SQLGetConnectOption(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLPOINTER Value); + +SQLRETURN SQL_API SQLGetCursorName +( + SQLHSTMT StatementHandle, + _Out_writes_opt_(BufferLength) SQLCHAR *CursorName, + SQLSMALLINT BufferLength, + _Out_opt_ + SQLSMALLINT *NameLengthPtr +); + +SQLRETURN SQL_API SQLGetData(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, + _Out_writes_opt_(_Inexpressible_(BufferLength)) SQLPOINTER TargetValue, SQLLEN BufferLength, + _Out_opt_ SQLLEN *StrLen_or_IndPtr); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetDescField(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + _Out_writes_opt_(_Inexpressible_(BufferLength)) SQLPOINTER Value, SQLINTEGER BufferLength, + _Out_opt_ SQLINTEGER *StringLength); + +SQLRETURN SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, _Out_writes_opt_(BufferLength) SQLCHAR *Name, + SQLSMALLINT BufferLength, _Out_opt_ SQLSMALLINT *StringLengthPtr, + _Out_opt_ SQLSMALLINT *TypePtr, _Out_opt_ SQLSMALLINT *SubTypePtr, + _Out_opt_ SQLLEN *LengthPtr, _Out_opt_ SQLSMALLINT *PrecisionPtr, + _Out_opt_ SQLSMALLINT *ScalePtr, _Out_opt_ SQLSMALLINT *NullablePtr); + +SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, + _Out_writes_opt_(_Inexpressible_(BufferLength)) SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, + _Out_opt_ SQLSMALLINT *StringLength); + +SQLRETURN SQL_API SQLGetDiagRec +( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + _Out_writes_opt_(6) SQLCHAR *Sqlstate, + SQLINTEGER *NativeError, + _Out_writes_opt_(BufferLength) SQLCHAR* MessageText, + SQLSMALLINT BufferLength, + _Out_opt_ + SQLSMALLINT *TextLength +); + +SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, _Out_writes_(_Inexpressible_(BufferLength)) SQLPOINTER Value, + SQLINTEGER BufferLength, _Out_opt_ SQLINTEGER *StringLength); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLGetFunctions(SQLHDBC ConnectionHandle, + SQLUSMALLINT FunctionId, + _Out_writes_opt_(_Inexpressible_("Buffer length pfExists points to depends on fFunction value.")) + SQLUSMALLINT *Supported); + +_Success_(return == SQL_SUCCESS) +SQLRETURN SQL_API SQLGetInfo(SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, _Out_writes_bytes_opt_(BufferLength) SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, _Out_opt_ SQLSMALLINT *StringLengthPtr); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, _Out_writes_opt_(_Inexpressible_(BufferLength)) SQLPOINTER Value, + SQLINTEGER BufferLength, _Out_opt_ SQLINTEGER *StringLength); +__declspec(deprecated("ODBC API: SQLGetStmtOption is deprecated. Please use SQLGetStmtAttr instead.")) +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLPOINTER Value); + +SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + +SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT StatementHandle, + _Out_ SQLSMALLINT *ColumnCount); + +SQLRETURN SQL_API SQLParamData(SQLHSTMT StatementHandle, + _Out_opt_ SQLPOINTER *Value); + +SQLRETURN SQL_API SQLPrepare +( + SQLHSTMT StatementHandle, + _In_reads_(TextLength) SQLCHAR* StatementText, + SQLINTEGER TextLength +); + +SQLRETURN SQL_API SQLPutData(SQLHSTMT StatementHandle, + _In_reads_(_Inexpressible_(StrLen_or_Ind)) SQLPOINTER Data, SQLLEN StrLen_or_Ind); + +SQLRETURN SQL_API SQLRowCount(_In_ SQLHSTMT StatementHandle, + _Out_ SQLLEN* RowCount); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, _In_reads_bytes_opt_(StringLength) SQLPOINTER Value, + SQLINTEGER StringLength); +__declspec(deprecated("ODBC API: SQLSetConnectOption is deprecated. Please use SQLSetConnectAttr instead.")) +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLSetConnectOption(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLULEN Value); + +SQLRETURN SQL_API SQLSetCursorName +( + SQLHSTMT StatementHandle, + _In_reads_(NameLength) SQLCHAR* CursorName, + SQLSMALLINT NameLength +); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetDescField(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + _In_reads_(_Inexpressible_(BufferLength)) SQLPOINTER Value, SQLINTEGER BufferLength); + +SQLRETURN SQL_API SQLSetDescRec(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT Type, + SQLSMALLINT SubType, SQLLEN Length, + SQLSMALLINT Precision, SQLSMALLINT Scale, + _Inout_updates_bytes_opt_(Length) SQLPOINTER Data, _Inout_opt_ SQLLEN *StringLength, + _Inout_opt_ SQLLEN *Indicator); + +SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, _In_reads_bytes_opt_(StringLength) SQLPOINTER Value, + SQLINTEGER StringLength); +#endif /* ODBCVER >= 0x0300 */ + +__declspec(deprecated("ODBC API: SQLSetParam is deprecated. Please use SQLBindParameter instead.")) +SQLRETURN SQL_API SQLSetParam(SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, _In_reads_(_Inexpressible_(*StrLen_or_Ind)) SQLPOINTER ParameterValue, + _Inout_ SQLLEN *StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, _In_reads_(_Inexpressible_(StringLength)) SQLPOINTER Value, + SQLINTEGER StringLength); +__declspec(deprecated("ODBC API: SQLSetStmtOption is deprecated. Please use SQLSetStmtAttr instead.")) +#endif + +SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLULEN Value); + +SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT StatementHandle, + SQLUSMALLINT IdentifierType, + _In_reads_opt_(NameLength1) SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + _In_reads_opt_(NameLength2) SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + _In_reads_opt_(NameLength3) SQLCHAR *TableName, SQLSMALLINT NameLength3, + SQLUSMALLINT Scope, SQLUSMALLINT Nullable); + +SQLRETURN SQL_API SQLStatistics(SQLHSTMT StatementHandle, + _In_reads_opt_(NameLength1) SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + _In_reads_opt_(NameLength2) SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + _In_reads_opt_(NameLength3) SQLCHAR *TableName, SQLSMALLINT NameLength3, + SQLUSMALLINT Unique, SQLUSMALLINT Reserved); + +SQLRETURN SQL_API SQLTables(SQLHSTMT StatementHandle, + _In_reads_opt_(NameLength1) SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + _In_reads_opt_(NameLength2) SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + _In_reads_opt_(NameLength3) SQLCHAR *TableName, SQLSMALLINT NameLength3, + _In_reads_opt_(NameLength4) SQLCHAR *TableType, SQLSMALLINT NameLength4); + +SQLRETURN SQL_API SQLTransact(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType); + +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion + +#endif /* #ifndef __SQL */ diff --git a/Windows/inc/sqlext.h b/Windows/inc/sqlext.h new file mode 100644 index 00000000..850f67ff --- /dev/null +++ b/Windows/inc/sqlext.h @@ -0,0 +1,2437 @@ +/******************************************************** +* * +* Copyright (C) Microsoft. All rights reserved. * +* * +********************************************************/ + +//----------------------------------------------------------------------------- +// File: sqlext.h +// +// Contents: This is the include for applications using the Microsoft SQL Extensions +// +// Comments: +// +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __SQLEXT +#define __SQLEXT + +#include + +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + +#ifndef __SQL +#include "sql.h" +#endif + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* generally useful constants */ +#define SQL_SPEC_MAJOR 4 /* Major version of specification */ +#define SQL_SPEC_MINOR 00 /* Minor version of specification */ +#define SQL_SPEC_STRING "04.00" /* String constant for version */ + +#define SQL_SQLSTATE_SIZE 5 /* size of SQLSTATE */ + +typedef SQLTCHAR SQLSTATE[SQL_SQLSTATE_SIZE+1]; + +#define SQL_MAX_DSN_LENGTH 32 /* maximum data source name size */ + +#define SQL_MAX_OPTION_STRING_LENGTH 256 + +/* return code SQL_NO_DATA_FOUND is the same as SQL_NO_DATA */ +#if (ODBCVER < 0x0300) +#define SQL_NO_DATA_FOUND 100 +#else +#define SQL_NO_DATA_FOUND SQL_NO_DATA +#endif + +/* extended function return values */ +#if (ODBCVER >= 0x0400) +#define SQL_DATA_AVAILABLE 102 +#define SQL_METADATA_CHANGED 103 +#define SQL_MORE_DATA 104 +#endif /*ODBC >= 0x0400*/ + +/* an end handle type */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_SENV 5 +#endif /* ODBCVER >= 0x0300 */ + +/* env attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ODBC_VERSION 200 +#define SQL_ATTR_CONNECTION_POOLING 201 +#define SQL_ATTR_CP_MATCH 202 +// For private driver manager +#define SQL_ATTR_APPLICATION_KEY 203 +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_CONNECTION_POOLING */ +#define SQL_CP_OFF 0UL +#define SQL_CP_ONE_PER_DRIVER 1UL +#define SQL_CP_ONE_PER_HENV 2UL +#define SQL_CP_DRIVER_AWARE 3UL +#define SQL_CP_DEFAULT SQL_CP_OFF + +/* values for SQL_ATTR_CP_MATCH */ +#define SQL_CP_STRICT_MATCH 0UL +#define SQL_CP_RELAXED_MATCH 1UL +#define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH + +/* values for SQL_ATTR_ODBC_VERSION */ +#define SQL_OV_ODBC2 2UL +#define SQL_OV_ODBC3 3UL +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0380) +// new values for SQL_ATTR_ODBC_VERSION +// From ODBC 3.8 onwards, we should use * 100 + +#define SQL_OV_ODBC3_80 380UL +#endif /* ODBCVER >= 0x0380 */ + +#if (ODBCVER >= 0x0400) +#define SQL_OV_ODBC4 400UL +#endif /* ODBCVER >= 0x0400 */ + +/* connection attributes */ +#define SQL_ACCESS_MODE 101 +#define SQL_AUTOCOMMIT 102 +#define SQL_LOGIN_TIMEOUT 103 +#define SQL_OPT_TRACE 104 +#define SQL_OPT_TRACEFILE 105 +#define SQL_TRANSLATE_DLL 106 +#define SQL_TRANSLATE_OPTION 107 +#define SQL_TXN_ISOLATION 108 +#define SQL_CURRENT_QUALIFIER 109 +#define SQL_ODBC_CURSORS 110 +#define SQL_QUIET_MODE 111 +#define SQL_PACKET_SIZE 112 + +/* connection attributes with new names */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE +#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT +#define SQL_ATTR_CONNECTION_TIMEOUT 113 +#define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER +#define SQL_ATTR_DISCONNECT_BEHAVIOR 114 +#define SQL_ATTR_ENLIST_IN_DTC 1207 +#define SQL_ATTR_ENLIST_IN_XA 1208 +#define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT +#define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS +#define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE +#define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE +#define SQL_ATTR_TRACE SQL_OPT_TRACE +#define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE +#define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL +#define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION +#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ + +#if (ODBCVER >= 0x0351) +/* ODBC Driver Manager sets this connection attribute to a unicode driver + (which supports SQLConnectW) when the application is an ANSI application + (which calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect). + This is SetConnectAttr only and application does not set this attribute + This attribute was introduced because some unicode driver's some APIs may + need to behave differently on ANSI or Unicode applications. A unicode + driver, which has same behavior for both ANSI or Unicode applications, + should return SQL_ERROR when the driver manager sets this connection + attribute. When a unicode driver returns SQL_SUCCESS on this attribute, + the driver manager treates ANSI and Unicode connections differently in + connection pooling. +*/ +#define SQL_ATTR_ANSI_APP 115 +#endif + +#if (ODBCVER >= 0x0380) +#define SQL_ATTR_RESET_CONNECTION 116 +#define SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE 117 +#endif + +// Connection attribute 118 is defined in sqlspi.h + +#if (ODBCVER >= 0x0380) +#define SQL_ATTR_ASYNC_DBC_EVENT 119 +#endif /* ODBCVER >= 0x0380 */ + +// Connection attribute 120 and 121 are defined in sqlspi.h + +#if (ODBCVER >= 0x0400) +#define SQL_ATTR_CREDENTIALS 122 +#define SQL_ATTR_REFRESH_CONNECTION 123 +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_CONNECT_OPT_DRVR_START is not meaningful for 3.0 driver */ +#if (ODBCVER < 0x0300) +#define SQL_CONNECT_OPT_DRVR_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE +#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE +#endif /* ODBCVER < 0x0300 */ + +/* SQL_ACCESS_MODE options */ +#define SQL_MODE_READ_WRITE 0UL +#define SQL_MODE_READ_ONLY 1UL +#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE + +/* SQL_AUTOCOMMIT options */ +#define SQL_AUTOCOMMIT_OFF 0UL +#define SQL_AUTOCOMMIT_ON 1UL +#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON + +/* SQL_LOGIN_TIMEOUT options */ +#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL + +/* SQL_OPT_TRACE options */ +#define SQL_OPT_TRACE_OFF 0UL +#define SQL_OPT_TRACE_ON 1UL +#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF +#define SQL_OPT_TRACE_FILE_DEFAULT "\\SQL.LOG" + +/* SQL_ODBC_CURSORS options */ +#pragma deprecated(SQL_CUR_USE_IF_NEEDED,SQL_CUR_USE_ODBC) +// SQL_CUR_USE_IF_NEEDED and SQL_CUR_USE_ODBC are deprecated. +// Please use SQL_CUR_USE_DRIVER for cursor functionalities provided by drivers +#define SQL_CUR_USE_IF_NEEDED 0UL +#define SQL_CUR_USE_ODBC 1UL +#define SQL_CUR_USE_DRIVER 2UL +#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_DISCONNECT_BEHAVIOR */ +#define SQL_DB_RETURN_TO_POOL 0UL +#define SQL_DB_DISCONNECT 1UL +#define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL + +/* values for SQL_ATTR_ENLIST_IN_DTC */ +#define SQL_DTC_DONE 0L +#endif /* ODBCVER >= 0x0300 */ + +/* values for SQL_ATTR_CONNECTION_DEAD */ +#define SQL_CD_TRUE 1L /* Connection is closed/dead */ +#define SQL_CD_FALSE 0L /* Connection is open/available */ + +/* values for SQL_ATTR_ANSI_APP */ +#if (ODBCVER >= 0x0351) +#define SQL_AA_TRUE 1L /* the application is an ANSI app */ +#define SQL_AA_FALSE 0L /* the application is a Unicode app */ +#endif + +/* values for SQL_ATTR_RESET_CONNECTION */ +#if (ODBCVER >= 0x0380) +#define SQL_RESET_CONNECTION_YES 1UL +#endif + +/* values for SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE */ +#if (ODBCVER >= 0x0380) +#define SQL_ASYNC_DBC_ENABLE_ON 1UL +#define SQL_ASYNC_DBC_ENABLE_OFF 0UL +#define SQL_ASYNC_DBC_ENABLE_DEFAULT SQL_ASYNC_DBC_ENABLE_OFF +#endif // ODBCVER >= 0x0380 + +/* values for SQL_ATTR_REFRESH_CONNECTION */ +#if (ODBCVER >= 0x0400) +#define SQL_REFRESH_NOW -1 +#define SQL_REFRESH_AUTO 0 +#define SQL_REFRESH_MANUAL 1 +#endif /* ODBCVER >= 0x0400 */ + +/* statement attributes */ +#define SQL_QUERY_TIMEOUT 0 +#define SQL_MAX_ROWS 1 +#define SQL_NOSCAN 2 +#define SQL_MAX_LENGTH 3 +#define SQL_ASYNC_ENABLE 4 +#define SQL_BIND_TYPE 5 +#define SQL_CURSOR_TYPE 6 +#define SQL_CONCURRENCY 7 +#define SQL_KEYSET_SIZE 8 +#define SQL_ROWSET_SIZE 9 +#define SQL_SIMULATE_CURSOR 10 +#define SQL_RETRIEVE_DATA 11 +#define SQL_USE_BOOKMARKS 12 +#define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */ +#define SQL_ROW_NUMBER 14 /* GetStmtOption Only */ + +/* statement attributes for ODBC 3.0 */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ASYNC_ENABLE SQL_ASYNC_ENABLE +#define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY +#define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE +#define SQL_ATTR_ENABLE_AUTO_IPD 15 +#define SQL_ATTR_FETCH_BOOKMARK_PTR 16 +#define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE +#define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH +#define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS +#define SQL_ATTR_NOSCAN SQL_NOSCAN +#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17 +#define SQL_ATTR_PARAM_BIND_TYPE 18 +#define SQL_ATTR_PARAM_OPERATION_PTR 19 +#define SQL_ATTR_PARAM_STATUS_PTR 20 +#define SQL_ATTR_PARAMS_PROCESSED_PTR 21 +#define SQL_ATTR_PARAMSET_SIZE 22 +#define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT +#define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA +#define SQL_ATTR_ROW_BIND_OFFSET_PTR 23 +#define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE +#define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/ +#define SQL_ATTR_ROW_OPERATION_PTR 24 +#define SQL_ATTR_ROW_STATUS_PTR 25 +#define SQL_ATTR_ROWS_FETCHED_PTR 26 +#define SQL_ATTR_ROW_ARRAY_SIZE 27 +#define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR +#define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0380) +#define SQL_ATTR_ASYNC_STMT_EVENT 29 +#endif /* ODBCVER >= 0x0380 */ + +#if (ODBCVER >= 0x0400) +#define SQL_ATTR_SAMPLE_SIZE 30 +#define SQL_ATTR_DYNAMIC_COLUMNS 31 +#define SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR 32 +#define SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR 33 +#endif /* ODBCVER >= 0x0400 */ + +#if (ODBCVER < 0x0300) +#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER +#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT +#endif /* ODBCVER < 0x0300 */ + +/* SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR values */ +#if (ODBCVER >= 0x0400) +#define SQL_TE_ERROR 0x0001 +#define SQL_TE_CONTINUE 0x0002 +#define SQL_TE_REPORT 0x0003 +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_ATTR_LENGTH_EXCEPTION_BEHAVIOR values */ +#if (ODBCVER >= 0x0400) +#define SQL_LE_CONTINUE 0x0001 +#define SQL_LE_REPORT 0x0002 +#endif /* ODBCVER >= 0x0400 */ + +/* New defines for SEARCHABLE column in SQLGetTypeInfo */ + +#if (ODBCVER >= 0x0300) +#define SQL_COL_PRED_CHAR SQL_LIKE_ONLY +#define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE +#endif /* ODBCVER >= 0x0300 */ + + + +/* whether an attribute is a pointer or not */ +#if (ODBCVER >= 0x0300) +#define SQL_IS_POINTER (-4) +#define SQL_IS_UINTEGER (-5) +#define SQL_IS_INTEGER (-6) +#define SQL_IS_USMALLINT (-7) +#define SQL_IS_SMALLINT (-8) +#endif /* ODBCVER >= 0x0300 */ + +/* the value of SQL_ATTR_PARAM_BIND_TYPE */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_BIND_BY_COLUMN 0UL +#define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUERY_TIMEOUT options */ +#define SQL_QUERY_TIMEOUT_DEFAULT 0UL + +/* SQL_MAX_ROWS options */ +#define SQL_MAX_ROWS_DEFAULT 0UL + +/* SQL_NOSCAN options */ +#define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */ +#define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */ +#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF + +/* SQL_MAX_LENGTH options */ +#define SQL_MAX_LENGTH_DEFAULT 0UL + +/* values for SQL_ATTR_ASYNC_ENABLE */ +#define SQL_ASYNC_ENABLE_OFF 0UL +#define SQL_ASYNC_ENABLE_ON 1UL +#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF + +/* SQL_BIND_TYPE options */ +#define SQL_BIND_BY_COLUMN 0UL +#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN /* Default value */ + +/* SQL_CONCURRENCY options */ +#define SQL_CONCUR_READ_ONLY 1 +#define SQL_CONCUR_LOCK 2 +#define SQL_CONCUR_ROWVER 3 +#define SQL_CONCUR_VALUES 4 +#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY /* Default value */ + +/* SQL_CURSOR_TYPE options */ +#define SQL_CURSOR_FORWARD_ONLY 0UL +#define SQL_CURSOR_KEYSET_DRIVEN 1UL +#define SQL_CURSOR_DYNAMIC 2UL +#define SQL_CURSOR_STATIC 3UL +#define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY /* Default value */ + +/* SQL_ROWSET_SIZE options */ +#define SQL_ROWSET_SIZE_DEFAULT 1UL + +/* SQL_KEYSET_SIZE options */ +#define SQL_KEYSET_SIZE_DEFAULT 0UL + +/* SQL_SIMULATE_CURSOR options */ +#define SQL_SC_NON_UNIQUE 0UL +#define SQL_SC_TRY_UNIQUE 1UL +#define SQL_SC_UNIQUE 2UL + +/* SQL_RETRIEVE_DATA options */ +#define SQL_RD_OFF 0UL +#define SQL_RD_ON 1UL +#define SQL_RD_DEFAULT SQL_RD_ON + +/* SQL_USE_BOOKMARKS options */ +#define SQL_UB_OFF 0UL +#define SQL_UB_ON 01UL +#define SQL_UB_DEFAULT SQL_UB_OFF + +/* New values for SQL_USE_BOOKMARKS attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_UB_FIXED SQL_UB_ON +#define SQL_UB_VARIABLE 2UL +#endif /* ODBCVER >= 0x0300 */ + +/* extended descriptor field */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ARRAY_SIZE 20 +#define SQL_DESC_ARRAY_STATUS_PTR 21 +#define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT +#define SQL_DESC_BASE_COLUMN_NAME 22 +#define SQL_DESC_BASE_TABLE_NAME 23 +#define SQL_DESC_BIND_OFFSET_PTR 24 +#define SQL_DESC_BIND_TYPE 25 +#define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE +#define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME +#define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE +#define SQL_DESC_DATETIME_INTERVAL_PRECISION 26 +#define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE +#define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY +#define SQL_DESC_LABEL SQL_COLUMN_LABEL +#define SQL_DESC_LITERAL_PREFIX 27 +#define SQL_DESC_LITERAL_SUFFIX 28 +#define SQL_DESC_LOCAL_TYPE_NAME 29 +#define SQL_DESC_MAXIMUM_SCALE 30 +#define SQL_DESC_MINIMUM_SCALE 31 +#define SQL_DESC_NUM_PREC_RADIX 32 +#define SQL_DESC_PARAMETER_TYPE 33 +#define SQL_DESC_ROWS_PROCESSED_PTR 34 +#if (ODBCVER >= 0x0350) +#define SQL_DESC_ROWVER 35 +#endif /* ODBCVER >= 0x0350 */ +#define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME +#define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE +#define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME +#define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME +#define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED +#define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0400) +#define SQL_DESC_MIME_TYPE 36 +#endif /* ODBCVER >= 0x0400 */ + + +/* defines for diagnostics fields */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_CURSOR_ROW_COUNT (-1249) +#define SQL_DIAG_ROW_NUMBER (-1248) +#define SQL_DIAG_COLUMN_NUMBER (-1247) +#endif /* ODBCVER >= 0x0300 */ + +/* SQL extended datatypes */ +#define SQL_DATE 9 +#if (ODBCVER >= 0x0300) +#define SQL_INTERVAL 10 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_TIME 10 +#define SQL_TIMESTAMP 11 +#define SQL_LONGVARCHAR (-1) +#define SQL_BINARY (-2) +#define SQL_VARBINARY (-3) +#define SQL_LONGVARBINARY (-4) +#define SQL_BIGINT (-5) +#define SQL_TINYINT (-6) +#define SQL_BIT (-7) +#if (ODBCVER >= 0x0350) +#define SQL_GUID (-11) +#endif /* ODBCVER >= 0x0350 */ + +#if (ODBCVER >= 0x0300) +/* interval code */ +#define SQL_CODE_YEAR 1 +#define SQL_CODE_MONTH 2 +#define SQL_CODE_DAY 3 +#define SQL_CODE_HOUR 4 +#define SQL_CODE_MINUTE 5 +#define SQL_CODE_SECOND 6 +#define SQL_CODE_YEAR_TO_MONTH 7 +#define SQL_CODE_DAY_TO_HOUR 8 +#define SQL_CODE_DAY_TO_MINUTE 9 +#define SQL_CODE_DAY_TO_SECOND 10 +#define SQL_CODE_HOUR_TO_MINUTE 11 +#define SQL_CODE_HOUR_TO_SECOND 12 +#define SQL_CODE_MINUTE_TO_SECOND 13 + +#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR) +#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH) +#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY) +#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR) +#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE) +#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND) +#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH) +#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR) +#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE) +#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND) +#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE) +#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND) +#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND) + +#else +#define SQL_INTERVAL_YEAR (-80) +#define SQL_INTERVAL_MONTH (-81) +#define SQL_INTERVAL_YEAR_TO_MONTH (-82) +#define SQL_INTERVAL_DAY (-83) +#define SQL_INTERVAL_HOUR (-84) +#define SQL_INTERVAL_MINUTE (-85) +#define SQL_INTERVAL_SECOND (-86) +#define SQL_INTERVAL_DAY_TO_HOUR (-87) +#define SQL_INTERVAL_DAY_TO_MINUTE (-88) +#define SQL_INTERVAL_DAY_TO_SECOND (-89) +#define SQL_INTERVAL_HOUR_TO_MINUTE (-90) +#define SQL_INTERVAL_HOUR_TO_SECOND (-91) +#define SQL_INTERVAL_MINUTE_TO_SECOND (-92) +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER <= 0x0300) +#define SQL_UNICODE (-95) +#define SQL_UNICODE_VARCHAR (-96) +#define SQL_UNICODE_LONGVARCHAR (-97) +#define SQL_UNICODE_CHAR SQL_UNICODE +#else +/* The previous definitions for SQL_UNICODE_ are historical and obsolete */ + +#define SQL_UNICODE SQL_WCHAR + +#define SQL_UNICODE_VARCHAR SQL_WVARCHAR +#define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR +#define SQL_UNICODE_CHAR SQL_WCHAR +#endif + +#if (ODBCVER < 0x0300) +#define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR +#define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR +#endif /* ODBCVER < 0x0300 */ + +/* C datatype to SQL datatype mapping SQL types + ------------------- */ +#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */ +#define SQL_C_LONG SQL_INTEGER /* INTEGER */ +#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */ +#define SQL_C_FLOAT SQL_REAL /* REAL */ +#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */ +#if (ODBCVER >= 0x0300) +#define SQL_C_NUMERIC SQL_NUMERIC +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_DEFAULT 99 + +#define SQL_SIGNED_OFFSET (-20) +#define SQL_UNSIGNED_OFFSET (-22) + +/* C datatype to SQL datatype mapping */ +#define SQL_C_DATE SQL_DATE +#define SQL_C_TIME SQL_TIME +#define SQL_C_TIMESTAMP SQL_TIMESTAMP +#if (ODBCVER >= 0x0300) +#define SQL_C_TYPE_DATE SQL_TYPE_DATE +#define SQL_C_TYPE_TIME SQL_TYPE_TIME +#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP +#if (ODBCVER >= 0x0400) +#define SQL_C_TYPE_TIME_WITH_TIMEZONE SQL_TYPE_TIME_WITH_TIMEZONE +#define SQL_C_TYPE_TIMESTAMP_WITH_TIMEZONE SQL_TYPE_TIMESTAMP_WITH_TIMEZONE +#endif /* ODBCVER >= 0x0400 */ +#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR +#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH +#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY +#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR +#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE +#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND +#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH +#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR +#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE +#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND +#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE +#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND +#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_BINARY SQL_BINARY +#define SQL_C_BIT SQL_BIT +#if (ODBCVER >= 0x0300) +#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) /* SIGNED BIGINT */ +#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */ +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_TINYINT SQL_TINYINT +#define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) /* SIGNED INTEGER */ +#define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) /* SIGNED SMALLINT */ +#define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) /* SIGNED TINYINT */ +#define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) /* UNSIGNED INTEGER*/ +#define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) /* UNSIGNED SMALLINT*/ +#define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED TINYINT*/ + +#ifdef _WIN64 +#define SQL_C_BOOKMARK SQL_C_UBIGINT /* BOOKMARK */ +#else +#define SQL_C_BOOKMARK SQL_C_ULONG /* BOOKMARK */ +#endif + +#if (ODBCVER >= 0x0350) +#define SQL_C_GUID SQL_GUID +#endif /* ODBCVER >= 0x0350 */ + +#define SQL_TYPE_NULL 0 +#if (ODBCVER < 0x0300) +#define SQL_TYPE_MIN SQL_BIT +#define SQL_TYPE_MAX SQL_VARCHAR +#endif + +// base value of driver-specific C-Type (max is 0x7fff) +// define driver-specific C-Type, named as SQL_DRIVER_C_TYPE_BASE, +// SQL_DRIVER_C_TYPE_BASE+1, SQL_DRIVER_C_TYPE_BASE+2, etc. +#if (ODBCVER >= 0x380) +#define SQL_DRIVER_C_TYPE_BASE 0x4000 +#endif + +// base value of driver-specific fields/attributes (max are 0x7fff [16-bit] or 0x00007fff [32-bit]) +// define driver-specific SQL-Type, named as SQL_DRIVER_SQL_TYPE_BASE, +// SQL_DRIVER_SQL_TYPE_BASE+1, SQL_DRIVER_SQL_TYPE_BASE+2, etc. +// +// Please note that there is no runtime change in this version of DM. +// However, we suggest that driver manufacturers adhere to this range +// as future versions of the DM may enforce these constraints +#if (ODBCVER >= 0x380) +#define SQL_DRIVER_SQL_TYPE_BASE 0x4000 +#define SQL_DRIVER_DESC_FIELD_BASE 0x4000 +#define SQL_DRIVER_DIAG_FIELD_BASE 0x4000 +#define SQL_DRIVER_INFO_TYPE_BASE 0x4000 +#define SQL_DRIVER_CONN_ATTR_BASE 0x00004000 // 32-bit +#define SQL_DRIVER_STMT_ATTR_BASE 0x00004000 // 32-bit +#endif + +#if (ODBCVER >= 0x0300) +#define SQL_C_VARBOOKMARK SQL_C_BINARY +#endif /* ODBCVER >= 0x0300 */ + +/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */ +#if (ODBCVER >= 0x0300) +#define SQL_NO_ROW_NUMBER (-1) +#define SQL_NO_COLUMN_NUMBER (-1) +#define SQL_ROW_NUMBER_UNKNOWN (-2) +#define SQL_COLUMN_NUMBER_UNKNOWN (-2) +#endif + +/* SQLBindParameter extensions */ +#define SQL_DEFAULT_PARAM (-5) +#define SQL_IGNORE (-6) +#if (ODBCVER >= 0x0300) +#define SQL_COLUMN_IGNORE SQL_IGNORE +#endif /* ODBCVER >= 0x0300 */ +#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) +#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET) + +/* binary length for driver specific attributes */ +#define SQL_LEN_BINARY_ATTR_OFFSET (-100) +#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) + +/* Defines used by Driver Manager when mapping SQLSetParam to SQLBindParameter +*/ +#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT +#define SQL_SETPARAM_VALUE_MAX (-1L) + +/* Extended length/indicator values Values */ +#if (ODBCVER >= 0x0400) +#define SQL_DATA_UNAVAILABLE SQL_IGNORE +#define SQL_DATA_AT_FETCH SQL_DATA_AT_EXEC +#define SQL_TYPE_EXCEPTION (-20) +#endif /* ODBCVER >= 0x400 */ + +/* SQLColAttributes defines */ +#define SQL_COLUMN_COUNT 0 +#define SQL_COLUMN_NAME 1 +#define SQL_COLUMN_TYPE 2 +#define SQL_COLUMN_LENGTH 3 +#define SQL_COLUMN_PRECISION 4 +#define SQL_COLUMN_SCALE 5 +#define SQL_COLUMN_DISPLAY_SIZE 6 +#define SQL_COLUMN_NULLABLE 7 +#define SQL_COLUMN_UNSIGNED 8 +#define SQL_COLUMN_MONEY 9 +#define SQL_COLUMN_UPDATABLE 10 +#define SQL_COLUMN_AUTO_INCREMENT 11 +#define SQL_COLUMN_CASE_SENSITIVE 12 +#define SQL_COLUMN_SEARCHABLE 13 +#define SQL_COLUMN_TYPE_NAME 14 +#define SQL_COLUMN_TABLE_NAME 15 +#define SQL_COLUMN_OWNER_NAME 16 +#define SQL_COLUMN_QUALIFIER_NAME 17 +#define SQL_COLUMN_LABEL 18 +#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL +#if (ODBCVER < 0x0300) +#define SQL_COLUMN_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT + +/* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */ +#define SQL_ATTR_READONLY 0 +#define SQL_ATTR_WRITE 1 +#define SQL_ATTR_READWRITE_UNKNOWN 2 + +/* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */ +/* These are also used by SQLGetInfo */ +#define SQL_UNSEARCHABLE 0 +#define SQL_LIKE_ONLY 1 +#define SQL_ALL_EXCEPT_LIKE 2 +#define SQL_SEARCHABLE 3 +#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE + + +/* Special return values for SQLGetData */ +#define SQL_NO_TOTAL (-4) + +/********************************************/ +/* SQLGetFunctions: additional values for */ +/* fFunction to represent functions that */ +/* are not in the X/Open spec. */ +/********************************************/ + +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLESTD 73 +#define SQL_API_SQLBULKOPERATIONS 24 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLBINDPARAMETER 72 +#define SQL_API_SQLBROWSECONNECT 55 +#define SQL_API_SQLCOLATTRIBUTES 6 +#define SQL_API_SQLCOLUMNPRIVILEGES 56 +#define SQL_API_SQLDESCRIBEPARAM 58 +#define SQL_API_SQLDRIVERCONNECT 41 +#define SQL_API_SQLDRIVERS 71 +#define SQL_API_SQLEXTENDEDFETCH 59 +#define SQL_API_SQLFOREIGNKEYS 60 +#define SQL_API_SQLMORERESULTS 61 +#define SQL_API_SQLNATIVESQL 62 +#define SQL_API_SQLNUMPARAMS 63 +#define SQL_API_SQLPARAMOPTIONS 64 +#define SQL_API_SQLPRIMARYKEYS 65 +#define SQL_API_SQLPROCEDURECOLUMNS 66 +#define SQL_API_SQLPROCEDURES 67 +#define SQL_API_SQLSETPOS 68 +#define SQL_API_SQLSETSCROLLOPTIONS 69 +#define SQL_API_SQLTABLEPRIVILEGES 70 + +#if (ODBCVER >= 0x0400) +#define SQL_API_SQLGETNESTEDHANDLE 74 +#define SQL_API_SQLSTRUCTUREDTYPES 75 +#define SQL_API_SQLSTRUCTUREDTYPECOLUMNS 76 +#define SQL_API_SQLNEXTCOLUMN 77 +#endif /* ODBCVER >= 0x0400 */ + +/*-------------------------------------------*/ +/* SQL_EXT_API_LAST is not useful with ODBC */ +/* version 3.0 because some of the values */ +/* from X/Open are in the 10000 range. */ +/*-------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER +#define SQL_NUM_FUNCTIONS 23 +#define SQL_EXT_API_START 40 +#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1) +#endif + +/*--------------------------------------------*/ +/* SQL_API_ALL_FUNCTIONS returns an array */ +/* of 'booleans' representing whether a */ +/* function is implemented by the driver. */ +/* */ +/* CAUTION: Only functions defined in ODBC */ +/* version 2.0 and earlier are returned, the */ +/* new high-range function numbers defined by */ +/* X/Open break this scheme. See the new */ +/* method -- SQL_API_ODBC3_ALL_FUNCTIONS */ +/*--------------------------------------------*/ + +#define SQL_API_ALL_FUNCTIONS 0 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* 2.X drivers export a dummy function with */ +/* ordinal number SQL_API_LOADBYORDINAL to speed*/ +/* loading under the windows operating system. */ +/* */ +/* CAUTION: Loading by ordinal is not supported */ +/* for 3.0 and above drivers. */ +/*----------------------------------------------*/ + +#define SQL_API_LOADBYORDINAL 199 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* SQL_API_ODBC3_ALL_FUNCTIONS */ +/* This returns a bitmap, which allows us to */ +/* handle the higher-valued function numbers. */ +/* Use SQL_FUNC_EXISTS(bitmap,function_number) */ +/* to determine if the function exists. */ +/*----------------------------------------------*/ + + +#if (ODBCVER >= 0x0300) +#define SQL_API_ODBC3_ALL_FUNCTIONS 999 +#define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 /* array of 250 words */ + +#define SQL_FUNC_EXISTS(pfExists, uwAPI) \ + ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \ + & (1 << ((uwAPI) & 0x000F)) \ + ) ? SQL_TRUE : SQL_FALSE \ + ) +#endif /* ODBCVER >= 0x0300 */ + + +/************************************************/ +/* Extended definitions for SQLGetInfo */ +/************************************************/ + +/*---------------------------------*/ +/* Values in ODBC 2.0 that are not */ +/* in the X/Open spec */ +/*---------------------------------*/ + +#define SQL_INFO_FIRST 0 +#define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */ +#define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */ +#define SQL_DRIVER_HDBC 3 +#define SQL_DRIVER_HENV 4 +#define SQL_DRIVER_HSTMT 5 +#define SQL_DRIVER_NAME 6 +#define SQL_DRIVER_VER 7 +#define SQL_ODBC_API_CONFORMANCE 9 +#define SQL_ODBC_VER 10 +#define SQL_ROW_UPDATES 11 +#define SQL_ODBC_SAG_CLI_CONFORMANCE 12 +#define SQL_ODBC_SQL_CONFORMANCE 15 +#define SQL_PROCEDURES 21 +#define SQL_CONCAT_NULL_BEHAVIOR 22 +#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 +#define SQL_EXPRESSIONS_IN_ORDERBY 27 +#define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */ +#define SQL_MAX_PROCEDURE_NAME_LEN 33 +#define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */ +#define SQL_MULT_RESULT_SETS 36 +#define SQL_MULTIPLE_ACTIVE_TXN 37 +#define SQL_OUTER_JOINS 38 +#define SQL_OWNER_TERM 39 +#define SQL_PROCEDURE_TERM 40 +#define SQL_QUALIFIER_NAME_SEPARATOR 41 +#define SQL_QUALIFIER_TERM 42 +#define SQL_SCROLL_OPTIONS 44 +#define SQL_TABLE_TERM 45 +#define SQL_CONVERT_FUNCTIONS 48 +#define SQL_NUMERIC_FUNCTIONS 49 +#define SQL_STRING_FUNCTIONS 50 +#define SQL_SYSTEM_FUNCTIONS 51 +#define SQL_TIMEDATE_FUNCTIONS 52 +#define SQL_CONVERT_BIGINT 53 +#define SQL_CONVERT_BINARY 54 +#define SQL_CONVERT_BIT 55 +#define SQL_CONVERT_CHAR 56 +#define SQL_CONVERT_DATE 57 +#define SQL_CONVERT_DECIMAL 58 +#define SQL_CONVERT_DOUBLE 59 +#define SQL_CONVERT_FLOAT 60 +#define SQL_CONVERT_INTEGER 61 +#define SQL_CONVERT_LONGVARCHAR 62 +#define SQL_CONVERT_NUMERIC 63 +#define SQL_CONVERT_REAL 64 +#define SQL_CONVERT_SMALLINT 65 +#define SQL_CONVERT_TIME 66 +#define SQL_CONVERT_TIMESTAMP 67 +#define SQL_CONVERT_TINYINT 68 +#define SQL_CONVERT_VARBINARY 69 +#define SQL_CONVERT_VARCHAR 70 +#define SQL_CONVERT_LONGVARBINARY 71 +#define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */ +#define SQL_CORRELATION_NAME 74 +#define SQL_NON_NULLABLE_COLUMNS 75 +#define SQL_DRIVER_HLIB 76 +#define SQL_DRIVER_ODBC_VER 77 +#define SQL_LOCK_TYPES 78 +#define SQL_POS_OPERATIONS 79 +#define SQL_POSITIONED_STATEMENTS 80 +#define SQL_BOOKMARK_PERSISTENCE 82 +#define SQL_STATIC_SENSITIVITY 83 +#define SQL_FILE_USAGE 84 +#define SQL_COLUMN_ALIAS 87 +#define SQL_GROUP_BY 88 +#define SQL_KEYWORDS 89 +#define SQL_OWNER_USAGE 91 +#define SQL_QUALIFIER_USAGE 92 +#define SQL_QUOTED_IDENTIFIER_CASE 93 +#define SQL_SUBQUERIES 95 +#define SQL_UNION 96 +#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 +#define SQL_MAX_CHAR_LITERAL_LEN 108 +#define SQL_TIMEDATE_ADD_INTERVALS 109 +#define SQL_TIMEDATE_DIFF_INTERVALS 110 +#define SQL_NEED_LONG_DATA_LEN 111 +#define SQL_MAX_BINARY_LITERAL_LEN 112 +#define SQL_LIKE_ESCAPE_CLAUSE 113 +#define SQL_QUALIFIER_LOCATION 114 + +#if (ODBCVER >= 0x0201 && ODBCVER < 0x0300) +#define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */ +#endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */ + +/*----------------------------------------------*/ +/* SQL_INFO_LAST and SQL_INFO_DRIVER_START are */ +/* not useful anymore, because X/Open has */ +/* values in the 10000 range. You */ +/* must contact X/Open directly to get a range */ +/* of numbers for driver-specific values. */ +/*----------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION +#define SQL_INFO_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +/*-----------------------------------------------*/ +/* ODBC 3.0 SQLGetInfo values that are not part */ +/* of the X/Open standard at this time. X/Open */ +/* standard values are in sql.h. */ +/*-----------------------------------------------*/ + +#if (ODBCVER >= 0x0300) +#define SQL_ACTIVE_ENVIRONMENTS 116 +#define SQL_ALTER_DOMAIN 117 + +#define SQL_SQL_CONFORMANCE 118 +#define SQL_DATETIME_LITERALS 119 + +#define SQL_ASYNC_MODE 10021 /* new X/Open spec */ +#define SQL_BATCH_ROW_COUNT 120 +#define SQL_BATCH_SUPPORT 121 +#define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION +#define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR +#define SQL_CATALOG_TERM SQL_QUALIFIER_TERM +#define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE +#define SQL_CONVERT_WCHAR 122 +#define SQL_CONVERT_INTERVAL_DAY_TIME 123 +#define SQL_CONVERT_INTERVAL_YEAR_MONTH 124 +#define SQL_CONVERT_WLONGVARCHAR 125 +#define SQL_CONVERT_WVARCHAR 126 +#define SQL_CREATE_ASSERTION 127 +#define SQL_CREATE_CHARACTER_SET 128 +#define SQL_CREATE_COLLATION 129 +#define SQL_CREATE_DOMAIN 130 +#define SQL_CREATE_SCHEMA 131 +#define SQL_CREATE_TABLE 132 +#define SQL_CREATE_TRANSLATION 133 +#define SQL_CREATE_VIEW 134 +#define SQL_DRIVER_HDESC 135 +#define SQL_DROP_ASSERTION 136 +#define SQL_DROP_CHARACTER_SET 137 +#define SQL_DROP_COLLATION 138 +#define SQL_DROP_DOMAIN 139 +#define SQL_DROP_SCHEMA 140 +#define SQL_DROP_TABLE 141 +#define SQL_DROP_TRANSLATION 142 +#define SQL_DROP_VIEW 143 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147 +#define SQL_INDEX_KEYWORDS 148 +#define SQL_INFO_SCHEMA_VIEWS 149 +#define SQL_KEYSET_CURSOR_ATTRIBUTES1 150 +#define SQL_KEYSET_CURSOR_ATTRIBUTES2 151 +#define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */ +#define SQL_ODBC_INTERFACE_CONFORMANCE 152 +#define SQL_PARAM_ARRAY_ROW_COUNTS 153 +#define SQL_PARAM_ARRAY_SELECTS 154 +#define SQL_SCHEMA_TERM SQL_OWNER_TERM +#define SQL_SCHEMA_USAGE SQL_OWNER_USAGE +#define SQL_SQL92_DATETIME_FUNCTIONS 155 +#define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156 +#define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157 +#define SQL_SQL92_GRANT 158 +#define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159 +#define SQL_SQL92_PREDICATES 160 +#define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161 +#define SQL_SQL92_REVOKE 162 +#define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163 +#define SQL_SQL92_STRING_FUNCTIONS 164 +#define SQL_SQL92_VALUE_EXPRESSIONS 165 +#define SQL_STANDARD_CLI_CONFORMANCE 166 +#define SQL_STATIC_CURSOR_ATTRIBUTES1 167 +#define SQL_STATIC_CURSOR_ATTRIBUTES2 168 + +#define SQL_AGGREGATE_FUNCTIONS 169 +#define SQL_DDL_INDEX 170 +#define SQL_DM_VER 171 +#define SQL_INSERT_STATEMENT 172 +#define SQL_CONVERT_GUID 173 +#define SQL_UNION_STATEMENT SQL_UNION + +#if (ODBCVER >= 0x0400) +#define SQL_SCHEMA_INFERENCE 174 +#define SQL_BINARY_FUNCTIONS 175 +#define SQL_ISO_STRING_FUNCTIONS 176 +#define SQL_ISO_BINARY_FUNCTIONS 177 +#define SQL_LIMIT_ESCAPE_CLAUSE 178 +#define SQL_NATIVE_ESCAPE_CLAUSE 179 +#define SQL_RETURN_ESCAPE_CLAUSE 180 +#define SQL_FORMAT_ESCAPE_CLAUSE 181 +#define SQL_ISO_DATETIME_FUNCTIONS SQL_SQL92_DATETIME_FUNCTIONS +#define SQL_ISO_FOREIGN_KEY_DELETE_RULE SQL_SQL92_FOREIGN_KEY_DELETE_RULE +#define SQL_ISO_FOREIGN_KEY_UPDATE_RULE SQL_SQL92_FOREIGN_KEY_UPDATE_RULE +#define SQL_ISO_GRANT SQL_SQL92_GRANT +#define SQL_ISO_NUMERIC_VALUE_FUNCTIONS SQL_SQL92_NUMERIC_VALUE_FUNCTIONS +#define SQL_ISO_PREDICATES SQL_SQL92_PREDICATES +#define SQL_ISO_RELATIONAL_JOIN_OPERATORS SQL_SQL92_RELATIONAL_JOIN_OPERATORS +#define SQL_ISO_REVOKE SQL_SQL92_REVOKE +#define SQL_ISO_ROW_VALUE_CONSTRUCTOR SQL_SQL92_ROW_VALUE_CONSTRUCTOR +#define SQL_ISO_VALUE_EXPRESSIONS SQL_SQL92_VALUE_EXPRESSIONS +#endif /* ODBCVER >= 0x0400 */ + +#if (ODBCVER >= 0x0380) +// Info Types +#define SQL_ASYNC_DBC_FUNCTIONS 10023 +#endif // ODBCVER >= 0x0380 + +#define SQL_DRIVER_AWARE_POOLING_SUPPORTED 10024 + +#if (ODBCVER >= 0x0380) +#define SQL_ASYNC_NOTIFICATION 10025 + +// Possible values for SQL_ASYNC_NOTIFICATION +#define SQL_ASYNC_NOTIFICATION_NOT_CAPABLE 0x00000000L +#define SQL_ASYNC_NOTIFICATION_CAPABLE 0x00000001L +#endif // ODBCVER >= 0x0380 + +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_DTC_TRANSITION_COST 1750 + +/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0300) +/* the following 5 bitmasks are defined in sql.h +*#define SQL_AT_ADD_COLUMN 0x00000001L +*#define SQL_AT_DROP_COLUMN 0x00000002L +*#define SQL_AT_ADD_CONSTRAINT 0x00000008L +*/ +#define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L +#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_CONVERT_* return value bitmasks */ + +#define SQL_CVT_CHAR 0x00000001L +#define SQL_CVT_NUMERIC 0x00000002L +#define SQL_CVT_DECIMAL 0x00000004L +#define SQL_CVT_INTEGER 0x00000008L +#define SQL_CVT_SMALLINT 0x00000010L +#define SQL_CVT_FLOAT 0x00000020L +#define SQL_CVT_REAL 0x00000040L +#define SQL_CVT_DOUBLE 0x00000080L +#define SQL_CVT_VARCHAR 0x00000100L +#define SQL_CVT_LONGVARCHAR 0x00000200L +#define SQL_CVT_BINARY 0x00000400L +#define SQL_CVT_VARBINARY 0x00000800L +#define SQL_CVT_BIT 0x00001000L +#define SQL_CVT_TINYINT 0x00002000L +#define SQL_CVT_BIGINT 0x00004000L +#define SQL_CVT_DATE 0x00008000L +#define SQL_CVT_TIME 0x00010000L +#define SQL_CVT_TIMESTAMP 0x00020000L +#define SQL_CVT_LONGVARBINARY 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L +#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L +#define SQL_CVT_WCHAR 0x00200000L +#define SQL_CVT_WLONGVARCHAR 0x00400000L +#define SQL_CVT_WVARCHAR 0x00800000L +#define SQL_CVT_GUID 0x01000000L + +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_CONVERT_FUNCTIONS functions */ +#define SQL_FN_CVT_CONVERT 0x00000001L +#if (ODBCVER >= 0x0300) +#define SQL_FN_CVT_CAST 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_STRING_FUNCTIONS functions */ + +#define SQL_FN_STR_CONCAT 0x00000001L +#define SQL_FN_STR_INSERT 0x00000002L +#define SQL_FN_STR_LEFT 0x00000004L +#define SQL_FN_STR_LTRIM 0x00000008L +#define SQL_FN_STR_LENGTH 0x00000010L +#define SQL_FN_STR_LOCATE 0x00000020L +#define SQL_FN_STR_LCASE 0x00000040L +#define SQL_FN_STR_REPEAT 0x00000080L +#define SQL_FN_STR_REPLACE 0x00000100L +#define SQL_FN_STR_RIGHT 0x00000200L +#define SQL_FN_STR_RTRIM 0x00000400L +#define SQL_FN_STR_SUBSTRING 0x00000800L +#define SQL_FN_STR_UCASE 0x00001000L +#define SQL_FN_STR_ASCII 0x00002000L +#define SQL_FN_STR_CHAR 0x00004000L +#define SQL_FN_STR_DIFFERENCE 0x00008000L +#define SQL_FN_STR_LOCATE_2 0x00010000L +#define SQL_FN_STR_SOUNDEX 0x00020000L +#define SQL_FN_STR_SPACE 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_STR_BIT_LENGTH 0x00080000L +#define SQL_FN_STR_CHAR_LENGTH 0x00100000L +#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L +#define SQL_FN_STR_OCTET_LENGTH 0x00400000L +#define SQL_FN_STR_POSITION 0x00800000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_STRING_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SSF_CONVERT 0x00000001L +#define SQL_SSF_LOWER 0x00000002L +#define SQL_SSF_UPPER 0x00000004L +#define SQL_SSF_SUBSTRING 0x00000008L +#define SQL_SSF_TRANSLATE 0x00000010L +#define SQL_SSF_TRIM_BOTH 0x00000020L +#define SQL_SSF_TRIM_LEADING 0x00000040L +#define SQL_SSF_TRIM_TRAILING 0x00000080L +#endif /* ODBCVER >= 0x0300 */ +#if (ODBCVER >= 0x0400) +#define SQL_SSF_OVERLAY 0x00000100L +#define SQL_SSF_LENGTH 0x00000200L +#define SQL_SSF_POSITION 0x00000400L +#define SQL_SSF_CONCAT 0x00000800L +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_BINARY_FUNCTIONS functions */ +#if (ODBCVER >= 0x0400) +#define SQL_FN_BIN_BIT_LENGTH SQL_FN_STR_BIT_LENGTH +#define SQL_FN_BIN_CONCAT SQL_FN_STR_CONCAT +#define SQL_FN_BIN_INSERT SQL_FN_STR_INSERT +#define SQL_FN_BIN_LTRIM SQL_FN_STR_LTRIM +#define SQL_FN_BIN_OCTET_LENGTH SQL_FN_STR_OCTET_LENGTH +#define SQL_FN_BIN_POSITION SQL_FN_STR_POSITION +#define SQL_FN_BIN_RTRIM SQL_FN_STR_RTRIM +#define SQL_FN_BIN_SUBSTRING SQL_FN_STR_SUBSTRING +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_SQLBINARY_FUNCTIONS */ +#if (ODBCVER >= 0x0400) +#define SQL_SBF_CONVERT SQL_SSF_CONVERT +#define SQL_SBF_SUBSTRING SQL_SSF_SUBSTRING +#define SQL_SBF_TRIM_BOTH SQL_SSF_TRIM_BOTH +#define SQL_SBF_TRIM_LEADING SQL_SSF_TRIM_LEADING +#define SQL_SBF_TRIM_TRAILING SQL_SSF_TRIM_TRAILING +#define SQL_SBF_OVERLAY SQL_SSF_OVERLAY +#define SQL_SBF_LENGTH SQL_SSF_LENGTH +#define SQL_SBF_POSITION SQL_SSF_POSITION +#define SQL_SBF_CONCAT SQL_SSF_CONCAT +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_NUMERIC_FUNCTIONS functions */ + +#define SQL_FN_NUM_ABS 0x00000001L +#define SQL_FN_NUM_ACOS 0x00000002L +#define SQL_FN_NUM_ASIN 0x00000004L +#define SQL_FN_NUM_ATAN 0x00000008L +#define SQL_FN_NUM_ATAN2 0x00000010L +#define SQL_FN_NUM_CEILING 0x00000020L +#define SQL_FN_NUM_COS 0x00000040L +#define SQL_FN_NUM_COT 0x00000080L +#define SQL_FN_NUM_EXP 0x00000100L +#define SQL_FN_NUM_FLOOR 0x00000200L +#define SQL_FN_NUM_LOG 0x00000400L +#define SQL_FN_NUM_MOD 0x00000800L +#define SQL_FN_NUM_SIGN 0x00001000L +#define SQL_FN_NUM_SIN 0x00002000L +#define SQL_FN_NUM_SQRT 0x00004000L +#define SQL_FN_NUM_TAN 0x00008000L +#define SQL_FN_NUM_PI 0x00010000L +#define SQL_FN_NUM_RAND 0x00020000L +#define SQL_FN_NUM_DEGREES 0x00040000L +#define SQL_FN_NUM_LOG10 0x00080000L +#define SQL_FN_NUM_POWER 0x00100000L +#define SQL_FN_NUM_RADIANS 0x00200000L +#define SQL_FN_NUM_ROUND 0x00400000L +#define SQL_FN_NUM_TRUNCATE 0x00800000L + +/* SQL_SQL92_NUMERIC_VALUE_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SNVF_BIT_LENGTH 0x00000001L +#define SQL_SNVF_CHAR_LENGTH 0x00000002L +#define SQL_SNVF_CHARACTER_LENGTH 0x00000004L +#define SQL_SNVF_EXTRACT 0x00000008L +#define SQL_SNVF_OCTET_LENGTH 0x00000010L +#define SQL_SNVF_POSITION 0x00000020L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_TIMEDATE_FUNCTIONS functions */ + +#define SQL_FN_TD_NOW 0x00000001L +#define SQL_FN_TD_CURDATE 0x00000002L +#define SQL_FN_TD_DAYOFMONTH 0x00000004L +#define SQL_FN_TD_DAYOFWEEK 0x00000008L +#define SQL_FN_TD_DAYOFYEAR 0x00000010L +#define SQL_FN_TD_MONTH 0x00000020L +#define SQL_FN_TD_QUARTER 0x00000040L +#define SQL_FN_TD_WEEK 0x00000080L +#define SQL_FN_TD_YEAR 0x00000100L +#define SQL_FN_TD_CURTIME 0x00000200L +#define SQL_FN_TD_HOUR 0x00000400L +#define SQL_FN_TD_MINUTE 0x00000800L +#define SQL_FN_TD_SECOND 0x00001000L +#define SQL_FN_TD_TIMESTAMPADD 0x00002000L +#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L +#define SQL_FN_TD_DAYNAME 0x00008000L +#define SQL_FN_TD_MONTHNAME 0x00010000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_TD_CURRENT_DATE 0x00020000L +#define SQL_FN_TD_CURRENT_TIME 0x00040000L +#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L +#define SQL_FN_TD_EXTRACT 0x00100000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_DATETIME_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SDF_CURRENT_DATE 0x00000001L +#define SQL_SDF_CURRENT_TIME 0x00000002L +#define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SYSTEM_FUNCTIONS functions */ + +#define SQL_FN_SYS_USERNAME 0x00000001L +#define SQL_FN_SYS_DBNAME 0x00000002L +#define SQL_FN_SYS_IFNULL 0x00000004L + +/* SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions */ + +#define SQL_FN_TSI_FRAC_SECOND 0x00000001L +#define SQL_FN_TSI_SECOND 0x00000002L +#define SQL_FN_TSI_MINUTE 0x00000004L +#define SQL_FN_TSI_HOUR 0x00000008L +#define SQL_FN_TSI_DAY 0x00000010L +#define SQL_FN_TSI_WEEK 0x00000020L +#define SQL_FN_TSI_MONTH 0x00000040L +#define SQL_FN_TSI_QUARTER 0x00000080L +#define SQL_FN_TSI_YEAR 0x00000100L + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES1, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, + * SQL_KEYSET_CURSOR_ATTRIBUTES1, and SQL_STATIC_CURSOR_ATTRIBUTES1 + */ +#if (ODBCVER >= 0x0300) +/* supported SQLFetchScroll FetchOrientation's */ +#define SQL_CA1_NEXT 0x00000001L +#define SQL_CA1_ABSOLUTE 0x00000002L +#define SQL_CA1_RELATIVE 0x00000004L +#define SQL_CA1_BOOKMARK 0x00000008L + +/* supported SQLSetPos LockType's */ +#define SQL_CA1_LOCK_NO_CHANGE 0x00000040L +#define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L +#define SQL_CA1_LOCK_UNLOCK 0x00000100L + +/* supported SQLSetPos Operations */ +#define SQL_CA1_POS_POSITION 0x00000200L +#define SQL_CA1_POS_UPDATE 0x00000400L +#define SQL_CA1_POS_DELETE 0x00000800L +#define SQL_CA1_POS_REFRESH 0x00001000L + +/* positioned updates and deletes */ +#define SQL_CA1_POSITIONED_UPDATE 0x00002000L +#define SQL_CA1_POSITIONED_DELETE 0x00004000L +#define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L + +/* supported SQLBulkOperations operations */ +#define SQL_CA1_BULK_ADD 0x00010000L +#define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L +#define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L +#define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES2, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, + * SQL_KEYSET_CURSOR_ATTRIBUTES2, and SQL_STATIC_CURSOR_ATTRIBUTES2 + */ +#if (ODBCVER >= 0x0300) +/* supported values for SQL_ATTR_SCROLL_CONCURRENCY */ +#define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L +#define SQL_CA2_LOCK_CONCURRENCY 0x00000002L +#define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L +#define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L + +/* sensitivity of the cursor to its own inserts, deletes, and updates */ +#define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L +#define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L +#define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L + +/* semantics of SQL_ATTR_MAX_ROWS */ +#define SQL_CA2_MAX_ROWS_SELECT 0x00000080L +#define SQL_CA2_MAX_ROWS_INSERT 0x00000100L +#define SQL_CA2_MAX_ROWS_DELETE 0x00000200L +#define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L +#define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L +#define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | \ + SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | \ + SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG) + +/* semantics of SQL_DIAG_CURSOR_ROW_COUNT */ +#define SQL_CA2_CRC_EXACT 0x00001000L +#define SQL_CA2_CRC_APPROXIMATE 0x00002000L + +/* the kinds of positioned statements that can be simulated */ +#define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L +#define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L +#define SQL_CA2_SIMULATE_UNIQUE 0x00010000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_ODBC_API_CONFORMANCE values */ + +#define SQL_OAC_NONE 0x0000 +#define SQL_OAC_LEVEL1 0x0001 +#define SQL_OAC_LEVEL2 0x0002 + +/* SQL_ODBC_SAG_CLI_CONFORMANCE values */ + +#define SQL_OSCC_NOT_COMPLIANT 0x0000 +#define SQL_OSCC_COMPLIANT 0x0001 + +/* SQL_ODBC_SQL_CONFORMANCE values */ + +#define SQL_OSC_MINIMUM 0x0000 +#define SQL_OSC_CORE 0x0001 +#define SQL_OSC_EXTENDED 0x0002 + + +/* SQL_CONCAT_NULL_BEHAVIOR values */ + +#define SQL_CB_NULL 0x0000 +#define SQL_CB_NON_NULL 0x0001 + +/* SQL_SCROLL_OPTIONS masks */ + +#define SQL_SO_FORWARD_ONLY 0x00000001L +#define SQL_SO_KEYSET_DRIVEN 0x00000002L +#define SQL_SO_DYNAMIC 0x00000004L +#define SQL_SO_MIXED 0x00000008L +#define SQL_SO_STATIC 0x00000010L + +/* SQL_FETCH_DIRECTION masks */ + +/* SQL_FETCH_RESUME is no longer supported +#define SQL_FD_FETCH_RESUME 0x00000040L +*/ +#define SQL_FD_FETCH_BOOKMARK 0x00000080L + +/* SQL_TXN_ISOLATION_OPTION masks */ +/* SQL_TXN_VERSIONING is no longer supported +#define SQL_TXN_VERSIONING 0x00000010L +*/ + +/* SQL_CORRELATION_NAME values */ + +#define SQL_CN_NONE 0x0000 +#define SQL_CN_DIFFERENT 0x0001 +#define SQL_CN_ANY 0x0002 + +/* SQL_NON_NULLABLE_COLUMNS values */ + +#define SQL_NNC_NULL 0x0000 +#define SQL_NNC_NON_NULL 0x0001 + +/* SQL_NULL_COLLATION values */ + +#define SQL_NC_START 0x0002 +#define SQL_NC_END 0x0004 + +/* SQL_FILE_USAGE values */ + +#define SQL_FILE_NOT_SUPPORTED 0x0000 +#define SQL_FILE_TABLE 0x0001 +#define SQL_FILE_QUALIFIER 0x0002 +#define SQL_FILE_CATALOG SQL_FILE_QUALIFIER // ODBC 3.0 + + +/* SQL_GETDATA_EXTENSIONS values */ + +#define SQL_GD_BLOCK 0x00000004L +#define SQL_GD_BOUND 0x00000008L +#if (ODBCVER >= 0x0380) + #define SQL_GD_OUTPUT_PARAMS 0x00000010L +#endif +#if (ODBCVER >= 0x0400) +#define SQL_GD_CONCURRENT 0x00000020L +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_POSITIONED_STATEMENTS masks */ + +#define SQL_PS_POSITIONED_DELETE 0x00000001L +#define SQL_PS_POSITIONED_UPDATE 0x00000002L +#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L + +/* SQL_GROUP_BY values */ + +#define SQL_GB_NOT_SUPPORTED 0x0000 +#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001 +#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002 +#define SQL_GB_NO_RELATION 0x0003 +#if (ODBCVER >= 0x0300) +#define SQL_GB_COLLATE 0x0004 + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_OWNER_USAGE masks */ + +#define SQL_OU_DML_STATEMENTS 0x00000001L +#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_OU_TABLE_DEFINITION 0x00000004L +#define SQL_OU_INDEX_DEFINITION 0x00000008L +#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L + +/* SQL_SCHEMA_USAGE masks */ +#if (ODBCVER >= 0x0300) +#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS +#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION +#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION +#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION +#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUALIFIER_USAGE masks */ + +#define SQL_QU_DML_STATEMENTS 0x00000001L +#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_QU_TABLE_DEFINITION 0x00000004L +#define SQL_QU_INDEX_DEFINITION 0x00000008L +#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L + +#if (ODBCVER >= 0x0300) +/* SQL_CATALOG_USAGE masks */ +#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS +#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION +#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION +#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION +#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SUBQUERIES masks */ + +#define SQL_SQ_COMPARISON 0x00000001L +#define SQL_SQ_EXISTS 0x00000002L +#define SQL_SQ_IN 0x00000004L +#define SQL_SQ_QUANTIFIED 0x00000008L +#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L + +/* SQL_UNION masks */ + +#define SQL_U_UNION 0x00000001L +#define SQL_U_UNION_ALL 0x00000002L + +/* SQL_BOOKMARK_PERSISTENCE values */ + +#define SQL_BP_CLOSE 0x00000001L +#define SQL_BP_DELETE 0x00000002L +#define SQL_BP_DROP 0x00000004L +#define SQL_BP_TRANSACTION 0x00000008L +#define SQL_BP_UPDATE 0x00000010L +#define SQL_BP_OTHER_HSTMT 0x00000020L +#define SQL_BP_SCROLL 0x00000040L + +/* SQL_STATIC_SENSITIVITY values */ + +#define SQL_SS_ADDITIONS 0x00000001L +#define SQL_SS_DELETIONS 0x00000002L +#define SQL_SS_UPDATES 0x00000004L + +/* SQL_VIEW values */ +#define SQL_CV_CREATE_VIEW 0x00000001L +#define SQL_CV_CHECK_OPTION 0x00000002L +#define SQL_CV_CASCADED 0x00000004L +#define SQL_CV_LOCAL 0x00000008L + +/* SQL_LOCK_TYPES masks */ + +#define SQL_LCK_NO_CHANGE 0x00000001L +#define SQL_LCK_EXCLUSIVE 0x00000002L +#define SQL_LCK_UNLOCK 0x00000004L + +/* SQL_POS_OPERATIONS masks */ + +#define SQL_POS_POSITION 0x00000001L +#define SQL_POS_REFRESH 0x00000002L +#define SQL_POS_UPDATE 0x00000004L +#define SQL_POS_DELETE 0x00000008L +#define SQL_POS_ADD 0x00000010L + +/* SQL_QUALIFIER_LOCATION values */ + +#define SQL_QL_START 0x0001 +#define SQL_QL_END 0x0002 + +/* Here start return values for ODBC 3.0 SQLGetInfo */ + +#if (ODBCVER >= 0x0300) +/* SQL_AGGREGATE_FUNCTIONS bitmasks */ +#define SQL_AF_AVG 0x00000001L +#define SQL_AF_COUNT 0x00000002L +#define SQL_AF_MAX 0x00000004L +#define SQL_AF_MIN 0x00000008L +#define SQL_AF_SUM 0x00000010L +#define SQL_AF_DISTINCT 0x00000020L +#define SQL_AF_ALL 0x00000040L +#if (ODBCVER >= 0x0400) +#define SQL_AF_EVERY 0x00000080L +#define SQL_AF_ANY 0x00000100L +#define SQL_AF_STDEV_OP 0x00000200L +#define SQL_AF_STDEV_SAMP 0x00000400L +#define SQL_AF_VAR_SAMP 0x00000800L +#define SQL_AF_VAR_POP 0x00001000L +#define SQL_AF_ARRAY_AGG 0x00002000L +#define SQL_AF_COLLECT 0x00004000L +#define SQL_AF_FUSION 0x00008000L +#define SQL_AF_INTERSECTION 0x00010000L +#endif /* ODBCVER >= 0x0400 */ + +/* SQL_SQL_CONFORMANCE bit masks */ +#define SQL_SC_SQL92_ENTRY 0x00000001L +#define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L +#define SQL_SC_SQL92_INTERMEDIATE 0x00000004L +#define SQL_SC_SQL92_FULL 0x00000008L + +/* SQL_DATETIME_LITERALS masks */ +#define SQL_DL_SQL92_DATE 0x00000001L +#define SQL_DL_SQL92_TIME 0x00000002L +#define SQL_DL_SQL92_TIMESTAMP 0x00000004L +#define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L +#define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L +#define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L +#define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L +#define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L +#define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L +#define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L +#define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L + +/* SQL_CATALOG_LOCATION values */ +#define SQL_CL_START SQL_QL_START +#define SQL_CL_END SQL_QL_END + +/* values for SQL_BATCH_ROW_COUNT */ +#define SQL_BRC_PROCEDURES 0x0000001 +#define SQL_BRC_EXPLICIT 0x0000002 +#define SQL_BRC_ROLLED_UP 0x0000004 + +/* bitmasks for SQL_BATCH_SUPPORT */ +#define SQL_BS_SELECT_EXPLICIT 0x00000001L +#define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L +#define SQL_BS_SELECT_PROC 0x00000004L +#define SQL_BS_ROW_COUNT_PROC 0x00000008L + +/* Values for SQL_PARAM_ARRAY_ROW_COUNTS getinfo */ +#define SQL_PARC_BATCH 1 +#define SQL_PARC_NO_BATCH 2 + +/* values for SQL_PARAM_ARRAY_SELECTS */ +#define SQL_PAS_BATCH 1 +#define SQL_PAS_NO_BATCH 2 +#define SQL_PAS_NO_SELECT 3 + +/* Bitmasks for SQL_INDEX_KEYWORDS */ +#define SQL_IK_NONE 0x00000000L +#define SQL_IK_ASC 0x00000001L +#define SQL_IK_DESC 0x00000002L +#define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC) + +/* Bitmasks for SQL_INFO_SCHEMA_VIEWS */ + +#define SQL_ISV_ASSERTIONS 0x00000001L +#define SQL_ISV_CHARACTER_SETS 0x00000002L +#define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L +#define SQL_ISV_COLLATIONS 0x00000008L +#define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L +#define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L +#define SQL_ISV_COLUMNS 0x00000040L +#define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L +#define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L +#define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L +#define SQL_ISV_DOMAINS 0x00000400L +#define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L +#define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L +#define SQL_ISV_SCHEMATA 0x00002000L +#define SQL_ISV_SQL_LANGUAGES 0x00004000L +#define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L +#define SQL_ISV_TABLE_PRIVILEGES 0x00010000L +#define SQL_ISV_TABLES 0x00020000L +#define SQL_ISV_TRANSLATIONS 0x00040000L +#define SQL_ISV_USAGE_PRIVILEGES 0x00080000L +#define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L +#define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L +#define SQL_ISV_VIEWS 0x00400000L + +/* Bitmasks for SQL_ASYNC_MODE */ + +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 + +/* Bitmasks for SQL_ALTER_DOMAIN */ +#define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L +#define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L +#define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L +#define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L +#define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L + + +/* SQL_CREATE_SCHEMA bitmasks */ +#define SQL_CS_CREATE_SCHEMA 0x00000001L +#define SQL_CS_AUTHORIZATION 0x00000002L +#define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L + +/* SQL_CREATE_TRANSLATION bitmasks */ +#define SQL_CTR_CREATE_TRANSLATION 0x00000001L + +/* SQL_CREATE_ASSERTION bitmasks */ +#define SQL_CA_CREATE_ASSERTION 0x00000001L +#define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L +#define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L +#define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L +#define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L + +/* SQL_CREATE_CHARACTER_SET bitmasks */ +#define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L +#define SQL_CCS_COLLATE_CLAUSE 0x00000002L +#define SQL_CCS_LIMITED_COLLATION 0x00000004L + +/* SQL_CREATE_COLLATION bitmasks */ +#define SQL_CCOL_CREATE_COLLATION 0x00000001L + +/* SQL_CREATE_DOMAIN bitmasks */ +#define SQL_CDO_CREATE_DOMAIN 0x00000001L +#define SQL_CDO_DEFAULT 0x00000002L +#define SQL_CDO_CONSTRAINT 0x00000004L +#define SQL_CDO_COLLATION 0x00000008L +#define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L +#define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L + +/* SQL_CREATE_TABLE bitmasks */ +#define SQL_CT_CREATE_TABLE 0x00000001L +#define SQL_CT_COMMIT_PRESERVE 0x00000002L +#define SQL_CT_COMMIT_DELETE 0x00000004L +#define SQL_CT_GLOBAL_TEMPORARY 0x00000008L +#define SQL_CT_LOCAL_TEMPORARY 0x00000010L +#define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#define SQL_CT_COLUMN_CONSTRAINT 0x00000200L +#define SQL_CT_COLUMN_DEFAULT 0x00000400L +#define SQL_CT_COLUMN_COLLATION 0x00000800L +#define SQL_CT_TABLE_CONSTRAINT 0x00001000L +#define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L + +/* SQL_DDL_INDEX bitmasks */ +#define SQL_DI_CREATE_INDEX 0x00000001L +#define SQL_DI_DROP_INDEX 0x00000002L + +/* SQL_DROP_COLLATION bitmasks */ +#define SQL_DC_DROP_COLLATION 0x00000001L + +/* SQL_DROP_DOMAIN bitmasks */ +#define SQL_DD_DROP_DOMAIN 0x00000001L +#define SQL_DD_RESTRICT 0x00000002L +#define SQL_DD_CASCADE 0x00000004L + +/* SQL_DROP_SCHEMA bitmasks */ +#define SQL_DS_DROP_SCHEMA 0x00000001L +#define SQL_DS_RESTRICT 0x00000002L +#define SQL_DS_CASCADE 0x00000004L + +/* SQL_DROP_CHARACTER_SET bitmasks */ +#define SQL_DCS_DROP_CHARACTER_SET 0x00000001L + +/* SQL_DROP_ASSERTION bitmasks */ +#define SQL_DA_DROP_ASSERTION 0x00000001L + +/* SQL_DROP_TABLE bitmasks */ +#define SQL_DT_DROP_TABLE 0x00000001L +#define SQL_DT_RESTRICT 0x00000002L +#define SQL_DT_CASCADE 0x00000004L + +/* SQL_DROP_TRANSLATION bitmasks */ +#define SQL_DTR_DROP_TRANSLATION 0x00000001L + +/* SQL_DROP_VIEW bitmasks */ +#define SQL_DV_DROP_VIEW 0x00000001L +#define SQL_DV_RESTRICT 0x00000002L +#define SQL_DV_CASCADE 0x00000004L + +/* SQL_INSERT_STATEMENT bitmasks */ +#define SQL_IS_INSERT_LITERALS 0x00000001L +#define SQL_IS_INSERT_SEARCHED 0x00000002L +#define SQL_IS_SELECT_INTO 0x00000004L + +/* SQL_ODBC_INTERFACE_CONFORMANCE values */ +#define SQL_OIC_CORE 1UL +#define SQL_OIC_LEVEL1 2UL +#define SQL_OIC_LEVEL2 3UL + +/* SQL_SQL92_FOREIGN_KEY_DELETE_RULE bitmasks */ +#define SQL_SFKD_CASCADE 0x00000001L +#define SQL_SFKD_NO_ACTION 0x00000002L +#define SQL_SFKD_SET_DEFAULT 0x00000004L +#define SQL_SFKD_SET_NULL 0x00000008L + +/* SQL_SQL92_FOREIGN_KEY_UPDATE_RULE bitmasks */ +#define SQL_SFKU_CASCADE 0x00000001L +#define SQL_SFKU_NO_ACTION 0x00000002L +#define SQL_SFKU_SET_DEFAULT 0x00000004L +#define SQL_SFKU_SET_NULL 0x00000008L + +/* SQL_SQL92_GRANT bitmasks */ +#define SQL_SG_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SG_USAGE_ON_COLLATION 0x00000004L +#define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SG_WITH_GRANT_OPTION 0x00000010L +#define SQL_SG_DELETE_TABLE 0x00000020L +#define SQL_SG_INSERT_TABLE 0x00000040L +#define SQL_SG_INSERT_COLUMN 0x00000080L +#define SQL_SG_REFERENCES_TABLE 0x00000100L +#define SQL_SG_REFERENCES_COLUMN 0x00000200L +#define SQL_SG_SELECT_TABLE 0x00000400L +#define SQL_SG_UPDATE_TABLE 0x00000800L +#define SQL_SG_UPDATE_COLUMN 0x00001000L + +/* SQL_SQL92_PREDICATES bitmasks */ +#define SQL_SP_EXISTS 0x00000001L +#define SQL_SP_ISNOTNULL 0x00000002L +#define SQL_SP_ISNULL 0x00000004L +#define SQL_SP_MATCH_FULL 0x00000008L +#define SQL_SP_MATCH_PARTIAL 0x00000010L +#define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L +#define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L +#define SQL_SP_OVERLAPS 0x00000080L +#define SQL_SP_UNIQUE 0x00000100L +#define SQL_SP_LIKE 0x00000200L +#define SQL_SP_IN 0x00000400L +#define SQL_SP_BETWEEN 0x00000800L +#define SQL_SP_COMPARISON 0x00001000L +#define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L + +/* SQL_SQL92_RELATIONAL_JOIN_OPERATORS bitmasks */ +#define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L +#define SQL_SRJO_CROSS_JOIN 0x00000002L +#define SQL_SRJO_EXCEPT_JOIN 0x00000004L +#define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L +#define SQL_SRJO_INNER_JOIN 0x00000010L +#define SQL_SRJO_INTERSECT_JOIN 0x00000020L +#define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L +#define SQL_SRJO_NATURAL_JOIN 0x00000080L +#define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L +#define SQL_SRJO_UNION_JOIN 0x00000200L + +/* SQL_SQL92_REVOKE bitmasks */ +#define SQL_SR_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SR_USAGE_ON_COLLATION 0x00000004L +#define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SR_GRANT_OPTION_FOR 0x00000010L +#define SQL_SR_CASCADE 0x00000020L +#define SQL_SR_RESTRICT 0x00000040L +#define SQL_SR_DELETE_TABLE 0x00000080L +#define SQL_SR_INSERT_TABLE 0x00000100L +#define SQL_SR_INSERT_COLUMN 0x00000200L +#define SQL_SR_REFERENCES_TABLE 0x00000400L +#define SQL_SR_REFERENCES_COLUMN 0x00000800L +#define SQL_SR_SELECT_TABLE 0x00001000L +#define SQL_SR_UPDATE_TABLE 0x00002000L +#define SQL_SR_UPDATE_COLUMN 0x00004000L + +/* SQL_SQL92_ROW_VALUE_CONSTRUCTOR bitmasks */ +#define SQL_SRVC_VALUE_EXPRESSION 0x00000001L +#define SQL_SRVC_NULL 0x00000002L +#define SQL_SRVC_DEFAULT 0x00000004L +#define SQL_SRVC_ROW_SUBQUERY 0x00000008L + +/* SQL_SQL92_VALUE_EXPRESSIONS bitmasks */ +#define SQL_SVE_CASE 0x00000001L +#define SQL_SVE_CAST 0x00000002L +#define SQL_SVE_COALESCE 0x00000004L +#define SQL_SVE_NULLIF 0x00000008L + +/* SQL_STANDARD_CLI_CONFORMANCE bitmasks */ +#define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L +#define SQL_SCC_ISO92_CLI 0x00000002L + +/* SQL_UNION_STATEMENT bitmasks */ +#define SQL_US_UNION SQL_U_UNION +#define SQL_US_UNION_ALL SQL_U_UNION_ALL + +/* values for SQL_DRIVER_AWARE_POOLING_SUPPORTED */ +#define SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE 0x00000000L +#define SQL_DRIVER_AWARE_POOLING_CAPABLE 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_DTC_TRANSITION_COST bitmasks */ +#define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L +#define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L + +#if (ODBCVER >= 0x0380) +// possible values for SQL_ASYNC_DBC_FUNCTIONS +#define SQL_ASYNC_DBC_NOT_CAPABLE 0x00000000L +#define SQL_ASYNC_DBC_CAPABLE 0x00000001L +#endif // ODBCVER >= 0x0380 + +/* Bitmask values for SQL_LIMIT_ESCAPE_CLAUSE */ +#if (ODBCVER >= 0x0400) +#define SQL_LC_NONE 0x00000000L +#define SQL_LC_TAKE 0x00000001L +#define SQL_LC_SKIP 0x00000003L +#endif /* ODBCVER >= 0x0400 */ + +/* Bitmask values for SQL_RETURN_ESCAPE_CLAUSE */ +#if (ODBCVER >= 0x0400) +#define SQL_RC_NONE 0x00000000L +#define SQL_RC_INSERT_SINGLE_ROWID 0x00000001L +#define SQL_RC_INSERT_SINGLE_ANY ( 0x00000002L | SQL_RC_INSERT_SINGLE_ROWID ) +#define SQL_RC_INSERT_MULTIPLE_ROWID ( 0x00000004L | SQL_RC_INSERT_SINGLE_ROWID) +#define SQL_RC_INSERT_MULTIPLE_ANY ( 0x00000008L | SQL_RC_INSERT_MULTIPLE_ROWID | SQL_RC_INSERT_SINGLE_ANY ) +#define SQL_RC_INSERT_SELECT_ROWID 0x00000010L +#define SQL_RC_INSERT_SELECT_ANY ( 0x00000020L | SQL_RC_INSERT_SELECT_ROWID ) +#define SQL_RC_UPDATE_ROWID 0x00000040L +#define SQL_RC_UPDATE_ANY ( 0x00000080L | SQL_RC_UPDATE_ROWID) +#define SQL_RC_DELETE_ROWID 0x00000100L +#define SQL_RC_DELETE_ANY ( 0x00000200L | SQL_RC_DELETE_ROWID ) +#define SQL_RC_SELECT_INTO_ROWID 0x00000400L +#define SQL_RC_SELECT_INTO_ANY ( 0x00000800L | SQL_RC_SELECT_INTO_ROWID ) +#endif /* ODBCVER >= 0x0400 */ + +/* Bitmask values for SQL_FORMAT_ESCAPE_CLAUSE */ +#if (ODBCVER >= 0x0400) +#define SQL_FC_NONE 0x00000000L +#define SQL_FC_JSON 0x00000001L +#define SQL_FC_JSON_BINARY 0x00000002L +#endif /* ODBCVER >= 0x0400 */ + +/* additional SQLDataSources fetch directions */ +#if (ODBCVER >= 0x0300) +#define SQL_FETCH_FIRST_USER 31 +#define SQL_FETCH_FIRST_SYSTEM 32 +#endif /* ODBCVER >= 0x0300 */ + + +/* Defines for SQLSetPos */ +#define SQL_ENTIRE_ROWSET 0 + +/* Operations in SQLSetPos */ +#define SQL_POSITION 0 /* 1.0 FALSE */ +#define SQL_REFRESH 1 /* 1.0 TRUE */ +#define SQL_UPDATE 2 +#define SQL_DELETE 3 + +/* Operations in SQLBulkOperations */ +#define SQL_ADD 4 +#define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD +#if (ODBCVER >= 0x0300) +#define SQL_UPDATE_BY_BOOKMARK 5 +#define SQL_DELETE_BY_BOOKMARK 6 +#define SQL_FETCH_BY_BOOKMARK 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Lock options in SQLSetPos */ +#define SQL_LOCK_NO_CHANGE 0 /* 1.0 FALSE */ +#define SQL_LOCK_EXCLUSIVE 1 /* 1.0 TRUE */ +#define SQL_LOCK_UNLOCK 2 + +#define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK + +/* Macros for SQLSetPos */ +#define SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) +#define SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock) +#define SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) +#define SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) +#define SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) +#define SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) + +/* Column types and scopes in SQLSpecialColumns. */ +#define SQL_BEST_ROWID 1 +#define SQL_ROWVER 2 + +/* Defines for SQLSpecialColumns (returned in the result set) + SQL_PC_UNKNOWN and SQL_PC_PSEUDO are defined in sql.h */ +#define SQL_PC_NOT_PSEUDO 1 + +/* Defines for SQLStatistics */ +#define SQL_QUICK 0 +#define SQL_ENSURE 1 + +/* Defines for SQLStatistics (returned in the result set) + SQL_INDEX_CLUSTERED, SQL_INDEX_HASHED, and SQL_INDEX_OTHER are + defined in sql.h */ +#define SQL_TABLE_STAT 0 + + +/* Defines for SQLTables */ +#if (ODBCVER >= 0x0300) +#define SQL_ALL_CATALOGS "%" +#define SQL_ALL_SCHEMAS "%" +#define SQL_ALL_TABLE_TYPES "%" +#endif /* ODBCVER >= 0x0300 */ + +/* Options for SQLDriverConnect */ +#define SQL_DRIVER_NOPROMPT 0 +#define SQL_DRIVER_COMPLETE 1 +#define SQL_DRIVER_PROMPT 2 +#define SQL_DRIVER_COMPLETE_REQUIRED 3 + +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLDriverConnect( + SQLHDBC hdbc, + SQLHWND hwnd, + _In_reads_(cchConnStrIn) + SQLCHAR *szConnStrIn, + SQLSMALLINT cchConnStrIn, + _Out_writes_opt_(cchConnStrOutMax) + SQLCHAR *szConnStrOut, + SQLSMALLINT cchConnStrOutMax, + _Out_opt_ + SQLSMALLINT *pcchConnStrOut, + SQLUSMALLINT fDriverCompletion); + +#endif /* RC_INVOKED */ + +/* Level 2 Functions */ + +/* SQLExtendedFetch "fFetchType" values */ +#define SQL_FETCH_BOOKMARK 8 + +/* SQLExtendedFetch "rgfRowStatus" element values */ +#define SQL_ROW_SUCCESS 0 +#define SQL_ROW_DELETED 1 +#define SQL_ROW_UPDATED 2 +#define SQL_ROW_NOROW 3 +#define SQL_ROW_ADDED 4 +#define SQL_ROW_ERROR 5 +#if (ODBCVER >= 0x0300) +#define SQL_ROW_SUCCESS_WITH_INFO 6 +#define SQL_ROW_PROCEED 0 +#define SQL_ROW_IGNORE 1 +#endif + +/* value for SQL_DESC_ARRAY_STATUS_PTR */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_SUCCESS 0 +#define SQL_PARAM_SUCCESS_WITH_INFO 6 +#define SQL_PARAM_ERROR 5 +#define SQL_PARAM_UNUSED 7 +#define SQL_PARAM_DIAG_UNAVAILABLE 1 + +#define SQL_PARAM_PROCEED 0 +#define SQL_PARAM_IGNORE 1 +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLForeignKeys (UPDATE_RULE and DELETE_RULE) */ +#define SQL_CASCADE 0 +#define SQL_RESTRICT 1 +#define SQL_SET_NULL 2 +#if (ODBCVER >= 0x0250) +#define SQL_NO_ACTION 3 +#define SQL_SET_DEFAULT 4 +#endif /* ODBCVER >= 0x0250 */ + +#if (ODBCVER >= 0x0300) +/* Note that the following are in a different column of SQLForeignKeys than */ +/* the previous #defines. These are for DEFERRABILITY. */ + +#define SQL_INITIALLY_DEFERRED 5 +#define SQL_INITIALLY_IMMEDIATE 6 +#define SQL_NOT_DEFERRABLE 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLBindParameter and + SQLProcedureColumns (returned in the result set) */ +#define SQL_PARAM_TYPE_UNKNOWN 0 +#define SQL_PARAM_INPUT 1 +#define SQL_PARAM_INPUT_OUTPUT 2 +#define SQL_RESULT_COL 3 +#define SQL_PARAM_OUTPUT 4 +#define SQL_RETURN_VALUE 5 +#if (ODBCVER >= 0x0380) + #define SQL_PARAM_INPUT_OUTPUT_STREAM 8 + #define SQL_PARAM_OUTPUT_STREAM 16 +#endif + +/* Defines for SQLProcedures (returned in the result set) */ +#define SQL_PT_UNKNOWN 0 +#define SQL_PT_PROCEDURE 1 +#define SQL_PT_FUNCTION 2 + +#ifndef RC_INVOKED + +/* This define is too large for RC */ +#define SQL_ODBC_KEYWORDS \ +"ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ +"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ +"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ +"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ +"COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ +"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ +"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ +"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ +"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ +"DISTINCT,DOMAIN,DOUBLE,DROP,"\ +"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ +"EXISTS,EXTERNAL,EXTRACT,"\ +"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ +"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ +"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ +"INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ +"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ +"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\ +"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ +"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ +"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ +"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ +"READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\ +"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\ +"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ +"SUBSTRING,SUM,SYSTEM_USER,"\ +"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ +"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ +"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ +"VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\ +"YEAR,ZONE" + +SQLRETURN SQL_API SQLBrowseConnect( + SQLHDBC hdbc, + _In_reads_(cchConnStrIn) + SQLCHAR *szConnStrIn, + SQLSMALLINT cchConnStrIn, + _Out_writes_opt_(cchConnStrOutMax) + SQLCHAR *szConnStrOut, + SQLSMALLINT cchConnStrOutMax, + _Out_opt_ + SQLSMALLINT *pcchConnStrOut); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLBulkOperations( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLColAttributes( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN * pfDesc); + +SQLRETURN SQL_API SQLColumnPrivileges( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) + SQLCHAR *szTableName, + SQLSMALLINT cchTableName, + _In_reads_opt_(cchColumnName) + SQLCHAR *szColumnName, + SQLSMALLINT cchColumnName); + +SQLRETURN SQL_API SQLDescribeParam( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + _Out_opt_ + SQLSMALLINT *pfSqlType, + _Out_opt_ + SQLULEN *pcbParamDef, + _Out_opt_ + SQLSMALLINT *pibScale, + _Out_opt_ + SQLSMALLINT *pfNullable); + +SQLRETURN SQL_API SQLExtendedFetch( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + _Out_opt_ + SQLULEN *pcrow, + _Out_opt_ + SQLUSMALLINT *rgfRowStatus); + +SQLRETURN SQL_API SQLForeignKeys( + SQLHSTMT hstmt, + _In_reads_opt_(cchPkCatalogName) + SQLCHAR *szPkCatalogName, + SQLSMALLINT cchPkCatalogName, + _In_reads_opt_(cchPkSchemaName) + SQLCHAR *szPkSchemaName, + SQLSMALLINT cchPkSchemaName, + _In_reads_opt_(cchPkTableName) + SQLCHAR *szPkTableName, + SQLSMALLINT cchPkTableName, + _In_reads_opt_(cchFkCatalogName) + SQLCHAR *szFkCatalogName, + SQLSMALLINT cchFkCatalogName, + _In_reads_opt_(cchFkSchemaName) + SQLCHAR *szFkSchemaName, + SQLSMALLINT cchFkSchemaName, + _In_reads_opt_(cchFkTableName) + SQLCHAR *szFkTableName, + SQLSMALLINT cchFkTableName); + +SQLRETURN SQL_API SQLMoreResults( + SQLHSTMT hstmt); + +SQLRETURN SQL_API SQLNativeSql +( + SQLHDBC hdbc, + _In_reads_(cchSqlStrIn) SQLCHAR* szSqlStrIn, + SQLINTEGER cchSqlStrIn, + _Out_writes_opt_(cchSqlStrMax) SQLCHAR* szSqlStr, + SQLINTEGER cchSqlStrMax, + SQLINTEGER *pcbSqlStr +); + +SQLRETURN SQL_API SQLNumParams( + SQLHSTMT hstmt, + _Out_opt_ + SQLSMALLINT *pcpar); + +SQLRETURN SQL_API SQLParamOptions( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); + +SQLRETURN SQL_API SQLPrimaryKeys( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) + SQLCHAR *szTableName, + SQLSMALLINT cchTableName); + +SQLRETURN SQL_API SQLProcedureColumns( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchProcName) + SQLCHAR *szProcName, + SQLSMALLINT cchProcName, + _In_reads_opt_(cchColumnName) + SQLCHAR *szColumnName, + SQLSMALLINT cchColumnName); + +SQLRETURN SQL_API SQLProcedures( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchProcName) + SQLCHAR *szProcName, + SQLSMALLINT cchProcName); + + + +SQLRETURN SQL_API SQLSetPos( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); + +SQLRETURN SQL_API SQLTablePrivileges( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) + SQLCHAR *szTableName, + SQLSMALLINT cchTableName); + +SQLRETURN SQL_API SQLDrivers( + SQLHENV henv, + SQLUSMALLINT fDirection, + _Out_writes_opt_(cchDriverDescMax) + SQLCHAR *szDriverDesc, + SQLSMALLINT cchDriverDescMax, + _Out_opt_ + SQLSMALLINT *pcchDriverDesc, + _Out_writes_opt_(cchDrvrAttrMax) + SQLCHAR *szDriverAttributes, + SQLSMALLINT cchDrvrAttrMax, + _Out_opt_ + SQLSMALLINT *pcchDrvrAttr); + +SQLRETURN SQL_API SQLBindParameter( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); + +#if (ODBCVER >= 0x0400) +SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, _Out_ SQLHANDLE *OutputHandle); + +SQLRETURN SQL_API SQLGetNestedHandle( + SQLHSTMT ParentStatementHandle, + SQLUSMALLINT Col_or_Param_Num, + _Out_ SQLHSTMT* OutputChildStatementHandle); + +SQLRETURN SQL_API SQLStructuredTypes( + SQLHSTMT StatementHandle, + _In_reads_opt_(NameLength1) SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + _In_reads_opt_(NameLength2) SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + _In_reads_opt_(NameLength3) SQLCHAR *TypeName, SQLSMALLINT NameLength3); + +SQLRETURN SQL_API SQLStructuredTypeColumns( + SQLHSTMT StatementHandle, + _In_reads_opt_(NameLength1) SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + _In_reads_opt_(NameLength2) SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + _In_reads_opt_(NameLength3) SQLCHAR *TypeName, SQLSMALLINT NameLength3, + _In_reads_opt_(NameLength4) SQLCHAR *ColumnName, SQLSMALLINT NameLength4); + +SQLRETURN SQL_API SQLNextColumn(SQLHSTMT StatementHandle, + _Out_ SQLUSMALLINT *ColumnCount); +#endif /* ODBCVER >= 0x0400 */ + +#endif /* RC_INVOKED */ + +/*---------------------------------------------------------*/ +/* SQLAllocHandleStd is implemented to make SQLAllocHandle */ +/* compatible with X/Open standard. an application should */ +/* not call SQLAllocHandleStd directly */ +/*---------------------------------------------------------*/ +#ifdef ODBC_STD +#define SQLAllocHandle SQLAllocHandleStd +#define SQLAllocEnv(phenv) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv) + +/* Internal type subcodes */ +#define SQL_YEAR SQL_CODE_YEAR +#define SQL_MONTH SQL_CODE_MONTH +#define SQL_DAY SQL_CODE_DAY +#define SQL_HOUR SQL_CODE_HOUR +#define SQL_MINUTE SQL_CODE_MINUTE +#define SQL_SECOND SQL_CODE_SECOND +#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH +#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR +#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE +#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND +#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE +#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND +#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND +#endif /* ODBC_STD */ + +#if (ODBCVER >= 0x0300) +#ifndef RC_INVOKED +SQLRETURN SQL_API SQLAllocHandleStd( + SQLSMALLINT fHandleType, + SQLHANDLE hInput, + _Out_ + SQLHANDLE *phOutput); +#endif /* RC_INVOKED */ +#endif + +/* Deprecated defines from prior versions of ODBC */ +#define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */ +#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR +#define SQL_FETCH_PREV SQL_FETCH_PRIOR +#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER +#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER +#define SQL_CC_DELETE SQL_CB_DELETE +#define SQL_CR_DELETE SQL_CB_DELETE +#define SQL_CC_CLOSE SQL_CB_CLOSE +#define SQL_CR_CLOSE SQL_CB_CLOSE +#define SQL_CC_PRESERVE SQL_CB_PRESERVE +#define SQL_CR_PRESERVE SQL_CB_PRESERVE +/* SQL_FETCH_RESUME is not supported by 2.0+ drivers +#define SQL_FETCH_RESUME 7 +*/ +#define SQL_SCROLL_FORWARD_ONLY 0L /*-SQL_CURSOR_FORWARD_ONLY */ +#define SQL_SCROLL_KEYSET_DRIVEN (-1L) /*-SQL_CURSOR_KEYSET_DRIVEN */ +#define SQL_SCROLL_DYNAMIC (-2L) /*-SQL_CURSOR_DYNAMIC */ +#define SQL_SCROLL_STATIC (-3L) /*-SQL_CURSOR_STATIC */ + +/* Deprecated functions from prior versions of ODBC */ +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLSetScrollOptions( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); + +/* Tracing section */ + +#define TRACE_VERSION 1000 /* Version of trace API */ + +// open a trace log file +RETCODE SQL_API TraceOpenLogFile +( + _In_opt_ LPWSTR szFileName, + _Out_writes_bytes_opt_(cbOutputMsg) LPWSTR lpwszOutputMsg, + _In_ DWORD cbOutputMsg +); + +RETCODE SQL_API TraceCloseLogFile(); // Request to close a trace log +VOID SQL_API TraceReturn(RETCODE,RETCODE); // Processes trace after FN is called +DWORD SQL_API TraceVersion(); // Returns trace API version + +/* Functions for Visual Studio Analyzer*/ +/* to turn on/off tracing or VS events, call TraceVSControl by setting or clearing the following bits */ +#pragma deprecated(TRACE_VS_EVENT_ON) +#define TRACE_ON 0x00000001L +#define TRACE_VS_EVENT_ON 0x00000002L + +RETCODE SQL_API TraceVSControl(DWORD); + +/* Functions for setting the connection pooling failure detection code */ +/* The "TryWait" value is the time (in seconds) that the DM will wait */ +/* between detecting that a connection is dead (using */ +/* SQL_ATTR_CONNECTION_DEAD) and retrying the connection. During that */ +/* interval, connection requests will get "The server appears to be */ +/* dead" error returns. */ + + +BOOL SQL_API ODBCSetTryWaitValue(DWORD dwValue); /* In seconds */ +DWORD SQL_API ODBCGetTryWaitValue(); /* In Milliseconds(!) */ + + +//------------- Visual Studio Analyzer Support is removed from ODBC (Windows 8 and onwards) --------- +// From Windows 8 and onwards, Visual Studio Analyzer Support for ODBC is removed. Third-party trace +// library does not need to define the function FireVSDebugEvent any more, which would not be called +// from ODBC DM in Windows 8. +// If your trace library is going to work on downlevel platforms, you may still want to define the +// function FireVSDebugEvent. But the trace library can still be loaded on downlevel platforms even +// if this function is not defined. +// +#pragma deprecated(ODBC_VS_FLAG_UNICODE_ARG, ODBC_VS_FLAG_UNICODE_COR, ODBC_VS_FLAG_RETCODE, ODBC_VS_FLAG_STOP, tagODBC_VS_ARGS, ODBC_VS_ARGS, PODBC_VS_ARGS) + +// the flags in ODBC_VS_ARGS +#define ODBC_VS_FLAG_UNICODE_ARG 0x00000001L /* the argument is unicode */ +#define ODBC_VS_FLAG_UNICODE_COR 0x00000002L /* the correlation is unicode */ +#define ODBC_VS_FLAG_RETCODE 0x00000004L /* RetCode field is set */ +#define ODBC_VS_FLAG_STOP 0x00000008L /* Stop firing visual studio analyzer events */ + +#pragma warning( push ) +#pragma warning(disable:4995) +typedef struct tagODBC_VS_ARGS { + const GUID *pguidEvent; /* the GUID for event */ + DWORD dwFlags; /* flags for the call */ + union { + WCHAR *wszArg; + CHAR *szArg; + }; + union { + WCHAR *wszCorrelation; + CHAR *szCorrelation; + }; + RETCODE RetCode; +} ODBC_VS_ARGS, *PODBC_VS_ARGS; + +VOID SQL_API FireVSDebugEvent(PODBC_VS_ARGS); +#pragma warning( pop ) + +#endif /* RC_INVOKED */ + + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#if defined(WIN32) || defined(_WIN64) +#include "sqlucode.h" +#endif + + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion + +#endif /* __SQLEXT */ diff --git a/Windows/inc/sqltypes.h b/Windows/inc/sqltypes.h new file mode 100644 index 00000000..0e47bf09 --- /dev/null +++ b/Windows/inc/sqltypes.h @@ -0,0 +1,355 @@ +/******************************************************** +* * +* Copyright (C) Microsoft. All rights reserved. * +* * +********************************************************/ + +//----------------------------------------------------------------------------- +// File: sqltypes.h +// +// Contents: This file defines the types used in ODBC +// +// Comments: +// +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef __SQLTYPES +#define __SQLTYPES + +#include + +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + + +/* if ODBCVER is not defined, default to ODBC 3.80 */ +#ifndef ODBCVER +#define ODBCVER 0x0380 +#endif /* ODBCVER */ + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* environment specific definitions */ +#ifndef EXPORT +#define EXPORT +#endif + +#ifdef WIN32 +#define SQL_API __stdcall +#else +#define SQL_API +#endif + +#ifndef RC_INVOKED + +/* API declaration data types */ +typedef unsigned char SQLCHAR; +#if (ODBCVER >= 0x0300) +typedef signed char SQLSCHAR; +typedef unsigned char SQLDATE; +typedef unsigned char SQLDECIMAL; +typedef double SQLDOUBLE; +typedef double SQLFLOAT; +#endif +typedef long SQLINTEGER; +typedef unsigned long SQLUINTEGER; + +#ifdef _WIN64 +typedef INT64 SQLLEN; +typedef UINT64 SQLULEN; +typedef UINT64 SQLSETPOSIROW; +#else +#define SQLLEN SQLINTEGER +#define SQLULEN SQLUINTEGER +#define SQLSETPOSIROW SQLUSMALLINT +#endif + +//For Backward compatibility +#ifdef WIN32 +typedef SQLULEN SQLROWCOUNT; +typedef SQLULEN SQLROWSETSIZE; +typedef SQLULEN SQLTRANSID; +typedef SQLLEN SQLROWOFFSET; +#endif + +#if (ODBCVER >= 0x0300) +typedef unsigned char SQLNUMERIC; +#endif +typedef void * SQLPOINTER; +#if (ODBCVER >= 0x0300) +typedef float SQLREAL; +#endif +typedef short SQLSMALLINT; +typedef unsigned short SQLUSMALLINT; +#if (ODBCVER >= 0x0300) +typedef unsigned char SQLTIME; +typedef unsigned char SQLTIMESTAMP; +typedef unsigned char SQLVARCHAR; +#endif +#if (ODBCVER >= 0x0400) +typedef unsigned char SQLTIMEWITHTIMEZONE; +typedef unsigned char SQLTIMESTAMPWITHTIMEZONE; +#endif /* ODBCVER >= 0x0400 */ + +/* function return type */ +typedef SQLSMALLINT SQLRETURN; + +/* generic data structures */ +#if (ODBCVER >= 0x0300) +#if defined(WIN32) || defined(_WIN64) +typedef void* SQLHANDLE; +#else +typedef SQLINTEGER SQLHANDLE; +#endif /* defined(WIN32) || defined(_WIN64) */ +typedef SQLHANDLE SQLHENV; +typedef SQLHANDLE SQLHDBC; +typedef SQLHANDLE SQLHSTMT; +typedef SQLHANDLE SQLHDESC; +#else //ODBCVER < 0x0300 +#if defined(WIN32) || defined(_WIN64) +typedef void* SQLHENV; +typedef void* SQLHDBC; +typedef void* SQLHSTMT; +#else +typedef SQLINTEGER SQLHENV; +typedef SQLINTEGER SQLHDBC; +typedef SQLINTEGER SQLHSTMT; +#endif /* defined(WIN32) || defined(_WIN64) */ +#endif /* ODBCVER >= 0x0300 */ + +/* SQL portable types for C */ +typedef unsigned char UCHAR; +typedef signed char SCHAR; +typedef SCHAR SQLSCHAR; +typedef long int SDWORD; +typedef short int SWORD; +typedef unsigned long int UDWORD; +typedef unsigned short int UWORD; +#ifndef _WIN64 +typedef UDWORD SQLUINTEGER; +#endif + +typedef signed long SLONG; +typedef signed short SSHORT; +typedef unsigned long ULONG; +typedef unsigned short USHORT; +typedef double SDOUBLE; +typedef double LDOUBLE; +typedef float SFLOAT; + +typedef void* PTR; + +typedef void* HENV; +typedef void* HDBC; +typedef void* HSTMT; + +typedef signed short RETCODE; + +#if defined(WIN32) || defined(OS2) +typedef HWND SQLHWND; +#elif defined (UNIX) +typedef Widget SQLHWND; +#else +/* placehold for future O/S GUI window handle definition */ +typedef SQLPOINTER SQLHWND; +#endif + +#ifndef __SQLDATE +#define __SQLDATE +/* transfer types for DATE, TIME, TIMESTAMP */ +typedef struct tagDATE_STRUCT +{ + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; +} DATE_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef DATE_STRUCT SQL_DATE_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + +typedef struct tagTIME_STRUCT +{ + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; +} TIME_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef TIME_STRUCT SQL_TIME_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + +typedef struct tagTIMESTAMP_STRUCT +{ + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; +} TIMESTAMP_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + +typedef struct tagTIME_WITH_TIMEZONE_STRUCT +{ + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLSMALLINT timezone_hours; + SQLUSMALLINT timezone_minutes; +} TIME_WITH_TIMEZONE_STRUCT; + +#if (ODBCVER >= 0x0400) +typedef TIME_WITH_TIMEZONE_STRUCT SQL_TIME_WITH_TIMEZONE_STRUCT; +#endif /* ODBCVER >= 0x0400 */ + +typedef struct tagTIMESTAMP_WITH_TIMEZONE_STRUCT +{ + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; + SQLSMALLINT timezone_hours; + SQLUSMALLINT timezone_minutes; +} TIMESTAMP_WITH_TIMEZONE_STRUCT; + +#if (ODBCVER >= 0x0400) +typedef TIMESTAMP_WITH_TIMEZONE_STRUCT SQL_TIMESTAMP_WITH_TIMEZONE_STRUCT; +#endif /* ODBCVER >= 0x0400 */ + +/* + * enumerations for DATETIME_INTERVAL_SUBCODE values for interval data types + * these values are from SQL-92 + */ + +#if (ODBCVER >= 0x0300) +typedef enum +{ + SQL_IS_YEAR = 1, + SQL_IS_MONTH = 2, + SQL_IS_DAY = 3, + SQL_IS_HOUR = 4, + SQL_IS_MINUTE = 5, + SQL_IS_SECOND = 6, + SQL_IS_YEAR_TO_MONTH = 7, + SQL_IS_DAY_TO_HOUR = 8, + SQL_IS_DAY_TO_MINUTE = 9, + SQL_IS_DAY_TO_SECOND = 10, + SQL_IS_HOUR_TO_MINUTE = 11, + SQL_IS_HOUR_TO_SECOND = 12, + SQL_IS_MINUTE_TO_SECOND = 13 +} SQLINTERVAL; + +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +typedef struct tagSQL_YEAR_MONTH +{ + SQLUINTEGER year; + SQLUINTEGER month; +} SQL_YEAR_MONTH_STRUCT; + +typedef struct tagSQL_DAY_SECOND +{ + SQLUINTEGER day; + SQLUINTEGER hour; + SQLUINTEGER minute; + SQLUINTEGER second; + SQLUINTEGER fraction; +} SQL_DAY_SECOND_STRUCT; + +typedef struct tagSQL_INTERVAL_STRUCT +{ + SQLINTERVAL interval_type; + SQLSMALLINT interval_sign; + union { + SQL_YEAR_MONTH_STRUCT year_month; + SQL_DAY_SECOND_STRUCT day_second; + } intval; + +} SQL_INTERVAL_STRUCT; + +#endif /* ODBCVER >= 0x0300 */ + +#endif /* __SQLDATE */ + +/* the ODBC C types for SQL_C_SBIGINT and SQL_C_UBIGINT */ +#if (ODBCVER >= 0x0300) +#if (_MSC_VER >= 900) +#define ODBCINT64 __int64 +#endif + +/* If using other compilers, define ODBCINT64 to the + approriate 64 bit integer type */ +#ifdef ODBCINT64 +typedef ODBCINT64 SQLBIGINT; +typedef unsigned ODBCINT64 SQLUBIGINT; +#endif +#endif /* ODBCVER >= 0x0300 */ + +/* internal representation of numeric data type */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_NUMERIC_LEN 16 +typedef struct tagSQL_NUMERIC_STRUCT +{ + SQLCHAR precision; + SQLSCHAR scale; + SQLCHAR sign; /* 1 if positive, 0 if negative */ + SQLCHAR val[SQL_MAX_NUMERIC_LEN]; +} SQL_NUMERIC_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0350) +#ifdef GUID_DEFINED +typedef GUID SQLGUID; +#else +/* size is 16 */ +typedef struct tagSQLGUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[ 8 ]; +} SQLGUID; +#endif /* GUID_DEFINED */ +#endif /* ODBCVER >= 0x0350 */ + +typedef SQLULEN BOOKMARK; + +#ifdef _WCHAR_T_DEFINED +typedef wchar_t SQLWCHAR; +#else +typedef unsigned short SQLWCHAR; +#endif + +#ifdef UNICODE +typedef SQLWCHAR SQLTCHAR; +#else +typedef SQLCHAR SQLTCHAR; +#endif /* UNICODE */ + + +#endif /* RC_INVOKED */ + + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion + +#endif /* #ifndef __SQLTYPES */ diff --git a/Windows/inc/sqlucode.h b/Windows/inc/sqlucode.h new file mode 100644 index 00000000..9e24114c --- /dev/null +++ b/Windows/inc/sqlucode.h @@ -0,0 +1,1009 @@ +//----------------------------------------------------------------------------- +// File: sqlucode.h +// +// Copyright: Copyright (c) Microsoft Corporation +// +// Contents: This is the the unicode include for ODBC Core functions +// +// Comments: +// +//----------------------------------------------------------------------------- + +#ifndef __SQLUCODE +#define __SQLUCODE + +#include + +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +#include + +#define SQL_WCHAR (-8) +#define SQL_WVARCHAR (-9) +#define SQL_WLONGVARCHAR (-10) +#define SQL_C_WCHAR SQL_WCHAR + +#ifdef UNICODE +#define SQL_C_TCHAR SQL_C_WCHAR +#else +#define SQL_C_TCHAR SQL_C_CHAR +#endif + +#define SQL_SQLSTATE_SIZEW 10 /* size of SQLSTATE for unicode */ + +#ifndef RC_INVOKED + +// UNICODE versions +#ifdef _WIN64 +SQLRETURN SQL_API SQLColAttributeW +( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + _Out_writes_bytes_opt_(cbDescMax) + SQLPOINTER pCharAttr, + SQLSMALLINT cbDescMax, + _Out_opt_ + SQLSMALLINT *pcbCharAttr, + _Out_opt_ + SQLLEN *pNumAttr +); +#else +SQLRETURN SQL_API SQLColAttributeW( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + _Out_writes_bytes_opt_(cbDescMax) + SQLPOINTER pCharAttr, + SQLSMALLINT cbDescMax, + _Out_opt_ + SQLSMALLINT *pcbCharAttr, + _Out_opt_ + SQLPOINTER pNumAttr); +#endif + +SQLRETURN SQL_API SQLColAttributesW +( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + _Out_writes_bytes_opt_(cbDescMax) + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + _Out_opt_ + SQLSMALLINT *pcbDesc, + _Out_opt_ + SQLLEN *pfDesc +); + +SQLRETURN SQL_API SQLConnectW +( + SQLHDBC hdbc, + _In_reads_(cchDSN) SQLWCHAR* szDSN, + SQLSMALLINT cchDSN, + _In_reads_(cchUID) SQLWCHAR* szUID, + SQLSMALLINT cchUID, + _In_reads_(cchAuthStr) SQLWCHAR* szAuthStr, + SQLSMALLINT cchAuthStr +); + +SQLRETURN SQL_API SQLDescribeColW +( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + _Out_writes_opt_(cchColNameMax) SQLWCHAR* szColName, + SQLSMALLINT cchColNameMax, + _Out_opt_ + SQLSMALLINT* pcchColName, + _Out_opt_ + SQLSMALLINT* pfSqlType, + _Out_opt_ + SQLULEN* pcbColDef, + _Out_opt_ + SQLSMALLINT* pibScale, + _Out_opt_ + SQLSMALLINT* pfNullable +); + +SQLRETURN SQL_API SQLErrorW +( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + _Out_writes_(6) SQLWCHAR* wszSqlState, + _Out_opt_ SQLINTEGER* pfNativeError, + _Out_writes_opt_(cchErrorMsgMax) SQLWCHAR* wszErrorMsg, + SQLSMALLINT cchErrorMsgMax, + _Out_opt_ SQLSMALLINT* pcchErrorMsg +); + +SQLRETURN SQL_API SQLExecDirectW +( + SQLHSTMT hstmt, + _In_reads_opt_(TextLength) SQLWCHAR* szSqlStr, + SQLINTEGER TextLength +); + +SQLRETURN SQL_API SQLGetConnectAttrW +( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + _Out_writes_opt_(_Inexpressible_(cbValueMax)) + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + _Out_opt_ + SQLINTEGER* pcbValue +); + +SQLRETURN SQL_API SQLGetCursorNameW +( + SQLHSTMT hstmt, + _Out_writes_opt_(cchCursorMax) SQLWCHAR* szCursor, + SQLSMALLINT cchCursorMax, + _Out_opt_ + SQLSMALLINT* pcchCursor +); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetDescFieldW +( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength +); + +SQLRETURN SQL_API SQLGetDescFieldW +( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + _Out_writes_opt_(_Inexpressible_(cbBufferLength)) + SQLPOINTER rgbValue, + SQLINTEGER cbBufferLength, + _Out_opt_ + SQLINTEGER *StringLength +); + +SQLRETURN SQL_API SQLGetDescRecW +( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + _Out_writes_opt_(cchNameMax) SQLWCHAR* szName, + SQLSMALLINT cchNameMax, + _Out_opt_ + SQLSMALLINT *pcchName, + _Out_opt_ + SQLSMALLINT *pfType, + _Out_opt_ + SQLSMALLINT *pfSubType, + _Out_opt_ + SQLLEN *pLength, + _Out_opt_ + SQLSMALLINT *pPrecision, + _Out_opt_ + SQLSMALLINT *pScale, + _Out_opt_ + SQLSMALLINT *pNullable +); + +SQLRETURN SQL_API SQLGetDiagFieldW +( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + _Out_writes_opt_(_Inexpressible_(cbBufferLength)) + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbBufferLength, + _Out_opt_ + SQLSMALLINT *pcbStringLength +); + +SQLRETURN SQL_API SQLGetDiagRecW +( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + _Out_writes_opt_(6) SQLWCHAR* szSqlState, + SQLINTEGER* pfNativeError, + _Out_writes_opt_(cchErrorMsgMax) SQLWCHAR* szErrorMsg, + SQLSMALLINT cchErrorMsgMax, + SQLSMALLINT* pcchErrorMsg +); +#endif + +SQLRETURN SQL_API SQLPrepareW +( + SQLHSTMT hstmt, + _In_reads_(cchSqlStr) SQLWCHAR* szSqlStr, + SQLINTEGER cchSqlStr +); + +SQLRETURN SQL_API SQLSetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + _In_reads_bytes_opt_(cbValue) + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameW +( + SQLHSTMT hstmt, + _In_reads_(cchCursor) SQLWCHAR* szCursor, + SQLSMALLINT cchCursor +); + +SQLRETURN SQL_API SQLColumnsW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName, + _In_reads_opt_(cchColumnName) SQLWCHAR* szColumnName, + SQLSMALLINT cchColumnName +); + +SQLRETURN SQL_API SQLGetConnectOptionW( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API SQLGetInfoW( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + _Out_writes_bytes_opt_(cbInfoValueMax) SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + _Out_opt_ + SQLSMALLINT* pcbInfoValue); + +SQLRETURN SQL_API SQLGetTypeInfoW( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + +SQLRETURN SQL_API SQLSetConnectOptionW( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSpecialColumnsW +( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable +); + +SQLRETURN SQL_API SQLStatisticsW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy +); + +SQLRETURN SQL_API SQLTablesW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName, + _In_reads_opt_(cchTableType) SQLWCHAR* szTableType, + SQLSMALLINT cchTableType +); + +SQLRETURN SQL_API SQLDataSourcesW +( + SQLHENV henv, + SQLUSMALLINT fDirection, + _Out_writes_opt_(cchDSNMax) SQLWCHAR* szDSN, + SQLSMALLINT cchDSNMax, + _Out_opt_ + SQLSMALLINT* pcchDSN, + _Out_writes_opt_(cchDescriptionMax) SQLWCHAR* wszDescription, + SQLSMALLINT cchDescriptionMax, + _Out_opt_ + SQLSMALLINT* pcchDescription +); + +SQLRETURN SQL_API SQLDriverConnectW +( + SQLHDBC hdbc, + SQLHWND hwnd, + _In_reads_(cchConnStrIn) SQLWCHAR* szConnStrIn, + SQLSMALLINT cchConnStrIn, + _Out_writes_opt_(cchConnStrOutMax) SQLWCHAR* szConnStrOut, + SQLSMALLINT cchConnStrOutMax, + _Out_opt_ SQLSMALLINT* pcchConnStrOut, + SQLUSMALLINT fDriverCompletion +); + +SQLRETURN SQL_API SQLBrowseConnectW +( + SQLHDBC hdbc, + _In_reads_(cchConnStrIn) SQLWCHAR* szConnStrIn, + SQLSMALLINT cchConnStrIn, + _Out_writes_opt_(cchConnStrOutMax) SQLWCHAR* szConnStrOut, + SQLSMALLINT cchConnStrOutMax, + _Out_opt_ + SQLSMALLINT* pcchConnStrOut +); + +SQLRETURN SQL_API SQLColumnPrivilegesW( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName, + _In_reads_opt_(cchColumnName) SQLWCHAR* szColumnName, + SQLSMALLINT cchColumnName +); + +SQLRETURN SQL_API SQLGetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLSetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); + +SQLRETURN SQL_API SQLForeignKeysW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchPkCatalogName) SQLWCHAR* szPkCatalogName, + SQLSMALLINT cchPkCatalogName, + _In_reads_opt_(cchPkSchemaName) SQLWCHAR* szPkSchemaName, + SQLSMALLINT cchPkSchemaName, + _In_reads_opt_(cchPkTableName) SQLWCHAR* szPkTableName, + SQLSMALLINT cchPkTableName, + _In_reads_opt_(cchFkCatalogName) SQLWCHAR* szFkCatalogName, + SQLSMALLINT cchFkCatalogName, + _In_reads_opt_(cchFkSchemaName) SQLWCHAR* szFkSchemaName, + SQLSMALLINT cchFkSchemaName, + _In_reads_opt_(cchFkTableName) SQLWCHAR* szFkTableName, + SQLSMALLINT cchFkTableName +); + +SQLRETURN SQL_API SQLNativeSqlW +( + SQLHDBC hdbc, + _In_reads_(cchSqlStrIn) SQLWCHAR* szSqlStrIn, + SQLINTEGER cchSqlStrIn, + _Out_writes_opt_(cchSqlStrMax) SQLWCHAR* szSqlStr, + SQLINTEGER cchSqlStrMax, + SQLINTEGER* pcchSqlStr +); + +SQLRETURN SQL_API SQLPrimaryKeysW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName +); + +SQLRETURN SQL_API SQLProcedureColumnsW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchProcName) SQLWCHAR* szProcName, + SQLSMALLINT cchProcName, + _In_reads_opt_(cchColumnName) SQLWCHAR* szColumnName, + SQLSMALLINT cchColumnName +); + +SQLRETURN SQL_API SQLProceduresW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchProcName) SQLWCHAR* szProcName, + SQLSMALLINT cchProcName +); + +SQLRETURN SQL_API SQLTablePrivilegesW +( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR* szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR* szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTableName) SQLWCHAR* szTableName, + SQLSMALLINT cchTableName +); + +SQLRETURN SQL_API SQLDriversW +( + SQLHENV henv, + SQLUSMALLINT fDirection, + _Out_writes_opt_(cchDriverDescMax) SQLWCHAR* szDriverDesc, + SQLSMALLINT cchDriverDescMax, + _Out_opt_ + SQLSMALLINT* pcchDriverDesc, + _Out_writes_opt_(cchDrvrAttrMax) SQLWCHAR* szDriverAttributes, + SQLSMALLINT cchDrvrAttrMax, + _Out_opt_ + SQLSMALLINT* pcchDrvrAttr +); + +#if (ODBCVER >= 0x0400) +SQLRETURN SQL_API SQLStructuredTypesW( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTypeName) SQLWCHAR *szTypeName, + SQLSMALLINT cchTypeName); + +SQLRETURN SQL_API SQLStructuredTypeColumnsW( + SQLHSTMT hstmt, + _In_reads_opt_(cchCatalogName) SQLWCHAR *szCatalogName, + SQLSMALLINT cchCatalogName, + _In_reads_opt_(cchSchemaName) SQLWCHAR *szSchemaName, + SQLSMALLINT cchSchemaName, + _In_reads_opt_(cchTypeName) SQLWCHAR *szTypeName, + SQLSMALLINT cchTypeName, + _In_reads_opt_(cchColumnName) SQLWCHAR *szColumnName, + SQLSMALLINT cchColumnName); +#endif /* ODBCVER >= 0x0400 */ + +// ANSI versions +#ifdef _WIN64 +SQLRETURN SQL_API SQLColAttributeA( + SQLHSTMT hstmt, + SQLSMALLINT iCol, + SQLSMALLINT iField, + _Out_writes_bytes_opt_(cbCharAttrMax) + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + _Out_opt_ + SQLSMALLINT *pcbCharAttr, + _Out_opt_ + SQLLEN *pNumAttr); +#else +SQLRETURN SQL_API SQLColAttributeA( + SQLHSTMT hstmt, + SQLSMALLINT iCol, + SQLSMALLINT iField, + _Out_writes_bytes_opt_(cbCharAttrMax) + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + _Out_opt_ + SQLSMALLINT *pcbCharAttr, + _Out_opt_ + SQLPOINTER pNumAttr); +#endif + +SQLRETURN SQL_API SQLColAttributesA( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + _Out_writes_bytes_opt_(cbDescMax) + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + _Out_opt_ + SQLSMALLINT *pcbDesc, + _Out_opt_ + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLConnectA( + SQLHDBC hdbc, + _In_reads_(cbDSN) + SQLCHAR *szDSN, + SQLSMALLINT cbDSN, + _In_reads_(cbUID) + SQLCHAR *szUID, + SQLSMALLINT cbUID, + _In_reads_(cbAuthStr) + SQLCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API SQLDescribeColA( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + _Out_writes_opt_(cbColNameMax) + SQLCHAR *szColName, + SQLSMALLINT cbColNameMax, + _Out_opt_ + SQLSMALLINT *pcbColName, + _Out_opt_ + SQLSMALLINT *pfSqlType, + _Out_opt_ + SQLULEN *pcbColDef, + _Out_opt_ + SQLSMALLINT *pibScale, + _Out_opt_ + SQLSMALLINT *pfNullable); + +SQLRETURN SQL_API SQLErrorA( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + _Out_writes_(SQL_SQLSTATE_SIZE + 1) + SQLCHAR *szSqlState, + _Out_opt_ + SQLINTEGER *pfNativeError, + _Out_writes_opt_(cbErrorMsgMax) + SQLCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + _Out_opt_ + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectA( + SQLHSTMT hstmt, + _In_reads_opt_(cbSqlStr) + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrA( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + _Out_writes_opt_(_Inexpressible_(cbValueMax)) + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + _Out_opt_ + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameA( + SQLHSTMT hstmt, + _Out_writes_opt_(cbCursorMax) + SQLCHAR *szCursor, + SQLSMALLINT cbCursorMax, + _Out_opt_ + SQLSMALLINT *pcbCursor); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetDescFieldA( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + _Out_writes_opt_(_Inexpressible_(cbBufferLength)) + SQLPOINTER rgbValue, + SQLINTEGER cbBufferLength, + _Out_opt_ + SQLINTEGER *StringLength); + +SQLRETURN SQL_API SQLGetDescRecA( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + _Out_writes_opt_(cbNameMax) + SQLCHAR *szName, + SQLSMALLINT cbNameMax, + _Out_opt_ + SQLSMALLINT *pcbName, + _Out_opt_ + SQLSMALLINT *pfType, + _Out_opt_ + SQLSMALLINT *pfSubType, + _Out_opt_ + SQLLEN *pLength, + _Out_opt_ + SQLSMALLINT *pPrecision, + _Out_opt_ + SQLSMALLINT *pScale, + _Out_opt_ + SQLSMALLINT *pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldA( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + _Out_writes_opt_(_Inexpressible_(cbDiagInfoMax)) + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + _Out_opt_ + SQLSMALLINT *pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecA( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + _Out_writes_opt_(6) + SQLCHAR *szSqlState, + SQLINTEGER *pfNativeError, + _Out_writes_opt_(cbErrorMsgMax) + SQLCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API SQLGetStmtAttrA( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); +#endif + +SQLRETURN SQL_API SQLGetTypeInfoA( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + +SQLRETURN SQL_API SQLPrepareA( + SQLHSTMT hstmt, + _In_reads_(cbSqlStr) + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLSetConnectAttrA( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + _In_reads_bytes_opt_(cbValue) + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameA( + SQLHSTMT hstmt, + _In_reads_(cbCursor) + SQLCHAR *szCursor, + SQLSMALLINT cbCursor); + +SQLRETURN SQL_API SQLColumnsA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + _In_reads_opt_(cbColumnName) + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetConnectOptionA( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API SQLGetInfoA( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + _Out_writes_bytes_opt_(cbInfoValueMax) + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + _Out_opt_ + SQLSMALLINT* pcbInfoValue); + +SQLRETURN SQL_API SQLGetStmtOptionA( + SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API SQLSetConnectOptionA( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSetStmtOptionA( + SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSpecialColumnsA( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + _In_reads_opt_(cbTableType) + SQLCHAR *szTableType, + SQLSMALLINT cbTableType); + +SQLRETURN SQL_API SQLDataSourcesA( + SQLHENV henv, + SQLUSMALLINT fDirection, + _Out_writes_opt_(cbDSNMax) + SQLCHAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT *pcbDSN, + _Out_writes_opt_(cbDescriptionMax) + SQLCHAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT *pcbDescription); + +SQLRETURN SQL_API SQLDriverConnectA( + SQLHDBC hdbc, + SQLHWND hwnd, + _In_reads_(cbConnStrIn) + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + _Out_writes_opt_(cbConnStrOutMax) + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + _Out_opt_ + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +SQLRETURN SQL_API SQLBrowseConnectA( + SQLHDBC hdbc, + _In_reads_(cbConnStrIn) + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + _Out_writes_opt_(cbConnStrOutMax) + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + _Out_opt_ + SQLSMALLINT *pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + _In_reads_opt_(cbColumnName) + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLDescribeParamA( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + _Out_opt_ + SQLSMALLINT *pfSqlType, + _Out_opt_ + SQLUINTEGER *pcbParamDef, + _Out_opt_ + SQLSMALLINT *pibScale, + _Out_opt_ + SQLSMALLINT *pfNullable); + +SQLRETURN SQL_API SQLForeignKeysA( + SQLHSTMT hstmt, + _In_reads_opt_(cbPkCatalogName) + SQLCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + _In_reads_opt_(cbPkSchemaName) + SQLCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + _In_reads_opt_(cbPkTableName) + SQLCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + _In_reads_opt_(cbFkCatalogName) + SQLCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + _In_reads_opt_(cbFkSchemaName) + SQLCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + _In_reads_opt_(cbFkTableName) + SQLCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLNativeSqlA( + SQLHDBC hdbc, + _In_reads_(cbSqlStrIn) + SQLCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + _Out_writes_opt_(cbSqlStrMax) + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + +SQLRETURN SQL_API SQLPrimaryKeysA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbProcName) + SQLCHAR *szProcName, + SQLSMALLINT cbProcName, + _In_reads_opt_(cbColumnName) + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbProcName) + SQLCHAR *szProcName, + SQLSMALLINT cbProcName); + +SQLRETURN SQL_API SQLTablePrivilegesA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTableName) + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDriversA( + SQLHENV henv, + SQLUSMALLINT fDirection, + _Out_writes_opt_(cbDriverDescMax) + SQLCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + _Out_opt_ + SQLSMALLINT *pcbDriverDesc, + _Out_writes_opt_(cbDrvrAttrMax) + SQLCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + _Out_opt_ + SQLSMALLINT *pcbDrvrAttr); + +#if (ODBCVER >= 0x0400) +SQLRETURN SQL_API SQLStructuredTypesA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTypeName) SQLCHAR *szTypeName, + SQLSMALLINT cbTypeName); + +SQLRETURN SQL_API SQLStructuredTypeColumnsA( + SQLHSTMT hstmt, + _In_reads_opt_(cbCatalogName) SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + _In_reads_opt_(cbSchemaName) SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + _In_reads_opt_(cbTypeName) SQLCHAR *szTypeName, + SQLSMALLINT cbTypeName, + _In_reads_opt_(cbColumnName) SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); +#endif /* ODBCVER >= 0x0400 */ +//--------------------------------------------- +// Mapping macros for Unicode +//--------------------------------------------- +#ifndef SQL_NOUNICODEMAP // define this to disable the mapping +#ifdef UNICODE + +#define SQLColAttribute SQLColAttributeW +#define SQLColAttributes SQLColAttributesW +#define SQLConnect SQLConnectW +#define SQLDescribeCol SQLDescribeColW +#define SQLError SQLErrorW +#define SQLExecDirect SQLExecDirectW +#define SQLGetConnectAttr SQLGetConnectAttrW +#define SQLGetCursorName SQLGetCursorNameW +#define SQLGetDescField SQLGetDescFieldW +#define SQLGetDescRec SQLGetDescRecW +#define SQLGetDiagField SQLGetDiagFieldW +#define SQLGetDiagRec SQLGetDiagRecW +#define SQLPrepare SQLPrepareW +#define SQLSetConnectAttr SQLSetConnectAttrW +#define SQLSetCursorName SQLSetCursorNameW +#define SQLSetDescField SQLSetDescFieldW +#define SQLSetStmtAttr SQLSetStmtAttrW +#define SQLGetStmtAttr SQLGetStmtAttrW +#define SQLColumns SQLColumnsW +#define SQLGetConnectOption SQLGetConnectOptionW +#define SQLGetInfo SQLGetInfoW +#define SQLGetTypeInfo SQLGetTypeInfoW +#define SQLSetConnectOption SQLSetConnectOptionW +#define SQLSpecialColumns SQLSpecialColumnsW +#define SQLStatistics SQLStatisticsW +#define SQLStructuredTypes SQLStructuredTypesW +#define SQLStructuredTypeColumns SQLStructuredTypeColumnsW +#define SQLTables SQLTablesW +#define SQLDataSources SQLDataSourcesW +#define SQLDriverConnect SQLDriverConnectW +#define SQLBrowseConnect SQLBrowseConnectW +#define SQLColumnPrivileges SQLColumnPrivilegesW +#define SQLForeignKeys SQLForeignKeysW +#define SQLNativeSql SQLNativeSqlW +#define SQLPrimaryKeys SQLPrimaryKeysW +#define SQLProcedureColumns SQLProcedureColumnsW +#define SQLProcedures SQLProceduresW +#define SQLTablePrivileges SQLTablePrivilegesW +#define SQLDrivers SQLDriversW + +#endif /* UNICODE */ +#endif /* SQL_NOUNICODEMAP */ + +#endif /* RC_INVOKED */ + + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion + +#endif /* #ifndef __SQLUCODE */ diff --git a/contribution-agreement.md b/contribution-agreement.md new file mode 100644 index 00000000..e4b0f6a7 --- /dev/null +++ b/contribution-agreement.md @@ -0,0 +1,44 @@ +# ODBC 4.0 Specification Contribution License Agreement +The Microsoft ODBC 4.0 Specification Project welcomes input. By participating in project you agree to the following: + +##1.1 Definitions. +A. “**You**” means the individual executing this Agreement. + +B. “**Entity**” means (1) Your principal, sponsor, or employer and (2) its Affiliates (i.e., entities that control, are controlled by, or are under common control with that principal, sponsor, or employer). If Your principal, sponsor, or employer changes, You must secure permission from the new entity and sign a new Agreement before making further Contributions. + +C. “**Microsoft**” means Microsoft Corporation and its affiliates and licensees. + +D. “**Project**” means the following computer architecture, software, specifications, and documentation owned or managed by Microsoft: + +1. Microsoft ODBC 4.0 Specification, an incremental update to the ODBC Programmers Reference and associated Driver Manager, Installer, configuration utility, header files, samples, SDK, and related components. + +E. "**Contribution**" means any proposal, suggestion, work of authorship, or other verbal submission (including oral contributions if also reduced to writing) made by You or Entity in any form to Microsoft or its representatives regarding a Project, unless conspicuously identified in writing in advance as “Not a Contribution” before or at the time of the communication. + +##1.2 Use Rights. +Contributions may be used by Microsoft for any purpose relating to the Project to which the Contribution was submitted. + +##1.3 Representations. +You represent that (1) You are authorized to make this Agreement and legally entitled to grant the licenses on Your own behalf and on behalf of Entity, and (2) except for patents that are subject to the Patent License Grant below, at the time each Contribution is made You will identify to Microsoft in writing any patent that (a) You believe might be infringed by use or implementation of the Contribution or (b) to Your knowledge others have asserted might be infringed by use or implementation of the Contribution. + +##1.4 Warranties. +You and Entity warrant that You and/or Entity own the copyright in each Contribution or otherwise have sufficient rights under copyright to make each Contribution (in which case You must identify each owner and provide details of any third-party license or other restriction of which You are aware) under the following Copyright License Grant. + +##1.5 Copyright License Grant. +You and Entity hereby grant to Microsoft a non-exclusive, transferable, worldwide, perpetual, irrevocable, sublicensable, fee- and royalty-free copyright license to disclose, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Contributions. + +##1.6 Patent License Grant. +With respect to patent claims owned or licensable by You or Entity that are necessarily infringed by use or implementation of any Contribution, You and Entity hereby grant to Microsoft and implementers of the Project and derivative works thereof a perpetual, irrevocable (except as set forth below), non-exclusive, worldwide, fee- and royalty-free patent license to use, make, have made, offer to sell, sell, distribute, import, and otherwise transfer products and services that use or implement the Contribution; provided, however, that +(1) the licensing obligations do not apply if the sublicensing of patents requires that You or Entity pay patent license fees or royalties to an unaffiliated third party, or the patents are subject to an exclusive license, and (2) any patent licenses granted pursuant to this Agreement terminate, as of the date litigation is filed, as to any entity that institutes, joins, or financially supports litigation seeking damages or injunctive relief based on claims that use or implementation of a Contribution, or the Project to which such Contribution was made, constitutes direct, indirect, or contributory patent infringement. + +##1.7 Other Rights Reserved. +Each party reserves all rights not expressly granted in this Agreement. No rights are granted by implication, exhaustion, estoppel, or otherwise. + +##1.8 Updates. +You agree to notify Microsoft in writing of any facts or circumstances of which You become aware that would make Your representations in this Agreement inaccurate in any respect. + +##1.9 Public Information. +You agree that contributions to Projects and information about Contributions may be maintained indefinitely and disclosed publicly, including Your name, Entity’s name, and other information relating to Your Contributions. + +##1.10 Entire Agreement/Assignment. +This Agreement is the entire agreement between the parties, and supersedes any and all prior agreements, understandings or communications, written or oral, between the parties relating to the subject matter hereof. This Agreement may be assigned by Microsoft. + diff --git a/license.txt b/license.txt new file mode 100644 index 00000000..4c2ecc94 --- /dev/null +++ b/license.txt @@ -0,0 +1,16 @@ +---- +ODBC Specification + +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +---- From 0a45de64c0a25e58d580a21493e69aa99cc03e6c Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Fri, 20 Jul 2018 19:51:20 +0200 Subject: [PATCH 2/9] Squashed 'libs/c-timestamp/' content from commit b205c40 git-subtree-dir: libs/c-timestamp git-subtree-split: b205c407ae6680d23d74359ac00444b80989792f --- .travis.yml | 16 +++ Makefile | 85 +++++++++++ README.md | 25 ++++ t/compare.c | 25 ++++ t/format.c | 168 ++++++++++++++++++++++ t/parse_malformed.c | 61 ++++++++ t/parse_wellformed.c | 101 ++++++++++++++ t/tap.c | 325 +++++++++++++++++++++++++++++++++++++++++++ t/tap.h | 114 +++++++++++++++ t/tm.c | 63 +++++++++ t/valid.c | 32 +++++ timestamp.h | 55 ++++++++ timestamp_compare.c | 40 ++++++ timestamp_format.c | 186 +++++++++++++++++++++++++ timestamp_parse.c | 168 ++++++++++++++++++++++ timestamp_tm.c | 92 ++++++++++++ timestamp_valid.c | 40 ++++++ 17 files changed, 1596 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile create mode 100644 README.md create mode 100644 t/compare.c create mode 100644 t/format.c create mode 100644 t/parse_malformed.c create mode 100644 t/parse_wellformed.c create mode 100644 t/tap.c create mode 100644 t/tap.h create mode 100644 t/tm.c create mode 100644 t/valid.c create mode 100644 timestamp.h create mode 100644 timestamp_compare.c create mode 100644 timestamp_format.c create mode 100644 timestamp_parse.c create mode 100644 timestamp_tm.c create mode 100644 timestamp_valid.c diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..289fc2ba --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: perl +install: "perl -V" +before_script: + - "cpanm -n Test::Harness" + - sudo pip install cpp-coveralls --use-mirrors +script: "make test" +after_success: + - "make clean" + - "make gcov" + - coveralls --exclude t +notifications: + recipients: + - chansen@cpan.org + email: + on_success: change + on_failure: always diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e4afb3f9 --- /dev/null +++ b/Makefile @@ -0,0 +1,85 @@ +CC = cc +GCOV = gcov +CFLAGS = $(DCFLAGS) -Wall -I. -I.. +LDFLAGS += -lc $(DLDFLAGS) + +SOURCES = \ + timestamp_compare.c \ + timestamp_format.c \ + timestamp_parse.c \ + timestamp_valid.c \ + timestamp_tm.c + +OBJECTS = \ + timestamp_compare.o \ + timestamp_format.o \ + timestamp_parse.o \ + timestamp_valid.o \ + timestamp_tm.o + +HARNESS_OBJS = \ + t/valid.o \ + t/compare.o \ + t/format.o \ + t/parse_wellformed.o \ + t/parse_malformed.o \ + t/tm.o + +HARNESS_EXES = \ + t/valid.t \ + t/compare.t \ + t/format.t \ + t/parse_wellformed.t \ + t/parse_malformed.t \ + t/tm.t + +HARNESS_DEPS = \ + $(OBJECTS) \ + t/tap.o + +.SUFFIXES: +.SUFFIXES: .o .c .t + +.PHONY: check-asan test gcov cover clean + +.o.t: + $(CC) $(LDFLAGS) $< $(HARNESS_DEPS) -o $@ + +t/valid.o: \ + $(HARNESS_DEPS) t/valid.c + +t/compare.o: \ + $(HARNESS_DEPS) t/compare.c + +t/format.o: \ + $(HARNESS_DEPS) t/format.c + +t/parse_wellformed.o: \ + $(HARNESS_DEPS) t/parse_wellformed.c + +t/parse_malformed.o: \ + $(HARNESS_DEPS) t/parse_malformed.c + +t/tm.o: \ + $(HARNESS_DEPS) t/tm.c + +test: $(HARNESS_EXES) + @prove $(HARNESS_EXES) + +check-asan: + @$(MAKE) DCFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer" \ + DLDFLAGS="-g -fsanitize=address" test + +gcov: + @$(MAKE) DCFLAGS="-O0 -g -coverage" DLDFLAGS="-coverage" test + @$(GCOV) $(SOURCES) + +cover: + @$(MAKE) DCFLAGS="-O0 -g --coverage" DLDFLAGS="-coverage" test + @$(GCOV) -abc $(SOURCES) + @gcov2perl *.gcov + @cover --no-gcov + +clean: + rm -f $(HARNESS_DEPS) $(HARNESS_OBJS) $(HARNESS_EXES) *.gc{ov,da,no} t/*.gc{ov,da,no} + diff --git a/README.md b/README.md new file mode 100644 index 00000000..e038b4c2 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +[![Build Status](https://travis-ci.org/chansen/c-timestamp.png?branch=master)](https://travis-ci.org/chansen/c-timestamp) [![Coverage Status](https://coveralls.io/repos/chansen/c-timestamp/badge.png)](https://coveralls.io/r/chansen/c-timestamp) + +timestamp +========= + + +```c + +typedef struct { + int64_t sec; /* Number of seconds since the epoch of 1970-01-01T00:00:00Z */ + int32_t nsec; /* Nanoseconds [0, 999999999] */ + int16_t offset; /* Offset from UTC in minutes [-1439, 1439] */ +} timestamp_t; + +int timestamp_parse (const char *str, size_t len, timestamp_t *tsp); +size_t timestamp_format (char *dst, size_t len, const timestamp_t *tsp); +size_t timestamp_format_precision (char *dst, size_t len, const timestamp_t *tsp, int precision); +int timestamp_compare (const timestamp_t *tsp1, const timestamp_t *tsp2); +bool timestamp_valid (const timestamp_t *tsp); +struct tm * timestamp_to_tm_utc (const timestamp_t *tsp, struct tm *tmp); +struct tm * timestamp_to_tm_local (const timestamp_t *tsp, struct tm *tmp); + + +``` + diff --git a/t/compare.c b/t/compare.c new file mode 100644 index 00000000..85690b5a --- /dev/null +++ b/t/compare.c @@ -0,0 +1,25 @@ +#include +#include "timestamp.h" +#include "tap.h" + +int +main() { + timestamp_t t1, t2; + + t1.sec = t2.sec = 0; + t1.nsec = t2.nsec = 0; + t1.offset = t2.offset = 0; + cmp_ok(timestamp_compare(&t1, &t2), "==", 0, "t1 == t2"); + + t1.sec = 1; + cmp_ok(timestamp_compare(&t1, &t2), ">", 0, "t1 > t2"); + cmp_ok(timestamp_compare(&t2, &t1), "<", 0, "t1 < t2"); + + t1.sec = 0; + t1.nsec = 1; + cmp_ok(timestamp_compare(&t1, &t2), ">", 0, "t1 > t2"); + cmp_ok(timestamp_compare(&t2, &t1), "<", 0, "t2 < t1"); + + done_testing(); +} + diff --git a/t/format.c b/t/format.c new file mode 100644 index 00000000..b32f22f2 --- /dev/null +++ b/t/format.c @@ -0,0 +1,168 @@ +#include +#include "timestamp.h" +#include "tap.h" + +const struct test_t { + timestamp_t ts; + int precision; + const char *exp; +} tests[] = { + { { INT64_C(-62135596800), 0, 0 }, 0, "0001-01-01T00:00:00Z" }, + { { INT64_C(-62135683140), 0, 1439 }, 0, "0001-01-01T00:00:00+23:59" }, + { { INT64_C(-62135510460), 0, -1439 }, 0, "0001-01-01T00:00:00-23:59" }, + { { INT64_C(253402300799), 0, 0 }, 0, "9999-12-31T23:59:59Z" }, + { { INT64_C(253402214459), 0, 1439 }, 0, "9999-12-31T23:59:59+23:59" }, + { { INT64_C(253402387139), 0, -1439 }, 0, "9999-12-31T23:59:59-23:59" }, + { { 0, 0, 0 }, 0, "1970-01-01T00:00:00Z" }, + { { 1, 0, 0 }, 0, "1970-01-01T00:00:01Z" }, + { { 10, 0, 0 }, 0, "1970-01-01T00:00:10Z" }, + { { 60, 0, 0 }, 0, "1970-01-01T00:01:00Z" }, + { { 600, 0, 0 }, 0, "1970-01-01T00:10:00Z" }, + { { 3600, 0, 0 }, 0, "1970-01-01T01:00:00Z" }, + { { 36000, 0, 0 }, 0, "1970-01-01T10:00:00Z" }, + { { 0, 123456789, 0 }, 9, "1970-01-01T00:00:00.123456789Z" }, + { { 0, 123456780, 0 }, 9, "1970-01-01T00:00:00.123456780Z" }, + { { 0, 123456700, 0 }, 9, "1970-01-01T00:00:00.123456700Z" }, + { { 0, 123456000, 0 }, 6, "1970-01-01T00:00:00.123456Z" }, + { { 0, 123450000, 0 }, 6, "1970-01-01T00:00:00.123450Z" }, + { { 0, 123400000, 0 }, 6, "1970-01-01T00:00:00.123400Z" }, + { { 0, 123000000, 0 }, 3, "1970-01-01T00:00:00.123Z" }, + { { 0, 120000000, 0 }, 3, "1970-01-01T00:00:00.120Z" }, + { { 0, 100000000, 0 }, 3, "1970-01-01T00:00:00.100Z" }, + { { 0, 10000000, 0 }, 3, "1970-01-01T00:00:00.010Z" }, + { { 0, 1000000, 0 }, 3, "1970-01-01T00:00:00.001Z" }, + { { 0, 100000, 0 }, 6, "1970-01-01T00:00:00.000100Z" }, + { { 0, 10000, 0 }, 6, "1970-01-01T00:00:00.000010Z" }, + { { 0, 1000, 0 }, 6, "1970-01-01T00:00:00.000001Z" }, + { { 0, 100, 0 }, 9, "1970-01-01T00:00:00.000000100Z" }, + { { 0, 10, 0 }, 9, "1970-01-01T00:00:00.000000010Z" }, + { { 0, 1, 0 }, 9, "1970-01-01T00:00:00.000000001Z" }, + { { 0, 9, 0 }, 9, "1970-01-01T00:00:00.000000009Z" }, + { { 0, 90, 0 }, 9, "1970-01-01T00:00:00.000000090Z" }, + { { 0, 900, 0 }, 9, "1970-01-01T00:00:00.000000900Z" }, + { { 0, 9000, 0 }, 6, "1970-01-01T00:00:00.000009Z" }, + { { 0, 90000, 0 }, 6, "1970-01-01T00:00:00.000090Z" }, + { { 0, 900000, 0 }, 6, "1970-01-01T00:00:00.000900Z" }, + { { 0, 9000000, 0 }, 3, "1970-01-01T00:00:00.009Z" }, + { { 0, 90000000, 0 }, 3, "1970-01-01T00:00:00.090Z" }, + { { 0, 900000000, 0 }, 3, "1970-01-01T00:00:00.900Z" }, + { { 0, 990000000, 0 }, 3, "1970-01-01T00:00:00.990Z" }, + { { 0, 999000000, 0 }, 3, "1970-01-01T00:00:00.999Z" }, + { { 0, 999900000, 0 }, 6, "1970-01-01T00:00:00.999900Z" }, + { { 0, 999990000, 0 }, 6, "1970-01-01T00:00:00.999990Z" }, + { { 0, 999999000, 0 }, 6, "1970-01-01T00:00:00.999999Z" }, + { { 0, 999999900, 0 }, 9, "1970-01-01T00:00:00.999999900Z" }, + { { 0, 999999990, 0 }, 9, "1970-01-01T00:00:00.999999990Z" }, + { { 0, 999999999, 0 }, 9, "1970-01-01T00:00:00.999999999Z" }, + { { 0, 0, 1439 }, 0, "1970-01-01T23:59:00+23:59" }, + { { 0, 0, 120 }, 0, "1970-01-01T02:00:00+02:00" }, + { { 0, 0, 90 }, 0, "1970-01-01T01:30:00+01:30" }, + { { 0, 0, 60 }, 0, "1970-01-01T01:00:00+01:00" }, + { { 0, 0, 1 }, 0, "1970-01-01T00:01:00+00:01" }, + { { 0, 0, -1 }, 0, "1969-12-31T23:59:00-00:01" }, + { { 0, 0, -60 }, 0, "1969-12-31T23:00:00-01:00" }, + { { 0, 0, -90 }, 0, "1969-12-31T22:30:00-01:30" }, + { { 0, 0, -120 }, 0, "1969-12-31T22:00:00-02:00" }, + { { 0, 0, -1439 }, 0, "1969-12-31T00:01:00-23:59" }, + { { 951782400, 0, 0 }, 0, "2000-02-29T00:00:00Z" }, + { { 1078012800, 0, 0 }, 0, "2004-02-29T00:00:00Z" }, +}; + +int +main() { + int i, ntests; + char buf[40]; + timestamp_t ts; + int n; + + ntests = sizeof(tests) / sizeof(*tests); + for (i = 0; i < ntests; i++) { + const struct test_t t = tests[i]; + + n = (int)timestamp_format(buf, sizeof(buf), &t.ts); + cmp_ok(n, "==", strlen(t.exp), "timestamp_format() (exp: \"%s\")", t.exp); + is(buf, t.exp); + + n = (int)timestamp_format_precision(buf, sizeof(buf), &t.ts, t.precision); + cmp_ok(n, "==", strlen(t.exp), "timestamp_format_precision(%d) (exp: \"%s\")", t.precision, t.exp); + is(buf, t.exp); + } + + { + ts.sec = 0; + ts.nsec = 0; + ts.offset = 0; + n = (int)timestamp_format_precision(buf, sizeof(buf), &ts, 9); + cmp_ok(n, "==", 30); + is(buf, "1970-01-01T00:00:00.000000000Z"); + + n = (int)timestamp_format_precision(buf, sizeof(buf), &ts, 6); + cmp_ok(n, "==", 27); + is(buf, "1970-01-01T00:00:00.000000Z"); + + n = (int)timestamp_format_precision(buf, sizeof(buf), &ts, 2); + cmp_ok(n, "==", 23); + is(buf, "1970-01-01T00:00:00.00Z"); + + n = (int)timestamp_format_precision(buf, sizeof(buf), &ts, 1); + cmp_ok(n, "==", 22); + is(buf, "1970-01-01T00:00:00.0Z"); + } + + { + ts.sec = 0; + ts.offset = 0; + ts.nsec = -1; + ok(!timestamp_format(buf, sizeof(buf), &ts), "nsec out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 0), "nsec out of range"); + ts.nsec = 1000000000; + ok(!timestamp_format(buf, sizeof(buf), &ts), "nsec out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 0), "nsec out of range"); + ts.nsec = 0; + ts.offset = -23 * 60 - 60; + ok(!timestamp_format(buf, sizeof(buf), &ts), "offset out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 0), "offset out of range"); + ts.offset = +23 * 60 + 60; + ok(!timestamp_format(buf, sizeof(buf), &ts), "offset out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 0), "offset out of range"); + ts.offset = 0; + ts.sec = INT64_C(-62135596801); /* 0000-12-31T23:59:59Z */ + ok(!timestamp_format(buf, sizeof(buf), &ts), "sec out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 0), "sec out of range"); + ts.sec = INT64_C(253402387140); /* 10000-01-01T23:59:00Z */ + ok(!timestamp_format(buf, sizeof(buf), &ts), "sec out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 0), "sec out of range"); + ts.sec = 0; + ts.offset = 0; + ts.nsec = 0; + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, -1), "precision out of range"); + ok(!timestamp_format_precision(buf, sizeof(buf), &ts, 10), "precision out of range"); + } + + /* + * 1 2 3 + * 12345678901234567890123456789012345 (+ null-terminator) + * YYYY-MM-DDThh:mm:ssZ + * YYYY-MM-DDThh:mm:ss±hh:mm + * YYYY-MM-DDThh:mm:ss.123Z + * YYYY-MM-DDThh:mm:ss.123±hh:mm + * YYYY-MM-DDThh:mm:ss.123456Z + * YYYY-MM-DDThh:mm:ss.123456±hh:mm + * YYYY-MM-DDThh:mm:ss.123456789Z + * YYYY-MM-DDThh:mm:ss.123456789±hh:mm + */ + + { + ts.sec = 0; + ts.offset = 0; + ts.nsec = 0; + ok( timestamp_format(buf, 21, &ts), "suffcient buffer size"); + ok(!timestamp_format(buf, 20, &ts), "insufficient buffer size"); + ts.offset = 1; + ok( timestamp_format(buf, 26, &ts), "suffcient buffer size"); + ok(!timestamp_format(buf, 25, &ts), "insufficient buffer size"); + } + + done_testing(); +} + diff --git a/t/parse_malformed.c b/t/parse_malformed.c new file mode 100644 index 00000000..70b75119 --- /dev/null +++ b/t/parse_malformed.c @@ -0,0 +1,61 @@ +#include +#include "timestamp.h" +#include "tap.h" + +const struct test_t { + const char *str; +} tests[] = { + { "" }, + { "0000-01-01T00:00:00Z" }, /* Year < 0001 */ + { "0001-00-01T00:00:00Z" }, /* Invalid month */ + { "0001-13-01T00:00:00Z" }, /* Invalid month */ + { "0001-01-32T00:00:00Z" }, /* Invalid day */ + { "2013-02-29T00:00:00Z" }, /* Invalid day */ + { "1970-01-01T24:00:00Z" }, /* Invalid hour */ + { "1970-01-01T23:60:00Z" }, /* Invalid minute */ + { "1970-01-01T23:59:61Z" }, /* Invalid second */ + { "1970-01-01T23:59:59+01" }, /* Invalid zone offset */ + { "1970-01-01T23:59:59+01:" }, /* Invalid zone offset */ + { "1970-01-01T23:59:59+01:0" }, /* Invalid zone offset */ + { "1970-01-01T23:59:59+0100" }, /* Invalid zone offset */ + { "1970-01-01T23:59:59+24:00" }, /* Zone hour > 23 */ + { "1970-01-01T23:59:59+01:60" }, /* Zone minute > 59 */ + { "1970-01-01" }, /* Date only */ + { "1970-01-01T23:59:59" }, /* Zone offset is required */ + { "1970-01-01T23:59:59.123" }, /* Zone offset is required */ + { "1970-01-01X23:59:59Z" }, /* Invalid time designator */ + { "1970:01:01T23-59-59Z" }, /* Invalid separators */ + { "1970-01-01T00:00:00.Z" }, /* Fraction must have at-least one digit */ + { "X970-01-01T00:00:00Z" }, /* Non-digit in component */ + { "1X70-01-01T00:00:00Z" }, /* Non-digit in component */ + { "19X0-01-01T00:00:00Z" }, /* Non-digit in component */ + { "197X-01-01T00:00:00Z" }, /* Non-digit in component */ + { "1970-X1-01T00:00:00Z" }, /* Non-digit in component */ + { "1970-0X-01T00:00:00Z" }, /* Non-digit in component */ + { "1970-00-X1T00:00:00Z" }, /* Non-digit in component */ + { "1970-00-0XT00:00:00Z" }, /* Non-digit in component */ + { "1970-01-01T0X:00:00Z" }, /* Non-digit in component */ + { "1970-01-01T00:0X:00Z" }, /* Non-digit in component */ + { "1970-01-01T00:00:0XZ" }, /* Non-digit in component */ + { "1970-01-01T00:00:00.12345X7890Z" }, /* Non-digit in component */ + { "1970-01-01T00:00:00.1234567890Z" }, /* Fraction > 9 digits */ + { "1970-01-01T00:00:00,123456789Z" }, /* Decimal sign must be full stop */ + { "1970-01-01T00:00:00Z " }, /* Trailing space */ +}; + +int +main() { + int i, ntests; + + ntests = sizeof(tests) / sizeof(*tests); + for (i = 0; i < ntests; i++) { + const struct test_t t = tests[i]; + timestamp_t ts; + int ret; + + ret = timestamp_parse(t.str, strlen(t.str), &ts); + cmp_ok(ret, "==", 1, "timestamp_parse(\"%s\")", t.str); + } + done_testing(); +} + diff --git a/t/parse_wellformed.c b/t/parse_wellformed.c new file mode 100644 index 00000000..4c48db19 --- /dev/null +++ b/t/parse_wellformed.c @@ -0,0 +1,101 @@ +#include +#include "timestamp.h" +#include "tap.h" + +const struct test_t { + timestamp_t exp; + const char *str; +} tests[] = { + { { INT64_C(-62135596800), 0, 0 }, "0001-01-01T00:00:00Z" }, + { { INT64_C(-62135683140), 0, 1439 }, "0001-01-01T00:00:00+23:59" }, + { { INT64_C(-62135510460), 0, -1439 }, "0001-01-01T00:00:00-23:59" }, + { { INT64_C(253402300799), 0, 0 }, "9999-12-31T23:59:59Z" }, + { { INT64_C(253402214459), 0, 1439 }, "9999-12-31T23:59:59+23:59" }, + { { INT64_C(253402387139), 0, -1439 }, "9999-12-31T23:59:59-23:59" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00Z" }, + { { 1, 0, 0 }, "1970-01-01T00:00:01Z" }, + { { 10, 0, 0 }, "1970-01-01T00:00:10Z" }, + { { 60, 0, 0 }, "1970-01-01T00:01:00Z" }, + { { 600, 0, 0 }, "1970-01-01T00:10:00Z" }, + { { 3600, 0, 0 }, "1970-01-01T01:00:00Z" }, + { { 36000, 0, 0 }, "1970-01-01T10:00:00Z" }, + { { 68169600, 0, 0 }, "1972-02-29T00:00:00Z" }, + { { 0, 123456789, 0 }, "1970-01-01T00:00:00.123456789Z" }, + { { 0, 123456780, 0 }, "1970-01-01T00:00:00.12345678Z" }, + { { 0, 123456700, 0 }, "1970-01-01T00:00:00.1234567Z" }, + { { 0, 123456000, 0 }, "1970-01-01T00:00:00.123456Z" }, + { { 0, 123450000, 0 }, "1970-01-01T00:00:00.12345Z" }, + { { 0, 123400000, 0 }, "1970-01-01T00:00:00.1234Z" }, + { { 0, 123000000, 0 }, "1970-01-01T00:00:00.123Z" }, + { { 0, 120000000, 0 }, "1970-01-01T00:00:00.12Z" }, + { { 0, 100000000, 0 }, "1970-01-01T00:00:00.1Z" }, + { { 0, 10000000, 0 }, "1970-01-01T00:00:00.01Z" }, + { { 0, 1000000, 0 }, "1970-01-01T00:00:00.001Z" }, + { { 0, 100000, 0 }, "1970-01-01T00:00:00.0001Z" }, + { { 0, 10000, 0 }, "1970-01-01T00:00:00.00001Z" }, + { { 0, 1000, 0 }, "1970-01-01T00:00:00.000001Z" }, + { { 0, 100, 0 }, "1970-01-01T00:00:00.0000001Z" }, + { { 0, 10, 0 }, "1970-01-01T00:00:00.00000001Z" }, + { { 0, 1, 0 }, "1970-01-01T00:00:00.000000001Z" }, + { { 0, 9, 0 }, "1970-01-01T00:00:00.000000009Z" }, + { { 0, 90, 0 }, "1970-01-01T00:00:00.00000009Z" }, + { { 0, 900, 0 }, "1970-01-01T00:00:00.0000009Z" }, + { { 0, 9000, 0 }, "1970-01-01T00:00:00.000009Z" }, + { { 0, 90000, 0 }, "1970-01-01T00:00:00.00009Z" }, + { { 0, 900000, 0 }, "1970-01-01T00:00:00.0009Z" }, + { { 0, 9000000, 0 }, "1970-01-01T00:00:00.009Z" }, + { { 0, 90000000, 0 }, "1970-01-01T00:00:00.09Z" }, + { { 0, 900000000, 0 }, "1970-01-01T00:00:00.9Z" }, + { { 0, 990000000, 0 }, "1970-01-01T00:00:00.99Z" }, + { { 0, 999000000, 0 }, "1970-01-01T00:00:00.999Z" }, + { { 0, 999900000, 0 }, "1970-01-01T00:00:00.9999Z" }, + { { 0, 999990000, 0 }, "1970-01-01T00:00:00.99999Z" }, + { { 0, 999999000, 0 }, "1970-01-01T00:00:00.999999Z" }, + { { 0, 999999900, 0 }, "1970-01-01T00:00:00.9999999Z" }, + { { 0, 999999990, 0 }, "1970-01-01T00:00:00.99999999Z" }, + { { 0, 999999999, 0 }, "1970-01-01T00:00:00.999999999Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.0Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.00Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.000Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.0000Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.00000Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.000000Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.0000000Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.00000000Z" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00.000000000Z" }, + { { 0, 0, 1439 }, "1970-01-01T23:59:00+23:59" }, + { { 0, 0, 120 }, "1970-01-01T02:00:00+02:00" }, + { { 0, 0, 90 }, "1970-01-01T01:30:00+01:30" }, + { { 0, 0, 60 }, "1970-01-01T01:00:00+01:00" }, + { { 0, 0, 1 }, "1970-01-01T00:01:00+00:01" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00+00:00" }, + { { 0, 0, -1 }, "1969-12-31T23:59:00-00:01" }, + { { 0, 0, -60 }, "1969-12-31T23:00:00-01:00" }, + { { 0, 0, -90 }, "1969-12-31T22:30:00-01:30" }, + { { 0, 0, -120 }, "1969-12-31T22:00:00-02:00" }, + { { 0, 0, -1439 }, "1969-12-31T00:01:00-23:59" }, + { { 0, 0, 0 }, "1970-01-01T00:00:00z" }, + { { 0, 0, 0 }, "1970-01-01 00:00:00Z" }, + { { 0, 0, 0 }, "1970-01-01t00:00:00Z" }, + { { 0, 0, 0 }, "1970-01-01 00:00:00+00:00" }, +}; + +int +main() { + int i, ntests; + + ntests = sizeof(tests) / sizeof(*tests); + for (i = 0; i < ntests; i++) { + const struct test_t t = tests[i]; + timestamp_t ts; + int ret; + + ret = timestamp_parse(t.str, strlen(t.str), &ts); + cmp_ok(ret, "==", 0, "timestamp_parse(\"%s\")", t.str); + ret = timestamp_compare(&ts, &t.exp); + cmp_ok(ret, "==", 0, "timestamp_compare(\"%s\")", t.str); + cmp_ok(ts.offset, "==", t.exp.offset, "offset (%s)", t.str); + } + done_testing(); +} + diff --git a/t/tap.c b/t/tap.c new file mode 100644 index 00000000..57b80389 --- /dev/null +++ b/t/tap.c @@ -0,0 +1,325 @@ +/* +libtap - Write tests in C +Copyright (C) 2011 Jake Gelbman +This file is licensed under the GPL v3 +*/ + +#include +#include +#include +#include +#include "tap.h" + +static int expected_tests = NO_PLAN; +static int failed_tests; +static int current_test; +static char *todo_mesg; + +static char * +vstrdupf (const char *fmt, va_list args) { + char *str; + int size; + va_list args2; + va_copy(args2, args); + if (!fmt) + fmt = ""; + size = vsnprintf(NULL, 0, fmt, args2) + 2; + str = (char *)malloc(size); + vsprintf(str, fmt, args); + va_end(args2); + return str; +} + +void +cplan (int tests, const char *fmt, ...) { + expected_tests = tests; + if (tests == SKIP_ALL) { + char *why; + va_list args; + va_start(args, fmt); + why = vstrdupf(fmt, args); + va_end(args); + printf("1..0 "); + note("SKIP %s\n", why); + exit(0); + } + if (tests != NO_PLAN) { + printf("1..%d\n", tests); + } +} + +int +vok_at_loc (const char *file, int line, int test, const char *fmt, + va_list args) +{ + char *name = vstrdupf(fmt, args); + printf("%sok %d", test ? "" : "not ", ++current_test); + if (*name) + printf(" - %s", name); + if (todo_mesg) { + printf(" # TODO"); + if (*todo_mesg) + printf(" %s", todo_mesg); + } + printf("\n"); + if (!test) { + if (*name) + diag(" Failed%s test '%s'\n at %s line %d.", + todo_mesg ? " (TODO)" : "", name, file, line); + else + diag(" Failed%s test at %s line %d.", + todo_mesg ? " (TODO)" : "", file, line); + if (!todo_mesg) + failed_tests++; + } + free(name); + return test; +} + +int +ok_at_loc (const char *file, int line, int test, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vok_at_loc(file, line, test, fmt, args); + va_end(args); + return test; +} + +static int +mystrcmp (const char *a, const char *b) { + return a == b ? 0 : !a ? -1 : !b ? 1 : strcmp(a, b); +} + +#define eq(a, b) (!mystrcmp(a, b)) +#define ne(a, b) (mystrcmp(a, b)) + +int +is_at_loc (const char *file, int line, const char *got, const char *expected, + const char *fmt, ...) +{ + int test = eq(got, expected); + va_list args; + va_start(args, fmt); + vok_at_loc(file, line, test, fmt, args); + va_end(args); + if (!test) { + diag(" got: '%s'", got); + diag(" expected: '%s'", expected); + } + return test; +} + +int +isnt_at_loc (const char *file, int line, const char *got, const char *expected, + const char *fmt, ...) +{ + int test = ne(got, expected); + va_list args; + va_start(args, fmt); + vok_at_loc(file, line, test, fmt, args); + va_end(args); + if (!test) { + diag(" got: '%s'", got); + diag(" expected: anything else"); + } + return test; +} + +int +cmp_ok_at_loc (const char *file, int line, int a, const char *op, int b, + const char *fmt, ...) +{ + int test = eq(op, "||") ? a || b + : eq(op, "&&") ? a && b + : eq(op, "|") ? a | b + : eq(op, "^") ? a ^ b + : eq(op, "&") ? a & b + : eq(op, "==") ? a == b + : eq(op, "!=") ? a != b + : eq(op, "<") ? a < b + : eq(op, ">") ? a > b + : eq(op, "<=") ? a <= b + : eq(op, ">=") ? a >= b + : eq(op, "<<") ? a << b + : eq(op, ">>") ? a >> b + : eq(op, "+") ? a + b + : eq(op, "-") ? a - b + : eq(op, "*") ? a * b + : eq(op, "/") ? a / b + : eq(op, "%") ? a % b + : diag("unrecognized operator '%s'", op); + va_list args; + va_start(args, fmt); + vok_at_loc(file, line, test, fmt, args); + va_end(args); + if (!test) { + diag(" %d", a); + diag(" %s", op); + diag(" %d", b); + } + return test; +} + +static void +vdiag_to_fh (FILE *fh, const char *fmt, va_list args) { + char *mesg, *line; + int i; + if (!fmt) + return; + mesg = vstrdupf(fmt, args); + line = mesg; + for (i = 0; *line; i++) { + char c = mesg[i]; + if (!c || c == '\n') { + mesg[i] = '\0'; + fprintf(fh, "# %s\n", line); + if (!c) + break; + mesg[i] = c; + line = mesg + i + 1; + } + } + free(mesg); + return; +} + +int +diag (const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vdiag_to_fh(stderr, fmt, args); + va_end(args); + return 0; +} + +int +note (const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vdiag_to_fh(stdout, fmt, args); + va_end(args); + return 0; +} + +int +exit_status () { + int retval = 0; + if (expected_tests == NO_PLAN) { + printf("1..%d\n", current_test); + } + else if (current_test != expected_tests) { + diag("Looks like you planned %d test%s but ran %d.", + expected_tests, expected_tests > 1 ? "s" : "", current_test); + retval = 255; + } + if (failed_tests) { + diag("Looks like you failed %d test%s of %d run.", + failed_tests, failed_tests > 1 ? "s" : "", current_test); + if (expected_tests == NO_PLAN) + retval = failed_tests; + else + retval = expected_tests - current_test + failed_tests; + } + return retval; +} + +int +bail_out (int ignore, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + printf("Bail out! "); + vprintf(fmt, args); + printf("\n"); + va_end(args); + exit(255); + return 0; +} + +void +skippy (int n, const char *fmt, ...) { + char *why; + va_list args; + va_start(args, fmt); + why = vstrdupf(fmt, args); + va_end(args); + while (n --> 0) { + printf("ok %d ", ++current_test); + note("skip %s\n", why); + } + free(why); +} + +void +ctodo (int ignore, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + todo_mesg = vstrdupf(fmt, args); + va_end(args); +} + +void +cendtodo () { + free(todo_mesg); + todo_mesg = NULL; +} + +#ifndef _WIN32 +#include +#include +#include + +#if defined __APPLE__ || defined BSD +#define MAP_ANONYMOUS MAP_ANON +#endif + +/* Create a shared memory int to keep track of whether a piece of code executed +dies. to be used in the dies_ok and lives_ok macros */ +int +tap_test_died (int status) { + static int *test_died = NULL; + int prev; + if (!test_died) { + test_died = (int *)mmap(0, sizeof (int), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + *test_died = 0; + } + prev = *test_died; + *test_died = status; + return prev; +} + +int +like_at_loc (int for_match, const char *file, int line, const char *got, + const char *expected, const char *fmt, ...) +{ + int test; + regex_t re; + va_list args; + int err = regcomp(&re, expected, REG_EXTENDED); + if (err) { + char errbuf[256]; + regerror(err, &re, errbuf, sizeof errbuf); + fprintf(stderr, "Unable to compile regex '%s': %s at %s line %d\n", + expected, errbuf, file, line); + exit(255); + } + err = regexec(&re, got, 0, NULL, 0); + regfree(&re); + test = for_match ? !err : err; + va_start(args, fmt); + vok_at_loc(file, line, test, fmt, args); + va_end(args); + if (!test) { + if (for_match) { + diag(" '%s'", got); + diag(" doesn't match: '%s'", expected); + } + else { + diag(" '%s'", got); + diag(" matches: '%s'", expected); + } + } + return test; +} +#endif + diff --git a/t/tap.h b/t/tap.h new file mode 100644 index 00000000..89484f47 --- /dev/null +++ b/t/tap.h @@ -0,0 +1,114 @@ +/* +libtap - Write tests in C +Copyright (C) 2011 Jake Gelbman +This file is licensed under the GPL v3 +*/ + +#ifndef __TAP_H__ +#define __TAP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef va_copy +#ifdef __va_copy +#define va_copy __va_copy +#else +#define va_copy(d, s) ((d) = (s)) +#endif +#endif + +#include +#include +#include + +int vok_at_loc (const char *file, int line, int test, const char *fmt, + va_list args); +int ok_at_loc (const char *file, int line, int test, const char *fmt, + ...); +int is_at_loc (const char *file, int line, const char *got, + const char *expected, const char *fmt, ...); +int isnt_at_loc (const char *file, int line, const char *got, + const char *expected, const char *fmt, ...); +int cmp_ok_at_loc (const char *file, int line, int a, const char *op, + int b, const char *fmt, ...); +int bail_out (int ignore, const char *fmt, ...); +void cplan (int tests, const char *fmt, ...); +int diag (const char *fmt, ...); +int note (const char *fmt, ...); +int exit_status (void); +void skippy (int n, const char *fmt, ...); +void ctodo (int ignore, const char *fmt, ...); +void cendtodo (void); + +#define NO_PLAN -1 +#define SKIP_ALL -2 +#define ok(...) ok_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL) +#define is(...) is_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL) +#define isnt(...) isnt_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL) +#define cmp_ok(...) cmp_ok_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL) +#define plan(...) cplan(__VA_ARGS__, NULL) +#define done_testing() return exit_status() +#define BAIL_OUT(...) bail_out(0, "" __VA_ARGS__, NULL) +#define pass(...) ok(1, "" __VA_ARGS__) +#define fail(...) ok(0, "" __VA_ARGS__) + +#define skip(test, ...) do {if (test) {skippy(__VA_ARGS__, NULL); break;} +#define endskip } while (0) + +#define todo(...) ctodo(0, "" __VA_ARGS__, NULL) +#define endtodo cendtodo() + +#define dies_ok(...) dies_ok_common(1, __VA_ARGS__) +#define lives_ok(...) dies_ok_common(0, __VA_ARGS__) + +#ifdef _WIN32 +#define like(...) skippy(1, "like is not implemented on MSWin32") +#define unlike like +#define dies_ok_common(...) \ + skippy(1, "Death detection is not supported on MSWin32") +#else +#define like(...) like_at_loc(1, __FILE__, __LINE__, __VA_ARGS__, NULL) +#define unlike(...) like_at_loc(0, __FILE__, __LINE__, __VA_ARGS__, NULL) +int like_at_loc (int for_match, const char *file, int line, + const char *got, const char *expected, + const char *fmt, ...); +#include +#include +#include +int tap_test_died (int status); +#define dies_ok_common(for_death, code, ...) \ + do { \ + int cpid; \ + int it_died; \ + tap_test_died(1); \ + cpid = fork(); \ + switch (cpid) { \ + case -1: \ + perror("fork error"); \ + exit(1); \ + case 0: \ + close(1); \ + close(2); \ + code \ + tap_test_died(0); \ + exit(0); \ + } \ + if (waitpid(cpid, NULL, 0) < 0) { \ + perror("waitpid error"); \ + exit(1); \ + } \ + it_died = tap_test_died(0); \ + if (!it_died) \ + {code} \ + ok(for_death ? it_died : !it_died, "" __VA_ARGS__); \ + } while (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/t/tm.c b/t/tm.c new file mode 100644 index 00000000..89f317ba --- /dev/null +++ b/t/tm.c @@ -0,0 +1,63 @@ +#include +#include "timestamp.h" +#include "tap.h" + +int +main() { + timestamp_t ts; + struct tm tm; + + { /* 0001-01-01T12:30:45Z */ + ts.sec = INT64_C(-62135551755); + ts.nsec = 0; + ts.offset = 0; + + memset(&tm, 0, sizeof(tm)); + ok(timestamp_to_tm_utc(&ts, &tm) != NULL); + cmp_ok(tm.tm_year, "==", -1899, "tm_year"); + cmp_ok(tm.tm_mon, "==", 0, "tm_mon"); + cmp_ok(tm.tm_mday, "==", 1, "tm_mday"); + cmp_ok(tm.tm_yday, "==", 0, "tm_yday"); + cmp_ok(tm.tm_wday, "==", 1, "tm_wday"); + cmp_ok(tm.tm_hour, "==", 12, "tm_hour"); + cmp_ok(tm.tm_min, "==", 30, "tm_min"); + cmp_ok(tm.tm_sec, "==", 45, "tm_sec"); + } + + { /* 0001-01-01T12:30:45+02:00 */ + ts.sec = INT64_C(-62135558955); + ts.nsec = 0; + ts.offset = 120; + + memset(&tm, 0, sizeof(tm)); + ok(timestamp_to_tm_local(&ts, &tm) != NULL); + cmp_ok(tm.tm_year, "==", -1899, "tm_year"); + cmp_ok(tm.tm_mon, "==", 0, "tm_mon"); + cmp_ok(tm.tm_mday, "==", 1, "tm_mday"); + cmp_ok(tm.tm_yday, "==", 0, "tm_yday"); + cmp_ok(tm.tm_wday, "==", 1, "tm_wday"); + cmp_ok(tm.tm_hour, "==", 12, "tm_hour"); + cmp_ok(tm.tm_min, "==", 30, "tm_min"); + cmp_ok(tm.tm_sec, "==", 45, "tm_sec"); + } + + { /* 1970-12-31T23:59:59Z */ + ts.sec = INT64_C(31535999); + ts.nsec = 0; + ts.offset = 0; + + memset(&tm, 0, sizeof(tm)); + ok(timestamp_to_tm_utc(&ts, &tm) != NULL); + cmp_ok(tm.tm_year, "==", 70, "tm_year"); + cmp_ok(tm.tm_mon, "==", 11, "tm_mon"); + cmp_ok(tm.tm_mday, "==", 31, "tm_mday"); + cmp_ok(tm.tm_yday, "==", 364, "tm_yday"); + cmp_ok(tm.tm_wday, "==", 4, "tm_wday"); + cmp_ok(tm.tm_hour, "==", 23, "tm_hour"); + cmp_ok(tm.tm_min, "==", 59, "tm_min"); + cmp_ok(tm.tm_sec, "==", 59, "tm_sec"); + } + + done_testing(); +} + diff --git a/t/valid.c b/t/valid.c new file mode 100644 index 00000000..2aaae0f9 --- /dev/null +++ b/t/valid.c @@ -0,0 +1,32 @@ +#include +#include "timestamp.h" +#include "tap.h" + +int +main() { + timestamp_t ts; + + ts.sec = 0; + ts.offset = 0; + ts.nsec = -1; + ok(!timestamp_valid(&ts), "nsec out of range"); + + ts.nsec = 1000000000; + ok(!timestamp_valid(&ts), "nsec out of range"); + + ts.nsec = 0; + ts.offset = -23 * 60 - 60; + ok(!timestamp_valid(&ts), "offset out of range"); + + ts.offset = +23 * 60 + 60; + ok(!timestamp_valid(&ts), "offset out of range"); + + ts.offset = 0; + ts.sec = INT64_C(-62135596801); /* 0000-12-31T23:59:59Z */ + ok(!timestamp_valid(&ts), "sec out of range"); + ts.sec = INT64_C(253402387140); /* 10000-01-01T23:59:00Z */ + ok(!timestamp_valid(&ts), "sec out of range"); + + done_testing(); +} + diff --git a/timestamp.h b/timestamp.h new file mode 100644 index 00000000..b52277a4 --- /dev/null +++ b/timestamp.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 Christian Hansen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __TIMESTAMP_H__ +#define __TIMESTAMP_H__ +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int64_t sec; /* Number of seconds since the epoch of 1970-01-01T00:00:00Z */ + int32_t nsec; /* Nanoseconds [0, 999999999] */ + int16_t offset; /* Offset from UTC in minutes [-1439, 1439] */ +} timestamp_t; + +int timestamp_parse (const char *str, size_t len, timestamp_t *tsp); +size_t timestamp_format (char *dst, size_t len, const timestamp_t *tsp); +size_t timestamp_format_precision (char *dst, size_t len, const timestamp_t *tsp, int precision); +int timestamp_compare (const timestamp_t *tsp1, const timestamp_t *tsp2); +bool timestamp_valid (const timestamp_t *tsp); +struct tm * timestamp_to_tm_utc (const timestamp_t *tsp, struct tm *tmp); +struct tm * timestamp_to_tm_local (const timestamp_t *tsp, struct tm *tmp); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/timestamp_compare.c b/timestamp_compare.c new file mode 100644 index 00000000..89c8b722 --- /dev/null +++ b/timestamp_compare.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 Christian Hansen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "timestamp.h" + +int +timestamp_compare(const timestamp_t *t1, const timestamp_t *t2) { + if (t1->sec < t2->sec) + return -1; + if (t1->sec > t2->sec) + return 1; + if (t1->nsec < t2->nsec) + return -1; + if (t1->nsec > t2->nsec) + return 1; + return 0; +} + diff --git a/timestamp_format.c b/timestamp_format.c new file mode 100644 index 00000000..570663c0 --- /dev/null +++ b/timestamp_format.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014 Christian Hansen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "timestamp.h" + +static const uint16_t DayOffset[13] = { + 0, 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275 +}; + +/* Rata Die algorithm by Peter Baum */ + +static void +rdn_to_ymd(uint32_t rdn, uint16_t *yp, uint16_t *mp, uint16_t *dp) { + uint32_t Z, H, A, B; + uint16_t y, m, d; + + Z = rdn + 306; + H = 100 * Z - 25; + A = H / 3652425; + B = A - (A >> 2); + y = (100 * B + H) / 36525; + d = B + Z - (1461 * y >> 2); + m = (535 * d + 48950) >> 14; + if (m > 12) + y++, m -= 12; + + *yp = y; + *mp = m; + *dp = d - DayOffset[m]; +} + +#define EPOCH INT64_C(62135683200) /* 1970-01-01T00:00:00 */ + +static const uint32_t Pow10[10] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 +}; + +static size_t +timestamp_format_internal(char *dst, size_t len, const timestamp_t *tsp, const int precision) { + unsigned char *p; + uint64_t sec; + uint32_t rdn, v; + uint16_t y, m, d; + size_t dlen; + + dlen = sizeof("YYYY-MM-DDThh:mm:ssZ") - 1; + if (tsp->offset) + dlen += 5; /* hh:mm */ + + if (precision) + dlen += 1 + precision; + + if (dlen >= len) + return 0; + + sec = tsp->sec + tsp->offset * 60 + EPOCH; + rdn = sec / 86400; + + rdn_to_ymd(rdn, &y, &m, &d); + + /* + * 1 + * 0123456789012345678 + * YYYY-MM-DDThh:mm:ss + */ + p = (unsigned char *)dst; + v = sec % 86400; + p[18] = '0' + (v % 10); v /= 10; + p[17] = '0' + (v % 6); v /= 6; + p[16] = ':'; + p[15] = '0' + (v % 10); v /= 10; + p[14] = '0' + (v % 6); v /= 6; + p[13] = ':'; + p[12] = '0' + (v % 10); v /= 10; + p[11] = '0' + (v % 10); + p[10] = 'T'; + p[ 9] = '0' + (d % 10); d /= 10; + p[ 8] = '0' + (d % 10); + p[ 7] = '-'; + p[ 6] = '0' + (m % 10); m /= 10; + p[ 5] = '0' + (m % 10); + p[ 4] = '-'; + p[ 3] = '0' + (y % 10); y /= 10; + p[ 2] = '0' + (y % 10); y /= 10; + p[ 1] = '0' + (y % 10); y /= 10; + p[ 0] = '0' + (y % 10); + p += 19; + + if (precision) { + v = tsp->nsec / Pow10[9 - precision]; + switch (precision) { + case 9: p[9] = '0' + (v % 10); v /= 10; + case 8: p[8] = '0' + (v % 10); v /= 10; + case 7: p[7] = '0' + (v % 10); v /= 10; + case 6: p[6] = '0' + (v % 10); v /= 10; + case 5: p[5] = '0' + (v % 10); v /= 10; + case 4: p[4] = '0' + (v % 10); v /= 10; + case 3: p[3] = '0' + (v % 10); v /= 10; + case 2: p[2] = '0' + (v % 10); v /= 10; + case 1: p[1] = '0' + (v % 10); + } + p[0] = '.'; + p += 1 + precision; + } + + if (!tsp->offset) + *p++ = 'Z'; + else { + if (tsp->offset < 0) + p[0] = '-', v = -tsp->offset; + else + p[0] = '+', v = tsp->offset; + + p[5] = '0' + (v % 10); v /= 10; + p[4] = '0' + (v % 6); v /= 6; + p[3] = ':'; + p[2] = '0' + (v % 10); v /= 10; + p[1] = '0' + (v % 10); + p += 6; + } + *p = 0; + return dlen; +} + +/* + * 1 2 3 + * 12345678901234567890123456789012345 (+ null-terminator) + * YYYY-MM-DDThh:mm:ssZ + * YYYY-MM-DDThh:mm:ss±hh:mm + * YYYY-MM-DDThh:mm:ss.123Z + * YYYY-MM-DDThh:mm:ss.123±hh:mm + * YYYY-MM-DDThh:mm:ss.123456Z + * YYYY-MM-DDThh:mm:ss.123456±hh:mm + * YYYY-MM-DDThh:mm:ss.123456789Z + * YYYY-MM-DDThh:mm:ss.123456789±hh:mm + */ + +size_t +timestamp_format(char *dst, size_t len, const timestamp_t *tsp) { + uint32_t f; + int precision; + + if (!timestamp_valid(tsp)) + return 0; + + f = tsp->nsec; + if (!f) + precision = 0; + else { + if ((f % 1000000) == 0) precision = 3; + else if ((f % 1000) == 0) precision = 6; + else precision = 9; + } + return timestamp_format_internal(dst, len, tsp, precision); +} + +size_t +timestamp_format_precision(char *dst, size_t len, const timestamp_t *tsp, int precision) { + if (!timestamp_valid(tsp) || precision < 0 || precision > 9) + return 0; + return timestamp_format_internal(dst, len, tsp, precision); +} + diff --git a/timestamp_parse.c b/timestamp_parse.c new file mode 100644 index 00000000..37251b38 --- /dev/null +++ b/timestamp_parse.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2014 Christian Hansen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "timestamp.h" + +static int +leap_year(uint16_t y) { + return ((y & 3) == 0 && (y % 100 != 0 || y % 400 == 0)); +} + +static unsigned char +month_days(uint16_t y, uint16_t m) { + static const unsigned char days[2][13] = { + {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + }; + return days[m == 2 && leap_year(y)][m]; +} + +static int +parse_2d(const unsigned char * const p, size_t i, uint16_t *vp) { + unsigned char d0, d1; + if (((d0 = p[i + 0] - '0') > 9) || + ((d1 = p[i + 1] - '0') > 9)) + return 1; + *vp = d0 * 10 + d1; + return 0; +} + +static int +parse_4d(const unsigned char * const p, size_t i, uint16_t *vp) { + unsigned char d0, d1, d2, d3; + if (((d0 = p[i + 0] - '0') > 9) || + ((d1 = p[i + 1] - '0') > 9) || + ((d2 = p[i + 2] - '0') > 9) || + ((d3 = p[i + 3] - '0') > 9)) + return 1; + *vp = d0 * 1000 + d1 * 100 + d2 * 10 + d3; + return 0; +} + +static const uint32_t Pow10[10] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 +}; + +static const uint16_t DayOffset[13] = { + 0, 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275 +}; + +int +timestamp_parse(const char *str, size_t len, timestamp_t *tsp) { + const unsigned char *cur, *end; + unsigned char ch; + uint16_t year, month, day, hour, min, sec; + uint32_t rdn, sod, nsec; + int16_t offset; + + /* + * 1 + * 01234567890123456789 + * 2013-12-31T23:59:59Z + */ + cur = (const unsigned char *)str; + if (len < 20 || + cur[4] != '-' || cur[7] != '-' || + cur[13] != ':' || cur[16] != ':') + return 1; + + ch = cur[10]; + if (!(ch == 'T' || ch == ' ' || ch == 't')) + return 1; + + if (parse_4d(cur, 0, &year) || year < 1 || + parse_2d(cur, 5, &month) || month < 1 || month > 12 || + parse_2d(cur, 8, &day) || day < 1 || day > 31 || + parse_2d(cur, 11, &hour) || hour > 23 || + parse_2d(cur, 14, &min) || min > 59 || + parse_2d(cur, 17, &sec) || sec > 59) + return 1; + + if (day > 28 && day > month_days(year, month)) + return 1; + + if (month < 3) + year--; + + rdn = (1461 * year)/4 - year/100 + year/400 + DayOffset[month] + day - 306; + sod = hour * 3600 + min * 60 + sec; + end = cur + len; + cur = cur + 19; + offset = nsec = 0; + + ch = *cur++; + if (ch == '.') { + const unsigned char *start; + size_t ndigits; + + start = cur; + for (; cur < end; cur++) { + const unsigned char digit = *cur - '0'; + if (digit > 9) + break; + nsec = nsec * 10 + digit; + } + + ndigits = cur - start; + if (ndigits < 1 || ndigits > 9) + return 1; + + nsec *= Pow10[9 - ndigits]; + + if (cur == end) + return 1; + + ch = *cur++; + } + + if (!(ch == 'Z' || ch == 'z')) { + /* + * 01234 + * ±00:00 + */ + if (cur + 5 < end || !(ch == '+' || ch == '-') || cur[2] != ':') + return 1; + + if (parse_2d(cur, 0, &hour) || hour > 23 || + parse_2d(cur, 3, &min) || min > 59) + return 1; + + offset = hour * 60 + min; + if (ch == '-') + offset *= -1; + + cur += 5; + } + + if (cur != end) + return 1; + + tsp->sec = ((int64_t)rdn - 719163) * 86400 + sod - offset * 60; + tsp->nsec = nsec; + tsp->offset = offset; + return 0; +} + diff --git a/timestamp_tm.c b/timestamp_tm.c new file mode 100644 index 00000000..3046b730 --- /dev/null +++ b/timestamp_tm.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014 Christian Hansen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "timestamp.h" + +static const uint16_t DayOffset[13] = { + 0, 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275 +}; + +/* Rata Die algorithm by Peter Baum */ + +static void +rdn_to_struct_tm(uint32_t rdn, struct tm *tmp) { + uint32_t Z, H, A, B; + uint16_t C, y, m, d; + + Z = rdn + 306; + H = 100 * Z - 25; + A = H / 3652425; + B = A - (A >> 2); + y = (100 * B + H) / 36525; + C = B + Z - (1461 * y >> 2); + m = (535 * C + 48950) >> 14; + if (m > 12) + d = C - 306, y++, m -= 12; + else + d = C + 59 + ((y & 3) == 0 && (y % 100 != 0 || y % 400 == 0)); + + tmp->tm_mday = C - DayOffset[m]; /* Day of month [1,31] */ + tmp->tm_mon = m - 1; /* Month of year [0,11] */ + tmp->tm_year = y - 1900; /* Years since 1900 */ + tmp->tm_wday = rdn % 7; /* Day of week [0,6] (Sunday =0) */ + tmp->tm_yday = d - 1; /* Day of year [0,365] */ +} + +#define RDN_OFFSET INT64_C(62135683200) /* 1970-01-01T00:00:00 */ + +static struct tm * +timestamp_to_tm(const timestamp_t *tsp, struct tm *tmp, const bool local) { + uint64_t sec; + uint32_t rdn, sod; + + if (!timestamp_valid(tsp)) + return NULL; + + sec = tsp->sec + RDN_OFFSET; + if (local) + sec += tsp->offset * 60; + rdn = sec / 86400; + sod = sec % 86400; + + rdn_to_struct_tm(rdn, tmp); + tmp->tm_sec = sod % 60; sod /= 60; + tmp->tm_min = sod % 60; sod /= 60; + tmp->tm_hour = sod; + return tmp; +} + +struct tm * +timestamp_to_tm_local(const timestamp_t *tsp, struct tm *tmp) { + return timestamp_to_tm(tsp, tmp, true); +} + +struct tm * +timestamp_to_tm_utc(const timestamp_t *tsp, struct tm *tmp) { + return timestamp_to_tm(tsp, tmp, false); +} + diff --git a/timestamp_valid.c b/timestamp_valid.c new file mode 100644 index 00000000..44c2648c --- /dev/null +++ b/timestamp_valid.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 Christian Hansen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "timestamp.h" + +#define MIN_SEC INT64_C(-62135596800) /* 0001-01-01T00:00:00 */ +#define MAX_SEC INT64_C(253402300799) /* 9999-12-31T23:59:59 */ + +bool +timestamp_valid(const timestamp_t *tsp) { + const int64_t sec = tsp->sec + tsp->offset * 60; + if (sec < MIN_SEC || sec > MAX_SEC || + tsp->nsec < 0 || tsp->nsec > 999999999 || + tsp->offset < -1439 || tsp->offset > 1439) + return false; + return true; +} + From 0319ade20016f8c579b2190a581aaec239df7245 Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Fri, 20 Jul 2018 19:53:03 +0200 Subject: [PATCH 3/9] Squashed 'libs/ujson4c/' content from commit 65d3e35 git-subtree-dir: libs/ujson4c git-subtree-split: 65d3e35864ee501a2b21fe5af8a45667d36a42be --- 3rdparty/ultrajson.h | 310 ++++ 3rdparty/ultrajsondec.c | 891 +++++++++++ LICENSE.txt | 31 + README.rst | 43 + src/ujdecode.c | 842 ++++++++++ src/ujdecode.h | 261 +++ tests/benchmark.c | 225 +++ tests/sample.json | 3315 +++++++++++++++++++++++++++++++++++++++ tests/tests.c | 102 ++ 9 files changed, 6020 insertions(+) create mode 100644 3rdparty/ultrajson.h create mode 100644 3rdparty/ultrajsondec.c create mode 100644 LICENSE.txt create mode 100644 README.rst create mode 100644 src/ujdecode.c create mode 100644 src/ujdecode.h create mode 100644 tests/benchmark.c create mode 100644 tests/sample.json create mode 100644 tests/tests.c diff --git a/3rdparty/ultrajson.h b/3rdparty/ultrajson.h new file mode 100644 index 00000000..787cd4c2 --- /dev/null +++ b/3rdparty/ultrajson.h @@ -0,0 +1,310 @@ +/* +Copyright (c) 2011-2013, ESN Social Software AB and Jonas Tarnstrom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the ESN Social Software AB nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) +http://code.google.com/p/stringencoders/ +Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved. + +Numeric decoder derived from from TCL library +http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms + * Copyright (c) 1988-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. +*/ + +/* +Ultra fast JSON encoder and decoder +Developed by Jonas Tarnstrom (jonas@esn.me). + +Encoder notes: +------------------ + +:: Cyclic references :: +Cyclic referenced objects are not detected. +Set JSONObjectEncoder.recursionMax to suitable value or make sure input object +tree doesn't have cyclic references. + +*/ + +#ifndef __ULTRAJSON_H__ +#define __ULTRAJSON_H__ + +#include +#include + +// Don't output any extra whitespaces when encoding +#define JSON_NO_EXTRA_WHITESPACE + +// Max decimals to encode double floating point numbers with +#ifndef JSON_DOUBLE_MAX_DECIMALS +#define JSON_DOUBLE_MAX_DECIMALS 15 +#endif + +// Max recursion depth, default for encoder +#ifndef JSON_MAX_RECURSION_DEPTH +#define JSON_MAX_RECURSION_DEPTH 1024 +#endif + +// Max recursion depth, default for decoder +#ifndef JSON_MAX_OBJECT_DEPTH +#define JSON_MAX_OBJECT_DEPTH 1024 +#endif + +/* +Dictates and limits how much stack space for buffers UltraJSON will use before resorting to provided heap functions */ +#ifndef JSON_MAX_STACK_BUFFER_SIZE +#define JSON_MAX_STACK_BUFFER_SIZE 131072 +#endif + +#ifdef _WIN32 + +typedef __int64 JSINT64; +typedef unsigned __int64 JSUINT64; + +typedef __int32 JSINT32; +typedef unsigned __int32 JSUINT32; +typedef unsigned __int8 JSUINT8; +typedef unsigned __int16 JSUTF16; +typedef unsigned __int32 JSUTF32; +typedef __int64 JSLONG; + +#define EXPORTFUNCTION __declspec(dllexport) + +#define FASTCALL_MSVC __fastcall +#define FASTCALL_ATTR +#define INLINE_PREFIX __inline + +#else + +#include +typedef int64_t JSINT64; +typedef uint64_t JSUINT64; + +typedef int32_t JSINT32; +typedef uint32_t JSUINT32; + +#define FASTCALL_MSVC + +#if !defined __x86_64__ +#define FASTCALL_ATTR __attribute__((fastcall)) +#else +#define FASTCALL_ATTR +#endif + +#define INLINE_PREFIX inline + +typedef uint8_t JSUINT8; +typedef uint16_t JSUTF16; +typedef uint32_t JSUTF32; + +typedef int64_t JSLONG; + +#define EXPORTFUNCTION +#endif + +#if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#else + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define __BIG_ENDIAN__ +#endif + +#endif + +#endif + +#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +#error "Endianess not supported" +#endif + +enum JSTYPES +{ + JT_NULL, // NULL + JT_TRUE, //boolean true + JT_FALSE, //boolean false + JT_INT, //(JSINT32 (signed 32-bit)) + JT_LONG, //(JSINT64 (signed 64-bit)) + JT_DOUBLE, //(double) + JT_UTF8, //(char 8-bit) + JT_ARRAY, // Array structure + JT_OBJECT, // Key/Value structure + JT_INVALID, // Internal, do not return nor expect +}; + +typedef void * JSOBJ; +typedef void * JSITER; + +typedef struct __JSONTypeContext +{ + int type; + void *prv; +} JSONTypeContext; + +/* +Function pointer declarations, suitable for implementing UltraJSON */ +typedef void (*JSPFN_ITERBEGIN)(JSOBJ obj, JSONTypeContext *tc); +typedef int (*JSPFN_ITERNEXT)(JSOBJ obj, JSONTypeContext *tc); +typedef void (*JSPFN_ITEREND)(JSOBJ obj, JSONTypeContext *tc); +typedef JSOBJ (*JSPFN_ITERGETVALUE)(JSOBJ obj, JSONTypeContext *tc); +typedef char *(*JSPFN_ITERGETNAME)(JSOBJ obj, JSONTypeContext *tc, size_t *outLen); +typedef void *(*JSPFN_MALLOC)(size_t size); +typedef void (*JSPFN_FREE)(void *pptr); +typedef void *(*JSPFN_REALLOC)(void *base, size_t size); + +typedef struct __JSONObjectEncoder +{ + void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc); + void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc); + const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen); + JSINT64 (*getLongValue)(JSOBJ obj, JSONTypeContext *tc); + JSINT32 (*getIntValue)(JSOBJ obj, JSONTypeContext *tc); + double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc); + + /* + Begin iteration of an iteratable object (JS_ARRAY or JS_OBJECT) + Implementor should setup iteration state in ti->prv + */ + JSPFN_ITERBEGIN iterBegin; + + /* + Retrieve next object in an iteration. Should return 0 to indicate iteration has reached end or 1 if there are more items. + Implementor is responsible for keeping state of the iteration. Use ti->prv fields for this + */ + JSPFN_ITERNEXT iterNext; + + /* + Ends the iteration of an iteratable object. + Any iteration state stored in ti->prv can be freed here + */ + JSPFN_ITEREND iterEnd; + + /* + Returns a reference to the value object of an iterator + The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object + */ + JSPFN_ITERGETVALUE iterGetValue; + + /* + Return name of iterator. + The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object + */ + JSPFN_ITERGETNAME iterGetName; + + /* + Release a value as indicated by setting ti->release = 1 in the previous getValue call. + The ti->prv array should contain the necessary context to release the value + */ + void (*releaseObject)(JSOBJ obj); + + /* Library functions + Set to NULL to use STDLIB malloc,realloc,free */ + JSPFN_MALLOC malloc; + JSPFN_REALLOC realloc; + JSPFN_FREE free; + + /* + Configuration for max recursion, set to 0 to use default (see JSON_MAX_RECURSION_DEPTH)*/ + int recursionMax; + + /* + Configuration for max decimals of double floating poiunt numbers to encode (0-9) */ + int doublePrecision; + + /* + If true output will be ASCII with all characters above 127 encoded as \uXXXX. If false output will be UTF-8 or what ever charset strings are brought as */ + int forceASCII; + + /* + If true, '<', '>', and '&' characters will be encoded as \u003c, \u003e, and \u0026, respectively. If false, no special encoding will be used. */ + int encodeHTMLChars; + + /* + Set to an error message if error occured */ + const char *errorMsg; + JSOBJ errorObj; + + /* Buffer stuff */ + char *start; + char *offset; + char *end; + int heap; + int level; + +} JSONObjectEncoder; + + +/* +Encode an object structure into JSON. + +Arguments: +obj - An anonymous type representing the object +enc - Function definitions for querying JSOBJ type +buffer - Preallocated buffer to store result in. If NULL function allocates own buffer +cbBuffer - Length of buffer (ignored if buffer is NULL) + +Returns: +Encoded JSON object as a null terminated char string. + +NOTE: +If the supplied buffer wasn't enough to hold the result the function will allocate a new buffer. +Life cycle of the provided buffer must still be handled by caller. + +If the return value doesn't equal the specified buffer caller must release the memory using +JSONObjectEncoder.free or free() as specified when calling this function. +*/ +EXPORTFUNCTION char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *buffer, size_t cbBuffer); + + + +typedef struct __JSONObjectDecoder +{ + JSOBJ (*newString)(void *prv, wchar_t *start, wchar_t *end); + void (*objectAddKey)(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value); + void (*arrayAddItem)(void *prv, JSOBJ obj, JSOBJ value); + JSOBJ (*newTrue)(void *prv); + JSOBJ (*newFalse)(void *prv); + JSOBJ (*newNull)(void *prv); + JSOBJ (*newObject)(void *prv); + JSOBJ (*newArray)(void *prv); + JSOBJ (*newInt)(void *prv, JSINT32 value); + JSOBJ (*newLong)(void *prv, JSINT64 value); + JSOBJ (*newDouble)(void *prv, double value); + void (*releaseObject)(void *prv, JSOBJ obj); + JSPFN_MALLOC malloc; + JSPFN_FREE free; + JSPFN_REALLOC realloc; + char *errorStr; + char *errorOffset; + int preciseFloat; + void *prv; +} JSONObjectDecoder; + +EXPORTFUNCTION JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer); + +#endif diff --git a/3rdparty/ultrajsondec.c b/3rdparty/ultrajsondec.c new file mode 100644 index 00000000..2ede7539 --- /dev/null +++ b/3rdparty/ultrajsondec.c @@ -0,0 +1,891 @@ +/* +Copyright (c) 2011-2013, ESN Social Software AB and Jonas Tarnstrom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of the ESN Social Software AB nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) +http://code.google.com/p/stringencoders/ +Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved. + +Numeric decoder derived from from TCL library +http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms +* Copyright (c) 1988-1993 The Regents of the University of California. +* Copyright (c) 1994 Sun Microsystems, Inc. +*/ + +#include "ultrajson.h" +#include +#include +#include +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif + +struct DecoderState +{ + char *start; + char *end; + wchar_t *escStart; + wchar_t *escEnd; + int escHeap; + int lastType; + JSUINT32 objDepth; + void *prv; + JSONObjectDecoder *dec; +}; + +JSOBJ FASTCALL_MSVC decode_any( struct DecoderState *ds) FASTCALL_ATTR; +typedef JSOBJ (*PFN_DECODER)( struct DecoderState *ds); + +static JSOBJ SetError( struct DecoderState *ds, int offset, const char *message) +{ + ds->dec->errorOffset = ds->start + offset; + ds->dec->errorStr = (char *) message; + return NULL; +} + +double createDouble(double intNeg, double intValue, double frcValue, int frcDecimalCount) +{ + static const double g_pow10[] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001, 0.000000000001, 0.0000000000001, 0.00000000000001, 0.000000000000001}; + return (intValue + (frcValue * g_pow10[frcDecimalCount])) * intNeg; +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodePreciseFloat(struct DecoderState *ds) +{ + char *end; + double value; + errno = 0; + + value = strtod(ds->start, &end); + + if (errno == ERANGE) + { + return SetError(ds, -1, "Range error when decoding numeric as double"); + } + + ds->start = end; + return ds->dec->newDouble(ds->prv, value); +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_numeric (struct DecoderState *ds) +{ + int intNeg = 1; + int mantSize = 0; + JSUINT64 intValue; + int chr; + int decimalCount = 0; + double frcValue = 0.0; + double expNeg; + double expValue; + char *offset = ds->start; + + JSUINT64 overflowLimit = LLONG_MAX; + + if (*(offset) == '-') + { + offset ++; + intNeg = -1; + overflowLimit = LLONG_MIN; + } + + // Scan integer part + intValue = 0; + + while (1) + { + chr = (int) (unsigned char) *(offset); + + switch (chr) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + //FIXME: Check for arithemtic overflow here + //PERF: Don't do 64-bit arithmetic here unless we know we have to + intValue = intValue * 10ULL + (JSLONG) (chr - 48); + + if (intValue > overflowLimit) + { + return SetError(ds, -1, overflowLimit == LLONG_MAX ? "Value is too big" : "Value is too small"); + } + + offset ++; + mantSize ++; + break; + } + case '.': + { + offset ++; + goto DECODE_FRACTION; + break; + } + case 'e': + case 'E': + { + offset ++; + goto DECODE_EXPONENT; + break; + } + + default: + { + goto BREAK_INT_LOOP; + break; + } + } + } + +BREAK_INT_LOOP: + + ds->lastType = JT_INT; + ds->start = offset; + + if ((intValue >> 31)) + { + return ds->dec->newLong(ds->prv, (JSINT64) (intValue * (JSINT64) intNeg)); + } + else + { + return ds->dec->newInt(ds->prv, (JSINT32) (intValue * intNeg)); + } + +DECODE_FRACTION: + + if (ds->dec->preciseFloat) + { + return decodePreciseFloat(ds); + } + + // Scan fraction part + frcValue = 0.0; + for (;;) + { + chr = (int) (unsigned char) *(offset); + + switch (chr) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + if (decimalCount < JSON_DOUBLE_MAX_DECIMALS) + { + frcValue = frcValue * 10.0 + (double) (chr - 48); + decimalCount ++; + } + offset ++; + break; + } + case 'e': + case 'E': + { + offset ++; + goto DECODE_EXPONENT; + break; + } + default: + { + goto BREAK_FRC_LOOP; + } + } + } + +BREAK_FRC_LOOP: + //FIXME: Check for arithemtic overflow here + ds->lastType = JT_DOUBLE; + ds->start = offset; + return ds->dec->newDouble (ds->prv, createDouble( (double) intNeg, (double) intValue, frcValue, decimalCount)); + +DECODE_EXPONENT: + if (ds->dec->preciseFloat) + { + return decodePreciseFloat(ds); + } + + expNeg = 1.0; + + if (*(offset) == '-') + { + expNeg = -1.0; + offset ++; + } + else + if (*(offset) == '+') + { + expNeg = +1.0; + offset ++; + } + + expValue = 0.0; + + for (;;) + { + chr = (int) (unsigned char) *(offset); + + switch (chr) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + expValue = expValue * 10.0 + (double) (chr - 48); + offset ++; + break; + } + default: + { + goto BREAK_EXP_LOOP; + } + } + } + +BREAK_EXP_LOOP: + //FIXME: Check for arithemtic overflow here + ds->lastType = JT_DOUBLE; + ds->start = offset; + return ds->dec->newDouble (ds->prv, createDouble( (double) intNeg, (double) intValue , frcValue, decimalCount) * pow(10.0, expValue * expNeg)); +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_true ( struct DecoderState *ds) +{ + char *offset = ds->start; + offset ++; + + if (*(offset++) != 'r') + goto SETERROR; + if (*(offset++) != 'u') + goto SETERROR; + if (*(offset++) != 'e') + goto SETERROR; + + ds->lastType = JT_TRUE; + ds->start = offset; + return ds->dec->newTrue(ds->prv); + +SETERROR: + return SetError(ds, -1, "Unexpected character found when decoding 'true'"); +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_false ( struct DecoderState *ds) +{ + char *offset = ds->start; + offset ++; + + if (*(offset++) != 'a') + goto SETERROR; + if (*(offset++) != 'l') + goto SETERROR; + if (*(offset++) != 's') + goto SETERROR; + if (*(offset++) != 'e') + goto SETERROR; + + ds->lastType = JT_FALSE; + ds->start = offset; + return ds->dec->newFalse(ds->prv); + +SETERROR: + return SetError(ds, -1, "Unexpected character found when decoding 'false'"); +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_null ( struct DecoderState *ds) +{ + char *offset = ds->start; + offset ++; + + if (*(offset++) != 'u') + goto SETERROR; + if (*(offset++) != 'l') + goto SETERROR; + if (*(offset++) != 'l') + goto SETERROR; + + ds->lastType = JT_NULL; + ds->start = offset; + return ds->dec->newNull(ds->prv); + +SETERROR: + return SetError(ds, -1, "Unexpected character found when decoding 'null'"); +} + +FASTCALL_ATTR void FASTCALL_MSVC SkipWhitespace(struct DecoderState *ds) +{ + char *offset = ds->start; + + for (;;) + { + switch (*offset) + { + case ' ': + case '\t': + case '\r': + case '\n': + offset ++; + break; + + default: + ds->start = offset; + return; + } + } +} + +enum DECODESTRINGSTATE +{ + DS_ISNULL = 0x32, + DS_ISQUOTE, + DS_ISESCAPE, + DS_UTFLENERROR, + +}; + +static const JSUINT8 g_decoderLookup[256] = +{ + /* 0x00 */ DS_ISNULL, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x20 */ 1, 1, DS_ISQUOTE, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, DS_ISESCAPE, 1, 1, 1, + /* 0x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0xa0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0xb0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0xc0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + /* 0xd0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + /* 0xe0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 0xf0 */ 4, 4, 4, 4, 4, 4, 4, 4, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, +}; + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds) +{ + JSUTF16 sur[2] = { 0 }; + int iSur = 0; + int index; + wchar_t *escOffset; + wchar_t *escStart; + size_t escLen = (ds->escEnd - ds->escStart); + JSUINT8 *inputOffset; + JSUINT8 oct; + JSUTF32 ucs; + ds->lastType = JT_INVALID; + ds->start ++; + + if ( (size_t) (ds->end - ds->start) > escLen) + { + size_t newSize = (ds->end - ds->start); + + if (ds->escHeap) + { + if (newSize > (UINT_MAX / sizeof(wchar_t))) + { + return SetError(ds, -1, "Could not reserve memory block"); + } + escStart = (wchar_t *)ds->dec->realloc(ds->escStart, newSize * sizeof(wchar_t)); + if (!escStart) + { + ds->dec->free(ds->escStart); + return SetError(ds, -1, "Could not reserve memory block"); + } + ds->escStart = escStart; + } + else + { + wchar_t *oldStart = ds->escStart; + ds->escHeap = 1; + if (newSize > (UINT_MAX / sizeof(wchar_t))) + { + return SetError(ds, -1, "Could not reserve memory block"); + } + ds->escStart = (wchar_t *) ds->dec->malloc(newSize * sizeof(wchar_t)); + if (!ds->escStart) + { + return SetError(ds, -1, "Could not reserve memory block"); + } + memcpy(ds->escStart, oldStart, escLen * sizeof(wchar_t)); + } + + ds->escEnd = ds->escStart + newSize; + } + + escOffset = ds->escStart; + inputOffset = (JSUINT8 *) ds->start; + + for (;;) + { + switch (g_decoderLookup[(JSUINT8)(*inputOffset)]) + { + case DS_ISNULL: + { + return SetError(ds, -1, "Unmatched ''\"' when when decoding 'string'"); + } + case DS_ISQUOTE: + { + ds->lastType = JT_UTF8; + inputOffset ++; + ds->start += ( (char *) inputOffset - (ds->start)); + return ds->dec->newString(ds->prv, ds->escStart, escOffset); + } + case DS_UTFLENERROR: + { + return SetError (ds, -1, "Invalid UTF-8 sequence length when decoding 'string'"); + } + case DS_ISESCAPE: + inputOffset ++; + switch (*inputOffset) + { + case '\\': *(escOffset++) = L'\\'; inputOffset++; continue; + case '\"': *(escOffset++) = L'\"'; inputOffset++; continue; + case '/': *(escOffset++) = L'/'; inputOffset++; continue; + case 'b': *(escOffset++) = L'\b'; inputOffset++; continue; + case 'f': *(escOffset++) = L'\f'; inputOffset++; continue; + case 'n': *(escOffset++) = L'\n'; inputOffset++; continue; + case 'r': *(escOffset++) = L'\r'; inputOffset++; continue; + case 't': *(escOffset++) = L'\t'; inputOffset++; continue; + + case 'u': + { + int index; + inputOffset ++; + + for (index = 0; index < 4; index ++) + { + switch (*inputOffset) + { + case '\0': return SetError (ds, -1, "Unterminated unicode escape sequence when decoding 'string'"); + default: return SetError (ds, -1, "Unexpected character in unicode escape sequence when decoding 'string'"); + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + sur[iSur] = (sur[iSur] << 4) + (JSUTF16) (*inputOffset - '0'); + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'a'); + break; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'A'); + break; + } + + inputOffset ++; + } + + if (iSur == 0) + { + if((sur[iSur] & 0xfc00) == 0xd800) + { + // First of a surrogate pair, continue parsing + iSur ++; + break; + } + (*escOffset++) = (wchar_t) sur[iSur]; + iSur = 0; + } + else + { + // Decode pair + if ((sur[1] & 0xfc00) != 0xdc00) + { + return SetError (ds, -1, "Unpaired high surrogate when decoding 'string'"); + } +#if WCHAR_MAX == 0xffff + (*escOffset++) = (wchar_t) sur[0]; + (*escOffset++) = (wchar_t) sur[1]; +#else + (*escOffset++) = (wchar_t) 0x10000 + (((sur[0] - 0xd800) << 10) | (sur[1] - 0xdc00)); +#endif + iSur = 0; + } + break; + } + + case '\0': return SetError(ds, -1, "Unterminated escape sequence when decoding 'string'"); + default: return SetError(ds, -1, "Unrecognized escape sequence when decoding 'string'"); + } + break; + + case 1: + { + *(escOffset++) = (wchar_t) (*inputOffset++); + break; + } + + case 2: + { + ucs = (*inputOffset++) & 0x1f; + ucs <<= 6; + if (((*inputOffset) & 0x80) != 0x80) + { + return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); + } + ucs |= (*inputOffset++) & 0x3f; + if (ucs < 0x80) return SetError (ds, -1, "Overlong 2 byte UTF-8 sequence detected when decoding 'string'"); + *(escOffset++) = (wchar_t) ucs; + break; + } + + case 3: + { + JSUTF32 ucs = 0; + ucs |= (*inputOffset++) & 0x0f; + + for (index = 0; index < 2; index ++) + { + ucs <<= 6; + oct = (*inputOffset++); + + if ((oct & 0x80) != 0x80) + { + return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); + } + + ucs |= oct & 0x3f; + } + + if (ucs < 0x800) return SetError (ds, -1, "Overlong 3 byte UTF-8 sequence detected when encoding string"); + *(escOffset++) = (wchar_t) ucs; + break; + } + + case 4: + { + JSUTF32 ucs = 0; + ucs |= (*inputOffset++) & 0x07; + + for (index = 0; index < 3; index ++) + { + ucs <<= 6; + oct = (*inputOffset++); + + if ((oct & 0x80) != 0x80) + { + return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); + } + + ucs |= oct & 0x3f; + } + + if (ucs < 0x10000) return SetError (ds, -1, "Overlong 4 byte UTF-8 sequence detected when decoding 'string'"); + +#if WCHAR_MAX == 0xffff + if (ucs >= 0x10000) + { + ucs -= 0x10000; + *(escOffset++) = (wchar_t) (ucs >> 10) + 0xd800; + *(escOffset++) = (wchar_t) (ucs & 0x3ff) + 0xdc00; + } + else + { + *(escOffset++) = (wchar_t) ucs; + } +#else + *(escOffset++) = (wchar_t) ucs; +#endif + break; + } + } + } +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_array(struct DecoderState *ds) +{ + JSOBJ itemValue; + JSOBJ newObj; + int len; + ds->objDepth++; + if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) { + return SetError(ds, -1, "Reached object decoding depth limit"); + } + + newObj = ds->dec->newArray(ds->prv); + len = 0; + + ds->lastType = JT_INVALID; + ds->start ++; + + for (;;) + { + SkipWhitespace(ds); + + if ((*ds->start) == ']') + { + ds->objDepth--; + if (len == 0) + { + ds->start ++; + return newObj; + } + + ds->dec->releaseObject(ds->prv, newObj); + return SetError(ds, -1, "Unexpected character found when decoding array value (1)"); + } + + itemValue = decode_any(ds); + + if (itemValue == NULL) + { + ds->dec->releaseObject(ds->prv, newObj); + return NULL; + } + + ds->dec->arrayAddItem (ds->prv, newObj, itemValue); + + SkipWhitespace(ds); + + switch (*(ds->start++)) + { + case ']': + { + ds->objDepth--; + return newObj; + } + case ',': + break; + + default: + ds->dec->releaseObject(ds->prv, newObj); + return SetError(ds, -1, "Unexpected character found when decoding array value (2)"); + } + + len ++; + } +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_object( struct DecoderState *ds) +{ + JSOBJ itemName; + JSOBJ itemValue; + JSOBJ newObj; + + ds->objDepth++; + if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) { + return SetError(ds, -1, "Reached object decoding depth limit"); + } + + newObj = ds->dec->newObject(ds->prv); + + ds->start ++; + + for (;;) + { + SkipWhitespace(ds); + + if ((*ds->start) == '}') + { + ds->objDepth--; + ds->start ++; + return newObj; + } + + ds->lastType = JT_INVALID; + itemName = decode_any(ds); + + if (itemName == NULL) + { + ds->dec->releaseObject(ds->prv, newObj); + return NULL; + } + + if (ds->lastType != JT_UTF8) + { + ds->dec->releaseObject(ds->prv, newObj); + ds->dec->releaseObject(ds->prv, itemName); + return SetError(ds, -1, "Key name of object must be 'string' when decoding 'object'"); + } + + SkipWhitespace(ds); + + if (*(ds->start++) != ':') + { + ds->dec->releaseObject(ds->prv, newObj); + ds->dec->releaseObject(ds->prv, itemName); + return SetError(ds, -1, "No ':' found when decoding object value"); + } + + SkipWhitespace(ds); + + itemValue = decode_any(ds); + + if (itemValue == NULL) + { + ds->dec->releaseObject(ds->prv, newObj); + ds->dec->releaseObject(ds->prv, itemName); + return NULL; + } + + ds->dec->objectAddKey (ds->prv, newObj, itemName, itemValue); + + SkipWhitespace(ds); + + switch (*(ds->start++)) + { + case '}': + { + ds->objDepth--; + return newObj; + } + case ',': + break; + + default: + ds->dec->releaseObject(ds->prv, newObj); + return SetError(ds, -1, "Unexpected character in found when decoding object value"); + } + } +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_any(struct DecoderState *ds) +{ + for (;;) + { + switch (*ds->start) + { + case '\"': + return decode_string (ds); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return decode_numeric (ds); + + case '[': return decode_array (ds); + case '{': return decode_object (ds); + case 't': return decode_true (ds); + case 'f': return decode_false (ds); + case 'n': return decode_null (ds); + + case ' ': + case '\t': + case '\r': + case '\n': + // White space + ds->start ++; + break; + + default: + return SetError(ds, -1, "Expected object or value"); + } + } +} + +JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer) +{ + /* + FIXME: Base the size of escBuffer of that of cbBuffer so that the unicode escaping doesn't run into the wall each time */ + struct DecoderState ds; + wchar_t escBuffer[(JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t))]; + JSOBJ ret; + + ds.start = (char *) buffer; + ds.end = ds.start + cbBuffer; + + ds.escStart = escBuffer; + ds.escEnd = ds.escStart + (JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t)); + ds.escHeap = 0; + ds.prv = dec->prv; + ds.dec = dec; + ds.dec->errorStr = NULL; + ds.dec->errorOffset = NULL; + ds.objDepth = 0; + + ds.dec = dec; + + ret = decode_any (&ds); + + if (ds.escHeap) + { + dec->free(ds.escStart); + } + + SkipWhitespace(&ds); + + if (ds.start != ds.end && ret) + { + dec->releaseObject(ds.prv, ret); + return SetError(&ds, -1, "Trailing data"); + } + + return ret; +} diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..61689b0d --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,31 @@ +ujson4c decoder helper 1.0 +Developed by ESN, an Electronic Arts Inc. studio. +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of ESN, Electronic Arts Inc. nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Uses UltraJSON library: +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. +www.github.com/esnme/ultrajson \ No newline at end of file diff --git a/README.rst b/README.rst new file mode 100644 index 00000000..626ac2fd --- /dev/null +++ b/README.rst @@ -0,0 +1,43 @@ +ujson4c +============= +A more user friendly layer for decoding JSON in C/C++ based on the ultra fast UltraJSON library + +============ +Usage +============ +Copy all of the files from /src and /3rdparty into a folder of choice in your own project. #include ujdecode.h read more about the API in ujdecode.h + +Example:: + + UJObject obj; + void *state; + const char input[] = "{\"name\": \"John Doe\", \"age\": 31, \"number\": 1337.37, \"address\": { \"city\": \"Uppsala\", \"population\": 9223372036854775807 } }"; + size_t cbInput = sizeof(input) - 1; + + const wchar_t *personKeys[] = { L"name", L"age", L"number", L"address"}; + UJObject oName, oAge, oNumber, oAddress; + + obj = UJDecode(input, cbInput, NULL, &state); + + if (UJObjectUnpack(obj, 4, "SNNO", personKeys, &oName, &oAge, &oNumber, &oAddress) == 4) + { + const wchar_t *addressKeys[] = { L"city", L"population" }; + UJObject oCity, oPopulation; + + const wchar_t *name = UJReadString(oName, NULL); + int age = UJNumericInt(oAge); + double number = UJNumericFloat(oNumber); + + if (UJObjectUnpack(oAddress, 2, "SN", addressKeys, &oCity, &oPopulation) == 2) + { + const wchar_t *city; + long long population; + city = UJReadString(oCity, NULL); + population = UJNumericLongLong(oPopulation); + } + } + + UJFree(state); + + + diff --git a/src/ujdecode.c b/src/ujdecode.c new file mode 100644 index 00000000..a8277aba --- /dev/null +++ b/src/ujdecode.c @@ -0,0 +1,842 @@ +/* +ujson4c decoder helper 1.0 +Developed by ESN, an Electronic Arts Inc. studio. +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of ESN, Electronic Arts Inc. nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Uses UltraJSON library: +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. +www.github.com/esnme/ultrajson +*/ + +#include "ujdecode.h" +#include "ultrajson.h" +#include +#include +#include +#include + +typedef struct __Item +{ + int type; +} Item; + +typedef struct __StringItem +{ + Item item; + UJString str; +} StringItem; + +typedef struct __KeyPair +{ + StringItem *name; + Item *value; + struct __KeyPair *next; +} KeyPair; + +typedef struct __ObjectItem +{ + Item item; + KeyPair *head; + KeyPair *tail; +} ObjectItem; + +typedef struct __ArrayEntry +{ + Item *item; + struct __ArrayEntry *next; +} ArrayEntry; + +typedef struct __ArrayItem +{ + Item item; + ArrayEntry *head; + ArrayEntry *tail; +} ArrayItem; + +typedef struct __LongValue +{ + Item item; + long value; +} LongValue; + +typedef struct __LongLongValue +{ + Item item; + long long value; +} LongLongValue; + +typedef struct __DoubleValue +{ + Item item; + double value; +} DoubleValue; + +typedef struct __NullValue +{ + Item item; +} NullValue; + +typedef struct __FalseValue +{ + Item item; +} FalseValue; + +typedef struct __TrueValue +{ + Item item; +} TrueValue; + +typedef struct __HeapSlab +{ + unsigned char *start; + unsigned char *offset; + unsigned char *end; + size_t size; + char owned; + struct __HeapSlab *next; +} HeapSlab; + +struct DecoderState +{ + HeapSlab *heap; + const char *error; + void *(*malloc)(size_t cbSize); + void (*free)(void *ptr); +}; + + +static void *alloc(struct DecoderState *ds, size_t cbSize) +{ + unsigned char *ret; + + if (ds->heap->offset + cbSize > ds->heap->end) + { + size_t newSize = ds->heap->size * 2; + HeapSlab *newSlab; + + while (newSize < (cbSize + sizeof (HeapSlab))) + newSize *= 2; + + newSlab = (HeapSlab *) ds->malloc(newSize); + newSlab->start = (unsigned char *) (newSlab + 1); + newSlab->end = (unsigned char *) newSlab + newSize; + newSlab->size = newSize; + newSlab->offset = newSlab->start; + newSlab->owned = 1; + + newSlab->next = ds->heap; + ds->heap = newSlab; + } + + + ret = ds->heap->offset; + ds->heap->offset += cbSize; + + return ret; +} + +static JSOBJ newString(void* context, wchar_t *start, wchar_t *end) +{ + struct DecoderState *ds = context; + size_t len; + StringItem *si = (StringItem *) alloc(ds, sizeof(StringItem) + (end - start + 1) * sizeof(wchar_t)); + len = end - start; + + si->item.type = UJT_String; + si->str.ptr = (wchar_t *) (si + 1); + si->str.cchLen = len; + + if (len < 4) + { + wchar_t *dst = si->str.ptr; + wchar_t *end = dst + len; + + while (dst < end) + { + *(dst++) = *(start++); + } + } + else + { + memcpy (si->str.ptr, start, len * sizeof(wchar_t)); + } + si->str.ptr[len] = '\0'; + return (JSOBJ) si; +} + +static void objectAddKey(void* context, JSOBJ obj, JSOBJ name, JSOBJ value) +{ + struct DecoderState *ds = context; + ObjectItem *oi = (ObjectItem *) obj; + KeyPair *kp = (KeyPair *) alloc(ds, sizeof(KeyPair)); + + kp->next = NULL; + + kp->name = (StringItem *) name; + kp->value = (Item *) value; + + if (oi->tail) + { + oi->tail->next = kp; + } + else + { + oi->head = kp; + } + oi->tail = kp; +} + +static void arrayAddItem(void* context, JSOBJ obj, JSOBJ value) +{ + struct DecoderState *ds = context; + ArrayItem *ai = (ArrayItem *) obj; + ArrayEntry *ae = (ArrayEntry *) alloc(ds, sizeof(ArrayEntry)); + + ae->next = NULL; + ae->item = (Item *) value; + + if (ai->tail) + { + ai->tail->next = ae; + } + else + { + ai->head = ae; + } + ai->tail = ae; + +} + +static JSOBJ newTrue(void* context) +{ + struct DecoderState *ds = context; + TrueValue *tv = (TrueValue *) alloc(ds, sizeof(TrueValue *)); + tv->item.type = UJT_True; + return (JSOBJ) tv; +} + +static JSOBJ newFalse(void *context) +{ + struct DecoderState *ds = context; + FalseValue *fv = (FalseValue *) alloc(ds, sizeof(FalseValue *)); + fv->item.type = UJT_False; + return (JSOBJ) fv; +} + +static JSOBJ newNull(void *context) +{ + struct DecoderState *ds = context; + NullValue *nv = (NullValue *) alloc(ds, sizeof(NullValue *)); + nv->item.type = UJT_Null; + return (JSOBJ) nv; +} + +static JSOBJ newObject(void *context) +{ + struct DecoderState *ds = context; + ObjectItem *oi = (ObjectItem *) alloc(ds, sizeof(ObjectItem)); + oi->item.type = UJT_Object; + oi->head = NULL; + oi->tail = NULL; + + return (JSOBJ) oi; +} + +static JSOBJ newArray(void *context) +{ + struct DecoderState *ds = context; + ArrayItem *ai = (ArrayItem *) alloc(ds, sizeof(ArrayItem)); + ai->head = NULL; + ai->tail = NULL; + ai->item.type = UJT_Array; + return (JSOBJ) ai; +} + +static JSOBJ newInt(void *context, JSINT32 value) +{ + struct DecoderState *ds = context; + LongValue *lv = (LongValue *) alloc(ds, sizeof(LongValue)); + lv->item.type = UJT_Long; + lv->value = (long) value; + return (JSOBJ) lv; +} + +static JSOBJ newLong(void *context, JSINT64 value) +{ + struct DecoderState *ds = context; + LongLongValue *llv = (LongLongValue *) alloc(ds, sizeof(LongLongValue)); + llv->item.type = UJT_LongLong; + llv->value = (long long) value; + return (JSOBJ) llv; +} + +static JSOBJ newDouble(void *context, double value) +{ + struct DecoderState *ds = context; + DoubleValue *dv = (DoubleValue *) alloc(ds, sizeof(DoubleValue)); + dv->item.type = UJT_Double; + dv->value = (double) value; + return (JSOBJ) dv; +} + +static void releaseObject(void *context, JSOBJ obj) +{ + struct DecoderState *ds = context; + //NOTE: Fix for C4100 warning in L4 MSVC + ds = NULL; + obj = NULL; +} + +static double GetDouble(UJObject obj) +{ + return ((DoubleValue *) obj)->value; +} + +static long GetLong(UJObject obj) +{ + return ((LongValue *) obj)->value; +} + +static long long GetLongLong(UJObject obj) +{ + return ((LongLongValue *) obj)->value; +} + +void UJFree(void *state) +{ + struct DecoderState *ds = (struct DecoderState *) state; + + HeapSlab *slab = ds->heap; + HeapSlab *next; + while (slab) + { + next = slab->next; + + if (slab->owned) + { + ds->free(slab); + } + + slab = next; + } +} + +int UJIsNull(UJObject obj) +{ + if (((Item *) obj)->type == UJT_Null) + { + return 1; + } + + return 0; +} + +int UJIsTrue(UJObject obj) +{ + if (((Item *) obj)->type == UJT_True) + { + return 1; + } + + return 0; +} + +int UJIsFalse(UJObject obj) +{ + if (((Item *) obj)->type == UJT_False) + { + return 1; + } + + + return 0; +} + +int UJIsLong(UJObject obj) +{ + if (((Item *) obj)->type == UJT_Long) + { + return 1; + } + + return 0; +} + +int UJIsLongLong(UJObject obj) +{ + if (((Item *) obj)->type == UJT_LongLong) + { + return 1; + } + + return 0; +} + +int UJIsInteger(UJObject *obj) +{ + if (((Item *) obj)->type == UJT_LongLong || + ((Item *) obj)->type == UJT_Long) + { + return 1; + } + + return 0; +} + +int UJIsDouble(UJObject obj) +{ + if (((Item *) obj)->type == UJT_Double) + { + return 1; + } + + return 0; +} + +int UJIsString(UJObject obj) +{ + if (((Item *) obj)->type == UJT_String) + { + return 1; + } + + return 0; +} + +int UJIsArray(UJObject obj) +{ + if (((Item *) obj)->type == UJT_Array) + { + return 1; + } + + return 0; +} + +int UJIsObject(UJObject obj) +{ + if (((Item *) obj)->type == UJT_Object) + { + return 1; + } + + return 0; +} + +void *UJBeginArray(UJObject arrObj) +{ + switch ( ((Item *) arrObj)->type) + { + case UJT_Array: return ((ObjectItem *) arrObj)->head; + default: break; + } + + return NULL; +} + +int UJIterArray(void **iter, UJObject *outObj) +{ + ArrayEntry *ae = (ArrayEntry *) *iter; + + if (ae == NULL) + { + return 0; + } + + *iter = ae->next; + *outObj = ae->item; + + return 1; +} + +void *UJBeginObject(UJObject objObj) +{ + switch ( ((Item *) objObj)->type) + { + case UJT_Object: return ((ObjectItem *) objObj)->head; + default: break; + } + + return NULL; +} + +int UJIterObject(void **iter, UJString *outKey, UJObject *outValue) +{ + KeyPair *kp; + + if (*iter == NULL) + { + return 0; + } + + kp = (KeyPair *) *iter; + + if (kp == NULL) + { + return 0; + } + + *outKey = ((StringItem *) kp->name)->str; + *outValue = kp->value; + *iter = kp->next; + return 1; +} + +long long UJNumericLongLong(UJObject obj) +{ + switch ( ((Item *) obj)->type) + { + case UJT_Long: return (long long) GetLong(obj); + case UJT_LongLong: return (long long) GetLongLong(obj); + case UJT_Double: return (long long) GetDouble(obj); + default: break; + } + + return 0; +} + +int UJNumericInt(UJObject obj) +{ + switch ( ((Item *) obj)->type) + { + case UJT_Long: return (int) GetLong(obj); + case UJT_LongLong: return (int) GetLongLong(obj); + case UJT_Double: return (int) GetDouble(obj); + default: break; + } + + return 0; +} + +double UJNumericFloat(UJObject obj) +{ + switch ( ((Item *) obj)->type) + { + case UJT_Long: return (double) GetLong(obj); + case UJT_LongLong: return (double) GetLongLong(obj); + case UJT_Double: return (double) GetDouble(obj); + default: break; + } + + return 0.0; +} + +const wchar_t *UJReadString(UJObject obj, size_t *cchOutBuffer) +{ + switch ( ((Item *) obj)->type) + { + case UJT_String: + if (cchOutBuffer) + *cchOutBuffer = ( (StringItem *) obj)->str.cchLen; + return ( (StringItem *) obj)->str.ptr; + + default: + break; + } + + if (cchOutBuffer) + *cchOutBuffer = 0; + return L""; +} + +const char *UJGetError(void *state) +{ + if (state == NULL) + return NULL; + + return ( (struct DecoderState *) state)->error; +} + +int UJGetType(UJObject obj) +{ + return ((Item *) obj)->type; +} + +static int checkType(int ki, const char *format, UJObject obj) +{ + int c = (unsigned char) format[ki]; + int type = UJGetType(obj); + int allowNull = 0; + + switch (c) + { + case 'b': + allowNull = 1; + case 'B': + switch (type) + { + case UJT_Null: + if (!allowNull) + return 0; + case UJT_True: + case UJT_False: + return 1; + + default: + return 0; + } + break; + + case 'n': + allowNull = 1; + case 'N': + switch (type) + { + case UJT_Null: + if (!allowNull) + return 0; + case UJT_Long: + case UJT_LongLong: + case UJT_Double: + return 1; + + default: + return 0; + } + break; + + case 's': + allowNull = 1; + case 'S': + switch (type) + { + case UJT_Null: + if (!allowNull) + return 0; + case UJT_String: + return 1; + + default: + return 0; + } + break; + + case 'a': + allowNull = 1; + case 'A': + switch (type) + { + case UJT_Null: + if (!allowNull) + return 0; + case UJT_Array: + return 1; + + default: + return 0; + } + break; + + case 'o': + allowNull = 1; + case 'O': + switch (type) + { + case UJT_Null: + if (!allowNull) + return 0; + case UJT_Object: + return 1; + default: + return 0; + } + + break; + + case 'u': + allowNull = 1; + case 'U': + return 1; + break; + } + + return 0; +} + +int UJObjectUnpack(UJObject objObj, int keys, const char *format, const wchar_t **_keyNames, ...) +{ + void *iter; + UJString key; + UJObject value; + int found = 0; + int ki; + int ks = 0; + const wchar_t *keyNames[64]; + UJObject *outValues[64]; + va_list args; + UJObject *outValue; + + + if (!UJIsObject(objObj)) + { + return 0; + } + + iter = UJBeginObject(objObj); + + if (keys > 64) + { + return -1; + } + + va_start(args, _keyNames); + for (ki = 0; ki < keys; ki ++) + { + keyNames[ki] = _keyNames[ki]; + outValue = va_arg(args, UJObject *); + outValues[ki] = outValue; + } + va_end(args); + + while (UJIterObject(&iter, &key, &value)) + { + for (ki = ks; ki < keys; ki ++) + { + const wchar_t *kn = keyNames[ki]; + + if (kn == NULL) + { + continue; + } + + if (wcscmp(key.ptr, kn) != 0) + { + continue; + } + + if (!checkType(ki, format, value)) + { + continue; + } + + found ++; + + if (outValues[ki]) + { + *outValues[ki] = value; + } + keyNames[ki] = NULL; + + if (ki == ks) + { + ks ++; + } + } + } + + + return found; +} + +UJObject UJDecode(const char *input, size_t cbInput, UJHeapFuncs *hf, void **outState) +{ + UJObject ret; + struct DecoderState *ds; + void *initialHeap; + size_t cbInitialHeap; + HeapSlab *slab; + + JSONObjectDecoder decoder = { + newString, + objectAddKey, + arrayAddItem, + newTrue, + newFalse, + newNull, + newObject, + newArray, + newInt, + newLong, + newDouble, + releaseObject, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + NULL + }; + + if (hf == NULL) + { + decoder.malloc = malloc; + decoder.free = free; + decoder.realloc = realloc; + cbInitialHeap = 16384; + initialHeap = malloc(cbInitialHeap); + + if (initialHeap == NULL) + { + return NULL; + } + } + else + { + decoder.malloc = hf->malloc; + decoder.free = hf->free; + decoder.realloc = hf->realloc; + initialHeap = hf->initalHeap; + cbInitialHeap = hf->cbInitialHeap; + + if (cbInitialHeap < sizeof(HeapSlab) + sizeof(struct DecoderState)) + { + return NULL; + } + } + + *outState = NULL; + + slab = (HeapSlab * ) initialHeap; + slab->start = (unsigned char *) (slab + 1); + slab->offset = slab->start; + slab->end = (unsigned char *) initialHeap + cbInitialHeap; + slab->size = cbInitialHeap; + slab->owned = hf == NULL ? 1 : 0; + slab->next = NULL; + + ds = (struct DecoderState *) slab->offset; + slab->offset += sizeof(struct DecoderState); + *outState = (void *) ds; + + ds->heap = slab; + + ds->malloc = decoder.malloc; + ds->free = decoder.free; + ds->error = NULL; + + decoder.prv = (void *) ds; + + ret = (UJObject) JSON_DecodeObject(&decoder, input, cbInput); + + if (ret == NULL) + { + ds->error = decoder.errorStr; + } + + return ret; +} diff --git a/src/ujdecode.h b/src/ujdecode.h new file mode 100644 index 00000000..9c4840dd --- /dev/null +++ b/src/ujdecode.h @@ -0,0 +1,261 @@ +/* +ujson4c decoder helper 1.0 +Developed by ESN, an Electronic Arts Inc. studio. +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of ESN, Electronic Arts Inc. nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Uses UltraJSON library: +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. +www.github.com/esnme/ultrajson +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + enum UJTypes + { + UJT_Null, + UJT_True, + UJT_False, + UJT_Long, + UJT_LongLong, + UJT_Double, + UJT_String, + UJT_Array, + UJT_Object + }; + +#include + typedef void * UJObject; + + typedef struct __UJString + { + wchar_t *ptr; + size_t cchLen; + } UJString; + + typedef struct __UJHeapFuncs + { + void *initalHeap; + size_t cbInitialHeap; + void *(*malloc)(size_t cbSize); + void (*free)(void *ptr); + void *(*realloc)(void *ptr, size_t cbSize); + } UJHeapFuncs; + + /* + =============================================================================== + Decodes an input text octet stream into a JSON object structure + + Arguments: + input - JSON data to decode in ANSI or UTF-8 format + cbInput - Length of input in bytes + hf - Heap functions, see UJHeapFuncs. Optional may be NULL + outState - Outputs the decoder state. + + Not about heap functions: + Declare a UJHeapFuncs structure on the stack if you want to manage your own heap + and pass it as the hf argument to UJDecode. + initalHeap - Pointer to a buffer for the initial heap handled by the caller. + Preferably stored on the stack. MUST not be smaller than 1024 bytes + cbInitialHeap - Size of the initial heap in bytes + malloc - Pointer to malloc function + free - Pointer to free function + realloc - Pointer to realloc function + + Returns a JSON object structure representation or NULL in case of error. + Use UJGetError get obtain error message. + + Example usage: + + const char *input; + size_t cbInput; + void *state; + + obj = UJDecode(input, cbInput, NULL, &state); + + if (obj == NULL) + printf ("Error: %s\n", UJGetError(state)); + + ...Poke around in returned obj... + + UJFree(state); + =============================================================================== + */ + UJObject UJDecode(const char *input, size_t cbInput, UJHeapFuncs *hf, void **outState); + + /* + =============================================================================== + Called to free the decoder state + =============================================================================== + */ + void UJFree(void *state); + + /* + =============================================================================== + Check if object is of certain type + =============================================================================== + */ + int UJIsNull(UJObject obj); + int UJIsTrue(UJObject obj); + int UJIsFalse(UJObject obj); + int UJIsLong(UJObject obj); + int UJIsLongLong(UJObject obj); + int UJIsInteger(UJObject *obj); + int UJIsDouble(UJObject obj); + int UJIsString(UJObject obj); + int UJIsArray(UJObject obj); + int UJIsObject(UJObject obj); + + /* + =============================================================================== + See UJTypes enum for possible return values + =============================================================================== + */ + int UJGetType(UJObject obj); + + /* + =============================================================================== + Called to initiate the iterator of an array object + May return NULL in case array is empty + =============================================================================== + */ + void *UJBeginArray(UJObject arrObj); + + /* + =============================================================================== + Iterates an array object + + Arguments: + iter - Anonymous iterator + outObj - Object in array + + Usage: + Get initial iterator from call to UJBeginArray. + Call this function until it returns 0 + =============================================================================== + */ + int UJIterArray(void **iter, UJObject *outObj); + + /* + =============================================================================== + Called to initiate the iterator of an Object (key-value structure) + May return NULL in case Object is empty + + =============================================================================== + */ + void *UJBeginObject(UJObject objObj); + + /* + =============================================================================== + Iterates an Object + + Arguments: + iter - Anonymous iterator + outKey - Key name + outValue - Value object + + Usage: + Get initial iterator from call to UJBeginObject + Call this function until it returns 0 + =============================================================================== + */ + int UJIterObject(void **iter, UJString *outKey, UJObject *outValue); + + /* + =============================================================================== + Unpacks an Object by matching the key name with the requested format + + Each key name needs to be matched by the character in the format string + representing the desired type of the value for that key + B - Boolean + N - Numeric + S - String + A - Array + O - Object + U - Unknown/any + + Use lower case to accept JSON Null in place of the expected value. + + Arguments: + objObj - The object to unpack (JSON Object) + keys - Number of keys to match. Keys can not exceed 64. + format - Specified the expected types for the key value. + keyNames - An array of key names + ... - Output value objects (as UJObject *) + + Return value: + Returns number of key pairs matched or -1 on error + =============================================================================== + */ + int UJObjectUnpack(UJObject objObj, int keys, const char *format, const wchar_t **keyNames, ...); + + /* + =============================================================================== + Returns the value of a double, long or long long value as a double. + If value is not any of these 0.0 is returned. + =============================================================================== + */ + double UJNumericFloat(UJObject obj); + + /* + =============================================================================== + Returns the value of a double, long or long long value as an integer. + If value is not any of these types 0 is returned. + + Truncation may arrise from word sizes and the presence of decimals when + converting doubles to integers. + =============================================================================== + */ + long long UJNumericLongLong(UJObject obj); + int UJNumericInt(UJObject obj); + + + + /* + =============================================================================== + Returns the value of a string value as a wide character string pointer. Caller must NOT free returned pointer. + cchOutBuffer contains the character length of the returned string. + + If the value is not a string an empty string is returned. + =============================================================================== + */ + const wchar_t *UJReadString(UJObject obj, size_t *cchOutBuffer); + + /* + =============================================================================== + Returns last error message if any as a string or NULL. + Caller must NOT free returned pointer. + =============================================================================== + */ + const char *UJGetError(void *state); + +#ifdef __cplusplus +} +#endif diff --git a/tests/benchmark.c b/tests/benchmark.c new file mode 100644 index 00000000..d3423ae0 --- /dev/null +++ b/tests/benchmark.c @@ -0,0 +1,225 @@ +/* +ujson4c decoder helper 1.0 +Developed by ESN, an Electronic Arts Inc. studio. +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of ESN, Electronic Arts Inc. nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Uses UltraJSON library: +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. +www.github.com/esnme/ultrajson +*/ + +#include +#include "ujdecode.h" +#include +#include +#include +#include + +void prefixLine(int level) +{ + int index; + for (index = 0; index < level; index ++) + { + fputc(' ', stdout); + fputc(' ', stdout); + } +} + + +void dumpObject(int level, void *state, UJObject obj) +{ + switch (UJGetType(obj)) + { + case UJT_Null: + { +#ifdef VERBOSE_DUMP + prefixLine(level); + fprintf (stdout, "NULL\n"); +#endif + break; + } + case UJT_True: + { +#ifdef VERBOSE_DUMP + prefixLine(level); + fprintf (stdout, "True\n"); +#endif + break; + } + case UJT_False: + { +#ifdef VERBOSE_DUMP + prefixLine(level); + fprintf (stdout, "False\n"); +#endif + break; + } + case UJT_Long: + { + long value = (long) UJNumericLongLong(obj); + +#ifdef VERBOSE_DUMP + prefixLine(level); + fprintf (stdout, "%ld\n", value); +#endif + break; + } + case UJT_LongLong: + { + long long value = UJNumericLongLong(obj); + +#ifdef VERBOSE_DUMP + prefixLine(level); + fprintf (stdout, "%lld\n", value); +#endif + break; + } + case UJT_Double: + { + double value = UJNumericFloat(obj); + +#ifdef VERBOSE_DUMP + prefixLine(level); + fprintf (stdout, "%f\n", value); +#endif + break; + } + case UJT_String: + { + size_t len; + const wchar_t *value; + value = UJReadString(obj, &len); + +#ifdef VERBOSE_DUMP + fwprintf (stdout, L"%s\n", value); +#endif + break; + } + case UJT_Array: + { + void *iter = NULL; + UJObject objiter = NULL; + +#ifdef VERBOSE_DUMP + fputc('[', stdout); +#endif + + iter = UJBeginArray(obj); + + while(UJIterArray(&iter, &objiter)) + { + dumpObject(level + 1, state, objiter); + } + +#ifdef VERBOSE_DUMP + fputc(']', stdout); +#endif + + break; + } + case UJT_Object: + { + void *iter = NULL; + UJObject objiter = NULL; + UJString key; + +#ifdef VERBOSE_DUMP + prefixLine(level); + fputc('{', stdout); +#endif + + iter = UJBeginObject(obj); + + while(UJIterObject(&iter, &key, &objiter)) + { +#ifdef VERBOSE_DUMP + fwprintf (stdout, L"%s: ", key.ptr); +#endif + dumpObject(level + 1, state, objiter); + } + +#ifdef VERBOSE_DUMP + fputc('}', stdout); +#endif + break; + } + } + +} + +#ifdef __BENCHMARK__ +int main () +{ + const char *input; + size_t cbInput; + void *state; + FILE *file; + char buffer[32768]; + time_t tsNow; + int count; + size_t bytesDecoded; + + UJHeapFuncs hf; + hf.cbInitialHeap = sizeof(buffer); + hf.initalHeap = buffer; + hf.free = free; + hf.malloc = malloc; + hf.realloc = realloc; + + file = fopen("./sample.json", "rb"); + input = (char *) malloc(1024 * 1024); + cbInput = fread ( (void *) input, 1, 1024 * 1024, file); + fclose(file); + + tsNow = time(0); + count = 0; + bytesDecoded = 0; + + for (;;) + { + UJObject obj; + + obj = UJDecode(input, cbInput, &hf, &state); + dumpObject(0, state, obj); + + UJFree(state); + + count ++; + bytesDecoded += cbInput; + + if (tsNow != time(0)) + { + float bps = (float) bytesDecoded; + fprintf (stderr, "Count %d, MBps: %f\n", count, bps / 1000000.0f); + + count = 0; + bytesDecoded = 0; + tsNow = time(0); + } + } +} +#endif \ No newline at end of file diff --git a/tests/sample.json b/tests/sample.json new file mode 100644 index 00000000..30930e76 --- /dev/null +++ b/tests/sample.json @@ -0,0 +1,3315 @@ +{ + "a": { + "6U閆崬밺뀫颒myj츥휘:$薈mY햚#rz飏+玭V㭢뾿愴YꖚX亥ᮉ푊\u0006垡㐭룝\"厓ᔧḅ^Sqpv媫\"⤽걒\"˽Ἆ?ꇆ䬔未tv{DV鯀Tἆl凸g\\㈭ĭ즿UH㽤": null, + "b茤z\\.N": [[ + "ZL:ᅣዎ*Y|猫劁櫕荾Oj为1糕쪥泏S룂w࡛Ᏺ⸥蚙)", + { + "\"䬰ỐwD捾V`邀⠕VD㺝sH6[칑.:醥葹*뻵倻aD\"": true, + "e浱up蔽Cr෠JK軵xCʨ<뜡癙Y獩ケ齈X/螗唻?<蘡+뷄㩤쳖3偑犾&\\첊xz坍崦ݻ鍴\"嵥B3㰃詤豺嚼aqJ⑆∥韼@\u000b㢊\u0015L臯.샥": false, + "l?Ǩ喳e6㔡$M꼄I,(3᝝縢,䊀疅뉲B㴔傳䂴\u0088㮰钘ꜵ!ᅛ韽>": -5514085325291784739, + "o㮚?\"춛㵉<\/﬊ࠃ䃪䝣wp6ἀ䱄[s*S嬈貒pᛥ㰉'돀": [{ + "(QP윤懊FI<ꃣ『䕷[\"珒嶮?%Ḭ壍಻䇟0荤!藲끹bd浶tl\u2049#쯀@僞": {"i妾8홫": { + ",M맃䞛K5nAㆴVN㒊햬$n꩑&ꎝ椞阫?/ṏ세뉪1x쥼㻤㪙`\"$쟒薟B煌܀쨝ଢ଼2掳7㙟鴙X婢\u0002": "Vዉ菈᧷⦌kﮞఈnz*﷜FM\"荭7ꍀ-VR<\/';䁙E9$䩉\f @s?퍪o3^衴cඎ䧪aK鼟q䆨c{䳠5mᒲՙ蘹ᮩ": { + "F㲷JGo⯍P덵x뒳p䘧☔\"+ꨲ吿JfR㔹)4n紬G练Q፞!C|": true, + "p^㫮솎oc.೚A㤠??r\u000f)⾽⌲們M2.䴘䩳:⫭胃\\፾@Fᭌ\\K": false, + "蟌Tk愙潦伩": { + "a<\/@ᾛ慂侇瘎": -7271305752851720826, + "艓藬/>၄ṯ,XW~㲆w": {"E痧郶)㜓ha朗!N赻瞉駠uC\u20ad辠x퓮⣫P1ࠫLMMX'M刼唳됤": null, + "P쓫晥%k覛ዩIUᇸ滨:噐혲lMR5䋈V梗>%幽u頖\\)쟟": null, + "eg+昉~矠䧞难\b?gQ쭷筝\\eꮠNl{ಢ哭|]Mn銌╥zꖘzⱷ⭤ᮜ^": [ + -1.30142114406914976E17, + -1.7555215491128452E-19, + null, + "渾㨝ߏ牄귛r?돌?w[⚞ӻ~廩輫㼧/", + -4.5737191805302129E18, + null, + "xy࿑M[oc셒竓Ⓔx?뜓y䊦>-D켍(&&?XKkc꩖ﺸᏋ뵞K伕6ী)딀P朁yW揙?훻魢傎EG碸9類៌g踲C⟌aEX舲:z꒸许", + 3808159498143417627, + null, + {"m試\u20df1{G8&뚈h홯J<\/": { + "3ஸ厠zs#1K7:rᥞoꅔꯧ&띇鵼鞫6跜#赿5l'8{7㕳(b/j\"厢aq籀ꏚ\u0015厼稥": [ + -2226135764510113982, + true, + null, + { + "h%'맞S싅Hs&dl슾W0j鿏MםD놯L~S-㇡R쭬%": null, + "⟓咔謡칲\u0000孺ꛭx旑檉㶆?": null, + "恇I転;￸B2Y`z\\獓w,놏濐撐埵䂄)!䶢D=ഭ㴟jyY": { + "$ࡘt厛毣ൢI芁<겿骫⫦6tr惺a": [ + 6.385779736989334E-20, + false, + true, + true, + [ + -6.891946211462334E-19, + null, + { + "]-\\Ꟑ1/薓❧Ὂ\\l牑\u0007A郃)阜ᇒᓌ-塯`W峬G}SDb㬨Q臉⮻빌O鞟톴첂B㺱<ƈmu챑J㴹㷳픷Oㆩs": { + "\"◉B\"pᶉt骔J꩸ᄇᛐi╰栛K쉷㉯鐩!㈐n칍䟅難>盥y铿e୔蒏M貹ヅ8嘋퀯䉶ጥ㏢殊뻳\"絧╿ꉑ䠥?∃蓊{}㣣Gk긔H1哵峱": false, + "6.瀫cN䇮F㧺?\\椯=ڈT䘆4␘8qv": -3.5687501019676885E-19, + "Q?yऴr혴{஀䳘p惭f1ﹸ䅷䕋贲<ྃᄊ繲hq\\b|#QSTs1c-7(䵢\u2069匏絘ꯉ:l毴汞t戀oෟᵶ뮱፣-醇Jx䙬䐁햢0࣫ᡁgrㄛ": "\u0011_xM/蘇Chv;dhA5.嗀绱V爤ﰦi뵲M", + "⏑[\"ugoy^儣횎~U\\섯겜論l2jw஌yD腅̂\u0019": true, + "ⵯɇ䐲᫿࢚!㯢l샅笶戮1꣖0Xe": null, + "劅f넀識b宁焊E찓橵G!ʱ獓뭔雩괛": [{"p⹣켙[q>燣䍃㞽ᩲx:쓤삘7玑퇼0<\/q璂ᑁ[Z\\3䅵䧳\u0011㤧|妱緒C['췓Yꞟ3Z鳱雼P錻BU씧U`ᢶg蓱>.1ӧ譫'L_5V䏵Ц": [ + false, + false, + {"22䂍盥N霂얢躰e9⑩_뵜斌n@B}$괻Yᐱ@䧋V\"☒-諯cV돯ʠ": true, + "Ű螧ᔼ檍鍎땒딜qꄃH뜣<獧ूCY吓⸏>XQ㵡趌o끬k픀빯a(ܵ甏끆୯/6Nᪧ}搚ᆚ짌P牰泱鈷^d꣟#L삀\"㕹襻;k㸊\\f+": true, + "쎣\",|⫝̸阊x庿k잣v庅$鈏괎炔k쬪O_": [ + "잩AzZGz3v愠ꉈⵎ?㊱}S尳௏p\r2>췝IP䘈M)w|\u000eE", + -9222726055990423201, + null, + [ + false, + {"´킮'뮤쯽Wx讐V,6ᩪ1紲aႈ\u205czD": [ + -930994432421097536, + 3157232031581030121, + "l貚PY䃛5@䭄귻m㎮琸f": 1.0318894506812084E-19, + "࢜⩢Ш䧔1肽씮+༎ᣰ闺馺窃䕨8Mƶq腽xc(៯夐J5굄䕁Qj_훨/~価.䢵慯틠퇱豠㼇Qﵘ$DuSp(8Uญ<\/ಟ룴𥳐ݩ$": 8350772684161555590, + "ㆎQ䄾\u001bpᩭ${[諟^^骴᤮b^ㅥI┧T㉇⾞\"绦r䰂f矩'-7䡭桥Dz兔V9谶居㺍ᔊ䩯덲.\u001eL0ὅㅷ釣": [{ + "<쯬J卷^숞u࠯䌗艞R9닪g㐾볎a䂈歖意:%鐔|ﵤ|y}>;2,覂⶚啵tb*仛8乒㓶B࿠㯉戩oX 貘5V嗆렽낁߼4h䧛ꍺM空\\b꿋貼": 8478577078537189402, + "VD*|吝z~h譺aᯒ": { + "YI췢K<\/濳xNne玗rJo쾘3핰鴊\"↱AR:ࢷ\"9?\"臁說)?誚ꊏe)_D翾W?&F6J@뺾ꍰNZ醊Z쾈വH嶿?炫㷱鬰M겈᭨b,⻁鈵P䕡䀠८ⱄ홎鄣": { + "@?k2鶖㋮\"Oರ K㨇廪儲\u0017䍾J?);\b*묀㗠섳햭1MC V": null, + "UIICP!BUA`ᢈ㋸~袩㗪⾒=fB﮴l1ꡛ죘R辂여ҳ7쮡<䩲`熕8頁": 4481809488267626463, + "Y?+8먙ᚔ鋳蜩럶1㥔y璜౩`": [ + null, + 1.2850335807501874E-19, + "~V2", + 2035406654801997866, + { + "<숻1>\"": -8062468865199390827, + "M㿣E]}qwG莎Gn᝶(ꔙ\\D⬲iꇲs寢t駇S뀡ꢜ": false, + "pꝤ㎏9W%>M;-U璏f(^j1?&RB隧 忓b똊E": "#G?C8.躬ꥯ'?냪#< 渟&헿란zpo왓Kj}鷧XﻘMツb䕖;㪻", + "vE풤幉xz뱕쫥Ug㦲aH} ᣟp:鬼YᰟH3镔ᴚ斦\\鏑r*2橱G⼔F/.j": true, + "RK좬뎂a홠f*f㱉ᮍ⦋潙㨋Gu곌SGI3I뿐\\F',)t`荁蘯囯ﮉ裲뇟쥼_ገ驪▵撏ᕤV": 1.52738225997956557E18, + "^k굲䪿꠹B逤%F㱢漥O披M㽯镞竇霒i꼂焅륓\u00059=皫之눃\u2047娤閍銤唫ၕb<\/w踲䔼u솆맚,䝒ᝳ'/it": "B餹饴is権ꖪ怯ꦂẉဎt\"!凢谵⧿0\\<=(uL䷍刨쑪>俆揓Cy襸Q힆䆭涷<\/ᐱ0ɧ䗾䚹\\ኜ?ꄢᇘ`䴢{囇}᠈䴥X4퓪檄]ꥷ/3謒ሴn+g騍X", + "GgG꽬[(嫓몍6\u0004궍宩㙻/>\u0011^辍dT腪hxǑ%ꊇk,8(W⧂結P鬜O": [{ + "M㴾c>\\ᓲ\u0019V{>ꤩ혙넪㭪躂TS-痴໸闓⍵/徯O.M㏥ʷD囎⧔쁳휤T??鉬뇙=#ꢫ숣BX䭼<\/d똬졬g榿)eꨋﯪ좇첻\u001a\u0011\";~쓆BH4坋攊7힪", + "iT:L闞椕윚*滛gI≀Wਟඊ'ꢆ縺뱹鮚Nꩁ᧬蕼21줧\\䋯``⍐\\㏱鳨": 1927052677739832894, + "쮁缦腃g]礿Y㬙 fヺSɪ꾾N㞈": [ + null, + null, + { + "!t,灝Y 1䗉罵?c饃호䉂Cᐭ쒘z(즽sZG㬣sഖE4뢜㓕䏞丮Qp簍6EZឪ겛fx'ꩱQ0罣i{k锩*㤴㯞r迎jTⲤ渔m炅肳": [ + -3.3325685522591933E18, + [{"㓁5]A䢕1룥BC?Ꙍ`r룔Ⳛ䙡u伲+\u0001്o": [ + null, + 4975309147809803991, + null, + null, + {"T팘8Dﯲ稟MM☻㧚䥧/8ﻥ⥯aXLaH\"顾S☟耲ît7fS෉놁뮔/ꕼ䓈쁺4\\霶䠴ᩢ<\/t4?죵>uD5➶༆쉌럮⢀秙䘥\u20972ETR3濡恆vB? ~鸆\u0005": { + "`閖m璝㥉b뜴?Wf;?DV콜\u2020퍉౓擝宏ZMj3mJ먡-傷뱙yח㸷꥿ ໘u=M읝!5吭L4v\\?ǎ7C홫": null, + "|": false, + "~Ztᛋ䚘\\擭㗝傪W陖+㗶qᵿ蘥ᙄp%䫎)}=⠔6ᮢS湟-螾-mXH?cp": 448751162044282216, + "\u209fad놹j檋䇌ᶾ梕㉝bוּ": {"?苴ꩠD䋓帘5騱qﱖPF?☸珗顒yU ᡫcb䫎 S@㥚gꮒ쎘泴멖\\:I鮱TZ듒ᶨQ3+f7캙\"?\f풾\\o杞紟﻽M.⏎靑OP": [ + -2.6990368911551596E18, + [{"䒖@<᰿<\/⽬tTr腞&G%᳊秩蜰擻f㎳?S㵧\r*k뎾-乢겹隷j軛겷0룁鮁": {")DO0腦:춍逿:1㥨่!蛍樋2": [{ + ",ꌣf侴笾m๫ꆽ?1?U?\u0011ꌈꂇ": { + "x捗甠nVq䅦w`CD⦂惺嘴0I#vỵ} \\귂S끴D얾?Ԓj溯\"v餄a": { + "@翙c⢃趚痋i\u0015OQ⍝lq돆Y0pࢥ3쉨䜩^<8g懥0w)]䊑n洺o5쭝QL댊랖L镈Qnt⪟㒅십q헎鳒⮤眉ᔹ梠@O縠u泌ㄘb榚癸XޔFtj;iC": false, + "I&뱋゘|蓔䔕측瓯%6ᗻHW\\N1貇#?僐ᗜgh᭪o'䗈꽹Rc욏/蔳迄༝!0邔䨷푪8疩)[쭶緄㇈୧ፐ": { + "B+:ꉰ`s쾭)빼C羍A䫊pMgjdx䐝Hf9᥸W0!C樃'蘿f䫤סи\u0017Jve? 覝f둀⬣퓉Whk\"஼=չﳐ皆笁BIW虨쫓F廰饞": -642906201042308791, + "sb,XcZ<\/m㉹ ;䑷@c䵀s奤⬷7`ꘖ蕘戚?Feb#輜}p4nH⬮eKL트}": [ + "RK鳗z=袤Pf|[,u욺", + "Ẏᏻ罯뉋⺖锅젯㷻{H䰞쬙-쩓D]~\u0013O㳢gb@揶蔉|kᦂ❗!\u001ebM褐sca쨜襒y⺉룓", + null, + null, + true, + -1.650777344339075E-19, + false, + "☑lꄆs힨꤇]'uTന⌳농].1⋔괁沰\"IWഩ\u0019氜8쟇䔻;3衲恋,窌z펏喁횗?4?C넁问?ᥙ橭{稻Ⴗ_썔", + "n?]讇빽嗁}1孅9#ꭨ靶v\u0014喈)vw祔}룼쮿I", + -2.7033457331882025E18, + { + ";⚃^㱋x:饬ኡj'꧵T☽O㔬RO婎?향ᒭ搩$渣y4i;(Q>꿘e8q": "j~錘}0g;L萺*;ᕭꄮ0l潛烢5H▄쳂ꏒוֹꙶT犘≫x閦웧v", + "~揯\u2018c4職렁E~ᑅቚꈂ?nq뎤.:慹`F햘+%鉎O瀜쟏敛菮⍌浢<\/㮺紿P鳆ࠉ8I-o?#jﮨ7v3Dt赻J9": null, + "ࣝW䌈0ꍎqC逖,횅c၃swj;jJS櫍5槗OaB>D踾Y": {"㒰䵝F%?59.㍈cᕨ흕틎ḏ㋩B=9IېⓌ{:9.yw}呰ㆮ肒᎒tI㾴62\"ዃ抡C﹬B<\/촋jo朣", + [ + -7675533242647793366, + {"ᙧ呃:[㒺쳀쌡쏂H稈㢤\u001dᶗGG-{GHྻຊꡃ哸䵬;$?&d\\⥬こN圴됤挨-'ꕮ$PU%?冕눖i魁q騎Q": [ + false, + [[ + 7929823049157504248, + [[ + true, + "Z菙\u0017'eꕤ᱕l,0\\X\u001c[=雿8蠬L<\/낲긯W99g톉4ퟋb㝺\u0007劁'!麕Q궈oW:@X၎z蘻m絙璩귓죉+3柚怫tS捇蒣䝠-擶D[0=퉿8)q0ٟ", + "唉\nFA椭穒巯\\䥴䅺鿤S#b迅獘 ﶗ꬘\\?q1qN犠pX꜅^䤊⛤㢌[⬛휖岺q唻ⳡ틍\"㙙Eh@oA賑㗠y必Nꊑᗘ", + -2154220236962890773, + -3.2442003245397908E18, + "Wᄿ筠:瘫퀩?o貸q⊻(᎞KWf宛尨h^残3[U(='橄", + -7857990034281549164, + 1.44283696979059942E18, + null, + {"ꫯAw跭喀 ?_9\"Aty背F=9缉ྦྷ@;?^鞀w:uN㘢Rỏ": [ + 7.393662029337442E15, + 3564680942654233068, + [ + false, + -5253931502642112194, + "煉\\辎ೆ罍5⒭1䪁䃑s䎢:[e5}峳ﴱn騎3?腳Hyꏃ膼N潭錖,Yᝋ˜YAၓ㬠bG렣䰣:", + true, + null, + { + "⒛'P&%죮|:⫶춞": -3818336746965687085, + "钖m<\/0ݎMtF2Pk=瓰୮洽겎.": [[ + -8757574841556350607, + -3045234949333270161, + null, + { + "Ꮬr輳>⫇9hU##w@귪A\\C 鋺㘓ꖐ梒뒬묹㹻+郸嬏윤'+g<\/碴,}ꙫ>손;情d齆J䬁ຩ撛챝탹/R澡7剌tꤼ?ặ!`⏲睤\u00002똥଴⟏": null, + "\u20f2ܹe\\tAꥍư\\x当뿖렉禛;G檳ﯪS૰3~㘠#[J<}{奲 5箉⨔{놁<\/釿抋,嚠/曳m&WaOvT赋皺璑텁": [[ + false, + null, + true, + -5.7131445659795661E18, + "萭m䓪D5|3婁ఞ>蠇晼6nﴺPp禽羱DS<睓닫屚삏姿", + true, + [ + -8759747687917306831, + { + ">ⓛ\t,odKr{䘠?b퓸C嶈=DyEᙬ@ᴔ쨺芛髿UT퓻春<\/yꏸ>豚W釺N뜨^?꽴﨟5殺ᗃ翐%>퍂ဿ䄸沂Ea;A_\u0005閹殀W+窊?Ꭼd\u0013P汴G5썓揘": 4.342729067882445E-18, + "Q^즾眆@AN\u0011Kb榰냎Y#䝀ꀒᳺ'q暇睵s\"!3#I⊆畼寤@HxJ9": false, + "⿾D[)袨㇩i]웪䀤ᛰMvR<蟏㣨": {"v퇓L㪱ꖣ豛톤\\곱#kDTN": [{ + "(쾴䡣,寴ph(C\"㳶w\"憳2s馆E!n!&柄<\/0Pꈗſ?㿳Qd鵔": {"娇堰孹L錮h嵅⛤躏顒?CglN束+쨣ﺜ\\MrH": {"獞䎇둃ቲ弭팭^ꄞ踦涟XK錆쳞ឌ`;੶S炥騞ଋ褂B៎{ڒ䭷ᶼ靜pI荗虶K$": [{"◖S~躘蒉꫿輜譝Q㽙闐@ᢗ¥E榁iء5┄^B[絮跉ᰥ遙PWi3wㄾⵀDJ9!w㞣ᄎ{듒ꓓb6\\篴??c⼰鶹⟧\\鮇ꮇ": [[ + 654120831325413520, + -1.9562073916357608E-19, + { + "DC(昐衵ἡ긙갵姭|֛[t": 7.6979110359897907E18, + "J␅))嫼❳9Xfd飉j7猬ᩉ+⤻眗벎E鰉Zᄊ63zၝ69}ZᶐL崭ᦥ⡦靚⋛ꎨ~i㨃咊ꧭo䰠阀3C(": -3.5844809362512589E17, + "p꣑팱쒬ꎑ뛡Ꙩ挴恍胔&7ᔈ묒4Hd硶훐㎖zꢼ豍㿢aሃ=<\/湉鵲EӅ%$F!퍶棌孼{O駍਺geu+": ")\u001b잓kŀX쩫A밁®ڣ癦狢)扔弒p}k縕ꩋ,䃉tࣼi", + "ァF肿輸<솄G-䢹䛸ꊏl`Tqꕗ蒞a氷⸅ᴉ蠰]S/{J왲m5{9.uέ~㕚㣹u>x8U讁B덺襪盎QhVS맅킃i识{벂磄Iහ䙅xZy/抍૭Z鲁-霳V据挦ℒ": null, + "㯛|Nꐸb7ⵐb?拠O\u0014ކ?-(EꞨ4ꕷᄤYᯕOW瞺~螸\"욿ќe㺰\"'㌢ƐW\u0004瞕>0?V鷵엳": true, + "뤥G\\迋䠿[庩'꼡\u001aiᩮV쯁ᳪ䦪Ô;倱ନ뛁誈": null, + "쥹䄆䚟Q榁䎐᢭<\/2㕣p}HW蟔|䃏꿈ꚉ锳2Pb7㙑Tⅹᵅ": { + "Y?֭$>#cVBꩨ:>eL蒁務": { + "86柡0po 䏚&-捑Ћ祌<\/휃-G*㶢הּ쩍s㶟餇c걺yu꽎還5*턧簕Og婥SꝐ": null, + "a+葞h٥ࠆ裈嗫ﵢ5輙퀟ᛜ,QDﹼ⟶Y騠锪E_|x죗j侵;m蜫轘趥?븅w5+mi콛L": { + ";⯭ﱢ!买F⽍柤鶂n䵣V㫚墱2렾ELEl⣆": [ + true, + -3.6479311868339015E-18, + -7270785619461995400, + 3.334081886177621E18, + 2.581457786298155E18, + -6.605252412954115E-20, + -3.9232347037744167E-20, + { + "B6㊕.k1": null, + "ZAꄮJ鮷ᳱo갘硥鈠䠒츼": { + "ᕅ}럡}.@y陪鶁r業'援퀉x䉴ﵴl퍘):씭脴ᥞhiꃰblﲂ䡲엕8߇M㶭0燋標挝-?PCwe⾕J碻Ᾱ䬈䈥뷰憵賣뵓痬+": {"a췩v礗X⋈耓ፊf罅靮!㔽YYᣓw澍33⎔芲F|\"䜏T↮輦挑6ᓘL侘?ᅥ]덆1R௯✎餘6ꏽ<\/௨\\?q喷ꁫj~@ulq": {"嗫欆뾔Xꆹ4H㌋F嵧]ࠎ]㠖1ꞤT<$m뫏O i댳0䲝i": {"?෩?\u20cd슮|ꯆjs{?d7?eNs⢚嫥氂䡮쎱:鑵롟2hJꎒﯭ鱢3춲亄:뼣v䊭諱Yj択cVmR䩃㘬T\"N홝*ै%x^F\\_s9보zz4淗?q": [ + null, + "?", + 2941869570821073737, + "{5{殇0䝾g6밖퍋臩綹R$䖭j紋釰7sXI繳漪행y", + false, + "aH磂?뛡#惇d婅?Fe,쐘+늵䍘\"3r瘆唊勐j⳧࠴ꇓ<\/唕윈x⬌讣䋵%拗ᛆⰿ妴᝔M2㳗必꧂淲?ゥ젯檢<8끒MidX䏒3᳻Q▮佐UT|⤪봦靏⊏", + [[{ + "颉(&뜸귙{y^\"P퟉춝Ჟ䮭D顡9=?}Y誱<$b뱣RvO8cH煉@tk~4ǂ⤧⩝屋SS;J{vV#剤餓ᯅc?#a6D,s": [ + -7.8781018564821536E16, + true, + [ + -2.28770899315832371E18, + false, + -1.0863912140143876E-20, + -6282721572097446995, + 6767121921199223078, + -2545487755405567831, + false, + null, + -9065970397975641765, + [ + -5.928721243413937E-20, + {"6촊\u001a홯kB0w撨燠룉{绎6⳹!턍贑y▾鱧ժ[;7ᨷ∀*땒䪮1x霆Hᩭ☔\"r䝐7毟ᝰr惃3ꉭE+>僒澐": [ + "Ta쎩aƝt쵯ⰪVb", + [ + -5222472249213580702, + null, + -2851641861541559595, + null, + 4808804630502809099, + 5657671602244269874, + "5犲﨣4mᥣ?yf젫꾯|䋬잁$`Iⳉﴷ扳兝,'c", + false, + [ + null, + { + "DyUIN쎾M仼惀⮥裎岶泭lh扠\u001e礼.tEC癯튻@_Qd4c5S熯A<\/\6U윲蹴Q=%푫汹\\\u20614b[௒C⒥Xe⊇囙b,服3ss땊뢍i~逇PA쇸1": -2.63273619193485312E17, + "Mq꺋貘k휕=nK硍뫞輩>㾆~἞ࡹ긐榵l⋙Hw뮢帋M엳뢯v⅃^": 1877913476688465125, + "ᶴ뻗`~筗免⚽টW˃⽝b犳䓺Iz篤p;乨A\u20ef쩏?疊m㝀컩뫡b탔鄃ᾈV(遢珳=뎲ିeF仢䆡谨8t0醄7㭧瘵⻰컆r厡궥d)a阄፷Ed&c﯄伮1p": null, + "⯁w4曢\"(欷輡": "\"M᭫]䣒頳B\\燧ࠃN㡇j姈g⊸⺌忉ꡥF矉স%^", + "㣡Oᄦ昵⫮Y祎S쐐級㭻撥>{I$": -378474210562741663, + "䛒掷留Q%쓗1*1J*끓헩ᦢ﫫哉쩧EↅIcꅡ\\?ⴊl귛顮4": false, + "寔愆샠5]䗄IH贈=d﯊/偶?ॊn%晥D視N򗘈'᫂⚦|X쵩넽z질tskxDQ莮Aoﱻ뛓": true, + "钣xp?&\u001e侉/y䴼~?U篔蘚缣/I畚?Q绊": -3034854258736382234, + "꺲໣眀)⿷J暘pИfAV삕쳭Nꯗ4々'唄ⶑ伻㷯騑倭D*Ok꧁3b␽_<\/챣Xm톰ၕ䆄`*fl㭀暮滠毡?": [ + "D男p`V뙸擨忝븪9c麺`淂⢦Yw⡢+kzܖ\fY1䬡H歁)벾Z♤溊-혰셢?1<-\u0005;搢Tᐁle\\ᛵߓﭩ榩訝-xJ;巡8깊蠝ﻓU$K": { + "Vꕡ諅搓W=斸s︪vﲜ츧$)iꡟ싉e寳?ጭムVથ嵬i楝Fg<\/Z|៪ꩆ-5'@ꃱ80!燱R쇤t糳]罛逇dṌ֣XHiͦ{": true, + "Ya矲C멗Q9膲墅携휻c\\딶G甔<\/.齵휴": -1.1456247877031811E-19, + "z#.OO￝J": -8263224695871959017, + "崍_3夼ᮟ1F븍뽯ᦓ鴭V豈Ь": [{ + "N蒬74": null, + "yuB?厅vK笗!ᔸcXQ旦컶P-녫mᄉ麟_": "1R@ 톘xa_|﩯遘s槞d!d껀筤⬫薐焵먑D{\\6k共倌☀G~AS_D\"딟쬚뮥馲렓쓠攥WTMܭ8nX㩴䕅檹E\u0007ﭨN 2 ℆涐ꥏ꠵3▙玽|됨_\u2048", + "恐A C䧩G": {":M큣5e들\\ꍀ恼ᔄ靸|I﨏$)n": { + "|U䬫㟯SKV6ꛤ㗮\bn봻䲄fXT:㾯쳤'笓0b/ೢC쳖?2浓uO.䰴": "ཐ꼋e?``,ᚇ慐^8ꜙNM䂱\u0001IᖙꝧM'vKdꌊH牮r\\O@䊷ᓵ쀆(fy聻i툺\"?<\/峧ࣞ⓺ᤤ쵒߯ꎺ騬?)刦\u2072l慪y꺜ﲖTj+u", + "뽫hh䈵w>1ⲏ쐭V[ⅎ\\헑벑F_㖝⠗㫇h恽;῝汰ᱼ瀖J옆9RR셏vsZ柺鶶툤r뢱橾/ꉇ囦FGm\"謗ꉦ⨶쒿⥡%]鵩#ᖣ_蹎 u5|祥?O", + null, + 2.0150326776036215E-19, + null, + true, + false, + true, + {"\fa᭶P捤WWc᠟f뚉ᬏ퓗ⳀW睹5:HXH=q7x찙X$)모r뚥ᆟ!Jﳸf": [ + -2995806398034583407, + [ + 6441377066589744683, + "Mﶒ醹i)Gἦ廃s6몞 KJ౹礎VZ螺费힀\u0000冺업{谥'꡾뱻:.ꘘ굄奉攼Di᷑K鶲y繈욊阓v㻘}枭캗e矮1c?휐\"4\u0005厑莔뀾墓낝⽴洗ṹ䇃糞@b1\u0016즽Y轹", + { + "1⽕⌰鉟픏M㤭n⧴ỼD#%鐘⊯쿼稁븣몐紧ᅇ㓕ᛖcw嬀~ഌ㖓(0r⧦Q䑕髍ര铂㓻R儮\"@ꇱm❈௿᦯頌8}㿹犴?xn잆꥽R": 2.07321075750427366E18, + "˳b18㗈䃟柵Z曆VTAu7+㛂cb0﯑Wp執<\/臋뭡뚋刼틮荋벲TLP预庰܈G\\O@VD'鱃#乖끺*鑪ꬳ?Mޞdﭹ{␇圯쇜㼞顄︖Y홡g": [{ + "0a,FZ": true, + "2z̬蝣ꧦ驸\u0006L↛Ḣ4๚뿀'?lcwᄧ㐮!蓚䃦-|7.飑挴.樵*+1ﮊ\u0010ꛌ%貨啺/JdM:똍!FBe?鰴㨗0O财I藻ʔWA᫓G쳛u`<\/I": [{ + "$τ5V鴐a뾆両環iZp頻යn븃v": -4869131188151215571, + "*즢[⦃b礞R◚nΰꕢH=귰燙[yc誘g䆌?ଜ臛": { + "洤湌鲒)⟻\\䥳va}PeAMnN[": "㐳ɪ/(軆lZR,Cp殍ȮN啷\"3B婴?i=r$펽ᤐ쀸", + "阄R4㒿㯔ڀ69ZᲦ2癁핌噗P崜#\\-쭍袛&鐑/$4童V꩑_ZHA澢fZ3": {"x;P{긳:G閉:9?活H": [ + "繺漮6?z犞焃슳\">ỏ[Ⳛ䌜녏䂹>聵⼶煜Y桥[泥뚩MvK$4jtロ", + "E#갶霠좭㦻ୗ먵F+䪀o蝒ba쮎4X㣵 h", + -335836610224228782, + null, + null, + [ + "r1᫩0>danjY짿bs{", + [ + -9.594464059325631E-23, + 1.0456894622831624E-20, + null, + 5.803973284253454E-20, + -8141787905188892123, + true, + -4735305442504973382, + 9.513150514479281E-20, + "7넳$螔忷㶪}䪪l짴\u0007鹁P鰚HF銏ZJﳴ/⍎1ᷓ忉睇ᜋ쓈x뵠m䷐窥Ꮤ^\u0019ᶌ偭#ヂt☆၃pᎍ臶䟱5$䰵&๵分숝]䝈뉍♂坎\u0011<>", + "C蒑貑藁lﰰ}X喇몛;t밿O7/᯹f\u0015kI嘦<ዴ㟮ᗎZ`GWퟩ瑹࡮ᅴB꿊칈??R校s脚", + { + "9珵戬+AU^洘拻ቒy柭床'粙XG鞕᠜繀伪%]hC,$輙?Ut乖Qm떚W8઼}~q⠪rU䤶CQ痗ig@#≲t샌f㈥酧l;y闥ZH斦e⸬]j⸗?ঢ拻퀆滌": null, + "畯}㧢J罚帐VX㨑>1ꢶkT⿄蘥㝑o|<嗸層沈挄GEOM@-䞚䧰$만峬輏䠱V✩5宸-揂D'㗪yP掶7b⠟J㕻SfP?d}v㼂Ꮕ'猘": { + "陓y잀v>╪": null, + "鬿L+7:됑Y=焠U;킻䯌잫!韎ஔ\f": { + "駫WmGጶ": { + "\\~m6狩K": -2586304199791962143, + "ႜࠀ%͑l⿅D.瑢Dk%0紪dḨTI픸%뗜☓s榗኉\"?V籄7w髄♲쟗翛歂E䤓皹t ?)ᄟ鬲鐜6C": { + "_췤a圷1\u000eB-XOy缿請∎$`쳌eZ~杁튻/蜞`塣৙\"⪰\"沒l}蕌\\롃荫氌.望wZ|o!)Hn獝qg}": null, + "kOSܧ䖨钨:಼鉝ꭝO醧S`십`ꓭ쭁ﯢN&Et㺪馻㍢ⅳ㢺崡ຊ蜚锫\\%ahx켨|ż劻ꎄ㢄쐟A躊᰹p譞綨Ir쿯\u0016ﵚOd럂*僨郀N*b㕷63z": { + ":L5r+T㡲": [{ + "VK泓돲ᮙRy㓤➙Ⱗ38oi}LJቨ7Ó㹡৘*q)1豢⛃e᫛뙪壥镇枝7G藯g㨛oI䄽 孂L缊ꋕ'EN`": -2148138481412096818, + "`⛝ᘑ$(खꊲ⤖ᄁꤒ䦦3=)]Y㢌跨NĴ驳줟秠++d孳>8ᎊ떩EꡣSv룃 쯫أ?#E|᭙㎐?zv:5祉^⋑V": [ + -1.4691944435285607E-19, + 3.4128661569395795E17, + "㐃촗^G9佭龶n募8R厞eEw⺡_ㆱ%⼨D뉄퉠2ꩵᛅⳍ搿L팹Lවn=\"慉념ᛮy>!`g!풲晴[/;?[v겁軇}⤳⤁핏∌T㽲R홓遉㓥", + "愰_⮹T䓒妒閤둥?0aB@㈧g焻-#~跬x<\/舁P݄ꐡ=\\׳P\u0015jᳪᢁq;㯏l%᭗;砢觨▝,謁ꍰGy?躤O黩퍋Y㒝a擯\n7覌똟_䔡]fJ晋IAS", + 4367930106786121250, + -4.9421193149720582E17, + null, + { + ";ᄌ똾柉곟ⰺKpፇ䱻ฺ䖝{o~h!eꁿ઻욄ښ\u0002y?xUd\u207c悜ꌭ": [ + 1.6010824122815255E-19, + [ + "宨︩9앉檥pr쇷?WxLb", + "氇9】J玚\u000f옛呲~ 輠1D嬛,*mW3?n휂糊γ虻*ᴫ꾠?q凐趗Ko↦GT铮", + "㶢ថmO㍔k'诔栀Z蛟}GZ钹D", + false, + -6.366995517736813E-20, + -4894479530745302899, + null, + "V%᫡II璅䅛䓎풹ﱢ/pU9se되뛞x梔~C)䨧䩻蜺(g㘚R?/Ự[忓C뾠ࢤc왈邠买?嫥挤풜隊枕", + ",v碍喔㌲쟚蔚톬៓ꭶ", + 3.9625444752577524E-19, + null, + [ + "kO8란뿒䱕馔b臻⍟隨\"㜮鲣Yq5m퐔K#ꢘug㼈ᝦ=P^6탲@䧔%$CqSw铜랊0&m⟭<\/a逎ym\u0013vᯗ": true, + "洫`|XN뤮\u0018詞=紩鴘_sX)㯅鿻Ố싹": 7.168252736947373E-20, + "ꛊ饤ﴏ袁(逊+~⽫얢鈮艬O힉7D筗S곯w操I斞᠈븘蓷x": [[[[ + -7.3136069426336952E18, + -2.13572396712722688E18, + { + "硢3㇩R:o칢行E<=\u0018ၬYuH!\u00044U%卝炼2>\u001eSi$⓷ꒈ'렢gᙫ番ꯒ㛹럥嶀澈v;葷鄕x蓎\\惩+稘UEᖸﳊ㊈壋N嫿⏾挎,袯苷ኢ\\x|3c": 7540762493381776411, + "?!*^ᢏ窯?\u0001ڔꙃw虜돳FgJ?&⨫*uo籤:?}ꃹ=ٴ惨瓜Z媊@ત戹㔏똩Ԛ耦Wt轁\\枒^\\ꩵ}}}ꀣD\\]6M_⌫)H豣:36섘㑜": { + ";홗ᰰU஋㙛`D왔ཿЃS회爁\u001b-㢈`봆?盂㛣듿ᦾ蒽_AD~EEຆ㊋(eNwk=Rɠ峭q\"5Ἠ婾^>'ls\n8QAK)- Q䲌mo펹L_칍樖庫9꩝쪹ᘹ䑖瀍aK ?*趤f뭓廝p=磕", + "哑z懅ᤏ-ꍹux쀭", + [ + true, + 3998739591332339511, + "ጻ㙙?᳸aK<\/囩U`B3袗ﱱ?\"/k鏔䍧2l@쿎VZ쨎/6ꃭ脥|B?31+on颼-ꮧ,O嫚m ࡭`KH葦:粘i]aSU쓙$쐂f+詛頖b", + [{"^<9<箝&絡;%i﫡2攑紴\\켉h쓙-柂䚝ven\u20f7浯-Ꮏ\r^훁䓚헬\u000e?\\ㅡֺJ떷VOt": [{ + "-௄卶k㘆혐஽y⎱㢬sS઄+^瞥h;ᾷj;抭\u0003밫f<\/5Ⱗ裏_朻%*[-撵䷮彈-芈": { + "㩩p3篊G|宮hz䑊o곥j^Co0": [ + 653239109285256503, + {"궲?|\":N1ۿ氃NZ#깩:쇡o8킗ࡊ[\"됸Po핇1(6鰏$膓}⽐*)渽J'DN<썙긘毦끲Ys칖": { + "2Pr?Xjㆠ?搮/?㓦柖馃5뚣Nᦼ|铢r衴㩖\"甝湗ܝ憍": "\"뾯i띇筝牻$珲/4ka $匝휴译zbAᩁꇸ瑅&뵲衯ꎀᆿ7@ꈋ'ᶨH@ᠴl+", + "7뢽뚐v?4^ꊥ_⪛.>pởr渲<\/⢕疻c\"g䇘vU剺dஔ鮥꒚(dv祴X⼹\\a8y5坆": true, + "o뼄B욞羁hr﷔폘뒚⿛U5pꪴfg!6\\\"爑쏍䢱W<ﶕ\\텣珇oI/BK뺡'谑♟[Ut븷亮g(\"t⡎有?ꬊ躺翁艩nl F⤿蠜": 1695826030502619742, + "ۊ깖>ࡹ햹^ⵕ쌾BnN〳2C䌕tʬ]찠?ݾ2饺蹳ぶꌭ訍\"◹ᬁD鯎4e滨T輀ﵣ੃3\u20f3킙D瘮g\\擦+泙ၧ 鬹ﯨַ肋7놷郟lP冝{ߒhড়r5,꓋": null, + "ΉN$y{}2\\N﹯ⱙK'8ɜͣwt,.钟廣䎘ꆚk媄_": null, + "䎥eᾆᝦ읉,Jުn岪㥐s搖謽䚔5t㯏㰳㱊ZhD䃭f絕s鋡篟a`Q鬃┦鸳n_靂(E4迠_觅뷝_宪D(NL疶hL追V熑%]v肫=惂!㇫5⬒\u001f喺4랪옑": { + "2a輍85먙R㮧㚪Sm}E2yꆣꫨrRym㐱膶ᔨ\\t綾A☰.焄뙗9<쫷챻䒵셴᭛䮜.<\/慌꽒9叻Ok䰊Z㥪幸k": [ + null, + true, + {"쌞쐍": { + "▟GL K2i뛱iQ\"̠.옛1X$}涺]靎懠ڦ늷?tf灟ݞゟ{": 1.227740268699265E-19, + "꒶]퓚%ฬK❅": [{ + "(ෛ@Ǯっ䧼䵤[aテൖvEnAdU렖뗈@볓yꈪ,mԴ|꟢캁(而첸죕CX4Y믅": "2⯩㳿ꢚ훀~迯?᪑\\啚;4X\u20c2襏B箹)俣eỻw䇄", + "75༂f詳䅫ꐧ鏿 }3\u20b5'∓䝱虀f菼Iq鈆﨤g퍩)BFa왢d0뮪痮M鋡nw∵謊;ꝧf美箈ḋ*\u001c`퇚퐋䳫$!V#N㹲抗ⱉ珎(V嵟鬒_b㳅\u0019": null, + "e_m@(i㜀3ꦗ䕯䭰Oc+-련0뭦⢹苿蟰ꂏSV䰭勢덥.ྈ爑Vd,ᕥ=퀍)vz뱊ꈊB_6듯\"?{㒲&㵞뵫疝돡믈%Qw限,?\r枮\"? N~癃ruࡗdn&": null, + "㉹&'Pfs䑜공j<\/?|8oc᧨L7\\pXᭁ 9᪘": -2.423073789014103E18, + "䝄瑄䢸穊f盈᥸,B뾧푗횵B1쟢f\u001f凄": "魖⚝2儉j꼂긾껢嗎0ࢇ纬xI4](੓`蕞;픬\fC\"斒\")2櫷I﹥迧", + "ퟯ詔x悝령+T?Bg⥄섅kOeQ큼㻴*{E靼6氿L缋\u001c둌๶-㥂2==-츫I즃㠐Lg踞ꙂEG貨鞠\"\u0014d'.缗gI-lIb䋱ᎂDy缦?": null, + "紝M㦁犿w浴詟棓쵫G:䜁?V2ힽ7N*n&㖊Nd-'ຊ?-樹DIv⊜)g䑜9뉂ㄹ푍阉~ꅐ쵃#R^\u000bB䌎䦾]p.䀳": [{"ϒ爛\"ꄱ︗竒G䃓-ま帳あ.j)qgu扐徣ਁZ鼗A9A鸦甈!k蔁喙:3T%&㠘+,䷞|챽v䚞문H<\/醯r셓㶾\\a볜卺zE䝷_죤ဵ뿰᎟CB": [ + 6233512720017661219, + null, + -1638543730522713294, + false, + -8901187771615024724, + [ + 3891351109509829590, + true, + false, + -1.03836679125188032E18, + { + "j랎:g曞ѕᘼ}链N", + -1.1103819473845426E-19, + true, + [ + true, + null, + -7.9091791735309888E17, + true, + {"}蔰鋈+ꐨ啵0?g*사%`J?*": [{ + "\"2wG?yn,癷BK\\龞䑞x?蠢": -3.7220345009853505E-19, + ";饹়❀)皋`噿焒j(3⿏w>偍5X薙婏聿3aFÆÝ": "2,ꓴg?_섦_>Y쪥션钺;=趘F~?D㨫\bX?㹤+>/믟kᠪ멅쬂Uzỵ]$珧`m雁瑊ඖ鯬cꙉ梢f묛bB", + "♽n$YjKiXX*GO贩鏃豮祴遞K醞眡}ꗨv嵎꼷0୸+M菋eH徸J꣆:⼐悥B켽迚㯃b諂\u000bjꠜ碱逮m8": [ + "푷᣺ﻯd8ﱖ嬇ភH鹎⡱᱅0g:果6$GQ췎{vᷧYy-脕x偹砡館⮸C蓼ꏚ=軄H犠G谖ES詤Z蠂3l봟hᅭ7䦹1GPQG癸숟~[#駥8zQ뛣J소obg,", + null, + 1513751096373485652, + null, + -6.851466660824754E-19, + {"䩂-⴮2ٰK솖풄꾚ႻP앳1H鷛wmR䗂皎칄?醜<\/&ࠧ㬍X濬䵈K`vJ륒Q/IC묛!;$vϑ": { + "@-ꚗxྐྵ@m瘬\u0010U絨ﮌ驐\\켑寛넆T=tQ㭤L연@脸삯e-:⩼u㎳VQ㋱襗ຓ<Ⅶ䌸cML3+\u001e_C)r\\9+Jn\\Pﺔ8蠱檾萅Pq鐳话T䄐I": -1.80683891195530061E18, + "ᷭዻU~ཷsgSJ`᪅'%㖔n5픆桪砳峣3獮枾䌷⊰呀": { + "Ş੉䓰邟自~X耤pl7间懑徛s첦5ਕXexh⬖鎥᐀nNr(J컗|ૃF\"Q겮葲놔엞^겄+㈆话〾희紐G'E?飕1f❼텬悚泬먐U睬훶Qs": false, + "(\u20dag8큽튣>^Y{뤋.袊䂓;_g]S\u202a꽬L;^'#땏bႌ?C緡<䝲䲝断ꏏ6\u001asD7IK5Wxo8\u0006p弊⼂ꯍ扵\u0003`뵂픋%ꄰ⫙됶l囏尛+䗅E쟇\\": [ + true, + { + "\n鱿aK㝡␒㼙2촹f;`쾏qIࡔG}㝷䐍瓰w늮*粅9뒪ㄊCj倡翑閳R渚MiUO~仨䜶RꙀA僈㉋⦋n{㖥0딿벑逦⥻0h薓쯴Ꝼ": [ + 5188716534221998369, + 2579413015347802508, + 9.010794400256652E-21, + -6.5327297761238093E17, + 1.11635352494065523E18, + -6656281618760253655, + { + "": ")?", + "TWKLꑙ裑꺔UE俸塑炌Ũ᜕-o\"徚#": {"M/癟6!oI51ni퐚=댡>xꍨ\u0004 ?": { + "皭": {"⢫䋖>u%w잼<䕏꘍P䋵$魋拝U䮎緧皇Y훂&|羋ꋕ잿cJ䨈跓齳5\u001a삱籷I꿾뤔S8㌷繖_Yឯ䲱B턼O歵F\\l醴o_欬6籏=D": [ + false, + true, + {"Mt|ꏞD|F궣MQ뵕T,띺k+?㍵i": [ + 7828094884540988137, + false, + { + "!༦鯠,&aﳑ>[euJꏽ綷搐B.h": -7648546591767075632, + "-n켧嘰{7挐毄Y,>❏螵煫乌pv醑Q嶚!|⌝責0왾덢ꏅ蛨S\\)竰'舓Q}A釡5#v": 3344849660672723988, + "8閪麁V=鈢1녈幬6棉⪮둌\u207d᚛驉ꛃ'r䆉惏ै|bἧﺢᒙ<=穊强s혧eꮿ慩⌡ \\槳W븧J檀C,ᘉ의0俯퀉M;筷ࣴ瓿{늊埂鄧_4揸Nn阼Jੵ˥(社": true, + "o뼀vw)4A뢵(a䵢)p姃뛸\u000fK#KiQp\u0005ꅍ芅쏅": null, + "砥$ꥸ┇耽u斮Gc{z빔깎밇\\숰\u001e괷各㶇쵿_ᴄ+h穢p촀Ნ䃬z䝁酳ӂ31xꔄ1_砚W렘G#2葊P ": [ + -3709692921720865059, + null, + [ + 6669892810652602379, + -135535375466621127, + "뎴iO}Z? 馢녱稹ᄾ䐩rSt帤넆&7i騏멗畖9誧鄜'w{Ͻ^2窭외b㑎粖i矪ꦨ탪跣)KEㆹ\u0015V8[W?⽉>'kc$䨘ᮛ뉻٬M5", + 1.10439588726055846E18, + false, + -4349729830749729097, + null, + [ + false, + "_蠢㠝^䟪/D녒㡋ỎC䒈판\u0006એq@O펢%;鹐쏌o戥~A[ꡉ濽ỳ&虃᩾荣唙藍茨Ig楡꒻M窓冉?", + true, + 2.17220752996421728E17, + -5079714907315156164, + -9.960375974658589E-20, + "ᾎ戞༒", + true, + false, + [[ + "ⶉᖌX⧕홇)g엃⹪x뚐癟\u0002", + -5185853871623955469, + { + "L㜤9ợㇶK鐰⋓V뽋˖!斫as|9"፬䆪?7胜&n薑~": -2.11545634977136992E17, + "O8뀩D}캖q萂6༣㏗䈓煮吽ਆᎼDᣘ폛;": false, + "YTᡅ^L㗎cbY$pᣞ縿#fh!ꘂb삵玊颟샞ဢ$䁗鼒몁~rkH^:닮먖츸륈⪺쒉砉?㙓扫㆕꣒`R䢱B酂?C뇞<5Iޚ讳騕S瞦z": null, + "\\RB?`mG댵鉡幐物䵎有5*e骄T㌓ᛪ琾駒Ku\u001a[柆jUq8⋈5鿋츿myﻗ?雍ux঴?": 5828963951918205428, + "n0晅:黯 xu씪^퓞cB㎊ᬍ⺘٤փ~B岚3㥕擄vᲂ~F?C䶖@$m~忔S왖㲚?챴⊟W#벌{'㰝I䝠縁s樘\\X뢻9핡I6菍ㄛ8쯶]wॽ0L\"q": null, + "x增줖j⦦t䏢᎙㛿Yf鼘~꫓恄4惊\u209c": "oOhbᤃ᛽z&Bi犑\\3B㩬劇䄑oŁ쨅孥멁ຖacA㖫借㞝vg싰샂㐜#譞⢤@k]鋰嘘䜾L熶塥_<\/⍾屈ﮊ_mY菹t뙺}Ox=w鮮4S1ꐩמּ'巑", + "㗓蟵ꂾe蠅匳(JP䗏෸\u0089耀왲": [{ + "ᤃ㵥韎뤽\r?挥O쯡⇔㞚3伖\u0005P⋪\"D궣QLn(⚘罩䩢Ŏv䤘尗뼤됛O淽鋋闚r崩a{4箙{煷m6〈": { + "l곺1L": { + "T'ਤ?砅|੬Km]䄩\"(࿶<\/6U爢䫈倔郴l2㴱^줣k'L浖L鰄Rp今鎗⒗C얨M훁㡧ΘX粜뫈N꤇輊㌻켑#㮮샶-䍗룲蠝癜㱐V>=\\I尬癤t=": 7648082845323511446, + "鋞EP:<\/_`ၧe混ㇹBd⯢㮂驋\\q碽饩跓྿ᴜ+j箿렏㗑yK毢宸p謹h䦹乕U媣\\炤": [[ + "3", + [ + true, + 3.4058271399411134E-20, + true, + "揀+憱f逮@먻BpW曉\u001a㣐⎊$n劈D枤㡞좾\u001aᛁ苔౩闝1B䷒Ṋ݋➐ꀞꐃ磍$t੤_:蘺⮼(#N", + 697483894874368636, + [ + "vᘯ锴)0訶}䳅⩚0O壱韈ߜ\u0018*U鍾䏖=䧉뽑单휻ID쿇嘗?ꌸῬ07", + -5.4858784319382006E18, + 7.5467775182251151E18, + -8911128589670029195, + -7531052386005780140, + null, + [ + null, + true, + [[{ + "1欯twG<\/Q:0怯押殃탷聫사<ỗꕧ蚨䡁nDꌕ\u001c녬~蓩鲃g儊>ꏡl㻿/⑷*챳6㻜W毤緛ﹺᨪ4\u0013뺚J髬e3쳸䘦伧?恪&{L掾p+꬜M䏊d娘6": { + "2p첼양棜h䜢﮶aQ*c扦v︥뮓kC寵횂S銩&ǝ{O*य़iH`U큅ࡓr䩕5ꄸ?`\\᧫?ᮼ?t〟崾훈k薐ì/iy꤃뵰z1<\/AQ#뿩8jJ1z@u䕥": 1.82135747285215155E18, + "ZdN &=d년ᅆ'쑏ⅉ:烋5&៏ᄂ汎来L㯄固{钧u\\㊏튚e摑&t嗄ꖄUb❌?m䴘熚9EW": [{ + "ଛ{i*a(": -8.0314147546006822E17, + "⫾ꃆY\u000e+W`௸ \"M뒶+\\뷐lKE}(NT킶Yj選篒쁶'jNQ硾(똡\\\"逌ⴍy? IRꜘ὞鄬﨧:M\\f⠋Cꚜ쫊ᚴNV^D䕗ㅖἔIao꿬C⍏8": [ + 287156137829026547, + { + "H丞N逕⯲": {"": { + "7-;枮阕梒9ᑄZ": [[[[ + null, + { + "": [[[[ + -7.365909561486078E-19, + 2948694324944243408, + null, + [ + true, + "荒\"并孷䂡쵼9o䀘F\u0002龬7⮹Wz%厖/*? a*R枈㌦됾g뒠䤈q딄㺿$쮸tᶎ릑弣^鏎<\/Y鷇驜L鿽<\/춋9Mᲆឨ^<\/庲3'l낢", + "c鮦\u001b두\\~?眾ಢu݆綑෪蘛轋◜gȃ<\/ⴃcpkDt誩܅\"Y", + [[ + null, + null, + [ + 3113744396744005402, + true, + "v(y", + { + "AQ幆h쾜O+꺷铀ꛉ練A蚗⼺螔j㌍3꽂楎䥯뎸먩?": null, + "蠗渗iz鱖w]擪E": 1.2927828494783804E-17, + "튷|䀭n*曎b✿~杤U]Gz鄭kW|㴚#㟗ഠ8u擨": [[ + true, + null, + null, + {"⾪壯톽g7?㥜ώQꑐ㦀恃㧽伓\\*᧰閖樧뢇赸N휶䎈pI氇镊maᬠ탷#X?A+kНM ༑᩟؝?5꧎鰜ṚY즫궔 =ঈ;ﳈ?*s|켦蜌wM笙莔": [ + null, + -3808207793125626469, + [ + -469910450345251234, + 7852761921290328872, + -2.7979740127017492E18, + 1.4458504352519893E-20, + true, + "㽙깹?먏䆢:䴎ۻg殠JBTU⇞}ꄹꗣi#I뵣鉍r혯~脀쏃#釯:场:䔁>䰮o'㼽HZ擓௧nd", + [ + 974441101787238751, + null, + -2.1647718292441327E-19, + 1.03602824249831488E18, + [ + null, + 1.0311977941822604E-17, + false, + true, + { + "": -3.7019778830816707E18, + "E峾恆茍6xLIm縂0n2视֯J-ᤜz+ᨣ跐mYD豍繹⹺䊓몓ﴀE(@詮(!Y膽#᎙2䟓섣A䈀㟎,囪QbK插wcG湎ꤧtG엝x⥏俎j'A一ᯥ뛙6ㅑ鬀": 8999803005418087004, + "よ殳\\zD⧅%Y泥簳Uꈩ*wRL{3#3FYHା[d岀䉯T稉駅䞘礄P:闈W怏ElB㤍喬赔bG䠼U଄Nw鰯闀楈ePsDꥷ꭬⊊": [ + 6.77723657904486E-20, + null, + [ + "ཚ_뷎꾑蹝q'㾱ꂓ钚蘞慵렜떆`ⴹ⎼櫯]J?[t9Ⓢ !컶躔I᮸uz>3a㠕i,錃L$氰텰@7녫W㸮?羧W뇧ꃞ,N鋮숪2ɼ콏┍䁲6", + "&y?뢶=킕올Za惻HZk>c\u20b58i?ꦶcfBv잉ET9j䡡", + "im珊Ճb칧校\\뼾쯀", + 9.555715121193197E-20, + true, + { + "<㫚v6腓㨭e1㕔&&V∌ᗈT奄5Lጥ>탤?튣瑦㳆ꉰ!(ᙪ㿬擇_n쌯IMΉ㕨␰櫈ᱷ5풔蟹&L.첽e鰷쯃劼﫭b#ﭶ퓀7뷄Wr㢈๧Tʴશ㶑澕鍍%": -1810142373373748101, + "fg晌o?߲ꗄ;>C>?=鑰監侯Kt굅": true, + "䫡蓺ꑷ]C蒹㦘\"1ః@呫\u0014NL䏾eg呮፳,r$裢k>/\\?ㄤᇰﻛ쉕1஥'Ċ\" \\_?쨔\"ʾr: 9S䘏禺ᪧꄂ㲄", + [[{ + "*硙^+E쌺I1䀖ju?:⦈Ꞓl๴竣迃xKC/饉:\fl\"XTFᄄ蟭,芢<\/骡軺띜hꏘ\u001f銿<棔햳▨(궆*=乥b8\\媦䷀뫝}닶ꇭ(Kej䤑M": [{ + "1Ꮼ?>옿I╅C<ގ?ꊌ冉SV5A㢊㶆z-๎玶绢2F뵨@㉌뀌o嶔f9-庒茪珓뷳4": null, + ";lᰳ": "CbB+肻a䄷苝*/볳+/4fq=㰁h6瘉샴4铢Y骐.⌖@哼猎㦞+'gꋸ㒕ߤ㞑(䶒跲ti⑴a硂#No볔", + "t?/jE幸YHT셵⩎K!Eq糦ꗣv刴w\"l$ο:=6:移": { + "z]鑪醊嫗J-Xm銌翁絨c里됏炙Ep㣋鏣똼嚌䀓GP﹖cmf4鹭T䅿꣭姧␸wy6ꦶ;S&(}ᎧKxᾂQ|t뻳k\"d6\"|Ml췆hwLt꼼4$&8Պ褵婶鯀9": {"嵃닢ᒯ'd᧫䳳#NXe3-붋鸿ଢ떓%dK\u0013䲎ꖍYV.裸R⍉rR3蟛\\:젯:南ĺLʆ넕>|텩鴷矔ꋅⒹ{t孶㓑4_": [ + true, + null, + [ + false, + "l怨콈lᏒ", + { + "0w䲏嬧-:`䉅쉇漧\\܂yㄨb%㽄j7ᦶ涶<": 3.7899452730383747E-19, + "ꯛTẀq纤q嶏V⿣?\"g}ი艹(쥯B T騠I=仵및X": {"KX6颠+&ᅃ^f畒y[": { + "H?뱜^?꤂-⦲1a㋞&ꍃ精Ii᤾챪咽쬘唂쫷<땡劈훫놡o㥂\\ KⴙD秼F氮[{'좴:례晰Iq+I쭥_T綺砸GO煝䟪ᚪ`↹l羉q쐼D꽁ᜅ훦: vUV": true, + "u^yﳍ0㱓#[y뜌앸ꊬL㷩?蕶蘾⻍KӼ": -7931695755102841701, + "䤬轉車>\u001c鴵惋\"$쯃྆⇻n뽀G氠S坪]ಲꨍ捇Qxኻ椕駔\\9ࣼ﫻읜磡煮뺪ᶚ볝l㕆t+sζ": [[[ + true, + false, + [ + null, + 3363739578828074923, + true, + { + "\"鸣詩 볰㑵gL㯦῅춝旫}ED辗ﮈI쀤-ꧤ|㠦Z\"娑ᕸ4爏騍㣐\"]쳝Af]茛⬻싦o蚁k䢯䩐菽3廇喑ޅ": 4.5017999150704666E17, + "TYႇ7ʠ值4챳唤~Zo&ݛ": false, + "`塄J袛㭆끺㳀N㺣`꽐嶥KﯝSVᶔ∲퀠獾N딂X\"ᤏhNﬨvI": {"\u20bb㭘I䖵䰼?sw䂷쇪](泒f\"~;꼪Fԝsᝦ": {"p,'ꉂ軿=A蚶?bƉ㏵䅰諬'LYKL6B깯⋩겦뎙(ᜭ\u0006噣d꾆㗼Z;䄝䚔cd<情@䞂3苼㸲U{)<6&ꩻ钛\u001au〷N숨囖愙j=BXW욕^x芜堏Ῑ爂뛷꒻t✘Q\b": [[ + "籛&ଃ䩹.ꃩ㦔\\C颫#暪&!勹ꇶ놽攺J堬镙~軌C'꾖䣹㮅岃ᙴ鵣", + 4.317829988264744E15, + 6.013585322002147E-20, + false, + true, + null, + null, + -3.084633632357326E-20, + false, + null, + { + "\"짫愔昻 X\"藣j\"\"먁ཅѻ㘤㬯0晲DU꟒㸃d벀윒l䦾c੻*3": null, + "谈Wm陧阦咟ฯ歖擓N喴㋐銭rCCnVࢥ^♼Ⅾ젲씗刊S༝+_t赔\\b䚍뉨ꬫ6펛cL䊘᜼<\/澤pF懽&H": [ + null, + { + "W\"HDUuΌ퀟M'P4࿰H똆ⰱﮯ<\/凐蘲\"C鴫ﭒж}ꭩ쥾t5yd诪ﮡ퍉ⴰ@?氐醳rj4I6Qt": 6.9090159359219891E17, + "絛ﳛ⺂": {"諰P㗮聦`ZQ?ꫦh*റcb⧱}埌茥h{棩렛툽o3钛5鮁l7Q榛6_g)ὄ\u0013kj뤬^爖eO4Ⱈ槞鉨ͺ订%qX0T썗嫷$?\\\"봅늆'%": [ + -2.348150870600346E-19, + [[ + true, + -6619392047819511778, + false, + [[ + -1.2929189982356161E-20, + 1.7417192219309838E-19, + {"?嵲2࿐2\u0001啑㷳c縯": [ + null, + [ + false, + true, + 2578060295690793218, + { + "?\"殃呎#㑑F": true, + "}F炊_殛oU헢兔Ꝉ,赭9703.B数gTz3⏬": { + "5&t3,햓Mݸᵣ㴵;꣫䩍↳#@뫷䠅+W-ࣇzᓃ鿕ಔ梭?T䮑ꥬ旴]u뫵막bB讍:왳둛lEh=숾鱠p咐$짏#?g⹷ᗊv㷵.斈u頻\u0018-G.": "뽙m-ouࣤ஫牷\"`Ksꕞ筼3HlȨvC堈\"I]㖡玎r먞#'W賜鴇k'c룼髋䆿飉㗆xg巤9;芔cጐ/ax䊨♢큓r吓㸫೼䢗da᩾\"]屣`", + ":M딪<䢥喠\u0013㖅x9蕐㑂XO]f*Q呰瞊吭VP@9,㨣 D\\穎vˤƩs㜂-曱唅L걬/롬j㈹EB8g<\/섩o渀\"u0y&룣": ">氍緩L/䕑돯Ꟙ蕞^aB뒣+0jK⪄瑨痜LXK^힦1qK{淚t츔X:Vm{2r獁B뾄H첚7氥?쉟䨗ꠂv팳圎踁齀\\", + "D彤5㢷Gꪻ[lㄆ@὜⓰絳[ଃ獽쮹☒[*0ꑚ㜳": 9022717159376231865, + "ҖaV銣tW+$魿\u20c3亜~뫡ᙰ禿쨽㏡fṼzE/h": "5臐㋇Ჯ쮺? 昨탰Wム밎#'\"崲钅U?幫뺀⍾@4kh>騧\\0ҾEV=爐͌U捀%ꉼ 㮋<{j]{R>:gԩL\u001c瀈锌ﯲﳡꚒ'⫿E4暍㌗뵉X\"H᝜", + "ᱚגּ;s醒}犍SἿ㦣&{T$jkB\\\tḮ앾䤹o<避(tW": "vb⯽䴪䮢@|)", + "⥒퐁껉%惀뗌+녣迺顀q條g⚯i⤭룐M琹j̈́⽜A": -8385214638503106917, + "逨ꊶZ<\/W⫟솪㎮ᘇb?ꠔi\"H㧺x෷韒Xꫨฟ|]窽\u001a熑}Agn?Mᶖa9韲4$3Ỵ^=쏍煤ፐ돷2䣃%鷠/eQ9頸쥎", + 2398360204813891033, + false, + 3.2658897259932633E-19, + null, + "?ꚃ8Nn㞷幵d䲳䱲뀙ꪛQ瑓鎴]䩋-鰾捡䳡??掊", + false, + -1309779089385483661, + "ᦲxu_/yecR.6芏.ᜇ過 ~", + -5658779764160586501, + "쒌:曠=l썜䢜wk#s蕚\"互㮉m䉤~0듐䋙#G;h숄옥顇෤勹(C7㢅雚㐯L⠅VV簅<", + null, + -4.664877097240962E18, + -4.1931322262828017E18, + { + ",": { + "v㮟麑䄠뤵g{M띮.\u001bzt뢜뵡0Ǥ龍떟Ᾰ怷ϓRT@Lꀌ樂U㏠⾕e扉|bJg(뵒㠶唺~ꂿ(땉x⻫싉쁊;%0鎻V(o\f,N鏊%nk郼螺": -1.73631993428376141E18, + "쟧摑繮Q@Rᕾ㭚㾣4隅待㓎3蒟": [ + 4971487283312058201, + 8973067552274458613, + { + "`a揙ᣗ\u0015iBo¸": 4.3236479112537999E18, + "HW&퉡ぁ圍Y?瑡Qy훍q!帰敏s舠㫸zꚗaS歲v`G株巷Jp6킼 (귶鍔⾏⡈>M汐㞍ቴ꙲dv@i㳓ᇆ?黍": [ + null, + 4997607199327183467, + "E㻎蠫ᐾ高䙟蘬洼旾﫠텛㇛?'M$㣒蔸=A_亀绉앭rN帮", + null, + [{ + "Eᑞ)8餧A5u&㗾q?": [ + -1.969987519306507E-19, + null, + [ + 3.42437673373841E-20, + true, + "e걷M墁\"割P␛퍧厀R䱜3ﻴO퓫r﹉⹊", + [ + -8164221302779285367, + [ + true, + null, + "爘y^-?蘞Ⲽꪓa␅ꍨ}I", + 1.4645984996724427E-19, + [{ + "tY좗⧑mrzﺝ㿥ⴖ᥷j諅\u0000q賋譁Ꞅ⮱S\nࡣB/큃굪3Zɑ复o<\/;롋": null, + "彟h浠_|V4䦭Dᙣ♞u쿻=삮㍦\u001e哀鬌": [{"6횣楠,qʎꗇ鎆빙]㱭R굋鈌%栲j分僅ペ䇰w폦p蛃N溈ꡐꏀ?@(GI뉬$ﮄ9誁ꓚ2e甸ڋ[䁺,\u0011\u001cࢃ=\\+衪䷨ᯕ鬸K": [[ + "ㅩ拏鈩勥\u000etgWVXs陂規p狵w퓼{뮵_i\u0002ퟑႢ⬐d6鋫F~챿搟\u0096䚼1ۼ칥0꣯儏=鋷牋ⅈꍞ龐", + -7283717290969427831, + true, + [ + 4911644391234541055, + { + "I鈒첽P릜朸W徨觘-Hᎄ퐟⓺>8kr1{겵䍃〛ᬡ̨O귑o䝕'쿡鉕p5": "fv粖RN瞖蛐a?q꤄\u001d⸥}'ꣴ犿ꦼ?뤋?鵆쥴덋䡫s矷̄?ඣ/;괱絢oWfV<\/\u202cC,㖦0䑾%n賹g&T;|lj_欂N4w", + "짨䠗;䌕u i+r๏0": [{"9䥁\\఩8\"馇z䇔<\/ႡY3e狚쐡\"ุ6ﰆZ遖c\"Ll:ꮾ疣<\/᭙O◌납୕湞9⡳Und㫜\u0018^4pj1;䧐儂䗷ୗ>@e톬": { + "a⑂F鋻Q螰'<퇽Q贝瀧{ᘪ,cP&~䮃Z?gI彃": [ + -1.69158726118025933E18, + [ + "궂z簽㔛㮨瘥⤜䛖Gℤ逆Y⪾j08Sn昞ꘔ캻禀鴚P謦b{ꓮmN靐Mᥙ5\"睏2냑I\u0011.L&=?6ᄠ뻷X鸌t刑\"#z)o꫚n쳟줋", + null, + 7517598198523963704, + "ኑQp襟`uᩄr方]*F48ꔵn俺ሙ9뇒", + null, + null, + 6645782462773449868, + 1219168146640438184, + null, + { + ")ယ넌竀Sd䰾zq⫣⏌ʥ\u0010ΐ' |磪&p牢蔑mV蘸૰짬꺵;K": [ + -7.539062290108008E-20, + [ + true, + false, + null, + true, + 6574577753576444630, + [[ + 1.2760162530699766E-19, + [ + null, + [ + "顊\\憎zXB,", + [{ + "㇆{CVC9-MN㜋ઘR눽#{h@ퟨ!鼚׼XOvXS\u0017ᝣ=cS+梽៲綆16s덽휐y屬?ᇳG2ᴭ\u00054쫖y룇nKcW̭炦s/鰘ᬽ?J|퓀髣n勌\u0010홠P>j": false, + "箴": [ + false, + "鍞j\"ꮾ*엇칬瘫xṬ⭽쩁䃳\"-⋵?ᦽ댎Ĝ": true, + "Pg帯佃籛n㔠⭹࠳뷏≻࿟3㞱!-쒾!}쭪䃕!籿n涻J5ਲ਼yvy;Rኂ%ᔡጀ裃;M⣼)쵂쑈": 1.80447711803435366E18, + "ꈑC⡂ᑆ㤉壂뎃Xub<\/쀆༈憓ق쨐ק\\": [ + 7706977185172797197, + {"": {"K╥踮砆NWࡆFy韣7ä밥{|紒︧䃀榫rᩛꦡTSy잺iH8}ퟴ,M?Ʂ勺ᴹ@T@~꾂=I㙕뾰_涀쑜嫴曣8IY?ҿo줫fऒ}\\S\"ᦨ뵼#nDX": { + "♘k6?଱癫d68?㽚乳䬳-V顷\u0005蝕?\u0018䞊V{邾zじl]雏k臤~ൖH뒐iꢥ]g?.G碄懺䔛pR$䅒X觨l봜A刊8R梒',}u邩퉕?;91Ea䈈믁G⊶芔h袪&廣㺄j;㡏綽\u001bN頸쳘橆": -2272208444812560733, + "拑Wﵚj鵼駳Oࣿ)#㾅顂N傓纝y僱栜'Bꐍ-!KF*ꭇK¦?䈴^:啤wG逭w᧯": "xᣱmYe1ۏ@霄F$ě꧘푫O䤕퀐Pq52憬ꀜ兴㑗ᡚ?L鷝ퟐ뭐zJꑙ}╆ᅨJB]\"袌㺲u8䯆f", + "꿽၅㔂긱Ǧ?SI": -1669030251960539193, + "쇝ɨ`!葎>瞺瘡驷錶❤ﻮ酜=": -6961311505642101651, + "?f7♄꫄Jᡔ훮e읇퍾፣䭴KhखT;Qty}O\\|뫁IῒNe(5惁ꥶㆷY9ﮡ\\ oy⭖-䆩婁m#x봉>Y鈕E疣s驇↙ᙰm<": {"퉻:dꂁ&efᅫ쫢[\"돈늖꺙|Ô剐1͖-K:ʚ᭕/;쏖㷛]I痐职4gZ4⍜kเꛘZ⥺\\Bʫᇩ鄨魢弞&幟ᓮ2̊盜", + -9006004849098116748, + -3118404930403695681, + { + "_彃Y艘-\"Xx㤩㳷瑃?%2䐡鵛o귵옔夘v*탋职&㳈챗|O钧": [ + false, + "daꧺdᗹ羞쯧H㍤鄳頳<型孒ン냆㹀f4㹰\u000f|C*ሟ鰠(O<ꨭ峹ipຠ*y೧4VQ蔔hV淬{?ᵌEfrI_", + "j;ꗣ밷邍副]ᗓ", + -4299029053086432759, + -5610837526958786727, + [ + null, + [ + -1.3958390678662759E-19, + { + "lh좈T_믝Y\"伨\u001cꔌG爔겕ꫳ晚踍⿻읐T䯎]~e#฽燇\"5hٔ嶰`泯r;ᗜ쮪Q):/t筑,榄&5懶뎫狝(": [{ + "2ፁⓛ]r3C攟וּ9賵s⛔6'ஂ|\"ⵈ鶆䐹禝3\"痰ࢤ霏䵩옆䌀?栕r7O簂Isd?K᫜`^讶}z8?z얰T:X倫⨎ꑹ": -6731128077618251511, + "|︦僰~m漿햭\\Y1'Vvخ굇ቍ챢c趖": [null] + }], + "虌魿閆5⛔煊뎰㞤ᗴꥰF䮥蘦䂪樳-K᝷-(^\u20dd_": 2.11318679791770592E17 + } + ] + ] + ]}, + "묗E䀳㧯᳀逞GMc\b墹㓄끖Ơ&U??펌鑍 媋k))ᄊ": null, + "묥7콽벼諌J_DɯﮪM殴䣏,煚ྼ`Y:씧<\/⩫%yf䦀!1Ჶk춎Q米W∠WC跉鬽*ᛱi㴕L꘻ꀏ쓪\"_g鿄'#t⽙?,Wg㥖|D鑆e⥏쪸僬h鯔咼ඡ;4TK聎졠嫞" + } + ] + ] + } + ] + ] + ]}} + } + ]} + }, + "뿋뀾淣截䔲踀&XJ펖꙯^Xb訅ꫥgᬐ>棟S\"혧騾밫겁7-": "擹8C憎W\"쵮yR뢩浗絆䠣簿9䏈引Wcy䤶孖ꯥ;퐌]輩䍐3@{叝 뽸0ᡈ쵡Ⲇ\u001dL匁꧐2F~ݕ㪂@W^靽L襒ᦘ~沦zZ棸!꒲栬R" + } + ] + ], + "Z:덃൛5Iz찇䅄駠㭧蓡K1": "e8᧤좱U%?ⵇ䯿鿝\u0013縮R∱骒EO\u000fg?幤@֗퉙vU`", + "䐃쪈埽້=Ij,쭗쓇చ": false + }]}} + ] + } + ]} + } + ] + ] + ], + "咰긖VM]᝼6䓑쇎琺etDҌ?㞏ꩄ퇫밉gj8蠃\"⩐5䛹1ࣚ㵪": "ക蹊?⎲⧘⾚̀I#\"䈈⦞돷`wo窭戕෱휾䃼)앷嵃꾞稧,Ⴆ윧9S?೗EMk3Მ3+e{⹔Te驨7䵒?타Ulg悳o43" + } + ], + "zQᤚ纂땺6#ٽ﹧v￿#ࠫ휊冟蹧텈ꃊʆ?&a䥯De潝|쿓pt瓞㭻啹^盚2Ꝋf醪,얏T窧\\Di䕎谄nn父ꋊE": -2914269627845628872, + "䉩跐|㨻ᷢ㝉B{蓧瞸`I!℄욃힕#ೲᙾ竛ᔺCjk췒늕貭词\u0017署?W딚%(pꍁ⤼띳^=on뺲l䆼bzrﳨ[&j狸䠠=ᜑꦦ\u2061յnj=牲攑)M\\龏": false, + "뎕y絬᫡⥮Ϙᯑ㌔/NF*˓.,QEzvK!Iwz?|쥾\"ꩻL꼗Bꔧ賴緜s뉣隤茛>ロ?(?^`>冺飒=噸泥⺭Ᲊ婓鎔븜z^坷裮êⓅ໗jM7ﶕ找\\O": 1.376745434746303E-19 + }, + "䐛r滖w㏤,|Nዜ": false + } + ]], + "@꿙?薕尬 gd晆(띄5躕ﻫS蔺4)떒錸瓍?~": 1665108992286702624, + "w믍nᏠ=`঺ᅥC>'從됐槷䤝眷螄㎻揰扰XᅧC贽uჍ낟jKD03T!lDV쀉Ӊy뢖,袛!终캨G?鉮Q)⑗1쾅庅O4ꁉH7?d\u0010蠈줘월ސ粯Q!낇껉6텝|{": null, + "~˷jg쿤촖쉯y": -5.5527605669177098E18, + "펅Wᶺzꐆと푭e?4j仪열[D<鈑皶婆䵽ehS?袪;HꍨM뗎ば[(嗏M3q퍟g4y╸鰧茀[Bi盤~﫝唎鋆彺⦊q?B4쉓癚O洙킋툈䶯_?ퟲ": null + } + ] + ]] + ]], + "꟱Ԕ㍤7曁聯ಃ錐V䷰?v㪃૦~K\"$%请|ꇹn\"k䫛㏨鲨\u2023䄢\u0004[︊VJ?䶟ាꮈ䗱=깘U빩": -4863152493797013264 + } + ]}]} + ] + }}} + ], + "쏷쐲۹퉃~aE唙a챑,9㮹gLHd'䔏|킗㍞䎥&KZYT맵7䥺Nⱳ同莞鿧w\\༌疣n/+ꎥU\"封랾○ퟙAJᭌ?9䛝$?驔9讐짘魡T֯c藳`虉C읇쐦T" + } + ], + "谶개gTR￐>ၵ͚dt晑䉇陏滺}9㉸P漄": -3350307268584339381 + }] + ] + ] + ]] + ] + ], + "0y꟭馋X뱔瑇:䌚￐廿jg-懲鸭䷭垤㒬茭u賚찶ಽ+\\mT땱\u20821殑㐄J쩩䭛ꬿNS潔*d\\X,壠뒦e殟%LxG9:摸": 3737064585881894882, + "풵O^-⧧ⅶvѪ8廸鉵㈉ר↝Q㿴뺟EႳvNM:磇>w/៻唎뷭୥!냹D䯙i뵱貁C#⼉NH6`柴ʗ#\\!2䂗Ⱨf?諳.P덈-返I꘶6?8ꐘ": -8934657287877777844, + "溎-蘍寃i诖ര\"汵\"\ftl,?d⼡쾪⺋h匱[,෩I8MҧF{k瓿PA'橸ꩯ綷퉲翓": null + } + ] + ], + "ោ係؁<元": 1.7926963090826924E-18 + }}] + } + ] + ]]}] + }] + ] + ] + ] + ], + "ጩV<\"ڸsOᤘ": 2.0527167903723048E-19 + }] + ]} + ] + ]], + "∳㙰3젴p᧗䱙?`yZA8Ez0,^ᙛ4_0븢\u001ft:~䎼s.bb룦明yNP8弆C偯;⪾짍'蕴뮛": -6976654157771105701, + "큵ꦀ\\㇑:nv+뒤燻䀪ﴣ﷍9ᚈ኷K㚊誦撪䚛,ꮪxሲ쳊\u0005HSf?asg昱dqꬌVꙇ㼺'k*'㈈": -5.937042203633044E-20 + } + ] + }], + "?}\u20e0],s嶳菋@#2u쒴sQS䩗=ꥮ;烌,|ꘔ䘆": "ᅩ영N璠kZ먕眻?2ቲ芋眑D륟渂⸑ﴃIRE]啗`K'" + }}, + "쨀jmV賂ﰊ姐䂦玞㬙ᏪM᪟Վ씜~`uOn*ॠ8\u000ef6??\\@/?9見d筜ﳋB|S䝬葫㽁o": true + }, + "즛ꄤ酳艚␂㺘봿㎨iG৕ࡿ?1\"䘓您\u001fSኝ⺿溏zៀ뻤B\u0019?윐a䳵᭱䉺膷d:<\/": 3935553551038864272 + } + ] + ]} + ]] + ]] + ]} + } + ] + } + ]]}}, + "᥺3h↛!ꋰy\"攜(ெl䪕oUkc1A㘞ᡲ촾ᣫ<\/䒌E㛝潨i{v?W౾H\\RჅpz蝬R脾;v:碽✘↯삞鷱o㸧瑠jcmK7㶧뾥찲n": true, + "ⶸ?x䊺⬝-䰅≁!e쩆2ꎿ准G踌XXᩯ1߁}0?.헀Z馟;稄\baDꟹ{-寪⚈ꉷ鮸_L7ƽᾚ<\u001bጨA䧆송뇵⨔\\礍뗔d设룱㶉cq{HyぱR㥽吢ſtp": -7985372423148569301, + "緫#콮IB6<\/=5Eh礹\t8럭@饹韠r㰛斣$甝LV췐a갵'请o0g:^": "䔨(.", + "띳℡圤pン௄ĝ倧訜B쁟G䙔\"Sb⓮;$$▏S1J뢙SF|赡g*\"Vu䲌y": "䪈&틐),\\kT鬜1풥;뷴'Zေ䩹@J鞽NぼM?坥eWb6榀ƩZڮ淽⺞삳煳xჿ絯8eⶍ羷V}ჿ쎱䄫R뱃9Z>'\u20f1ⓕ䏜齮" + } + ] + ]]] + }} + } + ] + ]}, + "펮b.h粔폯2npX詫g錰鷇㇒<쐙S値bBi@?镬矉`剔}c2壧ଭfhY깨R()痩⺃a\\⍔?M&ﯟ<劜꺄멊ᄟA\"_=": null + }, + "~潹Rqn榢㆓aR鬨侅?䜑亡V_翅㭔(䓷w劸ၳDp䀅<\/ﰎ鶊m䵱팱긽ꆘ긓准D3掱;o:_ќ)껚콥8곤d矦8nP倥ꃸI": null, + "뾎/Q㣩㫸벯➡㠦◕挮a鶧⋓偼\u00001뱓fm覞n?㛅\"": 2.8515592202045408E17 + }], + ",": -5426918750465854828, + "2櫫@0柡g䢻/gꆑ6演&D稒肩Y?艘/놘p{f투`飷ᒉ챻돎<늛䘍ﴡ줰쫄": false, + "8(鸑嵀⵹ퟡ<9㣎Tߗ┘d슒ل蘯&㠦뮮eࠍk砝g 엻": false, + "d-\u208b?0ﳮ嵙'(J`蔿d^踅⤔榥\\J⵲v7": 6.8002426206715341E17, + "ཎ耰큓ꐕ㱷\u0013y=詽I\"盈xm{0쾽倻䉚ષso#鰑/8㸴짯%ꀄ떸b츟*\\鲷礬ZQ兩?np㋄椂榨kc᡹醅3": false, + "싊j20": false + }]] + ]], + "俛\u0017n緽Tu뫉蜍鼟烬.ꭠIⰓ\"Ἀ᜾uC쎆J@古%ꛍm뻨ᾀ画蛐휃T:錖㑸ዚ9죡$": true + } + ] + ], + "㍵⇘ꦖ辈s}㱮慀밒s`\"㞟j:`i픻Z섫^諎0Ok{켿歁෣胰a2﨤[탳뚬쎼嫭뉮m": 409440660915023105, + "w墄#*ᢄ峠밮jLa`ㆪ꺊漓Lで끎!Agk'ꁛ뢃㯐岬D#㒦": false, + "ଦPGI䕺L몥罭ꃑ궩﮶#⮈ᢓӢ䚬p7웼臧%~S菠␌힀6&t䳙y㪘냏\\*;鉏ᅧ鿵'嗕pa\"oL쇿꬈Cg": "㶽1灸D⟸䴅ᆤ뉎﷛渤csx 䝔цꬃ锚捬?ຽ+x~꘩uI࡞\u0007栲5呚ẓem?袝\")=㥴䨃pac!/揎Y", + "ᷱo\\||뎂몷r篙|#X䦜I#딌媸픕叞RD斳X4t⯩夬=[뭲r=绥jh뷱츝⪘%]⚋܈㖴スH텹m(WO曝劉0~K3c柢Ր㏉着逳~": false, + "煽_qb[첑\\륌wE❽ZtCNﭝ+餌ᕜOꛭ": "{ﳾ쉌&s惧ᭁⵆ3䢫;䨞팑꒪흘褀࢖Q䠿V5뭀䎂澻%받u5텸oA⮥U㎦;B䳌wz䕙$ឿ\\௅婺돵⪾퐆\\`Kyौꋟ._\u0006L챯l뇠Hi䧈偒5", + "艊佁ࣃ롇䱠爬!*;⨣捎慓q靓|儑ᨋL+迥=6㒺딉6弄3辅J-㕎뛄듘SG㆛(\noAzQꝱ䰩X*ぢO퀌%펠낌mo틮a^<\/F&_눊ᾉ㨦ы4\"8H": 2974648459619059400, + "鬙@뎣䫳ၮ끡?){y?5K;TA*k溱䫜J汃ꂯ싔썍\u001dA}룖(<\/^,": false, + "몏@QꋦFꊩᒐ뎶lXl垨4^郣|ꮇ;䝴ᝓ}쵲z珖": null + } + ]]]], + ":_=닧弗D䙋暨鏛. 㱻붘䂍J儒&ZK/녩䪜r囁⽯D喠죥7⹌䪥c\u001a\u2076￞妈朹oLk菮F౟覛쐧㮏7T;}蛙2{9\"崓bB<\/⡷룀;즮鿹)丒툃୤뷠5W⊢嶜(fb뭳갣": "E{响1WM" + }}, + "䘨tjJ驳豨?y輊M*᳑梵瞻઻ofQG瑮e": 2.222802939724948E-19, + "䮴=❑➶T෋w䞜\"垦ꃼUt\u001dx;B$뵣䙶E↌艣ᡥ!᧟;䱀[䔯k쬃`੍8饙른熏'2_'袻tGf蒭J땟as꯳╖&啒zWࡇᒫYSᏬ\u0014ℑ첥鈤|cG~Pᓮ\">\"": "ႆl\f7V儊㦬nHꄬꨧC{쐢~C⮃⛓嶦vꄎ1w鰠嘩뿠魄&\"_qMⵖ釔녮ꝇ 㝚{糍J哋 cv?-jkﻯྌ鹑L舟r", + "龧葆yB✱H盋夔ﶉ?n*0(": "ꧣኆ㢓氥qZZ酒ຜ)鮢樛)X䣆gTSґG텞k.J圬疝롫쯭z L:\\ྤ@w炋塜쿖ᾳy뢀䶃뱝N䥨㚔勇겁#p", + "도畎Q娡\"@S/뼋:䵏!P衅촚fVHQs✜ᐫi㻑殡B䜇%믚k*U#濨낄~": "ꍟዕ쳸ꍈ敋&l妏\u0005憡멗瘌uPgᅪm<\/To쯬锩h뒓k" + } + ] + }], + "墥홞r绚<\/⸹ⰃB}<躅\\Y;๑@䔸>韫䜲뱀X뗩鿥쩗SI%ﴞ㳕䛇?<\/\u00018x\\&侂9鋙a[LR㋭W胕)⡿8㞙0JF,}?허d1cDMᐃ␛鄝ⱕ%X)!XQ": "ⳍꗳ=橇a;3t⦾꼑仈ူaᚯ⯋ꕃAs鴷N⍕_䎃ꙎAz\u0016䯷\\<࿫>8q{}キ?ᣰ}'0ᴕ펓B┦lF#趤厃T?㕊#撹圂䆲" + }, + "܋닐龫論c웑": false, + "ㇿ/q\"6-co髨휝C큦#\u001b4~?3䐹E삇<<": 7.600917488140322E-20, + "䁝E6?㣖ꃁ间t祗*鑠{ḣV(浾h逇큞=W?ૉ?nꇽ8ꅉຉj으쮺@Ꚅ㰤u]Oyr": "v≁᫸_*όAඤԆl)ۓᦇQ}폠z༏q滚", + "ソ᥊/넺I": true + }]] + ] + ] + ] + ]] + }, + "䭑Ik攑\u0002QV烄:芩.麑㟴㘨≕": true, + "坄꿕C쇻풉~崍%碼\\8\"䬦꣙": null, + "欌L圬䅘Y8c(♺2?ON}o椳s宥2䉀eJ%闹r冁O^K諭%凞⺉⡻,掜?$ꥉ?略焕찳㯊艼誜4?\"﯎<゛XፈINT:詓 +": -1.0750456770694562E-19, + "獒àc뜭싼ﺳ뎤K`]p隨LtE": null, + "甙8䵊神EIꩤ鐯ᢀ,ﵮU䝑u疒ử驺䚿≚ഋ梶秓F`覤譐#짾蔀묊4<媍쬦靪_Yzgcࡶ4k紥`kc[Lﮗ簐*I瀑[⾰L殽鑥_mGȠ<\/|囹灠g桰iri": true, + "챓ꖙꟻ좝菇ou,嗠0\\jK핻뜠qwQ?ഩ㼕3Y彦b\u009bJ榶N棨f?됦鏖綃6鳵M[OE봨u햏.Ꮁ癜蟳뽲ꩌ뻾rM豈R嗀羫 uDꎚ%": null + }, + "V傜2<": 7175127699521359521 + }], + "铫aG切<\/\"ী⊆e<^g࢛)D顝nאַ饼\u008c猪繩嵿ﱚCꡬ㻊g엺A엦\u000f暿_f꿤볝㦕桦`蒦䎔j甬%岝rj 糏": "䚢偎눴Au<4箞7礦Iﱔ坠eȧ䪸u䵁p|逹$嗫쨘ꖾ﷐!胠z寓팢^㨔|u8Nሇe텔ꅦ抷]،鹎㳁#༔繁 ", + "낂乕ꃻ볨ϱ-ꇋ㖍fs⿫)zꜦ/K?솞♞ꑌ宭hJ᤭瑥Fu": false, + "쟰ぜ魛G\u0003u?`㾕ℾ㣭5螠烶這趩ꖢ:@咕ꐶx뒘느m䰨b痃렐0鳊喵熬딃$摉_~7*ⱦ녯1錾GKhJ惎秴6'H妈Tᧅ窹㺒疄矤铟wላ": null, + "쯆q4!3錕㲏ⵆ㇛꘷Z瑩뭆\\◪NH\u001d\\㽰U~㯶<\"쑣낞3ᵤ'峉eꢬ;鬹o꣒木X*長PXᘱu\"䠹n惞": null, + "ᅸ祊\"&ꥴCjࢼ﴿?䡉`U效5殼㮞V昽ꏪ#ﺸ\\&t6x꠹盥꣰a[\u001aꪍSpe鎿蠹": -1.1564713893659811E-19 + } + ]] + ] + ] + ], + "羵䥳H,6ⱎ겾|@t\"#햊1|稃 섭)띜=뻔ꡜ???櫎~*ῡ꫌/繣ﻠq": null + } + ]} + ]}, + "츤": false + }}, + "s": 3.7339341963399598E18 + } + ], + "N,I?1+㢓|ࣱ嶃쩥V2\u0012(4EE虪朶$|w颇v步": "~읢~_,Mzr㐫YB溓E淚\"ⅹ䈔ᏺ抙 b,nt5V㐒J檶ꏨ⻔?", + "Q껑ꡡ}$넎qH煔惍/ez^!ẳF댙䝌馻剁8": "梲;yt钰$i冄}AL%a j뜐奷걳뚾d꿽*ሬuDY3?뮟鼯뮟w㍪틱V", + "o{Q/K O胟㍏zUdꀐm&⨺J舕⾏魸訟㌥[T籨櫉唐킝 aṭ뱫촙莛>碶覆⧬짙쭰ׯdAiH໥벤퐥_恸[ 0e:죃TC弼荎뵁DA:w唵ꣁ": null, + "὏樎䵮軧|?౗aWH쩃1 ꅭsu": null + } + ] + }, + "勂\\&m鰈J釮=Ⲽ鳋+䂡郑": null, + "殣b綊倶5㥗惢⳷萢ᑀ䬄镧M^ﱴ3⣢翣n櫻1㨵}ኯ뗙顖Z.Q➷ꮨ뗇\u0004": "ꔙ䁼>n^[GीA䨟AM琢ᒊS쨲w?d㶣젊嘶纝麓+愣a%気ྞSc됓ᔘ:8bM7Xd8㶑臌]Ꙥ0ꐭ쒙䫣挵C薽Dfⵃ떼᷸", + "?紡.셪_෨j\u0013Ox┠$Xᶨ-ᅇo薹-}軫;y毝㪜K㣁?.EV쮱4둽⛻䤜'2盡\u001f60(|e쐰㼎ᦀ㒧-$l@ﻑ坳\u0003䭱响巗WFo5c㧆T턁Y맸♤(": -2.50917882560589088E17 + }} + ], + "侸\\릩.᳠뎠狣살cs项䭩畳H1s瀉븇19?.w骴崖㤊h痠볭㞳㞳䁮Ql怠㦵": "@䟴-=7f", + "鹟1x௢+d ;vi䭴FSDS\u0004hꎹ㚍?⒍⦏ў6u,扩@됷Su)Pag휛TᒗV痩!瞏釀ꖞ蘥&ೞ蘐ꭰꞇᝎ": "ah懱Ժ&\u20f7䵅♎඀䞧鿪굛ౕ湚粎蚵ᯋ幌YOE)५襦㊝Y*^\"R+ඈ咷蝶9ꥂ榨艦멎헦閝돶v좛咊E)K㓷ྭr", + "搆q쮦4綱켙셁.f4<\/g<籽늷?#蚴픘:fF\u00051㹉뀭.ᰖ풎f֦Hv蔎㧤.!䭽=鞽]음H:?\"-4": 8.740133984938656E-20 + }]} + } + ], + "tVKn딩꘥⊾蹓᤹{\u0003lR꼽ᄲQFᅏ傅ﱋ猢⤊ᔁ,E㓒秤nTතv`♛I\u0000]꫔ṞD\"麵c踝杰X&濿또꣹깳౥葂鿎\\aꡨ?": 3900062609292104525 + } + ], + "ਉ샒⊩Lu@S䧰^g": -1.1487677090371648E18, + "⎢k⑊꬗yᏫ7^err糎Dt\u000bJ礯확ㆍ沑サꋽe赔㝢^J\u0004笲㿋idra剰-᪉C錇/Ĝ䂾ညS지?~콮gR敉⬹'䧭": 1901472137232418266, + "灗k䶥:?촽贍쓉꓈㒸g獘[뵎\\胕?\u0014_榙p.j稶,$`糉妋0>Fᡰly㘽$?": "]ꙛO赎&#㠃돱剳\"<◆>0誉齐_|z|裵씪>ᐌ㼍\"Z[琕}O?G뚇諦cs⠜撺5cu痑U圲\u001c?鴴計l춥/╓哼䄗茏ꮅ뫈댽A돌롖뤫V窗讬sHd&\nOi;_u" + } + ], + "Uﺗ\\Y\\梷䄬~\u0002": null, + "k\"Y磓ᗔ휎@U冈<\/w컑)[": false, + "曏J蝷⌻덦\u001f㙳s꥓⍟邫P늮쥄c∬ྡྷ舆렮칤Z趣5콡넛A쳨\\뀙骫(棻.*&輛LiIfi{@EA婳KᬰTXT": -4.3088230431977587E17 + }]} + ] + ], + "곃㲧<\/dఓꂟs其ࡧ&N葶=?c㠤Ჴ'횠숄臼#\u001a~": false + } + ] + ]}] + }] + }} + ], + "2f`⽰E쵟>J笂裭!〛觬囀ۺ쟰#桊l鹛ⲋ|RA_Vx፭gE됓h﵀mfỐ|?juTU档[d⢼⺻p濚7E峿": 5613688852456817133 + }, + "濘끶g忮7㏵殬W팕Q曁 뫰)惃廊5%-蹚zYZ樭ﴷQ锘쯤崫gg": true, + "絥ᇑ⦏쒓븣爚H.㗊߄o蘵貆ꂚ(쎔O᥉ﮓ]姨Wꁓ!RMA|o퉢THx轮7M껁U즨'i뾘舯o": "跥f꜃?" + }} + ], + "鷰鹮K-9k;ﰰ?_ݦѷ-ꅣ䩨Zꥱ\"mꠟ屎/콑Y╘2&鸞脇㏢ꀇ࠺ⰼ拾喭틮L꽩bt俸墶 [l/웄\"꾦\u20d3iও-&+\u000fQ+໱뵞": -1.296494662286671E-19 + }, + "HX੹/⨇୕붷Uﮘ旧\\쾜͔3l鄈磣糂̖䟎Eᐳw橖b῀_딕hu葰窳闹вU颵|染H죶.fP䗮:j䫢\\b뎖i燕ꜚG⮠W-≚뉗l趕": "ଊ칭Oa᡺$IV㷧L\u0019脴셀붿餲햪$迳向쐯켂PqfT\" ?I屉鴼쿕@硙z^鏕㊵M}㚛T젣쓌-W⩐-g%⺵<뮱~빅╴瑿浂脬\u0005왦燲4Ⴭb|D堧 <\/oEQh", + "䘶#㥘੐캔f巋ἡAJ䢚쭈ࣨ뫒*mᇊK,ࣺAꑱ\u000bR<\/A\"1a6鵌㯀bh곿w(\"$ꘁ*rಐ趣.d࿩k/抶면䒎9W⊃9": "漩b挋Sw藎\u0000", + "畀e㨼mK꙼HglKb,\"'䤜": null + }]}] + ] + ] + }] + ]} + ] + ]} + ], + "歙>駿ꣂ숰Q`J΋方樛(d鱾뼣(뫖턭\u20f9lচ9歌8o]8윶l얶?镖G摄탗6폋폵+g:䱫홊<멀뀿/س|ꭺs걐跶稚W々c㫣⎖": "㣮蔊깚Cꓔ舊|XRf遻㆚︆'쾉췝\\&言", + "殭\"cށɨꝙ䞘:嬮e潽Y펪㳅/\"O@ࠗ겴]췖YǞ(t>R\"N?梳LD恭=n氯T豰2R諸#N}*灧4}㶊G䍣b얚": null, + "襞<\/啧 B|싞W瓇)6簭鼡艆lN쩝`|펭佡\\間邝[z릶&쭟愱ꅅ\\T᰽1鯯偐栈4̸s윜R7⒝/똽?치X": "⏊躖Cﱰ2Qẫ脐&இ?%냝悊", + ",鰧偵셣싹xᎹ힨᯳EṬH㹖9": -4604276727380542356 + } + } + ]]]], + "웺㚑xs}q䭵䪠馯8?LB犯zK'os䚛HZ\"L?셎s^㿧㴘Cv2": null + }] + ] + ] + ], + "Kd2Kv+|z": 7367845130646124107, + "ᦂⶨ?ᝢ 祂些ഷ牢㋇操\"腭䙾㖪\\(y4cE뽺ㆷ쫺ᔖ%zfۻ$ў1柦,㶢9r漢": -3.133230960444846E-20, + "琘M焀q%㢟f鸯O⣏蓑맕鯊$O噷|)z褫^㢦⠮ꚯ꫞`毕1qꢚ{ĭ䎀বώT\"뱘3G൴?^^of": null + } + ], + "a8V᯺?:ﺃ/8ꉿBq|9啓댚;*i2": null, + "cpT瀇H珰Ừpೃi鎪Rr␣숬-鹸ҩ䠚z脚цGoN8入y%趌I┽2ឪЀiJNcN)槣/▟6S숆牟\"箑X僛G殱娇葱T%杻:J諹昰qV쨰": 8331037591040855245 + }], + "G5ᩜ䄗巢껳": true + } + }, + "Ồ巢ゕ@_譙A`碫鄐㡥砄㠓(^K": "?܃B혢▦@犑ὺD~T⧁|醁;o=J牌9냚⢽㨘{4觍蚔9#$∺\u0016p囅\\3Xk阖⪚\"UzA穕롬✎➁㭒춺C㣌ဉ\"2瓑员ᅽꝶ뫍}꽚ꞇ鶂舟彺]ꍽJC蝧銉", + "␆Ě膝\"b-퉐ACR言J謈53~V튥x䜢?ꃽɄY뮩ꚜ": "K/↾e萃}]Bs⾿q룅鷦-膋?m+死^魊镲6", + "粡霦c枋AHퟁo礼Ke?qWcA趸㡔ꂏ?\u000e춂8iতᦜ婪\u0015㢼nﵿꍻ!ᐴ関\u001d5j㨻gfῩUK5Ju丝tかTI'?㓏t>⼟o a>i}ᰗ;뤕ܝ": false, + "ꄮ匴껢ꂰ涽+䜨B蛹H䛓-k蕞fu7kL谖,'涃V~챳逋穞cT\"vQ쓕ObaCRQ㓡Ⲯ?轭⫦輢墳?vA餽=h䮇킵n폲퉅喙?\"'1疬V嬗Qd灗'Lự": "6v!s믁㭟㣯獃!磸餠ቂh0C뿯봗F鷭gꖶ~コkK<ᦈTt\\跓w㭣횋钘ᆹ듡䑚W䟾X'ꅔ4FL勉Vܴ邨y)2'〚쭉⽵-鞣E,Q.?块", + "?(˧쩯@崟吋歄K": null + }, + "Gc럃녧>?2DYI鴿\\륨)澔0ᔬlx'觔7젘⤡縷螩%Sv׫묈/]↱&S h\u0006歋ᑛxi̘}ひY蔯_醨鯘煑橾8?䵎쨋z儬ꁏ*@츾:": null + } + } + } + ] + ] + ]} + }, + "HO츧G": 3.694949578823609E17, + "QC\u0012(翻曇Tf㷟bGBJ옉53\\嚇ᛎD/\u001b夾၉4\"핀@祎)쫆yD\"i먎Vn㿿V1W᨝䶀": -6150931500380982286, + "Z㓮P翸鍱鉼K䋞꘺튿⭁Y": -7704503411315138850, + "]모开ꬖP븣c霤<[3aΠ\"黁䖖䰑뮋ꤦ秽∼㑷冹T+YUt\"싳F↭䖏&鋌": -2.7231911483181824E18, + "tꎖ": -4.9517948741799555E-19, + "䋘즊.⬅IꬃۣQ챢ꄑ黐|f?C⾺|兕읯sC鬸섾整腨솷V": "旆柩l쪦sᖸMy㦅울썉瘗㎜檵9ꍂ駓ૉᚿ/u3씅徐拉[Z䞸ࡗ1ꆱ&Q풘?ǂ8\u0011BCDY2볨;鸏": null, + "幫 n煥s쁇펇 왊-$C\"衝:\u0014㣯舼.3뙗Yl⋇\"K迎멎[꽵s}9鉳UK8쐥\"掄㹖h㙈!얄સ?Ꜳ봺R伕UTD媚I䜘W鏨蔮": -4.150842714188901E-17, + "ﺯ^㄄\b죵@fྉkf颡팋Ꞧ{/Pm0V둳⻿/落韒ꊔᚬ@5螺G\\咸a谆⊪ቧ慷绖?财(鷇u錝F=r၍橢ឳn:^iᴵtD볠覅N赴": null + }] + }] + } + ] + ]} + ]}, + "謯?w厓奰T李헗聝ឍ貖o⪇弒L!캶$ᆅ": -4299324168507841322, + "뺊奉_垐浸延몏孄Z舰2i$q붿좾껇d▵餏\"v暜Ҭ섁m￴g>": -1.60911932510533427E18 + } + ] + } + ] + ]], + "퉝꺔㠦楶Pꅱ": 7517896876489142899, + "": false + } + ]}, + "是u&I狻餼|谖j\"7c됮sסּ-踳鉷`䣷쉄_A艣鳞凃*m⯾☦椿q㎭N溔铉tlㆈ^": 1.93547720203604352E18, + "kⲨ\\%vr#\u000bⒺY\\t<\/3﬌R訤='﹠8蝤Ꞵ렴曔r": false + } + ]}, + "阨{c?C\u001d~K?鎌Ԭ8烫#뙣P초遗t㭱E­돒䆺}甗[R*1!\\~h㕅᰺@<9JꏏષI䳖栭6綘걹ᅩM\"▯是∔v鬽顭⋊譬": "운ﶁK敂(欖C취پ℄爦賾" + } + }} + }], + "鷨赼鸙+\\䭣t圙ڹx᜾ČN<\/踘\"S_맶a鷺漇T彚⎲i㈥LT-xA캔$\u001cUH=a0츺l릦": "溣㣂0濕=鉵氬駘>Pꌢpb솇쬤h힊줎獪㪬CrQ矠a&脍꼬爼M茴/΅\u0017弝轼y#Ꞡc6둴=?R崏뷠麖w?" + }, + "閕ᘜ]CT)䵞l9z'xZF{:ؐI/躅匽졁:䟇AGF૸\u001cퟗ9)駬慟ꡒꆒRS״툋A<>\u0010\"ꂔ炃7g덚E৏bꅰ輤]o㱏_뷕ܘ暂\"u": "芢+U^+㢩^鱆8*1鈶鮀\u0002뺰9⬳ꪮlL䃣괟,G8\u20a8DF㉪錖0ㄤ瓶8Nଷd?眡GLc陓\\_죌V쁰ल二?c띦捱 \u0019JC\u0011b⤉zẒT볕\"绣蘨뚋cꡉkI\u001e鳴", + "ꃣI'{6u^㡃#཰Kq4逹y൒䧠䵮!㱙/n??{L풓ZET㙠퍿X2᩟綳跠葿㚙w཮x캽扳B唕S|尾}촕%N?o䪨": null, + "ⰴFjෟ셈[\u0018辷px?椯\\1<ﲻ栘ᣁ봢憠뉴p": -5263694954586507640 + } + ] + ]] + ]} + ]}] + ] + ], + "?#癘82禩鋆ꊝty?&": -1.9419029518535086E-19 + } + ] + ] + ]} + ] + ] + ], + "훊榲.|῕戄&.㚏Zꛦ2\"䢥ሆ⤢fV_摕婔?≍Fji冀탆꜕i㏬_ẑKᅢ꫄蔻XWc|饡Siẘ^㲦?羡2ぴ1縁ᙅ?쐉Ou": false + }]] + ]}}}, + "慂뗄卓蓔ᐓ匐嚖/颹蘯/翻ㆼL?뇊,텵<\\獷ごCボ": null + }, + "p溉ᑟi짣z:䒤棇r^٫%G9缑r砌롧.물农g?0׼ሩ4ƸO㣥㯄쩞ጩ": null, + "껎繥YxK\"F젷쨹뤤1wq轫o?鱑뜀瘊?뎃h灑\\ꛣ}K峐^ኖ⤐林ꉓhy": null + } + ], + "᱀n肓ㄛ\"堻2>m殮'1橌%Ꞵ군=Ӳ鯨9耛<\/n據0u彘8㬇៩f᏿诙]嚊": "䋯쪦S럶匏ㅛ#)O`ሀX_鐪渲⛀㨻宅闩➈ꢙஶDR⪍" + }, + "tA썓龇 ⋥bj왎录r땽✒롰;羋^\\?툳*┎?썀ma䵳넅U䳆૘〹䆀LQ0\b疀U~u$M}(鵸g⳾i抦뛹?䤈땚검.鹆?ꩡtⶥGĒ;!ቹHS峻B츪켏f5≺": 2366175040075384032, + "전pJjleb]ួ": -7.5418493141528422E18, + "n.鎖ጲ\n?,$䪘": true + }, + "欈Ar㉣螵᪚茩?O)": null + }, + "쫸M#x}D秱欐K=侫们丐.KꕾxẠ\u001e㿯䣛F܍캗qq8꟞ṢFD훎⵳簕꭛^鳜\u205c٫~⑟~冫ऊ2쫰<\/戲윱o<\"": true + }, + "㷝聥/T뱂\u0010锕|内䞇x侁≦㭖:M?iM᣿IJe煜dG࣯尃⚩gPt*辂.{磼럾䝪@a\\袛?}ᓺB珼": true + } + } + ]]}]}}, + "tn\"6ꫤ샾䄄;銞^%VBPwu묪`Y僑N.↺Ws?3C⤻9唩S䠮ᐴm;sᇷ냞඘B/;툥B?lB∤)G+O9m裢0kC햪䪤": -4.5941249382502277E18, + "ᚔt'\\愫?鵀@\\びꂕP큠<<]煹G-b!S?\nꖽ鼫,ݛ&頺y踦?E揆릱H}햧캡b@手.p탻>췽㣬ꒅ`qe佭P>ᓂ&?u}毚ᜉ蟶頳졪ᎏzl2wO": -2.53561440423275936E17 + }]} + } + ] + ]], + "潈촒⿂叡": 5495738871964062986 + } + ]] + } + ] + ]} + ]] + ]] + ]} + ] + ]}, + "ႁq킍蓅R`謈蟐ᦏ儂槐僻ﹶ9婌櫞釈~\"%匹躾ɢ뤥>࢟瀴愅?殕节/냔O✬H鲽엢?ᮈੁ⋧d␽㫐zCe*": 2.15062231586689536E17, + "㶵Ui曚珰鋪ᾼ臧P{䍏䷪쨑̟A뼿T渠誈䏚D1!잶<\/㡍7?)2l≣穷᛾稝{:;㡹nemיּ訊`G": null, + "䀕\"飕辭p圁f#뫆䶷뛮;⛴ᩍ3灚덏ᰝ쎓⦷詵%᜖Մfs⇫(\u001e~P|ﭗCⲾផv湟W첋(텪બT<บSꏉ੗⋲X婵i ӵ⇮?L䬇|ꈏ?졸": 1.548341247351782E-19 + } + ] + }, + "t;:N\u0015q鐦Rt缆{ꮐC?஛㷱敪\\+鲊㉫㓪몗릙竏(氵kYS": "XᰂT?൮ô", + "碕飦幑|+ 㚦鏶`镥ꁩ B<\/加륙": -4314053432419755959, + "秌孳(p!G?V傫%8ሽ8w;5鲗㦙LI檸\u2098": "zG N볞䆭鎍흘\\ONK3횙<\/樚立圌Q튅k쩎Ff쁋aׂJK銆ઘ즐狩6༥✙䩜篥CzP(聻駇HHퟲ讃%,ά{렍p而刲vy䦅ክ^톺M楒鍢㹳]Mdg2>䤉洞", + "踛M젧>忔芿㌜Zk": 2215369545966507819, + "씐A`$槭頰퍻^U覒\bG毲aᣴU;8!팲f꜇E⸃_卵{嫏羃X쀳C7뗮m(嚼u N܁谟D劯9]#": true, + "ﻩ!뵸-筚P᭛}ἰ履lPh?౮ⶹꆛ穉뎃g萑㑓溢CX뾇G㖬A錟]RKaꄘ]Yo+@䘁's섎襠$^홰}F": null + }, + "粘ꪒ4HXᕘ蹵.$區\r\u001d묁77pPc^y笲Q<\/ꖶ 訍䃍ᨕG?*": 1.73773035935040224E17 + }, + "婅拳?bkU;#D矠❴vVN쩆t㜷A풃갮娪a%鮏絪3dAv룒#tm쑬⌛qYwc4|L8KZ;xU⓭㳔밆拓EZ7襨eD|隰ऌ䧼u9Ԣ+]贴P荿": 2.9628516456987075E18 + }]}}] + ]} + }} + ]}] + ], + "|g翉F*湹̶\u0005⏐1脉̀eI쩓ᖂ㫱0碞l䴨ꑅ㵽7AtἈ턧yq䳥塑:z:遀ᄐX눔擉)`N3昛oQ셖y-ڨ⾶恢ꈵq^<\/": null, + "菹\\랓G^璬x৴뭸ゆUS겧﮷Bꮤ ┉銜᯻0%N7}~f洋坄Xꔼ<\/4妟Vꄟ9:౟곡t킅冩䧉笭裟炂4봋ⱳ叺怊t+怯涗\"0㖈Hq": false, + "졬믟'ﺇফ圪쓬멤m邸QLব䗁愍4jvs翙 ྍ꧀艳H-|": null, + "컮襱⣱뗠 R毪/鹙꾀%헳8&": -5770986448525107020 + } + ], + "B䔚bꐻ뙏姓展槰T-똌鷺tc灿᫽^㓟䏀o3o$꘭趙萬I顩)뇭Ἑ䓝\f@{ᣨ`x3蔛": null + } + ] + ] + }], + "⦖扚vWꃱ꥙㾠壢輓{-⎳鹷贏璿䜑bG倛⋐磎c皇皩7a~ﳫU╣Q࠭ꎉS摅姽OW.홌ೞ.": null, + "蚪eVlH献r}ᮏ믠ﰩꔄ@瑄ⲱ": null, + "퀭$JWoꩢg역쁍䖔㑺h&ୢtXX愰㱇?㾫I_6 OaB瑈q裿": null, + "꽦ﲼLyr纛Zdu珍B絟쬴糔?㕂짹䏵e": "ḱ\u2009cX9멀i䶛簆㳀k" + } + ]]]], + "(_ꏮg່澮?ᩑyM<艷\u001aꪽ\\庼뙭Z맷㰩Vm\\lY筺]3㋲2㌩㄀Eਟ䝵⨄쐨ᔟgङHn鐖⤇놋瓇Q탚單oY\"♆臾jHᶈ征ቄ??uㇰA?#1侓": null + }, + "觓^~ሢ&iI띆g륎ḱ캀.ᓡꀮ胙鈉": 1.0664523593012836E-19, + "y詭Gbᔶऽs댁U:杜⤎ϲ쁗⮼D醄诿q뙰I#즧v蔎xHᵿt᡽[**?崮耖p缫쿃L菝,봬ꤦC쯵#=X1瞻@OZc鱗CQTx": null + } + ] + }}], + "剘紁\u0004\\Xn⊠6,တױ;嵣崇}讃iႽ)d1\\䔓": null + }, + "脨z\"{X,1u찜<'k&@?1}Yn$\u0015Rd輲ーa쮂굄+B$l": true, + "諳>*쭮괐䵟Ґ+<箁}빀䅱⡔檏臒hIH脟ꩪC핝ଗP좕\"0i<\/C褻D۞恗+^5?'ꂱ䚫^7}㡠cq6\\쨪ꔞꥢ?纖䫀氮蒫侲빦敶q{A煲G": -6880961710038544266 + }}] + }, + "5s⨲JvಽῶꭂᄢI.a৊": null, + "?1q꽏쿻ꛋDR%U娝>DgN乭G": -1.2105047302732358E-19 + } + ] + ]}, + "qZz`撋뙹둣j碇쁏\\ꆥ\u0018@藴疰Wz)O{F䶛l᷂绘訥$]뮍夻䢋䩇萿獰樧猵⣭j萶q)$꬚⵷0馢W:Ⱍ!Qoe": -1666634370862219540, + "t": "=wp|~碎Q鬳Ӎ\\l-<\/^ﳊhn퐖}䍔t碵ḛ혷?靻䊗", + "邙쇡㯇%#=,E4勃驆V繚q[Y댻XV㡸[逹ᰏ葢B@u=JS5?bLRn얮㍉⏅ﰳ?a6[&큟!藈": 1.2722786745736667E-19 + }, + "X블땨4{ph鵋ꉯ웸 5p簂䦭s_E徔濧d稝~No穔噕뽲)뉈c5M윅>⚋[岦䲟懷恁?鎐꓆ฬ爋獠䜔s{\u001bm鐚儸煛%bﯿXT>ꗘ@8G": 1157841540507770724, + "媤娪Q杸\u0011SAyᡈ쿯": true, + "灚^ಸ%걁<\/蛯?\"祴坓\\\\'흍": -3.4614808555942579E18, + "釴U:O湛㴑䀣렑縓\ta)(j:숾却䗌gCiB뽬Oyuq輥厁/7)?今hY︺Q": null + } + ] + ]]]}] + ], + "I笔趠Ph!<ཛྷ㸞诘X$畉F\u0005笷菟.Esr릙!W☆䲖뗷莾뒭U\"䀸犜Uo3Gꯌx4r蔇᡹㧪쨢準<䂀%ࡡꟼ瑍8炝Xs0䀝销?fi쥱ꆝલBB": -8571484181158525797, + "L⦁o#J|\"⽩-㱢d㌛8d\\㶤傩儻E[Y熯)r噤὘勇 }": "e(濨쓌K䧚僒㘍蠤Vᛸ\"络QJL2,嬓왍伢㋒䴿考澰@(㏾`kX$끑эE斡,蜍&~y", + "vj.|统圪ᵮPL?2oŶ`밧\"勃+0ue%⿥绬췈체$6:qa렐Q;~晘3㙘鹑": true, + "ශؙ4獄⶿c︋i⚅:ん閝Ⳙ苆籦kw{䙞셕pC췃ꍬ␜꟯ꚓ酄b힝hwk꭭M鬋8B耳쑘WQ\\偙ac'唀x᪌\u2048*h짎#ፇ鮠뾏ឿ뀌": false, + "⎀jꄒ牺3Ⓝ컴~?親ꕽぼܓ喏瘘!@<튋㐌꿱⩦{a?Yv%⪧笯Uܱ栅E搚i뚬:ꄃx7䙳ꦋ&䓹vq☶I䁘ᾘ涜\\썉뺌Lr%Bc㍜3?ꝭ砿裞]": null, + "⭤뙓z(㡂%亳K䌽꫿AԾ岺㦦㼴輞낚Vꦴw냟鬓㹈뽈+o3譻K1잞": 2091209026076965894, + "ㇲ\t⋇轑ꠤ룫X긒\"zoY읇희wj梐쐑l侸`e%s": -9.9240075473576563E17, + "啸ꮑ㉰!ᚓ}銏": -4.0694813896301194E18, + ">]囋੽EK뇜>_ꀣ緳碖{쐐裔[<ನ\"䇅\"5L?#xTwv#罐\u0005래t应\\N?빗;": "v쮽瞭p뭃" + } + ]], + "斴槾?Z翁\"~慍弞ﻆ=꜡o5鐋dw\"?K蠡i샾ogDﲰ_C*⬟iㇷ4nય蟏[㟉U꽌娛苸 ঢ়操贻洞펻)쿗૊許X⨪VY츚Z䍾㶭~튃ᵦ<\/E臭tve猑x嚢": null, + "锡⛩<\/칥ꈙᬙ蝀&Ꚑ籬■865?_>L詏쿨䈌浿弥爫̫lj&zx<\/C쉾?覯n?": null, + "꾳鑤/꼩d=ᘈn挫ᑩ䰬ZC": "3錢爋6Ƹ䴗v⪿Wr益G韠[\u0010屗9쁡钁u?殢c䳀蓃樄욂NAq赟c튒瘁렶Aૡɚ捍" + } + ] + ] + ]} + ] + ] + }]]]}} + ]}], + "Ej䗳U<\/Q=灒샎䞦,堰頠@褙g_\u0003ꤾfⶽ?퇋!łB〙ד3CC䌴鈌U:뭔咎(Qો臃䡬荋BO7㢝䟸\"Yb": 2.36010731779814E-20, + "逸'0岔j\u000e눘먷翌C츊秦=ꭣ棭ှ;鳸=麱$XP⩉駚橄A\\좱⛌jqv䰞3Ь踌v㳆¹gT┌gvLB賖烡m?@E঳i": null + }, + "曺v찘ׁ?&绫O័": 9107241066550187880 + } + ] + ], + "(e屄\u0019昜훕琖b蓘ᬄ0/۲묇Z蘮ဏ⨏蛘胯뢃@㘉8ሪWᨮ⦬ᅳ䅴HI၇쨳z囕陻엣1赳o": true, + ",b刈Z,ၠ晐T솝ŕB⩆ou'퐼≃绗雗d譊": null, + "a唥KB\"ﳝ肕$u\n^⅄P䟼냉䞸⩪u윗瀱ꔨ#yşs꒬=1|ﲤ爢`t౐튼쳫_Az(Ṋ擬㦷좕耈6": 2099309172767331582, + "?㴸U<\/䢔ꯡ阽扆㐤q鐋?f㔫wM嬙-;UV죫嚔픞G&\"Cᗍ䪏풊Q": "VM7疹+陕枡툩窲}翡䖶8欞čsT뮐}璤:jﺋ鎴}HfA൝⧻Zd#Qu茅J髒皣Y-︴[?-~쉜v딏璮㹚䅊﩯<-#\u000e걀h\u0004u抱﵊㼃U<㱷⊱IC進" + }, + "숌dee節鏽邺p넱蹓+e罕U": true + } + ], + "b⧴룏??ᔠ3ぱ>%郿劃翐ꏬꠛW瞳᫏누躨狀ໄy੽\"ីuS=㨞馸k乆E": "トz݈^9R䬑<ﮛGRꨳ\u000fTT泠纷꽀MRᴱ纊:㠭볮?%N56%鈕1䗍䜁a䲗j陇=뿻偂衋࿘ᓸ?ᕵZ+<\/}H耢b䀁z^f$&㝒LkꢳI脚뙛u": 5.694374481577558E-20 + }] + } + ]], + "obj": {"key": "wrong value"}, + "퓲꽪m{㶩/뇿#⼢&᭙硞㪔E嚉c樱㬇1a綑᝖DḾ䝩": null + }, + "key": "6.908319653520691E8", + "z": { + "6U閆崬밺뀫颒myj츥휘:$薈mY햚#rz飏+玭V㭢뾿愴YꖚX亥ᮉ푊\u0006垡㐭룝\"厓ᔧḅ^Sqpv媫\"⤽걒\"˽Ἆ?ꇆ䬔未tv{DV鯀Tἆl凸g\\㈭ĭ즿UH㽤": null, + "b茤z\\.N": [[ + "ZL:ᅣዎ*Y|猫劁櫕荾Oj为1糕쪥泏S룂w࡛Ᏺ⸥蚙)", + { + "\"䬰ỐwD捾V`邀⠕VD㺝sH6[칑.:醥葹*뻵倻aD\"": true, + "e浱up蔽Cr෠JK軵xCʨ<뜡癙Y獩ケ齈X/螗唻?<蘡+뷄㩤쳖3偑犾&\\첊xz坍崦ݻ鍴\"嵥B3㰃詤豺嚼aqJ⑆∥韼@\u000b㢊\u0015L臯.샥": false, + "l?Ǩ喳e6㔡$M꼄I,(3᝝縢,䊀疅뉲B㴔傳䂴\u0088㮰钘ꜵ!ᅛ韽>": -5514085325291784739, + "o㮚?\"춛㵉<\/﬊ࠃ䃪䝣wp6ἀ䱄[s*S嬈貒pᛥ㰉'돀": [{ + "(QP윤懊FI<ꃣ『䕷[\"珒嶮?%Ḭ壍಻䇟0荤!藲끹bd浶tl\u2049#쯀@僞": {"i妾8홫": { + ",M맃䞛K5nAㆴVN㒊햬$n꩑&ꎝ椞阫?/ṏ세뉪1x쥼㻤㪙`\"$쟒薟B煌܀쨝ଢ଼2掳7㙟鴙X婢\u0002": "Vዉ菈᧷⦌kﮞఈnz*﷜FM\"荭7ꍀ-VR<\/';䁙E9$䩉\f @s?퍪o3^衴cඎ䧪aK鼟q䆨c{䳠5mᒲՙ蘹ᮩ": { + "F㲷JGo⯍P덵x뒳p䘧☔\"+ꨲ吿JfR㔹)4n紬G练Q፞!C|": true, + "p^㫮솎oc.೚A㤠??r\u000f)⾽⌲們M2.䴘䩳:⫭胃\\፾@Fᭌ\\K": false, + "蟌Tk愙潦伩": { + "a<\/@ᾛ慂侇瘎": -7271305752851720826, + "艓藬/>၄ṯ,XW~㲆w": {"E痧郶)㜓ha朗!N赻瞉駠uC\u20ad辠x퓮⣫P1ࠫLMMX'M刼唳됤": null, + "P쓫晥%k覛ዩIUᇸ滨:噐혲lMR5䋈V梗>%幽u頖\\)쟟": null, + "eg+昉~矠䧞难\b?gQ쭷筝\\eꮠNl{ಢ哭|]Mn銌╥zꖘzⱷ⭤ᮜ^": [ + -1.30142114406914976E17, + -1.7555215491128452E-19, + null, + "渾㨝ߏ牄귛r?돌?w[⚞ӻ~廩輫㼧/", + -4.5737191805302129E18, + null, + "xy࿑M[oc셒竓Ⓔx?뜓y䊦>-D켍(&&?XKkc꩖ﺸᏋ뵞K伕6ী)딀P朁yW揙?훻魢傎EG碸9類៌g踲C⟌aEX舲:z꒸许", + 3808159498143417627, + null, + {"m試\u20df1{G8&뚈h홯J<\/": { + "3ஸ厠zs#1K7:rᥞoꅔꯧ&띇鵼鞫6跜#赿5l'8{7㕳(b/j\"厢aq籀ꏚ\u0015厼稥": [ + -2226135764510113982, + true, + null, + { + "h%'맞S싅Hs&dl슾W0j鿏MםD놯L~S-㇡R쭬%": null, + "⟓咔謡칲\u0000孺ꛭx旑檉㶆?": null, + "恇I転;￸B2Y`z\\獓w,놏濐撐埵䂄)!䶢D=ഭ㴟jyY": { + "$ࡘt厛毣ൢI芁<겿骫⫦6tr惺a": [ + 6.385779736989334E-20, + false, + true, + true, + [ + -6.891946211462334E-19, + null, + { + "]-\\Ꟑ1/薓❧Ὂ\\l牑\u0007A郃)阜ᇒᓌ-塯`W峬G}SDb㬨Q臉⮻빌O鞟톴첂B㺱<ƈmu챑J㴹㷳픷Oㆩs": { + "\"◉B\"pᶉt骔J꩸ᄇᛐi╰栛K쉷㉯鐩!㈐n칍䟅難>盥y铿e୔蒏M貹ヅ8嘋퀯䉶ጥ㏢殊뻳\"絧╿ꉑ䠥?∃蓊{}㣣Gk긔H1哵峱": false, + "6.瀫cN䇮F㧺?\\椯=ڈT䘆4␘8qv": -3.5687501019676885E-19, + "Q?yऴr혴{஀䳘p惭f1ﹸ䅷䕋贲<ྃᄊ繲hq\\b|#QSTs1c-7(䵢\u2069匏絘ꯉ:l毴汞t戀oෟᵶ뮱፣-醇Jx䙬䐁햢0࣫ᡁgrㄛ": "\u0011_xM/蘇Chv;dhA5.嗀绱V爤ﰦi뵲M", + "⏑[\"ugoy^儣횎~U\\섯겜論l2jw஌yD腅̂\u0019": true, + "ⵯɇ䐲᫿࢚!㯢l샅笶戮1꣖0Xe": null, + "劅f넀識b宁焊E찓橵G!ʱ獓뭔雩괛": [{"p⹣켙[q>燣䍃㞽ᩲx:쓤삘7玑퇼0<\/q璂ᑁ[Z\\3䅵䧳\u0011㤧|妱緒C['췓Yꞟ3Z鳱雼P錻BU씧U`ᢶg蓱>.1ӧ譫'L_5V䏵Ц": [ + false, + false, + {"22䂍盥N霂얢躰e9⑩_뵜斌n@B}$괻Yᐱ@䧋V\"☒-諯cV돯ʠ": true, + "Ű螧ᔼ檍鍎땒딜qꄃH뜣<獧ूCY吓⸏>XQ㵡趌o끬k픀빯a(ܵ甏끆୯/6Nᪧ}搚ᆚ짌P牰泱鈷^d꣟#L삀\"㕹襻;k㸊\\f+": true, + "쎣\",|⫝̸阊x庿k잣v庅$鈏괎炔k쬪O_": [ + "잩AzZGz3v愠ꉈⵎ?㊱}S尳௏p\r2>췝IP䘈M)w|\u000eE", + -9222726055990423201, + null, + [ + false, + {"´킮'뮤쯽Wx讐V,6ᩪ1紲aႈ\u205czD": [ + -930994432421097536, + 3157232031581030121, + "l貚PY䃛5@䭄귻m㎮琸f": 1.0318894506812084E-19, + "࢜⩢Ш䧔1肽씮+༎ᣰ闺馺窃䕨8Mƶq腽xc(៯夐J5굄䕁Qj_훨/~価.䢵慯틠퇱豠㼇Qﵘ$DuSp(8Uญ<\/ಟ룴𥳐ݩ$": 8350772684161555590, + "ㆎQ䄾\u001bpᩭ${[諟^^骴᤮b^ㅥI┧T㉇⾞\"绦r䰂f矩'-7䡭桥Dz兔V9谶居㺍ᔊ䩯덲.\u001eL0ὅㅷ釣": [{ + "<쯬J卷^숞u࠯䌗艞R9닪g㐾볎a䂈歖意:%鐔|ﵤ|y}>;2,覂⶚啵tb*仛8乒㓶B࿠㯉戩oX 貘5V嗆렽낁߼4h䧛ꍺM空\\b꿋貼": 8478577078537189402, + "VD*|吝z~h譺aᯒ": { + "YI췢K<\/濳xNne玗rJo쾘3핰鴊\"↱AR:ࢷ\"9?\"臁說)?誚ꊏe)_D翾W?&F6J@뺾ꍰNZ醊Z쾈വH嶿?炫㷱鬰M겈᭨b,⻁鈵P䕡䀠८ⱄ홎鄣": { + "@?k2鶖㋮\"Oರ K㨇廪儲\u0017䍾J?);\b*묀㗠섳햭1MC V": null, + "UIICP!BUA`ᢈ㋸~袩㗪⾒=fB﮴l1ꡛ죘R辂여ҳ7쮡<䩲`熕8頁": 4481809488267626463, + "Y?+8먙ᚔ鋳蜩럶1㥔y璜౩`": [ + null, + 1.2850335807501874E-19, + "~V2", + 2035406654801997866, + { + "<숻1>\"": -8062468865199390827, + "M㿣E]}qwG莎Gn᝶(ꔙ\\D⬲iꇲs寢t駇S뀡ꢜ": false, + "pꝤ㎏9W%>M;-U璏f(^j1?&RB隧 忓b똊E": "#G?C8.躬ꥯ'?냪#< 渟&헿란zpo왓Kj}鷧XﻘMツb䕖;㪻", + "vE풤幉xz뱕쫥Ug㦲aH} ᣟp:鬼YᰟH3镔ᴚ斦\\鏑r*2橱G⼔F/.j": true, + "RK좬뎂a홠f*f㱉ᮍ⦋潙㨋Gu곌SGI3I뿐\\F',)t`荁蘯囯ﮉ裲뇟쥼_ገ驪▵撏ᕤV": 1.52738225997956557E18, + "^k굲䪿꠹B逤%F㱢漥O披M㽯镞竇霒i꼂焅륓\u00059=皫之눃\u2047娤閍銤唫ၕb<\/w踲䔼u솆맚,䝒ᝳ'/it": "B餹饴is権ꖪ怯ꦂẉဎt\"!凢谵⧿0\\<=(uL䷍刨쑪>俆揓Cy襸Q힆䆭涷<\/ᐱ0ɧ䗾䚹\\ኜ?ꄢᇘ`䴢{囇}᠈䴥X4퓪檄]ꥷ/3謒ሴn+g騍X", + "GgG꽬[(嫓몍6\u0004궍宩㙻/>\u0011^辍dT腪hxǑ%ꊇk,8(W⧂結P鬜O": [{ + "M㴾c>\\ᓲ\u0019V{>ꤩ혙넪㭪躂TS-痴໸闓⍵/徯O.M㏥ʷD囎⧔쁳휤T??鉬뇙=#ꢫ숣BX䭼<\/d똬졬g榿)eꨋﯪ좇첻\u001a\u0011\";~쓆BH4坋攊7힪", + "iT:L闞椕윚*滛gI≀Wਟඊ'ꢆ縺뱹鮚Nꩁ᧬蕼21줧\\䋯``⍐\\㏱鳨": 1927052677739832894, + "쮁缦腃g]礿Y㬙 fヺSɪ꾾N㞈": [ + null, + null, + { + "!t,灝Y 1䗉罵?c饃호䉂Cᐭ쒘z(즽sZG㬣sഖE4뢜㓕䏞丮Qp簍6EZឪ겛fx'ꩱQ0罣i{k锩*㤴㯞r迎jTⲤ渔m炅肳": [ + -3.3325685522591933E18, + [{"㓁5]A䢕1룥BC?Ꙍ`r룔Ⳛ䙡u伲+\u0001്o": [ + null, + 4975309147809803991, + null, + null, + {"T팘8Dﯲ稟MM☻㧚䥧/8ﻥ⥯aXLaH\"顾S☟耲ît7fS෉놁뮔/ꕼ䓈쁺4\\霶䠴ᩢ<\/t4?죵>uD5➶༆쉌럮⢀秙䘥\u20972ETR3濡恆vB? ~鸆\u0005": { + "`閖m璝㥉b뜴?Wf;?DV콜\u2020퍉౓擝宏ZMj3mJ먡-傷뱙yח㸷꥿ ໘u=M읝!5吭L4v\\?ǎ7C홫": null, + "|": false, + "~Ztᛋ䚘\\擭㗝傪W陖+㗶qᵿ蘥ᙄp%䫎)}=⠔6ᮢS湟-螾-mXH?cp": 448751162044282216, + "\u209fad놹j檋䇌ᶾ梕㉝bוּ": {"?苴ꩠD䋓帘5騱qﱖPF?☸珗顒yU ᡫcb䫎 S@㥚gꮒ쎘泴멖\\:I鮱TZ듒ᶨQ3+f7캙\"?\f풾\\o杞紟﻽M.⏎靑OP": [ + -2.6990368911551596E18, + [{"䒖@<᰿<\/⽬tTr腞&G%᳊秩蜰擻f㎳?S㵧\r*k뎾-乢겹隷j軛겷0룁鮁": {")DO0腦:춍逿:1㥨่!蛍樋2": [{ + ",ꌣf侴笾m๫ꆽ?1?U?\u0011ꌈꂇ": { + "x捗甠nVq䅦w`CD⦂惺嘴0I#vỵ} \\귂S끴D얾?Ԓj溯\"v餄a": { + "@翙c⢃趚痋i\u0015OQ⍝lq돆Y0pࢥ3쉨䜩^<8g懥0w)]䊑n洺o5쭝QL댊랖L镈Qnt⪟㒅십q헎鳒⮤眉ᔹ梠@O縠u泌ㄘb榚癸XޔFtj;iC": false, + "I&뱋゘|蓔䔕측瓯%6ᗻHW\\N1貇#?僐ᗜgh᭪o'䗈꽹Rc욏/蔳迄༝!0邔䨷푪8疩)[쭶緄㇈୧ፐ": { + "B+:ꉰ`s쾭)빼C羍A䫊pMgjdx䐝Hf9᥸W0!C樃'蘿f䫤סи\u0017Jve? 覝f둀⬣퓉Whk\"஼=չﳐ皆笁BIW虨쫓F廰饞": -642906201042308791, + "sb,XcZ<\/m㉹ ;䑷@c䵀s奤⬷7`ꘖ蕘戚?Feb#輜}p4nH⬮eKL트}": [ + "RK鳗z=袤Pf|[,u욺", + "Ẏᏻ罯뉋⺖锅젯㷻{H䰞쬙-쩓D]~\u0013O㳢gb@揶蔉|kᦂ❗!\u001ebM褐sca쨜襒y⺉룓", + null, + null, + true, + -1.650777344339075E-19, + false, + "☑lꄆs힨꤇]'uTന⌳농].1⋔괁沰\"IWഩ\u0019氜8쟇䔻;3衲恋,窌z펏喁횗?4?C넁问?ᥙ橭{稻Ⴗ_썔", + "n?]讇빽嗁}1孅9#ꭨ靶v\u0014喈)vw祔}룼쮿I", + -2.7033457331882025E18, + { + ";⚃^㱋x:饬ኡj'꧵T☽O㔬RO婎?향ᒭ搩$渣y4i;(Q>꿘e8q": "j~錘}0g;L萺*;ᕭꄮ0l潛烢5H▄쳂ꏒוֹꙶT犘≫x閦웧v", + "~揯\u2018c4職렁E~ᑅቚꈂ?nq뎤.:慹`F햘+%鉎O瀜쟏敛菮⍌浢<\/㮺紿P鳆ࠉ8I-o?#jﮨ7v3Dt赻J9": null, + "ࣝW䌈0ꍎqC逖,횅c၃swj;jJS櫍5槗OaB>D踾Y": {"㒰䵝F%?59.㍈cᕨ흕틎ḏ㋩B=9IېⓌ{:9.yw}呰ㆮ肒᎒tI㾴62\"ዃ抡C﹬B<\/촋jo朣", + [ + -7675533242647793366, + {"ᙧ呃:[㒺쳀쌡쏂H稈㢤\u001dᶗGG-{GHྻຊꡃ哸䵬;$?&d\\⥬こN圴됤挨-'ꕮ$PU%?冕눖i魁q騎Q": [ + false, + [[ + 7929823049157504248, + [[ + true, + "Z菙\u0017'eꕤ᱕l,0\\X\u001c[=雿8蠬L<\/낲긯W99g톉4ퟋb㝺\u0007劁'!麕Q궈oW:@X၎z蘻m絙璩귓죉+3柚怫tS捇蒣䝠-擶D[0=퉿8)q0ٟ", + "唉\nFA椭穒巯\\䥴䅺鿤S#b迅獘 ﶗ꬘\\?q1qN犠pX꜅^䤊⛤㢌[⬛휖岺q唻ⳡ틍\"㙙Eh@oA賑㗠y必Nꊑᗘ", + -2154220236962890773, + -3.2442003245397908E18, + "Wᄿ筠:瘫퀩?o貸q⊻(᎞KWf宛尨h^残3[U(='橄", + -7857990034281549164, + 1.44283696979059942E18, + null, + {"ꫯAw跭喀 ?_9\"Aty背F=9缉ྦྷ@;?^鞀w:uN㘢Rỏ": [ + 7.393662029337442E15, + 3564680942654233068, + [ + false, + -5253931502642112194, + "煉\\辎ೆ罍5⒭1䪁䃑s䎢:[e5}峳ﴱn騎3?腳Hyꏃ膼N潭錖,Yᝋ˜YAၓ㬠bG렣䰣:", + true, + null, + { + "⒛'P&%죮|:⫶춞": -3818336746965687085, + "钖m<\/0ݎMtF2Pk=瓰୮洽겎.": [[ + -8757574841556350607, + -3045234949333270161, + null, + { + "Ꮬr輳>⫇9hU##w@귪A\\C 鋺㘓ꖐ梒뒬묹㹻+郸嬏윤'+g<\/碴,}ꙫ>손;情d齆J䬁ຩ撛챝탹/R澡7剌tꤼ?ặ!`⏲睤\u00002똥଴⟏": null, + "\u20f2ܹe\\tAꥍư\\x当뿖렉禛;G檳ﯪS૰3~㘠#[J<}{奲 5箉⨔{놁<\/釿抋,嚠/曳m&WaOvT赋皺璑텁": [[ + false, + null, + true, + -5.7131445659795661E18, + "萭m䓪D5|3婁ఞ>蠇晼6nﴺPp禽羱DS<睓닫屚삏姿", + true, + [ + -8759747687917306831, + { + ">ⓛ\t,odKr{䘠?b퓸C嶈=DyEᙬ@ᴔ쨺芛髿UT퓻春<\/yꏸ>豚W釺N뜨^?꽴﨟5殺ᗃ翐%>퍂ဿ䄸沂Ea;A_\u0005閹殀W+窊?Ꭼd\u0013P汴G5썓揘": 4.342729067882445E-18, + "Q^즾眆@AN\u0011Kb榰냎Y#䝀ꀒᳺ'q暇睵s\"!3#I⊆畼寤@HxJ9": false, + "⿾D[)袨㇩i]웪䀤ᛰMvR<蟏㣨": {"v퇓L㪱ꖣ豛톤\\곱#kDTN": [{ + "(쾴䡣,寴ph(C\"㳶w\"憳2s馆E!n!&柄<\/0Pꈗſ?㿳Qd鵔": {"娇堰孹L錮h嵅⛤躏顒?CglN束+쨣ﺜ\\MrH": {"獞䎇둃ቲ弭팭^ꄞ踦涟XK錆쳞ឌ`;੶S炥騞ଋ褂B៎{ڒ䭷ᶼ靜pI荗虶K$": [{"◖S~躘蒉꫿輜譝Q㽙闐@ᢗ¥E榁iء5┄^B[絮跉ᰥ遙PWi3wㄾⵀDJ9!w㞣ᄎ{듒ꓓb6\\篴??c⼰鶹⟧\\鮇ꮇ": [[ + 654120831325413520, + -1.9562073916357608E-19, + { + "DC(昐衵ἡ긙갵姭|֛[t": 7.6979110359897907E18, + "J␅))嫼❳9Xfd飉j7猬ᩉ+⤻眗벎E鰉Zᄊ63zၝ69}ZᶐL崭ᦥ⡦靚⋛ꎨ~i㨃咊ꧭo䰠阀3C(": -3.5844809362512589E17, + "p꣑팱쒬ꎑ뛡Ꙩ挴恍胔&7ᔈ묒4Hd硶훐㎖zꢼ豍㿢aሃ=<\/湉鵲EӅ%$F!퍶棌孼{O駍਺geu+": ")\u001b잓kŀX쩫A밁®ڣ癦狢)扔弒p}k縕ꩋ,䃉tࣼi", + "ァF肿輸<솄G-䢹䛸ꊏl`Tqꕗ蒞a氷⸅ᴉ蠰]S/{J왲m5{9.uέ~㕚㣹u>x8U讁B덺襪盎QhVS맅킃i识{벂磄Iහ䙅xZy/抍૭Z鲁-霳V据挦ℒ": null, + "㯛|Nꐸb7ⵐb?拠O\u0014ކ?-(EꞨ4ꕷᄤYᯕOW瞺~螸\"욿ќe㺰\"'㌢ƐW\u0004瞕>0?V鷵엳": true, + "뤥G\\迋䠿[庩'꼡\u001aiᩮV쯁ᳪ䦪Ô;倱ନ뛁誈": null, + "쥹䄆䚟Q榁䎐᢭<\/2㕣p}HW蟔|䃏꿈ꚉ锳2Pb7㙑Tⅹᵅ": { + "Y?֭$>#cVBꩨ:>eL蒁務": { + "86柡0po 䏚&-捑Ћ祌<\/휃-G*㶢הּ쩍s㶟餇c걺yu꽎還5*턧簕Og婥SꝐ": null, + "a+葞h٥ࠆ裈嗫ﵢ5輙퀟ᛜ,QDﹼ⟶Y騠锪E_|x죗j侵;m蜫轘趥?븅w5+mi콛L": { + ";⯭ﱢ!买F⽍柤鶂n䵣V㫚墱2렾ELEl⣆": [ + true, + -3.6479311868339015E-18, + -7270785619461995400, + 3.334081886177621E18, + 2.581457786298155E18, + -6.605252412954115E-20, + -3.9232347037744167E-20, + { + "B6㊕.k1": null, + "ZAꄮJ鮷ᳱo갘硥鈠䠒츼": { + "ᕅ}럡}.@y陪鶁r業'援퀉x䉴ﵴl퍘):씭脴ᥞhiꃰblﲂ䡲엕8߇M㶭0燋標挝-?PCwe⾕J碻Ᾱ䬈䈥뷰憵賣뵓痬+": {"a췩v礗X⋈耓ፊf罅靮!㔽YYᣓw澍33⎔芲F|\"䜏T↮輦挑6ᓘL侘?ᅥ]덆1R௯✎餘6ꏽ<\/௨\\?q喷ꁫj~@ulq": {"嗫欆뾔Xꆹ4H㌋F嵧]ࠎ]㠖1ꞤT<$m뫏O i댳0䲝i": {"?෩?\u20cd슮|ꯆjs{?d7?eNs⢚嫥氂䡮쎱:鑵롟2hJꎒﯭ鱢3춲亄:뼣v䊭諱Yj択cVmR䩃㘬T\"N홝*ै%x^F\\_s9보zz4淗?q": [ + null, + "?", + 2941869570821073737, + "{5{殇0䝾g6밖퍋臩綹R$䖭j紋釰7sXI繳漪행y", + false, + "aH磂?뛡#惇d婅?Fe,쐘+늵䍘\"3r瘆唊勐j⳧࠴ꇓ<\/唕윈x⬌讣䋵%拗ᛆⰿ妴᝔M2㳗必꧂淲?ゥ젯檢<8끒MidX䏒3᳻Q▮佐UT|⤪봦靏⊏", + [[{ + "颉(&뜸귙{y^\"P퟉춝Ჟ䮭D顡9=?}Y誱<$b뱣RvO8cH煉@tk~4ǂ⤧⩝屋SS;J{vV#剤餓ᯅc?#a6D,s": [ + -7.8781018564821536E16, + true, + [ + -2.28770899315832371E18, + false, + -1.0863912140143876E-20, + -6282721572097446995, + 6767121921199223078, + -2545487755405567831, + false, + null, + -9065970397975641765, + [ + -5.928721243413937E-20, + {"6촊\u001a홯kB0w撨燠룉{绎6⳹!턍贑y▾鱧ժ[;7ᨷ∀*땒䪮1x霆Hᩭ☔\"r䝐7毟ᝰr惃3ꉭE+>僒澐": [ + "Ta쎩aƝt쵯ⰪVb", + [ + -5222472249213580702, + null, + -2851641861541559595, + null, + 4808804630502809099, + 5657671602244269874, + "5犲﨣4mᥣ?yf젫꾯|䋬잁$`Iⳉﴷ扳兝,'c", + false, + [ + null, + { + "DyUIN쎾M仼惀⮥裎岶泭lh扠\u001e礼.tEC癯튻@_Qd4c5S熯A<\/\6U윲蹴Q=%푫汹\\\u20614b[௒C⒥Xe⊇囙b,服3ss땊뢍i~逇PA쇸1": -2.63273619193485312E17, + "Mq꺋貘k휕=nK硍뫞輩>㾆~἞ࡹ긐榵l⋙Hw뮢帋M엳뢯v⅃^": 1877913476688465125, + "ᶴ뻗`~筗免⚽টW˃⽝b犳䓺Iz篤p;乨A\u20ef쩏?疊m㝀컩뫡b탔鄃ᾈV(遢珳=뎲ିeF仢䆡谨8t0醄7㭧瘵⻰컆r厡궥d)a阄፷Ed&c﯄伮1p": null, + "⯁w4曢\"(欷輡": "\"M᭫]䣒頳B\\燧ࠃN㡇j姈g⊸⺌忉ꡥF矉স%^", + "㣡Oᄦ昵⫮Y祎S쐐級㭻撥>{I$": -378474210562741663, + "䛒掷留Q%쓗1*1J*끓헩ᦢ﫫哉쩧EↅIcꅡ\\?ⴊl귛顮4": false, + "寔愆샠5]䗄IH贈=d﯊/偶?ॊn%晥D視N򗘈'᫂⚦|X쵩넽z질tskxDQ莮Aoﱻ뛓": true, + "钣xp?&\u001e侉/y䴼~?U篔蘚缣/I畚?Q绊": -3034854258736382234, + "꺲໣眀)⿷J暘pИfAV삕쳭Nꯗ4々'唄ⶑ伻㷯騑倭D*Ok꧁3b␽_<\/챣Xm톰ၕ䆄`*fl㭀暮滠毡?": [ + "D男p`V뙸擨忝븪9c麺`淂⢦Yw⡢+kzܖ\fY1䬡H歁)벾Z♤溊-혰셢?1<-\u0005;搢Tᐁle\\ᛵߓﭩ榩訝-xJ;巡8깊蠝ﻓU$K": { + "Vꕡ諅搓W=斸s︪vﲜ츧$)iꡟ싉e寳?ጭムVથ嵬i楝Fg<\/Z|៪ꩆ-5'@ꃱ80!燱R쇤t糳]罛逇dṌ֣XHiͦ{": true, + "Ya矲C멗Q9膲墅携휻c\\딶G甔<\/.齵휴": -1.1456247877031811E-19, + "z#.OO￝J": -8263224695871959017, + "崍_3夼ᮟ1F븍뽯ᦓ鴭V豈Ь": [{ + "N蒬74": null, + "yuB?厅vK笗!ᔸcXQ旦컶P-녫mᄉ麟_": "1R@ 톘xa_|﩯遘s槞d!d껀筤⬫薐焵먑D{\\6k共倌☀G~AS_D\"딟쬚뮥馲렓쓠攥WTMܭ8nX㩴䕅檹E\u0007ﭨN 2 ℆涐ꥏ꠵3▙玽|됨_\u2048", + "恐A C䧩G": {":M큣5e들\\ꍀ恼ᔄ靸|I﨏$)n": { + "|U䬫㟯SKV6ꛤ㗮\bn봻䲄fXT:㾯쳤'笓0b/ೢC쳖?2浓uO.䰴": "ཐ꼋e?``,ᚇ慐^8ꜙNM䂱\u0001IᖙꝧM'vKdꌊH牮r\\O@䊷ᓵ쀆(fy聻i툺\"?<\/峧ࣞ⓺ᤤ쵒߯ꎺ騬?)刦\u2072l慪y꺜ﲖTj+u", + "뽫hh䈵w>1ⲏ쐭V[ⅎ\\헑벑F_㖝⠗㫇h恽;῝汰ᱼ瀖J옆9RR셏vsZ柺鶶툤r뢱橾/ꉇ囦FGm\"謗ꉦ⨶쒿⥡%]鵩#ᖣ_蹎 u5|祥?O", + null, + 2.0150326776036215E-19, + null, + true, + false, + true, + {"\fa᭶P捤WWc᠟f뚉ᬏ퓗ⳀW睹5:HXH=q7x찙X$)모r뚥ᆟ!Jﳸf": [ + -2995806398034583407, + [ + 6441377066589744683, + "Mﶒ醹i)Gἦ廃s6몞 KJ౹礎VZ螺费힀\u0000冺업{谥'꡾뱻:.ꘘ굄奉攼Di᷑K鶲y繈욊阓v㻘}枭캗e矮1c?휐\"4\u0005厑莔뀾墓낝⽴洗ṹ䇃糞@b1\u0016즽Y轹", + { + "1⽕⌰鉟픏M㤭n⧴ỼD#%鐘⊯쿼稁븣몐紧ᅇ㓕ᛖcw嬀~ഌ㖓(0r⧦Q䑕髍ര铂㓻R儮\"@ꇱm❈௿᦯頌8}㿹犴?xn잆꥽R": 2.07321075750427366E18, + "˳b18㗈䃟柵Z曆VTAu7+㛂cb0﯑Wp執<\/臋뭡뚋刼틮荋벲TLP预庰܈G\\O@VD'鱃#乖끺*鑪ꬳ?Mޞdﭹ{␇圯쇜㼞顄︖Y홡g": [{ + "0a,FZ": true, + "2z̬蝣ꧦ驸\u0006L↛Ḣ4๚뿀'?lcwᄧ㐮!蓚䃦-|7.飑挴.樵*+1ﮊ\u0010ꛌ%貨啺/JdM:똍!FBe?鰴㨗0O财I藻ʔWA᫓G쳛u`<\/I": [{ + "$τ5V鴐a뾆両環iZp頻යn븃v": -4869131188151215571, + "*즢[⦃b礞R◚nΰꕢH=귰燙[yc誘g䆌?ଜ臛": { + "洤湌鲒)⟻\\䥳va}PeAMnN[": "㐳ɪ/(軆lZR,Cp殍ȮN啷\"3B婴?i=r$펽ᤐ쀸", + "阄R4㒿㯔ڀ69ZᲦ2癁핌噗P崜#\\-쭍袛&鐑/$4童V꩑_ZHA澢fZ3": {"x;P{긳:G閉:9?活H": [ + "繺漮6?z犞焃슳\">ỏ[Ⳛ䌜녏䂹>聵⼶煜Y桥[泥뚩MvK$4jtロ", + "E#갶霠좭㦻ୗ먵F+䪀o蝒ba쮎4X㣵 h", + -335836610224228782, + null, + null, + [ + "r1᫩0>danjY짿bs{", + [ + -9.594464059325631E-23, + 1.0456894622831624E-20, + null, + 5.803973284253454E-20, + -8141787905188892123, + true, + -4735305442504973382, + 9.513150514479281E-20, + "7넳$螔忷㶪}䪪l짴\u0007鹁P鰚HF銏ZJﳴ/⍎1ᷓ忉睇ᜋ쓈x뵠m䷐窥Ꮤ^\u0019ᶌ偭#ヂt☆၃pᎍ臶䟱5$䰵&๵分숝]䝈뉍♂坎\u0011<>", + "C蒑貑藁lﰰ}X喇몛;t밿O7/᯹f\u0015kI嘦<ዴ㟮ᗎZ`GWퟩ瑹࡮ᅴB꿊칈??R校s脚", + { + "9珵戬+AU^洘拻ቒy柭床'粙XG鞕᠜繀伪%]hC,$輙?Ut乖Qm떚W8઼}~q⠪rU䤶CQ痗ig@#≲t샌f㈥酧l;y闥ZH斦e⸬]j⸗?ঢ拻퀆滌": null, + "畯}㧢J罚帐VX㨑>1ꢶkT⿄蘥㝑o|<嗸層沈挄GEOM@-䞚䧰$만峬輏䠱V✩5宸-揂D'㗪yP掶7b⠟J㕻SfP?d}v㼂Ꮕ'猘": { + "陓y잀v>╪": null, + "鬿L+7:됑Y=焠U;킻䯌잫!韎ஔ\f": { + "駫WmGጶ": { + "\\~m6狩K": -2586304199791962143, + "ႜࠀ%͑l⿅D.瑢Dk%0紪dḨTI픸%뗜☓s榗኉\"?V籄7w髄♲쟗翛歂E䤓皹t ?)ᄟ鬲鐜6C": { + "_췤a圷1\u000eB-XOy缿請∎$`쳌eZ~杁튻/蜞`塣৙\"⪰\"沒l}蕌\\롃荫氌.望wZ|o!)Hn獝qg}": null, + "kOSܧ䖨钨:಼鉝ꭝO醧S`십`ꓭ쭁ﯢN&Et㺪馻㍢ⅳ㢺崡ຊ蜚锫\\%ahx켨|ż劻ꎄ㢄쐟A躊᰹p譞綨Ir쿯\u0016ﵚOd럂*僨郀N*b㕷63z": { + ":L5r+T㡲": [{ + "VK泓돲ᮙRy㓤➙Ⱗ38oi}LJቨ7Ó㹡৘*q)1豢⛃e᫛뙪壥镇枝7G藯g㨛oI䄽 孂L缊ꋕ'EN`": -2148138481412096818, + "`⛝ᘑ$(खꊲ⤖ᄁꤒ䦦3=)]Y㢌跨NĴ驳줟秠++d孳>8ᎊ떩EꡣSv룃 쯫أ?#E|᭙㎐?zv:5祉^⋑V": [ + -1.4691944435285607E-19, + 3.4128661569395795E17, + "㐃촗^G9佭龶n募8R厞eEw⺡_ㆱ%⼨D뉄퉠2ꩵᛅⳍ搿L팹Lවn=\"慉념ᛮy>!`g!풲晴[/;?[v겁軇}⤳⤁핏∌T㽲R홓遉㓥", + "愰_⮹T䓒妒閤둥?0aB@㈧g焻-#~跬x<\/舁P݄ꐡ=\\׳P\u0015jᳪᢁq;㯏l%᭗;砢觨▝,謁ꍰGy?躤O黩퍋Y㒝a擯\n7覌똟_䔡]fJ晋IAS", + 4367930106786121250, + -4.9421193149720582E17, + null, + { + ";ᄌ똾柉곟ⰺKpፇ䱻ฺ䖝{o~h!eꁿ઻욄ښ\u0002y?xUd\u207c悜ꌭ": [ + 1.6010824122815255E-19, + [ + "宨︩9앉檥pr쇷?WxLb", + "氇9】J玚\u000f옛呲~ 輠1D嬛,*mW3?n휂糊γ虻*ᴫ꾠?q凐趗Ko↦GT铮", + "㶢ថmO㍔k'诔栀Z蛟}GZ钹D", + false, + -6.366995517736813E-20, + -4894479530745302899, + null, + "V%᫡II璅䅛䓎풹ﱢ/pU9se되뛞x梔~C)䨧䩻蜺(g㘚R?/Ự[忓C뾠ࢤc왈邠买?嫥挤풜隊枕", + ",v碍喔㌲쟚蔚톬៓ꭶ", + 3.9625444752577524E-19, + null, + [ + "kO8란뿒䱕馔b臻⍟隨\"㜮鲣Yq5m퐔K#ꢘug㼈ᝦ=P^6탲@䧔%$CqSw铜랊0&m⟭<\/a逎ym\u0013vᯗ": true, + "洫`|XN뤮\u0018詞=紩鴘_sX)㯅鿻Ố싹": 7.168252736947373E-20, + "ꛊ饤ﴏ袁(逊+~⽫얢鈮艬O힉7D筗S곯w操I斞᠈븘蓷x": [[[[ + -7.3136069426336952E18, + -2.13572396712722688E18, + { + "硢3㇩R:o칢行E<=\u0018ၬYuH!\u00044U%卝炼2>\u001eSi$⓷ꒈ'렢gᙫ番ꯒ㛹럥嶀澈v;葷鄕x蓎\\惩+稘UEᖸﳊ㊈壋N嫿⏾挎,袯苷ኢ\\x|3c": 7540762493381776411, + "?!*^ᢏ窯?\u0001ڔꙃw虜돳FgJ?&⨫*uo籤:?}ꃹ=ٴ惨瓜Z媊@ત戹㔏똩Ԛ耦Wt轁\\枒^\\ꩵ}}}ꀣD\\]6M_⌫)H豣:36섘㑜": { + ";홗ᰰU஋㙛`D왔ཿЃS회爁\u001b-㢈`봆?盂㛣듿ᦾ蒽_AD~EEຆ㊋(eNwk=Rɠ峭q\"5Ἠ婾^>'ls\n8QAK)- Q䲌mo펹L_칍樖庫9꩝쪹ᘹ䑖瀍aK ?*趤f뭓廝p=磕", + "哑z懅ᤏ-ꍹux쀭", + [ + true, + 3998739591332339511, + "ጻ㙙?᳸aK<\/囩U`B3袗ﱱ?\"/k鏔䍧2l@쿎VZ쨎/6ꃭ脥|B?31+on颼-ꮧ,O嫚m ࡭`KH葦:粘i]aSU쓙$쐂f+詛頖b", + [{"^<9<箝&絡;%i﫡2攑紴\\켉h쓙-柂䚝ven\u20f7浯-Ꮏ\r^훁䓚헬\u000e?\\ㅡֺJ떷VOt": [{ + "-௄卶k㘆혐஽y⎱㢬sS઄+^瞥h;ᾷj;抭\u0003밫f<\/5Ⱗ裏_朻%*[-撵䷮彈-芈": { + "㩩p3篊G|宮hz䑊o곥j^Co0": [ + 653239109285256503, + {"궲?|\":N1ۿ氃NZ#깩:쇡o8킗ࡊ[\"됸Po핇1(6鰏$膓}⽐*)渽J'DN<썙긘毦끲Ys칖": { + "2Pr?Xjㆠ?搮/?㓦柖馃5뚣Nᦼ|铢r衴㩖\"甝湗ܝ憍": "\"뾯i띇筝牻$珲/4ka $匝휴译zbAᩁꇸ瑅&뵲衯ꎀᆿ7@ꈋ'ᶨH@ᠴl+", + "7뢽뚐v?4^ꊥ_⪛.>pởr渲<\/⢕疻c\"g䇘vU剺dஔ鮥꒚(dv祴X⼹\\a8y5坆": true, + "o뼄B욞羁hr﷔폘뒚⿛U5pꪴfg!6\\\"爑쏍䢱W<ﶕ\\텣珇oI/BK뺡'谑♟[Ut븷亮g(\"t⡎有?ꬊ躺翁艩nl F⤿蠜": 1695826030502619742, + "ۊ깖>ࡹ햹^ⵕ쌾BnN〳2C䌕tʬ]찠?ݾ2饺蹳ぶꌭ訍\"◹ᬁD鯎4e滨T輀ﵣ੃3\u20f3킙D瘮g\\擦+泙ၧ 鬹ﯨַ肋7놷郟lP冝{ߒhড়r5,꓋": null, + "ΉN$y{}2\\N﹯ⱙK'8ɜͣwt,.钟廣䎘ꆚk媄_": null, + "䎥eᾆᝦ읉,Jުn岪㥐s搖謽䚔5t㯏㰳㱊ZhD䃭f絕s鋡篟a`Q鬃┦鸳n_靂(E4迠_觅뷝_宪D(NL疶hL追V熑%]v肫=惂!㇫5⬒\u001f喺4랪옑": { + "2a輍85먙R㮧㚪Sm}E2yꆣꫨrRym㐱膶ᔨ\\t綾A☰.焄뙗9<쫷챻䒵셴᭛䮜.<\/慌꽒9叻Ok䰊Z㥪幸k": [ + null, + true, + {"쌞쐍": { + "▟GL K2i뛱iQ\"̠.옛1X$}涺]靎懠ڦ늷?tf灟ݞゟ{": 1.227740268699265E-19, + "꒶]퓚%ฬK❅": [{ + "(ෛ@Ǯっ䧼䵤[aテൖvEnAdU렖뗈@볓yꈪ,mԴ|꟢캁(而첸죕CX4Y믅": "2⯩㳿ꢚ훀~迯?᪑\\啚;4X\u20c2襏B箹)俣eỻw䇄", + "75༂f詳䅫ꐧ鏿 }3\u20b5'∓䝱虀f菼Iq鈆﨤g퍩)BFa왢d0뮪痮M鋡nw∵謊;ꝧf美箈ḋ*\u001c`퇚퐋䳫$!V#N㹲抗ⱉ珎(V嵟鬒_b㳅\u0019": null, + "e_m@(i㜀3ꦗ䕯䭰Oc+-련0뭦⢹苿蟰ꂏSV䰭勢덥.ྈ爑Vd,ᕥ=퀍)vz뱊ꈊB_6듯\"?{㒲&㵞뵫疝돡믈%Qw限,?\r枮\"? N~癃ruࡗdn&": null, + "㉹&'Pfs䑜공j<\/?|8oc᧨L7\\pXᭁ 9᪘": -2.423073789014103E18, + "䝄瑄䢸穊f盈᥸,B뾧푗횵B1쟢f\u001f凄": "魖⚝2儉j꼂긾껢嗎0ࢇ纬xI4](੓`蕞;픬\fC\"斒\")2櫷I﹥迧", + "ퟯ詔x悝령+T?Bg⥄섅kOeQ큼㻴*{E靼6氿L缋\u001c둌๶-㥂2==-츫I즃㠐Lg踞ꙂEG貨鞠\"\u0014d'.缗gI-lIb䋱ᎂDy缦?": null, + "紝M㦁犿w浴詟棓쵫G:䜁?V2ힽ7N*n&㖊Nd-'ຊ?-樹DIv⊜)g䑜9뉂ㄹ푍阉~ꅐ쵃#R^\u000bB䌎䦾]p.䀳": [{"ϒ爛\"ꄱ︗竒G䃓-ま帳あ.j)qgu扐徣ਁZ鼗A9A鸦甈!k蔁喙:3T%&㠘+,䷞|챽v䚞문H<\/醯r셓㶾\\a볜卺zE䝷_죤ဵ뿰᎟CB": [ + 6233512720017661219, + null, + -1638543730522713294, + false, + -8901187771615024724, + [ + 3891351109509829590, + true, + false, + -1.03836679125188032E18, + { + "j랎:g曞ѕᘼ}链N", + -1.1103819473845426E-19, + true, + [ + true, + null, + -7.9091791735309888E17, + true, + {"}蔰鋈+ꐨ啵0?g*사%`J?*": [{ + "\"2wG?yn,癷BK\\龞䑞x?蠢": -3.7220345009853505E-19, + ";饹়❀)皋`噿焒j(3⿏w>偍5X薙婏聿3aFÆÝ": "2,ꓴg?_섦_>Y쪥션钺;=趘F~?D㨫\bX?㹤+>/믟kᠪ멅쬂Uzỵ]$珧`m雁瑊ඖ鯬cꙉ梢f묛bB", + "♽n$YjKiXX*GO贩鏃豮祴遞K醞眡}ꗨv嵎꼷0୸+M菋eH徸J꣆:⼐悥B켽迚㯃b諂\u000bjꠜ碱逮m8": [ + "푷᣺ﻯd8ﱖ嬇ភH鹎⡱᱅0g:果6$GQ췎{vᷧYy-脕x偹砡館⮸C蓼ꏚ=軄H犠G谖ES詤Z蠂3l봟hᅭ7䦹1GPQG癸숟~[#駥8zQ뛣J소obg,", + null, + 1513751096373485652, + null, + -6.851466660824754E-19, + {"䩂-⴮2ٰK솖풄꾚ႻP앳1H鷛wmR䗂皎칄?醜<\/&ࠧ㬍X濬䵈K`vJ륒Q/IC묛!;$vϑ": { + "@-ꚗxྐྵ@m瘬\u0010U絨ﮌ驐\\켑寛넆T=tQ㭤L연@脸삯e-:⩼u㎳VQ㋱襗ຓ<Ⅶ䌸cML3+\u001e_C)r\\9+Jn\\Pﺔ8蠱檾萅Pq鐳话T䄐I": -1.80683891195530061E18, + "ᷭዻU~ཷsgSJ`᪅'%㖔n5픆桪砳峣3獮枾䌷⊰呀": { + "Ş੉䓰邟自~X耤pl7间懑徛s첦5ਕXexh⬖鎥᐀nNr(J컗|ૃF\"Q겮葲놔엞^겄+㈆话〾희紐G'E?飕1f❼텬悚泬먐U睬훶Qs": false, + "(\u20dag8큽튣>^Y{뤋.袊䂓;_g]S\u202a꽬L;^'#땏bႌ?C緡<䝲䲝断ꏏ6\u001asD7IK5Wxo8\u0006p弊⼂ꯍ扵\u0003`뵂픋%ꄰ⫙됶l囏尛+䗅E쟇\\": [ + true, + { + "\n鱿aK㝡␒㼙2촹f;`쾏qIࡔG}㝷䐍瓰w늮*粅9뒪ㄊCj倡翑閳R渚MiUO~仨䜶RꙀA僈㉋⦋n{㖥0딿벑逦⥻0h薓쯴Ꝼ": [ + 5188716534221998369, + 2579413015347802508, + 9.010794400256652E-21, + -6.5327297761238093E17, + 1.11635352494065523E18, + -6656281618760253655, + { + "": ")?", + "TWKLꑙ裑꺔UE俸塑炌Ũ᜕-o\"徚#": {"M/癟6!oI51ni퐚=댡>xꍨ\u0004 ?": { + "皭": {"⢫䋖>u%w잼<䕏꘍P䋵$魋拝U䮎緧皇Y훂&|羋ꋕ잿cJ䨈跓齳5\u001a삱籷I꿾뤔S8㌷繖_Yឯ䲱B턼O歵F\\l醴o_欬6籏=D": [ + false, + true, + {"Mt|ꏞD|F궣MQ뵕T,띺k+?㍵i": [ + 7828094884540988137, + false, + { + "!༦鯠,&aﳑ>[euJꏽ綷搐B.h": -7648546591767075632, + "-n켧嘰{7挐毄Y,>❏螵煫乌pv醑Q嶚!|⌝責0왾덢ꏅ蛨S\\)竰'舓Q}A釡5#v": 3344849660672723988, + "8閪麁V=鈢1녈幬6棉⪮둌\u207d᚛驉ꛃ'r䆉惏ै|bἧﺢᒙ<=穊强s혧eꮿ慩⌡ \\槳W븧J檀C,ᘉ의0俯퀉M;筷ࣴ瓿{늊埂鄧_4揸Nn阼Jੵ˥(社": true, + "o뼀vw)4A뢵(a䵢)p姃뛸\u000fK#KiQp\u0005ꅍ芅쏅": null, + "砥$ꥸ┇耽u斮Gc{z빔깎밇\\숰\u001e괷各㶇쵿_ᴄ+h穢p촀Ნ䃬z䝁酳ӂ31xꔄ1_砚W렘G#2葊P ": [ + -3709692921720865059, + null, + [ + 6669892810652602379, + -135535375466621127, + "뎴iO}Z? 馢녱稹ᄾ䐩rSt帤넆&7i騏멗畖9誧鄜'w{Ͻ^2窭외b㑎粖i矪ꦨ탪跣)KEㆹ\u0015V8[W?⽉>'kc$䨘ᮛ뉻٬M5", + 1.10439588726055846E18, + false, + -4349729830749729097, + null, + [ + false, + "_蠢㠝^䟪/D녒㡋ỎC䒈판\u0006એq@O펢%;鹐쏌o戥~A[ꡉ濽ỳ&虃᩾荣唙藍茨Ig楡꒻M窓冉?", + true, + 2.17220752996421728E17, + -5079714907315156164, + -9.960375974658589E-20, + "ᾎ戞༒", + true, + false, + [[ + "ⶉᖌX⧕홇)g엃⹪x뚐癟\u0002", + -5185853871623955469, + { + "L㜤9ợㇶK鐰⋓V뽋˖!斫as|9"፬䆪?7胜&n薑~": -2.11545634977136992E17, + "O8뀩D}캖q萂6༣㏗䈓煮吽ਆᎼDᣘ폛;": false, + "YTᡅ^L㗎cbY$pᣞ縿#fh!ꘂb삵玊颟샞ဢ$䁗鼒몁~rkH^:닮먖츸륈⪺쒉砉?㙓扫㆕꣒`R䢱B酂?C뇞<5Iޚ讳騕S瞦z": null, + "\\RB?`mG댵鉡幐物䵎有5*e骄T㌓ᛪ琾駒Ku\u001a[柆jUq8⋈5鿋츿myﻗ?雍ux঴?": 5828963951918205428, + "n0晅:黯 xu씪^퓞cB㎊ᬍ⺘٤փ~B岚3㥕擄vᲂ~F?C䶖@$m~忔S왖㲚?챴⊟W#벌{'㰝I䝠縁s樘\\X뢻9핡I6菍ㄛ8쯶]wॽ0L\"q": null, + "x增줖j⦦t䏢᎙㛿Yf鼘~꫓恄4惊\u209c": "oOhbᤃ᛽z&Bi犑\\3B㩬劇䄑oŁ쨅孥멁ຖacA㖫借㞝vg싰샂㐜#譞⢤@k]鋰嘘䜾L熶塥_<\/⍾屈ﮊ_mY菹t뙺}Ox=w鮮4S1ꐩמּ'巑", + "㗓蟵ꂾe蠅匳(JP䗏෸\u0089耀왲": [{ + "ᤃ㵥韎뤽\r?挥O쯡⇔㞚3伖\u0005P⋪\"D궣QLn(⚘罩䩢Ŏv䤘尗뼤됛O淽鋋闚r崩a{4箙{煷m6〈": { + "l곺1L": { + "T'ਤ?砅|੬Km]䄩\"(࿶<\/6U爢䫈倔郴l2㴱^줣k'L浖L鰄Rp今鎗⒗C얨M훁㡧ΘX粜뫈N꤇輊㌻켑#㮮샶-䍗룲蠝癜㱐V>=\\I尬癤t=": 7648082845323511446, + "鋞EP:<\/_`ၧe混ㇹBd⯢㮂驋\\q碽饩跓྿ᴜ+j箿렏㗑yK毢宸p謹h䦹乕U媣\\炤": [[ + "3", + [ + true, + 3.4058271399411134E-20, + true, + "揀+憱f逮@먻BpW曉\u001a㣐⎊$n劈D枤㡞좾\u001aᛁ苔౩闝1B䷒Ṋ݋➐ꀞꐃ磍$t੤_:蘺⮼(#N", + 697483894874368636, + [ + "vᘯ锴)0訶}䳅⩚0O壱韈ߜ\u0018*U鍾䏖=䧉뽑单휻ID쿇嘗?ꌸῬ07", + -5.4858784319382006E18, + 7.5467775182251151E18, + -8911128589670029195, + -7531052386005780140, + null, + [ + null, + true, + [[{ + "1欯twG<\/Q:0怯押殃탷聫사<ỗꕧ蚨䡁nDꌕ\u001c녬~蓩鲃g儊>ꏡl㻿/⑷*챳6㻜W毤緛ﹺᨪ4\u0013뺚J髬e3쳸䘦伧?恪&{L掾p+꬜M䏊d娘6": { + "2p첼양棜h䜢﮶aQ*c扦v︥뮓kC寵횂S銩&ǝ{O*य़iH`U큅ࡓr䩕5ꄸ?`\\᧫?ᮼ?t〟崾훈k薐ì/iy꤃뵰z1<\/AQ#뿩8jJ1z@u䕥": 1.82135747285215155E18, + "ZdN &=d년ᅆ'쑏ⅉ:烋5&៏ᄂ汎来L㯄固{钧u\\㊏튚e摑&t嗄ꖄUb❌?m䴘熚9EW": [{ + "ଛ{i*a(": -8.0314147546006822E17, + "⫾ꃆY\u000e+W`௸ \"M뒶+\\뷐lKE}(NT킶Yj選篒쁶'jNQ硾(똡\\\"逌ⴍy? IRꜘ὞鄬﨧:M\\f⠋Cꚜ쫊ᚴNV^D䕗ㅖἔIao꿬C⍏8": [ + 287156137829026547, + { + "H丞N逕⯲": {"": { + "7-;枮阕梒9ᑄZ": [[[[ + null, + { + "": [[[[ + -7.365909561486078E-19, + 2948694324944243408, + null, + [ + true, + "荒\"并孷䂡쵼9o䀘F\u0002龬7⮹Wz%厖/*? a*R枈㌦됾g뒠䤈q딄㺿$쮸tᶎ릑弣^鏎<\/Y鷇驜L鿽<\/춋9Mᲆឨ^<\/庲3'l낢", + "c鮦\u001b두\\~?眾ಢu݆綑෪蘛轋◜gȃ<\/ⴃcpkDt誩܅\"Y", + [[ + null, + null, + [ + 3113744396744005402, + true, + "v(y", + { + "AQ幆h쾜O+꺷铀ꛉ練A蚗⼺螔j㌍3꽂楎䥯뎸먩?": null, + "蠗渗iz鱖w]擪E": 1.2927828494783804E-17, + "튷|䀭n*曎b✿~杤U]Gz鄭kW|㴚#㟗ഠ8u擨": [[ + true, + null, + null, + {"⾪壯톽g7?㥜ώQꑐ㦀恃㧽伓\\*᧰閖樧뢇赸N휶䎈pI氇镊maᬠ탷#X?A+kНM ༑᩟؝?5꧎鰜ṚY즫궔 =ঈ;ﳈ?*s|켦蜌wM笙莔": [ + null, + -3808207793125626469, + [ + -469910450345251234, + 7852761921290328872, + -2.7979740127017492E18, + 1.4458504352519893E-20, + true, + "㽙깹?먏䆢:䴎ۻg殠JBTU⇞}ꄹꗣi#I뵣鉍r혯~脀쏃#釯:场:䔁>䰮o'㼽HZ擓௧nd", + [ + 974441101787238751, + null, + -2.1647718292441327E-19, + 1.03602824249831488E18, + [ + null, + 1.0311977941822604E-17, + false, + true, + { + "": -3.7019778830816707E18, + "E峾恆茍6xLIm縂0n2视֯J-ᤜz+ᨣ跐mYD豍繹⹺䊓몓ﴀE(@詮(!Y膽#᎙2䟓섣A䈀㟎,囪QbK插wcG湎ꤧtG엝x⥏俎j'A一ᯥ뛙6ㅑ鬀": 8999803005418087004, + "よ殳\\zD⧅%Y泥簳Uꈩ*wRL{3#3FYHା[d岀䉯T稉駅䞘礄P:闈W怏ElB㤍喬赔bG䠼U଄Nw鰯闀楈ePsDꥷ꭬⊊": [ + 6.77723657904486E-20, + null, + [ + "ཚ_뷎꾑蹝q'㾱ꂓ钚蘞慵렜떆`ⴹ⎼櫯]J?[t9Ⓢ !컶躔I᮸uz>3a㠕i,錃L$氰텰@7녫W㸮?羧W뇧ꃞ,N鋮숪2ɼ콏┍䁲6", + "&y?뢶=킕올Za惻HZk>c\u20b58i?ꦶcfBv잉ET9j䡡", + "im珊Ճb칧校\\뼾쯀", + 9.555715121193197E-20, + true, + { + "<㫚v6腓㨭e1㕔&&V∌ᗈT奄5Lጥ>탤?튣瑦㳆ꉰ!(ᙪ㿬擇_n쌯IMΉ㕨␰櫈ᱷ5풔蟹&L.첽e鰷쯃劼﫭b#ﭶ퓀7뷄Wr㢈๧Tʴશ㶑澕鍍%": -1810142373373748101, + "fg晌o?߲ꗄ;>C>?=鑰監侯Kt굅": true, + "䫡蓺ꑷ]C蒹㦘\"1ః@呫\u0014NL䏾eg呮፳,r$裢k>/\\?ㄤᇰﻛ쉕1஥'Ċ\" \\_?쨔\"ʾr: 9S䘏禺ᪧꄂ㲄", + [[{ + "*硙^+E쌺I1䀖ju?:⦈Ꞓl๴竣迃xKC/饉:\fl\"XTFᄄ蟭,芢<\/骡軺띜hꏘ\u001f銿<棔햳▨(궆*=乥b8\\媦䷀뫝}닶ꇭ(Kej䤑M": [{ + "1Ꮼ?>옿I╅C<ގ?ꊌ冉SV5A㢊㶆z-๎玶绢2F뵨@㉌뀌o嶔f9-庒茪珓뷳4": null, + ";lᰳ": "CbB+肻a䄷苝*/볳+/4fq=㰁h6瘉샴4铢Y骐.⌖@哼猎㦞+'gꋸ㒕ߤ㞑(䶒跲ti⑴a硂#No볔", + "t?/jE幸YHT셵⩎K!Eq糦ꗣv刴w\"l$ο:=6:移": { + "z]鑪醊嫗J-Xm銌翁絨c里됏炙Ep㣋鏣똼嚌䀓GP﹖cmf4鹭T䅿꣭姧␸wy6ꦶ;S&(}ᎧKxᾂQ|t뻳k\"d6\"|Ml췆hwLt꼼4$&8Պ褵婶鯀9": {"嵃닢ᒯ'd᧫䳳#NXe3-붋鸿ଢ떓%dK\u0013䲎ꖍYV.裸R⍉rR3蟛\\:젯:南ĺLʆ넕>|텩鴷矔ꋅⒹ{t孶㓑4_": [ + true, + null, + [ + false, + "l怨콈lᏒ", + { + "0w䲏嬧-:`䉅쉇漧\\܂yㄨb%㽄j7ᦶ涶<": 3.7899452730383747E-19, + "ꯛTẀq纤q嶏V⿣?\"g}ი艹(쥯B T騠I=仵및X": {"KX6颠+&ᅃ^f畒y[": { + "H?뱜^?꤂-⦲1a㋞&ꍃ精Ii᤾챪咽쬘唂쫷<땡劈훫놡o㥂\\ KⴙD秼F氮[{'좴:례晰Iq+I쭥_T綺砸GO煝䟪ᚪ`↹l羉q쐼D꽁ᜅ훦: vUV": true, + "u^yﳍ0㱓#[y뜌앸ꊬL㷩?蕶蘾⻍KӼ": -7931695755102841701, + "䤬轉車>\u001c鴵惋\"$쯃྆⇻n뽀G氠S坪]ಲꨍ捇Qxኻ椕駔\\9ࣼ﫻읜磡煮뺪ᶚ볝l㕆t+sζ": [[[ + true, + false, + [ + null, + 3363739578828074923, + true, + { + "\"鸣詩 볰㑵gL㯦῅춝旫}ED辗ﮈI쀤-ꧤ|㠦Z\"娑ᕸ4爏騍㣐\"]쳝Af]茛⬻싦o蚁k䢯䩐菽3廇喑ޅ": 4.5017999150704666E17, + "TYႇ7ʠ值4챳唤~Zo&ݛ": false, + "`塄J袛㭆끺㳀N㺣`꽐嶥KﯝSVᶔ∲퀠獾N딂X\"ᤏhNﬨvI": {"\u20bb㭘I䖵䰼?sw䂷쇪](泒f\"~;꼪Fԝsᝦ": {"p,'ꉂ軿=A蚶?bƉ㏵䅰諬'LYKL6B깯⋩겦뎙(ᜭ\u0006噣d꾆㗼Z;䄝䚔cd<情@䞂3苼㸲U{)<6&ꩻ钛\u001au〷N숨囖愙j=BXW욕^x芜堏Ῑ爂뛷꒻t✘Q\b": [[ + "籛&ଃ䩹.ꃩ㦔\\C颫#暪&!勹ꇶ놽攺J堬镙~軌C'꾖䣹㮅岃ᙴ鵣", + 4.317829988264744E15, + 6.013585322002147E-20, + false, + true, + null, + null, + -3.084633632357326E-20, + false, + null, + { + "\"짫愔昻 X\"藣j\"\"먁ཅѻ㘤㬯0晲DU꟒㸃d벀윒l䦾c੻*3": null, + "谈Wm陧阦咟ฯ歖擓N喴㋐銭rCCnVࢥ^♼Ⅾ젲씗刊S༝+_t赔\\b䚍뉨ꬫ6펛cL䊘᜼<\/澤pF懽&H": [ + null, + { + "W\"HDUuΌ퀟M'P4࿰H똆ⰱﮯ<\/凐蘲\"C鴫ﭒж}ꭩ쥾t5yd诪ﮡ퍉ⴰ@?氐醳rj4I6Qt": 6.9090159359219891E17, + "絛ﳛ⺂": {"諰P㗮聦`ZQ?ꫦh*റcb⧱}埌茥h{棩렛툽o3钛5鮁l7Q榛6_g)ὄ\u0013kj뤬^爖eO4Ⱈ槞鉨ͺ订%qX0T썗嫷$?\\\"봅늆'%": [ + -2.348150870600346E-19, + [[ + true, + -6619392047819511778, + false, + [[ + -1.2929189982356161E-20, + 1.7417192219309838E-19, + {"?嵲2࿐2\u0001啑㷳c縯": [ + null, + [ + false, + true, + 2578060295690793218, + { + "?\"殃呎#㑑F": true, + "}F炊_殛oU헢兔Ꝉ,赭9703.B数gTz3⏬": { + "5&t3,햓Mݸᵣ㴵;꣫䩍↳#@뫷䠅+W-ࣇzᓃ鿕ಔ梭?T䮑ꥬ旴]u뫵막bB讍:왳둛lEh=숾鱠p咐$짏#?g⹷ᗊv㷵.斈u頻\u0018-G.": "뽙m-ouࣤ஫牷\"`Ksꕞ筼3HlȨvC堈\"I]㖡玎r먞#'W賜鴇k'c룼髋䆿飉㗆xg巤9;芔cጐ/ax䊨♢큓r吓㸫೼䢗da᩾\"]屣`", + ":M딪<䢥喠\u0013㖅x9蕐㑂XO]f*Q呰瞊吭VP@9,㨣 D\\穎vˤƩs㜂-曱唅L걬/롬j㈹EB8g<\/섩o渀\"u0y&룣": ">氍緩L/䕑돯Ꟙ蕞^aB뒣+0jK⪄瑨痜LXK^힦1qK{淚t츔X:Vm{2r獁B뾄H첚7氥?쉟䨗ꠂv팳圎踁齀\\", + "D彤5㢷Gꪻ[lㄆ@὜⓰絳[ଃ獽쮹☒[*0ꑚ㜳": 9022717159376231865, + "ҖaV銣tW+$魿\u20c3亜~뫡ᙰ禿쨽㏡fṼzE/h": "5臐㋇Ჯ쮺? 昨탰Wム밎#'\"崲钅U?幫뺀⍾@4kh>騧\\0ҾEV=爐͌U捀%ꉼ 㮋<{j]{R>:gԩL\u001c瀈锌ﯲﳡꚒ'⫿E4暍㌗뵉X\"H᝜", + "ᱚגּ;s醒}犍SἿ㦣&{T$jkB\\\tḮ앾䤹o<避(tW": "vb⯽䴪䮢@|)", + "⥒퐁껉%惀뗌+녣迺顀q條g⚯i⤭룐M琹j̈́⽜A": -8385214638503106917, + "逨ꊶZ<\/W⫟솪㎮ᘇb?ꠔi\"H㧺x෷韒Xꫨฟ|]窽\u001a熑}Agn?Mᶖa9韲4$3Ỵ^=쏍煤ፐ돷2䣃%鷠/eQ9頸쥎", + 2398360204813891033, + false, + 3.2658897259932633E-19, + null, + "?ꚃ8Nn㞷幵d䲳䱲뀙ꪛQ瑓鎴]䩋-鰾捡䳡??掊", + false, + -1309779089385483661, + "ᦲxu_/yecR.6芏.ᜇ過 ~", + -5658779764160586501, + "쒌:曠=l썜䢜wk#s蕚\"互㮉m䉤~0듐䋙#G;h숄옥顇෤勹(C7㢅雚㐯L⠅VV簅<", + null, + -4.664877097240962E18, + -4.1931322262828017E18, + { + ",": { + "v㮟麑䄠뤵g{M띮.\u001bzt뢜뵡0Ǥ龍떟Ᾰ怷ϓRT@Lꀌ樂U㏠⾕e扉|bJg(뵒㠶唺~ꂿ(땉x⻫싉쁊;%0鎻V(o\f,N鏊%nk郼螺": -1.73631993428376141E18, + "쟧摑繮Q@Rᕾ㭚㾣4隅待㓎3蒟": [ + 4971487283312058201, + 8973067552274458613, + { + "`a揙ᣗ\u0015iBo¸": 4.3236479112537999E18, + "HW&퉡ぁ圍Y?瑡Qy훍q!帰敏s舠㫸zꚗaS歲v`G株巷Jp6킼 (귶鍔⾏⡈>M汐㞍ቴ꙲dv@i㳓ᇆ?黍": [ + null, + 4997607199327183467, + "E㻎蠫ᐾ高䙟蘬洼旾﫠텛㇛?'M$㣒蔸=A_亀绉앭rN帮", + null, + [{ + "Eᑞ)8餧A5u&㗾q?": [ + -1.969987519306507E-19, + null, + [ + 3.42437673373841E-20, + true, + "e걷M墁\"割P␛퍧厀R䱜3ﻴO퓫r﹉⹊", + [ + -8164221302779285367, + [ + true, + null, + "爘y^-?蘞Ⲽꪓa␅ꍨ}I", + 1.4645984996724427E-19, + [{ + "tY좗⧑mrzﺝ㿥ⴖ᥷j諅\u0000q賋譁Ꞅ⮱S\nࡣB/큃굪3Zɑ复o<\/;롋": null, + "彟h浠_|V4䦭Dᙣ♞u쿻=삮㍦\u001e哀鬌": [{"6횣楠,qʎꗇ鎆빙]㱭R굋鈌%栲j分僅ペ䇰w폦p蛃N溈ꡐꏀ?@(GI뉬$ﮄ9誁ꓚ2e甸ڋ[䁺,\u0011\u001cࢃ=\\+衪䷨ᯕ鬸K": [[ + "ㅩ拏鈩勥\u000etgWVXs陂規p狵w퓼{뮵_i\u0002ퟑႢ⬐d6鋫F~챿搟\u0096䚼1ۼ칥0꣯儏=鋷牋ⅈꍞ龐", + -7283717290969427831, + true, + [ + 4911644391234541055, + { + "I鈒첽P릜朸W徨觘-Hᎄ퐟⓺>8kr1{겵䍃〛ᬡ̨O귑o䝕'쿡鉕p5": "fv粖RN瞖蛐a?q꤄\u001d⸥}'ꣴ犿ꦼ?뤋?鵆쥴덋䡫s矷̄?ඣ/;괱絢oWfV<\/\u202cC,㖦0䑾%n賹g&T;|lj_欂N4w", + "짨䠗;䌕u i+r๏0": [{"9䥁\\఩8\"馇z䇔<\/ႡY3e狚쐡\"ุ6ﰆZ遖c\"Ll:ꮾ疣<\/᭙O◌납୕湞9⡳Und㫜\u0018^4pj1;䧐儂䗷ୗ>@e톬": { + "a⑂F鋻Q螰'<퇽Q贝瀧{ᘪ,cP&~䮃Z?gI彃": [ + -1.69158726118025933E18, + [ + "궂z簽㔛㮨瘥⤜䛖Gℤ逆Y⪾j08Sn昞ꘔ캻禀鴚P謦b{ꓮmN靐Mᥙ5\"睏2냑I\u0011.L&=?6ᄠ뻷X鸌t刑\"#z)o꫚n쳟줋", + null, + 7517598198523963704, + "ኑQp襟`uᩄr方]*F48ꔵn俺ሙ9뇒", + null, + null, + 6645782462773449868, + 1219168146640438184, + null, + { + ")ယ넌竀Sd䰾zq⫣⏌ʥ\u0010ΐ' |磪&p牢蔑mV蘸૰짬꺵;K": [ + -7.539062290108008E-20, + [ + true, + false, + null, + true, + 6574577753576444630, + [[ + 1.2760162530699766E-19, + [ + null, + [ + "顊\\憎zXB,", + [{ + "㇆{CVC9-MN㜋ઘR눽#{h@ퟨ!鼚׼XOvXS\u0017ᝣ=cS+梽៲綆16s덽휐y屬?ᇳG2ᴭ\u00054쫖y룇nKcW̭炦s/鰘ᬽ?J|퓀髣n勌\u0010홠P>j": false, + "箴": [ + false, + "鍞j\"ꮾ*엇칬瘫xṬ⭽쩁䃳\"-⋵?ᦽ댎Ĝ": true, + "Pg帯佃籛n㔠⭹࠳뷏≻࿟3㞱!-쒾!}쭪䃕!籿n涻J5ਲ਼yvy;Rኂ%ᔡጀ裃;M⣼)쵂쑈": 1.80447711803435366E18, + "ꈑC⡂ᑆ㤉壂뎃Xub<\/쀆༈憓ق쨐ק\\": [ + 7706977185172797197, + {"": {"K╥踮砆NWࡆFy韣7ä밥{|紒︧䃀榫rᩛꦡTSy잺iH8}ퟴ,M?Ʂ勺ᴹ@T@~꾂=I㙕뾰_涀쑜嫴曣8IY?ҿo줫fऒ}\\S\"ᦨ뵼#nDX": { + "♘k6?଱癫d68?㽚乳䬳-V顷\u0005蝕?\u0018䞊V{邾zじl]雏k臤~ൖH뒐iꢥ]g?.G碄懺䔛pR$䅒X觨l봜A刊8R梒',}u邩퉕?;91Ea䈈믁G⊶芔h袪&廣㺄j;㡏綽\u001bN頸쳘橆": -2272208444812560733, + "拑Wﵚj鵼駳Oࣿ)#㾅顂N傓纝y僱栜'Bꐍ-!KF*ꭇK¦?䈴^:啤wG逭w᧯": "xᣱmYe1ۏ@霄F$ě꧘푫O䤕퀐Pq52憬ꀜ兴㑗ᡚ?L鷝ퟐ뭐zJꑙ}╆ᅨJB]\"袌㺲u8䯆f", + "꿽၅㔂긱Ǧ?SI": -1669030251960539193, + "쇝ɨ`!葎>瞺瘡驷錶❤ﻮ酜=": -6961311505642101651, + "?f7♄꫄Jᡔ훮e읇퍾፣䭴KhखT;Qty}O\\|뫁IῒNe(5惁ꥶㆷY9ﮡ\\ oy⭖-䆩婁m#x봉>Y鈕E疣s驇↙ᙰm<": {"퉻:dꂁ&efᅫ쫢[\"돈늖꺙|Ô剐1͖-K:ʚ᭕/;쏖㷛]I痐职4gZ4⍜kเꛘZ⥺\\Bʫᇩ鄨魢弞&幟ᓮ2̊盜", + -9006004849098116748, + -3118404930403695681, + { + "_彃Y艘-\"Xx㤩㳷瑃?%2䐡鵛o귵옔夘v*탋职&㳈챗|O钧": [ + false, + "daꧺdᗹ羞쯧H㍤鄳頳<型孒ン냆㹀f4㹰\u000f|C*ሟ鰠(O<ꨭ峹ipຠ*y೧4VQ蔔hV淬{?ᵌEfrI_", + "j;ꗣ밷邍副]ᗓ", + -4299029053086432759, + -5610837526958786727, + [ + null, + [ + -1.3958390678662759E-19, + { + "lh좈T_믝Y\"伨\u001cꔌG爔겕ꫳ晚踍⿻읐T䯎]~e#฽燇\"5hٔ嶰`泯r;ᗜ쮪Q):/t筑,榄&5懶뎫狝(": [{ + "2ፁⓛ]r3C攟וּ9賵s⛔6'ஂ|\"ⵈ鶆䐹禝3\"痰ࢤ霏䵩옆䌀?栕r7O簂Isd?K᫜`^讶}z8?z얰T:X倫⨎ꑹ": -6731128077618251511, + "|︦僰~m漿햭\\Y1'Vvخ굇ቍ챢c趖": [null] + }], + "虌魿閆5⛔煊뎰㞤ᗴꥰF䮥蘦䂪樳-K᝷-(^\u20dd_": 2.11318679791770592E17 + } + ] + ] + ]}, + "묗E䀳㧯᳀逞GMc\b墹㓄끖Ơ&U??펌鑍 媋k))ᄊ": null, + "묥7콽벼諌J_DɯﮪM殴䣏,煚ྼ`Y:씧<\/⩫%yf䦀!1Ჶk춎Q米W∠WC跉鬽*ᛱi㴕L꘻ꀏ쓪\"_g鿄'#t⽙?,Wg㥖|D鑆e⥏쪸僬h鯔咼ඡ;4TK聎졠嫞" + } + ] + ] + } + ] + ] + ]}} + } + ]} + }, + "뿋뀾淣截䔲踀&XJ펖꙯^Xb訅ꫥgᬐ>棟S\"혧騾밫겁7-": "擹8C憎W\"쵮yR뢩浗絆䠣簿9䏈引Wcy䤶孖ꯥ;퐌]輩䍐3@{叝 뽸0ᡈ쵡Ⲇ\u001dL匁꧐2F~ݕ㪂@W^靽L襒ᦘ~沦zZ棸!꒲栬R" + } + ] + ], + "Z:덃൛5Iz찇䅄駠㭧蓡K1": "e8᧤좱U%?ⵇ䯿鿝\u0013縮R∱骒EO\u000fg?幤@֗퉙vU`", + "䐃쪈埽້=Ij,쭗쓇చ": false + }]}} + ] + } + ]} + } + ] + ] + ], + "咰긖VM]᝼6䓑쇎琺etDҌ?㞏ꩄ퇫밉gj8蠃\"⩐5䛹1ࣚ㵪": "ക蹊?⎲⧘⾚̀I#\"䈈⦞돷`wo窭戕෱휾䃼)앷嵃꾞稧,Ⴆ윧9S?೗EMk3Მ3+e{⹔Te驨7䵒?타Ulg悳o43" + } + ], + "zQᤚ纂땺6#ٽ﹧v￿#ࠫ휊冟蹧텈ꃊʆ?&a䥯De潝|쿓pt瓞㭻啹^盚2Ꝋf醪,얏T窧\\Di䕎谄nn父ꋊE": -2914269627845628872, + "䉩跐|㨻ᷢ㝉B{蓧瞸`I!℄욃힕#ೲᙾ竛ᔺCjk췒늕貭词\u0017署?W딚%(pꍁ⤼띳^=on뺲l䆼bzrﳨ[&j狸䠠=ᜑꦦ\u2061յnj=牲攑)M\\龏": false, + "뎕y絬᫡⥮Ϙᯑ㌔/NF*˓.,QEzvK!Iwz?|쥾\"ꩻL꼗Bꔧ賴緜s뉣隤茛>ロ?(?^`>冺飒=噸泥⺭Ᲊ婓鎔븜z^坷裮êⓅ໗jM7ﶕ找\\O": 1.376745434746303E-19 + }, + "䐛r滖w㏤,|Nዜ": false + } + ]], + "@꿙?薕尬 gd晆(띄5躕ﻫS蔺4)떒錸瓍?~": 1665108992286702624, + "w믍nᏠ=`঺ᅥC>'從됐槷䤝眷螄㎻揰扰XᅧC贽uჍ낟jKD03T!lDV쀉Ӊy뢖,袛!终캨G?鉮Q)⑗1쾅庅O4ꁉH7?d\u0010蠈줘월ސ粯Q!낇껉6텝|{": null, + "~˷jg쿤촖쉯y": -5.5527605669177098E18, + "펅Wᶺzꐆと푭e?4j仪열[D<鈑皶婆䵽ehS?袪;HꍨM뗎ば[(嗏M3q퍟g4y╸鰧茀[Bi盤~﫝唎鋆彺⦊q?B4쉓癚O洙킋툈䶯_?ퟲ": null + } + ] + ]] + ]], + "꟱Ԕ㍤7曁聯ಃ錐V䷰?v㪃૦~K\"$%请|ꇹn\"k䫛㏨鲨\u2023䄢\u0004[︊VJ?䶟ាꮈ䗱=깘U빩": -4863152493797013264 + } + ]}]} + ] + }}} + ], + "쏷쐲۹퉃~aE唙a챑,9㮹gLHd'䔏|킗㍞䎥&KZYT맵7䥺Nⱳ同莞鿧w\\༌疣n/+ꎥU\"封랾○ퟙAJᭌ?9䛝$?驔9讐짘魡T֯c藳`虉C읇쐦T" + } + ], + "谶개gTR￐>ၵ͚dt晑䉇陏滺}9㉸P漄": -3350307268584339381 + }] + ] + ] + ]] + ] + ], + "0y꟭馋X뱔瑇:䌚￐廿jg-懲鸭䷭垤㒬茭u賚찶ಽ+\\mT땱\u20821殑㐄J쩩䭛ꬿNS潔*d\\X,壠뒦e殟%LxG9:摸": 3737064585881894882, + "풵O^-⧧ⅶvѪ8廸鉵㈉ר↝Q㿴뺟EႳvNM:磇>w/៻唎뷭୥!냹D䯙i뵱貁C#⼉NH6`柴ʗ#\\!2䂗Ⱨf?諳.P덈-返I꘶6?8ꐘ": -8934657287877777844, + "溎-蘍寃i诖ര\"汵\"\ftl,?d⼡쾪⺋h匱[,෩I8MҧF{k瓿PA'橸ꩯ綷퉲翓": null + } + ] + ], + "ោ係؁<元": 1.7926963090826924E-18 + }}] + } + ] + ]]}] + }] + ] + ] + ] + ], + "ጩV<\"ڸsOᤘ": 2.0527167903723048E-19 + }] + ]} + ] + ]], + "∳㙰3젴p᧗䱙?`yZA8Ez0,^ᙛ4_0븢\u001ft:~䎼s.bb룦明yNP8弆C偯;⪾짍'蕴뮛": -6976654157771105701, + "큵ꦀ\\㇑:nv+뒤燻䀪ﴣ﷍9ᚈ኷K㚊誦撪䚛,ꮪxሲ쳊\u0005HSf?asg昱dqꬌVꙇ㼺'k*'㈈": -5.937042203633044E-20 + } + ] + }], + "?}\u20e0],s嶳菋@#2u쒴sQS䩗=ꥮ;烌,|ꘔ䘆": "ᅩ영N璠kZ먕眻?2ቲ芋眑D륟渂⸑ﴃIRE]啗`K'" + }}, + "쨀jmV賂ﰊ姐䂦玞㬙ᏪM᪟Վ씜~`uOn*ॠ8\u000ef6??\\@/?9見d筜ﳋB|S䝬葫㽁o": true + }, + "즛ꄤ酳艚␂㺘봿㎨iG৕ࡿ?1\"䘓您\u001fSኝ⺿溏zៀ뻤B\u0019?윐a䳵᭱䉺膷d:<\/": 3935553551038864272 + } + ] + ]} + ]] + ]] + ]} + } + ] + } + ]]}}, + "᥺3h↛!ꋰy\"攜(ெl䪕oUkc1A㘞ᡲ촾ᣫ<\/䒌E㛝潨i{v?W౾H\\RჅpz蝬R脾;v:碽✘↯삞鷱o㸧瑠jcmK7㶧뾥찲n": true, + "ⶸ?x䊺⬝-䰅≁!e쩆2ꎿ准G踌XXᩯ1߁}0?.헀Z馟;稄\baDꟹ{-寪⚈ꉷ鮸_L7ƽᾚ<\u001bጨA䧆송뇵⨔\\礍뗔d设룱㶉cq{HyぱR㥽吢ſtp": -7985372423148569301, + "緫#콮IB6<\/=5Eh礹\t8럭@饹韠r㰛斣$甝LV췐a갵'请o0g:^": "䔨(.", + "띳℡圤pン௄ĝ倧訜B쁟G䙔\"Sb⓮;$$▏S1J뢙SF|赡g*\"Vu䲌y": "䪈&틐),\\kT鬜1풥;뷴'Zေ䩹@J鞽NぼM?坥eWb6榀ƩZڮ淽⺞삳煳xჿ絯8eⶍ羷V}ჿ쎱䄫R뱃9Z>'\u20f1ⓕ䏜齮" + } + ] + ]]] + }} + } + ] + ]}, + "펮b.h粔폯2npX詫g錰鷇㇒<쐙S値bBi@?镬矉`剔}c2壧ଭfhY깨R()痩⺃a\\⍔?M&ﯟ<劜꺄멊ᄟA\"_=": null + }, + "~潹Rqn榢㆓aR鬨侅?䜑亡V_翅㭔(䓷w劸ၳDp䀅<\/ﰎ鶊m䵱팱긽ꆘ긓准D3掱;o:_ќ)껚콥8곤d矦8nP倥ꃸI": null, + "뾎/Q㣩㫸벯➡㠦◕挮a鶧⋓偼\u00001뱓fm覞n?㛅\"": 2.8515592202045408E17 + }], + ",": -5426918750465854828, + "2櫫@0柡g䢻/gꆑ6演&D稒肩Y?艘/놘p{f투`飷ᒉ챻돎<늛䘍ﴡ줰쫄": false, + "8(鸑嵀⵹ퟡ<9㣎Tߗ┘d슒ل蘯&㠦뮮eࠍk砝g 엻": false, + "d-\u208b?0ﳮ嵙'(J`蔿d^踅⤔榥\\J⵲v7": 6.8002426206715341E17, + "ཎ耰큓ꐕ㱷\u0013y=詽I\"盈xm{0쾽倻䉚ષso#鰑/8㸴짯%ꀄ떸b츟*\\鲷礬ZQ兩?np㋄椂榨kc᡹醅3": false, + "싊j20": false + }]] + ]], + "俛\u0017n緽Tu뫉蜍鼟烬.ꭠIⰓ\"Ἀ᜾uC쎆J@古%ꛍm뻨ᾀ画蛐휃T:錖㑸ዚ9죡$": true + } + ] + ], + "㍵⇘ꦖ辈s}㱮慀밒s`\"㞟j:`i픻Z섫^諎0Ok{켿歁෣胰a2﨤[탳뚬쎼嫭뉮m": 409440660915023105, + "w墄#*ᢄ峠밮jLa`ㆪ꺊漓Lで끎!Agk'ꁛ뢃㯐岬D#㒦": false, + "ଦPGI䕺L몥罭ꃑ궩﮶#⮈ᢓӢ䚬p7웼臧%~S菠␌힀6&t䳙y㪘냏\\*;鉏ᅧ鿵'嗕pa\"oL쇿꬈Cg": "㶽1灸D⟸䴅ᆤ뉎﷛渤csx 䝔цꬃ锚捬?ຽ+x~꘩uI࡞\u0007栲5呚ẓem?袝\")=㥴䨃pac!/揎Y", + "ᷱo\\||뎂몷r篙|#X䦜I#딌媸픕叞RD斳X4t⯩夬=[뭲r=绥jh뷱츝⪘%]⚋܈㖴スH텹m(WO曝劉0~K3c柢Ր㏉着逳~": false, + "煽_qb[첑\\륌wE❽ZtCNﭝ+餌ᕜOꛭ": "{ﳾ쉌&s惧ᭁⵆ3䢫;䨞팑꒪흘褀࢖Q䠿V5뭀䎂澻%받u5텸oA⮥U㎦;B䳌wz䕙$ឿ\\௅婺돵⪾퐆\\`Kyौꋟ._\u0006L챯l뇠Hi䧈偒5", + "艊佁ࣃ롇䱠爬!*;⨣捎慓q靓|儑ᨋL+迥=6㒺딉6弄3辅J-㕎뛄듘SG㆛(\noAzQꝱ䰩X*ぢO퀌%펠낌mo틮a^<\/F&_눊ᾉ㨦ы4\"8H": 2974648459619059400, + "鬙@뎣䫳ၮ끡?){y?5K;TA*k溱䫜J汃ꂯ싔썍\u001dA}룖(<\/^,": false, + "몏@QꋦFꊩᒐ뎶lXl垨4^郣|ꮇ;䝴ᝓ}쵲z珖": null + } + ]]]], + ":_=닧弗D䙋暨鏛. 㱻붘䂍J儒&ZK/녩䪜r囁⽯D喠죥7⹌䪥c\u001a\u2076￞妈朹oLk菮F౟覛쐧㮏7T;}蛙2{9\"崓bB<\/⡷룀;즮鿹)丒툃୤뷠5W⊢嶜(fb뭳갣": "E{响1WM" + }}, + "䘨tjJ驳豨?y輊M*᳑梵瞻઻ofQG瑮e": 2.222802939724948E-19, + "䮴=❑➶T෋w䞜\"垦ꃼUt\u001dx;B$뵣䙶E↌艣ᡥ!᧟;䱀[䔯k쬃`੍8饙른熏'2_'袻tGf蒭J땟as꯳╖&啒zWࡇᒫYSᏬ\u0014ℑ첥鈤|cG~Pᓮ\">\"": "ႆl\f7V儊㦬nHꄬꨧC{쐢~C⮃⛓嶦vꄎ1w鰠嘩뿠魄&\"_qMⵖ釔녮ꝇ 㝚{糍J哋 cv?-jkﻯྌ鹑L舟r", + "龧葆yB✱H盋夔ﶉ?n*0(": "ꧣኆ㢓氥qZZ酒ຜ)鮢樛)X䣆gTSґG텞k.J圬疝롫쯭z L:\\ྤ@w炋塜쿖ᾳy뢀䶃뱝N䥨㚔勇겁#p", + "도畎Q娡\"@S/뼋:䵏!P衅촚fVHQs✜ᐫi㻑殡B䜇%믚k*U#濨낄~": "ꍟዕ쳸ꍈ敋&l妏\u0005憡멗瘌uPgᅪm<\/To쯬锩h뒓k" + } + ] + }], + "墥홞r绚<\/⸹ⰃB}<躅\\Y;๑@䔸>韫䜲뱀X뗩鿥쩗SI%ﴞ㳕䛇?<\/\u00018x\\&侂9鋙a[LR㋭W胕)⡿8㞙0JF,}?허d1cDMᐃ␛鄝ⱕ%X)!XQ": "ⳍꗳ=橇a;3t⦾꼑仈ူaᚯ⯋ꕃAs鴷N⍕_䎃ꙎAz\u0016䯷\\<࿫>8q{}キ?ᣰ}'0ᴕ펓B┦lF#趤厃T?㕊#撹圂䆲" + }, + "܋닐龫論c웑": false, + "ㇿ/q\"6-co髨휝C큦#\u001b4~?3䐹E삇<<": 7.600917488140322E-20, + "䁝E6?㣖ꃁ间t祗*鑠{ḣV(浾h逇큞=W?ૉ?nꇽ8ꅉຉj으쮺@Ꚅ㰤u]Oyr": "v≁᫸_*όAඤԆl)ۓᦇQ}폠z༏q滚", + "ソ᥊/넺I": true + }]] + ] + ] + ] + ]] + }, + "䭑Ik攑\u0002QV烄:芩.麑㟴㘨≕": true, + "坄꿕C쇻풉~崍%碼\\8\"䬦꣙": null, + "欌L圬䅘Y8c(♺2?ON}o椳s宥2䉀eJ%闹r冁O^K諭%凞⺉⡻,掜?$ꥉ?略焕찳㯊艼誜4?\"﯎<゛XፈINT:詓 +": -1.0750456770694562E-19, + "獒àc뜭싼ﺳ뎤K`]p隨LtE": null, + "甙8䵊神EIꩤ鐯ᢀ,ﵮU䝑u疒ử驺䚿≚ഋ梶秓F`覤譐#짾蔀묊4<媍쬦靪_Yzgcࡶ4k紥`kc[Lﮗ簐*I瀑[⾰L殽鑥_mGȠ<\/|囹灠g桰iri": true, + "챓ꖙꟻ좝菇ou,嗠0\\jK핻뜠qwQ?ഩ㼕3Y彦b\u009bJ榶N棨f?됦鏖綃6鳵M[OE봨u햏.Ꮁ癜蟳뽲ꩌ뻾rM豈R嗀羫 uDꎚ%": null + }, + "V傜2<": 7175127699521359521 + }], + "铫aG切<\/\"ী⊆e<^g࢛)D顝nאַ饼\u008c猪繩嵿ﱚCꡬ㻊g엺A엦\u000f暿_f꿤볝㦕桦`蒦䎔j甬%岝rj 糏": "䚢偎눴Au<4箞7礦Iﱔ坠eȧ䪸u䵁p|逹$嗫쨘ꖾ﷐!胠z寓팢^㨔|u8Nሇe텔ꅦ抷]،鹎㳁#༔繁 ", + "낂乕ꃻ볨ϱ-ꇋ㖍fs⿫)zꜦ/K?솞♞ꑌ宭hJ᤭瑥Fu": false, + "쟰ぜ魛G\u0003u?`㾕ℾ㣭5螠烶這趩ꖢ:@咕ꐶx뒘느m䰨b痃렐0鳊喵熬딃$摉_~7*ⱦ녯1錾GKhJ惎秴6'H妈Tᧅ窹㺒疄矤铟wላ": null, + "쯆q4!3錕㲏ⵆ㇛꘷Z瑩뭆\\◪NH\u001d\\㽰U~㯶<\"쑣낞3ᵤ'峉eꢬ;鬹o꣒木X*長PXᘱu\"䠹n惞": null, + "ᅸ祊\"&ꥴCjࢼ﴿?䡉`U效5殼㮞V昽ꏪ#ﺸ\\&t6x꠹盥꣰a[\u001aꪍSpe鎿蠹": -1.1564713893659811E-19 + } + ]] + ] + ] + ], + "羵䥳H,6ⱎ겾|@t\"#햊1|稃 섭)띜=뻔ꡜ???櫎~*ῡ꫌/繣ﻠq": null + } + ]} + ]}, + "츤": false + }}, + "s": 3.7339341963399598E18 + } + ], + "N,I?1+㢓|ࣱ嶃쩥V2\u0012(4EE虪朶$|w颇v步": "~읢~_,Mzr㐫YB溓E淚\"ⅹ䈔ᏺ抙 b,nt5V㐒J檶ꏨ⻔?", + "Q껑ꡡ}$넎qH煔惍/ez^!ẳF댙䝌馻剁8": "梲;yt钰$i冄}AL%a j뜐奷걳뚾d꿽*ሬuDY3?뮟鼯뮟w㍪틱V", + "o{Q/K O胟㍏zUdꀐm&⨺J舕⾏魸訟㌥[T籨櫉唐킝 aṭ뱫촙莛>碶覆⧬짙쭰ׯdAiH໥벤퐥_恸[ 0e:죃TC弼荎뵁DA:w唵ꣁ": null, + "὏樎䵮軧|?౗aWH쩃1 ꅭsu": null + } + ] + }, + "勂\\&m鰈J釮=Ⲽ鳋+䂡郑": null, + "殣b綊倶5㥗惢⳷萢ᑀ䬄镧M^ﱴ3⣢翣n櫻1㨵}ኯ뗙顖Z.Q➷ꮨ뗇\u0004": "ꔙ䁼>n^[GीA䨟AM琢ᒊS쨲w?d㶣젊嘶纝麓+愣a%気ྞSc됓ᔘ:8bM7Xd8㶑臌]Ꙥ0ꐭ쒙䫣挵C薽Dfⵃ떼᷸", + "?紡.셪_෨j\u0013Ox┠$Xᶨ-ᅇo薹-}軫;y毝㪜K㣁?.EV쮱4둽⛻䤜'2盡\u001f60(|e쐰㼎ᦀ㒧-$l@ﻑ坳\u0003䭱响巗WFo5c㧆T턁Y맸♤(": -2.50917882560589088E17 + }} + ], + "侸\\릩.᳠뎠狣살cs项䭩畳H1s瀉븇19?.w骴崖㤊h痠볭㞳㞳䁮Ql怠㦵": "@䟴-=7f", + "鹟1x௢+d ;vi䭴FSDS\u0004hꎹ㚍?⒍⦏ў6u,扩@됷Su)Pag휛TᒗV痩!瞏釀ꖞ蘥&ೞ蘐ꭰꞇᝎ": "ah懱Ժ&\u20f7䵅♎඀䞧鿪굛ౕ湚粎蚵ᯋ幌YOE)५襦㊝Y*^\"R+ඈ咷蝶9ꥂ榨艦멎헦閝돶v좛咊E)K㓷ྭr", + "搆q쮦4綱켙셁.f4<\/g<籽늷?#蚴픘:fF\u00051㹉뀭.ᰖ풎f֦Hv蔎㧤.!䭽=鞽]음H:?\"-4": 8.740133984938656E-20 + }]} + } + ], + "tVKn딩꘥⊾蹓᤹{\u0003lR꼽ᄲQFᅏ傅ﱋ猢⤊ᔁ,E㓒秤nTතv`♛I\u0000]꫔ṞD\"麵c踝杰X&濿또꣹깳౥葂鿎\\aꡨ?": 3900062609292104525 + } + ], + "ਉ샒⊩Lu@S䧰^g": -1.1487677090371648E18, + "⎢k⑊꬗yᏫ7^err糎Dt\u000bJ礯확ㆍ沑サꋽe赔㝢^J\u0004笲㿋idra剰-᪉C錇/Ĝ䂾ညS지?~콮gR敉⬹'䧭": 1901472137232418266, + "灗k䶥:?촽贍쓉꓈㒸g獘[뵎\\胕?\u0014_榙p.j稶,$`糉妋0>Fᡰly㘽$?": "]ꙛO赎&#㠃돱剳\"<◆>0誉齐_|z|裵씪>ᐌ㼍\"Z[琕}O?G뚇諦cs⠜撺5cu痑U圲\u001c?鴴計l춥/╓哼䄗茏ꮅ뫈댽A돌롖뤫V窗讬sHd&\nOi;_u" + } + ], + "Uﺗ\\Y\\梷䄬~\u0002": null, + "k\"Y磓ᗔ휎@U冈<\/w컑)[": false, + "曏J蝷⌻덦\u001f㙳s꥓⍟邫P늮쥄c∬ྡྷ舆렮칤Z趣5콡넛A쳨\\뀙骫(棻.*&輛LiIfi{@EA婳KᬰTXT": -4.3088230431977587E17 + }]} + ] + ], + "곃㲧<\/dఓꂟs其ࡧ&N葶=?c㠤Ჴ'횠숄臼#\u001a~": false + } + ] + ]}] + }] + }} + ], + "2f`⽰E쵟>J笂裭!〛觬囀ۺ쟰#桊l鹛ⲋ|RA_Vx፭gE됓h﵀mfỐ|?juTU档[d⢼⺻p濚7E峿": 5613688852456817133 + }, + "濘끶g忮7㏵殬W팕Q曁 뫰)惃廊5%-蹚zYZ樭ﴷQ锘쯤崫gg": true, + "絥ᇑ⦏쒓븣爚H.㗊߄o蘵貆ꂚ(쎔O᥉ﮓ]姨Wꁓ!RMA|o퉢THx轮7M껁U즨'i뾘舯o": "跥f꜃?" + }} + ], + "鷰鹮K-9k;ﰰ?_ݦѷ-ꅣ䩨Zꥱ\"mꠟ屎/콑Y╘2&鸞脇㏢ꀇ࠺ⰼ拾喭틮L꽩bt俸墶 [l/웄\"꾦\u20d3iও-&+\u000fQ+໱뵞": -1.296494662286671E-19 + }, + "HX੹/⨇୕붷Uﮘ旧\\쾜͔3l鄈磣糂̖䟎Eᐳw橖b῀_딕hu葰窳闹вU颵|染H죶.fP䗮:j䫢\\b뎖i燕ꜚG⮠W-≚뉗l趕": "ଊ칭Oa᡺$IV㷧L\u0019脴셀붿餲햪$迳向쐯켂PqfT\" ?I屉鴼쿕@硙z^鏕㊵M}㚛T젣쓌-W⩐-g%⺵<뮱~빅╴瑿浂脬\u0005왦燲4Ⴭb|D堧 <\/oEQh", + "䘶#㥘੐캔f巋ἡAJ䢚쭈ࣨ뫒*mᇊK,ࣺAꑱ\u000bR<\/A\"1a6鵌㯀bh곿w(\"$ꘁ*rಐ趣.d࿩k/抶면䒎9W⊃9": "漩b挋Sw藎\u0000", + "畀e㨼mK꙼HglKb,\"'䤜": null + }]}] + ] + ] + }] + ]} + ] + ]} + ], + "歙>駿ꣂ숰Q`J΋方樛(d鱾뼣(뫖턭\u20f9lচ9歌8o]8윶l얶?镖G摄탗6폋폵+g:䱫홊<멀뀿/س|ꭺs걐跶稚W々c㫣⎖": "㣮蔊깚Cꓔ舊|XRf遻㆚︆'쾉췝\\&言", + "殭\"cށɨꝙ䞘:嬮e潽Y펪㳅/\"O@ࠗ겴]췖YǞ(t>R\"N?梳LD恭=n氯T豰2R諸#N}*灧4}㶊G䍣b얚": null, + "襞<\/啧 B|싞W瓇)6簭鼡艆lN쩝`|펭佡\\間邝[z릶&쭟愱ꅅ\\T᰽1鯯偐栈4̸s윜R7⒝/똽?치X": "⏊躖Cﱰ2Qẫ脐&இ?%냝悊", + ",鰧偵셣싹xᎹ힨᯳EṬH㹖9": -4604276727380542356 + } + } + ]]]], + "웺㚑xs}q䭵䪠馯8?LB犯zK'os䚛HZ\"L?셎s^㿧㴘Cv2": null + }] + ] + ] + ], + "Kd2Kv+|z": 7367845130646124107, + "ᦂⶨ?ᝢ 祂些ഷ牢㋇操\"腭䙾㖪\\(y4cE뽺ㆷ쫺ᔖ%zfۻ$ў1柦,㶢9r漢": -3.133230960444846E-20, + "琘M焀q%㢟f鸯O⣏蓑맕鯊$O噷|)z褫^㢦⠮ꚯ꫞`毕1qꢚ{ĭ䎀বώT\"뱘3G൴?^^of": null + } + ], + "a8V᯺?:ﺃ/8ꉿBq|9啓댚;*i2": null, + "cpT瀇H珰Ừpೃi鎪Rr␣숬-鹸ҩ䠚z脚цGoN8入y%趌I┽2ឪЀiJNcN)槣/▟6S숆牟\"箑X僛G殱娇葱T%杻:J諹昰qV쨰": 8331037591040855245 + }], + "G5ᩜ䄗巢껳": true + } + }, + "Ồ巢ゕ@_譙A`碫鄐㡥砄㠓(^K": "?܃B혢▦@犑ὺD~T⧁|醁;o=J牌9냚⢽㨘{4觍蚔9#$∺\u0016p囅\\3Xk阖⪚\"UzA穕롬✎➁㭒춺C㣌ဉ\"2瓑员ᅽꝶ뫍}꽚ꞇ鶂舟彺]ꍽJC蝧銉", + "␆Ě膝\"b-퉐ACR言J謈53~V튥x䜢?ꃽɄY뮩ꚜ": "K/↾e萃}]Bs⾿q룅鷦-膋?m+死^魊镲6", + "粡霦c枋AHퟁo礼Ke?qWcA趸㡔ꂏ?\u000e춂8iতᦜ婪\u0015㢼nﵿꍻ!ᐴ関\u001d5j㨻gfῩUK5Ju丝tかTI'?㓏t>⼟o a>i}ᰗ;뤕ܝ": false, + "ꄮ匴껢ꂰ涽+䜨B蛹H䛓-k蕞fu7kL谖,'涃V~챳逋穞cT\"vQ쓕ObaCRQ㓡Ⲯ?轭⫦輢墳?vA餽=h䮇킵n폲퉅喙?\"'1疬V嬗Qd灗'Lự": "6v!s믁㭟㣯獃!磸餠ቂh0C뿯봗F鷭gꖶ~コkK<ᦈTt\\跓w㭣횋钘ᆹ듡䑚W䟾X'ꅔ4FL勉Vܴ邨y)2'〚쭉⽵-鞣E,Q.?块", + "?(˧쩯@崟吋歄K": null + }, + "Gc럃녧>?2DYI鴿\\륨)澔0ᔬlx'觔7젘⤡縷螩%Sv׫묈/]↱&S h\u0006歋ᑛxi̘}ひY蔯_醨鯘煑橾8?䵎쨋z儬ꁏ*@츾:": null + } + } + } + ] + ] + ]} + }, + "HO츧G": 3.694949578823609E17, + "QC\u0012(翻曇Tf㷟bGBJ옉53\\嚇ᛎD/\u001b夾၉4\"핀@祎)쫆yD\"i먎Vn㿿V1W᨝䶀": -6150931500380982286, + "Z㓮P翸鍱鉼K䋞꘺튿⭁Y": -7704503411315138850, + "]모开ꬖP븣c霤<[3aΠ\"黁䖖䰑뮋ꤦ秽∼㑷冹T+YUt\"싳F↭䖏&鋌": -2.7231911483181824E18, + "tꎖ": -4.9517948741799555E-19, + "䋘즊.⬅IꬃۣQ챢ꄑ黐|f?C⾺|兕읯sC鬸섾整腨솷V": "旆柩l쪦sᖸMy㦅울썉瘗㎜檵9ꍂ駓ૉᚿ/u3씅徐拉[Z䞸ࡗ1ꆱ&Q풘?ǂ8\u0011BCDY2볨;鸏": null, + "幫 n煥s쁇펇 왊-$C\"衝:\u0014㣯舼.3뙗Yl⋇\"K迎멎[꽵s}9鉳UK8쐥\"掄㹖h㙈!얄સ?Ꜳ봺R伕UTD媚I䜘W鏨蔮": -4.150842714188901E-17, + "ﺯ^㄄\b죵@fྉkf颡팋Ꞧ{/Pm0V둳⻿/落韒ꊔᚬ@5螺G\\咸a谆⊪ቧ慷绖?财(鷇u錝F=r၍橢ឳn:^iᴵtD볠覅N赴": null + }] + }] + } + ] + ]} + ]}, + "謯?w厓奰T李헗聝ឍ貖o⪇弒L!캶$ᆅ": -4299324168507841322, + "뺊奉_垐浸延몏孄Z舰2i$q붿좾껇d▵餏\"v暜Ҭ섁m￴g>": -1.60911932510533427E18 + } + ] + } + ] + ]], + "퉝꺔㠦楶Pꅱ": 7517896876489142899, + "": false + } + ]}, + "是u&I狻餼|谖j\"7c됮sסּ-踳鉷`䣷쉄_A艣鳞凃*m⯾☦椿q㎭N溔铉tlㆈ^": 1.93547720203604352E18, + "kⲨ\\%vr#\u000bⒺY\\t<\/3﬌R訤='﹠8蝤Ꞵ렴曔r": false + } + ]}, + "阨{c?C\u001d~K?鎌Ԭ8烫#뙣P초遗t㭱E­돒䆺}甗[R*1!\\~h㕅᰺@<9JꏏષI䳖栭6綘걹ᅩM\"▯是∔v鬽顭⋊譬": "운ﶁK敂(欖C취پ℄爦賾" + } + }} + }], + "鷨赼鸙+\\䭣t圙ڹx᜾ČN<\/踘\"S_맶a鷺漇T彚⎲i㈥LT-xA캔$\u001cUH=a0츺l릦": "溣㣂0濕=鉵氬駘>Pꌢpb솇쬤h힊줎獪㪬CrQ矠a&脍꼬爼M茴/΅\u0017弝轼y#Ꞡc6둴=?R崏뷠麖w?" + }, + "閕ᘜ]CT)䵞l9z'xZF{:ؐI/躅匽졁:䟇AGF૸\u001cퟗ9)駬慟ꡒꆒRS״툋A<>\u0010\"ꂔ炃7g덚E৏bꅰ輤]o㱏_뷕ܘ暂\"u": "芢+U^+㢩^鱆8*1鈶鮀\u0002뺰9⬳ꪮlL䃣괟,G8\u20a8DF㉪錖0ㄤ瓶8Nଷd?眡GLc陓\\_죌V쁰ल二?c띦捱 \u0019JC\u0011b⤉zẒT볕\"绣蘨뚋cꡉkI\u001e鳴", + "ꃣI'{6u^㡃#཰Kq4逹y൒䧠䵮!㱙/n??{L풓ZET㙠퍿X2᩟綳跠葿㚙w཮x캽扳B唕S|尾}촕%N?o䪨": null, + "ⰴFjෟ셈[\u0018辷px?椯\\1<ﲻ栘ᣁ봢憠뉴p": -5263694954586507640 + } + ] + ]] + ]} + ]}] + ] + ], + "?#癘82禩鋆ꊝty?&": -1.9419029518535086E-19 + } + ] + ] + ]} + ] + ] + ], + "훊榲.|῕戄&.㚏Zꛦ2\"䢥ሆ⤢fV_摕婔?≍Fji冀탆꜕i㏬_ẑKᅢ꫄蔻XWc|饡Siẘ^㲦?羡2ぴ1縁ᙅ?쐉Ou": false + }]] + ]}}}, + "慂뗄卓蓔ᐓ匐嚖/颹蘯/翻ㆼL?뇊,텵<\\獷ごCボ": null + }, + "p溉ᑟi짣z:䒤棇r^٫%G9缑r砌롧.물农g?0׼ሩ4ƸO㣥㯄쩞ጩ": null, + "껎繥YxK\"F젷쨹뤤1wq轫o?鱑뜀瘊?뎃h灑\\ꛣ}K峐^ኖ⤐林ꉓhy": null + } + ], + "᱀n肓ㄛ\"堻2>m殮'1橌%Ꞵ군=Ӳ鯨9耛<\/n據0u彘8㬇៩f᏿诙]嚊": "䋯쪦S럶匏ㅛ#)O`ሀX_鐪渲⛀㨻宅闩➈ꢙஶDR⪍" + }, + "tA썓龇 ⋥bj왎录r땽✒롰;羋^\\?툳*┎?썀ma䵳넅U䳆૘〹䆀LQ0\b疀U~u$M}(鵸g⳾i抦뛹?䤈땚검.鹆?ꩡtⶥGĒ;!ቹHS峻B츪켏f5≺": 2366175040075384032, + "전pJjleb]ួ": -7.5418493141528422E18, + "n.鎖ጲ\n?,$䪘": true + }, + "欈Ar㉣螵᪚茩?O)": null + }, + "쫸M#x}D秱欐K=侫们丐.KꕾxẠ\u001e㿯䣛F܍캗qq8꟞ṢFD훎⵳簕꭛^鳜\u205c٫~⑟~冫ऊ2쫰<\/戲윱o<\"": true + }, + "㷝聥/T뱂\u0010锕|内䞇x侁≦㭖:M?iM᣿IJe煜dG࣯尃⚩gPt*辂.{磼럾䝪@a\\袛?}ᓺB珼": true + } + } + ]]}]}}, + "tn\"6ꫤ샾䄄;銞^%VBPwu묪`Y僑N.↺Ws?3C⤻9唩S䠮ᐴm;sᇷ냞඘B/;툥B?lB∤)G+O9m裢0kC햪䪤": -4.5941249382502277E18, + "ᚔt'\\愫?鵀@\\びꂕP큠<<]煹G-b!S?\nꖽ鼫,ݛ&頺y踦?E揆릱H}햧캡b@手.p탻>췽㣬ꒅ`qe佭P>ᓂ&?u}毚ᜉ蟶頳졪ᎏzl2wO": -2.53561440423275936E17 + }]} + } + ] + ]], + "潈촒⿂叡": 5495738871964062986 + } + ]] + } + ] + ]} + ]] + ]] + ]} + ] + ]}, + "ႁq킍蓅R`謈蟐ᦏ儂槐僻ﹶ9婌櫞釈~\"%匹躾ɢ뤥>࢟瀴愅?殕节/냔O✬H鲽엢?ᮈੁ⋧d␽㫐zCe*": 2.15062231586689536E17, + "㶵Ui曚珰鋪ᾼ臧P{䍏䷪쨑̟A뼿T渠誈䏚D1!잶<\/㡍7?)2l≣穷᛾稝{:;㡹nemיּ訊`G": null, + "䀕\"飕辭p圁f#뫆䶷뛮;⛴ᩍ3灚덏ᰝ쎓⦷詵%᜖Մfs⇫(\u001e~P|ﭗCⲾផv湟W첋(텪બT<บSꏉ੗⋲X婵i ӵ⇮?L䬇|ꈏ?졸": 1.548341247351782E-19 + } + ] + }, + "t;:N\u0015q鐦Rt缆{ꮐC?஛㷱敪\\+鲊㉫㓪몗릙竏(氵kYS": "XᰂT?൮ô", + "碕飦幑|+ 㚦鏶`镥ꁩ B<\/加륙": -4314053432419755959, + "秌孳(p!G?V傫%8ሽ8w;5鲗㦙LI檸\u2098": "zG N볞䆭鎍흘\\ONK3횙<\/樚立圌Q튅k쩎Ff쁋aׂJK銆ઘ즐狩6༥✙䩜篥CzP(聻駇HHퟲ讃%,ά{렍p而刲vy䦅ክ^톺M楒鍢㹳]Mdg2>䤉洞", + "踛M젧>忔芿㌜Zk": 2215369545966507819, + "씐A`$槭頰퍻^U覒\bG毲aᣴU;8!팲f꜇E⸃_卵{嫏羃X쀳C7뗮m(嚼u N܁谟D劯9]#": true, + "ﻩ!뵸-筚P᭛}ἰ履lPh?౮ⶹꆛ穉뎃g萑㑓溢CX뾇G㖬A錟]RKaꄘ]Yo+@䘁's섎襠$^홰}F": null + }, + "粘ꪒ4HXᕘ蹵.$區\r\u001d묁77pPc^y笲Q<\/ꖶ 訍䃍ᨕG?*": 1.73773035935040224E17 + }, + "婅拳?bkU;#D矠❴vVN쩆t㜷A풃갮娪a%鮏絪3dAv룒#tm쑬⌛qYwc4|L8KZ;xU⓭㳔밆拓EZ7襨eD|隰ऌ䧼u9Ԣ+]贴P荿": 2.9628516456987075E18 + }]}}] + ]} + }} + ]}] + ], + "|g翉F*湹̶\u0005⏐1脉̀eI쩓ᖂ㫱0碞l䴨ꑅ㵽7AtἈ턧yq䳥塑:z:遀ᄐX눔擉)`N3昛oQ셖y-ڨ⾶恢ꈵq^<\/": null, + "菹\\랓G^璬x৴뭸ゆUS겧﮷Bꮤ ┉銜᯻0%N7}~f洋坄Xꔼ<\/4妟Vꄟ9:౟곡t킅冩䧉笭裟炂4봋ⱳ叺怊t+怯涗\"0㖈Hq": false, + "졬믟'ﺇফ圪쓬멤m邸QLব䗁愍4jvs翙 ྍ꧀艳H-|": null, + "컮襱⣱뗠 R毪/鹙꾀%헳8&": -5770986448525107020 + } + ], + "B䔚bꐻ뙏姓展槰T-똌鷺tc灿᫽^㓟䏀o3o$꘭趙萬I顩)뇭Ἑ䓝\f@{ᣨ`x3蔛": null + } + ] + ] + }], + "⦖扚vWꃱ꥙㾠壢輓{-⎳鹷贏璿䜑bG倛⋐磎c皇皩7a~ﳫU╣Q࠭ꎉS摅姽OW.홌ೞ.": null, + "蚪eVlH献r}ᮏ믠ﰩꔄ@瑄ⲱ": null, + "퀭$JWoꩢg역쁍䖔㑺h&ୢtXX愰㱇?㾫I_6 OaB瑈q裿": null, + "꽦ﲼLyr纛Zdu珍B絟쬴糔?㕂짹䏵e": "ḱ\u2009cX9멀i䶛簆㳀k" + } + ]]]], + "(_ꏮg່澮?ᩑyM<艷\u001aꪽ\\庼뙭Z맷㰩Vm\\lY筺]3㋲2㌩㄀Eਟ䝵⨄쐨ᔟgङHn鐖⤇놋瓇Q탚單oY\"♆臾jHᶈ征ቄ??uㇰA?#1侓": null + }, + "觓^~ሢ&iI띆g륎ḱ캀.ᓡꀮ胙鈉": 1.0664523593012836E-19, + "y詭Gbᔶऽs댁U:杜⤎ϲ쁗⮼D醄诿q뙰I#즧v蔎xHᵿt᡽[**?崮耖p缫쿃L菝,봬ꤦC쯵#=X1瞻@OZc鱗CQTx": null + } + ] + }}], + "剘紁\u0004\\Xn⊠6,တױ;嵣崇}讃iႽ)d1\\䔓": null + }, + "脨z\"{X,1u찜<'k&@?1}Yn$\u0015Rd輲ーa쮂굄+B$l": true, + "諳>*쭮괐䵟Ґ+<箁}빀䅱⡔檏臒hIH脟ꩪC핝ଗP좕\"0i<\/C褻D۞恗+^5?'ꂱ䚫^7}㡠cq6\\쨪ꔞꥢ?纖䫀氮蒫侲빦敶q{A煲G": -6880961710038544266 + }}] + }, + "5s⨲JvಽῶꭂᄢI.a৊": null, + "?1q꽏쿻ꛋDR%U娝>DgN乭G": -1.2105047302732358E-19 + } + ] + ]}, + "qZz`撋뙹둣j碇쁏\\ꆥ\u0018@藴疰Wz)O{F䶛l᷂绘訥$]뮍夻䢋䩇萿獰樧猵⣭j萶q)$꬚⵷0馢W:Ⱍ!Qoe": -1666634370862219540, + "t": "=wp|~碎Q鬳Ӎ\\l-<\/^ﳊhn퐖}䍔t碵ḛ혷?靻䊗", + "邙쇡㯇%#=,E4勃驆V繚q[Y댻XV㡸[逹ᰏ葢B@u=JS5?bLRn얮㍉⏅ﰳ?a6[&큟!藈": 1.2722786745736667E-19 + }, + "X블땨4{ph鵋ꉯ웸 5p簂䦭s_E徔濧d稝~No穔噕뽲)뉈c5M윅>⚋[岦䲟懷恁?鎐꓆ฬ爋獠䜔s{\u001bm鐚儸煛%bﯿXT>ꗘ@8G": 1157841540507770724, + "媤娪Q杸\u0011SAyᡈ쿯": true, + "灚^ಸ%걁<\/蛯?\"祴坓\\\\'흍": -3.4614808555942579E18, + "釴U:O湛㴑䀣렑縓\ta)(j:숾却䗌gCiB뽬Oyuq輥厁/7)?今hY︺Q": null + } + ] + ]]]}] + ], + "I笔趠Ph!<ཛྷ㸞诘X$畉F\u0005笷菟.Esr릙!W☆䲖뗷莾뒭U\"䀸犜Uo3Gꯌx4r蔇᡹㧪쨢準<䂀%ࡡꟼ瑍8炝Xs0䀝销?fi쥱ꆝલBB": -8571484181158525797, + "L⦁o#J|\"⽩-㱢d㌛8d\\㶤傩儻E[Y熯)r噤὘勇 }": "e(濨쓌K䧚僒㘍蠤Vᛸ\"络QJL2,嬓왍伢㋒䴿考澰@(㏾`kX$끑эE斡,蜍&~y", + "vj.|统圪ᵮPL?2oŶ`밧\"勃+0ue%⿥绬췈체$6:qa렐Q;~晘3㙘鹑": true, + "ශؙ4獄⶿c︋i⚅:ん閝Ⳙ苆籦kw{䙞셕pC췃ꍬ␜꟯ꚓ酄b힝hwk꭭M鬋8B耳쑘WQ\\偙ac'唀x᪌\u2048*h짎#ፇ鮠뾏ឿ뀌": false, + "⎀jꄒ牺3Ⓝ컴~?親ꕽぼܓ喏瘘!@<튋㐌꿱⩦{a?Yv%⪧笯Uܱ栅E搚i뚬:ꄃx7䙳ꦋ&䓹vq☶I䁘ᾘ涜\\썉뺌Lr%Bc㍜3?ꝭ砿裞]": null, + "⭤뙓z(㡂%亳K䌽꫿AԾ岺㦦㼴輞낚Vꦴw냟鬓㹈뽈+o3譻K1잞": 2091209026076965894, + "ㇲ\t⋇轑ꠤ룫X긒\"zoY읇희wj梐쐑l侸`e%s": -9.9240075473576563E17, + "啸ꮑ㉰!ᚓ}銏": -4.0694813896301194E18, + ">]囋੽EK뇜>_ꀣ緳碖{쐐裔[<ನ\"䇅\"5L?#xTwv#罐\u0005래t应\\N?빗;": "v쮽瞭p뭃" + } + ]], + "斴槾?Z翁\"~慍弞ﻆ=꜡o5鐋dw\"?K蠡i샾ogDﲰ_C*⬟iㇷ4nય蟏[㟉U꽌娛苸 ঢ়操贻洞펻)쿗૊許X⨪VY츚Z䍾㶭~튃ᵦ<\/E臭tve猑x嚢": null, + "锡⛩<\/칥ꈙᬙ蝀&Ꚑ籬■865?_>L詏쿨䈌浿弥爫̫lj&zx<\/C쉾?覯n?": null, + "꾳鑤/꼩d=ᘈn挫ᑩ䰬ZC": "3錢爋6Ƹ䴗v⪿Wr益G韠[\u0010屗9쁡钁u?殢c䳀蓃樄욂NAq赟c튒瘁렶Aૡɚ捍" + } + ] + ] + ]} + ] + ] + }]]]}} + ]}], + "Ej䗳U<\/Q=灒샎䞦,堰頠@褙g_\u0003ꤾfⶽ?퇋!łB〙ד3CC䌴鈌U:뭔咎(Qો臃䡬荋BO7㢝䟸\"Yb": 2.36010731779814E-20, + "逸'0岔j\u000e눘먷翌C츊秦=ꭣ棭ှ;鳸=麱$XP⩉駚橄A\\좱⛌jqv䰞3Ь踌v㳆¹gT┌gvLB賖烡m?@E঳i": null + }, + "曺v찘ׁ?&绫O័": 9107241066550187880 + } + ] + ], + "(e屄\u0019昜훕琖b蓘ᬄ0/۲묇Z蘮ဏ⨏蛘胯뢃@㘉8ሪWᨮ⦬ᅳ䅴HI၇쨳z囕陻엣1赳o": true, + ",b刈Z,ၠ晐T솝ŕB⩆ou'퐼≃绗雗d譊": null, + "a唥KB\"ﳝ肕$u\n^⅄P䟼냉䞸⩪u윗瀱ꔨ#yşs꒬=1|ﲤ爢`t౐튼쳫_Az(Ṋ擬㦷좕耈6": 2099309172767331582, + "?㴸U<\/䢔ꯡ阽扆㐤q鐋?f㔫wM嬙-;UV죫嚔픞G&\"Cᗍ䪏풊Q": "VM7疹+陕枡툩窲}翡䖶8欞čsT뮐}璤:jﺋ鎴}HfA൝⧻Zd#Qu茅J髒皣Y-︴[?-~쉜v딏璮㹚䅊﩯<-#\u000e걀h\u0004u抱﵊㼃U<㱷⊱IC進" + }, + "숌dee節鏽邺p넱蹓+e罕U": true + } + ], + "b⧴룏??ᔠ3ぱ>%郿劃翐ꏬꠛW瞳᫏누躨狀ໄy੽\"ីuS=㨞馸k乆E": "トz݈^9R䬑<ﮛGRꨳ\u000fTT泠纷꽀MRᴱ纊:㠭볮?%N56%鈕1䗍䜁a䲗j陇=뿻偂衋࿘ᓸ?ᕵZ+<\/}H耢b䀁z^f$&㝒LkꢳI脚뙛u": 5.694374481577558E-20 + }] + } + ]], + "obj": {"key": "wrong value"}, + "퓲꽪m{㶩/뇿#⼢&᭙硞㪔E嚉c樱㬇1a綑᝖DḾ䝩": null + } +} \ No newline at end of file diff --git a/tests/tests.c b/tests/tests.c new file mode 100644 index 00000000..5643da36 --- /dev/null +++ b/tests/tests.c @@ -0,0 +1,102 @@ +/* +ujson4c decoder helper 1.0 +Developed by ESN, an Electronic Arts Inc. studio. +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of ESN, Electronic Arts Inc. nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Uses UltraJSON library: +Copyright (c) 2013, Electronic Arts Inc. +All rights reserved. +www.github.com/esnme/ultrajson +*/ + +#include "ujdecode.h" +#include +#include +#include + +void test_unpackKeys() +{ + UJObject obj; + void *state; + char buffer[32768]; + const char input[] = "{\"name\": \"John Doe\", \"age\": 31, \"number\": 1337.37, \"address\": { \"city\": \"Uppsala\", \"population\": 9223372036854775807 } }"; + size_t cbInput = sizeof(input) - 1; + + const wchar_t *personKeys[] = { L"name", L"age", L"number", L"address"}; + UJObject oName, oAge, oNumber, oAddress; + + UJHeapFuncs hf; + hf.cbInitialHeap = sizeof(buffer); + hf.initalHeap = buffer; + hf.free = free; + hf.malloc = malloc; + hf.realloc = realloc; + + obj = UJDecode(input, cbInput, NULL, &state); + + if (UJObjectUnpack(obj, 4, "SNNO", personKeys, &oName, &oAge, &oNumber, &oAddress) == 4) + { + const wchar_t *addressKeys[] = { L"city", L"population" }; + UJObject oCity, oPopulation; + + const wchar_t *name = UJReadString(oName, NULL); + int age = UJNumericInt(oAge); + double number = UJNumericFloat(oNumber); + + assert(wcscmp(name, L"John Doe") == 0); + assert(age == 31); + assert(number == 1337.37); + + if (UJObjectUnpack(oAddress, 2, "SN", addressKeys, &oCity, &oPopulation) == 2) + { + const wchar_t *city; + long long population; + city = UJReadString(oCity, NULL); + assert(wcscmp(city, L"Uppsala") == 0); + population = UJNumericLongLong(oPopulation); + assert(population == LLONG_MAX); + } + else + { + assert(0); + } + } + else + { + assert(0); + } + + + UJFree(state); +} + +#ifndef __BENCHMARK__ +int main () +{ + test_unpackKeys(); + return 0; +} +#endif \ No newline at end of file From 311a74303c21df78496e8369289e7230f4879cb2 Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Sat, 21 Jul 2018 12:08:10 +0200 Subject: [PATCH 4/9] Squashed 'libs/curl/' content from commit d0924d0e0 git-subtree-dir: libs/curl git-subtree-split: d0924d0e03ef6ecc8da27d57f2f4994bcfb7af29 --- .dir-locals.el | 10 + .gitattributes | 7 + .github/CONTRIBUTING.md | 23 + .github/ISSUE_TEMPLATE | 16 + .github/lock.yml | 8 + .github/stale.yml | 17 + .gitignore | 58 + .lgtm.yml | 10 + .mailmap | 46 + .travis-iconv-env.sh | 1 + .travis.yml | 341 + CHANGES | 7 + CMake/CMakeConfigurableFile.in | 2 + CMake/CurlSymbolHiding.cmake | 61 + CMake/CurlTests.c | 551 ++ CMake/FindBrotli.cmake | 20 + CMake/FindCARES.cmake | 42 + CMake/FindGSS.cmake | 289 + CMake/FindLibSSH2.cmake | 35 + CMake/FindMbedTLS.cmake | 13 + CMake/FindNGHTTP2.cmake | 18 + CMake/Macros.cmake | 124 + CMake/OtherTests.cmake | 231 + CMake/Platforms/WindowsCache.cmake | 124 + CMake/Utilities.cmake | 13 + CMake/cmake_uninstall.cmake.in | 26 + CMake/curl-config.cmake | 59 + CMakeLists.txt | 1343 ++++ COPYING | 22 + GIT-INFO | 44 + MacOSX-Framework | 137 + Makefile.am | 644 ++ Makefile.dist | 127 + README | 49 + README.md | 78 + RELEASE-NOTES | 225 + acinclude.m4 | 2665 +++++++ appveyor.yml | 75 + buildconf | 448 ++ buildconf.bat | 317 + configure.ac | 4273 ++++++++++ curl-config.in | 182 + docs/.gitignore | 4 + docs/BINDINGS.md | 118 + docs/BUGS | 297 + docs/CHECKSRC.md | 124 + docs/CIPHERS.md | 487 ++ docs/CMakeLists.txt | 3 + docs/CODE_OF_CONDUCT.md | 32 + docs/CODE_STYLE.md | 246 + docs/CONTRIBUTE.md | 267 + docs/DEPRECATE.md | 73 + docs/FAQ | 1559 ++++ docs/FEATURES | 206 + docs/GOVERNANCE.md | 144 + docs/HELP-US.md | 70 + docs/HISTORY.md | 295 + docs/HTTP-COOKIES.md | 104 + docs/HTTP2.md | 126 + docs/INSTALL | 9 + docs/INSTALL.cmake | 91 + docs/INSTALL.md | 468 ++ docs/INTERNALS.md | 1081 +++ docs/KNOWN_BUGS | 696 ++ docs/LICENSE-MIXING.md | 127 + docs/MAIL-ETIQUETTE | 285 + docs/MANUAL | 1058 +++ docs/Makefile.am | 119 + docs/README.cmake | 16 + docs/README.md | 12 + docs/README.netware | 26 + docs/README.win32 | 25 + docs/RELEASE-PROCEDURE.md | 96 + docs/RESOURCES | 85 + docs/ROADMAP.md | 42 + docs/SECURITY-PROCESS.md | 139 + docs/SSL-PROBLEMS.md | 87 + docs/SSLCERTS.md | 173 + docs/THANKS | 1772 +++++ docs/THANKS-filter | 81 + docs/TODO | 1258 +++ docs/TheArtOfHttpScripting | 758 ++ docs/VERSIONS | 56 + docs/cmdline-opts/CMakeLists.txt | 12 + docs/cmdline-opts/MANPAGE.md | 52 + docs/cmdline-opts/Makefile.am | 34 + docs/cmdline-opts/Makefile.inc | 52 + docs/cmdline-opts/abstract-unix-socket.d | 9 + docs/cmdline-opts/anyauth.d | 17 + docs/cmdline-opts/append.d | 8 + docs/cmdline-opts/basic.d | 11 + docs/cmdline-opts/cacert.d | 33 + docs/cmdline-opts/capath.d | 15 + docs/cmdline-opts/cert-status.d | 13 + docs/cmdline-opts/cert-type.d | 10 + docs/cmdline-opts/cert.d | 43 + docs/cmdline-opts/ciphers.d | 11 + docs/cmdline-opts/compressed-ssh.d | 7 + docs/cmdline-opts/compressed.d | 7 + docs/cmdline-opts/config.d | 61 + docs/cmdline-opts/connect-timeout.d | 11 + docs/cmdline-opts/connect-to.d | 21 + docs/cmdline-opts/continue-at.d | 15 + docs/cmdline-opts/cookie-jar.d | 24 + docs/cmdline-opts/cookie.d | 37 + docs/cmdline-opts/create-dirs.d | 9 + docs/cmdline-opts/crlf.d | 7 + docs/cmdline-opts/crlfile.d | 10 + docs/cmdline-opts/data-ascii.d | 6 + docs/cmdline-opts/data-binary.d | 13 + docs/cmdline-opts/data-raw.d | 9 + docs/cmdline-opts/data-urlencode.d | 33 + docs/cmdline-opts/data.d | 30 + docs/cmdline-opts/delegation.d | 16 + docs/cmdline-opts/digest.d | 11 + docs/cmdline-opts/disable-eprt.d | 19 + docs/cmdline-opts/disable-epsv.d | 16 + docs/cmdline-opts/disable.d | 7 + docs/cmdline-opts/disallow-username-in-url.d | 7 + docs/cmdline-opts/dns-interface.d | 11 + docs/cmdline-opts/dns-ipv4-addr.d | 11 + docs/cmdline-opts/dns-ipv6-addr.d | 11 + docs/cmdline-opts/dns-servers.d | 10 + docs/cmdline-opts/dump-header.d | 18 + docs/cmdline-opts/egd-file.d | 8 + docs/cmdline-opts/engine.d | 8 + docs/cmdline-opts/expect100-timeout.d | 11 + docs/cmdline-opts/fail-early.d | 21 + docs/cmdline-opts/fail.d | 14 + docs/cmdline-opts/false-start.d | 12 + docs/cmdline-opts/form-string.d | 11 + docs/cmdline-opts/form.d | 138 + docs/cmdline-opts/ftp-account.d | 10 + docs/cmdline-opts/ftp-alternative-to-user.d | 10 + docs/cmdline-opts/ftp-create-dirs.d | 8 + docs/cmdline-opts/ftp-method.d | 21 + docs/cmdline-opts/ftp-pasv.d | 16 + docs/cmdline-opts/ftp-port.d | 32 + docs/cmdline-opts/ftp-pret.d | 8 + docs/cmdline-opts/ftp-skip-pasv-ip.d | 12 + docs/cmdline-opts/ftp-ssl-ccc-mode.d | 11 + docs/cmdline-opts/ftp-ssl-ccc.d | 10 + docs/cmdline-opts/ftp-ssl-control.d | 8 + docs/cmdline-opts/gen.pl | 391 + docs/cmdline-opts/get.d | 15 + docs/cmdline-opts/globoff.d | 8 + docs/cmdline-opts/happy-eyeballs-timeout-ms.d | 17 + docs/cmdline-opts/haproxy-protocol.d | 11 + docs/cmdline-opts/head.d | 8 + docs/cmdline-opts/header.d | 41 + docs/cmdline-opts/help.d | 6 + docs/cmdline-opts/hostpubmd5.d | 9 + docs/cmdline-opts/http1.0.d | 10 + docs/cmdline-opts/http1.1.d | 8 + docs/cmdline-opts/http2-prior-knowledge.d | 12 + docs/cmdline-opts/http2.d | 10 + docs/cmdline-opts/ignore-content-length.d | 10 + docs/cmdline-opts/include.d | 10 + docs/cmdline-opts/insecure.d | 16 + docs/cmdline-opts/interface.d | 16 + docs/cmdline-opts/ipv4.d | 12 + docs/cmdline-opts/ipv6.d | 12 + docs/cmdline-opts/junk-session-cookies.d | 10 + docs/cmdline-opts/keepalive-time.d | 13 + docs/cmdline-opts/key-type.d | 9 + docs/cmdline-opts/key.d | 10 + docs/cmdline-opts/krb.d | 11 + docs/cmdline-opts/libcurl.d | 11 + docs/cmdline-opts/limit-rate.d | 18 + docs/cmdline-opts/list-only.d | 24 + docs/cmdline-opts/local-port.d | 9 + docs/cmdline-opts/location-trusted.d | 9 + docs/cmdline-opts/location.d | 23 + docs/cmdline-opts/login-options.d | 14 + docs/cmdline-opts/mail-auth.d | 10 + docs/cmdline-opts/mail-from.d | 8 + docs/cmdline-opts/mail-rcpt.d | 19 + docs/cmdline-opts/manual.d | 5 + docs/cmdline-opts/max-filesize.d | 16 + docs/cmdline-opts/max-redirs.d | 11 + docs/cmdline-opts/max-time.d | 13 + docs/cmdline-opts/metalink.d | 27 + docs/cmdline-opts/negotiate.d | 15 + docs/cmdline-opts/netrc-file.d | 12 + docs/cmdline-opts/netrc-optional.d | 7 + docs/cmdline-opts/netrc.d | 17 + docs/cmdline-opts/next.d | 20 + docs/cmdline-opts/no-alpn.d | 11 + docs/cmdline-opts/no-buffer.d | 11 + docs/cmdline-opts/no-keepalive.d | 8 + docs/cmdline-opts/no-npn.d | 12 + docs/cmdline-opts/no-sessionid.d | 13 + docs/cmdline-opts/noproxy.d | 15 + docs/cmdline-opts/ntlm-wb.d | 7 + docs/cmdline-opts/ntlm.d | 18 + docs/cmdline-opts/oauth2-bearer.d | 12 + docs/cmdline-opts/output.d | 32 + docs/cmdline-opts/page-footer | 255 + docs/cmdline-opts/page-header | 141 + docs/cmdline-opts/pass.d | 8 + docs/cmdline-opts/path-as-is.d | 7 + docs/cmdline-opts/pinnedpubkey.d | 27 + docs/cmdline-opts/post301.d | 11 + docs/cmdline-opts/post302.d | 11 + docs/cmdline-opts/post303.d | 10 + docs/cmdline-opts/preproxy.d | 22 + docs/cmdline-opts/progress-bar.d | 12 + docs/cmdline-opts/proto-default.d | 18 + docs/cmdline-opts/proto-redir.d | 17 + docs/cmdline-opts/proto.d | 43 + docs/cmdline-opts/proxy-anyauth.d | 7 + docs/cmdline-opts/proxy-basic.d | 7 + docs/cmdline-opts/proxy-cacert.d | 7 + docs/cmdline-opts/proxy-capath.d | 7 + docs/cmdline-opts/proxy-cert-type.d | 6 + docs/cmdline-opts/proxy-cert.d | 6 + docs/cmdline-opts/proxy-ciphers.d | 6 + docs/cmdline-opts/proxy-crlfile.d | 6 + docs/cmdline-opts/proxy-digest.d | 6 + docs/cmdline-opts/proxy-header.d | 24 + docs/cmdline-opts/proxy-insecure.d | 5 + docs/cmdline-opts/proxy-key-type.d | 6 + docs/cmdline-opts/proxy-key.d | 5 + docs/cmdline-opts/proxy-negotiate.d | 8 + docs/cmdline-opts/proxy-ntlm.d | 6 + docs/cmdline-opts/proxy-pass.d | 6 + docs/cmdline-opts/proxy-pinnedpubkey.d | 16 + docs/cmdline-opts/proxy-service-name.d | 6 + docs/cmdline-opts/proxy-ssl-allow-beast.d | 5 + docs/cmdline-opts/proxy-tls13-ciphers.d | 12 + docs/cmdline-opts/proxy-tlsauthtype.d | 6 + docs/cmdline-opts/proxy-tlspassword.d | 6 + docs/cmdline-opts/proxy-tlsuser.d | 6 + docs/cmdline-opts/proxy-tlsv1.d | 5 + docs/cmdline-opts/proxy-user.d | 12 + docs/cmdline-opts/proxy.d | 39 + docs/cmdline-opts/proxy1.0.d | 10 + docs/cmdline-opts/proxytunnel.d | 13 + docs/cmdline-opts/pubkey.d | 14 + docs/cmdline-opts/quote.d | 56 + docs/cmdline-opts/random-file.d | 7 + docs/cmdline-opts/range.d | 46 + docs/cmdline-opts/raw.d | 7 + docs/cmdline-opts/referer.d | 14 + docs/cmdline-opts/remote-header-name.d | 19 + docs/cmdline-opts/remote-name-all.d | 8 + docs/cmdline-opts/remote-name.d | 21 + docs/cmdline-opts/remote-time.d | 7 + docs/cmdline-opts/request-target.d | 9 + docs/cmdline-opts/request.d | 39 + docs/cmdline-opts/resolve.d | 21 + docs/cmdline-opts/retry-connrefused.d | 6 + docs/cmdline-opts/retry-delay.d | 11 + docs/cmdline-opts/retry-max-time.d | 13 + docs/cmdline-opts/retry.d | 17 + docs/cmdline-opts/sasl-ir.d | 5 + docs/cmdline-opts/service-name.d | 8 + docs/cmdline-opts/show-error.d | 5 + docs/cmdline-opts/silent.d | 11 + docs/cmdline-opts/socks4.d | 19 + docs/cmdline-opts/socks4a.d | 19 + docs/cmdline-opts/socks5-basic.d | 7 + docs/cmdline-opts/socks5-gssapi-nec.d | 8 + docs/cmdline-opts/socks5-gssapi-service.d | 12 + docs/cmdline-opts/socks5-gssapi.d | 8 + docs/cmdline-opts/socks5-hostname.d | 19 + docs/cmdline-opts/socks5.d | 21 + docs/cmdline-opts/speed-limit.d | 10 + docs/cmdline-opts/speed-time.d | 13 + docs/cmdline-opts/ssl-allow-beast.d | 9 + docs/cmdline-opts/ssl-no-revoke.d | 7 + docs/cmdline-opts/ssl-reqd.d | 9 + docs/cmdline-opts/ssl.d | 12 + docs/cmdline-opts/sslv2.d | 13 + docs/cmdline-opts/sslv3.d | 13 + docs/cmdline-opts/stderr.d | 8 + docs/cmdline-opts/styled-output.d | 6 + docs/cmdline-opts/suppress-connect-headers.d | 8 + docs/cmdline-opts/tcp-fastopen.d | 5 + docs/cmdline-opts/tcp-nodelay.d | 9 + docs/cmdline-opts/telnet-option.d | 12 + docs/cmdline-opts/tftp-blksize.d | 11 + docs/cmdline-opts/tftp-no-options.d | 10 + docs/cmdline-opts/time-cond.d | 17 + docs/cmdline-opts/tls-max.d | 24 + docs/cmdline-opts/tls13-ciphers.d | 12 + docs/cmdline-opts/tlsauthtype.d | 10 + docs/cmdline-opts/tlspassword.d | 6 + docs/cmdline-opts/tlsuser.d | 7 + docs/cmdline-opts/tlsv1.0.d | 6 + docs/cmdline-opts/tlsv1.1.d | 6 + docs/cmdline-opts/tlsv1.2.d | 6 + docs/cmdline-opts/tlsv1.3.d | 10 + docs/cmdline-opts/tlsv1.d | 12 + docs/cmdline-opts/tr-encoding.d | 7 + docs/cmdline-opts/trace-ascii.d | 14 + docs/cmdline-opts/trace-time.d | 5 + docs/cmdline-opts/trace.d | 11 + docs/cmdline-opts/unix-socket.d | 7 + docs/cmdline-opts/upload-file.d | 33 + docs/cmdline-opts/url.d | 15 + docs/cmdline-opts/use-ascii.d | 8 + docs/cmdline-opts/user-agent.d | 12 + docs/cmdline-opts/user.d | 33 + docs/cmdline-opts/verbose.d | 19 + docs/cmdline-opts/version.d | 58 + docs/cmdline-opts/write-out.d | 142 + docs/cmdline-opts/xattr.d | 8 + docs/curl-config.1 | 102 + docs/examples/.gitignore | 88 + docs/examples/10-at-a-time.c | 198 + docs/examples/Makefile.am | 65 + docs/examples/Makefile.example | 53 + docs/examples/Makefile.inc | 46 + docs/examples/Makefile.m32 | 297 + docs/examples/Makefile.netware | 434 + docs/examples/README | 38 + docs/examples/adddocsref.pl | 35 + docs/examples/anyauthput.c | 168 + docs/examples/asiohiper.cpp | 486 ++ docs/examples/cacertinmem.c | 186 + docs/examples/certinfo.c | 85 + docs/examples/chkspeed.c | 213 + docs/examples/cookie_interface.c | 140 + docs/examples/crawler.c | 210 + docs/examples/curlgtk.c | 109 + docs/examples/curlx.c | 566 ++ docs/examples/debug.c | 154 + docs/examples/evhiperfifo.c | 449 ++ docs/examples/externalsocket.c | 166 + docs/examples/fileupload.c | 89 + docs/examples/fopen.c | 546 ++ docs/examples/ftp-wildcard.c | 152 + docs/examples/ftpget.c | 92 + docs/examples/ftpgetinfo.c | 91 + docs/examples/ftpgetresp.c | 77 + docs/examples/ftpsget.c | 99 + docs/examples/ftpupload.c | 139 + docs/examples/ftpuploadfrommem.c | 124 + docs/examples/ftpuploadresume.c | 161 + docs/examples/getinfo.c | 52 + docs/examples/getinmemory.c | 115 + docs/examples/getredirect.c | 70 + docs/examples/ghiper.c | 438 + docs/examples/hiperfifo.c | 465 ++ docs/examples/href_extractor.c | 86 + docs/examples/htmltidy.c | 127 + docs/examples/htmltitle.cpp | 294 + docs/examples/http-post.c | 59 + docs/examples/http2-download.c | 295 + docs/examples/http2-serverpush.c | 323 + docs/examples/http2-upload.c | 359 + docs/examples/httpcustomheader.c | 70 + docs/examples/httpput.c | 124 + docs/examples/https.c | 78 + docs/examples/imap-append.c | 131 + docs/examples/imap-copy.c | 71 + docs/examples/imap-create.c | 67 + docs/examples/imap-delete.c | 67 + docs/examples/imap-examine.c | 67 + docs/examples/imap-fetch.c | 65 + docs/examples/imap-list.c | 66 + docs/examples/imap-lsub.c | 68 + docs/examples/imap-multi.c | 173 + docs/examples/imap-noop.c | 67 + docs/examples/imap-search.c | 71 + docs/examples/imap-ssl.c | 92 + docs/examples/imap-store.c | 82 + docs/examples/imap-tls.c | 92 + docs/examples/makefile.dj | 56 + docs/examples/multi-app.c | 177 + docs/examples/multi-debugcallback.c | 231 + docs/examples/multi-double.c | 143 + docs/examples/multi-formadd.c | 171 + docs/examples/multi-post.c | 167 + docs/examples/multi-single.c | 111 + docs/examples/multi-uv.c | 235 + docs/examples/multithread.c | 95 + docs/examples/opensslthreadlock.c | 95 + docs/examples/persistant.c | 68 + docs/examples/pop3-dele.c | 70 + docs/examples/pop3-list.c | 64 + docs/examples/pop3-multi.c | 173 + docs/examples/pop3-noop.c | 70 + docs/examples/pop3-retr.c | 64 + docs/examples/pop3-ssl.c | 91 + docs/examples/pop3-stat.c | 70 + docs/examples/pop3-tls.c | 91 + docs/examples/pop3-top.c | 67 + docs/examples/pop3-uidl.c | 67 + docs/examples/post-callback.c | 154 + docs/examples/postinmemory.c | 114 + docs/examples/postit2-formadd.c | 107 + docs/examples/postit2.c | 103 + docs/examples/progressfunc.c | 144 + docs/examples/resolve.c | 56 + docs/examples/rtsp.c | 287 + docs/examples/sampleconv.c | 113 + docs/examples/sendrecv.c | 160 + docs/examples/sepheaders.c | 94 + docs/examples/sessioninfo.c | 109 + docs/examples/sftpget.c | 110 + docs/examples/sftpuploadresume.c | 134 + docs/examples/shared-connection-cache.c | 85 + docs/examples/simple.c | 51 + docs/examples/simplepost.c | 57 + docs/examples/simplessl.c | 141 + docs/examples/smooth-gtk-thread.c | 227 + docs/examples/smtp-expn.c | 79 + docs/examples/smtp-mail.c | 149 + docs/examples/smtp-mime.c | 162 + docs/examples/smtp-multi.c | 243 + docs/examples/smtp-ssl.c | 169 + docs/examples/smtp-tls.c | 171 + docs/examples/smtp-vrfy.c | 79 + docs/examples/sslbackend.c | 77 + docs/examples/synctime.c | 370 + docs/examples/threaded-shared-conn.c | 156 + docs/examples/threaded-ssl.c | 167 + docs/examples/url2file.c | 86 + docs/examples/usercertinmem.c | 226 + docs/examples/version-check.pl | 105 + docs/examples/xmlstream.c | 165 + docs/libcurl/.gitignore | 4 + docs/libcurl/ABI | 68 + docs/libcurl/CMakeLists.txt | 55 + docs/libcurl/Makefile.am | 78 + docs/libcurl/Makefile.inc | 25 + docs/libcurl/curl_easy_cleanup.3 | 68 + docs/libcurl/curl_easy_duphandle.3 | 52 + docs/libcurl/curl_easy_escape.3 | 67 + docs/libcurl/curl_easy_getinfo.3 | 277 + docs/libcurl/curl_easy_init.3 | 59 + docs/libcurl/curl_easy_pause.3 | 103 + docs/libcurl/curl_easy_perform.3 | 75 + docs/libcurl/curl_easy_recv.3 | 84 + docs/libcurl/curl_easy_reset.3 | 44 + docs/libcurl/curl_easy_send.3 | 75 + docs/libcurl/curl_easy_setopt.3 | 618 ++ docs/libcurl/curl_easy_strerror.3 | 40 + docs/libcurl/curl_easy_unescape.3 | 54 + docs/libcurl/curl_escape.3 | 48 + docs/libcurl/curl_formadd.3 | 266 + docs/libcurl/curl_formfree.3 | 48 + docs/libcurl/curl_formget.3 | 71 + docs/libcurl/curl_free.3 | 35 + docs/libcurl/curl_getdate.3 | 110 + docs/libcurl/curl_getenv.3 | 49 + docs/libcurl/curl_global_cleanup.3 | 55 + docs/libcurl/curl_global_init.3 | 101 + docs/libcurl/curl_global_init_mem.3 | 65 + docs/libcurl/curl_global_sslset.3 | 100 + docs/libcurl/curl_mime_addpart.3 | 66 + docs/libcurl/curl_mime_data.3 | 69 + docs/libcurl/curl_mime_data_cb.3 | 167 + docs/libcurl/curl_mime_encoder.3 | 97 + docs/libcurl/curl_mime_filedata.3 | 84 + docs/libcurl/curl_mime_filename.3 | 72 + docs/libcurl/curl_mime_free.3 | 48 + docs/libcurl/curl_mime_headers.3 | 65 + docs/libcurl/curl_mime_init.3 | 69 + docs/libcurl/curl_mime_name.3 | 63 + docs/libcurl/curl_mime_subparts.3 | 53 + docs/libcurl/curl_mime_type.3 | 83 + docs/libcurl/curl_mprintf.3 | 103 + docs/libcurl/curl_multi_add_handle.3 | 71 + docs/libcurl/curl_multi_assign.3 | 63 + docs/libcurl/curl_multi_cleanup.3 | 47 + docs/libcurl/curl_multi_fdset.3 | 84 + docs/libcurl/curl_multi_info_read.3 | 94 + docs/libcurl/curl_multi_init.3 | 40 + docs/libcurl/curl_multi_perform.3 | 128 + docs/libcurl/curl_multi_remove_handle.3 | 44 + docs/libcurl/curl_multi_setopt.3 | 78 + docs/libcurl/curl_multi_socket.3 | 159 + docs/libcurl/curl_multi_socket_action.3 | 156 + docs/libcurl/curl_multi_socket_all.3 | 1 + docs/libcurl/curl_multi_strerror.3 | 37 + docs/libcurl/curl_multi_timeout.3 | 79 + docs/libcurl/curl_multi_wait.3 | 122 + docs/libcurl/curl_share_cleanup.3 | 40 + docs/libcurl/curl_share_init.3 | 44 + docs/libcurl/curl_share_setopt.3 | 112 + docs/libcurl/curl_share_strerror.3 | 37 + docs/libcurl/curl_slist_append.3 | 60 + docs/libcurl/curl_slist_free_all.3 | 53 + docs/libcurl/curl_strequal.3 | 51 + docs/libcurl/curl_strnequal.3 | 1 + docs/libcurl/curl_unescape.3 | 48 + docs/libcurl/curl_version.3 | 39 + docs/libcurl/curl_version_info.3 | 189 + docs/libcurl/getinfo-times | 27 + docs/libcurl/libcurl-easy.3 | 58 + docs/libcurl/libcurl-env.3 | 89 + docs/libcurl/libcurl-errors.3 | 312 + docs/libcurl/libcurl-multi.3 | 181 + docs/libcurl/libcurl-security.3 | 342 + docs/libcurl/libcurl-share.3 | 65 + docs/libcurl/libcurl-thread.3 | 106 + docs/libcurl/libcurl-tutorial.3 | 1397 ++++ docs/libcurl/libcurl.3 | 227 + docs/libcurl/libcurl.m4 | 272 + docs/libcurl/mksymbolsmanpage.pl | 93 + docs/libcurl/opts/CMakeLists.txt | 12 + docs/libcurl/opts/CURLINFO_ACTIVESOCKET.3 | 69 + docs/libcurl/opts/CURLINFO_APPCONNECT_TIME.3 | 62 + .../libcurl/opts/CURLINFO_APPCONNECT_TIME_T.3 | 64 + docs/libcurl/opts/CURLINFO_CERTINFO.3 | 81 + docs/libcurl/opts/CURLINFO_CONDITION_UNMET.3 | 68 + docs/libcurl/opts/CURLINFO_CONNECT_TIME.3 | 59 + docs/libcurl/opts/CURLINFO_CONNECT_TIME_T.3 | 59 + .../opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 | 65 + .../opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 | 62 + .../opts/CURLINFO_CONTENT_LENGTH_UPLOAD.3 | 64 + .../opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 | 61 + docs/libcurl/opts/CURLINFO_CONTENT_TYPE.3 | 65 + docs/libcurl/opts/CURLINFO_COOKIELIST.3 | 77 + docs/libcurl/opts/CURLINFO_EFFECTIVE_URL.3 | 63 + docs/libcurl/opts/CURLINFO_FILETIME.3 | 69 + docs/libcurl/opts/CURLINFO_FILETIME_T.3 | 71 + docs/libcurl/opts/CURLINFO_FTP_ENTRY_PATH.3 | 65 + docs/libcurl/opts/CURLINFO_HEADER_SIZE.3 | 61 + docs/libcurl/opts/CURLINFO_HTTPAUTH_AVAIL.3 | 70 + docs/libcurl/opts/CURLINFO_HTTP_CONNECTCODE.3 | 61 + docs/libcurl/opts/CURLINFO_HTTP_VERSION.3 | 56 + docs/libcurl/opts/CURLINFO_LASTSOCKET.3 | 71 + docs/libcurl/opts/CURLINFO_LOCAL_IP.3 | 68 + docs/libcurl/opts/CURLINFO_LOCAL_PORT.3 | 65 + docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME.3 | 59 + .../libcurl/opts/CURLINFO_NAMELOOKUP_TIME_T.3 | 60 + docs/libcurl/opts/CURLINFO_NUM_CONNECTS.3 | 61 + docs/libcurl/opts/CURLINFO_OS_ERRNO.3 | 58 + docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME.3 | 62 + .../opts/CURLINFO_PRETRANSFER_TIME_T.3 | 64 + docs/libcurl/opts/CURLINFO_PRIMARY_IP.3 | 67 + docs/libcurl/opts/CURLINFO_PRIMARY_PORT.3 | 56 + docs/libcurl/opts/CURLINFO_PRIVATE.3 | 60 + docs/libcurl/opts/CURLINFO_PROTOCOL.3 | 64 + docs/libcurl/opts/CURLINFO_PROXYAUTH_AVAIL.3 | 71 + .../opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 | 57 + docs/libcurl/opts/CURLINFO_REDIRECT_COUNT.3 | 55 + docs/libcurl/opts/CURLINFO_REDIRECT_TIME.3 | 61 + docs/libcurl/opts/CURLINFO_REDIRECT_TIME_T.3 | 63 + docs/libcurl/opts/CURLINFO_REDIRECT_URL.3 | 62 + docs/libcurl/opts/CURLINFO_REQUEST_SIZE.3 | 59 + docs/libcurl/opts/CURLINFO_RESPONSE_CODE.3 | 60 + docs/libcurl/opts/CURLINFO_RTSP_CLIENT_CSEQ.3 | 54 + docs/libcurl/opts/CURLINFO_RTSP_CSEQ_RECV.3 | 56 + docs/libcurl/opts/CURLINFO_RTSP_SERVER_CSEQ.3 | 59 + docs/libcurl/opts/CURLINFO_RTSP_SESSION_ID.3 | 61 + docs/libcurl/opts/CURLINFO_SCHEME.3 | 62 + docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD.3 | 67 + docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD_T.3 | 64 + docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.3 | 62 + docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.3 | 59 + docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD.3 | 62 + docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD_T.3 | 59 + docs/libcurl/opts/CURLINFO_SPEED_UPLOAD.3 | 61 + docs/libcurl/opts/CURLINFO_SPEED_UPLOAD_T.3 | 58 + docs/libcurl/opts/CURLINFO_SSL_ENGINES.3 | 60 + docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3 | 57 + .../opts/CURLINFO_STARTTRANSFER_TIME.3 | 61 + .../opts/CURLINFO_STARTTRANSFER_TIME_T.3 | 63 + docs/libcurl/opts/CURLINFO_TLS_SESSION.3 | 70 + docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 | 170 + docs/libcurl/opts/CURLINFO_TOTAL_TIME.3 | 60 + docs/libcurl/opts/CURLINFO_TOTAL_TIME_T.3 | 61 + .../opts/CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 | 52 + .../CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 | 51 + docs/libcurl/opts/CURLMOPT_MAXCONNECTS.3 | 66 + .../opts/CURLMOPT_MAX_HOST_CONNECTIONS.3 | 62 + .../opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 | 55 + .../opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 | 54 + docs/libcurl/opts/CURLMOPT_PIPELINING.3 | 85 + .../opts/CURLMOPT_PIPELINING_SERVER_BL.3 | 60 + .../opts/CURLMOPT_PIPELINING_SITE_BL.3 | 56 + docs/libcurl/opts/CURLMOPT_PUSHDATA.3 | 79 + docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 | 133 + docs/libcurl/opts/CURLMOPT_SOCKETDATA.3 | 76 + docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.3 | 101 + docs/libcurl/opts/CURLMOPT_TIMERDATA.3 | 82 + docs/libcurl/opts/CURLMOPT_TIMERFUNCTION.3 | 104 + .../opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 | 58 + docs/libcurl/opts/CURLOPT_ACCEPTTIMEOUT_MS.3 | 54 + docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.3 | 96 + docs/libcurl/opts/CURLOPT_ADDRESS_SCOPE.3 | 57 + docs/libcurl/opts/CURLOPT_APPEND.3 | 55 + docs/libcurl/opts/CURLOPT_AUTOREFERER.3 | 60 + docs/libcurl/opts/CURLOPT_BUFFERSIZE.3 | 65 + docs/libcurl/opts/CURLOPT_CAINFO.3 | 84 + docs/libcurl/opts/CURLOPT_CAPATH.3 | 70 + docs/libcurl/opts/CURLOPT_CERTINFO.3 | 77 + .../libcurl/opts/CURLOPT_CHUNK_BGN_FUNCTION.3 | 114 + docs/libcurl/opts/CURLOPT_CHUNK_DATA.3 | 90 + .../libcurl/opts/CURLOPT_CHUNK_END_FUNCTION.3 | 71 + docs/libcurl/opts/CURLOPT_CLOSESOCKETDATA.3 | 55 + .../opts/CURLOPT_CLOSESOCKETFUNCTION.3 | 66 + docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.3 | 65 + docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.3 | 64 + docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3 | 63 + docs/libcurl/opts/CURLOPT_CONNECT_TO.3 | 111 + .../opts/CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 | 101 + .../opts/CURLOPT_CONV_FROM_UTF8_FUNCTION.3 | 99 + .../opts/CURLOPT_CONV_TO_NETWORK_FUNCTION.3 | 100 + docs/libcurl/opts/CURLOPT_COOKIE.3 | 83 + docs/libcurl/opts/CURLOPT_COOKIEFILE.3 | 83 + docs/libcurl/opts/CURLOPT_COOKIEJAR.3 | 78 + docs/libcurl/opts/CURLOPT_COOKIELIST.3 | 120 + docs/libcurl/opts/CURLOPT_COOKIESESSION.3 | 66 + docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.3 | 70 + docs/libcurl/opts/CURLOPT_CRLF.3 | 56 + docs/libcurl/opts/CURLOPT_CRLFILE.3 | 72 + docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.3 | 111 + docs/libcurl/opts/CURLOPT_DEBUGDATA.3 | 45 + docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 | 187 + docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.3 | 82 + docs/libcurl/opts/CURLOPT_DIRLISTONLY.3 | 73 + .../opts/CURLOPT_DISALLOW_USERNAME_IN_URL.3 | 56 + docs/libcurl/opts/CURLOPT_DNS_CACHE_TIMEOUT.3 | 73 + docs/libcurl/opts/CURLOPT_DNS_INTERFACE.3 | 59 + docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.3 | 62 + docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.3 | 62 + docs/libcurl/opts/CURLOPT_DNS_SERVERS.3 | 67 + .../opts/CURLOPT_DNS_SHUFFLE_ADDRESSES.3 | 69 + .../opts/CURLOPT_DNS_USE_GLOBAL_CACHE.3 | 60 + docs/libcurl/opts/CURLOPT_EGDSOCKET.3 | 56 + docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 | 92 + .../opts/CURLOPT_EXPECT_100_TIMEOUT_MS.3 | 59 + docs/libcurl/opts/CURLOPT_FAILONERROR.3 | 67 + docs/libcurl/opts/CURLOPT_FILETIME.3 | 64 + docs/libcurl/opts/CURLOPT_FNMATCH_DATA.3 | 64 + docs/libcurl/opts/CURLOPT_FNMATCH_FUNCTION.3 | 74 + docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.3 | 80 + docs/libcurl/opts/CURLOPT_FORBID_REUSE.3 | 59 + docs/libcurl/opts/CURLOPT_FRESH_CONNECT.3 | 59 + docs/libcurl/opts/CURLOPT_FTPPORT.3 | 83 + docs/libcurl/opts/CURLOPT_FTPSSLAUTH.3 | 63 + docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.3 | 60 + .../opts/CURLOPT_FTP_ALTERNATIVE_TO_USER.3 | 64 + .../opts/CURLOPT_FTP_CREATE_MISSING_DIRS.3 | 81 + docs/libcurl/opts/CURLOPT_FTP_FILEMETHOD.3 | 73 + .../opts/CURLOPT_FTP_RESPONSE_TIMEOUT.3 | 62 + docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 | 63 + docs/libcurl/opts/CURLOPT_FTP_SSL_CCC.3 | 64 + docs/libcurl/opts/CURLOPT_FTP_USE_EPRT.3 | 47 + docs/libcurl/opts/CURLOPT_FTP_USE_EPSV.3 | 60 + docs/libcurl/opts/CURLOPT_FTP_USE_PRET.3 | 58 + docs/libcurl/opts/CURLOPT_GSSAPI_DELEGATION.3 | 60 + .../opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 | 59 + docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 | 57 + docs/libcurl/opts/CURLOPT_HEADER.3 | 69 + docs/libcurl/opts/CURLOPT_HEADERDATA.3 | 78 + docs/libcurl/opts/CURLOPT_HEADERFUNCTION.3 | 111 + docs/libcurl/opts/CURLOPT_HEADEROPT.3 | 74 + docs/libcurl/opts/CURLOPT_HTTP200ALIASES.3 | 71 + docs/libcurl/opts/CURLOPT_HTTPAUTH.3 | 132 + docs/libcurl/opts/CURLOPT_HTTPGET.3 | 64 + docs/libcurl/opts/CURLOPT_HTTPHEADER.3 | 120 + docs/libcurl/opts/CURLOPT_HTTPPOST.3 | 82 + docs/libcurl/opts/CURLOPT_HTTPPROXYTUNNEL.3 | 68 + .../opts/CURLOPT_HTTP_CONTENT_DECODING.3 | 57 + .../opts/CURLOPT_HTTP_TRANSFER_DECODING.3 | 56 + docs/libcurl/opts/CURLOPT_HTTP_VERSION.3 | 84 + .../opts/CURLOPT_IGNORE_CONTENT_LENGTH.3 | 67 + docs/libcurl/opts/CURLOPT_INFILESIZE.3 | 71 + docs/libcurl/opts/CURLOPT_INFILESIZE_LARGE.3 | 72 + docs/libcurl/opts/CURLOPT_INTERFACE.3 | 72 + docs/libcurl/opts/CURLOPT_INTERLEAVEDATA.3 | 58 + .../libcurl/opts/CURLOPT_INTERLEAVEFUNCTION.3 | 84 + docs/libcurl/opts/CURLOPT_IOCTLDATA.3 | 60 + docs/libcurl/opts/CURLOPT_IOCTLFUNCTION.3 | 92 + docs/libcurl/opts/CURLOPT_IPRESOLVE.3 | 64 + docs/libcurl/opts/CURLOPT_ISSUERCERT.3 | 69 + .../opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 | 61 + docs/libcurl/opts/CURLOPT_KEYPASSWD.3 | 61 + docs/libcurl/opts/CURLOPT_KRBLEVEL.3 | 59 + docs/libcurl/opts/CURLOPT_LOCALPORT.3 | 56 + docs/libcurl/opts/CURLOPT_LOCALPORTRANGE.3 | 60 + docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.3 | 64 + docs/libcurl/opts/CURLOPT_LOW_SPEED_LIMIT.3 | 60 + docs/libcurl/opts/CURLOPT_LOW_SPEED_TIME.3 | 59 + docs/libcurl/opts/CURLOPT_MAIL_AUTH.3 | 69 + docs/libcurl/opts/CURLOPT_MAIL_FROM.3 | 62 + docs/libcurl/opts/CURLOPT_MAIL_RCPT.3 | 72 + docs/libcurl/opts/CURLOPT_MAXCONNECTS.3 | 68 + docs/libcurl/opts/CURLOPT_MAXFILESIZE.3 | 61 + docs/libcurl/opts/CURLOPT_MAXFILESIZE_LARGE.3 | 62 + docs/libcurl/opts/CURLOPT_MAXREDIRS.3 | 64 + .../opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 | 58 + .../opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 | 60 + docs/libcurl/opts/CURLOPT_MIMEPOST.3 | 52 + docs/libcurl/opts/CURLOPT_NETRC.3 | 83 + docs/libcurl/opts/CURLOPT_NETRC_FILE.3 | 60 + .../opts/CURLOPT_NEW_DIRECTORY_PERMS.3 | 57 + docs/libcurl/opts/CURLOPT_NEW_FILE_PERMS.3 | 56 + docs/libcurl/opts/CURLOPT_NOBODY.3 | 60 + docs/libcurl/opts/CURLOPT_NOPROGRESS.3 | 59 + docs/libcurl/opts/CURLOPT_NOPROXY.3 | 79 + docs/libcurl/opts/CURLOPT_NOSIGNAL.3 | 55 + docs/libcurl/opts/CURLOPT_OPENSOCKETDATA.3 | 81 + .../libcurl/opts/CURLOPT_OPENSOCKETFUNCTION.3 | 128 + docs/libcurl/opts/CURLOPT_PASSWORD.3 | 64 + docs/libcurl/opts/CURLOPT_PATH_AS_IS.3 | 65 + docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 | 132 + docs/libcurl/opts/CURLOPT_PIPEWAIT.3 | 63 + docs/libcurl/opts/CURLOPT_PORT.3 | 59 + docs/libcurl/opts/CURLOPT_POST.3 | 89 + docs/libcurl/opts/CURLOPT_POSTFIELDS.3 | 88 + docs/libcurl/opts/CURLOPT_POSTFIELDSIZE.3 | 62 + .../opts/CURLOPT_POSTFIELDSIZE_LARGE.3 | 64 + docs/libcurl/opts/CURLOPT_POSTQUOTE.3 | 64 + docs/libcurl/opts/CURLOPT_POSTREDIR.3 | 73 + docs/libcurl/opts/CURLOPT_PREQUOTE.3 | 66 + docs/libcurl/opts/CURLOPT_PRE_PROXY.3 | 80 + docs/libcurl/opts/CURLOPT_PRIVATE.3 | 61 + docs/libcurl/opts/CURLOPT_PROGRESSDATA.3 | 44 + docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.3 | 84 + docs/libcurl/opts/CURLOPT_PROTOCOLS.3 | 93 + docs/libcurl/opts/CURLOPT_PROXY.3 | 118 + docs/libcurl/opts/CURLOPT_PROXYAUTH.3 | 69 + docs/libcurl/opts/CURLOPT_PROXYHEADER.3 | 75 + docs/libcurl/opts/CURLOPT_PROXYPASSWORD.3 | 62 + docs/libcurl/opts/CURLOPT_PROXYPORT.3 | 57 + docs/libcurl/opts/CURLOPT_PROXYTYPE.3 | 76 + docs/libcurl/opts/CURLOPT_PROXYUSERNAME.3 | 66 + docs/libcurl/opts/CURLOPT_PROXYUSERPWD.3 | 62 + docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 | 83 + docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 | 72 + docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 | 75 + docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 | 62 + .../opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 | 111 + .../libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.3 | 57 + docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 | 72 + docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 | 67 + docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 | 68 + docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 | 61 + docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 | 96 + .../opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 | 80 + docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 | 72 + .../opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 | 82 + .../opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 | 89 + .../opts/CURLOPT_PROXY_TLS13_CIPHERS.3 | 63 + .../opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 | 62 + .../libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 | 70 + .../opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 | 62 + .../opts/CURLOPT_PROXY_TRANSFER_MODE.3 | 58 + docs/libcurl/opts/CURLOPT_PUT.3 | 46 + docs/libcurl/opts/CURLOPT_QUOTE.3 | 105 + docs/libcurl/opts/CURLOPT_RANDOM_FILE.3 | 56 + docs/libcurl/opts/CURLOPT_RANGE.3 | 73 + docs/libcurl/opts/CURLOPT_READDATA.3 | 64 + docs/libcurl/opts/CURLOPT_READFUNCTION.3 | 79 + docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 | 100 + docs/libcurl/opts/CURLOPT_REFERER.3 | 60 + docs/libcurl/opts/CURLOPT_REQUEST_TARGET.3 | 56 + docs/libcurl/opts/CURLOPT_RESOLVE.3 | 97 + .../opts/CURLOPT_RESOLVER_START_DATA.3 | 63 + .../opts/CURLOPT_RESOLVER_START_FUNCTION.3 | 83 + docs/libcurl/opts/CURLOPT_RESUME_FROM.3 | 72 + docs/libcurl/opts/CURLOPT_RESUME_FROM_LARGE.3 | 74 + docs/libcurl/opts/CURLOPT_RTSP_CLIENT_CSEQ.3 | 53 + docs/libcurl/opts/CURLOPT_RTSP_REQUEST.3 | 111 + docs/libcurl/opts/CURLOPT_RTSP_SERVER_CSEQ.3 | 53 + docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.3 | 61 + docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.3 | 66 + docs/libcurl/opts/CURLOPT_RTSP_TRANSPORT.3 | 62 + docs/libcurl/opts/CURLOPT_SASL_IR.3 | 64 + docs/libcurl/opts/CURLOPT_SEEKDATA.3 | 57 + docs/libcurl/opts/CURLOPT_SEEKFUNCTION.3 | 89 + docs/libcurl/opts/CURLOPT_SERVICE_NAME.3 | 58 + docs/libcurl/opts/CURLOPT_SHARE.3 | 81 + docs/libcurl/opts/CURLOPT_SOCKOPTDATA.3 | 67 + docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.3 | 124 + docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3 | 63 + docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_NEC.3 | 56 + .../opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.3 | 60 + docs/libcurl/opts/CURLOPT_SSH_AUTH_TYPES.3 | 59 + docs/libcurl/opts/CURLOPT_SSH_COMPRESSION.3 | 58 + .../opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 | 60 + docs/libcurl/opts/CURLOPT_SSH_KEYDATA.3 | 63 + docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3 | 124 + docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.3 | 61 + .../opts/CURLOPT_SSH_PRIVATE_KEYFILE.3 | 64 + .../libcurl/opts/CURLOPT_SSH_PUBLIC_KEYFILE.3 | 65 + docs/libcurl/opts/CURLOPT_SSLCERT.3 | 79 + docs/libcurl/opts/CURLOPT_SSLCERTTYPE.3 | 62 + docs/libcurl/opts/CURLOPT_SSLENGINE.3 | 66 + docs/libcurl/opts/CURLOPT_SSLENGINE_DEFAULT.3 | 63 + docs/libcurl/opts/CURLOPT_SSLKEY.3 | 63 + docs/libcurl/opts/CURLOPT_SSLKEYTYPE.3 | 64 + docs/libcurl/opts/CURLOPT_SSLVERSION.3 | 108 + docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3 | 75 + docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.3 | 124 + docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.3 | 78 + docs/libcurl/opts/CURLOPT_SSL_ENABLE_ALPN.3 | 53 + docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.3 | 53 + docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3 | 55 + docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 | 71 + .../opts/CURLOPT_SSL_SESSIONID_CACHE.3 | 58 + docs/libcurl/opts/CURLOPT_SSL_VERIFYHOST.3 | 94 + docs/libcurl/opts/CURLOPT_SSL_VERIFYPEER.3 | 93 + docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3 | 62 + docs/libcurl/opts/CURLOPT_STDERR.3 | 54 + docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.3 | 68 + docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.3 | 71 + docs/libcurl/opts/CURLOPT_STREAM_WEIGHT.3 | 76 + .../opts/CURLOPT_SUPPRESS_CONNECT_HEADERS.3 | 95 + docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3 | 54 + docs/libcurl/opts/CURLOPT_TCP_KEEPALIVE.3 | 63 + docs/libcurl/opts/CURLOPT_TCP_KEEPIDLE.3 | 61 + docs/libcurl/opts/CURLOPT_TCP_KEEPINTVL.3 | 61 + docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 | 64 + docs/libcurl/opts/CURLOPT_TELNETOPTIONS.3 | 59 + docs/libcurl/opts/CURLOPT_TFTP_BLKSIZE.3 | 57 + docs/libcurl/opts/CURLOPT_TFTP_NO_OPTIONS.3 | 71 + docs/libcurl/opts/CURLOPT_TIMECONDITION.3 | 65 + docs/libcurl/opts/CURLOPT_TIMEOUT.3 | 71 + docs/libcurl/opts/CURLOPT_TIMEOUT_MS.3 | 74 + docs/libcurl/opts/CURLOPT_TIMEVALUE.3 | 62 + docs/libcurl/opts/CURLOPT_TIMEVALUE_LARGE.3 | 64 + docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.3 | 62 + docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.3 | 60 + docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.3 | 65 + docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.3 | 60 + docs/libcurl/opts/CURLOPT_TRANSFERTEXT.3 | 59 + docs/libcurl/opts/CURLOPT_TRANSFER_ENCODING.3 | 61 + docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 | 81 + docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.3 | 60 + docs/libcurl/opts/CURLOPT_UPLOAD.3 | 78 + docs/libcurl/opts/CURLOPT_URL.3 | 349 + docs/libcurl/opts/CURLOPT_USERAGENT.3 | 59 + docs/libcurl/opts/CURLOPT_USERNAME.3 | 85 + docs/libcurl/opts/CURLOPT_USERPWD.3 | 91 + docs/libcurl/opts/CURLOPT_USE_SSL.3 | 69 + docs/libcurl/opts/CURLOPT_VERBOSE.3 | 63 + docs/libcurl/opts/CURLOPT_WILDCARDMATCH.3 | 87 + docs/libcurl/opts/CURLOPT_WRITEDATA.3 | 60 + docs/libcurl/opts/CURLOPT_WRITEFUNCTION.3 | 81 + docs/libcurl/opts/CURLOPT_XFERINFODATA.3 | 46 + docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.3 | 81 + docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.3 | 60 + docs/libcurl/opts/Makefile.am | 61 + docs/libcurl/opts/Makefile.inc | 340 + docs/libcurl/opts/template.3 | 38 + docs/libcurl/symbols-in-versions | 885 +++ docs/libcurl/symbols.pl | 100 + docs/mk-ca-bundle.1 | 119 + include/Makefile.am | 5 + include/README | 18 + include/curl/.gitignore | 3 + include/curl/Makefile.am | 34 + include/curl/curl.h | 2800 +++++++ include/curl/curlver.h | 77 + include/curl/easy.h | 102 + include/curl/mprintf.h | 50 + include/curl/multi.h | 441 ++ include/curl/stdcheaders.h | 33 + include/curl/system.h | 493 ++ include/curl/typecheck-gcc.h | 696 ++ lib/.gitattributes | 1 + lib/.gitignore | 12 + lib/CMakeLists.txt | 124 + lib/Makefile.Watcom | 275 + lib/Makefile.am | 143 + lib/Makefile.inc | 82 + lib/Makefile.m32 | 387 + lib/Makefile.netware | 760 ++ lib/Makefile.vxworks | 177 + lib/amigaos.c | 77 + lib/amigaos.h | 39 + lib/arpa_telnet.h | 104 + lib/asyn-ares.c | 701 ++ lib/asyn-thread.c | 732 ++ lib/asyn.h | 168 + lib/base64.c | 319 + lib/checksrc.pl | 629 ++ lib/config-amigaos.h | 166 + lib/config-dos.h | 184 + lib/config-mac.h | 125 + lib/config-os400.h | 569 ++ lib/config-riscos.h | 513 ++ lib/config-symbian.h | 808 ++ lib/config-tpf.h | 772 ++ lib/config-vxworks.h | 925 +++ lib/config-win32.h | 742 ++ lib/config-win32ce.h | 448 ++ lib/conncache.c | 632 ++ lib/conncache.h | 86 + lib/connect.c | 1442 ++++ lib/connect.h | 151 + lib/content_encoding.c | 1016 +++ lib/content_encoding.h | 55 + lib/cookie.c | 1569 ++++ lib/cookie.h | 109 + lib/curl_addrinfo.c | 624 ++ lib/curl_addrinfo.h | 110 + lib/curl_base64.h | 35 + lib/curl_config.h.cmake | 1011 +++ lib/curl_ctype.c | 133 + lib/curl_ctype.h | 81 + lib/curl_des.c | 63 + lib/curl_des.h | 34 + lib/curl_endian.c | 124 + lib/curl_endian.h | 46 + lib/curl_fnmatch.c | 396 + lib/curl_fnmatch.h | 44 + lib/curl_gethostname.c | 100 + lib/curl_gethostname.h | 31 + lib/curl_gssapi.c | 136 + lib/curl_gssapi.h | 75 + lib/curl_hmac.h | 67 + lib/curl_ldap.h | 35 + lib/curl_md4.h | 35 + lib/curl_md5.h | 63 + lib/curl_memory.h | 156 + lib/curl_memrchr.c | 62 + lib/curl_memrchr.h | 44 + lib/curl_multibyte.c | 84 + lib/curl_multibyte.h | 92 + lib/curl_ntlm_core.c | 826 ++ lib/curl_ntlm_core.h | 107 + lib/curl_ntlm_wb.c | 425 + lib/curl_ntlm_wb.h | 38 + lib/curl_path.c | 195 + lib/curl_path.h | 47 + lib/curl_printf.h | 56 + lib/curl_range.c | 95 + lib/curl_range.h | 30 + lib/curl_rtmp.c | 313 + lib/curl_rtmp.h | 33 + lib/curl_sasl.c | 629 ++ lib/curl_sasl.h | 143 + lib/curl_sec.h | 51 + lib/curl_setup.h | 811 ++ lib/curl_setup_once.h | 518 ++ lib/curl_sha256.h | 32 + lib/curl_sspi.c | 235 + lib/curl_sspi.h | 350 + lib/curl_threads.c | 146 + lib/curl_threads.h | 63 + lib/curlx.h | 105 + lib/dict.c | 279 + lib/dict.h | 29 + lib/dotdot.c | 180 + lib/dotdot.h | 25 + lib/easy.c | 1192 +++ lib/easyif.h | 33 + lib/escape.c | 240 + lib/escape.h | 33 + lib/file.c | 544 ++ lib/file.h | 41 + lib/fileinfo.c | 43 + lib/fileinfo.h | 36 + lib/firefox-db2pem.sh | 54 + lib/formdata.c | 951 +++ lib/formdata.h | 51 + lib/ftp.c | 4445 +++++++++++ lib/ftp.h | 161 + lib/ftplistparser.c | 1022 +++ lib/ftplistparser.h | 41 + lib/getenv.c | 54 + lib/getinfo.c | 491 ++ lib/getinfo.h | 27 + lib/gopher.c | 167 + lib/gopher.h | 29 + lib/hash.c | 351 + lib/hash.h | 100 + lib/hmac.c | 132 + lib/hostasyn.c | 153 + lib/hostcheck.c | 153 + lib/hostcheck.h | 32 + lib/hostip.c | 1051 +++ lib/hostip.h | 261 + lib/hostip4.c | 308 + lib/hostip6.c | 201 + lib/hostsyn.c | 107 + lib/http.c | 3885 +++++++++ lib/http.h | 256 + lib/http2.c | 2345 ++++++ lib/http2.h | 80 + lib/http_chunks.c | 351 + lib/http_chunks.h | 91 + lib/http_digest.c | 180 + lib/http_digest.h | 42 + lib/http_negotiate.c | 138 + lib/http_negotiate.h | 38 + lib/http_ntlm.c | 251 + lib/http_ntlm.h | 40 + lib/http_proxy.c | 686 ++ lib/http_proxy.h | 51 + lib/idn_win32.c | 111 + lib/if2ip.c | 274 + lib/if2ip.h | 84 + lib/imap.c | 2103 +++++ lib/imap.h | 97 + lib/inet_ntop.c | 197 + lib/inet_ntop.h | 38 + lib/inet_pton.c | 236 + lib/inet_pton.h | 40 + lib/krb5.c | 343 + lib/ldap.c | 1078 +++ lib/libcurl.plist | 35 + lib/libcurl.rc | 63 + lib/libcurl.vers.in | 13 + lib/llist.c | 197 + lib/llist.h | 54 + lib/makefile.amiga | 21 + lib/makefile.dj | 72 + lib/md4.c | 307 + lib/md5.c | 568 ++ lib/memdebug.c | 519 ++ lib/memdebug.h | 179 + lib/mime.c | 1975 +++++ lib/mime.h | 143 + lib/mk-ca-bundle.pl | 558 ++ lib/mk-ca-bundle.vbs | 431 + lib/mprintf.c | 1173 +++ lib/multi.c | 3183 ++++++++ lib/multihandle.h | 158 + lib/multiif.h | 100 + lib/netrc.c | 205 + lib/netrc.h | 36 + lib/non-ascii.c | 332 + lib/non-ascii.h | 61 + lib/nonblock.c | 90 + lib/nonblock.h | 31 + lib/nwlib.c | 325 + lib/nwos.c | 88 + lib/objnames-test08.sh | 217 + lib/objnames-test10.sh | 217 + lib/objnames.inc | 107 + lib/openldap.c | 763 ++ lib/parsedate.c | 596 ++ lib/parsedate.h | 31 + lib/pingpong.c | 521 ++ lib/pingpong.h | 150 + lib/pipeline.c | 404 + lib/pipeline.h | 56 + lib/pop3.c | 1544 ++++ lib/pop3.h | 95 + lib/progress.c | 607 ++ lib/progress.h | 65 + lib/psl.c | 111 + lib/psl.h | 47 + lib/rand.c | 185 + lib/rand.h | 47 + lib/rtsp.c | 849 ++ lib/rtsp.h | 67 + lib/security.c | 586 ++ lib/select.c | 585 ++ lib/select.h | 116 + lib/sendf.c | 836 ++ lib/sendf.h | 91 + lib/setopt.c | 2629 ++++++ lib/setopt.h | 29 + lib/setup-os400.h | 223 + lib/setup-vms.h | 443 ++ lib/sha256.c | 270 + lib/share.c | 257 + lib/share.h | 66 + lib/sigpipe.h | 78 + lib/slist.c | 145 + lib/slist.h | 40 + lib/smb.c | 1005 +++ lib/smb.h | 258 + lib/smtp.c | 1646 ++++ lib/smtp.h | 91 + lib/sockaddr.h | 43 + lib/socks.c | 792 ++ lib/socks.h | 76 + lib/socks_gssapi.c | 527 ++ lib/socks_sspi.c | 605 ++ lib/speedcheck.c | 73 + lib/speedcheck.h | 33 + lib/splay.c | 277 + lib/splay.h | 68 + lib/ssh-libssh.c | 2747 +++++++ lib/ssh.c | 3348 ++++++++ lib/ssh.h | 245 + lib/strcase.c | 177 + lib/strcase.h | 51 + lib/strdup.c | 100 + lib/strdup.h | 32 + lib/strerror.c | 1109 +++ lib/strerror.h | 37 + lib/strtok.c | 66 + lib/strtok.h | 34 + lib/strtoofft.c | 242 + lib/strtoofft.h | 52 + lib/system_win32.c | 329 + lib/system_win32.h | 61 + lib/telnet.c | 1701 ++++ lib/telnet.h | 29 + lib/tftp.c | 1404 ++++ lib/tftp.h | 29 + lib/timeval.c | 186 + lib/timeval.h | 56 + lib/transfer.c | 2089 +++++ lib/transfer.h | 72 + lib/url.c | 4869 ++++++++++++ lib/url.h | 95 + lib/urldata.h | 1769 +++++ lib/vauth/cleartext.c | 159 + lib/vauth/cram.c | 138 + lib/vauth/digest.c | 1003 +++ lib/vauth/digest.h | 47 + lib/vauth/digest_sspi.c | 669 ++ lib/vauth/krb5_gssapi.c | 401 + lib/vauth/krb5_sspi.c | 514 ++ lib/vauth/ntlm.c | 865 ++ lib/vauth/ntlm.h | 143 + lib/vauth/ntlm_sspi.c | 344 + lib/vauth/oauth2.c | 86 + lib/vauth/spnego_gssapi.c | 278 + lib/vauth/spnego_sspi.c | 320 + lib/vauth/vauth.c | 147 + lib/vauth/vauth.h | 207 + lib/version.c | 456 ++ lib/vtls/axtls.c | 741 ++ lib/vtls/axtls.h | 34 + lib/vtls/cyassl.c | 1026 +++ lib/vtls/cyassl.h | 31 + lib/vtls/darwinssl.c | 3067 +++++++ lib/vtls/darwinssl.h | 32 + lib/vtls/gskit.c | 1384 ++++ lib/vtls/gskit.h | 38 + lib/vtls/gtls.c | 1834 +++++ lib/vtls/gtls.h | 34 + lib/vtls/mbedtls.c | 1080 +++ lib/vtls/mbedtls.h | 32 + lib/vtls/nss.c | 2392 ++++++ lib/vtls/nssg.h | 39 + lib/vtls/openssl.c | 3799 +++++++++ lib/vtls/openssl.h | 37 + lib/vtls/polarssl.c | 933 +++ lib/vtls/polarssl.h | 32 + lib/vtls/polarssl_threadlock.c | 153 + lib/vtls/polarssl_threadlock.h | 53 + lib/vtls/schannel.c | 2137 +++++ lib/vtls/schannel.h | 108 + lib/vtls/schannel_verify.c | 557 ++ lib/vtls/vtls.c | 1336 ++++ lib/vtls/vtls.h | 278 + lib/warnless.c | 546 ++ lib/warnless.h | 113 + lib/wildcard.c | 69 + lib/wildcard.h | 61 + lib/x509asn1.c | 1200 +++ lib/x509asn1.h | 134 + libcurl.pc.in | 39 + m4/.gitignore | 6 + m4/ax_code_coverage.m4 | 264 + m4/ax_compile_check_sizeof.m4 | 115 + m4/curl-compilers.m4 | 1620 ++++ m4/curl-confopts.m4 | 652 ++ m4/curl-functions.m4 | 7027 +++++++++++++++++ m4/curl-openssl.m4 | 278 + m4/curl-override.m4 | 76 + m4/curl-reentrant.m4 | 617 ++ m4/xc-am-iface.m4 | 253 + m4/xc-cc-check.m4 | 96 + m4/xc-lt-iface.m4 | 465 ++ m4/xc-translit.m4 | 164 + m4/xc-val-flgs.m4 | 243 + m4/zz40-xc-ovr.m4 | 666 ++ m4/zz50-xc-ovr.m4 | 60 + m4/zz60-xc-ovr.m4 | 64 + maketgz | 217 + packages/AIX/Makefile.am | 3 + packages/AIX/RPM/.gitignore | 1 + packages/AIX/RPM/Makefile.am | 2 + packages/AIX/RPM/README | 33 + packages/AIX/RPM/curl.spec.in | 134 + packages/Android/Android.mk | 111 + packages/DOS/README | 11 + packages/DOS/common.dj | 136 + packages/EPM/.gitignore | 1 + packages/EPM/Makefile.am | 3 + packages/EPM/README | 12 + packages/EPM/curl.list.in | 60 + packages/Linux/Makefile.am | 1 + packages/Linux/RPM/.gitignore | 2 + packages/Linux/RPM/Makefile.am | 2 + packages/Linux/RPM/README | 5 + packages/Linux/RPM/curl-ssl.spec.in | 85 + packages/Linux/RPM/curl.spec.in | 84 + packages/Linux/RPM/make_curl_rpm | 62 + packages/Makefile.am | 33 + packages/NetWare/get_exp.awk | 72 + packages/NetWare/get_ver.awk | 44 + packages/OS400/README.OS400 | 338 + packages/OS400/ccsidcurl.c | 1426 ++++ packages/OS400/ccsidcurl.h | 89 + packages/OS400/curl.inc.in | 2643 +++++++ packages/OS400/initscript.sh | 261 + packages/OS400/make-include.sh | 83 + packages/OS400/make-lib.sh | 204 + packages/OS400/make-src.sh | 4 + packages/OS400/make-tests.sh | 114 + packages/OS400/makefile.sh | 54 + packages/OS400/os400sys.c | 1452 ++++ packages/OS400/os400sys.h | 55 + packages/README | 27 + packages/Solaris/Makefile.am | 38 + packages/Symbian/bwins/libcurlu.def | 61 + packages/Symbian/eabi/libcurlu.def | 61 + packages/Symbian/group/bld.inf | 10 + packages/Symbian/group/curl.iby | 15 + packages/Symbian/group/curl.mmp | 64 + packages/Symbian/group/curl.pkg | 26 + packages/Symbian/group/libcurl.iby | 14 + packages/Symbian/group/libcurl.mmp | 67 + packages/Symbian/group/libcurl.pkg | 22 + packages/Symbian/readme.txt | 93 + packages/TPF/curl.mak | 60 + packages/TPF/maketpf.env_curl | 25 + packages/TPF/maketpf.env_curllib | 57 + packages/Win32/Makefile.am | 3 + packages/Win32/README | 53 + packages/Win32/cygwin/Makefile.am | 62 + packages/Win32/cygwin/README | 114 + packages/vms/Makefile.am | 36 + packages/vms/backup_gnv_curl_src.com | 132 + packages/vms/build_curl-config_script.com | 154 + packages/vms/build_gnv_curl.com | 38 + packages/vms/build_gnv_curl_pcsi_desc.com | 492 ++ packages/vms/build_gnv_curl_pcsi_text.com | 198 + packages/vms/build_gnv_curl_release_notes.com | 102 + packages/vms/build_libcurl_pc.com | 205 + packages/vms/build_vms.com | 1038 +++ packages/vms/clean_gnv_curl.com | 244 + packages/vms/compare_curl_source.com | 371 + packages/vms/config_h.com | 2184 +++++ packages/vms/curl_crtl_init.c | 311 + packages/vms/curl_gnv_build_steps.txt | 288 + packages/vms/curl_release_note_start.txt | 77 + packages/vms/curl_startup.com | 100 + packages/vms/curlmsg.h | 141 + packages/vms/curlmsg.msg | 111 + packages/vms/curlmsg.sdl | 116 + packages/vms/curlmsg_vms.h | 141 + packages/vms/generate_config_vms_h_curl.com | 484 ++ packages/vms/generate_vax_transfer.com | 274 + packages/vms/gnv_conftest.c_first | 61 + packages/vms/gnv_curl_configure.sh | 46 + packages/vms/gnv_libcurl_symbols.opt | 181 + packages/vms/gnv_link_curl.com | 852 ++ packages/vms/macro32_exactcase.patch | 11 + packages/vms/make_gnv_curl_install.sh | 45 + packages/vms/make_pcsi_curl_kit_name.com | 190 + packages/vms/pcsi_gnv_curl_file_list.txt | 126 + packages/vms/pcsi_product_gnv_curl.com | 199 + packages/vms/readme | 228 + packages/vms/report_openssl_version.c | 100 + packages/vms/setup_gnv_curl_build.com | 288 + packages/vms/stage_curl_install.com | 173 + packages/vms/vms_eco_level.h | 30 + projects/README | 159 + projects/Windows/.gitattributes | 1 + projects/Windows/.gitignore | 6 + projects/Windows/VC10/.gitignore | 4 + projects/Windows/VC10/curl-all.sln | 298 + projects/Windows/VC10/lib/.gitignore | 6 + projects/Windows/VC10/lib/libcurl.sln | 181 + projects/Windows/VC10/lib/libcurl.tmpl | 2341 ++++++ .../Windows/VC10/lib/libcurl.vcxproj.filters | 17 + projects/Windows/VC10/src/.gitignore | 6 + projects/Windows/VC10/src/curl.sln | 181 + projects/Windows/VC10/src/curl.tmpl | 2643 +++++++ .../Windows/VC10/src/curl.vcxproj.filters | 17 + projects/Windows/VC11/.gitignore | 4 + projects/Windows/VC11/curl-all.sln | 298 + projects/Windows/VC11/lib/.gitignore | 6 + projects/Windows/VC11/lib/libcurl.sln | 181 + projects/Windows/VC11/lib/libcurl.tmpl | 2397 ++++++ .../Windows/VC11/lib/libcurl.vcxproj.filters | 17 + projects/Windows/VC11/src/.gitignore | 6 + projects/Windows/VC11/src/curl.sln | 181 + projects/Windows/VC11/src/curl.tmpl | 2699 +++++++ .../Windows/VC11/src/curl.vcxproj.filters | 17 + projects/Windows/VC12/.gitignore | 4 + projects/Windows/VC12/curl-all.sln | 298 + projects/Windows/VC12/lib/.gitignore | 6 + projects/Windows/VC12/lib/libcurl.sln | 181 + projects/Windows/VC12/lib/libcurl.tmpl | 2397 ++++++ .../Windows/VC12/lib/libcurl.vcxproj.filters | 17 + projects/Windows/VC12/src/.gitignore | 6 + projects/Windows/VC12/src/curl.sln | 181 + projects/Windows/VC12/src/curl.tmpl | 2699 +++++++ .../Windows/VC12/src/curl.vcxproj.filters | 17 + projects/Windows/VC14/.gitignore | 5 + projects/Windows/VC14/curl-all.sln | 298 + projects/Windows/VC14/lib/.gitignore | 6 + projects/Windows/VC14/lib/libcurl.sln | 181 + projects/Windows/VC14/lib/libcurl.tmpl | 2397 ++++++ .../Windows/VC14/lib/libcurl.vcxproj.filters | 17 + projects/Windows/VC14/src/.gitignore | 6 + projects/Windows/VC14/src/curl.sln | 181 + projects/Windows/VC14/src/curl.tmpl | 2699 +++++++ .../Windows/VC14/src/curl.vcxproj.filters | 17 + projects/Windows/VC15/.gitignore | 5 + projects/Windows/VC15/curl-all.sln | 298 + projects/Windows/VC15/lib/.gitignore | 6 + projects/Windows/VC15/lib/libcurl.sln | 181 + projects/Windows/VC15/lib/libcurl.tmpl | 2397 ++++++ .../Windows/VC15/lib/libcurl.vcxproj.filters | 17 + projects/Windows/VC15/src/.gitignore | 6 + projects/Windows/VC15/src/curl.sln | 181 + projects/Windows/VC15/src/curl.tmpl | 2699 +++++++ .../Windows/VC15/src/curl.vcxproj.filters | 17 + projects/Windows/VC6/.gitignore | 2 + projects/Windows/VC6/curl-all.dsw | 44 + projects/Windows/VC6/lib/.gitignore | 5 + projects/Windows/VC6/lib/libcurl.dsw | 29 + projects/Windows/VC6/lib/libcurl.tmpl | 748 ++ projects/Windows/VC6/src/.gitignore | 5 + projects/Windows/VC6/src/curl.dsw | 29 + projects/Windows/VC6/src/curl.tmpl | 695 ++ projects/Windows/VC7.1/.gitignore | 2 + projects/Windows/VC7.1/curl-all.sln | 140 + projects/Windows/VC7.1/lib/.gitignore | 3 + projects/Windows/VC7.1/lib/libcurl.sln | 87 + projects/Windows/VC7.1/lib/libcurl.tmpl | 1301 +++ projects/Windows/VC7.1/src/.gitignore | 3 + projects/Windows/VC7.1/src/curl.sln | 87 + projects/Windows/VC7.1/src/curl.tmpl | 1381 ++++ projects/Windows/VC7/.gitignore | 1 + projects/Windows/VC7/curl-all.sln | 138 + projects/Windows/VC7/lib/.gitignore | 2 + projects/Windows/VC7/lib/libcurl.sln | 87 + projects/Windows/VC7/lib/libcurl.tmpl | 1155 +++ projects/Windows/VC7/src/.gitignore | 2 + projects/Windows/VC7/src/curl.sln | 87 + projects/Windows/VC7/src/curl.tmpl | 1235 +++ projects/Windows/VC8/.gitignore | 2 + projects/Windows/VC8/curl-all.sln | 258 + projects/Windows/VC8/lib/.gitignore | 4 + projects/Windows/VC8/lib/libcurl.sln | 157 + projects/Windows/VC8/lib/libcurl.tmpl | 3662 +++++++++ projects/Windows/VC8/src/.gitignore | 4 + projects/Windows/VC8/src/curl.sln | 157 + projects/Windows/VC8/src/curl.tmpl | 4100 ++++++++++ projects/Windows/VC9/.gitignore | 2 + projects/Windows/VC9/curl-all.sln | 258 + projects/Windows/VC9/lib/.gitignore | 4 + projects/Windows/VC9/lib/libcurl.sln | 157 + projects/Windows/VC9/lib/libcurl.tmpl | 3603 +++++++++ projects/Windows/VC9/src/.gitignore | 4 + projects/Windows/VC9/src/curl.sln | 157 + projects/Windows/VC9/src/curl.tmpl | 3957 ++++++++++ projects/build-openssl.bat | 476 ++ projects/build-wolfssl.bat | 374 + projects/checksrc.bat | 193 + projects/generate.bat | 460 ++ projects/wolfssl_options.h | 224 + projects/wolfssl_override.props | 40 + scripts/Makefile.am | 45 + scripts/contributors.sh | 82 + scripts/contrithanks.sh | 59 + scripts/coverage.sh | 16 + scripts/installcheck.sh | 27 + scripts/log2changes.pl | 81 + scripts/updatemanpages.pl | 355 + scripts/zsh.pl | 89 + src/.gitignore | 10 + src/CMakeLists.txt | 86 + src/Makefile.Watcom | 234 + src/Makefile.am | 142 + src/Makefile.inc | 113 + src/Makefile.m32 | 402 + src/Makefile.netware | 524 ++ src/curl.rc | 111 + src/macos/MACINSTALL.TXT | 1 + src/macos/curl.mcp.xml.sit.hqx | 1 + src/macos/src/curl_GUSIConfig.cpp | 1 + src/macos/src/macos_main.cpp | 1 + src/makefile.amiga | 30 + src/makefile.dj | 94 + src/mkhelp.pl | 256 + src/slist_wc.c | 72 + src/slist_wc.h | 56 + src/tool_binmode.c | 52 + src/tool_binmode.h | 37 + src/tool_bname.c | 50 + src/tool_bname.h | 35 + src/tool_cb_dbg.c | 282 + src/tool_cb_dbg.h | 35 + src/tool_cb_hdr.c | 277 + src/tool_cb_hdr.h | 56 + src/tool_cb_prg.c | 238 + src/tool_cb_prg.h | 53 + src/tool_cb_rea.c | 55 + src/tool_cb_rea.h | 33 + src/tool_cb_see.c | 131 + src/tool_cb_see.h | 46 + src/tool_cb_wrt.c | 178 + src/tool_cb_wrt.h | 36 + src/tool_cfgable.c | 176 + src/tool_cfgable.h | 291 + src/tool_convert.c | 150 + src/tool_convert.h | 45 + src/tool_dirhie.c | 158 + src/tool_dirhie.h | 29 + src/tool_doswin.c | 675 ++ src/tool_doswin.h | 69 + src/tool_easysrc.c | 236 + src/tool_easysrc.h | 49 + src/tool_filetime.c | 154 + src/tool_filetime.h | 38 + src/tool_formparse.c | 862 ++ src/tool_formparse.h | 33 + src/tool_getparam.c | 2223 ++++++ src/tool_getparam.h | 65 + src/tool_getpass.c | 254 + src/tool_getpass.h | 36 + src/tool_help.c | 589 ++ src/tool_help.h | 31 + src/tool_helpers.c | 120 + src/tool_helpers.h | 35 + src/tool_homedir.c | 95 + src/tool_homedir.h | 28 + src/tool_hugehelp.c.cvs | 29 + src/tool_hugehelp.h | 28 + src/tool_libinfo.c | 102 + src/tool_libinfo.h | 34 + src/tool_main.c | 285 + src/tool_main.h | 44 + src/tool_metalink.c | 1007 +++ src/tool_metalink.h | 167 + src/tool_msgs.c | 125 + src/tool_msgs.h | 32 + src/tool_operate.c | 2047 +++++ src/tool_operate.h | 29 + src/tool_operhlp.c | 190 + src/tool_operhlp.h | 39 + src/tool_panykey.c | 48 + src/tool_panykey.h | 37 + src/tool_paramhlp.c | 610 ++ src/tool_paramhlp.h | 56 + src/tool_parsecfg.c | 359 + src/tool_parsecfg.h | 29 + src/tool_sdecls.h | 151 + src/tool_setopt.c | 704 ++ src/tool_setopt.h | 153 + src/tool_setup.h | 74 + src/tool_sleep.c | 58 + src/tool_sleep.h | 29 + src/tool_strdup.c | 47 + src/tool_strdup.h | 30 + src/tool_urlglob.c | 713 ++ src/tool_urlglob.h | 77 + src/tool_util.c | 126 + src/tool_util.h | 37 + src/tool_version.h | 34 + src/tool_vms.c | 219 + src/tool_vms.h | 47 + src/tool_writeout.c | 369 + src/tool_writeout.h | 28 + src/tool_xattr.c | 90 + src/tool_xattr.h | 28 + tests/.gitignore | 19 + tests/CMakeLists.txt | 4 + tests/FILEFORMAT | 460 ++ tests/Makefile.am | 124 + tests/README | 289 + tests/certs/EdelCurlRoot-ca.cacert | 84 + tests/certs/EdelCurlRoot-ca.cnf | 11 + tests/certs/EdelCurlRoot-ca.crt | 84 + tests/certs/EdelCurlRoot-ca.csr | 17 + tests/certs/EdelCurlRoot-ca.der | Bin 0 -> 918 bytes tests/certs/EdelCurlRoot-ca.key | 27 + tests/certs/EdelCurlRoot-ca.prm | 18 + tests/certs/Makefile.am | 116 + tests/certs/Server-localhost-firstSAN-sv.crl | 13 + tests/certs/Server-localhost-firstSAN-sv.crt | 80 + tests/certs/Server-localhost-firstSAN-sv.csr | 11 + tests/certs/Server-localhost-firstSAN-sv.der | Bin 0 -> 862 bytes tests/certs/Server-localhost-firstSAN-sv.dhp | 0 tests/certs/Server-localhost-firstSAN-sv.key | 15 + tests/certs/Server-localhost-firstSAN-sv.pem | 120 + tests/certs/Server-localhost-firstSAN-sv.prm | 25 + .../Server-localhost-firstSAN-sv.pub.der | Bin 0 -> 162 bytes .../Server-localhost-firstSAN-sv.pub.pem | 6 + tests/certs/Server-localhost-lastSAN-sv.crl | 14 + tests/certs/Server-localhost-lastSAN-sv.crt | 80 + tests/certs/Server-localhost-lastSAN-sv.csr | 11 + tests/certs/Server-localhost-lastSAN-sv.der | Bin 0 -> 862 bytes tests/certs/Server-localhost-lastSAN-sv.dhp | 0 tests/certs/Server-localhost-lastSAN-sv.key | 15 + tests/certs/Server-localhost-lastSAN-sv.pem | 120 + tests/certs/Server-localhost-lastSAN-sv.prm | 25 + .../certs/Server-localhost-lastSAN-sv.pub.der | Bin 0 -> 162 bytes .../certs/Server-localhost-lastSAN-sv.pub.pem | 6 + tests/certs/Server-localhost-sv.crl | 21 + tests/certs/Server-localhost-sv.crt | 80 + tests/certs/Server-localhost-sv.csr | 11 + tests/certs/Server-localhost-sv.der | Bin 0 -> 835 bytes tests/certs/Server-localhost-sv.dhp | 0 tests/certs/Server-localhost-sv.key | 15 + tests/certs/Server-localhost-sv.pem | 120 + tests/certs/Server-localhost-sv.prm | 25 + tests/certs/Server-localhost-sv.pub.der | Bin 0 -> 162 bytes tests/certs/Server-localhost-sv.pub.pem | 6 + tests/certs/Server-localhost.nn-sv.crl | 21 + tests/certs/Server-localhost.nn-sv.crt | 80 + tests/certs/Server-localhost.nn-sv.csr | 11 + tests/certs/Server-localhost.nn-sv.der | Bin 0 -> 841 bytes tests/certs/Server-localhost.nn-sv.dhp | 0 tests/certs/Server-localhost.nn-sv.key | 15 + tests/certs/Server-localhost.nn-sv.pem | 120 + tests/certs/Server-localhost.nn-sv.prm | 25 + tests/certs/Server-localhost.nn-sv.pub.der | Bin 0 -> 162 bytes tests/certs/Server-localhost.nn-sv.pub.pem | 6 + tests/certs/Server-localhost0h-sv.crl | 22 + tests/certs/Server-localhost0h-sv.crt | 80 + tests/certs/Server-localhost0h-sv.csr | 11 + tests/certs/Server-localhost0h-sv.der | Bin 0 -> 837 bytes tests/certs/Server-localhost0h-sv.dhp | 0 tests/certs/Server-localhost0h-sv.key | 15 + tests/certs/Server-localhost0h-sv.pem | 121 + tests/certs/Server-localhost0h-sv.prm | 26 + tests/certs/Server-localhost0h-sv.pub.der | Bin 0 -> 162 bytes tests/certs/Server-localhost0h-sv.pub.pem | 6 + tests/certs/scripts/Makefile.am | 29 + tests/certs/scripts/genroot.sh | 66 + tests/certs/scripts/genserv.sh | 118 + tests/certs/srp-verifier-conf | 3 + tests/certs/srp-verifier-db | 2 + tests/convsrctest.pl | 255 + tests/curl_test_data.py | 61 + tests/data/.gitattributes | 1 + tests/data/.gitignore | 1 + tests/data/CMakeLists.txt | 7 + tests/data/DISABLED | 20 + tests/data/Makefile.am | 29 + tests/data/Makefile.inc | 203 + tests/data/test1 | 55 + tests/data/test10 | 67 + tests/data/test100 | 57 + tests/data/test1000 | 42 + tests/data/test1001 | 107 + tests/data/test1002 | 117 + tests/data/test1003 | 48 + tests/data/test1004 | 59 + tests/data/test1005 | 48 + tests/data/test1006 | 49 + tests/data/test1007 | 42 + tests/data/test1008 | 133 + tests/data/test1009 | 47 + tests/data/test101 | 58 + tests/data/test1010 | 58 + tests/data/test1011 | 76 + tests/data/test1012 | 79 + tests/data/test1013 | 37 + tests/data/test1014 | 37 + tests/data/test1015 | 55 + tests/data/test1016 | 39 + tests/data/test1017 | 40 + tests/data/test1018 | 39 + tests/data/test1019 | 42 + tests/data/test102 | 52 + tests/data/test1020 | 42 + tests/data/test1021 | 141 + tests/data/test1022 | 37 + tests/data/test1023 | 37 + tests/data/test1024 | 103 + tests/data/test1025 | 105 + tests/data/test1026 | 42 + tests/data/test1027 | 39 + tests/data/test1028 | 94 + tests/data/test1029 | 58 + tests/data/test103 | 54 + tests/data/test1030 | 110 + tests/data/test1031 | 76 + tests/data/test1032 | 56 + tests/data/test1033 | 60 + tests/data/test1034 | 55 + tests/data/test1035 | 52 + tests/data/test1036 | 61 + tests/data/test1037 | 54 + tests/data/test1038 | 53 + tests/data/test1039 | 53 + tests/data/test104 | 43 + tests/data/test1040 | 79 + tests/data/test1041 | 78 + tests/data/test1042 | 94 + tests/data/test1043 | 84 + tests/data/test1044 | 58 + tests/data/test1045 | 52 + tests/data/test1046 | 60 + tests/data/test1047 | 58 + tests/data/test1048 | 68 + tests/data/test1049 | 47 + tests/data/test105 | 53 + tests/data/test1050 | 66 + tests/data/test1051 | 118 + tests/data/test1052 | 111 + tests/data/test1053 | 127 + tests/data/test1054 | 80 + tests/data/test1055 | 100 + tests/data/test1056 | 81 + tests/data/test1057 | 52 + tests/data/test1058 | 53 + tests/data/test1059 | 58 + tests/data/test106 | 52 + tests/data/test1060 | 902 +++ tests/data/test1061 | 907 +++ tests/data/test1062 | 49 + tests/data/test1063 | 45 + tests/data/test1064 | 79 + tests/data/test1065 | 78 + tests/data/test1066 | 82 + tests/data/test1067 | 78 + tests/data/test1068 | 58 + tests/data/test1069 | 36 + tests/data/test107 | 51 + tests/data/test1070 | 65 + tests/data/test1071 | 114 + tests/data/test1072 | 78 + tests/data/test1073 | 72 + tests/data/test1074 | 76 + tests/data/test1075 | 94 + tests/data/test1076 | 79 + tests/data/test1077 | 75 + tests/data/test1078 | 96 + tests/data/test1079 | 76 + tests/data/test108 | 56 + tests/data/test1080 | 69 + tests/data/test1081 | 77 + tests/data/test1082 | 55 + tests/data/test1083 | 59 + tests/data/test1084 | 41 + tests/data/test1085 | 48 + tests/data/test1086 | 110 + tests/data/test1087 | 110 + tests/data/test1088 | 112 + tests/data/test1089 | 91 + tests/data/test109 | 48 + tests/data/test1090 | 98 + tests/data/test1091 | 46 + tests/data/test1092 | 56 + tests/data/test1093 | 47 + tests/data/test1094 | 53 + tests/data/test1095 | 84 + tests/data/test1096 | 50 + tests/data/test1097 | 80 + tests/data/test1098 | 73 + tests/data/test1099 | 51 + tests/data/test11 | 76 + tests/data/test110 | 52 + tests/data/test1100 | 118 + tests/data/test1101 | 54 + tests/data/test1102 | 51 + tests/data/test1103 | 48 + tests/data/test1104 | 85 + tests/data/test1105 | 65 + tests/data/test1106 | 57 + tests/data/test1107 | 53 + tests/data/test1108 | 45 + tests/data/test1109 | 46 + tests/data/test111 | 45 + tests/data/test1110 | 47 + tests/data/test1111 | 47 + tests/data/test1112 | 114 + tests/data/test1113 | 99 + tests/data/test1114 | 136 + tests/data/test1115 | 52 + tests/data/test1116 | 79 + tests/data/test1117 | 87 + tests/data/test1118 | 55 + tests/data/test1119 | 25 + tests/data/test112 | 49 + tests/data/test1120 | 44 + tests/data/test1121 | 47 + tests/data/test1122 | 70 + tests/data/test1123 | 201 + tests/data/test1124 | 69 + tests/data/test1125 | 70 + tests/data/test1126 | 52 + tests/data/test1127 | 61 + tests/data/test1128 | 85 + tests/data/test1129 | 97 + tests/data/test113 | 37 + tests/data/test1130 | 97 + tests/data/test1131 | 95 + tests/data/test1132 | 25 + tests/data/test1133 | 103 + tests/data/test1134 | 65 + tests/data/test1135 | 108 + tests/data/test1136 | 64 + tests/data/test1137 | 52 + tests/data/test1138 | 74 + tests/data/test1139 | 27 + tests/data/test114 | 38 + tests/data/test1140 | 26 + tests/data/test1141 | 70 + tests/data/test1142 | 64 + tests/data/test1143 | 45 + tests/data/test1144 | 69 + tests/data/test1145 | 40 + tests/data/test1146 | 45 + tests/data/test1147 | 64 + tests/data/test1148 | 66 + tests/data/test1149 | 64 + tests/data/test115 | 44 + tests/data/test1150 | 55 + tests/data/test1151 | 66 + tests/data/test1152 | 61 + tests/data/test1153 | 61 + tests/data/test1154 | 57 + tests/data/test1155 | 54 + tests/data/test1156 | 70 + tests/data/test116 | 55 + tests/data/test1160 | 49 + tests/data/test1161 | 54 + tests/data/test1162 | 52 + tests/data/test1163 | 52 + tests/data/test1164 | 52 + tests/data/test117 | 44 + tests/data/test1170 | 70 + tests/data/test1171 | 70 + tests/data/test118 | 48 + tests/data/test119 | 50 + tests/data/test12 | 56 + tests/data/test120 | 53 + tests/data/test1200 | 39 + tests/data/test1201 | 39 + tests/data/test1202 | 40 + tests/data/test1203 | 43 + tests/data/test1204 | 79 + tests/data/test1205 | 50 + tests/data/test1206 | 53 + tests/data/test1207 | 53 + tests/data/test1208 | 58 + tests/data/test1209 | 58 + tests/data/test121 | 51 + tests/data/test1210 | 63 + tests/data/test1211 | 53 + tests/data/test1212 | 51 + tests/data/test1213 | 53 + tests/data/test1214 | 53 + tests/data/test1215 | 106 + tests/data/test1216 | 63 + tests/data/test1217 | 57 + tests/data/test1218 | 61 + tests/data/test1219 | 49 + tests/data/test122 | 45 + tests/data/test1220 | 37 + tests/data/test1221 | 53 + tests/data/test1222 | 53 + tests/data/test1223 | 60 + tests/data/test1224 | 49 + tests/data/test1225 | 57 + tests/data/test1226 | 49 + tests/data/test1227 | 48 + tests/data/test1228 | 55 + tests/data/test1229 | 83 + tests/data/test123 | 40 + tests/data/test1230 | 78 + tests/data/test1231 | 61 + tests/data/test1232 | 65 + tests/data/test1233 | 46 + tests/data/test1234 | 33 + tests/data/test1235 | 95 + tests/data/test1236 | 33 + tests/data/test1237 | 47 + tests/data/test1238 | 52 + tests/data/test1239 | 68 + tests/data/test124 | 47 + tests/data/test1240 | 48 + tests/data/test1241 | 64 + tests/data/test1242 | 43 + tests/data/test1243 | 44 + tests/data/test1244 | 61 + tests/data/test1245 | 63 + tests/data/test1246 | 64 + tests/data/test1247 | 38 + tests/data/test1248 | 49 + tests/data/test1249 | 52 + tests/data/test125 | 41 + tests/data/test1250 | 53 + tests/data/test1251 | 54 + tests/data/test1252 | 52 + tests/data/test1253 | 53 + tests/data/test1254 | 53 + tests/data/test1255 | 53 + tests/data/test1256 | 54 + tests/data/test1257 | 54 + tests/data/test1258 | 54 + tests/data/test1259 | 47 + tests/data/test126 | 48 + tests/data/test1260 | 36 + tests/data/test1261 | 61 + tests/data/test1262 | 40 + tests/data/test1263 | 37 + tests/data/test1264 | 36 + tests/data/test1265 | 53 + tests/data/test127 | 46 + tests/data/test128 | 57 + tests/data/test1280 | 58 + tests/data/test1281 | 38 + tests/data/test1282 | 45 + tests/data/test1283 | 57 + tests/data/test1284 | 89 + tests/data/test1285 | 97 + tests/data/test1286 | 110 + tests/data/test1287 | 91 + tests/data/test1288 | 96 + tests/data/test1289 | 35 + tests/data/test129 | 52 + tests/data/test1290 | 48 + tests/data/test1291 | 51 + tests/data/test1292 | 50 + tests/data/test1298 | 56 + tests/data/test1299 | 55 + tests/data/test13 | 44 + tests/data/test130 | 64 + tests/data/test1300 | 26 + tests/data/test1301 | 26 + tests/data/test1302 | 26 + tests/data/test1303 | 26 + tests/data/test1304 | 30 + tests/data/test1305 | 30 + tests/data/test1306 | 30 + tests/data/test1307 | 27 + tests/data/test1308 | 31 + tests/data/test1309 | 1568 ++++ tests/data/test131 | 63 + tests/data/test1310 | 125 + tests/data/test1311 | 64 + tests/data/test1312 | 64 + tests/data/test1313 | 64 + tests/data/test1314 | 79 + tests/data/test1315 | 83 + tests/data/test1316 | 81 + tests/data/test1317 | 56 + tests/data/test1318 | 60 + tests/data/test1319 | 83 + tests/data/test132 | 62 + tests/data/test1320 | 73 + tests/data/test1321 | 79 + tests/data/test1322 | 57 + tests/data/test1323 | 32 + tests/data/test1324 | 56 + tests/data/test1325 | 80 + tests/data/test1326 | 48 + tests/data/test1327 | 47 + tests/data/test1328 | 71 + tests/data/test1329 | 30 + tests/data/test133 | 62 + tests/data/test1330 | 51 + tests/data/test1331 | 89 + tests/data/test1332 | 80 + tests/data/test1333 | 55 + tests/data/test1334 | 76 + tests/data/test1335 | 73 + tests/data/test1336 | 81 + tests/data/test1337 | 78 + tests/data/test1338 | 77 + tests/data/test1339 | 74 + tests/data/test134 | 62 + tests/data/test1340 | 80 + tests/data/test1341 | 77 + tests/data/test1342 | 83 + tests/data/test1343 | 80 + tests/data/test1344 | 89 + tests/data/test1345 | 86 + tests/data/test1346 | 73 + tests/data/test1347 | 78 + tests/data/test1348 | 61 + tests/data/test1349 | 83 + tests/data/test135 | 54 + tests/data/test1350 | 80 + tests/data/test1351 | 84 + tests/data/test1352 | 81 + tests/data/test1353 | 83 + tests/data/test1354 | 78 + tests/data/test1355 | 61 + tests/data/test1356 | 79 + tests/data/test1357 | 99 + tests/data/test1358 | 96 + tests/data/test1359 | 100 + tests/data/test136 | 42 + tests/data/test1360 | 97 + tests/data/test1361 | 99 + tests/data/test1362 | 96 + tests/data/test1363 | 79 + tests/data/test1364 | 71 + tests/data/test1365 | 68 + tests/data/test1366 | 73 + tests/data/test1367 | 70 + tests/data/test1368 | 72 + tests/data/test1369 | 69 + tests/data/test137 | 47 + tests/data/test1370 | 74 + tests/data/test1371 | 71 + tests/data/test1372 | 78 + tests/data/test1373 | 75 + tests/data/test1374 | 81 + tests/data/test1375 | 78 + tests/data/test1376 | 68 + tests/data/test1377 | 70 + tests/data/test1378 | 56 + tests/data/test1379 | 76 + tests/data/test138 | 49 + tests/data/test1380 | 73 + tests/data/test1381 | 77 + tests/data/test1382 | 74 + tests/data/test1383 | 76 + tests/data/test1384 | 73 + tests/data/test1385 | 56 + tests/data/test1386 | 71 + tests/data/test1387 | 91 + tests/data/test1388 | 88 + tests/data/test1389 | 92 + tests/data/test139 | 47 + tests/data/test1390 | 89 + tests/data/test1391 | 91 + tests/data/test1392 | 88 + tests/data/test1393 | 71 + tests/data/test1394 | 30 + tests/data/test1395 | 26 + tests/data/test1396 | 27 + tests/data/test1397 | 27 + tests/data/test1398 | 26 + tests/data/test1399 | 26 + tests/data/test14 | 44 + tests/data/test140 | 42 + tests/data/test1400 | 108 + tests/data/test1401 | 129 + tests/data/test1402 | 115 + tests/data/test1403 | 110 + tests/data/test1404 | 185 + tests/data/test1405 | 141 + tests/data/test1406 | 127 + tests/data/test1407 | 105 + tests/data/test1408 | 74 + tests/data/test1409 | 31 + tests/data/test141 | 52 + tests/data/test1410 | 31 + tests/data/test1411 | 60 + tests/data/test1412 | 118 + tests/data/test1413 | 73 + tests/data/test1414 | 57 + tests/data/test1415 | 75 + tests/data/test1416 | 63 + tests/data/test1417 | 79 + tests/data/test1418 | 108 + tests/data/test1419 | 69 + tests/data/test142 | 190 + tests/data/test1420 | 110 + tests/data/test1421 | 72 + tests/data/test1422 | 63 + tests/data/test1423 | 57 + tests/data/test1424 | 76 + tests/data/test1425 | Bin 0 -> 1726 bytes tests/data/test1426 | Bin 0 -> 1663 bytes tests/data/test1427 | 29 + tests/data/test1428 | 81 + tests/data/test1429 | 69 + tests/data/test143 | 44 + tests/data/test1430 | 53 + tests/data/test1431 | 53 + tests/data/test1432 | 54 + tests/data/test1433 | 57 + tests/data/test1434 | 90 + tests/data/test1435 | 46 + tests/data/test1436 | 85 + tests/data/test1437 | 84 + tests/data/test1438 | 58 + tests/data/test1439 | 58 + tests/data/test144 | 49 + tests/data/test1440 | 35 + tests/data/test1441 | 35 + tests/data/test1442 | 35 + tests/data/test1443 | 68 + tests/data/test1444 | 52 + tests/data/test1445 | 35 + tests/data/test1446 | 42 + tests/data/test1447 | 38 + tests/data/test1448 | 92 + tests/data/test1449 | 38 + tests/data/test145 | 51 + tests/data/test1450 | 34 + tests/data/test1451 | 36 + tests/data/test1452 | 41 + tests/data/test1453 | 38 + tests/data/test1454 | 38 + tests/data/test1455 | 59 + tests/data/test1456 | 59 + tests/data/test146 | 55 + tests/data/test147 | 55 + tests/data/test148 | 49 + tests/data/test149 | 53 + tests/data/test15 | 57 + tests/data/test150 | 103 + tests/data/test1500 | 44 + tests/data/test1501 | 53 + tests/data/test1502 | 58 + tests/data/test1503 | 58 + tests/data/test1504 | 58 + tests/data/test1505 | 58 + tests/data/test1506 | 96 + tests/data/test1507 | 51 + tests/data/test1508 | 31 + tests/data/test1509 | 88 + tests/data/test151 | 48 + tests/data/test1510 | 96 + tests/data/test1511 | 70 + tests/data/test1512 | 80 + tests/data/test1513 | 49 + tests/data/test1514 | 48 + tests/data/test1515 | 62 + tests/data/test1516 | 58 + tests/data/test1517 | 69 + tests/data/test152 | 52 + tests/data/test1520 | 63 + tests/data/test1521 | 30 + tests/data/test1525 | 74 + tests/data/test1526 | 76 + tests/data/test1527 | 76 + tests/data/test1528 | 60 + tests/data/test1529 | 43 + tests/data/test153 | 134 + tests/data/test1530 | 30 + tests/data/test1531 | Bin 0 -> 552 bytes tests/data/test1532 | 49 + tests/data/test1533 | 74 + tests/data/test1534 | 50 + tests/data/test1535 | 50 + tests/data/test1536 | 50 + tests/data/test1537 | 45 + tests/data/test1538 | 151 + tests/data/test154 | 109 + tests/data/test1540 | 64 + tests/data/test155 | 140 + tests/data/test1550 | 29 + tests/data/test1551 | 72 + tests/data/test1552 | 52 + tests/data/test1553 | 54 + tests/data/test1554 | 85 + tests/data/test1555 | 50 + tests/data/test1556 | 63 + tests/data/test1557 | 36 + tests/data/test156 | 60 + tests/data/test157 | 47 + tests/data/test158 | 56 + tests/data/test159 | 83 + tests/data/test1590 | 54 + tests/data/test16 | 52 + tests/data/test160 | 73 + tests/data/test1600 | 27 + tests/data/test1601 | 26 + tests/data/test1602 | 26 + tests/data/test1603 | 26 + tests/data/test1604 | 25 + tests/data/test1605 | 25 + tests/data/test1606 | 26 + tests/data/test1607 | 26 + tests/data/test1608 | 26 + tests/data/test1609 | 26 + tests/data/test161 | 51 + tests/data/test162 | 61 + tests/data/test163 | 79 + tests/data/test164 | 68 + tests/data/test165 | 67 + tests/data/test166 | 60 + tests/data/test167 | 80 + tests/data/test168 | 100 + tests/data/test169 | 129 + tests/data/test17 | 54 + tests/data/test170 | 52 + tests/data/test1700 | 101 + tests/data/test1701 | 83 + tests/data/test1702 | 78 + tests/data/test171 | 58 + tests/data/test172 | 56 + tests/data/test173 | 79 + tests/data/test174 | 52 + tests/data/test175 | 86 + tests/data/test176 | 88 + tests/data/test177 | 54 + tests/data/test178 | 57 + tests/data/test179 | 57 + tests/data/test18 | 91 + tests/data/test180 | 67 + tests/data/test1800 | 55 + tests/data/test1801 | 69 + tests/data/test181 | 68 + tests/data/test182 | 43 + tests/data/test183 | 56 + tests/data/test184 | 75 + tests/data/test185 | 75 + tests/data/test186 | 62 + tests/data/test187 | 77 + tests/data/test188 | 78 + tests/data/test189 | 76 + tests/data/test19 | 37 + tests/data/test190 | 44 + tests/data/test1900 | 61 + tests/data/test1901 | 63 + tests/data/test1902 | 62 + tests/data/test1903 | 62 + tests/data/test1904 | 79 + tests/data/test191 | 41 + tests/data/test192 | 59 + tests/data/test193 | 82 + tests/data/test194 | 73 + tests/data/test195 | 38 + tests/data/test196 | 41 + tests/data/test197 | 75 + tests/data/test198 | 70 + tests/data/test199 | 59 + tests/data/test2 | 53 + tests/data/test20 | 38 + tests/data/test200 | 41 + tests/data/test2000 | 73 + tests/data/test2001 | 109 + tests/data/test2002 | 128 + tests/data/test2003 | 168 + tests/data/test2004 | 78 + tests/data/test2005 | 93 + tests/data/test2006 | 112 + tests/data/test2007 | 113 + tests/data/test2008 | 105 + tests/data/test2009 | 106 + tests/data/test201 | 34 + tests/data/test2010 | 105 + tests/data/test2011 | 93 + tests/data/test2012 | 92 + tests/data/test2013 | 78 + tests/data/test2014 | 78 + tests/data/test2015 | 78 + tests/data/test2016 | 78 + tests/data/test2017 | 78 + tests/data/test2018 | 78 + tests/data/test2019 | 78 + tests/data/test202 | 37 + tests/data/test2020 | 78 + tests/data/test2021 | 78 + tests/data/test2022 | 78 + tests/data/test2023 | 162 + tests/data/test2024 | 176 + tests/data/test2025 | 272 + tests/data/test2026 | 220 + tests/data/test2027 | 248 + tests/data/test2028 | 316 + tests/data/test2029 | 240 + tests/data/test203 | 42 + tests/data/test2030 | 297 + tests/data/test2031 | 321 + tests/data/test2032 | 123 + tests/data/test2033 | 124 + tests/data/test2034 | 58 + tests/data/test2035 | 44 + tests/data/test2036 | 39 + tests/data/test2037 | 58 + tests/data/test2038 | 44 + tests/data/test2039 | 63 + tests/data/test204 | 40 + tests/data/test2040 | 69 + tests/data/test2041 | 58 + tests/data/test2042 | 44 + tests/data/test2043 | 33 + tests/data/test2044 | 33 + tests/data/test2045 | 54 + tests/data/test2046 | 98 + tests/data/test2047 | 101 + tests/data/test2048 | 40 + tests/data/test2049 | 64 + tests/data/test205 | 38 + tests/data/test2050 | 78 + tests/data/test2051 | 74 + tests/data/test2052 | 68 + tests/data/test2053 | 56 + tests/data/test2054 | 64 + tests/data/test2055 | 80 + tests/data/test2056 | 87 + tests/data/test2057 | 108 + tests/data/test2058 | 107 + tests/data/test2059 | 107 + tests/data/test206 | 108 + tests/data/test2060 | 107 + tests/data/test2061 | 84 + tests/data/test2062 | 84 + tests/data/test2063 | 84 + tests/data/test2064 | 84 + tests/data/test2065 | 84 + tests/data/test2066 | 84 + tests/data/test2067 | 89 + tests/data/test2068 | 89 + tests/data/test2069 | 89 + tests/data/test207 | 67 + tests/data/test2070 | 41 + tests/data/test2071 | 41 + tests/data/test2072 | 44 + tests/data/test2073 | 68 + tests/data/test2074 | 57 + tests/data/test2075 | 34 + tests/data/test208 | 75 + tests/data/test209 | 123 + tests/data/test21 | 33 + tests/data/test210 | 52 + tests/data/test211 | 54 + tests/data/test212 | 64 + tests/data/test213 | 126 + tests/data/test214 | 50 + tests/data/test215 | 58 + tests/data/test216 | 45 + tests/data/test217 | 60 + tests/data/test218 | 59 + tests/data/test219 | 37 + tests/data/test22 | 46 + tests/data/test220 | 71 + tests/data/test221 | 74 + tests/data/test222 | 202 + tests/data/test223 | 95 + tests/data/test224 | 107 + tests/data/test225 | 28 + tests/data/test226 | 29 + tests/data/test227 | 57 + tests/data/test228 | 52 + tests/data/test229 | 41 + tests/data/test23 | 33 + tests/data/test230 | 203 + tests/data/test231 | 38 + tests/data/test232 | 202 + tests/data/test233 | 94 + tests/data/test234 | 97 + tests/data/test235 | 48 + tests/data/test236 | 52 + tests/data/test237 | 44 + tests/data/test238 | 42 + tests/data/test239 | 102 + tests/data/test24 | 50 + tests/data/test240 | 58 + tests/data/test241 | 56 + tests/data/test242 | 54 + tests/data/test243 | 131 + tests/data/test244 | 54 + tests/data/test245 | 88 + tests/data/test246 | 98 + tests/data/test247 | 47 + tests/data/test248 | 56 + tests/data/test249 | 53 + tests/data/test25 | 116 + tests/data/test250 | 58 + tests/data/test251 | 60 + tests/data/test252 | 60 + tests/data/test253 | 63 + tests/data/test254 | 61 + tests/data/test255 | 64 + tests/data/test256 | 64 + tests/data/test257 | 112 + tests/data/test258 | 135 + tests/data/test259 | 133 + tests/data/test26 | 45 + tests/data/test260 | 55 + tests/data/test261 | 48 + tests/data/test262 | Bin 0 -> 1137 bytes tests/data/test263 | 54 + tests/data/test264 | 49 + tests/data/test265 | 127 + tests/data/test266 | 79 + tests/data/test267 | 111 + tests/data/test268 | 57 + tests/data/test269 | 53 + tests/data/test27 | 56 + tests/data/test270 | 50 + tests/data/test271 | 46 + tests/data/test272 | 40 + tests/data/test273 | 84 + tests/data/test274 | 52 + tests/data/test275 | 88 + tests/data/test276 | 76 + tests/data/test277 | 58 + tests/data/test278 | 49 + tests/data/test279 | 50 + tests/data/test28 | 75 + tests/data/test280 | 63 + tests/data/test281 | 65 + tests/data/test282 | 45 + tests/data/test283 | 39 + tests/data/test284 | 70 + tests/data/test285 | 47 + tests/data/test286 | 95 + tests/data/test287 | 53 + tests/data/test288 | 48 + tests/data/test289 | 30 + tests/data/test29 | 52 + tests/data/test290 | 43 + tests/data/test291 | 47 + tests/data/test292 | 56 + tests/data/test293 | 60 + tests/data/test294 | 64 + tests/data/test295 | 45 + tests/data/test296 | 48 + tests/data/test297 | 46 + tests/data/test298 | 45 + tests/data/test299 | 53 + tests/data/test3 | 60 + tests/data/test30 | 43 + tests/data/test300 | 52 + tests/data/test3000 | 57 + tests/data/test3001 | 57 + tests/data/test301 | 57 + tests/data/test302 | 51 + tests/data/test303 | 55 + tests/data/test304 | 72 + tests/data/test305 | 35 + tests/data/test306 | 65 + tests/data/test307 | 56 + tests/data/test308 | 35 + tests/data/test309 | 86 + tests/data/test31 | 137 + tests/data/test310 | 57 + tests/data/test311 | 43 + tests/data/test312 | 43 + tests/data/test313 | 39 + tests/data/test314 | 198 + tests/data/test315 | 91 + tests/data/test316 | 198 + tests/data/test317 | 94 + tests/data/test318 | 95 + tests/data/test319 | 57 + tests/data/test32 | 56 + tests/data/test320 | 96 + tests/data/test321 | 33 + tests/data/test322 | 33 + tests/data/test323 | 33 + tests/data/test324 | 33 + tests/data/test325 | 66 + tests/data/test326 | 66 + tests/data/test33 | 64 + tests/data/test34 | 66 + tests/data/test340 | 40 + tests/data/test35 | Bin 0 -> 810 bytes tests/data/test350 | 57 + tests/data/test351 | 56 + tests/data/test352 | 57 + tests/data/test353 | 56 + tests/data/test354 | 50 + tests/data/test36 | 66 + tests/data/test37 | 47 + tests/data/test38 | 61 + tests/data/test39 | 109 + tests/data/test393 | 60 + tests/data/test394 | 59 + tests/data/test395 | 55 + tests/data/test4 | 62 + tests/data/test40 | 74 + tests/data/test400 | 62 + tests/data/test401 | 57 + tests/data/test402 | 36 + tests/data/test403 | 65 + tests/data/test404 | 32 + tests/data/test405 | 35 + tests/data/test406 | 67 + tests/data/test407 | 60 + tests/data/test408 | 62 + tests/data/test409 | 57 + tests/data/test41 | 32 + tests/data/test42 | 74 + tests/data/test43 | 79 + tests/data/test44 | 72 + tests/data/test45 | 76 + tests/data/test46 | 89 + tests/data/test47 | 49 + tests/data/test48 | 54 + tests/data/test49 | 74 + tests/data/test5 | 50 + tests/data/test50 | 74 + tests/data/test500 | 58 + tests/data/test501 | 40 + tests/data/test502 | 47 + tests/data/test503 | 87 + tests/data/test504 | 44 + tests/data/test505 | 66 + tests/data/test506 | 249 + tests/data/test507 | 37 + tests/data/test508 | 58 + tests/data/test509 | 44 + tests/data/test51 | 74 + tests/data/test510 | 65 + tests/data/test511 | 50 + tests/data/test512 | 53 + tests/data/test513 | 49 + tests/data/test514 | 57 + tests/data/test515 | 54 + tests/data/test516 | 54 + tests/data/test517 | 45 + tests/data/test518 | 67 + tests/data/test519 | 78 + tests/data/test52 | 74 + tests/data/test520 | 53 + tests/data/test521 | 60 + tests/data/test522 | 60 + tests/data/test523 | 64 + tests/data/test524 | 46 + tests/data/test525 | 59 + tests/data/test526 | 63 + tests/data/test527 | 63 + tests/data/test528 | 65 + tests/data/test529 | 59 + tests/data/test53 | 54 + tests/data/test530 | 83 + tests/data/test531 | 59 + tests/data/test532 | 63 + tests/data/test533 | 55 + tests/data/test534 | 53 + tests/data/test535 | 69 + tests/data/test536 | 74 + tests/data/test537 | 64 + tests/data/test538 | 45 + tests/data/test539 | 71 + tests/data/test54 | 45 + tests/data/test540 | 110 + tests/data/test541 | 57 + tests/data/test542 | 57 + tests/data/test543 | 35 + tests/data/test544 | 56 + tests/data/test545 | Bin 0 -> 798 bytes tests/data/test546 | 70 + tests/data/test547 | 135 + tests/data/test548 | 135 + tests/data/test549 | 65 + tests/data/test55 | 66 + tests/data/test550 | 65 + tests/data/test551 | 100 + tests/data/test552 | Bin 0 -> 142985 bytes tests/data/test553 | 65 + tests/data/test554 | 132 + tests/data/test555 | 140 + tests/data/test556 | 50 + tests/data/test557 | 47 + tests/data/test558 | 57 + tests/data/test559 | 50 + tests/data/test56 | 61 + tests/data/test560 | 56 + tests/data/test561 | 66 + tests/data/test562 | 53 + tests/data/test563 | 57 + tests/data/test564 | 65 + tests/data/test565 | 109 + tests/data/test566 | 57 + tests/data/test567 | 50 + tests/data/test568 | 117 + tests/data/test569 | 111 + tests/data/test57 | 48 + tests/data/test570 | 77 + tests/data/test571 | 108 + tests/data/test572 | 122 + tests/data/test573 | 58 + tests/data/test574 | 98 + tests/data/test575 | 121 + tests/data/test576 | 192 + tests/data/test577 | 55 + tests/data/test578 | 52 + tests/data/test579 | 87 + tests/data/test58 | 51 + tests/data/test580 | 58 + tests/data/test581 | 58 + tests/data/test582 | 49 + tests/data/test583 | 45 + tests/data/test584 | 102 + tests/data/test585 | 69 + tests/data/test586 | 59 + tests/data/test587 | 58 + tests/data/test588 | 69 + tests/data/test589 | 55 + tests/data/test59 | 47 + tests/data/test590 | 125 + tests/data/test591 | 73 + tests/data/test592 | 74 + tests/data/test593 | 72 + tests/data/test594 | 72 + tests/data/test595 | 57 + tests/data/test596 | 60 + tests/data/test597 | 37 + tests/data/test598 | 80 + tests/data/test599 | 86 + tests/data/test6 | 49 + tests/data/test60 | 58 + tests/data/test600 | 42 + tests/data/test601 | 42 + tests/data/test602 | 43 + tests/data/test603 | 43 + tests/data/test604 | 33 + tests/data/test605 | 33 + tests/data/test606 | 33 + tests/data/test607 | 33 + tests/data/test608 | 49 + tests/data/test609 | 45 + tests/data/test61 | 73 + tests/data/test610 | 47 + tests/data/test611 | 47 + tests/data/test612 | 47 + tests/data/test613 | 48 + tests/data/test614 | 49 + tests/data/test615 | 44 + tests/data/test616 | 39 + tests/data/test617 | 39 + tests/data/test618 | 39 + tests/data/test619 | 39 + tests/data/test62 | 65 + tests/data/test620 | 38 + tests/data/test621 | 38 + tests/data/test622 | 43 + tests/data/test623 | 44 + tests/data/test624 | 47 + tests/data/test625 | 47 + tests/data/test626 | 42 + tests/data/test627 | 46 + tests/data/test628 | 33 + tests/data/test629 | 33 + tests/data/test63 | 52 + tests/data/test630 | 34 + tests/data/test631 | 34 + tests/data/test632 | 34 + tests/data/test633 | 42 + tests/data/test634 | 43 + tests/data/test635 | 42 + tests/data/test636 | 43 + tests/data/test637 | 44 + tests/data/test638 | 49 + tests/data/test639 | 49 + tests/data/test64 | 84 + tests/data/test640 | 41 + tests/data/test641 | 41 + tests/data/test642 | 42 + tests/data/test643 | 131 + tests/data/test644 | 59 + tests/data/test645 | 141 + tests/data/test646 | 98 + tests/data/test647 | 79 + tests/data/test648 | 75 + tests/data/test649 | 72 + tests/data/test65 | 84 + tests/data/test650 | 123 + tests/data/test651 | 73 + tests/data/test652 | 358 + tests/data/test653 | 93 + tests/data/test654 | 109 + tests/data/test655 | 50 + tests/data/test66 | 41 + tests/data/test67 | 102 + tests/data/test68 | 101 + tests/data/test69 | 123 + tests/data/test7 | 62 + tests/data/test70 | 88 + tests/data/test700 | 57 + tests/data/test701 | 57 + tests/data/test702 | 39 + tests/data/test703 | 39 + tests/data/test704 | 36 + tests/data/test705 | 36 + tests/data/test706 | 59 + tests/data/test707 | 59 + tests/data/test708 | 60 + tests/data/test709 | 60 + tests/data/test71 | 78 + tests/data/test710 | 57 + tests/data/test711 | 52 + tests/data/test712 | 48 + tests/data/test713 | 49 + tests/data/test714 | 67 + tests/data/test715 | 69 + tests/data/test72 | 87 + tests/data/test73 | 55 + tests/data/test74 | 75 + tests/data/test75 | 50 + tests/data/test76 | 39 + tests/data/test77 | 56 + tests/data/test78 | 68 + tests/data/test79 | 55 + tests/data/test8 | 69 + tests/data/test80 | 83 + tests/data/test800 | 49 + tests/data/test801 | 46 + tests/data/test802 | 47 + tests/data/test803 | 45 + tests/data/test804 | 47 + tests/data/test805 | 62 + tests/data/test806 | 44 + tests/data/test807 | 45 + tests/data/test808 | 49 + tests/data/test809 | 43 + tests/data/test81 | 103 + tests/data/test810 | 43 + tests/data/test811 | 40 + tests/data/test812 | 40 + tests/data/test813 | 40 + tests/data/test814 | 41 + tests/data/test815 | 46 + tests/data/test816 | 49 + tests/data/test817 | 40 + tests/data/test818 | 46 + tests/data/test819 | 56 + tests/data/test82 | 56 + tests/data/test820 | 57 + tests/data/test821 | 59 + tests/data/test822 | 71 + tests/data/test823 | 63 + tests/data/test824 | 56 + tests/data/test825 | 56 + tests/data/test826 | 57 + tests/data/test827 | 71 + tests/data/test828 | 56 + tests/data/test829 | 29 + tests/data/test83 | 79 + tests/data/test830 | 56 + tests/data/test831 | 67 + tests/data/test832 | 58 + tests/data/test833 | 65 + tests/data/test834 | 76 + tests/data/test835 | 67 + tests/data/test836 | 59 + tests/data/test837 | 56 + tests/data/test838 | 56 + tests/data/test839 | 56 + tests/data/test84 | 54 + tests/data/test840 | 56 + tests/data/test841 | 51 + tests/data/test842 | 62 + tests/data/test843 | 62 + tests/data/test844 | 59 + tests/data/test845 | 59 + tests/data/test846 | 50 + tests/data/test85 | 58 + tests/data/test850 | 49 + tests/data/test851 | 44 + tests/data/test852 | 47 + tests/data/test853 | 52 + tests/data/test854 | 45 + tests/data/test855 | 47 + tests/data/test856 | 48 + tests/data/test857 | 60 + tests/data/test858 | 41 + tests/data/test859 | 41 + tests/data/test86 | 97 + tests/data/test860 | 41 + tests/data/test861 | 52 + tests/data/test862 | 50 + tests/data/test863 | 41 + tests/data/test864 | 54 + tests/data/test865 | 57 + tests/data/test866 | 58 + tests/data/test867 | 60 + tests/data/test868 | 72 + tests/data/test869 | 64 + tests/data/test87 | 61 + tests/data/test870 | 57 + tests/data/test871 | 56 + tests/data/test872 | 57 + tests/data/test873 | 71 + tests/data/test874 | 56 + tests/data/test875 | 29 + tests/data/test876 | 57 + tests/data/test877 | 68 + tests/data/test878 | 59 + tests/data/test879 | 66 + tests/data/test88 | 101 + tests/data/test880 | 77 + tests/data/test881 | 68 + tests/data/test882 | 58 + tests/data/test883 | 57 + tests/data/test884 | 57 + tests/data/test885 | 56 + tests/data/test886 | 56 + tests/data/test887 | 63 + tests/data/test888 | 62 + tests/data/test889 | 61 + tests/data/test89 | 147 + tests/data/test890 | 60 + tests/data/test891 | 47 + tests/data/test9 | 72 + tests/data/test90 | 193 + tests/data/test900 | 51 + tests/data/test901 | 63 + tests/data/test902 | 57 + tests/data/test903 | 56 + tests/data/test904 | 57 + tests/data/test905 | 59 + tests/data/test906 | 71 + tests/data/test907 | 63 + tests/data/test908 | 56 + tests/data/test909 | 51 + tests/data/test91 | 124 + tests/data/test910 | 51 + tests/data/test911 | 46 + tests/data/test912 | 55 + tests/data/test913 | 50 + tests/data/test914 | 46 + tests/data/test915 | 51 + tests/data/test916 | 47 + tests/data/test917 | 55 + tests/data/test918 | 48 + tests/data/test919 | 55 + tests/data/test92 | 69 + tests/data/test920 | 56 + tests/data/test921 | 70 + tests/data/test922 | 55 + tests/data/test923 | 40 + tests/data/test924 | 43 + tests/data/test925 | 40 + tests/data/test926 | 44 + tests/data/test927 | 43 + tests/data/test928 | 41 + tests/data/test929 | 38 + tests/data/test93 | 50 + tests/data/test930 | 38 + tests/data/test931 | 29 + tests/data/test932 | 56 + tests/data/test933 | 67 + tests/data/test934 | 58 + tests/data/test935 | 65 + tests/data/test936 | 76 + tests/data/test937 | 67 + tests/data/test938 | 65 + tests/data/test939 | 50 + tests/data/test94 | 58 + tests/data/test940 | 45 + tests/data/test941 | 66 + tests/data/test942 | 56 + tests/data/test943 | 56 + tests/data/test944 | 55 + tests/data/test945 | 55 + tests/data/test946 | 62 + tests/data/test947 | 61 + tests/data/test948 | 63 + tests/data/test949 | 62 + tests/data/test95 | 81 + tests/data/test950 | 43 + tests/data/test951 | 45 + tests/data/test952 | 45 + tests/data/test96 | 46 + tests/data/test97 | 52 + tests/data/test98 | 55 + tests/data/test99 | 69 + tests/dictserver.py | 159 + tests/directories.pm | 287 + tests/extern-scan.pl | 62 + tests/ftp.pm | 326 + tests/ftpserver.pl | 3239 ++++++++ tests/fuzz/README | 8 + tests/fuzz/download_fuzzer.sh | 8 + tests/getpart.pm | 294 + tests/http2-server.pl | 83 + tests/http_pipe.py | 441 ++ tests/httpserver.pl | 139 + tests/keywords.pl | 153 + tests/libtest/.gitignore | 6 + tests/libtest/CMakeLists.txt | 133 + tests/libtest/Makefile.am | 135 + tests/libtest/Makefile.inc | 506 ++ tests/libtest/chkhostname.c | 47 + tests/libtest/first.c | 183 + tests/libtest/lib1156.c | 162 + tests/libtest/lib1500.c | 90 + tests/libtest/lib1501.c | 111 + tests/libtest/lib1502.c | 154 + tests/libtest/lib1506.c | 137 + tests/libtest/lib1507.c | 151 + tests/libtest/lib1508.c | 49 + tests/libtest/lib1509.c | 97 + tests/libtest/lib1510.c | 99 + tests/libtest/lib1511.c | 75 + tests/libtest/lib1512.c | 91 + tests/libtest/lib1513.c | 74 + tests/libtest/lib1514.c | 80 + tests/libtest/lib1515.c | 154 + tests/libtest/lib1517.c | 116 + tests/libtest/lib1520.c | 115 + tests/libtest/lib1525.c | 98 + tests/libtest/lib1526.c | 104 + tests/libtest/lib1527.c | 100 + tests/libtest/lib1528.c | 73 + tests/libtest/lib1529.c | 60 + tests/libtest/lib1530.c | 68 + tests/libtest/lib1531.c | 149 + tests/libtest/lib1532.c | 80 + tests/libtest/lib1533.c | 200 + tests/libtest/lib1534.c | 129 + tests/libtest/lib1535.c | 128 + tests/libtest/lib1536.c | 129 + tests/libtest/lib1537.c | 89 + tests/libtest/lib1538.c | 52 + tests/libtest/lib1540.c | 121 + tests/libtest/lib1550.c | 46 + tests/libtest/lib1551.c | 47 + tests/libtest/lib1552.c | 93 + tests/libtest/lib1553.c | 109 + tests/libtest/lib1554.c | 90 + tests/libtest/lib1555.c | 77 + tests/libtest/lib1556.c | 78 + tests/libtest/lib1557.c | 62 + tests/libtest/lib1900.c | 248 + tests/libtest/lib500.c | 157 + tests/libtest/lib501.c | 59 + tests/libtest/lib502.c | 92 + tests/libtest/lib503.c | 102 + tests/libtest/lib504.c | 114 + tests/libtest/lib505.c | 150 + tests/libtest/lib506.c | 380 + tests/libtest/lib507.c | 100 + tests/libtest/lib508.c | 108 + tests/libtest/lib509.c | 147 + tests/libtest/lib510.c | 135 + tests/libtest/lib511.c | 56 + tests/libtest/lib512.c | 75 + tests/libtest/lib513.c | 83 + tests/libtest/lib514.c | 79 + tests/libtest/lib515.c | 60 + tests/libtest/lib516.c | 59 + tests/libtest/lib517.c | 164 + tests/libtest/lib518.c | 521 ++ tests/libtest/lib519.c | 63 + tests/libtest/lib520.c | 55 + tests/libtest/lib521.c | 57 + tests/libtest/lib523.c | 58 + tests/libtest/lib524.c | 56 + tests/libtest/lib525.c | 162 + tests/libtest/lib526.c | 184 + tests/libtest/lib530.c | 122 + tests/libtest/lib533.c | 112 + tests/libtest/lib536.c | 142 + tests/libtest/lib537.c | 523 ++ tests/libtest/lib539.c | 91 + tests/libtest/lib540.c | 246 + tests/libtest/lib541.c | 115 + tests/libtest/lib542.c | 73 + tests/libtest/lib543.c | 62 + tests/libtest/lib544.c | 95 + tests/libtest/lib547.c | 131 + tests/libtest/lib549.c | 66 + tests/libtest/lib552.c | 224 + tests/libtest/lib553.c | 115 + tests/libtest/lib554.c | 225 + tests/libtest/lib555.c | 164 + tests/libtest/lib556.c | 109 + tests/libtest/lib557.c | 1698 ++++ tests/libtest/lib558.c | 53 + tests/libtest/lib559.c | 56 + tests/libtest/lib560.c | 113 + tests/libtest/lib562.c | 74 + tests/libtest/lib564.c | 93 + tests/libtest/lib566.c | 68 + tests/libtest/lib567.c | 70 + tests/libtest/lib568.c | 178 + tests/libtest/lib569.c | 128 + tests/libtest/lib570.c | 116 + tests/libtest/lib571.c | 215 + tests/libtest/lib572.c | 184 + tests/libtest/lib573.c | 114 + tests/libtest/lib574.c | 71 + tests/libtest/lib575.c | 114 + tests/libtest/lib576.c | 125 + tests/libtest/lib578.c | 105 + tests/libtest/lib579.c | 161 + tests/libtest/lib582.c | 357 + tests/libtest/lib583.c | 84 + tests/libtest/lib586.c | 247 + tests/libtest/lib589.c | 59 + tests/libtest/lib590.c | 72 + tests/libtest/lib591.c | 145 + tests/libtest/lib597.c | 146 + tests/libtest/lib598.c | 73 + tests/libtest/lib599.c | 97 + tests/libtest/lib643.c | 297 + tests/libtest/lib650.c | 211 + tests/libtest/lib651.c | 94 + tests/libtest/lib652.c | 128 + tests/libtest/lib653.c | 63 + tests/libtest/lib654.c | 174 + tests/libtest/lib655.c | 112 + tests/libtest/libauthretry.c | 148 + tests/libtest/libntlmconnect.c | 229 + tests/libtest/mk-lib1521.pl | 310 + tests/libtest/notexists.pl | 15 + tests/libtest/sethostname.c | 41 + tests/libtest/sethostname.h | 41 + tests/libtest/stub_gssapi.c | 445 ++ tests/libtest/stub_gssapi.h | 183 + tests/libtest/test.h | 434 + tests/libtest/test1013.pl | 51 + tests/libtest/test1022.pl | 54 + tests/libtest/test307.pl | 19 + tests/libtest/test610.pl | 33 + tests/libtest/test613.pl | 109 + tests/libtest/test75.pl | 13 + tests/libtest/testtrace.c | 145 + tests/libtest/testtrace.h | 37 + tests/libtest/testutil.c | 130 + tests/libtest/testutil.h | 45 + tests/manpage-scan.pl | 289 + tests/mem-include-scan.pl | 96 + tests/memanalyze.pl | 425 + tests/negtelnetserver.py | 349 + tests/nroff-scan.pl | 104 + tests/pathhelp.pm | 761 ++ .../python_dependencies/impacket/__init__.py | 25 + tests/python_dependencies/impacket/nmb.py | 980 +++ .../python_dependencies/impacket/nt_errors.py | 3586 +++++++++ tests/python_dependencies/impacket/ntlm.py | 971 +++ tests/python_dependencies/impacket/smb.py | 4099 ++++++++++ tests/python_dependencies/impacket/smb3.py | 1629 ++++ .../impacket/smb3structs.py | 1363 ++++ .../python_dependencies/impacket/smbserver.py | 4168 ++++++++++ tests/python_dependencies/impacket/spnego.py | 372 + .../python_dependencies/impacket/structure.py | 743 ++ tests/python_dependencies/impacket/uuid.py | 68 + tests/python_dependencies/impacket/version.py | 12 + tests/rtspserver.pl | 109 + tests/runtests.1 | 117 + tests/runtests.pl | 5906 ++++++++++++++ tests/secureserver.pl | 356 + tests/server/.gitignore | 7 + tests/server/CMakeLists.txt | 60 + tests/server/Makefile.am | 65 + tests/server/Makefile.inc | 70 + tests/server/base64.pl | 9 + tests/server/fake_ntlm.c | 285 + tests/server/getpart.c | 482 ++ tests/server/getpart.h | 34 + tests/server/resolve.c | 156 + tests/server/rtspd.c | 1484 ++++ tests/server/server_setup.h | 29 + tests/server/server_sockaddr.h | 41 + tests/server/sockfilt.c | 1565 ++++ tests/server/sws.c | 2416 ++++++ tests/server/testpart.c | 50 + tests/server/tftp.h | 61 + tests/server/tftpd.c | 1432 ++++ tests/server/util.c | 499 ++ tests/server/util.h | 69 + tests/serverhelp.pm | 247 + tests/smbserver.py | 377 + tests/sshhelp.pm | 454 ++ tests/sshserver.pl | 1080 +++ tests/stunnel.pem | 143 + tests/symbol-scan.pl | 176 + tests/testcurl.1 | 124 + tests/testcurl.pl | 814 ++ tests/tftpserver.pl | 110 + tests/unit/.gitignore | 1 + tests/unit/CMakeLists.txt | 54 + tests/unit/Makefile.am | 74 + tests/unit/Makefile.inc | 97 + tests/unit/README | 70 + tests/unit/curlcheck.h | 102 + tests/unit/unit1300.c | 270 + tests/unit/unit1301.c | 54 + tests/unit/unit1302.c | 165 + tests/unit/unit1303.c | 149 + tests/unit/unit1304.c | 189 + tests/unit/unit1305.c | 139 + tests/unit/unit1307.c | 310 + tests/unit/unit1308.c | 95 + tests/unit/unit1309.c | 142 + tests/unit/unit1323.c | 66 + tests/unit/unit1330.c | 41 + tests/unit/unit1394.c | 126 + tests/unit/unit1395.c | 94 + tests/unit/unit1396.c | 115 + tests/unit/unit1397.c | 79 + tests/unit/unit1398.c | 91 + tests/unit/unit1399.c | 117 + tests/unit/unit1600.c | 71 + tests/unit/unit1601.c | 54 + tests/unit/unit1602.c | 78 + tests/unit/unit1603.c | 150 + tests/unit/unit1604.c | 353 + tests/unit/unit1605.c | 55 + tests/unit/unit1606.c | 89 + tests/unit/unit1607.c | 221 + tests/unit/unit1608.c | 70 + tests/unit/unit1609.c | 214 + tests/valgrind.pm | 34 + tests/valgrind.supp | 110 + winbuild/.gitignore | 2 + winbuild/BUILD.WINDOWS.txt | 123 + winbuild/Makefile.vc | 280 + winbuild/MakefileBuild.vc | 626 ++ winbuild/gen_resp_file.bat | 8 + 2984 files changed, 474566 insertions(+) create mode 100644 .dir-locals.el create mode 100644 .gitattributes create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/ISSUE_TEMPLATE create mode 100644 .github/lock.yml create mode 100644 .github/stale.yml create mode 100644 .gitignore create mode 100644 .lgtm.yml create mode 100644 .mailmap create mode 100644 .travis-iconv-env.sh create mode 100644 .travis.yml create mode 100644 CHANGES create mode 100644 CMake/CMakeConfigurableFile.in create mode 100644 CMake/CurlSymbolHiding.cmake create mode 100644 CMake/CurlTests.c create mode 100644 CMake/FindBrotli.cmake create mode 100644 CMake/FindCARES.cmake create mode 100644 CMake/FindGSS.cmake create mode 100644 CMake/FindLibSSH2.cmake create mode 100644 CMake/FindMbedTLS.cmake create mode 100644 CMake/FindNGHTTP2.cmake create mode 100644 CMake/Macros.cmake create mode 100644 CMake/OtherTests.cmake create mode 100644 CMake/Platforms/WindowsCache.cmake create mode 100644 CMake/Utilities.cmake create mode 100644 CMake/cmake_uninstall.cmake.in create mode 100644 CMake/curl-config.cmake create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 GIT-INFO create mode 100755 MacOSX-Framework create mode 100644 Makefile.am create mode 100644 Makefile.dist create mode 100644 README create mode 100644 README.md create mode 100644 RELEASE-NOTES create mode 100644 acinclude.m4 create mode 100644 appveyor.yml create mode 100755 buildconf create mode 100644 buildconf.bat create mode 100755 configure.ac create mode 100644 curl-config.in create mode 100644 docs/.gitignore create mode 100644 docs/BINDINGS.md create mode 100644 docs/BUGS create mode 100644 docs/CHECKSRC.md create mode 100644 docs/CIPHERS.md create mode 100644 docs/CMakeLists.txt create mode 100644 docs/CODE_OF_CONDUCT.md create mode 100644 docs/CODE_STYLE.md create mode 100644 docs/CONTRIBUTE.md create mode 100644 docs/DEPRECATE.md create mode 100644 docs/FAQ create mode 100644 docs/FEATURES create mode 100644 docs/GOVERNANCE.md create mode 100644 docs/HELP-US.md create mode 100644 docs/HISTORY.md create mode 100644 docs/HTTP-COOKIES.md create mode 100644 docs/HTTP2.md create mode 100644 docs/INSTALL create mode 100644 docs/INSTALL.cmake create mode 100644 docs/INSTALL.md create mode 100644 docs/INTERNALS.md create mode 100644 docs/KNOWN_BUGS create mode 100644 docs/LICENSE-MIXING.md create mode 100644 docs/MAIL-ETIQUETTE create mode 100644 docs/MANUAL create mode 100644 docs/Makefile.am create mode 100644 docs/README.cmake create mode 100644 docs/README.md create mode 100644 docs/README.netware create mode 100644 docs/README.win32 create mode 100644 docs/RELEASE-PROCEDURE.md create mode 100644 docs/RESOURCES create mode 100644 docs/ROADMAP.md create mode 100644 docs/SECURITY-PROCESS.md create mode 100644 docs/SSL-PROBLEMS.md create mode 100644 docs/SSLCERTS.md create mode 100644 docs/THANKS create mode 100644 docs/THANKS-filter create mode 100644 docs/TODO create mode 100644 docs/TheArtOfHttpScripting create mode 100644 docs/VERSIONS create mode 100644 docs/cmdline-opts/CMakeLists.txt create mode 100644 docs/cmdline-opts/MANPAGE.md create mode 100644 docs/cmdline-opts/Makefile.am create mode 100644 docs/cmdline-opts/Makefile.inc create mode 100644 docs/cmdline-opts/abstract-unix-socket.d create mode 100644 docs/cmdline-opts/anyauth.d create mode 100644 docs/cmdline-opts/append.d create mode 100644 docs/cmdline-opts/basic.d create mode 100644 docs/cmdline-opts/cacert.d create mode 100644 docs/cmdline-opts/capath.d create mode 100644 docs/cmdline-opts/cert-status.d create mode 100644 docs/cmdline-opts/cert-type.d create mode 100644 docs/cmdline-opts/cert.d create mode 100644 docs/cmdline-opts/ciphers.d create mode 100644 docs/cmdline-opts/compressed-ssh.d create mode 100644 docs/cmdline-opts/compressed.d create mode 100644 docs/cmdline-opts/config.d create mode 100644 docs/cmdline-opts/connect-timeout.d create mode 100644 docs/cmdline-opts/connect-to.d create mode 100644 docs/cmdline-opts/continue-at.d create mode 100644 docs/cmdline-opts/cookie-jar.d create mode 100644 docs/cmdline-opts/cookie.d create mode 100644 docs/cmdline-opts/create-dirs.d create mode 100644 docs/cmdline-opts/crlf.d create mode 100644 docs/cmdline-opts/crlfile.d create mode 100644 docs/cmdline-opts/data-ascii.d create mode 100644 docs/cmdline-opts/data-binary.d create mode 100644 docs/cmdline-opts/data-raw.d create mode 100644 docs/cmdline-opts/data-urlencode.d create mode 100644 docs/cmdline-opts/data.d create mode 100644 docs/cmdline-opts/delegation.d create mode 100644 docs/cmdline-opts/digest.d create mode 100644 docs/cmdline-opts/disable-eprt.d create mode 100644 docs/cmdline-opts/disable-epsv.d create mode 100644 docs/cmdline-opts/disable.d create mode 100644 docs/cmdline-opts/disallow-username-in-url.d create mode 100644 docs/cmdline-opts/dns-interface.d create mode 100644 docs/cmdline-opts/dns-ipv4-addr.d create mode 100644 docs/cmdline-opts/dns-ipv6-addr.d create mode 100644 docs/cmdline-opts/dns-servers.d create mode 100644 docs/cmdline-opts/dump-header.d create mode 100644 docs/cmdline-opts/egd-file.d create mode 100644 docs/cmdline-opts/engine.d create mode 100644 docs/cmdline-opts/expect100-timeout.d create mode 100644 docs/cmdline-opts/fail-early.d create mode 100644 docs/cmdline-opts/fail.d create mode 100644 docs/cmdline-opts/false-start.d create mode 100644 docs/cmdline-opts/form-string.d create mode 100644 docs/cmdline-opts/form.d create mode 100644 docs/cmdline-opts/ftp-account.d create mode 100644 docs/cmdline-opts/ftp-alternative-to-user.d create mode 100644 docs/cmdline-opts/ftp-create-dirs.d create mode 100644 docs/cmdline-opts/ftp-method.d create mode 100644 docs/cmdline-opts/ftp-pasv.d create mode 100644 docs/cmdline-opts/ftp-port.d create mode 100644 docs/cmdline-opts/ftp-pret.d create mode 100644 docs/cmdline-opts/ftp-skip-pasv-ip.d create mode 100644 docs/cmdline-opts/ftp-ssl-ccc-mode.d create mode 100644 docs/cmdline-opts/ftp-ssl-ccc.d create mode 100644 docs/cmdline-opts/ftp-ssl-control.d create mode 100755 docs/cmdline-opts/gen.pl create mode 100644 docs/cmdline-opts/get.d create mode 100644 docs/cmdline-opts/globoff.d create mode 100644 docs/cmdline-opts/happy-eyeballs-timeout-ms.d create mode 100644 docs/cmdline-opts/haproxy-protocol.d create mode 100644 docs/cmdline-opts/head.d create mode 100644 docs/cmdline-opts/header.d create mode 100644 docs/cmdline-opts/help.d create mode 100644 docs/cmdline-opts/hostpubmd5.d create mode 100644 docs/cmdline-opts/http1.0.d create mode 100644 docs/cmdline-opts/http1.1.d create mode 100644 docs/cmdline-opts/http2-prior-knowledge.d create mode 100644 docs/cmdline-opts/http2.d create mode 100644 docs/cmdline-opts/ignore-content-length.d create mode 100644 docs/cmdline-opts/include.d create mode 100644 docs/cmdline-opts/insecure.d create mode 100644 docs/cmdline-opts/interface.d create mode 100644 docs/cmdline-opts/ipv4.d create mode 100644 docs/cmdline-opts/ipv6.d create mode 100644 docs/cmdline-opts/junk-session-cookies.d create mode 100644 docs/cmdline-opts/keepalive-time.d create mode 100644 docs/cmdline-opts/key-type.d create mode 100644 docs/cmdline-opts/key.d create mode 100644 docs/cmdline-opts/krb.d create mode 100644 docs/cmdline-opts/libcurl.d create mode 100644 docs/cmdline-opts/limit-rate.d create mode 100644 docs/cmdline-opts/list-only.d create mode 100644 docs/cmdline-opts/local-port.d create mode 100644 docs/cmdline-opts/location-trusted.d create mode 100644 docs/cmdline-opts/location.d create mode 100644 docs/cmdline-opts/login-options.d create mode 100644 docs/cmdline-opts/mail-auth.d create mode 100644 docs/cmdline-opts/mail-from.d create mode 100644 docs/cmdline-opts/mail-rcpt.d create mode 100644 docs/cmdline-opts/manual.d create mode 100644 docs/cmdline-opts/max-filesize.d create mode 100644 docs/cmdline-opts/max-redirs.d create mode 100644 docs/cmdline-opts/max-time.d create mode 100644 docs/cmdline-opts/metalink.d create mode 100644 docs/cmdline-opts/negotiate.d create mode 100644 docs/cmdline-opts/netrc-file.d create mode 100644 docs/cmdline-opts/netrc-optional.d create mode 100644 docs/cmdline-opts/netrc.d create mode 100644 docs/cmdline-opts/next.d create mode 100644 docs/cmdline-opts/no-alpn.d create mode 100644 docs/cmdline-opts/no-buffer.d create mode 100644 docs/cmdline-opts/no-keepalive.d create mode 100644 docs/cmdline-opts/no-npn.d create mode 100644 docs/cmdline-opts/no-sessionid.d create mode 100644 docs/cmdline-opts/noproxy.d create mode 100644 docs/cmdline-opts/ntlm-wb.d create mode 100644 docs/cmdline-opts/ntlm.d create mode 100644 docs/cmdline-opts/oauth2-bearer.d create mode 100644 docs/cmdline-opts/output.d create mode 100644 docs/cmdline-opts/page-footer create mode 100644 docs/cmdline-opts/page-header create mode 100644 docs/cmdline-opts/pass.d create mode 100644 docs/cmdline-opts/path-as-is.d create mode 100644 docs/cmdline-opts/pinnedpubkey.d create mode 100644 docs/cmdline-opts/post301.d create mode 100644 docs/cmdline-opts/post302.d create mode 100644 docs/cmdline-opts/post303.d create mode 100644 docs/cmdline-opts/preproxy.d create mode 100644 docs/cmdline-opts/progress-bar.d create mode 100644 docs/cmdline-opts/proto-default.d create mode 100644 docs/cmdline-opts/proto-redir.d create mode 100644 docs/cmdline-opts/proto.d create mode 100644 docs/cmdline-opts/proxy-anyauth.d create mode 100644 docs/cmdline-opts/proxy-basic.d create mode 100644 docs/cmdline-opts/proxy-cacert.d create mode 100644 docs/cmdline-opts/proxy-capath.d create mode 100644 docs/cmdline-opts/proxy-cert-type.d create mode 100644 docs/cmdline-opts/proxy-cert.d create mode 100644 docs/cmdline-opts/proxy-ciphers.d create mode 100644 docs/cmdline-opts/proxy-crlfile.d create mode 100644 docs/cmdline-opts/proxy-digest.d create mode 100644 docs/cmdline-opts/proxy-header.d create mode 100644 docs/cmdline-opts/proxy-insecure.d create mode 100644 docs/cmdline-opts/proxy-key-type.d create mode 100644 docs/cmdline-opts/proxy-key.d create mode 100644 docs/cmdline-opts/proxy-negotiate.d create mode 100644 docs/cmdline-opts/proxy-ntlm.d create mode 100644 docs/cmdline-opts/proxy-pass.d create mode 100644 docs/cmdline-opts/proxy-pinnedpubkey.d create mode 100644 docs/cmdline-opts/proxy-service-name.d create mode 100644 docs/cmdline-opts/proxy-ssl-allow-beast.d create mode 100644 docs/cmdline-opts/proxy-tls13-ciphers.d create mode 100644 docs/cmdline-opts/proxy-tlsauthtype.d create mode 100644 docs/cmdline-opts/proxy-tlspassword.d create mode 100644 docs/cmdline-opts/proxy-tlsuser.d create mode 100644 docs/cmdline-opts/proxy-tlsv1.d create mode 100644 docs/cmdline-opts/proxy-user.d create mode 100644 docs/cmdline-opts/proxy.d create mode 100644 docs/cmdline-opts/proxy1.0.d create mode 100644 docs/cmdline-opts/proxytunnel.d create mode 100644 docs/cmdline-opts/pubkey.d create mode 100644 docs/cmdline-opts/quote.d create mode 100644 docs/cmdline-opts/random-file.d create mode 100644 docs/cmdline-opts/range.d create mode 100644 docs/cmdline-opts/raw.d create mode 100644 docs/cmdline-opts/referer.d create mode 100644 docs/cmdline-opts/remote-header-name.d create mode 100644 docs/cmdline-opts/remote-name-all.d create mode 100644 docs/cmdline-opts/remote-name.d create mode 100644 docs/cmdline-opts/remote-time.d create mode 100644 docs/cmdline-opts/request-target.d create mode 100644 docs/cmdline-opts/request.d create mode 100644 docs/cmdline-opts/resolve.d create mode 100644 docs/cmdline-opts/retry-connrefused.d create mode 100644 docs/cmdline-opts/retry-delay.d create mode 100644 docs/cmdline-opts/retry-max-time.d create mode 100644 docs/cmdline-opts/retry.d create mode 100644 docs/cmdline-opts/sasl-ir.d create mode 100644 docs/cmdline-opts/service-name.d create mode 100644 docs/cmdline-opts/show-error.d create mode 100644 docs/cmdline-opts/silent.d create mode 100644 docs/cmdline-opts/socks4.d create mode 100644 docs/cmdline-opts/socks4a.d create mode 100644 docs/cmdline-opts/socks5-basic.d create mode 100644 docs/cmdline-opts/socks5-gssapi-nec.d create mode 100644 docs/cmdline-opts/socks5-gssapi-service.d create mode 100644 docs/cmdline-opts/socks5-gssapi.d create mode 100644 docs/cmdline-opts/socks5-hostname.d create mode 100644 docs/cmdline-opts/socks5.d create mode 100644 docs/cmdline-opts/speed-limit.d create mode 100644 docs/cmdline-opts/speed-time.d create mode 100644 docs/cmdline-opts/ssl-allow-beast.d create mode 100644 docs/cmdline-opts/ssl-no-revoke.d create mode 100644 docs/cmdline-opts/ssl-reqd.d create mode 100644 docs/cmdline-opts/ssl.d create mode 100644 docs/cmdline-opts/sslv2.d create mode 100644 docs/cmdline-opts/sslv3.d create mode 100644 docs/cmdline-opts/stderr.d create mode 100644 docs/cmdline-opts/styled-output.d create mode 100644 docs/cmdline-opts/suppress-connect-headers.d create mode 100644 docs/cmdline-opts/tcp-fastopen.d create mode 100644 docs/cmdline-opts/tcp-nodelay.d create mode 100644 docs/cmdline-opts/telnet-option.d create mode 100644 docs/cmdline-opts/tftp-blksize.d create mode 100644 docs/cmdline-opts/tftp-no-options.d create mode 100644 docs/cmdline-opts/time-cond.d create mode 100644 docs/cmdline-opts/tls-max.d create mode 100644 docs/cmdline-opts/tls13-ciphers.d create mode 100644 docs/cmdline-opts/tlsauthtype.d create mode 100644 docs/cmdline-opts/tlspassword.d create mode 100644 docs/cmdline-opts/tlsuser.d create mode 100644 docs/cmdline-opts/tlsv1.0.d create mode 100644 docs/cmdline-opts/tlsv1.1.d create mode 100644 docs/cmdline-opts/tlsv1.2.d create mode 100644 docs/cmdline-opts/tlsv1.3.d create mode 100644 docs/cmdline-opts/tlsv1.d create mode 100644 docs/cmdline-opts/tr-encoding.d create mode 100644 docs/cmdline-opts/trace-ascii.d create mode 100644 docs/cmdline-opts/trace-time.d create mode 100644 docs/cmdline-opts/trace.d create mode 100644 docs/cmdline-opts/unix-socket.d create mode 100644 docs/cmdline-opts/upload-file.d create mode 100644 docs/cmdline-opts/url.d create mode 100644 docs/cmdline-opts/use-ascii.d create mode 100644 docs/cmdline-opts/user-agent.d create mode 100644 docs/cmdline-opts/user.d create mode 100644 docs/cmdline-opts/verbose.d create mode 100644 docs/cmdline-opts/version.d create mode 100644 docs/cmdline-opts/write-out.d create mode 100644 docs/cmdline-opts/xattr.d create mode 100644 docs/curl-config.1 create mode 100644 docs/examples/.gitignore create mode 100644 docs/examples/10-at-a-time.c create mode 100644 docs/examples/Makefile.am create mode 100644 docs/examples/Makefile.example create mode 100644 docs/examples/Makefile.inc create mode 100644 docs/examples/Makefile.m32 create mode 100644 docs/examples/Makefile.netware create mode 100644 docs/examples/README create mode 100755 docs/examples/adddocsref.pl create mode 100644 docs/examples/anyauthput.c create mode 100644 docs/examples/asiohiper.cpp create mode 100644 docs/examples/cacertinmem.c create mode 100644 docs/examples/certinfo.c create mode 100644 docs/examples/chkspeed.c create mode 100644 docs/examples/cookie_interface.c create mode 100644 docs/examples/crawler.c create mode 100644 docs/examples/curlgtk.c create mode 100644 docs/examples/curlx.c create mode 100644 docs/examples/debug.c create mode 100644 docs/examples/evhiperfifo.c create mode 100644 docs/examples/externalsocket.c create mode 100644 docs/examples/fileupload.c create mode 100644 docs/examples/fopen.c create mode 100644 docs/examples/ftp-wildcard.c create mode 100644 docs/examples/ftpget.c create mode 100644 docs/examples/ftpgetinfo.c create mode 100644 docs/examples/ftpgetresp.c create mode 100644 docs/examples/ftpsget.c create mode 100644 docs/examples/ftpupload.c create mode 100644 docs/examples/ftpuploadfrommem.c create mode 100644 docs/examples/ftpuploadresume.c create mode 100644 docs/examples/getinfo.c create mode 100644 docs/examples/getinmemory.c create mode 100644 docs/examples/getredirect.c create mode 100644 docs/examples/ghiper.c create mode 100644 docs/examples/hiperfifo.c create mode 100644 docs/examples/href_extractor.c create mode 100644 docs/examples/htmltidy.c create mode 100644 docs/examples/htmltitle.cpp create mode 100644 docs/examples/http-post.c create mode 100644 docs/examples/http2-download.c create mode 100644 docs/examples/http2-serverpush.c create mode 100644 docs/examples/http2-upload.c create mode 100644 docs/examples/httpcustomheader.c create mode 100644 docs/examples/httpput.c create mode 100644 docs/examples/https.c create mode 100644 docs/examples/imap-append.c create mode 100644 docs/examples/imap-copy.c create mode 100644 docs/examples/imap-create.c create mode 100644 docs/examples/imap-delete.c create mode 100644 docs/examples/imap-examine.c create mode 100644 docs/examples/imap-fetch.c create mode 100644 docs/examples/imap-list.c create mode 100644 docs/examples/imap-lsub.c create mode 100644 docs/examples/imap-multi.c create mode 100644 docs/examples/imap-noop.c create mode 100644 docs/examples/imap-search.c create mode 100644 docs/examples/imap-ssl.c create mode 100644 docs/examples/imap-store.c create mode 100644 docs/examples/imap-tls.c create mode 100644 docs/examples/makefile.dj create mode 100644 docs/examples/multi-app.c create mode 100644 docs/examples/multi-debugcallback.c create mode 100644 docs/examples/multi-double.c create mode 100644 docs/examples/multi-formadd.c create mode 100644 docs/examples/multi-post.c create mode 100644 docs/examples/multi-single.c create mode 100644 docs/examples/multi-uv.c create mode 100644 docs/examples/multithread.c create mode 100644 docs/examples/opensslthreadlock.c create mode 100644 docs/examples/persistant.c create mode 100644 docs/examples/pop3-dele.c create mode 100644 docs/examples/pop3-list.c create mode 100644 docs/examples/pop3-multi.c create mode 100644 docs/examples/pop3-noop.c create mode 100644 docs/examples/pop3-retr.c create mode 100644 docs/examples/pop3-ssl.c create mode 100644 docs/examples/pop3-stat.c create mode 100644 docs/examples/pop3-tls.c create mode 100644 docs/examples/pop3-top.c create mode 100644 docs/examples/pop3-uidl.c create mode 100644 docs/examples/post-callback.c create mode 100644 docs/examples/postinmemory.c create mode 100644 docs/examples/postit2-formadd.c create mode 100644 docs/examples/postit2.c create mode 100644 docs/examples/progressfunc.c create mode 100644 docs/examples/resolve.c create mode 100644 docs/examples/rtsp.c create mode 100644 docs/examples/sampleconv.c create mode 100644 docs/examples/sendrecv.c create mode 100644 docs/examples/sepheaders.c create mode 100644 docs/examples/sessioninfo.c create mode 100644 docs/examples/sftpget.c create mode 100644 docs/examples/sftpuploadresume.c create mode 100644 docs/examples/shared-connection-cache.c create mode 100644 docs/examples/simple.c create mode 100644 docs/examples/simplepost.c create mode 100644 docs/examples/simplessl.c create mode 100644 docs/examples/smooth-gtk-thread.c create mode 100644 docs/examples/smtp-expn.c create mode 100644 docs/examples/smtp-mail.c create mode 100644 docs/examples/smtp-mime.c create mode 100644 docs/examples/smtp-multi.c create mode 100644 docs/examples/smtp-ssl.c create mode 100644 docs/examples/smtp-tls.c create mode 100644 docs/examples/smtp-vrfy.c create mode 100644 docs/examples/sslbackend.c create mode 100644 docs/examples/synctime.c create mode 100644 docs/examples/threaded-shared-conn.c create mode 100644 docs/examples/threaded-ssl.c create mode 100644 docs/examples/url2file.c create mode 100644 docs/examples/usercertinmem.c create mode 100755 docs/examples/version-check.pl create mode 100644 docs/examples/xmlstream.c create mode 100644 docs/libcurl/.gitignore create mode 100644 docs/libcurl/ABI create mode 100644 docs/libcurl/CMakeLists.txt create mode 100644 docs/libcurl/Makefile.am create mode 100644 docs/libcurl/Makefile.inc create mode 100644 docs/libcurl/curl_easy_cleanup.3 create mode 100644 docs/libcurl/curl_easy_duphandle.3 create mode 100644 docs/libcurl/curl_easy_escape.3 create mode 100644 docs/libcurl/curl_easy_getinfo.3 create mode 100644 docs/libcurl/curl_easy_init.3 create mode 100644 docs/libcurl/curl_easy_pause.3 create mode 100644 docs/libcurl/curl_easy_perform.3 create mode 100644 docs/libcurl/curl_easy_recv.3 create mode 100644 docs/libcurl/curl_easy_reset.3 create mode 100644 docs/libcurl/curl_easy_send.3 create mode 100644 docs/libcurl/curl_easy_setopt.3 create mode 100644 docs/libcurl/curl_easy_strerror.3 create mode 100644 docs/libcurl/curl_easy_unescape.3 create mode 100644 docs/libcurl/curl_escape.3 create mode 100644 docs/libcurl/curl_formadd.3 create mode 100644 docs/libcurl/curl_formfree.3 create mode 100644 docs/libcurl/curl_formget.3 create mode 100644 docs/libcurl/curl_free.3 create mode 100644 docs/libcurl/curl_getdate.3 create mode 100644 docs/libcurl/curl_getenv.3 create mode 100644 docs/libcurl/curl_global_cleanup.3 create mode 100644 docs/libcurl/curl_global_init.3 create mode 100644 docs/libcurl/curl_global_init_mem.3 create mode 100644 docs/libcurl/curl_global_sslset.3 create mode 100644 docs/libcurl/curl_mime_addpart.3 create mode 100644 docs/libcurl/curl_mime_data.3 create mode 100644 docs/libcurl/curl_mime_data_cb.3 create mode 100644 docs/libcurl/curl_mime_encoder.3 create mode 100644 docs/libcurl/curl_mime_filedata.3 create mode 100644 docs/libcurl/curl_mime_filename.3 create mode 100644 docs/libcurl/curl_mime_free.3 create mode 100644 docs/libcurl/curl_mime_headers.3 create mode 100644 docs/libcurl/curl_mime_init.3 create mode 100644 docs/libcurl/curl_mime_name.3 create mode 100644 docs/libcurl/curl_mime_subparts.3 create mode 100644 docs/libcurl/curl_mime_type.3 create mode 100644 docs/libcurl/curl_mprintf.3 create mode 100644 docs/libcurl/curl_multi_add_handle.3 create mode 100644 docs/libcurl/curl_multi_assign.3 create mode 100644 docs/libcurl/curl_multi_cleanup.3 create mode 100644 docs/libcurl/curl_multi_fdset.3 create mode 100644 docs/libcurl/curl_multi_info_read.3 create mode 100644 docs/libcurl/curl_multi_init.3 create mode 100644 docs/libcurl/curl_multi_perform.3 create mode 100644 docs/libcurl/curl_multi_remove_handle.3 create mode 100644 docs/libcurl/curl_multi_setopt.3 create mode 100644 docs/libcurl/curl_multi_socket.3 create mode 100644 docs/libcurl/curl_multi_socket_action.3 create mode 100644 docs/libcurl/curl_multi_socket_all.3 create mode 100644 docs/libcurl/curl_multi_strerror.3 create mode 100644 docs/libcurl/curl_multi_timeout.3 create mode 100644 docs/libcurl/curl_multi_wait.3 create mode 100644 docs/libcurl/curl_share_cleanup.3 create mode 100644 docs/libcurl/curl_share_init.3 create mode 100644 docs/libcurl/curl_share_setopt.3 create mode 100644 docs/libcurl/curl_share_strerror.3 create mode 100644 docs/libcurl/curl_slist_append.3 create mode 100644 docs/libcurl/curl_slist_free_all.3 create mode 100644 docs/libcurl/curl_strequal.3 create mode 100644 docs/libcurl/curl_strnequal.3 create mode 100644 docs/libcurl/curl_unescape.3 create mode 100644 docs/libcurl/curl_version.3 create mode 100644 docs/libcurl/curl_version_info.3 create mode 100644 docs/libcurl/getinfo-times create mode 100644 docs/libcurl/libcurl-easy.3 create mode 100644 docs/libcurl/libcurl-env.3 create mode 100644 docs/libcurl/libcurl-errors.3 create mode 100644 docs/libcurl/libcurl-multi.3 create mode 100644 docs/libcurl/libcurl-security.3 create mode 100644 docs/libcurl/libcurl-share.3 create mode 100644 docs/libcurl/libcurl-thread.3 create mode 100644 docs/libcurl/libcurl-tutorial.3 create mode 100644 docs/libcurl/libcurl.3 create mode 100644 docs/libcurl/libcurl.m4 create mode 100755 docs/libcurl/mksymbolsmanpage.pl create mode 100644 docs/libcurl/opts/CMakeLists.txt create mode 100644 docs/libcurl/opts/CURLINFO_ACTIVESOCKET.3 create mode 100644 docs/libcurl/opts/CURLINFO_APPCONNECT_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_APPCONNECT_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_CERTINFO.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONDITION_UNMET.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONNECT_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONNECT_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_CONTENT_TYPE.3 create mode 100644 docs/libcurl/opts/CURLINFO_COOKIELIST.3 create mode 100644 docs/libcurl/opts/CURLINFO_EFFECTIVE_URL.3 create mode 100644 docs/libcurl/opts/CURLINFO_FILETIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_FILETIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_FTP_ENTRY_PATH.3 create mode 100644 docs/libcurl/opts/CURLINFO_HEADER_SIZE.3 create mode 100644 docs/libcurl/opts/CURLINFO_HTTPAUTH_AVAIL.3 create mode 100644 docs/libcurl/opts/CURLINFO_HTTP_CONNECTCODE.3 create mode 100644 docs/libcurl/opts/CURLINFO_HTTP_VERSION.3 create mode 100644 docs/libcurl/opts/CURLINFO_LASTSOCKET.3 create mode 100644 docs/libcurl/opts/CURLINFO_LOCAL_IP.3 create mode 100644 docs/libcurl/opts/CURLINFO_LOCAL_PORT.3 create mode 100644 docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_NUM_CONNECTS.3 create mode 100644 docs/libcurl/opts/CURLINFO_OS_ERRNO.3 create mode 100644 docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_PRIMARY_IP.3 create mode 100644 docs/libcurl/opts/CURLINFO_PRIMARY_PORT.3 create mode 100644 docs/libcurl/opts/CURLINFO_PRIVATE.3 create mode 100644 docs/libcurl/opts/CURLINFO_PROTOCOL.3 create mode 100644 docs/libcurl/opts/CURLINFO_PROXYAUTH_AVAIL.3 create mode 100644 docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 create mode 100644 docs/libcurl/opts/CURLINFO_REDIRECT_COUNT.3 create mode 100644 docs/libcurl/opts/CURLINFO_REDIRECT_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_REDIRECT_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_REDIRECT_URL.3 create mode 100644 docs/libcurl/opts/CURLINFO_REQUEST_SIZE.3 create mode 100644 docs/libcurl/opts/CURLINFO_RESPONSE_CODE.3 create mode 100644 docs/libcurl/opts/CURLINFO_RTSP_CLIENT_CSEQ.3 create mode 100644 docs/libcurl/opts/CURLINFO_RTSP_CSEQ_RECV.3 create mode 100644 docs/libcurl/opts/CURLINFO_RTSP_SERVER_CSEQ.3 create mode 100644 docs/libcurl/opts/CURLINFO_RTSP_SESSION_ID.3 create mode 100644 docs/libcurl/opts/CURLINFO_SCHEME.3 create mode 100644 docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD.3 create mode 100644 docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.3 create mode 100644 docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD.3 create mode 100644 docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_SPEED_UPLOAD.3 create mode 100644 docs/libcurl/opts/CURLINFO_SPEED_UPLOAD_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_SSL_ENGINES.3 create mode 100644 docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3 create mode 100644 docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLINFO_TLS_SESSION.3 create mode 100644 docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 create mode 100644 docs/libcurl/opts/CURLINFO_TOTAL_TIME.3 create mode 100644 docs/libcurl/opts/CURLINFO_TOTAL_TIME_T.3 create mode 100644 docs/libcurl/opts/CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 create mode 100644 docs/libcurl/opts/CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 create mode 100644 docs/libcurl/opts/CURLMOPT_MAXCONNECTS.3 create mode 100644 docs/libcurl/opts/CURLMOPT_MAX_HOST_CONNECTIONS.3 create mode 100644 docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 create mode 100644 docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 create mode 100644 docs/libcurl/opts/CURLMOPT_PIPELINING.3 create mode 100644 docs/libcurl/opts/CURLMOPT_PIPELINING_SERVER_BL.3 create mode 100644 docs/libcurl/opts/CURLMOPT_PIPELINING_SITE_BL.3 create mode 100644 docs/libcurl/opts/CURLMOPT_PUSHDATA.3 create mode 100644 docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLMOPT_SOCKETDATA.3 create mode 100644 docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLMOPT_TIMERDATA.3 create mode 100644 docs/libcurl/opts/CURLMOPT_TIMERFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 create mode 100644 docs/libcurl/opts/CURLOPT_ACCEPTTIMEOUT_MS.3 create mode 100644 docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.3 create mode 100644 docs/libcurl/opts/CURLOPT_ADDRESS_SCOPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_APPEND.3 create mode 100644 docs/libcurl/opts/CURLOPT_AUTOREFERER.3 create mode 100644 docs/libcurl/opts/CURLOPT_BUFFERSIZE.3 create mode 100644 docs/libcurl/opts/CURLOPT_CAINFO.3 create mode 100644 docs/libcurl/opts/CURLOPT_CAPATH.3 create mode 100644 docs/libcurl/opts/CURLOPT_CERTINFO.3 create mode 100644 docs/libcurl/opts/CURLOPT_CHUNK_BGN_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_CHUNK_DATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_CHUNK_END_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_CLOSESOCKETDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_CLOSESOCKETFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONNECT_TO.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONV_FROM_UTF8_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_CONV_TO_NETWORK_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_COOKIE.3 create mode 100644 docs/libcurl/opts/CURLOPT_COOKIEFILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_COOKIEJAR.3 create mode 100644 docs/libcurl/opts/CURLOPT_COOKIELIST.3 create mode 100644 docs/libcurl/opts/CURLOPT_COOKIESESSION.3 create mode 100644 docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.3 create mode 100644 docs/libcurl/opts/CURLOPT_CRLF.3 create mode 100644 docs/libcurl/opts/CURLOPT_CRLFILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.3 create mode 100644 docs/libcurl/opts/CURLOPT_DEBUGDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.3 create mode 100644 docs/libcurl/opts/CURLOPT_DIRLISTONLY.3 create mode 100644 docs/libcurl/opts/CURLOPT_DISALLOW_USERNAME_IN_URL.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_CACHE_TIMEOUT.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_INTERFACE.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_SERVERS.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_SHUFFLE_ADDRESSES.3 create mode 100644 docs/libcurl/opts/CURLOPT_DNS_USE_GLOBAL_CACHE.3 create mode 100644 docs/libcurl/opts/CURLOPT_EGDSOCKET.3 create mode 100644 docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 create mode 100644 docs/libcurl/opts/CURLOPT_EXPECT_100_TIMEOUT_MS.3 create mode 100644 docs/libcurl/opts/CURLOPT_FAILONERROR.3 create mode 100644 docs/libcurl/opts/CURLOPT_FILETIME.3 create mode 100644 docs/libcurl/opts/CURLOPT_FNMATCH_DATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_FNMATCH_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.3 create mode 100644 docs/libcurl/opts/CURLOPT_FORBID_REUSE.3 create mode 100644 docs/libcurl/opts/CURLOPT_FRESH_CONNECT.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTPPORT.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTPSSLAUTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_ALTERNATIVE_TO_USER.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_CREATE_MISSING_DIRS.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_FILEMETHOD.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_RESPONSE_TIMEOUT.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_SSL_CCC.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_USE_EPRT.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_USE_EPSV.3 create mode 100644 docs/libcurl/opts/CURLOPT_FTP_USE_PRET.3 create mode 100644 docs/libcurl/opts/CURLOPT_GSSAPI_DELEGATION.3 create mode 100644 docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 create mode 100644 docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 create mode 100644 docs/libcurl/opts/CURLOPT_HEADER.3 create mode 100644 docs/libcurl/opts/CURLOPT_HEADERDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_HEADERFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_HEADEROPT.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTP200ALIASES.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTPAUTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTPGET.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTPHEADER.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTPPOST.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTPPROXYTUNNEL.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTP_CONTENT_DECODING.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTP_TRANSFER_DECODING.3 create mode 100644 docs/libcurl/opts/CURLOPT_HTTP_VERSION.3 create mode 100644 docs/libcurl/opts/CURLOPT_IGNORE_CONTENT_LENGTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_INFILESIZE.3 create mode 100644 docs/libcurl/opts/CURLOPT_INFILESIZE_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_INTERFACE.3 create mode 100644 docs/libcurl/opts/CURLOPT_INTERLEAVEDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_INTERLEAVEFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_IOCTLDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_IOCTLFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_IPRESOLVE.3 create mode 100644 docs/libcurl/opts/CURLOPT_ISSUERCERT.3 create mode 100644 docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 create mode 100644 docs/libcurl/opts/CURLOPT_KEYPASSWD.3 create mode 100644 docs/libcurl/opts/CURLOPT_KRBLEVEL.3 create mode 100644 docs/libcurl/opts/CURLOPT_LOCALPORT.3 create mode 100644 docs/libcurl/opts/CURLOPT_LOCALPORTRANGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.3 create mode 100644 docs/libcurl/opts/CURLOPT_LOW_SPEED_LIMIT.3 create mode 100644 docs/libcurl/opts/CURLOPT_LOW_SPEED_TIME.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAIL_AUTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAIL_FROM.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAIL_RCPT.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAXCONNECTS.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAXFILESIZE.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAXFILESIZE_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAXREDIRS.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_MIMEPOST.3 create mode 100644 docs/libcurl/opts/CURLOPT_NETRC.3 create mode 100644 docs/libcurl/opts/CURLOPT_NETRC_FILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_NEW_DIRECTORY_PERMS.3 create mode 100644 docs/libcurl/opts/CURLOPT_NEW_FILE_PERMS.3 create mode 100644 docs/libcurl/opts/CURLOPT_NOBODY.3 create mode 100644 docs/libcurl/opts/CURLOPT_NOPROGRESS.3 create mode 100644 docs/libcurl/opts/CURLOPT_NOPROXY.3 create mode 100644 docs/libcurl/opts/CURLOPT_NOSIGNAL.3 create mode 100644 docs/libcurl/opts/CURLOPT_OPENSOCKETDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_OPENSOCKETFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_PASSWORD.3 create mode 100644 docs/libcurl/opts/CURLOPT_PATH_AS_IS.3 create mode 100644 docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 create mode 100644 docs/libcurl/opts/CURLOPT_PIPEWAIT.3 create mode 100644 docs/libcurl/opts/CURLOPT_PORT.3 create mode 100644 docs/libcurl/opts/CURLOPT_POST.3 create mode 100644 docs/libcurl/opts/CURLOPT_POSTFIELDS.3 create mode 100644 docs/libcurl/opts/CURLOPT_POSTFIELDSIZE.3 create mode 100644 docs/libcurl/opts/CURLOPT_POSTFIELDSIZE_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_POSTQUOTE.3 create mode 100644 docs/libcurl/opts/CURLOPT_POSTREDIR.3 create mode 100644 docs/libcurl/opts/CURLOPT_PREQUOTE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PRE_PROXY.3 create mode 100644 docs/libcurl/opts/CURLOPT_PRIVATE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROGRESSDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROTOCOLS.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYAUTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYHEADER.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYPASSWORD.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYPORT.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYTYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYUSERNAME.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXYUSERPWD.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 create mode 100644 docs/libcurl/opts/CURLOPT_PROXY_TRANSFER_MODE.3 create mode 100644 docs/libcurl/opts/CURLOPT_PUT.3 create mode 100644 docs/libcurl/opts/CURLOPT_QUOTE.3 create mode 100644 docs/libcurl/opts/CURLOPT_RANDOM_FILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_RANGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_READDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_READFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 create mode 100644 docs/libcurl/opts/CURLOPT_REFERER.3 create mode 100644 docs/libcurl/opts/CURLOPT_REQUEST_TARGET.3 create mode 100644 docs/libcurl/opts/CURLOPT_RESOLVE.3 create mode 100644 docs/libcurl/opts/CURLOPT_RESOLVER_START_DATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_RESOLVER_START_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_RESUME_FROM.3 create mode 100644 docs/libcurl/opts/CURLOPT_RESUME_FROM_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_RTSP_CLIENT_CSEQ.3 create mode 100644 docs/libcurl/opts/CURLOPT_RTSP_REQUEST.3 create mode 100644 docs/libcurl/opts/CURLOPT_RTSP_SERVER_CSEQ.3 create mode 100644 docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.3 create mode 100644 docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.3 create mode 100644 docs/libcurl/opts/CURLOPT_RTSP_TRANSPORT.3 create mode 100644 docs/libcurl/opts/CURLOPT_SASL_IR.3 create mode 100644 docs/libcurl/opts/CURLOPT_SEEKDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_SEEKFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_SERVICE_NAME.3 create mode 100644 docs/libcurl/opts/CURLOPT_SHARE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SOCKOPTDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_NEC.3 create mode 100644 docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_AUTH_TYPES.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_COMPRESSION.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_KEYDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_PRIVATE_KEYFILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSH_PUBLIC_KEYFILE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLCERT.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLCERTTYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLENGINE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLENGINE_DEFAULT.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLKEY.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLKEYTYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSLVERSION.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_ENABLE_ALPN.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_SESSIONID_CACHE.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_VERIFYHOST.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_VERIFYPEER.3 create mode 100644 docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3 create mode 100644 docs/libcurl/opts/CURLOPT_STDERR.3 create mode 100644 docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.3 create mode 100644 docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.3 create mode 100644 docs/libcurl/opts/CURLOPT_STREAM_WEIGHT.3 create mode 100644 docs/libcurl/opts/CURLOPT_SUPPRESS_CONNECT_HEADERS.3 create mode 100644 docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3 create mode 100644 docs/libcurl/opts/CURLOPT_TCP_KEEPALIVE.3 create mode 100644 docs/libcurl/opts/CURLOPT_TCP_KEEPIDLE.3 create mode 100644 docs/libcurl/opts/CURLOPT_TCP_KEEPINTVL.3 create mode 100644 docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 create mode 100644 docs/libcurl/opts/CURLOPT_TELNETOPTIONS.3 create mode 100644 docs/libcurl/opts/CURLOPT_TFTP_BLKSIZE.3 create mode 100644 docs/libcurl/opts/CURLOPT_TFTP_NO_OPTIONS.3 create mode 100644 docs/libcurl/opts/CURLOPT_TIMECONDITION.3 create mode 100644 docs/libcurl/opts/CURLOPT_TIMEOUT.3 create mode 100644 docs/libcurl/opts/CURLOPT_TIMEOUT_MS.3 create mode 100644 docs/libcurl/opts/CURLOPT_TIMEVALUE.3 create mode 100644 docs/libcurl/opts/CURLOPT_TIMEVALUE_LARGE.3 create mode 100644 docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.3 create mode 100644 docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.3 create mode 100644 docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.3 create mode 100644 docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.3 create mode 100644 docs/libcurl/opts/CURLOPT_TRANSFERTEXT.3 create mode 100644 docs/libcurl/opts/CURLOPT_TRANSFER_ENCODING.3 create mode 100644 docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 create mode 100644 docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.3 create mode 100644 docs/libcurl/opts/CURLOPT_UPLOAD.3 create mode 100644 docs/libcurl/opts/CURLOPT_URL.3 create mode 100644 docs/libcurl/opts/CURLOPT_USERAGENT.3 create mode 100644 docs/libcurl/opts/CURLOPT_USERNAME.3 create mode 100644 docs/libcurl/opts/CURLOPT_USERPWD.3 create mode 100644 docs/libcurl/opts/CURLOPT_USE_SSL.3 create mode 100644 docs/libcurl/opts/CURLOPT_VERBOSE.3 create mode 100644 docs/libcurl/opts/CURLOPT_WILDCARDMATCH.3 create mode 100644 docs/libcurl/opts/CURLOPT_WRITEDATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_WRITEFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_XFERINFODATA.3 create mode 100644 docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.3 create mode 100644 docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.3 create mode 100644 docs/libcurl/opts/Makefile.am create mode 100644 docs/libcurl/opts/Makefile.inc create mode 100644 docs/libcurl/opts/template.3 create mode 100644 docs/libcurl/symbols-in-versions create mode 100755 docs/libcurl/symbols.pl create mode 100644 docs/mk-ca-bundle.1 create mode 100644 include/Makefile.am create mode 100644 include/README create mode 100644 include/curl/.gitignore create mode 100644 include/curl/Makefile.am create mode 100644 include/curl/curl.h create mode 100644 include/curl/curlver.h create mode 100644 include/curl/easy.h create mode 100644 include/curl/mprintf.h create mode 100644 include/curl/multi.h create mode 100644 include/curl/stdcheaders.h create mode 100644 include/curl/system.h create mode 100644 include/curl/typecheck-gcc.h create mode 100644 lib/.gitattributes create mode 100644 lib/.gitignore create mode 100644 lib/CMakeLists.txt create mode 100644 lib/Makefile.Watcom create mode 100644 lib/Makefile.am create mode 100644 lib/Makefile.inc create mode 100644 lib/Makefile.m32 create mode 100644 lib/Makefile.netware create mode 100644 lib/Makefile.vxworks create mode 100644 lib/amigaos.c create mode 100644 lib/amigaos.h create mode 100644 lib/arpa_telnet.h create mode 100644 lib/asyn-ares.c create mode 100644 lib/asyn-thread.c create mode 100644 lib/asyn.h create mode 100644 lib/base64.c create mode 100755 lib/checksrc.pl create mode 100644 lib/config-amigaos.h create mode 100644 lib/config-dos.h create mode 100644 lib/config-mac.h create mode 100644 lib/config-os400.h create mode 100644 lib/config-riscos.h create mode 100644 lib/config-symbian.h create mode 100644 lib/config-tpf.h create mode 100644 lib/config-vxworks.h create mode 100644 lib/config-win32.h create mode 100644 lib/config-win32ce.h create mode 100644 lib/conncache.c create mode 100644 lib/conncache.h create mode 100644 lib/connect.c create mode 100644 lib/connect.h create mode 100644 lib/content_encoding.c create mode 100644 lib/content_encoding.h create mode 100644 lib/cookie.c create mode 100644 lib/cookie.h create mode 100644 lib/curl_addrinfo.c create mode 100644 lib/curl_addrinfo.h create mode 100644 lib/curl_base64.h create mode 100644 lib/curl_config.h.cmake create mode 100644 lib/curl_ctype.c create mode 100644 lib/curl_ctype.h create mode 100644 lib/curl_des.c create mode 100644 lib/curl_des.h create mode 100644 lib/curl_endian.c create mode 100644 lib/curl_endian.h create mode 100644 lib/curl_fnmatch.c create mode 100644 lib/curl_fnmatch.h create mode 100644 lib/curl_gethostname.c create mode 100644 lib/curl_gethostname.h create mode 100644 lib/curl_gssapi.c create mode 100644 lib/curl_gssapi.h create mode 100644 lib/curl_hmac.h create mode 100644 lib/curl_ldap.h create mode 100644 lib/curl_md4.h create mode 100644 lib/curl_md5.h create mode 100644 lib/curl_memory.h create mode 100644 lib/curl_memrchr.c create mode 100644 lib/curl_memrchr.h create mode 100644 lib/curl_multibyte.c create mode 100644 lib/curl_multibyte.h create mode 100644 lib/curl_ntlm_core.c create mode 100644 lib/curl_ntlm_core.h create mode 100644 lib/curl_ntlm_wb.c create mode 100644 lib/curl_ntlm_wb.h create mode 100644 lib/curl_path.c create mode 100644 lib/curl_path.h create mode 100644 lib/curl_printf.h create mode 100644 lib/curl_range.c create mode 100644 lib/curl_range.h create mode 100644 lib/curl_rtmp.c create mode 100644 lib/curl_rtmp.h create mode 100644 lib/curl_sasl.c create mode 100644 lib/curl_sasl.h create mode 100644 lib/curl_sec.h create mode 100644 lib/curl_setup.h create mode 100644 lib/curl_setup_once.h create mode 100644 lib/curl_sha256.h create mode 100644 lib/curl_sspi.c create mode 100644 lib/curl_sspi.h create mode 100644 lib/curl_threads.c create mode 100644 lib/curl_threads.h create mode 100644 lib/curlx.h create mode 100644 lib/dict.c create mode 100644 lib/dict.h create mode 100644 lib/dotdot.c create mode 100644 lib/dotdot.h create mode 100644 lib/easy.c create mode 100644 lib/easyif.h create mode 100644 lib/escape.c create mode 100644 lib/escape.h create mode 100644 lib/file.c create mode 100644 lib/file.h create mode 100644 lib/fileinfo.c create mode 100644 lib/fileinfo.h create mode 100644 lib/firefox-db2pem.sh create mode 100644 lib/formdata.c create mode 100644 lib/formdata.h create mode 100644 lib/ftp.c create mode 100644 lib/ftp.h create mode 100644 lib/ftplistparser.c create mode 100644 lib/ftplistparser.h create mode 100644 lib/getenv.c create mode 100644 lib/getinfo.c create mode 100644 lib/getinfo.h create mode 100644 lib/gopher.c create mode 100644 lib/gopher.h create mode 100644 lib/hash.c create mode 100644 lib/hash.h create mode 100644 lib/hmac.c create mode 100644 lib/hostasyn.c create mode 100644 lib/hostcheck.c create mode 100644 lib/hostcheck.h create mode 100644 lib/hostip.c create mode 100644 lib/hostip.h create mode 100644 lib/hostip4.c create mode 100644 lib/hostip6.c create mode 100644 lib/hostsyn.c create mode 100644 lib/http.c create mode 100644 lib/http.h create mode 100644 lib/http2.c create mode 100644 lib/http2.h create mode 100644 lib/http_chunks.c create mode 100644 lib/http_chunks.h create mode 100644 lib/http_digest.c create mode 100644 lib/http_digest.h create mode 100644 lib/http_negotiate.c create mode 100644 lib/http_negotiate.h create mode 100644 lib/http_ntlm.c create mode 100644 lib/http_ntlm.h create mode 100644 lib/http_proxy.c create mode 100644 lib/http_proxy.h create mode 100644 lib/idn_win32.c create mode 100644 lib/if2ip.c create mode 100644 lib/if2ip.h create mode 100644 lib/imap.c create mode 100644 lib/imap.h create mode 100644 lib/inet_ntop.c create mode 100644 lib/inet_ntop.h create mode 100644 lib/inet_pton.c create mode 100644 lib/inet_pton.h create mode 100644 lib/krb5.c create mode 100644 lib/ldap.c create mode 100644 lib/libcurl.plist create mode 100644 lib/libcurl.rc create mode 100644 lib/libcurl.vers.in create mode 100644 lib/llist.c create mode 100644 lib/llist.h create mode 100644 lib/makefile.amiga create mode 100644 lib/makefile.dj create mode 100644 lib/md4.c create mode 100644 lib/md5.c create mode 100644 lib/memdebug.c create mode 100644 lib/memdebug.h create mode 100644 lib/mime.c create mode 100644 lib/mime.h create mode 100755 lib/mk-ca-bundle.pl create mode 100755 lib/mk-ca-bundle.vbs create mode 100644 lib/mprintf.c create mode 100644 lib/multi.c create mode 100644 lib/multihandle.h create mode 100644 lib/multiif.h create mode 100644 lib/netrc.c create mode 100644 lib/netrc.h create mode 100644 lib/non-ascii.c create mode 100644 lib/non-ascii.h create mode 100644 lib/nonblock.c create mode 100644 lib/nonblock.h create mode 100644 lib/nwlib.c create mode 100644 lib/nwos.c create mode 100755 lib/objnames-test08.sh create mode 100755 lib/objnames-test10.sh create mode 100644 lib/objnames.inc create mode 100644 lib/openldap.c create mode 100644 lib/parsedate.c create mode 100644 lib/parsedate.h create mode 100644 lib/pingpong.c create mode 100644 lib/pingpong.h create mode 100644 lib/pipeline.c create mode 100644 lib/pipeline.h create mode 100644 lib/pop3.c create mode 100644 lib/pop3.h create mode 100644 lib/progress.c create mode 100644 lib/progress.h create mode 100644 lib/psl.c create mode 100644 lib/psl.h create mode 100644 lib/rand.c create mode 100644 lib/rand.h create mode 100644 lib/rtsp.c create mode 100644 lib/rtsp.h create mode 100644 lib/security.c create mode 100644 lib/select.c create mode 100644 lib/select.h create mode 100644 lib/sendf.c create mode 100644 lib/sendf.h create mode 100644 lib/setopt.c create mode 100644 lib/setopt.h create mode 100644 lib/setup-os400.h create mode 100644 lib/setup-vms.h create mode 100644 lib/sha256.c create mode 100644 lib/share.c create mode 100644 lib/share.h create mode 100644 lib/sigpipe.h create mode 100644 lib/slist.c create mode 100644 lib/slist.h create mode 100644 lib/smb.c create mode 100644 lib/smb.h create mode 100644 lib/smtp.c create mode 100644 lib/smtp.h create mode 100644 lib/sockaddr.h create mode 100644 lib/socks.c create mode 100644 lib/socks.h create mode 100644 lib/socks_gssapi.c create mode 100644 lib/socks_sspi.c create mode 100644 lib/speedcheck.c create mode 100644 lib/speedcheck.h create mode 100644 lib/splay.c create mode 100644 lib/splay.h create mode 100644 lib/ssh-libssh.c create mode 100644 lib/ssh.c create mode 100644 lib/ssh.h create mode 100644 lib/strcase.c create mode 100644 lib/strcase.h create mode 100644 lib/strdup.c create mode 100644 lib/strdup.h create mode 100644 lib/strerror.c create mode 100644 lib/strerror.h create mode 100644 lib/strtok.c create mode 100644 lib/strtok.h create mode 100644 lib/strtoofft.c create mode 100644 lib/strtoofft.h create mode 100644 lib/system_win32.c create mode 100644 lib/system_win32.h create mode 100644 lib/telnet.c create mode 100644 lib/telnet.h create mode 100644 lib/tftp.c create mode 100644 lib/tftp.h create mode 100644 lib/timeval.c create mode 100644 lib/timeval.h create mode 100644 lib/transfer.c create mode 100644 lib/transfer.h create mode 100644 lib/url.c create mode 100644 lib/url.h create mode 100644 lib/urldata.h create mode 100644 lib/vauth/cleartext.c create mode 100644 lib/vauth/cram.c create mode 100644 lib/vauth/digest.c create mode 100644 lib/vauth/digest.h create mode 100644 lib/vauth/digest_sspi.c create mode 100644 lib/vauth/krb5_gssapi.c create mode 100644 lib/vauth/krb5_sspi.c create mode 100644 lib/vauth/ntlm.c create mode 100644 lib/vauth/ntlm.h create mode 100644 lib/vauth/ntlm_sspi.c create mode 100644 lib/vauth/oauth2.c create mode 100644 lib/vauth/spnego_gssapi.c create mode 100644 lib/vauth/spnego_sspi.c create mode 100644 lib/vauth/vauth.c create mode 100644 lib/vauth/vauth.h create mode 100644 lib/version.c create mode 100644 lib/vtls/axtls.c create mode 100644 lib/vtls/axtls.h create mode 100644 lib/vtls/cyassl.c create mode 100644 lib/vtls/cyassl.h create mode 100644 lib/vtls/darwinssl.c create mode 100644 lib/vtls/darwinssl.h create mode 100644 lib/vtls/gskit.c create mode 100644 lib/vtls/gskit.h create mode 100644 lib/vtls/gtls.c create mode 100644 lib/vtls/gtls.h create mode 100644 lib/vtls/mbedtls.c create mode 100644 lib/vtls/mbedtls.h create mode 100644 lib/vtls/nss.c create mode 100644 lib/vtls/nssg.h create mode 100644 lib/vtls/openssl.c create mode 100644 lib/vtls/openssl.h create mode 100644 lib/vtls/polarssl.c create mode 100644 lib/vtls/polarssl.h create mode 100644 lib/vtls/polarssl_threadlock.c create mode 100644 lib/vtls/polarssl_threadlock.h create mode 100644 lib/vtls/schannel.c create mode 100644 lib/vtls/schannel.h create mode 100644 lib/vtls/schannel_verify.c create mode 100644 lib/vtls/vtls.c create mode 100644 lib/vtls/vtls.h create mode 100644 lib/warnless.c create mode 100644 lib/warnless.h create mode 100644 lib/wildcard.c create mode 100644 lib/wildcard.h create mode 100644 lib/x509asn1.c create mode 100644 lib/x509asn1.h create mode 100644 libcurl.pc.in create mode 100644 m4/.gitignore create mode 100644 m4/ax_code_coverage.m4 create mode 100644 m4/ax_compile_check_sizeof.m4 create mode 100644 m4/curl-compilers.m4 create mode 100644 m4/curl-confopts.m4 create mode 100644 m4/curl-functions.m4 create mode 100644 m4/curl-openssl.m4 create mode 100644 m4/curl-override.m4 create mode 100644 m4/curl-reentrant.m4 create mode 100644 m4/xc-am-iface.m4 create mode 100644 m4/xc-cc-check.m4 create mode 100644 m4/xc-lt-iface.m4 create mode 100644 m4/xc-translit.m4 create mode 100644 m4/xc-val-flgs.m4 create mode 100644 m4/zz40-xc-ovr.m4 create mode 100644 m4/zz50-xc-ovr.m4 create mode 100644 m4/zz60-xc-ovr.m4 create mode 100755 maketgz create mode 100644 packages/AIX/Makefile.am create mode 100644 packages/AIX/RPM/.gitignore create mode 100644 packages/AIX/RPM/Makefile.am create mode 100644 packages/AIX/RPM/README create mode 100644 packages/AIX/RPM/curl.spec.in create mode 100644 packages/Android/Android.mk create mode 100644 packages/DOS/README create mode 100644 packages/DOS/common.dj create mode 100644 packages/EPM/.gitignore create mode 100644 packages/EPM/Makefile.am create mode 100644 packages/EPM/README create mode 100644 packages/EPM/curl.list.in create mode 100644 packages/Linux/Makefile.am create mode 100644 packages/Linux/RPM/.gitignore create mode 100644 packages/Linux/RPM/Makefile.am create mode 100644 packages/Linux/RPM/README create mode 100644 packages/Linux/RPM/curl-ssl.spec.in create mode 100644 packages/Linux/RPM/curl.spec.in create mode 100644 packages/Linux/RPM/make_curl_rpm create mode 100644 packages/Makefile.am create mode 100644 packages/NetWare/get_exp.awk create mode 100644 packages/NetWare/get_ver.awk create mode 100644 packages/OS400/README.OS400 create mode 100644 packages/OS400/ccsidcurl.c create mode 100644 packages/OS400/ccsidcurl.h create mode 100644 packages/OS400/curl.inc.in create mode 100644 packages/OS400/initscript.sh create mode 100644 packages/OS400/make-include.sh create mode 100644 packages/OS400/make-lib.sh create mode 100644 packages/OS400/make-src.sh create mode 100644 packages/OS400/make-tests.sh create mode 100644 packages/OS400/makefile.sh create mode 100644 packages/OS400/os400sys.c create mode 100644 packages/OS400/os400sys.h create mode 100644 packages/README create mode 100644 packages/Solaris/Makefile.am create mode 100644 packages/Symbian/bwins/libcurlu.def create mode 100644 packages/Symbian/eabi/libcurlu.def create mode 100644 packages/Symbian/group/bld.inf create mode 100644 packages/Symbian/group/curl.iby create mode 100644 packages/Symbian/group/curl.mmp create mode 100644 packages/Symbian/group/curl.pkg create mode 100644 packages/Symbian/group/libcurl.iby create mode 100644 packages/Symbian/group/libcurl.mmp create mode 100644 packages/Symbian/group/libcurl.pkg create mode 100644 packages/Symbian/readme.txt create mode 100644 packages/TPF/curl.mak create mode 100644 packages/TPF/maketpf.env_curl create mode 100644 packages/TPF/maketpf.env_curllib create mode 100644 packages/Win32/Makefile.am create mode 100644 packages/Win32/README create mode 100644 packages/Win32/cygwin/Makefile.am create mode 100644 packages/Win32/cygwin/README create mode 100644 packages/vms/Makefile.am create mode 100644 packages/vms/backup_gnv_curl_src.com create mode 100644 packages/vms/build_curl-config_script.com create mode 100644 packages/vms/build_gnv_curl.com create mode 100644 packages/vms/build_gnv_curl_pcsi_desc.com create mode 100644 packages/vms/build_gnv_curl_pcsi_text.com create mode 100644 packages/vms/build_gnv_curl_release_notes.com create mode 100644 packages/vms/build_libcurl_pc.com create mode 100644 packages/vms/build_vms.com create mode 100644 packages/vms/clean_gnv_curl.com create mode 100644 packages/vms/compare_curl_source.com create mode 100644 packages/vms/config_h.com create mode 100644 packages/vms/curl_crtl_init.c create mode 100644 packages/vms/curl_gnv_build_steps.txt create mode 100644 packages/vms/curl_release_note_start.txt create mode 100644 packages/vms/curl_startup.com create mode 100644 packages/vms/curlmsg.h create mode 100644 packages/vms/curlmsg.msg create mode 100644 packages/vms/curlmsg.sdl create mode 100644 packages/vms/curlmsg_vms.h create mode 100644 packages/vms/generate_config_vms_h_curl.com create mode 100644 packages/vms/generate_vax_transfer.com create mode 100644 packages/vms/gnv_conftest.c_first create mode 100644 packages/vms/gnv_curl_configure.sh create mode 100644 packages/vms/gnv_libcurl_symbols.opt create mode 100644 packages/vms/gnv_link_curl.com create mode 100644 packages/vms/macro32_exactcase.patch create mode 100644 packages/vms/make_gnv_curl_install.sh create mode 100644 packages/vms/make_pcsi_curl_kit_name.com create mode 100644 packages/vms/pcsi_gnv_curl_file_list.txt create mode 100644 packages/vms/pcsi_product_gnv_curl.com create mode 100644 packages/vms/readme create mode 100644 packages/vms/report_openssl_version.c create mode 100644 packages/vms/setup_gnv_curl_build.com create mode 100644 packages/vms/stage_curl_install.com create mode 100644 packages/vms/vms_eco_level.h create mode 100644 projects/README create mode 100644 projects/Windows/.gitattributes create mode 100644 projects/Windows/.gitignore create mode 100644 projects/Windows/VC10/.gitignore create mode 100644 projects/Windows/VC10/curl-all.sln create mode 100644 projects/Windows/VC10/lib/.gitignore create mode 100644 projects/Windows/VC10/lib/libcurl.sln create mode 100644 projects/Windows/VC10/lib/libcurl.tmpl create mode 100644 projects/Windows/VC10/lib/libcurl.vcxproj.filters create mode 100644 projects/Windows/VC10/src/.gitignore create mode 100644 projects/Windows/VC10/src/curl.sln create mode 100644 projects/Windows/VC10/src/curl.tmpl create mode 100644 projects/Windows/VC10/src/curl.vcxproj.filters create mode 100644 projects/Windows/VC11/.gitignore create mode 100644 projects/Windows/VC11/curl-all.sln create mode 100644 projects/Windows/VC11/lib/.gitignore create mode 100644 projects/Windows/VC11/lib/libcurl.sln create mode 100644 projects/Windows/VC11/lib/libcurl.tmpl create mode 100644 projects/Windows/VC11/lib/libcurl.vcxproj.filters create mode 100644 projects/Windows/VC11/src/.gitignore create mode 100644 projects/Windows/VC11/src/curl.sln create mode 100644 projects/Windows/VC11/src/curl.tmpl create mode 100644 projects/Windows/VC11/src/curl.vcxproj.filters create mode 100644 projects/Windows/VC12/.gitignore create mode 100644 projects/Windows/VC12/curl-all.sln create mode 100644 projects/Windows/VC12/lib/.gitignore create mode 100644 projects/Windows/VC12/lib/libcurl.sln create mode 100644 projects/Windows/VC12/lib/libcurl.tmpl create mode 100644 projects/Windows/VC12/lib/libcurl.vcxproj.filters create mode 100644 projects/Windows/VC12/src/.gitignore create mode 100644 projects/Windows/VC12/src/curl.sln create mode 100644 projects/Windows/VC12/src/curl.tmpl create mode 100644 projects/Windows/VC12/src/curl.vcxproj.filters create mode 100644 projects/Windows/VC14/.gitignore create mode 100644 projects/Windows/VC14/curl-all.sln create mode 100644 projects/Windows/VC14/lib/.gitignore create mode 100644 projects/Windows/VC14/lib/libcurl.sln create mode 100644 projects/Windows/VC14/lib/libcurl.tmpl create mode 100644 projects/Windows/VC14/lib/libcurl.vcxproj.filters create mode 100644 projects/Windows/VC14/src/.gitignore create mode 100644 projects/Windows/VC14/src/curl.sln create mode 100644 projects/Windows/VC14/src/curl.tmpl create mode 100644 projects/Windows/VC14/src/curl.vcxproj.filters create mode 100644 projects/Windows/VC15/.gitignore create mode 100644 projects/Windows/VC15/curl-all.sln create mode 100644 projects/Windows/VC15/lib/.gitignore create mode 100644 projects/Windows/VC15/lib/libcurl.sln create mode 100644 projects/Windows/VC15/lib/libcurl.tmpl create mode 100644 projects/Windows/VC15/lib/libcurl.vcxproj.filters create mode 100644 projects/Windows/VC15/src/.gitignore create mode 100644 projects/Windows/VC15/src/curl.sln create mode 100644 projects/Windows/VC15/src/curl.tmpl create mode 100644 projects/Windows/VC15/src/curl.vcxproj.filters create mode 100644 projects/Windows/VC6/.gitignore create mode 100644 projects/Windows/VC6/curl-all.dsw create mode 100644 projects/Windows/VC6/lib/.gitignore create mode 100644 projects/Windows/VC6/lib/libcurl.dsw create mode 100644 projects/Windows/VC6/lib/libcurl.tmpl create mode 100644 projects/Windows/VC6/src/.gitignore create mode 100644 projects/Windows/VC6/src/curl.dsw create mode 100644 projects/Windows/VC6/src/curl.tmpl create mode 100644 projects/Windows/VC7.1/.gitignore create mode 100644 projects/Windows/VC7.1/curl-all.sln create mode 100644 projects/Windows/VC7.1/lib/.gitignore create mode 100644 projects/Windows/VC7.1/lib/libcurl.sln create mode 100644 projects/Windows/VC7.1/lib/libcurl.tmpl create mode 100644 projects/Windows/VC7.1/src/.gitignore create mode 100644 projects/Windows/VC7.1/src/curl.sln create mode 100644 projects/Windows/VC7.1/src/curl.tmpl create mode 100644 projects/Windows/VC7/.gitignore create mode 100644 projects/Windows/VC7/curl-all.sln create mode 100644 projects/Windows/VC7/lib/.gitignore create mode 100644 projects/Windows/VC7/lib/libcurl.sln create mode 100644 projects/Windows/VC7/lib/libcurl.tmpl create mode 100644 projects/Windows/VC7/src/.gitignore create mode 100644 projects/Windows/VC7/src/curl.sln create mode 100644 projects/Windows/VC7/src/curl.tmpl create mode 100644 projects/Windows/VC8/.gitignore create mode 100644 projects/Windows/VC8/curl-all.sln create mode 100644 projects/Windows/VC8/lib/.gitignore create mode 100644 projects/Windows/VC8/lib/libcurl.sln create mode 100644 projects/Windows/VC8/lib/libcurl.tmpl create mode 100644 projects/Windows/VC8/src/.gitignore create mode 100644 projects/Windows/VC8/src/curl.sln create mode 100644 projects/Windows/VC8/src/curl.tmpl create mode 100644 projects/Windows/VC9/.gitignore create mode 100644 projects/Windows/VC9/curl-all.sln create mode 100644 projects/Windows/VC9/lib/.gitignore create mode 100644 projects/Windows/VC9/lib/libcurl.sln create mode 100644 projects/Windows/VC9/lib/libcurl.tmpl create mode 100644 projects/Windows/VC9/src/.gitignore create mode 100644 projects/Windows/VC9/src/curl.sln create mode 100644 projects/Windows/VC9/src/curl.tmpl create mode 100644 projects/build-openssl.bat create mode 100644 projects/build-wolfssl.bat create mode 100644 projects/checksrc.bat create mode 100644 projects/generate.bat create mode 100644 projects/wolfssl_options.h create mode 100644 projects/wolfssl_override.props create mode 100644 scripts/Makefile.am create mode 100755 scripts/contributors.sh create mode 100755 scripts/contrithanks.sh create mode 100755 scripts/coverage.sh create mode 100644 scripts/installcheck.sh create mode 100755 scripts/log2changes.pl create mode 100755 scripts/updatemanpages.pl create mode 100755 scripts/zsh.pl create mode 100644 src/.gitignore create mode 100644 src/CMakeLists.txt create mode 100644 src/Makefile.Watcom create mode 100644 src/Makefile.am create mode 100644 src/Makefile.inc create mode 100644 src/Makefile.m32 create mode 100644 src/Makefile.netware create mode 100644 src/curl.rc create mode 100644 src/macos/MACINSTALL.TXT create mode 100644 src/macos/curl.mcp.xml.sit.hqx create mode 100644 src/macos/src/curl_GUSIConfig.cpp create mode 100644 src/macos/src/macos_main.cpp create mode 100644 src/makefile.amiga create mode 100644 src/makefile.dj create mode 100755 src/mkhelp.pl create mode 100644 src/slist_wc.c create mode 100644 src/slist_wc.h create mode 100644 src/tool_binmode.c create mode 100644 src/tool_binmode.h create mode 100644 src/tool_bname.c create mode 100644 src/tool_bname.h create mode 100644 src/tool_cb_dbg.c create mode 100644 src/tool_cb_dbg.h create mode 100644 src/tool_cb_hdr.c create mode 100644 src/tool_cb_hdr.h create mode 100644 src/tool_cb_prg.c create mode 100644 src/tool_cb_prg.h create mode 100644 src/tool_cb_rea.c create mode 100644 src/tool_cb_rea.h create mode 100644 src/tool_cb_see.c create mode 100644 src/tool_cb_see.h create mode 100644 src/tool_cb_wrt.c create mode 100644 src/tool_cb_wrt.h create mode 100644 src/tool_cfgable.c create mode 100644 src/tool_cfgable.h create mode 100644 src/tool_convert.c create mode 100644 src/tool_convert.h create mode 100644 src/tool_dirhie.c create mode 100644 src/tool_dirhie.h create mode 100644 src/tool_doswin.c create mode 100644 src/tool_doswin.h create mode 100644 src/tool_easysrc.c create mode 100644 src/tool_easysrc.h create mode 100644 src/tool_filetime.c create mode 100644 src/tool_filetime.h create mode 100644 src/tool_formparse.c create mode 100644 src/tool_formparse.h create mode 100644 src/tool_getparam.c create mode 100644 src/tool_getparam.h create mode 100644 src/tool_getpass.c create mode 100644 src/tool_getpass.h create mode 100644 src/tool_help.c create mode 100644 src/tool_help.h create mode 100644 src/tool_helpers.c create mode 100644 src/tool_helpers.h create mode 100644 src/tool_homedir.c create mode 100644 src/tool_homedir.h create mode 100644 src/tool_hugehelp.c.cvs create mode 100644 src/tool_hugehelp.h create mode 100644 src/tool_libinfo.c create mode 100644 src/tool_libinfo.h create mode 100644 src/tool_main.c create mode 100644 src/tool_main.h create mode 100644 src/tool_metalink.c create mode 100644 src/tool_metalink.h create mode 100644 src/tool_msgs.c create mode 100644 src/tool_msgs.h create mode 100644 src/tool_operate.c create mode 100644 src/tool_operate.h create mode 100644 src/tool_operhlp.c create mode 100644 src/tool_operhlp.h create mode 100644 src/tool_panykey.c create mode 100644 src/tool_panykey.h create mode 100644 src/tool_paramhlp.c create mode 100644 src/tool_paramhlp.h create mode 100644 src/tool_parsecfg.c create mode 100644 src/tool_parsecfg.h create mode 100644 src/tool_sdecls.h create mode 100644 src/tool_setopt.c create mode 100644 src/tool_setopt.h create mode 100644 src/tool_setup.h create mode 100644 src/tool_sleep.c create mode 100644 src/tool_sleep.h create mode 100644 src/tool_strdup.c create mode 100644 src/tool_strdup.h create mode 100644 src/tool_urlglob.c create mode 100644 src/tool_urlglob.h create mode 100644 src/tool_util.c create mode 100644 src/tool_util.h create mode 100644 src/tool_version.h create mode 100644 src/tool_vms.c create mode 100644 src/tool_vms.h create mode 100644 src/tool_writeout.c create mode 100644 src/tool_writeout.h create mode 100644 src/tool_xattr.c create mode 100644 src/tool_xattr.h create mode 100644 tests/.gitignore create mode 100644 tests/CMakeLists.txt create mode 100644 tests/FILEFORMAT create mode 100644 tests/Makefile.am create mode 100644 tests/README create mode 100644 tests/certs/EdelCurlRoot-ca.cacert create mode 100644 tests/certs/EdelCurlRoot-ca.cnf create mode 100644 tests/certs/EdelCurlRoot-ca.crt create mode 100644 tests/certs/EdelCurlRoot-ca.csr create mode 100644 tests/certs/EdelCurlRoot-ca.der create mode 100644 tests/certs/EdelCurlRoot-ca.key create mode 100644 tests/certs/EdelCurlRoot-ca.prm create mode 100644 tests/certs/Makefile.am create mode 100644 tests/certs/Server-localhost-firstSAN-sv.crl create mode 100644 tests/certs/Server-localhost-firstSAN-sv.crt create mode 100644 tests/certs/Server-localhost-firstSAN-sv.csr create mode 100644 tests/certs/Server-localhost-firstSAN-sv.der create mode 100644 tests/certs/Server-localhost-firstSAN-sv.dhp create mode 100644 tests/certs/Server-localhost-firstSAN-sv.key create mode 100644 tests/certs/Server-localhost-firstSAN-sv.pem create mode 100644 tests/certs/Server-localhost-firstSAN-sv.prm create mode 100644 tests/certs/Server-localhost-firstSAN-sv.pub.der create mode 100644 tests/certs/Server-localhost-firstSAN-sv.pub.pem create mode 100644 tests/certs/Server-localhost-lastSAN-sv.crl create mode 100644 tests/certs/Server-localhost-lastSAN-sv.crt create mode 100644 tests/certs/Server-localhost-lastSAN-sv.csr create mode 100644 tests/certs/Server-localhost-lastSAN-sv.der create mode 100644 tests/certs/Server-localhost-lastSAN-sv.dhp create mode 100644 tests/certs/Server-localhost-lastSAN-sv.key create mode 100644 tests/certs/Server-localhost-lastSAN-sv.pem create mode 100644 tests/certs/Server-localhost-lastSAN-sv.prm create mode 100644 tests/certs/Server-localhost-lastSAN-sv.pub.der create mode 100644 tests/certs/Server-localhost-lastSAN-sv.pub.pem create mode 100644 tests/certs/Server-localhost-sv.crl create mode 100644 tests/certs/Server-localhost-sv.crt create mode 100644 tests/certs/Server-localhost-sv.csr create mode 100644 tests/certs/Server-localhost-sv.der create mode 100644 tests/certs/Server-localhost-sv.dhp create mode 100644 tests/certs/Server-localhost-sv.key create mode 100644 tests/certs/Server-localhost-sv.pem create mode 100644 tests/certs/Server-localhost-sv.prm create mode 100644 tests/certs/Server-localhost-sv.pub.der create mode 100644 tests/certs/Server-localhost-sv.pub.pem create mode 100644 tests/certs/Server-localhost.nn-sv.crl create mode 100644 tests/certs/Server-localhost.nn-sv.crt create mode 100644 tests/certs/Server-localhost.nn-sv.csr create mode 100644 tests/certs/Server-localhost.nn-sv.der create mode 100644 tests/certs/Server-localhost.nn-sv.dhp create mode 100644 tests/certs/Server-localhost.nn-sv.key create mode 100644 tests/certs/Server-localhost.nn-sv.pem create mode 100644 tests/certs/Server-localhost.nn-sv.prm create mode 100644 tests/certs/Server-localhost.nn-sv.pub.der create mode 100644 tests/certs/Server-localhost.nn-sv.pub.pem create mode 100644 tests/certs/Server-localhost0h-sv.crl create mode 100644 tests/certs/Server-localhost0h-sv.crt create mode 100644 tests/certs/Server-localhost0h-sv.csr create mode 100644 tests/certs/Server-localhost0h-sv.der create mode 100644 tests/certs/Server-localhost0h-sv.dhp create mode 100644 tests/certs/Server-localhost0h-sv.key create mode 100644 tests/certs/Server-localhost0h-sv.pem create mode 100644 tests/certs/Server-localhost0h-sv.prm create mode 100644 tests/certs/Server-localhost0h-sv.pub.der create mode 100644 tests/certs/Server-localhost0h-sv.pub.pem create mode 100644 tests/certs/scripts/Makefile.am create mode 100755 tests/certs/scripts/genroot.sh create mode 100755 tests/certs/scripts/genserv.sh create mode 100644 tests/certs/srp-verifier-conf create mode 100644 tests/certs/srp-verifier-db create mode 100755 tests/convsrctest.pl create mode 100755 tests/curl_test_data.py create mode 100644 tests/data/.gitattributes create mode 100644 tests/data/.gitignore create mode 100644 tests/data/CMakeLists.txt create mode 100644 tests/data/DISABLED create mode 100644 tests/data/Makefile.am create mode 100644 tests/data/Makefile.inc create mode 100644 tests/data/test1 create mode 100644 tests/data/test10 create mode 100644 tests/data/test100 create mode 100644 tests/data/test1000 create mode 100644 tests/data/test1001 create mode 100644 tests/data/test1002 create mode 100644 tests/data/test1003 create mode 100644 tests/data/test1004 create mode 100644 tests/data/test1005 create mode 100644 tests/data/test1006 create mode 100644 tests/data/test1007 create mode 100644 tests/data/test1008 create mode 100644 tests/data/test1009 create mode 100644 tests/data/test101 create mode 100644 tests/data/test1010 create mode 100644 tests/data/test1011 create mode 100644 tests/data/test1012 create mode 100644 tests/data/test1013 create mode 100644 tests/data/test1014 create mode 100644 tests/data/test1015 create mode 100644 tests/data/test1016 create mode 100644 tests/data/test1017 create mode 100644 tests/data/test1018 create mode 100644 tests/data/test1019 create mode 100644 tests/data/test102 create mode 100644 tests/data/test1020 create mode 100644 tests/data/test1021 create mode 100644 tests/data/test1022 create mode 100644 tests/data/test1023 create mode 100644 tests/data/test1024 create mode 100644 tests/data/test1025 create mode 100644 tests/data/test1026 create mode 100644 tests/data/test1027 create mode 100644 tests/data/test1028 create mode 100644 tests/data/test1029 create mode 100644 tests/data/test103 create mode 100644 tests/data/test1030 create mode 100644 tests/data/test1031 create mode 100644 tests/data/test1032 create mode 100644 tests/data/test1033 create mode 100644 tests/data/test1034 create mode 100644 tests/data/test1035 create mode 100644 tests/data/test1036 create mode 100644 tests/data/test1037 create mode 100644 tests/data/test1038 create mode 100644 tests/data/test1039 create mode 100644 tests/data/test104 create mode 100644 tests/data/test1040 create mode 100644 tests/data/test1041 create mode 100644 tests/data/test1042 create mode 100644 tests/data/test1043 create mode 100644 tests/data/test1044 create mode 100644 tests/data/test1045 create mode 100644 tests/data/test1046 create mode 100644 tests/data/test1047 create mode 100644 tests/data/test1048 create mode 100644 tests/data/test1049 create mode 100644 tests/data/test105 create mode 100644 tests/data/test1050 create mode 100644 tests/data/test1051 create mode 100644 tests/data/test1052 create mode 100644 tests/data/test1053 create mode 100644 tests/data/test1054 create mode 100644 tests/data/test1055 create mode 100644 tests/data/test1056 create mode 100644 tests/data/test1057 create mode 100644 tests/data/test1058 create mode 100644 tests/data/test1059 create mode 100644 tests/data/test106 create mode 100644 tests/data/test1060 create mode 100644 tests/data/test1061 create mode 100644 tests/data/test1062 create mode 100644 tests/data/test1063 create mode 100644 tests/data/test1064 create mode 100644 tests/data/test1065 create mode 100644 tests/data/test1066 create mode 100644 tests/data/test1067 create mode 100644 tests/data/test1068 create mode 100644 tests/data/test1069 create mode 100644 tests/data/test107 create mode 100644 tests/data/test1070 create mode 100644 tests/data/test1071 create mode 100644 tests/data/test1072 create mode 100644 tests/data/test1073 create mode 100644 tests/data/test1074 create mode 100644 tests/data/test1075 create mode 100644 tests/data/test1076 create mode 100644 tests/data/test1077 create mode 100644 tests/data/test1078 create mode 100644 tests/data/test1079 create mode 100644 tests/data/test108 create mode 100644 tests/data/test1080 create mode 100644 tests/data/test1081 create mode 100644 tests/data/test1082 create mode 100644 tests/data/test1083 create mode 100644 tests/data/test1084 create mode 100644 tests/data/test1085 create mode 100644 tests/data/test1086 create mode 100644 tests/data/test1087 create mode 100644 tests/data/test1088 create mode 100644 tests/data/test1089 create mode 100644 tests/data/test109 create mode 100644 tests/data/test1090 create mode 100644 tests/data/test1091 create mode 100644 tests/data/test1092 create mode 100644 tests/data/test1093 create mode 100644 tests/data/test1094 create mode 100644 tests/data/test1095 create mode 100644 tests/data/test1096 create mode 100644 tests/data/test1097 create mode 100644 tests/data/test1098 create mode 100644 tests/data/test1099 create mode 100644 tests/data/test11 create mode 100644 tests/data/test110 create mode 100644 tests/data/test1100 create mode 100644 tests/data/test1101 create mode 100644 tests/data/test1102 create mode 100644 tests/data/test1103 create mode 100644 tests/data/test1104 create mode 100644 tests/data/test1105 create mode 100644 tests/data/test1106 create mode 100644 tests/data/test1107 create mode 100644 tests/data/test1108 create mode 100644 tests/data/test1109 create mode 100644 tests/data/test111 create mode 100644 tests/data/test1110 create mode 100644 tests/data/test1111 create mode 100644 tests/data/test1112 create mode 100644 tests/data/test1113 create mode 100644 tests/data/test1114 create mode 100644 tests/data/test1115 create mode 100644 tests/data/test1116 create mode 100644 tests/data/test1117 create mode 100644 tests/data/test1118 create mode 100644 tests/data/test1119 create mode 100644 tests/data/test112 create mode 100644 tests/data/test1120 create mode 100644 tests/data/test1121 create mode 100644 tests/data/test1122 create mode 100644 tests/data/test1123 create mode 100644 tests/data/test1124 create mode 100644 tests/data/test1125 create mode 100644 tests/data/test1126 create mode 100644 tests/data/test1127 create mode 100644 tests/data/test1128 create mode 100644 tests/data/test1129 create mode 100644 tests/data/test113 create mode 100644 tests/data/test1130 create mode 100644 tests/data/test1131 create mode 100644 tests/data/test1132 create mode 100644 tests/data/test1133 create mode 100644 tests/data/test1134 create mode 100644 tests/data/test1135 create mode 100644 tests/data/test1136 create mode 100644 tests/data/test1137 create mode 100644 tests/data/test1138 create mode 100644 tests/data/test1139 create mode 100644 tests/data/test114 create mode 100644 tests/data/test1140 create mode 100644 tests/data/test1141 create mode 100644 tests/data/test1142 create mode 100644 tests/data/test1143 create mode 100644 tests/data/test1144 create mode 100644 tests/data/test1145 create mode 100644 tests/data/test1146 create mode 100644 tests/data/test1147 create mode 100644 tests/data/test1148 create mode 100644 tests/data/test1149 create mode 100644 tests/data/test115 create mode 100644 tests/data/test1150 create mode 100644 tests/data/test1151 create mode 100644 tests/data/test1152 create mode 100644 tests/data/test1153 create mode 100644 tests/data/test1154 create mode 100644 tests/data/test1155 create mode 100644 tests/data/test1156 create mode 100644 tests/data/test116 create mode 100644 tests/data/test1160 create mode 100644 tests/data/test1161 create mode 100644 tests/data/test1162 create mode 100644 tests/data/test1163 create mode 100644 tests/data/test1164 create mode 100644 tests/data/test117 create mode 100644 tests/data/test1170 create mode 100644 tests/data/test1171 create mode 100644 tests/data/test118 create mode 100644 tests/data/test119 create mode 100644 tests/data/test12 create mode 100644 tests/data/test120 create mode 100644 tests/data/test1200 create mode 100644 tests/data/test1201 create mode 100644 tests/data/test1202 create mode 100644 tests/data/test1203 create mode 100644 tests/data/test1204 create mode 100644 tests/data/test1205 create mode 100644 tests/data/test1206 create mode 100644 tests/data/test1207 create mode 100644 tests/data/test1208 create mode 100644 tests/data/test1209 create mode 100644 tests/data/test121 create mode 100644 tests/data/test1210 create mode 100644 tests/data/test1211 create mode 100644 tests/data/test1212 create mode 100644 tests/data/test1213 create mode 100644 tests/data/test1214 create mode 100644 tests/data/test1215 create mode 100644 tests/data/test1216 create mode 100644 tests/data/test1217 create mode 100644 tests/data/test1218 create mode 100644 tests/data/test1219 create mode 100644 tests/data/test122 create mode 100644 tests/data/test1220 create mode 100644 tests/data/test1221 create mode 100644 tests/data/test1222 create mode 100644 tests/data/test1223 create mode 100644 tests/data/test1224 create mode 100644 tests/data/test1225 create mode 100644 tests/data/test1226 create mode 100644 tests/data/test1227 create mode 100644 tests/data/test1228 create mode 100644 tests/data/test1229 create mode 100644 tests/data/test123 create mode 100644 tests/data/test1230 create mode 100644 tests/data/test1231 create mode 100644 tests/data/test1232 create mode 100644 tests/data/test1233 create mode 100644 tests/data/test1234 create mode 100644 tests/data/test1235 create mode 100644 tests/data/test1236 create mode 100644 tests/data/test1237 create mode 100644 tests/data/test1238 create mode 100644 tests/data/test1239 create mode 100644 tests/data/test124 create mode 100644 tests/data/test1240 create mode 100644 tests/data/test1241 create mode 100644 tests/data/test1242 create mode 100644 tests/data/test1243 create mode 100644 tests/data/test1244 create mode 100644 tests/data/test1245 create mode 100644 tests/data/test1246 create mode 100644 tests/data/test1247 create mode 100644 tests/data/test1248 create mode 100644 tests/data/test1249 create mode 100644 tests/data/test125 create mode 100644 tests/data/test1250 create mode 100644 tests/data/test1251 create mode 100644 tests/data/test1252 create mode 100644 tests/data/test1253 create mode 100644 tests/data/test1254 create mode 100644 tests/data/test1255 create mode 100644 tests/data/test1256 create mode 100644 tests/data/test1257 create mode 100644 tests/data/test1258 create mode 100644 tests/data/test1259 create mode 100644 tests/data/test126 create mode 100644 tests/data/test1260 create mode 100644 tests/data/test1261 create mode 100644 tests/data/test1262 create mode 100644 tests/data/test1263 create mode 100644 tests/data/test1264 create mode 100644 tests/data/test1265 create mode 100644 tests/data/test127 create mode 100644 tests/data/test128 create mode 100644 tests/data/test1280 create mode 100644 tests/data/test1281 create mode 100644 tests/data/test1282 create mode 100644 tests/data/test1283 create mode 100644 tests/data/test1284 create mode 100644 tests/data/test1285 create mode 100644 tests/data/test1286 create mode 100644 tests/data/test1287 create mode 100644 tests/data/test1288 create mode 100644 tests/data/test1289 create mode 100644 tests/data/test129 create mode 100644 tests/data/test1290 create mode 100644 tests/data/test1291 create mode 100644 tests/data/test1292 create mode 100644 tests/data/test1298 create mode 100644 tests/data/test1299 create mode 100644 tests/data/test13 create mode 100644 tests/data/test130 create mode 100644 tests/data/test1300 create mode 100644 tests/data/test1301 create mode 100644 tests/data/test1302 create mode 100644 tests/data/test1303 create mode 100644 tests/data/test1304 create mode 100644 tests/data/test1305 create mode 100644 tests/data/test1306 create mode 100644 tests/data/test1307 create mode 100644 tests/data/test1308 create mode 100644 tests/data/test1309 create mode 100644 tests/data/test131 create mode 100644 tests/data/test1310 create mode 100644 tests/data/test1311 create mode 100644 tests/data/test1312 create mode 100644 tests/data/test1313 create mode 100644 tests/data/test1314 create mode 100644 tests/data/test1315 create mode 100644 tests/data/test1316 create mode 100644 tests/data/test1317 create mode 100644 tests/data/test1318 create mode 100644 tests/data/test1319 create mode 100644 tests/data/test132 create mode 100644 tests/data/test1320 create mode 100644 tests/data/test1321 create mode 100644 tests/data/test1322 create mode 100644 tests/data/test1323 create mode 100644 tests/data/test1324 create mode 100644 tests/data/test1325 create mode 100644 tests/data/test1326 create mode 100644 tests/data/test1327 create mode 100644 tests/data/test1328 create mode 100644 tests/data/test1329 create mode 100644 tests/data/test133 create mode 100644 tests/data/test1330 create mode 100644 tests/data/test1331 create mode 100644 tests/data/test1332 create mode 100644 tests/data/test1333 create mode 100644 tests/data/test1334 create mode 100644 tests/data/test1335 create mode 100644 tests/data/test1336 create mode 100644 tests/data/test1337 create mode 100644 tests/data/test1338 create mode 100644 tests/data/test1339 create mode 100644 tests/data/test134 create mode 100644 tests/data/test1340 create mode 100644 tests/data/test1341 create mode 100644 tests/data/test1342 create mode 100644 tests/data/test1343 create mode 100644 tests/data/test1344 create mode 100644 tests/data/test1345 create mode 100644 tests/data/test1346 create mode 100644 tests/data/test1347 create mode 100644 tests/data/test1348 create mode 100644 tests/data/test1349 create mode 100644 tests/data/test135 create mode 100644 tests/data/test1350 create mode 100644 tests/data/test1351 create mode 100644 tests/data/test1352 create mode 100644 tests/data/test1353 create mode 100644 tests/data/test1354 create mode 100644 tests/data/test1355 create mode 100644 tests/data/test1356 create mode 100644 tests/data/test1357 create mode 100644 tests/data/test1358 create mode 100644 tests/data/test1359 create mode 100644 tests/data/test136 create mode 100644 tests/data/test1360 create mode 100644 tests/data/test1361 create mode 100644 tests/data/test1362 create mode 100644 tests/data/test1363 create mode 100644 tests/data/test1364 create mode 100644 tests/data/test1365 create mode 100644 tests/data/test1366 create mode 100644 tests/data/test1367 create mode 100644 tests/data/test1368 create mode 100644 tests/data/test1369 create mode 100644 tests/data/test137 create mode 100644 tests/data/test1370 create mode 100644 tests/data/test1371 create mode 100644 tests/data/test1372 create mode 100644 tests/data/test1373 create mode 100644 tests/data/test1374 create mode 100644 tests/data/test1375 create mode 100644 tests/data/test1376 create mode 100644 tests/data/test1377 create mode 100644 tests/data/test1378 create mode 100644 tests/data/test1379 create mode 100644 tests/data/test138 create mode 100644 tests/data/test1380 create mode 100644 tests/data/test1381 create mode 100644 tests/data/test1382 create mode 100644 tests/data/test1383 create mode 100644 tests/data/test1384 create mode 100644 tests/data/test1385 create mode 100644 tests/data/test1386 create mode 100644 tests/data/test1387 create mode 100644 tests/data/test1388 create mode 100644 tests/data/test1389 create mode 100644 tests/data/test139 create mode 100644 tests/data/test1390 create mode 100644 tests/data/test1391 create mode 100644 tests/data/test1392 create mode 100644 tests/data/test1393 create mode 100644 tests/data/test1394 create mode 100644 tests/data/test1395 create mode 100644 tests/data/test1396 create mode 100644 tests/data/test1397 create mode 100644 tests/data/test1398 create mode 100644 tests/data/test1399 create mode 100644 tests/data/test14 create mode 100644 tests/data/test140 create mode 100644 tests/data/test1400 create mode 100644 tests/data/test1401 create mode 100644 tests/data/test1402 create mode 100644 tests/data/test1403 create mode 100644 tests/data/test1404 create mode 100644 tests/data/test1405 create mode 100644 tests/data/test1406 create mode 100644 tests/data/test1407 create mode 100644 tests/data/test1408 create mode 100644 tests/data/test1409 create mode 100644 tests/data/test141 create mode 100644 tests/data/test1410 create mode 100644 tests/data/test1411 create mode 100644 tests/data/test1412 create mode 100644 tests/data/test1413 create mode 100644 tests/data/test1414 create mode 100644 tests/data/test1415 create mode 100644 tests/data/test1416 create mode 100644 tests/data/test1417 create mode 100644 tests/data/test1418 create mode 100644 tests/data/test1419 create mode 100644 tests/data/test142 create mode 100644 tests/data/test1420 create mode 100644 tests/data/test1421 create mode 100644 tests/data/test1422 create mode 100644 tests/data/test1423 create mode 100644 tests/data/test1424 create mode 100644 tests/data/test1425 create mode 100644 tests/data/test1426 create mode 100644 tests/data/test1427 create mode 100644 tests/data/test1428 create mode 100644 tests/data/test1429 create mode 100644 tests/data/test143 create mode 100644 tests/data/test1430 create mode 100644 tests/data/test1431 create mode 100644 tests/data/test1432 create mode 100644 tests/data/test1433 create mode 100644 tests/data/test1434 create mode 100644 tests/data/test1435 create mode 100644 tests/data/test1436 create mode 100644 tests/data/test1437 create mode 100644 tests/data/test1438 create mode 100644 tests/data/test1439 create mode 100644 tests/data/test144 create mode 100644 tests/data/test1440 create mode 100644 tests/data/test1441 create mode 100644 tests/data/test1442 create mode 100644 tests/data/test1443 create mode 100644 tests/data/test1444 create mode 100644 tests/data/test1445 create mode 100644 tests/data/test1446 create mode 100644 tests/data/test1447 create mode 100644 tests/data/test1448 create mode 100644 tests/data/test1449 create mode 100644 tests/data/test145 create mode 100644 tests/data/test1450 create mode 100644 tests/data/test1451 create mode 100644 tests/data/test1452 create mode 100644 tests/data/test1453 create mode 100644 tests/data/test1454 create mode 100644 tests/data/test1455 create mode 100644 tests/data/test1456 create mode 100644 tests/data/test146 create mode 100644 tests/data/test147 create mode 100644 tests/data/test148 create mode 100644 tests/data/test149 create mode 100644 tests/data/test15 create mode 100644 tests/data/test150 create mode 100644 tests/data/test1500 create mode 100644 tests/data/test1501 create mode 100644 tests/data/test1502 create mode 100644 tests/data/test1503 create mode 100644 tests/data/test1504 create mode 100644 tests/data/test1505 create mode 100644 tests/data/test1506 create mode 100644 tests/data/test1507 create mode 100644 tests/data/test1508 create mode 100644 tests/data/test1509 create mode 100644 tests/data/test151 create mode 100644 tests/data/test1510 create mode 100644 tests/data/test1511 create mode 100644 tests/data/test1512 create mode 100644 tests/data/test1513 create mode 100644 tests/data/test1514 create mode 100644 tests/data/test1515 create mode 100644 tests/data/test1516 create mode 100644 tests/data/test1517 create mode 100644 tests/data/test152 create mode 100644 tests/data/test1520 create mode 100644 tests/data/test1521 create mode 100644 tests/data/test1525 create mode 100644 tests/data/test1526 create mode 100644 tests/data/test1527 create mode 100644 tests/data/test1528 create mode 100644 tests/data/test1529 create mode 100644 tests/data/test153 create mode 100644 tests/data/test1530 create mode 100644 tests/data/test1531 create mode 100644 tests/data/test1532 create mode 100644 tests/data/test1533 create mode 100644 tests/data/test1534 create mode 100644 tests/data/test1535 create mode 100644 tests/data/test1536 create mode 100644 tests/data/test1537 create mode 100644 tests/data/test1538 create mode 100644 tests/data/test154 create mode 100644 tests/data/test1540 create mode 100644 tests/data/test155 create mode 100644 tests/data/test1550 create mode 100644 tests/data/test1551 create mode 100644 tests/data/test1552 create mode 100644 tests/data/test1553 create mode 100644 tests/data/test1554 create mode 100644 tests/data/test1555 create mode 100644 tests/data/test1556 create mode 100644 tests/data/test1557 create mode 100644 tests/data/test156 create mode 100644 tests/data/test157 create mode 100644 tests/data/test158 create mode 100644 tests/data/test159 create mode 100644 tests/data/test1590 create mode 100644 tests/data/test16 create mode 100644 tests/data/test160 create mode 100644 tests/data/test1600 create mode 100644 tests/data/test1601 create mode 100644 tests/data/test1602 create mode 100644 tests/data/test1603 create mode 100644 tests/data/test1604 create mode 100644 tests/data/test1605 create mode 100644 tests/data/test1606 create mode 100644 tests/data/test1607 create mode 100644 tests/data/test1608 create mode 100644 tests/data/test1609 create mode 100644 tests/data/test161 create mode 100644 tests/data/test162 create mode 100644 tests/data/test163 create mode 100644 tests/data/test164 create mode 100644 tests/data/test165 create mode 100644 tests/data/test166 create mode 100644 tests/data/test167 create mode 100644 tests/data/test168 create mode 100644 tests/data/test169 create mode 100644 tests/data/test17 create mode 100644 tests/data/test170 create mode 100644 tests/data/test1700 create mode 100644 tests/data/test1701 create mode 100644 tests/data/test1702 create mode 100644 tests/data/test171 create mode 100644 tests/data/test172 create mode 100644 tests/data/test173 create mode 100644 tests/data/test174 create mode 100644 tests/data/test175 create mode 100644 tests/data/test176 create mode 100644 tests/data/test177 create mode 100644 tests/data/test178 create mode 100644 tests/data/test179 create mode 100644 tests/data/test18 create mode 100644 tests/data/test180 create mode 100644 tests/data/test1800 create mode 100644 tests/data/test1801 create mode 100644 tests/data/test181 create mode 100644 tests/data/test182 create mode 100644 tests/data/test183 create mode 100644 tests/data/test184 create mode 100644 tests/data/test185 create mode 100644 tests/data/test186 create mode 100644 tests/data/test187 create mode 100644 tests/data/test188 create mode 100644 tests/data/test189 create mode 100644 tests/data/test19 create mode 100644 tests/data/test190 create mode 100644 tests/data/test1900 create mode 100644 tests/data/test1901 create mode 100644 tests/data/test1902 create mode 100644 tests/data/test1903 create mode 100644 tests/data/test1904 create mode 100644 tests/data/test191 create mode 100644 tests/data/test192 create mode 100644 tests/data/test193 create mode 100644 tests/data/test194 create mode 100644 tests/data/test195 create mode 100644 tests/data/test196 create mode 100644 tests/data/test197 create mode 100644 tests/data/test198 create mode 100644 tests/data/test199 create mode 100644 tests/data/test2 create mode 100644 tests/data/test20 create mode 100644 tests/data/test200 create mode 100644 tests/data/test2000 create mode 100644 tests/data/test2001 create mode 100644 tests/data/test2002 create mode 100644 tests/data/test2003 create mode 100644 tests/data/test2004 create mode 100644 tests/data/test2005 create mode 100644 tests/data/test2006 create mode 100644 tests/data/test2007 create mode 100644 tests/data/test2008 create mode 100644 tests/data/test2009 create mode 100644 tests/data/test201 create mode 100644 tests/data/test2010 create mode 100644 tests/data/test2011 create mode 100644 tests/data/test2012 create mode 100644 tests/data/test2013 create mode 100644 tests/data/test2014 create mode 100644 tests/data/test2015 create mode 100644 tests/data/test2016 create mode 100644 tests/data/test2017 create mode 100644 tests/data/test2018 create mode 100644 tests/data/test2019 create mode 100644 tests/data/test202 create mode 100644 tests/data/test2020 create mode 100644 tests/data/test2021 create mode 100644 tests/data/test2022 create mode 100644 tests/data/test2023 create mode 100644 tests/data/test2024 create mode 100644 tests/data/test2025 create mode 100644 tests/data/test2026 create mode 100644 tests/data/test2027 create mode 100644 tests/data/test2028 create mode 100644 tests/data/test2029 create mode 100644 tests/data/test203 create mode 100644 tests/data/test2030 create mode 100644 tests/data/test2031 create mode 100644 tests/data/test2032 create mode 100644 tests/data/test2033 create mode 100644 tests/data/test2034 create mode 100644 tests/data/test2035 create mode 100644 tests/data/test2036 create mode 100644 tests/data/test2037 create mode 100644 tests/data/test2038 create mode 100644 tests/data/test2039 create mode 100644 tests/data/test204 create mode 100644 tests/data/test2040 create mode 100644 tests/data/test2041 create mode 100644 tests/data/test2042 create mode 100644 tests/data/test2043 create mode 100644 tests/data/test2044 create mode 100644 tests/data/test2045 create mode 100644 tests/data/test2046 create mode 100644 tests/data/test2047 create mode 100644 tests/data/test2048 create mode 100644 tests/data/test2049 create mode 100644 tests/data/test205 create mode 100644 tests/data/test2050 create mode 100644 tests/data/test2051 create mode 100644 tests/data/test2052 create mode 100644 tests/data/test2053 create mode 100644 tests/data/test2054 create mode 100644 tests/data/test2055 create mode 100644 tests/data/test2056 create mode 100644 tests/data/test2057 create mode 100644 tests/data/test2058 create mode 100644 tests/data/test2059 create mode 100644 tests/data/test206 create mode 100644 tests/data/test2060 create mode 100644 tests/data/test2061 create mode 100644 tests/data/test2062 create mode 100644 tests/data/test2063 create mode 100644 tests/data/test2064 create mode 100644 tests/data/test2065 create mode 100644 tests/data/test2066 create mode 100644 tests/data/test2067 create mode 100644 tests/data/test2068 create mode 100644 tests/data/test2069 create mode 100644 tests/data/test207 create mode 100644 tests/data/test2070 create mode 100644 tests/data/test2071 create mode 100644 tests/data/test2072 create mode 100644 tests/data/test2073 create mode 100644 tests/data/test2074 create mode 100644 tests/data/test2075 create mode 100644 tests/data/test208 create mode 100644 tests/data/test209 create mode 100644 tests/data/test21 create mode 100644 tests/data/test210 create mode 100644 tests/data/test211 create mode 100644 tests/data/test212 create mode 100644 tests/data/test213 create mode 100644 tests/data/test214 create mode 100644 tests/data/test215 create mode 100644 tests/data/test216 create mode 100644 tests/data/test217 create mode 100644 tests/data/test218 create mode 100644 tests/data/test219 create mode 100644 tests/data/test22 create mode 100644 tests/data/test220 create mode 100644 tests/data/test221 create mode 100644 tests/data/test222 create mode 100644 tests/data/test223 create mode 100644 tests/data/test224 create mode 100644 tests/data/test225 create mode 100644 tests/data/test226 create mode 100644 tests/data/test227 create mode 100644 tests/data/test228 create mode 100644 tests/data/test229 create mode 100644 tests/data/test23 create mode 100644 tests/data/test230 create mode 100644 tests/data/test231 create mode 100644 tests/data/test232 create mode 100644 tests/data/test233 create mode 100644 tests/data/test234 create mode 100644 tests/data/test235 create mode 100644 tests/data/test236 create mode 100644 tests/data/test237 create mode 100644 tests/data/test238 create mode 100644 tests/data/test239 create mode 100644 tests/data/test24 create mode 100644 tests/data/test240 create mode 100644 tests/data/test241 create mode 100644 tests/data/test242 create mode 100644 tests/data/test243 create mode 100644 tests/data/test244 create mode 100644 tests/data/test245 create mode 100644 tests/data/test246 create mode 100644 tests/data/test247 create mode 100644 tests/data/test248 create mode 100644 tests/data/test249 create mode 100644 tests/data/test25 create mode 100644 tests/data/test250 create mode 100644 tests/data/test251 create mode 100644 tests/data/test252 create mode 100644 tests/data/test253 create mode 100644 tests/data/test254 create mode 100644 tests/data/test255 create mode 100644 tests/data/test256 create mode 100644 tests/data/test257 create mode 100644 tests/data/test258 create mode 100644 tests/data/test259 create mode 100644 tests/data/test26 create mode 100644 tests/data/test260 create mode 100644 tests/data/test261 create mode 100644 tests/data/test262 create mode 100644 tests/data/test263 create mode 100644 tests/data/test264 create mode 100644 tests/data/test265 create mode 100644 tests/data/test266 create mode 100644 tests/data/test267 create mode 100644 tests/data/test268 create mode 100644 tests/data/test269 create mode 100644 tests/data/test27 create mode 100644 tests/data/test270 create mode 100644 tests/data/test271 create mode 100644 tests/data/test272 create mode 100644 tests/data/test273 create mode 100644 tests/data/test274 create mode 100644 tests/data/test275 create mode 100644 tests/data/test276 create mode 100644 tests/data/test277 create mode 100644 tests/data/test278 create mode 100644 tests/data/test279 create mode 100644 tests/data/test28 create mode 100644 tests/data/test280 create mode 100644 tests/data/test281 create mode 100644 tests/data/test282 create mode 100644 tests/data/test283 create mode 100644 tests/data/test284 create mode 100644 tests/data/test285 create mode 100644 tests/data/test286 create mode 100644 tests/data/test287 create mode 100644 tests/data/test288 create mode 100644 tests/data/test289 create mode 100644 tests/data/test29 create mode 100644 tests/data/test290 create mode 100644 tests/data/test291 create mode 100644 tests/data/test292 create mode 100644 tests/data/test293 create mode 100644 tests/data/test294 create mode 100644 tests/data/test295 create mode 100644 tests/data/test296 create mode 100644 tests/data/test297 create mode 100644 tests/data/test298 create mode 100644 tests/data/test299 create mode 100644 tests/data/test3 create mode 100644 tests/data/test30 create mode 100644 tests/data/test300 create mode 100644 tests/data/test3000 create mode 100644 tests/data/test3001 create mode 100644 tests/data/test301 create mode 100644 tests/data/test302 create mode 100644 tests/data/test303 create mode 100644 tests/data/test304 create mode 100644 tests/data/test305 create mode 100644 tests/data/test306 create mode 100644 tests/data/test307 create mode 100644 tests/data/test308 create mode 100644 tests/data/test309 create mode 100644 tests/data/test31 create mode 100644 tests/data/test310 create mode 100644 tests/data/test311 create mode 100644 tests/data/test312 create mode 100644 tests/data/test313 create mode 100644 tests/data/test314 create mode 100644 tests/data/test315 create mode 100644 tests/data/test316 create mode 100644 tests/data/test317 create mode 100644 tests/data/test318 create mode 100644 tests/data/test319 create mode 100644 tests/data/test32 create mode 100644 tests/data/test320 create mode 100644 tests/data/test321 create mode 100644 tests/data/test322 create mode 100644 tests/data/test323 create mode 100644 tests/data/test324 create mode 100644 tests/data/test325 create mode 100644 tests/data/test326 create mode 100644 tests/data/test33 create mode 100644 tests/data/test34 create mode 100644 tests/data/test340 create mode 100644 tests/data/test35 create mode 100644 tests/data/test350 create mode 100644 tests/data/test351 create mode 100644 tests/data/test352 create mode 100644 tests/data/test353 create mode 100644 tests/data/test354 create mode 100644 tests/data/test36 create mode 100644 tests/data/test37 create mode 100644 tests/data/test38 create mode 100644 tests/data/test39 create mode 100644 tests/data/test393 create mode 100644 tests/data/test394 create mode 100644 tests/data/test395 create mode 100644 tests/data/test4 create mode 100644 tests/data/test40 create mode 100644 tests/data/test400 create mode 100644 tests/data/test401 create mode 100644 tests/data/test402 create mode 100644 tests/data/test403 create mode 100644 tests/data/test404 create mode 100644 tests/data/test405 create mode 100644 tests/data/test406 create mode 100644 tests/data/test407 create mode 100644 tests/data/test408 create mode 100644 tests/data/test409 create mode 100644 tests/data/test41 create mode 100644 tests/data/test42 create mode 100644 tests/data/test43 create mode 100644 tests/data/test44 create mode 100644 tests/data/test45 create mode 100644 tests/data/test46 create mode 100644 tests/data/test47 create mode 100644 tests/data/test48 create mode 100644 tests/data/test49 create mode 100644 tests/data/test5 create mode 100644 tests/data/test50 create mode 100644 tests/data/test500 create mode 100644 tests/data/test501 create mode 100644 tests/data/test502 create mode 100644 tests/data/test503 create mode 100644 tests/data/test504 create mode 100644 tests/data/test505 create mode 100644 tests/data/test506 create mode 100644 tests/data/test507 create mode 100644 tests/data/test508 create mode 100644 tests/data/test509 create mode 100644 tests/data/test51 create mode 100644 tests/data/test510 create mode 100644 tests/data/test511 create mode 100644 tests/data/test512 create mode 100644 tests/data/test513 create mode 100644 tests/data/test514 create mode 100644 tests/data/test515 create mode 100644 tests/data/test516 create mode 100644 tests/data/test517 create mode 100644 tests/data/test518 create mode 100644 tests/data/test519 create mode 100644 tests/data/test52 create mode 100644 tests/data/test520 create mode 100644 tests/data/test521 create mode 100644 tests/data/test522 create mode 100644 tests/data/test523 create mode 100644 tests/data/test524 create mode 100644 tests/data/test525 create mode 100644 tests/data/test526 create mode 100644 tests/data/test527 create mode 100644 tests/data/test528 create mode 100644 tests/data/test529 create mode 100644 tests/data/test53 create mode 100644 tests/data/test530 create mode 100644 tests/data/test531 create mode 100644 tests/data/test532 create mode 100644 tests/data/test533 create mode 100644 tests/data/test534 create mode 100644 tests/data/test535 create mode 100644 tests/data/test536 create mode 100644 tests/data/test537 create mode 100644 tests/data/test538 create mode 100644 tests/data/test539 create mode 100644 tests/data/test54 create mode 100644 tests/data/test540 create mode 100644 tests/data/test541 create mode 100644 tests/data/test542 create mode 100644 tests/data/test543 create mode 100644 tests/data/test544 create mode 100644 tests/data/test545 create mode 100644 tests/data/test546 create mode 100644 tests/data/test547 create mode 100644 tests/data/test548 create mode 100644 tests/data/test549 create mode 100644 tests/data/test55 create mode 100644 tests/data/test550 create mode 100644 tests/data/test551 create mode 100644 tests/data/test552 create mode 100644 tests/data/test553 create mode 100644 tests/data/test554 create mode 100644 tests/data/test555 create mode 100644 tests/data/test556 create mode 100644 tests/data/test557 create mode 100644 tests/data/test558 create mode 100644 tests/data/test559 create mode 100644 tests/data/test56 create mode 100644 tests/data/test560 create mode 100644 tests/data/test561 create mode 100644 tests/data/test562 create mode 100644 tests/data/test563 create mode 100644 tests/data/test564 create mode 100644 tests/data/test565 create mode 100644 tests/data/test566 create mode 100644 tests/data/test567 create mode 100644 tests/data/test568 create mode 100644 tests/data/test569 create mode 100644 tests/data/test57 create mode 100644 tests/data/test570 create mode 100644 tests/data/test571 create mode 100644 tests/data/test572 create mode 100644 tests/data/test573 create mode 100644 tests/data/test574 create mode 100644 tests/data/test575 create mode 100644 tests/data/test576 create mode 100644 tests/data/test577 create mode 100644 tests/data/test578 create mode 100644 tests/data/test579 create mode 100644 tests/data/test58 create mode 100644 tests/data/test580 create mode 100644 tests/data/test581 create mode 100644 tests/data/test582 create mode 100644 tests/data/test583 create mode 100644 tests/data/test584 create mode 100644 tests/data/test585 create mode 100644 tests/data/test586 create mode 100644 tests/data/test587 create mode 100644 tests/data/test588 create mode 100644 tests/data/test589 create mode 100644 tests/data/test59 create mode 100644 tests/data/test590 create mode 100644 tests/data/test591 create mode 100644 tests/data/test592 create mode 100644 tests/data/test593 create mode 100644 tests/data/test594 create mode 100644 tests/data/test595 create mode 100644 tests/data/test596 create mode 100644 tests/data/test597 create mode 100644 tests/data/test598 create mode 100644 tests/data/test599 create mode 100644 tests/data/test6 create mode 100644 tests/data/test60 create mode 100644 tests/data/test600 create mode 100644 tests/data/test601 create mode 100644 tests/data/test602 create mode 100644 tests/data/test603 create mode 100644 tests/data/test604 create mode 100644 tests/data/test605 create mode 100644 tests/data/test606 create mode 100644 tests/data/test607 create mode 100644 tests/data/test608 create mode 100644 tests/data/test609 create mode 100644 tests/data/test61 create mode 100644 tests/data/test610 create mode 100644 tests/data/test611 create mode 100644 tests/data/test612 create mode 100644 tests/data/test613 create mode 100644 tests/data/test614 create mode 100644 tests/data/test615 create mode 100644 tests/data/test616 create mode 100644 tests/data/test617 create mode 100644 tests/data/test618 create mode 100644 tests/data/test619 create mode 100644 tests/data/test62 create mode 100644 tests/data/test620 create mode 100644 tests/data/test621 create mode 100644 tests/data/test622 create mode 100644 tests/data/test623 create mode 100644 tests/data/test624 create mode 100644 tests/data/test625 create mode 100644 tests/data/test626 create mode 100644 tests/data/test627 create mode 100644 tests/data/test628 create mode 100644 tests/data/test629 create mode 100644 tests/data/test63 create mode 100644 tests/data/test630 create mode 100644 tests/data/test631 create mode 100644 tests/data/test632 create mode 100644 tests/data/test633 create mode 100644 tests/data/test634 create mode 100644 tests/data/test635 create mode 100644 tests/data/test636 create mode 100644 tests/data/test637 create mode 100644 tests/data/test638 create mode 100644 tests/data/test639 create mode 100644 tests/data/test64 create mode 100644 tests/data/test640 create mode 100644 tests/data/test641 create mode 100644 tests/data/test642 create mode 100644 tests/data/test643 create mode 100644 tests/data/test644 create mode 100644 tests/data/test645 create mode 100644 tests/data/test646 create mode 100644 tests/data/test647 create mode 100644 tests/data/test648 create mode 100644 tests/data/test649 create mode 100644 tests/data/test65 create mode 100644 tests/data/test650 create mode 100644 tests/data/test651 create mode 100644 tests/data/test652 create mode 100644 tests/data/test653 create mode 100644 tests/data/test654 create mode 100644 tests/data/test655 create mode 100644 tests/data/test66 create mode 100644 tests/data/test67 create mode 100644 tests/data/test68 create mode 100644 tests/data/test69 create mode 100644 tests/data/test7 create mode 100644 tests/data/test70 create mode 100644 tests/data/test700 create mode 100644 tests/data/test701 create mode 100644 tests/data/test702 create mode 100644 tests/data/test703 create mode 100644 tests/data/test704 create mode 100644 tests/data/test705 create mode 100644 tests/data/test706 create mode 100644 tests/data/test707 create mode 100644 tests/data/test708 create mode 100644 tests/data/test709 create mode 100644 tests/data/test71 create mode 100644 tests/data/test710 create mode 100644 tests/data/test711 create mode 100644 tests/data/test712 create mode 100644 tests/data/test713 create mode 100644 tests/data/test714 create mode 100644 tests/data/test715 create mode 100644 tests/data/test72 create mode 100644 tests/data/test73 create mode 100644 tests/data/test74 create mode 100644 tests/data/test75 create mode 100644 tests/data/test76 create mode 100644 tests/data/test77 create mode 100644 tests/data/test78 create mode 100644 tests/data/test79 create mode 100644 tests/data/test8 create mode 100644 tests/data/test80 create mode 100644 tests/data/test800 create mode 100644 tests/data/test801 create mode 100644 tests/data/test802 create mode 100644 tests/data/test803 create mode 100644 tests/data/test804 create mode 100644 tests/data/test805 create mode 100644 tests/data/test806 create mode 100644 tests/data/test807 create mode 100644 tests/data/test808 create mode 100644 tests/data/test809 create mode 100644 tests/data/test81 create mode 100644 tests/data/test810 create mode 100644 tests/data/test811 create mode 100644 tests/data/test812 create mode 100644 tests/data/test813 create mode 100644 tests/data/test814 create mode 100644 tests/data/test815 create mode 100644 tests/data/test816 create mode 100644 tests/data/test817 create mode 100644 tests/data/test818 create mode 100644 tests/data/test819 create mode 100644 tests/data/test82 create mode 100644 tests/data/test820 create mode 100644 tests/data/test821 create mode 100644 tests/data/test822 create mode 100644 tests/data/test823 create mode 100644 tests/data/test824 create mode 100644 tests/data/test825 create mode 100644 tests/data/test826 create mode 100644 tests/data/test827 create mode 100644 tests/data/test828 create mode 100644 tests/data/test829 create mode 100644 tests/data/test83 create mode 100644 tests/data/test830 create mode 100644 tests/data/test831 create mode 100644 tests/data/test832 create mode 100644 tests/data/test833 create mode 100644 tests/data/test834 create mode 100644 tests/data/test835 create mode 100644 tests/data/test836 create mode 100644 tests/data/test837 create mode 100644 tests/data/test838 create mode 100644 tests/data/test839 create mode 100644 tests/data/test84 create mode 100644 tests/data/test840 create mode 100644 tests/data/test841 create mode 100644 tests/data/test842 create mode 100644 tests/data/test843 create mode 100644 tests/data/test844 create mode 100644 tests/data/test845 create mode 100644 tests/data/test846 create mode 100644 tests/data/test85 create mode 100644 tests/data/test850 create mode 100644 tests/data/test851 create mode 100644 tests/data/test852 create mode 100644 tests/data/test853 create mode 100644 tests/data/test854 create mode 100644 tests/data/test855 create mode 100644 tests/data/test856 create mode 100644 tests/data/test857 create mode 100644 tests/data/test858 create mode 100644 tests/data/test859 create mode 100644 tests/data/test86 create mode 100644 tests/data/test860 create mode 100644 tests/data/test861 create mode 100644 tests/data/test862 create mode 100644 tests/data/test863 create mode 100644 tests/data/test864 create mode 100644 tests/data/test865 create mode 100644 tests/data/test866 create mode 100644 tests/data/test867 create mode 100644 tests/data/test868 create mode 100644 tests/data/test869 create mode 100644 tests/data/test87 create mode 100644 tests/data/test870 create mode 100644 tests/data/test871 create mode 100644 tests/data/test872 create mode 100644 tests/data/test873 create mode 100644 tests/data/test874 create mode 100644 tests/data/test875 create mode 100644 tests/data/test876 create mode 100644 tests/data/test877 create mode 100644 tests/data/test878 create mode 100644 tests/data/test879 create mode 100644 tests/data/test88 create mode 100644 tests/data/test880 create mode 100644 tests/data/test881 create mode 100644 tests/data/test882 create mode 100644 tests/data/test883 create mode 100644 tests/data/test884 create mode 100644 tests/data/test885 create mode 100644 tests/data/test886 create mode 100644 tests/data/test887 create mode 100644 tests/data/test888 create mode 100644 tests/data/test889 create mode 100644 tests/data/test89 create mode 100644 tests/data/test890 create mode 100644 tests/data/test891 create mode 100644 tests/data/test9 create mode 100644 tests/data/test90 create mode 100644 tests/data/test900 create mode 100644 tests/data/test901 create mode 100644 tests/data/test902 create mode 100644 tests/data/test903 create mode 100644 tests/data/test904 create mode 100644 tests/data/test905 create mode 100644 tests/data/test906 create mode 100644 tests/data/test907 create mode 100644 tests/data/test908 create mode 100644 tests/data/test909 create mode 100644 tests/data/test91 create mode 100644 tests/data/test910 create mode 100644 tests/data/test911 create mode 100644 tests/data/test912 create mode 100644 tests/data/test913 create mode 100644 tests/data/test914 create mode 100644 tests/data/test915 create mode 100644 tests/data/test916 create mode 100644 tests/data/test917 create mode 100644 tests/data/test918 create mode 100644 tests/data/test919 create mode 100644 tests/data/test92 create mode 100644 tests/data/test920 create mode 100644 tests/data/test921 create mode 100644 tests/data/test922 create mode 100644 tests/data/test923 create mode 100644 tests/data/test924 create mode 100644 tests/data/test925 create mode 100644 tests/data/test926 create mode 100644 tests/data/test927 create mode 100644 tests/data/test928 create mode 100644 tests/data/test929 create mode 100644 tests/data/test93 create mode 100644 tests/data/test930 create mode 100644 tests/data/test931 create mode 100644 tests/data/test932 create mode 100644 tests/data/test933 create mode 100644 tests/data/test934 create mode 100644 tests/data/test935 create mode 100644 tests/data/test936 create mode 100644 tests/data/test937 create mode 100644 tests/data/test938 create mode 100644 tests/data/test939 create mode 100644 tests/data/test94 create mode 100644 tests/data/test940 create mode 100644 tests/data/test941 create mode 100644 tests/data/test942 create mode 100644 tests/data/test943 create mode 100644 tests/data/test944 create mode 100644 tests/data/test945 create mode 100644 tests/data/test946 create mode 100644 tests/data/test947 create mode 100644 tests/data/test948 create mode 100644 tests/data/test949 create mode 100644 tests/data/test95 create mode 100644 tests/data/test950 create mode 100644 tests/data/test951 create mode 100644 tests/data/test952 create mode 100644 tests/data/test96 create mode 100644 tests/data/test97 create mode 100644 tests/data/test98 create mode 100644 tests/data/test99 create mode 100755 tests/dictserver.py create mode 100644 tests/directories.pm create mode 100755 tests/extern-scan.pl create mode 100644 tests/ftp.pm create mode 100755 tests/ftpserver.pl create mode 100644 tests/fuzz/README create mode 100755 tests/fuzz/download_fuzzer.sh create mode 100644 tests/getpart.pm create mode 100755 tests/http2-server.pl create mode 100755 tests/http_pipe.py create mode 100755 tests/httpserver.pl create mode 100755 tests/keywords.pl create mode 100644 tests/libtest/.gitignore create mode 100644 tests/libtest/CMakeLists.txt create mode 100644 tests/libtest/Makefile.am create mode 100644 tests/libtest/Makefile.inc create mode 100644 tests/libtest/chkhostname.c create mode 100644 tests/libtest/first.c create mode 100644 tests/libtest/lib1156.c create mode 100644 tests/libtest/lib1500.c create mode 100644 tests/libtest/lib1501.c create mode 100644 tests/libtest/lib1502.c create mode 100644 tests/libtest/lib1506.c create mode 100644 tests/libtest/lib1507.c create mode 100644 tests/libtest/lib1508.c create mode 100644 tests/libtest/lib1509.c create mode 100644 tests/libtest/lib1510.c create mode 100644 tests/libtest/lib1511.c create mode 100644 tests/libtest/lib1512.c create mode 100644 tests/libtest/lib1513.c create mode 100644 tests/libtest/lib1514.c create mode 100644 tests/libtest/lib1515.c create mode 100644 tests/libtest/lib1517.c create mode 100644 tests/libtest/lib1520.c create mode 100644 tests/libtest/lib1525.c create mode 100644 tests/libtest/lib1526.c create mode 100644 tests/libtest/lib1527.c create mode 100644 tests/libtest/lib1528.c create mode 100644 tests/libtest/lib1529.c create mode 100644 tests/libtest/lib1530.c create mode 100644 tests/libtest/lib1531.c create mode 100644 tests/libtest/lib1532.c create mode 100644 tests/libtest/lib1533.c create mode 100644 tests/libtest/lib1534.c create mode 100644 tests/libtest/lib1535.c create mode 100644 tests/libtest/lib1536.c create mode 100644 tests/libtest/lib1537.c create mode 100644 tests/libtest/lib1538.c create mode 100644 tests/libtest/lib1540.c create mode 100644 tests/libtest/lib1550.c create mode 100644 tests/libtest/lib1551.c create mode 100644 tests/libtest/lib1552.c create mode 100644 tests/libtest/lib1553.c create mode 100644 tests/libtest/lib1554.c create mode 100644 tests/libtest/lib1555.c create mode 100644 tests/libtest/lib1556.c create mode 100644 tests/libtest/lib1557.c create mode 100644 tests/libtest/lib1900.c create mode 100644 tests/libtest/lib500.c create mode 100644 tests/libtest/lib501.c create mode 100644 tests/libtest/lib502.c create mode 100644 tests/libtest/lib503.c create mode 100644 tests/libtest/lib504.c create mode 100644 tests/libtest/lib505.c create mode 100644 tests/libtest/lib506.c create mode 100644 tests/libtest/lib507.c create mode 100644 tests/libtest/lib508.c create mode 100644 tests/libtest/lib509.c create mode 100644 tests/libtest/lib510.c create mode 100644 tests/libtest/lib511.c create mode 100644 tests/libtest/lib512.c create mode 100644 tests/libtest/lib513.c create mode 100644 tests/libtest/lib514.c create mode 100644 tests/libtest/lib515.c create mode 100644 tests/libtest/lib516.c create mode 100644 tests/libtest/lib517.c create mode 100644 tests/libtest/lib518.c create mode 100644 tests/libtest/lib519.c create mode 100644 tests/libtest/lib520.c create mode 100644 tests/libtest/lib521.c create mode 100644 tests/libtest/lib523.c create mode 100644 tests/libtest/lib524.c create mode 100644 tests/libtest/lib525.c create mode 100644 tests/libtest/lib526.c create mode 100644 tests/libtest/lib530.c create mode 100644 tests/libtest/lib533.c create mode 100644 tests/libtest/lib536.c create mode 100644 tests/libtest/lib537.c create mode 100644 tests/libtest/lib539.c create mode 100644 tests/libtest/lib540.c create mode 100644 tests/libtest/lib541.c create mode 100644 tests/libtest/lib542.c create mode 100644 tests/libtest/lib543.c create mode 100644 tests/libtest/lib544.c create mode 100644 tests/libtest/lib547.c create mode 100644 tests/libtest/lib549.c create mode 100644 tests/libtest/lib552.c create mode 100644 tests/libtest/lib553.c create mode 100644 tests/libtest/lib554.c create mode 100644 tests/libtest/lib555.c create mode 100644 tests/libtest/lib556.c create mode 100644 tests/libtest/lib557.c create mode 100644 tests/libtest/lib558.c create mode 100644 tests/libtest/lib559.c create mode 100644 tests/libtest/lib560.c create mode 100644 tests/libtest/lib562.c create mode 100644 tests/libtest/lib564.c create mode 100644 tests/libtest/lib566.c create mode 100644 tests/libtest/lib567.c create mode 100644 tests/libtest/lib568.c create mode 100644 tests/libtest/lib569.c create mode 100644 tests/libtest/lib570.c create mode 100644 tests/libtest/lib571.c create mode 100644 tests/libtest/lib572.c create mode 100644 tests/libtest/lib573.c create mode 100644 tests/libtest/lib574.c create mode 100644 tests/libtest/lib575.c create mode 100644 tests/libtest/lib576.c create mode 100644 tests/libtest/lib578.c create mode 100644 tests/libtest/lib579.c create mode 100644 tests/libtest/lib582.c create mode 100644 tests/libtest/lib583.c create mode 100644 tests/libtest/lib586.c create mode 100644 tests/libtest/lib589.c create mode 100644 tests/libtest/lib590.c create mode 100644 tests/libtest/lib591.c create mode 100644 tests/libtest/lib597.c create mode 100644 tests/libtest/lib598.c create mode 100644 tests/libtest/lib599.c create mode 100644 tests/libtest/lib643.c create mode 100644 tests/libtest/lib650.c create mode 100644 tests/libtest/lib651.c create mode 100644 tests/libtest/lib652.c create mode 100644 tests/libtest/lib653.c create mode 100644 tests/libtest/lib654.c create mode 100644 tests/libtest/lib655.c create mode 100644 tests/libtest/libauthretry.c create mode 100644 tests/libtest/libntlmconnect.c create mode 100755 tests/libtest/mk-lib1521.pl create mode 100755 tests/libtest/notexists.pl create mode 100644 tests/libtest/sethostname.c create mode 100644 tests/libtest/sethostname.h create mode 100644 tests/libtest/stub_gssapi.c create mode 100644 tests/libtest/stub_gssapi.h create mode 100644 tests/libtest/test.h create mode 100755 tests/libtest/test1013.pl create mode 100755 tests/libtest/test1022.pl create mode 100755 tests/libtest/test307.pl create mode 100755 tests/libtest/test610.pl create mode 100755 tests/libtest/test613.pl create mode 100755 tests/libtest/test75.pl create mode 100644 tests/libtest/testtrace.c create mode 100644 tests/libtest/testtrace.h create mode 100644 tests/libtest/testutil.c create mode 100644 tests/libtest/testutil.h create mode 100755 tests/manpage-scan.pl create mode 100755 tests/mem-include-scan.pl create mode 100755 tests/memanalyze.pl create mode 100755 tests/negtelnetserver.py create mode 100755 tests/nroff-scan.pl create mode 100644 tests/pathhelp.pm create mode 100644 tests/python_dependencies/impacket/__init__.py create mode 100644 tests/python_dependencies/impacket/nmb.py create mode 100644 tests/python_dependencies/impacket/nt_errors.py create mode 100644 tests/python_dependencies/impacket/ntlm.py create mode 100644 tests/python_dependencies/impacket/smb.py create mode 100644 tests/python_dependencies/impacket/smb3.py create mode 100644 tests/python_dependencies/impacket/smb3structs.py create mode 100644 tests/python_dependencies/impacket/smbserver.py create mode 100644 tests/python_dependencies/impacket/spnego.py create mode 100644 tests/python_dependencies/impacket/structure.py create mode 100644 tests/python_dependencies/impacket/uuid.py create mode 100644 tests/python_dependencies/impacket/version.py create mode 100755 tests/rtspserver.pl create mode 100644 tests/runtests.1 create mode 100755 tests/runtests.pl create mode 100755 tests/secureserver.pl create mode 100644 tests/server/.gitignore create mode 100644 tests/server/CMakeLists.txt create mode 100644 tests/server/Makefile.am create mode 100644 tests/server/Makefile.inc create mode 100755 tests/server/base64.pl create mode 100644 tests/server/fake_ntlm.c create mode 100644 tests/server/getpart.c create mode 100644 tests/server/getpart.h create mode 100644 tests/server/resolve.c create mode 100644 tests/server/rtspd.c create mode 100644 tests/server/server_setup.h create mode 100644 tests/server/server_sockaddr.h create mode 100644 tests/server/sockfilt.c create mode 100644 tests/server/sws.c create mode 100644 tests/server/testpart.c create mode 100644 tests/server/tftp.h create mode 100644 tests/server/tftpd.c create mode 100644 tests/server/util.c create mode 100644 tests/server/util.h create mode 100644 tests/serverhelp.pm create mode 100755 tests/smbserver.py create mode 100644 tests/sshhelp.pm create mode 100755 tests/sshserver.pl create mode 100644 tests/stunnel.pem create mode 100755 tests/symbol-scan.pl create mode 100644 tests/testcurl.1 create mode 100755 tests/testcurl.pl create mode 100755 tests/tftpserver.pl create mode 100644 tests/unit/.gitignore create mode 100644 tests/unit/CMakeLists.txt create mode 100644 tests/unit/Makefile.am create mode 100644 tests/unit/Makefile.inc create mode 100644 tests/unit/README create mode 100644 tests/unit/curlcheck.h create mode 100644 tests/unit/unit1300.c create mode 100644 tests/unit/unit1301.c create mode 100644 tests/unit/unit1302.c create mode 100644 tests/unit/unit1303.c create mode 100644 tests/unit/unit1304.c create mode 100644 tests/unit/unit1305.c create mode 100644 tests/unit/unit1307.c create mode 100644 tests/unit/unit1308.c create mode 100644 tests/unit/unit1309.c create mode 100644 tests/unit/unit1323.c create mode 100644 tests/unit/unit1330.c create mode 100644 tests/unit/unit1394.c create mode 100644 tests/unit/unit1395.c create mode 100644 tests/unit/unit1396.c create mode 100644 tests/unit/unit1397.c create mode 100644 tests/unit/unit1398.c create mode 100644 tests/unit/unit1399.c create mode 100644 tests/unit/unit1600.c create mode 100644 tests/unit/unit1601.c create mode 100644 tests/unit/unit1602.c create mode 100644 tests/unit/unit1603.c create mode 100644 tests/unit/unit1604.c create mode 100644 tests/unit/unit1605.c create mode 100644 tests/unit/unit1606.c create mode 100644 tests/unit/unit1607.c create mode 100644 tests/unit/unit1608.c create mode 100644 tests/unit/unit1609.c create mode 100644 tests/valgrind.pm create mode 100644 tests/valgrind.supp create mode 100644 winbuild/.gitignore create mode 100644 winbuild/BUILD.WINDOWS.txt create mode 100644 winbuild/Makefile.vc create mode 100644 winbuild/MakefileBuild.vc create mode 100755 winbuild/gen_resp_file.bat diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 00000000..ed91b128 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,10 @@ +;;; Directory Local Variables +;;; See Info node `(emacs) Directory Variables' for more information. + +((nil . ((indent-tabs-mode . nil) + (show-trailing-whitespace . t))) + (c-mode . ((c-basic-offset . 2) + )) + (c++-mode . ((c-basic-offset . 2) + )) + ) diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..429f8cde --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.dsw -crlf +buildconf eol=lf +configure.ac eol=lf +*.m4 eol=lf +*.in eol=lf +*.am eol=lf +*.sh eol=lf diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..bce89b44 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,23 @@ +How to contribute to curl +========================= + +Join the community +------------------ + + 1. Click 'watch' on the github repo + + 2. Subscribe to the suitable [mailing lists](https://curl.haxx.se/mail/) + +Read [CONTRIBUTE](../docs/CONTRIBUTE.md) +--------------------------------------- + +Send your suggestions using one of these methods: +------------------------------------------------- + + 1. in a mail to the mailing list + + 2. as a [pull request](https://github.com/curl/curl/pulls) + + 3. as an [issue](https://github.com/curl/curl/issues) + +/ The curl team! diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 00000000..a705e79e --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,16 @@ + + +### I did this + +### I expected the following + +### curl/libcurl version + +[curl -V output] + +### operating system diff --git a/.github/lock.yml b/.github/lock.yml new file mode 100644 index 00000000..66e79128 --- /dev/null +++ b/.github/lock.yml @@ -0,0 +1,8 @@ +# Configuration for lock-threads - https://github.com/dessant/lock-threads + +# Number of days of inactivity before a closed issue or pull request is locked +daysUntilLock: 90 +# Comment to post before locking. Set to `false` to disable +lockComment: false +# Limit to only `issues` or `pulls` +# only: issues diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..9bcd4eb1 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 180 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 14 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e567b38c --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +*.asc +*.dll +*.exe +*.exp +*.la +*.lib +*.lo +*.o +*.obj +*.pdb +*.pyc +*~ +.*.sw? +.cproject +.deps +.dirstamp +.libs +.project +.settings +/.vs +/build/ +/builds/ +__pycache__ +CHANGES.dist +Debug +INSTALL +Makefile +Makefile.in +Release +TAGS +aclocal.m4 +aclocal.m4.bak +autom4te.cache +compile +config.cache +config.guess +config.log +config.status +config.sub +configure +curl-*.tar.bz2 +curl-*.tar.gz +curl-*.tar.xz +curl-*.zip +curl-config +depcomp +install-sh +libcurl.pc +libtool +ltmain.sh +missing +mkinstalldirs +tags +test-driver +scripts/_curl +curl_fuzzer +curl_fuzzer_seed_corpus.zip +libstandaloneengine.a diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 00000000..bb6945f0 --- /dev/null +++ b/.lgtm.yml @@ -0,0 +1,10 @@ +extraction: + cpp: + prepare: + packages: # to avoid confusion with libopenafs-dev which also provides a des.h + - libssl-dev + after_prepare: # make sure lgtm.com doesn't use CMake (which generates and runs tests) + - rm -f CMakeLists.txt + - ./buildconf + configure: # enable as many optional features as possible + command: ./configure --enable-ares --with-libssh2 --with-gssapi --with-librtmp --with-libmetalink --with-libmetalink diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000..b1584e67 --- /dev/null +++ b/.mailmap @@ -0,0 +1,46 @@ +Guenter Knauf +Gisle Vanem +Gisle Vanem +Alessandro Ghedini +Alessandro Ghedini +Björn Stenberg +Björn Stenberg +Viktor Szakats +Daniel Gustafsson +Daniel Gustafsson +Linus Nielsen +Yamada Yasuharu +Ulion +Tim Rühsen +Steve Holme +Claes Jakobsson +Sergei Nikulov +Patrick Monnerat +Patrick Monnerat +Patrick Monnerat +Patrick Monnerat +Nick Zitzmann +Peter Wu +David Woodhouse +Marcel Raad +Marcel Raad +Marcel Raad +Anthony Bryan +Travis Burtrum +Dmitry Kostjuchenko +Richard Alcock +Richard Alcock +Jan Ehrhardt +Florin Petriuc +Pavel Pavlov +Jason Juang +Carlo Teubner +Joel Depooter +Sebastian Mundry +Rainer Canavan +Dan Fandrich +Henrik S. Gaßmann +Jiří Malák +Nick Zitzmann +Kees Dekker +Max Savenkov diff --git a/.travis-iconv-env.sh b/.travis-iconv-env.sh new file mode 100644 index 00000000..bb7dcf42 --- /dev/null +++ b/.travis-iconv-env.sh @@ -0,0 +1 @@ +export CPPFLAGS="-DCURL_DOES_CONVERSIONS -DHAVE_ICONV -DCURL_ICONV_CODESET_OF_HOST='\"ISO8859-1\"'" diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..0045c5e0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,341 @@ +language: c +sudo: required +cache: + directories: + - $HOME/libpsl-0.20.1 + - $HOME/mbedtls-mbedtls-2.8.0 + - $HOME/libidn2-2.0.4 + - $HOME/wolfssl-3.14.0-stable + +env: + global: + - LD_LIBRARY_PATH=/usr/local/lib + +addons: + apt: + config: + retries: true + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-6.0 + packages: + - cmake + - gcc-7 + - lcov + - clang-6.0 + - valgrind + - libev-dev + - libc-ares-dev + - g++-7 + - libstdc++-7-dev + - stunnel4 + - libidn2-0-dev + - libssh2-1-dev + - libssh-dev + - krb5-user + - autopoint # for libpsl that needs autoreconf that uses gettext that needs it + - libunistring-dev # for libidn2 needed by libpsl + - libnss3-dev + +matrix: + include: + - os: linux + compiler: gcc + dist: trusty + env: T=normal C="--with-gssapi --with-libssh2" + - os: linux + compiler: gcc + dist: trusty + env: T=normal C=--with-libssh + - os: linux + compiler: gcc + dist: trusty + env: T=normal C="--disable-http --disable-smtp --disable-imap" + - os: linux + compiler: gcc + dist: trusty + env: T=normal C="--enable-ares" + - os: linux + compiler: gcc + dist: trusty + env: T=normal BROTLI=yes + - os: linux + compiler: gcc + dist: trusty + env: T=novalgrind BORINGSSL=yes C="--with-ssl=$HOME/boringssl" LD_LIBRARY_PATH=/home/travis/boringssl/lib:/usr/local/lib + - os: linux + compiler: gcc + dist: trusty + env: T=debug-wolfssl C="--with-wolfssl --without-ssl" + - os: linux + compiler: clang + dist: trusty + env: T=debug + - os: linux + compiler: clang + dist: trusty + env: T=debug C="--with-mbedtls --without-ssl" + - os: linux + compiler: clang + dist: trusty + env: T=debug C="--disable-threaded-resolver" + - os: linux + compiler: clang + dist: trusty + env: T=debug C="--with-nss --without-ssl" NOTESTS=1 CPPFLAGS="-isystem /usr/include/nss" + - os: linux + compiler: gcc + dist: trusty + env: T=iconv + - os: osx + compiler: gcc + env: T=debug C=--with-libssh2 + - os: osx + compiler: gcc + env: T=debug C=--enable-ares + - os: osx + compiler: gcc + env: T=debug C="--with-ssl=/usr/local/opt/openssl --with-libmetalink" + - os: osx + compiler: gcc + env: T=debug C="--with-ssl=/usr/local/opt/libressl --with-libmetalink" + - os: osx + compiler: clang + env: T=debug C="--without-ssl --with-darwinssl --with-libmetalink" + - os: osx + compiler: clang + env: T=normal + - os: linux + compiler: gcc + dist: trusty + env: T=cmake + - os: linux + compiler: clang + dist: trusty + env: T=cmake + - os: linux + compiler: gcc + dist: trusty + env: T=coverage + - os: linux + compiler: gcc + dist: trusty + env: T=distcheck + - os: linux + compiler: clang + dist: trusty + env: T=fuzzer + +install: + - if [ "$T" = "coverage" ]; then pip2 install --user cpp-coveralls; fi + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update > /dev/null; fi + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew reinstall libtool > /dev/null; fi + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install rtmpdump libssh2 c-ares libmetalink libressl nghttp2 libmetalink; fi + - if [ $TRAVIS_OS_NAME = linux ]; then + curl -L https://github.com/nghttp2/nghttp2/releases/download/v1.24.0/nghttp2-1.24.0.tar.gz | + tar xzf - && + (cd nghttp2-1.24.0 && CXX="g++-7" ./configure --prefix=/usr --disable-threads --enable-app && make && sudo make install); + fi + +before_script: + - ./buildconf + - | + # No brotli package available for Trusty. Download & compile from source. + # Cannot be done in the install script because cmake is needed. + if [ "$TRAVIS_OS_NAME" = linux -a "$BROTLI" ]; then + curl -L https://github.com/google/brotli/archive/v1.0.1.tar.gz | + tar xzf - && + ( + cd brotli-1.0.1 && + cmake . -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_INSTALL_LIBDIR=/usr/lib && + make && + sudo make install + ) + fi + - | + if [ "$TRAVIS_OS_NAME" = linux -a "$BORINGSSL" ]; then + (cd $HOME && + git clone --depth=1 https://boringssl.googlesource.com/boringssl && + cd boringssl && + mkdir build && + cd build && + cmake -DCMAKE_BUILD_TYPE=release -DBUILD_SHARED_LIBS=1 .. && + make && + cd .. && + mkdir lib && + cd lib && + ln -s ../build/crypto/libcrypto.so . && + ln -s ../build/ssl/libssl.so . && + echo "BoringSSL lib dir: "`pwd` && + export LIBS=-lpthread ) + fi + - | + if [ $TRAVIS_OS_NAME = linux ]; then + if [ ! -e $HOME/libidn2-2.0.4/Makefile ]; then + (cd $HOME && \ + curl -LO https://ftp.gnu.org/gnu/libidn/libidn2-2.0.4.tar.gz && \ + tar -xzf libidn2-2.0.4.tar.gz && \ + cd libidn2-2.0.4 && \ + ./configure && \ + make) + fi + fi + - | + if [ $TRAVIS_OS_NAME = linux ]; then + if [ ! -e $HOME/libpsl-0.20.1/Makefile ]; then + (cd $HOME && \ + curl -LO https://github.com/rockdaboot/libpsl/releases/download/libpsl-0.20.1/libpsl-0.20.1.tar.gz && \ + tar -xzf libpsl-0.20.1.tar.gz && \ + cd libpsl-0.20.1 && \ + autoreconf -i && \ + ./configure && \ + make) + fi + fi + - | + if [ $TRAVIS_OS_NAME = linux ]; then + if [ ! -e $HOME/mbedtls-mbedtls-2.8.0/library/libmbedtls.a ]; then + (cd $HOME && \ + curl -LO https://github.com/ARMmbed/mbedtls/archive/mbedtls-2.8.0.tar.gz && \ + tar -xzf mbedtls-2.8.0.tar.gz && \ + cd mbedtls-mbedtls-2.8.0 && \ + cmake . -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_C_FLAGS=-fPIC && \ + make) + fi + fi + - | + if [ $TRAVIS_OS_NAME = linux ]; then + if [ ! -e $HOME/wolfssl-3.14.0-stable/Makefile ]; then + (cd $HOME && \ + curl -LO https://github.com/wolfSSL/wolfssl/archive/v3.14.0-stable.tar.gz && \ + tar -xzf v3.14.0-stable.tar.gz && \ + cd wolfssl-3.14.0-stable && \ + ./autogen.sh && \ + ./configure --enable-tls13 --enable-all && \ + touch wolfssl/wolfcrypt/fips.h && \ + make) + fi + fi + - | + if [ $TRAVIS_OS_NAME = linux ]; then + (cd $HOME/libidn2-2.0.4 && sudo make install) + (cd $HOME/libpsl-0.20.1 && sudo make install) + (cd $HOME/mbedtls-mbedtls-2.8.0 && sudo make install) + (cd $HOME/wolfssl-3.14.0-stable && sudo make install) + fi + +script: + - | + # Uncomment this when `coverage` runs on Trusty. + # set -eo pipefail + if [ "$T" = "coverage" ]; then + export CC="gcc-7" + ./configure --enable-debug --disable-shared --enable-code-coverage + make + make TFLAGS=-n test-nonflaky + make "TFLAGS=-n -e" test-nonflaky + tests="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 200 201 202 300 301 302 500 501 502 503 504 506 507 508 509 510 511 512 513 514 515 516 517 518 519 600 601 700 701 702 800 801 802 803 900 901 902 903 1000 1001 1002 1004 1100 1101 1200 1201 1302 1303 1304 1305 1306 1308 1400 1401 1402 1404 1450 1451 1452 1502 1507 1508 1600 1602 1603 1605 1700 1701 1702 2001 3000" + make "TFLAGS=-n -t $tests" test-nonflaky + coveralls --gcov /usr/bin/gcov-7 --gcov-options '\-lp' -i src -e lib -e tests -e docs -b $PWD/src + coveralls --gcov /usr/bin/gcov-7 --gcov-options '\-lp' -e src -i lib -e tests -e docs -b $PWD/lib + fi + - | + set -eo pipefail + if [ "$T" = "debug" ]; then + ./configure --enable-debug --enable-werror $C + make && make examples + if [ -z $NOTESTS ]; then + make TFLAGS=-n test-nonflaky + fi + fi + - | + set -eo pipefail + if [ "$T" = "debug-wolfssl" ]; then + ./configure --enable-debug --enable-werror $C + make + make "TFLAGS=-n !311 !313" test-nonflaky + fi + - | + set -eo pipefail + if [ "$T" = "novalgrind" ]; then + ./configure $C + make && make examples + make TFLAGS=-n test-nonflaky + fi + - | + set -eo pipefail + if [ "$T" = "normal" ]; then + ./configure --enable-warnings --enable-werror $C + make && make examples + make test-nonflaky + fi + - | + set -eo pipefail + if [ "$T" = "iconv" ]; then + source .travis-iconv-env.sh + ./configure --enable-debug --enable-werror $C + make && make examples + make TFLAGS=-n test-nonflaky + fi + - | + set -eo pipefail + if [ "$T" = "cmake" ]; then + mkdir build + cd build + cmake .. -DCURL_WERROR=ON + make + fi + - | + set -eo pipefail + if [ "$T" = "distcheck" ]; then + ./configure + make + ./maketgz 99.98.97 + # verify in-tree build - and install it + (tar xf curl-99.98.97.tar.gz && \ + cd curl-99.98.97 && \ + ./configure --prefix=$HOME/temp && \ + make && \ + make TFLAGS=1 test && \ + make install) + # basic check of the installed files + bash scripts/installcheck.sh $HOME/temp + rm -rf curl-99.98.97 + # verify out-of-tree build + (tar xf curl-99.98.97.tar.gz && \ + mkdir build && \ + cd build && \ + ../curl-99.98.97/configure && \ + make && \ + make TFLAGS=1 test) + # verify cmake build + rm -rf curl-99.98.97 + (tar xf curl-99.98.97.tar.gz && \ + cd curl-99.98.97 && \ + mkdir build && \ + cd build && \ + cmake .. && \ + make) + fi + - | + set -eo pipefail + if [ "$T" = "fuzzer" ]; then + # Download the fuzzer to a temporary folder + ./tests/fuzz/download_fuzzer.sh /tmp/curl_fuzzer + + export CURLSRC=$PWD + + # Run the mainline fuzzer test + pushd /tmp/curl_fuzzer + ./mainline.sh ${CURLSRC} + popd + fi + +# whitelist branches to avoid testing feature branches twice (as branch and as pull request) +branches: + only: + - master + +notifications: + email: false diff --git a/CHANGES b/CHANGES new file mode 100644 index 00000000..4d13ef69 --- /dev/null +++ b/CHANGES @@ -0,0 +1,7 @@ +See https://curl.haxx.se/changes.html for the edited and human readable online +version of what has changed over the years in different curl releases. + +Generate a CHANGES file like the one present in every release like this: + +$ git log --pretty=fuller --no-color --date=short --decorate=full | \ + ./scripts/log2changes.pl diff --git a/CMake/CMakeConfigurableFile.in b/CMake/CMakeConfigurableFile.in new file mode 100644 index 00000000..4cf74a12 --- /dev/null +++ b/CMake/CMakeConfigurableFile.in @@ -0,0 +1,2 @@ +@CMAKE_CONFIGURABLE_FILE_CONTENT@ + diff --git a/CMake/CurlSymbolHiding.cmake b/CMake/CurlSymbolHiding.cmake new file mode 100644 index 00000000..9f7d2963 --- /dev/null +++ b/CMake/CurlSymbolHiding.cmake @@ -0,0 +1,61 @@ +include(CheckCSourceCompiles) + +option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON) +mark_as_advanced(CURL_HIDDEN_SYMBOLS) + +if(CURL_HIDDEN_SYMBOLS) + set(SUPPORTS_SYMBOL_HIDING FALSE) + + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(SUPPORTS_SYMBOL_HIDING TRUE) + set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))") + set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden") + elseif(CMAKE_COMPILER_IS_GNUCC) + if(NOT CMAKE_VERSION VERSION_LESS 2.8.10) + set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION}) + else() + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion + OUTPUT_VARIABLE GCC_VERSION) + endif() + if(NOT GCC_VERSION VERSION_LESS 3.4) + # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact + set(SUPPORTS_SYMBOL_HIDING TRUE) + set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))") + set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) + set(SUPPORTS_SYMBOL_HIDING TRUE) + set(_SYMBOL_EXTERN "__global") + set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden") + elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0) + # note: this should probably just check for version 9.1.045 but I'm not 100% sure + # so let's to it the same way autotools do. + set(SUPPORTS_SYMBOL_HIDING TRUE) + set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))") + set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden") + check_c_source_compiles("#include + int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug) + if(NOT _no_bug) + set(SUPPORTS_SYMBOL_HIDING FALSE) + set(_SYMBOL_EXTERN "") + set(_CFLAG_SYMBOLS_HIDE "") + endif() + elseif(MSVC) + set(SUPPORTS_SYMBOL_HIDING TRUE) + endif() + + set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING}) +elseif(MSVC) + if(NOT CMAKE_VERSION VERSION_LESS 3.7) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken + set(HIDES_CURL_PRIVATE_SYMBOLS FALSE) + else() + message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.") + set(HIDES_CURL_PRIVATE_SYMBOLS TRUE) + endif() +elseif() + set(HIDES_CURL_PRIVATE_SYMBOLS FALSE) +endif() + +set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE}) +set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN}) diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c new file mode 100644 index 00000000..ab244ac3 --- /dev/null +++ b/CMake/CurlTests.c @@ -0,0 +1,551 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef TIME_WITH_SYS_TIME +/* Time with sys/time test */ + +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} + +#endif + +#ifdef HAVE_FCNTL_O_NONBLOCK + +/* headers for FCNTL_O_NONBLOCK test */ +#include +#include +#include +/* */ +#if defined(sun) || defined(__sun__) || \ + defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if defined(__SVR4) || defined(__srv4__) +# define PLATFORM_SOLARIS +# else +# define PLATFORM_SUNOS4 +# endif +#endif +#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41) +# define PLATFORM_AIX_V3 +#endif +/* */ +#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__) +#error "O_NONBLOCK does not work on this platform" +#endif + +int +main () +{ + /* O_NONBLOCK source test */ + int flags = 0; + if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK)) + return 1; + return 0; +} +#endif + +/* tests for gethostbyaddr_r or gethostbyname_r */ +#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \ + defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \ + defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \ + defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \ + defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \ + defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT) +# define _REENTRANT + /* no idea whether _REENTRANT is always set, just invent a new flag */ +# define TEST_GETHOSTBYFOO_REENTRANT +#endif +#if defined(HAVE_GETHOSTBYADDR_R_5) || \ + defined(HAVE_GETHOSTBYADDR_R_7) || \ + defined(HAVE_GETHOSTBYADDR_R_8) || \ + defined(HAVE_GETHOSTBYNAME_R_3) || \ + defined(HAVE_GETHOSTBYNAME_R_5) || \ + defined(HAVE_GETHOSTBYNAME_R_6) || \ + defined(TEST_GETHOSTBYFOO_REENTRANT) +#include +#include +int main(void) +{ + char *address = "example.com"; + int length = 0; + int type = 0; + struct hostent h; + int rc = 0; +#if defined(HAVE_GETHOSTBYADDR_R_5) || \ + defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \ + \ + defined(HAVE_GETHOSTBYNAME_R_3) || \ + defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) + struct hostent_data hdata; +#elif defined(HAVE_GETHOSTBYADDR_R_7) || \ + defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \ + defined(HAVE_GETHOSTBYADDR_R_8) || \ + defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \ + \ + defined(HAVE_GETHOSTBYNAME_R_5) || \ + defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \ + defined(HAVE_GETHOSTBYNAME_R_6) || \ + defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT) + char buffer[8192]; + int h_errnop; + struct hostent *hp; +#endif + +#ifndef gethostbyaddr_r + (void)gethostbyaddr_r; +#endif + +#if defined(HAVE_GETHOSTBYADDR_R_5) || \ + defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) + rc = gethostbyaddr_r(address, length, type, &h, &hdata); +#elif defined(HAVE_GETHOSTBYADDR_R_7) || \ + defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) + hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop); + (void)hp; +#elif defined(HAVE_GETHOSTBYADDR_R_8) || \ + defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) + rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop); +#endif + +#if defined(HAVE_GETHOSTBYNAME_R_3) || \ + defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) + rc = gethostbyname_r(address, &h, &hdata); +#elif defined(HAVE_GETHOSTBYNAME_R_5) || \ + defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) + rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop); + (void)hp; /* not used for test */ +#elif defined(HAVE_GETHOSTBYNAME_R_6) || \ + defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT) + rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop); +#endif + + (void)length; + (void)type; + (void)rc; + return 0; +} +#endif + +#ifdef HAVE_SOCKLEN_T +#ifdef _WIN32 +#include +#else +#include +#include +#endif +int +main () +{ +if ((socklen_t *) 0) + return 0; +if (sizeof (socklen_t)) + return 0; + ; + return 0; +} +#endif +#ifdef HAVE_IN_ADDR_T +#include +#include +#include + +int +main () +{ +if ((in_addr_t *) 0) + return 0; +if (sizeof (in_addr_t)) + return 0; + ; + return 0; +} +#endif + +#ifdef HAVE_BOOL_T +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDBOOL_H +#include +#endif +int +main () +{ +if (sizeof (bool *) ) + return 0; + ; + return 0; +} +#endif + +#ifdef STDC_HEADERS +#include +#include +#include +#include +int main() { return 0; } +#endif +#ifdef RETSIGTYPE_TEST +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ + return 0; +} +#endif +#ifdef HAVE_INET_NTOA_R_DECL +#include + +typedef void (*func_type)(); + +int main() +{ +#ifndef inet_ntoa_r + func_type func; + func = (func_type)inet_ntoa_r; +#endif + return 0; +} +#endif +#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT +#define _REENTRANT +#include + +typedef void (*func_type)(); + +int main() +{ +#ifndef inet_ntoa_r + func_type func; + func = (func_type)&inet_ntoa_r; +#endif + return 0; +} +#endif +#ifdef HAVE_GETADDRINFO +#include +#include +#include + +int main(void) { + struct addrinfo hints, *ai; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; +#ifndef getaddrinfo + (void)getaddrinfo; +#endif + error = getaddrinfo("127.0.0.1", "8080", &hints, &ai); + if (error) { + return 1; + } + return 0; +} +#endif +#ifdef HAVE_FILE_OFFSET_BITS +#ifdef _FILE_OFFSET_BITS +#undef _FILE_OFFSET_BITS +#endif +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int main () { ; return 0; } +#endif +#ifdef HAVE_IOCTLSOCKET +/* includes start */ +#ifdef HAVE_WINDOWS_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# ifdef HAVE_WINSOCK2_H +# include +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +#endif + +int +main () +{ + +/* ioctlsocket source code */ + int socket; + unsigned long flags = ioctlsocket(socket, FIONBIO, &flags); + + ; + return 0; +} + +#endif +#ifdef HAVE_IOCTLSOCKET_CAMEL +/* includes start */ +#ifdef HAVE_WINDOWS_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# ifdef HAVE_WINSOCK2_H +# include +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +#endif + +int +main () +{ + +/* IoctlSocket source code */ + if(0 != IoctlSocket(0, 0, 0)) + return 1; + ; + return 0; +} +#endif +#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO +/* includes start */ +#ifdef HAVE_WINDOWS_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# ifdef HAVE_WINSOCK2_H +# include +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +#endif + +int +main () +{ + +/* IoctlSocket source code */ + long flags = 0; + if(0 != ioctlsocket(0, FIONBIO, &flags)) + return 1; + ; + return 0; +} +#endif +#ifdef HAVE_IOCTLSOCKET_FIONBIO +/* includes start */ +#ifdef HAVE_WINDOWS_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# ifdef HAVE_WINSOCK2_H +# include +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +#endif + +int +main () +{ + + int flags = 0; + if(0 != ioctlsocket(0, FIONBIO, &flags)) + return 1; + + ; + return 0; +} +#endif +#ifdef HAVE_IOCTL_FIONBIO +/* headers for FIONBIO test */ +/* includes start */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_STROPTS_H +# include +#endif + +int +main () +{ + + int flags = 0; + if(0 != ioctl(0, FIONBIO, &flags)) + return 1; + + ; + return 0; +} +#endif +#ifdef HAVE_IOCTL_SIOCGIFADDR +/* headers for FIONBIO test */ +/* includes start */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_STROPTS_H +# include +#endif +#include + +int +main () +{ + struct ifreq ifr; + if(0 != ioctl(0, SIOCGIFADDR, &ifr)) + return 1; + + ; + return 0; +} +#endif +#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK +/* includes start */ +#ifdef HAVE_WINDOWS_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# ifdef HAVE_WINSOCK2_H +# include +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +#endif +/* includes start */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +/* includes end */ + +int +main () +{ + if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0)) + return 1; + ; + return 0; +} +#endif +#ifdef HAVE_GLIBC_STRERROR_R +#include +#include + +void check(char c) {} + +int +main () { + char buffer[1024]; + /* This will not compile if strerror_r does not return a char* */ + check(strerror_r(EACCES, buffer, sizeof(buffer))[0]); + return 0; +} +#endif +#ifdef HAVE_POSIX_STRERROR_R +#include +#include + +/* float, because a pointer can't be implicitly cast to float */ +void check(float f) {} + +int +main () { + char buffer[1024]; + /* This will not compile if strerror_r does not return an int */ + check(strerror_r(EACCES, buffer, sizeof(buffer))); + return 0; +} +#endif +#ifdef HAVE_FSETXATTR_6 +#include /* header from libc, not from libattr */ +int +main() { + fsetxattr(0, 0, 0, 0, 0, 0); + return 0; +} +#endif +#ifdef HAVE_FSETXATTR_5 +#include /* header from libc, not from libattr */ +int +main() { + fsetxattr(0, 0, 0, 0, 0); + return 0; +} +#endif diff --git a/CMake/FindBrotli.cmake b/CMake/FindBrotli.cmake new file mode 100644 index 00000000..351b8f75 --- /dev/null +++ b/CMake/FindBrotli.cmake @@ -0,0 +1,20 @@ +include(FindPackageHandleStandardArgs) + +find_path(BROTLI_INCLUDE_DIR "brotli/decode.h") + +find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon) +find_library(BROTLIDEC_LIBRARY NAMES brotlidec) + +find_package_handle_standard_args(BROTLI + FOUND_VAR + BROTLI_FOUND + REQUIRED_VARS + BROTLIDEC_LIBRARY + BROTLICOMMON_LIBRARY + BROTLI_INCLUDE_DIR + FAIL_MESSAGE + "Could NOT find BROTLI" +) + +set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR}) +set(BROTLI_LIBRARIES ${BROTLICOMMON_LIBRARY} ${BROTLIDEC_LIBRARY}) diff --git a/CMake/FindCARES.cmake b/CMake/FindCARES.cmake new file mode 100644 index 00000000..c4ab5f13 --- /dev/null +++ b/CMake/FindCARES.cmake @@ -0,0 +1,42 @@ +# - Find c-ares +# Find the c-ares includes and library +# This module defines +# CARES_INCLUDE_DIR, where to find ares.h, etc. +# CARES_LIBRARIES, the libraries needed to use c-ares. +# CARES_FOUND, If false, do not try to use c-ares. +# also defined, but not for general use are +# CARES_LIBRARY, where to find the c-ares library. + +FIND_PATH(CARES_INCLUDE_DIR ares.h + /usr/local/include + /usr/include + ) + +SET(CARES_NAMES ${CARES_NAMES} cares) +FIND_LIBRARY(CARES_LIBRARY + NAMES ${CARES_NAMES} + PATHS /usr/lib /usr/local/lib + ) + +IF (CARES_LIBRARY AND CARES_INCLUDE_DIR) + SET(CARES_LIBRARIES ${CARES_LIBRARY}) + SET(CARES_FOUND "YES") +ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR) + SET(CARES_FOUND "NO") +ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR) + + +IF (CARES_FOUND) + IF (NOT CARES_FIND_QUIETLY) + MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}") + ENDIF (NOT CARES_FIND_QUIETLY) +ELSE (CARES_FOUND) + IF (CARES_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find c-ares library") + ENDIF (CARES_FIND_REQUIRED) +ENDIF (CARES_FOUND) + +MARK_AS_ADVANCED( + CARES_LIBRARY + CARES_INCLUDE_DIR + ) diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake new file mode 100644 index 00000000..60dcb73c --- /dev/null +++ b/CMake/FindGSS.cmake @@ -0,0 +1,289 @@ +# - Try to find the GSS Kerberos library +# Once done this will define +# +# GSS_ROOT_DIR - Set this variable to the root installation of GSS +# +# Read-Only variables: +# GSS_FOUND - system has the Heimdal library +# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found. +# GSS_INCLUDE_DIR - the Heimdal include directory +# GSS_LIBRARIES - The libraries needed to use GSS +# GSS_LINK_DIRECTORIES - Directories to add to linker search path +# GSS_LINKER_FLAGS - Additional linker flags +# GSS_COMPILER_FLAGS - Additional compiler flags +# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest. +# In case the library is found but no version info available it'll be set to "unknown" + +set(_MIT_MODNAME mit-krb5-gssapi) +set(_HEIMDAL_MODNAME heimdal-gssapi) + +include(CheckIncludeFile) +include(CheckIncludeFiles) +include(CheckTypeSize) + +set(_GSS_ROOT_HINTS + "${GSS_ROOT_DIR}" + "$ENV{GSS_ROOT_DIR}" +) + +# try to find library using system pkg-config if user didn't specify root dir +if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}") + if(UNIX) + find_package(PkgConfig QUIET) + pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME}) + list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}") + elseif(WIN32) + list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]") + endif() +endif() + +if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach. + find_file(_GSS_CONFIGURE_SCRIPT + NAMES + "krb5-config" + HINTS + ${_GSS_ROOT_HINTS} + PATH_SUFFIXES + bin + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + ) + + # if not found in user-supplied directories, maybe system knows better + find_file(_GSS_CONFIGURE_SCRIPT + NAMES + "krb5-config" + PATH_SUFFIXES + bin + ) + + if(_GSS_CONFIGURE_SCRIPT) + execute_process( + COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi" + OUTPUT_VARIABLE _GSS_CFLAGS + RESULT_VARIABLE _GSS_CONFIGURE_FAILED + ) +message(STATUS "CFLAGS: ${_GSS_CFLAGS}") + if(NOT _GSS_CONFIGURE_FAILED) # 0 means success + # should also work in an odd case when multiple directories are given + string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS) + string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}") + string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}") + + foreach(_flag ${_GSS_CFLAGS}) + if(_flag MATCHES "^-I.*") + string(REGEX REPLACE "^-I" "" _val "${_flag}") + list(APPEND _GSS_INCLUDE_DIR "${_val}") + else() + list(APPEND _GSS_COMPILER_FLAGS "${_flag}") + endif() + endforeach() + endif() + + execute_process( + COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi" + OUTPUT_VARIABLE _GSS_LIB_FLAGS + RESULT_VARIABLE _GSS_CONFIGURE_FAILED + ) +message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}") + if(NOT _GSS_CONFIGURE_FAILED) # 0 means success + # this script gives us libraries and link directories. Blah. We have to deal with it. + string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS) + string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}") + string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}") + + foreach(_flag ${_GSS_LIB_FLAGS}) + if(_flag MATCHES "^-l.*") + string(REGEX REPLACE "^-l" "" _val "${_flag}") + list(APPEND _GSS_LIBRARIES "${_val}") + elseif(_flag MATCHES "^-L.*") + string(REGEX REPLACE "^-L" "" _val "${_flag}") + list(APPEND _GSS_LINK_DIRECTORIES "${_val}") + else() + list(APPEND _GSS_LINKER_FLAGS "${_flag}") + endif() + endforeach() + endif() + + + execute_process( + COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version" + OUTPUT_VARIABLE _GSS_VERSION + RESULT_VARIABLE _GSS_CONFIGURE_FAILED + ) + + # older versions may not have the "--version" parameter. In this case we just don't care. + if(_GSS_CONFIGURE_FAILED) + set(_GSS_VERSION 0) + endif() + + + execute_process( + COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor" + OUTPUT_VARIABLE _GSS_VENDOR + RESULT_VARIABLE _GSS_CONFIGURE_FAILED + ) + + # older versions may not have the "--vendor" parameter. In this case we just don't care. + if(_GSS_CONFIGURE_FAILED) + set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter + else() + if(_GSS_VENDOR MATCHES ".*H|heimdal.*") + set(GSS_FLAVOUR "Heimdal") + else() + set(GSS_FLAVOUR "MIT") + endif() + endif() + + else() # either there is no config script or we are on platform that doesn't provide one (Windows?) + + find_path(_GSS_INCLUDE_DIR + NAMES + "gssapi/gssapi.h" + HINTS + ${_GSS_ROOT_HINTS} + PATH_SUFFIXES + include + inc + ) + + if(_GSS_INCLUDE_DIR) #jay, we've found something + set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}") + check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS) + + if(_GSS_HAVE_MIT_HEADERS) + set(GSS_FLAVOUR "MIT") + else() + # prevent compiling the header - just check if we can include it + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__") + check_include_file( "roken.h" _GSS_HAVE_ROKEN_H) + + check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H) + if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H) + set(GSS_FLAVOUR "Heimdal") + endif() + set(CMAKE_REQUIRED_DEFINITIONS "") + endif() + else() + # I'm not convienced if this is the right way but this is what autotools do at the moment + find_path(_GSS_INCLUDE_DIR + NAMES + "gssapi.h" + HINTS + ${_GSS_ROOT_HINTS} + PATH_SUFFIXES + include + inc + ) + + if(_GSS_INCLUDE_DIR) + set(GSS_FLAVOUR "Heimdal") + endif() + endif() + + # if we have headers, check if we can link libraries + if(GSS_FLAVOUR) + set(_GSS_LIBDIR_SUFFIXES "") + set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS}) + get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH) + list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT}) + + if(WIN32) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64") + if(GSS_FLAVOUR STREQUAL "MIT") + set(_GSS_LIBNAME "gssapi64") + else() + set(_GSS_LIBNAME "libgssapi") + endif() + else() + list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386") + if(GSS_FLAVOUR STREQUAL "MIT") + set(_GSS_LIBNAME "gssapi32") + else() + set(_GSS_LIBNAME "libgssapi") + endif() + endif() + else() + list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS + if(GSS_FLAVOUR STREQUAL "MIT") + set(_GSS_LIBNAME "gssapi_krb5") + else() + set(_GSS_LIBNAME "gssapi") + endif() + endif() + + find_library(_GSS_LIBRARIES + NAMES + ${_GSS_LIBNAME} + HINTS + ${_GSS_LIBDIR_HINTS} + PATH_SUFFIXES + ${_GSS_LIBDIR_SUFFIXES} + ) + + endif() + + endif() +else() + if(_GSS_PKG_${_MIT_MODNAME}_VERSION) + set(GSS_FLAVOUR "MIT") + set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION) + else() + set(GSS_FLAVOUR "Heimdal") + set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION) + endif() +endif() + +set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR}) +set(GSS_LIBRARIES ${_GSS_LIBRARIES}) +set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES}) +set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS}) +set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS}) +set(GSS_VERSION ${_GSS_VERSION}) + +if(GSS_FLAVOUR) + + if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest") + else() + set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest") + endif() + + if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}") + file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str + REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$") + + string(REGEX MATCH "[0-9]\\.[^\"]+" + GSS_VERSION "${heimdal_version_str}") + endif() + + if(NOT GSS_VERSION) + set(GSS_VERSION "Heimdal Unknown") + endif() + elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT") + get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE) + if(WIN32 AND _MIT_VERSION) + set(GSS_VERSION "${_MIT_VERSION}") + else() + set(GSS_VERSION "MIT Unknown") + endif() + endif() +endif() + + +include(FindPackageHandleStandardArgs) + +set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR) + +find_package_handle_standard_args(GSS + REQUIRED_VARS + ${_GSS_REQUIRED_VARS} + VERSION_VAR + GSS_VERSION + FAIL_MESSAGE + "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR" +) + +mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES) diff --git a/CMake/FindLibSSH2.cmake b/CMake/FindLibSSH2.cmake new file mode 100644 index 00000000..12a7c612 --- /dev/null +++ b/CMake/FindLibSSH2.cmake @@ -0,0 +1,35 @@ +# - Try to find the libssh2 library +# Once done this will define +# +# LIBSSH2_FOUND - system has the libssh2 library +# LIBSSH2_INCLUDE_DIR - the libssh2 include directory +# LIBSSH2_LIBRARY - the libssh2 library name + +if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY) + set(LibSSH2_FIND_QUIETLY TRUE) +endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY) + +FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h +) + +FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2 +) + +if(LIBSSH2_INCLUDE_DIR) + file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*") + + string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}") + string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}") + string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}") + + string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}") + string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}") + string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}") + + set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}") +endif(LIBSSH2_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY ) + +MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION) diff --git a/CMake/FindMbedTLS.cmake b/CMake/FindMbedTLS.cmake new file mode 100644 index 00000000..a9163958 --- /dev/null +++ b/CMake/FindMbedTLS.cmake @@ -0,0 +1,13 @@ +find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h) + +find_library(MBEDTLS_LIBRARY mbedtls) +find_library(MBEDX509_LIBRARY mbedx509) +find_library(MBEDCRYPTO_LIBRARY mbedcrypto) + +set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MBEDTLS DEFAULT_MSG + MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) + +mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) diff --git a/CMake/FindNGHTTP2.cmake b/CMake/FindNGHTTP2.cmake new file mode 100644 index 00000000..4e566cf0 --- /dev/null +++ b/CMake/FindNGHTTP2.cmake @@ -0,0 +1,18 @@ +include(FindPackageHandleStandardArgs) + +find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h") + +find_library(NGHTTP2_LIBRARY NAMES nghttp2) + +find_package_handle_standard_args(NGHTTP2 + FOUND_VAR + NGHTTP2_FOUND + REQUIRED_VARS + NGHTTP2_LIBRARY + NGHTTP2_INCLUDE_DIR + FAIL_MESSAGE + "Could NOT find NGHTTP2" +) + +set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR} ) +set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY}) diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake new file mode 100644 index 00000000..87bf905f --- /dev/null +++ b/CMake/Macros.cmake @@ -0,0 +1,124 @@ +#File defines convenience macros for available feature testing + +# This macro checks if the symbol exists in the library and if it +# does, it prepends library to the list. It is intended to be called +# multiple times with a sequence of possibly dependent libraries in +# order of least-to-most-dependent. Some libraries depend on others +# to link correctly. +macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE) + check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}" + ${VARIABLE}) + if(${VARIABLE}) + set(CURL_LIBS ${LIBRARY} ${CURL_LIBS}) + endif() +endmacro() + +# Check if header file exists and add it to the list. +# This macro is intended to be called multiple times with a sequence of +# possibly dependent header files. Some headers depend on others to be +# compiled correctly. +macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE) + check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE}) + if(${VARIABLE}) + set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE}) + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}") + endif() +endmacro() + +# For other curl specific tests, use this macro. +macro(CURL_INTERNAL_TEST CURL_TEST) + if(NOT DEFINED "${CURL_TEST}") + set(MACRO_CHECK_FUNCTION_DEFINITIONS + "-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}") + if(CMAKE_REQUIRED_LIBRARIES) + set(CURL_TEST_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + endif() + + message(STATUS "Performing Curl Test ${CURL_TEST}") + try_compile(${CURL_TEST} + ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + "${CURL_TEST_ADD_LIBRARIES}" + OUTPUT_VARIABLE OUTPUT) + if(${CURL_TEST}) + set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}") + message(STATUS "Performing Curl Test ${CURL_TEST} - Success") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Performing Curl Test ${CURL_TEST} passed with the following output:\n" + "${OUTPUT}\n") + else() + message(STATUS "Performing Curl Test ${CURL_TEST} - Failed") + set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Performing Curl Test ${CURL_TEST} failed with the following output:\n" + "${OUTPUT}\n") + endif() + endif() +endmacro() + +macro(CURL_INTERNAL_TEST_RUN CURL_TEST) + if(NOT DEFINED "${CURL_TEST}_COMPILE") + set(MACRO_CHECK_FUNCTION_DEFINITIONS + "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}") + if(CMAKE_REQUIRED_LIBRARIES) + set(CURL_TEST_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + endif() + + message(STATUS "Performing Curl Test ${CURL_TEST}") + try_run(${CURL_TEST} ${CURL_TEST}_COMPILE + ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + "${CURL_TEST_ADD_LIBRARIES}" + OUTPUT_VARIABLE OUTPUT) + if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) + set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}") + message(STATUS "Performing Curl Test ${CURL_TEST} - Success") + else() + message(STATUS "Performing Curl Test ${CURL_TEST} - Failed") + set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") + file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" + "Performing Curl Test ${CURL_TEST} failed with the following output:\n" + "${OUTPUT}") + if(${CURL_TEST}_COMPILE) + file(APPEND + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" + "There was a problem running this test\n") + endif() + file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" + "\n\n") + endif() + endif() +endmacro() + +macro(CURL_NROFF_CHECK) + find_program(NROFF NAMES gnroff nroff) + if(NROFF) + # Need a way to write to stdin, this will do + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test") + # Tests for a valid nroff option to generate a manpage + foreach(_MANOPT "-man" "-mandoc") + execute_process(COMMAND "${NROFF}" ${_MANOPT} + OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT + INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" + ERROR_QUIET) + # Save the option if it was valid + if(NROFF_MANOPT_OUTPUT) + message("Found *nroff option: -- ${_MANOPT}") + set(NROFF_MANOPT ${_MANOPT}) + set(NROFF_USEFUL ON) + break() + endif() + endforeach() + # No need for the temporary file + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt") + if(NOT NROFF_USEFUL) + message(WARNING "Found no *nroff option to get plaintext from man pages") + endif() + else() + message(WARNING "Found no *nroff program") + endif() +endmacro() diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake new file mode 100644 index 00000000..ce6d3e13 --- /dev/null +++ b/CMake/OtherTests.cmake @@ -0,0 +1,231 @@ +include(CheckCSourceCompiles) +# The begin of the sources (macros and includes) +set(_source_epilogue "#undef inline") + +macro(add_header_include check header) + if(${check}) + set(_source_epilogue "${_source_epilogue}\n#include <${header}>") + endif() +endmacro() + +set(signature_call_conv) +if(HAVE_WINDOWS_H) + add_header_include(HAVE_WINSOCK2_H "winsock2.h") + add_header_include(HAVE_WINDOWS_H "windows.h") + add_header_include(HAVE_WINSOCK_H "winsock.h") + set(_source_epilogue + "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif") + set(signature_call_conv "PASCAL") + if(HAVE_LIBWS2_32) + set(CMAKE_REQUIRED_LIBRARIES ws2_32) + endif() +else() + add_header_include(HAVE_SYS_TYPES_H "sys/types.h") + add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h") +endif() + +check_c_source_compiles("${_source_epilogue} +int main(void) { + recv(0, 0, 0, 0); + return 0; +}" curl_cv_recv) +if(curl_cv_recv) + if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown") + foreach(recv_retv "int" "ssize_t" ) + foreach(recv_arg1 "SOCKET" "int" ) + foreach(recv_arg2 "char *" "void *" ) + foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int") + foreach(recv_arg4 "int" "unsigned int") + if(NOT curl_cv_func_recv_done) + unset(curl_cv_func_recv_test CACHE) + check_c_source_compiles(" + ${_source_epilogue} + extern ${recv_retv} ${signature_call_conv} + recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4}); + int main(void) { + ${recv_arg1} s=0; + ${recv_arg2} buf=0; + ${recv_arg3} len=0; + ${recv_arg4} flags=0; + ${recv_retv} res = recv(s, buf, len, flags); + (void) res; + return 0; + }" + curl_cv_func_recv_test) + message(STATUS + "Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})") + if(curl_cv_func_recv_test) + set(curl_cv_func_recv_args + "${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}") + set(RECV_TYPE_ARG1 "${recv_arg1}") + set(RECV_TYPE_ARG2 "${recv_arg2}") + set(RECV_TYPE_ARG3 "${recv_arg3}") + set(RECV_TYPE_ARG4 "${recv_arg4}") + set(RECV_TYPE_RETV "${recv_retv}") + set(HAVE_RECV 1) + set(curl_cv_func_recv_done 1) + endif() + endif() + endforeach() + endforeach() + endforeach() + endforeach() + endforeach() + else() + string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}") + string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}") + endif() + + if("${curl_cv_func_recv_args}" STREQUAL "unknown") + message(FATAL_ERROR "Cannot find proper types to use for recv args") + endif() +else() + message(FATAL_ERROR "Unable to link function recv") +endif() +set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv") +set(HAVE_RECV 1) + +check_c_source_compiles("${_source_epilogue} +int main(void) { + send(0, 0, 0, 0); + return 0; +}" curl_cv_send) +if(curl_cv_send) + if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown") + foreach(send_retv "int" "ssize_t" ) + foreach(send_arg1 "SOCKET" "int" "ssize_t" ) + foreach(send_arg2 "const char *" "const void *" "void *" "char *") + foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int") + foreach(send_arg4 "int" "unsigned int") + if(NOT curl_cv_func_send_done) + unset(curl_cv_func_send_test CACHE) + check_c_source_compiles(" + ${_source_epilogue} + extern ${send_retv} ${signature_call_conv} + send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4}); + int main(void) { + ${send_arg1} s=0; + ${send_arg2} buf=0; + ${send_arg3} len=0; + ${send_arg4} flags=0; + ${send_retv} res = send(s, buf, len, flags); + (void) res; + return 0; + }" + curl_cv_func_send_test) + message(STATUS + "Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})") + if(curl_cv_func_send_test) + string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}") + string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}") + set(curl_cv_func_send_args + "${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}") + set(SEND_TYPE_ARG1 "${send_arg1}") + set(SEND_TYPE_ARG2 "${send_arg2}") + set(SEND_TYPE_ARG3 "${send_arg3}") + set(SEND_TYPE_ARG4 "${send_arg4}") + set(SEND_TYPE_RETV "${send_retv}") + set(HAVE_SEND 1) + set(curl_cv_func_send_done 1) + endif() + endif() + endforeach() + endforeach() + endforeach() + endforeach() + endforeach() + else() + string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}") + string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}") + string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}") + endif() + + if("${curl_cv_func_send_args}" STREQUAL "unknown") + message(FATAL_ERROR "Cannot find proper types to use for send args") + endif() + set(SEND_QUAL_ARG2 "const") +else() + message(FATAL_ERROR "Unable to link function send") +endif() +set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send") +set(HAVE_SEND 1) + +check_c_source_compiles("${_source_epilogue} + int main(void) { + int flag = MSG_NOSIGNAL; + (void)flag; + return 0; + }" HAVE_MSG_NOSIGNAL) + +if(NOT HAVE_WINDOWS_H) + add_header_include(HAVE_SYS_TIME_H "sys/time.h") + add_header_include(TIME_WITH_SYS_TIME "time.h") + add_header_include(HAVE_TIME_H "time.h") +endif() +check_c_source_compiles("${_source_epilogue} +int main(void) { + struct timeval ts; + ts.tv_sec = 0; + ts.tv_usec = 0; + (void)ts; + return 0; +}" HAVE_STRUCT_TIMEVAL) + + +include(CheckCSourceRuns) +# See HAVE_POLL in CMakeLists.txt for why poll is disabled on macOS +if(NOT APPLE) + set(CMAKE_REQUIRED_FLAGS) + if(HAVE_SYS_POLL_H) + set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H") + endif() + check_c_source_runs(" + #ifdef HAVE_SYS_POLL_H + # include + #endif + int main(void) { + return poll((void *)0, 0, 10 /*ms*/); + }" HAVE_POLL_FINE) +endif() + +set(HAVE_SIG_ATOMIC_T 1) +set(CMAKE_REQUIRED_FLAGS) +if(HAVE_SIGNAL_H) + set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H") + set(CMAKE_EXTRA_INCLUDE_FILES "signal.h") +endif() +check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T) +if(HAVE_SIZEOF_SIG_ATOMIC_T) + check_c_source_compiles(" + #ifdef HAVE_SIGNAL_H + # include + #endif + int main(void) { + static volatile sig_atomic_t dummy = 0; + (void)dummy; + return 0; + }" HAVE_SIG_ATOMIC_T_NOT_VOLATILE) + if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE) + set(HAVE_SIG_ATOMIC_T_VOLATILE 1) + endif() +endif() + +if(HAVE_WINDOWS_H) + set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h) +else() + set(CMAKE_EXTRA_INCLUDE_FILES) + if(HAVE_SYS_SOCKET_H) + set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) + endif() +endif() + +check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE) +if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE) + set(HAVE_STRUCT_SOCKADDR_STORAGE 1) +endif() diff --git a/CMake/Platforms/WindowsCache.cmake b/CMake/Platforms/WindowsCache.cmake new file mode 100644 index 00000000..cafaec21 --- /dev/null +++ b/CMake/Platforms/WindowsCache.cmake @@ -0,0 +1,124 @@ +if(NOT UNIX) + if(WIN32) + set(HAVE_LIBDL 0) + set(HAVE_LIBUCB 0) + set(HAVE_LIBSOCKET 0) + set(NOT_NEED_LIBNSL 0) + set(HAVE_LIBNSL 0) + set(HAVE_GETHOSTNAME 1) + set(HAVE_LIBZ 0) + set(HAVE_LIBCRYPTO 0) + + set(HAVE_DLOPEN 0) + + set(HAVE_ALLOCA_H 0) + set(HAVE_ARPA_INET_H 0) + set(HAVE_DLFCN_H 0) + set(HAVE_FCNTL_H 1) + set(HAVE_INTTYPES_H 0) + set(HAVE_IO_H 1) + set(HAVE_MALLOC_H 1) + set(HAVE_MEMORY_H 1) + set(HAVE_NETDB_H 0) + set(HAVE_NETINET_IF_ETHER_H 0) + set(HAVE_NETINET_IN_H 0) + set(HAVE_NET_IF_H 0) + set(HAVE_PROCESS_H 1) + set(HAVE_PWD_H 0) + set(HAVE_SETJMP_H 1) + set(HAVE_SGTTY_H 0) + set(HAVE_SIGNAL_H 1) + set(HAVE_SOCKIO_H 0) + set(HAVE_STDINT_H 0) + set(HAVE_STDLIB_H 1) + set(HAVE_STRINGS_H 0) + set(HAVE_STRING_H 1) + set(HAVE_SYS_PARAM_H 0) + set(HAVE_SYS_POLL_H 0) + set(HAVE_SYS_SELECT_H 0) + set(HAVE_SYS_SOCKET_H 0) + set(HAVE_SYS_SOCKIO_H 0) + set(HAVE_SYS_STAT_H 1) + set(HAVE_SYS_TIME_H 0) + set(HAVE_SYS_TYPES_H 1) + set(HAVE_SYS_UTIME_H 1) + set(HAVE_TERMIOS_H 0) + set(HAVE_TERMIO_H 0) + set(HAVE_TIME_H 1) + set(HAVE_UNISTD_H 0) + set(HAVE_UTIME_H 0) + set(HAVE_X509_H 0) + set(HAVE_ZLIB_H 0) + + set(HAVE_SIZEOF_LONG_DOUBLE 1) + set(SIZEOF_LONG_DOUBLE 8) + + set(HAVE_SOCKET 1) + set(HAVE_POLL 0) + set(HAVE_SELECT 1) + set(HAVE_STRDUP 1) + set(HAVE_STRSTR 1) + set(HAVE_STRTOK_R 0) + set(HAVE_STRFTIME 1) + set(HAVE_UNAME 0) + set(HAVE_STRCASECMP 0) + set(HAVE_STRICMP 1) + set(HAVE_STRCMPI 1) + set(HAVE_GETHOSTBYADDR 1) + set(HAVE_GETTIMEOFDAY 0) + set(HAVE_INET_ADDR 1) + set(HAVE_INET_NTOA 1) + set(HAVE_INET_NTOA_R 0) + set(HAVE_TCGETATTR 0) + set(HAVE_TCSETATTR 0) + set(HAVE_PERROR 1) + set(HAVE_CLOSESOCKET 1) + set(HAVE_SETVBUF 0) + set(HAVE_SIGSETJMP 0) + set(HAVE_GETPASS_R 0) + set(HAVE_STRLCAT 0) + set(HAVE_GETPWUID 0) + set(HAVE_GETEUID 0) + set(HAVE_UTIME 1) + set(HAVE_RAND_EGD 0) + set(HAVE_RAND_SCREEN 0) + set(HAVE_RAND_STATUS 0) + set(HAVE_GMTIME_R 0) + set(HAVE_LOCALTIME_R 0) + set(HAVE_GETHOSTBYADDR_R 0) + set(HAVE_GETHOSTBYNAME_R 0) + set(HAVE_SIGNAL_FUNC 1) + set(HAVE_SIGNAL_MACRO 0) + + set(HAVE_GETHOSTBYADDR_R_5 0) + set(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0) + set(HAVE_GETHOSTBYADDR_R_7 0) + set(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0) + set(HAVE_GETHOSTBYADDR_R_8 0) + set(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0) + set(HAVE_GETHOSTBYNAME_R_3 0) + set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0) + set(HAVE_GETHOSTBYNAME_R_5 0) + set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0) + set(HAVE_GETHOSTBYNAME_R_6 0) + set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0) + + set(TIME_WITH_SYS_TIME 0) + set(HAVE_O_NONBLOCK 0) + set(HAVE_IN_ADDR_T 0) + set(HAVE_INET_NTOA_R_DECL 0) + set(HAVE_INET_NTOA_R_DECL_REENTRANT 0) + if(ENABLE_IPV6) + set(HAVE_GETADDRINFO 1) + else() + set(HAVE_GETADDRINFO 0) + endif() + set(STDC_HEADERS 1) + set(RETSIGTYPE_TEST 1) + + set(HAVE_SIGACTION 0) + set(HAVE_MACRO_SIGSETJMP 0) + else() + message("This file should be included on Windows platform only") + endif() +endif() diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake new file mode 100644 index 00000000..5cb1d449 --- /dev/null +++ b/CMake/Utilities.cmake @@ -0,0 +1,13 @@ +# File containing various utilities + +# Returns a list of arguments that evaluate to true +function(count_true output_count_var) + set(lst) + foreach(option_var IN LISTS ARGN) + if(${option_var}) + list(APPEND lst ${option_var}) + endif() + endforeach() + list(LENGTH lst lst_len) + set(${output_count_var} ${lst_len} PARENT_SCOPE) +endfunction() diff --git a/CMake/cmake_uninstall.cmake.in b/CMake/cmake_uninstall.cmake.in new file mode 100644 index 00000000..d00a5166 --- /dev/null +++ b/CMake/cmake_uninstall.cmake.in @@ -0,0 +1,26 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +if (NOT DEFINED CMAKE_INSTALL_PREFIX) + set (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@") +endif () + message(${CMAKE_INSTALL_PREFIX}) + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/CMake/curl-config.cmake b/CMake/curl-config.cmake new file mode 100644 index 00000000..119332cd --- /dev/null +++ b/CMake/curl-config.cmake @@ -0,0 +1,59 @@ + +get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + +if(NOT CURL_FIND_COMPONENTS) + set(CURL_FIND_COMPONENTS curl libcurl) + if(CURL_FIND_REQUIRED) + set(CURL_FIND_REQUIRED_curl TRUE) + set(CURL_FIND_REQUIRED_libcurl TRUE) + endif() +endif() + +set(_curl_missing_components) +foreach(_comp ${CURL_FIND_COMPONENTS}) + if(EXISTS "${_DIR}/${_comp}-target.cmake") + include("${_DIR}/${_comp}-target.cmake") + set(CURL_${_comp}_FOUND TRUE) + else() + set(CURL_${_comp}_FOUND FALSE) + if(CURL_FIND_REQUIRED_${_comp}) + set(CURL_FOUND FALSE) + list(APPEND _curl_missing_components ${_comp}) + endif() + endif() +endforeach() + +if(_curl_missing_components) + set(CURL_NOT_FOUND_MESSAGE "Following required components not found: " ${_curl_missing_components}) +else() + if(TARGET CURL::libcurl) + string(TOUPPER "${CMAKE_BUILD_TYPE}" _curl_current_config) + if(NOT _curl_current_config) + set(_curl_current_config "NOCONFIG") + endif() + get_target_property(_curl_configurations CURL::libcurl IMPORTED_CONFIGURATIONS) + list(FIND _curl_configurations "${_curl_current_config}" _i) + if(_i LESS 0) + set(_curl_config "RELEASE") + list(FIND _curl_configurations "${_curl_current_config}" _i) + if(_i LESS 0) + set(_curl_config "NOCONFIG") + list(FIND _curl_configurations "${_curl_current_config}" _i) + endif() + endif() + + if(_i LESS 0) + set(_curl_current_config "") # let CMake pick config at random + else() + set(_curl_current_config "_${_curl_current_config}") + endif() + + get_target_property(CURL_INCLUDE_DIRS CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(CURL_LIBRARIES CURL::libcurl "LOCATION${_curl_current_config}") + set(_curl_current_config) + set(_curl_configurations) + set(_i) + endif() +endif() + +unset(_curl_missing_components) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..df164500 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,1343 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +# curl/libcurl CMake script +# by Tetetest and Sukender (Benoit Neil) + +# TODO: +# The output .so file lacks the soname number which we currently have within the lib/Makefile.am file +# Add full (4 or 5 libs) SSL support +# Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include). +# Add CTests(?) +# Check on all possible platforms +# Test with as many configurations possible (With or without any option) +# Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest: +# - lists of headers that 'configure' checks for; +# - curl-specific tests (the ones that are in m4/curl-*.m4 files); +# - (most obvious thing:) curl version numbers. +# Add documentation subproject +# +# To check: +# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not. +# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options. +cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") +include(Utilities) +include(Macros) +include(CMakeDependentOption) +include(CheckCCompilerFlag) + +project( CURL C ) + +message(WARNING "the curl cmake build system is poorly maintained. Be aware") + +file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS) +string (REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*" + CURL_VERSION ${CURL_VERSION_H_CONTENTS}) +string (REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION}) +string (REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+" + CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS}) +string (REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM}) + +include_regular_expression("^.*$") # Sukender: Is it necessary? + +# Setup package meta-data +# SET(PACKAGE "curl") +message(STATUS "curl version=[${CURL_VERSION}]") +# SET(PACKAGE_TARNAME "curl") +# SET(PACKAGE_NAME "curl") +# SET(PACKAGE_VERSION "-") +# SET(PACKAGE_STRING "curl-") +# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/") +set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}") +set(OS "\"${CMAKE_SYSTEM_NAME}\"") + +include_directories(${PROJECT_BINARY_DIR}/include/curl) +include_directories( ${CURL_SOURCE_DIR}/include ) + +option(CURL_WERROR "Turn compiler warnings into errors" OFF) +option(PICKY_COMPILER "Enable picky compiler options" ON) +option(BUILD_CURL_EXE "Set to ON to build curl executable." ON) +option(CURL_STATICLIB "Set to ON to build libcurl with static linking." OFF) +option(ENABLE_ARES "Set to ON to enable c-ares support" OFF) +if(WIN32) + option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF) + option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON) +endif() + +CMAKE_DEPENDENT_OPTION(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup" + ON "NOT ENABLE_ARES" + OFF) + +option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF) +option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF) + +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) + if (PICKY_COMPILER) + foreach (_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers) + # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new + # test result in. + CHECK_C_COMPILER_FLAG(${_CCOPT} OPT${_CCOPT}) + if(OPT${_CCOPT}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}") + endif() + endforeach() + endif() +endif() + +if (ENABLE_DEBUG) + # DEBUGBUILD will be defined only for Debug builds + if(NOT CMAKE_VERSION VERSION_LESS 3.0) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$:DEBUGBUILD>) + else() + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUGBUILD) + endif() + set(ENABLE_CURLDEBUG ON) +endif() + +if (ENABLE_CURLDEBUG) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG) +endif() + +# For debug libs and exes, add "-d" postfix +if(NOT DEFINED CMAKE_DEBUG_POSTFIX) + set(CMAKE_DEBUG_POSTFIX "-d") +endif() + +# initialize CURL_LIBS +set(CURL_LIBS "") + +if(ENABLE_ARES) + set(USE_ARES 1) + find_package(CARES REQUIRED) + list(APPEND CURL_LIBS ${CARES_LIBRARY} ) + set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY}) +endif() + +include(CurlSymbolHiding) + +option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF) +mark_as_advanced(HTTP_ONLY) +option(CURL_DISABLE_FTP "disables FTP" OFF) +mark_as_advanced(CURL_DISABLE_FTP) +option(CURL_DISABLE_LDAP "disables LDAP" OFF) +mark_as_advanced(CURL_DISABLE_LDAP) +option(CURL_DISABLE_TELNET "disables Telnet" OFF) +mark_as_advanced(CURL_DISABLE_TELNET) +option(CURL_DISABLE_DICT "disables DICT" OFF) +mark_as_advanced(CURL_DISABLE_DICT) +option(CURL_DISABLE_FILE "disables FILE" OFF) +mark_as_advanced(CURL_DISABLE_FILE) +option(CURL_DISABLE_TFTP "disables TFTP" OFF) +mark_as_advanced(CURL_DISABLE_TFTP) +option(CURL_DISABLE_HTTP "disables HTTP" OFF) +mark_as_advanced(CURL_DISABLE_HTTP) + +option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF) +mark_as_advanced(CURL_DISABLE_LDAPS) + +option(CURL_DISABLE_RTSP "to disable RTSP" OFF) +mark_as_advanced(CURL_DISABLE_RTSP) +option(CURL_DISABLE_PROXY "to disable proxy" OFF) +mark_as_advanced(CURL_DISABLE_PROXY) +option(CURL_DISABLE_POP3 "to disable POP3" OFF) +mark_as_advanced(CURL_DISABLE_POP3) +option(CURL_DISABLE_IMAP "to disable IMAP" OFF) +mark_as_advanced(CURL_DISABLE_IMAP) +option(CURL_DISABLE_SMTP "to disable SMTP" OFF) +mark_as_advanced(CURL_DISABLE_SMTP) +option(CURL_DISABLE_GOPHER "to disable Gopher" OFF) +mark_as_advanced(CURL_DISABLE_GOPHER) + +if(HTTP_ONLY) + set(CURL_DISABLE_FTP ON) + set(CURL_DISABLE_LDAP ON) + set(CURL_DISABLE_LDAPS ON) + set(CURL_DISABLE_TELNET ON) + set(CURL_DISABLE_DICT ON) + set(CURL_DISABLE_FILE ON) + set(CURL_DISABLE_TFTP ON) + set(CURL_DISABLE_RTSP ON) + set(CURL_DISABLE_POP3 ON) + set(CURL_DISABLE_IMAP ON) + set(CURL_DISABLE_SMTP ON) + set(CURL_DISABLE_GOPHER ON) +endif() + +option(CURL_DISABLE_COOKIES "to disable cookies support" OFF) +mark_as_advanced(CURL_DISABLE_COOKIES) + +option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF) +mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH) +option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF) +mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS) +option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON) +mark_as_advanced(ENABLE_IPV6) +if(ENABLE_IPV6 AND NOT WIN32) + include(CheckStructHasMember) + check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h" + HAVE_SOCKADDR_IN6_SIN6_ADDR) + check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h" + HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) + if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR) + message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support") + # Force the feature off as this name is used as guard macro... + set(ENABLE_IPV6 OFF + CACHE BOOL "Define if you want to enable IPv6 support" FORCE) + endif() +endif() + +CURL_NROFF_CHECK() +find_package(Perl) + +CMAKE_DEPENDENT_OPTION(ENABLE_MANUAL "to provide the built-in manual" + ON "NROFF_USEFUL;PERL_FOUND" + OFF) + +if(NOT PERL_FOUND) + message(STATUS "Perl not found, testing disabled.") + set(BUILD_TESTING OFF) +endif() +if(ENABLE_MANUAL) + set(USE_MANUAL ON) +endif() + +# We need ansi c-flags, especially on HP +set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") +set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS}) + +if(CURL_STATIC_CRT) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") +endif() + +# Disable warnings on Borland to avoid changing 3rd party code. +if(BORLAND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-") +endif() + +# If we are on AIX, do the _ALL_SOURCE magic +if(${CMAKE_SYSTEM_NAME} MATCHES AIX) + set(_ALL_SOURCE 1) +endif() + +# Include all the necessary files for macros +include (CheckFunctionExists) +include (CheckIncludeFile) +include (CheckIncludeFiles) +include (CheckLibraryExists) +include (CheckSymbolExists) +include (CheckTypeSize) +include (CheckCSourceCompiles) +include (CMakeDependentOption) + +# On windows preload settings +if(WIN32) + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_=") + include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake) +endif() + +if(ENABLE_THREADED_RESOLVER) + find_package(Threads REQUIRED) + if(WIN32) + set(USE_THREADS_WIN32 ON) + else() + set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT}) + set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT}) + endif() + set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +endif() + +# Check for all needed libraries +check_library_exists_concat("dl" dlopen HAVE_LIBDL) +check_library_exists_concat("socket" connect HAVE_LIBSOCKET) +check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL) + +# Yellowtab Zeta needs different libraries than BeOS 5. +if(BEOS) + set(NOT_NEED_LIBNSL 1) + check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND) + check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI) +endif() + +if(NOT NOT_NEED_LIBNSL) + check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL) +endif() + +check_function_exists(gethostname HAVE_GETHOSTNAME) + +if(WIN32) + check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32) + check_library_exists_concat("winmm" getch HAVE_LIBWINMM) + list(APPEND CURL_LIBS "advapi32") +endif() + +# check SSL libraries +# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL + +if(APPLE) + option(CMAKE_USE_DARWINSSL "enable Apple OS native SSL/TLS" OFF) +endif() +if(WIN32) + option(CMAKE_USE_WINSSL "enable Windows native SSL/TLS" OFF) + cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON + CMAKE_USE_WINSSL OFF) +endif() +option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF) + +set(openssl_default ON) +if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS) + set(openssl_default OFF) +endif() +option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default}) + +count_true(enabled_ssl_options_count + CMAKE_USE_WINSSL + CMAKE_USE_DARWINSSL + CMAKE_USE_OPENSSL + CMAKE_USE_MBEDTLS +) +if(enabled_ssl_options_count GREATER "1") + set(CURL_WITH_MULTI_SSL ON) +endif() + +if(CMAKE_USE_WINSSL) + set(SSL_ENABLED ON) + set(USE_SCHANNEL ON) # Windows native SSL/TLS support + set(USE_WINDOWS_SSPI ON) # CMAKE_USE_WINSSL implies CURL_WINDOWS_SSPI + list(APPEND CURL_LIBS "crypt32") +endif() +if(CURL_WINDOWS_SSPI) + set(USE_WINDOWS_SSPI ON) + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32") +endif() + +if(CMAKE_USE_DARWINSSL) + find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation") + if(NOT COREFOUNDATION_FRAMEWORK) + message(FATAL_ERROR "CoreFoundation framework not found") + endif() + + find_library(SECURITY_FRAMEWORK "Security") + if(NOT SECURITY_FRAMEWORK) + message(FATAL_ERROR "Security framework not found") + endif() + + set(SSL_ENABLED ON) + set(USE_DARWINSSL ON) + list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}") +endif() + +if(CMAKE_USE_OPENSSL) + find_package(OpenSSL REQUIRED) + set(SSL_ENABLED ON) + set(USE_OPENSSL ON) + set(HAVE_LIBCRYPTO ON) + set(HAVE_LIBSSL ON) + list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES}) + include_directories(${OPENSSL_INCLUDE_DIR}) + set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H) + check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H) + check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H) + check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H) + check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H) + check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H) + check_include_file("openssl/rand.h" HAVE_OPENSSL_RAND_H) + check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS) + check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN) + check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD) +endif() + +if(CMAKE_USE_MBEDTLS) + find_package(MbedTLS REQUIRED) + set(SSL_ENABLED ON) + set(USE_MBEDTLS ON) + list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES}) + include_directories(${MBEDTLS_INCLUDE_DIRS}) +endif() + +option(USE_NGHTTP2 "Use Nghttp2 library" OFF) +if(USE_NGHTTP2) + find_package(NGHTTP2 REQUIRED) + include_directories(${NGHTTP2_INCLUDE_DIRS}) + list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES}) +endif() + +if(NOT CURL_DISABLE_LDAP) + if(WIN32) + option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON) + if(USE_WIN32_LDAP) + check_library_exists_concat("wldap32" cldap_open HAVE_WLDAP32) + if(NOT HAVE_WLDAP32) + set(USE_WIN32_LDAP OFF) + endif() + endif() + endif() + + option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF) + mark_as_advanced(CMAKE_USE_OPENLDAP) + set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library") + set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library") + + if(CMAKE_USE_OPENLDAP AND USE_WIN32_LDAP) + message(FATAL_ERROR "Cannot use USE_WIN32_LDAP and CMAKE_USE_OPENLDAP at the same time") + endif() + + # Now that we know, we're not using windows LDAP... + if(USE_WIN32_LDAP) + check_include_file_concat("winldap.h" HAVE_WINLDAP_H) + check_include_file_concat("winber.h" HAVE_WINBER_H) + else() + # Check for LDAP + set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) + check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP) + check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER) + + set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES}) + set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory") + if(CMAKE_LDAP_INCLUDE_DIR) + list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR}) + endif() + check_include_file_concat("ldap.h" HAVE_LDAP_H) + check_include_file_concat("lber.h" HAVE_LBER_H) + + if(NOT HAVE_LDAP_H) + message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON") + set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE) + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used + elseif(NOT HAVE_LIBLDAP) + message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON") + set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE) + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used + else() + if(CMAKE_USE_OPENLDAP) + set(USE_OPENLDAP ON) + endif() + if(CMAKE_LDAP_INCLUDE_DIR) + include_directories(${CMAKE_LDAP_INCLUDE_DIR}) + endif() + set(NEED_LBER_H ON) + set(_HEADER_LIST) + if(HAVE_WINDOWS_H) + list(APPEND _HEADER_LIST "windows.h") + endif() + if(HAVE_SYS_TYPES_H) + list(APPEND _HEADER_LIST "sys/types.h") + endif() + list(APPEND _HEADER_LIST "ldap.h") + + set(_SRC_STRING "") + foreach(_HEADER ${_HEADER_LIST}) + set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n") + endforeach() + + set(_SRC_STRING + " + ${_INCLUDE_STRING} + int main(int argc, char ** argv) + { + BerValue *bvp = NULL; + BerElement *bep = ber_init(bvp); + ber_free(bep, 1); + return 0; + }" + ) + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DLDAP_DEPRECATED=1") + list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB}) + if(HAVE_LIBLBER) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB}) + endif() + check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H) + + if(NOT_NEED_LBER_H) + set(NEED_LBER_H OFF) + else() + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H") + endif() + endif() + endif() + +endif() + +# No ldap, no ldaps. +if(CURL_DISABLE_LDAP) + if(NOT CURL_DISABLE_LDAPS) + message(STATUS "LDAP needs to be enabled to support LDAPS") + set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE) + endif() +endif() + +if(NOT CURL_DISABLE_LDAPS) + check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H) + check_include_file_concat("ldapssl.h" HAVE_LDAPSSL_H) +endif() + +# Check for idn +check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2) + +# Check for symbol dlopen (same as HAVE_LIBDL) +check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN) + +option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON) +set(HAVE_LIBZ OFF) +set(HAVE_ZLIB_H OFF) +set(HAVE_ZLIB OFF) +if(CURL_ZLIB) + find_package(ZLIB QUIET) + if(ZLIB_FOUND) + set(HAVE_ZLIB_H ON) + set(HAVE_ZLIB ON) + set(HAVE_LIBZ ON) + list(APPEND CURL_LIBS ${ZLIB_LIBRARIES}) + include_directories(${ZLIB_INCLUDE_DIRS}) + list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) + endif() +endif() + +option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF) +set(HAVE_BROTLI OFF) +if(CURL_BROTLI) + find_package(BROTLI QUIET) + if(BROTLI_FOUND) + set(HAVE_BROTLI ON) + list(APPEND CURL_LIBS ${BROTLI_LIBRARIES}) + include_directories(${BROTLI_INCLUDE_DIRS}) + list(APPEND CMAKE_REQUIRED_INCLUDES ${BROTLI_INCLUDE_DIRS}) + endif() +endif() + +#libSSH2 +option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON) +mark_as_advanced(CMAKE_USE_LIBSSH2) +set(USE_LIBSSH2 OFF) +set(HAVE_LIBSSH2 OFF) +set(HAVE_LIBSSH2_H OFF) + +if(CMAKE_USE_LIBSSH2) + find_package(LibSSH2) + if(LIBSSH2_FOUND) + list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY}) + set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY}) + list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}") + include_directories("${LIBSSH2_INCLUDE_DIR}") + set(HAVE_LIBSSH2 ON) + set(USE_LIBSSH2 ON) + + # find_package has already found the headers + set(HAVE_LIBSSH2_H ON) + set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h") + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H") + + # now check for specific libssh2 symbols as they were added in different versions + set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h") + check_function_exists(libssh2_version HAVE_LIBSSH2_VERSION) + check_function_exists(libssh2_init HAVE_LIBSSH2_INIT) + check_function_exists(libssh2_exit HAVE_LIBSSH2_EXIT) + check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64) + check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE) + set(CMAKE_EXTRA_INCLUDE_FILES "") + endif() +endif() + +option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF) +mark_as_advanced(CMAKE_USE_GSSAPI) + +if(CMAKE_USE_GSSAPI) + find_package(GSS) + + set(HAVE_GSSAPI ${GSS_FOUND}) + if(GSS_FOUND) + + message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"") + + list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRECTORIES}) + check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H) + check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H) + check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H) + + if(GSS_FLAVOUR STREQUAL "Heimdal") + set(HAVE_GSSHEIMDAL ON) + else() # MIT + set(HAVE_GSSMIT ON) + set(_INCLUDE_LIST "") + if(HAVE_GSSAPI_GSSAPI_H) + list(APPEND _INCLUDE_LIST "gssapi/gssapi.h") + endif() + if(HAVE_GSSAPI_GSSAPI_GENERIC_H) + list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h") + endif() + if(HAVE_GSSAPI_GSSAPI_KRB5_H) + list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h") + endif() + + string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}") + string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}") + + foreach(_dir ${GSS_LINK_DIRECTORIES}) + set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"") + endforeach() + + set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}") + set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES}) + check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE) + if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE) + set(HAVE_OLD_GSSMIT ON) + endif() + + endif() + + include_directories(${GSS_INCLUDE_DIRECTORIES}) + link_directories(${GSS_LINK_DIRECTORIES}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}") + list(APPEND CURL_LIBS ${GSS_LIBRARIES}) + + else() + message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.") + endif() +endif() + +option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON) +if(ENABLE_UNIX_SOCKETS) + include(CheckStructHasMember) + check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS) +else() + unset(USE_UNIX_SOCKETS CACHE) +endif() + + +# +# CA handling +# +set(CURL_CA_BUNDLE "auto" CACHE STRING + "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") +set(CURL_CA_FALLBACK OFF CACHE BOOL + "Set ON to use built-in CA store of TLS backend. Defaults to OFF") +set(CURL_CA_PATH "auto" CACHE STRING + "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") + +if("${CURL_CA_BUNDLE}" STREQUAL "") + message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.") +elseif("${CURL_CA_BUNDLE}" STREQUAL "none") + unset(CURL_CA_BUNDLE CACHE) +elseif("${CURL_CA_BUNDLE}" STREQUAL "auto") + unset(CURL_CA_BUNDLE CACHE) + set(CURL_CA_BUNDLE_AUTODETECT TRUE) +else() + set(CURL_CA_BUNDLE_SET TRUE) +endif() + +if("${CURL_CA_PATH}" STREQUAL "") + message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.") +elseif("${CURL_CA_PATH}" STREQUAL "none") + unset(CURL_CA_PATH CACHE) +elseif("${CURL_CA_PATH}" STREQUAL "auto") + unset(CURL_CA_PATH CACHE) + set(CURL_CA_PATH_AUTODETECT TRUE) +else() + set(CURL_CA_PATH_SET TRUE) +endif() + +if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT) + # Skip autodetection of unset CA path because CA bundle is set explicitly +elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT) + # Skip autodetection of unset CA bundle because CA path is set explicitly +elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT) + # first try autodetecting a CA bundle, then a CA path + + if(CURL_CA_BUNDLE_AUTODETECT) + set(SEARCH_CA_BUNDLE_PATHS + /etc/ssl/certs/ca-certificates.crt + /etc/pki/tls/certs/ca-bundle.crt + /usr/share/ssl/certs/ca-bundle.crt + /usr/local/share/certs/ca-root-nss.crt + /etc/ssl/cert.pem) + + foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS}) + if(EXISTS "${SEARCH_CA_BUNDLE_PATH}") + message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}") + set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}") + set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set") + break() + endif() + endforeach() + endif() + + if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET)) + if(EXISTS "/etc/ssl/certs") + set(CURL_CA_PATH "/etc/ssl/certs") + set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set") + endif() + endif() +endif() + +if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS) + message(FATAL_ERROR + "CA path only supported by OpenSSL, GnuTLS or mbed TLS. " + "Set CURL_CA_PATH=none or enable one of those TLS backends.") +endif() + + +# Check for header files +if(NOT UNIX) + check_include_file_concat("windows.h" HAVE_WINDOWS_H) + check_include_file_concat("winsock.h" HAVE_WINSOCK_H) + check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H) + check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H) + if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL) + set(CURL_LIBS ${CURL_LIBS} "crypt32") + endif() +endif() + +check_include_file_concat("stdio.h" HAVE_STDIO_H) +check_include_file_concat("inttypes.h" HAVE_INTTYPES_H) +check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H) +check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H) +check_include_file_concat("sys/param.h" HAVE_SYS_PARAM_H) +check_include_file_concat("sys/poll.h" HAVE_SYS_POLL_H) +check_include_file_concat("sys/resource.h" HAVE_SYS_RESOURCE_H) +check_include_file_concat("sys/select.h" HAVE_SYS_SELECT_H) +check_include_file_concat("sys/socket.h" HAVE_SYS_SOCKET_H) +check_include_file_concat("sys/sockio.h" HAVE_SYS_SOCKIO_H) +check_include_file_concat("sys/stat.h" HAVE_SYS_STAT_H) +check_include_file_concat("sys/time.h" HAVE_SYS_TIME_H) +check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H) +check_include_file_concat("sys/uio.h" HAVE_SYS_UIO_H) +check_include_file_concat("sys/un.h" HAVE_SYS_UN_H) +check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H) +check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H) +check_include_file_concat("alloca.h" HAVE_ALLOCA_H) +check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H) +check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H) +check_include_file_concat("assert.h" HAVE_ASSERT_H) +check_include_file_concat("crypto.h" HAVE_CRYPTO_H) +check_include_file_concat("des.h" HAVE_DES_H) +check_include_file_concat("err.h" HAVE_ERR_H) +check_include_file_concat("errno.h" HAVE_ERRNO_H) +check_include_file_concat("fcntl.h" HAVE_FCNTL_H) +check_include_file_concat("idn2.h" HAVE_IDN2_H) +check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H) +check_include_file_concat("io.h" HAVE_IO_H) +check_include_file_concat("krb.h" HAVE_KRB_H) +check_include_file_concat("libgen.h" HAVE_LIBGEN_H) +check_include_file_concat("locale.h" HAVE_LOCALE_H) +check_include_file_concat("net/if.h" HAVE_NET_IF_H) +check_include_file_concat("netdb.h" HAVE_NETDB_H) +check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H) +check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H) + +check_include_file_concat("pem.h" HAVE_PEM_H) +check_include_file_concat("poll.h" HAVE_POLL_H) +check_include_file_concat("pwd.h" HAVE_PWD_H) +check_include_file_concat("rsa.h" HAVE_RSA_H) +check_include_file_concat("setjmp.h" HAVE_SETJMP_H) +check_include_file_concat("sgtty.h" HAVE_SGTTY_H) +check_include_file_concat("signal.h" HAVE_SIGNAL_H) +check_include_file_concat("ssl.h" HAVE_SSL_H) +check_include_file_concat("stdbool.h" HAVE_STDBOOL_H) +check_include_file_concat("stdint.h" HAVE_STDINT_H) +check_include_file_concat("stdio.h" HAVE_STDIO_H) +check_include_file_concat("stdlib.h" HAVE_STDLIB_H) +check_include_file_concat("string.h" HAVE_STRING_H) +check_include_file_concat("strings.h" HAVE_STRINGS_H) +check_include_file_concat("stropts.h" HAVE_STROPTS_H) +check_include_file_concat("termio.h" HAVE_TERMIO_H) +check_include_file_concat("termios.h" HAVE_TERMIOS_H) +check_include_file_concat("time.h" HAVE_TIME_H) +check_include_file_concat("unistd.h" HAVE_UNISTD_H) +check_include_file_concat("utime.h" HAVE_UTIME_H) +check_include_file_concat("x509.h" HAVE_X509_H) + +check_include_file_concat("process.h" HAVE_PROCESS_H) +check_include_file_concat("stddef.h" HAVE_STDDEF_H) +check_include_file_concat("dlfcn.h" HAVE_DLFCN_H) +check_include_file_concat("malloc.h" HAVE_MALLOC_H) +check_include_file_concat("memory.h" HAVE_MEMORY_H) +check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H) +check_include_file_concat("stdint.h" HAVE_STDINT_H) +check_include_file_concat("sockio.h" HAVE_SOCKIO_H) +check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H) + +check_type_size(size_t SIZEOF_SIZE_T) +check_type_size(ssize_t SIZEOF_SSIZE_T) +check_type_size("long long" SIZEOF_LONG_LONG) +check_type_size("long" SIZEOF_LONG) +check_type_size("short" SIZEOF_SHORT) +check_type_size("int" SIZEOF_INT) +check_type_size("__int64" SIZEOF___INT64) +check_type_size("long double" SIZEOF_LONG_DOUBLE) +check_type_size("time_t" SIZEOF_TIME_T) +if(NOT HAVE_SIZEOF_SSIZE_T) + if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T) + set(ssize_t long) + endif() + if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T) + set(ssize_t __int64) + endif() +endif() +# off_t is sized later, after the HAVE_FILE_OFFSET_BITS test + +if(HAVE_SIZEOF_LONG_LONG) + set(HAVE_LONGLONG 1) + set(HAVE_LL 1) +endif() + +find_file(RANDOM_FILE urandom /dev) +mark_as_advanced(RANDOM_FILE) + +# Check for some functions that are used +if(HAVE_LIBWS2_32) + set(CMAKE_REQUIRED_LIBRARIES ws2_32) +elseif(HAVE_LIBSOCKET) + set(CMAKE_REQUIRED_LIBRARIES socket) +endif() + +check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME) +check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET) +# poll on macOS is unreliable, it first did not exist, then was broken until +# fixed in 10.9 only to break again in 10.12. +if(NOT APPLE) + check_symbol_exists(poll "${CURL_INCLUDES}" HAVE_POLL) +endif() +check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT) +check_symbol_exists(strdup "${CURL_INCLUDES}" HAVE_STRDUP) +check_symbol_exists(strstr "${CURL_INCLUDES}" HAVE_STRSTR) +check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R) +check_symbol_exists(strftime "${CURL_INCLUDES}" HAVE_STRFTIME) +check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME) +check_symbol_exists(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP) +check_symbol_exists(stricmp "${CURL_INCLUDES}" HAVE_STRICMP) +check_symbol_exists(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI) +check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI) +check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM) +if(NOT HAVE_STRNCMPI) + set(HAVE_STRCMPI) +endif() +check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR) +check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R) +check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY) +check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR) +check_symbol_exists(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA) +check_symbol_exists(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R) +check_symbol_exists(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR) +check_symbol_exists(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR) +check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR) +check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET) +check_symbol_exists(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF) +check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP) +check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R) +check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT) +check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID) +check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R) +check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID) +check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME) +check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R) +check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R) + +check_symbol_exists(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME) +check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R) + +check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC) +check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO) +if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO) + set(HAVE_SIGNAL 1) +endif() +check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME) +check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL) +check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64) +check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R) +check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT) +check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR) +check_symbol_exists(fork "${CURL_INCLUDES}" HAVE_FORK) +check_symbol_exists(getaddrinfo "${CURL_INCLUDES}" HAVE_GETADDRINFO) +check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO) +check_symbol_exists(freeifaddrs "${CURL_INCLUDES}" HAVE_FREEIFADDRS) +check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE) +check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE) +check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME) +check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT) +check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE) +check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE) +check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT) +check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL) +check_symbol_exists(ioctl "${CURL_INCLUDES}" HAVE_IOCTL) +check_symbol_exists(setsockopt "${CURL_INCLUDES}" HAVE_SETSOCKOPT) +check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME) + +# symbol exists in win32, but function does not. +if(WIN32) + if(ENABLE_INET_PTON) + check_function_exists(inet_pton HAVE_INET_PTON) + # _WIN32_WINNT_VISTA (0x0600) + add_definitions(-D_WIN32_WINNT=0x0600) + else() + # _WIN32_WINNT_WINXP (0x0501) + add_definitions(-D_WIN32_WINNT=0x0501) + endif() +else() + check_function_exists(inet_pton HAVE_INET_PTON) +endif() + +check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR) +if(HAVE_FSETXATTR) + foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6) + curl_internal_test(${CURL_TEST}) + endforeach() +endif() + +# sigaction and sigsetjmp are special. Use special mechanism for +# detecting those, but only if previous attempt failed. +if(HAVE_SIGNAL_H) + check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) +endif() + +if(NOT HAVE_SIGSETJMP) + if(HAVE_SETJMP_H) + check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP) + if(HAVE_MACRO_SIGSETJMP) + set(HAVE_SIGSETJMP 1) + endif() + endif() +endif() + +# If there is no stricmp(), do not allow LDAP to parse URLs +if(NOT HAVE_STRICMP) + set(HAVE_LDAP_URL_PARSE 1) +endif() + +# Do curl specific tests +foreach(CURL_TEST + HAVE_FCNTL_O_NONBLOCK + HAVE_IOCTLSOCKET + HAVE_IOCTLSOCKET_CAMEL + HAVE_IOCTLSOCKET_CAMEL_FIONBIO + HAVE_IOCTLSOCKET_FIONBIO + HAVE_IOCTL_FIONBIO + HAVE_IOCTL_SIOCGIFADDR + HAVE_SETSOCKOPT_SO_NONBLOCK + HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + TIME_WITH_SYS_TIME + HAVE_O_NONBLOCK + HAVE_GETHOSTBYADDR_R_5 + HAVE_GETHOSTBYADDR_R_7 + HAVE_GETHOSTBYADDR_R_8 + HAVE_GETHOSTBYADDR_R_5_REENTRANT + HAVE_GETHOSTBYADDR_R_7_REENTRANT + HAVE_GETHOSTBYADDR_R_8_REENTRANT + HAVE_GETHOSTBYNAME_R_3 + HAVE_GETHOSTBYNAME_R_5 + HAVE_GETHOSTBYNAME_R_6 + HAVE_GETHOSTBYNAME_R_3_REENTRANT + HAVE_GETHOSTBYNAME_R_5_REENTRANT + HAVE_GETHOSTBYNAME_R_6_REENTRANT + HAVE_SOCKLEN_T + HAVE_IN_ADDR_T + HAVE_BOOL_T + STDC_HEADERS + RETSIGTYPE_TEST + HAVE_INET_NTOA_R_DECL + HAVE_INET_NTOA_R_DECL_REENTRANT + HAVE_GETADDRINFO + HAVE_FILE_OFFSET_BITS + ) + curl_internal_test(${CURL_TEST}) +endforeach() + +if(HAVE_FILE_OFFSET_BITS) + set(_FILE_OFFSET_BITS 64) + set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64") +endif() +check_type_size("off_t" SIZEOF_OFF_T) + +# include this header to get the type +set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCE_DIR}/include") +set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h") +check_type_size("curl_off_t" SIZEOF_CURL_OFF_T) +set(CMAKE_EXTRA_INCLUDE_FILES "") + +set(CMAKE_REQUIRED_FLAGS) + +foreach(CURL_TEST + HAVE_GLIBC_STRERROR_R + HAVE_POSIX_STRERROR_R + ) + curl_internal_test(${CURL_TEST}) +endforeach() + +# Check for reentrant +foreach(CURL_TEST + HAVE_GETHOSTBYADDR_R_5 + HAVE_GETHOSTBYADDR_R_7 + HAVE_GETHOSTBYADDR_R_8 + HAVE_GETHOSTBYNAME_R_3 + HAVE_GETHOSTBYNAME_R_5 + HAVE_GETHOSTBYNAME_R_6 + HAVE_INET_NTOA_R_DECL_REENTRANT) + if(NOT ${CURL_TEST}) + if(${CURL_TEST}_REENTRANT) + set(NEED_REENTRANT 1) + endif() + endif() +endforeach() + +if(NEED_REENTRANT) + foreach(CURL_TEST + HAVE_GETHOSTBYADDR_R_5 + HAVE_GETHOSTBYADDR_R_7 + HAVE_GETHOSTBYADDR_R_8 + HAVE_GETHOSTBYNAME_R_3 + HAVE_GETHOSTBYNAME_R_5 + HAVE_GETHOSTBYNAME_R_6) + set(${CURL_TEST} 0) + if(${CURL_TEST}_REENTRANT) + set(${CURL_TEST} 1) + endif() + endforeach() +endif() + +if(HAVE_INET_NTOA_R_DECL_REENTRANT) + set(HAVE_INET_NTOA_R_DECL 1) + set(NEED_REENTRANT 1) +endif() + +# Some other minor tests + +if(NOT HAVE_IN_ADDR_T) + set(in_addr_t "unsigned long") +endif() + +# Fix libz / zlib.h + +if(NOT CURL_SPECIAL_LIBZ) + if(NOT HAVE_LIBZ) + set(HAVE_ZLIB_H 0) + endif() + + if(NOT HAVE_ZLIB_H) + set(HAVE_LIBZ 0) + endif() +endif() + +# Check for nonblocking +set(HAVE_DISABLED_NONBLOCKING 1) +if(HAVE_FIONBIO OR + HAVE_IOCTLSOCKET OR + HAVE_IOCTLSOCKET_CASE OR + HAVE_O_NONBLOCK) + set(HAVE_DISABLED_NONBLOCKING) +endif() + +if(RETSIGTYPE_TEST) + set(RETSIGTYPE void) +else() + set(RETSIGTYPE int) +endif() + +if(CMAKE_COMPILER_IS_GNUCC AND APPLE) + include(CheckCCompilerFlag) + check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double) + if(HAVE_C_FLAG_Wno_long_double) + # The Mac version of GCC warns about use of long double. Disable it. + get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS) + if(MPRINTF_COMPILE_FLAGS) + set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double") + else() + set(MPRINTF_COMPILE_FLAGS "-Wno-long-double") + endif() + set_source_files_properties(mprintf.c PROPERTIES + COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS}) + endif() +endif() + +if(HAVE_SOCKLEN_T) + set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t") + if(WIN32) + set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h") + elseif(HAVE_SYS_SOCKET_H) + set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") + endif() + check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T) + set(CMAKE_EXTRA_INCLUDE_FILES) + if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T) + message(FATAL_ERROR + "Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log") + endif() +else() + set(CURL_TYPEOF_CURL_SOCKLEN_T int) + set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT}) +endif() + +# TODO test which of these headers are required +if(WIN32) + set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H}) +else() + set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H}) + set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H}) + set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H}) +endif() +set(CURL_PULL_STDINT_H ${HAVE_STDINT_H}) +set(CURL_PULL_INTTYPES_H ${HAVE_INTTYPES_H}) + +include(CMake/OtherTests.cmake) + +add_definitions(-DHAVE_CONFIG_H) + +# For Windows, all compilers used by CMake should support large files +if(WIN32) + set(USE_WIN32_LARGE_FILES ON) + + # Use the manifest embedded in the Windows Resource + set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST") +endif() + +if(MSVC) + # Disable default manifest added by CMake + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") + + add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) + if(CMAKE_C_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") + endif() +endif() + +if(CURL_WERROR) + if(MSVC_VERSION) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") + else() + # this assumes clang or gcc style options + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + endif() +endif() + +# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it). +function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE) + file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT) + string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + + string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + + string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${} + string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts. + file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT}) + +endfunction() + +if(WIN32 AND NOT CYGWIN) + set(CURL_INSTALL_CMAKE_DIR CMake) +else() + set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl) +endif() + +if(USE_MANUAL) + add_subdirectory(docs) +endif() + +add_subdirectory(lib) + +if(BUILD_CURL_EXE) + add_subdirectory(src) +endif() + +include(CTest) +if(BUILD_TESTING) + add_subdirectory(tests) +endif() + +# Helper to populate a list (_items) with a label when conditions (the remaining +# args) are satisfied +function(_add_if label) + # TODO need to disable policy CMP0054 (CMake 3.1) to allow this indirection + if(${ARGN}) + set(_items ${_items} "${label}" PARENT_SCOPE) + endif() +endfunction() + +# Clear list and try to detect available features +set(_items) +_add_if("WinSSL" SSL_ENABLED AND USE_WINDOWS_SSPI) +_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL) +_add_if("DarwinSSL" SSL_ENABLED AND USE_DARWINSSL) +_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS) +_add_if("IPv6" ENABLE_IPV6) +_add_if("unix-sockets" USE_UNIX_SOCKETS) +_add_if("libz" HAVE_LIBZ) +_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) +_add_if("IDN" HAVE_LIBIDN2) +_add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND + ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) +# TODO SSP1 (WinSSL) check is missing +_add_if("SSPI" USE_WINDOWS_SSPI) +_add_if("GSS-API" HAVE_GSSAPI) +# TODO SSP1 missing for SPNEGO +_add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) +_add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) +# NTLM support requires crypto function adaptions from various SSL libs +# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS +if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_DARWINSSL OR USE_MBEDTLS)) + _add_if("NTLM" 1) + # TODO missing option (autoconf: --enable-ntlm-wb) + _add_if("NTLM_WB" NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED) +endif() +# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP +_add_if("TLS-SRP" USE_TLS_SRP) +# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header +_add_if("HTTP2" USE_NGHTTP2) +string(REPLACE ";" " " SUPPORT_FEATURES "${_items}") +message(STATUS "Enabled features: ${SUPPORT_FEATURES}") + +# Clear list and try to detect available protocols +set(_items) +_add_if("HTTP" NOT CURL_DISABLE_HTTP) +_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED) +_add_if("FTP" NOT CURL_DISABLE_FTP) +_add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED) +_add_if("FILE" NOT CURL_DISABLE_FILE) +_add_if("TELNET" NOT CURL_DISABLE_TELNET) +_add_if("LDAP" NOT CURL_DISABLE_LDAP) +# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS +# TODO check HAVE_LDAP_SSL (in autoconf this is enabled with --enable-ldaps) +_add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND + ((USE_OPENLDAP AND SSL_ENABLED) OR + (NOT USE_OPENLDAP AND HAVE_LDAP_SSL))) +_add_if("DICT" NOT CURL_DISABLE_DICT) +_add_if("TFTP" NOT CURL_DISABLE_TFTP) +_add_if("GOPHER" NOT CURL_DISABLE_GOPHER) +_add_if("POP3" NOT CURL_DISABLE_POP3) +_add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED) +_add_if("IMAP" NOT CURL_DISABLE_IMAP) +_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED) +_add_if("SMTP" NOT CURL_DISABLE_SMTP) +_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED) +_add_if("SCP" USE_LIBSSH2) +_add_if("SFTP" USE_LIBSSH2) +_add_if("RTSP" NOT CURL_DISABLE_RTSP) +_add_if("RTMP" USE_LIBRTMP) +list(SORT _items) +string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}") +message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}") + +# curl-config needs the following options to be set. +set(CC "${CMAKE_C_COMPILER}") +# TODO probably put a -D... options here? +set(CONFIGURE_OPTIONS "") +# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB? +set(CPPFLAG_CURL_STATICLIB "") +set(CURLVERSION "${CURL_VERSION}") +set(ENABLE_SHARED "yes") +if(CURL_STATICLIB) + set(ENABLE_STATIC "yes") +else() + set(ENABLE_STATIC "no") +endif() +set(exec_prefix "\${prefix}") +set(includedir "\${prefix}/include") +set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}") +set(LIBCURL_LIBS "") +set(libdir "${CMAKE_INSTALL_PREFIX}/lib") +foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS}) + if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-") + set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}") + else() + set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}") + endif() +endforeach() +# "a" (Linux) or "lib" (Windows) +string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}") +set(prefix "${CMAKE_INSTALL_PREFIX}") +# Set this to "yes" to append all libraries on which -lcurl is dependent +set(REQUIRE_LIB_DEPS "no") +# SUPPORT_FEATURES +# SUPPORT_PROTOCOLS +set(VERSIONNUM "${CURL_VERSION_NUM}") + +# Finally generate a "curl-config" matching this config +configure_file("${CURL_SOURCE_DIR}/curl-config.in" + "${CURL_BINARY_DIR}/curl-config" @ONLY) +install(FILES "${CURL_BINARY_DIR}/curl-config" + DESTINATION bin + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + +# Finally generate a pkg-config file matching this config +configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in" + "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) +install(FILES "${CURL_BINARY_DIR}/libcurl.pc" + DESTINATION lib/pkgconfig) + +# This needs to be run very last so other parts of the scripts can take advantage of this. +if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE) + set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before") +endif() + +# install headers +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl" + DESTINATION include + FILES_MATCHING PATTERN "*.h") + + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/curl-config-version.cmake" + VERSION ${CURL_VERSION} + COMPATIBILITY SameMajorVersion +) + +configure_file(CMake/curl-config.cmake + "${PROJECT_BINARY_DIR}/curl-config.cmake" + COPYONLY +) + +install( + FILES ${PROJECT_BINARY_DIR}/curl-config.cmake + ${PROJECT_BINARY_DIR}/curl-config-version.cmake + DESTINATION ${CURL_INSTALL_CMAKE_DIR} +) + +# Workaround for MSVS10 to avoid the Dialog Hell +# FIXME: This could be removed with future version of CMake. +if(MSVC_VERSION EQUAL 1600) + set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln") + if(EXISTS "${CURL_SLN_FILENAME}") + file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n") + endif() +endif() + +if(NOT TARGET uninstall) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake + IMMEDIATE @ONLY) + + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake) +endif() diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..560a49dc --- /dev/null +++ b/COPYING @@ -0,0 +1,22 @@ +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1996 - 2018, Daniel Stenberg, , and many +contributors, see the THANKS file. + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. diff --git a/GIT-INFO b/GIT-INFO new file mode 100644 index 00000000..51df76ab --- /dev/null +++ b/GIT-INFO @@ -0,0 +1,44 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +GIT-INFO + +This file is only present in git - never in release archives. It contains +information about other files and things that the git repository keeps in its +inner sanctum. + +To build in environments that support configure, after having extracted +everything from git, do this: + +./buildconf +./configure +make + + Daniel uses a ./configure line similar to this for easier development: + + ./configure --disable-shared --enable-debug --enable-maintainer-mode + +In environments that don't support configure (i.e. Microsoft), do this: + +buildconf.bat + + +REQUIREMENTS + + For buildconf (not buildconf.bat) to work, you need the following software +installed: + + o autoconf 2.57 (or later) + o automake 1.7 (or later) + o libtool 1.4.2 (or later) + o GNU m4 (required by autoconf) + + o nroff + perl + + If you don't have nroff and perl and you for some reason don't want to + install them, you can rename the source file src/tool_hugehelp.c.cvs to + src/tool_hugehelp.c and avoid having to generate this file. This will + give you a stubbed version of the file that doesn't contain actual content. diff --git a/MacOSX-Framework b/MacOSX-Framework new file mode 100755 index 00000000..e6badcde --- /dev/null +++ b/MacOSX-Framework @@ -0,0 +1,137 @@ +#!/bin/bash +# This script performs all of the steps needed to build a +# universal binary libcurl.framework for Mac OS X 10.4 or greater. +# +# Hendrik Visage: +# Generalizations added since Snowleopard (10.6) do not include +# the 10.4u SDK. +# +# Also note: +# 10.5 is the *ONLY* SDK that support PPC64 :( -- 10.6 do not have ppc64 support +#If you need to have PPC64 support then change below to 1 +PPC64_NEEDED=0 +# Apple does not support building for PPC anymore in Xcode 4 and later. +# If you're using Xcode 3 or earlier and need PPC support, then change +# the setting below to 1 +PPC_NEEDED=0 + +# For me the default is to develop for the platform I am on, and if you +#desire compatibility with older versions then change USE_OLD to 1 :) +USE_OLD=0 + +VERSION=`/usr/bin/sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' include/curl/curlver.h` +FRAMEWORK_VERSION=Versions/Release-$VERSION + +#I also wanted to "copy over" the system, and thus the reason I added the +# version to Versions/Release-7.20.1 etc. +# now a simple rsync -vaP libcurl.framework /Library/Frameworks will install it +# and setup the right paths to this version, leaving the system version +# "intact", so you can "fix" it later with the links to Versions/A/... + +DEVELOPER_PATH=`xcode-select --print-path` +# Around Xcode 4.3, SDKs were moved from the Developer folder into the +# MacOSX.platform folder +if test -d "$DEVELOPER_PATH/Platforms/MacOSX.platform/Developer/SDKs"; then + SDK_PATH="$DEVELOPER_PATH/Platforms/MacOSX.platform/Developer/SDKs" +else + SDK_PATH="$DEVELOPER_PATH/SDKs"; +fi +OLD_SDK=`ls $SDK_PATH|head -1` +NEW_SDK=`ls -r $SDK_PATH|head -1` + +if test "0"$USE_OLD -gt 0 +then + SDK32=$OLD_SDK +else + SDK32=$NEW_SDK +fi + +MACVER=`echo $SDK32|sed -e s/[a-zA-Z]//g -e s/.\$//` + +SDK32_DIR=$SDK_PATH/$SDK32 +MINVER32='-mmacosx-version-min='$MACVER +if test $PPC_NEEDED -gt 0; then + ARCHES32='-arch i386 -arch ppc' +else + ARCHES32='-arch i386' +fi + +if test $PPC64_NEEDED -gt 0 +then + SDK64=10.5 + ARCHES64='-arch x86_64 -arch ppc64' + SDK64=`ls $SDK_PATH|grep 10.5|head -1` +else + ARCHES64='-arch x86_64' + #We "know" that 10.4 and earlier do not support 64bit + OLD_SDK64=`ls $SDK_PATH|egrep -v "10.[0-4]"|head -1` + NEW_SDK64=`ls -r $SDK_PATH|egrep -v "10.[0-4][^0-9]" | head -1` + if test $USE_OLD -gt 0 + then + SDK64=$OLD_SDK64 + else + SDK64=$NEW_SDK64 + fi +fi + +SDK64_DIR=$SDK_PATH/$SDK64 +MACVER64=`echo $SDK64|sed -e s/[a-zA-Z]//g -e s/.\$//` + +MINVER64='-mmacosx-version-min='$MACVER64 + +if test ! -z $SDK32; then + echo "----Configuring libcurl for 32 bit universal framework..." + make clean + ./configure --disable-dependency-tracking --disable-static --with-gssapi --with-darwinssl \ + CFLAGS="-Os -isysroot $SDK32_DIR $ARCHES32" \ + LDFLAGS="-Wl,-syslibroot,$SDK32_DIR $ARCHES32 -Wl,-headerpad_max_install_names" \ + CC=$CC + + echo "----Building 32 bit libcurl..." + make -j `sysctl -n hw.logicalcpu_max` + + echo "----Creating 32 bit framework..." + rm -r libcurl.framework + mkdir -p libcurl.framework/${FRAMEWORK_VERSION}/Resources + cp lib/.libs/libcurl.dylib libcurl.framework/${FRAMEWORK_VERSION}/libcurl + install_name_tool -id @rpath/libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl + /usr/bin/sed -e "s/7\.12\.3/$VERSION/" lib/libcurl.plist >libcurl.framework/${FRAMEWORK_VERSION}/Resources/Info.plist + mkdir -p libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl + cp include/curl/*.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl + pushd libcurl.framework + ln -fs ${FRAMEWORK_VERSION}/libcurl libcurl + ln -fs ${FRAMEWORK_VERSION}/Resources Resources + ln -fs ${FRAMEWORK_VERSION}/Headers Headers + cd Versions + ln -fs $(basename "${FRAMEWORK_VERSION}") Current + + echo Testing for SDK64 + if test -d $SDK64_DIR; then + echo entering... + popd + make clean + echo "----Configuring libcurl for 64 bit universal framework..." + ./configure --disable-dependency-tracking --disable-static --with-gssapi --with-darwinssl \ + CFLAGS="-Os -isysroot $SDK64_DIR $ARCHES64" \ + LDFLAGS="-Wl,-syslibroot,$SDK64_DIR $ARCHES64 -Wl,-headerpad_max_install_names" \ + CC=$CC + + echo "----Building 64 bit libcurl..." + make -j `sysctl -n hw.logicalcpu_max` + + echo "----Appending 64 bit framework to 32 bit framework..." + cp lib/.libs/libcurl.dylib libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 + install_name_tool -id @rpath/libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 + cp libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 + pwd + lipo libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 -create -output libcurl.framework/${FRAMEWORK_VERSION}/libcurl + rm libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 + fi + + pwd + lipo -info libcurl.framework/${FRAMEWORK_VERSION}/libcurl + echo "libcurl.framework is built and can now be included in other projects." + echo "Copy libcurl.framework to your bundle's Contents/Frameworks folder, ~/Library/Frameworks or /Library/Frameworks." +else + echo "Building libcurl.framework requires Mac OS X 10.4 or later with the MacOSX10.4/5/6 SDK installed." +fi diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..bf6bfa98 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,644 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +AUTOMAKE_OPTIONS = foreign + +ACLOCAL_AMFLAGS = -I m4 + +CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \ + CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake \ + CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake \ + CMake/Macros.cmake \ + CMake/CurlSymbolHiding.cmake CMake/FindCARES.cmake \ + CMake/FindLibSSH2.cmake CMake/FindNGHTTP2.cmake \ + CMake/FindMbedTLS.cmake CMake/cmake_uninstall.cmake.in \ + CMake/curl-config.cmake + +VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl +VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist +VC6_LIBDSP_DEPS = $(VC6_LIBTMPL) Makefile.am lib/Makefile.inc +VC6_SRCTMPL = projects/Windows/VC6/src/curl.tmpl +VC6_SRCDSP = projects/Windows/VC6/src/curl.dsp.dist +VC6_SRCDSP_DEPS = $(VC6_SRCTMPL) Makefile.am src/Makefile.inc + +VC7_LIBTMPL = projects/Windows/VC7/lib/libcurl.tmpl +VC7_LIBVCPROJ = projects/Windows/VC7/lib/libcurl.vcproj.dist +VC7_LIBVCPROJ_DEPS = $(VC7_LIBTMPL) Makefile.am lib/Makefile.inc +VC7_SRCTMPL = projects/Windows/VC7/src/curl.tmpl +VC7_SRCVCPROJ = projects/Windows/VC7/src/curl.vcproj.dist +VC7_SRCVCPROJ_DEPS = $(VC7_SRCTMPL) Makefile.am src/Makefile.inc + +VC71_LIBTMPL = projects/Windows/VC7.1/lib/libcurl.tmpl +VC71_LIBVCPROJ = projects/Windows/VC7.1/lib/libcurl.vcproj.dist +VC71_LIBVCPROJ_DEPS = $(VC71_LIBTMPL) Makefile.am lib/Makefile.inc +VC71_SRCTMPL = projects/Windows/VC7.1/src/curl.tmpl +VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curl.vcproj.dist +VC71_SRCVCPROJ_DEPS = $(VC71_SRCTMPL) Makefile.am src/Makefile.inc + +VC8_LIBTMPL = projects/Windows/VC8/lib/libcurl.tmpl +VC8_LIBVCPROJ = projects/Windows/VC8/lib/libcurl.vcproj.dist +VC8_LIBVCPROJ_DEPS = $(VC8_LIBTMPL) Makefile.am lib/Makefile.inc +VC8_SRCTMPL = projects/Windows/VC8/src/curl.tmpl +VC8_SRCVCPROJ = projects/Windows/VC8/src/curl.vcproj.dist +VC8_SRCVCPROJ_DEPS = $(VC8_SRCTMPL) Makefile.am src/Makefile.inc + +VC9_LIBTMPL = projects/Windows/VC9/lib/libcurl.tmpl +VC9_LIBVCPROJ = projects/Windows/VC9/lib/libcurl.vcproj.dist +VC9_LIBVCPROJ_DEPS = $(VC9_LIBTMPL) Makefile.am lib/Makefile.inc +VC9_SRCTMPL = projects/Windows/VC9/src/curl.tmpl +VC9_SRCVCPROJ = projects/Windows/VC9/src/curl.vcproj.dist +VC9_SRCVCPROJ_DEPS = $(VC9_SRCTMPL) Makefile.am src/Makefile.inc + +VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl +VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist +VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc +VC10_SRCTMPL = projects/Windows/VC10/src/curl.tmpl +VC10_SRCVCXPROJ = projects/Windows/VC10/src/curl.vcxproj.dist +VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc + +VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl +VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist +VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc +VC11_SRCTMPL = projects/Windows/VC11/src/curl.tmpl +VC11_SRCVCXPROJ = projects/Windows/VC11/src/curl.vcxproj.dist +VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc + +VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl +VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist +VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc +VC12_SRCTMPL = projects/Windows/VC12/src/curl.tmpl +VC12_SRCVCXPROJ = projects/Windows/VC12/src/curl.vcxproj.dist +VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc + +VC14_LIBTMPL = projects/Windows/VC14/lib/libcurl.tmpl +VC14_LIBVCXPROJ = projects/Windows/VC14/lib/libcurl.vcxproj.dist +VC14_LIBVCXPROJ_DEPS = $(VC14_LIBTMPL) Makefile.am lib/Makefile.inc +VC14_SRCTMPL = projects/Windows/VC14/src/curl.tmpl +VC14_SRCVCXPROJ = projects/Windows/VC14/src/curl.vcxproj.dist +VC14_SRCVCXPROJ_DEPS = $(VC14_SRCTMPL) Makefile.am src/Makefile.inc + +VC15_LIBTMPL = projects/Windows/VC15/lib/libcurl.tmpl +VC15_LIBVCXPROJ = projects/Windows/VC15/lib/libcurl.vcxproj.dist +VC15_LIBVCXPROJ_DEPS = $(VC15_LIBTMPL) Makefile.am lib/Makefile.inc +VC15_SRCTMPL = projects/Windows/VC15/src/curl.tmpl +VC15_SRCVCXPROJ = projects/Windows/VC15/src/curl.vcxproj.dist +VC15_SRCVCXPROJ_DEPS = $(VC15_SRCTMPL) Makefile.am src/Makefile.inc + +VC_DIST = projects/README \ + projects/build-openssl.bat \ + projects/build-wolfssl.bat \ + projects/checksrc.bat \ + projects/Windows/VC6/curl-all.dsw \ + projects/Windows/VC6/lib/libcurl.dsw \ + projects/Windows/VC6/src/curl.dsw \ + projects/Windows/VC7/curl-all.sln \ + projects/Windows/VC7/lib/libcurl.sln \ + projects/Windows/VC7/src/curl.sln \ + projects/Windows/VC7.1/curl-all.sln \ + projects/Windows/VC7.1/lib/libcurl.sln \ + projects/Windows/VC7.1/src/curl.sln \ + projects/Windows/VC8/curl-all.sln \ + projects/Windows/VC8/lib/libcurl.sln \ + projects/Windows/VC8/src/curl.sln \ + projects/Windows/VC9/curl-all.sln \ + projects/Windows/VC9/lib/libcurl.sln \ + projects/Windows/VC9/src/curl.sln \ + projects/Windows/VC10/curl-all.sln \ + projects/Windows/VC10/lib/libcurl.sln \ + projects/Windows/VC10/lib/libcurl.vcxproj.filters \ + projects/Windows/VC10/src/curl.sln \ + projects/Windows/VC10/src/curl.vcxproj.filters \ + projects/Windows/VC11/curl-all.sln \ + projects/Windows/VC11/lib/libcurl.sln \ + projects/Windows/VC11/lib/libcurl.vcxproj.filters \ + projects/Windows/VC11/src/curl.sln \ + projects/Windows/VC11/src/curl.vcxproj.filters \ + projects/Windows/VC12/curl-all.sln \ + projects/Windows/VC12/lib/libcurl.sln \ + projects/Windows/VC12/lib/libcurl.vcxproj.filters \ + projects/Windows/VC12/src/curl.sln \ + projects/Windows/VC12/src/curl.vcxproj.filters \ + projects/Windows/VC14/curl-all.sln \ + projects/Windows/VC14/lib/libcurl.sln \ + projects/Windows/VC14/lib/libcurl.vcxproj.filters \ + projects/Windows/VC14/src/curl.sln \ + projects/Windows/VC14/src/curl.vcxproj.filters \ + projects/Windows/VC15/curl-all.sln \ + projects/Windows/VC15/lib/libcurl.sln \ + projects/Windows/VC15/lib/libcurl.vcxproj.filters \ + projects/Windows/VC15/src/curl.sln \ + projects/Windows/VC15/src/curl.vcxproj.filters \ + projects/generate.bat \ + projects/wolfssl_options.h \ + projects/wolfssl_override.props + +WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \ + winbuild/MakefileBuild.vc winbuild/Makefile.vc + +EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \ + RELEASE-NOTES buildconf libcurl.pc.in MacOSX-Framework scripts/zsh.pl \ + scripts/updatemanpages.pl $(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) \ + lib/libcurl.vers.in buildconf.bat scripts/coverage.sh + +CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \ + $(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \ + $(VC9_LIBVCPROJ) $(VC9_SRCVCPROJ) $(VC10_LIBVCXPROJ) $(VC10_SRCVCXPROJ) \ + $(VC11_LIBVCXPROJ) $(VC11_SRCVCXPROJ) $(VC12_LIBVCXPROJ) $(VC12_SRCVCXPROJ) \ + $(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ) $(VC15_LIBVCXPROJ) $(VC15_SRCVCXPROJ) + +bin_SCRIPTS = curl-config + +SUBDIRS = lib src +DIST_SUBDIRS = $(SUBDIRS) tests packages scripts include docs + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libcurl.pc + +# List of files required to generate VC IDE .dsp, .vcproj and .vcxproj files +include lib/Makefile.inc +include src/Makefile.inc + +dist-hook: + rm -rf $(top_builddir)/tests/log + find $(distdir) -name "*.dist" -exec rm {} \; + (distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \ + for file in $$distit; do \ + strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ + cp -p $$file $(distdir)$$strip; \ + done) + +html: + cd docs && $(MAKE) html + +pdf: + cd docs && $(MAKE) pdf + +check: test examples check-docs + +if CROSSCOMPILING +test-full: test +test-torture: test + +test: + @echo "NOTICE: we can't run the tests when cross-compiling!" + +else + +test: + @(cd tests; $(MAKE) all quiet-test) + +test-full: + @(cd tests; $(MAKE) all full-test) + +test-nonflaky: + @(cd tests; $(MAKE) all nonflaky-test) + +test-torture: + @(cd tests; $(MAKE) all torture-test) + +test-event: + @(cd tests; $(MAKE) all event-test) + +test-am: + @(cd tests; $(MAKE) all am-test) + +endif + +examples: + @(cd docs/examples; $(MAKE) check) + +check-docs: + @(cd docs/libcurl; $(MAKE) check) + +# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros +# must contain the following line: +# %_topdir /home/loic/local/rpm +# and that /home/loic/local/rpm contains the directory SOURCES, BUILD etc. +# +# cd /home/loic/local/rpm ; mkdir -p SOURCES BUILD RPMS/i386 SPECS SRPMS +# +# If additional configure flags are needed to build the package, add the +# following in ~/.rpmmacros +# %configure CFLAGS="%{optflags}" ./configure %{_target_platform} --prefix=%{_prefix} ${AM_CONFIGFLAGS} +# and run make rpm in the following way: +# AM_CONFIGFLAGS='--with-uri=/home/users/loic/local/RedHat-6.2' make rpm +# + +rpms: + $(MAKE) RPMDIST=curl rpm + $(MAKE) RPMDIST=curl-ssl rpm + +rpm: + RPM_TOPDIR=`rpm --showrc | $(PERL) -n -e 'print if(s/.*_topdir\s+(.*)/$$1/)'` ; \ + cp $(srcdir)/packages/Linux/RPM/$(RPMDIST).spec $$RPM_TOPDIR/SPECS ; \ + cp $(PACKAGE)-$(VERSION).tar.gz $$RPM_TOPDIR/SOURCES ; \ + rpm -ba --clean --rmsource $$RPM_TOPDIR/SPECS/$(RPMDIST).spec ; \ + mv $$RPM_TOPDIR/RPMS/i386/$(RPMDIST)-*.rpm . ; \ + mv $$RPM_TOPDIR/SRPMS/$(RPMDIST)-*.src.rpm . + +# +# Build a Solaris pkgadd format file +# run 'make pkgadd' once you've done './configure' and 'make' to make a Solaris pkgadd format +# file (which ends up back in this directory). +# The pkgadd file is in 'pkgtrans' format, so to install on Solaris, do +# pkgadd -d ./HAXXcurl-* +# + +# gak - libtool requires an absolute directory, hence the pwd below... +pkgadd: + umask 022 ; \ + $(MAKE) install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \ + cat COPYING > $(srcdir)/packages/Solaris/copyright ; \ + cd $(srcdir)/packages/Solaris && $(MAKE) package + +# +# Build a cygwin binary tarball installation file +# resulting .tar.bz2 file will end up at packages/Win32/cygwin +cygwinbin: + $(MAKE) -C packages/Win32/cygwin cygwinbin + +# We extend the standard install with a custom hook: +install-data-hook: + cd include && $(MAKE) install + cd docs && $(MAKE) install + cd docs/libcurl && $(MAKE) install + +# We extend the standard uninstall with a custom hook: +uninstall-hook: + cd include && $(MAKE) uninstall + cd docs && $(MAKE) uninstall + cd docs/libcurl && $(MAKE) uninstall + +ca-bundle: lib/mk-ca-bundle.pl + @echo "generating a fresh ca-bundle.crt" + @perl $< -b -l -u lib/ca-bundle.crt + +ca-firefox: lib/firefox-db2pem.sh + @echo "generating a fresh ca-bundle.crt" + ./lib/firefox-db2pem.sh lib/ca-bundle.crt + +checksrc: + cd lib && $(MAKE) checksrc + cd src && $(MAKE) checksrc + cd tests && $(MAKE) checksrc + cd include/curl && $(MAKE) checksrc + cd docs/examples && $(MAKE) checksrc + +.PHONY: vc-ide + +vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \ + $(VC7_SRCVCPROJ_DEPS) $(VC71_LIBVCPROJ_DEPS) $(VC71_SRCVCPROJ_DEPS) \ + $(VC8_LIBVCPROJ_DEPS) $(VC8_SRCVCPROJ_DEPS) $(VC9_LIBVCPROJ_DEPS) \ + $(VC9_SRCVCPROJ_DEPS) $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_DEPS) \ + $(VC11_LIBVCXPROJ_DEPS) $(VC11_SRCVCXPROJ_DEPS) $(VC12_LIBVCXPROJ_DEPS) \ + $(VC12_SRCVCXPROJ_DEPS) $(VC14_LIBVCXPROJ_DEPS) $(VC14_SRCVCXPROJ_DEPS) \ + $(VC15_LIBVCXPROJ_DEPS) $(VC15_SRCVCXPROJ_DEPS) + @(win32_lib_srcs='$(LIB_CFILES)'; \ + win32_lib_hdrs='$(LIB_HFILES) config-win32.h'; \ + win32_lib_rc='$(LIB_RCFILES)'; \ + win32_lib_vauth_srcs='$(LIB_VAUTH_CFILES)'; \ + win32_lib_vauth_hdrs='$(LIB_VAUTH_HFILES)'; \ + win32_lib_vtls_srcs='$(LIB_VTLS_CFILES)'; \ + win32_lib_vtls_hdrs='$(LIB_VTLS_HFILES)'; \ + win32_src_srcs='$(CURL_CFILES)'; \ + win32_src_hdrs='$(CURL_HFILES)'; \ + win32_src_rc='$(CURL_RCFILES)'; \ + win32_src_x_srcs='$(CURLX_CFILES)'; \ + win32_src_x_hdrs='$(CURLX_HFILES) ../lib/config-win32.h'; \ + \ + sorted_lib_srcs=`for file in $$win32_lib_srcs; do echo $$file; done | sort`; \ + sorted_lib_hdrs=`for file in $$win32_lib_hdrs; do echo $$file; done | sort`; \ + sorted_lib_vauth_srcs=`for file in $$win32_lib_vauth_srcs; do echo $$file; done | sort`; \ + sorted_lib_vauth_hdrs=`for file in $$win32_lib_vauth_hdrs; do echo $$file; done | sort`; \ + sorted_lib_vtls_srcs=`for file in $$win32_lib_vtls_srcs; do echo $$file; done | sort`; \ + sorted_lib_vtls_hdrs=`for file in $$win32_lib_vtls_hdrs; do echo $$file; done | sort`; \ + sorted_src_srcs=`for file in $$win32_src_srcs; do echo $$file; done | sort`; \ + sorted_src_hdrs=`for file in $$win32_src_hdrs; do echo $$file; done | sort`; \ + sorted_src_x_srcs=`for file in $$win32_src_x_srcs; do echo $$file; done | sort`; \ + sorted_src_x_hdrs=`for file in $$win32_src_x_hdrs; do echo $$file; done | sort`; \ + \ + awk_code='\ +function gen_element(type, dir, file)\ +{\ + sub(/vauth\//, "", file);\ + sub(/vtls\//, "", file);\ +\ + spaces=" ";\ + if(dir == "lib\\vauth" || dir == "lib\\vtls")\ + tabs=" ";\ + else\ + tabs=" ";\ +\ + if(type == "dsp") {\ + printf("# Begin Source File\r\n");\ + printf("\r\n");\ + printf("SOURCE=..\\..\\..\\..\\%s\\%s\r\n", dir, file);\ + printf("# End Source File\r\n");\ + }\ + else if(type == "vcproj1") {\ + printf("%s\r\n",\ + tabs, dir, file);\ + printf("%s\r\n", tabs);\ + }\ + else if(type == "vcproj2") {\ + printf("%s\r\n", tabs);\ + printf("%s\r\n", tabs);\ + }\ + else if(type == "vcxproj") {\ + i = index(file, ".");\ + ext = substr(file, i == 0 ? 0 : i + 1);\ +\ + if(ext == "c")\ + printf("%s\r\n",\ + spaces, dir, file);\ + else if(ext == "h")\ + printf("%s\r\n",\ + spaces, dir, file);\ + else if(ext == "rc")\ + printf("%s\r\n",\ + spaces, dir, file);\ + }\ +}\ +\ +{\ +\ + if($$0 == "CURL_LIB_C_FILES") {\ + split(lib_srcs, arr);\ + for(val in arr) gen_element(proj_type, "lib", arr[val]);\ + }\ + else if($$0 == "CURL_LIB_H_FILES") {\ + split(lib_hdrs, arr);\ + for(val in arr) gen_element(proj_type, "lib", arr[val]);\ + }\ + else if($$0 == "CURL_LIB_RC_FILES") {\ + split(lib_rc, arr);\ + for(val in arr) gen_element(proj_type, "lib", arr[val]);\ + }\ + else if($$0 == "CURL_LIB_VAUTH_C_FILES") {\ + split(lib_vauth_srcs, arr);\ + for(val in arr) gen_element(proj_type, "lib\\vauth", arr[val]);\ + }\ + else if($$0 == "CURL_LIB_VAUTH_H_FILES") {\ + split(lib_vauth_hdrs, arr);\ + for(val in arr) gen_element(proj_type, "lib\\vauth", arr[val]);\ + }\ + else if($$0 == "CURL_LIB_VTLS_C_FILES") {\ + split(lib_vtls_srcs, arr);\ + for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\ + }\ + else if($$0 == "CURL_LIB_VTLS_H_FILES") {\ + split(lib_vtls_hdrs, arr);\ + for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\ + }\ + else if($$0 == "CURL_SRC_C_FILES") {\ + split(src_srcs, arr);\ + for(val in arr) gen_element(proj_type, "src", arr[val]);\ + }\ + else if($$0 == "CURL_SRC_H_FILES") {\ + split(src_hdrs, arr);\ + for(val in arr) gen_element(proj_type, "src", arr[val]);\ + }\ + else if($$0 == "CURL_SRC_RC_FILES") {\ + split(src_rc, arr);\ + for(val in arr) gen_element(proj_type, "src", arr[val]);\ + }\ + else if($$0 == "CURL_SRC_X_C_FILES") {\ + split(src_x_srcs, arr);\ + for(val in arr) {\ + sub(/..\/lib\//, "", arr[val]);\ + gen_element(proj_type, "lib", arr[val]);\ + }\ + }\ + else if($$0 == "CURL_SRC_X_H_FILES") {\ + split(src_x_hdrs, arr);\ + for(val in arr) {\ + sub(/..\/lib\//, "", arr[val]);\ + gen_element(proj_type, "lib", arr[val]);\ + }\ + }\ + else\ + printf("%s\r\n", $$0);\ +}';\ + \ + echo "generating '$(VC6_LIBDSP)'"; \ + awk -v proj_type=dsp \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC6_LIBTMPL) > $(VC6_LIBDSP) || { exit 1; }; \ + \ + echo "generating '$(VC6_SRCDSP)'"; \ + awk -v proj_type=dsp \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC6_SRCTMPL) > $(VC6_SRCDSP) || { exit 1; }; \ + \ + echo "generating '$(VC7_LIBVCPROJ)'"; \ + awk -v proj_type=vcproj1 \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC7_LIBTMPL) > $(VC7_LIBVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC7_SRCVCPROJ)'"; \ + awk -v proj_type=vcproj1 \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC7_SRCTMPL) > $(VC7_SRCVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC71_LIBVCPROJ)'"; \ + awk -v proj_type=vcproj1 \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC71_LIBTMPL) > $(VC71_LIBVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC71_SRCVCPROJ)'"; \ + awk -v proj_type=vcproj1 \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC71_SRCTMPL) > $(VC71_SRCVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC8_LIBVCPROJ)'"; \ + awk -v proj_type=vcproj2 \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC8_LIBTMPL) > $(VC8_LIBVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC8_SRCVCPROJ)'"; \ + awk -v proj_type=vcproj2 \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC8_SRCTMPL) > $(VC8_SRCVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC9_LIBVCPROJ)'"; \ + awk -v proj_type=vcproj2 \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC9_LIBTMPL) > $(VC9_LIBVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC9_SRCVCPROJ)'"; \ + awk -v proj_type=vcproj2 \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC9_SRCTMPL) > $(VC9_SRCVCPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC10_LIBVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC10_LIBTMPL) > $(VC10_LIBVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC10_SRCVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC10_SRCTMPL) > $(VC10_SRCVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC11_LIBVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC11_LIBTMPL) > $(VC11_LIBVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC11_SRCVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC11_SRCTMPL) > $(VC11_SRCVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC12_LIBVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC12_LIBTMPL) > $(VC12_LIBVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC12_SRCVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC12_SRCTMPL) > $(VC12_SRCVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC14_LIBVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC14_LIBTMPL) > $(VC14_LIBVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC14_SRCVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC14_SRCTMPL) > $(VC14_SRCVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC15_LIBVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v lib_srcs="$$sorted_lib_srcs" \ + -v lib_hdrs="$$sorted_lib_hdrs" \ + -v lib_rc="$$win32_lib_rc" \ + -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ + -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ + -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ + -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ + "$$awk_code" $(srcdir)/$(VC15_LIBTMPL) > $(VC15_LIBVCXPROJ) || { exit 1; }; \ + \ + echo "generating '$(VC15_SRCVCXPROJ)'"; \ + awk -v proj_type=vcxproj \ + -v src_srcs="$$sorted_src_srcs" \ + -v src_hdrs="$$sorted_src_hdrs" \ + -v src_rc="$$win32_src_rc" \ + -v src_x_srcs="$$sorted_src_x_srcs" \ + -v src_x_hdrs="$$sorted_src_x_hdrs" \ + "$$awk_code" $(srcdir)/$(VC15_SRCTMPL) > $(VC15_SRCVCXPROJ) || { exit 1; };) diff --git a/Makefile.dist b/Makefile.dist new file mode 100644 index 00000000..a6316ab5 --- /dev/null +++ b/Makefile.dist @@ -0,0 +1,127 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +all: + ./configure + make + +ssl: + ./configure --with-ssl + make + +watcom: .SYMBOLIC + cd lib && $(MAKE) -u -f Makefile.Watcom + cd src && $(MAKE) -u -f Makefile.Watcom + +watcom-clean: .SYMBOLIC + cd lib && $(MAKE) -u -f Makefile.Watcom clean + cd src && $(MAKE) -u -f Makefile.Watcom clean + +watcom-vclean: .SYMBOLIC + cd lib && $(MAKE) -u -f Makefile.Watcom vclean + cd src && $(MAKE) -u -f Makefile.Watcom vclean + +mingw32: + $(MAKE) -C lib -f Makefile.m32 + $(MAKE) -C src -f Makefile.m32 + +mingw32-clean: + $(MAKE) -C lib -f Makefile.m32 clean + $(MAKE) -C src -f Makefile.m32 clean + $(MAKE) -C docs/examples -f Makefile.m32 clean + +mingw32-vclean mingw32-distclean: + $(MAKE) -C lib -f Makefile.m32 vclean + $(MAKE) -C src -f Makefile.m32 vclean + $(MAKE) -C docs/examples -f Makefile.m32 vclean + +mingw32-examples%: + $(MAKE) -C docs/examples -f Makefile.m32 CFG=$@ + +mingw32%: + $(MAKE) -C lib -f Makefile.m32 CFG=$@ + $(MAKE) -C src -f Makefile.m32 CFG=$@ + +vc: + cd winbuild + nmake /f Makefile.vc MACHINE=x86 + +vc-x64: + cd winbuild + nmake /f Makefile.vc MACHINE=x64 + +djgpp: + $(MAKE) -C lib -f Makefile.dj + $(MAKE) -C src -f Makefile.dj + +cygwin: + ./configure + make + +cygwin-ssl: + ./configure --with-ssl + make + +amiga: + cd ./lib && make -f makefile.amiga + cd ./src && make -f makefile.amiga + +netware: + $(MAKE) -C lib -f Makefile.netware + $(MAKE) -C src -f Makefile.netware + +netware-clean: + $(MAKE) -C lib -f Makefile.netware clean + $(MAKE) -C src -f Makefile.netware clean + $(MAKE) -C docs/examples -f Makefile.netware clean + +netware-vclean netware-distclean: + $(MAKE) -C lib -f Makefile.netware vclean + $(MAKE) -C src -f Makefile.netware vclean + $(MAKE) -C docs/examples -f Makefile.netware vclean + +netware-install: + $(MAKE) -C lib -f Makefile.netware install + $(MAKE) -C src -f Makefile.netware install + +netware-examples-%: + $(MAKE) -C docs/examples -f Makefile.netware CFG=$@ + +netware-%: + $(MAKE) -C lib -f Makefile.netware CFG=$@ + $(MAKE) -C src -f Makefile.netware CFG=$@ + +unix: all + +unix-ssl: ssl + +linux: all + +linux-ssl: ssl + +ca-bundle: lib/mk-ca-bundle.pl + @echo "generate a fresh ca-bundle.crt" + @perl $< -b -l -u lib/ca-bundle.crt + +ca-firefox: lib/firefox-db2pem.sh + @echo "generate a fresh ca-bundle.crt" + ./lib/firefox-db2pem.sh lib/ca-bundle.crt diff --git a/README b/README new file mode 100644 index 00000000..f0b3b939 --- /dev/null +++ b/README @@ -0,0 +1,49 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +README + + Curl is a command line tool for transferring data specified with URL + syntax. Find out how to use curl by reading the curl.1 man page or the + MANUAL document. Find out how to install Curl by reading the INSTALL + document. + + libcurl is the library curl is using to do its job. It is readily + available to be used by your software. Read the libcurl.3 man page to + learn how! + + You find answers to the most frequent questions we get in the FAQ document. + + Study the COPYING file for distribution terms and similar. If you distribute + curl binaries or other binaries that involve libcurl, you might enjoy the + LICENSE-MIXING document. + +CONTACT + + If you have problems, questions, ideas or suggestions, please contact us + by posting to a suitable mailing list. See https://curl.haxx.se/mail/ + + All contributors to the project are listed in the THANKS document. + +WEB SITE + + Visit the curl web site for the latest news and downloads: + + https://curl.haxx.se/ + +GIT + + To download the very latest source off the GIT server do this: + + git clone https://github.com/curl/curl.git + + (you'll get a directory named curl created, filled with the source code) + +NOTICE + + Curl contains pieces of source code that is Copyright (c) 1998, 1999 + Kungliga Tekniska Högskolan. This notice is included here to comply with the + distribution terms. diff --git a/README.md b/README.md new file mode 100644 index 00000000..e4dab23a --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +![curl logo](https://cdn.rawgit.com/curl/curl-www/master/logo/curl-logo.svg) + +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/63/badge)](https://bestpractices.coreinfrastructure.org/projects/63) +[![Coverity passed](https://scan.coverity.com/projects/curl/badge.svg)](https://scan.coverity.com/projects/curl) +[![Build Status](https://travis-ci.org/curl/curl.svg?branch=master)](https://travis-ci.org/curl/curl) +[![Coverage Status](https://coveralls.io/repos/github/curl/curl/badge.svg)](https://coveralls.io/github/curl/curl) +[![Backers on Open Collective](https://opencollective.com/curl/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/curl/sponsors/badge.svg)](#sponsors) + +Curl is a command-line tool for transferring data specified with URL +syntax. Find out how to use curl by reading [the curl.1 man +page](https://curl.haxx.se/docs/manpage.html) or [the MANUAL +document](https://curl.haxx.se/docs/manual.html). Find out how to install Curl +by reading [the INSTALL document](https://curl.haxx.se/docs/install.html). + +libcurl is the library curl is using to do its job. It is readily available to +be used by your software. Read [the libcurl.3 man +page](https://curl.haxx.se/libcurl/c/libcurl.html) to learn how! + +You find answers to the most frequent questions we get in [the FAQ +document](https://curl.haxx.se/docs/faq.html). + +Study [the COPYING file](https://curl.haxx.se/docs/copyright.html) for +distribution terms and similar. If you distribute curl binaries or other +binaries that involve libcurl, you might enjoy [the LICENSE-MIXING +document](https://curl.haxx.se/legal/licmix.html). + +## Contact + +If you have problems, questions, ideas or suggestions, please contact us by +posting to a suitable [mailing list](https://curl.haxx.se/mail/). + +All contributors to the project are listed in [the THANKS +document](https://curl.haxx.se/docs/thanks.html). + +## Website + +Visit the [curl web site](https://curl.haxx.se/) for the latest news and +downloads. + +## Git + +To download the very latest source from the Git server do this: + + git clone https://github.com/curl/curl.git + +(you'll get a directory named curl created, filled with the source code) + +## Notice + +Curl contains pieces of source code that is Copyright (c) 1998, 1999 Kungliga +Tekniska Högskolan. This notice is included here to comply with the +distribution terms. + +## Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/curl#backer)] + + + + +## Sponsors + +Support this project by becoming a sponsor. Your logo will show up here with a +link to your website. [[Become a +sponsor](https://opencollective.com/curl#sponsor)] + + + + + + + + + + + + + diff --git a/RELEASE-NOTES b/RELEASE-NOTES new file mode 100644 index 00000000..21fd6e9e --- /dev/null +++ b/RELEASE-NOTES @@ -0,0 +1,225 @@ +Curl and libcurl 7.61.0 + + Public curl releases: 175 + Command line options: 218 + curl_easy_setopt() options: 258 + Public functions in libcurl: 74 + Contributors: 1766 + +This release includes the following changes: + + o getinfo: add microsecond precise timers for seven intervals [3] + o curl: show headers in bold, switch off with --no-styled-output [10] + o httpauth: add support for Bearer tokens [16] + o Add CURLOPT_TLS13_CIPHERS and CURLOPT_PROXY_TLS13_CIPHERS [30] + o curl: --tls13-ciphers and --proxy-tls13-ciphers [30] + o Add CURLOPT_DISALLOW_USERNAME_IN_URL [32] + o curl: --disallow-username-in-url [32] + +This release includes the following bugfixes: + + o CVE-2018-0500: smtp: fix SMTP send buffer overflow [82] + o schannel: disable client cert option if APIs not available [1] + o schannel: disable manual verify if APIs not available + o tests/libtest/Makefile: Do not unconditionally add gcc-specific flags [2] + o openssl: acknowledge --tls-max for default version too [4] + o stub_gssapi: fix 'unused parameter' warnings + o examples/progressfunc: make it build on both new and old libcurls [5] + o docs: mention it is HA Proxy protocol "version 1" [6] + o curl_fnmatch: only allow two asterisks for matching [7] + o docs: clarify CURLOPT_HTTPGET [8] + o configure: replace a AC_TRY_RUN with CURL_RUN_IFELSE [9] + o configure: do compile-time SIZEOF checks instead of run-time [9] + o checksrc: make sure sizeof() is used *with* parentheses [11] + o CURLOPT_ACCEPT_ENCODING.3: add brotli and clarify a bit + o schannel: make CAinfo parsing resilient to CR/LF [12] + o tftp: make sure error is zero terminated before printfing it + o http resume: skip body if http code 416 (range error) is ignored [13] + o configure: add basic test of --with-ssl prefix [14] + o cmake: set -d postfix for debug builds [15] + o multi: provide a socket to wait for in Curl_protocol_getsock [17] + o content_encoding: handle zlib versions too old for Z_BLOCK [18] + o winbuild: only delete OUTFILE if it exists [19] + o winbuild: In MakefileBuild.vc fix typo DISTDIR->DIRDIST [20] + o schannel: add failf calls for client certificate failures [21] + o cmake: Fix the test for fsetxattr and strerror_r + o curl.1: Fix cmdline-opts reference errors [22] + o cmdline-opts/gen.pl: warn if mutexes: or see-also: list non-existing options + o cmake: check for getpwuid_r [23] + o configure: fix ssh2 linking when built with a static mbedtls [24] + o psl: use latest psl and refresh it periodically [25] + o fnmatch: insist on escaped bracket to match [26] + o KNOWN_BUGS: restore text regarding #2101 [27] + o INSTALL: LDFLAGS=-Wl,-R/usr/local/ssl/lib [28] + o configure: override AR_FLAGS to silence warning [29] + o os400: implement mime api EBCDIC wrappers + o curl.rc: embed manifest for correct Windows version detection [31] + o strictness: correct {infof, failf} format specifiers [33] + o tests: update .gitignore for libtests [34] + o configure: check for declaration of getpwuid_r [35] + o fnmatch: use the system one if available [36] + o CURLOPT_RESOLVE: always purge old entry first [37] + o multi: remove a potentially bad DEBUGF() [38] + o curl_addrinfo: use same #ifdef conditions in source as header + o build: remove the Borland specific makefiles [39] + o axTLS: not considered fit for use [40] + o cmdline-opts/cert-type.d: mention "p12" as a recognized type + o system.h: add support for IBM xlc C compiler [41] + o tests/libtest: Add lib1521 to nodist_SOURCES [42] + o mk-ca-bundle.pl: leave certificate name untouched [43] + o boringssl + schannel: undef X509_NAME in lib/schannel.h [44] + o openssl: assume engine support in 1.0.1 or later [45] + o cppcheck: fix warnings [46] + o test 46: make test pass after year 2025 [47] + o schannel: support selecting ciphers [48] + o Curl_debug: remove dead printhost code [49] + o test 1455: unflakified [50] + o Curl_init_do: handle NULL connection pointer passed in [51] + o progress: remove a set of unused defines [52] + o mk-ca-bundle.pl: make -u delete certdata.txt if found not changed [53] + o GOVERNANCE.md: explains how this project is run [54] + o configure: use pkg-config for c-ares detection [55] + o configure: enhance ability to build with static openssl [56] + o maketgz: fix sed issues on OSX [57] + o multi: fix memory leak when stopped during name resolve [58] + o CURLOPT_INTERFACE.3: interface names not supported on Windows + o url: fix dangling conn->data pointer [59] + o cmake: allow multiple SSL backends [60] + o system.h: fix for gcc on 32 bit OpenServer [61] + o ConnectionExists: make sure conn->data is set when "taking" a connection [62] + o multi: fix crash due to dangling entry in connect-pending list [63] + o CURLOPT_SSL_VERIFYPEER.3: Add performance note [64] + o netrc: use a larger buffer to support longer passwords [65] + o url: check Curl_conncache_add_conn return code [66] + o configure: Add dependent libraries after crypto [67] + o easy_perform: faster local name resolves by using *multi_timeout() [68] + o getnameinfo: not used, removed all configure checks [69] + o travis: add a build using the synchronous name resolver [70] + o CURLINFO_TLS_SSL_PTR.3: improve the example [71] + o openssl: allow TLS 1.3 by default [72] + o openssl: make the requested TLS version the *minimum* wanted [73] + o openssl: Remove some dead code [74] + o telnet: fix clang warnings [75] + o DEPRECATE: new doc describing planned item removals [76] + o example/crawler.c: simple crawler based on libxml2 [77] + o libssh: goto DISCONNECT state on error, not SESSION_FREE [78] + o CMake: Remove unused functions [79] + o darwinssl: allow High Sierra users to build the code using GCC [80] + o scripts: include _curl as part of CLEANFILES [81] + o examples: fix -Wformat warnings + o curl_setup: include before + o schannel: make more cipher options conditional [83] + o CMake: remove redundant and old end-of-block syntax [84] + o post303.d: clarify that this is an RFC violation [85] + +This release includes the following known bugs: + + o see docs/KNOWN_BUGS (https://curl.haxx.se/docs/knownbugs.html) + +This release would not have looked like this without help, code, reports and +advice from friends like these: + + Adrian Peniak, Alejandro R. Sedeño, Andreas Olsson, Archangel_SDY on github, + Bernhard M. Wiedemann, Bernhard Walle, Björn Stenberg, bsammon on github, + Dagobert Michelsen, Daniel Stenberg, Dario Nieuwenhuis, Dave Reisner, + elephoenix on github, Fabrice Fontaine, Frank Gevaerts, Gaurav Malhotra, + Gisle Vanem, Ithubg on github, Jakub Zakrzewski, Javier Blazquez, + Jeroen Ooms, Johannes Schindelin, Kevin R. Bulgrien, Linus Lewandowski, + Lyman Epp, Mamta Upadhyay, Marcel Raad, Marian Klymov, Matteo Bignotti, + Max Dymond, Max Savenkov, Nick Zitzmann, Oleg Pudeyev, Patrick Monnerat, + Patrick Schlangen, Per Malmberg, Peter Varga, Peter Wu, Philip Prindeville, + pszemus on github, Raphael Gozzo, Ray Satiro, Richard Alcock, + Rikard Falkeborn, Robert Prag, Ruslan Baratov, Sean Miller, Sergei Nikulov, + Stephan Mühlstrasser, Vasiliy Faronov, Viktor Szakats, Vladimir Kotal, + Will Dietz, Yaakov Selkowitz, zzq1015 on github, + (55 contributors) + + Thanks! (and sorry if I forgot to mention someone) + +References to bug reports and discussions on issues: + + [1] = https://curl.haxx.se/bug/?i=2522 + [2] = https://curl.haxx.se/bug/?i=2576 + [3] = https://curl.haxx.se/bug/?i=2495 + [4] = https://curl.haxx.se/bug/?i=2571 + [5] = https://curl.haxx.se/bug/?i=2584 + [6] = https://curl.haxx.se/bug/?i=2579 + [7] = https://curl.haxx.se/bug/?i=2587 + [8] = https://curl.haxx.se/bug/?i=2590 + [9] = https://curl.haxx.se/bug/?i=2586 + [10] = https://curl.haxx.se/bug/?i=2538 + [11] = https://curl.haxx.se/bug/?i=2563 + [12] = https://curl.haxx.se/bug/?i=2592 + [13] = https://curl.haxx.se/bug/?i=1163 + [14] = https://curl.haxx.se/bug/?i=2580 + [15] = https://curl.haxx.se/bug/?i=2121 + [16] = https://curl.haxx.se/bug/?i=2102 + [17] = https://curl.haxx.se/mail/lib-2018-05/0062.html + [18] = https://curl.haxx.se/bug/?i=2606 + [19] = https://curl.haxx.se/bug/?i=2602 + [20] = https://curl.haxx.se/bug/?i=2603 + [21] = https://curl.haxx.se/bug/?i=2604 + [22] = https://curl.haxx.se/bug/?i=2612 + [23] = https://curl.haxx.se/bug/?i=2609 + [24] = https://curl.haxx.se/bug/?i=2613 + [25] = https://curl.haxx.se/bug/?i=2553 + [26] = https://curl.haxx.se/bug/?i=2614 + [27] = https://curl.haxx.se/bug/?i=2618 + [28] = https://curl.haxx.se/bug/?i=2615 + [29] = https://curl.haxx.se/bug/?i=2617 + [30] = https://curl.haxx.se/bug/?i=2435 + [31] = https://curl.haxx.se/bug/?i=1221 + [32] = https://curl.haxx.se/bug/?i=2340 + [33] = https://curl.haxx.se/bug/?i=2623 + [34] = https://curl.haxx.se/bug/?i=2624 + [35] = https://curl.haxx.se/bug/?i=2609 + [36] = https://curl.haxx.se/bug/?i=2626 + [37] = https://curl.haxx.se/bug/?i=2622 + [38] = https://curl.haxx.se/bug/?i=2627 + [39] = https://curl.haxx.se/bug/?i=2629 + [40] = https://curl.haxx.se/bug/?i=2628 + [41] = https://curl.haxx.se/bug/?i=2637 + [42] = https://curl.haxx.se/bug/?i=2633 + [43] = https://curl.haxx.se/bug/?i=2640 + [44] = https://curl.haxx.se/bug/?i=2634 + [45] = https://curl.haxx.se/bug/?i=2641 + [46] = https://curl.haxx.se/bug/?i=2631 + [47] = https://curl.haxx.se/bug/?i=2646 + [48] = https://curl.haxx.se/bug/?i=2630 + [49] = https://curl.haxx.se/bug/?i=2647 + [50] = https://curl.haxx.se/bug/?i=2649 + [51] = https://curl.haxx.se/bug/?i=2653 + [52] = https://curl.haxx.se/bug/?i=2654 + [53] = https://curl.haxx.se/bug/?i=2655 + [54] = https://curl.haxx.se/bug/?i=2657 + [55] = https://curl.haxx.se/bug/?i=2203 + [56] = https://curl.haxx.se/bug/?i=2199 + [57] = https://curl.haxx.se/bug/?i=2660 + [58] = https://curl.haxx.se/bug/?i=1968 + [59] = https://curl.haxx.se/bug/?i=2669 + [60] = https://curl.haxx.se/bug/?i=2665 + [61] = https://curl.haxx.se/mail/lib-2018-06/0100.html + [62] = https://curl.haxx.se/bug/?i=2674 + [63] = https://curl.haxx.se/bug/?i=2677 + [64] = https://curl.haxx.se/bug/?i=2673 + [65] = https://curl.haxx.se/bug/?i=2676 + [66] = https://curl.haxx.se/bug/?i=2681 + [67] = https://curl.haxx.se/bug/?i=2684 + [68] = https://curl.haxx.se/bug/?i=2685 + [69] = https://curl.haxx.se/bug/?i=2687 + [70] = https://curl.haxx.se/bug/?i=2689 + [71] = https://curl.haxx.se/bug/?i=2690 + [72] = https://curl.haxx.se/bug/?i=2692 + [73] = https://curl.haxx.se/bug/?i=2691 + [74] = https://curl.haxx.se/bug/?i=2698 + [75] = https://curl.haxx.se/bug/?i=2696 + [76] = https://curl.haxx.se/dev/deprecate.html + [77] = https://curl.haxx.se/bug/?i=2706 + [78] = https://curl.haxx.se/bug/?i=2708 + [79] = https://curl.haxx.se/bug/?i=2711 + [80] = https://curl.haxx.se/bug/?i=2656 + [81] = https://curl.haxx.se/bug/?i=2718 + [82] = https://curl.haxx.se/docs/adv_2018-70a2.html + [83] = https://curl.haxx.se/bug/?i=2721 + [84] = https://curl.haxx.se/bug/?i=2715 + [85] = https://curl.haxx.se/bug/?i=2723 diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 00000000..f32e86cd --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,2665 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** + +dnl CURL_CHECK_DEF (SYMBOL, [INCLUDES], [SILENT]) +dnl ------------------------------------------------- +dnl Use the C preprocessor to find out if the given object-style symbol +dnl is defined and get its expansion. This macro will not use default +dnl includes even if no INCLUDES argument is given. This macro will run +dnl silently when invoked with three arguments. If the expansion would +dnl result in a set of double-quoted strings the returned expansion will +dnl actually be a single double-quoted string concatenating all them. + +AC_DEFUN([CURL_CHECK_DEF], [ + AC_REQUIRE([CURL_CPP_P])dnl + OLDCPPFLAGS=$CPPFLAGS + # CPPPFLAG comes from CURL_CPP_P + CPPFLAGS="$CPPFLAGS $CPPPFLAG" + AS_VAR_PUSHDEF([ac_HaveDef], [curl_cv_have_def_$1])dnl + AS_VAR_PUSHDEF([ac_Def], [curl_cv_def_$1])dnl + if test -z "$SED"; then + AC_MSG_ERROR([SED not set. Cannot continue without SED being set.]) + fi + if test -z "$GREP"; then + AC_MSG_ERROR([GREP not set. Cannot continue without GREP being set.]) + fi + ifelse($3,,[AC_MSG_CHECKING([for preprocessor definition of $1])]) + tmp_exp="" + AC_PREPROC_IFELSE([ + AC_LANG_SOURCE( +ifelse($2,,,[$2])[[ +#ifdef $1 +CURL_DEF_TOKEN $1 +#endif + ]]) + ],[ + tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \ + "$GREP" CURL_DEF_TOKEN 2>/dev/null | \ + "$SED" 's/.*CURL_DEF_TOKEN[[ ]][[ ]]*//' 2>/dev/null | \ + "$SED" 's/[["]][[ ]]*[["]]//g' 2>/dev/null` + if test -z "$tmp_exp" || test "$tmp_exp" = "$1"; then + tmp_exp="" + fi + ]) + if test -z "$tmp_exp"; then + AS_VAR_SET(ac_HaveDef, no) + ifelse($3,,[AC_MSG_RESULT([no])]) + else + AS_VAR_SET(ac_HaveDef, yes) + AS_VAR_SET(ac_Def, $tmp_exp) + ifelse($3,,[AC_MSG_RESULT([$tmp_exp])]) + fi + AS_VAR_POPDEF([ac_Def])dnl + AS_VAR_POPDEF([ac_HaveDef])dnl + CPPFLAGS=$OLDCPPFLAGS +]) + + +dnl CURL_CHECK_DEF_CC (SYMBOL, [INCLUDES], [SILENT]) +dnl ------------------------------------------------- +dnl Use the C compiler to find out only if the given symbol is defined +dnl or not, this can not find out its expansion. This macro will not use +dnl default includes even if no INCLUDES argument is given. This macro +dnl will run silently when invoked with three arguments. + +AC_DEFUN([CURL_CHECK_DEF_CC], [ + AS_VAR_PUSHDEF([ac_HaveDef], [curl_cv_have_def_$1])dnl + ifelse($3,,[AC_MSG_CHECKING([for compiler definition of $1])]) + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE( +ifelse($2,,,[$2])[[ +int main (void) +{ +#ifdef $1 + return 0; +#else + force compilation error +#endif +} + ]]) + ],[ + tst_symbol_defined="yes" + ],[ + tst_symbol_defined="no" + ]) + if test "$tst_symbol_defined" = "yes"; then + AS_VAR_SET(ac_HaveDef, yes) + ifelse($3,,[AC_MSG_RESULT([yes])]) + else + AS_VAR_SET(ac_HaveDef, no) + ifelse($3,,[AC_MSG_RESULT([no])]) + fi + AS_VAR_POPDEF([ac_HaveDef])dnl +]) + + +dnl CURL_CHECK_LIB_XNET +dnl ------------------------------------------------- +dnl Verify if X/Open network library is required. + +AC_DEFUN([CURL_CHECK_LIB_XNET], [ + AC_MSG_CHECKING([if X/Open network library is required]) + tst_lib_xnet_required="no" + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([[ +int main (void) +{ +#if defined(__hpux) && defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600) + return 0; +#elif defined(__hpux) && defined(_XOPEN_SOURCE_EXTENDED) + return 0; +#else + force compilation error +#endif +} + ]]) + ],[ + tst_lib_xnet_required="yes" + LIBS="-lxnet $LIBS" + ]) + AC_MSG_RESULT([$tst_lib_xnet_required]) +]) + + +dnl CURL_CHECK_AIX_ALL_SOURCE +dnl ------------------------------------------------- +dnl Provides a replacement of traditional AC_AIX with +dnl an uniform behaviour across all autoconf versions, +dnl and with our own placement rules. + +AC_DEFUN([CURL_CHECK_AIX_ALL_SOURCE], [ + AH_VERBATIM([_ALL_SOURCE], + [/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif]) + AC_BEFORE([$0], [AC_SYS_LARGEFILE])dnl + AC_BEFORE([$0], [CURL_CONFIGURE_REENTRANT])dnl + AC_BEFORE([$0], [CURL_CONFIGURE_PULL_SYS_POLL])dnl + AC_MSG_CHECKING([if OS is AIX (to define _ALL_SOURCE)]) + AC_EGREP_CPP([yes_this_is_aix],[ +#ifdef _AIX + yes_this_is_aix +#endif + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(_ALL_SOURCE) + ],[ + AC_MSG_RESULT([no]) + ]) +]) + + +dnl CURL_CHECK_HEADER_WINDOWS +dnl ------------------------------------------------- +dnl Check for compilable and valid windows.h header + +AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [ + AC_CACHE_CHECK([for windows.h], [curl_cv_header_windows_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + ]],[[ +#if defined(__CYGWIN__) || defined(__CEGCC__) + HAVE_WINDOWS_H shall not be defined. +#else + int dummy=2*WINVER; +#endif + ]]) + ],[ + curl_cv_header_windows_h="yes" + ],[ + curl_cv_header_windows_h="no" + ]) + ]) + case "$curl_cv_header_windows_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1, + [Define to 1 if you have the windows.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_NATIVE_WINDOWS +dnl ------------------------------------------------- +dnl Check if building a native Windows target + +AC_DEFUN([CURL_CHECK_NATIVE_WINDOWS], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl + AC_CACHE_CHECK([whether build target is a native Windows one], [curl_cv_native_windows], [ + if test "$curl_cv_header_windows_h" = "no"; then + curl_cv_native_windows="no" + else + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ +#if defined(__MINGW32__) || defined(__MINGW32CE__) || \ + (defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))) + int dummy=1; +#else + Not a native Windows build target. +#endif + ]]) + ],[ + curl_cv_native_windows="yes" + ],[ + curl_cv_native_windows="no" + ]) + fi + ]) + AM_CONDITIONAL(DOING_NATIVE_WINDOWS, test "x$curl_cv_native_windows" = xyes) +]) + + +dnl CURL_CHECK_HEADER_WINSOCK +dnl ------------------------------------------------- +dnl Check for compilable and valid winsock.h header + +AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl + AC_CACHE_CHECK([for winsock.h], [curl_cv_header_winsock_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include + ]],[[ +#if defined(__CYGWIN__) || defined(__CEGCC__) + HAVE_WINSOCK_H shall not be defined. +#else + int dummy=WSACleanup(); +#endif + ]]) + ],[ + curl_cv_header_winsock_h="yes" + ],[ + curl_cv_header_winsock_h="no" + ]) + ]) + case "$curl_cv_header_winsock_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1, + [Define to 1 if you have the winsock.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_WINSOCK2 +dnl ------------------------------------------------- +dnl Check for compilable and valid winsock2.h header + +AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl + AC_CACHE_CHECK([for winsock2.h], [curl_cv_header_winsock2_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include + ]],[[ +#if defined(__CYGWIN__) || defined(__CEGCC__) || defined(__MINGW32CE__) + HAVE_WINSOCK2_H shall not be defined. +#else + int dummy=2*IPPROTO_ESP; +#endif + ]]) + ],[ + curl_cv_header_winsock2_h="yes" + ],[ + curl_cv_header_winsock2_h="no" + ]) + ]) + case "$curl_cv_header_winsock2_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1, + [Define to 1 if you have the winsock2.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_WS2TCPIP +dnl ------------------------------------------------- +dnl Check for compilable and valid ws2tcpip.h header + +AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl + AC_CACHE_CHECK([for ws2tcpip.h], [curl_cv_header_ws2tcpip_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#include + ]],[[ +#if defined(__CYGWIN__) || defined(__CEGCC__) || defined(__MINGW32CE__) + HAVE_WS2TCPIP_H shall not be defined. +#else + int dummy=2*IP_PKTINFO; +#endif + ]]) + ],[ + curl_cv_header_ws2tcpip_h="yes" + ],[ + curl_cv_header_ws2tcpip_h="no" + ]) + ]) + case "$curl_cv_header_ws2tcpip_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1, + [Define to 1 if you have the ws2tcpip.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_WINLDAP +dnl ------------------------------------------------- +dnl Check for compilable and valid winldap.h header + +AC_DEFUN([CURL_CHECK_HEADER_WINLDAP], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl + AC_CACHE_CHECK([for winldap.h], [curl_cv_header_winldap_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif +#include + ]],[[ +#if defined(__CYGWIN__) || defined(__CEGCC__) + HAVE_WINLDAP_H shall not be defined. +#else + LDAP *ldp = ldap_init("dummy", LDAP_PORT); + ULONG res = ldap_unbind(ldp); +#endif + ]]) + ],[ + curl_cv_header_winldap_h="yes" + ],[ + curl_cv_header_winldap_h="no" + ]) + ]) + case "$curl_cv_header_winldap_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_WINLDAP_H, 1, + [Define to 1 if you have the winldap.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_WINBER +dnl ------------------------------------------------- +dnl Check for compilable and valid winber.h header + +AC_DEFUN([CURL_CHECK_HEADER_WINBER], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINLDAP])dnl + AC_CACHE_CHECK([for winber.h], [curl_cv_header_winber_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif +#include +#include + ]],[[ +#if defined(__CYGWIN__) || defined(__CEGCC__) + HAVE_WINBER_H shall not be defined. +#else + BERVAL *bvp = NULL; + BerElement *bep = ber_init(bvp); + ber_free(bep, 1); +#endif + ]]) + ],[ + curl_cv_header_winber_h="yes" + ],[ + curl_cv_header_winber_h="no" + ]) + ]) + case "$curl_cv_header_winber_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_WINBER_H, 1, + [Define to 1 if you have the winber.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_LBER +dnl ------------------------------------------------- +dnl Check for compilable and valid lber.h header, +dnl and check if it is needed even with ldap.h + +AC_DEFUN([CURL_CHECK_HEADER_LBER], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl + AC_CACHE_CHECK([for lber.h], [curl_cv_header_lber_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#endif +#ifndef NULL +#define NULL (void *)0 +#endif +#include + ]],[[ + BerValue *bvp = NULL; + BerElement *bep = ber_init(bvp); + ber_free(bep, 1); + ]]) + ],[ + curl_cv_header_lber_h="yes" + ],[ + curl_cv_header_lber_h="no" + ]) + ]) + if test "$curl_cv_header_lber_h" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_LBER_H, 1, + [Define to 1 if you have the lber.h header file.]) + # + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#endif +#ifndef NULL +#define NULL (void *)0 +#endif +#ifndef LDAP_DEPRECATED +#define LDAP_DEPRECATED 1 +#endif +#include + ]],[[ + BerValue *bvp = NULL; + BerElement *bep = ber_init(bvp); + ber_free(bep, 1); + ]]) + ],[ + curl_cv_need_header_lber_h="no" + ],[ + curl_cv_need_header_lber_h="yes" + ]) + # + case "$curl_cv_need_header_lber_h" in + yes) + AC_DEFINE_UNQUOTED(NEED_LBER_H, 1, + [Define to 1 if you need the lber.h header file even with ldap.h]) + ;; + esac + fi +]) + + +dnl CURL_CHECK_HEADER_LDAP +dnl ------------------------------------------------- +dnl Check for compilable and valid ldap.h header + +AC_DEFUN([CURL_CHECK_HEADER_LDAP], [ + AC_REQUIRE([CURL_CHECK_HEADER_LBER])dnl + AC_CACHE_CHECK([for ldap.h], [curl_cv_header_ldap_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#endif +#ifndef LDAP_DEPRECATED +#define LDAP_DEPRECATED 1 +#endif +#ifdef NEED_LBER_H +#include +#endif +#include + ]],[[ + LDAP *ldp = ldap_init("dummy", LDAP_PORT); + int res = ldap_unbind(ldp); + ]]) + ],[ + curl_cv_header_ldap_h="yes" + ],[ + curl_cv_header_ldap_h="no" + ]) + ]) + case "$curl_cv_header_ldap_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_LDAP_H, 1, + [Define to 1 if you have the ldap.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_LDAP_SSL +dnl ------------------------------------------------- +dnl Check for compilable and valid ldap_ssl.h header + +AC_DEFUN([CURL_CHECK_HEADER_LDAP_SSL], [ + AC_REQUIRE([CURL_CHECK_HEADER_LDAP])dnl + AC_CACHE_CHECK([for ldap_ssl.h], [curl_cv_header_ldap_ssl_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#endif +#ifndef LDAP_DEPRECATED +#define LDAP_DEPRECATED 1 +#endif +#ifdef NEED_LBER_H +#include +#endif +#ifdef HAVE_LDAP_H +#include +#endif +#include + ]],[[ + LDAP *ldp = ldapssl_init("dummy", LDAPS_PORT, 1); + ]]) + ],[ + curl_cv_header_ldap_ssl_h="yes" + ],[ + curl_cv_header_ldap_ssl_h="no" + ]) + ]) + case "$curl_cv_header_ldap_ssl_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_LDAP_SSL_H, 1, + [Define to 1 if you have the ldap_ssl.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_HEADER_LDAPSSL +dnl ------------------------------------------------- +dnl Check for compilable and valid ldapssl.h header + +AC_DEFUN([CURL_CHECK_HEADER_LDAPSSL], [ + AC_REQUIRE([CURL_CHECK_HEADER_LDAP])dnl + AC_CACHE_CHECK([for ldapssl.h], [curl_cv_header_ldapssl_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#endif +#ifndef NULL +#define NULL (void *)0 +#endif +#ifndef LDAP_DEPRECATED +#define LDAP_DEPRECATED 1 +#endif +#ifdef NEED_LBER_H +#include +#endif +#ifdef HAVE_LDAP_H +#include +#endif +#include + ]],[[ + char *cert_label = NULL; + LDAP *ldp = ldap_ssl_init("dummy", LDAPS_PORT, cert_label); + ]]) + ],[ + curl_cv_header_ldapssl_h="yes" + ],[ + curl_cv_header_ldapssl_h="no" + ]) + ]) + case "$curl_cv_header_ldapssl_h" in + yes) + AC_DEFINE_UNQUOTED(HAVE_LDAPSSL_H, 1, + [Define to 1 if you have the ldapssl.h header file.]) + ;; + esac +]) + + +dnl CURL_CHECK_LIBS_WINLDAP +dnl ------------------------------------------------- +dnl Check for libraries needed for WINLDAP support, +dnl and prepended to LIBS any needed libraries. +dnl This macro can take an optional parameter with a +dnl white space separated list of libraries to check +dnl before the WINLDAP default ones. + +AC_DEFUN([CURL_CHECK_LIBS_WINLDAP], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINBER])dnl + # + AC_MSG_CHECKING([for WINLDAP libraries]) + # + u_libs="" + # + ifelse($1,,,[ + for x_lib in $1; do + case "$x_lib" in + -l*) + l_lib="$x_lib" + ;; + *) + l_lib="-l$x_lib" + ;; + esac + if test -z "$u_libs"; then + u_libs="$l_lib" + else + u_libs="$u_libs $l_lib" + fi + done + ]) + # + curl_cv_save_LIBS="$LIBS" + curl_cv_ldap_LIBS="unknown" + # + for x_nlibs in '' "$u_libs" \ + '-lwldap32' ; do + if test "$curl_cv_ldap_LIBS" = "unknown"; then + if test -z "$x_nlibs"; then + LIBS="$curl_cv_save_LIBS" + else + LIBS="$x_nlibs $curl_cv_save_LIBS" + fi + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINLDAP_H +#include +#endif +#ifdef HAVE_WINBER_H +#include +#endif +#endif + ]],[[ + BERVAL *bvp = NULL; + BerElement *bep = ber_init(bvp); + LDAP *ldp = ldap_init("dummy", LDAP_PORT); + ULONG res = ldap_unbind(ldp); + ber_free(bep, 1); + ]]) + ],[ + curl_cv_ldap_LIBS="$x_nlibs" + ]) + fi + done + # + LIBS="$curl_cv_save_LIBS" + # + case X-"$curl_cv_ldap_LIBS" in + X-unknown) + AC_MSG_RESULT([cannot find WINLDAP libraries]) + ;; + X-) + AC_MSG_RESULT([no additional lib required]) + ;; + *) + if test -z "$curl_cv_save_LIBS"; then + LIBS="$curl_cv_ldap_LIBS" + else + LIBS="$curl_cv_ldap_LIBS $curl_cv_save_LIBS" + fi + AC_MSG_RESULT([$curl_cv_ldap_LIBS]) + ;; + esac + # +]) + + +dnl CURL_CHECK_LIBS_LDAP +dnl ------------------------------------------------- +dnl Check for libraries needed for LDAP support, +dnl and prepended to LIBS any needed libraries. +dnl This macro can take an optional parameter with a +dnl white space separated list of libraries to check +dnl before the default ones. + +AC_DEFUN([CURL_CHECK_LIBS_LDAP], [ + AC_REQUIRE([CURL_CHECK_HEADER_LDAP])dnl + # + AC_MSG_CHECKING([for LDAP libraries]) + # + u_libs="" + # + ifelse($1,,,[ + for x_lib in $1; do + case "$x_lib" in + -l*) + l_lib="$x_lib" + ;; + *) + l_lib="-l$x_lib" + ;; + esac + if test -z "$u_libs"; then + u_libs="$l_lib" + else + u_libs="$u_libs $l_lib" + fi + done + ]) + # + curl_cv_save_LIBS="$LIBS" + curl_cv_ldap_LIBS="unknown" + # + for x_nlibs in '' "$u_libs" \ + '-lldap' \ + '-lldap -llber' \ + '-llber -lldap' \ + '-lldapssl -lldapx -lldapsdk' \ + '-lldapsdk -lldapx -lldapssl' ; do + if test "$curl_cv_ldap_LIBS" = "unknown"; then + if test -z "$x_nlibs"; then + LIBS="$curl_cv_save_LIBS" + else + LIBS="$x_nlibs $curl_cv_save_LIBS" + fi + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#endif +#ifndef NULL +#define NULL (void *)0 +#endif +#ifndef LDAP_DEPRECATED +#define LDAP_DEPRECATED 1 +#endif +#ifdef NEED_LBER_H +#include +#endif +#ifdef HAVE_LDAP_H +#include +#endif + ]],[[ + BerValue *bvp = NULL; + BerElement *bep = ber_init(bvp); + LDAP *ldp = ldap_init("dummy", LDAP_PORT); + int res = ldap_unbind(ldp); + ber_free(bep, 1); + ]]) + ],[ + curl_cv_ldap_LIBS="$x_nlibs" + ]) + fi + done + # + LIBS="$curl_cv_save_LIBS" + # + case X-"$curl_cv_ldap_LIBS" in + X-unknown) + AC_MSG_RESULT([cannot find LDAP libraries]) + ;; + X-) + AC_MSG_RESULT([no additional lib required]) + ;; + *) + if test -z "$curl_cv_save_LIBS"; then + LIBS="$curl_cv_ldap_LIBS" + else + LIBS="$curl_cv_ldap_LIBS $curl_cv_save_LIBS" + fi + AC_MSG_RESULT([$curl_cv_ldap_LIBS]) + ;; + esac + # +]) + + +dnl CURL_CHECK_HEADER_MALLOC +dnl ------------------------------------------------- +dnl Check for compilable and valid malloc.h header, +dnl and check if it is needed even with stdlib.h + +AC_DEFUN([CURL_CHECK_HEADER_MALLOC], [ + AC_CACHE_CHECK([for malloc.h], [curl_cv_header_malloc_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include + ]],[[ + void *p = malloc(10); + void *q = calloc(10,10); + free(p); + free(q); + ]]) + ],[ + curl_cv_header_malloc_h="yes" + ],[ + curl_cv_header_malloc_h="no" + ]) + ]) + if test "$curl_cv_header_malloc_h" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_MALLOC_H, 1, + [Define to 1 if you have the malloc.h header file.]) + # + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include + ]],[[ + void *p = malloc(10); + void *q = calloc(10,10); + free(p); + free(q); + ]]) + ],[ + curl_cv_need_header_malloc_h="no" + ],[ + curl_cv_need_header_malloc_h="yes" + ]) + # + case "$curl_cv_need_header_malloc_h" in + yes) + AC_DEFINE_UNQUOTED(NEED_MALLOC_H, 1, + [Define to 1 if you need the malloc.h header file even with stdlib.h]) + ;; + esac + fi +]) + + +dnl CURL_CHECK_HEADER_MEMORY +dnl ------------------------------------------------- +dnl Check for compilable and valid memory.h header, +dnl and check if it is needed even with stdlib.h for +dnl memory related functions. + +AC_DEFUN([CURL_CHECK_HEADER_MEMORY], [ + AC_CACHE_CHECK([for memory.h], [curl_cv_header_memory_h], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include + ]],[[ + void *p = malloc(10); + void *q = calloc(10,10); + free(p); + free(q); + ]]) + ],[ + curl_cv_header_memory_h="yes" + ],[ + curl_cv_header_memory_h="no" + ]) + ]) + if test "$curl_cv_header_memory_h" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_MEMORY_H, 1, + [Define to 1 if you have the memory.h header file.]) + # + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include + ]],[[ + void *p = malloc(10); + void *q = calloc(10,10); + free(p); + free(q); + ]]) + ],[ + curl_cv_need_header_memory_h="no" + ],[ + curl_cv_need_header_memory_h="yes" + ]) + # + case "$curl_cv_need_header_memory_h" in + yes) + AC_DEFINE_UNQUOTED(NEED_MEMORY_H, 1, + [Define to 1 if you need the memory.h header file even with stdlib.h]) + ;; + esac + fi +]) + +dnl TYPE_SOCKADDR_STORAGE +dnl ------------------------------------------------- +dnl Check for struct sockaddr_storage. Most IPv6-enabled +dnl hosts have it, but AIX 4.3 is one known exception. + +AC_DEFUN([TYPE_SOCKADDR_STORAGE], +[ + AC_CHECK_TYPE([struct sockaddr_storage], + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, + [if struct sockaddr_storage is defined]), , + [ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#endif +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#endif + ]) +]) + +dnl CURL_CHECK_FUNC_RECV +dnl ------------------------------------------------- +dnl Test if the socket recv() function is available, +dnl and check its return type and the types of its +dnl arguments. If the function succeeds HAVE_RECV +dnl will be defined, defining the types of the arguments +dnl in RECV_TYPE_ARG1, RECV_TYPE_ARG2, RECV_TYPE_ARG3 +dnl and RECV_TYPE_ARG4, defining the type of the function +dnl return value in RECV_TYPE_RETV. + +AC_DEFUN([CURL_CHECK_FUNC_RECV], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl + AC_CHECK_HEADERS(sys/types.h sys/socket.h) + # + AC_MSG_CHECKING([for recv]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#endif + ]],[[ + recv(0, 0, 0, 0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + curl_cv_recv="yes" + ],[ + AC_MSG_RESULT([no]) + curl_cv_recv="no" + ]) + # + if test "$curl_cv_recv" = "yes"; then + AC_CACHE_CHECK([types of args and return type for recv], + [curl_cv_func_recv_args], [ + curl_cv_func_recv_args="unknown" + for recv_retv in 'int' 'ssize_t'; do + for recv_arg1 in 'int' 'ssize_t' 'SOCKET'; do + for recv_arg2 in 'char *' 'void *'; do + for recv_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do + for recv_arg4 in 'int' 'unsigned int'; do + if test "$curl_cv_func_recv_args" = "unknown"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#define RECVCALLCONV PASCAL +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#define RECVCALLCONV +#endif + extern $recv_retv RECVCALLCONV +#ifdef __ANDROID__ +__attribute__((overloadable)) +#endif + recv($recv_arg1, $recv_arg2, $recv_arg3, $recv_arg4); + ]],[[ + $recv_arg1 s=0; + $recv_arg2 buf=0; + $recv_arg3 len=0; + $recv_arg4 flags=0; + $recv_retv res = recv(s, buf, len, flags); + ]]) + ],[ + curl_cv_func_recv_args="$recv_arg1,$recv_arg2,$recv_arg3,$recv_arg4,$recv_retv" + ]) + fi + done + done + done + done + done + ]) # AC-CACHE-CHECK + if test "$curl_cv_func_recv_args" = "unknown"; then + AC_MSG_ERROR([Cannot find proper types to use for recv args]) + else + recv_prev_IFS=$IFS; IFS=',' + set dummy `echo "$curl_cv_func_recv_args" | sed 's/\*/\*/g'` + IFS=$recv_prev_IFS + shift + # + AC_DEFINE_UNQUOTED(RECV_TYPE_ARG1, $[1], + [Define to the type of arg 1 for recv.]) + AC_DEFINE_UNQUOTED(RECV_TYPE_ARG2, $[2], + [Define to the type of arg 2 for recv.]) + AC_DEFINE_UNQUOTED(RECV_TYPE_ARG3, $[3], + [Define to the type of arg 3 for recv.]) + AC_DEFINE_UNQUOTED(RECV_TYPE_ARG4, $[4], + [Define to the type of arg 4 for recv.]) + AC_DEFINE_UNQUOTED(RECV_TYPE_RETV, $[5], + [Define to the function return type for recv.]) + # + AC_DEFINE_UNQUOTED(HAVE_RECV, 1, + [Define to 1 if you have the recv function.]) + curl_cv_func_recv="yes" + fi + else + AC_MSG_ERROR([Unable to link function recv]) + fi +]) + + +dnl CURL_CHECK_FUNC_SEND +dnl ------------------------------------------------- +dnl Test if the socket send() function is available, +dnl and check its return type and the types of its +dnl arguments. If the function succeeds HAVE_SEND +dnl will be defined, defining the types of the arguments +dnl in SEND_TYPE_ARG1, SEND_TYPE_ARG2, SEND_TYPE_ARG3 +dnl and SEND_TYPE_ARG4, defining the type of the function +dnl return value in SEND_TYPE_RETV, and also defining the +dnl type qualifier of second argument in SEND_QUAL_ARG2. + +AC_DEFUN([CURL_CHECK_FUNC_SEND], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl + AC_CHECK_HEADERS(sys/types.h sys/socket.h) + # + AC_MSG_CHECKING([for send]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#endif + ]],[[ + send(0, 0, 0, 0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + curl_cv_send="yes" + ],[ + AC_MSG_RESULT([no]) + curl_cv_send="no" + ]) + # + if test "$curl_cv_send" = "yes"; then + AC_CACHE_CHECK([types of args and return type for send], + [curl_cv_func_send_args], [ + curl_cv_func_send_args="unknown" + for send_retv in 'int' 'ssize_t'; do + for send_arg1 in 'int' 'ssize_t' 'SOCKET'; do + for send_arg2 in 'char *' 'void *' 'const char *' 'const void *'; do + for send_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do + for send_arg4 in 'int' 'unsigned int'; do + if test "$curl_cv_func_send_args" = "unknown"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#define SENDCALLCONV PASCAL +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#define SENDCALLCONV +#endif + extern $send_retv SENDCALLCONV +#ifdef __ANDROID__ +__attribute__((overloadable)) +#endif + send($send_arg1, $send_arg2, $send_arg3, $send_arg4); + ]],[[ + $send_arg1 s=0; + $send_arg3 len=0; + $send_arg4 flags=0; + $send_retv res = send(s, 0, len, flags); + ]]) + ],[ + curl_cv_func_send_args="$send_arg1,$send_arg2,$send_arg3,$send_arg4,$send_retv" + ]) + fi + done + done + done + done + done + ]) # AC-CACHE-CHECK + if test "$curl_cv_func_send_args" = "unknown"; then + AC_MSG_ERROR([Cannot find proper types to use for send args]) + else + send_prev_IFS=$IFS; IFS=',' + set dummy `echo "$curl_cv_func_send_args" | sed 's/\*/\*/g'` + IFS=$send_prev_IFS + shift + # + send_qual_type_arg2=$[2] + # + AC_DEFINE_UNQUOTED(SEND_TYPE_ARG1, $[1], + [Define to the type of arg 1 for send.]) + AC_DEFINE_UNQUOTED(SEND_TYPE_ARG3, $[3], + [Define to the type of arg 3 for send.]) + AC_DEFINE_UNQUOTED(SEND_TYPE_ARG4, $[4], + [Define to the type of arg 4 for send.]) + AC_DEFINE_UNQUOTED(SEND_TYPE_RETV, $[5], + [Define to the function return type for send.]) + # + prev_sh_opts=$- + # + case $prev_sh_opts in + *f*) + ;; + *) + set -f + ;; + esac + # + case "$send_qual_type_arg2" in + const*) + send_qual_arg2=const + send_type_arg2=`echo $send_qual_type_arg2 | sed 's/^const //'` + ;; + *) + send_qual_arg2= + send_type_arg2=$send_qual_type_arg2 + ;; + esac + # + AC_DEFINE_UNQUOTED(SEND_QUAL_ARG2, $send_qual_arg2, + [Define to the type qualifier of arg 2 for send.]) + AC_DEFINE_UNQUOTED(SEND_TYPE_ARG2, $send_type_arg2, + [Define to the type of arg 2 for send.]) + # + case $prev_sh_opts in + *f*) + ;; + *) + set +f + ;; + esac + # + AC_DEFINE_UNQUOTED(HAVE_SEND, 1, + [Define to 1 if you have the send function.]) + curl_cv_func_send="yes" + fi + else + AC_MSG_ERROR([Unable to link function send]) + fi +]) + +dnl CURL_CHECK_MSG_NOSIGNAL +dnl ------------------------------------------------- +dnl Check for MSG_NOSIGNAL + +AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [ + AC_CHECK_HEADERS(sys/types.h sys/socket.h) + AC_CACHE_CHECK([for MSG_NOSIGNAL], [curl_cv_msg_nosignal], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#endif + ]],[[ + int flag=MSG_NOSIGNAL; + ]]) + ],[ + curl_cv_msg_nosignal="yes" + ],[ + curl_cv_msg_nosignal="no" + ]) + ]) + case "$curl_cv_msg_nosignal" in + yes) + AC_DEFINE_UNQUOTED(HAVE_MSG_NOSIGNAL, 1, + [Define to 1 if you have the MSG_NOSIGNAL flag.]) + ;; + esac +]) + + +dnl CURL_CHECK_STRUCT_TIMEVAL +dnl ------------------------------------------------- +dnl Check for timeval struct + +AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [ + AC_REQUIRE([AC_HEADER_TIME])dnl + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl + AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl + AC_CHECK_HEADERS(sys/types.h sys/time.h time.h sys/socket.h) + AC_CACHE_CHECK([for struct timeval], [curl_cv_struct_timeval], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + ]],[[ + struct timeval ts; + ts.tv_sec = 0; + ts.tv_usec = 0; + ]]) + ],[ + curl_cv_struct_timeval="yes" + ],[ + curl_cv_struct_timeval="no" + ]) + ]) + case "$curl_cv_struct_timeval" in + yes) + AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1, + [Define to 1 if you have the timeval struct.]) + ;; + esac +]) + + +dnl TYPE_SIG_ATOMIC_T +dnl ------------------------------------------------- +dnl Check if the sig_atomic_t type is available, and +dnl verify if it is already defined as volatile. + +AC_DEFUN([TYPE_SIG_ATOMIC_T], [ + AC_CHECK_HEADERS(signal.h) + AC_CHECK_TYPE([sig_atomic_t],[ + AC_DEFINE(HAVE_SIG_ATOMIC_T, 1, + [Define to 1 if sig_atomic_t is an available typedef.]) + ], ,[ +#ifdef HAVE_SIGNAL_H +#include +#endif + ]) + case "$ac_cv_type_sig_atomic_t" in + yes) + # + AC_MSG_CHECKING([if sig_atomic_t is already defined as volatile]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#ifdef HAVE_SIGNAL_H +#include +#endif + ]],[[ + static volatile sig_atomic_t dummy = 0; + ]]) + ],[ + AC_MSG_RESULT([no]) + curl_cv_sig_atomic_t_volatile="no" + ],[ + AC_MSG_RESULT([yes]) + curl_cv_sig_atomic_t_volatile="yes" + ]) + # + if test "$curl_cv_sig_atomic_t_volatile" = "yes"; then + AC_DEFINE(HAVE_SIG_ATOMIC_T_VOLATILE, 1, + [Define to 1 if sig_atomic_t is already defined as volatile.]) + fi + ;; + esac +]) + + +dnl TYPE_IN_ADDR_T +dnl ------------------------------------------------- +dnl Check for in_addr_t: it is used to receive the return code of inet_addr() +dnl and a few other things. + +AC_DEFUN([TYPE_IN_ADDR_T], [ + AC_CHECK_TYPE([in_addr_t], ,[ + dnl in_addr_t not available + AC_CACHE_CHECK([for in_addr_t equivalent], + [curl_cv_in_addr_t_equiv], [ + curl_cv_in_addr_t_equiv="unknown" + for t in "unsigned long" int size_t unsigned long; do + if test "$curl_cv_in_addr_t_equiv" = "unknown"; then + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#endif + ]],[[ + $t data = inet_addr ("1.2.3.4"); + ]]) + ],[ + curl_cv_in_addr_t_equiv="$t" + ]) + fi + done + ]) + case "$curl_cv_in_addr_t_equiv" in + unknown) + AC_MSG_ERROR([Cannot find a type to use in place of in_addr_t]) + ;; + *) + AC_DEFINE_UNQUOTED(in_addr_t, $curl_cv_in_addr_t_equiv, + [Type to use in place of in_addr_t when system does not provide it.]) + ;; + esac + ],[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#else +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#endif + ]) +]) + + +dnl CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC +dnl ------------------------------------------------- +dnl Check if monotonic clock_gettime is available. + +AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [ + AC_REQUIRE([AC_HEADER_TIME])dnl + AC_CHECK_HEADERS(sys/types.h sys/time.h time.h) + AC_MSG_CHECKING([for monotonic clock_gettime]) + # + if test "x$dontwant_rt" = "xno" ; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif + ]],[[ + struct timespec ts; + (void)clock_gettime(CLOCK_MONOTONIC, &ts); + ]]) + ],[ + AC_MSG_RESULT([yes]) + curl_func_clock_gettime="yes" + ],[ + AC_MSG_RESULT([no]) + curl_func_clock_gettime="no" + ]) + fi + dnl Definition of HAVE_CLOCK_GETTIME_MONOTONIC is intentionally postponed + dnl until library linking and run-time checks for clock_gettime succeed. +]) + + +dnl CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC +dnl ------------------------------------------------- +dnl If monotonic clock_gettime is available then, +dnl check and prepended to LIBS any needed libraries. + +AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [ + AC_REQUIRE([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC])dnl + # + if test "$curl_func_clock_gettime" = "yes"; then + # + AC_MSG_CHECKING([for clock_gettime in libraries]) + # + curl_cv_save_LIBS="$LIBS" + curl_cv_gclk_LIBS="unknown" + # + for x_xlibs in '' '-lrt' '-lposix4' ; do + if test "$curl_cv_gclk_LIBS" = "unknown"; then + if test -z "$x_xlibs"; then + LIBS="$curl_cv_save_LIBS" + else + LIBS="$x_xlibs $curl_cv_save_LIBS" + fi + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif + ]],[[ + struct timespec ts; + (void)clock_gettime(CLOCK_MONOTONIC, &ts); + ]]) + ],[ + curl_cv_gclk_LIBS="$x_xlibs" + ]) + fi + done + # + LIBS="$curl_cv_save_LIBS" + # + case X-"$curl_cv_gclk_LIBS" in + X-unknown) + AC_MSG_RESULT([cannot find clock_gettime]) + AC_MSG_WARN([HAVE_CLOCK_GETTIME_MONOTONIC will not be defined]) + curl_func_clock_gettime="no" + ;; + X-) + AC_MSG_RESULT([no additional lib required]) + curl_func_clock_gettime="yes" + ;; + *) + if test -z "$curl_cv_save_LIBS"; then + LIBS="$curl_cv_gclk_LIBS" + else + LIBS="$curl_cv_gclk_LIBS $curl_cv_save_LIBS" + fi + AC_MSG_RESULT([$curl_cv_gclk_LIBS]) + curl_func_clock_gettime="yes" + ;; + esac + # + dnl only do runtime verification when not cross-compiling + if test "x$cross_compiling" != "xyes" && + test "$curl_func_clock_gettime" = "yes"; then + AC_MSG_CHECKING([if monotonic clock_gettime works]) + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif + ]],[[ + struct timespec ts; + if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) + exit(0); + else + exit(1); + ]]) + ],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_WARN([HAVE_CLOCK_GETTIME_MONOTONIC will not be defined]) + curl_func_clock_gettime="no" + LIBS="$curl_cv_save_LIBS" + ]) + fi + # + case "$curl_func_clock_gettime" in + yes) + AC_DEFINE_UNQUOTED(HAVE_CLOCK_GETTIME_MONOTONIC, 1, + [Define to 1 if you have the clock_gettime function and monotonic timer.]) + ;; + esac + # + fi + # +]) + + +dnl CURL_CHECK_LIBS_CONNECT +dnl ------------------------------------------------- +dnl Verify if network connect function is already available +dnl using current libraries or if another one is required. + +AC_DEFUN([CURL_CHECK_LIBS_CONNECT], [ + AC_REQUIRE([CURL_INCLUDES_WINSOCK2])dnl + AC_MSG_CHECKING([for connect in libraries]) + tst_connect_save_LIBS="$LIBS" + tst_connect_need_LIBS="unknown" + for tst_lib in '' '-lsocket' ; do + if test "$tst_connect_need_LIBS" = "unknown"; then + LIBS="$tst_lib $tst_connect_save_LIBS" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_winsock2 + #ifndef HAVE_WINDOWS_H + int connect(int, void*, int); + #endif + ]],[[ + if(0 != connect(0, 0, 0)) + return 1; + ]]) + ],[ + tst_connect_need_LIBS="$tst_lib" + ]) + fi + done + LIBS="$tst_connect_save_LIBS" + # + case X-"$tst_connect_need_LIBS" in + X-unknown) + AC_MSG_RESULT([cannot find connect]) + AC_MSG_ERROR([cannot find connect function in libraries.]) + ;; + X-) + AC_MSG_RESULT([yes]) + ;; + *) + AC_MSG_RESULT([$tst_connect_need_LIBS]) + LIBS="$tst_connect_need_LIBS $tst_connect_save_LIBS" + ;; + esac +]) + + +dnl CURL_DEFINE_UNQUOTED (VARIABLE, [VALUE]) +dnl ------------------------------------------------- +dnl Like AC_DEFINE_UNQUOTED this macro will define a C preprocessor +dnl symbol that can be further used in custom template configuration +dnl files. This macro, unlike AC_DEFINE_UNQUOTED, does not use a third +dnl argument for the description. Symbol definitions done with this +dnl macro are intended to be exclusively used in handcrafted *.h.in +dnl template files. Contrary to what AC_DEFINE_UNQUOTED does, this one +dnl prevents autoheader generation and insertion of symbol template +dnl stub and definition into the first configuration header file. Do +dnl not use this macro as a replacement for AC_DEFINE_UNQUOTED, each +dnl one serves different functional needs. + +AC_DEFUN([CURL_DEFINE_UNQUOTED], [ +cat >>confdefs.h <<_EOF +[@%:@define] $1 ifelse($#, 2, [$2], 1) +_EOF +]) + + +dnl CURL_CONFIGURE_CURL_SOCKLEN_T +dnl ------------------------------------------------- +dnl The need for the curl_socklen_t definition arises mainly to properly +dnl interface HP-UX systems which on one hand have a typedef'ed socklen_t +dnl data type which is 32 or 64-Bit wide depending on the data model being +dnl used, and that on the other hand is only actually used when interfacing +dnl the X/Open sockets provided in the xnet library. + +AC_DEFUN([CURL_CONFIGURE_CURL_SOCKLEN_T], [ + AC_REQUIRE([CURL_INCLUDES_WS2TCPIP])dnl + AC_REQUIRE([CURL_INCLUDES_SYS_SOCKET])dnl + AC_REQUIRE([CURL_PREPROCESS_CALLCONV])dnl + # + AC_BEFORE([$0], [CURL_CONFIGURE_PULL_SYS_POLL])dnl + # + AC_MSG_CHECKING([for curl_socklen_t data type]) + curl_typeof_curl_socklen_t="unknown" + for arg1 in int SOCKET; do + for arg2 in 'struct sockaddr' void; do + for t in socklen_t int size_t 'unsigned int' long 'unsigned long' void; do + if test "$curl_typeof_curl_socklen_t" = "unknown"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_ws2tcpip + $curl_includes_sys_socket + $curl_preprocess_callconv + extern int FUNCALLCONV getpeername($arg1, $arg2 *, $t *); + ]],[[ + $t *lenptr = 0; + if(0 != getpeername(0, 0, lenptr)) + return 1; + ]]) + ],[ + curl_typeof_curl_socklen_t="$t" + ]) + fi + done + done + done + for t in socklen_t int; do + if test "$curl_typeof_curl_socklen_t" = "void"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_sys_socket + typedef $t curl_socklen_t; + ]],[[ + curl_socklen_t dummy; + ]]) + ],[ + curl_typeof_curl_socklen_t="$t" + ]) + fi + done + AC_MSG_RESULT([$curl_typeof_curl_socklen_t]) + if test "$curl_typeof_curl_socklen_t" = "void" || + test "$curl_typeof_curl_socklen_t" = "unknown"; then + AC_MSG_ERROR([cannot find data type for curl_socklen_t.]) + fi + # + AC_MSG_CHECKING([size of curl_socklen_t]) + curl_sizeof_curl_socklen_t="unknown" + curl_pull_headers_socklen_t="unknown" + if test "$curl_cv_header_ws2tcpip_h" = "yes"; then + tst_pull_header_checks='none ws2tcpip' + tst_size_checks='4' + else + tst_pull_header_checks='none systypes syssocket' + tst_size_checks='4 8 2' + fi + for tst_size in $tst_size_checks; do + for tst_pull_headers in $tst_pull_header_checks; do + if test "$curl_sizeof_curl_socklen_t" = "unknown"; then + case $tst_pull_headers in + ws2tcpip) + tmp_includes="$curl_includes_ws2tcpip" + ;; + systypes) + tmp_includes="$curl_includes_sys_types" + ;; + syssocket) + tmp_includes="$curl_includes_sys_socket" + ;; + *) + tmp_includes="" + ;; + esac + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $tmp_includes + typedef $curl_typeof_curl_socklen_t curl_socklen_t; + typedef char dummy_arr[sizeof(curl_socklen_t) == $tst_size ? 1 : -1]; + ]],[[ + curl_socklen_t dummy; + ]]) + ],[ + curl_sizeof_curl_socklen_t="$tst_size" + curl_pull_headers_socklen_t="$tst_pull_headers" + ]) + fi + done + done + AC_MSG_RESULT([$curl_sizeof_curl_socklen_t]) + if test "$curl_sizeof_curl_socklen_t" = "unknown"; then + AC_MSG_ERROR([cannot find out size of curl_socklen_t.]) + fi + # + case $curl_pull_headers_socklen_t in + ws2tcpip) + CURL_DEFINE_UNQUOTED([CURL_PULL_WS2TCPIP_H]) + ;; + systypes) + CURL_DEFINE_UNQUOTED([CURL_PULL_SYS_TYPES_H]) + ;; + syssocket) + CURL_DEFINE_UNQUOTED([CURL_PULL_SYS_TYPES_H]) + CURL_DEFINE_UNQUOTED([CURL_PULL_SYS_SOCKET_H]) + ;; + esac + CURL_DEFINE_UNQUOTED([CURL_TYPEOF_CURL_SOCKLEN_T], [$curl_typeof_curl_socklen_t]) + CURL_DEFINE_UNQUOTED([CURL_SIZEOF_CURL_SOCKLEN_T], [$curl_sizeof_curl_socklen_t]) +]) + + +dnl CURL_CONFIGURE_PULL_SYS_POLL +dnl ------------------------------------------------- +dnl The need for the sys/poll.h inclusion arises mainly to properly +dnl interface AIX systems which define macros 'events' and 'revents'. + +AC_DEFUN([CURL_CONFIGURE_PULL_SYS_POLL], [ + AC_REQUIRE([CURL_INCLUDES_POLL])dnl + # + tst_poll_events_macro_defined="unknown" + # + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_poll + ]],[[ +#if defined(events) || defined(revents) + return 0; +#else + force compilation error +#endif + ]]) + ],[ + tst_poll_events_macro_defined="yes" + ],[ + tst_poll_events_macro_defined="no" + ]) + # + if test "$tst_poll_events_macro_defined" = "yes"; then + if test "x$ac_cv_header_sys_poll_h" = "xyes"; then + CURL_DEFINE_UNQUOTED([CURL_PULL_SYS_POLL_H]) + fi + fi + # +]) + + +dnl CURL_CHECK_FUNC_SELECT +dnl ------------------------------------------------- +dnl Test if the socket select() function is available, +dnl and check its return type and the types of its +dnl arguments. If the function succeeds HAVE_SELECT +dnl will be defined, defining the types of the +dnl arguments in SELECT_TYPE_ARG1, SELECT_TYPE_ARG234 +dnl and SELECT_TYPE_ARG5, defining the type of the +dnl function return value in SELECT_TYPE_RETV, and +dnl also defining the type qualifier of fifth argument +dnl in SELECT_QUAL_ARG5. + +AC_DEFUN([CURL_CHECK_FUNC_SELECT], [ + AC_REQUIRE([CURL_CHECK_STRUCT_TIMEVAL])dnl + AC_CHECK_HEADERS(sys/select.h sys/socket.h) + # + AC_MSG_CHECKING([for select]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif +#ifndef HAVE_WINDOWS_H +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#endif + ]],[[ + select(0, 0, 0, 0, 0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + curl_cv_select="yes" + ],[ + AC_MSG_RESULT([no]) + curl_cv_select="no" + ]) + # + if test "$curl_cv_select" = "yes"; then + AC_CACHE_CHECK([types of args and return type for select], + [curl_cv_func_select_args], [ + curl_cv_func_select_args="unknown" + for sel_retv in 'int' 'ssize_t'; do + for sel_arg1 in 'int' 'ssize_t' 'size_t' 'unsigned long int' 'unsigned int'; do + for sel_arg234 in 'fd_set *' 'int *' 'void *'; do + for sel_arg5 in 'struct timeval *' 'const struct timeval *'; do + if test "$curl_cv_func_select_args" = "unknown"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#define SELECTCALLCONV PASCAL +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif +#ifndef HAVE_WINDOWS_H +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#define SELECTCALLCONV +#endif +#ifndef HAVE_STRUCT_TIMEVAL + struct timeval { + long tv_sec; + long tv_usec; + }; +#endif + extern $sel_retv SELECTCALLCONV +#ifdef __ANDROID__ +__attribute__((overloadable)) +#endif + select($sel_arg1, + $sel_arg234, + $sel_arg234, + $sel_arg234, + $sel_arg5); + ]],[[ + $sel_arg1 nfds=0; + $sel_arg234 rfds=0; + $sel_arg234 wfds=0; + $sel_arg234 efds=0; + $sel_retv res = select(nfds, rfds, wfds, efds, 0); + ]]) + ],[ + curl_cv_func_select_args="$sel_arg1,$sel_arg234,$sel_arg5,$sel_retv" + ]) + fi + done + done + done + done + ]) # AC-CACHE-CHECK + if test "$curl_cv_func_select_args" = "unknown"; then + AC_MSG_WARN([Cannot find proper types to use for select args]) + AC_MSG_WARN([HAVE_SELECT will not be defined]) + else + select_prev_IFS=$IFS; IFS=',' + set dummy `echo "$curl_cv_func_select_args" | sed 's/\*/\*/g'` + IFS=$select_prev_IFS + shift + # + sel_qual_type_arg5=$[3] + # + AC_DEFINE_UNQUOTED(SELECT_TYPE_ARG1, $[1], + [Define to the type of arg 1 for select.]) + AC_DEFINE_UNQUOTED(SELECT_TYPE_ARG234, $[2], + [Define to the type of args 2, 3 and 4 for select.]) + AC_DEFINE_UNQUOTED(SELECT_TYPE_RETV, $[4], + [Define to the function return type for select.]) + # + prev_sh_opts=$- + # + case $prev_sh_opts in + *f*) + ;; + *) + set -f + ;; + esac + # + case "$sel_qual_type_arg5" in + const*) + sel_qual_arg5=const + sel_type_arg5=`echo $sel_qual_type_arg5 | sed 's/^const //'` + ;; + *) + sel_qual_arg5= + sel_type_arg5=$sel_qual_type_arg5 + ;; + esac + # + AC_DEFINE_UNQUOTED(SELECT_QUAL_ARG5, $sel_qual_arg5, + [Define to the type qualifier of arg 5 for select.]) + AC_DEFINE_UNQUOTED(SELECT_TYPE_ARG5, $sel_type_arg5, + [Define to the type of arg 5 for select.]) + # + case $prev_sh_opts in + *f*) + ;; + *) + set +f + ;; + esac + # + AC_DEFINE_UNQUOTED(HAVE_SELECT, 1, + [Define to 1 if you have the select function.]) + curl_cv_func_select="yes" + fi + fi +]) + + +dnl CURL_VERIFY_RUNTIMELIBS +dnl ------------------------------------------------- +dnl Verify that the shared libs found so far can be used when running +dnl programs, since otherwise the situation will create odd configure errors +dnl that are misleading people. +dnl +dnl Make sure this test is run BEFORE the first test in the script that +dnl runs anything, which at the time of this writing is the AC_CHECK_SIZEOF +dnl macro. It must also run AFTER all lib-checking macros are complete. + +AC_DEFUN([CURL_VERIFY_RUNTIMELIBS], [ + + dnl this test is of course not sensible if we are cross-compiling! + if test "x$cross_compiling" != xyes; then + + dnl just run a program to verify that the libs checked for previous to this + dnl point also is available run-time! + AC_MSG_CHECKING([run-time libs availability]) + CURL_RUN_IFELSE([ +main() +{ + return 0; +} +], + AC_MSG_RESULT([fine]), + AC_MSG_RESULT([failed]) + AC_MSG_ERROR([one or more libs available at link-time are not available run-time. Libs used at link-time: $LIBS]) + ) + + dnl if this test fails, configure has already stopped + fi +]) + + +dnl CURL_CHECK_VARIADIC_MACROS +dnl ------------------------------------------------- +dnl Check compiler support of variadic macros + +AC_DEFUN([CURL_CHECK_VARIADIC_MACROS], [ + AC_CACHE_CHECK([for compiler support of C99 variadic macro style], + [curl_cv_variadic_macros_c99], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__) +#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__) + int fun3(int arg1, int arg2, int arg3); + int fun2(int arg1, int arg2); + int fun3(int arg1, int arg2, int arg3) + { return arg1 + arg2 + arg3; } + int fun2(int arg1, int arg2) + { return arg1 + arg2; } + ]],[[ + int res3 = c99_vmacro3(1, 2, 3); + int res2 = c99_vmacro2(1, 2); + ]]) + ],[ + curl_cv_variadic_macros_c99="yes" + ],[ + curl_cv_variadic_macros_c99="no" + ]) + ]) + case "$curl_cv_variadic_macros_c99" in + yes) + AC_DEFINE_UNQUOTED(HAVE_VARIADIC_MACROS_C99, 1, + [Define to 1 if compiler supports C99 variadic macro style.]) + ;; + esac + AC_CACHE_CHECK([for compiler support of old gcc variadic macro style], + [curl_cv_variadic_macros_gcc], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#define gcc_vmacro3(first, args...) fun3(first, args) +#define gcc_vmacro2(first, args...) fun2(first, args) + int fun3(int arg1, int arg2, int arg3); + int fun2(int arg1, int arg2); + int fun3(int arg1, int arg2, int arg3) + { return arg1 + arg2 + arg3; } + int fun2(int arg1, int arg2) + { return arg1 + arg2; } + ]],[[ + int res3 = gcc_vmacro3(1, 2, 3); + int res2 = gcc_vmacro2(1, 2); + ]]) + ],[ + curl_cv_variadic_macros_gcc="yes" + ],[ + curl_cv_variadic_macros_gcc="no" + ]) + ]) + case "$curl_cv_variadic_macros_gcc" in + yes) + AC_DEFINE_UNQUOTED(HAVE_VARIADIC_MACROS_GCC, 1, + [Define to 1 if compiler supports old gcc variadic macro style.]) + ;; + esac +]) + + +dnl CURL_CHECK_CA_BUNDLE +dnl ------------------------------------------------- +dnl Check if a default ca-bundle should be used +dnl +dnl regarding the paths this will scan: +dnl /etc/ssl/certs/ca-certificates.crt Debian systems +dnl /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva +dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat +dnl /usr/local/share/certs/ca-root-nss.crt FreeBSD +dnl /etc/ssl/cert.pem OpenBSD, FreeBSD (symlink) +dnl /etc/ssl/certs/ (ca path) SUSE + +AC_DEFUN([CURL_CHECK_CA_BUNDLE], [ + + AC_MSG_CHECKING([default CA cert bundle/path]) + + AC_ARG_WITH(ca-bundle, +AC_HELP_STRING([--with-ca-bundle=FILE], +[Path to a file containing CA certificates (example: /etc/ca-bundle.crt)]) +AC_HELP_STRING([--without-ca-bundle], [Don't use a default CA bundle]), + [ + want_ca="$withval" + if test "x$want_ca" = "xyes"; then + AC_MSG_ERROR([--with-ca-bundle=FILE requires a path to the CA bundle]) + fi + ], + [ want_ca="unset" ]) + AC_ARG_WITH(ca-path, +AC_HELP_STRING([--with-ca-path=DIRECTORY], +[Path to a directory containing CA certificates stored individually, with \ +their filenames in a hash format. This option can be used with OpenSSL, \ +GnuTLS and PolarSSL backends. Refer to OpenSSL c_rehash for details. \ +(example: /etc/certificates)]) +AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]), + [ + want_capath="$withval" + if test "x$want_capath" = "xyes"; then + AC_MSG_ERROR([--with-ca-path=DIRECTORY requires a path to the CA path directory]) + fi + ], + [ want_capath="unset"]) + + ca_warning=" (warning: certs not found)" + capath_warning=" (warning: certs not found)" + check_capath="" + + if test "x$want_ca" != "xno" -a "x$want_ca" != "xunset" -a \ + "x$want_capath" != "xno" -a "x$want_capath" != "xunset"; then + dnl both given + ca="$want_ca" + capath="$want_capath" + elif test "x$want_ca" != "xno" -a "x$want_ca" != "xunset"; then + dnl --with-ca-bundle given + ca="$want_ca" + capath="no" + elif test "x$want_capath" != "xno" -a "x$want_capath" != "xunset"; then + dnl --with-ca-path given + if test "x$OPENSSL_ENABLED" != "x1" -a "x$GNUTLS_ENABLED" != "x1" -a "x$POLARSSL_ENABLED" != "x1"; then + AC_MSG_ERROR([--with-ca-path only works with OpenSSL, GnuTLS or PolarSSL]) + fi + capath="$want_capath" + ca="no" + else + dnl first try autodetecting a CA bundle , then a CA path + dnl both autodetections can be skipped by --without-ca-* + ca="no" + capath="no" + if test "x$cross_compiling" != "xyes"; then + dnl NOT cross-compiling and... + dnl neither of the --with-ca-* options are provided + if test "x$want_ca" = "xunset"; then + dnl the path we previously would have installed the curl ca bundle + dnl to, and thus we now check for an already existing cert in that + dnl place in case we find no other + if test "x$prefix" != xNONE; then + cac="${prefix}/share/curl/curl-ca-bundle.crt" + else + cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt" + fi + + for a in /etc/ssl/certs/ca-certificates.crt \ + /etc/pki/tls/certs/ca-bundle.crt \ + /usr/share/ssl/certs/ca-bundle.crt \ + /usr/local/share/certs/ca-root-nss.crt \ + /etc/ssl/cert.pem \ + "$cac"; do + if test -f "$a"; then + ca="$a" + break + fi + done + fi + if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \ + "x$OPENSSL_ENABLED" = "x1"; then + check_capath="/etc/ssl/certs/" + fi + else + dnl no option given and cross-compiling + AC_MSG_WARN([skipped the ca-cert path detection when cross-compiling]) + fi + fi + + if test "x$ca" = "xno" || test -f "$ca"; then + ca_warning="" + fi + + if test "x$capath" != "xno"; then + check_capath="$capath" + fi + + if test ! -z "$check_capath"; then + for a in "$check_capath"; do + if test -d "$a" && ls "$a"/[[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]].0 >/dev/null 2>/dev/null; then + if test "x$capath" = "xno"; then + capath="$a" + fi + capath_warning="" + break + fi + done + fi + + if test "x$capath" = "xno"; then + capath_warning="" + fi + + if test "x$ca" != "xno"; then + CURL_CA_BUNDLE='"'$ca'"' + AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [Location of default ca bundle]) + AC_SUBST(CURL_CA_BUNDLE) + AC_MSG_RESULT([$ca]) + fi + if test "x$capath" != "xno"; then + CURL_CA_PATH="\"$capath\"" + AC_DEFINE_UNQUOTED(CURL_CA_PATH, "$capath", [Location of default ca path]) + AC_MSG_RESULT([$capath (capath)]) + fi + if test "x$ca" = "xno" && test "x$capath" = "xno"; then + AC_MSG_RESULT([no]) + fi + + AC_MSG_CHECKING([whether to use builtin CA store of SSL library]) + AC_ARG_WITH(ca-fallback, +AC_HELP_STRING([--with-ca-fallback], [Use the built in CA store of the SSL library]) +AC_HELP_STRING([--without-ca-fallback], [Don't use the built in CA store of the SSL library]), + [ + if test "x$with_ca_fallback" != "xyes" -a "x$with_ca_fallback" != "xno"; then + AC_MSG_ERROR([--with-ca-fallback only allows yes or no as parameter]) + fi + ], + [ with_ca_fallback="no"]) + AC_MSG_RESULT([$with_ca_fallback]) + if test "x$with_ca_fallback" = "xyes"; then + if test "x$OPENSSL_ENABLED" != "x1" -a "x$GNUTLS_ENABLED" != "x1"; then + AC_MSG_ERROR([--with-ca-fallback only works with OpenSSL or GnuTLS]) + fi + AC_DEFINE_UNQUOTED(CURL_CA_FALLBACK, 1, [define "1" to use built in CA store of SSL library ]) + fi +]) + +dnl CURL_CHECK_WIN32_LARGEFILE +dnl ------------------------------------------------- +dnl Check if curl's WIN32 large file will be used + +AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [ + AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl + AC_MSG_CHECKING([whether build target supports WIN32 file API]) + curl_win32_file_api="no" + if test "$curl_cv_header_windows_h" = "yes"; then + if test x"$enable_largefile" != "xno"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ +#if !defined(_WIN32_WCE) && \ + (defined(__MINGW32__) || \ + (defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64)))) + int dummy=1; +#else + WIN32 large file API not supported. +#endif + ]]) + ],[ + curl_win32_file_api="win32_large_files" + ]) + fi + if test "$curl_win32_file_api" = "no"; then + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ +#if defined(_WIN32_WCE) || defined(__MINGW32__) || defined(_MSC_VER) + int dummy=1; +#else + WIN32 small file API not supported. +#endif + ]]) + ],[ + curl_win32_file_api="win32_small_files" + ]) + fi + fi + case "$curl_win32_file_api" in + win32_large_files) + AC_MSG_RESULT([yes (large file enabled)]) + AC_DEFINE_UNQUOTED(USE_WIN32_LARGE_FILES, 1, + [Define to 1 if you are building a Windows target with large file support.]) + ;; + win32_small_files) + AC_MSG_RESULT([yes (large file disabled)]) + AC_DEFINE_UNQUOTED(USE_WIN32_SMALL_FILES, 1, + [Define to 1 if you are building a Windows target without large file support.]) + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +]) + +dnl CURL_EXPORT_PCDIR ($pcdir) +dnl ------------------------ +dnl if $pcdir is not empty, set PKG_CONFIG_LIBDIR to $pcdir and export +dnl +dnl we need this macro since pkg-config distinguishes among empty and unset +dnl variable while checking PKG_CONFIG_LIBDIR +dnl + +AC_DEFUN([CURL_EXPORT_PCDIR], [ + if test -n "$1"; then + PKG_CONFIG_LIBDIR="$1" + export PKG_CONFIG_LIBDIR + fi +]) + +dnl CURL_CHECK_PKGCONFIG ($module, [$pcdir]) +dnl ------------------------ +dnl search for the pkg-config tool. Set the PKGCONFIG variable to hold the +dnl path to it, or 'no' if not found/present. +dnl +dnl If pkg-config is present, check that it has info about the $module or +dnl return "no" anyway! +dnl +dnl Optionally PKG_CONFIG_LIBDIR may be given as $pcdir. +dnl + +AC_DEFUN([CURL_CHECK_PKGCONFIG], [ + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no], + [$PATH:/usr/bin:/usr/local/bin]) + fi + + if test "x$PKGCONFIG" != "xno"; then + AC_MSG_CHECKING([for $1 options with pkg-config]) + dnl ask pkg-config about $1 + itexists=`CURL_EXPORT_PCDIR([$2]) dnl + $PKGCONFIG --exists $1 >/dev/null 2>&1 && echo 1` + + if test -z "$itexists"; then + dnl pkg-config does not have info about the given module! set the + dnl variable to 'no' + PKGCONFIG="no" + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([found]) + fi + fi +]) + + +dnl CURL_GENERATE_CONFIGUREHELP_PM +dnl ------------------------------------------------- +dnl Generate test harness configurehelp.pm module, defining and +dnl initializing some perl variables with values which are known +dnl when the configure script runs. For portability reasons, test +dnl harness needs information on how to run the C preprocessor. + +AC_DEFUN([CURL_GENERATE_CONFIGUREHELP_PM], [ + AC_REQUIRE([AC_PROG_CPP])dnl + tmp_cpp=`eval echo "$ac_cpp" 2>/dev/null` + if test -z "$tmp_cpp"; then + tmp_cpp='cpp' + fi + cat >./tests/configurehelp.pm <<_EOF +[@%:@] This is a generated file. Do not edit. + +package configurehelp; + +use strict; +use warnings; +use Exporter; + +use vars qw( + @ISA + @EXPORT_OK + \$Cpreprocessor + ); + +@ISA = qw(Exporter); + +@EXPORT_OK = qw( + \$Cpreprocessor + ); + +\$Cpreprocessor = '$tmp_cpp'; + +1; +_EOF +]) + +dnl CURL_CPP_P +dnl +dnl Check if $cpp -P should be used for extract define values due to gcc 5 +dnl splitting up strings and defines between line outputs. gcc by default +dnl (without -P) will show TEST EINVAL TEST as +dnl +dnl # 13 "conftest.c" +dnl TEST +dnl # 13 "conftest.c" 3 4 +dnl 22 +dnl # 13 "conftest.c" +dnl TEST + +AC_DEFUN([CURL_CPP_P], [ + AC_MSG_CHECKING([if cpp -P is needed]) + AC_EGREP_CPP([TEST.*TEST], [ + #include +TEST EINVAL TEST + ], [cpp=no], [cpp=yes]) + AC_MSG_RESULT([$cpp]) + + dnl we need cpp -P so check if it works then + if test "x$cpp" = "xyes"; then + AC_MSG_CHECKING([if cpp -P works]) + OLDCPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -P" + AC_EGREP_CPP([TEST.*TEST], [ + #include +TEST EINVAL TEST + ], [cpp_p=yes], [cpp_p=no]) + AC_MSG_RESULT([$cpp_p]) + + if test "x$cpp_p" = "xno"; then + AC_MSG_WARN([failed to figure out cpp -P alternative]) + # without -P + CPPPFLAG="" + else + # with -P + CPPPFLAG="-P" + fi + dnl restore CPPFLAGS + CPPFLAGS=$OLDCPPFLAGS + else + # without -P + CPPPFLAG="" + fi +]) + + +dnl CURL_MAC_CFLAGS +dnl +dnl Check if -mmacosx-version-min, -miphoneos-version-min or any +dnl similar are set manually, otherwise do. And set +dnl -Werror=partial-availability. +dnl + +AC_DEFUN([CURL_MAC_CFLAGS], [ + + tst_cflags="no" + case $host_os in + darwin*) + tst_cflags="yes" + ;; + esac + + AC_MSG_CHECKING([for good-to-use Mac CFLAGS]) + AC_MSG_RESULT([$tst_cflags]); + + if test "$tst_cflags" = "yes"; then + AC_MSG_CHECKING([for *version-min in CFLAGS]) + min="" + if test -z "$(echo $CFLAGS | grep m.*os.*-version-min)"; then + min="-mmacosx-version-min=10.8" + CFLAGS="$CFLAGS $min" + fi + if test -z "$min"; then + AC_MSG_RESULT([set by user]) + else + AC_MSG_RESULT([$min set]) + fi + + old_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Werror=partial-availability" + AC_MSG_CHECKING([whether $CC accepts -Werror=partial-availability]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + CFLAGS=$old_CFLAGS]) + fi + +]) + + +dnl CURL_SUPPORTS_BUILTIN_AVAILABLE +dnl +dnl Check to see if the compiler supports __builtin_available. This built-in +dnl compiler function first appeared in Apple LLVM 9.0.0. It's so new that, at +dnl the time this macro was written, the function was not yet documented. Its +dnl purpose is to return true if the code is running under a certain OS version +dnl or later. + +AC_DEFUN([CURL_SUPPORTS_BUILTIN_AVAILABLE], [ + AC_MSG_CHECKING([to see if the compiler supports __builtin_available()]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include + ]],[[ + if (__builtin_available(macOS 10.8, iOS 5.0, *)) {} + ]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_BUILTIN_AVAILABLE, 1, + [Define to 1 if you have the __builtin_available function.]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..e2664b4c --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,75 @@ +version: 7.50.0.{build} + +environment: + matrix: + - PRJ_GEN: "Visual Studio 11 2012 Win64" + BDIR: msvc2012 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: OFF + STATICLIB: OFF + - PRJ_GEN: "Visual Studio 12 2013 Win64" + BDIR: msvc2013 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: OFF + STATICLIB: OFF + - PRJ_GEN: "Visual Studio 14 2015 Win64" + BDIR: msvc2015 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: OFF + STATICLIB: OFF + - PRJ_GEN: "Visual Studio 11 2012 Win64" + BDIR: msvc2012 + PRJ_CFG: Release + OPENSSL: ON + TESTING: OFF + STATICLIB: OFF + - PRJ_GEN: "Visual Studio 12 2013 Win64" + BDIR: msvc2013 + PRJ_CFG: Release + OPENSSL: ON + TESTING: OFF + STATICLIB: OFF + - PRJ_GEN: "Visual Studio 14 2015 Win64" + BDIR: msvc2015 + PRJ_CFG: Release + OPENSSL: ON + TESTING: OFF + STATICLIB: OFF + - PRJ_GEN: "Visual Studio 11 2012 Win64" + BDIR: msvc2012 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: ON + STATICLIB: ON + - PRJ_GEN: "Visual Studio 12 2013 Win64" + BDIR: msvc2013 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: ON + STATICLIB: ON + - PRJ_GEN: "Visual Studio 14 2015 Win64" + BDIR: msvc2015 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: ON + STATICLIB: ON + - PRJ_GEN: "Visual Studio 14 2015" + BDIR: msvc2015 + PRJ_CFG: Release + OPENSSL: OFF + TESTING: ON + STATICLIB: ON + +build_script: + - mkdir build.%BDIR% + - cd build.%BDIR% + - cmake .. -G"%PRJ_GEN%" -DCMAKE_USE_OPENSSL=%OPENSSL% -DCURL_STATICLIB=%STATICLIB% -DBUILD_TESTING=%TESTING% -DCURL_WERROR=ON + - cmake --build . --config %PRJ_CFG% --clean-first + +# whitelist branches to avoid testing feature branches twice (as branch and as pull request) +branches: + only: + - master diff --git a/buildconf b/buildconf new file mode 100755 index 00000000..50957531 --- /dev/null +++ b/buildconf @@ -0,0 +1,448 @@ +#!/bin/sh +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +#-------------------------------------------------------------------------- +# die prints argument string to stdout and exits this shell script. +# +die(){ + echo "buildconf: $@" + exit 1 +} + +#-------------------------------------------------------------------------- +# findtool works as 'which' but we use a different name to make it more +# obvious we aren't using 'which'! ;-) +# Unlike 'which' does, the current directory is ignored. +# +findtool(){ + file="$1" + + if { echo "$file" | grep "/" >/dev/null 2>&1; } then + # when file is given with a path check it first + if test -f "$file"; then + echo "$file" + return + fi + fi + + old_IFS=$IFS; IFS=':' + for path in $PATH + do + IFS=$old_IFS + # echo "checks for $file in $path" >&2 + if test "$path" -a "$path" != '.' -a -f "$path/$file"; then + echo "$path/$file" + return + fi + done + IFS=$old_IFS +} + +#-------------------------------------------------------------------------- +# removethis() removes all files and subdirectories with the given name, +# inside and below the current subdirectory at invocation time. +# +removethis(){ + if test "$#" = "1"; then + find . -depth -name $1 -print > buildconf.tmp.$$ + while read fdname + do + if test -f "$fdname"; then + rm -f "$fdname" + elif test -d "$fdname"; then + rm -f -r "$fdname" + fi + done < buildconf.tmp.$$ + rm -f buildconf.tmp.$$ + fi +} + +#-------------------------------------------------------------------------- +# Ensure that buildconf runs from the subdirectory where configure.ac lives +# +if test ! -f configure.ac || + test ! -f src/tool_main.c || + test ! -f lib/urldata.h || + test ! -f include/curl/curl.h || + test ! -f m4/curl-functions.m4; then + echo "Can not run buildconf from outside of curl's source subdirectory!" + echo "Change to the subdirectory where buildconf is found, and try again." + exit 1 +fi + +#-------------------------------------------------------------------------- +# autoconf 2.57 or newer. Unpatched version 2.67 does not generate proper +# configure script. Unpatched version 2.68 is simply unusable, we should +# disallow 2.68 usage. +# +need_autoconf="2.57" +ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'` +if test -z "$ac_version"; then + echo "buildconf: autoconf not found." + echo " You need autoconf version $need_autoconf or newer installed." + exit 1 +fi +old_IFS=$IFS; IFS='.'; set $ac_version; IFS=$old_IFS +if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then + echo "buildconf: autoconf version $ac_version found." + echo " You need autoconf version $need_autoconf or newer installed." + echo " If you have a sufficient autoconf installed, but it" + echo " is not named 'autoconf', then try setting the" + echo " AUTOCONF environment variable." + exit 1 +fi + +if test "$1" = "2" -a "$2" -eq "67"; then + echo "buildconf: autoconf version $ac_version (BAD)" + echo " Unpatched version generates broken configure script." +elif test "$1" = "2" -a "$2" -eq "68"; then + echo "buildconf: autoconf version $ac_version (BAD)" + echo " Unpatched version generates unusable configure script." +else + echo "buildconf: autoconf version $ac_version (ok)" +fi + +am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'` +if test -z "$am4te_version"; then + echo "buildconf: autom4te not found. Weird autoconf installation!" + exit 1 +fi +if test "$am4te_version" = "$ac_version"; then + echo "buildconf: autom4te version $am4te_version (ok)" +else + echo "buildconf: autom4te version $am4te_version (ERROR: does not match autoconf version)" + exit 1 +fi + +#-------------------------------------------------------------------------- +# autoheader 2.50 or newer +# +ah_version=`${AUTOHEADER:-autoheader} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'` +if test -z "$ah_version"; then + echo "buildconf: autoheader not found." + echo " You need autoheader version 2.50 or newer installed." + exit 1 +fi +old_IFS=$IFS; IFS='.'; set $ah_version; IFS=$old_IFS +if test "$1" = "2" -a "$2" -lt "50" || test "$1" -lt "2"; then + echo "buildconf: autoheader version $ah_version found." + echo " You need autoheader version 2.50 or newer installed." + echo " If you have a sufficient autoheader installed, but it" + echo " is not named 'autoheader', then try setting the" + echo " AUTOHEADER environment variable." + exit 1 +fi + +echo "buildconf: autoheader version $ah_version (ok)" + +#-------------------------------------------------------------------------- +# automake 1.7 or newer +# +need_automake="1.7" +am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'` +if test -z "$am_version"; then + echo "buildconf: automake not found." + echo " You need automake version $need_automake or newer installed." + exit 1 +fi +old_IFS=$IFS; IFS='.'; set $am_version; IFS=$old_IFS +if test "$1" = "1" -a "$2" -lt "7" || test "$1" -lt "1"; then + echo "buildconf: automake version $am_version found." + echo " You need automake version $need_automake or newer installed." + echo " If you have a sufficient automake installed, but it" + echo " is not named 'automake', then try setting the" + echo " AUTOMAKE environment variable." + exit 1 +fi + +echo "buildconf: automake version $am_version (ok)" + +acloc_version=`${ACLOCAL:-aclocal} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'` +if test -z "$acloc_version"; then + echo "buildconf: aclocal not found. Weird automake installation!" + exit 1 +fi +if test "$acloc_version" = "$am_version"; then + echo "buildconf: aclocal version $acloc_version (ok)" +else + echo "buildconf: aclocal version $acloc_version (ERROR: does not match automake version)" + exit 1 +fi + +#-------------------------------------------------------------------------- +# GNU libtoolize preliminary check +# +want_lt_major=1 +want_lt_minor=4 +want_lt_patch=2 +want_lt_version=1.4.2 + +# This approach that tries 'glibtoolize' first is intended for systems that +# have GNU libtool named as 'glibtoolize' and libtoolize not being GNU's. + +libtoolize=`findtool glibtoolize 2>/dev/null` +if test ! -x "$libtoolize"; then + libtoolize=`findtool ${LIBTOOLIZE:-libtoolize}` +fi +if test -z "$libtoolize"; then + echo "buildconf: libtoolize not found." + echo " You need GNU libtoolize $want_lt_version or newer installed." + exit 1 +fi + +lt_pver=`$libtoolize --version 2>/dev/null|head -n 1` +lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"` +lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"` +if test -z "$lt_version"; then + echo "buildconf: libtoolize not found." + echo " You need GNU libtoolize $want_lt_version or newer installed." + exit 1 +fi +old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS +lt_major=$1 +lt_minor=$2 +lt_patch=$3 + +if test -z "$lt_major"; then + lt_status="bad" +elif test "$lt_major" -gt "$want_lt_major"; then + lt_status="good" +elif test "$lt_major" -lt "$want_lt_major"; then + lt_status="bad" +elif test -z "$lt_minor"; then + lt_status="bad" +elif test "$lt_minor" -gt "$want_lt_minor"; then + lt_status="good" +elif test "$lt_minor" -lt "$want_lt_minor"; then + lt_status="bad" +elif test -z "$lt_patch"; then + lt_status="bad" +elif test "$lt_patch" -gt "$want_lt_patch"; then + lt_status="good" +elif test "$lt_patch" -lt "$want_lt_patch"; then + lt_status="bad" +else + lt_status="good" +fi +if test "$lt_status" != "good"; then + echo "buildconf: libtoolize version $lt_version found." + echo " You need GNU libtoolize $want_lt_version or newer installed." + exit 1 +fi + +echo "buildconf: libtoolize version $lt_version (ok)" + +#-------------------------------------------------------------------------- +# m4 check +# +m4=`(${M4:-m4} --version 0<&- || ${M4:-gm4} --version) 2>/dev/null 0<&- | head -n 1`; +m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'` + +if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then + echo "buildconf: GNU m4 version $m4_version (ok)" +else + if test -z "$m4"; then + echo "buildconf: m4 version not recognized. You need a GNU m4 installed!" + else + echo "buildconf: m4 version $m4 found. You need a GNU m4 installed!" + fi + exit 1 +fi + +#-------------------------------------------------------------------------- +# perl check +# +PERL=`findtool ${PERL:-perl}` +if test -z "$PERL"; then + echo "buildconf: perl not found" + exit 1 +fi + +#-------------------------------------------------------------------------- +# Remove files generated on previous buildconf/configure run. +# +for fname in .deps \ + .libs \ + *.la \ + *.lo \ + *.a \ + *.o \ + Makefile \ + Makefile.in \ + aclocal.m4 \ + aclocal.m4.bak \ + ares_build.h \ + ares_config.h \ + ares_config.h.in \ + autom4te.cache \ + compile \ + config.guess \ + curl_config.h \ + curl_config.h.in \ + config.log \ + config.lt \ + config.status \ + config.sub \ + configure \ + configurehelp.pm \ + curl-config \ + depcomp \ + libcares.pc \ + libcurl.pc \ + libtool \ + libtool.m4 \ + libtool.m4.tmp \ + ltmain.sh \ + ltoptions.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + lt~obsolete.m4 \ + missing \ + install-sh \ + stamp-h1 \ + stamp-h2 \ + stamp-h3 ; do + removethis "$fname" +done + +#-------------------------------------------------------------------------- +# run the correct scripts now +# + +echo "buildconf: running libtoolize" +${libtoolize} --copy --force || die "libtoolize command failed" + +# When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4 +# subdirectory and this local copy is patched to fix some warnings that +# are triggered when running aclocal and using autoconf 2.62 or later. + +if test "$lt_major" = "1" && test "$lt_minor" = "5"; then + if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then + echo "buildconf: copying libtool.m4 to local m4 subdir" + ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir` + if test -f $ac_dir/libtool.m4; then + cp -f $ac_dir/libtool.m4 m4/libtool.m4 + else + echo "buildconf: $ac_dir/libtool.m4 not found" + fi + if test -f m4/libtool.m4; then + echo "buildconf: renaming some variables in local m4/libtool.m4" + $PERL -i.tmp -pe \ + 's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \ + s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \ + m4/libtool.m4 + rm -f m4/libtool.m4.tmp + fi + fi +fi + +if test -f m4/libtool.m4; then + echo "buildconf: converting all mv to mv -f in local m4/libtool.m4" + $PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4 + rm -f m4/libtool.m4.tmp +fi + +echo "buildconf: running aclocal" +${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed" + +echo "buildconf: converting all mv to mv -f in local aclocal.m4" +$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 + +echo "buildconf: running autoheader" +${AUTOHEADER:-autoheader} || die "autoheader command failed" + +echo "buildconf: running autoconf" +${AUTOCONF:-autoconf} || die "autoconf command failed" + +if test -d ares; then + cd ares + echo "buildconf: running in ares" + ./buildconf + cd .. +fi + +echo "buildconf: running automake" +${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed" + +#-------------------------------------------------------------------------- +# GNU libtool complementary check +# +# Depending on the libtool and automake versions being used, config.guess +# might not be installed in the subdirectory until automake has finished. +# So we can not attempt to use it until this very last buildconf stage. +# +if test ! -f ./config.guess; then + echo "buildconf: config.guess not found" +else + buildhost=`./config.guess 2>/dev/null|head -n 1` + case $buildhost in + *-*-darwin*) + need_lt_major=1 + need_lt_minor=5 + need_lt_patch=26 + need_lt_check="yes" + ;; + *-*-hpux*) + need_lt_major=1 + need_lt_minor=5 + need_lt_patch=24 + need_lt_check="yes" + ;; + esac + if test ! -z "$need_lt_check"; then + if test -z "$lt_major"; then + lt_status="bad" + elif test "$lt_major" -gt "$need_lt_major"; then + lt_status="good" + elif test "$lt_major" -lt "$need_lt_major"; then + lt_status="bad" + elif test -z "$lt_minor"; then + lt_status="bad" + elif test "$lt_minor" -gt "$need_lt_minor"; then + lt_status="good" + elif test "$lt_minor" -lt "$need_lt_minor"; then + lt_status="bad" + elif test -z "$lt_patch"; then + lt_status="bad" + elif test "$lt_patch" -gt "$need_lt_patch"; then + lt_status="good" + elif test "$lt_patch" -lt "$need_lt_patch"; then + lt_status="bad" + else + lt_status="good" + fi + if test "$lt_status" != "good"; then + need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch" + echo "buildconf: libtool version $lt_version found." + echo " $buildhost requires GNU libtool $need_lt_version or newer installed." + rm -f configure + exit 1 + fi + fi +fi + +#-------------------------------------------------------------------------- +# Finished successfully. +# +echo "buildconf: OK" +exit 0 diff --git a/buildconf.bat b/buildconf.bat new file mode 100644 index 00000000..da5c0391 --- /dev/null +++ b/buildconf.bat @@ -0,0 +1,317 @@ +@echo off +rem *************************************************************************** +rem * _ _ ____ _ +rem * Project ___| | | | _ \| | +rem * / __| | | | |_) | | +rem * | (__| |_| | _ <| |___ +rem * \___|\___/|_| \_\_____| +rem * +rem * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +rem * +rem * This software is licensed as described in the file COPYING, which +rem * you should have received as part of this distribution. The terms +rem * are also available at https://curl.haxx.se/docs/copyright.html. +rem * +rem * You may opt to use, copy, modify, merge, publish, distribute and/or sell +rem * copies of the Software, and permit persons to whom the Software is +rem * furnished to do so, under the terms of the COPYING file. +rem * +rem * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +rem * KIND, either express or implied. +rem * +rem *************************************************************************** + +rem NOTES +rem +rem This batch file must be used to set up a git tree to build on systems where +rem there is no autotools support (i.e. DOS and Windows). +rem + +:begin + rem Set our variables + if "%OS%" == "Windows_NT" setlocal + set MODE=GENERATE + + rem Switch to this batch file's directory + cd /d "%~0\.." 1>NUL 2>&1 + + rem Check we are running from a curl git repository + if not exist GIT-INFO goto norepo + + rem Detect programs. HAVE_ + rem When not found the variable is set undefined. The undefined pattern + rem allows for statements like "if not defined HAVE_PERL (command)" + groff --version NUL 2>&1 + if errorlevel 1 (set HAVE_GROFF=) else (set HAVE_GROFF=Y) + nroff --version NUL 2>&1 + if errorlevel 1 (set HAVE_NROFF=) else (set HAVE_NROFF=Y) + perl --version NUL 2>&1 + if errorlevel 1 (set HAVE_PERL=) else (set HAVE_PERL=Y) + gzip --version NUL 2>&1 + if errorlevel 1 (set HAVE_GZIP=) else (set HAVE_GZIP=Y) + +:parseArgs + if "%~1" == "" goto start + + if /i "%~1" == "-clean" ( + set MODE=CLEAN + ) else if /i "%~1" == "-?" ( + goto syntax + ) else if /i "%~1" == "-h" ( + goto syntax + ) else if /i "%~1" == "-help" ( + goto syntax + ) else ( + goto unknown + ) + + shift & goto parseArgs + +:start + if "%MODE%" == "GENERATE" ( + echo. + echo Generating prerequisite files + + call :generate + if errorlevel 3 goto nogenhugehelp + if errorlevel 2 goto nogenmakefile + if errorlevel 1 goto warning + + ) else ( + echo. + echo Removing prerequisite files + + call :clean + if errorlevel 2 goto nocleanhugehelp + if errorlevel 1 goto nocleanmakefile + ) + + goto success + +rem Main generate function. +rem +rem Returns: +rem +rem 0 - success +rem 1 - success with simplified tool_hugehelp.c +rem 2 - failed to generate Makefile +rem 3 - failed to generate tool_hugehelp.c +rem +:generate + if "%OS%" == "Windows_NT" setlocal + set BASIC_HUGEHELP=0 + + rem Create Makefile + echo * %CD%\Makefile + if exist Makefile.dist ( + copy /Y Makefile.dist Makefile 1>NUL 2>&1 + if errorlevel 1 ( + if "%OS%" == "Windows_NT" endlocal + exit /B 2 + ) + ) + + rem Create tool_hugehelp.c + echo * %CD%\src\tool_hugehelp.c + call :genHugeHelp + if errorlevel 2 ( + if "%OS%" == "Windows_NT" endlocal + exit /B 3 + ) + if errorlevel 1 ( + set BASIC_HUGEHELP=1 + ) + cmd /c exit 0 + + rem Setup c-ares git tree + if exist ares\buildconf.bat ( + echo. + echo Configuring c-ares build environment + cd ares + call buildconf.bat + cd .. + ) + + if "%BASIC_HUGEHELP%" == "1" ( + if "%OS%" == "Windows_NT" endlocal + exit /B 1 + ) + + if "%OS%" == "Windows_NT" endlocal + exit /B 0 + +rem Main clean function. +rem +rem Returns: +rem +rem 0 - success +rem 1 - failed to clean Makefile +rem 2 - failed to clean tool_hugehelp.c +rem +:clean + rem Remove Makefile + echo * %CD%\Makefile + if exist Makefile ( + del Makefile 2>NUL + if exist Makefile ( + exit /B 1 + ) + ) + + rem Remove tool_hugehelp.c + echo * %CD%\src\tool_hugehelp.c + if exist src\tool_hugehelp.c ( + del src\tool_hugehelp.c 2>NUL + if exist src\tool_hugehelp.c ( + exit /B 2 + ) + ) + + exit /B + +rem Function to generate src\tool_hugehelp.c +rem +rem Returns: +rem +rem 0 - full tool_hugehelp.c generated +rem 1 - simplified tool_hugehelp.c +rem 2 - failure +rem +:genHugeHelp + if "%OS%" == "Windows_NT" setlocal + set LC_ALL=C + set ROFFCMD= + set BASIC=1 + + if defined HAVE_PERL ( + if defined HAVE_GROFF ( + set ROFFCMD=groff -mtty-char -Tascii -P-c -man + ) else if defined HAVE_NROFF ( + set ROFFCMD=nroff -c -Tascii -man + ) + ) + + if defined ROFFCMD ( + echo #include "tool_setup.h"> src\tool_hugehelp.c + echo #include "tool_hugehelp.h">> src\tool_hugehelp.c + + if defined HAVE_GZIP ( + echo #ifndef HAVE_LIBZ>> src\tool_hugehelp.c + ) + + %ROFFCMD% docs\curl.1 2>NUL | perl src\mkhelp.pl docs\MANUAL >> src\tool_hugehelp.c + if defined HAVE_GZIP ( + echo #else>> src\tool_hugehelp.c + %ROFFCMD% docs\curl.1 2>NUL | perl src\mkhelp.pl -c docs\MANUAL >> src\tool_hugehelp.c + echo #endif /^* HAVE_LIBZ ^*/>> src\tool_hugehelp.c + ) + + set BASIC=0 + ) else ( + if exist src\tool_hugehelp.c.cvs ( + copy /Y src\tool_hugehelp.c.cvs src\tool_hugehelp.c 1>NUL 2>&1 + ) else ( + echo #include "tool_setup.h"> src\tool_hugehelp.c + echo #include "tool_hugehelp.hd">> src\tool_hugehelp.c + echo.>> src\tool_hugehelp.c + echo void hugehelp(void^)>> src\tool_hugehelp.c + echo {>> src\tool_hugehelp.c + echo #ifdef USE_MANUAL>> src\tool_hugehelp.c + echo fputs("Built-in manual not included\n", stdout^);>> src\tool_hugehelp.c + echo #endif>> src\tool_hugehelp.c + echo }>> src\tool_hugehelp.c + ) + ) + + findstr "/C:void hugehelp(void)" src\tool_hugehelp.c 1>NUL 2>&1 + if errorlevel 1 ( + if "%OS%" == "Windows_NT" endlocal + exit /B 2 + ) + + if "%BASIC%" == "1" ( + if "%OS%" == "Windows_NT" endlocal + exit /B 1 + ) + + if "%OS%" == "Windows_NT" endlocal + exit /B 0 + +rem Function to clean-up local variables under DOS, Windows 3.x and +rem Windows 9x as setlocal isn't available until Windows NT +rem +:dosCleanup + set MODE= + set HAVE_GROFF= + set HAVE_NROFF= + set HAVE_PERL= + set HAVE_GZIP= + set BASIC_HUGEHELP= + set LC_ALL + set ROFFCMD= + set BASIC= + + exit /B + +:syntax + rem Display the help + echo. + echo Usage: buildconf [-clean] + echo. + echo -clean - Removes the files + goto error + +:unknown + echo. + echo Error: Unknown argument '%1' + goto error + +:norepo + echo. + echo Error: This batch file should only be used with a curl git repository + goto error + +:nogenmakefile + echo. + echo Error: Unable to generate Makefile + goto error + +:nogenhugehelp + echo. + echo Error: Unable to generate src\tool_hugehelp.c + goto error + +:nocleanmakefile + echo. + echo Error: Unable to clean Makefile + goto error + +:nocleanhugehelp + echo. + echo Error: Unable to clean src\tool_hugehelp.c + goto error + +:warning + echo. + echo Warning: The curl manual could not be integrated in the source. This means when + echo you build curl the manual will not be available (curl --man^). Integration of + echo the manual is not required and a summary of the options will still be available + echo (curl --help^). To integrate the manual your PATH is required to have + echo groff/nroff, perl and optionally gzip for compression. + goto success + +:error + if "%OS%" == "Windows_NT" ( + endlocal + ) else ( + call :dosCleanup + ) + exit /B 1 + +:success + if "%OS%" == "Windows_NT" ( + endlocal + ) else ( + call :dosCleanup + ) + exit /B 0 diff --git a/configure.ac b/configure.ac new file mode 100755 index 00000000..22280a5e --- /dev/null +++ b/configure.ac @@ -0,0 +1,4273 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.57) + +dnl We don't know the version number "statically" so we use a dash here +AC_INIT([curl], [-], [a suitable curl mailing list: https://curl.haxx.se/mail/]) + +XC_OVR_ZZ50 +XC_OVR_ZZ60 +CURL_OVERRIDE_AUTOCONF + +dnl configure script copyright +AC_COPYRIGHT([Copyright (c) 1998 - 2017 Daniel Stenberg, +This configure script may be copied, distributed and modified under the +terms of the curl license; see COPYING for more details]) + +AC_CONFIG_SRCDIR([lib/urldata.h]) +AC_CONFIG_HEADERS(lib/curl_config.h) +AC_CONFIG_MACRO_DIR([m4]) +AM_MAINTAINER_MODE +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +CURL_CHECK_OPTION_DEBUG +CURL_CHECK_OPTION_OPTIMIZE +CURL_CHECK_OPTION_WARNINGS +CURL_CHECK_OPTION_WERROR +CURL_CHECK_OPTION_CURLDEBUG +CURL_CHECK_OPTION_SYMBOL_HIDING +CURL_CHECK_OPTION_ARES +CURL_CHECK_OPTION_RT + +XC_CHECK_PATH_SEPARATOR + +# +# save the configure arguments +# +CONFIGURE_OPTIONS="\"$ac_configure_args\"" +AC_SUBST(CONFIGURE_OPTIONS) + +CURL_CFLAG_EXTRAS="" +if test X"$want_werror" = Xyes; then + CURL_CFLAG_EXTRAS="-Werror" +fi +AC_SUBST(CURL_CFLAG_EXTRAS) + +dnl SED is mandatory for configure process and libtool. +dnl Set it now, allowing it to be changed later. +if test -z "$SED"; then + dnl allow it to be overridden + AC_PATH_PROG([SED], [sed], [not_found], + [$PATH:/usr/bin:/usr/local/bin]) + if test -z "$SED" || test "$SED" = "not_found"; then + AC_MSG_ERROR([sed not found in PATH. Cannot continue without sed.]) + fi +fi +AC_SUBST([SED]) + +dnl GREP is mandatory for configure process and libtool. +dnl Set it now, allowing it to be changed later. +if test -z "$GREP"; then + dnl allow it to be overridden + AC_PATH_PROG([GREP], [grep], [not_found], + [$PATH:/usr/bin:/usr/local/bin]) + if test -z "$GREP" || test "$GREP" = "not_found"; then + AC_MSG_ERROR([grep not found in PATH. Cannot continue without grep.]) + fi +fi +AC_SUBST([GREP]) + +dnl EGREP is mandatory for configure process and libtool. +dnl Set it now, allowing it to be changed later. +if test -z "$EGREP"; then + dnl allow it to be overridden + if echo a | ($GREP -E '(a|b)') >/dev/null 2>&1; then + AC_MSG_CHECKING([for egrep]) + EGREP="$GREP -E" + AC_MSG_RESULT([$EGREP]) + else + AC_PATH_PROG([EGREP], [egrep], [not_found], + [$PATH:/usr/bin:/usr/local/bin]) + fi +fi +if test -z "$EGREP" || test "$EGREP" = "not_found"; then + AC_MSG_ERROR([egrep not found in PATH. Cannot continue without egrep.]) +fi +AC_SUBST([EGREP]) + +dnl AR is mandatory for configure process and libtool. +dnl This is target dependent, so check it as a tool. +if test -z "$AR"; then + dnl allow it to be overridden + AC_PATH_TOOL([AR], [ar], [not_found], + [$PATH:/usr/bin:/usr/local/bin]) + if test -z "$AR" || test "$AR" = "not_found"; then + AC_MSG_ERROR([ar not found in PATH. Cannot continue without ar.]) + fi +fi +AC_SUBST([AR]) + +AC_SUBST(libext) + +dnl figure out the libcurl version +CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)".*/\1/p' ${srcdir}/include/curl/curlver.h` +XC_CHECK_PROG_CC + +dnl Check if gcc is being used before adding AX_CODE_COVERAGE +AS_IF([ test "$GCC" = "yes" ], [AX_CODE_COVERAGE], + # not using GCC so pass a test below - CODE_COVERAGE_ENABLED_TRUE is not zero length + CODE_COVERAGE_ENABLED_TRUE='#' +) + +XC_AUTOMAKE +AC_MSG_CHECKING([curl version]) +AC_MSG_RESULT($CURLVERSION) + +AC_SUBST(CURLVERSION) + +dnl +dnl we extract the numerical version for curl-config only +VERSIONNUM=`$SED -ne 's/^#define LIBCURL_VERSION_NUM 0x\([0-9A-Fa-f]*\).*/\1/p' ${srcdir}/include/curl/curlver.h` +AC_SUBST(VERSIONNUM) + +dnl Solaris pkgadd support definitions +PKGADD_PKG="HAXXcurl" +PKGADD_NAME="curl - a client that groks URLs" +PKGADD_VENDOR="curl.haxx.se" +AC_SUBST(PKGADD_PKG) +AC_SUBST(PKGADD_NAME) +AC_SUBST(PKGADD_VENDOR) + +dnl +dnl initialize all the info variables + curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,axtls,winssl,darwinssl} )" + curl_ssh_msg="no (--with-libssh2)" + curl_zlib_msg="no (--with-zlib)" + curl_brotli_msg="no (--with-brotli)" + curl_gss_msg="no (--with-gssapi)" +curl_tls_srp_msg="no (--enable-tls-srp)" + curl_res_msg="default (--enable-ares / --enable-threaded-resolver)" + curl_ipv6_msg="no (--enable-ipv6)" +curl_unix_sockets_msg="no (--enable-unix-sockets)" + curl_idn_msg="no (--with-{libidn2,winidn})" + curl_manual_msg="no (--enable-manual)" +curl_libcurl_msg="enabled (--disable-libcurl-option)" +curl_verbose_msg="enabled (--disable-verbose)" + curl_sspi_msg="no (--enable-sspi)" + curl_ldap_msg="no (--enable-ldap / --with-ldap-lib / --with-lber-lib)" + curl_ldaps_msg="no (--enable-ldaps)" + curl_rtsp_msg="no (--enable-rtsp)" + curl_rtmp_msg="no (--with-librtmp)" + curl_mtlnk_msg="no (--with-libmetalink)" + curl_psl_msg="no (--with-libpsl)" + + ssl_backends= + +dnl +dnl Save some initial values the user might have provided +dnl +INITIAL_LDFLAGS=$LDFLAGS +INITIAL_LIBS=$LIBS + +dnl +dnl Detect the canonical host and target build environment +dnl + +AC_CANONICAL_HOST +dnl Get system canonical name +AC_DEFINE_UNQUOTED(OS, "${host}", [cpu-machine-OS]) + +# Silence warning: ar: 'u' modifier ignored since 'D' is the default +AC_SUBST(AR_FLAGS, [cr]) + +dnl This defines _ALL_SOURCE for AIX +CURL_CHECK_AIX_ALL_SOURCE + +dnl Our configure and build reentrant settings +CURL_CONFIGURE_THREAD_SAFE +CURL_CONFIGURE_REENTRANT + +dnl check for how to do large files +AC_SYS_LARGEFILE + +XC_LIBTOOL + +# +# Automake conditionals based on libtool related checks +# + +AM_CONDITIONAL([CURL_LT_SHLIB_USE_VERSION_INFO], + [test "x$xc_lt_shlib_use_version_info" = 'xyes']) +AM_CONDITIONAL([CURL_LT_SHLIB_USE_NO_UNDEFINED], + [test "x$xc_lt_shlib_use_no_undefined" = 'xyes']) +AM_CONDITIONAL([CURL_LT_SHLIB_USE_MIMPURE_TEXT], + [test "x$xc_lt_shlib_use_mimpure_text" = 'xyes']) + +# +# Due to libtool and automake machinery limitations of not allowing +# specifying separate CPPFLAGS or CFLAGS when compiling objects for +# inclusion of these in shared or static libraries, we are forced to +# build using separate configure runs for shared and static libraries +# on systems where different CPPFLAGS or CFLAGS are mandatory in order +# to compile objects for each kind of library. Notice that relying on +# the '-DPIC' CFLAG that libtool provides is not valid given that the +# user might for example choose to build static libraries with PIC. +# + +# +# Make our Makefile.am files use the staticlib CPPFLAG only when strictly +# targeting a static library and not building its shared counterpart. +# + +AM_CONDITIONAL([USE_CPPFLAG_CURL_STATICLIB], + [test "x$xc_lt_build_static_only" = 'xyes']) + +# +# Make staticlib CPPFLAG variable and its definition visible in output +# files unconditionally, providing an empty definition unless strictly +# targeting a static library and not building its shared counterpart. +# + +CPPFLAG_CURL_STATICLIB= +if test "x$xc_lt_build_static_only" = 'xyes'; then + CPPFLAG_CURL_STATICLIB='-DCURL_STATICLIB' +fi +AC_SUBST([CPPFLAG_CURL_STATICLIB]) + + +# Determine whether all dependent libraries must be specified when linking +if test "X$enable_shared" = "Xyes" -a "X$link_all_deplibs" = "Xno" +then + REQUIRE_LIB_DEPS=no +else + REQUIRE_LIB_DEPS=yes +fi +AC_SUBST(REQUIRE_LIB_DEPS) +AM_CONDITIONAL(USE_EXPLICIT_LIB_DEPS, test x$REQUIRE_LIB_DEPS = xyes) + +dnl check if there's a way to force code inline +AC_C_INLINE + +dnl ********************************************************************** +dnl platform/compiler/architecture specific checks/flags +dnl ********************************************************************** + +CURL_CHECK_COMPILER +CURL_SET_COMPILER_BASIC_OPTS +CURL_SET_COMPILER_DEBUG_OPTS +CURL_SET_COMPILER_OPTIMIZE_OPTS +CURL_SET_COMPILER_WARNING_OPTS + +if test "$compiler_id" = "INTEL_UNIX_C"; then + # + if test "$compiler_num" -ge "1000"; then + dnl icc 10.X or later + CFLAGS="$CFLAGS -shared-intel" + elif test "$compiler_num" -ge "900"; then + dnl icc 9.X specific + CFLAGS="$CFLAGS -i-dynamic" + fi + # +fi + +CURL_CHECK_COMPILER_HALT_ON_ERROR +CURL_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE +CURL_CHECK_COMPILER_PROTOTYPE_MISMATCH +CURL_CHECK_COMPILER_SYMBOL_HIDING + +CURL_CHECK_CURLDEBUG +AM_CONDITIONAL(CURLDEBUG, test x$want_curldebug = xyes) + +supports_unittests=yes +# cross-compilation of unit tests static library/programs fails when +# libcurl shared library is built. This might be due to a libtool or +# automake issue. In this case we disable unit tests. +if test "x$cross_compiling" != "xno" && + test "x$enable_shared" != "xno"; then + supports_unittests=no +fi + +# IRIX 6.5.24 gcc 3.3 autobuilds fail unittests library compilation due to +# a problem related with OpenSSL headers and library versions not matching. +# Disable unit tests while time to further investigate this is found. +case $host in + mips-sgi-irix6.5) + if test "$compiler_id" = "GNU_C"; then + supports_unittests=no + fi + ;; +esac + +# All AIX autobuilds fails unit tests linking against unittests library +# due to unittests library being built with no symbols or members. Libtool ? +# Disable unit tests while time to further investigate this is found. +case $host_os in + aix*) + supports_unittests=no + ;; +esac + +dnl Build unit tests when option --enable-debug is given. +if test "x$want_debug" = "xyes" && + test "x$supports_unittests" = "xyes"; then + want_unittests=yes +else + want_unittests=no +fi +AM_CONDITIONAL(BUILD_UNITTESTS, test x$want_unittests = xyes) + +dnl ********************************************************************** +dnl Compilation based checks should not be done before this point. +dnl ********************************************************************** + +dnl ********************************************************************** +dnl Make sure that our checks for headers windows.h winsock.h winsock2.h +dnl and ws2tcpip.h take precedence over any other further checks which +dnl could be done later using AC_CHECK_HEADER or AC_CHECK_HEADERS for +dnl this specific header files. And do them before its results are used. +dnl ********************************************************************** + +CURL_CHECK_HEADER_WINDOWS +CURL_CHECK_NATIVE_WINDOWS +case X-"$curl_cv_native_windows" in + X-yes) + CURL_CHECK_HEADER_WINSOCK + CURL_CHECK_HEADER_WINSOCK2 + CURL_CHECK_HEADER_WS2TCPIP + CURL_CHECK_HEADER_WINLDAP + CURL_CHECK_HEADER_WINBER + ;; + *) + curl_cv_header_winsock_h="no" + curl_cv_header_winsock2_h="no" + curl_cv_header_ws2tcpip_h="no" + curl_cv_header_winldap_h="no" + curl_cv_header_winber_h="no" + ;; +esac +CURL_CHECK_WIN32_LARGEFILE + +CURL_MAC_CFLAGS +CURL_SUPPORTS_BUILTIN_AVAILABLE + +dnl ************************************************************ +dnl switch off particular protocols +dnl +AC_MSG_CHECKING([whether to support http]) +AC_ARG_ENABLE(http, +AC_HELP_STRING([--enable-http],[Enable HTTP support]) +AC_HELP_STRING([--disable-http],[Disable HTTP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP]) + disable_http="yes" + AC_MSG_WARN([disable HTTP disables FTP over proxy and RTSP]) + AC_SUBST(CURL_DISABLE_HTTP, [1]) + AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP]) + AC_SUBST(CURL_DISABLE_RTSP, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) +AC_MSG_CHECKING([whether to support ftp]) +AC_ARG_ENABLE(ftp, +AC_HELP_STRING([--enable-ftp],[Enable FTP support]) +AC_HELP_STRING([--disable-ftp],[Disable FTP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_FTP, 1, [to disable FTP]) + AC_SUBST(CURL_DISABLE_FTP, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) +AC_MSG_CHECKING([whether to support file]) +AC_ARG_ENABLE(file, +AC_HELP_STRING([--enable-file],[Enable FILE support]) +AC_HELP_STRING([--disable-file],[Disable FILE support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_FILE, 1, [to disable FILE]) + AC_SUBST(CURL_DISABLE_FILE, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) +AC_MSG_CHECKING([whether to support ldap]) +AC_ARG_ENABLE(ldap, +AC_HELP_STRING([--enable-ldap],[Enable LDAP support]) +AC_HELP_STRING([--disable-ldap],[Disable LDAP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) + AC_SUBST(CURL_DISABLE_LDAP, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; + esac ],[ + AC_MSG_RESULT(yes) ] +) +AC_MSG_CHECKING([whether to support ldaps]) +AC_ARG_ENABLE(ldaps, +AC_HELP_STRING([--enable-ldaps],[Enable LDAPS support]) +AC_HELP_STRING([--disable-ldaps],[Disable LDAPS support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + ;; + *) if test "x$CURL_DISABLE_LDAP" = "x1" ; then + AC_MSG_RESULT(LDAP needs to be enabled to support LDAPS) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + else + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LDAP_SSL, 1, [Use LDAPS implementation]) + AC_SUBST(HAVE_LDAP_SSL, [1]) + fi + ;; + esac ],[ + if test "x$CURL_DISABLE_LDAP" = "x1" ; then + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + else + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LDAP_SSL, 1, [Use LDAPS implementation]) + AC_SUBST(HAVE_LDAP_SSL, [1]) + fi ] +) + +AC_MSG_CHECKING([whether to support rtsp]) +AC_ARG_ENABLE(rtsp, +AC_HELP_STRING([--enable-rtsp],[Enable RTSP support]) +AC_HELP_STRING([--disable-rtsp],[Disable RTSP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP]) + AC_SUBST(CURL_DISABLE_RTSP, [1]) + ;; + *) if test x$CURL_DISABLE_HTTP = x1 ; then + AC_MSG_ERROR(HTTP support needs to be enabled in order to enable RTSP support!) + else + AC_MSG_RESULT(yes) + curl_rtsp_msg="enabled" + fi + ;; + esac ], + if test "x$CURL_DISABLE_HTTP" != "x1"; then + AC_MSG_RESULT(yes) + curl_rtsp_msg="enabled" + else + AC_MSG_RESULT(no) + fi +) + +AC_MSG_CHECKING([whether to support proxies]) +AC_ARG_ENABLE(proxy, +AC_HELP_STRING([--enable-proxy],[Enable proxy support]) +AC_HELP_STRING([--disable-proxy],[Disable proxy support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_PROXY, 1, [to disable proxies]) + AC_SUBST(CURL_DISABLE_PROXY, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +AC_MSG_CHECKING([whether to support dict]) +AC_ARG_ENABLE(dict, +AC_HELP_STRING([--enable-dict],[Enable DICT support]) +AC_HELP_STRING([--disable-dict],[Disable DICT support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_DICT, 1, [to disable DICT]) + AC_SUBST(CURL_DISABLE_DICT, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) +AC_MSG_CHECKING([whether to support telnet]) +AC_ARG_ENABLE(telnet, +AC_HELP_STRING([--enable-telnet],[Enable TELNET support]) +AC_HELP_STRING([--disable-telnet],[Disable TELNET support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_TELNET, 1, [to disable TELNET]) + AC_SUBST(CURL_DISABLE_TELNET, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) +AC_MSG_CHECKING([whether to support tftp]) +AC_ARG_ENABLE(tftp, +AC_HELP_STRING([--enable-tftp],[Enable TFTP support]) +AC_HELP_STRING([--disable-tftp],[Disable TFTP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_TFTP, 1, [to disable TFTP]) + AC_SUBST(CURL_DISABLE_TFTP, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +AC_MSG_CHECKING([whether to support pop3]) +AC_ARG_ENABLE(pop3, +AC_HELP_STRING([--enable-pop3],[Enable POP3 support]) +AC_HELP_STRING([--disable-pop3],[Disable POP3 support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_POP3, 1, [to disable POP3]) + AC_SUBST(CURL_DISABLE_POP3, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + + +AC_MSG_CHECKING([whether to support imap]) +AC_ARG_ENABLE(imap, +AC_HELP_STRING([--enable-imap],[Enable IMAP support]) +AC_HELP_STRING([--disable-imap],[Disable IMAP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_IMAP, 1, [to disable IMAP]) + AC_SUBST(CURL_DISABLE_IMAP, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + + +AC_MSG_CHECKING([whether to support smb]) +AC_ARG_ENABLE(smb, +AC_HELP_STRING([--enable-smb],[Enable SMB/CIFS support]) +AC_HELP_STRING([--disable-smb],[Disable SMB/CIFS support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SMB, 1, [to disable SMB/CIFS]) + AC_SUBST(CURL_DISABLE_SMB, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +AC_MSG_CHECKING([whether to support smtp]) +AC_ARG_ENABLE(smtp, +AC_HELP_STRING([--enable-smtp],[Enable SMTP support]) +AC_HELP_STRING([--disable-smtp],[Disable SMTP support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SMTP, 1, [to disable SMTP]) + AC_SUBST(CURL_DISABLE_SMTP, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +AC_MSG_CHECKING([whether to support gopher]) +AC_ARG_ENABLE(gopher, +AC_HELP_STRING([--enable-gopher],[Enable Gopher support]) +AC_HELP_STRING([--disable-gopher],[Disable Gopher support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable Gopher]) + AC_SUBST(CURL_DISABLE_GOPHER, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + + +dnl ********************************************************************** +dnl Check for built-in manual +dnl ********************************************************************** + +AC_MSG_CHECKING([whether to provide built-in manual]) +AC_ARG_ENABLE(manual, +AC_HELP_STRING([--enable-manual],[Enable built-in manual]) +AC_HELP_STRING([--disable-manual],[Disable built-in manual]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + ;; + *) AC_MSG_RESULT(yes) + USE_MANUAL="1" + ;; + esac ], + AC_MSG_RESULT(yes) + USE_MANUAL="1" +) +dnl The actual use of the USE_MANUAL variable is done much later in this +dnl script to allow other actions to disable it as well. + +dnl ************************************************************ +dnl disable C code generation support +dnl +AC_MSG_CHECKING([whether to enable generation of C code]) +AC_ARG_ENABLE(libcurl_option, +AC_HELP_STRING([--enable-libcurl-option],[Enable --libcurl C code generation support]) +AC_HELP_STRING([--disable-libcurl-option],[Disable --libcurl C code generation support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LIBCURL_OPTION, 1, [to disable --libcurl C code generation option]) + curl_libcurl_msg="no" + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +dnl ********************************************************************** +dnl Checks for libraries. +dnl ********************************************************************** + +AC_MSG_CHECKING([whether to use libgcc]) +AC_ARG_ENABLE(libgcc, +AC_HELP_STRING([--enable-libgcc],[use libgcc when linking]), +[ case "$enableval" in + yes) + LIBS="-lgcc $LIBS" + AC_MSG_RESULT(yes) + ;; + *) AC_MSG_RESULT(no) + ;; + esac ], + AC_MSG_RESULT(no) +) + +CURL_CHECK_LIB_XNET + +dnl gethostbyname without lib or in the nsl lib? +AC_CHECK_FUNC(gethostbyname, + [HAVE_GETHOSTBYNAME="1" + ], + [ AC_CHECK_LIB(nsl, gethostbyname, + [HAVE_GETHOSTBYNAME="1" + LIBS="-lnsl $LIBS" + ]) + ]) + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl gethostbyname in the socket lib? + AC_CHECK_LIB(socket, gethostbyname, + [HAVE_GETHOSTBYNAME="1" + LIBS="-lsocket $LIBS" + ]) +fi + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl gethostbyname in the watt lib? + AC_CHECK_LIB(watt, gethostbyname, + [HAVE_GETHOSTBYNAME="1" + CPPFLAGS="-I/dev/env/WATT_ROOT/inc" + LDFLAGS="-L/dev/env/WATT_ROOT/lib" + LIBS="-lwatt $LIBS" + ]) +fi + +dnl At least one system has been identified to require BOTH nsl and socket +dnl libs at the same time to link properly. +if test "$HAVE_GETHOSTBYNAME" != "1" +then + AC_MSG_CHECKING([for gethostbyname with both nsl and socket libs]) + my_ac_save_LIBS=$LIBS + LIBS="-lnsl -lsocket $LIBS" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ + gethostbyname(); + ]]) + ],[ + AC_MSG_RESULT([yes]) + HAVE_GETHOSTBYNAME="1" + ],[ + AC_MSG_RESULT([no]) + LIBS=$my_ac_save_LIBS + ]) +fi + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl This is for winsock systems + if test "$curl_cv_header_windows_h" = "yes"; then + if test "$curl_cv_header_winsock_h" = "yes"; then + case $host in + *-*-mingw32ce*) + winsock_LIB="-lwinsock" + ;; + *) + winsock_LIB="-lwsock32" + ;; + esac + fi + if test "$curl_cv_header_winsock2_h" = "yes"; then + winsock_LIB="-lws2_32" + fi + if test ! -z "$winsock_LIB"; then + my_ac_save_LIBS=$LIBS + LIBS="$winsock_LIB $LIBS" + AC_MSG_CHECKING([for gethostbyname in $winsock_LIB]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#endif + ]],[[ + gethostbyname("www.dummysite.com"); + ]]) + ],[ + AC_MSG_RESULT([yes]) + HAVE_GETHOSTBYNAME="1" + ],[ + AC_MSG_RESULT([no]) + winsock_LIB="" + LIBS=$my_ac_save_LIBS + ]) + fi + fi +fi + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl This is for Minix 3.1 + AC_MSG_CHECKING([for gethostbyname for Minix 3]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +/* Older Minix versions may need here instead */ +#include + ]],[[ + gethostbyname("www.dummysite.com"); + ]]) + ],[ + AC_MSG_RESULT([yes]) + HAVE_GETHOSTBYNAME="1" + ],[ + AC_MSG_RESULT([no]) + ]) +fi + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl This is for eCos with a stubbed DNS implementation + AC_MSG_CHECKING([for gethostbyname for eCos]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include + ]],[[ + gethostbyname("www.dummysite.com"); + ]]) + ],[ + AC_MSG_RESULT([yes]) + HAVE_GETHOSTBYNAME="1" + ],[ + AC_MSG_RESULT([no]) + ]) +fi + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl gethostbyname in the network lib - for Haiku OS + AC_CHECK_LIB(network, gethostbyname, + [HAVE_GETHOSTBYNAME="1" + LIBS="-lnetwork $LIBS" + ]) +fi + +if test "$HAVE_GETHOSTBYNAME" != "1" +then + dnl gethostbyname in the net lib - for BeOS + AC_CHECK_LIB(net, gethostbyname, + [HAVE_GETHOSTBYNAME="1" + LIBS="-lnet $LIBS" + ]) +fi + + +if test "$HAVE_GETHOSTBYNAME" != "1"; then + AC_MSG_ERROR([couldn't find libraries for gethostbyname()]) +fi + +CURL_CHECK_LIBS_CONNECT + +CURL_NETWORK_LIBS=$LIBS + +dnl ********************************************************************** +dnl In case that function clock_gettime with monotonic timer is available, +dnl check for additional required libraries. +dnl ********************************************************************** +CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC + +dnl ********************************************************************** +dnl The preceding library checks are all potentially useful for test +dnl servers and libtest cases which require networking and clock_gettime +dnl support. Save the list of required libraries at this point for use +dnl while linking those test servers and programs. +dnl ********************************************************************** +CURL_NETWORK_AND_TIME_LIBS=$LIBS + +dnl ********************************************************************** +dnl Check for the presence of ZLIB libraries and headers +dnl ********************************************************************** + +dnl Check for & handle argument to --with-zlib. + +clean_CPPFLAGS=$CPPFLAGS +clean_LDFLAGS=$LDFLAGS +clean_LIBS=$LIBS +ZLIB_LIBS="" +AC_ARG_WITH(zlib, +AC_HELP_STRING([--with-zlib=PATH],[search for zlib in PATH]) +AC_HELP_STRING([--without-zlib],[disable use of zlib]), + [OPT_ZLIB="$withval"]) + +if test "$OPT_ZLIB" = "no" ; then + AC_MSG_WARN([zlib disabled]) +else + if test "$OPT_ZLIB" = "yes" ; then + OPT_ZLIB="" + fi + + if test -z "$OPT_ZLIB" ; then + CURL_CHECK_PKGCONFIG(zlib) + + if test "$PKGCONFIG" != "no" ; then + LIBS="`$PKGCONFIG --libs-only-l zlib` $LIBS" + LDFLAGS="$LDFLAGS `$PKGCONFIG --libs-only-L zlib`" + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags-only-I zlib`" + OPT_ZLIB="" + HAVE_LIBZ="1" + fi + + if test -z "$HAVE_LIBZ"; then + + dnl Check for the lib without setting any new path, since many + dnl people have it in the default path + + AC_CHECK_LIB(z, inflateEnd, + dnl libz found, set the variable + [HAVE_LIBZ="1" + LIBS="-lz $LIBS"], + dnl if no lib found, try /usr/local + [OPT_ZLIB="/usr/local"]) + fi + fi + + dnl Add a nonempty path to the compiler flags + if test -n "$OPT_ZLIB"; then + CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include" + LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff" + fi + + AC_CHECK_HEADER(zlib.h, + [ + dnl zlib.h was found + HAVE_ZLIB_H="1" + dnl if the lib wasn't found already, try again with the new paths + if test "$HAVE_LIBZ" != "1"; then + AC_CHECK_LIB(z, gzread, + [ + dnl the lib was found! + HAVE_LIBZ="1" + LIBS="-lz $LIBS" + ], + [ CPPFLAGS=$clean_CPPFLAGS + LDFLAGS=$clean_LDFLAGS]) + fi + ], + [ + dnl zlib.h was not found, restore the flags + CPPFLAGS=$clean_CPPFLAGS + LDFLAGS=$clean_LDFLAGS] + ) + + if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1" + then + AC_MSG_WARN([configure found only the libz lib, not the header file!]) + HAVE_LIBZ="" + CPPFLAGS=$clean_CPPFLAGS + LDFLAGS=$clean_LDFLAGS + LIBS=$clean_LIBS + elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1" + then + AC_MSG_WARN([configure found only the libz header file, not the lib!]) + CPPFLAGS=$clean_CPPFLAGS + LDFLAGS=$clean_LDFLAGS + LIBS=$clean_LIBS + elif test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" = "1" + then + dnl both header and lib were found! + AC_SUBST(HAVE_LIBZ) + AC_DEFINE(HAVE_ZLIB_H, 1, [if you have the zlib.h header file]) + AC_DEFINE(HAVE_LIBZ, 1, [if zlib is available]) + + ZLIB_LIBS="-lz" + LIBS="-lz $clean_LIBS" + + dnl replace 'HAVE_LIBZ' in the automake makefile.ams + AMFIXLIB="1" + AC_MSG_NOTICE([found both libz and libz.h header]) + curl_zlib_msg="enabled" + fi +fi + +dnl set variable for use in automakefile(s) +AM_CONDITIONAL(HAVE_LIBZ, test x"$AMFIXLIB" = x1) +AC_SUBST(ZLIB_LIBS) + +dnl ********************************************************************** +dnl Check for the presence of BROTLI decoder libraries and headers +dnl ********************************************************************** + +dnl Brotli project home page: https://github.com/google/brotli + +dnl Default to compiler & linker defaults for BROTLI files & libraries. +OPT_BROTLI=off +AC_ARG_WITH(brotli,dnl +AC_HELP_STRING([--with-brotli=PATH],[Where to look for brotli, PATH points to the BROTLI installation; when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]) +AC_HELP_STRING([--without-brotli], [disable BROTLI]), + OPT_BROTLI=$withval) + +if test X"$OPT_BROTLI" != Xno; then + dnl backup the pre-brotli variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + case "$OPT_BROTLI" in + yes) + dnl --with-brotli (without path) used + CURL_CHECK_PKGCONFIG(libbrotlidec) + + if test "$PKGCONFIG" != "no" ; then + LIB_BROTLI=`$PKGCONFIG --libs-only-l libbrotlidec` + LD_BROTLI=`$PKGCONFIG --libs-only-L libbrotlidec` + CPP_BROTLI=`$PKGCONFIG --cflags-only-I libbrotlidec` + version=`$PKGCONFIG --modversion libbrotlidec` + DIR_BROTLI=`echo $LD_BROTLI | $SED -e 's/-L//'` + fi + + ;; + off) + dnl no --with-brotli option given, just check default places + ;; + *) + dnl use the given --with-brotli spot + PREFIX_BROTLI=$OPT_BROTLI + ;; + esac + + dnl if given with a prefix, we set -L and -I based on that + if test -n "$PREFIX_BROTLI"; then + LIB_BROTLI="-lbrotlidec" + LD_BROTLI=-L${PREFIX_BROTLI}/lib$libsuff + CPP_BROTLI=-I${PREFIX_BROTLI}/include + DIR_BROTLI=${PREFIX_BROTLI}/lib$libsuff + fi + + LDFLAGS="$LDFLAGS $LD_BROTLI" + CPPFLAGS="$CPPFLAGS $CPP_BROTLI" + LIBS="$LIB_BROTLI $LIBS" + + AC_CHECK_LIB(brotlidec, BrotliDecoderDecompress) + + AC_CHECK_HEADERS(brotli/decode.h, + curl_brotli_msg="enabled (libbrotlidec)" + HAVE_BROTLI=1 + AC_DEFINE(HAVE_BROTLI, 1, [if BROTLI is in use]) + AC_SUBST(HAVE_BROTLI, [1]) + ) + + if test X"$OPT_BROTLI" != Xoff && + test "$HAVE_BROTLI" != "1"; then + AC_MSG_ERROR([BROTLI libs and/or directories were not found where specified!]) + fi + + if test "$HAVE_BROTLI" = "1"; then + if test -n "$DIR_BROTLI"; then + dnl when the brotli shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_BROTLI" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_BROTLI to CURL_LIBRARY_PATH]) + fi + fi + else + dnl no brotli, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + fi +fi + +dnl ********************************************************************** +dnl Check for LDAP +dnl ********************************************************************** + +LDAPLIBNAME="" +AC_ARG_WITH(ldap-lib, +AC_HELP_STRING([--with-ldap-lib=libname],[Specify name of ldap lib file]), + [LDAPLIBNAME="$withval"]) + +LBERLIBNAME="" +AC_ARG_WITH(lber-lib, +AC_HELP_STRING([--with-lber-lib=libname],[Specify name of lber lib file]), + [LBERLIBNAME="$withval"]) + +if test x$CURL_DISABLE_LDAP != x1 ; then + + CURL_CHECK_HEADER_LBER + CURL_CHECK_HEADER_LDAP + CURL_CHECK_HEADER_LDAPSSL + CURL_CHECK_HEADER_LDAP_SSL + + if test -z "$LDAPLIBNAME" ; then + if test "$curl_cv_native_windows" = "yes"; then + dnl Windows uses a single and unique LDAP library name + LDAPLIBNAME="wldap32" + LBERLIBNAME="no" + fi + fi + + if test "$LDAPLIBNAME" ; then + AC_CHECK_LIB("$LDAPLIBNAME", ldap_init,, [ + AC_MSG_WARN(["$LDAPLIBNAME" is not an LDAP library: LDAP disabled]) + AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) + AC_SUBST(CURL_DISABLE_LDAP, [1]) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1])]) + else + dnl Try to find the right ldap libraries for this system + CURL_CHECK_LIBS_LDAP + case X-"$curl_cv_ldap_LIBS" in + X-unknown) + AC_MSG_WARN([Cannot find libraries for LDAP support: LDAP disabled]) + AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) + AC_SUBST(CURL_DISABLE_LDAP, [1]) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + ;; + esac + fi +fi + +if test x$CURL_DISABLE_LDAP != x1 ; then + + if test "$LBERLIBNAME" ; then + dnl If name is "no" then don't define this library at all + dnl (it's only needed if libldap.so's dependencies are broken). + if test "$LBERLIBNAME" != "no" ; then + AC_CHECK_LIB("$LBERLIBNAME", ber_free,, [ + AC_MSG_WARN(["$LBERLIBNAME" is not an LBER library: LDAP disabled]) + AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) + AC_SUBST(CURL_DISABLE_LDAP, [1]) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1])]) + fi + fi +fi + +if test x$CURL_DISABLE_LDAP != x1 ; then + AC_CHECK_FUNCS([ldap_url_parse ldap_init_fd]) + + if test "$LDAPLIBNAME" = "wldap32"; then + curl_ldap_msg="enabled (winldap)" + AC_DEFINE(USE_WIN32_LDAP, 1, [Use Windows LDAP implementation]) + else + curl_ldap_msg="enabled (OpenLDAP)" + if test "x$ac_cv_func_ldap_init_fd" = "xyes"; then + AC_DEFINE(USE_OPENLDAP, 1, [Use OpenLDAP-specific code]) + AC_SUBST(USE_OPENLDAP, [1]) + fi + fi +fi + +if test x$CURL_DISABLE_LDAPS != x1 ; then + curl_ldaps_msg="enabled" +fi + +dnl ********************************************************************** +dnl Checks for IPv6 +dnl ********************************************************************** + +AC_MSG_CHECKING([whether to enable IPv6]) +AC_ARG_ENABLE(ipv6, +AC_HELP_STRING([--enable-ipv6],[Enable IPv6 (with IPv4) support]) +AC_HELP_STRING([--disable-ipv6],[Disable IPv6 support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + ipv6=no + ;; + *) AC_MSG_RESULT(yes) + ipv6=yes + ;; + esac ], + + AC_TRY_RUN([ /* is AF_INET6 available? */ +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#include +#endif +#include /* for exit() */ +main() +{ + if (socket(AF_INET6, SOCK_STREAM, 0) < 0) + exit(1); + else + exit(0); +} +], + AC_MSG_RESULT(yes) + ipv6=yes, + AC_MSG_RESULT(no) + ipv6=no, + AC_MSG_RESULT(yes) + ipv6=yes +)) + +if test "$ipv6" = "yes"; then + curl_ipv6_msg="enabled" +fi + +# Check if struct sockaddr_in6 have sin6_scope_id member +if test "$ipv6" = yes; then + AC_MSG_CHECKING([if struct sockaddr_in6 has sin6_scope_id member]) + AC_TRY_COMPILE([ +#include +#ifdef HAVE_WINSOCK2_H +#include +#include +#else +#include +#if defined (__TANDEM) +# include +#endif +#endif] , + struct sockaddr_in6 s; s.sin6_scope_id = 0; , have_sin6_scope_id=yes) + if test "$have_sin6_scope_id" = yes; then + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID, 1, [Define to 1 if struct sockaddr_in6 has the sin6_scope_id member]) + else + AC_MSG_RESULT([no]) + fi +fi + +dnl ********************************************************************** +dnl Check if the operating system allows programs to write to their own argv[] +dnl ********************************************************************** + +AC_MSG_CHECKING([if argv can be written to]) +CURL_RUN_IFELSE([ +int main(int argc, char ** argv) { + argv[0][0] = ' '; + return (argv[0][0] == ' ')?0:1; +} +],[ + curl_cv_writable_argv=yes +],[ + curl_cv_writable_argv=no +],[ + curl_cv_writable_argv=cross +]) +case $curl_cv_writable_argv in +yes) + AC_DEFINE(HAVE_WRITABLE_ARGV, 1, [Define this symbol if your OS supports changing the contents of argv]) + AC_MSG_RESULT(yes) + ;; +no) + AC_MSG_RESULT(no) + ;; +*) + AC_MSG_RESULT(no) + AC_MSG_WARN([the previous check could not be made default was used]) + ;; +esac + +dnl ********************************************************************** +dnl Check for GSS-API libraries +dnl ********************************************************************** + +dnl check for GSS-API stuff in the /usr as default + +GSSAPI_ROOT="/usr" +AC_ARG_WITH(gssapi-includes, + AC_HELP_STRING([--with-gssapi-includes=DIR], + [Specify location of GSS-API headers]), + [ GSSAPI_INCS="-I$withval" + want_gss="yes" ] +) + +AC_ARG_WITH(gssapi-libs, + AC_HELP_STRING([--with-gssapi-libs=DIR], + [Specify location of GSS-API libs]), + [ GSSAPI_LIB_DIR="-L$withval" + want_gss="yes" ] +) + +AC_ARG_WITH(gssapi, + AC_HELP_STRING([--with-gssapi=DIR], + [Where to look for GSS-API]), [ + GSSAPI_ROOT="$withval" + if test x"$GSSAPI_ROOT" != xno; then + want_gss="yes" + if test x"$GSSAPI_ROOT" = xyes; then + dnl if yes, then use default root + GSSAPI_ROOT="/usr" + fi + fi +]) + +: ${KRB5CONFIG:="$GSSAPI_ROOT/bin/krb5-config"} + +save_CPPFLAGS="$CPPFLAGS" +AC_MSG_CHECKING([if GSS-API support is requested]) +if test x"$want_gss" = xyes; then + AC_MSG_RESULT(yes) + + if test -z "$GSSAPI_INCS"; then + if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` + elif test -f "$KRB5CONFIG"; then + GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` + elif test "$GSSAPI_ROOT" != "yes"; then + GSSAPI_INCS="-I$GSSAPI_ROOT/include" + fi + fi + + CPPFLAGS="$CPPFLAGS $GSSAPI_INCS" + + AC_CHECK_HEADER(gss.h, + [ + dnl found in the given dirs + AC_DEFINE(HAVE_GSSGNU, 1, [if you have GNU GSS]) + gnu_gss=yes + ], + [ + dnl not found, check Heimdal or MIT + AC_CHECK_HEADERS([gssapi/gssapi.h], [], [not_mit=1]) + AC_CHECK_HEADERS( + [gssapi/gssapi_generic.h gssapi/gssapi_krb5.h], + [], + [not_mit=1], + [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_GSSAPI_GSSAPI_H +#include +#endif + ]) + if test "x$not_mit" = "x1"; then + dnl MIT not found, check for Heimdal + AC_CHECK_HEADER(gssapi.h, + [ + dnl found + AC_DEFINE(HAVE_GSSHEIMDAL, 1, [if you have Heimdal]) + ], + [ + dnl no header found, disabling GSS + want_gss=no + AC_MSG_WARN(disabling GSS-API support since no header files were found) + ] + ) + else + dnl MIT found + AC_DEFINE(HAVE_GSSMIT, 1, [if you have MIT Kerberos]) + dnl check if we have a really old MIT Kerberos version (<= 1.2) + AC_MSG_CHECKING([if GSS-API headers declare GSS_C_NT_HOSTBASED_SERVICE]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include +#include + ]],[[ + gss_import_name( + (OM_uint32 *)0, + (gss_buffer_t)0, + GSS_C_NT_HOSTBASED_SERVICE, + (gss_name_t *)0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_DEFINE(HAVE_OLD_GSSMIT, 1, + [if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE]) + ]) + fi + ] + ) +else + AC_MSG_RESULT(no) +fi +if test x"$want_gss" = xyes; then + AC_DEFINE(HAVE_GSSAPI, 1, [if you have GSS-API libraries]) + HAVE_GSSAPI=1 + curl_gss_msg="enabled (MIT Kerberos/Heimdal)" + + if test -n "$gnu_gss"; then + curl_gss_msg="enabled (GNU GSS)" + LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" + LIBS="-lgss $LIBS" + elif test -z "$GSSAPI_LIB_DIR"; then + case $host in + *-*-darwin*) + LIBS="-lgssapi_krb5 -lresolv $LIBS" + ;; + *) + if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + dnl krb5-config doesn't have --libs-only-L or similar, put everything + dnl into LIBS + gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` + LIBS="$gss_libs $LIBS" + elif test -f "$KRB5CONFIG"; then + dnl krb5-config doesn't have --libs-only-L or similar, put everything + dnl into LIBS + gss_libs=`$KRB5CONFIG --libs gssapi` + LIBS="$gss_libs $LIBS" + else + case $host in + *-hp-hpux*) + gss_libname="gss" + ;; + *) + gss_libname="gssapi" + ;; + esac + + if test "$GSSAPI_ROOT" != "yes"; then + LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" + LIBS="-l$gss_libname $LIBS" + else + LIBS="-l$gss_libname $LIBS" + fi + fi + ;; + esac + else + LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" + case $host in + *-hp-hpux*) + LIBS="-lgss $LIBS" + ;; + *) + LIBS="-lgssapi $LIBS" + ;; + esac + fi +else + CPPFLAGS="$save_CPPFLAGS" +fi + +build_libstubgss=no +if test x"$want_gss" = "xyes"; then + build_libstubgss=yes +fi + +AM_CONDITIONAL(BUILD_STUB_GSS, test "x$build_libstubgss" = "xyes") + +dnl ------------------------------------------------------------- +dnl parse --with-default-ssl-backend so it can be validated below +dnl ------------------------------------------------------------- + +DEFAULT_SSL_BACKEND=no +VALID_DEFAULT_SSL_BACKEND= +AC_ARG_WITH(default-ssl-backend, +AC_HELP_STRING([--with-default-ssl-backend=NAME],[Use NAME as default SSL backend]) +AC_HELP_STRING([--without-default-ssl-backend],[Use implicit default SSL backend]), + [DEFAULT_SSL_BACKEND=$withval]) +case "$DEFAULT_SSL_BACKEND" in + no) + dnl --without-default-ssl-backend option used + ;; + default|yes) + dnl --with-default-ssl-backend option used without name + AC_MSG_ERROR([The name of the default SSL backend is required.]) + ;; + *) + dnl --with-default-ssl-backend option used with name + AC_SUBST(DEFAULT_SSL_BACKEND) + dnl needs to be validated below + VALID_DEFAULT_SSL_BACKEND=no + ;; +esac + +dnl ********************************************************************** + +dnl ------------------------------------------------- +dnl check winssl option before other SSL libraries +dnl ------------------------------------------------- + +OPT_WINSSL=no +AC_ARG_WITH(winssl,dnl +AC_HELP_STRING([--with-winssl],[enable Windows native SSL/TLS]) +AC_HELP_STRING([--without-winssl], [disable Windows native SSL/TLS]), + OPT_WINSSL=$withval) + +AC_MSG_CHECKING([whether to enable Windows native SSL/TLS (Windows native builds only)]) +if test -z "$ssl_backends" -o "x$OPT_WINSSL" != xno; then + ssl_msg= + if test "x$OPT_WINSSL" != "xno" && + test "x$curl_cv_native_windows" = "xyes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(USE_SCHANNEL, 1, [to enable Windows native SSL/TLS support]) + AC_SUBST(USE_SCHANNEL, [1]) + ssl_msg="Windows-native" + test schannel != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + WINSSL_ENABLED=1 + # --with-winssl implies --enable-sspi + AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support]) + AC_SUBST(USE_WINDOWS_SSPI, [1]) + curl_sspi_msg="enabled" + LIBS="-lcrypt32 $LIBS" + else + AC_MSG_RESULT(no) + fi + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +else + AC_MSG_RESULT(no) +fi + +OPT_DARWINSSL=no +AC_ARG_WITH(darwinssl,dnl +AC_HELP_STRING([--with-darwinssl],[enable Apple OS native SSL/TLS]) +AC_HELP_STRING([--without-darwinssl], [disable Apple OS native SSL/TLS]), + OPT_DARWINSSL=$withval) + +AC_MSG_CHECKING([whether to enable Apple OS native SSL/TLS]) +if test -z "$ssl_backends" -o "x$OPT_DARWINSSL" != xno; then + if test "x$OPT_DARWINSSL" != "xno" && + test -d "/System/Library/Frameworks/Security.framework"; then + AC_MSG_RESULT(yes) + AC_DEFINE(USE_DARWINSSL, 1, [to enable Apple OS native SSL/TLS support]) + AC_SUBST(USE_DARWINSSL, [1]) + ssl_msg="Apple OS-native" + test darwinssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + DARWINSSL_ENABLED=1 + LDFLAGS="$LDFLAGS -framework CoreFoundation -framework Security" + else + AC_MSG_RESULT(no) + fi + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +else + AC_MSG_RESULT(no) +fi + +dnl ********************************************************************** +dnl Check for the presence of SSL libraries and headers +dnl ********************************************************************** + +dnl Default to compiler & linker defaults for SSL files & libraries. +OPT_SSL=off +dnl Default to no CA bundle +ca="no" +AC_ARG_WITH(ssl,dnl +AC_HELP_STRING([--with-ssl=PATH],[Where to look for OpenSSL, PATH points to the SSL installation (default: /usr/local/ssl); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]) +AC_HELP_STRING([--without-ssl], [disable OpenSSL]), + OPT_SSL=$withval) + +if test -z "$ssl_backends" -o "x$OPT_SSL" != xno && + test X"$OPT_SSL" != Xno; then + ssl_msg= + + dnl backup the pre-ssl variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + dnl This is for Msys/Mingw + case $host in + *-*-msys* | *-*-mingw*) + AC_MSG_CHECKING([for gdi32]) + my_ac_save_LIBS=$LIBS + LIBS="-lgdi32 $LIBS" + AC_TRY_LINK([#include + #include ], + [GdiFlush();], + [ dnl worked! + AC_MSG_RESULT([yes])], + [ dnl failed, restore LIBS + LIBS=$my_ac_save_LIBS + AC_MSG_RESULT(no)] + ) + ;; + esac + + case "$OPT_SSL" in + yes) + dnl --with-ssl (without path) used + if test x$cross_compiling != xyes; then + dnl only do pkg-config magic when not cross-compiling + PKGTEST="yes" + fi + PREFIX_OPENSSL=/usr/local/ssl + LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff" + ;; + off) + dnl no --with-ssl option given, just check default places + if test x$cross_compiling != xyes; then + dnl only do pkg-config magic when not cross-compiling + PKGTEST="yes" + fi + PREFIX_OPENSSL= + ;; + *) + dnl check the given --with-ssl spot + PKGTEST="no" + PREFIX_OPENSSL=$OPT_SSL + + dnl Try pkg-config even when cross-compiling. Since we + dnl specify PKG_CONFIG_LIBDIR we're only looking where + dnl the user told us to look + OPENSSL_PCDIR="$OPT_SSL/lib/pkgconfig" + if test -f "$OPENSSL_PCDIR/openssl.pc"; then + AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$OPENSSL_PCDIR"]) + PKGTEST="yes" + elif test ! -f "$PREFIX_OPENSSL/include/openssl/ssl.h"; then + AC_MSG_ERROR([$PREFIX_OPENSSL is a bad --with-ssl prefix!]) + fi + + dnl in case pkg-config comes up empty, use what we got + dnl via --with-ssl + LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff" + if test "$PREFIX_OPENSSL" != "/usr" ; then + SSL_LDFLAGS="-L$LIB_OPENSSL" + SSL_CPPFLAGS="-I$PREFIX_OPENSSL/include" + fi + SSL_CPPFLAGS="$SSL_CPPFLAGS -I$PREFIX_OPENSSL/include/openssl" + ;; + esac + + if test "$PKGTEST" = "yes"; then + + CURL_CHECK_PKGCONFIG(openssl, [$OPENSSL_PCDIR]) + + if test "$PKGCONFIG" != "no" ; then + SSL_LIBS=`CURL_EXPORT_PCDIR([$OPENSSL_PCDIR]) dnl + $PKGCONFIG --libs-only-l openssl 2>/dev/null` + + SSL_LDFLAGS=`CURL_EXPORT_PCDIR([$OPENSSL_PCDIR]) dnl + $PKGCONFIG --libs-only-L openssl 2>/dev/null` + + SSL_CPPFLAGS=`CURL_EXPORT_PCDIR([$OPENSSL_PCDIR]) dnl + $PKGCONFIG --cflags-only-I openssl 2>/dev/null` + + AC_SUBST(SSL_LIBS) + AC_MSG_NOTICE([pkg-config: SSL_LIBS: "$SSL_LIBS"]) + AC_MSG_NOTICE([pkg-config: SSL_LDFLAGS: "$SSL_LDFLAGS"]) + AC_MSG_NOTICE([pkg-config: SSL_CPPFLAGS: "$SSL_CPPFLAGS"]) + + LIB_OPENSSL=`echo $SSL_LDFLAGS | sed -e 's/-L//g'` + + dnl use the values pkg-config reported. This is here + dnl instead of below with CPPFLAGS and LDFLAGS because we only + dnl learn about this via pkg-config. If we only have + dnl the argument to --with-ssl we don't know what + dnl additional libs may be necessary. Hope that we + dnl don't need any. + LIBS="$SSL_LIBS $LIBS" + fi + fi + + dnl finally, set flags to use SSL + CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS" + LDFLAGS="$LDFLAGS $SSL_LDFLAGS" + + AC_CHECK_LIB(crypto, HMAC_Update,[ + HAVECRYPTO="yes" + LIBS="-lcrypto $LIBS" + ],[ + LDFLAGS="$CLEANLDFLAGS -L$LIB_OPENSSL" + CPPFLAGS="$CLEANCPPFLAGS -I$PREFIX_OPENSSL/include/openssl -I$PREFIX_OPENSSL/include" + AC_CHECK_LIB(crypto, HMAC_Init_ex,[ + HAVECRYPTO="yes" + LIBS="-lcrypto $LIBS"], [ + + dnl still no, but what about with -ldl? + AC_MSG_CHECKING([OpenSSL linking with -ldl]) + LIBS="$CLEANLIBS -lcrypto -ldl" + AC_TRY_LINK( + [ + #include + ], + [ + ERR_clear_error(); + ], + [ + AC_MSG_RESULT(yes) + HAVECRYPTO="yes" + ], + [ + AC_MSG_RESULT(no) + dnl ok, so what about both -ldl and -lpthread? + + AC_MSG_CHECKING([OpenSSL linking with -ldl and -lpthread]) + LIBS="$CLEANLIBS -lcrypto -ldl -lpthread" + AC_TRY_LINK( + [ + #include + ], + [ + ERR_clear_error(); + ], + [ + AC_MSG_RESULT(yes) + HAVECRYPTO="yes" + ], + [ + AC_MSG_RESULT(no) + LDFLAGS="$CLEANLDFLAGS" + CPPFLAGS="$CLEANCPPFLAGS" + LIBS="$CLEANLIBS" + + ]) + + ]) + + ]) + ]) + + if test X"$HAVECRYPTO" = X"yes"; then + dnl This is only reasonable to do if crypto actually is there: check for + dnl SSL libs NOTE: it is important to do this AFTER the crypto lib + + AC_CHECK_LIB(ssl, SSL_connect) + + if test "$ac_cv_lib_ssl_SSL_connect" != yes; then + dnl we didn't find the SSL lib, try the RSAglue/rsaref stuff + AC_MSG_CHECKING(for ssl with RSAglue/rsaref libs in use); + OLIBS=$LIBS + LIBS="-lRSAglue -lrsaref $LIBS" + AC_CHECK_LIB(ssl, SSL_connect) + if test "$ac_cv_lib_ssl_SSL_connect" != yes; then + dnl still no SSL_connect + AC_MSG_RESULT(no) + LIBS=$OLIBS + else + AC_MSG_RESULT(yes) + fi + + else + + dnl Have the libraries--check for OpenSSL headers + AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \ + openssl/pem.h openssl/ssl.h openssl/err.h, + ssl_msg="OpenSSL" + test openssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + OPENSSL_ENABLED=1 + AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use])) + + if test $ac_cv_header_openssl_x509_h = no; then + dnl we don't use the "action" part of the AC_CHECK_HEADERS macro + dnl since 'err.h' might in fact find a krb4 header with the same + dnl name + AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h) + + if test $ac_cv_header_x509_h = yes && + test $ac_cv_header_crypto_h = yes && + test $ac_cv_header_ssl_h = yes; then + dnl three matches + ssl_msg="OpenSSL" + OPENSSL_ENABLED=1 + fi + fi + fi + + if test X"$OPENSSL_ENABLED" != X"1"; then + LIBS="$CLEANLIBS" + fi + + if test X"$OPT_SSL" != Xoff && + test "$OPENSSL_ENABLED" != "1"; then + AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!]) + fi + fi + + if test X"$OPENSSL_ENABLED" = X"1"; then + dnl These can only exist if OpenSSL exists + dnl Older versions of Cyassl (some time before 2.9.4) don't have + dnl SSL_get_shutdown (but this check won't actually detect it there + dnl as it's a macro that needs the header files be included) + + AC_CHECK_FUNCS( RAND_egd \ + ENGINE_cleanup \ + SSL_get_shutdown \ + SSLv2_client_method ) + + AC_MSG_CHECKING([for BoringSSL]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + #include + ]],[[ + #ifndef OPENSSL_IS_BORINGSSL + #error not boringssl + #endif + ]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_BORINGSSL, 1, + [Define to 1 if using BoringSSL.]) + ssl_msg="BoringSSL" + ],[ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([for libressl]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include + ]],[[ + int dummy = LIBRESSL_VERSION_NUMBER; + ]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_LIBRESSL, 1, + [Define to 1 if using libressl.]) + ssl_msg="libressl" + ],[ + AC_MSG_RESULT([no]) + ]) + fi + + if test "$OPENSSL_ENABLED" = "1"; then + if test -n "$LIB_OPENSSL"; then + dnl when the ssl shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$LIB_OPENSSL" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $LIB_OPENSSL to CURL_LIBRARY_PATH]) + fi + fi + CURL_CHECK_OPENSSL_API + check_for_ca_bundle=1 + fi + + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +dnl ********************************************************************** +dnl Check for the random seed preferences +dnl ********************************************************************** + +if test X"$OPENSSL_ENABLED" = X"1"; then + AC_ARG_WITH(egd-socket, + AC_HELP_STRING([--with-egd-socket=FILE], + [Entropy Gathering Daemon socket pathname]), + [ EGD_SOCKET="$withval" ] + ) + if test -n "$EGD_SOCKET" ; then + AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET", + [your Entropy Gathering Daemon socket pathname] ) + fi + + dnl Check for user-specified random device + AC_ARG_WITH(random, + AC_HELP_STRING([--with-random=FILE], + [read randomness from FILE (default=/dev/urandom)]), + [ RANDOM_FILE="$withval" ], + [ + if test x$cross_compiling != xyes; then + dnl Check for random device + AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] ) + else + AC_MSG_WARN([skipped the /dev/urandom detection when cross-compiling]) + fi + ] + ) + if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then + AC_SUBST(RANDOM_FILE) + AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE", + [a suitable file to read random data from]) + fi +fi + +dnl --- +dnl We require OpenSSL with SRP support. +dnl --- +if test "$OPENSSL_ENABLED" = "1"; then + AC_CHECK_LIB(crypto, SRP_Calc_client_key, + [ + AC_DEFINE(HAVE_OPENSSL_SRP, 1, [if you have the function SRP_Calc_client_key]) + AC_SUBST(HAVE_OPENSSL_SRP, [1]) + ]) +fi + +dnl ---------------------------------------------------- +dnl check for GnuTLS +dnl ---------------------------------------------------- + +dnl Default to compiler & linker defaults for GnuTLS files & libraries. +OPT_GNUTLS=no + +AC_ARG_WITH(gnutls,dnl +AC_HELP_STRING([--with-gnutls=PATH],[where to look for GnuTLS, PATH points to the installation root]) +AC_HELP_STRING([--without-gnutls], [disable GnuTLS detection]), + OPT_GNUTLS=$withval) + +if test -z "$ssl_backends" -o "x$OPT_GNUTLS" != xno; then + ssl_msg= + + if test X"$OPT_GNUTLS" != Xno; then + + addld="" + addlib="" + gtlslib="" + version="" + addcflags="" + + if test "x$OPT_GNUTLS" = "xyes"; then + dnl this is with no partiular path given + CURL_CHECK_PKGCONFIG(gnutls) + + if test "$PKGCONFIG" != "no" ; then + addlib=`$PKGCONFIG --libs-only-l gnutls` + addld=`$PKGCONFIG --libs-only-L gnutls` + addcflags=`$PKGCONFIG --cflags-only-I gnutls` + version=`$PKGCONFIG --modversion gnutls` + gtlslib=`echo $addld | $SED -e 's/-L//'` + else + dnl without pkg-config, we try libgnutls-config as that was how it + dnl used to be done + check=`libgnutls-config --version 2>/dev/null` + if test -n "$check"; then + addlib=`libgnutls-config --libs` + addcflags=`libgnutls-config --cflags` + version=`libgnutls-config --version` + gtlslib=`libgnutls-config --prefix`/lib$libsuff + fi + fi + else + dnl this is with a given path, first check if there's a libgnutls-config + dnl there and if not, make an educated guess + cfg=$OPT_GNUTLS/bin/libgnutls-config + check=`$cfg --version 2>/dev/null` + if test -n "$check"; then + addlib=`$cfg --libs` + addcflags=`$cfg --cflags` + version=`$cfg --version` + gtlslib=`$cfg --prefix`/lib$libsuff + else + dnl without pkg-config and libgnutls-config, we guess a lot! + addlib=-lgnutls + addld=-L$OPT_GNUTLS/lib$libsuff + addcflags=-I$OPT_GNUTLS/include + version="" # we just don't know + gtlslib=$OPT_GNUTLS/lib$libsuff + fi + fi + + if test -z "$version"; then + dnl lots of efforts, still no go + version="unknown" + fi + + if test -n "$addlib"; then + + CLEANLIBS="$LIBS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLDFLAGS="$LDFLAGS" + + LIBS="$addlib $LIBS" + LDFLAGS="$LDFLAGS $addld" + if test "$addcflags" != "-I/usr/include"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + + AC_CHECK_LIB(gnutls, gnutls_check_version, + [ + AC_DEFINE(USE_GNUTLS, 1, [if GnuTLS is enabled]) + AC_SUBST(USE_GNUTLS, [1]) + GNUTLS_ENABLED=1 + USE_GNUTLS="yes" + ssl_msg="GnuTLS" + test gnutls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + LIBS="$CLEANLIBS" + CPPFLAGS="$CLEANCPPFLAGS" + ]) + + if test "x$USE_GNUTLS" = "xyes"; then + AC_MSG_NOTICE([detected GnuTLS version $version]) + check_for_ca_bundle=1 + if test -n "$gtlslib"; then + dnl when shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl CURL_LIBRARY_PATH to prevent further configure tests to fail + dnl due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$gtlslib" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $gtlslib to CURL_LIBRARY_PATH]) + fi + fi + AC_CHECK_FUNCS([gnutls_certificate_set_x509_key_file2 gnutls_alpn_set_protocols gnutls_ocsp_req_init]) + fi + + fi + + fi dnl GNUTLS not disabled + + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +dnl --- +dnl Check which crypto backend GnuTLS uses +dnl --- + +if test "$GNUTLS_ENABLED" = "1"; then + USE_GNUTLS_NETTLE= + # First check if we can detect either crypto library via transitive linking + AC_CHECK_LIB(gnutls, nettle_MD5Init, [ USE_GNUTLS_NETTLE=1 ]) + if test "$USE_GNUTLS_NETTLE" = ""; then + AC_CHECK_LIB(gnutls, gcry_control, [ USE_GNUTLS_NETTLE=0 ]) + fi + # If not, try linking directly to both of them to see if they are available + if test "$USE_GNUTLS_NETTLE" = ""; then + AC_CHECK_LIB(nettle, nettle_MD5Init, [ USE_GNUTLS_NETTLE=1 ]) + fi + if test "$USE_GNUTLS_NETTLE" = ""; then + AC_CHECK_LIB(gcrypt, gcry_control, [ USE_GNUTLS_NETTLE=0 ]) + fi + if test "$USE_GNUTLS_NETTLE" = ""; then + AC_MSG_ERROR([GnuTLS found, but neither gcrypt nor nettle found]) + fi + if test "$USE_GNUTLS_NETTLE" = "1"; then + AC_DEFINE(USE_GNUTLS_NETTLE, 1, [if GnuTLS uses nettle as crypto backend]) + AC_SUBST(USE_GNUTLS_NETTLE, [1]) + LIBS="-lnettle $LIBS" + else + LIBS="-lgcrypt $LIBS" + fi +fi + +dnl --- +dnl We require GnuTLS with SRP support. +dnl --- +if test "$GNUTLS_ENABLED" = "1"; then + AC_CHECK_LIB(gnutls, gnutls_srp_verifier, + [ + AC_DEFINE(HAVE_GNUTLS_SRP, 1, [if you have the function gnutls_srp_verifier]) + AC_SUBST(HAVE_GNUTLS_SRP, [1]) + ]) +fi + +dnl ---------------------------------------------------- +dnl check for PolarSSL +dnl ---------------------------------------------------- + +dnl Default to compiler & linker defaults for PolarSSL files & libraries. +OPT_POLARSSL=no + +_cppflags=$CPPFLAGS +_ldflags=$LDFLAGS +AC_ARG_WITH(polarssl,dnl +AC_HELP_STRING([--with-polarssl=PATH],[where to look for PolarSSL, PATH points to the installation root]) +AC_HELP_STRING([--without-polarssl], [disable PolarSSL detection]), + OPT_POLARSSL=$withval) + +if test -z "$ssl_backends" -o "x$OPT_POLARSSL" != xno; then + ssl_msg= + + if test X"$OPT_POLARSSL" != Xno; then + + if test "$OPT_POLARSSL" = "yes"; then + OPT_POLARSSL="" + fi + + if test -z "$OPT_POLARSSL" ; then + dnl check for lib first without setting any new path + + AC_CHECK_LIB(polarssl, havege_init, + dnl libpolarssl found, set the variable + [ + AC_DEFINE(USE_POLARSSL, 1, [if PolarSSL is enabled]) + AC_SUBST(USE_POLARSSL, [1]) + POLARSSL_ENABLED=1 + USE_POLARSSL="yes" + ssl_msg="PolarSSL" + test polarssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ]) + fi + + addld="" + addlib="" + addcflags="" + polarssllib="" + + if test "x$USE_POLARSSL" != "xyes"; then + dnl add the path and test again + addld=-L$OPT_POLARSSL/lib$libsuff + addcflags=-I$OPT_POLARSSL/include + polarssllib=$OPT_POLARSSL/lib$libsuff + + LDFLAGS="$LDFLAGS $addld" + if test "$addcflags" != "-I/usr/include"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + + AC_CHECK_LIB(polarssl, ssl_init, + [ + AC_DEFINE(USE_POLARSSL, 1, [if PolarSSL is enabled]) + AC_SUBST(USE_POLARSSL, [1]) + POLARSSL_ENABLED=1 + USE_POLARSSL="yes" + ssl_msg="PolarSSL" + test polarssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + ]) + fi + + if test "x$USE_POLARSSL" = "xyes"; then + AC_MSG_NOTICE([detected PolarSSL]) + check_for_ca_bundle=1 + LIBS="-lpolarssl $LIBS" + + if test -n "$polarssllib"; then + dnl when shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl CURL_LIBRARY_PATH to prevent further configure tests to fail + dnl due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$polarssllib" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $polarssllib to CURL_LIBRARY_PATH]) + fi + fi + fi + + fi dnl PolarSSL not disabled + + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +dnl ---------------------------------------------------- +dnl check for mbedTLS +dnl ---------------------------------------------------- + +OPT_MBEDTLS=no + +_cppflags=$CPPFLAGS +_ldflags=$LDFLAGS +AC_ARG_WITH(mbedtls,dnl +AC_HELP_STRING([--with-mbedtls=PATH],[where to look for mbedTLS, PATH points to the installation root]) +AC_HELP_STRING([--without-mbedtls], [disable mbedTLS detection]), + OPT_MBEDTLS=$withval) + +if test -z "$ssl_backends" -o "x$OPT_MBEDTLS" != xno; then + ssl_msg= + + if test X"$OPT_MBEDTLS" != Xno; then + + if test "$OPT_MBEDTLS" = "yes"; then + OPT_MBEDTLS="" + fi + + if test -z "$OPT_MBEDTLS" ; then + dnl check for lib first without setting any new path + + AC_CHECK_LIB(mbedtls, mbedtls_havege_init, + dnl libmbedtls found, set the variable + [ + AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled]) + AC_SUBST(USE_MBEDTLS, [1]) + MBEDTLS_ENABLED=1 + USE_MBEDTLS="yes" + ssl_msg="mbedTLS" + test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], [], -lmbedx509 -lmbedcrypto) + fi + + addld="" + addlib="" + addcflags="" + mbedtlslib="" + + if test "x$USE_MBEDTLS" != "xyes"; then + dnl add the path and test again + addld=-L$OPT_MBEDTLS/lib$libsuff + addcflags=-I$OPT_MBEDTLS/include + mbedtlslib=$OPT_MBEDTLS/lib$libsuff + + LDFLAGS="$LDFLAGS $addld" + if test "$addcflags" != "-I/usr/include"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + + AC_CHECK_LIB(mbedtls, mbedtls_ssl_init, + [ + AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled]) + AC_SUBST(USE_MBEDTLS, [1]) + MBEDTLS_ENABLED=1 + USE_MBEDTLS="yes" + ssl_msg="mbedTLS" + test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + ], -lmbedx509 -lmbedcrypto) + fi + + if test "x$USE_MBEDTLS" = "xyes"; then + AC_MSG_NOTICE([detected mbedTLS]) + check_for_ca_bundle=1 + + LIBS="-lmbedtls -lmbedx509 -lmbedcrypto $LIBS" + + if test -n "$mbedtlslib"; then + dnl when shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl CURL_LIBRARY_PATH to prevent further configure tests to fail + dnl due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$mbedtlslib" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $mbedtlslib to CURL_LIBRARY_PATH]) + fi + fi + fi + + fi dnl mbedTLS not disabled + + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +dnl ---------------------------------------------------- +dnl check for CyaSSL +dnl ---------------------------------------------------- + +dnl Default to compiler & linker defaults for CyaSSL files & libraries. +OPT_CYASSL=no + +_cppflags=$CPPFLAGS +_ldflags=$LDFLAGS +AC_ARG_WITH(cyassl,dnl +AC_HELP_STRING([--with-cyassl=PATH],[where to look for CyaSSL, PATH points to the installation root (default: system lib default)]) +AC_HELP_STRING([--without-cyassl], [disable CyaSSL detection]), + OPT_CYASSL=$withval) + +dnl provide --with-wolfssl as an alias for --with-cyassl +AC_ARG_WITH(wolfssl,dnl +AC_HELP_STRING([--with-wolfssl=PATH],[where to look for WolfSSL, PATH points to the installation root (default: system lib default)]) +AC_HELP_STRING([--without-wolfssl], [disable WolfSSL detection]), + OPT_CYASSL=$withval) + +if test -z "$ssl_backends" -o "x$OPT_CYASSL" != xno; then + ssl_msg= + + if test X"$OPT_CYASSL" != Xno; then + + if test "$OPT_CYASSL" = "yes"; then + OPT_CYASSL="" + fi + + dnl This should be reworked to use pkg-config instead + + cyassllibname=cyassl + + if test -z "$OPT_CYASSL" ; then + dnl check for lib in system default first + + AC_CHECK_LIB(cyassl, CyaSSL_Init, + dnl libcyassl found, set the variable + [ + AC_DEFINE(USE_CYASSL, 1, [if CyaSSL is enabled]) + AC_SUBST(USE_CYASSL, [1]) + CYASSL_ENABLED=1 + USE_CYASSL="yes" + ssl_msg="CyaSSL" + test cyassl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ]) + fi + + addld="" + addlib="" + addcflags="" + cyassllib="" + + if test "x$USE_CYASSL" != "xyes"; then + dnl add the path and test again + addld=-L$OPT_CYASSL/lib$libsuff + addcflags=-I$OPT_CYASSL/include + cyassllib=$OPT_CYASSL/lib$libsuff + + LDFLAGS="$LDFLAGS $addld" + if test "$addcflags" != "-I/usr/include"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + + AC_CHECK_LIB(cyassl, CyaSSL_Init, + [ + AC_DEFINE(USE_CYASSL, 1, [if CyaSSL is enabled]) + AC_SUBST(USE_CYASSL, [1]) + CYASSL_ENABLED=1 + USE_CYASSL="yes" + ssl_msg="CyaSSL" + test cyassl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + cyassllib="" + ]) + fi + + addld="" + addlib="" + addcflags="" + + if test "x$USE_CYASSL" != "xyes"; then + dnl libcyassl renamed to libwolfssl as of 3.4.0 + addld=-L$OPT_CYASSL/lib$libsuff + addcflags=-I$OPT_CYASSL/include + cyassllib=$OPT_CYASSL/lib$libsuff + + LDFLAGS="$LDFLAGS $addld" + if test "$addcflags" != "-I/usr/include"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + + cyassllibname=wolfssl + my_ac_save_LIBS="$LIBS" + LIBS="-l$cyassllibname -lm $LIBS" + + AC_MSG_CHECKING([for CyaSSL_Init in -lwolfssl]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +/* These aren't needed for detection and confuse WolfSSL. + They are set up properly later if it is detected. */ +#undef SIZEOF_LONG +#undef SIZEOF_LONG_LONG +#include + ]],[[ + return CyaSSL_Init(); + ]]) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(USE_CYASSL, 1, [if CyaSSL/WolfSSL is enabled]) + AC_SUBST(USE_CYASSL, [1]) + CYASSL_ENABLED=1 + USE_CYASSL="yes" + ssl_msg="WolfSSL" + test cyassl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + AC_MSG_RESULT(no) + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + cyassllib="" + ]) + LIBS="$my_ac_save_LIBS" + fi + + if test "x$USE_CYASSL" = "xyes"; then + AC_MSG_NOTICE([detected $cyassllibname]) + check_for_ca_bundle=1 + + dnl cyassl/ctaocrypt/types.h needs SIZEOF_LONG_LONG defined! + AX_COMPILE_CHECK_SIZEOF(long long) + + dnl Versions since at least 2.6.0 may have options.h + AC_CHECK_HEADERS(cyassl/options.h) + + dnl Versions since at least 2.9.4 renamed error.h to error-ssl.h + AC_CHECK_HEADERS(cyassl/error-ssl.h) + + LIBS="-l$cyassllibname -lm $LIBS" + + if test "x$cyassllibname" = "xwolfssl"; then + dnl Recent WolfSSL versions build without SSLv3 by default + dnl WolfSSL needs configure --enable-opensslextra to have *get_peer* + AC_CHECK_FUNCS(wolfSSLv3_client_method \ + wolfSSL_CTX_UseSupportedCurve \ + wolfSSL_get_peer_certificate \ + wolfSSL_UseALPN) + else + dnl Cyassl needs configure --enable-opensslextra to have *get_peer* + AC_CHECK_FUNCS(CyaSSL_CTX_UseSupportedCurve \ + CyaSSL_get_peer_certificate) + fi + + if test -n "$cyassllib"; then + dnl when shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl CURL_LIBRARY_PATH to prevent further configure tests to fail + dnl due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$cyassllib" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $cyassllib to CURL_LIBRARY_PATH]) + fi + fi + + fi + + fi dnl CyaSSL not disabled + + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +dnl ---------------------------------------------------- +dnl NSS. Only check if GnuTLS and OpenSSL are not enabled +dnl ---------------------------------------------------- + +dnl Default to compiler & linker defaults for NSS files & libraries. +OPT_NSS=no + +AC_ARG_WITH(nss,dnl +AC_HELP_STRING([--with-nss=PATH],[where to look for NSS, PATH points to the installation root]) +AC_HELP_STRING([--without-nss], [disable NSS detection]), + OPT_NSS=$withval) + +if test -z "$ssl_backends" -o "x$OPT_NSS" != xno; then + ssl_msg= + + if test X"$OPT_NSS" != Xno; then + + addld="" + addlib="" + addcflags="" + nssprefix="" + version="" + + if test "x$OPT_NSS" = "xyes"; then + + CURL_CHECK_PKGCONFIG(nss) + + if test "$PKGCONFIG" != "no" ; then + addlib=`$PKGCONFIG --libs nss` + addcflags=`$PKGCONFIG --cflags nss` + version=`$PKGCONFIG --modversion nss` + nssprefix=`$PKGCONFIG --variable=prefix nss` + else + dnl Without pkg-config, we check for nss-config + + check=`nss-config --version 2>/dev/null` + if test -n "$check"; then + addlib=`nss-config --libs` + addcflags=`nss-config --cflags` + version=`nss-config --version` + nssprefix=`nss-config --prefix` + else + addlib="-lnss3" + addcflags="" + version="unknown" + fi + fi + else + NSS_PCDIR="$OPT_NSS/lib/pkgconfig" + if test -f "$NSS_PCDIR/nss.pc"; then + CURL_CHECK_PKGCONFIG(nss, [$NSS_PCDIR]) + if test "$PKGCONFIG" != "no" ; then + addld=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --libs-only-L nss` + addlib=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --libs-only-l nss` + addcflags=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --cflags nss` + version=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --modversion nss` + nssprefix=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --variable=prefix nss` + fi + fi + fi + + if test -z "$addlib"; then + # Without pkg-config, we'll kludge in some defaults + AC_MSG_WARN([Using hard-wired libraries and compilation flags for NSS.]) + addld="-L$OPT_NSS/lib" + addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4" + addcflags="-I$OPT_NSS/include" + version="unknown" + nssprefix=$OPT_NSS + fi + + CLEANLDFLAGS="$LDFLAGS" + CLEANLIBS="$LIBS" + CLEANCPPFLAGS="$CPPFLAGS" + + LDFLAGS="$addld $LDFLAGS" + LIBS="$addlib $LIBS" + if test "$addcflags" != "-I/usr/include"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + + dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0 + AC_CHECK_LIB(nss3, SSL_VersionRangeSet, + [ + AC_DEFINE(USE_NSS, 1, [if NSS is enabled]) + AC_SUBST(USE_NSS, [1]) + USE_NSS="yes" + NSS_ENABLED=1 + ssl_msg="NSS" + test nss != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + LDFLAGS="$CLEANLDFLAGS" + LIBS="$CLEANLIBS" + CPPFLAGS="$CLEANCPPFLAGS" + ]) + + if test "x$USE_NSS" = "xyes"; then + AC_MSG_NOTICE([detected NSS version $version]) + + dnl PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because + dnl PK11_DestroyGenericObject() does not release resources allocated by + dnl PK11_CreateGenericObject() early enough. + AC_CHECK_FUNC(PK11_CreateManagedGenericObject, + [ + AC_DEFINE(HAVE_PK11_CREATEMANAGEDGENERICOBJECT, 1, + [if you have the PK11_CreateManagedGenericObject function]) + ]) + + dnl needed when linking the curl tool without USE_EXPLICIT_LIB_DEPS + NSS_LIBS=$addlib + AC_SUBST([NSS_LIBS]) + + dnl when shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl CURL_LIBRARY_PATH to prevent further configure tests to fail + dnl due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$nssprefix/lib$libsuff" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $nssprefix/lib$libsuff to CURL_LIBRARY_PATH]) + fi + + fi dnl NSS found + + fi dnl NSS not disabled + + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +OPT_AXTLS=off + +AC_ARG_WITH(axtls,dnl +AC_HELP_STRING([--with-axtls=PATH],[Where to look for axTLS, PATH points to the axTLS installation prefix (default: /usr/local). Ignored if another SSL engine is selected.]) +AC_HELP_STRING([--without-axtls], [disable axTLS]), + OPT_AXTLS=$withval) + +if test -z "$ssl_backends" -o "x$OPT_AXTLS" != xno; then + ssl_msg= + if test X"$OPT_AXTLS" != Xno; then + dnl backup the pre-axtls variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + case "$OPT_AXTLS" in + yes) + dnl --with-axtls (without path) used + PREFIX_AXTLS=/usr/local + LIB_AXTLS="$PREFIX_AXTLS/lib" + LDFLAGS="$LDFLAGS -L$LIB_AXTLS" + CPPFLAGS="$CPPFLAGS -I$PREFIX_AXTLS/include" + ;; + off) + dnl no --with-axtls option given, just check default places + PREFIX_AXTLS= + ;; + *) + dnl check the given --with-axtls spot + PREFIX_AXTLS=$OPT_AXTLS + LIB_AXTLS="$PREFIX_AXTLS/lib" + LDFLAGS="$LDFLAGS -L$LIB_AXTLS" + CPPFLAGS="$CPPFLAGS -I$PREFIX_AXTLS/include" + ;; + esac + + AC_CHECK_LIB(axtls, ssl_version,[ + LIBS="-laxtls $LIBS" + AC_DEFINE(USE_AXTLS, 1, [if axTLS is enabled]) + AC_SUBST(USE_AXTLS, [1]) + AXTLS_ENABLED=1 + check_for_ca_bundle=1 + USE_AXTLS="yes" + ssl_msg="axTLS" + test axtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$LIB_AXTLS" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $LIB_AXTLS to CURL_LIBRARY_PATH]) + fi + ],[ + LDFLAGS="$CLEANLDFLAGS" + CPPFLAGS="$CLEANCPPFLAGS" + LIBS="$CLEANLIBS" + ]) + fi + test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg" +fi + +case "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$POLARSSL_ENABLED$MBEDTLS_ENABLED$AXTLS_ENABLED$CYASSL_ENABLED$WINSSL_ENABLED$DARWINSSL_ENABLED" in +x) + AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.]) + AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-polarssl, --with-cyassl, --with-nss, --with-axtls, --with-winssl, or --with-darwinssl to address this.]) + ;; +x1) + # one SSL backend is enabled + AC_SUBST(SSL_ENABLED) + SSL_ENABLED="1" + AC_MSG_NOTICE([built with one SSL backend]) + ;; +*) + # more than one SSL backend is enabled + AC_SUBST(SSL_ENABLED) + SSL_ENABLED="1" + AC_SUBST(CURL_WITH_MULTI_SSL) + CURL_WITH_MULTI_SSL="1" + AC_DEFINE(CURL_WITH_MULTI_SSL, 1, [built with multiple SSL backends]) + AC_MSG_NOTICE([built with multiple SSL backends]) + ;; +esac + +if test -n "$ssl_backends"; then + curl_ssl_msg="enabled ($ssl_backends)" +fi + +if test no = "$VALID_DEFAULT_SSL_BACKEND" +then + if test -n "$SSL_ENABLED" + then + AC_MSG_ERROR([Default SSL backend $DEFAULT_SSL_BACKEND not enabled!]) + else + AC_MSG_ERROR([Default SSL backend requires SSL!]) + fi +elif test yes = "$VALID_DEFAULT_SSL_BACKEND" +then + AC_DEFINE_UNQUOTED([CURL_DEFAULT_SSL_BACKEND], ["$DEFAULT_SSL_BACKEND"], [Default SSL backend]) +fi + +dnl ********************************************************************** +dnl Check for the CA bundle +dnl ********************************************************************** + +if test "$check_for_ca_bundle" -gt 0; then + CURL_CHECK_CA_BUNDLE +fi + +dnl ********************************************************************** +dnl Check for libpsl +dnl ********************************************************************** + +AC_ARG_WITH(libpsl, + AS_HELP_STRING([--without-libpsl], + [disable support for libpsl cookie checking]), + with_libpsl=$withval, + with_libpsl=yes) +if test $with_libpsl != "no"; then + AC_SEARCH_LIBS(psl_builtin, psl, + [curl_psl_msg="yes"; + AC_DEFINE([USE_LIBPSL], [1], [PSL support enabled]) + ], + [curl_psl_msg="no (libpsl not found)"; + AC_MSG_WARN([libpsl was not found]) + ] + ) +fi +AM_CONDITIONAL([USE_LIBPSL], [test "$curl_psl_msg" = "yes"]) + +dnl ********************************************************************** +dnl Check for libmetalink +dnl ********************************************************************** + +OPT_LIBMETALINK=no + +AC_ARG_WITH(libmetalink,dnl +AC_HELP_STRING([--with-libmetalink=PATH],[where to look for libmetalink, PATH points to the installation root]) +AC_HELP_STRING([--without-libmetalink], [disable libmetalink detection]), + OPT_LIBMETALINK=$withval) + +if test X"$OPT_LIBMETALINK" != Xno; then + + addld="" + addlib="" + addcflags="" + version="" + libmetalinklib="" + + PKGTEST="no" + if test "x$OPT_LIBMETALINK" = "xyes"; then + dnl this is with no partiular path given + PKGTEST="yes" + CURL_CHECK_PKGCONFIG(libmetalink) + else + dnl When particular path is given, set PKG_CONFIG_LIBDIR using the path. + LIBMETALINK_PCDIR="$OPT_LIBMETALINK/lib/pkgconfig" + AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$LIBMETALINK_PCDIR"]) + if test -f "$LIBMETALINK_PCDIR/libmetalink.pc"; then + PKGTEST="yes" + fi + if test "$PKGTEST" = "yes"; then + CURL_CHECK_PKGCONFIG(libmetalink, [$LIBMETALINK_PCDIR]) + fi + fi + if test "$PKGTEST" = "yes" && test "$PKGCONFIG" != "no"; then + addlib=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl + $PKGCONFIG --libs-only-l libmetalink` + addld=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl + $PKGCONFIG --libs-only-L libmetalink` + addcflags=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl + $PKGCONFIG --cflags-only-I libmetalink` + version=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl + $PKGCONFIG --modversion libmetalink` + libmetalinklib=`echo $addld | $SED -e 's/-L//'` + fi + if test -n "$addlib"; then + + clean_CPPFLAGS="$CPPFLAGS" + clean_LDFLAGS="$LDFLAGS" + clean_LIBS="$LIBS" + CPPFLAGS="$clean_CPPFLAGS $addcflags" + LDFLAGS="$clean_LDFLAGS $addld" + LIBS="$addlib $clean_LIBS" + AC_MSG_CHECKING([if libmetalink is recent enough]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +# include + ]],[[ + if(0 != metalink_strerror(0)) /* added in 0.1.0 */ + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes ($version)]) + want_metalink="yes" + ],[ + AC_MSG_RESULT([no ($version)]) + AC_MSG_NOTICE([libmetalink library defective or too old]) + want_metalink="no" + ]) + CPPFLAGS="$clean_CPPFLAGS" + LDFLAGS="$clean_LDFLAGS" + LIBS="$clean_LIBS" + if test "$want_metalink" = "yes"; then + dnl finally libmetalink will be used + AC_DEFINE(USE_METALINK, 1, [Define to enable metalink support]) + LIBMETALINK_LIBS=$addlib + LIBMETALINK_LDFLAGS=$addld + LIBMETALINK_CPPFLAGS=$addcflags + AC_SUBST([LIBMETALINK_LIBS]) + AC_SUBST([LIBMETALINK_LDFLAGS]) + AC_SUBST([LIBMETALINK_CPPFLAGS]) + curl_mtlnk_msg="enabled" + fi + + fi +fi + +dnl ********************************************************************** +dnl Check for the presence of LIBSSH2 libraries and headers +dnl ********************************************************************** + +dnl Default to compiler & linker defaults for LIBSSH2 files & libraries. +OPT_LIBSSH2=off +AC_ARG_WITH(libssh2,dnl +AC_HELP_STRING([--with-libssh2=PATH],[Where to look for libssh2, PATH points to the LIBSSH2 installation; when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]) +AC_HELP_STRING([--with-libssh2], [enable LIBSSH2]), + OPT_LIBSSH2=$withval, OPT_LIBSSH2=no) + + +OPT_LIBSSH=off +AC_ARG_WITH(libssh,dnl +AC_HELP_STRING([--with-libssh=PATH],[Where to look for libssh, PATH points to the LIBSSH installation; when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]) +AC_HELP_STRING([--with-libssh], [enable LIBSSH]), + OPT_LIBSSH=$withval, OPT_LIBSSH=no) + +if test X"$OPT_LIBSSH2" != Xno; then + dnl backup the pre-libssh2 variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + case "$OPT_LIBSSH2" in + yes) + dnl --with-libssh2 (without path) used + CURL_CHECK_PKGCONFIG(libssh2) + + if test "$PKGCONFIG" != "no" ; then + LIB_SSH2=`$PKGCONFIG --libs libssh2` + LD_SSH2=`$PKGCONFIG --libs-only-L libssh2` + CPP_SSH2=`$PKGCONFIG --cflags-only-I libssh2` + version=`$PKGCONFIG --modversion libssh2` + DIR_SSH2=`echo $LD_SSH2 | $SED -e 's/-L//'` + fi + + ;; + off) + dnl no --with-libssh2 option given, just check default places + ;; + *) + dnl use the given --with-libssh2 spot + PREFIX_SSH2=$OPT_LIBSSH2 + ;; + esac + + dnl if given with a prefix, we set -L and -I based on that + if test -n "$PREFIX_SSH2"; then + LIB_SSH2="-lssh2" + LD_SSH2=-L${PREFIX_SSH2}/lib$libsuff + CPP_SSH2=-I${PREFIX_SSH2}/include + DIR_SSH2=${PREFIX_SSH2}/lib$libsuff + fi + + LDFLAGS="$LDFLAGS $LD_SSH2" + CPPFLAGS="$CPPFLAGS $CPP_SSH2" + LIBS="$LIB_SSH2 $LIBS" + + AC_CHECK_LIB(ssh2, libssh2_channel_open_ex) + + AC_CHECK_HEADERS(libssh2.h, + curl_ssh_msg="enabled (libSSH2)" + LIBSSH2_ENABLED=1 + AC_DEFINE(USE_LIBSSH2, 1, [if libSSH2 is in use]) + AC_SUBST(USE_LIBSSH2, [1]) + ) + + if test X"$OPT_LIBSSH2" != Xoff && + test "$LIBSSH2_ENABLED" != "1"; then + AC_MSG_ERROR([libSSH2 libs and/or directories were not found where specified!]) + fi + + if test "$LIBSSH2_ENABLED" = "1"; then + if test -n "$DIR_SSH2"; then + dnl when the libssh2 shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH2" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_SSH2 to CURL_LIBRARY_PATH]) + fi + fi + else + dnl no libssh2, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + fi +elif test X"$OPT_LIBSSH" != Xno; then + dnl backup the pre-libssh variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + case "$OPT_LIBSSH" in + yes) + dnl --with-libssh (without path) used + CURL_CHECK_PKGCONFIG(libssh) + + if test "$PKGCONFIG" != "no" ; then + LIB_SSH=`$PKGCONFIG --libs-only-l libssh` + LD_SSH=`$PKGCONFIG --libs-only-L libssh` + CPP_SSH=`$PKGCONFIG --cflags-only-I libssh` + version=`$PKGCONFIG --modversion libssh` + DIR_SSH=`echo $LD_SSH | $SED -e 's/-L//'` + fi + + ;; + off) + dnl no --with-libssh option given, just check default places + ;; + *) + dnl use the given --with-libssh spot + PREFIX_SSH=$OPT_LIBSSH + ;; + esac + + dnl if given with a prefix, we set -L and -I based on that + if test -n "$PREFIX_SSH"; then + LIB_SSH="-lssh" + LD_SSH=-L${PREFIX_SSH}/lib$libsuff + CPP_SSH=-I${PREFIX_SSH}/include + DIR_SSH=${PREFIX_SSH}/lib$libsuff + fi + + LDFLAGS="$LDFLAGS $LD_SSH" + CPPFLAGS="$CPPFLAGS $CPP_SSH" + LIBS="$LIB_SSH $LIBS" + + AC_CHECK_LIB(ssh, ssh_new) + + AC_CHECK_HEADERS(libssh/libssh.h, + curl_ssh_msg="enabled (libSSH)" + LIBSSH_ENABLED=1 + AC_DEFINE(USE_LIBSSH, 1, [if libSSH is in use]) + AC_SUBST(USE_LIBSSH, [1]) + ) + + if test X"$OPT_LIBSSH" != Xoff && + test "$LIBSSH_ENABLED" != "1"; then + AC_MSG_ERROR([libSSH libs and/or directories were not found where specified!]) + fi + + if test "$LIBSSH_ENABLED" = "1"; then + if test -n "$DIR_SSH"; then + dnl when the libssh shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_SSH to CURL_LIBRARY_PATH]) + fi + fi + else + dnl no libssh, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + fi +fi + +dnl ********************************************************************** +dnl Check for the presence of LIBRTMP libraries and headers +dnl ********************************************************************** + +dnl Default to compiler & linker defaults for LIBRTMP files & libraries. +OPT_LIBRTMP=off +AC_ARG_WITH(librtmp,dnl +AC_HELP_STRING([--with-librtmp=PATH],[Where to look for librtmp, PATH points to the LIBRTMP installation; when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]) +AC_HELP_STRING([--without-librtmp], [disable LIBRTMP]), + OPT_LIBRTMP=$withval) + +if test X"$OPT_LIBRTMP" != Xno; then + dnl backup the pre-librtmp variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + case "$OPT_LIBRTMP" in + yes) + dnl --with-librtmp (without path) used + CURL_CHECK_PKGCONFIG(librtmp) + + if test "$PKGCONFIG" != "no" ; then + LIB_RTMP=`$PKGCONFIG --libs-only-l librtmp` + LD_RTMP=`$PKGCONFIG --libs-only-L librtmp` + CPP_RTMP=`$PKGCONFIG --cflags-only-I librtmp` + version=`$PKGCONFIG --modversion librtmp` + DIR_RTMP=`echo $LD_RTMP | $SED -e 's/-L//'` + else + dnl To avoid link errors, we do not allow --librtmp without + dnl a pkgconfig file + AC_MSG_ERROR([--librtmp was specified but could not find librtmp pkgconfig file.]) + fi + + ;; + off) + dnl no --with-librtmp option given, just check default places + LIB_RTMP="-lrtmp" + ;; + *) + dnl use the given --with-librtmp spot + LIB_RTMP="-lrtmp" + PREFIX_RTMP=$OPT_LIBRTMP + ;; + esac + + dnl if given with a prefix, we set -L and -I based on that + if test -n "$PREFIX_RTMP"; then + LD_RTMP=-L${PREFIX_RTMP}/lib$libsuff + CPP_RTMP=-I${PREFIX_RTMP}/include + DIR_RTMP=${PREFIX_RTMP}/lib$libsuff + fi + + LDFLAGS="$LDFLAGS $LD_RTMP" + CPPFLAGS="$CPPFLAGS $CPP_RTMP" + LIBS="$LIB_RTMP $LIBS" + + AC_CHECK_LIB(rtmp, RTMP_Init, + [ + AC_CHECK_HEADERS(librtmp/rtmp.h, + curl_rtmp_msg="enabled (librtmp)" + LIBRTMP_ENABLED=1 + AC_DEFINE(USE_LIBRTMP, 1, [if librtmp is in use]) + AC_SUBST(USE_LIBRTMP, [1]) + ) + ], + dnl not found, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + ) + + if test X"$OPT_LIBRTMP" != Xoff && + test "$LIBRTMP_ENABLED" != "1"; then + AC_MSG_ERROR([librtmp libs and/or directories were not found where specified!]) + fi + +fi + +dnl ********************************************************************** +dnl Check for linker switch for versioned symbols +dnl ********************************************************************** + +versioned_symbols_flavour= +AC_MSG_CHECKING([whether versioned symbols are wanted]) +AC_ARG_ENABLE(versioned-symbols, +AC_HELP_STRING([--enable-versioned-symbols], [Enable versioned symbols in shared library]) +AC_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shared library]), +[ case "$enableval" in + yes) AC_MSG_RESULT(yes) + AC_MSG_CHECKING([if libraries can be versioned]) + GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script` + if test -z "$GLD"; then + AC_MSG_RESULT(no) + AC_MSG_WARN([You need an ld version supporting the --version-script option]) + else + AC_MSG_RESULT(yes) + if test "x$CURL_WITH_MULTI_SSL" = "x1"; then + versioned_symbols_flavour="MULTISSL_" + elif test "x$OPENSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="OPENSSL_" + elif test "x$GNUTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="GNUTLS_" + elif test "x$NSS_ENABLED" = "x1"; then + versioned_symbols_flavour="NSS_" + elif test "x$POLARSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="POLARSSL_" + elif test "x$CYASSL_ENABLED" = "x1"; then + versioned_symbols_flavour="CYASSL_" + elif test "x$AXTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="AXTLS_" + elif test "x$WINSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="WINSSL_" + elif test "x$DARWINSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="DARWINSSL_" + else + versioned_symbols_flavour="" + fi + versioned_symbols="yes" + fi + ;; + + *) AC_MSG_RESULT(no) + ;; + esac +], [ +AC_MSG_RESULT(no) +] +) + +AC_SUBST([CURL_LT_SHLIB_VERSIONED_FLAVOUR], + ["$versioned_symbols_flavour"]) +AM_CONDITIONAL([CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS], + [test "x$versioned_symbols" = 'xyes']) + +dnl ------------------------------------------------- +dnl check winidn option before other IDN libraries +dnl ------------------------------------------------- + +AC_MSG_CHECKING([whether to enable Windows native IDN (Windows native builds only)]) +OPT_WINIDN="default" +AC_ARG_WITH(winidn, +AC_HELP_STRING([--with-winidn=PATH],[enable Windows native IDN]) +AC_HELP_STRING([--without-winidn], [disable Windows native IDN]), + OPT_WINIDN=$withval) +case "$OPT_WINIDN" in + no|default) + dnl --without-winidn option used or configure option not specified + want_winidn="no" + AC_MSG_RESULT([no]) + ;; + yes) + dnl --with-winidn option used without path + want_winidn="yes" + want_winidn_path="default" + AC_MSG_RESULT([yes]) + ;; + *) + dnl --with-winidn option used with path + want_winidn="yes" + want_winidn_path="$withval" + AC_MSG_RESULT([yes ($withval)]) + ;; +esac + +if test "$want_winidn" = "yes"; then + dnl winidn library support has been requested + clean_CPPFLAGS="$CPPFLAGS" + clean_LDFLAGS="$LDFLAGS" + clean_LIBS="$LIBS" + WINIDN_LIBS="-lnormaliz" + WINIDN_CPPFLAGS="-DWINVER=0x0600" + # + if test "$want_winidn_path" != "default"; then + dnl path has been specified + dnl pkg-config not available or provides no info + WINIDN_LDFLAGS="-L$want_winidn_path/lib$libsuff" + WINIDN_CPPFLAGS="-I$want_winidn_path/include" + WINIDN_DIR="$want_winidn_path/lib$libsuff" + fi + # + CPPFLAGS="$CPPFLAGS $WINIDN_CPPFLAGS" + LDFLAGS="$LDFLAGS $WINIDN_LDFLAGS" + LIBS="$WINIDN_LIBS $LIBS" + # + AC_MSG_CHECKING([if IdnToUnicode can be linked]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #include + ]],[[ + IdnToUnicode(0, NULL, 0, NULL, 0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_winidn="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_winidn="no" + ]) + # + if test "$tst_links_winidn" = "yes"; then + AC_DEFINE(USE_WIN32_IDN, 1, [Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz).]) + AC_DEFINE(WANT_IDN_PROTOTYPES, 1, [Define to 1 to provide own prototypes.]) + AC_SUBST([IDN_ENABLED], [1]) + curl_idn_msg="enabled (Windows-native)" + else + AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) + CPPFLAGS="$clean_CPPFLAGS" + LDFLAGS="$clean_LDFLAGS" + LIBS="$clean_LIBS" + fi +fi + +dnl ********************************************************************** +dnl Check for the presence of IDN libraries and headers +dnl ********************************************************************** + +AC_MSG_CHECKING([whether to build with libidn2]) +OPT_IDN="default" +AC_ARG_WITH(libidn2, +AC_HELP_STRING([--with-libidn2=PATH],[Enable libidn2 usage]) +AC_HELP_STRING([--without-libidn2],[Disable libidn2 usage]), + [OPT_IDN=$withval]) +case "$OPT_IDN" in + no) + dnl --without-libidn2 option used + want_idn="no" + AC_MSG_RESULT([no]) + ;; + default) + dnl configure option not specified + want_idn="yes" + want_idn_path="default" + AC_MSG_RESULT([(assumed) yes]) + ;; + yes) + dnl --with-libidn2 option used without path + want_idn="yes" + want_idn_path="default" + AC_MSG_RESULT([yes]) + ;; + *) + dnl --with-libidn2 option used with path + want_idn="yes" + want_idn_path="$withval" + AC_MSG_RESULT([yes ($withval)]) + ;; +esac + +if test "$want_idn" = "yes"; then + dnl idn library support has been requested + clean_CPPFLAGS="$CPPFLAGS" + clean_LDFLAGS="$LDFLAGS" + clean_LIBS="$LIBS" + PKGCONFIG="no" + # + if test "$want_idn_path" != "default"; then + dnl path has been specified + IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig" + CURL_CHECK_PKGCONFIG(libidn2, [$IDN_PCDIR]) + if test "$PKGCONFIG" != "no"; then + IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl + $PKGCONFIG --libs-only-l libidn2 2>/dev/null` + IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl + $PKGCONFIG --libs-only-L libidn2 2>/dev/null` + IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl + $PKGCONFIG --cflags-only-I libidn2 2>/dev/null` + IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'` + else + dnl pkg-config not available or provides no info + IDN_LIBS="-lidn2" + IDN_LDFLAGS="-L$want_idn_path/lib$libsuff" + IDN_CPPFLAGS="-I$want_idn_path/include" + IDN_DIR="$want_idn_path/lib$libsuff" + fi + else + dnl path not specified + CURL_CHECK_PKGCONFIG(libidn2) + if test "$PKGCONFIG" != "no"; then + IDN_LIBS=`$PKGCONFIG --libs-only-l libidn2 2>/dev/null` + IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn2 2>/dev/null` + IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn2 2>/dev/null` + IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'` + else + dnl pkg-config not available or provides no info + IDN_LIBS="-lidn2" + fi + fi + # + if test "$PKGCONFIG" != "no"; then + AC_MSG_NOTICE([pkg-config: IDN_LIBS: "$IDN_LIBS"]) + AC_MSG_NOTICE([pkg-config: IDN_LDFLAGS: "$IDN_LDFLAGS"]) + AC_MSG_NOTICE([pkg-config: IDN_CPPFLAGS: "$IDN_CPPFLAGS"]) + AC_MSG_NOTICE([pkg-config: IDN_DIR: "$IDN_DIR"]) + else + AC_MSG_NOTICE([IDN_LIBS: "$IDN_LIBS"]) + AC_MSG_NOTICE([IDN_LDFLAGS: "$IDN_LDFLAGS"]) + AC_MSG_NOTICE([IDN_CPPFLAGS: "$IDN_CPPFLAGS"]) + AC_MSG_NOTICE([IDN_DIR: "$IDN_DIR"]) + fi + # + CPPFLAGS="$CPPFLAGS $IDN_CPPFLAGS" + LDFLAGS="$LDFLAGS $IDN_LDFLAGS" + LIBS="$IDN_LIBS $LIBS" + # + AC_MSG_CHECKING([if idn2_lookup_ul can be linked]) + AC_LINK_IFELSE([ + AC_LANG_FUNC_LINK_TRY([idn2_lookup_ul]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_libidn="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_libidn="no" + ]) + # + AC_CHECK_HEADERS( idn2.h ) + + if test "$tst_links_libidn" = "yes"; then + AC_DEFINE(HAVE_LIBIDN2, 1, [Define to 1 if you have the `idn2' library (-lidn2).]) + dnl different versions of libidn have different setups of these: + + AC_SUBST([IDN_ENABLED], [1]) + curl_idn_msg="enabled (libidn2)" + if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$IDN_DIR" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $IDN_DIR to CURL_LIBRARY_PATH]) + fi + else + AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) + CPPFLAGS="$clean_CPPFLAGS" + LDFLAGS="$clean_LDFLAGS" + LIBS="$clean_LIBS" + fi +fi + + +dnl Let's hope this split URL remains working: +dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \ +dnl genprogc/thread_quick_ref.htm + + +dnl ********************************************************************** +dnl Check for nghttp2 +dnl ********************************************************************** + +OPT_H2="yes" + +if test "x$disable_http" = "xyes"; then + # without HTTP, nghttp2 is no use + OPT_H2="no" +fi + +AC_ARG_WITH(nghttp2, +AC_HELP_STRING([--with-nghttp2=PATH],[Enable nghttp2 usage]) +AC_HELP_STRING([--without-nghttp2],[Disable nghttp2 usage]), + [OPT_H2=$withval]) +case "$OPT_H2" in + no) + dnl --without-nghttp2 option used + want_h2="no" + ;; + yes) + dnl --with-nghttp2 option used without path + want_h2="default" + want_h2_path="" + ;; + *) + dnl --with-nghttp2 option used with path + want_h2="yes" + want_h2_path="$withval/lib/pkgconfig" + ;; +esac + +curl_h2_msg="disabled (--with-nghttp2)" +if test X"$want_h2" != Xno; then + dnl backup the pre-nghttp2 variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + CURL_CHECK_PKGCONFIG(libnghttp2, $want_h2_path) + + if test "$PKGCONFIG" != "no" ; then + LIB_H2=`CURL_EXPORT_PCDIR([$want_h2_path]) + $PKGCONFIG --libs-only-l libnghttp2` + AC_MSG_NOTICE([-l is $LIB_H2]) + + CPP_H2=`CURL_EXPORT_PCDIR([$want_h2_path]) dnl + $PKGCONFIG --cflags-only-I libnghttp2` + AC_MSG_NOTICE([-I is $CPP_H2]) + + LD_H2=`CURL_EXPORT_PCDIR([$want_h2_path]) + $PKGCONFIG --libs-only-L libnghttp2` + AC_MSG_NOTICE([-L is $LD_H2]) + + LDFLAGS="$LDFLAGS $LD_H2" + CPPFLAGS="$CPPFLAGS $CPP_H2" + LIBS="$LIB_H2 $LIBS" + + # use nghttp2_option_set_no_recv_client_magic to require nghttp2 + # >= 1.0.0 + AC_CHECK_LIB(nghttp2, nghttp2_option_set_no_recv_client_magic, + [ + AC_CHECK_HEADERS(nghttp2/nghttp2.h, + curl_h2_msg="enabled (nghttp2)" + NGHTTP2_ENABLED=1 + AC_DEFINE(USE_NGHTTP2, 1, [if nghttp2 is in use]) + AC_SUBST(USE_NGHTTP2, [1]) + ) + ], + dnl not found, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + ) + + else + dnl no nghttp2 pkg-config found, deal with it + if test X"$want_h2" != Xdefault; then + dnl To avoid link errors, we do not allow --with-nghttp2 without + dnl a pkgconfig file + AC_MSG_ERROR([--with-nghttp2 was specified but could not find libnghttp2 pkg-config file.]) + fi + fi + +fi + +dnl ********************************************************************** +dnl Check for zsh completion path +dnl ********************************************************************** + +OPT_ZSH_FPATH=default +AC_ARG_WITH(zsh-functions-dir, +AC_HELP_STRING([--with-zsh-functions-dir=PATH],[Install zsh completions to PATH]) +AC_HELP_STRING([--without-zsh-functions-dir],[Do not install zsh completions]), + [OPT_ZSH_FPATH=$withval]) +case "$OPT_ZSH_FPATH" in + no) + dnl --without-zsh-functions-dir option used + ;; + default|yes) + dnl --with-zsh-functions-dir option used without path + ZSH_FUNCTIONS_DIR="$datarootdir/zsh/site-functions" + AC_SUBST(ZSH_FUNCTIONS_DIR) + ;; + *) + dnl --with-zsh-functions-dir option used with path + ZSH_FUNCTIONS_DIR="$withval" + AC_SUBST(ZSH_FUNCTIONS_DIR) + ;; +esac + +dnl ********************************************************************** +dnl Back to "normal" configuring +dnl ********************************************************************** + +dnl Checks for header files. +AC_HEADER_STDC + +CURL_CHECK_HEADER_MALLOC +CURL_CHECK_HEADER_MEMORY + +dnl Now check for the very most basic headers. Then we can use these +dnl ones as default-headers when checking for the rest! +AC_CHECK_HEADERS( + sys/types.h \ + sys/time.h \ + sys/select.h \ + sys/socket.h \ + sys/ioctl.h \ + sys/uio.h \ + assert.h \ + unistd.h \ + stdlib.h \ + arpa/inet.h \ + net/if.h \ + netinet/in.h \ + netinet/in6.h \ + sys/un.h \ + linux/tcp.h \ + netinet/tcp.h \ + netdb.h \ + sys/sockio.h \ + sys/stat.h \ + sys/param.h \ + termios.h \ + termio.h \ + sgtty.h \ + fcntl.h \ + alloca.h \ + time.h \ + io.h \ + pwd.h \ + utime.h \ + sys/utime.h \ + sys/poll.h \ + poll.h \ + socket.h \ + sys/resource.h \ + libgen.h \ + locale.h \ + errno.h \ + stdbool.h \ + arpa/tftp.h \ + sys/filio.h \ + sys/wait.h \ + setjmp.h, +dnl to do if not found +[], +dnl to do if found +[], +dnl default includes +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_IN6_H +#include +#endif +#ifdef HAVE_SYS_UN_H +#include +#endif +] +) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +CURL_CHECK_VARIADIC_MACROS +AC_TYPE_SIZE_T +AC_HEADER_TIME +CURL_CHECK_STRUCT_TIMEVAL +CURL_VERIFY_RUNTIMELIBS + +AX_COMPILE_CHECK_SIZEOF(size_t) +AX_COMPILE_CHECK_SIZEOF(long) +AX_COMPILE_CHECK_SIZEOF(int) +AX_COMPILE_CHECK_SIZEOF(short) +AX_COMPILE_CHECK_SIZEOF(time_t) +AX_COMPILE_CHECK_SIZEOF(off_t) + +o=$CPPFLAGS +CPPFLAGS="-I$srcdir/include $CPPFLAGS" +AX_COMPILE_CHECK_SIZEOF(curl_off_t, [ +#include +]) +CPPFLAGS=$o + +AC_CHECK_TYPE(long long, + [AC_DEFINE(HAVE_LONGLONG, 1, + [Define to 1 if the compiler supports the 'long long' data type.])] + longlong="yes" +) + +if test "xyes" = "x$longlong"; then + AC_MSG_CHECKING([if numberLL works]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ + long long val = 1000LL; + ]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_LL, 1, [if your compiler supports LL]) + ],[ + AC_MSG_RESULT([no]) + ]) +fi + + +# check for ssize_t +AC_CHECK_TYPE(ssize_t, , + AC_DEFINE(ssize_t, int, [the signed version of size_t])) + +# check for bool type +AC_CHECK_TYPE([bool],[ + AC_DEFINE(HAVE_BOOL_T, 1, + [Define to 1 if bool is an available type.]) +], ,[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDBOOL_H +#include +#endif +]) + +# check for sa_family_t +AC_CHECK_TYPE(sa_family_t, + AC_DEFINE(CURL_SA_FAMILY_T, sa_family_t, [IP address type in sockaddr]), + [ + # The windows name? + AC_CHECK_TYPE(ADDRESS_FAMILY, + AC_DEFINE(CURL_SA_FAMILY_T, ADDRESS_FAMILY, [IP address type in sockaddr]), + AC_DEFINE(CURL_SA_FAMILY_T, unsigned short, [IP address type in sockaddr]), + [ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + ]) + ], +[ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +]) + +AC_MSG_CHECKING([if time_t is unsigned]) +CURL_RUN_IFELSE( + [ + #include + #include + time_t t = -1; + return (t > 0); + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_TIME_T_UNSIGNED, 1, [Define this if time_t is unsigned]) +],[ + AC_MSG_RESULT([no]) +],[ + dnl cross-compiling, most systems are unsigned + AC_MSG_RESULT([no]) +]) + +CURL_CONFIGURE_CURL_SOCKLEN_T + +CURL_CONFIGURE_PULL_SYS_POLL + +TYPE_IN_ADDR_T + +TYPE_SOCKADDR_STORAGE + +TYPE_SIG_ATOMIC_T + +AC_TYPE_SIGNAL + +CURL_CHECK_FUNC_SELECT + +CURL_CHECK_FUNC_RECV +CURL_CHECK_FUNC_SEND +CURL_CHECK_MSG_NOSIGNAL + +CURL_CHECK_FUNC_ALARM +CURL_CHECK_FUNC_BASENAME +CURL_CHECK_FUNC_CLOSESOCKET +CURL_CHECK_FUNC_CLOSESOCKET_CAMEL +CURL_CHECK_FUNC_CONNECT +CURL_CHECK_FUNC_FCNTL +CURL_CHECK_FUNC_FDOPEN +CURL_CHECK_FUNC_FREEADDRINFO +CURL_CHECK_FUNC_FREEIFADDRS +CURL_CHECK_FUNC_FSETXATTR +CURL_CHECK_FUNC_FTRUNCATE +CURL_CHECK_FUNC_GETADDRINFO +CURL_CHECK_FUNC_GAI_STRERROR +CURL_CHECK_FUNC_GETHOSTBYADDR +CURL_CHECK_FUNC_GETHOSTBYADDR_R +CURL_CHECK_FUNC_GETHOSTBYNAME +CURL_CHECK_FUNC_GETHOSTBYNAME_R +CURL_CHECK_FUNC_GETHOSTNAME +CURL_CHECK_FUNC_GETIFADDRS +CURL_CHECK_FUNC_GETSERVBYPORT_R +CURL_CHECK_FUNC_GMTIME_R +CURL_CHECK_FUNC_INET_NTOA_R +CURL_CHECK_FUNC_INET_NTOP +CURL_CHECK_FUNC_INET_PTON +CURL_CHECK_FUNC_IOCTL +CURL_CHECK_FUNC_IOCTLSOCKET +CURL_CHECK_FUNC_IOCTLSOCKET_CAMEL +CURL_CHECK_FUNC_LOCALTIME_R +CURL_CHECK_FUNC_MEMRCHR +CURL_CHECK_FUNC_POLL +CURL_CHECK_FUNC_SETSOCKOPT +CURL_CHECK_FUNC_SIGACTION +CURL_CHECK_FUNC_SIGINTERRUPT +CURL_CHECK_FUNC_SIGNAL +CURL_CHECK_FUNC_SIGSETJMP +CURL_CHECK_FUNC_SOCKET +CURL_CHECK_FUNC_SOCKETPAIR +CURL_CHECK_FUNC_STRCASECMP +CURL_CHECK_FUNC_STRCMPI +CURL_CHECK_FUNC_STRDUP +CURL_CHECK_FUNC_STRERROR_R +CURL_CHECK_FUNC_STRICMP +CURL_CHECK_FUNC_STRNCASECMP +CURL_CHECK_FUNC_STRNCMPI +CURL_CHECK_FUNC_STRNICMP +CURL_CHECK_FUNC_STRSTR +CURL_CHECK_FUNC_STRTOK_R +CURL_CHECK_FUNC_STRTOLL +CURL_CHECK_FUNC_WRITEV + +case $host in + *msdosdjgpp) + ac_cv_func_pipe=no + skipcheck_pipe=yes + AC_MSG_NOTICE([skip check for pipe on msdosdjgpp]) + ;; +esac + +AC_CHECK_DECLS([getpwuid_r], [], [AC_DEFINE(HAVE_DECL_GETPWUID_R_MISSING, 1, "Set if getpwuid_r() declaration is missing")], + [[#include + #include ]]) + + +AC_CHECK_FUNCS([fnmatch \ + geteuid \ + getpass_r \ + getppid \ + getpwuid \ + getpwuid_r \ + getrlimit \ + gettimeofday \ + if_nametoindex \ + mach_absolute_time \ + pipe \ + setlocale \ + setmode \ + setrlimit \ + utime \ + utimes +],[ +],[ + func="$ac_func" + eval skipcheck=\$skipcheck_$func + if test "x$skipcheck" != "xyes"; then + AC_MSG_CHECKING([deeper for $func]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ + $func (); + ]]) + ],[ + AC_MSG_RESULT([yes]) + eval "ac_cv_func_$func=yes" + AC_DEFINE_UNQUOTED(XC_SH_TR_CPP([HAVE_$func]), [1], + [Define to 1 if you have the $func function.]) + ],[ + AC_MSG_RESULT([but still no]) + ]) + fi +]) + +if test "$ipv6" = "yes"; then + if test "$curl_cv_func_getaddrinfo" = "yes"; then + AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support]) + IPV6_ENABLED=1 + AC_SUBST(IPV6_ENABLED) + fi +fi + +CURL_CHECK_NONBLOCKING_SOCKET + +dnl ************************************************************ +dnl nroff tool stuff +dnl + +AC_PATH_PROG( PERL, perl, , + $PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin ) +AC_SUBST(PERL) + +AC_PATH_PROGS( NROFF, gnroff nroff, , + $PATH:/usr/bin/:/usr/local/bin ) +AC_SUBST(NROFF) + +if test -n "$NROFF"; then + dnl only check for nroff options if an nroff command was found + + AC_MSG_CHECKING([how to use *nroff to get plain text from man pages]) + MANOPT="-man" + mancheck=`echo foo | $NROFF $MANOPT 2>/dev/null` + if test -z "$mancheck"; then + MANOPT="-mandoc" + mancheck=`echo foo | $NROFF $MANOPT 2>/dev/null` + if test -z "$mancheck"; then + MANOPT="" + AC_MSG_RESULT([failed]) + AC_MSG_WARN([found no *nroff option to get plaintext from man pages]) + else + AC_MSG_RESULT([$MANOPT]) + fi + else + AC_MSG_RESULT([$MANOPT]) + fi + AC_SUBST(MANOPT) +fi + +if test -z "$MANOPT" +then + dnl if no nroff tool was found, or no option that could convert man pages + dnl was found, then disable the built-in manual stuff + AC_MSG_WARN([disabling built-in manual]) + USE_MANUAL="no"; +fi + +dnl ************************************************************************* +dnl If the manual variable still is set, then we go with providing a built-in +dnl manual + +if test "$USE_MANUAL" = "1"; then + AC_DEFINE(USE_MANUAL, 1, [If you want to build curl with the built-in manual]) + curl_manual_msg="enabled" +fi + +dnl set variable for use in automakefile(s) +AM_CONDITIONAL(USE_MANUAL, test x"$USE_MANUAL" = x1) + +CURL_CHECK_LIB_ARES +AM_CONDITIONAL(USE_EMBEDDED_ARES, test x$embedded_ares = xyes) + +if test "x$curl_cv_native_windows" != "xyes" && + test "x$enable_shared" = "xyes"; then + build_libhostname=yes +else + build_libhostname=no +fi +AM_CONDITIONAL(BUILD_LIBHOSTNAME, test x$build_libhostname = xyes) + +if test "x$want_ares" != xyes; then + CURL_CHECK_OPTION_THREADED_RESOLVER +fi + +dnl ************************************************************ +dnl disable POSIX threads +dnl +AC_MSG_CHECKING([whether to use POSIX threads for threaded resolver]) +AC_ARG_ENABLE(pthreads, +AC_HELP_STRING([--enable-pthreads], + [Enable POSIX threads (default for threaded resolver)]) +AC_HELP_STRING([--disable-pthreads],[Disable POSIX threads]), +[ case "$enableval" in + no) AC_MSG_RESULT(no) + want_pthreads=no + ;; + *) AC_MSG_RESULT(yes) + want_pthreads=yes + ;; + esac ], [ + AC_MSG_RESULT(auto) + want_pthreads=auto + ] +) + +dnl turn off pthreads if rt is disabled +if test "$want_pthreads" != "no"; then + if test "$want_pthreads" = "yes" && test "$dontwant_rt" = "yes"; then + AC_MSG_ERROR([options --enable-pthreads and --disable-rt are mutually exclusive]) + fi + if test "$dontwant_rt" != "no"; then + dnl if --enable-pthreads was explicit then warn it's being ignored + if test "$want_pthreads" = "yes"; then + AC_MSG_WARN([--enable-pthreads Ignored since librt is disabled.]) + fi + want_pthreads=no + fi +fi + +dnl turn off pthreads if no threaded resolver +if test "$want_pthreads" != "no" && test "$want_thres" != "yes"; then + want_pthreads=no +fi + +dnl detect pthreads +if test "$want_pthreads" != "no"; then + AC_CHECK_HEADER(pthread.h, + [ AC_DEFINE(HAVE_PTHREAD_H, 1, [if you have ]) + save_CFLAGS="$CFLAGS" + + dnl first check for function without lib + AC_CHECK_FUNC(pthread_create, [USE_THREADS_POSIX=1] ) + + dnl if it wasn't found without lib, search for it in pthread lib + if test "$USE_THREADS_POSIX" != "1" + then + CFLAGS="$CFLAGS -pthread" + AC_CHECK_LIB(pthread, pthread_create, + [USE_THREADS_POSIX=1], + [ CFLAGS="$save_CFLAGS"]) + fi + + if test "x$USE_THREADS_POSIX" = "x1" + then + AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup]) + curl_res_msg="POSIX threaded" + fi + ]) +fi + +dnl threaded resolver check +if test "$want_thres" = "yes" && test "x$USE_THREADS_POSIX" != "x1"; then + if test "$want_pthreads" = "yes"; then + AC_MSG_ERROR([--enable-pthreads but pthreads was not found]) + fi + dnl If native Windows fallback on Win32 threads since no POSIX threads + if test "$curl_cv_native_windows" = "yes"; then + USE_THREADS_WIN32=1 + AC_DEFINE(USE_THREADS_WIN32, 1, [if you want Win32 threaded DNS lookup]) + curl_res_msg="Win32 threaded" + else + AC_MSG_ERROR([Threaded resolver enabled but no thread library found]) + fi +fi + +dnl ************************************************************ +dnl disable verbose text strings +dnl +AC_MSG_CHECKING([whether to enable verbose strings]) +AC_ARG_ENABLE(verbose, +AC_HELP_STRING([--enable-verbose],[Enable verbose strings]) +AC_HELP_STRING([--disable-verbose],[Disable verbose strings]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_VERBOSE_STRINGS, 1, [to disable verbose strings]) + curl_verbose_msg="no" + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +dnl ************************************************************ +dnl enable SSPI support +dnl +AC_MSG_CHECKING([whether to enable SSPI support (Windows native builds only)]) +AC_ARG_ENABLE(sspi, +AC_HELP_STRING([--enable-sspi],[Enable SSPI]) +AC_HELP_STRING([--disable-sspi],[Disable SSPI]), +[ case "$enableval" in + yes) + if test "$curl_cv_native_windows" = "yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support]) + AC_SUBST(USE_WINDOWS_SSPI, [1]) + curl_sspi_msg="enabled" + else + AC_MSG_RESULT(no) + AC_MSG_WARN([--enable-sspi Ignored. Only supported on native Windows builds.]) + fi + ;; + *) + if test "x$WINSSL_ENABLED" = "x1"; then + # --with-winssl implies --enable-sspi + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + ;; + esac ], + if test "x$WINSSL_ENABLED" = "x1"; then + # --with-winssl implies --enable-sspi + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +) + +dnl ************************************************************ +dnl disable cryptographic authentication +dnl +AC_MSG_CHECKING([whether to enable cryptographic authentication methods]) +AC_ARG_ENABLE(crypto-auth, +AC_HELP_STRING([--enable-crypto-auth],[Enable cryptographic authentication]) +AC_HELP_STRING([--disable-crypto-auth],[Disable cryptographic authentication]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_CRYPTO_AUTH, 1, [to disable cryptographic authentication]) + CURL_DISABLE_CRYPTO_AUTH=1 + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +CURL_CHECK_OPTION_NTLM_WB + +CURL_CHECK_NTLM_WB + +dnl ************************************************************ +dnl disable TLS-SRP authentication +dnl +AC_MSG_CHECKING([whether to enable TLS-SRP authentication]) +AC_ARG_ENABLE(tls-srp, +AC_HELP_STRING([--enable-tls-srp],[Enable TLS-SRP authentication]) +AC_HELP_STRING([--disable-tls-srp],[Disable TLS-SRP authentication]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_TLS_SRP, 1, [to disable TLS-SRP authentication]) + want_tls_srp=no + ;; + *) AC_MSG_RESULT(yes) + want_tls_srp=yes + ;; + esac ], + AC_MSG_RESULT(yes) + want_tls_srp=yes +) + +if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$HAVE_OPENSSL_SRP" = "x1") ; then + AC_DEFINE(USE_TLS_SRP, 1, [Use TLS-SRP authentication]) + USE_TLS_SRP=1 + curl_tls_srp_msg="enabled" +fi + +dnl ************************************************************ +dnl disable Unix domain sockets support +dnl +AC_MSG_CHECKING([whether to enable Unix domain sockets]) +AC_ARG_ENABLE(unix-sockets, +AC_HELP_STRING([--enable-unix-sockets],[Enable Unix domain sockets]) +AC_HELP_STRING([--disable-unix-sockets],[Disable Unix domain sockets]), +[ case "$enableval" in + no) AC_MSG_RESULT(no) + want_unix_sockets=no + ;; + *) AC_MSG_RESULT(yes) + want_unix_sockets=yes + ;; + esac ], [ + AC_MSG_RESULT(auto) + want_unix_sockets=auto + ] +) +if test "x$want_unix_sockets" != "xno"; then + AC_CHECK_MEMBER([struct sockaddr_un.sun_path], [ + AC_DEFINE(USE_UNIX_SOCKETS, 1, [Use Unix domain sockets]) + AC_SUBST(USE_UNIX_SOCKETS, [1]) + curl_unix_sockets_msg="enabled" + ], [ + if test "x$want_unix_sockets" = "xyes"; then + AC_MSG_ERROR([--enable-unix-sockets is not available on this platform!]) + fi + ], [ + #include + ]) +fi + +dnl ************************************************************ +dnl disable cookies support +dnl +AC_MSG_CHECKING([whether to enable support for cookies]) +AC_ARG_ENABLE(cookies, +AC_HELP_STRING([--enable-cookies],[Enable cookies support]) +AC_HELP_STRING([--disable-cookies],[Disable cookies support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_COOKIES, 1, [to disable cookies support]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +dnl ************************************************************ +dnl hiding of library internal symbols +dnl +CURL_CONFIGURE_SYMBOL_HIDING + +dnl +dnl All the library dependencies put into $LIB apply to libcurl only. +dnl +LIBCURL_LIBS=$LIBS + +AC_SUBST(LIBCURL_LIBS) +AC_SUBST(CURL_NETWORK_LIBS) +AC_SUBST(CURL_NETWORK_AND_TIME_LIBS) + +dnl BLANK_AT_MAKETIME may be used in our Makefile.am files to blank +dnl LIBS variable used in generated makefile at makefile processing +dnl time. Doing this functionally prevents LIBS from being used for +dnl all link targets in given makefile. +BLANK_AT_MAKETIME= +AC_SUBST(BLANK_AT_MAKETIME) + +AM_CONDITIONAL(CROSSCOMPILING, test x$cross_compiling = xyes) + +dnl yes or no +ENABLE_SHARED="$enable_shared" +AC_SUBST(ENABLE_SHARED) + +dnl to let curl-config output the static libraries correctly +ENABLE_STATIC="$enable_static" +AC_SUBST(ENABLE_STATIC) + + +dnl +dnl For keeping supported features and protocols also in pkg-config file +dnl since it is more cross-compile friendly than curl-config +dnl + +if test "x$OPENSSL_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES SSL" +elif test -n "$SSL_ENABLED"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES SSL" +fi +if test "x$IPV6_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6" +fi +if test "x$USE_UNIX_SOCKETS" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES UnixSockets" +fi +if test "x$HAVE_LIBZ" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES libz" +fi +if test "x$HAVE_BROTLI" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES brotli" +fi +if test "x$USE_ARES" = "x1" -o "x$USE_THREADS_POSIX" = "x1" \ + -o "x$USE_THREADS_WIN32" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES AsynchDNS" +fi +if test "x$IDN_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES IDN" +fi +if test "x$USE_WINDOWS_SSPI" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES SSPI" +fi + +if test "x$HAVE_GSSAPI" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES GSS-API" +fi + +if test "x$curl_psl_msg" = "xyes"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES PSL" +fi + +if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \ + \( "x$HAVE_GSSAPI" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \); then + SUPPORT_FEATURES="$SUPPORT_FEATURES SPNEGO" +fi + +if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \ + \( "x$HAVE_GSSAPI" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \); then + SUPPORT_FEATURES="$SUPPORT_FEATURES Kerberos" +fi + +if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1"; then + if test "x$OPENSSL_ENABLED" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \ + -o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \ + -o "x$NSS_ENABLED" = "x1" -o "x$DARWINSSL_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM" + + if test "x$CURL_DISABLE_HTTP" != "x1" -a \ + "x$NTLM_WB_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM_WB" + fi + fi +fi + +if test "x$USE_TLS_SRP" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES TLS-SRP" +fi + +if test "x$USE_NGHTTP2" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2" +fi + +if test "x$CURL_WITH_MULTI_SSL" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES MultiSSL" +fi + +if test "x$OPENSSL_ENABLED" = "x1" -o "x$GNUTLS_ENABLED" = "x1" \ + -o "x$NSS_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" +fi + +AC_SUBST(SUPPORT_FEATURES) + +dnl For supported protocols in pkg-config file +if test "x$CURL_DISABLE_HTTP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS HTTP" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS HTTPS" + fi +fi +if test "x$CURL_DISABLE_FTP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS FTP" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS FTPS" + fi +fi +if test "x$CURL_DISABLE_FILE" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS FILE" +fi +if test "x$CURL_DISABLE_TELNET" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS TELNET" +fi +if test "x$CURL_DISABLE_LDAP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS LDAP" + if test "x$CURL_DISABLE_LDAPS" != "x1"; then + if (test "x$USE_OPENLDAP" = "x1" && test "x$SSL_ENABLED" = "x1") || + (test "x$USE_OPENLDAP" != "x1" && test "x$HAVE_LDAP_SSL" = "x1"); then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS LDAPS" + fi + fi +fi +if test "x$CURL_DISABLE_DICT" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS DICT" +fi +if test "x$CURL_DISABLE_TFTP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS TFTP" +fi +if test "x$CURL_DISABLE_GOPHER" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER" +fi +if test "x$CURL_DISABLE_POP3" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS POP3" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS POP3S" + fi +fi +if test "x$CURL_DISABLE_IMAP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS IMAP" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS IMAPS" + fi +fi +if test "x$CURL_DISABLE_SMB" != "x1" \ + -a "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" \ + -a \( "x$OPENSSL_ENABLED" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \ + -o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \ + -o "x$NSS_ENABLED" = "x1" -o "x$DARWINSSL_ENABLED" = "x1" \); then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMB" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMBS" + fi +fi +if test "x$CURL_DISABLE_SMTP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMTP" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMTPS" + fi +fi +if test "x$USE_LIBSSH2" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SCP" + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SFTP" +fi +if test "x$USE_LIBSSH" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SCP" + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SFTP" +fi +if test "x$CURL_DISABLE_RTSP" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS RTSP" +fi +if test "x$USE_LIBRTMP" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS RTMP" +fi + +dnl replace spaces with newlines +dnl sort the lines +dnl replace the newlines back to spaces +SUPPORT_PROTOCOLS=`echo $SUPPORT_PROTOCOLS | tr ' ' '\012' | sort | tr '\012' ' '` + +AC_SUBST(SUPPORT_PROTOCOLS) + +dnl squeeze whitespace out of some variables + +squeeze CFLAGS +squeeze CPPFLAGS +squeeze DEFS +squeeze LDFLAGS +squeeze LIBS + +squeeze LIBCURL_LIBS +squeeze CURL_NETWORK_LIBS +squeeze CURL_NETWORK_AND_TIME_LIBS + +squeeze SUPPORT_FEATURES +squeeze SUPPORT_PROTOCOLS + +XC_CHECK_BUILD_FLAGS + +SSL_BACKENDS=${ssl_backends} +AC_SUBST(SSL_BACKENDS) + +if test "x$want_curldebug_assumed" = "xyes" && + test "x$want_curldebug" = "xyes" && test "x$USE_ARES" = "x1"; then + ac_configure_args="$ac_configure_args --enable-curldebug" +fi + +AC_CONFIG_FILES([Makefile \ + docs/Makefile \ + docs/examples/Makefile \ + docs/libcurl/Makefile \ + docs/libcurl/opts/Makefile \ + docs/cmdline-opts/Makefile \ + include/Makefile \ + include/curl/Makefile \ + src/Makefile \ + lib/Makefile \ + scripts/Makefile \ + lib/libcurl.vers \ + tests/Makefile \ + tests/certs/Makefile \ + tests/certs/scripts/Makefile \ + tests/data/Makefile \ + tests/server/Makefile \ + tests/libtest/Makefile \ + tests/unit/Makefile \ + packages/Makefile \ + packages/Win32/Makefile \ + packages/Win32/cygwin/Makefile \ + packages/Linux/Makefile \ + packages/Linux/RPM/Makefile \ + packages/Linux/RPM/curl.spec \ + packages/Linux/RPM/curl-ssl.spec \ + packages/Solaris/Makefile \ + packages/EPM/curl.list \ + packages/EPM/Makefile \ + packages/vms/Makefile \ + packages/AIX/Makefile \ + packages/AIX/RPM/Makefile \ + packages/AIX/RPM/curl.spec \ + curl-config \ + libcurl.pc +]) +AC_OUTPUT + +CURL_GENERATE_CONFIGUREHELP_PM + +XC_AMEND_DISTCLEAN([lib src tests/unit tests/server tests/libtest docs/examples]) + +AC_MSG_NOTICE([Configured to build curl/libcurl: + + curl version: ${CURLVERSION} + Host setup: ${host} + Install prefix: ${prefix} + Compiler: ${CC} + SSL support: ${curl_ssl_msg} + SSH support: ${curl_ssh_msg} + zlib support: ${curl_zlib_msg} + brotli support: ${curl_brotli_msg} + GSS-API support: ${curl_gss_msg} + TLS-SRP support: ${curl_tls_srp_msg} + resolver: ${curl_res_msg} + IPv6 support: ${curl_ipv6_msg} + Unix sockets support: ${curl_unix_sockets_msg} + IDN support: ${curl_idn_msg} + Build libcurl: Shared=${enable_shared}, Static=${enable_static} + Built-in manual: ${curl_manual_msg} + --libcurl option: ${curl_libcurl_msg} + Verbose errors: ${curl_verbose_msg} + SSPI support: ${curl_sspi_msg} + ca cert bundle: ${ca}${ca_warning} + ca cert path: ${capath}${capath_warning} + ca fallback: ${with_ca_fallback} + LDAP support: ${curl_ldap_msg} + LDAPS support: ${curl_ldaps_msg} + RTSP support: ${curl_rtsp_msg} + RTMP support: ${curl_rtmp_msg} + metalink support: ${curl_mtlnk_msg} + PSL support: ${curl_psl_msg} + HTTP2 support: ${curl_h2_msg} + Protocols: ${SUPPORT_PROTOCOLS} +]) diff --git a/curl-config.in b/curl-config.in new file mode 100644 index 00000000..2f958ca9 --- /dev/null +++ b/curl-config.in @@ -0,0 +1,182 @@ +#! /bin/sh +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2001 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +includedir=@includedir@ +cppflag_curl_staticlib=@CPPFLAG_CURL_STATICLIB@ + +usage() +{ + cat <&2 + exit 1 + fi + ;; + + --configure) + echo @CONFIGURE_OPTIONS@ + ;; + + *) + echo "unknown option: $1" + usage 1 + ;; + esac + shift +done + +exit 0 diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..60f32938 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,4 @@ +*.html +*.pdf +curl.1 +*.1.dist diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md new file mode 100644 index 00000000..024f169e --- /dev/null +++ b/docs/BINDINGS.md @@ -0,0 +1,118 @@ +libcurl bindings +================ + + Creative people have written bindings or interfaces for various environments + and programming languages. Using one of these allows you to take advantage of + curl powers from within your favourite language or system. + + This is a list of all known interfaces as of this writing. + + The bindings listed below are not part of the curl/libcurl distribution + archives, but must be downloaded and installed separately. + +[Ada95](http://www.almroth.com/adacurl/index.html) Written by Andreas Almroth + +[Basic](http://scriptbasic.com/) ScriptBasic bindings written by Peter Verhas + +C++: [curlpp](http://curlpp.org/) Written by Jean-Philippe Barrette-LaPierre, +[curlcpp](https://github.com/JosephP91/curlcpp) by Giuseppe Persico and [C++ +Requests](https://github.com/whoshuu/cpr) by Huu Nguyen + +[Ch](https://chcurl.sourceforge.io/) Written by Stephen Nestinger and Jonathan Rogado + +Cocoa: [BBHTTP](https://github.com/brunodecarvalho/BBHTTP) written by Bruno de Carvalho +[curlhandle](https://github.com/karelia/curlhandle) Written by Dan Wood + +[D](https://dlang.org/library/std/net/curl.html) Written by Kenneth Bogert + +[Delphi](https://github.com/Mercury13/curl4delphi) Written by Mikhail Merkuryev + +[Dylan](https://dylanlibs.sourceforge.io/) Written by Chris Double + +[Eiffel](https://room.eiffel.com/library/curl) Written by Eiffel Software + +[Euphoria](http://rays-web.com/eulibcurl.htm) Written by Ray Smith + +[Falcon](http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl) + +[Ferite](http://www.ferite.org/) Written by Paul Querna + +[Gambas](https://gambas.sourceforge.io/) + +[glib/GTK+](http://atterer.net/glibcurl/) Written by Richard Atterer + +Go: [go-curl](https://github.com/andelf/go-curl) by ShuYu Wang + +[Guile](http://www.lonelycactus.com/guile-curl.html) Written by Michael L. Gran + +[Harbour](https://github.com/vszakats/harbour-core/tree/master/contrib/hbcurl) Written by Viktor Szakáts + +[Haskell](https://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl) Written by Galois, Inc + +[Java](https://github.com/pjlegato/curl-java) + +[Julia](https://github.com/forio/Curl.jl) Written by Paul Howe + +[Lisp](https://common-lisp.net/project/cl-curl/) Written by Liam Healy + +Lua: [luacurl](http://luacurl.luaforge.net/) by Alexander Marinov, [Lua-cURL](https://github.com/Lua-cURL) by Jürgen Hötzel + +[Mono](https://forge.novell.com/modules/xfmod/project/?libcurl-mono) Written by Jeffrey Phillips + +[.NET](https://sourceforge.net/projects/libcurl-net/) libcurl-net by Jeffrey Phillips + +[node.js](https://github.com/JCMais/node-libcurl) node-libcurl by Jonathan Cardoso Machado + +[Object-Pascal](http://www.tekool.com/opcurl) Free Pascal, Delphi and Kylix binding written by Christophe Espern. + +[OCaml](https://opam.ocaml.org/packages/ocurl/) Written by Lars Nilsson and ygrek + +[Pascal](http://houston.quik.com/jkp/curlpas/) Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer. + +Perl: [WWW--Curl](https://github.com/szbalint/WWW--Curl) Maintained by Cris +Bailiff and Bálint Szilakszi, +[perl6-net-curl](https://github.com/azawawi/perl6-net-curl) by Ahmad M. Zawawi + +[PHP](https://php.net/curl) Originally written by Sterling Hughes + +[PostgreSQL](https://github.com/pramsey/pgsql-http) - HTTP client for PostgreSQL + +[Python](http://pycurl.io/) PycURL by Kjetil Jacobsen + +[R](https://cran.r-project.org/package=curl) + +[Rexx](https://rexxcurl.sourceforge.io/) Written Mark Hessling + +[Ring](https://ring-lang.sourceforge.io/doc1.3/libcurl.html) RingLibCurl by Mahmoud Fayed + +RPG, support for ILE/RPG on OS/400 is included in source distribution + +Ruby: [curb](https://github.com/taf2/curb) written by Ross Bamford + +[Rust](https://github.com/carllerche/curl-rust) curl-rust - by Carl Lerche + +[Scheme](https://www.metapaper.net/lisovsky/web/curl/) Bigloo binding by Kirill Lisovsky + +[Scilab](https://help.scilab.org/docs/current/fr_FR/getURL.html) binding by Sylvestre Ledru + +[S-Lang](https://www.jedsoft.org/slang/modules/curl.html) by John E Davis + +[Smalltalk](http://www.squeaksource.com/CurlPlugin/) Written by Danil Osipchuk + +[SP-Forth](https://sourceforge.net/p/spf/spf/ci/master/tree/devel/~ac/lib/lin/curl/) Written by Andrey Cherezov + +[SPL](http://www.clifford.at/spl/) Written by Clifford Wolf + +[Tcl](http://mirror.yellow5.com/tclcurl/) Tclcurl by Andrés García + +[Visual Basic](https://sourceforge.net/projects/libcurl-vb/) libcurl-vb by Jeffrey Phillips + +[Visual Foxpro](http://www.ctl32.com.ar/libcurl.asp) by Carlos Alloatti + +[Q](https://q-lang.sourceforge.io/) The libcurl module is part of the default install + +[wxWidgets](https://wxcode.sourceforge.io/components/wxcurl/) Written by Casey O'Donnell + +[XBLite](http://perso.wanadoo.fr/xblite/libraries.html) Written by David Szafranski + +[Xojo](https://github.com/charonn0/RB-libcURL) Written by Andrew Lambert diff --git a/docs/BUGS b/docs/BUGS new file mode 100644 index 00000000..7322d9b2 --- /dev/null +++ b/docs/BUGS @@ -0,0 +1,297 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +BUGS + + 1. Bugs + 1.1 There are still bugs + 1.2 Where to report + 1.3 Security bugs + 1.4 What to report + 1.5 libcurl problems + 1.6 Who will fix the problems + 1.7 How to get a stack trace + 1.8 Bugs in libcurl bindings + 1.9 Bugs in old versions + + 2. Bug fixing procedure + 2.1 What happens on first filing + 2.2 First response + 2.3 Not reproducible + 2.4 Unresponsive + 2.5 Lack of time/interest + 2.6 KNOWN_BUGS + 2.7 TODO + 2.8 Closing off stalled bugs + +============================================================================== + +1.1 There are still bugs + + Curl and libcurl keep being developed. Adding features and changing code + means that bugs will sneak in, no matter how hard we try not to. + + Of course there are lots of bugs left. And lots of misfeatures. + + To help us make curl the stable and solid product we want it to be, we need + bug reports and bug fixes. + +1.2 Where to report + + If you can't fix a bug yourself and submit a fix for it, try to report an as + detailed report as possible to a curl mailing list to allow one of us to + have a go at a solution. You can optionally also post your bug/problem at + curl's bug tracking system over at + + https://github.com/curl/curl/issues + + Please read the rest of this document below first before doing that! + + If you feel you need to ask around first, find a suitable mailing list and + post there. The lists are available on https://curl.haxx.se/mail/ + +1.3 Security bugs + + If you find a bug or problem in curl or libcurl that you think has a + security impact, for example a bug that can put users in danger or make them + vulnerable if the bug becomes public knowledge, then please report that bug + using our security development process. + + Security related bugs or bugs that are suspected to have a security impact, + should be reported by email to curl-security@haxx.se so that they first can + be dealt with away from the public to minimize the harm and impact it will + have on existing users out there who might be using the vulnerable versions. + + The curl project's process for handling security related issues is + documented here: + + https://curl.haxx.se/dev/secprocess.html + +1.4 What to report + + When reporting a bug, you should include all information that will help us + understand what's wrong, what you expected to happen and how to repeat the + bad behavior. You therefore need to tell us: + + - your operating system's name and version number + + - what version of curl you're using (curl -V is fine) + + - versions of the used libraries that libcurl is built to use + + - what URL you were working with (if possible), at least which protocol + + and anything and everything else you think matters. Tell us what you + expected to happen, tell use what did happen, tell us how you could make it + work another way. Dig around, try out, test. Then include all the tiny bits + and pieces in your report. You will benefit from this yourself, as it will + enable us to help you quicker and more accurately. + + Since curl deals with networks, it often helps us if you include a protocol + debug dump with your bug report. The output you get by using the -v or + --trace options. + + If curl crashed, causing a core dump (in unix), there is hardly any use to + send that huge file to anyone of us. Unless we have an exact same system + setup as you, we can't do much with it. Instead we ask you to get a stack + trace and send that (much smaller) output to us instead! + + The address and how to subscribe to the mailing lists are detailed in the + MANUAL file. + +1.5 libcurl problems + + When you've written your own application with libcurl to perform transfers, + it is even more important to be specific and detailed when reporting bugs. + + Tell us the libcurl version and your operating system. Tell us the name and + version of all relevant sub-components like for example the SSL library + you're using and what name resolving your libcurl uses. If you use SFTP or + SCP, the libssh2 version is relevant etc. + + Showing us a real source code example repeating your problem is the best way + to get our attention and it will greatly increase our chances to understand + your problem and to work on a fix (if we agree it truly is a problem). + + Lots of problems that appear to be libcurl problems are actually just abuses + of the libcurl API or other malfunctions in your applications. It is advised + that you run your problematic program using a memory debug tool like + valgrind or similar before you post memory-related or "crashing" problems to + us. + +1.6 Who will fix the problems + + If the problems or bugs you describe are considered to be bugs, we want to + have the problems fixed. + + There are no developers in the curl project that are paid to work on bugs. + All developers that take on reported bugs do this on a voluntary basis. We + do it out of an ambition to keep curl and libcurl excellent products and out + of pride. + + But please do not assume that you can just lump over something to us and it + will then magically be fixed after some given time. Most often we need + feedback and help to understand what you've experienced and how to repeat a + problem. Then we may only be able to assist YOU to debug the problem and to + track down the proper fix. + + We get reports from many people every month and each report can take a + considerable amount of time to really go to the bottom with. + +1.7 How to get a stack trace + + First, you must make sure that you compile all sources with -g and that you + don't 'strip' the final executable. Try to avoid optimizing the code as + well, remove -O, -O2 etc from the compiler options. + + Run the program until it cores. + + Run your debugger on the core file, like ' curl core'. + should be replaced with the name of your debugger, in most cases that will + be 'gdb', but 'dbx' and others also occur. + + When the debugger has finished loading the core file and presents you a + prompt, enter 'where' (without the quotes) and press return. + + The list that is presented is the stack trace. If everything worked, it is + supposed to contain the chain of functions that were called when curl + crashed. Include the stack trace with your detailed bug report. It'll help a + lot. + +1.8 Bugs in libcurl bindings + + There will of course pop up bugs in libcurl bindings. You should then + primarily approach the team that works on that particular binding and see + what you can do to help them fix the problem. + + If you suspect that the problem exists in the underlying libcurl, then + please convert your program over to plain C and follow the steps outlined + above. + +1.9 Bugs in old versions + + The curl project typically releases new versions every other month, and we + fix several hundred bugs per year. For a huge table of releases, number of + bug fixes and more, see: https://curl.haxx.se/docs/releases.html + + The developers in the curl project do not have bandwidth or energy enough to + maintain several branches or to spend much time on hunting down problems in + old versions when chances are we already fixed them or at least that they've + changed nature and appearance in later versions. + + When you experience a problem and want to report it, you really SHOULD + include the version number of the curl you're using when you experience the + issue. If that version number shows us that you're using an out-of-date + curl, you should also try out a modern curl version to see if the problem + persists or how/if it has changed in appearance. + + Even if you cannot immediately upgrade your application/system to run the + latest curl version, you can most often at least run a test version or + experimental build or similar, to get this confirmed or not. + + At times people insist that they cannot upgrade to a modern curl version, + but instead they "just want the bug fixed". That's fine, just don't count on + us spending many cycles on trying to identify which single commit, if that's + even possible, that at some point in the past fixed the problem you're now + experiencing. + + Security wise, it is almost always a bad idea to lag behind the current curl + versions by a lot. We keeping discovering and reporting security problems + over time see you can see in this table: + https://curl.haxx.se/docs/vulnerabilities.html + +2. Bug fixing procedure + +2.1 What happens on first filing + + When a new issue is posted in the issue tracker or on the mailing list, the + team of developers first need to see the report. Maybe they took the day + off, maybe they're off in the woods hunting. Have patience. Allow at least a + few days before expecting someone to have responded. + + In the issue tracker you can expect that some labels will be set on the + issue to help categorize it. + +2.2 First response + + If your issue/bug report wasn't perfect at once (and few are), chances are + that someone will ask follow-up questions. Which version did you use? Which + options did you use? How often does the problem occur? How can we reproduce + this problem? Which protocols does it involve? Or perhaps much more specific + and deep diving questions. It all depends on your specific issue. + + You should then respond to these follow-up questions and provide more info + about the problem, so that we can help you figure it out. Or maybe you can + help us figure it out. An active back-and-forth communication is important + and the key for finding a cure and landing a fix. + +2.3 Not reproducible + + For problems that we can't reproduce and can't understand even after having + gotten all the info we need and having studied the source code over again, + are really hard to solve so then we may require further work from you who + actually see or experience the problem. + +2.4 Unresponsive + + If the problem haven't been understood or reproduced, and there's nobody + responding to follow-up questions or questions asking for clarifications or + for discussing possible ways to move forward with the task, we take that as + a strong suggestion that the bug is not important. + + Unimportant issues will be closed as inactive sooner or later as they can't + be fixed. The inactivity period (waiting for responses) should not be + shorter than two weeks but may extend months. + +2.5 Lack of time/interest + + Bugs that are filed and are understood can unfortunately end up in the + "nobody cares enough about it to work on it" category. Such bugs are + perfectly valid problems that *should* get fixed but apparently aren't. We + try to mark such bugs as "KNOWN_BUGS material" after a time of inactivity + and if no activity is noticed after yet some time those bugs are added to + KNOWN_BUGS and are closed in the issue tracker. + +2.6 KNOWN_BUGS + + This is a list of known bugs. Bugs we know exist and that have been pointed + out but that haven't yet been fixed. The reasons for why they haven't been + fixed can involve anything really, but the primary reason is that nobody has + considered these problems to be important enough to spend the necessary time + and effort to have them fixed. + + The KNOWN_BUGS are always up for grabs and we will always love the ones who + bring one of them back to live and offers solutions to them. + + The KNOWN_BUGS document has a sibling document known as TODO. + +2.7 TODO + + Issues that are filed or reported that aren't really bugs but more missing + features or ideas for future improvements and so on are marked as + 'enhancement' or 'feature-request' and will be added to the TODO document + instead and the issue is closed. We don't keep TODO items in the issue + tracker. + + The TODO document is full of ideas and suggestions of what we can add or fix + one day. You're always encouraged and free to grab one of those items and + take up a discussion with the curl development team on how that could be + implemented or provided in the project so that you can work on ticking it + odd that document. + + If the issue is rather a bug and not a missing feature or functionality, it + is listed in KNOWN_BUGS instead. + +2.8 Closing off stalled bugs + + The issue and pull request trackers on https://github.com/curl/curl will + only hold "active" entries (using a non-precise definition of what active + actually is, but they're at least not completely dead). Those that are + abandoned or in other ways dormant will be closed and sometimes added to + TODO and KNOWN_BUGS instead. + + This way, we only have "active" issues open on github. Irrelevant issues and + pull requests will not distract developers or casual visitors. diff --git a/docs/CHECKSRC.md b/docs/CHECKSRC.md new file mode 100644 index 00000000..f246b57e --- /dev/null +++ b/docs/CHECKSRC.md @@ -0,0 +1,124 @@ +# checksrc + +This is the tool we use within the curl project to scan C source code and +check that it adheres to our [Source Code Style guide](CODE_STYLE.md). + +## Usage + + checksrc.pl [options] [file1] [file2] ... + +## Command line options + +`-W[file]` whitelists that file and excludes it from being checked. Helpful +when, for example, one of the files is generated. + +`-D[dir]` directory name to prepend to file names when accessing them. + +`-h` shows the help output, that also lists all recognized warnings + +## What does checksrc warn for? + +checksrc does not check and verify the code against the entire style guide, +but the script is instead an effort to detect the most common mistakes and +syntax mistakes that contributors make before they get accustomed to our code +style. Heck, many of us regulars do the mistakes too and this script helps us +keep the code in shape. + + checksrc.pl -h + +Lists how to use the script and it lists all existing warnings it has and +problems it detects. At the time of this writing, the existing checksrc +warnings are: + +- `BADCOMMAND`: There's a bad !checksrc! instruction in the code. See the + **Ignore certain warnings** section below for details. + +- `BANNEDFUNC`: A banned function was used. The functions sprintf, vsprintf, + strcat, strncat, gets are **never** allowed in curl source code. + +- `BRACEELSE`: '} else' on the same line. The else is supposed to be on the + following line. + +- `BRACEPOS`: wrong position for an open brace (`{`). + +- `COMMANOSPACE`: a comma without following space + +- `COPYRIGHT`: the file is missing a copyright statement! + +- `CPPCOMMENTS`: `//` comment detected, that's not C89 compliant + +- `FOPENMODE`: `fopen()` needs a macro for the mode string, use it + +- `INDENTATION`: detected a wrong start column for code. Note that this warning + only checks some specific places and will certainly miss many bad + indentations. + +- `LONGLINE`: A line is longer than 79 columns. + +- `PARENBRACE`: `){` was used without sufficient space in between. + +- `RETURNNOSPACE`: `return` was used without space between the keyword and the + following value. + +- `SPACEAFTERPAREN`: there was a space after open parenthesis, `( text`. + +- `SPACEBEFORECLOSE`: there was a space before a close parenthesis, `text )`. + +- `SPACEBEFORECOMMA`: there was a space before a comma, `one , two`. + +- `SPACEBEFOREPAREN`: there was a space before an open parenthesis, `if (`, + where one was not expected + +- `SPACESEMICOLON`: there was a space before semicolon, ` ;`. + +- `TABS`: TAB characters are not allowed! + +- `TRAILINGSPACE`: Trailing white space on the line + +- `UNUSEDIGNORE`: a checksrc inlined warning ignore was asked for but not used, + that's an ignore that should be removed or changed to get used. + +## Ignore certain warnings + +Due to the nature of the source code and the flaws of the checksrc tool, there +is sometimes a need to ignore specific warnings. checksrc allows a few +different ways to do this. + +### Inline ignore + +You can control what to ignore within a specific source file by providing +instructions to checksrc in the source code itself. You need a magic marker +that is `!checksrc!` followed by the instruction. The instruction can ask to +ignore a specific warning N number of times or you ignore all of them until +you mark the end of the ignored section. + +Inline ignores are only done for that single specific source code file. + +Example + + /* !checksrc! disable LONGLINE all */ + +This will ignore the warning for overly long lines until it is re-enabled with: + + /* !checksrc! enable LONGLINE */ + +If the enabling isn't performed before the end of the file, it will be enabled +automatically for the next file. + +You can also opt to ignore just N violations so that if you have a single long +line you just can't shorten and is agreed to be fine anyway: + + /* !checksrc! disable LONGLINE 1 */ + +... and the warning for long lines will be enabled again automatically after +it has ignored that single warning. The number `1` can of course be changed to +any other integer number. It can be used to make sure only the exact intended +instances are ignored and nothing extra. + +### Directory wide ignore patterns + +This is a method we've transitioned away from. Use inline ignores as far as +possible. + +Make a `checksrc.whitelist` file in the directory of the source code with the +false positive, and include the full offending line into this file. diff --git a/docs/CIPHERS.md b/docs/CIPHERS.md new file mode 100644 index 00000000..2a1d8ca7 --- /dev/null +++ b/docs/CIPHERS.md @@ -0,0 +1,487 @@ +# Ciphers + +With curl's options `CURLOPT_SSL_CIPHER_LIST` and `--ciphers` users can +control which ciphers to consider when negotiating TLS connections. + +The names of the known ciphers differ depending on which TLS backend that +libcurl was built to use. This is an attempt to list known cipher names. + +## OpenSSL + +(based on [OpenSSL docs](https://www.openssl.org/docs/man1.1.0/apps/ciphers.html)) + +### SSL3 cipher suites + +`NULL-MD5` +`NULL-SHA` +`RC4-MD5` +`RC4-SHA` +`IDEA-CBC-SHA` +`DES-CBC3-SHA` +`DH-DSS-DES-CBC3-SHA` +`DH-RSA-DES-CBC3-SHA` +`DHE-DSS-DES-CBC3-SHA` +`DHE-RSA-DES-CBC3-SHA` +`ADH-RC4-MD5` +`ADH-DES-CBC3-SHA` + +### TLS v1.0 cipher suites + +`NULL-MD5` +`NULL-SHA` +`RC4-MD5` +`RC4-SHA` +`IDEA-CBC-SHA` +`DES-CBC3-SHA` +`DHE-DSS-DES-CBC3-SHA` +`DHE-RSA-DES-CBC3-SHA` +`ADH-RC4-MD5` +`ADH-DES-CBC3-SHA` + +### AES ciphersuites from RFC3268, extending TLS v1.0 + +`AES128-SHA` +`AES256-SHA` +`DH-DSS-AES128-SHA` +`DH-DSS-AES256-SHA` +`DH-RSA-AES128-SHA` +`DH-RSA-AES256-SHA` +`DHE-DSS-AES128-SHA` +`DHE-DSS-AES256-SHA` +`DHE-RSA-AES128-SHA` +`DHE-RSA-AES256-SHA` +`ADH-AES128-SHA` +`ADH-AES256-SHA` + +### SEED ciphersuites from RFC4162, extending TLS v1.0 + +`SEED-SHA` +`DH-DSS-SEED-SHA` +`DH-RSA-SEED-SHA` +`DHE-DSS-SEED-SHA` +`DHE-RSA-SEED-SHA` +`ADH-SEED-SHA` + +### GOST ciphersuites, extending TLS v1.0 + +`GOST94-GOST89-GOST89` +`GOST2001-GOST89-GOST89` +`GOST94-NULL-GOST94` +`GOST2001-NULL-GOST94` + +### Elliptic curve cipher suites + +`ECDHE-RSA-NULL-SHA` +`ECDHE-RSA-RC4-SHA` +`ECDHE-RSA-DES-CBC3-SHA` +`ECDHE-RSA-AES128-SHA` +`ECDHE-RSA-AES256-SHA` +`ECDHE-ECDSA-NULL-SHA` +`ECDHE-ECDSA-RC4-SHA` +`ECDHE-ECDSA-DES-CBC3-SHA` +`ECDHE-ECDSA-AES128-SHA` +`ECDHE-ECDSA-AES256-SHA` +`AECDH-NULL-SHA` +`AECDH-RC4-SHA` +`AECDH-DES-CBC3-SHA` +`AECDH-AES128-SHA` +`AECDH-AES256-SHA` + +### TLS v1.2 cipher suites + +`NULL-SHA256` +`AES128-SHA256` +`AES256-SHA256` +`AES128-GCM-SHA256` +`AES256-GCM-SHA384` +`DH-RSA-AES128-SHA256` +`DH-RSA-AES256-SHA256` +`DH-RSA-AES128-GCM-SHA256` +`DH-RSA-AES256-GCM-SHA384` +`DH-DSS-AES128-SHA256` +`DH-DSS-AES256-SHA256` +`DH-DSS-AES128-GCM-SHA256` +`DH-DSS-AES256-GCM-SHA384` +`DHE-RSA-AES128-SHA256` +`DHE-RSA-AES256-SHA256` +`DHE-RSA-AES128-GCM-SHA256` +`DHE-RSA-AES256-GCM-SHA384` +`DHE-DSS-AES128-SHA256` +`DHE-DSS-AES256-SHA256` +`DHE-DSS-AES128-GCM-SHA256` +`DHE-DSS-AES256-GCM-SHA384` +`ECDHE-RSA-AES128-SHA256` +`ECDHE-RSA-AES256-SHA384` +`ECDHE-RSA-AES128-GCM-SHA256` +`ECDHE-RSA-AES256-GCM-SHA384` +`ECDHE-ECDSA-AES128-SHA256` +`ECDHE-ECDSA-AES256-SHA384` +`ECDHE-ECDSA-AES128-GCM-SHA256` +`ECDHE-ECDSA-AES256-GCM-SHA384` +`ADH-AES128-SHA256` +`ADH-AES256-SHA256` +`ADH-AES128-GCM-SHA256` +`ADH-AES256-GCM-SHA384` +`AES128-CCM` +`AES256-CCM` +`DHE-RSA-AES128-CCM` +`DHE-RSA-AES256-CCM` +`AES128-CCM8` +`AES256-CCM8` +`DHE-RSA-AES128-CCM8` +`DHE-RSA-AES256-CCM8` +`ECDHE-ECDSA-AES128-CCM` +`ECDHE-ECDSA-AES256-CCM` +`ECDHE-ECDSA-AES128-CCM8` +`ECDHE-ECDSA-AES256-CCM8` + +### Camellia HMAC-Based ciphersuites from RFC6367, extending TLS v1.2 + +`ECDHE-ECDSA-CAMELLIA128-SHA256` +`ECDHE-ECDSA-CAMELLIA256-SHA384` +`ECDHE-RSA-CAMELLIA128-SHA256` +`ECDHE-RSA-CAMELLIA256-SHA384` + +### TLS 1.3 cipher suites + +(Note: the TLS 1.3 cipher suites are set with a separate option.) + +`TLS13-AES-256-GCM-SHA384` +`TLS13-CHACHA20-POLY1305-SHA256` +`TLS13-AES-128-GCM-SHA256` +`TLS13-AES-128-CCM-8-SHA256` +`TLS13-AES-128-CCM-SHA256` + +## NSS + +### Totally insecure + +`rc4` +`rc4-md5` +`rc4export` +`rc2` +`rc2export` +`des` +`desede3` + +### SSL3/TLS cipher suites + +`rsa_rc4_128_md5` +`rsa_rc4_128_sha` +`rsa_3des_sha` +`rsa_des_sha` +`rsa_rc4_40_md5` +`rsa_rc2_40_md5` +`rsa_null_md5` +`rsa_null_sha` +`fips_3des_sha` +`fips_des_sha` +`fortezza` +`fortezza_rc4_128_sha` +`fortezza_null` + +### TLS 1.0 Exportable 56-bit Cipher Suites + +`rsa_des_56_sha` +`rsa_rc4_56_sha` + +### AES ciphers + +`dhe_dss_aes_128_cbc_sha` +`dhe_dss_aes_256_cbc_sha` +`dhe_rsa_aes_128_cbc_sha` +`dhe_rsa_aes_256_cbc_sha` +`rsa_aes_128_sha` +`rsa_aes_256_sha` + +### ECC ciphers + +`ecdh_ecdsa_null_sha` +`ecdh_ecdsa_rc4_128_sha` +`ecdh_ecdsa_3des_sha` +`ecdh_ecdsa_aes_128_sha` +`ecdh_ecdsa_aes_256_sha` +`ecdhe_ecdsa_null_sha` +`ecdhe_ecdsa_rc4_128_sha` +`ecdhe_ecdsa_3des_sha` +`ecdhe_ecdsa_aes_128_sha` +`ecdhe_ecdsa_aes_256_sha` +`ecdh_rsa_null_sha` +`ecdh_rsa_128_sha` +`ecdh_rsa_3des_sha` +`ecdh_rsa_aes_128_sha` +`ecdh_rsa_aes_256_sha` +`ecdhe_rsa_null` +`ecdhe_rsa_rc4_128_sha` +`ecdhe_rsa_3des_sha` +`ecdhe_rsa_aes_128_sha` +`ecdhe_rsa_aes_256_sha` +`ecdh_anon_null_sha` +`ecdh_anon_rc4_128sha` +`ecdh_anon_3des_sha` +`ecdh_anon_aes_128_sha` +`ecdh_anon_aes_256_sha` + +### HMAC-SHA256 cipher suites + +`rsa_null_sha_256` +`rsa_aes_128_cbc_sha_256` +`rsa_aes_256_cbc_sha_256` +`dhe_rsa_aes_128_cbc_sha_256` +`dhe_rsa_aes_256_cbc_sha_256` +`ecdhe_ecdsa_aes_128_cbc_sha_256` +`ecdhe_rsa_aes_128_cbc_sha_256` + +### AES GCM cipher suites in RFC 5288 and RFC 5289 + +`rsa_aes_128_gcm_sha_256` +`dhe_rsa_aes_128_gcm_sha_256` +`dhe_dss_aes_128_gcm_sha_256` +`ecdhe_ecdsa_aes_128_gcm_sha_256` +`ecdh_ecdsa_aes_128_gcm_sha_256` +`ecdhe_rsa_aes_128_gcm_sha_256` +`ecdh_rsa_aes_128_gcm_sha_256` + +### cipher suites using SHA384 + +`rsa_aes_256_gcm_sha_384` +`dhe_rsa_aes_256_gcm_sha_384` +`dhe_dss_aes_256_gcm_sha_384` +`ecdhe_ecdsa_aes_256_sha_384` +`ecdhe_rsa_aes_256_sha_384` +`ecdhe_ecdsa_aes_256_gcm_sha_384` +`ecdhe_rsa_aes_256_gcm_sha_384` + +### chacha20-poly1305 cipher suites + +`ecdhe_rsa_chacha20_poly1305_sha_256` +`ecdhe_ecdsa_chacha20_poly1305_sha_256` +`dhe_rsa_chacha20_poly1305_sha_256` + +## GSKit + +Ciphers are internally defined as numeric codes (https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/apis/gsk_attribute_set_buffer.htm), +but libcurl maps them to the following case-insensitive names. + +### SSL2 cipher suites (insecure: disabled by default) + +`rc2-md5` +`rc4-md5` +`exp-rc2-md5` +`exp-rc4-md5` +`des-cbc-md5` +`des-cbc3-md5` + +### SSL3 cipher suites + +`null-md5` +`null-sha` +`rc4-md5` +`rc4-sha` +`exp-rc2-cbc-md5` +`exp-rc4-md5` +`exp-des-cbc-sha` +`des-cbc3-sha` + +### TLS v1.0 cipher suites + +`null-md5` +`null-sha` +`rc4-md5` +`rc4-sha` +`exp-rc2-cbc-md5` +`exp-rc4-md5` +`exp-des-cbc-sha` +`des-cbc3-sha` +`aes128-sha` +`aes256-sha` + +### TLS v1.1 cipher suites + +`null-md5` +`null-sha` +`rc4-md5` +`rc4-sha` +`exp-des-cbc-sha` +`des-cbc3-sha` +`aes128-sha` +`aes256-sha` + +### TLS v1.2 cipher suites + +`null-md5` +`null-sha` +`null-sha256` +`rc4-md5` +`rc4-sha` +`des-cbc3-sha` +`aes128-sha` +`aes256-sha` +`aes128-sha256` +`aes256-sha256` +`aes128-gcm-sha256` +`aes256-gcm-sha384` + +## WolfSSL + +`RC4-SHA`, +`RC4-MD5`, +`DES-CBC3-SHA`, +`AES128-SHA`, +`AES256-SHA`, +`NULL-SHA`, +`NULL-SHA256`, +`DHE-RSA-AES128-SHA`, +`DHE-RSA-AES256-SHA`, +`DHE-PSK-AES256-GCM-SHA384`, +`DHE-PSK-AES128-GCM-SHA256`, +`PSK-AES256-GCM-SHA384`, +`PSK-AES128-GCM-SHA256`, +`DHE-PSK-AES256-CBC-SHA384`, +`DHE-PSK-AES128-CBC-SHA256`, +`PSK-AES256-CBC-SHA384`, +`PSK-AES128-CBC-SHA256`, +`PSK-AES128-CBC-SHA`, +`PSK-AES256-CBC-SHA`, +`DHE-PSK-AES128-CCM`, +`DHE-PSK-AES256-CCM`, +`PSK-AES128-CCM`, +`PSK-AES256-CCM`, +`PSK-AES128-CCM-8`, +`PSK-AES256-CCM-8`, +`DHE-PSK-NULL-SHA384`, +`DHE-PSK-NULL-SHA256`, +`PSK-NULL-SHA384`, +`PSK-NULL-SHA256`, +`PSK-NULL-SHA`, +`HC128-MD5`, +`HC128-SHA`, +`HC128-B2B256`, +`AES128-B2B256`, +`AES256-B2B256`, +`RABBIT-SHA`, +`NTRU-RC4-SHA`, +`NTRU-DES-CBC3-SHA`, +`NTRU-AES128-SHA`, +`NTRU-AES256-SHA`, +`AES128-CCM-8`, +`AES256-CCM-8`, +`ECDHE-ECDSA-AES128-CCM`, +`ECDHE-ECDSA-AES128-CCM-8`, +`ECDHE-ECDSA-AES256-CCM-8`, +`ECDHE-RSA-AES128-SHA`, +`ECDHE-RSA-AES256-SHA`, +`ECDHE-ECDSA-AES128-SHA`, +`ECDHE-ECDSA-AES256-SHA`, +`ECDHE-RSA-RC4-SHA`, +`ECDHE-RSA-DES-CBC3-SHA`, +`ECDHE-ECDSA-RC4-SHA`, +`ECDHE-ECDSA-DES-CBC3-SHA`, +`AES128-SHA256`, +`AES256-SHA256`, +`DHE-RSA-AES128-SHA256`, +`DHE-RSA-AES256-SHA256`, +`ECDH-RSA-AES128-SHA`, +`ECDH-RSA-AES256-SHA`, +`ECDH-ECDSA-AES128-SHA`, +`ECDH-ECDSA-AES256-SHA`, +`ECDH-RSA-RC4-SHA`, +`ECDH-RSA-DES-CBC3-SHA`, +`ECDH-ECDSA-RC4-SHA`, +`ECDH-ECDSA-DES-CBC3-SHA`, +`AES128-GCM-SHA256`, +`AES256-GCM-SHA384`, +`DHE-RSA-AES128-GCM-SHA256`, +`DHE-RSA-AES256-GCM-SHA384`, +`ECDHE-RSA-AES128-GCM-SHA256`, +`ECDHE-RSA-AES256-GCM-SHA384`, +`ECDHE-ECDSA-AES128-GCM-SHA256`, +`ECDHE-ECDSA-AES256-GCM-SHA384`, +`ECDH-RSA-AES128-GCM-SHA256`, +`ECDH-RSA-AES256-GCM-SHA384`, +`ECDH-ECDSA-AES128-GCM-SHA256`, +`ECDH-ECDSA-AES256-GCM-SHA384`, +`CAMELLIA128-SHA`, +`DHE-RSA-CAMELLIA128-SHA`, +`CAMELLIA256-SHA`, +`DHE-RSA-CAMELLIA256-SHA`, +`CAMELLIA128-SHA256`, +`DHE-RSA-CAMELLIA128-SHA256`, +`CAMELLIA256-SHA256`, +`DHE-RSA-CAMELLIA256-SHA256`, +`ECDHE-RSA-AES128-SHA256`, +`ECDHE-ECDSA-AES128-SHA256`, +`ECDH-RSA-AES128-SHA256`, +`ECDH-ECDSA-AES128-SHA256`, +`ECDHE-RSA-AES256-SHA384`, +`ECDHE-ECDSA-AES256-SHA384`, +`ECDH-RSA-AES256-SHA384`, +`ECDH-ECDSA-AES256-SHA384`, +`ECDHE-RSA-CHACHA20-POLY1305`, +`ECDHE-ECDSA-CHACHA20-POLY1305`, +`DHE-RSA-CHACHA20-POLY1305`, +`ECDHE-RSA-CHACHA20-POLY1305-OLD`, +`ECDHE-ECDSA-CHACHA20-POLY1305-OLD`, +`DHE-RSA-CHACHA20-POLY1305-OLD`, +`ADH-AES128-SHA`, +`QSH`, +`RENEGOTIATION-INFO`, +`IDEA-CBC-SHA`, +`ECDHE-ECDSA-NULL-SHA`, +`ECDHE-PSK-NULL-SHA256`, +`ECDHE-PSK-AES128-CBC-SHA256`, +`PSK-CHACHA20-POLY1305`, +`ECDHE-PSK-CHACHA20-POLY1305`, +`DHE-PSK-CHACHA20-POLY1305`, +`EDH-RSA-DES-CBC3-SHA`, + +## WinSSL + +WinSSL allows the enabling and disabling of encryption algorithms, but not specific ciphersuites. They are defined by Microsoft (https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx) + +`CALG_MD2`, +`CALG_MD4`, +`CALG_MD5`, +`CALG_SHA`, +`CALG_SHA1`, +`CALG_MAC`, +`CALG_RSA_SIGN`, +`CALG_DSS_SIGN`, +`CALG_NO_SIGN`, +`CALG_RSA_KEYX`, +`CALG_DES`, +`CALG_3DES_112`, +`CALG_3DES`, +`CALG_DESX`, +`CALG_RC2`, +`CALG_RC4`, +`CALG_SEAL`, +`CALG_DH_SF`, +`CALG_DH_EPHEM`, +`CALG_AGREEDKEY_ANY`, +`CALG_HUGHES_MD5`, +`CALG_SKIPJACK`, +`CALG_TEK`, +`CALG_CYLINK_MEK`, +`CALG_SSL3_SHAMD5`, +`CALG_SSL3_MASTER`, +`CALG_SCHANNEL_MASTER_HASH`, +`CALG_SCHANNEL_MAC_KEY`, +`CALG_SCHANNEL_ENC_KEY`, +`CALG_PCT1_MASTER`, +`CALG_SSL2_MASTER`, +`CALG_TLS1_MASTER`, +`CALG_RC5`, +`CALG_HMAC`, +`CALG_TLS1PRF`, +`CALG_HASH_REPLACE_OWF`, +`CALG_AES_128`, +`CALG_AES_192`, +`CALG_AES_256`, +`CALG_AES`, +`CALG_SHA_256`, +`CALG_SHA_384`, +`CALG_SHA_512`, +`CALG_ECDH`, +`CALG_ECMQV`, +`CALG_ECDSA`, diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt new file mode 100644 index 00000000..69486172 --- /dev/null +++ b/docs/CMakeLists.txt @@ -0,0 +1,3 @@ +#add_subdirectory(examples) +add_subdirectory(libcurl) +add_subdirectory(cmdline-opts) diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..1f71c387 --- /dev/null +++ b/docs/CODE_OF_CONDUCT.md @@ -0,0 +1,32 @@ +Contributor Code of Conduct +=========================== + +As contributors and maintainers of this project, we pledge to respect all +people who contribute through reporting issues, posting feature requests, +updating documentation, submitting pull requests or patches, and other +activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, or religion. + +Examples of unacceptable behavior by participants include the use of sexual +language or imagery, derogatory comments or personal attacks, trolling, public +or private harassment, insults, or other unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct. Project maintainers who do not +follow the Code of Conduct may be removed from the project team. + +This code of conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by opening an issue or contacting one or more of the project +maintainers. + +This Code of Conduct is adapted from the [Contributor +Covenant](https://contributor-covenant.org/), version 1.1.0, available at +[https://contributor-covenant.org/version/1/1/0/](https://contributor-covenant.org/version/1/1/0/) diff --git a/docs/CODE_STYLE.md b/docs/CODE_STYLE.md new file mode 100644 index 00000000..2d275cd7 --- /dev/null +++ b/docs/CODE_STYLE.md @@ -0,0 +1,246 @@ +# curl C code style + +Source code that has a common style is easier to read than code that uses +different styles in different places. It helps making the code feel like one +single code base. Easy-to-read is a very important property of code and helps +making it easier to review when new things are added and it helps debugging +code when developers are trying to figure out why things go wrong. A unified +style is more important than individual contributors having their own personal +tastes satisfied. + +Our C code has a few style rules. Most of them are verified and upheld by the +"lib/checksrc.pl" script. Invoked with "make checksrc" or even by default by +the build system when built after "./configure --enable-debug" has been used. + +It is normally not a problem for anyone to follow the guidelines, as you just +need to copy the style already used in the source code and there are no +particularly unusual rules in our set of rules. + +We also work hard on writing code that are warning-free on all the major +platforms and in general on as many platforms as possible. Code that obviously +will cause warnings will not be accepted as-is. + +## Naming + +Try using a non-confusing naming scheme for your new functions and variable +names. It doesn't necessarily have to mean that you should use the same as in +other places of the code, just that the names should be logical, +understandable and be named according to what they're used for. File-local +functions should be made static. We like lower case names. + +See the [INTERNALS](INTERNALS.md) document on how we name non-exported +library-global symbols. + +## Indenting + +We use only spaces for indentation, never TABs. We use two spaces for each new +open brace. + + if(something_is_true) { + while(second_statement == fine) { + moo(); + } + } + +## Comments + +Since we write C89 code, **//** comments are not allowed. They weren't +introduced in the C standard until C99. We use only **/* comments */**. + + /* this is a comment */ + +## Long lines + +Source code in curl may never be wider than 79 columns and there are two +reasons for maintaining this even in the modern era of very large and high +resolution screens: + +1. Narrower columns are easier to read than very wide ones. There's a reason + newspapers have used columns for decades or centuries. + +2. Narrower columns allow developers to easier show multiple pieces of code + next to each other in different windows. I often have two or three source + code windows next to each other on the same screen - as well as multiple + terminal and debugging windows. + +## Braces + +In if/while/do/for expressions, we write the open brace on the same line as +the keyword and we then set the closing brace on the same indentation level as +the initial keyword. Like this: + + if(age < 40) { + /* clearly a youngster */ + } + +You may omit the braces if they would contain only a one-line statement: + + if(!x) + continue; + +For functions the opening brace should be on a separate line: + + int main(int argc, char **argv) + { + return 1; + } + +## 'else' on the following line + +When adding an **else** clause to a conditional expression using braces, we +add it on a new line after the closing brace. Like this: + + if(age < 40) { + /* clearly a youngster */ + } + else { + /* probably grumpy */ + } + +## No space before parentheses + +When writing expressions using if/while/do/for, there shall be no space +between the keyword and the open parenthesis. Like this: + + while(1) { + /* loop forever */ + } + +## Use boolean conditions + +Rather than test a conditional value such as a bool against TRUE or FALSE, a +pointer against NULL or != NULL and an int against zero or not zero in +if/while conditions we prefer: + + result = do_something(); + if(!result) { + /* something went wrong */ + return result; + } + +## No assignments in conditions + +To increase readability and reduce complexity of conditionals, we avoid +assigning variables within if/while conditions. We frown upon this style: + + if((ptr = malloc(100)) == NULL) + return NULL; + +and instead we encourage the above version to be spelled out more clearly: + + ptr = malloc(100); + if(!ptr) + return NULL; + +## New block on a new line + +We never write multiple statements on the same source line, even for very +short if() conditions. + + if(a) + return TRUE; + else if(b) + return FALSE; + +and NEVER: + + if(a) return TRUE; + else if(b) return FALSE; + +## Space around operators + +Please use spaces on both sides of operators in C expressions. Postfix **(), +[], ->, ., ++, --** and Unary **+, - !, ~, &** operators excluded they should +have no space. + +Examples: + + bla = func(); + who = name[0]; + age += 1; + true = !false; + size += -2 + 3 * (a + b); + ptr->member = a++; + struct.field = b--; + ptr = &address; + contents = *pointer; + complement = ~bits; + empty = (!*string) ? TRUE : FALSE; + +## No parentheses for return values + +We use the 'return' statement without extra parentheses around the value: + + int works(void) + { + return TRUE; + } + +## Parentheses for sizeof arguments + +When using the sizeof operator in code, we prefer it to be written with +parentheses around its argument: + + int size = sizeof(int); + +## Column alignment + +Some statements cannot be completed on a single line because the line would be +too long, the statement too hard to read, or due to other style guidelines +above. In such a case the statement will span multiple lines. + +If a continuation line is part of an expression or sub-expression then you +should align on the appropriate column so that it's easy to tell what part of +the statement it is. Operators should not start continuation lines. In other +cases follow the 2-space indent guideline. Here are some examples from +libcurl: + + if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) && + (handle->set.httpversion != CURL_HTTP_VERSION_1_0) && + (handle->set.httpreq == HTTPREQ_GET || + handle->set.httpreq == HTTPREQ_HEAD)) + /* didn't ask for HTTP/1.0 and a GET or HEAD */ + return TRUE; + +If no parenthesis, use the default indent: + + data->set.http_disable_hostname_check_before_authentication = + (0 != va_arg(param, long)) ? TRUE : FALSE; + +Function invoke with an open parenthesis: + + if(option) { + result = parse_login_details(option, strlen(option), + (userp ? &user : NULL), + (passwdp ? &passwd : NULL), + NULL); + } + +Align with the "current open" parenthesis: + + DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing " + "server response left\n", + (int)clipamount)); + +## Platform dependent code + +Use **#ifdef HAVE_FEATURE** to do conditional code. We avoid checking for +particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE +shall be generated by the configure script for unix-like systems and they are +hard-coded in the config-[system].h files for the others. + +We also encourage use of macros/functions that possibly are empty or defined +to constants when libcurl is built without that feature, to make the code +seamless. Like this example where the **magic()** function works differently +depending on a build-time conditional: + + #ifdef HAVE_MAGIC + void magic(int a) + { + return a + 2; + } + #else + #define magic(x) 1 + #endif + + int content = magic(3); diff --git a/docs/CONTRIBUTE.md b/docs/CONTRIBUTE.md new file mode 100644 index 00000000..536a9ceb --- /dev/null +++ b/docs/CONTRIBUTE.md @@ -0,0 +1,267 @@ +# Contributing to the curl project + +This document is intended to offer guidelines on how to best contribute to the +curl project. This concerns new features as well as corrections to existing +flaws or bugs. + +## Learning curl + +### Join the Community + +Skip over to [https://curl.haxx.se/mail/](https://curl.haxx.se/mail/) and join +the appropriate mailing list(s). Read up on details before you post +questions. Read this file before you start sending patches! We prefer +questions sent to and discussions being held on the mailing list(s), not sent +to individuals. + +Before posting to one of the curl mailing lists, please read up on the +[mailing list etiquette](https://curl.haxx.se/mail/etiquette.html). + +We also hang out on IRC in #curl on irc.freenode.net + +If you're at all interested in the code side of things, consider clicking +'watch' on the [curl repo on github](https://github.com/curl/curl) to get +notified on pull requests and new issues posted there. + +### License and copyright + +When contributing with code, you agree to put your changes and new code under +the same license curl and libcurl is already using unless stated and agreed +otherwise. + +If you add a larger piece of code, you can opt to make that file or set of +files to use a different license as long as they don't enforce any changes to +the rest of the package and they make sense. Such "separate parts" can not be +GPL licensed (as we don't want copyleft to affect users of libcurl) but they +must use "GPL compatible" licenses (as we want to allow users to use libcurl +properly in GPL licensed environments). + +When changing existing source code, you do not alter the copyright of the +original file(s). The copyright will still be owned by the original creator(s) +or those who have been assigned copyright by the original author(s). + +By submitting a patch to the curl project, you are assumed to have the right +to the code and to be allowed by your employer or whatever to hand over that +patch/code to us. We will credit you for your changes as far as possible, to +give credit but also to keep a trace back to who made what changes. Please +always provide us with your full real name when contributing! + +### What To Read + +Source code, the man pages, the [INTERNALS +document](https://curl.haxx.se/dev/internals.html), +[TODO](https://curl.haxx.se/docs/todo.html), +[KNOWN_BUGS](https://curl.haxx.se/docs/knownbugs.html) and the [most recent +changes](https://curl.haxx.se/dev/sourceactivity.html) in git. Just lurking on +the [curl-library mailing +list](https://curl.haxx.se/mail/list.cgi?list=curl-library) will give you a +lot of insights on what's going on right now. Asking there is a good idea too. + +## Write a good patch + +### Follow code style + +When writing C code, follow the +[CODE_STYLE](https://curl.haxx.se/dev/code-style.html) already established in +the project. Consistent style makes code easier to read and mistakes less +likely to happen. Run `make checksrc` before you submit anything, to make sure +you follow the basic style. That script doesn't verify everything, but if it +complains you know you have work to do. + +### Non-clobbering All Over + +When you write new functionality or fix bugs, it is important that you don't +fiddle all over the source files and functions. Remember that it is likely +that other people have done changes in the same source files as you have and +possibly even in the same functions. If you bring completely new +functionality, try writing it in a new source file. If you fix bugs, try to +fix one bug at a time and send them as separate patches. + +### Write Separate Changes + +It is annoying when you get a huge patch from someone that is said to fix 511 +odd problems, but discussions and opinions don't agree with 510 of them - or +509 of them were already fixed in a different way. Then the person merging +this change needs to extract the single interesting patch from somewhere +within the huge pile of source, and that creates a lot of extra work. + +Preferably, each fix that corrects a problem should be in its own patch/commit +with its own description/commit message stating exactly what they correct so +that all changes can be selectively applied by the maintainer or other +interested parties. + +Also, separate changes enable bisecting much better for tracking problems +and regression in the future. + +### Patch Against Recent Sources + +Please try to get the latest available sources to make your patches against. +It makes the lives of the developers so much easier. The very best is if you +get the most up-to-date sources from the git repository, but the latest +release archive is quite OK as well! + +### Documentation + +Writing docs is dead boring and one of the big problems with many open source +projects. But someone's gotta do it! It makes things a lot easier if you +submit a small description of your fix or your new features with every +contribution so that it can be swiftly added to the package documentation. + +The documentation is always made in man pages (nroff formatted) or plain +ASCII files. All HTML files on the web site and in the release archives are +generated from the nroff/ASCII versions. + +### Test Cases + +Since the introduction of the test suite, we can quickly verify that the main +features are working as they're supposed to. To maintain this situation and +improve it, all new features and functions that are added need to be tested +in the test suite. Every feature that is added should get at least one valid +test case that verifies that it works as documented. If every submitter also +posts a few test cases, it won't end up as a heavy burden on a single person! + +If you don't have test cases or perhaps you have done something that is very +hard to write tests for, do explain exactly how you have otherwise tested and +verified your changes. + +## Sharing Your Changes + +### How to get your changes into the main sources + +Ideally you file a [pull request on +github](https://github.com/curl/curl/pulls), but you can also send your plain +patch to [the curl-library mailing +list](https://curl.haxx.se/mail/list.cgi?list=curl-library). + +Either way, your change will be reviewed and discussed there and you will be +expected to correct flaws pointed out and update accordingly, or the change +risks stalling and eventually just getting deleted without action. As a +submitter of a change, you are the owner of that change until it has been merged. + +Respond on the list or on github about the change and answer questions and/or +fix nits/flaws. This is very important. We will take lack of replies as a +sign that you're not very anxious to get your patch accepted and we tend to +simply drop such changes. + +### About pull requests + +With github it is easy to send a [pull +request](https://github.com/curl/curl/pulls) to the curl project to have +changes merged. + +We strongly prefer pull requests to mailed patches, as it makes it a proper +git commit that is easy to merge and they are easy to track and not that easy +to loose in the flood of many emails, like they sometimes do on the mailing +lists. + +Every pull request submitted will automatically be tested in several different +ways. Every pull request is verfied that: + + - ... it still builds, warning-free, on Linux and macOS, with both + clang and gcc + - ... it still builds fine on Windows with several MSVC versions + - ... it still builds with cmake on Linux, with gcc and clang + - ... it follows rudimentary code style rules + - ... the test suite still runs 100% fine + - ... the release tarball (the "dist") still works + - ... it builds fine in-tree as well as out-of-tree + - ... code coverage doesn't shrink drastically + +If the pull-request fails one of these tests, it will show up as a red X and +you are expected to fix the problem. If you don't understand whan the issue is +or have other problems to fix the complaint, just ask and other project +members will likely be able to help out. + +When you adjust your pull requests after review, consider squashing the +commits so that we can review the full updated version more easily. + +### Making quality patches + +Make the patch against as recent source versions as possible. + +If you've followed the tips in this document and your patch still hasn't been +incorporated or responded to after some weeks, consider resubmitting it to the +list or better yet: change it to a pull request. + +### Write good commit messages + +A short guide to how to write commit messages in the curl project. + + ---- start ---- + [area]: [short line describing the main effect] + -- empty line -- + [full description, no wider than 72 columns that describe as much as + possible as to why this change is made, and possibly what things + it fixes and everything else that is related] + -- empty line -- + [Closes/Fixes #1234 - if this closes or fixes a github issue] + [Bug: URL to source of the report or more related discussion] + [Reported-by: John Doe - credit the reporter] + [whatever-else-by: credit all helpers, finders, doers] + ---- stop ---- + +Don't forget to use commit --author="" if you commit someone else's work, and +make sure that you have your own user and email setup correctly in git before +you commit + +### Write Access to git Repository + +If you are a very frequent contributor, you may be given push access to the +git repository and then you'll be able to push your changes straight into the +git repo instead of sending changes as pull requests or by mail as patches. + +Just ask if this is what you'd want. You will be required to have posted +several high quality patches first, before you can be granted push access. + +### How To Make a Patch with git + +You need to first checkout the repository: + + git clone https://github.com/curl/curl.git + +You then proceed and edit all the files you like and you commit them to your +local repository: + + git commit [file] + +As usual, group your commits so that you commit all changes at once that +constitute a logical change. + +Once you have done all your commits and you're happy with what you see, you +can make patches out of your changes that are suitable for mailing: + + git format-patch remotes/origin/master + +This creates files in your local directory named NNNN-[name].patch for each +commit. + +Now send those patches off to the curl-library list. You can of course opt to +do that with the 'git send-email' command. + +### How To Make a Patch without git + +Keep a copy of the unmodified curl sources. Make your changes in a separate +source tree. When you think you have something that you want to offer the +curl community, use GNU diff to generate patches. + +If you have modified a single file, try something like: + + diff -u unmodified-file.c my-changed-one.c > my-fixes.diff + +If you have modified several files, possibly in different directories, you +can use diff recursively: + + diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff + +The GNU diff and GNU patch tools exist for virtually all platforms, including +all kinds of Unixes and Windows: + +For unix-like operating systems: + + - [https://savannah.gnu.org/projects/patch/](https://savannah.gnu.org/projects/patch/) + - [https://www.gnu.org/software/diffutils/](https://www.gnu.org/software/diffutils/) + +For Windows: + + - [https://gnuwin32.sourceforge.io/packages/patch.htm](https://gnuwin32.sourceforge.io/packages/patch.htm) + - [https://gnuwin32.sourceforge.io/packages/diffutils.htm](https://gnuwin32.sourceforge.io/packages/diffutils.htm) diff --git a/docs/DEPRECATE.md b/docs/DEPRECATE.md new file mode 100644 index 00000000..4506fae5 --- /dev/null +++ b/docs/DEPRECATE.md @@ -0,0 +1,73 @@ +# Items to be removed from future curl releases + +If any of these deprecated features is a cause for concern for you, please +email the curl-library mailing list as soon as possible and explain to us why +this is a problem for you and how your use case can't be satisfied properly +using a work around. + +## axTLS backend + +Here are some complaints on axTLS. + + - home page without HTTPS + - [doesn't support modern TLS features like SNI](https://github.com/dsheets/axtls/issues/2) + - [lacks support for modern ciphers](https://github.com/micropython/micropython/issues/3198) + - [doesn't allow for outside bug report submissions](https://sourceforge.net/p/axtls/bugs/) + - there's virtually no discussion about it in its [forum](https://sourceforge.net/p/axtls/discussion/) + nor [mailing list](https://sourceforge.net/p/axtls/mailman/axtls-general/) + +Combined, this list hints that this is not a library and project we should +recommend to users. + +### State + +Since June 1st, 2018 (curl 7.61.0) axTLS support is disabled in code and +requires a small code change to build without errors. [See +PR](https://github.com/curl/curl/pull/2628) + +### Removal + +Remove all axTLS related code from curl on December 1st, exactly six months +after previously mentioned commit. To be shipped on December 26, 2018 +(possibly called version 7.64.0) + +## HTTP pipelining + +HTTP pipelining is badly supported by curl in the sense that we have bugs and +it is a fragile feature without enough tests. Also, when something turns out +to have problems it is really tricky to debug due to the timing sensitivity so +very often enabling debug outputs or similar completely changes the nature of +the behavior and things are not reproducing anymore! + +HTTP pipelining was never enabled by default by the large desktop browsers due +to all the issues with it. Both Firefox and Chrome have also dropped +pipelining support entirely since a long time back now. We are in fact over +time becoming more and more lonely in supporting pipelining. + +The bad state of HTTP pipelining was a primary driving factor behind HTTP/2 +and its multiplexing feature. HTTP/2 multiplexing is truly and really +"pipelining done right". It is way more solid, practical and solves the use +case in a better way with better performance and fewer downsides and problems. + +In 2018, pipelining *should* be abandoned and HTTP/2 should be used instead. + +### State + +In 7.62.0 (release planned to happen in September 2018), we add code +that ignores the "enable pipeline" option setting). The *setopt() function +would still return "OK" though so the application couldn't tell that this is +happening. + +Users who truly need pipelining from that version will need to modify the code +(ever so slightly) and rebuild. + +### Removal + +Six months later, in sync with the planned release happen in April 2019, +(might be 7.66.0), assuming no major riots have occurred due to this in the +mean time, we rip out the pipelining code. It is in the order of 1000 lines of +libcurl code. + +Left to answer: should the *setopt() function start to return error when these +options are set to be able to tell when they're trying to use options that are +no longer around or should we maintain behavior as much as possible? diff --git a/docs/FAQ b/docs/FAQ new file mode 100644 index 00000000..cb28c2a5 --- /dev/null +++ b/docs/FAQ @@ -0,0 +1,1559 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +FAQ + + 1. Philosophy + 1.1 What is cURL? + 1.2 What is libcurl? + 1.3 What is curl not? + 1.4 When will you make curl do XXXX ? + 1.5 Who makes curl? + 1.6 What do you get for making curl? + 1.7 What about CURL from curl.com? + 1.8 I have a problem who do I mail? + 1.9 Where do I buy commercial support for curl? + 1.10 How many are using curl? + 1.11 Why don't you update ca-bundle.crt + 1.12 I have a problem who can I chat with? + 1.13 curl's ECCN number? + 1.14 How do I submit my patch? + 1.15 How do I port libcurl to my OS? + + 2. Install Related Problems + 2.1 configure doesn't find OpenSSL even when it is installed + 2.1.1 native linker doesn't find OpenSSL + 2.1.2 only the libssl lib is missing + 2.2 Does curl work/build with other SSL libraries? + 2.3 Where can I find a copy of LIBEAY32.DLL? + 2.4 Does curl support SOCKS (RFC 1928) ? + + 3. Usage Problems + 3.1 curl: (1) SSL is disabled, https: not supported + 3.2 How do I tell curl to resume a transfer? + 3.3 Why doesn't my posting using -F work? + 3.4 How do I tell curl to run custom FTP commands? + 3.5 How can I disable the Accept: */* header? + 3.6 Does curl support ASP, XML, XHTML or HTML version Y? + 3.7 Can I use curl to delete/rename a file through FTP? + 3.8 How do I tell curl to follow HTTP redirects? + 3.9 How do I use curl in my favorite programming language? + 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? + 3.11 How do I POST with a different Content-Type? + 3.12 Why do FTP specific features over HTTP proxy fail? + 3.13 Why does my single/double quotes fail? + 3.14 Does curl support Javascript or PAC (automated proxy config)? + 3.15 Can I do recursive fetches with curl? + 3.16 What certificates do I need when I use SSL? + 3.17 How do I list the root dir of an FTP server? + 3.18 Can I use curl to send a POST/PUT and not wait for a response? + 3.19 How do I get HTTP from a host using a specific IP address? + 3.20 How to SFTP from my user's home directory? + 3.21 Protocol xxx not supported or disabled in libcurl + 3.22 curl -X gives me HTTP problems + + 4. Running Problems + 4.1 Problems connecting to SSL servers. + 4.2 Why do I get problems when I use & or % in the URL? + 4.3 How can I use {, }, [ or ] to specify multiple URLs? + 4.4 Why do I get downloaded data even though the web page doesn't exist? + 4.5 Why do I get return code XXX from a HTTP server? + 4.5.1 "400 Bad Request" + 4.5.2 "401 Unauthorized" + 4.5.3 "403 Forbidden" + 4.5.4 "404 Not Found" + 4.5.5 "405 Method Not Allowed" + 4.5.6 "301 Moved Permanently" + 4.6 Can you tell me what error code 142 means? + 4.7 How do I keep user names and passwords secret in Curl command lines? + 4.8 I found a bug! + 4.9 Curl can't authenticate to the server that requires NTLM? + 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! + 4.11 Why does my HTTP range requests return the full document? + 4.12 Why do I get "certificate verify failed" ? + 4.13 Why is curl -R on Windows one hour off? + 4.14 Redirects work in browser but not with curl! + 4.15 FTPS doesn't work + 4.16 My HTTP POST or PUT requests are slow! + 4.17 Non-functional connect timeouts on Windows + 4.18 file:// URLs containing drive letters (Windows, NetWare) + 4.19 Why doesn't curl return an error when the network cable is unplugged? + 4.20 curl doesn't return error for HTTP non-200 responses! + 4.21 Why is there a HTTP/1.1 in my HTTP/2 request? + + 5. libcurl Issues + 5.1 Is libcurl thread-safe? + 5.2 How can I receive all data into a large memory chunk? + 5.3 How do I fetch multiple files with libcurl? + 5.4 Does libcurl do Winsock initing on win32 systems? + 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? + 5.6 What about Keep-Alive or persistent connections? + 5.7 Link errors when building libcurl on Windows! + 5.8 libcurl.so.X: open failed: No such file or directory + 5.9 How does libcurl resolve host names? + 5.10 How do I prevent libcurl from writing the response to stdout? + 5.11 How do I make libcurl not receive the whole HTTP response? + 5.12 Can I make libcurl fake or hide my real IP address? + 5.13 How do I stop an ongoing transfer? + 5.14 Using C++ non-static functions for callbacks? + 5.15 How do I get an FTP directory listing? + 5.16 I want a different time-out! + 5.17 Can I write a server with libcurl? + 5.18 Does libcurl use threads? + + 6. License Issues + 6.1 I have a GPL program, can I use the libcurl library? + 6.2 I have a closed-source program, can I use the libcurl library? + 6.3 I have a BSD licensed program, can I use the libcurl library? + 6.4 I have a program that uses LGPL libraries, can I use libcurl? + 6.5 Can I modify curl/libcurl for my program and keep the changes secret? + 6.6 Can you please change the curl/libcurl license to XXXX? + 6.7 What are my obligations when using libcurl in my commercial apps? + + 7. PHP/CURL Issues + 7.1 What is PHP/CURL? + 7.2 Who wrote PHP/CURL? + 7.3 Can I perform multiple requests using the same handle? + 7.4 Does PHP/CURL have dependencies? + +============================================================================== + +1. Philosophy + + 1.1 What is cURL? + + cURL is the name of the project. The name is a play on 'Client for URLs', + originally with URL spelled in uppercase to make it obvious it deals with + URLs. The fact it can also be pronounced 'see URL' also helped, it works as + an abbreviation for "Client URL Request Library" or why not the recursive + version: "Curl URL Request Library". + + The cURL project produces two products: + + libcurl + + A free and easy-to-use client-side URL transfer library, supporting DICT, + FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, + POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP. + + libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, + Kerberos, SPNEGO, HTTP form based upload, proxies, cookies, user+password + authentication, file transfer resume, http proxy tunneling and more! + + libcurl is highly portable, it builds and works identically on numerous + platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HP-UX, + IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac + OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF, + Android, Minix, IBM TPF and more... + + libcurl is free, thread-safe, IPv6 compatible, feature rich, well + supported and fast. + + curl + + A command line tool for getting or sending files using URL syntax. + + Since curl uses libcurl, curl supports the same wide range of common + Internet protocols that libcurl does. + + We pronounce curl with an initial k sound. It rhymes with words like girl + and earl. This is a short WAV file to help you: + + https://media.merriam-webster.com/soundc11/c/curl0001.wav + + There are numerous sub-projects and related projects that also use the word + curl in the project names in various combinations, but you should take + notice that this FAQ is directed at the command-line tool named curl (and + libcurl the library), and may therefore not be valid for other curl-related + projects. (There is however a small section for the PHP/CURL in this FAQ.) + + 1.2 What is libcurl? + + libcurl is a reliable and portable library which provides you with an easy + interface to a range of common Internet protocols. + + You can use libcurl for free in your application, be it open source, + commercial or closed-source. + + libcurl is most probably the most portable, most powerful and most often + used C-based multi-platform file transfer library on this planet - be it + open source or commercial. + + 1.3 What is curl not? + + Curl is not a wget clone. That is a common misconception. Never, during + curl's development, have we intended curl to replace wget or compete on its + market. Curl is targeted at single-shot file transfers. + + Curl is not a web site mirroring program. If you want to use curl to mirror + something: fine, go ahead and write a script that wraps around curl to make + it reality (like curlmirror.pl does). + + Curl is not an FTP site mirroring program. Sure, get and send FTP with curl + but if you want systematic and sequential behavior you should write a + script (or write a new program that interfaces libcurl) and do it. + + Curl is not a PHP tool, even though it works perfectly well when used from + or with PHP (when using the PHP/CURL module). + + Curl is not a program for a single operating system. Curl exists, compiles, + builds and runs under a wide range of operating systems, including all + modern Unixes (and a bunch of older ones too), Windows, Amiga, BeOS, OS/2, + OS X, QNX etc. + + 1.4 When will you make curl do XXXX ? + + We love suggestions of what to change in order to make curl and libcurl + better. We do however believe in a few rules when it comes to the future of + curl: + + Curl -- the command line tool -- is to remain a non-graphical command line + tool. If you want GUIs or fancy scripting capabilities, you should look for + another tool that uses libcurl. + + We do not add things to curl that other small and available tools already do + very well at the side. Curl's output can be piped into another program or + redirected to another file for the next program to interpret. + + We focus on protocol related issues and improvements. If you want to do more + magic with the supported protocols than curl currently does, chances are good + we will agree. If you want to add more protocols, we may very well agree. + + If you want someone else to do all the work while you wait for us to + implement it for you, that is not a very friendly attitude. We spend a + considerable time already on maintaining and developing curl. In order to + get more out of us, you should consider trading in some of your time and + effort in return. Simply go to the GitHub repo which resides at + https://github.com/curl/curl, fork the project, and create pull requests + with your proposed changes. + + If you write the code, chances are better that it will get into curl faster. + + 1.5 Who makes curl? + + curl and libcurl are not made by any single individual. Daniel Stenberg is + project leader and main developer, but other persons' submissions are + important and crucial. Anyone can contribute and post their changes and + improvements and have them inserted in the main sources (of course on the + condition that developers agree that the fixes are good). + + The full list of all contributors is found in the docs/THANKS file. + + curl is developed by a community, with Daniel at the wheel. + + 1.6 What do you get for making curl? + + Project cURL is entirely free and open. No person gets paid for developing + curl full time. We do this voluntarily, mostly in our spare time. + Occasionally companies pay individual developers to work on curl, but that's + up to each company and developer. This is not controlled by nor supervised in + any way by the project. + + We still get help from companies. Haxx provides web site, bandwidth, mailing + lists etc, sourceforge.net hosts project services we take advantage from, + like the bug tracker, and GitHub hosts the primary git repository at + https://github.com/curl/curl. Also again, some companies have sponsored + certain parts of the development in the past and I hope some will continue to + do so in the future. + + If you want to support our project, consider a donation or a banner-program + or even better: by helping us with coding, documenting or testing etc. + + 1.7 What about CURL from curl.com? + + During the summer of 2001, curl.com was busy advertising their client-side + programming language for the web, named CURL. + + We are in no way associated with curl.com or their CURL programming + language. + + Our project name curl has been in effective use since 1998. We were not the + first computer related project to use the name "curl" and do not claim any + rights to the name. + + We recognize that we will be living in parallel with curl.com and wish them + every success. + + 1.8 I have a problem whom do I mail? + + Please do not mail any single individual unless you really need to. Keep + curl-related questions on a suitable mailing list. All available mailing + lists are listed in the MANUAL document and online at + https://curl.haxx.se/mail/ + + Keeping curl-related questions and discussions on mailing lists allows + others to join in and help, to share their ideas, to contribute their + suggestions and to spread their wisdom. Keeping discussions on public mailing + lists also allows for others to learn from this (both current and future + users thanks to the web based archives of the mailing lists), thus saving us + from having to repeat ourselves even more. Thanks for respecting this. + + If you have found or simply suspect a security problem in curl or libcurl, + mail curl-security at haxx.se (closed list of receivers, mails are not + disclosed) and tell. Then we can produce a fix in a timely manner before the + flaw is announced to the world, thus lessen the impact the problem will have + on existing users. + + 1.9 Where do I buy commercial support for curl? + + curl is fully open source. It means you can hire any skilled engineer to fix + your curl-related problems. + + We list available alternatives on the curl web site: + https://curl.haxx.se/support.html + + 1.10 How many are using curl? + + It is impossible to tell. + + We don't know how many users that knowingly have installed and use curl. + + We don't know how many users that use curl without knowing that they are in + fact using it. + + We don't know how many users that downloaded or installed curl and then + never use it. + + In May 2012 Daniel did a counting game and came up with a number that may + be completely wrong or somewhat accurate. Over 500 million! + + See https://daniel.haxx.se/blog/2012/05/16/300m-users/ + + 1.11 Why don't you update ca-bundle.crt + + The ca cert bundle that used to be shipped with curl was very outdated and + must be replaced with an up-to-date version by anyone who wants to verify + peers. It is no longer provided by curl. The last curl release that ever + shipped a ca cert bundle was curl 7.18.0. + + In the cURL project we've decided not to attempt to keep this file updated + (or even present anymore) since deciding what to add to a ca cert bundle is + an undertaking we've not been ready to accept, and the one we can get from + Mozilla is perfectly fine so there's no need to duplicate that work. + + Today, with many services performed over HTTPS, every operating system + should come with a default ca cert bundle that can be deemed somewhat + trustworthy and that collection (if reasonably updated) should be deemed to + be a lot better than a private curl version. + + If you want the most recent collection of ca certs that Mozilla Firefox + uses, we recommend that you extract the collection yourself from Mozilla + Firefox (by running 'make ca-bundle), or by using our online service setup + for this purpose: https://curl.haxx.se/docs/caextract.html + + 1.12 I have a problem who can I chat with? + + There's a bunch of friendly people hanging out in the #curl channel on the + IRC network irc.freenode.net. If you're polite and nice, chances are good + that you can get -- or provide -- help instantly. + + 1.13 curl's ECCN number? + + The US government restricts exports of software that contains or uses + cryptography. When doing so, the Export Control Classification Number (ECCN) + is used to identify the level of export control etc. + + Apache Software Foundation gives a good explanation of ECCNs at + https://www.apache.org/dev/crypto.html + + We believe curl's number might be ECCN 5D002, another possibility is + 5D992. It seems necessary to write them (the authority that administers ECCN + numbers), asking to confirm. + + Comprehensible explanations of the meaning of such numbers and how to obtain + them (resp.) are here + + https://www.bis.doc.gov/licensing/exportingbasics.htm + https://www.bis.doc.gov/licensing/do_i_needaneccn.html + + An incomprehensible description of the two numbers above is here + http://www.access.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf + + 1.14 How do I submit my patch? + + When you have made a patch or a change of whatever sort, and want to submit + that to the project, there are a few different ways we prefer: + + o send a patch to the curl-library mailing list. We're many subscribers + there and there are lots of people who can review patches, comment on them + and "receive" them properly. + + o if your patch changes or fixes a bug, you can also opt to submit a bug + report in the bug tracker and attach your patch there. There are less + people involved there. + + Lots of more details are found in the CONTRIBUTE and INTERNALS docs. + + 1.15 How do I port libcurl to my OS? + + Here's a rough step-by-step: + + 1. copy a suitable lib/config-*.h file as a start to lib/config-[youros].h + + 2. edit lib/config-[youros].h to match your OS and setup + + 3. edit lib/curl_setup.h to include config-[youros].h when your OS is + detected by the preprocessor, in the style others already exist + + 4. compile lib/*.c and make them into a library + + +2. Install Related Problems + + 2.1 configure doesn't find OpenSSL even when it is installed + + This may be because of several reasons. + + 2.1.1 native linker doesn't find openssl + + Affected platforms: + Solaris (native cc compiler) + HPUX (native cc compiler) + SGI IRIX (native cc compiler) + SCO UNIX (native cc compiler) + + When configuring curl, I specify --with-ssl. OpenSSL is installed in + /usr/local/ssl Configure reports SSL in /usr/local/ssl, but fails to find + CRYPTO_lock in -lcrypto + + Cause: The cc for this test places the -L/usr/local/ssl/lib AFTER + -lcrypto, so ld can't find the library. This is due to a bug in the GNU + autoconf tool. + + Workaround: Specifying "LDFLAGS=-L/usr/local/ssl/lib" in front of + ./configure places the -L/usr/local/ssl/lib early enough in the command + line to make things work + + 2.1.2 only the libssl lib is missing + + If all include files and the libcrypto lib is present, with only the + libssl being missing according to configure, this is most likely because + a few functions are left out from the libssl. + + If the function names missing include RSA or RSAREF you can be certain + that this is because libssl requires the RSA and RSAREF libs to build. + + See the INSTALL file section that explains how to add those libs to + configure. Make sure that you remove the config.cache file before you + rerun configure with the new flags. + + 2.2 Does curl work/build with other SSL libraries? + + Curl has been written to use a generic SSL function layer internally, and + that SSL functionality can then be provided by one out of many different SSL + backends. + + curl can be built to use one of the following SSL alternatives: OpenSSL, + GnuTLS, yassl, NSS, PolarSSL, axTLS, Secure Transport (native iOS/OS X), + WinSSL (native Windows) or GSKit (native IBM i). They all have their pros + and cons, and we try to maintain a comparison of them here: + https://curl.haxx.se/docs/ssl-compared.html + + 2.3 Where can I find a copy of LIBEAY32.DLL? + + That is an OpenSSL binary built for Windows. + + Curl can be built with OpenSSL to do the SSL stuff. The LIBEAY32.DLL is then + what curl needs on a windows machine to do https:// etc. Check out the curl + web site to find accurate and up-to-date pointers to recent OpenSSL DLLs and + other binary packages. + + 2.4 Does curl support SOCKS (RFC 1928) ? + + Yes, SOCKS 4 and 5 are supported. + + +3. Usage problems + + 3.1 curl: (1) SSL is disabled, https: not supported + + If you get this output when trying to get anything from a https:// server, + it means that the instance of curl/libcurl that you're using was built + without support for this protocol. + + This could've happened if the configure script that was run at build time + couldn't find all libs and include files curl requires for SSL to work. If + the configure script fails to find them, curl is simply built without SSL + support. + + To get the https:// support into a curl that was previously built but that + reports that https:// is not supported, you should dig through the document + and logs and check out why the configure script doesn't find the SSL libs + and/or include files. + + Also, check out the other paragraph in this FAQ labelled "configure doesn't + find OpenSSL even when it is installed". + + 3.2 How do I tell curl to resume a transfer? + + Curl supports resumed transfers both ways on both FTP and HTTP. + Try the -C option. + + 3.3 Why doesn't my posting using -F work? + + You can't arbitrarily use -F or -d, the choice between -F or -d depends on the + HTTP operation you need curl to do and what the web server that will receive + your post expects. + + If the form you're trying to submit uses the type 'multipart/form-data', then + and only then you must use the -F type. In all the most common cases, you + should use -d which then causes a posting with the type + 'application/x-www-form-urlencoded'. + + This is described in some detail in the MANUAL and TheArtOfHttpScripting + documents, and if you don't understand it the first time, read it again + before you post questions about this to the mailing list. Also, try reading + through the mailing list archives for old postings and questions regarding + this. + + 3.4 How do I tell curl to run custom FTP commands? + + You can tell curl to perform optional commands both before and/or after a + file transfer. Study the -Q/--quote option. + + Since curl is used for file transfers, you don't normally use curl to + perform FTP commands without transferring anything. Therefore you must + always specify a URL to transfer to/from even when doing custom FTP + commands, or use -I which implies the "no body" option sent to libcurl. + + 3.5 How can I disable the Accept: */* header? + + You can change all internally generated headers by adding a replacement with + the -H/--header option. By adding a header with empty contents you safely + disable that one. Use -H "Accept:" to disable that specific header. + + 3.6 Does curl support ASP, XML, XHTML or HTML version Y? + + To curl, all contents are alike. It doesn't matter how the page was + generated. It may be ASP, PHP, Perl, shell-script, SSI or plain HTML + files. There's no difference to curl and it doesn't even know what kind of + language that generated the page. + + See also item 3.14 regarding javascript. + + 3.7 Can I use curl to delete/rename a file through FTP? + + Yes. You specify custom FTP commands with -Q/--quote. + + One example would be to delete a file after you have downloaded it: + + curl -O ftp://download.com/coolfile -Q '-DELE coolfile' + + or rename a file after upload: + + curl -T infile ftp://upload.com/dir/ -Q "-RNFR infile" -Q "-RNTO newname" + + 3.8 How do I tell curl to follow HTTP redirects? + + Curl does not follow so-called redirects by default. The Location: header + that informs the client about this is only interpreted if you're using the + -L/--location option. As in: + + curl -L http://redirector.com + + Not all redirects are HTTP ones, see 4.14 + + 3.9 How do I use curl in my favorite programming language? + + There exist many language interfaces/bindings for curl that integrates it + better with various languages. If you are fluid in a script language, you + may very well opt to use such an interface instead of using the command line + tool. + + Find out more about which languages that support curl directly, and how to + install and use them, in the libcurl section of the curl web site: + https://curl.haxx.se/libcurl/ + + All the various bindings to libcurl are made by other projects and people, + outside of the cURL project. The cURL project itself only produces libcurl + with its plain C API. If you don't find anywhere else to ask you can ask + about bindings on the curl-library list too, but be prepared that people on + that list may not know anything about bindings. + + In October 2009, there were interfaces available for the following + languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria, + Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET, + Object-Pascal, OCaml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby, + Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro, + Q, wxwidgets and XBLite. By the time you read this, additional ones may have + appeared! + + 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? + + Curl adheres to the HTTP spec, which basically means you can play with *any* + protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and + XML-RPC are all such ones. You can use -X to set custom requests and -H to + set custom headers (or replace internally generated ones). + + Using libcurl is of course just as good and you'd just use the proper + library options to do the same. + + 3.11 How do I POST with a different Content-Type? + + You can always replace the internally generated headers with -H/--header. + To make a simple HTTP POST with text/xml as content-type, do something like: + + curl -d "datatopost" -H "Content-Type: text/xml" [URL] + + 3.12 Why do FTP specific features over HTTP proxy fail? + + Because when you use a HTTP proxy, the protocol spoken on the network will + be HTTP, even if you specify a FTP URL. This effectively means that you + normally can't use FTP specific features such as FTP upload and FTP quote + etc. + + There is one exception to this rule, and that is if you can "tunnel through" + the given HTTP proxy. Proxy tunneling is enabled with a special option (-p) + and is generally not available as proxy admins usually disable tunneling to + ports other than 443 (which is used for HTTPS access through proxies). + + 3.13 Why does my single/double quotes fail? + + To specify a command line option that includes spaces, you might need to + put the entire option within quotes. Like in: + + curl -d " with spaces " url.com + + or perhaps + + curl -d ' with spaces ' url.com + + Exactly what kind of quotes and how to do this is entirely up to the shell + or command line interpreter that you are using. For most unix shells, you + can more or less pick either single (') or double (") quotes. For + Windows/DOS prompts I believe you're forced to use double (") quotes. + + Please study the documentation for your particular environment. Examples in + the curl docs will use a mix of both of these as shown above. You must + adjust them to work in your environment. + + Remember that curl works and runs on more operating systems than most single + individuals have ever tried. + + 3.14 Does curl support Javascript or PAC (automated proxy config)? + + Many web pages do magic stuff using embedded Javascript. Curl and libcurl + have no built-in support for that, so it will be treated just like any other + contents. + + .pac files are a netscape invention and are sometimes used by organizations + to allow them to differentiate which proxies to use. The .pac contents is + just a Javascript program that gets invoked by the browser and that returns + the name of the proxy to connect to. Since curl doesn't support Javascript, + it can't support .pac proxy configuration either. + + Some workarounds usually suggested to overcome this Javascript dependency: + + Depending on the Javascript complexity, write up a script that translates it + to another language and execute that. + + Read the Javascript code and rewrite the same logic in another language. + + Implement a Javascript interpreter, people have successfully used the + Mozilla Javascript engine in the past. + + Ask your admins to stop this, for a static proxy setup or similar. + + 3.15 Can I do recursive fetches with curl? + + No. curl itself has no code that performs recursive operations, such as + those performed by wget and similar tools. + + There exists wrapper scripts with that functionality (for example the + curlmirror perl script), and you can write programs based on libcurl to do + it, but the command line tool curl itself cannot. + + 3.16 What certificates do I need when I use SSL? + + There are three different kinds of "certificates" to keep track of when we + talk about using SSL-based protocols (HTTPS or FTPS) using curl or libcurl. + + CLIENT CERTIFICATE + + The server you communicate with may require that you can provide this in + order to prove that you actually are who you claim to be. If the server + doesn't require this, you don't need a client certificate. + + A client certificate is always used together with a private key, and the + private key has a pass phrase that protects it. + + SERVER CERTIFICATE + + The server you communicate with has a server certificate. You can and should + verify this certificate to make sure that you are truly talking to the real + server and not a server impersonating it. + + CERTIFICATE AUTHORITY CERTIFICATE ("CA cert") + + You often have several CA certs in a CA cert bundle that can be used to + verify a server certificate that was signed by one of the authorities in the + bundle. curl does not come with a CA cert bundle but most curl installs + provide one. You can also override the default. + + The server certificate verification process is made by using a Certificate + Authority certificate ("CA cert") that was used to sign the server + certificate. Server certificate verification is enabled by default in curl + and libcurl and is often the reason for problems as explained in FAQ entry + 4.12 and the SSLCERTS document + (https://curl.haxx.se/docs/sslcerts.html). Server certificates that are + "self-signed" or otherwise signed by a CA that you do not have a CA cert + for, cannot be verified. If the verification during a connect fails, you are + refused access. You then need to explicitly disable the verification to + connect to the server. + + 3.17 How do I list the root dir of an FTP server? + + There are two ways. The way defined in the RFC is to use an encoded slash + in the first path part. List the "/tmp" dir like this: + + curl ftp://ftp.sunet.se/%2ftmp/ + + or the not-quite-kosher-but-more-readable way, by simply starting the path + section of the URL with a slash: + + curl ftp://ftp.sunet.se//tmp/ + + 3.18 Can I use curl to send a POST/PUT and not wait for a response? + + No. + + But you could easily write your own program using libcurl to do such stunts. + + 3.19 How do I get HTTP from a host using a specific IP address? + + For example, you may be trying out a web site installation that isn't yet in + the DNS. Or you have a site using multiple IP addresses for a given host + name and you want to address a specific one out of the set. + + Set a custom Host: header that identifies the server name you want to reach + but use the target IP address in the URL: + + curl --header "Host: www.example.com" http://127.0.0.1/ + + You can also opt to add faked host name entries to curl with the --resolve + option. That has the added benefit that things like redirects will also work + properly. The above operation would instead be done as: + + curl --resolve www.example.com:80:127.0.0.1 http://www.example.com/ + + 3.20 How to SFTP from my user's home directory? + + Contrary to how FTP works, SFTP and SCP URLs specify the exact directory to + work with. It means that if you don't specify that you want the user's home + directory, you get the actual root directory. + + To specify a file in your user's home directory, you need to use the correct + URL syntax which for sftp might look similar to: + + curl -O -u user:password sftp://example.com/~/file.txt + + and for SCP it is just a different protocol prefix: + + curl -O -u user:password scp://example.com/~/file.txt + + 3.21 Protocol xxx not supported or disabled in libcurl + + When passing on a URL to curl to use, it may respond that the particular + protocol is not supported or disabled. The particular way this error message + is phrased is because curl doesn't make a distinction internally of whether + a particular protocol is not supported (i.e. never got any code added that + knows how to speak that protocol) or if it was explicitly disabled. curl can + be built to only support a given set of protocols, and the rest would then + be disabled or not supported. + + Note that this error will also occur if you pass a wrongly spelled protocol + part as in "htpt://example.com" or as in the less evident case if you prefix + the protocol part with a space as in " http://example.com/". + + 3.22 curl -X gives me HTTP problems + + In normal circumstances, -X should hardly ever be used. + + By default you use curl without explicitly saying which request method to + use when the URL identifies a HTTP transfer. If you just pass in a URL like + "curl http://example.com" it will use GET. If you use -d or -F curl will use + POST, -I will cause a HEAD and -T will make it a PUT. + + If for whatever reason you're not happy with these default choices that curl + does for you, you can override those request methods by specifying -X + [WHATEVER]. This way you can for example send a DELETE by doing "curl -X + DELETE [URL]". + + It is thus pointless to do "curl -XGET [URL]" as GET would be used + anyway. In the same vein it is pointless to do "curl -X POST -d data + [URL]"... But you can make a fun and somewhat rare request that sends a + request-body in a GET request with something like "curl -X GET -d data + [URL]" + + Note that -X doesn't actually change curl's behavior as it only modifies the + actual string sent in the request, but that may of course trigger a + different set of events. + + Accordingly, by using -XPOST on a command line that for example would follow + a 303 redirect, you will effectively prevent curl from behaving + correctly. Be aware. + + +4. Running Problems + + 4.1 Problems connecting to SSL servers. + + It took a very long time before we could sort out why curl had problems to + connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. The + error sometimes showed up similar to: + + 16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233: + + It turned out to be because many older SSL servers don't deal with SSLv3 + requests properly. To correct this problem, tell curl to select SSLv2 from + the command line (-2/--sslv2). + + There have also been examples where the remote server didn't like the SSLv2 + request and instead you had to force curl to use SSLv3 with -3/--sslv3. + + 4.2 Why do I get problems when I use & or % in the URL? + + In general unix shells, the & symbol is treated specially and when used, it + runs the specified command in the background. To safely send the & as a part + of a URL, you should quote the entire URL by using single (') or double (") + quotes around it. Similar problems can also occur on some shells with other + characters, including ?*!$~(){}<>\|;`. When in doubt, quote the URL. + + An example that would invoke a remote CGI that uses &-symbols could be: + + curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl' + + In Windows, the standard DOS shell treats the percent sign specially and you + need to use TWO percent signs for each single one you want to use in the + URL. + + If you want a literal percent sign to be part of the data you pass in a POST + using -d/--data you must encode it as '%25' (which then also needs the + percent sign doubled on Windows machines). + + 4.3 How can I use {, }, [ or ] to specify multiple URLs? + + Because those letters have a special meaning to the shell, to be used in + a URL specified to curl you must quote them. + + An example that downloads two URLs (sequentially) would be: + + curl '{curl,www}.haxx.se' + + To be able to use those characters as actual parts of the URL (without using + them for the curl URL "globbing" system), use the -g/--globoff option: + + curl -g 'www.site.com/weirdname[].html' + + 4.4 Why do I get downloaded data even though the web page doesn't exist? + + Curl asks remote servers for the page you specify. If the page doesn't exist + at the server, the HTTP protocol defines how the server should respond and + that means that headers and a "page" will be returned. That's simply how + HTTP works. + + By using the --fail option you can tell curl explicitly to not get any data + if the HTTP return code doesn't say success. + + 4.5 Why do I get return code XXX from a HTTP server? + + RFC2616 clearly explains the return codes. This is a short transcript. Go + read the RFC for exact details: + + 4.5.1 "400 Bad Request" + + The request could not be understood by the server due to malformed + syntax. The client SHOULD NOT repeat the request without modifications. + + 4.5.2 "401 Unauthorized" + + The request requires user authentication. + + 4.5.3 "403 Forbidden" + + The server understood the request, but is refusing to fulfil it. + Authorization will not help and the request SHOULD NOT be repeated. + + 4.5.4 "404 Not Found" + + The server has not found anything matching the Request-URI. No indication + is given of whether the condition is temporary or permanent. + + 4.5.5 "405 Method Not Allowed" + + The method specified in the Request-Line is not allowed for the resource + identified by the Request-URI. The response MUST include an Allow header + containing a list of valid methods for the requested resource. + + 4.5.6 "301 Moved Permanently" + + If you get this return code and an HTML output similar to this: + +

Moved Permanently

The document has moved here. + + it might be because you request a directory URL but without the trailing + slash. Try the same operation again _with_ the trailing URL, or use the + -L/--location option to follow the redirection. + + 4.6 Can you tell me what error code 142 means? + + All curl error codes are described at the end of the man page, in the + section called "EXIT CODES". + + Error codes that are larger than the highest documented error code means + that curl has exited due to a crash. This is a serious error, and we + appreciate a detailed bug report from you that describes how we could go + ahead and repeat this! + + 4.7 How do I keep user names and passwords secret in Curl command lines? + + This problem has two sides: + + The first part is to avoid having clear-text passwords in the command line + so that they don't appear in 'ps' outputs and similar. That is easily + avoided by using the "-K" option to tell curl to read parameters from a file + or stdin to which you can pass the secret info. curl itself will also + attempt to "hide" the given password by blanking out the option - this + doesn't work on all platforms. + + To keep the passwords in your account secret from the rest of the world is + not a task that curl addresses. You could of course encrypt them somehow to + at least hide them from being read by human eyes, but that is not what + anyone would call security. + + Also note that regular HTTP (using Basic authentication) and FTP passwords + are sent in clear across the network. All it takes for anyone to fetch them + is to listen on the network. Eavesdropping is very easy. Use more secure + authentication methods (like Digest, Negotiate or even NTLM) or consider the + SSL-based alternatives HTTPS and FTPS. + + 4.8 I found a bug! + + It is not a bug if the behavior is documented. Read the docs first. + Especially check out the KNOWN_BUGS file, it may be a documented bug! + + If it is a problem with a binary you've downloaded or a package for your + particular platform, try contacting the person who built the package/archive + you have. + + If there is a bug, read the BUGS document first. Then report it as described + in there. + + 4.9 Curl can't authenticate to the server that requires NTLM? + + NTLM support requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport, or + Microsoft Windows libraries at build-time to provide this functionality. + + NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You + should not use such ones. + + 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! + + Many web servers allow or demand that the administrator configures the + server properly for these requests to work on the web server. + + Some servers seem to support HEAD only on certain kinds of URLs. + + To fully grasp this, try the documentation for the particular server + software you're trying to interact with. This is not anything curl can do + anything about. + + 4.11 Why does my HTTP range requests return the full document? + + Because the range may not be supported by the server, or the server may + choose to ignore it and return the full document anyway. + + 4.12 Why do I get "certificate verify failed" ? + + You invoke curl 7.10 or later to communicate on a https:// URL and get an + error back looking something similar to this: + + curl: (35) SSL: error:14090086:SSL routines: + SSL3_GET_SERVER_CERTIFICATE:certificate verify failed + + Then it means that curl couldn't verify that the server's certificate was + good. Curl verifies the certificate using the CA cert bundle that comes with + the curl installation. + + To disable the verification (which makes it act like curl did before 7.10), + use -k. This does however enable man-in-the-middle attacks. + + If you get this failure but are having a CA cert bundle installed and used, + the server's certificate is not signed by one of the CA's in the bundle. It + might for example be self-signed. You then correct this problem by obtaining + a valid CA cert for the server. Or again, decrease the security by disabling + this check. + + Details are also in the SSLCERTS file in the release archives, found online + here: https://curl.haxx.se/docs/sslcerts.html + + 4.13 Why is curl -R on Windows one hour off? + + Since curl 7.53.0 this issue should be fixed as long as curl was built with + any modern compiler that allows for a 64-bit curl_off_t type. For older + compilers or prior curl versions it may set a time that appears one hour off. + This happens due to a flaw in how Windows stores and uses file modification + times and it is not easily worked around. For more details read this: + https://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting + + 4.14 Redirects work in browser but not with curl! + + curl supports HTTP redirects well (see item 3.8). Browsers generally support + at least two other ways to perform redirects that curl does not: + + Meta tags. You can write a HTML tag that will cause the browser to redirect + to another given URL after a certain time. + + Javascript. You can write a Javascript program embedded in a HTML page that + redirects the browser to another given URL. + + There is no way to make curl follow these redirects. You must either + manually figure out what the page is set to do, or you write a script that + parses the results and fetches the new URL. + + 4.15 FTPS doesn't work + + curl supports FTPS (sometimes known as FTP-SSL) both implicit and explicit + mode. + + When a URL is used that starts with FTPS://, curl assumes implicit SSL on + the control connection and will therefore immediately connect and try to + speak SSL. FTPS:// connections default to port 990. + + To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one + of its related flavours). This is the most common method, and the one + mandated by RFC4217. This kind of connection will then of course use the + standard FTP port 21 by default. + + 4.16 My HTTP POST or PUT requests are slow! + + libcurl makes all POST and PUT requests (except for POST requests with a + very tiny request body) use the "Expect: 100-continue" header. This header + allows the server to deny the operation early so that libcurl can bail out + before having to send any data. This is useful in authentication + cases and others. + + However, many servers don't implement the Expect: stuff properly and if the + server doesn't respond (positively) within 1 second libcurl will continue + and send off the data anyway. + + You can disable libcurl's use of the Expect: header the same way you disable + any header, using -H / CURLOPT_HTTPHEADER, or by forcing it to use HTTP 1.0. + + 4.17 Non-functional connect timeouts + + In most Windows setups having a timeout longer than 21 seconds make no + difference, as it will only send 3 TCP SYN packets and no more. The second + packet sent three seconds after the first and the third six seconds after + the second. No more than three packets are sent, no matter how long the + timeout is set. + + See option TcpMaxConnectRetransmissions on this page: + https://support.microsoft.com/en-us/kb/175523/en-us + + Also, even on non-Windows systems there may run a firewall or anti-virus + software or similar that accepts the connection but does not actually do + anything else. This will make (lib)curl to consider the connection connected + and thus the connect timeout won't trigger. + + 4.18 file:// URLs containing drive letters (Windows, NetWare) + + When using curl to try to download a local file, one might use a URL + in this format: + + file://D:/blah.txt + + You'll find that even if D:\blah.txt does exist, curl returns a 'file + not found' error. + + According to RFC 1738 (https://www.ietf.org/rfc/rfc1738.txt), + file:// URLs must contain a host component, but it is ignored by + most implementations. In the above example, 'D:' is treated as the + host component, and is taken away. Thus, curl tries to open '/blah.txt'. + If your system is installed to drive C:, that will resolve to 'C:\blah.txt', + and if that doesn't exist you will get the not found error. + + To fix this problem, use file:// URLs with *three* leading slashes: + + file:///D:/blah.txt + + Alternatively, if it makes more sense, specify 'localhost' as the host + component: + + file://localhost/D:/blah.txt + + In either case, curl should now be looking for the correct file. + + 4.19 Why doesn't curl return an error when the network cable is unplugged? + + Unplugging a cable is not an error situation. The TCP/IP protocol stack + was designed to be fault tolerant, so even though there may be a physical + break somewhere the connection shouldn't be affected, just possibly + delayed. Eventually, the physical break will be fixed or the data will be + re-routed around the physical problem through another path. + + In such cases, the TCP/IP stack is responsible for detecting when the + network connection is irrevocably lost. Since with some protocols it is + perfectly legal for the client to wait indefinitely for data, the stack may + never report a problem, and even when it does, it can take up to 20 minutes + for it to detect an issue. The curl option --keepalive-time enables + keep-alive support in the TCP/IP stack which makes it periodically probe the + connection to make sure it is still available to send data. That should + reliably detect any TCP/IP network failure. + + But even that won't detect the network going down before the TCP/IP + connection is established (e.g. during a DNS lookup) or using protocols that + don't use TCP. To handle those situations, curl offers a number of timeouts + on its own. --speed-limit/--speed-time will abort if the data transfer rate + falls too low, and --connect-timeout and --max-time can be used to put an + overall timeout on the connection phase or the entire transfer. + + A libcurl-using application running in a known physical environment (e.g. + an embedded device with only a single network connection) may want to act + immediately if its lone network connection goes down. That can be achieved + by having the application monitor the network connection on its own using an + OS-specific mechanism, then signalling libcurl to abort (see also item 5.13). + + 4.20 curl doesn't return error for HTTP non-200 responses! + + Correct. Unless you use -f (--fail). + + When doing HTTP transfers, curl will perform exactly what you're asking it + to do and if successful it will not return an error. You can use curl to + test your web server's "file not found" page (that gets 404 back), you can + use it to check your authentication protected web pages (that gets a 401 + back) and so on. + + The specific HTTP response code does not constitute a problem or error for + curl. It simply sends and delivers HTTP as you asked and if that worked, + everything is fine and dandy. The response code is generally providing more + higher level error information that curl doesn't care about. The error was + not in the HTTP transfer. + + If you want your command line to treat error codes in the 400 and up range + as errors and thus return a non-zero value and possibly show an error + message, curl has a dedicated option for that: -f (CURLOPT_FAILONERROR in + libcurl speak). + + You can also use the -w option and the variable %{response_code} to extract + the exact response code that was returned in the response. + + 4.21 Why is there a HTTP/1.1 in my HTTP/2 request? + + If you use verbose to see the HTTP request when you send off a HTTP/2 + request, it will still say 1.1. + + The reason for this is that we first generate the request to send using the + old 1.1 style and show that request in the verbose output, and then we + convert it over to the binary header-compressed HTTP/2 style. The actual + "1.1" part from that request is then not actually used in the transfer. + The binary HTTP/2 headers are not human readable. + +5. libcurl Issues + + 5.1 Is libcurl thread-safe? + + Yes. + + We have written the libcurl code specifically adjusted for multi-threaded + programs. libcurl will use thread-safe functions instead of non-safe ones if + your system has such. Note that you must never share the same handle in + multiple threads. + + There may be some exceptions to thread safety depending on how libcurl was + built. Please review the guidelines for thread safety to learn more: + https://curl.haxx.se/libcurl/c/threadsafe.html + + 5.2 How can I receive all data into a large memory chunk? + + [ See also the examples/getinmemory.c source ] + + You are in full control of the callback function that gets called every time + there is data received from the remote server. You can make that callback do + whatever you want. You do not have to write the received data to a file. + + One solution to this problem could be to have a pointer to a struct that you + pass to the callback function. You set the pointer using the + CURLOPT_WRITEDATA option. Then that pointer will be passed to the callback + instead of a FILE * to a file: + + /* imaginary struct */ + struct MemoryStruct { + char *memory; + size_t size; + }; + + /* imaginary callback function */ + size_t + WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) + { + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)data; + + mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); + if (mem->memory) { + memcpy(&(mem->memory[mem->size]), ptr, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + } + return realsize; + } + + 5.3 How do I fetch multiple files with libcurl? + + libcurl has excellent support for transferring multiple files. You should + just repeatedly set new URLs with curl_easy_setopt() and then transfer it + with curl_easy_perform(). The handle you get from curl_easy_init() is not + only reusable, but you're even encouraged to reuse it if you can, as that + will enable libcurl to use persistent connections. + + 5.4 Does libcurl do Winsock initialization on win32 systems? + + Yes, if told to in the curl_global_init() call. + + 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? + + Yes, but you cannot open a FILE * and pass the pointer to a DLL and have + that DLL use the FILE * (as the DLL and the client application cannot access + each others' variable memory areas). If you set CURLOPT_WRITEDATA you must + also use CURLOPT_WRITEFUNCTION as well to set a function that writes the + file, even if that simply writes the data to the specified FILE *. + Similarly, if you use CURLOPT_READDATA you must also specify + CURLOPT_READFUNCTION. + + 5.6 What about Keep-Alive or persistent connections? + + curl and libcurl have excellent support for persistent connections when + transferring several files from the same server. Curl will attempt to reuse + connections for all URLs specified on the same command line/config file, and + libcurl will reuse connections for all transfers that are made using the + same libcurl handle. + + When you use the easy interface the connection cache is kept within the easy + handle. If you instead use the multi interface, the connection cache will be + kept within the multi handle and will be shared among all the easy handles + that are used within the same multi handle. + + 5.7 Link errors when building libcurl on Windows! + + You need to make sure that your project, and all the libraries (both static + and dynamic) that it links against, are compiled/linked against the same run + time library. + + This is determined by the /MD, /ML, /MT (and their corresponding /M?d) + options to the command line compiler. /MD (linking against MSVCRT dll) seems + to be the most commonly used option. + + When building an application that uses the static libcurl library, you must + add -DCURL_STATICLIB to your CFLAGS. Otherwise the linker will look for + dynamic import symbols. If you're using Visual Studio, you need to instead + add CURL_STATICLIB in the "Preprocessor Definitions" section. + + If you get linker error like "unknown symbol __imp__curl_easy_init ..." you + have linked against the wrong (static) library. If you want to use the + libcurl.dll and import lib, you don't need any extra CFLAGS, but use one of + the import libraries below. These are the libraries produced by the various + lib/Makefile.* files: + + Target: static lib. import lib for libcurl*.dll. + ----------------------------------------------------------- + MingW: libcurl.a libcurldll.a + MSVC (release): libcurl.lib libcurl_imp.lib + MSVC (debug): libcurld.lib libcurld_imp.lib + Borland: libcurl.lib libcurl_imp.lib + + 5.8 libcurl.so.X: open failed: No such file or directory + + This is an error message you might get when you try to run a program linked + with a shared version of libcurl and your run-time linker (ld.so) couldn't + find the shared library named libcurl.so.X. (Where X is the number of the + current libcurl ABI, typically 3 or 4). + + You need to make sure that ld.so finds libcurl.so.X. You can do that + multiple ways, and it differs somewhat between different operating systems, + but they are usually: + + * Add an option to the linker command line that specify the hard-coded path + the run-time linker should check for the lib (usually -R) + + * Set an environment variable (LD_LIBRARY_PATH for example) where ld.so + should check for libs + + * Adjust the system's config to check for libs in the directory where you've + put the dir (like Linux's /etc/ld.so.conf) + + 'man ld.so' and 'man ld' will tell you more details + + 5.9 How does libcurl resolve host names? + + libcurl supports a large a number of different name resolve functions. One + of them is picked at build-time and will be used unconditionally. Thus, if + you want to change name resolver function you must rebuild libcurl and tell + it to use a different function. + + - The non-IPv6 resolver that can use one of four different host name resolve + calls (depending on what your system supports): + + A - gethostbyname() + B - gethostbyname_r() with 3 arguments + C - gethostbyname_r() with 5 arguments + D - gethostbyname_r() with 6 arguments + + - The IPv6-resolver that uses getaddrinfo() + + - The c-ares based name resolver that uses the c-ares library for resolves. + Using this offers asynchronous name resolves. + + - The threaded resolver (default option on Windows). It uses: + + A - gethostbyname() on plain IPv4 hosts + B - getaddrinfo() on IPv6 enabled hosts + + Also note that libcurl never resolves or reverse-lookups addresses given as + pure numbers, such as 127.0.0.1 or ::1. + + 5.10 How do I prevent libcurl from writing the response to stdout? + + libcurl provides a default built-in write function that writes received data + to stdout. Set the CURLOPT_WRITEFUNCTION to receive the data, or possibly + set CURLOPT_WRITEDATA to a different FILE * handle. + + 5.11 How do I make libcurl not receive the whole HTTP response? + + You make the write callback (or progress callback) return an error and + libcurl will then abort the transfer. + + 5.12 Can I make libcurl fake or hide my real IP address? + + No. libcurl operates on a higher level. Besides, faking IP address would + imply sending IP packets with a made-up source address, and then you normally + get a problem with receiving the packet sent back as they would then not be + routed to you! + + If you use a proxy to access remote sites, the sites will not see your local + IP address but instead the address of the proxy. + + Also note that on many networks NATs or other IP-munging techniques are used + that makes you see and use a different IP address locally than what the + remote server will see you coming from. You may also consider using + https://www.torproject.org/ . + + 5.13 How do I stop an ongoing transfer? + + With the easy interface you make sure to return the correct error code from + one of the callbacks, but none of them are instant. There is no function you + can call from another thread or similar that will stop it immediately. + Instead, you need to make sure that one of the callbacks you use returns an + appropriate value that will stop the transfer. Suitable callbacks that you + can do this with include the progress callback, the read callback and the + write callback. + + If you're using the multi interface, you can also stop a transfer by + removing the particular easy handle from the multi stack at any moment you + think the transfer is done or when you wish to abort the transfer. + + 5.14 Using C++ non-static functions for callbacks? + + libcurl is a C library, it doesn't know anything about C++ member functions. + + You can overcome this "limitation" with relative ease using a static + member function that is passed a pointer to the class: + + // f is the pointer to your object. + static size_t YourClass::func(void *buffer, size_t sz, size_t n, void *f) + { + // Call non-static member function. + static_cast(f)->nonStaticFunction(); + } + + // This is how you pass pointer to the static function: + curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass::func); + curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this); + + 5.15 How do I get an FTP directory listing? + + If you end the FTP URL you request with a slash, libcurl will provide you + with a directory listing of that given directory. You can also set + CURLOPT_CUSTOMREQUEST to alter what exact listing command libcurl would use + to list the files. + + The follow-up question tends to be how is a program supposed to parse the + directory listing. How does it know what's a file and what's a dir and what's + a symlink etc. If the FTP server supports the MLSD command then it will + return data in a machine-readable format that can be parsed for type. The + types are specified by RFC3659 section 7.5.1. If MLSD is not supported then + you have to work with what you're given. The LIST output format is entirely + at the server's own liking and the NLST output doesn't reveal any types and + in many cases doesn't even include all the directory entries. Also, both LIST + and NLST tend to hide unix-style hidden files (those that start with a dot) + by default so you need to do "LIST -a" or similar to see them. + + Example - List only directories. + ftp.funet.fi supports MLSD and ftp.kernel.org does not: + + curl -s ftp.funet.fi/pub/ -X MLSD | \ + perl -lne 'print if s/(?:^|;)type=dir;[^ ]+ (.+)$/$1/' + + curl -s ftp.kernel.org/pub/linux/kernel/ | \ + perl -lne 'print if s/^d[-rwx]{9}(?: +[^ ]+){7} (.+)$/$1/' + + If you need to parse LIST output in libcurl one such existing + list parser is available at https://cr.yp.to/ftpparse.html Versions of + libcurl since 7.21.0 also provide the ability to specify a wildcard to + download multiple files from one FTP directory. + + 5.16 I want a different time-out! + + Time and time again users realize that CURLOPT_TIMEOUT and + CURLOPT_CONNECTIMEOUT are not sufficiently advanced or flexible to cover all + the various use cases and scenarios applications end up with. + + libcurl offers many more ways to time-out operations. A common alternative + is to use the CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME options to + specify the lowest possible speed to accept before to consider the transfer + timed out. + + The most flexible way is by writing your own time-out logic and using + CURLOPT_XFERINFOFUNCTION (perhaps in combination with other callbacks) and + use that to figure out exactly when the right condition is met when the + transfer should get stopped. + + 5.17 Can I write a server with libcurl? + + No. libcurl offers no functions or building blocks to build any kind of + internet protocol server. libcurl is only a client-side library. For server + libraries, you need to continue your search elsewhere but there exist many + good open source ones out there for most protocols you could possibly want a + server for. And there are really good stand-alone ones that have been tested + and proven for many years. There's no need for you to reinvent them! + + 5.18 Does libcurl use threads? + + Put simply: no, libcurl will execute in the same thread you call it in. All + callbacks will be called in the same thread as the one you call libcurl in. + + If you want to avoid your thread to be blocked by the libcurl call, you make + sure you use the non-blocking API which will do transfers asynchronously - + but still in the same single thread. + + libcurl will potentially internally use threads for name resolving, if it + was built to work like that, but in those cases it'll create the child + threads by itself and they will only be used and then killed internally by + libcurl and never exposed to the outside. + +6. License Issues + + Curl and libcurl are released under a MIT/X derivate license. The license is + very liberal and should not impose a problem for your project. This section + is just a brief summary for the cases we get the most questions. (Parts of + this section was much enhanced by Bjorn Reese.) + + We are not lawyers and this is not legal advice. You should probably consult + one if you want true and accurate legal insights without our prejudice. Note + especially that this section concerns the libcurl license only; compiling in + features of libcurl that depend on other libraries (e.g. OpenSSL) may affect + the licensing obligations of your application. + + 6.1 I have a GPL program, can I use the libcurl library? + + Yes! + + Since libcurl may be distributed under the MIT/X derivate license, it can be + used together with GPL in any software. + + 6.2 I have a closed-source program, can I use the libcurl library? + + Yes! + + libcurl does not put any restrictions on the program that uses the library. + + 6.3 I have a BSD licensed program, can I use the libcurl library? + + Yes! + + libcurl does not put any restrictions on the program that uses the library. + + 6.4 I have a program that uses LGPL libraries, can I use libcurl? + + Yes! + + The LGPL license doesn't clash with other licenses. + + 6.5 Can I modify curl/libcurl for my program and keep the changes secret? + + Yes! + + The MIT/X derivate license practically allows you to do almost anything with + the sources, on the condition that the copyright texts in the sources are + left intact. + + 6.6 Can you please change the curl/libcurl license to XXXX? + + No. + + We have carefully picked this license after years of development and + discussions and a large amount of people have contributed with source code + knowing that this is the license we use. This license puts the restrictions + we want on curl/libcurl and it does not spread to other programs or + libraries that use it. It should be possible for everyone to use libcurl or + curl in their projects, no matter what license they already have in use. + + 6.7 What are my obligations when using libcurl in my commercial apps? + + Next to none. All you need to adhere to is the MIT-style license (stated in + the COPYING file) which basically says you have to include the copyright + notice in "all copies" and that you may not use the copyright holder's name + when promoting your software. + + You do not have to release any of your source code. + + You do not have to reveal or make public any changes to the libcurl source + code. + + You do not have to broadcast to the world that you are using libcurl within + your app. + + All we ask is that you disclose "the copyright notice and this permission + notice" somewhere. Most probably like in the documentation or in the section + where other third party dependencies already are mentioned and acknowledged. + + As can be seen here: https://curl.haxx.se/docs/companies.html and elsewhere, + more and more companies are discovering the power of libcurl and take + advantage of it even in commercial environments. + + +7. PHP/CURL Issues + + 7.1 What is PHP/CURL? + + The module for PHP that makes it possible for PHP programs to access curl- + functions from within PHP. + + In the cURL project we call this module PHP/CURL to differentiate it from + curl the command line tool and libcurl the library. The PHP team however + does not refer to it like this (for unknown reasons). They call it plain + CURL (often using all caps) or sometimes ext/curl, but both cause much + confusion to users which in turn gives us a higher question load. + + 7.2 Who wrote PHP/CURL? + + PHP/CURL was initially written by Sterling Hughes. + + 7.3 Can I perform multiple requests using the same handle? + + Yes - at least in PHP version 4.3.8 and later (this has been known to not + work in earlier versions, but the exact version when it started to work is + unknown to me). + + After a transfer, you just set new options in the handle and make another + transfer. This will make libcurl re-use the same connection if it can. + + 7.4 Does PHP/CURL have dependencies? + + PHP/CURL is a module that comes with the regular PHP package. It depends on + and uses libcurl, so you need to have libcurl installed properly before + PHP/CURL can be used. diff --git a/docs/FEATURES b/docs/FEATURES new file mode 100644 index 00000000..39ac3904 --- /dev/null +++ b/docs/FEATURES @@ -0,0 +1,206 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +FEATURES + +curl tool + - config file support + - multiple URLs in a single command line + - range "globbing" support: [0-13], {one,two,three} + - multiple file upload on a single command line + - custom maximum transfer rate + - redirectable stderr + - metalink support (*13) + +libcurl + - full URL syntax with no length limit + - custom maximum download time + - custom least download speed acceptable + - custom output result after completion + - guesses protocol from host name unless specified + - uses .netrc + - progress bar with time statistics while downloading + - "standard" proxy environment variables support + - compiles on win32 (reported builds on 40+ operating systems) + - selectable network interface for outgoing traffic + - IPv6 support on unix and Windows + - persistent connections + - socks 4 + 5 support, with or without local name resolving + - supports user name and password in proxy environment variables + - operations through proxy "tunnel" (using CONNECT) + - support for large files (>2GB and >4GB) during upload and download + - replaceable memory functions (malloc, free, realloc, etc) + - asynchronous name resolving (*6) + - both a push and a pull style interface + - international domain names (*11) + +HTTP + - HTTP/1.1 compliant (optionally uses 1.0) + - GET + - PUT + - HEAD + - POST + - Pipelining + - multipart formpost (RFC1867-style) + - authentication: Basic, Digest, NTLM (*9) and Negotiate (SPNEGO) (*3) + to server and proxy + - resume (both GET and PUT) + - follow redirects + - maximum amount of redirects to follow + - custom HTTP request + - cookie get/send fully parsed + - reads/writes the netscape cookie file format + - custom headers (replace/remove internally generated headers) + - custom user-agent string + - custom referrer string + - range + - proxy authentication + - time conditions + - via http-proxy + - retrieve file modification date + - Content-Encoding support for deflate and gzip + - "Transfer-Encoding: chunked" support in uploads + - data compression (*12) + - HTTP/2 (*5) + +HTTPS (*1) + - (all the HTTP features) + - using client certificates + - verify server certificate + - via http-proxy + - select desired encryption + - force usage of a specific SSL version (SSLv2 (*7), SSLv3 (*10) or TLSv1) + +FTP + - download + - authentication + - Kerberos 5 (*14) + - active/passive using PORT, EPRT, PASV or EPSV + - single file size information (compare to HTTP HEAD) + - 'type=' URL support + - dir listing + - dir listing names-only + - upload + - upload append + - upload via http-proxy as HTTP PUT + - download resume + - upload resume + - custom ftp commands (before and/or after the transfer) + - simple "range" support + - via http-proxy + - all operations can be tunneled through a http-proxy + - customizable to retrieve file modification date + - no dir depth limit + +FTPS (*1) + - implicit ftps:// support that use SSL on both connections + - explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain ftp:// + connection to use SSL for both or one of the connections + +SCP (*8) + - both password and public key auth + +SFTP (*8) + - both password and public key auth + - with custom commands sent before/after the transfer + +TFTP + - download + - upload + +TELNET + - connection negotiation + - custom telnet options + - stdin/stdout I/O + +LDAP (*2) + - full LDAP URL support + +DICT + - extended DICT URL support + +FILE + - URL support + - upload + - resume + +SMB + - SMBv1 over TCP and SSL + - download + - upload + - authentication with NTLMv1 + +SMTP + - authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9), Kerberos 5 + (*4) and External. + - send e-mails + - mail from support + - mail size support + - mail auth support for trusted server-to-server relaying + - multiple recipients + - via http-proxy + +SMTPS (*1) + - implicit smtps:// support + - explicit "STARTTLS" usage to "upgrade" plain smtp:// connections to use SSL + - via http-proxy + +POP3 + - authentication: Clear Text, APOP and SASL + - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9), + Kerberos 5 (*4) and External. + - list e-mails + - retrieve e-mails + - enhanced command support for: CAPA, DELE, TOP, STAT, UIDL and NOOP via + custom requests + - via http-proxy + +POP3S (*1) + - implicit pop3s:// support + - explicit "STLS" usage to "upgrade" plain pop3:// connections to use SSL + - via http-proxy + +IMAP + - authentication: Clear Text and SASL + - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9), + Kerberos 5 (*4) and External. + - list the folders of a mailbox + - select a mailbox with support for verifying the UIDVALIDITY + - fetch e-mails with support for specifying the UID and SECTION + - upload e-mails via the append command + - enhanced command support for: EXAMINE, CREATE, DELETE, RENAME, STATUS, + STORE, COPY and UID via custom requests + - via http-proxy + +IMAPS (*1) + - implicit imaps:// support + - explicit "STARTTLS" usage to "upgrade" plain imap:// connections to use SSL + - via http-proxy + +FOOTNOTES +========= + + *1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native + Windows), Secure Transport (native iOS/OS X) or GSKit (native IBM i) + *2 = requires OpenLDAP or WinLDAP + *3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or + SSPI (native Windows) + *4 = requires a GSS-API implementation, however, only Windows SSPI is + currently supported + *5 = requires nghttp2 and possibly a recent TLS library + *6 = requires c-ares + *7 = requires OpenSSL, NSS, GSKit, WinSSL or Secure Transport; GnuTLS, for + example, only supports SSLv3 and TLSv1 + *8 = requires libssh2 + *9 = requires OpenSSL, GnuTLS, mbedTLS, NSS, yassl, Secure Transport or SSPI + (native Windows) + *10 = requires any of the SSL libraries in (*1) above other than axTLS, which + does not support SSLv3 + *11 = requires libidn or Windows + *12 = requires libz + *13 = requires libmetalink, and either an Apple or Microsoft operating + system, or OpenSSL, or GnuTLS, or NSS + *14 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) diff --git a/docs/GOVERNANCE.md b/docs/GOVERNANCE.md new file mode 100644 index 00000000..6de2eff4 --- /dev/null +++ b/docs/GOVERNANCE.md @@ -0,0 +1,144 @@ +# Decision making in the curl project + +A rough guide to how we make decisions and who does what. + +## BDFL + +This project was started by and has to some extent been pushed forward over +the years with Daniel Stenberg as the driving force. It matches a standard +BDFL (Benevolent Dictator For Life) style project. + +This setup has been used due to convenience and the fact that is has worked +fine this far. It is not because someone thinks of it as a superior project +leadership model. It will also only continue working as long as Daniel manages +to listen in to what the project and the general user population wants and +expects from us. + +## Legal entity + +There is no legal entity. The curl project is just a bunch of people scattered +around the globe with the common goal to produce source code that creates +great products. + +The copyrights in the project are owned by the individuals and organizations +that wrote those parts of the code. + +## Decisions + +The curl project is not a democracy, but everyone is entitled to state their +opinion and may argue for their sake within the community. + +All and any changes that have been done or will be done are eligible to bring +up for discussion, to object to or to praise. Ideally, we find consensus for +the appropriate way forward in any given situation or challenge. + +If there is no obvious consensus, a maintainer who's knowledgeable in the +specific area will take an "executive" decision that they think is the right +for the project. + +## Key roles + +### Maintainers + +A maintainer in the curl project is an individual who has been given +permissions to push commits to one of the git repositories. + +Maintainers are free to push commits to the repositories at their own will. +Maintainers are however expected to listen to feedback from users and any +change that is non-trivial in size or nature *should* be brought to the +project as a PR to allow others to comment/object before merge. + +### Former maintainers + +A maintainer who stops being active in the project will at some point get +their push permissions removed. We do this for security reasons but also to +make sure that we always have the list of maintainers as "the team that push +stuff to curl". + +Getting push permissions removed is not a punishment. Everyone who ever worked +on maintaining curl is considered a hero, for all time hereafter. + +### Security team members + +We have a security team. That's the team of people who are subscribed to the +curl-security mailing list; the receivers of security reports from users and +developers. This list of people will vary over time but should be skilled +developers familiar with the curl project. + +The security team works best when it consists of a small set of active +persons. We invite new members when the team seems to need it, and we also +expect to retire security team members as they "drift off" from the project or +just find themselves unable to perform their duties there. + +### Server admins + +We run a web server, a mailing list and more on the curl project's primary +server. That physical machine is owned and run by Haxx. Daniel is the primary +admin of all things curl related server stuff, but Björn Stenberg and Linus +Feltzing serve as backup admins for when Daniel is gone or unable. + +The primary server is paid for by Haxx. The machine is physically located in a +server bunker in Stockholm Sweden, operated by the company Portlane. + +The web site contents are served to the web via Fastly and Daniel is the +primary curl contact with Fastly. + +### BDFL + +That's Daniel. + +# Maintainers + +A curl maintainer is a project volunteer who has the authority and rights to +merge changes into a git repository in the curl project. + +Anyone can aspire to become a curl maintainer. + +### Duties + +There are no mandatory duties. We hope and wish that maintainers consider +reviewing patches and help merching them, especially when the changes are +within the area of personal expertise and experience. + +### Requirements + +- only merge code that meets our quality and style guide requirements. +- *never* merge code without doing a PR first, unless the change is "trivial" +- if in doubt, ask for input/feedback from others + +### Recommendations + +- please enable 2fa on your github account to reduce risk of malicious sourc + code tampering +- consider enabling signed git commits for additional verification of changes + +### Merge advice + +When you're merging patches/PRs... + +- make sure the commit messages follow our template +- squash patch sets into a few logical commits even if the PR didn't, if + necessary +- avoid the "merge" button on github, do it "manually" instead to get full + control and full audit trail (github leaves out you as "Committer:") +- remember to credit the reporter and the helpers! + +## Who are maintainers? + +The [list of maintainers](https://github.com/orgs/curl/people). Be aware that +the level of presence and activity in the project vary greatly between +different individuals and over time. + +### Become a maintainer? + +If you think you can help making the project better by shouldering some +maintaining responsibilities, then please get in touch. + +You will be expected to be familiar with the curl project and its ways of +working. You need to have gotten a few quality patches merged as a proof of +this. + +### Stop being a maintainer + +If you (appear to) not be active in the project anymore, you may be removed as +a maintainer. Thank you for your service! diff --git a/docs/HELP-US.md b/docs/HELP-US.md new file mode 100644 index 00000000..aae2b9f5 --- /dev/null +++ b/docs/HELP-US.md @@ -0,0 +1,70 @@ +# How to get started helping out in the curl project + +We are always in need of more help. If you are new to the project and are +looking for ways to contribute and help out, this document aims to give a few +good starting points. + +A good idea is to start by subscribing to the [curl-library mailing +list](https://cool.haxx.se/mailman/listinfo/curl-library) to keep track of the +current discussion topics. + +## Scratch your own itch + +One of the best ways is to start working on any problems or issues you have +found yourself or perhaps got annoyed at in the past. It can be a spelling +error in an error text or a weirdly phrased section in a man page. Hunt it +down and report the bug. Or make your first pull request with a fix for that. + +## Help wanted + +In the issue tracker we occasionally mark bugs with [help +wanted](https://github.com/curl/curl/labels/help%20wanted), as a sign that the +bug is acknowledged to exist and that there's nobody known to work on this +issue for the moment. Those are bugs that are fine to "grab" and provide a +pull request for. The complexity level of these will of course vary, so pick +one that piques your interest. + +## Work on known bugs + +Some bugs are known and haven't yet received attention and work enough to get +fixed. We collect such known existing flaws in the +[KNOWN_BUGS](https://curl.haxx.se/docs/knownbugs.html) page. Many of them link +to the original bug report with some additional details, but some may also +have aged a bit and may require some verification that the bug still exists in +the same way and that what was said about it in the past is still valid. + +## Fix autobuild problems + +On the [autobuilds page](https://curl.haxx.se/dev/builds.html) we show a +collection of test results from the automatic curl build and tests that are +performed by volunteers. Fixing compiler warnings and errors shown there is +something we value greatly. Also, if you own or run systems or architectures +that aren't already tested in the autobuilds, we also appreciate more +volunteers running builds automatically to help us keep curl portable. + +## TODO items + +Ideas for features and functions that we have considered worthwhile to +implement and provide are kept in the +[TODO](https://curl.haxx.se/docs/todo.html) file. Some of the ideas are +rough. Some are well thought out. Some probably aren't really suitable +anymore. + +Before you invest a lot of time on a TODO item, do bring it up for discussion +on the mailing list. For discussion on applicability but also for ideas and +brainstorming on specific ways to do the implementation etc. + +## You decide + +You can also come up with a completely new thing you think we should do. Or +not do. Or fix. Or add to the project. You then either bring it to the mailing +list first to see if people will shoot down the idea at once, or you bring a +first draft of the idea as a pull request and take the discussion there around +the specific implementation. Either way is fine. + +## CONTRIBUTE + +We offer [guidelines](https://curl.haxx.se/dev/contribute.html) that are +suitable to be familiar with before you decide to contribute to curl. If +you're used to open source development, you'll probably not find many +surprises in there. diff --git a/docs/HISTORY.md b/docs/HISTORY.md new file mode 100644 index 00000000..a84ad8f1 --- /dev/null +++ b/docs/HISTORY.md @@ -0,0 +1,295 @@ +How curl Became Like This +========================= + +Towards the end of 1996, Daniel Stenberg was spending time writing an IRC bot +for an Amiga related channel on EFnet. He then came up with the idea to make +currency-exchange calculations available to Internet Relay Chat (IRC) +users. All the necessary data were published on the Web; he just needed to +automate their retrieval. + +Daniel simply adopted an existing command-line open-source tool, httpget, that +Brazilian Rafael Sagula had written and recently released version 0.1 of. After +a few minor adjustments, it did just what he needed. + +1997 +---- + +HttpGet 1.0 was released on April 8th 1997 with brand new HTTP proxy support. + +We soon found and fixed support for getting currencies over GOPHER. Once FTP +download support was added, the name of the project was changed and urlget 2.0 +was released in August 1997. The http-only days were already passed. + +1998 +---- + +The project slowly grew bigger. When upload capabilities were added and the +name once again was misleading, a second name change was made and on March 20, +1998 curl 4 was released. (The version numbering from the previous names was +kept.) + +(Unrelated to this project a company called Curl Corporation registered a US +trademark on the name "CURL" on May 18 1998. That company had then already +registered the curl.com domain back in November of the previous year. All this +was revealed to us much later.) + +SSL support was added, powered by the SSLeay library. + +August: first announcement of curl on freshmeat.net. + +October: with the curl 4.9 release and the introduction of cookie support, +curl was no longer released under the GPL license. Now we're at 4000 lines of +code, we switched over to the MPL license to restrict the effects of +"copyleft". + +November: configure script and reported successful compiles on several +major operating systems. The never-quite-understood -F option was added and +curl could now simulate quite a lot of a browser. TELNET support was added. + +Curl 5 was released in December 1998 and introduced the first ever curl man +page. People started making Linux RPM packages out of it. + +1999 +---- + +January: DICT support added. + +OpenSSL took over and SSLeay was abandoned. + +May: first Debian package. + +August: LDAP:// and FILE:// support added. The curl web site gets 1300 visits +weekly. Moved site to curl.haxx.nu. + +September: Released curl 6.0. 15000 lines of code. + +December 28: added the project on Sourceforge and started using its services +for managing the project. + +2000 +---- + +Spring: major internal overhaul to provide a suitable library interface. +The first non-beta release was named 7.1 and arrived in August. This offered +the easy interface and turned out to be the beginning of actually getting +other software and programs to be based on and powered by libcurl. Almost +20000 lines of code. + +June: the curl site moves to "curl.haxx.se" + +August, the curl web site gets 4000 visits weekly. + +The PHP guys adopted libcurl already the same month, when the first ever third +party libcurl binding showed up. CURL has been a supported module in PHP since +the release of PHP 4.0.2. This would soon get followers. More than 16 +different bindings exist at the time of this writing. + +September: kerberos4 support was added. + +November: started the work on a test suite for curl. It was later re-written +from scratch again. The libcurl major SONAME number was set to 1. + +2001 +---- + +January: Daniel released curl 7.5.2 under a new license again: MIT (or +MPL). The MIT license is extremely liberal and can be combined with GPL +in other projects. This would finally put an end to the "complaints" from +people involved in GPLed projects that previously were prohibited from using +libcurl while it was released under MPL only. (Due to the fact that MPL is +deemed "GPL incompatible".) + +March 22: curl supports HTTP 1.1 starting with the release of 7.7. This +also introduced libcurl's ability to do persistent connections. 24000 lines of +code. The libcurl major SONAME number was bumped to 2 due to this overhaul. +The first experimental ftps:// support was added. + +August: curl is bundled in Mac OS X, 10.1. It was already becoming more and +more of a standard utility of Linux distributions and a regular in the BSD +ports collections. The curl web site gets 8000 visits weekly. Curl Corporation +contacted Daniel to discuss "the name issue". After Daniel's reply, they have +never since got back in touch again. + +September: libcurl 7.9 introduces cookie jar and curl_formadd(). During the +forthcoming 7.9.x releases, we introduced the multi interface slowly and +without many whistles. + +2002 +---- + +June: the curl web site gets 13000 visits weekly. curl and libcurl is +35000 lines of code. Reported successful compiles on more than 40 combinations +of CPUs and operating systems. + +To estimate number of users of the curl tool or libcurl library is next to +impossible. Around 5000 downloaded packages each week from the main site gives +a hint, but the packages are mirrored extensively, bundled with numerous OS +distributions and otherwise retrieved as part of other software. + +September: with the release of curl 7.10 it is released under the MIT license +only. + +2003 +---- + +January: Started working on the distributed curl tests. The autobuilds. + +February: the curl site averages at 20000 visits weekly. At any given moment, +there's an average of 3 people browsing the curl.haxx.se site. + +Multiple new authentication schemes are supported: Digest (May), NTLM (June) +and Negotiate (June). + +November: curl 7.10.8 is released. 45000 lines of code. ~55000 unique visitors +to the curl.haxx.se site. Five official web mirrors. + +December: full-fledged SSL for FTP is supported. + +2004 +---- + +January: curl 7.11.0 introduced large file support. + +June: curl 7.12.0 introduced IDN support. 10 official web mirrors. + +This release bumped the major SONAME to 3 due to the removal of the +curl_formparse() function + +August: Curl and libcurl 7.12.1 + + Public curl release number: 82 + Releases counted from the very beginning: 109 + Available command line options: 96 + Available curl_easy_setopt() options: 120 + Number of public functions in libcurl: 36 + Amount of public web site mirrors: 12 + Number of known libcurl bindings: 26 + +2005 +---- + +April: GnuTLS can now optionally be used for the secure layer when curl is +built. + +April: Added the multi_socket() API + +September: TFTP support was added. + +More than 100,000 unique visitors of the curl web site. 25 mirrors. + +December: security vulnerability: libcurl URL Buffer Overflow + +2006 +---- + +January: We dropped support for Gopher. We found bugs in the implementation +that turned out to have been introduced years ago, so with the conclusion that +nobody had found out in all this time we removed it instead of fixing it. + +March: security vulnerability: libcurl TFTP Packet Buffer Overflow + +September: The major SONAME number for libcurl was bumped to 4 due to the +removal of ftp third party transfer support. + +November: Added SCP and SFTP support + +2007 +---- + +February: Added support for the Mozilla NSS library to do the SSL/TLS stuff + +July: security vulnerability: libcurl GnuTLS insufficient cert verification + +2008 +---- + +November: + + Command line options: 128 + curl_easy_setopt() options: 158 + Public functions in libcurl: 58 + Known libcurl bindings: 37 + Contributors: 683 + + 145,000 unique visitors. >100 GB downloaded. + +2009 +---- + +March: security vulnerability: libcurl Arbitrary File Access + +August: security vulnerability: libcurl embedded zero in cert name + +December: Added support for IMAP, POP3 and SMTP + +2010 +---- + +January: Added support for RTSP + +February: security vulnerability: libcurl data callback excessive length + +March: The project switched over to use git (hosted by github) instead of CVS +for source code control + +May: Added support for RTMP + +Added support for PolarSSL to do the SSL/TLS stuff + +August: + + Public curl releases: 117 + Command line options: 138 + curl_easy_setopt() options: 180 + Public functions in libcurl: 58 + Known libcurl bindings: 39 + Contributors: 808 + + Gopher support added (re-added actually, see January 2006) + +2012 +---- + + July: Added support for Schannel (native Windows TLS backend) and Darwin SSL + (Native Mac OS X and iOS TLS backend). + + Supports metalink + + October: SSH-agent support. + +2013 +---- + + February: Cleaned up internals to always uses the "multi" non-blocking + approach internally and only expose the blocking API with a wrapper. + + September: First small steps on supporting HTTP/2 with nghttp2. + + October: Removed krb4 support. + + December: Happy eyeballs. + +2014 +---- + + March: first real release supporting HTTP/2 + + September: Web site had 245,000 unique visitors and served 236GB data + +2016 +---- + + December: curl 7.52.0 introduced support for HTTPS-proxy! + +2017 +---- + + September: Added Multi-SSL support + + The web site serves 3100 GB/month + + Public curl releases: 169 + Command line options: 211 + curl_easy_setopt() options: 249 + Public functions in libcurl: 74 + Contributors: 1609 diff --git a/docs/HTTP-COOKIES.md b/docs/HTTP-COOKIES.md new file mode 100644 index 00000000..a1b28345 --- /dev/null +++ b/docs/HTTP-COOKIES.md @@ -0,0 +1,104 @@ +# HTTP Cookies + +## Cookie overview + + Cookies are `name=contents` pairs that a HTTP server tells the client to + hold and then the client sends back those to the server on subsequent + requests to the same domains and paths for which the cookies were set. + + Cookies are either "session cookies" which typically are forgotten when the + session is over which is often translated to equal when browser quits, or + the cookies aren't session cookies they have expiration dates after which + the client will throw them away. + + Cookies are set to the client with the Set-Cookie: header and are sent to + servers with the Cookie: header. + + For a very long time, the only spec explaining how to use cookies was the + original [Netscape spec from 1994](https://curl.haxx.se/rfc/cookie_spec.html). + + In 2011, [RFC6265](https://www.ietf.org/rfc/rfc6265.txt) was finally + published and details how cookies work within HTTP. + +## Cookies saved to disk + + Netscape once created a file format for storing cookies on disk so that they + would survive browser restarts. curl adopted that file format to allow + sharing the cookies with browsers, only to see browsers move away from that + format. Modern browsers no longer use it, while curl still does. + + The netscape cookie file format stores one cookie per physical line in the + file with a bunch of associated meta data, each field separated with + TAB. That file is called the cookiejar in curl terminology. + + When libcurl saves a cookiejar, it creates a file header of its own in which + there is a URL mention that will link to the web version of this document. + +## Cookies with curl the command line tool + + curl has a full cookie "engine" built in. If you just activate it, you can + have curl receive and send cookies exactly as mandated in the specs. + + Command line options: + + `-b, --cookie` + + tell curl a file to read cookies from and start the cookie engine, or if it + isn't a file it will pass on the given string. -b name=var works and so does + -b cookiefile. + + `-j, --junk-session-cookies` + + when used in combination with -b, it will skip all "session cookies" on load + so as to appear to start a new cookie session. + + `-c, --cookie-jar` + + tell curl to start the cookie engine and write cookies to the given file + after the request(s) + +## Cookies with libcurl + + libcurl offers several ways to enable and interface the cookie engine. These + options are the ones provided by the native API. libcurl bindings may offer + access to them using other means. + + `CURLOPT_COOKIE` + + Is used when you want to specify the exact contents of a cookie header to + send to the server. + + `CURLOPT_COOKIEFILE` + + Tell libcurl to activate the cookie engine, and to read the initial set of + cookies from the given file. Read-only. + + `CURLOPT_COOKIEJAR` + + Tell libcurl to activate the cookie engine, and when the easy handle is + closed save all known cookies to the given cookiejar file. Write-only. + + `CURLOPT_COOKIELIST` + + Provide detailed information about a single cookie to add to the internal + storage of cookies. Pass in the cookie as a HTTP header with all the details + set, or pass in a line from a netscape cookie file. This option can also be + used to flush the cookies etc. + + `CURLINFO_COOKIELIST` + + Extract cookie information from the internal cookie storage as a linked + list. + +## Cookies with javascript + + These days a lot of the web is built up by javascript. The webbrowser loads + complete programs that render the page you see. These javascript programs + can also set and access cookies. + + Since curl and libcurl are plain HTTP clients without any knowledge of or + capability to handle javascript, such cookies will not be detected or used. + + Often, if you want to mimic what a browser does on such web sites, you can + record web browser HTTP traffic when using such a site and then repeat the + cookie operations using curl or libcurl. diff --git a/docs/HTTP2.md b/docs/HTTP2.md new file mode 100644 index 00000000..efbe6999 --- /dev/null +++ b/docs/HTTP2.md @@ -0,0 +1,126 @@ +HTTP/2 with curl +================ + +[HTTP/2 Spec](https://www.rfc-editor.org/rfc/rfc7540.txt) +[http2 explained](https://daniel.haxx.se/http2/) + +Build prerequisites +------------------- + - nghttp2 + - OpenSSL, libressl, BoringSSL, NSS, GnutTLS, mbedTLS, wolfSSL or SChannel + with a new enough version. + +[nghttp2](https://nghttp2.org/) +------------------------------- + +libcurl uses this 3rd party library for the low level protocol handling +parts. The reason for this is that HTTP/2 is much more complex at that layer +than HTTP/1.1 (which we implement on our own) and that nghttp2 is an already +existing and well functional library. + +We require at least version 1.0.0. + +Over an http:// URL +------------------- + +If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl will +include an upgrade header in the initial request to the host to allow +upgrading to HTTP/2. + +Possibly we can later introduce an option that will cause libcurl to fail if +not possible to upgrade. Possibly we introduce an option that makes libcurl +use HTTP/2 at once over http:// + +Over an https:// URL +-------------------- + +If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl will use +ALPN (or NPN) to negotiate which protocol to continue with. Possibly introduce +an option that will cause libcurl to fail if not possible to use HTTP/2. + +`CURL_HTTP_VERSION_2TLS` was added in 7.47.0 as a way to ask libcurl to prefer +HTTP/2 for HTTPS but stick to 1.1 by default for plain old HTTP connections. + +ALPN is the TLS extension that HTTP/2 is expected to use. The NPN extension is +for a similar purpose, was made prior to ALPN and is used for SPDY so early +HTTP/2 servers are implemented using NPN before ALPN support is widespread. + +`CURLOPT_SSL_ENABLE_ALPN` and `CURLOPT_SSL_ENABLE_NPN` are offered to allow +applications to explicitly disable ALPN or NPN. + +SSL libs +-------- + +The challenge is the ALPN and NPN support and all our different SSL +backends. You may need a fairly updated SSL library version for it to provide +the necessary TLS features. Right now we support: + + - OpenSSL: ALPN and NPN + - libressl: ALPN and NPN + - BoringSSL: ALPN and NPN + - NSS: ALPN and NPN + - GnuTLS: ALPN + - mbedTLS: ALPN + - SChannel: ALPN + - wolfSSL: ALPN + +Multiplexing +------------ + +Starting in 7.43.0, libcurl fully supports HTTP/2 multiplexing, which is the +term for doing multiple independent transfers over the same physical TCP +connection. + +To take advantage of multiplexing, you need to use the multi interface and set +`CURLMOPT_PIPELINING` to `CURLPIPE_MULTIPLEX`. With that bit set, libcurl will +attempt to re-use existing HTTP/2 connections and just add a new stream over +that when doing subsequent parallel requests. + +While libcurl sets up a connection to a HTTP server there is a period during +which it doesn't know if it can pipeline or do multiplexing and if you add new +transfers in that period, libcurl will default to start new connections for +those transfers. With the new option `CURLOPT_PIPEWAIT` (added in 7.43.0), you +can ask that a transfer should rather wait and see in case there's a +connection for the same host in progress that might end up being possible to +multiplex on. It favours keeping the number of connections low to the cost of +slightly longer time to first byte transferred. + +Applications +------------ + +We hide HTTP/2's binary nature and convert received HTTP/2 traffic to headers +in HTTP 1.1 style. This allows applications to work unmodified. + +curl tool +--------- + +curl offers the `--http2` command line option to enable use of HTTP/2. + +curl offers the `--http2-prior-knowledge` command line option to enable use of +HTTP/2 without HTTP/1.1 Upgrade. + +Since 7.47.0, the curl tool enables HTTP/2 by default for HTTPS connections. + +curl tool limitations +--------------------- + +The command line tool won't do any HTTP/2 multiplexing even though libcurl +supports it, simply because the curl tool is not written to take advantage of +the libcurl API that's necessary for this (the multi interface). We have an +outstanding TODO item for this and **you** can help us make it happen. + +The command line tool also doesn't support HTTP/2 server push for the same +reason it doesn't do multiplexing: it needs to use the multi interface for +that so that multiplexing is supported. + +HTTP Alternative Services +------------------------- + +Alt-Svc is an extension with a corresponding frame (ALTSVC) in HTTP/2 that +tells the client about an alternative "route" to the same content for the same +origin server that you get the response from. A browser or long-living client +can use that hint to create a new connection asynchronously. For libcurl, we +may introduce a way to bring such clues to the application and/or let a +subsequent request use the alternate route automatically. + +[Detailed in RFC 7838](https://tools.ietf.org/html/rfc7838) diff --git a/docs/INSTALL b/docs/INSTALL new file mode 100644 index 00000000..ff260b1b --- /dev/null +++ b/docs/INSTALL @@ -0,0 +1,9 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + How To Compile + +see INSTALL.md diff --git a/docs/INSTALL.cmake b/docs/INSTALL.cmake new file mode 100644 index 00000000..0a8e4397 --- /dev/null +++ b/docs/INSTALL.cmake @@ -0,0 +1,91 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + How To Compile with CMake + +Building with CMake +========================== + This document describes how to compile, build and install curl and libcurl + from source code using the CMake build tool. To build with CMake, you will + of course have to first install CMake. The minimum required version of + CMake is specified in the file CMakeLists.txt found in the top of the curl + source tree. Once the correct version of CMake is installed you can follow + the instructions below for the platform you are building on. + + CMake builds can be configured either from the command line, or from one + of CMake's GUI's. + +Current flaws in the curl CMake build +===================================== + + Missing features in the cmake build: + + - Builds libcurl without large file support + - Does not support all SSL libraries (only OpenSSL, WinSSL, DarwinSSL, and + mbed TLS) + - Doesn't build with SCP and SFTP support (libssh2) (see issue #1155) + - Doesn't allow different resolver backends (no c-ares build support) + - No RTMP support built + - Doesn't allow build curl and libcurl debug enabled + - Doesn't allow a custom CA bundle path + - Doesn't allow you to disable specific protocols from the build + - Doesn't find or use krb4 or GSS + - Rebuilds test files too eagerly, but still can't run the tests + - Doesn't detect the correct strerror_r flavor when cross-compiling (issue #1123) + + +Command Line CMake +================== + A CMake build of curl is similar to the autotools build of curl. It + consists of the following steps after you have unpacked the source. + + 1. Create an out of source build tree parallel to the curl source + tree and change into that directory + + $ mkdir curl-build + $ cd curl-build + + 2. Run CMake from the build tree, giving it the path to the top of + the curl source tree. CMake will pick a compiler for you. If you + want to specify the compile, you can set the CC environment + variable prior to running CMake. + + $ cmake ../curl + $ make + + 3. Install to default location: + + $ make install + + (The test suite does not work with the cmake build) + +ccmake +========= + CMake comes with a curses based interface called ccmake. To run ccmake on + a curl use the instructions for the command line cmake, but substitute + ccmake ../curl for cmake ../curl. This will bring up a curses interface + with instructions on the bottom of the screen. You can press the "c" key + to configure the project, and the "g" key to generate the project. After + the project is generated, you can run make. + +cmake-gui +========= + CMake also comes with a Qt based GUI called cmake-gui. To configure with + cmake-gui, you run cmake-gui and follow these steps: + 1. Fill in the "Where is the source code" combo box with the path to + the curl source tree. + 2. Fill in the "Where to build the binaries" combo box with the path + to the directory for your build tree, ideally this should not be the + same as the source tree, but a parallel directory called curl-build or + something similar. + 3. Once the source and binary directories are specified, press the + "Configure" button. + 4. Select the native build tool that you want to use. + 5. At this point you can change any of the options presented in the + GUI. Once you have selected all the options you want, click the + "Generate" button. + 6. Run the native build tool that you used CMake to generate. + diff --git a/docs/INSTALL.md b/docs/INSTALL.md new file mode 100644 index 00000000..767105c9 --- /dev/null +++ b/docs/INSTALL.md @@ -0,0 +1,468 @@ +# how to install curl and libcurl + +## Installing Binary Packages + +Lots of people download binary distributions of curl and libcurl. This +document does not describe how to install curl or libcurl using such a binary +package. This document describes how to compile, build and install curl and +libcurl from source code. + +## Building from git + +If you get your code off a git repository instead of a release tarball, see +the `GIT-INFO` file in the root directory for specific instructions on how to +proceed. + +# Unix + +A normal Unix installation is made in three or four steps (after you've +unpacked the source archive): + + ./configure + make + make test (optional) + make install + +You probably need to be root when doing the last command. + +Get a full listing of all available configure options by invoking it like: + + ./configure --help + +If you want to install curl in a different file hierarchy than `/usr/local`, +specify that when running configure: + + ./configure --prefix=/path/to/curl/tree + +If you have write permission in that directory, you can do 'make install' +without being root. An example of this would be to make a local install in +your own home directory: + + ./configure --prefix=$HOME + make + make install + +The configure script always tries to find a working SSL library unless +explicitly told not to. If you have OpenSSL installed in the default search +path for your compiler/linker, you don't need to do anything special. If you +have OpenSSL installed in /usr/local/ssl, you can run configure like: + + ./configure --with-ssl + +If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL) and +you have pkg-config installed, set the pkg-config path first, like this: + + env PKG_CONFIG_PATH=/opt/OpenSSL/lib/pkgconfig ./configure --with-ssl + +Without pkg-config installed, use this: + + ./configure --with-ssl=/opt/OpenSSL + +If you insist on forcing a build without SSL support, even though you may +have OpenSSL installed in your system, you can run configure like this: + + ./configure --without-ssl + +If you have OpenSSL installed, but with the libraries in one place and the +header files somewhere else, you have to set the LDFLAGS and CPPFLAGS +environment variables prior to running configure. Something like this should +work: + + CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" ./configure + +If you have shared SSL libs installed in a directory where your run-time +linker doesn't find them (which usually causes configure failures), you can +provide this option to gcc to set a hard-coded path to the run-time linker: + + LDFLAGS=-Wl,-R/usr/local/ssl/lib ./configure --with-ssl + +## More Options + +To force a static library compile, disable the shared library creation by +running configure like: + + ./configure --disable-shared + +To tell the configure script to skip searching for thread-safe functions, add +an option like: + + ./configure --disable-thread + +If you're a curl developer and use gcc, you might want to enable more debug +options with the `--enable-debug` option. + +curl can be built to use a whole range of libraries to provide various useful +services, and configure will try to auto-detect a decent default. But if you +want to alter it, you can select how to deal with each individual library. + +## Select TLS backend + +The default OpenSSL configure check will also detect and use BoringSSL or +libressl. + + - GnuTLS: `--without-ssl --with-gnutls`. + - Cyassl: `--without-ssl --with-cyassl` + - NSS: `--without-ssl --with-nss` + - PolarSSL: `--without-ssl --with-polarssl` + - mbedTLS: `--without-ssl --with-mbedtls` + - axTLS: `--without-ssl --with-axtls` + - schannel: `--without-ssl --with-winssl` + - secure transport: `--without-ssl --with-darwinssl` + +# Windows + +## Building Windows DLLs and C run-time (CRT) linkage issues + + As a general rule, building a DLL with static CRT linkage is highly + discouraged, and intermixing CRTs in the same app is something to avoid at + any cost. + + Reading and comprehending Microsoft Knowledge Base articles KB94248 and + KB140584 is a must for any Windows developer. Especially important is full + understanding if you are not going to follow the advice given above. + + - [How To Use the C Run-Time](https://support.microsoft.com/kb/94248/en-us) + - [How to link with the correct C Run-Time CRT library](https://support.microsoft.com/kb/140584/en-us) + - [Potential Errors Passing CRT Objects Across DLL Boundaries](https://msdn.microsoft.com/en-us/library/ms235460) + +If your app is misbehaving in some strange way, or it is suffering from +memory corruption, before asking for further help, please try first to +rebuild every single library your app uses as well as your app using the +debug multithreaded dynamic C runtime. + + If you get linkage errors read section 5.7 of the FAQ document. + +## MingW32 + +Make sure that MinGW32's bin dir is in the search path, for example: + + set PATH=c:\mingw32\bin;%PATH% + +then run `mingw32-make mingw32` in the root dir. There are other +make targets available to build libcurl with more features, use: + + - `mingw32-make mingw32-zlib` to build with Zlib support; + - `mingw32-make mingw32-ssl-zlib` to build with SSL and Zlib enabled; + - `mingw32-make mingw32-ssh2-ssl-zlib` to build with SSH2, SSL, Zlib; + - `mingw32-make mingw32-ssh2-ssl-sspi-zlib` to build with SSH2, SSL, Zlib + and SSPI support. + +If you have any problems linking libraries or finding header files, be sure +to verify that the provided "Makefile.m32" files use the proper paths, and +adjust as necessary. It is also possible to override these paths with +environment variables, for example: + + set ZLIB_PATH=c:\zlib-1.2.8 + set OPENSSL_PATH=c:\openssl-1.0.2c + set LIBSSH2_PATH=c:\libssh2-1.6.0 + +It is also possible to build with other LDAP SDKs than MS LDAP; currently +it is possible to build with native Win32 OpenLDAP, or with the Novell CLDAP +SDK. If you want to use these you need to set these vars: + + set LDAP_SDK=c:\openldap + set USE_LDAP_OPENLDAP=1 + +or for using the Novell SDK: + + set USE_LDAP_NOVELL=1 + +If you want to enable LDAPS support then set LDAPS=1. + +## Cygwin + +Almost identical to the unix installation. Run the configure script in the +curl source tree root with `sh configure`. Make sure you have the sh +executable in /bin/ or you'll see the configure fail toward the end. + +Run `make` + +## Disabling Specific Protocols in Windows builds + +The configure utility, unfortunately, is not available for the Windows +environment, therefore, you cannot use the various disable-protocol options of +the configure utility on this platform. + +However, you can use the following defines to disable specific +protocols: + + - `HTTP_ONLY` disables all protocols except HTTP + - `CURL_DISABLE_FTP` disables FTP + - `CURL_DISABLE_LDAP` disables LDAP + - `CURL_DISABLE_TELNET` disables TELNET + - `CURL_DISABLE_DICT` disables DICT + - `CURL_DISABLE_FILE` disables FILE + - `CURL_DISABLE_TFTP` disables TFTP + - `CURL_DISABLE_HTTP` disables HTTP + - `CURL_DISABLE_IMAP` disables IMAP + - `CURL_DISABLE_POP3` disables POP3 + - `CURL_DISABLE_SMTP` disables SMTP + +If you want to set any of these defines you have the following options: + + - Modify lib/config-win32.h + - Modify lib/curl_setup.h + - Modify winbuild/Makefile.vc + - Modify the "Preprocessor Definitions" in the libcurl project + +Note: The pre-processor settings can be found using the Visual Studio IDE +under "Project -> Settings -> C/C++ -> General" in VC6 and "Project -> +Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later +versions. + +## Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds + +In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack it is +necessary to make definition of preprocessor symbol USE_LWIPSOCK visible to +libcurl and curl compilation processes. To set this definition you have the +following alternatives: + + - Modify lib/config-win32.h and src/config-win32.h + - Modify winbuild/Makefile.vc + - Modify the "Preprocessor Definitions" in the libcurl project + +Note: The pre-processor settings can be found using the Visual Studio IDE +under "Project -> Settings -> C/C++ -> General" in VC6 and "Project -> +Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later +versions. + +Once that libcurl has been built with BSD-style lwIP TCP/IP stack support, in +order to use it with your program it is mandatory that your program includes +lwIP header file `` (or another lwIP header that includes this) +before including any libcurl header. Your program does not need the +`USE_LWIPSOCK` preprocessor definition which is for libcurl internals only. + +Compilation has been verified with [lwIP +1.4.0](https://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip) and +[contrib-1.4.0](https://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip). + +This BSD-style lwIP TCP/IP stack support must be considered experimental given +that it has been verified that lwIP 1.4.0 still needs some polish, and libcurl +might yet need some additional adjustment, caveat emptor. + +## Important static libcurl usage note + +When building an application that uses the static libcurl library on Windows, +you must add `-DCURL_STATICLIB` to your `CFLAGS`. Otherwise the linker will +look for dynamic import symbols. + +## Legacy Windows and SSL + +WinSSL (specifically SChannel from Windows SSPI), is the native SSL library in +Windows. However, WinSSL in Windows <= XP is unable to connect to servers that +no longer support the legacy handshakes and algorithms used by those +versions. If you will be using curl in one of those earlier versions of +Windows you should choose another SSL backend such as OpenSSL. + +# Apple iOS and Mac OS X + +On modern Apple operating systems, curl can be built to use Apple's SSL/TLS +implementation, Secure Transport, instead of OpenSSL. To build with Secure +Transport for SSL/TLS, use the configure option `--with-darwinssl`. (It is not +necessary to use the option `--without-ssl`.) This feature requires iOS 5.0 or +later, or OS X 10.5 ("Leopard") or later. + +When Secure Transport is in use, the curl options `--cacert` and `--capath` +and their libcurl equivalents, will be ignored, because Secure Transport uses +the certificates stored in the Keychain to evaluate whether or not to trust +the server. This, of course, includes the root certificates that ship with the +OS. The `--cert` and `--engine` options, and their libcurl equivalents, are +currently unimplemented in curl with Secure Transport. + +For OS X users: In OS X 10.8 ("Mountain Lion"), Apple made a major overhaul to +the Secure Transport API that, among other things, added support for the newer +TLS 1.1 and 1.2 protocols. To get curl to support TLS 1.1 and 1.2, you must +build curl on Mountain Lion or later, or by using the equivalent SDK. If you +set the `MACOSX_DEPLOYMENT_TARGET` environmental variable to an earlier +version of OS X prior to building curl, then curl will use the new Secure +Transport API on Mountain Lion and later, and fall back on the older API when +the same curl binary is executed on older cats. For example, running these +commands in curl's directory in the shell will build the code such that it +will run on cats as old as OS X 10.6 ("Snow Leopard") (using bash): + + export MACOSX_DEPLOYMENT_TARGET="10.6" + ./configure --with-darwinssl + make + +# Cross compile + +Download and unpack the curl package. + +'cd' to the new directory. (e.g. `cd curl-7.12.3`) + +Set environment variables to point to the cross-compile toolchain and call +configure with any options you need. Be sure and specify the `--host` and +`--build` parameters at configuration time. The following script is an +example of cross-compiling for the IBM 405GP PowerPC processor using the +toolchain from MonteVista for Hardhat Linux. + + #! /bin/sh + + export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin + export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include" + export AR=ppc_405-ar + export AS=ppc_405-as + export LD=ppc_405-ld + export RANLIB=ppc_405-ranlib + export CC=ppc_405-gcc + export NM=ppc_405-nm + + ./configure --target=powerpc-hardhat-linux + --host=powerpc-hardhat-linux + --build=i586-pc-linux-gnu + --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local + --exec-prefix=/usr/local + +You may also need to provide a parameter like `--with-random=/dev/urandom` to +configure as it cannot detect the presence of a random number generating +device for a target system. The `--prefix` parameter specifies where curl +will be installed. If `configure` completes successfully, do `make` and `make +install` as usual. + +In some cases, you may be able to simplify the above commands to as little as: + + ./configure --host=ARCH-OS + +# REDUCING SIZE + +There are a number of configure options that can be used to reduce the size of +libcurl for embedded applications where binary size is an important factor. +First, be sure to set the CFLAGS variable when configuring with any relevant +compiler optimization flags to reduce the size of the binary. For gcc, this +would mean at minimum the -Os option, and potentially the `-march=X`, +`-mdynamic-no-pic` and `-flto` options as well, e.g. + + ./configure CFLAGS='-Os' LDFLAGS='-Wl,-Bsymbolic'... + +Note that newer compilers often produce smaller code than older versions +due to improved optimization. + +Be sure to specify as many `--disable-` and `--without-` flags on the +configure command-line as you can to disable all the libcurl features that you +know your application is not going to need. Besides specifying the +`--disable-PROTOCOL` flags for all the types of URLs your application will not +use, here are some other flags that can reduce the size of the library: + + - `--disable-ares` (disables support for the C-ARES DNS library) + - `--disable-cookies` (disables support for HTTP cookies) + - `--disable-crypto-auth` (disables HTTP cryptographic authentication) + - `--disable-ipv6` (disables support for IPv6) + - `--disable-manual` (disables support for the built-in documentation) + - `--disable-proxy` (disables support for HTTP and SOCKS proxies) + - `--disable-unix-sockets` (disables support for UNIX sockets) + - `--disable-verbose` (eliminates debugging strings and error code strings) + - `--disable-versioned-symbols` (disables support for versioned symbols) + - `--enable-hidden-symbols` (eliminates unneeded symbols in the shared library) + - `--without-libidn` (disables support for the libidn DNS library) + - `--without-librtmp` (disables support for RTMP) + - `--without-ssl` (disables support for SSL/TLS) + - `--without-zlib` (disables support for on-the-fly decompression) + +The GNU compiler and linker have a number of options that can reduce the +size of the libcurl dynamic libraries on some platforms even further. +Specify them by providing appropriate CFLAGS and LDFLAGS variables on the +configure command-line, e.g. + + CFLAGS="-Os -ffunction-sections -fdata-sections + -fno-unwind-tables -fno-asynchronous-unwind-tables -flto" + LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" + +Be sure also to strip debugging symbols from your binaries after compiling +using 'strip' (or the appropriate variant if cross-compiling). If space is +really tight, you may be able to remove some unneeded sections of the shared +library using the -R option to objcopy (e.g. the .comment section). + +Using these techniques it is possible to create a basic HTTP-only shared +libcurl library for i386 Linux platforms that is only 113 KiB in size, and an +FTP-only library that is 113 KiB in size (as of libcurl version 7.50.3, using +gcc 5.4.0). + +You may find that statically linking libcurl to your application will result +in a lower total size than dynamically linking. + +Note that the curl test harness can detect the use of some, but not all, of +the `--disable` statements suggested above. Use will cause tests relying on +those features to fail. The test harness can be manually forced to skip the +relevant tests by specifying certain key words on the runtests.pl command +line. Following is a list of appropriate key words: + + - `--disable-cookies` !cookies + - `--disable-manual` !--manual + - `--disable-proxy` !HTTP\ proxy !proxytunnel !SOCKS4 !SOCKS5 + +# PORTS + +This is a probably incomplete list of known hardware and operating systems +that curl has been compiled for. If you know a system curl compiles and +runs on, that isn't listed, please let us know! + + - Alpha DEC OSF 4 + - Alpha Digital UNIX v3.2 + - Alpha FreeBSD 4.1, 4.5 + - Alpha Linux 2.2, 2.4 + - Alpha NetBSD 1.5.2 + - Alpha OpenBSD 3.0 + - Alpha OpenVMS V7.1-1H2 + - Alpha Tru64 v5.0 5.1 + - AVR32 Linux + - ARM Android 1.5, 2.1, 2.3, 3.2, 4.x + - ARM INTEGRITY + - ARM iOS + - Cell Linux + - Cell Cell OS + - HP-PA HP-UX 9.X 10.X 11.X + - HP-PA Linux + - HP3000 MPE/iX + - MicroBlaze uClinux + - MIPS IRIX 6.2, 6.5 + - MIPS Linux + - OS/400 + - Pocket PC/Win CE 3.0 + - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2 + - PowerPC Darwin 1.0 + - PowerPC INTEGRITY + - PowerPC Linux + - PowerPC Mac OS 9 + - PowerPC Mac OS X + - SH4 Linux 2.6.X + - SH4 OS21 + - SINIX-Z v5 + - Sparc Linux + - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10 + - Sparc SunOS 4.1.X + - StrongARM (and other ARM) RISC OS 3.1, 4.02 + - StrongARM/ARM7/ARM9 Linux 2.4, 2.6 + - StrongARM NetBSD 1.4.1 + - Symbian OS (P.I.P.S.) 9.x + - TPF + - Ultrix 4.3a + - UNICOS 9.0 + - i386 BeOS + - i386 DOS + - i386 eCos 1.3.1 + - i386 Esix 4.1 + - i386 FreeBSD + - i386 HURD + - i386 Haiku OS + - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 + - i386 Mac OS X + - i386 MINIX 3.1 + - i386 NetBSD + - i386 Novell NetWare + - i386 OS/2 + - i386 OpenBSD + - i386 QNX 6 + - i386 SCO unix + - i386 Solaris 2.7 + - i386 Windows 95, 98, ME, NT, 2000, XP, 2003 + - i486 ncr-sysv4.3.03 (NCR MP-RAS) + - ia64 Linux 2.3.99 + - m68k AmigaOS 3 + - m68k Linux + - m68k uClinux + - m68k OpenBSD + - m88k dg-dgux5.4R3.00 + - s390 Linux + - x86_64 Linux + - XScale/PXA250 Linux 2.4 + - Nios II uClinux diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md new file mode 100644 index 00000000..459684ba --- /dev/null +++ b/docs/INTERNALS.md @@ -0,0 +1,1081 @@ +curl internals +============== + + - [Intro](#intro) + - [git](#git) + - [Portability](#Portability) + - [Windows vs Unix](#winvsunix) + - [Library](#Library) + - [`Curl_connect`](#Curl_connect) + - [`Curl_do`](#Curl_do) + - [`Curl_readwrite`](#Curl_readwrite) + - [`Curl_done`](#Curl_done) + - [`Curl_disconnect`](#Curl_disconnect) + - [HTTP(S)](#http) + - [FTP](#ftp) + - [Kerberos](#kerberos) + - [TELNET](#telnet) + - [FILE](#file) + - [SMB](#smb) + - [LDAP](#ldap) + - [E-mail](#email) + - [General](#general) + - [Persistent Connections](#persistent) + - [multi interface/non-blocking](#multi) + - [SSL libraries](#ssl) + - [Library Symbols](#symbols) + - [Return Codes and Informationals](#returncodes) + - [AP/ABI](#abi) + - [Client](#client) + - [Memory Debugging](#memorydebug) + - [Test Suite](#test) + - [Asynchronous name resolves](#asyncdns) + - [c-ares](#cares) + - [`curl_off_t`](#curl_off_t) + - [curlx](#curlx) + - [Content Encoding](#contentencoding) + - [hostip.c explained](#hostip) + - [Track Down Memory Leaks](#memoryleak) + - [`multi_socket`](#multi_socket) + - [Structs in libcurl](#structs) + + +Intro +===== + + This project is split in two. The library and the client. The client part + uses the library, but the library is designed to allow other applications to + use it. + + The largest amount of code and complexity is in the library part. + + + +git +=== + + All changes to the sources are committed to the git repository as soon as + they're somewhat verified to work. Changes shall be committed as independently + as possible so that individual changes can be easily spotted and tracked + afterwards. + + Tagging shall be used extensively, and by the time we release new archives we + should tag the sources with a name similar to the released version number. + + +Portability +=========== + + We write curl and libcurl to compile with C89 compilers. On 32bit and up + machines. Most of libcurl assumes more or less POSIX compliance but that's + not a requirement. + + We write libcurl to build and work with lots of third party tools, and we + want it to remain functional and buildable with these and later versions + (older versions may still work but is not what we work hard to maintain): + +Dependencies +------------ + + - OpenSSL 0.9.7 + - GnuTLS 1.2 + - zlib 1.1.4 + - libssh2 0.16 + - c-ares 1.6.0 + - libidn2 2.0.0 + - cyassl 2.0.0 + - openldap 2.0 + - MIT Kerberos 1.2.4 + - GSKit V5R3M0 + - NSS 3.14.x + - axTLS 2.1.0 + - PolarSSL 1.3.0 + - Heimdal ? + - nghttp2 1.0.0 + +Operating Systems +----------------- + + On systems where configure runs, we aim at working on them all - if they have + a suitable C compiler. On systems that don't run configure, we strive to keep + curl running correctly on: + + - Windows 98 + - AS/400 V5R3M0 + - Symbian 9.1 + - Windows CE ? + - TPF ? + +Build tools +----------- + + When writing code (mostly for generating stuff included in release tarballs) + we use a few "build tools" and we make sure that we remain functional with + these versions: + + - GNU Libtool 1.4.2 + - GNU Autoconf 2.57 + - GNU Automake 1.7 + - GNU M4 1.4 + - perl 5.004 + - roffit 0.5 + - groff ? (any version that supports "groff -Tps -man [in] [out]") + - ps2pdf (gs) ? + + +Windows vs Unix +=============== + + There are a few differences in how to program curl the Unix way compared to + the Windows way. Perhaps the four most notable details are: + + 1. Different function names for socket operations. + + In curl, this is solved with defines and macros, so that the source looks + the same in all places except for the header file that defines them. The + macros in use are sclose(), sread() and swrite(). + + 2. Windows requires a couple of init calls for the socket stuff. + + That's taken care of by the `curl_global_init()` call, but if other libs + also do it etc there might be reasons for applications to alter that + behaviour. + + 3. The file descriptors for network communication and file operations are + not as easily interchangeable as in Unix. + + We avoid this by not trying any funny tricks on file descriptors. + + 4. When writing data to stdout, Windows makes end-of-lines the DOS way, thus + destroying binary data, although you do want that conversion if it is + text coming through... (sigh) + + We set stdout to binary under windows + + Inside the source code, We make an effort to avoid `#ifdef [Your OS]`. All + conditionals that deal with features *should* instead be in the format + `#ifdef HAVE_THAT_WEIRD_FUNCTION`. Since Windows can't run configure scripts, + we maintain a `curl_config-win32.h` file in lib directory that is supposed to + look exactly like a `curl_config.h` file would have looked like on a Windows + machine! + + Generally speaking: always remember that this will be compiled on dozens of + operating systems. Don't walk on the edge! + + +Library +======= + + (See [Structs in libcurl](#structs) for the separate section describing all + major internal structs and their purposes.) + + There are plenty of entry points to the library, namely each publicly defined + function that libcurl offers to applications. All of those functions are + rather small and easy-to-follow. All the ones prefixed with `curl_easy` are + put in the lib/easy.c file. + + `curl_global_init()` and `curl_global_cleanup()` should be called by the + application to initialize and clean up global stuff in the library. As of + today, it can handle the global SSL initing if SSL is enabled and it can init + the socket layer on windows machines. libcurl itself has no "global" scope. + + All printf()-style functions use the supplied clones in lib/mprintf.c. This + makes sure we stay absolutely platform independent. + + [ `curl_easy_init()`][2] allocates an internal struct and makes some + initializations. The returned handle does not reveal internals. This is the + `Curl_easy` struct which works as an "anchor" struct for all `curl_easy` + functions. All connections performed will get connect-specific data allocated + that should be used for things related to particular connections/requests. + + [`curl_easy_setopt()`][1] takes three arguments, where the option stuff must + be passed in pairs: the parameter-ID and the parameter-value. The list of + options is documented in the man page. This function mainly sets things in + the `Curl_easy` struct. + + `curl_easy_perform()` is just a wrapper function that makes use of the multi + API. It basically calls `curl_multi_init()`, `curl_multi_add_handle()`, + `curl_multi_wait()`, and `curl_multi_perform()` until the transfer is done + and then returns. + + Some of the most important key functions in url.c are called from multi.c + when certain key steps are to be made in the transfer operation. + + +Curl_connect() +-------------- + + Analyzes the URL, it separates the different components and connects to the + remote host. This may involve using a proxy and/or using SSL. The + `Curl_resolv()` function in lib/hostip.c is used for looking up host names + (it does then use the proper underlying method, which may vary between + platforms and builds). + + When `Curl_connect` is done, we are connected to the remote site. Then it + is time to tell the server to get a document/file. `Curl_do()` arranges + this. + + This function makes sure there's an allocated and initiated 'connectdata' + struct that is used for this particular connection only (although there may + be several requests performed on the same connect). A bunch of things are + inited/inherited from the `Curl_easy` struct. + + +Curl_do() +--------- + + `Curl_do()` makes sure the proper protocol-specific function is called. The + functions are named after the protocols they handle. + + The protocol-specific functions of course deal with protocol-specific + negotiations and setup. They have access to the `Curl_sendf()` (from + lib/sendf.c) function to send printf-style formatted data to the remote + host and when they're ready to make the actual file transfer they call the + `Curl_Transfer()` function (in lib/transfer.c) to setup the transfer and + returns. + + If this DO function fails and the connection is being re-used, libcurl will + then close this connection, setup a new connection and re-issue the DO + request on that. This is because there is no way to be perfectly sure that + we have discovered a dead connection before the DO function and thus we + might wrongly be re-using a connection that was closed by the remote peer. + + Some time during the DO function, the `Curl_setup_transfer()` function must + be called with some basic info about the upcoming transfer: what socket(s) + to read/write and the expected file transfer sizes (if known). + + +Curl_readwrite() +---------------- + + Called during the transfer of the actual protocol payload. + + During transfer, the progress functions in lib/progress.c are called at + frequent intervals (or at the user's choice, a specified callback might get + called). The speedcheck functions in lib/speedcheck.c are also used to + verify that the transfer is as fast as required. + + +Curl_done() +----------- + + Called after a transfer is done. This function takes care of everything + that has to be done after a transfer. This function attempts to leave + matters in a state so that `Curl_do()` should be possible to call again on + the same connection (in a persistent connection case). It might also soon + be closed with `Curl_disconnect()`. + + +Curl_disconnect() +----------------- + + When doing normal connections and transfers, no one ever tries to close any + connections so this is not normally called when `curl_easy_perform()` is + used. This function is only used when we are certain that no more transfers + are going to be made on the connection. It can be also closed by force, or + it can be called to make sure that libcurl doesn't keep too many + connections alive at the same time. + + This function cleans up all resources that are associated with a single + connection. + + +HTTP(S) +======= + + HTTP offers a lot and is the protocol in curl that uses the most lines of + code. There is a special file (lib/formdata.c) that offers all the multipart + post functions. + + base64-functions for user+password stuff (and more) is in (lib/base64.c) and + all functions for parsing and sending cookies are found in (lib/cookie.c). + + HTTPS uses in almost every case the same procedure as HTTP, with only two + exceptions: the connect procedure is different and the function used to read + or write from the socket is different, although the latter fact is hidden in + the source by the use of `Curl_read()` for reading and `Curl_write()` for + writing data to the remote server. + + `http_chunks.c` contains functions that understands HTTP 1.1 chunked transfer + encoding. + + An interesting detail with the HTTP(S) request, is the `Curl_add_buffer()` + series of functions we use. They append data to one single buffer, and when + the building is finished the entire request is sent off in one single write. This is done this way to overcome problems with flawed firewalls and lame servers. + + +FTP +=== + + The `Curl_if2ip()` function can be used for getting the IP number of a + specified network interface, and it resides in lib/if2ip.c. + + `Curl_ftpsendf()` is used for sending FTP commands to the remote server. It + was made a separate function to prevent us programmers from forgetting that + they must be CRLF terminated. They must also be sent in one single write() to + make firewalls and similar happy. + + +Kerberos +-------- + + Kerberos support is mainly in lib/krb5.c and lib/security.c but also + `curl_sasl_sspi.c` and `curl_sasl_gssapi.c` for the email protocols and + `socks_gssapi.c` and `socks_sspi.c` for SOCKS5 proxy specifics. + + +TELNET +====== + + Telnet is implemented in lib/telnet.c. + + +FILE +==== + + The file:// protocol is dealt with in lib/file.c. + + +SMB +=== + + The smb:// protocol is dealt with in lib/smb.c. + + +LDAP +==== + + Everything LDAP is in lib/ldap.c and lib/openldap.c + + +E-mail +====== + + The e-mail related source code is in lib/imap.c, lib/pop3.c and lib/smtp.c. + + +General +======= + + URL encoding and decoding, called escaping and unescaping in the source code, + is found in lib/escape.c. + + While transferring data in Transfer() a few functions might get used. + `curl_getdate()` in lib/parsedate.c is for HTTP date comparisons (and more). + + lib/getenv.c offers `curl_getenv()` which is for reading environment + variables in a neat platform independent way. That's used in the client, but + also in lib/url.c when checking the proxy environment variables. Note that + contrary to the normal unix getenv(), this returns an allocated buffer that + must be free()ed after use. + + lib/netrc.c holds the .netrc parser + + lib/timeval.c features replacement functions for systems that don't have + gettimeofday() and a few support functions for timeval conversions. + + A function named `curl_version()` that returns the full curl version string + is found in lib/version.c. + + +Persistent Connections +====================== + + The persistent connection support in libcurl requires some considerations on + how to do things inside of the library. + + - The `Curl_easy` struct returned in the [`curl_easy_init()`][2] call + must never hold connection-oriented data. It is meant to hold the root data + as well as all the options etc that the library-user may choose. + + - The `Curl_easy` struct holds the "connection cache" (an array of + pointers to 'connectdata' structs). + + - This enables the 'curl handle' to be reused on subsequent transfers. + + - When libcurl is told to perform a transfer, it first checks for an already + existing connection in the cache that we can use. Otherwise it creates a + new one and adds that to the cache. If the cache is full already when a new + connection is added, it will first close the oldest unused one. + + - When the transfer operation is complete, the connection is left + open. Particular options may tell libcurl not to, and protocols may signal + closure on connections and then they won't be kept open, of course. + + - When `curl_easy_cleanup()` is called, we close all still opened connections, + unless of course the multi interface "owns" the connections. + + The curl handle must be re-used in order for the persistent connections to + work. + + +multi interface/non-blocking +============================ + + The multi interface is a non-blocking interface to the library. To make that + interface work as well as possible, no low-level functions within libcurl + must be written to work in a blocking manner. (There are still a few spots + violating this rule.) + + One of the primary reasons we introduced c-ares support was to allow the name + resolve phase to be perfectly non-blocking as well. + + The FTP and the SFTP/SCP protocols are examples of how we adapt and adjust + the code to allow non-blocking operations even on multi-stage command- + response protocols. They are built around state machines that return when + they would otherwise block waiting for data. The DICT, LDAP and TELNET + protocols are crappy examples and they are subject for rewrite in the future + to better fit the libcurl protocol family. + + +SSL libraries +============= + + Originally libcurl supported SSLeay for SSL/TLS transports, but that was then + extended to its successor OpenSSL but has since also been extended to several + other SSL/TLS libraries and we expect and hope to further extend the support + in future libcurl versions. + + To deal with this internally in the best way possible, we have a generic SSL + function API as provided by the vtls/vtls.[ch] system, and they are the only + SSL functions we must use from within libcurl. vtls is then crafted to use + the appropriate lower-level function calls to whatever SSL library that is in + use. For example vtls/openssl.[ch] for the OpenSSL library. + + +Library Symbols +=============== + + All symbols used internally in libcurl must use a `Curl_` prefix if they're + used in more than a single file. Single-file symbols must be made static. + Public ("exported") symbols must use a `curl_` prefix. (There are exceptions, + but they are to be changed to follow this pattern in future versions.) Public + API functions are marked with `CURL_EXTERN` in the public header files so + that all others can be hidden on platforms where this is possible. + + +Return Codes and Informationals +=============================== + + I've made things simple. Almost every function in libcurl returns a CURLcode, + that must be `CURLE_OK` if everything is OK or otherwise a suitable error + code as the curl/curl.h include file defines. The very spot that detects an + error must use the `Curl_failf()` function to set the human-readable error + description. + + In aiding the user to understand what's happening and to debug curl usage, we + must supply a fair number of informational messages by using the + `Curl_infof()` function. Those messages are only displayed when the user + explicitly asks for them. They are best used when revealing information that + isn't otherwise obvious. + + +API/ABI +======= + + We make an effort to not export or show internals or how internals work, as + that makes it easier to keep a solid API/ABI over time. See docs/libcurl/ABI + for our promise to users. + + +Client +====== + + main() resides in `src/tool_main.c`. + + `src/tool_hugehelp.c` is automatically generated by the mkhelp.pl perl script + to display the complete "manual" and the `src/tool_urlglob.c` file holds the + functions used for the URL-"globbing" support. Globbing in the sense that the + {} and [] expansion stuff is there. + + The client mostly sets up its 'config' struct properly, then + it calls the `curl_easy_*()` functions of the library and when it gets back + control after the `curl_easy_perform()` it cleans up the library, checks + status and exits. + + When the operation is done, the ourWriteOut() function in src/writeout.c may + be called to report about the operation. That function is using the + `curl_easy_getinfo()` function to extract useful information from the curl + session. + + It may loop and do all this several times if many URLs were specified on the + command line or config file. + + +Memory Debugging +================ + + The file lib/memdebug.c contains debug-versions of a few functions. Functions + such as malloc, free, fopen, fclose, etc that somehow deal with resources + that might give us problems if we "leak" them. The functions in the memdebug + system do nothing fancy, they do their normal function and then log + information about what they just did. The logged data can then be analyzed + after a complete session, + + memanalyze.pl is the perl script present in tests/ that analyzes a log file + generated by the memory tracking system. It detects if resources are + allocated but never freed and other kinds of errors related to resource + management. + + Internally, definition of preprocessor symbol DEBUGBUILD restricts code which + is only compiled for debug enabled builds. And symbol CURLDEBUG is used to + differentiate code which is _only_ used for memory tracking/debugging. + + Use -DCURLDEBUG when compiling to enable memory debugging, this is also + switched on by running configure with --enable-curldebug. Use -DDEBUGBUILD + when compiling to enable a debug build or run configure with --enable-debug. + + curl --version will list 'Debug' feature for debug enabled builds, and + will list 'TrackMemory' feature for curl debug memory tracking capable + builds. These features are independent and can be controlled when running + the configure script. When --enable-debug is given both features will be + enabled, unless some restriction prevents memory tracking from being used. + + +Test Suite +========== + + The test suite is placed in its own subdirectory directly off the root in the + curl archive tree, and it contains a bunch of scripts and a lot of test case + data. + + The main test script is runtests.pl that will invoke test servers like + httpserver.pl and ftpserver.pl before all the test cases are performed. The + test suite currently only runs on Unix-like platforms. + + You'll find a description of the test suite in the tests/README file, and the + test case data files in the tests/FILEFORMAT file. + + The test suite automatically detects if curl was built with the memory + debugging enabled, and if it was, it will detect memory leaks, too. + + +Asynchronous name resolves +========================== + + libcurl can be built to do name resolves asynchronously, using either the + normal resolver in a threaded manner or by using c-ares. + + +[c-ares][3] +------ + +### Build libcurl to use a c-ares + +1. ./configure --enable-ares=/path/to/ares/install +2. make + +### c-ares on win32 + + First I compiled c-ares. I changed the default C runtime library to be the + single-threaded rather than the multi-threaded (this seems to be required to + prevent linking errors later on). Then I simply build the areslib project + (the other projects adig/ahost seem to fail under MSVC). + + Next was libcurl. I opened lib/config-win32.h and I added a: + `#define USE_ARES 1` + + Next thing I did was I added the path for the ares includes to the include + path, and the libares.lib to the libraries. + + Lastly, I also changed libcurl to be single-threaded rather than + multi-threaded, again this was to prevent some duplicate symbol errors. I'm + not sure why I needed to change everything to single-threaded, but when I + didn't I got redefinition errors for several CRT functions (malloc, stricmp, + etc.) + + +`curl_off_t` +========== + + `curl_off_t` is a data type provided by the external libcurl include + headers. It is the type meant to be used for the [`curl_easy_setopt()`][1] + options that end with LARGE. The type is 64bit large on most modern + platforms. + +curlx +===== + + The libcurl source code offers a few functions by source only. They are not + part of the official libcurl API, but the source files might be useful for + others so apps can optionally compile/build with these sources to gain + additional functions. + + We provide them through a single header file for easy access for apps: + "curlx.h" + +`curlx_strtoofft()` +------------------- + A macro that converts a string containing a number to a `curl_off_t` number. + This might use the `curlx_strtoll()` function which is provided as source + code in strtoofft.c. Note that the function is only provided if no + strtoll() (or equivalent) function exist on your platform. If `curl_off_t` + is only a 32 bit number on your platform, this macro uses strtol(). + +Future +------ + + Several functions will be removed from the public `curl_` name space in a + future libcurl release. They will then only become available as `curlx_` + functions instead. To make the transition easier, we already today provide + these functions with the `curlx_` prefix to allow sources to be built + properly with the new function names. The concerned functions are: + + - `curlx_getenv` + - `curlx_strequal` + - `curlx_strnequal` + - `curlx_mvsnprintf` + - `curlx_msnprintf` + - `curlx_maprintf` + - `curlx_mvaprintf` + - `curlx_msprintf` + - `curlx_mprintf` + - `curlx_mfprintf` + - `curlx_mvsprintf` + - `curlx_mvprintf` + - `curlx_mvfprintf` + + +Content Encoding +================ + +## About content encodings + + [HTTP/1.1][4] specifies that a client may request that a server encode its + response. This is usually used to compress a response using one (or more) + encodings from a set of commonly available compression techniques. These + schemes include 'deflate' (the zlib algorithm), 'gzip' 'br' (brotli) and + 'compress'. A client requests that the server perform an encoding by including + an Accept-Encoding header in the request document. The value of the header + should be one of the recognized tokens 'deflate', ... (there's a way to + register new schemes/tokens, see sec 3.5 of the spec). A server MAY honor + the client's encoding request. When a response is encoded, the server + includes a Content-Encoding header in the response. The value of the + Content-Encoding header indicates which encodings were used to encode the + data, in the order in which they were applied. + + It's also possible for a client to attach priorities to different schemes so + that the server knows which it prefers. See sec 14.3 of RFC 2616 for more + information on the Accept-Encoding header. See sec [3.1.2.2 of RFC 7231][15] + for more information on the Content-Encoding header. + +## Supported content encodings + + The 'deflate', 'gzip' and 'br' content encodings are supported by libcurl. + Both regular and chunked transfers work fine. The zlib library is required + for the 'deflate' and 'gzip' encodings, while the brotli decoding library is + for the 'br' encoding. + +## The libcurl interface + + To cause libcurl to request a content encoding use: + + [`curl_easy_setopt`][1](curl, [`CURLOPT_ACCEPT_ENCODING`][5], string) + + where string is the intended value of the Accept-Encoding header. + + Currently, libcurl does support multiple encodings but only + understands how to process responses that use the "deflate", "gzip" and/or + "br" content encodings, so the only values for [`CURLOPT_ACCEPT_ENCODING`][5] + that will work (besides "identity," which does nothing) are "deflate", + "gzip" and "br". If a response is encoded using the "compress" or methods, + libcurl will return an error indicating that the response could + not be decoded. If is NULL no Accept-Encoding header is generated. + If is a zero-length string, then an Accept-Encoding header + containing all supported encodings will be generated. + + The [`CURLOPT_ACCEPT_ENCODING`][5] must be set to any non-NULL value for + content to be automatically decoded. If it is not set and the server still + sends encoded content (despite not having been asked), the data is returned + in its raw form and the Content-Encoding type is not checked. + +## The curl interface + + Use the [--compressed][6] option with curl to cause it to ask servers to + compress responses using any format supported by curl. + + +hostip.c explained +================== + + The main compile-time defines to keep in mind when reading the host*.c source + file are these: + +## `CURLRES_IPV6` + + this host has getaddrinfo() and family, and thus we use that. The host may + not be able to resolve IPv6, but we don't really have to take that into + account. Hosts that aren't IPv6-enabled have `CURLRES_IPV4` defined. + +## `CURLRES_ARES` + + is defined if libcurl is built to use c-ares for asynchronous name + resolves. This can be Windows or *nix. + +## `CURLRES_THREADED` + + is defined if libcurl is built to use threading for asynchronous name + resolves. The name resolve will be done in a new thread, and the supported + asynch API will be the same as for ares-builds. This is the default under + (native) Windows. + + If any of the two previous are defined, `CURLRES_ASYNCH` is defined too. If + libcurl is not built to use an asynchronous resolver, `CURLRES_SYNCH` is + defined. + +## host*.c sources + + The host*.c sources files are split up like this: + + - hostip.c - method-independent resolver functions and utility functions + - hostasyn.c - functions for asynchronous name resolves + - hostsyn.c - functions for synchronous name resolves + - asyn-ares.c - functions for asynchronous name resolves using c-ares + - asyn-thread.c - functions for asynchronous name resolves using threads + - hostip4.c - IPv4 specific functions + - hostip6.c - IPv6 specific functions + + The hostip.h is the single united header file for all this. It defines the + `CURLRES_*` defines based on the config*.h and `curl_setup.h` defines. + + +Track Down Memory Leaks +======================= + +## Single-threaded + + Please note that this memory leak system is not adjusted to work in more + than one thread. If you want/need to use it in a multi-threaded app. Please + adjust accordingly. + + +## Build + + Rebuild libcurl with -DCURLDEBUG (usually, rerunning configure with + --enable-debug fixes this). 'make clean' first, then 'make' so that all + files are actually rebuilt properly. It will also make sense to build + libcurl with the debug option (usually -g to the compiler) so that debugging + it will be easier if you actually do find a leak in the library. + + This will create a library that has memory debugging enabled. + +## Modify Your Application + + Add a line in your application code: + + `curl_memdebug("dump");` + + This will make the malloc debug system output a full trace of all resource + using functions to the given file name. Make sure you rebuild your program + and that you link with the same libcurl you built for this purpose as + described above. + +## Run Your Application + + Run your program as usual. Watch the specified memory trace file grow. + + Make your program exit and use the proper libcurl cleanup functions etc. So + that all non-leaks are returned/freed properly. + +## Analyze the Flow + + Use the tests/memanalyze.pl perl script to analyze the dump file: + + tests/memanalyze.pl dump + + This now outputs a report on what resources that were allocated but never + freed etc. This report is very fine for posting to the list! + + If this doesn't produce any output, no leak was detected in libcurl. Then + the leak is mostly likely to be in your code. + + +`multi_socket` +============== + + Implementation of the `curl_multi_socket` API + + The main ideas of this API are simply: + + 1 - The application can use whatever event system it likes as it gets info + from libcurl about what file descriptors libcurl waits for what action + on. (The previous API returns `fd_sets` which is very select()-centric). + + 2 - When the application discovers action on a single socket, it calls + libcurl and informs that there was action on this particular socket and + libcurl can then act on that socket/transfer only and not care about + any other transfers. (The previous API always had to scan through all + the existing transfers.) + + The idea is that [`curl_multi_socket_action()`][7] calls a given callback + with information about what socket to wait for what action on, and the + callback only gets called if the status of that socket has changed. + + We also added a timer callback that makes libcurl call the application when + the timeout value changes, and you set that with [`curl_multi_setopt()`][9] + and the [`CURLMOPT_TIMERFUNCTION`][10] option. To get this to work, + Internally, there's an added struct to each easy handle in which we store + an "expire time" (if any). The structs are then "splay sorted" so that we + can add and remove times from the linked list and yet somewhat swiftly + figure out both how long there is until the next nearest timer expires + and which timer (handle) we should take care of now. Of course, the upside + of all this is that we get a [`curl_multi_timeout()`][8] that should also + work with old-style applications that use [`curl_multi_perform()`][11]. + + We created an internal "socket to easy handles" hash table that given + a socket (file descriptor) returns the easy handle that waits for action on + that socket. This hash is made using the already existing hash code + (previously only used for the DNS cache). + + To make libcurl able to report plain sockets in the socket callback, we had + to re-organize the internals of the [`curl_multi_fdset()`][12] etc so that + the conversion from sockets to `fd_sets` for that function is only done in + the last step before the data is returned. I also had to extend c-ares to + get a function that can return plain sockets, as that library too returned + only `fd_sets` and that is no longer good enough. The changes done to c-ares + are available in c-ares 1.3.1 and later. + + +Structs in libcurl +================== + +This section should cover 7.32.0 pretty accurately, but will make sense even +for older and later versions as things don't change drastically that often. + +## Curl_easy + + The `Curl_easy` struct is the one returned to the outside in the external API + as a "CURL *". This is usually known as an easy handle in API documentations + and examples. + + Information and state that is related to the actual connection is in the + 'connectdata' struct. When a transfer is about to be made, libcurl will + either create a new connection or re-use an existing one. The particular + connectdata that is used by this handle is pointed out by + `Curl_easy->easy_conn`. + + Data and information that regard this particular single transfer is put in + the SingleRequest sub-struct. + + When the `Curl_easy` struct is added to a multi handle, as it must be in + order to do any transfer, the ->multi member will point to the `Curl_multi` + struct it belongs to. The ->prev and ->next members will then be used by the + multi code to keep a linked list of `Curl_easy` structs that are added to + that same multi handle. libcurl always uses multi so ->multi *will* point to + a `Curl_multi` when a transfer is in progress. + + ->mstate is the multi state of this particular `Curl_easy`. When + `multi_runsingle()` is called, it will act on this handle according to which + state it is in. The mstate is also what tells which sockets to return for a + specific `Curl_easy` when [`curl_multi_fdset()`][12] is called etc. + + The libcurl source code generally use the name 'data' for the variable that + points to the `Curl_easy`. + + When doing multiplexed HTTP/2 transfers, each `Curl_easy` is associated with + an individual stream, sharing the same connectdata struct. Multiplexing + makes it even more important to keep things associated with the right thing! + +## connectdata + + A general idea in libcurl is to keep connections around in a connection + "cache" after they have been used in case they will be used again and then + re-use an existing one instead of creating a new as it creates a significant + performance boost. + + Each 'connectdata' identifies a single physical connection to a server. If + the connection can't be kept alive, the connection will be closed after use + and then this struct can be removed from the cache and freed. + + Thus, the same `Curl_easy` can be used multiple times and each time select + another connectdata struct to use for the connection. Keep this in mind, as + it is then important to consider if options or choices are based on the + connection or the `Curl_easy`. + + Functions in libcurl will assume that connectdata->data points to the + `Curl_easy` that uses this connection (for the moment). + + As a special complexity, some protocols supported by libcurl require a + special disconnect procedure that is more than just shutting down the + socket. It can involve sending one or more commands to the server before + doing so. Since connections are kept in the connection cache after use, the + original `Curl_easy` may no longer be around when the time comes to shut down + a particular connection. For this purpose, libcurl holds a special dummy + `closure_handle` `Curl_easy` in the `Curl_multi` struct to use when needed. + + FTP uses two TCP connections for a typical transfer but it keeps both in + this single struct and thus can be considered a single connection for most + internal concerns. + + The libcurl source code generally use the name 'conn' for the variable that + points to the connectdata. + +## Curl_multi + + Internally, the easy interface is implemented as a wrapper around multi + interface functions. This makes everything multi interface. + + `Curl_multi` is the multi handle struct exposed as "CURLM *" in external + APIs. + + This struct holds a list of `Curl_easy` structs that have been added to this + handle with [`curl_multi_add_handle()`][13]. The start of the list is + `->easyp` and `->num_easy` is a counter of added `Curl_easy`s. + + `->msglist` is a linked list of messages to send back when + [`curl_multi_info_read()`][14] is called. Basically a node is added to that + list when an individual `Curl_easy`'s transfer has completed. + + `->hostcache` points to the name cache. It is a hash table for looking up + name to IP. The nodes have a limited life time in there and this cache is + meant to reduce the time for when the same name is wanted within a short + period of time. + + `->timetree` points to a tree of `Curl_easy`s, sorted by the remaining time + until it should be checked - normally some sort of timeout. Each `Curl_easy` + has one node in the tree. + + `->sockhash` is a hash table to allow fast lookups of socket descriptor for + which `Curl_easy` uses that descriptor. This is necessary for the + `multi_socket` API. + + `->conn_cache` points to the connection cache. It keeps track of all + connections that are kept after use. The cache has a maximum size. + + `->closure_handle` is described in the 'connectdata' section. + + The libcurl source code generally use the name 'multi' for the variable that + points to the `Curl_multi` struct. + +## Curl_handler + + Each unique protocol that is supported by libcurl needs to provide at least + one `Curl_handler` struct. It defines what the protocol is called and what + functions the main code should call to deal with protocol specific issues. + In general, there's a source file named [protocol].c in which there's a + "struct `Curl_handler` `Curl_handler_[protocol]`" declared. In url.c there's + then the main array with all individual `Curl_handler` structs pointed to + from a single array which is scanned through when a URL is given to libcurl + to work with. + + `->scheme` is the URL scheme name, usually spelled out in uppercase. That's + "HTTP" or "FTP" etc. SSL versions of the protocol need their own `Curl_handler` setup so HTTPS separate from HTTP. + + `->setup_connection` is called to allow the protocol code to allocate + protocol specific data that then gets associated with that `Curl_easy` for + the rest of this transfer. It gets freed again at the end of the transfer. + It will be called before the 'connectdata' for the transfer has been + selected/created. Most protocols will allocate its private + 'struct [PROTOCOL]' here and assign `Curl_easy->req.protop` to point to it. + + `->connect_it` allows a protocol to do some specific actions after the TCP + connect is done, that can still be considered part of the connection phase. + + Some protocols will alter the `connectdata->recv[]` and + `connectdata->send[]` function pointers in this function. + + `->connecting` is similarly a function that keeps getting called as long as + the protocol considers itself still in the connecting phase. + + `->do_it` is the function called to issue the transfer request. What we call + the DO action internally. If the DO is not enough and things need to be kept + getting done for the entire DO sequence to complete, `->doing` is then + usually also provided. Each protocol that needs to do multiple commands or + similar for do/doing need to implement their own state machines (see SCP, + SFTP, FTP). Some protocols (only FTP and only due to historical reasons) has + a separate piece of the DO state called `DO_MORE`. + + `->doing` keeps getting called while issuing the transfer request command(s) + + `->done` gets called when the transfer is complete and DONE. That's after the + main data has been transferred. + + `->do_more` gets called during the `DO_MORE` state. The FTP protocol uses + this state when setting up the second connection. + + ->`proto_getsock` + ->`doing_getsock` + ->`domore_getsock` + ->`perform_getsock` + Functions that return socket information. Which socket(s) to wait for which + action(s) during the particular multi state. + + ->disconnect is called immediately before the TCP connection is shutdown. + + ->readwrite gets called during transfer to allow the protocol to do extra + reads/writes + + ->defport is the default report TCP or UDP port this protocol uses + + ->protocol is one or more bits in the `CURLPROTO_*` set. The SSL versions + have their "base" protocol set and then the SSL variation. Like + "HTTP|HTTPS". + + ->flags is a bitmask with additional information about the protocol that will + make it get treated differently by the generic engine: + + - `PROTOPT_SSL` - will make it connect and negotiate SSL + + - `PROTOPT_DUAL` - this protocol uses two connections + + - `PROTOPT_CLOSEACTION` - this protocol has actions to do before closing the + connection. This flag is no longer used by code, yet still set for a bunch + of protocol handlers. + + - `PROTOPT_DIRLOCK` - "direction lock". The SSH protocols set this bit to + limit which "direction" of socket actions that the main engine will + concern itself with. + + - `PROTOPT_NONETWORK` - a protocol that doesn't use network (read file:) + + - `PROTOPT_NEEDSPWD` - this protocol needs a password and will use a default + one unless one is provided + + - `PROTOPT_NOURLQUERY` - this protocol can't handle a query part on the URL + (?foo=bar) + +## conncache + + Is a hash table with connections for later re-use. Each `Curl_easy` has a + pointer to its connection cache. Each multi handle sets up a connection + cache that all added `Curl_easy`s share by default. + +## Curl_share + + The libcurl share API allocates a `Curl_share` struct, exposed to the + external API as "CURLSH *". + + The idea is that the struct can have a set of its own versions of caches and + pools and then by providing this struct in the `CURLOPT_SHARE` option, those + specific `Curl_easy`s will use the caches/pools that this share handle + holds. + + Then individual `Curl_easy` structs can be made to share specific things + that they otherwise wouldn't, such as cookies. + + The `Curl_share` struct can currently hold cookies, DNS cache and the SSL + session cache. + +## CookieInfo + + This is the main cookie struct. It holds all known cookies and related + information. Each `Curl_easy` has its own private CookieInfo even when + they are added to a multi handle. They can be made to share cookies by using + the share API. + + +[1]: https://curl.haxx.se/libcurl/c/curl_easy_setopt.html +[2]: https://curl.haxx.se/libcurl/c/curl_easy_init.html +[3]: https://c-ares.haxx.se/ +[4]: https://tools.ietf.org/html/rfc7230 "RFC 7230" +[5]: https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html +[6]: https://curl.haxx.se/docs/manpage.html#--compressed +[7]: https://curl.haxx.se/libcurl/c/curl_multi_socket_action.html +[8]: https://curl.haxx.se/libcurl/c/curl_multi_timeout.html +[9]: https://curl.haxx.se/libcurl/c/curl_multi_setopt.html +[10]: https://curl.haxx.se/libcurl/c/CURLMOPT_TIMERFUNCTION.html +[11]: https://curl.haxx.se/libcurl/c/curl_multi_perform.html +[12]: https://curl.haxx.se/libcurl/c/curl_multi_fdset.html +[13]: https://curl.haxx.se/libcurl/c/curl_multi_add_handle.html +[14]: https://curl.haxx.se/libcurl/c/curl_multi_info_read.html +[15]: https://tools.ietf.org/html/rfc7231#section-3.1.2.2 diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS new file mode 100644 index 00000000..c8d8722e --- /dev/null +++ b/docs/KNOWN_BUGS @@ -0,0 +1,696 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + Known Bugs + +These are problems and bugs known to exist at the time of this release. Feel +free to join in and help us correct one or more of these! Also be sure to +check the changelog of the current development status, as one or more of these +problems may have been fixed or changed somewhat since this was written! + + 1. HTTP + 1.1 CURLFORM_CONTENTLEN in an array + 1.2 Disabling HTTP Pipelining + 1.3 STARTTRANSFER time is wrong for HTTP POSTs + 1.4 multipart formposts file name encoding + 1.5 Expect-100 meets 417 + 1.6 Unnecessary close when 401 received waiting for 100 + 1.9 HTTP/2 frames while in the connection pool kill reuse + 1.10 Strips trailing dot from host name + 1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM + + 2. TLS + 2.1 CURLINFO_SSL_VERIFYRESULT has limited support + 2.2 DER in keychain + 2.3 GnuTLS backend skips really long certificate fields + 2.4 DarwinSSL won't import PKCS#12 client certificates without a password + 2.5 Client cert handling with Issuer DN differs between backends + 2.6 CURL_GLOBAL_SSL + + 3. Email protocols + 3.1 IMAP SEARCH ALL truncated response + 3.2 No disconnect command + 3.3 SMTP to multiple recipients + 3.4 POP3 expects "CRLF.CRLF" eob for some single-line responses + + 4. Command line + 4.1 -J and -O with %-encoded file names + 4.2 -J with -C - fails + 4.3 --retry and transfer timeouts + 4.4 --upload-file . hang if delay in STDIN + + 5. Build and portability issues + 5.2 curl-config --libs contains private details + 5.5 can't handle Unicode arguments in Windows + 5.6 cmake support gaps + 5.7 Visual Studio project gaps + 5.8 configure finding libs in wrong directory + 5.9 Utilize Requires.private directives in libcurl.pc + + 6. Authentication + 6.1 NTLM authentication and unicode + 6.2 MIT Kerberos for Windows build + 6.3 NTLM in system context uses wrong name + 6.4 Negotiate and Kerberos V5 need a fake user name + 6.5 NTLM doen't support password with § character + + 7. FTP + 7.1 FTP without or slow 220 response + 7.2 FTP with CONNECT and slow server + 7.3 FTP with NOBODY and FAILONERROR + 7.4 FTP with ACCT + 7.5 ASCII FTP + 7.6 FTP with NULs in URL parts + 7.7 FTP and empty path parts in the URL + 7.8 Premature transfer end but healthy control channel + 7.9 Passive transfer tries only one IP address + 7.10 Stick to same family over SOCKS proxy + + 8. TELNET + 8.1 TELNET and time limtiations don't work + 8.2 Microsoft telnet server + + 9. SFTP and SCP + 9.1 SFTP doesn't do CURLOPT_POSTQUOTE correct + + 10. SOCKS + 10.1 SOCKS proxy connections are done blocking + 10.2 SOCKS don't support timeouts + 10.3 FTPS over SOCKS + 10.4 active FTP over a SOCKS + + 11. Internals + 11.1 Curl leaks .onion hostnames in DNS + 11.2 error buffer not set if connection to multiple addresses fails + 11.3 c-ares deviates from stock resolver on http://1346569778 + 11.4 HTTP test server 'connection-monitor' problems + 11.5 Connection information when using TCP Fast Open + 11.6 slow connect to localhost on Windows + + 12. LDAP and OpenLDAP + 12.1 OpenLDAP hangs after returning results + + 13. TCP/IP + 13.1 --interface for ipv6 binds to unusable IP address + + 14 DICT + 14.1 DICT responses show the underlying protocol + +============================================================================== + +1. HTTP + +1.1 CURLFORM_CONTENTLEN in an array + + It is not possible to pass a 64-bit value using CURLFORM_CONTENTLEN with + CURLFORM_ARRAY, when compiled on 32-bit platforms that support 64-bit + integers. This is because the underlying structure 'curl_forms' uses a dual + purpose char* for storing these values in via casting. For more information + see the now closed related issue: + https://github.com/curl/curl/issues/608 + +1.2 Disabling HTTP Pipelining + + Disabling HTTP Pipelining when there are ongoing transfers can lead to + heap corruption and crash. https://curl.haxx.se/bug/view.cgi?id=1411 + + Similarly, removing a handle when pipelining corrupts data: + https://github.com/curl/curl/issues/2101 + +1.3 STARTTRANSFER time is wrong for HTTP POSTs + + Wrong STARTTRANSFER timer accounting for POST requests Timer works fine with + GET requests, but while using POST the time for CURLINFO_STARTTRANSFER_TIME + is wrong. While using POST CURLINFO_STARTTRANSFER_TIME minus + CURLINFO_PRETRANSFER_TIME is near to zero every time. + + https://github.com/curl/curl/issues/218 + https://curl.haxx.se/bug/view.cgi?id=1213 + +1.4 multipart formposts file name encoding + + When creating multipart formposts. The file name part can be encoded with + something beyond ascii but currently libcurl will only pass in the verbatim + string the app provides. There are several browsers that already do this + encoding. The key seems to be the updated draft to RFC2231: + https://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02 + +1.5 Expect-100 meets 417 + + If an upload using Expect: 100-continue receives an HTTP 417 response, it + ought to be automatically resent without the Expect:. A workaround is for + the client application to redo the transfer after disabling Expect:. + https://curl.haxx.se/mail/archive-2008-02/0043.html + +1.6 Unnecessary close when 401 received waiting for 100 + + libcurl closes the connection if an HTTP 401 reply is received while it is + waiting for the the 100-continue response. + https://curl.haxx.se/mail/lib-2008-08/0462.html + +1.9 HTTP/2 frames while in the connection pool kill reuse + + If the server sends HTTP/2 frames (like for example an HTTP/2 PING frame) to + curl while the connection is held in curl's connection pool, the socket will + be found readable when considered for reuse and that makes curl think it is + dead and then it will be closed and a new connection gets created instead. + + This is *best* fixed by adding monitoring to connections while they are kept + in the pool so that pings can be responded to appropriately. + +1.10 Strips trailing dot from host name + + When given a URL with a trailing dot for the host name part: + "https://example.com./", libcurl will strip off the dot and use the name + without a dot internally and send it dot-less in HTTP Host: headers and in + the TLS SNI field. + + The HTTP part violates RFC 7230 section 5.4 but the SNI part is accordance + with RFC 6066 section 3. + + URLs using these trailing dots are very rare in the wild and we have not seen + or gotten any real-world problems with such URLs reported. The popular + browsers seem to have stayed with not stripping the dot for both uses (thus + they violate RFC 6066 instead of RFC 7230). + + Daniel took the discussion to the HTTPbis mailing list in March 2016: + https://lists.w3.org/Archives/Public/ietf-http-wg/2016JanMar/0430.html but + there was not major rush or interest to fix this. The impression I get is + that most HTTP people rather not rock the boat now and instead prioritize web + compatibility rather than to strictly adhere to these RFCs. + + Our current approach allows a knowing client to send a custom HTTP header + with the dot added. + + It can also be noted that while adding a trailing dot to the host name in + most (all?) cases will make the name resolve to the same set of IP addresses, + many HTTP servers will not happily accept the trailing dot there unless that + has been specifically configured to be a fine virtual host. + + If URLs with trailing dots for host names become more popular or even just + used more than for just plain fun experiments, I'm sure we will have reason + to go back and reconsider. + + See https://github.com/curl/curl/issues/716 for the discussion. + +1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM + + I'm using libcurl to POST form data using a FILE* with the CURLFORM_STREAM + option of curl_formadd(). I've noticed that if the connection drops at just + the right time, the POST is reattempted without the data from the file. It + seems like the file stream position isn't getting reset to the beginning of + the file. I found the CURLOPT_SEEKFUNCTION option and set that with a + function that performs an fseek() on the FILE*. However, setting that didn't + seem to fix the issue or even get called. See + https://github.com/curl/curl/issues/768 + + +2. TLS + +2.1 CURLINFO_SSL_VERIFYRESULT has limited support + + CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS + backends, so relying on this information in a generic app is flaky. + +2.2 DER in keychain + + Curl doesn't recognize certificates in DER format in keychain, but it works + with PEM. https://curl.haxx.se/bug/view.cgi?id=1065 + +2.3 GnuTLS backend skips really long certificate fields + + libcurl calls gnutls_x509_crt_get_dn() with a fixed buffer size and if the + field is too long in the cert, it'll just return an error and the field will + be displayed blank. + +2.4 DarwinSSL won't import PKCS#12 client certificates without a password + + libcurl calls SecPKCS12Import with the PKCS#12 client certificate, but that + function rejects certificates that do not have a password. + https://github.com/curl/curl/issues/1308 + +2.5 Client cert handling with Issuer DN differs between backends + + When the specified client certificate doesn't match any of the + server-specified DNs, the OpenSSL and GnuTLS backends behave differently. + The github discussion may contain a solution. + + See https://github.com/curl/curl/issues/1411 + +2.6 CURL_GLOBAL_SSL + + Since libcurl 7.57.0, the flag CURL_GLOBAL_SSL is a no-op. The change was + merged in https://github.com/curl/curl/commit/d661b0afb571a + + It was removed since it was + + A) never clear for applications on how to deal with init in the light of + different SSL backends (the option was added back in the days when life + was simpler) + + B) multissl introduced dynamic switching between SSL backends which + emphasized (A) even more + + C) libcurl uses some TLS backend functionality even for non-TLS functions (to + get "good" random) so applications trying to avoid the init for + performance reasons would do wrong anyway + + D) never very carefully documented so all this mostly just happened to work + for some users + + However, in spite of the problems with the feature, there were some users who + apparently depended on this feature and who now claim libcurl is broken for + them. The fix for this situation is not obvious as a downright revert of the + patch is totally ruled out due to those reasons above. + + https://github.com/curl/curl/issues/2276 + + +3. Email protocols + +3.1 IMAP SEARCH ALL truncated response + + IMAP "SEARCH ALL" truncates output on large boxes. "A quick search of the + code reveals that pingpong.c contains some truncation code, at line 408, when + it deems the server response to be too large truncating it to 40 characters" + https://curl.haxx.se/bug/view.cgi?id=1366 + +3.2 No disconnect command + + The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3 and + SMTP if a failure occurs during the authentication phase of a connection. + +3.3 SMTP to multiple recipients + + When sending data to multiple recipients, curl will abort and return failure + if one of the recipients indicate failure (on the "RCPT TO" + command). Ordinary mail programs would proceed and still send to the ones + that can receive data. This is subject for change in the future. + https://curl.haxx.se/bug/view.cgi?id=1116 + +3.4 POP3 expects "CRLF.CRLF" eob for some single-line responses + + You have to tell libcurl not to expect a body, when dealing with one line + response commands. Please see the POP3 examples and test cases which show + this for the NOOP and DELE commands. https://curl.haxx.se/bug/?i=740 + + +4. Command line + +4.1 -J and -O with %-encoded file names + + -J/--remote-header-name doesn't decode %-encoded file names. RFC6266 details + how it should be done. The can of worm is basically that we have no charset + handling in curl and ascii >=128 is a challenge for us. Not to mention that + decoding also means that we need to check for nastiness that is attempted, + like "../" sequences and the like. Probably everything to the left of any + embedded slashes should be cut off. + https://curl.haxx.se/bug/view.cgi?id=1294 + + -O also doesn't decode %-encoded names, and while it has even less + information about the charset involved the process is similar to the -J case. + + Note that we won't add decoding to -O without the user asking for it with + some other means as well, since -O has always been documented to use the name + exactly as specified in the URL. + +4.2 -J with -C - fails + + When using -J (with -O), automatically resumed downloading together with "-C + -" fails. Without -J the same command line works! This happens because the + resume logic is worked out before the target file name (and thus its + pre-transfer size) has been figured out! + https://curl.haxx.se/bug/view.cgi?id=1169 + +4.3 --retry and transfer timeouts + + If using --retry and the transfer timeouts (possibly due to using -m or + -y/-Y) the next attempt doesn't resume the transfer properly from what was + downloaded in the previous attempt but will truncate and restart at the + original position where it was at before the previous failed attempt. See + https://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report + https://qa.mandriva.com/show_bug.cgi?id=22565 + +4.4 --upload-file . hangs if delay in STDIN + + "(echo start; sleep 1; echo end) | curl --upload-file . http://mywebsite -vv" + + ... causes a hang when it shouldn't. + + See https://github.com/curl/curl/issues/2051 + +5. Build and portability issues + +5.2 curl-config --libs contains private details + + "curl-config --libs" will include details set in LDFLAGS when configure is + run that might be needed only for building libcurl. Further, curl-config + --cflags suffers from the same effects with CFLAGS/CPPFLAGS. + +5.5 can't handle Unicode arguments in Windows + + If a URL or filename can't be encoded using the user's current codepage then + it can only be encoded properly in the Unicode character set. Windows uses + UTF-16 encoding for Unicode and stores it in wide characters, however curl + and libcurl are not equipped for that at the moment. And, except for Cygwin, + Windows can't use UTF-8 as a locale. + + https://curl.haxx.se/bug/?i=345 + https://curl.haxx.se/bug/?i=731 + +5.6 cmake support gaps + + The cmake build setup lacks several features that the autoconf build + offers. This includes: + + - use of correct soname for the shared library build + - support for several TLS backends are missing + - the unit tests cause link failures in regular non-static builds + - no nghttp2 check + +5.7 Visual Studio project gaps + + The Visual Studio projects lack some features that the autoconf and nmake + builds offer, such as the following: + + - support for zlib and nghttp2 + - use of static runtime libraries + - add the test suite components + + In addition to this the following could be implemented: + + - support for other development IDEs + - add PATH environment variables for third-party DLLs + +5.8 configure finding libs in wrong directory + + When the configure script checks for third-party libraries, it adds those + directories to the LDFLAGS variable and then tries linking to see if it + works. When successful, the found directory is kept in the LDFLAGS variable + when the script continues to execute and do more tests and possibly check for + more libraries. + + This can make subsequent checks for libraries wrongly detect another + installation in a directory that was previously added to LDFLAGS by another + library check! + + A possibly better way to do these checks would be to keep the pristine LDFLAGS + even after successful checks and instead add those verified paths to a + separate variable that only after all library checks have been performed gets + appended to LDFLAGS. + +5.9 Utilize Requires.private directives in libcurl.pc + + https://github.com/curl/curl/issues/864 + +6. Authentication + +6.1 NTLM authentication and unicode + + NTLM authentication involving unicode user name or password only works + properly if built with UNICODE defined together with the WinSSL/schannel + backend. The original problem was mentioned in: + https://curl.haxx.se/mail/lib-2009-10/0024.html + https://curl.haxx.se/bug/view.cgi?id=896 + + The WinSSL/schannel version verified to work as mentioned in + https://curl.haxx.se/mail/lib-2012-07/0073.html + +6.2 MIT Kerberos for Windows build + + libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's + library header files exporting symbols/macros that should be kept private to + the KfW library. See ticket #5601 at https://krbdev.mit.edu/rt/ + +6.3 NTLM in system context uses wrong name + + NTLM authentication using SSPI (on Windows) when (lib)curl is running in + "system context" will make it use wrong(?) user name - at least when compared + to what winhttp does. See https://curl.haxx.se/bug/view.cgi?id=535 + +6.4 Negotiate and Kerberos V5 need a fake user name + + In order to get Negotiate (SPNEGO) authentication to work in HTTP or Kerberos + V5 in the e-mail protocols, you need to provide a (fake) user name (this + concerns both curl and the lib) because the code wrongly only considers + authentication if there's a user name provided by setting + conn->bits.user_passwd in url.c https://curl.haxx.se/bug/view.cgi?id=440 How? + https://curl.haxx.se/mail/lib-2004-08/0182.html A possible solution is to + either modify this variable to be set or introduce a variable such as + new conn->bits.want_authentication which is set when any of the authentication + options are set. + +6.5 NTLM doen't support password with § character + + https://github.com/curl/curl/issues/2120 + +7. FTP + +7.1 FTP without or slow 220 response + + If a connection is made to a FTP server but the server then just never sends + the 220 response or otherwise is dead slow, libcurl will not acknowledge the + connection timeout during that phase but only the "real" timeout - which may + surprise users as it is probably considered to be the connect phase to most + people. Brought up (and is being misunderstood) in: + https://curl.haxx.se/bug/view.cgi?id=856 + +7.2 FTP with CONNECT and slow server + + When doing FTP over a socks proxy or CONNECT through HTTP proxy and the multi + interface is used, libcurl will fail if the (passive) TCP connection for the + data transfer isn't more or less instant as the code does not properly wait + for the connect to be confirmed. See test case 564 for a first shot at a test + case. + +7.3 FTP with NOBODY and FAILONERROR + + It seems sensible to be able to use CURLOPT_NOBODY and CURLOPT_FAILONERROR + with FTP to detect if a file exists or not, but it is not working: + https://curl.haxx.se/mail/lib-2008-07/0295.html + +7.4 FTP with ACCT + + When doing an operation over FTP that requires the ACCT command (but not when + logging in), the operation will fail since libcurl doesn't detect this and + thus fails to issue the correct command: + https://curl.haxx.se/bug/view.cgi?id=635 + +7.5 ASCII FTP + + FTP ASCII transfers do not follow RFC959. They don't convert the data + accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1 + clearly describes how this should be done: + + The sender converts the data from an internal character representation to + the standard 8-bit NVT-ASCII representation (see the Telnet + specification). The receiver will convert the data from the standard + form to his own internal form. + + Since 7.15.4 at least line endings are converted. + +7.6 FTP with NULs in URL parts + + FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 , + , and components, encoded as "%00". The problem is that + curl_unescape does not detect this, but instead returns a shortened C string. + From a strict FTP protocol standpoint, NUL is a valid character within RFC + 959 , so the way to handle this correctly in curl would be to use a + data structure other than a plain C string, one that can handle embedded NUL + characters. From a practical standpoint, most FTP servers would not + meaningfully support NUL characters within RFC 959 , anyway (e.g., + Unix pathnames may not contain NUL). + +7.7 FTP and empty path parts in the URL + + libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that + such parts should be sent to the server as 'CWD ' (without an argument). The + only exception to this rule, is that we knowingly break this if the empty + part is first in the path, as then we use the double slashes to indicate that + the user wants to reach the root dir (this exception SHALL remain even when + this bug is fixed). + +7.8 Premature transfer end but healthy control channel + + When 'multi_done' is called before the transfer has been completed the normal + way, it is considered a "premature" transfer end. In this situation, libcurl + closes the connection assuming it doesn't know the state of the connection so + it can't be reused for subsequent requests. + + With FTP however, this isn't necessarily true but there are a bunch of + situations (listed in the ftp_done code) where it *could* keep the connection + alive even in this situation - but the current code doesn't. Fixing this would + allow libcurl to reuse FTP connections better. + +7.9 Passive transfer tries only one IP address + + When doing FTP operations through a proxy at localhost, the reported spotted + that curl only tried to connect once to the proxy, while it had mulitiple + addresses and a failed connect on one address should make it try the next. + + After switching to passive mode (EPSV), curl should try all IP addresses for + "localhost". Currently it tries ::1, but it should also try 127.0.0.1. + + See https://github.com/curl/curl/issues/1508 + +7.10 Stick to same family over SOCKS proxy + + When asked to do FTP over a SOCKS proxy, it might connect to the proxy (and + then subsequently to the remote server) using for example IPv4. When doing + the second connection, curl should make sure that the second connection is + using the same IP protocol version as the first connection did and not try + others, since the remote server will only accept the same. + + See https://curl.haxx.se/mail/archive-2018-07/0000.html + +8. TELNET + +8.1 TELNET and time limtiations don't work + + When using telnet, the time limitation options don't work. + https://curl.haxx.se/bug/view.cgi?id=846 + +8.2 Microsoft telnet server + + There seems to be a problem when connecting to the Microsoft telnet server. + https://curl.haxx.se/bug/view.cgi?id=649 + + +9. SFTP and SCP + +9.1 SFTP doesn't do CURLOPT_POSTQUOTE correct + + When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP server + using the multi interface, the commands are not being sent correctly and + instead the connection is "cancelled" (the operation is considered done) + prematurely. There is a half-baked (busy-looping) patch provided in the bug + report but it cannot be accepted as-is. See + https://curl.haxx.se/bug/view.cgi?id=748 + + +10. SOCKS + +10.1 SOCKS proxy connections are done blocking + + Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very bad + when used with the multi interface. + +10.2 SOCKS don't support timeouts + + The SOCKS4 connection codes don't properly acknowledge (connect) timeouts. + According to bug #1556528, even the SOCKS5 connect code does not do it right: + https://curl.haxx.se/bug/view.cgi?id=604 + + When connecting to a SOCK proxy, the (connect) timeout is not properly + acknowledged after the actual TCP connect (during the SOCKS "negotiate" + phase). + +10.3 FTPS over SOCKS + + libcurl doesn't support FTPS over a SOCKS proxy. + +10.4 active FTP over a SOCKS + + libcurl doesn't support active FTP over a SOCKS proxy + + +11. Internals + +11.1 Curl leaks .onion hostnames in DNS + + Curl sends DNS requests for hostnames with a .onion TLD. This leaks + information about what the user is attempting to access, and violates this + requirement of RFC7686: https://tools.ietf.org/html/rfc7686 + + Issue: https://github.com/curl/curl/issues/543 + +11.2 error buffer not set if connection to multiple addresses fails + + If you ask libcurl to resolve a hostname like example.com to IPv6 addresses + only. But you only have IPv4 connectivity. libcurl will correctly fail with + CURLE_COULDNT_CONNECT. But the error buffer set by CURLOPT_ERRORBUFFER + remains empty. Issue: https://github.com/curl/curl/issues/544 + +11.3 c-ares deviates from stock resolver on http://1346569778 + + When using the socket resolvers, that URL becomes: + + * Rebuilt URL to: http://1346569778/ + * Trying 80.67.6.50... + + but with c-ares it instead says "Could not resolve: 1346569778 (Domain name + not found)" + + See https://github.com/curl/curl/issues/893 + +11.4 HTTP test server 'connection-monitor' problems + + The 'connection-monitor' feature of the sws HTTP test server doesn't work + properly if some tests are run in unexpected order. Like 1509 and then 1525. + + See https://github.com/curl/curl/issues/868 + +11.5 Connection information when using TCP Fast Open + + CURLINFO_LOCAL_PORT (and possibly a few other) fails when TCP Fast Open is + enabled. + + See https://github.com/curl/curl/issues/1332 + +11.6 slow connect to localhost on Windows + + When connecting to "localhost" on Windows, curl will resolve the name for + both ipv4 and ipv6 and try to connect to both happy eyeballs-style. Something + in there does however make it take 200 millseconds to succeed - which is the + HAPPY_EYEBALLS_TIMEOUT define exactly. Lowering that define speeds up the + connection, suggesting a problem in the HE handling. + + If we can *know* that we're talking to a local host, we should lower the + happy eyeballs delay timeout for IPv6 (related: hardcode the "localhost" + addresses, mentioned in TODO). Possibly we should reduce that delay for all. + + https://github.com/curl/curl/issues/2281 + +12. LDAP and OpenLDAP + +12.1 OpenLDAP hangs after returning results + + By configuration defaults, openldap automatically chase referrals on + secondary socket descriptors. The OpenLDAP backend is asynchronous and thus + should monitor all socket descriptors involved. Currently, these secondary + descriptors are not monitored, causing openldap library to never receive + data from them. + + As a temporary workaround, disable referrals chasing by configuration. + + The fix is not easy: proper automatic referrals chasing requires a + synchronous bind callback and monitoring an arbitrary number of socket + descriptors for a single easy handle (currently limited to 5). + + Generic LDAP is synchronous: OK. + + See https://github.com/curl/curl/issues/622 and + https://curl.haxx.se/mail/lib-2016-01/0101.html + + +13. TCP/IP + +13.1 --interface for ipv6 binds to unusable IP address + + Since IPv6 provides a lot of addresses with different scope, binding to an + IPv6 address needs to take the proper care so that it doesn't bind to a + locally scoped address as that is bound to fail. + + https://github.com/curl/curl/issues/686 + +14. DICT + +14.1 DICT responses show the underlying protocol + + When getting a DICT response, the protocol parts of DICT aren't stripped off + from the output. + + https://github.com/curl/curl/issues/1809 diff --git a/docs/LICENSE-MIXING.md b/docs/LICENSE-MIXING.md new file mode 100644 index 00000000..5376bdb7 --- /dev/null +++ b/docs/LICENSE-MIXING.md @@ -0,0 +1,127 @@ +License Mixing +============== + +libcurl can be built to use a fair amount of various third party libraries, +libraries that are written and provided by other parties that are distributed +using their own licenses. Even libcurl itself contains code that may cause +problems to some. This document attempts to describe what licenses libcurl and +the other libraries use and what possible dilemmas linking and mixing them all +can lead to for end users. + +I am not a lawyer and this is not legal advice! + +One common dilemma is that [GPL](https://www.gnu.org/licenses/gpl.html) +licensed code is not allowed to be linked with code licensed under the +[Original BSD license](https://spdx.org/licenses/BSD-4-Clause.html) (with the +announcement clause). You may still build your own copies that use them all, +but distributing them as binaries would be to violate the GPL license - unless +you accompany your license with an +[exception](https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs). This +particular problem was addressed when the [Modified BSD +license](https://opensource.org/licenses/BSD-3-Clause) was created, which does +not have the announcement clause that collides with GPL. + +## libcurl + + Uses an [MIT style license](https://curl.haxx.se/docs/copyright.html) that is + very liberal. + +## OpenSSL + + (May be used for SSL/TLS support) Uses an Original BSD-style license with an + announcement clause that makes it "incompatible" with GPL. You are not + allowed to ship binaries that link with OpenSSL that includes GPL code + (unless that specific GPL code includes an exception for OpenSSL - a habit + that is growing more and more common). If OpenSSL's licensing is a problem + for you, consider using another TLS library. + +## GnuTLS + + (May be used for SSL/TLS support) Uses the + [LGPL](https://www.gnu.org/licenses/lgpl.html) license. If this is a problem + for you, consider using another TLS library. Also note that GnuTLS itself + depends on and uses other libs (libgcrypt and libgpg-error) and they too are + LGPL- or GPL-licensed. + +## WolfSSL + + (May be used for SSL/TLS support) Uses the GPL license or a proprietary + license. If this is a problem for you, consider using another TLS library. + +## NSS + + (May be used for SSL/TLS support) Is covered by the + [MPL](https://www.mozilla.org/MPL/) license, the GPL license and the LGPL + license. You may choose to license the code under MPL terms, GPL terms, or + LGPL terms. These licenses grant you different permissions and impose + different obligations. You should select the license that best meets your + needs. + +## axTLS + + (May be used for SSL/TLS support) Uses a Modified BSD-style license. + +## mbedTLS + + (May be used for SSL/TLS support) Uses the [Apache 2.0 + license](https://opensource.org/licenses/Apache-2.0) or the GPL license. + You may choose to license the code under Apache 2.0 terms or GPL terms. + These licenses grant you different permissions and impose different + obligations. You should select the license that best meets your needs. + +## BoringSSL + + (May be used for SSL/TLS support) As an OpenSSL fork, it has the same + license as that. + +## libressl + + (May be used for SSL/TLS support) As an OpenSSL fork, it has the same + license as that. + +## c-ares + + (Used for asynchronous name resolves) Uses an MIT license that is very + liberal and imposes no restrictions on any other library or part you may link + with. + +## zlib + + (Used for compressed Transfer-Encoding support) Uses an MIT-style license + that shouldn't collide with any other library. + +## MIT Kerberos + + (May be used for GSS support) MIT licensed, that shouldn't collide with any + other parts. + +## Heimdal + + (May be used for GSS support) Heimdal is Original BSD licensed with the + announcement clause. + +## GNU GSS + + (May be used for GSS support) GNU GSS is GPL licensed. Note that you may not + distribute binary curl packages that uses this if you build curl to also link + and use any Original BSD licensed libraries! + +## libidn + + (Used for IDNA support) Uses the GNU Lesser General Public License [3]. LGPL + is a variation of GPL with slightly less aggressive "copyleft". This license + requires more requirements to be met when distributing binaries, see the + license for details. Also note that if you distribute a binary that includes + this library, you must also include the full LGPL license text. Please + properly point out what parts of the distributed package that the license + addresses. + +## OpenLDAP + + (Used for LDAP support) Uses a Modified BSD-style license. Since libcurl uses + OpenLDAP as a shared library only, I have not heard of anyone that ships + OpenLDAP linked with libcurl in an app. + +## libssh2 + + (Used for scp and sftp support) libssh2 uses a Modified BSD-style license. diff --git a/docs/MAIL-ETIQUETTE b/docs/MAIL-ETIQUETTE new file mode 100644 index 00000000..07660a00 --- /dev/null +++ b/docs/MAIL-ETIQUETTE @@ -0,0 +1,285 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +MAIL ETIQUETTE + + 1. About the lists + 1.1 Mailing Lists + 1.2 Netiquette + 1.3 Do Not Mail a Single Individual + 1.4 Subscription Required + 1.5 Moderation of new posters + 1.6 Handling trolls and spam + 1.7 How to unsubscribe + 1.8 I posted, now what? + 1.9 Your emails are public + + 2. Sending mail + 2.1 Reply or New Mail + 2.2 Reply to the List + 2.3 Use a Sensible Subject + 2.4 Do Not Top-Post + 2.5 HTML is not for mails + 2.6 Quoting + 2.7 Digest + 2.8 Please Tell Us How You Solved The Problem! + +============================================================================== + +1. About the lists + + 1.1 Mailing Lists + + The mailing lists we have are all listed and described at + https://curl.haxx.se/mail/ + + Each mailing list is targeted to a specific set of users and subjects, + please use the one or the ones that suit you the most. + + Each mailing list has hundreds up to thousands of readers, meaning that + each mail sent will be received and read by a very large number of people. + People from various cultures, regions, religions and continents. + + 1.2 Netiquette + + Netiquette is a common term for how to behave on the internet. Of course, in + each particular group and subculture there will be differences in what is + acceptable and what is considered good manners. + + This document outlines what we in the curl project consider to be good + etiquette, and primarily this focus on how to behave on and how to use our + mailing lists. + + 1.3 Do Not Mail a Single Individual + + Many people send one question to one person. One person gets many mails, and + there is only one person who can give you a reply. The question may be + something that other people would also like to ask. These other people have + no way to read the reply, but to ask the one person the question. The one + person consequently gets overloaded with mail. + + If you really want to contact an individual and perhaps pay for his or her + services, by all means go ahead, but if it's just another curl question, + take it to a suitable list instead. + + 1.4 Subscription Required + + All curl mailing lists require that you are subscribed to allow a mail to go + through to all the subscribers. + + If you post without being subscribed (or from a different mail address than + the one you are subscribed with), your mail will simply be silently + discarded. You have to subscribe first, then post. + + The reason for this unfortunate and strict subscription policy is of course + to stop spam from pestering the lists. + + 1.5 Moderation of new posters + + Several of the curl mailing lists automatically make all posts from new + subscribers be moderated. This means that after you've subscribed and + sent your first mail to a list, that mail will not be let through to the + list until a mailing list administrator has verified that it is OK and + permits it to get posted. + + Once a first post has been made that proves the sender is actually talking + about curl-related subjects, the moderation "flag" will be switched off and + future posts will go through without being moderated. + + The reason for this moderation policy is that we do suffer from spammers who + actually subscribe and send spam to our lists. + + 1.6 Handling trolls and spam + + Despite our good intentions and hard work to keep spam off the lists and to + maintain a friendly and positive atmosphere, there will be times when spam + and or trolls get through. + + Troll - "someone who posts inflammatory, extraneous, or off-topic messages + in an online community" + + Spam - "use of electronic messaging systems to send unsolicited bulk + messages" + + No matter what, we NEVER EVER respond to trolls or spammers on the list. If + you believe the list admin should do something in particular, contact him/her + off-list. The subject will be taken care of as much as possible to prevent + repeated offenses, but responding on the list to such messages never leads to + anything good and only puts the light even more on the offender: which was + the entire purpose of it getting sent to the list in the first place. + + Don't feed the trolls! + + 1.7 How to unsubscribe + + You can unsubscribe the same way you subscribed in the first place. You go + to the page for the particular mailing list you're subscribed to and you enter + your email address and password and press the unsubscribe button. + + Also, the instructions to unsubscribe are included in the headers of every + mail that is sent out to all curl related mailing lists and there's a footer + in each mail that links to the "admin" page on which you can unsubscribe and + change other options. + + You NEVER EVER email the mailing list requesting someone else to take you off + the list. + + 1.8 I posted, now what? + + If you aren't subscribed with the exact same email address that you used to + send the email, your post will just be silently discarded. + + If you posted for the first time to the mailing list, you first need to wait + for an administrator to allow your email to go through (moderated). This normally + happens very quickly but in case we're asleep, you may have to wait a few + hours. + + Once your email goes through it is sent out to several hundred or even + thousands of recipients. Your email may cover an area that not that many people + know about or are interested in. Or possibly the person who knows about it + is on vacation or under a very heavy work load right now. You may have to wait + for a response and you should not expect to get a response at all, but + hopefully you get an answer within a couple of days. + + You do yourself and all of us a service when you include as many details as + possible already in your first email. Mention your operating system and + environment. Tell us which curl version you're using and tell us what you + did, what happened and what you expected would happen. Preferably, show us + what you did with details enough to allow others to help point out the problem + or repeat the same steps in their locations. + + Failing to include details will only delay responses and make people respond + and ask for more details and you will have to send a follow-up email that + includes them. + + Expect the responses to primarily help YOU debug the issue, or ask YOU + questions that can lead you or others towards a solution or explanation to + whatever you experience. + + If you are a repeat offender to the guidelines outlined in this document, + chances are that people will ignore you at will and your chances to get + responses in the future will greatly diminish. + + 1.9 Your emails are public + + Your email, its contents and all its headers and the details in those + headers will be received by every subscriber of the mailing list that you + send your email to. + + Your email as sent to a curl mailing list will end up in mail archives, on + the curl web site and elsewhere, for others to see and read. Today and in + the future. In addition to the archives, the mail is sent out to thousands + of individuals. There is no way to undo a sent email. + + When sending emails to a curl mailing list, do not include sensitive + information such as user names and passwords; use fake ones, temporary ones + or just remove them completely from the mail. Note that this includes base64 + encoded HTTP Basic auth headers. + + This public nature of the curl mailing lists makes automatically inserted mail + footers about mails being "private" or "only meant for the recipient" or + similar even more silly than usual. Because they are absolutely not private + when sent to a public mailing list. + + +2. Sending mail + + 2.1 Reply or New Mail + + Please do not reply to an existing message as a short-cut to post a message + to the lists. + + Many mail programs and web archivers use information within mails to keep + them together as "threads", as collections of posts that discuss a certain + subject. If you don't intend to reply on the same or similar subject, don't + just hit reply on an existing mail and change subject, create a new mail. + + 2.2 Reply to the List + + When replying to a message from the list, make sure that you do "group + reply" or "reply to all", and not just reply to the author of the single + mail you reply to. + + We're actively discouraging replying back to the single person by setting + the Reply-To: field in outgoing mails back to the mailing list address, + making it harder for people to mail the author directly, if only by mistake. + + 2.3 Use a Sensible Subject + + Please use a subject of the mail that makes sense and that is related to the + contents of your mail. It makes it a lot easier to find your mail afterwards + and it makes it easier to track mail threads and topics. + + 2.4 Do Not Top-Post + + If you reply to a message, don't use top-posting. Top-posting is when you + write the new text at the top of a mail and you insert the previous quoted + mail conversation below. It forces users to read the mail in a backwards + order to properly understand it. + + This is why top posting is so bad (in top posting order): + + A: Because it messes up the order in which people normally read text. + Q: Why is top-posting such a bad thing? + A: Top-posting. + Q: What is the most annoying thing in e-mail? + + Apart from the screwed up read order (especially when mixed together in a + thread when someone responds using the mandated bottom-posting style), it + also makes it impossible to quote only parts of the original mail. + + When you reply to a mail. You let the mail client insert the previous mail + quoted. Then you put the cursor on the first line of the mail and you move + down through the mail, deleting all parts of the quotes that don't add + context for your comments. When you want to add a comment you do so, inline, + right after the quotes that relate to your comment. Then you continue + downwards again. + + When most of the quotes have been removed and you've added your own words, + you're done! + + 2.5 HTML is not for mails + + Please switch off those HTML encoded messages. You can mail all those funny + mails to your friends. We speak plain text mails. + + 2.6 Quoting + + Quote as little as possible. Just enough to provide the context you cannot + leave out. A lengthy description can be found here: + + https://www.netmeister.org/news/learn2quote.html + + 2.7 Digest + + We allow subscribers to subscribe to the "digest" version of the mailing + lists. A digest is a collection of mails lumped together in one single mail. + + Should you decide to reply to a mail sent out as a digest, there are two + things you MUST consider if you really really cannot subscribe normally + instead: + + Cut off all mails and chatter that is not related to the mail you want to + reply to. + + Change the subject name to something sensible and related to the subject, + preferably even the actual subject of the single mail you wanted to reply to + + 2.8 Please Tell Us How You Solved The Problem! + + Many people mail questions to the list, people spend some of their time and + make an effort in providing good answers to these questions. + + If you are the one who asks, please consider responding once more in case + one of the hints was what solved your problems. The guys who write answers + feel good to know that they provided a good answer and that you fixed the + problem. Far too often, the person who asked the question is never heard from + again, and we never get to know if he/she is gone because the problem was + solved or perhaps because the problem was unsolvable! + + Getting the solution posted also helps other users that experience the same + problem(s). They get to see (possibly in the web archives) that the + suggested fixes actually has helped at least one person. diff --git a/docs/MANUAL b/docs/MANUAL new file mode 100644 index 00000000..5df37e44 --- /dev/null +++ b/docs/MANUAL @@ -0,0 +1,1058 @@ +LATEST VERSION + + You always find news about what's going on as well as the latest versions + from the curl web pages, located at: + + https://curl.haxx.se + +SIMPLE USAGE + + Get the main page from Netscape's web-server: + + curl http://www.netscape.com/ + + Get the README file the user's home directory at funet's ftp-server: + + curl ftp://ftp.funet.fi/README + + Get a web page from a server using port 8000: + + curl http://www.weirdserver.com:8000/ + + Get a directory listing of an FTP site: + + curl ftp://cool.haxx.se/ + + Get the definition of curl from a dictionary: + + curl dict://dict.org/m:curl + + Fetch two documents at once: + + curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/ + + Get a file off an FTPS server: + + curl ftps://files.are.secure.com/secrets.txt + + or use the more appropriate FTPS way to get the same file: + + curl --ftp-ssl ftp://files.are.secure.com/secrets.txt + + Get a file from an SSH server using SFTP: + + curl -u username sftp://example.com/etc/issue + + Get a file from an SSH server using SCP using a private key + (not password-protected) to authenticate: + + curl -u username: --key ~/.ssh/id_rsa \ + scp://example.com/~/file.txt + + Get a file from an SSH server using SCP using a private key + (password-protected) to authenticate: + + curl -u username: --key ~/.ssh/id_rsa --pass private_key_password \ + scp://example.com/~/file.txt + + Get the main page from an IPv6 web server: + + curl "http://[2001:1890:1112:1::20]/" + + Get a file from an SMB server: + + curl -u "domain\username:passwd" smb://server.example.com/share/file.txt + +DOWNLOAD TO A FILE + + Get a web page and store in a local file with a specific name: + + curl -o thatpage.html http://www.netscape.com/ + + Get a web page and store in a local file, make the local file get the name + of the remote document (if no file name part is specified in the URL, this + will fail): + + curl -O http://www.netscape.com/index.html + + Fetch two files and store them with their remote names: + + curl -O www.haxx.se/index.html -O curl.haxx.se/download.html + +USING PASSWORDS + + FTP + + To ftp files using name+passwd, include them in the URL like: + + curl ftp://name:passwd@machine.domain:port/full/path/to/file + + or specify them with the -u flag like + + curl -u name:passwd ftp://machine.domain:port/full/path/to/file + + FTPS + + It is just like for FTP, but you may also want to specify and use + SSL-specific options for certificates etc. + + Note that using FTPS:// as prefix is the "implicit" way as described in the + standards while the recommended "explicit" way is done by using FTP:// and + the --ftp-ssl option. + + SFTP / SCP + + This is similar to FTP, but you can use the --key option to specify a + private key to use instead of a password. Note that the private key may + itself be protected by a password that is unrelated to the login password + of the remote system; this password is specified using the --pass option. + Typically, curl will automatically extract the public key from the private + key file, but in cases where curl does not have the proper library support, + a matching public key file must be specified using the --pubkey option. + + HTTP + + Curl also supports user and password in HTTP URLs, thus you can pick a file + like: + + curl http://name:passwd@machine.domain/full/path/to/file + + or specify user and password separately like in + + curl -u name:passwd http://machine.domain/full/path/to/file + + HTTP offers many different methods of authentication and curl supports + several: Basic, Digest, NTLM and Negotiate (SPNEGO). Without telling which + method to use, curl defaults to Basic. You can also ask curl to pick the + most secure ones out of the ones that the server accepts for the given URL, + by using --anyauth. + + NOTE! According to the URL specification, HTTP URLs can not contain a user + and password, so that style will not work when using curl via a proxy, even + though curl allows it at other times. When using a proxy, you _must_ use + the -u style for user and password. + + HTTPS + + Probably most commonly used with private certificates, as explained below. + +PROXY + + curl supports both HTTP and SOCKS proxy servers, with optional authentication. + It does not have special support for FTP proxy servers since there are no + standards for those, but it can still be made to work with many of them. You + can also use both HTTP and SOCKS proxies to transfer files to and from FTP + servers. + + Get an ftp file using an HTTP proxy named my-proxy that uses port 888: + + curl -x my-proxy:888 ftp://ftp.leachsite.com/README + + Get a file from an HTTP server that requires user and password, using the + same proxy as above: + + curl -u user:passwd -x my-proxy:888 http://www.get.this/ + + Some proxies require special authentication. Specify by using -U as above: + + curl -U user:passwd -x my-proxy:888 http://www.get.this/ + + A comma-separated list of hosts and domains which do not use the proxy can + be specified as: + + curl --noproxy localhost,get.this -x my-proxy:888 http://www.get.this/ + + If the proxy is specified with --proxy1.0 instead of --proxy or -x, then + curl will use HTTP/1.0 instead of HTTP/1.1 for any CONNECT attempts. + + curl also supports SOCKS4 and SOCKS5 proxies with --socks4 and --socks5. + + See also the environment variables Curl supports that offer further proxy + control. + + Most FTP proxy servers are set up to appear as a normal FTP server from the + client's perspective, with special commands to select the remote FTP server. + curl supports the -u, -Q and --ftp-account options that can be used to + set up transfers through many FTP proxies. For example, a file can be + uploaded to a remote FTP server using a Blue Coat FTP proxy with the + options: + + curl -u "Remote-FTP-Username@remote.ftp.server Proxy-Username:Remote-Pass" \ + --ftp-account Proxy-Password --upload-file local-file \ + ftp://my-ftp.proxy.server:21/remote/upload/path/ + + See the manual for your FTP proxy to determine the form it expects to set up + transfers, and curl's -v option to see exactly what curl is sending. + +RANGES + + HTTP 1.1 introduced byte-ranges. Using this, a client can request + to get only one or more subparts of a specified document. Curl supports + this with the -r flag. + + Get the first 100 bytes of a document: + + curl -r 0-99 http://www.get.this/ + + Get the last 500 bytes of a document: + + curl -r -500 http://www.get.this/ + + Curl also supports simple ranges for FTP files as well. Then you can only + specify start and stop position. + + Get the first 100 bytes of a document using FTP: + + curl -r 0-99 ftp://www.get.this/README + +UPLOADING + + FTP / FTPS / SFTP / SCP + + Upload all data on stdin to a specified server: + + curl -T - ftp://ftp.upload.com/myfile + + Upload data from a specified file, login with user and password: + + curl -T uploadfile -u user:passwd ftp://ftp.upload.com/myfile + + Upload a local file to the remote site, and use the local file name at the remote + site too: + + curl -T uploadfile -u user:passwd ftp://ftp.upload.com/ + + Upload a local file to get appended to the remote file: + + curl -T localfile -a ftp://ftp.upload.com/remotefile + + Curl also supports ftp upload through a proxy, but only if the proxy is + configured to allow that kind of tunneling. If it does, you can run curl in + a fashion similar to: + + curl --proxytunnel -x proxy:port -T localfile ftp.upload.com + +SMB / SMBS + + curl -T file.txt -u "domain\username:passwd" + smb://server.example.com/share/ + + HTTP + + Upload all data on stdin to a specified HTTP site: + + curl -T - http://www.upload.com/myfile + + Note that the HTTP server must have been configured to accept PUT before + this can be done successfully. + + For other ways to do HTTP data upload, see the POST section below. + +VERBOSE / DEBUG + + If curl fails where it isn't supposed to, if the servers don't let you in, + if you can't understand the responses: use the -v flag to get verbose + fetching. Curl will output lots of info and what it sends and receives in + order to let the user see all client-server interaction (but it won't show + you the actual data). + + curl -v ftp://ftp.upload.com/ + + To get even more details and information on what curl does, try using the + --trace or --trace-ascii options with a given file name to log to, like + this: + + curl --trace trace.txt www.haxx.se + + +DETAILED INFORMATION + + Different protocols provide different ways of getting detailed information + about specific files/documents. To get curl to show detailed information + about a single file, you should use -I/--head option. It displays all + available info on a single file for HTTP and FTP. The HTTP information is a + lot more extensive. + + For HTTP, you can get the header information (the same as -I would show) + shown before the data by using -i/--include. Curl understands the + -D/--dump-header option when getting files from both FTP and HTTP, and it + will then store the headers in the specified file. + + Store the HTTP headers in a separate file (headers.txt in the example): + + curl --dump-header headers.txt curl.haxx.se + + Note that headers stored in a separate file can be very useful at a later + time if you want curl to use cookies sent by the server. More about that in + the cookies section. + +POST (HTTP) + + It's easy to post data using curl. This is done using the -d + option. The post data must be urlencoded. + + Post a simple "name" and "phone" guestbook. + + curl -d "name=Rafael%20Sagula&phone=3320780" \ + http://www.where.com/guest.cgi + + How to post a form with curl, lesson #1: + + Dig out all the tags in the form that you want to fill in. + + If there's a "normal" post, you use -d to post. -d takes a full "post + string", which is in the format + + =&=&... + + The 'variable' names are the names set with "name=" in the tags, and + the data is the contents you want to fill in for the inputs. The data *must* + be properly URL encoded. That means you replace space with + and that you + replace weird letters with %XX where XX is the hexadecimal representation of + the letter's ASCII code. + + Example: + + (page located at http://www.formpost.com/getthis/ + +
+ + + + +
+ + We want to enter user 'foobar' with password '12345'. + + To post to this, you enter a curl command line like: + + curl -d "user=foobar&pass=12345&id=blablabla&ding=submit" (continues) + http://www.formpost.com/getthis/post.cgi + + + While -d uses the application/x-www-form-urlencoded mime-type, generally + understood by CGI's and similar, curl also supports the more capable + multipart/form-data type. This latter type supports things like file upload. + + -F accepts parameters like -F "name=contents". If you want the contents to + be read from a file, use <@filename> as contents. When specifying a file, + you can also specify the file content type by appending ';type=' + to the file name. You can also post the contents of several files in one + field. For example, the field name 'coolfiles' is used to send three files, + with different content types using the following syntax: + + curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \ + http://www.post.com/postit.cgi + + If the content-type is not specified, curl will try to guess from the file + extension (it only knows a few), or use the previously specified type (from + an earlier file if several files are specified in a list) or else it will + use the default type 'application/octet-stream'. + + Emulate a fill-in form with -F. Let's say you fill in three fields in a + form. One field is a file name which to post, one field is your name and one + field is a file description. We want to post the file we have written named + "cooltext.txt". To let curl do the posting of this data instead of your + favourite browser, you have to read the HTML source of the form page and + find the names of the input fields. In our example, the input field names + are 'file', 'yourname' and 'filedescription'. + + curl -F "file=@cooltext.txt" -F "yourname=Daniel" \ + -F "filedescription=Cool text file with cool text inside" \ + http://www.post.com/postit.cgi + + To send two files in one post you can do it in two ways: + + 1. Send multiple files in a single "field" with a single field name: + + curl -F "pictures=@dog.gif,cat.gif" + + 2. Send two fields with two field names: + + curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif" + + To send a field value literally without interpreting a leading '@' + or '<', or an embedded ';type=', use --form-string instead of + -F. This is recommended when the value is obtained from a user or + some other unpredictable source. Under these circumstances, using + -F instead of --form-string would allow a user to trick curl into + uploading a file. + +REFERRER + + An HTTP request has the option to include information about which address + referred it to the actual page. Curl allows you to specify the + referrer to be used on the command line. It is especially useful to + fool or trick stupid servers or CGI scripts that rely on that information + being available or contain certain data. + + curl -e www.coolsite.com http://www.showme.com/ + + NOTE: The Referer: [sic] field is defined in the HTTP spec to be a full URL. + +USER AGENT + + An HTTP request has the option to include information about the browser + that generated the request. Curl allows it to be specified on the command + line. It is especially useful to fool or trick stupid servers or CGI + scripts that only accept certain browsers. + + Example: + + curl -A 'Mozilla/3.0 (Win95; I)' http://www.nationsbank.com/ + + Other common strings: + 'Mozilla/3.0 (Win95; I)' Netscape Version 3 for Windows 95 + 'Mozilla/3.04 (Win95; U)' Netscape Version 3 for Windows 95 + 'Mozilla/2.02 (OS/2; U)' Netscape Version 2 for OS/2 + 'Mozilla/4.04 [en] (X11; U; AIX 4.2; Nav)' NS for AIX + 'Mozilla/4.05 [en] (X11; U; Linux 2.0.32 i586)' NS for Linux + + Note that Internet Explorer tries hard to be compatible in every way: + 'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)' MSIE for W95 + + Mozilla is not the only possible User-Agent name: + 'Konqueror/1.0' KDE File Manager desktop client + 'Lynx/2.7.1 libwww-FM/2.14' Lynx command line browser + +COOKIES + + Cookies are generally used by web servers to keep state information at the + client's side. The server sets cookies by sending a response line in the + headers that looks like 'Set-Cookie: ' where the data part then + typically contains a set of NAME=VALUE pairs (separated by semicolons ';' + like "NAME1=VALUE1; NAME2=VALUE2;"). The server can also specify for what + path the "cookie" should be used for (by specifying "path=value"), when the + cookie should expire ("expire=DATE"), for what domain to use it + ("domain=NAME") and if it should be used on secure connections only + ("secure"). + + If you've received a page from a server that contains a header like: + Set-Cookie: sessionid=boo123; path="/foo"; + + it means the server wants that first pair passed on when we get anything in + a path beginning with "/foo". + + Example, get a page that wants my name passed in a cookie: + + curl -b "name=Daniel" www.sillypage.com + + Curl also has the ability to use previously received cookies in following + sessions. If you get cookies from a server and store them in a file in a + manner similar to: + + curl --dump-header headers www.example.com + + ... you can then in a second connect to that (or another) site, use the + cookies from the 'headers' file like: + + curl -b headers www.example.com + + While saving headers to a file is a working way to store cookies, it is + however error-prone and not the preferred way to do this. Instead, make curl + save the incoming cookies using the well-known netscape cookie format like + this: + + curl -c cookies.txt www.example.com + + Note that by specifying -b you enable the "cookie awareness" and with -L + you can make curl follow a location: (which often is used in combination + with cookies). So that if a site sends cookies and a location, you can + use a non-existing file to trigger the cookie awareness like: + + curl -L -b empty.txt www.example.com + + The file to read cookies from must be formatted using plain HTTP headers OR + as netscape's cookie file. Curl will determine what kind it is based on the + file contents. In the above command, curl will parse the header and store + the cookies received from www.example.com. curl will send to the server the + stored cookies which match the request as it follows the location. The + file "empty.txt" may be a nonexistent file. + + To read and write cookies from a netscape cookie file, you can set both -b + and -c to use the same file: + + curl -b cookies.txt -c cookies.txt www.example.com + +PROGRESS METER + + The progress meter exists to show a user that something actually is + happening. The different fields in the output have the following meaning: + + % Total % Received % Xferd Average Speed Time Curr. + Dload Upload Total Current Left Speed + 0 151M 0 38608 0 0 9406 0 4:41:43 0:00:04 4:41:39 9287 + + From left-to-right: + % - percentage completed of the whole transfer + Total - total size of the whole expected transfer + % - percentage completed of the download + Received - currently downloaded amount of bytes + % - percentage completed of the upload + Xferd - currently uploaded amount of bytes + Average Speed + Dload - the average transfer speed of the download + Average Speed + Upload - the average transfer speed of the upload + Time Total - expected time to complete the operation + Time Current - time passed since the invoke + Time Left - expected time left to completion + Curr.Speed - the average transfer speed the last 5 seconds (the first + 5 seconds of a transfer is based on less time of course.) + + The -# option will display a totally different progress bar that doesn't + need much explanation! + +SPEED LIMIT + + Curl allows the user to set the transfer speed conditions that must be met + to let the transfer keep going. By using the switch -y and -Y you + can make curl abort transfers if the transfer speed is below the specified + lowest limit for a specified time. + + To have curl abort the download if the speed is slower than 3000 bytes per + second for 1 minute, run: + + curl -Y 3000 -y 60 www.far-away-site.com + + This can very well be used in combination with the overall time limit, so + that the above operation must be completed in whole within 30 minutes: + + curl -m 1800 -Y 3000 -y 60 www.far-away-site.com + + Forcing curl not to transfer data faster than a given rate is also possible, + which might be useful if you're using a limited bandwidth connection and you + don't want your transfer to use all of it (sometimes referred to as + "bandwidth throttle"). + + Make curl transfer data no faster than 10 kilobytes per second: + + curl --limit-rate 10K www.far-away-site.com + + or + + curl --limit-rate 10240 www.far-away-site.com + + Or prevent curl from uploading data faster than 1 megabyte per second: + + curl -T upload --limit-rate 1M ftp://uploadshereplease.com + + When using the --limit-rate option, the transfer rate is regulated on a + per-second basis, which will cause the total transfer speed to become lower + than the given number. Sometimes of course substantially lower, if your + transfer stalls during periods. + +CONFIG FILE + + Curl automatically tries to read the .curlrc file (or _curlrc file on win32 + systems) from the user's home dir on startup. + + The config file could be made up with normal command line switches, but you + can also specify the long options without the dashes to make it more + readable. You can separate the options and the parameter with spaces, or + with = or :. Comments can be used within the file. If the first letter on a + line is a '#'-symbol the rest of the line is treated as a comment. + + If you want the parameter to contain spaces, you must enclose the entire + parameter within double quotes ("). Within those quotes, you specify a + quote as \". + + NOTE: You must specify options and their arguments on the same line. + + Example, set default time out and proxy in a config file: + + # We want a 30 minute timeout: + -m 1800 + # ... and we use a proxy for all accesses: + proxy = proxy.our.domain.com:8080 + + White spaces ARE significant at the end of lines, but all white spaces + leading up to the first characters of each line are ignored. + + Prevent curl from reading the default file by using -q as the first command + line parameter, like: + + curl -q www.thatsite.com + + Force curl to get and display a local help page in case it is invoked + without URL by making a config file similar to: + + # default url to get + url = "http://help.with.curl.com/curlhelp.html" + + You can specify another config file to be read by using the -K/--config + flag. If you set config file name to "-" it'll read the config from stdin, + which can be handy if you want to hide options from being visible in process + tables etc: + + echo "user = user:passwd" | curl -K - http://that.secret.site.com + +EXTRA HEADERS + + When using curl in your own very special programs, you may end up needing + to pass on your own custom headers when getting a web page. You can do + this by using the -H flag. + + Example, send the header "X-you-and-me: yes" to the server when getting a + page: + + curl -H "X-you-and-me: yes" www.love.com + + This can also be useful in case you want curl to send a different text in a + header than it normally does. The -H header you specify then replaces the + header curl would normally send. If you replace an internal header with an + empty one, you prevent that header from being sent. To prevent the Host: + header from being used: + + curl -H "Host:" www.server.com + +FTP and PATH NAMES + + Do note that when getting files with the ftp:// URL, the given path is + relative the directory you enter. To get the file 'README' from your home + directory at your ftp site, do: + + curl ftp://user:passwd@my.site.com/README + + But if you want the README file from the root directory of that very same + site, you need to specify the absolute file name: + + curl ftp://user:passwd@my.site.com//README + + (I.e with an extra slash in front of the file name.) + +SFTP and SCP and PATH NAMES + + With sftp: and scp: URLs, the path name given is the absolute name on the + server. To access a file relative to the remote user's home directory, + prefix the file with /~/ , such as: + + curl -u $USER sftp://home.example.com/~/.bashrc + +FTP and firewalls + + The FTP protocol requires one of the involved parties to open a second + connection as soon as data is about to get transferred. There are two ways to + do this. + + The default way for curl is to issue the PASV command which causes the + server to open another port and await another connection performed by the + client. This is good if the client is behind a firewall that doesn't allow + incoming connections. + + curl ftp.download.com + + If the server, for example, is behind a firewall that doesn't allow connections + on ports other than 21 (or if it just doesn't support the PASV command), the + other way to do it is to use the PORT command and instruct the server to + connect to the client on the given IP number and port (as parameters to the + PORT command). + + The -P flag to curl supports a few different options. Your machine may have + several IP-addresses and/or network interfaces and curl allows you to select + which of them to use. Default address can also be used: + + curl -P - ftp.download.com + + Download with PORT but use the IP address of our 'le0' interface (this does + not work on windows): + + curl -P le0 ftp.download.com + + Download with PORT but use 192.168.0.10 as our IP address to use: + + curl -P 192.168.0.10 ftp.download.com + +NETWORK INTERFACE + + Get a web page from a server using a specified port for the interface: + + curl --interface eth0:1 http://www.netscape.com/ + + or + + curl --interface 192.168.1.10 http://www.netscape.com/ + +HTTPS + + Secure HTTP requires SSL libraries to be installed and used when curl is + built. If that is done, curl is capable of retrieving and posting documents + using the HTTPS protocol. + + Example: + + curl https://www.secure-site.com + + Curl is also capable of using your personal certificates to get/post files + from sites that require valid certificates. The only drawback is that the + certificate needs to be in PEM-format. PEM is a standard and open format to + store certificates with, but it is not used by the most commonly used + browsers (Netscape and MSIE both use the so called PKCS#12 format). If you + want curl to use the certificates you use with your (favourite) browser, you + may need to download/compile a converter that can convert your browser's + formatted certificates to PEM formatted ones. This kind of converter is + included in recent versions of OpenSSL, and for older versions Dr Stephen + N. Henson has written a patch for SSLeay that adds this functionality. You + can get his patch (that requires an SSLeay installation) from his site at: + http://www.drh-consultancy.demon.co.uk/ + + Example on how to automatically retrieve a document using a certificate with + a personal password: + + curl -E /path/to/cert.pem:password https://secure.site.com/ + + If you neglect to specify the password on the command line, you will be + prompted for the correct password before any data can be received. + + Many older SSL-servers have problems with SSLv3 or TLS, which newer versions + of OpenSSL etc use, therefore it is sometimes useful to specify what + SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL + version to use (for SSLv3, SSLv2 or TLSv1 respectively): + + curl -2 https://secure.site.com/ + + Otherwise, curl will first attempt to use v3 and then v2. + + To use OpenSSL to convert your favourite browser's certificate into a PEM + formatted one that curl can use, do something like this: + + In Netscape, you start with hitting the 'Security' menu button. + + Select 'certificates->yours' and then pick a certificate in the list + + Press the 'Export' button + + enter your PIN code for the certs + + select a proper place to save it + + Run the 'openssl' application to convert the certificate. If you cd to the + openssl installation, you can do it like: + + # ./apps/openssl pkcs12 -in [file you saved] -clcerts -out [PEMfile] + + In Firefox, select Options, then Advanced, then the Encryption tab, + View Certificates. This opens the Certificate Manager, where you can + Export. Be sure to select PEM for the Save as type. + + In Internet Explorer, select Internet Options, then the Content tab, then + Certificates. Then you can Export, and depending on the format you may + need to convert to PEM. + + In Chrome, select Settings, then Show Advanced Settings. Under HTTPS/SSL + select Manage Certificates. + +RESUMING FILE TRANSFERS + + To continue a file transfer where it was previously aborted, curl supports + resume on HTTP(S) downloads as well as FTP uploads and downloads. + + Continue downloading a document: + + curl -C - -o file ftp://ftp.server.com/path/file + + Continue uploading a document(*1): + + curl -C - -T file ftp://ftp.server.com/path/file + + Continue downloading a document from a web server(*2): + + curl -C - -o file http://www.server.com/ + + (*1) = This requires that the FTP server supports the non-standard command + SIZE. If it doesn't, curl will say so. + + (*2) = This requires that the web server supports at least HTTP/1.1. If it + doesn't, curl will say so. + +TIME CONDITIONS + + HTTP allows a client to specify a time condition for the document it + requests. It is If-Modified-Since or If-Unmodified-Since. Curl allows you to + specify them with the -z/--time-cond flag. + + For example, you can easily make a download that only gets performed if the + remote file is newer than a local copy. It would be made like: + + curl -z local.html http://remote.server.com/remote.html + + Or you can download a file only if the local file is newer than the remote + one. Do this by prepending the date string with a '-', as in: + + curl -z -local.html http://remote.server.com/remote.html + + You can specify a "free text" date as condition. Tell curl to only download + the file if it was updated since January 12, 2012: + + curl -z "Jan 12 2012" http://remote.server.com/remote.html + + Curl will then accept a wide range of date formats. You always make the date + check the other way around by prepending it with a dash '-'. + +DICT + + For fun try + + curl dict://dict.org/m:curl + curl dict://dict.org/d:heisenbug:jargon + curl dict://dict.org/d:daniel:web1913 + + Aliases for 'm' are 'match' and 'find', and aliases for 'd' are 'define' + and 'lookup'. For example, + + curl dict://dict.org/find:curl + + Commands that break the URL description of the RFC (but not the DICT + protocol) are + + curl dict://dict.org/show:db + curl dict://dict.org/show:strat + + Authentication is still missing (but this is not required by the RFC) + +LDAP + + If you have installed the OpenLDAP library, curl can take advantage of it + and offer ldap:// support. + On Windows, curl will use WinLDAP from Platform SDK by default. + + Default protocol version used by curl is LDAPv3. LDAPv2 will be used as + fallback mechanism in case if LDAPv3 will fail to connect. + + LDAP is a complex thing and writing an LDAP query is not an easy task. I do + advise you to dig up the syntax description for that elsewhere. One such + place might be: + + RFC 2255, "The LDAP URL Format" https://curl.haxx.se/rfc/rfc2255.txt + + To show you an example, this is how I can get all people from my local LDAP + server that has a certain sub-domain in their email address: + + curl -B "ldap://ldap.frontec.se/o=frontec??sub?mail=*sth.frontec.se" + + If I want the same info in HTML format, I can get it by not using the -B + (enforce ASCII) flag. + + You also can use authentication when accessing LDAP catalog: + + curl -u user:passwd "ldap://ldap.frontec.se/o=frontec??sub?mail=*" + curl "ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*" + + By default, if user and password provided, OpenLDAP/WinLDAP will use basic + authentication. On Windows you can control this behavior by providing + one of --basic, --ntlm or --digest option in curl command line + + curl --ntlm "ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*" + + On Windows, if no user/password specified, auto-negotiation mechanism will + be used with current logon credentials (SSPI/SPNEGO). + +ENVIRONMENT VARIABLES + + Curl reads and understands the following environment variables: + + http_proxy, HTTPS_PROXY, FTP_PROXY + + They should be set for protocol-specific proxies. General proxy should be + set with + + ALL_PROXY + + A comma-separated list of host names that shouldn't go through any proxy is + set in (only an asterisk, '*' matches all hosts) + + NO_PROXY + + If the host name matches one of these strings, or the host is within the + domain of one of these strings, transactions with that node will not be + proxied. When a domain is used, it needs to start with a period. A user can + specify that both www.example.com and foo.example.com should not uses a + proxy by setting NO_PROXY to ".example.com". By including the full name you + can exclude specific host names, so to make www.example.com not use a proxy + but still have foo.example.com do it, set NO_PROXY to "www.example.com" + + The usage of the -x/--proxy flag overrides the environment variables. + +NETRC + + Unix introduced the .netrc concept a long time ago. It is a way for a user + to specify name and password for commonly visited FTP sites in a file so + that you don't have to type them in each time you visit those sites. You + realize this is a big security risk if someone else gets hold of your + passwords, so therefore most unix programs won't read this file unless it is + only readable by yourself (curl doesn't care though). + + Curl supports .netrc files if told to (using the -n/--netrc and + --netrc-optional options). This is not restricted to just FTP, + so curl can use it for all protocols where authentication is used. + + A very simple .netrc file could look something like: + + machine curl.haxx.se login iamdaniel password mysecret + +CUSTOM OUTPUT + + To better allow script programmers to get to know about the progress of + curl, the -w/--write-out option was introduced. Using this, you can specify + what information from the previous transfer you want to extract. + + To display the amount of bytes downloaded together with some text and an + ending newline: + + curl -w 'We downloaded %{size_download} bytes\n' www.download.com + +KERBEROS FTP TRANSFER + + Curl supports kerberos4 and kerberos5/GSSAPI for FTP transfers. You need + the kerberos package installed and used at curl build time for it to be + available. + + First, get the krb-ticket the normal way, like with the kinit/kauth tool. + Then use curl in way similar to: + + curl --krb private ftp://krb4site.com -u username:fakepwd + + There's no use for a password on the -u switch, but a blank one will make + curl ask for one and you already entered the real password to kinit/kauth. + +TELNET + + The curl telnet support is basic and very easy to use. Curl passes all data + passed to it on stdin to the remote server. Connect to a remote telnet + server using a command line similar to: + + curl telnet://remote.server.com + + And enter the data to pass to the server on stdin. The result will be sent + to stdout or to the file you specify with -o. + + You might want the -N/--no-buffer option to switch off the buffered output + for slow connections or similar. + + Pass options to the telnet protocol negotiation, by using the -t option. To + tell the server we use a vt100 terminal, try something like: + + curl -tTTYPE=vt100 telnet://remote.server.com + + Other interesting options for it -t include: + + - XDISPLOC= Sets the X display location. + + - NEW_ENV= Sets an environment variable. + + NOTE: The telnet protocol does not specify any way to login with a specified + user and password so curl can't do that automatically. To do that, you need + to track when the login prompt is received and send the username and + password accordingly. + +PERSISTENT CONNECTIONS + + Specifying multiple files on a single command line will make curl transfer + all of them, one after the other in the specified order. + + libcurl will attempt to use persistent connections for the transfers so that + the second transfer to the same host can use the same connection that was + already initiated and was left open in the previous transfer. This greatly + decreases connection time for all but the first transfer and it makes a far + better use of the network. + + Note that curl cannot use persistent connections for transfers that are used + in subsequence curl invokes. Try to stuff as many URLs as possible on the + same command line if they are using the same host, as that'll make the + transfers faster. If you use an HTTP proxy for file transfers, practically + all transfers will be persistent. + +MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE + + As is mentioned above, you can download multiple files with one command line + by simply adding more URLs. If you want those to get saved to a local file + instead of just printed to stdout, you need to add one save option for each + URL you specify. Note that this also goes for the -O option (but not + --remote-name-all). + + For example: get two files and use -O for the first and a custom file + name for the second: + + curl -O http://url.com/file.txt ftp://ftp.com/moo.exe -o moo.jpg + + You can also upload multiple files in a similar fashion: + + curl -T local1 ftp://ftp.com/moo.exe -T local2 ftp://ftp.com/moo2.txt + +IPv6 + + curl will connect to a server with IPv6 when a host lookup returns an IPv6 + address and fall back to IPv4 if the connection fails. The --ipv4 and --ipv6 + options can specify which address to use when both are available. IPv6 + addresses can also be specified directly in URLs using the syntax: + + http://[2001:1890:1112:1::20]/overview.html + + When this style is used, the -g option must be given to stop curl from + interpreting the square brackets as special globbing characters. Link local + and site local addresses including a scope identifier, such as fe80::1234%1, + may also be used, but the scope portion must be numeric or match an existing + network interface on Linux and the percent character must be URL escaped. The + previous example in an SFTP URL might look like: + + sftp://[fe80::1234%251]/ + + IPv6 addresses provided other than in URLs (e.g. to the --proxy, --interface + or --ftp-port options) should not be URL encoded. + +METALINK + + Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way + to list multiple URIs and hashes for a file. Curl will make use of the mirrors + listed within for failover if there are errors (such as the file or server not + being available). It will also verify the hash of the file after the download + completes. The Metalink file itself is downloaded and processed in memory and + not stored in the local file system. + + Example to use a remote Metalink file: + + curl --metalink http://www.example.com/example.metalink + + To use a Metalink file in the local file system, use FILE protocol (file://): + + curl --metalink file://example.metalink + + Please note that if FILE protocol is disabled, there is no way to use a local + Metalink file at the time of this writing. Also note that if --metalink and + --include are used together, --include will be ignored. This is because including + headers in the response will break Metalink parser and if the headers are included + in the file described in Metalink file, hash check will fail. + +MAILING LISTS + + For your convenience, we have several open mailing lists to discuss curl, + its development and things relevant to this. Get all info at + https://curl.haxx.se/mail/. Some of the lists available are: + + curl-users + + Users of the command line tool. How to use it, what doesn't work, new + features, related tools, questions, news, installations, compilations, + running, porting etc. + + curl-library + + Developers using or developing libcurl. Bugs, extensions, improvements. + + curl-announce + + Low-traffic. Only receives announcements of new public versions. At worst, + that makes something like one or two mails per month, but usually only one + mail every second month. + + curl-and-php + + Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP + with a curl angle. + + curl-and-python + + Python hackers using curl with or without the python binding pycurl. + + Please direct curl questions, feature requests and trouble reports to one of + these mailing lists instead of mailing any individual. diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..3c029678 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,119 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +AUTOMAKE_OPTIONS = foreign no-dependencies + +# EXTRA_DIST breaks with $(abs_builddir) so build it using this variable +# but distribute it (using the relative file name) in the next variable +man_MANS = $(abs_builddir)/curl.1 +noinst_man_MANS = curl.1 mk-ca-bundle.1 +dist_man_MANS = curl-config.1 +GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html +PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf +MANDISTPAGES = curl.1.dist curl-config.1.dist + +HTMLPAGES = $(GENHTMLPAGES) index.html + +# Build targets in this file (.) before cmdline-opts to ensure that +# the curl.1 rule below runs first +SUBDIRS = . cmdline-opts +DIST_SUBDIRS = $(SUBDIRS) examples libcurl + +CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES) $(MANDISTPAGES) curl.1 + +EXTRA_DIST = \ + $(noinst_man_MANS) \ + BINDINGS.md \ + BUGS \ + CHECKSRC.md \ + CIPHERS.md \ + CMakeLists.txt \ + CODE_OF_CONDUCT.md \ + CODE_STYLE.md \ + CONTRIBUTE.md \ + DEPRECATE.md \ + FAQ \ + FEATURES \ + GOVERNANCE.md \ + HELP-US.md \ + HISTORY.md \ + HTTP-COOKIES.md \ + HTTP2.md \ + INSTALL \ + INSTALL.cmake \ + INSTALL.md \ + INTERNALS.md \ + KNOWN_BUGS \ + LICENSE-MIXING.md \ + MAIL-ETIQUETTE \ + MANUAL \ + README.cmake \ + README.md \ + README.netware \ + README.win32 \ + RELEASE-PROCEDURE.md \ + RESOURCES \ + ROADMAP.md \ + SECURITY-PROCESS.md \ + SSL-PROBLEMS.md \ + SSLCERTS.md \ + THANKS \ + TODO \ + TheArtOfHttpScripting \ + VERSIONS + +MAN2HTML= roffit $< >$@ + +SUFFIXES = .1 .html .pdf + +# $(abs_builddir) is to disable VPATH when searching for this file, which +# would otherwise find the copy in $(srcdir) which breaks the $(HUGE) +# rule in src/Makefile.am in out-of-tree builds that references the file in the +# build directory. +# +# First, seed the used copy of curl.1 with the prebuilt copy (in an out-of-tree +# build), then run make recursively to rebuild it only if its dependencies +# have changed. +$(abs_builddir)/curl.1: + if test "$(top_builddir)x" != "$(top_srcdir)x" -a -e "$(srcdir)/curl.1"; then \ + cp -fp "$(srcdir)/curl.1" $@; fi + cd cmdline-opts && $(MAKE) + +html: $(HTMLPAGES) + cd libcurl && $(MAKE) html + +pdf: $(PDFPAGES) + cd libcurl && $(MAKE) pdf + +.1.html: + $(MAN2HTML) + +.1.pdf: + @(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \ + groff -Tps -man $< >$$foo.ps; \ + ps2pdf $$foo.ps $@; \ + rm $$foo.ps; \ + echo "converted $< to $@") + +distclean: + rm -f $(CLEANFILES) + diff --git a/docs/README.cmake b/docs/README.cmake new file mode 100644 index 00000000..084c1de6 --- /dev/null +++ b/docs/README.cmake @@ -0,0 +1,16 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +README.cmake + Read the README file first. + + Curl contains CMake build files that provide a way to build Curl with the + CMake build tool (www.cmake.org). CMake is a cross platform meta build tool + that generates native makefiles and IDE project files. The CMake build + system can be used to build Curl on any of its supported platforms. + + Read the INSTALL.cmake file for instructions on how to compile curl with + CMake. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..56691fc4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,12 @@ +![curl logo](https://cdn.rawgit.com/curl/curl-www/master/logo/curl-logo.svg) + +# Documentation + +You'll find a mix of various documentation in this directory and +subdirectories, using several different formats. Some of them are not ideal +for reading directly in your browser. + +If you'd rather see the rendered version of the documentation, check out the +curl web site's [documentation section](https://curl.haxx.se/docs/) for +general curl stuff or the [libcurl section](https://curl.haxx.se/libcurl/) for +libcurl related documentation. diff --git a/docs/README.netware b/docs/README.netware new file mode 100644 index 00000000..9028963f --- /dev/null +++ b/docs/README.netware @@ -0,0 +1,26 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +README.netware + + Read the README file first. + + Curl has been successfully compiled with gcc / nlmconv on different flavours + of Linux as well as with the official Metrowerks CodeWarrior compiler. + While not being the main development target, a continuously growing share of + curl users are NetWare-based, especially also consuming the lib from PHP. + + The unix-style man pages are tricky to read on windows, so therefore all + those pages are also provided as web pages on the curl web site. + + The main curl.1 man page is also "built-in" in the command line tool. Use a + command line similar to this in order to extract a separate text file: + + curl -M >manual.txt + + Read the INSTALL file for instructions on how to compile curl self. + + diff --git a/docs/README.win32 b/docs/README.win32 new file mode 100644 index 00000000..00ca197f --- /dev/null +++ b/docs/README.win32 @@ -0,0 +1,25 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +README.win32 + + Read the README file first. + + Curl has been compiled, built and run on all sorts of Windows and win32 + systems. While not being the main develop target, a fair share of curl users + are win32-based. + + The unix-style man pages are tricky to read on windows, so therefore all + those pages are also provided as web pages on the curl web site. + + The main curl.1 man page is also "built-in" in the command line tool. Use a + command line similar to this in order to extract a separate text file: + + curl -M >manual.txt + + Read the INSTALL file for instructions on how to compile curl self. + + diff --git a/docs/RELEASE-PROCEDURE.md b/docs/RELEASE-PROCEDURE.md new file mode 100644 index 00000000..637d0a70 --- /dev/null +++ b/docs/RELEASE-PROCEDURE.md @@ -0,0 +1,96 @@ +curl release procedure - how to do a release +============================================ + +in the source code repo +----------------------- + +- edit `RELEASE-NOTES` to be accurate + +- update `docs/THANKS` + +- make sure all relevant changes are committed on the master branch + +- tag the git repo in this style: `git tag -a curl-7_34_0`. -a annotates the + tag and we use underscores instead of dots in the version number. Make sure + the tag is GPG signed (using -s). + +- run "./maketgz 7.34.0" to build the release tarballs. It is important that + you run this on a machine with the correct set of autotools etc installed + as this is what then will be shipped and used by most users on *nix like + systems. + +- push the git commits and the new tag + +- gpg sign the 4 tarballs as maketgz suggests + +- upload the 8 resulting files to the primary download directory + +in the curl-www repo +-------------------- + +- edit `Makefile` (version number and date), + +- edit `_newslog.html` (announce the new release) and + +- edit `_changes.html` (insert changes+bugfixes from RELEASE-NOTES) + +- commit all local changes + +- tag the repo with the same name as used for the source repo. + +- make sure all relevant changes are committed and pushed on the master branch + + (the web site then updates its contents automatically) + +on github +--------- + +- edit the newly made release tag so that it is listed as the latest release + +inform +------ + +- send an email to curl-users, curl-announce and curl-library. Insert the + RELEASE-NOTES into the mail. + +celebrate +--------- + +- suitable beverage intake is encouraged for the festivities + +curl release scheduling +======================= + +Basics +------ + +We do releases every 8 weeks on Wednesdays. If critical problems arise, we can +insert releases outside of the schedule or we can move the release date - but +this is very rare. + +Each 8 week release cycle is split in two 4-week periods. + +- During the first 4 weeks after a release, we allow new features and changes + to curl and libcurl. If we accept any such changes, we bump the minor number + used for the next release. + +- During the second 4-week period we do not merge any features or changes, we + then only focus on fixing bugs and polishing things to make a solid coming + release. + +Coming dates +------------ + +Based on the description above, here are some planned release dates (at the +time of this writing): + +- July 11, 2018 +- September 5, 2018 +- October 31, 2018 +- December 26, 2018 +- February 20, 2019 +- April 17, 2019 +- June 12, 2019 +- August 7, 2019 +- October 2, 2019 +- December 27, 2019 diff --git a/docs/RESOURCES b/docs/RESOURCES new file mode 100644 index 00000000..55f75df7 --- /dev/null +++ b/docs/RESOURCES @@ -0,0 +1,85 @@ + _ _ ____ _ + Project ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + +This document lists documents and standards used by curl. + + RFC 959 - FTP Protocol + + RFC 1635 - How to Use Anonymous FTP + + RFC 1738 - Uniform Resource Locators + + RFC 1777 - Lightweight Directory Access Protocol (LDAP) + + RFC 1808 - Relative Uniform Resource Locators + + RFC 1867 - Form-based File Upload in HTML + + RFC 1950 - ZLIB Compressed Data Format Specification + + RFC 1951 - DEFLATE Compressed Data Format Specification + + RFC 1952 - GZIP File Format Specification + + RFC 1959 - LDAP URL Syntax + + RFC 2045-2049 - Everything you need to know about MIME! (needed for form + based upload) + + RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616) + + RFC 2104 - Keyed-Hashing for Message Authentication + + RFC 2109 - HTTP State Management Mechanism (cookie stuff) + - Also, read Netscape's specification at + https://curl.haxx.se/rfc/cookie_spec.html + + RFC 2183 - The Content-Disposition Header Field + + RFC 2195 - CRAM-MD5 Authentication + + RFC 2229 - A Dictionary Server Protocol + + RFC 2255 - Newer LDAP URL Format + + RFC 2231 - MIME Parameter Value and Encoded Word Extensions: + Character Sets, Languages, and Continuations + + RFC 2388 - "Returning Values from Forms: multipart/form-data" + Use this as an addition to the RFC1867 + + RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This + one obsoletes RFC 1738, but since RFC 1738 is often mentioned + I've left it in this list. + + RFC 2428 - FTP Extensions for IPv6 and NATs + + RFC 2577 - FTP Security Considerations + + RFC 2616 - HTTP 1.1, the latest + + RFC 2617 - HTTP Authentication + + RFC 2718 - Guidelines for new URL Schemes + + RFC 2732 - Format for Literal IPv6 Addresses in URL's + + RFC 2818 - HTTP Over TLS (TLS is the successor to SSL) + + RFC 2821 - Simple Mail Transfer Protocol (SMTP) + + RFC 2964 - Use of HTTP State Management + + RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109 + + RFC 3207 - SMTP Over TLS + + RFC 4616 - PLAIN Authentication + + RFC 4954 - SMTP Authentication + + RFC 7932 - Brotli Compressed Data Format diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 00000000..64989b1b --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,42 @@ +curl the next few years - perhaps +================================= + +Roadmap of things Daniel Stenberg wants to work on next. It is intended to +serve as a guideline for others for information, feedback and possible +participation. + +QUIC +---- + + See the [QUIC wiki page](https://github.com/curl/curl/wiki/QUIC). + +HTTP cookies +------------ + +Two cookie drafts have been adopted by the httpwg in IETF and we should +support them as the popular browsers will as well: + +[Deprecate modification of 'secure' cookies from non-secure +origins](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-00) + +[Cookie Prefixes](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00) + +[Firefox bug report about secure cookies](https://bugzilla.mozilla.org/show_bug.cgi?id=976073) + +SRV records +----------- + +How to find services for specific domains/hosts. + +Improve +------- + +1. curl -h output (considered overwhelming to users). + +2. We have > 200 command line options, is there a way to redo things to + simplify or improve the situation as we are likely to keep adding + features/options in the future too. + +3. Perform some of the clean up from the TODO document, removing old + definitions and such like that are currently earmarked to be removed years + ago. diff --git a/docs/SECURITY-PROCESS.md b/docs/SECURITY-PROCESS.md new file mode 100644 index 00000000..4991d5fb --- /dev/null +++ b/docs/SECURITY-PROCESS.md @@ -0,0 +1,139 @@ +curl security process +===================== + +This document describes how security vulnerabilities should be handled in the +curl project. + +Publishing Information +---------------------- + +All known and public curl or libcurl related vulnerabilities are listed on +[the curl web site security page](https://curl.haxx.se/docs/security.html). + +Security vulnerabilities should not be entered in the project's public bug +tracker unless the necessary configuration is in place to limit access to the +issue to only the reporter and the project's security team. + +Vulnerability Handling +---------------------- + +The typical process for handling a new security vulnerability is as follows. + +No information should be made public about a vulnerability until it is +formally announced at the end of this process. That means, for example that a +bug tracker entry must NOT be created to track the issue since that will make +the issue public and it should not be discussed on any of the project's public +mailing lists. Also messages associated with any commits should not make +any reference to the security nature of the commit if done prior to the public +announcement. + +- The person discovering the issue, the reporter, reports the vulnerability + privately to `curl-security@haxx.se`. That's an email alias that reaches a + handful of selected and trusted people. + +- Messages that do not relate to the reporting or managing of an undisclosed + security vulnerability in curl or libcurl are ignored and no further action + is required. + +- A person in the security team sends an e-mail to the original reporter to + acknowledge the report. + +- The security team investigates the report and either rejects it or accepts + it. + +- If the report is rejected, the team writes to the reporter to explain why. + +- If the report is accepted, the team writes to the reporter to let him/her + know it is accepted and that they are working on a fix. + +- The security team discusses the problem, works out a fix, considers the + impact of the problem and suggests a release schedule. This discussion + should involve the reporter as much as possible. + +- The release of the information should be "as soon as possible" and is most + often synced with an upcoming release that contains the fix. If the + reporter, or anyone else, thinks the next planned release is too far away + then a separate earlier release for security reasons should be considered. + +- Write a security advisory draft about the problem that explains what the + problem is, its impact, which versions it affects, solutions or workarounds, + when the release is out and make sure to credit all contributors properly. + Figure out the CWE (Common Weakness Enumeration) number for the flaw. + +- Request a CVE number from + [distros@openwall](http://oss-security.openwall.org/wiki/mailing-lists/distros) + when also informing and preparing them for the upcoming public security + vulnerability announcement - attach the advisory draft for information. Note + that 'distros' won't accept an embargo longer than 14 days and they do not + care for Windows-specific flaws. For windows-specific flaws, request CVE + directly from MITRE. + +- Update the "security advisory" with the CVE number. + +- The security team commits the fix in a private branch. The commit message + should ideally contain the CVE number. This fix is usually also distributed + to the 'distros' mailing list to allow them to use the fix prior to the + public announcement. + +- No more than 48 hours before the release, the private branch is merged into + the master branch and pushed. Once pushed, the information is accessible to + the public and the actual release should follow suit immediately afterwards. + The time between the push and the release is used for final tests and + reviews. + +- The project team creates a release that includes the fix. + +- The project team announces the release and the vulnerability to the world in + the same manner we always announce releases. It gets sent to the + curl-announce, curl-library and curl-users mailing lists. + +- The security web page on the web site should get the new vulnerability + mentioned. + +Pre-notification +---------------- + +If you think you are or should be eligible for a pre-notification about +upcoming security announcements for curl, we urge OS distros and similar +vendors to primarily join the distros@openwall list as that is one of the +purposes of that list - and not just for curl of course. + +If you are not a distro or otherwise not suitable for distros@openwall and yet +want pre-notifications from us, contact the curl security team with a detailed +and clear explanation why this is the case. + +curl-security (at haxx dot se) +------------------------------ + +Who is on this list? There are a couple of criteria you must meet, and then we +might ask you to join the list or you can ask to join it. It really isn't very +formal. We basically only require that you have a long-term presence in the +curl project and you have shown an understanding for the project and its way +of working. You must've been around for a good while and you should have no +plans in vanishing in the near future. + +We do not make the list of participants public mostly because it tends to vary +somewhat over time and a list somewhere will only risk getting outdated. + +Publishing Security Advisories +------------------------------ + +1. Write up the security advisory, using markdown syntax. Use the same + subtitles as last time to maintain consistency. + +2. Name the advisory file (and ultimately the URL to be used when the flaw + gets published), using a randomized component so that third parties that + are involved in the process for each individual flaw will not be given + insights about possible *other* flaws worked on in parallel. + `adv_YEAR_RANDOM.md` has been used before. + +3. Add a line on the top of the array in `curl-www/docs/vuln.pm'. + +4. Put the new advisory markdown file in the curl-www/docs/ directory. Add it + to the git repo. Update the Makefile in the same directory to build the + HTML representation. + +5. Run `make` in your local web checkout and verify that things look fine. + +6. On security advisory release day, push the changes on the curl-www + repository's remote master branch. diff --git a/docs/SSL-PROBLEMS.md b/docs/SSL-PROBLEMS.md new file mode 100644 index 00000000..91803e22 --- /dev/null +++ b/docs/SSL-PROBLEMS.md @@ -0,0 +1,87 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +# SSL problems + + First, let's establish that we often refer to TLS and SSL interchangeably as + SSL here. The current protocol is called TLS, it was called SSL a long time + ago. + + There are several known reasons why a connection that involves SSL might + fail. This is a document that attempts to details the most common ones and + how to mitigate them. + +## CA certs + + CA certs are used to digitally verify the server's certificate. You need a + "ca bundle" for this. See lots of more details on this in the SSLCERTS + document. + +## CA bundle missing intermediate certificates + + When using said CA bundle to verify a server cert, you will experience + problems if your CA cert does not have the certificates for the + intermediates in the whole trust chain. + +## Protocol version + + Some broken servers fail to support the protocol negotiation properly that + SSL servers are supposed to handle. This may cause the connection to fail + completely. Sometimes you may need to explicitly select a SSL version to use + when connecting to make the connection succeed. + + An additional complication can be that modern SSL libraries sometimes are + built with support for older SSL and TLS versions disabled! + + All versions of SSL are considered insecure and should be avoided. Use TLS. + +## Ciphers + + Clients give servers a list of ciphers to select from. If the list doesn't + include any ciphers the server wants/can use, the connection handshake + fails. + + curl has recently disabled the user of a whole bunch of seriously insecure + ciphers from its default set (slightly depending on SSL backend in use). + + You may have to explicitly provide an alternative list of ciphers for curl + to use to allow the server to use a WEAK cipher for you. + + Note that these weak ciphers are identified as flawed. For example, this + includes symmetric ciphers with less than 128 bit keys and RC4. + + WinSSL in Windows XP is not able to connect to servers that no longer + support the legacy handshakes and algorithms used by those versions, so we + advice against building curl to use WinSSL on really old Windows versions. + + References: + + https://tools.ietf.org/html/draft-popov-tls-prohibiting-rc4-01 + +## Allow BEAST + + BEAST is the name of a TLS 1.0 attack that surfaced 2011. When adding means + to mitigate this attack, it turned out that some broken servers out there in + the wild didn't work properly with the BEAST mitigation in place. + + To make such broken servers work, the --ssl-allow-beast option was + introduced. Exactly as it sounds, it re-introduces the BEAST vulnerability + but on the other hand it allows curl to connect to that kind of strange + servers. + +## Disabling certificate revocation checks + + Some SSL backends may do certificate revocation checks (CRL, OCSP, etc) + depending on the OS or build configuration. The --ssl-no-revoke option was + introduced in 7.44.0 to disable revocation checking but currently is only + supported for WinSSL (the native Windows SSL library), with an exception in + the case of Windows' Untrusted Publishers blacklist which it seems can't be + bypassed. This option may have broader support to accommodate other SSL + backends in the future. + + References: + + https://curl.haxx.se/docs/ssl-compared.html diff --git a/docs/SSLCERTS.md b/docs/SSLCERTS.md new file mode 100644 index 00000000..3fcd345b --- /dev/null +++ b/docs/SSLCERTS.md @@ -0,0 +1,173 @@ +SSL Certificate Verification +============================ + +SSL is TLS +---------- + +SSL is the old name. It is called TLS these days. + + +Native SSL +---------- + +If libcurl was built with Schannel or Secure Transport support (the native SSL +libraries included in Windows and Mac OS X), then this does not apply to +you. Scroll down for details on how the OS-native engines handle SSL +certificates. If you're not sure, then run "curl -V" and read the results. If +the version string says "WinSSL" in it, then it was built with Schannel +support. + +It is about trust +----------------- + +This system is about trust. In your local CA certificate store you have certs +from *trusted* Certificate Authorities that you then can use to verify that the +server certificates you see are valid. They're signed by one of the CAs you +trust. + +Which CAs do you trust? You can decide to trust the same set of companies your +operating system trusts, or the set one of the known browsers trust. That's +basically trust via someone else you trust. You should just be aware that +modern operating systems and browsers are setup to trust *hundreds* of +companies and recent years several such CAs have been found untrustworthy. + +Certificate Verification +------------------------ + +libcurl performs peer SSL certificate verification by default. This is done +by using a CA certificate store that the SSL library can use to make sure the +peer's server certificate is valid. + +If you communicate with HTTPS, FTPS or other TLS-using servers using +certificates that are signed by CAs present in the store, you can be sure +that the remote server really is the one it claims to be. + +If the remote server uses a self-signed certificate, if you don't install a CA +cert store, if the server uses a certificate signed by a CA that isn't +included in the store you use or if the remote host is an impostor +impersonating your favorite site, and you want to transfer files from this +server, do one of the following: + + 1. Tell libcurl to *not* verify the peer. With libcurl you disable this with + `curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);` + + With the curl command line tool, you disable this with -k/--insecure. + + 2. Get a CA certificate that can verify the remote server and use the proper + option to point out this CA cert for verification when connecting. For + libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAPATH, capath);` + + With the curl command line tool: --cacert [file] + + 3. Add the CA cert for your server to the existing default CA certificate + store. The default CA certificate store can changed at compile time with the + following configure options: + + --with-ca-bundle=FILE: use the specified file as CA certificate store. CA + certificates need to be concatenated in PEM format into this file. + + --with-ca-path=PATH: use the specified path as CA certificate store. CA + certificates need to be stored as individual PEM files in this directory. + You may need to run c_rehash after adding files there. + + If neither of the two options is specified, configure will try to auto-detect + a setting. It's also possible to explicitly not hardcode any default store + but rely on the built in default the crypto library may provide instead. + You can achieve that by passing both --without-ca-bundle and + --without-ca-path to the configure script. + + If you use Internet Explorer, this is one way to get extract the CA cert + for a particular server: + + - View the certificate by double-clicking the padlock + - Find out where the CA certificate is kept (Certificate> + Authority Information Access>URL) + - Get a copy of the crt file using curl + - Convert it from crt to PEM using the openssl tool: + openssl x509 -inform DES -in yourdownloaded.crt \ + -out outcert.pem -text + - Add the 'outcert.pem' to the CA certificate store or use it stand-alone + as described below. + + If you use the 'openssl' tool, this is one way to get extract the CA cert + for a particular server: + + - `openssl s_client -connect xxxxx.com:443 |tee logfile` + - type "QUIT", followed by the "ENTER" key + - The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE" + markers. + - If you want to see the data in the certificate, you can do: "openssl + x509 -inform PEM -in certfile -text -out certdata" where certfile is + the cert you extracted from logfile. Look in certdata. + - If you want to trust the certificate, you can add it to your CA + certificate store or use it stand-alone as described. Just remember that + the security is no better than the way you obtained the certificate. + + 4. If you're using the curl command line tool, you can specify your own CA + cert path by setting the environment variable `CURL_CA_BUNDLE` to the path + of your choice. + + If you're using the curl command line tool on Windows, curl will search + for a CA cert file named "curl-ca-bundle.crt" in these directories and in + this order: + 1. application's directory + 2. current working directory + 3. Windows System directory (e.g. C:\windows\system32) + 4. Windows Directory (e.g. C:\windows) + 5. all directories along %PATH% + + 5. Get a better/different/newer CA cert bundle! One option is to extract the + one a recent Firefox browser uses by running 'make ca-bundle' in the curl + build tree root, or possibly download a version that was generated this + way for you: [CA Extract](https://curl.haxx.se/docs/caextract.html) + +Neglecting to use one of the above methods when dealing with a server using a +certificate that isn't signed by one of the certificates in the installed CA +certificate store, will cause SSL to report an error ("certificate verify +failed") during the handshake and SSL will then refuse further communication +with that server. + +Certificate Verification with NSS +--------------------------------- + +If libcurl was built with NSS support, then depending on the OS distribution, +it is probably required to take some additional steps to use the system-wide +CA cert db. RedHat ships with an additional module, libnsspem.so, which +enables NSS to read the OpenSSL PEM CA bundle. On openSUSE you can install +p11-kit-nss-trust which makes NSS use the system wide CA certificate store. NSS +also has a new [database format](https://wiki.mozilla.org/NSS_Shared_DB). + +Starting with version 7.19.7, libcurl automatically adds the 'sql:' prefix to +the certdb directory (either the hardcoded default /etc/pki/nssdb or the +directory configured with SSL_DIR environment variable). To check which certdb +format your distribution provides, examine the default certdb location: +/etc/pki/nssdb; the new certdb format can be identified by the filenames +cert9.db, key4.db, pkcs11.txt; filenames of older versions are cert8.db, +key3.db, secmod.db. + +Certificate Verification with Schannel and Secure Transport +----------------------------------------------------------- + +If libcurl was built with Schannel (Microsoft's native TLS engine) or Secure +Transport (Apple's native TLS engine) support, then libcurl will still perform +peer certificate verification, but instead of using a CA cert bundle, it will +use the certificates that are built into the OS. These are the same +certificates that appear in the Internet Options control panel (under Windows) +or Keychain Access application (under OS X). Any custom security rules for +certificates will be honored. + +Schannel will run CRL checks on certificates unless peer verification is +disabled. Secure Transport on iOS will run OCSP checks on certificates unless +peer verification is disabled. Secure Transport on OS X will run either OCSP +or CRL checks on certificates if those features are enabled, and this behavior +can be adjusted in the preferences of Keychain Access. + +HTTPS proxy +----------- + +Since version 7.52.0, curl can do HTTPS to the proxy separately from the +connection to the server. This TLS connection is handled separately from the +server connection so instead of `--insecure` and `--cacert` to control the +certificate verification, you use `--proxy-insecure` and `--proxy-cacert`. +With these options, you make sure that the TLS connection and the trust of the +proxy can be kept totally separate from the TLS connection to the server. diff --git a/docs/THANKS b/docs/THANKS new file mode 100644 index 00000000..661fae08 --- /dev/null +++ b/docs/THANKS @@ -0,0 +1,1772 @@ + This project has been alive for many years. Countless people have provided + feedback that have improved curl. Here follows a list of people that have + contributed (a-z order). + + If you have contributed but are missing here, please let us know! + +"Captain Basil" +"Spoon Man" +Aaro Koskinen +Aaron Oneal +Aaron Orenstein +Abram Pousada +Adam Brown +Adam D. Moss +Adam Langley +Adam Light +Adam Marcionek +Adam Piggott +Adam Sampson +Adam Tkac +Adrian Peniak +Adrian Schuur +Adriano Meirelles +Ajit Dhumale +Akhil Kedia +Aki Koskinen +Akos Pasztory +Akshay Vernekar +Alain Danteny +Alan Jenkins +Alan Pinstein +Albert Chin-A-Young +Albert Choy +Ale Vesely +Alejandro Alvarez Ayllon +Alejandro R. Sedeño +Aleksandar Milivojevic +Aleksey Tulinov +Ales Mlakar +Ales Novak +Alessandro Ghedini +Alessandro Vesely +Alex Baines +Alex Bligh +Alex Chan +Alex Fishman +Alex Gruz +Alex Malinovich +Alex McLellan +Alex Neblett +Alex Nichols +Alex Potapenko +Alex Rousskov +Alex Suykov +Alex Vinnik +Alex aka WindEagle +Alexander Beedie +Alexander Dyagilev +Alexander Elgert +Alexander Klauer +Alexander Kourakos +Alexander Krasnostavsky +Alexander Lazic +Alexander Pepper +Alexander Peslyak +Alexander Sinditskiy +Alexander Traud +Alexander Zhuravlev +Alexey Borzov +Alexey Melnichuk +Alexey Pesternikov +Alexey Simak +Alexey Zakhlestin +Alexis Carvalho +Alexis La Goutte +Alfonso Martone +Alfred Gebert +Allen Pulsifer +Alona Rossen +Amol Pattekar +Amr Shahin +Anatol Belski +Anatoli Tubman +Anders Bakken +Anders Gustafsson +Anders Havn +Anders Roxell +Andi Jahja +Andre Guibert de Bruet +Andre Heinecke +Andreas Damm +Andreas Faerber +Andreas Farber +Andreas Malzahn +Andreas Ntaflos +Andreas Olsson +Andreas Rieke +Andreas Roth +Andreas Schneider +Andreas Schuldei +Andreas Streichardt +Andreas Wurf +Andrei Benea +Andrei Cipu +Andrei Karas +Andrei Kurushin +Andrei Sedoi +Andrej E Baranov +Andrew Benham +Andrew Biggs +Andrew Bushnell +Andrew Francis +Andrew Fuller +Andrew Krieger +Andrew Kurushin +Andrew Lambert +Andrew Moise +Andrew Robbins +Andrew Wansink +Andrew de los Reyes +Andrey Labunets +Andrii Moiseiev +Andrés García +Andy Cedilnik +Andy Serpa +Andy Tsouladze +Angus Mackay +Anthon Pang +Anthony Avina +Anthony Bryan +Anthony G. Basile +Antoine Aubert +Antoine Calando +Anton Bychkov +Anton Kalmykov +Anton Malov +Anton Yabchinskiy +Antonio Larrosa +Antony74 on github +Antti Hätälä +Archangel_SDY on github +Arkadiusz Miskiewicz +Armel Asselin +Arnaud Compan +Arnaud Ebalard +Aron Bergman +Artak Galoyan +Arthur Murray +Arve Knudsen +Arvid Norberg +Ashish Shukla +Ask Bjørn Hansen +Askar Safin +Ates Goral +Augustus Saunders +Avery Fay +Axel Tillequin +Balaji Parasuram +Balaji Salunke +Balint Szilakszi +Barry Abrahamson +Bart Whiteley +Bas Mevissen +Bas van Schaik +Basuke Suzuki +Ben Boeckel +Ben Darnell +Ben Greear +Ben Madsen +Ben Noordhuis +Ben Van Hof +Ben Winslow +Benbuck Nason +Benjamin Gerard +Benjamin Gilbert +Benjamin Johnson +Benjamin Kircher +Benjamin Sergeant +Benoit Neil +Benoit Sigoure +Bernard Leak +Bernard Spil +Bernhard M. Wiedemann +Bernhard Reutner-Fischer +Bernhard Walle +Bert Huijben +Bertrand Demiddelaer +Bertrand Simonnet +Bill Doyle +Bill Egert +Bill Hoffman +Bill Middlecamp +Bill Nagel +Bill Pyne +Bjoern Sikora +Bjorn Augustsson +Bjorn Reese +Björn Stenberg +Blaise Potard +Bob Relyea +Bob Richmond +Bob Schader +Bogdan Nicula +Brad Burdick +Brad Fitzpatrick +Brad Harder +Brad Hards +Brad King +Brad Spencer +Bradford Bruce +Brandon Casey +Brandon Wang +Brendan Jurd +Brent Beardsley +Brian Akins +Brian Carpenter +Brian Childs +Brian Chrisman +Brian Dessent +Brian J. Murrell +Brian Prodoehl +Brian R Duffy +Brian Ulm +Brock Noland +Bru Rom +Bruce Mitchener +Bruce Stephens +Bruno Grasselli +Bruno Thomsen +Bruno de Carvalho +Bryan Henderson +Bryan Kemp +Byrial Jensen +Cameron Kaiser +Cameron MacMinn +Camille Moncelier +Caolan McNamara +Carlo Cannas +Carlo Teubner +Carlo Wood +Carsten Lange +Casey O'Donnell +Catalin Patulea +Chad Monroe +Chandrakant Bagul +Charles Kerr +Charles Romestant +Chen Prog +Chester Liu +Chih-Chung Chang +Chris "Bob Bob" +Chris Araman +Chris Carlmar +Chris Combes +Chris Conlon +Chris Deidun +Chris Faherty +Chris Flerackers +Chris Gaukroger +Chris Maltby +Chris Mumford +Chris Smowton +Chris Young +Christian Fillion +Christian Grothoff +Christian Heimes +Christian Hägele +Christian Krause +Christian Kurz +Christian Robottom Reis +Christian Schmitz +Christian Stewart +Christian Vogt +Christian Weisgerber +Christophe Demory +Christophe Legry +Christopher Conroy +Christopher Palow +Christopher R. Palmer +Christopher Stone +Chungtsun Li +Ciprian Badescu +Claes Jakobsson +Clarence Gardner +Clemens Gruber +Clifford Wolf +Clint Clayton +Cody Jones +Cody Mack +Colby Ranger +Colin Blair +Colin Hogben +Colin Watson +Colm Buckley +Constantine Sapuntzakis +Cory Benfield +Cory Nelson +Craig A West +Craig Davison +Craig Markwardt +Craig de Stigter +Cris Bailiff +Cristian Rodríguez +Curt Bogmine +Cyril B +Cyrill Osterwalder +Cédric Connes +Cédric Deltheil +D. Flinkmann +Da-Yoon Chung +Dag Ekengren +Dagobert Michelsen +Dair Grant +Dambaev Alexander +Damian Dixon +Damien Adant +Damien Vielpeau +Dan Becker +Dan C +Dan Cristian +Dan Donahue +Dan Fandrich +Dan Jacobson +Dan Johnson +Dan Locks +Dan McNulty +Dan Nelson +Dan Petitt +Dan Torop +Dan Zitter +Daniel Bankhead +Daniel Black +Daniel Cater +Daniel Egger +Daniel Gustafsson +Daniel Hwang +Daniel Johnson +Daniel Kahn Gillmor +Daniel Krügler +Daniel Lee Hwang +Daniel Melani +Daniel Mentz +Daniel Romero +Daniel Schauenberg +Daniel Seither +Daniel Shahaf +Daniel Steinberg +Daniel Stenberg +Daniel Theron +Daniel at touchtunes +Daphne Luong +Dario Nieuwenhuis +Dario Weisser +Darryl House +Darshan Mody +Darío Hereñú +Dave Dribin +Dave Halbakken +Dave Hamilton +Dave May +Dave Reisner +Dave Thompson +Dave Vasilevsky +Davey Shafik +David Bau +David Benjamin +David Binderman +David Blaikie +David Byron +David Cohen +David E. Narváez +David Eriksson +David Garske +David Houlder +David Hull +David J Meyer +David James +David Kalnischkies +David Kierznowski +David Kimdon +David L. +David Lang +David LeBlanc +David Lord +David McCreedy +David Meyer +David Odin +David Phillips +David Rosenstrauch +David Ryskalczyk +David Schweikert +David Shaw +David Strauss +David Tarendash +David Thiel +David Walser +David Woodhouse +David Wright +David Yan +Dengminwen +Denis Feklushkin +Denis Ollier +Dennis Clarke +Derek Higgins +Desmond O. Chang +Detlef Schmier +Didier Brisebourg +Diego Bes +Diego Casorran +Dilyan Palauzov +Dima Barsky +Dima Tisnek +Dimitar Boevski +Dimitre Dimitrov +Dimitrios Apostolou +Dimitrios Siganos +Dimitris Sarris +Dinar +Dirk Eddelbuettel +Dirk Feytons +Dirk Manske +Dmitri Shubin +Dmitri Tikhonov +Dmitriy Sergeyev +Dmitry Bartsevich +Dmitry Eremin-Solenikov +Dmitry Falko +Dmitry Kostjuchenko +Dmitry Kurochkin +Dmitry Mikhirev +Dmitry Popov +Dmitry Rechkin +Dmitry S. Baikov +Dolbneff A.V +Domenico Andreoli +Dominick Meglio +Dominik Hölzl +Dominique Leuenberger +Don J Olmstead +Dongliang Mu +Doug Kaufman +Doug Porter +Douglas Creager +Douglas E. Wegscheid +Douglas Kilpatrick +Douglas Mencken +Douglas R. Horner +Douglas Steinwand +Dov Murik +Drake Arconis +Duane Cathey +Duncan Mac-Vicar Prett +Dustin Boswell +Dusty Mabe +Duy Phan Thanh +Dwarakanath Yadavalli +Dylan Ellicott +Dylan Salisbury +Dániel Bakai +Early Ehlinger +Earnestly on github +Ebenezer Ikonne +Ed Morley +Edin Kadribasic +Eduard Bloch +Edward Kimmel +Edward Rudd +Edward Sheldrake +Edward Thomson +Eelco Dolstra +Eetu Ojanen +Egon Eckert +Eldar Zaitov +Elliot Saba +Ellis Pritchard +Elmira A Semenova +Emanuele Bovisio +Emil Lerner +Emil Romanus +Emiliano Ida +Emmanuel Tychon +Enrico Scholz +Enrik Berkhan +Eramoto Masaya +Eric Cooper +Eric Gallager +Eric Hu +Eric Landes +Eric Lavigne +Eric Lubin +Eric Melville +Eric Mertens +Eric Rautman +Eric Rescorla +Eric Ridge +Eric S. Raymond +Eric Thelin +Eric Vergnaud +Eric Wong +Eric Young +Erick Nuwendam +Erik Janssen +Erik Johansson +Ernest Beinrohr +Ernst Sjöstrand +Erwan Legrand +Erwin Authried +Ethan Glasser Camp +Eugene Kotlyarov +Evan Jordan +Even Rouault +Evert Pot +Evgeny Grin +Evgeny Turnaev +Eygene Ryabinkin +Fabian Frank +Fabian Hiernaux +Fabian Keil +Fabian Ruff +Fabrice Fontaine +Fabrizio Ammollo +Fahim Chandurwala +Fedor Karpelevitch +Feist Josselin +Felix Kaiser +Felix Yan +Felix von Leitner +Feng Tu +Fernando Muñoz +Flavio Medeiros +Florian Schoppmann +Florian Weimer +Florin Petriuc +Forrest Cahoon +Francisco Moraes +Francisco Sedano +Francois Petitjean +Frank Denis +Frank Gevaerts +Frank Hempel +Frank Keeney +Frank McGeough +Frank Meier +Frank Ticheler +Frank Van Uffelen +František Kučera +François Charlier +Fred Machado +Fred New +Fred Noz +Fred Stluka +Frederic Lepied +Frederik B +Fredrik Thulin +Gabriel Kuri +Gabriel Sjoberg +Garrett Holmstrom +Gary Maxwell +Gaurav Malhotra +Gautam Kachroo +Gautam Mani +Gavrie Philipson +Gaz Iqbal +Gaël Portay +Geeknik Labs +Geoff Beier +Georg Horn +Georg Huettenegger +Georg Lippitsch +Georg Wicherski +Gerd v. Egidy +Gergely Nagy +Gerhard Herre +Gerrit Bruchhäuser +Ghennadi Procopciuc +Giancarlo Formicuccia +Giaslas Georgios +Gil Weber +Gilad +Gilbert Ramirez Jr. +Gilles Blanc +Gisle Vanem +Giuseppe Attardi +Giuseppe D'Ambrosio +Giuseppe Persico +Glen A Johnson Jr. +Glen Nakamura +Glen Scott +Glenn Sheridan +Google Inc. +Gordon Marler +Gorilla Maguila +Gou Lingfeng +Grant Erickson +Grant Pannell +Greg Hewgill +Greg Morse +Greg Onufer +Greg Pratt +Greg Rowe +Greg Zavertnik +Gregory Szorc +Grigory Entin +Guenole Bescon +Guenter Knauf +Guido Berhoerster +Guillaume Arluison +Gunter Knauf +Gustaf Hui +Gustavo Grieco +GwanYeong Kim +Gwenole Beauchesne +Gökhan Şengün +Götz Babin-Ebell +Hamish Mackenzie +Han Qiao +Hang Kin Lau +Hang Su +Hannes Magnusson +Hanno Böck +Hanno Kranzhoff +Hans Steegers +Hans-Jurgen May +Hardeep Singh +Haris Okanovic +Harold Stuart +Harshal Pradhan +Hauke Duden +He Qin +Heikki Korpela +Heinrich Ko +Heinrich Schaefer +Helmut K. C. Tessarek +Helwing Lutz +Hendrik Visage +Henrik Gaßmann +Henrik Storner +Henry Ludemann +Henry Roeland +Herve Amblard +Hidemoto Nakada +Ho-chi Chen +Hoi-Ho Chan +Hongli Lai +Howard Chu +Hubert Kario +Hzhijun +Ian D Allen +Ian Fette +Ian Ford +Ian Gulliver +Ian Lynagh +Ian Turner +Ian Wilkes +Ignacio Vazquez-Abrams +Igor Franchuk +Igor Novoseltsev +Igor Polyakov +Iida Yosiaki +Ilguiz Latypov +Ilja van Sprundel +Immanuel Gregoire +Inca R +Ingmar Runge +Ingo Ralf Blum +Ingo Wilken +Irfan Adilovic +Isaac Boukris +Ishan SinghLevett +Ithubg on github +Ivan Avdeev +Ivo Bellin Salarin +Jack Zhang +Jackarain on github +Jacky Lam +Jacob Meuser +Jacob Moshenko +Jactry Zeng +Jad Chamcham +Jaime Fullaondo +Jakub Wilk +Jakub Zakrzewski +James Atwill +James Bursa +James Cheng +James Clancy +James Cone +James Dury +James Gallagher +James Griffiths +James Housley +James MacMillan +James Slaughter +Jamie Lokier +Jamie Newton +Jamie Wilkinson +Jan Alexander Steffens +Jan Ehrhardt +Jan Koen Annot +Jan Kunder +Jan Schaumann +Jan Schmidt +Jan Van Boghout +Jared Jennings +Jared Lundell +Jari Aalto +Jari Sundell +Jason Glasgow +Jason Juang +Jason Liu +Jason McDonald +Jason S. Priebe +Javier Barroso +Javier Blazquez +Javier G. Sogo +Javier Sixto +Jay Austin +Jayesh A Shah +Jaz Fresh +Jean Gressmann +Jean Jacques Drouin +Jean-Claude Chauve +Jean-Francois Bertrand +Jean-Francois Durand +Jean-Louis Lemaire +Jean-Marc Ranger +Jean-Noël Rouvignac +Jean-Philippe Barrette-LaPierre +Jeff Connelly +Jeff Hodges +Jeff Johnson +Jeff King +Jeff Lawson +Jeff Phillips +Jeff Pohlmeyer +Jeff Weber +Jeffrey Walton +Jens Rantil +Jeremy Friesner +Jeremy Huddleston +Jeremy Lin +Jeremy Pearson +Jeremy Tan +Jeroen Koekkoek +Jeroen Ooms +Jerome Muffat-Meridol +Jerome Robert +Jerome Vouillon +Jerry Krinock +Jerry Wu +Jes Badwal +Jesper Jensen +Jesse Chisholm +Jesse Noller +Jesse Tan +Jie He +Jim Drash +Jim Freeman +Jim Hollinger +Jim Meyering +Jiri Dvorak +Jiri Hruska +Jiri Jaburek +Jiří Malák +Jocelyn Jaubert +Joe Halpin +Joe Malicki +Joe Mason +Joel Chen +Joel Depooter +Jofell Gallardo +Johan Anderson +Johan Lantz +Johan Nilsson +Johan van Selst +Johannes Bauer +Johannes Ernst +Johannes Schindelin +John Bradshaw +John Coffey +John Crow +John David Anglin +John DeHelian +John Dennis +John Dunn +John E. Malmberg +John Gardiner Myers +John Hascall +John Janssen +John Joseph Bachir +John Kelly +John Kohl +John Lask +John Levon +John Lightsey +John Marino +John Marshall +John McGowan +John P. McCaskey +John Starks +John Suprock +John Wanghui +John Wilkinson +John-Mark Bell +Johnny Luong +Jon DeVree +Jon Grubbs +Jon Nelson +Jon Sargeant +Jon Seymour +Jon Spencer +Jon Torrey +Jon Travis +Jon Turner +Jonas Forsman +Jonas Minnberg +Jonas Schnelli +Jonatan Lander +Jonatan Vela +Jonathan Cardoso Machado +Jonathan Cardoso Machado Machado +Jonathan Hseu +Jonathan Nieder +Jongki Suwandi +Joonas Kuorilehto +Jose Alf +Jose Kahan +Josef Wolf +Josh Kapell +Joshua Kwan +Josue Andrade Gomes +Jozef Kralik +Juan Barreto +Juan F. Codagnone +Juan Ignacio Hervás +Juan RP +Judson Bishop +Juergen Wilke +Jukka Pihl +Julian Noble +Julian Ospald +Julian Taylor +Julien Chaffraix +Julien Nabet +Julien Royer +Jun-ichiro itojun Hagino +Jurij Smakov +Juro Bystricky +Justin Clift +Justin Ehlert +Justin Fletcher +Justin Karneges +Justin Maggard +János Fekete +Jörg Mueller-Tolk +Jörn Hartroth +K. R. Walker +Kai Engert +Kai Noda +Kai Sommerfeld +Kai-Uwe Rommel +Kalle Vahlman +Kamil Dudka +Kang Lin +Kang-Jin Lee +Karl Moerder +Karol Pietrzak +Kartik Mahajan +Kaspar Brand +Katie Wang +Kazuho Oku +Kees Cook +Kees Dekker +Keith MacDonald +Keith McGuigan +Keith Mok +Ken Hirsch +Ken Rastatter +Kenny To +Kent Boortz +Keshav Krity +Kevin Baughman +Kevin Fisk +Kevin Ji +Kevin Lussier +Kevin R. Bulgrien +Kevin Reed +Kevin Roth +Kevin Smith +Kim Minjoong +Kim Rinnewitz +Kim Vandry +Kimmo Kinnunen +Kjell Ericson +Kjetil Jacobsen +Klaus Stein +Klevtsov Vadim +Kobi Gurkan +Konstantin Isakov +Kris Kennaway +Krishnendu Majumdar +Krister Johansen +Kristian Gunstone +Kristian Köhntopp +Kristiyan Tsaklev +Kurt Fankhauser +Kyle J. McKay +Kyle L. Huff +Kyle Sallee +Kyselgov E.N +Lachlan O'Dea +Larry Campbell +Larry Fahnoe +Larry Lin +Larry Stefani +Larry Stone +Lars Buitinck +Lars Gustafsson +Lars J. Aas +Lars Johannesen +Lars Nilsson +Lars Torben Wilson +Lau Hang Kin +Laurent Rabret +Lauri Kasanen +Laurie Clark-Michalek +Lawrence Matthews +Lawrence Wagerfield +Legoff Vincent +Lehel Bernadt +Leif W +Leith Bade +Len Krause +Lenaic Lefever +Lenny Rachitsky +Leon Winter +Leonardo Rosati +Liam Healy +Lijo Antony +Linas Vepstas +Lindley French +Ling Thio +Linus Lewandowski +Linus Nielsen Feltzing +Linus Nordberg +Lior Kaplan +Lisa Xu +Liviu Chircu +Liza Alenchery +Lloyd Fournier +Lluís Batlle i Rossell +Loic Dachary +Loren Kirkby +Luan Cestari +Luca Altea +Luca Boccassi +Lucas Adamski +Lucas Pardue +Ludek Finstrle +Ludovico Cavedon +Ludwig Nussel +Lukas Ruzicka +Lukasz Czekierda +Luke Amery +Luke Call +Luke Dashjr +Luo Jinghua +Luong Dinh Dung +Luz Paz +Luật Nguyễn +Lyman Epp +Lyndon Hill +Maciej Karpiuk +Maciej Puzio +Maciej W. Rozycki +Mahmoud Samir Fayed +Maks Naumov +Maksim Kuzevanov +Maksim Stsepanenka +Mamoru Tasaka +Mamta Upadhyay +Mandy Wu +Manfred Schwarb +Manuel Massing +Marc Aldorasi +Marc Boucher +Marc Deslauriers +Marc Doughty +Marc Hesse +Marc Hörsken +Marc Kleine-Budde +Marc Renault +Marc-Antoine Perennou +Marcel Raad +Marcel Roelofs +Marcelo Echeverria +Marcelo Juchem +Marcin Adamski +Marcin Gryszkalis +Marcin Konicki +Marco Deckel +Marco G. Salvagno +Marco Maggi +Marcus Hoffmann +Marcus Sundberg +Marcus Webster +Marian Klymov +Mario Schroeder +Mark Brand +Mark Butler +Mark Davies +Mark Eichin +Mark Hamilton +Mark Incley +Mark Karpeles +Mark Lentczner +Mark Nottingham +Mark Salisbury +Mark Snelling +Mark Tully +Markus Duft +Markus Elfring +Markus Koetter +Markus Moeller +Markus Oberhumer +Markus Westerlind +Marquis de Muesli +Martijn Koster +Martin C. Martin +Martin Drasar +Martin Dreher +Martin Frodl +Martin Galvan +Martin Hager +Martin Hedenfalk +Martin Jansen +Martin Kepplinger +Martin Lemke +Martin Skinner +Martin Storsjö +Martin Vejnár +Marty Kuhrt +Maruko +Massimiliano Ziccardi +Massimo Callegari +Mateusz Loskot +Mathias Axelsson +Mats Lidell +Matt Arsenault +Matt Ford +Matt Kraai +Matt Veenstra +Matt Witherspoon +Matt Wixson +Matteo B. +Matteo Bignotti +Matteo Rocco +Matthew Blain +Matthew Clarke +Matthew Hall +Matthew Kerwin +Matthias Bolte +Mattias Fornander +Maurice Barnum +Mauro Iorio +Mauro Rappa +Max Dymond +Max Katsev +Max Khon +Max Savenkov +Maxim Ivanov +Maxim Perenesenko +Maxim Prohorov +Maxime Larocque +Mehmet Bozkurt +Mekonikum +Melissa Mears +Mettgut Jamalla +Michael Benedict +Michael Calmer +Michael Cronenworth +Michael Curtis +Michael Day +Michael Felt +Michael Gmelin +Michael Goffioul +Michael Jahn +Michael Jerris +Michael Kalinin +Michael Kaufmann +Michael Kilburn +Michael König +Michael Maltese +Michael Mealling +Michael Mueller +Michael Osipov +Michael Smith +Michael Stapelberg +Michael Stillwell +Michael Wallner +Michal Bonino +Michal Marek +Michal Trybus +Michał Fita +Michał Górny +Michał Janiszewski +Michał Kowalczyk +Michał Piechowski +Michel Promonet +Michele Bini +Miguel Angel +Miguel Diaz +Mihai Ionescu +Mikael Johansson +Mikael Sennerholm +Mikalai Ananenka +Mike Bytnar +Mike Crowe +Mike Dobbs +Mike Giancola +Mike Hasselberg +Mike Henshaw +Mike Hommey +Mike Mio +Mike Power +Mike Protts +Mike Revi +Miklos Nemeth +Miloš Ljumović +Mingliang Zhu +Miroslav Franc +Miroslav Spousta +Mitz Wark +Mohamed Lrhazi +Mohammad AlSaleh +Mohun Biswas +Mostyn Bramley-Moore +Moti Avrahami +Muz Dima +Myk Taylor +Nach M. S. +Nagai H +Nathan Coulter +Nathan O'Sullivan +Nathanael Nerode +Nathaniel Waisbrot +Naveen Chandran +Naveen Noel +Neal Poole +Nehal J Wani +Neil Bowers +Neil Dunbar +Neil Kolban +Neil Spring +Nic Roets +Nicholas Maniscalco +Nick Draffen +Nick Gimbrone +Nick Humfrey +Nick Miyake +Nick Zitzmann +Nico Baggus +Nicolas Berloquin +Nicolas Croiset +Nicolas François +Nicolas Morey-Chaisemartin +Niels van Tongeren +Nikita Schmidt +Nikitinskit Dmitriy +Niklas Angebrand +Nikolai Kondrashov +Nikos Mavrogiannopoulos +Nikos Tsipinakis +Ning Dong +Nir Soffer +Nis Jorgensen +Nobuhiro Ban +Nodak Sodak +Norbert Frese +Norbert Kett +Norbert Novotny +Octavio Schroeder +Ofer +Okhin Vasilij +Ola Mork +Olaf Flebbe +Olaf Stüben +Oleg Pudeyev +Oli Kingshott +Oliver Gondža +Oliver Graute +Oliver Kuckertz +Oliver Schindler +Olivier Berger +Olivier Brunel +Orange Tsai +Oren Souroujon +Oren Tirosh +Orgad Shaneh +Ori Avtalion +Oscar Koeroo +Oscar Norlander +Oumph on github +P R Schaffner +Palo Markovic +Paolo Piacentini +Paras Sethia +Pascal Gaudette +Pascal Terjan +Pasha Kuznetsov +Pasi Karkkainen +Pat Ray +Patrice Guerin +Patricia Muscalu +Patrick Bihan-Faou +Patrick Dawson +Patrick McManus +Patrick Monnerat +Patrick Rapin +Patrick Schlangen +Patrick Scott +Patrick Smith +Patrick Watson +Patrik Thunstrom +Pau Garcia i Quiles +Paul Donohue +Paul Harrington +Paul Harris +Paul Howarth +Paul Joyce +Paul Marks +Paul Marquis +Paul Moore +Paul Nolan +Paul Oliver +Paul Querna +Paul Saab +Pavel Cenek +Pavel Gushchin +Pavel Orehov +Pavel Pavlov +Pavel Raiskup +Pavel Rochnyak +Pavol Markovic +Pawel A. Gajda +Pawel Kierski +Pedro Larroy +Pedro Neves +Per Lundberg +Per Malmberg +Pete Lomax +Peter Bray +Peter Forret +Peter Frühberger +Peter Gal +Peter Heuchert +Peter Hjalmarsson +Peter Korsgaard +Peter Lamare +Peter Lamberg +Peter Laser +Peter O'Gorman +Peter Pentchev +Peter Piekarski +Peter Silva +Peter Su +Peter Sylvester +Peter Todd +Peter Varga +Peter Verhas +Peter Wang +Peter Wu +Peter Wullinger +Peteris Krumins +Petr Bahula +Petr Novak +Petr Pisar +Petr Voytsik +Phil Blundell +Phil Crump +Phil Karn +Phil Lisiecki +Phil Pellouchoud +Philip Craig +Philip Gladstone +Philip Langdale +Philip Prindeville +Philippe Hameau +Philippe Raoult +Philippe Vaucher +Pierre +Pierre Brico +Pierre Chapuis +Pierre Joye +Pierre Ynard +Piotr Dobrogost +Pooyan McSporran +Pramod Sharma +Prash Dush +Praveen Pvs +Priyanka Shah +Puneet Pawaia +Quagmire +Quanah Gibson-Mount +Quinn Slack +R. Dennis Steed +Radu Simionescu +Rafa Muyo +Rafael Antonio +Rafael Sagula +Rafayel Mkrtchyan +Rafaël Carré +Rainer Canavan +Rainer Jung +Rainer Koenig +Rainer Müller +Rajesh Naganathan +Rajkumar Mandal +Ralf S. Engelschall +Ralph Beckmann +Ralph Mitchell +Ramana Mokkapati +Randall S. Becker +Randy Armstrong +Randy McMurchy +Raphael Gozzo +Ravi Pratap +Ray Dassen +Ray Pekowski +Ray Satiro +Razvan Cojocaru +Reinhard Max +Reinout van Schouwen +Remi Gacogne +Remo E +Renato Botelho +Renaud Chaillat +Renaud Duhaut +Renaud Guillard +Renaud Lehoux +Rene Bernhardt +Rene Rebe +Reuven Wachtfogel +Reza Arbab +Ricardo Cadime +Rich Burridge +Rich Gray +Rich Rauenzahn +Richard Alcock +Richard Archer +Richard Atterer +Richard Bramante +Richard Clayton +Richard Cooper +Richard Gorton +Richard Gray +Richard Hosking +Richard Hsu +Richard Michael +Richard Moore +Richard Prescott +Richard Silverman +Richard van den Berg +Richy Kim +Rick Deist +Rick Jones +Rick Richardson +Ricki Hirner +Rider Linden +Rikard Falkeborn +Rob Cotrone +Rob Crittenden +Rob Davies +Rob Jones +Rob Sanders +Rob Stanzel +Rob Ward +Robert A. Monat +Robert B. Harris +Robert D. Young +Robert Foreman +Robert Iakobashvili +Robert Kolcun +Robert Olson +Robert Prag +Robert Schumann +Robert Weaver +Robert Wruck +Robin Cornelius +Robin Johnson +Robin Kay +Robson Braga Araujo +Rod Widdowson +Rodney Simmons +Rodric Glaser +Rodrigo Silva +Roger Leigh +Roland Blom +Roland Krikava +Roland Zimmermann +Rolland Dudemaine +Romain Coltel +Roman Koifman +Roman Mamedov +Romulo A. Ceccon +Ron Eldor +Ron Parker +Ron Zapp +Ronnie Mose +Rosimildo da Silva +Roy Shan +Rune Kleveland +Ruslan Baratov +Ruslan Gazizov +Rutger Hofman +Ruurd Beerstra +Ryan Braud +Ryan Chan +Ryan Nelson +Ryan Schmidt +Ryan Scott +Ryan Winograd +Ryuichi KAWAMATA +Rémy Léone +S. Moonesamy +SBKarr on github +Salah-Eddin Shaban +Salvador Dávila +Salvatore Sorrentino +Sam Deane +Sam Hurst +Sam Roth +Sam Schanken +Sampo Kellomaki +Samuel Díaz García +Samuel Listopad +Samuel Thibault +Sander Gates +Sandor Feldi +Santhana Todatry +Saqib Ali +Sara Golemon +Saran Neti +Sascha Swiercy +Saul good +Saurav Babu +Scott Bailey +Scott Barrett +Scott Cantor +Scott Davis +Scott McCreary +Sean Boudreau +Sean Burford +Sean MacLennan +Sean Miller +Sebastian Mundry +Sebastian Pohlschmidt +Sebastian Rasmussen +Senthil Raja Velu +Sergei Kuzmin +Sergei Nikulov +Sergey Tatarincev +Sergii Kavunenko +Sergii Pylypenko +Sergio Ballestrero +Sergio Borghese +Serj Kalichev +Seshubabu Pasam +Seth Mos +Sh Diao +Shachaf Ben-Kiki +Shao Shuchao +Sharad Gupta +Shard +Shawn Landden +Shawn Poulson +Shine Fan +Shmulik Regev +Siddhartha Prakash Jain +Sidney San Martín +Siegfried Gyuricsko +Simon Dick +Simon H. +Simon Josefsson +Simon Liu +Simon Warta +Somnath Kundu +Song Ma +Sonia Subramanian +Spacen Jasset +Spiridonoff A.V +Spork Schivago +Stadler Stephan +Stan van de Burgt +Stanislav Ivochkin +Stanislav Zidek +Stefan Agner +Stefan Bühler +Stefan Eissing +Stefan Esser +Stefan Kanthak +Stefan Krause +Stefan Neis +Stefan Teleman +Stefan Tomanek +Stefan Ulrich +Steinar H. Gunderson +Stepan Broz +Stephan Bergmann +Stephan Mühlstrasser +Stephen Brokenshire +Stephen Collyer +Stephen Kick +Stephen More +Stephen Toub +Sterling Hughes +Steve Brokenshire +Steve Green +Steve H Truong +Steve Havelka +Steve Holme +Steve Lhomme +Steve Little +Steve Marx +Steve Oliphant +Steve Roskowski +Steven Bazyl +Steven G. Johnson +Steven Gu +Steven M. Schweda +Steven Parkes +Stoned Elipot +Stuart Henderson +Sune Ahlgren +Sunny Purushe +Sven Anders +Sven Neuhaus +Sven Wegener +Svyatoslav Mishyn +Sylvestre Ledru +Symeon Paraschoudis +Sébastien Willemijns +T. Bharath +T. Yamada +TJ Saunders +Tae Hyoung Ahn +Taneli Vähäkangas +Tanguy Fautre +Tatsuhiro Tsujikawa +Temprimus +Terri Oda +Terry Wu +TheAssassin on github +Theodore Dubois +Thomas Braun +Thomas Glanzmann +Thomas J. Moore +Thomas Klausner +Thomas L. Shinnick +Thomas Lopatic +Thomas Petazzoni +Thomas Ruecker +Thomas Schwinge +Thomas Tonino +Thomas van Hesteren +Thorsten Schöning +Tiit Pikma +Till Maas +Tim Ansell +Tim Baker +Tim Bartley +Tim Chen +Tim Costello +Tim Harder +Tim Heckman +Tim Mcdonough +Tim Newsome +Tim Rühsen +Tim Sneddon +Tim Stack +Tim Starling +Timo Sirainen +Timotej Lazar +Timothe Litt +Timothy Polich +Tinus van den Berg +Tobias Markus +Tobias Rundström +Tobias Stoeckmann +Toby Peterson +Todd A Ouska +Todd Kulesza +Todd Short +Todd Vierling +Tom Benoist +Tom Donovan +Tom Grace +Tom Lee +Tom Mattison +Tom Moers +Tom Mueller +Tom Regner +Tom Seddon +Tom Sparrow +Tom Wright +Tom Zerucha +Tomas Hoger +Tomas Jakobsson +Tomas Mlcoch +Tomas Mraz +Tomas Pospisek +Tomas Szepe +Tomas Tomecek +Tomasz Kojm +Tomasz Lacki +Tommie Gannert +Tommy Tam +Ton Voon +Toni Moreno +Tony Kelman +Toon Verwaest +Tor Arntsen +Torben Dannhauer +Torsten Foertsch +Toshio Kuratomi +Toshiyuki Maezawa +Traian Nicolescu +Travis Burtrum +Travis Obenhaus +Troels Walsted Hansen +Troy Engel +Tupone Alfredo +Tyler Hall +Török Edwin +Ulf Härnhammar +Ulf Samuelsson +Ulrich Doehner +Ulrich Telle +Ulrich Zadow +Valentin David +Vasiliy Faronov +Vasy Okhin +Venkat Akella +Venkataramana Mokkapati +Victor Snezhko +Vijay Panghal +Vikram Saxena +Viktor Szakats +Ville Skyttä +Vilmos Nebehaj +Vincas Razma +Vincent Bronner +Vincent Le Normand +Vincent Penquerc'h +Vincent Sanders +Vincent Torri +Vlad Grachov +Vlad Ureche +Vladimir Grishchenko +Vladimir Kotal +Vladimir Lazarenko +Vojtech Janota +Vojtech Minarik +Vojtěch Král +Vsevolod Novikov +W. Mark Kubacki +Waldek Kozba +Walter J. Mack +Ward Willats +Warp Kawada +Warren Menzer +Wayne Haigh +Werner Koch +Wesley Laxton +Wesley Miaw +Wez Furlong +Wham Bang +Wilfredo Sanchez +Will Dietz +Willem Sparreboom +William Ahern +Wojciech Zwiefka +Wouter Van Rooy +Wu Yongzheng +Wyatt O'Day +Xavier Bouchoux +XhstormR on github +Xiangbin Li +Yaakov Selkowitz +Yamada Yasuharu +Yang Tse +Yarram Sunil +Yasuharu Yamada +Yehezkel Horowitz +Yehoshua Hershberg +Yi Huang +Yingwei Liu +Yonggang Luo +Yousuke Kimoto +Yukihiro Kawada +Yun SangHo +Yuriy Sosov +Yves Arrouye +Yves Lejeune +Zachary Seguin +Zdenek Pavlas +Zekun Ni +Zenju on github +Zhouyihai Ding +Zmey Petroff +Zvi Har'El +afrind on github +ahodesuka on github +anshnd on github +arainchik on github +asavah on github +baumanj on github +bsammon on github +cbartl on github +cmfrolick on github +dasimx on github +destman on github +dkjjr89 on github +dpull on github +eXeC64 on github +elelel on github +elephoenix on github +guitared on github +hsiao yi +imilli on github +iz8mbw on github +jonrumsey on github +joshhe on github +jungle-boogie on github +jveazey on github +ka7 on github +kreshano on github +lijian996 on github +lukaszgn on github +madblobfish on github +marc-groundctl on github +mccormickt12 on github +mkzero on github +moohoorama on github +neex on github +neheb on github +nk +nopjmp on github +olesteban on github +omau on github +ovidiu-benea on github +patelvivekv1993 on github +paulharris on github +pszemus on github +silveja1 on github +steelman on github +steini2000 on github +stootill on github +swalkaus at yahoo.com +tarek112 on github +tommink[at]post.pl +vanillajonathan on github +wmsch on github +wncboy on github +wyattoday on github +youngchopin on github +zelinchen on github +zzq1015 on github +İsmail Dönmez +Łukasz Domeradzki +Štefan Kremeň +Никита Дорохин diff --git a/docs/THANKS-filter b/docs/THANKS-filter new file mode 100644 index 00000000..76b5f50d --- /dev/null +++ b/docs/THANKS-filter @@ -0,0 +1,81 @@ +# This is a list of names we have recorded that already are thanked +# appropriately in THANKS. This list contains variations of their names and +# their "canonical" name. This file is used for scripting purposes to avoid +# duplicate entries and will not be included in release tarballs. +# When removing dupes that aren't identical names from THANKS, add a line +# here! +# +# Used-by: contributor.sh +s/Andres Garcia/Andrés García/ +s/Chris Conroy/Christopher Conroy/ +s/Francois Charlier/François Charlier/ +s/Gokhan Sengun/Gökhan Şengün/ +s/John Malmberg/John E. Malmberg/ +s/Luca Alteas/Luca Altea/ +s/Michal Gorny/Michał Górny/ +s/Michal Górny/Michał Górny/ +s/Moonesamy/S. Moonesamy/ +s/Pete Su$/Peter Su/ +s/Sam Listopad/Samuel Listopad/ +s/Sebastien Willemijns/Sébastien Willemijns/ +s/YAMADA Yasuharu/Yasuharu Yamada/ +s/Karl M$/Karl Moerder/ +s/Bjorn Stenberg/Björn Stenberg/ +s/upstream tests 305 and 404// +s/Gaël PORTAY/Gaël Portay/ +s/Romulo Ceccon/Romulo A. Ceccon/ +s/Nach M. S$/Nach M. S./ +s/Jay Satiro/Ray Satiro/ +s/Richard J. Moore/Richard Moore/ +s/Sergey Nikulov/Sergei Nikulov/ +s/Petr Písař/Petr Pisar/ +s/Nick Zitzmann (originally)/Nick Zitzmann/ +s/product-security at Apple// +s/IT DOES NOT WORK// +s/Albert Chin/Albert Chin-A-Young/ +s/Paras S\z/Paras Sethia/ +s/Paras Sethiaethia/Paras Sethia/ +s/Дмитрий Фалько/Dmitry Falko/ +s/byte_bucket in the #curl IRC channel// +s/Michal Górny and Anthony G. Basile// +s/Alejandro Alvarez$/Alejandro Alvarez Ayllon/ +s/Ant Bryan/Anthony Bryan/ +s/Cédric Deltheil/Cédric Deltheil/ +s/Christian Hagele/Christian Hägele/ +s/douglas steinwand/Douglas Steinwand/ +s/Frank Van Uffelen and Fabian Hiernaux// +s/Rodrigo Silva (MestreLion)/Rodrigo Silva/ +s/tetetest tetetest// +s/Jiří Hruška/Jiri Hruska/ +s/Viktor Szakáts/Viktor Szakats/ +s/Jonathan Cardoso$/Jonathan Cardoso Machado/ +s/Linus Nielsen$/Linus Nielsen Feltzing/ +s/Todd Ouska$/Todd A Ouska/ +s/Tim Ruehsen/Tim Rühsen/ +s/Michael Koenig/Michael König/ +s/moparisthebest/Travis Burtrum/ +s/Jan-E/Jan Ehrhardt/ +s/Paras S$/Paras Sethia/ +s/Cristian Rodr\xEDguez$/Cristian Rodríguez/ +s/Sidney San Mart\xEDn$/Sidney San Martín/ +s/Sidney San Martin$/Sidney San Martín/ +s/Taneli V\xE4h\xE4kangas$/Taneli Vähäkangas/ +s/Taneli Vahakangas$/Taneli Vähäkangas/ +s/Никита Дорохин./Никита Дорохин/ +s/upstream tests 305// +s/ (edited)// +s/Jean-Philippe Barette-LaPierre$/Jean-Philippe Barrette-LaPierre/ +s/Joern Hartroth$/Jörn Hartroth/ +s/Hongli Lai (Phusion)$/Hongli Lai/ +s/github user 'kreshano'$/kreshano on github/ +s/Marc Hoersken$/Marc Hörsken/ +s/Martin Storsjo$/Martin Storsjö/ +s/Jiri Malak$/Jiří Malák/ +s/JDepooter$/Joel Depooter/ +s/ERAMOTO Masaya$/Eramoto Masaya/ +s/shachaf on github$/Shachaf Ben-Kiki/ +s/CarloCannas on github$/Carlo Cannas/ +s/Henrik S. Gaßmann$/Henrik Gaßmann/ +s/moteus on github/Alexey Melnichuk/ +s/Rich Moore/Richard Moore/ +s/kdekker/Kees Dekker/ diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 00000000..269c9300 --- /dev/null +++ b/docs/TODO @@ -0,0 +1,1258 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + Things that could be nice to do in the future + + Things to do in project curl. Please tell us what you think, contribute and + send us patches that improve things! + + Be aware that these are things that we could do, or have once been considered + things we could do. If you want to work on any of these areas, please + consider bringing it up for discussions first on the mailing list so that we + all agree it is still a good idea for the project! + + All bugs documented in the KNOWN_BUGS document are subject for fixing! + + 1. libcurl + 1.2 More data sharing + 1.3 struct lifreq + 1.4 signal-based resolver timeouts + 1.5 get rid of PATH_MAX + 1.6 Modified buffer size approach + 1.7 Support HTTP/2 for HTTP(S) proxies + 1.8 CURLOPT_RESOLVE for any port number + 1.9 Cache negative name resolves + 1.10 auto-detect proxy + 1.11 minimize dependencies with dynamically loaded modules + 1.12 updated DNS server while running + 1.13 DNS-over-HTTPS + 1.14 Typesafe curl_easy_setopt() + 1.15 Monitor connections in the connection pool + 1.16 Try to URL encode given URL + 1.17 Add support for IRIs + 1.18 try next proxy if one doesn't work + 1.19 Timeout idle connections from the pool + 1.20 SRV and URI DNS records + 1.21 API for URL parsing/splitting + 1.22 CURLINFO_PAUSE_STATE + 1.23 Offer API to flush the connection pool + 1.24 TCP Fast Open for windows + 1.25 Expose tried IP addresses that failed + 1.26 CURL_REFUSE_CLEARTEXT + 1.27 hardcode the "localhost" addresses + 1.28 FD_CLOEXEC + + 2. libcurl - multi interface + 2.1 More non-blocking + 2.2 Better support for same name resolves + 2.3 Non-blocking curl_multi_remove_handle() + 2.4 Split connect and authentication process + 2.5 Edge-triggered sockets should work + + 3. Documentation + 3.2 Provide cmake config-file + + 4. FTP + 4.1 HOST + 4.2 Alter passive/active on failure and retry + 4.3 Earlier bad letter detection + 4.4 REST for large files + 4.5 ASCII support + 4.6 GSSAPI via Windows SSPI + 4.7 STAT for LIST without data connection + 4.8 Option to ignore private IP addresses in PASV response + + 5. HTTP + 5.1 Better persistency for HTTP 1.0 + 5.2 support FF3 sqlite cookie files + 5.3 Rearrange request header order + 5.5 auth= in URLs + 5.6 Refuse "downgrade" redirects + 5.7 QUIC + 5.8 Leave secure cookies alone + + 6. TELNET + 6.1 ditch stdin + 6.2 ditch telnet-specific select + 6.3 feature negotiation debug data + + 7. SMTP + 7.1 Pipelining + 7.2 Enhanced capability support + 7.3 Add CURLOPT_MAIL_CLIENT option + + 8. POP3 + 8.1 Pipelining + 8.2 Enhanced capability support + + 9. IMAP + 9.1 Enhanced capability support + + 10. LDAP + 10.1 SASL based authentication mechanisms + + 11. SMB + 11.1 File listing support + 11.2 Honor file timestamps + 11.3 Use NTLMv2 + 11.4 Create remote directories + + 12. New protocols + 12.1 RSYNC + + 13. SSL + 13.1 Disable specific versions + 13.2 Provide mutex locking API + 13.3 Support in-memory certs/ca certs/keys + 13.4 Cache/share OpenSSL contexts + 13.5 Export session ids + 13.6 Provide callback for cert verification + 13.7 improve configure --with-ssl + 13.8 Support DANE + 13.9 Configurable loading of OpenSSL configuration file + 13.11 Support intermediate & root pinning for PINNEDPUBLICKEY + 13.12 Support HSTS + 13.13 Support HPKP + 13.14 Support the clienthello extension + + 14. GnuTLS + 14.1 SSL engine stuff + 14.2 check connection + + 15. WinSSL/SChannel + 15.1 Add support for client certificate authentication + 15.3 Add support for the --ciphers option + + 16. SASL + 16.1 Other authentication mechanisms + 16.2 Add QOP support to GSSAPI authentication + 16.3 Support binary messages (i.e.: non-base64) + + 17. SSH protocols + 17.1 Multiplexing + 17.2 SFTP performance + 17.3 Support better than MD5 hostkey hash + 17.4 Support CURLOPT_PREQUOTE + + 18. Command line tool + 18.1 sync + 18.2 glob posts + 18.3 prevent file overwriting + 18.4 simultaneous parallel transfers + 18.5 UTF-8 filenames in Content-Disposition + 18.6 warning when setting an option + 18.7 warning if curl version is not in sync with libcurl version + 18.8 offer color-coded HTTP header output + 18.9 Choose the name of file in braces for complex URLs + 18.10 improve how curl works in a windows console window + 18.11 -w output to stderr + 18.12 keep running, read instructions from pipe/socket + 18.13 support metalink in http headers + 18.14 --fail without --location should treat 3xx as a failure + 18.15 --retry should resume + 18.16 send only part of --data + 18.17 consider file name from the redirected URL with -O ? + 18.18 retry on network is unreachable + 18.19 expand ~/ in config files + + 19. Build + 19.1 roffit + 19.2 Enable PIE and RELRO by default + + 20. Test suite + 20.1 SSL tunnel + 20.2 nicer lacking perl message + 20.3 more protocols supported + 20.4 more platforms supported + 20.5 Add support for concurrent connections + 20.6 Use the RFC6265 test suite + + 21. Next SONAME bump + 21.1 http-style HEAD output for FTP + 21.2 combine error codes + 21.3 extend CURLOPT_SOCKOPTFUNCTION prototype + + 22. Next major release + 22.1 cleanup return codes + 22.2 remove obsolete defines + 22.3 size_t + 22.4 remove several functions + 22.5 remove CURLOPT_FAILONERROR + 22.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE + 22.7 remove progress meter from libcurl + 22.8 remove 'curl_httppost' from public + +============================================================================== + +1. libcurl + +1.2 More data sharing + + curl_share_* functions already exist and work, and they can be extended to + share more. For example, enable sharing of the ares channel. + +1.3 struct lifreq + + Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and + SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete. + To support IPv6 interface addresses for network interfaces properly. + +1.4 signal-based resolver timeouts + + libcurl built without an asynchronous resolver library uses alarm() to time + out DNS lookups. When a timeout occurs, this causes libcurl to jump from the + signal handler back into the library with a sigsetjmp, which effectively + causes libcurl to continue running within the signal handler. This is + non-portable and could cause problems on some platforms. A discussion on the + problem is available at https://curl.haxx.se/mail/lib-2008-09/0197.html + + Also, alarm() provides timeout resolution only to the nearest second. alarm + ought to be replaced by setitimer on systems that support it. + +1.5 get rid of PATH_MAX + + Having code use and rely on PATH_MAX is not nice: + https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html + + Currently the SSH based code uses it a bit, but to remove PATH_MAX from there + we need libssh2 to properly tell us when we pass in a too small buffer and + its current API (as of libssh2 1.2.7) doesn't. + +1.6 Modified buffer size approach + + Current libcurl allocates a fixed 16K size buffer for download and an + additional 16K for upload. They are always unconditionally part of the easy + handle. If CRLF translations are requested, an additional 32K "scratch + buffer" is allocated. A total of 64K transfer buffers in the worst case. + + First, while the handles are not actually in use these buffers could be freed + so that lingering handles just kept in queues or whatever waste less memory. + + Secondly, SFTP is a protocol that needs to handle many ~30K blocks at once + since each need to be individually acked and therefore libssh2 must be + allowed to send (or receive) many separate ones in parallel to achieve high + transfer speeds. A current libcurl build with a 16K buffer makes that + impossible, but one with a 512K buffer will reach MUCH faster transfers. But + allocating 512K unconditionally for all buffers just in case they would like + to do fast SFTP transfers at some point is not a good solution either. + + Dynamically allocate buffer size depending on protocol in use in combination + with freeing it after each individual transfer? Other suggestions? + +1.7 Support HTTP/2 for HTTP(S) proxies + + Support for doing HTTP/2 to HTTP and HTTPS proxies is still missing. + +1.8 CURLOPT_RESOLVE for any port number + + This option allows applications to set a replacement IP address for a given + host + port pair. Consider making support for providing a replacement address + for the host name on all port numbers. + + See https://github.com/curl/curl/issues/1264 + +1.9 Cache negative name resolves + + A name resolve that has failed is likely to fail when made again within a + short period of time. Currently we only cache positive responses. + +1.10 auto-detect proxy + + libcurl could be made to detect the system proxy setup automatically and use + that. On Windows, macOS and Linux desktops for example. + + The pull-request to use libproxy for this was deferred due to doubts on the + reliability of the dependency and how to use it: + https://github.com/curl/curl/pull/977 + + libdetectproxy is a (C++) library for detecting the proxy on Windows + https://github.com/paulharris/libdetectproxy + +1.11 minimize dependencies with dynamically loaded modules + + We can create a system with loadable modules/plug-ins, where these modules + would be the ones that link to 3rd party libs. That would allow us to avoid + having to load ALL dependencies since only the necessary ones for this + app/invoke/used protocols would be necessary to load. See + https://github.com/curl/curl/issues/349 + +1.12 updated DNS server while running + + If /etc/resolv.conf gets updated while a program using libcurl is running, it + is may cause name resolves to fail unless res_init() is called. We should + consider calling res_init() + retry once unconditionally on all name resolve + failures to mitigate against this. Firefox works like that. Note that Windows + doesn't have res_init() or an alternative. + + https://github.com/curl/curl/issues/2251 + +1.13 DNS-over-HTTPS + + By adding support for DNS-over-HTTPS curl could resolve host names using a + totally separate name server than the standard system resolver, while at the + same time doing so over a communication channel that enhances privacy and + security. + + https://github.com/curl/curl/wiki/DNS-over-HTTPS + +1.14 Typesafe curl_easy_setopt() + + One of the most common problems in libcurl using applications is the lack of + type checks for curl_easy_setopt() which happens because it accepts varargs + and thus can take any type. + + One possible solution to this is to introduce a few different versions of the + setopt version for the different kinds of data you can set. + + curl_easy_set_num() - sets a long value + + curl_easy_set_large() - sets a curl_off_t value + + curl_easy_set_ptr() - sets a pointer + + curl_easy_set_cb() - sets a callback PLUS its callback data + +1.15 Monitor connections in the connection pool + + libcurl's connection cache or pool holds a number of open connections for the + purpose of possible subsequent connection reuse. It may contain a few up to a + significant amount of connections. Currently, libcurl leaves all connections + as they are and first when a connection is iterated over for matching or + reuse purpose it is verified that it is still alive. + + Those connections may get closed by the server side for idleness or they may + get a HTTP/2 ping from the peer to verify that they're still alive. By adding + monitoring of the connections while in the pool, libcurl can detect dead + connections (and close them) better and earlier, and it can handle HTTP/2 + pings to keep such ones alive even when not actively doing transfers on them. + +1.16 Try to URL encode given URL + + Given a URL that for example contains spaces, libcurl could have an option + that would try somewhat harder than it does now and convert spaces to %20 and + perhaps URL encoded byte values over 128 etc (basically do what the redirect + following code already does). + + https://github.com/curl/curl/issues/514 + +1.17 Add support for IRIs + + IRIs (RFC 3987) allow localized, non-ascii, names in the URL. To properly + support this, curl/libcurl would need to translate/encode the given input + from the input string encoding into percent encoded output "over the wire". + + To make that work smoothly for curl users even on Windows, curl would + probably need to be able to convert from several input encodings. + +1.18 try next proxy if one doesn't work + + Allow an application to specify a list of proxies to try, and failing to + connect to the first go on and try the next instead until the list is + exhausted. Browsers support this feature at least when they specify proxies + using PACs. + + https://github.com/curl/curl/issues/896 + +1.19 Timeout idle connections from the pool + + libcurl currently keeps connections in its connection pool for an indefinite + period of time, until it either gets reused, gets noticed that it has been + closed by the server or gets pruned to make room for a new connection. + + To reduce overhead (especially for when we add monitoring of the connections + in the pool), we should introduce a timeout so that connections that have + been idle for N seconds get closed. + +1.20 SRV and URI DNS records + + Offer support for resolving SRV and URI DNS records for libcurl to know which + server to connect to for various protocols (including HTTP!). + +1.21 API for URL parsing/splitting + + libcurl has always parsed URLs internally and never exposed any API or + features to allow applications to do it. Still most or many applications + using libcurl need that ability. In polls to users, we've learned that many + libcurl users would like to see and use such an API. + +1.22 CURLINFO_PAUSE_STATE + + Return information about the transfer's current pause state, in both + directions. https://github.com/curl/curl/issues/2588 + +1.23 Offer API to flush the connection pool + + Sometimes applications want to flush all the existing connections kept alive. + An API could allow a forced flush or just a forced loop that would properly + close all connections that have been closed by the server already. + +1.24 TCP Fast Open for windows + + libcurl supports the CURLOPT_TCP_FASTOPEN option since 7.49.0 for Linux and + Mac OS. Windows supports TCP Fast Open starting with Windows 10, version 1607 + and we should add support for it. + +1.25 Expose tried IP addresses that failed + + When libcurl fails to connect to a host, it should be able to offer the + application the list of IP addresses that were used in the attempt. + + https://github.com/curl/curl/issues/2126 + +1.26 CURL_REFUSE_CLEARTEXT + + An environment variable that when set will make libcurl refuse to use any + cleartext network protocol. That's all non-encrypted ones (FTP, HTTP, Gopher, + etc). By adding the check to libcurl and not just curl, this environment + variable can then help users to block all libcurl-using programs from + accessing the network using unsafe protocols. + + The variable could be given some sort of syntax or different levels and be + used to also allow for example users to refuse libcurl to do transfers with + HTTPS certificate checks disabled. + + It could also offer to refuse usernames in URLs (see TODO 1.1) + +1.27 hardcode the "localhost" addresses + + There's this new spec getting adopted that says "localhost" should always and + unconditionally be a local address and not get resolved by a DNS server. A + fine way for curl to fix this would be to simply hard-code the response to + 127.0.0.1 and/or ::1 (depending on what IP versions that are requested). This + is what the browsers probably will do with this hostname. + + https://bugzilla.mozilla.org/show_bug.cgi?id=1220810 + + https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02 + +1.28 FD_CLOEXEC + + It sets the close-on-exec flag for the file descriptor, which causes the file + descriptor to be automatically (and atomically) closed when any of the + exec-family functions succeed. Should probably be set by default? + + https://github.com/curl/curl/issues/2252 + +2. libcurl - multi interface + +2.1 More non-blocking + + Make sure we don't ever loop because of non-blocking sockets returning + EWOULDBLOCK or similar. Blocking cases include: + + - Name resolves on non-windows unless c-ares or the threaded resolver is used + - SOCKS proxy handshakes + - file:// transfers + - TELNET transfers + - The "DONE" operation (post transfer protocol-specific actions) for the + protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task. + +2.2 Better support for same name resolves + + If a name resolve has been initiated for name NN and a second easy handle + wants to resolve that name as well, make it wait for the first resolve to end + up in the cache instead of doing a second separate resolve. This is + especially needed when adding many simultaneous handles using the same host + name when the DNS resolver can get flooded. + +2.3 Non-blocking curl_multi_remove_handle() + + The multi interface has a few API calls that assume a blocking behavior, like + add_handle() and remove_handle() which limits what we can do internally. The + multi API need to be moved even more into a single function that "drives" + everything in a non-blocking manner and signals when something is done. A + remove or add would then only ask for the action to get started and then + multi_perform() etc still be called until the add/remove is completed. + +2.4 Split connect and authentication process + + The multi interface treats the authentication process as part of the connect + phase. As such any failures during authentication won't trigger the relevant + QUIT or LOGOFF for protocols such as IMAP, POP3 and SMTP. + +2.5 Edge-triggered sockets should work + + The multi_socket API should work with edge-triggered socket events. One of + the internal actions that need to be improved for this to work perfectly is + the 'maxloops' handling in transfer.c:readwrite_data(). + +3. Documentation + +3.2 Provide cmake config-file + + A config-file package is a set of files provided by us to allow applications + to write cmake scripts to find and use libcurl easier. See + https://github.com/curl/curl/issues/885 + +4. FTP + +4.1 HOST + + HOST is a command for a client to tell which host name to use, to offer FTP + servers named-based virtual hosting: + + https://tools.ietf.org/html/rfc7151 + +4.2 Alter passive/active on failure and retry + + When trying to connect passively to a server which only supports active + connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the + connection. There could be a way to fallback to an active connection (and + vice versa). https://curl.haxx.se/bug/feature.cgi?id=1754793 + +4.3 Earlier bad letter detection + + Make the detection of (bad) %0d and %0a codes in FTP URL parts earlier in the + process to avoid doing a resolve and connect in vain. + +4.4 REST for large files + + REST fix for servers not behaving well on >2GB requests. This should fail if + the server doesn't set the pointer to the requested index. The tricky + (impossible?) part is to figure out if the server did the right thing or not. + +4.5 ASCII support + + FTP ASCII transfers do not follow RFC959. They don't convert the data + accordingly. + +4.6 GSSAPI via Windows SSPI + + In addition to currently supporting the SASL GSSAPI mechanism (Kerberos V5) + via third-party GSS-API libraries, such as Heimdal or MIT Kerberos, also add + support for GSSAPI authentication via Windows SSPI. + +4.7 STAT for LIST without data connection + + Some FTP servers allow STAT for listing directories instead of using LIST, + and the response is then sent over the control connection instead of as the + otherwise usedw data connection: http://www.nsftools.com/tips/RawFTP.htm#STAT + + This is not detailed in any FTP specification. + +4.8 Option to ignore private IP addresses in PASV response + + Some servers respond with and some other FTP client implementations can + ignore private (RFC 1918 style) IP addresses when received in PASV responses. + To consider for libcurl as well. See https://github.com/curl/curl/issues/1455 + +5. HTTP + +5.1 Better persistency for HTTP 1.0 + + "Better" support for persistent connections over HTTP 1.0 + https://curl.haxx.se/bug/feature.cgi?id=1089001 + +5.2 support FF3 sqlite cookie files + + Firefox 3 is changing from its former format to a a sqlite database instead. + We should consider how (lib)curl can/should support this. + https://curl.haxx.se/bug/feature.cgi?id=1871388 + +5.3 Rearrange request header order + + Server implementors often make an effort to detect browser and to reject + clients it can detect to not match. One of the last details we cannot yet + control in libcurl's HTTP requests, which also can be exploited to detect + that libcurl is in fact used even when it tries to impersonate a browser, is + the order of the request headers. I propose that we introduce a new option in + which you give headers a value, and then when the HTTP request is built it + sorts the headers based on that number. We could then have internally created + headers use a default value so only headers that need to be moved have to be + specified. + +5.5 auth= in URLs + + Add the ability to specify the preferred authentication mechanism to use by + using ;auth= in the login part of the URL. + + For example: + + http://test:pass;auth=NTLM@example.com would be equivalent to specifying --user + test:pass;auth=NTLM or --user test:pass --ntlm from the command line. + + Additionally this should be implemented for proxy base URLs as well. + +5.6 Refuse "downgrade" redirects + + See https://github.com/curl/curl/issues/226 + + Consider a way to tell curl to refuse to "downgrade" protocol with a redirect + and/or possibly a bit that refuses redirect to change protocol completely. + +5.7 QUIC + + The standardization process of QUIC has been taken to the IETF and can be + followed on the [IETF QUIC Mailing + list](https://www.ietf.org/mailman/listinfo/quic). I'd like us to get on the + bandwagon. Ideally, this would be done with a separate library/project to + handle the binary/framing layer in a similar fashion to how HTTP/2 is + implemented. This, to allow other projects to benefit from the work and to + thus broaden the interest and chance of others to participate. + +5.8 Leave secure cookies alone + + Non-secure origins (HTTP sites) should not be allowed to set or modify + cookies with the 'secure' property: + + https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-01 + + +6. TELNET + +6.1 ditch stdin + +Reading input (to send to the remote server) on stdin is a crappy solution for +library purposes. We need to invent a good way for the application to be able +to provide the data to send. + +6.2 ditch telnet-specific select + + Move the telnet support's network select() loop go away and merge the code + into the main transfer loop. Until this is done, the multi interface won't + work for telnet. + +6.3 feature negotiation debug data + + Add telnet feature negotiation data to the debug callback as header data. + + +7. SMTP + +7.1 Pipelining + + Add support for pipelining emails. + +7.2 Enhanced capability support + + Add the ability, for an application that uses libcurl, to obtain the list of + capabilities returned from the EHLO command. + +7.3 Add CURLOPT_MAIL_CLIENT option + + Rather than use the URL to specify the mail client string to present in the + HELO and EHLO commands, libcurl should support a new CURLOPT specifically for + specifying this data as the URL is non-standard and to be honest a bit of a + hack ;-) + + Please see the following thread for more information: + https://curl.haxx.se/mail/lib-2012-05/0178.html + + +8. POP3 + +8.1 Pipelining + + Add support for pipelining commands. + +8.2 Enhanced capability support + + Add the ability, for an application that uses libcurl, to obtain the list of + capabilities returned from the CAPA command. + +9. IMAP + +9.1 Enhanced capability support + + Add the ability, for an application that uses libcurl, to obtain the list of + capabilities returned from the CAPABILITY command. + +10. LDAP + +10.1 SASL based authentication mechanisms + + Currently the LDAP module only supports ldap_simple_bind_s() in order to bind + to an LDAP server. However, this function sends username and password details + using the simple authentication mechanism (as clear text). However, it should + be possible to use ldap_bind_s() instead specifying the security context + information ourselves. + +11. SMB + +11.1 File listing support + +Add support for listing the contents of a SMB share. The output should probably +be the same as/similar to FTP. + +11.2 Honor file timestamps + +The timestamp of the transferred file should reflect that of the original file. + +11.3 Use NTLMv2 + +Currently the SMB authentication uses NTLMv1. + +11.4 Create remote directories + +Support for creating remote directories when uploading a file to a directory +that doesn't exist on the server, just like --ftp-create-dirs. + +12. New protocols + +12.1 RSYNC + + There's no RFC for the protocol or an URI/URL format. An implementation + should most probably use an existing rsync library, such as librsync. + +13. SSL + +13.1 Disable specific versions + + Provide an option that allows for disabling specific SSL versions, such as + SSLv2 https://curl.haxx.se/bug/feature.cgi?id=1767276 + +13.2 Provide mutex locking API + + Provide a libcurl API for setting mutex callbacks in the underlying SSL + library, so that the same application code can use mutex-locking + independently of OpenSSL or GnutTLS being used. + +13.3 Support in-memory certs/ca certs/keys + + You can specify the private and public keys for SSH/SSL as file paths. Some + programs want to avoid using files and instead just pass them as in-memory + data blobs. There's probably a challenge to make this work across the + plethory of different TLS and SSH backends that curl supports. + https://github.com/curl/curl/issues/2310 + +13.4 Cache/share OpenSSL contexts + + "Look at SSL cafile - quick traces look to me like these are done on every + request as well, when they should only be necessary once per SSL context (or + once per handle)". The major improvement we can rather easily do is to make + sure we don't create and kill a new SSL "context" for every request, but + instead make one for every connection and re-use that SSL context in the same + style connections are re-used. It will make us use slightly more memory but + it will libcurl do less creations and deletions of SSL contexts. + + Technically, the "caching" is probably best implemented by getting added to + the share interface so that easy handles who want to and can reuse the + context specify that by sharing with the right properties set. + + https://github.com/curl/curl/issues/1110 + +13.5 Export session ids + + Add an interface to libcurl that enables "session IDs" to get + exported/imported. Cris Bailiff said: "OpenSSL has functions which can + serialise the current SSL state to a buffer of your choice, and recover/reset + the state from such a buffer at a later date - this is used by mod_ssl for + apache to implement and SSL session ID cache". + +13.6 Provide callback for cert verification + + OpenSSL supports a callback for customised verification of the peer + certificate, but this doesn't seem to be exposed in the libcurl APIs. Could + it be? There's so much that could be done if it were! + +13.7 improve configure --with-ssl + + make the configure --with-ssl option first check for OpenSSL, then GnuTLS, + then NSS... + +13.8 Support DANE + + DNS-Based Authentication of Named Entities (DANE) is a way to provide SSL + keys and certs over DNS using DNSSEC as an alternative to the CA model. + https://www.rfc-editor.org/rfc/rfc6698.txt + + An initial patch was posted by Suresh Krishnaswamy on March 7th 2013 + (https://curl.haxx.se/mail/lib-2013-03/0075.html) but it was a too simple + approach. See Daniel's comments: + https://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the + correct library to base this development on. + + Björn Stenberg wrote a separate initial take on DANE that was never + completed. + +13.9 Configurable loading of OpenSSL configuration file + + libcurl calls the OpenSSL function CONF_modules_load_file() in openssl.c, + Curl_ossl_init(). "We regard any changes in the OpenSSL configuration as a + security risk or at least as unnecessary." + + Please add a configuration switch or something similar to disable the + CONF_modules_load_file() call. + + See https://github.com/curl/curl/issues/2724 + +13.11 Support intermediate & root pinning for PINNEDPUBLICKEY + + CURLOPT_PINNEDPUBLICKEY does not consider the hashes of intermediate & root + certificates when comparing the pinned keys. Therefore it is not compatible + with "HTTP Public Key Pinning" as there also intermediate and root certificates + can be pinned. This is very useful as it prevents webadmins from "locking + themself out of their servers". + + Adding this feature would make curls pinning 100% compatible to HPKP and allow + more flexible pinning. + +13.12 Support HSTS + + "HTTP Strict Transport Security" is TOFU (trust on first use), time-based + features indicated by a HTTP header send by the webserver. It is widely used + in browsers and it's purpose is to prevent insecure HTTP connections after + a previous HTTPS connection. It protects against SSLStripping attacks. + + Doc: https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security + RFC 6797: https://tools.ietf.org/html/rfc6797 + +13.13 Support HPKP + + "HTTP Public Key Pinning" is TOFU (trust on first use), time-based + features indicated by a HTTP header send by the webserver. It's purpose is + to prevent Man-in-the-middle attacks by trusted CAs by allowing webadmins + to specify which CAs/certificates/public keys to trust when connection to + their websites. + + It can be build based on PINNEDPUBLICKEY. + + Wikipedia: https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning + OWASP: https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning + Doc: https://developer.mozilla.org/de/docs/Web/Security/Public_Key_Pinning + RFC: https://tools.ietf.org/html/draft-ietf-websec-key-pinning-21 + +13.14 Support the clienthello extension + + Certain stupid networks and middle boxes have a problem with SSL handshake + pakets that are within a certain size range because how that sets some bits + that previously (in older TLS version) were not set. The clienthello + extension adds padding to avoid that size range. + + https://tools.ietf.org/html/rfc7685 + https://github.com/curl/curl/issues/2299 + +14. GnuTLS + +14.1 SSL engine stuff + + Is this even possible? + +14.2 check connection + + Add a way to check if the connection seems to be alive, to correspond to the + SSL_peak() way we use with OpenSSL. + +15. WinSSL/SChannel + +15.1 Add support for client certificate authentication + + WinSSL/SChannel currently makes use of the OS-level system and user + certificate and private key stores. This does not allow the application + or the user to supply a custom client certificate using curl or libcurl. + + Therefore support for the existing -E/--cert and --key options should be + implemented by supplying a custom certificate to the SChannel APIs, see: + - Getting a Certificate for Schannel + https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx + +15.3 Add support for the --ciphers option + + The cipher suites used by WinSSL/SChannel are configured on an OS-level + instead of an application-level. This does not allow the application or + the user to customize the configured cipher suites using curl or libcurl. + + Therefore support for the existing --ciphers option should be implemented + by mapping the OpenSSL/GnuTLS cipher suites to the SChannel APIs, see + - Specifying Schannel Ciphers and Cipher Strengths + https://msdn.microsoft.com/en-us/library/windows/desktop/aa380161.aspx + +16. SASL + +16.1 Other authentication mechanisms + + Add support for other authentication mechanisms such as OLP, + GSS-SPNEGO and others. + +16.2 Add QOP support to GSSAPI authentication + + Currently the GSSAPI authentication only supports the default QOP of auth + (Authentication), whilst Kerberos V5 supports both auth-int (Authentication + with integrity protection) and auth-conf (Authentication with integrity and + privacy protection). + +16.3 Support binary messages (i.e.: non-base64) + + Mandatory to support LDAP SASL authentication. + + +17. SSH protocols + +17.1 Multiplexing + + SSH is a perfectly fine multiplexed protocols which would allow libcurl to do + multiple parallel transfers from the same host using the same connection, + much in the same spirit as HTTP/2 does. libcurl however does not take + advantage of that ability but will instead always create a new connection for + new transfers even if an existing connection already exists to the host. + + To fix this, libcurl would have to detect an existing connection and "attach" + the new transfer to the existing one. + +17.2 SFTP performance + + libcurl's SFTP transfer performance is sub par and can be improved, mostly by + the approach mentioned in "1.6 Modified buffer size approach". + +17.3 Support better than MD5 hostkey hash + + libcurl offers the CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 option for verifying the + server's key. MD5 is generally being deprecated so we should implement + support for stronger hashing algorithms. libssh2 itself is what provides this + underlying functionality and it supports at least SHA-1 as an alternative. + SHA-1 is also being deprecated these days so we should consider workign with + libssh2 to instead offer support for SHA-256 or similar. + +17.4 Support CURLOPT_PREQUOTE + + The two other QUOTE options are supported for SFTP, but this was left out for + unknown reasons! + +18. Command line tool + +18.1 sync + + "curl --sync http://example.com/feed[1-100].rss" or + "curl --sync http://example.net/{index,calendar,history}.html" + + Downloads a range or set of URLs using the remote name, but only if the + remote file is newer than the local file. A Last-Modified HTTP date header + should also be used to set the mod date on the downloaded file. + +18.2 glob posts + + Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'. + This is easily scripted though. + +18.3 prevent file overwriting + + Add an option that prevents curl from overwriting existing local files. When + used, and there already is an existing file with the target file name + (either -O or -o), a number should be appended (and increased if already + existing). So that index.html becomes first index.html.1 and then + index.html.2 etc. + +18.4 simultaneous parallel transfers + + The client could be told to use maximum N simultaneous parallel transfers and + then just make sure that happens. It should of course not make more than one + connection to the same remote host. This would require the client to use the + multi interface. https://curl.haxx.se/bug/feature.cgi?id=1558595 + + Using the multi interface would also allow properly using parallel transfers + with HTTP/2 and supporting HTTP/2 server push from the command line. + +18.5 UTF-8 filenames in Content-Disposition + + RFC 6266 documents how UTF-8 names can be passed to a client in the + Content-Disposition header, and curl does not support this. + + https://github.com/curl/curl/issues/1888 + +18.6 warning when setting an option + + Display a warning when libcurl returns an error when setting an option. + This can be useful to tell when support for a particular feature hasn't been + compiled into the library. + +18.7 warning if curl version is not in sync with libcurl version + + This is usually a sign of a funny, weird or unexpected install situations + that aren't always quickly nor easily detected by users. curl and libcurl are + always released in sync and should use the same version numbers unless very + special situations. + +18.8 offer color-coded HTTP header output + + By offering different color output on the header name and the header + contents, they could be made more readable and thus help users working on + HTTP services. + +18.9 Choose the name of file in braces for complex URLs + + When using braces to download a list of URLs and you use complicated names + in the list of alternatives, it could be handy to allow curl to use other + names when saving. + + Consider a way to offer that. Possibly like + {partURL1:name1,partURL2:name2,partURL3:name3} where the name following the + colon is the output name. + + See https://github.com/curl/curl/issues/221 + +18.10 improve how curl works in a windows console window + + If you pull the scrollbar when transferring with curl in a Windows console + window, the transfer is interrupted and can get disconnected. This can + probably be improved. See https://github.com/curl/curl/issues/322 + +18.11 -w output to stderr + + -w is quite useful, but not to those of us who use curl without -o or -O + (such as for scripting through a higher level language). It would be nice to + have an option that is exactly like -w but sends it to stderr + instead. Proposed name: --write-stderr. See + https://github.com/curl/curl/issues/613 + +18.12 keep running, read instructions from pipe/socket + + Provide an option that makes curl not exit after the last URL (or even work + without a given URL), and then make it read instructions passed on a pipe or + over a socket to make further instructions so that a second subsequent curl + invoke can talk to the still running instance and ask for transfers to get + done, and thus maintain its connection pool, DNS cache and more. + +18.13 support metalink in http headers + + Curl has support for downloading a metalink xml file, processing it, and then + downloading the target of the metalink. This is done via the --metalink option. + It would be nice if metalink also supported downloading via metalink + information that is stored in HTTP headers (RFC 6249). Theoretically this could + also be supported with the --metalink option. + + See https://tools.ietf.org/html/rfc6249 + + See also https://lists.gnu.org/archive/html/bug-wget/2015-06/msg00034.html for + an implematation of this in wget. + +18.14 --fail without --location should treat 3xx as a failure + + To allow a command line like this to detect a redirect and consider it a + failure: + + curl -v --fail -O https://example.com/curl-7.48.0.tar.gz + + ... --fail must treat 3xx responses as failures too. The least problematic + way to implement this is probably to add that new logic in the command line + tool only and not in the underlying CURLOPT_FAILONERROR logic. + +18.15 --retry should resume + + When --retry is used and curl actually retries transfer, it should use the + already transferred data and do a resumed transfer for the rest (when + possible) so that it doesn't have to transfer the same data again that was + already transferred before the retry. + + See https://github.com/curl/curl/issues/1084 + +18.16 send only part of --data + + When the user only wants to send a small piece of the data provided with + --data or --data-binary, like when that data is a huge file, consider a way + to specify that curl should only send a piece of that. One suggested syntax + would be: "--data-binary @largefile.zip!1073741823-2147483647". + + See https://github.com/curl/curl/issues/1200 + +18.17 consider file name from the redirected URL with -O ? + + When a user gives a URL and uses -O, and curl follows a redirect to a new + URL, the file name is not extracted and used from the newly redirected-to URL + even if the new URL may have a much more sensible file name. + + This is clearly documented and helps for security since there's no surprise + to users which file name that might get overwritten. But maybe a new option + could allow for this or maybe -J should imply such a treatment as well as -J + already allows for the server to decide what file name to use so it already + provides the "may overwrite any file" risk. + + This is extra tricky if the original URL has no file name part at all since + then the current code path will error out with an error message, and we can't + *know* already at that point if curl will be redirected to a URL that has a + file name... + + See https://github.com/curl/curl/issues/1241 + +18.18 retry on network is unreachable + + The --retry option retries transfers on "transient failures". We later added + --retry-connrefused to also retry for "connection refused" errors. + + Suggestions have been brought to also allow retry on "network is unreachable" + errors and while totally reasonable, maybe we should consider a way to make + this more configurable than to add a new option for every new error people + want to retry for? + + https://github.com/curl/curl/issues/1603 + +18.19 expand ~/ in config files + + For example .curlrc could benefit from being able to do this. + + See https://github.com/curl/curl/issues/2317 + + +19. Build + +19.1 roffit + + Consider extending 'roffit' to produce decent ASCII output, and use that + instead of (g)nroff when building src/tool_hugehelp.c + +19.2 Enable PIE and RELRO by default + + Especially when having programs that execute curl via the command line, PIE + renders the exploitation of memory corruption vulnerabilities a lot more + difficult. This can be attributed to the additional information leaks being + required to conduct a successful attack. RELRO, on the other hand, masks + different binary sections like the GOT as read-only and thus kills a handful + of techniques that come in handy when attackers are able to arbitrarily + overwrite memory. A few tests showed that enabling these features had close + to no impact, neither on the performance nor on the general functionality of + curl. + + +20. Test suite + +20.1 SSL tunnel + + Make our own version of stunnel for simple port forwarding to enable HTTPS + and FTP-SSL tests without the stunnel dependency, and it could allow us to + provide test tools built with either OpenSSL or GnuTLS + +20.2 nicer lacking perl message + + If perl wasn't found by the configure script, don't attempt to run the tests + but explain something nice why it doesn't. + +20.3 more protocols supported + + Extend the test suite to include more protocols. The telnet could just do FTP + or http operations (for which we have test servers). + +20.4 more platforms supported + + Make the test suite work on more platforms. OpenBSD and Mac OS. Remove + fork()s and it should become even more portable. + +20.5 Add support for concurrent connections + + Tests 836, 882 and 938 were designed to verify that separate connections aren't + used when using different login credentials in protocols that shouldn't re-use + a connection under such circumstances. + + Unfortunately, ftpserver.pl doesn't appear to support multiple concurrent + connections. The read while() loop seems to loop until it receives a disconnect + from the client, where it then enters the waiting for connections loop. When + the client opens a second connection to the server, the first connection hasn't + been dropped (unless it has been forced - which we shouldn't do in these tests) + and thus the wait for connections loop is never entered to receive the second + connection. + +20.6 Use the RFC6265 test suite + + A test suite made for HTTP cookies (RFC 6265) by Adam Barth is available at + https://github.com/abarth/http-state/tree/master/tests + + It'd be really awesome if someone would write a script/setup that would run + curl with that test suite and detect deviances. Ideally, that would even be + incorporated into our regular test suite. + + +21. Next SONAME bump + +21.1 http-style HEAD output for FTP + + #undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers + from being output in NOBODY requests over FTP + +21.2 combine error codes + + Combine some of the error codes to remove duplicates. The original + numbering should not be changed, and the old identifiers would be + macroed to the new ones in an CURL_NO_OLDIES section to help with + backward compatibility. + + Candidates for removal and their replacements: + + CURLE_FILE_COULDNT_READ_FILE => CURLE_REMOTE_FILE_NOT_FOUND + + CURLE_FTP_COULDNT_RETR_FILE => CURLE_REMOTE_FILE_NOT_FOUND + + CURLE_FTP_COULDNT_USE_REST => CURLE_RANGE_ERROR + + CURLE_FUNCTION_NOT_FOUND => CURLE_FAILED_INIT + + CURLE_LDAP_INVALID_URL => CURLE_URL_MALFORMAT + + CURLE_TFTP_NOSUCHUSER => CURLE_TFTP_ILLEGAL + + CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND + + CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED + +21.3 extend CURLOPT_SOCKOPTFUNCTION prototype + + The current prototype only provides 'purpose' that tells what the + connection/socket is for, but not any protocol or similar. It makes it hard + for applications to differentiate on TCP vs UDP and even HTTP vs FTP and + similar. + +22. Next major release + +22.1 cleanup return codes + + curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a + CURLMcode. These should be changed to be the same. + +22.2 remove obsolete defines + + remove obsolete defines from curl/curl.h + +22.3 size_t + + make several functions use size_t instead of int in their APIs + +22.4 remove several functions + + remove the following functions from the public API: + + curl_getenv + + curl_mprintf (and variations) + + curl_strequal + + curl_strnequal + + They will instead become curlx_ - alternatives. That makes the curl app + still capable of using them, by building with them from source. + + These functions have no purpose anymore: + + curl_multi_socket + + curl_multi_socket_all + +22.5 remove CURLOPT_FAILONERROR + + Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird + internally. Let the app judge success or not for itself. + +22.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE + + Remove support for a global DNS cache. Anything global is silly, and we + already offer the share interface for the same functionality but done + "right". + +22.7 remove progress meter from libcurl + + The internally provided progress meter output doesn't belong in the library. + Basically no application wants it (apart from curl) but instead applications + can and should do their own progress meters using the progress callback. + + The progress callback should then be bumped as well to get proper 64bit + variable types passed to it instead of doubles so that big files work + correctly. + +22.8 remove 'curl_httppost' from public + + curl_formadd() was made to fill in a public struct, but the fact that the + struct is public is never really used by application for their own advantage + but instead often restricts how the form functions can or can't be modified. + + Changing them to return a private handle will benefit the implementation and + allow us much greater freedoms while still maintaining a solid API and ABI. diff --git a/docs/TheArtOfHttpScripting b/docs/TheArtOfHttpScripting new file mode 100644 index 00000000..b2bd9db7 --- /dev/null +++ b/docs/TheArtOfHttpScripting @@ -0,0 +1,758 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + + +The Art Of Scripting HTTP Requests Using Curl + + 1. HTTP Scripting + 1.1 Background + 1.2 The HTTP Protocol + 1.3 See the Protocol + 1.4 See the Timing + 1.5 See the Response + 2. URL + 2.1 Spec + 2.2 Host + 2.3 Port number + 2.4 User name and password + 2.5 Path part + 3. Fetch a page + 3.1 GET + 3.2 HEAD + 3.3 Multiple URLs in a single command line + 3.4 Multiple HTTP methods in a single command line + 4. HTML forms + 4.1 Forms explained + 4.2 GET + 4.3 POST + 4.4 File Upload POST + 4.5 Hidden Fields + 4.6 Figure Out What A POST Looks Like + 5. HTTP upload + 5.1 PUT + 6. HTTP Authentication + 6.1 Basic Authentication + 6.2 Other Authentication + 6.3 Proxy Authentication + 6.4 Hiding credentials + 7. More HTTP Headers + 7.1 Referer + 7.2 User Agent + 8. Redirects + 8.1 Location header + 8.2 Other redirects + 9. Cookies + 9.1 Cookie Basics + 9.2 Cookie options + 10. HTTPS + 10.1 HTTPS is HTTP secure + 10.2 Certificates + 11. Custom Request Elements + 11.1 Modify method and headers + 11.2 More on changed methods + 12. Web Login + 12.1 Some login tricks + 13. Debug + 13.1 Some debug tricks + 14. References + 14.1 Standards + 14.2 Sites + +============================================================================== + +1. HTTP Scripting + + 1.1 Background + + This document assumes that you're familiar with HTML and general networking. + + The increasing amount of applications moving to the web has made "HTTP + Scripting" more frequently requested and wanted. To be able to automatically + extract information from the web, to fake users, to post or upload data to + web servers are all important tasks today. + + Curl is a command line tool for doing all sorts of URL manipulations and + transfers, but this particular document will focus on how to use it when + doing HTTP requests for fun and profit. I'll assume that you know how to + invoke 'curl --help' or 'curl --manual' to get basic information about it. + + Curl is not written to do everything for you. It makes the requests, it gets + the data, it sends data and it retrieves the information. You probably need + to glue everything together using some kind of script language or repeated + manual invokes. + + 1.2 The HTTP Protocol + + HTTP is the protocol used to fetch data from web servers. It is a very simple + protocol that is built upon TCP/IP. The protocol also allows information to + get sent to the server from the client using a few different methods, as will + be shown here. + + HTTP is plain ASCII text lines being sent by the client to a server to + request a particular action, and then the server replies a few text lines + before the actual requested content is sent to the client. + + The client, curl, sends a HTTP request. The request contains a method (like + GET, POST, HEAD etc), a number of request headers and sometimes a request + body. The HTTP server responds with a status line (indicating if things went + well), response headers and most often also a response body. The "body" part + is the plain data you requested, like the actual HTML or the image etc. + + 1.3 See the Protocol + + Using curl's option --verbose (-v as a short option) will display what kind + of commands curl sends to the server, as well as a few other informational + texts. + + --verbose is the single most useful option when it comes to debug or even + understand the curl<->server interaction. + + Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer + even more details as they show EVERYTHING curl sends and receives. Use it + like this: + + curl --trace-ascii debugdump.txt http://www.example.com/ + + 1.4 See the Timing + + Many times you may wonder what exactly is taking all the time, or you just + want to know the amount of milliseconds between two points in a + transfer. For those, and other similar situations, the --trace-time option + is what you need. It'll prepend the time to each trace output line: + + curl --trace-ascii d.txt --trace-time http://example.com/ + + 1.5 See the Response + + By default curl sends the response to stdout. You need to redirect it + somewhere to avoid that, most often that is done with -o or -O. + +2. URL + + 2.1 Spec + + The Uniform Resource Locator format is how you specify the address of a + particular resource on the Internet. You know these, you've seen URLs like + https://curl.haxx.se or https://yourbank.com a million times. RFC 3986 is the + canonical spec. And yeah, the formal name is not URL, it is URI. + + 2.2 Host + + The host name is usually resolved using DNS or your /etc/hosts file to an IP + address and that's what curl will communicate with. Alternatively you specify + the IP address directly in the URL instead of a name. + + For development and other trying out situations, you can point to a different + IP address for a host name than what would otherwise be used, by using curl's + --resolve option: + + curl --resolve www.example.org:80:127.0.0.1 http://www.example.org/ + + 2.3 Port number + + Each protocol curl supports operates on a default port number, be it over TCP + or in some cases UDP. Normally you don't have to take that into + consideration, but at times you run test servers on other ports or + similar. Then you can specify the port number in the URL with a colon and a + number immediately following the host name. Like when doing HTTP to port + 1234: + + curl http://www.example.org:1234/ + + The port number you specify in the URL is the number that the server uses to + offer its services. Sometimes you may use a local proxy, and then you may + need to specify that proxy's port number separately for what curl needs to + connect to locally. Like when using a HTTP proxy on port 4321: + + curl --proxy http://proxy.example.org:4321 http://remote.example.org/ + + 2.4 User name and password + + Some services are setup to require HTTP authentication and then you need to + provide name and password which is then transferred to the remote site in + various ways depending on the exact authentication protocol used. + + You can opt to either insert the user and password in the URL or you can + provide them separately: + + curl http://user:password@example.org/ + + or + + curl -u user:password http://example.org/ + + You need to pay attention that this kind of HTTP authentication is not what + is usually done and requested by user-oriented web sites these days. They + tend to use forms and cookies instead. + + 2.5 Path part + + The path part is just sent off to the server to request that it sends back + the associated response. The path is what is to the right side of the slash + that follows the host name and possibly port number. + +3. Fetch a page + + 3.1 GET + + The simplest and most common request/operation made using HTTP is to GET a + URL. The URL could itself refer to a web page, an image or a file. The client + issues a GET request to the server and receives the document it asked for. + If you issue the command line + + curl https://curl.haxx.se + + you get a web page returned in your terminal window. The entire HTML document + that that URL holds. + + All HTTP replies contain a set of response headers that are normally hidden, + use curl's --include (-i) option to display them as well as the rest of the + document. + + 3.2 HEAD + + You can ask the remote server for ONLY the headers by using the --head (-I) + option which will make curl issue a HEAD request. In some special cases + servers deny the HEAD method while others still work, which is a particular + kind of annoyance. + + The HEAD method is defined and made so that the server returns the headers + exactly the way it would do for a GET, but without a body. It means that you + may see a Content-Length: in the response headers, but there must not be an + actual body in the HEAD response. + + 3.3 Multiple URLs in a single command line + + A single curl command line may involve one or many URLs. The most common case + is probably to just use one, but you can specify any amount of URLs. Yes + any. No limits. You'll then get requests repeated over and over for all the + given URLs. + + Example, send two GETs: + + curl http://url1.example.com http://url2.example.com + + If you use --data to POST to the URL, using multiple URLs means that you send + that same POST to all the given URLs. + + Example, send two POSTs: + + curl --data name=curl http://url1.example.com http://url2.example.com + + + 3.4 Multiple HTTP methods in a single command line + + Sometimes you need to operate on several URLs in a single command line and do + different HTTP methods on each. For this, you'll enjoy the --next option. It + is basically a separator that separates a bunch of options from the next. All + the URLs before --next will get the same method and will get all the POST + data merged into one. + + When curl reaches the --next on the command line, it'll sort of reset the + method and the POST data and allow a new set. + + Perhaps this is best shown with a few examples. To send first a HEAD and then + a GET: + + curl -I http://example.com --next http://example.com + + To first send a POST and then a GET: + + curl -d score=10 http://example.com/post.cgi --next http://example.com/results.html + + +4. HTML forms + + 4.1 Forms explained + + Forms are the general way a web site can present a HTML page with fields for + the user to enter data in, and then press some kind of 'OK' or 'Submit' + button to get that data sent to the server. The server then typically uses + the posted data to decide how to act. Like using the entered words to search + in a database, or to add the info in a bug tracking system, display the entered + address on a map or using the info as a login-prompt verifying that the user + is allowed to see what it is about to see. + + Of course there has to be some kind of program on the server end to receive + the data you send. You cannot just invent something out of the air. + + 4.2 GET + + A GET-form uses the method GET, as specified in HTML like: + +
+ + +
+ + In your favorite browser, this form will appear with a text box to fill in + and a press-button labeled "OK". If you fill in '1905' and press the OK + button, your browser will then create a new URL to get for you. The URL will + get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the + previous URL. + + If the original form was seen on the page "www.hotmail.com/when/birth.html", + the second page you'll get will become + "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK". + + Most search engines work this way. + + To make curl do the GET form post for you, just enter the expected created + URL: + + curl "http://www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK" + + 4.3 POST + + The GET method makes all input field names get displayed in the URL field of + your browser. That's generally a good thing when you want to be able to + bookmark that page with your given data, but it is an obvious disadvantage + if you entered secret information in one of the fields or if there are a + large amount of fields creating a very long and unreadable URL. + + The HTTP protocol then offers the POST method. This way the client sends the + data separated from the URL and thus you won't see any of it in the URL + address field. + + The form would look very similar to the previous one: + +
+ + +
+ + And to use curl to post this form with the same data filled in as before, we + could do it like: + + curl --data "birthyear=1905&press=%20OK%20" \ + http://www.example.com/when.cgi + + This kind of POST will use the Content-Type + application/x-www-form-urlencoded and is the most widely used POST kind. + + The data you send to the server MUST already be properly encoded, curl will + not do that for you. For example, if you want the data to contain a space, + you need to replace that space with %20 etc. Failing to comply with this + will most likely cause your data to be received wrongly and messed up. + + Recent curl versions can in fact url-encode POST data for you, like this: + + curl --data-urlencode "name=I am Daniel" http://www.example.com + + If you repeat --data several times on the command line, curl will + concatenate all the given data pieces - and put a '&' symbol between each + data segment. + + 4.4 File Upload POST + + Back in late 1995 they defined an additional way to post data over HTTP. It + is documented in the RFC 1867, why this method sometimes is referred to as + RFC1867-posting. + + This method is mainly designed to better support file uploads. A form that + allows a user to upload a file could be written like this in HTML: + +
+ + +
+ + This clearly shows that the Content-Type about to be sent is + multipart/form-data. + + To post to a form like this with curl, you enter a command line like: + + curl --form upload=@localfilename --form press=OK [URL] + + 4.5 Hidden Fields + + A very common way for HTML based applications to pass state information + between pages is to add hidden fields to the forms. Hidden fields are + already filled in, they aren't displayed to the user and they get passed + along just as all the other fields. + + A similar example form with one visible field, one hidden field and one + submit button could look like: + +
+ + + +
+ + To POST this with curl, you won't have to think about if the fields are + hidden or not. To curl they're all the same: + + curl --data "birthyear=1905&press=OK&person=daniel" [URL] + + 4.6 Figure Out What A POST Looks Like + + When you're about fill in a form and send to a server by using curl instead + of a browser, you're of course very interested in sending a POST exactly the + way your browser does. + + An easy way to get to see this, is to save the HTML page with the form on + your local disk, modify the 'method' to a GET, and press the submit button + (you could also change the action URL if you want to). + + You will then clearly see the data get appended to the URL, separated with a + '?'-letter as GET forms are supposed to. + +5. HTTP upload + + 5.1 PUT + + Perhaps the best way to upload data to a HTTP server is to use PUT. Then + again, this of course requires that someone put a program or script on the + server end that knows how to receive a HTTP PUT stream. + + Put a file to a HTTP server with curl: + + curl --upload-file uploadfile http://www.example.com/receive.cgi + +6. HTTP Authentication + + 6.1 Basic Authentication + + HTTP Authentication is the ability to tell the server your username and + password so that it can verify that you're allowed to do the request you're + doing. The Basic authentication used in HTTP (which is the type curl uses by + default) is *plain* *text* based, which means it sends username and password + only slightly obfuscated, but still fully readable by anyone that sniffs on + the network between you and the remote server. + + To tell curl to use a user and password for authentication: + + curl --user name:password http://www.example.com + + 6.2 Other Authentication + + The site might require a different authentication method (check the headers + returned by the server), and then --ntlm, --digest, --negotiate or even + --anyauth might be options that suit you. + + 6.3 Proxy Authentication + + Sometimes your HTTP access is only available through the use of a HTTP + proxy. This seems to be especially common at various companies. A HTTP proxy + may require its own user and password to allow the client to get through to + the Internet. To specify those with curl, run something like: + + curl --proxy-user proxyuser:proxypassword curl.haxx.se + + If your proxy requires the authentication to be done using the NTLM method, + use --proxy-ntlm, if it requires Digest use --proxy-digest. + + If you use any one of these user+password options but leave out the password + part, curl will prompt for the password interactively. + + 6.4 Hiding credentials + + Do note that when a program is run, its parameters might be possible to see + when listing the running processes of the system. Thus, other users may be + able to watch your passwords if you pass them as plain command line + options. There are ways to circumvent this. + + It is worth noting that while this is how HTTP Authentication works, very + many web sites will not use this concept when they provide logins etc. See + the Web Login chapter further below for more details on that. + +7. More HTTP Headers + + 7.1 Referer + + A HTTP request may include a 'referer' field (yes it is misspelled), which + can be used to tell from which URL the client got to this particular + resource. Some programs/scripts check the referer field of requests to verify + that this wasn't arriving from an external site or an unknown page. While + this is a stupid way to check something so easily forged, many scripts still + do it. Using curl, you can put anything you want in the referer-field and + thus more easily be able to fool the server into serving your request. + + Use curl to set the referer field with: + + curl --referer http://www.example.come http://www.example.com + + 7.2 User Agent + + Very similar to the referer field, all HTTP requests may set the User-Agent + field. It names what user agent (client) that is being used. Many + applications use this information to decide how to display pages. Silly web + programmers try to make different pages for users of different browsers to + make them look the best possible for their particular browsers. They usually + also do different kinds of javascript, vbscript etc. + + At times, you will see that getting a page with curl will not return the same + page that you see when getting the page with your browser. Then you know it + is time to set the User Agent field to fool the server into thinking you're + one of those browsers. + + To make curl look like Internet Explorer 5 on a Windows 2000 box: + + curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL] + + Or why not look like you're using Netscape 4.73 on an old Linux box: + + curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL] + +8. Redirects + + 8.1 Location header + + When a resource is requested from a server, the reply from the server may + include a hint about where the browser should go next to find this page, or a + new page keeping newly generated output. The header that tells the browser + to redirect is Location:. + + Curl does not follow Location: headers by default, but will simply display + such pages in the same manner it displays all HTTP replies. It does however + feature an option that will make it attempt to follow the Location: pointers. + + To tell curl to follow a Location: + + curl --location http://www.example.com + + If you use curl to POST to a site that immediately redirects you to another + page, you can safely use --location (-L) and --data/--form together. Curl will + only use POST in the first request, and then revert to GET in the following + operations. + + 8.2 Other redirects + + Browser typically support at least two other ways of redirects that curl + doesn't: first the html may contain a meta refresh tag that asks the browser + to load a specific URL after a set number of seconds, or it may use + javascript to do it. + +9. Cookies + + 9.1 Cookie Basics + + The way the web browsers do "client side state control" is by using + cookies. Cookies are just names with associated contents. The cookies are + sent to the client by the server. The server tells the client for what path + and host name it wants the cookie sent back, and it also sends an expiration + date and a few more properties. + + When a client communicates with a server with a name and path as previously + specified in a received cookie, the client sends back the cookies and their + contents to the server, unless of course they are expired. + + Many applications and servers use this method to connect a series of requests + into a single logical session. To be able to use curl in such occasions, we + must be able to record and send back cookies the way the web application + expects them. The same way browsers deal with them. + + 9.2 Cookie options + + The simplest way to send a few cookies to the server when getting a page with + curl is to add them on the command line like: + + curl --cookie "name=Daniel" http://www.example.com + + Cookies are sent as common HTTP headers. This is practical as it allows curl + to record cookies simply by recording headers. Record cookies with curl by + using the --dump-header (-D) option like: + + curl --dump-header headers_and_cookies http://www.example.com + + (Take note that the --cookie-jar option described below is a better way to + store cookies.) + + Curl has a full blown cookie parsing engine built-in that comes in use if you + want to reconnect to a server and use cookies that were stored from a + previous connection (or hand-crafted manually to fool the server into + believing you had a previous connection). To use previously stored cookies, + you run curl like: + + curl --cookie stored_cookies_in_file http://www.example.com + + Curl's "cookie engine" gets enabled when you use the --cookie option. If you + only want curl to understand received cookies, use --cookie with a file that + doesn't exist. Example, if you want to let curl understand cookies from a + page and follow a location (and thus possibly send back cookies it received), + you can invoke it like: + + curl --cookie nada --location http://www.example.com + + Curl has the ability to read and write cookie files that use the same file + format that Netscape and Mozilla once used. It is a convenient way to share + cookies between scripts or invokes. The --cookie (-b) switch automatically + detects if a given file is such a cookie file and parses it, and by using the + --cookie-jar (-c) option you'll make curl write a new cookie file at the end + of an operation: + + curl --cookie cookies.txt --cookie-jar newcookies.txt \ + http://www.example.com + +10. HTTPS + + 10.1 HTTPS is HTTP secure + + There are a few ways to do secure HTTP transfers. By far the most common + protocol for doing this is what is generally known as HTTPS, HTTP over + SSL. SSL encrypts all the data that is sent and received over the network and + thus makes it harder for attackers to spy on sensitive information. + + SSL (or TLS as the latest version of the standard is called) offers a + truckload of advanced features to allow all those encryptions and key + infrastructure mechanisms encrypted HTTP requires. + + Curl supports encrypted fetches when built to use a TLS library and it can be + built to use one out of a fairly large set of libraries - "curl -V" will show + which one your curl was built to use (if any!). To get a page from a HTTPS + server, simply run curl like: + + curl https://secure.example.com + + 10.2 Certificates + + In the HTTPS world, you use certificates to validate that you are the one + you claim to be, as an addition to normal passwords. Curl supports client- + side certificates. All certificates are locked with a pass phrase, which you + need to enter before the certificate can be used by curl. The pass phrase + can be specified on the command line or if not, entered interactively when + curl queries for it. Use a certificate with curl on a HTTPS server like: + + curl --cert mycert.pem https://secure.example.com + + curl also tries to verify that the server is who it claims to be, by + verifying the server's certificate against a locally stored CA cert + bundle. Failing the verification will cause curl to deny the connection. You + must then use --insecure (-k) in case you want to tell curl to ignore that + the server can't be verified. + + More about server certificate verification and ca cert bundles can be read + in the SSLCERTS document, available online here: + + https://curl.haxx.se/docs/sslcerts.html + + At times you may end up with your own CA cert store and then you can tell + curl to use that to verify the server's certificate: + + curl --cacert ca-bundle.pem https://example.com/ + + +11. Custom Request Elements + +11.1 Modify method and headers + + Doing fancy stuff, you may need to add or change elements of a single curl + request. + + For example, you can change the POST request to a PROPFIND and send the data + as "Content-Type: text/xml" (instead of the default Content-Type) like this: + + curl --data "" --header "Content-Type: text/xml" \ + --request PROPFIND url.com + + You can delete a default header by providing one without content. Like you + can ruin the request by chopping off the Host: header: + + curl --header "Host:" http://www.example.com + + You can add headers the same way. Your server may want a "Destination:" + header, and you can add it: + + curl --header "Destination: http://nowhere" http://example.com + + 11.2 More on changed methods + + It should be noted that curl selects which methods to use on its own + depending on what action to ask for. -d will do POST, -I will do HEAD and so + on. If you use the --request / -X option you can change the method keyword + curl selects, but you will not modify curl's behavior. This means that if you + for example use -d "data" to do a POST, you can modify the method to a + PROPFIND with -X and curl will still think it sends a POST. You can change + the normal GET to a POST method by simply adding -X POST in a command line + like: + + curl -X POST http://example.org/ + + ... but curl will still think and act as if it sent a GET so it won't send any + request body etc. + + +12. Web Login + + 12.1 Some login tricks + + While not strictly just HTTP related, it still causes a lot of people problems + so here's the executive run-down of how the vast majority of all login forms + work and how to login to them using curl. + + It can also be noted that to do this properly in an automated fashion, you + will most certainly need to script things and do multiple curl invokes etc. + + First, servers mostly use cookies to track the logged-in status of the + client, so you will need to capture the cookies you receive in the + responses. Then, many sites also set a special cookie on the login page (to + make sure you got there through their login page) so you should make a habit + of first getting the login-form page to capture the cookies set there. + + Some web-based login systems feature various amounts of javascript, and + sometimes they use such code to set or modify cookie contents. Possibly they + do that to prevent programmed logins, like this manual describes how to... + Anyway, if reading the code isn't enough to let you repeat the behavior + manually, capturing the HTTP requests done by your browsers and analyzing the + sent cookies is usually a working method to work out how to shortcut the + javascript need. + + In the actual
tag for the login, lots of sites fill-in random/session + or otherwise secretly generated hidden tags and you may need to first capture + the HTML code for the login form and extract all the hidden fields to be able + to do a proper login POST. Remember that the contents need to be URL encoded + when sent in a normal POST. + +13. Debug + + 13.1 Some debug tricks + + Many times when you run curl on a site, you'll notice that the site doesn't + seem to respond the same way to your curl requests as it does to your + browser's. + + Then you need to start making your curl requests more similar to your + browser's requests: + + * Use the --trace-ascii option to store fully detailed logs of the requests + for easier analyzing and better understanding + + * Make sure you check for and use cookies when needed (both reading with + --cookie and writing with --cookie-jar) + + * Set user-agent to one like a recent popular browser does + + * Set referer like it is set by the browser + + * If you use POST, make sure you send all the fields and in the same order as + the browser does it. + + A very good helper to make sure you do this right, is the LiveHTTPHeader tool + that lets you view all headers you send and receive with Mozilla/Firefox + (even when using HTTPS). Chrome features similar functionality out of the box + among the developer's tools. + + A more raw approach is to capture the HTTP traffic on the network with tools + such as ethereal or tcpdump and check what headers that were sent and + received by the browser. (HTTPS makes this technique inefficient.) + +14. References + + 14.1 Standards + + RFC 7230 is a must to read if you want in-depth understanding of the HTTP + protocol + + RFC 3986 explains the URL syntax + + RFC 1867 defines the HTTP post upload format + + RFC 6525 defines how HTTP cookies work + + 14.2 Sites + + https://curl.haxx.se is the home of the curl project diff --git a/docs/VERSIONS b/docs/VERSIONS new file mode 100644 index 00000000..72a45474 --- /dev/null +++ b/docs/VERSIONS @@ -0,0 +1,56 @@ +Version Numbers and Releases +============================ + + Curl is not only curl. Curl is also libcurl. They're actually individually + versioned, but they mostly follow each other rather closely. + + The version numbering is always built up using the same system: + + X.Y.Z + + - X is main version number + - Y is release number + - Z is patch number + +## Bumping numbers + + One of these numbers will get bumped in each new release. The numbers to the + right of a bumped number will be reset to zero. If Z is zero, it may not be + included in the version number. + + The main version number will get bumped when *really* big, world colliding + changes are made. The release number is bumped when changes are performed or + things/features are added. The patch number is bumped when the changes are + mere bugfixes. + + It means that after release 1.2.3, we can release 2.0 if something really big + has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs + were fixed. + + Bumping, as in increasing the number with 1, is unconditionally only + affecting one of the numbers (except the ones to the right of it, that may be + set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99 + becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come. + + All original curl source release archives are named according to the libcurl + version (not according to the curl client version that, as said before, might + differ). + + As a service to any application that might want to support new libcurl + features while still being able to build with older versions, all releases + have the libcurl version stored in the curl/curlver.h file using a static + numbering scheme that can be used for comparison. The version number is + defined as: + + #define LIBCURL_VERSION_NUM 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal. All three number fields are always represented using two digits + (eight bits each). 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit hexadecimal number is always a greater number in a more recent + release. It makes comparisons with greater than and less than work. + + This number is also available as three separate defines: + `LIBCURL_VERSION_MAJOR`, `LIBCURL_VERSION_MINOR` and `LIBCURL_VERSION_PATCH`. diff --git a/docs/cmdline-opts/CMakeLists.txt b/docs/cmdline-opts/CMakeLists.txt new file mode 100644 index 00000000..5aa20dfd --- /dev/null +++ b/docs/cmdline-opts/CMakeLists.txt @@ -0,0 +1,12 @@ +set(MANPAGE "${CMAKE_BINARY_DIR}/docs/curl.1") + +# Load DPAGES and OTHERPAGES from shared file +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + +add_custom_command(OUTPUT "${MANPAGE}" + COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/gen.pl" mainpage "${CMAKE_CURRENT_SOURCE_DIR}" > "${MANPAGE}" + DEPENDS ${DPAGES} ${OTHERPAGES} + VERBATIM +) +add_custom_target(generate-curl.1 DEPENDS "${MANPAGE}") diff --git a/docs/cmdline-opts/MANPAGE.md b/docs/cmdline-opts/MANPAGE.md new file mode 100644 index 00000000..3a8270b0 --- /dev/null +++ b/docs/cmdline-opts/MANPAGE.md @@ -0,0 +1,52 @@ +# curl man page generator + +This is the curl man page generator. It generates a single nroff man page +output from the set of sources files in this directory. + +There is one source file for each supported command line option. The format is +described below. + +## Option files + +Each command line option is described in a file named `.d`, where +option name is written without any prefixing dashes. Like the file name for +the -v, --verbose option is named `verbose.d`. + +Each file has a set of meta-data and a body of text. + +### Meta-data + + Short: (single letter, without dash) + Long: (long form name, without dashes) + Arg: (the argument the option takes) + Magic: (description of "magic" options) + Tags: (space separated list) + Protocols: (space separated list for which protocols this option works) + Added: (version number in which this was added) + Mutexed: (space separated list of options this overrides, no dashes) + Requires: (space separated list of features this requires, no dashes) + See-also: (space separated list of related options, no dashes) + Help: (short text for the --help output for this option) + --- (end of meta-data) + +### Body + +The body of the description. Only refer to options with their long form option +version, like --verbose. The output generator will replace such with the +correct markup that shows both short and long version. + +## Header + +`page-header` is the nroff formatted file that will be output before the +generated options output for the master man page. + +## Generate + +`./gen.pl mainpage` + +This command outputs a single huge nroff file, meant to become `curl.1`. The +full curl man page. + +`./gen.pl listhelp` + +Generates a full `curl --help` output for all known command line options. diff --git a/docs/cmdline-opts/Makefile.am b/docs/cmdline-opts/Makefile.am new file mode 100644 index 00000000..e6ecf7a6 --- /dev/null +++ b/docs/cmdline-opts/Makefile.am @@ -0,0 +1,34 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +AUTOMAKE_OPTIONS = foreign no-dependencies + +MANPAGE = $(top_builddir)/docs/curl.1 + +include Makefile.inc + +EXTRA_DIST = $(DPAGES) MANPAGE.md gen.pl $(OTHERPAGES) CMakeLists.txt + +all: $(MANPAGE) + +$(MANPAGE): $(DPAGES) $(OTHERPAGES) Makefile.inc + @PERL@ $(srcdir)/gen.pl mainpage $(srcdir) > $(MANPAGE) diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc new file mode 100644 index 00000000..67fe1a04 --- /dev/null +++ b/docs/cmdline-opts/Makefile.inc @@ -0,0 +1,52 @@ +# Shared between Makefile.am and CMakeLists.txt + +DPAGES = abstract-unix-socket.d anyauth.d append.d basic.d cacert.d capath.d cert.d \ + cert-status.d cert-type.d ciphers.d compressed.d compressed-ssh.d \ + config.d \ + connect-timeout.d connect-to.d continue-at.d cookie.d cookie-jar.d \ + create-dirs.d crlf.d crlfile.d data-ascii.d data-binary.d data.d \ + data-raw.d data-urlencode.d delegation.d digest.d disable.d \ + disable-eprt.d disable-epsv.d dns-interface.d dns-ipv4-addr.d \ + dns-ipv6-addr.d dns-servers.d dump-header.d egd-file.d engine.d \ + expect100-timeout.d fail.d fail-early.d false-start.d \ + form.d form-string.d ftp-account.d ftp-alternative-to-user.d \ + ftp-create-dirs.d ftp-method.d ftp-pasv.d ftp-port.d ftp-pret.d \ + ftp-skip-pasv-ip.d ftp-ssl-ccc.d ftp-ssl-ccc-mode.d ftp-ssl-control.d \ + get.d globoff.d \ + happy-eyeballs-timeout-ms.d \ + head.d header.d help.d hostpubmd5.d http1.0.d \ + http1.1.d http2.d http2-prior-knowledge.d ignore-content-length.d \ + include.d insecure.d interface.d ipv4.d ipv6.d junk-session-cookies.d \ + keepalive-time.d key.d key-type.d krb.d libcurl.d limit-rate.d \ + list-only.d local-port.d location.d location-trusted.d \ + login-options.d mail-auth.d mail-from.d mail-rcpt.d manual.d \ + max-filesize.d max-redirs.d max-time.d metalink.d negotiate.d netrc.d \ + netrc-file.d netrc-optional.d next.d no-alpn.d no-buffer.d \ + no-keepalive.d no-npn.d noproxy.d no-sessionid.d ntlm.d ntlm-wb.d \ + oauth2-bearer.d output.d pass.d path-as-is.d pinnedpubkey.d post301.d \ + post302.d post303.d preproxy.d progress-bar.d proto.d proto-default.d \ + proto-redir.d proxy1.0.d proxy-anyauth.d proxy-basic.d proxy-cacert.d \ + proxy-capath.d proxy-cert.d proxy-cert-type.d proxy-ciphers.d \ + proxy-crlfile.d proxy.d proxy-digest.d proxy-header.d \ + proxy-insecure.d proxy-key.d proxy-key-type.d proxy-negotiate.d \ + proxy-ntlm.d proxy-pass.d proxy-service-name.d \ + proxy-ssl-allow-beast.d proxy-tlsauthtype.d proxy-tlspassword.d \ + proxy-tlsuser.d proxy-tlsv1.d proxytunnel.d proxy-user.d pubkey.d \ + quote.d random-file.d range.d raw.d referer.d remote-header-name.d \ + remote-name-all.d remote-name.d remote-time.d request.d resolve.d \ + retry-connrefused.d retry.d retry-delay.d retry-max-time.d sasl-ir.d \ + service-name.d show-error.d silent.d socks4a.d socks4.d socks5.d \ + socks5-basic.d socks5-gssapi.d proxy-pinnedpubkey.d \ + socks5-gssapi-nec.d socks5-gssapi-service.d socks5-hostname.d \ + speed-limit.d speed-time.d ssl-allow-beast.d ssl.d ssl-no-revoke.d \ + ssl-reqd.d sslv2.d sslv3.d stderr.d suppress-connect-headers.d \ + tcp-fastopen.d tcp-nodelay.d \ + telnet-option.d tftp-blksize.d tftp-no-options.d time-cond.d \ + tls-max.d \ + tlsauthtype.d tlspassword.d tlsuser.d tlsv1.0.d tlsv1.1.d tlsv1.2.d \ + tlsv1.3.d tlsv1.d trace-ascii.d trace.d trace-time.d tr-encoding.d \ + unix-socket.d upload-file.d url.d use-ascii.d user-agent.d user.d \ + verbose.d version.d write-out.d xattr.d request-target.d \ + styled-output.d tls13-ciphers.d proxy-tls13-ciphers.d + +OTHERPAGES = page-footer page-header diff --git a/docs/cmdline-opts/abstract-unix-socket.d b/docs/cmdline-opts/abstract-unix-socket.d new file mode 100644 index 00000000..1fda4e5d --- /dev/null +++ b/docs/cmdline-opts/abstract-unix-socket.d @@ -0,0 +1,9 @@ +Long: abstract-unix-socket +Arg: +Help: Connect via abstract Unix domain socket +Added: 7.53.0 +Protocols: HTTP +--- +Connect through an abstract Unix domain socket, instead of using the network. +Note: netstat shows the path of an abstract socket prefixed with '@', however +the argument should not have this leading character. diff --git a/docs/cmdline-opts/anyauth.d b/docs/cmdline-opts/anyauth.d new file mode 100644 index 00000000..c32d1ed5 --- /dev/null +++ b/docs/cmdline-opts/anyauth.d @@ -0,0 +1,17 @@ +Long: anyauth +Help: Pick any authentication method +Protocols: HTTP +See-also: proxy-anyauth basic digest +--- +Tells curl to figure out authentication method by itself, and use the most +secure one the remote site claims to support. This is done by first doing a +request and checking the response-headers, thus possibly inducing an extra +network round-trip. This is used instead of setting a specific authentication +method, which you can do with --basic, --digest, --ntlm, and --negotiate. + +Using --anyauth is not recommended if you do uploads from stdin, since it may +require data to be sent twice and then the client must be able to rewind. If +the need should arise when uploading from stdin, the upload operation will +fail. + +Used together with --user. diff --git a/docs/cmdline-opts/append.d b/docs/cmdline-opts/append.d new file mode 100644 index 00000000..f001b123 --- /dev/null +++ b/docs/cmdline-opts/append.d @@ -0,0 +1,8 @@ +Short: a +Long: append +Help: Append to target file when uploading +Protocols: FTP SFTP +--- +When used in an upload, this makes curl append to the target file instead of +overwriting it. If the remote file doesn't exist, it will be created. Note +that this flag is ignored by some SFTP servers (including OpenSSH). diff --git a/docs/cmdline-opts/basic.d b/docs/cmdline-opts/basic.d new file mode 100644 index 00000000..09d42af9 --- /dev/null +++ b/docs/cmdline-opts/basic.d @@ -0,0 +1,11 @@ +Long: basic +Help: Use HTTP Basic Authentication +See-also: proxy-basic +Protocols: HTTP +--- +Tells curl to use HTTP Basic authentication with the remote host. This is the +default and this option is usually pointless, unless you use it to override a +previously set option that sets a different authentication method (such as +--ntlm, --digest, or --negotiate). + +Used together with --user. diff --git a/docs/cmdline-opts/cacert.d b/docs/cmdline-opts/cacert.d new file mode 100644 index 00000000..073ad3a9 --- /dev/null +++ b/docs/cmdline-opts/cacert.d @@ -0,0 +1,33 @@ +Long: cacert +Arg: +Help: CA certificate to verify peer against +Protocols: TLS +--- +Tells curl to use the specified certificate file to verify the peer. The file +may contain multiple CA certificates. The certificate(s) must be in PEM +format. Normally curl is built to use a default file for this, so this option +is typically used to alter that default file. + +curl recognizes the environment variable named 'CURL_CA_BUNDLE' if it is +set, and uses the given path as a path to a CA cert bundle. This option +overrides that variable. + +The windows version of curl will automatically look for a CA certs file named +\'curl-ca-bundle.crt\', either in the same directory as curl.exe, or in the +Current Working Directory, or in any folder along your PATH. + +If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module +(libnsspem.so) needs to be available for this option to work properly. + +(iOS and macOS only) If curl is built against Secure Transport, then this +option is supported for backward compatibility with other SSL engines, but it +should not be set. If the option is not set, then curl will use the +certificates in the system and user Keychain to verify the peer, which is the +preferred method of verifying the peer's certificate chain. + +(Schannel/WinSSL only) This option is supported for WinSSL in Windows 7 or +later with libcurl 7.60 or later. This option is supported for backward +compatibility with other SSL engines; instead it is recommended to use Windows' +store of root certificates (the default for WinSSL). + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/capath.d b/docs/cmdline-opts/capath.d new file mode 100644 index 00000000..0763f7a0 --- /dev/null +++ b/docs/cmdline-opts/capath.d @@ -0,0 +1,15 @@ +Long: capath +Arg: +Help: CA directory to verify peer against +Protocols: TLS +--- +Tells curl to use the specified certificate directory to verify the +peer. Multiple paths can be provided by separating them with ":" (e.g. +\&"path1:path2:path3"). The certificates must be in PEM format, and if curl is +built against OpenSSL, the directory must have been processed using the +c_rehash utility supplied with OpenSSL. Using --capath can allow +OpenSSL-powered curl to make SSL-connections much more efficiently than using +--cacert if the --cacert file contains many CA certificates. + +If this option is set, the default capath value will be ignored, and if it is +used several times, the last one will be used. diff --git a/docs/cmdline-opts/cert-status.d b/docs/cmdline-opts/cert-status.d new file mode 100644 index 00000000..f1aaa217 --- /dev/null +++ b/docs/cmdline-opts/cert-status.d @@ -0,0 +1,13 @@ +Long: cert-status +Protocols: TLS +Added: 7.41.0 +Help: Verify the status of the server certificate +--- +Tells curl to verify the status of the server certificate by using the +Certificate Status Request (aka. OCSP stapling) TLS extension. + +If this option is enabled and the server sends an invalid (e.g. expired) +response, if the response suggests that the server certificate has been revoked, +or no response at all is received, the verification fails. + +This is currently only implemented in the OpenSSL, GnuTLS and NSS backends. diff --git a/docs/cmdline-opts/cert-type.d b/docs/cmdline-opts/cert-type.d new file mode 100644 index 00000000..55d8033b --- /dev/null +++ b/docs/cmdline-opts/cert-type.d @@ -0,0 +1,10 @@ +Long: cert-type +Protocols: TLS +Arg: +Help: Certificate file type +See-also: cert key key-type +--- +Tells curl what type the provided client certificate is using. PEM, DER, ENG +and P12 are recognized types. If not specified, PEM is assumed. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/cert.d b/docs/cmdline-opts/cert.d new file mode 100644 index 00000000..adf62fc7 --- /dev/null +++ b/docs/cmdline-opts/cert.d @@ -0,0 +1,43 @@ +Short: E +Long: cert +Arg: +Help: Client certificate file and password +Protocols: TLS +See-also: cert-type key key-type +--- +Tells curl to use the specified client certificate file when getting a file +with HTTPS, FTPS or another SSL-based protocol. The certificate must be in +PKCS#12 format if using Secure Transport, or PEM format if using any other +engine. If the optional password isn't specified, it will be queried for on +the terminal. Note that this option assumes a \&"certificate" file that is the +private key and the client certificate concatenated! See --cert and --key to +specify them independently. + +If curl is built against the NSS SSL library then this option can tell +curl the nickname of the certificate to use within the NSS database defined +by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the +NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be +loaded. If you want to use a file from the current directory, please precede +it with "./" prefix, in order to avoid confusion with a nickname. If the +nickname contains ":", it needs to be preceded by "\\" so that it is not +recognized as password delimiter. If the nickname contains "\\", it needs to +be escaped as "\\\\" so that it is not recognized as an escape character. + +(iOS and macOS only) If curl is built against Secure Transport, then the +certificate string can either be the name of a certificate/private key in the +system or user keychain, or the path to a PKCS#12-encoded certificate and +private key. If you want to use a file from the current directory, please +precede it with "./" prefix, in order to avoid confusion with a nickname. + +(Schannel/WinSSL only) Client certificates must be specified by a path +expression to a certificate store. (Loading PFX is not supported; you can +import it to a store first). You can use +"\\\\" to refer to a certificate +in the system certificates store, for example, +"CurrentUser\\MY\\934a7ac6f8a5d579285a74fa61e19f23ddfe8d7a". Thumbprint is +usually a SHA-1 hex string which you can see in certificate details. Following +store locations are supported: CurrentUser, LocalMachine, CurrentService, +Services, CurrentUserGroupPolicy, LocalMachineGroupPolicy, +LocalMachineEnterprise. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/ciphers.d b/docs/cmdline-opts/ciphers.d new file mode 100644 index 00000000..69e85525 --- /dev/null +++ b/docs/cmdline-opts/ciphers.d @@ -0,0 +1,11 @@ +Long: ciphers +Arg: +Help: SSL ciphers to use +Protocols: TLS +--- +Specifies which ciphers to use in the connection. The list of ciphers must +specify valid ciphers. Read up on SSL cipher list details on this URL: + + https://curl.haxx.se/docs/ssl-ciphers.html + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/compressed-ssh.d b/docs/cmdline-opts/compressed-ssh.d new file mode 100644 index 00000000..583452ae --- /dev/null +++ b/docs/cmdline-opts/compressed-ssh.d @@ -0,0 +1,7 @@ +Long: compressed-ssh +Help: Enable SSH compression +Protocols: SCP SFTP +Added: 7.56.0 +--- +Enables built-in SSH compression. +This is a request, not an order; the server may or may not do it. diff --git a/docs/cmdline-opts/compressed.d b/docs/cmdline-opts/compressed.d new file mode 100644 index 00000000..dc130c1f --- /dev/null +++ b/docs/cmdline-opts/compressed.d @@ -0,0 +1,7 @@ +Long: compressed +Help: Request compressed response +Protocols: HTTP +--- +Request a compressed response using one of the algorithms curl supports, and +save the uncompressed document. If this option is used and the server sends +an unsupported encoding, curl will report an error. diff --git a/docs/cmdline-opts/config.d b/docs/cmdline-opts/config.d new file mode 100644 index 00000000..105d6282 --- /dev/null +++ b/docs/cmdline-opts/config.d @@ -0,0 +1,61 @@ +Long: config +Arg: +Help: Read config from a file +Short: K +--- + +Specify a text file to read curl arguments from. The command line arguments +found in the text file will be used as if they were provided on the command +line. + +Options and their parameters must be specified on the same line in the file, +separated by whitespace, colon, or the equals sign. Long option names can +optionally be given in the config file without the initial double dashes and +if so, the colon or equals characters can be used as separators. If the option +is specified with one or two dashes, there can be no colon or equals character +between the option and its parameter. + +If the parameter is to contain whitespace, the parameter must be enclosed +within quotes. Within double quotes, the following escape sequences are +available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash preceding any other +letter is ignored. If the first column of a config line is a '#' character, +the rest of the line will be treated as a comment. Only write one option per +physical line in the config file. + +Specify the filename to --config as '-' to make curl read the file from stdin. + +Note that to be able to specify a URL in the config file, you need to specify +it using the --url option, and not by simply writing the URL on its own +line. So, it could look similar to this: + +url = "https://curl.haxx.se/docs/" + +When curl is invoked, it (unless --disable is used) checks for a default +config file and uses it if found. The default config file is checked for in +the following places in this order: + +1) curl tries to find the "home dir": It first checks for the CURL_HOME and +then the HOME environment variables. Failing that, it uses getpwuid() on +Unix-like systems (which returns the home dir given the current user in your +system). On Windows, it then checks for the APPDATA variable, or as a last +resort the '%USERPROFILE%\\Application Data'. + +2) On windows, if there is no _curlrc file in the home dir, it checks for one +in the same dir the curl executable is placed. On Unix-like systems, it will +simply try to load .curlrc from the determined home dir. + +.nf +# --- Example file --- +# this is a comment +url = "example.com" +output = "curlhere.html" +user-agent = "superagent/1.0" + +# and fetch another URL too +url = "example.com/docs/manpage.html" +-O +referer = "http://nowhereatall.example.com/" +# --- End of example file --- +.fi + +This option can be used multiple times to load multiple config files. diff --git a/docs/cmdline-opts/connect-timeout.d b/docs/cmdline-opts/connect-timeout.d new file mode 100644 index 00000000..3a32d868 --- /dev/null +++ b/docs/cmdline-opts/connect-timeout.d @@ -0,0 +1,11 @@ +Long: connect-timeout +Arg: +Help: Maximum time allowed for connection +See-also: max-time +--- +Maximum time in seconds that you allow curl's connection to take. This only +limits the connection phase, so if curl connects within the given period it +will continue - if not it will exit. Since version 7.32.0, this option +accepts decimal values. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/connect-to.d b/docs/cmdline-opts/connect-to.d new file mode 100644 index 00000000..458bfe85 --- /dev/null +++ b/docs/cmdline-opts/connect-to.d @@ -0,0 +1,21 @@ +Long: connect-to +Arg: +Help: Connect to host +Added: 7.49.0 +See-also: resolve header +--- + +For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead. +This option is suitable to direct requests at a specific server, e.g. at a +specific cluster node in a cluster of servers. This option is only used to +establish the network connection. It does NOT affect the hostname/port that is +used for TLS/SSL (e.g. SNI, certificate verification) or for the application +protocols. "HOST1" and "PORT1" may be the empty string, meaning "any +host/port". "HOST2" and "PORT2" may also be the empty string, meaning "use the +request's original host/port". + +A "host" specified to this option is compared as a string, so it needs to +match the name used in request URL. It can be either numerical such as +"127.0.0.1" or the full host name such as "example.org". + +This option can be used many times to add many connect rules. diff --git a/docs/cmdline-opts/continue-at.d b/docs/cmdline-opts/continue-at.d new file mode 100644 index 00000000..733f4941 --- /dev/null +++ b/docs/cmdline-opts/continue-at.d @@ -0,0 +1,15 @@ +Short: C +Long: continue-at +Arg: +Help: Resumed transfer offset +See-also: range +--- +Continue/Resume a previous file transfer at the given offset. The given offset +is the exact number of bytes that will be skipped, counting from the beginning +of the source file before it is transferred to the destination. If used with +uploads, the FTP server command SIZE will not be used by curl. + +Use "-C -" to tell curl to automatically find out where/how to resume the +transfer. It then uses the given output/input files to figure that out. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/cookie-jar.d b/docs/cmdline-opts/cookie-jar.d new file mode 100644 index 00000000..da79777e --- /dev/null +++ b/docs/cmdline-opts/cookie-jar.d @@ -0,0 +1,24 @@ +Short: c +Long: cookie-jar +Arg: +Protocols: HTTP +Help: Write cookies to after operation +--- +Specify to which file you want curl to write all cookies after a completed +operation. Curl writes all cookies from its in-memory cookie storage to the +given file at the end of operations. If no cookies are known, no data will be +written. The file will be written using the Netscape cookie file format. If +you set the file name to a single dash, "-", the cookies will be written to +stdout. + +This command line option will activate the cookie engine that makes curl +record and use cookies. Another way to activate it is to use the --cookie +option. + +If the cookie jar can't be created or written to, the whole curl operation +won't fail or even report an error clearly. Using --verbose will get a warning +displayed, but that is the only visible feedback you get about this possibly +lethal situation. + +If this option is used several times, the last specified file name will be +used. diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d new file mode 100644 index 00000000..3ae69754 --- /dev/null +++ b/docs/cmdline-opts/cookie.d @@ -0,0 +1,37 @@ +Short: b +Long: cookie +Arg: +Protocols: HTTP +Help: Send cookies from string/file +--- +Pass the data to the HTTP server in the Cookie header. It is supposedly +the data previously received from the server in a "Set-Cookie:" line. The +data should be in the format "NAME1=VALUE1; NAME2=VALUE2". + +If no '=' symbol is used in the argument, it is instead treated as a filename +to read previously stored cookie from. This option also activates the cookie +engine which will make curl record incoming cookies, which may be handy if +you're using this in combination with the --location option or do multiple URL +transfers on the same invoke. If the file name is exactly a minus ("-"), curl +will instead the contents from stdin. + +The file format of the file to read cookies from should be plain HTTP headers +(Set-Cookie style) or the Netscape/Mozilla cookie file format. + +The file specified with --cookie is only used as input. No cookies will be +written to the file. To store cookies, use the --cookie-jar option. + +Exercise caution if you are using this option and multiple transfers may +occur. If you use the NAME1=VALUE1; format, or in a file use the Set-Cookie +format and don't specify a domain, then the cookie is sent for any domain +(even after redirects are followed) and cannot be modified by a server-set +cookie. If the cookie engine is enabled and a server sets a cookie of the same +name then both will be sent on a future transfer to that server, likely not +what you intended. To address these issues set a domain in Set-Cookie (doing +that will include sub domains) or use the Netscape format. + +If this option is used several times, the last one will be used. + +Users very often want to both read cookies from a file and write updated +cookies back to a file, so using both --cookie and --cookie-jar in the same +command line is common. diff --git a/docs/cmdline-opts/create-dirs.d b/docs/cmdline-opts/create-dirs.d new file mode 100644 index 00000000..49e22e75 --- /dev/null +++ b/docs/cmdline-opts/create-dirs.d @@ -0,0 +1,9 @@ +Long: create-dirs +Help: Create necessary local directory hierarchy +--- +When used in conjunction with the --output option, curl will create the +necessary local directory hierarchy as needed. This option creates the dirs +mentioned with the --output option, nothing else. If the --output file name +uses no dir or if the dirs it mentions already exist, no dir will be created. + +To create remote directories when using FTP or SFTP, try --ftp-create-dirs. diff --git a/docs/cmdline-opts/crlf.d b/docs/cmdline-opts/crlf.d new file mode 100644 index 00000000..f6694b65 --- /dev/null +++ b/docs/cmdline-opts/crlf.d @@ -0,0 +1,7 @@ +Long: crlf +Help: Convert LF to CRLF in upload +Protocols: FTP SMTP +--- +Convert LF to CRLF in upload. Useful for MVS (OS/390). + +(SMTP added in 7.40.0) diff --git a/docs/cmdline-opts/crlfile.d b/docs/cmdline-opts/crlfile.d new file mode 100644 index 00000000..0fcc63c8 --- /dev/null +++ b/docs/cmdline-opts/crlfile.d @@ -0,0 +1,10 @@ +Long: crlfile +Arg: +Protocols: TLS +Help: Get a CRL list in PEM format from the given file +Added: 7.19.7 +--- +Provide a file using PEM format with a Certificate Revocation List that may +specify peer certificates that are to be considered revoked. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/data-ascii.d b/docs/cmdline-opts/data-ascii.d new file mode 100644 index 00000000..bda4abc3 --- /dev/null +++ b/docs/cmdline-opts/data-ascii.d @@ -0,0 +1,6 @@ +Long: data-ascii +Arg: +Help: HTTP POST ASCII data +Protocols: HTTP +--- +This is just an alias for --data. diff --git a/docs/cmdline-opts/data-binary.d b/docs/cmdline-opts/data-binary.d new file mode 100644 index 00000000..c6721c64 --- /dev/null +++ b/docs/cmdline-opts/data-binary.d @@ -0,0 +1,13 @@ +Long: data-binary +Arg: +Help: HTTP POST binary data +Protocols: HTTP +--- +This posts data exactly as specified with no extra processing whatsoever. + +If you start the data with the letter @, the rest should be a filename. Data +is posted in a similar manner as --data does, except that newlines and +carriage returns are preserved and conversions are never done. + +If this option is used several times, the ones following the first will append +data as described in --data. diff --git a/docs/cmdline-opts/data-raw.d b/docs/cmdline-opts/data-raw.d new file mode 100644 index 00000000..7669b4ab --- /dev/null +++ b/docs/cmdline-opts/data-raw.d @@ -0,0 +1,9 @@ +Long: data-raw +Arg: +Protocols: HTTP +Help: HTTP POST data, '@' allowed +Added: 7.43.0 +See-also: data +--- +This posts data similarly to --data but without the special +interpretation of the @ character. diff --git a/docs/cmdline-opts/data-urlencode.d b/docs/cmdline-opts/data-urlencode.d new file mode 100644 index 00000000..9873f335 --- /dev/null +++ b/docs/cmdline-opts/data-urlencode.d @@ -0,0 +1,33 @@ +Long: data-urlencode +Arg: +Help: HTTP POST data url encoded +Protocols: HTTP +See-also: data data-raw +Added: 7.18.0 +--- +This posts data, similar to the other --data options with the exception +that this performs URL-encoding. + +To be CGI-compliant, the part should begin with a \fIname\fP followed +by a separator and a content specification. The part can be passed to +curl using one of the following syntaxes: +.RS +.IP "content" +This will make curl URL-encode the content and pass that on. Just be careful +so that the content doesn't contain any = or @ symbols, as that will then make +the syntax match one of the other cases below! +.IP "=content" +This will make curl URL-encode the content and pass that on. The preceding = +symbol is not included in the data. +.IP "name=content" +This will make curl URL-encode the content part and pass that on. Note that +the name part is expected to be URL-encoded already. +.IP "@filename" +This will make curl load data from the given file (including any newlines), +URL-encode that data and pass it on in the POST. +.IP "name@filename" +This will make curl load data from the given file (including any newlines), +URL-encode that data and pass it on in the POST. The name part gets an equal +sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the +name is expected to be URL-encoded already. +.RE diff --git a/docs/cmdline-opts/data.d b/docs/cmdline-opts/data.d new file mode 100644 index 00000000..7d499665 --- /dev/null +++ b/docs/cmdline-opts/data.d @@ -0,0 +1,30 @@ +Long: data +Short: d +Arg: +Help: HTTP POST data +Protocols: HTTP +See-also: data-binary data-urlencode data-raw +Mutexed: form head upload-file +--- +Sends the specified data in a POST request to the HTTP server, in the same way +that a browser does when a user has filled in an HTML form and presses the +submit button. This will cause curl to pass the data to the server using the +content-type application/x-www-form-urlencoded. Compare to --form. + +--data-raw is almost the same but does not have a special interpretation of +the @ character. To post data purely binary, you should instead use the +--data-binary option. To URL-encode the value of a form field you may use +--data-urlencode. + +If any of these options is used more than once on the same command line, the +data pieces specified will be merged together with a separating +&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post +chunk that looks like \&'name=daniel&skill=lousy'. + +If you start the data with the letter @, the rest should be a file name to +read the data from, or - if you want curl to read the data from +stdin. Multiple files can also be specified. Posting data from a file named +'foobar' would thus be done with --data @foobar. When --data is told to read +from a file like that, carriage returns and newlines will be stripped out. If +you don't want the @ character to have a special interpretation use --data-raw +instead. diff --git a/docs/cmdline-opts/delegation.d b/docs/cmdline-opts/delegation.d new file mode 100644 index 00000000..138d8233 --- /dev/null +++ b/docs/cmdline-opts/delegation.d @@ -0,0 +1,16 @@ +Long: delegation +Arg: +Help: GSS-API delegation permission +Protocols: GSS/kerberos +--- +Set LEVEL to tell the server what it is allowed to delegate when it +comes to user credentials. +.RS +.IP "none" +Don't allow any delegation. +.IP "policy" +Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos +service ticket, which is a matter of realm policy. +.IP "always" +Unconditionally allow the server to delegate. +.RE diff --git a/docs/cmdline-opts/digest.d b/docs/cmdline-opts/digest.d new file mode 100644 index 00000000..5cdd9258 --- /dev/null +++ b/docs/cmdline-opts/digest.d @@ -0,0 +1,11 @@ +Long: digest +Help: Use HTTP Digest Authentication +Protocols: HTTP +Mutexed: basic ntlm negotiate +See-also: user proxy-digest anyauth +--- +Enables HTTP Digest authentication. This is an authentication scheme that +prevents the password from being sent over the wire in clear text. Use this in +combination with the normal --user option to set user name and password. + +If this option is used several times, only the first one is used. diff --git a/docs/cmdline-opts/disable-eprt.d b/docs/cmdline-opts/disable-eprt.d new file mode 100644 index 00000000..a1e53c0b --- /dev/null +++ b/docs/cmdline-opts/disable-eprt.d @@ -0,0 +1,19 @@ +Long: disable-eprt +Help: Inhibit using EPRT or LPRT +Protocols: FTP +--- +Tell curl to disable the use of the EPRT and LPRT commands when doing active +FTP transfers. Curl will normally always first attempt to use EPRT, then LPRT +before using PORT, but with this option, it will use PORT right away. EPRT and +LPRT are extensions to the original FTP protocol, and may not work on all +servers, but they enable more functionality in a better way than the +traditional PORT command. + +--eprt can be used to explicitly enable EPRT again and --no-eprt is an alias +for --disable-eprt. + +If the server is accessed using IPv6, this option will have no effect as EPRT +is necessary then. + +Disabling EPRT only changes the active behavior. If you want to switch to +passive mode you need to not use --ftp-port or force it with --ftp-pasv. diff --git a/docs/cmdline-opts/disable-epsv.d b/docs/cmdline-opts/disable-epsv.d new file mode 100644 index 00000000..6d2cb708 --- /dev/null +++ b/docs/cmdline-opts/disable-epsv.d @@ -0,0 +1,16 @@ +Long: disable-epsv +Help: Inhibit using EPSV +Protocols: FTP +--- +(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP +transfers. Curl will normally always first attempt to use EPSV before PASV, +but with this option, it will not try using EPSV. + +--epsv can be used to explicitly enable EPSV again and --no-epsv is an alias +for --disable-epsv. + +If the server is an IPv6 host, this option will have no effect as EPSV is +necessary then. + +Disabling EPSV only changes the passive behavior. If you want to switch to +active mode you need to use --ftp-port. diff --git a/docs/cmdline-opts/disable.d b/docs/cmdline-opts/disable.d new file mode 100644 index 00000000..20b27b4c --- /dev/null +++ b/docs/cmdline-opts/disable.d @@ -0,0 +1,7 @@ +Long: disable +Short: q +Help: Disable .curlrc +--- +If used as the first parameter on the command line, the \fIcurlrc\fP config +file will not be read and used. See the --config for details on the default +config file search path. diff --git a/docs/cmdline-opts/disallow-username-in-url.d b/docs/cmdline-opts/disallow-username-in-url.d new file mode 100644 index 00000000..a7f46ea1 --- /dev/null +++ b/docs/cmdline-opts/disallow-username-in-url.d @@ -0,0 +1,7 @@ +Long: disallow-username-in-url +Help: Disallow username in url +Protocols: HTTP +Added: 7.61.0 +See-also: proto +--- +This tells curl to exit if passed a url containing a username. diff --git a/docs/cmdline-opts/dns-interface.d b/docs/cmdline-opts/dns-interface.d new file mode 100644 index 00000000..45e5af26 --- /dev/null +++ b/docs/cmdline-opts/dns-interface.d @@ -0,0 +1,11 @@ +Long: dns-interface +Arg: +Help: Interface to use for DNS requests +Protocols: DNS +See-also: dns-ipv4-addr dns-ipv6-addr +Added: 7.33.0 +Requires: c-ares +--- +Tell curl to send outgoing DNS requests through . This option is a +counterpart to --interface (which does not affect DNS). The supplied string +must be an interface name (not an address). diff --git a/docs/cmdline-opts/dns-ipv4-addr.d b/docs/cmdline-opts/dns-ipv4-addr.d new file mode 100644 index 00000000..597b8588 --- /dev/null +++ b/docs/cmdline-opts/dns-ipv4-addr.d @@ -0,0 +1,11 @@ +Long: dns-ipv4-addr +Arg:
+Help: IPv4 address to use for DNS requests +Protocols: DNS +See-also: dns-interface dns-ipv6-addr +Added: 7.33.0 +Requires: c-ares +--- +Tell curl to bind to when making IPv4 DNS requests, so that +the DNS requests originate from this address. The argument should be a +single IPv4 address. diff --git a/docs/cmdline-opts/dns-ipv6-addr.d b/docs/cmdline-opts/dns-ipv6-addr.d new file mode 100644 index 00000000..581f0195 --- /dev/null +++ b/docs/cmdline-opts/dns-ipv6-addr.d @@ -0,0 +1,11 @@ +Long: dns-ipv6-addr +Arg:
+Help: IPv6 address to use for DNS requests +Protocols: DNS +See-also: dns-interface dns-ipv4-addr +Added: 7.33.0 +Requires: c-ares +--- +Tell curl to bind to when making IPv6 DNS requests, so that +the DNS requests originate from this address. The argument should be a +single IPv6 address. diff --git a/docs/cmdline-opts/dns-servers.d b/docs/cmdline-opts/dns-servers.d new file mode 100644 index 00000000..a98fd07d --- /dev/null +++ b/docs/cmdline-opts/dns-servers.d @@ -0,0 +1,10 @@ +Long: dns-servers +Arg: +Help: DNS server addrs to use +Requires: c-ares +Added: 7.33.0 +--- +Set the list of DNS servers to be used instead of the system default. +The list of IP addresses should be separated with commas. Port numbers +may also optionally be given as \fI:\fP after each IP +address. diff --git a/docs/cmdline-opts/dump-header.d b/docs/cmdline-opts/dump-header.d new file mode 100644 index 00000000..05c10aff --- /dev/null +++ b/docs/cmdline-opts/dump-header.d @@ -0,0 +1,18 @@ +Long: dump-header +Short: D +Arg: +Help: Write the received headers to +Protocols: HTTP FTP +See-also: output +--- +Write the received protocol headers to the specified file. + +This option is handy to use when you want to store the headers that an HTTP +site sends to you. Cookies from the headers could then be read in a second +curl invocation by using the --cookie option! The --cookie-jar option is a +better way to store cookies. + +When used in FTP, the FTP server response lines are considered being "headers" +and thus are saved there. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/egd-file.d b/docs/cmdline-opts/egd-file.d new file mode 100644 index 00000000..c22790f6 --- /dev/null +++ b/docs/cmdline-opts/egd-file.d @@ -0,0 +1,8 @@ +Long: egd-file +Arg: +Help: EGD socket path for random data +Protocols: TLS +See-also: random-file +--- +Specify the path name to the Entropy Gathering Daemon socket. The socket is +used to seed the random engine for SSL connections. diff --git a/docs/cmdline-opts/engine.d b/docs/cmdline-opts/engine.d new file mode 100644 index 00000000..cde1a477 --- /dev/null +++ b/docs/cmdline-opts/engine.d @@ -0,0 +1,8 @@ +Long: engine +Arg: +Help: Crypto engine to use +Protocols: TLS +--- +Select the OpenSSL crypto engine to use for cipher operations. Use --engine +list to print a list of build-time supported engines. Note that not all (or +none) of the engines may be available at run-time. diff --git a/docs/cmdline-opts/expect100-timeout.d b/docs/cmdline-opts/expect100-timeout.d new file mode 100644 index 00000000..c88f0b84 --- /dev/null +++ b/docs/cmdline-opts/expect100-timeout.d @@ -0,0 +1,11 @@ +Long: expect100-timeout +Arg: +Help: How long to wait for 100-continue +Protocols: HTTP +Added: 7.47.0 +See-also: connect-timeout +--- +Maximum time in seconds that you allow curl to wait for a 100-continue +response when curl emits an Expects: 100-continue header in its request. By +default curl will wait one second. This option accepts decimal values! When +curl stops waiting, it will continue as if the response has been received. diff --git a/docs/cmdline-opts/fail-early.d b/docs/cmdline-opts/fail-early.d new file mode 100644 index 00000000..375d4c91 --- /dev/null +++ b/docs/cmdline-opts/fail-early.d @@ -0,0 +1,21 @@ +Long: fail-early +Help: Fail on first transfer error, do not continue +Added: 7.52.0 +--- +Fail and exit on the first detected transfer error. + +When curl is used to do multiple transfers on the command line, it will +attempt to operate on each given URL, one by one. By default, it will ignore +errors if there are more URLs given and the last URL's success will determine +the error code curl returns. So early failures will be "hidden" by subsequent +successful transfers. + +Using this option, curl will instead return an error on the first transfer +that fails, independent of the amount of URLs that are given on the command +line. This way, no transfer failures go undetected by scripts and similar. + +This option is global and does not need to be specified for each use of --next. + +This option does not imply --fail, which causes transfers to fail due to the +server's HTTP status code. You can combine the two options, however note --fail +is not global and is therefore contained by --next. diff --git a/docs/cmdline-opts/fail.d b/docs/cmdline-opts/fail.d new file mode 100644 index 00000000..c46c571b --- /dev/null +++ b/docs/cmdline-opts/fail.d @@ -0,0 +1,14 @@ +Long: fail +Short: f +Protocols: HTTP +Help: Fail silently (no output at all) on HTTP errors +--- +Fail silently (no output at all) on server errors. This is mostly done to +better enable scripts etc to better deal with failed attempts. In normal cases +when an HTTP server fails to deliver a document, it returns an HTML document +stating so (which often also describes why and more). This flag will prevent +curl from outputting that and return error 22. + +This method is not fail-safe and there are occasions where non-successful +response codes will slip through, especially when authentication is involved +(response codes 401 and 407). diff --git a/docs/cmdline-opts/false-start.d b/docs/cmdline-opts/false-start.d new file mode 100644 index 00000000..65a8afb8 --- /dev/null +++ b/docs/cmdline-opts/false-start.d @@ -0,0 +1,12 @@ +Long: false-start +Help: Enable TLS False Start +Protocols: TLS +Added: 7.42.0 +--- +Tells curl to use false start during the TLS handshake. False start is a mode +where a TLS client will start sending application data before verifying the +server's Finished message, thus saving a round trip when performing a full +handshake. + +This is currently only implemented in the NSS and Secure Transport (on iOS 7.0 +or later, or OS X 10.9 or later) backends. diff --git a/docs/cmdline-opts/form-string.d b/docs/cmdline-opts/form-string.d new file mode 100644 index 00000000..49d0d44e --- /dev/null +++ b/docs/cmdline-opts/form-string.d @@ -0,0 +1,11 @@ +Long: form-string +Help: Specify multipart MIME data +Protocols: HTTP SMTP IMAP +Arg: +See-also: form +--- +Similar to --form except that the value string for the named parameter is used +literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in +the value have no special meaning. Use this in preference to --form if +there's any possibility that the string value may accidentally trigger the +\&'@' or \&'<' features of --form. diff --git a/docs/cmdline-opts/form.d b/docs/cmdline-opts/form.d new file mode 100644 index 00000000..0bbc3701 --- /dev/null +++ b/docs/cmdline-opts/form.d @@ -0,0 +1,138 @@ +Long: form +Short: F +Arg: +Help: Specify multipart MIME data +Protocols: HTTP SMTP IMAP +Mutexed: data head upload-file +--- +For HTTP protocol family, this lets curl emulate a filled-in form in which a +user has pressed the submit button. This causes curl to POST data using the +Content-Type multipart/form-data according to RFC 2388. + +For SMTP and IMAP protocols, this is the mean to compose a multipart mail +message to transmit. + +This enables uploading of binary files etc. To force the 'content' part to be +a file, prefix the file name with an @ sign. To just get the content part from +a file, prefix the file name with the symbol <. The difference between @ and < +is then that @ makes a file get attached in the post as a file upload, while +the < makes a text field and just get the contents for that text field from a +file. + +Tell curl to read content from stdin instead of a file by using - as +filename. This goes for both @ and < constructs. When stdin is used, the +contents is buffered in memory first by curl to determine its size and allow a +possible resend. Defining a part's data from a named non-regular file (such +as a named pipe or similar) is unfortunately not subject to buffering and will +be effectively read at transmission time; since the full size is unknown +before the transfer starts, such data is sent as chunks by HTTP and rejected +by IMAP. + +Example: send an image to an HTTP server, where \&'profile' is the name of the +form-field to which the file portrait.jpg will be the input: + + curl -F profile=@portrait.jpg https://example.com/upload.cgi + +Example: send a your name and shoe size in two text fields to the server: + + curl -F name=John -F shoesize=11 https://example.com/ + +Example: send a your essay in a text field to the server. Send it as a plain +text field, but get the contents for it from a local file: + + curl -F "story=HTML message;type=text/html' \\ +.br + -F '=)' -F '=@textfile.txt' ... smtp://example.com + +Data can be encoded for transfer using encoder=. Available encodings are +\fIbinary\fP and \fI8bit\fP that do nothing else than adding the corresponding +Content-Transfer-Encoding header, \fI7bit\fP that only rejects 8-bit characters +with a transfer error, \fIquoted-printable\fP and \fIbase64\fP that encodes +data according to the corresponding schemes, limiting lines length to +76 characters. + +Example: send multipart mail with a quoted-printable text message and a +base64 attached file: + + curl -F '=text message;encoder=quoted-printable' \\ +.br + -F '=@localfile;encoder=base64' ... smtp://example.com + +See further examples and details in the MANUAL. + +This option can be used multiple times. diff --git a/docs/cmdline-opts/ftp-account.d b/docs/cmdline-opts/ftp-account.d new file mode 100644 index 00000000..013c4f37 --- /dev/null +++ b/docs/cmdline-opts/ftp-account.d @@ -0,0 +1,10 @@ +Long: ftp-account +Arg: +Help: Account data string +Protocols: FTP +Added: 7.13.0 +--- +When an FTP server asks for "account data" after user name and password has +been provided, this data is sent off using the ACCT command. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/ftp-alternative-to-user.d b/docs/cmdline-opts/ftp-alternative-to-user.d new file mode 100644 index 00000000..8982ba8b --- /dev/null +++ b/docs/cmdline-opts/ftp-alternative-to-user.d @@ -0,0 +1,10 @@ +Long: ftp-alternative-to-user +Arg: +Help: String to replace USER [name] +Protocols: FTP +Added: 7.15.5 +--- +If authenticating with the USER and PASS commands fails, send this command. +When connecting to Tumbleweed's Secure Transport server over FTPS using a +client certificate, using "SITE AUTH" will tell the server to retrieve the +username from the certificate. diff --git a/docs/cmdline-opts/ftp-create-dirs.d b/docs/cmdline-opts/ftp-create-dirs.d new file mode 100644 index 00000000..ede57100 --- /dev/null +++ b/docs/cmdline-opts/ftp-create-dirs.d @@ -0,0 +1,8 @@ +Long: ftp-create-dirs +Protocols: FTP SFTP +Help: Create the remote dirs if not present +See-also: create-dirs +--- +When an FTP or SFTP URL/operation uses a path that doesn't currently exist on +the server, the standard behavior of curl is to fail. Using this option, curl +will instead attempt to create missing directories. diff --git a/docs/cmdline-opts/ftp-method.d b/docs/cmdline-opts/ftp-method.d new file mode 100644 index 00000000..95aa522e --- /dev/null +++ b/docs/cmdline-opts/ftp-method.d @@ -0,0 +1,21 @@ +Long: ftp-method +Arg: +Help: Control CWD usage +Protocols: FTP +Added: 7.15.1 +--- +Control what method curl should use to reach a file on an FTP(S) +server. The method argument should be one of the following alternatives: +.RS +.IP multicwd +curl does a single CWD operation for each path part in the given URL. For deep +hierarchies this means very many commands. This is how RFC 1738 says it should +be done. This is the default but the slowest behavior. +.IP nocwd +curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full +path to the server for all these commands. This is the fastest behavior. +.IP singlecwd +curl does one CWD with the full target directory and then operates on the file +\&"normally" (like in the multicwd case). This is somewhat more standards +compliant than 'nocwd' but without the full penalty of 'multicwd'. +.RE diff --git a/docs/cmdline-opts/ftp-pasv.d b/docs/cmdline-opts/ftp-pasv.d new file mode 100644 index 00000000..44103e21 --- /dev/null +++ b/docs/cmdline-opts/ftp-pasv.d @@ -0,0 +1,16 @@ +Long: ftp-pasv +Help: Use PASV/EPSV instead of PORT +Protocols: FTP +Added: 7.11.0 +See-also: disable-epsv +--- +Use passive mode for the data connection. Passive is the internal default +behavior, but using this option can be used to override a previous --ftp-port +option. + +If this option is used several times, only the first one is used. Undoing an +enforced passive really isn't doable but you must then instead enforce the +correct --ftp-port again. + +Passive mode means that curl will try the EPSV command first and then PASV, +unless --disable-epsv is used. diff --git a/docs/cmdline-opts/ftp-port.d b/docs/cmdline-opts/ftp-port.d new file mode 100644 index 00000000..e4b14560 --- /dev/null +++ b/docs/cmdline-opts/ftp-port.d @@ -0,0 +1,32 @@ +Long: ftp-port +Arg:
+Help: Use PORT instead of PASV +Short: P +Protocols: FTP +See-also: ftp-pasv disable-eprt +--- +Reverses the default initiator/listener roles when connecting with FTP. This +option makes curl use active mode. curl then tells the server to connect back +to the client's specified address and port, while passive mode asks the server +to setup an IP address and port for it to connect to.
should be one +of: +.RS +.IP interface +e.g. "eth0" to specify which interface's IP address you want to use (Unix only) +.IP "IP address" +e.g. "192.168.10.1" to specify the exact IP address +.IP "host name" +e.g. "my.host.domain" to specify the machine +.IP "-" +make curl pick the same IP address that is already used for the control +connection +.RE + +If this option is used several times, the last one will be used. Disable the +use of PORT with --ftp-pasv. Disable the attempt to use the EPRT command +instead of PORT by using --disable-eprt. EPRT is really PORT++. + +Since 7.19.5, you can append \&":[start]-[end]\&" to the right of the address, +to tell curl what TCP port range to use. That means you specify a port range, +from a lower to a higher number. A single number works as well, but do note +that it increases the risk of failure since the port may not be available. diff --git a/docs/cmdline-opts/ftp-pret.d b/docs/cmdline-opts/ftp-pret.d new file mode 100644 index 00000000..dac4c353 --- /dev/null +++ b/docs/cmdline-opts/ftp-pret.d @@ -0,0 +1,8 @@ +Long: ftp-pret +Help: Send PRET before PASV +Protocols: FTP +Added: 7.20.0 +--- +Tell curl to send a PRET command before PASV (and EPSV). Certain FTP servers, +mainly drftpd, require this non-standard command for directory listings as +well as up and downloads in PASV mode. diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d new file mode 100644 index 00000000..da6ab11f --- /dev/null +++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d @@ -0,0 +1,12 @@ +Long: ftp-skip-pasv-ip +Help: Skip the IP address for PASV +Protocols: FTP +Added: 7.14.2 +See-also: ftp-pasv +--- +Tell curl to not use the IP address the server suggests in its response +to curl's PASV command when curl connects the data connection. Instead curl +will re-use the same IP address it already uses for the control +connection. + +This option has no effect if PORT, EPRT or EPSV is used instead of PASV. diff --git a/docs/cmdline-opts/ftp-ssl-ccc-mode.d b/docs/cmdline-opts/ftp-ssl-ccc-mode.d new file mode 100644 index 00000000..be102949 --- /dev/null +++ b/docs/cmdline-opts/ftp-ssl-ccc-mode.d @@ -0,0 +1,11 @@ +Long: ftp-ssl-ccc-mode +Arg: +Help: Set CCC mode +Protocols: FTP +Added: 7.16.2 +See-also: ftp-ssl-ccc +--- +Sets the CCC mode. The passive mode will not initiate the shutdown, but +instead wait for the server to do it, and will not reply to the shutdown from +the server. The active mode initiates the shutdown and waits for a reply from +the server. diff --git a/docs/cmdline-opts/ftp-ssl-ccc.d b/docs/cmdline-opts/ftp-ssl-ccc.d new file mode 100644 index 00000000..c6edc5b3 --- /dev/null +++ b/docs/cmdline-opts/ftp-ssl-ccc.d @@ -0,0 +1,10 @@ +Long: ftp-ssl-ccc +Help: Send CCC after authenticating +Protocols: FTP +See-also: ssl ftp-ssl-ccc-mode +Added: 7.16.1 +--- +Use CCC (Clear Command Channel) Shuts down the SSL/TLS layer after +authenticating. The rest of the control channel communication will be +unencrypted. This allows NAT routers to follow the FTP transaction. The +default mode is passive. diff --git a/docs/cmdline-opts/ftp-ssl-control.d b/docs/cmdline-opts/ftp-ssl-control.d new file mode 100644 index 00000000..87a82253 --- /dev/null +++ b/docs/cmdline-opts/ftp-ssl-control.d @@ -0,0 +1,8 @@ +Long: ftp-ssl-control +Help: Require SSL/TLS for FTP login, clear for transfer +Protocols: FTP +Added: 7.16.0 +--- +Require SSL/TLS for the FTP login, clear for transfer. Allows secure +authentication, but non-encrypted data transfers for efficiency. Fails the +transfer if the server doesn't support SSL/TLS. diff --git a/docs/cmdline-opts/gen.pl b/docs/cmdline-opts/gen.pl new file mode 100755 index 00000000..dd990caf --- /dev/null +++ b/docs/cmdline-opts/gen.pl @@ -0,0 +1,391 @@ +#!/usr/bin/env perl + +=begin comment + +This script generates the manpage. + +Example: gen.pl mainpage > curl.1 + +Dev notes: + +We open *input* files in :crlf translation (a no-op on many platforms) in +case we have CRLF line endings in Windows but a perl that defaults to LF. +Unfortunately it seems some perls like msysgit can't handle a global input-only +:crlf so it has to be specified on each file open for text input. + +=end comment +=cut + +my $some_dir=$ARGV[1] || "."; + +opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!"; +my @s = grep { /\.d$/ && -f "$some_dir/$_" } readdir($dh); +closedir $dh; + +my %optshort; +my %optlong; +my %helplong; +my %arglong; +my %redirlong; +my %protolong; + +# get the long name version, return the man page string +sub manpageify { + my ($k)=@_; + my $l; + if($optlong{$k} ne "") { + # both short + long + $l = "\\fI-".$optlong{$k}.", --$k\\fP"; + } + else { + # only long + $l = "\\fI--$k\\fP"; + } + return $l; +} + +sub printdesc { + my @desc = @_; + for my $d (@desc) { + # skip lines starting with space (examples) + if($d =~ /^[^ ]/) { + for my $k (keys %optlong) { + my $l = manpageify($k); + $d =~ s/--$k([^a-z0-9_-])/$l$1/; + } + } + print $d; + } +} + +sub seealso { + my($standalone, $data)=@_; + if($standalone) { + return sprintf + ".SH \"SEE ALSO\"\n$data\n"; + } + else { + return "See also $data. "; + } +} + +sub overrides { + my ($standalone, $data)=@_; + if($standalone) { + return ".SH \"OVERRIDES\"\n$data\n"; + } + else { + return $data; + } +} + +sub protocols { + my ($standalone, $data)=@_; + if($standalone) { + return ".SH \"PROTOCOLS\"\n$data\n"; + } + else { + return "($data) "; + } +} + +sub added { + my ($standalone, $data)=@_; + if($standalone) { + return ".SH \"ADDED\"\nAdded in curl version $data\n"; + } + else { + return "Added in $data. "; + } +} + +sub single { + my ($f, $standalone)=@_; + open(F, "<:crlf", "$some_dir/$f") || + return 1; + my $short; + my $long; + my $tags; + my $added; + my $protocols; + my $arg; + my $mutexed; + my $requires; + my $seealso; + my $magic; # cmdline special option + while() { + if(/^Short: *(.)/i) { + $short=$1; + } + elsif(/^Long: *(.*)/i) { + $long=$1; + } + elsif(/^Added: *(.*)/i) { + $added=$1; + } + elsif(/^Tags: *(.*)/i) { + $tags=$1; + } + elsif(/^Arg: *(.*)/i) { + $arg=$1; + } + elsif(/^Magic: *(.*)/i) { + $magic=$1; + } + elsif(/^Mutexed: *(.*)/i) { + $mutexed=$1; + } + elsif(/^Protocols: *(.*)/i) { + $protocols=$1; + } + elsif(/^See-also: *(.*)/i) { + $seealso=$1; + } + elsif(/^Requires: *(.*)/i) { + $requires=$1; + } + elsif(/^Help: *(.*)/i) { + ; + } + elsif(/^---/) { + if(!$long) { + print STDERR "WARN: no 'Long:' in $f\n"; + } + last; + } + else { + chomp; + print STDERR "WARN: unrecognized line in $f, ignoring:\n:'$_';" + } + } + my @dest; + while() { + push @desc, $_; + } + close(F); + my $opt; + if(defined($short) && $long) { + $opt = "-$short, --$long"; + } + elsif($short && !$long) { + $opt = "-$short"; + } + elsif($long && !$short) { + $opt = "--$long"; + } + + if($arg) { + $opt .= " $arg"; + } + + if($standalone) { + print ".TH curl 1 \"30 Nov 2016\" \"curl 7.52.0\" \"curl manual\"\n"; + print ".SH OPTION\n"; + print "curl $opt\n"; + } + else { + print ".IP \"$opt\"\n"; + } + if($protocols) { + print protocols($standalone, $protocols); + } + + if($standalone) { + print ".SH DESCRIPTION\n"; + } + + printdesc(@desc); + undef @desc; + + my @foot; + if($seealso) { + my @m=split(/ /, $seealso); + my $mstr; + for my $k (@m) { + if(!$helplong{$k}) { + print STDERR "WARN: $f see-alsos a non-existing option: $k\n"; + } + my $l = manpageify($k); + $mstr .= sprintf "%s$l", $mstr?" and ":""; + } + push @foot, seealso($standalone, $mstr); + } + if($requires) { + my $l = manpageify($long); + push @foot, "$l requires that the underlying libcurl". + " was built to support $requires. "; + } + if($mutexed) { + my @m=split(/ /, $mutexed); + my $mstr; + for my $k (@m) { + if(!$helplong{$k}) { + print STDERR "WARN: $f mutexes a non-existing option: $k\n"; + } + my $l = manpageify($k); + $mstr .= sprintf "%s$l", $mstr?" and ":""; + } + push @foot, overrides($standalone, "This option overrides $mstr. "); + } + if($added) { + push @foot, added($standalone, $added); + } + if($foot[0]) { + print "\n"; + my $f = join("", @foot); + $f =~ s/ +\z//; # remove trailing space + print "$f\n"; + } + return 0; +} + +sub getshortlong { + my ($f)=@_; + open(F, "<:crlf", "$some_dir/$f"); + my $short; + my $long; + my $help; + my $arg; + my $protocols; + while() { + if(/^Short: (.)/i) { + $short=$1; + } + elsif(/^Long: (.*)/i) { + $long=$1; + } + elsif(/^Help: (.*)/i) { + $help=$1; + } + elsif(/^Arg: (.*)/i) { + $arg=$1; + } + elsif(/^Protocols: (.*)/i) { + $protocols=$1; + } + elsif(/^---/) { + last; + } + } + close(F); + if($short) { + $optshort{$short}=$long; + } + if($long) { + $optlong{$long}=$short; + $helplong{$long}=$help; + $arglong{$long}=$arg; + $protolong{$long}=$protocols; + } +} + +sub indexoptions { + foreach my $f (@s) { + getshortlong($f); + } +} + +sub header { + my ($f)=@_; + open(F, "<:crlf", "$some_dir/$f"); + my @d; + while() { + push @d, $_; + } + close(F); + printdesc(@d); +} + +sub listhelp { + foreach my $f (sort keys %helplong) { + my $long = $f; + my $short = $optlong{$long}; + my $opt; + + if(defined($short) && $long) { + $opt = "-$short, --$long"; + } + elsif($long && !$short) { + $opt = " --$long"; + } + + my $arg = $arglong{$long}; + if($arg) { + $opt .= " $arg"; + } + my $desc = $helplong{$f}; + $desc =~ s/\"/\\\"/g; # escape double quotes + + my $line = sprintf " {\"%s\",\n \"%s\"},\n", $opt, $desc; + + if(length($opt) + length($desc) > 78) { + print STDERR "WARN: the --$long line is too long\n"; + } + print $line; + } +} + +sub mainpage { + # show the page header + header("page-header"); + + # output docs for all options + foreach my $f (sort @s) { + single($f, 0); + } + + header("page-footer"); +} + +sub showonly { + my ($f) = @_; + if(single($f, 1)) { + print STDERR "$f: failed\n"; + } +} + +sub showprotocols { + my %prots; + foreach my $f (keys %optlong) { + my @p = split(/ /, $protolong{$f}); + for my $p (@p) { + $prots{$p}++; + } + } + for(sort keys %prots) { + printf "$_ (%d options)\n", $prots{$_}; + } +} + +sub getargs { + my $f; + do { + $f = shift @ARGV; + if($f eq "mainpage") { + mainpage(); + return; + } + elsif($f eq "listhelp") { + listhelp(); + return; + } + elsif($f eq "single") { + showonly(shift @ARGV); + return; + } + elsif($f eq "protos") { + showprotocols(); + return; + } + } while($f); + + print "Usage: gen.pl [srcdir]\n"; +} + +#------------------------------------------------------------------------ + +# learn all existing options +indexoptions(); + +getargs(); + diff --git a/docs/cmdline-opts/get.d b/docs/cmdline-opts/get.d new file mode 100644 index 00000000..be7cb25f --- /dev/null +++ b/docs/cmdline-opts/get.d @@ -0,0 +1,15 @@ +Long: get +Short: G +Help: Put the post data in the URL and use GET +--- +When used, this option will make all data specified with --data, --data-binary +or --data-urlencode to be used in an HTTP GET request instead of the POST +request that otherwise would be used. The data will be appended to the URL +with a '?' separator. + +If used in combination with --head, the POST data will instead be appended to +the URL with a HEAD request. + +If this option is used several times, only the first one is used. This is +because undoing a GET doesn't make sense, but you should then instead enforce +the alternative method you prefer. diff --git a/docs/cmdline-opts/globoff.d b/docs/cmdline-opts/globoff.d new file mode 100644 index 00000000..fff6516b --- /dev/null +++ b/docs/cmdline-opts/globoff.d @@ -0,0 +1,8 @@ +Long: globoff +Short: g +Help: Disable URL sequences and ranges using {} and [] +--- +This option switches off the "URL globbing parser". When you set this option, +you can specify URLs that contain the letters {}[] without having them being +interpreted by curl itself. Note that these letters are not normal legal URL +contents but they should be encoded according to the URI standard. diff --git a/docs/cmdline-opts/happy-eyeballs-timeout-ms.d b/docs/cmdline-opts/happy-eyeballs-timeout-ms.d new file mode 100644 index 00000000..ec9a8c22 --- /dev/null +++ b/docs/cmdline-opts/happy-eyeballs-timeout-ms.d @@ -0,0 +1,17 @@ +Long: happy-eyeballs-timeout-ms +Arg: +Help: How long to wait in milliseconds for IPv6 before trying IPv4 +Added: 7.59.0 +--- +Happy eyeballs is an algorithm that attempts to connect to both IPv4 and IPv6 +addresses for dual-stack hosts, preferring IPv6 first for the number of +milliseconds. If the IPv6 address cannot be connected to within that time then +a connection attempt is made to the IPv4 address in parallel. The first +connection to be established is the one that is used. + +The range of suggested useful values is limited. Happy Eyeballs RFC 6555 says +"It is RECOMMENDED that connection attempts be paced 150-250 ms apart to +balance human factors against network load." libcurl currently defaults to +200 ms. Firefox and Chrome currently default to 300 ms. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/haproxy-protocol.d b/docs/cmdline-opts/haproxy-protocol.d new file mode 100644 index 00000000..cc41c9c4 --- /dev/null +++ b/docs/cmdline-opts/haproxy-protocol.d @@ -0,0 +1,11 @@ +Long: haproxy-protocol +Help: Send HAProxy PROXY protocol v1 header +Protocols: HTTP +Added: 7.60.0 +--- +Send a HAProxy PROXY protocol v1 header at the beginning of the connection. This +is used by some load balancers and reverse proxies to indicate the client's +true IP address and port. + +This option is primarily useful when sending test requests to a service that +expects this header. diff --git a/docs/cmdline-opts/head.d b/docs/cmdline-opts/head.d new file mode 100644 index 00000000..350a100f --- /dev/null +++ b/docs/cmdline-opts/head.d @@ -0,0 +1,8 @@ +Long: head +Short: I +Help: Show document info only +Protocols: HTTP FTP FILE +--- +Fetch the headers only! HTTP-servers feature the command HEAD which this uses +to get nothing but the header of a document. When used on an FTP or FILE file, +curl displays the file size and last modification time only. diff --git a/docs/cmdline-opts/header.d b/docs/cmdline-opts/header.d new file mode 100644 index 00000000..d8292ed7 --- /dev/null +++ b/docs/cmdline-opts/header.d @@ -0,0 +1,41 @@ +Long: header +Short: H +Arg:
+Help: Pass custom header(s) to server +Protocols: HTTP +--- +Extra header to include in the request when sending HTTP to a server. You may +specify any number of extra headers. Note that if you should add a custom +header that has the same name as one of the internal ones curl would use, your +externally set header will be used instead of the internal one. This allows +you to make even trickier stuff than curl would normally do. You should not +replace internally set headers without knowing perfectly well what you're +doing. Remove an internal header by giving a replacement without content on +the right side of the colon, as in: -H \&"Host:". If you send the custom +header with no-value then its header must be terminated with a semicolon, such +as \-H \&"X-Custom-Header;" to send "X-Custom-Header:". + +curl will make sure that each header you add/replace is sent with the proper +end-of-line marker, you should thus \fBnot\fP add that as a part of the header +content: do not add newlines or carriage returns, they will only mess things up +for you. + +Starting in 7.55.0, this option can take an argument in @filename style, which +then adds a header for each line in the input file. Using @- will make curl +read the header file from stdin. + +See also the --user-agent and --referer options. + +Starting in 7.37.0, you need --proxy-header to send custom headers intended +for a proxy. + +Example: + + curl -H "X-First-Name: Joe" http://example.com/ + +\fBWARNING\fP: headers set with this option will be set in all requests - even +after redirects are followed, like when told with --location. This can lead to +the header being sent to other hosts than the original host, so sensitive +headers should be used with caution combined with following redirects. + +This option can be used multiple times to add/replace/remove multiple headers. diff --git a/docs/cmdline-opts/help.d b/docs/cmdline-opts/help.d new file mode 100644 index 00000000..64aa696d --- /dev/null +++ b/docs/cmdline-opts/help.d @@ -0,0 +1,6 @@ +Long: help +Short: h +Help: This help text +--- +Usage help. This lists all current command line options with a short +description. diff --git a/docs/cmdline-opts/hostpubmd5.d b/docs/cmdline-opts/hostpubmd5.d new file mode 100644 index 00000000..a8511580 --- /dev/null +++ b/docs/cmdline-opts/hostpubmd5.d @@ -0,0 +1,9 @@ +Long: hostpubmd5 +Arg: +Help: Acceptable MD5 hash of the host public key +Protocols: SFTP SCP +Added: 7.17.1 +--- +Pass a string containing 32 hexadecimal digits. The string should +be the 128 bit MD5 checksum of the remote host's public key, curl will refuse +the connection with the host unless the md5sums match. diff --git a/docs/cmdline-opts/http1.0.d b/docs/cmdline-opts/http1.0.d new file mode 100644 index 00000000..d9bbd76f --- /dev/null +++ b/docs/cmdline-opts/http1.0.d @@ -0,0 +1,10 @@ +Short: 0 +Long: http1.0 +Tags: Versions +Protocols: HTTP +Added: +Mutexed: http1.1 http2 +Help: Use HTTP 1.0 +--- +Tells curl to use HTTP version 1.0 instead of using its internally preferred +HTTP version. diff --git a/docs/cmdline-opts/http1.1.d b/docs/cmdline-opts/http1.1.d new file mode 100644 index 00000000..f1e6b5c3 --- /dev/null +++ b/docs/cmdline-opts/http1.1.d @@ -0,0 +1,8 @@ +Long: http1.1 +Tags: Versions +Protocols: HTTP +Added: 7.33.0 +Mutexed: http1.0 http2 +Help: Use HTTP 1.1 +--- +Tells curl to use HTTP version 1.1. diff --git a/docs/cmdline-opts/http2-prior-knowledge.d b/docs/cmdline-opts/http2-prior-knowledge.d new file mode 100644 index 00000000..f793f775 --- /dev/null +++ b/docs/cmdline-opts/http2-prior-knowledge.d @@ -0,0 +1,12 @@ +Long: http2-prior-knowledge +Tags: Versions +Protocols: HTTP +Added: 7.49.0 +Mutexed: http1.1 http1.0 http2 +Requires: HTTP/2 +Help: Use HTTP 2 without HTTP/1.1 Upgrade +--- +Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1 +Upgrade. It requires prior knowledge that the server supports HTTP/2 straight +away. HTTPS requests will still do HTTP/2 the standard way with negotiated +protocol version in the TLS handshake. diff --git a/docs/cmdline-opts/http2.d b/docs/cmdline-opts/http2.d new file mode 100644 index 00000000..04cff00a --- /dev/null +++ b/docs/cmdline-opts/http2.d @@ -0,0 +1,10 @@ +Long: http2 +Tags: Versions +Protocols: HTTP +Added: 7.33.0 +Mutexed: http1.1 http1.0 http2-prior-knowledge +Requires: HTTP/2 +See-also: no-alpn +Help: Use HTTP 2 +--- +Tells curl to use HTTP version 2. diff --git a/docs/cmdline-opts/ignore-content-length.d b/docs/cmdline-opts/ignore-content-length.d new file mode 100644 index 00000000..53524f51 --- /dev/null +++ b/docs/cmdline-opts/ignore-content-length.d @@ -0,0 +1,10 @@ +Long: ignore-content-length +Help: Ignore the size of the remote resource +Protocols: FTP HTTP +--- +For HTTP, Ignore the Content-Length header. This is particularly useful for +servers running Apache 1.x, which will report incorrect Content-Length for +files larger than 2 gigabytes. + +For FTP (since 7.46.0), skip the RETR command to figure out the size before +downloading a file. diff --git a/docs/cmdline-opts/include.d b/docs/cmdline-opts/include.d new file mode 100644 index 00000000..9d282dd1 --- /dev/null +++ b/docs/cmdline-opts/include.d @@ -0,0 +1,10 @@ +Long: include +Short: i +Help: Include protocol response headers in the output +See-also: verbose +--- +Include the HTTP response headers in the output. The HTTP response headers can +include things like server name, cookies, date of the document, HTTP version +and more... + +To view the request headers, consider the --verbose option. diff --git a/docs/cmdline-opts/insecure.d b/docs/cmdline-opts/insecure.d new file mode 100644 index 00000000..49b0a432 --- /dev/null +++ b/docs/cmdline-opts/insecure.d @@ -0,0 +1,16 @@ +Long: insecure +Short: k +Help: Allow insecure server connections when using SSL +Protocols: TLS +See-also: proxy-insecure cacert +--- + +By default, every SSL connection curl makes is verified to be secure. This +option allows curl to proceed and operate even for server connections +otherwise considered insecure. + +The server connection is verified by making sure the server's certificate +contains the right name and verifies successfully using the cert store. + +See this online resource for further details: + https://curl.haxx.se/docs/sslcerts.html diff --git a/docs/cmdline-opts/interface.d b/docs/cmdline-opts/interface.d new file mode 100644 index 00000000..65827fb8 --- /dev/null +++ b/docs/cmdline-opts/interface.d @@ -0,0 +1,16 @@ +Long: interface +Arg: +Help: Use network INTERFACE (or address) +See-also: dns-interface +--- + +Perform an operation using a specified interface. You can enter interface +name, IP address or host name. An example could look like: + + curl --interface eth0:1 https://www.example.com/ + +If this option is used several times, the last one will be used. + +On Linux it can be used to specify a VRF, but the binary needs to either +have CAP_NET_RAW or to be run as root. More information about Linux VRF: +https://www.kernel.org/doc/Documentation/networking/vrf.txt diff --git a/docs/cmdline-opts/ipv4.d b/docs/cmdline-opts/ipv4.d new file mode 100644 index 00000000..9c40c8c3 --- /dev/null +++ b/docs/cmdline-opts/ipv4.d @@ -0,0 +1,12 @@ +Short: 4 +Long: ipv4 +Tags: Versions +Protocols: +Added: +Mutexed: ipv6 +Requires: +See-also: http1.1 http2 +Help: Resolve names to IPv4 addresses +--- +This option tells curl to resolve names to IPv4 addresses only, and not for +example try IPv6. diff --git a/docs/cmdline-opts/ipv6.d b/docs/cmdline-opts/ipv6.d new file mode 100644 index 00000000..c2392e77 --- /dev/null +++ b/docs/cmdline-opts/ipv6.d @@ -0,0 +1,12 @@ +Short: 6 +Long: ipv6 +Tags: Versions +Protocols: +Added: +Mutexed: ipv6 +Requires: +See-also: http1.1 http2 +Help: Resolve names to IPv6 addresses +--- +This option tells curl to resolve names to IPv6 addresses only, and not for +example try IPv4. diff --git a/docs/cmdline-opts/junk-session-cookies.d b/docs/cmdline-opts/junk-session-cookies.d new file mode 100644 index 00000000..40ccd9c2 --- /dev/null +++ b/docs/cmdline-opts/junk-session-cookies.d @@ -0,0 +1,10 @@ +Long: junk-session-cookies +Short: j +Help: Ignore session cookies read from file +Protocols: HTTP +See-also: cookie cookie-jar +--- +When curl is told to read cookies from a given file, this option will make it +discard all "session cookies". This will basically have the same effect as if +a new session is started. Typical browsers always discard session cookies when +they're closed down. diff --git a/docs/cmdline-opts/keepalive-time.d b/docs/cmdline-opts/keepalive-time.d new file mode 100644 index 00000000..c816e13f --- /dev/null +++ b/docs/cmdline-opts/keepalive-time.d @@ -0,0 +1,13 @@ +Long: keepalive-time +Arg: +Help: Interval time for keepalive probes +Added: 7.18.0 +--- +This option sets the time a connection needs to remain idle before sending +keepalive probes and the time between individual keepalive probes. It is +currently effective on operating systems offering the TCP_KEEPIDLE and +TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This +option has no effect if --no-keepalive is used. + +If this option is used several times, the last one will be used. If +unspecified, the option defaults to 60 seconds. diff --git a/docs/cmdline-opts/key-type.d b/docs/cmdline-opts/key-type.d new file mode 100644 index 00000000..bf39bcd3 --- /dev/null +++ b/docs/cmdline-opts/key-type.d @@ -0,0 +1,9 @@ +Long: key-type +Arg: +Help: Private key file type (DER/PEM/ENG) +Protocols: TLS +--- +Private key file type. Specify which type your --key provided private key +is. DER, PEM, and ENG are supported. If not specified, PEM is assumed. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/key.d b/docs/cmdline-opts/key.d new file mode 100644 index 00000000..fbf583af --- /dev/null +++ b/docs/cmdline-opts/key.d @@ -0,0 +1,10 @@ +Long: key +Arg: +Protocols: TLS SSH +Help: Private key file name +--- +Private key file name. Allows you to provide your private key in this separate +file. For SSH, if not specified, curl tries the following candidates in order: +'~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/krb.d b/docs/cmdline-opts/krb.d new file mode 100644 index 00000000..19547af0 --- /dev/null +++ b/docs/cmdline-opts/krb.d @@ -0,0 +1,11 @@ +Long: krb +Arg: +Help: Enable Kerberos with security +Protocols: FTP +Requires: Kerberos +--- +Enable Kerberos authentication and use. The level must be entered and should +be one of 'clear', 'safe', 'confidential', or 'private'. Should you use a +level that is not one of these, 'private' will instead be used. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/libcurl.d b/docs/cmdline-opts/libcurl.d new file mode 100644 index 00000000..ef132fe7 --- /dev/null +++ b/docs/cmdline-opts/libcurl.d @@ -0,0 +1,11 @@ +Long: libcurl +Arg: +Help: Dump libcurl equivalent code of this command line +Added: 7.16.1 +--- +Append this option to any ordinary curl command line, and you will get a +libcurl-using C source code written to the file that does the equivalent +of what your command-line operation does! + +If this option is used several times, the last given file name will be +used. diff --git a/docs/cmdline-opts/limit-rate.d b/docs/cmdline-opts/limit-rate.d new file mode 100644 index 00000000..06c456e3 --- /dev/null +++ b/docs/cmdline-opts/limit-rate.d @@ -0,0 +1,18 @@ +Long: limit-rate +Arg: +Help: Limit transfer speed to RATE +--- +Specify the maximum transfer rate you want curl to use - for both downloads +and uploads. This feature is useful if you have a limited pipe and you'd like +your transfer not to use your entire bandwidth. To make it slower than it +otherwise would be. + +The given speed is measured in bytes/second, unless a suffix is appended. +Appending 'k' or 'K' will count the number as kilobytes, 'm' or 'M' makes it +megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G. + +If you also use the --speed-limit option, that option will take precedence and +might cripple the rate-limiting slightly, to help keeping the speed-limit +logic working. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/list-only.d b/docs/cmdline-opts/list-only.d new file mode 100644 index 00000000..4c56304a --- /dev/null +++ b/docs/cmdline-opts/list-only.d @@ -0,0 +1,24 @@ +Long: list-only +Short: l +Protocols: FTP POP3 +Help: List only mode +Added: 7.21.5 +--- +(FTP) +When listing an FTP directory, this switch forces a name-only view. This is +especially useful if the user wants to machine-parse the contents of an FTP +directory since the normal directory view doesn't use a standard look or +format. When used like this, the option causes a NLST command to be sent to +the server instead of LIST. + +Note: Some FTP servers list only files in their response to NLST; they do not +include sub-directories and symbolic links. + +(POP3) +When retrieving a specific email from POP3, this switch forces a LIST command +to be performed instead of RETR. This is particularly useful if the user wants +to see if a specific message id exists on the server and what size it is. + +Note: When combined with --request, this option can be used to send an UIDL +command instead, so the user may use the email's unique identifier rather than +it's message id to make the request. diff --git a/docs/cmdline-opts/local-port.d b/docs/cmdline-opts/local-port.d new file mode 100644 index 00000000..d96b46eb --- /dev/null +++ b/docs/cmdline-opts/local-port.d @@ -0,0 +1,9 @@ +Long: local-port +Arg: +Help: Force use of RANGE for local port numbers +Added: 7.15.2 +--- +Set a preferred single number or range (FROM-TO) of local port numbers to use +for the connection(s). Note that port numbers by nature are a scarce resource +that will be busy at times so setting this range to something too narrow might +cause unnecessary connection setup failures. diff --git a/docs/cmdline-opts/location-trusted.d b/docs/cmdline-opts/location-trusted.d new file mode 100644 index 00000000..995a8718 --- /dev/null +++ b/docs/cmdline-opts/location-trusted.d @@ -0,0 +1,9 @@ +Long: location-trusted +Help: Like --location, and send auth to other hosts +Protocols: HTTP +See-also: user +--- +Like --location, but will allow sending the name + password to all hosts that +the site may redirect to. This may or may not introduce a security breach if +the site redirects you to a site to which you'll send your authentication info +(which is plaintext in the case of HTTP Basic authentication). diff --git a/docs/cmdline-opts/location.d b/docs/cmdline-opts/location.d new file mode 100644 index 00000000..7c70e698 --- /dev/null +++ b/docs/cmdline-opts/location.d @@ -0,0 +1,23 @@ +Long: location +Short: L +Help: Follow redirects +Protocols: HTTP +--- +If the server reports that the requested page has moved to a different +location (indicated with a Location: header and a 3XX response code), this +option will make curl redo the request on the new place. If used together with +--include or --head, headers from all requested pages will be shown. When +authentication is used, curl only sends its credentials to the initial +host. If a redirect takes curl to a different host, it won't be able to +intercept the user+password. See also --location-trusted on how to change +this. You can limit the amount of redirects to follow by using the +--max-redirs option. + +When curl follows a redirect and the request is not a plain GET (for example +POST or PUT), it will do the following request with a GET if the HTTP response +was 301, 302, or 303. If the response code was any other 3xx code, curl will +re-send the following request using the same unmodified method. + +You can tell curl to not change the non-GET request method to GET after a 30x +response by using the dedicated options for that: --post301, --post302 and +--post303. diff --git a/docs/cmdline-opts/login-options.d b/docs/cmdline-opts/login-options.d new file mode 100644 index 00000000..8bad0511 --- /dev/null +++ b/docs/cmdline-opts/login-options.d @@ -0,0 +1,14 @@ +Long: login-options +Arg: +Protocols: IMAP POP3 SMTP +Help: Server login options +Added: 7.34.0 +--- +Specify the login options to use during server authentication. + +You can use the login options to specify protocol specific options that may +be used during authentication. At present only IMAP, POP3 and SMTP support +login options. For more information about the login options please see +RFC 2384, RFC 5092 and IETF draft draft-earhart-url-smtp-00.txt + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/mail-auth.d b/docs/cmdline-opts/mail-auth.d new file mode 100644 index 00000000..70cf0eda --- /dev/null +++ b/docs/cmdline-opts/mail-auth.d @@ -0,0 +1,10 @@ +Long: mail-auth +Arg:
+Protocols: SMTP +Help: Originator address of the original email +Added: 7.25.0 +See-also: mail-rcpt mail-from +--- +Specify a single address. This will be used to specify the authentication +address (identity) of a submitted message that is being relayed to another +server. diff --git a/docs/cmdline-opts/mail-from.d b/docs/cmdline-opts/mail-from.d new file mode 100644 index 00000000..1d932344 --- /dev/null +++ b/docs/cmdline-opts/mail-from.d @@ -0,0 +1,8 @@ +Long: mail-from +Arg:
+Help: Mail from this address +Protocols: SMTP +Added: 7.20.0 +See-also: mail-rcpt mail-auth +--- +Specify a single address that the given mail should get sent from. diff --git a/docs/cmdline-opts/mail-rcpt.d b/docs/cmdline-opts/mail-rcpt.d new file mode 100644 index 00000000..0a2859b6 --- /dev/null +++ b/docs/cmdline-opts/mail-rcpt.d @@ -0,0 +1,19 @@ +Long: mail-rcpt +Arg:
+Help: Mail to this address +Protocols: SMTP +Added: 7.20.0 +--- +Specify a single address, user name or mailing list name. Repeat this +option several times to send to multiple recipients. + +When performing a mail transfer, the recipient should specify a valid email +address to send the mail to. + +When performing an address verification (VRFY command), the recipient should be +specified as the user name or user name and domain (as per Section 3.5 of +RFC5321). (Added in 7.34.0) + +When performing a mailing list expand (EXPN command), the recipient should be +specified using the mailing list name, such as "Friends" or "London-Office". +(Added in 7.34.0) diff --git a/docs/cmdline-opts/manual.d b/docs/cmdline-opts/manual.d new file mode 100644 index 00000000..a9dbb0c7 --- /dev/null +++ b/docs/cmdline-opts/manual.d @@ -0,0 +1,5 @@ +Long: manual +Short: M +Help: Display the full manual +--- +Manual. Display the huge help text. diff --git a/docs/cmdline-opts/max-filesize.d b/docs/cmdline-opts/max-filesize.d new file mode 100644 index 00000000..50d5266e --- /dev/null +++ b/docs/cmdline-opts/max-filesize.d @@ -0,0 +1,16 @@ +Long: max-filesize +Arg: +Help: Maximum file size to download +See-also: limit-rate +--- +Specify the maximum size (in bytes) of a file to download. If the file +requested is larger than this value, the transfer will not start and curl will +return with exit code 63. + +A size modifier may be used. For example, Appending 'k' or 'K' will count the +number as kilobytes, 'm' or 'M' makes it megabytes, while 'g' or 'G' makes it +gigabytes. Examples: 200K, 3m and 1G. (Added in 7.58.0) + +\fBNOTE:\fP The file size is not always known prior to download, and for such +files this option has no effect even if the file transfer ends up being larger +than this given limit. This concerns both FTP and HTTP transfers. diff --git a/docs/cmdline-opts/max-redirs.d b/docs/cmdline-opts/max-redirs.d new file mode 100644 index 00000000..04b824bd --- /dev/null +++ b/docs/cmdline-opts/max-redirs.d @@ -0,0 +1,11 @@ +Long: max-redirs +Arg: +Help: Maximum number of redirects allowed +Protocols: HTTP +--- +Set maximum number of redirection-followings allowed. When --location is used, +is used to prevent curl from following redirections \&"in absurdum". By +default, the limit is set to 50 redirections. Set this option to -1 to make it +unlimited. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/max-time.d b/docs/cmdline-opts/max-time.d new file mode 100644 index 00000000..0057f9d0 --- /dev/null +++ b/docs/cmdline-opts/max-time.d @@ -0,0 +1,13 @@ +Long: max-time +Short: m +Arg: +Help: Maximum time allowed for the transfer +See-also: connect-timeout +--- +Maximum time in seconds that you allow the whole operation to take. This is +useful for preventing your batch jobs from hanging for hours due to slow +networks or links going down. Since 7.32.0, this option accepts decimal +values, but the actual timeout will decrease in accuracy as the specified +timeout increases in decimal precision. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/metalink.d b/docs/cmdline-opts/metalink.d new file mode 100644 index 00000000..8047e9f5 --- /dev/null +++ b/docs/cmdline-opts/metalink.d @@ -0,0 +1,27 @@ +Long: metalink +Help: Process given URLs as metalink XML file +Added: 7.27.0 +Requires: metalink +--- +This option can tell curl to parse and process a given URI as Metalink file +(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors +listed within for failover if there are errors (such as the file or server not +being available). It will also verify the hash of the file after the download +completes. The Metalink file itself is downloaded and processed in memory and +not stored in the local file system. + +Example to use a remote Metalink file: + + curl --metalink http://www.example.com/example.metalink + +To use a Metalink file in the local file system, use FILE protocol (file://): + + curl --metalink file://example.metalink + +Please note that if FILE protocol is disabled, there is no way to use a local +Metalink file at the time of this writing. Also note that if --metalink and +--include are used together, --include will be ignored. This is because +including headers in the response will break Metalink parser and if the +headers are included in the file described in Metalink file, hash check will +fail. + diff --git a/docs/cmdline-opts/negotiate.d b/docs/cmdline-opts/negotiate.d new file mode 100644 index 00000000..69a6b917 --- /dev/null +++ b/docs/cmdline-opts/negotiate.d @@ -0,0 +1,15 @@ +Long: negotiate +Help: Use HTTP Negotiate (SPNEGO) authentication +Protocols: HTTP +See-also: basic ntlm anyauth proxy-negotiate +--- +Enables Negotiate (SPNEGO) authentication. + +This option requires a library built with GSS-API or SSPI support. Use +--version to see if your curl supports GSS-API/SSPI or SPNEGO. + +When using this option, you must also provide a fake --user option to activate +the authentication code properly. Sending a '-u :' is enough as the user name +and password from the --user option aren't actually used. + +If this option is used several times, only the first one is used. diff --git a/docs/cmdline-opts/netrc-file.d b/docs/cmdline-opts/netrc-file.d new file mode 100644 index 00000000..0b5d2400 --- /dev/null +++ b/docs/cmdline-opts/netrc-file.d @@ -0,0 +1,12 @@ +Long: netrc-file +Help: Specify FILE for netrc +Arg: +Added: 7.21.5 +Mutexed: netrc +--- +This option is similar to --netrc, except that you provide the path (absolute +or relative) to the netrc file that Curl should use. You can only specify one +netrc file per invocation. If several --netrc-file options are provided, +the last one will be used. + +It will abide by --netrc-optional if specified. diff --git a/docs/cmdline-opts/netrc-optional.d b/docs/cmdline-opts/netrc-optional.d new file mode 100644 index 00000000..c2854030 --- /dev/null +++ b/docs/cmdline-opts/netrc-optional.d @@ -0,0 +1,7 @@ +Long: netrc-optional +Help: Use either .netrc or URL +Mutexed: netrc +See-also: netrc-file +--- +Very similar to --netrc, but this option makes the .netrc usage \fBoptional\fP +and not mandatory as the --netrc option does. diff --git a/docs/cmdline-opts/netrc.d b/docs/cmdline-opts/netrc.d new file mode 100644 index 00000000..2df26782 --- /dev/null +++ b/docs/cmdline-opts/netrc.d @@ -0,0 +1,17 @@ +Long: netrc +Short: n +Help: Must read .netrc for user name and password +--- +Makes curl scan the \fI.netrc\fP (\fI_netrc\fP on Windows) file in the user's +home directory for login name and password. This is typically used for FTP on +Unix. If used with HTTP, curl will enable user authentication. See +\fInetrc(5)\fP \fIftp(1)\fP for details on the file format. Curl will not +complain if that file doesn't have the right permissions (it should not be +either world- or group-readable). The environment variable "HOME" is used to +find the home directory. + +A quick and very simple example of how to setup a \fI.netrc\fP to allow curl +to FTP to the machine host.domain.com with user name \&'myself' and password +\&'secret' should look similar to: + +.B "machine host.domain.com login myself password secret" diff --git a/docs/cmdline-opts/next.d b/docs/cmdline-opts/next.d new file mode 100644 index 00000000..1d1e70a3 --- /dev/null +++ b/docs/cmdline-opts/next.d @@ -0,0 +1,20 @@ +Short: : +Long: next +Tags: +Protocols: +Added: 7.36.0 +Magic: divider +Help: Make next URL use its separate set of options +--- +Tells curl to use a separate operation for the following URL and associated +options. This allows you to send several URL requests, each with their own +specific options, for example, such as different user names or custom requests +for each. + +--next will reset all local options and only global ones will have their +values survive over to the operation following the --next instruction. Global +options include --verbose, --trace, --trace-ascii and --fail-early. + +For example, you can do both a GET and a POST in a single command line: + + curl www1.example.com --next -d postthis www2.example.com diff --git a/docs/cmdline-opts/no-alpn.d b/docs/cmdline-opts/no-alpn.d new file mode 100644 index 00000000..88abb836 --- /dev/null +++ b/docs/cmdline-opts/no-alpn.d @@ -0,0 +1,11 @@ +Long: no-alpn +Tags: HTTP/2 +Protocols: HTTPS +Added: 7.36.0 +See-also: no-npn http2 +Requires: TLS +Help: Disable the ALPN TLS extension +--- +Disable the ALPN TLS extension. ALPN is enabled by default if libcurl was built +with an SSL library that supports ALPN. ALPN is used by a libcurl that supports +HTTP/2 to negotiate HTTP/2 support with the server during https sessions. diff --git a/docs/cmdline-opts/no-buffer.d b/docs/cmdline-opts/no-buffer.d new file mode 100644 index 00000000..65a6282f --- /dev/null +++ b/docs/cmdline-opts/no-buffer.d @@ -0,0 +1,11 @@ +Long: no-buffer +Short: N +Help: Disable buffering of the output stream +--- +Disables the buffering of the output stream. In normal work situations, curl +will use a standard buffered output stream that will have the effect that it +will output the data in chunks, not necessarily exactly when the data arrives. +Using this option will disable that buffering. + +Note that this is the negated option name documented. You can thus use +--buffer to enforce the buffering. diff --git a/docs/cmdline-opts/no-keepalive.d b/docs/cmdline-opts/no-keepalive.d new file mode 100644 index 00000000..8fb28a03 --- /dev/null +++ b/docs/cmdline-opts/no-keepalive.d @@ -0,0 +1,8 @@ +Long: no-keepalive +Help: Disable TCP keepalive on the connection +--- +Disables the use of keepalive messages on the TCP connection. curl otherwise +enables them by default. + +Note that this is the negated option name documented. You can thus use +--keepalive to enforce keepalive. diff --git a/docs/cmdline-opts/no-npn.d b/docs/cmdline-opts/no-npn.d new file mode 100644 index 00000000..ab0f6de2 --- /dev/null +++ b/docs/cmdline-opts/no-npn.d @@ -0,0 +1,12 @@ +Long: no-npn +Tags: Versions HTTP/2 +Protocols: HTTPS +Added: 7.36.0 +Mutexed: +See-also: no-alpn http2 +Requires: TLS +Help: Disable the NPN TLS extension +--- +Disable the NPN TLS extension. NPN is enabled by default if libcurl was built +with an SSL library that supports NPN. NPN is used by a libcurl that supports +HTTP/2 to negotiate HTTP/2 support with the server during https sessions. diff --git a/docs/cmdline-opts/no-sessionid.d b/docs/cmdline-opts/no-sessionid.d new file mode 100644 index 00000000..397a1586 --- /dev/null +++ b/docs/cmdline-opts/no-sessionid.d @@ -0,0 +1,13 @@ +Long: no-sessionid +Help: Disable SSL session-ID reusing +Protocols: TLS +Added: 7.16.0 +--- +Disable curl's use of SSL session-ID caching. By default all transfers are +done using the cache. Note that while nothing should ever get hurt by +attempting to reuse SSL session-IDs, there seem to be broken SSL +implementations in the wild that may require you to disable this in order for +you to succeed. + +Note that this is the negated option name documented. You can thus use +--sessionid to enforce session-ID caching. diff --git a/docs/cmdline-opts/noproxy.d b/docs/cmdline-opts/noproxy.d new file mode 100644 index 00000000..a216e75f --- /dev/null +++ b/docs/cmdline-opts/noproxy.d @@ -0,0 +1,15 @@ +Long: noproxy +Arg: +Help: List of hosts which do not use proxy +Added: 7.19.4 +--- +Comma-separated list of hosts which do not use a proxy, if one is specified. +The only wildcard is a single * character, which matches all hosts, and +effectively disables the proxy. Each name in this list is matched as either +a domain which contains the hostname, or the hostname itself. For example, +local.com would match local.com, local.com:80, and www.local.com, but not +www.notlocal.com. + +Since 7.53.0, This option overrides the environment variables that disable the +proxy. If there's an environment variable disabling a proxy, you can set +noproxy list to \&"" to override it. diff --git a/docs/cmdline-opts/ntlm-wb.d b/docs/cmdline-opts/ntlm-wb.d new file mode 100644 index 00000000..7b933840 --- /dev/null +++ b/docs/cmdline-opts/ntlm-wb.d @@ -0,0 +1,7 @@ +Long: ntlm-wb +Help: Use HTTP NTLM authentication with winbind +Protocols: HTTP +See-also: ntlm proxy-ntlm +--- +Enables NTLM much in the style --ntlm does, but hand over the authentication +to the separate binary ntlmauth application that is executed when needed. diff --git a/docs/cmdline-opts/ntlm.d b/docs/cmdline-opts/ntlm.d new file mode 100644 index 00000000..baaa1d53 --- /dev/null +++ b/docs/cmdline-opts/ntlm.d @@ -0,0 +1,18 @@ +Long: ntlm +Help: Use HTTP NTLM authentication +Mutexed: basic negotiate digest anyauth +See-also: proxy-ntlm +Protocols: HTTP +Requires: TLS +--- +Enables NTLM authentication. The NTLM authentication method was designed by +Microsoft and is used by IIS web servers. It is a proprietary protocol, +reverse-engineered by clever people and implemented in curl based on their +efforts. This kind of behavior should not be endorsed, you should encourage +everyone who uses NTLM to switch to a public and documented authentication +method instead, such as Digest. + +If you want to enable NTLM for your proxy authentication, then use +--proxy-ntlm. + +If this option is used several times, only the first one is used. diff --git a/docs/cmdline-opts/oauth2-bearer.d b/docs/cmdline-opts/oauth2-bearer.d new file mode 100644 index 00000000..78071674 --- /dev/null +++ b/docs/cmdline-opts/oauth2-bearer.d @@ -0,0 +1,12 @@ +Long: oauth2-bearer +Help: OAuth 2 Bearer Token +Arg: +Protocols: IMAP POP3 SMTP +--- +Specify the Bearer Token for OAUTH 2.0 server authentication. The Bearer Token +is used in conjunction with the user name which can be specified as part of +the --url or --user options. + +The Bearer Token and user name are formatted according to RFC 6750. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/output.d b/docs/cmdline-opts/output.d new file mode 100644 index 00000000..35f52a21 --- /dev/null +++ b/docs/cmdline-opts/output.d @@ -0,0 +1,32 @@ +Long: output +Arg: +Short: o +Help: Write to file instead of stdout +See-also: remote-name remote-name-all remote-header-name +--- +Write output to instead of stdout. If you are using {} or [] to fetch +multiple documents, you can use '#' followed by a number in the +specifier. That variable will be replaced with the current string for the URL +being fetched. Like in: + + curl http://{one,two}.example.com -o "file_#1.txt" + +or use several variables like: + + curl http://{site,host}.host[1-5].com -o "#1_#2" + +You may use this option as many times as the number of URLs you have. For +example, if you specify two URLs on the same command line, you can use it like +this: + + curl -o aa example.com -o bb example.net + +and the order of the -o options and the URLs doesn't matter, just that the +first -o is for the first URL and so on, so the above command line can also be +written as + + curl example.com example.net -o aa -o bb + +See also the --create-dirs option to create the local directories +dynamically. Specifying the output as '-' (a single dash) will force the +output to be done to stdout. diff --git a/docs/cmdline-opts/page-footer b/docs/cmdline-opts/page-footer new file mode 100644 index 00000000..89bface6 --- /dev/null +++ b/docs/cmdline-opts/page-footer @@ -0,0 +1,255 @@ +.SH FILES +.I ~/.curlrc +.RS +Default config file, see --config for details. +.SH ENVIRONMENT +The environment variables can be specified in lower case or upper case. The +lower case version has precedence. http_proxy is an exception as it is only +available in lower case. + +Using an environment variable to set the proxy has the same effect as using +the --proxy option. + +.IP "http_proxy [protocol://][:port]" +Sets the proxy server to use for HTTP. +.IP "HTTPS_PROXY [protocol://][:port]" +Sets the proxy server to use for HTTPS. +.IP "[url-protocol]_PROXY [protocol://][:port]" +Sets the proxy server to use for [url-protocol], where the protocol is a +protocol that curl supports and as specified in a URL. FTP, FTPS, POP3, IMAP, +SMTP, LDAP etc. +.IP "ALL_PROXY [protocol://][:port]" +Sets the proxy server to use if no protocol-specific proxy is set. +.IP "NO_PROXY " +list of host names that shouldn't go through any proxy. If set to an asterisk +\&'*' only, it matches all hosts. + +This environment variable disables use of the proxy even when specified with +the --proxy option. That is +.B NO_PROXY=direct.example.com curl -x http://proxy.example.com +.B http://direct.example.com +accesses the target URL directly, and +.B NO_PROXY=direct.example.com curl -x http://proxy.example.com +.B http://somewhere.example.com +accesses the target URL through the proxy. + +The list of host names can also be include numerical IP addresses, and IPv6 +versions should then be given without enclosing brackets. + +.SH "PROXY PROTOCOL PREFIXES" +Since curl version 7.21.7, the proxy string may be specified with a +protocol:// prefix to specify alternative proxy protocols. + +If no protocol is specified in the proxy string or if the string doesn't match +a supported one, the proxy will be treated as an HTTP proxy. + +The supported proxy protocol prefixes are as follows: +.IP "http://" +Makes it use it as an HTTP proxy. The default if no scheme prefix is used. +.IP "https://" +Makes it treated as an \fBHTTPS\fP proxy. +.IP "socks4://" +Makes it the equivalent of --socks4 +.IP "socks4a://" +Makes it the equivalent of --socks4a +.IP "socks5://" +Makes it the equivalent of --socks5 +.IP "socks5h://" +Makes it the equivalent of --socks5-hostname +.SH EXIT CODES +There are a bunch of different error codes and their corresponding error +messages that may appear during bad conditions. At the time of this writing, +the exit codes are: +.IP 1 +Unsupported protocol. This build of curl has no support for this protocol. +.IP 2 +Failed to initialize. +.IP 3 +URL malformed. The syntax was not correct. +.IP 4 +A feature or option that was needed to perform the desired request was not +enabled or was explicitly disabled at build-time. To make curl able to do +this, you probably need another build of libcurl! +.IP 5 +Couldn't resolve proxy. The given proxy host could not be resolved. +.IP 6 +Couldn't resolve host. The given remote host was not resolved. +.IP 7 +Failed to connect to host. +.IP 8 +Weird server reply. The server sent data curl couldn't parse. +.IP 9 +FTP access denied. The server denied login or denied access to the particular +resource or directory you wanted to reach. Most often you tried to change to a +directory that doesn't exist on the server. +.IP 10 +FTP accept failed. While waiting for the server to connect back when an active +FTP session is used, an error code was sent over the control connection or +similar. +.IP 11 +FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request. +.IP 12 +During an active FTP session while waiting for the server to connect back to +curl, the timeout expired. +.IP 13 +FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request. +.IP 14 +FTP weird 227 format. Curl couldn't parse the 227-line the server sent. +.IP 15 +FTP can't get host. Couldn't resolve the host IP we got in the 227-line. +.IP 16 +HTTP/2 error. A problem was detected in the HTTP2 framing layer. This is +somewhat generic and can be one out of several problems, see the error message +for details. +.IP 17 +FTP couldn't set binary. Couldn't change transfer method to binary. +.IP 18 +Partial file. Only a part of the file was transferred. +.IP 19 +FTP couldn't download/access the given file, the RETR (or similar) command +failed. +.IP 21 +FTP quote error. A quote command returned error from the server. +.IP 22 +HTTP page not retrieved. The requested url was not found or returned another +error with the HTTP error code being 400 or above. This return code only +appears if --fail is used. +.IP 23 +Write error. Curl couldn't write data to a local filesystem or similar. +.IP 25 +FTP couldn't STOR file. The server denied the STOR operation, used for FTP +uploading. +.IP 26 +Read error. Various reading problems. +.IP 27 +Out of memory. A memory allocation request failed. +.IP 28 +Operation timeout. The specified time-out period was reached according to the +conditions. +.IP 30 +FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT +command, try doing a transfer using PASV instead! +.IP 31 +FTP couldn't use REST. The REST command failed. This command is used for +resumed FTP transfers. +.IP 33 +HTTP range error. The range "command" didn't work. +.IP 34 +HTTP post error. Internal post-request generation error. +.IP 35 +SSL connect error. The SSL handshaking failed. +.IP 36 +Bad download resume. Couldn't continue an earlier aborted download. +.IP 37 +FILE couldn't read file. Failed to open the file. Permissions? +.IP 38 +LDAP cannot bind. LDAP bind operation failed. +.IP 39 +LDAP search failed. +.IP 41 +Function not found. A required LDAP function was not found. +.IP 42 +Aborted by callback. An application told curl to abort the operation. +.IP 43 +Internal error. A function was called with a bad parameter. +.IP 45 +Interface error. A specified outgoing interface could not be used. +.IP 47 +Too many redirects. When following redirects, curl hit the maximum amount. +.IP 48 +Unknown option specified to libcurl. This indicates that you passed a weird +option to curl that was passed on to libcurl and rejected. Read up in the +manual! +.IP 49 +Malformed telnet option. +.IP 51 +The peer's SSL certificate or SSH MD5 fingerprint was not OK. +.IP 52 +The server didn't reply anything, which here is considered an error. +.IP 53 +SSL crypto engine not found. +.IP 54 +Cannot set SSL crypto engine as default. +.IP 55 +Failed sending network data. +.IP 56 +Failure in receiving network data. +.IP 58 +Problem with the local certificate. +.IP 59 +Couldn't use specified SSL cipher. +.IP 60 +Peer certificate cannot be authenticated with known CA certificates. +.IP 61 +Unrecognized transfer encoding. +.IP 62 +Invalid LDAP URL. +.IP 63 +Maximum file size exceeded. +.IP 64 +Requested FTP SSL level failed. +.IP 65 +Sending the data requires a rewind that failed. +.IP 66 +Failed to initialise SSL Engine. +.IP 67 +The user name, password, or similar was not accepted and curl failed to log in. +.IP 68 +File not found on TFTP server. +.IP 69 +Permission problem on TFTP server. +.IP 70 +Out of disk space on TFTP server. +.IP 71 +Illegal TFTP operation. +.IP 72 +Unknown TFTP transfer ID. +.IP 73 +File already exists (TFTP). +.IP 74 +No such user (TFTP). +.IP 75 +Character conversion failed. +.IP 76 +Character conversion functions required. +.IP 77 +Problem with reading the SSL CA cert (path? access rights?). +.IP 78 +The resource referenced in the URL does not exist. +.IP 79 +An unspecified error occurred during the SSH session. +.IP 80 +Failed to shut down the SSL connection. +.IP 82 +Could not load CRL file, missing or wrong format (added in 7.19.0). +.IP 83 +Issuer check failed (added in 7.19.0). +.IP 84 +The FTP PRET command failed +.IP 85 +RTSP: mismatch of CSeq numbers +.IP 86 +RTSP: mismatch of Session Identifiers +.IP 87 +unable to parse FTP file list +.IP 88 +FTP chunk callback reported error +.IP 89 +No connection available, the session will be queued +.IP 90 +SSL public key does not matched pinned public key +.IP 91 +Invalid SSL certificate status. +.IP 92 +Stream error in HTTP/2 framing layer. +.IP XX +More error codes will appear here in future releases. The existing ones +are meant to never change. +.SH AUTHORS / CONTRIBUTORS +Daniel Stenberg is the main author, but the whole list of contributors is +found in the separate THANKS file. +.SH WWW +https://curl.haxx.se +.SH "SEE ALSO" +.BR ftp (1), +.BR wget (1) diff --git a/docs/cmdline-opts/page-header b/docs/cmdline-opts/page-header new file mode 100644 index 00000000..51f45eda --- /dev/null +++ b/docs/cmdline-opts/page-header @@ -0,0 +1,141 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" ************************************************************************** +.\" +.\" DO NOT EDIT. Generated by the curl project gen.pl man page generator. +.\" +.TH curl 1 "16 Dec 2016" "Curl 7.52.0" "Curl Manual" +.SH NAME +curl \- transfer a URL +.SH SYNOPSIS +.B curl [options / URLs] +.SH DESCRIPTION +.B curl +is a tool to transfer data from or to a server, using one of the supported +protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, +LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET +and TFTP). The command is designed to work without user interaction. + +curl offers a busload of useful tricks like proxy support, user +authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer +resume, Metalink, and more. As you will see below, the number of features will +make your head spin! + +curl is powered by libcurl for all transfer-related features. See +\fIlibcurl(3)\fP for details. +.SH URL +The URL syntax is protocol-dependent. You'll find a detailed description in +RFC 3986. + +You can specify multiple URLs or parts of URLs by writing part sets within +braces as in: + + http://site.{one,two,three}.com + +or you can get sequences of alphanumeric series by using [] as in: + + ftp://ftp.example.com/file[1-100].txt + + ftp://ftp.example.com/file[001-100].txt (with leading zeros) + + ftp://ftp.example.com/file[a-z].txt + +Nested sequences are not supported, but you can use several ones next to each +other: + + http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html + +You can specify any amount of URLs on the command line. They will be fetched +in a sequential manner in the specified order. You can specify command line +options and URLs mixed and in any order on the command line. + +You can specify a step counter for the ranges to get every Nth number or +letter: + + http://example.com/file[1-100:10].txt + + http://example.com/file[a-z:2].txt + +When using [] or {} sequences when invoked from a command line prompt, you +probably have to put the full URL within double quotes to avoid the shell from +interfering with it. This also goes for other characters treated special, like +for example '&', '?' and '*'. + +Provide the IPv6 zone index in the URL with an escaped percentage sign and the +interface name. Like in + + http://[fe80::3%25eth0]/ + +If you specify URL without protocol:// prefix, curl will attempt to guess what +protocol you might want. It will then default to HTTP but try other protocols +based on often-used host name prefixes. For example, for host names starting +with "ftp." curl will assume you want to speak FTP. + +curl will do its best to use what you pass to it as a URL. It is not trying to +validate it as a syntactically correct URL by any means but is instead +\fBvery\fP liberal with what it accepts. + +curl will attempt to re-use connections for multiple file transfers, so that +getting many files from the same server will not do multiple connects / +handshakes. This improves speed. Of course this is only done on files +specified on a single command line and cannot be used between separate curl +invokes. +.SH "PROGRESS METER" +curl normally displays a progress meter during operations, indicating the +amount of transferred data, transfer speeds and estimated time left, etc. The +progress meter displays number of bytes and the speeds are in bytes per +second. The suffixes (k, M, G, T, P) are 1024 based. For example 1k is 1024 +bytes. 1M is 1048576 bytes. + +curl displays this data to the terminal by default, so if you invoke curl to +do an operation and it is about to write data to the terminal, it +\fIdisables\fP the progress meter as otherwise it would mess up the output +mixing progress meter and response data. + +If you want a progress meter for HTTP POST or PUT requests, you need to +redirect the response output to a file, using shell redirect (>), --output or +similar. + +It is not the same case for FTP upload as that operation does not spit out +any response data to the terminal. + +If you prefer a progress "bar" instead of the regular meter, --progress-bar is +your friend. You can also disable the progress meter completely with the +--silent option. +.SH OPTIONS +Options start with one or two dashes. Many of the options require an +additional value next to them. + +The short "single-dash" form of the options, -d for example, may be used with +or without a space between it and its value, although a space is a recommended +separator. The long "double-dash" form, --data for example, requires a space +between it and its value. + +Short version options that don't need any additional values can be used +immediately next to each other, like for example you can specify all the +options -O, -L and -v at once as -OLv. + +In general, all boolean options are enabled with --\fBoption\fP and yet again +disabled with --\fBno-\fPoption. That is, you use the exact same option name +but prefix it with "no-". However, in this list we mostly only list and show +the --option version of them. (This concept with --no options was added in +7.19.0. Previously most options were toggled on/off on repeated use of the +same command line option.) diff --git a/docs/cmdline-opts/pass.d b/docs/cmdline-opts/pass.d new file mode 100644 index 00000000..2639cb9d --- /dev/null +++ b/docs/cmdline-opts/pass.d @@ -0,0 +1,8 @@ +Long: pass +Arg: +Help: Pass phrase for the private key +Protocols: SSH TLS +--- +Passphrase for the private key + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/path-as-is.d b/docs/cmdline-opts/path-as-is.d new file mode 100644 index 00000000..946e2f07 --- /dev/null +++ b/docs/cmdline-opts/path-as-is.d @@ -0,0 +1,7 @@ +Long: path-as-is +Help: Do not squash .. sequences in URL path +Added: 7.42.0 +--- +Tell curl to not handle sequences of /../ or /./ in the given URL +path. Normally curl will squash or merge them according to standards but with +this option set you tell it not to do that. diff --git a/docs/cmdline-opts/pinnedpubkey.d b/docs/cmdline-opts/pinnedpubkey.d new file mode 100644 index 00000000..0657e6e7 --- /dev/null +++ b/docs/cmdline-opts/pinnedpubkey.d @@ -0,0 +1,27 @@ +Long: pinnedpubkey +Arg: +Help: FILE/HASHES Public key to verify peer against +Protocols: TLS +--- +Tells curl to use the specified public key file (or hashes) to verify the +peer. This can be a path to a file which contains a single public key in PEM +or DER format, or any number of base64 encoded sha256 hashes preceded by +\'sha256//\' and separated by \';\' + +When negotiating a TLS or SSL connection, the server sends a certificate +indicating its identity. A public key is extracted from this certificate and +if it does not exactly match the public key provided to this option, curl will +abort the connection before sending or receiving any data. + +PEM/DER support: + 7.39.0: OpenSSL, GnuTLS and GSKit + 7.43.0: NSS and wolfSSL/CyaSSL + 7.47.0: mbedtls + 7.49.0: PolarSSL +sha256 support: + 7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL. + 7.47.0: mbedtls + 7.49.0: PolarSSL +Other SSL backends not supported. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/post301.d b/docs/cmdline-opts/post301.d new file mode 100644 index 00000000..87a9fe7e --- /dev/null +++ b/docs/cmdline-opts/post301.d @@ -0,0 +1,11 @@ +Long: post301 +Help: Do not switch to GET after following a 301 +Protocols: HTTP +See-also: post302 post303 location +Added: 7.17.1 +--- +Tells curl to respect RFC 7231/6.4.2 and not convert POST requests into GET +requests when following a 301 redirection. The non-RFC behaviour is ubiquitous +in web browsers, so curl does the conversion by default to maintain +consistency. However, a server may require a POST to remain a POST after such +a redirection. This option is meaningful only when using --location. diff --git a/docs/cmdline-opts/post302.d b/docs/cmdline-opts/post302.d new file mode 100644 index 00000000..caf0d87f --- /dev/null +++ b/docs/cmdline-opts/post302.d @@ -0,0 +1,11 @@ +Long: post302 +Help: Do not switch to GET after following a 302 +Protocols: HTTP +See-also: post301 post303 location +Added: 7.19.1 +--- +Tells curl to respect RFC 7231/6.4.3 and not convert POST requests into GET +requests when following a 302 redirection. The non-RFC behaviour is ubiquitous +in web browsers, so curl does the conversion by default to maintain +consistency. However, a server may require a POST to remain a POST after such +a redirection. This option is meaningful only when using --location. diff --git a/docs/cmdline-opts/post303.d b/docs/cmdline-opts/post303.d new file mode 100644 index 00000000..44f39e61 --- /dev/null +++ b/docs/cmdline-opts/post303.d @@ -0,0 +1,10 @@ +Long: post303 +Help: Do not switch to GET after following a 303 +Protocols: HTTP +See-also: post302 post301 location +Added: 7.26.0 +--- +Tells curl to violate RFC 7231/6.4.4 and not convert POST requests into GET +requests when following 303 redirections. A server may require a POST to +remain a POST after a 303 redirection. This option is meaningful only when +using --location. diff --git a/docs/cmdline-opts/preproxy.d b/docs/cmdline-opts/preproxy.d new file mode 100644 index 00000000..b8eb77fa --- /dev/null +++ b/docs/cmdline-opts/preproxy.d @@ -0,0 +1,22 @@ +Long: preproxy +Arg: [protocol://]host[:port] +Help: Use this proxy first +Added: 7.52.0 +--- +Use the specified SOCKS proxy before connecting to an HTTP or HTTPS --proxy. In +such a case curl first connects to the SOCKS proxy and then connects (through +SOCKS) to the HTTP or HTTPS proxy. Hence pre proxy. + +The pre proxy string should be specified with a protocol:// prefix to specify +alternative proxy protocols. Use socks4://, socks4a://, socks5:// or +socks5h:// to request the specific SOCKS version to be used. No protocol +specified will make curl default to SOCKS4. + +If the port number is not specified in the proxy string, it is assumed to be +1080. + +User and password that might be provided in the proxy string are URL decoded +by curl. This allows you to pass in special characters such as @ by using %40 +or pass in a colon with %3a. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/progress-bar.d b/docs/cmdline-opts/progress-bar.d new file mode 100644 index 00000000..f27de2d9 --- /dev/null +++ b/docs/cmdline-opts/progress-bar.d @@ -0,0 +1,12 @@ +Short: # +Long: progress-bar +Help: Display transfer progress as a bar +--- +Make curl display transfer progress as a simple progress bar instead of the +standard, more informational, meter. + +This progress bar draws a single line of '#' characters across the screen and +shows a percentage if the transfer size is known. For transfers without a +known size, there will be space ship (-=o=-) that moves back and forth but +only while data is being transferred, with a set of flying hash sign symbols on +top. diff --git a/docs/cmdline-opts/proto-default.d b/docs/cmdline-opts/proto-default.d new file mode 100644 index 00000000..ccc3b85f --- /dev/null +++ b/docs/cmdline-opts/proto-default.d @@ -0,0 +1,18 @@ +Long: proto-default +Help: Use PROTOCOL for any URL missing a scheme +Arg: +Added: 7.45.0 +--- +Tells curl to use \fIprotocol\fP for any URL missing a scheme name. + +Example: + + curl --proto-default https ftp.mozilla.org + +An unknown or unsupported protocol causes error +\fICURLE_UNSUPPORTED_PROTOCOL\fP (1). + +This option does not change the default proxy protocol (http). + +Without this option curl would make a guess based on the host, see --url for +details. diff --git a/docs/cmdline-opts/proto-redir.d b/docs/cmdline-opts/proto-redir.d new file mode 100644 index 00000000..c9eeeab1 --- /dev/null +++ b/docs/cmdline-opts/proto-redir.d @@ -0,0 +1,17 @@ +Long: proto-redir +Arg: +Help: Enable/disable PROTOCOLS on redirect +Added: 7.20.2 +--- +Tells curl to limit what protocols it may use on redirect. Protocols denied by +--proto are not overridden by this option. See --proto for how protocols are +represented. + +Example, allow only HTTP and HTTPS on redirect: + + curl --proto-redir -all,http,https http://example.com + +By default curl will allow all protocols on redirect except several disabled +for security reasons: Since 7.19.4 FILE and SCP are disabled, and since 7.40.0 +SMB and SMBS are also disabled. Specifying \fIall\fP or \fI+all\fP enables all +protocols on redirect, including those disabled for security. diff --git a/docs/cmdline-opts/proto.d b/docs/cmdline-opts/proto.d new file mode 100644 index 00000000..1513fdc0 --- /dev/null +++ b/docs/cmdline-opts/proto.d @@ -0,0 +1,43 @@ +Long: proto +Arg: +Help: Enable/disable PROTOCOLS +See-also: proto-redir proto-default +Added: 7.20.2 +--- +Tells curl to limit what protocols it may use in the transfer. Protocols are +evaluated left to right, are comma separated, and are each a protocol name or +'all', optionally prefixed by zero or more modifiers. Available modifiers are: +.RS +.TP 3 +.B + +Permit this protocol in addition to protocols already permitted (this is +the default if no modifier is used). +.TP +.B - +Deny this protocol, removing it from the list of protocols already permitted. +.TP +.B = +Permit only this protocol (ignoring the list already permitted), though +subject to later modification by subsequent entries in the comma separated +list. +.RE +.IP +For example: +.RS +.TP 15 +.B --proto -ftps +uses the default protocols, but disables ftps +.TP +.B --proto -all,https,+http +only enables http and https +.TP +.B --proto =http,https +also only enables http and https +.RE + +Unknown protocols produce a warning. This allows scripts to safely rely on +being able to disable potentially dangerous protocols, without relying upon +support for that protocol being built into curl to avoid an error. + +This option can be used multiple times, in which case the effect is the same +as concatenating the protocols into one instance of the option. diff --git a/docs/cmdline-opts/proxy-anyauth.d b/docs/cmdline-opts/proxy-anyauth.d new file mode 100644 index 00000000..b60d0a05 --- /dev/null +++ b/docs/cmdline-opts/proxy-anyauth.d @@ -0,0 +1,7 @@ +Long: proxy-anyauth +Help: Pick any proxy authentication method +Added: 7.13.2 +See-also: proxy proxy-basic proxy-digest +--- +Tells curl to pick a suitable authentication method when communicating with +the given HTTP proxy. This might cause an extra request/response round-trip. diff --git a/docs/cmdline-opts/proxy-basic.d b/docs/cmdline-opts/proxy-basic.d new file mode 100644 index 00000000..566f890a --- /dev/null +++ b/docs/cmdline-opts/proxy-basic.d @@ -0,0 +1,7 @@ +Long: proxy-basic +Help: Use Basic authentication on the proxy +See-also: proxy proxy-anyauth proxy-digest +--- +Tells curl to use HTTP Basic authentication when communicating with the given +proxy. Use --basic for enabling HTTP Basic with a remote host. Basic is the +default authentication method curl uses with proxies. diff --git a/docs/cmdline-opts/proxy-cacert.d b/docs/cmdline-opts/proxy-cacert.d new file mode 100644 index 00000000..2713dd2a --- /dev/null +++ b/docs/cmdline-opts/proxy-cacert.d @@ -0,0 +1,7 @@ +Long: proxy-cacert +Help: CA certificate to verify peer against for proxy +Arg: +Added: 7.52.0 +See-also: proxy-capath cacert capath proxy +--- +Same as --cacert but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-capath.d b/docs/cmdline-opts/proxy-capath.d new file mode 100644 index 00000000..177246aa --- /dev/null +++ b/docs/cmdline-opts/proxy-capath.d @@ -0,0 +1,7 @@ +Long: proxy-capath +Help: CA directory to verify peer against for proxy +Arg: +Added: 7.52.0 +See-also: proxy-cacert proxy capath +--- +Same as --capath but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-cert-type.d b/docs/cmdline-opts/proxy-cert-type.d new file mode 100644 index 00000000..906d2a11 --- /dev/null +++ b/docs/cmdline-opts/proxy-cert-type.d @@ -0,0 +1,6 @@ +Long: proxy-cert-type +Arg: +Added: 7.52.0 +Help: Client certificate type for HTTPS proxy +--- +Same as --cert-type but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-cert.d b/docs/cmdline-opts/proxy-cert.d new file mode 100644 index 00000000..43acd395 --- /dev/null +++ b/docs/cmdline-opts/proxy-cert.d @@ -0,0 +1,6 @@ +Long: proxy-cert +Arg: +Help: Set client certificate for proxy +Added: 7.52.0 +--- +Same as --cert but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-ciphers.d b/docs/cmdline-opts/proxy-ciphers.d new file mode 100644 index 00000000..dcac8128 --- /dev/null +++ b/docs/cmdline-opts/proxy-ciphers.d @@ -0,0 +1,6 @@ +Long: proxy-ciphers +Arg: +Help: SSL ciphers to use for proxy +Added: 7.52.0 +--- +Same as --ciphers but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-crlfile.d b/docs/cmdline-opts/proxy-crlfile.d new file mode 100644 index 00000000..1d6247f4 --- /dev/null +++ b/docs/cmdline-opts/proxy-crlfile.d @@ -0,0 +1,6 @@ +Long: proxy-crlfile +Arg: +Help: Set a CRL list for proxy +Added: 7.52.0 +--- +Same as --crlfile but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-digest.d b/docs/cmdline-opts/proxy-digest.d new file mode 100644 index 00000000..ccf46636 --- /dev/null +++ b/docs/cmdline-opts/proxy-digest.d @@ -0,0 +1,6 @@ +Long: proxy-digest +Help: Use Digest authentication on the proxy +See-also: proxy proxy-anyauth proxy-basic +--- +Tells curl to use HTTP Digest authentication when communicating with the given +proxy. Use --digest for enabling HTTP Digest with a remote host. diff --git a/docs/cmdline-opts/proxy-header.d b/docs/cmdline-opts/proxy-header.d new file mode 100644 index 00000000..c1b0bb7c --- /dev/null +++ b/docs/cmdline-opts/proxy-header.d @@ -0,0 +1,24 @@ +Long: proxy-header +Arg:
+Help: Pass custom header(s) to proxy +Protocols: HTTP +Added: 7.37.0 +--- +Extra header to include in the request when sending HTTP to a proxy. You may +specify any number of extra headers. This is the equivalent option to --header +but is for proxy communication only like in CONNECT requests when you want a +separate header sent to the proxy to what is sent to the actual remote host. + +curl will make sure that each header you add/replace is sent with the proper +end-of-line marker, you should thus \fBnot\fP add that as a part of the header +content: do not add newlines or carriage returns, they will only mess things +up for you. + +Headers specified with this option will not be included in requests that curl +knows will not be sent to a proxy. + +Starting in 7.55.0, this option can take an argument in @filename style, which +then adds a header for each line in the input file. Using @- will make curl +read the header file from stdin. + +This option can be used multiple times to add/replace/remove multiple headers. diff --git a/docs/cmdline-opts/proxy-insecure.d b/docs/cmdline-opts/proxy-insecure.d new file mode 100644 index 00000000..762828f4 --- /dev/null +++ b/docs/cmdline-opts/proxy-insecure.d @@ -0,0 +1,5 @@ +Long: proxy-insecure +Help: Do HTTPS proxy connections without verifying the proxy +Added: 7.52.0 +--- +Same as --insecure but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-key-type.d b/docs/cmdline-opts/proxy-key-type.d new file mode 100644 index 00000000..ce7482ae --- /dev/null +++ b/docs/cmdline-opts/proxy-key-type.d @@ -0,0 +1,6 @@ +Long: proxy-key-type +Arg: +Help: Private key file type for proxy +Added: 7.52.0 +--- +Same as --key-type but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-key.d b/docs/cmdline-opts/proxy-key.d new file mode 100644 index 00000000..e61eb18a --- /dev/null +++ b/docs/cmdline-opts/proxy-key.d @@ -0,0 +1,5 @@ +Long: proxy-key +Help: Private key for HTTPS proxy +Arg: +--- +Same as --key but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-negotiate.d b/docs/cmdline-opts/proxy-negotiate.d new file mode 100644 index 00000000..775f62a9 --- /dev/null +++ b/docs/cmdline-opts/proxy-negotiate.d @@ -0,0 +1,8 @@ +Long: proxy-negotiate +Help: Use HTTP Negotiate (SPNEGO) authentication on the proxy +Added: 7.17.1 +See-also: proxy-anyauth proxy-basic +--- +Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating +with the given proxy. Use --negotiate for enabling HTTP Negotiate (SPNEGO) +with a remote host. diff --git a/docs/cmdline-opts/proxy-ntlm.d b/docs/cmdline-opts/proxy-ntlm.d new file mode 100644 index 00000000..c30db53b --- /dev/null +++ b/docs/cmdline-opts/proxy-ntlm.d @@ -0,0 +1,6 @@ +Long: proxy-ntlm +Help: Use NTLM authentication on the proxy +See-also: proxy-negotiate proxy-anyauth +--- +Tells curl to use HTTP NTLM authentication when communicating with the given +proxy. Use --ntlm for enabling NTLM with a remote host. diff --git a/docs/cmdline-opts/proxy-pass.d b/docs/cmdline-opts/proxy-pass.d new file mode 100644 index 00000000..3371714b --- /dev/null +++ b/docs/cmdline-opts/proxy-pass.d @@ -0,0 +1,6 @@ +Long: proxy-pass +Arg: +Help: Pass phrase for the private key for HTTPS proxy +Added: 7.52.0 +--- +Same as --pass but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-pinnedpubkey.d b/docs/cmdline-opts/proxy-pinnedpubkey.d new file mode 100644 index 00000000..abd6dc4a --- /dev/null +++ b/docs/cmdline-opts/proxy-pinnedpubkey.d @@ -0,0 +1,16 @@ +Long: proxy-pinnedpubkey +Arg: +Help: FILE/HASHES public key to verify proxy with +Protocols: TLS +--- +Tells curl to use the specified public key file (or hashes) to verify the +proxy. This can be a path to a file which contains a single public key in PEM +or DER format, or any number of base64 encoded sha256 hashes preceded by +\'sha256//\' and separated by \';\' + +When negotiating a TLS or SSL connection, the server sends a certificate +indicating its identity. A public key is extracted from this certificate and +if it does not exactly match the public key provided to this option, curl will +abort the connection before sending or receiving any data. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/proxy-service-name.d b/docs/cmdline-opts/proxy-service-name.d new file mode 100644 index 00000000..9a73f2be --- /dev/null +++ b/docs/cmdline-opts/proxy-service-name.d @@ -0,0 +1,6 @@ +Long: proxy-service-name +Arg: +Help: SPNEGO proxy service name +Added: 7.43.0 +--- +This option allows you to change the service name for proxy negotiation. diff --git a/docs/cmdline-opts/proxy-ssl-allow-beast.d b/docs/cmdline-opts/proxy-ssl-allow-beast.d new file mode 100644 index 00000000..de96b843 --- /dev/null +++ b/docs/cmdline-opts/proxy-ssl-allow-beast.d @@ -0,0 +1,5 @@ +Long: proxy-ssl-allow-beast +Help: Allow security flaw for interop for HTTPS proxy +Added: 7.52.0 +--- +Same as --ssl-allow-beast but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-tls13-ciphers.d b/docs/cmdline-opts/proxy-tls13-ciphers.d new file mode 100644 index 00000000..3e35b076 --- /dev/null +++ b/docs/cmdline-opts/proxy-tls13-ciphers.d @@ -0,0 +1,12 @@ +Long: proxy-tls13-ciphers +Arg: +help: TLS 1.3 proxy cipher suites +Protocols: TLS +--- +Specifies which cipher suites to use in the connection to your HTTPS proxy +when it negotiates TLS 1.3. The list of ciphers suites must specify valid +ciphers. Read up on TLS 1.3 cipher suite details on this URL: + + https://curl.haxx.se/docs/ssl-ciphers.html + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/proxy-tlsauthtype.d b/docs/cmdline-opts/proxy-tlsauthtype.d new file mode 100644 index 00000000..7d0ce8e1 --- /dev/null +++ b/docs/cmdline-opts/proxy-tlsauthtype.d @@ -0,0 +1,6 @@ +Long: proxy-tlsauthtype +Arg: +Help: TLS authentication type for HTTPS proxy +Added: 7.52.0 +--- +Same as --tlsauthtype but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-tlspassword.d b/docs/cmdline-opts/proxy-tlspassword.d new file mode 100644 index 00000000..cf003844 --- /dev/null +++ b/docs/cmdline-opts/proxy-tlspassword.d @@ -0,0 +1,6 @@ +Long: proxy-tlspassword +Arg: +Help: TLS password for HTTPS proxy +Added: 7.52.0 +--- +Same as --tlspassword but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-tlsuser.d b/docs/cmdline-opts/proxy-tlsuser.d new file mode 100644 index 00000000..758a7c95 --- /dev/null +++ b/docs/cmdline-opts/proxy-tlsuser.d @@ -0,0 +1,6 @@ +Long: proxy-tlsuser +Arg: +Help: TLS username for HTTPS proxy +Added: 7.52.0 +--- +Same as --tlsuser but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-tlsv1.d b/docs/cmdline-opts/proxy-tlsv1.d new file mode 100644 index 00000000..d024eeac --- /dev/null +++ b/docs/cmdline-opts/proxy-tlsv1.d @@ -0,0 +1,5 @@ +Long: proxy-tlsv1 +Help: Use TLSv1 for HTTPS proxy +Added: 7.52.0 +--- +Same as --tlsv1 but used in HTTPS proxy context. diff --git a/docs/cmdline-opts/proxy-user.d b/docs/cmdline-opts/proxy-user.d new file mode 100644 index 00000000..b1f6f6e0 --- /dev/null +++ b/docs/cmdline-opts/proxy-user.d @@ -0,0 +1,12 @@ +Long: proxy-user +Short: U +Arg: +Help: Proxy user and password +--- +Specify the user name and password to use for proxy authentication. + +If you use a Windows SSPI-enabled curl binary and do either Negotiate or NTLM +authentication then you can tell curl to select the user name and password +from your environment by specifying a single colon with this option: "-U :". + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/proxy.d b/docs/cmdline-opts/proxy.d new file mode 100644 index 00000000..6506692b --- /dev/null +++ b/docs/cmdline-opts/proxy.d @@ -0,0 +1,39 @@ +Long: proxy +Short: x +Arg: [protocol://]host[:port] +Help: Use this proxy +--- +Use the specified proxy. + +The proxy string can be specified with a protocol:// prefix. No protocol +specified or http:// will be treated as HTTP proxy. Use socks4://, socks4a://, +socks5:// or socks5h:// to request a specific SOCKS version to be used. +(The protocol support was added in curl 7.21.7) + +HTTPS proxy support via https:// protocol prefix was added in 7.52.0 for +OpenSSL, GnuTLS and NSS. + +Unrecognized and unsupported proxy protocols cause an error since 7.52.0. +Prior versions may ignore the protocol and use http:// instead. + +If the port number is not specified in the proxy string, it is assumed to be +1080. + +This option overrides existing environment variables that set the proxy to +use. If there's an environment variable setting a proxy, you can set proxy to +\&"" to override it. + +All operations that are performed over an HTTP proxy will transparently be +converted to HTTP. It means that certain protocol specific operations might +not be available. This is not the case if you can tunnel through the proxy, as +one with the --proxytunnel option. + +User and password that might be provided in the proxy string are URL decoded +by curl. This allows you to pass in special characters such as @ by using %40 +or pass in a colon with %3a. + +The proxy host can be specified the exact same way as the proxy environment +variables, including the protocol prefix (http://) and the embedded user + +password. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/proxy1.0.d b/docs/cmdline-opts/proxy1.0.d new file mode 100644 index 00000000..4a931bd1 --- /dev/null +++ b/docs/cmdline-opts/proxy1.0.d @@ -0,0 +1,10 @@ +Long: proxy1.0 +Arg: +Help: Use HTTP/1.0 proxy on given port +--- +Use the specified HTTP 1.0 proxy. If the port number is not specified, it is +assumed at port 1080. + +The only difference between this and the HTTP proxy option --proxy, is that +attempts to use CONNECT through the proxy will specify an HTTP 1.0 protocol +instead of the default HTTP 1.1. diff --git a/docs/cmdline-opts/proxytunnel.d b/docs/cmdline-opts/proxytunnel.d new file mode 100644 index 00000000..42aee2bb --- /dev/null +++ b/docs/cmdline-opts/proxytunnel.d @@ -0,0 +1,13 @@ +Long: proxytunnel +Short: p +Help: Operate through an HTTP proxy tunnel (using CONNECT) +See-also: proxy +--- +When an HTTP proxy is used --proxy, this option will cause non-HTTP protocols +to attempt to tunnel through the proxy instead of merely using it to do +HTTP-like operations. The tunnel approach is made with the HTTP proxy CONNECT +request and requires that the proxy allows direct connect to the remote port +number curl wants to tunnel through to. + +To suppress proxy CONNECT response headers when curl is set to output headers +use --suppress-connect-headers. diff --git a/docs/cmdline-opts/pubkey.d b/docs/cmdline-opts/pubkey.d new file mode 100644 index 00000000..b2e11c02 --- /dev/null +++ b/docs/cmdline-opts/pubkey.d @@ -0,0 +1,14 @@ +Long: pubkey +Arg: +Protocols: SFTP SCP +Help: SSH Public key file name +--- +Public key file name. Allows you to provide your public key in this separate +file. + +If this option is used several times, the last one will be used. + +(As of 7.39.0, curl attempts to automatically extract the public key from the +private key file, so passing this option is generally not required. Note that +this public key extraction requires libcurl to be linked against a copy of +libssh2 1.2.8 or higher that is itself linked against OpenSSL.) diff --git a/docs/cmdline-opts/quote.d b/docs/cmdline-opts/quote.d new file mode 100644 index 00000000..cdd3ca6b --- /dev/null +++ b/docs/cmdline-opts/quote.d @@ -0,0 +1,56 @@ +Long: quote +Short: Q +Help: Send command(s) to server before transfer +Protocols: FTP SFTP +--- + +Send an arbitrary command to the remote FTP or SFTP server. Quote commands are +sent BEFORE the transfer takes place (just after the initial PWD command in an +FTP transfer, to be exact). To make commands take place after a successful +transfer, prefix them with a dash '-'. To make commands be sent after curl +has changed the working directory, just before the transfer command(s), prefix +the command with a '+' (this is only supported for FTP). You may specify any +number of commands. + +If the server returns failure for one of the commands, the entire operation +will be aborted. You must send syntactically correct FTP commands as RFC 959 +defines to FTP servers, or one of the commands listed below to SFTP servers. + +This option can be used multiple times. When speaking to an FTP server, prefix +the command with an asterisk (*) to make curl continue even if the command +fails as by default curl will stop at first failure. + +SFTP is a binary protocol. Unlike for FTP, curl interprets SFTP quote commands +itself before sending them to the server. File names may be quoted +shell-style to embed spaces or special characters. Following is the list of +all supported SFTP quote commands: +.RS +.IP "chgrp group file" +The chgrp command sets the group ID of the file named by the file operand to +the group ID specified by the group operand. The group operand is a decimal +integer group ID. +.IP "chmod mode file" +The chmod command modifies the file mode bits of the specified file. The +mode operand is an octal integer mode number. +.IP "chown user file" +The chown command sets the owner of the file named by the file operand to the +user ID specified by the user operand. The user operand is a decimal +integer user ID. +.IP "ln source_file target_file" +The ln and symlink commands create a symbolic link at the target_file location +pointing to the source_file location. +.IP "mkdir directory_name" +The mkdir command creates the directory named by the directory_name operand. +.IP "pwd" +The pwd command returns the absolute pathname of the current working directory. +.IP "rename source target" +The rename command renames the file or directory named by the source +operand to the destination path named by the target operand. +.IP "rm file" +The rm command removes the file specified by the file operand. +.IP "rmdir directory" +The rmdir command removes the directory entry specified by the directory +operand, provided it is empty. +.IP "symlink source_file target_file" +See ln. +.RE diff --git a/docs/cmdline-opts/random-file.d b/docs/cmdline-opts/random-file.d new file mode 100644 index 00000000..51626f88 --- /dev/null +++ b/docs/cmdline-opts/random-file.d @@ -0,0 +1,7 @@ +Long: random-file +Arg: +Help: File for reading random data from +--- +Specify the path name to file containing what will be considered as random +data. The data may be used to seed the random engine for SSL connections. See +also the --egd-file option. diff --git a/docs/cmdline-opts/range.d b/docs/cmdline-opts/range.d new file mode 100644 index 00000000..b888dd18 --- /dev/null +++ b/docs/cmdline-opts/range.d @@ -0,0 +1,46 @@ +Long: range +Short: r +Help: Retrieve only the bytes within RANGE +Arg: +Protocols: HTTP FTP SFTP FILE +--- +Retrieve a byte range (i.e. a partial document) from an HTTP/1.1, FTP or SFTP +server or a local FILE. Ranges can be specified in a number of ways. +.RS +.TP 10 +.B 0-499 +specifies the first 500 bytes +.TP +.B 500-999 +specifies the second 500 bytes +.TP +.B -500 +specifies the last 500 bytes +.TP +.B 9500- +specifies the bytes from offset 9500 and forward +.TP +.B 0-0,-1 +specifies the first and last byte only(*)(HTTP) +.TP +.B 100-199,500-599 +specifies two separate 100-byte ranges(*) (HTTP) +.RE +.IP +(*) = NOTE that this will cause the server to reply with a multipart +response! + +Only digit characters (0-9) are valid in the 'start' and 'stop' fields of the +\&'start-stop' range syntax. If a non-digit character is given in the range, +the server's response will be unspecified, depending on the server's +configuration. + +You should also be aware that many HTTP/1.1 servers do not have this feature +enabled, so that when you attempt to get a range, you'll instead get the whole +document. + +FTP and SFTP range downloads only support the simple 'start-stop' syntax +(optionally with one of the numbers omitted). FTP use depends on the extended +FTP command SIZE. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/raw.d b/docs/cmdline-opts/raw.d new file mode 100644 index 00000000..c3328e69 --- /dev/null +++ b/docs/cmdline-opts/raw.d @@ -0,0 +1,7 @@ +Long: raw +Help: Do HTTP "raw"; no transfer decoding +Added: 7.16.2 +Protocols: HTTP +--- +When used, it disables all internal HTTP decoding of content or transfer +encodings and instead makes them passed on unaltered, raw. diff --git a/docs/cmdline-opts/referer.d b/docs/cmdline-opts/referer.d new file mode 100644 index 00000000..cd84e9d5 --- /dev/null +++ b/docs/cmdline-opts/referer.d @@ -0,0 +1,14 @@ +Long: referer +Short: e +Arg: +Protocols: HTTP +Help: Referrer URL +See-also: user-agent header +--- +Sends the "Referrer Page" information to the HTTP server. This can also be set +with the --header flag of course. When used with --location you can append +";auto" to the --referer URL to make curl automatically set the previous URL +when it follows a Location: header. The \&";auto" string can be used alone, +even if you don't set an initial --referer. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/remote-header-name.d b/docs/cmdline-opts/remote-header-name.d new file mode 100644 index 00000000..771b6d46 --- /dev/null +++ b/docs/cmdline-opts/remote-header-name.d @@ -0,0 +1,19 @@ +Long: remote-header-name +Short: J +Protocols: HTTP +Help: Use the header-provided filename +--- +This option tells the --remote-name option to use the server-specified +Content-Disposition filename instead of extracting a filename from the URL. + +If the server specifies a file name and a file with that name already exists +in the current working directory it will not be overwritten and an error will +occur. If the server doesn't specify a file name then this option has no +effect. + +There's no attempt to decode %-sequences (yet) in the provided file name, so +this option may provide you with rather unexpected file names. + +\fBWARNING\fP: Exercise judicious use of this option, especially on Windows. A +rogue server could send you the name of a DLL or other file that could possibly +be loaded automatically by Windows or some third party software. diff --git a/docs/cmdline-opts/remote-name-all.d b/docs/cmdline-opts/remote-name-all.d new file mode 100644 index 00000000..f7a19967 --- /dev/null +++ b/docs/cmdline-opts/remote-name-all.d @@ -0,0 +1,8 @@ +Long: remote-name-all +Help: Use the remote file name for all URLs +Added: 7.19.0 +--- +This option changes the default action for all given URLs to be dealt with as +if --remote-name were used for each one. So if you want to disable that for a +specific URL after --remote-name-all has been used, you must use "-o -" or +--no-remote-name. diff --git a/docs/cmdline-opts/remote-name.d b/docs/cmdline-opts/remote-name.d new file mode 100644 index 00000000..9fed64bf --- /dev/null +++ b/docs/cmdline-opts/remote-name.d @@ -0,0 +1,21 @@ +Long: remote-name +Short: O +Help: Write output to a file named as the remote file +--- +Write output to a local file named like the remote file we get. (Only the file +part of the remote file is used, the path is cut off.) + +The file will be saved in the current working directory. If you want the file +saved in a different directory, make sure you change the current working +directory before invoking curl with this option. + +The remote file name to use for saving is extracted from the given URL, +nothing else, and if it already exists it will be overwritten. If you want the +server to be able to choose the file name refer to --remote-header-name which +can be used in addition to this option. If the server chooses a file name and +that name already exists it will not be overwritten. + +There is no URL decoding done on the file name. If it has %20 or other URL +encoded parts of the name, they will end up as-is as file name. + +You may use this option as many times as the number of URLs you have. diff --git a/docs/cmdline-opts/remote-time.d b/docs/cmdline-opts/remote-time.d new file mode 100644 index 00000000..7f6809dc --- /dev/null +++ b/docs/cmdline-opts/remote-time.d @@ -0,0 +1,7 @@ +Long: remote-time +Short: R +Help: Set the remote file's time on the local output +--- +When used, this will make curl attempt to figure out the timestamp of the +remote file, and if that is available make the local file get that same +timestamp. diff --git a/docs/cmdline-opts/request-target.d b/docs/cmdline-opts/request-target.d new file mode 100644 index 00000000..b46b4af0 --- /dev/null +++ b/docs/cmdline-opts/request-target.d @@ -0,0 +1,9 @@ +Long: request-target +Help: Specify the target for this request +Protocols: HTTP +Added: 7.55.0 +--- +Tells curl to use an alternative "target" (path) instead of using the path as +provided in the URL. Particularly useful when wanting to issue HTTP requests +without leading slash or other data that doesn't follow the regular URL +pattern, like "OPTIONS *". diff --git a/docs/cmdline-opts/request.d b/docs/cmdline-opts/request.d new file mode 100644 index 00000000..3919d426 --- /dev/null +++ b/docs/cmdline-opts/request.d @@ -0,0 +1,39 @@ +Long: request +Short: X +Arg: +Help: Specify request command to use +--- +(HTTP) Specifies a custom request method to use when communicating with the +HTTP server. The specified request method will be used instead of the method +otherwise used (which defaults to GET). Read the HTTP 1.1 specification for +details and explanations. Common additional HTTP requests include PUT and +DELETE, but related technologies like WebDAV offers PROPFIND, COPY, MOVE and +more. + +Normally you don't need this option. All sorts of GET, HEAD, POST and PUT +requests are rather invoked by using dedicated command line options. + +This option only changes the actual word used in the HTTP request, it does not +alter the way curl behaves. So for example if you want to make a proper HEAD +request, using -X HEAD will not suffice. You need to use the --head option. + +The method string you set with --request will be used for all requests, which +if you for example use --location may cause unintended side-effects when curl +doesn't change request method according to the HTTP 30x response codes - and +similar. + +(FTP) +Specifies a custom FTP command to use instead of LIST when doing file lists +with FTP. + +(POP3) +Specifies a custom POP3 command to use instead of LIST or RETR. (Added in +7.26.0) + +(IMAP) +Specifies a custom IMAP command to use instead of LIST. (Added in 7.30.0) + +(SMTP) +Specifies a custom SMTP command to use instead of HELP or VRFY. (Added in 7.34.0) + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/resolve.d b/docs/cmdline-opts/resolve.d new file mode 100644 index 00000000..9e1457b5 --- /dev/null +++ b/docs/cmdline-opts/resolve.d @@ -0,0 +1,21 @@ +Long: resolve +Arg: +Help: Resolve the host+port to this address +Added: 7.21.3 +--- +Provide a custom address for a specific host and port pair. Using this, you +can make the curl requests(s) use a specified address and prevent the +otherwise normally resolved address to be used. Consider it a sort of +/etc/hosts alternative provided on the command line. The port number should be +the number used for the specific protocol the host will be used for. It means +you need several entries if you want to provide address for the same host but +different ports. + +The provided address set by this option will be used even if --ipv4 or --ipv6 +is set to make curl use another IP version. + +Support for providing the IP address within [brackets] was added in 7.57.0. + +Support for providing multiple IP addresses per entry was added in 7.59.0. + +This option can be used many times to add many host names to resolve. diff --git a/docs/cmdline-opts/retry-connrefused.d b/docs/cmdline-opts/retry-connrefused.d new file mode 100644 index 00000000..6a78e1fd --- /dev/null +++ b/docs/cmdline-opts/retry-connrefused.d @@ -0,0 +1,6 @@ +Long: retry-connrefused +Help: Retry on connection refused (use with --retry) +Added: 7.52.0 +--- +In addition to the other conditions, consider ECONNREFUSED as a transient +error too for --retry. This option is used together with --retry. diff --git a/docs/cmdline-opts/retry-delay.d b/docs/cmdline-opts/retry-delay.d new file mode 100644 index 00000000..1691356d --- /dev/null +++ b/docs/cmdline-opts/retry-delay.d @@ -0,0 +1,11 @@ +Long: retry-delay +Arg: +Help: Wait time between retries +Added: 7.12.3 +--- +Make curl sleep this amount of time before each retry when a transfer has +failed with a transient error (it changes the default backoff time algorithm +between retries). This option is only interesting if --retry is also +used. Setting this delay to zero will make curl use the default backoff time. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/retry-max-time.d b/docs/cmdline-opts/retry-max-time.d new file mode 100644 index 00000000..0920c924 --- /dev/null +++ b/docs/cmdline-opts/retry-max-time.d @@ -0,0 +1,13 @@ +Long: retry-max-time +Arg: +Help: Retry only within this period +Added: 7.12.3 +--- +The retry timer is reset before the first transfer attempt. Retries will be +done as usual (see --retry) as long as the timer hasn't reached this given +limit. Notice that if the timer hasn't reached the limit, the request will be +made and while performing, it may take longer than this given time period. To +limit a single request\'s maximum time, use --max-time. Set this option to +zero to not timeout retries. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/retry.d b/docs/cmdline-opts/retry.d new file mode 100644 index 00000000..35215dfd --- /dev/null +++ b/docs/cmdline-opts/retry.d @@ -0,0 +1,17 @@ +Long: retry +Arg: +Added: 7.12.3 +Help: Retry request if transient problems occur +--- +If a transient error is returned when curl tries to perform a transfer, it +will retry this number of times before giving up. Setting the number to 0 +makes curl do no retries (which is the default). Transient error means either: +a timeout, an FTP 4xx response code or an HTTP 5xx response code. + +When curl is about to retry a transfer, it will first wait one second and then +for all forthcoming retries it will double the waiting time until it reaches +10 minutes which then will be the delay between the rest of the retries. By +using --retry-delay you disable this exponential backoff algorithm. See also +--retry-max-time to limit the total time allowed for retries. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/sasl-ir.d b/docs/cmdline-opts/sasl-ir.d new file mode 100644 index 00000000..c0dab946 --- /dev/null +++ b/docs/cmdline-opts/sasl-ir.d @@ -0,0 +1,5 @@ +Long: sasl-ir +Help: Enable initial response in SASL authentication +Added: 7.31.0 +--- +Enable initial response in SASL authentication. diff --git a/docs/cmdline-opts/service-name.d b/docs/cmdline-opts/service-name.d new file mode 100644 index 00000000..4dfeb27d --- /dev/null +++ b/docs/cmdline-opts/service-name.d @@ -0,0 +1,8 @@ +Long: service-name +Help: SPNEGO service name +Arg: +Added: 7.43.0 +--- +This option allows you to change the service name for SPNEGO. + +Examples: --negotiate --service-name sockd would use sockd/server-name. diff --git a/docs/cmdline-opts/show-error.d b/docs/cmdline-opts/show-error.d new file mode 100644 index 00000000..b9667a4c --- /dev/null +++ b/docs/cmdline-opts/show-error.d @@ -0,0 +1,5 @@ +Long: show-error +Short: S +Help: Show error even when -s is used +--- +When used with --silent, it makes curl show an error message if it fails. diff --git a/docs/cmdline-opts/silent.d b/docs/cmdline-opts/silent.d new file mode 100644 index 00000000..b0b4425b --- /dev/null +++ b/docs/cmdline-opts/silent.d @@ -0,0 +1,11 @@ +Long: silent +Short: s +Help: Silent mode +See-also: verbose stderr +--- +Silent or quiet mode. Don't show progress meter or error messages. Makes Curl +mute. It will still output the data you ask for, potentially even to the +terminal/stdout unless you redirect it. + +Use --show-error in addition to this option to disable progress meter but +still show error messages. diff --git a/docs/cmdline-opts/socks4.d b/docs/cmdline-opts/socks4.d new file mode 100644 index 00000000..11f6ae03 --- /dev/null +++ b/docs/cmdline-opts/socks4.d @@ -0,0 +1,19 @@ +Long: socks4 +Arg: +Help: SOCKS4 proxy on given host + port +Added: 7.15.2 +--- +Use the specified SOCKS4 proxy. If the port number is not specified, it is +assumed at port 1080. + +This option overrides any previous use of --proxy, as they are mutually +exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks4 proxy +with --proxy using a socks4:// protocol prefix. + +Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time +--proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to +the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/socks4a.d b/docs/cmdline-opts/socks4a.d new file mode 100644 index 00000000..ae254ae0 --- /dev/null +++ b/docs/cmdline-opts/socks4a.d @@ -0,0 +1,19 @@ +Long: socks4a +Arg: +Help: SOCKS4a proxy on given host + port +Added: 7.18.0 +--- +Use the specified SOCKS4a proxy. If the port number is not specified, it is +assumed at port 1080. + +This option overrides any previous use of --proxy, as they are mutually +exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks4a proxy +with --proxy using a socks4a:// protocol prefix. + +Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time +--proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to +the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/socks5-basic.d b/docs/cmdline-opts/socks5-basic.d new file mode 100644 index 00000000..67d16b3a --- /dev/null +++ b/docs/cmdline-opts/socks5-basic.d @@ -0,0 +1,7 @@ +Long: socks5-basic +Help: Enable username/password auth for SOCKS5 proxies +Added: 7.55.0 +--- +Tells curl to use username/password authentication when connecting to a SOCKS5 +proxy. The username/password authentication is enabled by default. Use +--socks5-gssapi to force GSS-API authentication to SOCKS5 proxies. diff --git a/docs/cmdline-opts/socks5-gssapi-nec.d b/docs/cmdline-opts/socks5-gssapi-nec.d new file mode 100644 index 00000000..477e218e --- /dev/null +++ b/docs/cmdline-opts/socks5-gssapi-nec.d @@ -0,0 +1,8 @@ +Long: socks5-gssapi-nec +Help: Compatibility with NEC SOCKS5 server +Added: 7.19.4 +--- +As part of the GSS-API negotiation a protection mode is negotiated. RFC 1961 +says in section 4.3/4.4 it should be protected, but the NEC reference +implementation does not. The option --socks5-gssapi-nec allows the +unprotected exchange of the protection mode negotiation. diff --git a/docs/cmdline-opts/socks5-gssapi-service.d b/docs/cmdline-opts/socks5-gssapi-service.d new file mode 100644 index 00000000..eb3b2407 --- /dev/null +++ b/docs/cmdline-opts/socks5-gssapi-service.d @@ -0,0 +1,12 @@ +Long: socks5-gssapi-service +Arg: +Help: SOCKS5 proxy service name for GSS-API +Added: 7.19.4 +--- +The default service name for a socks server is rcmd/server-fqdn. This option +allows you to change it. + +Examples: --socks5 proxy-name --socks5-gssapi-service sockd would use +sockd/proxy-name --socks5 proxy-name --socks5-gssapi-service sockd/real-name +would use sockd/real-name for cases where the proxy-name does not match the +principal name. diff --git a/docs/cmdline-opts/socks5-gssapi.d b/docs/cmdline-opts/socks5-gssapi.d new file mode 100644 index 00000000..0070f37e --- /dev/null +++ b/docs/cmdline-opts/socks5-gssapi.d @@ -0,0 +1,8 @@ +Long: socks5-gssapi +Help: Enable GSS-API auth for SOCKS5 proxies +Added: 7.55.0 +--- +Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy. +The GSS-API authentication is enabled by default (if curl is compiled with +GSS-API support). Use --socks5-basic to force username/password authentication +to SOCKS5 proxies. diff --git a/docs/cmdline-opts/socks5-hostname.d b/docs/cmdline-opts/socks5-hostname.d new file mode 100644 index 00000000..9d9d946e --- /dev/null +++ b/docs/cmdline-opts/socks5-hostname.d @@ -0,0 +1,19 @@ +Long: socks5-hostname +Arg: +Help: SOCKS5 proxy, pass host name to proxy +Added: 7.18.0 +--- +Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If +the port number is not specified, it is assumed at port 1080. + +This option overrides any previous use of --proxy, as they are mutually +exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks5 +hostname proxy with --proxy using a socks5h:// protocol prefix. + +Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time +--proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to +the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/socks5.d b/docs/cmdline-opts/socks5.d new file mode 100644 index 00000000..22fae762 --- /dev/null +++ b/docs/cmdline-opts/socks5.d @@ -0,0 +1,21 @@ +Long: socks5 +Arg: +Help: SOCKS5 proxy on given host + port +Added: 7.18.0 +--- +Use the specified SOCKS5 proxy - but resolve the host name locally. If the +port number is not specified, it is assumed at port 1080. + +This option overrides any previous use of --proxy, as they are mutually +exclusive. + +Since 7.21.7, this option is superfluous since you can specify a socks5 proxy +with --proxy using a socks5:// protocol prefix. + +Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time +--proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to +the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. + +If this option is used several times, the last one will be used. + +This option (as well as --socks4) does not work with IPV6, FTPS or LDAP. diff --git a/docs/cmdline-opts/speed-limit.d b/docs/cmdline-opts/speed-limit.d new file mode 100644 index 00000000..e2b81c79 --- /dev/null +++ b/docs/cmdline-opts/speed-limit.d @@ -0,0 +1,10 @@ +Long: speed-limit +Short: Y +Arg: +Help: Stop transfers slower than this +--- +If a download is slower than this given speed (in bytes per second) for +speed-time seconds it gets aborted. speed-time is set with --speed-time and is +30 if not set. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/speed-time.d b/docs/cmdline-opts/speed-time.d new file mode 100644 index 00000000..98d6ae13 --- /dev/null +++ b/docs/cmdline-opts/speed-time.d @@ -0,0 +1,13 @@ +Long: speed-time +Short: y +Arg: +Help: Trigger 'speed-limit' abort after this time +--- +If a download is slower than speed-limit bytes per second during a speed-time +period, the download gets aborted. If speed-time is used, the default +speed-limit will be 1 unless set with --speed-limit. + +This option controls transfers and thus will not affect slow connects etc. If +this is a concern for you, try the --connect-timeout option. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/ssl-allow-beast.d b/docs/cmdline-opts/ssl-allow-beast.d new file mode 100644 index 00000000..973fcd45 --- /dev/null +++ b/docs/cmdline-opts/ssl-allow-beast.d @@ -0,0 +1,9 @@ +Long: ssl-allow-beast +Help: Allow security flaw to improve interop +Added: 7.25.0 +--- +This option tells curl to not work around a security flaw in the SSL3 and +TLS1.0 protocols known as BEAST. If this option isn't used, the SSL layer may +use workarounds known to cause interoperability problems with some older SSL +implementations. WARNING: this option loosens the SSL security, and by using +this flag you ask for exactly that. diff --git a/docs/cmdline-opts/ssl-no-revoke.d b/docs/cmdline-opts/ssl-no-revoke.d new file mode 100644 index 00000000..cdb6fb5e --- /dev/null +++ b/docs/cmdline-opts/ssl-no-revoke.d @@ -0,0 +1,7 @@ +Long: ssl-no-revoke +Help: Disable cert revocation checks (WinSSL) +Added: 7.44.0 +--- +(WinSSL) This option tells curl to disable certificate revocation checks. +WARNING: this option loosens the SSL security, and by using this flag you ask +for exactly that. diff --git a/docs/cmdline-opts/ssl-reqd.d b/docs/cmdline-opts/ssl-reqd.d new file mode 100644 index 00000000..3c6f8a25 --- /dev/null +++ b/docs/cmdline-opts/ssl-reqd.d @@ -0,0 +1,9 @@ +Long: ssl-reqd +Help: Require SSL/TLS +Protocols: FTP IMAP POP3 SMTP +Added: 7.20.0 +--- +Require SSL/TLS for the connection. Terminates the connection if the server +doesn't support SSL/TLS. + +This option was formerly known as --ftp-ssl-reqd. diff --git a/docs/cmdline-opts/ssl.d b/docs/cmdline-opts/ssl.d new file mode 100644 index 00000000..dabd8376 --- /dev/null +++ b/docs/cmdline-opts/ssl.d @@ -0,0 +1,12 @@ +Long: ssl +Help: Try SSL/TLS +Protocols: FTP IMAP POP3 SMTP +Added: 7.20.0 +--- + +Try to use SSL/TLS for the connection. Reverts to a non-secure connection if +the server doesn't support SSL/TLS. See also --ftp-ssl-control and --ssl-reqd +for different levels of encryption required. + +This option was formerly known as --ftp-ssl (Added in 7.11.0). That option +name can still be used but will be removed in a future version. diff --git a/docs/cmdline-opts/sslv2.d b/docs/cmdline-opts/sslv2.d new file mode 100644 index 00000000..67d2b850 --- /dev/null +++ b/docs/cmdline-opts/sslv2.d @@ -0,0 +1,13 @@ +Short: 2 +Long: sslv2 +Tags: Versions +Protocols: SSL +Added: +Mutexed: sslv3 tlsv1 tlsv1.1 tlsv1.2 +Requires: TLS +See-also: http1.1 http2 +Help: Use SSLv2 +--- +Forces curl to use SSL version 2 when negotiating with a remote SSL +server. Sometimes curl is built without SSLv2 support. SSLv2 is widely +considered insecure (see RFC 6176). diff --git a/docs/cmdline-opts/sslv3.d b/docs/cmdline-opts/sslv3.d new file mode 100644 index 00000000..101ad100 --- /dev/null +++ b/docs/cmdline-opts/sslv3.d @@ -0,0 +1,13 @@ +Short: 3 +Long: sslv3 +Tags: Versions +Protocols: SSL +Added: +Mutexed: sslv2 tlsv1 tlsv1.1 tlsv1.2 +Requires: TLS +See-also: http1.1 http2 +Help: Use SSLv3 +--- +Forces curl to use SSL version 3 when negotiating with a remote SSL +server. Sometimes curl is built without SSLv3 support. SSLv3 is widely +considered insecure (see RFC 7568). diff --git a/docs/cmdline-opts/stderr.d b/docs/cmdline-opts/stderr.d new file mode 100644 index 00000000..e8cf7ba6 --- /dev/null +++ b/docs/cmdline-opts/stderr.d @@ -0,0 +1,8 @@ +Long: stderr +Help: Where to redirect stderr +See-also: verbose silent +--- +Redirect all writes to stderr to the specified file instead. If the file name +is a plain '-', it is instead written to stdout. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/styled-output.d b/docs/cmdline-opts/styled-output.d new file mode 100644 index 00000000..e4751aec --- /dev/null +++ b/docs/cmdline-opts/styled-output.d @@ -0,0 +1,6 @@ +Long: styled-output +Help: Enable styled output for HTTP headers +Added: 7.61.0 +--- +Enables the automatic use of bold font styles when writing HTTP headers to the +terminal. Use --no-styled-output to switch them off. diff --git a/docs/cmdline-opts/suppress-connect-headers.d b/docs/cmdline-opts/suppress-connect-headers.d new file mode 100644 index 00000000..d208b891 --- /dev/null +++ b/docs/cmdline-opts/suppress-connect-headers.d @@ -0,0 +1,8 @@ +Long: suppress-connect-headers +Help: Suppress proxy CONNECT response headers +See-also: dump-header include proxytunnel +--- +When --proxytunnel is used and a CONNECT request is made don't output proxy +CONNECT response headers. This option is meant to be used with --dump-header or +--include which are used to show protocol headers in the output. It has no +effect on debug options such as --verbose or --trace, or any statistics. diff --git a/docs/cmdline-opts/tcp-fastopen.d b/docs/cmdline-opts/tcp-fastopen.d new file mode 100644 index 00000000..08e141df --- /dev/null +++ b/docs/cmdline-opts/tcp-fastopen.d @@ -0,0 +1,5 @@ +Long: tcp-fastopen +Added: 7.49.0 +Help: Use TCP Fast Open +--- +Enable use of TCP Fast Open (RFC7413). diff --git a/docs/cmdline-opts/tcp-nodelay.d b/docs/cmdline-opts/tcp-nodelay.d new file mode 100644 index 00000000..f047a7c6 --- /dev/null +++ b/docs/cmdline-opts/tcp-nodelay.d @@ -0,0 +1,9 @@ +Long: tcp-nodelay +Help: Use the TCP_NODELAY option +Added: 7.11.2 +--- +Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for +details about this option. + +Since 7.50.2, curl sets this option by default and you need to explicitly +switch it off if you don't want it on. diff --git a/docs/cmdline-opts/telnet-option.d b/docs/cmdline-opts/telnet-option.d new file mode 100644 index 00000000..a67cb627 --- /dev/null +++ b/docs/cmdline-opts/telnet-option.d @@ -0,0 +1,12 @@ +Long: telnet-option +Short: t +Arg: +Help: Set telnet option +--- +Pass options to the telnet protocol. Supported options are: + +TTYPE= Sets the terminal type. + +XDISPLOC= Sets the X display location. + +NEW_ENV= Sets an environment variable. diff --git a/docs/cmdline-opts/tftp-blksize.d b/docs/cmdline-opts/tftp-blksize.d new file mode 100644 index 00000000..c184328d --- /dev/null +++ b/docs/cmdline-opts/tftp-blksize.d @@ -0,0 +1,11 @@ +Long: tftp-blksize +Arg: +Help: Set TFTP BLKSIZE option +Protocols: TFTP +Added: 7.20.0 +--- +Set TFTP BLKSIZE option (must be >512). This is the block size that curl will +try to use when transferring data to or from a TFTP server. By default 512 +bytes will be used. + +If this option is used several times, the last one will be used. diff --git a/docs/cmdline-opts/tftp-no-options.d b/docs/cmdline-opts/tftp-no-options.d new file mode 100644 index 00000000..e2a4dacd --- /dev/null +++ b/docs/cmdline-opts/tftp-no-options.d @@ -0,0 +1,10 @@ +Long: tftp-no-options +Help: Do not send any TFTP options +Protocols: TFTP +Added: 7.48.0 +--- +Tells curl not to send TFTP options requests. + +This option improves interop with some legacy servers that do not acknowledge +or properly implement TFTP options. When this option is used --tftp-blksize is +ignored. diff --git a/docs/cmdline-opts/time-cond.d b/docs/cmdline-opts/time-cond.d new file mode 100644 index 00000000..830b4e1a --- /dev/null +++ b/docs/cmdline-opts/time-cond.d @@ -0,0 +1,17 @@ +Long: time-cond +Short: z +Arg: