xref: /openbmc/ipmitool/lib/helper.c (revision 2d79e69f)
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