Solaris ネーミングの管理

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

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