xref: /onnv-gate/usr/src/cmd/wbem/provider/c/wbem_disk/common/util.c (revision 0:68f95e015346)
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