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