|
Neonは、
オープンソースで開発・公開されているC言語用のWebDAVクライアント・ライブラリです。
WebDAVによる通信といっても基本から応用まで幅広いのですが、
「FTPの延長じゃないの?」というような基本的な通信だけできればいい、
要するにWebDAVを汎用ネットワーク型ファイルシステムだとか、
インターネット次世代プロトコルだとか、
そのよーな大げさなことは言わないで、
単なるデータ通信ツールとして使いたい、という向きにはぴったりのライブラリです。
●Neonインストール
Neonのソース配布は上記サイトからダウンロードできます。
Neonをコンパイルするには、XML関連のライブラリlibXML2またはexpatが必要です。
またlibXML2は多言語対応にGNUのエンコーディング変換ライブラリiconvを内部的に使うので、
日本語圏ではiconvも必要となる機会が多いでしょう。
まとめると、Neonを使うにはlibXML2とiconvが必要になるということです。(-_-)
これらのライブラリについては、他のページで紹介しています。
NeonのソースはUNIX、Windows-Cygwin環境では、
おなじみの「configure→make→make install」でコンパイルできます。
ここでは次の環境で試した結果をまとめています。
OS | コンパイラ | Neonのバージョン |
Red Hat Linux 7.3 | gcc 2.96 | 0.24.0 |
MS-Windows XP Home Edition | gcc 2.95.3-5(cygwin) | 0.21.3 |
MS-Windows XP Home Edition | MinGW 2.0 | 0.24.7 |
●MinGWの場合
Windows環境に移植されたgccコンパイラのMinGWでは、
configureやmakeの実行前に少し工夫が必要です。
まず、環境変数の設定をします。
$ export CFLAGS="-Dssize_t=size_t -Dvsnprintf=_vsnprintf -Dsnprintf=_snprintf →
-I/usr/local/include -I/usr/local/include/libxml2"
$ export CPPFLAGS="$CFLAGS"
$ export LDFLAGS=-L/usr/local/lib
$ export LIBS=-lwsock32
|
この他に、configureを実行していると
「socket」「gethostbyname」のライブラリがリンクできない、というエラーで落ちるので、
これらの場合にエラーで落とす処理部分をconfigureスクリプトから削っておく必要があります。
次に、「ne_utils.h」を編集して、次の部分の「#ifndef」の行と「#endif」の行を削ります。
/*#ifndef WIN32*/
#undef min
#define min(a,b) ((a)<(b)?(a):(b))
/*#endif*/
|
そしてconfigure→make→make installです。
$ sh configure
$ make
$ make install
|
●サンプルプログラム
Neonのダウンロードページでは、ソースアーカイブの他、
「neon-example-***.tar.gz」というサンプルプログラムのアーカイブも配布されています。
簡単なものですが、超基本はこれで習得できると思います。
以下のサンプルプログラムはバージョン0.24.5で試したものです。
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <ne_session.h>
#include <ne_socket.h>
#include <ne_uri.h>
#include <ne_basic.h>
#include <ne_utils.h>
int main(int argc, char* argv[]){
ne_session *sess;
ne_uri uri = {0};
int ret;
if (argc < 2) {
printf("Usage: nget URL.\n");return -1;
}
if(ne_uri_parse(argv[1], &uri)
|| uri.host == NULL || uri.path == NULL) {
printf("Could not parse URL `%s'.\n", argv[1]);
return -1;
}
/* Set defaults. */
if (uri.scheme == NULL) uri.scheme = "http";
if (uri.port == 0) uri.port = ne_uri_defaultport(uri.scheme);
/* Initialize socket libraries */
if (ne_sock_init()) {
printf("nget: Failed to initialize socket libraries.\n");
return -1;
}
/* Create session. */
sess = ne_session_create(uri.scheme, uri.host, uri.port);
/* Load default CAs if using SSL. */
#if 0
if(strcasecmp(uri.scheme, "https") == 0)
if (ne_ssl_load_default_ca(sess))
fprintf(stderr, "Failed to load default CAs.\n");
#endif
/* Dispatch a GET request, sending the response body to stdout. */
ret = ne_get(sess, uri.path, fileno(stdout));
if (ret != NE_OK) {
fprintf(stderr, "nget: Failed: %s\n", ne_get_error(sess));
}
ne_session_destroy(sess);
return ret;
}
|
/*#include "config.h" */
#include <unistd.h>
#include <string.h>
#include <ne_session.h>
#include <ne_socket.h>
#include <ne_uri.h>
#include <ne_basic.h>
#include <ne_utils.h>
int main(int argc, char* argv[]){
ne_session *sess;
ne_uri uri = {0};
char* filename;
if (argc < 3) {
printf("Usage: nput URLas filename.\n");return -1;
}
if(ne_uri_parse(argv[1], &uri)
|| uri.host == NULL || uri.path == NULL) {
printf("Could not parse URL `%s'.\n", argv[1]);
return -1;
}
filename = argv[2];
/* Set defaults. */
if (uri.scheme == NULL) uri.scheme = "http";
if (uri.port == 0) uri.port = ne_uri_defaultport(uri.scheme);
/* Initialize socket libraries */
if (ne_sock_init()) {
printf("nput: Failed to initialize socket libraries.\n");
return -1;
}
/* Create session. */
sess = ne_session_create(uri.scheme, uri.host, uri.port);
/* Load default CAs if using SSL. */
#if 0
if(strcasecmp(uri.scheme, "https") == 0)
if (ne_ssl_load_default_ca(sess))
fprintf(stderr, "Failed to load default CAs.\n");
#endif
{
FILE* fin;
int ret;
if((fin = fopen(filename, "rb")) == NULL){
fprintf(stderr, "Cannot open a local file %s\n", filename);
ne_session_destroy(sess);
return -1;
}
ret = ne_put(sess, uri.path, fileno(fin));
if (ret != NE_OK) {
fprintf(stderr, "nput: Failed: %s\n", ne_get_error(sess));
}
fclose(fin);
ne_session_destroy(sess);
return ret;
}
}
|
CC = gcc
CFLAGS = -Wall -I/usr/local/include/neon
LDFLAGS = -L/usr/local/lib
LIBS = -lneon -lxml2 -liconv -lz -lwsock32 -lm
.c.o:
$(CC) $(CFLAGS) -c $<
all: nget.exe nput.exe
nget.exe: nget.o
$(CC) -o $@ $(LDFLAGS) nget.o $(LIBS)
nput.exe: nput.o
$(CC) -o $@ $(LDFLAGS) nput.o $(LIBS)
# end.
|
なお、これを拡張して、Tcl/Tkから呼び出せるインターフェースを作ったものが、
Tcl/Tk Scripting Laboratory
の
なもなも
にあるので、興味のある方は見て頂ればと思います。
(first uploaded 2002/08/15 last updated 2004/09/12, URANO398)
|