9698 pkcs11 C_Digest() is too restrictive in input
[unleashed.git] / usr / src / lib / libunistat / common / spcs_s_u.c
blobf5f946b31b03ed5c0068e05266d0230657ecd402
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * The SPCS status support user utilities
27 * See spcs_s_u.h and the docs subdirectory for functional spec
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <sys/types.h>
36 #include <locale.h>
37 #include <libintl.h>
38 #include <sys/unistat/spcs_s.h>
39 #include <sys/unistat/spcs_s_u.h>
40 #include <sys/unistat/spcs_s_impl.h>
41 #include <sys/unistat/spcs_errors.h>
42 #include <sys/unistat/spcs_etext.h>
43 #include <sys/unistat/spcs_etrinkets.h>
44 #include <sys/unistat/spcs_dtrinkets.h>
47 * Initialize ioctl status storage to "remove" any old status present
50 void
51 spcs_s_uinit(spcs_s_info_t ustatus)
53 spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)ustatus;
54 p->major = SPCS_S_MAJOR_REV;
55 p->minor = SPCS_S_MINOR_REV;
56 p->icount = 0;
57 p->scount = 0;
58 p->tcount = 0;
62 * Create and initialize local status. Call this prior to invoking
63 * an ioctl.
66 spcs_s_info_t
67 spcs_s_ucreate()
69 static int need_to_bind = 1;
70 spcs_s_pinfo_t *ustatus;
72 if (need_to_bind) {
73 (void) setlocale(LC_ALL, "");
74 (void) bindtextdomain("unistat", LIBUNISTAT_LOCALE);
75 need_to_bind = 0;
78 ustatus = (spcs_s_pinfo_t *)malloc(sizeof (spcs_s_pinfo_t));
79 spcs_s_uinit((spcs_s_info_t)ustatus);
81 return ((spcs_s_info_t)ustatus);
85 * Return the idata index of the last status code in the array (i.e.
86 * the "youngest" code present). The assumption is that the caller has
87 * checked to see that pcount is nonzero.
90 ISSTATIC int
91 last_code_idx(spcs_s_pinfo_t *p)
93 int last = 0;
94 int idx = 0;
96 while (idx < p->icount) {
97 last = idx;
98 idx += p->idata[idx].f.sup_count + 1;
100 return (last);
104 * Return a string with the module label and error message text or NULL
105 * if none left
108 char *
109 spcs_s_string(spcs_s_info_t ustatus, char *msg)
111 spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)ustatus;
112 int idx;
113 int sup;
114 int s;
115 char *format;
116 char *sp[SPCS_S_MAXSUPP];
117 char mtemp[SPCS_S_MAXLINE];
119 if (p->icount > 0) {
120 idx = last_code_idx(p);
121 strcpy(msg, module_names[p->idata[idx].f.module]);
122 strcat(msg, ": ");
123 sup = p->idata[idx].f.sup_count;
125 if (p->idata[idx].f.module)
127 * The gettext formal parameter is a const char*
128 * I guess the gettext creator couldn't imagine
129 * needing a variable string. If there is an underlying
130 * routine that can be called it should be used.
131 * otherwise there will be a compiler warning about this
132 * line FOREVER (TS).
134 format = (char *)dgettext("unistat",
135 SPCS_S_MSG[p->idata[idx].f.module]
136 [p->idata[idx].f.code]);
138 else
139 format = strerror(p->idata[idx].f.code);
142 * step across the status code to the first supplemental data
143 * descriptor.
146 idx += 1;
149 * Initialize the array with empty string pointers so we don't
150 * seg fault if there are actually fewer values than "%s"
151 * format descriptors.
153 for (s = 0; s < SPCS_S_MAXSUPP; s++)
154 sp[s] = "";
157 * Walk through the supplemental value descriptors and build
158 * an array of string pointers.
161 for (s = 0; s < sup; s++) {
162 sp[s] = (char *)(p->sdata + p->idata[idx+s].su.offset);
166 * Now format the message. The unused string pointers will be
167 * ignored.
168 * NOTE: Any change to SPCS_S_MAXSUPP requires a change to
169 * this sprintf.
172 sprintf(mtemp, format, sp[0], sp[1], sp[2], sp[3], sp[4], sp[5],
173 sp[6], sp[7]);
175 /* remove the code and its supplemental info */
177 p->icount -= (sup + 1);
179 return (strcat(msg, mtemp));
180 } else
181 return (NULL);
185 * Write status info
188 void
189 spcs_s_report(spcs_s_info_t ustatus, FILE *fd)
191 spcs_s_pinfo_t *p = (spcs_s_pinfo_t *)ustatus;
192 short saved_count = p->icount;
193 char msg[SPCS_S_MAXTEXT];
194 char *sp;
195 char *se;
196 int first_time = 1;
198 do {
199 if (sp = spcs_s_string(ustatus, msg))
200 fprintf(fd, "%s\n", sp);
201 else if (first_time && (errno > 0)) {
203 * This covers the case where Solaris aborted the
204 * operation or the ioctl service code got an EFAULT
205 * or something from copyin or couldn't allocate the
206 * kernel status structure. If errno > 0 but not a
207 * valid Solaris error code the extended error is
208 * decoded and printed.
210 se = strerror(errno);
211 if (se)
212 fprintf(fd, "%s\n", se);
213 else {
214 spcs_s_udata_t spcs_errno;
216 spcs_errno.i = errno;
217 fprintf(fd, "%s: %s\n",
218 module_names[spcs_errno.f.module],
219 dgettext("unistat",
220 SPCS_S_MSG[spcs_errno.f.module]
221 [spcs_errno.f.code]));
225 first_time = 0;
226 } while (sp);
228 p->icount = saved_count;
231 /*ARGSUSED*/
232 void
233 spcs_s_exception(spcs_s_info_t ustatus, void *env)
238 * Release (free) ioctl status storage.
241 void
242 spcs_s_ufree(spcs_s_info_t *ustatus_a)
244 free((void *)*ustatus_a);
245 *ustatus_a = NULL;