mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 02:21:44 +03:00
systemctl: use format-table.[ch] for tables
This commit is contained in:
parent
7c286cd6a6
commit
de9a8fe18e
@ -39,6 +39,7 @@
|
||||
#include "exec-util.h"
|
||||
#include "exit-status.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-table.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "glob-util.h"
|
||||
@ -389,122 +390,42 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) {
|
||||
}
|
||||
|
||||
static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
|
||||
unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len, max_desc_len;
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
const UnitInfo *u;
|
||||
unsigned n_shown = 0;
|
||||
int job_count = 0;
|
||||
bool full = arg_full || FLAGS_SET(arg_pager_flags, PAGER_DISABLE);
|
||||
int r;
|
||||
|
||||
max_id_len = STRLEN("UNIT");
|
||||
load_len = STRLEN("LOAD");
|
||||
active_len = STRLEN("ACTIVE");
|
||||
sub_len = STRLEN("SUB");
|
||||
job_len = STRLEN("JOB");
|
||||
max_desc_len = STRLEN("DESCRIPTION");
|
||||
table = table_new("", "unit", "load", "active", "sub", "job", "description");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
table_set_header(table, !arg_no_legend);
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
for (u = unit_infos; u < unit_infos + c; u++) {
|
||||
max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
|
||||
load_len = MAX(load_len, strlen(u->load_state));
|
||||
active_len = MAX(active_len, strlen(u->active_state));
|
||||
sub_len = MAX(sub_len, strlen(u->sub_state));
|
||||
max_desc_len = MAX(max_desc_len, strlen(u->description));
|
||||
|
||||
if (u->job_id != 0) {
|
||||
job_len = MAX(job_len, strlen(u->job_type));
|
||||
job_count++;
|
||||
}
|
||||
|
||||
if (!arg_no_legend &&
|
||||
(streq(u->active_state, "failed") ||
|
||||
STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked")))
|
||||
circle_len = 2;
|
||||
}
|
||||
|
||||
if (!arg_full && original_stdout_is_tty) {
|
||||
unsigned basic_len;
|
||||
|
||||
id_len = MIN(max_id_len, 25u); /* as much as it needs, but at most 25 for now */
|
||||
basic_len = circle_len + 1 + id_len + 1 + load_len + 1 + active_len + 1 + sub_len + 1;
|
||||
|
||||
if (job_count)
|
||||
basic_len += job_len + 1;
|
||||
|
||||
if (basic_len < (unsigned) columns()) {
|
||||
unsigned extra_len, incr;
|
||||
extra_len = columns() - basic_len;
|
||||
|
||||
/* Either UNIT already got 25, or is fully satisfied.
|
||||
* Grant up to 25 to DESC now. */
|
||||
incr = MIN(extra_len, 25u);
|
||||
desc_len = incr;
|
||||
extra_len -= incr;
|
||||
|
||||
/* Of the remainder give as much as the ID needs to the ID, and give the rest to the
|
||||
* description but not more than it needs. */
|
||||
if (extra_len > 0) {
|
||||
incr = MIN(max_id_len - id_len, extra_len);
|
||||
id_len += incr;
|
||||
desc_len += MIN(extra_len - incr, max_desc_len - desc_len);
|
||||
}
|
||||
} else
|
||||
desc_len = 0;
|
||||
} else {
|
||||
id_len = max_id_len;
|
||||
desc_len = max_desc_len;
|
||||
}
|
||||
|
||||
for (u = unit_infos; u < unit_infos + c; u++) {
|
||||
_cleanup_free_ char *e = NULL, *j = NULL;
|
||||
const char *on_underline = "", *off_underline = "";
|
||||
const char *on_loaded = "", *off_loaded = "";
|
||||
const char *on_active = "", *off_active = "";
|
||||
const char *on_circle = "", *off_circle = "";
|
||||
const char *id;
|
||||
_cleanup_free_ char *j = NULL;
|
||||
const char *on_underline = "", *on_loaded = "", *on_active = "";
|
||||
const char *on_circle = "", *id;
|
||||
bool circle = false, underline = false;
|
||||
|
||||
if (!n_shown && !arg_no_legend) {
|
||||
|
||||
if (circle_len > 0)
|
||||
fputs(" ", stdout);
|
||||
|
||||
printf("%s%-*s %-*s %-*s %-*s ",
|
||||
ansi_underline(),
|
||||
id_len, "UNIT",
|
||||
load_len, "LOAD",
|
||||
active_len, "ACTIVE",
|
||||
sub_len, "SUB");
|
||||
|
||||
if (job_count)
|
||||
printf("%-*s ", job_len, "JOB");
|
||||
|
||||
printf("%-*.*s%s\n",
|
||||
desc_len,
|
||||
full ? -1 : (int) desc_len,
|
||||
"DESCRIPTION",
|
||||
ansi_normal());
|
||||
}
|
||||
|
||||
n_shown++;
|
||||
|
||||
if (u + 1 < unit_infos + c &&
|
||||
!streq(unit_type_suffix(u->id), unit_type_suffix((u + 1)->id))) {
|
||||
on_underline = ansi_underline();
|
||||
off_underline = ansi_normal();
|
||||
underline = true;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked") && !arg_plain) {
|
||||
on_circle = ansi_highlight_yellow();
|
||||
off_circle = ansi_normal();
|
||||
circle = true;
|
||||
on_loaded = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||
off_loaded = underline ? on_underline : ansi_normal();
|
||||
} else if (streq(u->active_state, "failed") && !arg_plain) {
|
||||
on_circle = ansi_highlight_red();
|
||||
off_circle = ansi_normal();
|
||||
circle = true;
|
||||
on_active = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||
off_active = underline ? on_underline : ansi_normal();
|
||||
} else {
|
||||
on_active = on_underline;
|
||||
on_loaded = on_underline;
|
||||
}
|
||||
|
||||
if (u->machine) {
|
||||
@ -516,36 +437,47 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
|
||||
} else
|
||||
id = u->id;
|
||||
|
||||
if (arg_full) {
|
||||
e = ellipsize(id, id_len, 33);
|
||||
if (!e)
|
||||
return log_oom();
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
|
||||
TABLE_SET_COLOR, on_circle,
|
||||
TABLE_STRING, id,
|
||||
TABLE_SET_COLOR, on_active,
|
||||
TABLE_STRING, u->load_state,
|
||||
TABLE_SET_COLOR, on_loaded,
|
||||
TABLE_STRING, u->active_state,
|
||||
TABLE_SET_COLOR, on_active,
|
||||
TABLE_STRING, u->sub_state,
|
||||
TABLE_SET_COLOR, on_active,
|
||||
TABLE_STRING, u->job_id ? u->job_type: "",
|
||||
TABLE_SET_COLOR, u->job_id ? on_underline : "",
|
||||
TABLE_STRING, u->description,
|
||||
TABLE_SET_COLOR, on_underline);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
id = e;
|
||||
}
|
||||
|
||||
if (circle_len > 0)
|
||||
printf("%s%s%s ", on_circle, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ", off_circle);
|
||||
|
||||
printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
|
||||
on_underline,
|
||||
on_active, id_len, id, off_active,
|
||||
on_loaded, load_len, u->load_state, off_loaded,
|
||||
on_active, active_len, u->active_state,
|
||||
sub_len, u->sub_state, off_active,
|
||||
job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
|
||||
|
||||
printf("%-*.*s%s\n",
|
||||
desc_len,
|
||||
full ? -1 : (int) desc_len,
|
||||
u->description,
|
||||
off_underline);
|
||||
if (u->job_id != 0)
|
||||
job_count++;
|
||||
}
|
||||
|
||||
if (job_count == 0) {
|
||||
/* There's no data in the JOB column, so let's hide it */
|
||||
/* Also, convert all number constants to size_t so va_arg()
|
||||
* in table_set_display() fetches a correct number of bytes from
|
||||
* the stack */
|
||||
r = table_set_display(table, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) 3, (size_t) 4, (size_t) 6, (size_t) -1);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set columns to display: %m");
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print the table: %m");
|
||||
|
||||
if (!arg_no_legend) {
|
||||
const char *on, *off;
|
||||
size_t records = table_get_rows(table) - 1;
|
||||
|
||||
if (n_shown) {
|
||||
if (records > 0) {
|
||||
puts("\n"
|
||||
"LOAD = Reflects whether the unit definition was properly loaded.\n"
|
||||
"ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
|
||||
@ -559,15 +491,15 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
|
||||
}
|
||||
|
||||
if (arg_all || strv_contains(arg_states, "inactive"))
|
||||
printf("%s%u loaded units listed.%s\n"
|
||||
printf("%s%zu loaded units listed.%s\n"
|
||||
"To show all installed unit files use 'systemctl list-unit-files'.\n",
|
||||
on, n_shown, off);
|
||||
on, records, off);
|
||||
else if (!arg_states)
|
||||
printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
|
||||
printf("%s%zu loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
|
||||
"To show all installed unit files use 'systemctl list-unit-files'.\n",
|
||||
on, n_shown, off);
|
||||
on, records, off);
|
||||
else
|
||||
printf("%u loaded units listed.\n", n_shown);
|
||||
printf("%zu loaded units listed.\n", records);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1048,39 +980,30 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_
|
||||
}
|
||||
|
||||
static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
struct socket_info *s;
|
||||
unsigned pathlen = STRLEN("LISTEN"),
|
||||
typelen = STRLEN("TYPE") * arg_show_types,
|
||||
socklen = STRLEN("UNIT"),
|
||||
servlen = STRLEN("ACTIVATES");
|
||||
const char *on, *off;
|
||||
int r;
|
||||
|
||||
for (s = socket_infos; s < socket_infos + cs; s++) {
|
||||
unsigned tmp = 0;
|
||||
char **a;
|
||||
table = table_new("listen", "type", "units", "activates");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
socklen = MAX(socklen, strlen(s->id));
|
||||
if (arg_show_types)
|
||||
typelen = MAX(typelen, strlen(s->type));
|
||||
pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
|
||||
|
||||
STRV_FOREACH(a, s->triggered)
|
||||
tmp += strlen(*a) + 2*(a != s->triggered);
|
||||
servlen = MAX(servlen, tmp);
|
||||
if (!arg_show_types) {
|
||||
/* Hide the second (TYPE) column */
|
||||
r = table_set_display(table, 0, 2, 3, (size_t) -1);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set columns to display: %m");
|
||||
}
|
||||
|
||||
if (cs) {
|
||||
if (!arg_no_legend)
|
||||
printf("%-*s %-*.*s%-*s %s\n",
|
||||
pathlen, "LISTEN",
|
||||
typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
|
||||
socklen, "UNIT",
|
||||
"ACTIVATES");
|
||||
table_set_header(table, !arg_no_legend);
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
if (cs) {
|
||||
for (s = socket_infos; s < socket_infos + cs; s++) {
|
||||
_cleanup_free_ char *j = NULL;
|
||||
_cleanup_free_ char *j = NULL, *activates = NULL;
|
||||
const char *path;
|
||||
char **a;
|
||||
|
||||
if (s->machine) {
|
||||
j = strjoin(s->machine, ":", s->path);
|
||||
@ -1090,29 +1013,32 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
|
||||
} else
|
||||
path = s->path;
|
||||
|
||||
if (arg_show_types)
|
||||
printf("%-*s %-*s %-*s",
|
||||
pathlen, path, typelen, s->type, socklen, s->id);
|
||||
else
|
||||
printf("%-*s %-*s",
|
||||
pathlen, path, socklen, s->id);
|
||||
STRV_FOREACH(a, s->triggered)
|
||||
printf("%s %s",
|
||||
a == s->triggered ? "" : ",", *a);
|
||||
printf("\n");
|
||||
activates = strv_join(s->triggered, ", ");
|
||||
if (!activates)
|
||||
return log_oom();
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, path,
|
||||
TABLE_STRING, s->type,
|
||||
TABLE_STRING, s->id,
|
||||
TABLE_STRING, activates);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
on = ansi_highlight();
|
||||
off = ansi_normal();
|
||||
if (!arg_no_legend)
|
||||
printf("\n");
|
||||
} else {
|
||||
on = ansi_highlight_red();
|
||||
off = ansi_normal();
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print the table: %m");
|
||||
|
||||
if (!arg_no_legend) {
|
||||
printf("%s%u sockets listed.%s\n", on, cs, off);
|
||||
printf("\n%s%u sockets listed.%s\n", on, cs, off);
|
||||
if (!arg_all)
|
||||
printf("Pass --all to see loaded but inactive sockets, too.\n");
|
||||
}
|
||||
@ -1303,73 +1229,25 @@ static int timer_info_compare(const struct timer_info *a, const struct timer_inf
|
||||
}
|
||||
|
||||
static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
struct timer_info *t;
|
||||
unsigned
|
||||
nextlen = STRLEN("NEXT"),
|
||||
leftlen = STRLEN("LEFT"),
|
||||
lastlen = STRLEN("LAST"),
|
||||
passedlen = STRLEN("PASSED"),
|
||||
unitlen = STRLEN("UNIT"),
|
||||
activatelen = STRLEN("ACTIVATES");
|
||||
|
||||
const char *on, *off;
|
||||
int r;
|
||||
|
||||
assert(timer_infos || n == 0);
|
||||
|
||||
for (t = timer_infos; t < timer_infos + n; t++) {
|
||||
unsigned ul = 0;
|
||||
char **a;
|
||||
table = table_new("next", "left", "last", "passed", "unit", "activates");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
if (t->next_elapse > 0) {
|
||||
char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
|
||||
|
||||
format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
|
||||
nextlen = MAX(nextlen, strlen(tstamp) + 1);
|
||||
|
||||
format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
|
||||
leftlen = MAX(leftlen, strlen(trel));
|
||||
}
|
||||
|
||||
if (t->last_trigger > 0) {
|
||||
char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
|
||||
|
||||
format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
|
||||
lastlen = MAX(lastlen, strlen(tstamp) + 1);
|
||||
|
||||
format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
|
||||
passedlen = MAX(passedlen, strlen(trel));
|
||||
}
|
||||
|
||||
unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
|
||||
|
||||
STRV_FOREACH(a, t->triggered)
|
||||
ul += strlen(*a) + 2*(a != t->triggered);
|
||||
|
||||
activatelen = MAX(activatelen, ul);
|
||||
}
|
||||
table_set_header(table, !arg_no_legend);
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
if (n > 0) {
|
||||
if (!arg_no_legend)
|
||||
printf("%-*s %-*s %-*s %-*s %-*s %s\n",
|
||||
nextlen, "NEXT",
|
||||
leftlen, "LEFT",
|
||||
lastlen, "LAST",
|
||||
passedlen, "PASSED",
|
||||
unitlen, "UNIT",
|
||||
"ACTIVATES");
|
||||
|
||||
for (t = timer_infos; t < timer_infos + n; t++) {
|
||||
_cleanup_free_ char *j = NULL;
|
||||
_cleanup_free_ char *j = NULL, *activates = NULL;
|
||||
const char *unit;
|
||||
char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
|
||||
char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
|
||||
char **a;
|
||||
|
||||
format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
|
||||
format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
|
||||
|
||||
format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
|
||||
format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
|
||||
|
||||
if (t->machine) {
|
||||
j = strjoin(t->machine, ":", t->id);
|
||||
@ -1379,26 +1257,34 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
|
||||
} else
|
||||
unit = t->id;
|
||||
|
||||
printf("%-*s %-*s %-*s %-*s %-*s",
|
||||
nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
|
||||
activates = strv_join(t->triggered, ", ");
|
||||
if (!activates)
|
||||
return log_oom();
|
||||
|
||||
STRV_FOREACH(a, t->triggered)
|
||||
printf("%s %s",
|
||||
a == t->triggered ? "" : ",", *a);
|
||||
printf("\n");
|
||||
r = table_add_many(table,
|
||||
TABLE_TIMESTAMP, t->next_elapse,
|
||||
TABLE_TIMESTAMP_RELATIVE, t->next_elapse,
|
||||
TABLE_TIMESTAMP, t->last_trigger,
|
||||
TABLE_TIMESTAMP_RELATIVE, t->last_trigger,
|
||||
TABLE_STRING, unit,
|
||||
TABLE_STRING, activates);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
on = ansi_highlight();
|
||||
off = ansi_normal();
|
||||
if (!arg_no_legend)
|
||||
printf("\n");
|
||||
} else {
|
||||
on = ansi_highlight_red();
|
||||
off = ansi_normal();
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print the table: %m");
|
||||
|
||||
if (!arg_no_legend) {
|
||||
printf("%s%u timers listed.%s\n", on, n, off);
|
||||
printf("\n%s%u timers listed.%s\n", on, n, off);
|
||||
if (!arg_all)
|
||||
printf("Pass --all to see loaded but inactive timers, too.\n");
|
||||
}
|
||||
@ -1549,42 +1435,22 @@ static bool output_show_unit_file(const UnitFileList *u, char **states, char **p
|
||||
return true;
|
||||
}
|
||||
|
||||
static void output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
unsigned max_id_len, id_cols, state_cols, preset_cols;
|
||||
static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
const UnitFileList *u;
|
||||
int r;
|
||||
|
||||
max_id_len = STRLEN("UNIT FILE");
|
||||
state_cols = STRLEN("STATE");
|
||||
preset_cols = STRLEN("VENDOR PRESET");
|
||||
table = table_new("unit file", "state", "vendor preset");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
for (u = units; u < units + c; u++) {
|
||||
max_id_len = MAX(max_id_len, strlen(basename(u->path)));
|
||||
state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
|
||||
}
|
||||
|
||||
if (!arg_full) {
|
||||
unsigned basic_cols;
|
||||
|
||||
id_cols = MIN(max_id_len, 25u);
|
||||
basic_cols = 1 + id_cols + state_cols;
|
||||
if (basic_cols < (unsigned) columns())
|
||||
id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
|
||||
} else
|
||||
id_cols = max_id_len;
|
||||
|
||||
if (!arg_no_legend && c > 0)
|
||||
printf("%s%-*s %-*s %-*s%s\n",
|
||||
ansi_underline(),
|
||||
id_cols, "UNIT FILE",
|
||||
state_cols, "STATE",
|
||||
preset_cols, "VENDOR PRESET",
|
||||
ansi_normal());
|
||||
table_set_header(table, !arg_no_legend);
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
for (u = units; u < units + c; u++) {
|
||||
const char *on_underline = NULL, *on_unit_color = NULL, *id;
|
||||
const char *on_preset_color = NULL, *off_preset = NULL, *unit_preset_str;
|
||||
_cleanup_free_ char *e = NULL;
|
||||
int r;
|
||||
const char *on_preset_color = NULL, *unit_preset_str;
|
||||
bool underline;
|
||||
|
||||
underline = u + 1 < units + c &&
|
||||
@ -1601,6 +1467,8 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
on_unit_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||
else if (u->state == UNIT_FILE_ENABLED)
|
||||
on_unit_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||
else
|
||||
on_unit_color = on_underline;
|
||||
|
||||
id = basename(u->path);
|
||||
|
||||
@ -1616,20 +1484,25 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||
}
|
||||
|
||||
if (on_underline || on_preset_color)
|
||||
off_preset = ansi_normal();
|
||||
|
||||
e = arg_full ? NULL : ellipsize(id, id_cols, 33);
|
||||
|
||||
printf("%s%-*s %s%-*s %s%-*s%s\n",
|
||||
strempty(on_underline),
|
||||
id_cols, e ? e : id,
|
||||
strempty(on_unit_color), state_cols, unit_file_state_to_string(u->state),
|
||||
strempty(on_preset_color), preset_cols, unit_preset_str, strempty(off_preset));
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, id,
|
||||
TABLE_SET_COLOR, strempty(on_underline),
|
||||
TABLE_STRING, unit_file_state_to_string(u->state),
|
||||
TABLE_SET_COLOR, strempty(on_unit_color),
|
||||
TABLE_STRING, unit_preset_str,
|
||||
TABLE_SET_COLOR, strempty(on_preset_color));
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print the table: %m");
|
||||
|
||||
if (!arg_no_legend)
|
||||
printf("\n%u unit files listed.\n", c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int list_unit_files(int argc, char *argv[], void *userdata) {
|
||||
@ -1772,7 +1645,9 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
typesafe_qsort(units, c, compare_unit_file_list);
|
||||
output_unit_file_list(units, c);
|
||||
r = output_unit_file_list(units, c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (install_client_side())
|
||||
for (unit = units; unit < units + c; unit++)
|
||||
@ -2081,94 +1956,77 @@ static int get_machine_list(
|
||||
return c;
|
||||
}
|
||||
|
||||
static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
|
||||
static int output_machines_list(struct machine_info *machine_infos, unsigned n) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
struct machine_info *m;
|
||||
unsigned
|
||||
circle_len = 0,
|
||||
namelen = STRLEN("NAME"),
|
||||
statelen = STRLEN("STATE"),
|
||||
failedlen = STRLEN("FAILED"),
|
||||
jobslen = STRLEN("JOBS");
|
||||
bool state_missing = false;
|
||||
int r;
|
||||
|
||||
assert(machine_infos || n == 0);
|
||||
|
||||
for (m = machine_infos; m < machine_infos + n; m++) {
|
||||
namelen = MAX(namelen,
|
||||
strlen(m->name) + (m->is_host ? STRLEN(" (host)") : 0));
|
||||
statelen = MAX(statelen, strlen_ptr(m->state));
|
||||
failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
|
||||
jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
|
||||
table = table_new("", "name", "state", "failed", "jobs");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
if (!arg_plain && m->state && !streq(m->state, "running"))
|
||||
circle_len = 2;
|
||||
}
|
||||
|
||||
if (!arg_no_legend) {
|
||||
if (circle_len > 0)
|
||||
fputs(" ", stdout);
|
||||
|
||||
printf("%-*s %-*s %-*s %-*s\n",
|
||||
namelen, "NAME",
|
||||
statelen, "STATE",
|
||||
failedlen, "FAILED",
|
||||
jobslen, "JOBS");
|
||||
}
|
||||
table_set_header(table, !arg_no_legend);
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
for (m = machine_infos; m < machine_infos + n; m++) {
|
||||
const char *on_state = "", *off_state = "";
|
||||
const char *on_failed = "", *off_failed = "";
|
||||
_cleanup_free_ char *mname = NULL;
|
||||
const char *on_state = "", *on_failed = "";
|
||||
bool circle = false;
|
||||
|
||||
if (streq_ptr(m->state, "degraded")) {
|
||||
on_state = ansi_highlight_red();
|
||||
off_state = ansi_normal();
|
||||
circle = true;
|
||||
} else if (!streq_ptr(m->state, "running")) {
|
||||
on_state = ansi_highlight_yellow();
|
||||
off_state = ansi_normal();
|
||||
circle = true;
|
||||
}
|
||||
|
||||
if (m->n_failed_units > 0) {
|
||||
if (m->n_failed_units > 0)
|
||||
on_failed = ansi_highlight_red();
|
||||
off_failed = ansi_normal();
|
||||
} else
|
||||
on_failed = off_failed = "";
|
||||
|
||||
if (circle_len > 0)
|
||||
printf("%s%s%s ", on_state, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ", off_state);
|
||||
else
|
||||
on_failed = "";
|
||||
|
||||
if (!m->state)
|
||||
state_missing = true;
|
||||
|
||||
if (m->is_host)
|
||||
printf("%-*s (host) %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
|
||||
(int) (namelen - strlen(" (host)")),
|
||||
strna(m->name),
|
||||
on_state, statelen, strna(m->state), off_state,
|
||||
on_failed, failedlen, m->n_failed_units, off_failed,
|
||||
jobslen, m->n_jobs);
|
||||
else
|
||||
printf("%-*s %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
|
||||
namelen, strna(m->name),
|
||||
on_state, statelen, strna(m->state), off_state,
|
||||
on_failed, failedlen, m->n_failed_units, off_failed,
|
||||
jobslen, m->n_jobs);
|
||||
mname = strjoin(strna(m->name), " (host)");
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
|
||||
TABLE_SET_COLOR, on_state,
|
||||
TABLE_STRING, m->is_host ? mname : strna(m->name),
|
||||
TABLE_STRING, strna(m->state),
|
||||
TABLE_SET_COLOR, on_state,
|
||||
TABLE_UINT32, m->n_failed_units,
|
||||
TABLE_SET_COLOR, on_failed,
|
||||
TABLE_UINT32, m->n_jobs);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print the table: %m");
|
||||
|
||||
if (!arg_no_legend) {
|
||||
printf("\n");
|
||||
if (state_missing && geteuid() != 0)
|
||||
printf("Notice: some information only available to privileged users was not shown.\n");
|
||||
printf("%u machines listed.\n", n);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int list_machines(int argc, char *argv[], void *userdata) {
|
||||
struct machine_info *machine_infos = NULL;
|
||||
sd_bus *bus;
|
||||
int r;
|
||||
int r, rc;
|
||||
|
||||
r = acquire_bus(BUS_MANAGER, &bus);
|
||||
if (r < 0)
|
||||
@ -2181,10 +2039,10 @@ static int list_machines(int argc, char *argv[], void *userdata) {
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
typesafe_qsort(machine_infos, r, compare_machine_info);
|
||||
output_machines_list(machine_infos, r);
|
||||
rc = output_machines_list(machine_infos, r);
|
||||
free_machines_list(machine_infos, r);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int get_default(int argc, char *argv[], void *userdata) {
|
||||
@ -2292,7 +2150,7 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int output_waiting_jobs(sd_bus *bus, uint32_t id, const char *method, const char *prefix) {
|
||||
static int output_waiting_jobs(sd_bus *bus, Table *table, uint32_t id, const char *method, const char *prefix) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
const char *name, *type;
|
||||
@ -2317,8 +2175,22 @@ static int output_waiting_jobs(sd_bus *bus, uint32_t id, const char *method, con
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
while ((r = sd_bus_message_read(reply, "(usssoo)", &other_id, &name, &type, NULL, NULL, NULL)) > 0)
|
||||
printf("%s %u (%s/%s)\n", prefix, other_id, name, type);
|
||||
while ((r = sd_bus_message_read(reply, "(usssoo)", &other_id, &name, &type, NULL, NULL, NULL)) > 0) {
|
||||
_cleanup_free_ char *row = NULL;
|
||||
int rc;
|
||||
|
||||
if (asprintf(&row, "%s %u (%s/%s)", prefix, other_id, name, type) < 0)
|
||||
return log_oom();
|
||||
|
||||
rc = table_add_many(table,
|
||||
TABLE_STRING, special_glyph(SPECIAL_GLYPH_TREE_RIGHT),
|
||||
TABLE_STRING, row,
|
||||
TABLE_EMPTY,
|
||||
TABLE_EMPTY);
|
||||
if (rc < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
@ -2334,11 +2206,11 @@ struct job_info {
|
||||
const char *name, *type, *state;
|
||||
};
|
||||
|
||||
static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n, bool skipped) {
|
||||
unsigned id_len, unit_len, type_len, state_len;
|
||||
static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n, bool skipped) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
const struct job_info *j;
|
||||
const char *on, *off;
|
||||
bool shorten = false;
|
||||
int r;
|
||||
|
||||
assert(n == 0 || jobs);
|
||||
|
||||
@ -2349,66 +2221,54 @@ static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned
|
||||
|
||||
printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
id_len = STRLEN("JOB");
|
||||
unit_len = STRLEN("UNIT");
|
||||
type_len = STRLEN("TYPE");
|
||||
state_len = STRLEN("STATE");
|
||||
table = table_new("job", "unit", "type", "state");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
table_set_header(table, !arg_no_legend);
|
||||
if (arg_full)
|
||||
table_set_width(table, 0);
|
||||
|
||||
for (j = jobs; j < jobs + n; j++) {
|
||||
uint32_t id = j->id;
|
||||
assert(j->name && j->type && j->state);
|
||||
|
||||
id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
|
||||
unit_len = MAX(unit_len, strlen(j->name));
|
||||
type_len = MAX(type_len, strlen(j->type));
|
||||
state_len = MAX(state_len, strlen(j->state));
|
||||
}
|
||||
|
||||
if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
|
||||
unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
|
||||
shorten = true;
|
||||
}
|
||||
|
||||
if (!arg_no_legend)
|
||||
printf("%*s %-*s %-*s %-*s\n",
|
||||
id_len, "JOB",
|
||||
unit_len, "UNIT",
|
||||
type_len, "TYPE",
|
||||
state_len, "STATE");
|
||||
|
||||
for (j = jobs; j < jobs + n; j++) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
|
||||
if (streq(j->state, "running")) {
|
||||
if (streq(j->state, "running"))
|
||||
on = ansi_highlight();
|
||||
off = ansi_normal();
|
||||
} else
|
||||
on = off = "";
|
||||
else
|
||||
on = "";
|
||||
|
||||
e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
|
||||
printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
|
||||
id_len, j->id,
|
||||
on, unit_len, e ? e : j->name, off,
|
||||
type_len, j->type,
|
||||
on, state_len, j->state, off);
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_UINT, j->id,
|
||||
TABLE_STRING, j->name,
|
||||
TABLE_SET_COLOR, on,
|
||||
TABLE_STRING, j->type,
|
||||
TABLE_STRING, j->state,
|
||||
TABLE_SET_COLOR, on);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
if (arg_jobs_after)
|
||||
output_waiting_jobs(bus, j->id, "GetJobAfter", "\twaiting for job");
|
||||
output_waiting_jobs(bus, table, j->id, "GetJobAfter", "\twaiting for job");
|
||||
if (arg_jobs_before)
|
||||
output_waiting_jobs(bus, j->id, "GetJobBefore", "\tblocking job");
|
||||
output_waiting_jobs(bus, table, j->id, "GetJobBefore", "\tblocking job");
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print the table: %m");
|
||||
|
||||
if (!arg_no_legend) {
|
||||
on = ansi_highlight();
|
||||
off = ansi_normal();
|
||||
|
||||
printf("\n%s%u jobs listed%s.\n", on, n, off);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool output_show_job(struct job_info *job, char **patterns) {
|
||||
@ -2469,8 +2329,7 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
|
||||
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
output_jobs_list(bus, jobs, c, skipped);
|
||||
return 0;
|
||||
return output_jobs_list(bus, jobs, c, skipped);
|
||||
}
|
||||
|
||||
static int cancel_job(int argc, char *argv[], void *userdata) {
|
||||
|
Loading…
Reference in New Issue
Block a user