15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering/***
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering This file is part of systemd.
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering Copyright 2014 Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering (at your option) any later version.
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering systemd is distributed in the hope that it will be useful, but
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering Lesser General Public License for more details.
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering***/
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "fd-util.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "io-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "show-status.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "terminal-util.h"
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering#include "util.h"
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poetteringint parse_show_status(const char *v, ShowStatus *ret) {
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering int r;
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering assert(v);
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering assert(ret);
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering if (streq(v, "auto")) {
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering *ret = SHOW_STATUS_AUTO;
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering return 0;
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering }
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering r = parse_boolean(v);
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering if (r < 0)
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering return r;
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering *ret = r ? SHOW_STATUS_YES : SHOW_STATUS_NO;
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering return 0;
15bd9a285858c374684e75709de82681ab7daaa7Lennart Poettering}
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poetteringint status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering static const char status_indent[] = " "; /* "[" STATUS "] " */
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering _cleanup_free_ char *s = NULL;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering _cleanup_close_ int fd = -1;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering struct iovec iovec[6] = {};
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering int n = 0;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering static bool prev_ephemeral;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering assert(format);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering /* This is independent of logging, as status messages are
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering * optional and go exclusively to the console. */
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (vasprintf(&s, format, ap) < 0)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering return log_oom();
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (fd < 0)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering return fd;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (ellipse) {
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering char *e;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering size_t emax, sl;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering int c;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering c = fd_columns(fd);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (c <= 0)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering c = 80;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering sl = status ? sizeof(status_indent)-1 : 0;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering emax = c - sl - 1;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (emax < 3)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering emax = 3;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering e = ellipsize(s, emax, 50);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (e) {
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering free(s);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering s = e;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering }
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering }
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (prev_ephemeral)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering prev_ephemeral = ephemeral;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (status) {
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (!isempty(status)) {
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], "[");
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], status);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], "] ");
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering } else
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], status_indent);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering }
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], s);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (!ephemeral)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering IOVEC_SET_STRING(iovec[n++], "\n");
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering if (writev(fd, iovec, n) < 0)
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering return -errno;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering return 0;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering}
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poetteringint status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) {
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering va_list ap;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering int r;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering assert(format);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering va_start(ap, format);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering r = status_vprintf(status, ellipse, ephemeral, format, ap);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering va_end(ap);
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering return r;
b8faf2ecd551d853c449c7cadc3944af84156bc9Lennart Poettering}