1998-10-26 Roland McGrath <roland@baalperazim.frob.com>
[glibc.git] / nis / nis_subr.c
blob3283e4cf939863b87abaf7a19a549e02b1c0ca1f
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.
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.
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.
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. */
20 #include <errno.h>
21 #include <string.h>
22 #include <rpcsvc/nis.h>
24 nis_name
25 nis_leaf_of (const_nis_name name)
27 static char result[NIS_MAXNAMELEN + 1];
29 return nis_leaf_of_r (name, result, NIS_MAXNAMELEN);
32 nis_name
33 nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen)
35 size_t i = 0;
37 buffer[0] = '\0';
39 while (name[i] != '.' && name[i] != '\0')
40 i++;
42 if (i > buflen - 1)
44 errno = ERANGE;
45 return NULL;
48 if (i > 0)
50 if ((size_t)i >= buflen)
52 errno = ERANGE;
53 return NULL;
55 strncpy (buffer, name, i);
56 buffer[i] = 0;
59 return buffer;
62 nis_name
63 nis_name_of (const_nis_name name)
65 static char result[NIS_MAXNAMELEN + 1];
67 return nis_name_of_r (name, result, NIS_MAXNAMELEN);
70 nis_name
71 nis_name_of_r (const_nis_name name, char *buffer, size_t buflen)
73 char *local_domain;
74 int diff;
76 local_domain = nis_local_directory ();
78 diff = strlen (name) - strlen (local_domain);
79 if (diff <= 0)
80 return NULL;
82 if (strcmp (&name[diff], local_domain) != 0)
83 return NULL;
85 if ((size_t) diff >= buflen)
87 errno = ERANGE;
88 return NULL;
90 memcpy (buffer, name, diff - 1);
91 buffer[diff - 1] = '\0';
93 if (diff - 1 == 0)
94 return NULL;
96 return buffer;
99 static int
100 count_dots (const_nis_name str)
102 int count = 0;
103 size_t i;
105 for (i = 0; i < strlen (str); ++i)
106 if (str[i] == '.')
107 ++count;
109 return count;
112 nis_name *
113 nis_getnames (const_nis_name name)
115 nis_name *getnames = NULL;
116 char local_domain[NIS_MAXNAMELEN + 1];
117 char *path, *cp;
118 int count, pos, have_point;
120 strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
121 local_domain[NIS_MAXNAMELEN] = '\0';
123 count = 1;
124 if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
125 return NULL;
127 /* Do we have a fully qualified NIS+ name ? If yes, give it back */
128 if (name[strlen (name) - 1] == '.')
130 if ((getnames[0] = strdup (name)) == NULL)
132 free (getnames);
133 return NULL;
135 getnames[1] = NULL;
137 return getnames;
140 /* Get the search path, where we have to search "name" */
141 path = getenv ("NIS_PATH");
142 if (path == NULL)
143 path = strdupa ("$");
144 else
145 path = strdupa (path);
147 have_point = (strchr (name, '.') != NULL);
149 pos = 0;
151 cp = strtok (path, ":");
152 while (cp)
154 if (strcmp (cp, "$") == 0)
156 char *cptr = local_domain;
157 char *tmp;
159 while ((have_point && *cptr != '\0') || (count_dots (cptr) >= 2))
161 if (pos >= count)
163 count += 5;
164 getnames = realloc (getnames, (count + 1) * sizeof (char *));
166 tmp = malloc (strlen (cptr) + strlen (local_domain) +
167 strlen (name) + 2);
168 if (tmp == NULL)
169 return NULL;
171 getnames[pos] = tmp;
172 tmp = stpcpy (tmp, name);
173 *tmp++ = '.';
174 if (cptr[1] != '\0')
175 stpcpy (tmp, cptr);
176 else
177 ++cptr;
179 ++pos;
181 while (*cptr != '.' && *cptr != '\0')
182 ++cptr;
183 if (cptr[0] != '\0' && cptr[1] != '\0')
184 /* If we have only ".", don't remove the "." */
185 ++cptr;
188 else
190 char *tmp;
192 if (cp[strlen (cp) - 1] == '$')
194 char *p;
196 tmp = malloc (strlen (cp) + strlen (local_domain) +
197 strlen (name) + 2);
198 if (tmp == NULL)
199 return NULL;
201 p = stpcpy (tmp, name);
202 *p++ = '.';
203 p = stpcpy (p, cp);
204 --p;
205 if (p[-1] != '.')
206 *p++ = '.';
207 stpcpy (p, local_domain);
209 else
211 char *p;
213 tmp = malloc (strlen (cp) + strlen (name) + 2);
214 if (tmp == NULL)
215 return NULL;
217 p = stpcpy (tmp, name);
218 *p++ = '.';
219 stpcpy (p, cp);
222 if (pos >= count)
224 count += 5;
225 getnames = realloc (getnames, (count + 1) * sizeof (char *));
226 if (getnames == NULL)
227 return NULL;
229 getnames[pos] = tmp;
230 ++pos;
232 cp = strtok (NULL, ":");
235 getnames[pos] = NULL;
237 return getnames;
240 void
241 nis_freenames (nis_name *names)
243 int i = 0;
245 while (names[i] != NULL)
247 free (names[i]);
248 ++i;
251 free (names);
254 name_pos
255 nis_dir_cmp (const_nis_name n1, const_nis_name n2)
257 int len1, len2;
259 len1 = strlen (n1);
260 len2 = strlen (n2);
262 if (len1 == len2)
264 if (strcmp (n1, n2) == 0)
265 return SAME_NAME;
266 else
267 return NOT_SEQUENTIAL;
270 if (len1 < len2)
272 if (n2[len2 - len1 - 1] != '.')
273 return NOT_SEQUENTIAL;
274 else if (strcmp (&n2[len2 - len1], n1) == 0)
275 return HIGHER_NAME;
276 else
277 return NOT_SEQUENTIAL;
279 else
281 if (n1[len1 - len2 - 1] != '.')
282 return NOT_SEQUENTIAL;
283 else if (strcmp (&n1[len1 - len2], n2) == 0)
284 return LOWER_NAME;
285 else
286 return NOT_SEQUENTIAL;
291 void
292 nis_destroy_object (nis_object *obj)
294 nis_free_object (obj);