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 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*LINTLIBRARY*/
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <sys/types.h>
32 #include <stdarg.h>
33 #include <string.h>
34
35 #include <ns.h>
36 #include <list.h>
37
38 /*
39 * Commonly Used routines...
40 */
41
42 /*
43 * FUNCTION:
44 * kvp_create(const char *key, const void *value)
45 * INPUT(S):
46 * const char *key
47 * - key for key/value pair
48 * const void *value
49 * - value for key/value pair
50 * OUTPUT(S):
51 * ns_kvp_t * (return value)
52 * - pointer to structure containing the key/value pair
53 * DESCRIPTION:
54 */
55 ns_kvp_t *
ns_kvp_create(const char * key,const char * value)56 ns_kvp_create(const char *key, const char *value)
57 {
58 ns_kvp_t *kvp;
59
60 if ((kvp = calloc(1, sizeof (*kvp))) != NULL) {
61 kvp->key = strdup(key);
62 kvp->value = (char *)value;
63 }
64 return (kvp);
65 }
66
67 int
ns_kvp_destroy(void * arg,va_list arg1 __unused)68 ns_kvp_destroy(void *arg, va_list arg1 __unused)
69 {
70 ns_kvp_t *kvp = arg;
71
72 if (kvp != NULL) {
73 if (kvp->key != NULL)
74 free(kvp->key);
75 if (kvp->value != NULL)
76 free(kvp->value);
77 free(kvp);
78 }
79 return (0);
80 }
81
82
83
84
85 /*
86 * FUNCTION:
87 * ns_kvp_match_key(const ns_kvp_t *kvp, const char *key)
88 * INPUT(S):
89 * const ns_kvp_t *kvp
90 * - key/value pair to check
91 * const char *key
92 * - key for matching
93 * OUTPUT(S):
94 * int (return value)
95 * - 0 if matched
96 * DESCRIPTION:
97 */
98 static int
ns_kvp_match_key(const ns_kvp_t * kvp,char * key)99 ns_kvp_match_key(const ns_kvp_t *kvp, char *key)
100 {
101 if ((kvp != NULL) && (kvp->key != NULL) && (key != NULL))
102 return (strcmp(kvp->key, key));
103 return (-1);
104 }
105
106
107 /*
108 * FUNCTION:
109 * ns_r_get_value(const char *key, const ns_printer_t *printer)
110 * INPUT(S):
111 * const char *key
112 * - key for matching
113 * const ns_printer_t *printer
114 * - printer to glean this from
115 * OUTPUT(S):
116 * char * (return value)
117 * - NULL, if not matched
118 * DESCRIPTION:
119 */
120 static void *
ns_r_get_value(const char * key,const ns_printer_t * printer,int level)121 ns_r_get_value(const char *key, const ns_printer_t *printer, int level)
122 {
123 ns_kvp_t *kvp, **attrs;
124
125 if ((key == NULL) || (printer == NULL) ||
126 (printer->attributes == NULL))
127 return (NULL);
128
129 if (level++ == 16)
130 return (NULL);
131
132 /* find it right here */
133 if ((kvp = list_locate((void **)printer->attributes,
134 (COMP_T)ns_kvp_match_key, (void *)key)) != NULL) {
135 void *value = string_to_value(key, kvp->value);
136
137 /* fill in an empty printer for a bsdaddr */
138 if (strcmp(key, NS_KEY_BSDADDR) == 0) {
139 ns_bsd_addr_t *addr = value;
140
141 if (addr->printer == NULL)
142 addr->printer = strdup(printer->name);
143 }
144 return (value);
145 }
146
147 /* find it in a child */
148 for (attrs = printer->attributes; attrs != NULL && *attrs != NULL;
149 attrs++) {
150 void *value = NULL;
151
152 if ((strcmp((*attrs)->key, NS_KEY_ALL) == 0) ||
153 (strcmp((*attrs)->key, NS_KEY_GROUP) == 0)) {
154 char **printers;
155
156 for (printers = string_to_value((*attrs)->key,
157 (*attrs)->value);
158 printers != NULL && *printers != NULL; printers++) {
159 ns_printer_t *printer =
160 ns_printer_get_name(*printers, NULL);
161
162 value = ns_r_get_value(key, printer, level);
163 if (value != NULL)
164 return (value);
165 ns_printer_destroy(printer);
166 }
167 } else if (strcmp((*attrs)->key, NS_KEY_LIST) == 0) {
168 ns_printer_t **printers;
169
170 for (printers = string_to_value((*attrs)->key,
171 (*attrs)->value);
172 printers != NULL && *printers != NULL; printers++) {
173 value = ns_r_get_value(key, *printers, level);
174 if (value != NULL)
175 return (value);
176 }
177 } else if (strcmp((*attrs)->key, NS_KEY_USE) == 0) {
178 char *string = NULL;
179 ns_printer_t *printer =
180 ns_printer_get_name((*attrs)->value, NULL);
181 value = ns_r_get_value(key, printer, level);
182 if (value != NULL)
183 string = value_to_string(string, value);
184 if (string != NULL)
185 value = string_to_value(key, string);
186 ns_printer_destroy(printer);
187 }
188
189 if (value != NULL)
190 return (value);
191 }
192
193 return (NULL);
194 }
195
196
197 /*
198 * ns_get_value() gets the value of the passed in attribute from the passed
199 * in printer structure. The value is returned in a converted format.
200 */
201 void *
ns_get_value(const char * key,const ns_printer_t * printer)202 ns_get_value(const char *key, const ns_printer_t *printer)
203 {
204 return (ns_r_get_value(key, printer, 0));
205 }
206
207
208 /*
209 * ns_get_value_string() gets the value of the key passed in from the
210 * printer structure passed in. The results is an ascii string.
211 */
212 char *
ns_get_value_string(const char * key,const ns_printer_t * printer)213 ns_get_value_string(const char *key, const ns_printer_t *printer)
214 {
215 return ((char *)value_to_string(key, ns_get_value(key, printer)));
216 }
217
218
219 /*
220 * ns_set_value() sets the passed in kvp in the passed in printer structure,
221 * This is done by converting the value to a string first.
222 */
223 int
ns_set_value(const char * key,const void * value,ns_printer_t * printer)224 ns_set_value(const char *key, const void *value, ns_printer_t *printer)
225 {
226 return (ns_set_value_from_string(key,
227 value_to_string(key, (void *)value), printer));
228 }
229
230
231 /*
232 * ns_set_value_from_string() sets the passed in kvp in the passed in printer
233 * structure.
234 */
235 int
ns_set_value_from_string(const char * key,const char * string,ns_printer_t * printer)236 ns_set_value_from_string(const char *key, const char *string,
237 ns_printer_t *printer)
238 {
239 if (printer == NULL)
240 return (-1);
241
242 if (key == NULL) {
243 list_iterate((void **)printer->attributes, ns_kvp_destroy);
244 } else {
245 ns_kvp_t *kvp;
246
247 if (((kvp = list_locate((void **)printer->attributes,
248 (COMP_T)ns_kvp_match_key, (void *)key)) == NULL) &&
249 ((kvp = calloc(1, sizeof (*kvp))) != NULL)) {
250 kvp->key = strdup(key);
251 printer->attributes = (ns_kvp_t **)
252 list_append((void **)printer->attributes, kvp);
253 }
254 if (string != NULL)
255 kvp->value = strdup(string);
256 else
257 kvp->value = NULL;
258 }
259
260 return (0);
261 }
262