1*2264Sjacobs /*
2*2264Sjacobs  * CDDL HEADER START
3*2264Sjacobs  *
4*2264Sjacobs  * The contents of this file are subject to the terms of the
5*2264Sjacobs  * Common Development and Distribution License (the "License").
6*2264Sjacobs  * You may not use this file except in compliance with the License.
7*2264Sjacobs  *
8*2264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs  * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs  * See the License for the specific language governing permissions
11*2264Sjacobs  * and limitations under the License.
12*2264Sjacobs  *
13*2264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs  *
19*2264Sjacobs  * CDDL HEADER END
20*2264Sjacobs  */
21*2264Sjacobs /*
22*2264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*2264Sjacobs  * Use is subject to license terms.
24*2264Sjacobs  */
25*2264Sjacobs 
26*2264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*2264Sjacobs 
28*2264Sjacobs /*
29*2264Sjacobs  * This file contains routines necessary to convert a string buffer into
30*2264Sjacobs  * a printer object.
31*2264Sjacobs  */
32*2264Sjacobs 
33*2264Sjacobs #include <stdio.h>
34*2264Sjacobs #include <stdlib.h>
35*2264Sjacobs #include <unistd.h>
36*2264Sjacobs #include <sys/types.h>
37*2264Sjacobs #include <string.h>
38*2264Sjacobs #include <stdarg.h>
39*2264Sjacobs #include <syslog.h>
40*2264Sjacobs 
41*2264Sjacobs #include <ns.h>
42*2264Sjacobs #include <list.h>
43*2264Sjacobs #include <misc.h>
44*2264Sjacobs 
45*2264Sjacobs #define	ESCAPE_CHARS	"\\\n=:"	/* \, \n, =, : */
46*2264Sjacobs 
47*2264Sjacobs /*
48*2264Sjacobs  * Just like strncat(3C), but escapes the supplied characters.
49*2264Sjacobs  * This allows the escape character '\' and seperators to be part of the
50*2264Sjacobs  * keys or values.
51*2264Sjacobs  */
52*2264Sjacobs char *
53*2264Sjacobs strncat_escaped(char *d, char *s, int len, char *escape)
54*2264Sjacobs {
55*2264Sjacobs 	char *t = d;
56*2264Sjacobs 
57*2264Sjacobs 	while ((*t != NULL) && (len > 0))
58*2264Sjacobs 		len--, t++;
59*2264Sjacobs 
60*2264Sjacobs 	if (escape == NULL)
61*2264Sjacobs 		escape = "\\";
62*2264Sjacobs 
63*2264Sjacobs 	while ((*s != NULL) && (len > 0)) {
64*2264Sjacobs 		if (strchr(escape, *s) != NULL)
65*2264Sjacobs 			len--, *t++ = '\\';
66*2264Sjacobs 		len--, *t++ = *s++;
67*2264Sjacobs 	}
68*2264Sjacobs 	*t = NULL;
69*2264Sjacobs 
70*2264Sjacobs 	return (d);
71*2264Sjacobs }
72*2264Sjacobs 
73*2264Sjacobs 
74*2264Sjacobs 
75*2264Sjacobs char *
76*2264Sjacobs _cvt_printer_to_entry(ns_printer_t *printer, char *buf, int buflen)
77*2264Sjacobs {
78*2264Sjacobs 	int i, len;
79*2264Sjacobs 	int bufferok = 1;
80*2264Sjacobs 
81*2264Sjacobs 	(void) memset(buf, NULL, buflen);
82*2264Sjacobs 
83*2264Sjacobs 	if ((printer == NULL) || (printer->attributes == NULL))
84*2264Sjacobs 		return (NULL);
85*2264Sjacobs 
86*2264Sjacobs 	if (snprintf(buf, buflen, "%s", printer->name) >= buflen) {
87*2264Sjacobs 		(void) memset(buf, NULL, buflen);
88*2264Sjacobs 		syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow");
89*2264Sjacobs 		return (NULL);
90*2264Sjacobs 	}
91*2264Sjacobs 
92*2264Sjacobs 	if ((printer->aliases != NULL) && (printer->aliases[0] != NULL)) {
93*2264Sjacobs 		char **alias = printer->aliases;
94*2264Sjacobs 
95*2264Sjacobs 		while (*alias != NULL) {
96*2264Sjacobs 			(void) strlcat(buf, "|", buflen);
97*2264Sjacobs 			(void) strncat_escaped(buf, *alias++, buflen,
98*2264Sjacobs 			    ESCAPE_CHARS);
99*2264Sjacobs 		}
100*2264Sjacobs 	}
101*2264Sjacobs 
102*2264Sjacobs 	if (strlcat(buf, ":", buflen) >= buflen) {
103*2264Sjacobs 		(void) memset(buf, NULL, buflen);
104*2264Sjacobs 		syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow");
105*2264Sjacobs 		return (NULL);
106*2264Sjacobs 	}
107*2264Sjacobs 
108*2264Sjacobs 	len = strlen(buf);
109*2264Sjacobs 
110*2264Sjacobs 	for (i = 0; printer->attributes[i] != NULL && bufferok; i++) {
111*2264Sjacobs 		ns_kvp_t *kvp = printer->attributes[i];
112*2264Sjacobs 
113*2264Sjacobs 		if (kvp->value == NULL)
114*2264Sjacobs 			continue;
115*2264Sjacobs 		(void) strlcat(buf, "\\\n\t:", buflen);
116*2264Sjacobs 		(void) strncat_escaped(buf, kvp->key, buflen, ESCAPE_CHARS);
117*2264Sjacobs 		(void) strlcat(buf, "=", buflen);
118*2264Sjacobs 		(void) strncat_escaped(buf, kvp->value, buflen, ESCAPE_CHARS);
119*2264Sjacobs 		if (strlcat(buf, ":", buflen) >= buflen) {
120*2264Sjacobs 			bufferok = 0;
121*2264Sjacobs 		}
122*2264Sjacobs 	}
123*2264Sjacobs 
124*2264Sjacobs 	if (!bufferok) {
125*2264Sjacobs 		(void) memset(buf, NULL, buflen);
126*2264Sjacobs 		syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow");
127*2264Sjacobs 		return (NULL);
128*2264Sjacobs 	}
129*2264Sjacobs 
130*2264Sjacobs 	if (strlen(buf) == len) {	/* there were no attributes */
131*2264Sjacobs 		(void) memset(buf, NULL, buflen);
132*2264Sjacobs 		buf = NULL;
133*2264Sjacobs 	}
134*2264Sjacobs 
135*2264Sjacobs 	return (buf);
136*2264Sjacobs }
137*2264Sjacobs 
138*2264Sjacobs 
139*2264Sjacobs ns_printer_t *
140*2264Sjacobs _cvt_nss_entry_to_printer(char *entry, char *ns)
141*2264Sjacobs {
142*2264Sjacobs 	char	*name = NULL,
143*2264Sjacobs 		*key = NULL,
144*2264Sjacobs 		**aliases = NULL,
145*2264Sjacobs 		*cp,
146*2264Sjacobs 		buf[BUFSIZ];
147*2264Sjacobs 	int in_namelist = 1, buf_pos = 0;
148*2264Sjacobs 	ns_printer_t *printer = NULL;
149*2264Sjacobs 
150*2264Sjacobs 	if (entry == NULL)
151*2264Sjacobs 		return (NULL);
152*2264Sjacobs 
153*2264Sjacobs 	(void) memset(buf, NULL, sizeof (buf));
154*2264Sjacobs 	for (cp = entry; *cp != NULL; cp++) {
155*2264Sjacobs 		switch (*cp) {
156*2264Sjacobs 		case ':':	/* end of kvp */
157*2264Sjacobs 			if (in_namelist != 0) {
158*2264Sjacobs 				if (name == NULL)
159*2264Sjacobs 					name = strdup(buf);
160*2264Sjacobs 				else
161*2264Sjacobs 					aliases = (char **)list_append(
162*2264Sjacobs 							(void **)aliases,
163*2264Sjacobs 							(void *)strdup(buf));
164*2264Sjacobs 				printer = (ns_printer_t *)ns_printer_create(
165*2264Sjacobs 						name, aliases, ns, NULL);
166*2264Sjacobs 				in_namelist = 0;
167*2264Sjacobs 			} else if (key != NULL)
168*2264Sjacobs 				(void) ns_set_value_from_string(key, buf,
169*2264Sjacobs 				    printer);
170*2264Sjacobs 			(void) memset(buf, NULL, sizeof (buf));
171*2264Sjacobs 			buf_pos = 0;
172*2264Sjacobs 			key = NULL;
173*2264Sjacobs 			break;
174*2264Sjacobs 		case '=':	/* kvp seperator */
175*2264Sjacobs 			if (key == NULL) {
176*2264Sjacobs 				key = strdup(buf);
177*2264Sjacobs 				(void) memset(buf, NULL, sizeof (buf));
178*2264Sjacobs 				buf_pos = 0;
179*2264Sjacobs 			} else
180*2264Sjacobs 				buf[buf_pos++] = *cp;
181*2264Sjacobs 			break;
182*2264Sjacobs 		case '|':	/* namelist seperator */
183*2264Sjacobs 			if (in_namelist != 0) {
184*2264Sjacobs 				if (name == NULL)
185*2264Sjacobs 					name = strdup(buf);
186*2264Sjacobs 				else
187*2264Sjacobs 					aliases = (char **)list_append(
188*2264Sjacobs 							(void **)aliases,
189*2264Sjacobs 							(void *)strdup(buf));
190*2264Sjacobs 				(void) memset(buf, NULL, sizeof (buf));
191*2264Sjacobs 				buf_pos = 0;
192*2264Sjacobs 			} else	/* add it to the buffer */
193*2264Sjacobs 				buf[buf_pos++] = *cp;
194*2264Sjacobs 			break;
195*2264Sjacobs 		case '\\':	/* escape char */
196*2264Sjacobs 			buf[buf_pos++] = *(++cp);
197*2264Sjacobs 			break;
198*2264Sjacobs 		default:
199*2264Sjacobs 			buf[buf_pos++] = *cp;
200*2264Sjacobs 		}
201*2264Sjacobs 
202*2264Sjacobs 	}
203*2264Sjacobs 
204*2264Sjacobs 	if (key != NULL)
205*2264Sjacobs 		(void) ns_set_value_from_string(key, buf, printer);
206*2264Sjacobs 
207*2264Sjacobs 	return (printer);
208*2264Sjacobs }
209