Solaris のシステム管理 (ネーミングとディレクトリサービス : FNS、NIS+ 編)

名前空間ブラウザのプログラムの例

この節のプログラミング例は、次の操作を実行するための 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);

割り当ての作成

例 25-1 は、割り当ての作成方法を示しています。


例 25-1 割り当ての作成


#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);
}