17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5a126dc1aSTony Nguyen * Common Development and Distribution License (the "License").
6a126dc1aSTony Nguyen * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
224e1c7343SJan Friedel * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate */
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <strings.h>
297c478bd9Sstevel@tonic-gate #include <secdb.h>
307c478bd9Sstevel@tonic-gate #include <ctype.h>
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate /* From libnsl */
337c478bd9Sstevel@tonic-gate extern char *_strdup_null(char *);
347c478bd9Sstevel@tonic-gate extern char *_strtok_escape(char *, char *, char **);
357c478bd9Sstevel@tonic-gate extern char *_strpbrk_escape(char *, char *);
367c478bd9Sstevel@tonic-gate extern char *_unescape(char *, char *);
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate char *_do_unescape(char *);
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate * kva_match(): Given a key-value array and a key, return a pointer to the
437c478bd9Sstevel@tonic-gate * value that matches the key.
447c478bd9Sstevel@tonic-gate */
457c478bd9Sstevel@tonic-gate char *
kva_match(kva_t * kva,char * key)467c478bd9Sstevel@tonic-gate kva_match(kva_t *kva, char *key)
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate int i;
497c478bd9Sstevel@tonic-gate kv_t *data;
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate if (kva == NULL || key == NULL) {
52*f8994074SJan Friedel return (NULL);
537c478bd9Sstevel@tonic-gate }
547c478bd9Sstevel@tonic-gate data = kva->data;
557c478bd9Sstevel@tonic-gate for (i = 0; i < kva->length; i++) {
567c478bd9Sstevel@tonic-gate if (strcmp(data[i].key, key) == 0) {
577c478bd9Sstevel@tonic-gate return (data[i].value);
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate }
607c478bd9Sstevel@tonic-gate
61*f8994074SJan Friedel return (NULL);
627c478bd9Sstevel@tonic-gate }
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate /*
657c478bd9Sstevel@tonic-gate * _kva_free(): Free up memory.
667c478bd9Sstevel@tonic-gate */
677c478bd9Sstevel@tonic-gate void
_kva_free(kva_t * kva)687c478bd9Sstevel@tonic-gate _kva_free(kva_t *kva)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate int i;
717c478bd9Sstevel@tonic-gate kv_t *data;
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate if (kva == NULL) {
747c478bd9Sstevel@tonic-gate return;
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate data = kva->data;
777c478bd9Sstevel@tonic-gate for (i = 0; i < kva->length; i++) {
787c478bd9Sstevel@tonic-gate if (data[i].key != NULL) {
797c478bd9Sstevel@tonic-gate free(data[i].key);
807c478bd9Sstevel@tonic-gate data[i].key = NULL;
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate if (data[i].value != NULL) {
837c478bd9Sstevel@tonic-gate free(data[i].value);
847c478bd9Sstevel@tonic-gate data[i].value = NULL;
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate free(kva->data);
887c478bd9Sstevel@tonic-gate free(kva);
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate /*
92*f8994074SJan Friedel * _kva_free_value(): Free up memory (value) for all the occurrences of
93*f8994074SJan Friedel * the given key.
94*f8994074SJan Friedel */
95*f8994074SJan Friedel void
_kva_free_value(kva_t * kva,char * key)96*f8994074SJan Friedel _kva_free_value(kva_t *kva, char *key)
97*f8994074SJan Friedel {
98*f8994074SJan Friedel int ctr;
99*f8994074SJan Friedel kv_t *data;
100*f8994074SJan Friedel
101*f8994074SJan Friedel if (kva == NULL) {
102*f8994074SJan Friedel return;
103*f8994074SJan Friedel }
104*f8994074SJan Friedel
105*f8994074SJan Friedel ctr = kva->length;
106*f8994074SJan Friedel data = kva->data;
107*f8994074SJan Friedel
108*f8994074SJan Friedel while (ctr--) {
109*f8994074SJan Friedel if (strcmp(data->key, key) == 0 && data->value != NULL) {
110*f8994074SJan Friedel free(data->value);
111*f8994074SJan Friedel data->value = NULL;
112*f8994074SJan Friedel }
113*f8994074SJan Friedel data++;
114*f8994074SJan Friedel }
115*f8994074SJan Friedel }
116*f8994074SJan Friedel
117*f8994074SJan Friedel /*
1187c478bd9Sstevel@tonic-gate * new_kva(): Allocate a key-value array.
1197c478bd9Sstevel@tonic-gate */
1207c478bd9Sstevel@tonic-gate kva_t *
_new_kva(int size)1217c478bd9Sstevel@tonic-gate _new_kva(int size)
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate kva_t *new_kva;
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate if ((new_kva = (kva_t *)calloc(1, sizeof (kva_t))) == NULL) {
126*f8994074SJan Friedel return (NULL);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate if ((new_kva->data = (kv_t *)calloc(1, (size*sizeof (kv_t)))) == NULL) {
1297c478bd9Sstevel@tonic-gate free(new_kva);
130*f8994074SJan Friedel return (NULL);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate return (new_kva);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate /*
1377c478bd9Sstevel@tonic-gate * _str2kva(): Given a string (s) of key-value pairs, separated by delimeter
1387c478bd9Sstevel@tonic-gate * (del), place the values into the key value array (nkva).
1397c478bd9Sstevel@tonic-gate */
1407c478bd9Sstevel@tonic-gate kva_t *
_str2kva(char * s,char * ass,char * del)1417c478bd9Sstevel@tonic-gate _str2kva(char *s, char *ass, char *del)
1427c478bd9Sstevel@tonic-gate {
1437c478bd9Sstevel@tonic-gate int n = 0;
1447c478bd9Sstevel@tonic-gate int m;
1457c478bd9Sstevel@tonic-gate int size = KV_ADD_KEYS;
1467c478bd9Sstevel@tonic-gate char *buf;
1477c478bd9Sstevel@tonic-gate char *p;
1487c478bd9Sstevel@tonic-gate char *pair;
1497c478bd9Sstevel@tonic-gate char *key;
1507c478bd9Sstevel@tonic-gate char *last_pair;
1517c478bd9Sstevel@tonic-gate char *last_key;
1527c478bd9Sstevel@tonic-gate kv_t *data;
1537c478bd9Sstevel@tonic-gate kva_t *nkva;
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate if (s == NULL ||
1567c478bd9Sstevel@tonic-gate ass == NULL ||
1577c478bd9Sstevel@tonic-gate del == NULL ||
1587c478bd9Sstevel@tonic-gate *s == '\0' ||
1597c478bd9Sstevel@tonic-gate *s == '\n' ||
1607c478bd9Sstevel@tonic-gate (strlen(s) <= 1)) {
161*f8994074SJan Friedel return (NULL);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate p = s;
1647c478bd9Sstevel@tonic-gate while ((p = _strpbrk_escape(p, ass)) != NULL) {
1657c478bd9Sstevel@tonic-gate n++;
1667c478bd9Sstevel@tonic-gate p++;
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate if (n > size) {
1697c478bd9Sstevel@tonic-gate m = n/size;
1707c478bd9Sstevel@tonic-gate if (n%size) {
1717c478bd9Sstevel@tonic-gate ++m;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate size = m * KV_ADD_KEYS;
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate if ((nkva = _new_kva(size)) == NULL) {
176*f8994074SJan Friedel return (NULL);
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate data = nkva->data;
1797c478bd9Sstevel@tonic-gate nkva->length = 0;
1807c478bd9Sstevel@tonic-gate if ((buf = strdup(s)) == NULL) {
181*f8994074SJan Friedel return (NULL);
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate pair = _strtok_escape(buf, del, &last_pair);
1847c478bd9Sstevel@tonic-gate do {
1857c478bd9Sstevel@tonic-gate key = _strtok_escape(pair, ass, &last_key);
1867c478bd9Sstevel@tonic-gate if (key != NULL) {
1877c478bd9Sstevel@tonic-gate data[nkva->length].key = _do_unescape(key);
1887c478bd9Sstevel@tonic-gate data[nkva->length].value = _do_unescape(last_key);
1897c478bd9Sstevel@tonic-gate nkva->length++;
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate } while ((pair = _strtok_escape(NULL, del, &last_pair)) != NULL);
1927c478bd9Sstevel@tonic-gate free(buf);
1937c478bd9Sstevel@tonic-gate return (nkva);
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate /*
1977c478bd9Sstevel@tonic-gate * _kva2str(): Given an array of key-value pairs, place them into a string
1987c478bd9Sstevel@tonic-gate * (buf). Use delimeter (del) to separate pairs. Use assignment character
1997c478bd9Sstevel@tonic-gate * (ass) to separate keys and values.
2007c478bd9Sstevel@tonic-gate *
201*f8994074SJan Friedel * Return Values: 0 Success 1 Buffer too small
2027c478bd9Sstevel@tonic-gate */
2037c478bd9Sstevel@tonic-gate int
_kva2str(kva_t * kva,char * buf,int buflen,char * ass,char * del)2047c478bd9Sstevel@tonic-gate _kva2str(kva_t *kva, char *buf, int buflen, char *ass, char *del)
2057c478bd9Sstevel@tonic-gate {
2067c478bd9Sstevel@tonic-gate int i;
207*f8994074SJan Friedel int len;
208*f8994074SJan Friedel int off = 0;
2097c478bd9Sstevel@tonic-gate kv_t *data;
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate if (kva == NULL) {
2127c478bd9Sstevel@tonic-gate return (0);
2137c478bd9Sstevel@tonic-gate }
214*f8994074SJan Friedel
215*f8994074SJan Friedel buf[0] = '\0';
2167c478bd9Sstevel@tonic-gate data = kva->data;
217*f8994074SJan Friedel
2187c478bd9Sstevel@tonic-gate for (i = 0; i < kva->length; i++) {
2197c478bd9Sstevel@tonic-gate if (data[i].value != NULL) {
220*f8994074SJan Friedel len = snprintf(buf + off, buflen - off, "%s%s%s%s",
221*f8994074SJan Friedel data[i].key, ass, data[i].value, del);
222*f8994074SJan Friedel if (len < 0 || len + off >= buflen) {
2237c478bd9Sstevel@tonic-gate return (1);
2247c478bd9Sstevel@tonic-gate }
225*f8994074SJan Friedel off += len;
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate }
228*f8994074SJan Friedel
2297c478bd9Sstevel@tonic-gate return (0);
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate int
_insert2kva(kva_t * kva,char * key,char * value)2337c478bd9Sstevel@tonic-gate _insert2kva(kva_t *kva, char *key, char *value)
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate int i;
2367c478bd9Sstevel@tonic-gate kv_t *data;
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate if (kva == NULL) {
2397c478bd9Sstevel@tonic-gate return (0);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate data = kva->data;
2427c478bd9Sstevel@tonic-gate for (i = 0; i < kva->length; i++) {
2437c478bd9Sstevel@tonic-gate if (strcmp(data[i].key, key) == 0) {
2447c478bd9Sstevel@tonic-gate if (data[i].value != NULL)
2457c478bd9Sstevel@tonic-gate free(data[i].value);
2467c478bd9Sstevel@tonic-gate data[i].value = _strdup_null(value);
2477c478bd9Sstevel@tonic-gate return (0);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate return (1);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate kva_t *
_kva_dup(kva_t * old_kva)2547c478bd9Sstevel@tonic-gate _kva_dup(kva_t *old_kva)
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate int i;
2577c478bd9Sstevel@tonic-gate int size;
2587c478bd9Sstevel@tonic-gate kv_t *old_data;
2597c478bd9Sstevel@tonic-gate kv_t *new_data;
260*f8994074SJan Friedel kva_t *nkva = NULL;
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate if (old_kva == NULL) {
263*f8994074SJan Friedel return (NULL);
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate old_data = old_kva->data;
2667c478bd9Sstevel@tonic-gate size = old_kva->length;
2677c478bd9Sstevel@tonic-gate if ((nkva = _new_kva(size)) == NULL) {
268*f8994074SJan Friedel return (NULL);
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate new_data = nkva->data;
2717c478bd9Sstevel@tonic-gate nkva->length = old_kva->length;
272c94b466cSJan Friedel for (i = 0; i < nkva->length; i++) {
2737c478bd9Sstevel@tonic-gate new_data[i].key = _strdup_null(old_data[i].key);
2747c478bd9Sstevel@tonic-gate new_data[i].value = _strdup_null(old_data[i].value);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate
2777c478bd9Sstevel@tonic-gate return (nkva);
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate
2807c478bd9Sstevel@tonic-gate static void
strip_spaces(char ** valuep)2817c478bd9Sstevel@tonic-gate strip_spaces(char **valuep)
2827c478bd9Sstevel@tonic-gate {
2837c478bd9Sstevel@tonic-gate char *p, *start;
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate /* Find first non-white space character and return pointer to it */
2867c478bd9Sstevel@tonic-gate for (p = *valuep; *p != '\0' && isspace((unsigned char)*p); p++)
2877c478bd9Sstevel@tonic-gate ;
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate *valuep = start = p;
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate if (*p == '\0')
2927c478bd9Sstevel@tonic-gate return;
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate p = p + strlen(p) - 1;
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate /* Remove trailing spaces */
2977c478bd9Sstevel@tonic-gate while (p > start && isspace((unsigned char)*p))
2987c478bd9Sstevel@tonic-gate p--;
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate p[1] = '\0';
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate char *
_do_unescape(char * src)3047c478bd9Sstevel@tonic-gate _do_unescape(char *src)
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate char *tmp = NULL;
3077c478bd9Sstevel@tonic-gate char *dst = NULL;
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate if (src == NULL) {
3107c478bd9Sstevel@tonic-gate dst = _strdup_null(src);
3117c478bd9Sstevel@tonic-gate } else {
3127c478bd9Sstevel@tonic-gate strip_spaces(&src);
3137c478bd9Sstevel@tonic-gate tmp = _unescape(src, "=;:,\\");
3147c478bd9Sstevel@tonic-gate dst = (tmp == NULL) ? _strdup_null(src) : tmp;
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate return (dst);
3187c478bd9Sstevel@tonic-gate }
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate * Some utilities for handling comma-separated lists.
3237c478bd9Sstevel@tonic-gate */
3247c478bd9Sstevel@tonic-gate char *
_argv_to_csl(char ** strings)3257c478bd9Sstevel@tonic-gate _argv_to_csl(char **strings)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate int len = 0;
3287c478bd9Sstevel@tonic-gate int i = 0;
329*f8994074SJan Friedel char *newstr = NULL;
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate if (strings == NULL)
332*f8994074SJan Friedel return (NULL);
3337c478bd9Sstevel@tonic-gate for (i = 0; strings[i] != NULL; i++) {
3347c478bd9Sstevel@tonic-gate len += strlen(strings[i]) + 1;
3357c478bd9Sstevel@tonic-gate }
336a126dc1aSTony Nguyen if ((len > 0) && ((newstr = (char *)malloc(len + 1)) != NULL)) {
3377c478bd9Sstevel@tonic-gate (void) memset(newstr, 0, len);
3387c478bd9Sstevel@tonic-gate for (i = 0; strings[i] != NULL; i++) {
3397c478bd9Sstevel@tonic-gate (void) strcat(newstr, strings[i]);
3407c478bd9Sstevel@tonic-gate (void) strcat(newstr, ",");
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate newstr[len-1] = NULL;
3437c478bd9Sstevel@tonic-gate return (newstr);
344a126dc1aSTony Nguyen } else
345*f8994074SJan Friedel return (NULL);
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate char **
_csl_to_argv(char * csl)3507c478bd9Sstevel@tonic-gate _csl_to_argv(char *csl)
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate int len = 0;
3537c478bd9Sstevel@tonic-gate int ncommas = 0;
3547c478bd9Sstevel@tonic-gate int i = 0;
355*f8994074SJan Friedel char **spc = NULL;
356*f8994074SJan Friedel char *copy = NULL;
3577c478bd9Sstevel@tonic-gate char *pc;
358*f8994074SJan Friedel char *lasts = NULL;
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate len = strlen(csl);
3617c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) {
3627c478bd9Sstevel@tonic-gate if (csl[i] == ',')
3637c478bd9Sstevel@tonic-gate ncommas++;
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate if ((spc = (char **)malloc((ncommas + 2) * sizeof (char *))) == NULL) {
366*f8994074SJan Friedel return (NULL);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate copy = strdup(csl);
3697c478bd9Sstevel@tonic-gate for (pc = strtok_r(copy, ",", &lasts), i = 0; pc != NULL;
3707c478bd9Sstevel@tonic-gate pc = strtok_r(NULL, ",", &lasts), i++) {
3717c478bd9Sstevel@tonic-gate spc[i] = strdup(pc);
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate spc[i] = NULL;
3747c478bd9Sstevel@tonic-gate free(copy);
3757c478bd9Sstevel@tonic-gate return (spc);
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate void
_free_argv(char ** p_argv)3807c478bd9Sstevel@tonic-gate _free_argv(char **p_argv)
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate char **p_a;
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate for (p_a = p_argv; *p_a != NULL; p_a++)
3857c478bd9Sstevel@tonic-gate free(*p_a);
3867c478bd9Sstevel@tonic-gate free(p_argv);
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate #ifdef DEBUG
3917c478bd9Sstevel@tonic-gate void
print_kva(kva_t * kva)3927c478bd9Sstevel@tonic-gate print_kva(kva_t *kva)
3937c478bd9Sstevel@tonic-gate {
3947c478bd9Sstevel@tonic-gate int i;
3957c478bd9Sstevel@tonic-gate kv_t *data;
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate if (kva == NULL) {
398*f8994074SJan Friedel (void) printf(" (empty)\n");
3997c478bd9Sstevel@tonic-gate return;
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate data = kva->data;
4027c478bd9Sstevel@tonic-gate for (i = 0; i < kva->length; i++) {
403*f8994074SJan Friedel (void) printf(" %s = %s\n",
404*f8994074SJan Friedel data[i].key != NULL ? data[i].key : "NULL",
405*f8994074SJan Friedel data[i].value != NULL ? data[i].value : "NULL");
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate #endif /* DEBUG */
409