Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
  Previous   Contents   Next 
   
 
Chapter 3

XFN Programming Examples

This chapter presents self-contained executable programs for the following programs:

  • A namespace browser

  • A printer client and server

  • A tool to populate attributes of users.

Namespace Browser Example

Figure 3-1illustrates the XFN APIs that are used by the browser application.

Figure 3-1 Diagram of fnbrowse Program

The first example is a browser that lists all names that it finds in the namespace. When the program is invoked, the browser is set at the initial context or the composite name given on the command line.

See "Commands"and "Sample Output".


Example 3-1 fnbrowse Source

/*
 * fnbrowse.c -- FNS namespace browser.
 *
 * To keep this example program relatively short,
 * limited error checking is done.
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xfn/xfn.h>
 
 
#define LINELEN 128    /* maximum length of input line */
 
typedef enum {CMD_DOWN, CMD_UP, CMD_LIST, CMD_SHOW, CMD_QUIT} command;
 
static FN_status_t *status;
static unsigned 	int auth = 0; /* non-authoritative */
 
 
/* Lookup a context named relative to the initial context. */
FN_ctx_t *lookup(const FN_composite_name_t *name);
 
/* Set the browser's focus to the given context. */
void browse(FN_ctx_t *ctx);
 
/* Set the browser's focus to a subcontext of the given context. */
void cmd_down(FN_ctx_t *ctx, const FN_composite_name_t *child);
 
/* Print the names bound within a context. */
void cmd_list(FN_ctx_t *ctx);
 
/*
 * Print a description of the reference bound to "child" in the
 * given context or, if "child" is the empty string, the reference
 * of the context itself.
 */
void cmd_show(FN_ctx_t *ctx, const FN_composite_name_t *child);
 
/*
 * Read and parse the next command typed by the user.  If the
 * command has an argument, set *argp to point to the argument.
 */
command read_command(FN_string_t **argp);
 
/* Print an error message, and the description associated
 * with "status". 
 */
