1. Keep up to date by merging master

2. Factored out the parameter string parsing for ncgen and nccopy
   int libdispatch/dfilter.c + include/ncfilter.h
3. Allow a parameter string to use constant types other than
   unsigned int. See docs/filters.md for details.
4. Moved the old content of  include/netcdf_filter.h into include/netcdf.h
   and removed include/netcdf_filter.h as no longer needed.
5. Force the test filter (bzip2) in nc_test4/filter_test to
   be built using BUILT_SOURCES.
This commit is contained in:
Dennis Heimbigner 2017-10-08 15:56:45 -06:00
commit 733da154c5
86 changed files with 1724 additions and 1076 deletions

View File

@ -758,16 +758,25 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
ENDIF(USE_HDF5 OR ENABLE_NETCDF_4)
# Option to turn on CDF5 support.
OPTION(ENABLE_CDF5 "Enable CDF5 Support." OFF)
IF(ENABLE_CDF5)
SET(USE_CDF5 ON CACHE BOOL "")
ENDIF(ENABLE_CDF5)
# Option to Build DAP2+DAP4 Clients
OPTION(ENABLE_DAP "Enable DAP2 and DAP4 Client." ON)
IF(ENABLE_DAP)
SET(USE_DAP ON)
SET(ENABLE_DAP2 ON)
SET(ENABLE_DAP4 ON)
IF(NOT ENABLE_NETCDF_4)
SET(ENABLE_DAP4 OFF)
ENDIF()
SET(USE_DAP ON CACHE BOOL "")
SET(ENABLE_DAP2 ON CACHE BOOL "")
IF(ENABLE_NETCDF_4)
SET(ENABLE_DAP4 ON CACHE BOOL "")
ELSE(ENABLE_NETCDF_4)
SET(ENABLE_DAP4 OFF CACHE BOOL "")
ENDIF(ENABLE_NETCDF_4)
FIND_PACKAGE(CURL)
IF(NOT CURL_LIBRARY)
MESSAGE(FATAL_ERROR "DAP Support specified, CURL libraries are not found.")
@ -806,6 +815,12 @@ IF(ENABLE_DAP)
#include <curl/curl.h>
int main() {int x = CURLOPT_CHUNK_BGN_FUNCTION;}" HAVE_CURLOPT_CHUNK_BGN_FUNCTION)
# Check to see if CURLINFO_HTTP_CONNECTCODE is defined.
# It showed up in curl 7.10.7.
CHECK_C_SOURCE_COMPILES("
#include <curl/curl.h>
int main() {int x = CURLINFO_HTTP_CONNECTCODE;}" HAVE_CURLINFO_HTTP_CONNECTCODE)
ELSE()
SET(ENABLE_DAP2 OFF)
SET(ENABLE_DAP4 OFF)
@ -1887,11 +1902,13 @@ is_enabled(STATUS_PNETCDF HAS_PNETCDF)
is_enabled(STATUS_PARALLEL HAS_PARALLEL)
is_enabled(ENABLE_PARALLEL4 HAS_PARALLEL4)
is_enabled(ENABLE_DAP HAS_DAP)
is_enabled(ENABLE_DAP HAS_DAP2)
is_enabled(ENABLE_DAP4 HAS_DAP4)
is_enabled(USE_DISKLESS HAS_DISKLESS)
is_enabled(USE_MMAP HAS_MMAP)
is_enabled(JNA HAS_JNA)
is_enabled(STATUS_RELAX_COORD_BOUND RELAX_COORD_BOUND)
is_enabled(USE_CDF5 HAS_CDF5)
# Generate file from template.
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/libnetcdf.settings.in"

View File

@ -10,6 +10,13 @@ This file contains a high-level description of this package's evolution. Release
reading and writing. See the file docs/filters.md.
* [Bug Fix] Corrected an issue with diskless file access, see [Pull Request #400](https://github.com/Unidata/netcdf-c/issues/400) and [Pull Request #403](https://github.com/Unidata/netcdf-c/issues/403) for more information.
### 4.5.0-rc3 - September 29, 2017
* [Update] Due to ongoing issues, native CDF5 support has been disabled by **default**. You can use the options mentioned below (`--enable-cdf5` or `-DENABLE_CDF5=TRUE` for `configure` or `cmake`, respectively). Just be aware that for the time being, Reading/Writing CDF5 files on 32-bit platforms may result in unexpected behavior when using extremely large variables. For 32-bit platforms it is best to continue using `NC_FORMAT_64BIT_OFFSET`.
* [Bug] Corrected an issue where older versions of curl might fail. See [GitHub #487](https://github.com/Unidata/netcdf-c/issues/487) for more information.
* [Enhancement] Added options to enable/disable `CDF5` support at configure time for autotools and cmake-based builds. The options are `--enable/disable-cdf5` and `ENABLE_CDF5`, respectively. See [Github #484](https://github.com/Unidata/netcdf-c/issues/484) for more information.
* [Bug Fix] Corrected an issue when subsetting a netcdf3 file via `nccopy -v/-V`. See [Github #425](https://github.com/Unidata/netcdf-c/issues/425) and [Github #463](https://github.com/Unidata/netcdf-c/issues/463) for more information.
* [Bug Fix] Corrected `--has-dap` and `--has-dap4` output for cmake-based builds. See [GitHub #473](https://github.com/Unidata/netcdf-c/pull/473) for more information.
* [Bug Fix] Corrected an issue where `NC_64BIT_DATA` files were being read incorrectly by ncdump, despite the data having been written correctly. See [GitHub #457](https://github.com/Unidata/netcdf-c/issues/457) for more information.
* [Bug Fix] Corrected a potential stack buffer overflow. See [GitHub #450](https://github.com/Unidata/netcdf-c/pull/450) for more information.

12
cf
View File

@ -19,11 +19,6 @@ if test "x$PNETCDF" = x1 -o "x$PAR4" = x1 ; then
MPIO=1
fi
#RPC=1
#M32=1
#M64=1
CFLAGS=""
#CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wconversion ${CFLAGS}"
CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wno-char-subscripts -Wno-pointer-sign -Wno-format ${CFLAGS}"
@ -48,6 +43,11 @@ if test "x$HDF4" = x1 ; then
HDF5=1
fi
# !HDF5=>!SZIP
if test "x$HDF5" != x1 ; then
SZIP=0
fi
CC=gcc
MALLOC_CHECK=""
@ -105,7 +105,7 @@ FLAGS="$FLAGS --enable-extra-tests"
#FLAGS="$FLAGS --disable-testsets"
#FLAGS="$FLAGS --disable-dap-remote-tests"
#FLAGS="$FLAGS --enable-dap-auth-tests" -- requires a new remotetest server
#FLAGS="$FLAGS --enable-doxygen"
FLAGS="$FLAGS --enable-doxygen --enable-internal-docs"
FLAGS="$FLAGS --enable-logging"
#FLAGS="$FLAGS --disable-diskless"
#FLAGS="$FLAGS --enable-mmap"

View File

@ -1,5 +1,5 @@
# Visual Studio
#VS=1
VS=1
#VSSETUP=1
#export NCPATHDEBUG=1

View File

@ -14,12 +14,12 @@
*/
#cmakedefine HAVE_WINSOCK2_H
/* #cmakedefine HAVE_WINSOCK2_H
#ifdef HAVE_WINSOCK2_H
#define _WINSOCKAPI_
#endif
*/
#if _MSC_VER>=1900
#define STDC99
#endif
@ -107,6 +107,10 @@ are set when opening a binary file on Windows. */
/* set this only when building a DLL under MinGW */
#cmakedefine DLL_NETCDF 1
/* if true, enable CDF5 Support */
#cmakedefine ENABLE_CDF5 1
#cmakedefine USE_CDF5 1
/* if true, build DAP2 and DAP4 Client */
#cmakedefine ENABLE_DAP 1
@ -147,6 +151,9 @@ are set when opening a binary file on Windows. */
/* Is CURLINFO_RESPONSE_CODE defined */
#cmakedefine HAVE_CURLINFO_RESPONSE_CODE 1
/* Is CURLINFO_HTTP_CODE defined */
#cmakedefine HAVE_CURLINFO_HTTP_CONNECTCODE 1
/* Is CURLOPT_CHUNK_BGN_FUNCTION defined */
#cmakedefine HAVE_CURLOPT_CHUNK_BGN_FUNCTION 1

View File

@ -441,6 +441,22 @@ AC_MSG_RESULT([$enable_dap_long_tests])
AM_CONDITIONAL(INTERNAL_OCLIB,[test "x" = "x"])
# Check whether we want to enable CDF5 support.
AC_MSG_CHECKING([whether CDF5 support should be enabled (default off)])
AC_ARG_ENABLE([cdf5],
[AS_HELP_STRING([--enable-cdf5],
[build with CDF5 support.])])
test "x$enable_cdf5" = xyes || enable_cdf5=no
AC_MSG_RESULT($enable_cdf5)
if test "x$enable_cdf5" = xyes; then
AC_DEFINE([USE_CDF5], [1], [if true, enable CDF5 Support])
AC_DEFINE([ENABLE_CDF5], [1], [if true, enable CDF5 Support])
fi
AM_CONDITIONAL(USE_CDF5, [test x$enable_cdf5 = xyes ])
AM_CONDITIONAL(ENABLE_CDF5, [test x$enable_cdf5 = xyes ])
# Does the user want to do some extra tests?
AC_MSG_CHECKING([whether netCDF extra tests should be run (developers only)])
AC_ARG_ENABLE([extra-tests],
@ -1000,11 +1016,15 @@ if test "x$enable_netcdf_4" = xyes; then
fi
# The user may have built HDF5 with the SZLIB library.
enable_szlib=no
if test "x$ac_cv_func_H5Z_SZIP" = xyes; then
AC_SEARCH_LIBS([SZ_Compress], [szip sz], [], [])
enable_szlib=yes
AC_SEARCH_LIBS([ SZ_Compress], [szip sz], [], [])
AC_DEFINE([USE_SZIP], [1], [if true, compile in szip compression in netCDF-4 variables])
fi
if test "x$ac_cv_func_H5free_memory" = xyes; then
AC_DEFINE([HDF5_HAS_H5FREE], [1], [if true, H5free_memory() will be used to free hdf5-allocated memory in nc4file.])
fi
@ -1249,7 +1269,7 @@ AM_CONDITIONAL(USE_DAP, [test "x$enable_dap" = xyes]) # Alias
# Provide protocol specific flags
AM_CONDITIONAL(ENABLE_DAP, [test "x$enable_dap" = xyes])
AM_CONDITIONAL(ENABLE_DAP4, [test "x$enable_dap4" = xyes])
AM_CONDITIONAL(ENABLE_CDF5, [test "x$enable_cdf5" = xyes])
AM_CONDITIONAL(ENABLE_DAP_REMOTE_TESTS, [test "x$enable_dap_remote_tests" = xyes])
AM_CONDITIONAL(ENABLE_DAP_AUTH_TESTS, [test "x$enable_dap_auth_tests" = xyes])
AM_CONDITIONAL(ENABLE_DAP_LONG_TESTS, [test "x$enable_dap_long_tests" = xyes])
@ -1374,14 +1394,16 @@ AM_CONDITIONAL(ENABLE_FILTER_TEST, [test x$enable_filter_test = xyes])
AC_SUBST(NC_LIBS,[$NC_LIBS])
AC_SUBST(HAS_DAP,[$enable_dap])
AC_SUBST(HAS_DAP2,[$enable_dap])
AC_SUBST(HAS_DAP4,[$enable_dap4])
AC_SUBST(HAS_NC2,[$nc_build_v2])
AC_SUBST(HAS_NC4,[$enable_netcdf_4])
AC_SUBST(HAS_CDF5,[$enable_cdf5])
AC_SUBST(HAS_HDF4,[$enable_hdf4])
AC_SUBST(HAS_PNETCDF,[$enable_pnetcdf])
AC_SUBST(HAS_HDF5,[$enable_netcdf_4])
AC_SUBST(HAS_LOGGING, [$enable_logging])
AC_SUBST(HAS_SZLIB,[$ac_cv_func_H4Z_SZIP])
AC_SUBST(HAS_SZLIB,[$enable_szlib])
AC_SUBST(HAS_PARALLEL,[$enable_parallel])
AC_SUBST(HAS_PARALLEL4,[$enable_parallel4])
AC_SUBST(HAS_DISKLESS,[$enable_diskless])
@ -1445,7 +1467,7 @@ AX_SET_META([NC_HAS_NC4],[$enable_netcdf_4],[yes])
AX_SET_META([NC_HAS_HDF4],[$enable_hdf4],[yes])
AX_SET_META([NC_HAS_HDF5],[$enable_netcdf_4],[yes])
AX_SET_META([NC_HAS_SZIP],[$ac_cv_func_H5Z_SZIP],[yes])
AX_SET_META([NC_HAS_DAP],[$enable_dap],[yes])
AX_SET_META([NC_HAS_DAP2],[$enable_dap],[yes])
AX_SET_META([NC_HAS_DAP4],[$enable_dap4],[yes])
AX_SET_META([NC_HAS_DISKLESS],[$enable_diskless],[yes])
AX_SET_META([NC_HAS_MMAP],[$enable_mmap],[yes])
@ -1453,6 +1475,7 @@ AX_SET_META([NC_HAS_JNA],[$enable_jna],[yes])
AX_SET_META([NC_HAS_PNETCDF],[$enable_pnetcdf],[yes])
AX_SET_META([NC_HAS_PARALLEL],[$enable_parallel],[yes])
AX_SET_META([NC_HAS_PARALLEL4],[$enable_parallel4],[yes])
AX_SET_META([NC_HAS_CDF5],[$enable_cdf5],[yes])
# Automake says that this is always run in top_builddir
# and that srcdir is defined (== top_srcdir)

View File

@ -51,7 +51,7 @@ EXTRA_DIST = test_parse.sh test_meta.sh test_data.sh \
test_raw.sh test_remote.sh test_hyrax.sh \
d4test_common.sh \
daptestfiles dmrtestfiles cdltestfiles nctestfiles \
baseline baselineraw baselineremote
baseline baselineraw baselineremote CMakeLists.txt
CLEANFILES = *.exe

View File

@ -74,6 +74,6 @@ IF(ENABLE_DOXYGEN)
ENDIF(ENABLE_DOXYGEN)
SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am netcdf.m4 DoxygenLayout.xml Doxyfile.in Doxyfile.guide.in footer.html mainpage.dox tutorial.dox dispatch.dox guide.dox types.dox notes.md cdl.dox architecture.dox internal.dox install-fortran.dox Doxyfile.in.cmake windows-binaries.md building-with-cmake.md install.md)
SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am netcdf.m4 DoxygenLayout.xml Doxyfile.in Doxyfile.guide.in footer.html mainpage.dox tutorial.dox guide.dox types.dox notes.md cdl.dox architecture.dox internal.dox install-fortran.dox Doxyfile.in.cmake windows-binaries.md building-with-cmake.md install.md)
ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")

View File

@ -748,7 +748,6 @@ INPUT = \
@abs_top_srcdir@/RELEASE_NOTES.md \
@abs_top_srcdir@/docs/install.md \
@abs_top_srcdir@/docs/install-fortran.md \
@abs_top_srcdir@/docs/dispatch.dox \
@abs_top_srcdir@/docs/types.dox \
@abs_top_srcdir@/docs/internal.dox \
@abs_top_srcdir@/docs/windows-binaries.md \

View File

@ -5,7 +5,7 @@
# These files will be included with the dist.
EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html \
mainpage.dox tutorial.dox dispatch.dox \
mainpage.dox tutorial.dox \
guide.dox types.dox cdl.dox \
architecture.dox internal.dox windows-binaries.md \
building-with-cmake.md CMakeLists.txt \

View File

@ -25,11 +25,14 @@ It is strongly recommended that applicable conventions be followed unless there
<p>
> It is not necessary to define your own _FillValue attribute for a variable if the default fill value for the type of the variable is adequate. However, use of the default fill value for data type byte is not recommended. Note that if you change the value of this attribute, the changed value applies only to subsequent writes; previously written data are not changed.
> If _FillValue is undefined, it is assumed that there are no unwritten data-values. Generic applications needing to write a value to represent undefined or missing values may use either `_FillValue` or `missing_value` for this purpose. It is legal (but not recommended) for the fill value to be within the valid range of the data.
<p>
> Generic applications often need to write a value to represent undefined or missing values. The fill value provides an appropriate value for this purpose because it is normally outside the valid range and therefore treated as missing when read by generic applications. It is legal (but not recommended) for the fill value to be within the valid range.
> Generic applications often need to write a value to represent undefined or missing values. The fill value provides an appropriate value for this purpose because it is normally outside the valid range and therefore treated as missing when read by generic applications. It is legal (but not recommended) for the fill value to be within the valid range.
> **Note that if you change the value of this attribute, the changed value applies only to subsequent writes; previously written data are not changed.**
`missing_value`
@ -183,4 +186,3 @@ Using the following API calls will fail.
> The type of this attribute is NC_INT.
> This attribute is computed by using the HDF5 API to walk the file to look for attributes specific to netcdf-4. False negatives are possible for a small subset of netcdf-4 files, especially those not containing dimensions. False positives are only possible by deliberate modifications to an existing HDF5 file thru the HDF5 API. For files with the _NCProperties attribute, this attribute is redundant. For files created prior to the introduction of the _NCProperties attribute, this may be a useful indicator of the provenance of the file.

View File

@ -1,5 +1,5 @@
netCDF Authorization Support
============================
======================================
<!-- double header is needed to workaround doxygen bug -->
# netCDF Authorization Support {#Header}
@ -37,29 +37,92 @@ directly insert the username and the password into a url in this form.
This username and password will be used if the server asks for
authentication. Note that only simple password authentication
is supported in this format.
Specifically note that [redirection-based](#REDIR)
authorization will not work with this because the username and password
will only be used on the initial request, not the redirection
authorization may work with this but it is a security risk.
This is because the username and password
may be sent to each server in the redirection chain.
Note also that the `user:password` form may contain characters that must be
escaped. See the <a href="#USERPWDESCAPE">password escaping</a> section to see
how to properly escape the user and password.
## RC File Authentication {#DODSRC}
The netcdf library supports an _rc_ file mechanism to allow the passing
of a number of parameters to libnetcdf and libcurl.
Locating the _rc_ file is a multi-step process.
### Search Order
The file must be called one of the following names:
".daprc" or ".dodsrc".
If both ".daprc" and ".dodsrc" exist, then
the ".daprc" file will take precedence.
The rc file is searched for first in the current directory
and then in the home directory (as defined by the HOME environment
variable).
It is strongly suggested that you pick one of the two names
and use it always. Otherwise you may observe unexpected results
when the netcdf-c library finds one that you did not intend.
The search for an _rc_ file looks in the following places in this order.
1. Check for the environment variable named _DAPRCFILE_.
This will specify the full path for the _rc_ file
(not just the containing directory).
2. Search the current working directory (`./`) looking
for (in order) .daprc or .dodsrc.
3. Search the HOME directory (`$HOME`) looking
for (in order) .daprc or .dodsrc. The HOME environment
variable is used to define the directory in which to search.
It is strongly suggested that you pick a uniform location
and use it always. Otherwise you may observe unexpected results
when the netcdf-c library get an rc file you did not expect.
### RC File Format
The rc file format is a series of lines of the general form:
[<host:port>]<key>=<value>
where the bracket-enclosed host:port is optional and will be discussed
subsequently.
where the bracket-enclosed host:port is optional.
### URL Constrained RC File Entries
Each line of the rc file can begin with
a host+port enclosed in square brackets.
The form is "host:port".
If the port is not specified
then the form is just "host".
The reason that more of the url is not used is that
libcurl's authorization grain is not any finer than host level.
Examples.
[remotetest.unidata.ucar.edu]HTTP.VERBOSE=1
or
[fake.ucar.edu:9090]HTTP.VERBOSE=0
If the url request from, say, the _netcdf_open_ method
has a host+port matching one of the prefixes in the rc file, then
the corresponding entry will be used, otherwise ignored.
This means that an entry with a matching host+port will take
precedence over an entry without a host+port.
For example, the URL
http://remotetest.unidata.ucar.edu/thredds/dodsC/testdata/testData.nc
will have HTTP.VERBOSE set to 1 because its host matches the example above.
Similarly,
http://fake.ucar.edu:9090/dts/test.01
will have HTTP.VERBOSE set to 0 because its host+port matches the example above.
## Authorization-Related Keys {#AUTHKEYS}
The currently defined set of authorization-related keys are as follows.
The second column is the affected curl_easy_setopt option(s), if any.
@ -71,12 +134,12 @@ The second column is the affected curl_easy_setopt option(s), if any.
<tr><td>HTTP.SSL.CERTIFICATE</td><td>CURLOPT_SSLCERT</td>
<tr><td>HTTP.SSL.KEY</td><td>CURLOPT_SSLKEY</td>
<tr><td>HTTP.SSL.KEYPASSWORD</td><td>CURLOPT_KEYPASSWORD</td>
<tr><td>HTTP.SSL.CAINFO</td><td>CURLOPT_SSLCAINFO</td>
<tr><td>HTTP.SSL.CAPATH</td><td>CURLOPT_SSLCAPATH</td>
<tr><td>HTTP.SSL.CAINFO</td><td>CURLOPT_CAINFO</td>
<tr><td>HTTP.SSL.CAPATH</td><td>CURLOPT_CAPATH</td>
<tr><td>HTTP.SSL.VERIFYPEER</td><td>CURLOPT_SSL_VERIFYPEER</td>
<tr><td>HTTP.SSL.VALIDATE</td><td>CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST</td>
<tr><td>HTTP.CREDENTIALS.USERPASSWORD</td><td>CURLOPT_USERPASSWORD</td>
<tr><td>HTTP.NETRC</td><td>N.A.</td><td>Specify path of the .netrc file</td>
<tr><td>HTTP.NETRC</td><td>CURLOPT_NETRC,CURLOPT_NETRC_FILE</td>
</table>
### Password Authentication
@ -86,7 +149,9 @@ HTTP.CREDENTIALS.USERPASSWORD
can be used to set the simple password authentication.
This is an alternative to setting it in the url.
The value must be of the form "username:password".
See <a href="#REDIR">redirection authorization</a>
See the <a href="#USERPWDESCAPE">password escaping</a> section
to see how this value must escape certain characters.
Also see <a href="#REDIR">redirection authorization</a>
for important additional information.
### Cookie Jar
@ -129,6 +194,29 @@ specifies the absolute path of the .netrc file.
See [redirection authorization](#REDIR)
for information about using .netrc.
## Password Escaping {#USERPWDESCAPE}
With current password rules, it is is not unlikely that the password
will contain characters that need to be escaped. Similarly, the user
may contain characters such as '@' that need to be escaped. To support this,
it is assumed that all occurrences of `user:password` use URL (i.e. %%XX)
escaping for at least the characters in the table below.
The minimum set of characters that must be escaped depends on the location.
If the user+pwd is embedded in the URL, then '@' and ':' __must__ be escaped.
If the user+pwd is the value for
the HTTP.CREDENTIALS.USERPASSWORD key in the _rc_ file, then
':' __must__ be escaped.
Escaping should __not__ be used in the `.netrc` file.
The relevant escape codes are as follows.
<table>
<tr><th>Character</th><th>Escaped Form</th>
<tr><td>'@'</td><td>%40</td>
<tr><td>':'</td><td>%3a</td>
</table>
Additional characters can be escaped if desired.
## Redirection-Based Authentication {#REDIR}
Some sites provide authentication by using a third party site
@ -145,16 +233,18 @@ using the _https_ protocol (note the use of _https_ instead of _http_).
4. URS sends a redirect (with authorization information) to send
the client back to the SOI to actually obtain the data.
It turns out that libcurl uses the password in the `.daprc`
file (or from the url)
only for the initial connection. This causes problems because
the redirected connection is the one that actually requires the password.
This is where the `.netrc` file comes in. Libcurl will use `.netrc` for
the redirected connection. It is possible to cause libcurl to use
the `.daprc` password always, but this introduces a security hole
because it may send the initial user+pwd to the redirection site.
In summary, if you are using redirection, then you must create a `.netrc`
file to hold the password for the site to which the redirection is sent.
It turns out that libcurl, by default, uses the password in the
`.daprc` file (or from the url) for all connections that request
a password. This causes problems because only the the specific
redirected connection is the one that actually requires the password.
This is where the `.netrc` file comes in. Libcurl will use `.netrc`
for the redirected connection. It is possible to cause libcurl
to use the `.daprc` password always, but this introduces a
security hole because it may send the initial user+pwd to every
server in the redirection chain.
In summary, if you are using redirection, then you are
''strongly'' encouraged to create a `.netrc` file to hold the
password for the site to which the redirection is sent.
The format of this `.netrc` file will contain lines that
typically look like this.
@ -165,52 +255,19 @@ where the machine, mmmmmm, is the hostname of the machine to
which the client is redirected for authorization, and the
login and password are those needed to authenticate on that machine.
The `.netrc` file can be specified by
The location of the `.netrc` file can be specified by
putting the following line in your `.daprc`/`.dodsrc` file.
HTTP.NETRC=<path to netrc file>
If not specified, then libcurl will look first in the current
directory, and then in the HOME directory.
One final note. In using this, you MUST
to specify a real file in the file system to act as the
cookie jar file (HTTP.COOKIEJAR) so that the
redirect site can properly pass back authorization information.
## URL Constrained RC File Entries {#URLCONS}
Each line of the rc file can begin with
a host+port enclosed in square brackets.
The form is "host:port".
If the port is not specified
then the form is just "host".
The reason that more of the url is not used is that
libcurl's authorization grain is not any finer than host level.
Examples.
[remotetest.unidata.ucar.edu]HTTP.VERBOSE=1
or
[fake.ucar.edu:9090]HTTP.VERBOSE=0
If the url request from, say, the _netcdf_open_ method
has a host+port matching one of the prefixes in the rc file, then
the corresponding entry will be used, otherwise ignored.
This means that an entry with a matching host+port will take
precedence over an entry without a host+port.
For example, the URL
http://remotetest.unidata.ucar.edu/thredds/dodsC/testdata/testData.nc
will have HTTP.VERBOSE set to 1 because its host matches the example above.
Similarly,
http://fake.ucar.edu:9090/dts/test.01
will have HTTP.VERBOSE set to 0 because its host+port matches the example above.
## Client-Side Certificates {#CLIENTCERTS}
Some systems, notably ESG (Earth System Grid), requires
@ -244,8 +301,8 @@ the code is definitive.
<tr><td>HTTP.SSL.CERTIFICATE</td><td>CUROPT_SSLCERT</td>
<tr><td>HTTP.SSL.KEY</td><td>CUROPT_SSLKEY</td>
<tr><td>HTTP.SSL.KEYPASSWORD</td><td>CUROPT_KEYPASSWORD</td>
<tr><td>HTTP.SSL.CAINFO</td><td>CUROPT_SSLCAINFO</td>
<tr><td>HTTP.SSL.CAPATH</td><td>CUROPT_SSLCAPATH</td>
<tr><td>HTTP.SSL.CAINFO</td><td>CUROPT_CAINFO</td>
<tr><td>HTTP.SSL.CAPATH</td><td>CUROPT_CAPATH</td>
<tr><td>HTTP.SSL.VERIFYPEER</td><td>CUROPT_SSL_VERIFYPEER</td>
<tr><td>HTTP.CREDENTIALS.USERPASSWORD</td><td>CUROPT_USERPASSWORD</td>
<tr><td>HTTP.NETRC</td><td>CURLOPT_NETRC,CURLOPT_NETRC_FILE</td>

View File

@ -66,16 +66,42 @@ using __ncgen__, via an API call, or via command line parameters to __nccopy__.
In any case, remember that filtering also requires setting chunking, so the
variable must also be marked with chunking information.
Using The API {#API}
-------------
The necessary API methods are included in __netcdf.h__ by default.
One API method is for setting the filter to be used
when writing a variable. The relevant signature is
as follows.
````
int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
````
This must be invoked after the variable has been created and before
__nc_enddef__ is invoked.
A second API methods makes it possible to query a variable to
obtain information about any associated filter using this signature.
````
int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
````
The filter id wil be returned in the __idp__ argument (if non-NULL),
the number of parameters in __nparamsp__ and the actual parameters in
__params__. As is usual with the netcdf API, one is expected to call
this function twice. The first time to get __nparams__ and the
second to get the parameters in client-allocated memory.
Using ncgen {#NCGEN}
-------------
In a CDL file, compression of a variable can be specified
by annotating it with the following attribute:
1. ''_Filter'' -- a string containing a comma separated list of
unsigned integers specifying (1) the filter id to apply, and (2)
a vector of unsigned integers representing the
* ''_Filter'' -- a string containing a comma separated list of
constants specifying (1) the filter id to apply, and (2)
a vector of constants representing the
parameters for controlling the operation of the specified filter.
See the section on the <a href="#Syntax">parameter encoding syntax</a>
for the details on the allowable kinds of constants.
This is a "special" attribute, which means that
it will normally be invisible when using
@ -97,30 +123,6 @@ data:
}
````
Using The API {#API}
-------------
The include file, __netcdf_filter.h__ defines
an API method for setting the filter to be used
when writing a variable. The relevant signature is
as follows.
````
int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
````
This must be invoked after the variable has been created and before
__nc_enddef__ is invoked.
It is also possible to query a variable to obtain information about
any associated filter using this signature.
````
int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
````
The filter id wil be returned in the __idp__ argument (if non-NULL),
the number of parameters in __nparamsp__ and the actual parameters in
__params__. As is usual with the netcdf API, one is expected to call
this function twice. The first time to get __nparams__ and the
second to get the parameters in client-allocated memory.
Using nccopy {#NCCOPY}
-------------
When copying a netcdf file using __nccopy__ it is possible
@ -133,6 +135,8 @@ Assume that __unfiltered.nc__ has a chunked but not bzip2 compressed
variable named "var". This command will create that variable in
the __filtered.nc__ output file but using filter with id 307
(i.e. bzip2) and with parameter(s) 9 indicating the compression level.
See the section on the <a href="#Syntax">parameter encoding syntax</a>
for the details on the allowable kinds of constants.
The "-F" option can be used repeatedly as long as the variable name
part is different. A different filter id and parameters can be
@ -146,7 +150,7 @@ the netcdf-c library.
Parameter Encoding {#ParamEncode}
==========
The parameters passed to a filter are encoded in a vector
The parameters passed to a filter are encoded internally as a vector
of 32-bit unsigned integers. It may be that the parameters
required by a filter can naturally be encoded as unsigned integers.
The bzip2 compression filter, for example, expects a single
@ -210,6 +214,51 @@ byte order (big-endian) so that the filter always assumes it is getting
its parameters in network order and will always do swapping as needed.
This is irritating, but one needs to be aware of it.
Filter Specification Syntax {#Syntax}
==========
Both of the utilities
<a href="#NCGEN">__ncgen__</a>
and
<a href="#NCCOPY">__nccopy__</a>
allow the specification of filter parameters.
These specifications consist of a sequence of comma
separated constants. The constants are converted
within the utility to a proper set of unsigned int
constants (see the <a href="#ParamEncode">parameter encoding section</a>).
To simplify things, various kinds of constants can be specified
rather than just simple unsigned integers. The utilities will encode
them properly using the rules specified in
the <a href="#ParamEncode">parameter encoding section</a>.
The currently supported constants are as follows.
<table>
<tr halign="center"><th>Example<th>Type<th>Format Tag<th>Notes
<tr><td>-17b<td>signed 8-bit byte<td>b|B<td>
<tr><td>23ub<td>unsigned 8-bit byte<td>u|U b|B<td>
<tr><td>-25S<td>signed 16-bit short<td>s|S<td>
<tr><td>27US<td>unsigned 16-bit short<td>u|U s|S<td>
<tr><td>-77<td>implicit signed 32-bit integer<td>Leading minus sign and no tag<td>
<tr><td>77<td>implicit unsigned 32-bit integer<td>No tag<td>
<tr><td>93U<td>explicit unsigned 32-bit integer<td>u|U<td>
<tr><td>789f<td>32-bit float<td>f|F<td>
<tr><td>12345678.12345678d<td>64-bit double<td>d|D<td>Network byte order
<tr><td>-9223372036854775807L<td>64-bit signed long long<td>l|L<td>Network byte order
<tr><td>18446744073709551615UL<td>64-bit unsigned long long<td>u|U l|L<td>Network byte order
</table>
Some things to note.
1. In all cases, except for an untagged positive integer,
the format tag is required and determines how the constant
is converted to one or two unsigned int values.
The positive integer case is for backward compatibility.
2. For signed byte and short, the value is sign extended to 32 bits
and then treated as an unsigned int value.
3. For double, and signed|unsigned long long, they are converted
to network byte order and then treated as two unsigned int values.
This is consistent with the <a href="#ParamEncode">parameter encoding</a>.
Dynamic Loading Process {#Process}
==========
@ -297,6 +346,43 @@ non-standard platform.
Although it is fragile, this test can serve as a complete example for building
plugins for other filters.
Appendix A. Byte Swap Code {#AppendixA}
==========
Since in some cases, it is necessary for a filter to
byte swap from network byte order to little endian, This appendix
provides sample code for doing this. It also provides
a code snippet for testing if the machine is big-endian.
Byte swap an 8-byte chunk of memory
-------
````
static void
byteswap8(unsigned char* mem)
{
unsigned char c;
c = mem[0];
mem[0] = mem[7];
mem[7] = c;
c = mem[1];
mem[1] = mem[6];
mem[6] = c;
c = mem[2];
mem[2] = mem[5];
mem[5] = c;
c = mem[3];
mem[3] = mem[4];
mem[4] = c;
}
````
Test for Big-Endian Machine
-------
````
static const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
int bigendian = (1 == *(unsigned int*)b);
````
References {#References}
==========

View File

@ -6,24 +6,32 @@
This document describes the architecture and details of the netCDF
internal dispatch mechanism. The idea is that when a user opens or
creates a netcdf file, a specific dispatch table is
chosen. Subsequent netcdf API calls are then channeled through that
creates a netcdf file, a specific dispatch table is chosen.
A dispatch table is a struct containing an entry for every function
in the netcdf-c API.
Subsequent netcdf API calls are then channeled through that
dispatch table to the appropriate function for implementing that API
call.
call. The functions in the dispatch table are not quite the same
as those defined in netcdf.h. For simplicity and compactness,
some netcdf.h API calls are
mapped to the same dispatch table function. In addition to
the functions, the first entry in the table defines the model
that this dispatch table implements. It will be one of the
NC_FORMATX_XXX values.
At least the following dispatch tables are supported.
The list of supported dispatch tables will grow over time.
To date, at least the following dispatch tables are supported.
- netcdf classic files (netcdf-3)
- netcdf enhanced files (netcdf-4)
- OPeNDAP to netcdf-3
- OPeNDAP to netcdf-4
- DAP2 to netcdf-3
- DAP4 to netcdf-4
- pnetcdf (parallel cdf5)
Internal Dispatch Tables
- \subpage adding_dispatch
- \subpage dispatch_notes
- \subpage put_vara_dispatch
- \subpage put_attr_dispatch
The dispatch table represents a distillation of the netcdf API down to
a minimal set of internal operations. The format of the dispatch table
is defined in the file libdispatch/ncdispatch.h. Every new dispatch
@ -36,12 +44,15 @@ table must define this minimal set of operations.
In order to make this process concrete, let us assume we plan to add
an in-memory implementation of netcdf-3.
\section dispatch_step1 Step 1.
\section dispatch_configure_ac Defining configure.ac flags
Define a enable flag and an AM_CONFIGURE flag in configure.ac. We
will use the flags enable-netcdfm and USE_NETCDFM respectively.
Define a -enable flag and an AM_CONFIGURE flag in configure.ac.
For our example, we assume the option "--enable-ncm" and the AM_CONFIGURE
flag "ENABLE_NCM". If you examine the existing configure.ac and see how,
for example, dap2 is defined, then it should be clear how to do it for
your code.
\section dispatch_step2 Step 2.
\section dispatch_namespace Defining a "name space"
Choose some prefix of characters to identify the new dispatch
system. In effect we are defining a name-space. For our in-memory
@ -49,94 +60,66 @@ system, we will choose "NCM" and "ncm". NCM is used for non-static
procedures to be entered into the dispatch table and ncm for all other
non-static procedures.
\section dispatch_step3 Step 3.
\section dispatch_netcdf_h Extend include/netcdf.h
Modify file libdispatch/ncdispatch.h as follows.
Add a index for this implementation:
Modify file include/netcdf.h to add an NC_FORMATX_XXX flag
by adding a flag for this dispatch format at the appropriate places.
\code
#define NC_DISPATCH_NCM 5
#define NC_FORMATX_NCM 7
\endcode
Define an external reference to the in-memory dispatch table.
Add any format specific new error codes.
\code
#ifdef USE_NETCDFM
#define NC_ENCM (?)
\endcode
\section dispatch_ncdispatch Extend include/ncdispatch.h
Modify file include/ncdispatch.h as follows.
Add format specific data and functions; note the of our NCM namespace.
\code
#ifdef ENABLE_NCM
extern NC_Dispatch* NCM_dispatch_table;
extern int NCM_initialize(void);
#endif
\endcode
\section dispatch_step4 Step 4.
Modify file libdispatch/netcdf.c as follows.
Add a ptr to the in-memory dispatch table.
\code
#ifdef USE_NETCDFM
NC_Dispatch* NCM_dispatch_table = NULL;
#endif
\endcode
Add includes for any necessary header files as needed.
\section dispatch_step5 Step 5.
\section dispatch_define_code Define the dispatch table functions
Define the functions necessary to fill in the dispatch table. As a
rule, we assume that a new directory is defined, libsrcm, say. Within
this directory, we need to define Makefile.am, the source files
this directory, we need to define Makefile.am and CMakeLists.txt.
We also need to define the source files
containing the dispatch table and the functions to be placed in the
dispatch table call them ncmdispatch.c and ncmdispatch.h. Look at
libsrc/nc3dispatch.[ch] for an example.
libsrc/nc3dispatch.[ch] or libdap4/ncd4dispatch.[ch] for examples.
As part of the ncmdispatch.c file, you must define the following.
Similarly, it is best to take existing Makefile.am and CMakeLists.txt
files (from libdap4 for example) and modify them.
\code
NC_Dispatch NCM_dispatcher = {
NC_DISPATCH_NCM,
NCM_create,
NCM_open,
...
};
int
NCM_initialize(void)
{
NCM_dispatch_table = &NCM_dispatcher;
return NC_NOERR;
}
\endcode
Assuming that the in-memory library does not require any external
libraries, then the Makefile.am will look something like this.
\code
NCM_SOURCES = ncmdispatch.c ncmdispatch.h ...
AM_CPPFLAGS += -I$(top_srcdir)/libsrc -I$(top_srcdir)/libdispatch
libnetcdfm_la_SOURCES = $(NCM_SOURCES)
noinst_LTLIBRARIES = libnetcdfm.la
\endcode
\section dispatch_step6 Step 6.
\section dispatch_lib Adding the dispatch code to libnetcdf
Provide for the inclusion of this library in the final libnetcdf
library. This is accomplished by modifying liblib/Makefile.am by
adding something like the following.
\code
if USE_NETCDFM
if ENABLE_NCM
libnetcdf_la_LIBADD += $(top_builddir)/libsrcm/libnetcdfm.la
endif
\endcode
\section dispatch_step7 Step 7.
\section dispatch_init Extend library initialization
Modify the NC_initialize function in liblib/stub.c by adding
Modify the NC_initialize function in liblib/nc_initialize.c by adding
appropriate references to the NCM dispatch function.
\code
#ifdef USE_NETCDFM
#ifdef ENABLE_NCM
extern int NCM_initialize(void);
#endif
...
@ -150,7 +133,7 @@ appropriate references to the NCM dispatch function.
}
\endcode
\section dispatch_step8 Step 8.
\section dispatch_tests Testing the new dispatch table
Add a directory of tests; ncm_test, say. The file ncm_test/Makefile.am
will look something like this.
@ -169,13 +152,13 @@ will look something like this.
EXTRA_DIST = ...
\endcode
\section dispatch_step9 Step 9.
\section dispatch_toplevel Top-Level build of the dispatch code
Provide for libnetcdfm to be constructed by adding the following to
the top-level Makefile.am.
\code
if USE_NETCDFM
if ENABLE_NCM
NCM=libsrcm
NCMTESTDIR=ncm_test
endif
@ -186,29 +169,27 @@ the top-level Makefile.am.
\section choosing_dispatch_table Choosing a Dispatch Table
The dispatch table is chosen in the NC_create and the NC_open
procedures in libdispatch/netcdf.c. The decision is currently based on
the following pieces of information.
procedures in libdispatch/netcdf.c.
This can be, unfortunately, a complex process.
The file path this can be used to detect, for example, a DAP url
versus a normal file system file.
The decision is currently based on the following pieces of information.
Using a mode flag is the most common mechanism, in which case
netcdf.h needs to be modified to define the relevant mode flag.
The mode argument this can be used to detect, for example, what kind
1. The mode argument this can be used to detect, for example, what kind
of file to create: netcdf-3, netcdf-4, 64-bit netcdf-3, etc. For
nc_open and when the file path references a real file, the contents of
the file can also be used to determine the dispatch table. Although
currently not used, this code could be modified to also use other
pieces of information such as environment variables.
In addition to the above, there is one additional mechanism to force
the use of a specific dispatch table. The procedure
"NC_set_dispatch_override()" can be invoked to specify a dispatch
table.
2. The file path this can be used to detect, for example, a DAP url
versus a normal file system file.
When adding a new dispatcher, it is necessary to modify NC_create and
NC_open in libdispatch/netcdf.c to detect when it is appropriate to
NC_open in libdispatch/dfile.c to detect when it is appropriate to
use the NCM dispatcher. Some possibilities are as follows.
- Add a new mode flag: say NC_NETCDFM.
- Use an environment variable.
- Define a special file path format that indicates the need to use a
special dispatch table.
@ -217,65 +198,35 @@ use the NCM dispatcher. Some possibilities are as follows.
Several of the entries in the dispatch table are significantly
different than those of the external API.
\section create_open_dispatch Create/Open
\subsection create_open_dispatch Create/Open
The create table entry and the open table entry have the following
signatures respectively.
The create table entry and the open table entry in the dispatch table
have the following signatures respectively.
\code
int (*create)(const char *path, int cmode,
size_t initialsz, int basepe, size_t *chunksizehintp,
int useparallel, MPI_Comm comm, MPI_Info info,
struct NC_Dispatch*, struct NC** ncp);
int useparallel, void* parameters,
struct NC_Dispatch* table, NC* ncp);
\endcode
\code
int (*open)(const char *path, int mode,
int basepe, size_t *chunksizehintp,
int use_parallel, MPI_Comm comm, MPI_Info info,
NC_Dispatch*, NC** ncp);
int use_parallel, void* parameters,
struct NC_Dispatch* table, NC* ncp);
\endcode
The key difference is that these are the union of all the possible
create/open signatures from the netcdf.h API. Note especially the last
two parameters. The dispatch table is included in case the create
create/open signatures from the include/netcdfXXX.h files. Note especially the last
three parameters. The parameters argument is a pointer to arbitrary data
to provide extra info to the dispatcher.
The table argument is included in case the create
function (e.g. NCM_create) needs to invoke other dispatch
functions. The very last parameter is a pointer to a pointer to an NC
instance. It is expected that the create function will allocate and
fill in an instance of an "NC" object and return a pointer to it in
the ncp parameter.
\page dispatch_notes Dispatch Programming Notes
As with the existing code, and when MPI is not being used, the comm
and info parameters should be passed in as 0. This is taken care of in
the nc_open() and nc_create() API procedures in libdispatch/netcdf.c.
In fact, the object returned in the ncp parameter does not actually
have to be an instance of struct NC. It only needs to "look like it
for the first few fields. This is, in effect, a fake version of
subclassing. Let us suppose that the NCM_create function uses a struct
NCM object. The initial part of the definition of NCM must match the
fields at the beginning of struct NC between the comments BEGIN_COMMON
and END_COMMON. So, we would have the following.
\code
typedef struct NCM {
/*BEGIN COMMON*/
int ext_ncid; /* uid «« 16 */
int int_ncid; /* unspecified other id */
struct NC_Dispatch* dispatch;
#ifdef USE_DAP
struct NCDRNO* drno;
#endif
/*END COMMON*/
...
} NCM;
\endcode
This allows the pointer to the NCM object to be cast as an instance of
NC* and its pointer returned in the ncp file. Eventually, this will be
replaced with a separate structure containing the common fields.
functions. The very last argument, ncp, is a pointer to an NC
instance. The raw NC instance will have been created by libdispatch/dfile.c
and is passed to e.g. open with the expectation that it will be filled in
by the dispatch open function.
\page put_vara_dispatch Accessing Data with put_vara() and get_vara()

View File

@ -63,7 +63,6 @@ to be used for different types of back-ends, for example, the HDF5
library, or a DAP client accessing remote data.
- \ref nc_dispatch
- \ref adding_dispatch
- \ref dispatch_notes
- \ref put_vara_dispatch
- \ref put_attr_dispatch

View File

@ -22,9 +22,10 @@ The atomic external types supported by the netCDF interface are:
- ::NC_UINT64 64-bit unsigned integer *
- ::NC_FLOAT 32-bit floating point
- ::NC_DOUBLE 64-bit floating point
- ::NC_STRING variable length character string *
- ::NC_STRING variable length character string +
\remark{* These types are available only for CDF5 (NC_CDF5) and netCDF-4 format (NC_NETCDF4) files. All the unsigned ints (except \ref NC_CHAR), the 64-bit ints, and string type are for CDF5 or netCDF-4 files only.}
\remark * These types are available only for CDF5 (NC_CDF5) and netCDF-4 format (NC_NETCDF4) files. All the unsigned ints (except \ref NC_CHAR) and the 64-bit ints are for CDF5 or netCDF-4 files only.
\remark + These types are available only for netCDF-4 (NC_NETCDF4) files.
These types were chosen to provide a reasonably wide range of
trade-offs between data precision and number of bits required for each

View File

@ -10,10 +10,6 @@ INSTALL(FILES ${netCDF_SOURCE_DIR}/include/netcdf_mem.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT headers)
INSTALL(FILES ${netCDF_SOURCE_DIR}/include/netcdf_filter.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT headers)
INSTALL(FILES ${netCDF_BINARY_DIR}/include/netcdf_meta.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT headers)

View File

@ -4,7 +4,7 @@
# This automake file generates the Makefile to build the include
# directory.
include_HEADERS = netcdf.h netcdf_meta.h netcdf_filter.h
include_HEADERS = netcdf.h netcdf_meta.h
if BUILD_PARALLEL
include_HEADERS += netcdf_par.h
@ -19,7 +19,7 @@ nclist.h ncuri.h ncutf8.h ncdispatch.h ncdimscale.h \
netcdf_f.h err_macros.h ncbytes.h nchashmap.h ceconstraints.h rnd.h \
nclog.h ncconfigure.h nc4internal.h nctime.h nc3internal.h \
onstack.h nc_hashmap.h ncrc.h ncoffsets.h nctestserver.h \
nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h
nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h ncfilter.h
if USE_DAP
noinst_HEADERS += ncdap.h

25
include/ncfilter.h Normal file
View File

@ -0,0 +1,25 @@
/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
See the COPYRIGHT file for more information. */
#ifndef NCFILTER_H
#define NCFILTER_H 1
/* API for libdispatch/dfilter.c */
/* Must match values in <H5Zpublic.h> */
#ifndef H5Z_FILTER_SZIP
#define H5Z_FILTER_SZIP 4
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/* Provide consistent filter spec parser */
EXTERNL int NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
#if defined(__cplusplus)
}
#endif
#endif /* NCFILTER_H */

View File

@ -9,6 +9,10 @@
#define TIMEOUT 10 /*seconds*/
#define BUFSIZE 8192 /*bytes*/
#ifndef HAVE_CURLINFO_RESPONSE_CODE
#define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
#endif
static int ping(const char* url);
static char**

View File

@ -21,11 +21,11 @@
#define NCU_ECONSTRAINTS (11)
/* Define flags to control what is included by ncuribuild*/
#define NCURIPATH 1
#define NCURIPWD 2
#define NCURIQUERY 4
#define NCURIFRAG 8
#define NCURIENCODE 16 /* If output should be encoded */
#define NCURIPATH 1
#define NCURIPWD 2
#define NCURIQUERY 4
#define NCURIFRAG 8
#define NCURIENCODE 16 /* If output should be encoded */
#define NCURIBASE (NCURIPWD|NCURIPATH)
#define NCURISVC (NCURIQUERY|NCURIBASE) /* for sending to server */
#define NCURIALL (NCURIPATH|NCURIPWD|NCURIQUERY|NCURIFRAG) /* for rebuilding after changes */
@ -81,9 +81,13 @@ extern const char* ncurilookup(NCURI*, const char* param);
extern const char* ncuriquerylookup(NCURI*, const char* param);
/* URL Encode/Decode */
extern char* ncuriencode(char* s, char* allowable);
extern char* ncuridecode(char* s);
extern char* ncuridecodeonly(char* s, char*);
/* Partial decode */
extern char* ncuridecodepartial(char* s, const char* decodeset);
/* Encode using specified character set */
extern char* ncuriencodeonly(char* s, char* allowable);
/* Encode user or pwd */
extern char* ncuriencodeuserpwd(char* s);
#if defined(_CPLUSPLUS_) || defined(__CPLUSPLUS__) || defined(__CPLUSPLUS)
}

View File

@ -863,6 +863,14 @@ nc_def_var_endian(int ncid, int varid, int endian);
EXTERNL int
nc_inq_var_endian(int ncid, int varid, int *endianp);
/* Define a filter for a variable */
EXTERNL int
nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
/* Learn about the filter on a variable */
EXTERNL int
nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
/* Set the fill mode (classic or 64-bit offset files only). */
EXTERNL int
nc_set_fill(int ncid, int fillmode, int *old_modep);

View File

@ -1,34 +0,0 @@
/*! \file netcdf_filter.h
*
* Main header file for filter functionality.
*
* Copyright 2010 University Corporation for Atmospheric
* Research/Unidata. See COPYRIGHT file for more info.
*
* See \ref copyright file for more info.
*
*/
#ifndef NETCDF_FILTER_H
#define NETCDF_FILTER_H 1
#include <netcdf.h>
/* Must match values in <H5Zpublic.h> */
#ifndef H5Z_FILTER_SZIP
#define H5Z_FILTER_SZIP 4
#endif
#if defined(__cplusplus)
extern "C" {
#endif
EXTERNL int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
EXTERNL int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
#if defined(__cplusplus)
}
#endif
#endif /* NETCDF_FILTER_H */

View File

@ -48,6 +48,10 @@
#define NC_HAS_MMAP @NC_HAS_MMAP@ /*!< mmap support. */
#define NC_HAS_JNA @NC_HAS_JNA@ /*!< jna support. */
#define NC_HAS_PNETCDF @NC_HAS_PNETCDF@ /*!< pnetcdf support. */
#define NC_HAS_PARALLEL @NC_HAS_PARALLEL@ /*!< parallel IO support via hdf5 and/or pnetcdf. */
#define NC_HAS_PARALLEL @NC_HAS_PARALLEL@ /*!< parallel IO support via hdf5 and
/or pnetcdf. */
#define NC_HAS_CDF5 @NC_HAS_CDF5@ /*!< CDF5 support. */
#endif

View File

@ -6,7 +6,6 @@
#include "dapincludes.h"
#include "ncd2dispatch.h"
#include "ncoffsets.h"
#include "netcdf_filter.h"
#ifdef DEBUG2
#include "dapdump.h"
#endif

View File

@ -11,7 +11,9 @@ struct CURLFLAG curlopts[] = {
{"CURLOPT_PROXYUSERPWD",CURLOPT_PROXYUSERPWD,10006,CF_STRING},
{"CURLOPT_SSLCERT",CURLOPT_SSLCERT,10025,CF_STRING},
{"CURLOPT_SSLKEY",CURLOPT_SSLKEY,10087,CF_STRING},
#ifdef HAVE_CURLOPT_KEYPASSWD
{"CURLOPT_SSLKEYPASSWD",CURLOPT_SSLKEYPASSWD,CURLOPT_KEYPASSWD,CF_STRING},
#endif
{"CURLOPT_SSL_VERIFYHOST",CURLOPT_SSL_VERIFYHOST,81,CF_LONG},
{"CURLOPT_SSL_VERIFYPEER",CURLOPT_SSL_VERIFYPEER,64,CF_LONG},
{"CURLOPT_TIMEOUT",CURLOPT_TIMEOUT,13,CF_LONG},

View File

@ -56,9 +56,11 @@ set_curlflag(NCD4INFO* state, int flag)
{
int ret = NC_NOERR;
switch (flag) {
case CURLOPT_USERPWD:
if(state->curl->creds.userpwd != NULL) {
CHECK(state, CURLOPT_USERPWD, state->curl->creds.userpwd);
case CURLOPT_USERPWD: /* Do both user and pwd */
if(state->curl->creds.user != NULL
&& state->curl->creds.pwd != NULL) {
CHECK(state, CURLOPT_USERNAME, state->curl->creds.user);
CHECK(state, CURLOPT_PASSWORD, state->curl->creds.pwd);
CHECK(state, CURLOPT_HTTPAUTH, (OPTARG)CURLAUTH_ANY);
}
break;
@ -107,8 +109,10 @@ set_curlflag(NCD4INFO* state, int flag)
if(state->curl->proxy.host != NULL) {
CHECK(state, CURLOPT_PROXY, state->curl->proxy.host);
CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->curl->proxy.port);
if(state->curl->proxy.userpwd) {
CHECK(state, CURLOPT_PROXYUSERPWD, state->curl->proxy.userpwd);
if(state->curl->proxy.user != NULL
&& state->curl->proxy.pwd != NULL) {
CHECK(state, CURLOPT_PROXYUSERNAME, state->curl->proxy.user);
CHECK(state, CURLOPT_PROXYPASSWORD, state->curl->proxy.pwd);
#ifdef CURLOPT_PROXYAUTH
CHECK(state, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
#endif
@ -264,6 +268,7 @@ NCD4_curl_protocols(NCD4globalstate* state)
}
#if 0
/*
"Inverse" of set_curlflag;
Given a flag and value, it updates state.
@ -349,6 +354,7 @@ NCD4_set_curlstate(NCD4INFO* state, int flag, void* value)
done:
return THROW(ret);
}
#endif
void
NCD4_curl_printerror(NCD4INFO* state)

View File

@ -6,6 +6,14 @@
#ifndef D4CURLFUNCTIONS_H
#define D4CURLFUNCTIONS_H
/* Aliases to older names */
#ifndef HAVE_CURLOPT_KEYPASSWD
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
#endif
#ifndef HAVE_CURLINFO_RESPONSE_CODE
#define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
#endif
enum CURLFLAGTYPE {CF_UNKNOWN=0,CF_OTHER=1,CF_STRING=2,CF_LONG=3};
struct CURLFLAG {
const char* name;
@ -20,7 +28,6 @@ extern ncerror NCD4_set_flags_perfetch(NCD4INFO*);
extern ncerror NCD4_set_flags_perlink(NCD4INFO*);
extern ncerror NCD4_set_curlflag(NCD4INFO*,int);
extern ncerror NCD4_set_curlstate(NCD4INFO* state, int flag, void* value);
extern void NCD4_curl_debug(NCD4INFO* state);

View File

@ -327,8 +327,10 @@ freeCurl(NCD4curl* curl)
nullfree(curl->ssl.cainfo);
nullfree(curl->ssl.capath);
nullfree(curl->proxy.host);
nullfree(curl->proxy.userpwd);
nullfree(curl->creds.userpwd);
nullfree(curl->proxy.user);
nullfree(curl->proxy.pwd);
nullfree(curl->creds.user);
nullfree(curl->creds.pwd);
if(curl->curlflags.createdflags & COOKIECREATED)
d4removecookies(curl->curlflags.cookiejar);
nullfree(curl->curlflags.cookiejar);

View File

@ -24,7 +24,7 @@ NCD4_fetchhttpcode(CURL* curl)
#ifdef HAVE_CURLINFO_RESPONSE_CODE
cstat = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpcode);
#else
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CODE,&httpcode);
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CONNECTCODE,&httpcode);
#endif
if(cstat != CURLE_OK) {
httpcode = 0;
@ -321,7 +321,7 @@ curlerrtoncerr(CURLcode cstat)
switch (cstat) {
case CURLE_OK: return THROW(NC_NOERR);
case CURLE_URL_MALFORMAT:
return THROW(NC_EURL);
return THROW(NC_EURL);
case CURLE_COULDNT_RESOLVE_HOST:
case CURLE_COULDNT_CONNECT:
case CURLE_REMOTE_ACCESS_DENIED:
@ -338,5 +338,5 @@ curlerrtoncerr(CURLcode cstat)
case CURLE_SSL_CACERT_BADFILE:
default: break;
}
return THROW(NC_ECURL);
return THROW(NC_ECURL);
}

View File

@ -16,14 +16,14 @@
#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
/* Forward */
static char* extract_credentials(NCURI*);
static int rccompile(const char* path);
static struct NCD4triple* rclocate(char* key, char* hostport);
static void rcorder(NClist* rc);
static NClist* rcorder(NClist* rc);
static char* rcreadline(char**);
static int rcsearch(const char* prefix, const char* rcname, char** pathp);
static void rctrim(char* text);
static int rcsetinfocurlflag(NCD4INFO*, const char* flag, const char* value);
static int parsecredentials(const char* userpwd, char** userp, char** pwdp);
#ifdef D4DEBUG
static void storedump(char* msg, NClist* triples);
#endif
@ -80,30 +80,34 @@ rctrim(char* text)
}
}
/* Order the triples: put all those with urls first */
static void
/* Order the triples: those with urls must be first,
but otherwise relative order does not matter.
*/
static NClist*
rcorder(NClist* rc)
{
int i,j;
int len = nclistlength(rc);
if(rc == NULL || len == 0) return;
NClist* newrc = nclistnew();
if(rc == NULL || len == 0) return newrc;
/* Two passes: 1) pull triples with host */
for(i=0;i<len;i++) {
NCD4triple* ti = nclistget(rc,i);
NCD4triple* ti = nclistget(rc,i);
if(ti->host == NULL) continue;
nclistpush(newrc,ti);
}
/* pass 2 pull triples without host*/
for(i=0;i<len;i++) {
NCD4triple* ti = nclistget(rc,i);
if(ti->host != NULL) continue;
for(j=i;j<len;j++) {
NCD4triple* tj = nclistget(rc,j);
if(tj->host != NULL) {/*swap*/
NCD4triple* t = ti;
nclistset(rc,i,tj);
nclistset(rc,j,t);
}
}
nclistpush(newrc,ti);
}
#ifdef D4DEBUG
storedump("reorder:",rc);
storedump("reorder:",newrc);
#endif
}
return newrc;
}
/* Create a triple store from a file */
static int
@ -373,10 +377,15 @@ rcsetinfocurlflag(NCD4INFO* info, const char* flag, const char* value)
#endif
}
if(strcmp(flag,"HTTP.CREDENTIALS.USERPASSWORD")==0) {
nullfree(info->curl->creds.userpwd);
info->curl->creds.userpwd = strdup(value);
MEMCHECK(info->curl->creds.userpwd);
if(strcmp(flag,"HTTP.CREDENTIALS.USERNAME")==0) {
nullfree(info->curl->creds.user);
info->curl->creds.user = strdup(value);
MEMCHECK(info->curl->creds.user);
}
if(strcmp(flag,"HTTP.CREDENTIALS.PASSWORD")==0) {
nullfree(info->curl->creds.pwd);
info->curl->creds.pwd = strdup(value);
MEMCHECK(info->curl->creds.pwd);
}
done:
@ -390,9 +399,7 @@ int
NCD4_rcprocess(NCD4INFO* info)
{
int ret = NC_NOERR;
char userpwd[NC_MAX_PATH];
char hostport[NC_MAX_PATH];
char* url_userpwd = userpwd; /* WATCH OUT: points to previous variable */
char* url_hostport = hostport; /* WATCH OUT: points to previous variable */
NCURI* uri = info->uri;
@ -403,15 +410,12 @@ NCD4_rcprocess(NCD4INFO* info)
/* Note, we still must do this function even if
NCD4_globalstate->rc.ignore is set in order
to getinfo e.g. user:pwd from url
to getinfo e.g. host+port from url
*/
url_hostport = NULL;
if(uri != NULL) {
NCD4_userpwd(uri,url_userpwd,sizeof(userpwd));
NCD4_hostport(uri,url_hostport,sizeof(hostport));
} else {
url_hostport = NULL;
url_userpwd = NULL;
}
rcsetinfocurlflag(info,"HTTP.DEFLATE",
@ -450,29 +454,38 @@ NCD4_rcprocess(NCD4INFO* info)
NCD4_rclookup("HTTP.NETRC",url_hostport));
{ /* Handle various cases for user + password */
/* First, see if the user+pwd was in the original url */
char* userpwd = NULL;
char* user = NULL;
char* pwd = NULL;
if(url_userpwd != NULL)
userpwd = url_userpwd;
else {
if(uri->user != NULL && uri->password != NULL) {
user = uri->user;
pwd = uri->password;
} else {
user = NCD4_rclookup("HTTP.CREDENTIALS.USER",url_hostport);
pwd = NCD4_rclookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
userpwd = NCD4_rclookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
}
if(userpwd == NULL && user != NULL && pwd != NULL) {
char creds[NC_MAX_PATH];
strncpy(creds,user,sizeof(creds));
strncat(creds,":",sizeof(creds));
strncat(creds,pwd,sizeof(creds));
rcsetinfocurlflag(info,"HTTP.USERPASSWORD",creds);
} else if(userpwd != NULL)
rcsetinfocurlflag(info,"HTTP.USERPASSWORD",userpwd);
if(user != NULL && pwd != NULL) {
user = strdup(user); /* so we can consistently reclaim */
pwd = strdup(pwd);
} else {
/* Could not get user and pwd, so try USERPASSWORD */
const char* userpwd = NCD4_rclookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
if(userpwd != NULL) {
ret = parsecredentials(userpwd,&user,&pwd);
if(ret) return ret;
}
}
rcsetinfocurlflag(info,"HTTP.USERNAME",user);
rcsetinfocurlflag(info,"HTTP.PASSWORD",pwd);
nullfree(user);
nullfree(pwd);
}
return THROW(ret);
}
/**
* (Internal) Locate a triple by property key and host+port (may be null or "").
* If duplicate keys, first takes precedence.
*/
static struct NCD4triple*
rclocate(char* key, char* hostport)
{
@ -503,6 +516,10 @@ rclocate(char* key, char* hostport)
return (found?triple:NULL);
}
/**
* Locate a triple by property key and host+port (may be null|"")
* If duplicate keys, first takes precedence.
*/
char*
NCD4_rclookup(char* key, char* hostport)
{
@ -524,13 +541,16 @@ storedump(char* msg, NClist* triples)
for(i=0;i<nclistlength(triples);i++) {
NCD4triple* t = (NCD4triple*)nclistget(triples,i);
fprintf(stderr,"\t%s\t%s\t%s\n",
(t->host == NULL || strlen(t->host)==0?"--":t->host),t->key,t->value);
((t->host == NULL || strlen(t->host)==0)?"--":t->host),t->key,t->value);
}
fflush(stderr);
}
#endif
/**
* Locate rc file by searching in directory prefix.
* Prefix must end in '/'
*/
static
@ -592,7 +612,8 @@ NCD4_parseproxy(NCD4INFO* info, const char* surl)
return THROW(NC_NOERR); /* nothing there*/
if(ncuriparse(surl,&uri) != NCU_OK)
return THROW(NC_EURL);
info->curl->proxy.userpwd = extract_credentials(uri);
info->curl->proxy.user = uri->user;
info->curl->proxy.pwd = uri->password;
info->curl->proxy.host = strdup(uri->host);
if(uri->port != NULL)
info->curl->proxy.port = atoi(uri->port);
@ -601,15 +622,32 @@ NCD4_parseproxy(NCD4INFO* info, const char* surl)
return THROW(ret);
}
/* Caller must free result_url */
static char*
extract_credentials(NCURI* url)
/*
Given form user:pwd, parse into user and pwd
and do %xx unescaping
*/
static int
parsecredentials(const char* userpwd, char** userp, char** pwdp)
{
char tmp[NC_MAX_PATH];
if(url->user == NULL || url->password == NULL)
return NULL;
NCD4_userpwd(url,tmp,sizeof(tmp));
return strdup(tmp);
char* user = NULL;
char* pwd = NULL;
if(userpwd == NULL)
return NC_EINVAL;
user = strdup(userpwd);
if(user == NULL)
return NC_ENOMEM;
pwd = strchr(user,':');
if(pwd == NULL)
return NC_EINVAL;
*pwd = '\0';
pwd++;
if(userp)
*userp = ncuridecode(user);
if(pwdp)
*pwdp = ncuridecode(pwd);
free(user);
return NC_NOERR;
}
int

View File

@ -408,6 +408,7 @@ NCD4_hostport(NCURI* uri, char* space, size_t len)
}
}
#if 0
void
NCD4_userpwd(NCURI* uri, char* space, size_t len)
{
@ -420,6 +421,7 @@ NCD4_userpwd(NCURI* uri, char* space, size_t len)
}
}
}
#endif
#ifdef BLOB
void

View File

@ -129,7 +129,6 @@ extern int NCD4_getToplevelVars(NCD4meta* meta, NCD4node* group, NClist* topleve
/* From d4util.c */
extern d4size_t NCD4_dimproduct(NCD4node* node);
extern void NCD4_hostport(NCURI* uri, char* space, size_t len);
extern void NCD4_userpwd(NCURI* uri, char* space, size_t len);
extern size_t NCD4_typesize(nc_type tid);
extern int NCD4_isLittleEndian(void);/* Return 1 if this machine is little endian */
extern int NCD4_errorNC(int code, const int line, const char* file);

View File

@ -325,10 +325,12 @@ struct NCD4curl {
struct proxy {
char *host; /*CURLOPT_PROXY*/
int port; /*CURLOPT_PROXYPORT*/
char* userpwd; /*CURLOPT_PROXYUSERPWD*/
char* user; /*CURLOPT_PROXYUSERNAME*/
char* pwd; /*CURLOPT_PROXYPASSWORD*/
} proxy;
struct credentials {
char *userpwd; /*CURLOPT_USERPWD*/
char *user; /*CURLOPT_USERNAME*/
char *pwd; /*CURLOPT_PASSWORD*/
} creds;
};

View File

@ -1,7 +1,7 @@
SET(libdispatch_SOURCES dparallel.c dcopy.c dfile.c ddim.c datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c dvarinq.c ddispatch.c nclog.c dstring.c dutf8.c dinternal.c doffsets.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c utf8proc.h utf8proc.c dwinpath.c)
IF(USE_NETCDF4)
SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c)
SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c dfilter.c)
ENDIF(USE_NETCDF4)
IF(BUILD_V2)

View File

@ -17,9 +17,8 @@ libdispatch_la_CPPFLAGS = ${AM_CPPFLAGS}
# The source files.
libdispatch_la_SOURCES = dparallel.c dcopy.c dfile.c ddim.c datt.c \
dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c \
dvarinq.c dinternal.c ddispatch.c dutf8.c \
nclog.c dstring.c \
ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c \
dvarinq.c dinternal.c ddispatch.c dutf8.c dstring.c \
nclog.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c \
nc.c nclistmgr.c drc.c doffsets.c dwinpath.c
# Add the utf8 codebase
@ -28,7 +27,7 @@ libdispatch_la_SOURCES += utf8proc.c utf8proc.h
# Add functions only found in netCDF-4.
if USE_NETCDF4
libdispatch_la_SOURCES += dgroup.c dvlen.c dcompound.c dtype.c denum.c \
dopaque.c ncaux.c
dopaque.c dfilter.c ncaux.c
endif # USE_NETCDF4
# Turn on pre-processor flag when building a DLL for windows.

View File

@ -258,7 +258,7 @@ const char *nc_strerror(int ncerr1)
case NC_EDISKLESS:
return "NetCDF: Error in using diskless access";
case NC_EFILTER:
return "NetCDF: Error in filter id or parameters";
return "NetCDF: Filter error: bad id or parameters or filter library non-existent";
default:
#ifdef USE_PNETCDF
/* The behavior of ncmpi_strerror here is to return

View File

@ -104,10 +104,12 @@ NC_interpret_magic_number(char* magic, int* model, int* version, int use_paralle
} else if(magic[3] == '\002') {
*version = 2; /* netcdf classic version 2 */
*model = NC_FORMATX_NC3;
} else if(magic[3] == '\005') {
*version = 5; /* cdf5 (including pnetcdf) file */
#ifdef USE_CDF5
} else if(magic[3] == '\005') {
*version = 5; /* cdf5 (including pnetcdf) file */
*model = NC_FORMATX_NC3;
} else
#endif
} else
{status = NC_ENOTNC; goto done;}
} else
{status = NC_ENOTNC; goto done;}
@ -1608,11 +1610,10 @@ Create a file, calling the appropriate dispatch create call.
For create, we have the following pieces of information to use to
determine the dispatch table:
- table specified by override
- path
- cmode
\param path The file name of the new netCDF dataset.
\param path0 The file name of the new netCDF dataset.
\param cmode The creation mode flag, the same as in nc_create().
@ -1720,11 +1721,13 @@ fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
model = NC_FORMATX_NC4;
break;
#endif
#ifdef USE_CDF5
case NC_FORMAT_CDF5:
xcmode |= NC_64BIT_DATA;
model = NC_FORMATX_NC3;
break;
case NC_FORMAT_64BIT_OFFSET:
#endif
case NC_FORMAT_64BIT_OFFSET:
xcmode |= NC_64BIT_OFFSET;
model = NC_FORMATX_NC3;
break;

View File

@ -1,7 +1,7 @@
/*********************************************************************
* Copyright 2016, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
/*
Copyright (c) 1998-2017 University Corporation for Atmospheric Research/Unidata
See LICENSE.txt for license information.
*/
#include "config.h"
#ifdef HAVE_UNISTD_H

View File

@ -6,7 +6,13 @@ Research/Unidata. See COPYRIGHT file for more info.
*/
#include "ncdispatch.h"
#include "netcdf_filter.h"
#ifdef USE_NETCDF4
#include <hdf5.h>
#endif
#ifndef H5Z_FILTER_SZIP
#define H5Z_FILTER_SZIP 4
#endif
/** \name Learning about Variables
@ -245,7 +251,6 @@ nc_inq_varnatts(int ncid, int varid, int *nattsp)
nattsp);
}
#ifdef USE_NETCDF4
/** \ingroup variables
Learn the storage and deflate settings for a variable.
@ -300,97 +305,6 @@ nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep,
);
}
/** \ingroup variables
Learn the szip settings of a variable.
This function returns the szip settings for a variable.
With the introduction of general filter support,
szip inquiry is converted to use the filter interface.
This is a wrapper for nc_inq_var_filter().
\param ncid NetCDF or group ID, from a previous call to nc_open(),
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID
\param options_maskp The szip options mask will be copied to this
pointer. \ref ignored_if_null.
\param pixels_per_blockp The szip pixels per block will be copied
here. \ref ignored_if_null.
\returns ::NC_NOERR No error.
\returns ::NC_EBADID Bad ncid.
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
\returns ::NC_ENOTVAR Invalid variable ID.
\returns ::NC_EFILTER Variable is not szip encoded
*/
int
nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
{
NC* ncp;
unsigned int id;
size_t nparams;
unsigned int params[2];
int stat = NC_check_id(ncid,&ncp);
if(stat != NC_NOERR) return stat;
TRACE(nc_inq_var_szip);
/* Verify id and nparams */
stat = ncp->dispatch->inq_var_all(
ncid, varid,
NULL, /*name*/
NULL, /*xtypep*/
NULL, /*ndimsp*/
NULL, /*dimidsp*/
NULL, /*nattsp*/
NULL, /*shufflep*/
NULL, /*deflatep*/
NULL, /*deflatelevelp*/
NULL, /*fletcher32p*/
NULL, /*contiguousp*/
NULL, /*chunksizep*/
NULL, /*nofillp*/
NULL, /*fillvaluep*/
NULL, /*endianp*/
&id,
&nparams,
NULL
);
if(stat != NC_NOERR) return stat;
if(id != H5Z_FILTER_SZIP || nparams != 2)
return NC_EFILTER; /* not szip or bad # params */
/* Get params */
stat = ncp->dispatch->inq_var_all(
ncid, varid,
NULL, /*name*/
NULL, /*xtypep*/
NULL, /*ndimsp*/
NULL, /*dimidsp*/
NULL, /*nattsp*/
NULL, /*shufflep*/
NULL, /*deflatep*/
NULL, /*deflatelevelp*/
NULL, /*fletcher32p*/
NULL, /*contiguousp*/
NULL, /*chunksizep*/
NULL, /*nofillp*/
NULL, /*fillvaluep*/
NULL, /*endianp*/
&id,
&nparams,
params
);
if(stat != NC_NOERR) return stat;
/* Param[0] should be options_mask, Param[1] should be pixels_per_block */
if(options_maskp) *options_maskp = (int)params[0];
if(pixels_per_blockp) *pixels_per_blockp = (int)params[1];
return NC_NOERR;
}
/** \ingroup variables
Learn the checksum settings for a variable.
@ -633,12 +547,16 @@ This function will return one of the following values.
int
nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp)
{
#ifndef USE_NETCDF4
return NC_ENOTNC4;
#else
NC* ncp;
int stat = NC_check_id(ncid,&ncp);
if(stat != NC_NOERR) return stat;
TRACE(nc_inq_unlimdims);
TRACE(nc_inq_unlimdims);
return ncp->dispatch->inq_unlimdims(ncid, nunlimdimsp,
unlimdimidsp);
#endif
}
/** \ingroup variables
@ -691,7 +609,97 @@ nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparamsp, unsi
idp, nparamsp, params);
}
#endif /* USE_NETCDF4 */
/** \ingroup variables
Learn the szip settings of a variable.
Similar to nc_inq_var_deflate.
This function returns the szip settings for a variable.
With the introduction of general filter support,
szip inquiry is converted to use the filter interface.
This is a wrapper for nc_inq_var_filter().
\param ncid NetCDF or group ID, from a previous call to nc_open(),
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID
\param options_maskp The szip options mask will be copied to this
pointer. \ref ignored_if_null.
\param pixels_per_blockp The szip pixels per block will be copied
here. \ref ignored_if_null.
\returns ::NC_NOERR No error.
\returns ::NC_EBADID Bad ncid.
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
\returns ::NC_ENOTVAR Invalid variable ID.
\returns ::NC_EFILTER Variable is not szip encoded
*/
int
nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
{
NC* ncp;
unsigned int id;
size_t nparams;
unsigned int params[2];
int stat = NC_check_id(ncid,&ncp);
if(stat != NC_NOERR) return stat;
TRACE(nc_inq_var_szip);
/* Verify id and nparams */
stat = ncp->dispatch->inq_var_all(
ncid, varid,
NULL, /*name*/
NULL, /*xtypep*/
NULL, /*ndimsp*/
NULL, /*dimidsp*/
NULL, /*nattsp*/
NULL, /*shufflep*/
NULL, /*deflatep*/
NULL, /*deflatelevelp*/
NULL, /*fletcher32p*/
NULL, /*contiguousp*/
NULL, /*chunksizep*/
NULL, /*nofillp*/
NULL, /*fillvaluep*/
NULL, /*endianp*/
&id,
&nparams,
NULL
);
if(stat != NC_NOERR) return stat;
if(id != H5Z_FILTER_SZIP || nparams != 2)
return NC_EFILTER; /* not szip or bad # params */
/* Get params */
stat = ncp->dispatch->inq_var_all(
ncid, varid,
NULL, /*name*/
NULL, /*xtypep*/
NULL, /*ndimsp*/
NULL, /*dimidsp*/
NULL, /*nattsp*/
NULL, /*shufflep*/
NULL, /*deflatep*/
NULL, /*deflatelevelp*/
NULL, /*fletcher32p*/
NULL, /*contiguousp*/
NULL, /*chunksizep*/
NULL, /*nofillp*/
NULL, /*fillvaluep*/
NULL, /*endianp*/
&id,
&nparams,
params
);
if(stat != NC_NOERR) return stat;
/* Param[0] should be options_mask, Param[1] should be pixels_per_block */
if(options_maskp) *options_maskp = (int)params[0];
if(pixels_per_blockp) *pixels_per_blockp = (int)params[1];
return NC_NOERR;
}
/*!
@ -713,8 +721,6 @@ Used in libdap2 and libdap4.
@param[out] no_fill Pointer to memory to store whether or not there is a fill value associated with the variable.
@param[out] fill_valuep Pointer to memory to store the fill value (if one exists) for the variable.
@param[out] endiannessp Pointer to memory to store endianness value. One of ::NC_ENDIAN_BIG ::NC_ENDIAN_LITTLE ::NC_ENDIAN_NATIVE
@param[out] options_maskp Pointer to memory to store mask options information.
@param[out] pixels_per_blockp Pointer to memory to store pixels-per-block information for chunked data.
@param[out] idp Pointer to memory to store filter id.
@param[out] nparamsp Pointer to memory to store filter parameter count.
@param[out] params Pointer to vector of unsigned integers into which

View File

@ -63,6 +63,10 @@ static char* pathallow =
static char* queryallow =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$&'()*+,-./:;=?@_~";
/* user+pwd allow = path allow - "@:" */
static char* userpwdallow =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$&'()*+,-.;=_~?#/";
#ifndef HAVE_STRNCMP
#define strndup ncstrndup
/* Not all systems have strndup, so provide one*/
@ -345,8 +349,13 @@ ncuriparse(const char* uri0, NCURI** durip)
/* save original uri */
duri->uri = strdup(uri0);
duri->protocol = nulldup(tmp.protocol);
duri->user = nulldup(tmp.user);
duri->password = nulldup(tmp.password);
/* before saving, we need to decode the user+pwd */
duri->user = NULL;
duri->password = NULL;
if(tmp.user != NULL)
duri->user = ncuridecode(tmp.user);
if(tmp.password != NULL)
duri->password = ncuridecode(tmp.password);
duri->host = nulldup(tmp.host);
duri->port = nulldup(tmp.port);
if(tmp.path != NULL) {
@ -530,9 +539,14 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
ncbytescat(buf,"://"); /* this will produce file:///... */
if((flags & NCURIPWD) && duri->user != NULL && duri->password != NULL) {
ncbytescat(buf,duri->user);
/* The user and password must be encoded */
char* encoded = ncuriencodeonly(duri->user,userpwdallow);
ncbytescat(buf,encoded);
nullfree(encoded);
ncbytescat(buf,":");
ncbytescat(buf,duri->password);
encoded = ncuriencodeonly(duri->password,userpwdallow);
ncbytescat(buf,encoded);
nullfree(encoded);
ncbytescat(buf,"@");
}
if(duri->host != NULL) ncbytescat(buf,duri->host);
@ -544,7 +558,7 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
if(duri->path == NULL)
ncbytescat(buf,"/");
else if(encode) {
char* encoded = ncuriencode(duri->path,pathallow);
char* encoded = ncuriencodeonly(duri->path,pathallow);
ncbytescat(buf,encoded);
nullfree(encoded);
} else
@ -566,7 +580,7 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
if(p[1] != NULL && strlen(p[1]) > 0) {
ncbytescat(buf,"=");
if(encode) {
char* encoded = ncuriencode(p[1],queryallow);
char* encoded = ncuriencodeonly(p[1],queryallow);
ncbytescat(buf,encoded);
nullfree(encoded);
} else
@ -583,7 +597,7 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
if(p[1] != NULL && strlen(p[1]) > 0) {
ncbytescat(buf,"=");
if(encode) {
char* encoded = ncuriencode(p[1],queryallow);
char* encoded = ncuriencodeonly(p[1],queryallow);
ncbytescat(buf,encoded);
nullfree(encoded);
} else
@ -720,8 +734,8 @@ static char* hexchars = "0123456789abcdefABCDEF";
static void
toHex(unsigned int b, char hex[2])
{
hex[0] = hexchars[(b >> 4) & 0xff];
hex[1] = hexchars[(b) & 0xff];
hex[0] = hexchars[(b >> 4) & 0xf];
hex[1] = hexchars[(b) & 0xf];
}
@ -734,6 +748,14 @@ fromHex(int c)
return 0;
}
/*
Support encode of user and password fields
*/
char*
ncuriencodeuserpwd(char* s)
{
return ncuriencodeonly(s,userpwdallow);
}
/* Return a string representing encoding of input; caller must free;
watch out: will encode whole string, so watch what you give it.
@ -741,7 +763,7 @@ fromHex(int c)
*/
char*
ncuriencode(char* s, char* allowable)
ncuriencodeonly(char* s, char* allowable)
{
size_t slen;
char* encoded;
@ -760,12 +782,10 @@ ncuriencode(char* s, char* allowable)
} else {
/* search allowable */
int c2;
char* a = allowable;
while((c2=*a++)) {
if(c == c2) break;
}
if(c2) {*outptr++ = (char)c;}
else {
char* p = strchr(allowable,c);
if(p != NULL) {
*outptr++ = (char)c;
} else {
char hex[2];
toHex(c,hex);
*outptr++ = '%';
@ -781,15 +801,6 @@ ncuriencode(char* s, char* allowable)
/* Return a string representing decoding of input; caller must free;*/
char*
ncuridecode(char* s)
{
return ncuridecodeonly(s,NULL);
}
/* Return a string representing decoding of input only for specified
characters; caller must free
*/
char*
ncuridecodeonly(char* s, char* only)
{
size_t slen;
char* decoded;
@ -805,7 +816,45 @@ ncuridecodeonly(char* s, char* only)
outptr = decoded;
inptr = s;
while((c = (unsigned int)*inptr++)) {
if(c == '+' && only != NULL && strchr(only,'+') != NULL)
if(c == '%') {
/* try to pull two hex more characters */
if(inptr[0] != EOFCHAR && inptr[1] != EOFCHAR
&& strchr(hexchars,inptr[0]) != NULL
&& strchr(hexchars,inptr[1]) != NULL) {
/* test conversion */
int xc = (fromHex(inptr[0]) << 4) | (fromHex(inptr[1]));
inptr += 2; /* decode it */
c = (unsigned int)xc;
}
}
*outptr++ = (char)c;
}
*outptr = EOFCHAR;
return decoded;
}
/*
Partially decode a string. Only characters in 'decodeset'
are decoded. Return decoded string; caller must free.
*/
char*
ncuridecodepartial(char* s, const char* decodeset)
{
size_t slen;
char* decoded;
char* outptr;
char* inptr;
unsigned int c;
if (s == NULL || decodeset == NULL) return NULL;
slen = strlen(s);
decoded = (char*)malloc(slen+1); /* Should be max we need */
outptr = decoded;
inptr = s;
while((c = (unsigned int)*inptr++)) {
if(c == '+' && strchr(decodeset,'+') != NULL)
*outptr++ = ' ';
else if(c == '%') {
/* try to pull two hex more characters */
@ -814,13 +863,14 @@ ncuridecodeonly(char* s, char* only)
&& strchr(hexchars,inptr[1]) != NULL) {
/* test conversion */
int xc = (fromHex(inptr[0]) << 4) | (fromHex(inptr[1]));
if(only == NULL || strchr(only,xc) != NULL) {
if(strchr(decodeset,xc) != NULL) {
inptr += 2; /* decode it */
c = (unsigned int)xc;
}
}
}
}
*outptr++ = (char)c;
*outptr++ = (char)c; /* pass either the % or decoded char */
} else /* Not a % char */
*outptr++ = (char)c;
}
*outptr = EOFCHAR;
return decoded;

View File

@ -34,3 +34,4 @@ DAP4 Support: @HAS_DAP4@
Diskless Support: @HAS_DISKLESS@
MMap Support: @HAS_MMAP@
JNA Support: @HAS_JNA@
CDF5 Support: @HAS_CDF5@

View File

@ -95,9 +95,12 @@ err:
int
nc3_cktype(int mode, nc_type type)
{
#ifdef USE_CDF5
if (mode & NC_CDF5) { /* CDF-5 format */
if (type >= NC_BYTE && type < NC_STRING) return NC_NOERR;
} else if (mode & NC_64BIT_OFFSET) { /* CDF-2 format */
} else
#endif
if (mode & NC_64BIT_OFFSET) { /* CDF-2 format */
if (type >= NC_BYTE && type <= NC_DOUBLE) return NC_NOERR;
} else if ((mode & NC_64BIT_OFFSET) == 0) { /* CDF-1 format */
if (type >= NC_BYTE && type <= NC_DOUBLE) return NC_NOERR;
@ -1086,8 +1089,11 @@ nc_set_default_format(int format, int *old_formatp)
format != NC_FORMAT_NETCDF4 && format != NC_FORMAT_NETCDF4_CLASSIC)
return NC_EINVAL;
#else
if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET &&
format != NC_FORMAT_CDF5)
if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET
#ifdef USE_CDF5
&& format != NC_FORMAT_CDF5
#endif
)
return NC_EINVAL;
#endif
default_create_format = format;
@ -1582,9 +1588,12 @@ NC3_inq_format(int ncid, int *formatp)
nc3 = NC3_DATA(nc);
/* only need to check for netCDF-3 variants, since this is never called for netCDF-4 files */
#ifdef USE_CDF5
if (fIsSet(nc3->flags, NC_64BIT_DATA))
*formatp = NC_FORMAT_CDF5;
else if (fIsSet(nc3->flags, NC_64BIT_OFFSET))
else
#endif
if (fIsSet(nc3->flags, NC_64BIT_OFFSET))
*formatp = NC_FORMAT_64BIT_OFFSET;
else
*formatp = NC_FORMAT_CLASSIC;

View File

@ -13,68 +13,78 @@ cc="@CMAKE_C_COMPILER@"
cflags="-I@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@"
libs="-L@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ @NC_LIBS@"
if [ -z "@USE_DAP@" -o -z "@ENABLE_DAP2@" ] ; then
has_dap2=ON
fi
if [ -z $has_dap2 ]; then
has_dap2="@ENABLE_DAP2@"
if [ -z $has_dap2 -o "$has_dap2" = "OFF" ]; then
has_dap2="no"
else
has_dap2="yes"
fi
has_dap4="@ENABLE_DAP4"
has_dap4="@ENABLE_DAP4@"
if [ -z $has_dap4 -o "$has_dap4" = "OFF" ]; then
has_dap4="no"
else
has_dap4="yes"
fi
has_nc2="@BUILD_V2@"
if [ -z $has_nc2 -o "$has_nc2" = "OFF" ]; then
if [ -z "$has_nc2" -o "$has_nc2" = "OFF" ]; then
has_nc2="no"
else
has_nc2="yes"
fi
has_nc4="@USE_NETCDF4@"
if [ -z $has_nc4 ]; then
if [ -z "$has_nc4" -o "$has_nc4" = "OFF" ]; then
has_nc4="no"
else
has_nc4="yes"
fi
has_logging="@ENABLE_LOGGING@"
if [ -z $has_logging ]; then
if [ -z "$has_logging" -o "$has_logging" = "OFF" ]; then
has_logging="no"
else
has_logging="yes"
fi
has_hdf4="@USE_HDF4@"
if [ -z $has_hdf4 ]; then
if [ -z "$has_hdf4" -o "$has_hdf4" = "OFF" ]; then
has_hdf4="no"
else
has_hdf4="yes"
fi
has_pnetcdf="@USE_PNETCDF@"
if [ -z $has_pnetcdf ]; then
if [ -z "$has_pnetcdf" -o "$has_pnetcdf" = "OFF" ]; then
has_pnetcdf="no"
else
has_pnetcdf="yes"
fi
has_hdf5="@USE_HDF5@"
if [ -z $has_hdf5 -o "$has_hdf5" = "OFF" ]; then
if [ -z "$has_hdf5" -o "$has_hdf5" = "OFF" ]; then
has_hdf5="no"
else
has_hdf5="yes"
fi
has_szlib="@USE_SZLIB@"
if [ -z $has_szlib ]; then
if [ -z "$has_szlib" -o "$has_szlib" = "OFF" ]; then
has_szlib="no"
else
has_szlib="yes"
fi
has_cdf5="@ENABLE_CDF5@"
if [ -z "has_cdf5" -o "$has_cdf5" = "OFF" -o "$has_cdf5" = "FALSE" ]; then
has_cdf5="no"
else
has_cdf5="yes"
fi
version="@PACKAGE@ @VERSION@"
@ -128,7 +138,7 @@ Available values for OPTION include:
--has-fortran whether Fortran API is installed
--has-dap2 whether OPeNDAP (DAP2) is enabled in this build
--has-dap4 whether DAP4 is enabled in this build
--has-dap same as --has-dp (Deprecated)
--has-dap same as --has-dap2 (Deprecated)
--has-nc2 whether NetCDF-2 API is enabled
--has-nc4 whether NetCDF-4/HDF-5 is enabled in this build
--has-hdf5 whether HDF5 is used in build (always the same as --has-nc4)
@ -136,6 +146,7 @@ Available values for OPTION include:
--has-logging whether logging is enabled with --enable-logging.
--has-pnetcdf whether parallel-netcdf (a.k.a. pnetcdf) was used in build
--has-szlib whether szlib is included in build
--has-cdf5 whether cdf5 support is included in build
--libs library linking information for netcdf
--prefix Install prefix
--includedir Include directory
@ -202,7 +213,7 @@ if [ -f "$nfconf" ]; then
echo " --has-f03 -> $has_f03"
echo
fi
echo " --has-dap -> $has_dap"
echo " --has-dap -> $has_dap2"
echo " --has-dap2 -> $has_dap2"
echo " --has-dap4 -> $has_dap4"
echo " --has-nc2 -> $has_nc2"
@ -212,6 +223,7 @@ fi
echo " --has-logging-> $has_logging"
echo " --has-pnetcdf-> $has_pnetcdf"
echo " --has-szlib -> $has_szlib"
echo " --has-cdf5 -> $has_cdf5"
echo
echo " --prefix -> $prefix"
echo " --includedir-> $includedir"
@ -252,7 +264,7 @@ while test $# -gt 0; do
;;
--has-dap)
echo $has_dap2 $has_dap4
echo $has_dap2
;;
--has-dap2)
@ -291,6 +303,10 @@ while test $# -gt 0; do
echo $has_szlib
;;
--has-cdf5)
echo $has_cdf5
;;
--libs)
echo $libs
;;

View File

@ -21,8 +21,12 @@ has_hdf4="@HAS_HDF4@"
has_pnetcdf="@HAS_PNETCDF@"
has_hdf5="@HAS_HDF5@"
has_logging="@HAS_LOGGING@"
has_cdf5="@HAS_CDF5@"
has_szlib="@HAS_SZLIB@"
version="@PACKAGE_NAME@ @PACKAGE_VERSION@"
has_fortran="no"
has_f90="no"
has_f03="no"
@ -79,8 +83,9 @@ Available values for OPTION include:
--has-logging whether logging is enabled with --enable-logging.
--has-pnetcdf whether parallel-netcdf (a.k.a. pnetcdf) was used in build
--has-szlib whether szlib is included in build
--has-cdf5 whether cdf5 support is included in build
--libs library linking information for netcdf
--prefix Install prefix
--prefix Install prefixx
--includedir Include directory
--libdir Library directory
--version Library version
@ -154,6 +159,7 @@ fi
echo " --has-logging-> $has_logging"
echo " --has-pnetcdf-> $has_pnetcdf"
echo " --has-szlib -> $has_szlib"
echo " --has-cdf5 -> $has_cdf5"
echo
echo " --prefix -> $prefix"
echo " --includedir-> $includedir"
@ -229,6 +235,10 @@ while test $# -gt 0; do
echo $has_szlib
;;
--has-cdf5)
echo $has_cdf5
;;
--libs)
echo $libs
;;

View File

@ -9,6 +9,8 @@ int numVars; /* number of variables */
int numTypes; /* number of netCDF data types to test */
#include "tests.h"
#include "config.h"
/*
* Test driver for netCDF-3 interface. This program performs tests against
@ -130,14 +132,19 @@ main(int argc, char *argv[])
fprintf(stderr, "\n\nSwitching to 64-bit offset format.\n");
strcpy(testfile, "nc_test_64bit.nc");
break;
case NC_FORMAT_CDF5:
nc_set_default_format(NC_FORMAT_CDF5, NULL);
#ifdef USE_CDF5
nc_set_default_format(NC_FORMAT_CDF5, NULL);
fprintf(stderr, "\n\nSwitching to 64-bit data format.\n");
strcpy(testfile, "nc_test_cdf5.nc");
numGatts = NGATTS;
numVars = NVARS;
numTypes = NTYPES;
break;
#else
continue;
#endif
case NC_FORMAT_NETCDF4_CLASSIC:
case NC_FORMAT_NETCDF4: /* actually it's _CLASSIC. */
#ifdef USE_NETCDF4

View File

@ -33,6 +33,7 @@ dnl
#endif
#include "tests.h"
#include "config.h"
#include "math.h"
define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl
@ -2405,8 +2406,11 @@ APIFunc(get_file_version)(char *path, int *version)
if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) {
if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC ||
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET ||
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5)
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET
#ifdef USE_CDF5
|| magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5
#endif
)
*version = magic[MAGIC_NUM_LEN-1];
else
return NC_ENOTNC;
@ -2449,8 +2453,8 @@ TestFunc(set_default_format)(void)
ELSE_NOK
/* Cycle through available formats. */
for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++)
{
for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++) {
if (i == NC_FORMAT_NETCDF4 || i == NC_FORMAT_NETCDF4_CLASSIC)
continue; /* test classic formats only */
if ((err = APIFunc(set_default_format)(i, NULL)))

View File

@ -54,8 +54,11 @@ static int file_create(const char *filename, int cmode, int *ncid)
#ifdef USE_PNETCDF
if (default_format == NC_FORMAT_CLASSIC ||
default_format == NC_FORMAT_64BIT_OFFSET ||
default_format == NC_FORMAT_64BIT_DATA)
default_format == NC_FORMAT_64BIT_OFFSET
#ifdef USE_CDF5
|| default_format == NC_FORMAT_64BIT_DATA
#endif
)
err = nc_create_par(filename, cmode|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, ncid);
else
#endif
@ -522,11 +525,16 @@ main(int argc, char **argv)
printf("Switching to 64-bit offset format.\n");
strcpy(testfile, "tst_small_64bit.nc");
break;
#ifdef USE_CDF5
case NC_FORMAT_CDF5:
nc_set_default_format(NC_FORMAT_CDF5, NULL);
printf("Switching to 64-bit data format.\n");
strcpy(testfile, "tst_small_cdf5.nc");
break;
#else
case NC_FORMAT_CDF5:
continue;
#endif
#ifdef USE_NETCDF4
case NC_FORMAT_NETCDF4_CLASSIC:
nc_set_default_format(NC_FORMAT_NETCDF4_CLASSIC, NULL);

