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