Solaris 共通デスクトップ環境 プログラマーズ・ガイド

第 10 章 カレンダとの統合

カレンダのアプリケーション・プログラム・インタフェース (API) は、ネットワーク環境でカレンダ・データにアクセスし、管理するためのプログラム的な方法を提供します。API は、項目の挿入、削除、変更だけでなく、ブラウズおよび検索機能もサポートします。また、カレンダ管理関数をサポートします。

カレンダ API は、X.400 Application Programming Interface Association (XAPIA) の Calendaring and Scheduling API (CSA API) を実装しています。CSA API は、カレンダが有効なアプリケーションからカレンダおよびスケジュール・サービスのさまざまな機能へのアクセスを可能にする高水準の関数のセットを定義しています。最新の XAPIA 仕様の詳細は、X.400 API Association (800 El Camino Real, Mountain View, California 94043) に問い合わせてください。

この章では、次の節でカレンダ API を説明します。

ライブラリとヘッダ・ファイル

カレンダ API を使用するには、libcsa ライブラリをリンクする必要があります。ヘッダ・ファイルは、csa/csa.h です。

デモ・プログラム

カレンダ API の使用例を示すデモ・プログラムが、/usr/dt/examples/dtcalendar にあります。

カレンダ API の使い方

カレンダと統合するには

カレンダ API は、ネットワーク環境でカレンダ・データにアクセスし、管理する方法を提供します。

  1. アプリケーションに csa/csa.h を組み込みます。

  2. カレンダ API を使用して、アプリケーションの中で使用するカレンダ操作を組み込みます。

  3. libcsa とリンクします。

CSA API の概要

CSA インタフェースは、カレンダおよびスケジュール・サービスへの共通インタフェースを可能にします。CSA 実装のそれぞれについて、CSA によって与えられる表示と機能は、基本のカレンダ・サービスの表示と機能にマップされなければなりません。インタフェースは、実際のカレンダおよびスケジュールの実装に依存しないように設計されています。また、インタフェースは、カレンダ・サービスが使用するオペレーティング・システムと基本のハードウェアに依存しないように設計されています。

提供される関数呼び出しの数は、最小限のものです。一組の関数で複数の種類のカレンダ項目を管理します。

C の命名規則

表 10-1 に示すように、C インタフェースの要素の識別子は、要素の属性名とそれに関連するデータ型に由来します。属性名には、テーブルの 2 番目の欄の文字列が接頭辞として付けられます。英字は、3 番目の欄の大文字または小文字に変換されます。

表 10-1 C 命名規則の由来

要素の種類 

接頭辞 

大文字/小文字 

データ型 

CSA_

小文字 

データの値 

CSA_

大文字 

関数 

csa_

小文字 

関数の引き数 

なし

小文字 

関数の結果 

なし

小文字 

定数 

CSA_

大文字 

エラー 

CSA_E_

大文字 

マクロ 

CSA_

大文字 

拡張セットのために確保 

CSA_XS_

大文字/小文字 

拡張のために確保 

CSA_X_

大文字/小文字 

処理系作成者が使用するために確保 

CSAP

大文字/小文字 

ベンダ関数拡張のために確保 

csa_x

小文字 

構造体のタグ 

CSA_TAG_

大文字 

接頭辞 CSAP (大文字/小文字) が付いている要素は、CSA サービスの実装の作成者が内部専用として使用するために確保されています。CSA インタフェースによって書かれたプログラムが直接使用するためのものではありません。

接頭辞 CSA_XS_CSA_X_ (大文字/小文字)、および csa_x は、ベンダまたはグループによるインタフェースの拡張のために確保されています。仕様では、これらのインタフェース拡張は、基本関数セットの拡張として定義されています。

定数データ値の場合、定数データ値のデータ構造体または関数を示すために、通常、追加の文字列が CSA_ に追加されます。

機能のアーキテクチャ

本節では、CSA API をサポートしているサービスの機能のアーキテクチャを説明します。抽象実装モデル、抽象データ・モデル、および機能の概要を示します。

実装モデル

CSA API の適用範囲が理解できるように、抽象実装モデルが用意されています。

CSA インタフェースは、カレンダが使用可能なアプリケーションとカレンダ・サービスの間に定義されます。このインタフェースの機能はすべて、カレンダ・サービスに依存しないように設計されています。ただし、この API では、拡張の使用によって実行される共通関数のプロトコル固有の拡張は許されています。詳細は、「拡張」を参照してください。カレンダが使用可能なアプリケーションとカレンダ・サービスの CSA インタフェースの関係を図 10-1 に示します。

図 10-1 カレンダおよびスケジュール API の位置付け

Graphic

CSA インタフェースのモデルは、管理、カレンダ管理、および項目管理という 3 つのコンポーネントに分けることができます。これらのコンポーネントを図 10-2 に示します。

図 10-2 カレンダおよびスケジュール API のコンポーネント

Graphic

カレンダ・サービスへのアクセスは、カレンダ・セッションを通して確立されます。セッションは、カレンダ・サービスへの有効な接続のために用意され、サービスによって保持されるカレンダ情報の整合性の確保を支援します。カレンダが使用可能なアプリケーションは、カレンダ・サービス内の個々のカレンダにログインして、有効なセッションまたは接続を確立します。セッションは、カレンダが使用可能なアプリケーションがカレンダからログアウトすることによって終了します。

カレンダ・サービスは、1 つ以上のカレンダを保持します。カレンダ・サービスは、これらのカレンダに対して、いくつかのレベルの管理サポートを提供します。カレンダが使用可能なアプリケーションは、特定のカレンダ・サービスによって保持されるカレンダのリストにアクセスできます。さらに、カレンダ・サービスにより、実装固有の永続的形式にカレンダ情報を保管したり復元したりできます。カレンダ・サービスが複数のカレンダの保持をサポートする場合には、カレンダの作成と削除のためのサポート関数が定義されます。また、カレンダの特性を管理するための関数が定義されます。

CSA インタフェースのほとんどの関数は、個々のカレンダ項目を管理します。カレンダ項目は、イベント、予定、またはメモです。項目は、特定のカレンダへの追加、削除、更新、および読み取りができます。カレンダが使用可能なアプリケーションは、カレンダ項目に通知方法を追加できます。

データ・モデル

CSA インタフェースは、カレンダ・サービスによって保持されるカレンダ情報の概念上のバックエンドの記憶領域へのアクセス方法です。共通データ・モデルは、カレンダ・サービスによって保持されるカレンダ情報のコンポーネントを視覚化する際に役に立ちます。

カレンダ・エンティティ

データ・モデルは、カレンダ・エンティティの概念に基づきます。カレンダは、管理カレンダ属性とカレンダ項目の名前付きコレクションによって表されます。カレンダは、個々のユーザによって所有されます。ユーザは、個人、グループ、またはリソースを表します。

カレンダ属性は、カレンダに関する共通、実装固有、またはアプリケーション固有の管理特性を表す名前付きの値のセットです。たとえば、タイムゾーン、名前、所有者、およびカレンダへのアクセスの権利を、個々のカレンダ属性の中で指定できます。

カレンダ項目は、カレンダの主要なコンポーネントです。カレンダ項目の 3 つのクラスは、次のとおりです。

カレンダ項目は、固有な名前を付けられた項目属性のコレクションによって表されます。項目属性は、カレンダ項目の共通、実装固有、またはアプリケーション固有の特性を表す名前付きの値のセットです。たとえばイベントには、開始と終了の日付と時間、説明、およびサブタイプを指定できます。予定には、作成日、期限、優先順位、およびステータスを指定できます。メモには、作成日とテキスト内容または説明を入れることができます。

カレンダ属性と項目属性は、名前、型、値の 3 つの組から成ります。仕様によって定義されている共通属性を拡張できます。実装によって、固有の属性を定義できます。また、アプリケーションでアプリケーション固有の属性を定義するための機能を提供するものもあります。共通デスクトップ環境では、アプリケーション定義の属性をサポートします。

アクセス権

個々のユーザがカレンダにアクセスできるかどうかは、そのユーザに与えられるアクセス権によって制御されます。アクセス権は、カレンダのユーザと対になっています。CSA では、ユーザは、個人、グループ、またはリソースです。共通デスクトップ環境では、個々のユーザだけをサポートします。アクセス権は、アクセス・リストで保持されます。アクセス・リストは、特定のカレンダ属性です。アクセス権は、個別に制御され、それを累積することによって、カレンダとその項目に対するユーザのアクセスの範囲を定義できます。アクセス権は、次のアクセスの役割の観点から指定できます。

所有者の役割を与えられたユーザは、カレンダの所有者ができることであれば、カレンダまたはカレンダ項目に対して何でも実行できます。すなわち、カレンダの削除、カレンダ属性の表示、挿入、変更、カレンダ項目の追加と削除、項目属性の表示、挿入、および変更を実行できます。

主催者の役割を与えられたユーザは、そのユーザが主催者として指定されたカレンダ項目に対して、項目の削除、または項目属性の表示や変更を実行できます。デフォルトでは、項目を作成したカレンダ・ユーザが主催者です。

スポンサーの役割を与えられたユーザは、そのユーザがスポンサーとして指定されたカレンダ項目に対して、項目の削除、または項目属性の表示や変更を実行できます。スポンサーは、カレンダ項目を実質的に所有するカレンダ・ユーザです。

これらの役割に加えて、アクセス権の設定によって、公用、半私用、私用の分類に応じて、空き時間の検索へのアクセス、カレンダ属性の表示、挿入、変更、あるいは項目の表示、挿入、変更を制限できます。項目の分類は、アクセスできるかどうかの二次フィルタとして機能します。

機能の概要

CSA インタフェースは、主に 3 種類の作業をサポートします。

管理

CSA 関数呼び出しの大部分は、カレンダ・セッションの中で発生します。カレンダ・セッションは、カレンダが使用可能なアプリケーションとカレンダ・サービスによって保持された特定のカレンダとの間の論理的な接続です。セッションは、csa_logon() 関数の呼び出しで確立され、csa_logoff() 関数の呼び出しで終了します。セッションの状況は、セッション・ハンドルによって表されます。このハンドルは、1 つのカレンダ・セッションを他のセッションと見分けるためのトークンを各 CSA 関数の中で提供します。csa_logon() 関数は、また、カレンダ・サービスに対してユーザを認証し、セッション属性を設定します。現時点では、アプリケーション間でのカレンダ・セッションの共有はサポートされていません。

csa_list_calendars() 関数は、特定のカレンダ・サービスによって管理されるカレンダ名をリストするために使用されます。

csa_query_configuration()関数は、現在のカレンダ・サービスの構成に関する情報をリストするために使用されます。この情報は、文字セット、テキスト文字列の行終了文字、デフォルトのサービス名、指定されたカレンダ・サービスのデフォルトの認証ユーザ識別子、ユーザ識別子を認証するためにパスワードが必要かどうかを示すインジケータ、ユーザ・インタフェース・ダイアログの共通拡張がサポートされるかどうかを示すインジケータ、および実装によってサポートされる CSA 仕様などです。

CSA の実装は、サービスによって返されるカレンダ・オブジェクトおよび属性のためのメモリの管理をサポートします。csa_free() 関数は、このメモリが不要になったときに、解放するために使用されます。カレンダ・サービスによって割り当てられ、管理されるメモリを解放するのは、アプリケーションの責任です。

カレンダ管理

CSA インタフェースは、いくつかのカレンダ管理関数を提供します。共通デスクトップ環境では、1 つのカレンダ・サービスにつき複数のカレンダをサポートします。カレンダが使用可能なアプリケーションは、カレンダを追加したり削除したりできます。csa_delete_calendar() 関数は、カレンダを削除するために使用されます。csa_add_calendar() 関数は、サービスに新しいカレンダを追加するために使用されます。

アプリケーションは、また、csa_list_calendar_attributes()csa_read_calendar_attributes()、および csa_update_calendar_attributes() 関数を使用して、カレンダ属性のリスト、読み取り、および更新を実行できます。アプリケーションは、カレンダ・ログイン、カレンダの削除、カレンダ属性の更新、新しいカレンダ項目の追加、カレンダ項目の削除、およびカレンダ項目の更新について通知を受けるためのコールバック関数を登録できます。コールバック関数は、カレンダ・セッションの継続中だけ登録されます。この情報は、一部のカレンダ管理アプリケーションにとっては貴重なものです。

エントリ管理

CSA インタフェースは、カレンダ項目を管理するための強力な関数のセットを備えています。カレンダ・セッション中のカレンダ項目の状況は、項目ハンドルによって保持されます。このハンドルは、1 つのカレンダ項目を他の項目と見分けるためのトークンを CSA 関数の中で提供します。項目ハンドルは、csa_add_entry()csa_list_entries() 関数によって返されます。項目ハンドルは、カレンダ・セッションの継続期間、あるいは項目が削除または更新されるまで有効です。csa_free() の呼び出しによって解放されると、項目ハンドルは無効になります。

csa_add_entry() 関数は、カレンダに新しい項目を追加するために使用されます。csa_delete_entry() 関数は、カレンダの中の項目を削除するために使用されます。csa_list_entries() 関数は、項目属性基準の特定のセットと一致するカレンダ項目を列挙するために使用されます。csa_read_entry_attributes() 関数は、特定のカレンダ項目に関連するすべてまたは一組の項目属性値を取り出すために使用されます。

