| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389 | /* * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. *  * Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. *  * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. *  * This software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */#define _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || \	_XOPEN_SOURCE || _POSIX_SOURCE#include <stdlib.h>#include <string.h>#include <stdio.h>#include <time.h>#include <ipmitool/bswap.h>#include <ipmitool/helper.h>#include <ipmitool/ipmi.h>#include <ipmitool/log.h>#include <ipmitool/ipmi_intf.h>#include <ipmitool/ipmi_strings.h>#include <ipmitool/ipmi_chassis.h>extern int verbose;intipmi_chassis_power_status(struct ipmi_intf * intf){	struct ipmi_rs * rsp;	struct ipmi_rq req;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x1;	req.msg.data_len = 0;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Unable to get Chassis Power Status");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Get Chassis Power Status failed: %s",				val2str(rsp->ccode, completion_code_vals));		return -1;	}	return rsp->data[0] & 1;}static intipmi_chassis_print_power_status(struct ipmi_intf * intf){	int ps = ipmi_chassis_power_status(intf);	if (ps < 0)		return -1;	printf("Chassis Power is %s\n", ps ? "on" : "off");	return 0;}intipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl){	struct ipmi_rs * rsp;	struct ipmi_rq req;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x2;	req.msg.data = &ctl;	req.msg.data_len = 1;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Unable to set Chassis Power Control to %s",				val2str(ctl, ipmi_chassis_power_control_vals));		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Set Chassis Power Control to %s failed: %s",				val2str(ctl, ipmi_chassis_power_control_vals),				val2str(rsp->ccode, completion_code_vals));		return -1;	}	printf("Chassis Power Control: %s\n",			val2str(ctl, ipmi_chassis_power_control_vals));	return 0;}static intipmi_chassis_identify(struct ipmi_intf * intf, char * arg){	struct ipmi_rq req;	struct ipmi_rs * rsp;	int rc = (-3);	struct {		uint8_t interval;		uint8_t force_on;	} identify_data = { .interval = 0, .force_on = 0 };	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x4;	if (arg != NULL) {		if (strncmp(arg, "force", 5) == 0) {			identify_data.force_on = 1;		} else {			if ( (rc = str2uchar(arg, &identify_data.interval)) != 0) {				if (rc == (-2)) {					lprintf(LOG_ERR, "Invalid interval given.");				} else {					lprintf(LOG_ERR, "Given interval is too big.");				}				return (-1);			}		}		req.msg.data = (uint8_t *)&identify_data;		/* The Force Identify On byte is optional and not		 * supported by all devices-- if force is not specified,		 * we pass only one data byte; if specified, we pass two		 * data bytes and check for an error completion code		 */		req.msg.data_len = (identify_data.force_on) ? 2 : 1;	}	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Unable to set Chassis Identify");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Set Chassis Identify failed: %s",				val2str(rsp->ccode, completion_code_vals));		if (identify_data.force_on != 0) {			/* Intel SE7501WV2 F/W 1.2 returns CC 0xC7, but			 * the IPMI v1.5 spec does not standardize a CC			 * if unsupported, so we warn			 */			lprintf(LOG_WARNING, "Chassis may not support Force Identify On\n");		}		return -1;	}	printf("Chassis identify interval: ");	if (arg == NULL) {		printf("default (15 seconds)\n");	} else {		if (identify_data.force_on != 0) {			printf("indefinite\n");		} else {			if (identify_data.interval == 0)				printf("off\n");			else				printf("%i seconds\n", identify_data.interval);		}	}	return 0;}static intipmi_chassis_poh(struct ipmi_intf * intf){	struct ipmi_rs * rsp;	struct ipmi_rq req;	uint8_t mins_per_count;	uint32_t count;	float minutes;	uint32_t days, hours;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0xf;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Unable to get Chassis Power-On-Hours");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Get Chassis Power-On-Hours failed: %s",				val2str(rsp->ccode, completion_code_vals));		return -1;	}	mins_per_count = rsp->data[0];	memcpy(&count, rsp->data+1, 4);#if WORDS_BIGENDIAN	count = BSWAP_32(count);#endif	minutes = (float)count * mins_per_count;	days = minutes / 1440;	minutes -= (float)days * 1440;	hours = minutes / 60;	minutes -= hours * 60;	if (mins_per_count < 60) {		printf("POH Counter  : %i days, %i hours, %li minutes\n",				days, hours, (long)minutes);	} else {		printf("POH Counter  : %i days, %i hours\n", days, hours);	}	return 0;}static intipmi_chassis_restart_cause(struct ipmi_intf * intf){	struct ipmi_rs * rsp;	struct ipmi_rq req;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x7;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Unable to get Chassis Restart Cause");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Get Chassis Restart Cause failed: %s",				val2str(rsp->ccode, completion_code_vals));		return -1;	}	printf("System restart cause: ");	switch (rsp->data[0] & 0xf) {	case 0:		printf("unknown\n");		break;	case 1:		printf("chassis power control command\n");		break;	case 2:		printf("reset via pushbutton\n");		break;	case 3:		printf("power-up via pushbutton\n");		break;	case 4:		printf("watchdog expired\n");		break;	case 5:		printf("OEM\n");		break;	case 6:		printf("power-up due to always-restore power policy\n");		break;	case 7:		printf("power-up due to restore-previous power policy\n");		break;	case 8:		printf("reset via PEF\n");		break;	case 9:		printf("power-cycle via PEF\n");		break;	default:		printf("invalid\n");	}	return 0;}intipmi_chassis_status(struct ipmi_intf * intf){	struct ipmi_rs * rsp;	struct ipmi_rq req;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x1;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Error sending Chassis Status command");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Error sending Chassis Status command: %s",				val2str(rsp->ccode, completion_code_vals));		return -1;	}	/* byte 1 */	printf("System Power         : %s\n", (rsp->data[0] & 0x1) ? "on" : "off");	printf("Power Overload       : %s\n", (rsp->data[0] & 0x2) ? "true" : "false");	printf("Power Interlock      : %s\n", (rsp->data[0] & 0x4) ? "active" : "inactive");	printf("Main Power Fault     : %s\n", (rsp->data[0] & 0x8) ? "true" : "false");	printf("Power Control Fault  : %s\n", (rsp->data[0] & 0x10) ? "true" : "false");	printf("Power Restore Policy : ");	switch ((rsp->data[0] & 0x60) >> 5) {	case 0x0:		printf("always-off\n");		break;	case 0x1:		printf("previous\n");		break;	case 0x2:		printf("always-on\n");		break;	case 0x3:	default:		printf("unknown\n");	}	/* byte 2 */	printf("Last Power Event     : ");	if (rsp->data[1] & 0x1)		printf("ac-failed ");	if (rsp->data[1] & 0x2)		printf("overload ");	if (rsp->data[1] & 0x4)		printf("interlock ");	if (rsp->data[1] & 0x8)		printf("fault ");	if (rsp->data[1] & 0x10)		printf("command");	printf("\n");	/* byte 3 */	printf("Chassis Intrusion    : %s\n", (rsp->data[2] & 0x1) ? "active" : "inactive");	printf("Front-Panel Lockout  : %s\n", (rsp->data[2] & 0x2) ? "active" : "inactive");	printf("Drive Fault          : %s\n", (rsp->data[2] & 0x4) ? "true" : "false");	printf("Cooling/Fan Fault    : %s\n", (rsp->data[2] & 0x8) ? "true" : "false");	if (rsp->data_len > 3) {		/* optional byte 4 */		if (rsp->data[3] == 0) {			printf("Front Panel Control  : none\n");		} else {			printf("Sleep Button Disable : %s\n", (rsp->data[3] & 0x80) ? "allowed" : "not allowed");			printf("Diag Button Disable  : %s\n", (rsp->data[3] & 0x40) ? "allowed" : "not allowed");			printf("Reset Button Disable : %s\n", (rsp->data[3] & 0x20) ? "allowed" : "not allowed");			printf("Power Button Disable : %s\n", (rsp->data[3] & 0x10) ? "allowed" : "not allowed");			printf("Sleep Button Disabled: %s\n", (rsp->data[3] & 0x08) ? "true" : "false");			printf("Diag Button Disabled : %s\n", (rsp->data[3] & 0x04) ? "true" : "false");			printf("Reset Button Disabled: %s\n", (rsp->data[3] & 0x02) ? "true" : "false");			printf("Power Button Disabled: %s\n", (rsp->data[3] & 0x01) ? "true" : "false");		}	}	return 0;}static intipmi_chassis_selftest(struct ipmi_intf * intf){	struct ipmi_rs * rsp;	struct ipmi_rq req;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_APP;	req.msg.cmd = 0x4;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Error sending Get Self Test command");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Error sending Get Self Test command: %s",				val2str(rsp->ccode, completion_code_vals));		return -1;	}	printf("Self Test Results    : ");	switch (rsp->data[0]) {	case 0x55:		printf("passed\n");		break;	case 0x56:		printf("not implemented\n");		break;	case 0x57:	{		int i;		const struct valstr broken_dev_vals[] = {			{ 0, "firmware corrupted" },			{ 1, "boot block corrupted" },			{ 2, "FRU Internal Use Area corrupted" },			{ 3, "SDR Repository empty" },			{ 4, "IPMB not responding" },			{ 5, "cannot access BMC FRU" },			{ 6, "cannot access SDR Repository" },			{ 7, "cannot access SEL Device" },			{ 0xff, NULL },		};		printf("device error\n");		for (i=0; i<8; i++) {			if (rsp->data[1] & (1<<i)) {				printf("                       [%s]\n",						val2str(i, broken_dev_vals));			}		}	}	break;	case 0x58:		printf("Fatal hardware error: %02xh\n", rsp->data[1]);		break;	default:		printf("Device-specific failure %02xh:%02xh\n",				rsp->data[0], rsp->data[1]);		break;	}	return 0;}static intipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * data, int len){	struct ipmi_rs * rsp;	struct ipmi_rq req;	uint8_t msg_data[16];	memset(msg_data, 0, 16);	msg_data[0] = param & 0x7f;	memcpy(msg_data+1, data, len);	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x8;	req.msg.data = msg_data;	req.msg.data_len = len + 1;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Error setting Chassis Boot Parameter %d", param);		return -1;	}	if (rsp->ccode > 0) {		if (param != 0) {			lprintf(LOG_ERR, "Set Chassis Boot Parameter %d failed: %s",					param, val2str(rsp->ccode, completion_code_vals));		}		return -1;	}	lprintf(LOG_DEBUG, "Chassis Set Boot Parameter %d to %s", param, buf2str(data, len));	return 0;}static intipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg){	struct ipmi_rs * rsp;	struct ipmi_rq req;	uint8_t msg_data[3];	uint8_t param_id = 0;	if (arg == NULL)		return -1;	if (str2uchar(arg, ¶m_id) != 0) {		lprintf(LOG_ERR, "Invalid parameter '%s' given instead of bootparam.",				arg);		return (-1);	}	memset(msg_data, 0, 3);	msg_data[0] = param_id & 0x7f;	msg_data[1] = 0;	msg_data[2] = 0;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x9;	req.msg.data = msg_data;	req.msg.data_len = 3;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Error Getting Chassis Boot Parameter %s", arg);		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Get Chassis Boot Parameter %s failed: %s",				arg, val2str(rsp->ccode, completion_code_vals));		return -1;	}	if (verbose > 2)		printbuf(rsp->data, rsp->data_len, "Boot Option");	param_id = 0;	param_id = (rsp->data[1] & 0x7f);	printf("Boot parameter version: %d\n", rsp->data[0]);	printf("Boot parameter %d is %s\n", rsp->data[1] & 0x7f,			(rsp->data[1] & 0x80) ? "invalid/locked" : "valid/unlocked");	printf("Boot parameter data: %s\n", buf2str(rsp->data+2, rsp->data_len - 2));	switch(param_id)	{		case 0:		{			printf(" Set In Progress : ");			switch((rsp->data[2]) &0x03)			{				case 0: printf("set complete\n"); break;				case 1: printf("set in progress\n"); break;				case 2: printf("commit write\n"); break;				default: printf("error, reserved bit\n"); break;			}		}		break;		case 1:		{			printf(" Service Partition Selector : ");			if((rsp->data[2]) == 0)			{				printf("unspecified\n");			}			else			{				printf("%d\n",(rsp->data[2]));			}		}		break;		case 2:		{			printf(   " Service Partition Scan :\n");			if((rsp->data[2]&0x03) != 0)			{				if((rsp->data[2]&0x01) == 0x01)					printf("     - Request BIOS to scan\n");				if((rsp->data[2]&0x02) == 0x02)					printf("     - Service Partition Discovered\n");			}			else			{				printf("     No flag set\n");			}		}		break;		case 3:		{			printf(   " BMC boot flag valid bit clearing :\n");			if((rsp->data[2]&0x1f) != 0)			{				if((rsp->data[2]&0x10) == 0x10)					printf("     - Don't clear valid bit on reset/power cycle cause by PEF\n");				if((rsp->data[2]&0x08) == 0x08)					printf("     - Don't automatically clear boot flag valid bit on timeout\n");				if((rsp->data[2]&0x04) == 0x04)					printf("     - Don't clear valid bit on reset/power cycle cause by watchdog\n");				if((rsp->data[2]&0x02) == 0x02)					printf("     - Don't clear valid bit on push button reset // soft reset\n");				if((rsp->data[2]&0x01) == 0x01)					printf("     - Don't clear valid bit on power up via power push button or wake event\n");			}			else			{				printf("     No flag set\n");			}		}		break;		case 4:		{			printf(   " Boot Info Acknowledge :\n");			if((rsp->data[3]&0x1f) != 0)			{				if((rsp->data[3]&0x10) == 0x10)					printf("    - OEM has handled boot info\n");				if((rsp->data[3]&0x08) == 0x08)					printf("    - SMS has handled boot info\n");				if((rsp->data[3]&0x04) == 0x04)					printf("    - OS // service partition has handled boot info\n");				if((rsp->data[3]&0x02) == 0x02)					printf("    - OS Loader has handled boot info\n");				if((rsp->data[3]&0x01) == 0x01)					printf("    - BIOS/POST has handled boot info\n");			}			else			{				printf("     No flag set\n");			}		}		break;		case 5:		{			printf(   " Boot Flags :\n");			if((rsp->data[2]&0x80) == 0x80)				printf("   - Boot Flag Valid\n");			else				printf("   - Boot Flag Invalid\n");			if((rsp->data[2]&0x40) == 0x40)				printf("   - Options apply to all future boots\n");			else				printf("   - Options apply to only next boot\n");			if((rsp->data[2]&0x20) == 0x20)				printf("   - BIOS EFI boot \n");			else				printf("   - BIOS PC Compatible (legacy) boot \n");			if((rsp->data[3]&0x80) == 0x80)				printf("   - CMOS Clear\n");			if((rsp->data[3]&0x40) == 0x40)				printf("   - Lock Keyboard\n");			printf("   - Boot Device Selector : ");			switch( ((rsp->data[3]>>2)&0x0f))			{				case 0: printf("No override\n"); break;				case 1: printf("Force PXE\n"); break;				case 2: printf("Force Boot from default Hard-Drive\n"); break;				case 3: printf("Force Boot from default Hard-Drive, request Safe-Mode\n"); break;				case 4: printf("Force Boot from Diagnostic Partition\n"); break;				case 5: printf("Force Boot from CD/DVD\n"); break;				case 6: printf("Force Boot into BIOS Setup\n"); break;				case 15: printf("Force Boot from Floppy/primary removable media\n"); break;				default: printf("Flag error\n"); break;			}			if((rsp->data[3]&0x02) == 0x02)				printf("   - Screen blank\n");			if((rsp->data[3]&0x01) == 0x01)				printf("   - Lock out Reset buttons\n");			if((rsp->data[4]&0x80) == 0x80)				printf("   - Lock out (power off/sleep request) vi Power Button\n");			printf("   - Console Redirection control : ");			switch( ((rsp->data[4]>>5)&0x03))			{				case 0: printf("System Default\n"); break;				case 1: printf("Request Quiet Display\n"); break;				case 2: printf("Request Verbose Display\n"); break;				default: printf("Flag error\n"); break;			}			if((rsp->data[4]&0x10) == 0x10)				printf("   - Force progress event traps\n");			if((rsp->data[4]&0x08) == 0x08)				printf("   - User password bypass\n");			if((rsp->data[4]&0x04) == 0x04)				printf("   - Lock Out Sleep Button\n");			if((rsp->data[4]&0x02) == 0x02)				printf("   - Lock Out Sleep Button\n");			printf("   - BIOS verbosity : ");			switch( ((rsp->data[4]>>0)&0x03))			{				case 0: printf("Console redirection occurs per BIOS configuration setting (default)\n"); break;				case 1: printf("Suppress (skip) console redirection if enabled\n"); break;				case 2: printf("Request console redirection be enabled\n"); break;				default: printf("Flag error\n"); break;			}			if((rsp->data[5]&0x08) == 0x08)				printf("   - BIOS Shared Mode Override\n");			printf("   - BIOS Mux Control Override : ");			switch( ((rsp->data[5]>>0)&0x07))			{				case 0: printf("BIOS uses recommended setting of the mux at the end of POST\n"); break;				case 1: printf("Requests BIOS to force mux to BMC at conclusion of POST/start of OS boot\n"); break;				case 2: printf("Requests BIOS to force mux to system at conclusion of POST/start of OS boot\n"); break;				default: printf("Flag error\n"); break;			}		}		break;		case 6:		{			unsigned long session_id;			unsigned long timestamp;			char time_buf[40];			time_t out_time;			session_id  = ((unsigned long) rsp->data[3]);			session_id |= (((unsigned long) rsp->data[4])<<8);			session_id |= (((unsigned long) rsp->data[5])<<16);			session_id |= (((unsigned long) rsp->data[6])<<24);			timestamp  = ((unsigned long) rsp->data[7]);			timestamp |= (((unsigned long) rsp->data[8])<<8);			timestamp |= (((unsigned long) rsp->data[9])<<16);			timestamp |= (((unsigned long) rsp->data[10])<<24);			memset(time_buf, 0, 40);			strftime(					time_buf,					sizeof(time_buf),					"%m/%d/%Y %H:%M:%S", localtime(&out_time)			);			printf(" Boot Initiator Info :\n");			printf("    Channel Number : %d\n", (rsp->data[2] & 0x0f));			printf("    Session Id     : %08lXh\n",session_id);			if(timestamp != 0)			{				printf("    Timestamp      : %08lXh, %s\n",timestamp,time_buf);			}			else			{				printf("    Timestamp      : %08lXh, undefined\n",timestamp);			}		}		break;		case 7:		{			printf(" Selector   : %d\n", rsp->data[2] );			printf(" Block Data : %s\n", buf2str(rsp->data+3, rsp->data_len - 2));		}		break;		default:			printf(" Undefined byte\n");			break;	}	return 0;}static intget_bootparam_options(char *optstring,		unsigned char *set_flag, unsigned char *clr_flag){	char *token;	char *saveptr = NULL;	int optionError = 0;	*set_flag = 0;	*clr_flag = 0;	static struct {		char *name;		unsigned char value;		char *desc;	} options[] = {	{"PEF",          0x10,	    "Clear valid bit on reset/power cycle cause by PEF"},	{"timeout",      0x08,	    "Automatically clear boot flag valid bit on timeout"},	{"watchdog",     0x04,	    "Clear valid bit on reset/power cycle cause by watchdog"},	{"reset",        0x02,	    "Clear valid bit on push button reset/soft reset"},	{"power", 0x01,	    "Clear valid bit on power up via power push button or wake event"},	{NULL}	/* End marker */	}, *op;	if (strncmp(optstring, "options=", 8) != 0) {		lprintf(LOG_ERR, "No options= keyword found \"%s\"", optstring);		return -1;	}	token = strtok_r(optstring + 8, ",", &saveptr);	while (token != NULL) {		int setbit = 0;		if (strcmp(token, "help") == 0) {			optionError = 1;			break;		}		if (strncmp(token, "no-", 3) == 0) {			setbit = 1;			token += 3;		}		for (op = options; op->name != NULL; ++op) {			if (strncmp(token, op->name, strlen(op->name)) == 0) {				if (setbit) {				    *set_flag |= op->value;				} else {				    *clr_flag |= op->value;				}				break;			}		}		if (op->name == NULL) {			/* Option not found */			optionError = 1;			if (setbit) {				token -=3;			}			lprintf(LOG_ERR, "Invalid option: %s", token);		}		token = strtok_r(NULL, ",", &saveptr);	}	if (optionError) {		lprintf(LOG_NOTICE, " Legal options are:");		lprintf(LOG_NOTICE, "  %-8s: print this message", "help");		for (op = options; op->name != NULL; ++op) {			lprintf(LOG_NOTICE, "  %-8s: %s", op->name, op->desc);		}		lprintf(LOG_NOTICE, " Any Option may be prepended with no-"				    " to invert sense of operation\n");		return (-1);	}	return (0);}static intipmi_chassis_get_bootvalid(struct ipmi_intf * intf){	struct ipmi_rs * rsp;	struct ipmi_rq req;	uint8_t msg_data[3];	uint8_t param_id = IPMI_CHASSIS_BOOTPARAM_FLAG_VALID;	memset(msg_data, 0, 3);	msg_data[0] = param_id & 0x7f;	msg_data[1] = 0;	msg_data[2] = 0;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x9;	req.msg.data = msg_data;	req.msg.data_len = 3;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR,			"Error Getting Chassis Boot Parameter %d", param_id);		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Get Chassis Boot Parameter %d failed: %s",			param_id, val2str(rsp->ccode, completion_code_vals));		return -1;	}	if (verbose > 2)		printbuf(rsp->data, rsp->data_len, "Boot Option");	return(rsp->data[2]);}static intipmi_chassis_set_bootvalid(struct ipmi_intf *intf, uint8_t set_flag, uint8_t clr_flag){	int bootvalid;	uint8_t flags[5];	int rc = 0;	int use_progress = 1;	uint8_t param_id = IPMI_CHASSIS_BOOTPARAM_FLAG_VALID;	if (use_progress) {		/* set set-in-progress flag */		memset(flags, 0, 5);		flags[0] = 0x01;		rc = ipmi_chassis_set_bootparam(intf,				IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);		if (rc < 0)			use_progress = 0;	}	memset(flags, 0, 5);	flags[0] = 0x01;	flags[1] = 0x01;	rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,			flags, 2);	if (rc < 0) {		if (use_progress) {			/* set-in-progress = set-complete */			memset(flags, 0, 5);			ipmi_chassis_set_bootparam(intf,					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,					flags, 1);		}		return -1;	}	bootvalid = ipmi_chassis_get_bootvalid(intf);	if (bootvalid < 0) {		if (use_progress) {			/* set-in-progress = set-complete */			memset(flags, 0, 5);			ipmi_chassis_set_bootparam(intf,					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,					flags, 1);		}		return -1;	}	flags[0] = (bootvalid & ~clr_flag) | set_flag;	rc = ipmi_chassis_set_bootparam(intf, param_id, flags, 1);	if (rc == 0) {		if (use_progress) {			/* set-in-progress = commit-write */			memset(flags, 0, 5);			flags[0] = 0x02;			ipmi_chassis_set_bootparam(intf,					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,					flags, 1);		}	}	if (use_progress) {		/* set-in-progress = set-complete */		memset(flags, 0, 5);		ipmi_chassis_set_bootparam(intf,				IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,				flags, 1);	}	return rc;}static intipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, uint8_t *iflags){	uint8_t flags[5];	int rc = 0;	int use_progress = 1;	if (use_progress) {		/* set set-in-progress flag */		memset(flags, 0, 5);		flags[0] = 0x01;		rc = ipmi_chassis_set_bootparam(intf,				IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);		if (rc < 0)			use_progress = 0;	}	memset(flags, 0, 5);	flags[0] = 0x01;	flags[1] = 0x01;	rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,			flags, 2);	if (rc < 0) {		if (use_progress) {			/* set-in-progress = set-complete */			memset(flags, 0, 5);			ipmi_chassis_set_bootparam(intf,					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,					flags, 1);		}		return -1;	}	if (iflags == NULL)		memset(flags, 0, 5);	else		memcpy(flags, iflags, sizeof (flags));	if (arg == NULL)		flags[1] |= 0x00;	else if (strncmp(arg, "none", 4) == 0)		flags[1] |= 0x00;	else if (strncmp(arg, "pxe", 3) == 0 ||		strncmp(arg, "force_pxe", 9) == 0)		flags[1] |= 0x04;	else if (strncmp(arg, "disk", 4) == 0 ||		strncmp(arg, "force_disk", 10) == 0)		flags[1] |= 0x08;	else if (strncmp(arg, "safe", 4) == 0 ||		strncmp(arg, "force_safe", 10) == 0)		flags[1] |= 0x0c;	else if (strncmp(arg, "diag", 4) == 0 ||		strncmp(arg, "force_diag", 10) == 0)		flags[1] |= 0x10;	else if (strncmp(arg, "cdrom", 5) == 0 ||		strncmp(arg, "force_cdrom", 11) == 0)		flags[1] |= 0x14;	else if (strncmp(arg, "floppy", 6) == 0 ||		strncmp(arg, "force_floppy", 12) == 0)		flags[1] |= 0x3c;	else if (strncmp(arg, "bios", 4) == 0 ||		strncmp(arg, "force_bios", 10) == 0)		flags[1] |= 0x18;	else {		lprintf(LOG_ERR, "Invalid argument: %s", arg);		if (use_progress) {			/* set-in-progress = set-complete */			memset(flags, 0, 5);			ipmi_chassis_set_bootparam(intf,					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,					flags, 1);		}		return -1;	}	/* set flag valid bit */	flags[0] |= 0x80;	rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_BOOT_FLAGS,			flags, 5);	if (rc == 0) {		if (use_progress) {			/* set-in-progress = commit-write */			memset(flags, 0, 5);			flags[0] = 0x02;			ipmi_chassis_set_bootparam(intf,					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,					flags, 1);		}		printf("Set Boot Device to %s\n", arg);	}	if (use_progress) {		/* set-in-progress = set-complete */		memset(flags, 0, 5);		ipmi_chassis_set_bootparam(intf,				IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,				flags, 1);	}	return rc;}static intipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy){	struct ipmi_rs * rsp;	struct ipmi_rq req;	memset(&req, 0, sizeof(req));	req.msg.netfn = IPMI_NETFN_CHASSIS;	req.msg.cmd = 0x6;	req.msg.data = &policy;	req.msg.data_len = 1;	rsp = intf->sendrecv(intf, &req);	if (rsp == NULL) {		lprintf(LOG_ERR, "Error in Power Restore Policy command");		return -1;	}	if (rsp->ccode > 0) {		lprintf(LOG_ERR, "Power Restore Policy command failed: %s",				val2str(rsp->ccode, completion_code_vals));		return -1;	}	if (policy == IPMI_CHASSIS_POLICY_NO_CHANGE) {		printf("Supported chassis power policy:  ");		if (rsp->data[0] & (1<<IPMI_CHASSIS_POLICY_ALWAYS_OFF))			printf("always-off ");		if (rsp->data[0] & (1<<IPMI_CHASSIS_POLICY_ALWAYS_ON))			printf("always-on ");		if (rsp->data[0] & (1<<IPMI_CHASSIS_POLICY_PREVIOUS))			printf("previous");		printf("\n");	}	else {		printf("Set chassis power restore policy to ");		switch (policy) {		case IPMI_CHASSIS_POLICY_ALWAYS_ON:			printf("always-on\n");			break;		case IPMI_CHASSIS_POLICY_ALWAYS_OFF:			printf("always-off\n");			break;		case IPMI_CHASSIS_POLICY_PREVIOUS:			printf("previous\n");			break;		default:			printf("unknown\n");		}	}	return 0;}intipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv){	int rc = 0;	uint8_t ctl = 0;	if ((argc < 1) || (strncmp(argv[0], "help", 4) == 0)) {		lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");		return 0;	}	if (strncmp(argv[0], "status", 6) == 0) {		rc = ipmi_chassis_print_power_status(intf);		return rc;	}	if ((strncmp(argv[0], "up", 2) == 0) || (strncmp(argv[0], "on", 2) == 0))		ctl = IPMI_CHASSIS_CTL_POWER_UP;	else if ((strncmp(argv[0], "down", 4) == 0) || (strncmp(argv[0], "off", 3) == 0))		ctl = IPMI_CHASSIS_CTL_POWER_DOWN;	else if (strncmp(argv[0], "cycle", 5) == 0)		ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;	else if (strncmp(argv[0], "reset", 5) == 0)		ctl = IPMI_CHASSIS_CTL_HARD_RESET;	else if (strncmp(argv[0], "diag", 4) == 0)		ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;	else if ((strncmp(argv[0], "acpi", 4) == 0) || (strncmp(argv[0], "soft", 4) == 0))		ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;	else {		lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[0]);		return -1;	}	rc = ipmi_chassis_power_control(intf, ctl);	return rc;}voidipmi_chassis_set_bootflag_help(){	unsigned char set_flag;	unsigned char clr_flag;	lprintf(LOG_NOTICE, "bootparam set bootflag <device> [options=...]");	lprintf(LOG_NOTICE, " Legal devices are:");	lprintf(LOG_NOTICE, "  none        : No override");	lprintf(LOG_NOTICE, "  force_pxe   : Force PXE boot");	lprintf(LOG_NOTICE, "  force_disk  : Force boot from default Hard-drive");	lprintf(LOG_NOTICE, "  force_safe  : Force boot from default Hard-drive, request Safe Mode");	lprintf(LOG_NOTICE, "  force_diag  : Force boot from Diagnostic Partition");	lprintf(LOG_NOTICE, "  force_cdrom : Force boot from CD/DVD");	lprintf(LOG_NOTICE, "  force_bios  : Force boot into BIOS Setup");	get_bootparam_options("options=help", &set_flag, &clr_flag);}intipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv){	int rc = 0;	if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {		lprintf(LOG_NOTICE, "Chassis Commands:  status, power, identify, policy, restart_cause, poh, bootdev, bootparam, selftest");	}	else if (strncmp(argv[0], "status", 6) == 0) {		rc = ipmi_chassis_status(intf);	}	else if (strncmp(argv[0], "selftest", 8) == 0) {		rc = ipmi_chassis_selftest(intf);	}	else if (strncmp(argv[0], "power", 5) == 0) {		uint8_t ctl = 0;		if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {			lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");			return 0;		}		if (strncmp(argv[1], "status", 6) == 0) {			rc = ipmi_chassis_print_power_status(intf);			return rc;		}		if ((strncmp(argv[1], "up", 2) == 0) || (strncmp(argv[1], "on", 2) == 0))			ctl = IPMI_CHASSIS_CTL_POWER_UP;		else if ((strncmp(argv[1], "down", 4) == 0) || (strncmp(argv[1], "off", 3) == 0))			ctl = IPMI_CHASSIS_CTL_POWER_DOWN;		else if (strncmp(argv[1], "cycle", 5) == 0)			ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;		else if (strncmp(argv[1], "reset", 5) == 0)			ctl = IPMI_CHASSIS_CTL_HARD_RESET;		else if (strncmp(argv[1], "diag", 4) == 0)			ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;		else if ((strncmp(argv[1], "acpi", 4) == 0) || (strncmp(argv[1], "soft", 4) == 0))			ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;		else {			lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[1]);			return -1;		}		rc = ipmi_chassis_power_control(intf, ctl);	}	else if (strncmp(argv[0], "identify", 8) == 0) {		if (argc < 2) {			rc = ipmi_chassis_identify(intf, NULL);		}		else if (strncmp(argv[1], "help", 4) == 0) {			lprintf(LOG_NOTICE, "chassis identify <interval>");			lprintf(LOG_NOTICE, "                 default is 15 seconds");			lprintf(LOG_NOTICE, "                 0 to turn off");			lprintf(LOG_NOTICE, "                 force to turn on indefinitely");		} else {			rc = ipmi_chassis_identify(intf, argv[1]);		}	}	else if (strncmp(argv[0], "poh", 3) == 0) {		rc = ipmi_chassis_poh(intf);	}	else if (strncmp(argv[0], "restart_cause", 13) == 0) {		rc = ipmi_chassis_restart_cause(intf);	}	else if (strncmp(argv[0], "policy", 4) == 0) {		if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {			lprintf(LOG_NOTICE, "chassis policy <state>");			lprintf(LOG_NOTICE, "   list        : return supported policies");			lprintf(LOG_NOTICE, "   always-on   : turn on when power is restored");			lprintf(LOG_NOTICE, "   previous    : return to previous state when power is restored");			lprintf(LOG_NOTICE, "   always-off  : stay off after power is restored");		} else {			uint8_t ctl;			if (strncmp(argv[1], "list", 4) == 0)				ctl = IPMI_CHASSIS_POLICY_NO_CHANGE;			else if (strncmp(argv[1], "always-on", 9) == 0)				ctl = IPMI_CHASSIS_POLICY_ALWAYS_ON;			else if (strncmp(argv[1], "previous", 8) == 0)				ctl = IPMI_CHASSIS_POLICY_PREVIOUS;			else if (strncmp(argv[1], "always-off", 10) == 0)				ctl = IPMI_CHASSIS_POLICY_ALWAYS_OFF;			else {				lprintf(LOG_ERR, "Invalid chassis policy: %s", argv[1]);				return -1;			}			rc = ipmi_chassis_power_policy(intf, ctl);		}	}	else if (strncmp(argv[0], "bootparam", 9) == 0) {		if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) {			lprintf(LOG_NOTICE, "bootparam get <param #>");		    ipmi_chassis_set_bootflag_help();		}		else {			if (strncmp(argv[1], "get", 3) == 0) {				rc = ipmi_chassis_get_bootparam(intf, argv[2]);			}			else if (strncmp(argv[1], "set", 3) == 0) {			    unsigned char set_flag=0;			    unsigned char clr_flag=0;				if (strncmp(argv[2], "help", 4) == 0  ||						argc < 4 || (argc >= 4 &&							 strncmp(argv[2], "bootflag", 8) != 0)) {					ipmi_chassis_set_bootflag_help();				} else {					if (argc == 5) {						get_bootparam_options(argv[4], &set_flag, &clr_flag);					}					rc = ipmi_chassis_set_bootdev(intf, argv[3], NULL);					if (argc == 5 && (set_flag != 0 || clr_flag != 0)) {						rc = ipmi_chassis_set_bootvalid(intf, set_flag, clr_flag);					}				}			}			else				lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]");		}	}	else if (strncmp(argv[0], "bootdev", 7) == 0) {		if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {			lprintf(LOG_NOTICE, "bootdev <device> [clear-cmos=yes|no]");			lprintf(LOG_NOTICE, "bootdev <device> [options=help,...]");			lprintf(LOG_NOTICE, "  none  : Do not change boot device order");			lprintf(LOG_NOTICE, "  pxe   : Force PXE boot");			lprintf(LOG_NOTICE, "  disk  : Force boot from default Hard-drive");			lprintf(LOG_NOTICE, "  safe  : Force boot from default Hard-drive, request Safe Mode");			lprintf(LOG_NOTICE, "  diag  : Force boot from Diagnostic Partition");			lprintf(LOG_NOTICE, "  cdrom : Force boot from CD/DVD");			lprintf(LOG_NOTICE, "  bios  : Force boot into BIOS Setup");			lprintf(LOG_NOTICE, "  floppy: Force boot from Floppy/primary removable media");		} else {			if (argc < 3)				rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);			else if (strncmp(argv[2], "clear-cmos=", 11) == 0) {				if (strncmp(argv[2]+11, "yes", 3) == 0) {					uint8_t flags[5] = {0, (1<<7), 0, 0, 0};					rc = ipmi_chassis_set_bootdev(intf, argv[1], flags);				} else					rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);			}			else if (strncmp(argv[2], "options=", 8) == 0) {				char *token;				char *saveptr = NULL;				int optionError = 0;				unsigned char flags[5];				static struct {					char *name;					int i;					unsigned char mask;					unsigned char value;					char *desc;				} options[] = {					/* data 1 */					{"valid", 0, (1<<7), (1<<7),						"Boot flags valid"},					{"persistent", 0, (1<<6), (1<<6),						"Changes are persistent for all future boots"},					{"efiboot", 0, (1<<5), (1<<5),						"Extensible Firmware Interface Boot (EFI)"},					/* data 2 */					{"clear-cmos", 1, (1<<7), (1<<7),						"CMOS clear"},					{"lockkbd", 1, (1<<6), (1<<6),						"Lock Keyboard"},					/* data2[5:2] is parsed elsewhere */					{"screenblank", 1, (1<<1), (1<<1),						"Screen Blank"},					{"lockoutreset", 1, (1<<0), (1<<0),						"Lock out Resetbuttons"},					/* data 3 */					{"lockout_power", 2, (1<<7), (1<<7),						"Lock out (power off/sleep request) via Power Button"},					{"verbose=default", 2, (3<<5), (0<<5),						"Request quiet BIOS display"},					{"verbose=no", 2, (3<<5), (1<<5),						"Request quiet BIOS display"},					{"verbose=yes", 2, (3<<5), (2<<5),						"Request verbose BIOS display"},					{"force_pet", 2, (1<<4), (1<<4),						"Force progress event traps"},					{"upw_bypass", 2, (1<<3), (1<<3),						"User password bypass"},					{"lockout_sleep", 2, (1<<2), (1<<2),						"Log Out Sleep Button"},					{"cons_redirect=default", 2, (3<<0), (0<<0),						"Console redirection occurs per BIOS configuration setting"},					{"cons_redirect=skip", 2, (3<<0), (1<<0),						"Suppress (skip) console redirection if enabled"},					{"cons_redirect=enable", 2, (3<<0), (2<<0),						"Suppress (skip) console redirection if enabled"},					/* data 4 */					/* data4[7:4] reserved */					/* data4[3] BIOS Shared Mode Override, not implemented here */					/* data4[2:0] BIOS Mux Control Override, not implemented here */					/* data5 reserved */					{NULL}	/* End marker */			}, *op;			memset(&flags[0], 0, sizeof(flags));			token = strtok_r(argv[2] + 8, ",", &saveptr);			while (token != NULL) {				if (strcmp(token, "help") == 0) {					optionError = 1;					break;				}				for (op = options; op->name != NULL; ++op) {					if (strcmp(token, op->name) == 0) {						flags[op->i] &= op->mask;						flags[op->i] |= op->value;						break;					}				}				if (op->name == NULL) {					/* Option not found */					optionError = 1;					lprintf(LOG_ERR, "Invalid option: %s", token);				}				token = strtok_r(NULL, ",", &saveptr);			}			if (optionError) {				lprintf(LOG_NOTICE, "Legal options settings are:");				lprintf(LOG_NOTICE, "\thelp:\tprint this message");				for (op = options; op->name != NULL; ++op) {					lprintf(LOG_NOTICE, "\t%s:\t%s", op->name, op->desc);				}				return (-1);			}			rc = ipmi_chassis_set_bootdev(intf, argv[1], flags);		}		else			rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);		}	}	else {		lprintf(LOG_ERR, "Invalid chassis command: %s", argv[0]);		return -1;	}	return rc;}
 |