Add BIND 9.2.4rc7.
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / bind / irs / irpmarshall.c
blob8776b16e4f368434353cb0ef4e93e166c5054246
1 /*
2 * Copyright(c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
35 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
36 * Portions Copyright (c) 1996 by Internet Software Consortium.
38 * Permission to use, copy, modify, and distribute this software for any
39 * purpose with or without fee is hereby granted, provided that the above
40 * copyright notice and this permission notice appear in all copies.
42 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
43 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
48 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 #if defined(LIBC_SCCS) && !defined(lint)
52 static const char rcsid[] = "$Id: irpmarshall.c,v 1.3.2.3 2004/03/17 01:15:47 marka Exp $";
53 #endif /* LIBC_SCCS and not lint */
55 #if 0
57 Check values are in approrpriate endian order.
59 Double check memory allocations on unmarhsalling
61 #endif
64 /* Extern */
66 #include "port_before.h"
68 #include <sys/types.h>
69 #include <sys/socket.h>
71 #include <netinet/in.h>
72 #include <arpa/inet.h>
73 #include <arpa/nameser.h>
75 #include <stdio.h>
76 #include <ctype.h>
77 #include <pwd.h>
78 #include <stdlib.h>
79 #include <string.h>
80 #include <syslog.h>
81 #include <utmp.h>
82 #include <unistd.h>
83 #include <assert.h>
84 #include <errno.h>
86 #include <irs.h>
87 #include <isc/memcluster.h>
88 #include <isc/irpmarshall.h>
90 #include "port_after.h"
93 #ifndef HAVE_STRNDUP
94 static char *strndup(const char *str, size_t len);
95 #endif
97 static char **splitarray(const char *buffer, const char *buffend, char delim);
98 static int joinarray(char * const * argv, char *buffer, char delim);
99 static char *getfield(char **res, size_t reslen, char **buffer, char delim);
100 static size_t joinlength(char * const *argv);
101 static void free_array(char **argv, size_t entries);
103 #define ADDR_T_STR(x) (x == AF_INET ? "AF_INET" :\
104 (x == AF_INET6 ? "AF_INET6" : "UNKNOWN"))
106 #define MAXPADDRSIZE (sizeof "255.255.255.255" + 1)
108 static char COMMA = ',';
110 static const char *COMMASTR = ",";
111 static const char *COLONSTR = ":";
115 /* See big comment at bottom of irpmarshall.h for description. */
118 #ifdef WANT_IRS_PW
119 /* +++++++++++++++++++++++++ struct passwd +++++++++++++++++++++++++ */
123 * int irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len)
125 * notes:
127 * See above
129 * return:
131 * 0 on sucess, -1 on failure.
136 irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) {
137 size_t need = 1 ; /* for null byte */
138 char pwUid[24];
139 char pwGid[24];
140 char pwChange[24];
141 char pwExpire[24];
142 const char *pwClass;
143 const char *fieldsep = COLONSTR;
145 if (pw == NULL || len == NULL) {
146 errno = EINVAL;
147 return (-1);
150 sprintf(pwUid, "%ld", (long)pw->pw_uid);
151 sprintf(pwGid, "%ld", (long)pw->pw_gid);
153 #ifdef HAVE_PW_CHANGE
154 sprintf(pwChange, "%ld", (long)pw->pw_change);
155 #else
156 pwChange[0] = '0';
157 pwChange[1] = '\0';
158 #endif
160 #ifdef HAVE_PW_EXPIRE
161 sprintf(pwExpire, "%ld", (long)pw->pw_expire);
162 #else
163 pwExpire[0] = '0';
164 pwExpire[1] = '\0';
165 #endif
167 #ifdef HAVE_PW_CLASS
168 pwClass = pw->pw_class;
169 #else
170 pwClass = "";
171 #endif
173 need += strlen(pw->pw_name) + 1; /* one for fieldsep */
174 need += strlen(pw->pw_passwd) + 1;
175 need += strlen(pwUid) + 1;
176 need += strlen(pwGid) + 1;
177 need += strlen(pwClass) + 1;
178 need += strlen(pwChange) + 1;
179 need += strlen(pwExpire) + 1;
180 need += strlen(pw->pw_gecos) + 1;
181 need += strlen(pw->pw_dir) + 1;
182 need += strlen(pw->pw_shell) + 1;
184 if (buffer == NULL) {
185 *len = need;
186 return (0);
189 if (*buffer != NULL && need > *len) {
190 errno = EINVAL;
191 return (-1);
194 if (*buffer == NULL) {
195 need += 2; /* for CRLF */
196 *buffer = memget(need);
197 if (*buffer == NULL) {
198 errno = ENOMEM;
199 return (-1);
202 *len = need;
205 strcpy(*buffer, pw->pw_name); strcat(*buffer, fieldsep);
206 strcat(*buffer, pw->pw_passwd); strcat(*buffer, fieldsep);
207 strcat(*buffer, pwUid); strcat(*buffer, fieldsep);
208 strcat(*buffer, pwGid); strcat(*buffer, fieldsep);
209 strcat(*buffer, pwClass); strcat(*buffer, fieldsep);
210 strcat(*buffer, pwChange); strcat(*buffer, fieldsep);
211 strcat(*buffer, pwExpire); strcat(*buffer, fieldsep);
212 strcat(*buffer, pw->pw_gecos); strcat(*buffer, fieldsep);
213 strcat(*buffer, pw->pw_dir); strcat(*buffer, fieldsep);
214 strcat(*buffer, pw->pw_shell); strcat(*buffer, fieldsep);
216 return (0);
224 * int irp_unmarshall_pw(struct passwd *pw, char *buffer)
226 * notes:
228 * see above
230 * return:
232 * 0 on success, -1 on failure
237 irp_unmarshall_pw(struct passwd *pw, char *buffer) {
238 char *name, *pass, *class, *gecos, *dir, *shell;
239 uid_t pwuid;
240 gid_t pwgid;
241 time_t pwchange;
242 time_t pwexpire;
243 char *p;
244 long t;
245 char tmpbuf[24];
246 char *tb = &tmpbuf[0];
247 char fieldsep = ':';
248 int myerrno = EINVAL;
250 name = pass = class = gecos = dir = shell = NULL;
251 p = buffer;
253 /* pw_name field */
254 name = NULL;
255 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
256 goto error;
259 /* pw_passwd field */
260 pass = NULL;
261 if (getfield(&pass, 0, &p, fieldsep) == NULL) { /* field can be empty */
262 goto error;
266 /* pw_uid field */
267 tb = tmpbuf;
268 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
269 strlen(tb) == 0) {
270 goto error;
272 t = strtol(tmpbuf, &tb, 10);
273 if (*tb) {
274 goto error; /* junk in value */
276 pwuid = (uid_t)t;
277 if ((long) pwuid != t) { /* value must have been too big. */
278 goto error;
283 /* pw_gid field */
284 tb = tmpbuf;
285 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
286 strlen(tb) == 0) {
287 goto error;
289 t = strtol(tmpbuf, &tb, 10);
290 if (*tb) {
291 goto error; /* junk in value */
293 pwgid = (gid_t)t;
294 if ((long)pwgid != t) { /* value must have been too big. */
295 goto error;
300 /* pw_class field */
301 class = NULL;
302 if (getfield(&class, 0, &p, fieldsep) == NULL) {
303 goto error;
308 /* pw_change field */
309 tb = tmpbuf;
310 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
311 strlen(tb) == 0) {
312 goto error;
314 t = strtol(tmpbuf, &tb, 10);
315 if (*tb) {
316 goto error; /* junk in value */
318 pwchange = (time_t)t;
319 if ((long)pwchange != t) { /* value must have been too big. */
320 goto error;
325 /* pw_expire field */
326 tb = tmpbuf;
327 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
328 strlen(tb) == 0) {
329 goto error;
331 t = strtol(tmpbuf, &tb, 10);
332 if (*tb) {
333 goto error; /* junk in value */
335 pwexpire = (time_t)t;
336 if ((long) pwexpire != t) { /* value must have been too big. */
337 goto error;
342 /* pw_gecos field */
343 gecos = NULL;
344 if (getfield(&gecos, 0, &p, fieldsep) == NULL) {
345 goto error;
350 /* pw_dir field */
351 dir = NULL;
352 if (getfield(&dir, 0, &p, fieldsep) == NULL) {
353 goto error;
358 /* pw_shell field */
359 shell = NULL;
360 if (getfield(&shell, 0, &p, fieldsep) == NULL) {
361 goto error;
366 pw->pw_name = name;
367 pw->pw_passwd = pass;
368 pw->pw_uid = pwuid;
369 pw->pw_gid = pwgid;
370 pw->pw_gecos = gecos;
371 pw->pw_dir = dir;
372 pw->pw_shell = shell;
374 #ifdef HAVE_PW_CHANGE
375 pw->pw_change = pwchange;
376 #endif
377 #ifdef HAVE_PW_CLASS
378 pw->pw_class = class;
379 #endif
380 #ifdef HAVE_PW_EXPIRE
381 pw->pw_expire = pwexpire;
382 #endif
384 return (0);
386 error:
387 errno = myerrno;
389 if (name != NULL) free(name);
390 if (pass != NULL) free(pass);
391 if (gecos != NULL) free(gecos);
392 if (dir != NULL) free(dir);
393 if (shell != NULL) free(shell);
395 return (-1);
398 /* ------------------------- struct passwd ------------------------- */
399 #endif /* WANT_IRS_PW */
403 /* +++++++++++++++++++++++++ struct group +++++++++++++++++++++++++ */
408 * int irp_marshall_gr(const struct group *gr, char **buffer, size_t *len)
410 * notes:
412 * see above.
414 * return:
416 * 0 on success, -1 on failure
420 irp_marshall_gr(const struct group *gr, char **buffer, size_t *len) {
421 size_t need = 1; /* for null byte */
422 char grGid[24];
423 const char *fieldsep = COLONSTR;
425 if (gr == NULL || len == NULL) {
426 errno = EINVAL;
427 return (-1);
430 sprintf(grGid, "%ld", (long)gr->gr_gid);
432 need += strlen(gr->gr_name) + 1;
433 #ifndef MISSING_GR_PASSWD
434 need += strlen(gr->gr_passwd) + 1;
435 #else
436 need++;
437 #endif
438 need += strlen(grGid) + 1;
439 need += joinlength(gr->gr_mem) + 1;
441 if (buffer == NULL) {
442 *len = need;
443 return (0);
446 if (*buffer != NULL && need > *len) {
447 errno = EINVAL;
448 return (-1);
451 if (*buffer == NULL) {
452 need += 2; /* for CRLF */
453 *buffer = memget(need);
454 if (*buffer == NULL) {
455 errno = ENOMEM;
456 return (-1);
459 *len = need;
462 strcpy(*buffer, gr->gr_name); strcat(*buffer, fieldsep);
463 #ifndef MISSING_GR_PASSWD
464 strcat(*buffer, gr->gr_passwd);
465 #endif
466 strcat(*buffer, fieldsep);
467 strcat(*buffer, grGid); strcat(*buffer, fieldsep);
468 joinarray(gr->gr_mem, *buffer, COMMA) ; strcat(*buffer, fieldsep);
470 return (0);
477 * int irp_unmarshall_gr(struct group *gr, char *buffer)
479 * notes:
481 * see above
483 * return:
485 * 0 on success and -1 on failure.
490 irp_unmarshall_gr(struct group *gr, char *buffer) {
491 char *p, *q;
492 gid_t grgid;
493 long t;
494 char *name = NULL;
495 char *pass = NULL;
496 char **members = NULL;
497 char tmpbuf[24];
498 char *tb;
499 char fieldsep = ':';
500 int myerrno = EINVAL;
502 if (gr == NULL || buffer == NULL) {
503 errno = EINVAL;
504 return (-1);
507 p = buffer;
509 /* gr_name field */
510 name = NULL;
511 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
512 goto error;
516 /* gr_passwd field */
517 pass = NULL;
518 if (getfield(&pass, 0, &p, fieldsep) == NULL) {
519 goto error;
523 /* gr_gid field */
524 tb = tmpbuf;
525 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
526 strlen(tb) == 0U) {
527 goto error;
529 t = strtol(tmpbuf, &tb, 10);
530 if (*tb) {
531 goto error; /* junk in value */
533 grgid = (gid_t)t;
534 if ((long) grgid != t) { /* value must have been too big. */
535 goto error;
539 /* gr_mem field. Member names are separated by commas */
540 q = strchr(p, fieldsep);
541 if (q == NULL) {
542 goto error;
544 members = splitarray(p, q, COMMA);
545 if (members == NULL) {
546 myerrno = errno;
547 goto error;
549 p = q + 1;
552 gr->gr_name = name;
553 #ifndef MISSING_GR_PASSWD
554 gr->gr_passwd = pass;
555 #endif
556 gr->gr_gid = grgid;
557 gr->gr_mem = members;
559 return (0);
561 error:
562 errno = myerrno;
564 if (name != NULL) free(name);
565 if (pass != NULL) free(pass);
567 return (-1);
571 /* ------------------------- struct group ------------------------- */
576 /* +++++++++++++++++++++++++ struct servent +++++++++++++++++++++++++ */
581 * int irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len)
583 * notes:
585 * see above
587 * return:
589 * 0 on success, -1 on failure.
594 irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len) {
595 size_t need = 1; /* for null byte */
596 char svPort[24];
597 const char *fieldsep = COLONSTR;
598 short realport;
600 if (sv == NULL || len == NULL) {
601 errno = EINVAL;
602 return (-1);
605 /* the int s_port field is actually a short in network order. We
606 want host order to make the marshalled data look correct */
607 realport = ntohs((short)sv->s_port);
608 sprintf(svPort, "%d", realport);
610 need += strlen(sv->s_name) + 1;
611 need += joinlength(sv->s_aliases) + 1;
612 need += strlen(svPort) + 1;
613 need += strlen(sv->s_proto) + 1;
615 if (buffer == NULL) {
616 *len = need;
617 return (0);
620 if (*buffer != NULL && need > *len) {
621 errno = EINVAL;
622 return (-1);
625 if (*buffer == NULL) {
626 need += 2; /* for CRLF */
627 *buffer = memget(need);
628 if (*buffer == NULL) {
629 errno = ENOMEM;
630 return (-1);
633 *len = need;
636 strcpy(*buffer, sv->s_name); strcat(*buffer, fieldsep);
637 joinarray(sv->s_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
638 strcat(*buffer, svPort); strcat(*buffer, fieldsep);
639 strcat(*buffer, sv->s_proto); strcat(*buffer, fieldsep);
641 return (0);
649 * int irp_unmarshall_sv(struct servent *sv, char *buffer)
651 * notes:
653 * see above
655 * return:
657 * 0 on success, -1 on failure.
662 irp_unmarshall_sv(struct servent *sv, char *buffer) {
663 char *p, *q;
664 short svport;
665 long t;
666 char *name = NULL;
667 char *proto = NULL;
668 char **aliases = NULL;
669 char tmpbuf[24];
670 char *tb;
671 char fieldsep = ':';
672 int myerrno = EINVAL;
674 if (sv == NULL || buffer == NULL)
675 return (-1);
677 p = buffer;
680 /* s_name field */
681 name = NULL;
682 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
683 goto error;
687 /* s_aliases field */
688 q = strchr(p, fieldsep);
689 if (q == NULL) {
690 goto error;
692 aliases = splitarray(p, q, COMMA);
693 if (aliases == NULL) {
694 myerrno = errno;
695 goto error;
697 p = q + 1;
700 /* s_port field */
701 tb = tmpbuf;
702 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
703 strlen(tb) == 0U) {
704 goto error;
706 t = strtol(tmpbuf, &tb, 10);
707 if (*tb) {
708 goto error; /* junk in value */
710 svport = (short)t;
711 if ((long) svport != t) { /* value must have been too big. */
712 goto error;
714 svport = htons(svport);
716 /* s_proto field */
717 proto = NULL;
718 if (getfield(&proto, 0, &p, fieldsep) == NULL) {
719 goto error;
722 sv->s_name = name;
723 sv->s_aliases = aliases;
724 sv->s_port = svport;
725 sv->s_proto = proto;
727 return (0);
729 error:
730 errno = myerrno;
732 if (name != NULL) free(name);
733 if (proto != NULL) free(proto);
734 free_array(aliases, 0);
736 return (-1);
740 /* ------------------------- struct servent ------------------------- */
742 /* +++++++++++++++++++++++++ struct protoent +++++++++++++++++++++++++ */
747 * int irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len)
749 * notes:
751 * see above
753 * return:
755 * 0 on success and -1 on failure.
760 irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len) {
761 size_t need = 1; /* for null byte */
762 char prProto[24];
763 const char *fieldsep = COLONSTR;
765 if (pr == NULL || len == NULL) {
766 errno = EINVAL;
767 return (-1);
770 sprintf(prProto, "%d", (int)pr->p_proto);
772 need += strlen(pr->p_name) + 1;
773 need += joinlength(pr->p_aliases) + 1;
774 need += strlen(prProto) + 1;
776 if (buffer == NULL) {
777 *len = need;
778 return (0);
781 if (*buffer != NULL && need > *len) {
782 errno = EINVAL;
783 return (-1);
786 if (*buffer == NULL) {
787 need += 2; /* for CRLF */
788 *buffer = memget(need);
789 if (*buffer == NULL) {
790 errno = ENOMEM;
791 return (-1);
794 *len = need;
797 strcpy(*buffer, pr->p_name); strcat(*buffer, fieldsep);
798 joinarray(pr->p_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
799 strcat(*buffer, prProto); strcat(*buffer, fieldsep);
801 return (0);
808 * int irp_unmarshall_pr(struct protoent *pr, char *buffer)
810 * notes:
812 * See above
814 * return:
816 * 0 on success, -1 on failure
820 int irp_unmarshall_pr(struct protoent *pr, char *buffer) {
821 char *p, *q;
822 int prproto;
823 long t;
824 char *name = NULL;
825 char **aliases = NULL;
826 char tmpbuf[24];
827 char *tb;
828 char fieldsep = ':';
829 int myerrno = EINVAL;
831 if (pr == NULL || buffer == NULL) {
832 errno = EINVAL;
833 return (-1);
836 p = buffer;
838 /* p_name field */
839 name = NULL;
840 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
841 goto error;
845 /* p_aliases field */
846 q = strchr(p, fieldsep);
847 if (q == NULL) {
848 goto error;
850 aliases = splitarray(p, q, COMMA);
851 if (aliases == NULL) {
852 myerrno = errno;
853 goto error;
855 p = q + 1;
858 /* p_proto field */
859 tb = tmpbuf;
860 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
861 strlen(tb) == 0U) {
862 goto error;
864 t = strtol(tmpbuf, &tb, 10);
865 if (*tb) {
866 goto error; /* junk in value */
868 prproto = (int)t;
869 if ((long) prproto != t) { /* value must have been too big. */
870 goto error;
873 pr->p_name = name;
874 pr->p_aliases = aliases;
875 pr->p_proto = prproto;
877 return (0);
879 error:
880 errno = myerrno;
882 if (name != NULL) free(name);
883 free_array(aliases, 0);
885 return (-1);
888 /* ------------------------- struct protoent ------------------------- */
892 /* +++++++++++++++++++++++++ struct hostent +++++++++++++++++++++++++ */
896 * int irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len)
898 * notes:
900 * see above.
902 * return:
904 * 0 on success, -1 on failure.
909 irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len) {
910 size_t need = 1; /* for null byte */
911 char hoaddrtype[24];
912 char holength[24];
913 char **av;
914 char *p;
915 int addrlen;
916 int malloced = 0;
917 size_t remlen;
918 const char *fieldsep = "@";
920 if (ho == NULL || len == NULL) {
921 errno = EINVAL;
922 return (-1);
925 switch(ho->h_addrtype) {
926 case AF_INET:
927 strcpy(hoaddrtype, "AF_INET");
928 break;
930 case AF_INET6:
931 strcpy(hoaddrtype, "AF_INET6");
932 break;
934 default:
935 errno = EINVAL;
936 return (-1);
939 sprintf(holength, "%d", ho->h_length);
941 need += strlen(ho->h_name) + 1;
942 need += joinlength(ho->h_aliases) + 1;
943 need += strlen(hoaddrtype) + 1;
944 need += strlen(holength) + 1;
946 /* we determine an upper bound on the string length needed, not an
947 exact length. */
948 addrlen = (ho->h_addrtype == AF_INET ? 16 : 46) ; /* XX other AF's?? */
949 for (av = ho->h_addr_list; av != NULL && *av != NULL ; av++)
950 need += addrlen;
952 if (buffer == NULL) {
953 *len = need;
954 return (0);
957 if (*buffer != NULL && need > *len) {
958 errno = EINVAL;
959 return (-1);
962 if (*buffer == NULL) {
963 need += 2; /* for CRLF */
964 *buffer = memget(need);
965 if (*buffer == NULL) {
966 errno = ENOMEM;
967 return (-1);
970 *len = need;
971 malloced = 1;
974 strcpy(*buffer, ho->h_name); strcat(*buffer, fieldsep);
975 joinarray(ho->h_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
976 strcat(*buffer, hoaddrtype); strcat(*buffer, fieldsep);
977 strcat(*buffer, holength); strcat(*buffer, fieldsep);
979 p = *buffer + strlen(*buffer);
980 remlen = need - strlen(*buffer);
981 for (av = ho->h_addr_list ; av != NULL && *av != NULL ; av++) {
982 if (inet_ntop(ho->h_addrtype, *av, p, remlen) == NULL) {
983 goto error;
985 if (*(av + 1) != NULL)
986 strcat(p, COMMASTR);
987 remlen -= strlen(p);
988 p += strlen(p);
990 strcat(*buffer, fieldsep);
992 return (0);
994 error:
995 if (malloced) {
996 memput(*buffer, need);
999 return (-1);
1005 * int irp_unmarshall_ho(struct hostent *ho, char *buffer)
1007 * notes:
1009 * See above.
1011 * return:
1013 * 0 on success, -1 on failure.
1018 irp_unmarshall_ho(struct hostent *ho, char *buffer) {
1019 char *p, *q, *r;
1020 int hoaddrtype;
1021 int holength;
1022 long t;
1023 char *name = NULL;
1024 char **aliases = NULL;
1025 char **hohaddrlist = NULL;
1026 size_t hoaddrsize;
1027 char tmpbuf[24];
1028 char *tb;
1029 char **alist;
1030 int addrcount;
1031 char fieldsep = '@';
1032 int myerrno = EINVAL;
1034 if (ho == NULL || buffer == NULL) {
1035 errno = EINVAL;
1036 return (-1);
1039 p = buffer;
1041 /* h_name field */
1042 name = NULL;
1043 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
1044 goto error;
1048 /* h_aliases field */
1049 q = strchr(p, fieldsep);
1050 if (q == NULL) {
1051 goto error;
1053 aliases = splitarray(p, q, COMMA);
1054 if (aliases == NULL) {
1055 myerrno = errno;
1056 goto error;
1058 p = q + 1;
1061 /* h_addrtype field */
1062 tb = tmpbuf;
1063 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1064 strlen(tb) == 0U) {
1065 goto error;
1067 if (strcmp(tmpbuf, "AF_INET") == 0)
1068 hoaddrtype = AF_INET;
1069 else if (strcmp(tmpbuf, "AF_INET6") == 0)
1070 hoaddrtype = AF_INET6;
1071 else
1072 goto error;
1075 /* h_length field */
1076 tb = tmpbuf;
1077 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1078 strlen(tb) == 0U) {
1079 goto error;
1081 t = strtol(tmpbuf, &tb, 10);
1082 if (*tb) {
1083 goto error; /* junk in value */
1085 holength = (int)t;
1086 if ((long) holength != t) { /* value must have been too big. */
1087 goto error;
1091 /* h_addr_list field */
1092 q = strchr(p, fieldsep);
1093 if (q == NULL)
1094 goto error;
1096 /* count how many addresss are in there */
1097 if (q > p + 1) {
1098 for (addrcount = 1, r = p ; r != q ; r++) {
1099 if (*r == COMMA)
1100 addrcount++;
1102 } else {
1103 addrcount = 0;
1106 hoaddrsize = (addrcount + 1) * sizeof (char *);
1107 hohaddrlist = malloc(hoaddrsize);
1108 if (hohaddrlist == NULL) {
1109 myerrno = ENOMEM;
1110 goto error;
1113 memset(hohaddrlist, 0x0, hoaddrsize);
1115 alist = hohaddrlist;
1116 for (t = 0, r = p ; r != q ; p = r + 1, t++) {
1117 char saved;
1118 while (r != q && *r != COMMA) r++;
1119 saved = *r;
1120 *r = 0x0;
1122 alist[t] = malloc(hoaddrtype == AF_INET ? 4 : 16);
1123 if (alist[t] == NULL) {
1124 myerrno = ENOMEM;
1125 goto error;
1128 if (inet_pton(hoaddrtype, p, alist[t]) == -1)
1129 goto error;
1130 *r = saved;
1132 alist[t] = NULL;
1134 ho->h_name = name;
1135 ho->h_aliases = aliases;
1136 ho->h_addrtype = hoaddrtype;
1137 ho->h_length = holength;
1138 ho->h_addr_list = hohaddrlist;
1140 return (0);
1142 error:
1143 errno = myerrno;
1145 if (name != NULL) free(name);
1146 free_array(aliases, 0);
1148 return (-1);
1151 /* ------------------------- struct hostent------------------------- */
1155 /* +++++++++++++++++++++++++ struct netgrp +++++++++++++++++++++++++ */
1159 * int irp_marshall_ng(const char *host, const char *user,
1160 * const char *domain, char *buffer, size_t *len)
1162 * notes:
1164 * See note for irp_marshall_ng_start
1166 * return:
1168 * 0 on success, 0 on failure.
1173 irp_marshall_ng(const char *host, const char *user, const char *domain,
1174 char **buffer, size_t *len) {
1175 size_t need = 1; /* for nul byte */
1176 const char *fieldsep = ",";
1178 if (len == NULL) {
1179 errno = EINVAL;
1180 return (-1);
1183 need += 4; /* two parens and two commas */
1184 need += (host == NULL ? 0 : strlen(host));
1185 need += (user == NULL ? 0 : strlen(user));
1186 need += (domain == NULL ? 0 : strlen(domain));
1188 if (buffer == NULL) {
1189 *len = need;
1190 return (0);
1191 } else if (*buffer != NULL && need > *len) {
1192 errno = EINVAL;
1193 return (-1);
1196 if (*buffer == NULL) {
1197 need += 2; /* for CRLF */
1198 *buffer = memget(need);
1199 if (*buffer == NULL) {
1200 errno = ENOMEM;
1201 return (-1);
1204 *len = need;
1207 (*buffer)[0] = '(';
1208 (*buffer)[1] = '\0';
1210 if (host != NULL)
1211 strcat(*buffer, host);
1212 strcat(*buffer, fieldsep);
1214 if (user != NULL)
1215 strcat(*buffer, user);
1216 strcat(*buffer, fieldsep);
1218 if (domain != NULL)
1219 strcat(*buffer, domain);
1220 strcat(*buffer, ")");
1222 return (0);
1227 /* ---------- */
1231 * int irp_unmarshall_ng(const char **host, const char **user,
1232 * const char **domain, char *buffer)
1234 * notes:
1236 * Unpacks the BUFFER into 3 character arrays it allocates and assigns
1237 * to *HOST, *USER and *DOMAIN. If any field of the value is empty,
1238 * then the corresponding paramater value will be set to NULL.
1240 * return:
1242 * 0 on success and -1 on failure.
1246 irp_unmarshall_ng(const char **hostp, const char **userp, const char **domainp,
1247 char *buffer)
1249 char *p, *q;
1250 char fieldsep = ',';
1251 int myerrno = EINVAL;
1252 char *host, *user, *domain;
1254 if (userp == NULL || hostp == NULL ||
1255 domainp == NULL || buffer == NULL) {
1256 errno = EINVAL;
1257 return (-1);
1260 host = user = domain = NULL;
1262 p = buffer;
1263 while (isspace((unsigned char)*p)) {
1264 p++;
1266 if (*p != '(') {
1267 goto error;
1270 q = p + 1;
1271 while (*q && *q != fieldsep)
1272 q++;
1273 if (!*q) {
1274 goto error;
1275 } else if (q > p + 1) {
1276 host = strndup(p, q - p);
1279 p = q + 1;
1280 if (!*p) {
1281 goto error;
1282 } else if (*p != fieldsep) {
1283 q = p + 1;
1284 while (*q && *q != fieldsep)
1285 q++;
1286 if (!*q) {
1287 goto error;
1289 user = strndup(p, q - p);
1290 } else {
1291 p++;
1294 if (!*p) {
1295 goto error;
1296 } else if (*p != ')') {
1297 q = p + 1;
1298 while (*q && *q != ')')
1299 q++;
1300 if (!*q) {
1301 goto error;
1303 domain = strndup(p, q - p);
1305 *hostp = host;
1306 *userp = user;
1307 *domainp = domain;
1309 return (0);
1311 error:
1312 errno = myerrno;
1314 if (host != NULL) free(host);
1315 if (user != NULL) free(user);
1316 if (domain != NULL) free(domain);
1318 return (-1);
1321 /* ------------------------- struct netgrp ------------------------- */
1326 /* +++++++++++++++++++++++++ struct nwent +++++++++++++++++++++++++ */
1330 * int irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len)
1332 * notes:
1334 * See at top.
1336 * return:
1338 * 0 on success and -1 on failure.
1343 irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len) {
1344 size_t need = 1; /* for null byte */
1345 char nAddrType[24];
1346 char nNet[MAXPADDRSIZE];
1347 const char *fieldsep = COLONSTR;
1349 if (ne == NULL || len == NULL) {
1350 return (-1);
1353 strcpy(nAddrType, ADDR_T_STR(ne->n_addrtype));
1355 if (inet_net_ntop(ne->n_addrtype, ne->n_addr, ne->n_length,
1356 nNet, sizeof nNet) == NULL) {
1357 return (-1);
1361 need += strlen(ne->n_name) + 1;
1362 need += joinlength(ne->n_aliases) + 1;
1363 need += strlen(nAddrType) + 1;
1364 need += strlen(nNet) + 1;
1366 if (buffer == NULL) {
1367 *len = need;
1368 return (0);
1371 if (*buffer != NULL && need > *len) {
1372 errno = EINVAL;
1373 return (-1);
1376 if (*buffer == NULL) {
1377 need += 2; /* for CRLF */
1378 *buffer = memget(need);
1379 if (*buffer == NULL) {
1380 errno = ENOMEM;
1381 return (-1);
1384 *len = need;
1387 strcpy(*buffer, ne->n_name); strcat(*buffer, fieldsep);
1388 joinarray(ne->n_aliases, *buffer, COMMA) ; strcat(*buffer, fieldsep);
1389 strcat(*buffer, nAddrType); strcat(*buffer, fieldsep);
1390 strcat(*buffer, nNet); strcat(*buffer, fieldsep);
1392 return (0);
1398 * int irp_unmarshall_nw(struct nwent *ne, char *buffer)
1400 * notes:
1402 * See note up top.
1404 * return:
1406 * 0 on success and -1 on failure.
1411 irp_unmarshall_nw(struct nwent *ne, char *buffer) {
1412 char *p, *q;
1413 int naddrtype;
1414 long nnet;
1415 int bits;
1416 char *name = NULL;
1417 char **aliases = NULL;
1418 char tmpbuf[24];
1419 char *tb;
1420 char fieldsep = ':';
1421 int myerrno = EINVAL;
1423 if (ne == NULL || buffer == NULL) {
1424 goto error;
1427 p = buffer;
1429 /* n_name field */
1430 name = NULL;
1431 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
1432 goto error;
1436 /* n_aliases field. Aliases are separated by commas */
1437 q = strchr(p, fieldsep);
1438 if (q == NULL) {
1439 goto error;
1441 aliases = splitarray(p, q, COMMA);
1442 if (aliases == NULL) {
1443 myerrno = errno;
1444 goto error;
1446 p = q + 1;
1449 /* h_addrtype field */
1450 tb = tmpbuf;
1451 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1452 strlen(tb) == 0U) {
1453 goto error;
1455 if (strcmp(tmpbuf, "AF_INET") == 0)
1456 naddrtype = AF_INET;
1457 else if (strcmp(tmpbuf, "AF_INET6") == 0)
1458 naddrtype = AF_INET6;
1459 else
1460 goto error;
1463 /* n_net field */
1464 tb = tmpbuf;
1465 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1466 strlen(tb) == 0U) {
1467 goto error;
1469 nnet = 0;
1470 bits = inet_net_pton(naddrtype, tmpbuf, &nnet, sizeof nnet);
1471 if (bits < 0) {
1472 goto error;
1475 /* nnet = ntohl(nnet); */ /* keep in network order for nwent */
1477 ne->n_name = name;
1478 ne->n_aliases = aliases;
1479 ne->n_addrtype = naddrtype;
1480 ne->n_length = bits;
1481 ne->n_addr = malloc(sizeof nnet);
1482 if (ne->n_addr == NULL) {
1483 goto error;
1486 memcpy(ne->n_addr, &nnet, sizeof nnet);
1488 return (0);
1490 error:
1491 errno = myerrno;
1493 if (name != NULL) free(name);
1494 free_array(aliases, 0);
1496 return (-1);
1500 /* ------------------------- struct nwent ------------------------- */
1503 /* +++++++++++++++++++++++++ struct netent +++++++++++++++++++++++++ */
1507 * int irp_marshall_ne(struct netent *ne, char **buffer, size_t *len)
1509 * notes:
1511 * See at top.
1513 * return:
1515 * 0 on success and -1 on failure.
1520 irp_marshall_ne(struct netent *ne, char **buffer, size_t *len) {
1521 size_t need = 1; /* for null byte */
1522 char nAddrType[24];
1523 char nNet[MAXPADDRSIZE];
1524 const char *fieldsep = COLONSTR;
1525 long nval;
1527 if (ne == NULL || len == NULL) {
1528 return (-1);
1531 strcpy(nAddrType, ADDR_T_STR(ne->n_addrtype));
1533 nval = htonl(ne->n_net);
1534 if (inet_ntop(ne->n_addrtype, &nval, nNet, sizeof nNet) == NULL) {
1535 return (-1);
1538 need += strlen(ne->n_name) + 1;
1539 need += joinlength(ne->n_aliases) + 1;
1540 need += strlen(nAddrType) + 1;
1541 need += strlen(nNet) + 1;
1543 if (buffer == NULL) {
1544 *len = need;
1545 return (0);
1548 if (*buffer != NULL && need > *len) {
1549 errno = EINVAL;
1550 return (-1);
1553 if (*buffer == NULL) {
1554 need += 2; /* for CRLF */
1555 *buffer = memget(need);
1556 if (*buffer == NULL) {
1557 errno = ENOMEM;
1558 return (-1);
1561 *len = need;
1564 strcpy(*buffer, ne->n_name); strcat(*buffer, fieldsep);
1565 joinarray(ne->n_aliases, *buffer, COMMA) ; strcat(*buffer, fieldsep);
1566 strcat(*buffer, nAddrType); strcat(*buffer, fieldsep);
1567 strcat(*buffer, nNet); strcat(*buffer, fieldsep);
1569 return (0);
1575 * int irp_unmarshall_ne(struct netent *ne, char *buffer)
1577 * notes:
1579 * See note up top.
1581 * return:
1583 * 0 on success and -1 on failure.
1588 irp_unmarshall_ne(struct netent *ne, char *buffer) {
1589 char *p, *q;
1590 int naddrtype;
1591 long nnet;
1592 int bits;
1593 char *name = NULL;
1594 char **aliases = NULL;
1595 char tmpbuf[24];
1596 char *tb;
1597 char fieldsep = ':';
1598 int myerrno = EINVAL;
1600 if (ne == NULL || buffer == NULL) {
1601 goto error;
1604 p = buffer;
1606 /* n_name field */
1607 name = NULL;
1608 if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) {
1609 goto error;
1613 /* n_aliases field. Aliases are separated by commas */
1614 q = strchr(p, fieldsep);
1615 if (q == NULL) {
1616 goto error;
1618 aliases = splitarray(p, q, COMMA);
1619 if (aliases == NULL) {
1620 myerrno = errno;
1621 goto error;
1623 p = q + 1;
1626 /* h_addrtype field */
1627 tb = tmpbuf;
1628 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1629 strlen(tb) == 0U) {
1630 goto error;
1632 if (strcmp(tmpbuf, "AF_INET") == 0)
1633 naddrtype = AF_INET;
1634 else if (strcmp(tmpbuf, "AF_INET6") == 0)
1635 naddrtype = AF_INET6;
1636 else
1637 goto error;
1640 /* n_net field */
1641 tb = tmpbuf;
1642 if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
1643 strlen(tb) == 0U) {
1644 goto error;
1646 bits = inet_net_pton(naddrtype, tmpbuf, &nnet, sizeof nnet);
1647 if (bits < 0) {
1648 goto error;
1650 nnet = ntohl(nnet);
1652 ne->n_name = name;
1653 ne->n_aliases = aliases;
1654 ne->n_addrtype = naddrtype;
1655 ne->n_net = nnet;
1657 return (0);
1659 error:
1660 errno = myerrno;
1662 if (name != NULL) free(name);
1663 free_array(aliases, 0);
1665 return (-1);
1669 /* ------------------------- struct netent ------------------------- */
1672 /* =========================================================================== */
1676 * static char ** splitarray(const char *buffer, const char *buffend, char delim)
1678 * notes:
1680 * Split a delim separated astring. Not allowed
1681 * to have two delims next to each other. BUFFER points to begining of
1682 * string, BUFFEND points to one past the end of the string
1683 * (i.e. points at where the null byte would be if null
1684 * terminated).
1686 * return:
1688 * Returns a malloced array of pointers, each pointer pointing to a
1689 * malloced string. If BUFEER is an empty string, then return values is
1690 * array of 1 pointer that is NULL. Returns NULL on failure.
1694 static char **
1695 splitarray(const char *buffer, const char *buffend, char delim) {
1696 const char *p, *q;
1697 int count = 0;
1698 char **arr = NULL;
1699 char **aptr;
1701 if (buffend < buffer)
1702 return (NULL);
1703 else if (buffend > buffer && *buffer == delim)
1704 return (NULL);
1705 else if (buffend > buffer && *(buffend - 1) == delim)
1706 return (NULL);
1708 /* count the number of field and make sure none are empty */
1709 if (buffend > buffer + 1) {
1710 for (count = 1, q = buffer ; q != buffend ; q++) {
1711 if (*q == delim) {
1712 if (q > buffer && (*(q - 1) == delim)) {
1713 errno = EINVAL;
1714 return (NULL);
1716 count++;
1721 if (count > 0) {
1722 count++ ; /* for NULL at end */
1723 aptr = arr = malloc(count * sizeof (char *));
1724 if (aptr == NULL) {
1725 errno = ENOMEM;
1726 return (NULL);
1729 memset(arr, 0x0, count * sizeof (char *));
1730 for (p = buffer ; p < buffend ; p++) {
1731 for (q = p ; *q != delim && q != buffend ; q++)
1732 /* nothing */;
1733 *aptr = strndup(p, q - p);
1735 p = q;
1736 aptr++;
1738 *aptr = NULL;
1739 } else {
1740 arr = malloc(sizeof (char *));
1741 if (arr == NULL) {
1742 errno = ENOMEM;
1743 return (NULL);
1746 *arr = NULL;
1749 return (arr);
1756 * static size_t joinlength(char * const *argv)
1758 * return:
1760 * the number of bytes in all the arrays pointed at
1761 * by argv, including their null bytes(which will usually be turned
1762 * into commas).
1767 static size_t
1768 joinlength(char * const *argv) {
1769 int len = 0;
1771 while (argv && *argv) {
1772 len += (strlen(*argv) + 1);
1773 argv++;
1776 return (len);
1782 * int joinarray(char * const *argv, char *buffer, char delim)
1784 * notes:
1786 * Copy all the ARGV strings into the end of BUFFER
1787 * separating them with DELIM. BUFFER is assumed to have
1788 * enough space to hold everything and to be already null-terminated.
1790 * return:
1792 * 0 unless argv or buffer is NULL.
1797 static int
1798 joinarray(char * const *argv, char *buffer, char delim) {
1799 char * const *p;
1800 char sep[2];
1802 if (argv == NULL || buffer == NULL) {
1803 errno = EINVAL;
1804 return (-1);
1807 sep[0] = delim;
1808 sep[1] = 0x0;
1810 for (p = argv ; *p != NULL ; p++) {
1811 strcat(buffer, *p);
1812 if (*(p + 1) != NULL) {
1813 strcat(buffer, sep);
1817 return (0);
1822 * static char * getfield(char **res, size_t reslen, char **ptr, char delim)
1824 * notes:
1826 * Stores in *RES, which is a buffer of length RESLEN, a
1827 * copy of the bytes from *PTR up to and including the first
1828 * instance of DELIM. If *RES is NULL, then it will be
1829 * assigned a malloced buffer to hold the copy. *PTR is
1830 * modified to point at the found delimiter.
1832 * return:
1834 * If there was no delimiter, then NULL is returned,
1835 * otherewise *RES is returned.
1839 static char *
1840 getfield(char **res, size_t reslen, char **ptr, char delim) {
1841 char *q;
1843 if (res == NULL || ptr == NULL || *ptr == NULL) {
1844 errno = EINVAL;
1845 return (NULL);
1848 q = strchr(*ptr, delim);
1850 if (q == NULL) {
1851 errno = EINVAL;
1852 return (NULL);
1853 } else {
1854 if (*res == NULL) {
1855 *res = strndup(*ptr, q - *ptr);
1856 } else {
1857 if ((size_t)(q - *ptr + 1) > reslen) { /* to big for res */
1858 errno = EINVAL;
1859 return (NULL);
1860 } else {
1861 strncpy(*res, *ptr, q - *ptr);
1862 (*res)[q - *ptr] = 0x0;
1865 *ptr = q + 1;
1868 return (*res);
1875 #ifndef HAVE_STRNDUP
1877 * static char * strndup(const char *str, size_t len)
1879 * notes:
1881 * like strdup, except do len bytes instead of the whole string. Always
1882 * null-terminates.
1884 * return:
1886 * The newly malloced string.
1890 static char *
1891 strndup(const char *str, size_t len) {
1892 char *p = malloc(len + 1);
1894 if (p == NULL)
1895 return (NULL);
1896 strncpy(p, str, len);
1897 p[len] = 0x0;
1898 return (p);
1900 #endif
1902 #if WANT_MAIN
1905 * static int strcmp_nws(const char *a, const char *b)
1907 * notes:
1909 * do a strcmp, except uneven lengths of whitespace compare the same
1911 * return:
1915 static int
1916 strcmp_nws(const char *a, const char *b) {
1917 while (*a && *b) {
1918 if (isspace(*a) && isspace(*b)) {
1919 do {
1920 a++;
1921 } while (isspace(*a));
1922 do {
1923 b++;
1924 } while (isspace(*b));
1926 if (*a < *b)
1927 return (-1);
1928 else if (*a > *b)
1929 return (1);
1931 a++;
1932 b++;;
1935 if (*a == *b)
1936 return (0);
1937 else if (*a > *b)
1938 return (1);
1939 else
1940 return (-1);
1943 #endif
1950 * static void free_array(char **argv, size_t entries)
1952 * notes:
1954 * Free argv and each of the pointers inside it. The end of
1955 * the array is when a NULL pointer is found inside. If
1956 * entries is > 0, then NULL pointers inside the array do
1957 * not indicate the end of the array.
1961 static void
1962 free_array(char **argv, size_t entries) {
1963 char **p = argv;
1964 int useEntries = (entries > 0U);
1966 if (argv == NULL)
1967 return;
1969 while ((useEntries && entries > 0U) || *p) {
1970 if (*p)
1971 free(*p);
1972 p++;
1973 if (useEntries)
1974 entries--;
1976 free(argv);
1983 /* ************************************************** */
1985 #if WANT_MAIN
1987 /* takes an option to indicate what sort of marshalling(read the code) and
1988 an argument. If the argument looks like a marshalled buffer(has a ':'
1989 embedded) then it's unmarshalled and the remarshalled and the new string
1990 is compared to the old one.
1994 main(int argc, char **argv) {
1995 char buffer[1024];
1996 char *b = &buffer[0];
1997 size_t len = sizeof buffer;
1998 char option;
2000 if (argc < 2 || argv[1][0] != '-')
2001 exit(1);
2003 option = argv[1][1];
2004 argv++;
2005 argc--;
2008 #if 0
2010 char buff[10];
2011 char *p = argv[1], *q = &buff[0];
2013 while (getfield(&q, sizeof buff, &p, ':') != NULL) {
2014 printf("field: \"%s\"\n", q);
2015 p++;
2017 printf("p is now \"%s\"\n", p);
2019 #endif
2021 #if 0
2023 char **x = splitarray(argv[1], argv[1] + strlen(argv[1]),
2024 argv[2][0]);
2025 char **p;
2027 if (x == NULL)
2028 printf("split failed\n");
2030 for (p = x ; p != NULL && *p != NULL ; p++) {
2031 printf("\"%s\"\n", *p);
2034 #endif
2036 #if 1
2037 switch(option) {
2038 case 'n': {
2039 struct nwent ne;
2040 int i;
2042 if (strchr(argv[1], ':') != NULL) {
2043 if (irp_unmarshall_nw(&ne, argv[1]) != 0) {
2044 printf("Unmarhsalling failed\n");
2045 exit(1);
2048 printf("Name: \"%s\"\n", ne.n_name);
2049 printf("Aliases:");
2050 for (i = 0 ; ne.n_aliases[i] != NULL ; i++)
2051 printf("\n\t\"%s\"", ne.n_aliases[i]);
2052 printf("\nAddrtype: %s\n", ADDR_T_STR(ne.n_addrtype));
2053 inet_net_ntop(ne.n_addrtype, ne.n_addr, ne.n_length,
2054 buffer, sizeof buffer);
2055 printf("Net: \"%s\"\n", buffer);
2056 *((long*)ne.n_addr) = htonl(*((long*)ne.n_addr));
2057 inet_net_ntop(ne.n_addrtype, ne.n_addr, ne.n_length,
2058 buffer, sizeof buffer);
2059 printf("Corrected Net: \"%s\"\n", buffer);
2060 } else {
2061 struct netent *np1 = getnetbyname(argv[1]);
2062 ne.n_name = np1->n_name;
2063 ne.n_aliases = np1->n_aliases;
2064 ne.n_addrtype = np1->n_addrtype;
2065 ne.n_addr = &np1->n_net;
2066 ne.n_length = (IN_CLASSA(np1->n_net) ?
2068 (IN_CLASSB(np1->n_net) ?
2069 16 :
2070 (IN_CLASSC(np1->n_net) ?
2071 24 : -1)));
2072 np1->n_net = htonl(np1->n_net);
2073 if (irp_marshall_nw(&ne, &b, &len) != 0) {
2074 printf("Marshalling failed\n");
2076 printf("%s\n", b);
2078 break;
2082 case 'r': {
2083 char **hosts, **users, **domains;
2084 size_t entries;
2085 int i;
2086 char *buff;
2087 size_t size;
2088 char *ngname;
2090 if (strchr(argv[1], '(') != NULL) {
2091 if (irp_unmarshall_ng(&ngname, &entries,
2092 &hosts, &users, &domains,
2093 argv[1]) != 0) {
2094 printf("unmarshall failed\n");
2095 exit(1);
2098 #define STRVAL(x) (x == NULL ? "*" : x)
2100 printf("%s {\n", ngname);
2101 for (i = 0 ; i < entries ; i++)
2102 printf("\t\"%s\" : \"%s\" : \"%s\"\n",
2103 STRVAL(hosts[i]),
2104 STRVAL(users[i]),
2105 STRVAL(domains[i]));
2106 printf("}\n\n\n");
2109 irp_marshall_ng_start(ngname, NULL, &size);
2110 for (i = 0 ; i < entries ; i++)
2111 irp_marshall_ng_next(hosts[i], users[i],
2112 domains[i], NULL, &size);
2113 irp_marshall_ng_end(NULL, &size);
2115 buff = malloc(size);
2117 irp_marshall_ng_start(ngname, buff, &size);
2118 for (i = 0 ; i < entries ; i++) {
2119 if (irp_marshall_ng_next(hosts[i], users[i],
2120 domains[i], buff,
2121 &size) != 0)
2122 printf("next marshalling failed.\n");
2124 irp_marshall_ng_end(buff, &size);
2126 if (strcmp_nws(argv[1], buff) != 0) {
2127 printf("compare failed:\n\t%s\n\t%s\n",
2128 buffer, argv[1]);
2129 } else {
2130 printf("compare ok\n");
2132 } else {
2133 char *h, *u, *d, *buff;
2134 size_t size;
2136 /* run through two times. First to figure out how
2137 much of a buffer we need. Second to do the
2138 actual marshalling */
2140 setnetgrent(argv[1]);
2141 irp_marshall_ng_start(argv[1], NULL, &size);
2142 while (getnetgrent(&h, &u, &d) == 1)
2143 irp_marshall_ng_next(h, u, d, NULL, &size);
2144 irp_marshall_ng_end(NULL, &size);
2145 endnetgrent(argv[1]);
2147 buff = malloc(size);
2149 setnetgrent(argv[1]);
2150 if (irp_marshall_ng_start(argv[1], buff, &size) != 0)
2151 printf("Marshalling start failed\n");
2153 while (getnetgrent(&h, &u, &d) == 1) {
2154 if (irp_marshall_ng_next(h, u, d, buff, &size)
2155 != 0) {
2156 printf("Marshalling failed\n");
2160 irp_marshall_ng_end(buff, &size);
2161 endnetgrent();
2163 printf("success: %s\n", buff);
2165 break;
2170 case 'h': {
2171 struct hostent he, *hp;
2172 int i;
2175 if (strchr(argv[1], '@') != NULL) {
2176 if (irp_unmarshall_ho(&he, argv[1]) != 0) {
2177 printf("unmarshall failed\n");
2178 exit(1);
2181 printf("Host: \"%s\"\nAliases:", he.h_name);
2182 for (i = 0 ; he.h_aliases[i] != NULL ; i++)
2183 printf("\n\t\t\"%s\"", he.h_aliases[i]);
2184 printf("\nAddr Type: \"%s\"\n",
2185 ADDR_T_STR(he.h_addrtype));
2186 printf("Length: %d\nAddresses:", he.h_length);
2187 for (i = 0 ; he.h_addr_list[i] != 0 ; i++) {
2188 inet_ntop(he.h_addrtype, he.h_addr_list[i],
2189 buffer, sizeof buffer);
2190 printf("\n\t\"%s\"\n", buffer);
2192 printf("\n\n");
2194 irp_marshall_ho(&he, &b, &len);
2195 if (strcmp(argv[1], buffer) != 0) {
2196 printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2197 buffer, argv[1]);
2198 } else {
2199 printf("compare ok\n");
2201 } else {
2202 if ((hp = gethostbyname(argv[1])) == NULL) {
2203 perror("gethostbyname");
2204 printf("\"%s\"\n", argv[1]);
2205 exit(1);
2208 if (irp_marshall_ho(hp, &b, &len) != 0) {
2209 printf("irp_marshall_ho failed\n");
2210 exit(1);
2213 printf("success: \"%s\"\n", buffer);
2215 break;
2219 case 's': {
2220 struct servent *sv;
2221 struct servent sv1;
2223 if (strchr(argv[1], ':') != NULL) {
2224 sv = &sv1;
2225 memset(sv, 0xef, sizeof (struct servent));
2226 if (irp_unmarshall_sv(sv, argv[1]) != 0) {
2227 printf("unmarshall failed\n");
2231 irp_marshall_sv(sv, &b, &len);
2232 if (strcmp(argv[1], buffer) != 0) {
2233 printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2234 buffer, argv[1]);
2235 } else {
2236 printf("compare ok\n");
2238 } else {
2239 if ((sv = getservbyname(argv[1], argv[2])) == NULL) {
2240 perror("getservent");
2241 exit(1);
2244 if (irp_marshall_sv(sv, &b, &len) != 0) {
2245 printf("irp_marshall_sv failed\n");
2246 exit(1);
2249 printf("success: \"%s\"\n", buffer);
2251 break;
2254 case 'g': {
2255 struct group *gr;
2256 struct group gr1;
2258 if (strchr(argv[1], ':') != NULL) {
2259 gr = &gr1;
2260 memset(gr, 0xef, sizeof (struct group));
2261 if (irp_unmarshall_gr(gr, argv[1]) != 0) {
2262 printf("unmarshall failed\n");
2266 irp_marshall_gr(gr, &b, &len);
2267 if (strcmp(argv[1], buffer) != 0) {
2268 printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2269 buffer, argv[1]);
2270 } else {
2271 printf("compare ok\n");
2273 } else {
2274 if ((gr = getgrnam(argv[1])) == NULL) {
2275 perror("getgrnam");
2276 exit(1);
2279 if (irp_marshall_gr(gr, &b, &len) != 0) {
2280 printf("irp_marshall_gr failed\n");
2281 exit(1);
2284 printf("success: \"%s\"\n", buffer);
2286 break;
2290 case 'p': {
2291 struct passwd *pw;
2292 struct passwd pw1;
2294 if (strchr(argv[1], ':') != NULL) {
2295 pw = &pw1;
2296 memset(pw, 0xef, sizeof (*pw));
2297 if (irp_unmarshall_pw(pw, argv[1]) != 0) {
2298 printf("unmarshall failed\n");
2299 exit(1);
2302 printf("User: \"%s\"\nPasswd: \"%s\"\nUid: %ld\nGid: %ld\n",
2303 pw->pw_name, pw->pw_passwd, (long)pw->pw_uid,
2304 (long)pw->pw_gid);
2305 printf("Class: \"%s\"\nChange: %ld\nGecos: \"%s\"\n",
2306 pw->pw_class, (long)pw->pw_change, pw->pw_gecos);
2307 printf("Shell: \"%s\"\nDirectory: \"%s\"\n",
2308 pw->pw_shell, pw->pw_dir);
2310 pw = getpwnam(pw->pw_name);
2311 irp_marshall_pw(pw, &b, &len);
2312 if (strcmp(argv[1], buffer) != 0) {
2313 printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
2314 buffer, argv[1]);
2315 } else {
2316 printf("compare ok\n");
2318 } else {
2319 if ((pw = getpwnam(argv[1])) == NULL) {
2320 perror("getpwnam");
2321 exit(1);
2324 if (irp_marshall_pw(pw, &b, &len) != 0) {
2325 printf("irp_marshall_pw failed\n");
2326 exit(1);
2329 printf("success: \"%s\"\n", buffer);
2331 break;
2334 default:
2335 printf("Wrong option: %c\n", option);
2336 break;
2339 #endif
2341 return (0);
2344 #endif