📄 wti_nps.c
字号:
* Map the given host name into an (AC) Outlet number on the power strip */static intNPSNametoOutlet(struct WTINPS* nps, const char * name, char **outlets){ char NameMapping[128]; int sockno; char sockname[32]; char buf[32]; int left = 17; int ret = -1; if ((*outlets = (char *)MALLOC(left*sizeof(char))) == NULL) { syslog(LOG_ERR, "out of memory"); return(-1); } strncpy(*outlets, "", left); left = left - 1; /* ensure terminating '\0' */ /* Expect "PS>" */ EXPECT(Prompt, 5); /* The status command output contains mapping of hosts to outlets */ SEND("/s\r"); /* Expect: "-----+" so we can skip over it... */ EXPECT(Separator, 5); do { NameMapping[0] = EOS; SNARF(NameMapping, 5); if (sscanf(NameMapping , "%d | %16c",&sockno, sockname) == 2) { char * last = sockname+16; *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; sprintf(buf, "%d ", sockno); strncat(*outlets, buf, left); left = left - 2; } } } while (strlen(NameMapping) > 2 && left > 0); return(ret);}static intwti_nps_status(Stonith *s){ struct WTINPS* nps; int rc; if (!ISWTINPS(s)) { syslog(LOG_ERR, "invalid argument to NPS_status"); return(S_OOPS); } if (!ISCONFIGED(s)) { syslog(LOG_ERR , "unconfigured stonith object in NPS_status"); return(S_OOPS); } nps = (struct WTINPS*) s->pinfo; if ((rc = NPSRobustLogin(nps) != S_OK)) { syslog(LOG_ERR, _("Cannot log into " DEVICE ".")); return(rc); } /* Send "/h" help command and expect back prompt */ SEND("/h\r"); /* Expect "PS>" */ EXPECT(Prompt, 5); return(NPSLogout(nps));}/* * Return the list of hosts (outlet names) for the devices on this NPS unit */static char **wti_nps_hostlist(Stonith *s){ char NameMapping[128]; char* NameList[64]; unsigned int numnames = 0; char ** ret = NULL; struct WTINPS* nps; if (!ISWTINPS(s)) { syslog(LOG_ERR, "invalid argument to NPS_list_hosts"); return(NULL); } if (!ISCONFIGED(s)) { syslog(LOG_ERR , "unconfigured stonith object in NPS_list_hosts"); return(NULL); } nps = (struct WTINPS*) s->pinfo; if (NPS_connect_device(nps) != S_OK) { return(NULL); } if (NPSRobustLogin(nps) != S_OK) { syslog(LOG_ERR, _("Cannot log into " DEVICE ".")); return(NULL); } /* Expect "PS>" */ NULLEXPECT(Prompt, 5); /* The status command output contains mapping of hosts to outlets */ SEND("/s\r"); /* Expect: "-----" so we can skip over it... */ NULLEXPECT(Separator, 5); NULLEXPECT(CRNL, 5); /* Looks Good! Parse the status output */ do { int sockno; char sockname[64]; NameMapping[0] = EOS; NULLSNARF(NameMapping, 5); if (sscanf(NameMapping , "%d | %16c",&sockno, sockname) == 2) { char * last = sockname+16; char * nm; *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 = 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); if (numnames >= 1) { ret = (char **)MALLOC((numnames+1)*sizeof(char*)); if (ret == NULL) { syslog(LOG_ERR, "out of memory"); }else{ memset(ret, 0, (numnames+1)*sizeof(char*)); memcpy(ret, NameList, (numnames+1)*sizeof(char*)); } } (void)NPSLogout(nps); return(ret); }static voidwti_nps_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 intNPS_parse_config_info(struct WTINPS* nps, const char * info){ static char dev[1024]; static char passwd[1024]; if (nps->config) { return(S_OOPS); } if (sscanf(info, "%s %[^\n\r\t]", dev, passwd) == 2 && strlen(passwd) > 1) { if ((nps->device = strdup(dev)) == NULL) { syslog(LOG_ERR, "out of memory"); return(S_OOPS); } if ((nps->passwd = strdup(passwd)) == NULL) { free(nps->device); nps->device=NULL; syslog(LOG_ERR, "out of memory"); return(S_OOPS); } nps->config = 1; return(S_OK); } return(S_BADCONFIG);}/* * Connect to the given NPS device. We should add serial support here * eventually... */static intNPS_connect_device(struct WTINPS * nps){ char TelnetCommand[256]; snprintf(TelnetCommand, sizeof(TelnetCommand) , "exec telnet %s 2>/dev/null", nps->device); nps->pid=STARTPROC(TelnetCommand, &nps->rdfd, &nps->wrfd); if (nps->pid <= 0) { return(S_OOPS); } return(S_OK);}/* * Reset the given host on this Stonith device. */static intwti_nps_reset_req(Stonith * s, int request, const char * host){ int rc = 0; int lorc = 0; struct WTINPS* nps; if (!ISWTINPS(s)) { syslog(LOG_ERR, "invalid argument to NPS_reset_host"); return(S_OOPS); } if (!ISCONFIGED(s)) { syslog(LOG_ERR , "unconfigured stonith object in NPS_reset_host"); return(S_OOPS); } nps = (struct WTINPS*) s->pinfo; if ((rc = NPSRobustLogin(nps)) != S_OK) { syslog(LOG_ERR, _("Cannot log into " DEVICE ".")); }else{ char *outlets; char *shost; int noutlet; if ((shost = STRDUP(host)) == NULL) { syslog(LOG_ERR, "strdup failed in NPS_reset_host"); return(S_OOPS); } g_strdown(shost); noutlet = NPSNametoOutlet(nps, host, &outlets); free(shost); if (noutlet < 1) { syslog(LOG_WARNING, _("%s %s " "doesn't control host [%s]."), nps->idinfo , nps->unitid, host); NPSkillcomm(nps); return(S_BADHOST); } switch(request) {#if defined(ST_POWERON) && defined(ST_POWEROFF) case ST_POWERON: case ST_POWEROFF: rc = NPS_onoff(nps, outlets, host, request); if (outlets != NULL) { free(outlets); outlets = NULL; } break;#endif case ST_GENERIC_RESET: rc = NPSReset(nps, outlets, host); break; if (outlets != NULL) { free(outlets); outlets = NULL; } default: rc = S_INVAL; if (outlets != NULL) { free(outlets); outlets = NULL; } break; } } lorc = NPSLogout(nps); return(rc != S_OK ? rc : lorc);}/* * Parse the information in the given configuration file, * and stash it away... */static intwti_nps_set_config_file(Stonith* s, const char * configname){ FILE * cfgfile; char WTINPSid[256]; struct WTINPS* nps; if (!ISWTINPS(s)) { syslog(LOG_ERR, "invalid argument to NPS_set_configfile"); return(S_OOPS); } nps = (struct WTINPS*) s->pinfo; if ((cfgfile = fopen(configname, "r")) == NULL) { syslog(LOG_ERR, _("Cannot open %s"), configname); return(S_BADCONFIG); } while (fgets(WTINPSid, sizeof(WTINPSid), cfgfile) != NULL){ if (*WTINPSid == '#' || *WTINPSid == '\n' || *WTINPSid == EOS) { continue; } return(NPS_parse_config_info(nps, WTINPSid)); } return(S_BADCONFIG);}/* * Parse the config information in the given string, and stash it away... */static intwti_nps_set_config_info(Stonith* s, const char * info){ struct WTINPS* nps; if (!ISWTINPS(s)) { syslog(LOG_ERR, "NPS_provide_config_info: invalid argument"); return(S_OOPS); } nps = (struct WTINPS *)s->pinfo; return(NPS_parse_config_info(nps, info));}static const char *wti_nps_getinfo(Stonith * s, int reqtype){ struct WTINPS* nps; const char * ret; if (!ISWTINPS(s)) { syslog(LOG_ERR, "NPS_idinfo: invalid argument"); return NULL; } /* * We look in the ST_TEXTDOMAIN catalog for our messages */ nps = (struct WTINPS *)s->pinfo; switch (reqtype) { case ST_DEVICEID: ret = nps->idinfo; break; case ST_CONF_INFO_SYNTAX: ret = _("IP-address password\n" "The IP-address and password are white-space delimited."); break; case ST_CONF_FILE_SYNTAX: ret = _("IP-address password\n" "The IP-address and password are white-space delimited. " "All three items must be on one line. " "Blank lines and lines beginning with # are ignored"); break; case ST_DEVICEDESCR: ret = _("Western Telematic (WTI) Network Power Switch Devices (NPS-xxx)\n" "Also supports the WTI Telnet Power Switch Devices (TPS-xxx)\n" "NOTE: The WTI Network Power Switch, accepts only " "one (telnet) connection/session at a time."); break; case ST_DEVICEURL: ret = "http://www.wti.com/"; break; default: ret = NULL; break; } return ret;}/* * WTI NPS Stonith destructor... */static voidwti_nps_destroy(Stonith *s){ struct WTINPS* nps; if (!ISWTINPS(s)) { syslog(LOG_ERR, "wtinps_del: invalid argument"); return; } nps = (struct WTINPS *)s->pinfo; nps->NPSid = NOTnpsid; NPSkillcomm(nps); if (nps->device != NULL) { FREE(nps->device); nps->device = NULL; } if (nps->passwd != NULL) { FREE(nps->passwd); nps->passwd = NULL; } if (nps->idinfo != NULL) { FREE(nps->idinfo); nps->idinfo = NULL; } if (nps->unitid != NULL) { FREE(nps->unitid); nps->unitid = NULL; }}/* Create a new BayTech Stonith device. */static void *wti_nps_new(void){ struct WTINPS* nps = MALLOCT(struct WTINPS); if (nps == NULL) { syslog(LOG_ERR, "out of memory"); return(NULL); } memset(nps, 0, sizeof(*nps)); nps->NPSid = NPSid; nps->pid = -1; nps->rdfd = -1; nps->wrfd = -1; nps->config = 0; nps->device = NULL; nps->passwd = NULL; nps->idinfo = NULL; nps->unitid = NULL; REPLSTR(nps->idinfo, DEVICE); REPLSTR(nps->unitid, "unknown"); return((void *)nps);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -