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 2002-2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdlib.h>
30 #include <strings.h>
31 #include <errno.h>
32 #include <pthread.h>
33
34 #include "util.h"
35
36 static void setLastError(CIMErrorReason, const cimchar *, const cimchar *, \
37 int *);
38 static void cleanupThreadExceptions(void *pParam);
39
40
41 pthread_key_t gWbemDiskLastErrorKey;
42
43 #pragma init(errorInit)
44 #pragma fini(errorFinalize)
45
46 /*
47 * The infastructure will call this when
48 * an error occurs, it should return a
49 * CCIMException which describes the error.
50 * Caller is responsable for freeing
51 * memory assocaited with the returned CCIMException
52 */
53
54 CCIMException *
cp_getLastError()55 cp_getLastError()
56 {
57 CCIMException *lastError = NULL;
58
59 lastError =
60 (CCIMException *)pthread_getspecific(gWbemDiskLastErrorKey);
61 (void) pthread_setspecific(gWbemDiskLastErrorKey, NULL);
62 return (lastError);
63 }
64
65 /*
66 * Handle the errors that come in from the providers. This involves writing to
67 * the CIM log and setting the last error on the stack for the CIMOM exception
68 * handling.
69 */
70
71 void
util_handleError(char * funcName,CIMErrorReason reason,char * reasonString,CCIMException * ex,int * errp)72 util_handleError(char *funcName, CIMErrorReason reason, char *reasonString,
73 CCIMException *ex, int *errp)
74 {
75
76
77 /*
78 * Create a copy of the exception, if it exists. The caller of
79 * this function should free the exception passed in.
80 */
81 if (ex != NULL) {
82 if (reasonString == NULL) {
83 setLastError(ex->mReason, ex->mErrorString, funcName, errp);
84 } else {
85 setLastError(ex->mReason, reasonString, funcName, errp);
86 }
87 cim_freeCIMException(ex);
88 } else {
89 setLastError(reason, reasonString, funcName, errp);
90 }
91 }
92
93 void *
util_getKeyValue(CCIMPropertyList * propList,CIMType propType,char * key,int * error)94 util_getKeyValue(CCIMPropertyList *propList, CIMType propType,
95 char *key, int *error) {
96
97 CCIMProperty *pProp;
98 CCIMPropertyList *pList = propList;
99
100 *error = 0;
101
102 do {
103 pProp = pList->mDataObject;
104 if (strcasecmp(pProp->mName, key) == 0) {
105 break;
106 }
107 pList = pList->mNext;
108 } while (pList);
109
110 if (pList == NULL) {
111 *error = CIM_ERR_INVALID_PARAMETER;
112 return ((CCIMProperty *)NULL);
113 }
114
115 /*
116 * If reference property, then return object path. In all other cases.
117 * the value is a string.
118 */
119
120 if (propType == reference) {
121 return (pProp->mObjPathValue);
122 } else {
123 return (pProp->mValue);
124 }
125 }
126 void
util_doProperty(cimchar * name,CIMType type,cimchar * value,CIMBool is_key,CCIMInstance * inst,int * error)127 util_doProperty(cimchar *name, CIMType type, cimchar *value, CIMBool is_key,
128 CCIMInstance *inst, int *error)
129 {
130
131 CCIMProperty *prop;
132
133 *error = 0;
134
135 prop = cim_createProperty(name, type, value, NULL, is_key);
136 if (prop == NULL) {
137 *error = CIM_ERR_FAILED;
138 return;
139 }
140 if ((cim_addProperty(inst, prop)) == cim_false) {
141 cim_freeProperty(prop);
142 *error = CIM_ERR_FAILED;
143 return;
144 }
145 }
146
147 void
util_doReferenceProperty(cimchar * role,CCIMObjectPath * obj,CIMBool isKey,CCIMInstance * inst,int * error)148 util_doReferenceProperty(cimchar *role, CCIMObjectPath *obj, CIMBool isKey,
149 CCIMInstance *inst, int *error)
150 {
151
152 CCIMProperty *prop;
153
154 *error = 0;
155 prop = cim_createReferenceProperty(role, obj, isKey);
156 if (prop == NULL) {
157 *error = CIM_ERR_INVALID_PARAMETER;
158 return;
159 }
160 if (cim_addProperty(inst, prop) == cim_false) {
161 cim_freeProperty(prop);
162 *error = CIM_ERR_FAILED;
163 return;
164 }
165 }
166
167 /*
168 * Function: openFile
169 *
170 * Parameters: fileName - char pointer to the name of the file to open.
171 * fMode - char pointer to the mode used to open the file.
172 *
173 * Returns: On successful completion returns the FILE pointer for
174 * the open file.
175 * On failure returns a NULL FILE pointer.
176 *
177 * Description: 'fopen's file and checks for errors.
178 */
179 FILE *
util_openFile(char * fileName,char * fMode)180 util_openFile(char *fileName, char *fMode)
181 {
182 FILE *pTmpFile;
183 int error;
184
185 /* Open the temporary file based on fMode */
186 pTmpFile = fopen(fileName, fMode);
187 if (pTmpFile == NULL) {
188 util_handleError(UTIL_OPENFILE, CIM_ERR_FAILED,
189 UTIL_FILEOPEN_FAILURE, NULL, &error);
190 return ((FILE *)NULL);
191 }
192 return (pTmpFile);
193 }
194
195 /*
196 * Function: util_closeFile
197 *
198 * Parameters: file - FILE pointer to an open file.
199 *
200 * Returns: On successful completion returns 1.
201 * On failure returns 0.
202 *
203 * Description: 'fclose's file and handles errors.
204 */
205
206 /* ARGSUSED */
207 int
util_closeFile(FILE * file,char * fName)208 util_closeFile(FILE *file, char *fName)
209 {
210 int error;
211
212 if (fclose(file) != 0) {
213 util_handleError(UTIL_CLOSEFILE, CIM_ERR_FAILED,
214 UTIL_FILECLOSE_FAILURE, NULL, &error);
215 return (0);
216 }
217 return (1);
218 }
219
220 /*
221 * Function: util_removeFile
222 *
223 * Parameters: tFName - char pointer to the filename
224 *
225 * Returns: NULL
226 *
227 * Description: Removes file and releases the memory used for
228 * the filename.
229 */
230 void
util_removeFile(char * tFName)231 util_removeFile(char *tFName)
232 {
233 int error;
234
235 if (remove(tFName) != 0) {
236 util_handleError(UTIL_REMOVEFILE, CIM_ERR_FAILED,
237 UTIL_FILEREMOVE_FAILURE, NULL, &error);
238 }
239
240 free(tFName);
241 }
242
243 char *
util_routineFailureMessage(char * routine)244 util_routineFailureMessage(char *routine)
245 {
246 static char msgBuf[MAXFAILSTRINGLEN];
247
248 /*
249 * TRANSLATION_NOTE
250 *
251 * "%s Failed." indicates an error returned by the function
252 * whose name is specified by the string used to replace %s.
253 */
254 (void) snprintf(msgBuf, MAXFAILSTRINGLEN,
255 dgettext(TEXT_DOMAIN, "%s Failed."), routine);
256
257 return (msgBuf);
258 }
259
260 /*
261 * Function: util_routineStartDaemonMessage
262 *
263 * Parameters: dname - the name of the daemon we we're attempting to start
264 *
265 * Returns: the generated string
266 *
267 * Description: creates a localized sring for eror messages.
268 */
269 char *
util_routineStartDaemonMessage(char * dname)270 util_routineStartDaemonMessage(char *dname)
271 {
272 static char msgBuf[MAXFAILSTRINGLEN];
273
274 /*
275 * TRANSLATION_NOTE
276 *
277 * "%s failed to start and must be started manually. " indicates
278 * an error stsrting the daemon specified by the string used to
279 * replace %s.
280 */
281 (void) snprintf(msgBuf, MAXFAILSTRINGLEN,
282 dgettext(TEXT_DOMAIN,
283 "%s failed to start and must be started manually. "),
284 dname);
285
286 return (msgBuf);
287 }
288
289 static void
cleanupThreadExceptions(void * pParam)290 cleanupThreadExceptions(void *pParam)
291 {
292 CCIMException *e = pParam;
293 cim_freeCIMException(e);
294 }
295
errorInit()296 static void errorInit()
297 {
298 /* Create the TSD key */
299 (void) pthread_key_create(&gWbemDiskLastErrorKey,
300 cleanupThreadExceptions);
301 if (gethostname(hostName, MAXHOSTNAMELEN) < 0) {
302 hostName[0] = '\0';
303 }
304 }
305
306 static void
errorFinalize()307 errorFinalize()
308 {
309 (void) pthread_key_delete(gWbemDiskLastErrorKey);
310 }
311
312 static void
setLastError(CIMErrorReason pRsn,const cimchar * pErrString,const cimchar * pCallingFunc,int * errp)313 setLastError(CIMErrorReason pRsn,
314 const cimchar* pErrString, const cimchar* pCallingFunc, int *errp)
315 {
316 char *msgp = "(null)";
317 CCIMException *lastError = NULL;
318
319 lastError =
320 (CCIMException *)pthread_getspecific(gWbemDiskLastErrorKey);
321
322 if (lastError != NULL) {
323 cim_freeCIMException(lastError);
324 }
325
326 if (pErrString != NULL) {
327 msgp = (char *)pErrString;
328 }
329
330 lastError = cim_createException(pRsn, msgp, pCallingFunc);
331 (void) pthread_setspecific(gWbemDiskLastErrorKey, lastError);
332 *errp = 1;
333 }
334