/* Copyright (C) 2017-2021 Fredrik Öhrström (gpl-3.0-or-later) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include"printer.h" #include"shell.h" using namespace std; Printer::Printer(bool json, bool pretty_print_json, bool fields, char separator, bool use_meterfiles, string &meterfiles_dir, bool use_logfile, string &logfile, vector shell_cmdlines, bool overwrite, MeterFileNaming naming, MeterFileTimestamp timestamp) { json_ = json; pretty_print_json_ = pretty_print_json; fields_ = fields; separator_ = separator; use_meterfiles_ = use_meterfiles; meterfiles_dir_ = meterfiles_dir; use_logfile_ = use_logfile; logfile_ = logfile; shell_cmdlines_ = shell_cmdlines; overwrite_ = overwrite; naming_ = naming; timestamp_ = timestamp; } void Printer::print(Telegram *t, Meter *meter, vector *more_json, vector *selected_fields) { string human_readable, fields, json; vector envs; bool printed = false; meter->printMeter(t, &human_readable, &fields, separator_, &json, &envs, more_json, selected_fields, pretty_print_json_); if (shell_cmdlines_.size() > 0 || meter->shellCmdlinesMeterUpdated().size() > 0) { printShells(meter, envs); printed = true; } if (use_meterfiles_) { printFiles(meter, t, human_readable, fields, json); printed = true; } if (!printed) { // This will print on stdout or in the logfile. printFiles(meter, t, human_readable, fields, json); fflush(stdout); } } void Printer::printShells(Meter *meter, vector &envs) { vector *shells = &shell_cmdlines_; if (meter->shellCmdlinesMeterUpdated().size() > 0) { shells = &meter->shellCmdlinesMeterUpdated(); } for (auto &s : *shells) { vector args; args.push_back("-c"); args.push_back(s); invokeShell("/bin/sh", args, envs); } } void Printer::printFiles(Meter *meter, Telegram *t, string &human_readable, string &fields, string &json) { FILE *output = stdout; if (use_meterfiles_) { char filename[256]; memset(filename, 0, sizeof(filename)); switch (naming_) { case MeterFileNaming::Name: snprintf(filename, 127, "%s/%s", meterfiles_dir_.c_str(), meter->name().c_str()); break; case MeterFileNaming::Id: snprintf(filename, 127, "%s/%s", meterfiles_dir_.c_str(), t->addresses.back().id.c_str()); break; case MeterFileNaming::NameId: snprintf(filename, 127, "%s/%s-%s", meterfiles_dir_.c_str(), meter->name().c_str(), t->addresses.back().id.c_str()); break; } string stamp; switch (timestamp_) { case MeterFileTimestamp::Never: // Append nothing. break; case MeterFileTimestamp::Day: stamp = currentDay(); break; case MeterFileTimestamp::Hour: stamp = currentHour(); break; case MeterFileTimestamp::Minute: stamp = currentMinute(); break; case MeterFileTimestamp::Micros: stamp = currentMicros(); break; } if (stamp.length() > 0) { // There is a timestamp, lets append it. strcat(filename, "_"); strcat(filename, stamp.c_str()); } const char *mode = overwrite_ ? "w" : "a"; output = fopen(filename, mode); if (!output) { warning("Could not open file \"%s\" for writing!\n", filename); return; } } else if (use_logfile_) { output = fopen(logfile_.c_str(), "a"); if (!output) { warning("Could not open file \"%s\" for writing!\n", logfile_.c_str()); return; } } if (json_) { if (output) { fprintf(output, "%s\n", json.c_str()); } else { notice("%s\n", json.c_str()); } } else if (fields_) { if (output) { fprintf(output, "%s\n", fields.c_str()); } else { notice("%s\n", fields.c_str()); } } else { if (output) { fprintf(output, "%s\n", human_readable.c_str()); } else { notice("%s\n", human_readable.c_str()); } } if (output != stdout && output) { fclose(output); } }