Avoid warnings.
[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   size_t i = 0;
37
38   buffer[0] = '\0';
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 ((size_t) diff >= buflen)
79     {
80       errno = ERANGE;
81       return NULL;
82     }
83   memcpy (buffer, name, diff - 1);
84   buffer[diff - 1] = '\0';
85
86   if (diff - 1 == 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   size_t cptr_len;
105
106   cptr = strchr (name, '.');    /* XXX What happens if the NIS name
107                                    does not contain a `.'?  */
108   ++cptr;
109   cptr_len = strlen (cptr);
110
111   if (cptr_len == 0)
112     strcpy (buffer, ".");
113   else if (cptr_len >= buflen)
114     {
115       errno = ERANGE;
116       return NULL;
117     }
118   else
119     memcpy (buffer, cptr, cptr_len + 1);
120
121   return buffer;
122 }
123
124 static int
125 count_dots (const nis_name str)
126 {
127   int count = 0;
128   size_t i;
129
130   for (i = 0; i < strlen (str); ++i)
131     if (str[i] == '.')
132       ++count;
133
134   return count;
135 }
136
137 nis_name *
138 nis_getnames (const nis_name name)
139 {
140   nis_name *getnames = NULL;
141   char local_domain[NIS_MAXNAMELEN + 1];
142   char *path, *cp;
143   int count, pos;
144
145
146   strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
147   local_domain[NIS_MAXNAMELEN] = '\0';
148
149   count = 1;
150   if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
151       return NULL;
152
153   /* Do we have a fully qualified NIS+ name ? If yes, give it back */
154   if (name[strlen (name) - 1] == '.')
155     {
156       if ((getnames[0] = strdup (name)) == NULL)
157         {
158           free (getnames);
159           return NULL;
160         }
161       getnames[1] = NULL;
162
163       return getnames;
164     }
165
166   /* Get the search path, where we have to search "name" */
167   path = getenv ("NIS_PATH");
168   if (path == NULL)
169     path = strdupa ("$");
170   else
171     path = strdupa (path);
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               if (tmp == NULL)
193                 return NULL;
194
195               getnames[pos] = tmp;
196               tmp = stpcpy (tmp, name);
197               *tmp++ = '.';
198               stpcpy (tmp, cptr);
199
200               ++pos;
201
202               while (*cptr != '.')
203                 ++cptr;
204               ++cptr;
205             }
206         }
207       else
208         {
209           char *tmp;
210
211           if (cp[strlen (cp) - 1] == '$')
212             {
213               tmp = malloc (strlen (cp) + strlen (local_domain) +
214                             strlen (name) + 2);
215               if (tmp == NULL)
216                 return NULL;
217
218               tmp = stpcpy (tmp, name);
219               *tmp++ = '.';
220               tmp = stpcpy (tmp, cp);
221               --tmp;
222               if (tmp[-1] != '.')
223                 *tmp++ = '.';
224               stpcpy (tmp, local_domain);
225             }
226           else
227             {
228               tmp = malloc (strlen (cp) + strlen (name) + 2);
229               if (tmp == NULL)
230                 return NULL;
231
232               tmp = stpcpy (tmp, name);
233               *tmp++ = '.';
234               stpcpy (tmp, cp);
235             }
236
237           if (pos > count)
238             {
239               count += 5;
240               getnames = realloc (getnames, (count + 1) * sizeof (char *));
241               if (getnames == NULL)
242                 return NULL;
243             }
244           getnames[pos] = tmp;
245           ++pos;
246         }
247       cp = strtok (NULL, ":");
248     }
249
250   getnames[pos] = NULL;
251
252   return getnames;
253 }
254
255 void
256 nis_freenames (nis_name *names)
257 {
258   int i = 0;
259
260   while (names[i] != NULL)
261     {
262       free (names[i]);
263       ++i;
264     }
265
266   free (names);
267 }
268
269 name_pos
270 nis_dir_cmp (const nis_name n1, const nis_name n2)
271 {
272   int len1, len2;
273
274   len1 = strlen (n1);
275   len2 = strlen (n2);
276
277   if (len1 == len2)
278     {
279       if (strcmp (n1, n2) == 0)
280         return SAME_NAME;
281       else
282         return NOT_SEQUENTIAL;
283     }
284
285   if (len1 < len2)
286     {
287       if (n2[len2 - len1 - 1] != '.')
288         return NOT_SEQUENTIAL;
289       else if (strcmp (&n2[len2 - len1], n1) == 0)
290         return HIGHER_NAME;
291       else
292         return NOT_SEQUENTIAL;
293     }
294   else
295     {
296       if (n1[len1 - len2 - 1] != '.')
297         return NOT_SEQUENTIAL;
298       else if (strcmp (&n1[len1 - len2], n2) == 0)
299         return LOWER_NAME;
300       else
301         return NOT_SEQUENTIAL;
302
303     }
304 }
305
306 void
307 nis_destroy_object (nis_object *obj)
308 {
309   nis_free_object (obj);
310 }