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