int main(int argc, char **argv) { int i, port; const char *prog = xbasename(argv[0]); char *password = NULL, *username = NULL, *setvar = NULL; while ((i = getopt(argc, argv, "+hs:p:u:V")) != -1) { switch (i) { case 's': setvar = optarg; break; case 'p': password = optarg; break; case 'u': username = optarg; break; case 'V': printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); exit(EXIT_SUCCESS); case 'h': default: usage(prog); exit(EXIT_SUCCESS); } } argc -= optind; argv += optind; if (argc < 1) { usage(prog); exit(EXIT_SUCCESS); } /* be a good little client that cleans up after itself */ atexit(clean_exit); if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0) { fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]"); } ups = xcalloc(1, sizeof(*ups)); if (upscli_connect(ups, hostname, port, 0) < 0) { fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } if (setvar) { /* setting a variable */ do_setvar(setvar, username, password); } else { /* if not, get the list of supported read/write variables */ print_rwlist(); } exit(EXIT_SUCCESS); }
static void do_range(const char *varname) { int ret; unsigned int numq, numa; char **answer; const char *query[4], *val; int ival, min, max; /* get current value */ val = get_data("VAR", varname); if (!val) { fatalx(EXIT_FAILURE, "do_range: can't get current value of %s", varname); } ival = atoi(val); query[0] = "RANGE"; query[1] = upsname; query[2] = varname; numq = 3; ret = upscli_list_start(ups, numq, query); if (ret < 0) { fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } ret = upscli_list_next(ups, numq, query, &numa, &answer); printf("Type: RANGE\n"); while (ret == 1) { /* RANGE <upsname> <varname> <min> <max> */ if (numa < 5) { fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa); } min = atoi(answer[3]); max = atoi(answer[4]); printf("Option: \"%i-%i\"", min, max); if ((ival >= min) && (ival <= max)) { printf(" SELECTED"); } printf("\n"); ret = upscli_list_next(ups, numq, query, &numa, &answer); } }
/* check for master permissions on the server for this ups */ static int checkmaster(utype_t *ups) { char buf[SMALLBUF]; /* don't bother if we're not configured as a master for this ups */ if (!flag_isset(ups->status, ST_MASTER)) return 1; /* this shouldn't happen (LOGIN checks it earlier) */ if ((ups->upsname == NULL) || (strlen(ups->upsname) == 0)) { upslogx(LOG_ERR, "Set master on UPS [%s] failed: empty upsname", ups->sys); return 0; } snprintf(buf, sizeof(buf), "MASTER %s\n", ups->upsname); if (upscli_sendline(&ups->conn, buf, strlen(buf)) < 0) { upslogx(LOG_ALERT, "Can't set master mode on UPS [%s] - %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } if (upscli_readline(&ups->conn, buf, sizeof(buf)) == 0) { if (!strncmp(buf, "OK", 2)) return 1; /* not ERR, but not caught by readline either? */ upslogx(LOG_ALERT, "Master privileges unavailable on UPS [%s]", ups->sys); upslogx(LOG_ALERT, "Response: [%s]", buf); } else { /* something caught by readraw's parsing call */ upslogx(LOG_ALERT, "Master privileges unavailable on UPS [%s]", ups->sys); upslogx(LOG_ALERT, "Reason: %s", upscli_strerror(&ups->conn)); } return 0; }
static void do_set(const char *varname, const char *newval) { char buf[SMALLBUF], enc[SMALLBUF]; snprintf(buf, sizeof(buf), "SET VAR %s %s \"%s\"\n", upsname, varname, pconf_encode(newval, enc, sizeof(enc))); if (upscli_sendline(ups, buf, strlen(buf)) < 0) { fatalx(EXIT_FAILURE, "Can't set variable: %s", upscli_strerror(ups)); } if (upscli_readline(ups, buf, sizeof(buf)) < 0) { fatalx(EXIT_FAILURE, "Set variable failed: %s", upscli_strerror(ups)); } /* FUTURE: status cookies will tie in here */ if (strncmp(buf, "OK", 2) != 0) { fatalx(EXIT_FAILURE, "Unexpected response from upsd: %s", buf); } fprintf(stderr, "%s\n", buf); }
/* handle connecting to upsd, plus get SSL going too if possible */ static int try_connect(utype_t *ups) { int flags = 0, ret; upsdebugx(1, "Trying to connect to UPS [%s]", ups->sys); clearflag(&ups->status, ST_CONNECTED); /* force it if configured that way, just try it otherwise */ if (forcessl == 1) flags |= UPSCLI_CONN_REQSSL; else flags |= UPSCLI_CONN_TRYSSL; if (opt_af == AF_INET) flags |= UPSCLI_CONN_INET; if (opt_af == AF_INET6) flags |= UPSCLI_CONN_INET6; ret = upscli_connect(&ups->conn, ups->hostname, ups->port, flags); if (ret < 0) { upslogx(LOG_ERR, "UPS [%s]: connect failed: %s", ups->sys, upscli_strerror(&ups->conn)); ups_is_gone(ups); return 0; } ret = try_ssl(ups); if (ret == 0) return 0; /* something broke while trying SSL */ /* we're definitely connected now */ setflag(&ups->status, ST_CONNECTED); /* now try to authenticate to upsd */ ret = do_upsd_auth(ups); if (ret == 1) return 1; /* everything is happy */ /* something failed in the auth so we may not be completely logged in */ /* FUTURE: do something beyond the error msgs from do_upsd_auth? */ return 0; }
/* set forced shutdown flag so other upsmons know what's going on here */ static void setfsd(utype_t *ups) { char buf[SMALLBUF]; int ret; /* this shouldn't happen */ if (!ups->upsname) { upslogx(LOG_ERR, "setfsd: programming error: no UPS name set [%s]", ups->sys); return; } upsdebugx(2, "Setting FSD on UPS %s", ups->sys); snprintf(buf, sizeof(buf), "FSD %s\n", ups->upsname); ret = upscli_sendline(&ups->conn, buf, strlen(buf)); if (ret < 0) { upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys, upscli_strerror(&ups->conn)); return; } ret = upscli_readline(&ups->conn, buf, sizeof(buf)); if (ret < 0) { upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys, upscli_strerror(&ups->conn)); return; } if (!strncmp(buf, "OK", 2)) return; /* protocol error: upsd said something other than "OK" */ upslogx(LOG_ERR, "FSD set on UPS %s failed: %s", ups->sys, buf); }
static void do_enum(const char *varname) { int ret; unsigned int numq, numa; char **answer, buf[SMALLBUF]; const char *query[4], *val; /* get current value */ val = get_data("VAR", varname); if (!val) { fatalx(EXIT_FAILURE, "do_enum: can't get current value of %s", varname); } snprintf(buf, sizeof(buf), "%s", val); query[0] = "ENUM"; query[1] = upsname; query[2] = varname; numq = 3; ret = upscli_list_start(ups, numq, query); if (ret < 0) { fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } ret = upscli_list_next(ups, numq, query, &numa, &answer); printf("Type: ENUM\n"); while (ret == 1) { /* ENUM <upsname> <varname> <value> */ if (numa < 4) { fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa); } printf("Option: \"%s\"", answer[3]); if (!strcmp(answer[3], buf)) { printf(" SELECTED"); } printf("\n"); ret = upscli_list_next(ups, numq, query, &numa, &answer); } }
/* 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; } }
static int try_ssl(utype_t *ups) { int ret; /* if not doing SSL, we're done */ if (!upscli_ssl(&ups->conn)) return 1; if (!certpath) { if (certverify == 1) { upslogx(LOG_ERR, "Configuration error: " "CERTVERIFY is set, but CERTPATH isn't"); upslogx(LOG_ERR, "UPS [%s]: Connection impossible, " "dropping link", ups->sys); ups_is_gone(ups); drop_connection(ups); return 0; /* failed */ } /* certverify is 0, so just warn them and return */ upslogx(LOG_WARNING, "Certificate verification is disabled"); return 1; } /* you REALLY should set CERTVERIFY to 1 if using SSL... */ if (certverify == 0) upslogx(LOG_WARNING, "Certificate verification is disabled"); ret = upscli_sslcert(&ups->conn, NULL, certpath, certverify); if (ret < 0) { upslogx(LOG_ERR, "UPS [%s]: SSL certificate set failed: %s", ups->sys, upscli_strerror(&ups->conn)); ups_is_gone(ups); drop_connection(ups); return 0; } return 1; }
void upsdrv_updateinfo(void) { upsdebugx(1, "upsdrv_updateinfo..."); sleep(1); switch (mode) { case MODE_DUMMY: /* Now get user's defined variables */ if (parse_data_file(upsfd) >= 0) dstate_dataok(); break; case MODE_META: case MODE_REPEATER: if (upsclient_update_vars() > 0) { dstate_dataok(); } else { /* try to reconnect */ upscli_disconnect(ups); if (upscli_connect(ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) { upsdebugx(1, "Error reconnecting: %s", upscli_strerror(ups)); } else { upsdebugx(1, "Reconnected"); } } break; case MODE_NONE: default: break; } }
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; }
static int nut_read_one (nut_ups_t *ups) { const char *query[3] = {"VAR", ups->upsname, NULL}; unsigned int query_num = 2; char **answer; unsigned int answer_num; int status; /* (Re-)Connect if we have no connection */ if (ups->conn == NULL) { ups->conn = (collectd_upsconn_t *) malloc (sizeof (collectd_upsconn_t)); if (ups->conn == NULL) { ERROR ("nut plugin: malloc failed."); return (-1); } status = upscli_connect (ups->conn, ups->hostname, ups->port, UPSCLI_CONN_TRYSSL); if (status != 0) { ERROR ("nut plugin: nut_read_one: upscli_connect (%s, %i) failed: %s", ups->hostname, ups->port, upscli_strerror (ups->conn)); sfree (ups->conn); return (-1); } INFO ("nut plugin: Connection to (%s, %i) established.", ups->hostname, ups->port); } /* if (ups->conn == NULL) */ /* nut plugin: nut_read_one: upscli_list_start (adpos) failed: Protocol * error */ status = upscli_list_start (ups->conn, query_num, query); if (status != 0) { ERROR ("nut plugin: nut_read_one: upscli_list_start (%s) failed: %s", ups->upsname, upscli_strerror (ups->conn)); upscli_disconnect (ups->conn); sfree (ups->conn); return (-1); } while ((status = upscli_list_next (ups->conn, query_num, query, &answer_num, &answer)) == 1) { char *key; double value; if (answer_num < 4) continue; key = answer[2]; value = atof (answer[3]); if (strncmp ("ambient.", key, 8) == 0) { if (strcmp ("ambient.humidity", key) == 0) nut_submit (ups, "humidity", "ambient", value); else if (strcmp ("ambient.temperature", key) == 0) nut_submit (ups, "temperature", "ambient", value); } else if (strncmp ("battery.", key, 8) == 0) { if (strcmp ("battery.charge", key) == 0) nut_submit (ups, "percent", "charge", value); else if (strcmp ("battery.current", key) == 0) nut_submit (ups, "current", "battery", value); else if (strcmp ("battery.runtime", key) == 0) nut_submit (ups, "timeleft", "battery", value); else if (strcmp ("battery.temperature", key) == 0) nut_submit (ups, "temperature", "battery", value); else if (strcmp ("battery.voltage", key) == 0) nut_submit (ups, "voltage", "battery", value); } else if (strncmp ("input.", key, 6) == 0) { if (strcmp ("input.frequency", key) == 0) nut_submit (ups, "frequency", "input", value); else if (strcmp ("input.voltage", key) == 0) nut_submit (ups, "voltage", "input", value); } else if (strncmp ("output.", key, 7) == 0) { if (strcmp ("output.current", key) == 0) nut_submit (ups, "current", "output", value); else if (strcmp ("output.frequency", key) == 0) nut_submit (ups, "frequency", "output", value); else if (strcmp ("output.voltage", key) == 0) nut_submit (ups, "voltage", "output", value); } else if (strncmp ("ups.", key, 4) == 0) { if (strcmp ("ups.load", key) == 0) nut_submit (ups, "percent", "load", value); else if (strcmp ("ups.power", key) == 0) nut_submit (ups, "power", "ups", value); else if (strcmp ("ups.temperature", key) == 0) nut_submit (ups, "temperature", "ups", value); } } /* while (upscli_list_next) */ return (0); } /* int nut_read_one */
int main(int argc, char **argv) { int interval = 30, i; const char *prog = xbasename(argv[0]); time_t now, nextpoll = 0; const char *user = NULL; struct passwd *new_uid = NULL; const char *pidfilebase = prog; logformat = DEFAULT_LOGFORMAT; user = RUN_AS_USER; printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:")) != -1) { switch(i) { case 'h': help(prog); break; case 's': monhost = optarg; break; case 'l': logfn = optarg; break; case 'i': interval = atoi(optarg); break; case 'f': logformat = optarg; break; case 'u': user = optarg; break; case 'V': exit(EXIT_SUCCESS); case 'p': pidfilebase = optarg; break; } } argc -= optind; argv += optind; /* not enough args for the old way? */ if ((argc == 1) || (argc == 2)) help(prog); /* see if it's being called in the old style - 3 or 4 args */ /* <system> <logfn> <interval> [<format>] */ if (argc >= 3) { monhost = argv[0]; logfn = argv[1]; interval = atoi(argv[2]); } if (argc >= 4) { /* read out the remaining argv entries to the format string */ logformat = xmalloc(LARGEBUF); memset(logformat, '\0', LARGEBUF); for (i = 3; i < argc; i++) snprintfcat(logformat, LARGEBUF, "%s ", argv[i]); } if (!monhost) fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s <system>"); if (!logfn) fatalx(EXIT_FAILURE, "No filename defined for logging - use -l <file>"); /* shouldn't happen */ if (!logformat) fatalx(EXIT_FAILURE, "No format defined - but this should be impossible"); printf("logging status of %s to %s (%is intervals)\n", monhost, logfn, interval); if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) { fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); } if (upscli_connect(&ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) fprintf(stderr, "Warning: initial connect failed: %s\n", upscli_strerror(&ups)); if (strcmp(logfn, "-") == 0) logfile = stdout; else logfile = fopen(logfn, "a"); if (logfile == NULL) fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn); /* now drop root if we have it */ new_uid = get_user_pwent(user); open_syslog(prog); if (logfile != stdout) background(); setup_signals(); writepid(pidfilebase); become_user(new_uid); compile_format(); while (exit_flag == 0) { time(&now); if (nextpoll > now) { /* there is still time left, so sleep it off */ sleep(difftime(nextpoll, now)); nextpoll += interval; } else { /* we spent more time in polling than the interval allows */ nextpoll = now + interval; } if (reopen_flag) { upslogx(LOG_INFO, "Signal %d: reopening log file", reopen_flag); reopen_log(); reopen_flag = 0; } /* reconnect if necessary */ if (upscli_fd(&ups) < 0) { upscli_connect(&ups, hostname, port, 0); } run_flist(); /* don't keep connection open if we don't intend to use it shortly */ if (interval > 30) { upscli_disconnect(&ups); } } upslogx(LOG_INFO, "Signal %d: exiting", exit_flag); if (logfile != stdout) fclose(logfile); upscli_disconnect(&ups); exit(EXIT_SUCCESS); }
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 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; } }
/* authenticate to upsd, plus do LOGIN and MASTER if applicable */ static int do_upsd_auth(utype_t *ups) { char buf[SMALLBUF]; if (!ups->un) { upslogx(LOG_ERR, "UPS [%s]: no username defined!", ups->sys); return 0; } snprintf(buf, sizeof(buf), "USERNAME %s\n", ups->un); if (upscli_sendline(&ups->conn, buf, strlen(buf)) < 0) { upslogx(LOG_ERR, "Can't set username on [%s]: %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } if (upscli_readline(&ups->conn, buf, sizeof(buf)) < 0) { upslogx(LOG_ERR, "Set username on [%s] failed: %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } /* authenticate first */ snprintf(buf, sizeof(buf), "PASSWORD %s\n", ups->pw); if (upscli_sendline(&ups->conn, buf, strlen(buf)) < 0) { upslogx(LOG_ERR, "Can't set password on [%s]: %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } if (upscli_readline(&ups->conn, buf, sizeof(buf)) < 0) { upslogx(LOG_ERR, "Set password on [%s] failed: %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } /* catch insanity from the server - not ERR and not OK either */ if (strncmp(buf, "OK", 2) != 0) { upslogx(LOG_ERR, "Set password on [%s] failed - got [%s]", ups->sys, buf); return 0; } /* we require a upsname now */ if ((ups->upsname == NULL) || (strlen(ups->upsname) == 0)) { upslogx(LOG_ERR, "Login to UPS [%s] failed: empty upsname", ups->sys); return 0; } /* password is set, let's login */ snprintf(buf, sizeof(buf), "LOGIN %s\n", ups->upsname); if (upscli_sendline(&ups->conn, buf, strlen(buf)) < 0) { upslogx(LOG_ERR, "Login to UPS [%s] failed: %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } if (upscli_readline(&ups->conn, buf, sizeof(buf)) < 0) { upslogx(LOG_ERR, "Can't login to UPS [%s]: %s", ups->sys, upscli_strerror(&ups->conn)); return 0; } /* catch insanity from the server - not ERR and not OK either */ if (strncmp(buf, "OK", 2) != 0) { upslogx(LOG_ERR, "Login on UPS [%s] failed - got [%s]", ups->sys, buf); return 0; } /* finally - everything is OK */ upsdebugx(1, "Logged into UPS %s", ups->sys); setflag(&ups->status, ST_LOGIN); /* now see if we also need to test master permissions */ return checkmaster(ups); }
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); }