カレンダに項目を追加するには、カレンダが使用可能なアプリケーションは、まず csa_logon() 関数を使用して、カレンダ・サービスとのセッションを確立しなければなりません。次に、アプリケーションは、csa_add_entry() 関数を新しい項目を指定するために実行します。カレンダが使用可能なアプリケーションは、csa_add_entry() 関数の中で使われる属性を組み立てる責任があります。セッションの終了には、csa_logoff() 関数が使用されます。

個々のカレンダ項目の中の項目属性は、csa_list_entry_attributes() 関数で列挙できます。csa_read_entry_attributes() 関数を使用すると、1 つ以上の属性の値を読み取ることができます。個々の項目属性は、csa_update_entry_attributes() 関数で変更できます。

カレンダ情報を検索するために CSA の実装によって割り当てられたメモリは、関連するメモリ・ポインタを csa_free() 関数に渡すことによって解放されます。

再帰的活動に関連するカレンダ項目もあります。csa_list_entry_sequence() 関数を使用すると、他の再帰的カレンダ項目を列挙できます。この関数は、再帰的項目の項目ハンドルのリストを返します。

CDE カレンダ・サーバは、カレンダ項目に関連付けられるアラームまたは通知方法のサポートを提供します。通知方法は、端末のスピーカからの音声による通知、端末画面の点滅による通知、カレンダ・ユーザへのメール送信による通知、端末画面にポップアップを表示することによる通知などの形を取ることができます。カレンダ・サービスは通知方法を管理しますが、通知情報を検索し、情報に対処するのはカレンダ・アプリケーションの責任です。csa_read_next_reminder() 関数は、次のスケジュール済みの通知に関する情報を読み込むために使用されます。

拡張

CSA 仕様で定義されている大半のデータ構造と関数は拡張できます。拡張は、データ構造にフィールドを追加したり、関数呼び出しにパラメータを追加したりするために行われます。これらの拡張のための標準的な汎用データ構造が定義されています。それは、拡張を識別する項目コード、拡張データまたはデータ自体の長さを保持する項目データ、拡張値が格納されている場所を示す項目参照と、関連する項目の格納領域がない場合には NULL、および拡張のフラグから成ります。

関数呼び出しにパラメータを追加するような拡張を、入力または出力時に実行できます。すなわち、拡張は、アプリケーションから CSA サービスへの入力パラメータとして渡すことができ、または、CSA サービスからアプリケーションへの出力パラメータとして渡すこともできます。拡張が入力パラメータの場合には、アプリケーションは、拡張構造体と、その拡張に関連するその他の構造体のためのメモリを割り当てます。拡張が出力パラメータの場合には、CSA サービスは必要に応じて、拡張の結果のための記憶領域を割り当てます。この場合、アプリケーションは、割り当てられた記憶領域を csa_free() 呼び出しによって解放しなければなりません。

サポートされていない拡張が要求された場合には、CSA_E_UNSUPPORTED_FUNCTION_EXT が返されます。

共通デスクトップ環境 (CDE) の実装

CSA API の CDE 実装は、CDE カレンダ・サーバへのアクセスを可能にするライブラリです。ライブラリとサーバとの通信には、ONC の RPC が使用されます。CDE 実装におけるカレンダ・サーバは、カレンダ・プロトコル・バージョン 2 から 5、およびデータ・バージョン 3 と 4 をサポートするバージョン 5 です。カレンダ・プロトコルのバージョン 2 から 4 とデータ・バージョン 3 は、OpenWindows カレンダ・マネージャへの下位互換を確保するためのものです。カレンダ・プロトコル・バージョン 5 とデータ・バージョン 4 は CSA インタフェースとデータの拡張性をサポートします。

表 10-2 サポートされるサーバのバージョンとデータのバージョン

サーバのバージョン 

データのバージョン 

3、4 

サポートされるアクセス・モデル

2 つのアクセス・モデルがカレンダ API によってサポートされています。XAPIA CSA 仕様において指定されているアクセス・モデルは、データ・バージョン 4 のためだけにサポートされています。OpenWindows カレンダ・マネージャのアクセス・モデルは、データ・バージョン 1 から 3 までのためにサポートされています。OpenWindows のカレンダ・マネージャ・アクセス・モデルでは、カレンダのアクセス許可は、アクセス権を指定するアクセス・リストにより制御されます。次の 3 種類のアクセス権が定義されています。

CSA_X_DT_BROWSE_ACCESS (ユーザはカレンダのエントリをリストして、読み取ることができる)

CSA_X_DT_INSERT_ACCESS (ユーザはカレンダのエントリを挿入できる)

CSA_X_DT_DELETE_ACCESS (ユーザはカレンダのエントリを削除できる)

カレンダ API はすべてのバージョンのカレンダへのアクセスを可能にするので、プログラマは、データ・バージョンに対応する正しいアクセス・モデルを使用して、アクセス・リストに含まれるアクセス権を解釈しなければなりません。

カレンダが作成されるとき、アクセス・リストを指定しないかぎり、デフォルトのアクセス・リストにユーザ名として world という 1 つのエントリが含まれます。world のアクセス権では、公開エントリをブラウズできます。world というユーザ名は、すべてのユーザを意味する特別の名前です。

デフォルトでは、カレンダの所有者と同じユーザ名を持つユーザは、任意のマシンから、所有者のアクセス権でカレンダにアクセスできます。さらに厳しいアクセス制御をするには、owner-user-name@host という書式の名前をカレンダのアクセス・リストに追加できます。このようなエントリをアクセス・リストに追加するときは、対応するアクセス権は、データ・バージョン 4 では CSA_OWNER_RIGHTS、データ・バージョン 3 では (CSA_X_DT_BROWSE_ACCESS|CSA_X_DT_INSERT_ACCESS|CSA_X_DT_DELETE_ACCESS) です。このようなエントリをアクセス・リストに追加した後は、指定されたホストからのユーザだけが所有者のすべての権利でカレンダにアクセスできます。

データ構造

表 10-3 に、CSA データ構造をリストします。詳細は、関連するマニュアル・ページを参照してください。

表 10-3 CSA データ構造

データ型の名前 

説明 

Access List 

カレンダ・ユーザのアクセスの権利構造体のリスト 

Attendee List 

出席者構造体のリスト 

Attribute 

属性構造体 

Attribute Reference 

属性参照構造体 

Boolean 

論理的な True または False を示す値 

Buffer 

データ項目のポインタ 

Calendar User 

カレンダ・ユーザ構造体 

Callback Data Structures 

コールバック・データ構造体 

Date and Time 

日付と時間の指定 

Date and Time List 

日付と時間の値のリスト 

Date and Time Range 

日付と時間の範囲 

Entry Handle 

カレンダ項目のハンドル 

Enumerated 

計算の値を含むデータ型 

Extension 

拡張構造体 

Flags 

ビート・マスクのコンテナ 

Free Time 

空き時間構造体 

