source: trunk/third/sendmail/libsm/niprop.c @ 19204

Revision 19204, 4.7 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2001 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 *
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.
8 */
9
10#include <sm/gen.h>
11SM_RCSID("@(#)$Id: niprop.c,v 1.1.1.1 2003-04-08 15:06:04 zacheiss Exp $")
12
13#if NETINFO
14#include <ctype.h>
15#include <stdlib.h>
16#include <sm/io.h>
17#include <sm/assert.h>
18#include <sm/debug.h>
19#include <sm/string.h>
20#include <sm/varargs.h>
21#include <sm/heap.h>
22
23/*
24**  NI_PROPVAL -- NetInfo property value lookup routine
25**
26**      Parameters:
27**              keydir -- the NetInfo directory name in which to search
28**                      for the key.
29**              keyprop -- the name of the property in which to find the
30**                      property we are interested.  Defaults to "name".
31**              keyval -- the value for which we are really searching.
32**              valprop -- the property name for the value in which we
33**                      are interested.
34**              sepchar -- if non-nil, this can be multiple-valued, and
35**                      we should return a string separated by this
36**                      character.
37**
38**      Returns:
39**              NULL -- if:
40**                      1. the directory is not found
41**                      2. the property name is not found
42**                      3. the property contains multiple values
43**                      4. some error occurred
44**              else -- the value of the lookup.
45**
46**      Example:
47**              To search for an alias value, use:
48**                ni_propval("/aliases", "name", aliasname, "members", ',')
49**
50**      Notes:
51**              Caller should free the return value of ni_proval
52*/
53
54# include <netinfo/ni.h>
55
56# define LOCAL_NETINFO_DOMAIN   "."
57# define PARENT_NETINFO_DOMAIN  ".."
58# define MAX_NI_LEVELS          256
59
60char *
61ni_propval(keydir, keyprop, keyval, valprop, sepchar)
62        char *keydir;
63        char *keyprop;
64        char *keyval;
65        char *valprop;
66        int sepchar;
67{
68        char *propval = NULL;
69        int i;
70        int j, alen, l;
71        void *ni = NULL;
72        void *lastni = NULL;
73        ni_status nis;
74        ni_id nid;
75        ni_namelist ninl;
76        register char *p;
77        char keybuf[1024];
78
79        /*
80        **  Create the full key from the two parts.
81        **
82        **      Note that directory can end with, e.g., "name=" to specify
83        **      an alternate search property.
84        */
85
86        i = strlen(keydir) + strlen(keyval) + 2;
87        if (keyprop != NULL)
88                i += strlen(keyprop) + 1;
89        if (i >= sizeof keybuf)
90                return NULL;
91        (void) sm_strlcpyn(keybuf, sizeof keybuf, 2, keydir, "/");
92        if (keyprop != NULL)
93        {
94                (void) sm_strlcat2(keybuf, keyprop, "=", sizeof keybuf);
95        }
96        (void) sm_strlcat(keybuf, keyval, sizeof keybuf);
97
98#if 0
99        if (tTd(38, 21))
100                sm_dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
101                        keydir, keyprop, keyval, valprop, sepchar, keybuf);
102#endif /* 0 */
103
104        /*
105        **  If the passed directory and property name are found
106        **  in one of netinfo domains we need to search (starting
107        **  from the local domain moving all the way back to the
108        **  root domain) set propval to the property's value
109        **  and return it.
110        */
111
112        for (i = 0; i < MAX_NI_LEVELS && propval == NULL; i++)
113        {
114                if (i == 0)
115                {
116                        nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
117#if 0
118                        if (tTd(38, 20))
119                                sm_dprintf("ni_open(LOCAL) = %d\n", nis);
120#endif /* 0 */
121                }
122                else
123                {
124                        if (lastni != NULL)
125                                ni_free(lastni);
126                        lastni = ni;
127                        nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
128#if 0
129                        if (tTd(38, 20))
130                                sm_dprintf("ni_open(PARENT) = %d\n", nis);
131#endif /* 0 */
132                }
133
134                /*
135                **  Don't bother if we didn't get a handle on a
136                **  proper domain.  This is not necessarily an error.
137                **  We would get a positive ni_status if, for instance
138                **  we never found the directory or property and tried
139                **  to open the parent of the root domain!
140                */
141
142                if (nis != 0)
143                        break;
144
145                /*
146                **  Find the path to the server information.
147                */
148
149                if (ni_pathsearch(ni, &nid, keybuf) != 0)
150                        continue;
151
152                /*
153                **  Find associated value information.
154                */
155
156                if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0)
157                        continue;
158
159#if 0
160                if (tTd(38, 20))
161                        sm_dprintf("ni_lookupprop: len=%d\n",
162                                ninl.ni_namelist_len);
163#endif /* 0 */
164
165                /*
166                **  See if we have an acceptable number of values.
167                */
168
169                if (ninl.ni_namelist_len <= 0)
170                        continue;
171
172                if (sepchar == '\0' && ninl.ni_namelist_len > 1)
173                {
174                        ni_namelist_free(&ninl);
175                        continue;
176                }
177
178                /*
179                **  Calculate number of bytes needed and build result
180                */
181
182                alen = 1;
183                for (j = 0; j < ninl.ni_namelist_len; j++)
184                        alen += strlen(ninl.ni_namelist_val[j]) + 1;
185                propval = p = sm_malloc(alen);
186                if (propval == NULL)
187                        goto cleanup;
188                for (j = 0; j < ninl.ni_namelist_len; j++)
189                {
190                        (void) sm_strlcpy(p, ninl.ni_namelist_val[j], alen);
191                        l = strlen(p);
192                        p += l;
193                        *p++ = sepchar;
194                        alen -= l + 1;
195                }
196                *--p = '\0';
197
198                ni_namelist_free(&ninl);
199        }
200
201  cleanup:
202        if (ni != NULL)
203                ni_free(ni);
204        if (lastni != NULL && ni != lastni)
205                ni_free(lastni);
206#if 0
207        if (tTd(38, 20))
208                sm_dprintf("ni_propval returns: '%s'\n", propval);
209#endif /* 0 */
210
211        return propval;
212}
213#endif /* NETINFO */
Note: See TracBrowser for help on using the repository browser.