📄 rcd_serial.c
字号:
++hl; } FREE(hlist); hlist = NULL;}/* * Parse the config information, and stash it away... */static intRCD_SERIAL_parse_config_info(struct RCD_SerialDevice* rcd, const char * info){ char *copy; char *token; char *endptr; int ret; if (rcd->hostcount >= 0) { return(S_OOPS); } /* strtok() is nice to use to parse a string with (other than it isn't threadsafe), but it is destructive, so we're going to alloc our own private little copy for the duration of this function. */ copy = STRDUP(info); if (!copy) { syslog(LOG_ERR, "%s: out of memory!", __FUNCTION__); return S_OOPS; } /* Grab the hostname */ token = strtok (copy, WHITESPACE); if (!token) { syslog(LOG_ERR, "%s: Can't find hostname on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } if ((rcd->hostlist = (char **)MALLOC(2*sizeof(char*))) == NULL) { syslog(LOG_ERR, "%s: out of memory!", __FUNCTION__); ret = S_OOPS; goto token_error; } memset(rcd->hostlist, 0, 2*sizeof(char*)); rcd->hostcount = 0; rcd->hostlist[0] = STRDUP(token); if (!rcd->hostlist[0]) { syslog(LOG_ERR, "%s: out of memory!", __FUNCTION__); ret = S_OOPS; goto token_error; } g_strdown(rcd->hostlist[0]); rcd->hostcount = 1; /* Grab the device name */ token = strtok (NULL, WHITESPACE); if (!token) { syslog(LOG_ERR, "%s: Can't find device on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } rcd->device = STRDUP(token); if (!rcd->device) { syslog(LOG_ERR, "%s: out of memory!", __FUNCTION__); ret = S_OOPS; goto token_error; } /* Grab the signal name */ token = strtok (NULL, WHITESPACE); if (!token) { syslog(LOG_ERR, "%s: Can't find signal on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } rcd->signal = STRDUP(token); if (!rcd->signal) { syslog(LOG_ERR, "%s: out of memory!", __FUNCTION__); ret = S_OOPS; goto token_error; } if (strcmp(rcd->signal, "rts") && strcmp(rcd->signal, "dtr")) { syslog(LOG_ERR, "%s: Invalid signal name on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } /* Grab the duration in millisecs */ token = strtok (NULL, WHITESPACE); if (!token) { syslog(LOG_ERR, "%s: Can't find msduration on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } rcd->msduration = strtol(token, &endptr, 0); if (*token == 0 || *endptr != 0 || rcd->msduration < 1) { syslog(LOG_ERR, "%s: Invalid msduration on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } /* Make sure nothing extra provided */ token = strtok (NULL, WHITESPACE); if (token) { syslog(LOG_ERR, "%s: Too many params on config line '%s'", RCD_SERIALid, info); ret = S_BADCONFIG; goto token_error; } /* free our private copy of the string we've been destructively parsing with strtok() */ FREE(copy); return S_OK;token_error: FREE(copy); return(ret);}/* * At last, we really do it! I don't know what the request argument * is so am just ignoring it... */static intrcd_serial_reset_req(Stonith * s, int request, const char * host){ struct RCD_SerialDevice* rcd; int fd; int sigbit; struct itimerval timer; const char * err; char* shost; if (!ISRCD_SERIALDEV(s)) { syslog(LOG_ERR, "invalid argument to %s", __FUNCTION__); return(S_OOPS); } rcd = (struct RCD_SerialDevice *) s->pinfo; /* check that host matches */ if ((shost = STRDUP(host)) == NULL) { syslog(LOG_ERR, "%s: strdup failed", __FUNCTION__); return(S_OOPS); } g_strdown(shost); if (strcmp(host, rcd->hostlist[0])) { syslog(LOG_ERR, "%s: host '%s' not in hostlist.", __FUNCTION__, host); free(shost); return(S_BADHOST); } free(shost); /* Set the appropriate bit for the signal */ sigbit = *(rcd->signal)=='r' ? TIOCM_RTS : TIOCM_DTR; /* Set up the timer */ timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; timer.it_value.tv_sec = rcd->msduration / 1000; timer.it_value.tv_usec = (rcd->msduration % 1000) * 1000; /* Open the device */ if ((fd = RCD_open_serial_port(rcd->device)) == -1) {#ifdef HAVE_STRERROR err = strerror(errno);#else err = sys_errlist[errno];#endif syslog(LOG_ERR, "%s: open of %s failed - %s", __FUNCTION__, rcd->device, err); return(S_OOPS); } /* Start the timer */ RCD_alarm_handler(0);#ifdef RCD_NOPAUSE RCD_alarmcaught = 0;#endif setitimer(ITIMER_REAL, &timer, 0); /* Set the line high */ ioctl(fd, TIOCMBIS, &sigbit); /* Wait for the alarm signal */#ifdef RCD_NOPAUSE while(!RCD_alarmcaught) ioctl(fd, TIOCMBIS, &sigbit);#else pause();#endif /* Clear the line low */ ioctl(fd, TIOCMBIC, &sigbit); /* Close the port */ if (RCD_close_serial_port(fd) != 0) { err = strerror(errno); syslog(LOG_ERR, "%s: close of %s failed - %s", __FUNCTION__, rcd->device, err); return(S_OOPS); } syslog(LOG_INFO, _("Host %s rcd_serial-reset."), host); return S_OK;}/* * Parse the information in the given configuration file, * and stash it away... */static intrcd_serial_set_config_file(Stonith* s, const char * configname){ FILE * cfgfile; char RCD_SERIALline[256]; struct RCD_SerialDevice* rcd; if (!ISRCD_SERIALDEV(s)) { syslog(LOG_ERR,"invalid argument to RCD_SERIAL_set_configfile"); return(S_OOPS); } rcd = (struct RCD_SerialDevice*) s->pinfo; if ((cfgfile = fopen(configname, "r")) == NULL) { syslog(LOG_ERR, "Cannot open %s", configname); return(S_BADCONFIG); } while (fgets(RCD_SERIALline, sizeof(RCD_SERIALline), cfgfile) != NULL){ if ( *RCD_SERIALline == '#' || \ *RCD_SERIALline == '\n' || \ *RCD_SERIALline == EOS) { continue; } return(RCD_SERIAL_parse_config_info(rcd, RCD_SERIALline)); } return(S_BADCONFIG);}/* * Parse the config information in the given string, and stash it away... */static intrcd_serial_set_config_info(Stonith* s, const char * info){ struct RCD_SerialDevice* rcd; if (!ISRCD_SERIALDEV(s)) { syslog(LOG_ERR, "%s: invalid argument", __FUNCTION__); return(S_OOPS); } rcd = (struct RCD_SerialDevice *)s->pinfo; return(RCD_SERIAL_parse_config_info(rcd, info));}static const char *rcd_serial_getinfo(Stonith * s, int reqtype){ struct RCD_SerialDevice* rcd; char * ret; if (!ISRCD_SERIALDEV(s)) { syslog(LOG_ERR, "RCD_SERIAL_idinfo: invalid argument"); return NULL; } /* * We look in the ST_TEXTDOMAIN catalog for our messages */ rcd = (struct RCD_SerialDevice *)s->pinfo; switch (reqtype) { case ST_DEVICEID: ret = _(DEVICE); break; case ST_CONF_INFO_SYNTAX: ret = _("<hostname> <serial_device> <dtr|rts> " "<msduration>\n" "All tokens are white-space delimited.\n"); break; case ST_CONF_FILE_SYNTAX: ret = _("<hostname> <serial_device> <dtr|rts> " "<msduration>\n" "All tokens are white-space delimited.\n" "Blank lines and lines beginning with # are ignored"); break; case ST_DEVICEDESCR: ret = _("RC Delayed Serial STONITH Device\n" "This device can be constructed cheaply from" " readily available components,\n" "with sufficient expertise and testing.\n" "See README.rcd_serial for circuit diagram.\n"); break; case ST_DEVICEURL: ret = _("http://www.scl.co.uk/rcd_serial/"); break; default: ret = NULL; break; } return ret;}/* * RCD_SERIAL Stonith destructor... */static voidrcd_serial_destroy(Stonith *s){ struct RCD_SerialDevice* rcd; if (!ISRCD_SERIALDEV(s)) { syslog(LOG_ERR, "%s: invalid argument", __FUNCTION__); return; } rcd = (struct RCD_SerialDevice *)s->pinfo; rcd->RCD_SERIALid = NOTrcd_serialID; if (rcd->hostlist) { rcd_serial_free_hostlist(rcd->hostlist); rcd->hostlist = NULL; } rcd->hostcount = -1; if (rcd->device) FREE(rcd->device); if (rcd->signal) FREE(rcd->signal); FREE(rcd);}/* * Create a new RCD_Serial Stonith device. * Too bad this function can't be static. (Hmm, weird, it _is_ static?) */static void *rcd_serial_new(void){ struct RCD_SerialDevice* rcd = MALLOCT(struct RCD_SerialDevice); if (rcd == NULL) { syslog(LOG_ERR, "out of memory"); return(NULL); } memset(rcd, 0, sizeof(*rcd)); rcd->RCD_SERIALid = RCD_SERIALid; rcd->hostlist = NULL; rcd->hostcount = -1; rcd->device = NULL; rcd->signal = NULL; rcd->msduration = 0; return((void *)rcd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -