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 (c) 1998 by Sun Microsystems, Inc.
24  * All Rights Reserved
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * This file contains routines necessary to convert a string buffer into
31  * a printer object.
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <string.h>
39 #include <stdarg.h>
40 #include <syslog.h>
41 
42 #include <print/ns.h>
43 #include <print/list.h>
44 #include <print/misc.h>
45 
46 #define	ESCAPE_CHARS	"\\\n=:"	/* \, \n, =, : */
47 
48 /*
49  * Just like strncat(3C), but escapes the supplied characters.
50  * This allows the escape character '\' and seperators to be part of the
51  * keys or values.
52  */
53 char *
54 strncat_escaped(char *d, char *s, int len, char *escape)
55 {
56 	char *t = d;
57 
58 	while ((*t != NULL) && (len > 0))
59 		len--, t++;
60 
61 	if (escape == NULL)
62 		escape = "\\";
63 
64 	while ((*s != NULL) && (len > 0)) {
65 		if (strchr(escape, *s) != NULL)
66 			len--, *t++ = '\\';
67 		len--, *t++ = *s++;
68 	}
69 	*t = NULL;
70 
71 	return (d);
72 }
73 
74 
75 
76 char *
77 _cvt_printer_to_entry(ns_printer_t *printer, char *buf, int buflen)
78 {
79 	int i, len;
80 	int bufferok = 1;
81 
82 	memset(buf, NULL, buflen);
83 
84 	if ((printer == NULL) || (printer->attributes == NULL))
85 		return (NULL);
86 
87 	if (snprintf(buf, buflen, "%s", printer->name) >= buflen) {
88 		memset(buf, NULL, buflen);
89 		syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow");
90 		return (NULL);
91 	}
92 
93 	if ((printer->aliases != NULL) && (printer->aliases[0] != NULL)) {
94 		char **alias = printer->aliases;
95 
96 		while (*alias != NULL) {
97 			strlcat(buf, "|", buflen);
98 			strncat_escaped(buf, *alias++, buflen, ESCAPE_CHARS);
99 		}
100 	}
101 
102 	if (strlcat(buf, ":", buflen) >= buflen) {
103 		memset(buf, NULL, buflen);
104 		syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow");
105 		return (NULL);
106 	}
107 
108 	len = strlen(buf);
109 
110 	for (i = 0; printer->attributes[i] != NULL && bufferok; i++) {
111 		ns_kvp_t *kvp = printer->attributes[i];
112 
113 		if (kvp->value == NULL)
114 			continue;
115 		strlcat(buf, "\\\n\t:", buflen);
116 		strncat_escaped(buf, kvp->key, buflen, ESCAPE_CHARS);
117 		strlcat(buf, "=", buflen);
118 		strncat_escaped(buf, kvp->value, buflen, ESCAPE_CHARS);
119 		if (strlcat(buf, ":", buflen) >= buflen) {
120 			bufferok = 0;
121 		}
122 	}
123 
124 	if (!bufferok) {
125 		memset(buf, NULL, buflen);
126 		syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow");
127 		return (NULL);
128 	}
129 
130 	if (strlen(buf) == len) {	/* there were no attributes */
131 		memset(buf, NULL, buflen);
132 		buf = NULL;
133 	}
134 
135 	return (buf);
136 }
137 
138 
139 ns_printer_t *
140 _cvt_nss_entry_to_printer(char *entry, char *ns)
141 {
142 	char	*name = NULL,
143 		*key = NULL,
144 		**aliases = NULL,
145 		*cp,
146 		buf[BUFSIZ];
147 	int in_namelist = 1, buf_pos = 0;
148 	ns_printer_t *printer = NULL;
149 
150 	if (entry == NULL)
151 		return (NULL);
152 
153 	memset(buf, NULL, sizeof (buf));
154 	for (cp = entry; *cp != NULL; cp++) {
155 		switch (*cp) {
156 		case ':':	/* end of kvp */
157 			if (in_namelist != 0) {
158 				if (name == NULL)
159 					name = strdup(buf);
160 				else
161 					aliases = (char **)list_append(
162 							(void **)aliases,
163 							(void *)strdup(buf));
164 				printer = (ns_printer_t *)ns_printer_create(
165 						name, aliases, ns, NULL);
166 				in_namelist = 0;
167 			} else if (key != NULL)
168 				ns_set_value_from_string(key, buf, printer);
169 			memset(buf, NULL, sizeof (buf));
170 			buf_pos = 0;
171 			key = NULL;
172 			break;
173 		case '=':	/* kvp seperator */
174 			if (key == NULL) {
175 				key = strdup(buf);
176 				memset(buf, NULL, sizeof (buf));
177 				buf_pos = 0;
178 			} else
179 				buf[buf_pos++] = *cp;
180 			break;
181 		case '|':	/* namelist seperator */
182 			if (in_namelist != 0) {
183 				if (name == NULL)
184 					name = strdup(buf);
185 				else
186 					aliases = (char **)list_append(
187 							(void **)aliases,
188 							(void *)strdup(buf));
189 				memset(buf, NULL, sizeof (buf));
190 				buf_pos = 0;
191 			} else	/* add it to the buffer */
192 				buf[buf_pos++] = *cp;
193 			break;
194 		case '\\':	/* escape char */
195 			buf[buf_pos++] = *(++cp);
196 			break;
197 		default:
198 			buf[buf_pos++] = *cp;
199 		}
200 
201 	}
202 
203 	if (key != NULL)
204 		ns_set_value_from_string(key, buf, printer);
205 
206 	return (printer);
207 }
208