View File

@ -10,7 +10,7 @@ SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars
tst_vars2 tst_files5 tst_files6 tst_sync tst_h_strbug tst_h_refs
tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite
tst_put_vars_two_unlim_dim tst_hdf5_file_compat tst_fill_attr_vanish
tst_rehash)
tst_rehash tst_filterparser)
# Note, renamegroup needs to be compiled before run_grp_rename

View File

@ -1,5 +1,5 @@
# Test c output
T=tst_szip
T=tst_filterparser
#CMD=valgrind --leak-check=full
CMD=gdb --args

View File

@ -22,7 +22,7 @@ tst_xplatform tst_xplatform2 tst_h_atts2 tst_endian_fill tst_atts \
t_type cdm_sea_soundings tst_camrun tst_vl tst_atts1 tst_atts2 \
tst_vars2 tst_files5 tst_files6 tst_sync \
tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite \
tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash
tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash tst_filterparser
# Temporary I hope
if !ISCYGWIN
@ -167,7 +167,6 @@ MYD29.A2009152.0000.005.2009153124331.hdf \
MYD29.A2002185.0000.005.2007160150627.hdf \
MOD29.A2000055.0005.005.2006267200024.hdf
endif # HDF4_FILE_TESTS
SUBDIRS=filter_test