Opaque Data 

不透明データ構造体 

Reminder 

通知方法構造体 

Reminder Reference 

通知方法参照構造体 

Return Code 

関数が成功したこと、または失敗した理由を示す戻り値 

Service Reference 

サービス参照構造体 

Session Handle 

カレンダ・セッションのハンドル 

String 

文字列ポインタ 

Time Duration 

継続時間 

カレンダ属性

表 10-4 に、共通デスクトップ環境でサポートされるカレンダ属性をリストします。詳細は、関連するマニュアル・ページを参照してください。カレンダ属性のリストは、拡張命名規則による拡張が可能です。

表 10-4 CSA カレンダ属性

属性名 

記号名 

サーバのバージョン 

データのバージョン 

読み取り専用 

Access List 

CSA_CAL_ATTR_ACCESS_LIST_ 

2-5 

1-4 

Calendar Name 

CSA_CAL_ATTR_CALENDAR_NAME 

2-5 

1-4 

○ * 

Calendar Owner 

CSA_CAL_ATTR_CALENDAR_OWNER 

2-5 

1-4 

○ * 

Calendar Size 

CSA_CAL_ATTR_CALENDAR_SIZE 

3,4 

○ 

Character Set 

CSA_CAL_ATTR_CHARACTER_SET 

○ 

Data Version** 

CSA_X_DT_CAL_ATTR_DATA_VERSION 

2-5 

1-4 

○ 

Date Created 

CSA_CAL_ATTR_DATE_CREATED 

○ 

Number Entries 

CSA_CAL_ATTR_NUMBER_ENTRIES 

2-5 

1-4 

○ 

Product Identifier 

CSA_CAL_ATTR_PRODUCT_IDENTIFIER 

2-5 

1-4 

○ 

Server Version** 

CSA_X_DT_CAL_ATTR_SERVER_VERSION 

2-5 

1-4 

○ 

Time Zone 

CSA_CAL_ATTR_TIME_ZONE 

○ 

Version 

CSA_CAL_ATTR_VERSION 

2-5 

1-4 

○ 

* カレンダ作成時に指定し、その後は読み取り専用になります。

** CDE のみ

次のカレンダ属性はサポートされません。

      
CSA_CAL_ATTR_COUNTRY
      CSA_CAL_ATTR_LANGUAGE
      CSA_CAL_ATTR_WORK_SCHEDULE

次の節では、表 10-4 にリストしたカレンダ属性について、追加の情報を提供します。

CDE 定義済みカレンダ属性は、次のとおりです。

項目属性

表 10-5 に、共通デスクトップ環境でサポートされる項目属性をリストします。詳細は、関連するマニュアル・ページを参照してください。項目属性のリストは、拡張命名規則による拡張が可能です。

表 10-5 CSA 項目属性

属性名 

記号名 

サーバのバージョン 

データのバージョン 

読み取り専用 

Audio Reminder 

CSA_ENTRY_ATTR_AUDIO_REMINDER 

2-5 

1-4 

Character Set* 

CSA_X_DT_ENTRY_ATTR_CHARACTER _SET 

Classification 

CSA_ENTRY_ATTR_CLASSIFICATION 

2-4 

Date Completed 

CSA_ENTRY_ATTR_DATE_COMPLETED 

Date Created 

CSA_ENTRY_ATTR_DATE_CREATED 

○ 

Description 

CSA_ENTRY_ATTR_DESCRIPTION 

Due Date 

CSA_ENTRY_ATTR_DUE_DATE 

End Date 

CSA_ENTRY_ATTR_END_DATE 

2-5 

1-4 

Exception Dates 

CSA_ENTRY_ATTR_EXCEPTION_DATES 

Flashing Reminder 

CSA_ENTRY_ATTR_FLASHING_ REMINDER 

2-5 

1-4 

Last Update 

CSA_ENTRY_ATTR_LAST_UPDATE 

○ 

Mail Reminder 

CSA_ENTRY_ATTR_MAIL_REMINDER 

2-5 

1-4 

Number Recurrences 

CSA_ENTRY_ATTR_NUMBER_ RECURRENCES 

○ 

Organizer 

CSA_ENTRY_ATTR_ORGANIZER 

2-5 

1-4 

○ 

Popup Reminder 

CSA_ENTRY_ATTR_POPUP_REMINDER 

2-5 

1-4 

Priority 

CSA_ENTRY_ATTR_PRIORITY 

Recurrence Rule 

CSA_ENTRY_ATTR_RECURRENCE_RULE 

Reference Identifier 

CSA_ENTRY_ATTR_REFERENCE_ IDENTIFIER 

2-5 

1-4 

○ 

Repeat Interval*  

CSA_X_ENTRY_ATTR_REPEAT_INTERVAL 

2-5 

1-4 

** 

Repeat Occurrence*  

CSA_X_ENTRY_ATTR_REPEAT_ OCCURRENCE_NUM 

2-5 

1-4 

** 

Repeat Times* 

CSA_X_ENTRY_ATTR_REPEAT_TIMES 

2-5 

1-4 

** 

Repeat Type* 

CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE 

2-5 

1-4 

** 

Sequence End Date* 

CSA_X_ENTRY_ATTR_SEQUENCE_END_ DATE 

2-5 

1-4 

** 

Showtimes* 

CSA_X_ENTRY_ATTR_SHOWTIME 

2-5 

1-4 

Sponsor 

CSA_ENTRY_ATTR_SPONSOR 

Start Date 

CSA_ENTRY_ATTR_START_DATE 

2-5 

1-4 

Status 

CSA_ENTRY_ATTR_STATUS  

2-5 

1-4 

Subtype 

CSA_ENTRY_ATTR_SUBTYPE 

2-5 

1-4 

Summary 

CSA_ENTRY_ATTR_SUMMARY 

2-5 

1-4 

Transparency 

CSA_ENTRY_ATTR_TIME_ TRANSPARENCY 

Type 

CSA_ENTRY_ATTR_TYPE 

2-5 

1-4 

○*** 

* CDE のみ

** データ・バージョン 1 から 3 については、この属性は指定または変更できます。ただし、データ・バージョン 4 については読み取り専用です。データ・バージョン 4 では、エントリ属性 CSA_ENTRY_ATTR_RECURRENCE_RULE から値が取られます。

***カレンダ作成時に指定し、その後は読み取り専用になります。

次のカレンダ属性はサポートされません。

      CSA_ENTRY_ATTR_ATTENDEE_LIST
      CSA_ENTRY_ATTR_EXCEPTION_RULE
      CSA_ENTRY_ATTR_RECURRING_DATES
      CSA_ENTRY_ATTR_SEQUENCE_NUMBER