void error(const char *msg);
 
 
int
main(int argc, char *argv[])
{
	    unsigned char	*target;
 
	    switch (argc) {
    case 1:
        target = (unsigned char *)"";
        break;
    case 2:
        target = (unsigned char *)argv[1];
        break;
    default:
        fprintf(stderr, "Usage: %s [<composite_name>]\n",
             argv[0]);
        return (1);
	}
 
    status = fn_status_create();
 
    browse(lookup(fn_composite_name_from_str(target)));
    return (0);
}
 
 
FN_ctx_t *
lookup(const FN_composite_name_t *name)
{
    FN_ctx_t	*ctx;
    FN_ref_t	*ref;
 
    ctx = fn_ctx_handle_from_initial(auth, status);
    if (ctx == NULL) {
       error("Could not construct initial context");
       exit(1);
    }
    if (fn_composite_name_is_empty(name)) {
        return (ctx);
    }
    ref = fn_ctx_lookup(ctx, name, status);
    fn_ctx_handle_destroy(ctx);
    if (ref == NULL) {
       error("Lookup failed");
       exit(1);
    }
    ctx = fn_ctx_handle_from_ref(ref, auth, status);
    fn_ref_destroy(ref);
    if (ctx == NULL) {
       error("Could not construct context handle");
       exit(1);
    }
    return (ctx);
}
 
 
void
browse(FN_ctx_t *ctx)
{
  FN_string_t		*arg;
  FN_composite_name_t	*child;
 
  while (1) {
     switch (read_command(&arg)) {
     case CMD_DOWN:
        child = fn_composite_name_from_string(arg);
        fn_string_destroy(arg);
			  cmd_down(ctx, child);
        fn_composite_name_destroy(child);
        break;
     case CMD_UP:
        return;
     case CMD_LIST:
        cmd_list(ctx);
        break;
     case CMD_SHOW:
        child = fn_composite_name_from_string(arg);
        fn_string_destroy(arg);
        cmd_show(ctx, child);
        fn_composite_name_destroy(child);
        break;
     case CMD_QUIT:
        exit(0);
     }
   }
}
 
 
void
cmd_down(FN_ctx_t *ctx, const FN_composite_name_t *child)
{
  FN_ref_t	*ref;
  FN_ctx_t	*subctx;
 
  ref = fn_ctx_lookup(ctx, child, status);
  if (ref == NULL) {
      error("Lookup failed");
      return;
  }
  subctx = fn_ctx_handle_from_ref(ref, auth, status);
  fn_ref_destroy(ref);
	  if (subctx == NULL) {
      error("Could not construct context handle");
      return;
  }
  browse(subctx);
  fn_ctx_handle_destroy(subctx);
}
 
 
void
cmd_list(FN_ctx_t *ctx)
{
  FN_string_t		*empty_string = fn_string_create();
  FN_composite_name_t	*empty_name;
  FN_namelist_t		*children;
  FN_string_t		*child;
  unsigned intstatcode;
  int  has_children = 0;
 
  empty_name = fn_composite_name_from_string(empty_string);
  fn_string_destroy(empty_string);
 
  children = fn_ctx_list_names(ctx, empty_name, status);
  fn_composite_name_destroy(empty_name);
 
  if (children == NULL) {
      error("Could not list names");
      return;
	}
  while ((child = fn_namelist_next(children, status))
    != NULL) {
    has_children = 1;
    printf("%s  ", fn_string_str(child, &statcode));
    fn_string_destroy(child);
  }
  if (has_children) {
      printf("\n");
  }
  fn_namelist_destroy(children);
}
 
 
void
cmd_show(FN_ctx_t *ctx, const FN_composite_name_t *child)
{
    FN_string_t	*desc;
    FN_ref_t	*ref;
    unsigned int	statcode;
 
    ref = fn_ctx_lookup(ctx, child, status);
    if (ref == NULL) {
        error("Lookup failed");
        return;
    }
 
    desc = fn_ref_description(ref, 2, NULL);
    fn_ref_destroy(ref);
    if (desc != NULL) {
        printf("%s", fn_string_str(desc, &statcode));
        fn_string_destroy(desc);
    } else {
        printf("[No description]\n");
	    }
}
 
 
command
read_command(FN_string_t **argp)
{
     char	buf[LINELEN + 1];
     char  *cmd;
     char  *child;
 
     while (printf("\n> "), fflush(stdout), gets(buf) != NULL) {
        cmd = strtok(buf, " \t");
        if (cmd == NULL) {
            continue;
		     }
        if (strcmp(cmd, "down") == 0) {
           child = strtok(NULL, " \t");
           if (child != NULL) {
              *argp =
                  fn_string_from_str((unsigned char *)child);
              return (CMD_DOWN);
           }
        }
        if (strcmp(cmd, "up") == 0) {
           return (CMD_UP);
        }
        if (strcmp(cmd, "list") == 0) {
           return (CMD_LIST);
        }
        if (strcmp(cmd, "show") == 0) {
           child = strtok(NULL, " \t");
           *argp = (child != NULL)
               ? fn_string_from_str((unsigned char *)child)
               : fn_string_create();
           return (CMD_SHOW);
        }
        if (strcmp(cmd, "quit") == 0) {
           return (CMD_QUIT);
		    }
       fprintf(stderr, "Valid commands are:  "
           "down <child>, up, list, show [<child>], quit\n");
    }
    return (CMD_QUIT);	/* EOF */
}
 
 
void
error(const char *msg)
{
    FN_string_t	*reason;
    unsigned int	statcode;
 
    fprintf(stderr, "%s", msg);
    reason = fn_status_description(status, 0, NULL);
    if (reason != NULL) {
        fprintf(stderr, ": %s",
            (const char *)fn_string_str(reason, &statcode));
        fn_string_destroy(reason);
    }
    fprintf(stderr, "\n");
}

 
 
 
  Previous   Contents   Next