Files
s390-tools/zdev/src/table_attribs.c
Daniel S. Haischt 889293e557 zdev: implement --shell command line switch
Fix issue in the lszdev command where column names if using the --pairs
command line switch can contain characters that are not allowed to be
used as variable names in a shell environment.

Replace bad characters in column names by an underscore if the --shell
command line switch is specified along with the --pairs switch.

The additional --shell switch mimics what is already available in the
lsblk command and thus it shall be used along with the --pairs switch.

Signed-off-by: Daniel S. Haischt <modean@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2022-12-07 16:50:16 +01:00

284 lines
6.2 KiB
C

/*
* zdev - Modify and display the persistent configuration of devices
*
* Copyright IBM Corp. 2016, 2019
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "attrib.h"
#include "ccw.h"
#include "devtype.h"
#include "misc.h"
#include "subtype.h"
#include "table.h"
#include "table_attribs.h"
/* Column IDs for the types table. */
enum table_attribs_id {
table_attribs_name,
table_attribs_desc,
};
/* Definition of output table for --list-types. */
static struct column *table_attribs = COLUMN_ARRAY(
COLUMN("NAME", align_left, table_attribs_name, 1, ""),
COLUMN("DESCRIPTION", align_left, table_attribs_desc, 1, "")
);
/* Return a newly allocated struct table_attrib. */
struct table_attrib *table_attrib_new(struct subtype *st, struct attrib *a)
{
struct table_attrib *t;
t = misc_malloc(sizeof(struct table_attrib));
t->st = st;
t->attrib = a;
return t;
}
/* Retrieve value of a cell for devtype/subtype name @item in column @id in the
* types table. */
static char *table_attribs_get_value(void *item, int id, const char *heading,
void *data)
{
struct table_attrib *t = item;
struct attrib *a = t->attrib;
switch (id) {
case table_attribs_name:
return misc_strdup(a->name);
case table_attribs_desc:
return misc_strdup(a->title);
}
return NULL;
}
static struct util_list *get_subtypes(struct util_list *attribs)
{
struct ptrlist_node *p, *q;
struct table_attrib *t;
struct util_list *list;
list = ptrlist_new();
util_list_iterate(attribs, p) {
t = p->ptr;
util_list_iterate(list, q) {
if (t->st == q->ptr)
break;
}
if (!q)
ptrlist_add(list, t->st);
}
return list;
}
struct util_list *get_subtype_attribs(struct util_list *all, struct subtype *st)
{
struct util_list *subattribs;
struct ptrlist_node *p;
struct table_attrib *t;
subattribs = ptrlist_new();
util_list_iterate(all, p) {
t = p->ptr;
if (t->st == st)
ptrlist_add(subattribs, t);
}
return subattribs;
}
void print_type(struct devtype *dt, struct subtype *st, bool multiple)
{
int i;
if (!multiple)
return;
if (st)
printf("TYPE %s\n", st->name);
else {
printf("TYPE ");
for (i = 0; dt->subtypes[i]; i++) {
printf("%s%s", i == 0 ? "" : ", ",
dt->subtypes[i]->name);
}
printf("\n");
}
}
/* Display table of attributes. */
void table_attribs_show(struct util_list *attribs, int headings, int pairs,
int shell, struct devtype *dt)
{
struct util_list *subtypes, *subattribs;
struct ptrlist_node *p;
struct subtype *st;
bool multiple, first;
int indent;
subtypes = get_subtypes(attribs);
if (util_list_len(subtypes) > 1) {
multiple = true;
indent = 2;
} else {
multiple = false;
indent = 0;
}
first = true;
util_list_iterate(subtypes, p) {
st = p->ptr;
subattribs = get_subtype_attribs(attribs, st);
if (first)
first = false;
else
printf("\n");
print_type(dt, st, multiple);
table_print(table_attribs, table_attribs_get_value, st,
subattribs, NULL, headings, pairs, shell, indent, 0);
ptrlist_free(subattribs, 0);
}
ptrlist_free(subtypes, 0);
}
static void table_attribs_show_details_one(struct table_attrib *t,
struct devtype *dt, bool multiple)
{
struct subtype *st = t->st;
struct attrib *a = t->attrib;
const int i = 2, j = 4;
int k;
printf("ATTRIBUTE %s\n\n", a->name);
if (multiple) {
indent(i, "APPLICABLE TYPES\n");
printf("%*s", j, "");
if (st)
printf("%s", st->name);
else {
for (k = 0; dt->subtypes[k]; k++) {
printf("%s%s", k == 0 ? "" : ", ",
dt->subtypes[k]->name);
}
}
printf("\n\n");
}
indent(i, "DESCRIPTION\n");
indent(j, "%s", a->desc);
if (a->defval) {
printf("\n");
indent(i, "DEFAULT VALUE\n");
indent(j, "The default value is '%s'.\n", a->defval);
}
if (!a->readonly) {
printf("\n");
indent(i, "ACCEPTED VALUES\n");
attrib_print_acceptable(a, j);
}
if (!(a->multi || a->activeonly || a->unstable || a->writeonly ||
a->rewrite || a->mandatory || a->newline || a->activerem ||
a->nounload || a->check || a->readonly))
return;
printf("\n");
indent(i, "NOTES\n");
if (a->multi) {
indent(j, "- This attribute maintains a list of values "
"written to it\n");
}
if (a->activeonly) {
indent(j, "- Only specify this attribute in the active "
"configuration\n");
}
if (a->unstable) {
indent(j, "- The value read from this attribute is different "
"from the last value\n written to it\n");
}
if (a->writeonly)
indent(j, "- You cannot read this attribute\n");
if (a->readonly)
indent(j, "- You cannot write to this attribute\n");
if (a->rewrite) {
indent(j, "- Setting the same value multiple times may have "
"additional effects\n");
}
if (a->mandatory)
indent(j, "- Settings for this attribute cannot be removed\n");
if (a->newline) {
indent(j, "- A value written to this attribute must be "
"followed by a newline character\n");
}
if (a->activerem) {
indent(j, "- Settings for this attribute can be removed in "
"the active configuration\n");
}
if (a->check == ccw_offline_only_check) {
indent(j, "- This attribute cannot be changed while the device "
"is online\n");
}
if (a->check == ccw_online_only_check) {
indent(j, "- This attribute cannot be changed while the device "
"is offline\n");
}
if (a->nounload) {
indent(j, "- Settings for this attribute can be changed "
"without reloading the\n associated kernel "
"module\n");
}
}
static bool check_multiple_types(struct util_list *list)
{
struct ptrlist_node *p;
struct table_attrib *t;
struct subtype *st = NULL;
bool first;
first = true;
util_list_iterate(list, p) {
t = p->ptr;
if (first) {
first = false;
st = t->st;
} else if (t->st != st)
return true;
}
return false;
}
/* Display detailed attribute information*/
void table_attribs_show_details(struct util_list *attribs, struct devtype *dt)
{
struct ptrlist_node *p;
bool first, multiple;
first = true;
multiple = check_multiple_types(attribs);
util_list_iterate(attribs, p) {
if (first)
first = false;
else
printf("\n");
table_attribs_show_details_one(p->ptr, dt, multiple);
}
}