Files
s390-tools/lsstp/lsstp.c
Szabina Korbai 9fdfd1a6dc lsstp: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:48:33 +02:00

224 lines
5.1 KiB
C

/*
* lsstp - Display STP system information
*
* Copyright IBM Corp. 2020, 2022
*
* 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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <iconv.h>
#include <inttypes.h>
#include "lib/util_opt.h"
#include "lib/util_file.h"
#include "lib/util_prg.h"
#include "lib/util_path.h"
#include "lsstp_cli.h"
static const struct util_prg prg = {
.desc = "Display STP system information",
.args = "",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2020,
},
UTIL_PRG_COPYRIGHT_END
}
};
struct stp_parms {
uint64_t ctn_id;
unsigned int online;
unsigned int leap_seconds;
int leap_seconds_diff;
unsigned int leap_seconds_utc;
unsigned int stratum;
unsigned int ctn_type;
unsigned int timing_mode;
unsigned int timing_state;
int dst_offset;
int time_offset;
int time_zone_offset;
};
static int convert_ctn_id(char *in, char *out)
{
iconv_t ic;
size_t inlen = sizeof(unsigned long long);
size_t outlen = sizeof(unsigned long long);
ic = iconv_open("ISO-8859-1", "EBCDIC-US");
if (ic == (iconv_t)-1) {
warn("Could not initialize EBCDIC to ISO-8859-1 conversion table");
return -1;
}
if (iconv(ic, &in, &inlen, (char **)&out, &outlen) == (size_t)-1) {
warn("Code page translation EBCDIC to ISO-8859-1 failed");
iconv_close(ic);
return -1;
}
iconv_close(ic);
return 0;
}
static const char *ctn_type_str(int type)
{
switch (type) {
case 0:
return "No CTN defined";
case 1:
return "STP-only";
case 2:
return "mixed";
default:
return "unknown";
}
}
static const char *tmd_to_str(int mode)
{
switch (mode) {
case 0:
return "Local";
case 1:
return "ETR";
case 2:
return "STP";
case 15:
return "Uninitialized";
default:
return "unknown";
}
}
static const char *tst_to_str(int mode)
{
switch (mode) {
case 0:
return "Unsynchronized";
case 1:
return "Synchronized";
case 2:
return "Physical clock stopped";
default:
return "unknown";
}
}
static const char *yesno_str(int val)
{
return val ? "yes" : "no";
}
#define read_sysfs_attr(attr, parm, func, base) \
do { \
path = util_path_sysfs("devices/system/stp/%s", attr); \
ret = func(parm, base, path); \
if (ret) { \
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); \
free(path); \
exit(EXIT_FAILURE); \
} \
free(path); \
} while (0)
int main(int argc, char **argv)
{
struct stp_parms parm = { 0 };
char ctn_id[32] = { 0 };
char *path;
int ret, c;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
for (;;) {
c = util_opt_getopt_long(argc, argv);
if (c == -1)
break;
switch (c) {
case 'v':
util_prg_print_version();
exit(EXIT_SUCCESS);
case 'h':
util_prg_print_help();
util_opt_print_help();
exit(EXIT_SUCCESS);
default:
fprintf(stderr, "Try 'lsstp --help' for more information.\n");
exit(EXIT_FAILURE);
}
}
read_sysfs_attr("online", &parm.online, util_file_read_ui, 10);
if (!parm.online) {
printf("STP disabled\n");
goto out;
}
read_sysfs_attr("ctn_id", &parm.ctn_id, util_file_read_ul, 16);
read_sysfs_attr("ctn_type", &parm.ctn_type, util_file_read_ui, 10);
read_sysfs_attr("stratum", &parm.stratum, util_file_read_ui, 10);
read_sysfs_attr("leap_seconds", &parm.leap_seconds, util_file_read_ui, 10);
read_sysfs_attr("timing_mode", &parm.timing_mode, util_file_read_ui, 10);
read_sysfs_attr("timing_state", &parm.timing_state, util_file_read_ui, 10);
read_sysfs_attr("dst_offset", &parm.dst_offset, util_file_read_i, 10);
read_sysfs_attr("time_offset", &parm.time_offset, util_file_read_i, 10);
read_sysfs_attr("time_zone_offset", &parm.time_zone_offset, util_file_read_i, 10);
if (convert_ctn_id((char *)&parm.ctn_id, ctn_id))
snprintf(ctn_id, sizeof(ctn_id)-1, "%016" PRIx64, parm.ctn_id);
printf("STP online: %s\n"
"CTN ID: %s\n"
"CTN type: %s\n"
"Stratum: %d\n"
"Timing mode: %s\n"
"Timing state: %s\n"
"DST offset: %d\n"
"Timezone offset: %d\n"
"Time offset: %d\n"
"Active leap seconds: %d\n",
yesno_str(parm.online),
ctn_id,
ctn_type_str(parm.ctn_type),
parm.stratum,
tmd_to_str(parm.timing_mode),
tst_to_str(parm.timing_state),
parm.dst_offset,
parm.time_zone_offset,
parm.time_offset,
parm.leap_seconds);
printf("Scheduled leap second: ");
path = util_path_sysfs("devices/system/stp/leap_seconds_scheduled");
if (util_file_read_va(path, "%d,%d", &parm.leap_seconds_utc,
&parm.leap_seconds_diff) == 2 &&
parm.leap_seconds_diff && parm.leap_seconds_utc) {
time_t lsoup = parm.leap_seconds_utc;
printf("%s at: %s UTC",
parm.leap_seconds_diff > 0 ? "insertion" : "deletion",
ctime(&lsoup));
} else {
printf("-\n");
}
free(path);
return 0;
out:
return 1;
}