The programming examples in this section shows the usage of XFN APIs to perform the following operations:
The example below shows XFN operations to list a context.
#include <stdio.h>
#include <xfn/xfn.h>
#include <string.h>
#include <stdlib.h>
/*
This routine returns the list of names
bound under the given context (ctx_name).
Examples of ctx_name are "user", "thisorgunit/service",
host/alto/service, user/jsmit/service/calendar, etc.,
*/
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();
/* Obtain the initial context */
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 call to list names */
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);
}
/* Obtain the names individually */
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);
|
Example 25–1 shows how to create a binding.
#include <stdio.h>
#include <xfn/xfn.h>
#include <string.h>
/*
This routine creates a binding with a name provided by "name"
and having a reference type "reference_type" and address type
"address_type".
An example of using the function could be:
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;
/* Obtain the initial context */
status = fn_status_create();
initial_context = fn_ctx_handle_from_initial(0, status);
/* Check status for any error messages */
if ((return_status = fn_status_code(status)) != FN_SUCCESS) {
fprintf(stderr, "Unable to obtain the initial context\n");
return (return_status);
}
/* Get the composite name for the printer name */
binding_name = fn_composite_name_from_str((unsigned char *) name);
/* Construct the Address */
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);
/* Construct the Reference */
ref_id.format = FN_ID_STRING;
ref_id.length = strlen(reference_type);
ref_id.contents = (void *) reference_type;
reference = fn_ref_create(&ref_id);
/* Add Address to the Reference */
fn_ref_append_addr(reference, address);
/* Create a binding */
fn_ctx_bind(initial_context, binding_name, reference, 0, status);
/* Check the error status and return */
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);
}
|
The examples below show techniques to list and work with attributes of an object.
The example below shows how to list the attributes of an object.
#include <stdio.h>
#include <xfn/xfn.h>
/*
This routine prints all the attributes associated
with the named object to the standard output.
Examples of using the function:
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();
/* Obtain the initial context */
initial_context = fn_ctx_handle_from_initial(0, status);
if (!fn_status_is_success(status)) {
fprintf(stderr, "Unable to obtain intial context\n");
return;
}
/* Obtain all the attributes */
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;
}
/* List all attributes */
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);
}
|
The example below shows how to add, delete, or modify an object's attributes.
#include <stdio.h>
#include <xfn/xfn.h>
/*
This routine modifies an attribute associated
with the named object. The modify operation supported are:
FN_ATTR_OP_ADD
FN_ATTR_OP_ADD_EXCLUSIVE
FN_ATTR_OP_REMOVE
FN_ATTR_OP_ADD_VALUES
FN_ATTR_OP_REMOVE_VALUES
The function assumes the attribute values to be strings.
Examples of using the function:
The following function add an attribute of identifier "realname"
with value "James Smith" to the user object "user/jsmith".
fns_attr_modify(
"user/jsmith",
"realname",
"James Smith",
FN_ATTR_OP_ADD);
The following function removes an attribute of identifier
"location" from the printer object
"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();
/* Obtain the initial context */
initial_context = fn_ctx_handle_from_initial(0, status);
if (!fn_status_is_success(status)) {
fprintf(stderr, "Unable to obtain intial context\n");
return;
}
/* Create the attribute to be added */
/* First, the identifier */
identifier.format = FN_ID_STRING;
identifier.length = strlen(attr_id);
identifier.contents = (void *) strdup(attr_id);
/* Second, the syntax */
syntax.format = FN_ID_STRING;
syntax.length = strlen(attr_id_syntax);
syntax.contents = (void *) strdup(attr_id_syntax);
/* Third, the attribute value */
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;
/* Fourth, create the attribute */
attribute = fn_attribute_create(&identifier, &syntax);
/*Fifth, add the attribute value */
if (values)
fn_attribute_add(attribute, values, 0);
/* Perform the XFN operation */
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);
]
]
|
The example below shows how to search for objects in a context with a specific attribute identifier and value.
#include <stdio.h>
#include <xfn/xfn.h>
#include <string.h>
#include <stdlib.h>
/*
This routine searchs for objects in a context
which has the specified attribute identifier and value.
*/
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);
}
/* Construnct the attrset with attributes to be searched */
/* First, the identifier */
identifier.format = FN_ID_STRING;
identifier.length = strlen(attr_id);
identifier.contents = (void *) strdup(attr_id);
/* Second, the syntax */
syntax.format = FN_ID_STRING;
syntax.length = strlen(attr_id_syntax);
syntax.contents = (void *) strdup(attr_id_syntax);
/* Third, the attribute value */
values = (FN_attrvalue_t *) malloc(sizeof(FN_attrvalue_t));
values->length = strlen(attr_value);
values->contents = (void *) strdup(attr_value);
/* Fourth, create the attribute */
attribute = fn_attribute_create(&identifier, &syntax);
/* Fifth, add the attribute value */
fn_attribute_add(attribute, values, 0);
/* Sixth, create attrset, and add the attribute */
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);
}
|