/* translate HID numeric path to string path and return path depth */ static int path_to_string(char *string, size_t size, const HIDPath_t *path, usage_tables_t *utab) { int i; const char *p; snprintf(string, size, "%s", ""); for (i = 0; i < path->Size; i++) { if (i > 0) snprintfcat(string, size, "."); /* lookup tables first (to override defaults) */ if ((p = hid_lookup_path(path->Node[i], utab)) != NULL) { snprintfcat(string, size, "%s", p); continue; } /* indexed collection */ if ((path->Node[i] & 0xffff0000) == 0x00ff0000) { snprintfcat(string, size, "[%i]", path->Node[i] & 0x0000ffff); continue; } /* unnamed path components such as "ff860024" */ snprintfcat(string, size, "%08x", path->Node[i]); } return i; }
/* write the status_buf into the externally visible dstate storage */ void status_commit(void) { while (ignorelb) { const char *val, *low; val = dstate_getinfo("battery.charge"); low = dstate_getinfo("battery.charge.low"); if (val && low && (strtol(val, NULL, 10) < strtol(low, NULL, 10))) { snprintfcat(status_buf, sizeof(status_buf), " LB"); upsdebugx(2, "%s: appending LB flag [charge '%s' below '%s']", __func__, val, low); break; } val = dstate_getinfo("battery.runtime"); low = dstate_getinfo("battery.runtime.low"); if (val && low && (strtol(val, NULL, 10) < strtol(low, NULL, 10))) { snprintfcat(status_buf, sizeof(status_buf), " LB"); upsdebugx(2, "%s: appending LB flag [runtime '%s' below '%s']", __func__, val, low); break; } /* LB condition not detected */ break; } if (alarm_active) { dstate_setinfo("ups.status", "ALARM %s", status_buf); } else { dstate_setinfo("ups.status", "%s", status_buf); } }
void alarm_set(const char *buf) { if (strlen(alarm_buf) > 0) { snprintfcat(alarm_buf, sizeof(alarm_buf), " %s", buf); } else { snprintfcat(alarm_buf, sizeof(alarm_buf), "%s", buf); } }
/* add a status element */ void status_set(const char *buf) { if (ignorelb && !strcasecmp(buf, "LB")) { upsdebugx(2, "%s: ignoring LB flag from device", __func__); return; } /* separate with a space if multiple elements are present */ if (strlen(status_buf) > 0) { snprintfcat(status_buf, sizeof(status_buf), " %s", buf); } else { snprintfcat(status_buf, sizeof(status_buf), "%s", buf); } }
static void do_etime(const char *arg) { time_t tod; time(&tod); snprintfcat(logbuffer, sizeof(logbuffer), "%ld", (unsigned long) tod); }
/** @copydoc widgetdata::event_func */ static int widget_event(widgetdata *widget, SDL_Event *event) { network_graph_widget_t *network_graph = widget->subwidget; network_graph_data_t *data = &network_graph->data[network_graph->type]; if (event->type == SDL_MOUSEMOTION) { int x = event->motion.x - widget->x; if (x < 0 || x >= widget->w) { return 0; } char buf[HUGE_BUF]; snprintf(VS(buf), "Maximum: %" PRIu64 " Bytes/s (%" PRIu64 " kB/s)", (uint64_t) data->max, (uint64_t) data->max / 1000); for (int i = 0; i < NETWORK_GRAPH_TRAFFIC_MAX; i++) { size_t bytes = data->data[x * NETWORK_GRAPH_TRAFFIC_MAX + i]; snprintfcat(VS(buf), "\n%s: %" PRIu64 " Bytes/s (%" PRIu64 " kB/s)", network_graph_filters[i], (uint64_t) bytes, (uint64_t) bytes / 1000); } tooltip_create(event->motion.x, event->motion.y, FONT_ARIAL11, buf); tooltip_multiline(200); tooltip_enable_delay(100); } return 0; }
static void get_type(nut_ctype_t *client, const char *upsname, const char *var) { char buf[SMALLBUF]; const upstype_t *ups; const st_tree_t *node; ups = get_ups_ptr(upsname); if (!ups) { send_err(client, NUT_ERR_UNKNOWN_UPS); return; } if (!ups_available(ups, client)) return; node = sstate_getnode(ups, var); if (!node) { send_err(client, NUT_ERR_VAR_NOT_SUPPORTED); return; } snprintf(buf, sizeof(buf), "TYPE %s %s", upsname, var); if (node->flags & ST_FLAG_RW) snprintfcat(buf, sizeof(buf), " RW"); if (node->enum_list) { snprintfcat(buf, sizeof(buf), " ENUM"); } if (node->range_list) { snprintfcat(buf, sizeof(buf), " RANGE"); } if (node->flags & ST_FLAG_STRING) { sendback(client, "%s STRING:%d\n", buf, node->aux); return; } /* Any variable that is not string | range | enum is just a simple * numeric value */ sendback(client, "%s NUMBER\n", buf); }
static void getvar(const char *var) { int ret; unsigned int numq, numa; const char *query[4]; char **answer; query[0] = "VAR"; query[1] = upsname; query[2] = var; numq = 3; ret = upscli_get(&ups, numq, query, &numa, &answer); if ((ret < 0) || (numa < numq)) { snprintfcat(logbuffer, sizeof(logbuffer), "NA"); return; } snprintfcat(logbuffer, sizeof(logbuffer), "%s", answer[3]); }
static void do_var(const char *arg) { if ((!arg) || (strlen(arg) < 1)) { snprintfcat(logbuffer, sizeof(logbuffer), "INVALID"); return; } /* old variable names are no longer supported */ if (!strchr(arg, '.')) { snprintfcat(logbuffer, sizeof(logbuffer), "INVALID"); return; } /* a UPS name is now required */ if (!upsname) { snprintfcat(logbuffer, sizeof(logbuffer), "INVALID"); return; } getvar(arg); }
/* print out a command line at the given debug level. */ static void debugcmdline(int level, const char *msg, char *const argv[]) { char cmdline[LARGEBUF]; snprintf(cmdline, sizeof(cmdline), "%s", msg); while (*argv) { snprintfcat(cmdline, sizeof(cmdline), " %s", *argv++); } upsdebugx(level, "%s", cmdline); }
void dstate_setflags(const char *var, int flags) { st_tree_t *sttmp; char flist[SMALLBUF]; /* find the dtree node for var */ sttmp = state_tree_find(dtree_root, var); if (!sttmp) { upslogx(LOG_ERR, "%s: base variable (%s) does not exist", __func__, var); return; } if (sttmp->flags & ST_FLAG_IMMUTABLE) { upslogx(LOG_WARNING, "%s: base variable (%s) is immutable", __func__, var); return; } if (sttmp->flags == flags) { return; /* no change */ } sttmp->flags = flags; /* build the list */ snprintf(flist, sizeof(flist), "%s", var); if (flags & ST_FLAG_RW) { snprintfcat(flist, sizeof(flist), " RW"); } if (flags & ST_FLAG_STRING) { snprintfcat(flist, sizeof(flist), " STRING"); } /* update listeners */ send_to_all("SETFLAGS %s\n", flist); }
/* print current host name */ static void do_host(const char *arg) { int ret; char hn[LARGEBUF]; ret = gethostname(hn, sizeof(hn)); if (ret != 0) { upslog_with_errno(LOG_ERR, "gethostname failed"); return; } snprintfcat(logbuffer, sizeof(logbuffer), "%s", hn); }
void load_upsdconf(int reloading) { char fn[SMALLBUF]; PCONF_CTX_t ctx; snprintf(fn, sizeof(fn), "%s/upsd.conf", confpath()); check_perms(fn); pconf_init(&ctx, upsd_conf_err); if (!pconf_file_begin(&ctx, fn)) { pconf_finish(&ctx); if (!reloading) fatalx(EXIT_FAILURE, "%s", ctx.errmsg); upslogx(LOG_ERR, "Reload failed: %s", ctx.errmsg); return; } while (pconf_file_next(&ctx)) { if (pconf_parse_error(&ctx)) { upslogx(LOG_ERR, "Parse error: %s:%d: %s", fn, ctx.linenum, ctx.errmsg); continue; } if (ctx.numargs < 1) continue; if (!parse_upsd_conf_args(ctx.numargs, ctx.arglist)) { unsigned int i; char errmsg[SMALLBUF]; snprintf(errmsg, sizeof(errmsg), "upsd.conf: invalid directive"); for (i = 0; i < ctx.numargs; i++) snprintfcat(errmsg, sizeof(errmsg), " %s", ctx.arglist[i]); upslogx(LOG_WARNING, "%s", errmsg); } } pconf_finish(&ctx); }
/* dump message msg and len bytes from buf to upsdebugx(level) in ascii. */ void upsdebug_ascii(int level, const char *msg, const void *buf, int len) { char line[256]; int i; unsigned char ch; if (nut_debug_level < level) return; /* save cpu cycles */ snprintf(line, sizeof(line), "%s", msg); for (i=0; i<len; ++i) { ch = ((unsigned char *)buf)[i]; if (ch < 0x20) snprintfcat(line, sizeof(line), "%3s ", ascii_symb[ch]); else if (ch >= 0x80) snprintfcat(line, sizeof(line), "%02Xh ", ch); else snprintfcat(line, sizeof(line), "'%c' ", ch); } upsdebugx(level, "%s", line); }
/** * Shows version information. * @param op * If NULL the version is logged using LOG(), otherwise it is * shown to the player object using draw_info_format(). */ void version(object *op) { char buf[HUGE_BUF]; snprintf(VS(buf), "This is Atrinik v%s", PACKAGE_VERSION); #ifdef GITVERSION snprintfcat(VS(buf), "%s", " (" STRINGIFY(GITBRANCH) "/" STRINGIFY(GITVERSION) " by " STRINGIFY(GITAUTHOR) ")"); #endif if (op != NULL) { draw_info(COLOR_WHITE, op, buf); } else { LOG(INFO, "%s", buf); } }
static void loadconfig(void) { PCONF_CTX_t ctx; pconf_init(&ctx, upsmon_err); if (!pconf_file_begin(&ctx, configfile)) { pconf_finish(&ctx); if (reload_flag == 1) { upslog_with_errno(LOG_ERR, "Reload failed: %s", ctx.errmsg); return; } fatalx(EXIT_FAILURE, "%s", ctx.errmsg); } while (pconf_file_next(&ctx)) { if (pconf_parse_error(&ctx)) { upslogx(LOG_ERR, "Parse error: %s:%d: %s", configfile, ctx.linenum, ctx.errmsg); continue; } if (ctx.numargs < 1) continue; if (!parse_conf_arg(ctx.numargs, ctx.arglist)) { unsigned int i; char errmsg[SMALLBUF]; snprintf(errmsg, sizeof(errmsg), "%s line %d: invalid directive", configfile, ctx.linenum); for (i = 0; i < ctx.numargs; i++) snprintfcat(errmsg, sizeof(errmsg), " %s", ctx.arglist[i]); upslogx(LOG_WARNING, "%s", errmsg); } } pconf_finish(&ctx); }
/* dump message msg and len bytes from buf to upsdebugx(level) in hexadecimal. (This function replaces Philippe Marzouk's original dump_hex() function) */ void upsdebug_hex(int level, const char *msg, const void *buf, int len) { char line[100]; int n; /* number of characters currently in line */ int i; /* number of bytes output from buffer */ n = snprintf(line, sizeof(line), "%s: (%d bytes) =>", msg, len); for (i = 0; i < len; i++) { if (n > 72) { upsdebugx(level, "%s", line); line[0] = 0; } n = snprintfcat(line, sizeof(line), n ? " %02x" : "%02x", ((unsigned char *)buf)[i]); } upsdebugx(level, "%s", line); }
static void do_time(const char *arg) { unsigned int i; char timebuf[SMALLBUF], *format; time_t tod; format = xstrdup(arg); /* @s are used on the command line since % is taken */ for (i = 0; i < strlen(format); i++) if (format[i] == '@') format[i] = '%'; time(&tod); strftime(timebuf, sizeof(timebuf), format, localtime(&tod)); snprintfcat(logbuffer, sizeof(logbuffer), "%s", timebuf); free(format); }
static void vupslog(int priority, const char *fmt, va_list va, int use_strerror) { int ret; char buf[LARGEBUF]; ret = vsnprintf(buf, sizeof(buf), fmt, va); if ((ret < 0) || (ret >= (int) sizeof(buf))) syslog(LOG_WARNING, "vupslog: vsnprintf needed more than %d bytes", LARGEBUF); if (use_strerror) snprintfcat(buf, sizeof(buf), ": %s", strerror(errno)); if (nut_debug_level > 0) { static struct timeval start = { 0 }; struct timeval now; gettimeofday(&now, NULL); if (start.tv_sec == 0) { start = now; } if (start.tv_usec > now.tv_usec) { now.tv_usec += 1000000; now.tv_sec -= 1; } fprintf(stderr, "%4.0f.%06ld\t", difftime(now.tv_sec, start.tv_sec), (long)(now.tv_usec - start.tv_usec)); } if (xbit_test(upslog_flags, UPSLOG_STDERR)) fprintf(stderr, "%s\n", buf); if (xbit_test(upslog_flags, UPSLOG_SYSLOG)) syslog(priority, "%s", buf); }
static void sendcmd(const char *cmd, const char *arg1, const char *arg2) { int i, pipefd, ret; char buf[SMALLBUF], enc[SMALLBUF]; /* insanity */ if (!arg1) return; /* build the request */ snprintf(buf, sizeof(buf), "%s \"%s\"", cmd, pconf_encode(arg1, enc, sizeof(enc))); if (arg2) snprintfcat(buf, sizeof(buf), " \"%s\"", pconf_encode(arg2, enc, sizeof(enc))); snprintf(enc, sizeof(enc), "%s\n", buf); /* see if the parent needs to be started (and maybe start it) */ for (i = 0; i < MAX_TRIES; i++) { pipefd = check_parent(cmd, arg2); if (pipefd == PARENT_STARTED) { /* loop back and try to connect now */ usleep(250000); continue; } /* special case for CANCEL when no parent is running */ if (pipefd == PARENT_UNNECESSARY) return; /* we're connected now */ ret = write(pipefd, enc, strlen(enc)); /* if we can't send the whole thing, loop back and try again */ if ((ret < 1) || (ret != (int) strlen(enc))) { upslogx(LOG_ERR, "write failed, trying again"); close(pipefd); continue; } /* ugh - probably should use select here... */ setup_sigalrm(); alarm(2); ret = read(pipefd, buf, sizeof(buf)); alarm(0); signal(SIGALRM, SIG_IGN); close(pipefd); /* same idea: no OK = go try it all again */ if (ret < 2) { upslogx(LOG_ERR, "read confirmation failed, trying again"); continue; } if (!strncmp(buf, "OK", 2)) return; /* success */ upslogx(LOG_ERR, "read confirmation got [%s]", buf); /* try again ... */ } fatalx(EXIT_FAILURE, "Unable to connect to daemon and unable to start daemon"); }
static int st_tree_dump_conn(st_tree_t *node, conn_t *conn) { int ret; enum_t *etmp; range_t *rtmp; if (!node) { return 1; /* not an error */ } if (node->left) { ret = st_tree_dump_conn(node->left, conn); if (!ret) { return 0; /* write failed in the child */ } } if (!send_to_one(conn, "SETINFO %s \"%s\"\n", node->var, node->val)) { return 0; /* write failed, bail out */ } /* send any enums */ for (etmp = node->enum_list; etmp; etmp = etmp->next) { if (!send_to_one(conn, "ADDENUM %s \"%s\"\n", node->var, etmp->val)) { return 0; } } /* send any ranges */ for (rtmp = node->range_list; rtmp; rtmp = rtmp->next) { if (!send_to_one(conn, "ADDRANGE %s %i %i\n", node->var, rtmp->min, rtmp->max)) { return 0; } } /* provide any auxiliary data */ if (node->aux) { if (!send_to_one(conn, "SETAUX %s %d\n", node->var, node->aux)) { return 0; } } /* finally report any flags */ if (node->flags) { char flist[SMALLBUF]; /* build the list */ snprintf(flist, sizeof(flist), "%s", node->var); if (node->flags & ST_FLAG_RW) { snprintfcat(flist, sizeof(flist), " RW"); } if (node->flags & ST_FLAG_STRING) { snprintfcat(flist, sizeof(flist), " STRING"); } if (!send_to_one(conn, "SETFLAGS %s\n", flist)) { return 0; } } if (node->right) { return st_tree_dump_conn(node->right, conn); } return 1; /* everything's OK here ... */ }
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); }
static void print_literal(const char *arg) { snprintfcat(logbuffer, sizeof(logbuffer), "%s", arg); }
/* Preprocess the answer we got back from the UPS when queried with 'QS\r' */ static int voltronic_qs_hex_preprocess_qs_answer(item_t *item, const int len) { int i, token; char refined[SMALLBUF] = ""; if (len <= 0) return len; if (item->answer[0] != '#') { upsdebugx(4, "%s: wrong leading character [%s: 0x%0x]", __func__, item->info_type, item->answer[0]); return -1; } snprintf(refined, sizeof(refined), "%s", "#"); /* e.g.: item->answer = "#\x6C\x01 \x35 \x6C\x01 \x35 \x03 \x51\x9A \x28\x02\x12\xD0 \xE6 \x1E \x09\r" */ upsdebug_hex(4, "read", item->answer, len); for (i = 1, token = 1; i < len; i++) { /* New token */ if (item->answer[i] == 0x20) { snprintfcat(refined, sizeof(refined), "%s", " "); token++; continue; } /* 'Unescape' raw data */ if (item->answer[i] == 0x28 && i < len) { switch (item->answer[i + 1]) { case 0x00: /* Escaped because: CR */ snprintfcat(refined, sizeof(refined), "%02x", 0x0D); break; case 0x01: /* Escaped because: XON */ snprintfcat(refined, sizeof(refined), "%02x", 0x11); break; case 0x02: /* Escaped because: XOFF */ snprintfcat(refined, sizeof(refined), "%02x", 0x13); break; case 0x03: /* Escaped because: LF */ snprintfcat(refined, sizeof(refined), "%02x", 0x0A); break; case 0x04: /* Escaped because: space */ snprintfcat(refined, sizeof(refined), "%02x", 0x20); break; default: if (token != 10) snprintfcat(refined, sizeof(refined), "%02x", ((unsigned char *)item->answer)[i]); else snprintfcat(refined, sizeof(refined), "%08d", voltronic_qs_hex_status_char_to_binary(((unsigned char *)item->answer)[i])); continue; } i++; continue; } /* Trailing CR */ if (item->answer[i] == 0x0D) break; if (token != 10) snprintfcat(refined, sizeof(refined), "%02x", ((unsigned char *)item->answer)[i]); else snprintfcat(refined, sizeof(refined), "%08d", voltronic_qs_hex_status_char_to_binary(((unsigned char *)item->answer)[i])); } if (token != 10 || strlen(refined) != 46) { upsdebugx(2, "noncompliant reply: %s", refined); return -1; } upsdebugx(4, "read: %s", refined); /* e.g.: item->answer = "#6C01 35 6C01 35 03 519A 1312D0 E6 1E 00001001" */ return snprintf(item->answer, sizeof(item->answer), "%s\r", refined); }
static int netxml_alarm_subscribe(const char *page) { int ret, port = -1, secret = -1; char buf[LARGEBUF], *s; ne_request *request; ne_sock_addr *addr; const ne_inet_addr *ai; char resp_buf[LARGEBUF]; /* Clear response buffer */ memset(resp_buf, 0, sizeof(resp_buf)); upsdebugx(2, "%s: %s", __func__, page); sock = ne_sock_create(); if (gethostname(buf, sizeof(buf)) == 0) { dstate_setinfo("driver.hostname", "%s", buf); } else { dstate_setinfo("driver.hostname", "<unknown>"); } #ifdef HAVE_NE_SOCK_CONNECT_TIMEOUT ne_sock_connect_timeout(sock, timeout); #endif ne_sock_read_timeout(sock, 1); netxml_get_page(subdriver->configure); snprintf(buf, sizeof(buf), "<?xml version=\"1.0\"?>\n"); snprintfcat(buf, sizeof(buf), "<Subscribe>\n"); snprintfcat(buf, sizeof(buf), "<Class>%s v%s</Class>\n", progname, DRIVER_VERSION); snprintfcat(buf, sizeof(buf), "<Type>connected socket</Type>\n"); snprintfcat(buf, sizeof(buf), "<HostName>%s</HostName>\n", dstate_getinfo("driver.hostname")); snprintfcat(buf, sizeof(buf), "<XMLClientParameters>\n"); snprintfcat(buf, sizeof(buf), "<ShutdownDuration>%d</ShutdownDuration>\n", shutdown_duration); if( shutdown_timer > 0 ) { snprintfcat(buf, sizeof(buf), "<ShutdownTimer>%d</ShutdownTimer>\r\n", shutdown_timer); } else { snprintfcat(buf, sizeof(buf), "<ShutdownTimer>NONE</ShutdownTimer>\n"); } snprintfcat(buf, sizeof(buf), "<AutoConfig>LOCAL</AutoConfig>\n"); snprintfcat(buf, sizeof(buf), "<OutletGroup>1</OutletGroup>\n"); snprintfcat(buf, sizeof(buf), "</XMLClientParameters>\n"); snprintfcat(buf, sizeof(buf), "<Warning></Warning>\n"); snprintfcat(buf, sizeof(buf), "</Subscribe>\n"); /* now send subscription message setting all the proper flags */ request = ne_request_create(session, "POST", page); ne_set_request_body_buffer(request, buf, strlen(buf)); /* as the NMC reply is not xml standard compliant let's parse it this way */ do { #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(timeout+1); #endif ret = ne_begin_request(request); #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(0); #endif if (ret != NE_OK) { break; } ret = ne_read_response_block(request, resp_buf, sizeof(resp_buf)); if (ret == NE_OK) { ret = ne_end_request(request); } } while (ret == NE_RETRY); ne_request_destroy(request); /* due to different formats used by the various NMCs, we need to\ break up the reply in lines and parse each one separately */ for (s = strtok(resp_buf, "\r\n"); s != NULL; s = strtok(NULL, "\r\n")) { upsdebugx(2, "%s: parsing %s", __func__, s); if (!strncasecmp(s, "<Port>", 6) && (sscanf(s+6, "%u", &port) != 1)) { return NE_RETRY; } if (!strncasecmp(s, "<Secret>", 8) && (sscanf(s+8, "%u", &secret) != 1)) { return NE_RETRY; } } if ((port == -1) || (secret == -1)) { upsdebugx(2, "%s: parsing initial subcription failed", __func__); return NE_RETRY; } /* Resolve the given hostname. 'flags' must be zero. Hex * string IPv6 addresses (e.g. `::1') may be enclosed in brackets * (e.g. `[::1]'). */ addr = ne_addr_resolve(uri.host, 0); /* Returns zero if name resolution was successful, non-zero on * error. */ if (ne_addr_result(addr) != 0) { upsdebugx(2, "%s: name resolution failure on %s: %s", __func__, uri.host, ne_addr_error(addr, buf, sizeof(buf))); ne_addr_destroy(addr); return NE_RETRY; } for (ai = ne_addr_first(addr); ai != NULL; ai = ne_addr_next(addr)) { upsdebugx(2, "%s: connecting to host %s port %d", __func__, ne_iaddr_print(ai, buf, sizeof(buf)), port); #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(timeout+1); #endif ret = ne_sock_connect(sock, ai, port); #ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT alarm(0); #endif if (ret == NE_OK) { upsdebugx(2, "%s: connection to %s open on fd %d", __func__, uri.host, ne_sock_fd(sock)); break; } } ne_addr_destroy(addr); if (ai == NULL) { upsdebugx(2, "%s: failed to create listening socket", __func__); return NE_RETRY; } snprintf(buf, sizeof(buf), "<Subscription Identification=\"%u\"></Subscription>", secret); ret = ne_sock_fullwrite(sock, buf, strlen(buf) + 1); if (ret != NE_OK) { upsdebugx(2, "%s: send failed: %s", __func__, ne_sock_error(sock)); return NE_RETRY; } ret = ne_sock_read(sock, buf, sizeof(buf)); if (ret < 1) { upsdebugx(2, "%s: read failed: %s", __func__, ne_sock_error(sock)); return NE_RETRY; } if (strcasecmp(buf, "<Subscription Answer=\"ok\"></Subscription>")) { upsdebugx(2, "%s: subscription rejected", __func__); return NE_RETRY; } upslogx(LOG_INFO, "NSM connection to '%s' established", uri.host); return NE_OK; }
/* for dummy mode * parse the definition file and process its content */ static int parse_data_file(int upsfd) { char fn[SMALLBUF]; char *ptr, var_value[MAX_STRING_SIZE]; int value_args = 0, counter; time_t now; time(&now); upsdebugx(1, "entering parse_data_file()"); if (now < next_update) { upsdebugx(1, "leaving (paused)..."); return 1; } /* initialise everything, to loop back at the beginning of the file */ if (ctx == NULL) { ctx = (PCONF_CTX_t *)xmalloc(sizeof(PCONF_CTX_t)); if (device_path[0] == '/') snprintf(fn, sizeof(fn), "%s", device_path); else snprintf(fn, sizeof(fn), "%s/%s", confpath(), device_path); pconf_init(ctx, upsconf_err); if (!pconf_file_begin(ctx, fn)) fatalx(EXIT_FAILURE, "Can't open dummy-ups definition file %s: %s", fn, ctx->errmsg); } /* Reset the next call time, so that we can loop back on the file * if there is no blocking action (ie TIMER) until the end of the file */ next_update = -1; /* Now start or continue parsing... */ while (pconf_file_next(ctx)) { if (pconf_parse_error(ctx)) { upsdebugx(2, "Parse error: %s:%d: %s", fn, ctx->linenum, ctx->errmsg); continue; } /* Check if we have something to process */ if (ctx->numargs < 1) continue; /* Process actions (only "TIMER" ATM) */ if (!strncmp(ctx->arglist[0], "TIMER", 5)) { /* TIMER <seconds> will wait "seconds" before * continuing the parsing */ int delay = atoi (ctx->arglist[1]); time(&next_update); next_update += delay; upsdebugx(1, "suspending execution for %i seconds...", delay); break; } /* Remove ":" suffix, after the variable name */ if ((ptr = strchr(ctx->arglist[0], ':')) != NULL) *ptr = '\0'; upsdebugx(3, "parse_data_file: variable \"%s\" with %d args", ctx->arglist[0], (int)ctx->numargs); /* Skip the driver.* collection data */ if (!strncmp(ctx->arglist[0], "driver.", 7)) { upsdebugx(2, "parse_data_file: skipping %s", ctx->arglist[0]); continue; } /* From there, we get varname in arg[0], and values in other arg[1...x] */ /* special handler for status */ if (!strncmp( ctx->arglist[0], "ups.status", 10)) { status_init(); for (counter = 1, value_args = ctx->numargs ; counter < value_args ; counter++) { status_set(ctx->arglist[counter]); } status_commit(); } else { for (counter = 1, value_args = ctx->numargs ; counter < value_args ; counter++) { if (counter == 1) /* don't append the first space separator */ snprintf(var_value, sizeof(var_value), "%s", ctx->arglist[counter]); else snprintfcat(var_value, sizeof(var_value), " %s", ctx->arglist[counter]); } if (setvar(ctx->arglist[0], var_value) == STAT_SET_UNKNOWN) { upsdebugx(2, "parse_data_file: can't add \"%s\" with value \"%s\"\nError: %s", ctx->arglist[0], var_value, ctx->errmsg); } else { upsdebugx(3, "parse_data_file: added \"%s\" with value \"%s\"", ctx->arglist[0], var_value); } } } /* Cleanup parseconf if there is no pending action */ if (next_update == -1) { pconf_finish(ctx); free(ctx); ctx=NULL; } return 1; }
static void do_pid(const char *arg) { snprintfcat(logbuffer, sizeof(logbuffer), "%ld", (long)getpid()); }
static void do_upshost(const char *arg) { snprintfcat(logbuffer, sizeof(logbuffer), "%s", monhost); }
int virgo__lua_debug_stackwalk(lua_State *L) { virgo_t* v = virgo__lua_context(L); const char *errstr = lua_tostring(L, 1); lua_Debug ldbg; int i = 0; logDbg(v, "Lua stack backtrace: %s", errstr); /* start at 1 to skip this function. */ for (i = 1; lua_getstack(L, i, &ldbg); i++) { char *ptr = (char *) scratchbuf; size_t len = sizeof (scratchbuf); int bw = snprintfcat(&ptr, &len, "#%d", i-1); const int maxspacing = 4; int spacing = maxspacing - bw; while (spacing-- > 0) snprintfcat(&ptr, &len, " "); if (!lua_getinfo(L, "nSl", &ldbg)) { snprintfcat(&ptr, &len, "???\n"); logDbg(v, "%s", (const char *) scratchbuf); continue; } if (ldbg.namewhat[0]) snprintfcat(&ptr, &len, "%s ", ldbg.namewhat); if ((ldbg.name) && (ldbg.name[0])) snprintfcat(&ptr, &len, "function %s ()", ldbg.name); else { if (strcmp(ldbg.what, "main") == 0) snprintfcat(&ptr, &len, "mainline of chunk"); else if (strcmp(ldbg.what, "tail") == 0) snprintfcat(&ptr, &len, "tail call"); else snprintfcat(&ptr, &len, "unidentifiable function"); } ptr = (char *) scratchbuf; len = sizeof (scratchbuf); for (spacing = 0; spacing < maxspacing; spacing++) snprintfcat(&ptr, &len, " "); if (strcmp(ldbg.what, "C") == 0) snprintfcat(&ptr, &len, "in native code"); else if (strcmp(ldbg.what, "tail") == 0) snprintfcat(&ptr, &len, "in Lua code"); else if ( (strcmp(ldbg.source, "=?") == 0) && (ldbg.currentline == 0) ) snprintfcat(&ptr, &len, "in Lua code (debug info stripped)"); else { snprintfcat(&ptr, &len, "in Lua code at %s", ldbg.short_src); if (ldbg.currentline != -1) snprintfcat(&ptr, &len, ":%d", ldbg.currentline); snprintfcat(&ptr, &len, " %s()", ldbg.name); } logDbg(v, "%s", (const char *) scratchbuf); } return 0; }
static void _cmd_help_i(void *value, void *data) { co_cmd_t *cvalue = value; snprintfcat((char *)data, 2048, "Command: %s Usage: %s", cvalue->name, cvalue->usage); return; }