From 4fa513090a05602bf5378a33fdb3a60f56684f1e Mon Sep 17 00:00:00 2001 From: Uwe Seimet <48174652+uweseimet@users.noreply.github.com> Date: Thu, 10 Nov 2022 07:44:06 +0100 Subject: [PATCH] Improve code sharing and dependencies, address code duplication (#976) --- cpp/.gitignore | 3 +- cpp/Makefile | 85 ++++---- cpp/controllers/abstract_controller.cpp | 4 +- cpp/controllers/abstract_controller.h | 2 +- cpp/controllers/phase_handler.h | 2 +- cpp/controllers/scsi_controller.cpp | 4 +- cpp/controllers/scsi_controller.h | 6 +- cpp/devices/cfilesystem.cpp | 2 +- cpp/devices/ctapdriver.cpp | 8 +- cpp/devices/device.cpp | 4 +- cpp/devices/device.h | 2 +- cpp/devices/device_factory.cpp | 2 +- cpp/devices/device_factory.h | 2 +- cpp/devices/disk.cpp | 4 +- cpp/devices/disk.h | 2 +- cpp/devices/disk_track.cpp | 2 +- cpp/devices/host_services.cpp | 2 +- cpp/devices/mode_page_device.cpp | 4 +- cpp/devices/primary_device.cpp | 4 +- cpp/devices/primary_device.h | 2 +- cpp/devices/scsi_command_util.cpp | 4 +- cpp/devices/scsi_command_util.h | 2 +- cpp/devices/scsi_daynaport.cpp | 4 +- cpp/devices/scsi_host_bridge.cpp | 4 +- cpp/devices/scsi_printer.cpp | 4 +- cpp/devices/scsicd.cpp | 2 +- cpp/devices/scsihd.cpp | 2 +- cpp/devices/scsihd.h | 2 +- cpp/devices/scsihd_nec.cpp | 6 +- cpp/devices/scsimo.cpp | 2 +- cpp/devices/storage_device.cpp | 2 +- cpp/hal/bus.h | 4 +- cpp/hal/gpiobus.cpp | 4 +- cpp/hal/gpiobus.h | 4 +- cpp/hal/systimer.cpp | 2 +- cpp/hal/systimer.h | 4 +- cpp/monitor/data_sample.cpp | 2 +- cpp/monitor/data_sample.h | 2 +- cpp/monitor/sm_core.cpp | 36 +--- cpp/monitor/sm_core.h | 1 - cpp/monitor/sm_html_report.cpp | 6 +- cpp/monitor/sm_json_report.cpp | 3 +- cpp/monitor/sm_vcd_report.cpp | 8 +- cpp/rascsi/command_context.cpp | 4 +- cpp/rascsi/command_context.h | 4 +- cpp/rascsi/rascsi_core.cpp | 169 +++++++-------- cpp/rascsi/rascsi_core.h | 17 +- cpp/rascsi/rascsi_executor.cpp | 10 +- cpp/rascsi/rascsi_executor.h | 2 +- cpp/rascsi/rascsi_image.cpp | 4 +- cpp/rascsi/rascsi_image.h | 2 +- cpp/rascsi/rascsi_response.cpp | 8 +- cpp/rascsi/rascsi_response.h | 2 +- cpp/rascsi/rascsi_service.cpp | 8 +- cpp/rascsi/rascsi_service.h | 2 +- cpp/rasctl/rasctl_commands.cpp | 9 +- cpp/rasctl/rasctl_commands.h | 4 +- cpp/rasctl/rasctl_core.cpp | 41 ++-- cpp/rasctl/rasctl_core.h | 5 +- cpp/rasctl/rasctl_display.cpp | 6 +- cpp/rasctl/rasctl_display.h | 2 +- cpp/rasctl/rasctl_parser.cpp | 1 - cpp/rasctl/rasctl_parser.h | 2 +- cpp/rasdump/rasdump_core.cpp | 262 +++++++++-------------- cpp/rasdump/rasdump_core.h | 16 +- cpp/{ => shared}/config.h | 2 - cpp/{ => shared}/log.h | 0 cpp/{ => shared}/protobuf_serializer.cpp | 6 +- cpp/{ => shared}/protobuf_serializer.h | 0 cpp/{ => shared}/protobuf_util.cpp | 55 ++++- cpp/{ => shared}/protobuf_util.h | 6 +- cpp/{ => shared}/rascsi_exceptions.h | 5 + cpp/{ => shared}/rascsi_version.cpp | 0 cpp/{ => shared}/rascsi_version.h | 0 cpp/{ => shared}/rasutil.cpp | 72 ++----- cpp/{ => shared}/rasutil.h | 13 +- cpp/{ => shared}/scsi.h | 0 cpp/test/abstract_controller_test.cpp | 2 +- cpp/test/device_factory_test.cpp | 4 +- cpp/test/device_test.cpp | 2 +- cpp/test/disk_test.cpp | 4 +- cpp/test/host_services_test.cpp | 2 +- cpp/test/mode_page_device_test.cpp | 2 +- cpp/test/primary_device_test.cpp | 4 +- cpp/test/protobuf_serializer_test.cpp | 6 +- cpp/test/protobuf_util_test.cpp | 29 ++- cpp/test/rascsi_exceptions_test.cpp | 2 +- cpp/test/rascsi_executor_test.cpp | 6 +- cpp/test/rascsi_image_test.cpp | 4 +- cpp/test/rascsi_response_test.cpp | 4 +- cpp/test/rasctl_commands_test.cpp | 6 +- cpp/test/rasutil_test.cpp | 43 +--- cpp/test/scsi_command_util_test.cpp | 4 +- cpp/test/scsi_controller_test.cpp | 4 +- cpp/test/scsi_daynaport_test.cpp | 2 +- cpp/test/scsi_printer_test.cpp | 2 +- cpp/test/scsicd_test.cpp | 2 +- cpp/test/scsihd_nec_test.cpp | 2 +- cpp/test/scsihd_test.cpp | 2 +- cpp/test/storage_device_test.cpp | 2 +- cpp/test/test_shared.cpp | 4 +- cpp/test/test_shared.h | 4 +- doc/rasctl.1 | 7 +- doc/rasctl_man_page.txt | 26 +-- 104 files changed, 541 insertions(+), 635 deletions(-) rename cpp/{ => shared}/config.h (96%) rename cpp/{ => shared}/log.h (100%) rename cpp/{ => shared}/protobuf_serializer.cpp (94%) rename cpp/{ => shared}/protobuf_serializer.h (100%) rename cpp/{ => shared}/protobuf_util.cpp (65%) rename cpp/{ => shared}/protobuf_util.h (85%) rename cpp/{ => shared}/rascsi_exceptions.h (91%) rename cpp/{ => shared}/rascsi_version.cpp (100%) rename cpp/{ => shared}/rascsi_version.h (100%) rename cpp/{ => shared}/rasutil.cpp (52%) rename cpp/{ => shared}/rasutil.h (63%) rename cpp/{ => shared}/scsi.h (100%) diff --git a/cpp/.gitignore b/cpp/.gitignore index e5c2d4e4..813de54d 100644 --- a/cpp/.gitignore +++ b/cpp/.gitignore @@ -11,8 +11,7 @@ rascsi.dat obj bin coverage -/rascsi_interface.pb.cpp -/rascsi_interface.pb.h +generated .project .cproject .settings diff --git a/cpp/Makefile b/cpp/Makefile index 483a71c4..2eb22067 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -66,12 +66,12 @@ RSYSLOG_LOG = /var/log/rascsi.log USR_LOCAL_BIN = /usr/local/bin MAN_PAGE_DIR = /usr/local/man/man1 DOC_DIR = ../doc -COVERAGE_DIR = ./coverage +COVERAGE_DIR = coverage COVERAGE_FILE = rascsi.dat -OS_FILES = ./os_integration +OS_FILES = os_integration -OBJDIR := ./obj/$(shell echo $(CONNECT_TYPE) | tr '[:upper:]' '[:lower:]') -BINDIR := ./bin/$(shell echo $(CONNECT_TYPE) | tr '[:upper:]' '[:lower:]') +OBJDIR := obj/$(shell echo $(CONNECT_TYPE) | tr '[:upper:]' '[:lower:]') +BINDIR := bin/$(shell echo $(CONNECT_TYPE) | tr '[:upper:]' '[:lower:]') BIN_ALL = \ $(BINDIR)/$(RASCSI) \ @@ -79,17 +79,17 @@ BIN_ALL = \ $(BINDIR)/$(SCSIMON) \ $(BINDIR)/$(RASDUMP) -SRC_PROTOC = \ - rascsi_interface.proto +SRC_PROTOC = rascsi_interface.proto + +SRC_GENERATED = $(GENERATED_DIR)/rascsi_interface.pb.cpp SRC_PROTOBUF = \ - rascsi_interface.pb.cpp + shared/protobuf_util.cpp \ + shared/protobuf_serializer.cpp SRC_SHARED = \ - rascsi_version.cpp \ - rasutil.cpp \ - protobuf_util.cpp \ - protobuf_serializer.cpp + shared/rascsi_version.cpp \ + shared/rasutil.cpp SRC_RASCSI_CORE = $(shell find ./rascsi -name '*.cpp') SRC_RASCSI_CORE += $(shell find ./controllers -name '*.cpp') @@ -98,9 +98,7 @@ SRC_RASCSI_CORE += $(shell find ./hal -name '*.cpp') SRC_RASCSI = rascsi.cpp -SRC_SCSIMON = \ - scsimon.cpp \ - rascsi_version.cpp +SRC_SCSIMON = scsimon.cpp SRC_SCSIMON += $(shell find ./monitor -name '*.cpp') SRC_SCSIMON += $(shell find ./hal -name '*.cpp') @@ -108,9 +106,7 @@ SRC_RASCTL_CORE = $(shell find ./rasctl -name '*.cpp') SRC_RASCTL = rasctl.cpp -SRC_RASDUMP = \ - rasdump.cpp \ - rascsi_version.cpp +SRC_RASDUMP = rasdump.cpp SRC_RASDUMP += $(shell find ./rasdump -name '*.cpp') SRC_RASDUMP += $(shell find ./hal -name '*.cpp') @@ -118,8 +114,8 @@ SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp') SRC_RASCSI_TEST += $(shell find ./rasdump -name '*.cpp') SRC_RASCSI_TEST += $(shell find ./monitor -name '*.cpp') -vpath %.h ./ ./controllers ./devices ./monitor ./hal ./rascsi ./rasctl ./rasdump -vpath %.cpp ./ ./controllers ./devices ./monitor ./hal ./rascsi ./rasctl ./rasdump ./test +vpath %.h ./ ./shared ./controllers ./devices ./monitor ./hal ./rascsi ./rasctl ./rasdump +vpath %.cpp ./ ./shared ./controllers ./devices ./monitor ./hal ./rascsi ./rasctl ./rasdump ./test vpath %.o ./$(OBJDIR) vpath ./$(BINDIR) @@ -133,26 +129,31 @@ OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o))) OBJ_RASCSI_TEST := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCSI_TEST:%.cpp=%.o))) OBJ_SHARED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SHARED:%.cpp=%.o))) OBJ_PROTOBUF := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PROTOBUF:%.cpp=%.o))) +OBJ_GENERATED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_GENERATED:%.cpp=%.o))) -GEN_PROTOBUF := $(SRC_PROTOBUF) rascsi_interface.pb.h +GENERATED_DIR := generated # The following will include all of the auto-generated dependency files (*.d) # if they exist. This will trigger a rebuild of a source file if a header changes -ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_SCSIMON) $(OBJ_RASCSI_TEST)) +ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SCSIMON) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_RASCSI_TEST)) -include $(ALL_DEPS) $(OBJDIR) $(BINDIR): - echo "-- Creating directory $@" + @echo "-- Creating directory $@" mkdir -p $@ $(OBJDIR)/%.o: %.cpp | $(OBJDIR) $(CXX) $(CXXFLAGS) -c $< -o $@ -$(SRC_PROTOBUF): $(SRC_PROTOC) - echo "-- Generating protobuf-based source files" - protoc --cpp_out=. $(SRC_PROTOC) - mv rascsi_interface.pb.cc $@ +$(SRC_GENERATED) : $(SRC_PROTOC) + @echo "-- Generating protobuf-based source files" + mkdir -p $(GENERATED_DIR) + protoc --cpp_out=$(GENERATED_DIR) $(SRC_PROTOC) + mv $(GENERATED_DIR)/rascsi_interface.pb.cc $@ + +$(OBJ_GENERATED) : $(SRC_GENERATED) + $(CXX) $(CXXFLAGS) -c $< -o $@ ## Build Targets: ## all : Rebuild all of the executable files and re-generate @@ -180,37 +181,37 @@ lcov: test docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(DOC_DIR)/rasdump_man_page.txt -$(SRC_SHARED) $(SRC_RASCSI_CORE) $(SRC_RASCTL_CORE): $(OBJ_PROTOBUF) +$(SRC_RASCSI_CORE) $(SRC_RASCTL_CORE) : $(OBJ_GENERATED) -$(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) -lpthread -lpcap -lprotobuf -lstdc++fs +$(BINDIR)/$(RASCSI): $(SRC_GENERATED) $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lstdc++fs -$(BINDIR)/$(RASCTL): $(SRC_PROTOBUF) $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) -lpthread -lprotobuf +$(BINDIR)/$(RASCTL): $(SRC_GENERATED) $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL_CORE) $(OBJ_RASCTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lprotobuf -$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP) +$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) $(OBJ_SHARED) | $(BINDIR) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP) $(OBJ_SHARED) -$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) -lpthread +$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) $(OBJ_SHARED) | $(BINDIR) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) $(OBJ_SHARED) -$(BINDIR)/$(RASCSI_TEST): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_RASCTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) -lpthread -lpcap -lprotobuf -lstdc++fs -lgmock -lgtest +$(BINDIR)/$(RASCSI_TEST): $(SRC_GENERATED) $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_RASCTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR) + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCTL_CORE) $(OBJ_RASCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lstdc++fs -lgmock -lgtest # Phony rules for building individual utilities -.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SCSIMON) -$(RASCSI) : $(BINDIR)/$(RASCSI) -$(RASCTL) : $(BINDIR)/$(RASCTL) +.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SCSIMON) $(RASCSI_TEST) +$(RASCSI) : $(BINDIR)/$(RASCSI) +$(RASCTL) : $(BINDIR)/$(RASCTL) $(RASDUMP) : $(BINDIR)/$(RASDUMP) $(SCSIMON) : $(BINDIR)/$(SCSIMON) - +$(RASCSI_TEST): $(BINDIR)/$(RASCSI_TEST) ## clean : Remove all of the object files, intermediate ## compiler files and executable files .PHONY: clean clean: - rm -rf $(OBJDIR) $(BINDIR) $(GEN_PROTOBUF) $(COVERAGE_DIR) $(COVERAGE_FILE) + rm -rf $(OBJDIR) $(BINDIR) $(GENERATED_DIR) $(COVERAGE_DIR) $(COVERAGE_FILE) ## install : Copies all of the man pages to the correct location ## Copies the binaries to a global install location diff --git a/cpp/controllers/abstract_controller.cpp b/cpp/controllers/abstract_controller.cpp index 7354bce3..b2e6d9b4 100644 --- a/cpp/controllers/abstract_controller.cpp +++ b/cpp/controllers/abstract_controller.cpp @@ -7,8 +7,8 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "devices/primary_device.h" #include "abstract_controller.h" diff --git a/cpp/controllers/abstract_controller.h b/cpp/controllers/abstract_controller.h index 0b4a24f0..587fdadd 100644 --- a/cpp/controllers/abstract_controller.h +++ b/cpp/controllers/abstract_controller.h @@ -11,7 +11,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include "hal/bus.h" #include "phase_handler.h" #include "controller_manager.h" diff --git a/cpp/controllers/phase_handler.h b/cpp/controllers/phase_handler.h index 3cdd4606..47ae864e 100644 --- a/cpp/controllers/phase_handler.h +++ b/cpp/controllers/phase_handler.h @@ -9,7 +9,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" class PhaseHandler { diff --git a/cpp/controllers/scsi_controller.cpp b/cpp/controllers/scsi_controller.cpp index 698f9fb8..19bc3122 100644 --- a/cpp/controllers/scsi_controller.cpp +++ b/cpp/controllers/scsi_controller.cpp @@ -12,10 +12,10 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "hal/gpiobus.h" #include "hal/systimer.h" -#include "rascsi_exceptions.h" #include "devices/interfaces/byte_writer.h" #include "devices/mode_page_device.h" #include "devices/disk.h" diff --git a/cpp/controllers/scsi_controller.h b/cpp/controllers/scsi_controller.h index b1167540..502d9bf7 100644 --- a/cpp/controllers/scsi_controller.h +++ b/cpp/controllers/scsi_controller.h @@ -14,11 +14,13 @@ #pragma once +#include "shared/scsi.h" #include "controller_manager.h" #include "abstract_controller.h" -#include "scsi.h" #include +using namespace std; + class PrimaryDevice; class ScsiController : public AbstractController @@ -46,7 +48,7 @@ class ScsiController : public AbstractController // ATN message bool atnmsg; int msc; - std::array msb; + array msb; }; public: diff --git a/cpp/devices/cfilesystem.cpp b/cpp/devices/cfilesystem.cpp index ba4b0c89..d0cd7e4d 100644 --- a/cpp/devices/cfilesystem.cpp +++ b/cpp/devices/cfilesystem.cpp @@ -17,7 +17,7 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" #include "cfilesystem.h" #include #include diff --git a/cpp/devices/ctapdriver.cpp b/cpp/devices/ctapdriver.cpp index 02f24a27..df02e187 100644 --- a/cpp/devices/ctapdriver.cpp +++ b/cpp/devices/ctapdriver.cpp @@ -9,13 +9,13 @@ // //--------------------------------------------------------------------------- +#include "shared/log.h" +#include "shared/rasutil.h" +#include "shared/rascsi_exceptions.h" #include #include #include #include "ctapdriver.h" -#include "log.h" -#include "rasutil.h" -#include "rascsi_exceptions.h" #include #include #include @@ -236,7 +236,7 @@ bool CTapDriver::Init(const unordered_map& const_params) address = inet.substr(0, separatorPos); int m; - if (!GetAsInt(inet.substr(separatorPos + 1), m) || m < 8 || m > 32) { + if (!GetAsUnsignedInt(inet.substr(separatorPos + 1), m) || m < 8 || m > 32) { LOGERROR("Invalid CIDR netmask notation '%s'", inet.substr(separatorPos + 1).c_str()) close(m_hTAP); diff --git a/cpp/devices/device.cpp b/cpp/devices/device.cpp index 8a329409..c30343a3 100644 --- a/cpp/devices/device.cpp +++ b/cpp/devices/device.cpp @@ -7,8 +7,8 @@ // //--------------------------------------------------------------------------- -#include "rascsi_version.h" -#include "log.h" +#include "shared/log.h" +#include "shared/rascsi_version.h" #include "device.h" #include #include diff --git a/cpp/devices/device.h b/cpp/devices/device.h index cb403ef4..1decf11a 100644 --- a/cpp/devices/device.h +++ b/cpp/devices/device.h @@ -9,7 +9,7 @@ #pragma once -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include #include diff --git a/cpp/devices/device_factory.cpp b/cpp/devices/device_factory.cpp index 5706035c..a16f0ab2 100644 --- a/cpp/devices/device_factory.cpp +++ b/cpp/devices/device_factory.cpp @@ -7,6 +7,7 @@ // //--------------------------------------------------------------------------- +#include "shared/rasutil.h" #include "scsihd.h" #include "scsihd_nec.h" #include "scsimo.h" @@ -15,7 +16,6 @@ #include "scsi_host_bridge.h" #include "scsi_daynaport.h" #include "host_services.h" -#include "rasutil.h" #include "device_factory.h" #include #include diff --git a/cpp/devices/device_factory.h b/cpp/devices/device_factory.h index 08287952..5ae023f7 100644 --- a/cpp/devices/device_factory.h +++ b/cpp/devices/device_factory.h @@ -15,7 +15,7 @@ #include #include #include -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" using namespace std; using namespace rascsi_interface; diff --git a/cpp/devices/disk.cpp b/cpp/devices/disk.cpp index 95285931..5db92dab 100644 --- a/cpp/devices/disk.cpp +++ b/cpp/devices/disk.cpp @@ -14,8 +14,8 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "disk.h" diff --git a/cpp/devices/disk.h b/cpp/devices/disk.h index c6d10b00..75af2697 100644 --- a/cpp/devices/disk.h +++ b/cpp/devices/disk.h @@ -15,7 +15,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include "device_factory.h" #include "disk_track.h" #include "disk_cache.h" diff --git a/cpp/devices/disk_track.cpp b/cpp/devices/disk_track.cpp index 9e18ec25..8f046be1 100644 --- a/cpp/devices/disk_track.cpp +++ b/cpp/devices/disk_track.cpp @@ -14,7 +14,7 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" #include "disk_track.h" #include diff --git a/cpp/devices/host_services.cpp b/cpp/devices/host_services.cpp index 88bc6558..bd5aa10a 100644 --- a/cpp/devices/host_services.cpp +++ b/cpp/devices/host_services.cpp @@ -20,8 +20,8 @@ // c) start && load (LOAD): Reboot the Raspberry Pi // +#include "shared/rascsi_exceptions.h" #include "controllers/scsi_controller.h" -#include "rascsi_exceptions.h" #include "scsi_command_util.h" #include "host_services.h" #include diff --git a/cpp/devices/mode_page_device.cpp b/cpp/devices/mode_page_device.cpp index ff069fb9..2c6e5535 100644 --- a/cpp/devices/mode_page_device.cpp +++ b/cpp/devices/mode_page_device.cpp @@ -9,8 +9,8 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "mode_page_device.h" #include diff --git a/cpp/devices/primary_device.cpp b/cpp/devices/primary_device.cpp index 14a21b50..02a92924 100644 --- a/cpp/devices/primary_device.cpp +++ b/cpp/devices/primary_device.cpp @@ -7,8 +7,8 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "primary_device.h" diff --git a/cpp/devices/primary_device.h b/cpp/devices/primary_device.h index d57791f9..254433d8 100644 --- a/cpp/devices/primary_device.h +++ b/cpp/devices/primary_device.h @@ -11,7 +11,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include "interfaces/scsi_primary_commands.h" #include "controllers/abstract_controller.h" #include "device.h" diff --git a/cpp/devices/scsi_command_util.cpp b/cpp/devices/scsi_command_util.cpp index 9737f7ea..b4b6e426 100644 --- a/cpp/devices/scsi_command_util.cpp +++ b/cpp/devices/scsi_command_util.cpp @@ -7,8 +7,8 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" using namespace scsi_defs; diff --git a/cpp/devices/scsi_command_util.h b/cpp/devices/scsi_command_util.h index 13b1bd26..209c3df2 100644 --- a/cpp/devices/scsi_command_util.h +++ b/cpp/devices/scsi_command_util.h @@ -11,7 +11,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include #include diff --git a/cpp/devices/scsi_daynaport.cpp b/cpp/devices/scsi_daynaport.cpp index 08821a2e..beacae69 100644 --- a/cpp/devices/scsi_daynaport.cpp +++ b/cpp/devices/scsi_daynaport.cpp @@ -24,8 +24,8 @@ // Note: This requires a DaynaPort SCSI Link driver. //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "scsi_daynaport.h" diff --git a/cpp/devices/scsi_host_bridge.cpp b/cpp/devices/scsi_host_bridge.cpp index 7be8c333..f0e1bc70 100644 --- a/cpp/devices/scsi_host_bridge.cpp +++ b/cpp/devices/scsi_host_bridge.cpp @@ -16,8 +16,8 @@ // work with the Sharp X68000 operating system. //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "scsi_host_bridge.h" #include diff --git a/cpp/devices/scsi_printer.cpp b/cpp/devices/scsi_printer.cpp index 986ca0ff..0d4c7736 100644 --- a/cpp/devices/scsi_printer.cpp +++ b/cpp/devices/scsi_printer.cpp @@ -29,8 +29,8 @@ // With STOP PRINT printing can be cancelled before SYNCHRONIZE BUFFER was sent. // -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "scsi_printer.h" #include diff --git a/cpp/devices/scsicd.cpp b/cpp/devices/scsicd.cpp index 10b64301..12fa2998 100644 --- a/cpp/devices/scsicd.cpp +++ b/cpp/devices/scsicd.cpp @@ -14,7 +14,7 @@ // //--------------------------------------------------------------------------- -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "scsicd.h" #include diff --git a/cpp/devices/scsihd.cpp b/cpp/devices/scsihd.cpp index c76dfee6..f3a2efe2 100644 --- a/cpp/devices/scsihd.cpp +++ b/cpp/devices/scsihd.cpp @@ -13,8 +13,8 @@ // //--------------------------------------------------------------------------- +#include "shared/rascsi_exceptions.h" #include "scsihd.h" -#include "rascsi_exceptions.h" #include "scsi_command_util.h" using namespace scsi_command_util; diff --git a/cpp/devices/scsihd.h b/cpp/devices/scsihd.h index c2ccd6e7..a3c747be 100644 --- a/cpp/devices/scsihd.h +++ b/cpp/devices/scsihd.h @@ -15,7 +15,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include "disk.h" #include #include diff --git a/cpp/devices/scsihd_nec.cpp b/cpp/devices/scsihd_nec.cpp index 66fadb17..bd002d46 100644 --- a/cpp/devices/scsihd_nec.cpp +++ b/cpp/devices/scsihd_nec.cpp @@ -10,12 +10,10 @@ // Licensed under the BSD 3-Clause License. // See LICENSE file in the project root folder. // -// [ SCSI NEC Compatible Hard Disk] -// //--------------------------------------------------------------------------- -#include "rascsi_exceptions.h" -#include "rasutil.h" +#include "shared/rasutil.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "scsihd_nec.h" #include diff --git a/cpp/devices/scsimo.cpp b/cpp/devices/scsimo.cpp index c660d631..967c076d 100644 --- a/cpp/devices/scsimo.cpp +++ b/cpp/devices/scsimo.cpp @@ -12,7 +12,7 @@ // //--------------------------------------------------------------------------- -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "scsi_command_util.h" #include "scsimo.h" diff --git a/cpp/devices/storage_device.cpp b/cpp/devices/storage_device.cpp index 0714bd9c..aecad900 100644 --- a/cpp/devices/storage_device.cpp +++ b/cpp/devices/storage_device.cpp @@ -7,7 +7,7 @@ // //--------------------------------------------------------------------------- -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "storage_device.h" #include #include diff --git a/cpp/hal/bus.h b/cpp/hal/bus.h index 3a2adfc5..ee7fa54a 100644 --- a/cpp/hal/bus.h +++ b/cpp/hal/bus.h @@ -9,8 +9,8 @@ #pragma once -#include "config.h" -#include "scsi.h" +#include "shared/config.h" +#include "shared/scsi.h" #include #include #include diff --git a/cpp/hal/gpiobus.cpp b/cpp/hal/gpiobus.cpp index f8b41c0d..18c7130c 100644 --- a/cpp/hal/gpiobus.cpp +++ b/cpp/hal/gpiobus.cpp @@ -15,8 +15,8 @@ #include #include "hal/gpiobus.h" #include "hal/systimer.h" -#include "config.h" -#include "log.h" +#include "shared/config.h" +#include "shared/log.h" #include #ifdef __linux__ #include diff --git a/cpp/hal/gpiobus.h b/cpp/hal/gpiobus.h index 56597979..037bc098 100644 --- a/cpp/hal/gpiobus.h +++ b/cpp/hal/gpiobus.h @@ -11,8 +11,8 @@ #pragma once -#include "config.h" -#include "scsi.h" +#include "shared/config.h" +#include "shared/scsi.h" #include "bus.h" #include diff --git a/cpp/hal/systimer.cpp b/cpp/hal/systimer.cpp index 1dd727fa..bdcec4e2 100644 --- a/cpp/hal/systimer.cpp +++ b/cpp/hal/systimer.cpp @@ -13,7 +13,7 @@ #include "hal/systimer.h" #include "hal/gpiobus.h" -#include "config.h" +#include "shared/config.h" #include #include #include diff --git a/cpp/hal/systimer.h b/cpp/hal/systimer.h index 8f4b31d9..7ff5f459 100644 --- a/cpp/hal/systimer.h +++ b/cpp/hal/systimer.h @@ -15,8 +15,8 @@ #include -#include "config.h" -#include "scsi.h" +#include "shared/config.h" +#include "shared/scsi.h" //=========================================================================== // diff --git a/cpp/monitor/data_sample.cpp b/cpp/monitor/data_sample.cpp index 387cd145..370f25fd 100644 --- a/cpp/monitor/data_sample.cpp +++ b/cpp/monitor/data_sample.cpp @@ -9,7 +9,7 @@ // //--------------------------------------------------------------------------- -#include "scsi.h" +#include "shared/scsi.h" #include "data_sample.h" const char *GetPhaseStr(const data_capture *sample) diff --git a/cpp/monitor/data_sample.h b/cpp/monitor/data_sample.h index 4531a98b..81ad2dcf 100644 --- a/cpp/monitor/data_sample.h +++ b/cpp/monitor/data_sample.h @@ -11,7 +11,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include "hal/gpiobus.h" using data_capture_t = struct data_capture diff --git a/cpp/monitor/sm_core.cpp b/cpp/monitor/sm_core.cpp index 5e6a9e82..046063a5 100644 --- a/cpp/monitor/sm_core.cpp +++ b/cpp/monitor/sm_core.cpp @@ -8,21 +8,23 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" +#include "shared/rasutil.h" +#include "shared/rascsi_version.h" #include "hal/gpiobus_factory.h" #include "hal/gpiobus.h" -#include "rascsi_version.h" +#include "monitor/sm_reports.h" +#include "monitor/sm_core.h" +#include "monitor/data_sample.h" #include #include #include #include #include #include -#include "monitor/sm_reports.h" -#include "monitor/sm_core.h" -#include "monitor/data_sample.h" using namespace std; +using namespace ras_util; // TODO Should not be global and not be used by sm_vcd_report double ns_per_loop; @@ -158,30 +160,6 @@ void ScsiMon::Reset() const bus->Reset(); } -//--------------------------------------------------------------------------- -// -// Pin the thread to a specific CPU (Only applies to Linux) -// -//--------------------------------------------------------------------------- -#ifdef __linux__ -void ScsiMon::FixCpu(int cpu) const -{ - // Get the number of CPUs - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); - int cpus = CPU_COUNT(&cpuset); - - // Set the thread affinity - if (cpu < cpus) - { - CPU_ZERO(&cpuset); - CPU_SET(cpu, &cpuset); - sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); - } -} -#endif - #ifdef DEBUG static uint32_t high_bits = 0x0; static uint32_t low_bits = 0xFFFFFFFF; diff --git a/cpp/monitor/sm_core.h b/cpp/monitor/sm_core.h index 4bf0c6a3..4d66353a 100644 --- a/cpp/monitor/sm_core.h +++ b/cpp/monitor/sm_core.h @@ -35,7 +35,6 @@ private: bool Init(); void Cleanup() const; void Reset() const; - void FixCpu(int) const; static void KillHandler(int); diff --git a/cpp/monitor/sm_html_report.cpp b/cpp/monitor/sm_html_report.cpp index 7c12248d..375ad859 100644 --- a/cpp/monitor/sm_html_report.cpp +++ b/cpp/monitor/sm_html_report.cpp @@ -8,11 +8,11 @@ // //--------------------------------------------------------------------------- +#include "shared/log.h" +#include "shared/rascsi_version.h" +#include "sm_reports.h" #include #include -#include "log.h" -#include "sm_reports.h" -#include "rascsi_version.h" using namespace std; diff --git a/cpp/monitor/sm_json_report.cpp b/cpp/monitor/sm_json_report.cpp index 0d7f9283..62ed70c8 100644 --- a/cpp/monitor/sm_json_report.cpp +++ b/cpp/monitor/sm_json_report.cpp @@ -8,11 +8,12 @@ // //--------------------------------------------------------------------------- +#include "shared/log.h" #include "sm_reports.h" -#include "log.h" #include "string.h" #include #include + using namespace std; const char timestamp_label[] = "\"timestamp\":\"0x"; diff --git a/cpp/monitor/sm_vcd_report.cpp b/cpp/monitor/sm_vcd_report.cpp index 68d85da7..95bb7be6 100644 --- a/cpp/monitor/sm_vcd_report.cpp +++ b/cpp/monitor/sm_vcd_report.cpp @@ -9,13 +9,13 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" +#include "hal/gpiobus.h" +#include "data_sample.h" +#include "sm_reports.h" #include #include #include -#include "data_sample.h" -#include "sm_reports.h" -#include "hal/gpiobus.h" using namespace std; diff --git a/cpp/rascsi/command_context.cpp b/cpp/rascsi/command_context.cpp index da64354d..ec76e496 100644 --- a/cpp/rascsi/command_context.cpp +++ b/cpp/rascsi/command_context.cpp @@ -7,8 +7,8 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_interface.pb.h" +#include "shared/log.h" +#include "generated/rascsi_interface.pb.h" #include "command_context.h" #include diff --git a/cpp/rascsi/command_context.h b/cpp/rascsi/command_context.h index 5a0879b5..8b919460 100644 --- a/cpp/rascsi/command_context.h +++ b/cpp/rascsi/command_context.h @@ -9,9 +9,9 @@ #pragma once -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include "localizer.h" -#include "protobuf_serializer.h" +#include "shared/protobuf_serializer.h" #include using namespace std; diff --git a/cpp/rascsi/rascsi_core.cpp b/cpp/rascsi/rascsi_core.cpp index 47465c03..d368840e 100644 --- a/cpp/rascsi/rascsi_core.cpp +++ b/cpp/rascsi/rascsi_core.cpp @@ -6,12 +6,16 @@ // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS // Copyright (C) 2020-2022 Contributors to the RaSCSI project -// [ RaSCSI main ] // //--------------------------------------------------------------------------- -#include "config.h" -#include "log.h" +#include "shared/config.h" +#include "shared/log.h" +#include "shared/rasutil.h" +#include "shared/protobuf_serializer.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_exceptions.h" +#include "shared/rascsi_version.h" #include "controllers/controller_manager.h" #include "controllers/scsi_controller.h" #include "devices/device_factory.h" @@ -19,12 +23,8 @@ #include "hal/gpiobus_factory.h" #include "hal/gpiobus.h" #include "hal/systimer.h" -#include "rascsi_version.h" -#include "protobuf_serializer.h" -#include "protobuf_util.h" #include "rascsi/rascsi_executor.h" #include "rascsi/rascsi_core.h" -#include "rasutil.h" #include "spdlog/sinks/stdout_color_sinks.h" #include #include @@ -33,8 +33,10 @@ #include #include #include +#include using namespace std; +using namespace filesystem; using namespace spdlog; using namespace rascsi_interface; using namespace ras_util; @@ -46,9 +48,9 @@ void Rascsi::Banner(const vector& args) const cout << "Connect type: " << CONNECT_DESC << '\n' << flush; if ((args.size() > 1 && strcmp(args[1], "-h") == 0) || (args.size() > 1 && strcmp(args[1], "--help") == 0)){ - cout << "\nUsage: " << args[0] << " [-idn[:m] FILE] ...\n\n"; - cout << " n is SCSI device ID (0-7).\n"; - cout << " m is the optional logical unit (LUN) (0-31).\n"; + cout << "\nUsage: " << args[0] << " [-idID[:LUN] FILE] ...\n\n"; + cout << " ID is SCSI device ID (0-7).\n"; + cout << " LUN is the optional logical unit (0-31).\n"; cout << " FILE is a disk image file, \"daynaport\", \"bridge\", \"printer\" or \"services\".\n\n"; cout << " Image type is detected based on file extension if no explicit type is specified.\n"; cout << " hd1 : SCSI-1 HD image (Non-removable generic SCSI-1 HD image)\n"; @@ -89,37 +91,36 @@ void Rascsi::Cleanup() bus->Cleanup(); } -bool Rascsi::ReadAccessToken(const char *filename) const +void Rascsi::ReadAccessToken(const string& filename) const { struct stat st; - if (stat(filename, &st) || !S_ISREG(st.st_mode)) { - cerr << "Can't access token file '" << optarg << "'" << endl; - return false; + if (stat(filename.c_str(), &st) || !S_ISREG(st.st_mode)) { + throw parser_exception("Can't access token file '" + filename + "'"); } - if (st.st_uid || st.st_gid || (st.st_mode & (S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP))) { - cerr << "Access token file '" << optarg << "' must be owned by root and readable by root only" << endl; - return false; + if (st.st_uid || st.st_gid) { + throw parser_exception("Access token file '" + filename + "' must be owned by root"); + } + + if (const auto perms = filesystem::status(filename).permissions(); + (perms & perms::group_read) != perms::none || (perms & perms::others_read) != perms::none || + (perms & perms::group_write) != perms::none || (perms & perms::others_write) != perms::none) { + throw parser_exception("Access token file '" + filename + "' must be readable by root only"); } ifstream token_file(filename); if (token_file.fail()) { - cerr << "Can't open access token file '" << optarg << "'" << endl; - return false; + throw parser_exception("Can't open access token file '" + filename + "'"); } getline(token_file, access_token); if (token_file.fail()) { - cerr << "Can't read access token file '" << optarg << "'" << endl; - return false; + throw parser_exception("Can't read access token file '" + filename + "'"); } if (access_token.empty()) { - cerr << "Access token file '" << optarg << "' must not be empty" << endl; - return false; + throw parser_exception("Access token file '" + filename + "' must not be empty"); } - - return true; } void Rascsi::LogDevices(string_view devices) const @@ -139,27 +140,9 @@ void Rascsi::TerminationHandler(int signum) exit(signum); } -bool Rascsi::ProcessId(const string& id_spec, int& id, int& unit) const -{ - if (const size_t separator_pos = id_spec.find(COMPONENT_SEPARATOR); separator_pos == string::npos) { - if (!GetAsInt(id_spec, id) || id < 0 || id >= 8) { - cerr << optarg << ": Invalid device ID (0-7)" << endl; - return false; - } - - unit = 0; - } - else if (!GetAsInt(id_spec.substr(0, separator_pos), id) || id < 0 || id > 7 || - !GetAsInt(id_spec.substr(separator_pos + 1), unit) || unit < 0 || unit >= ScsiController::LUN_MAX) { - cerr << optarg << ": Invalid unit (0-" << (ScsiController::LUN_MAX - 1) << ")" << endl; - return false; - } - - return true; -} - -bool Rascsi::ParseArguments(const vector& args, int& port, optarg_queue_type& post_process) const +Rascsi::optargs_type Rascsi::ParseArguments(const vector& args, int& port) const { + optargs_type optargs; int block_size = 0; string name; @@ -181,14 +164,13 @@ bool Rascsi::ParseArguments(const vector& args, int& port, optarg_queue_ case 'z': { const string optarg_str = optarg == nullptr ? "" : optarg; - post_process.emplace_back(opt, optarg_str); + optargs.emplace_back(opt, optarg_str); continue; } case 'b': { - if (!GetAsInt(optarg, block_size)) { - cerr << "Invalid block size " << optarg << endl; - return false; + if (!GetAsUnsignedInt(optarg, block_size)) { + throw parser_exception("Invalid block size " + string(optarg)); } continue; } @@ -198,16 +180,13 @@ bool Rascsi::ParseArguments(const vector& args, int& port, optarg_queue_ continue; case 'p': - if (!GetAsInt(optarg, port) || port <= 0 || port > 65535) { - cerr << "Invalid port " << optarg << ", port must be between 1 and 65535" << endl; - return false; + if (!GetAsUnsignedInt(optarg, port) || port <= 0 || port > 65535) { + throw parser_exception("Invalid port " + string(optarg) + ", port must be between 1 and 65535"); } continue; case 'P': - if (!ReadAccessToken(optarg)) { - return false; - } + ReadAccessToken(optarg); continue; case 'v': @@ -218,27 +197,27 @@ bool Rascsi::ParseArguments(const vector& args, int& port, optarg_queue_ { // Encountered filename const string optarg_str = (optarg == nullptr) ? "" : string(optarg); - post_process.emplace_back(opt, optarg_str); + optargs.emplace_back(opt, optarg_str); continue; } default: - return false; + throw parser_exception("Parser error"); } if (optopt) { - return false; + throw parser_exception("Praser error"); } } - return true; + return optargs; } -bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const +void Rascsi::CreateInitialDevices(const optargs_type& optargs) const { PbCommand command; int id = -1; - int unit = -1; + int lun = -1; PbDeviceType type = UNDEFINED; int block_size = 0; string name; @@ -249,22 +228,18 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const locale = "en"; } - opterr = 1; - for (const auto& [option, value] : optarg_queue) { + for (const auto& [option, value] : optargs) { switch (option) { - // The two options below are kind of a compound option with two letters case 'i': case 'I': id = -1; - unit = -1; + lun = -1; continue; case 'd': case 'D': { - if (!ProcessId(value, id, unit)) { - return false; - } + ProcessId(value, ScsiController::LUN_MAX, id, lun); continue; } @@ -272,19 +247,16 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const locale = value.c_str(); continue; - case 'F': { - if (const string result = rascsi_image.SetDefaultFolder(value); !result.empty()) { - cerr << result << endl; - return false; + case 'F': + if (const string error = rascsi_image.SetDefaultFolder(value); !error.empty()) { + throw parser_exception(error); } continue; - } case 'R': int depth; - if (!GetAsInt(value, depth) || depth < 0) { - cerr << "Invalid image file scan depth " << value << endl; - return false; + if (!GetAsUnsignedInt(value, depth)) { + throw parser_exception("Invalid image file scan depth " + value); } rascsi_image.SetDepth(depth); continue; @@ -293,12 +265,9 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const name = value; continue; - case 'r': { - string error = executor->SetReservedIds(value); - if (!error.empty()) { - cerr << error << endl; - return false; - } + case 'r': + if (const string error = executor->SetReservedIds(value); !error.empty()) { + throw parser_exception(error); } continue; @@ -306,8 +275,7 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const string t = value; transform(t.begin(), t.end(), t.begin(), ::toupper); if (!PbDeviceType_Parse(t, &type)) { - cerr << "Illegal device type '" << value << "'" << endl; - return false; + throw parser_exception("Illegal device type '" + value + "'"); } } continue; @@ -317,13 +285,13 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const break; default: - return false; + throw parser_exception("Parser error"); } // Set up the device data PbDeviceDefinition *device = command.add_devices(); device->set_id(id); - device->set_unit(unit); + device->set_unit(lun); device->set_type(type); device->set_block_size(block_size); @@ -355,7 +323,7 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const command.set_operation(ATTACH); if (CommandContext context(locale); !executor->ProcessCmd(context, command)) { - return false; + throw parser_exception("Can't execute " + PbOperation_Name(command.operation())); } // Display and log the device list @@ -365,8 +333,6 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const const string device_list = ListDevices(devices); LogDevices(device_list); cout << device_list << flush; - - return true; } bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& command) @@ -526,25 +492,38 @@ int Rascsi::run(const vector& args) const Banner(args); int port = DEFAULT_PORT; - optarg_queue_type optarg_queue; - if (!ParseArguments(args, port, optarg_queue)) { + optargs_type optargs; + try { + optargs = ParseArguments(args, port); + } + catch(const parser_exception& e) { + cerr << "Error: " << e.what() << endl; + return EXIT_FAILURE; } - // Note that current_log_level may have been modified by ParseArguments() + // current_log_level may have been updated by ParseArguments() executor->SetLogLevel(current_log_level); // Create a thread-safe stdout logger to process the log messages const auto logger = stdout_color_mt("rascsi stdout logger"); if (!InitBus()) { + cerr << "Error: Can't initialize bus" << endl; + return EXIT_FAILURE; } - // We need to wait to create the devices until after the bus/controller/etc - // objects have been created. - if (!CreateInitialDevices(optarg_queue)) { + // We need to wait to create the devices until after the bus/controller/etc objects have been created + // TODO Try to resolve dependencies so that this work-around can be removed + try { + CreateInitialDevices(optargs); + } + catch(const parser_exception& e) { + cerr << "Error: " << e.what() << endl; + Cleanup(); + return EXIT_FAILURE; } diff --git a/cpp/rascsi/rascsi_core.h b/cpp/rascsi/rascsi_core.h index 6690ea0b..818a6f9c 100644 --- a/cpp/rascsi/rascsi_core.h +++ b/cpp/rascsi/rascsi_core.h @@ -13,7 +13,7 @@ #include "rascsi/rascsi_service.h" #include "rascsi/rascsi_image.h" #include "rascsi/rascsi_response.h" -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include #include @@ -25,10 +25,9 @@ class RascsiExecutor; class Rascsi { - using optarg_queue_type = vector>; + using optargs_type = vector>; static const int DEFAULT_PORT = 6868; - static const char COMPONENT_SEPARATOR = ':'; public: @@ -42,16 +41,18 @@ private: void Banner(const vector&) const; bool InitBus() const; static void Cleanup(); - bool ReadAccessToken(const char *) const; + void ReadAccessToken(const string&) const; void LogDevices(string_view) const; static void TerminationHandler(int); - bool ProcessId(const string&, int&, int&) const; - bool ParseArguments(const vector&, int&, optarg_queue_type&) const; - bool CreateInitialDevices(const optarg_queue_type&) const; + optargs_type ParseArguments(const vector&, int&) const; + void CreateInitialDevices(const optargs_type&) const; // TODO Should not be static and should be moved to RascsiService static bool ExecuteCommand(const CommandContext&, const PbCommand&); + // A static instance is needed because of the signal handler + static inline shared_ptr bus; + // TODO These fields should not be static static inline RascsiService service; @@ -60,8 +61,6 @@ private: const static inline RascsiResponse rascsi_response; - static inline shared_ptr bus; - static inline shared_ptr controller_manager; static inline shared_ptr executor; diff --git a/cpp/rascsi/rascsi_executor.cpp b/cpp/rascsi/rascsi_executor.cpp index dd8f8ba2..7f5edc33 100644 --- a/cpp/rascsi/rascsi_executor.cpp +++ b/cpp/rascsi/rascsi_executor.cpp @@ -7,7 +7,10 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" +#include "shared/rasutil.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_exceptions.h" #include "controllers/controller_manager.h" #include "controllers/scsi_controller.h" #include "devices/device_factory.h" @@ -15,11 +18,8 @@ #include "devices/disk.h" #include "rascsi_service.h" #include "rascsi_image.h" -#include "rascsi_exceptions.h" #include "localizer.h" -#include "protobuf_util.h" #include "command_context.h" -#include "rasutil.h" #include "rascsi_executor.h" #include @@ -506,7 +506,7 @@ string RascsiExecutor::SetReservedIds(string_view ids) set reserved; for (const string& id_to_reserve : ids_to_reserve) { int res_id; - if (!GetAsInt(id_to_reserve, res_id) || res_id > 7) { + if (!GetAsUnsignedInt(id_to_reserve, res_id) || res_id > 7) { return "Invalid ID " + id_to_reserve; } diff --git a/cpp/rascsi/rascsi_executor.h b/cpp/rascsi/rascsi_executor.h index 942f7f7b..e3c75907 100644 --- a/cpp/rascsi/rascsi_executor.h +++ b/cpp/rascsi/rascsi_executor.h @@ -9,8 +9,8 @@ #pragma once +#include "shared/protobuf_serializer.h" #include "rascsi/rascsi_response.h" -#include "protobuf_serializer.h" class RascsiImage; class DeviceFactory; diff --git a/cpp/rascsi/rascsi_image.cpp b/cpp/rascsi/rascsi_image.cpp index 746056e8..02e21f90 100644 --- a/cpp/rascsi/rascsi_image.cpp +++ b/cpp/rascsi/rascsi_image.cpp @@ -7,9 +7,9 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" +#include "shared/protobuf_util.h" #include "devices/disk.h" -#include "protobuf_util.h" #include "command_context.h" #include "rascsi_image.h" #include diff --git a/cpp/rascsi/rascsi_image.h b/cpp/rascsi/rascsi_image.h index d10bacc4..12f4d4ff 100644 --- a/cpp/rascsi/rascsi_image.h +++ b/cpp/rascsi/rascsi_image.h @@ -9,7 +9,7 @@ #pragma once -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include "command_context.h" #include #include diff --git a/cpp/rascsi/rascsi_response.cpp b/cpp/rascsi/rascsi_response.cpp index 6444994f..9930aa81 100644 --- a/cpp/rascsi/rascsi_response.cpp +++ b/cpp/rascsi/rascsi_response.cpp @@ -7,12 +7,12 @@ // //--------------------------------------------------------------------------- -#include "log.h" +#include "shared/log.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_version.h" #include "devices/disk.h" #include "devices/device_factory.h" -#include "protobuf_util.h" -#include "rascsi_version.h" -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include "rascsi_response.h" #include diff --git a/cpp/rascsi/rascsi_response.h b/cpp/rascsi/rascsi_response.h index d9a188ff..5389627c 100644 --- a/cpp/rascsi/rascsi_response.h +++ b/cpp/rascsi/rascsi_response.h @@ -11,7 +11,7 @@ #include "devices/device_factory.h" #include "devices/primary_device.h" -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include #include #include diff --git a/cpp/rascsi/rascsi_service.cpp b/cpp/rascsi/rascsi_service.cpp index 68a94323..483f8274 100644 --- a/cpp/rascsi/rascsi_service.cpp +++ b/cpp/rascsi/rascsi_service.cpp @@ -7,12 +7,12 @@ // //--------------------------------------------------------------------------- -#include "log.h" -#include "rascsi_exceptions.h" +#include "shared/log.h" +#include "shared/rasutil.h" +#include "shared/protobuf_serializer.h" +#include "shared/rascsi_exceptions.h" #include "command_context.h" -#include "protobuf_serializer.h" #include "localizer.h" -#include "rasutil.h" #include "rascsi_service.h" #include #include diff --git a/cpp/rascsi/rascsi_service.h b/cpp/rascsi/rascsi_service.h index d5ebe819..da092c12 100644 --- a/cpp/rascsi/rascsi_service.h +++ b/cpp/rascsi/rascsi_service.h @@ -9,7 +9,7 @@ #pragma once -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include #include diff --git a/cpp/rasctl/rasctl_commands.cpp b/cpp/rasctl/rasctl_commands.cpp index 0e927304..4968b138 100644 --- a/cpp/rasctl/rasctl_commands.cpp +++ b/cpp/rasctl/rasctl_commands.cpp @@ -7,8 +7,9 @@ // //--------------------------------------------------------------------------- -#include "rascsi_exceptions.h" -#include "protobuf_util.h" +#include "shared/rasutil.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_exceptions.h" #include "rasctl_commands.h" #include #include @@ -17,11 +18,9 @@ using namespace std; using namespace rascsi_interface; +using namespace ras_util; using namespace protobuf_util; -// Separator for the INQUIRY name components -static const char COMPONENT_SEPARATOR = ':'; - bool RasctlCommands::Execute(const string& log_level, const string& default_folder, const string& reserved_ids, const string& image_params, const string& filename) { diff --git a/cpp/rasctl/rasctl_commands.h b/cpp/rasctl/rasctl_commands.h index ec18f36b..6c39b409 100644 --- a/cpp/rasctl/rasctl_commands.h +++ b/cpp/rasctl/rasctl_commands.h @@ -9,8 +9,8 @@ #pragma once -#include "protobuf_serializer.h" -#include "rascsi_interface.pb.h" +#include "shared/protobuf_serializer.h" +#include "generated/rascsi_interface.pb.h" #include "rasctl_display.h" #include diff --git a/cpp/rasctl/rasctl_core.cpp b/cpp/rasctl/rasctl_core.cpp index 5db2e449..ebf5dd9c 100644 --- a/cpp/rasctl/rasctl_core.cpp +++ b/cpp/rasctl/rasctl_core.cpp @@ -10,11 +10,12 @@ // //--------------------------------------------------------------------------- -#include "rascsi_version.h" -#include "protobuf_util.h" -#include "rasutil.h" -#include "rascsi_exceptions.h" -#include "rascsi_interface.pb.h" +#include "controllers/scsi_controller.h" +#include "shared/rasutil.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_exceptions.h" +#include "shared/rascsi_version.h" +#include "generated/rascsi_interface.pb.h" #include "rasctl/rasctl_parser.h" #include "rasctl/rasctl_commands.h" #include "rasctl/rasctl_core.h" @@ -32,13 +33,12 @@ void RasCtl::Banner(const vector& args) const if (args.size() < 2) { cout << ras_util::Banner("Controller"); - cout << "\nUsage: " << args[0] << " -i ID [-u UNIT] [-c CMD] [-C FILE] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] "; + cout << "\nUsage: " << args[0] << " -i ID[:LUN] [-c CMD] [-C FILE] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] "; cout << "[-F IMAGE_FOLDER] [-L LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] "; cout << "[-C FILENAME:FILESIZE] [-d FILENAME] [-w FILENAME] [-R CURRENT_NAME:NEW_NAME] "; cout << "[-x CURRENT_NAME:NEW_NAME] [-z LOCALE] "; cout << "[-e] [-E FILENAME] [-D] [-I] [-l] [-m] [o] [-O] [-P] [-s] [-v] [-V] [-y] [-X]\n"; - cout << " where ID := {0-7}\n"; - cout << " UNIT := {0-31}, default is 0\n"; + cout << " where ID[:LUN] ID := {0-7}, LUN := {0-31}, default is 0\n"; cout << " CMD := {attach|detach|insert|eject|protect|unprotect|show}\n"; cout << " TYPE := {schd|scrm|sccd|scmo|scbr|scdp} or convenience type {hd|rm|mo|cd|bridge|daynaport}\n"; cout << " BLOCK_SIZE := {512|1024|2048|4096) bytes per hard disk drive block\n"; @@ -86,25 +86,20 @@ int RasCtl::run(const vector& args) const opterr = 1; int opt; while ((opt = getopt(static_cast(args.size()), args.data(), - "e::lmos::vDINOTVXa:b:c:d:f:h:i:n:p:r:t:u:x:z:C:E:F:L:P::R:")) != -1) { + "e::lmos::vDINOTVXa:b:c:d:f:h:i:n:p:r:t:x:z:C:E:F:L:P::R:")) != -1) { switch (opt) { case 'i': { int id; - if (!GetAsInt(optarg, id)) { - cerr << "Error: Invalid device ID " << optarg << endl; + int lun; + try { + ProcessId(optarg, ScsiController::LUN_MAX, id, lun); + } + catch(const parser_exception& e) { + cerr << "Error: " << e.what() << endl; exit(EXIT_FAILURE); } device->set_id(id); - break; - } - - case 'u': { - int unit; - if (!GetAsInt(optarg, unit)) { - cerr << "Error: Invalid unit " << optarg << endl; - exit(EXIT_FAILURE); - } - device->set_unit(unit); + device->set_unit(lun); break; } @@ -115,7 +110,7 @@ int RasCtl::run(const vector& args) const case 'b': int block_size; - if (!GetAsInt(optarg, block_size)) { + if (!GetAsUnsignedInt(optarg, block_size)) { cerr << "Error: Invalid block size " << optarg << endl; exit(EXIT_FAILURE); } @@ -240,7 +235,7 @@ int RasCtl::run(const vector& args) const break; case 'p': - if (!GetAsInt(optarg, port) || port <= 0 || port > 65535) { + if (!GetAsUnsignedInt(optarg, port) || port <= 0 || port > 65535) { cerr << "Error: Invalid port " << optarg << ", port must be between 1 and 65535" << endl; exit(EXIT_FAILURE); } diff --git a/cpp/rasctl/rasctl_core.h b/cpp/rasctl/rasctl_core.h index 2251e6f1..70ccfed9 100644 --- a/cpp/rasctl/rasctl_core.h +++ b/cpp/rasctl/rasctl_core.h @@ -15,10 +15,7 @@ using namespace std; class RasCtl { - // Separator for the INQUIRY name components and for compound parameters - static const char COMPONENT_SEPARATOR = ':'; - -public: + public: RasCtl() = default; ~RasCtl() = default; diff --git a/cpp/rasctl/rasctl_display.cpp b/cpp/rasctl/rasctl_display.cpp index 0f7ee855..0b38bdac 100644 --- a/cpp/rasctl/rasctl_display.cpp +++ b/cpp/rasctl/rasctl_display.cpp @@ -7,8 +7,8 @@ // //--------------------------------------------------------------------------- -#include "rascsi_interface.pb.h" -#include "rasutil.h" +#include "shared/protobuf_util.h" +#include "generated/rascsi_interface.pb.h" #include "rasctl_display.h" #include #include @@ -16,7 +16,7 @@ using namespace std; using namespace rascsi_interface; -using namespace ras_util; +using namespace protobuf_util; string RasctlDisplay::DisplayDevicesInfo(const PbDevicesInfo& devices_info) const { diff --git a/cpp/rasctl/rasctl_display.h b/cpp/rasctl/rasctl_display.h index b944f4b1..3df91fc0 100644 --- a/cpp/rasctl/rasctl_display.h +++ b/cpp/rasctl/rasctl_display.h @@ -9,7 +9,7 @@ #pragma once -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include #include diff --git a/cpp/rasctl/rasctl_parser.cpp b/cpp/rasctl/rasctl_parser.cpp index 23fbe4f3..984aedff 100644 --- a/cpp/rasctl/rasctl_parser.cpp +++ b/cpp/rasctl/rasctl_parser.cpp @@ -9,7 +9,6 @@ #include "rasctl_parser.h" - PbOperation RasctlParser::ParseOperation(const string& operation) const { const auto& it = operations.find(tolower(operation[0])); diff --git a/cpp/rasctl/rasctl_parser.h b/cpp/rasctl/rasctl_parser.h index 94048b57..b0420418 100644 --- a/cpp/rasctl/rasctl_parser.h +++ b/cpp/rasctl/rasctl_parser.h @@ -7,7 +7,7 @@ // //--------------------------------------------------------------------------- -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include #include diff --git a/cpp/rasdump/rasdump_core.cpp b/cpp/rasdump/rasdump_core.cpp index 904c25b9..a96f086c 100644 --- a/cpp/rasdump/rasdump_core.cpp +++ b/cpp/rasdump/rasdump_core.cpp @@ -9,17 +9,20 @@ // //--------------------------------------------------------------------------- -// TODO Evaluate CHECK CONDITION +// TODO Evaluate CHECK CONDITION after sending a command +// TODO Send IDENTIFY message in order to support LUNS > 7 -#include "log.h" +#include "shared/log.h" +#include "shared/rasutil.h" +#include "shared/rascsi_exceptions.h" +#include "shared/rascsi_version.h" #include "hal/gpiobus_factory.h" #include "hal/gpiobus.h" #include "hal/systimer.h" -#include "rascsi_version.h" #include "rasdump/rasdump_core.h" -#include "spdlog/sinks/stdout_color_sinks.h" #include #include +#include #include #include #include @@ -28,6 +31,7 @@ using namespace std; using namespace spdlog; using namespace scsi_defs; +using namespace ras_util; void RasDump::CleanUp() { @@ -45,8 +49,7 @@ void RasDump::KillHandler(int) bool RasDump::Banner(const vector& args) const { - cout << "RaSCSI hard disk dump utility version " << rascsi_get_version_string() - << " (" << __DATE__ << ", " << __TIME__ << ")\n" << flush; + cout << ras_util::Banner("RaSCSI hard disk dump/restore utility"); if (args.size() < 2 || string(args[1]) == "-h") { cout << "Usage: " << args[0] << " -t ID[:LUN] [-i BID] -f FILE [-v] [-r] [-s BUFFER_SIZE]\n" @@ -85,11 +88,11 @@ void RasDump::ParseArguments(const vector& args) int buffer_size = DEFAULT_BUFFER_SIZE; opterr = 0; - while ((opt = getopt(static_cast(args.size()), args.data(), "i:f:s:t:u:rv")) != -1) { + while ((opt = getopt(static_cast(args.size()), args.data(), "i:f:s:t:rv")) != -1) { switch (opt) { case 'i': - if (!GetAsInt(optarg, initiator_id) || initiator_id > 7) { - throw rasdump_exception("Invalid RaSCSI board ID " + to_string(initiator_id) + " (0-7)"); + if (!GetAsUnsignedInt(optarg, initiator_id) || initiator_id > 7) { + throw parser_exception("Invalid RaSCSI board ID " + to_string(initiator_id) + " (0-7)"); } break; @@ -98,20 +101,14 @@ void RasDump::ParseArguments(const vector& args) break; case 's': - if (!GetAsInt(optarg, buffer_size) || buffer_size < MINIMUM_BUFFER_SIZE) { - throw rasdump_exception("Buffer size must be at least " + to_string(MINIMUM_BUFFER_SIZE / 1024) + "KiB"); + if (!GetAsUnsignedInt(optarg, buffer_size) || buffer_size < MINIMUM_BUFFER_SIZE) { + throw parser_exception("Buffer size must be at least " + to_string(MINIMUM_BUFFER_SIZE / 1024) + "KiB"); } break; case 't': - ProcessId(optarg, target_id, target_lun); - break; - - case 'u': - if (!GetAsInt(optarg, target_lun) || target_lun > 7) { - throw rasdump_exception("Invalid target LUN " + to_string(target_lun) + " (0-7)"); - } + ProcessId(optarg, 8, target_id, target_lun); break; case 'v': @@ -128,11 +125,11 @@ void RasDump::ParseArguments(const vector& args) } if (target_id == initiator_id) { - throw rasdump_exception("Target ID and RaSCSI board ID must not be identical"); + throw parser_exception("Target ID and RaSCSI board ID must not be identical"); } if (filename.empty()) { - throw rasdump_exception("Missing filename"); + throw parser_exception("Missing filename"); } buffer = vector(buffer_size); @@ -151,29 +148,22 @@ void RasDump::WaitPhase(BUS::phase_t phase) const } } - throw rasdump_exception("Expected " + string(BUS::GetPhaseStrRaw(phase)) + " phase, actual phase is " + throw parser_exception("Expected " + string(BUS::GetPhaseStrRaw(phase)) + " phase, actual phase is " + string(BUS::GetPhaseStrRaw(bus->GetPhase()))); } void RasDump::Selection() const { // Set initiator and target ID - auto data = static_cast(1 << initiator_id); - data |= (1 << target_id); - bus->SetDAT(data); + auto data = static_cast(1 << initiator_id); + data |= static_cast(1 << target_id); + bus->SetDAT(static_cast(data)); bus->SetSEL(true); - //bus->SetATN(true); WaitForBusy(); bus->SetSEL(false); - - // TODO Send IDENTIFY message for LUN selection - //buffer[0] = 0x80 | target_lun; - //MessageOut(); - - //bus->SetATN(false); } void RasDump::Command(scsi_command cmd, vector& cdb) const @@ -184,13 +174,12 @@ void RasDump::Command(scsi_command cmd, vector& cdb) const WaitPhase(BUS::phase_t::command); - // Send command. Success if the transmission result is the same as the number of requests cdb[0] = static_cast(cmd); - cdb[1] |= target_lun << 5; + cdb[1] = static_cast(static_cast(cdb[1]) | static_cast(target_lun << 5)); if (static_cast(cdb.size()) != bus->SendHandShake(cdb.data(), static_cast(cdb.size()), BUS::SEND_NO_DELAY)) { BusFree(); - throw rasdump_exception(command_mapping.find(cmd)->second.second + string(" failed")); + throw parser_exception(command_mapping.find(cmd)->second.second + string(" failed")); } } @@ -199,7 +188,7 @@ void RasDump::DataIn(int length) WaitPhase(BUS::phase_t::datain); if (!bus->ReceiveHandShake(buffer.data(), length)) { - throw rasdump_exception("DATA IN failed"); + throw parser_exception("DATA IN failed"); } } @@ -208,7 +197,7 @@ void RasDump::DataOut(int length) WaitPhase(BUS::phase_t::dataout); if (!bus->SendHandShake(buffer.data(), length, BUS::SEND_NO_DELAY)) { - throw rasdump_exception("DATA OUT failed"); + throw parser_exception("DATA OUT failed"); } } @@ -217,7 +206,7 @@ void RasDump::Status() const WaitPhase(BUS::phase_t::status); if (array buf; bus->ReceiveHandShake(buf.data(), 1) != 1) { - throw rasdump_exception("STATUS failed"); + throw parser_exception("STATUS failed"); } } @@ -226,16 +215,7 @@ void RasDump::MessageIn() const WaitPhase(BUS::phase_t::msgin); if (array buf; bus->ReceiveHandShake(buf.data(), 1) != 1) { - throw rasdump_exception("MESSAGE IN failed"); - } -} - -void RasDump::MessageOut() -{ - WaitPhase(BUS::phase_t::msgout); - - if (!bus->SendHandShake(buffer.data(), 1, BUS::SEND_NO_DELAY)) { - throw rasdump_exception("MESSAGE OUT failed"); + throw parser_exception("MESSAGE IN failed"); } } @@ -390,7 +370,7 @@ void RasDump::WaitForBusy() const // Success if the target is busy if(!bus->GetBSY()) { - throw rasdump_exception("SELECTION failed"); + throw parser_exception("SELECTION failed"); } } @@ -417,7 +397,7 @@ int RasDump::run(const vector& args) return DumpRestore(); } - catch(const rasdump_exception& e) { + catch(const parser_exception& e) { cerr << "Error: " << e.what() << endl; CleanUp(); @@ -432,13 +412,88 @@ int RasDump::run(const vector& args) int RasDump::DumpRestore() { + const auto [capacity, sector_size] = GetDeviceInfo(); + fstream fs; fs.open(filename, (restore ? ios::in : ios::out) | ios::binary); if (fs.fail()) { - throw rasdump_exception("Can't open image file '" + filename + "'"); + throw parser_exception("Can't open image file '" + filename + "'"); } + if (restore) { + cout << "Starting restore\n" << flush; + + // filesystem::file_size cannot be used here because gcc < 10.3.0 cannot handle more than 2 GiB + off_t size; + if (struct stat st; !stat(filename.c_str(), &st)) { + size = st.st_size; + } + else { + throw parser_exception("Can't determine file size"); + } + + cout << "Restore file size: " << size << " bytes\n"; + if (size > (off_t)(sector_size * capacity)) { + cout << "WARNING: File size is larger than disk size\n" << flush; + } else if (size < (off_t)(sector_size * capacity)) { + throw parser_exception("File size is smaller than disk size"); + } + } + else { + cout << "Starting dump\n" << flush; + } + + // Dump by buffer size + auto dsiz = static_cast(buffer.size()); + const int duni = dsiz / sector_size; + auto dnum = static_cast((capacity * sector_size) / dsiz); + + int i; + for (i = 0; i < dnum; i++) { + if (restore) { + fs.read((char *)buffer.data(), dsiz); + Write10(i * duni, duni, dsiz); + } + else { + Read10(i * duni, duni, dsiz); + fs.write((const char *)buffer.data(), dsiz); + } + + if (fs.fail()) { + throw parser_exception("File I/O failed"); + } + + cout << ((i + 1) * 100 / dnum) << "%" << " (" << ( i + 1) * duni << "/" << capacity << ")\n" << flush; + } + + // Rounding on capacity + dnum = capacity % duni; + dsiz = dnum * sector_size; + if (dnum > 0) { + if (restore) { + fs.read((char *)buffer.data(), dsiz); + if (!fs.fail()) { + Write10(i * duni, dnum, dsiz); + } + } + else { + Read10(i * duni, dnum, dsiz); + fs.write((const char *)buffer.data(), dsiz); + } + + if (fs.fail()) { + throw parser_exception("File I/O failed"); + } + + cout << "100% (" << capacity << "/" << capacity << ")\n" << flush; + } + + return EXIT_SUCCESS; +} + +pair RasDump::GetDeviceInfo() +{ // Assert RST for 1 ms bus->SetRST(true); const timespec ts = { .tv_sec = 0, .tv_nsec = 1000 * 1000}; @@ -463,7 +518,7 @@ int RasDump::DumpRestore() if (auto type = static_cast(buffer[0]); type != device_type::DIRECT_ACCESS && type != device_type::CD_ROM && type != device_type::OPTICAL_MEMORY) { - throw rasdump_exception("Invalid device type, supported types are DIRECT ACCESS, CD-ROM and OPTICAL MEMORY"); + throw parser_exception("Invalid device type, supported types are DIRECT ACCESS, CD-ROM and OPTICAL MEMORY"); } TestUnitReady(); @@ -477,108 +532,5 @@ int RasDump::DumpRestore() << "Capacity: " << sector_size * capacity / 1024 / 1024 << " MiB (" << sector_size * capacity << " bytes)\n\n" << flush; - if (restore) { - cout << "Starting restore\n" << flush; - - // filesystem::file_size cannot be used here because gcc < 10.3.0 cannot handle more than 2 GiB - off_t size; - if (struct stat st; !stat(filename.c_str(), &st)) { - size = st.st_size; - } - else { - throw rasdump_exception("Can't determine file size"); - } - - cout << "Restore file size: " << size << " bytes\n"; - if (size > (off_t)(sector_size * capacity)) { - cout << "WARNING: File size is larger than disk size\n" << flush; - } else if (size < (off_t)(sector_size * capacity)) { - throw rasdump_exception("File size is smaller than disk size"); - } - } - else { - cout << "Starting dump\n" << flush; - } - - // Dump by buffer size - auto dsiz = static_cast(buffer.size()); - const int duni = dsiz / sector_size; - int dnum = static_cast((capacity * sector_size) / dsiz); - - int i; - for (i = 0; i < dnum; i++) { - if (restore) { - fs.read((char *)buffer.data(), dsiz); - Write10(i * duni, duni, dsiz); - } - else { - Read10(i * duni, duni, dsiz); - fs.write((const char *)buffer.data(), dsiz); - } - - if (fs.fail()) { - throw rasdump_exception("File I/O failed"); - } - - cout << ((i + 1) * 100 / dnum) << "%" << " (" << ( i + 1) * duni << "/" << capacity << ")\n" << flush; - } - - // Rounding on capacity - dnum = capacity % duni; - dsiz = dnum * sector_size; - if (dnum > 0) { - if (restore) { - fs.read((char *)buffer.data(), dsiz); - if (!fs.fail()) { - Write10(i * duni, dnum, dsiz); - } - } - else { - Read10(i * duni, dnum, dsiz); - fs.write((const char *)buffer.data(), dsiz); - } - - if (fs.fail()) { - throw rasdump_exception("File I/O failed"); - } - - cout << "100% (" << capacity << "/" << capacity << ")\n" << flush; - } - - return EXIT_SUCCESS; -} - -void RasDump::ProcessId(const string& id_spec, int& id, int& lun) -{ - if (const size_t separator_pos = id_spec.find(COMPONENT_SEPARATOR); separator_pos == string::npos) { - if (!GetAsInt(id_spec, id) || id >= 8) { - throw rasdump_exception("Invalid device ID (0-7)"); - } - - lun = 0; - } - else if (!GetAsInt(id_spec.substr(0, separator_pos), id) || id < 0 || id > 7 || - !GetAsInt(id_spec.substr(separator_pos + 1), lun) || lun >= 32) { - throw rasdump_exception("Invalid unit (0-7)"); - } -} - -bool RasDump::GetAsInt(const string& value, int& result) -{ - if (value.find_first_not_of("0123456789") != string::npos) { - return false; - } - - try { - auto v = stoul(value); - result = (int)v; - } - catch(const invalid_argument&) { - return false; - } - catch(const out_of_range&) { - return false; - } - - return true; + return make_pair(capacity, sector_size); } diff --git a/cpp/rasdump/rasdump_core.h b/cpp/rasdump/rasdump_core.h index 4a66ccec..b0eab3fd 100644 --- a/cpp/rasdump/rasdump_core.h +++ b/cpp/rasdump/rasdump_core.h @@ -9,7 +9,7 @@ #pragma once -#include "scsi.h" +#include "shared/scsi.h" #include "hal/bus.h" #include #include @@ -18,15 +18,8 @@ using namespace std; -class rasdump_exception : public runtime_error -{ - using runtime_error::runtime_error; -}; - class RasDump { - static const char COMPONENT_SEPARATOR = ':'; - static const int MINIMUM_BUFFER_SIZE = 1024 * 64; static const int DEFAULT_BUFFER_SIZE = 1024 * 1024; @@ -43,6 +36,7 @@ private: bool Init() const; void ParseArguments(const vector&); int DumpRestore(); + pair GetDeviceInfo(); void WaitPhase(BUS::phase_t) const; void Selection() const; void Command(scsi_defs::scsi_command, vector&) const; @@ -50,7 +44,6 @@ private: void DataOut(int); void Status() const; void MessageIn() const; - void MessageOut(); void BusFree() const; void TestUnitReady() const; void RequestSense(); @@ -60,11 +53,6 @@ private: void Write10(uint32_t, uint32_t, uint32_t); void WaitForBusy() const; - // TODO Use ras_util after removing its dependencies on protobuf interface. - // Not required in case rasdump is integrated into rascsi. - static void ProcessId(const string&, int&, int&); - static bool GetAsInt(const string&, int&); - static void CleanUp(); static void KillHandler(int); diff --git a/cpp/config.h b/cpp/shared/config.h similarity index 96% rename from cpp/config.h rename to cpp/shared/config.h index c25566ec..a1586aec 100644 --- a/cpp/config.h +++ b/cpp/shared/config.h @@ -6,8 +6,6 @@ // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS // -// [ Common Definitions ] -// //--------------------------------------------------------------------------- #pragma once diff --git a/cpp/log.h b/cpp/shared/log.h similarity index 100% rename from cpp/log.h rename to cpp/shared/log.h diff --git a/cpp/protobuf_serializer.cpp b/cpp/shared/protobuf_serializer.cpp similarity index 94% rename from cpp/protobuf_serializer.cpp rename to cpp/shared/protobuf_serializer.cpp index f9167cd7..1dd1bb20 100644 --- a/cpp/protobuf_serializer.cpp +++ b/cpp/shared/protobuf_serializer.cpp @@ -7,9 +7,9 @@ // //--------------------------------------------------------------------------- -#include "rascsi_interface.pb.h" -#include "protobuf_serializer.h" -#include "rascsi_exceptions.h" +#include "shared/protobuf_serializer.h" +#include "shared/rascsi_exceptions.h" +#include "generated/rascsi_interface.pb.h" #include using namespace std; diff --git a/cpp/protobuf_serializer.h b/cpp/shared/protobuf_serializer.h similarity index 100% rename from cpp/protobuf_serializer.h rename to cpp/shared/protobuf_serializer.h diff --git a/cpp/protobuf_util.cpp b/cpp/shared/protobuf_util.cpp similarity index 65% rename from cpp/protobuf_util.cpp rename to cpp/shared/protobuf_util.cpp index aa8024bb..e9513865 100644 --- a/cpp/protobuf_util.cpp +++ b/cpp/shared/protobuf_util.cpp @@ -8,19 +8,17 @@ //--------------------------------------------------------------------------- #include "log.h" -#include "rascsi_interface.pb.h" +#include "rasutil.h" #include "protobuf_serializer.h" #include "protobuf_util.h" #include using namespace std; +using namespace ras_util; using namespace rascsi_interface; #define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ ) -static const char COMPONENT_SEPARATOR = ':'; -static const char KEY_VALUE_SEPARATOR = '='; - void protobuf_util::ParseParameters(PbDeviceDefinition& device, const string& params) { if (params.empty()) { @@ -97,3 +95,52 @@ void protobuf_util::SetPatternParams(PbCommand& command, string_view patterns) SetParam(command, "folder_pattern", folder_pattern); SetParam(command, "file_pattern", file_pattern); } + +string protobuf_util::ListDevices(const list& pb_devices) +{ + if (pb_devices.empty()) { + return "No devices currently attached.\n"; + } + + ostringstream s; + s << "+----+-----+------+-------------------------------------\n" + << "| ID | LUN | TYPE | IMAGE FILE\n" + << "+----+-----+------+-------------------------------------\n"; + + list devices = pb_devices; + devices.sort([](const auto& a, const auto& b) { return a.id() < b.id() || a.unit() < b.unit(); }); + + for (const auto& device : devices) { + string filename; + switch (device.type()) { + case SCBR: + filename = "X68000 HOST BRIDGE"; + break; + + case SCDP: + filename = "DaynaPort SCSI/Link"; + break; + + case SCHS: + filename = "Host Services"; + break; + + case SCLP: + filename = "SCSI Printer"; + break; + + default: + filename = device.file().name(); + break; + } + + s << "| " << device.id() << " | " << device.unit() << " | " << PbDeviceType_Name(device.type()) << " | " + << (filename.empty() ? "NO MEDIUM" : filename) + << (!device.status().removed() && (device.properties().read_only() || device.status().protected_()) ? " (READ-ONLY)" : "") + << '\n'; + } + + s << "+----+-----+------+-------------------------------------\n"; + + return s.str(); +} diff --git a/cpp/protobuf_util.h b/cpp/shared/protobuf_util.h similarity index 85% rename from cpp/protobuf_util.h rename to cpp/shared/protobuf_util.h index 04cd79ff..9e8fb8eb 100644 --- a/cpp/protobuf_util.h +++ b/cpp/shared/protobuf_util.h @@ -12,14 +12,17 @@ #pragma once #include "google/protobuf/message.h" -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include +#include using namespace std; using namespace rascsi_interface; namespace protobuf_util { + static const char KEY_VALUE_SEPARATOR = '='; + void ParseParameters(PbDeviceDefinition&, const string&); string GetParam(const PbCommand&, const string&); string GetParam(const PbDeviceDefinition&, const string&); @@ -27,4 +30,5 @@ namespace protobuf_util void SetParam(PbDevice&, const string&, string_view); void SetParam(PbDeviceDefinition&, const string&, string_view); void SetPatternParams(PbCommand&, string_view); + string ListDevices(const list&); } diff --git a/cpp/rascsi_exceptions.h b/cpp/shared/rascsi_exceptions.h similarity index 91% rename from cpp/rascsi_exceptions.h rename to cpp/shared/rascsi_exceptions.h index 519419ca..e39e1f6d 100644 --- a/cpp/rascsi_exceptions.h +++ b/cpp/shared/rascsi_exceptions.h @@ -14,6 +14,11 @@ using namespace std; +class parser_exception : public runtime_error +{ + using runtime_error::runtime_error; +}; + class io_exception : public runtime_error { using runtime_error::runtime_error; diff --git a/cpp/rascsi_version.cpp b/cpp/shared/rascsi_version.cpp similarity index 100% rename from cpp/rascsi_version.cpp rename to cpp/shared/rascsi_version.cpp diff --git a/cpp/rascsi_version.h b/cpp/shared/rascsi_version.h similarity index 100% rename from cpp/rascsi_version.h rename to cpp/shared/rascsi_version.h diff --git a/cpp/rasutil.cpp b/cpp/shared/rasutil.cpp similarity index 52% rename from cpp/rasutil.cpp rename to cpp/shared/rasutil.cpp index 1c07e835..57e51e31 100644 --- a/cpp/rasutil.cpp +++ b/cpp/shared/rasutil.cpp @@ -3,18 +3,19 @@ // SCSI Target Emulator RaSCSI Reloaded // for Raspberry Pi // -// Copyright (C) 2021-22 Uwe Seimet +// Copyright (C) 2021-2022 Uwe Seimet // //--------------------------------------------------------------------------- +#include "rascsi_exceptions.h" #include "rascsi_version.h" #include "rasutil.h" #include +#include using namespace std; -using namespace rascsi_interface; -bool ras_util::GetAsInt(const string& value, int& result) +bool ras_util::GetAsUnsignedInt(const string& value, int& result) { if (value.find_first_not_of("0123456789") != string::npos) { return false; @@ -34,6 +35,20 @@ bool ras_util::GetAsInt(const string& value, int& result) return true; } +void ras_util::ProcessId(const string& id_spec, int max_luns, int& id, int& lun) +{ + if (const size_t separator_pos = id_spec.find(COMPONENT_SEPARATOR); separator_pos == string::npos) { + if (!GetAsUnsignedInt(id_spec, id) || id >= 8) { + throw parser_exception("Invalid device ID (0-7)"); + } + + lun = 0; + } + else if (!GetAsUnsignedInt(id_spec.substr(0, separator_pos), id) || id > 7 || + !GetAsUnsignedInt(id_spec.substr(separator_pos + 1), lun) || lun >= max_luns) { + throw parser_exception("Invalid LUN (0-" + to_string(max_luns - 1) + ")"); + } +} string ras_util::Banner(const string& app) { @@ -48,62 +63,13 @@ string ras_util::Banner(const string& app) return s.str(); } -string ras_util::ListDevices(const list& pb_devices) -{ - if (pb_devices.empty()) { - return "No devices currently attached.\n"; - } - - ostringstream s; - s << "+----+-----+------+-------------------------------------\n" - << "| ID | LUN | TYPE | IMAGE FILE\n" - << "+----+-----+------+-------------------------------------\n"; - - list devices = pb_devices; - devices.sort([](const auto& a, const auto& b) { return a.id() < b.id() || a.unit() < b.unit(); }); - - for (const auto& device : devices) { - string filename; - switch (device.type()) { - case SCBR: - filename = "X68000 HOST BRIDGE"; - break; - - case SCDP: - filename = "DaynaPort SCSI/Link"; - break; - - case SCHS: - filename = "Host Services"; - break; - - case SCLP: - filename = "SCSI Printer"; - break; - - default: - filename = device.file().name(); - break; - } - - s << "| " << device.id() << " | " << device.unit() << " | " << PbDeviceType_Name(device.type()) << " | " - << (filename.empty() ? "NO MEDIUM" : filename) - << (!device.status().removed() && (device.properties().read_only() || device.status().protected_()) ? " (READ-ONLY)" : "") - << '\n'; - } - - s << "+----+-----+------+-------------------------------------\n"; - - return s.str(); -} - string ras_util::GetExtensionLowerCase(const string& filename) { string ext; if (const size_t separator = filename.rfind('.'); separator != string::npos) { ext = filename.substr(separator + 1); } - std::transform(ext.begin(), ext.end(), ext.begin(), [](unsigned char c){ return std::tolower(c); }); + transform(ext.begin(), ext.end(), ext.begin(), [](unsigned char c){ return std::tolower(c); }); return ext; } diff --git a/cpp/rasutil.h b/cpp/shared/rasutil.h similarity index 63% rename from cpp/rasutil.h rename to cpp/shared/rasutil.h index 9bf69c9e..afb94258 100644 --- a/cpp/rasutil.h +++ b/cpp/shared/rasutil.h @@ -3,25 +3,24 @@ // SCSI Target Emulator RaSCSI Reloaded // for Raspberry Pi // -// Copyright (C) 2021 Uwe Seimet -// -// Helper methods used by rascsi and rasctl +// Copyright (C) 2021-2022 Uwe Seimet // //--------------------------------------------------------------------------- #pragma once -#include #include -#include "rascsi_interface.pb.h" using namespace std; namespace ras_util { - bool GetAsInt(const string&, int&); + // Separator for compound options like ID:LUN + static const char COMPONENT_SEPARATOR = ':'; + + bool GetAsUnsignedInt(const string&, int&); + void ProcessId(const string&, int, int&, int&); string Banner(const string&); - string ListDevices(const list&); string GetExtensionLowerCase(const string&); diff --git a/cpp/scsi.h b/cpp/shared/scsi.h similarity index 100% rename from cpp/scsi.h rename to cpp/shared/scsi.h diff --git a/cpp/test/abstract_controller_test.cpp b/cpp/test/abstract_controller_test.cpp index 963df7b9..302d197c 100644 --- a/cpp/test/abstract_controller_test.cpp +++ b/cpp/test/abstract_controller_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "controllers/abstract_controller.h" using namespace scsi_defs; diff --git a/cpp/test/device_factory_test.cpp b/cpp/test/device_factory_test.cpp index c63bfba4..c3ef0492 100644 --- a/cpp/test/device_factory_test.cpp +++ b/cpp/test/device_factory_test.cpp @@ -8,8 +8,8 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" -#include "rascsi_version.h" +#include "shared/rascsi_exceptions.h" +#include "shared/rascsi_version.h" #include "controllers/controller_manager.h" #include "devices/device.h" #include "devices/device_factory.h" diff --git a/cpp/test/device_test.cpp b/cpp/test/device_test.cpp index 5bb121dd..f8363dff 100644 --- a/cpp/test/device_test.cpp +++ b/cpp/test/device_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "devices/device.h" TEST(DeviceTest, Properties) diff --git a/cpp/test/disk_test.cpp b/cpp/test/disk_test.cpp index f741e1b8..6ccb9939 100644 --- a/cpp/test/disk_test.cpp +++ b/cpp/test/disk_test.cpp @@ -8,10 +8,10 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "scsi.h" +#include "shared/scsi.h" +#include "shared/rascsi_exceptions.h" #include "devices/disk.h" #include "devices/scsi_command_util.h" -#include "rascsi_exceptions.h" using namespace scsi_defs; using namespace scsi_command_util; diff --git a/cpp/test/host_services_test.cpp b/cpp/test/host_services_test.cpp index 78d2e50b..eb4a6f40 100644 --- a/cpp/test/host_services_test.cpp +++ b/cpp/test/host_services_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "controllers/controller_manager.h" #include "devices/host_services.h" diff --git a/cpp/test/mode_page_device_test.cpp b/cpp/test/mode_page_device_test.cpp index bbccb790..a919f0dc 100644 --- a/cpp/test/mode_page_device_test.cpp +++ b/cpp/test/mode_page_device_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "devices/mode_page_device.h" using namespace std; diff --git a/cpp/test/primary_device_test.cpp b/cpp/test/primary_device_test.cpp index c32ad813..402dd04b 100644 --- a/cpp/test/primary_device_test.cpp +++ b/cpp/test/primary_device_test.cpp @@ -8,8 +8,8 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "scsi.h" -#include "rascsi_exceptions.h" +#include "shared/scsi.h" +#include "shared/rascsi_exceptions.h" #include "devices/primary_device.h" #include "devices/device_factory.h" #include "devices/scsi_command_util.h" diff --git a/cpp/test/protobuf_serializer_test.cpp b/cpp/test/protobuf_serializer_test.cpp index c5727239..1c23435a 100644 --- a/cpp/test/protobuf_serializer_test.cpp +++ b/cpp/test/protobuf_serializer_test.cpp @@ -8,9 +8,9 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" -#include "rascsi_interface.pb.h" -#include "protobuf_serializer.h" +#include "shared/protobuf_serializer.h" +#include "shared/rascsi_exceptions.h" +#include "generated/rascsi_interface.pb.h" #include using namespace filesystem; diff --git a/cpp/test/protobuf_util_test.cpp b/cpp/test/protobuf_util_test.cpp index d72cdd3b..d1a4359d 100644 --- a/cpp/test/protobuf_util_test.cpp +++ b/cpp/test/protobuf_util_test.cpp @@ -8,8 +8,8 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_interface.pb.h" -#include "protobuf_util.h" +#include "shared/protobuf_util.h" +#include "generated/rascsi_interface.pb.h" using namespace rascsi_interface; using namespace protobuf_util; @@ -81,3 +81,28 @@ TEST(ProtobufUtil, SetPatternParams) EXPECT_EQ("folder", GetParam(command4, "folder_pattern")); EXPECT_EQ("file", GetParam(command4, "file_pattern")); } + +TEST(ProtobufUtil, ListDevices) +{ + list devices; + + EXPECT_FALSE(ListDevices(devices).empty()); + + PbDevice device; + device.set_type(SCHD); + devices.push_back(device); + device.set_type(SCBR); + devices.push_back(device); + device.set_type(SCDP); + devices.push_back(device); + device.set_type(SCHS); + devices.push_back(device); + device.set_type(SCLP); + devices.push_back(device); + const string device_list = ListDevices(devices); + EXPECT_FALSE(device_list.empty()); + EXPECT_NE(string::npos, device_list.find("X68000 HOST BRIDGE")); + EXPECT_NE(string::npos, device_list.find("DaynaPort SCSI/Link")); + EXPECT_NE(string::npos, device_list.find("Host Services")); + EXPECT_NE(string::npos, device_list.find("SCSI Printer")); +} diff --git a/cpp/test/rascsi_exceptions_test.cpp b/cpp/test/rascsi_exceptions_test.cpp index 9b5d1f91..7f9a7eb4 100644 --- a/cpp/test/rascsi_exceptions_test.cpp +++ b/cpp/test/rascsi_exceptions_test.cpp @@ -9,7 +9,7 @@ #include -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" using namespace scsi_defs; diff --git a/cpp/test/rascsi_executor_test.cpp b/cpp/test/rascsi_executor_test.cpp index f16e05ee..22b2b0a9 100644 --- a/cpp/test/rascsi_executor_test.cpp +++ b/cpp/test/rascsi_executor_test.cpp @@ -9,11 +9,11 @@ #include "spdlog/spdlog.h" #include "mocks.h" -#include "rascsi_exceptions.h" -#include "protobuf_util.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_exceptions.h" #include "controllers/controller_manager.h" #include "devices/device_factory.h" -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include "rascsi/command_context.h" #include "rascsi/rascsi_response.h" #include "rascsi/rascsi_image.h" diff --git a/cpp/test/rascsi_image_test.cpp b/cpp/test/rascsi_image_test.cpp index 643abce2..f43c8ea3 100644 --- a/cpp/test/rascsi_image_test.cpp +++ b/cpp/test/rascsi_image_test.cpp @@ -8,8 +8,8 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "protobuf_util.h" -#include "rascsi_interface.pb.h" +#include "shared/protobuf_util.h" +#include "generated/rascsi_interface.pb.h" #include "rascsi/rascsi_image.h" using namespace rascsi_interface; diff --git a/cpp/test/rascsi_response_test.cpp b/cpp/test/rascsi_response_test.cpp index f773571f..c3669eec 100644 --- a/cpp/test/rascsi_response_test.cpp +++ b/cpp/test/rascsi_response_test.cpp @@ -8,10 +8,10 @@ //--------------------------------------------------------------------------- #include "mocks.h" +#include "shared/rascsi_version.h" #include "controllers/controller_manager.h" #include "devices/device_factory.h" -#include "rascsi_version.h" -#include "rascsi_interface.pb.h" +#include "generated/rascsi_interface.pb.h" #include "rascsi/rascsi_response.h" using namespace rascsi_interface; diff --git a/cpp/test/rasctl_commands_test.cpp b/cpp/test/rasctl_commands_test.cpp index 43aef037..70c405e4 100644 --- a/cpp/test/rasctl_commands_test.cpp +++ b/cpp/test/rasctl_commands_test.cpp @@ -11,9 +11,9 @@ #include -#include "protobuf_util.h" -#include "rascsi_exceptions.h" -#include "rascsi_interface.pb.h" +#include "shared/protobuf_util.h" +#include "shared/rascsi_exceptions.h" +#include "generated/rascsi_interface.pb.h" #include "rasctl/rasctl_commands.h" using namespace testing; diff --git a/cpp/test/rasutil_test.cpp b/cpp/test/rasutil_test.cpp index a038fbb9..211704a8 100644 --- a/cpp/test/rasutil_test.cpp +++ b/cpp/test/rasutil_test.cpp @@ -9,8 +9,8 @@ #include -#include "rascsi_interface.pb.h" -#include "rasutil.h" +#include "shared/rasutil.h" +#include "generated/rascsi_interface.pb.h" #ifdef __linux__ #include #endif @@ -19,17 +19,17 @@ using namespace std; using namespace rascsi_interface; using namespace ras_util; -TEST(RasUtilTest, GetAsInt) +TEST(RasUtilTest, GetAsUnsignedInt) { int result; - EXPECT_FALSE(GetAsInt("", result)); - EXPECT_FALSE(GetAsInt("xyz", result)); - EXPECT_FALSE(GetAsInt("-1", result)); - EXPECT_FALSE(GetAsInt("1234567898765432112345678987654321", result)) << "Value is out of range"; - EXPECT_TRUE(GetAsInt("0", result)); + EXPECT_FALSE(GetAsUnsignedInt("", result)); + EXPECT_FALSE(GetAsUnsignedInt("xyz", result)); + EXPECT_FALSE(GetAsUnsignedInt("-1", result)); + EXPECT_FALSE(GetAsUnsignedInt("1234567898765432112345678987654321", result)) << "Value is out of range"; + EXPECT_TRUE(GetAsUnsignedInt("0", result)); EXPECT_EQ(0, result); - EXPECT_TRUE(GetAsInt("1234", result)); + EXPECT_TRUE(GetAsUnsignedInt("1234", result)); EXPECT_EQ(1234, result); } @@ -38,31 +38,6 @@ TEST(RasUtilTest, Banner) EXPECT_FALSE(Banner("Test").empty()); } -TEST(RasUtilTest, ListDevices) -{ - list devices; - - EXPECT_FALSE(ListDevices(devices).empty()); - - PbDevice device; - device.set_type(SCHD); - devices.push_back(device); - device.set_type(SCBR); - devices.push_back(device); - device.set_type(SCDP); - devices.push_back(device); - device.set_type(SCHS); - devices.push_back(device); - device.set_type(SCLP); - devices.push_back(device); - const string device_list = ListDevices(devices); - EXPECT_FALSE(device_list.empty()); - EXPECT_NE(string::npos, device_list.find("X68000 HOST BRIDGE")); - EXPECT_NE(string::npos, device_list.find("DaynaPort SCSI/Link")); - EXPECT_NE(string::npos, device_list.find("Host Services")); - EXPECT_NE(string::npos, device_list.find("SCSI Printer")); -} - TEST(RasUtilTest, GetExtensionLowerCase) { EXPECT_EQ("", GetExtensionLowerCase("")); diff --git a/cpp/test/scsi_command_util_test.cpp b/cpp/test/scsi_command_util_test.cpp index d198413b..cd18c9ad 100644 --- a/cpp/test/scsi_command_util_test.cpp +++ b/cpp/test/scsi_command_util_test.cpp @@ -8,8 +8,8 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "scsi.h" -#include "rascsi_exceptions.h" +#include "shared/scsi.h" +#include "shared/rascsi_exceptions.h" #include "devices/scsi_command_util.h" using namespace scsi_command_util; diff --git a/cpp/test/scsi_controller_test.cpp b/cpp/test/scsi_controller_test.cpp index 2fa611c8..13807165 100644 --- a/cpp/test/scsi_controller_test.cpp +++ b/cpp/test/scsi_controller_test.cpp @@ -8,8 +8,8 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "scsi.h" -#include "rascsi_exceptions.h" +#include "shared/scsi.h" +#include "shared/rascsi_exceptions.h" #include "controllers/scsi_controller.h" using namespace scsi_defs; diff --git a/cpp/test/scsi_daynaport_test.cpp b/cpp/test/scsi_daynaport_test.cpp index d9352554..38ec50e1 100644 --- a/cpp/test/scsi_daynaport_test.cpp +++ b/cpp/test/scsi_daynaport_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "devices/scsi_daynaport.h" TEST(ScsiDaynaportTest, Inquiry) diff --git a/cpp/test/scsi_printer_test.cpp b/cpp/test/scsi_printer_test.cpp index 76430502..83d7321a 100644 --- a/cpp/test/scsi_printer_test.cpp +++ b/cpp/test/scsi_printer_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "controllers/controller_manager.h" #include "devices/scsi_printer.h" diff --git a/cpp/test/scsicd_test.cpp b/cpp/test/scsicd_test.cpp index bb03e1c6..29bda9b0 100644 --- a/cpp/test/scsicd_test.cpp +++ b/cpp/test/scsicd_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include #include diff --git a/cpp/test/scsihd_nec_test.cpp b/cpp/test/scsihd_nec_test.cpp index 3e8a871e..903436db 100644 --- a/cpp/test/scsihd_nec_test.cpp +++ b/cpp/test/scsihd_nec_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "controllers/controller_manager.h" #include "devices/scsihd_nec.h" #include diff --git a/cpp/test/scsihd_test.cpp b/cpp/test/scsihd_test.cpp index 4d9d6cd9..57945ee5 100644 --- a/cpp/test/scsihd_test.cpp +++ b/cpp/test/scsihd_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "devices/scsihd.h" void ScsiHdTest_SetUpModePages(map>& pages) diff --git a/cpp/test/storage_device_test.cpp b/cpp/test/storage_device_test.cpp index d9e4f9b3..c632134e 100644 --- a/cpp/test/storage_device_test.cpp +++ b/cpp/test/storage_device_test.cpp @@ -8,7 +8,7 @@ //--------------------------------------------------------------------------- #include "mocks.h" -#include "rascsi_exceptions.h" +#include "shared/rascsi_exceptions.h" #include "devices/storage_device.h" #include diff --git a/cpp/test/test_shared.cpp b/cpp/test/test_shared.cpp index 9dc80ae1..4b474cc4 100644 --- a/cpp/test/test_shared.cpp +++ b/cpp/test/test_shared.cpp @@ -8,9 +8,9 @@ //--------------------------------------------------------------------------- #include "mocks.h" +#include "shared/rascsi_exceptions.h" +#include "shared/rascsi_version.h" #include "controllers/controller_manager.h" -#include "rascsi_exceptions.h" -#include "rascsi_version.h" #include "test_shared.h" #include #include diff --git a/cpp/test/test_shared.h b/cpp/test/test_shared.h index e38212f7..365ec760 100644 --- a/cpp/test/test_shared.h +++ b/cpp/test/test_shared.h @@ -9,8 +9,8 @@ #pragma once -#include "scsi.h" -#include "rascsi_interface.pb.h" +#include "shared/scsi.h" +#include "generated/rascsi_interface.pb.h" #include #include #include diff --git a/doc/rasctl.1 b/doc/rasctl.1 index a75f232d..35fa8676 100644 --- a/doc/rasctl.1 +++ b/doc/rasctl.1 @@ -25,12 +25,11 @@ rasctl \- Sends management commands to the rascsi process [\fB\-f\fR \fIFILE|PARAM\fR] [\fB\-g\fR \fILOG_LEVEL\fR] [\fB\-h\fR \fIHOST\fR] -[\fB\-i\fR \fIID\fR +[\fB\-i\fR \fIID[:LUN]\fR [\fB\-n\fR \fINAME\fR] [\fB\-p\fR \fIPORT\fR] [\fB\-r\fR \fIRESERVED_IDS\fR] [\fB\-t\fR \fITYPE\fR] -[\fB\-u\fR \fIUNIT\fR] [\fB\-x\fR \fICURRENT_NAME:NEW_NAME\fR] [\fB\-z\fR \fILOCALE\fR] .SH DESCRIPTION @@ -120,8 +119,8 @@ Copy an image file in the default image folder. .BR \-z\fI " "\fILOCALE Overrides the default locale for client-facing error messages. .TP -.BR \-i\fI " " \fIID -ID is the SCSI ID that you want to control. (0-7) +.BR \-i\fI " " \fIID[:LUN] +The SCSI ID and optional LUN that you want to control. (0-7:0-31) .TP .BR \-c\fI " " \fICMD Command is the operation being requested. Options are: diff --git a/doc/rasctl_man_page.txt b/doc/rasctl_man_page.txt index d7ed524e..dee66667 100644 --- a/doc/rasctl_man_page.txt +++ b/doc/rasctl_man_page.txt @@ -9,8 +9,8 @@ SYNOPSIS rasctl -e | -l | -m | -o | -s | -v | -D | -I | -L | -O | -P | -T | -V | -X | [-C FILENAME:FILESIZE] [-E FILENAME] [-F IMAGE_FOLDER] [-R CUR‐ RENT_NAME:NEW_NAME] [-c CMD] [-f FILE|PARAM] [-g LOG_LEVEL] [-h HOST] - [-i ID [-n NAME] [-p PORT] [-r RESERVED_IDS] [-t TYPE] [-u UNIT] [-x - CURRENT_NAME:NEW_NAME] [-z LOCALE] + [-i ID[:LUN] [-n NAME] [-p PORT] [-r RESERVED_IDS] [-t TYPE] [-x CUR‐ + RENT_NAME:NEW_NAME] [-z LOCALE] DESCRIPTION rasctl sends commands to the rascsi process to make configuration ad‐ @@ -93,14 +93,16 @@ OPTIONS -z LOCALE Overrides the default locale for client-facing error messages. - -i ID ID is the SCSI ID that you want to control. (0-7) + -i ID[:LUN] + The SCSI ID and optional LUN that you want to control. + (0-7:0-31) -c CMD Command is the operation being requested. Options are: a(ttach): Attach disk d(etach): Detach disk i(nsert): Insert media (removable media devices only) e(ject): Eject media (removable media devices only) - p(rotect): Write protect the medium (not for CD-ROMs, which + p(rotect): Write protect the medium (not for CD-ROMs, which are always read-only) u(nprotect): Remove write protection from the medium (not for CD-ROMs, which are always read-only) @@ -109,18 +111,18 @@ OPTIONS eject, protect and unprotect are idempotent. -b BLOCK_SIZE - The optional block size, either 512, 1024, 2048 or 4096 bytes. + The optional block size, either 512, 1024, 2048 or 4096 bytes. The default size is 512 bytes. -f FILE|PARAM Device-specific: Either a path to a disk image file, or a param‐ - eter for a non-disk device. See the rascsi(1) man page for per‐ + eter for a non-disk device. See the rascsi(1) man page for per‐ mitted file types. -t TYPE - Specifies the device type. This type overrides the type derived + Specifies the device type. This type overrides the type derived from the file extension of the specified image. See the - rascsi(1) man page for the available device types. For some + rascsi(1) man page for the available device types. For some types there are shortcuts (only the first letter is required): hd: SCSI hard disk drive rm: SCSI removable media drive @@ -132,16 +134,16 @@ OPTIONS services: Host services device -n VENDOR:PRODUCT:REVISION - The vendor, product and revision for the device, to be returned + The vendor, product and revision for the device, to be returned with the INQUIRY data. A complete set of name components must be provided. VENDOR may have up to 8, PRODUCT up to 16, REVISION up to 4 characters. Padding with blanks to the maxium length is au‐ - tomatically applied. Once set the name of a device cannot be + tomatically applied. Once set the name of a device cannot be changed. -u UNIT - Unit number (0-31). This will default to 0. This option is only - used when there are multiple SCSI devices on a shared SCSI con‐ + Unit number (0-31). This will default to 0. This option is only + used when there are multiple SCSI devices on a shared SCSI con‐ troller. (This is not common) EXAMPLES