View File

@ -0,0 +1,38 @@
# Test c output
T=test_filter
#CMD=valgrind --leak-check=full
CMD=gdb --args
EXECDIR=../..
SRCDIR=../..
#PAR=1
SZIP=1
CFLAGS = -Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I${SRCDIR} -I${SRCDIR}/include
LDFLAGS = ${EXECDIR}/liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lm
ifdef PAR
CC=mpicc
LDFLAGS += -lmpich
else
CC=gcc
endif
ifdef SZIP
LDFLAGS += -lsz -laec
endif
LLP=/usr/local/lib:${LD_LIBRARY_PATH}
all:: cmp
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
${CMD} ./t
cmp::
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}
cpp::
${CC} -E ${CFLAGS} ${T}.c > ${T}.txt

View File

@ -54,7 +54,8 @@ HDF5LIBDIR = /usr/local/lib
# Ditto for zlib
ZLIBDIR = ${HDF5LIBDIR}
makebzip2::
BUILT_SOURCES = ${LIBNAME}
${LIBNAME}:
SDIR=${srcdir} ;\
for f in ${PLUGINSRC} ${BZIP2SRC} ; do \
DLLSRC="$${DLLSRC} $${SDIR}/$$f" ; \

View File

@ -1,7 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <netcdf.h>
#include <netcdf_filter.h>
static size_t var_chunksizes[4] = {4, 4, 4, 4} ;

