⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 baytech.c

📁 在LINUX下实现HA的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	SEND(unum);	/* Expect "RPC->x "... or "(Y/N)" (if confirmation turned on) */	if (RPCLookFor(bt, RPC, 10) == 1) {		/* They've turned on that annoying command confirmation :-( */		SEND("Y\r");		EXPECT(RPC, 10);	}	EXPECT(GTSign, 10);	/* All Right!  Command done. Life is Good! */	syslog(LOG_NOTICE, _("Power to host %s turned %s."), unitid, onoff);	/* Pop back to main menu */	SEND("MENU\r");	return(S_OK);}#endif /* defined(ST_POWERON) && defined(ST_POWEROFF) *//* *	Map the given host name into an (AC) Outlet number on the power strip */static intRPCNametoOutlet(struct BayTech* bt, const char * name){	char	NameMapping[128];	int	sockno;	char	sockname[32];	int	ret = -1;	/* Verify that we're in the top-level menu */	SEND("\r");	/* Expect "RPC-x Menu" */	EXPECT(RPC, 5);	EXPECT(Menu, 5);	/* OK.  Request sub-menu 1 (Outlet Control) */	SEND("1\r");	/* Verify that we're in the sub-menu */	/* Expect: "RPC-x>" */	EXPECT(RPC, 5);	EXPECT(GTSign, 5);	/* The status command output contains mapping of hosts to outlets */	SEND("STATUS\r");	/* Expect: "emperature:" so we can skip over it... */	EXPECT(bt->modelinfo->expect, 5);	EXPECT(CRNL, 5);	/* Looks Good!  Parse the status output */	do {		char *	last;		NameMapping[0] = EOS;		SNARF(NameMapping, 5);		if (!parse_socket_line(bt, NameMapping, &sockno, sockname)) {			continue;		}		last = sockname+bt->modelinfo->socklen;		*last = EOS;		--last;		/* Strip off trailing blanks */		for(; last > sockname; --last) {			if (*last == ' ') {				*last = EOS;			}else{				break;			}		}		g_strdown(sockname);		if (strcmp(name, sockname) == 0) {			ret = sockno;		}	} while (strlen(NameMapping) > 2 && ret < 0);	/* Pop back out to the top level menu */	SEND("MENU\r");	return(ret);}static intbaytech_status(Stonith  *s){	struct BayTech*	bt;	int	rc;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "invalid argument to RPC_status");		return(S_OOPS);	}	if (!ISCONFIGED(s)) {		syslog(LOG_ERR		,	"unconfigured stonith object in RPC_status");		return(S_OOPS);	}	bt = (struct BayTech*) s->pinfo;	if ((rc = RPCRobustLogin(bt) != S_OK)) {		syslog(LOG_ERR, _("Cannot log into " DEVICE "."));		return(rc);	}	/* Verify that we're in the top-level menu */	SEND("\r");	/* Expect "RPC-x Menu" */	EXPECT(RPC, 5);	EXPECT(Menu, 5);	return(RPCLogout(bt));}/* *	Return the list of hosts (outlet names) for the devices on this BayTech unit */static char **baytech_hostlist(Stonith  *s){	char		NameMapping[128];	char*		NameList[64];	unsigned int	numnames = 0;	char **		ret = NULL;	struct BayTech*	bt;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "invalid argument to baytech_hostlist");		return(NULL);	}	if (!ISCONFIGED(s)) {		syslog(LOG_ERR		,	"unconfigured stonith object in baytech_hostlist");		return(NULL);	}	bt = (struct BayTech*) s->pinfo;	if (RPCRobustLogin(bt) != S_OK) {		syslog(LOG_ERR, _("Cannot log into " DEVICE "."));		return(NULL);	}	/* Verify that we're in the top-level menu */	SEND("\r");	/* Expect "RPC-x Menu" */	NULLEXPECT(RPC, 5);	NULLEXPECT(Menu, 5);	/* OK.  Request sub-menu 1 (Outlet Control) */	SEND("1\r");	/* Verify that we're in the sub-menu */	/* Expect: "RPC-x>" */	NULLEXPECT(RPC, 5);	NULLEXPECT(GTSign, 5);	/* The status command output contains mapping of hosts to outlets */	SEND("STATUS\r");	/* Expect: "emperature:" so we can skip over it... */	NULLEXPECT(bt->modelinfo->expect, 5);	NULLEXPECT(CRNL, 5);	/* Looks Good!  Parse the status output */	do {		int	sockno;		char	sockname[64];		char *	last;		char *	nm;		NameMapping[0] = EOS;		NULLSNARF(NameMapping, 5);		if (!parse_socket_line(bt, NameMapping, &sockno, sockname)) {			continue;		}		last = sockname+bt->modelinfo->socklen;		*last = EOS;		--last;		/* Strip off trailing blanks */		for(; last > sockname; --last) {			if (*last == ' ') {				*last = EOS;			}else{				break;			}		}		if (numnames >= DIMOF(NameList)-1) {			break;		}		if ((nm = (char*)STRDUP(sockname)) == NULL) {			syslog(LOG_ERR, "out of memory");			return(NULL);		}		g_strdown(nm);		NameList[numnames] = nm;		++numnames;		NameList[numnames] = NULL;	} while (strlen(NameMapping) > 2);	/* Pop back out to the top level menu */	SEND("MENU\r");	if (numnames >= 1) {		ret = (char **)MALLOC((numnames+1)*sizeof(char*));		if (ret == NULL) {			syslog(LOG_ERR, "out of memory");		}else{			memcpy(ret, NameList, (numnames+1)*sizeof(char*));		}	}	(void)RPCLogout(bt);	return(ret);}static voidbaytech_free_hostlist (char ** hlist){	char **	hl = hlist;	if (hl == NULL) {		return;	}	while (*hl) {		FREE(*hl);		*hl = NULL;		++hl;	}	FREE(hlist);}/* *	Parse the given configuration information, and stash it away... */static intRPC_parse_config_info(struct BayTech* bt, const char * info){	static char dev[1024];	static char user[1024];	static char passwd[1024];	if (bt->config) {		return(S_OOPS);	}	if (sscanf(info, "%s %s %[^\n\r\t]", dev, user, passwd) == 3	&&	strlen(passwd) > 1) {		if ((bt->device = STRDUP(dev)) == NULL) {			syslog(LOG_ERR, "out of memory");			return(S_OOPS);		}		if ((bt->user = STRDUP(user)) == NULL) {			FREE(bt->device);			bt->device=NULL;			syslog(LOG_ERR, "out of memory");			return(S_OOPS);		}		if ((bt->passwd = STRDUP(passwd)) == NULL) {			FREE(bt->user);			bt->user=NULL;			FREE(bt->device);			bt->device=NULL;			syslog(LOG_ERR, "out of memory");			return(S_OOPS);		}		bt->config = 1;		return(S_OK);	}	return(S_BADCONFIG);}/* *	Connect to the given BayTech device.  We should add serial support here *	eventually... */static intRPC_connect_device(struct BayTech * bt){	char	TelnetCommand[256];	snprintf(TelnetCommand, sizeof(TelnetCommand)	,	"exec telnet %s 2>/dev/null", bt->device);	bt->pid=STARTPROC(TelnetCommand, &bt->rdfd, &bt->wrfd);	if (bt->pid <= 0) {		return(S_OOPS);	}	return(S_OK);}/* *	Reset the given host on this Stonith device. */static intbaytech_reset_req(Stonith * s, int request, const char * host){	int	rc = 0;	int	lorc = 0;	struct BayTech*	bt;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "invalid argument to baytech_reset");		return(S_OOPS);	}	if (!ISCONFIGED(s)) {		syslog(LOG_ERR		,	"unconfigured stonith object in baytech_reset");		return(S_OOPS);	}	bt = (struct BayTech*) s->pinfo;	if ((rc = RPCRobustLogin(bt)) != S_OK) {		syslog(LOG_ERR, _("Cannot log into " DEVICE "."));	}else{		int	noutlet;		noutlet = RPCNametoOutlet(bt, host);		if (noutlet < 1) {			syslog(LOG_WARNING, _("%s %s "			"doesn't control host [%s]."), bt->idinfo			,	bt->unitid, host);			RPCkillcomm(bt);			return(S_BADHOST);		}		switch(request) {#if defined(ST_POWERON) && defined(ST_POWEROFF)		case ST_POWERON:		case ST_POWEROFF:			rc = RPC_onoff(bt, noutlet, host, request);			break;#endif		case ST_GENERIC_RESET:			rc = RPCReset(bt, noutlet, host);			break;		default:			rc = S_INVAL;			break;		}	}	lorc = RPCLogout(bt);	RPCkillcomm(bt);	return(rc != S_OK ? rc : lorc);}/* *	Parse the information in the given configuration file, *	and stash it away... */static intbaytech_set_config_file(Stonith* s, const char * configname){	FILE *	cfgfile;	char	RPCid[256];	struct BayTech*	bt;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "invalid argument to baytech_set");		return(S_OOPS);	}	bt = (struct BayTech*) s->pinfo;	if ((cfgfile = fopen(configname, "r")) == NULL)  {		syslog(LOG_ERR, _("Cannot open %s"), configname);		return(S_BADCONFIG);	}	while (fgets(RPCid, sizeof(RPCid), cfgfile) != NULL){		if (*RPCid == '#' || *RPCid == '\n' || *RPCid == EOS) {			continue;		}		return(RPC_parse_config_info(bt, RPCid));	}	return(S_BADCONFIG);}/* *	Parse the config information in the given string, and stash it away... */static intbaytech_set_config_info(Stonith* s, const char * info){	struct BayTech* bt;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "baytech_set_config_info: invalid argument");		return(S_OOPS);	}	bt = (struct BayTech *)s->pinfo;	return(RPC_parse_config_info(bt, info));}static const char *baytech_getinfo(Stonith * s, int reqtype){	struct BayTech* bt;	const char *		ret;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "RPC_idinfo: invalid argument");		return NULL;	}	/*	 *	We look in the ST_TEXTDOMAIN catalog for our messages	 */	bt = (struct BayTech *)s->pinfo;	switch (reqtype) {		case ST_DEVICEID:		/* Exactly what type of device? */			ret = bt->idinfo;			break;		case ST_DEVICENAME:		/* Which particular individual device? */			ret = bt->device;			break;		case ST_CONF_INFO_SYNTAX:			ret = _("IP-address login password\n"			"The IP-address and login are white-space delimited.");			break;		case ST_CONF_FILE_SYNTAX:			ret = _("IP-address login password\n"			"The IP-address and login are white-space delimited.  "			"All three items must be on one line.  "			"Blank lines and lines beginning with # are ignored");			break;		case ST_DEVICEDESCR:		/* Description of device type */			ret = _("Bay Technical Associates (Baytech) RPC "			"series power switches (via telnet).\n"			"The RPC-5, RPC-3 and RPC-3A switches are well tested.");			break;		case ST_DEVICEURL:		/* Manufacturer's web site */			ret = "http://www.baytech.net/";			break;		default:			ret = NULL;			break;	}	return ret;}/* *	Baytech Stonith destructor... */static voidbaytech_destroy(Stonith *s){	struct BayTech* bt;	if (!ISBAYTECH(s)) {		syslog(LOG_ERR, "baytech_del: invalid argument");		return;	}	bt = (struct BayTech *)s->pinfo;	bt->BTid = NOTbtid;	RPCkillcomm(bt);	if (bt->rdfd >= 0) {		close(bt->rdfd);		bt->rdfd = -1;	}	if (bt->wrfd >= 0) {		close(bt->wrfd);		bt->wrfd = -1;	}	if (bt->device != NULL) {		FREE(bt->device);		bt->device = NULL;	}	if (bt->user != NULL) {		FREE(bt->user);		bt->user = NULL;	}	if (bt->passwd != NULL) {		FREE(bt->passwd);		bt->passwd = NULL;	}	if (bt->idinfo != NULL) {		FREE(bt->idinfo);		bt->idinfo = NULL;	}	if (bt->unitid != NULL) {		FREE(bt->unitid);		bt->unitid = NULL;	}}/* Create a new BayTech Stonith device. */static void *baytech_new(void){	struct BayTech*	bt = MALLOCT(struct BayTech);	if (bt == NULL) {		syslog(LOG_ERR, "out of memory");		return(NULL);	}	memset(bt, 0, sizeof(*bt));	bt->BTid = BTid;	bt->pid = -1;	bt->rdfd = -1;	bt->wrfd = -1;	bt->config = 0;	bt->user = NULL;	bt->device = NULL;	bt->passwd = NULL;	bt->idinfo = NULL;	bt->unitid = NULL;	REPLSTR(bt->idinfo, DEVICE);	bt->modelinfo = &ModelInfo[0];	return((void *)bt);}static intparse_socket_line(struct BayTech * bt,	const char *NameMapping,	int *sockno, char *sockname){#if 0	char format[64];	snprintf(format, sizeof(format), "%%7d       %%%dc"	,	bt->modelinfo->socklen);	/* 7 digits, 7 blanks, then 'socklen' characters */	/* [0-6]: digits, NameMapping[13] begins the sockname */	/* NameMapping strlen must be >= socklen + 14 */	if (sscanf(NameMapping, format, sockno, sockname) != 2) {		return FALSE;	}#else#	define	OFFSET 14	if (sscanf(NameMapping, "%7d", sockno) != 1	||	strlen(NameMapping) < OFFSET+bt->modelinfo->socklen) {		return FALSE;	}	strncpy(sockname, NameMapping+OFFSET, bt->modelinfo->socklen);	sockname[bt->modelinfo->socklen] = EOS;#endif	return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -