xref: /illumos-gate/usr/src/lib/print/libprint/common/ns_cmn_kvp.c (revision ef2333d135d7eeabe888ac20be8a501a394db591)
1355b4669Sjacobs /*
2355b4669Sjacobs  * CDDL HEADER START
3355b4669Sjacobs  *
4355b4669Sjacobs  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
7355b4669Sjacobs  *
8355b4669Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9355b4669Sjacobs  * or http://www.opensolaris.org/os/licensing.
10355b4669Sjacobs  * See the License for the specific language governing permissions
11355b4669Sjacobs  * and limitations under the License.
12355b4669Sjacobs  *
13355b4669Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14355b4669Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15355b4669Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16355b4669Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17355b4669Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18355b4669Sjacobs  *
19355b4669Sjacobs  * CDDL HEADER END
20355b4669Sjacobs  */
21355b4669Sjacobs /*
22355b4669Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23355b4669Sjacobs  * Use is subject to license terms.
24355b4669Sjacobs  */
25355b4669Sjacobs 
26355b4669Sjacobs /*LINTLIBRARY*/
27355b4669Sjacobs 
28355b4669Sjacobs #include <stdio.h>
29355b4669Sjacobs #include <stdlib.h>
30355b4669Sjacobs #include <unistd.h>
31355b4669Sjacobs #include <sys/types.h>
32355b4669Sjacobs #include <stdarg.h>
33355b4669Sjacobs #include <string.h>
34355b4669Sjacobs 
35355b4669Sjacobs #include <ns.h>
36355b4669Sjacobs #include <list.h>
37355b4669Sjacobs 
38355b4669Sjacobs /*
39355b4669Sjacobs  *	Commonly Used routines...
40355b4669Sjacobs  */
41355b4669Sjacobs 
42355b4669Sjacobs /*
43355b4669Sjacobs  * FUNCTION:
44355b4669Sjacobs  *	kvp_create(const char *key, const void *value)
45355b4669Sjacobs  * INPUT(S):
46355b4669Sjacobs  *	const char *key
47355b4669Sjacobs  *		- key for key/value pair
48355b4669Sjacobs  *	const void *value
49355b4669Sjacobs  *		- value for key/value pair
50355b4669Sjacobs  * OUTPUT(S):
51355b4669Sjacobs  *	ns_kvp_t * (return value)
52355b4669Sjacobs  *		- pointer to structure containing the key/value pair
53355b4669Sjacobs  * DESCRIPTION:
54355b4669Sjacobs  */
55355b4669Sjacobs ns_kvp_t *
ns_kvp_create(const char * key,const char * value)56355b4669Sjacobs ns_kvp_create(const char *key, const char *value)
57355b4669Sjacobs {
58355b4669Sjacobs 	ns_kvp_t *kvp;
59355b4669Sjacobs 
60355b4669Sjacobs 	if ((kvp = calloc(1, sizeof (*kvp))) != NULL) {
61355b4669Sjacobs 		kvp->key = strdup(key);
62355b4669Sjacobs 		kvp->value = (char *)value;
63355b4669Sjacobs 	}
64355b4669Sjacobs 	return (kvp);
65355b4669Sjacobs }
66355b4669Sjacobs 
67*ef2333d1SToomas Soome int
ns_kvp_destroy(void * arg,va_list arg1 __unused)68*ef2333d1SToomas Soome ns_kvp_destroy(void *arg, va_list arg1 __unused)
69355b4669Sjacobs {
70*ef2333d1SToomas Soome 	ns_kvp_t *kvp = arg;
71*ef2333d1SToomas Soome 
72355b4669Sjacobs 	if (kvp != NULL) {
73355b4669Sjacobs 		if (kvp->key != NULL)
74355b4669Sjacobs 			free(kvp->key);
75355b4669Sjacobs 		if (kvp->value != NULL)
76355b4669Sjacobs 			free(kvp->value);
77355b4669Sjacobs 		free(kvp);
78355b4669Sjacobs 	}
79*ef2333d1SToomas Soome 	return (0);
80355b4669Sjacobs }
81355b4669Sjacobs 
82355b4669Sjacobs 
83355b4669Sjacobs 
84355b4669Sjacobs 
85355b4669Sjacobs /*
86355b4669Sjacobs  * FUNCTION:
87355b4669Sjacobs  *	ns_kvp_match_key(const ns_kvp_t *kvp, const char *key)
88355b4669Sjacobs  * INPUT(S):
89355b4669Sjacobs  *	const ns_kvp_t *kvp
90355b4669Sjacobs  *		- key/value pair to check
91355b4669Sjacobs  *	const char *key
92355b4669Sjacobs  *		- key for matching
93355b4669Sjacobs  * OUTPUT(S):
94355b4669Sjacobs  *	int (return value)
95355b4669Sjacobs  *		- 0 if matched
96355b4669Sjacobs  * DESCRIPTION:
97355b4669Sjacobs  */
98355b4669Sjacobs static int
ns_kvp_match_key(const ns_kvp_t * kvp,char * key)99355b4669Sjacobs ns_kvp_match_key(const ns_kvp_t *kvp, char *key)
100355b4669Sjacobs {
101355b4669Sjacobs 	if ((kvp != NULL) && (kvp->key != NULL) && (key != NULL))
102355b4669Sjacobs 		return (strcmp(kvp->key, key));
103355b4669Sjacobs 	return (-1);
104355b4669Sjacobs }
105355b4669Sjacobs 
106355b4669Sjacobs 
107355b4669Sjacobs /*
108355b4669Sjacobs  * FUNCTION:
109355b4669Sjacobs  *	ns_r_get_value(const char *key, const ns_printer_t *printer)
110355b4669Sjacobs  * INPUT(S):
111355b4669Sjacobs  *	const char *key
112355b4669Sjacobs  *		- key for matching
113355b4669Sjacobs  *	const ns_printer_t *printer
114355b4669Sjacobs  *		- printer to glean this from
115355b4669Sjacobs  * OUTPUT(S):
116355b4669Sjacobs  *	char * (return value)
117355b4669Sjacobs  *		- NULL, if not matched
118355b4669Sjacobs  * DESCRIPTION:
119355b4669Sjacobs  */
120355b4669Sjacobs static void *
ns_r_get_value(const char * key,const ns_printer_t * printer,int level)121355b4669Sjacobs ns_r_get_value(const char *key, const ns_printer_t *printer, int level)
122355b4669Sjacobs {
123355b4669Sjacobs 	ns_kvp_t *kvp, **attrs;
124355b4669Sjacobs 
125355b4669Sjacobs 	if ((key == NULL) || (printer == NULL) ||
126355b4669Sjacobs 	    (printer->attributes == NULL))
127355b4669Sjacobs 		return (NULL);
128355b4669Sjacobs 
129355b4669Sjacobs 	if (level++ == 16)
130355b4669Sjacobs 		return (NULL);
131355b4669Sjacobs 
132355b4669Sjacobs 	/* find it right here */
133355b4669Sjacobs 	if ((kvp = list_locate((void **)printer->attributes,
134355b4669Sjacobs 	    (COMP_T)ns_kvp_match_key, (void *)key)) != NULL) {
135355b4669Sjacobs 		void *value = string_to_value(key, kvp->value);
136355b4669Sjacobs 
137355b4669Sjacobs 		/* fill in an empty printer for a bsdaddr */
138355b4669Sjacobs 		if (strcmp(key, NS_KEY_BSDADDR) == 0) {
139355b4669Sjacobs 			ns_bsd_addr_t *addr = value;
140355b4669Sjacobs 
141355b4669Sjacobs 			if (addr->printer == NULL)
142355b4669Sjacobs 				addr->printer = strdup(printer->name);
143355b4669Sjacobs 		}
144355b4669Sjacobs 		return (value);
145355b4669Sjacobs 	}
146355b4669Sjacobs 
147355b4669Sjacobs 	/* find it in a child */
148355b4669Sjacobs 	for (attrs = printer->attributes; attrs != NULL && *attrs != NULL;
149355b4669Sjacobs 	    attrs++) {
150355b4669Sjacobs 		void *value = NULL;
151355b4669Sjacobs 
152355b4669Sjacobs 		if ((strcmp((*attrs)->key, NS_KEY_ALL) == 0) ||
153355b4669Sjacobs 		    (strcmp((*attrs)->key, NS_KEY_GROUP) == 0)) {
154355b4669Sjacobs 			char **printers;
155355b4669Sjacobs 
156355b4669Sjacobs 			for (printers = string_to_value((*attrs)->key,
157355b4669Sjacobs 			    (*attrs)->value);
158355b4669Sjacobs 			    printers != NULL && *printers != NULL; printers++) {
159355b4669Sjacobs 				ns_printer_t *printer =
160355b4669Sjacobs 				    ns_printer_get_name(*printers, NULL);
161355b4669Sjacobs 
162*ef2333d1SToomas Soome 				value = ns_r_get_value(key, printer, level);
163*ef2333d1SToomas Soome 				if (value != NULL)
164355b4669Sjacobs 					return (value);
165355b4669Sjacobs 				ns_printer_destroy(printer);
166355b4669Sjacobs 			}
167355b4669Sjacobs 		} else if (strcmp((*attrs)->key, NS_KEY_LIST) == 0) {
168355b4669Sjacobs 			ns_printer_t **printers;
169355b4669Sjacobs 
170355b4669Sjacobs 			for (printers = string_to_value((*attrs)->key,
171355b4669Sjacobs 			    (*attrs)->value);
172355b4669Sjacobs 			    printers != NULL && *printers != NULL; printers++) {
173*ef2333d1SToomas Soome 				value = ns_r_get_value(key, *printers, level);
174*ef2333d1SToomas Soome 				if (value != NULL)
175355b4669Sjacobs 					return (value);
176355b4669Sjacobs 			}
177355b4669Sjacobs 		} else if (strcmp((*attrs)->key, NS_KEY_USE) == 0) {
178355b4669Sjacobs 			char *string = NULL;
179355b4669Sjacobs 			ns_printer_t *printer =
180355b4669Sjacobs 			    ns_printer_get_name((*attrs)->value, NULL);
181*ef2333d1SToomas Soome 			value = ns_r_get_value(key, printer, level);
182*ef2333d1SToomas Soome 			if (value != NULL)
183355b4669Sjacobs 				string = value_to_string(string, value);
184355b4669Sjacobs 			if (string != NULL)
185355b4669Sjacobs 				value = string_to_value(key, string);
186355b4669Sjacobs 			ns_printer_destroy(printer);
187355b4669Sjacobs 		}
188355b4669Sjacobs 
189355b4669Sjacobs 		if (value != NULL)
190355b4669Sjacobs 			return (value);
191355b4669Sjacobs 	}
192355b4669Sjacobs 
193355b4669Sjacobs 	return (NULL);
194355b4669Sjacobs }
195355b4669Sjacobs 
196355b4669Sjacobs 
197355b4669Sjacobs /*
198355b4669Sjacobs  * ns_get_value() gets the value of the passed in attribute from the passed
199355b4669Sjacobs  * in printer structure.  The value is returned in a converted format.
200355b4669Sjacobs  */
201355b4669Sjacobs void *
ns_get_value(const char * key,const ns_printer_t * printer)202355b4669Sjacobs ns_get_value(const char *key, const ns_printer_t *printer)
203355b4669Sjacobs {
204355b4669Sjacobs 	return (ns_r_get_value(key, printer, 0));
205355b4669Sjacobs }
206355b4669Sjacobs 
207355b4669Sjacobs 
208355b4669Sjacobs /*
209355b4669Sjacobs  * ns_get_value_string() gets the value of the key passed in from the
210355b4669Sjacobs  * printer structure passed in.  The results is an ascii string.
211355b4669Sjacobs  */
212355b4669Sjacobs char *
ns_get_value_string(const char * key,const ns_printer_t * printer)213355b4669Sjacobs ns_get_value_string(const char *key, const ns_printer_t *printer)
214355b4669Sjacobs {
215355b4669Sjacobs 	return ((char *)value_to_string(key, ns_get_value(key, printer)));
216355b4669Sjacobs }
217355b4669Sjacobs 
218355b4669Sjacobs 
219355b4669Sjacobs /*
220355b4669Sjacobs  * ns_set_value() sets the passed in kvp in the passed in printer structure,
221355b4669Sjacobs  * This is done by converting the value to a string first.
222355b4669Sjacobs  */
223355b4669Sjacobs int
ns_set_value(const char * key,const void * value,ns_printer_t * printer)224355b4669Sjacobs ns_set_value(const char *key, const void *value, ns_printer_t *printer)
225355b4669Sjacobs {
226355b4669Sjacobs 	return (ns_set_value_from_string(key,
227355b4669Sjacobs 	    value_to_string(key, (void *)value), printer));
228355b4669Sjacobs }
229355b4669Sjacobs 
230355b4669Sjacobs 
231355b4669Sjacobs /*
232355b4669Sjacobs  * ns_set_value_from_string() sets the passed in kvp in the passed in printer
233355b4669Sjacobs  * structure.
234355b4669Sjacobs  */
235355b4669Sjacobs int
ns_set_value_from_string(const char * key,const char * string,ns_printer_t * printer)236355b4669Sjacobs ns_set_value_from_string(const char *key, const char *string,
237355b4669Sjacobs     ns_printer_t *printer)
238355b4669Sjacobs {
239355b4669Sjacobs 	if (printer == NULL)
240355b4669Sjacobs 		return (-1);
241355b4669Sjacobs 
242*ef2333d1SToomas Soome 	if (key == NULL) {
243*ef2333d1SToomas Soome 		list_iterate((void **)printer->attributes, ns_kvp_destroy);
244*ef2333d1SToomas Soome 	} else {
245355b4669Sjacobs 		ns_kvp_t *kvp;
246355b4669Sjacobs 
247355b4669Sjacobs 		if (((kvp = list_locate((void **)printer->attributes,
248*ef2333d1SToomas Soome 		    (COMP_T)ns_kvp_match_key, (void *)key)) == NULL) &&
249355b4669Sjacobs 		    ((kvp = calloc(1, sizeof (*kvp))) != NULL)) {
250355b4669Sjacobs 			kvp->key = strdup(key);
251355b4669Sjacobs 			printer->attributes = (ns_kvp_t **)
252355b4669Sjacobs 			    list_append((void **)printer->attributes, kvp);
253355b4669Sjacobs 		}
254355b4669Sjacobs 		if (string != NULL)
255355b4669Sjacobs 			kvp->value = strdup(string);
256355b4669Sjacobs 		else
257355b4669Sjacobs 			kvp->value = NULL;
258355b4669Sjacobs 	}
259355b4669Sjacobs 
260355b4669Sjacobs 	return (0);
261355b4669Sjacobs }
262