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); }
static void conn_del(conn_t *target) { conn_t *tmp, *last = NULL; tmp = connhead; while (tmp) { if (tmp == target) { if (last) last->next = tmp->next; else connhead = tmp->next; pconf_finish(&tmp->ctx); free(tmp); return; } last = tmp; tmp = tmp->next; } upslogx(LOG_ERR, "Tried to delete a bogus state connection"); }
/* open the ups.conf, parse it, and call back do_upsconf_args() */ void read_upsconf(void) { char fn[SMALLBUF]; PCONF_CTX_t ctx; ups_section = NULL; snprintf(fn, sizeof(fn), "%s/ups.conf", confpath()); pconf_init(&ctx, upsconf_err); if (!pconf_file_begin(&ctx, fn)) fatalx(EXIT_FAILURE, "Can't open %s: %s", fn, ctx.errmsg); while (pconf_file_next(&ctx)) { if (pconf_parse_error(&ctx)) { upslogx(LOG_ERR, "Parse error: %s:%d: %s", fn, ctx.linenum, ctx.errmsg); continue; } conf_args(ctx.numargs, ctx.arglist); } pconf_finish(&ctx); free(ups_section); }
int upscli_disconnect(UPSCONN *ups) { if (!ups) return -1; if (!upscli_checkmagic(ups)) return -1; if (ups->fd != -1) { /* try to disconnect gracefully */ net_write(ups, "LOGOUT\n", 7); upscli_closefd(ups); } if (ups->pc_ctx) { pconf_finish(ups->pc_ctx); free(ups->pc_ctx); ups->pc_ctx = NULL; } if (ups->host) free(ups->host); ups->host = NULL; ups->upsclient_magic = 0; return 0; }
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); }
static void sstate_disconnect(void) { if (upsfd < 0) { return; } pconf_finish(&sock_ctx); close(upsfd); upsfd = -1; }
/* change the configuration of an existing UPS (used during reloads) */ static void ups_update(const char *fn, const char *name, const char *desc) { upstype_t *temp; temp = get_ups_ptr(name); if (!temp) { upslogx(LOG_ERR, "UPS %s disappeared during reload", name); return; } /* paranoia */ if (!temp->fn) { upslogx(LOG_ERR, "UPS %s had a NULL filename!", name); /* let's give it something quick to use later */ temp->fn = xstrdup(""); } /* when the filename changes, force a reconnect */ if (strcmp(temp->fn, fn) != 0) { upslogx(LOG_NOTICE, "Redefined UPS [%s]", name); /* release all data */ sstate_infofree(temp); sstate_cmdfree(temp); pconf_finish(&temp->sock_ctx); close(temp->sock_fd); temp->sock_fd = -1; temp->dumpdone = 0; /* now redefine the filename and wrap up */ free(temp->fn); temp->fn = xstrdup(fn); } /* update the description */ free(temp->desc); if (desc) temp->desc = xstrdup(desc); else temp->desc = NULL; /* always set this on reload */ temp->retain = 1; }
/* remove a UPS from the linked list */ static void delete_ups(upstype_t *target) { upstype_t *ptr, *last; if (!target) return; ptr = last = firstups; while (ptr) { if (ptr == target) { upslogx(LOG_NOTICE, "Deleting UPS [%s]", target->name); /* make sure nobody stays logged into this thing */ kick_login_clients(target->name); /* about to delete the first ups? */ if (ptr == last) firstups = ptr->next; else last->next = ptr->next; if (ptr->sock_fd != -1) close(ptr->sock_fd); /* release memory */ sstate_infofree(ptr); sstate_cmdfree(ptr); pconf_finish(&ptr->sock_ctx); free(ptr->fn); free(ptr->name); free(ptr->desc); free(ptr); return; } last = ptr; ptr = ptr->next; } /* shouldn't happen */ upslogx(LOG_ERR, "delete_ups: UPS not found"); }
void upsdrv_cleanup(void) { if ( (mode == MODE_META) || (mode == MODE_REPEATER) ) { if (ups) { upscli_disconnect(ups); } if (ctx) { pconf_finish(ctx); free(ctx); } free(client_upsname); free(hostname); free(ups); } }
static void sock_disconnect(conn_t *conn) { close(conn->fd); pconf_finish(&conn->ctx); if (conn->prev) { conn->prev->next = conn->next; } else { connhead = conn->next; } if (conn->next) { conn->next->prev = conn->prev; } else { /* conntail = conn->prev; */ } free(conn); }
int upscli_disconnect(UPSCONN_t *ups) { if (!ups) { return -1; } if (ups->upsclient_magic != UPSCLIENT_MAGIC) { return -1; } pconf_finish(&ups->pc_ctx); free(ups->host); ups->host = NULL; if (ups->fd < 0) { return 0; } net_write(ups, "LOGOUT\n", 7); #ifdef HAVE_SSL if (ups->ssl) { SSL_shutdown(ups->ssl); SSL_free(ups->ssl); ups->ssl = NULL; } if (ups->ssl_ctx) { SSL_CTX_free(ups->ssl_ctx); ups->ssl_ctx = NULL; } #endif shutdown(ups->fd, shutdown_how); close(ups->fd); ups->fd = -1; return 0; }
/* 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; }