次の節では、表 10-5 にリストした項目属性について、追加の情報を提供します。

      
CSA_X_DT_STATUS_ACTIVE
      CSA_X_DT_STATUS_DELETE_PENDING
      CSA_X_DT_STATUS_ADD_PENDING
      CSA_X_DT_STATUS_COMMITTED
      CSA_X_DT_STATUS_CANCELLED
      
CSA_X_DT_TYPE_OTHER

CDE エントリ属性

CDE 定義済み項目属性は、次のとおりです。

      
CSA_X_DT_REPEAT_ONETIME
      CSA_X_DT_REPEAT_DAILY
      CSA_X_DT_REPEAT_WEEKLY
      CSA_X_DT_REPEAT_BIWEEKLY
      CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY
      CSA_X_DT_REPEAT_MONTHLY_BY_DATE
      CSA_X_DT_REPEAT_YEARLY
      CSA_X_DT_REPEAT_EVERY_NDAY
      CSA_X_DT_REPEAT_EVERY_NWEEK
      CSA_X_DT_REPEAT_EVERY_NMONTH
      CSA_X_DT_REPEAT_MON_TO_FRI
      CSA_X_DT_REPEAT_MONWEDFRI
      CSA_X_DT_REPEAT_TUETHUR
      CSA_X_DT_REPEAT_WEEKDAYCOMBO
      CSA_X_DT_REPEAT_OTHER
      CSA_X_DT_REPEAT_OTHER_WEEKLY
      CSA_X_DT_REPEAT_OTHER_MONTHLY
      CSA_X_DT_REPEAT_OTHER_YEARLY

反復情報のエントリ属性

データ・バージョン 1 から 3 については、次の属性を使用してエントリの反復情報を指定します。すべて読み取りおよび書き込み属性です。

      CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE
      CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES
      CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL
      CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM
      CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE

データ・バージョン 4 については、エントリ属性 CSA_ENTRY_ATTR_RECURRENCE_RULECSA_ENTRY_ATTR_EXCEPTION_DATES を使用してカレンダ・エントリの反復情報を指定します。CSA_ENTRY_ATTR_RECURRENCE_RULE 属性の情報は、次の属性を使用して問い合わせることができます。

      CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE
      CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES
      CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL
      CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM
      CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE 

これらの計算された属性は、データ・バージョン 4 に対して読み取り専用です。

データ・バージョンによりサポートされる値

関数についての一般的な情報

次の一般的な情報は、すべての関数に適用されます。


注 -

ライブラリの中で渡されるテキストでの説明以外のデータは、すべて ASCII 形式でなければなりませんが、ライブラリはシングルバイトだけでなくマルチバイト文字列もサポートします。


サポートされる関数の拡張

管理関数

この節では、CDE でサポートされる管理関数について説明します。関数のプロトタイプと戻りコードのリストは、各関数に含まれています。詳細は、関連するマニュアル・ページを参照してください。

カレンダ管理関数

この節では、CDE でサポートされるカレンダ管理関数について説明します。関数のプロトタイプと戻りコードのリストは、各関数に含まれています。詳細は、関連するマニュアル・ページを参照してください。

項目管理関数

この節では、CDE でサポートされる項目管理関数について説明します。関数のプロトタイプと戻りコードのリストは、各関数に含まれています。詳細は、関連するマニュアル・ページを参照してください。

コーディング例

カレンダのリストおよび出力


例 10-1 サーバがサポートするカレンダをリストし出力する

Example:
List and print out the calendars supported by a server.
 	   Free memory returned by a CSA function. 
list_calendar() 
{
 	CSA_return_code		stat;
	CSA_uint32		i, number;
 	CSA_calendar_user	*calendars;
 	char			*host;

  	/* ネットワーク上のいくつかのマシンを指定します */
 	host = "somehost";

  	stat= csa_list_calendars(host, &number, &calendars, NULL);
  	for (i = 0; i< number; i++) {
 		/* calendar_address フィールドには、カレンダのアドレスが
 		 * user@host の書式で入っています		 */
 	printf("%d: %s¥n", i, calendars[i].calendar_address); 	
   }

  	/* 例: CSA 関数により返されるメモリを解放する
 	 * csa_list_calendars により返されるメモリを解放します
 	 */
 	stat = csa_free(calendars); 
}


カレンダの追加


例 10-2 activity という名前のカレンダをホスト host1 に追加する

#include <csa/csa.h>  

CSA_access_rights *setup_access_list() {
 	CSA_access_rights	*ptr1, *ptr2;
  	/* 任意のユーザに、公開および非公開エントリを表示する許可を与え、
 	 * ユーザ user1 に、公開エントリを表示し、挿入する許可を与えます。
 	 * 特別なユーザ名 world は任意のユーザを意味します。
   */

ptr2 = (CSA_access_rights *)calloc(1, sizeof(CSA_access_rights));
ptr2->user = (CSA_calendar_user *)calloc(1, sizeof(CSA_calendar_user));
ptr2->user->user_name = strdup("world");
ptr2->user->user_type = CSA_USER_TYPE_INDIVIDUAL;
ptr2->flags = CSA_VIEW_PUBLIC_ENTRIES | CSA_VIEW_CONFIDENTIAL_ENTRIES;
ptr1 = (CSA_access_rights *)calloc(1, sizeof(CSA_access_rights));
ptr1->user = (CSA_calendar_user *)calloc(1, sizeof(CSA_calendar_user));
ptr1->user->user_name = strdup("user1");
ptr1->user->user_type = CSA_USER_TYPE_INDIVIDUAL;
ptr1->flags = CSA_VIEW_PUBLIC_ENTRIES | CSA_INSERT_PUBLIC_ENTRIES;
ptr1->next = ptr2; 
} 

void destroy_access_list(CSA_access_rights *list) 
{
 	CSA_access_rights	*ptr;

  	while (list != NULL) {
 		ptr = list->next;

  		if (list->user) {
 			if (list->user->user_name)
 			free(list->user->user_name);
 			free(list->user);
 		} 		free(list);
  		list = ptr;
 	}
} 
add_calendar() 
{
 	CSA_return_code		stat;
 	CSA_calendar_user	caddr;
 	CSA_attribute		attr;
 	CSA_attribute_value	attr_val;

  	/* 追加するカレンダを指定します。 */

 	caddr.user_name = NULL;
 	caddr.user_type = NULL;
 	caddr.calendar_address = "activity@host1";
 	caddr.calendar_user_extensions = NULL;

  	/* アクセス・リストを設定します */
 	attr_val.type			= CSA_VALUE_ACCESS_LIST;
 	attr_val.item.access_list_value	= setup_access_list();
 	attr.name			= CSA_CAL_ATTR_ACCESS_LIST;
 	attr.value			= &attr_val;
 	attr.attribute_extensions	= NULL;
  	stat = csa_add_calendar(NULL, &caddr, 1, &attr, NULL);
  	destroy_access_list(attr_val.item.access_list_value);
}


