1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
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 (__builtin_expect (i >= buflen, 0))
43: {
44: __set_errno (ERANGE);
45: return NULL;
46: }
47:
48: *((char *) __mempcpy (buffer, name, i)) = '\0';
49:
50: return buffer;
51: }
52: libnsl_hidden_def (nis_leaf_of_r)
53:
54: nis_name
55: nis_name_of (const_nis_name name)
56: {
57: static char result[NIS_MAXNAMELEN + 1];
58:
59: return nis_name_of_r (name, result, NIS_MAXNAMELEN);
60: }
61:
62: nis_name
63: nis_name_of_r (const_nis_name name, char *buffer, size_t buflen)
64: {
65: char *local_domain;
66: int diff;
67:
68: local_domain = nis_local_directory ();
69:
70: diff = strlen (name) - strlen (local_domain);
71: if (diff <= 0)
72: return NULL;
73:
74: if (strcmp (&name[diff], local_domain) != 0)
75: return NULL;
76:
77: if ((size_t) diff >= buflen)
78: {
79: __set_errno (ERANGE);
80: return NULL;
81: }
82:
83: *((char *) __mempcpy (buffer, name, diff - 1)) = '\0';
84:
85: if (diff - 1 == 0)
86: return NULL;
87:
88: return buffer;
89: }
90: libnsl_hidden_def (nis_name_of_r)
91:
92: static int __always_inline
93: count_dots (const_nis_name str)
94: {
95: int count = 0;
96:
97: for (size_t i = 0; str[i] != '\0'; ++i)
98: if (str[i] == '.')
99: ++count;
100:
101: return count;
102: }
103:
104:
105:
106:
107: nis_name *
108: nis_getnames (const_nis_name name)
109: {
110: const char *local_domain = nis_local_directory ();
111: size_t local_domain_len = strlen (local_domain);
112: size_t name_len = strlen (name);
113: char *path;
114: int pos = 0;
115: char *saveptr = NULL;
116: int have_point;
117: const char *cp;
118: const char *cp2;
119:
120: int count = 2;
121: nis_name *getnames = malloc ((count + 1) * sizeof (char *));
122: if (__builtin_expect (getnames == NULL, 0))
123: return NULL;
124:
125:
126: if (name[name_len - 1] == '.')
127: {
128: if ((getnames[0] = strdup (name)) == NULL)
129: {
130: free_null:
131: while (pos-- > 0)
132: free (getnames[pos]);
133: free (getnames);
134: return NULL;
135: }
136:
137: getnames[1] = NULL;
138:
139: return getnames;
140: }
141:
142:
143:
144:
145: if (local_domain_len > 2)
146: {
147: have_point = 0;
148: cp = &local_domain[local_domain_len - 2];
149: cp2 = &name[name_len - 1];
150:
151: while (*cp == *cp2)
152: {
153: if (*cp == '.')
154: have_point = 1;
155: --cp;
156: --cp2;
157: if (cp < local_domain)
158: {
159: have_point = cp2 < name || *cp2 == '.';
160: break;
161: }
162: if (cp2 < name)
163: {
164: have_point = *cp == '.';
165: break;
166: }
167: }
168:
169: if (have_point)
170: {
171: getnames[0] = malloc (name_len + 2);
172: if (getnames[0] == NULL)
173: goto free_null;
174:
175: strcpy (stpcpy (getnames[0], name), ".");
176: ++pos;
177: }
178: }
179:
180:
181: path = getenv ("NIS_PATH");
182: if (path == NULL)
183: path = strdupa ("$");
184: else
185: path = strdupa (path);
186:
187: have_point = strchr (name, '.') != NULL;
188:
189: cp = __strtok_r (path, ":", &saveptr);
190: while (cp)
191: {
192: if (strcmp (cp, "$") == 0)
193: {
194: const char *cptr = local_domain;
195: char *tmp;
196:
197: while (*cptr != '\0' && count_dots (cptr) >= 2)
198: {
199: if (pos >= count)
200: {
201: count += 5;
202: nis_name *newp = realloc (getnames,
203: (count + 1) * sizeof (char *));
204: if (__builtin_expect (newp == NULL, 0))
205: goto free_null;
206: getnames = newp;
207: }
208: tmp = malloc (strlen (cptr) + local_domain_len + name_len + 2);
209: if (__builtin_expect (tmp == NULL, 0))
210: goto free_null;
211:
212: getnames[pos] = tmp;
213: tmp = stpcpy (tmp, name);
214: *tmp++ = '.';
215: if (cptr[1] != '\0')
216: stpcpy (tmp, cptr);
217: else
218: ++cptr;
219:
220: ++pos;
221:
222: while (*cptr != '.' && *cptr != '\0')
223: ++cptr;
224: if (cptr[0] != '\0' && cptr[1] != '\0')
225:
226: ++cptr;
227: }
228: }
229: else
230: {
231: char *tmp;
232: size_t cplen = strlen (cp);
233:
234: if (cp[cplen - 1] == '$')
235: {
236: char *p;
237:
238: tmp = malloc (cplen + local_domain_len + name_len + 2);
239: if (__builtin_expect (tmp == NULL, 0))
240: goto free_null;
241:
242: p = __stpcpy (tmp, name);
243: *p++ = '.';
244: p = __mempcpy (p, cp, cplen);
245: --p;
246: if (p[-1] != '.')
247: *p++ = '.';
248: __stpcpy (p, local_domain);
249: }
250: else
251: {
252: char *p;
253:
254: tmp = malloc (cplen + name_len + 3);
255: if (__builtin_expect (tmp == NULL, 0))
256: goto free_null;
257:
258: p = __mempcpy (tmp, name, name_len);
259: *p++ = '.';
260: p = __mempcpy (p, cp, cplen);
261: if (p[-1] != '.')
262: *p++ = '.';
263: *p = '\0';
264: }
265:
266: if (pos >= count)
267: {
268: count += 5;
269: nis_name *newp = realloc (getnames,
270: (count + 1) * sizeof (char *));
271: if (__builtin_expect (newp == NULL, 0))
272: goto free_null;
273: getnames = newp;
274: }
275: getnames[pos] = tmp;
276: ++pos;
277: }
278: cp = __strtok_r (NULL, ":", &saveptr);
279: }
280:
281: if (pos == 0
282: && __asprintf (&getnames[pos++], "%s%s%s%s",
283: name, name[name_len - 1] == '.' ? "" : ".",
284: local_domain,
285: local_domain[local_domain_len - 1] == '.' ? "" : ".") < 0)
286: goto free_null;
287:
288: getnames[pos] = NULL;
289:
290: return getnames;
291: }
292: libnsl_hidden_def (nis_getnames)
293:
294: void
295: nis_freenames (nis_name *names)
296: {
297: int i = 0;
298:
299: while (names[i] != NULL)
300: {
301: free (names[i]);
302: ++i;
303: }
304:
305: free (names);
306: }
307: libnsl_hidden_def (nis_freenames)
308:
309: name_pos
310: nis_dir_cmp (const_nis_name n1, const_nis_name n2)
311: {
312: int len1, len2;
313:
314: len1 = strlen (n1);
315: len2 = strlen (n2);
316:
317: if (len1 == len2)
318: {
319: if (strcmp (n1, n2) == 0)
320: return SAME_NAME;
321: else
322: return NOT_SEQUENTIAL;
323: }
324:
325: if (len1 < len2)
326: {
327: if (n2[len2 - len1 - 1] != '.')
328: return NOT_SEQUENTIAL;
329: else if (strcmp (&n2[len2 - len1], n1) == 0)
330: return HIGHER_NAME;
331: else
332: return NOT_SEQUENTIAL;
333: }
334: else
335: {
336: if (n1[len1 - len2 - 1] != '.')
337: return NOT_SEQUENTIAL;
338: else if (strcmp (&n1[len1 - len2], n2) == 0)
339: return LOWER_NAME;
340: else
341: return NOT_SEQUENTIAL;
342:
343: }
344: }
345: libnsl_hidden_def (nis_dir_cmp)
346:
347: void
348: nis_destroy_object (nis_object *obj)
349: {
350: nis_free_object (obj);
351: }
352: libnsl_hidden_def (nis_destroy_object)