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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/syscall.h> 29 #include <stdlib.h> 30 #include <stdio.h> 31 #include <strings.h> 32 #include <unistd.h> 33 #include <errno.h> 34 #include <libintl.h> 35 #include <libnvpair.h> 36 #include <thread.h> 37 #include <synch.h> 38 39 #include "libcpc.h" 40 #include "libcpc_impl.h" 41 42 /* 43 * Pack a request set into a buffer using libnvpair. Size of buffer is returned 44 * in buflen. 45 */ 46 char * 47 __cpc_pack_set(cpc_set_t *set, uint_t flags, size_t *buflen) 48 { 49 cpc_request_t *req; 50 nvlist_t *setlist, **reqlist; 51 size_t packsize = 0; 52 char *buf = NULL; 53 int i; 54 int j; 55 56 if (nvlist_alloc(&setlist, 0, 0) == ENOMEM) { 57 errno = ENOMEM; 58 return (NULL); 59 } 60 61 if ((reqlist = (nvlist_t **)malloc(set->cs_nreqs * sizeof (*reqlist))) 62 == NULL) { 63 nvlist_free(setlist); 64 errno = ENOMEM; 65 return (NULL); 66 } 67 68 bzero((void *)reqlist, set->cs_nreqs * sizeof (*reqlist)); 69 70 i = 0; 71 for (req = set->cs_request; req != NULL; req = req->cr_next) { 72 if (nvlist_alloc(&reqlist[i], 0, 0) == ENOMEM) 73 goto nomem; 74 75 if (nvlist_add_string(reqlist[i], "cr_event", 76 req->cr_event) != 0) 77 goto nomem; 78 if (nvlist_add_uint64(reqlist[i], "cr_preset", 79 req->cr_preset) != 0) 80 goto nomem; 81 if (nvlist_add_uint32(reqlist[i], "cr_flags", 82 req->cr_flags) != 0) 83 goto nomem; 84 if (nvlist_add_uint32(reqlist[i], "cr_index", 85 req->cr_index) != 0) 86 goto nomem; 87 88 if (req->cr_nattrs != 0) { 89 nvlist_t *attrs; 90 91 if (nvlist_alloc(&attrs, NV_UNIQUE_NAME, 0) == ENOMEM) 92 goto nomem; 93 94 for (j = 0; j < req->cr_nattrs; j++) { 95 if (nvlist_add_uint64(attrs, 96 req->cr_attr[j].ka_name, 97 req->cr_attr[j].ka_val) != 0) { 98 nvlist_free(attrs); 99 goto nomem; 100 } 101 } 102 103 if (nvlist_add_nvlist(reqlist[i], "cr_attr", 104 attrs) != 0) { 105 nvlist_free(attrs); 106 goto nomem; 107 } 108 109 nvlist_free(attrs); 110 } 111 i++; 112 } 113 114 if (nvlist_add_nvlist_array(setlist, "reqs", reqlist, 115 set->cs_nreqs) != 0) 116 goto nomem; 117 118 if (nvlist_add_uint32(setlist, "flags", flags) != 0) 119 goto nomem; 120 121 if (nvlist_pack(setlist, &buf, &packsize, NV_ENCODE_NATIVE, 122 0) != 0) 123 goto nomem; 124 125 for (i = 0; i < set->cs_nreqs; i++) 126 nvlist_free(reqlist[i]); 127 128 nvlist_free(setlist); 129 free(reqlist); 130 131 *buflen = packsize; 132 return (buf); 133 134 nomem: 135 for (i = 0; i < set->cs_nreqs; i++) { 136 if (reqlist[i] != 0) 137 nvlist_free(reqlist[i]); 138 } 139 nvlist_free(setlist); 140 free(reqlist); 141 errno = ENOMEM; 142 return (NULL); 143 } 144 145 cpc_strhash_t * 146 __cpc_strhash_alloc(void) 147 { 148 cpc_strhash_t *p; 149 150 if ((p = malloc(sizeof (cpc_strhash_t))) == NULL) 151 return (NULL); 152 153 p->str = ""; 154 p->cur = NULL; 155 p->next = NULL; 156 157 return (p); 158 } 159 160 void 161 __cpc_strhash_free(cpc_strhash_t *hash) 162 { 163 cpc_strhash_t *p = hash, *f; 164 165 while (p != NULL) { 166 f = p; 167 p = p->next; 168 free(f); 169 } 170 } 171 172 /* 173 * Insert a new key into the hash table. 174 * 175 * Returns 0 if key was unique and insert successful. 176 * 177 * Returns 1 if key was already in table and no insert took place. 178 * 179 * Returns -1 if out of memory. 180 */ 181 int 182 __cpc_strhash_add(cpc_strhash_t *hash, char *key) 183 { 184 cpc_strhash_t *p, *tmp; 185 186 for (p = hash; p != NULL; p = p->next) { 187 if (strcmp(p->str, key) == 0) 188 return (1); 189 } 190 191 if ((p = malloc(sizeof (*p))) == NULL) 192 return (-1); 193 194 p->str = key; 195 tmp = hash->next; 196 hash->next = p; 197 p->next = tmp; 198 /* 199 * The head node's current pointer must stay pointed at the first 200 * real node. We just inserted at the head. 201 */ 202 hash->cur = p; 203 204 return (0); 205 } 206 207 char * 208 __cpc_strhash_next(cpc_strhash_t *hash) 209 { 210 cpc_strhash_t *p; 211 212 if (hash->cur != NULL) { 213 p = hash->cur; 214 hash->cur = hash->cur->next; 215 return (p->str); 216 } 217 218 return (NULL); 219 } 220