この節のプログラミング例は、次の操作を実行するための XFN API の使用法を示しています。
次の例は、コンテキストをリスト表示するための XFN 操作を示しています。
#include <stdio.h> #include <xfn/xfn.h> #include <string.h> #include <stdlib.h> /* このルーチンは与えられたコンテキスト (ctx_name) の下で 割り当てられた名前のリストを返す。 ctx_name の例としては "user"、"thisorgunit/service"、 host/alto/service、user/jsmit/service/calendar などがある */ typedef struct fns_listing { char *name; struct fns_listing *next; } fns_listing; fns_listing * fns_list_names(const char *ctx_name) { FN_status_t *status; FN_ctx_t *initial_context; FN_composite_name_t *context_name; FN_namelist_t *name_list; FN_string_t *name; unsigned int stat; fns_listing *head = 0, *current, *prev; int no_names = 0; status = fn_status_create(); /* 初期コンテキストの獲得 */ initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context¥n"); return (0); } context_name = fn_composite_name_from_str((unsigned char *) ctx_name); /* FNS によるリスト名の呼び出し */ name_list = fn_ctx_list_names(initial_context, context_name, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to list names¥n"); return (0); } /* 名前を個々に呼び出す */ while (name = fn_namelist_next(name_list, status)) { no_names++; current = (fns_listing *) malloc(sizeof(fns_listing)); current->name = (char *) malloc(strlen((char *) fn_string_str(name, &stat)) + 1); strcpy(current->name, (char *) fn_string_str(name, &stat)); current->next = 0; if (head) { prev->next = current; prev = current; } else { head = current; prev = current; } fn_string_destroy(name); } fn_namelist_destroy(name_list); fn_status_destroy(status); fn_ctx_destroy(initial_context); return (head); |
次の例は、バインディングの作成方法を示しています。
#include <stdio.h> #include <xfn/xfn.h> #include <string.h> /* このルーチンは "name" によって提供される名前を用いて バインディングを作成する。提供される名前のリファレンスのタイプは "reference_type" で、アドレスのタイプは "address_type"である。 関数の使用例として fns_create_bindings( "user/jsmith/service/calendar"、 "onc_calendar"、 "onc_cal_str"、 "jsmith&calserver"); がある */ int fns_create_bindings( char *name, char *reference_type, char *address_type, char *data) { int return_status; FN_composite_name_t *binding_name; FN_identifier_t ref_id, addr_id; FN_status_t *status; FN_ref_t *reference; FN_ref_addr_t *address; FN_ctx_t *initial_context; /* 初期コンテキストの獲得 */ status = fn_status_create(); initial_context = fn_ctx_handle_from_initial(0, status); /* エラーメッセージの状態のチェック */ if ((return_status = fn_status_code(status)) != FN_SUCCESS) { fprintf(stderr, "Unable to obtain the initial context¥n"); return (return_status); } /* プリンタ名に付ける複合名の獲得 */ binding_name = fn_composite_name_from_str((unsigned char *) name); /* アドレスのコンストラクト */ addr_id.format = FN_ID_STRING; addr_id.length = strlen(address_type); addr_id.contents = (void *) address_type; address = fn_ref_addr_create(&addr_id, strlen(data), (const void *) data); /* リファレンスのコンストラクト */ ref_id.format = FN_ID_STRING; ref_id.length = strlen(reference_type); ref_id.contents = (void *) reference_type; reference = fn_ref_create(&ref_id); /* リファレンスにアドレスを追加する */ fn_ref_append_addr(reference, address); /* 割り当ての作成 */ fn_ctx_bind(initial_context, binding_name, reference, 0, status); /* エラー状態をチェックして返す */ return_status = fn_status_code(status); fn_composite_name_destroy(binding_name); fn_ref_addr_destroy(address); fn_ref_destroy(reference); fn_ctx_destroy(initial_context); return (return_status); } |
次の例は、オブジェクト属性をリスト表示して処理する方法を示しています。
次の例は、オブジェクト属性をリスト表示する方法を示しています。
#include <stdio.h> #include <xfn/xfn.h> /* このルーチンは名前付きオブジェクトに関連付けられたすべての属性を 標準出力に出力する。関数の使用例として fns_attr_list("user/jsmith"); や fns_attr_list("thisorgunit/service/printer/color"); がある */ void fns_attr_list(const char *name) { FN_composite_name_t *name_comp; const FN_identifier_t *identifier; FN_attribute_t *attribute; const FN_attrvalue_t *values; char *id, *val; FN_multigetlist_t *attrset; void *ip; FN_status_t *status; FN_ctx_t *initial_context; name_comp = fn_composite_name_from_str((unsigned char *) name); status = fn_status_create(); /* 初期コンテキストの獲得 */ initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context¥n"); return; } /* 全属性の獲得 */ attrset = fn_attr_multi_get(initial_context, name_comp, 0, 0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain attributes¥n"); return; } /* 全属性の表示 */ while (attribute = fn_multigetlist_next(attrset, status)) { identifier = fn_attribute_identifier(attribute); switch(identifier->format) { case FN_ID_STRING: id = (char *) malloc(identifier->length + 1); memcpy(id, identifier->contents, identifier->length); id[identifier->length] = '¥0'; printf("Attribute Identifier: %s", id); free(id); break; default: printf("Attribute of non-string format¥n¥n"); continue; } for (values = fn_attribute_first(attribute, &ip); values != NULL; values = fn_attribute_next(attribute, &ip)) { val = (char *) malloc(values->length + 1); memcpy(val, values->contents, values->length); val[values->length] = '¥0'; printf("Value: %s", val); free(val); } fn_attribute_destroy(attribute); printf("¥n"); } fn_multigetlist_destroy(attrset); fn_ctx_destroy(initial_context); fn_status_destroy(status); fn_composite_name_destroy(name_comp); } |
次の例は、オブジェクト属性の追加、削除、変更を示しています。
#include <stdio.h> #include <xfn/xfn.h> /* このルーチンは名前付きオブジェクトに関連付けられた属性を変更する。 変更としては、 FN_ATTR_OP_ADD FN_ATTR_OP_ADD_EXCLUSIVE FN_ATTR_OP_REMOVE FN_ATTR_OP_ADD_VALUES FN_ATTR_OP_REMOVE_VALUES が有効である。この関数は属性値が文字列であることを前提とする。 関数の使用例として、以下に "James Smith" という値を持つ識別子 "realname" の属性を、ユーザーオブジェクト "user/jsmith" に追加する。 fns_attr_modify( "user/jsmith", "realname", "James Smith", FN_ATTR_OP_ADD); 次の関数は識別子 "location" の属性をプリンタオブジェクト "thisorgunit/service/printer/color" から削除する。 fns_attr_modify( "thisorgunit/service/printer/color", "location", NULL, FN_ATTR_OP_REMOVE); */ static const char *attr_id_syntax = "fn_attr_syntax_ascii"; void fns_attr_modify(const char *name, const char *attr_id, const char *attr_value, unsigned int operation) { FN_composite_name_t *name_comp; FN_identifier_t identifier, syntax; FN_attrvalue_t *values; FN_attribute_t *attribute; FN_status_t *status; FN_ctx_t *initial_context; name_comp = fn_composite_name_from_str((unsigned char *) name); status = fn_status_create(); /* 初期コンテキストの獲得 */ initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context¥n"); return; } /* 追加する属性の作成 */ /* 最初に識別子 */ identifier.format = FN_ID_STRING; identifier.length = strlen(attr_id); identifier.contents = (void *) strdup(attr_id); /* 次に構文 */ syntax.format = FN_ID_STRING; syntax.length = strlen(attr_id_syntax); syntax.contents = (void *) strdup(attr_id_syntax); /* 次に属性値 */ if (attr_value) { values = (FN_attrvalue_t *) malloc(sizeof(FN_attrvalue_t)); values->length = strlen(attr_value); values->contents = (void *) strdup(attr_value); } else values = NULL; /* 次に属性の作成 */ attribute = fn_attribute_create(&identifier, &syntax); /*次に属性値の追加 */ if (values) fn_attribute_add(attribute, values, 0); /* XFN オペレーションの実行 */ fn_attr_modify(initial_context, name_comp, operation, attribute, 0, status); if (!fn_status_is_success(status)) fprintf(stderr, "Unable to perform attribute operation¥n"); fn_ctx_destroy(initial_context); fn_status_destroy(status); fn_composite_name_destroy(name_comp); fn_attibute_destroy(attribute); free(identifier.contents); free(syntax.contents); if (values) { free(values->contents); free(values); ] ] |
次の例は、特定の属性識別子と値によって、コンテキスト内のオブジェクトを検索する方法を示しています。
#include <stdio.h> #include <xfn/xfn.h> #include <string.h> #include <stdlib.h> /* このルーチンは、指定された属性識別子と値を持つコンテキスト内の オブジェクトを検索します。 */ typedef struct fns_search_results { char *name; struct fns_search_results *next; } fns_search_results; static const char *attr_id_syntax = "fn_attr_syntax_ascii"; fns_search_results * fns_attr_search(const char *name, const char *attr_id, const char *attr_value) { FN_status_t *status; FN_ctx_t *initial_context; FN_composite_name_t *context_name; FN_searchlist_t *search_list; FN_string_t *search_name; FN_attribute_t *attribute; FN_attrset_t *attrset; FN_identifier_t identifier, syntax; FN_attrvalue_t *values; unsigned stat; fns_search_results *head = 0, *current, *prev; int no_names = 0; context_name = fn_composite_name_from_str((unsigned char *) name); status = fn_status_create(); initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context¥n"); return (0); } /* 検索する属性を持つ attrset のコンストラクト */ /* 最初に識別子 */ identifier.format = FN_ID_STRING; identifier.length = strlen(attr_id); identifier.contents = (void *) strdup(attr_id); /* 次に構文 */ syntax.format = FN_ID_STRING; syntax.length = strlen(attr_id_syntax); syntax.contents = (void *) strdup(attr_id_syntax); /* 次に属性値 */ values = (FN_attrvalue_t *) malloc(sizeof(FN_attrvalue_t)); values->length = strlen(attr_value); values->contents = (void *) strdup(attr_value); /* 次に属性の作成 */ attribute = fn_attribute_create(&identifier, &syntax); /* 次に属性値の作成 */ fn_attribute_add(attribute, values, 0); /* 次に attrset の作成と属性の追加 */ attrset = fn_attrset_create(); fn_attrset_add(attrset, attribute, 0); search_list = prelim_fn_attr_search(initial_context, context_name, attrset, 0, 0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to list names¥n"); return (0); } while (search_name = prelim_fn_searchlist_next(search_list, 0, 0, status)) { no_names++; current = (fns_search_results *) malloc(sizeof(fns_search_results)); current->name = (char *) malloc(strlen((char *) fn_string_str(search_name, &stat)) + 1); strcpy(current->name, (char *) fn_string_str(search_name, &stat)); current->next = 0; if (head) { prev->next = current; prev = current; } else { head = current; prev = current; } fn_string_destroy(search_name); } fn_searchlist_destroy(search_list); fn_status_destroy(status); fn_ctx_destroy(initial_context); fn_attrset_destroy(attrset); fn_attribute_destroy(attribute); free(identifier.contents); free(syntax.contents); free(values->contents); free(values); return (head); } |