Define as __pwrite and make pwrite weak alias.
[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
24 nis_name
25 nis_leaf_of (const_nis_name name)
26 {
27   static char result[NIS_MAXNAMELEN + 1];
28
29   return nis_leaf_of_r (name, result, NIS_MAXNAMELEN);
30 }
31
32 nis_name
33 nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen)
34 {
35   size_t i = 0;
36
37   buffer[0] = '\0';
38
39   while (name[i] != '.' && name[i] != '\0')
40     i++;
41
42   if (i > buflen - 1)
43     {
44       errno = ERANGE;
45       return NULL;
46     }
47
48   if (i > 0)
49     {
50       if ((size_t)i >= buflen)
51         {
52           errno = ERANGE;
53           return NULL;
54         }
55       strncpy (buffer, name, i);
56       buffer[i] = 0;
57     }
58
59   return buffer;
60 }
61
62 nis_name
63 nis_name_of (const_nis_name name)
64 {
65   static char result[NIS_MAXNAMELEN + 1];
66
67   return nis_name_of_r (name, result, NIS_MAXNAMELEN);
68 }
69
70 nis_name
71 nis_name_of_r (const_nis_name name, char *buffer, size_t buflen)
72 {
73   char *local_domain;
74   int diff;
75
76   local_domain = nis_local_directory ();
77
78   diff = strlen (name) - strlen (local_domain);
79   if (diff <= 0)
80     return NULL;
81
82   if (strcmp (&name[diff], local_domain) != 0)
83     return NULL;
84
85   if ((size_t) diff >= buflen)
86     {
87       errno = ERANGE;
88       return NULL;
89     }
90   memcpy (buffer, name, diff - 1);
91   buffer[diff - 1] = '\0';
92
93   if (diff - 1 == 0)
94     return NULL;
95
96   return buffer;
97 }
98
99 static int
100 count_dots (const_nis_name str)
101 {
102   int count = 0;
103   size_t i;
104
105   for (i = 0; i < strlen (str); ++i)
106     if (str[i] == '.')
107       ++count;
108
109   return count;
110 }
111
112 nis_name *
113 nis_getnames (const_nis_name name)
114 {
115   nis_name *getnames = NULL;
116   char local_domain[NIS_MAXNAMELEN + 1];
117   char *path, *cp;
118   int count, pos, have_point;
119
120   strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
121   local_domain[NIS_MAXNAMELEN] = '\0';
122
123   count = 1;
124   if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
125       return NULL;
126
127   /* Do we have a fully qualified NIS+ name ? If yes, give it back */
128   if (name[strlen (name) - 1] == '.')
129     {
130       if ((getnames[0] = strdup (name)) == NULL)
131         {
132           free (getnames);
133           return NULL;
134         }
135       getnames[1] = NULL;
136
137       return getnames;
138     }
139
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);
146
147   have_point = (strchr (name, '.') != NULL);
148
149   pos = 0;
150
151   cp = strtok (path, ":");
152   while (cp)
153     {
154       if (strcmp (cp, "$") == 0)
155         {
156           char *cptr = local_domain;
157           char *tmp;
158
159           while ((have_point && *cptr != '\0') || (count_dots (cptr) >= 2))
160             {
161               if (pos >= count)
162                 {
163                   count += 5;
164                   getnames = realloc (getnames, (count + 1) * sizeof (char *));
165                 }
166               tmp = malloc (strlen (cptr) + strlen (local_domain) +
167                             strlen (name) + 2);
168               if (tmp == NULL)
169                 return NULL;
170
171               getnames[pos] = tmp;
172               tmp = stpcpy (tmp, name);
173               *tmp++ = '.';
174               if (cptr[1] != '\0')
175                 stpcpy (tmp, cptr);
176               else
177                 ++cptr;
178
179               ++pos;
180
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;
186             }
187         }
188       else
189         {
190           char *tmp;
191
192           if (cp[strlen (cp) - 1] == '$')
193             {
194               char *p;
195
196               tmp = malloc (strlen (cp) + strlen (local_domain) +
197                             strlen (name) + 2);
198               if (tmp == NULL)
199                 return NULL;
200
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);
208             }
209           else
210             {
211               char *p;
212
213               tmp = malloc (strlen (cp) + strlen (name) + 2);
214               if (tmp == NULL)
215                 return NULL;
216
217               p = stpcpy (tmp, name);
218               *p++ = '.';
219               stpcpy (p, cp);
220             }
221
222           if (pos >= count)
223             {
224               count += 5;
225               getnames = realloc (getnames, (count + 1) * sizeof (char *));
226               if (getnames == NULL)
227                 return NULL;
228             }
229           getnames[pos] = tmp;
230           ++pos;
231         }
232       cp = strtok (NULL, ":");
233     }
234
235   getnames[pos] = NULL;
236
237   return getnames;
238 }
239
240 void
241 nis_freenames (nis_name *names)
242 {
243   int i = 0;
244
245   while (names[i] != NULL)
246     {
247       free (names[i]);
248       ++i;
249     }
250
251   free (names);
252 }
253
254 name_pos
255 nis_dir_cmp (const_nis_name n1, const_nis_name n2)
256 {
257   int len1, len2;
258
259   len1 = strlen (n1);
260   len2 = strlen (n2);
261
262   if (len1 == len2)
263     {
264       if (strcmp (n1, n2) == 0)
265         return SAME_NAME;
266       else
267         return NOT_SEQUENTIAL;
268     }
269
270   if (len1 < len2)
271     {
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;
278     }
279   else
280     {
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;
287
288     }
289 }
290
291 void
292 nis_destroy_object (nis_object *obj)
293 {
294   nis_free_object (obj);
295 }