2 * Copyright (c) 2001 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
10 #pragma ident "%Z%%M% %I% %E% SMI"
13 SM_RCSID("@(#)$Id: niprop.c,v 1.6 2001/09/04 22:41:27 ca Exp $")
19 #include <sm/assert.h>
21 #include <sm/string.h>
22 #include <sm/varargs.h>
26 ** NI_PROPVAL -- NetInfo property value lookup routine
29 ** keydir -- the NetInfo directory name in which to search
31 ** keyprop -- the name of the property in which to find the
32 ** property we are interested. Defaults to "name".
33 ** keyval -- the value for which we are really searching.
34 ** valprop -- the property name for the value in which we
36 ** sepchar -- if non-nil, this can be multiple-valued, and
37 ** we should return a string separated by this
42 ** 1. the directory is not found
43 ** 2. the property name is not found
44 ** 3. the property contains multiple values
45 ** 4. some error occurred
46 ** else -- the value of the lookup.
49 ** To search for an alias value, use:
50 ** ni_propval("/aliases", "name", aliasname, "members", ',')
53 ** Caller should free the return value of ni_proval
56 # include <netinfo/ni.h>
58 # define LOCAL_NETINFO_DOMAIN "."
59 # define PARENT_NETINFO_DOMAIN ".."
60 # define MAX_NI_LEVELS 256
63 ni_propval(keydir
, keyprop
, keyval
, valprop
, sepchar
)
82 ** Create the full key from the two parts.
84 ** Note that directory can end with, e.g., "name=" to specify
85 ** an alternate search property.
88 i
= strlen(keydir
) + strlen(keyval
) + 2;
90 i
+= strlen(keyprop
) + 1;
91 if (i
>= sizeof keybuf
)
93 (void) sm_strlcpyn(keybuf
, sizeof keybuf
, 2, keydir
, "/");
96 (void) sm_strlcat2(keybuf
, keyprop
, "=", sizeof keybuf
);
98 (void) sm_strlcat(keybuf
, keyval
, sizeof keybuf
);
102 sm_dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
103 keydir
, keyprop
, keyval
, valprop
, sepchar
, keybuf
);
107 ** If the passed directory and property name are found
108 ** in one of netinfo domains we need to search (starting
109 ** from the local domain moving all the way back to the
110 ** root domain) set propval to the property's value
114 for (i
= 0; i
< MAX_NI_LEVELS
&& propval
== NULL
; i
++)
118 nis
= ni_open(NULL
, LOCAL_NETINFO_DOMAIN
, &ni
);
121 sm_dprintf("ni_open(LOCAL) = %d\n", nis
);
129 nis
= ni_open(lastni
, PARENT_NETINFO_DOMAIN
, &ni
);
132 sm_dprintf("ni_open(PARENT) = %d\n", nis
);
137 ** Don't bother if we didn't get a handle on a
138 ** proper domain. This is not necessarily an error.
139 ** We would get a positive ni_status if, for instance
140 ** we never found the directory or property and tried
141 ** to open the parent of the root domain!
148 ** Find the path to the server information.
151 if (ni_pathsearch(ni
, &nid
, keybuf
) != 0)
155 ** Find associated value information.
158 if (ni_lookupprop(ni
, &nid
, valprop
, &ninl
) != 0)
163 sm_dprintf("ni_lookupprop: len=%d\n",
164 ninl
.ni_namelist_len
);
168 ** See if we have an acceptable number of values.
171 if (ninl
.ni_namelist_len
<= 0)
174 if (sepchar
== '\0' && ninl
.ni_namelist_len
> 1)
176 ni_namelist_free(&ninl
);
181 ** Calculate number of bytes needed and build result
185 for (j
= 0; j
< ninl
.ni_namelist_len
; j
++)
186 alen
+= strlen(ninl
.ni_namelist_val
[j
]) + 1;
187 propval
= p
= sm_malloc(alen
);
190 for (j
= 0; j
< ninl
.ni_namelist_len
; j
++)
192 (void) sm_strlcpy(p
, ninl
.ni_namelist_val
[j
], alen
);
200 ni_namelist_free(&ninl
);
206 if (lastni
!= NULL
&& ni
!= lastni
)
210 sm_dprintf("ni_propval returns: '%s'\n", propval
);