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 */
55ns_kvp_t *
56ns_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
67int
68ns_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 */
98static int
99ns_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 */
120static void *
121ns_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 */
201void *
202ns_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 */
212char *
213ns_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 */
223int
224ns_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 */
235int
236ns_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