?? apcmaster.c
字號:
/* All Right! Command done. Life is Good! */ LOG(PIL_INFO, "%s %d %s %s", _("Power to MS outlet(s)"), outletNum, _("turned"), onoff); /* Pop back to main menu */ SEND(ms->wrfd, "\033\033\033\033\033\033\033\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 intMSNametoOutlet(struct pluginDevice* ms, const char * name){ char NameMapping[128]; int sockno; char sockname[32]; int times = 0; int ret = -1; /* Verify that we're in the top-level menu */ EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); /* Expect ">" */ EXPECT(ms->rdfd, Prompt, 5); /* Request menu 1 (Device Control) */ SEND(ms->wrfd, "1\r"); /* Expect: "-----" so we can skip over it... */ EXPECT(ms->rdfd, Separator, 5); EXPECT(ms->rdfd, CRNL, 5); EXPECT(ms->rdfd, CRNL, 5); /* Looks Good! Parse the status output */ do { times++; NameMapping[0] = EOS; SNARF(ms->rdfd, NameMapping, 5); if (sscanf(NameMapping , "%d- %23c",&sockno, sockname) == 2) { char * last = sockname+23; *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 && times < 8); /* Pop back out to the top level menu */ EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); EXPECT(ms->rdfd, Prompt, 5); SEND(ms->wrfd, "\033"); return(ret);}static intapcmaster_status(StonithPlugin *s){ struct pluginDevice* ms; int rc; ERRIFNOTCONFIGED(s,S_OOPS); ms = (struct pluginDevice*) s; if ((rc = MSRobustLogin(ms) != S_OK)) { LOG(PIL_CRIT, "%s", _("Cannot log into " DEVICE ".")); return(rc); } /* Expect ">" */ SEND(ms->wrfd, "\033\r"); EXPECT(ms->rdfd, Prompt, 5); return(MSLogout(ms));}/* * Return the list of hosts (outlet names) for the devices on this MS unit */static char **apcmaster_hostlist(StonithPlugin *s){ char NameMapping[128]; char* NameList[64]; unsigned int numnames = 0; char ** ret = NULL; struct pluginDevice* ms; ERRIFNOTCONFIGED(s,NULL); ms = (struct pluginDevice*) s; if (MSRobustLogin(ms) != S_OK) { LOG(PIL_CRIT, "%s", _("Cannot log into " DEVICE ".")); return(NULL); } /* Expect ">" */ NULLEXPECT(ms->rdfd, Prompt, 10); /* Request menu 1 (Device Control) */ SEND(ms->wrfd, "1\r"); /* Expect: "-----" so we can skip over it... */ NULLEXPECT(ms->rdfd, Separator, 5); NULLEXPECT(ms->rdfd, CRNL, 5); NULLEXPECT(ms->rdfd, CRNL, 5); /* Looks Good! Parse the status output */ do { int sockno; char sockname[64]; NameMapping[0] = EOS; NULLSNARF(ms->rdfd, NameMapping, 5); if (sscanf(NameMapping , "%d- %23c",&sockno, sockname) == 2) { char * last = sockname+23; 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 = (char*)STRDUP(sockname)) == NULL) { LOG(PIL_CRIT, "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(ms->wrfd, "\033"); NULLEXPECT(ms->rdfd, Prompt, 10); SEND(ms->wrfd, "\033"); NULLEXPECT(ms->rdfd, Prompt, 10); SEND(ms->wrfd, "\033"); NULLEXPECT(ms->rdfd, Prompt, 10); SEND(ms->wrfd, "\033"); NULLEXPECT(ms->rdfd, Prompt, 10); if (numnames >= 1) { ret = (char **)MALLOC((numnames+1)*sizeof(char*)); if (ret == NULL) { LOG(PIL_CRIT, "out of memory"); }else{ memcpy(ret, NameList, (numnames+1)*sizeof(char*)); } } (void)MSLogout(ms); return(ret);}/* * Connect to the given MS device. We should add serial support here * eventually... */static intMS_connect_device(struct pluginDevice * ms){ char TelnetCommand[256]; snprintf(TelnetCommand, sizeof(TelnetCommand) , "exec telnet %s 2>/dev/null", ms->device); ms->pid=STARTPROC(TelnetCommand, &ms->rdfd, &ms->wrfd); if (ms->pid <= 0) { return(S_OOPS); } return(S_OK);}/* * Reset the given host on this StonithPlugin device. */static intapcmaster_reset_req(StonithPlugin * s, int request, const char * host){ int rc = 0; int lorc = 0; struct pluginDevice* ms; ERRIFNOTCONFIGED(s,S_OOPS); ms = (struct pluginDevice*) s; if ((rc = MSRobustLogin(ms)) != S_OK) { LOG(PIL_CRIT, "%s", _("Cannot log into " DEVICE ".")); return(rc); }else{ int noutlet; noutlet = MSNametoOutlet(ms, host); if (noutlet < 1) { LOG(PIL_WARN, "%s %s %s [%s]" , ms->idinfo ,ms->unitid, _("doesn't control host"), host); Stonithkillcomm(&ms->rdfd,&ms->wrfd,&ms->pid); return(S_BADHOST); } switch(request) {#if defined(ST_POWERON) && defined(ST_POWEROFF) case ST_POWERON: rc = apcmaster_onoff(ms, noutlet, host, request); break; case ST_POWEROFF: rc = apcmaster_onoff(ms, noutlet, host, request); break;#endif case ST_GENERIC_RESET: rc = MSReset(ms, noutlet, host); break; default: rc = S_INVAL; break; } } lorc = MSLogout(ms); return(rc != S_OK ? rc : lorc);}/* * Get the configuration parameters names */static const char **apcmaster_get_confignames(StonithPlugin * s){ static const char * ret[] = {ST_IPADDR, ST_LOGIN, ST_PASSWD, NULL}; return ret;}/* * Set the configuration parameters */static intapcmaster_set_config(StonithPlugin * s, StonithNVpair * list){ struct pluginDevice* sd = (struct pluginDevice *)s; int rc; StonithNamesToGet namestoget [] = { {ST_IPADDR, NULL} , {ST_LOGIN, NULL} , {ST_PASSWD, NULL} , {NULL, NULL} }; ERRIFWRONGDEV(s, S_OOPS); if (sd->sp.isconfigured) { return S_OOPS; } if ((rc=OurImports->GetAllValues(namestoget, list)) != S_OK) { return rc; } sd->device = namestoget[0].s_value; sd->user = namestoget[1].s_value; sd->passwd = namestoget[2].s_value; sd->config = 1; return(S_OK);}static const char *apcmaster_getinfo(StonithPlugin * s, int reqtype){ struct pluginDevice* ms; const char * ret; ERRIFWRONGDEV(s,NULL); /* * We look in the ST_TEXTDOMAIN catalog for our messages */ ms = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: ret = ms->idinfo; break; case ST_DEVICEDESCR: ret = _("APC MasterSwitch (via telnet)\n" "NOTE: The APC MasterSwitch accepts only one (telnet)\n" "connection/session a time. When one session is active,\n" "subsequent attempt to connect to the MasterSwitch" " will fail."); break; case ST_DEVICEURL: ret = "http://www.apc.com/"; break; default: ret = NULL; break; } return ret;}/* * APC MasterSwitch StonithPlugin destructor... */static voidapcmaster_destroy(StonithPlugin *s){ struct pluginDevice* ms; VOIDERRIFWRONGDEV(s); ms = (struct pluginDevice *)s; ms->pluginid = NOTpluginID; Stonithkillcomm(&ms->rdfd,&ms->wrfd,&ms->pid); if (ms->device != NULL) { FREE(ms->device); ms->device = NULL; } if (ms->user != NULL) { FREE(ms->user); ms->user = NULL; } if (ms->passwd != NULL) { FREE(ms->passwd); ms->passwd = NULL; } if (ms->idinfo != NULL) { FREE(ms->idinfo); ms->idinfo = NULL; } if (ms->unitid != NULL) { FREE(ms->unitid); ms->unitid = NULL; }}/* Create a new APC Master Switch StonithPlugin device. */static StonithPlugin *apcmaster_new(void){ struct pluginDevice* ms = MALLOCT(struct pluginDevice); if (ms == NULL) { LOG(PIL_CRIT, "out of memory"); return(NULL); } memset(ms, 0, sizeof(*ms)); ms->pluginid = pluginid; ms->pid = -1; ms->rdfd = -1; ms->wrfd = -1; ms->config = 0; ms->user = NULL; ms->device = NULL; ms->passwd = NULL; ms->idinfo = NULL; ms->unitid = NULL; REPLSTR(ms->idinfo, DEVICE); REPLSTR(ms->unitid, "unknown"); ms->sp.s_ops = &apcmasterOps; return(&(ms->sp));}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -