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