View File

@ -10,7 +10,6 @@
#include <stdlib.h>
#include "netcdf.h"
#include "netcdf_filter.h"
//#define BASELINE 1
@ -102,6 +101,8 @@ check(int err,int line)
{
if(err != NC_NOERR) {
fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
fflush(stderr);
exit(1);
}
return NC_NOERR;
}

View File

@ -14,7 +14,6 @@
#include "nc_tests.h"
#include "err_macros.h"
#include "netcdf.h"
#include "netcdf_filter.h"
#undef PLAIN
#define USECLOSE

292
nc_test4/tst_filterparser.c Normal file
View File

@ -0,0 +1,292 @@
/*
Copyright 2008, UCAR/Unidata
See COPYRIGHT file for copying and redistribution conditions.
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "netcdf.h"
#include "ncfilter.h"
#undef USE_INTERNAL
#define PARAMS_ID 32768
static const unsigned int baseline[] = {
-17, /*0 signed int*/
23, /*1 unsigned int*/
-25, /*2 signed int*/
27, /*3 unsigned int*/
77, /*4 signed int*/
93, /*5 unsigned int*/
1145389056U, /*6 float*/
697067329, 2723935171, /*7-8 double*/
128, 16777216, /*9-10 signed long long*/
4294967295, 4294967295, /*11-12 unsigned long long*/
/* Edge cases */
2147483647, /*13 max signed int*/
-2147483648, /*14 min signed int*/
4294967295 /*15 max unsigned int with no trailing U*/
};
static const char* spec =
"32768, -17b, 23ub, -25S, 27US, 77, 93U, 789f, 12345678.12345678d, -9223372036854775807L, 18446744073709551615UL, 2147483647, -2147483648, 4294967295";
/* Test support for the conversions */
/* Not sure if this kind of casting via union is legal C99 */
static union {
unsigned int ui;
float f;
} uf;
static union {
unsigned int ui[2];
double d;
} ud;
static union {
unsigned int ui[2];
unsigned long long ull;
long long ll;
} ul;
static int nerrs = 0;
#ifdef USE_INTERNAL
static int parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
#endif
static void byteswap8(unsigned char* mem);
static void
report(const char* which)
{
fprintf(stderr,"mismatch: %s\n",which);
fflush(stderr);
nerrs++;
}
static void
mismatch(size_t i, unsigned int baseline, unsigned int params)
{
fprintf(stderr,"mismatch: [%d] baseline=%ud spec=%ud\n",i,baseline,params);
fflush(stderr);
nerrs++;
}
/**************************************************/
int
main(int argc, char **argv)
{
int stat = 0;
unsigned int id = 0;
size_t i,nparams = 0;
unsigned int* params = NULL;
#ifdef USE_INTERNAL
stat = parsefilterspec(spec,&id,&nparams,&params);
#else
stat = NC_parsefilterspec(spec,&id,&nparams,&params);
#endif
if(!stat) {
report("NC_parsefilterspec failed");
exit(1);
}
for(i=0;i<nparams;i++) {
if(baseline[i] != params[i])
mismatch(i,baseline[i],params[i]);
}
/* Now some specialized tests */
uf.ui = params[6];
if(uf.f != (float)789.0)
report("uf.f");
ud.ui[0] = params[7];
ud.ui[1] = params[8];
#ifndef WORD_BIGENDIAN
byteswap8((unsigned char*)&ud.d);
#endif
if(ud.d != (double)12345678.12345678)
report("ud.d");
ul.ui[0] = params[9];
ul.ui[1] = params[10];
#ifndef WORD_BIGENDIAN
byteswap8((unsigned char*)&ul.ll);
#endif
if(ul.ll != -9223372036854775807LL)
report("ul.ll");
ul.ui[0] = params[11];
ul.ui[1] = params[12];
#ifndef WORD_BIGENDIAN
byteswap8((unsigned char*)&ul.ull);
#endif
if(ul.ull != 18446744073709551615ULL)
report("ul.ull");
return (nerrs > 0 ? 1 : 0);
}
/* Byte swap an 8-byte integer in place */
static void
byteswap8(unsigned char* mem)
{
unsigned char c;
c = mem[0];
mem[0] = mem[7];
mem[7] = c;
c = mem[1];
mem[1] = mem[6];
mem[6] = c;
c = mem[2];
mem[2] = mem[5];
mem[5] = c;
c = mem[3];
mem[3] = mem[4];
mem[4] = c;
}
#ifdef USE_INTERNAL
static int
parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp)
{
char* p;
char* sdata = NULL;
int stat;
unsigned int uval, id;
size_t count; /* no. of comma delimited params */
size_t nparams; /* final no. of unsigned ints */
size_t i;
unsigned int* ulist = NULL;
unsigned char mem[8]; /* to convert to network byte order */
if(spec == NULL || strlen(spec) == 0) goto fail;
sdata = strdup(spec);
/* Count number of parameters + id and delimit */
p=sdata;
for(count=0;;count++) {
char* q = strchr(p,',');
if(q == NULL) break;
*q++ = '\0';
p = q;
}
count++; /* for final piece */
if(count == 0)
goto fail; /* no id and no parameters */
/* Extract the filter id */
p = sdata;
stat = sscanf(p,"%u",&id);
if(stat != 1) goto fail;
p = p + strlen(p) + 1; /* skip the filter id */
count--;
/* Allocate the max needed space; *2 in case the params are all doubles */
ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count)*2);
if(ulist == NULL) goto fail;
/* walk and convert */
nparams = 0;
for(i=0;i<count;i++) {
char* q;
unsigned long long val64u;
unsigned int val32u;
double vald;
float valf;
unsigned int *vector;
int isunsigned;
int isnegative;
int type;
/* Get trailing discrimination characters */
isunsigned = 0;
isnegative = 0;
type = 0;
if(strchr(p,'-') != NULL) isnegative = 1;
q = p+strlen(p)-2;
if(*q == 'U' || *q == 'u') isunsigned = 1;
q++;
switch (*q) {
case 'f': case 'F': type = 'f'; break; /* short */
case 'd': case 'D': type = 'd'; break; /* double */
case 'b': case 'B': type = 'b'; break; /* byte */
case 's': case 'S': type = 's'; break; /* short */
case 'l': case 'L': type = 'l'; break; /* long long */
case 'u': case 'U': type = 'i'; isunsigned = 1; break; /* integer */
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': type = 'i'; break;
default:
if(*q == '\0')
type = 'i';
else goto fail;
}
/* Now parse */
switch (type) {
case 'b':
case 's':
case 'i':
/* special case for a positive integer;for back compatibility.*/
if(!isnegative)
stat = sscanf(p,"%u",&val32u);
else
stat = sscanf(p,"%d",(int*)&val32u);
if(stat != 1) goto fail;
ulist[nparams++] = val32u;
break;
case 'f':
stat = sscanf(p,"%lf",&vald);
if(stat != 1) goto fail;
valf = (float)vald;
ulist[nparams++] = *(unsigned int*)&valf;
break;
case 'd':
stat = sscanf(p,"%lf",&vald);
if(stat != 1) goto fail;
/* convert to network byte order */
memcpy(mem,&vald,sizeof(mem));
#ifndef WORDS_BIGENDIAN
byteswap8(mem); /* convert little endian to big endian */
#endif
vector = (unsigned int*)mem;
ulist[nparams++] = vector[0];
ulist[nparams++] = vector[1];
break;
case 'l': /* long long */
if(isunsigned)
stat = sscanf(p,"%llu",&val64u);
else
stat = sscanf(p,"%lld",(long long*)&val64u);
if(stat != 1) goto fail;
/* convert to network byte order */
memcpy(mem,&val64u,sizeof(mem));
#ifndef WORDS_BIGENDIAN
byteswap8(mem); /* convert little endian to big endian */
#endif
vector = (unsigned int*)mem;
ulist[nparams++] = vector[0];
ulist[nparams++] = vector[1];
break;
default:
goto fail;
}
p = p + strlen(p) + 1; /* move to next param */
}
/* Now return results */
if(idp) *idp = id;
if(nparamsp) *nparamsp = nparams;
if(paramsp) *paramsp = ulist;
ulist = NULL; /* avoid duplicate free */
if(sdata) free(sdata);
if(ulist) free(ulist);
return 1;
fail:
if(sdata) free(sdata);
if(ulist) free(ulist);
return 0;
}
#endif /*USE_INTERNAL*/