カレンダへのログイン


例 10-3 カレンダにログインする

CSA_session_handle	cal;

logon() 
{
 	CSA_return_code		stat;
 	CSA_calendar_user	caddr;
 	CSA_flags		access;
 	CSA_extension		logon_exts[2];
 	CSA_X_COM_support	check_support[2];

  	/* ログインするカレンダを指定します */
caddr.user_name = NULL;
caddr.user_type = CSA_USER_TYPE_INDIVIDUAL;
caddr.calendar_address = "user@host";
caddr.calendar_user_extensions = NULL;

  	/* (CSA_X_DT_GET_USER_ACCESS_EXT) を指定して、
 	 * カレンダに関するユーザのアクセス権を取得します。
 	 */
logon_exts[0].item_code		= CSA_X_DT_GET_USER_ACCESS_EXT;
logon_exts[0].item_data		= 0;
logon_exts[0].item_reference	= NULL;
logon_exts[0].extension_flags	= NULL;

	/* CSA_X_COM_SUPPORT_EXT 拡張を指定して、
 	 * CSA_X_XT_APP_CONTEXT_EXT 拡張と、CSA_X_UI_ID_EXT 拡張が
 	 * サポートされているかどうかをチェックします。
 	 */
check_support[0].item_code	= CSA_X_XT_APP_CONTEXT_EXT;
check_support[0].flags		= NULL;
check_support[1].item_code	= CSA_X_UI_ID_EXT;
check_support[1].flags		= NULL;
logon_exts[1].item_code		= CSA_X_COM_SUPPORT_EXT;
logon_exts[1].item_data		= 2;
logon_exts[1].item_reference	= (CSA_buffer)check_support;
logon_exts[0].extension_flags	= CSA_EXT_LAST_ELEMENT;

  	stat = csa_logon(NULL, &caddr, NULL, NULL, NULL, &cal, logon_exts);

  	if (stat == CSA_SUCCESS) {
 		access = (CSA_flags)get_access_ext.item_data;
  		if (check_support[0].flag & CSA_X_COM_SUPPORTED)
 			printf("The CSA_X_XT_APP_CONTEXT_EXT extension is supported¥n");
  		if (check_support[1].flag & CSA_X_COM_SUPPORTED)
 			printf("The CSA_X_UI_ID_EXT extension is supported¥n");
 	}
 }


カレンダ・セッションの終了


例 10-4 カレンダ・セッションを終了する

logoff() 
{
 	CSA_return_code		stat;

  	/* セッションが必要ない場合は、csa_logoff を呼び出すことにより終了できます。
 	 * 前の例で csa_logon により返されたセッションを終了します。
 	 */
 	stat = csa_logoff(cal, NULL); 
}


カレンダの削除


例 10-5 カレンダを削除する

delete_calendar() 
{
 	/* csa_logon() を呼び出すことによりカレンダ・セッションを確立後、
 	 * csa_delete_calender() を使用してカレンダを削除できます。
 	 */
 	CSA_return_code		stat;
  	stat = csa_delete_calendar(cal, NULL);
}


カレンダ・エントリの追加


例 10-6 カレンダ・エントリを追加する

#include <csa/csa.h>  

CSA_return_code		stat;
CSA_session_handle	cal;
CSA_attribute		attrs[9];
CSA_attribute_value	attr_val[9];
CSA_reminder		audio;
CSA_reminder		mail;
CSA_entry_handle	new_entry;
int			i;

i = 0;

/* 開始日の属性。この属性にはデフォルトがないため、必ず指定してください。
 * CSA_date_time 値は、ISO 8601 規格にある UTC ベースの日付と時間を指定します。
 */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE;
 attrs[i].value = &attr_val[i];
 attrs[i].attribute_extensions = NULL;
 attr_val[i].type = CSA_VALUE_DATE_TIME;
 attr_val[i].item.date_time_value = iso8601time(time(NULL));
 i++;

/* 終了日の属性。
 * 指定しないと、エントリは終了日の属性を持ちません。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_END_DATE;
 attrs[i].value = &attr_val[i];
 attrs[i].attribute_extensions = NULL;
 attr_val[i].type = CSA_VALUE_DATE_TIME;
 attr_val[i].item.date_time_value = iso8601time(time(NULL) + 3600);
 i++;

/* 分類属性。
 * 指定しないと、デフォルト値は CSA_CLASS_PUBLIC になります。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_CLASSIFICATION;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_CLASS_CONFIDENTIAL;
i++;  

/* タイプ属性。
 * この属性にはデフォルトがないため、必ず指定してください。
 */
attrs[i].name = CSA_ENTRY_ATTR_TYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_TYPE_EVENT;
i++;

/* サブタイプ属性。
 * 指定しないと、デフォルト値は CSA_SUBTYPE_APPOINTMENT になります。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_SUBTYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = CSA_SUBTYPE_APPOINTMENT; 
i++;  

/* サマリ属性 */
attrs[i].name = CSA_ENTRY_ATTR_SUMMARY; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = argv6; 
attrs[i].attribute_extensions = NULL; 
i++;

/* 反復規則属性。
 * 指定しないと、エントリは 1 回だけのエントリになります。反復規則 D1 #3 は、
 * エントリが毎日 3 日間繰り返されるよう指定します。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_RECURRENCE_RULE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = argv7; 
i++;

/* オーディオ通知属性。
 * 通知プログラムのリード・タイムは、ISO 8601 規格にある CSA_time_duration の値で
 * 指定します。
 * たとえば、5 分間のリード・タイムは、文字列 +PT300S と表します。
 * マイナス 5 分間のリード・タイムは、-PT300S と表します。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_AUDIO_REMINDER; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_REMINDER; 
attr_val[i].item.reminder_value = &audio; 
memset((void *)&audio, NULL, sizeof(audio)); 
audio.lead_time = "+PT300S"; i++;

/* メール通知属性。
 * 電子メール・アドレスは、reminder_data フィールドに指定します。
 * この通知プログラムのリード・タイムは 1 日。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_MAIL_REMINDER; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_REMINDER; 
attr_val[i].item.reminder_value = &mail; 
memset((void *)&mail, NULL, sizeof(mail)); 
mail.lead_time = "+PT86400S"; 
mail.reminder_data.data = "someuser@somehost"; 
mail.reminder_data.size = strlen(mail.reminder_data.data); 
i++;

/* 指定した属性値でエントリを追加します */
stat = csa_add_entry(cal, i, attrs, &newentry, NULL);  
if (stat == CSA_SUCCESS)
 	csa_free((CSA_buffer)newentry);


カレンダのエントリの検索


例 10-7 カレンダのエントリを検索する/属性値を読み取る

#include <csa/csa.h>  

