From 44e90986b1aea4296ba69198130fd37a9ffca082 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Fri, 4 Nov 2022 04:22:18 +0000 Subject: remove archive directory (and its contents) [github.com/doug-gilbert/sg3_utils/pull/31]; more sg_logs JSON work git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@979 6180dd3e-e324-4e3e-922d-17de1ae2f315 --- ChangeLog | 3 +- archive/README | 16 -- archive/align_b4_memalign.c | 24 -- archive/llseek.c | 128 ----------- archive/llseek.h | 14 -- archive/o_scsi_logging_level | 295 ------------------------- archive/sg_json_writer.c | 360 ------------------------------ archive/sg_json_writer.h | 101 --------- src/sg_logs.c | 506 ++++++++++++++++++++++++++++++++----------- src/sg_read_block_limits.c | 19 +- 10 files changed, 393 insertions(+), 1073 deletions(-) delete mode 100644 archive/README delete mode 100644 archive/align_b4_memalign.c delete mode 100644 archive/llseek.c delete mode 100644 archive/llseek.h delete mode 100755 archive/o_scsi_logging_level delete mode 100644 archive/sg_json_writer.c delete mode 100644 archive/sg_json_writer.h diff --git a/ChangeLog b/ChangeLog index 31fd8ad4..823fd921 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and some description at the top of its ".c" file. All utilities in the main directory have their own "man" pages. There is also a sg3_utils man page. -Changelog for pre-release sg3_utils-1.48 [20221101] [svn: r978] +Changelog for pre-release sg3_utils-1.48 [20221103] [svn: r979] - some utilities: add experimental --json[=JO] option - sg_z_act_query: new utility for sending either a Zone activate or Zone query command @@ -104,6 +104,7 @@ Changelog for pre-release sg3_utils-1.48 [20221101] [svn: r978] - round of coverity identified issue fixes (and non-issues) - autoconf: upgrade version 2.70 to 2.71; automake upgrade to version 1.16.5 (from Fedora 36) + - remove archive directory (and its contents) - codespell fixes Changelog for released sg3_utils-1.47 [20211110] [svn: r919] diff --git a/archive/README b/archive/README deleted file mode 100644 index e0e32205..00000000 --- a/archive/README +++ /dev/null @@ -1,16 +0,0 @@ -The code and scripts in this directory may be removed at some later -date. The last cleanup (i.e. purge of unused files) of this -directory occurred between sg3_utils version 1.22 and 1.23 . -No other code or script in this package currently uses the contents -of this directory. The contents of this directory are not -maintained by the author. - -The rescan-scsi-bus.sh script was copied long ago from -http://www.garloff.de/kurt/linux (under the "Rescan SCSI bus" -heading) and was later placed in this directory. Since others -do use the version of this script found in this package then -rescan-scsi-bus.sh was updated in sg3_utils version 1.35 and -was moved to the scripts directory. - -Douglas Gilbert -9th January 2013 diff --git a/archive/align_b4_memalign.c b/archive/align_b4_memalign.c deleted file mode 100644 index 1cd4032d..00000000 --- a/archive/align_b4_memalign.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Code fragment of how to get a buffer from the heap that has a specific - * alignment. The typical alignment is to a "page" whose size is often - * 4096 bytes. */ - - uint8_t * wrkBuff; /* will get pointer to heap allocation */ - uint8_t * wrkPos; /* will get aligned pointer within wrkBuff */ - uint32_t sz_of_aligned = 1234; /* number of aligned bytes required */ - - int psz; - -#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) - psz = sysconf(_SC_PAGESIZE); /* POSIX.1 (was getpagesize()) */ -#else - psz = 4096; /* give up, pick likely figure */ -#endif - - - /* perhaps use posix_memalign() instead. Yes but not always available */ - wrkBuff = (uint8_t *)malloc(sz_of_aligned + psz); - wrkPos = (uint8_t *)(((sg_uintptr_t)wrkBuff + psz - 1) & (~(psz - 1))); - -/* The disadvantage of this approach is that it needs both wrkBuff and wrkPos - * to be held by the application. The wrkBuff is only needed for the - * corresponding free(), all other uses should be via wrkPos. */ diff --git a/archive/llseek.c b/archive/llseek.c deleted file mode 100644 index fcc53faa..00000000 --- a/archive/llseek.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * llseek.c -- stub calling the llseek system call - * - * Copyright (C) 1994 Remy Card. This file may be redistributed - * under the terms of the GNU Public License. - * - * This file is borrowed from the util-linux-2.11z tarball's implementation - * of fdisk. It allows seeks to 64 bit offsets, if supported. - * Changed "ext2_" prefix to "llse". - */ - -#include "config.h" - -#define _XOPEN_SOURCE 500 -#define _GNU_SOURCE - -#include - -#include -#include - -#if defined(__GNUC__) || defined(HAS_LONG_LONG) -typedef int64_t llse_loff_t; -#else -typedef long llse_loff_t; -#endif - -extern llse_loff_t llse_llseek (unsigned int, llse_loff_t, unsigned int); - -#ifdef __linux__ - -#ifdef HAVE_LLSEEK -#include - -#else /* HAVE_LLSEEK */ - -#if defined(__alpha__) || defined(__ia64__) || defined(__s390x__) || defined (__x86_64__) || defined (__powerpc64__) - -#define my_llseek lseek - -#else -#include /* for __NR__llseek */ - -static int _llseek (unsigned int, unsigned long, - unsigned long, llse_loff_t *, unsigned int); - -#ifdef __NR__llseek - -static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high, - unsigned long, offset_low,llse_loff_t *,result, - unsigned int, origin) - -#else - -/* no __NR__llseek on compilation machine - might give it explicitly */ -static int _llseek (unsigned int fd, unsigned long oh, - unsigned long ol, llse_loff_t *result, - unsigned int origin) { - errno = ENOSYS; - return -1; -} - -#endif - -static llse_loff_t my_llseek (unsigned int fd, llse_loff_t offset, - unsigned int origin) -{ - llse_loff_t result; - int retval; - -#ifdef HAVE_LSEEK64 - return lseek64 (fd, offset, origin); -#else - retval = _llseek (fd, ((uint64_t) offset) >> 32, - ((uint64_t) offset) & 0xffffffff, - &result, origin); - return (retval == -1 ? (llse_loff_t) retval : result); -#endif -} - -#endif /* __alpha__ */ - -#endif /* HAVE_LLSEEK */ - -llse_loff_t llse_llseek (unsigned int fd, llse_loff_t offset, - unsigned int origin) -{ - llse_loff_t result; - static int do_compat = 0; - - if (!do_compat) { - result = my_llseek (fd, offset, origin); - if (!(result == -1 && errno == ENOSYS)) - return result; - - /* - * Just in case this code runs on top of an old kernel - * which does not support the llseek system call - */ - do_compat = 1; - /* - * Now try ordinary lseek. - */ - } - - if ((sizeof(off_t) >= sizeof(llse_loff_t)) || - (offset < ((llse_loff_t) 1 << ((sizeof(off_t)*8) -1)))) - return lseek(fd, (off_t) offset, origin); - - errno = EINVAL; - return -1; -} - -#else /* !linux */ - -llse_loff_t llse_llseek (unsigned int fd, llse_loff_t offset, - unsigned int origin) -{ - if ((sizeof(off_t) < sizeof(llse_loff_t)) && - (offset >= ((llse_loff_t) 1 << ((sizeof(off_t)*8) -1)))) { - errno = EINVAL; - return -1; - } - return lseek (fd, (off_t) offset, origin); -} - -#endif /* linux */ - diff --git a/archive/llseek.h b/archive/llseek.h deleted file mode 100644 index 61c12e43..00000000 --- a/archive/llseek.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LLSEEK_H -#define LLSEEK_H - -#if defined(__GNUC__) || defined(HAS_LONG_LONG) -typedef int64_t llse_loff_t; -#else -typedef long llse_loff_t; -#endif - -extern llse_loff_t llse_llseek(unsigned int fd, - llse_loff_t offset, - unsigned int origin); - -#endif diff --git a/archive/o_scsi_logging_level b/archive/o_scsi_logging_level deleted file mode 100755 index ecbc8277..00000000 --- a/archive/o_scsi_logging_level +++ /dev/null @@ -1,295 +0,0 @@ -#! /bin/bash -############################################################################### -# Conveniently create and set scsi logging level, show SCSI_LOG fields in human -# readable form. -# -# Copyright (C) IBM Corp. 2006 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or (at -# your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. -############################################################################### - -# Contributed by Andreas Herrmann 2006/08/18 - -SCRIPTNAME="scsi_logging_level" - -declare -i LOG_ERROR=0 -declare -i LOG_TIMEOUT=0 -declare -i LOG_SCAN=0 -declare -i LOG_MLQUEUE=0 -declare -i LOG_MLCOMPLETE=0 -declare -i LOG_LLQUEUE=0 -declare -i LOG_LLCOMPLETE=0 -declare -i LOG_HLQUEUE=0 -declare -i LOG_HLCOMPLETE=0 -declare -i LOG_IOCTL=0 - -declare -i LEVEL=0 - -_ERROR_SHIFT=0 -_TIMEOUT_SHIFT=3 -_SCAN_SHIFT=6 -_MLQUEUE_SHIFT=9 -_MLCOMPLETE_SHIFT=12 -_LLQUEUE_SHIFT=15 -_LLCOMPLETE_SHIFT=18 -_HLQUEUE_SHIFT=21 -_HLCOMPLETE_SHIFT=24 -_IOCTL_SHIFT=27 - -SET=0 -GET=0 -CREATE=0 - -OPTS=`getopt -o hvcgsa:E:T:S:I:M:L:H: --long \ -help,version,create,get,set,all:,error:,timeout:,scan:,ioctl:,\ -midlevel:,mlqueue:,mlcomplete:,lowlevel:,llqueue:,llcomplete:,\ -highlevel:,hlqueue:,hlcomplete: -n \'$SCRIPTNAME\' -- "$@"` -eval set -- "$OPTS" - -# print version info -printversion() -{ - cat <>$_ERROR_SHIFT) & 7)) - LOG_TIMEOUT=$((($LEVEL>>$_TIMEOUT_SHIFT) & 7)) - LOG_SCAN=$((($LEVEL>>$_SCAN_SHIFT) & 7)) - LOG_MLQUEUE=$((($LEVEL>>$_MLQUEUE_SHIFT) & 7)) - LOG_MLCOMPLETE=$((($LEVEL>>$_MLCOMPLETE_SHIFT) & 7)) - LOG_LLQUEUE=$((($LEVEL>>$_LLQUEUE_SHIFT) & 7)) - LOG_LLCOMPLETE=$((($LEVEL>>$_LLCOMPLETE_SHIFT) & 7)) - LOG_HLQUEUE=$((($LEVEL>>$_HLQUEUE_SHIFT) & 7)) - LOG_HLCOMPLETE=$((($LEVEL>>$_HLCOMPLETE_SHIFT) & 7)) - LOG_IOCTL=$((($LEVEL>>$_IOCTL_SHIFT) & 7)) - - echo "SCSI_LOG_ERROR=$LOG_ERROR" - echo "SCSI_LOG_TIMEOUT=$LOG_TIMEOUT" - echo "SCSI_LOG_SCAN=$LOG_SCAN" - echo "SCSI_LOG_MLQUEUE=$LOG_MLQUEUE" - echo "SCSI_LOG_MLCOMPLETE=$LOG_MLCOMPLETE" - echo "SCSI_LOG_LLQUEUE=$LOG_LLQUEUE" - echo "SCSI_LOG_LLCOMPLETE=$LOG_LLCOMPLETE" - echo "SCSI_LOG_HLQUEUE=$LOG_HLQUEUE" - echo "SCSI_LOG_HLCOMPLETE=$LOG_HLCOMPLETE" - echo "SCSI_LOG_IOCTL=$LOG_IOCTL" -} - -set_logging_level() -{ - echo "New scsi logging level:" - sysctl -q -w dev.scsi.logging_level=$LEVEL - if [ $? != 0 ] - then - echo "$SCRIPTNAME: could not write scsi logging level" \ - "(kernel probably without SCSI_LOGGING support)" - exit 1 - fi -} - -create_logging_level() -{ - LEVEL=$((($LOG_ERROR & 7)<<$_ERROR_SHIFT)) - LEVEL=$(($LEVEL|(($LOG_TIMEOUT & 7)<<$_TIMEOUT_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_SCAN & 7)<<$_SCAN_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_MLQUEUE & 7)<<$_MLQUEUE_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_MLCOMPLETE & 7)<<$_MLCOMPLETE_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_LLQUEUE & 7)<<$_LLQUEUE_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_LLCOMPLETE & 7)<<$_LLCOMPLETE_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_HLQUEUE & 7)<<$_HLQUEUE_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_HLCOMPLETE & 7)<<$_HLCOMPLETE_SHIFT))) - LEVEL=$(($LEVEL|(($LOG_IOCTL & 7)<<$_IOCTL_SHIFT))) -} - -check_cmdline $* - -if [ $SET = "1" ] -then - create_logging_level - set_logging_level - show_logging_level -elif [ $GET = "1" ] -then - get_logging_level - show_logging_level -elif [ $CREATE = "1" ] -then - create_logging_level - show_logging_level -else - invalid_cmdline missing option \'-g\', \'-s\' or \'-c\' -fi - diff --git a/archive/sg_json_writer.c b/archive/sg_json_writer.c deleted file mode 100644 index bc1c7b16..00000000 --- a/archive/sg_json_writer.c +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -/* - * Simple streaming JSON writer - * - * This takes care of the annoying bits of JSON syntax like the commas - * after elements - * - * Authors: Stephen Hemminger - * - * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc] - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "sg_json_writer.h" - -struct json_writer { - FILE *out; /* output file */ - unsigned depth; /* nesting */ - bool pretty; /* optional whitepace */ - char sep; /* either nul or comma */ -}; - -/* indentation for pretty print */ -static void jsonw_indent(json_writer_t *self) -{ - unsigned i; - for (i = 0; i < self->depth; ++i) - fputs(" ", self->out); -} - -/* end current line and indent if pretty printing */ -static void jsonw_eol(json_writer_t *self) -{ - if (!self->pretty) - return; - - putc('\n', self->out); - jsonw_indent(self); -} - -/* If current object is not empty print a comma */ -static void jsonw_eor(json_writer_t *self) -{ - if (self->sep != '\0') - putc(self->sep, self->out); - self->sep = ','; -} - - -/* Output JSON encoded string */ -/* Handles C escapes, does not do Unicode */ -static void jsonw_puts(json_writer_t *self, const char *str) -{ - putc('"', self->out); - for (; *str; ++str) - switch (*str) { - case '\t': - fputs("\\t", self->out); - break; - case '\n': - fputs("\\n", self->out); - break; - case '\r': - fputs("\\r", self->out); - break; - case '\f': - fputs("\\f", self->out); - break; - case '\b': - fputs("\\b", self->out); - break; - case '\\': - fputs("\\n", self->out); - break; - case '"': - fputs("\\\"", self->out); - break; - case '\'': - fputs("\\\'", self->out); - break; - default: - putc(*str, self->out); - } - putc('"', self->out); -} - -/* Create a new JSON stream */ -json_writer_t *jsonw_new(FILE *f) -{ - json_writer_t *self = malloc(sizeof(*self)); - if (self) { - self->out = f; - self->depth = 0; - self->pretty = false; - self->sep = '\0'; - } - return self; -} - -/* End output to JSON stream */ -void jsonw_destroy(json_writer_t **self_p) -{ - json_writer_t *self = *self_p; - - assert(self->depth == 0); - fputs("\n", self->out); - fflush(self->out); - free(self); - *self_p = NULL; -} - -void jsonw_pretty(json_writer_t *self, bool on) -{ - self->pretty = on; -} - -void jsonw_reset(json_writer_t *self) -{ - assert(self->depth == 0); - self->sep = '\0'; -} - -/* Basic blocks */ -static void jsonw_begin(json_writer_t *self, int c) -{ - jsonw_eor(self); - putc(c, self->out); - ++self->depth; - self->sep = '\0'; -} - -static void jsonw_end(json_writer_t *self, int c) -{ - assert(self->depth > 0); - - --self->depth; - if (self->sep != '\0') - jsonw_eol(self); - putc(c, self->out); - self->sep = ','; -} - - -/* Add a JSON property name */ -void jsonw_name(json_writer_t *self, const char *name) -{ - jsonw_eor(self); - jsonw_eol(self); - self->sep = '\0'; - jsonw_puts(self, name); - putc(':', self->out); - if (self->pretty) - putc(' ', self->out); -} - -void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) -{ - jsonw_eor(self); - putc('"', self->out); - vfprintf(self->out, fmt, ap); - putc('"', self->out); -} - -void jsonw_printf(json_writer_t *self, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - jsonw_eor(self); - vfprintf(self->out, fmt, ap); - va_end(ap); -} - -/* Collections */ -void jsonw_start_object(json_writer_t *self) -{ - jsonw_begin(self, '{'); -} - -void jsonw_end_object(json_writer_t *self) -{ - jsonw_end(self, '}'); -} - -void jsonw_start_array(json_writer_t *self) -{ - jsonw_begin(self, '['); -} - -void jsonw_end_array(json_writer_t *self) -{ - jsonw_end(self, ']'); -} - -/* JSON value types */ -void jsonw_string(json_writer_t *self, const char *value) -{ - jsonw_eor(self); - jsonw_puts(self, value); -} - -void jsonw_bool(json_writer_t *self, bool val) -{ - jsonw_printf(self, "%s", val ? "true" : "false"); -} - -void jsonw_null(json_writer_t *self) -{ - jsonw_printf(self, "null"); -} - -void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num) -{ - jsonw_printf(self, fmt, num); -} - -// #ifdef notused -void jsonw_float(json_writer_t *self, double num) -{ - jsonw_printf(self, "%g", num); -} -// #endif - -void jsonw_hu(json_writer_t *self, unsigned short num) -{ - jsonw_printf(self, "%hu", num); -} - -void jsonw_uint(json_writer_t *self, uint64_t num) -{ - jsonw_printf(self, "%"PRIu64, num); -} - -void jsonw_lluint(json_writer_t *self, unsigned long long int num) -{ - jsonw_printf(self, "%llu", num); -} - -void jsonw_int(json_writer_t *self, int64_t num) -{ - jsonw_printf(self, "%"PRId64, num); -} - -/* Basic name/value objects */ -void jsonw_string_field(json_writer_t *self, const char *prop, const char *val) -{ - jsonw_name(self, prop); - jsonw_string(self, val); -} - -void jsonw_bool_field(json_writer_t *self, const char *prop, bool val) -{ - jsonw_name(self, prop); - jsonw_bool(self, val); -} - -// #ifdef notused -void jsonw_float_field(json_writer_t *self, const char *prop, double val) -{ - jsonw_name(self, prop); - jsonw_float(self, val); -} -// #endif - -void jsonw_float_field_fmt(json_writer_t *self, - const char *prop, - const char *fmt, - double val) -{ - jsonw_name(self, prop); - jsonw_float_fmt(self, fmt, val); -} - -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) -{ - jsonw_name(self, prop); - jsonw_uint(self, num); -} - -void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) -{ - jsonw_name(self, prop); - jsonw_hu(self, num); -} - -void jsonw_lluint_field(json_writer_t *self, - const char *prop, - unsigned long long int num) -{ - jsonw_name(self, prop); - jsonw_lluint(self, num); -} - -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num) -{ - jsonw_name(self, prop); - jsonw_int(self, num); -} - -void jsonw_null_field(json_writer_t *self, const char *prop) -{ - jsonw_name(self, prop); - jsonw_null(self); -} - -#ifdef TEST -int main(int argc, char **argv) -{ - json_writer_t *wr = jsonw_new(stdout); - - jsonw_start_object(wr); - jsonw_pretty(wr, true); - jsonw_name(wr, "Vyatta"); - jsonw_start_object(wr); - jsonw_string_field(wr, "url", "http://vyatta.com"); - jsonw_uint_field(wr, "downloads", 2000000ul); - jsonw_float_field(wr, "stock", 8.16); - - jsonw_name(wr, "ARGV"); - jsonw_start_array(wr); - while (--argc) - jsonw_string(wr, *++argv); - jsonw_end_array(wr); - - jsonw_name(wr, "empty"); - jsonw_start_array(wr); - jsonw_end_array(wr); - - jsonw_name(wr, "NIL"); - jsonw_start_object(wr); - jsonw_end_object(wr); - - jsonw_null_field(wr, "my_null"); - - jsonw_name(wr, "special chars"); - jsonw_start_array(wr); - jsonw_string_field(wr, "slash", "/"); - jsonw_string_field(wr, "newline", "\n"); - jsonw_string_field(wr, "tab", "\t"); - jsonw_string_field(wr, "ff", "\f"); - jsonw_string_field(wr, "quote", "\""); - jsonw_string_field(wr, "tick", "\'"); - jsonw_string_field(wr, "backslash", "\\"); - jsonw_end_array(wr); - - jsonw_end_object(wr); - - jsonw_end_object(wr); - jsonw_destroy(&wr); - return 0; -} - -#endif diff --git a/archive/sg_json_writer.h b/archive/sg_json_writer.h deleted file mode 100644 index c751ade8..00000000 --- a/archive/sg_json_writer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ -/* - * Simple streaming JSON writer - * - * This takes care of the annoying bits of JSON syntax like the commas - * after elements - * - * Authors: Stephen Hemminger - * - * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc] - */ - -#ifndef SG_JSON_WRITER_H_ -#define SG_JSON_WRITER_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Need to resolve __printf(a, b) macro calls -#if defined(__GNUC__) || defined(__clang__) -#ifdef SG_LIB_MINGW -/* MinGW uses Microsoft's printf */ - -#define __printf(a, b) - -#else /* GNU/clang other than MinGW */ - -#define __printf(a, b) __attribute__ ((format (printf, a, b))) - -#endif - -#else /* not GNU (and not clang) */ - -#define __printf(a, b) - -#endif - -/* Opaque class structure */ -typedef struct json_writer json_writer_t; - -/* Create a new JSON stream */ -json_writer_t *jsonw_new(FILE *f); -/* End output to JSON stream */ -void jsonw_destroy(json_writer_t **self_p); - -/* Cause output to have pretty whitespace */ -void jsonw_pretty(json_writer_t *self, bool on); - -/* Reset separator to create new JSON */ -void jsonw_reset(json_writer_t *self); - -/* Add property name */ -void jsonw_name(json_writer_t *self, const char *name); - -/* Add value */ -void __printf(2, 0) jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, - va_list ap); -void __printf(2, 3) jsonw_printf(json_writer_t *self, const char *fmt, ...); -void jsonw_string(json_writer_t *self, const char *value); -void jsonw_bool(json_writer_t *self, bool value); -void jsonw_float(json_writer_t *self, double number); -void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); -void jsonw_uint(json_writer_t *self, uint64_t number); -void jsonw_hu(json_writer_t *self, unsigned short number); -void jsonw_int(json_writer_t *self, int64_t number); -void jsonw_null(json_writer_t *self); -void jsonw_lluint(json_writer_t *self, unsigned long long int num); - -/* Useful Combinations of name and value */ -void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); -void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); -void jsonw_float_field(json_writer_t *self, const char *prop, double num); -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num); -void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num); -void jsonw_null_field(json_writer_t *self, const char *prop); -void jsonw_lluint_field(json_writer_t *self, const char *prop, - unsigned long long int num); -void jsonw_float_field_fmt(json_writer_t *self, const char *prop, - const char *fmt, double val); - -/* Collections */ -void jsonw_start_object(json_writer_t *self); -void jsonw_end_object(json_writer_t *self); - -void jsonw_start_array(json_writer_t *self); -void jsonw_end_array(json_writer_t *self); - -/* Override default exception handling */ -typedef void (jsonw_err_handler_fn)(const char *); - -#ifdef __cplusplus -} -#endif - -#endif /* SG_JSON_WRITER_H_ */ diff --git a/src/sg_logs.c b/src/sg_logs.c index 0a49671b..9f8f2383 100644 --- a/src/sg_logs.c +++ b/src/sg_logs.c @@ -37,7 +37,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "2.02 20221101"; /* spc6r06 + sbc5r03 */ +static const char * version_str = "2.04 20221103"; /* spc6r06 + sbc5r03 */ #define MY_NAME "sg_logs" @@ -124,9 +124,10 @@ static const int parr_sz = 4096; static const char * unknown_s = "unknown"; static const char * not_avail = "not available"; -static const char * param_c = "parameter code"; +static const char * param_c = "Parameter code"; static const char * param_c_snake = "parameter_code"; static const char * as_s_s = "as_string"; +static const char * restricted_s = "restricted"; static struct option long_options[] = { {"All", no_argument, 0, 'A'}, /* equivalent to '-aa' */ @@ -192,6 +193,7 @@ struct opts_t { int do_hex; int do_list; int dstrhex_no_ascii; /* value for dStrHex() no_ascii argument */ + int hex2str_oformat; /* value for hex2str() oformat argument */ int vend_prod_num; /* one of the VP_* constants or -1 (def) */ int deduced_vpn; /* deduced vendor_prod_num; from INQUIRY, etc */ int verbose; @@ -953,18 +955,21 @@ pg_subpg_pdt_search(int pg_code, int subpg_code, int pdt, int vpn) } static void -js_snakenv_ihexstr_nex(sgj_state * jsp, sgj_opaque_p jop, const char * name, - int64_t val_i, bool hex_as_well, const char * str_name, +js_snakenv_ihexstr_nex(sgj_state * jsp, sgj_opaque_p jop, + const char * conv2sname, int64_t val_i, + bool hex_as_well, const char * str_name, const char * val_s, const char * nex_s) { - if (sgj_is_snake_name(name)) - sgj_js_nv_ihexstr_nex(jsp, jop, name, val_i, hex_as_well, str_name, - val_s, nex_s); + if ((NULL == jsp) || (NULL == jop)) + return; + if (sgj_is_snake_name(conv2sname)) + sgj_js_nv_ihexstr_nex(jsp, jop, conv2sname, val_i, hex_as_well, + str_name, val_s, nex_s); else { char b[128]; - sgj_convert_to_snake_name(name, b, sizeof(b)); + sgj_convert_to_snake_name(conv2sname, b, sizeof(b)); sgj_js_nv_ihexstr_nex(jsp, jop, b, val_i, hex_as_well, str_name, val_s, nex_s); } @@ -2115,14 +2120,26 @@ show_non_medium_error_page(const uint8_t * resp, int len, bool skip_out = false; bool evsm_output = false; int num, pl, pc; + uint64_t count; const uint8_t * bp; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p; + sgj_opaque_p jo3p = NULL; + sgj_opaque_p jap = NULL; char str[PCB_STR_LEN]; + char b[128] SG_C_CPP_ZERO_INIT; + static const char * nmelp = "Non-medium error log page"; + static const char * nmec = "Non-medium error count"; -if (jop) { }; if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) - printf("Non-medium error page [0x6]\n"); + sgj_pr_hr(jsp, "%s [0x6]\n", nmelp); num = len - 4; bp = &resp[0] + 4; + if (jsp->pr_as_json) { + jo2p = sg_log_js_hdr(jsp, jop, nmelp, resp); + jap = sgj_named_subarray_r(jsp, jo2p, + "non_medium_error_log_parameters"); + } while (num > 3) { pc = sg_get_unaligned_be16(bp + 0); pl = bp[3] + 4; @@ -2137,35 +2154,47 @@ if (jop) { }; hex2stdout(bp, pl, op->dstrhex_no_ascii); break; } + if (jsp->pr_as_json) { + jo3p = sgj_new_unattached_object_r(jsp); + if (op->do_pcb) + js_pcb(jsp, jo3p, bp[2]); + } + switch (pc) { case 0: - printf(" Non-medium error count"); + snprintf(b, sizeof(b), "%s", nmec); break; default: if (pc <= 0x7fff) - printf(" Reserved [0x%x]", pc); + snprintf(b, sizeof(b), " Reserved [0x%x]", pc); else { if (op->exclude_vendor) { skip_out = true; if ((op->verbose > 0) && (0 == op->do_brief) && (! evsm_output)) { evsm_output = true; - printf(" Vendor specific parameter(s) being " - "ignored\n"); + pr2serr(" Vendor specific parameter(s) being " + "ignored\n"); } } else - printf(" Vendor specific [0x%x]", pc); + snprintf(b, sizeof(b), "Vendor specific [0x%x]", pc); } break; } if (skip_out) skip_out = false; else { - printf(" = %" PRIu64 "", sg_get_unaligned_be(pl - 4, bp + 4)); - printf("\n"); + count = sg_get_unaligned_be(pl - 4, bp + 4); + sgj_pr_hr(jsp, " %s = %" PRIu64 "\n", b, count); + js_snakenv_ihexstr_nex(jsp, jo3p, param_c, pc, true, + NULL, b, NULL); + sgj_js_nv_ihex(jsp, jo3p, nmec, count); } if (op->do_pcb) - printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); + sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2], + str, sizeof(str))); + if (jsp->pr_as_json) + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); if (op->filter_given) break; skip: @@ -2181,14 +2210,27 @@ show_power_condition_transitions_page(const uint8_t * resp, int len, struct opts_t * op, sgj_opaque_p jop) { int num, pl, pc; + uint64_t count; const uint8_t * bp; + const char * cp; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p; + sgj_opaque_p jo3p = NULL; + sgj_opaque_p jap = NULL; char str[PCB_STR_LEN]; + char b[80]; + static const char * pctlp = "Power condition transitions log page"; -if (jop) { }; if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) - printf("Power condition transitions page [0x1a]\n"); + sgj_pr_hr(jsp, "%s [0x1a]\n", pctlp); num = len - 4; bp = &resp[0] + 4; + if (jsp->pr_as_json) { + jo2p = sg_log_js_hdr(jsp, jop, pctlp, resp); + jap = sgj_named_subarray_r(jsp, jo2p, + "power_condition_transition_log_parameters"); + } + while (num > 3) { pc = sg_get_unaligned_be16(bp + 0); pl = bp[3] + 4; @@ -2203,26 +2245,44 @@ if (jop) { }; hex2stdout(bp, pl, op->dstrhex_no_ascii); break; } + if (jsp->pr_as_json) { + jo3p = sgj_new_unattached_object_r(jsp); + if (op->do_pcb) + js_pcb(jsp, jo3p, bp[2]); + } + + cp = NULL; switch (pc) { case 1: - printf(" Accumulated transitions to active"); break; + cp = "Accumulated transitions to active"; + break; case 2: - printf(" Accumulated transitions to idle_a"); break; + cp = "Accumulated transitions to idle_a"; + break; case 3: - printf(" Accumulated transitions to idle_b"); break; + cp = "Accumulated transitions to idle_b"; + break; case 4: - printf(" Accumulated transitions to idle_c"); break; + cp = "Accumulated transitions to idle_c"; + break; case 8: - printf(" Accumulated transitions to standby_z"); break; + cp = "Accumulated transitions to standby_z"; + break; case 9: - printf(" Accumulated transitions to standby_y"); break; + cp = "Accumulated transitions to standby_y"; + break; default: - printf(" Reserved [0x%x]", pc); + snprintf(b, sizeof(b), "Reserved [0x%x]", pc); + cp = b; + break; } - printf(" = %" PRIu64 "", sg_get_unaligned_be(pl - 4, bp + 4)); - printf("\n"); + count = sg_get_unaligned_be(pl - 4, bp + 4); + sgj_pr_hr(jsp, " %s = %" PRIu64 "\n", cp, count); if (op->do_pcb) - printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); + sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2], + str, sizeof(str))); + if (jsp->pr_as_json) + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); if (op->filter_given) break; skip: @@ -2589,20 +2649,45 @@ skip: return true; } -/* CMD_DUR_LIMITS_SUBPG [0x19,0x21] introduced: SPC-6 (rev 01) */ +/* CMD_DUR_LIMITS_SUBPG [0x19,0x21] + * introduced: SPC-6 rev 1, significantly changed rev 6 */ static bool show_cmd_dur_limits_page(const uint8_t * resp, int len, struct opts_t * op, sgj_opaque_p jop) { int num, pl, pc; + uint32_t count, noitmc_v, noatmc_v, noitatmc_v, noc_v; const uint8_t * bp; + const char * cp; + const char * thp; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p; + sgj_opaque_p jo3p = NULL; + sgj_opaque_p jap = NULL; char str[PCB_STR_LEN]; + char b[144]; + static const char * cdllp = "Command duration limits statistics log page"; + static const char * t2cdld = "T2 command duration limit descriptor"; + static const char * cdlt2amp = "CDL T2A mode page"; + static const char * cdlt2bmp = "CDL T2B mode page"; + static const char * first_7[] = {"First", "Second", "Third", "Fourth", + "Fifth", "Sixth", "Seventh"}; + static const char * noitmc = "Number of inactive target miss commands"; + static const char * noatmc = "Number of active target miss commands"; + static const char * noitatmc = + "Number of inactive target and active target miss commands"; + static const char * noc = "Number of commands"; -if (jop) { }; if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) - printf("Command duration limits page [0x19,0x21]\n"); + sgj_pr_hr(jsp, "%s [0x19,0x21]\n", cdllp); num = len - 4; bp = &resp[0] + 4; + if (jsp->pr_as_json) { + jo2p = sg_log_js_hdr(jsp, jop, cdllp, resp); + jap = sgj_named_subarray_r(jsp, jo2p, + "command_duration_limits_statistcs_log_parameters"); + } + while (num > 3) { pc = sg_get_unaligned_be16(bp + 0); pl = bp[3] + 4; /* parameter length */ @@ -2617,10 +2702,24 @@ if (jop) { }; hex2stdout(bp, pl, op->dstrhex_no_ascii); break; } + if (jsp->pr_as_json) { + jo3p = sgj_new_unattached_object_r(jsp); + if (op->do_pcb) + js_pcb(jsp, jo3p, bp[2]); + } + switch (pc) { case 0x1: - printf(" Number of READ commands = %" PRIu64 "\n", - sg_get_unaligned_be64(bp + 4)); + /* spc6r06: table 349 name "Number of READ commands" seems to + * be wrong. Use what surrounding text and table 347 suggest */ + cp = "Achievable latency target"; + count = sg_get_unaligned_be32(bp + 4); + sgj_pr_hr(jsp, " %s = %" PRIu32 "\n", cp, count); + if (jsp->pr_as_json) { + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, cp); + js_snakenv_ihexstr_nex(jsp, jop, cp, count, true, NULL, NULL, + "unit: microsecond"); + } break; case 0x11: case 0x12: @@ -2629,6 +2728,11 @@ if (jop) { }; case 0x15: case 0x16: case 0x17: + sgj_pr_hr(jsp, " parameter code 0x%x restricted\n", pc); + if (jsp->pr_as_json) + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, + restricted_s); + break; case 0x21: case 0x22: case 0x23: @@ -2636,25 +2740,30 @@ if (jop) { }; case 0x25: case 0x26: case 0x27: - printf(" Command duration limit T2%s %d [Parameter code 0x%x]:\n", - ((pc > 0x20) ? "B" : "A"), - ((pc > 0x20) ? (pc - 0x20) : (pc - 0x10)), pc); - printf(" Number of inactive target miss commands = %u\n", - sg_get_unaligned_be32(bp + 4)); - printf(" Number of active target miss commands = %u\n", - sg_get_unaligned_be32(bp + 8)); - printf(" Number of latency miss commands = %u\n", - sg_get_unaligned_be32(bp + 12)); - printf(" Number of nonconforming miss commands = %u\n", - sg_get_unaligned_be32(bp + 16)); - printf(" Number of predictive latency miss commands = %u\n", - sg_get_unaligned_be32(bp + 20)); - printf(" Number of latency misses attributable to errors = %u\n", - sg_get_unaligned_be32(bp + 24)); - printf(" Number of latency misses attributable to deferred " - "errors = %u\n", sg_get_unaligned_be32(bp + 28)); - printf(" Number of latency misses attributable to background " - "operations = %u\n", sg_get_unaligned_be32(bp + 32)); + thp = first_7[pc - 0x21]; + sgj_pr_hr(jsp, " %s %s for %s [pc=0x%x]:\n", thp, t2cdld, + cdlt2amp, pc); + noitmc_v = sg_get_unaligned_be32(bp + 4); + sgj_pr_hr(jsp, " %s = %u\n", noitmc, noitmc_v); + noatmc_v = sg_get_unaligned_be32(bp + 8); + sgj_pr_hr(jsp, " %s = %u\n", noatmc, noatmc_v); + noitatmc_v = sg_get_unaligned_be32(bp + 12); + sgj_pr_hr(jsp, " %s = %u\n", noitatmc, noitatmc_v); + noc_v = sg_get_unaligned_be32(bp + 16); + sgj_pr_hr(jsp, " %s = %u\n", noc, noc_v); + if (jsp->pr_as_json) { + snprintf(b, sizeof(b), "%s %s for %s", thp, t2cdld, cdlt2amp); + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, b); + + js_snakenv_ihexstr_nex(jsp, jop, noitmc, noitmc_v, true, NULL, + NULL, NULL); + js_snakenv_ihexstr_nex(jsp, jop, noatmc, noatmc_v, true, NULL, + NULL, NULL); + js_snakenv_ihexstr_nex(jsp, jop, noitatmc, noitatmc_v, true, + NULL, NULL, NULL); + js_snakenv_ihexstr_nex(jsp, jop, noc, noc_v, true, NULL, + NULL, NULL); + } break; case 0x31: case 0x32: @@ -2663,6 +2772,11 @@ if (jop) { }; case 0x35: case 0x36: case 0x37: + sgj_pr_hr(jsp, " parameter code 0x%x restricted\n", pc); + if (jsp->pr_as_json) + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, + restricted_s); + break; case 0x41: case 0x42: case 0x43: @@ -2671,24 +2785,41 @@ if (jop) { }; case 0x46: case 0x47: /* This short form introduced in draft spc6r06 */ - printf(" Command duration limit T2%s %d [Parameter code 0x%x]:\n", - ((pc > 0x40) ? "B" : "A"), - ((pc > 0x40) ? (pc - 0x40) : (pc - 0x30)), pc); - printf(" Number of inactive target miss commands = %u\n", - sg_get_unaligned_be32(bp + 4)); - printf(" Number of active target miss commands = %u\n", - sg_get_unaligned_be32(bp + 8)); - printf(" Number of inactive+active target miss commands = %u\n", - sg_get_unaligned_be32(bp + 12)); - printf(" Number of commands = %u\n", - sg_get_unaligned_be32(bp + 16)); + thp = first_7[pc - 0x41]; + sgj_pr_hr(jsp, " %s %s for %s [pc=0x%x]:\n", thp, t2cdld, + cdlt2bmp, pc); + noitmc_v = sg_get_unaligned_be32(bp + 4); + sgj_pr_hr(jsp, " %s = %u\n", noitmc, noitmc_v); + noatmc_v = sg_get_unaligned_be32(bp + 8); + sgj_pr_hr(jsp, " %s = %u\n", noatmc, noatmc_v); + noitatmc_v = sg_get_unaligned_be32(bp + 12); + sgj_pr_hr(jsp, " %s = %u\n", noitatmc, noitatmc_v); + noc_v = sg_get_unaligned_be32(bp + 16); + sgj_pr_hr(jsp, " %s = %u\n", noc, noc_v); + if (jsp->pr_as_json) { + snprintf(b, sizeof(b), "%s %s for %s", thp, t2cdld, cdlt2amp); + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, b); + + js_snakenv_ihexstr_nex(jsp, jop, noitmc, noitmc_v, true, NULL, + NULL, NULL); + js_snakenv_ihexstr_nex(jsp, jop, noatmc, noatmc_v, true, NULL, + NULL, NULL); + js_snakenv_ihexstr_nex(jsp, jop, noitatmc, noitatmc_v, true, + NULL, NULL, NULL); + js_snakenv_ihexstr_nex(jsp, jop, noc, noc_v, true, NULL, + NULL, NULL); + } + break; default: - printf(" <do_pcb) - printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); + sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2], + str, sizeof(str))); + if (jsp->pr_as_json) + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); if (op->filter_given) break; skip: @@ -3059,22 +3190,33 @@ show_last_n_error_page(const uint8_t * resp, int len, { int k, num, pl; const uint8_t * bp; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p; + sgj_opaque_p jo3p = NULL; + sgj_opaque_p jap = NULL; char str[PCB_STR_LEN]; + char b[256]; + static const char * lneelp = "Last n error events log page"; + static const char * eed = "error_event_data"; -if (jop) { }; num = len - 4; bp = &resp[0] + 4; if (num < 4) { - printf("No error events logged\n"); + sgj_pr_hr(jsp, "No error events logged\n"); return true; } if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) - printf("Last n error events page [0x7]\n"); + sgj_pr_hr(jsp, "%s [0x7]\n", lneelp); + if (jsp->pr_as_json) { + jo2p = sg_log_js_hdr(jsp, jop, lneelp, resp); + jap = sgj_named_subarray_r(jsp, jo2p, "error_event_log_parameters"); + } + for (k = num; k > 0; k -= pl, bp += pl) { - int pc; + uint16_t pc; if (k < 3) { - printf("short Last n error events page\n"); + pr2serr("short %s\n", lneelp); return false; } pl = bp[3] + 4; @@ -3090,20 +3232,42 @@ if (jop) { }; hex2stdout(bp, pl, op->dstrhex_no_ascii); break; } - printf(" Error event %d:\n", pc); + if (jsp->pr_as_json) { + jo3p = sgj_new_unattached_object_r(jsp); + if (op->do_pcb) + js_pcb(jsp, jo3p, bp[2]); + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, NULL); + } + + sgj_pr_hr(jsp, " Error event %u [0x%x]:\n", pc, pc); if (pl > 4) { if ((bp[2] & 0x1) && (bp[2] & 0x2)) { - printf(" [binary]:\n"); - hex2stdout(bp + 4, pl - 4, op->dstrhex_no_ascii); - } else if (0x01 == (bp[2] & 0x3) /* ASCII */) - printf(" %.*s\n", pl - 4, (const char *)(bp + 4)); - else { - printf(" [data counter?? (LP bit should be set)]:\n"); - hex2stdout(bp + 4, pl - 4, op->dstrhex_no_ascii); + sgj_pr_hr(jsp, " [binary]:\n"); + hex2str(bp + 4, pl - 4, " ", op->hex2str_oformat, + sizeof(b), b); + sgj_pr_hr(jsp, "%s\n", b); + if (jsp->pr_as_json) + sgj_js_nv_hex_bytes(jsp, jo3p, eed, bp + 4, pl - 4); + } else if (0x01 == (bp[2] & 0x3)) { /* ASCII */ + sgj_pr_hr(jsp, " %.*s\n", pl - 4, (const char *)(bp + 4)); + if (jsp->pr_as_json) + sgj_js_nv_s_len(jsp, jo3p, eed, + (const char *)(bp + 4), pl - 4); + } else { + sgj_pr_hr(jsp, " [data counter?? (LP bit should be " + "set)]:\n"); + hex2str(bp + 4, pl - 4, " ", op->hex2str_oformat, + sizeof(b), b); + sgj_pr_hr(jsp, "%s\n", b); + if (jsp->pr_as_json) + sgj_js_nv_hex_bytes(jsp, jo3p, eed, bp + 4, pl - 4); } } if (op->do_pcb) - printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); + sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2], + str, sizeof(str))); + if (jsp->pr_as_json) + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); if (op->filter_given) break; } @@ -3117,23 +3281,37 @@ show_last_n_deferred_error_page(const uint8_t * resp, int len, { int k, n, num, pl; const uint8_t * bp; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p, jo4p; + sgj_opaque_p jo3p = NULL; + sgj_opaque_p jap = NULL; char str[PCB_STR_LEN]; + char b[512]; + static const char * lndeoaelp = + "Last n deferred errors or asynchronous events log page"; + static const char * deoae = "Deferred error or asynchronous event"; + static const char * sd = "sense_data"; -if (jop) { }; num = len - 4; bp = &resp[0] + 4; if (num < 4) { - printf("No deferred errors logged\n"); + pr2serr("No deferred errors logged\n"); return true; } if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) - printf("Last n deferred errors page [0xb]\n"); + sgj_pr_hr(jsp, "%s [0xb]\n", lndeoaelp); + if (jsp->pr_as_json) { + jo2p = sg_log_js_hdr(jsp, jop, lndeoaelp, resp); + jap = sgj_named_subarray_r(jsp, jo2p, + "deferred_error_or_asynchronous_event_log_parameters"); + } + for (k = num; k > 0; k -= pl, bp += pl) { int pc; if (k < 3) { - printf("short Last n deferred errors page\n"); - return true; + pr2serr("short %s\n", lndeoaelp); + return false; } pl = bp[3] + 4; pc = sg_get_unaligned_be16(bp + 0); @@ -3148,18 +3326,35 @@ if (jop) { }; hex2stdout(bp, pl, op->dstrhex_no_ascii); break; } - printf(" Deferred error [0x%x]:\n", pc); - if (op->do_brief > 0) + if (jsp->pr_as_json) { + jo3p = sgj_new_unattached_object_r(jsp); + if (op->do_pcb) + js_pcb(jsp, jo3p, bp[2]); + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, deoae); + } + sgj_pr_hr(jsp, " %s [0x%x]:\n", deoae, pc); + if (op->do_brief > 0) { hex2stdout(bp + 4, pl - 4, op->dstrhex_no_ascii); - else { - char b[512]; + hex2str(bp + 4, pl - 4, " ", op->hex2str_oformat, + sizeof(b), b); + sgj_pr_hr(jsp, "%s\n", b); + if (jsp->pr_as_json) + sgj_js_nv_hex_bytes(jsp, jo3p, sd, bp + 4, pl - 4); + } else { n = sg_get_sense_str(" ", bp + 4, pl - 4, false, sizeof(b), b); - printf("%.*s\n", n, b); + sgj_pr_hr(jsp, "%.*s\n", n, b); + if (jsp->pr_as_json) { + jo4p = sgj_named_subobject_r(jsp, jo3p, sd); + sgj_js_sense(jsp, jo4p, bp + 4, pl - 4); + } } if (op->do_pcb) - printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); + sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2], + str, sizeof(str))); + if (jsp->pr_as_json) + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); if (op->filter_given) break; } @@ -3171,16 +3366,33 @@ static bool show_last_n_inq_data_ch_page(const uint8_t * resp, int len, struct opts_t * op, sgj_opaque_p jop) { - int j, num, pl; - unsigned int k; + bool vpd; + int j, num, pl, vpd_pg; + uint32_t k, n; const uint8_t * bp; + const char * vpd_pg_name = NULL; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p, jo4p; + sgj_opaque_p jo3p = NULL; + sgj_opaque_p jap = NULL; + sgj_opaque_p ja2p; char str[PCB_STR_LEN]; + char b[128]; + static const char * lnidclp = "Last n inquiry data changed log page"; + static const char * clgc = "Change list generation code"; + static const char * idci = "Inquiry data changed indicator"; + static const char * cgn = "Changed generation number"; -if (jop) { }; if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) - printf("Last n Inquiry data changed [0xb,0x1]\n"); + sgj_pr_hr(jsp, "%s [0xb,0x1]\n", lnidclp); num = len - 4; bp = &resp[0] + 4; + if (jsp->pr_as_json) { + jo2p = sg_log_js_hdr(jsp, jop, lnidclp, resp); + jap = sgj_named_subarray_r(jsp, jo2p, + "inquiry_data_changed_log_parameters"); + } + while (num > 3) { int pc = sg_get_unaligned_be16(bp + 0); @@ -3196,42 +3408,75 @@ if (jop) { }; hex2stdout(bp, pl, op->dstrhex_no_ascii); break; } + if (jsp->pr_as_json) { + jo3p = sgj_new_unattached_object_r(jsp); + if (op->do_pcb) + js_pcb(jsp, jo3p, bp[2]); + sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, + 0 == pc ? clgc : idci); + } if (0 == pc) { if (pl < 8) { - printf(" <>\n", pc, pl); + pr2serr(" <>\n", pc, pl); goto skip; } - printf(" Change list generation code [pc=0x0]:\n"); - for (j = 4, k = 1; j < pl; j +=4, ++k) - printf(" Changed generation number [0x%x]: %u\n", k, - sg_get_unaligned_be32(bp + j)); + sgj_pr_hr(jsp, " %s [pc=0x0]:\n", clgc); + for (j = 4, k = 1; j < pl; j +=4, ++k) { + n = sg_get_unaligned_be32(bp + j); + sgj_pr_hr(jsp, " %s [0x%x]: %u\n", cgn, k, n); + } + if (jsp->pr_as_json) { + ja2p = sgj_named_subarray_r(jsp, jo3p, + "changed_generation_numbers"); + for (j = 4, k = 1; j < pl; j +=4, ++k) { + jo4p = sgj_new_unattached_object_r(jsp); + n = sg_get_unaligned_be32(bp + j); + js_snakenv_ihexstr_nex(jsp, jo4p, cgn, n, true, NULL, + NULL, NULL); + sgj_js_nv_o(jsp, ja2p, NULL /* name */, jo4p); + } + } } else { - printf(" Parameter code 0x%x, ", pc); - if (1 & *(bp + 4)) { /* VPD bit set */ - int vpd = *(bp + 5); - printf("VPD page 0x%x changed\n", vpd); + int m; + const int nn = sg_lib_names_mode_len; + struct sg_lib_simple_value_name_t * nvp = sg_lib_names_vpd_arr; + + snprintf(b, sizeof(b), " %s 0x%x, ", param_c, pc); + vpd = !! (1 & *(bp + 4)); + vpd_pg = *(bp + 5); + if (vpd) { + for (m = 0; m < nn; ++m, ++nvp) { + if (nvp->value == vpd_pg) + break; + } + vpd_pg_name = (m < nn) ? nvp->name : NULL; + } else + vpd_pg_name = "Standard INQUIRY"; + + if (jsp->pr_as_json) { + sgj_js_nv_i(jsp, jo3p, "vpd", (int)vpd); + sgj_js_nv_ihex(jsp, jo3p, "changed_page_code", vpd_pg); + if (vpd_pg_name) + sgj_js_nv_s(jsp, jo3p, "changed_page_name", vpd_pg_name); + } + if (vpd) { + sgj_pr_hr(jsp, "%sVPD page 0x%x changed\n", b, vpd_pg); if (0 == op->do_brief) { - int m; - const int nn = sg_lib_names_mode_len; - struct sg_lib_simple_value_name_t * nvp = - sg_lib_names_vpd_arr; - - for (m = 0; m < nn; ++m, ++nvp) { - if (nvp->value == vpd) - break; - } - if (m < nn) - printf(" name: %s\n", nvp->name); + if (vpd_pg_name) + sgj_pr_hr(jsp, " name: %s\n", vpd_pg_name); } } else - printf("Standard Inquiry data changed\n"); + sgj_pr_hr(jsp, "%sStandard INQUIRY data changed\n", b); } if (op->do_pcb) - printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); + sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2], + str, sizeof(str))); +skip: + if (jsp->pr_as_json) + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); if (op->filter_given) break; -skip: num -= pl; bp += pl; } @@ -3247,6 +3492,7 @@ show_last_n_mode_pg_data_ch_page(const uint8_t * resp, int len, const uint8_t * bp; char str[PCB_STR_LEN]; +// yyyyyyyyy if (jop) { }; if (op->verbose || ((! op->do_raw) && (0 == op->do_hex))) printf("Last n Mode page data changed [0xb,0x2]\n"); @@ -7739,18 +7985,26 @@ main(int argc, char * argv[]) return 0; } if (op->do_hex > 0) { - if (op->do_hex > 2) + if (op->do_hex > 2) { op->dstrhex_no_ascii = -1; - else + op->hex2str_oformat = 1; + } else { op->dstrhex_no_ascii = (1 == op->do_hex); + op->hex2str_oformat = (1 == op->do_hex); + } } else { if (op->undefined_hex > 0) { - if (op->undefined_hex > 2) + if (op->undefined_hex > 2) { op->dstrhex_no_ascii = -1; - else + op->hex2str_oformat = 1; + } else { op->dstrhex_no_ascii = (1 == op->undefined_hex); - } else /* default when no --hex nor --undefined */ + op->hex2str_oformat = (1 == op->undefined_hex); + } + } else { /* default when no --hex nor --undefined */ op->dstrhex_no_ascii = -1; + op->hex2str_oformat = 1; + } } vb = op->verbose; if (op->vend_prod) { @@ -8182,7 +8436,7 @@ err_out: } if (as_json) { if (0 == op->do_hex) - sgj_js2file(jsp, NULL, res, stdout); + sgj_js2file(jsp, NULL, ret, stdout); sgj_finish(jsp); } return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; diff --git a/src/sg_read_block_limits.c b/src/sg_read_block_limits.c index 3ffa1dc2..4fc1fae6 100644 --- a/src/sg_read_block_limits.c +++ b/src/sg_read_block_limits.c @@ -37,7 +37,9 @@ static const char * version_str = "1.09 20221101"; -#define MAX_READ_BLOCK_LIMITS_LEN 20 +#define DEF_READ_BLOCK_LIMITS_LEN 6 +#define MLIO_READ_BLOCK_LIMITS_LEN 20 +#define MAX_READ_BLOCK_LIMITS_LEN MLIO_READ_BLOCK_LIMITS_LEN static uint8_t readBlkLmtBuff[MAX_READ_BLOCK_LIMITS_LEN]; @@ -191,7 +193,8 @@ main(int argc, char * argv[]) goto the_end2; } - max_resp_len = do_mloi ? 20 : 6; + max_resp_len = do_mloi ? MLIO_READ_BLOCK_LIMITS_LEN : + DEF_READ_BLOCK_LIMITS_LEN; memset(readBlkLmtBuff, 0x0, sizeof(readBlkLmtBuff)); res = sg_ll_read_block_limits_v2(sg_fd, do_mloi, readBlkLmtBuff, max_resp_len, &resid, true, verbose); @@ -213,9 +216,9 @@ main(int argc, char * argv[]) } if (do_mloi) { - if (actual_len < 20) { - pr2serr("Expected at least 20 bytes in response but only " - "%d bytes\n", actual_len); + if (actual_len < MLIO_READ_BLOCK_LIMITS_LEN) { + pr2serr("Expected at least %d bytes in response but only " + "%d bytes\n", MLIO_READ_BLOCK_LIMITS_LEN, actual_len); goto the_end; } printf("Read Block Limits (MLOI=1) results:\n"); @@ -223,9 +226,9 @@ main(int argc, char * argv[]) printf(" Maximum logical block identifier: %" PRIu64 "\n", mloi); } else { /* MLOI=0 (only case before ssc4r02.pdf) */ - if (actual_len < 6) { - pr2serr("Expected at least 6 bytes in response but only " - "%d bytes\n", actual_len); + if (actual_len < DEF_READ_BLOCK_LIMITS_LEN) { + pr2serr("Expected at least %d bytes in response but only " + "%d bytes\n", DEF_READ_BLOCK_LIMITS_LEN, actual_len); goto the_end; } max_block_size = sg_get_unaligned_be32(readBlkLmtBuff + 0); -- cgit v1.2.3