MilterClientContext

MilterClientContext — milterプロトコルを処理します。

概要

#define             MILTER_CLIENT_CONTEXT_ERROR
enum                MilterClientContextError;
enum                MilterClientContextState;
                    MilterClientContext;
GQuark              milter_client_context_error_quark   (void);
MilterClientContext* milter_client_context_new          (void);
gboolean            milter_client_context_feed          (MilterClientContext *context,
                                                         const gchar *chunk,
                                                         gsize size,
                                                         GError **error);
gpointer            milter_client_context_get_private_data
                                                        (MilterClientContext *context);
void                milter_client_context_set_private_data
                                                        (MilterClientContext *context,
                                                         gpointer data,
                                                         GDestroyNotify destroy);
gboolean            milter_client_context_set_reply     (MilterClientContext *context,
                                                         guint code,
                                                         const gchar *extended_code,
                                                         const gchar *message,
                                                         GError **error);
gchar*              milter_client_context_format_reply  (MilterClientContext *context);
gboolean            milter_client_context_add_header    (MilterClientContext *context,
                                                         const gchar *name,
                                                         const gchar *value,
                                                         GError **error);
gboolean            milter_client_context_insert_header (MilterClientContext *context,
                                                         guint32 index,
                                                         const gchar *name,
                                                         const gchar *value,
                                                         GError **error);
gboolean            milter_client_context_change_header (MilterClientContext *context,
                                                         const gchar *name,
                                                         guint32 index,
                                                         const gchar *value);
gboolean            milter_client_context_delete_header (MilterClientContext *context,
                                                         const gchar *name,
                                                         guint32 index);
gboolean            milter_client_context_change_from   (MilterClientContext *context,
                                                         const gchar *from,
                                                         const gchar *parameters);
gboolean            milter_client_context_add_recipient (MilterClientContext *context,
                                                         const gchar *recipient,
                                                         const gchar *parameters);
gboolean            milter_client_context_delete_recipient
                                                        (MilterClientContext *context,
                                                         const gchar *recipient);
gboolean            milter_client_context_replace_body  (MilterClientContext *context,
                                                         const gchar *body,
                                                         gsize body_size);
gboolean            milter_client_context_progress      (MilterClientContext *context);
gboolean            milter_client_context_quarantine    (MilterClientContext *context,
                                                         const gchar *reason);
void                milter_client_context_set_timeout   (MilterClientContext *context,
                                                         guint timeout);
guint               milter_client_context_get_timeout   (MilterClientContext *context);
void                milter_client_context_set_state     (MilterClientContext *context,
                                                         MilterClientContextState state);
MilterClientContextState milter_client_context_get_state
                                                        (MilterClientContext *context);
void                milter_client_context_set_option    (MilterClientContext *context,
                                                         MilterOption *option);
MilterOption*       milter_client_context_get_option    (MilterClientContext *context);

説明

MilterClientContextは1つのmilterプロトコルセッションを処理します。これはMilterClientContextインスタンスは各milterプロトコルセッション毎に生成されるということです。

各milterプロトコルコマンドを処理するために、MilterClientContextのシグナルに接続します。MilterClientContextにはmilterプロトコルのイベントに対応したシグナルがあります。

以下はシグナルに接続する例です。すべてのシグナルに接続して、各シグナルハンドラはイベント名を表示します。

static MilterStatus
cb_negotiate (MilterClientContext *context, MilterOption *option,
              gpointer user_data)
{
    g_print("negotiate\n");
    return MILTER_STATUS_ALL_OPTIONS;
}

