mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
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>
284 lines
6.2 KiB
C
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);
|
|
}
|
|
}
|