ns_fnreaddir.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*
* Copyright (c) 1995 - 1996, by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "automount.h"
#include "ns_fnutils.h"
/*
* Given the name of an XFN map, create a list of the map entries for a
* given user. Set error to zero on success.
*
* extern void
* getmapkeys_fn(const char *map, struct dir_entry **, int *error,
* int *cache_time, uid_t);
*/
/*
* Given a multi-component composite name, construct the corresponding
* context handle and the context handle of its prefix. The prefix is
* that part of the name up to (and possibly including) the last slash
* in the name. Return zero on success.
*
*/
static int
/*
* Split a multi-component composite name into its last component and
* its other components. Return zero on success.
*/
static int
/*
* Given a context and its prefix context (defined above), determine
* whether the context, its NNS context, or both should be listed.
* (The syntaxes of the contexts are used to help make this
* determination.) Add the subdirectories of the appropriate
* context(s) to the dir_entry list. Return zero on success.
*
* "ls /xfn/.../c=us" => list context and NNS
*/
static int
FN_status_t *);
/*
* Given a context and its prefix context (defined above), return true
* if the NNS of the context should be listed but the context itself
* should not.
*/
static bool_t
/*
* Return true if both the given context and its NNS should be listed.
*/
static bool_t
/*
* Add the subdirectories of a context to the dir_entry list. Return
* zero on success.
*/
static int
/*
* Given a context and its name relative to the root of its rightmost
* naming system, add the context's subdirectories to the dir_entry
* list. If syntax is non-NULL recursively list names until a context
* with a different syntax is encountered, otherwise list one level
* only. May modify "name". Return zero on success.
*
* the compound name "eng" would be passed in, and the following might
* be added to the dir_entry list:
* ssi.eng
* feds.ssi.eng
* ste.eng
*/
static int
struct dir_entry **, FN_status_t *);
/*
* Add a name to a dir_entry list. Return zero on success.
*/
static int
/*
* Return true if a set of syntax attributes correspond to a
* hierarchical namespace with a slash separator. Return false on
* error.
*/
static bool_t
/*
* Return true if a set of syntax attributes correspond to a
* hierarchical namespace with a separator other than a slash.
* Return false on error.
*/
static bool_t
/*
* Return true if two syntax attribute sets are equal.
*/
static bool_t
/*
* Return a value of a given attribute in an attribute set, or NULL
* on error.
*/
static const FN_attrvalue_t *
/*
* Lookup a name and return the corresponding context handle. On
* error return NULL and, if "log" is true or the error is transient,
* log an error message.
*/
static FN_ctx_t *
/*
* Unlike during a lookup or mount, transient errors are tolerated. A
* potentially transient error during a readdir() (such as no response
* from an X.500 server) could result in an incomplete listing, but at
* least readdir() will return everything that it can. Note that it
* is still possible to mount a directory that for some reason did not
* show up in a prior readdir().
*/
void
{
struct dir_entry *p;
*error = -1;
return;
}
return;
}
/*
* List the initial context.
* Contents of initial ctx is user-relative
*/
*cache_time = 0;
/* Cannot list DNS; report success but no entries. */
*error = 0;
} else {
/* List X.500 but not DNS. */
} else {
}
*error = -1;
/* List an atomic name. */
} else {
*error = -1;
}
} else {
/* List a multi-component name. */
if (*error == 0) {
}
}
}
if (*error == 0) {
/*
* create the binary tree of entries
*/
btree_enter(entries_p, p);
}
}
static int
{
/*
* can be more efficient than doing it the reverse order.
*/
return (-1);
}
if (*prefix_ctxp != NULL) {
*prefix_ctxp = nns_ctx;
} else {
}
}
*ctxp =
}
}
}
static int
{
void *iter;
return (-1);
}
return (0);
}
static int
{
int rc;
return (-1);
}
return (0);
}
}
return (0);
}
return (rc);
}
/*
* True if ctx has a hierarchical syntax with a non-slash separator
* and prefix_ctx either has the same syntax or does not provide any
* syntax ("..." should be the only example of the latter condition).
*/
static bool_t
{
return (FALSE);
}
/*
* ctx is hierarchical and not slash-separated. How about prefix_ctx?
*/
return (retval);
}
/*
* True if ctx has a slash-separated hierarchical syntax.
*/
static bool_t
{
return (FALSE);
}
return (retval);
}
static int
{
int retval;
return (-1);
}
name =
return (-1);
}
if (!non_slash_hierarchy(syntax)) {
}
return (retval);
}
static int
{
unsigned int stat;
int rc = 0;
void *iter;
return (0);
}
rc = -1;
break;
}
rc = -1;
break;
}
/* Traverse hierarchy. */
status);
if (rc != 0) {
break;
}
}
}
}
return (rc);
}
static int
{
char *str;
unsigned int stat;
return (-1);
}
}
return (-1);
}
/* LINTED pointer alignment */
auto_rddir_malloc(sizeof (*entry));
return (-1);
}
return (0);
}
/*
* Identifiers of syntax attributes for direction and separator.
*/
static const FN_identifier_t syntax_direction = {
sizeof ("fn_std_syntax_direction") - 1,
"fn_std_syntax_direction"
};
static const FN_identifier_t syntax_separator = {
sizeof ("fn_std_syntax_separator") - 1,
"fn_std_syntax_separator"
};
static bool_t
{
}
static bool_t
{
}
static bool_t
{
const FN_attribute_t *attr;
const FN_attrvalue_t *val1;
const FN_attrvalue_t *val2;
void *iter1;
void *iter2;
return (FALSE);
}
return (FALSE);
}
return (FALSE);
}
}
}
return (TRUE);
}
static const FN_attrvalue_t *
{
const FN_attribute_t *attr;
void *iter;
} else {
return (NULL);
}
}
static FN_ctx_t *
{
char *msg;
msg = "lookup failed";
} else {
msg = "could not construct context handle";
}
}
}
return (ctx);
}