DeliciousFS を作ってみる - curl で早速こける

MacFUSE を使ってみる」でちろっと書きましたが、C++ で del.icio.us をマウントできるモジュールを作ってみようっつうことで、FUSE のページにある FUSE tutorialHello World を読んでみました。

何となくわかったような感じもするので、まずはマウントしたら del.icio.us のタグがディレクトリに見えるくらいのところを目指して実装開始。

del.icio.us の API 呼ぶところは libcurl を使おうと思い、サンプル見ながらやってやってみました。以下 test.cc。

C++:
  1. #include <curl/curl.h>
  2. #include <curl/easy.h>
  3. #include <cstdlib>
  4. #include <cerrno>
  5. #include <iostream>
  6. #include <fstream>
  7.  
  8. using namespace std;
  9.  
  10. struct memchunk {
  11.     char* memory;
  12.     size_t size;
  13. };
  14.  
  15. void* myrealloc(void* ptr, size_t size) {
  16.     if (ptr) {
  17.         return realloc(ptr, size);
  18.     } else {
  19.         return malloc(size);
  20.     }
  21. }
  22.  
  23. size_t writeMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data) {
  24.     size_t realsize = size * nmemb;
  25.     struct memchunk* mem = (struct memchunk*)data;
  26.     mem->memory = static_cast<char*>(myrealloc(mem->memory, mem->size + realsize + 1));
  27.     if (mem->memory) {
  28.         memcpy(&(mem->memory[mem->size]), ptr, realsize);
  29.         mem->size += realsize;
  30.         mem->memory[mem->size] = 0;
  31.     }
  32.     return realsize;
  33. }
  34.  
  35. int main(int argc, char* argv[]) {
  36.     CURL* curl = curl_easy_init();
  37.     if (curl == NULL) {
  38.         exit(1);
  39.     }
  40.     // URL を設定
  41.     CURLcode code = curl_easy_setopt(curl, CURLOPT_URL, "https://api.del.icio.us/v1/tags/get");
  42.     if (code != CURLE_OK) {
  43.         exit(1);
  44.     }
  45.     //
  46.     code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeMemoryCallback);
  47.     if (code != CURLE_OK) {
  48.         exit(1);
  49.     }
  50.     // データの書き込み先を設定
  51.     struct memchunk chunk;
  52.     memset(&chunk, 0, sizeof(memchunk));
  53.     code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(&chunk));
  54.     if (code != CURLE_OK) {
  55.         exit(1);
  56.     }
  57.     // ユーザ名、パスワードを設定
  58.     curl_easy_setopt(curl, CURLOPT_USERPWD, "YOUR_ID:YOUR_PASSWORD");
  59. // *1   char* error[256] = {0,};
  60. // *1  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error);
  61.     // 実行
  62.     code = curl_easy_perform(curl);
  63. // *1    cerr <<(char*)error <<endl;
  64.     if (code != CURLE_OK) {
  65.         exit(1);
  66.     }
  67.     // 取得した内容を表示
  68.     if (chunk.memory) {
  69.         cout <<chunk.memory <<endl;
  70.     }
  71.     // 後始末
  72.     curl_easy_cleanup(curl);
  73.     if (chunk.memory) {
  74.         free(chunk.memory);
  75.     }
  76.  
  77.     return 0;
  78. }

こんな感じ。取得内容の保存先とそれを扱うコールバック関数、del.icio.us のユーザ名とパスワード(YOUR_ID:YOUR_PASSWOD 部分)を指定しています。ああ、もっとさくっとした言語で書きたい。。

で、とにかくビルドして実行。

CODE:
  1. [ihara@barcelona.local:~/work] $ g++ -L/opt/local/lib -lcurl test.cc -o test
  2. [ihara@barcelona.local:~/work] $ ./test

しても何も出えへんやん。なので *1 部分を追加してエラーメッセージ出させてみると、

CODE:
  1. [ihara@barcelona.local:~/work] $ ./test
  2. libcurl was built with SSL disabled, https: not supported!

ですって。アガ。MacPorts の variants に ssl のオプションがあるんだろうなあって感じで見てみるとあったので再インストール。

CODE:
  1. [ihara@barcelona.local:~/work] $ port variants curl
  2. curl has the variants:
  3.         universal
  4.         darwin_6
  5.         darwin_8
  6.         ssl
  7.         ipv6
  8.         ares
  9.         idn
  10.         spnego
  11.         gnutls
  12.         gss
  13.         openldap
  14.         doc
  15. [ihara@barcelona.local:~/work] $ sudo port uninstall --archive curl
  16. [ihara@barcelona.local:~/work] $ sudo port install -dv curl +ssl

で test プログラム再実行すると、

CODE:
  1. <?xml version='1.0' standalone='yes'?>
  2. <tags>
  3.   <tag count="1" tag="37signals" />
  4.   <tag count="1" tag="aa" />
  5.   <tag count="1" tag="adobe" />
  6.   <tag count="1" tag="adsense" />
  7.   ...
  8.   <tag count="17" tag="後で読む" />
  9.   <tag count="2" tag="鍋" />
  10. </tags>

と無事タグの一覧を取得することがでけました。MacPorts の curl のデフォルトでは ssl はサポートされてないっつう話でした。

さて、これでとりあえずタグの一覧取れているので、次はエラー処理とかきちんとして、これらがディレクトリとして見えるように DeliciousFS の実装をしてみようと思います。

しかし手間かかりますね。XML のパースもどうしようかなあって感じです。やっぱし PHP とか楽。勉強兼ねて Ruby にしよかな。。


About this entry