xref: /illumos-gate/usr/src/lib/nsswitch/files/common/getprinter.c (revision 60405de4d8688d96dd05157c28db3ade5c9bc234)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 static const char *printers = "/etc/printers.conf";
32 
33 #pragma weak _nss_files__printers_constr = _nss_files_printers_constr
34 
35 #include "files_common.h"
36 #include <stdlib.h>
37 #include <strings.h>
38 
39 static nss_status_t _nss_files_XY_printers(files_backend_ptr_t,
40 	nss_XbyY_args_t *, const char *);
41 
42 
43 static nss_status_t
44 getent(be, a)
45 	files_backend_ptr_t	be;
46 	void			*a;
47 {
48 	nss_XbyY_args_t	 *args = (nss_XbyY_args_t *)a;
49 
50 	return (_nss_files_XY_all(be, args, 0, 0, 0));
51 }
52 
53 
54 static nss_status_t
55 getbyname(be, a)
56 	files_backend_ptr_t	be;
57 	void			*a;
58 {
59 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
60 	nss_status_t		res;
61 
62 	/* printers_getbyname() has not set/endent; rewind on each call */
63 	if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) {
64 		return (res);
65 	}
66 	return (_nss_files_XY_printers(be, argp, argp->key.name));
67 }
68 
69 static files_backend_op_t printers_ops[] = {
70 	_nss_files_destr,
71 	_nss_files_endent,
72 	_nss_files_setent,
73 	getent,
74 	getbyname
75 };
76 
77 nss_backend_t *
78 _nss_files_printers_constr(dummy1, dummy2, dummy3)
79 	const char	*dummy1, *dummy2, *dummy3;
80 {
81 	return (_nss_files_constr(printers_ops,
82 		sizeof (printers_ops) / sizeof (printers_ops[0]),
83 		printers,
84 		NSS_LINELEN_PRINTERS,
85 		NULL));
86 }
87 
88 /*
89  * printers has the hostname as part of the data in the file, but the other
90  * backends don't include it in the data passed to the backend.  For this
91  * reason, we process everything here and don't bother calling the backend.
92  */
93 static nss_status_t
94 _nss_files_XY_printers(be, args, filter)
95 	files_backend_ptr_t	be;
96 	nss_XbyY_args_t		*args;
97 	const char		*filter;
98 			/*
99 			 * filter not useful here since the key
100 			 * we are looking for is the first "word"
101 			 * on the line and we can be fast enough.
102 			 */
103 {
104 	nss_status_t		res;
105 	int	parsestat;
106 	int namelen;
107 
108 	if (be->buf == 0 &&
109 		(be->buf = (char *)malloc(be->minbuf)) == 0) {
110 		(void) _nss_files_endent(be, 0);
111 		return (NSS_UNAVAIL); /* really panic, malloc failed */
112 	}
113 
114 	res = NSS_NOTFOUND;
115 	namelen = strlen(args->key.name);
116 
117 	while (1) {
118 		char		*instr	= be->buf;
119 		char		*p, *limit;
120 		int		linelen;
121 		int		found = 0;
122 
123 		/*
124 		 * _nss_files_read_line does process the '\' that are used
125 		 * in /etc/printers.conf for continuation and gives one long
126 		 * buffer.
127 		 *
128 		 * linelen counts the characters up to but excluding the '\n'
129 		 */
130 		if ((linelen = _nss_files_read_line(be->f, instr,
131 		    be->minbuf)) < 0) {
132 			/* End of file */
133 			args->returnval = 0;
134 			args->erange    = 0;
135 			break;
136 		}
137 		p = instr;
138 
139 		if (*p == '#')					/* comment */
140 			continue;
141 
142 		/*
143 		 * find the name in the namelist a|b|c...:
144 		 */
145 		if ((limit = strchr(instr, ':')) == NULL)	/* bad line */
146 			continue;
147 		while ((p < limit) && (found == 0)) {
148 			if ((strncmp(p, args->key.name, namelen) == 0) &&
149 			    ((*(p+namelen) == '|') || (*(p+namelen) == ':')))
150 				found++;
151 			else {
152 				if ((p = strchr(p, '|')) == NULL)
153 					p = limit;
154 				else	/* skip the '|' */
155 					p++;
156 			}
157 		}
158 		if (found == 0)
159 			continue;
160 
161 		p = instr;
162 
163 		if (args->buf.buflen <= linelen) {	/* not enough buffer */
164 			args->erange = 1;
165 			break;
166 		}
167 		(void) memcpy(args->buf.buffer, p, linelen);
168 		args->buf.buffer[linelen] = '\0';
169 		args->returnval = args->buf.result;
170 		res = NSS_SUCCESS;
171 		break;
172 	}
173 	(void) _nss_files_endent(be, 0);
174 	return (res);
175 }
176