static MilterStatus
cb_connect (MilterClientContext *context, const gchar *host_name,
            const struct sockaddr *address, socklen_t address_length,
            gpointer user_data)
{
    g_print("connect\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_helo (MilterClientContext *context, const gchar *fqdn, gpointer user_data)
{
    g_print("helo\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_envelope_from (MilterClientContext *context, const gchar *from,
                  gpointer user_data)
{
    g_print("envelope-from\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_envelope_recipient (MilterClientContext *context, const gchar *to,
                       gpointer user_data)
{
    g_print("envelope-recipient\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_data (MilterClientContext *context, gpointer user_data)
{
    g_print("data\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_header (MilterClientContext *context, const gchar *name, const gchar *value,
           gpointer user_data)
{
    g_print("header\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_end_of_header (MilterClientContext *context, gpointer user_data)
{
    g_print("end-of-header\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_body (MilterClientContext *context, const gchar *chunk, gsize length,
         gpointer user_data)
{
    g_print("body\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_end_of_message (MilterClientContext *context, gpointer user_data)
{
    g_print("end-of-message\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_abort (MilterClientContext *context, gpointer user_data)
{
    g_print("abort\n");
    return MILTER_STATUS_CONTINUE;
}

static MilterStatus
cb_unknown (MilterClientContext *context, const gchar *command,
            gpointer user_data)
{
    g_print("unknown\n");
    return MILTER_STATUS_CONTINUE;
}

static void
setup_context_signals (MilterClientContext *context)
{
#define CONNECT(name)                                                   \
    g_signal_connect(context, name, G_CALLBACK(cb_ ## name), NULL)

    CONNECT(negotiate);
    CONNECT(connect);
    CONNECT(helo);
    CONNECT(envelope_from);
    CONNECT(envelope_recipient);
    CONNECT(data);
    CONNECT(header);
    CONNECT(end_of_header);
    CONNECT(body);
    CONNECT(end_of_message);
    CONNECT(abort);
    CONNECT(unknown);

#undef CONNECT
}

詳細

MILTER_CLIENT_CONTEXT_ERROR

#define MILTER_CLIENT_CONTEXT_ERROR           (milter_client_context_error_quark())

MilterClientContextのエラー用のGErrorクォークを取得するために使われます。


enum MilterClientContextError

typedef enum
{
    MILTER_CLIENT_CONTEXT_ERROR_INVALID_CODE,
    MILTER_CLIENT_CONTEXT_ERROR_IO_ERROR,
    MILTER_CLIENT_CONTEXT_ERROR_NULL,
    MILTER_CLIENT_CONTEXT_ERROR_INVALID_STATE,
    MILTER_CLIENT_CONTEXT_ERROR_INVALID_ACTION
} MilterClientContextError;

MilterClientContextの関数呼び出し中に発生するエラーを識別します。

MILTER_CLIENT_CONTEXT_ERROR_INVALID_CODE

milter_client_context_set_reply()で指定されたステータスコードが不正であることを示します。

MILTER_CLIENT_CONTEXT_ERROR_IO_ERROR

milterプロトコルデータの読み書き時に発生した入出力エラーを示します。

MILTER_CLIENT_CONTEXT_ERROR_NULL

予期しない場所でNULLが渡されたことを示します。

MILTER_CLIENT_CONTEXT_ERROR_INVALID_STATE

現在のMilterClientContextStateで予期しない操作が要求されたことを示します。

MILTER_CLIENT_CONTEXT_ERROR_INVALID_ACTION

コンテキストのMilterActionFlagsで予期しない操作が要求されたことを示します。

enum MilterClientContextState

typedef enum
{
    MILTER_CLIENT_CONTEXT_STATE_INVALID,
    MILTER_CLIENT_CONTEXT_STATE_START,
    MILTER_CLIENT_CONTEXT_STATE_NEGOTIATE,
    MILTER_CLIENT_CONTEXT_STATE_NEGOTIATE_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_CONNECT,
    MILTER_CLIENT_CONTEXT_STATE_CONNECT_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_HELO,
    MILTER_CLIENT_CONTEXT_STATE_HELO_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_FROM,
    MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_FROM_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_RECIPIENT,
    MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_RECIPIENT_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_DATA,
    MILTER_CLIENT_CONTEXT_STATE_DATA_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_UNKNOWN,
    MILTER_CLIENT_CONTEXT_STATE_UNKNOWN_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_HEADER,
    MILTER_CLIENT_CONTEXT_STATE_HEADER_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_END_OF_HEADER,
    MILTER_CLIENT_CONTEXT_STATE_END_OF_HEADER_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_BODY,
    MILTER_CLIENT_CONTEXT_STATE_BODY_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_END_OF_MESSAGE,
    MILTER_CLIENT_CONTEXT_STATE_END_OF_MESSAGE_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_QUIT,
    MILTER_CLIENT_CONTEXT_STATE_QUIT_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_ABORT,
    MILTER_CLIENT_CONTEXT_STATE_ABORT_REPLIED,
    MILTER_CLIENT_CONTEXT_STATE_FINISHED
} MilterClientContextState;

MilterClientContextの状態を識別します。

MILTER_CLIENT_CONTEXT_STATE_INVALID

不正な状態。

MILTER_CLIENT_CONTEXT_STATE_START

はじまったばかり。

MILTER_CLIENT_CONTEXT_STATE_NEGOTIATE

ネゴシエーションを開始。

MILTER_CLIENT_CONTEXT_STATE_NEGOTIATE_REPLIED

ネゴシエーション応答を受信した

MILTER_CLIENT_CONTEXT_STATE_CONNECT

接続情報を送信しました。

MILTER_CLIENT_CONTEXT_STATE_CONNECT_REPLIED

接続情報への応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_HELO

HELOコマンドの開始。

MILTER_CLIENT_CONTEXT_STATE_HELO_REPLIED

HELOコマンドへの応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_FROM

MAIL FROMコマンド開始。

MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_FROM_REPLIED

MAIL FROMコマンドへの応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_RECIPIENT

RCPT TOコマンドの開始。

MILTER_CLIENT_CONTEXT_STATE_ENVELOPE_RECIPIENT_REPLIED

RCPT TOコマンドへの応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_DATA

DATAコマンドの開始。

MILTER_CLIENT_CONTEXT_STATE_DATA_REPLIED

DATAコマンドへの応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_UNKNOWN

未知のSMTPコマンドの受信。

MILTER_CLIENT_CONTEXT_STATE_UNKNOWN_REPLIED

未知のSMTPコマンドへの応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_HEADER

ヘッダを送信した。

MILTER_CLIENT_CONTEXT_STATE_HEADER_REPLIED

ヘッダへの応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_END_OF_HEADER

すべてのヘッダを送信した。

MILTER_CLIENT_CONTEXT_STATE_END_OF_HEADER_REPLIED

ヘッダ終了への応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_BODY

本体のかたまりの送信。

MILTER_CLIENT_CONTEXT_STATE_BODY_REPLIED

本体への応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_END_OF_MESSAGE

すべての本文を送信した。

MILTER_CLIENT_CONTEXT_STATE_END_OF_MESSAGE_REPLIED

メッセージ終了への応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_QUIT

正常終了の開始。

MILTER_CLIENT_CONTEXT_STATE_QUIT_REPLIED

正常終了への応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_ABORT

異常終了の開始。

MILTER_CLIENT_CONTEXT_STATE_ABORT_REPLIED

異常終了への応答を受信した。

MILTER_CLIENT_CONTEXT_STATE_FINISHED

終了した。

MilterClientContext

typedef struct {
    MilterProtocolAgent object;
} MilterClientContext;


milter_client_context_error_quark ()

GQuark              milter_client_context_error_quark   (void);

返値 :


milter_client_context_new ()

MilterClientContext* milter_client_context_new          (void);

新しいコンテキストオブジェクトの生成。通常は、コンテキストオブジェクトはMilterClientが生成し、"connection-established"シグナルで渡されます。

返値 :

新しいMilterClientContextオブジェクト。

milter_client_context_feed ()

gboolean            milter_client_context_feed          (MilterClientContext *context,
                                                         const gchar *chunk,
                                                         gsize size,
                                                         GError **error);

contextに入力を与えます。テストやデバッグに使えます。

context :

MilterClientContext

chunk :

contextへの入力。

size :

chunkのサイズ。

error :

エラーを受け取る場所のアドレス、またはNULL

返値 :

成功時はTRUE

milter_client_context_get_private_data ()

gpointer            milter_client_context_get_private_data
                                                        (MilterClientContext *context);

contextのプライベートなデータ。

context :

MilterClientContext

返値 :

milter_client_context_set_private_data()で設定したプライベートなデータ、あるいはNULL

milter_client_context_set_private_data ()

void                milter_client_context_set_private_data
                                                        (MilterClientContext *context,
                                                         gpointer data,
                                                         GDestroyNotify destroy);

contextのプライベートなデータを設定します。datadestroyで破棄されます。dataが破棄されるのは、新しいプライベートなデータが設定されたときか、contextが破棄されたときです。

context :

MilterClientContext

data :

プライベートなデータ。

destroy :

dataの破棄関数、あるいはNULL

milter_client_context_set_reply ()

gboolean            milter_client_context_set_reply     (MilterClientContext *context,
                                                         guint code,
                                                         const gchar *extended_code,
                                                         const gchar *message,
                                                         GError **error);

エラー応答コードを設定します。MILTER_REPLY_TEMPORARY_FAILUREのときは4xx codeを使います。MILTER_REPLY_REJECTのときは5xx codeを使います。

milter.orgの smfi_setreplyも見てください。

context :

MilterClientContext

code :

3桁のSMTPエラー応答コード。(RFC 2821)4xxと5xxだけが使えます。

extended_code :

拡張応答コード(RFC 1893/2034)、あるいはNULL

message :

SMTP応答のテキスト部分またはNULL

error :

エラーを受け取る場所のアドレス、またはNULL

返値 :

成功時はTRUE

milter_client_context_format_reply ()

gchar*              milter_client_context_format_reply  (MilterClientContext *context);

milter_client_context_set_reply()で指定された現在のエラー応答コードを整形します。エラー応答コードが設定されていない場合は、NULLを返します。

context :

MilterClientContext

返値 :

整形された応答コード、あるいはNULL

milter_client_context_add_header ()

gboolean            milter_client_context_add_header    (MilterClientContext *context,
                                                         const gchar *name,
                                                         const gchar *value,
                                                         GError **error);

現在のメッセージのヘッダリストにヘッダを追加します。この関数は"end-of-message"シグナルの中で呼ぶことができます。

milter.orgの smfi_addheaderも見てください。

FIXME: MILTER_ACTION_ADD_HEADERSについて書くこと。

context :

MilterClientContext

name :

ヘッダ名。

value :

ヘッダ値。

error :

エラーを受け取る場所のアドレス、またはNULL

返値 :

成功時はTRUE

milter_client_context_insert_header ()

gboolean            milter_client_context_insert_header (MilterClientContext *context,
                                                         guint32 index,
                                                         const gchar *name,
                                                         const gchar *value,
                                                         GError **error);

現在のメッセージのヘッダリストのindexにヘッダを追加します。"end-of-message"シグナルの中で呼ぶことができます。milter.orgの smfi_insheaderも見てください。

FIXME: MILTER_ACTION_ADD_HEADERSについて書くこと。

context :

MilterClientContext

index :

挿入する位置。

name :

ヘッダ名。

value :

ヘッダ値。

error :

エラーを受け取る場所のアドレス、またはNULL

返値 :

成功時はTRUE

milter_client_context_change_header ()

gboolean            milter_client_context_change_header (MilterClientContext *context,
                                                         const gchar *name,
                                                         guint32 index,
                                                         const gchar *value);

名前がnameのヘッダのうち、indexのヘッダを変更します。valueNULLならヘッダは削除されます。"end-of-message"シグナルの中で呼ぶことができます。

milter.orgの smfi_chgheaderも見てください。

FIXME: MILTER_ACTION_CHANGE_HEADERSについて書くこと。

context :

MilterClientContext

name :

ヘッダ名。

index :

名前がnameのヘッダの位置。(1ベース)FIXME: 0ベースに変更する?

value :

ヘッダ値。ターゲットのヘッダを削除する場合はNULLを指定してください。

返値 :

成功時はTRUE

milter_client_context_delete_header ()

gboolean            milter_client_context_delete_header (MilterClientContext *context,
                                                         const gchar *name,
                                                         guint32 index);

名前がnameのヘッダのうち、indexのヘッダを削除します。"end-of-message"シグナルの中で呼ぶことができます。milter_client_context_change_header()valueNULLで呼んだときと同じ動作です。

FIXME: MILTER_ACTION_CHANGE_HEADERSについて書くこと。

context :

MilterClientContext

name :

ヘッダ名。

index :

名前がnameのヘッダの位置。(1ベース)FIXME: 0ベースに変更する?

返値 :

成功時はTRUE

milter_client_context_change_from ()

gboolean            milter_client_context_change_from   (MilterClientContext *context,
                                                         const gchar *from,
                                                         const gchar *parameters);

現在のメッセージの送信ドレスを変更します。parametersでESMTPの'MAIL FROM'コマンドのパラメタを設定できます。parametersNULLでもかまいません。"end-of-message"シグナルの中で呼ぶことができます。milter.orgのsmfi_chgfromも見てください。

FIXME: MILTER_ACTION_CHANGE_FROMについて書くこと。

context :

MilterClientContext

from :

新しい送信アドレス。

parameters :

ESMTPの'MAIL FROM'パラメタ。NULLも可。

返値 :

成功時はTRUE

milter_client_context_add_recipient ()

gboolean            milter_client_context_add_recipient (MilterClientContext *context,
                                                         const gchar *recipient,
                                                         const gchar *parameters);

現在のメッセージに宛先アドレスを追加します。parametersでESMTPの'RCPT TO'パラメタを設定することができます。parametersNULLでもかまいません。"end-of-message"シグナルの中で呼ぶことができます。milter.orgのsmfi_addrcptsmfi_addrcpt_parも見てください。

FIXME: MILTER_ACTION_ADD_RECIPIENTとMILTER_ACTION_ADD_ENVELOPE_RECIPIENT_WITH_PARAMETERSについて書くこと。

context :

MilterClientContext

recipient :

新しい宛先アドレス。

parameters :

ESMTPの'RCPT TO'パラメタ。NULLも可。

返値 :

成功時はTRUE

milter_client_context_delete_recipient ()

gboolean            milter_client_context_delete_recipient
                                                        (MilterClientContext *context,
                                                         const gchar *recipient);

名前がrecipientの宛先を削除します。"end-of-message"シグナルの中で呼ぶことができます。milter.orgのsmfi_delrcpt も見てください。

FIXME: MILTER_ACTION_DELETE_RECIPIENTについて書くこと。

context :

MilterClientContext

recipient :

削除する宛先アドレス。

返値 :

成功時はTRUE

milter_client_context_replace_body ()

gboolean            milter_client_context_replace_body  (MilterClientContext *context,
                                                         const gchar *body,
                                                         gsize body_size);

現在のメッセージの本文をbodyで置き換えます。"end-of-message"シグナルの中で呼ぶことができます。milter.orgのsmfi_replacebody も見てください。

FIXME: MILTER_ACTION_CHANGE_BODYについて書くこと。

context :

MilterClientContext

body :

新しい本文。

body_size :

bodyのサイズ。

返値 :

成功時はTRUE

milter_client_context_progress ()

gboolean            milter_client_context_progress      (MilterClientContext *context);

このmilterはまだ処理中であることをMTAに通知します。"end-of-message"シグナルの中で呼ぶことができます。milter.orgのsmfi_progress も見てください。

context :

MilterClientContext

返値 :

成功時はTRUE

milter_client_context_quarantine ()

gboolean            milter_client_context_quarantine    (MilterClientContext *context,
                                                         const gchar *reason);

現在のメッセージを理由reasonで隔離します。"end-of-message"シグナルの中で呼ぶことができます。milter.orgのsmfi_quarantine も見てください。

FIXME: MILTER_ACTION_QUARANTINEについて書くこと。

context :

MilterClientContext

reason :

どうして現在のメッセージが隔離されるかの理由。

返値 :

成功時はTRUE

milter_client_context_set_timeout ()

void                milter_client_context_set_timeout   (MilterClientContext *context,
                                                         guint timeout);

秒単位でタイムアウトを設定します。MTAがtimeout秒以内に応答しない場合は、"timeout"シグナルが発行されます。milter.orgのsmfi_settimeout も見てください。

context :

MilterClientContext

timeout :

秒単位のタイムアウト。(既定値は7210秒)

milter_client_context_get_timeout ()

guint               milter_client_context_get_timeout   (MilterClientContext *context);

秒単位でタイムアウトを取得します。

context :

MilterClientContext

返値 :

秒単位でのタイムアウト。

milter_client_context_set_state ()

void                milter_client_context_set_state     (MilterClientContext *context,
                                                         MilterClientContextState state);

現在の状態を設定します。

context :

MilterClientContext

state :

MilterClientContextState

milter_client_context_get_state ()

MilterClientContextState milter_client_context_get_state
                                                        (MilterClientContext *context);

現在の状態を取得します。

context :

MilterClientContext

返値 :

現在の状態。

milter_client_context_set_option ()

void                milter_client_context_set_option    (MilterClientContext *context,
                                                         MilterOption *option);

現在のコンテキストのオプションを取得します。

context :

MilterClientContext

option :

MilterOption

milter_client_context_get_option ()

MilterOption*       milter_client_context_get_option    (MilterClientContext *context);

コンテキストのオプションを取得します。

context :

MilterClientContext

返値 :

コンテキストのオプション。