Add NIS+ functions
[kopensolaris-gnu/glibc.git] / nis / nis_subr.c
1 /* Copyright (c) 1997 Free Software Foundation, Inc.
2
3    This file is part of the GNU C Library.
4    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include <errno.h>
22 #include <string.h>
23 #include <rpcsvc/nis.h>
24 #include <rpcsvc/nislib.h>
25
26 nis_name
27 nis_leaf_of (const nis_name name)
28 {
29   static char result[NIS_MAXNAMELEN + 1];
30
31   return nis_leaf_of_r (name, result, NIS_MAXNAMELEN);
32 }
33
34 nis_name
35 nis_leaf_of_r (const nis_name name, char *buffer, size_t buflen)
36 {
37   int i = 0;
38
39   memset (buffer, '\0', buflen);
40
41   while (name[i] != '.' && name[i] != '\0')
42     i++;
43
44   if (i > buflen - 1)
45     {
46       errno = ERANGE;
47       return NULL;
48     }
49
50   if (i > 1)
51     strncpy (buffer, name, i - 1);
52
53   return buffer;
54 }
55
56 nis_name
57 nis_name_of (const nis_name name)
58 {
59   static char result[NIS_MAXNAMELEN + 1];
60
61   return nis_name_of_r (name, result, NIS_MAXNAMELEN);
62 }
63
64 nis_name
65 nis_name_of_r (const nis_name name, char *buffer, size_t buflen)
66 {
67   char *local_domain;
68   int diff;
69
70   local_domain = nis_local_directory ();
71
72   diff = strlen (name) - strlen (local_domain);
73   if (diff <= 0)
74     return NULL;
75
76   if (strcmp (&name[diff], local_domain) != 0)
77     return NULL;
78
79   if (diff >= buflen)
80     {
81       errno = ERANGE;
82       return NULL;
83     }
84   memset (buffer, '\0', buflen);
85   strncpy (buffer, name, diff - 1);
86
87   if (strlen (buffer) == 0)
88     return NULL;
89
90   return buffer;
91 }
92
93 nis_name
94 nis_domain_of (const nis_name name)
95 {
96   static char result[NIS_MAXNAMELEN + 1];
97
98   return nis_domain_of_r (name, result, NIS_MAXNAMELEN);
99 }
100
101 nis_name
102 nis_domain_of_r (const nis_name name, char *buffer, size_t buflen)
103 {
104   char *cptr;
105
106   cptr = strchr (name, '.');
107   cptr++;
108
109   if (strlen (cptr) == 0)
110     strcpy (buffer, ".");
111   else if (strlen (cptr) >= buflen)
112     {
113       errno = ERANGE;
114       return NULL;
115     }
116   else
117     strcpy (buffer, cptr);
118
119   return buffer;
120 }
121
122 static int
123 count_dots (const nis_name str)
124 {
125   int count = 0;
126   int i;
127
128   for (i = 0; i < strlen (str); i++)
129     if (str[i] == '.')
130       count++;
131
132   return count;
133 }
134
135 nis_name
136 * nis_getnames (const nis_name name)
137 {
138   nis_name *getnames = NULL;
139   char local_domain[NIS_MAXNAMELEN + 1];
140   char *path, *cp;
141   int count, pos;
142
143
144   strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
145   local_domain[NIS_MAXNAMELEN] = '\0';
146
147   count = 1;
148   if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
149       return NULL;
150
151   /* Do we have a fully qualified NIS+ name ? If yes, give it back */
152   if (name[strlen (name) - 1] == '.')
153     {
154       if ((getnames[0] = strdup (name)) == NULL)
155         {
156           free (getnames);
157           return NULL;
158         }
159       getnames[1] = NULL;
160
161       return getnames;
162     }
163
164   /* Get the search path, where we have to search "name" */
165   path = getenv ("NIS_PATH");
166   if (path == NULL)
167     path = strdup ("$");
168   else
169     path = strdup (path);
170   if (path == NULL)
171     return NULL;
172
173   pos = 0;
174
175   cp = strtok (path, ":");
176   while (cp)
177     {
178       if (strcmp (cp, "$") == 0)
179         {
180           char *cptr = local_domain;
181           char *tmp;
182
183           while (count_dots (cptr) >= 2)
184             {
185               if (pos >= count)
186                 {
187                   count += 5;
188                   getnames = realloc (getnames, (count + 1) * sizeof (char *));
189                 }
190               tmp = malloc (strlen (cptr) + strlen (local_domain) +
191                             strlen (name) + 2);
192
193               strcpy (tmp, name);
194               strcat (tmp, ".");
195               strcat (tmp, cptr);
196
197               getnames[pos] = tmp;
198               pos++;
199
200               while (*cptr != '.')
201                 cptr++;
202               cptr++;
203             }
204         }
205       else
206         {
207           char *tmp;
208
209           if (cp[strlen (cp) - 1] == '$')
210             {
211               tmp = malloc (strlen (cp) + strlen (local_domain) +
212                             strlen (name) + 2);
213               strcpy (tmp, name);
214               strcat (tmp, ".");
215               strcat (tmp, cp);
216               tmp[strlen (tmp) - 1] = '\0';
217               if (tmp[strlen (tmp) - 1] != '.')
218                 strcat (tmp, ".");
219               strcat (tmp, local_domain);
220             }
221           else
222             {
223               tmp = malloc (strlen (cp) + strlen (name) + 2);
224               strcpy (tmp, name);
225               strcat (tmp, ".");
226               strcat (tmp, cp);
227             }
228
229           if (pos > count)
230             {
231               count += 5;
232               getnames = realloc (getnames, (count + 1) * sizeof (char *));
233             }
234           getnames[pos] = tmp;
235           pos++;
236         }
237       cp = strtok (NULL, ":");
238     }
239
240   getnames[pos] = NULL;
241
242   free (path);
243
244   return getnames;
245 }
246
247 void
248 nis_freenames (nis_name * names)
249 {
250   int i = 0;
251
252   while (names[i] != NULL)
253     {
254       free (names[i]);
255       i++;
256     }
257
258   free (names);
259 }
260
261 name_pos
262 nis_dir_cmp (const nis_name n1, const nis_name n2)
263 {
264   int len1, len2;
265
266   len1 = strlen (n1);
267   len2 = strlen (n2);
268
269   if (len1 == len2)
270     {
271       if (strcmp (n1, n2) == 0)
272         return SAME_NAME;
273       else
274         return NOT_SEQUENTIAL;
275     }
276
277   if (len1 < len2)
278     {
279       if (n2[len2 - len1 - 1] != '.')
280         return NOT_SEQUENTIAL;
281       else if (strcmp (&n2[len2 - len1], n1) == 0)
282         return HIGHER_NAME;
283       else
284         return NOT_SEQUENTIAL;
285     }
286   else
287     {
288       if (n1[len1 - len2 - 1] != '.')
289         return NOT_SEQUENTIAL;
290       else if (strcmp (&n1[len1 - len2], n2) == 0)
291         return LOWER_NAME;
292       else
293         return NOT_SEQUENTIAL;
294
295     }
296 }
297
298 void
299 nis_destroy_object (nis_object * obj)
300 {
301   nis_free_object (obj);
302 }