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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <libipmi.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <stdarg.h> 33 34 #include "ipmi_impl.h" 35 36 /* 37 * Error handling 38 */ 39 int 40 ipmi_set_error(ipmi_handle_t *ihp, int error, const char *fmt, ...) 41 { 42 va_list ap; 43 44 va_start(ap, fmt); 45 46 ihp->ih_errno = error; 47 if (fmt == NULL) 48 ihp->ih_errmsg[0] = '\0'; 49 else 50 (void) vsnprintf(ihp->ih_errmsg, sizeof (ihp->ih_errmsg), 51 fmt, ap); 52 va_end(ap); 53 54 return (-1); 55 } 56 57 int 58 ipmi_errno(ipmi_handle_t *ihp) 59 { 60 return (ihp->ih_errno); 61 } 62 63 static struct { 64 int err; 65 const char *msg; 66 } errno_table[] = { 67 { EIPMI_NOMEM, "memory allocation failure" }, 68 { EIPMI_BMC_OPEN_FAILED, "failed to open /dev/bmc" }, 69 { EIPMI_BMC_PUTMSG, "failed to send message to /dev/bmc" }, 70 { EIPMI_BMC_GETMSG, 71 "failed to read response from /dev/bmc" }, 72 { EIPMI_BMC_RESPONSE, 73 "failed to read response from /dev/bmc" }, 74 { EIPMI_INVALID_COMMAND, "invalid command" }, 75 { EIPMI_COMMAND_TIMEOUT, "command timed out" }, 76 { EIPMI_DATA_LENGTH_EXCEEDED, "maximum data length exceeded" }, 77 { EIPMI_SEND_FAILED, "failed to send BMC request" }, 78 { EIPMI_UNSPECIFIED, "unspecified BMC error" }, 79 { EIPMI_BAD_RESPONSE_LENGTH, 80 "unexpected command response data length" }, 81 { EIPMI_INVALID_RESERVATION, "invalid or cancelled reservation" }, 82 { EIPMI_NOT_PRESENT, "request entity not present" }, 83 { EIPMI_INVALID_REQUEST, "malformed request data" }, 84 { EIPMI_BUSY, "service processor is busy" }, 85 { EIPMI_NOSPACE, "service processor is out of space" }, 86 { EIPMI_UNAVAILABLE, "service processor is unavailable" }, 87 { EIPMI_ACCESS, "insufficient privileges" } 88 }; 89 90 /* ARGSUSED */ 91 const char * 92 ipmi_errmsg(ipmi_handle_t *ihp) 93 { 94 int i; 95 const char *str; 96 97 str = NULL; 98 for (i = 0; i < sizeof (errno_table) / sizeof (errno_table[0]); i++) { 99 if (errno_table[i].err == ihp->ih_errno) { 100 str = errno_table[i].msg; 101 break; 102 } 103 } 104 105 if (str == NULL && (str = strerror(ihp->ih_errno)) == NULL) 106 str = "unknown failure"; 107 108 if (ihp->ih_errmsg[0] == '\0') 109 return (str); 110 111 (void) snprintf(ihp->ih_errbuf, sizeof (ihp->ih_errbuf), 112 "%s: %s", str, ihp->ih_errmsg); 113 return (ihp->ih_errbuf); 114 } 115 116 /* 117 * Memory allocation 118 */ 119 120 void * 121 ipmi_alloc(ipmi_handle_t *ihp, size_t size) 122 { 123 void *ptr; 124 125 if ((ptr = malloc(size)) == NULL) 126 (void) ipmi_set_error(ihp, EIPMI_NOMEM, NULL); 127 128 return (ptr); 129 } 130 131 void * 132 ipmi_zalloc(ipmi_handle_t *ihp, size_t size) 133 { 134 void *ptr; 135 136 if ((ptr = calloc(size, 1)) == NULL) 137 (void) ipmi_set_error(ihp, EIPMI_NOMEM, NULL); 138 139 return (ptr); 140 } 141 142 char * 143 ipmi_strdup(ipmi_handle_t *ihp, const char *str) 144 { 145 char *ptr; 146 147 if ((ptr = strdup(str)) == NULL) 148 (void) ipmi_set_error(ihp, EIPMI_NOMEM, NULL); 149 150 return (ptr); 151 } 152 153 /* ARGSUSED */ 154 void 155 ipmi_free(ipmi_handle_t *ihp, void *ptr) 156 { 157 free(ptr); 158 } 159