View File

@ -131,6 +131,7 @@ ENDIF()
ENDIF(USE_NETCDF4)
add_sh_test(ncdump tst_nccopy3)
add_sh_test(ncdump tst_nccopy3_subset)
add_sh_test(ncdump tst_charfill)
add_sh_test(ncdump tst_formatx3)

View File

@ -43,7 +43,7 @@ check_PROGRAMS = rewrite-scalar ctest ctest64 ncdump tst_utf8 bom tst_dimsizes n
TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ctest ctest64 tst_output.sh \
tst_lengths.sh tst_calendars.sh tst_utf8 run_utf8_tests.sh \
tst_nccopy3.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
tst_nccopy3.sh tst_nccopy3_subset.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
tst_dimsizes.sh run_ncgen_tests.sh
if USE_NETCDF4
@ -62,6 +62,10 @@ TESTS += tst_inmemory_nc4.sh
endif
endif
if USE_NETCDF4
TESTS += tst_inttags4.sh
endif
if USE_NETCDF4
# NetCDF-4 has some extra tests.
check_PROGRAMS += tst_create_files tst_h_rdc0 tst_group_data \
@ -69,7 +73,7 @@ tst_enum_data tst_opaque_data tst_string_data tst_vlen_data tst_comp \
tst_comp2 tst_nans tst_special_atts tst_unicode tst_fillbug tst_compress \
tst_chunking tst_h_scalar tst_bug324
TESTS += tst_inttags4.sh tst_create_files tst_group_data tst_enum_data tst_opaque_data \
TESTS += tst_create_files tst_group_data tst_enum_data tst_opaque_data \
tst_string_data tst_vlen_data tst_comp tst_comp2 tst_nans \
tst_special_atts tst_netcdf4.sh tst_h_rdc0 tst_unicode tst_fillbug \
tst_fillbug.sh tst_netcdf4_4.sh tst_compress tst_nccopy4.sh \
@ -110,7 +114,10 @@ endif
endif BUILD_TESTSETS
CLEANFILES = test0.nc test1.cdl test1.nc test2.cdl ctest1.cdl \
CLEANFILES = test0.nc test1_ncdump.cdl test1_ncdump.nc test2_ncdump.cdl \
test1.cdl test0_ncdump.nc ctest1.cdl \
test1_cdf5.nc test1_cdf5.cdl test0_cdf5.nc test2_cdf5.nc test2_cdf5.cdl \
test0_offset.nc test1_offset.nc test1_offset.cdl test2_offset.nc test2_offset.cdl \
ctest0.nc ctest0_64.nc c1.cdl c1_4.cdl ctest1_64.cdl c0.nc c0_4.nc small.nc \
small2.nc c0tmp.nc c1.ncml utf8.cdl utf8_64.cdl utf8.nc utf8_64.nc \
tmp.cdl tst_vlen_data.nc tst_utf8.nc tst_special_atts.nc \
@ -135,10 +142,10 @@ tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc \
nc4_fileinfo.nc hdf5_fileinfo.hdf \
ref_hdf5_compat1.nc ref_hdf5_compat2.nc ref_hdf5_compat3.nc \
ref_tst_compounds.nc ref_tst_dims.nc ref_tst_interops4.nc \
ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc
ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc nccopy3_subset_out.nc
# These files all have to be included with the distribution.
EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
ref_ctest1_nc4.cdl ref_ctest1_nc4c.cdl ref_tst_solar_1.cdl \
ref_tst_solar_2.cdl tst_netcdf4.sh tst_netcdf4_4.sh ref_tst_small.cdl \
tst_lengths.sh tst_ncml.cdl ref1.ncml ref_tst_group_data.cdl \
@ -164,7 +171,7 @@ tst_formatx3.sh tst_formatx4.sh ref_tst_utf8_4.cdl \
tst_inttags.sh tst_inttags4.sh \
CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh \
tst_dimsizes.sh tst_inmemory_nc4.sh tst_fileinfo.sh run_ncgen_tests.sh \
run_ncgen_nc4_tests.sh
run_ncgen_nc4_tests.sh tst_nccopy3_subset.sh ref_nccopy3_subset.nc
# CDL files and Expected results
SUBDIRS=cdl expected
@ -177,7 +184,7 @@ CLEANFILES += results/*.nc results/*.dmp results/*.dmp2 tmp*.cdl \
tst_c0_64.cdl tst_compound_datasize_test.cdl \
tst_compound_datasize_test2.cdl tst_gattenum.nc \
tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl \
tst_usuffix.nc tst_bug324.nc
tst_usuffix.nc tst_bug324.nc nccopy3_subset_out.nc
DISTCLEANFILES = results

View File

@ -1,7 +1,7 @@
/*********************************************************************
* Copyright 2010, University Corporation for Atmospheric Research
* See netcdf/README file for copying and redistribution conditions.
* Thanks to Philippe Poilbarbe and Antonio S. Cofiño for
* Thanks to Philippe Poilbarbe and Antonio S. Cofiño for
* compression additions.
* $Id: nccopy.c 400 2010-08-27 21:02:52Z russ $
*********************************************************************/
@ -17,14 +17,12 @@
#endif
#include <string.h>
#include "netcdf.h"
#ifdef USE_NETCDF4
#include "netcdf_filter.h"
#endif
#include "nciter.h"
#include "utils.h"
#include "chunkspec.h"
#include "dimmap.h"
#include "nccomps.h"
#include "ncfilter.h"
#ifdef _MSC_VER
#include "XGetopt.h"
@ -230,18 +228,17 @@ done:
}
#endif
static int
parsefilterspec(const char* optarg0, struct FilterSpec* spec)
{
char* p;
char* q;
char* optarg = NULL;
unsigned int* params = NULL;
size_t nparams;
unsigned int id;
char* p = NULL;
char* remainder = NULL;
unsigned int params[MAX_FILTER_PARAMS];
int nparams = 0;
if(optarg0 == NULL || strlen(optarg0) == 0) return 0;
if(optarg0 == NULL || strlen(optarg0) == 0 || spec == NULL) return 0;
optarg = strdup(optarg0);
/* Collect the fqn, taking escapes into account */
@ -263,37 +260,14 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
strcat(spec->fqn,optarg);
}
/* Get filterid */
q = (p = remainder);
for(;;) {
if(*p == ',') {*p = '\0'; remainder = p+1; break;}
else if(*p == '\0') {remainder = p; break;}
else if(strchr("0123456789",*p) == NULL) return 0; /* not a number */
/* else continue */
p++;
/* Collect the id+parameters */
if(!NC_parsefilterspec(remainder,&id,&nparams,&params))
return 0;
if(spec != NULL) {
spec->filterid = id;
spec->nparams = nparams;
spec->params = params;
}
if(strlen(q) == 0) return 0; /* id does not exist */
sscanf(q,"%u",&spec->filterid);
/* Collect the parameters */
q = (p = remainder);
for(;;) {
int c = *p;
if(c == ',' || c == '\0') {
unsigned int parm;
*p++ = '\0';
if(strlen(q) == 0) return 0; /* bad param */
sscanf(q,"%u",&parm);
params[nparams++] = parm;
q = p;
if(c == '\0') break;
} else if(strchr("0123456789",*p) == NULL) return 0; /* not a number */
/* else continue */
p++;
}
spec->nparams = nparams;
spec->params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
memcpy(spec->params,params,(sizeof(unsigned int)*nparams));
return 1;
}
@ -412,14 +386,14 @@ inq_var_chunking_params(int igrp, int ivarid, int ogrp, int ovarid,
/* Forward declaration, because copy_type, copy_vlen_type call each other */
static int copy_type(int igrp, nc_type typeid, int ogrp);
/*
/*
* copy a user-defined variable length type in the group igrp to the
* group ogrp
*/
static int
copy_vlen_type(int igrp, nc_type itype, int ogrp)
{
int stat = NC_NOERR;
int stat = NC_NOERR;
nc_type ibasetype;
nc_type obasetype; /* base type in target group */
char name[NC_MAX_NAME];
@ -446,13 +420,13 @@ copy_vlen_type(int igrp, nc_type itype, int ogrp)
return stat;
}
/*
/*
* copy a user-defined opaque type in the group igrp to the group ogrp
*/
static int
copy_opaque_type(int igrp, nc_type itype, int ogrp)
{
int stat = NC_NOERR;
int stat = NC_NOERR;
nc_type otype;
char name[NC_MAX_NAME];
size_t size;
@ -463,13 +437,13 @@ copy_opaque_type(int igrp, nc_type itype, int ogrp)
return stat;
}
/*
/*
* copy a user-defined enum type in the group igrp to the group ogrp
*/
static int
copy_enum_type(int igrp, nc_type itype, int ogrp)
{
int stat = NC_NOERR;
int stat = NC_NOERR;
nc_type otype;
nc_type basetype;
size_t basesize;
@ -488,13 +462,13 @@ copy_enum_type(int igrp, nc_type itype, int ogrp)
return stat;
}
/*
/*
* copy a user-defined compound type in the group igrp to the group ogrp
*/
static int
copy_compound_type(int igrp, nc_type itype, int ogrp)
{
int stat = NC_NOERR;
int stat = NC_NOERR;
char name[NC_MAX_NAME];
size_t size;
size_t nfields;
@ -522,7 +496,7 @@ copy_compound_type(int igrp, nc_type itype, int ogrp)
} else { /* field is array type */
int *fdimsizes;
fdimsizes = (int *) emalloc((fndims + 1) * sizeof(int));
stat = nc_inq_compound_field(igrp, itype, fid, NULL, NULL, NULL,
stat = nc_inq_compound_field(igrp, itype, fid, NULL, NULL, NULL,
NULL, fdimsizes);
NC_CHECK(nc_insert_array_compound(ogrp, otype, fname, foff, oftype, fndims, fdimsizes));
free(fdimsizes);
@ -532,13 +506,13 @@ copy_compound_type(int igrp, nc_type itype, int ogrp)
}
/*
/*
* copy a user-defined type in the group igrp to the group ogrp
*/
static int
copy_type(int igrp, nc_type typeid, int ogrp)
{
int stat = NC_NOERR;
int stat = NC_NOERR;
nc_type type_class;
NC_CHECK(nc_inq_user_type(igrp, typeid, NULL, NULL, NULL, NULL, &type_class));
@ -593,7 +567,7 @@ copy_groups(int iroot, int oroot)
NC_CHECK(nc_inq_grpname_full(grpids[i], &len_name, grpname_full));
/* Make sure, the parent group is also wanted (root group is always wanted) */
NC_CHECK(nc_inq_parid(iroot, grpname_full, &iparid));
if (!option_grpstruct && !group_wanted(iparid, option_nlgrps, option_grpids)
if (!option_grpstruct && !group_wanted(iparid, option_nlgrps, option_grpids)
&& iparid != iroot) {
error("ERROR: trying to copy a group but not the parent: %s", grpname_full);
}
@ -610,17 +584,17 @@ copy_groups(int iroot, int oroot)
}
free(grpids);
}
return stat;
return stat;
}
/*
/*
* Copy the user-defined types in this group (igrp) and all its
* subgroups, recursively, to corresponding group in output (ogrp)
*/
static int
copy_types(int igrp, int ogrp)
{
int stat = NC_NOERR;
int stat = NC_NOERR;
int ntypes;
nc_type *types = NULL;
int numgrps;
@ -672,7 +646,7 @@ copy_var_specials(int igrp, int varid, int ogrp, int o_varid)
size_t *chunkp = (size_t *) emalloc(ndims * sizeof(size_t));
int *dimids = (int *) emalloc(ndims * sizeof(int));
int idim;
/* size of a chunk: product of dimension chunksizes and size of value */
/* size of a chunk: product of dimension chunksizes and size of value */
size_t csprod = val_size(ogrp, o_varid);
int is_unlimited = 0;
NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, chunkp));
@ -788,8 +762,10 @@ copy_var_filter(int igrp, int varid, int ogrp, int o_varid)
}
/* Apply filter spec if any */
if(spec.filterid > 0) {/* Apply filter */
#ifdef USE_NETCDF4
if((stat=nc_def_var_filter(ovid.grpid,ovid.varid,spec.filterid,spec.nparams,spec.params)))
goto done;
#endif
}
done:
/* Cleanup */
@ -842,7 +818,7 @@ set_var_chunked(int ogrp, int o_varid)
size_t dimlen;
NC_CHECK(nc_inq_dimlen(ogrp, odimid, &dimlen));
if( (chunksize > 0) || dimmap_ounlim(odimid)) {
chunked = 1;
chunked = 1;
}
if(dimlen > 0) { /* dimlen for unlimited dims is still 0 before copying data */
varsize *= dimlen;
@ -934,7 +910,7 @@ copy_dims(int igrp, int ogrp)
int *unlimids;
#else
int unlimid;
#endif /* USE_NETCDF4 */
#endif /* USE_NETCDF4 */
NC_CHECK(nc_inq_ndims(igrp, &ndims));
@ -971,7 +947,7 @@ copy_dims(int igrp, int ogrp)
if(idimid == unlimids[uld]) {
i_is_unlim = 1;
break;
}
}
}
#else
idimid = dgrp;
@ -983,7 +959,7 @@ copy_dims(int igrp, int ogrp)
stat = nc_inq_dim(igrp, idimid, name, &length);
if (stat == NC_EDIMSIZE && sizeof(size_t) < 8) {
error("dimension \"%s\" requires 64-bit platform", name);
}
}
NC_CHECK(stat);
o_is_unlim = i_is_unlim;
if(i_is_unlim && !option_fix_unlimdims) {
@ -998,7 +974,7 @@ copy_dims(int igrp, int ogrp)
#ifdef USE_NETCDF4
free(dimids);
free(unlimids);
#endif /* USE_NETCDF4 */
#endif /* USE_NETCDF4 */
return stat;
}
@ -1013,7 +989,7 @@ copy_atts(int igrp, int ivar, int ogrp, int ovar)
int stat = NC_NOERR;
NC_CHECK(nc_inq_varnatts(igrp, ivar, &natts));
for(iatt = 0; iatt < natts; iatt++) {
char name[NC_MAX_NAME];
NC_CHECK(nc_inq_attname(igrp, ivar, iatt, name));
@ -1064,7 +1040,7 @@ copy_var(int igrp, int varid, int ogrp)
NC_CHECK(nc_def_var(ogrp, name, o_typeid, ndims, odimids, &o_varid));
/* attach the variable attributes to the output variable */
NC_CHECK(copy_atts(igrp, varid, ogrp, o_varid));
#ifdef USE_NETCDF4
#ifdef USE_NETCDF4
{
int inkind;
int outkind;
@ -1112,7 +1088,7 @@ copy_vars(int igrp, int ogrp)
if(nc_inq_gvarid(igrp, option_lvars[iv], &varid) == NC_NOERR)
idadd(vlist, varid);
}
NC_CHECK(nc_inq_nvars(igrp, &nvars));
for (varid = 0; varid < nvars; varid++) {
if (!option_varstruct && option_nlvars > 0 && ! idmember(vlist, varid))
@ -1127,7 +1103,7 @@ copy_vars(int igrp, int ogrp)
* group igrp in input to parent group ogrp in destination. Use
* dimmap array to map input dimids to output dimids. */
static int
copy_schema(int igrp, int ogrp)
copy_schema(int igrp, int ogrp)
{
int stat = NC_NOERR;
int ogid; /* like igrp but in output file */
@ -1139,7 +1115,7 @@ copy_schema(int igrp, int ogrp)
NC_CHECK(copy_dims(igrp, ogid));
NC_CHECK(copy_atts(igrp, NC_GLOBAL, ogid, NC_GLOBAL));
NC_CHECK(copy_vars(igrp, ogid));
#ifdef USE_NETCDF4
#ifdef USE_NETCDF4
{
int numgrps;
int *grpids;
@ -1148,7 +1124,7 @@ copy_schema(int igrp, int ogrp)
stat = nc_inq_grps(igrp, &numgrps, NULL);
grpids = (int *)emalloc((numgrps + 1) * sizeof(int));
NC_CHECK(nc_inq_grps(igrp, &numgrps, grpids));
for(i = 0; i < numgrps; i++) {
if (option_grpstruct || group_wanted(grpids[i], option_nlgrps, option_grpids)) {
NC_CHECK(copy_schema(grpids[i], ogid));
@ -1157,7 +1133,7 @@ copy_schema(int igrp, int ogrp)
free(grpids);
}
#endif /* USE_NETCDF4 */
return stat;
return stat;
}
/* Return number of values for a variable varid in a group igrp */
@ -1199,7 +1175,7 @@ copy_var_data(int igrp, int varid, int ogrp) {
size_t *count;
nciter_t *iterp; /* opaque structure for iteration status */
int do_realloc = 0;
#ifdef USE_NETCDF4
#ifdef USE_NETCDF4
int okind;
size_t chunksize;
#endif
@ -1216,10 +1192,10 @@ copy_var_data(int igrp, int varid, int ogrp) {
option_copy_buffer_size = value_size;
do_realloc = 1;
}
#ifdef USE_NETCDF4
#ifdef USE_NETCDF4
NC_CHECK(nc_inq_format(ogrp, &okind));
if(okind == NC_FORMAT_NETCDF4 || okind == NC_FORMAT_NETCDF4_CLASSIC) {
/* if this variable chunked, set variable chunk cache size */
/* if this variable chunked, set variable chunk cache size */
int contig = 1;
NC_CHECK(nc_inq_var_chunking(ogrp, ovarid, &contig, NULL));
if(contig == 0) { /* chunked */
@ -1230,16 +1206,16 @@ copy_var_data(int igrp, int varid, int ogrp) {
size_t chunkcache_size, chunkcache_nelems;
float chunkcache_preemption;
NC_CHECK(inq_var_chunking_params(igrp, varid, ogrp, ovarid,
&chunkcache_size,
&chunkcache_nelems,
&chunkcache_size,
&chunkcache_nelems,
&chunkcache_preemption));
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
chunkcache_size,
chunkcache_nelems,
chunkcache_preemption));
} else {
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
chunkcache_size,
chunkcache_nelems,
chunkcache_preemption));
} else {
/* by default, use same chunk cache for all chunked variables */
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
option_chunk_cache_size,
option_chunk_cache_nelems,
COPY_CHUNKCACHE_PREEMPTION));
@ -1331,11 +1307,11 @@ copy_data(int igrp, int ogrp)
if(nc_inq_gvarid(igrp, option_lvars[iv], &varid) == NC_NOERR)
idadd(vlist, varid);
}
/* get groupid in output corresponding to group igrp in input,
* given parent group (or root group) ogrp in output */
NC_CHECK(get_grpid(igrp, ogrp, &ogid));
/* Copy data from this group */
NC_CHECK(nc_inq_nvars(igrp, &nvars));
@ -1378,7 +1354,7 @@ count_dims(int ncid) {
for(igrp = 0; igrp < numgrps; igrp++) {
ndims += count_dims(grpids[igrp]);
}
free(grpids);
free(grpids);
}
#endif /* USE_NETCDF4 */
return ndims;
@ -1433,20 +1409,36 @@ classify_vars(
int **rvars) /* the array of record variable IDs, caller should free */
{
int varid;
int varindex = 0;
int nvars;
NC_CHECK(nc_inq_nvars(ncid, &nvars));
*nf = 0;
*fvars = (int *) emalloc(nvars * sizeof(int));
*nr = 0;
*rvars = (int *) emalloc(nvars * sizeof(int));
for (varid = 0; varid < nvars; varid++) {
if (isrecvar(ncid, varid)) {
(*rvars)[*nr] = varid;
(*nr)++;
} else {
(*fvars)[*nf] = varid;
(*nf)++;
}
if(option_nlvars > 0) {
for (varindex = 0; varindex < option_nlvars; varindex++) {
nc_inq_varid(ncid,option_lvars[varindex],&varid);
if (isrecvar(ncid, varid)) {
(*rvars)[*nr] = varid;
(*nr)++;
} else {
(*fvars)[*nf] = varid;
(*nf)++;
}
}
} else {
for (varid = 0; varid < nvars; varid++) {
if (isrecvar(ncid, varid)) {
(*rvars)[*nr] = varid;
(*nr)++;
} else {
(*fvars)[*nf] = varid;
(*nf)++;
}
}
}
return NC_NOERR;
}
@ -1475,7 +1467,7 @@ copy_rec_var_data(int ncid, /* input */
size_t *start, /* start indices for record data */
size_t *count, /* edge lengths for record data */
void *buf /* buffer large enough to hold data */
)
)
{
NC_CHECK(nc_get_vara(ncid, varid, start, count, buf));
NC_CHECK(nc_put_vara(ogrp, ovarid, start, count, buf));
@ -1525,7 +1517,7 @@ copy_record_data(int ncid, int ogrp, size_t nrec_vars, int *rec_varids) {
start[ivar][ii] = 0;
count[ivar][ii] = dimlen;
}
start[ivar][0] = 0;
start[ivar][0] = 0;
count[ivar][0] = 1; /* 1 record */
buf[ivar] = (void *) emalloc(nvals * value_size);
NC_CHECK(nc_inq_varname(ncid, varid, varname));
@ -1541,7 +1533,7 @@ copy_record_data(int ncid, int ogrp, size_t nrec_vars, int *rec_varids) {
varid = rec_varids[ivar];
ovarid = rec_ovarids[ivar];
start[ivar][0] = irec;
NC_CHECK(copy_rec_var_data(ncid, ogrp, irec, varid, ovarid,
NC_CHECK(copy_rec_var_data(ncid, ogrp, irec, varid, ovarid,
start[ivar], count[ivar], buf[ivar]));
}
}
@ -1591,11 +1583,11 @@ copy(char* infile, char* outfile)
/* option_kind specifies which netCDF format for output, one of
*
* SAME_AS_INPUT, NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
* NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC
* SAME_AS_INPUT, NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
* NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC
*
* However, if compression or shuffling was specified and kind was SAME_AS_INPUT,
* option_kind is changed to NC_FORMAT_NETCDF4_CLASSIC, if input format is
* option_kind is changed to NC_FORMAT_NETCDF4_CLASSIC, if input format is
* NC_FORMAT_CLASSIC or NC_FORMAT_64BIT .
*/
outkind = option_kind;
@ -1603,11 +1595,11 @@ copy(char* infile, char* outfile)
outkind = inkind;
/* Deduce output kind if netCDF-4 features requested */
if (inkind == NC_FORMAT_CLASSIC || inkind == NC_FORMAT_64BIT_OFFSET
|| inkind == NC_FORMAT_CDF5) {
if (option_deflate_level > 0 ||
option_shuffle_vars == NC_SHUFFLE ||
option_chunkspec)
{
|| inkind == NC_FORMAT_CDF5) {
if (option_deflate_level > 0 ||
option_shuffle_vars == NC_SHUFFLE ||
option_chunkspec)
{
outkind = NC_FORMAT_NETCDF4_CLASSIC;
}
}
@ -1645,8 +1637,13 @@ copy(char* infile, char* outfile)
create_mode |= NC_64BIT_OFFSET;
break;
case NC_FORMAT_CDF5:
create_mode |= NC_64BIT_DATA;
break;
#ifdef USE_CDF5
create_mode |= NC_64BIT_DATA;
break;
#else
error("netCDF library built without CDF5 support, can't create CDF5 files");
break;
#endif
#ifdef USE_NETCDF4
case NC_FORMAT_NETCDF4:
create_mode |= NC_NETCDF4;
@ -1700,7 +1697,7 @@ copy(char* infile, char* outfile)
NC_CHECK(classify_vars(ogrp, &nfixed_vars, &fixed_varids, &nrec_vars, &rec_varids));
NC_CHECK(copy_fixed_size_data(igrp, ogrp, nfixed_vars, fixed_varids));
NC_CHECK(copy_record_data(igrp, ogrp, nrec_vars, rec_varids));
} else {
} else {
NC_CHECK(copy_data(igrp, ogrp)); /* recursive, to handle nested groups */
}
@ -1709,7 +1706,7 @@ copy(char* infile, char* outfile)
return stat;
}
/*
/*
* For non-negative numeric string with multiplier suffix K, M, G, T,
* or P (or lower-case equivalent), return corresponding value
* incorporating multiplier 1000, 1000000, 1.0d9, ... 1.0d15, or -1.0
@ -1742,7 +1739,7 @@ double_with_suffix(char *str) {
break;
default:
dval = -1.0; /* error, suffix multiplier must be K, M, G, or T */
}
}
}
return dval;
}
@ -1802,13 +1799,13 @@ main(int argc, char**argv)
{"classic", NC_FORMAT_CLASSIC}, /* canonical format name */
{"nc3", NC_FORMAT_CLASSIC}, /* short format name */
{"1", NC_FORMAT_CLASSIC}, /* deprecated, use "-3" or "-k nc3" instead */
/* NetCDF-3 64-bit offset format */
{"64-bit offset", NC_FORMAT_64BIT_OFFSET}, /* canonical format name */
{"nc6", NC_FORMAT_64BIT_OFFSET}, /* short format name */
{"2", NC_FORMAT_64BIT_OFFSET}, /* deprecated, use "-6" or "-k nc6" instead */
{"64-bit-offset", NC_FORMAT_64BIT_OFFSET}, /* deprecated alias */
/* NetCDF-4 HDF5-based format */
{"netCDF-4", NC_FORMAT_NETCDF4}, /* canonical format name */
{"nc4", NC_FORMAT_NETCDF4}, /* short format name */
@ -1848,7 +1845,7 @@ main(int argc, char**argv)
while ((c = getopt(argc, argv, "k:3467d:sum:c:h:e:rwxg:G:v:V:F:")) != -1) {
switch(c) {
case 'k': /* for specifying variant of netCDF format to be generated
case 'k': /* for specifying variant of netCDF format to be generated
Format names:
"classic" or "nc3"
"64-bit offset" or "nc6"

View File

@ -36,7 +36,6 @@ int optind;
#include "netcdf.h"
#include "netcdf_mem.h"
#include "netcdf_filter.h"
#include "utils.h"
#include "nccomps.h"
#include "nctime0.h" /* new iso time and calendar stuff */

View File

@ -5,7 +5,7 @@ variables:
ubyte ub(d) ;
ushort us(d) ;
uint ui(d) ;
int i64(d) ;
int64 i64(d) ;
uint64 ui64(d) ;
// global attributes:
@ -18,7 +18,7 @@ data:
ui = 4294967294, 4294967294, 4294967294 ;
i64 = -1, -1, -1 ;
i64 = 9223372036854775807, 9223372036854775807, 9223372036854775807 ;
ui64 = 18446744073709551615, 18446744073709551615, 18446744073709551615 ;
}

Binary file not shown.

View File

@ -8,6 +8,19 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
echo "*** Testing ncgen."
set -e
# This shell script runs the ncdump tests.
# get some config.h parameters
if test -f ${top_builddir}/config.h ; then
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
CDF5=1
else
CDF5=0
fi
else
echo "Cannot locate config.h"
exit 1
fi
#VALGRIND="valgrind -q --error-exitcode=2 --leak-check=full"
validateNC() {
@ -37,11 +50,15 @@ echo "*** creating 64-bit offset file c0_64.nc from c0.cdl..."
validateNC c0 "c0_64" -k 64-bit-offset -b
echo "*** creating 64-bit offset file c5.nc from c5.cdl..."
${NCGEN} -k 64-bit-data -b -o c5.nc $top_srcdir/ncgen/c5.cdl
if [ ! -f c5.nc ]; then
echo "Failure."
exit 1
if test "x$USE_CDF5" = x1 ; then
echo "*** creating 64-bit data file c5.nc from c5.cdl..."
${NCGEN} -k 64-bit-data -b -o c5.nc $top_srcdir/ncgen/c5.cdl
if [ ! -f c5.nc ]; then
echo "Failure."
exit 1
fi
fi
echo "*** Test successful!"

View File

@ -15,16 +15,16 @@ echo "*** creating tst_small.cdl from tst_small.nc..."
${NCDUMP} tst_small.nc > tst_small.cdl
diff -b -w tst_small.cdl $srcdir/ref_tst_small.cdl
echo "*** creating test0.nc from test0.cdl..."
${NCGEN} -b $srcdir/test0.cdl
echo "*** creating test1.cdl from test0.nc..."
${NCDUMP} -n test1 test0.nc > test1.cdl
echo "*** creating test1.nc from test1.cdl..."
${NCGEN} -b test1.cdl
echo "*** creating test2.cdl from test1.nc..."
${NCDUMP} test1.nc > test2.cdl
echo "*** checking that test1.cdl and test2.cdl are the same..."
diff -b -w test1.cdl test2.cdl
echo "*** creating test0_ncdump.nc from test0.cdl..."
${NCGEN} -o test0_ncdump.nc -b $srcdir/test0.cdl
echo "*** creating test1_ncdump.cdl from test0_ncdump.nc..."
${NCDUMP} -n test1_ncdump test0_ncdump.nc > test1_ncdump.cdl
echo "*** creating test1_ncdump.nc from test1_ncdump.cdl..."
${NCGEN} -b test1_ncdump.cdl
echo "*** creating test2_ncdump.cdl from test1_ncdump.nc..."
${NCDUMP} test1_ncdump.nc > test2_ncdump.cdl
echo "*** checking that test1_ncdump.cdl and test2_ncdump.cdl are the same..."
diff -b -w test1_ncdump.cdl test2_ncdump.cdl
echo "*** All tests of ncgen and ncdump using test0.cdl passed!"
exit 0

View File

@ -1,37 +1,52 @@
#!/bin/sh
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
set -e
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
# This shell script runs the ncdump tests.
# get some config.h parameters
if test -f ${top_builddir}/config.h ; then
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
CDF5=1
else
CDF5=0
fi
else
echo "Cannot locate config.h"
exit 1
fi
echo ""
echo "*** Testing ncgen and ncdump with 64-bit offset format."
set -e
echo "*** creating test0.nc from test0.cdl..."
${NCGEN} -b -k2 $srcdir/test0.cdl
echo "*** creating test1.cdl from test0.nc..."
${NCDUMP} -n test1 test0.nc > test1.cdl
echo "*** creating test1.nc from test1.cdl..."
${NCGEN} -b -k2 test1.cdl
echo "*** creating test2.cdl from test1.nc..."
${NCDUMP} test1.nc > test2.cdl
cmp test1.cdl test2.cdl
echo "*** creating test0_offset.nc from test0.cdl..."
${NCGEN} -b -k2 -o test0_offset.nc $srcdir/test0.cdl
echo "*** creating test1_offset.cdl from test0_offset.nc..."
${NCDUMP} -n test1_offset test0_offset.nc > test1_offset.cdl
echo "*** creating test1_offset.nc from test1_offset.cdl..."
${NCGEN} -b -k2 -o test1_offset.nc test1_offset.cdl
echo "*** creating test2_offset.cdl from test1.nc..."
${NCDUMP} test1_offset.nc > test2_offset.cdl
cmp test1_offset.cdl test2_offset.cdl
echo "*** All ncgen and ncdump with 64-bit offset format tests passed!"
if test "x$CDF5" = x1 ; then
echo ""
echo "*** Testing ncgen and ncdump with CDF5 format."
set -e
echo "*** creating test0.nc from test0.cdl..."
${NCGEN} -b -k5 $srcdir/test0.cdl
echo "*** creating test1.cdl from test0.nc..."
${NCDUMP} -n test1 test0.nc > test1.cdl
echo "*** creating test1.nc from test1.cdl..."
${NCGEN} -b -k5 test1.cdl
echo "*** creating test2.cdl from test1.nc..."
${NCDUMP} test1.nc > test2.cdl
cmp test1.cdl test2.cdl
echo "*** creating test0_cdf5.nc from test0.cdl..."
${NCGEN} -b -k5 -o test0_cdf5.nc $srcdir/test0.cdl
echo "*** creating test1_cdf5.cdl from test0_cdf5.nc..."
${NCDUMP} -n test1_cdf5 test0_cdf5.nc > test1_cdf5.cdl
echo "*** creating test1_cdf5.nc from test1_cdf5.cdl..."
${NCGEN} -b -k5 -o test1_cdf5.nc test1_cdf5.cdl
echo "*** creating test2_cdf5.cdl from test1_cdf5.nc..."
${NCDUMP} test1_cdf5.nc > test2_cdf5.cdl
cmp test1_cdf5.cdl test2_cdf5.cdl
echo "*** All ncgen and ncdump with CDF5 format tests passed!"
fi
exit 0

View File

@ -1,3 +1,4 @@
#include "config.h"
#include <nc_tests.h>
#include "err_macros.h"
#include <stdio.h>
@ -10,7 +11,10 @@
#define DIMMAXCLASSIC (NC_MAX_INT - 3)
#define DIMMAX64OFFSET (NC_MAX_UINT - 3)
#ifdef USE_CDF5
#define DIMMAX64DATA (NC_MAX_UINT64 - 3)
#endif
/*
Test that at least the meta-data works
@ -62,6 +66,7 @@ main(int argc, char **argv)
if(dimsize != DIMMAX64OFFSET) ERR;
if ((stat=nc_close(ncid))) ERRSTAT(stat);
#ifdef USE_CDF5
if(sizeof(size_t) == 8) {
printf("\n*** Writing Max Dimension Size (%llu) For NC_64BIT_DATA\n",DIMMAX64DATA);
if ((stat=nc_create(FILE64DATA, NC_CLOBBER | NC_64BIT_DATA, &ncid))) ERRSTAT(stat);
@ -76,6 +81,7 @@ main(int argc, char **argv)
if(dimsize != DIMMAX64DATA) ERR;
if ((stat=nc_close(ncid))) ERRSTAT(stat);
}
#endif /* USE_CDF5 */
SUMMARIZE_ERR;
FINAL_RESULTS;

View File

@ -1,8 +1,21 @@
#!/bin/sh
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
# This shell script runs the ncdump tests.
# get some config.h parameters
if test -f ${top_builddir}/config.h ; then
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
USE_CDF5=1
else
USE_CDF5=0
fi
else
echo "Cannot locate config.h"
exit 1
fi
# This shell script tests the output several previous tests.
ECODE=0
@ -28,17 +41,20 @@ echo "*** Fail: extended format for a 64-bit classic file"
ECODE=1
fi
echo "Test extended format output for a 64-bit CDF-5 classic file"
rm -f tmp
${NCGEN} -k5 -b -o ./test.nc $srcdir/ref_tst_small.cdl
${NCDUMP} -K test.nc >tmp
if ! grep -F '64-bit data mode=00000020' <tmp ; then
echo "*** Fail: extended format for a 64-bit CDF-5 classic file"
ECODE=1
# Only do following test if USE_CDF5 is true.
if test "x$USE_CDF5" = x1 ; then
echo "Test extended format output for a 64-bit CDF-5 classic file"
rm -f tmp
${NCGEN} -k5 -b -o ./test.nc $srcdir/ref_tst_small.cdl
${NCDUMP} -K test.nc >tmp
if ! grep -F '64-bit data mode=00000020' <tmp ; then
echo "*** Fail: extended format for a 64-bit CDF-5 classic file"
ECODE=1
fi
fi
rm -f tmp test.nc
exit $ECODE

View File

@ -1,6 +1,6 @@
#!/bin/sh
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
set -e
@ -8,7 +8,7 @@ set -e
echo "*** Test netcdf-4 integer constant suffixes"
echo "*** creating inttags4.nc from inttags4.cdl..."
${NCGEN} -lb -o inttags4.nc $srcdir/inttags4.cdl
${NCGEN} -lb -k nc4 -o inttags4.nc $srcdir/inttags4.cdl
echo "*** creating tst_inttags4.cdl from inttags4.nc..."
${NCDUMP} inttags4.nc > tst_inttags4.cdl
echo "*** comparing tst_inttags4.cdl to ref_inttags4.nc..."

View File

@ -1,8 +1,20 @@
#!/bin/sh
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
# get some config.h parameters
if test -f ${top_builddir}/config.h ; then
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
HAVE_CDF5=1
else
HAVE_CDF5=0
fi
else
echo "Cannot locate config.h"
exit 1
fi
# It is unreasonable to test actual lengths of files
# (even netcdf-3 files).
#However, the files created in this script are used in later ones
@ -10,7 +22,7 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
${NCGEN} -b ${srcdir}/small.cdl
${NCGEN} -b ${srcdir}/small2.cdl
# This shell script tests lengths of small netcdf files and tests
# This shell script tests lengths of small netcdf files and tests
# that rewriting a numeric value doesn't change file length
# $Id: tst_lengths.sh,v 1.10 2008/08/07 00:07:52 ed Exp $
@ -93,39 +105,44 @@ ${NCGEN} -b -k64-bit-offset -x ${srcdir}/small.cdl && ${execdir}/rewrite-scalar
# exit 1
#fi
echo "*** testing length of 64-bit data file"
${NCGEN} -b -k64-bit-data ${srcdir}/small.cdl
if test `wc -c < small.nc` != 104; then
exit 1
# The following tests only occur if we have CDF5.
if test "x$HAVE_CDF5" = x1 ; then
echo "*** testing length of 64-bit data file"
${NCGEN} -b -k64-bit-data ${srcdir}/small.cdl
if test `wc -c < small.nc` != 104; then
exit 1
fi
echo "*** testing length of 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small.cdl
if test `wc -c < small.nc` != 104; then
exit 1
fi
echo "*** testing length of 64-bit data file written with NOFILL"
${NCGEN} -b -5 -x ${srcdir}/small.cdl
#if test `wc -c < small.nc` != 104; then
# exit 1
#fi
echo "*** testing length of rewritten 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
# Watch out, it appears that the CDF-5 files are being rounded up to next page size
# So, we need to truncate them wrt nul's in order to check size.
# Bad hack, but what else can I do?
if test `${execdir}/nctrunc <small.nc |wc -c` != 104; then
exit 1
fi
echo "*** testing length of rewritten 64-bit data file written with NOFILL"
${NCGEN} -b -5 -x ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
#if test `wc -c < small.nc` != 104; then
# exit 1
#fi
# End HAVE_CDF5 block.
fi
echo "*** testing length of 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small.cdl
if test `wc -c < small.nc` != 104; then
exit 1
fi
echo "*** testing length of 64-bit data file written with NOFILL"
${NCGEN} -b -5 -x ${srcdir}/small.cdl
#if test `wc -c < small.nc` != 104; then
# exit 1
#fi
echo "*** testing length of rewritten 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
# Watch out, it appears that the CDF-5 files are being rounded up to next page size
# So, we need to truncate them wrt nul's in order to check size.
# Bad hack, but what else can I do?
if test `${execdir}/nctrunc <small.nc |wc -c` != 104; then
exit 1
fi
echo "*** testing length of rewritten 64-bit data file written with NOFILL"
${NCGEN} -b -5 -x ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
#if test `wc -c < small.nc` != 104; then
# exit 1
#fi
# test with only one record variable of type byte or short, which need
# not be 4-byte aligned
echo "*** testing length of one-record-variable classic file"
@ -134,22 +151,28 @@ ${NCGEN} -b ${srcdir}/small2.cdl
# exit 1
#fi
echo "*** testing length of one-record-variable 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small2.cdl
if test `wc -c < small2.nc` != 161; then
exit 1
fi
# The following tests only occur if we have CDF5.
if test "x$HAVE_CDF5" = x1 ; then
echo "*** testing length of one-record-variable 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small2.cdl
if test `wc -c < small2.nc` != 161; then
exit 1
fi
echo "*** testing length of one-record-variable 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small2.cdl
if test `wc -c < small2.nc` != 161; then
exit 1
fi
echo "*** testing length of one-record-variable 64-bit data file written with NOFILL"
${NCGEN} -b -5 -x ${srcdir}/small2.cdl
if test `wc -c < small2.nc` != 161; then
exit 1
echo "*** testing length of one-record-variable 64-bit data file"
${NCGEN} -b -5 ${srcdir}/small2.cdl
if test `wc -c < small2.nc` != 161; then
exit 1
fi
echo "*** testing length of one-record-variable 64-bit data file written with NOFILL"
${NCGEN} -b -5 -x ${srcdir}/small2.cdl
if test `wc -c < small2.nc` != 161; then
exit 1
fi
#end HAVE_CDF5 block
fi
echo "*** testing length of one-record-variable classic file written with NOFILL"

View File

@ -1,6 +1,6 @@
#!/bin/sh
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
# For a netCDF-3 build, test nccopy on netCDF files in this directory
@ -8,9 +8,26 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
set -e
echo ""
TESTFILES='c0 c0tmp ctest0 ctest0_64 small small2 test0 test1
# get some config.h parameters
if test -f ${top_builddir}/config.h ; then
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
HAVE_CDF5=1
else
HAVE_CDF5=0
fi
else
echo "Cannot locate config.h"
exit 1
fi
TESTFILES='c0 c0tmp ctest0 ctest0_64 test0_offset test1_offset
tst_calendars tst_mslp tst_mslp_64 tst_ncml tst_small tst_utf8 utf8'
if test "x$HAVE_CDF5" = x1 ; then
TESTFILES="$TESTFILES small small2"
fi
echo "*** Testing netCDF-3 features of nccopy on ncdump/*.nc files"
for i in $TESTFILES ; do
echo "*** Testing nccopy $i.nc copy_of_$i.nc ..."

41
ncdump/tst_nccopy3_subset.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
#
# Added in support of https://github.com/Unidata/netcdf-c/gh425 and
# https://github.com/Unidata/netcdf-c/gh469
#
# The output isn't validated, but the regression it is fixing fails on nccopy.
#
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
. ../test_common.sh
# For a netCDF-3 build, test nccopy on netCDF files in this directory
set -e
echo ""
INFILE=${TOPSRCDIR}/ncdump/ref_nccopy3_subset.nc
OUTFILE=nccopy3_subset_out.nc
echo "*** Testing netCDF-3 nccopy -v/-V flags on $IN"
echo "*** One Dimensional Tests"
echo "*** Testing nccopy -v"
${NCCOPY} -v lat ${INFILE} ${OUTFILE}
echo "*** Testing nccopy -V"
${NCCOPY} -V lat ${INFILE} ${OUTFILE}
echo "*** Two Dimensional Tests"
echo "*** Testing nccopy -v"
${NCCOPY} -v lat_2D_rct ${INFILE} ${OUTFILE}
echo "*** Testing nccopy -V"
${NCCOPY} -V lat_2D_rct ${INFILE} ${OUTFILE}
echo "nccopy passed!"
exit 0

View File

@ -59,7 +59,6 @@ gen_ncc(const char *filename)
codeline("#include <stdio.h>");
codeline("#include <stdlib.h>");
codeline("#include <netcdf.h>");
codeline("#include <netcdf_filter.h>");
codeline("");
codeflush();

View File

@ -48,7 +48,6 @@
#include "util.h"
#include "debug.h"
#include "nc.h"
#include "netcdf_filter.h"
#ifdef USE_NETCDF4
#include "nc4internal.h"
#endif

View File

@ -498,6 +498,13 @@ main(
/* Compute the k_flag (1st pass) using rules in the man page (ncgen.1).*/
#ifndef USE_CDF5
if(k_flag == NC_FORMAT_CDF5) {
derror("Output format CDF5 requested, but netcdf was built without cdf5 support.");
return 0;
}
#endif
#ifndef USE_NETCDF4
if(enhanced_flag) {
derror("CDL input is enhanced mode, but --disable-netcdf4 was specified during build");
@ -506,7 +513,7 @@ main(
#endif
if(l_flag == L_JAVA || l_flag == L_F77) {
k_flag = 1;
k_flag = NC_FORMAT_CLASSIC;
if(enhanced_flag) {
derror("Java or Fortran requires classic model CDL input");
return 0;
@ -517,12 +524,12 @@ main(
k_flag = globalspecials._Format;
if(cdf5_flag && !enhanced_flag && k_flag == 0)
k_flag = 5;
k_flag = NC_FORMAT_64BIT_DATA;
if(enhanced_flag && k_flag == 0)
k_flag = 3;
k_flag = NC_FORMAT_NETCDF4;
if(enhanced_flag && k_flag != 3) {
if(enhanced_flag && k_flag != 3 && k_flag != 5) {
if(enhanced_flag && k_flag != NC_FORMAT_NETCDF4) {
if(enhanced_flag && k_flag != NC_FORMAT_NETCDF4 && k_flag != NC_FORMAT_64BIT_DATA) {
derror("-k or _Format conflicts with enhanced CDL input");
return 0;
}
@ -530,13 +537,13 @@ main(
if(specials_flag > 0 && k_flag == 0)
#ifdef USE_NETCDF4
k_flag = 3;
k_flag = NC_FORMAT_NETCDF4;
#else
k_flag = 1;
k_flag = NC_FORMAT_CLASSIC;
#endif
if(k_flag == 0)
k_flag = 1;
k_flag = NC_FORMAT_CLASSIC;
/* Figure out usingclassic */
switch (k_flag) {

View File

@ -1,8 +1,8 @@
#!/bin/bash
flex -Pncg -8 ncgen.l
rm -f ncgenl.c
sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
bison -pncg -t -d ncgen.y
rm -f ncgeny.c ncgeny.h
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.c >ncgeny.c
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.h >ncgeny.h
flex -Pncg -8 ncgen.l
rm -f ncgenl.c
sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
bison -pncg -t -d ncgen.y
rm -f ncgeny.c ncgeny.h
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.c >ncgeny.c
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.h >ncgeny.h

View File

@ -1410,15 +1410,19 @@ datalistextend(Datalist* dl, NCConstant* con)
dlappend(dl,con);
}
/*
Try to infer the file type from the
kinds of constructs used in the cdl file.
*/
static void
vercheck(int tid)
{
switch (tid) {
case NC_UBYTE: markcdf5("netCDF4/5 type: UBYTE"); break;
case NC_USHORT: markcdf5("netCDF4/5 type: USHORT"); break;
case NC_UINT: markcdf5("netCDF4/5 type: UINT"); break;
case NC_INT64: markcdf5("netCDF4/5 type: INT64"); break;
case NC_UINT64: markcdf5("netCDF4/5 type: UINT64"); break;
case NC_UBYTE: markcdf4("netCDF4/5 type: UBYTE"); break;
case NC_USHORT: markcdf4("netCDF4/5 type: USHORT"); break;
case NC_UINT: markcdf4("netCDF4/5 type: UINT"); break;
case NC_INT64: markcdf4("netCDF4/5 type: INT64"); break;
case NC_UINT64: markcdf4("netCDF4/5 type: UINT64"); break;
case NC_STRING: markcdf4("netCDF4 type: STRING"); break;
case NC_VLEN: markcdf4("netCDF4 type: VLEN"); break;
case NC_OPAQUE: markcdf4("netCDF4 type: OPAQUE"); break;
@ -1445,54 +1449,26 @@ Parse a filter spec string and store it in special
static int
parsefilterflag(const char* sdata0, Specialdata* special)
{
char* p;
char* sdata = NULL;
int stat;
size_t count;
unsigned int* ulist = NULL;
unsigned int* params = NULL;
size_t nparams;
unsigned int id;
if(sdata0 == NULL || strlen(sdata0) == 0) goto fail;
sdata = strdup(sdata0);
if(!NC_parsefilterspec(sdata0,&id,&nparams,*params))
goto fail;
/* Count number of unsigned integers and delimit */
p=sdata;
for(count=0;;count++) {
char* q = strchr(p,',');
if(q == NULL) break;
*q++ = '\0'; /* delimit */
p = q;
if(special) {
/* Store the id */
special->_FilterID = id;
/* And the parameter info */
special->nparams = nparams;
special->_FilterParams = params;
ulist = NULL; /* avoid duplicate free */
}
count++; /* for final piece */
/* Start by collecting the filter id */
p = sdata;
stat = sscanf(p,"%u",&special->_FilterID);
if(stat != 1) goto fail;
count--; /* actual param count minus the id */
ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count));
if(ulist == NULL) goto fail;
special->nparams = count;
for(count=0;count < special->nparams ;) {
unsigned int uval;
p = p + strlen(p) + 1; /* move to next param */
stat = sscanf(p,"%u",&uval);
if(stat != 1) goto fail;
ulist[count++] = uval;
}
special->_FilterParams = ulist;
ulist = NULL; /* avoid duplicate free */
if(sdata) free(sdata);
if(ulist) free(ulist);
return 1;
fail:
if(sdata) free(sdata);
if(ulist) free(ulist);
if(params) free(params);
if(special) special->_FilterID = 0;
derror("Malformed filter spec: %s",sdata);
return 0;
}

View File

@ -3434,15 +3434,19 @@ datalistextend(Datalist* dl, NCConstant* con)
dlappend(dl,con);
}
/*
Try to infer the file type from the
kinds of constructs used in the cdl file.
*/
static void
vercheck(int tid)
{
switch (tid) {
case NC_UBYTE: markcdf5("netCDF4/5 type: UBYTE"); break;
case NC_USHORT: markcdf5("netCDF4/5 type: USHORT"); break;
case NC_UINT: markcdf5("netCDF4/5 type: UINT"); break;
case NC_INT64: markcdf5("netCDF4/5 type: INT64"); break;
case NC_UINT64: markcdf5("netCDF4/5 type: UINT64"); break;
case NC_UBYTE: markcdf4("netCDF4/5 type: UBYTE"); break;
case NC_USHORT: markcdf4("netCDF4/5 type: USHORT"); break;
case NC_UINT: markcdf4("netCDF4/5 type: UINT"); break;
case NC_INT64: markcdf4("netCDF4/5 type: INT64"); break;
case NC_UINT64: markcdf4("netCDF4/5 type: UINT64"); break;
case NC_STRING: markcdf4("netCDF4 type: STRING"); break;
case NC_VLEN: markcdf4("netCDF4 type: VLEN"); break;
case NC_OPAQUE: markcdf4("netCDF4 type: OPAQUE"); break;

View File

@ -11,6 +11,9 @@
#undef URLCVT /* NEVER turn this on */
/* Do we %xx decode all or part of a DAP Identifer: see dapdecode() */
#define DECODE_PARTIAL
#define DAP2ENCODE
#ifdef DAP2ENCODE
#define KEEPSLASH
@ -355,8 +358,8 @@ daplexcleanup(DAPlexstate** lexstatep)
1. if the encoded character is in fact a legal DAP2 character
(alphanum+"_!~*'-\"") then it is decoded, otherwise not.
*/
#ifndef DECODE_IDENTIFIERS
static char* decodelist =
#ifdef DECODE_PARTIAL
static char* decodeset = /* Specify which characters are decoded */
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!~*'-\"";
#endif
@ -364,10 +367,10 @@ char*
dapdecode(DAPlexstate* lexstate, char* name)
{
char* decoded = NULL;
#ifdef DECODE_IDENTIFIERS
decoded = ncuridecode(name);
#ifdef DECODE_PARTIAL
decoded = ncuridecodepartial(name,decodeset); /* Decode selected */
#else
decoded = ncuridecodeonly(name,decodelist);
decoded = ncuridecode(name); /* Decode everything */
#endif
nclistpush(lexstate->reclaim,(void*)decoded);
return decoded;

View File

@ -4,6 +4,7 @@
#include "config.h"
#include <curl/curl.h>
#include "ocinternal.h"
#include "occurlfunctions.h"
#include "ocdebug.h"
static int nflags = 0;
@ -22,7 +23,10 @@ static struct OCCURLFLAG oc_curlflags[] = {
{"CURLOPT_ERRORBUFFER",CURLOPT_ERRORBUFFER,10010,CF_STRING},
{"CURLOPT_FOLLOWLOCATION",CURLOPT_FOLLOWLOCATION,52,CF_LONG},
{"CURLOPT_HTTPAUTH",CURLOPT_HTTPAUTH,1007,CF_LONG},
#ifdef HAVE_CURLOPT_KEYPASSWD
{"CURLOPT_KEYPASSWD",CURLOPT_KEYPASSWD,10026,CF_STRING},
{"CURLOPT_SSLKEYPASSWD",CURLOPT_SSLKEYPASSWD,CURLOPT_KEYPASSWD,CF_STRING},
#endif
{"CURLOPT_MAXREDIRS",CURLOPT_MAXREDIRS,68,CF_LONG},
{"CURLOPT_NETRC",CURLOPT_NETRC,51,CF_LONG},
{"CURLOPT_NETRC_FILE",CURLOPT_NETRC_FILE,10118,CF_STRING},
@ -32,7 +36,6 @@ static struct OCCURLFLAG oc_curlflags[] = {
{"CURLOPT_PROXYUSERPWD",CURLOPT_PROXYUSERPWD,10006,CF_STRING},
{"CURLOPT_SSLCERT",CURLOPT_SSLCERT,10025,CF_STRING},
{"CURLOPT_SSLKEY",CURLOPT_SSLKEY,10087,CF_STRING},
{"CURLOPT_SSLKEYPASSWD",CURLOPT_SSLKEYPASSWD,CURLOPT_KEYPASSWD,CF_STRING},
{"CURLOPT_SSL_VERIFYHOST",CURLOPT_SSL_VERIFYHOST,81,CF_LONG},
{"CURLOPT_SSL_VERIFYPEER",CURLOPT_SSL_VERIFYPEER,64,CF_LONG},
{"CURLOPT_TIMEOUT",CURLOPT_TIMEOUT,13,CF_LONG},
@ -43,205 +46,6 @@ static struct OCCURLFLAG oc_curlflags[] = {
{NULL,0}
};
#if 0
static struct OCCURLFLAG oc_allcurlflags[] = {
{"CURLOPT_ADDRESS_SCOPE",CURLOPT_ADDRESS_SCOPE,171,CF_UNKNOWN},
{"CURLOPT_APPEND",CURLOPT_APPEND,50,CF_UNKNOWN},
{"CURLOPT_AUTOREFERER",CURLOPT_AUTOREFERER,58,CF_UNKNOWN},
{"CURLOPT_BUFFERSIZE",CURLOPT_BUFFERSIZE,98,CF_UNKNOWN},
{"CURLOPT_CAINFO",CURLOPT_CAINFO,10065,CF_UNKNOWN},
{"CURLOPT_CAPATH",CURLOPT_CAPATH,10097,CF_UNKNOWN},
{"CURLOPT_CERTINFO",CURLOPT_CERTINFO,172,CF_UNKNOWN},
{"CURLOPT_CHUNK_BGN_FUNCTION",CURLOPT_CHUNK_BGN_FUNCTION,20198,CF_UNKNOWN},
{"CURLOPT_CHUNK_DATA",CURLOPT_CHUNK_DATA,10201,CF_UNKNOWN},
{"CURLOPT_CHUNK_END_FUNCTION",CURLOPT_CHUNK_END_FUNCTION,20199,CF_UNKNOWN},
{"CURLOPT_CLOSEPOLICY",CURLOPT_CLOSEPOLICY,72,CF_UNKNOWN},
{"CURLOPT_CONNECT_ONLY",CURLOPT_CONNECT_ONLY,141,CF_UNKNOWN},
{"CURLOPT_CONNECTTIMEOUT",CURLOPT_CONNECTTIMEOUT,78,CF_UNKNOWN},
{"CURLOPT_CONNECTTIMEOUT_MS",CURLOPT_CONNECTTIMEOUT_MS,156,CF_UNKNOWN},
{"CURLOPT_CONV_FROM_NETWORK_FUNCTION",CURLOPT_CONV_FROM_NETWORK_FUNCTION,20142,CF_UNKNOWN},
{"CURLOPT_CONV_FROM_UTF8_FUNCTION",CURLOPT_CONV_FROM_UTF8_FUNCTION,20144,CF_UNKNOWN},
{"CURLOPT_CONV_TO_NETWORK_FUNCTION",CURLOPT_CONV_TO_NETWORK_FUNCTION,20143,CF_UNKNOWN},
{"CURLOPT_COOKIE",CURLOPT_COOKIE,10022,CF_UNKNOWN},
{"CURLOPT_COOKIEFILE",CURLOPT_COOKIEFILE,10031,CF_UNKNOWN},
{"CURLOPT_COOKIEJAR",CURLOPT_COOKIEJAR,10082,CF_UNKNOWN},
{"CURLOPT_COOKIELIST",CURLOPT_COOKIELIST,10135,CF_UNKNOWN},
{"CURLOPT_COOKIESESSION",CURLOPT_COOKIESESSION,96,CF_UNKNOWN},
{"CURLOPT_COPYPOSTFIELDS",CURLOPT_COPYPOSTFIELDS,10165,CF_UNKNOWN},
{"CURLOPT_CRLF",CURLOPT_CRLF,27,CF_UNKNOWN},
{"CURLOPT_CRLFILE",CURLOPT_CRLFILE,10169,CF_UNKNOWN},
{"CURLOPT_CUSTOMREQUEST",CURLOPT_CUSTOMREQUEST,10036,CF_UNKNOWN},
{"CURLOPT_DEBUGDATA",CURLOPT_DEBUGDATA,10095,CF_UNKNOWN},
{"CURLOPT_DEBUGFUNCTION",CURLOPT_DEBUGFUNCTION,20094,CF_UNKNOWN},
{"CURLOPT_DIRLISTONLY",CURLOPT_DIRLISTONLY,48,CF_UNKNOWN},
{"CURLOPT_DNS_CACHE_TIMEOUT",CURLOPT_DNS_CACHE_TIMEOUT,92,CF_UNKNOWN},
{"CURLOPT_DNS_USE_GLOBAL_CACHE",CURLOPT_DNS_USE_GLOBAL_CACHE,91,CF_UNKNOWN},
{"CURLOPT_EGDSOCKET",CURLOPT_EGDSOCKET,10077,CF_UNKNOWN},
{"CURLOPT_ENCODING",CURLOPT_ENCODING,10102,CF_UNKNOWN},
{"CURLOPT_ERRORBUFFER",CURLOPT_ERRORBUFFER,10010,CF_UNKNOWN},
{"CURLOPT_FAILONERROR",CURLOPT_FAILONERROR,45,CF_UNKNOWN},
{"CURLOPT_FILE",CURLOPT_FILE,10001,CF_UNKNOWN},
{"CURLOPT_FILETIME",CURLOPT_FILETIME,69,CF_UNKNOWN},
{"CURLOPT_FNMATCH_DATA",CURLOPT_FNMATCH_DATA,10202,CF_UNKNOWN},
{"CURLOPT_FNMATCH_FUNCTION",CURLOPT_FNMATCH_FUNCTION,20200,CF_UNKNOWN},
{"CURLOPT_FOLLOWLOCATION",CURLOPT_FOLLOWLOCATION,52,CF_UNKNOWN},
{"CURLOPT_FORBID_REUSE",CURLOPT_FORBID_REUSE,75,CF_UNKNOWN},
{"CURLOPT_FRESH_CONNECT",CURLOPT_FRESH_CONNECT,74,CF_UNKNOWN},
{"CURLOPT_FTP_ACCOUNT",CURLOPT_FTP_ACCOUNT,10134,CF_UNKNOWN},
{"CURLOPT_FTP_ALTERNATIVE_TO_USER",CURLOPT_FTP_ALTERNATIVE_TO_USER,10147,CF_UNKNOWN},
{"CURLOPT_FTP_CREATE_MISSING_DIRS",CURLOPT_FTP_CREATE_MISSING_DIRS,110,CF_UNKNOWN},
{"CURLOPT_FTP_FILEMETHOD",CURLOPT_FTP_FILEMETHOD,138,CF_UNKNOWN},
{"CURLOPT_FTPPORT",CURLOPT_FTPPORT,10017,CF_UNKNOWN},
{"CURLOPT_FTP_RESPONSE_TIMEOUT",CURLOPT_FTP_RESPONSE_TIMEOUT,112,CF_UNKNOWN},
{"CURLOPT_FTP_SKIP_PASV_IP",CURLOPT_FTP_SKIP_PASV_IP,137,CF_UNKNOWN},
{"CURLOPT_FTPSSLAUTH",CURLOPT_FTPSSLAUTH,129,CF_UNKNOWN},
{"CURLOPT_FTP_SSL_CCC",CURLOPT_FTP_SSL_CCC,154,CF_UNKNOWN},
{"CURLOPT_FTP_USE_EPRT",CURLOPT_FTP_USE_EPRT,106,CF_UNKNOWN},
{"CURLOPT_FTP_USE_EPSV",CURLOPT_FTP_USE_EPSV,85,CF_UNKNOWN},
{"CURLOPT_FTP_USE_PRET",CURLOPT_FTP_USE_PRET,188,CF_UNKNOWN},
{"CURLOPT_GSSAPI_DELEGATION",CURLOPT_GSSAPI_DELEGATION,210,CF_UNKNOWN},
{"CURLOPT_HEADER",CURLOPT_HEADER,42,CF_UNKNOWN},
{"CURLOPT_HEADERFUNCTION",CURLOPT_HEADERFUNCTION,20079,CF_UNKNOWN},
{"CURLOPT_HTTP200ALIASES",CURLOPT_HTTP200ALIASES,10104,CF_UNKNOWN},
{"CURLOPT_HTTPAUTH",CURLOPT_HTTPAUTH,107,CF_UNKNOWN},
{"CURLOPT_HTTP_CONTENT_DECODING",CURLOPT_HTTP_CONTENT_DECODING,158,CF_UNKNOWN},
{"CURLOPT_HTTPGET",CURLOPT_HTTPGET,80,CF_UNKNOWN},
{"CURLOPT_HTTPHEADER",CURLOPT_HTTPHEADER,10023,CF_UNKNOWN},
{"CURLOPT_HTTPPOST",CURLOPT_HTTPPOST,10024,CF_UNKNOWN},
{"CURLOPT_HTTPPROXYTUNNEL",CURLOPT_HTTPPROXYTUNNEL,61,CF_UNKNOWN},
{"CURLOPT_HTTP_TRANSFER_DECODING",CURLOPT_HTTP_TRANSFER_DECODING,157,CF_UNKNOWN},
{"CURLOPT_HTTP_VERSION",CURLOPT_HTTP_VERSION,84,CF_UNKNOWN},
{"CURLOPT_IGNORE_CONTENT_LENGTH",CURLOPT_IGNORE_CONTENT_LENGTH,136,CF_UNKNOWN},
{"CURLOPT_INFILE",CURLOPT_INFILE,10009,CF_UNKNOWN},
{"CURLOPT_INFILESIZE",CURLOPT_INFILESIZE,14,CF_UNKNOWN},
{"CURLOPT_INFILESIZE_LARGE",CURLOPT_INFILESIZE_LARGE,30115,CF_UNKNOWN},
{"CURLOPT_INTERFACE",CURLOPT_INTERFACE,10062,CF_UNKNOWN},
{"CURLOPT_INTERLEAVEDATA",CURLOPT_INTERLEAVEDATA,10195,CF_UNKNOWN},
{"CURLOPT_INTERLEAVEFUNCTION",CURLOPT_INTERLEAVEFUNCTION,20196,CF_UNKNOWN},
{"CURLOPT_IOCTLDATA",CURLOPT_IOCTLDATA,10131,CF_UNKNOWN},
{"CURLOPT_IOCTLFUNCTION",CURLOPT_IOCTLFUNCTION,20130,CF_UNKNOWN},
{"CURLOPT_IPRESOLVE",CURLOPT_IPRESOLVE,113,CF_UNKNOWN},
{"CURLOPT_ISSUERCERT",CURLOPT_ISSUERCERT,10170,CF_UNKNOWN},
{"CURLOPT_KEYPASSWD",CURLOPT_KEYPASSWD,10026,CF_UNKNOWN},
{"CURLOPT_KRBLEVEL",CURLOPT_KRBLEVEL,10063,CF_UNKNOWN},
{"CURLOPT_LOCALPORT",CURLOPT_LOCALPORT,139,CF_UNKNOWN},
{"CURLOPT_LOCALPORTRANGE",CURLOPT_LOCALPORTRANGE,140,CF_UNKNOWN},
{"CURLOPT_LOW_SPEED_LIMIT",CURLOPT_LOW_SPEED_LIMIT,19,CF_UNKNOWN},
{"CURLOPT_LOW_SPEED_TIME",CURLOPT_LOW_SPEED_TIME,20,CF_UNKNOWN},
{"CURLOPT_MAIL_FROM",CURLOPT_MAIL_FROM,10186,CF_UNKNOWN},
{"CURLOPT_MAIL_RCPT",CURLOPT_MAIL_RCPT,10187,CF_UNKNOWN},
{"CURLOPT_MAXCONNECTS",CURLOPT_MAXCONNECTS,71,CF_UNKNOWN},
{"CURLOPT_MAXFILESIZE",CURLOPT_MAXFILESIZE,114,CF_UNKNOWN},
{"CURLOPT_MAXFILESIZE_LARGE",CURLOPT_MAXFILESIZE_LARGE,30117,CF_UNKNOWN},
{"CURLOPT_MAX_RECV_SPEED_LARGE",CURLOPT_MAX_RECV_SPEED_LARGE,30146,CF_UNKNOWN},
{"CURLOPT_MAXREDIRS",CURLOPT_MAXREDIRS,68,CF_UNKNOWN},
{"CURLOPT_MAX_SEND_SPEED_LARGE",CURLOPT_MAX_SEND_SPEED_LARGE,30145,CF_UNKNOWN},
{"CURLOPT_NETRC",CURLOPT_NETRC,51,CF_UNKNOWN},
{"CURLOPT_NETRC_FILE",CURLOPT_NETRC_FILE,10118,CF_UNKNOWN},
{"CURLOPT_NEW_DIRECTORY_PERMS",CURLOPT_NEW_DIRECTORY_PERMS,160,CF_UNKNOWN},
{"CURLOPT_NEW_FILE_PERMS",CURLOPT_NEW_FILE_PERMS,159,CF_UNKNOWN},
{"CURLOPT_NOBODY",CURLOPT_NOBODY,44,CF_UNKNOWN},
{"CURLOPT_NOPROGRESS",CURLOPT_NOPROGRESS,43,CF_UNKNOWN},
{"CURLOPT_NOPROXY",CURLOPT_NOPROXY,10177,CF_UNKNOWN},
{"CURLOPT_NOSIGNAL",CURLOPT_NOSIGNAL,99,CF_UNKNOWN},
{"CURLOPT_OPENSOCKETDATA",CURLOPT_OPENSOCKETDATA,10164,CF_UNKNOWN},
{"CURLOPT_OPENSOCKETFUNCTION",CURLOPT_OPENSOCKETFUNCTION,20163,CF_UNKNOWN},
{"CURLOPT_PASSWORD",CURLOPT_PASSWORD,10174,CF_UNKNOWN},
{"CURLOPT_PORT",CURLOPT_PORT,3,CF_UNKNOWN},
{"CURLOPT_POST",CURLOPT_POST,47,CF_UNKNOWN},
{"CURLOPT_POSTFIELDS",CURLOPT_POSTFIELDS,10015,CF_UNKNOWN},
{"CURLOPT_POSTFIELDSIZE",CURLOPT_POSTFIELDSIZE,60,CF_UNKNOWN},
{"CURLOPT_POSTFIELDSIZE_LARGE",CURLOPT_POSTFIELDSIZE_LARGE,30120,CF_UNKNOWN},
{"CURLOPT_POSTQUOTE",CURLOPT_POSTQUOTE,10039,CF_UNKNOWN},
{"CURLOPT_POSTREDIR",CURLOPT_POSTREDIR,161,CF_UNKNOWN},
{"CURLOPT_PREQUOTE",CURLOPT_PREQUOTE,10093,CF_UNKNOWN},
{"CURLOPT_PRIVATE",CURLOPT_PRIVATE,10103,CF_UNKNOWN},
{"CURLOPT_PROGRESSDATA",CURLOPT_PROGRESSDATA,10057,CF_UNKNOWN},
{"CURLOPT_PROGRESSFUNCTION",CURLOPT_PROGRESSFUNCTION,20056,CF_UNKNOWN},
{"CURLOPT_PROTOCOLS",CURLOPT_PROTOCOLS,181,CF_UNKNOWN},
{"CURLOPT_PROXY",CURLOPT_PROXY,10004,CF_UNKNOWN},
{"CURLOPT_PROXYAUTH",CURLOPT_PROXYAUTH,111,CF_UNKNOWN},
{"CURLOPT_PROXYPASSWORD",CURLOPT_PROXYPASSWORD,10176,CF_UNKNOWN},
{"CURLOPT_PROXYPORT",CURLOPT_PROXYPORT,59,CF_UNKNOWN},
{"CURLOPT_PROXY_TRANSFER_MODE",CURLOPT_PROXY_TRANSFER_MODE,166,CF_UNKNOWN},
{"CURLOPT_PROXYTYPE",CURLOPT_PROXYTYPE,101,CF_UNKNOWN},
{"CURLOPT_PROXYUSERNAME",CURLOPT_PROXYUSERNAME,10175,CF_UNKNOWN},
{"CURLOPT_PROXYUSERPWD",CURLOPT_PROXYUSERPWD,10006,CF_UNKNOWN},
{"CURLOPT_PUT",CURLOPT_PUT,54,CF_UNKNOWN},
{"CURLOPT_QUOTE",CURLOPT_QUOTE,10028,CF_UNKNOWN},
{"CURLOPT_RANDOM_FILE",CURLOPT_RANDOM_FILE,10076,CF_UNKNOWN},
{"CURLOPT_RANGE",CURLOPT_RANGE,10007,CF_UNKNOWN},
{"CURLOPT_READFUNCTION",CURLOPT_READFUNCTION,20012,CF_UNKNOWN},
{"CURLOPT_REDIR_PROTOCOLS",CURLOPT_REDIR_PROTOCOLS,182,CF_UNKNOWN},
{"CURLOPT_REFERER",CURLOPT_REFERER,10016,CF_UNKNOWN},
{"CURLOPT_RESUME_FROM",CURLOPT_RESUME_FROM,21,CF_UNKNOWN},
{"CURLOPT_RESUME_FROM_LARGE",CURLOPT_RESUME_FROM_LARGE,30116,CF_UNKNOWN},
{"CURLOPT_RTSP_CLIENT_CSEQ",CURLOPT_RTSP_CLIENT_CSEQ,193,CF_UNKNOWN},
{"CURLOPT_RTSP_REQUEST",CURLOPT_RTSP_REQUEST,189,CF_UNKNOWN},
{"CURLOPT_RTSP_SERVER_CSEQ",CURLOPT_RTSP_SERVER_CSEQ,194,CF_UNKNOWN},
{"CURLOPT_RTSP_SESSION_ID",CURLOPT_RTSP_SESSION_ID,10190,CF_UNKNOWN},
{"CURLOPT_RTSP_STREAM_URI",CURLOPT_RTSP_STREAM_URI,10191,CF_UNKNOWN},
{"CURLOPT_RTSP_TRANSPORT",CURLOPT_RTSP_TRANSPORT,10192,CF_UNKNOWN},
{"CURLOPT_SEEKDATA",CURLOPT_SEEKDATA,10168,CF_UNKNOWN},
{"CURLOPT_SEEKFUNCTION",CURLOPT_SEEKFUNCTION,20167,CF_UNKNOWN},
{"CURLOPT_SHARE",CURLOPT_SHARE,10100,CF_UNKNOWN},
{"CURLOPT_SOCKOPTDATA",CURLOPT_SOCKOPTDATA,10149,CF_UNKNOWN},
{"CURLOPT_SOCKOPTFUNCTION",CURLOPT_SOCKOPTFUNCTION,20148,CF_UNKNOWN},
{"CURLOPT_SOCKS5_GSSAPI_NEC",CURLOPT_SOCKS5_GSSAPI_NEC,180,CF_UNKNOWN},
{"CURLOPT_SOCKS5_GSSAPI_SERVICE",CURLOPT_SOCKS5_GSSAPI_SERVICE,10179,CF_UNKNOWN},
{"CURLOPT_SSH_AUTH_TYPES",CURLOPT_SSH_AUTH_TYPES,151,CF_UNKNOWN},
{"CURLOPT_SSH_HOST_PUBLIC_KEY_MD5",CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,10162,CF_UNKNOWN},
{"CURLOPT_SSH_KEYDATA",CURLOPT_SSH_KEYDATA,10185,CF_UNKNOWN},
{"CURLOPT_SSH_KEYFUNCTION",CURLOPT_SSH_KEYFUNCTION,20184,CF_UNKNOWN},
{"CURLOPT_SSH_KNOWNHOSTS",CURLOPT_SSH_KNOWNHOSTS,10183,CF_UNKNOWN},
{"CURLOPT_SSH_PRIVATE_KEYFILE",CURLOPT_SSH_PRIVATE_KEYFILE,10153,CF_UNKNOWN},
{"CURLOPT_SSH_PUBLIC_KEYFILE",CURLOPT_SSH_PUBLIC_KEYFILE,10152,CF_UNKNOWN},
{"CURLOPT_SSLCERT",CURLOPT_SSLCERT,10025,CF_UNKNOWN},
{"CURLOPT_SSLCERTTYPE",CURLOPT_SSLCERTTYPE,10086,CF_UNKNOWN},
{"CURLOPT_SSL_CIPHER_LIST",CURLOPT_SSL_CIPHER_LIST,10083,CF_UNKNOWN},
{"CURLOPT_SSL_CTX_DATA",CURLOPT_SSL_CTX_DATA,10109,CF_UNKNOWN},
{"CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,20108,CF_UNKNOWN},
{"CURLOPT_SSLENGINE",CURLOPT_SSLENGINE,10089,CF_UNKNOWN},
{"CURLOPT_SSLENGINE_DEFAULT",CURLOPT_SSLENGINE_DEFAULT,90,CF_UNKNOWN},
{"CURLOPT_SSLKEY",CURLOPT_SSLKEY,10087,CF_UNKNOWN},
{"CURLOPT_SSLKEYTYPE",CURLOPT_SSLKEYTYPE,10088,CF_UNKNOWN},
{"CURLOPT_SSL_SESSIONID_CACHE",CURLOPT_SSL_SESSIONID_CACHE,150,CF_UNKNOWN},
{"CURLOPT_SSL_VERIFYHOST",CURLOPT_SSL_VERIFYHOST,81,CF_UNKNOWN},
{"CURLOPT_SSL_VERIFYPEER",CURLOPT_SSL_VERIFYPEER,64,CF_UNKNOWN},
{"CURLOPT_SSLVERSION",CURLOPT_SSLVERSION,32,CF_UNKNOWN},
{"CURLOPT_STDERR",CURLOPT_STDERR,10037,CF_UNKNOWN},
{"CURLOPT_TCP_NODELAY",CURLOPT_TCP_NODELAY,121,CF_UNKNOWN},
{"CURLOPT_TELNETOPTIONS",CURLOPT_TELNETOPTIONS,10070,CF_UNKNOWN},
{"CURLOPT_TFTP_BLKSIZE",CURLOPT_TFTP_BLKSIZE,178,CF_UNKNOWN},
{"CURLOPT_TIMECONDITION",CURLOPT_TIMECONDITION,33,CF_UNKNOWN},
{"CURLOPT_TIMEOUT",CURLOPT_TIMEOUT,13,CF_UNKNOWN},
{"CURLOPT_TIMEOUT_MS",CURLOPT_TIMEOUT_MS,155,CF_UNKNOWN},
{"CURLOPT_TIMEVALUE",CURLOPT_TIMEVALUE,34,CF_UNKNOWN},
{"CURLOPT_TRANSFERTEXT",CURLOPT_TRANSFERTEXT,53,CF_UNKNOWN},
{"CURLOPT_UNRESTRICTED_AUTH",CURLOPT_UNRESTRICTED_AUTH,105,CF_UNKNOWN},
{"CURLOPT_UPLOAD",CURLOPT_UPLOAD,46,CF_UNKNOWN},
{"CURLOPT_URL",CURLOPT_URL,10002,CF_UNKNOWN},
{"CURLOPT_USERAGENT",CURLOPT_USERAGENT,10018,CF_UNKNOWN},
{"CURLOPT_USERNAME",CURLOPT_USERNAME,10173,CF_UNKNOWN},
{"CURLOPT_USERPWD",CURLOPT_USERPWD,10005,CF_UNKNOWN},
{"CURLOPT_USE_SSL",CURLOPT_USE_SSL,119,CF_UNKNOWN},
{"CURLOPT_VERBOSE",CURLOPT_VERBOSE,41,CF_UNKNOWN},
{"CURLOPT_WILDCARDMATCH",CURLOPT_WILDCARDMATCH,197,CF_UNKNOWN},
{"CURLOPT_WRITEFUNCTION",CURLOPT_WRITEFUNCTION,20011,CF_UNKNOWN},
{"CURLOPT_WRITEHEADER",CURLOPT_WRITEHEADER,10029,CF_UNKNOWN},
{"CURLOPT_WRITEINFO",CURLOPT_WRITEINFO,10040,CF_UNKNOWN},
{NULL,0}
};
struct OCCURLFLAG*
occurlflagsall(void)
{
if(nflags == 0) initialize();
return oc_allcurlflags;
}
#endif
static int touppercase(int c)
{
if(c >= 'a' && c <= 'z')

View File

@ -11,12 +11,6 @@
/* Mnemonic */
#define OPTARG void*
/* Condition on libcurl version */
/* Set up an alias as needed */
#ifndef HAVE_CURLOPT_KEYPASSWD
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
#endif
#define NETRCFILETAG "HTTP.NETRC"
#define CHECK(state,flag,value) {if(check(state,flag,(void*)value) != OC_NOERR) {goto done;}}
@ -94,9 +88,10 @@ ocset_curlflag(OCstate* state, int flag)
switch (flag) {
case CURLOPT_USERPWD:
if(state->creds.userpwd != NULL) {
CHECK(state, CURLOPT_USERPWD, state->creds.userpwd);
case CURLOPT_USERPWD: /* Does both user and pwd */
if(state->creds.user != NULL && state->creds.pwd != NULL) {
CHECK(state, CURLOPT_USERNAME, state->creds.user);
CHECK(state, CURLOPT_PASSWORD, state->creds.pwd);
CHECK(state, CURLOPT_HTTPAUTH, (OPTARG)CURLAUTH_ANY);
}
break;
@ -155,8 +150,9 @@ ocset_curlflag(OCstate* state, int flag)
if(state->proxy.host != NULL) {
CHECK(state, CURLOPT_PROXY, state->proxy.host);
CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->proxy.port);
if(state->proxy.userpwd) {
CHECK(state, CURLOPT_PROXYUSERPWD, state->proxy.userpwd);
if(state->proxy.user != NULL && state->proxy.pwd != NULL) {
CHECK(state, CURLOPT_PROXYUSERNAME, state->proxy.user);
CHECK(state, CURLOPT_PROXYPASSWORD, state->proxy.pwd);
#ifdef CURLOPT_PROXYAUTH
CHECK(state, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
#endif
@ -340,6 +336,7 @@ oc_curl_protocols(struct OCGLOBALSTATE* state)
}
#if 0
/*
"Inverse" of ocset_curlflag;
Given a flag and value, it updates state.
@ -352,9 +349,14 @@ ocset_curlstate(OCstate* state, int flag, void* value)
switch (flag) {
case CURLOPT_USERPWD:
if(state->creds.userpwd != NULL) free(state->creds.userpwd);
state->creds.userpwd = strdup((char*)value);
case CURLOPT_USERNAME:
if(state->creds.user != NULL) free(state->creds.user);
state->creds.user = strdup((char*)value);
break;
case CURLOPT_PASSWORD:
if(state->creds.pwd != NULL) free(state->creds.pwd);
state->creds.pwd = strdup((char*)value);
break;
case CURLOPT_COOKIEJAR: case CURLOPT_COOKIEFILE:
@ -443,3 +445,4 @@ ocset_curlstate(OCstate* state, int flag, void* value)
done:
return stat;
}
#endif

View File

@ -9,6 +9,15 @@
#define _CURLFUNCTION_H_
/* Condition on libcurl version */
/* Set up an alias as needed */
#ifndef HAVE_CURLOPT_KEYPASSWD
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
#endif
#ifndef HAVE_CURLINFO_RESPONSE_CODE
#define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
#endif
extern OCerror ocset_curlopt(OCstate* state, int flag, void* value);
struct OCCURLFLAG* occurlflagbyflag(int flag);
@ -18,7 +27,6 @@ extern OCerror ocset_flags_perfetch(OCstate*);
extern OCerror ocset_flags_perlink(OCstate*);
extern OCerror ocset_curlflag(OCstate*,int);
extern OCerror ocset_curlstate(OCstate* state, int flag, void* value);
extern void oc_curl_debug(OCstate* state);

View File

@ -23,11 +23,7 @@ ocfetchhttpcode(CURL* curl)
long httpcode = 200;
CURLcode cstat = CURLE_OK;
/* Extract the http code */
#ifdef HAVE_CURLINFO_RESPONSE_CODE
cstat = CURLERR(curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpcode));
#else
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CODE,&httpcode);
#endif
if(cstat != CURLE_OK) httpcode = 0;
return httpcode;
}

View File

@ -427,8 +427,10 @@ occlose(OCstate* state)
ocfree(state->ssl.cainfo);
ocfree(state->ssl.capath);
ocfree(state->proxy.host);
ocfree(state->proxy.userpwd);
ocfree(state->creds.userpwd);
ocfree(state->proxy.user);
ocfree(state->proxy.pwd);
ocfree(state->creds.user);
ocfree(state->creds.pwd);
if(state->curl != NULL) occurlclose(state->curl);
ocfree(state);
}
@ -606,7 +608,6 @@ ocset_curlproperties(OCstate* state)
if(path == NULL) return OC_ENOMEM;
occopycat(path,len,3,ocglobalstate.tempdir,"/","occookies");
stat = ocmktmp(path,&name);
fprintf(stderr,"%s => %s\n",state->uri->uri,name); fflush(stderr);
free(path);
state->curlflags.cookiejar = name;
state->curlflags.createdflags |= COOKIECREATED;

View File

@ -217,10 +217,12 @@ struct OCstate {
struct OCproxy {
char *host; /*CURLOPT_PROXY*/
int port; /*CURLOPT_PROXYPORT*/
char* userpwd; /*CURLOPT_PROXYUSERPWD*/
char* user; /*CURLOPT_PROXYUSERNAME*/
char* pwd; /*CURLOPT_PROXYPASSWORD*/
} proxy;
struct OCcredentials {
char *userpwd; /*CURLOPT_USERPWD*/
char *user; /*CURLOPT_USERNAME*/
char *pwd; /*CURLOPT_PASSWORD*/
} creds;
void* usercurldata;
long ddslastmodified;

View File

@ -26,7 +26,6 @@ static OCerror rc_search(const char* prefix, const char* rcfile, char** pathp);
static int rcreadline(FILE* f, char* more, int morelen);
static void rctrim(char* text);
static char* combinecredentials(const char* user, const char* pwd);
static void storedump(char* msg, struct OCTriple*, int ntriples);
@ -48,17 +47,49 @@ occredentials_in_url(const char *url)
return 0;
}
/*
Given form user:pwd, parse into user and pwd
and do %xx unescaping
*/
static OCerror
ocextract_credentials(const char *url, char **userpwd, char **result_url)
parsecredentials(const char* userpwd, char** userp, char** pwdp)
{
char* user = NULL;
char* pwd = NULL;
if(userpwd == NULL)
return OC_EINVAL;
user = strdup(userpwd);
if(user == NULL)
return NC_ENOMEM;
pwd = strchr(user,':');
if(pwd == NULL)
return OC_EINVAL;
*pwd = '\0';
pwd++;
if(userp)
*userp = ncuridecode(user);
if(pwdp)
*pwdp = ncuridecode(pwd);
free(user);
return OC_NOERR;
}
static OCerror
ocextract_credentials(const char *url, char **user, char** pwd, char **result_url)
{
NCURI* parsed = NULL;
if(ncuriparse(url,&parsed) != NCU_OK)
if(url == NULL || ncuriparse(url,&parsed) != NCU_OK)
return OCTHROW(OC_EBADURL);
if(parsed->user != NULL || parsed->password == NULL) {
ncurifree(parsed);
return OCTHROW(OC_EBADURL);
}
if(userpwd) *userpwd = combinecredentials(parsed->user,parsed->password);
if(user)
*user = parsed->user;
if(pwd)
*pwd = parsed->password;
ncurifree(parsed);
return OC_NOERR;
}
@ -85,24 +116,40 @@ occombinehostport(const NCURI* uri)
return hp;
}
#if 0
/*
Combine user and pwd into the user:pwd form.
Note that we must %xx escape the user and the pwd
*/
static char*
combinecredentials(const char* user, const char* pwd)
{
int userPassSize;
char *userPassword;
char *escapeduser = NULL;
char* escapedpwd = NULL;
if(user == NULL) user = "";
if(pwd == NULL) pwd = "";
userPassSize = strlen(user) + strlen(pwd) + 2;
if(user == NULL || pwd == NULL)
return NULL;
userPassSize = 3*strlen(user) + 3*strlen(pwd) + 2; /* times 3 for escapes */
userPassword = malloc(sizeof(char) * userPassSize);
if (!userPassword) {
nclog(NCLOGERR,"Out of Memory\n");
return NULL;
}
occopycat(userPassword,userPassSize-1,3,user,":",pwd);
escapeduser = ncuriencodeuserpwd(user);
escapedpwd = ncuriencodeuserpwd(pwd);
if(escapeduser == NULL || escapedpwd == NULL) {
nclog(NCLOGERR,"Out of Memory\n");
return NULL;
}
occopycat(userPassword,userPassSize-1,3,escapeduser,":",escapedpwd);
free(escapeduser);
free(escapedpwd);
return userPassword;
}
#endif
static int
rcreadline(FILE* f, char* more, int morelen)
@ -158,7 +205,7 @@ ocparseproxy(OCstate* state, char* v)
return OC_NOERR; /* nothing there*/
if (occredentials_in_url(v)) {
char *result_url = NULL;
ocextract_credentials(v, &state->proxy.userpwd, &result_url);
ocextract_credentials(v, &state->proxy.user, &state->proxy.pwd, &result_url);
v = result_url;
}
/* allocating a bit more than likely needed ... */
@ -208,7 +255,7 @@ ocparseproxy(OCstate* state, char* v)
if (ocdebug > 1) {
nclog(NCLOGNOTE,"host name: %s", state->proxy.host);
#ifdef INSECURE
nclog(NCLOGNOTE,"user+pwd: %s", state->proxy.userpwd);
nclog(NCLOGNOTE,"user+pwd: %s+%s", state->proxy.user,state->proxy.pwd);
#endif
nclog(NCLOGNOTE,"port number: %d", state->proxy.port);
}
@ -373,8 +420,8 @@ ocrc_load(void)
/* locate the configuration files in the following order:
1. specified by set_rcfile
2. set by DAPRCFILE env variable
3. '.'
4. $HOME
3. '.'/<rcfile>
4. $HOME/<rcfile>
*/
if(ocglobalstate.rc.rcfile != NULL) { /* always use this */
path = strdup(ocglobalstate.rc.rcfile);
@ -416,7 +463,6 @@ ocrc_process(OCstate* state)
OCerror stat = OC_NOERR;
char* value = NULL;
NCURI* uri = state->uri;
char* url_userpwd = NULL;
char* url_hostport = NULL;
if(!ocglobalstate.initialized)
@ -428,7 +474,6 @@ ocrc_process(OCstate* state)
to getinfo e.g. user:pwd from url
*/
url_userpwd = combinecredentials(uri->user,uri->password);
url_hostport = occombinehostport(uri);
if(url_hostport == NULL)
return OC_ENOMEM;
@ -545,21 +590,28 @@ ocrc_process(OCstate* state)
{ /* Handle various cases for user + password */
/* First, see if the user+pwd was in the original url */
char* userpwd = NULL;
char* user = NULL;
char* pwd = NULL;
if(url_userpwd != NULL)
userpwd = url_userpwd;
else {
if(uri->user != NULL && uri->password != NULL) {
user = uri->user;
pwd = uri->password;
} else {
user = ocrc_lookup("HTTP.CREDENTIALS.USER",url_hostport);
pwd = ocrc_lookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
userpwd = ocrc_lookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
}
if(userpwd == NULL && user != NULL && pwd != NULL) {
userpwd = combinecredentials(user,pwd);
state->creds.userpwd = userpwd;
} else if(userpwd != NULL)
state->creds.userpwd = strdup(userpwd);
if(user != NULL && pwd != NULL) {
state->creds.user = strdup(user);
state->creds.pwd = strdup(pwd);
} else {
/* Could not get user and pwd, so try USERPASSWORD */
const char* userpwd = ocrc_lookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
if(userpwd != NULL) {
stat = parsecredentials(userpwd,&user,&pwd);
if(stat) goto done;
state->creds.user = user;
state->creds.pwd = pwd;
}
}
}
done:
@ -624,7 +676,7 @@ storedump(char* msg, struct OCTriple* triples, int ntriples)
if(ntriples < 0 ) ntriples= ocrc->ntriples;
for(i=0;i<ntriples;i++) {
fprintf(stderr,"\t%s\t%s\t%s\n",
(strlen(triples[i].host)==0?"--":triples[i].host),
(triples[i].host == NULL || strlen(triples[i].host)==0?"--":triples[i].host),
triples[i].key,
triples[i].value);
}