1*e6e30c83Schristos /*	$NetBSD: irpmarshall.c,v 1.1.1.2 2012/09/09 16:07:57 christos Exp $	*/
2b5677b36Schristos 
3b5677b36Schristos /*
4b5677b36Schristos  * Copyright(c) 1989, 1993, 1995
5b5677b36Schristos  *	The Regents of the University of California.  All rights reserved.
6b5677b36Schristos  *
7b5677b36Schristos  * Redistribution and use in source and binary forms, with or without
8b5677b36Schristos  * modification, are permitted provided that the following conditions
9b5677b36Schristos  * are met:
10b5677b36Schristos  * 1. Redistributions of source code must retain the above copyright
11b5677b36Schristos  *    notice, this list of conditions and the following disclaimer.
12b5677b36Schristos  * 2. Redistributions in binary form must reproduce the above copyright
13b5677b36Schristos  *    notice, this list of conditions and the following disclaimer in the
14b5677b36Schristos  *    documentation and/or other materials provided with the distribution.
15b5677b36Schristos  * 3. All advertising materials mentioning features or use of this software
16b5677b36Schristos  *    must display the following acknowledgement:
17b5677b36Schristos  *	This product includes software developed by the University of
18b5677b36Schristos  *	California, Berkeley and its contributors.
19b5677b36Schristos  * 4. Neither the name of the University nor the names of its contributors
20b5677b36Schristos  *    may be used to endorse or promote products derived from this software
21b5677b36Schristos  *    without specific prior written permission.
22b5677b36Schristos  *
23b5677b36Schristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24b5677b36Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25b5677b36Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26b5677b36Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27b5677b36Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28b5677b36Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29b5677b36Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30b5677b36Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31b5677b36Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32b5677b36Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33b5677b36Schristos  * SUCH DAMAGE.
34b5677b36Schristos  */
35b5677b36Schristos 
36b5677b36Schristos /*
37b5677b36Schristos  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
38b5677b36Schristos  * Portions Copyright (c) 1996 by Internet Software Consortium.
39b5677b36Schristos  *
40b5677b36Schristos  * Permission to use, copy, modify, and distribute this software for any
41b5677b36Schristos  * purpose with or without fee is hereby granted, provided that the above
42b5677b36Schristos  * copyright notice and this permission notice appear in all copies.
43b5677b36Schristos  *
44b5677b36Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
45b5677b36Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
46b5677b36Schristos  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
47b5677b36Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
48b5677b36Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
49b5677b36Schristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
50b5677b36Schristos  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51b5677b36Schristos  */
52b5677b36Schristos 
53b5677b36Schristos #if defined(LIBC_SCCS) && !defined(lint)
54b5677b36Schristos static const char rcsid[] = "Id: irpmarshall.c,v 1.7 2006/03/09 23:57:56 marka Exp ";
55b5677b36Schristos #endif /* LIBC_SCCS and not lint */
56b5677b36Schristos 
57b5677b36Schristos #if 0
58b5677b36Schristos 
59b5677b36Schristos Check values are in approrpriate endian order.
60b5677b36Schristos 
61b5677b36Schristos Double check memory allocations on unmarhsalling
62b5677b36Schristos 
63b5677b36Schristos #endif
64b5677b36Schristos 
65b5677b36Schristos 
66b5677b36Schristos /* Extern */
67b5677b36Schristos 
68b5677b36Schristos #include "port_before.h"
69b5677b36Schristos 
70b5677b36Schristos #include <sys/types.h>
71b5677b36Schristos #include <sys/socket.h>
72b5677b36Schristos 
73b5677b36Schristos #include <netinet/in.h>
74b5677b36Schristos #include <arpa/inet.h>
75b5677b36Schristos #include <arpa/nameser.h>
76b5677b36Schristos 
77b5677b36Schristos #include <stdio.h>
78b5677b36Schristos #include <ctype.h>
79b5677b36Schristos #include <pwd.h>
80b5677b36Schristos #include <stdlib.h>
81b5677b36Schristos #include <string.h>
82b5677b36Schristos #include <syslog.h>
83b5677b36Schristos #include <utmp.h>
84b5677b36Schristos #include <unistd.h>
85b5677b36Schristos #include <assert.h>
86b5677b36Schristos #include <errno.h>
87b5677b36Schristos 
88b5677b36Schristos #include <irs.h>
89b5677b36Schristos #include <isc/memcluster.h>
90b5677b36Schristos #include <isc/irpmarshall.h>
91b5677b36Schristos 
92b5677b36Schristos #include "port_after.h"
93b5677b36Schristos 
94b5677b36Schristos 
95b5677b36Schristos #ifndef HAVE_STRNDUP
96b5677b36Schristos static char    *strndup(const char *str, size_t len);
97b5677b36Schristos #endif
98b5677b36Schristos 
99b5677b36Schristos static char   **splitarray(const char *buffer, const char *buffend, char delim);
100b5677b36Schristos static int	joinarray(char * const * argv, char *buffer, char delim);
101b5677b36Schristos static char    *getfield(char **res, size_t reslen, char **buffer, char delim);
102b5677b36Schristos static size_t	joinlength(char * const *argv);
103b5677b36Schristos static void	free_array(char **argv, size_t entries);
104b5677b36Schristos 
105b5677b36Schristos #define ADDR_T_STR(x) (x == AF_INET ? "AF_INET" :\
106b5677b36Schristos 		       (x == AF_INET6 ? "AF_INET6" : "UNKNOWN"))
107b5677b36Schristos 
108b5677b36Schristos #define MAXPADDRSIZE (sizeof "255.255.255.255" + 1)
109b5677b36Schristos 
110b5677b36Schristos static char COMMA = ',';
111b5677b36Schristos 
112b5677b36Schristos static const char *COMMASTR = ",";
113b5677b36Schristos static const char *COLONSTR = ":";
114b5677b36Schristos 
115b5677b36Schristos 
116b5677b36Schristos 
117b5677b36Schristos /* See big comment at bottom of irpmarshall.h for description. */
118b5677b36Schristos 
119b5677b36Schristos 
120b5677b36Schristos #ifdef WANT_IRS_PW
121b5677b36Schristos /* +++++++++++++++++++++++++ struct passwd +++++++++++++++++++++++++ */
122b5677b36Schristos 
123b5677b36Schristos /*%
124b5677b36Schristos  * int irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len)
125b5677b36Schristos  *
126b5677b36Schristos  * notes: \li
127b5677b36Schristos  *
128b5677b36Schristos  *	See irpmarshall.h
129b5677b36Schristos  *
130b5677b36Schristos  * return: \li
131b5677b36Schristos  *
132b5677b36Schristos  *	0 on sucess, -1 on failure.
133b5677b36Schristos  *
134b5677b36Schristos  */
135b5677b36Schristos 
136b5677b36Schristos int
irp_marshall_pw(const struct passwd * pw,char ** buffer,size_t * len)137b5677b36Schristos irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) {
138b5677b36Schristos 	size_t need = 1 ;		/*%< for null byte */
139b5677b36Schristos 	char pwUid[24];
140b5677b36Schristos 	char pwGid[24];
141b5677b36Schristos 	char pwChange[24];
142b5677b36Schristos 	char pwExpire[24];
143b5677b36Schristos 	const char *pwClass;
144b5677b36Schristos 	const char *fieldsep = COLONSTR;
145b5677b36Schristos 
146b5677b36Schristos 	if (pw == NULL || len == NULL) {
147b5677b36Schristos 		errno = EINVAL;
148b5677b36Schristos 		return (-1);
149b5677b36Schristos 	}
150b5677b36Schristos 
151b5677b36Schristos 	sprintf(pwUid, "%ld", (long)pw->pw_uid);
152b5677b36Schristos 	sprintf(pwGid, "%ld", (long)pw->pw_gid);
153b5677b36Schristos 
154b5677b36Schristos #ifdef HAVE_PW_CHANGE
155b5677b36Schristos 	sprintf(pwChange, "%ld", (long)pw->pw_change);
156b5677b36Schristos #else
157b5677b36Schristos 	pwChange[0] = '0';
158b5677b36Schristos 	pwChange[1] = '\0';
159b5677b36Schristos #endif
160b5677b36Schristos 
161b5677b36Schristos #ifdef HAVE_PW_EXPIRE
162b5677b36Schristos 	sprintf(pwExpire, "%ld", (long)pw->pw_expire);
163b5677b36Schristos #else
164b5677b36Schristos 	pwExpire[0] = '0';
165b5677b36Schristos 	pwExpire[1] = '\0';
166b5677b36Schristos #endif
167b5677b36Schristos 
168b5677b36Schristos #ifdef HAVE_PW_CLASS
169b5677b36Schristos 	pwClass = pw->pw_class;
170b5677b36Schristos #else
171b5677b36Schristos 	pwClass = "";
172b5677b36Schristos #endif
173b5677b36Schristos 
174b5677b36Schristos 	need += strlen(pw->pw_name)	+ 1; /*%< one for fieldsep */
175b5677b36Schristos 	need += strlen(pw->pw_passwd)	+ 1;
176b5677b36Schristos 	need += strlen(pwUid)		+ 1;
177b5677b36Schristos 	need += strlen(pwGid)		+ 1;
178b5677b36Schristos 	need += strlen(pwClass)		+ 1;
179b5677b36Schristos 	need += strlen(pwChange)	+ 1;
180b5677b36Schristos 	need += strlen(pwExpire)	+ 1;
181b5677b36Schristos 	need += strlen(pw->pw_gecos)	+ 1;
182b5677b36Schristos 	need += strlen(pw->pw_dir)	+ 1;
183b5677b36Schristos 	need += strlen(pw->pw_shell)	+ 1;
184b5677b36Schristos 
185b5677b36Schristos 	if (buffer == NULL) {
186b5677b36Schristos 		*len = need;
187b5677b36Schristos 		return (0);
188b5677b36Schristos 	}
189b5677b36Schristos 
190b5677b36Schristos 	if (*buffer != NULL && need > *len) {
191b5677b36Schristos 		errno = EINVAL;
192b5677b36Schristos 		return (-1);
193b5677b36Schristos 	}
194b5677b36Schristos 
195b5677b36Schristos 	if (*buffer == NULL) {
196b5677b36Schristos 		need += 2;		/*%< for CRLF */
197b5677b36Schristos 		*buffer = memget(need);
198b5677b36Schristos 		if (*buffer == NULL) {
199b5677b36Schristos 			errno = ENOMEM;
200b5677b36Schristos 			return (-1);
201b5677b36Schristos 		}
202b5677b36Schristos 
203b5677b36Schristos 		*len = need;
204b5677b36Schristos 	}
205b5677b36Schristos 
206b5677b36Schristos 	strcpy(*buffer, pw->pw_name);		strcat(*buffer, fieldsep);
207b5677b36Schristos 	strcat(*buffer, pw->pw_passwd);		strcat(*buffer, fieldsep);
208b5677b36Schristos 	strcat(*buffer, pwUid);			strcat(*buffer, fieldsep);
209b5677b36Schristos 	strcat(*buffer, pwGid);			strcat(*buffer, fieldsep);
210b5677b36Schristos 	strcat(*buffer, pwClass);		strcat(*buffer, fieldsep);
211b5677b36Schristos 	strcat(*buffer, pwChange);		strcat(*buffer, fieldsep);
212b5677b36Schristos 	strcat(*buffer, pwExpire);		strcat(*buffer, fieldsep);
213b5677b36Schristos 	strcat(*buffer, pw->pw_gecos);		strcat(*buffer, fieldsep);
214b5677b36Schristos 	strcat(*buffer, pw->pw_dir);		strcat(*buffer, fieldsep);
215b5677b36Schristos 	strcat(*buffer, pw->pw_shell);		strcat(*buffer, fieldsep);
216b5677b36Schristos 
217b5677b36Schristos 	return (0);
218b5677b36Schristos }
219b5677b36Schristos 
220b5677b36Schristos /*%
221b5677b36Schristos  * int irp_unmarshall_pw(struct passwd *pw, char *buffer)
222b5677b36Schristos  *
223b5677b36Schristos  * notes: \li
224b5677b36Schristos  *
225b5677b36Schristos  *	See irpmarshall.h
226b5677b36Schristos  *
227b5677b36Schristos  * return: \li
228b5677b36Schristos  *
229b5677b36Schristos  *	0 on success, -1 on failure
230b5677b36Schristos  *
231b5677b36Schristos  */
232b5677b36Schristos 
233b5677b36Schristos int
irp_unmarshall_pw(struct passwd * pw,char * buffer)234b5677b36Schristos irp_unmarshall_pw(struct passwd *pw, char *buffer) {
235b5677b36Schristos 	char *name, *pass, *class, *gecos, *dir, *shell;
236b5677b36Schristos 	uid_t pwuid;
237b5677b36Schristos 	gid_t pwgid;
238b5677b36Schristos 	time_t pwchange;
239b5677b36Schristos 	time_t pwexpire;
240b5677b36Schristos 	char *p;
241b5677b36Schristos 	long t;
242b5677b36Schristos 	char tmpbuf[24];
243b5677b36Schristos 	char *tb = &tmpbuf[0];
244b5677b36Schristos 	char fieldsep = ':';
245b5677b36Schristos 	int myerrno = EINVAL;
246b5677b36Schristos 
247b5677b36Schristos 	name = pass = class = gecos = dir = shell = NULL;
248b5677b36Schristos 	p = buffer;
249b5677b36Schristos 
250b5677b36Schristos 	/* pw_name field */
251b5677b36Schristos 	name = NULL;
252b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
253b5677b36Schristos 		goto error;
254b5677b36Schristos 	}
255b5677b36Schristos 
256b5677b36Schristos 	/* pw_passwd field */
257b5677b36Schristos 	pass = NULL;
258b5677b36Schristos 	if (getfield(&pass, 0, &p, fieldsep) == NULL) { /*%< field can be empty */
259b5677b36Schristos 		goto error;
260b5677b36Schristos 	}
261b5677b36Schristos 
262b5677b36Schristos 
263b5677b36Schristos 	/* pw_uid field */
264b5677b36Schristos 	tb = tmpbuf;
265b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
266b5677b36Schristos 	    strlen(tb) == 0) {
267b5677b36Schristos 		goto error;
268b5677b36Schristos 	}
269b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
270b5677b36Schristos 	if (*tb) {
271b5677b36Schristos 		goto error;	/*%< junk in value */
272b5677b36Schristos 	}
273b5677b36Schristos 	pwuid = (uid_t)t;
274b5677b36Schristos 	if ((long) pwuid != t) {	/*%< value must have been too big. */
275b5677b36Schristos 		goto error;
276b5677b36Schristos 	}
277b5677b36Schristos 
278b5677b36Schristos 
279b5677b36Schristos 
280b5677b36Schristos 	/* pw_gid field */
281b5677b36Schristos 	tb = tmpbuf;
282b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
283b5677b36Schristos 	    strlen(tb) == 0) {
284b5677b36Schristos 		goto error;
285b5677b36Schristos 	}
286b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
287b5677b36Schristos 	if (*tb) {
288b5677b36Schristos 		goto error;	/*%< junk in value */
289b5677b36Schristos 	}
290b5677b36Schristos 	pwgid = (gid_t)t;
291b5677b36Schristos 	if ((long)pwgid != t) {	/*%< value must have been too big. */
292b5677b36Schristos 		goto error;
293b5677b36Schristos 	}
294b5677b36Schristos 
295b5677b36Schristos 
296b5677b36Schristos 
297b5677b36Schristos 	/* pw_class field */
298b5677b36Schristos 	class = NULL;
299b5677b36Schristos 	if (getfield(&class, 0, &p, fieldsep) == NULL) {
300b5677b36Schristos 		goto error;
301b5677b36Schristos 	}
302b5677b36Schristos 
303b5677b36Schristos 
304b5677b36Schristos 
305b5677b36Schristos 	/* pw_change field */
306b5677b36Schristos 	tb = tmpbuf;
307b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
308b5677b36Schristos 	    strlen(tb) == 0) {
309b5677b36Schristos 		goto error;
310b5677b36Schristos 	}
311b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
312b5677b36Schristos 	if (*tb) {
313b5677b36Schristos 		goto error;	/*%< junk in value */
314b5677b36Schristos 	}
315b5677b36Schristos 	pwchange = (time_t)t;
316b5677b36Schristos 	if ((long)pwchange != t) {	/*%< value must have been too big. */
317b5677b36Schristos 		goto error;
318b5677b36Schristos 	}
319b5677b36Schristos 
320b5677b36Schristos 
321b5677b36Schristos 
322b5677b36Schristos 	/* pw_expire field */
323b5677b36Schristos 	tb = tmpbuf;
324b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
325b5677b36Schristos 	    strlen(tb) == 0) {
326b5677b36Schristos 		goto error;
327b5677b36Schristos 	}
328b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
329b5677b36Schristos 	if (*tb) {
330b5677b36Schristos 		goto error;	/*%< junk in value */
331b5677b36Schristos 	}
332b5677b36Schristos 	pwexpire = (time_t)t;
333b5677b36Schristos 	if ((long) pwexpire != t) {	/*%< value must have been too big. */
334b5677b36Schristos 		goto error;
335b5677b36Schristos 	}
336b5677b36Schristos 
337b5677b36Schristos 
338b5677b36Schristos 
339b5677b36Schristos 	/* pw_gecos field */
340b5677b36Schristos 	gecos = NULL;
341b5677b36Schristos 	if (getfield(&gecos, 0, &p, fieldsep) == NULL) {
342b5677b36Schristos 		goto error;
343b5677b36Schristos 	}
344b5677b36Schristos 
345b5677b36Schristos 
346b5677b36Schristos 
347b5677b36Schristos 	/* pw_dir field */
348b5677b36Schristos 	dir = NULL;
349b5677b36Schristos 	if (getfield(&dir, 0, &p, fieldsep) == NULL) {
350b5677b36Schristos 		goto error;
351b5677b36Schristos 	}
352b5677b36Schristos 
353b5677b36Schristos 
354b5677b36Schristos 
355b5677b36Schristos 	/* pw_shell field */
356b5677b36Schristos 	shell = NULL;
357b5677b36Schristos 	if (getfield(&shell, 0, &p, fieldsep) == NULL) {
358b5677b36Schristos 		goto error;
359b5677b36Schristos 	}
360b5677b36Schristos 
361b5677b36Schristos 
362b5677b36Schristos 
363b5677b36Schristos 	pw->pw_name = name;
364b5677b36Schristos 	pw->pw_passwd = pass;
365b5677b36Schristos 	pw->pw_uid = pwuid;
366b5677b36Schristos 	pw->pw_gid = pwgid;
367b5677b36Schristos 	pw->pw_gecos = gecos;
368b5677b36Schristos 	pw->pw_dir = dir;
369b5677b36Schristos 	pw->pw_shell = shell;
370b5677b36Schristos 
371b5677b36Schristos #ifdef HAVE_PW_CHANGE
372b5677b36Schristos 	pw->pw_change = pwchange;
373b5677b36Schristos #endif
374b5677b36Schristos #ifdef HAVE_PW_CLASS
375b5677b36Schristos 	pw->pw_class = class;
376b5677b36Schristos #endif
377b5677b36Schristos #ifdef HAVE_PW_EXPIRE
378b5677b36Schristos 	pw->pw_expire = pwexpire;
379b5677b36Schristos #endif
380b5677b36Schristos 
381b5677b36Schristos 	return (0);
382b5677b36Schristos 
383b5677b36Schristos  error:
384b5677b36Schristos 	errno = myerrno;
385b5677b36Schristos 
386b5677b36Schristos 	if (name != NULL) free(name);
387b5677b36Schristos 	if (pass != NULL) free(pass);
388b5677b36Schristos 	if (gecos != NULL) free(gecos);
389b5677b36Schristos 	if (dir != NULL) free(dir);
390b5677b36Schristos 	if (shell != NULL) free(shell);
391b5677b36Schristos 
392b5677b36Schristos 	return (-1);
393b5677b36Schristos }
394b5677b36Schristos 
395b5677b36Schristos /* ------------------------- struct passwd ------------------------- */
396b5677b36Schristos #endif /* WANT_IRS_PW */
397b5677b36Schristos /* +++++++++++++++++++++++++ struct group +++++++++++++++++++++++++ */
398b5677b36Schristos 
399b5677b36Schristos /*%
400b5677b36Schristos  * int irp_marshall_gr(const struct group *gr, char **buffer, size_t *len)
401b5677b36Schristos  *
402b5677b36Schristos  * notes: \li
403b5677b36Schristos  *
404b5677b36Schristos  *	See irpmarshall.h.
405b5677b36Schristos  *
406b5677b36Schristos  * return: \li
407b5677b36Schristos  *
408b5677b36Schristos  *	0 on success, -1 on failure
409b5677b36Schristos  */
410b5677b36Schristos 
411b5677b36Schristos int
irp_marshall_gr(const struct group * gr,char ** buffer,size_t * len)412b5677b36Schristos irp_marshall_gr(const struct group *gr, char **buffer, size_t *len) {
413b5677b36Schristos 	size_t need = 1;	/*%< for null byte */
414b5677b36Schristos 	char grGid[24];
415b5677b36Schristos 	const char *fieldsep = COLONSTR;
416b5677b36Schristos 
417b5677b36Schristos 	if (gr == NULL || len == NULL) {
418b5677b36Schristos 		errno = EINVAL;
419b5677b36Schristos 		return (-1);
420b5677b36Schristos 	}
421b5677b36Schristos 
422b5677b36Schristos 	sprintf(grGid, "%ld", (long)gr->gr_gid);
423b5677b36Schristos 
424b5677b36Schristos 	need += strlen(gr->gr_name) + 1;
425b5677b36Schristos #ifndef MISSING_GR_PASSWD
426b5677b36Schristos 	need += strlen(gr->gr_passwd) + 1;
427b5677b36Schristos #else
428b5677b36Schristos 	need++;
429b5677b36Schristos #endif
430b5677b36Schristos 	need += strlen(grGid) + 1;
431b5677b36Schristos 	need += joinlength(gr->gr_mem) + 1;
432b5677b36Schristos 
433b5677b36Schristos 	if (buffer == NULL) {
434b5677b36Schristos 		*len = need;
435b5677b36Schristos 		return (0);
436b5677b36Schristos 	}
437b5677b36Schristos 
438b5677b36Schristos 	if (*buffer != NULL && need > *len) {
439b5677b36Schristos 		errno = EINVAL;
440b5677b36Schristos 		return (-1);
441b5677b36Schristos 	}
442b5677b36Schristos 
443b5677b36Schristos 	if (*buffer == NULL) {
444b5677b36Schristos 		need += 2;		/*%< for CRLF */
445b5677b36Schristos 		*buffer = memget(need);
446b5677b36Schristos 		if (*buffer == NULL) {
447b5677b36Schristos 			errno = ENOMEM;
448b5677b36Schristos 			return (-1);
449b5677b36Schristos 		}
450b5677b36Schristos 
451b5677b36Schristos 		*len = need;
452b5677b36Schristos 	}
453b5677b36Schristos 
454b5677b36Schristos 	strcpy(*buffer, gr->gr_name);		strcat(*buffer, fieldsep);
455b5677b36Schristos #ifndef MISSING_GR_PASSWD
456b5677b36Schristos 	strcat(*buffer, gr->gr_passwd);
457b5677b36Schristos #endif
458b5677b36Schristos 	strcat(*buffer, fieldsep);
459b5677b36Schristos 	strcat(*buffer, grGid);			strcat(*buffer, fieldsep);
460b5677b36Schristos 	joinarray(gr->gr_mem, *buffer, COMMA) ;	strcat(*buffer, fieldsep);
461b5677b36Schristos 
462b5677b36Schristos 	return (0);
463b5677b36Schristos }
464b5677b36Schristos 
465b5677b36Schristos /*%
466b5677b36Schristos  * int irp_unmarshall_gr(struct group *gr, char *buffer)
467b5677b36Schristos  *
468b5677b36Schristos  * notes: \li
469b5677b36Schristos  *
470b5677b36Schristos  *	See irpmarshall.h
471b5677b36Schristos  *
472b5677b36Schristos  * return: \li
473b5677b36Schristos  *
474b5677b36Schristos  *	0 on success and -1 on failure.
475b5677b36Schristos  *
476b5677b36Schristos  */
477b5677b36Schristos 
478b5677b36Schristos int
irp_unmarshall_gr(struct group * gr,char * buffer)479b5677b36Schristos irp_unmarshall_gr(struct group *gr, char *buffer) {
480b5677b36Schristos 	char *p, *q;
481b5677b36Schristos 	gid_t grgid;
482b5677b36Schristos 	long t;
483b5677b36Schristos 	char *name = NULL;
484b5677b36Schristos 	char *pass = NULL;
485b5677b36Schristos 	char **members = NULL;
486b5677b36Schristos 	char tmpbuf[24];
487b5677b36Schristos 	char *tb;
488b5677b36Schristos 	char fieldsep = ':';
489b5677b36Schristos 	int myerrno = EINVAL;
490b5677b36Schristos 
491b5677b36Schristos 	if (gr == NULL || buffer == NULL) {
492b5677b36Schristos 		errno = EINVAL;
493b5677b36Schristos 		return (-1);
494b5677b36Schristos 	}
495b5677b36Schristos 
496b5677b36Schristos 	p = buffer;
497b5677b36Schristos 
498b5677b36Schristos 	/* gr_name field */
499b5677b36Schristos 	name = NULL;
500b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
501b5677b36Schristos 		goto error;
502b5677b36Schristos 	}
503b5677b36Schristos 
504b5677b36Schristos 
505b5677b36Schristos 	/* gr_passwd field */
506b5677b36Schristos 	pass = NULL;
507b5677b36Schristos 	if (getfield(&pass, 0, &p, fieldsep) == NULL) {
508b5677b36Schristos 		goto error;
509b5677b36Schristos 	}
510b5677b36Schristos 
511b5677b36Schristos 
512b5677b36Schristos 	/* gr_gid field */
513b5677b36Schristos 	tb = tmpbuf;
514b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
515b5677b36Schristos 	    strlen(tb) == 0U) {
516b5677b36Schristos 		goto error;
517b5677b36Schristos 	}
518b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
519b5677b36Schristos 	if (*tb) {
520b5677b36Schristos 		goto error;	/*%< junk in value */
521b5677b36Schristos 	}
522b5677b36Schristos 	grgid = (gid_t)t;
523b5677b36Schristos 	if ((long) grgid != t) {	/*%< value must have been too big. */
524b5677b36Schristos 		goto error;
525b5677b36Schristos 	}
526b5677b36Schristos 
527b5677b36Schristos 
528b5677b36Schristos 	/* gr_mem field. Member names are separated by commas */
529b5677b36Schristos 	q = strchr(p, fieldsep);
530b5677b36Schristos 	if (q == NULL) {
531b5677b36Schristos 		goto error;
532b5677b36Schristos 	}
533b5677b36Schristos 	members = splitarray(p, q, COMMA);
534b5677b36Schristos 	if (members == NULL) {
535b5677b36Schristos 		myerrno = errno;
536b5677b36Schristos 		goto error;
537b5677b36Schristos 	}
538b5677b36Schristos 	p = q + 1;
539b5677b36Schristos 
540b5677b36Schristos 
541b5677b36Schristos 	gr->gr_name = name;
542b5677b36Schristos #ifndef MISSING_GR_PASSWD
543b5677b36Schristos 	gr->gr_passwd = pass;
544b5677b36Schristos #endif
545b5677b36Schristos 	gr->gr_gid = grgid;
546b5677b36Schristos 	gr->gr_mem = members;
547b5677b36Schristos 
548b5677b36Schristos 	return (0);
549b5677b36Schristos 
550b5677b36Schristos  error:
551b5677b36Schristos 	errno = myerrno;
552b5677b36Schristos 
553b5677b36Schristos 	if (name != NULL) free(name);
554b5677b36Schristos 	if (pass != NULL) free(pass);
555b5677b36Schristos 
556b5677b36Schristos 	return (-1);
557b5677b36Schristos }
558b5677b36Schristos 
559b5677b36Schristos 
560b5677b36Schristos /* ------------------------- struct group ------------------------- */
561b5677b36Schristos 
562b5677b36Schristos 
563b5677b36Schristos 
564b5677b36Schristos 
565b5677b36Schristos /* +++++++++++++++++++++++++ struct servent +++++++++++++++++++++++++ */
566b5677b36Schristos 
567b5677b36Schristos /*%
568b5677b36Schristos  * int irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len)
569b5677b36Schristos  *
570b5677b36Schristos  * notes: \li
571b5677b36Schristos  *
572b5677b36Schristos  *	See irpmarshall.h
573b5677b36Schristos  *
574b5677b36Schristos  * return: \li
575b5677b36Schristos  *
576b5677b36Schristos  *	0 on success, -1 on failure.
577b5677b36Schristos  *
578b5677b36Schristos  */
579b5677b36Schristos 
580b5677b36Schristos int
irp_marshall_sv(const struct servent * sv,char ** buffer,size_t * len)581b5677b36Schristos irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len) {
582b5677b36Schristos 	size_t need = 1;	/*%< for null byte */
583b5677b36Schristos 	char svPort[24];
584b5677b36Schristos 	const char *fieldsep = COLONSTR;
585b5677b36Schristos 	short realport;
586b5677b36Schristos 
587b5677b36Schristos 	if (sv == NULL || len == NULL) {
588b5677b36Schristos 		errno = EINVAL;
589b5677b36Schristos 		return (-1);
590b5677b36Schristos 	}
591b5677b36Schristos 
592b5677b36Schristos 	/* the int s_port field is actually a short in network order. We
593b5677b36Schristos 	   want host order to make the marshalled data look correct */
594b5677b36Schristos 	realport = ntohs((short)sv->s_port);
595b5677b36Schristos 	sprintf(svPort, "%d", realport);
596b5677b36Schristos 
597b5677b36Schristos 	need += strlen(sv->s_name) + 1;
598b5677b36Schristos 	need += joinlength(sv->s_aliases) + 1;
599b5677b36Schristos 	need += strlen(svPort) + 1;
600b5677b36Schristos 	need += strlen(sv->s_proto) + 1;
601b5677b36Schristos 
602b5677b36Schristos 	if (buffer == NULL) {
603b5677b36Schristos 		*len = need;
604b5677b36Schristos 		return (0);
605b5677b36Schristos 	}
606b5677b36Schristos 
607b5677b36Schristos 	if (*buffer != NULL && need > *len) {
608b5677b36Schristos 		errno = EINVAL;
609b5677b36Schristos 		return (-1);
610b5677b36Schristos 	}
611b5677b36Schristos 
612b5677b36Schristos 	if (*buffer == NULL) {
613b5677b36Schristos 		need += 2;		/*%< for CRLF */
614b5677b36Schristos 		*buffer = memget(need);
615b5677b36Schristos 		if (*buffer == NULL) {
616b5677b36Schristos 			errno = ENOMEM;
617b5677b36Schristos 			return (-1);
618b5677b36Schristos 		}
619b5677b36Schristos 
620b5677b36Schristos 		*len = need;
621b5677b36Schristos 	}
622b5677b36Schristos 
623b5677b36Schristos 	strcpy(*buffer, sv->s_name);		strcat(*buffer, fieldsep);
624b5677b36Schristos 	joinarray(sv->s_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
625b5677b36Schristos 	strcat(*buffer, svPort);		strcat(*buffer, fieldsep);
626b5677b36Schristos 	strcat(*buffer, sv->s_proto);		strcat(*buffer, fieldsep);
627b5677b36Schristos 
628b5677b36Schristos 	return (0);
629b5677b36Schristos }
630b5677b36Schristos 
631b5677b36Schristos /*%
632b5677b36Schristos  * int irp_unmarshall_sv(struct servent *sv, char *buffer)
633b5677b36Schristos  *
634b5677b36Schristos  * notes: \li
635b5677b36Schristos  *
636b5677b36Schristos  *	See irpmarshall.h
637b5677b36Schristos  *
638b5677b36Schristos  * return: \li
639b5677b36Schristos  *
640b5677b36Schristos  *	0 on success, -1 on failure.
641b5677b36Schristos  *
642b5677b36Schristos  */
643b5677b36Schristos 
644b5677b36Schristos int
irp_unmarshall_sv(struct servent * sv,char * buffer)645b5677b36Schristos irp_unmarshall_sv(struct servent *sv, char *buffer) {
646b5677b36Schristos 	char *p, *q;
647b5677b36Schristos 	short svport;
648b5677b36Schristos 	long t;
649b5677b36Schristos 	char *name = NULL;
650b5677b36Schristos 	char *proto = NULL;
651b5677b36Schristos 	char **aliases = NULL;
652b5677b36Schristos 	char tmpbuf[24];
653b5677b36Schristos 	char *tb;
654b5677b36Schristos 	char fieldsep = ':';
655b5677b36Schristos 	int myerrno = EINVAL;
656b5677b36Schristos 
657b5677b36Schristos 	if (sv == NULL || buffer == NULL)
658b5677b36Schristos 		return (-1);
659b5677b36Schristos 
660b5677b36Schristos 	p = buffer;
661b5677b36Schristos 
662b5677b36Schristos 
663b5677b36Schristos 	/* s_name field */
664b5677b36Schristos 	name = NULL;
665b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
666b5677b36Schristos 		goto error;
667b5677b36Schristos 	}
668b5677b36Schristos 
669b5677b36Schristos 
670b5677b36Schristos 	/* s_aliases field */
671b5677b36Schristos 	q = strchr(p, fieldsep);
672b5677b36Schristos 	if (q == NULL) {
673b5677b36Schristos 		goto error;
674b5677b36Schristos 	}
675b5677b36Schristos 	aliases = splitarray(p, q, COMMA);
676b5677b36Schristos 	if (aliases == NULL) {
677b5677b36Schristos 		myerrno = errno;
678b5677b36Schristos 		goto error;
679b5677b36Schristos 	}
680b5677b36Schristos 	p = q + 1;
681b5677b36Schristos 
682b5677b36Schristos 
683b5677b36Schristos 	/* s_port field */
684b5677b36Schristos 	tb = tmpbuf;
685b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
686b5677b36Schristos 	    strlen(tb) == 0U) {
687b5677b36Schristos 		goto error;
688b5677b36Schristos 	}
689b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
690b5677b36Schristos 	if (*tb) {
691b5677b36Schristos 		goto error;	/*%< junk in value */
692b5677b36Schristos 	}
693b5677b36Schristos 	svport = (short)t;
694b5677b36Schristos 	if ((long) svport != t) {	/*%< value must have been too big. */
695b5677b36Schristos 		goto error;
696b5677b36Schristos 	}
697b5677b36Schristos 	svport = htons(svport);
698b5677b36Schristos 
699b5677b36Schristos 	/* s_proto field */
700b5677b36Schristos 	proto = NULL;
701b5677b36Schristos 	if (getfield(&proto, 0, &p, fieldsep) == NULL) {
702b5677b36Schristos 		goto error;
703b5677b36Schristos 	}
704b5677b36Schristos 
705b5677b36Schristos 	sv->s_name = name;
706b5677b36Schristos 	sv->s_aliases = aliases;
707b5677b36Schristos 	sv->s_port = svport;
708b5677b36Schristos 	sv->s_proto = proto;
709b5677b36Schristos 
710b5677b36Schristos 	return (0);
711b5677b36Schristos 
712b5677b36Schristos  error:
713b5677b36Schristos 	errno = myerrno;
714b5677b36Schristos 
715b5677b36Schristos 	if (name != NULL) free(name);
716b5677b36Schristos 	if (proto != NULL) free(proto);
717b5677b36Schristos 	free_array(aliases, 0);
718b5677b36Schristos 
719b5677b36Schristos 	return (-1);
720b5677b36Schristos }
721b5677b36Schristos 
722b5677b36Schristos 
723b5677b36Schristos /* ------------------------- struct servent ------------------------- */
724b5677b36Schristos 
725b5677b36Schristos /* +++++++++++++++++++++++++ struct protoent +++++++++++++++++++++++++ */
726b5677b36Schristos 
727b5677b36Schristos /*%
728b5677b36Schristos  * int irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len)
729b5677b36Schristos  *
730b5677b36Schristos  * notes: \li
731b5677b36Schristos  *
732b5677b36Schristos  *	See irpmarshall.h
733b5677b36Schristos  *
734b5677b36Schristos  * return: \li
735b5677b36Schristos  *
736b5677b36Schristos  *	0 on success and -1 on failure.
737b5677b36Schristos  *
738b5677b36Schristos  */
739b5677b36Schristos 
740b5677b36Schristos int
irp_marshall_pr(struct protoent * pr,char ** buffer,size_t * len)741b5677b36Schristos irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len) {
742b5677b36Schristos 	size_t need = 1;	/*%< for null byte */
743b5677b36Schristos 	char prProto[24];
744b5677b36Schristos 	const char *fieldsep = COLONSTR;
745b5677b36Schristos 
746b5677b36Schristos 	if (pr == NULL || len == NULL) {
747b5677b36Schristos 		errno = EINVAL;
748b5677b36Schristos 		return (-1);
749b5677b36Schristos 	}
750b5677b36Schristos 
751b5677b36Schristos 	sprintf(prProto, "%d", (int)pr->p_proto);
752b5677b36Schristos 
753b5677b36Schristos 	need += strlen(pr->p_name) + 1;
754b5677b36Schristos 	need += joinlength(pr->p_aliases) + 1;
755b5677b36Schristos 	need += strlen(prProto) + 1;
756b5677b36Schristos 
757b5677b36Schristos 	if (buffer == NULL) {
758b5677b36Schristos 		*len = need;
759b5677b36Schristos 		return (0);
760b5677b36Schristos 	}
761b5677b36Schristos 
762b5677b36Schristos 	if (*buffer != NULL && need > *len) {
763b5677b36Schristos 		errno = EINVAL;
764b5677b36Schristos 		return (-1);
765b5677b36Schristos 	}
766b5677b36Schristos 
767b5677b36Schristos 	if (*buffer == NULL) {
768b5677b36Schristos 		need += 2;		/*%< for CRLF */
769b5677b36Schristos 		*buffer = memget(need);
770b5677b36Schristos 		if (*buffer == NULL) {
771b5677b36Schristos 			errno = ENOMEM;
772b5677b36Schristos 			return (-1);
773b5677b36Schristos 		}
774b5677b36Schristos 
775b5677b36Schristos 		*len = need;
776b5677b36Schristos 	}
777b5677b36Schristos 
778b5677b36Schristos 	strcpy(*buffer, pr->p_name);		strcat(*buffer, fieldsep);
779b5677b36Schristos 	joinarray(pr->p_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
780b5677b36Schristos 	strcat(*buffer, prProto);		strcat(*buffer, fieldsep);
781b5677b36Schristos 
782b5677b36Schristos 	return (0);
783b5677b36Schristos 
784b5677b36Schristos }
785b5677b36Schristos 
786b5677b36Schristos /*%
787b5677b36Schristos  * int irp_unmarshall_pr(struct protoent *pr, char *buffer)
788b5677b36Schristos  *
789b5677b36Schristos  * notes: \li
790b5677b36Schristos  *
791b5677b36Schristos  *	See irpmarshall.h
792b5677b36Schristos  *
793b5677b36Schristos  * return: \li
794b5677b36Schristos  *
795b5677b36Schristos  *	0 on success, -1 on failure
796b5677b36Schristos  *
797b5677b36Schristos  */
798b5677b36Schristos 
irp_unmarshall_pr(struct protoent * pr,char * buffer)799b5677b36Schristos int irp_unmarshall_pr(struct protoent *pr, char *buffer) {
800b5677b36Schristos 	char *p, *q;
801b5677b36Schristos 	int prproto;
802b5677b36Schristos 	long t;
803b5677b36Schristos 	char *name = NULL;
804b5677b36Schristos 	char **aliases = NULL;
805b5677b36Schristos 	char tmpbuf[24];
806b5677b36Schristos 	char *tb;
807b5677b36Schristos 	char fieldsep = ':';
808b5677b36Schristos 	int myerrno = EINVAL;
809b5677b36Schristos 
810b5677b36Schristos 	if (pr == NULL || buffer == NULL) {
811b5677b36Schristos 		errno = EINVAL;
812b5677b36Schristos 		return (-1);
813b5677b36Schristos 	}
814b5677b36Schristos 
815b5677b36Schristos 	p = buffer;
816b5677b36Schristos 
817b5677b36Schristos 	/* p_name field */
818b5677b36Schristos 	name = NULL;
819b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
820b5677b36Schristos 		goto error;
821b5677b36Schristos 	}
822b5677b36Schristos 
823b5677b36Schristos 
824b5677b36Schristos 	/* p_aliases field */
825b5677b36Schristos 	q = strchr(p, fieldsep);
826b5677b36Schristos 	if (q == NULL) {
827b5677b36Schristos 		goto error;
828b5677b36Schristos 	}
829b5677b36Schristos 	aliases = splitarray(p, q, COMMA);
830b5677b36Schristos 	if (aliases == NULL) {
831b5677b36Schristos 		myerrno = errno;
832b5677b36Schristos 		goto error;
833b5677b36Schristos 	}
834b5677b36Schristos 	p = q + 1;
835b5677b36Schristos 
836b5677b36Schristos 
837b5677b36Schristos 	/* p_proto field */
838b5677b36Schristos 	tb = tmpbuf;
839b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
840b5677b36Schristos 	    strlen(tb) == 0U) {
841b5677b36Schristos 		goto error;
842b5677b36Schristos 	}
843b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
844b5677b36Schristos 	if (*tb) {
845b5677b36Schristos 		goto error;	/*%< junk in value */
846b5677b36Schristos 	}
847b5677b36Schristos 	prproto = (int)t;
848b5677b36Schristos 	if ((long) prproto != t) {	/*%< value must have been too big. */
849b5677b36Schristos 		goto error;
850b5677b36Schristos 	}
851b5677b36Schristos 
852b5677b36Schristos 	pr->p_name = name;
853b5677b36Schristos 	pr->p_aliases = aliases;
854b5677b36Schristos 	pr->p_proto = prproto;
855b5677b36Schristos 
856b5677b36Schristos 	return (0);
857b5677b36Schristos 
858b5677b36Schristos  error:
859b5677b36Schristos 	errno = myerrno;
860b5677b36Schristos 
861b5677b36Schristos 	if (name != NULL) free(name);
862b5677b36Schristos 	free_array(aliases, 0);
863b5677b36Schristos 
864b5677b36Schristos 	return (-1);
865b5677b36Schristos }
866b5677b36Schristos 
867b5677b36Schristos /* ------------------------- struct protoent ------------------------- */
868b5677b36Schristos 
869b5677b36Schristos 
870b5677b36Schristos 
871b5677b36Schristos /* +++++++++++++++++++++++++ struct hostent +++++++++++++++++++++++++ */
872b5677b36Schristos 
873b5677b36Schristos /*%
874b5677b36Schristos  * int irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len)
875b5677b36Schristos  *
876b5677b36Schristos  * notes: \li
877b5677b36Schristos  *
878b5677b36Schristos  *	See irpmarshall.h.
879b5677b36Schristos  *
880b5677b36Schristos  * return: \li
881b5677b36Schristos  *
882b5677b36Schristos  *	0 on success, -1 on failure.
883b5677b36Schristos  *
884b5677b36Schristos  */
885b5677b36Schristos 
886b5677b36Schristos int
irp_marshall_ho(struct hostent * ho,char ** buffer,size_t * len)887b5677b36Schristos irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len) {
888b5677b36Schristos 	size_t need = 1;	/*%< for null byte */
889b5677b36Schristos 	char hoaddrtype[24];
890b5677b36Schristos 	char holength[24];
891b5677b36Schristos 	char **av;
892b5677b36Schristos 	char *p;
893b5677b36Schristos 	int addrlen;
894b5677b36Schristos 	int malloced = 0;
895b5677b36Schristos 	size_t remlen;
896b5677b36Schristos 	const char *fieldsep = "@";
897b5677b36Schristos 
898b5677b36Schristos 	if (ho == NULL || len == NULL) {
899b5677b36Schristos 		errno = EINVAL;
900b5677b36Schristos 		return (-1);
901b5677b36Schristos 	}
902b5677b36Schristos 
903b5677b36Schristos 	switch(ho->h_addrtype) {
904b5677b36Schristos 	case AF_INET:
905b5677b36Schristos 		strcpy(hoaddrtype, "AF_INET");
906b5677b36Schristos 		break;
907b5677b36Schristos 
908b5677b36Schristos 	case AF_INET6:
909b5677b36Schristos 		strcpy(hoaddrtype, "AF_INET6");
910b5677b36Schristos 		break;
911b5677b36Schristos 
912b5677b36Schristos 	default:
913b5677b36Schristos 		errno = EINVAL;
914b5677b36Schristos 		return (-1);
915b5677b36Schristos 	}
916b5677b36Schristos 
917b5677b36Schristos 	sprintf(holength, "%d", ho->h_length);
918b5677b36Schristos 
919b5677b36Schristos 	need += strlen(ho->h_name) + 1;
920b5677b36Schristos 	need += joinlength(ho->h_aliases) + 1;
921b5677b36Schristos 	need += strlen(hoaddrtype) + 1;
922b5677b36Schristos 	need += strlen(holength) + 1;
923b5677b36Schristos 
924b5677b36Schristos 	/* we determine an upper bound on the string length needed, not an
925b5677b36Schristos 	   exact length. */
926b5677b36Schristos 	addrlen = (ho->h_addrtype == AF_INET ? 16 : 46) ; /*%< XX other AF's?? */
927b5677b36Schristos 	for (av = ho->h_addr_list; av != NULL && *av != NULL ; av++)
928b5677b36Schristos 		need += addrlen;
929b5677b36Schristos 
930b5677b36Schristos 	if (buffer == NULL) {
931b5677b36Schristos 		*len = need;
932b5677b36Schristos 		return (0);
933b5677b36Schristos 	}
934b5677b36Schristos 
935b5677b36Schristos 	if (*buffer != NULL && need > *len) {
936b5677b36Schristos 		errno = EINVAL;
937b5677b36Schristos 		return (-1);
938b5677b36Schristos 	}
939b5677b36Schristos 
940b5677b36Schristos 	if (*buffer == NULL) {
941b5677b36Schristos 		need += 2;		/*%< for CRLF */
942b5677b36Schristos 		*buffer = memget(need);
943b5677b36Schristos 		if (*buffer == NULL) {
944b5677b36Schristos 			errno = ENOMEM;
945b5677b36Schristos 			return (-1);
946b5677b36Schristos 		}
947b5677b36Schristos 
948b5677b36Schristos 		*len = need;
949b5677b36Schristos 		malloced = 1;
950b5677b36Schristos 	}
951b5677b36Schristos 
952b5677b36Schristos 	strcpy(*buffer, ho->h_name);		strcat(*buffer, fieldsep);
953b5677b36Schristos 	joinarray(ho->h_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
954b5677b36Schristos 	strcat(*buffer, hoaddrtype);		strcat(*buffer, fieldsep);
955b5677b36Schristos 	strcat(*buffer, holength);		strcat(*buffer, fieldsep);
956b5677b36Schristos 
957b5677b36Schristos 	p = *buffer + strlen(*buffer);
958b5677b36Schristos 	remlen = need - strlen(*buffer);
959b5677b36Schristos 	for (av = ho->h_addr_list ; av != NULL && *av != NULL ; av++) {
960b5677b36Schristos 		if (inet_ntop(ho->h_addrtype, *av, p, remlen) == NULL) {
961b5677b36Schristos 			goto error;
962b5677b36Schristos 		}
963b5677b36Schristos 		if (*(av + 1) != NULL)
964b5677b36Schristos 			strcat(p, COMMASTR);
965b5677b36Schristos 		remlen -= strlen(p);
966b5677b36Schristos 		p += strlen(p);
967b5677b36Schristos 	}
968b5677b36Schristos 	strcat(*buffer, fieldsep);
969b5677b36Schristos 
970b5677b36Schristos 	return (0);
971b5677b36Schristos 
972b5677b36Schristos  error:
973b5677b36Schristos 	if (malloced) {
974b5677b36Schristos 		memput(*buffer, need);
975b5677b36Schristos 	}
976b5677b36Schristos 
977b5677b36Schristos 	return (-1);
978b5677b36Schristos }
979b5677b36Schristos 
980b5677b36Schristos /*%
981b5677b36Schristos  * int irp_unmarshall_ho(struct hostent *ho, char *buffer)
982b5677b36Schristos  *
983b5677b36Schristos  * notes: \li
984b5677b36Schristos  *
985b5677b36Schristos  *	See irpmarshall.h.
986b5677b36Schristos  *
987b5677b36Schristos  * return: \li
988b5677b36Schristos  *
989b5677b36Schristos  *	0 on success, -1 on failure.
990b5677b36Schristos  *
991b5677b36Schristos  */
992b5677b36Schristos 
993b5677b36Schristos int
irp_unmarshall_ho(struct hostent * ho,char * buffer)994b5677b36Schristos irp_unmarshall_ho(struct hostent *ho, char *buffer) {
995b5677b36Schristos 	char *p, *q, *r;
996b5677b36Schristos 	int hoaddrtype;
997b5677b36Schristos 	int holength;
998b5677b36Schristos 	long t;
999b5677b36Schristos 	char *name;
1000b5677b36Schristos 	char **aliases = NULL;
1001b5677b36Schristos 	char **hohaddrlist = NULL;
1002b5677b36Schristos 	size_t hoaddrsize;
1003b5677b36Schristos 	char tmpbuf[24];
1004b5677b36Schristos 	char *tb;
1005b5677b36Schristos 	char **alist;
1006b5677b36Schristos 	int addrcount;
1007b5677b36Schristos 	char fieldsep = '@';
1008b5677b36Schristos 	int myerrno = EINVAL;
1009b5677b36Schristos 
1010b5677b36Schristos 	if (ho == NULL || buffer == NULL) {
1011b5677b36Schristos 		errno = EINVAL;
1012b5677b36Schristos 		return (-1);
1013b5677b36Schristos 	}
1014b5677b36Schristos 
1015b5677b36Schristos 	p = buffer;
1016b5677b36Schristos 
1017b5677b36Schristos 	/* h_name field */
1018b5677b36Schristos 	name = NULL;
1019b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
1020b5677b36Schristos 		goto error;
1021b5677b36Schristos 	}
1022b5677b36Schristos 
1023b5677b36Schristos 
1024b5677b36Schristos 	/* h_aliases field */
1025b5677b36Schristos 	q = strchr(p, fieldsep);
1026b5677b36Schristos 	if (q == NULL) {
1027b5677b36Schristos 		goto error;
1028b5677b36Schristos 	}
1029b5677b36Schristos 	aliases = splitarray(p, q, COMMA);
1030b5677b36Schristos 	if (aliases == NULL) {
1031b5677b36Schristos 		myerrno = errno;
1032b5677b36Schristos 		goto error;
1033b5677b36Schristos 	}
1034b5677b36Schristos 	p = q + 1;
1035b5677b36Schristos 
1036b5677b36Schristos 
1037b5677b36Schristos 	/* h_addrtype field */
1038b5677b36Schristos 	tb = tmpbuf;
1039b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1040b5677b36Schristos 	    strlen(tb) == 0U) {
1041b5677b36Schristos 		goto error;
1042b5677b36Schristos 	}
1043b5677b36Schristos 	if (strcmp(tmpbuf, "AF_INET") == 0)
1044b5677b36Schristos 		hoaddrtype = AF_INET;
1045b5677b36Schristos 	else if (strcmp(tmpbuf, "AF_INET6") == 0)
1046b5677b36Schristos 		hoaddrtype = AF_INET6;
1047b5677b36Schristos 	else
1048b5677b36Schristos 		goto error;
1049b5677b36Schristos 
1050b5677b36Schristos 
1051b5677b36Schristos 	/* h_length field */
1052b5677b36Schristos 	tb = tmpbuf;
1053b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1054b5677b36Schristos 	    strlen(tb) == 0U) {
1055b5677b36Schristos 		goto error;
1056b5677b36Schristos 	}
1057b5677b36Schristos 	t = strtol(tmpbuf, &tb, 10);
1058b5677b36Schristos 	if (*tb) {
1059b5677b36Schristos 		goto error;	/*%< junk in value */
1060b5677b36Schristos 	}
1061b5677b36Schristos 	holength = (int)t;
1062b5677b36Schristos 	if ((long) holength != t) {	/*%< value must have been too big. */
1063b5677b36Schristos 		goto error;
1064b5677b36Schristos 	}
1065b5677b36Schristos 
1066b5677b36Schristos 
1067b5677b36Schristos 	/* h_addr_list field */
1068b5677b36Schristos 	q = strchr(p, fieldsep);
1069b5677b36Schristos 	if (q == NULL)
1070b5677b36Schristos 		goto error;
1071b5677b36Schristos 
1072b5677b36Schristos 	/* count how many addresss are in there */
1073b5677b36Schristos 	if (q > p + 1) {
1074b5677b36Schristos 		for (addrcount = 1, r = p ; r != q ; r++) {
1075b5677b36Schristos 			if (*r == COMMA)
1076b5677b36Schristos 				addrcount++;
1077b5677b36Schristos 		}
1078b5677b36Schristos 	} else {
1079b5677b36Schristos 		addrcount = 0;
1080b5677b36Schristos 	}
1081b5677b36Schristos 
1082b5677b36Schristos 	hoaddrsize = (addrcount + 1) * sizeof (char *);
1083b5677b36Schristos 	hohaddrlist = malloc(hoaddrsize);
1084b5677b36Schristos 	if (hohaddrlist == NULL) {
1085b5677b36Schristos 		myerrno = ENOMEM;
1086b5677b36Schristos 		goto error;
1087b5677b36Schristos 	}
1088b5677b36Schristos 
1089b5677b36Schristos 	memset(hohaddrlist, 0x0, hoaddrsize);
1090b5677b36Schristos 
1091b5677b36Schristos 	alist = hohaddrlist;
1092b5677b36Schristos 	for (t = 0, r = p ; r != q ; p = r + 1, t++) {
1093b5677b36Schristos 		char saved;
1094b5677b36Schristos 		while (r != q && *r != COMMA) r++;
1095b5677b36Schristos 		saved = *r;
1096b5677b36Schristos 		*r = 0x0;
1097b5677b36Schristos 
1098b5677b36Schristos 		alist[t] = malloc(hoaddrtype == AF_INET ? 4 : 16);
1099b5677b36Schristos 		if (alist[t] == NULL) {
1100b5677b36Schristos 			myerrno = ENOMEM;
1101b5677b36Schristos 			goto error;
1102b5677b36Schristos 		}
1103b5677b36Schristos 
1104b5677b36Schristos 		if (inet_pton(hoaddrtype, p, alist[t]) == -1)
1105b5677b36Schristos 			goto error;
1106b5677b36Schristos 		*r = saved;
1107b5677b36Schristos 	}
1108b5677b36Schristos 	alist[t] = NULL;
1109b5677b36Schristos 
1110b5677b36Schristos 	ho->h_name = name;
1111b5677b36Schristos 	ho->h_aliases = aliases;
1112b5677b36Schristos 	ho->h_addrtype = hoaddrtype;
1113b5677b36Schristos 	ho->h_length = holength;
1114b5677b36Schristos 	ho->h_addr_list = hohaddrlist;
1115b5677b36Schristos 
1116b5677b36Schristos 	return (0);
1117b5677b36Schristos 
1118b5677b36Schristos  error:
1119b5677b36Schristos 	errno = myerrno;
1120b5677b36Schristos 
1121b5677b36Schristos 	if (name != NULL) free(name);
1122b5677b36Schristos 	free_array(hohaddrlist, 0);
1123b5677b36Schristos 	free_array(aliases, 0);
1124b5677b36Schristos 
1125b5677b36Schristos 	return (-1);
1126b5677b36Schristos }
1127b5677b36Schristos 
1128b5677b36Schristos /* ------------------------- struct hostent------------------------- */
1129b5677b36Schristos 
1130b5677b36Schristos 
1131b5677b36Schristos 
1132b5677b36Schristos /* +++++++++++++++++++++++++ struct netgrp +++++++++++++++++++++++++ */
1133b5677b36Schristos 
1134b5677b36Schristos /*%
1135b5677b36Schristos  * int irp_marshall_ng(const char *host, const char *user,
1136b5677b36Schristos  *		       const char *domain, char *buffer, size_t *len)
1137b5677b36Schristos  *
1138b5677b36Schristos  * notes: \li
1139b5677b36Schristos  *
1140b5677b36Schristos  *	See note for irp_marshall_ng_start
1141b5677b36Schristos  *
1142b5677b36Schristos  * return: \li
1143b5677b36Schristos  *
1144b5677b36Schristos  *	0 on success, 0 on failure.
1145b5677b36Schristos  *
1146b5677b36Schristos  */
1147b5677b36Schristos 
1148b5677b36Schristos int
irp_marshall_ng(const char * host,const char * user,const char * domain,char ** buffer,size_t * len)1149b5677b36Schristos irp_marshall_ng(const char *host, const char *user, const char *domain,
1150b5677b36Schristos 		char **buffer, size_t *len) {
1151b5677b36Schristos 	size_t need = 1; /*%< for nul byte */
1152b5677b36Schristos 	const char *fieldsep = ",";
1153b5677b36Schristos 
1154b5677b36Schristos 	if (len == NULL) {
1155b5677b36Schristos 		errno = EINVAL;
1156b5677b36Schristos 		return (-1);
1157b5677b36Schristos 	}
1158b5677b36Schristos 
1159b5677b36Schristos 	need += 4;		       /*%< two parens and two commas */
1160b5677b36Schristos 	need += (host == NULL ? 0 : strlen(host));
1161b5677b36Schristos 	need += (user == NULL ? 0 : strlen(user));
1162b5677b36Schristos 	need += (domain == NULL ? 0 : strlen(domain));
1163b5677b36Schristos 
1164b5677b36Schristos 	if (buffer == NULL) {
1165b5677b36Schristos 		*len = need;
1166b5677b36Schristos 		return (0);
1167b5677b36Schristos 	} else if (*buffer != NULL && need > *len) {
1168b5677b36Schristos 		errno = EINVAL;
1169b5677b36Schristos 		return (-1);
1170b5677b36Schristos 	}
1171b5677b36Schristos 
1172b5677b36Schristos 	if (*buffer == NULL) {
1173b5677b36Schristos 		need += 2;		/*%< for CRLF */
1174b5677b36Schristos 		*buffer = memget(need);
1175b5677b36Schristos 		if (*buffer == NULL) {
1176b5677b36Schristos 			errno = ENOMEM;
1177b5677b36Schristos 			return (-1);
1178b5677b36Schristos 		}
1179b5677b36Schristos 
1180b5677b36Schristos 		*len = need;
1181b5677b36Schristos 	}
1182b5677b36Schristos 
1183b5677b36Schristos 	(*buffer)[0] = '(';
1184b5677b36Schristos 	(*buffer)[1] = '\0';
1185b5677b36Schristos 
1186b5677b36Schristos 	if (host != NULL)
1187b5677b36Schristos 		strcat(*buffer, host);
1188b5677b36Schristos 	strcat(*buffer, fieldsep);
1189b5677b36Schristos 
1190b5677b36Schristos 	if (user != NULL)
1191b5677b36Schristos 		strcat(*buffer, user);
1192b5677b36Schristos 	strcat(*buffer, fieldsep);
1193b5677b36Schristos 
1194b5677b36Schristos 	if (domain != NULL)
1195b5677b36Schristos 		strcat(*buffer, domain);
1196b5677b36Schristos 	strcat(*buffer, ")");
1197b5677b36Schristos 
1198b5677b36Schristos 	return (0);
1199b5677b36Schristos }
1200b5677b36Schristos 
1201b5677b36Schristos 
1202b5677b36Schristos 
1203b5677b36Schristos /* ---------- */
1204b5677b36Schristos 
1205b5677b36Schristos /*%
1206b5677b36Schristos  * int irp_unmarshall_ng(const char **host, const char **user,
1207b5677b36Schristos  *			 const char **domain, char *buffer)
1208b5677b36Schristos  *
1209b5677b36Schristos  * notes: \li
1210b5677b36Schristos  *
1211b5677b36Schristos  *	Unpacks the BUFFER into 3 character arrays it allocates and assigns
1212b5677b36Schristos  *	to *HOST, *USER and *DOMAIN. If any field of the value is empty,
1213b5677b36Schristos  *	then the corresponding paramater value will be set to NULL.
1214b5677b36Schristos  *
1215b5677b36Schristos  * return: \li
1216b5677b36Schristos  *
1217b5677b36Schristos  *	0 on success and -1 on failure.
1218b5677b36Schristos  */
1219b5677b36Schristos 
1220b5677b36Schristos int
irp_unmarshall_ng(const char ** hostp,const char ** userp,const char ** domainp,char * buffer)1221b5677b36Schristos irp_unmarshall_ng(const char **hostp, const char **userp, const char **domainp,
1222b5677b36Schristos 		  char *buffer)
1223b5677b36Schristos {
1224b5677b36Schristos 	char *p, *q;
1225b5677b36Schristos 	char fieldsep = ',';
1226b5677b36Schristos 	int myerrno = EINVAL;
1227b5677b36Schristos 	char *host, *user, *domain;
1228b5677b36Schristos 
1229b5677b36Schristos 	if (userp == NULL || hostp == NULL ||
1230b5677b36Schristos 	    domainp == NULL || buffer == NULL) {
1231b5677b36Schristos 		errno = EINVAL;
1232b5677b36Schristos 		return (-1);
1233b5677b36Schristos 	}
1234b5677b36Schristos 
1235b5677b36Schristos 	host = user = domain = NULL;
1236b5677b36Schristos 
1237b5677b36Schristos 	p = buffer;
1238b5677b36Schristos 	while (isspace((unsigned char)*p)) {
1239b5677b36Schristos 		p++;
1240b5677b36Schristos 	}
1241b5677b36Schristos 	if (*p != '(') {
1242b5677b36Schristos 		goto error;
1243b5677b36Schristos 	}
1244b5677b36Schristos 
1245b5677b36Schristos 	q = p + 1;
1246b5677b36Schristos 	while (*q && *q != fieldsep)
1247b5677b36Schristos 		q++;
1248b5677b36Schristos 	if (!*q) {
1249b5677b36Schristos 		goto error;
1250b5677b36Schristos 	} else if (q > p + 1) {
1251b5677b36Schristos 		host = strndup(p, q - p);
1252b5677b36Schristos 	}
1253b5677b36Schristos 
1254b5677b36Schristos 	p = q + 1;
1255b5677b36Schristos 	if (!*p) {
1256b5677b36Schristos 		goto error;
1257b5677b36Schristos 	} else if (*p != fieldsep) {
1258b5677b36Schristos 		q = p + 1;
1259b5677b36Schristos 		while (*q && *q != fieldsep)
1260b5677b36Schristos 			q++;
1261b5677b36Schristos 		if (!*q) {
1262b5677b36Schristos 			goto error;
1263b5677b36Schristos 		}
1264b5677b36Schristos 		user = strndup(p, q - p);
1265b5677b36Schristos 	} else {
1266b5677b36Schristos 		p++;
1267b5677b36Schristos 	}
1268b5677b36Schristos 
1269b5677b36Schristos 	if (!*p) {
1270b5677b36Schristos 		goto error;
1271b5677b36Schristos 	} else if (*p != ')') {
1272b5677b36Schristos 		q = p + 1;
1273b5677b36Schristos 		while (*q && *q != ')')
1274b5677b36Schristos 			q++;
1275b5677b36Schristos 		if (!*q) {
1276b5677b36Schristos 			goto error;
1277b5677b36Schristos 		}
1278b5677b36Schristos 		domain = strndup(p, q - p);
1279b5677b36Schristos 	}
1280b5677b36Schristos 	*hostp = host;
1281b5677b36Schristos 	*userp = user;
1282b5677b36Schristos 	*domainp = domain;
1283b5677b36Schristos 
1284b5677b36Schristos 	return (0);
1285b5677b36Schristos 
1286b5677b36Schristos  error:
1287b5677b36Schristos 	errno = myerrno;
1288b5677b36Schristos 
1289b5677b36Schristos 	if (host != NULL) free(host);
1290b5677b36Schristos 	if (user != NULL) free(user);
1291b5677b36Schristos 
1292b5677b36Schristos 	return (-1);
1293b5677b36Schristos }
1294b5677b36Schristos 
1295b5677b36Schristos /* ------------------------- struct netgrp ------------------------- */
1296b5677b36Schristos 
1297b5677b36Schristos 
1298b5677b36Schristos 
1299b5677b36Schristos 
1300b5677b36Schristos /* +++++++++++++++++++++++++ struct nwent +++++++++++++++++++++++++ */
1301b5677b36Schristos 
1302b5677b36Schristos /*%
1303b5677b36Schristos  * int irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len)
1304b5677b36Schristos  *
1305b5677b36Schristos  * notes: \li
1306b5677b36Schristos  *
1307b5677b36Schristos  *	See at top.
1308b5677b36Schristos  *
1309b5677b36Schristos  * return: \li
1310b5677b36Schristos  *
1311b5677b36Schristos  *	0 on success and -1 on failure.
1312b5677b36Schristos  *
1313b5677b36Schristos  */
1314b5677b36Schristos 
1315b5677b36Schristos int
irp_marshall_nw(struct nwent * ne,char ** buffer,size_t * len)1316b5677b36Schristos irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len) {
1317b5677b36Schristos 	size_t need = 1;	/*%< for null byte */
1318b5677b36Schristos 	char nAddrType[24];
1319b5677b36Schristos 	char nNet[MAXPADDRSIZE];
1320b5677b36Schristos 	const char *fieldsep = COLONSTR;
1321b5677b36Schristos 
1322b5677b36Schristos 	if (ne == NULL || len == NULL) {
1323b5677b36Schristos 		return (-1);
1324b5677b36Schristos 	}
1325b5677b36Schristos 
1326b5677b36Schristos 	strcpy(nAddrType, ADDR_T_STR(ne->n_addrtype));
1327b5677b36Schristos 
1328b5677b36Schristos 	if (inet_net_ntop(ne->n_addrtype, ne->n_addr, ne->n_length,
1329b5677b36Schristos 			  nNet, sizeof nNet) == NULL) {
1330b5677b36Schristos 		return (-1);
1331b5677b36Schristos 	}
1332b5677b36Schristos 
1333b5677b36Schristos 
1334b5677b36Schristos 	need += strlen(ne->n_name) + 1;
1335b5677b36Schristos 	need += joinlength(ne->n_aliases) + 1;
1336b5677b36Schristos 	need += strlen(nAddrType) + 1;
1337b5677b36Schristos 	need += strlen(nNet) + 1;
1338b5677b36Schristos 
1339b5677b36Schristos 	if (buffer == NULL) {
1340b5677b36Schristos 		*len = need;
1341b5677b36Schristos 		return (0);
1342b5677b36Schristos 	}
1343b5677b36Schristos 
1344b5677b36Schristos 	if (*buffer != NULL && need > *len) {
1345b5677b36Schristos 		errno = EINVAL;
1346b5677b36Schristos 		return (-1);
1347b5677b36Schristos 	}
1348b5677b36Schristos 
1349b5677b36Schristos 	if (*buffer == NULL) {
1350b5677b36Schristos 		need += 2;		/*%< for CRLF */
1351b5677b36Schristos 		*buffer = memget(need);
1352b5677b36Schristos 		if (*buffer == NULL) {
1353b5677b36Schristos 			errno = ENOMEM;
1354b5677b36Schristos 			return (-1);
1355b5677b36Schristos 		}
1356b5677b36Schristos 
1357b5677b36Schristos 		*len = need;
1358b5677b36Schristos 	}
1359b5677b36Schristos 
1360b5677b36Schristos 	strcpy(*buffer, ne->n_name);		strcat(*buffer, fieldsep);
1361b5677b36Schristos 	joinarray(ne->n_aliases, *buffer, COMMA) ; strcat(*buffer, fieldsep);
1362b5677b36Schristos 	strcat(*buffer, nAddrType);		strcat(*buffer, fieldsep);
1363b5677b36Schristos 	strcat(*buffer, nNet);			strcat(*buffer, fieldsep);
1364b5677b36Schristos 
1365b5677b36Schristos 	return (0);
1366b5677b36Schristos }
1367b5677b36Schristos 
1368b5677b36Schristos /*%
1369b5677b36Schristos  * int irp_unmarshall_nw(struct nwent *ne, char *buffer)
1370b5677b36Schristos  *
1371b5677b36Schristos  * notes: \li
1372b5677b36Schristos  *
1373b5677b36Schristos  *	See note up top.
1374b5677b36Schristos  *
1375b5677b36Schristos  * return: \li
1376b5677b36Schristos  *
1377b5677b36Schristos  *	0 on success and -1 on failure.
1378b5677b36Schristos  *
1379b5677b36Schristos  */
1380b5677b36Schristos 
1381b5677b36Schristos int
irp_unmarshall_nw(struct nwent * ne,char * buffer)1382b5677b36Schristos irp_unmarshall_nw(struct nwent *ne, char *buffer) {
1383b5677b36Schristos 	char *p, *q;
1384b5677b36Schristos 	int naddrtype;
1385b5677b36Schristos 	long nnet;
1386b5677b36Schristos 	int bits;
1387b5677b36Schristos 	char *name = NULL;
1388b5677b36Schristos 	char **aliases = NULL;
1389b5677b36Schristos 	char tmpbuf[24];
1390b5677b36Schristos 	char *tb;
1391b5677b36Schristos 	char fieldsep = ':';
1392b5677b36Schristos 	int myerrno = EINVAL;
1393b5677b36Schristos 
1394b5677b36Schristos 	if (ne == NULL || buffer == NULL) {
1395b5677b36Schristos 		goto error;
1396b5677b36Schristos 	}
1397b5677b36Schristos 
1398b5677b36Schristos 	p = buffer;
1399b5677b36Schristos 
1400b5677b36Schristos 	/* n_name field */
1401b5677b36Schristos 	name = NULL;
1402b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
1403b5677b36Schristos 		goto error;
1404b5677b36Schristos 	}
1405b5677b36Schristos 
1406b5677b36Schristos 
1407b5677b36Schristos 	/* n_aliases field. Aliases are separated by commas */
1408b5677b36Schristos 	q = strchr(p, fieldsep);
1409b5677b36Schristos 	if (q == NULL) {
1410b5677b36Schristos 		goto error;
1411b5677b36Schristos 	}
1412b5677b36Schristos 	aliases = splitarray(p, q, COMMA);
1413b5677b36Schristos 	if (aliases == NULL) {
1414b5677b36Schristos 		myerrno = errno;
1415b5677b36Schristos 		goto error;
1416b5677b36Schristos 	}
1417b5677b36Schristos 	p = q + 1;
1418b5677b36Schristos 
1419b5677b36Schristos 
1420b5677b36Schristos 	/* h_addrtype field */
1421b5677b36Schristos 	tb = tmpbuf;
1422b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1423b5677b36Schristos 	    strlen(tb) == 0U) {
1424b5677b36Schristos 		goto error;
1425b5677b36Schristos 	}
1426b5677b36Schristos 	if (strcmp(tmpbuf, "AF_INET") == 0)
1427b5677b36Schristos 		naddrtype = AF_INET;
1428b5677b36Schristos 	else if (strcmp(tmpbuf, "AF_INET6") == 0)
1429b5677b36Schristos 		naddrtype = AF_INET6;
1430b5677b36Schristos 	else
1431b5677b36Schristos 		goto error;
1432b5677b36Schristos 
1433b5677b36Schristos 
1434b5677b36Schristos 	/* n_net field */
1435b5677b36Schristos 	tb = tmpbuf;
1436b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1437b5677b36Schristos 	    strlen(tb) == 0U) {
1438b5677b36Schristos 		goto error;
1439b5677b36Schristos 	}
1440b5677b36Schristos 	nnet = 0;
1441b5677b36Schristos 	bits = inet_net_pton(naddrtype, tmpbuf, &nnet, sizeof nnet);
1442b5677b36Schristos 	if (bits < 0) {
1443b5677b36Schristos 		goto error;
1444b5677b36Schristos 	}
1445b5677b36Schristos 
1446b5677b36Schristos 	/* nnet = ntohl(nnet); */ /* keep in network order for nwent */
1447b5677b36Schristos 
1448b5677b36Schristos 	ne->n_name = name;
1449b5677b36Schristos 	ne->n_aliases = aliases;
1450b5677b36Schristos 	ne->n_addrtype = naddrtype;
1451b5677b36Schristos 	ne->n_length = bits;
1452b5677b36Schristos 	ne->n_addr = malloc(sizeof nnet);
1453b5677b36Schristos 	if (ne->n_addr == NULL) {
1454b5677b36Schristos 		goto error;
1455b5677b36Schristos 	}
1456b5677b36Schristos 
1457b5677b36Schristos 	memcpy(ne->n_addr, &nnet, sizeof nnet);
1458b5677b36Schristos 
1459b5677b36Schristos 	return (0);
1460b5677b36Schristos 
1461b5677b36Schristos  error:
1462b5677b36Schristos 	errno = myerrno;
1463b5677b36Schristos 
1464b5677b36Schristos 	if (name != NULL) free(name);
1465b5677b36Schristos 	free_array(aliases, 0);
1466b5677b36Schristos 
1467b5677b36Schristos 	return (-1);
1468b5677b36Schristos }
1469b5677b36Schristos 
1470b5677b36Schristos 
1471b5677b36Schristos /* ------------------------- struct nwent ------------------------- */
1472b5677b36Schristos 
1473b5677b36Schristos 
1474b5677b36Schristos /* +++++++++++++++++++++++++ struct netent +++++++++++++++++++++++++ */
1475b5677b36Schristos 
1476b5677b36Schristos /*%
1477b5677b36Schristos  * int irp_marshall_ne(struct netent *ne, char **buffer, size_t *len)
1478b5677b36Schristos  *
1479b5677b36Schristos  * notes: \li
1480b5677b36Schristos  *
1481b5677b36Schristos  *	See at top.
1482b5677b36Schristos  *
1483b5677b36Schristos  * return: \li
1484b5677b36Schristos  *
1485b5677b36Schristos  *	0 on success and -1 on failure.
1486b5677b36Schristos  *
1487b5677b36Schristos  */
1488b5677b36Schristos 
1489b5677b36Schristos int
irp_marshall_ne(struct netent * ne,char ** buffer,size_t * len)1490b5677b36Schristos irp_marshall_ne(struct netent *ne, char **buffer, size_t *len) {
1491b5677b36Schristos 	size_t need = 1;	/*%< for null byte */
1492b5677b36Schristos 	char nAddrType[24];
1493b5677b36Schristos 	char nNet[MAXPADDRSIZE];
1494b5677b36Schristos 	const char *fieldsep = COLONSTR;
1495b5677b36Schristos 	long nval;
1496b5677b36Schristos 
1497b5677b36Schristos 	if (ne == NULL || len == NULL) {
1498b5677b36Schristos 		return (-1);
1499b5677b36Schristos 	}
1500b5677b36Schristos 
1501b5677b36Schristos 	strcpy(nAddrType, ADDR_T_STR(ne->n_addrtype));
1502b5677b36Schristos 
1503b5677b36Schristos 	nval = htonl(ne->n_net);
1504b5677b36Schristos 	if (inet_ntop(ne->n_addrtype, &nval, nNet, sizeof nNet) == NULL) {
1505b5677b36Schristos 		return (-1);
1506b5677b36Schristos 	}
1507b5677b36Schristos 
1508b5677b36Schristos 	need += strlen(ne->n_name) + 1;
1509b5677b36Schristos 	need += joinlength(ne->n_aliases) + 1;
1510b5677b36Schristos 	need += strlen(nAddrType) + 1;
1511b5677b36Schristos 	need += strlen(nNet) + 1;
1512b5677b36Schristos 
1513b5677b36Schristos 	if (buffer == NULL) {
1514b5677b36Schristos 		*len = need;
1515b5677b36Schristos 		return (0);
1516b5677b36Schristos 	}
1517b5677b36Schristos 
1518b5677b36Schristos 	if (*buffer != NULL && need > *len) {
1519b5677b36Schristos 		errno = EINVAL;
1520b5677b36Schristos 		return (-1);
1521b5677b36Schristos 	}
1522b5677b36Schristos 
1523b5677b36Schristos 	if (*buffer == NULL) {
1524b5677b36Schristos 		need += 2;		/*%< for CRLF */
1525b5677b36Schristos 		*buffer = memget(need);
1526b5677b36Schristos 		if (*buffer == NULL) {
1527b5677b36Schristos 			errno = ENOMEM;
1528b5677b36Schristos 			return (-1);
1529b5677b36Schristos 		}
1530b5677b36Schristos 
1531b5677b36Schristos 		*len = need;
1532b5677b36Schristos 	}
1533b5677b36Schristos 
1534b5677b36Schristos 	strcpy(*buffer, ne->n_name);		strcat(*buffer, fieldsep);
1535b5677b36Schristos 	joinarray(ne->n_aliases, *buffer, COMMA) ; strcat(*buffer, fieldsep);
1536b5677b36Schristos 	strcat(*buffer, nAddrType);		strcat(*buffer, fieldsep);
1537b5677b36Schristos 	strcat(*buffer, nNet);			strcat(*buffer, fieldsep);
1538b5677b36Schristos 
1539b5677b36Schristos 	return (0);
1540b5677b36Schristos }
1541b5677b36Schristos 
1542b5677b36Schristos /*%
1543b5677b36Schristos  * int irp_unmarshall_ne(struct netent *ne, char *buffer)
1544b5677b36Schristos  *
1545b5677b36Schristos  * notes: \li
1546b5677b36Schristos  *
1547b5677b36Schristos  *	See note up top.
1548b5677b36Schristos  *
1549b5677b36Schristos  * return: \li
1550b5677b36Schristos  *
1551b5677b36Schristos  *	0 on success and -1 on failure.
1552b5677b36Schristos  *
1553b5677b36Schristos  */
1554b5677b36Schristos 
1555b5677b36Schristos int
irp_unmarshall_ne(struct netent * ne,char * buffer)1556b5677b36Schristos irp_unmarshall_ne(struct netent *ne, char *buffer) {
1557b5677b36Schristos 	char *p, *q;
1558b5677b36Schristos 	int naddrtype;
1559b5677b36Schristos 	long nnet;
1560b5677b36Schristos 	int bits;
1561b5677b36Schristos 	char *name = NULL;
1562b5677b36Schristos 	char **aliases = NULL;
1563b5677b36Schristos 	char tmpbuf[24];
1564b5677b36Schristos 	char *tb;
1565b5677b36Schristos 	char fieldsep = ':';
1566b5677b36Schristos 	int myerrno = EINVAL;
1567b5677b36Schristos 
1568b5677b36Schristos 	if (ne == NULL || buffer == NULL) {
1569b5677b36Schristos 		goto error;
1570b5677b36Schristos 	}
1571b5677b36Schristos 
1572b5677b36Schristos 	p = buffer;
1573b5677b36Schristos 
1574b5677b36Schristos 	/* n_name field */
1575b5677b36Schristos 	name = NULL;
1576b5677b36Schristos 	if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
1577b5677b36Schristos 		goto error;
1578b5677b36Schristos 	}
1579b5677b36Schristos 
1580b5677b36Schristos 
1581b5677b36Schristos 	/* n_aliases field. Aliases are separated by commas */
1582b5677b36Schristos 	q = strchr(p, fieldsep);
1583b5677b36Schristos 	if (q == NULL) {
1584b5677b36Schristos 		goto error;
1585b5677b36Schristos 	}
1586b5677b36Schristos 	aliases = splitarray(p, q, COMMA);
1587b5677b36Schristos 	if (aliases == NULL) {
1588b5677b36Schristos 		myerrno = errno;
1589b5677b36Schristos 		goto error;
1590b5677b36Schristos 	}
1591b5677b36Schristos 	p = q + 1;
1592b5677b36Schristos 
1593b5677b36Schristos 
1594b5677b36Schristos 	/* h_addrtype field */
1595b5677b36Schristos 	tb = tmpbuf;
1596b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1597b5677b36Schristos 	    strlen(tb) == 0U) {
1598b5677b36Schristos 		goto error;
1599b5677b36Schristos 	}
1600b5677b36Schristos 	if (strcmp(tmpbuf, "AF_INET") == 0)
1601b5677b36Schristos 		naddrtype = AF_INET;
1602b5677b36Schristos 	else if (strcmp(tmpbuf, "AF_INET6") == 0)
1603b5677b36Schristos 		naddrtype = AF_INET6;
1604b5677b36Schristos 	else
1605b5677b36Schristos 		goto error;
1606b5677b36Schristos 
1607b5677b36Schristos 
1608b5677b36Schristos 	/* n_net field */
1609b5677b36Schristos 	tb = tmpbuf;
1610b5677b36Schristos 	if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1611b5677b36Schristos 	    strlen(tb) == 0U) {
1612b5677b36Schristos 		goto error;
1613b5677b36Schristos 	}
1614b5677b36Schristos 	bits = inet_net_pton(naddrtype, tmpbuf, &nnet, sizeof nnet);
1615b5677b36Schristos 	if (bits < 0) {
1616b5677b36Schristos 		goto error;
1617b5677b36Schristos 	}
1618b5677b36Schristos 	nnet = ntohl(nnet);
1619b5677b36Schristos 
1620b5677b36Schristos 	ne->n_name = name;
1621b5677b36Schristos 	ne->n_aliases = aliases;
1622b5677b36Schristos 	ne->n_addrtype = naddrtype;
1623b5677b36Schristos 	ne->n_net = nnet;
1624b5677b36Schristos 
1625b5677b36Schristos 	return (0);
1626b5677b36Schristos 
1627b5677b36Schristos  error:
1628b5677b36Schristos 	errno = myerrno;
1629b5677b36Schristos 
1630b5677b36Schristos 	if (name != NULL) free(name);
1631b5677b36Schristos 	free_array(aliases, 0);
1632b5677b36Schristos 
1633b5677b36Schristos 	return (-1);
1634b5677b36Schristos }
1635b5677b36Schristos 
1636b5677b36Schristos 
1637b5677b36Schristos /* ------------------------- struct netent ------------------------- */
1638b5677b36Schristos 
1639b5677b36Schristos 
1640b5677b36Schristos /* =========================================================================== */
1641b5677b36Schristos 
1642b5677b36Schristos /*%
1643b5677b36Schristos  * static char ** splitarray(const char *buffer, const char *buffend, char delim)
1644b5677b36Schristos  *
1645b5677b36Schristos  * notes: \li
1646b5677b36Schristos  *
1647b5677b36Schristos  *	Split a delim separated astring. Not allowed
1648b5677b36Schristos  *	to have two delims next to each other. BUFFER points to begining of
1649b5677b36Schristos  *	string, BUFFEND points to one past the end of the string
1650b5677b36Schristos  *	(i.e. points at where the null byte would be if null
1651b5677b36Schristos  *	terminated).
1652b5677b36Schristos  *
1653b5677b36Schristos  * return: \li
1654b5677b36Schristos  *
1655b5677b36Schristos  *	Returns a malloced array of pointers, each pointer pointing to a
1656b5677b36Schristos  *	malloced string. If BUFEER is an empty string, then return values is
1657b5677b36Schristos  *	array of 1 pointer that is NULL. Returns NULL on failure.
1658b5677b36Schristos  *
1659b5677b36Schristos  */
1660b5677b36Schristos 
1661b5677b36Schristos static char **
splitarray(const char * buffer,const char * buffend,char delim)1662b5677b36Schristos splitarray(const char *buffer, const char *buffend, char delim) {
1663b5677b36Schristos 	const char *p, *q;
1664b5677b36Schristos 	int count = 0;
1665b5677b36Schristos 	char **arr = NULL;
1666b5677b36Schristos 	char **aptr;
1667b5677b36Schristos 
1668b5677b36Schristos 	if (buffend < buffer)
1669b5677b36Schristos 		return (NULL);
1670b5677b36Schristos 	else if (buffend > buffer && *buffer == delim)
1671b5677b36Schristos 		return (NULL);
1672b5677b36Schristos 	else if (buffend > buffer && *(buffend - 1) == delim)
1673b5677b36Schristos 		return (NULL);
1674b5677b36Schristos 
1675b5677b36Schristos 	/* count the number of field and make sure none are empty */
1676b5677b36Schristos 	if (buffend > buffer + 1) {
1677b5677b36Schristos 		for (count = 1, q = buffer ; q != buffend ; q++) {
1678b5677b36Schristos 			if (*q == delim) {
1679b5677b36Schristos 				if (q > buffer && (*(q - 1) == delim)) {
1680b5677b36Schristos 					errno = EINVAL;
1681b5677b36Schristos 					return (NULL);
1682b5677b36Schristos 				}
1683b5677b36Schristos 				count++;
1684b5677b36Schristos 			}
1685b5677b36Schristos 		}
1686b5677b36Schristos 	}
1687b5677b36Schristos 
1688b5677b36Schristos 	if (count > 0) {
1689b5677b36Schristos 		count++ ;		/*%< for NULL at end */
1690b5677b36Schristos 		aptr = arr = malloc(count * sizeof (char *));
1691b5677b36Schristos 		if (aptr == NULL) {
1692b5677b36Schristos 			 errno = ENOMEM;
1693b5677b36Schristos 			 return (NULL);
1694b5677b36Schristos 		 }
1695b5677b36Schristos 
1696b5677b36Schristos 		memset(arr, 0x0, count * sizeof (char *));
1697b5677b36Schristos 		for (p = buffer ; p < buffend ; p++) {
1698b5677b36Schristos 			for (q = p ; *q != delim && q != buffend ; q++)
1699b5677b36Schristos 				/* nothing */;
1700b5677b36Schristos 			*aptr = strndup(p, q - p);
1701b5677b36Schristos 
1702b5677b36Schristos 			p = q;
1703b5677b36Schristos 			aptr++;
1704b5677b36Schristos 		}
1705b5677b36Schristos 		*aptr = NULL;
1706b5677b36Schristos 	} else {
1707b5677b36Schristos 		arr = malloc(sizeof (char *));
1708b5677b36Schristos 		if (arr == NULL) {
1709b5677b36Schristos 			errno = ENOMEM;
1710b5677b36Schristos 			return (NULL);
1711b5677b36Schristos 		}
1712b5677b36Schristos 
1713b5677b36Schristos 		*arr = NULL;
1714b5677b36Schristos 	}
1715b5677b36Schristos 
1716b5677b36Schristos 	return (arr);
1717b5677b36Schristos }
1718b5677b36Schristos 
1719b5677b36Schristos /*%
1720b5677b36Schristos  * static size_t joinlength(char * const *argv)
1721b5677b36Schristos  *
1722b5677b36Schristos  * return: \li
1723b5677b36Schristos  *
1724b5677b36Schristos  *	the number of bytes in all the arrays pointed at
1725b5677b36Schristos  *	by argv, including their null bytes(which will usually be turned
1726b5677b36Schristos  *	into commas).
1727b5677b36Schristos  *
1728b5677b36Schristos  *
1729b5677b36Schristos  */
1730b5677b36Schristos 
1731b5677b36Schristos static size_t
joinlength(char * const * argv)1732b5677b36Schristos joinlength(char * const *argv) {
1733b5677b36Schristos 	int len = 0;
1734b5677b36Schristos 
1735b5677b36Schristos 	while (argv && *argv) {
1736b5677b36Schristos 		len += (strlen(*argv) + 1);
1737b5677b36Schristos 		argv++;
1738b5677b36Schristos 	}
1739b5677b36Schristos 
1740b5677b36Schristos 	return (len);
1741b5677b36Schristos }
1742b5677b36Schristos 
1743b5677b36Schristos /*%
1744b5677b36Schristos  * int joinarray(char * const *argv, char *buffer, char delim)
1745b5677b36Schristos  *
1746b5677b36Schristos  * notes: \li
1747b5677b36Schristos  *
1748b5677b36Schristos  *	Copy all the ARGV strings into the end of BUFFER
1749b5677b36Schristos  *	separating them with DELIM.  BUFFER is assumed to have
1750b5677b36Schristos  *	enough space to hold everything and to be already null-terminated.
1751b5677b36Schristos  *
1752b5677b36Schristos  * return: \li
1753b5677b36Schristos  *
1754b5677b36Schristos  *	0 unless argv or buffer is NULL.
1755b5677b36Schristos  *
1756b5677b36Schristos  *
1757b5677b36Schristos  */
1758b5677b36Schristos 
1759b5677b36Schristos static int
joinarray(char * const * argv,char * buffer,char delim)1760b5677b36Schristos joinarray(char * const *argv, char *buffer, char delim) {
1761b5677b36Schristos 	char * const *p;
1762b5677b36Schristos 	char sep[2];
1763b5677b36Schristos 
1764b5677b36Schristos 	if (argv == NULL || buffer == NULL) {
1765b5677b36Schristos 		errno = EINVAL;
1766b5677b36Schristos 		return (-1);
1767b5677b36Schristos 	}
1768b5677b36Schristos 
1769b5677b36Schristos 	sep[0] = delim;
1770b5677b36Schristos 	sep[1] = 0x0;
1771b5677b36Schristos 
1772b5677b36Schristos 	for (p = argv ; *p != NULL ; p++) {
1773b5677b36Schristos 		strcat(buffer, *p);
1774b5677b36Schristos 		if (*(p + 1) != NULL) {
1775b5677b36Schristos 			strcat(buffer, sep);
1776b5677b36Schristos 		}
1777b5677b36Schristos 	}
1778b5677b36Schristos 
1779b5677b36Schristos 	return (0);
1780b5677b36Schristos }
1781b5677b36Schristos 
1782b5677b36Schristos /*%
1783b5677b36Schristos  * static char * getfield(char **res, size_t reslen, char **ptr, char delim)
1784b5677b36Schristos  *
1785b5677b36Schristos  * notes: \li
1786b5677b36Schristos  *
1787b5677b36Schristos  *	Stores in *RES, which is a buffer of length RESLEN, a
1788b5677b36Schristos  *	copy of the bytes from *PTR up to and including the first
1789b5677b36Schristos  *	instance of DELIM. If *RES is NULL, then it will be
1790b5677b36Schristos  *	assigned a malloced buffer to hold the copy. *PTR is
1791b5677b36Schristos  *	modified to point at the found delimiter.
1792b5677b36Schristos  *
1793b5677b36Schristos  * return: \li
1794b5677b36Schristos  *
1795b5677b36Schristos  *	If there was no delimiter, then NULL is returned,
1796b5677b36Schristos  *	otherewise *RES is returned.
1797b5677b36Schristos  *
1798b5677b36Schristos  */
1799b5677b36Schristos 
1800b5677b36Schristos static char *
getfield(char ** res,size_t reslen,char ** ptr,char delim)1801b5677b36Schristos getfield(char **res, size_t reslen, char **ptr, char delim) {
1802b5677b36Schristos 	char *q;
1803b5677b36Schristos 
1804b5677b36Schristos 	if (res == NULL || ptr == NULL || *ptr == NULL) {
1805b5677b36Schristos 		errno = EINVAL;
1806b5677b36Schristos 		return (NULL);
1807b5677b36Schristos 	}
1808b5677b36Schristos 
1809b5677b36Schristos 	q = strchr(*ptr, delim);
1810b5677b36Schristos 
1811b5677b36Schristos 	if (q == NULL) {
1812b5677b36Schristos 		errno = EINVAL;
1813b5677b36Schristos 		return (NULL);
1814b5677b36Schristos 	} else {
1815b5677b36Schristos 		if (*res == NULL) {
1816b5677b36Schristos 			*res = strndup(*ptr, q - *ptr);
1817b5677b36Schristos 		} else {
1818b5677b36Schristos 			if ((size_t)(q - *ptr + 1) > reslen) { /*%< to big for res */
1819b5677b36Schristos 				errno = EINVAL;
1820b5677b36Schristos 				return (NULL);
1821b5677b36Schristos 			} else {
1822b5677b36Schristos 				strncpy(*res, *ptr, q - *ptr);
1823b5677b36Schristos 				(*res)[q - *ptr] = 0x0;
1824b5677b36Schristos 			}
1825b5677b36Schristos 		}
1826b5677b36Schristos 		*ptr = q + 1;
1827b5677b36Schristos 	}
1828b5677b36Schristos 
1829b5677b36Schristos 	return (*res);
1830b5677b36Schristos }
1831b5677b36Schristos 
1832b5677b36Schristos 
1833b5677b36Schristos 
1834b5677b36Schristos 
1835b5677b36Schristos 
1836b5677b36Schristos #ifndef HAVE_STRNDUP
1837b5677b36Schristos /*
1838b5677b36Schristos  * static char * strndup(const char *str, size_t len)
1839b5677b36Schristos  *
1840b5677b36Schristos  * notes: \li
1841b5677b36Schristos  *
1842b5677b36Schristos  *	like strdup, except do len bytes instead of the whole string. Always
1843b5677b36Schristos  *	null-terminates.
1844b5677b36Schristos  *
1845b5677b36Schristos  * return: \li
1846b5677b36Schristos  *
1847b5677b36Schristos  *	The newly malloced string.
1848b5677b36Schristos  *
1849b5677b36Schristos  */
1850b5677b36Schristos 
1851b5677b36Schristos static char *
strndup(const char * str,size_t len)1852b5677b36Schristos strndup(const char *str, size_t len) {
1853b5677b36Schristos 	char *p = malloc(len + 1);
1854b5677b36Schristos 
1855b5677b36Schristos 	if (p == NULL)
1856b5677b36Schristos 		return (NULL);
1857b5677b36Schristos 	strncpy(p, str, len);
1858b5677b36Schristos 	p[len] = 0x0;
1859b5677b36Schristos 	return (p);
1860b5677b36Schristos }
1861b5677b36Schristos #endif
1862b5677b36Schristos 
1863b5677b36Schristos #if WANT_MAIN
1864b5677b36Schristos 
1865b5677b36Schristos /*%
1866b5677b36Schristos  * static int strcmp_nws(const char *a, const char *b)
1867b5677b36Schristos  *
1868b5677b36Schristos  * notes: \li
1869b5677b36Schristos  *
1870b5677b36Schristos  *	do a strcmp, except uneven lengths of whitespace compare the same
1871b5677b36Schristos  *
1872b5677b36Schristos  * return: \li
1873b5677b36Schristos  *
1874b5677b36Schristos  */
1875b5677b36Schristos 
1876b5677b36Schristos static int
strcmp_nws(const char * a,const char * b)1877b5677b36Schristos strcmp_nws(const char *a, const char *b) {
1878b5677b36Schristos 	while (*a && *b) {
1879b5677b36Schristos 		if (isspace(*a) && isspace(*b)) {
1880b5677b36Schristos 			do {
1881b5677b36Schristos 				a++;
1882b5677b36Schristos 			} while (isspace(*a));
1883b5677b36Schristos 			do {
1884b5677b36Schristos 				b++;
1885b5677b36Schristos 			} while (isspace(*b));
1886b5677b36Schristos 		}
1887b5677b36Schristos 		if (*a < *b)
1888b5677b36Schristos 			return (-1);
1889b5677b36Schristos 		else if (*a > *b)
1890b5677b36Schristos 			return (1);
1891b5677b36Schristos 
1892b5677b36Schristos 		a++;
1893b5677b36Schristos 		b++;;
1894b5677b36Schristos 	}
1895b5677b36Schristos 
1896b5677b36Schristos 	if (*a == *b)
1897b5677b36Schristos 		return (0);
1898b5677b36Schristos 	else if (*a > *b)
1899b5677b36Schristos 		return (1);
1900b5677b36Schristos 	else
1901b5677b36Schristos 		return (-1);
1902b5677b36Schristos }
1903b5677b36Schristos 
1904b5677b36Schristos #endif
1905b5677b36Schristos 
1906b5677b36Schristos /*%
1907b5677b36Schristos  * static void free_array(char **argv, size_t entries)
1908b5677b36Schristos  *
1909b5677b36Schristos  * notes: \li
1910b5677b36Schristos  *
1911b5677b36Schristos  *	Free argv and each of the pointers inside it. The end of
1912b5677b36Schristos  *	the array is when a NULL pointer is found inside. If
1913b5677b36Schristos  *	entries is > 0, then NULL pointers inside the array do
1914b5677b36Schristos  *	not indicate the end of the array.
1915b5677b36Schristos  *
1916b5677b36Schristos  */
1917b5677b36Schristos 
1918b5677b36Schristos static void
free_array(char ** argv,size_t entries)1919b5677b36Schristos free_array(char **argv, size_t entries) {
1920b5677b36Schristos 	char **p = argv;
1921b5677b36Schristos 	int useEntries = (entries > 0U);
1922b5677b36Schristos 
1923b5677b36Schristos 	if (argv == NULL)
1924b5677b36Schristos 		return;
1925b5677b36Schristos 
1926b5677b36Schristos 	while ((useEntries && entries > 0U) || *p) {
1927b5677b36Schristos 		if (*p)
1928b5677b36Schristos 			free(*p);
1929b5677b36Schristos 		p++;
1930b5677b36Schristos 		if (useEntries)
1931b5677b36Schristos 			entries--;
1932b5677b36Schristos 	}
1933b5677b36Schristos 	free(argv);
1934b5677b36Schristos }
1935b5677b36Schristos 
1936b5677b36Schristos 
1937b5677b36Schristos 
1938b5677b36Schristos 
1939b5677b36Schristos 
1940b5677b36Schristos /* ************************************************** */
1941b5677b36Schristos 
1942b5677b36Schristos #if WANT_MAIN
1943b5677b36Schristos 
1944b5677b36Schristos /*% takes an option to indicate what sort of marshalling(read the code) and
1945b5677b36Schristos    an argument. If the argument looks like a marshalled buffer(has a ':'
1946b5677b36Schristos    embedded) then it's unmarshalled and the remarshalled and the new string
1947b5677b36Schristos    is compared to the old one.
1948b5677b36Schristos */
1949b5677b36Schristos 
1950b5677b36Schristos int
main(int argc,char ** argv)1951b5677b36Schristos main(int argc, char **argv) {
1952b5677b36Schristos 	char buffer[1024];
1953b5677b36Schristos 	char *b = &buffer[0];
1954b5677b36Schristos 	size_t len = sizeof buffer;
1955b5677b36Schristos 	char option;
1956b5677b36Schristos 
1957b5677b36Schristos 	if (argc < 2 || argv[1][0] != '-')
1958b5677b36Schristos 		exit(1);
1959b5677b36Schristos 
1960b5677b36Schristos 	option = argv[1][1];
1961b5677b36Schristos 	argv++;
1962b5677b36Schristos 	argc--;
1963b5677b36Schristos 
1964b5677b36Schristos 
1965b5677b36Schristos #if 0
1966b5677b36Schristos 	{
1967b5677b36Schristos 		char buff[10];
1968b5677b36Schristos 		char *p = argv[1], *q = &buff[0];
1969b5677b36Schristos 
1970b5677b36Schristos 		while (getfield(&q, sizeof buff, &p, ':') != NULL) {
1971b5677b36Schristos 			printf("field: \"%s\"\n", q);
1972b5677b36Schristos 			p++;
1973b5677b36Schristos 		}
1974b5677b36Schristos 		printf("p is now \"%s\"\n", p);
1975b5677b36Schristos 	}
1976b5677b36Schristos #endif
1977b5677b36Schristos 
1978b5677b36Schristos #if 0
1979b5677b36Schristos 	{
1980b5677b36Schristos 		char **x = splitarray(argv[1], argv[1] + strlen(argv[1]),
1981b5677b36Schristos 				      argv[2][0]);
1982b5677b36Schristos 		char **p;
1983b5677b36Schristos 
1984b5677b36Schristos 		if (x == NULL)
1985b5677b36Schristos 			printf("split failed\n");
1986b5677b36Schristos 
1987b5677b36Schristos 		for (p = x ; p != NULL && *p != NULL ; p++) {
1988b5677b36Schristos 			printf("\"%s\"\n", *p);
1989b5677b36Schristos 		}
1990b5677b36Schristos 	}
1991b5677b36Schristos #endif
1992b5677b36Schristos 
1993b5677b36Schristos #if 1
1994b5677b36Schristos 	switch(option) {
1995b5677b36Schristos 	case 'n': {
1996b5677b36Schristos 		struct nwent ne;
1997b5677b36Schristos 		int i;
1998b5677b36Schristos 
1999b5677b36Schristos 		if (strchr(argv[1], ':') != NULL) {
2000b5677b36Schristos 			if (irp_unmarshall_nw(&ne, argv[1]) != 0) {
2001b5677b36Schristos 				printf("Unmarhsalling failed\n");
2002b5677b36Schristos 				exit(1);
2003b5677b36Schristos 			}
2004b5677b36Schristos 
2005b5677b36Schristos 			printf("Name: \"%s\"\n", ne.n_name);
2006b5677b36Schristos 			printf("Aliases:");
2007b5677b36Schristos 			for (i = 0 ; ne.n_aliases[i] != NULL ; i++)
2008b5677b36Schristos 				printf("\n\t\"%s\"", ne.n_aliases[i]);
2009b5677b36Schristos 			printf("\nAddrtype: %s\n", ADDR_T_STR(ne.n_addrtype));
2010b5677b36Schristos 			inet_net_ntop(ne.n_addrtype, ne.n_addr, ne.n_length,
2011b5677b36Schristos 				      buffer, sizeof buffer);
2012b5677b36Schristos 			printf("Net: \"%s\"\n", buffer);
2013b5677b36Schristos 			*((long*)ne.n_addr) = htonl(*((long*)ne.n_addr));
2014b5677b36Schristos 			inet_net_ntop(ne.n_addrtype, ne.n_addr, ne.n_length,
2015b5677b36Schristos 				      buffer, sizeof buffer);
2016b5677b36Schristos 			printf("Corrected Net: \"%s\"\n", buffer);
2017b5677b36Schristos 		} else {
2018b5677b36Schristos 			struct netent *np1 = getnetbyname(argv[1]);
2019b5677b36Schristos 			ne.n_name = np1->n_name;
2020b5677b36Schristos 			ne.n_aliases = np1->n_aliases;
2021b5677b36Schristos 			ne.n_addrtype = np1->n_addrtype;
2022b5677b36Schristos 			ne.n_addr = &np1->n_net;
2023b5677b36Schristos 			ne.n_length = (IN_CLASSA(np1->n_net) ?
2024b5677b36Schristos 				       8 :
2025b5677b36Schristos 				       (IN_CLASSB(np1->n_net) ?
2026b5677b36Schristos 					16 :
2027b5677b36Schristos 					(IN_CLASSC(np1->n_net) ?
2028b5677b36Schristos 					 24 : -1)));
2029b5677b36Schristos 			np1->n_net = htonl(np1->n_net);
2030b5677b36Schristos 			if (irp_marshall_nw(&ne, &b, &len) != 0) {
2031b5677b36Schristos 				printf("Marshalling failed\n");
2032b5677b36Schristos 			}
2033b5677b36Schristos 			printf("%s\n", b);
2034b5677b36Schristos 		}
2035b5677b36Schristos 		break;
2036b5677b36Schristos 	}
2037b5677b36Schristos 
2038b5677b36Schristos 
2039b5677b36Schristos 	case 'r': {
2040b5677b36Schristos 		char **hosts, **users, **domains;
2041b5677b36Schristos 		size_t entries;
2042b5677b36Schristos 		int i;
2043b5677b36Schristos 		char *buff;
2044b5677b36Schristos 		size_t size;
2045b5677b36Schristos 		char *ngname;
2046b5677b36Schristos 
2047b5677b36Schristos 		if (strchr(argv[1], '(') != NULL) {
2048b5677b36Schristos 			if (irp_unmarshall_ng(&ngname, &entries,
2049b5677b36Schristos 					      &hosts, &users, &domains,
2050b5677b36Schristos 					      argv[1]) != 0) {
2051b5677b36Schristos 				printf("unmarshall failed\n");
2052b5677b36Schristos 				exit(1);
2053b5677b36Schristos 			}
2054b5677b36Schristos 
2055b5677b36Schristos #define STRVAL(x) (x == NULL ? "*" : x)
2056b5677b36Schristos 
2057b5677b36Schristos 			printf("%s {\n", ngname);
2058b5677b36Schristos 			for (i = 0 ; i < entries ; i++)
2059b5677b36Schristos 				printf("\t\"%s\" : \"%s\" : \"%s\"\n",
2060b5677b36Schristos 				       STRVAL(hosts[i]),
2061b5677b36Schristos 				       STRVAL(users[i]),
2062b5677b36Schristos 				       STRVAL(domains[i]));
2063b5677b36Schristos 			printf("}\n\n\n");
2064b5677b36Schristos 
2065b5677b36Schristos 
2066b5677b36Schristos 			irp_marshall_ng_start(ngname, NULL, &size);
2067b5677b36Schristos 			for (i = 0 ; i < entries ; i++)
2068b5677b36Schristos 				irp_marshall_ng_next(hosts[i], users[i],
2069b5677b36Schristos 						     domains[i], NULL, &size);
2070b5677b36Schristos 			irp_marshall_ng_end(NULL, &size);
2071b5677b36Schristos 
2072b5677b36Schristos 			buff = malloc(size);
2073b5677b36Schristos 
2074b5677b36Schristos 			irp_marshall_ng_start(ngname, buff, &size);
2075b5677b36Schristos 			for (i = 0 ; i < entries ; i++) {
2076b5677b36Schristos 				if (irp_marshall_ng_next(hosts[i], users[i],
2077b5677b36Schristos 							 domains[i], buff,
2078b5677b36Schristos 							 &size) != 0)
2079b5677b36Schristos 					printf("next marshalling failed.\n");
2080b5677b36Schristos 			}
2081b5677b36Schristos 			irp_marshall_ng_end(buff, &size);
2082b5677b36Schristos 
2083b5677b36Schristos 			if (strcmp_nws(argv[1], buff) != 0) {
2084b5677b36Schristos 				printf("compare failed:\n\t%s\n\t%s\n",
2085b5677b36Schristos 				       buffer, argv[1]);
2086b5677b36Schristos 			} else {
2087b5677b36Schristos 				printf("compare ok\n");
2088b5677b36Schristos 			}
2089b5677b36Schristos 		} else {
2090b5677b36Schristos 			char *h, *u, *d, *buff;
2091b5677b36Schristos 			size_t size;
2092b5677b36Schristos 
2093b5677b36Schristos 			/* run through two times. First to figure out how
2094b5677b36Schristos 			   much of a buffer we need. Second to do the
2095b5677b36Schristos 			   actual marshalling */
2096b5677b36Schristos 
2097b5677b36Schristos 			setnetgrent(argv[1]);
2098b5677b36Schristos 			irp_marshall_ng_start(argv[1], NULL, &size);
2099b5677b36Schristos 			while (getnetgrent(&h, &u, &d) == 1)
2100b5677b36Schristos 				irp_marshall_ng_next(h, u, d, NULL, &size);
2101b5677b36Schristos 			irp_marshall_ng_end(NULL, &size);
2102b5677b36Schristos 			endnetgrent(argv[1]);
2103b5677b36Schristos 
2104b5677b36Schristos 			buff = malloc(size);
2105b5677b36Schristos 
2106b5677b36Schristos 			setnetgrent(argv[1]);
2107b5677b36Schristos 			if (irp_marshall_ng_start(argv[1], buff, &size) != 0)
2108b5677b36Schristos 				printf("Marshalling start failed\n");
2109b5677b36Schristos 
2110b5677b36Schristos 			while (getnetgrent(&h, &u, &d) == 1) {
2111b5677b36Schristos 				if (irp_marshall_ng_next(h, u, d, buff, &size)
2112b5677b36Schristos 				    != 0) {
2113b5677b36Schristos 					printf("Marshalling failed\n");
2114b5677b36Schristos 				}
2115b5677b36Schristos 			}
2116b5677b36Schristos 
2117b5677b36Schristos 			irp_marshall_ng_end(buff, &size);
2118b5677b36Schristos 			endnetgrent();
2119b5677b36Schristos 
2120b5677b36Schristos 			printf("success: %s\n", buff);
2121b5677b36Schristos 		}
2122b5677b36Schristos 		break;
2123b5677b36Schristos 	}
2124b5677b36Schristos 
2125b5677b36Schristos 
2126b5677b36Schristos 
2127b5677b36Schristos 	case 'h': {
2128b5677b36Schristos 		struct hostent he, *hp;
2129b5677b36Schristos 		int i;
2130b5677b36Schristos 
2131b5677b36Schristos 
2132b5677b36Schristos 		if (strchr(argv[1], '@') != NULL) {
2133b5677b36Schristos 			if (irp_unmarshall_ho(&he, argv[1]) != 0) {
2134b5677b36Schristos 				printf("unmarshall failed\n");
2135b5677b36Schristos 				exit(1);
2136b5677b36Schristos 			}
2137b5677b36Schristos 
2138b5677b36Schristos 			printf("Host: \"%s\"\nAliases:", he.h_name);
2139b5677b36Schristos 			for (i = 0 ; he.h_aliases[i] != NULL ; i++)
2140b5677b36Schristos 				printf("\n\t\t\"%s\"", he.h_aliases[i]);
2141b5677b36Schristos 			printf("\nAddr Type: \"%s\"\n",
2142b5677b36Schristos 			       ADDR_T_STR(he.h_addrtype));
2143b5677b36Schristos 			printf("Length: %d\nAddresses:", he.h_length);
2144b5677b36Schristos 			for (i = 0 ; he.h_addr_list[i] != 0 ; i++) {
2145b5677b36Schristos 				inet_ntop(he.h_addrtype, he.h_addr_list[i],
2146b5677b36Schristos 					  buffer, sizeof buffer);
2147b5677b36Schristos 				printf("\n\t\"%s\"\n", buffer);
2148b5677b36Schristos 			}
2149b5677b36Schristos 			printf("\n\n");
2150b5677b36Schristos 
2151b5677b36Schristos 			irp_marshall_ho(&he, &b, &len);
2152b5677b36Schristos 			if (strcmp(argv[1], buffer) != 0) {
2153b5677b36Schristos 				printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2154b5677b36Schristos 				       buffer, argv[1]);
2155b5677b36Schristos 			} else {
2156b5677b36Schristos 				printf("compare ok\n");
2157b5677b36Schristos 			}
2158b5677b36Schristos 		} else {
2159b5677b36Schristos 			if ((hp = gethostbyname(argv[1])) == NULL) {
2160b5677b36Schristos 				perror("gethostbyname");
2161b5677b36Schristos 				printf("\"%s\"\n", argv[1]);
2162b5677b36Schristos 				exit(1);
2163b5677b36Schristos 			}
2164b5677b36Schristos 
2165b5677b36Schristos 			if (irp_marshall_ho(hp, &b, &len) != 0) {
2166b5677b36Schristos 				printf("irp_marshall_ho failed\n");
2167b5677b36Schristos 				exit(1);
2168b5677b36Schristos 			}
2169b5677b36Schristos 
2170b5677b36Schristos 			printf("success: \"%s\"\n", buffer);
2171b5677b36Schristos 		}
2172b5677b36Schristos 		break;
2173b5677b36Schristos 	}
2174b5677b36Schristos 
2175b5677b36Schristos 
2176b5677b36Schristos 	case 's': {
2177b5677b36Schristos 		struct servent *sv;
2178b5677b36Schristos 		struct servent sv1;
2179b5677b36Schristos 
2180b5677b36Schristos 		if (strchr(argv[1], ':') != NULL) {
2181b5677b36Schristos 			sv = &sv1;
2182b5677b36Schristos 			memset(sv, 0xef, sizeof (struct servent));
2183b5677b36Schristos 			if (irp_unmarshall_sv(sv, argv[1]) != 0) {
2184b5677b36Schristos 				printf("unmarshall failed\n");
2185b5677b36Schristos 
2186b5677b36Schristos 			}
2187b5677b36Schristos 
2188b5677b36Schristos 			irp_marshall_sv(sv, &b, &len);
2189b5677b36Schristos 			if (strcmp(argv[1], buffer) != 0) {
2190b5677b36Schristos 				printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2191b5677b36Schristos 				       buffer, argv[1]);
2192b5677b36Schristos 			} else {
2193b5677b36Schristos 				printf("compare ok\n");
2194b5677b36Schristos 			}
2195b5677b36Schristos 		} else {
2196b5677b36Schristos 			if ((sv = getservbyname(argv[1], argv[2])) == NULL) {
2197b5677b36Schristos 				perror("getservent");
2198b5677b36Schristos 				exit(1);
2199b5677b36Schristos 			}
2200b5677b36Schristos 
2201b5677b36Schristos 			if (irp_marshall_sv(sv, &b, &len) != 0) {
2202b5677b36Schristos 				printf("irp_marshall_sv failed\n");
2203b5677b36Schristos 				exit(1);
2204b5677b36Schristos 			}
2205b5677b36Schristos 
2206b5677b36Schristos 			printf("success: \"%s\"\n", buffer);
2207b5677b36Schristos 		}
2208b5677b36Schristos 		break;
2209b5677b36Schristos 	}
2210b5677b36Schristos 
2211b5677b36Schristos 	case 'g': {
2212b5677b36Schristos 		struct group *gr;
2213b5677b36Schristos 		struct group gr1;
2214b5677b36Schristos 
2215b5677b36Schristos 		if (strchr(argv[1], ':') != NULL) {
2216b5677b36Schristos 			gr = &gr1;
2217b5677b36Schristos 			memset(gr, 0xef, sizeof (struct group));
2218b5677b36Schristos 			if (irp_unmarshall_gr(gr, argv[1]) != 0) {
2219b5677b36Schristos 				printf("unmarshall failed\n");
2220b5677b36Schristos 
2221b5677b36Schristos 			}
2222b5677b36Schristos 
2223b5677b36Schristos 			irp_marshall_gr(gr, &b, &len);
2224b5677b36Schristos 			if (strcmp(argv[1], buffer) != 0) {
2225b5677b36Schristos 				printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2226b5677b36Schristos 				       buffer, argv[1]);
2227b5677b36Schristos 			} else {
2228b5677b36Schristos 				printf("compare ok\n");
2229b5677b36Schristos 			}
2230b5677b36Schristos 		} else {
2231b5677b36Schristos 			if ((gr = getgrnam(argv[1])) == NULL) {
2232b5677b36Schristos 				perror("getgrnam");
2233b5677b36Schristos 				exit(1);
2234b5677b36Schristos 			}
2235b5677b36Schristos 
2236b5677b36Schristos 			if (irp_marshall_gr(gr, &b, &len) != 0) {
2237b5677b36Schristos 				printf("irp_marshall_gr failed\n");
2238b5677b36Schristos 				exit(1);
2239b5677b36Schristos 			}
2240b5677b36Schristos 
2241b5677b36Schristos 			printf("success: \"%s\"\n", buffer);
2242b5677b36Schristos 		}
2243b5677b36Schristos 		break;
2244b5677b36Schristos 	}
2245b5677b36Schristos 
2246b5677b36Schristos 
2247b5677b36Schristos 	case 'p': {
2248b5677b36Schristos 		struct passwd *pw;
2249b5677b36Schristos 		struct passwd pw1;
2250b5677b36Schristos 
2251b5677b36Schristos 		if (strchr(argv[1], ':') != NULL) {
2252b5677b36Schristos 			pw = &pw1;
2253b5677b36Schristos 			memset(pw, 0xef, sizeof (*pw));
2254b5677b36Schristos 			if (irp_unmarshall_pw(pw, argv[1]) != 0) {
2255b5677b36Schristos 				printf("unmarshall failed\n");
2256b5677b36Schristos 				exit(1);
2257b5677b36Schristos 			}
2258b5677b36Schristos 
2259b5677b36Schristos 			printf("User: \"%s\"\nPasswd: \"%s\"\nUid: %ld\nGid: %ld\n",
2260b5677b36Schristos 			       pw->pw_name, pw->pw_passwd, (long)pw->pw_uid,
2261b5677b36Schristos 			       (long)pw->pw_gid);
2262b5677b36Schristos 			printf("Class: \"%s\"\nChange: %ld\nGecos: \"%s\"\n",
2263b5677b36Schristos 			       pw->pw_class, (long)pw->pw_change, pw->pw_gecos);
2264b5677b36Schristos 			printf("Shell: \"%s\"\nDirectory: \"%s\"\n",
2265b5677b36Schristos 			       pw->pw_shell, pw->pw_dir);
2266b5677b36Schristos 
2267b5677b36Schristos 			pw = getpwnam(pw->pw_name);
2268b5677b36Schristos 			irp_marshall_pw(pw, &b, &len);
2269b5677b36Schristos 			if (strcmp(argv[1], buffer) != 0) {
2270b5677b36Schristos 				printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2271b5677b36Schristos 				       buffer, argv[1]);
2272b5677b36Schristos 			} else {
2273b5677b36Schristos 				printf("compare ok\n");
2274b5677b36Schristos 			}
2275b5677b36Schristos 		} else {
2276b5677b36Schristos 			if ((pw = getpwnam(argv[1])) == NULL) {
2277b5677b36Schristos 				perror("getpwnam");
2278b5677b36Schristos 				exit(1);
2279b5677b36Schristos 			}
2280b5677b36Schristos 
2281b5677b36Schristos 			if (irp_marshall_pw(pw, &b, &len) != 0) {
2282b5677b36Schristos 				printf("irp_marshall_pw failed\n");
2283b5677b36Schristos 				exit(1);
2284b5677b36Schristos 			}
2285b5677b36Schristos 
2286b5677b36Schristos 			printf("success: \"%s\"\n", buffer);
2287b5677b36Schristos 		}
2288b5677b36Schristos 		break;
2289b5677b36Schristos 	}
2290b5677b36Schristos 
2291b5677b36Schristos 	default:
2292b5677b36Schristos 		printf("Wrong option: %c\n", option);
2293b5677b36Schristos 		break;
2294b5677b36Schristos 	}
2295b5677b36Schristos 
2296b5677b36Schristos #endif
2297b5677b36Schristos 
2298b5677b36Schristos 	return (0);
2299b5677b36Schristos }
2300b5677b36Schristos 
2301b5677b36Schristos #endif
2302b5677b36Schristos 
2303b5677b36Schristos /*! \file */
2304