1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3c18ec02fSPetter Reinholdtsen *
4c18ec02fSPetter Reinholdtsen * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen * are met:
7c18ec02fSPetter Reinholdtsen *
8c18ec02fSPetter Reinholdtsen * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen *
11c18ec02fSPetter Reinholdtsen * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen *
15c18ec02fSPetter Reinholdtsen * Neither the name of Sun Microsystems, Inc. or the names of
16c18ec02fSPetter Reinholdtsen * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen *
19c18ec02fSPetter Reinholdtsen * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen */
32ce02ffafSZdenek Styblik #define _POSIX_SOURCE
33c18ec02fSPetter Reinholdtsen
34c18ec02fSPetter Reinholdtsen #include <sys/types.h>
35c18ec02fSPetter Reinholdtsen #include <sys/stat.h>
36c18ec02fSPetter Reinholdtsen #include <sys/ioctl.h> /* For TIOCNOTTY */
37c18ec02fSPetter Reinholdtsen
38c18ec02fSPetter Reinholdtsen #include <stdlib.h>
39c18ec02fSPetter Reinholdtsen #include <stdint.h>
40c18ec02fSPetter Reinholdtsen #include <stdio.h>
41c18ec02fSPetter Reinholdtsen #include <inttypes.h>
42c18ec02fSPetter Reinholdtsen #include <signal.h>
43c18ec02fSPetter Reinholdtsen #include <string.h>
44c18ec02fSPetter Reinholdtsen #include <strings.h>
45c18ec02fSPetter Reinholdtsen #include <unistd.h>
46c18ec02fSPetter Reinholdtsen #include <fcntl.h>
47c18ec02fSPetter Reinholdtsen #include <errno.h>
48c18ec02fSPetter Reinholdtsen #include <assert.h>
49c18ec02fSPetter Reinholdtsen
50c18ec02fSPetter Reinholdtsen #if HAVE_CONFIG_H
51c18ec02fSPetter Reinholdtsen # include <config.h>
52c18ec02fSPetter Reinholdtsen #endif
53c18ec02fSPetter Reinholdtsen
54c18ec02fSPetter Reinholdtsen #ifdef HAVE_PATHS_H
55c18ec02fSPetter Reinholdtsen # include <paths.h>
56c18ec02fSPetter Reinholdtsen #else
57c18ec02fSPetter Reinholdtsen # define _PATH_VARRUN "/var/run/"
58c18ec02fSPetter Reinholdtsen #endif
59c18ec02fSPetter Reinholdtsen
60c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
61c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
62c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
63c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
64c18ec02fSPetter Reinholdtsen
65c18ec02fSPetter Reinholdtsen extern int verbose;
66c18ec02fSPetter Reinholdtsen
buf2long(uint8_t * buf)67c18ec02fSPetter Reinholdtsen uint32_t buf2long(uint8_t * buf)
68c18ec02fSPetter Reinholdtsen {
69c18ec02fSPetter Reinholdtsen return (uint32_t)(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]);
70c18ec02fSPetter Reinholdtsen }
71c18ec02fSPetter Reinholdtsen
buf2short(uint8_t * buf)72c18ec02fSPetter Reinholdtsen uint16_t buf2short(uint8_t * buf)
73c18ec02fSPetter Reinholdtsen {
74c18ec02fSPetter Reinholdtsen return (uint16_t)(buf[1] << 8 | buf[0]);
75c18ec02fSPetter Reinholdtsen }
76c18ec02fSPetter Reinholdtsen
buf2str(uint8_t * buf,int len)77c18ec02fSPetter Reinholdtsen const char * buf2str(uint8_t * buf, int len)
78c18ec02fSPetter Reinholdtsen {
79c18ec02fSPetter Reinholdtsen static char str[2049];
80c18ec02fSPetter Reinholdtsen int i;
81c18ec02fSPetter Reinholdtsen
82c18ec02fSPetter Reinholdtsen if (len <= 0 || len > 1024)
83c18ec02fSPetter Reinholdtsen return NULL;
84c18ec02fSPetter Reinholdtsen
85c18ec02fSPetter Reinholdtsen memset(str, 0, 2049);
86c18ec02fSPetter Reinholdtsen
87c18ec02fSPetter Reinholdtsen for (i=0; i<len; i++)
88c18ec02fSPetter Reinholdtsen sprintf(str+i+i, "%2.2x", buf[i]);
89c18ec02fSPetter Reinholdtsen
90c18ec02fSPetter Reinholdtsen str[len*2] = '\0';
91c18ec02fSPetter Reinholdtsen
92c18ec02fSPetter Reinholdtsen return (const char *)str;
93c18ec02fSPetter Reinholdtsen }
94c18ec02fSPetter Reinholdtsen
printbuf(const uint8_t * buf,int len,const char * desc)95c18ec02fSPetter Reinholdtsen void printbuf(const uint8_t * buf, int len, const char * desc)
96c18ec02fSPetter Reinholdtsen {
97c18ec02fSPetter Reinholdtsen int i;
98c18ec02fSPetter Reinholdtsen
99c18ec02fSPetter Reinholdtsen if (len <= 0)
100c18ec02fSPetter Reinholdtsen return;
101c18ec02fSPetter Reinholdtsen
102c18ec02fSPetter Reinholdtsen if (verbose < 1)
103c18ec02fSPetter Reinholdtsen return;
104c18ec02fSPetter Reinholdtsen
105c18ec02fSPetter Reinholdtsen fprintf(stderr, "%s (%d bytes)\n", desc, len);
106c18ec02fSPetter Reinholdtsen for (i=0; i<len; i++) {
107c18ec02fSPetter Reinholdtsen if (((i%16) == 0) && (i != 0))
108c18ec02fSPetter Reinholdtsen fprintf(stderr, "\n");
109c18ec02fSPetter Reinholdtsen fprintf(stderr, " %2.2x", buf[i]);
110c18ec02fSPetter Reinholdtsen }
111c18ec02fSPetter Reinholdtsen fprintf(stderr, "\n");
112c18ec02fSPetter Reinholdtsen }
113c18ec02fSPetter Reinholdtsen
val2str(uint16_t val,const struct valstr * vs)114c18ec02fSPetter Reinholdtsen const char * val2str(uint16_t val, const struct valstr *vs)
115c18ec02fSPetter Reinholdtsen {
116c18ec02fSPetter Reinholdtsen static char un_str[32];
117c18ec02fSPetter Reinholdtsen int i;
118c18ec02fSPetter Reinholdtsen
119c18ec02fSPetter Reinholdtsen for (i = 0; vs[i].str != NULL; i++) {
120c18ec02fSPetter Reinholdtsen if (vs[i].val == val)
121c18ec02fSPetter Reinholdtsen return vs[i].str;
122c18ec02fSPetter Reinholdtsen }
123c18ec02fSPetter Reinholdtsen
124c18ec02fSPetter Reinholdtsen memset(un_str, 0, 32);
125c18ec02fSPetter Reinholdtsen snprintf(un_str, 32, "Unknown (0x%02X)", val);
126c18ec02fSPetter Reinholdtsen
127c18ec02fSPetter Reinholdtsen return un_str;
128c18ec02fSPetter Reinholdtsen }
129c18ec02fSPetter Reinholdtsen
oemval2str(uint32_t oem,uint16_t val,const struct oemvalstr * vs)130c18ec02fSPetter Reinholdtsen const char * oemval2str(uint32_t oem, uint16_t val,
131c18ec02fSPetter Reinholdtsen const struct oemvalstr *vs)
132c18ec02fSPetter Reinholdtsen {
133c18ec02fSPetter Reinholdtsen static char un_str[32];
134c18ec02fSPetter Reinholdtsen int i;
135c18ec02fSPetter Reinholdtsen
136c18ec02fSPetter Reinholdtsen for (i = 0; vs[i].oem != 0xffffff && vs[i].str != NULL; i++) {
137c18ec02fSPetter Reinholdtsen /* FIXME: for now on we assume PICMG capability on all IANAs */
138c18ec02fSPetter Reinholdtsen if ( (vs[i].oem == oem || vs[i].oem == IPMI_OEM_PICMG) &&
139c18ec02fSPetter Reinholdtsen vs[i].val == val ) {
140c18ec02fSPetter Reinholdtsen return vs[i].str;
141c18ec02fSPetter Reinholdtsen }
142c18ec02fSPetter Reinholdtsen }
143c18ec02fSPetter Reinholdtsen
144c18ec02fSPetter Reinholdtsen memset(un_str, 0, 32);
145c18ec02fSPetter Reinholdtsen snprintf(un_str, 32, "Unknown (0x%X)", val);
146c18ec02fSPetter Reinholdtsen
147c18ec02fSPetter Reinholdtsen return un_str;
148c18ec02fSPetter Reinholdtsen }
149c18ec02fSPetter Reinholdtsen
150c18ec02fSPetter Reinholdtsen /* str2double - safely convert string to double
151c18ec02fSPetter Reinholdtsen *
152c18ec02fSPetter Reinholdtsen * @str: source string to convert from
153c18ec02fSPetter Reinholdtsen * @double_ptr: pointer where to store result
154c18ec02fSPetter Reinholdtsen *
155c18ec02fSPetter Reinholdtsen * returns zero on success
156c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
157c18ec02fSPetter Reinholdtsen */
str2double(const char * str,double * double_ptr)158c18ec02fSPetter Reinholdtsen int str2double(const char * str, double * double_ptr)
159c18ec02fSPetter Reinholdtsen {
160c18ec02fSPetter Reinholdtsen char * end_ptr = 0;
161c18ec02fSPetter Reinholdtsen if (!str || !double_ptr)
162c18ec02fSPetter Reinholdtsen return (-1);
163c18ec02fSPetter Reinholdtsen
164c18ec02fSPetter Reinholdtsen *double_ptr = 0;
165c18ec02fSPetter Reinholdtsen errno = 0;
166c18ec02fSPetter Reinholdtsen *double_ptr = strtod(str, &end_ptr);
167c18ec02fSPetter Reinholdtsen
168c18ec02fSPetter Reinholdtsen if (*end_ptr != '\0')
169c18ec02fSPetter Reinholdtsen return (-2);
170c18ec02fSPetter Reinholdtsen
171c18ec02fSPetter Reinholdtsen if (errno != 0)
172c18ec02fSPetter Reinholdtsen return (-3);
173c18ec02fSPetter Reinholdtsen
174c18ec02fSPetter Reinholdtsen return 0;
175c18ec02fSPetter Reinholdtsen } /* str2double(...) */
176c18ec02fSPetter Reinholdtsen
177c18ec02fSPetter Reinholdtsen /* str2long - safely convert string to int64_t
178c18ec02fSPetter Reinholdtsen *
179c18ec02fSPetter Reinholdtsen * @str: source string to convert from
180c18ec02fSPetter Reinholdtsen * @lng_ptr: pointer where to store result
181c18ec02fSPetter Reinholdtsen *
182c18ec02fSPetter Reinholdtsen * returns zero on success
183c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
184c18ec02fSPetter Reinholdtsen */
str2long(const char * str,int64_t * lng_ptr)185c18ec02fSPetter Reinholdtsen int str2long(const char * str, int64_t * lng_ptr)
186c18ec02fSPetter Reinholdtsen {
187c18ec02fSPetter Reinholdtsen char * end_ptr = 0;
188c18ec02fSPetter Reinholdtsen if (!str || !lng_ptr)
189c18ec02fSPetter Reinholdtsen return (-1);
190c18ec02fSPetter Reinholdtsen
191c18ec02fSPetter Reinholdtsen *lng_ptr = 0;
192c18ec02fSPetter Reinholdtsen errno = 0;
193c18ec02fSPetter Reinholdtsen *lng_ptr = strtol(str, &end_ptr, 0);
194c18ec02fSPetter Reinholdtsen
195c18ec02fSPetter Reinholdtsen if (*end_ptr != '\0')
196c18ec02fSPetter Reinholdtsen return (-2);
197c18ec02fSPetter Reinholdtsen
198c18ec02fSPetter Reinholdtsen if (errno != 0)
199c18ec02fSPetter Reinholdtsen return (-3);
200c18ec02fSPetter Reinholdtsen
201c18ec02fSPetter Reinholdtsen return 0;
202c18ec02fSPetter Reinholdtsen } /* str2long(...) */
203c18ec02fSPetter Reinholdtsen
204c18ec02fSPetter Reinholdtsen /* str2ulong - safely convert string to uint64_t
205c18ec02fSPetter Reinholdtsen *
206c18ec02fSPetter Reinholdtsen * @str: source string to convert from
207c18ec02fSPetter Reinholdtsen * @ulng_ptr: pointer where to store result
208c18ec02fSPetter Reinholdtsen *
209c18ec02fSPetter Reinholdtsen * returns zero on success
210c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
211c18ec02fSPetter Reinholdtsen */
str2ulong(const char * str,uint64_t * ulng_ptr)212c18ec02fSPetter Reinholdtsen int str2ulong(const char * str, uint64_t * ulng_ptr)
213c18ec02fSPetter Reinholdtsen {
214c18ec02fSPetter Reinholdtsen char * end_ptr = 0;
215c18ec02fSPetter Reinholdtsen if (!str || !ulng_ptr)
216c18ec02fSPetter Reinholdtsen return (-1);
217c18ec02fSPetter Reinholdtsen
218c18ec02fSPetter Reinholdtsen *ulng_ptr = 0;
219c18ec02fSPetter Reinholdtsen errno = 0;
220c18ec02fSPetter Reinholdtsen *ulng_ptr = strtoul(str, &end_ptr, 0);
221c18ec02fSPetter Reinholdtsen
222c18ec02fSPetter Reinholdtsen if (*end_ptr != '\0')
223c18ec02fSPetter Reinholdtsen return (-2);
224c18ec02fSPetter Reinholdtsen
225c18ec02fSPetter Reinholdtsen if (errno != 0)
226c18ec02fSPetter Reinholdtsen return (-3);
227c18ec02fSPetter Reinholdtsen
228c18ec02fSPetter Reinholdtsen return 0;
229c18ec02fSPetter Reinholdtsen } /* str2ulong(...) */
230c18ec02fSPetter Reinholdtsen
231c18ec02fSPetter Reinholdtsen /* str2int - safely convert string to int32_t
232c18ec02fSPetter Reinholdtsen *
233c18ec02fSPetter Reinholdtsen * @str: source string to convert from
234c18ec02fSPetter Reinholdtsen * @int_ptr: pointer where to store result
235c18ec02fSPetter Reinholdtsen *
236c18ec02fSPetter Reinholdtsen * returns zero on success
237c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
238c18ec02fSPetter Reinholdtsen */
str2int(const char * str,int32_t * int_ptr)239c18ec02fSPetter Reinholdtsen int str2int(const char * str, int32_t * int_ptr)
240c18ec02fSPetter Reinholdtsen {
241c18ec02fSPetter Reinholdtsen int rc = 0;
242c18ec02fSPetter Reinholdtsen int64_t arg_long = 0;
243c18ec02fSPetter Reinholdtsen if (!str || !int_ptr)
244c18ec02fSPetter Reinholdtsen return (-1);
245c18ec02fSPetter Reinholdtsen
246c18ec02fSPetter Reinholdtsen if ( (rc = str2long(str, &arg_long)) != 0 ) {
247c18ec02fSPetter Reinholdtsen *int_ptr = 0;
248c18ec02fSPetter Reinholdtsen return rc;
249c18ec02fSPetter Reinholdtsen }
250c18ec02fSPetter Reinholdtsen
251c18ec02fSPetter Reinholdtsen if (arg_long < INT32_MIN || arg_long > INT32_MAX)
252c18ec02fSPetter Reinholdtsen return (-3);
253c18ec02fSPetter Reinholdtsen
254c18ec02fSPetter Reinholdtsen *int_ptr = (int32_t)arg_long;
255c18ec02fSPetter Reinholdtsen return 0;
256c18ec02fSPetter Reinholdtsen } /* str2int(...) */
257c18ec02fSPetter Reinholdtsen
258c18ec02fSPetter Reinholdtsen /* str2uint - safely convert string to uint32_t
259c18ec02fSPetter Reinholdtsen *
260c18ec02fSPetter Reinholdtsen * @str: source string to convert from
261c18ec02fSPetter Reinholdtsen * @uint_ptr: pointer where to store result
262c18ec02fSPetter Reinholdtsen *
263c18ec02fSPetter Reinholdtsen * returns zero on success
264c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
265c18ec02fSPetter Reinholdtsen */
str2uint(const char * str,uint32_t * uint_ptr)266c18ec02fSPetter Reinholdtsen int str2uint(const char * str, uint32_t * uint_ptr)
267c18ec02fSPetter Reinholdtsen {
268c18ec02fSPetter Reinholdtsen int rc = 0;
269c18ec02fSPetter Reinholdtsen uint64_t arg_ulong = 0;
270c18ec02fSPetter Reinholdtsen if (!str || !uint_ptr)
271c18ec02fSPetter Reinholdtsen return (-1);
272c18ec02fSPetter Reinholdtsen
273c18ec02fSPetter Reinholdtsen if ( (rc = str2ulong(str, &arg_ulong)) != 0) {
274c18ec02fSPetter Reinholdtsen *uint_ptr = 0;
275c18ec02fSPetter Reinholdtsen return rc;
276c18ec02fSPetter Reinholdtsen }
277c18ec02fSPetter Reinholdtsen
278c18ec02fSPetter Reinholdtsen if (arg_ulong > UINT32_MAX)
279c18ec02fSPetter Reinholdtsen return (-3);
280c18ec02fSPetter Reinholdtsen
281c18ec02fSPetter Reinholdtsen *uint_ptr = (uint32_t)arg_ulong;
282c18ec02fSPetter Reinholdtsen return 0;
283c18ec02fSPetter Reinholdtsen } /* str2uint(...) */
284c18ec02fSPetter Reinholdtsen
285c18ec02fSPetter Reinholdtsen /* str2short - safely convert string to int16_t
286c18ec02fSPetter Reinholdtsen *
287c18ec02fSPetter Reinholdtsen * @str: source string to convert from
288c18ec02fSPetter Reinholdtsen * @shrt_ptr: pointer where to store result
289c18ec02fSPetter Reinholdtsen *
290c18ec02fSPetter Reinholdtsen * returns zero on success
291c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
292c18ec02fSPetter Reinholdtsen */
str2short(const char * str,int16_t * shrt_ptr)293c18ec02fSPetter Reinholdtsen int str2short(const char * str, int16_t * shrt_ptr)
294c18ec02fSPetter Reinholdtsen {
295c18ec02fSPetter Reinholdtsen int rc = (-3);
296c18ec02fSPetter Reinholdtsen int64_t arg_long = 0;
297c18ec02fSPetter Reinholdtsen if (!str || !shrt_ptr)
298c18ec02fSPetter Reinholdtsen return (-1);
299c18ec02fSPetter Reinholdtsen
300c18ec02fSPetter Reinholdtsen if ( (rc = str2long(str, &arg_long)) != 0 ) {
301c18ec02fSPetter Reinholdtsen *shrt_ptr = 0;
302c18ec02fSPetter Reinholdtsen return rc;
303c18ec02fSPetter Reinholdtsen }
304c18ec02fSPetter Reinholdtsen
305c18ec02fSPetter Reinholdtsen if (arg_long < INT16_MIN || arg_long > INT16_MAX)
306c18ec02fSPetter Reinholdtsen return (-3);
307c18ec02fSPetter Reinholdtsen
308c18ec02fSPetter Reinholdtsen *shrt_ptr = (int16_t)arg_long;
309c18ec02fSPetter Reinholdtsen return 0;
310c18ec02fSPetter Reinholdtsen } /* str2short(...) */
311c18ec02fSPetter Reinholdtsen
312c18ec02fSPetter Reinholdtsen /* str2ushort - safely convert string to uint16_t
313c18ec02fSPetter Reinholdtsen *
314c18ec02fSPetter Reinholdtsen * @str: source string to convert from
315c18ec02fSPetter Reinholdtsen * @ushrt_ptr: pointer where to store result
316c18ec02fSPetter Reinholdtsen *
317c18ec02fSPetter Reinholdtsen * returns zero on success
318c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow
319c18ec02fSPetter Reinholdtsen */
str2ushort(const char * str,uint16_t * ushrt_ptr)320c18ec02fSPetter Reinholdtsen int str2ushort(const char * str, uint16_t * ushrt_ptr)
321c18ec02fSPetter Reinholdtsen {
322c18ec02fSPetter Reinholdtsen int rc = (-3);
323c18ec02fSPetter Reinholdtsen uint64_t arg_ulong = 0;
324c18ec02fSPetter Reinholdtsen if (!str || !ushrt_ptr)
325c18ec02fSPetter Reinholdtsen return (-1);
326c18ec02fSPetter Reinholdtsen
327c18ec02fSPetter Reinholdtsen if ( (rc = str2ulong(str, &arg_ulong)) != 0 ) {
328c18ec02fSPetter Reinholdtsen *ushrt_ptr = 0;
329c18ec02fSPetter Reinholdtsen return rc;
330c18ec02fSPetter Reinholdtsen }
331c18ec02fSPetter Reinholdtsen
332c18ec02fSPetter Reinholdtsen if (arg_ulong > UINT16_MAX)
333c18ec02fSPetter Reinholdtsen return (-3);
334c18ec02fSPetter Reinholdtsen
335c18ec02fSPetter Reinholdtsen *ushrt_ptr = (uint16_t)arg_ulong;
336c18ec02fSPetter Reinholdtsen return 0;
337c18ec02fSPetter Reinholdtsen } /* str2ushort(...) */
338c18ec02fSPetter Reinholdtsen
339c18ec02fSPetter Reinholdtsen /* str2char - safely convert string to int8
340c18ec02fSPetter Reinholdtsen *
341c18ec02fSPetter Reinholdtsen * @str: source string to convert from
342c18ec02fSPetter Reinholdtsen * @chr_ptr: pointer where to store result
343c18ec02fSPetter Reinholdtsen *
344c18ec02fSPetter Reinholdtsen * returns zero on success
345c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) or (-3) if conversion fails
346c18ec02fSPetter Reinholdtsen */
str2char(const char * str,int8_t * chr_ptr)347c18ec02fSPetter Reinholdtsen int str2char(const char *str, int8_t * chr_ptr)
348c18ec02fSPetter Reinholdtsen {
349c18ec02fSPetter Reinholdtsen int rc = (-3);
350c18ec02fSPetter Reinholdtsen int64_t arg_long = 0;
351c18ec02fSPetter Reinholdtsen if (!str || !chr_ptr) {
352c18ec02fSPetter Reinholdtsen return (-1);
353c18ec02fSPetter Reinholdtsen }
354c18ec02fSPetter Reinholdtsen if ((rc = str2long(str, &arg_long)) != 0) {
355c18ec02fSPetter Reinholdtsen *chr_ptr = 0;
356c18ec02fSPetter Reinholdtsen return rc;
357c18ec02fSPetter Reinholdtsen }
358c18ec02fSPetter Reinholdtsen if (arg_long < INT8_MIN || arg_long > INT8_MAX) {
359c18ec02fSPetter Reinholdtsen return (-3);
360c18ec02fSPetter Reinholdtsen }
361bee3fda6SParthasarathy Bhuvaragan *chr_ptr = (uint8_t)arg_long;
362c18ec02fSPetter Reinholdtsen return 0;
363c18ec02fSPetter Reinholdtsen } /* str2char(...) */
364c18ec02fSPetter Reinholdtsen
365c18ec02fSPetter Reinholdtsen /* str2uchar - safely convert string to uint8
366c18ec02fSPetter Reinholdtsen *
367c18ec02fSPetter Reinholdtsen * @str: source string to convert from
368c18ec02fSPetter Reinholdtsen * @uchr_ptr: pointer where to store result
369c18ec02fSPetter Reinholdtsen *
370c18ec02fSPetter Reinholdtsen * returns zero on success
371c18ec02fSPetter Reinholdtsen * returns (-1) if one of args is NULL, (-2) or (-3) if conversion fails
372c18ec02fSPetter Reinholdtsen */
str2uchar(const char * str,uint8_t * uchr_ptr)373c18ec02fSPetter Reinholdtsen int str2uchar(const char * str, uint8_t * uchr_ptr)
374c18ec02fSPetter Reinholdtsen {
375c18ec02fSPetter Reinholdtsen int rc = (-3);
376c18ec02fSPetter Reinholdtsen uint64_t arg_ulong = 0;
377c18ec02fSPetter Reinholdtsen if (!str || !uchr_ptr)
378c18ec02fSPetter Reinholdtsen return (-1);
379c18ec02fSPetter Reinholdtsen
380c18ec02fSPetter Reinholdtsen if ( (rc = str2ulong(str, &arg_ulong)) != 0 ) {
381c18ec02fSPetter Reinholdtsen *uchr_ptr = 0;
382c18ec02fSPetter Reinholdtsen return rc;
383c18ec02fSPetter Reinholdtsen }
384c18ec02fSPetter Reinholdtsen
385c18ec02fSPetter Reinholdtsen if (arg_ulong > UINT8_MAX)
386c18ec02fSPetter Reinholdtsen return (-3);
387c18ec02fSPetter Reinholdtsen
388c18ec02fSPetter Reinholdtsen *uchr_ptr = (uint8_t)arg_ulong;
389c18ec02fSPetter Reinholdtsen return 0;
390c18ec02fSPetter Reinholdtsen } /* str2uchar(...) */
391c18ec02fSPetter Reinholdtsen
str2val(const char * str,const struct valstr * vs)392c18ec02fSPetter Reinholdtsen uint16_t str2val(const char *str, const struct valstr *vs)
393c18ec02fSPetter Reinholdtsen {
394c18ec02fSPetter Reinholdtsen int i;
395c18ec02fSPetter Reinholdtsen
396c18ec02fSPetter Reinholdtsen for (i = 0; vs[i].str != NULL; i++) {
397c18ec02fSPetter Reinholdtsen if (strncasecmp(vs[i].str, str, __maxlen(str, vs[i].str)) == 0)
398c18ec02fSPetter Reinholdtsen return vs[i].val;
399c18ec02fSPetter Reinholdtsen }
400c18ec02fSPetter Reinholdtsen
401c18ec02fSPetter Reinholdtsen return vs[i].val;
402c18ec02fSPetter Reinholdtsen }
403c18ec02fSPetter Reinholdtsen
404c18ec02fSPetter Reinholdtsen /* print_valstr - print value string list to log or stdout
405c18ec02fSPetter Reinholdtsen *
406c18ec02fSPetter Reinholdtsen * @vs: value string list to print
407c18ec02fSPetter Reinholdtsen * @title: name of this value string list
408c18ec02fSPetter Reinholdtsen * @loglevel: what log level to print, -1 for stdout
409c18ec02fSPetter Reinholdtsen */
410c18ec02fSPetter Reinholdtsen void
print_valstr(const struct valstr * vs,const char * title,int loglevel)411c18ec02fSPetter Reinholdtsen print_valstr(const struct valstr * vs, const char * title, int loglevel)
412c18ec02fSPetter Reinholdtsen {
413c18ec02fSPetter Reinholdtsen int i;
414c18ec02fSPetter Reinholdtsen
415c18ec02fSPetter Reinholdtsen if (vs == NULL)
416c18ec02fSPetter Reinholdtsen return;
417c18ec02fSPetter Reinholdtsen
418c18ec02fSPetter Reinholdtsen if (title != NULL) {
419c18ec02fSPetter Reinholdtsen if (loglevel < 0)
420c18ec02fSPetter Reinholdtsen printf("\n%s:\n\n", title);
421c18ec02fSPetter Reinholdtsen else
422c18ec02fSPetter Reinholdtsen lprintf(loglevel, "\n%s:\n", title);
423c18ec02fSPetter Reinholdtsen }
424c18ec02fSPetter Reinholdtsen
425c18ec02fSPetter Reinholdtsen if (loglevel < 0) {
426c18ec02fSPetter Reinholdtsen printf(" VALUE\tHEX\tSTRING\n");
427c18ec02fSPetter Reinholdtsen printf("==============================================\n");
428c18ec02fSPetter Reinholdtsen } else {
429c18ec02fSPetter Reinholdtsen lprintf(loglevel, " VAL\tHEX\tSTRING");
430c18ec02fSPetter Reinholdtsen lprintf(loglevel, "==============================================");
431c18ec02fSPetter Reinholdtsen }
432c18ec02fSPetter Reinholdtsen
433c18ec02fSPetter Reinholdtsen for (i = 0; vs[i].str != NULL; i++) {
434c18ec02fSPetter Reinholdtsen if (loglevel < 0) {
435c18ec02fSPetter Reinholdtsen if (vs[i].val < 256)
436c18ec02fSPetter Reinholdtsen printf(" %d\t0x%02x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
437c18ec02fSPetter Reinholdtsen else
438c18ec02fSPetter Reinholdtsen printf(" %d\t0x%04x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
439c18ec02fSPetter Reinholdtsen } else {
440c18ec02fSPetter Reinholdtsen if (vs[i].val < 256)
441c18ec02fSPetter Reinholdtsen lprintf(loglevel, " %d\t0x%02x\t%s", vs[i].val, vs[i].val, vs[i].str);
442c18ec02fSPetter Reinholdtsen else
443c18ec02fSPetter Reinholdtsen lprintf(loglevel, " %d\t0x%04x\t%s", vs[i].val, vs[i].val, vs[i].str);
444c18ec02fSPetter Reinholdtsen }
445c18ec02fSPetter Reinholdtsen }
446c18ec02fSPetter Reinholdtsen
447c18ec02fSPetter Reinholdtsen if (loglevel < 0)
448c18ec02fSPetter Reinholdtsen printf("\n");
449c18ec02fSPetter Reinholdtsen else
450c18ec02fSPetter Reinholdtsen lprintf(loglevel, "");
451c18ec02fSPetter Reinholdtsen }
452c18ec02fSPetter Reinholdtsen
453c18ec02fSPetter Reinholdtsen /* print_valstr_2col - print value string list in two columns to log or stdout
454c18ec02fSPetter Reinholdtsen *
455c18ec02fSPetter Reinholdtsen * @vs: value string list to print
456c18ec02fSPetter Reinholdtsen * @title: name of this value string list
457c18ec02fSPetter Reinholdtsen * @loglevel: what log level to print, -1 for stdout
458c18ec02fSPetter Reinholdtsen */
459c18ec02fSPetter Reinholdtsen void
print_valstr_2col(const struct valstr * vs,const char * title,int loglevel)460c18ec02fSPetter Reinholdtsen print_valstr_2col(const struct valstr * vs, const char * title, int loglevel)
461c18ec02fSPetter Reinholdtsen {
462c18ec02fSPetter Reinholdtsen int i;
463c18ec02fSPetter Reinholdtsen
464c18ec02fSPetter Reinholdtsen if (vs == NULL)
465c18ec02fSPetter Reinholdtsen return;
466c18ec02fSPetter Reinholdtsen
467c18ec02fSPetter Reinholdtsen if (title != NULL) {
468c18ec02fSPetter Reinholdtsen if (loglevel < 0)
469c18ec02fSPetter Reinholdtsen printf("\n%s:\n\n", title);
470c18ec02fSPetter Reinholdtsen else
471c18ec02fSPetter Reinholdtsen lprintf(loglevel, "\n%s:\n", title);
472c18ec02fSPetter Reinholdtsen }
473c18ec02fSPetter Reinholdtsen
474c18ec02fSPetter Reinholdtsen for (i = 0; vs[i].str != NULL; i++) {
475c18ec02fSPetter Reinholdtsen if (vs[i+1].str == NULL) {
476c18ec02fSPetter Reinholdtsen /* last one */
477c18ec02fSPetter Reinholdtsen if (loglevel < 0) {
478c18ec02fSPetter Reinholdtsen printf(" %4d %-32s\n", vs[i].val, vs[i].str);
479c18ec02fSPetter Reinholdtsen } else {
480c18ec02fSPetter Reinholdtsen lprintf(loglevel, " %4d %-32s\n", vs[i].val, vs[i].str);
481c18ec02fSPetter Reinholdtsen }
482c18ec02fSPetter Reinholdtsen }
483c18ec02fSPetter Reinholdtsen else {
484c18ec02fSPetter Reinholdtsen if (loglevel < 0) {
485c18ec02fSPetter Reinholdtsen printf(" %4d %-32s %4d %-32s\n",
486c18ec02fSPetter Reinholdtsen vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
487c18ec02fSPetter Reinholdtsen } else {
488c18ec02fSPetter Reinholdtsen lprintf(loglevel, " %4d %-32s %4d %-32s\n",
489c18ec02fSPetter Reinholdtsen vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
490c18ec02fSPetter Reinholdtsen }
491c18ec02fSPetter Reinholdtsen i++;
492c18ec02fSPetter Reinholdtsen }
493c18ec02fSPetter Reinholdtsen }
494c18ec02fSPetter Reinholdtsen
495c18ec02fSPetter Reinholdtsen if (loglevel < 0)
496c18ec02fSPetter Reinholdtsen printf("\n");
497c18ec02fSPetter Reinholdtsen else
498c18ec02fSPetter Reinholdtsen lprintf(loglevel, "");
499c18ec02fSPetter Reinholdtsen }
500c18ec02fSPetter Reinholdtsen
501c18ec02fSPetter Reinholdtsen /* ipmi_csum - calculate an ipmi checksum
502c18ec02fSPetter Reinholdtsen *
503c18ec02fSPetter Reinholdtsen * @d: buffer to check
504c18ec02fSPetter Reinholdtsen * @s: position in buffer to start checksum from
505c18ec02fSPetter Reinholdtsen */
506c18ec02fSPetter Reinholdtsen uint8_t
ipmi_csum(uint8_t * d,int s)507c18ec02fSPetter Reinholdtsen ipmi_csum(uint8_t * d, int s)
508c18ec02fSPetter Reinholdtsen {
509c18ec02fSPetter Reinholdtsen uint8_t c = 0;
510c18ec02fSPetter Reinholdtsen for (; s > 0; s--, d++)
511c18ec02fSPetter Reinholdtsen c += *d;
512c18ec02fSPetter Reinholdtsen return -c;
513c18ec02fSPetter Reinholdtsen }
514c18ec02fSPetter Reinholdtsen
515c18ec02fSPetter Reinholdtsen /* ipmi_open_file - safely open a file for reading or writing
516c18ec02fSPetter Reinholdtsen *
517c18ec02fSPetter Reinholdtsen * @file: filename
518c18ec02fSPetter Reinholdtsen * @rw: read-write flag, 1=write
519c18ec02fSPetter Reinholdtsen *
520c18ec02fSPetter Reinholdtsen * returns pointer to file handler on success
521c18ec02fSPetter Reinholdtsen * returns NULL on error
522c18ec02fSPetter Reinholdtsen */
523c18ec02fSPetter Reinholdtsen FILE *
ipmi_open_file(const char * file,int rw)524c18ec02fSPetter Reinholdtsen ipmi_open_file(const char * file, int rw)
525c18ec02fSPetter Reinholdtsen {
526c18ec02fSPetter Reinholdtsen struct stat st1, st2;
527c18ec02fSPetter Reinholdtsen FILE * fp;
528c18ec02fSPetter Reinholdtsen
529c18ec02fSPetter Reinholdtsen /* verify existance */
530c18ec02fSPetter Reinholdtsen if (lstat(file, &st1) < 0) {
531c18ec02fSPetter Reinholdtsen if (rw) {
532c18ec02fSPetter Reinholdtsen /* does not exist, ok to create */
533c18ec02fSPetter Reinholdtsen fp = fopen(file, "w");
534c18ec02fSPetter Reinholdtsen if (fp == NULL) {
535c18ec02fSPetter Reinholdtsen lperror(LOG_ERR, "Unable to open file %s "
536c18ec02fSPetter Reinholdtsen "for write", file);
537c18ec02fSPetter Reinholdtsen return NULL;
538c18ec02fSPetter Reinholdtsen }
539c18ec02fSPetter Reinholdtsen /* created ok, now return the descriptor */
540c18ec02fSPetter Reinholdtsen return fp;
541c18ec02fSPetter Reinholdtsen } else {
542c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "File %s does not exist", file);
543c18ec02fSPetter Reinholdtsen return NULL;
544c18ec02fSPetter Reinholdtsen }
545c18ec02fSPetter Reinholdtsen }
546c18ec02fSPetter Reinholdtsen
547c18ec02fSPetter Reinholdtsen #ifndef ENABLE_FILE_SECURITY
548c18ec02fSPetter Reinholdtsen if (!rw) {
549c18ec02fSPetter Reinholdtsen /* on read skip the extra checks */
550c18ec02fSPetter Reinholdtsen fp = fopen(file, "r");
551c18ec02fSPetter Reinholdtsen if (fp == NULL) {
552c18ec02fSPetter Reinholdtsen lperror(LOG_ERR, "Unable to open file %s", file);
553c18ec02fSPetter Reinholdtsen return NULL;
554c18ec02fSPetter Reinholdtsen }
555c18ec02fSPetter Reinholdtsen return fp;
556c18ec02fSPetter Reinholdtsen }
557c18ec02fSPetter Reinholdtsen #endif
558c18ec02fSPetter Reinholdtsen
559c18ec02fSPetter Reinholdtsen /* it exists - only regular files, not links */
560c18ec02fSPetter Reinholdtsen if (S_ISREG(st1.st_mode) == 0) {
561c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "File %s has invalid mode: %d",
562c18ec02fSPetter Reinholdtsen file, st1.st_mode);
563c18ec02fSPetter Reinholdtsen return NULL;
564c18ec02fSPetter Reinholdtsen }
565c18ec02fSPetter Reinholdtsen
566c18ec02fSPetter Reinholdtsen /* allow only files with 1 link (itself) */
567c18ec02fSPetter Reinholdtsen if (st1.st_nlink != 1) {
568c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
569c18ec02fSPetter Reinholdtsen file, (int)st1.st_nlink);
570c18ec02fSPetter Reinholdtsen return NULL;
571c18ec02fSPetter Reinholdtsen }
572c18ec02fSPetter Reinholdtsen
573c18ec02fSPetter Reinholdtsen fp = fopen(file, rw ? "w+" : "r");
574c18ec02fSPetter Reinholdtsen if (fp == NULL) {
575c18ec02fSPetter Reinholdtsen lperror(LOG_ERR, "Unable to open file %s", file);
576c18ec02fSPetter Reinholdtsen return NULL;
577c18ec02fSPetter Reinholdtsen }
578c18ec02fSPetter Reinholdtsen
579c18ec02fSPetter Reinholdtsen /* stat again */
580c18ec02fSPetter Reinholdtsen if (fstat(fileno(fp), &st2) < 0) {
581c18ec02fSPetter Reinholdtsen lperror(LOG_ERR, "Unable to stat file %s", file);
582c18ec02fSPetter Reinholdtsen fclose(fp);
583c18ec02fSPetter Reinholdtsen return NULL;
584c18ec02fSPetter Reinholdtsen }
585c18ec02fSPetter Reinholdtsen
586c18ec02fSPetter Reinholdtsen /* verify inode */
587c18ec02fSPetter Reinholdtsen if (st1.st_ino != st2.st_ino) {
588c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "File %s has invalid inode: %d != %d",
589c18ec02fSPetter Reinholdtsen file, st1.st_ino, st2.st_ino);
590c18ec02fSPetter Reinholdtsen fclose(fp);
591c18ec02fSPetter Reinholdtsen return NULL;
592c18ec02fSPetter Reinholdtsen }
593c18ec02fSPetter Reinholdtsen
594c18ec02fSPetter Reinholdtsen /* verify owner */
595c18ec02fSPetter Reinholdtsen if (st1.st_uid != st2.st_uid) {
596c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "File %s has invalid user id: %d != %d",
597c18ec02fSPetter Reinholdtsen file, st1.st_uid, st2.st_uid);
598c18ec02fSPetter Reinholdtsen fclose(fp);
599c18ec02fSPetter Reinholdtsen return NULL;
600c18ec02fSPetter Reinholdtsen }
601c18ec02fSPetter Reinholdtsen
602c18ec02fSPetter Reinholdtsen /* verify inode */
603c18ec02fSPetter Reinholdtsen if (st2.st_nlink != 1) {
604c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
605c18ec02fSPetter Reinholdtsen file, st2.st_nlink);
606c18ec02fSPetter Reinholdtsen fclose(fp);
607c18ec02fSPetter Reinholdtsen return NULL;
608c18ec02fSPetter Reinholdtsen }
609c18ec02fSPetter Reinholdtsen
610c18ec02fSPetter Reinholdtsen return fp;
611c18ec02fSPetter Reinholdtsen }
612c18ec02fSPetter Reinholdtsen
613c18ec02fSPetter Reinholdtsen void
ipmi_start_daemon(struct ipmi_intf * intf)614c18ec02fSPetter Reinholdtsen ipmi_start_daemon(struct ipmi_intf *intf)
615c18ec02fSPetter Reinholdtsen {
616c18ec02fSPetter Reinholdtsen pid_t pid;
617c18ec02fSPetter Reinholdtsen int fd;
618c18ec02fSPetter Reinholdtsen #ifdef SIGHUP
619c18ec02fSPetter Reinholdtsen sigset_t sighup;
620c18ec02fSPetter Reinholdtsen #endif
621c18ec02fSPetter Reinholdtsen
622c18ec02fSPetter Reinholdtsen #ifdef SIGHUP
623c18ec02fSPetter Reinholdtsen sigemptyset(&sighup);
624c18ec02fSPetter Reinholdtsen sigaddset(&sighup, SIGHUP);
625c18ec02fSPetter Reinholdtsen if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
626c18ec02fSPetter Reinholdtsen fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
627c18ec02fSPetter Reinholdtsen signal(SIGHUP, SIG_IGN);
628c18ec02fSPetter Reinholdtsen #endif
629c18ec02fSPetter Reinholdtsen #ifdef SIGTTOU
630c18ec02fSPetter Reinholdtsen signal(SIGTTOU, SIG_IGN);
631c18ec02fSPetter Reinholdtsen #endif
632c18ec02fSPetter Reinholdtsen #ifdef SIGTTIN
633c18ec02fSPetter Reinholdtsen signal(SIGTTIN, SIG_IGN);
634c18ec02fSPetter Reinholdtsen #endif
635c18ec02fSPetter Reinholdtsen #ifdef SIGQUIT
636c18ec02fSPetter Reinholdtsen signal(SIGQUIT, SIG_IGN);
637c18ec02fSPetter Reinholdtsen #endif
638c18ec02fSPetter Reinholdtsen #ifdef SIGTSTP
639c18ec02fSPetter Reinholdtsen signal(SIGTSTP, SIG_IGN);
640c18ec02fSPetter Reinholdtsen #endif
641c18ec02fSPetter Reinholdtsen
642c18ec02fSPetter Reinholdtsen pid = (pid_t) fork();
643c18ec02fSPetter Reinholdtsen if (pid < 0 || pid > 0)
644c18ec02fSPetter Reinholdtsen exit(0);
645c18ec02fSPetter Reinholdtsen
646c18ec02fSPetter Reinholdtsen #if defined(SIGTSTP) && defined(TIOCNOTTY)
647c18ec02fSPetter Reinholdtsen if (setpgid(0, getpid()) == -1)
648c18ec02fSPetter Reinholdtsen exit(1);
649c18ec02fSPetter Reinholdtsen if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
650c18ec02fSPetter Reinholdtsen ioctl(fd, TIOCNOTTY, NULL);
651c18ec02fSPetter Reinholdtsen close(fd);
652c18ec02fSPetter Reinholdtsen }
653c18ec02fSPetter Reinholdtsen #else
654c18ec02fSPetter Reinholdtsen if (setpgid(0, 0) == -1)
655c18ec02fSPetter Reinholdtsen exit(1);
656c18ec02fSPetter Reinholdtsen pid = (pid_t) fork();
657c18ec02fSPetter Reinholdtsen if (pid < 0 || pid > 0)
658c18ec02fSPetter Reinholdtsen exit(0);
659c18ec02fSPetter Reinholdtsen #endif
660c18ec02fSPetter Reinholdtsen
661c18ec02fSPetter Reinholdtsen chdir("/");
662c18ec02fSPetter Reinholdtsen umask(0);
663c18ec02fSPetter Reinholdtsen
664c18ec02fSPetter Reinholdtsen for (fd=0; fd<64; fd++) {
665c18ec02fSPetter Reinholdtsen if (fd != intf->fd)
666c18ec02fSPetter Reinholdtsen close(fd);
667c18ec02fSPetter Reinholdtsen }
668c18ec02fSPetter Reinholdtsen
669c18ec02fSPetter Reinholdtsen fd = open("/dev/null", O_RDWR);
670c18ec02fSPetter Reinholdtsen assert(0 == fd);
671c18ec02fSPetter Reinholdtsen dup(fd);
672c18ec02fSPetter Reinholdtsen dup(fd);
673c18ec02fSPetter Reinholdtsen }
674c18ec02fSPetter Reinholdtsen
675bb35d370SZdenek Styblik /* eval_ccode - evaluate return value of _ipmi_* functions and print error error
676bb35d370SZdenek Styblik * message, if conditions are met.
677bb35d370SZdenek Styblik *
678bb35d370SZdenek Styblik * @ccode - return value of _ipmi_* function.
679bb35d370SZdenek Styblik *
680bb35d370SZdenek Styblik * returns - 0 if ccode is 0, otherwise (-1) and error might get printed-out.
681bb35d370SZdenek Styblik */
682bb35d370SZdenek Styblik int
eval_ccode(const int ccode)683bb35d370SZdenek Styblik eval_ccode(const int ccode)
684bb35d370SZdenek Styblik {
685bb35d370SZdenek Styblik if (ccode == 0) {
686bb35d370SZdenek Styblik return 0;
687bb35d370SZdenek Styblik } else if (ccode < 0) {
688bb35d370SZdenek Styblik switch (ccode) {
689bb35d370SZdenek Styblik case (-1):
690bb35d370SZdenek Styblik lprintf(LOG_ERR, "IPMI response is NULL.");
691bb35d370SZdenek Styblik break;
692bb35d370SZdenek Styblik case (-2):
693bb35d370SZdenek Styblik lprintf(LOG_ERR, "Unexpected data length received.");
694bb35d370SZdenek Styblik break;
695*b591bc2aSZdenek Styblik case (-3):
696*b591bc2aSZdenek Styblik lprintf(LOG_ERR, "Invalid function parameter.");
697*b591bc2aSZdenek Styblik break;
698*b591bc2aSZdenek Styblik case (-4):
699*b591bc2aSZdenek Styblik lprintf(LOG_ERR, "ipmitool: malloc failure.");
700*b591bc2aSZdenek Styblik break;
701bb35d370SZdenek Styblik default:
702bb35d370SZdenek Styblik break;
703bb35d370SZdenek Styblik }
704bb35d370SZdenek Styblik return (-1);
705bb35d370SZdenek Styblik } else {
706bb35d370SZdenek Styblik lprintf(LOG_ERR, "IPMI command failed: %s",
707bb35d370SZdenek Styblik val2str(ccode, completion_code_vals));
708bb35d370SZdenek Styblik return (-1);
709bb35d370SZdenek Styblik }
710bb35d370SZdenek Styblik }
711bb35d370SZdenek Styblik
712c18ec02fSPetter Reinholdtsen /* is_fru_id - wrapper for str-2-int FRU ID conversion. Message is printed
713c18ec02fSPetter Reinholdtsen * on error.
714c18ec02fSPetter Reinholdtsen * FRU ID range: <0..255>
715c18ec02fSPetter Reinholdtsen *
716c18ec02fSPetter Reinholdtsen * @argv_ptr: source string to convert from; usually argv
717c18ec02fSPetter Reinholdtsen * @fru_id_ptr: pointer where to store result
718c18ec02fSPetter Reinholdtsen *
719c18ec02fSPetter Reinholdtsen * returns zero on success
720c18ec02fSPetter Reinholdtsen * returns (-1) on error and message is printed on STDERR
721c18ec02fSPetter Reinholdtsen */
722c18ec02fSPetter Reinholdtsen int
is_fru_id(const char * argv_ptr,uint8_t * fru_id_ptr)723c18ec02fSPetter Reinholdtsen is_fru_id(const char *argv_ptr, uint8_t *fru_id_ptr)
724c18ec02fSPetter Reinholdtsen {
725c18ec02fSPetter Reinholdtsen if (!argv_ptr || !fru_id_ptr) {
726c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "is_fru_id(): invalid argument(s).");
727c18ec02fSPetter Reinholdtsen return (-1);
728c18ec02fSPetter Reinholdtsen }
729c18ec02fSPetter Reinholdtsen
730c18ec02fSPetter Reinholdtsen if (str2uchar(argv_ptr, fru_id_ptr) == 0) {
731c18ec02fSPetter Reinholdtsen return 0;
732c18ec02fSPetter Reinholdtsen }
733c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "FRU ID '%s' is either invalid or out of range.",
734c18ec02fSPetter Reinholdtsen argv_ptr);
735c18ec02fSPetter Reinholdtsen return (-1);
736c18ec02fSPetter Reinholdtsen } /* is_fru_id(...) */
737c18ec02fSPetter Reinholdtsen
738c18ec02fSPetter Reinholdtsen /* is_ipmi_channel_num - wrapper for str-2-int Channel conversion. Message is
739c18ec02fSPetter Reinholdtsen * printed on error.
740c18ec02fSPetter Reinholdtsen *
7417cd86aafSZdenek Styblik * 6.3 Channel Numbers, p. 49, IPMIv2 spec. rev1.1
7427cd86aafSZdenek Styblik * Valid channel numbers are: <0x0..0xB>, <0xE-0xF>
7437cd86aafSZdenek Styblik * Reserved channel numbers: <0xC-0xD>
744c18ec02fSPetter Reinholdtsen *
745c18ec02fSPetter Reinholdtsen * @argv_ptr: source string to convert from; usually argv
746c18ec02fSPetter Reinholdtsen * @channel_ptr: pointer where to store result
747c18ec02fSPetter Reinholdtsen *
748c18ec02fSPetter Reinholdtsen * returns zero on success
749c18ec02fSPetter Reinholdtsen * returns (-1) on error and message is printed on STDERR
750c18ec02fSPetter Reinholdtsen */
751c18ec02fSPetter Reinholdtsen int
is_ipmi_channel_num(const char * argv_ptr,uint8_t * channel_ptr)752c18ec02fSPetter Reinholdtsen is_ipmi_channel_num(const char *argv_ptr, uint8_t *channel_ptr)
753c18ec02fSPetter Reinholdtsen {
754c18ec02fSPetter Reinholdtsen if (!argv_ptr || !channel_ptr) {
755c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR,
756c18ec02fSPetter Reinholdtsen "is_ipmi_channel_num(): invalid argument(s).");
757c18ec02fSPetter Reinholdtsen return (-1);
758c18ec02fSPetter Reinholdtsen }
759c18ec02fSPetter Reinholdtsen if ((str2uchar(argv_ptr, channel_ptr) == 0)
760148d0e09SZdenek Styblik && (*channel_ptr <= 0xB
761c18ec02fSPetter Reinholdtsen || (*channel_ptr >= 0xE && *channel_ptr <= 0xF))) {
762c18ec02fSPetter Reinholdtsen return 0;
763c18ec02fSPetter Reinholdtsen }
764c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR,
765c18ec02fSPetter Reinholdtsen "Given Channel number '%s' is either invalid or out of range.",
766c18ec02fSPetter Reinholdtsen argv_ptr);
7677cd86aafSZdenek Styblik lprintf(LOG_ERR, "Channel number must be from ranges: <0x0..0xB>, <0xE..0xF>");
768c18ec02fSPetter Reinholdtsen return (-1);
769c18ec02fSPetter Reinholdtsen }
770c18ec02fSPetter Reinholdtsen
771c18ec02fSPetter Reinholdtsen /* is_ipmi_user_id() - wrapper for str-2-uint IPMI UID conversion. Message is
772c18ec02fSPetter Reinholdtsen * printed on error.
773c18ec02fSPetter Reinholdtsen *
774c18ec02fSPetter Reinholdtsen * @argv_ptr: source string to convert from; usually argv
775c18ec02fSPetter Reinholdtsen * @ipmi_uid_ptr: pointer where to store result
776c18ec02fSPetter Reinholdtsen *
777c18ec02fSPetter Reinholdtsen * returns zero on success
778c18ec02fSPetter Reinholdtsen * returns (-1) on error and message is printed on STDERR
779c18ec02fSPetter Reinholdtsen */
780c18ec02fSPetter Reinholdtsen int
is_ipmi_user_id(const char * argv_ptr,uint8_t * ipmi_uid_ptr)781c18ec02fSPetter Reinholdtsen is_ipmi_user_id(const char *argv_ptr, uint8_t *ipmi_uid_ptr)
782c18ec02fSPetter Reinholdtsen {
783c18ec02fSPetter Reinholdtsen if (!argv_ptr || !ipmi_uid_ptr) {
784c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR,
785c18ec02fSPetter Reinholdtsen "is_ipmi_user_id(): invalid argument(s).");
786c18ec02fSPetter Reinholdtsen return (-1);
787c18ec02fSPetter Reinholdtsen }
788c18ec02fSPetter Reinholdtsen if ((str2uchar(argv_ptr, ipmi_uid_ptr) == 0)
789c18ec02fSPetter Reinholdtsen && *ipmi_uid_ptr >= IPMI_UID_MIN
790c18ec02fSPetter Reinholdtsen && *ipmi_uid_ptr <= IPMI_UID_MAX) {
791c18ec02fSPetter Reinholdtsen return 0;
792c18ec02fSPetter Reinholdtsen }
793c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR,
794c18ec02fSPetter Reinholdtsen "Given User ID '%s' is either invalid or out of range.",
795c18ec02fSPetter Reinholdtsen argv_ptr);
796c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "User ID is limited to range <%i..%i>.",
797c18ec02fSPetter Reinholdtsen IPMI_UID_MIN, IPMI_UID_MAX);
798c18ec02fSPetter Reinholdtsen return (-1);
799c18ec02fSPetter Reinholdtsen }
800c18ec02fSPetter Reinholdtsen
8016e6a04f9SZdenek Styblik /* is_ipmi_user_priv_limit - check whether given value is valid User Privilege
8026e6a04f9SZdenek Styblik * Limit, eg. IPMI v2 spec, 22.27 Get User Access Command.
8036e6a04f9SZdenek Styblik *
8046e6a04f9SZdenek Styblik * @priv_limit: User Privilege Limit
8056e6a04f9SZdenek Styblik *
8066e6a04f9SZdenek Styblik * returns 0 if Priv Limit is valid
8076e6a04f9SZdenek Styblik * returns (-1) when Priv Limit is invalid
8086e6a04f9SZdenek Styblik */
8096e6a04f9SZdenek Styblik int
is_ipmi_user_priv_limit(const char * argv_ptr,uint8_t * ipmi_priv_limit_ptr)810140add9dSZdenek Styblik is_ipmi_user_priv_limit(const char *argv_ptr, uint8_t *ipmi_priv_limit_ptr)
8116e6a04f9SZdenek Styblik {
812140add9dSZdenek Styblik if (!argv_ptr || !ipmi_priv_limit_ptr) {
813140add9dSZdenek Styblik lprintf(LOG_ERR,
814140add9dSZdenek Styblik "is_ipmi_user_priv_limit(): invalid argument(s).");
8156e6a04f9SZdenek Styblik return (-1);
8166e6a04f9SZdenek Styblik }
817140add9dSZdenek Styblik if ((str2uchar(argv_ptr, ipmi_priv_limit_ptr) != 0)
818140add9dSZdenek Styblik || ((*ipmi_priv_limit_ptr < 0x01
819140add9dSZdenek Styblik || *ipmi_priv_limit_ptr > 0x05)
820140add9dSZdenek Styblik && *ipmi_priv_limit_ptr != 0x0F)) {
821140add9dSZdenek Styblik lprintf(LOG_ERR,
822140add9dSZdenek Styblik "Given Privilege Limit '%s' is invalid.",
823140add9dSZdenek Styblik argv_ptr);
824140add9dSZdenek Styblik lprintf(LOG_ERR,
825140add9dSZdenek Styblik "Privilege Limit is limited to <0x1..0x5> and <0xF>.");
826140add9dSZdenek Styblik return (-1);
827140add9dSZdenek Styblik }
828140add9dSZdenek Styblik return 0;
8296e6a04f9SZdenek Styblik }
8306e6a04f9SZdenek Styblik
831c18ec02fSPetter Reinholdtsen uint16_t
ipmi_get_oem_id(struct ipmi_intf * intf)832c18ec02fSPetter Reinholdtsen ipmi_get_oem_id(struct ipmi_intf *intf)
833c18ec02fSPetter Reinholdtsen {
834c18ec02fSPetter Reinholdtsen /* Execute a Get Board ID command to determine the board */
835c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp;
836c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
837c18ec02fSPetter Reinholdtsen uint16_t oem_id;
838c18ec02fSPetter Reinholdtsen
839c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
840c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_TSOL;
841c18ec02fSPetter Reinholdtsen req.msg.cmd = 0x21;
842c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
843c18ec02fSPetter Reinholdtsen
844c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
845c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
846c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Board ID command failed");
847c18ec02fSPetter Reinholdtsen return 0;
848c18ec02fSPetter Reinholdtsen }
849c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
850c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Board ID command failed: %#x %s",
851c18ec02fSPetter Reinholdtsen rsp->ccode, val2str(rsp->ccode, completion_code_vals));
852c18ec02fSPetter Reinholdtsen return 0;
853c18ec02fSPetter Reinholdtsen }
854c18ec02fSPetter Reinholdtsen oem_id = rsp->data[0] | (rsp->data[1] << 8);
855c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"Board ID: %x", oem_id);
856c18ec02fSPetter Reinholdtsen
857c18ec02fSPetter Reinholdtsen return oem_id;
858c18ec02fSPetter Reinholdtsen }
859