[pgsql-jp: 39336] Re: 端末の名称

Ryo HAYAKAWA ryo @ fastriver.net
2008年 4月 2日 (水) 10:12:56 JST


早川と申します。

From: zen-pgsql @ suzuki.que.ne.jp
Subject: [pgsql-jp: 39334] Re: 端末の名称
Date: Wed, 02 Apr 2008 00:13:51 +0900 (JST)
Message-ID: <20080402.001351.98893685.inetd @ x.inetd.co.jp>

> 1. DHCPサーバ(もしくはクライアント)とDNSサーバを連携
>     --> DNSのDynamic Update機能を利用してDNSサーバにDHCPクライアント
>         を登録する

DHCP で配布する範囲のアドレスを、あらかじめ静的に DNS に登録していると
ころもあると思います。

生島さんの質問に戻りますが、逆引きで良いのでしたら、getnameinfo() あた
りを使うような PostgreSQL のユーザ定義関数を自作すれば良いと思います。

で、例として、私自身のユーザ定義関数の勉強も兼ねてちょっと作ってみまし
た。ただし、RHEL5 + PostgreSQL 8.1.4 でしか試してません。セキュリティ
的な対策もエラー処理も何も考えずに作っていますので、そのあたりご容赦く
ださい。
# メモリリークもあやしいかも…

引数は、ドット付 10 進表記の IP アドレス(TEXT 型)を一つ取るようにして
います。
# inet_client_addr() を使うのであれば
# split_part(inet_client_addr()::text, '/', 1) として取得できるもので
# す。

------------------------- きりとり -------------------------
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"

PG_FUNCTION_INFO_V1(get_host_name);

Datum get_host_name(PG_FUNCTION_ARGS){

    text *text_ipaddr = PG_GETARG_TEXT_P(0);
    char* ipaddr = NULL, buf[NI_MAXHOST] = "";
    struct addrinfo *aires = NULL;

    ipaddr = DatumGetCString(DirectFunctionCall1(textout,
                             PointerGetDatum(text_ipaddr)));

    if(getaddrinfo(ipaddr, NULL, NULL, &aires) != 0){
        if(aires) freeaddrinfo(aires);
        if(ipaddr) pfree(ipaddr);
        PG_RETURN_TEXT_P(text_ipaddr);
    }

    if(ipaddr) pfree(ipaddr);

    if(getnameinfo((struct sockaddr*)aires->ai_addr, aires->ai_addrlen,
                   buf, sizeof(buf), NULL, 0, 0) != 0){
        if(aires) freeaddrinfo(aires);
        PG_RETURN_TEXT_P(text_ipaddr);
    }

    if(aires) freeaddrinfo(aires);
    if(text_ipaddr) pfree(text_ipaddr);

    PG_RETURN_TEXT_P(DirectFunctionCall1(textin, CStringGetDatum(buf)));

}
------------------------- きりとり -------------------------

これを共有ライブラリとしてコンパイルして create function で定義すれば 
SQL の中で使えると思います。

私の環境だと以下でコンパイル出来ます。

  gcc -I/usr/include/pgsql/server -shared get_host_name.c -o get_host_name.so

ご参考までに create function 文は以下です。

  create or replace function get_host_name(TEXT)
  returns TEXT
  as '/path/to/get_host_name.so','get_host_name'
  language 'C'

-- はやかわ



pgsql-jp メーリングリストの案内