📄 cyclades.c
字号:
memset(name, 0, sizeof(name)); memset(locked, 0, sizeof(locked)); memset(on, 0, sizeof(on)); err = CYCScanLine(sd, 2, savebuf, sizeof(savebuf)); if ((err == S_OK) && (sscanf(savebuf,"%3d %10s %10s %3s", &outlet, name, locked, on) > 0)) { if (strstr(locked, "ocked")) { nm = (char *) STRDUP (name); if (!nm) { syslog(LOG_ERR, "out of memory"); goto out_of_memory; } g_strdown(nm); NameList[numnames] = nm; numnames++; NameList[numnames] = NULL; } } } while (err == S_OK); if (numnames) { ret = (char **)MALLOC((numnames+1)*sizeof(char*)); if (ret == NULL) { syslog(LOG_ERR, "out of memory"); goto out_of_memory; } else { memcpy(ret, NameList, (numnames+1)*sizeof(char*)); } return (ret); }out_of_memory: for (i=0; i<numnames; i++) free(NameList[i]); return (NULL);}static voidcyclades_free_hostlist (char ** hlist){ char ** hl = hlist; if (hl == NULL) { return; } while (*hl) { FREE(*hl); *hl = NULL; ++hl; } FREE(hlist); hlist = NULL;}/* * Parse the config information, and stash it away... */static intcyclades_parse_config_info(struct cycladesDevice* sd, const char * info){ static char dev[1024]; static char user[1024]; int serial_port; if (sd->config) return(S_OOPS); /* sscanf is dangerous ? */ if (sscanf(info, "%s %s %d", dev, user, &serial_port) == 3) { if ((sd->device = STRDUP(dev)) == NULL) { syslog(LOG_ERR, "out of memory"); return (S_OOPS); } if ((sd->user = STRDUP(user)) == NULL) { FREE(sd->device); sd->device = NULL; syslog(LOG_ERR, "out of memory"); return (S_OOPS); } sd->serial_port = serial_port; sd->config = 1; return(S_OK); } return(S_BADCONFIG);}static char *cyclades_outletstr(int *outlet, int numoutlet){ int i, len; char *ret; /* maximum length per outlet is currently four (outlet is one to * three digits, followed by either a comma or null), so add one * for good measure */ len = numoutlet * 5 * sizeof(char); if ((ret = MALLOC(len)) != NULL) { snprintf(ret, len, "%d", outlet[0]); for (i = 1; i < numoutlet; i++) { char buf[5]; snprintf(buf, sizeof(buf), ",%d", outlet[i]); strcat(ret, buf); } } return(ret);}static int cyclades_onoff(struct cycladesDevice *sd, int *outlet, int numoutlet, const char *unitid, int req){ char savebuf[MAXSAVE]; const char * onoff; char cmd[MAX_OUTLETS*4], expstring[64]; struct Etoken exp[] = {{NULL, 0, 0}, {NULL, 0, 0}}; char *outletstr; int i; onoff = (req == ST_POWERON ? "on" : "off"); memset(cmd, 0, sizeof(cmd)); outletstr = cyclades_outletstr(outlet, numoutlet); if (outletstr == NULL) { syslog(LOG_ERR, "out of memory"); return(S_OOPS); } snprintf(cmd, sizeof(cmd), "%s %s", onoff, outletstr); if (CYC_robust_cmd(sd, cmd) != S_OK) { syslog(LOG_ERR, "can't run %s command", onoff); FREE(outletstr); return(S_OOPS); } EXPECT(CRNL, 50, savebuf, sizeof(savebuf)); for (i = 0; i < numoutlet; i++) { memset(expstring, 0, sizeof(expstring)); snprintf(expstring, sizeof(expstring), "%d: Outlet turned %s." , outlet[i], onoff); exp[0].string = expstring; /* FIXME: should handle "already powered on/off" case and inform to syslog */ EXPECT(exp, 50, savebuf, sizeof(savebuf)); } syslog(LOG_NOTICE, _("Power to host %s turned %s."), unitid, onoff); FREE(outletstr); return (S_OK);}static int cyclades_reset(struct cycladesDevice *sd, int *outlet, int numoutlet, const char *unitid){ char savebuf[MAXSAVE]; char cmd[MAX_OUTLETS*4], expstring[64]; struct Etoken exp[] = {{NULL, 0, 0}, {NULL, 0, 0}}; char *outletstr; int i; memset(cmd, 0, sizeof(cmd)); outletstr = cyclades_outletstr(outlet, numoutlet); if (outletstr == NULL) { syslog(LOG_ERR, "out of memory"); return(S_OOPS); } snprintf(cmd, sizeof(cmd), "%s %s", cycle, outletstr); syslog(LOG_INFO, _("Host %s being rebooted."), unitid); if (CYC_robust_cmd(sd, cmd) != S_OK) { syslog(LOG_ERR, "can't run cycle command"); FREE(outletstr); return(S_OOPS); } RESETEXPECT(CRNL, 50, savebuf, sizeof(savebuf)); for (i = 0; i < numoutlet; i++) { memset(expstring, 0, sizeof(expstring)); snprintf(expstring, sizeof(expstring), "%d: Outlet turned off." , outlet[i]); exp[0].string = expstring; RESETEXPECT(exp, 50, savebuf, sizeof(savebuf)); } for (i = 0; i < numoutlet; i++) { memset(expstring, 0, sizeof(expstring)); snprintf(expstring, sizeof(expstring), "%d: Outlet turned on." , outlet[i]); exp[0].string = expstring; RESETEXPECT(exp, 50, savebuf, sizeof(savebuf)); } FREE(outletstr); return (S_OK);}/* * Reset the given host on this Stonith device. */static intcyclades_reset_req(Stonith * s, int request, const char * host){ struct cycladesDevice *sd; int rc = 0; int numoutlet, outlets[MAX_OUTLETS]; if (!ISCYCLADESDEV(s)) { syslog (LOG_ERR, "invalid argument to cyclades_reset"); return (S_OOPS); } sd = (struct cycladesDevice *)s->pinfo; numoutlet = CYCNametoOutlet(sd, host, outlets, MAX_OUTLETS); if (!numoutlet) { syslog (LOG_ERR, "Unknown host %s to " DEVICE, host); return (S_OOPS); } switch (request) { case ST_POWERON: case ST_POWEROFF: rc = cyclades_onoff(sd, outlets, numoutlet, host, request); break; case ST_GENERIC_RESET: rc = cyclades_reset(sd, outlets, numoutlet, host); break; default: rc = S_INVAL; break; } return rc;}/* * Parse the information in the given configuration file, * and stash it away... */static intcyclades_set_config_file(Stonith* s, const char * configname){ FILE * cfgfile; char line[256]; struct cycladesDevice* sd; if (!ISCYCLADESDEV(s)) { syslog(LOG_ERR, "invalid argument to cyclades_set_config_file"); return(S_OOPS); } sd = (struct cycladesDevice*) s->pinfo; if ((cfgfile = fopen(configname, "r")) == NULL) { syslog(LOG_ERR, "Cannot open %s", configname); return(S_BADCONFIG); } while (fgets(line, sizeof(line), cfgfile) != NULL){ if (*line == '#' || *line == '\n' || *line == EOS) { continue; } return(cyclades_parse_config_info(sd, line)); } return(S_BADCONFIG);}/* * Parse the config information in the given string, and stash it away... */static intcyclades_set_config_info(Stonith* s, const char * info){ struct cycladesDevice* sd; if (!ISCYCLADESDEV(s)) { syslog(LOG_ERR, "%s: invalid argument", __FUNCTION__); return(S_OOPS); } sd = (struct cycladesDevice *)s->pinfo; return(cyclades_parse_config_info(sd, info));}static const char *cyclades_getinfo(Stonith * s, int reqtype){ struct cycladesDevice * sd; const char * ret; if (!ISCYCLADESDEV(s)) { syslog(LOG_ERR, "cyclades_getinfo: invalid argument"); return NULL; } /* * We look in the ST_TEXTDOMAIN catalog for our messages */ sd = (struct cycladesDevice *)s->pinfo; switch (reqtype) { case ST_DEVICEID: /* FIXME: could inform the exact PM model */ ret = _("Cyclades AlterPath PM"); break; case ST_CONF_INFO_SYNTAX: ret = _("IP-address login serial-port\n" "The IP address, login and serial-port are white-space delimited. " "login is the username on the TS/ACS (usually root) and " "serial-port indicates in which port the PM is connected to."); break; case ST_CONF_FILE_SYNTAX: ret = _("IP-address login serial-port\n" "The IP-address, login and serial-port 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 = _("Cyclades AlterPath PM " "series power switches (via TS/ACS/KVM)."); break; case ST_DEVICEURL: ret = "http://www.cyclades.com/"; break; default: ret = NULL; break; } return ret;}/* * Cyclades Stonith destructor... */static voidcyclades_destroy(Stonith *s){ struct cycladesDevice* sd; if (!ISCYCLADESDEV(s)) { syslog(LOG_ERR, "%s: invalid argument", __FUNCTION__); return; } sd = (struct cycladesDevice *)s->pinfo; sd->cycladesid = NOTcycladesID; CYCkillcomm(sd); if (sd->device != NULL) { FREE(sd->device); sd->device = NULL; } if (sd->user != NULL) { FREE(sd->user); sd->user = NULL; } FREE(sd);}/* Create a new cyclades Stonith device */static void *cyclades_new(void){ struct cycladesDevice* sd = MALLOCT(struct cycladesDevice); if (sd == NULL) { syslog(LOG_ERR, "out of memory"); return(NULL); } memset(sd, 0, sizeof(*sd)); sd->cycladesid = cycladesid; sd->rdfd = -1; sd->wrfd = -1; return((void *)sd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -