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