CSA_return_code		stat; 
CSA_session_handle	cal;
CSA_attribute		attrs[4]; 
CSA_attribute_value	attr_val[4]; 
CSA_enum		ops[4];
CSA_uint32		i; 
CSA_uint32		num_entries;
CSA_entry_handle	*entries;
CSA_uint32		num_attributes; 
CSA_attribute		*entry_attrs;  

/* 次の判断基準ですべてのエントリを検索します。
 * UTC 時間 1996 年 8 月のすべてのアポイント
 * 開始日は、UTC 時間 1996 年 8 月 1 日 00:00:00 以降
 * 開始日は、UTC 時間 1996 年 9 月 1 日 00:00:00 より前
 * タイプは CSA_TYPE_EVENT 
 * サブタイプは CSA_SUBTYPE_APPOINTMENT
 */  

i = 0;  

/* 開始日は、UTC 時間 1996 年 8 月 1 日 00:00:00 以降 */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_DATE_TIME;
attr_val[i].item.date_time_value = "19960801T000000Z"; 
ops[i] = CSA_MATCH_GREATER_THAN_OR_EQUAL_TO; 
i++;

/* 開始日は、UTC 時間 1996 年 9 月 1 日 00:00:00 より前 */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_DATE_TIME; 
attr_val[i].item.date_time_value = "19960901T000000Z" 
ops[i] = CSA_MATCH_LESS_THAN; 
i++;  

/* タイプは CSA_TYPE_EVENT */ 
attrs[i].name = CSA_ENTRY_ATTR_TYPE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_UINT32; 
attr_val[i].item.sint32_value = CSA_TYPE_EVENT; 
ops[i] = CSA_MATCH_EQUAL_TO; 
i++;

/* サブタイプは CSA_SUBTYPE_APPOINTMENT */
attrs[i].name = CSA_ENTRY_ATTR_SUBTYPE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = CSA_SUBTYPE_APPOINTMENT; 
ops[i] = CSA_MATCH_EQUAL_TO; 
i++;

/* 検索の実行 */
stat = csa_list_entries(csa, i, attrs, ops, &num_entries, &entries, NULL);

  if (stat == CSA_SUCCESS) {
     for (i = 0; i < num_entries; i++) {
	/* エントリのすべての属性値を取得します。
	 * number_names に 0 を指定し、attribute_names に NULL を指定すると、
	 * すべての属性値が返されます。
 	 */ 	
   stat = csa_read_entry_attributes(cal, entries[i], 0, NULL,
 					 &num_attributes, &entry_attrs,
 					 NULL); 	if (stat == CSA_SUCCESS) {
	    /* 返された属性値を使用し、終了時にメモリを解放します
 	     */
 	    csa_free(entry_attrs);
 	} else {
	    /* ハンドル・エラー */
 	}
     }
 } else {
     /* ハンドル・エラー */
}   

Example: Change the end time of the returned appointments to be
 	 one hour later.

CSA_attribute_reference	name = CSA_ENTRY_ATTR_END_DATE; 
char			buffer[80]; 
time_t			endtime; 
CSA_entry_handle	new_entry;

for (i = 0; i < num_entries; i++) {
     /* アポイントの終了時間を取得します */
     stat = csa_read_entry_attributes(cal, entries[i], 0, &name,
 				    &num_attributes, &entry_attrs, NULL);
     if (stat == CSA_SUCCESS) {
	/* 終了時間を 1 時間後に変更します */
 	from_iso8601_time(entry_attrs[0].value->item.date_time_value, &endtime);
 	endtime += 60*60 /* 1 時間の秒数 */
 	to_iso8601_time(endtime, buffer);
    attrs[0].name = CSA_ENTRY_ATTR_END_DATE;
    attrs[0].value = &attr_val[i];
    attrs[0].attribute_extensions = NULL;	
    attr_val[0].type = CSA_VALUE_DATE_TIME;
 	attr_val[0].item.date_time_value = buffer;
  	stat = csa_update_entry_attributes(cal, entries[0], CSA_SCOPE_ALL,
 			      	CSA_FALSE, 1, attrs, &new_entry,
 					   NULL);
 	if (stat == CSA_SUCCESS) {
 	    csa_free(new_entry);
 	} else {
 	    /* ハンドル・エラー */
 	}
  	csa_free(entry_attrs);
      } else {
 	    /* ハンドル・エラー */
     } 
}


カレンダのエントリの更新


例 10-8 返されたアポイントの終了時間を 1 時間後に変更する

CSA_attribute_reference	name = CSA_ENTRY_ATTR_END_DATE; 
char			buffer[80]; 
time_t			endtime; 
CSA_entry_handle	new_entry;  

for (i = 0; i < num_entries; i++) {
     /* アポイントの終了時間を取得します */
     stat = csa_read_entry_attributes(cal, entries[i], 0, &name,
 				     &num_attributes, &entry_attrs, NULL);
     if (stat == CSA_SUCCESS) {
	/* 終了時間を 1 時間後に変更します */
 	from_iso8601_time(entry_attrs[0].value->item.date_time_value, &endtime);
 	endtime += 60*60 /* 1 時間の秒数 */
 	to_iso8601_time(endtime, buffer);

  	attrs[0].name = CSA_ENTRY_ATTR_END_DATE;
 	attrs[0].value = &attr_val[i];
 	attrs[0].attribute_extensions = NULL;
 	attr_val[0].type = CSA_VALUE_DATE_TIME;
 	attr_val[0].item.date_time_value = buffer;
  	stat = csa_update_entry_attributes(cal, entries[0], CSA_SCOPE_ALL,
 					   CSA_FALSE, 1, attrs, &new_entry,
 					   NULL); 	if (stat == CSA_SUCCESS) {
 	    csa_free(new_entry);
 	} else {
 	    /* ハンドル・エラー */
 	}
  	csa_free(entry_attrs);
      } else {
 	    /* ハンドル・エラー */
    }
}


コールバックの登録および通知プログラムの保持


例 10-9 コールバックを登録し、通知プログラムを保持する

/* このコーディング例では、csa_register_callback、csa_read_next_reminder、
  * および csa_call_callbacks の使用方法について示します。
  * 基本となるコードでは、イベント CSA_CB_ENTRY_ADDED、CSA_CB_ENTRY_DELETED、
  * および CSA_CB_ENTRY_UPDATED 用のコールバック・ルーチンを登録します。
  * また、別のコールバック・ルーチンを、CSA_CB_CALENDAR_ATTRIBUTE_UPDATE 
  * イベント用に登録します。
  * 通知デリバリ用のタイマを設定する方法も示します。
  * ISO 8601 書式の時間表記を UTC 1970 年 1 月 1 日 00:00:00 からの経過秒数を示す
  * ティック数への変換用の 2 つのユーティリティ・ルーチンも含みます。
  */ 

#include <csa/csa.h> 
#include <time.h> 
#include <unistd.h>  

