1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1986-1992 by Sun Microsystems Inc.
24*0Sstevel@tonic-gate  */
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate #include <ctype.h>
29*0Sstevel@tonic-gate #include <netdb.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <nss_dbdefs.h>
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate static int str2protoent(const char *, int, void *,
35*0Sstevel@tonic-gate 		char *, int);
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate static int proto_stayopen;
38*0Sstevel@tonic-gate /*
39*0Sstevel@tonic-gate  * Unsynchronized, but it affects only
40*0Sstevel@tonic-gate  * efficiency, not correctness
41*0Sstevel@tonic-gate  */
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(db_root);
44*0Sstevel@tonic-gate static DEFINE_NSS_GETENT(context);
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate static void
47*0Sstevel@tonic-gate _nss_initf_proto(nss_db_params_t *p)
48*0Sstevel@tonic-gate {
49*0Sstevel@tonic-gate 	p->name	= NSS_DBNAM_PROTOCOLS;
50*0Sstevel@tonic-gate 	p->default_config = NSS_DEFCONF_PROTOCOLS;
51*0Sstevel@tonic-gate }
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate struct protoent *
54*0Sstevel@tonic-gate getprotobyname_r(const char *name, struct protoent *result,
55*0Sstevel@tonic-gate 	char *buffer, int buflen)
56*0Sstevel@tonic-gate {
57*0Sstevel@tonic-gate 	nss_XbyY_args_t arg;
58*0Sstevel@tonic-gate 	nss_status_t	res;
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 	NSS_XbyY_INIT(&arg, result, buffer, buflen, str2protoent);
61*0Sstevel@tonic-gate 	arg.key.name	= name;
62*0Sstevel@tonic-gate 	arg.stayopen	= proto_stayopen;
63*0Sstevel@tonic-gate 	res = nss_search(&db_root, _nss_initf_proto,
64*0Sstevel@tonic-gate 		NSS_DBOP_PROTOCOLS_BYNAME, &arg);
65*0Sstevel@tonic-gate 	arg.status = res;
66*0Sstevel@tonic-gate 	(void) NSS_XbyY_FINI(&arg);
67*0Sstevel@tonic-gate 	return ((struct protoent *)arg.returnval);
68*0Sstevel@tonic-gate }
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate struct protoent *
71*0Sstevel@tonic-gate getprotobynumber_r(int proto, struct protoent *result, char *buffer, int buflen)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate 	nss_XbyY_args_t arg;
74*0Sstevel@tonic-gate 	nss_status_t	res;
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 	NSS_XbyY_INIT(&arg, result, buffer, buflen, str2protoent);
77*0Sstevel@tonic-gate 	arg.key.number = proto;
78*0Sstevel@tonic-gate 	arg.stayopen	= proto_stayopen;
79*0Sstevel@tonic-gate 	res = nss_search(&db_root, _nss_initf_proto,
80*0Sstevel@tonic-gate 		NSS_DBOP_PROTOCOLS_BYNUMBER, &arg);
81*0Sstevel@tonic-gate 	arg.status = res;
82*0Sstevel@tonic-gate 	(void) NSS_XbyY_FINI(&arg);
83*0Sstevel@tonic-gate 	return ((struct protoent *)arg.returnval);
84*0Sstevel@tonic-gate }
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate int
87*0Sstevel@tonic-gate setprotoent(int stay)
88*0Sstevel@tonic-gate {
89*0Sstevel@tonic-gate 	proto_stayopen = stay;
90*0Sstevel@tonic-gate 	nss_setent(&db_root, _nss_initf_proto, &context);
91*0Sstevel@tonic-gate 	return (0);
92*0Sstevel@tonic-gate }
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate int
95*0Sstevel@tonic-gate endprotoent()
96*0Sstevel@tonic-gate {
97*0Sstevel@tonic-gate 	proto_stayopen = 0;
98*0Sstevel@tonic-gate 	nss_endent(&db_root, _nss_initf_proto, &context);
99*0Sstevel@tonic-gate 	nss_delete(&db_root);
100*0Sstevel@tonic-gate 	return (0);
101*0Sstevel@tonic-gate }
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate struct protoent *
104*0Sstevel@tonic-gate getprotoent_r(struct protoent *result, char *buffer, int buflen)
105*0Sstevel@tonic-gate {
106*0Sstevel@tonic-gate 	nss_XbyY_args_t arg;
107*0Sstevel@tonic-gate 	nss_status_t	res;
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate 	NSS_XbyY_INIT(&arg, result, buffer, buflen, str2protoent);
110*0Sstevel@tonic-gate 	/* No stayopen flag;  of course you stay open for iteration */
111*0Sstevel@tonic-gate 	res = nss_getent(&db_root, _nss_initf_proto, &context, &arg);
112*0Sstevel@tonic-gate 	arg.status = res;
113*0Sstevel@tonic-gate 	(void) NSS_XbyY_FINI(&arg);
114*0Sstevel@tonic-gate 	return ((struct protoent *)arg.returnval);
115*0Sstevel@tonic-gate }
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate /*
118*0Sstevel@tonic-gate  * Return values: 0 = success, 1 = parse error, 2 = erange ...
119*0Sstevel@tonic-gate  * The structure pointer passed in is a structure in the caller's space
120*0Sstevel@tonic-gate  * wherein the field pointers would be set to areas in the buffer if
121*0Sstevel@tonic-gate  * need be. instring and buffer should be separate areas. Let's not
122*0Sstevel@tonic-gate  * fight over crumbs.
123*0Sstevel@tonic-gate  */
124*0Sstevel@tonic-gate static int
125*0Sstevel@tonic-gate str2protoent(const char *instr, int lenstr,
126*0Sstevel@tonic-gate 	void *ent /* it is really (struct protoent *) */,
127*0Sstevel@tonic-gate 	char *buffer, int buflen)
128*0Sstevel@tonic-gate {
129*0Sstevel@tonic-gate 	struct	protoent *proto = (struct protoent *)ent;
130*0Sstevel@tonic-gate 	const char	*p, *numstart, *namestart, *limit;
131*0Sstevel@tonic-gate 	int		numlen, namelen = 0;
132*0Sstevel@tonic-gate 	char		numbuf[16];
133*0Sstevel@tonic-gate 	char		*numend;
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	if ((instr >= buffer && (buffer + buflen) > instr) ||
136*0Sstevel@tonic-gate 	    (buffer >= instr && (instr + lenstr) > buffer)) {
137*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_PARSE);
138*0Sstevel@tonic-gate 	}
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	p = instr;
141*0Sstevel@tonic-gate 	limit = p + lenstr;
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate 	while (p < limit && isspace(*p)) {
144*0Sstevel@tonic-gate 		p++;
145*0Sstevel@tonic-gate 	}
146*0Sstevel@tonic-gate 	namestart = p;
147*0Sstevel@tonic-gate 	while (p < limit && !isspace(*p)) {
148*0Sstevel@tonic-gate 		p++;		/* Skip over the canonical name */
149*0Sstevel@tonic-gate 	}
150*0Sstevel@tonic-gate 	namelen = (int)(p - namestart);
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate 	if (buflen <= namelen) { /* not enough buffer */
153*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_ERANGE);
154*0Sstevel@tonic-gate 	}
155*0Sstevel@tonic-gate 	(void) memcpy(buffer, namestart, namelen);
156*0Sstevel@tonic-gate 	buffer[namelen] = '\0';
157*0Sstevel@tonic-gate 	proto->p_name = buffer;
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate 	while (p < limit && isspace(*p)) {
160*0Sstevel@tonic-gate 		p++;
161*0Sstevel@tonic-gate 	}
162*0Sstevel@tonic-gate 	if (p >= limit) {
163*0Sstevel@tonic-gate 		/* Syntax error -- no proto number */
164*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_PARSE);
165*0Sstevel@tonic-gate 	}
166*0Sstevel@tonic-gate 	numstart = p;
167*0Sstevel@tonic-gate 	do {
168*0Sstevel@tonic-gate 		p++;		/* Find the end of the proto number */
169*0Sstevel@tonic-gate 	} while (p < limit && !isspace(*p));
170*0Sstevel@tonic-gate 	numlen = (int)(p - numstart);
171*0Sstevel@tonic-gate 	if (numlen >= (int)sizeof (numbuf)) {
172*0Sstevel@tonic-gate 		/* Syntax error -- supposed number is too long */
173*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_PARSE);
174*0Sstevel@tonic-gate 	}
175*0Sstevel@tonic-gate 	(void) memcpy(numbuf, numstart, (size_t)numlen);
176*0Sstevel@tonic-gate 	numbuf[numlen] = '\0';
177*0Sstevel@tonic-gate 	proto->p_proto = (int)strtol(numbuf, &numend, 10);
178*0Sstevel@tonic-gate 	if (*numend != '\0') {
179*0Sstevel@tonic-gate 		/* Syntax error -- protocol number isn't a number */
180*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_PARSE);
181*0Sstevel@tonic-gate 	}
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	while (p < limit && isspace(*p)) {
184*0Sstevel@tonic-gate 		p++;
185*0Sstevel@tonic-gate 	}
186*0Sstevel@tonic-gate 	/*
187*0Sstevel@tonic-gate 	 * Although nss_files_XY_all calls us with # stripped,
188*0Sstevel@tonic-gate 	 * we should be able to deal with it here in order to
189*0Sstevel@tonic-gate 	 * be more useful.
190*0Sstevel@tonic-gate 	 */
191*0Sstevel@tonic-gate 	if (p >= limit || *p == '#') { /* no aliases, no problem */
192*0Sstevel@tonic-gate 		char **ptr;
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 		ptr = (char **)ROUND_UP(buffer + namelen + 1,
195*0Sstevel@tonic-gate 							sizeof (char *));
196*0Sstevel@tonic-gate 		if ((char *)ptr >= buffer + buflen) {
197*0Sstevel@tonic-gate 			/* hope they don't try to peek in */
198*0Sstevel@tonic-gate 			proto->p_aliases = 0;
199*0Sstevel@tonic-gate 			return (NSS_STR_PARSE_ERANGE);
200*0Sstevel@tonic-gate 		} else {
201*0Sstevel@tonic-gate 			*ptr = 0;
202*0Sstevel@tonic-gate 			proto->p_aliases = ptr;
203*0Sstevel@tonic-gate 			return (NSS_STR_PARSE_SUCCESS);
204*0Sstevel@tonic-gate 		}
205*0Sstevel@tonic-gate 	}
206*0Sstevel@tonic-gate 	proto->p_aliases = _nss_netdb_aliases(p, lenstr - (int)(p - instr),
207*0Sstevel@tonic-gate 				buffer + namelen + 1, buflen - namelen - 1);
208*0Sstevel@tonic-gate 	return (NSS_STR_PARSE_SUCCESS);
209*0Sstevel@tonic-gate }
210