xref: /illumos-gate/usr/src/lib/libc/port/gen/nss_dbdefs.c (revision 9a016c63ca347047a236dff12f0da83aac8981d1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include "synonyms.h"
30 #include <ctype.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <nss_dbdefs.h>
35 #include <limits.h>
36 
37 /*
38  * ALIGN? is there an official definition of this?
39  * We use sizeof(long) to cover what we want
40  * for both the 32-bit world and 64-bit world.
41  */
42 
43 #define	ALIGN(x) ((((long)(x)) + sizeof (long) - 1) & ~(sizeof (long) - 1))
44 
45 nss_XbyY_buf_t *
46 _nss_XbyY_buf_alloc(int struct_size, int buffer_size)
47 {
48 	nss_XbyY_buf_t	*b;
49 
50 	/* Use one malloc for dbargs, result struct and buffer */
51 	b = (nss_XbyY_buf_t *)
52 		malloc(ALIGN(sizeof (*b)) + struct_size + buffer_size);
53 	if (b == 0) {
54 		return (0);
55 	}
56 	b->result = (void *)ALIGN(&b[1]);
57 	b->buffer = (char *)(b->result) + struct_size;
58 	b->buflen = buffer_size;
59 	return (b);
60 }
61 
62 void
63 _nss_XbyY_buf_free(nss_XbyY_buf_t *b)
64 {
65 	if (b != 0) {
66 		free(b);
67 	}
68 }
69 
70 /* === Comment:  used by fget{gr,pw,sp}ent */
71 /* ==== Should do ye olde syslog()ing of suspiciously long lines */
72 
73 void
74 _nss_XbyY_fgets(FILE *f, nss_XbyY_args_t *b)
75 {
76 	char		buf[LINE_MAX];
77 	int		len, parsestat;
78 
79 	if (fgets(buf, LINE_MAX, f) == 0) {
80 		/* End of file */
81 		b->returnval = 0;
82 		b->erange    = 0;
83 		return;
84 	}
85 	len = (int)strlen(buf);
86 	/* len >= 0 (otherwise we would have got EOF) */
87 	if (buf[len - 1] != '\n') {
88 		if ((len + 1) == LINE_MAX) {
89 			/* Line too long for buffer; too bad */
90 			while (fgets(buf, LINE_MAX, f) != 0 &&
91 			    buf[strlen(buf) - 1] != '\n') {
92 				;
93 			}
94 			b->returnval = 0;
95 			b->erange    = 1;
96 			return;
97 		}
98 		/* case where the file is not terminated with a Newline */
99 		len++;
100 	}
101 	parsestat = (*b->str2ent)(buf, (len - 1), b->buf.result, b->buf.buffer,
102 		b->buf.buflen);
103 	if (parsestat == NSS_STR_PARSE_ERANGE) {
104 		b->returnval = 0;
105 		b->erange    = 1;
106 	} else if (parsestat == NSS_STR_PARSE_SUCCESS) {
107 		b->returnval = b->buf.result;
108 	}
109 }
110 
111 /*
112  * parse the aliases string into the buffer and if successful return
113  * a char ** pointer to the beginning of the aliases.
114  *
115  * CAUTION: (instr, instr+lenstr) and (buffer, buffer+buflen) are
116  * non-intersecting memory areas. Since this is an internal interface,
117  * we should be able to live with that.
118  */
119 char **
120 _nss_netdb_aliases(const char *instr, int lenstr, char *buffer, int buflen)
121 	/* "instr" is the beginning of the aliases string */
122 	/* "buffer" has the return val for success */
123 	/* "buflen" is the length of the buffer available for aliases */
124 {
125 	/*
126 	 * Build the alias-list in the start of the buffer, and copy
127 	 * the strings to the end of the buffer.
128 	 */
129 	const char
130 		*instr_limit	= instr + lenstr;
131 	char	*copyptr	= buffer + buflen;
132 	char	**aliasp	= (char **)ROUND_UP(buffer, sizeof (*aliasp));
133 	char	**alias_start	= aliasp;
134 	int	nstrings	= 0;
135 
136 	for (;;) {
137 		const char	*str_start;
138 		size_t		str_len;
139 
140 		while (instr < instr_limit && isspace(*instr)) {
141 			instr++;
142 		}
143 		if (instr >= instr_limit || *instr == '#') {
144 			break;
145 		}
146 		str_start = instr;
147 		while (instr < instr_limit && !isspace(*instr)) {
148 			instr++;
149 		}
150 
151 		++nstrings;
152 
153 		str_len = instr - str_start;
154 		copyptr -= str_len + 1;
155 		if (copyptr <= (char *)(&aliasp[nstrings + 1])) {
156 			/* Has to be room for the pointer to */
157 			/* the alias we're about to add,   */
158 			/* as well as the final NULL ptr.  */
159 			return (0);
160 		}
161 		*aliasp++ = copyptr;
162 		(void) memcpy(copyptr, str_start, str_len);
163 		copyptr[str_len] = '\0';
164 	}
165 	*aliasp++ = 0;
166 	return (alias_start);
167 }
168