mdn_nameinit
)
mdn_encodename
)
mdn_decodename
)
mdn_enable
)
多言語ドメイン名の処理は次の2つの処理から構成されます。
mDNkit では、これに加えて地域化のために
の2つの処理を追加しています。
多言語ドメイン処理のアーキテクチャ
IDNA
では、これらの処理はすべてアプリケーションで行うことになっており、
例えば名前解決用の関数 gethostbyname
を呼び出して
多言語ドメイン名の名前解決を行う場合には、
すでにこれらの処理が行われた結果の文字列を渡すことになっています。
mDNkit はアプリケーションでこれらの処理を行うために 2種類の API を用意しています。
低レベル API は特殊なアプリケーションのために用意された API ですので、
ここでは説明しません。もし低レベル API を使用したい場合には、
MDN ライブラリ仕様書の
resconf
モジュール
および
res
モジュール
をご覧ください。
高レベル API は次の3つの関数から構成されます。
mdn_nameinit
mdn_encodename
mdn_decodename
以下、それぞれの関数の説明をします。
MDN ライブラリ仕様書の
api
モジュール
も合わせてご覧ください。
多言語ドメイン名の処理のための初期化を行うためには
mdn_nameinit
を用います。
mdn_result_t mdn_nameinit(void)
この関数は MDN ライブラリ全体の初期化を行い、次に 多言語ドメイン名の処理のための各種の設定が記述されている 設定ファイル (mdn.conf) を読み込みます。
この関数は戻り値として実行結果を示す
mdn_result_t
型の値を返します。
本関数が返すコードとその意味は次の通りです。
mdn_success
mdn_nofile
mdn_invalid_syntax
mdn_invalid_name
mdn_nomemory
この関数を複数回呼び出すこともできますが、その場合 MDN ライブラリ全体の初期化が行われるのは最初の呼び出しの時だけで、 2回目以降は設定ファイルの再読み込みのみが行われます。 アプリケーションの実行中に設定ファイルの内容を変更した場合、 この関数を呼び出すことで最新の設定に合わせることができます。
この関数をあらかじめ呼び出さずにエンコードやデコード関数を 呼び出しても構いません。その場合には、エンコードやデコードの処理に先だち この関数で行われるような初期化の処理が暗黙的に行われます。
多言語ドメイン名のエンコード処理、つまり名前解決関数などへ渡すための
文字列に変換するには mdn_encodename
を用います。
mdn_result_t mdn_encodename(int actions, const char *from, char *to, size_t tolen)
from で指定されるドメイン名に対して、actions で 指定される処理を行い、その結果を to の指す領域に書き込みます。 tolen は to の指す領域の大きさ (バイト数) で、 tolen を越えて書き込むことはありません。
この関数による多言語ドメイン名のエンコード処理は一般的には 次のような手順になります。
引数 actions で、これらのどの処理を実際に実行するかを以下に示す フラグで指定します。 実際に actions に指定するのはこれらのビット毎の論理和です。
MDN_LOCALCONV
MDN_DELIMMAP
MDN_LOCALMAP
MDN_NAMEPREP
MDN_UNASCHECK
MDN_IDNCONV
通常のアプリケーションは MDN_UNASCHECK
を除くすべての処理を
行えばよいはずです。そのために MDN_ENCODE_APP
というマクロが
定義されており、actions にこの値を指定すれば
未割り当てコードポイントの検出を除くすべての処理が行われます。
なお、上記の各処理でのパラメータはすべて mDNkit の 設定ファイル (mdn.conf) で設定されたものが使用されます。以下に使用されるパラメータを記します。
この関数は戻り値として実行結果を示す
mdn_result_t
型の値を返します。
本関数が返すコードとその意味は次の通りです。
mdn_success
mdn_invalid_action
mdn_invalid_encoding
mdn_prohibited
MDN_UNASCHECK
を指定した場合には
未割り当てコードポイントが存在した場合にもこのコードを返す。
mdn_buffer_overflow
mdn_nomemory
なお、初期化関数 mdn_nameinit
を事前に呼び出さずに
本関数を呼び出した場合には、変換処理に先だって初期化が行われます。
この場合には本関数は上に示した他に次のような実行結果を返すことがあります。
mdn_nofile
mdn_invalid_syntax
mdn_invalid_name
なお、 環境変数 MDN_DISABLE が設定されている場合は、この関数を使用しても 文字列の変換は行われず、元の文字列のままの結果が返されます。 MDN_DISABLE が設定されている環境で文字列の変換を強制的に行う方法は、 環境変数 MDN_DISABLE のオーバーライド に書かれています。
多言語ドメイン名のデコード処理、つまり名前解決関数などから返された
エンコード済のドメイン名文字列を、アプリケーションが使用している
エンコーディングの文字列に変換するには mdn_decodename
を用います。
mdn_result_t mdn_decodename(int actions, const char *from, char *to, size_t tolen)
from で指定されるドメイン名に対して、actions で 指定される処理を行い、その結果を to の指す領域に書き込みます。 tolen は to の指す領域の大きさ (バイト数) で、 tolen を越えて書き込むことはありません。
この関数による多言語ドメイン名のデコード処理は一般的には 次のような手順になります。
引数 actions で、これらのどの処理を実際に実行するかを以下に示す フラグで指定します。 実際に actions に指定するのはこれらのビット毎の論理和です。
MDN_IDNCONV
MDN_NAMEPREP
MDN_UNASCHECK
MDN_LOCALCONV
通常のアプリケーションは MDN_UNASCHECK
を除くすべての処理を
行えばよいはずです。そのために MDN_DECODE_APP
というマクロが
定義されており、actions にこの値を指定すれば
未割り当てコードポイントの検出を除くすべての処理が行われます。
なお、上記の各処理でのパラメータはすべて mDNkit の 設定ファイル (mdn.conf) で設定されたものが使用されます。以下に使用されるパラメータを記します。
この関数は戻り値として実行結果を示す
mdn_result_t
型の値を返します。
本関数が返すコードとその意味は次の通りです。
mdn_success
mdn_invalid_action
mdn_invalid_encoding
mdn_buffer_overflow
mdn_nomemory
なお、初期化関数 mdn_nameinit
を事前に呼び出さずに
本関数を呼び出した場合には、変換処理に先だって初期化が行われます。
この場合には本関数は上に示した他に次のような実行結果を返すことがあります。
mdn_nofile
mdn_invalid_syntax
mdn_invalid_name
なお、 環境変数 MDN_DISABLE が設定されている場合は、この関数を使用しても 文字列の変換は行われず、元の文字列のままの結果が返されます。 MDN_DISABLE が設定されている環境で文字列の変換を強制的に行う方法は、 環境変数 MDN_DISABLE のオーバーライド に書かれています。
通常の場合、
環境変数 MDN_DISABLE
が設定されている環境でドメイン名を変換
するための API を使用しても変換処理は実行されず、元の文字列のまま結果が
返されます。ただし、この設定を明示的にオーバーライドするための API とし
て、mdn_enable
が用意されています。
void mdn_enable(int on_off)
環境変数 MDN_DISABLE が設定されているかどうかにかかわらず、 on_off が 0 の場合、これ以降のドメイン名変換は行われません。 また、on_off が 0 以外の値であれば、この関数の呼び出し以降は MDN_DISABLE 環境変数が設定されているかどうかにかかわらず、ドメイン名変換 処理が行われます。
上記の API を使用したプログラムを作る方法、および注意点などについて まとめておきます。
stddef.h
と
mdn/api.h
の2つのヘッダファイルをインクルードしてください。
#include <stddef.h> #include <mdn/api.h>
MDN_LOCAL_CODESET
から
取得します。ロケール情報から取得する場合にはアプリケーションの先頭で
setlocale
を行い、アプリケーションのロケールを正しく
設定してください。
mdn_result_t
型の値を返します。この値から
対応するメッセージ文字列を得るための関数 mdn_result_tostring
が用意されています。エラーメッセージを表示する際に使うことができます。
この関数については
仕様書の説明をご覧ください。
-I
オプションで mDNkit の
ヘッダファイルのインストールディレクトリ (デフォルトでは
/usr/local/include
) を指定してください。cc -I/usr/local/include example.c -L/usr/local/lib -lmdn -liconv
ここでは、上記の API を使用して多言語ドメイン名の名前解決を行うための 簡単なプログラムを紹介します。
#include <stdio.h> #include <stddef.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <mdn/api.h> int main(int ac, char **av) { struct hostent *hp; char buf1[256]; char buf2[256]; char addrbuf[100]; mdn_result_t r; /* ロケールを設定する */ setlocale(LC_ALL, ""); if (ac != 2) { fprintf(stderr, "Usage: %s hostname\n", av[0]); return 1; } /* gethostbyname を呼ぶ前に名前を変換する */ if ((r = mdn_encodename(MDN_ENCODE_APP, av[1], buf1, sizeof(buf1))) != mdn_success) { fprintf(stderr, "mdn_encodename: %s\n", mdn_result_tostring(r)); return 1; } /* 名前解決を行う */ if ((hp = gethostbyname(buf1)) == NULL) { fprintf(stderr, "gethostbyname failed\n"); return 1; } /* 返された名前をローカルエンコーディングに変換する */ if ((r = mdn_decodename(MDN_DECODE_APP, hp->h_name, buf2, sizeof(buf2))) != mdn_success) { fprintf(stderr, "mdn_decodename: %s\n", mdn_result_tostring(r)); return 1; } printf("%s %s\n", inet_ntop(hp->h_addrtype, hp->h_addr, addrbuf, sizeof(addrbuf)), buf2); return 0; }