WebDAVクライアントライブラリNeon

 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.3gcc 2.960.24.0
MS-Windows XP Home Editiongcc 2.95.3-5(cygwin)0.21.3
MS-Windows XP Home EditionMinGW 2.00.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なもなも にあるので、興味のある方は見て頂ればと思います。

Open Source Web Architecture Top

(first uploaded 2002/08/15 last updated 2004/09/12, URANO398)

Gポイントポイ活 Amazon Yahoo 楽天

無料ホームページ 楽天モバイル[UNLIMITが今なら1円] 海外格安航空券 海外旅行保険が無料!