xref: /illumos-gate/usr/src/lib/fm/libdiskstatus/common/ds_util.c (revision 0ccfe5834c3b867c1b6c273cae02ec8922bc0fd2)
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 #include <ctype.h>
27 #include <libdiskstatus.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "ds_impl.h"
33 
34 boolean_t ds_debug;
35 
36 /*PRINTFLIKE1*/
37 void
38 dprintf(const char *fmt, ...)
39 {
40 	va_list ap;
41 
42 	if (!ds_debug)
43 		return;
44 
45 	va_start(ap, fmt);
46 	(void) vprintf(fmt, ap);
47 	va_end(ap);
48 }
49 
50 void
51 ddump(const char *label, const void *data, size_t length)
52 {
53 	int byte_count;
54 	int i;
55 #define	LINEBUFLEN 128
56 	char linebuf[LINEBUFLEN];
57 	char *linep;
58 	int bufleft, len;
59 	const char *start = data;
60 
61 	if (!ds_debug)
62 		return;
63 
64 	if (label != NULL)
65 		dprintf("%s\n", label);
66 
67 	linep = linebuf;
68 	bufleft = LINEBUFLEN;
69 
70 	for (byte_count = 0; byte_count < length; byte_count += i) {
71 
72 		(void) snprintf(linep, bufleft, "0x%08x ", byte_count);
73 		len = strlen(linep);
74 		bufleft -= len;
75 		linep += len;
76 
77 		/*
78 		 * Inner loop processes 16 bytes at a time, or less
79 		 * if we have less than 16 bytes to go
80 		 */
81 		for (i = 0; (i < 16) && ((byte_count + i) < length); i++) {
82 			(void) snprintf(linep, bufleft, "%02X", (unsigned int)
83 			    (unsigned char) start[byte_count + i]);
84 
85 			len = strlen(linep);
86 			bufleft -= len;
87 			linep += len;
88 
89 			if (bufleft >= 2) {
90 				if (i == 7)
91 					*linep = '-';
92 				else
93 					*linep = ' ';
94 
95 				--bufleft;
96 				++linep;
97 			}
98 		}
99 
100 		/*
101 		 * If i is less than 16, then we had less than 16 bytes
102 		 * written to the output.  We need to fixup the alignment
103 		 * to allow the "text" output to be aligned
104 		 */
105 		if (i < 16) {
106 			int numspaces = (16 - i) * 3;
107 			while (numspaces-- > 0) {
108 				if (bufleft >= 2) {
109 					*linep = ' ';
110 					--bufleft;
111 					linep++;
112 				}
113 			}
114 		}
115 
116 		if (bufleft >= 2) {
117 			*linep = ' ';
118 			--bufleft;
119 			++linep;
120 		}
121 
122 		for (i = 0; (i < 16) && ((byte_count + i) < length); i++) {
123 			int subscript = byte_count + i;
124 			char ch =  (isprint(start[subscript]) ?
125 			    start[subscript] : '.');
126 
127 			if (bufleft >= 2) {
128 				*linep = ch;
129 				--bufleft;
130 				++linep;
131 			}
132 		}
133 
134 		linebuf[LINEBUFLEN - bufleft] = 0;
135 
136 		dprintf("%s\n", linebuf);
137 
138 		linep = linebuf;
139 		bufleft = LINEBUFLEN;
140 	}
141 
142 }
143 
144 const char *
145 disk_status_errmsg(int error)
146 {
147 	switch (error) {
148 	case EDS_NOMEM:
149 		return ("memory allocation failure");
150 	case EDS_CANT_OPEN:
151 		return ("failed to open device");
152 	case EDS_NO_TRANSPORT:
153 		return ("no supported communication protocol");
154 	case EDS_NOT_SUPPORTED:
155 		return ("disk status information not supported");
156 	case EDS_NOT_SIMULATOR:
157 		return ("not a valid simulator file");
158 	case EDS_IO:
159 		return ("I/O error from device");
160 	default:
161 		return ("unknown error");
162 	}
163 }
164 
165 int
166 ds_set_errno(disk_status_t *dsp, int error)
167 {
168 	dsp->ds_error = error;
169 	return (-1);
170 }
171