/* see what the status of the UPS is and handle any changes */ static void pollups(utype_t *ups) { char status[SMALLBUF]; /* try a reconnect here */ if (!flag_isset(ups->status, ST_CONNECTED)) if (try_connect(ups) != 1) return; if (upscli_ssl(&ups->conn) == 1) upsdebugx(2, "%s: %s [SSL]", __func__, ups->sys); else upsdebugx(2, "%s: %s", __func__, ups->sys); set_alarm(); if (get_var(ups, "status", status, sizeof(status)) == 0) { clear_alarm(); parse_status(ups, status); return; } /* fallthrough: no communications */ clear_alarm(); /* try to make some of these a little friendlier */ switch (upscli_upserror(&ups->conn)) { case UPSCLI_ERR_UNKNOWNUPS: upslogx(LOG_ERR, "Poll UPS [%s] failed - [%s] " "does not exist on server %s", ups->sys, ups->upsname, ups->hostname); break; default: upslogx(LOG_ERR, "Poll UPS [%s] failed - %s", ups->sys, upscli_strerror(&ups->conn)); break; } /* throw COMMBAD or NOCOMM as conditions may warrant */ ups_is_gone(ups); /* if upsclient lost the connection, clean up things on our side */ if (upscli_fd(&ups->conn) == -1) { drop_connection(ups); return; } }
std::list<Device> Device::getUps(UPSCONN_t* upsconn) { std::list<Device> ret; if(!upsconn) return ret; const char* query[] = {"UPS"}; char** answer; unsigned int nbanswer; int res = upscli_list_start(upsconn, 1, query); if(res==-1) { printf("*** %d : %s\n", upscli_upserror(upsconn), upscli_strerror(upsconn)); return ret; } while(upscli_list_next(upsconn, 1, query, &nbanswer, &answer)>0) { if(nbanswer>=2) ret.push_back(Device(wxString(answer[1], wxConvISO8859_1), upsconn)); } return ret; }
static int upsclient_update_vars(void) { int ret; unsigned int numq, numa; const char *query[4]; char **answer; query[0] = "VAR"; query[1] = client_upsname; numq = 2; ret = upscli_list_start(ups, numq, query); if (ret < 0) { upsdebugx(1, "Error: %s (%i)", upscli_strerror(ups), upscli_upserror(ups)); return ret; } while (upscli_list_next(ups, numq, query, &numa, &answer) == 1) { /* VAR <upsname> <varname> <val> */ if (numa < 4) { upsdebugx(1, "Error: insufficient data (got %d args, need at least 4)", numa); } upsdebugx(5, "Received: %s %s %s %s", answer[0], answer[1], answer[2], answer[3]); /* do not override the driver collection */ if (strncmp(answer[2], "driver.", 7)) setvar(answer[2], answer[3]); } return 1; }
void upsdrv_initinfo(void) { dummy_info_t *item; switch (mode) { case MODE_DUMMY: /* Initialise basic essential variables */ for ( item = nut_data ; item->info_type != NULL ; item++ ) { if (item->drv_flags & DU_FLAG_INIT) { dstate_setinfo(item->info_type, "%s", item->default_value); dstate_setflags(item->info_type, item->info_flags); /* Set max length for strings, if needed */ if (item->info_flags & ST_FLAG_STRING) dstate_setaux(item->info_type, item->info_len); } } /* Now get user's defined variables */ if (parse_data_file(upsfd) < 0) upslogx(LOG_NOTICE, "Unable to parse the definition file %s", device_path); /* Initialize handler */ upsh.setvar = setvar; dstate_dataok(); break; case MODE_META: case MODE_REPEATER: /* Obtain the target name */ if (upscli_splitname(device_path, &client_upsname, &hostname, &port) != 0) { fatalx(EXIT_FAILURE, "Error: invalid UPS definition.\nRequired format: upsname[@hostname[:port]]"); } /* Connect to the target */ ups = xmalloc(sizeof(*ups)); if (upscli_connect(ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) { fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } else { upsdebugx(1, "Connected to %s@%s", client_upsname, hostname); } if (upsclient_update_vars() < 0) { /* check for an old upsd */ if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) { fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query"); } fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } /* FIXME: commands and settable variable! */ break; default: case MODE_NONE: fatalx(EXIT_FAILURE, "no suitable definition found!"); break; } upsh.instcmd = instcmd; dstate_addcmd("load.off"); }
static int get_var(utype_t *ups, const char *var, char *buf, size_t bufsize) { int ret; unsigned int numq, numa; const char *query[4]; char **answer; /* this shouldn't happen */ if (!ups->upsname) { upslogx(LOG_ERR, "get_var: programming error: no UPS name set [%s]", ups->sys); return -1; } numq = 0; if (!strcmp(var, "numlogins")) { query[0] = "NUMLOGINS"; query[1] = ups->upsname; numq = 2; } if (!strcmp(var, "status")) { query[0] = "VAR"; query[1] = ups->upsname; query[2] = "ups.status"; numq = 3; } if (numq == 0) { upslogx(LOG_ERR, "get_var: programming error: var=%s", var); return -1; } upsdebugx(3, "%s: %s / %s", __func__, ups->sys, var); ret = upscli_get(&ups->conn, numq, query, &numa, &answer); if (ret < 0) { /* detect old upsd */ if (upscli_upserror(&ups->conn) == UPSCLI_ERR_UNKCOMMAND) { upslogx(LOG_ERR, "UPS [%s]: Too old to monitor", ups->sys); return -1; } /* some other error */ return -1; } if (numa < numq) { upslogx(LOG_ERR, "%s: Error: insufficient data " "(got %d args, need at least %d)", var, numa, numq); return -1; } snprintf(buf, bufsize, "%s", answer[numq]); return 0; }
static void do_setvar(const char *varname, char *uin, const char *pass) { char newval[SMALLBUF], temp[SMALLBUF], user[SMALLBUF], *ptr; struct passwd *pw; if (uin) { snprintf(user, sizeof(user), "%s", uin); } else { memset(user, '\0', sizeof(user)); pw = getpwuid(getuid()); if (pw) { printf("Username (%s): ", pw->pw_name); } else { printf("Username: "******"%s", __func__); } /* deal with that pesky newline */ if (strlen(user) > 1) { user[strlen(user) - 1] = '\0'; } else { if (!pw) { fatalx(EXIT_FAILURE, "No username available - even tried getpwuid"); } snprintf(user, sizeof(user), "%s", pw->pw_name); } } /* leaks - use -p when running in valgrind */ if (!pass) { pass = GETPASS("Password: "******"getpass failed"); } } /* Check if varname is in VAR=VALUE form */ if ((ptr = strchr(varname, '=')) != NULL) { *ptr++ = 0; snprintf(newval, sizeof(newval), "%s", ptr); } else { printf("Enter new value for %s: ", varname); fflush(stdout); if (fgets(newval, sizeof(newval), stdin) == NULL) { upsdebug_with_errno(LOG_INFO, "%s", __func__); } newval[strlen(newval) - 1] = '\0'; } snprintf(temp, sizeof(temp), "USERNAME %s\n", user); if (upscli_sendline(ups, temp, strlen(temp)) < 0) { fatalx(EXIT_FAILURE, "Can't set username: %s", upscli_strerror(ups)); } if (upscli_readline(ups, temp, sizeof(temp)) < 0) { if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) { fatalx(EXIT_FAILURE, "Set username failed due to an unknown command. You probably need to upgrade upsd."); } fatalx(EXIT_FAILURE, "Set username failed: %s", upscli_strerror(ups)); } snprintf(temp, sizeof(temp), "PASSWORD %s\n", pass); if (upscli_sendline(ups, temp, strlen(temp)) < 0) { fatalx(EXIT_FAILURE, "Can't set password: %s", upscli_strerror(ups)); } if (upscli_readline(ups, temp, sizeof(temp)) < 0) { fatalx(EXIT_FAILURE, "Set password failed: %s", upscli_strerror(ups)); } /* no upsname means die */ if (!upsname) { fatalx(EXIT_FAILURE, "Error: a UPS name must be specified (upsname[@hostname[:port]])"); } /* old variable names are no longer supported */ if (!strchr(varname, '.')) { fatalx(EXIT_FAILURE, "Error: old variable names are not supported"); } do_set(varname, newval); }
static void print_rwlist(void) { int ret; unsigned int numq, numa; const char *query[2]; char **answer; struct list_t *lhead, *llast, *ltmp, *lnext; /* the upsname is now required */ if (!upsname) { fatalx(EXIT_FAILURE, "Error: a UPS name must be specified (upsname[@hostname[:port]])"); } llast = lhead = NULL; query[0] = "RW"; query[1] = upsname; numq = 2; ret = upscli_list_start(ups, numq, query); if (ret < 0) { /* old upsd --> fall back on old LISTRW technique */ if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) { fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query"); } fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } ret = upscli_list_next(ups, numq, query, &numa, &answer); while (ret == 1) { /* RW <upsname> <varname> <value> */ if (numa < 4) { fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa); } /* sock this entry away for later */ ltmp = xmalloc(sizeof(struct list_t)); ltmp->name = xstrdup(answer[2]); ltmp->next = NULL; if (llast) { llast->next = ltmp; } else { lhead = ltmp; } llast = ltmp; ret = upscli_list_next(ups, numq, query, &numa, &answer); } /* use the list to get descriptions and types */ ltmp = lhead; while (ltmp) { lnext = ltmp->next; print_rw(ltmp->name); free(ltmp->name); free(ltmp); ltmp = lnext; } }