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