xref: /illumos-gate/usr/src/lib/nsswitch/files/common/getprinter.c (revision f37b3cbb6f67aaea5eec1c335bdc7bf432867d64)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  *	files/printers_getbyname.c -- "files" backend for
23  *	nsswitch "printers" database.
24  *
25  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 static const char *printers = "/etc/printers.conf";
30 
31 #pragma weak _nss_files__printers_constr = _nss_files_printers_constr
32 
33 #include "files_common.h"
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <ctype.h>
37 
38 static int
39 check_name(nss_XbyY_args_t *argp, const char *line, int linelen)
40 {
41 
42 	const char	*limit, *linep;
43 	const char	*keyp = argp->key.name;
44 	int		klen = strlen(keyp);
45 
46 	linep = line;
47 	limit = line + linelen;
48 
49 	/*
50 	 * find the name in the namelist a|b|c...:
51 	 */
52 	while (linep+klen < limit && *linep != '|' && *linep != ':') {
53 		if ((strncmp(linep, keyp, klen) == 0) &&
54 		    ((*(linep + klen) == '|') || (*(linep + klen) == ':'))) {
55 			return (1);
56 		} else {
57 			while (linep < limit && *linep != '|' && *linep != ':')
58 				linep++;
59 			if (linep >= limit || *linep == ':')
60 				return (0);
61 			if (*linep == '|')
62 				linep++;
63 		}
64 	}
65 	return (0);
66 }
67 
68 nss_status_t
69 _nss_files_XY_printer(be, args, filter, check)
70 	files_backend_ptr_t	be;
71 	nss_XbyY_args_t		*args;
72 	const char		*filter;	/* advisory, to speed up */
73 						/* string search */
74 	files_XY_check_func	check;	/* NULL means one-shot, for getXXent */
75 {
76 	nss_status_t		res;
77 	int	parsestat;
78 	int (*func)();
79 
80 	if (filter != NULL && *filter == '\0')
81 		return (NSS_NOTFOUND);
82 	if (be->buf == 0 &&
83 		(be->buf = malloc(be->minbuf)) == 0) {
84 		return (NSS_UNAVAIL); /* really panic, malloc failed */
85 	}
86 
87 	if (check != 0 || be->f == 0) {
88 		if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) {
89 			return (res);
90 		}
91 	}
92 
93 	res = NSS_NOTFOUND;
94 
95 	/*CONSTCOND*/
96 	while (1) {
97 		char		*instr	= be->buf;
98 		int		linelen;
99 
100 		if ((linelen = _nss_files_read_line(be->f, instr,
101 		    be->minbuf)) < 0) {
102 			/* End of file */
103 			args->returnval = 0;
104 			args->returnlen = 0;
105 			break;
106 		}
107 
108 		/* begin at the first non-blank character */
109 		while (isspace(*instr)) {
110 			instr++;
111 			linelen--;
112 		}
113 
114 		/* comment line, skip it. */
115 		if (*instr == '#')
116 			continue;
117 
118 		/* blank line, skip it */
119 		if ((*instr == '\n') || (*instr == '\0'))
120 			continue;
121 
122 		if (filter != 0 && strstr(instr, filter) == 0) {
123 			/*
124 			 * Optimization:  if the entry doesn't contain the
125 			 *   filter string then it can't be the entry we want,
126 			 *   so don't bother looking more closely at it.
127 			 */
128 			continue;
129 		}
130 
131 		args->returnval = 0;
132 		args->returnlen = 0;
133 
134 		if (check != NULL && (*check)(args, instr, linelen) == 0)
135 			continue;
136 
137 		func = args->str2ent;
138 		parsestat = (*func)(instr, linelen, args->buf.result,
139 					args->buf.buffer, args->buf.buflen);
140 
141 		if (parsestat == NSS_STR_PARSE_SUCCESS) {
142 			args->returnval = (args->buf.result != NULL)?
143 					args->buf.result : args->buf.buffer;
144 			args->returnlen = linelen;
145 			res = NSS_SUCCESS;
146 			break;
147 		} else if (parsestat == NSS_STR_PARSE_ERANGE) {
148 			args->erange = 1;
149 			break;
150 		} else if (parsestat == NSS_STR_PARSE_PARSE)
151 			continue;
152 	}
153 
154 	/*
155 	 * stayopen is set to 0 by default in order to close the opened
156 	 * file.  Some applications may break if it is set to 1.
157 	 */
158 	if (check != 0 && !args->stayopen) {
159 		(void) _nss_files_endent(be, 0);
160 	}
161 
162 	return (res);
163 }
164 
165 static nss_status_t
166 getent(be, a)
167 	files_backend_ptr_t	be;
168 	void			*a;
169 {
170 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
171 
172 	return (_nss_files_XY_printer(be, argp, (const char *)0,
173 					(files_XY_check_func)0));
174 }
175 
176 static nss_status_t
177 getbyname(be, a)
178 	files_backend_ptr_t	be;
179 	void			*a;
180 {
181 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
182 
183 	return (_nss_files_XY_printer(be, argp, argp->key.name, check_name));
184 }
185 
186 static files_backend_op_t printers_ops[] = {
187 	_nss_files_destr,
188 	_nss_files_endent,
189 	_nss_files_setent,
190 	getent,
191 	getbyname
192 };
193 
194 /*ARGSUSED*/
195 nss_backend_t *
196 _nss_files_printers_constr(dummy1, dummy2, dummy3)
197 	const char	*dummy1, *dummy2, *dummy3;
198 {
199 	return (_nss_files_constr(printers_ops,
200 			sizeof (printers_ops) / sizeof (printers_ops[0]),
201 			printers,
202 			NSS_LINELEN_PRINTERS,
203 			NULL));
204 }
205