CSA_session_handle	cal;	 /* カレンダ・セッション */
time_t			run_time; /* 通知プログラムを実行する時間 */ 
CSA_uint32		num_rems; /* 返される通知数 */
CSA_reminder_reference	*rems;	  /* 通知情報の配列 */

void 
set_up_callback_handler() 
{
 	CSA_return_code		stat;
 	CSA_flags		flags;

	/* Xt ベースのアプリケーションは、コールバック・ルーチンが非同期に呼び出せるように
	 * するため、CSA_X_XT_APP_CONTEXT_EXT 拡張を使用して、
	 * Xt アプリケーションのコンテキストを指定できます。
  *
  *	CSA_extension callback_ext;
  *	callback_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
  * 	callback_ext.item_data = (CSA_uint32)application_context;
  *	callback_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
  *
  * callback_ext を最後のパラメータとして、csa_register_callback に渡す。
  */

  	flags = CSA_CB_ENTRY_ADDED|CSA_CB_ENTRY_DELETED|CSA_CB_ENTRY_UPDATED;
 	stat = csa_register_callback(cal, flags, entry_update_callback,
 		NULL, NULL);

  	if (stat != CSA_SUCCESS) {
		/* エラー処理コード */
 	}

  	stat = csa_register_callback(cal, CSA_CB_CALENDAR_ATTRIBUTE_UPDATED,
 		calendar_update_callback, NULL, NULL);
  	if (stat != CSA_SUCCESS) {
		/* エラー処理コード */
 	} 
}  

/*  * このルーチンはライブラリをポーリングし、特定のイベントが発生していた場合に、
 * 登録されているコールバックを呼び出します。
 * アプリケーションが CSA_X_XT_APP_CONTEXT_EXT 拡張を使用してコールバックの
 * 呼び出しを非同期に設定していない場合、csa_call_callbacks を呼び出して、
 * コールバックの呼び出しを強制する必要があります。
 */ 

check_events(CSA_flags event)
{
 	csa_call_callbacks(cal, event, NULL); 
}

  /*
  * これは、イベント CSA_CB_ENTRY_ADDED、CSA_CB_ENTRY_ADDED、および 
  * CSA_CB_ENTRY_UPDATED のためのコールバック・ルーチンです。
  */ 
void 
entry_update_callback(
 	CSA_session_handle	cal,
 	CSA_flags		flags,
 	CSA_buffer		call_data,
 	CSA_buffer		client_data,
 	CSA_extension		*ext) 
{
	/* エントリが追加、削除、または更新されます。
	 * このコールバック・ルーチンで行う可能性があるのは次のとおりです。
	 *
	 * 1. カレンダ表示の更新
	 * 2. ユーザ自身のカレンダの場合は、通知情報の更新
	 *
	 * このルーチンのコーディング例は通知情報を更新します。
 	 */ 	reset_reminder();
}
 /*
 * これは CSA_CB_CALENDAR_ATTRIBUTE_UPDATED イベントのための
 * コールバック・ルーチンです。
 */ 
void 
calendar_update_callback(
 	CSA_session_handle	cal,
 	CSA_flags		flags,
 	CSA_buffer		call_data,
 	CSA_buffer		client_data,
 	CSA_extension		*ext) 
{
 	/* カレンダ属性を更新する */
}

   /*
  * このルーチンは通知情報を更新します。
  *	 - 既存の情報がある場合は削除する
  *	 - csa_read_next_reminder() を呼び出して、次に転送する通知を取得する
  *	 - 実行時間をチェックし、タイマーを設定する
  */ 
void 
reset_reminder() {
 	CSA_return_code		stat;
 	time_t			current_time;
 	char			isotime[BUFSIZ];
 	CSA_uint32		number_reminders;
 	CSA_reminder_reference	*reminders;

  	current_time = time(NULL);

	/* 既存の情報を削除する */
 	if (rems) {
		/* この比較の目的は、最後に実行された時刻から、現在の時刻までの間に実行された
		 * 通知が失われていないかを確認することです。
 		 */
 		if (current_time > run_time)
 			current_time = run_time;

  		csa_free((CSA_buffer)rems);
 	}

  	to_iso8601_time(current_time, isotime);
 	stat = csa_read_next_reminder(cal, 0, NULL, isotime,
 		&number_reminders, &reminders, NULL);

  	if (stat == CSA_SUCCESS && num_rems > 0) {
 		num_rems = number_reminders;
 		rems = reminders;

		/* タイマーを設定し、通知を転送する。
		 * sigset() を使用して、SIGALRM シグナルのためのシグナル処理を設定します。
 		 */
 		from_iso8601_time(reminders[0].run_time, &run_time);
 		remain = run_time - time(NULL);
 		alarm((remain > 0) ? remain : 1);

		/* Xt ベースのアプリケーションは、XtAppAddTimeOut を使用して
		 * タイマーを設定できます。
 		 */
 	}
}

/*
  * このルーチンは、ISO 8601 書式の時間表記を、UTC 1970 年 1 月 1 日 00:00:00 
  * からの経過秒数を示すティック数へ変換します。
  * このティックはローカル時間に調整されます。
  */ int from_iso8601_time(char *buf, time_t *tick_out) 
{
 	int		year, month, day, hour, min, sec;
 	struct tm	time_str;

  	sscanf(buf, "%4d%2d%2dT%2d%2d%2dZ",
 	    &year, &month, &day, &hour, &min, &sec);

  	time_str.tm_year	= year - 1900;
 	time_str.tm_mon		= month - 1;
 	time_str.tm_mday	= day;
 	time_str.tm_hour	= hour;
 	time_str.tm_min		= min;
 	time_str.tm_sec		= sec;
 	time_str.tm_isdst	= -1;
  	*tick_out = mktime(&time_str);

  	if (*tick_out != (long)-1) {

		/* ローカル・タイムゾーンに調整 */
 		if (time_str.tm_isdst == 0)
 			*tick_out -= timezone;
 		else
 			*tick_out -= altzone;
  		return(0);
 	} else
 		return(-1); 
}  

/*
  * このルーチンは、UTC 1970 年 1 月 1 日 00:00:00 からの経過秒数を示すティック数を、
  * ISO 8601 書式の時間表記へ変換します。
  */ 
int 
to_iso8601_time(time_t tick, char *buf_out) 
{
 	struct tm	time_str;
  	if (gmtime_r(&tick, &time_str)) {

		/* 書式文字列が固定幅 (ゼロで埋め込み) フィールドを強制する。 */
 		sprintf(buf_out, "%04d%02d%02dT%02d%02d%02dZ",
 			time_str.tm_year + 1900,
 			time_str.tm_mon + 1,
 			time_str.tm_mday,
 			time_str.tm_hour,
 			time_str.tm_min,
 			time_str.tm_sec);
  		return (0);
 	} else {
 		return (-1);
 	} 
}