Fix simple SonarCloud issues (#834)

* Fixing SonarCloud issues, first round

* Fixing SonarCLoud issues, next round

* Fixing SonarQube issues, next round

* Fixed warning

* Replaced empty constructors/destructors with = default;

* Fixed warning

* Replaced new

* Use constants instead of macros

* Use structured binding declarations

* Use init statements for if

* Use string views

* Use enum class, use using instead of typedef

* Fixed more SonarCloud warnings

* Replaced redundant/duplicate types with auto

* Devlared methods const

* Memory management update

* Fixed warning

* Added missing const

* Improved RaScsiResponse memory management

* Improved memory management

* Improved memory management

* Replaced macros by constants, removed unused constants

* Made member private

* Fixed warning

* Added comment

* Fixed shadowing warnings

* Cleanup

* Cleanup

* Cleanup

* Fixed shadowing warning

* Removed unused code

* Fixed more warnings

* Removed obsolete casts

* Fixed warnings

* Removed unused field

* Removed library not needed by rasctl

* Include cleanup

* Updated platform check for better compatibility

* Improved check for invalid option. This prevents rasctl to break on macos.

* Updated option check

* Fixed typo

* Added TODO

* Removed macro

* Scope update

* Replaced macro

* Added TODO, update memory management

* Fixed typo

* Replaced NULL by nullptr

* Use more structured bindings

* Added TODO

* Use calloc instead of mallco to not need memset

* Fixed warnings

* Fixed SonarQube initialization issues

* Fixed warning

* Cleaned up override/virtual/final

* Fixed warnings

* Constructor update

* Fixed tests

* Improved memory management

* Added missing const

* Added const

* Fixed two bugs reported by SonarCloud

* Fix SonarCloud hotspot

* Fixed memory management

* Memory management update

* Addressing hotspot by using strncpy

* Fixed SonarCloud issues

* Fixed SonarQube issues

* Added missing const

* Added const

* Added const

* Suppress false positive

* Added SonarQube suppressions for false positives

* Added suppresoin

* Fixed code smells

* Reverted changes that is a SonarQube issue, but caused problems with -O3

* Removed TODO based on review
This commit is contained in:
Uwe Seimet 2022-09-07 16:38:42 +02:00 committed by GitHub
parent 34242a29ba
commit 05db0e4688
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
82 changed files with 1168 additions and 1275 deletions

View File

@ -21,8 +21,8 @@ ifeq ($(DEBUG), 1)
CXXFLAGS += -O0 -g -Wall -Wextra -DDEBUG
BUILD_TYPE = Debug
else
# Release compiler flags, ignore unused parameters because they are reported for some assertions
CXXFLAGS += -O3 -Wall -Werror -Wextra -Wno-unused-parameter -DNDEBUG
# Release compiler flags
CXXFLAGS += -O3 -Wall -Werror -Wextra -DNDEBUG
BUILD_TYPE = Release
endif
ifeq ("$(shell uname -s)","Linux")
@ -190,7 +190,7 @@ $(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) | $(BINDIR
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_CORE) $(OBJ_RASCSI) -lpthread -lpcap -lprotobuf -lstdc++fs
$(BINDIR)/$(RASCTL): $(SRC_PROTOBUF) $(OBJ_RASCTL) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) -lpthread -lprotobuf -lstdc++fs
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) -lpthread -lprotobuf
$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP)

View File

@ -19,7 +19,7 @@
//---------------------------------------------------------------------------
#define USE_SEL_EVENT_ENABLE // Check SEL signal by event
// This avoids an indefinite loop with warnings if there is no RaSCSI hardware
// and thus helps with running certain tests on X86 hardware.
#if defined(__x86_64) || defined(__X86)
// and thus helps with running rasctl and unit test on other hardware.
#if !defined(__arm__)
#undef USE_SEL_EVENT_ENABLE
#endif

View File

@ -37,12 +37,11 @@ bool AbstractController::HasDeviceForLun(int lun) const
return ctrl.luns.find(lun) != ctrl.luns.end();
}
int AbstractController::ExtractInitiatorId(int id_data)
int AbstractController::ExtractInitiatorId(int id_data) const
{
int initiator_id = -1;
int tmp = id_data - (1 << target_id);
if (tmp) {
if (int tmp = id_data - (1 << target_id); tmp) {
initiator_id = 0;
for (int j = 0; j < 8; j++) {
tmp >>= 1;

View File

@ -18,14 +18,14 @@ using namespace std;
class PrimaryDevice;
class AbstractController : virtual public PhaseHandler
class AbstractController : public PhaseHandler
{
public:
// Maximum number of logical units
static const int LUN_MAX = 32;
enum rascsi_shutdown_mode {
enum class rascsi_shutdown_mode {
NONE,
STOP_RASCSI,
STOP_PI,
@ -35,7 +35,7 @@ public:
// Internal data definition
// TODO Some of these data are probably device specific, and in this case they should be moved.
// These data are not internal, otherwise they could all be private
typedef struct _ctrl_t {
using ctrl_t = struct _ctrl_t {
// General
BUS::phase_t phase = BUS::busfree; // Transition phase
@ -55,10 +55,10 @@ public:
// Logical units of this device controller mapped to their LUN numbers
unordered_map<int, PrimaryDevice *> luns;
} ctrl_t;
};
AbstractController(BUS *bus, int target_id) : bus(bus), target_id(target_id) {}
virtual ~AbstractController() {}
~AbstractController() override = default;
virtual BUS::phase_t Process(int) = 0;
@ -81,7 +81,7 @@ public:
bool AddDevice(PrimaryDevice *);
bool DeleteDevice(const PrimaryDevice *);
bool HasDeviceForLun(int) const;
int ExtractInitiatorId(int id_data);
int ExtractInitiatorId(int id_data) const;
// TODO Do not expose internal data
ctrl_t* GetCtrl() { return &ctrl; }
@ -91,7 +91,9 @@ protected:
BUS *bus;
int target_id;
ctrl_t ctrl = {};
private:
int target_id;
};

View File

@ -41,9 +41,9 @@ bool ControllerManager::CreateScsiController(BUS *bus, PrimaryDevice *device)
AbstractController *ControllerManager::IdentifyController(int data) const
{
for (const auto& controller : controllers) {
if (data & (1 << controller.second->GetTargetId())) {
return controller.second;
for (const auto& [id, controller] : controllers) {
if (data & (1 << controller->GetTargetId())) {
return controller;
}
}
@ -58,8 +58,8 @@ AbstractController *ControllerManager::FindController(int target_id) const
void ControllerManager::DeleteAllControllersAndDevices()
{
for (const auto& controller : controllers) {
delete controller.second;
for (const auto& [id, controller] : controllers) {
delete controller;
}
controllers.clear();
@ -71,15 +71,14 @@ void ControllerManager::DeleteAllControllersAndDevices()
void ControllerManager::ResetAllControllers()
{
for (const auto& controller : controllers) {
controller.second->Reset();
for (const auto& [id, controller] : controllers) {
controller->Reset();
}
}
PrimaryDevice *ControllerManager::GetDeviceByIdAndLun(int id, int lun) const
{
const AbstractController *controller = FindController(id);
if (controller != nullptr) {
if (const auto controller = FindController(id); controller != nullptr) {
return controller->GetDeviceForLun(lun);
}

View File

@ -19,7 +19,7 @@ class PrimaryDevice;
class ControllerManager
{
ControllerManager() {}
ControllerManager() = default;
~ControllerManager();
public:

View File

@ -17,8 +17,8 @@ class PhaseHandler
{
public:
PhaseHandler() {}
virtual ~PhaseHandler() {}
PhaseHandler() = default;
virtual ~PhaseHandler() = default;
virtual void SetPhase(BUS::phase_t) = 0;
virtual void BusFree() = 0;

View File

@ -68,7 +68,7 @@ BUS::phase_t ScsiController::Process(int initiator_id)
// Check to see if the reset signal was asserted
if (bus->GetRST()) {
LOGWARN("RESET signal received!");
LOGWARN("RESET signal received!")
// Reset the controller
Reset();
@ -80,10 +80,10 @@ BUS::phase_t ScsiController::Process(int initiator_id)
}
if (initiator_id != UNKNOWN_INITIATOR_ID) {
LOGTRACE("%s Initiator ID is %d", __PRETTY_FUNCTION__, initiator_id);
LOGTRACE("%s Initiator ID is %d", __PRETTY_FUNCTION__, initiator_id)
}
else {
LOGTRACE("%s Initiator ID is unknown", __PRETTY_FUNCTION__);
LOGTRACE("%s Initiator ID is unknown", __PRETTY_FUNCTION__)
}
this->initiator_id = initiator_id;
@ -132,7 +132,7 @@ BUS::phase_t ScsiController::Process(int initiator_id)
// Any exception should have been handled during the phase processing
assert(false);
LOGERROR("%s Unhandled SCSI error, resetting controller and bus and entering bus free phase", __PRETTY_FUNCTION__);
LOGERROR("%s Unhandled SCSI error, resetting controller and bus and entering bus free phase", __PRETTY_FUNCTION__)
Reset();
bus->Reset();
@ -146,7 +146,7 @@ BUS::phase_t ScsiController::Process(int initiator_id)
void ScsiController::BusFree()
{
if (ctrl.phase != BUS::busfree) {
LOGTRACE("%s Bus free phase", __PRETTY_FUNCTION__);
LOGTRACE("%s Bus free phase", __PRETTY_FUNCTION__)
SetPhase(BUS::busfree);
@ -171,22 +171,22 @@ void ScsiController::BusFree()
// When the bus is free RaSCSI or the Pi may be shut down.
// TODO Try to find a better place for this code without breaking encapsulation
switch(shutdown_mode) {
case STOP_RASCSI:
LOGINFO("RaSCSI shutdown requested");
case AbstractController::rascsi_shutdown_mode::STOP_RASCSI:
LOGINFO("RaSCSI shutdown requested")
exit(0);
break;
case STOP_PI:
LOGINFO("Raspberry Pi shutdown requested");
case AbstractController::rascsi_shutdown_mode::STOP_PI:
LOGINFO("Raspberry Pi shutdown requested")
if (system("init 0") == -1) {
LOGERROR("Raspberry Pi shutdown failed: %s", strerror(errno));
LOGERROR("Raspberry Pi shutdown failed: %s", strerror(errno))
}
break;
case RESTART_PI:
LOGINFO("Raspberry Pi restart requested");
case AbstractController::rascsi_shutdown_mode::RESTART_PI:
LOGINFO("Raspberry Pi restart requested")
if (system("init 6") == -1) {
LOGERROR("Raspberry Pi restart failed: %s", strerror(errno));
LOGERROR("Raspberry Pi restart failed: %s", strerror(errno))
}
break;
@ -217,7 +217,7 @@ void ScsiController::Selection()
return;
}
LOGTRACE("%s Selection Phase Target ID=%d", __PRETTY_FUNCTION__, GetTargetId());
LOGTRACE("%s Selection Phase Target ID=%d", __PRETTY_FUNCTION__, GetTargetId())
SetPhase(BUS::selection);
@ -240,7 +240,7 @@ void ScsiController::Selection()
void ScsiController::Command()
{
if (ctrl.phase != BUS::command) {
LOGTRACE("%s Command Phase", __PRETTY_FUNCTION__);
LOGTRACE("%s Command Phase", __PRETTY_FUNCTION__)
SetPhase(BUS::command);
@ -256,7 +256,7 @@ void ScsiController::Command()
// If no byte can be received move to the status phase
int command_byte_count = bus->CommandHandShake(ctrl.buffer);
if (!command_byte_count) {
LOGERROR("%s No command bytes received", __PRETTY_FUNCTION__);
LOGERROR("%s No command bytes received", __PRETTY_FUNCTION__)
Error(sense_key::ABORTED_COMMAND);
return;
}
@ -272,7 +272,7 @@ void ScsiController::Command()
// Command data transfer
for (int i = 0; i < (int)ctrl.length; i++) {
ctrl.cmd[i] = ctrl.buffer[i];
LOGTRACE("%s CDB[%d]=$%02X",__PRETTY_FUNCTION__, i, ctrl.cmd[i]);
LOGTRACE("%s CDB[%d]=$%02X",__PRETTY_FUNCTION__, i, ctrl.cmd[i])
}
// Clear length and block
@ -285,7 +285,7 @@ void ScsiController::Command()
void ScsiController::Execute()
{
LOGTRACE("%s Execution phase command $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]);
LOGTRACE("%s Execution phase command $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0])
SetPhase(BUS::execute);
@ -299,13 +299,13 @@ void ScsiController::Execute()
ctrl.status = 0;
}
LOGDEBUG("++++ CMD ++++ %s Executing command $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]);
LOGDEBUG("++++ CMD ++++ %s Executing command $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0])
int lun = GetEffectiveLun();
if (!HasDeviceForLun(lun)) {
if ((scsi_command)ctrl.cmd[0] != scsi_command::eCmdInquiry &&
(scsi_command)ctrl.cmd[0] != scsi_command::eCmdRequestSense) {
LOGDEBUG("Invalid LUN %d for ID %d", lun, GetTargetId());
LOGDEBUG("Invalid LUN %d for ID %d", lun, GetTargetId())
Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN);
return;
@ -328,12 +328,12 @@ void ScsiController::Execute()
try {
if (!device->Dispatch()) {
LOGTRACE("ID %d LUN %d received unsupported command: $%02X", GetTargetId(), lun, (BYTE)ctrl.cmd[0]);
LOGTRACE("ID %d LUN %d received unsupported command: $%02X", GetTargetId(), lun, (BYTE)ctrl.cmd[0])
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE);
}
}
catch(const scsi_error_exception& e) {
catch(const scsi_error_exception& e) { //NOSONAR This exception is handled properly
Error(e.get_sense_key(), e.get_asc(), e.get_status());
// Fall through
@ -343,7 +343,7 @@ void ScsiController::Execute()
if ((scsi_command)ctrl.cmd[0] == scsi_command::eCmdInquiry && !HasDeviceForLun(lun)) {
lun = GetEffectiveLun();
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, device->GetId());
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, device->GetId())
ctrl.buffer[0] = 0x7f;
}
@ -359,7 +359,7 @@ void ScsiController::Status()
SysTimer::SleepUsec(5);
}
LOGTRACE("%s Status Phase $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.status);
LOGTRACE("%s Status Phase $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.status)
SetPhase(BUS::status);
@ -383,7 +383,7 @@ void ScsiController::Status()
void ScsiController::MsgIn()
{
if (ctrl.phase != BUS::msgin) {
LOGTRACE("%s Message In phase", __PRETTY_FUNCTION__);
LOGTRACE("%s Message In phase", __PRETTY_FUNCTION__)
SetPhase(BUS::msgin);
@ -398,16 +398,16 @@ void ScsiController::MsgIn()
return;
}
LOGTRACE("%s Transitioning to Send()", __PRETTY_FUNCTION__);
LOGTRACE("%s Transitioning to Send()", __PRETTY_FUNCTION__)
Send();
}
void ScsiController::MsgOut()
{
LOGTRACE("%s ID %d",__PRETTY_FUNCTION__, GetTargetId());
LOGTRACE("%s ID %d",__PRETTY_FUNCTION__, GetTargetId())
if (ctrl.phase != BUS::msgout) {
LOGTRACE("Message Out Phase");
LOGTRACE("Message Out Phase")
// process the IDENTIFY message
if (ctrl.phase == BUS::selection) {
@ -447,7 +447,7 @@ void ScsiController::DataIn()
return;
}
LOGTRACE("%s Going into Data-in Phase", __PRETTY_FUNCTION__);
LOGTRACE("%s Going into Data-in Phase", __PRETTY_FUNCTION__)
SetPhase(BUS::datain);
@ -479,7 +479,7 @@ void ScsiController::DataOut()
return;
}
LOGTRACE("%s Data out phase", __PRETTY_FUNCTION__);
LOGTRACE("%s Data out phase", __PRETTY_FUNCTION__)
SetPhase(BUS::dataout);
@ -529,7 +529,7 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status)
ctrl.status = status;
ctrl.message = 0x00;
LOGTRACE("%s Error (to status phase)", __PRETTY_FUNCTION__);
LOGTRACE("%s Error (to status phase)", __PRETTY_FUNCTION__)
Status();
}
@ -541,7 +541,7 @@ void ScsiController::Send()
if (ctrl.length != 0) {
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(ctrl.offset) + ", length "
+ to_string(ctrl.length)).c_str());
+ to_string(ctrl.length)).c_str())
// TODO The delay has to be taken from ctrl.unit[lun], but as there are currently no Daynaport drivers for
// LUNs other than 0 this work-around works.
@ -569,7 +569,7 @@ void ScsiController::Send()
if (ctrl.blocks != 0) {
// set next buffer (set offset, length)
result = XferIn(ctrl.buffer);
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(ctrl.blocks)).c_str());
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(ctrl.blocks)).c_str())
}
}
@ -581,14 +581,14 @@ void ScsiController::Send()
// Continue sending if block !=0
if (ctrl.blocks != 0){
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Continuing to send. Blocks: " + to_string(ctrl.blocks)).c_str());
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Continuing to send. Blocks: " + to_string(ctrl.blocks)).c_str())
assert(ctrl.length > 0);
assert(ctrl.offset == 0);
return;
}
// Move to next phase
LOGTRACE("%s Move to next phase %s (%d)", __PRETTY_FUNCTION__, BUS::GetPhaseStrRaw(ctrl.phase), ctrl.phase);
LOGTRACE("%s Move to next phase %s (%d)", __PRETTY_FUNCTION__, BUS::GetPhaseStrRaw(ctrl.phase), ctrl.phase)
switch (ctrl.phase) {
// Message in phase
case BUS::msgin:
@ -636,7 +636,7 @@ void ScsiController::Receive()
int len;
BYTE data;
LOGTRACE("%s",__PRETTY_FUNCTION__);
LOGTRACE("%s",__PRETTY_FUNCTION__)
// REQ is low
assert(!bus->GetREQ());
@ -644,13 +644,13 @@ void ScsiController::Receive()
// Length != 0 if received
if (ctrl.length != 0) {
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, (int)ctrl.length);
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, (int)ctrl.length)
// Receive
len = bus->ReceiveHandShake(&ctrl.buffer[ctrl.offset], ctrl.length);
// If not able to receive all, move to status phase
if (len != (int)ctrl.length) {
LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, (int)ctrl.length, len);
LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, (int)ctrl.length, len)
Error(sense_key::ABORTED_COMMAND);
return;
}
@ -666,7 +666,7 @@ void ScsiController::Receive()
bool result = true;
// Processing after receiving data (by phase)
LOGTRACE("%s ctrl.phase: %d (%s)",__PRETTY_FUNCTION__, (int)ctrl.phase, BUS::GetPhaseStrRaw(ctrl.phase));
LOGTRACE("%s ctrl.phase: %d (%s)",__PRETTY_FUNCTION__, (int)ctrl.phase, BUS::GetPhaseStrRaw(ctrl.phase))
switch (ctrl.phase) {
case BUS::dataout:
if (ctrl.blocks == 0) {
@ -714,7 +714,7 @@ void ScsiController::Receive()
for (int i = 0; i < len; i++) {
ctrl.cmd[i] = ctrl.buffer[i];
LOGTRACE("%s Command Byte %d: $%02X",__PRETTY_FUNCTION__, i, ctrl.cmd[i]);
LOGTRACE("%s Command Byte %d: $%02X",__PRETTY_FUNCTION__, i, ctrl.cmd[i])
}
Execute();
@ -739,14 +739,14 @@ void ScsiController::Receive()
// ABORT
if (data == 0x06) {
LOGTRACE("Message code ABORT $%02X", data);
LOGTRACE("Message code ABORT $%02X", data)
BusFree();
return;
}
// BUS DEVICE RESET
if (data == 0x0C) {
LOGTRACE("Message code BUS DEVICE RESET $%02X", data);
LOGTRACE("Message code BUS DEVICE RESET $%02X", data)
scsi.syncoffset = 0;
BusFree();
return;
@ -755,12 +755,12 @@ void ScsiController::Receive()
// IDENTIFY
if (data >= 0x80) {
identified_lun = data & 0x1F;
LOGTRACE("Message code IDENTIFY $%02X, LUN %d selected", data, identified_lun);
LOGTRACE("Message code IDENTIFY $%02X, LUN %d selected", data, identified_lun)
}
// Extended Message
if (data == 0x01) {
LOGTRACE("Message code EXTENDED MESSAGE $%02X", data);
LOGTRACE("Message code EXTENDED MESSAGE $%02X", data)
// Check only when synchronous transfer is possible
if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) {
@ -835,21 +835,21 @@ void ScsiController::ReceiveBytes()
uint32_t len;
BYTE data;
LOGTRACE("%s",__PRETTY_FUNCTION__);
LOGTRACE("%s",__PRETTY_FUNCTION__)
// REQ is low
assert(!bus->GetREQ());
assert(!bus->GetIO());
if (ctrl.length) {
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length);
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length)
len = bus->ReceiveHandShake(&ctrl.buffer[ctrl.offset], ctrl.length);
// If not able to receive all, move to status phase
if (len != ctrl.length) {
LOGERROR("%s Not able to receive %d bytes of data, only received %d",
__PRETTY_FUNCTION__, ctrl.length, len);
__PRETTY_FUNCTION__, ctrl.length, len)
Error(sense_key::ABORTED_COMMAND);
return;
}
@ -866,7 +866,7 @@ void ScsiController::ReceiveBytes()
bool result = true;
// Processing after receiving data (by phase)
LOGTRACE("%s ctrl.phase: %d (%s)",__PRETTY_FUNCTION__, (int)ctrl.phase, BUS::GetPhaseStrRaw(ctrl.phase));
LOGTRACE("%s ctrl.phase: %d (%s)",__PRETTY_FUNCTION__, (int)ctrl.phase, BUS::GetPhaseStrRaw(ctrl.phase))
switch (ctrl.phase) {
case BUS::dataout:
@ -902,7 +902,7 @@ void ScsiController::ReceiveBytes()
for (uint32_t i = 0; i < len; i++) {
ctrl.cmd[i] = ctrl.buffer[i];
LOGTRACE("%s Command Byte %d: $%02X",__PRETTY_FUNCTION__, i, ctrl.cmd[i]);
LOGTRACE("%s Command Byte %d: $%02X",__PRETTY_FUNCTION__, i, ctrl.cmd[i])
}
Execute();
@ -927,14 +927,14 @@ void ScsiController::ReceiveBytes()
// ABORT
if (data == 0x06) {
LOGTRACE("Message code ABORT $%02X", data);
LOGTRACE("Message code ABORT $%02X", data)
BusFree();
return;
}
// BUS DEVICE RESET
if (data == 0x0C) {
LOGTRACE("Message code BUS DEVICE RESET $%02X", data);
LOGTRACE("Message code BUS DEVICE RESET $%02X", data)
scsi.syncoffset = 0;
BusFree();
return;
@ -943,12 +943,12 @@ void ScsiController::ReceiveBytes()
// IDENTIFY
if (data >= 0x80) {
identified_lun = data & 0x1F;
LOGTRACE("Message code IDENTIFY $%02X, LUN %d selected", data, identified_lun);
LOGTRACE("Message code IDENTIFY $%02X, LUN %d selected", data, identified_lun)
}
// Extended Message
if (data == 0x01) {
LOGTRACE("Message code EXTENDED MESSAGE $%02X", data);
LOGTRACE("Message code EXTENDED MESSAGE $%02X", data)
// Check only when synchronous transfer is possible
if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) {
@ -1051,7 +1051,7 @@ void ScsiController::FlushUnit()
disk->ModeSelect(ctrl.cmd, ctrl.buffer, ctrl.offset);
}
catch(const scsi_error_exception& e) {
LOGWARN("Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]);
LOGWARN("Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0])
Error(e.get_sense_key(), e.get_asc(), e.get_status());
return;
}
@ -1079,7 +1079,7 @@ bool ScsiController::XferIn(BYTE *buf)
{
assert(ctrl.phase == BUS::datain);
LOGTRACE("%s ctrl.cmd[0]=%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]);
LOGTRACE("%s ctrl.cmd[0]=%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0])
int lun = GetEffectiveLun();
if (!HasDeviceForLun(lun)) {
@ -1205,7 +1205,7 @@ bool ScsiController::XferOutBlockOriented(bool cont)
}
case eCmdSetMcastAddr:
LOGTRACE("%s Done with DaynaPort Set Multicast Address", __PRETTY_FUNCTION__);
LOGTRACE("%s Done with DaynaPort Set Multicast Address", __PRETTY_FUNCTION__)
break;
default:

View File

@ -54,7 +54,7 @@ class ScsiController : public AbstractController
eCmdWriteLong16 = 0x9F
};
typedef struct _scsi_t {
using scsi_t = struct _scsi_t {
// Synchronous transfer
bool syncenable; // Synchronous transfer possible
int syncperiod = MAX_SYNC_PERIOD; // Synchronous transfer period
@ -65,12 +65,12 @@ class ScsiController : public AbstractController
bool atnmsg;
int msc;
BYTE msb[256];
} scsi_t;
};
public:
ScsiController(BUS *, int);
~ScsiController();
~ScsiController() override;
void Reset() override;
@ -130,6 +130,6 @@ private:
scsi_t scsi = {};
rascsi_shutdown_mode shutdown_mode = NONE;
AbstractController::rascsi_shutdown_mode shutdown_mode = AbstractController::rascsi_shutdown_mode::NONE;
};

View File

@ -27,7 +27,7 @@
// Kanji code conversion
//
//---------------------------------------------------------------------------
#define IC_BUF_SIZE 1024
static const int IC_BUF_SIZE = 1024;
static char convert_buf[IC_BUF_SIZE];
#define CONVERT(src, dest, inbuf, outbuf, outsize) \
convert(src, dest, (char *)inbuf, outbuf, outsize)
@ -256,7 +256,7 @@ void CHostDrv::Init(const TCHAR* szBase, DWORD nFlag)
// Remove the last path delimiter in the base path
// @warning needs to be modified when using Unicode
TCHAR* pClear = NULL;
TCHAR* pClear = nullptr;
TCHAR* p = m_szBase;
for (;;) {
TCHAR c = *p;
@ -265,7 +265,7 @@ void CHostDrv::Init(const TCHAR* szBase, DWORD nFlag)
if (c == _T('/') || c == _T('\\')) {
pClear = p;
} else {
pClear = NULL;
pClear = nullptr;
}
if ((c <= (TCHAR)0x9F) || (TCHAR)0xE0 <= c) { // To be precise: 0x81~0x9F 0xE0~0xEF
p++;
@ -286,7 +286,7 @@ void CHostDrv::Init(const TCHAR* szBase, DWORD nFlag)
// Media check
//
//---------------------------------------------------------------------------
BOOL CHostDrv::isMediaOffline()
BOOL CHostDrv::isMediaOffline() const
{
// Offline status check
return m_bEnable == FALSE;
@ -475,14 +475,12 @@ BOOL CHostDrv::GetCapacityCache(Human68k::capacity_t* pCapacity) const
/// Update all cache
//
//---------------------------------------------------------------------------
void CHostDrv::CleanCache()
void CHostDrv::CleanCache() const
{
Lock();
for (CHostPath* p = (CHostPath*)m_cRing.Next(); p != &m_cRing;) {
for (auto p = (CHostPath*)m_cRing.Next(); p != &m_cRing;) {
p->Release();
p = (CHostPath*)p->Next();
}
Unlock();
}
//---------------------------------------------------------------------------
@ -494,13 +492,11 @@ void CHostDrv::CleanCache(const BYTE* szHumanPath)
{
ASSERT(szHumanPath);
Lock();
CHostPath* p = FindCache(szHumanPath);
if (p) {
p->Restore();
p->Release();
}
Unlock();
}
//---------------------------------------------------------------------------
@ -508,18 +504,16 @@ void CHostDrv::CleanCache(const BYTE* szHumanPath)
/// Update the cache below and including the specified path
//
//---------------------------------------------------------------------------
void CHostDrv::CleanCacheChild(const BYTE* szHumanPath)
void CHostDrv::CleanCacheChild(const BYTE* szHumanPath) const
{
ASSERT(szHumanPath);
Lock();
CHostPath* p = (CHostPath*)m_cRing.Next();
auto p = (CHostPath*)m_cRing.Next();
while (p != &m_cRing) {
if (p->isSameChild(szHumanPath))
p->Release();
p = (CHostPath*)p->Next();
}
Unlock();
}
//---------------------------------------------------------------------------
@ -531,14 +525,12 @@ void CHostDrv::DeleteCache(const BYTE* szHumanPath)
{
ASSERT(szHumanPath);
Lock();
CHostPath* p = FindCache(szHumanPath);
auto p = FindCache(szHumanPath);
if (p) {
delete p;
ASSERT(m_nRing);
m_nRing--;
}
Unlock();
}
//---------------------------------------------------------------------------
@ -555,13 +547,13 @@ CHostPath* CHostDrv::FindCache(const BYTE* szHuman)
ASSERT(szHuman);
// Find something that matches perfectly with either of the stored file names
for (CHostPath* p = (CHostPath*)m_cRing.Next(); p != &m_cRing;) {
for (auto p = (CHostPath*)m_cRing.Next(); p != &m_cRing;) {
if (p->isSameHuman(szHuman))
return p;
p = (CHostPath*)p->Next();
}
return NULL;
return nullptr;
}
//---------------------------------------------------------------------------
@ -580,8 +572,8 @@ CHostPath* CHostDrv::CopyCache(CHostFiles* pFiles)
// Find in cache
CHostPath* pPath = FindCache(pFiles->GetHumanPath());
if (pPath == NULL) {
return NULL; // Error: No cache
if (pPath == nullptr) {
return nullptr; // Error: No cache
}
// Move to the beginning of the ring
@ -589,7 +581,7 @@ CHostPath* CHostDrv::CopyCache(CHostFiles* pFiles)
// Cache update check
if (pPath->isRefresh()) {
return NULL; // Error: Cache update is required
return nullptr; // Error: Cache update is required
}
// Store the host side path
@ -615,7 +607,7 @@ CHostPath* CHostDrv::CopyCache(CHostFiles* pFiles)
/// If it's cached, do a destruction check. If it was destroyed, treat it as uncached.
/// If it isn't cached, build cache.
/// Exit after processing all directory and file names in order.
/// Make it NULL is an error is thrown.
/// Make it nullptr is an error is thrown.
//
//---------------------------------------------------------------------------
CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
@ -639,26 +631,26 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
for (;;) {
// Add path separators
if (nHumanPath + 1 >= HUMAN68K_PATH_MAX)
return NULL; // Error: The Human68k path is too long
return nullptr; // Error: The Human68k path is too long
szHumanPath[nHumanPath++] = '/';
szHumanPath[nHumanPath] = '\0';
if (nHostPath + 1 >= FILEPATH_MAX)
return NULL; // Error: The host side path is too long
return nullptr; // Error: The host side path is too long
szHostPath[nHostPath++] = _T('/');
szHostPath[nHostPath] = _T('\0');
// Insert one file
BYTE szHumanFilename[24]; // File name part
p = SeparateCopyFilename(p, szHumanFilename);
if (p == NULL)
return NULL; // Error: Failed to read file name
if (p == nullptr)
return nullptr; // Error: Failed to read file name
size_t n = strlen((const char*)szHumanFilename);
if (nHumanPath + n >= HUMAN68K_PATH_MAX)
return NULL; // Error: The Human68k path is too long
return nullptr; // Error: The Human68k path is too long
// Is the relevant path cached?
pPath = FindCache(szHumanPath);
if (pPath == NULL) {
if (pPath == nullptr) {
// Check for max number of cache
if (m_nRing >= XM6_HOST_DIRENTRY_CACHE_MAX) {
// Destroy the oldest cache and reuse it
@ -699,8 +691,8 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
pFilename = pPath->FindFilename(szHumanFilename, Human68k::AT_DIRECTORY);
else
pFilename = pPath->FindFilename(szHumanFilename);
if (pFilename == NULL)
return NULL; // Error: Could not find path or file names in the middle
if (pFilename == nullptr)
return nullptr; // Error: Could not find path or file names in the middle
// Link path name
strcpy((char*)szHumanPath + nHumanPath, (const char*)szHumanFilename);
@ -708,7 +700,7 @@ CHostPath* CHostDrv::MakeCache(CHostFiles* pFiles)
n = strlen(pFilename->GetHost());
if (nHostPath + n >= FILEPATH_MAX)
return NULL; // Error: Host side path is too long
return nullptr; // Error: Host side path is too long
strcpy(szHostPath + nHostPath, pFilename->GetHost());
nHostPath += n;
@ -734,14 +726,11 @@ BOOL CHostDrv::Find(CHostFiles* pFiles)
{
ASSERT(pFiles);
Lock();
// Get path name and build cache
CHostPath* pPath = CopyCache(pFiles);
if (pPath == NULL) {
if (pPath == nullptr) {
pPath = MakeCache(pFiles);
if (pPath == NULL) {
Unlock();
if (pPath == nullptr) {
CleanCache();
return FALSE; // Error: Failed to build cache
}
@ -752,14 +741,12 @@ BOOL CHostDrv::Find(CHostFiles* pFiles)
// Exit if only path name
if (pFiles->isPathOnly()) {
Unlock();
return TRUE; // Normal exit: only path name
}
// Find file name
const CHostFilename* pFilename = pFiles->Find(pPath);
if (pFilename == NULL) {
Unlock();
if (pFilename == nullptr) {
return FALSE; // Error: Could not get file name
}
@ -769,8 +756,6 @@ BOOL CHostDrv::Find(CHostFiles* pFiles)
// Store the host side full path name
pFiles->AddResult(pFilename->GetHost());
Unlock();
return TRUE;
}
@ -854,7 +839,7 @@ void CHostFilename::ConvertHuman(int nCount)
// Preparations to adjust the base name segment
BYTE szNumber[8];
BYTE* pNumber = NULL;
BYTE* pNumber = nullptr;
if (nCount >= 0) {
pNumber = &szNumber[8];
for (DWORD i = 0; i < 5; i++) { // Max 5+1 digits (always leave the first 2 bytes of the base name)
@ -878,7 +863,7 @@ void CHostFilename::ConvertHuman(int nCount)
BYTE szHuman[FILEPATH_MAX];
const BYTE* pFirst = szHuman;
const BYTE* pLast;
const BYTE* pExt = NULL;
const BYTE* pExt = nullptr;
{
strcpy(szHost, m_szHost);
@ -934,6 +919,8 @@ void CHostFilename::ConvertHuman(int nCount)
if (nOption & WINDRV_OPT_CONVERT_PERIODS)
c = '_';
break;
default:
break;
}
*pWrite++ = c;
if (c == '\0')
@ -992,7 +979,7 @@ void CHostFilename::ConvertHuman(int nCount)
// Evaluate base name
pCut = (BYTE*)strchr((const char*)pCut, '.'); // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
if (pCut == NULL)
if (pCut == nullptr)
pCut = pLast;
if ((size_t)(pCut - pFirst) > nMax)
pCut = pFirst + nMax; // Execute Shift-JIS 2 byte evaluation/adjustment later. Not allowed to do it here.
@ -1078,7 +1065,6 @@ void CHostFilename::CopyHuman(const BYTE* szHuman)
//---------------------------------------------------------------------------
void CHostFilename::SetEntryName()
{
// Set file name
BYTE* p = m_szHuman;
size_t i;
@ -1113,7 +1099,6 @@ void CHostFilename::SetEntryName()
//---------------------------------------------------------------------------
BOOL CHostFilename::isReduce() const
{
return strcmp((char *)m_szHost, (const char*)m_szHuman) != 0;
}
@ -1124,7 +1109,6 @@ BOOL CHostFilename::isReduce() const
//---------------------------------------------------------------------------
BOOL CHostFilename::CheckAttribute(DWORD nHumanAttribute) const
{
BYTE nAttribute = m_dirHuman.attr;
if ((nAttribute & (Human68k::AT_ARCHIVE | Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 0)
nAttribute |= Human68k::AT_ARCHIVE;
@ -1146,7 +1130,7 @@ const BYTE* CHostFilename::SeparateExt(const BYTE* szHuman) // static
// Confirm the position of the Human68k extension
const BYTE* pExt = (BYTE*)strrchr((const char*)pFirst, '.'); // The 2nd byte of Shift-JIS is always 0x40 or higher, so this is ok
if (pExt == NULL)
if (pExt == nullptr)
pExt = pLast;
// Special handling of the pattern where the file name is 20~22 chars, and the 19th char is '.' or ends with '.'
if (20 <= nLength && nLength <= 22 && pFirst[18] == '.' && pFirst[nLength - 1] == '.')
@ -1227,7 +1211,6 @@ void CHostPath::Free(ring_t* pRing) // static
//---------------------------------------------------------------------------
void CHostPath::Clean()
{
Release();
// Release all file names
@ -1412,7 +1395,7 @@ const CHostFilename* CHostPath::FindFilename(const BYTE* szHuman, DWORD nHumanAt
return &p->f;
}
return NULL;
return nullptr;
}
//---------------------------------------------------------------------------
@ -1500,7 +1483,7 @@ const CHostFilename* CHostPath::FindFilenameWildcard(const BYTE* szHuman, DWORD
pFind->id = m_nId;
pFind->pos = p;
memset(&pFind->entry, 0, sizeof(pFind->entry));
return NULL;
return nullptr;
}
//---------------------------------------------------------------------------
@ -1508,9 +1491,8 @@ const CHostFilename* CHostPath::FindFilenameWildcard(const BYTE* szHuman, DWORD
/// Confirm that the file update has been carried out
//
//---------------------------------------------------------------------------
BOOL CHostPath::isRefresh()
BOOL CHostPath::isRefresh() const
{
return m_bRefresh;
}
@ -1551,22 +1533,22 @@ void CHostPath::Refresh()
// Register file name
BOOL bUpdate = FALSE;
struct dirent **pd = NULL;
dirent **pd = nullptr;
int nument = 0;
int maxent = XM6_HOST_DIRENTRY_FILE_MAX;
for (int i = 0; i < maxent; i++) {
TCHAR szFilename[FILEPATH_MAX];
if (pd == NULL) {
nument = scandir(S2U(szPath), &pd, NULL, AsciiSort);
if (pd == nullptr) {
nument = scandir(S2U(szPath), &pd, nullptr, AsciiSort);
if (nument == -1) {
pd = NULL;
pd = nullptr;
break;
}
maxent = nument;
}
// When at the top level directory, exclude current and parent
struct dirent* pe = pd[i];
const dirent* pe = pd[i];
if (m_szHuman[0] == '/' && m_szHuman[1] == 0) {
if (strcmp(pe->d_name, ".") == 0 || strcmp(pe->d_name, "..") == 0) {
continue;
@ -1582,10 +1564,10 @@ void CHostPath::Refresh()
pFilename->SetHost(szFilename);
// If there is a relevant file name in the previous cache, prioritize that for the Human68k name
ring_t* pCache = (ring_t*)cRingBackup.Next();
auto pCache = (ring_t*)cRingBackup.Next();
for (;;) {
if (pCache == (ring_t*)&cRingBackup) {
pCache = NULL; // No relevant entry
pCache = nullptr; // No relevant entry
bUpdate = TRUE; // Confirm new entry
pFilename->ConvertHuman();
break;
@ -1609,7 +1591,7 @@ void CHostPath::Refresh()
if (pFilename->isCorrect()) {
// Confirm match with previous entry
const CHostFilename* pCheck = FindFilename(pFilename->GetHuman());
if (pCheck == NULL) {
if (pCheck == nullptr) {
// If no match, confirm existence of real file
strcpy(szPath, m_szHost);
strcat(szPath, (const char*)pFilename->GetHuman());
@ -1630,7 +1612,7 @@ void CHostPath::Refresh()
strcpy(szPath, m_szHost);
strcat(szPath, U2S(pe->d_name));
struct stat sb;
struct stat sb; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (stat(S2U(szPath), &sb))
continue;
@ -1646,7 +1628,7 @@ void CHostPath::Refresh()
WORD nHumanDate = 0;
WORD nHumanTime = 0;
struct tm* pt = localtime(&sb.st_mtime);
const tm* pt = localtime(&sb.st_mtime);
if (pt) {
nHumanDate = (WORD)(((pt->tm_year - 80) << 9) | ((pt->tm_mon + 1) << 5) | pt->tm_mday);
nHumanTime = (WORD)((pt->tm_hour << 11) | (pt->tm_min << 5) | (pt->tm_sec >> 1));
@ -1711,7 +1693,7 @@ void CHostPath::Backup()
len--;
ASSERT(szPath[len] == _T('/'));
szPath[len] = _T('\0');
struct stat sb;
struct stat sb; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (stat(S2U(szPath), &sb) == 0)
m_tBackup = sb.st_mtime;
}
@ -1737,7 +1719,7 @@ void CHostPath::Restore() const
ASSERT(szPath[len] == _T('/'));
szPath[len] = _T('\0');
struct utimbuf ut;
utimbuf ut;
ut.actime = m_tBackup;
ut.modtime = m_tBackup;
utime(szPath, &ut);
@ -1764,7 +1746,7 @@ void CHostPath::Release()
CHostEntry::CHostEntry()
{
for (size_t n = 0; n < DriveMax; n++) {
m_pDrv[n] = NULL;
m_pDrv[n] = nullptr;
}
m_nTimeout = 0;
@ -1777,7 +1759,7 @@ CHostEntry::~CHostEntry()
#ifdef _DEBUG
// Confirm object
for (size_t n = 0; n < DriveMax; n++) {
ASSERT(m_pDrv[n] == NULL);
ASSERT(m_pDrv[n] == nullptr);
}
#endif // _DEBUG
}
@ -1793,7 +1775,7 @@ void CHostEntry::Init()
#ifdef _DEBUG
// Confirm object
for (size_t n = 0; n < DriveMax; n++) {
ASSERT(m_pDrv[n] == NULL);
ASSERT(m_pDrv[n] == nullptr);
}
#endif // _DEBUG
}
@ -1809,7 +1791,7 @@ void CHostEntry::Clean()
// Delete object
for (size_t n = 0; n < DriveMax; n++) {
delete m_pDrv[n];
m_pDrv[n] = NULL;
m_pDrv[n] = nullptr;
}
}
@ -1889,7 +1871,7 @@ void CHostEntry::DeleteCache(DWORD nUnit, const BYTE* szHumanPath)
/// Find host side names (path name + file name (can be abbreviated) + attribute)
//
//---------------------------------------------------------------------------
BOOL CHostEntry::Find(DWORD nUnit, CHostFiles* pFiles)
BOOL CHostEntry::Find(DWORD nUnit, CHostFiles* pFiles) const
{
ASSERT(pFiles);
ASSERT(nUnit < DriveMax);
@ -1898,8 +1880,6 @@ BOOL CHostEntry::Find(DWORD nUnit, CHostFiles* pFiles)
return m_pDrv[nUnit]->Find(pFiles);
}
void CHostEntry::ShellNotify(DWORD, const TCHAR*) {}
//---------------------------------------------------------------------------
//
/// Drive settings
@ -1908,7 +1888,7 @@ void CHostEntry::ShellNotify(DWORD, const TCHAR*) {}
void CHostEntry::SetDrv(DWORD nUnit, CHostDrv* pDrv)
{
ASSERT(nUnit < DriveMax);
ASSERT(m_pDrv[nUnit] == NULL);
ASSERT(m_pDrv[nUnit] == nullptr);
m_pDrv[nUnit] = pDrv;
}
@ -1944,7 +1924,7 @@ BOOL CHostEntry::isEnable(DWORD nUnit) const
/// Media check
//
//---------------------------------------------------------------------------
BOOL CHostEntry::isMediaOffline(DWORD nUnit)
BOOL CHostEntry::isMediaOffline(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(m_pDrv[nUnit]);
@ -1983,7 +1963,7 @@ DWORD CHostEntry::GetStatus(DWORD nUnit) const
/// Media change check
//
//---------------------------------------------------------------------------
BOOL CHostEntry::CheckMedia(DWORD nUnit)
BOOL CHostEntry::CheckMedia(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(m_pDrv[nUnit]);
@ -2035,7 +2015,7 @@ BOOL CHostEntry::GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const
/// Get capacity
//
//---------------------------------------------------------------------------
DWORD CHostEntry::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity)
DWORD CHostEntry::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const
{
ASSERT(nUnit < DriveMax);
ASSERT(m_pDrv[nUnit]);
@ -2077,7 +2057,7 @@ const BYTE* CHostDrv::SeparateCopyFilename(const BYTE* szHuman, BYTE* szBuffer)
BYTE c = *p++; // Read
if (c != '/' && c != '\\')
return NULL; // Error: Invalid path name
return nullptr; // Error: Invalid path name
// Insert one file
size_t i = 0;
@ -2087,22 +2067,22 @@ const BYTE* CHostDrv::SeparateCopyFilename(const BYTE* szHuman, BYTE* szBuffer)
break; // Exit if at the end of an array (return the end position)
if (c == '/' || c == '\\') {
if (i == 0)
return NULL; // Error: Two separator chars appear in sequence
return nullptr; // Error: Two separator chars appear in sequence
break; // Exit after reading the separator (return the char position)
}
p++;
if (i >= nMax)
return NULL; // Error: The first byte hits the end of the buffer
return nullptr; // Error: The first byte hits the end of the buffer
szBuffer[i++] = c; // Read
if ((0x80 <= c && c <= 0x9F) || 0xE0 <= c) { // Specifically 0x81~0x9F and 0xE0~0xEF
c = *p++; // Read
if (c < 0x40)
return NULL; // Error: Invalid Shift-JIS 2nd byte
return nullptr; // Error: Invalid Shift-JIS 2nd byte
if (i >= nMax)
return NULL; // Error: The second byte hits the end of the buffer
return nullptr; // Error: The second byte hits the end of the buffer
szBuffer[i++] = c; // Read
}
}
@ -2111,16 +2091,6 @@ const BYTE* CHostDrv::SeparateCopyFilename(const BYTE* szHuman, BYTE* szBuffer)
return p;
}
//===========================================================================
//
// File search processing
//
//===========================================================================
void CHostFiles::Init()
{
}
//---------------------------------------------------------------------------
//
/// Generate path and file name internally
@ -2272,7 +2242,7 @@ CHostFiles* CHostFilesManager::Alloc(DWORD nKey)
ASSERT(nKey);
// Select from the end
ring_t* p = (ring_t*)m_cRing.Prev();
auto p = (ring_t*)m_cRing.Prev();
// Move to the start of the ring
p->r.Insert(&m_cRing);
@ -2287,7 +2257,7 @@ CHostFiles* CHostFilesManager::Search(DWORD nKey)
// ASSERT(nKey); // The search key may become 0 due to DPB damage
// Find the relevant object
ring_t* p = (ring_t*)m_cRing.Next();
auto p = (ring_t*)m_cRing.Next();
for (; p != (ring_t*)&m_cRing; p = (ring_t*)p->r.Next()) {
if (p->f.isSameKey(nKey)) {
// Move to the start of the ring
@ -2296,7 +2266,7 @@ CHostFiles* CHostFilesManager::Search(DWORD nKey)
}
}
return NULL;
return nullptr;
}
void CHostFilesManager::Free(CHostFiles* pFiles)
@ -2305,7 +2275,6 @@ void CHostFilesManager::Free(CHostFiles* pFiles)
// Release
pFiles->SetKey(0);
pFiles->Init();
// Move to the end of the ring
ring_t* p = (ring_t*)((size_t)pFiles - offsetof(ring_t, f));
@ -2321,7 +2290,7 @@ void CHostFilesManager::Free(CHostFiles* pFiles)
void CHostFcb::Init()
{
m_bUpdate = FALSE;
m_pFile = NULL;
m_pFile = nullptr;
}
//---------------------------------------------------------------------------
@ -2373,15 +2342,15 @@ void CHostFcb::SetHumanPath(const BYTE* szHumanPath)
/// Return FALSE if error is thrown.
//
//---------------------------------------------------------------------------
BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce)
BOOL CHostFcb::Create(DWORD, BOOL bForce)
{
ASSERT((nHumanAttribute & (Human68k::AT_DIRECTORY | Human68k::AT_VOLUME)) == 0);
ASSERT((Human68k::AT_DIRECTORY | Human68k::AT_VOLUME) == 0);
ASSERT(strlen(m_szFilename) > 0);
ASSERT(m_pFile == NULL);
ASSERT(m_pFile == nullptr);
// Duplication check
if (bForce == FALSE) {
struct stat sb;
struct stat sb; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (stat(S2U(m_szFilename), &sb) == 0)
return FALSE;
}
@ -2389,7 +2358,7 @@ BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce)
// Create file
m_pFile = fopen(S2U(m_szFilename), "w+b"); /// @warning The ideal operation is to overwrite each attribute
return m_pFile != NULL;
return m_pFile != nullptr;
}
//---------------------------------------------------------------------------
@ -2401,22 +2370,19 @@ BOOL CHostFcb::Create(DWORD nHumanAttribute, BOOL bForce)
//---------------------------------------------------------------------------
BOOL CHostFcb::Open()
{
struct stat st;
ASSERT(strlen(m_szFilename) > 0);
// Fail if directory
if (stat(S2U(m_szFilename), &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFDIR) {
return FALSE || m_bFlag;
}
struct stat st; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (stat(S2U(m_szFilename), &st) == 0 && ((st.st_mode & S_IFMT) == S_IFDIR)) {
return FALSE || m_bFlag;
}
// File open
if (m_pFile == NULL)
if (m_pFile == nullptr)
m_pFile = fopen(S2U(m_szFilename), m_pszMode);
return m_pFile != NULL || m_bFlag;
return m_pFile != nullptr || m_bFlag;
}
//---------------------------------------------------------------------------
@ -2426,7 +2392,7 @@ BOOL CHostFcb::Open()
/// Return FALSE if error is thrown.
//
//---------------------------------------------------------------------------
BOOL CHostFcb::Rewind(DWORD nOffset)
BOOL CHostFcb::Rewind(DWORD nOffset) const
{
ASSERT(m_pFile);
@ -2483,7 +2449,7 @@ DWORD CHostFcb::Write(const BYTE* pBuffer, DWORD nSize)
/// Return FALSE if error is thrown.
//
//---------------------------------------------------------------------------
BOOL CHostFcb::Truncate()
BOOL CHostFcb::Truncate() const
{
ASSERT(m_pFile);
@ -2529,11 +2495,11 @@ DWORD CHostFcb::Seek(DWORD nOffset, DWORD nHumanSeek)
/// Return FALSE if error is thrown.
//
//---------------------------------------------------------------------------
BOOL CHostFcb::TimeStamp(DWORD nHumanTime)
BOOL CHostFcb::TimeStamp(DWORD nHumanTime) const
{
ASSERT(m_pFile || m_bFlag);
struct tm t = { };
tm t = { };
t.tm_year = (nHumanTime >> 25) + 80;
t.tm_mon = ((nHumanTime >> 21) - 1) & 15;
t.tm_mday = (nHumanTime >> 16) & 31;
@ -2543,7 +2509,7 @@ BOOL CHostFcb::TimeStamp(DWORD nHumanTime)
time_t ti = mktime(&t);
if (ti == (time_t)-1)
return FALSE;
struct utimbuf ut;
utimbuf ut;
ut.actime = ti;
ut.modtime = ti;
@ -2569,7 +2535,7 @@ BOOL CHostFcb::Close()
// Always initialize because of the Close→Free (internally one more Close) flow.
if (m_pFile) {
fclose(m_pFile);
m_pFile = NULL;
m_pFile = nullptr;
}
return bResult;
@ -2630,12 +2596,12 @@ CHostFcb* CHostFcbManager::Alloc(DWORD nKey)
ASSERT(nKey);
// Select from the end
ring_t* p = (ring_t*)m_cRing.Prev();
auto p = (ring_t*)m_cRing.Prev();
// Error if in use (just in case)
if (p->f.isSameKey(0) == FALSE) {
ASSERT(0);
return NULL;
ASSERT(FALSE);
return nullptr;
}
// Move to the top of the ring
@ -2652,7 +2618,7 @@ CHostFcb* CHostFcbManager::Search(DWORD nKey)
ASSERT(nKey);
// Search for applicable objects
ring_t* p = (ring_t*)m_cRing.Next();
auto p = (ring_t*)m_cRing.Next();
while (p != (ring_t*)&m_cRing) {
if (p->f.isSameKey(nKey)) {
// Move to the top of the ring
@ -2662,7 +2628,7 @@ CHostFcb* CHostFcbManager::Search(DWORD nKey)
p = (ring_t*)p->r.Next();
}
return NULL;
return nullptr;
}
void CHostFcbManager::Free(CHostFcb* pFcb)
@ -3063,7 +3029,7 @@ int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD
DWORD nAttribute = (nHumanAttribute & Human68k::AT_READONLY) |
(f.GetAttribute() & ~Human68k::AT_READONLY);
if (f.GetAttribute() != nAttribute) {
struct stat sb;
struct stat sb; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (stat(S2U(f.GetPath()), &sb))
return FS_FILENOTFND;
mode_t m = sb.st_mode & 0777;
@ -3100,7 +3066,7 @@ int CFileSys::Files(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests
// Release if memory with the same key already exists
CHostFiles* pHostFiles = m_cFiles.Search(nKey);
if (pHostFiles != NULL) {
if (pHostFiles != nullptr) {
m_cFiles.Free(pHostFiles);
}
@ -3136,7 +3102,7 @@ int CFileSys::Files(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests
// Allocate buffer
pHostFiles = m_cFiles.Alloc(nKey);
if (pHostFiles == NULL)
if (pHostFiles == nullptr)
return FS_OUTOFMEM;
// Directory check
@ -3201,7 +3167,7 @@ int CFileSys::NFiles(DWORD nUnit, DWORD nKey, Human68k::files_t* pFiles)
// Find buffer
CHostFiles* pHostFiles = m_cFiles.Search(nKey);
if (pHostFiles == NULL)
if (pHostFiles == nullptr)
return FS_INVALIDPTR;
// Find file
@ -3250,7 +3216,7 @@ int CFileSys::Create(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamest
return FS_FATAL_WRITEPROTECT;
// Release if memory with the same key already exists
if (m_cFcb.Search(nKey) != NULL)
if (m_cFcb.Search(nKey) != nullptr)
return FS_INVALIDPTR;
// Generate path name
@ -3267,7 +3233,7 @@ int CFileSys::Create(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamest
// Store path name
CHostFcb* pHostFcb = m_cFcb.Alloc(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_OUTOFMEM;
pHostFcb->SetFilename(f.GetPath());
pHostFcb->SetHumanPath(f.GetHumanPath());
@ -3318,10 +3284,12 @@ int CFileSys::Open(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests,
case Human68k::OP_FULL:
if (m_cEntry.isWriteProtect(nUnit))
return FS_FATAL_WRITEPROTECT;
break;
default: break;
}
// Release if memory with the same key already exists
if (m_cFcb.Search(nKey) != NULL)
if (m_cFcb.Search(nKey) != nullptr)
return FS_INVALIDPRM;
// Generate path name
@ -3340,7 +3308,7 @@ int CFileSys::Open(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests,
// Store path name
CHostFcb* pHostFcb = m_cFcb.Alloc(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_OUTOFMEM;
pHostFcb->SetFilename(f.GetPath());
pHostFcb->SetHumanPath(f.GetHumanPath());
@ -3381,7 +3349,7 @@ int CFileSys::Close(DWORD nUnit, DWORD nKey, Human68k::fcb_t* /* pFcb */)
// Throw error if memory with the same key does not exist
CHostFcb* pHostFcb = m_cFcb.Search(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_INVALIDPRM;
// File close and release memory
@ -3412,11 +3380,11 @@ int CFileSys::Read(DWORD nKey, Human68k::fcb_t* pFcb, BYTE* pBuffer, DWORD nSize
// Throw error if memory with the same key does not exist
CHostFcb* pHostFcb = m_cFcb.Search(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_NOTOPENED;
// Confirm the existence of the buffer
if (pBuffer == NULL) {
if (pBuffer == nullptr) {
m_cFcb.Free(pHostFcb);
return FS_INVALIDFUNC;
}
@ -3452,7 +3420,7 @@ int CFileSys::Write(DWORD nKey, Human68k::fcb_t* pFcb, const BYTE* pBuffer, DWOR
// Throw error if memory with the same key does not exist
CHostFcb* pHostFcb = m_cFcb.Search(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_NOTOPENED;
DWORD nResult;
@ -3469,7 +3437,7 @@ int CFileSys::Write(DWORD nKey, Human68k::fcb_t* pFcb, const BYTE* pBuffer, DWOR
nResult = 0;
} else {
// Confirm the existence of the buffer
if (pBuffer == NULL) {
if (pBuffer == nullptr) {
m_cFcb.Free(pHostFcb);
return FS_INVALIDFUNC;
}
@ -3507,7 +3475,7 @@ int CFileSys::Seek(DWORD nKey, Human68k::fcb_t* pFcb, DWORD nSeek, int nOffset)
// Throw error if memory with the same key does not exist
CHostFcb* pHostFcb = m_cFcb.Search(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_NOTOPENED;
// Parameter check
@ -3562,7 +3530,7 @@ DWORD CFileSys::TimeStamp(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb, DWORD
// Throw error if memory with the same key does not exist
CHostFcb* pHostFcb = m_cFcb.Search(nKey);
if (pHostFcb == NULL)
if (pHostFcb == nullptr)
return FS_NOTOPENED;
// Set time stamp
@ -3584,7 +3552,7 @@ DWORD CFileSys::TimeStamp(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb, DWORD
/// $50 - Get capacity
//
//---------------------------------------------------------------------------
int CFileSys::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity)
int CFileSys::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const
{
ASSERT(pCapacity);
@ -3635,6 +3603,9 @@ int CFileSys::CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive)
case 8: // Eject inspection
return 1;
default:
break;
}
return FS_INVALIDFUNC;
@ -3648,7 +3619,7 @@ int CFileSys::CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive)
/// Therefore, treat even a unit out of bounds as normal operation.
//
//---------------------------------------------------------------------------
int CFileSys::GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb)
int CFileSys::GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb) const
{
ASSERT(pDpb);
@ -3703,7 +3674,7 @@ int CFileSys::GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb)
DWORD nData = cap.sectors * 3;
// Set DPB
pDpb->sector_size = (WORD)cap.bytes; // Bytes per sector
pDpb->sector_size = cap.bytes; // Bytes per sector
pDpb->cluster_size =
(BYTE)(cap.sectors - 1); // Sectors per cluster - 1
pDpb->shift = (BYTE)nShift; // Number of cluster → sector shifts
@ -3713,7 +3684,7 @@ int CFileSys::GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb)
pDpb->file_max =
(WORD)(cap.sectors * cap.bytes / 0x20); // Number of files in the root directory
pDpb->data_sector = (WORD)nData; // First sector number of data memory
pDpb->cluster_max = (WORD)cap.clusters; // Total number of clusters + 1
pDpb->cluster_max = cap.clusters; // Total number of clusters + 1
pDpb->root_sector = (WORD)nRoot; // First sector number of the root directory
pDpb->media = media; // Media byte
@ -3754,7 +3725,7 @@ int CFileSys::DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize)
}
// Access pseudo-directory entry
CHostFiles* pHostFiles = m_cFiles.Search(nSector);
const CHostFiles* pHostFiles = m_cFiles.Search(nSector);
if (pHostFiles) {
// Generate pseudo-directory entry
Human68k::dirent_t* dir = (Human68k::dirent_t*)pBuffer;
@ -3810,9 +3781,8 @@ int CFileSys::DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize)
/// $54 - Write sector
//
//---------------------------------------------------------------------------
int CFileSys::DiskWrite(DWORD nUnit)
int CFileSys::DiskWrite(DWORD nUnit) const
{
// Unit check
if (nUnit >= DriveMax)
return FS_FATAL_INVALIDUNIT;
@ -3869,6 +3839,9 @@ int CFileSys::Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl)
case 1:
// Dummy for Human68k compatibility
return 0;
default:
return FS_NOTIOCTRL;
}
break;
@ -3886,6 +3859,9 @@ int CFileSys::Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl)
// Get options
pIoctrl->param = GetOption();
return 0;
default:
break;
}
return FS_NOTIOCTRL;
@ -3896,7 +3872,7 @@ int CFileSys::Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl)
/// $56 - Flush
//
//---------------------------------------------------------------------------
int CFileSys::Flush(DWORD nUnit)
int CFileSys::Flush(DWORD nUnit) const
{
// Unit check
@ -3914,7 +3890,7 @@ int CFileSys::Flush(DWORD nUnit)
/// $57 - Media change check
//
//---------------------------------------------------------------------------
int CFileSys::CheckMedia(DWORD nUnit)
int CFileSys::CheckMedia(DWORD nUnit) const
{
// Unit check
@ -3939,7 +3915,7 @@ int CFileSys::CheckMedia(DWORD nUnit)
/// $58 - Lock
//
//---------------------------------------------------------------------------
int CFileSys::Lock(DWORD nUnit)
int CFileSys::Lock(DWORD nUnit) const
{
// Unit check
@ -4040,6 +4016,8 @@ void CFileSys::InitOption(const Human68k::argument_t* pArgument)
case 'h': nBit = WINDRV_OPT_REDUCED_HYPHENS; break;
case 'x': nBit = WINDRV_OPT_REDUCED_BADCHAR; break;
case 's': nBit = WINDRV_OPT_REDUCED_SPACE; break;
default: break;
}
if (nMode)

View File

@ -536,7 +536,7 @@ public:
///< Find file name
const CHostFilename* FindFilenameWildcard(const BYTE* szHuman, DWORD nHumanAttribute, find_t* pFind) const;
///< Find file name (with support for wildcards)
BOOL isRefresh(); ///< Check that the file change has been done
BOOL isRefresh() const; ///< Check that the file change has been done
void Refresh(); ///< Refresh file
void Backup(); /// Backup the time stamp on the host side
void Restore() const; /// Restore the time stamp on the host side
@ -584,7 +584,7 @@ private:
//===========================================================================
class CHostFiles {
public:
CHostFiles() { SetKey(0); Init(); }
CHostFiles() { SetKey(0); }
void Init();
void SetKey(DWORD nKey) { m_nKey = nKey; } ///< Set search key
@ -594,9 +594,8 @@ public:
void SetPathWildcard() { m_nHumanWildcard = 1; } ///< Enable file search using wildcards
void SetPathOnly() { m_nHumanWildcard = 0xFF; } ///< Enable only path names
BOOL isPathOnly() const { return m_nHumanWildcard == 0xFF; } ///< Check if set to only path names
void SetAttribute(DWORD nHumanAttribute) { m_nHumanAttribute = nHumanAttribute; }
///< Set search attribute
BOOL Find(DWORD nUnit, class CHostEntry* pEntry); ///< Find files on the Human68k side, generating data on the host side
void SetAttribute(DWORD nHumanAttribute) { m_nHumanAttribute = nHumanAttribute; } ///< Set search attribute
BOOL Find(DWORD nUnit, class CHostEntry* pEntry) ; ///< Find files on the Human68k side, generating data on the host side
const CHostFilename* Find(CHostPath* pPath); ///< Find file name
void SetEntry(const CHostFilename* pFilename); ///< Store search results on the Human68k side
void SetResult(const TCHAR* szPath); ///< Set names on the host side
@ -676,12 +675,12 @@ public:
BOOL Create(DWORD nHumanAttribute, BOOL bForce); ///< Create file
BOOL Open(); ///< Open file
BOOL Rewind(DWORD nOffset); ///< Seek file
BOOL Rewind(DWORD nOffset) const; ///< Seek file
DWORD Read(BYTE* pBuffer, DWORD nSize); ///< Read file
DWORD Write(const BYTE* pBuffer, DWORD nSize); ///< Write file
BOOL Truncate(); ///< Truncate file
BOOL Truncate() const; ///< Truncate file
DWORD Seek(DWORD nOffset, DWORD nHumanSeek); ///< Seek file
BOOL TimeStamp(DWORD nHumanTime); ///< Set file time stamp
BOOL TimeStamp(DWORD nHumanTime) const; ///< Set file time stamp
BOOL Close(); ///< Close file
private:
@ -738,7 +737,7 @@ public:
BOOL isWriteProtect() const { return m_bWriteProtect; }
BOOL isEnable() const { return m_bEnable; } ///< Is it accessible?
BOOL isMediaOffline();
BOOL isMediaOffline() const;
BYTE GetMediaByte() const;
DWORD GetStatus() const;
void SetEnable(BOOL bEnable); ///< Set media status
@ -751,9 +750,9 @@ public:
BOOL GetCapacityCache(Human68k::capacity_t* pCapacity) const; ///< Get capacity from cache
// Cache operations
void CleanCache(); ///< Update all cache
void CleanCache() const; ///< Update all cache
void CleanCache(const BYTE* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(const BYTE* szHumanPath); ///< Update all cache below the specified path
void CleanCacheChild(const BYTE* szHumanPath) const; ///< Update all cache below the specified path
void DeleteCache(const BYTE* szHumanPath); ///< Delete the cache for the specified path
CHostPath* FindCache(const BYTE* szHuman); ///< Inspect if the specified path is cached
CHostPath* CopyCache(CHostFiles* pFiles); ///< Acquire the host side name on the basis of cache information
@ -765,9 +764,6 @@ private:
static const BYTE* SeparateCopyFilename(const BYTE* szHuman, BYTE* szBuffer);
///< Split and copy the first element of the Human68k full path name
void Lock() {}
void Unlock() {}
/// For memory management
struct ring_t {
CRing r;
@ -802,21 +798,21 @@ public:
void CleanCache(DWORD nUnit, const BYTE* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath); ///< Update cache below the specified path
void DeleteCache(DWORD nUnit, const BYTE* szHumanPath); ///< Delete cache for the specified path
BOOL Find(DWORD nUnit, CHostFiles* pFiles); ///< Find host side name (path + file name (can be abbreviated) + attribute)
BOOL Find(DWORD nUnit, CHostFiles* pFiles) const; ///< Find host side name (path + file name (can be abbreviated) + attribute)
void ShellNotify(DWORD nEvent, const TCHAR* szPath); ///< Notify status change in the host side file system
// Drive object operations
void SetDrv(DWORD nUnit, CHostDrv* pDrv);
BOOL isWriteProtect(DWORD nUnit) const;
BOOL isEnable(DWORD nUnit) const; ///< Is it accessible?
BOOL isMediaOffline(DWORD nUnit);
BOOL isMediaOffline(DWORD nUnit) const;
BYTE GetMediaByte(DWORD nUnit) const;
DWORD GetStatus(DWORD nUnit) const; ///< Get drive status
BOOL CheckMedia(DWORD nUnit); ///< Media change check
BOOL CheckMedia(DWORD nUnit) const; ///< Media change check
void Eject(DWORD nUnit);
void GetVolume(DWORD nUnit, TCHAR* szLabel); ///< Get volume label
BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const; ///< Get volume label from cache
DWORD GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity);
DWORD GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const;
BOOL GetCapacityCache(DWORD nUnit, Human68k::capacity_t* pCapacity) const;
///< Get cluster size from cache
@ -864,7 +860,7 @@ class CFileSys
{
public:
CFileSys();
virtual ~CFileSys() {};
virtual ~CFileSys() = default;
void Reset(); ///< Reset (close all)
void Init(); ///< Initialization (device startup and load)
@ -894,22 +890,20 @@ public:
int Seek(DWORD nKey, Human68k::fcb_t* pFcb, DWORD nSeek, int nOffset); ///< $4E - Seek file
DWORD TimeStamp(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb, DWORD nHumanTime);
///< $4F - Get / set file timestamp
int GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity); ///< $50 - Get capacity
int GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const; ///< $50 - Get capacity
int CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive); ///< $51 - Inspect / control drive status
int GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb); ///< $52 - Get DPB
int GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb) const; ///< $52 - Get DPB
int DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize); ///< $53 - Read sectors
int DiskWrite(DWORD nUnit); ///< $54 - Write sectors
int DiskWrite(DWORD nUnit) const; ///< $54 - Write sectors
int Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl); ///< $55 - IOCTRL
int Flush(DWORD nUnit); ///< $56 - Flush
int CheckMedia(DWORD nUnit); ///< $57 - Media change check
int Lock(DWORD nUnit); ///< $58 - Lock
int Flush(DWORD nUnit) const; ///< $56 - Flush
int CheckMedia(DWORD nUnit) const; ///< $57 - Media change check
int Lock(DWORD nUnit) const; ///< $58 - Lock
void SetOption(DWORD nOption); ///< Set option
DWORD GetOption() const { return m_nOption; } ///< Get option
DWORD GetDefault() const { return m_nOptionDefault; } ///< Get default options
static DWORD GetFileOption() { return g_nOption; } ///< Get file name change option
void ShellNotify(DWORD nEvent, const TCHAR* szPath)
{ m_cEntry.ShellNotify(nEvent, szPath); } ///< Notify host side file system status change
enum {
DriveMax = CHostEntry::DriveMax ///< Max number of drive candidates

View File

@ -39,12 +39,12 @@ static bool br_setif(int br_socket_fd, const char* bridgename, const char* ifnam
struct ifreq ifr;
ifr.ifr_ifindex = if_nametoindex(ifname);
if (ifr.ifr_ifindex == 0) {
LOGERROR("Can't if_nametoindex: %s", strerror(errno));
LOGERROR("Can't if_nametoindex: %s", strerror(errno))
return false;
}
strncpy(ifr.ifr_name, bridgename, IFNAMSIZ);
if (ioctl(br_socket_fd, add ? SIOCBRADDIF : SIOCBRDELIF, &ifr) < 0) {
LOGERROR("Can't ioctl %s: %s", add ? "SIOCBRADDIF" : "SIOCBRDELIF", strerror(errno));
LOGERROR("Can't ioctl %s: %s", add ? "SIOCBRADDIF" : "SIOCBRDELIF", strerror(errno))
return false;
}
return true;
@ -55,7 +55,7 @@ static bool ip_link(int fd, const char* ifname, bool up) {
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1); // Need to save room for null terminator
int err = ioctl(fd, SIOCGIFFLAGS, &ifr);
if (err) {
LOGERROR("Can't ioctl SIOCGIFFLAGS: %s", strerror(errno));
LOGERROR("Can't ioctl SIOCGIFFLAGS: %s", strerror(errno))
return false;
}
ifr.ifr_flags &= ~IFF_UP;
@ -64,7 +64,7 @@ static bool ip_link(int fd, const char* ifname, bool up) {
}
err = ioctl(fd, SIOCSIFFLAGS, &ifr);
if (err) {
LOGERROR("Can't ioctl SIOCSIFFLAGS: %s", strerror(errno));
LOGERROR("Can't ioctl SIOCSIFFLAGS: %s", strerror(errno))
return false;
}
return true;
@ -93,7 +93,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
unordered_map<string, string> params = const_params;
if (params.count("interfaces")) {
LOGWARN("You are using the deprecated 'interfaces' parameter. "
"Provide the interface list and the IP address/netmask with the 'interface' and 'inet' parameters");
"Provide the interface list and the IP address/netmask with the 'interface' and 'inet' parameters")
// TODO Remove the deprecated syntax in a future version
const string& interfaces = params["interfaces"];
@ -111,14 +111,14 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
}
this->inet = params["inet"];
LOGTRACE("Opening Tap device");
LOGTRACE("Opening Tap device")
// TAP device initilization
if ((m_hTAP = open("/dev/net/tun", O_RDWR)) < 0) {
LOGERROR("Can't open tun: %s", strerror(errno));
LOGERROR("Can't open tun: %s", strerror(errno))
return false;
}
LOGTRACE("Opened tap device %d",m_hTAP);
LOGTRACE("Opened tap device %d",m_hTAP)
// IFF_NO_PI for no extra packet information
struct ifreq ifr;
@ -127,21 +127,21 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
char dev[IFNAMSIZ] = "ras0";
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
LOGTRACE("Going to open %s", ifr.ifr_name);
LOGTRACE("Going to open %s", ifr.ifr_name)
int ret = ioctl(m_hTAP, TUNSETIFF, (void *)&ifr);
if (ret < 0) {
LOGERROR("Can't ioctl TUNSETIFF: %s", strerror(errno));
LOGERROR("Can't ioctl TUNSETIFF: %s", strerror(errno))
close(m_hTAP);
return false;
}
LOGTRACE("Return code from ioctl was %d", ret);
LOGTRACE("Return code from ioctl was %d", ret)
int ip_fd = socket(PF_INET, SOCK_DGRAM, 0);
if (ip_fd < 0) {
LOGERROR("Can't open ip socket: %s", strerror(errno));
LOGERROR("Can't open ip socket: %s", strerror(errno))
close(m_hTAP);
return false;
@ -149,7 +149,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
int br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (br_socket_fd < 0) {
LOGERROR("Can't open bridge socket: %s", strerror(errno));
LOGERROR("Can't open bridge socket: %s", strerror(errno))
close(m_hTAP);
close(ip_fd);
@ -160,35 +160,35 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
string sys_file = "/sys/class/net/";
sys_file += BRIDGE_NAME;
if (access(sys_file.c_str(), F_OK)) {
LOGINFO("%s is not yet available", BRIDGE_NAME);
LOGINFO("%s is not yet available", BRIDGE_NAME)
LOGTRACE("Checking which interface is available for creating the bridge");
LOGTRACE("Checking which interface is available for creating the bridge")
string bridge_interface;
for (const string& interface : interfaces) {
if (is_interface_up(interface)) {
LOGTRACE("%s", string("Interface " + interface + " is up").c_str());
LOGTRACE("%s", string("Interface " + interface + " is up").c_str())
bridge_interface = interface;
break;
}
else {
LOGTRACE("%s", string("Interface " + interface + " is not available or is not up").c_str());
LOGTRACE("%s", string("Interface " + interface + " is not available or is not up").c_str())
}
}
if (bridge_interface.empty()) {
LOGERROR("No interface is up, not creating bridge");
LOGERROR("No interface is up, not creating bridge")
return false;
}
LOGINFO("Creating %s for interface %s", BRIDGE_NAME, bridge_interface.c_str());
LOGINFO("Creating %s for interface %s", BRIDGE_NAME, bridge_interface.c_str())
if (bridge_interface == "eth0") {
LOGTRACE("brctl addbr %s", BRIDGE_NAME);
LOGTRACE("brctl addbr %s", BRIDGE_NAME)
if ((ret = ioctl(br_socket_fd, SIOCBRADDBR, BRIDGE_NAME)) < 0) {
LOGERROR("Can't ioctl SIOCBRADDBR: %s", strerror(errno));
if (ioctl(br_socket_fd, SIOCBRADDBR, BRIDGE_NAME) < 0) {
LOGERROR("Can't ioctl SIOCBRADDBR: %s", strerror(errno))
close(m_hTAP);
close(ip_fd);
@ -196,7 +196,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
return false;
}
LOGTRACE("brctl addif %s %s", BRIDGE_NAME, bridge_interface.c_str());
LOGTRACE("brctl addif %s %s", BRIDGE_NAME, bridge_interface.c_str())
if (!br_setif(br_socket_fd, BRIDGE_NAME, bridge_interface.c_str(), true)) {
close(m_hTAP);
@ -214,7 +214,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
int m;
if (!GetAsInt(inet.substr(separatorPos + 1), m) || m < 8 || m > 32) {
LOGERROR("Invalid CIDR netmask notation '%s'", inet.substr(separatorPos + 1).c_str());
LOGERROR("Invalid CIDR netmask notation '%s'", inet.substr(separatorPos + 1).c_str())
close(m_hTAP);
close(ip_fd);
@ -230,10 +230,10 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
netmask = buf;
}
LOGTRACE("brctl addbr %s", BRIDGE_NAME);
LOGTRACE("brctl addbr %s", BRIDGE_NAME)
if ((ret = ioctl(br_socket_fd, SIOCBRADDBR, BRIDGE_NAME)) < 0) {
LOGERROR("Can't ioctl SIOCBRADDBR: %s", strerror(errno));
if (ioctl(br_socket_fd, SIOCBRADDBR, BRIDGE_NAME) < 0) {
LOGERROR("Can't ioctl SIOCBRADDBR: %s", strerror(errno))
close(m_hTAP);
close(ip_fd);
@ -244,9 +244,9 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
struct ifreq ifr_a;
ifr_a.ifr_addr.sa_family = AF_INET;
strncpy(ifr_a.ifr_name, BRIDGE_NAME, IFNAMSIZ);
struct sockaddr_in* addr = (struct sockaddr_in*)&ifr_a.ifr_addr;
if (inet_pton(AF_INET, address.c_str(), &addr->sin_addr) != 1) {
LOGERROR("Can't convert '%s' into a network address: %s", address.c_str(), strerror(errno));
if (auto addr = (struct sockaddr_in*)&ifr_a.ifr_addr;
inet_pton(AF_INET, address.c_str(), &addr->sin_addr) != 1) {
LOGERROR("Can't convert '%s' into a network address: %s", address.c_str(), strerror(errno))
close(m_hTAP);
close(ip_fd);
@ -257,9 +257,9 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
struct ifreq ifr_n;
ifr_n.ifr_addr.sa_family = AF_INET;
strncpy(ifr_n.ifr_name, BRIDGE_NAME, IFNAMSIZ);
struct sockaddr_in* mask = (struct sockaddr_in*)&ifr_n.ifr_addr;
if (inet_pton(AF_INET, netmask.c_str(), &mask->sin_addr) != 1) {
LOGERROR("Can't convert '%s' into a netmask: %s", netmask.c_str(), strerror(errno));
if (auto mask = (struct sockaddr_in*)&ifr_n.ifr_addr;
inet_pton(AF_INET, netmask.c_str(), &mask->sin_addr) != 1) {
LOGERROR("Can't convert '%s' into a netmask: %s", netmask.c_str(), strerror(errno))
close(m_hTAP);
close(ip_fd);
@ -267,10 +267,10 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
return false;
}
LOGTRACE("ip address add %s dev %s", inet.c_str(), BRIDGE_NAME);
LOGTRACE("ip address add %s dev %s", inet.c_str(), BRIDGE_NAME)
if (ioctl(ip_fd, SIOCSIFADDR, &ifr_a) < 0 || ioctl(ip_fd, SIOCSIFNETMASK, &ifr_n) < 0) {
LOGERROR("Can't ioctl SIOCSIFADDR or SIOCSIFNETMASK: %s", strerror(errno));
LOGERROR("Can't ioctl SIOCSIFADDR or SIOCSIFNETMASK: %s", strerror(errno))
close(m_hTAP);
close(ip_fd);
@ -279,7 +279,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
}
}
LOGTRACE("ip link set dev %s up", BRIDGE_NAME);
LOGTRACE("ip link set dev %s up", BRIDGE_NAME)
if (!ip_link(ip_fd, BRIDGE_NAME, true)) {
close(m_hTAP);
@ -290,10 +290,10 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
}
else
{
LOGINFO("%s is already available", BRIDGE_NAME);
LOGINFO("%s is already available", BRIDGE_NAME)
}
LOGTRACE("ip link set ras0 up");
LOGTRACE("ip link set ras0 up")
if (!ip_link(ip_fd, "ras0", true)) {
close(m_hTAP);
@ -302,7 +302,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
return false;
}
LOGTRACE("brctl addif %s ras0", BRIDGE_NAME);
LOGTRACE("brctl addif %s ras0", BRIDGE_NAME)
if (!br_setif(br_socket_fd, BRIDGE_NAME, "ras0", true)) {
close(m_hTAP);
@ -312,18 +312,18 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
}
// Get MAC address
LOGTRACE("Getting the MAC address");
LOGTRACE("Getting the MAC address")
ifr.ifr_addr.sa_family = AF_INET;
if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) {
LOGERROR("Can't ioctl SIOCGIFHWADDR: %s", strerror(errno));
if (ioctl(m_hTAP, SIOCGIFHWADDR, &ifr) < 0) {
LOGERROR("Can't ioctl SIOCGIFHWADDR: %s", strerror(errno))
close(m_hTAP);
close(ip_fd);
close(br_socket_fd);
return false;
}
LOGTRACE("Got the MAC");
LOGTRACE("Got the MAC")
// Save MAC address
memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr));
@ -331,7 +331,7 @@ bool CTapDriver::Init(const unordered_map<string, string>& const_params)
close(ip_fd);
close(br_socket_fd);
LOGINFO("Tap device %s created", ifr.ifr_name);
LOGINFO("Tap device %s created", ifr.ifr_name)
return true;
}
@ -344,24 +344,23 @@ void CTapDriver::OpenDump(const Filepath& path) {
pcap_dump_close(m_pcap_dumper);
}
m_pcap_dumper = pcap_dump_open(m_pcap, path.GetPath());
if (m_pcap_dumper == NULL) {
LOGERROR("Can't open pcap file: %s", pcap_geterr(m_pcap));
if (m_pcap_dumper == nullptr) {
LOGERROR("Can't open pcap file: %s", pcap_geterr(m_pcap))
throw io_exception("Can't open pcap file");
}
LOGTRACE("%s Opened %s for dumping", __PRETTY_FUNCTION__, path.GetPath());
LOGTRACE("%s Opened %s for dumping", __PRETTY_FUNCTION__, path.GetPath())
}
void CTapDriver::Cleanup()
{
int br_socket_fd = -1;
if ((br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
LOGERROR("Can't open bridge socket: %s", strerror(errno));
if (int br_socket_fd; (br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
LOGERROR("Can't open bridge socket: %s", strerror(errno))
} else {
LOGDEBUG("brctl delif %s ras0", BRIDGE_NAME);
LOGDEBUG("brctl delif %s ras0", BRIDGE_NAME)
if (!br_setif(br_socket_fd, BRIDGE_NAME, "ras0", false)) {
LOGWARN("Warning: Removing ras0 from the bridge failed.");
LOGWARN("You may need to manually remove the ras0 tap device from the bridge");
LOGWARN("Warning: Removing ras0 from the bridge failed.")
LOGWARN("You may need to manually remove the ras0 tap device from the bridge")
}
close(br_socket_fd);
}
@ -385,7 +384,7 @@ void CTapDriver::Cleanup()
bool CTapDriver::Enable(){
int fd = socket(PF_INET, SOCK_DGRAM, 0);
LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__);
LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__)
bool result = ip_link(fd, "ras0", true);
close(fd);
return result;
@ -393,14 +392,14 @@ bool CTapDriver::Enable(){
bool CTapDriver::Disable(){
int fd = socket(PF_INET, SOCK_DGRAM, 0);
LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__);
LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__)
bool result = ip_link(fd, "ras0", false);
close(fd);
return result;
}
void CTapDriver::Flush(){
LOGTRACE("%s", __PRETTY_FUNCTION__);
LOGTRACE("%s", __PRETTY_FUNCTION__)
while(PendingPackets()){
(void)Rx(m_garbage_buffer);
}
@ -420,7 +419,7 @@ void CTapDriver::GetMacAddr(BYTE *mac)
//---------------------------------------------------------------------------
bool CTapDriver::PendingPackets()
{
struct pollfd fds;
pollfd fds;
ASSERT(m_hTAP != -1);
@ -429,7 +428,7 @@ bool CTapDriver::PendingPackets()
fds.events = POLLIN | POLLERR;
fds.revents = 0;
poll(&fds, 1, 0);
LOGTRACE("%s %u revents", __PRETTY_FUNCTION__, fds.revents);
LOGTRACE("%s %u revents", __PRETTY_FUNCTION__, fds.revents)
if (!(fds.revents & POLLIN)) {
return false;
}else {
@ -467,7 +466,7 @@ int CTapDriver::Rx(BYTE *buf)
// Receive
DWORD dwReceived = read(m_hTAP, buf, ETH_FRAME_LEN);
if (dwReceived == (DWORD)-1) {
LOGWARN("%s Error occured while receiving an packet", __PRETTY_FUNCTION__);
LOGWARN("%s Error occured while receiving an packet", __PRETTY_FUNCTION__)
return 0;
}
@ -483,7 +482,7 @@ int CTapDriver::Rx(BYTE *buf)
buf[dwReceived + 2] = (BYTE)((crc >> 16) & 0xFF);
buf[dwReceived + 3] = (BYTE)((crc >> 24) & 0xFF);
LOGDEBUG("%s CRC is %08X - %02X %02X %02X %02X\n", __PRETTY_FUNCTION__, crc, buf[dwReceived+0], buf[dwReceived+1], buf[dwReceived+2], buf[dwReceived+3]);
LOGDEBUG("%s CRC is %08X - %02X %02X %02X %02X\n", __PRETTY_FUNCTION__, crc, buf[dwReceived+0], buf[dwReceived+1], buf[dwReceived+2], buf[dwReceived+3])
// Add FCS size to the received message size
dwReceived += 4;
@ -495,9 +494,9 @@ int CTapDriver::Rx(BYTE *buf)
.caplen = dwReceived,
.len = dwReceived
};
gettimeofday(&h.ts, NULL);
gettimeofday(&h.ts, nullptr);
pcap_dump((u_char*)m_pcap_dumper, &h, buf);
LOGTRACE("%s Dumped %d byte packet (first byte: %02x last byte: %02x)", __PRETTY_FUNCTION__, (unsigned int)dwReceived, buf[0], buf[dwReceived-1]);
LOGTRACE("%s Dumped %d byte packet (first byte: %02x last byte: %02x)", __PRETTY_FUNCTION__, (unsigned int)dwReceived, buf[0], buf[dwReceived-1])
}
// Return the number of bytes
@ -519,9 +518,9 @@ int CTapDriver::Tx(const BYTE *buf, int len)
.caplen = (bpf_u_int32)len,
.len = (bpf_u_int32)len,
};
gettimeofday(&h.ts, NULL);
gettimeofday(&h.ts, nullptr);
pcap_dump((u_char*)m_pcap_dumper, &h, buf);
LOGTRACE("%s Dumped %d byte packet (first byte: %02x last byte: %02x)", __PRETTY_FUNCTION__, (unsigned int)h.len, buf[0], buf[h.len-1]);
LOGTRACE("%s Dumped %d byte packet (first byte: %02x last byte: %02x)", __PRETTY_FUNCTION__, (unsigned int)h.len, buf[0], buf[h.len-1])
}
// Start sending

View File

@ -38,7 +38,7 @@ private:
friend class SCSIBR;
CTapDriver() : interfaces({}), inet({}) {}
~CTapDriver() {}
~CTapDriver() = default;
bool Init(const unordered_map<string, string>&);

View File

@ -16,15 +16,12 @@
unordered_set<Device *> Device::devices;
Device::Device(const string& type)
Device::Device(const string& t) : type(t)
{
assert(type.length() == 4);
devices.insert(this);
this->type = type;
vendor = DEFAULT_VENDOR;
char rev[5];
sprintf(rev, "%02d%02d", rascsi_major_version, rascsi_minor_version);
revision = rev;
@ -42,46 +39,46 @@ void Device::Reset()
reset = false;
}
void Device::SetProtected(bool write_protected)
void Device::SetProtected(bool b)
{
if (!read_only) {
this->write_protected = write_protected;
write_protected = b;
}
}
void Device::SetVendor(const string& vendor)
void Device::SetVendor(const string& v)
{
if (vendor.empty() || vendor.length() > 8) {
throw illegal_argument_exception("Vendor '" + vendor + "' must be between 1 and 8 characters");
if (v.empty() || v.length() > 8) {
throw illegal_argument_exception("Vendor '" + v + "' must be between 1 and 8 characters");
}
this->vendor = vendor;
vendor = v;
}
void Device::SetProduct(const string& product, bool force)
void Device::SetProduct(const string& p, bool force)
{
if (p.empty() || p.length() > 16) {
throw illegal_argument_exception("Product '" + p + "' must be between 1 and 16 characters");
}
// Changing the device name is not SCSI compliant
if (!this->product.empty() && !force) {
if (!product.empty() && !force) {
return;
}
if (product.empty() || product.length() > 16) {
throw illegal_argument_exception("Product '" + product + "' must be between 1 and 16 characters");
}
this->product = product;
product = p;
}
void Device::SetRevision(const string& revision)
void Device::SetRevision(const string& r)
{
if (revision.empty() || revision.length() > 4) {
throw illegal_argument_exception("Revision '" + revision + "' must be between 1 and 4 characters");
if (r.empty() || r.length() > 4) {
throw illegal_argument_exception("Revision '" + r + "' must be between 1 and 4 characters");
}
this->revision = revision;
revision = r;
}
const string Device::GetPaddedName() const
string Device::GetPaddedName() const
{
string name = vendor;
name.append(8 - vendor.length(), ' ');
@ -95,33 +92,34 @@ const string Device::GetPaddedName() const
return name;
}
const string Device::GetParam(const string& key)
string Device::GetParam(const string& key) const
{
return params.find(key) != params.end() ? params[key] : "";
const auto& it = params.find(key);
return it == params.end() ? "" : it->second;
}
void Device::SetParams(const unordered_map<string, string>& set_params)
{
params = default_params;
for (const auto& param : set_params) {
for (const auto& [key, value] : set_params) {
// It is assumed that there are default parameters for all supported parameters
if (params.find(param.first) != params.end()) {
params[param.first] = param.second;
if (params.find(key) != params.end()) {
params[key] = value;
}
else {
LOGWARN("%s", string("Ignored unknown parameter '" + param.first + "'").c_str());
LOGWARN("%s", string("Ignored unknown parameter '" + key + "'").c_str())
}
}
}
void Device::SetStatusCode(int status_code)
void Device::SetStatusCode(int s)
{
if (status_code) {
LOGDEBUG("Error status: Sense Key $%02X, ASC $%02X, ASCQ $%02X", status_code >> 16, (status_code >> 8 &0xff), status_code & 0xff);
if (s) {
LOGDEBUG("Error status: Sense Key $%02X, ASC $%02X, ASCQ $%02X", s >> 16, (s >> 8 &0xff), s & 0xff)
}
this->status_code = status_code;
status_code = s;
}
bool Device::Start()

View File

@ -16,12 +16,12 @@
using namespace std;
#define DEFAULT_VENDOR "RaSCSI"
class Device
{
friend class DeviceFactory;
const string DEFAULT_VENDOR = "RaSCSI";
string type;
bool ready = false;
@ -57,7 +57,7 @@ class Device
int32_t lun = 0;
// Device identifier (for INQUIRY)
string vendor;
string vendor = DEFAULT_VENDOR;
string product;
string revision;
@ -84,16 +84,17 @@ protected:
int GetStatusCode() const { return status_code; }
const string GetParam(const string&);
string GetParam(const string&) const;
void SetParams(const unordered_map<string, string>&);
static unordered_set<Device *> devices;
Device(const string&);
virtual ~Device();
explicit Device(const string&);
public:
virtual ~Device();
// Override for device specific initializations, to be called after all device properties have been set
virtual bool Init(const unordered_map<string, string>&) { return true; };
@ -130,18 +131,18 @@ public:
int32_t GetLun() const { return lun; }
void SetLun(int32_t lun) { this->lun = lun; }
const string GetVendor() const { return vendor; }
string GetVendor() const { return vendor; }
void SetVendor(const string&);
const string GetProduct() const { return product; }
string GetProduct() const { return product; }
void SetProduct(const string&, bool = true);
const string GetRevision() const { return revision; }
string GetRevision() const { return revision; }
void SetRevision(const string&);
const string GetPaddedName() const;
string GetPaddedName() const;
bool SupportsParams() const { return supports_params; }
virtual bool SupportsFile() const { return !supports_params; }
void SupportsParams(bool supports_paams) { this->supports_params = supports_paams; }
const unordered_map<string, string> GetParams() const { return params; }
unordered_map<string, string> GetParams() const { return params; }
void SetDefaultParams(const unordered_map<string, string>& default_params) { this->default_params = default_params; }
void SetStatusCode(int);
@ -149,5 +150,7 @@ public:
bool Start();
void Stop();
virtual bool Eject(bool);
virtual void FlushCache() { }
virtual void FlushCache() {
// Devices with a cache have to implement this method
}
};

View File

@ -76,7 +76,7 @@ DeviceFactory& DeviceFactory::instance()
return instance;
}
void DeviceFactory::DeleteDevice(Device *device)
void DeviceFactory::DeleteDevice(const Device *device) const
{
auto iterpair = devices.equal_range(device->GetId());
@ -90,32 +90,32 @@ void DeviceFactory::DeleteDevice(Device *device)
}
}
void DeviceFactory::DeleteAllDevices()
void DeviceFactory::DeleteAllDevices() const
{
for (const auto& device : devices) {
delete device.second;
for (const auto& [id, device] : devices) {
delete device;
}
devices.clear();
}
const Device * DeviceFactory::GetDeviceByIdAndLun(int id, int lun) const
const Device * DeviceFactory::GetDeviceByIdAndLun(int i, int lun) const
{
for (const auto& device : devices) {
if (device.second->GetId() == id && device.second->GetLun() == lun) {
return device.second;
for (const auto& [id, device] : devices) {
if (device->GetId() == i && device->GetLun() == lun) {
return device;
}
}
return nullptr;
}
const list<Device *> DeviceFactory::GetAllDevices() const
list<Device *> DeviceFactory::GetAllDevices() const
{
list<Device *> result;
for (const auto& device : devices) {
result.push_back(device.second);
for (const auto& [id, device] : devices) {
result.push_back(device);
}
return result;
@ -135,9 +135,7 @@ string DeviceFactory::GetExtension(const string& filename) const
PbDeviceType DeviceFactory::GetTypeForFile(const string& filename) const
{
string ext = GetExtension(filename);
const auto& it = extension_mapping.find(ext);
const auto& it = extension_mapping.find(GetExtension(filename));
if (it != extension_mapping.end()) {
return it->second;
}
@ -168,14 +166,13 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
}
}
Device *device = nullptr;
unique_ptr<Device> device;
switch (type) {
case SCHD: {
string ext = GetExtension(filename);
if (ext == "hdn" || ext == "hdi" || ext == "nhd") {
device = new SCSIHD_NEC({ 512 });
if (string ext = GetExtension(filename); ext == "hdn" || ext == "hdi" || ext == "nhd") {
device = make_unique<SCSIHD_NEC>();
} else {
device = new SCSIHD(sector_sizes[SCHD], false);
device = make_unique<SCSIHD>(sector_sizes[SCHD], false);
// Some Apple tools require a particular drive identification
if (ext == "hda") {
@ -189,7 +186,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
}
case SCRM:
device = new SCSIHD(sector_sizes[SCRM], true);
device = make_unique<SCSIHD>(sector_sizes[SCRM], true);
device->SetProtectable(true);
device->SetStoppable(true);
device->SetRemovable(true);
@ -198,7 +195,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
break;
case SCMO:
device = new SCSIMO(sector_sizes[SCMO], geometries[SCMO]);
device = make_unique<SCSIMO>(sector_sizes[SCMO], geometries[SCMO]);
device->SetProtectable(true);
device->SetStoppable(true);
device->SetRemovable(true);
@ -207,7 +204,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
break;
case SCCD:
device = new SCSICD(sector_sizes[SCCD]);
device = make_unique<SCSICD>(sector_sizes[SCCD]);
device->SetReadOnly(true);
device->SetStoppable(true);
device->SetRemovable(true);
@ -216,14 +213,14 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
break;
case SCBR:
device = new SCSIBR();
device = make_unique<SCSIBR>();
device->SetProduct("SCSI HOST BRIDGE");
device->SupportsParams(true);
device->SetDefaultParams(default_params[SCBR]);
break;
case SCDP:
device = new SCSIDaynaPort();
device = make_unique<SCSIDaynaPort>();
// Since this is an emulation for a specific device the full INQUIRY data have to be set accordingly
device->SetVendor("Dayna");
device->SetProduct("SCSI/Link");
@ -233,14 +230,14 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
break;
case SCHS:
device = new HostServices();
device = make_unique<HostServices>();
// Since this is an emulation for a specific device the full INQUIRY data have to be set accordingly
device->SetVendor("RaSCSI");
device->SetProduct("Host Services");
break;
case SCLP:
device = new SCSIPrinter();
device = make_unique<SCSIPrinter>();
device->SetProduct("SCSI PRINTER");
device->SupportsParams(true);
device->SetDefaultParams(default_params[SCLP]);
@ -252,11 +249,15 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
assert(device != nullptr);
device->SetId(id);
Device *d = device.release();
devices.emplace(id, device);
if (d != nullptr) {
d->SetId(id);
return device;
devices.emplace(id, d);
}
return d;
}
const unordered_set<uint32_t>& DeviceFactory::GetSectorSizes(const string& type) const
@ -270,7 +271,7 @@ const unordered_set<uint32_t>& DeviceFactory::GetSectorSizes(const string& type)
return it->second;
}
const list<string> DeviceFactory::GetNetworkInterfaces() const
list<string> DeviceFactory::GetNetworkInterfaces() const
{
list<string> network_interfaces;
@ -283,15 +284,11 @@ const list<string> DeviceFactory::GetNetworkInterfaces() const
strcmp(tmp->ifa_name, "lo") && strcmp(tmp->ifa_name, "rascsi_bridge")) {
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifreq ifr = {};
strcpy(ifr.ifr_name, tmp->ifa_name);
if (!ioctl(fd, SIOCGIFFLAGS, &ifr)) {
// Only list interfaces that are up
if (ifr.ifr_flags & IFF_UP) {
network_interfaces.push_back(tmp->ifa_name);
}
// Only list interfaces that are up
if (!ioctl(fd, SIOCGIFFLAGS, &ifr) && ifr.ifr_flags & IFF_UP) {
network_interfaces.push_back(tmp->ifa_name);
}
close(fd);

View File

@ -21,7 +21,7 @@
using namespace std;
using namespace rascsi_interface;
typedef pair<uint32_t, uint32_t> Geometry;
using Geometry = pair<uint32_t, uint32_t>;
class Device;
@ -37,19 +37,19 @@ public:
static DeviceFactory& instance();
Device *CreateDevice(PbDeviceType, const string&, int);
void DeleteDevice(Device *);
void DeleteDevice(const Device *) const;
const Device *GetDeviceByIdAndLun(int, int) const;
const list<Device *> GetAllDevices() const;
list<Device *> GetAllDevices() const;
PbDeviceType GetTypeForFile(const string&) const;
const unordered_set<uint32_t>& GetSectorSizes(PbDeviceType type) { return sector_sizes[type]; }
const unordered_set<uint32_t>& GetSectorSizes(const string&) const;
const unordered_map<string, string>& GetDefaultParams(PbDeviceType type) { return default_params[type]; }
const list<string> GetNetworkInterfaces() const;
const unordered_map<string, PbDeviceType> GetExtensionMapping() const { return extension_mapping; }
list<string> GetNetworkInterfaces() const;
unordered_map<string, PbDeviceType> GetExtensionMapping() const { return extension_mapping; }
private:
void DeleteAllDevices();
void DeleteAllDevices() const;
unordered_map<PbDeviceType, unordered_set<uint32_t>> sector_sizes;

View File

@ -147,7 +147,7 @@ void Disk::Read(access_mode mode)
uint64_t start;
if (CheckAndGetStartAndCount(start, ctrl->blocks, mode)) {
ctrl->length = Read(ctrl->cmd, ctrl->buffer, start);
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, (int)ctrl->length);
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, (int)ctrl->length)
// Set next block
ctrl->next = start + 1;
@ -277,7 +277,7 @@ void Disk::PreventAllowMediumRemoval()
bool lock = ctrl->cmd[4] & 0x01;
LOGTRACE("%s", lock ? "Locking medium" : "Unlocking medium");
LOGTRACE("%s", lock ? "Locking medium" : "Unlocking medium")
SetLocked(lock);
@ -329,7 +329,7 @@ bool Disk::Eject(bool force)
// The image file for this drive is not in use anymore
// TODO This cast and the FileSupport class can be removed as soon as only disk-like devices inherit from Disk
FileSupport *file_support = dynamic_cast<FileSupport *>(this);
auto file_support = dynamic_cast<FileSupport *>(this);
if (file_support) {
file_support->UnreserveFile();
}
@ -473,7 +473,7 @@ int Disk::ModeSense10(const DWORD *cdb, BYTE *buf, int max_length)
return size;
}
void Disk::SetDeviceParameters(BYTE *buf)
void Disk::SetDeviceParameters(BYTE *buf) const
{
// DEVICE SPECIFIC PARAMETER
if (IsProtected()) {
@ -639,7 +639,7 @@ void Disk::Format(const DWORD *cdb)
// TODO Read more than one block in a single call. Currently blocked by the the track-oriented cache
int Disk::Read(const DWORD *, BYTE *buf, uint64_t block)
{
LOGTRACE("%s", __PRETTY_FUNCTION__);
LOGTRACE("%s", __PRETTY_FUNCTION__)
CheckReady();
@ -678,7 +678,7 @@ int Disk::WriteCheck(uint64_t block)
// TODO Write more than one block in a single call. Currently blocked by the track-oriented cache
void Disk::Write(const DWORD *, BYTE *buf, uint64_t block)
{
LOGTRACE("%s", __PRETTY_FUNCTION__);
LOGTRACE("%s", __PRETTY_FUNCTION__)
// Error if not ready
if (!IsReady()) {
@ -730,10 +730,10 @@ bool Disk::StartStop(const DWORD *cdb)
bool load = cdb[4] & 0x02;
if (load) {
LOGTRACE("%s", start ? "Loading medium" : "Ejecting medium");
LOGTRACE("%s", start ? "Loading medium" : "Ejecting medium")
}
else {
LOGTRACE("%s", start ? "Starting unit" : "Stopping unit");
LOGTRACE("%s", start ? "Starting unit" : "Stopping unit")
SetStopped(!start);
}
@ -908,7 +908,7 @@ void Disk::ValidateBlockAddress(access_mode mode) const
uint64_t capacity = GetBlockCount();
if (block > capacity) {
LOGTRACE("%s", ("Capacity of " + to_string(capacity) + " blocks exceeded: Trying to access block "
+ to_string(block)).c_str());
+ to_string(block)).c_str())
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::LBA_OUT_OF_RANGE);
}
}
@ -966,13 +966,12 @@ bool Disk::CheckAndGetStartAndCount(uint64_t& start, uint32_t& count, access_mod
}
}
LOGTRACE("%s READ/WRITE/VERIFY/SEEK command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, count);
LOGTRACE("%s READ/WRITE/VERIFY/SEEK command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, count)
// Check capacity
uint64_t capacity = GetBlockCount();
if (start > capacity || start + count > capacity) {
if (uint64_t capacity = GetBlockCount(); start > capacity || start + count > capacity) {
LOGTRACE("%s", ("Capacity of " + to_string(capacity) + " blocks exceeded: Trying to access block "
+ to_string(start) + ", block count " + to_string(count)).c_str());
+ to_string(start) + ", block count " + to_string(count)).c_str())
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::LBA_OUT_OF_RANGE);
}
@ -1047,7 +1046,7 @@ uint32_t Disk::GetConfiguredSectorSize() const
bool Disk::SetConfiguredSectorSize(uint32_t configured_sector_size)
{
DeviceFactory& device_factory = DeviceFactory::instance();
const DeviceFactory& device_factory = DeviceFactory::instance();
unordered_set<uint32_t> sector_sizes = device_factory.GetSectorSizes(GetType());
if (sector_sizes.find(configured_sector_size) == sector_sizes.end()) {

View File

@ -32,7 +32,7 @@
using namespace std;
class Disk : public ModePageDevice, ScsiBlockCommands
class Disk : public ModePageDevice, public ScsiBlockCommands
{
private:
@ -42,22 +42,22 @@ private:
unordered_set<uint32_t> sector_sizes;
uint32_t configured_sector_size = 0;
typedef struct {
using disk_t = struct {
uint32_t size; // Sector Size (9=512, 10=1024, 11=2048, 12=4096)
uint64_t blocks; // Total number of sectors
DiskCache *dcache; // Disk cache
off_t image_offset; // Offset to actual data
bool is_medium_changed;
} disk_t;
};
Dispatcher<Disk> dispatcher;
public:
Disk(const string&);
virtual ~Disk();
explicit Disk(const string&);
~Disk() override;
virtual bool Dispatch() override;
bool Dispatch() override;
void MediumChanged();
bool Eject(bool) override;
@ -76,7 +76,7 @@ public:
private:
typedef ModePageDevice super;
using super = ModePageDevice;
// Commands covered by the SCSI specifications (see https://www.t10.org/drafts.htm)
void StartStopUnit();
@ -95,7 +95,7 @@ private:
void Verify16();
void Seek();
void Seek10();
virtual void ReadCapacity10() override;
void ReadCapacity10() override;
void ReadCapacity16() override;
void Reserve();
void Release();
@ -123,7 +123,7 @@ protected:
virtual void Open(const Filepath&);
virtual void SetDeviceParameters(BYTE *);
virtual void SetDeviceParameters(BYTE *) const;
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
virtual void AddErrorPage(map<int, vector<BYTE>>&, bool) const;
virtual void AddFormatPage(map<int, vector<BYTE>>&, bool) const;

View File

@ -108,7 +108,7 @@ bool DiskTrack::Load(const Filepath& path)
if (dt.buffer == nullptr) {
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__);
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__)
}
dt.length = length;
}
@ -121,7 +121,7 @@ bool DiskTrack::Load(const Filepath& path)
if (dt.length != (DWORD)length) {
free(dt.buffer);
if (posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512)) {
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__);
LOGWARN("%s posix_memalign failed", __PRETTY_FUNCTION__)
}
dt.length = length;
}
@ -276,9 +276,9 @@ bool DiskTrack::Save(const Filepath& path)
bool DiskTrack::ReadSector(BYTE *buf, int sec) const
{
ASSERT(buf);
ASSERT((sec >= 0) & (sec < 0x100));
ASSERT((sec >= 0) && (sec < 0x100));
LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec);
LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec)
// Error if not initialized
if (!dt.init) {
return false;
@ -301,7 +301,7 @@ bool DiskTrack::ReadSector(BYTE *buf, int sec) const
bool DiskTrack::WriteSector(const BYTE *buf, int sec)
{
ASSERT(buf);
ASSERT((sec >= 0) & (sec < 0x100));
ASSERT((sec >= 0) && (sec < 0x100));
ASSERT(!dt.raw);
// Error if not initialized
@ -347,7 +347,7 @@ DiskCache::DiskCache(const Filepath& path, int size, uint32_t blocks, off_t imgo
ASSERT(imgoff >= 0);
// Cache work
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
cache[i].disktrk = nullptr;
cache[i].serial = 0;
}
@ -376,7 +376,7 @@ void DiskCache::SetRawMode(BOOL raw)
bool DiskCache::Save()
{
// Save track
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
// Is it a valid track?
if (cache[i].disktrk) {
// Save
@ -396,7 +396,7 @@ bool DiskCache::Save()
//---------------------------------------------------------------------------
bool DiskCache::GetCache(int index, int& track, DWORD& aserial) const
{
ASSERT((index >= 0) && (index < CacheMax));
ASSERT((index >= 0) && (index < CACHE_MAX));
// false if unused
if (!cache[index].disktrk) {
@ -413,7 +413,7 @@ bool DiskCache::GetCache(int index, int& track, DWORD& aserial) const
void DiskCache::Clear()
{
// Free the cache
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
if (cache[i].disktrk) {
delete cache[i].disktrk;
cache[i].disktrk = nullptr;
@ -432,8 +432,8 @@ bool DiskCache::ReadSector(BYTE *buf, int block)
int track = block >> 8;
// Get the track data
DiskTrack *disktrk = Assign(track);
if (!disktrk) {
const DiskTrack *disktrk = Assign(track);
if (disktrk == nullptr) {
return false;
}
@ -453,7 +453,7 @@ bool DiskCache::WriteSector(const BYTE *buf, int block)
// Get that track data
DiskTrack *disktrk = Assign(track);
if (!disktrk) {
if (disktrk == nullptr) {
return false;
}
@ -472,7 +472,7 @@ DiskTrack* DiskCache::Assign(int track)
ASSERT(track >= 0);
// First, check if it is already assigned
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
if (cache[i].disktrk) {
if (cache[i].disktrk->GetTrack() == track) {
// Track match
@ -483,7 +483,7 @@ DiskTrack* DiskCache::Assign(int track)
}
// Next, check for empty
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
if (!cache[i].disktrk) {
// Try loading
if (Load(i, track)) {
@ -504,7 +504,7 @@ DiskTrack* DiskCache::Assign(int track)
int c = 0;
// Compare candidate with serial and update to smaller one
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
ASSERT(cache[i].disktrk);
// Compare and update the existing serial
@ -540,7 +540,7 @@ DiskTrack* DiskCache::Assign(int track)
//---------------------------------------------------------------------------
bool DiskCache::Load(int index, int track, DiskTrack *disktrk)
{
ASSERT((index >= 0) && (index < CacheMax));
ASSERT((index >= 0) && (index < CACHE_MAX));
ASSERT(track >= 0);
ASSERT(!cache[index].disktrk);
@ -581,7 +581,7 @@ void DiskCache::UpdateSerialNumber()
}
// Clear serial of all caches (loop in 32bit)
for (int i = 0; i < CacheMax; i++) {
for (int i = 0; i < CACHE_MAX; i++) {
cache[i].serial = 0;
}
}

View File

@ -20,7 +20,7 @@
#include "filepath.h"
// Number of tracks to cache
#define CacheMax 16
static const int CACHE_MAX = 16;
class DiskTrack
{
@ -61,12 +61,11 @@ class DiskCache
{
public:
// Internal data definition
typedef struct {
using cache_t = struct {
DiskTrack *disktrk; // Disk Track
DWORD serial; // Serial
} cache_t;
};
public:
DiskCache(const Filepath& path, int size, uint32_t blocks, off_t imgoff = 0);
~DiskCache();
@ -82,11 +81,11 @@ private:
// Internal Management
void Clear(); // Clear all tracks
DiskTrack* Assign(int track); // Load track
bool Load(int index, int track, DiskTrack *disktrk = NULL); // Load track
bool Load(int index, int track, DiskTrack *disktrk = nullptr); // Load track
void UpdateSerialNumber(); // Update serial number
// Internal data
cache_t cache[CacheMax]; // Cache management
cache_t cache[CACHE_MAX]; // Cache management
DWORD serial; // Last serial number
Filepath sec_path; // Path
int sec_size; // Sector Size (8=256, 9=512, 10=1024, 11=2048, 12=4096)

View File

@ -26,20 +26,21 @@ public:
Dispatcher() : commands({}) {}
~Dispatcher()
{
for (auto const& command : commands) {
delete command.second;
for (auto const& [name, command] : commands) {
delete command;
}
}
typedef struct _command_t {
using operation = void (T::*)();
using command_t = struct _command_t {
const char* name;
void (T::*execute)();
operation execute;
_command_t(const char* _name, void (T::*_execute)()) : name(_name), execute(_execute) { };
} command_t;
_command_t(const char* _name, operation _execute) : name(_name), execute(_execute) { };
};
unordered_map<scsi_command, command_t*> commands;
void AddCommand(scsi_command opcode, const char* name, void (T::*execute)())
void AddCommand(scsi_command opcode, const char* name, operation execute)
{
commands[opcode] = new command_t(name, execute);
}
@ -48,7 +49,7 @@ public:
{
const auto& it = commands.find(static_cast<scsi_command>(cmd));
if (it != commands.end()) {
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, it->second->name, (uint32_t)cmd);
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, it->second->name, (uint32_t)cmd)
(instance->*it->second->execute)();

View File

@ -13,7 +13,7 @@ using namespace std;
unordered_map<string, id_set> FileSupport::reserved_files;
void FileSupport::ReserveFile(const Filepath& path, int id, int lun)
void FileSupport::ReserveFile(const Filepath& path, int id, int lun) const
{
reserved_files[path.GetPath()] = make_pair(id, lun);
}

View File

@ -17,7 +17,7 @@
using namespace std;
typedef pair<int, int> id_set;
using id_set = pair<int, int>;
class FileSupport
{
@ -33,15 +33,15 @@ class FileSupport
public:
FileSupport() : diskpath({}) {}
virtual ~FileSupport() {}
virtual ~FileSupport() = default;
void GetPath(Filepath& path) const { path = diskpath; }
void SetPath(const Filepath& path) { diskpath = path; }
void ReserveFile(const Filepath&, int, int);
void ReserveFile(const Filepath&, int, int) const;
void UnreserveFile();
static const unordered_map<string, id_set> GetReservedFiles() { return reserved_files; }
static unordered_map<string, id_set> GetReservedFiles() { return reserved_files; }
static void SetReservedFiles(const unordered_map<string, id_set>& files_in_use)
{ FileSupport::reserved_files = files_in_use; }
static bool GetIdsForReservedFile(const Filepath&, int&, int&);

View File

@ -22,9 +22,9 @@ class HostServices: public ModePageDevice
public:
HostServices();
~HostServices() {}
~HostServices() override = default;
virtual bool Dispatch() override;
bool Dispatch() override;
vector<BYTE> InquiryInternal() const override;
void TestUnitReady() override;
@ -38,7 +38,7 @@ protected:
private:
typedef ModePageDevice super;
using super = ModePageDevice;
Dispatcher<HostServices> dispatcher;

View File

@ -17,8 +17,8 @@ class ScsiBlockCommands : virtual public ScsiPrimaryCommands
{
public:
ScsiBlockCommands() {}
virtual ~ScsiBlockCommands() {}
ScsiBlockCommands() = default;
~ScsiBlockCommands() override = default;
// Mandatory commands
virtual void FormatUnit() = 0;

View File

@ -17,8 +17,8 @@ class ScsiMmcCommands : virtual public ScsiPrimaryCommands
{
public:
ScsiMmcCommands() {}
virtual ~ScsiMmcCommands() {}
ScsiMmcCommands() = default;
~ScsiMmcCommands() override = default;
virtual void ReadToc() = 0;
virtual void GetEventStatusNotification() = 0;

View File

@ -15,8 +15,8 @@ class ScsiPrimaryCommands
{
public:
ScsiPrimaryCommands() {}
virtual ~ScsiPrimaryCommands() {}
ScsiPrimaryCommands() = default;
virtual ~ScsiPrimaryCommands() = default;
// Mandatory commands
virtual void TestUnitReady() = 0;

View File

@ -17,8 +17,8 @@ class ScsiPrinterCommands : virtual public ScsiPrimaryCommands
{
public:
ScsiPrinterCommands() {}
virtual ~ScsiPrinterCommands() {}
ScsiPrinterCommands() = default;
~ScsiPrinterCommands() override = default;
// Mandatory commands
virtual void Print() = 0;

View File

@ -30,7 +30,7 @@ bool ModePageDevice::Dispatch()
return dispatcher.Dispatch(this, ctrl->cmd[0]) ? true : super::Dispatch();
}
int ModePageDevice::AddModePages(const DWORD *cdb, BYTE *buf, int max_length)
int ModePageDevice::AddModePages(const DWORD *cdb, BYTE *buf, int max_length) const
{
if (max_length <= 0) {
return 0;
@ -41,14 +41,14 @@ int ModePageDevice::AddModePages(const DWORD *cdb, BYTE *buf, int max_length)
// Get page code (0x3f means all pages)
int page = cdb[2] & 0x3f;
LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page);
LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page)
// Mode page data mapped to the respective page numbers, C++ maps are ordered by key
map<int, vector<BYTE>> pages;
AddModePages(pages, page, changeable);
if (pages.empty()) {
LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page);
LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page)
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}

View File

@ -20,21 +20,23 @@ class ModePageDevice: public PrimaryDevice
{
public:
ModePageDevice(const string&);
virtual ~ModePageDevice() {}
explicit ModePageDevice(const string&);
~ModePageDevice()override = default;
virtual bool Dispatch() override;
bool Dispatch() override;
vector<BYTE> InquiryInternal() const override = 0;
virtual void ModeSelect(const DWORD *, const BYTE *, int);
protected:
int AddModePages(const DWORD *, BYTE *, int);
int AddModePages(const DWORD *, BYTE *, int) const;
virtual void AddModePages(map<int, vector<BYTE>>&, int, bool) const = 0;
private:
typedef PrimaryDevice super;
using super = PrimaryDevice;
Dispatcher<ModePageDevice> dispatcher;

View File

@ -65,7 +65,7 @@ void PrimaryDevice::Inquiry()
// Report if the device does not support the requested LUN
if (!controller->HasDeviceForLun(lun)) {
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, GetId());
LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, GetId())
// Signal that the requested LUN does not exist
ctrl->buffer[0] |= 0x7f;
@ -141,25 +141,25 @@ void PrimaryDevice::CheckReady()
// Not ready if reset
if (IsReset()) {
SetReset(false);
LOGTRACE("%s Device in reset", __PRETTY_FUNCTION__);
LOGTRACE("%s Device in reset", __PRETTY_FUNCTION__)
throw scsi_error_exception(sense_key::UNIT_ATTENTION, asc::POWER_ON_OR_RESET);
}
// Not ready if it needs attention
if (IsAttn()) {
SetAttn(false);
LOGTRACE("%s Device in needs attention", __PRETTY_FUNCTION__);
LOGTRACE("%s Device in needs attention", __PRETTY_FUNCTION__)
throw scsi_error_exception(sense_key::UNIT_ATTENTION, asc::NOT_READY_TO_READY_CHANGE);
}
// Return status if not ready
if (!IsReady()) {
LOGTRACE("%s Device not ready", __PRETTY_FUNCTION__);
LOGTRACE("%s Device not ready", __PRETTY_FUNCTION__)
throw scsi_error_exception(sense_key::NOT_READY, asc::MEDIUM_NOT_PRESENT);
}
// Initialization with no error
LOGTRACE("%s Device is ready", __PRETTY_FUNCTION__);
LOGTRACE("%s Device is ready", __PRETTY_FUNCTION__)
}
vector<BYTE> PrimaryDevice::HandleInquiry(device_type type, scsi_level level, bool is_removable) const
@ -203,14 +203,14 @@ vector<BYTE> PrimaryDevice::HandleRequestSense()
buf[12] = GetStatusCode() >> 8;
buf[13] = GetStatusCode();
LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, ctrl->status, ctrl->buffer[2], ctrl->buffer[12]);
LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, ctrl->status, ctrl->buffer[2], ctrl->buffer[12])
return buf;
}
bool PrimaryDevice::WriteByteSequence(BYTE *, uint32_t)
{
LOGERROR("%s Writing bytes is not supported by this device", __PRETTY_FUNCTION__);
LOGERROR("%s Writing bytes is not supported by this device", __PRETTY_FUNCTION__)
return false;
}

View File

@ -23,10 +23,10 @@ class PrimaryDevice: public Device, virtual public ScsiPrimaryCommands
{
public:
PrimaryDevice(const string&);
virtual ~PrimaryDevice() {}
explicit PrimaryDevice(const string&);
~PrimaryDevice() override = default;
virtual bool Dispatch();
bool Dispatch() override;
void SetController(AbstractController *);
virtual bool WriteByteSequence(BYTE *, uint32_t);
@ -47,10 +47,10 @@ protected:
private:
void TestUnitReady();
void RequestSense();
void ReportLuns();
void Inquiry();
void TestUnitReady() override;
void RequestSense() override;
void ReportLuns() override;
void Inquiry() override;
vector<BYTE> HandleRequestSense();

View File

@ -38,28 +38,22 @@ void scsi_command_util::ModeSelect(const DWORD *cdb, const BYTE *buf, int length
// Parsing the page
// TODO The length handling is wrong in case of length < size
while (length > 0) {
int page = buf[0];
// Format device page
if (int page = buf[0]; page == 0x03) {
// With this page the sector size for a subsequent FORMAT can be selected, but only very few
// drives support this, e.g FUJITSU M2624S
// We are fine as long as the current sector size remains unchanged
if (buf[0xc] != (BYTE)(sector_size >> 8) || buf[0xd] != (BYTE)sector_size) {
// With rascsi it is not possible to permanently (by formatting) change the sector size,
// because the size is an externally configurable setting only
LOGWARN("In order to change the sector size use the -b option when launching rascsi");
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_PARAMETER_LIST);
}
switch (page) {
// Format device page
case 0x03: {
// With this page the sector size for a subsequent FORMAT can be selected, but only very few
// drives support this, e.g FUJITSU M2624S
// We are fine as long as the current sector size remains unchanged
if (buf[0xc] != (BYTE)(sector_size >> 8) || buf[0xd] != (BYTE)sector_size) {
// With rascsi it is not possible to permanently (by formatting) change the sector size,
// because the size is an externally configurable setting only
LOGWARN("In order to change the sector size use the -b option when launching rascsi");
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_PARAMETER_LIST);
}
has_valid_page_code = true;
}
break;
default:
LOGWARN("Unknown MODE SELECT page code: $%02X", page);
break;
has_valid_page_code = true;
}
else {
LOGWARN("Unknown MODE SELECT page code: $%02X", page);
}
// Advance to the next page

View File

@ -76,14 +76,14 @@ bool SCSIDaynaPort::Init(const unordered_map<string, string>& params)
m_tap = new CTapDriver();
m_bTapEnable = m_tap->Init(GetParams());
if(!m_bTapEnable){
LOGERROR("Unable to open the TAP interface");
LOGERROR("Unable to open the TAP interface")
// Not terminating on regular Linux PCs is helpful for testing
#if !defined(__x86_64__) && !defined(__X86__)
return false;
#endif
} else {
LOGDEBUG("Tap interface created");
LOGDEBUG("Tap interface created")
}
this->Reset();
@ -164,7 +164,7 @@ int SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, uint64_t)
scsi_resp_read_t *response = (scsi_resp_read_t*)buf;
int requested_length = cdb[4];
LOGTRACE("%s Read maximum length %d, (%04X)", __PRETTY_FUNCTION__, requested_length, requested_length);
LOGTRACE("%s Read maximum length %d, (%04X)", __PRETTY_FUNCTION__, requested_length, requested_length)
// At host startup, it will send a READ(6) command with a length of 1. We should
@ -187,13 +187,13 @@ int SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, uint64_t)
// If we didn't receive anything, return size of 0
if (rx_packet_size <= 0) {
LOGTRACE("%s No packet received", __PRETTY_FUNCTION__);
LOGTRACE("%s No packet received", __PRETTY_FUNCTION__)
response->length = 0;
response->flags = e_no_more_data;
return DAYNAPORT_READ_HEADER_SZ;
}
LOGTRACE("%s Packet Sz %d (%08X) read: %d", __PRETTY_FUNCTION__, (unsigned int) rx_packet_size, (unsigned int) rx_packet_size, read_count);
LOGTRACE("%s Packet Sz %d (%08X) read: %d", __PRETTY_FUNCTION__, (unsigned int) rx_packet_size, (unsigned int) rx_packet_size, read_count)
// This is a very basic filter to prevent unnecessary packets from
// being sent to the SCSI initiator.
@ -230,7 +230,7 @@ int SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, uint64_t)
(int)response->data[2],
(int)response->data[3],
(int)response->data[4],
(int)response->data[5]);
(int)response->data[5])
// If there are pending packets to be processed, we'll tell the host that the read
// length was 0.
@ -320,18 +320,18 @@ bool SCSIDaynaPort::WriteBytes(const DWORD *cdb, BYTE *buf, uint64_t)
if (data_format == 0x00){
m_tap->Tx(buf, data_length);
LOGTRACE("%s Transmitted %u bytes (00 format)", __PRETTY_FUNCTION__, data_length);
LOGTRACE("%s Transmitted %u bytes (00 format)", __PRETTY_FUNCTION__, data_length)
}
else if (data_format == 0x80){
// The data length is specified in the first 2 bytes of the payload
data_length=(WORD)buf[1] + ((WORD)buf[0] << 8);
m_tap->Tx(&buf[4], data_length);
LOGTRACE("%s Transmitted %u bytes (80 format)", __PRETTY_FUNCTION__, data_length);
LOGTRACE("%s Transmitted %u bytes (80 format)", __PRETTY_FUNCTION__, data_length)
}
else
{
// LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)command->format);
LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format);
// LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)command->format)
LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format)
}
return true;
@ -353,7 +353,7 @@ bool SCSIDaynaPort::WriteBytes(const DWORD *cdb, BYTE *buf, uint64_t)
// - long #3: frames lost
//
//---------------------------------------------------------------------------
int SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer)
int SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer) const
{
int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8);
@ -400,20 +400,20 @@ bool SCSIDaynaPort::EnableInterface(const DWORD *cdb)
if (cdb[5] & 0x80) {
result = m_tap->Enable();
if (result) {
LOGINFO("The DaynaPort interface has been ENABLED.");
LOGINFO("The DaynaPort interface has been ENABLED.")
}
else{
LOGWARN("Unable to enable the DaynaPort Interface");
LOGWARN("Unable to enable the DaynaPort Interface")
}
m_tap->Flush();
}
else {
result = m_tap->Disable();
if (result) {
LOGINFO("The DaynaPort interface has been DISABLED.");
LOGINFO("The DaynaPort interface has been DISABLED.")
}
else{
LOGWARN("Unable to disable the DaynaPort Interface");
LOGWARN("Unable to disable the DaynaPort Interface")
}
}
@ -439,14 +439,14 @@ void SCSIDaynaPort::Read6()
// If any commands have a bogus control value, they were probably not
// generated by the DaynaPort driver so ignore them
if (ctrl->cmd[5] != 0xc0 && ctrl->cmd[5] != 0x80) {
LOGTRACE("%s Control value %d, (%04X), returning invalid CDB", __PRETTY_FUNCTION__, ctrl->cmd[5], ctrl->cmd[5]);
LOGTRACE("%s Control value %d, (%04X), returning invalid CDB", __PRETTY_FUNCTION__, ctrl->cmd[5], ctrl->cmd[5])
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl->blocks);
LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl->blocks)
ctrl->length = Read(ctrl->cmd, ctrl->buffer, record);
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, (int)ctrl->length);
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, (int)ctrl->length)
// Set next block
ctrl->next = record + 1;
@ -472,9 +472,9 @@ void SCSIDaynaPort::Write6()
ctrl->length = (WORD)ctrl->cmd[4] + ((WORD)ctrl->cmd[3] << 8) + 8;
}
else {
LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format);
LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format)
}
LOGTRACE("%s length: %04X (%d) format: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->length, (int)ctrl->length, (unsigned int)data_format);
LOGTRACE("%s length: %04X (%d) format: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->length, (int)ctrl->length, (unsigned int)data_format)
if (ctrl->length <= 0) {
throw scsi_error_exception();
@ -541,7 +541,7 @@ void SCSIDaynaPort::SetInterfaceMode()
break;
default:
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[5]);
LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[5])
break;
}
}
@ -550,7 +550,7 @@ void SCSIDaynaPort::SetMcastAddr()
{
ctrl->length = (DWORD)ctrl->cmd[4];
if (ctrl->length == 0) {
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl->cmd[2]);
LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl->cmd[2])
throw scsi_error_exception();
}

View File

@ -43,7 +43,7 @@ class SCSIDaynaPort: public Disk
public:
SCSIDaynaPort();
~SCSIDaynaPort();
~SCSIDaynaPort() final;
bool Init(const unordered_map<string, string>&) override;
void Open(const Filepath& path) override;
@ -54,7 +54,7 @@ public:
bool WriteBytes(const DWORD *, BYTE *, uint64_t);
int WriteCheck(uint64_t block) override;
int RetrieveStats(const DWORD *cdb, BYTE *buffer);
int RetrieveStats(const DWORD *cdb, BYTE *buffer) const;
bool EnableInterface(const DWORD *cdb);
void SetMacAddr(const DWORD *cdb, BYTE *buffer); // Set MAC address
@ -90,17 +90,17 @@ public:
static const DWORD DAYNAPORT_READ_HEADER_SZ = 2 + 4;
private:
typedef Disk super;
using super = Disk;
Dispatcher<SCSIDaynaPort> dispatcher;
typedef struct __attribute__((packed)) {
using scsi_cmd_daynaport_write_t = struct __attribute__((packed)) {
BYTE operation_code;
BYTE misc_cdb_information;
BYTE logical_block_address;
uint16_t length;
BYTE format;
} scsi_cmd_daynaport_write_t;
};
enum read_data_flags_t : uint32_t {
e_no_more_data = 0x00000000,
@ -108,19 +108,19 @@ private:
e_dropped_packets = 0xFFFFFFFF,
};
typedef struct __attribute__((packed)) {
using scsi_resp_read_t = struct __attribute__((packed)) {
uint32_t length;
read_data_flags_t flags;
BYTE pad;
BYTE data[ETH_FRAME_LEN + sizeof(uint32_t)]; // Frame length + 4 byte CRC
} scsi_resp_read_t;
};
typedef struct __attribute__((packed)) {
using scsi_resp_link_stats_t = struct __attribute__((packed)) {
BYTE mac_address[6];
uint32_t frame_alignment_errors;
uint32_t crc_errors;
uint32_t frames_lost;
} scsi_resp_link_stats_t;
};
scsi_resp_link_stats_t m_scsi_link_stats = {
.mac_address = { 0x00, 0x80, 0x19, 0x10, 0x98, 0xE3 },//MAC address of @PotatoFi's DayanPort

View File

@ -43,10 +43,8 @@ SCSIBR::~SCSIBR()
}
// Release host file system
if (fs) {
fs->Reset();
delete fs;
}
fs->Reset();
delete fs;
}
bool SCSIBR::Init(const unordered_map<string, string>& params)
@ -161,7 +159,8 @@ int SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf)
GetPacketBuf(&buf[2]);
return packet_len + 2;
case 3: // Simultaneous acquisition of multiple packets (size + buffer simultaneously)
case 3: {
// Simultaneous acquisition of multiple packets (size + buffer simultaneously)
// Currently the maximum number of packets is 10
// Isn't it too fast if I increase more?
int total_len = 0;
@ -177,6 +176,11 @@ int SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf)
total_len += packet_len;
}
return total_len;
}
default:
assert(false);
return -1;
}
break;
@ -190,8 +194,14 @@ int SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf)
case 2: // Return additional data acquisition
return ReadFsOpt(buf);
default:
break;
}
break;
default:
break;
}
// Error
@ -232,6 +242,9 @@ bool SCSIBR::WriteBytes(const DWORD *cdb, BYTE *buf, uint64_t)
case 1: // Send packet
SendPacket(buf, len);
return true;
default:
break;
}
break;
@ -244,8 +257,14 @@ bool SCSIBR::WriteBytes(const DWORD *cdb, BYTE *buf, uint64_t)
case 1: // additional data writing
WriteFsOpt(buf, len);
return true;
default:
break;
}
break;
default:
break;
}
assert(false);
@ -307,7 +326,7 @@ void SCSIBR::SendMessage10()
EnterDataOutPhase();
}
int SCSIBR::GetMacAddr(BYTE *mac)
int SCSIBR::GetMacAddr(BYTE *mac) const
{
memcpy(mac, mac_addr, 6);
return 6;
@ -398,7 +417,7 @@ void SCSIBR::FS_CheckDir(BYTE *buf)
DWORD nUnit = ntohl(*dp);
int i = sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
fsresult = fs->CheckDir(nUnit, pNamests);
@ -415,7 +434,7 @@ void SCSIBR::FS_MakeDir(BYTE *buf)
DWORD nUnit = ntohl(*dp);
int i = sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
fsresult = fs->MakeDir(nUnit, pNamests);
@ -432,7 +451,7 @@ void SCSIBR::FS_RemoveDir(BYTE *buf)
DWORD nUnit = ntohl(*dp);
int i = sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
fsresult = fs->RemoveDir(nUnit, pNamests);
@ -449,10 +468,10 @@ void SCSIBR::FS_Rename(BYTE *buf)
DWORD nUnit = ntohl(*dp);
int i = sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
Human68k::namests_t *pNamestsNew = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamestsNew = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
fsresult = fs->Rename(nUnit, pNamests, pNamestsNew);
@ -469,7 +488,7 @@ void SCSIBR::FS_Delete(BYTE *buf)
DWORD nUnit = ntohl(*dp);
int i = sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
fsresult = fs->Delete(nUnit, pNamests);
@ -486,7 +505,7 @@ void SCSIBR::FS_Attribute(BYTE *buf)
DWORD nUnit = ntohl(*dp);
int i = sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
dp = (DWORD*)&buf[i];
@ -511,7 +530,7 @@ void SCSIBR::FS_Files(BYTE *buf)
DWORD nKey = ntohl(*dp);
i += sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
Human68k::files_t *files = (Human68k::files_t*)&buf[i];
@ -592,7 +611,7 @@ void SCSIBR::FS_Create(BYTE *buf)
DWORD nKey = ntohl(*dp);
i += sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
Human68k::fcb_t *pFcb = (Human68k::fcb_t*)&buf[i];
@ -642,7 +661,7 @@ void SCSIBR::FS_Open(BYTE *buf)
DWORD nKey = ntohl(*dp);
i += sizeof(DWORD);
Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
const Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i];
i += sizeof(Human68k::namests_t);
Human68k::fcb_t *pFcb = (Human68k::fcb_t*)&buf[i];
@ -806,7 +825,7 @@ void SCSIBR::FS_Seek(BYTE *buf)
DWORD nMode = ntohl(*dp);
i += sizeof(DWORD);
int *ip = (int*)&buf[i];
auto ip = (const int*)&buf[i];
int nOffset = ntohl(*ip);
i += sizeof(int);
@ -998,6 +1017,8 @@ void SCSIBR::FS_Ioctrl(BYTE *buf)
case (DWORD)-2:
pIoctrl->param = htonl(pIoctrl->param);
break;
default:
break;
}
fsresult = fs->Ioctrl(nUnit, nFunction, pIoctrl);
@ -1010,6 +1031,8 @@ void SCSIBR::FS_Ioctrl(BYTE *buf)
case (DWORD)-3:
pIoctrl->param = htonl(pIoctrl->param);
break;
default:
break;
}
i = 0;
@ -1062,7 +1085,7 @@ void SCSIBR::FS_Lock(BYTE *buf)
// Read Filesystem (result code)
//
//---------------------------------------------------------------------------
int SCSIBR::ReadFsResult(BYTE *buf)
int SCSIBR::ReadFsResult(BYTE *buf) const
{
DWORD *dp = (DWORD*)buf;
*dp = htonl(fsresult);
@ -1074,7 +1097,7 @@ int SCSIBR::ReadFsResult(BYTE *buf)
// Read Filesystem (return data)
//
//---------------------------------------------------------------------------
int SCSIBR::ReadFsOut(BYTE *buf)
int SCSIBR::ReadFsOut(BYTE *buf) const
{
memcpy(buf, fsout, fsoutlen);
return fsoutlen;
@ -1085,7 +1108,7 @@ int SCSIBR::ReadFsOut(BYTE *buf)
// Read file system (return option data)
//
//---------------------------------------------------------------------------
int SCSIBR::ReadFsOpt(BYTE *buf)
int SCSIBR::ReadFsOpt(BYTE *buf) const
{
memcpy(buf, fsopt, fsoptlen);
return fsoptlen;
@ -1129,6 +1152,7 @@ void SCSIBR::WriteFs(int func, BYTE *buf)
case 0x16: return FS_Flush(buf); // $56 - flush
case 0x17: return FS_CheckMedia(buf); // $57 - check media exchange
case 0x18: return FS_Lock(buf); // $58 - exclusive control
default: break;
}
}

View File

@ -33,8 +33,9 @@ class SCSIBR : public Disk
{
public:
SCSIBR();
~SCSIBR();
~SCSIBR() final;
bool Init(const unordered_map<string, string>&) override;
bool Dispatch() override;
@ -48,11 +49,12 @@ public:
void SendMessage10();
private:
typedef Disk super;
using super = Disk;
Dispatcher<SCSIBR> dispatcher;
int GetMacAddr(BYTE *buf); // Get MAC address
int GetMacAddr(BYTE *buf) const; // Get MAC address
void SetMacAddr(const BYTE *buf); // Set MAC address
void ReceivePacket(); // Receive a packet
void GetPacketBuf(BYTE *buf); // Get a packet
@ -65,20 +67,20 @@ private:
BYTE packet_buf[0x1000]; // Receive packet buffer
bool packet_enable = false; // Received packet valid
int ReadFsResult(BYTE *buf); // Read filesystem (result code)
int ReadFsOut(BYTE *buf); // Read filesystem (return data)
int ReadFsOpt(BYTE *buf); // Read file system (optional data)
void WriteFs(int func, BYTE *buf); // File system write (execute)
void WriteFsOpt(BYTE *buf, int len); // File system write (optional data)
int ReadFsResult(BYTE *buf) const; // Read filesystem (result code)
int ReadFsOut(BYTE *buf) const; // Read filesystem (return data)
int ReadFsOpt(BYTE *buf) const; // Read file system (optional data)
void WriteFs(int func, BYTE *buf); // File system write (execute)
void WriteFsOpt(BYTE *buf, int len); // File system write (optional data)
// Command handlers
void FS_InitDevice(BYTE *buf); // $40 - boot
void FS_CheckDir(BYTE *buf); // $41 - directory check
void FS_InitDevice(BYTE *buf); // $40 - boot
void FS_CheckDir(BYTE *buf); // $41 - directory check
void FS_MakeDir(BYTE *buf); // $42 - create directory
void FS_RemoveDir(BYTE *buf); // $43 - delete directory
void FS_RemoveDir(BYTE *buf); // $43 - delete directory
void FS_Rename(BYTE *buf); // $44 - change filename
void FS_Delete(BYTE *buf); // $45 - delete file
void FS_Attribute(BYTE *buf); // $46 - get/set file attributes
void FS_Attribute(BYTE *buf); // $46 - get/set file attributes
void FS_Files(BYTE *buf); // $47 - file search
void FS_NFiles(BYTE *buf); // $48 - find next file
void FS_Create(BYTE *buf); // $49 - create file
@ -87,15 +89,15 @@ private:
void FS_Read(BYTE *buf); // $4C - read file
void FS_Write(BYTE *buf); // $4D - write file
void FS_Seek(BYTE *buf); // $4E - seek file
void FS_TimeStamp(BYTE *buf); // $4F - get/set file time
void FS_TimeStamp(BYTE *buf); // $4F - get/set file time
void FS_GetCapacity(BYTE *buf); // $50 - get capacity
void FS_CtrlDrive(BYTE *buf); // $51 - drive status check/control
void FS_CtrlDrive(BYTE *buf); // $51 - drive status check/control
void FS_GetDPB(BYTE *buf); // $52 - get DPB
void FS_DiskRead(BYTE *buf); // $53 - read sector
void FS_DiskWrite(BYTE *buf); // $54 - write sector
void FS_DiskRead(BYTE *buf); // $53 - read sector
void FS_DiskWrite(BYTE *buf); // $54 - write sector
void FS_Ioctrl(BYTE *buf); // $55 - IOCTRL
void FS_Flush(BYTE *buf); // $56 - flush cache
void FS_CheckMedia(BYTE *buf); // $57 - check media
void FS_CheckMedia(BYTE *buf); // $57 - check media
void FS_Lock(BYTE *buf); // $58 - get exclusive control
CFileSys *fs; // File system accessor

View File

@ -69,12 +69,12 @@ bool SCSIPrinter::Init(const unordered_map<string, string>& params)
SetParams(params);
if (GetParam("cmd").find("%f") == string::npos) {
LOGERROR("Missing filename specifier %s", "%f");
LOGERROR("Missing filename specifier %s", "%f")
return false;
}
if (!GetAsInt(GetParam("timeout"), timeout) || timeout <= 0) {
LOGERROR("Reservation timeout value must be > 0");
LOGERROR("Reservation timeout value must be > 0")
return false;
}
@ -102,7 +102,7 @@ vector<BYTE> SCSIPrinter::InquiryInternal() const
void SCSIPrinter::ReserveUnit()
{
// The printer is released after a configurable time in order to prevent deadlocks caused by broken clients
if (reservation_time + timeout < time(0)) {
if (reservation_time + timeout < time(nullptr)) {
DiscardReservation();
}
@ -111,10 +111,10 @@ void SCSIPrinter::ReserveUnit()
reserving_initiator = controller->GetInitiatorId();
if (reserving_initiator != -1) {
LOGTRACE("Reserved device ID %d, LUN %d for initiator ID %d", GetId(), GetLun(), reserving_initiator);
LOGTRACE("Reserved device ID %d, LUN %d for initiator ID %d", GetId(), GetLun(), reserving_initiator)
}
else {
LOGTRACE("Reserved device ID %d, LUN %d for unknown initiator", GetId(), GetLun());
LOGTRACE("Reserved device ID %d, LUN %d for unknown initiator", GetId(), GetLun())
}
Cleanup();
@ -127,10 +127,10 @@ void SCSIPrinter::ReleaseUnit()
CheckReservation();
if (reserving_initiator != -1) {
LOGTRACE("Released device ID %d, LUN %d reserved by initiator ID %d", GetId(), GetLun(), reserving_initiator);
LOGTRACE("Released device ID %d, LUN %d reserved by initiator ID %d", GetId(), GetLun(), reserving_initiator)
}
else {
LOGTRACE("Released device ID %d, LUN %d reserved by unknown initiator", GetId(), GetLun());
LOGTRACE("Released device ID %d, LUN %d reserved by unknown initiator", GetId(), GetLun())
}
DiscardReservation();
@ -243,15 +243,15 @@ bool SCSIPrinter::WriteByteSequence(BYTE *buf, uint32_t length)
void SCSIPrinter::CheckReservation()
{
if (reserving_initiator == NOT_RESERVED || reserving_initiator == controller->GetInitiatorId()) {
reservation_time = time(0);
reservation_time = time(nullptr);
return;
}
if (controller->GetInitiatorId() != -1) {
LOGTRACE("Initiator ID %d tries to access reserved device ID %d, LUN %d", controller->GetInitiatorId(), GetId(), GetLun());
LOGTRACE("Initiator ID %d tries to access reserved device ID %d, LUN %d", controller->GetInitiatorId(), GetId(), GetLun())
}
else {
LOGTRACE("Unknown initiator tries to access reserved device ID %d, LUN %d", GetId(), GetLun());
LOGTRACE("Unknown initiator tries to access reserved device ID %d, LUN %d", GetId(), GetLun())
}
throw scsi_error_exception(sense_key::ABORTED_COMMAND, asc::NO_ADDITIONAL_SENSE_INFORMATION,

View File

@ -17,18 +17,19 @@
using namespace std;
#define TMP_FILE_PATTERN "/tmp/rascsi_sclp-XXXXXX"
class SCSIPrinter: public PrimaryDevice, ScsiPrinterCommands
class SCSIPrinter: public PrimaryDevice, public ScsiPrinterCommands
{
static constexpr const char *TMP_FILE_PATTERN = "/tmp/rascsi_sclp-XXXXXX";
static constexpr const int TMP_FILENAME_LENGTH = strlen(TMP_FILE_PATTERN);
static const int NOT_RESERVED = -2;
public:
SCSIPrinter();
~SCSIPrinter();
~SCSIPrinter() final;
virtual bool Dispatch() override;
bool Dispatch() override;
bool Init(const unordered_map<string, string>&) override;
@ -48,11 +49,11 @@ public:
private:
typedef PrimaryDevice super;
using super = PrimaryDevice;
Dispatcher<SCSIPrinter> dispatcher;
char filename[sizeof(TMP_FILE_PATTERN) + 1];
char filename[TMP_FILENAME_LENGTH + 1];
int fd = -1;
int reserving_initiator = NOT_RESERVED;

View File

@ -26,24 +26,6 @@ using namespace scsi_defs;
//
//===========================================================================
CDTrack::CDTrack(SCSICD *scsicd)
{
ASSERT(scsicd);
// Set parent CD-ROM device
cdrom = scsicd;
// Track defaults to disabled
valid = false;
// Initialize other data
track_no = -1;
first_lba = 0;
last_lba = 0;
audio = false;
raw = false;
}
void CDTrack::Init(int track, DWORD first, DWORD last)
{
ASSERT(!valid);
@ -78,17 +60,6 @@ void CDTrack::GetPath(Filepath& path) const
path = imgpath;
}
void CDTrack::AddIndex(int index, DWORD lba)
{
ASSERT(valid);
ASSERT(index > 0);
ASSERT(first_lba <= lba);
ASSERT(lba <= last_lba);
// Currently does not support indexes
ASSERT(FALSE);
}
//---------------------------------------------------------------------------
//
// Gets the start of LBA
@ -222,8 +193,7 @@ void SCSICD::Open(const Filepath& path)
OpenPhysical(path);
} else {
// Get file size
off_t size = fio.GetFileSize();
if (size <= 4) {
if (off_t size = fio.GetFileSize(); size <= 4) {
fio.Close();
throw io_exception("CD-ROM file size must be at least 4 bytes");
}
@ -260,7 +230,7 @@ void SCSICD::Open(const Filepath& path)
}
}
void SCSICD::OpenCue(const Filepath& /*path*/)
void SCSICD::OpenCue(const Filepath& /*path*/) const
{
throw io_exception("Opening CUE CD-ROM files is not supported");
}
@ -328,7 +298,7 @@ void SCSICD::OpenIso(const Filepath& path)
// Create only one data track
assert(!track[0]);
track[0] = new CDTrack(this);
track[0] = new CDTrack();
track[0]->Init(1, 0, GetBlockCount() - 1);
track[0]->SetPath(false, path);
tracks = 1;
@ -361,7 +331,7 @@ void SCSICD::OpenPhysical(const Filepath& path)
// Create only one data track
ASSERT(!track[0]);
track[0] = new CDTrack(this);
track[0] = new CDTrack();
track[0]->Init(1, 0, GetBlockCount() - 1);
track[0]->SetPath(false, path);
tracks = 1;
@ -598,7 +568,7 @@ void SCSICD::GetEventStatusNotification()
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
LOGTRACE("Received request for event polling, which is currently not supported");
LOGTRACE("Received request for event polling, which is currently not supported")
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
@ -635,9 +605,9 @@ void SCSICD::LBAtoMSF(DWORD lba, BYTE *msf) const
void SCSICD::ClearTrack()
{
// delete the track object
for (int i = 0; i < TrackMax; i++) {
delete track[i];
track[i] = nullptr;
for (auto t: track) {
delete t;
t = nullptr;
}
// Number of tracks is 0

View File

@ -21,8 +21,6 @@
#include "interfaces/scsi_mmc_commands.h"
#include "interfaces/scsi_primary_commands.h"
class SCSICD;
//===========================================================================
//
// CD-ROM Track
@ -34,8 +32,8 @@ private:
friend class SCSICD;
CDTrack(SCSICD *scsicd);
virtual ~CDTrack() {}
CDTrack() = default;
virtual ~CDTrack() final = default;
public:
@ -44,7 +42,6 @@ public:
// Properties
void SetPath(bool cdda, const Filepath& path); // Set the path
void GetPath(Filepath& path) const; // Get the path
void AddIndex(int index, DWORD lba); // Add index
DWORD GetFirst() const; // Get the start LBA
DWORD GetLast() const; // Get the last LBA
DWORD GetBlocks() const; // Get the number of blocks
@ -53,13 +50,11 @@ public:
bool IsAudio() const; // Is this an audio track?
private:
SCSICD *cdrom; // Parent device
bool valid; // Valid track
int track_no; // Track number
DWORD first_lba; // First LBA
DWORD last_lba; // Last LBA
bool audio; // Audio track flag
bool raw; // RAW data flag
bool valid = false; // Valid track
int track_no = -1; // Track number
DWORD first_lba = 0; // First LBA
DWORD last_lba = 0; // Last LBA
bool audio = false; // Audio track flag
Filepath imgpath; // Image file path
};
@ -76,8 +71,8 @@ public:
TrackMax = 96 // Maximum number of tracks
};
SCSICD(const unordered_set<uint32_t>&);
~SCSICD();
explicit SCSICD(const unordered_set<uint32_t>&);
~SCSICD() override;
bool Dispatch() override;
@ -93,7 +88,7 @@ protected:
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
private:
typedef Disk super;
using super = Disk;
Dispatcher<SCSICD> dispatcher;
@ -101,9 +96,9 @@ private:
void AddCDDAPage(map<int, vector<BYTE>>&, bool) const;
// Open
void OpenCue(const Filepath& path); // Open(CUE)
void OpenIso(const Filepath& path); // Open(ISO)
void OpenPhysical(const Filepath& path); // Open(Physical)
void OpenCue(const Filepath& path) const;
void OpenIso(const Filepath& path);
void OpenPhysical(const Filepath& path);
void ReadToc() override;
void GetEventStatusNotification() override;

View File

@ -19,7 +19,7 @@
#include "scsi_command_util.h"
#include <sstream>
#define DEFAULT_PRODUCT "SCSI HD"
static const char *DEFAULT_PRODUCT = "SCSI HD";
SCSIHD::SCSIHD(const unordered_set<uint32_t>& sector_sizes, bool removable) : Disk(removable ? "SCRM" : "SCHD")
{

View File

@ -23,15 +23,15 @@ class SCSIHD : public Disk, public FileSupport
{
public:
SCSIHD(const unordered_set<uint32_t>&, bool);
virtual ~SCSIHD() {}
~SCSIHD() override = default;
void FinalizeSetup(const Filepath&, off_t);
void Reset();
virtual void Open(const Filepath&) override;
void Open(const Filepath&) override;
// Commands
virtual vector<BYTE> InquiryInternal() const override;
vector<BYTE> InquiryInternal() const override;
void ModeSelect(const DWORD *cdb, const BYTE *buf, int length) override;
void AddFormatPage(map<int, vector<BYTE>>&, bool) const override;

View File

@ -18,9 +18,7 @@
#include "fileio.h"
#include "rascsi_exceptions.h"
SCSIHD_NEC::SCSIHD_NEC(const unordered_set<uint32_t>& sector_sizes) : SCSIHD(sector_sizes, false)
{
}
const unordered_set<uint32_t> SCSIHD_NEC::sector_sizes = { 512 };
//---------------------------------------------------------------------------
//
@ -72,10 +70,9 @@ void SCSIHD_NEC::Open(const Filepath& path)
int sector_size = 0;
// Determine parameters by extension
const char *ext = path.GetFileExt();
// PC-9801-55 NEC genuine?
if (!strcasecmp(ext, ".hdn")) {
if (const char *ext = path.GetFileExt(); !strcasecmp(ext, ".hdn")) {
// Assuming sector size 512, number of sectors 25, number of heads 8 as default settings
disk.image_offset = 0;
image_size = size;
@ -110,8 +107,12 @@ void SCSIHD_NEC::Open(const Filepath& path)
}
}
if (sector_size == 0) {
throw io_exception("Invalid NEC drive sector size");
}
// Image size consistency check
if (disk.image_offset + image_size > size || (image_size % sector_size != 0)) {
if (disk.image_offset + image_size > size || image_size % sector_size != 0) {
throw io_exception("Image size consistency check failed");
}

View File

@ -24,13 +24,15 @@
//===========================================================================
class SCSIHD_NEC : public SCSIHD
{
static const unordered_set<uint32_t> sector_sizes;
public:
SCSIHD_NEC(const unordered_set<uint32_t>&);
~SCSIHD_NEC() {}
explicit SCSIHD_NEC() : SCSIHD(sector_sizes, false) {}
~SCSIHD_NEC() override = default;
void Open(const Filepath& path) override;
// Commands
vector<BYTE> InquiryInternal() const override;
void AddErrorPage(map<int, vector<BYTE>>&, bool) const override;
@ -38,6 +40,7 @@ public:
void AddDrivePage(map<int, vector<BYTE>>&, bool) const override;
private:
// Geometry data
int cylinders = 0;
int heads = 0;

View File

@ -70,7 +70,7 @@ vector<BYTE> SCSIMO::InquiryInternal() const
return HandleInquiry(device_type::OPTICAL_MEMORY, scsi_level::SCSI_2, true);
}
void SCSIMO::SetDeviceParameters(BYTE *buf)
void SCSIMO::SetDeviceParameters(BYTE *buf) const
{
Disk::SetDeviceParameters(buf);
@ -176,6 +176,9 @@ void SCSIMO::AddVendorPage(map<int, vector<BYTE>>& pages, int page, bool changea
spare = 2250;
bands = 18;
break;
default:
break;
}
}
@ -192,6 +195,9 @@ void SCSIMO::AddVendorPage(map<int, vector<BYTE>>& pages, int page, bool changea
spare = 4437;
bands = 18;
break;
default:
break;
}
}

View File

@ -25,7 +25,7 @@ class SCSIMO : public Disk, public FileSupport
public:
SCSIMO(const unordered_set<uint32_t>&, const unordered_map<uint64_t, Geometry>&);
~SCSIMO() {}
~SCSIMO() override = default;
void Open(const Filepath& path) override;
@ -34,7 +34,7 @@ public:
protected:
void SetDeviceParameters(BYTE *) override;
void SetDeviceParameters(BYTE *) const override;
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
void AddFormatPage(map<int, vector<BYTE>>&, bool) const override;
void AddVendorPage(map<int, vector<BYTE>>&, int, bool) const override;

View File

@ -20,10 +20,6 @@
//
//===========================================================================
Fileio::Fileio()
{
}
Fileio::~Fileio()
{
ASSERT(handle == -1);
@ -52,7 +48,7 @@ BOOL Fileio::Load(const Filepath& path, void *buffer, int size)
return TRUE;
}
BOOL Fileio::Save(const Filepath& path, void *buffer, int size)
BOOL Fileio::Save(const Filepath& path, const void *buffer, int size)
{
ASSERT(buffer);
ASSERT(size > 0);
@ -149,9 +145,9 @@ BOOL Fileio::OpenDIO(const Filepath& path, OpenMode mode)
return OpenDIO(path.GetPath(), mode);
}
BOOL Fileio::Read(void *buffer, int size)
BOOL Fileio::Read(void *buffer, int size) const
{
int count;
long count;
ASSERT(buffer);
ASSERT(size > 0);
@ -165,9 +161,9 @@ BOOL Fileio::Read(void *buffer, int size)
return TRUE;
}
BOOL Fileio::Write(const void *buffer, int size)
BOOL Fileio::Write(const void *buffer, int size) const
{
int count;
long count;
ASSERT(buffer);
ASSERT(size > 0);
@ -181,7 +177,7 @@ BOOL Fileio::Write(const void *buffer, int size)
return TRUE;
}
BOOL Fileio::Seek(off_t offset, BOOL relative)
BOOL Fileio::Seek(off_t offset, BOOL relative) const
{
ASSERT(handle >= 0);
ASSERT(offset >= 0);
@ -198,7 +194,7 @@ BOOL Fileio::Seek(off_t offset, BOOL relative)
return TRUE;
}
off_t Fileio::GetFileSize()
off_t Fileio::GetFileSize() const
{
off_t cur;
off_t end;

View File

@ -42,20 +42,19 @@ public:
ReadWrite
};
public:
Fileio();
Fileio() = default;
virtual ~Fileio();
BOOL Load(const Filepath& path, void *buffer, int size); // Load ROM, RAM
BOOL Save(const Filepath& path, void *buffer, int size); // Save RAM
BOOL Save(const Filepath& path, const void *buffer, int size); // Save RAM
BOOL Open(const char *fname, OpenMode mode);
BOOL Open(const Filepath& path, OpenMode mode);
BOOL OpenDIO(const char *fname, OpenMode mode);
BOOL OpenDIO(const Filepath& path, OpenMode mode);
BOOL Seek(off_t offset, BOOL relative = FALSE);
BOOL Read(void *buffer, int size);
BOOL Write(const void *buffer, int size);
off_t GetFileSize();
BOOL Seek(off_t offset, BOOL relative = FALSE) const;
BOOL Read(void *buffer, int size) const;
BOOL Write(const void *buffer, int size) const;
off_t GetFileSize() const;
off_t GetFilePos() const;
void Close();
BOOL IsValid() const { return (BOOL)(handle != -1); }

View File

@ -18,10 +18,6 @@ Filepath::Filepath()
Clear();
}
Filepath::~Filepath()
{
}
Filepath& Filepath::operator=(const Filepath& path)
{
// Set path (split internally)
@ -70,10 +66,10 @@ void Filepath::Split()
// Split
char *pDir = strdup(m_szPath);
char *pDirName = dirname(pDir);
const char *pDirName = dirname(pDir);
char *pBase = strdup(m_szPath);
char *pBaseName = basename(pBase);
char *pExtName = strrchr(pBaseName, '.');
const char *pExtName = strrchr(pBaseName, '.');
// Transmit
if (pDirName) {
@ -110,20 +106,6 @@ const char *Filepath::GetFileExt() const
return (const char *)FileExt;
}
BOOL Filepath::Save(Fileio *fio, int /*ver*/)
{
ASSERT(fio);
return TRUE;
}
BOOL Filepath::Load(Fileio *fio, int /*ver*/)
{
ASSERT(fio);
return TRUE;
}
//---------------------------------------------------------------------------
//
// Filename and extension

View File

@ -31,15 +31,13 @@ class Filepath
{
public:
Filepath();
virtual ~Filepath();
virtual ~Filepath() = default;
Filepath& operator=(const Filepath& path);
void Clear();
void SetPath(const char *path); // File settings (user) for MBCS
const char *GetPath() const { return m_szPath; } // Get path name
const char *GetFileExt() const; // Get short name (LPCTSTR)
BOOL Save(Fileio *fio, int ver);
BOOL Load(Fileio *fio, int ver);
private:
void Split(); // Split the path

View File

@ -27,11 +27,9 @@
static DWORD get_dt_ranges(const char *filename, DWORD offset)
{
DWORD address = ~0;
FILE *fp = fopen(filename, "rb");
if (fp) {
if (FILE *fp = fopen(filename, "rb"); fp) {
fseek(fp, offset, SEEK_SET);
BYTE buf[4];
if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
if (BYTE buf[4]; fread(buf, 1, sizeof buf, fp) == sizeof buf) {
address =
buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
}
@ -76,10 +74,6 @@ DWORD bcm_host_get_peripheral_address(void)
}
#endif // __NetBSD__
GPIOBUS::GPIOBUS()
{
}
bool GPIOBUS::Init(mode_e mode)
{
#if defined(__x86_64__) || defined(__X86__)
@ -106,14 +100,14 @@ bool GPIOBUS::Init(mode_e mode)
// Open /dev/mem
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
LOGERROR("Error: Unable to open /dev/mem. Are you running as root?");
LOGERROR("Error: Unable to open /dev/mem. Are you running as root?")
return false;
}
// Map peripheral region memory
map = mmap(NULL, 0x1000100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, baseaddr);
if (map == MAP_FAILED) {
LOGERROR("Error: Unable to map memory");
LOGERROR("Error: Unable to map memory")
close(fd);
return false;
}
@ -926,7 +920,7 @@ int GPIOBUS::SendHandShake(BYTE *buf, int count, int delay_after_bytes)
if (actmode == TARGET) {
for (i = 0; i < count; i++) {
if(i==delay_after_bytes){
LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, (int)delay_after_bytes);
LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, (int)delay_after_bytes)
SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US);
}
@ -969,7 +963,7 @@ int GPIOBUS::SendHandShake(BYTE *buf, int count, int delay_after_bytes)
for (i = 0; i < count; i++) {
if(i==delay_after_bytes){
LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, (int)delay_after_bytes);
LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, (int)delay_after_bytes)
SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US);
}
@ -1036,12 +1030,12 @@ bool GPIOBUS::PollSelectEvent()
struct gpioevent_data gpev;
if (epoll_wait(epfd, &epev, 1, -1) <= 0) {
LOGWARN("%s epoll_wait failed", __PRETTY_FUNCTION__);
LOGWARN("%s epoll_wait failed", __PRETTY_FUNCTION__)
return false;
}
if (read(selevreq.fd, &gpev, sizeof(gpev)) < 0) {
LOGWARN("%s read failed", __PRETTY_FUNCTION__);
LOGWARN("%s read failed", __PRETTY_FUNCTION__)
return false;
}
@ -1096,7 +1090,7 @@ void GPIOBUS::MakeTable(void)
// Create parity table
for (i = 0; i < 0x100; i++) {
DWORD bits = (DWORD)i;
auto bits = (DWORD)i;
DWORD parity = 0;
for (j = 0; j < 8; j++) {
parity ^= bits & 1;
@ -1112,7 +1106,7 @@ void GPIOBUS::MakeTable(void)
memset(tblDatSet, 0x00, sizeof(tblDatSet));
for (i = 0; i < 0x100; i++) {
// Bit string for inspection
DWORD bits = (DWORD)i;
auto bits = (DWORD)i;
// Get parity
if (tblParity[i]) {

View File

@ -150,14 +150,14 @@
#define CONNECT_DESC "FULLSPEC" // Startup message
// Select signal control mode
#define SIGNAL_CONTROL_MODE 0 // SCSI logical specification
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal pin assignment (-1 means no control)
#define PIN_ACT 4 // ACTIVE
#define PIN_ENB 5 // ENABLE
#define PIN_IND 6 // INITIATOR CTRL DIRECTION
#define PIN_TAD 7 // TARGET CTRL DIRECTION
#define PIN_DTD 8 // DATA DIRECTION
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 5; // ENABLE
const static int PIN_IND = 6; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = 7; // TARGET CTRL DIRECTION
const static int PIN_DTD = 8; // DATA DIRECTION
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
@ -167,24 +167,24 @@
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI signal pin assignment
#define PIN_DT0 10 // Data 0
#define PIN_DT1 11 // Data 1
#define PIN_DT2 12 // Data 2
#define PIN_DT3 13 // Data 3
#define PIN_DT4 14 // Data 4
#define PIN_DT5 15 // Data 5
#define PIN_DT6 16 // Data 6
#define PIN_DT7 17 // Data 7
#define PIN_DP 18 // Data parity
#define PIN_ATN 19 // ATN
#define PIN_RST 20 // RST
#define PIN_ACK 21 // ACK
#define PIN_REQ 22 // REQ
#define PIN_MSG 23 // MSG
#define PIN_CD 24 // CD
#define PIN_IO 25 // IO
#define PIN_BSY 26 // BSY
#define PIN_SEL 27 // SEL
const static int PIN_DT0 = 10; // Data 0
const static int PIN_DT1 = 11; // Data 1
const static int PIN_DT2 = 12; // Data 2
const static int PIN_DT3 = 13; // Data 3
const static int PIN_DT4 = 14; // Data 4
const static int PIN_DT5 = 15; // Data 5
const static int PIN_DT6 = 16; // Data 6
const static int PIN_DT7 = 17; // Data 7
const static int PIN_DP = 18; // Data parity
const static int PIN_ATN = 19; // ATN
const static int PIN_RST = 20; // RST
const static int PIN_ACK = 21; // ACK
const static int PIN_REQ = 22; // REQ
const static int PIN_MSG = 23; // MSG
const static int PIN_CD = 24; // CD
const static int PIN_IO = 25; // IO
const static int PIN_BSY = 26; // BSY
const static int PIN_SEL = 27; // SEL
#endif
#ifdef CONNECT_TYPE_AIBOM
@ -232,6 +232,7 @@
#define PIN_SEL 8 // SEL
#endif
// TODO Is this type stil relevant?
#ifdef CONNECT_TYPE_GAMERNIUM
//
// RaSCSI Adapter GAMERnium.com version
@ -435,33 +436,33 @@
//---------------------------------------------------------------------------
// SCSI Bus timings taken from:
// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html
#define SCSI_DELAY_ARBITRATION_DELAY_NS 2400
#define SCSI_DELAY_ASSERTION_PERIOD_NS 90
#define SCSI_DELAY_BUS_CLEAR_DELAY_NS 800
#define SCSI_DELAY_BUS_FREE_DELAY_NS 800
#define SCSI_DELAY_BUS_SET_DELAY_NS 1800
#define SCSI_DELAY_BUS_SETTLE_DELAY_NS 400
#define SCSI_DELAY_CABLE_SKEW_DELAY_NS 10
#define SCSI_DELAY_DATA_RELEASE_DELAY_NS 400
#define SCSI_DELAY_DESKEW_DELAY_NS 45
#define SCSI_DELAY_DISCONNECTION_DELAY_US 200
#define SCSI_DELAY_HOLD_TIME_NS 45
#define SCSI_DELAY_NEGATION_PERIOD_NS 90
#define SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S 10 // (recommended)
#define SCSI_DELAY_RESET_TO_SELECTION_TIME_US (250*1000) // (recommended)
#define SCSI_DELAY_RESET_HOLD_TIME_US 25
#define SCSI_DELAY_SELECTION_ABORT_TIME_US 200
#define SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS (250*1000) // (recommended)
#define SCSI_DELAY_FAST_ASSERTION_PERIOD_NS 30
#define SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS 5
#define SCSI_DELAY_FAST_DESKEW_DELAY_NS 20
#define SCSI_DELAY_FAST_HOLD_TIME_NS 10
#define SCSI_DELAY_FAST_NEGATION_PERIOD_NS 30
const static int SCSI_DELAY_ARBITRATION_DELAY_NS = 2400;
const static int SCSI_DELAY_ASSERTION_PERIOD_NS = 90;
const static int SCSI_DELAY_BUS_CLEAR_DELAY_NS = 800;
const static int SCSI_DELAY_BUS_FREE_DELAY_NS = 800;
const static int SCSI_DELAY_BUS_SET_DELAY_NS = 1800;
const static int SCSI_DELAY_BUS_SETTLE_DELAY_NS = 400;
const static int SCSI_DELAY_CABLE_SKEW_DELAY_NS = 10;
const static int SCSI_DELAY_DATA_RELEASE_DELAY_NS = 400;
const static int SCSI_DELAY_DESKEW_DELAY_NS = 45;
const static int SCSI_DELAY_DISCONNECTION_DELAY_US = 200;
const static int SCSI_DELAY_HOLD_TIME_NS = 45;
const static int SCSI_DELAY_NEGATION_PERIOD_NS = 90;
const static int SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S = 10; // (recommended)
const static int SCSI_DELAY_RESET_TO_SELECTION_TIME_US = 250*1000; // (recommended)
const static int SCSI_DELAY_RESET_HOLD_TIME_US = 25;
const static int SCSI_DELAY_SELECTION_ABORT_TIME_US = 200;
const static int SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS = 250*1000; // (recommended)
const static int SCSI_DELAY_FAST_ASSERTION_PERIOD_NS = 30;
const static int SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS = 5;
const static int SCSI_DELAY_FAST_DESKEW_DELAY_NS = 20;
const static int SCSI_DELAY_FAST_HOLD_TIME_NS = 10;
const static int SCSI_DELAY_FAST_NEGATION_PERIOD_NS = 30;
// The DaynaPort SCSI Link do a short delay in the middle of transfering
// a packet. This is the number of uS that will be delayed between the
// header and the actual data.
#define SCSI_DELAY_SEND_DATA_DAYNAPORT_US 100
const static int SCSI_DELAY_SEND_DATA_DAYNAPORT_US = 100;
//---------------------------------------------------------------------------
//
@ -472,8 +473,8 @@ class GPIOBUS : public BUS
{
public:
// Basic Functions
GPIOBUS();
virtual ~GPIOBUS() {}
GPIOBUS()= default;
~GPIOBUS() final = default;
// Destructor
bool Init(mode_e mode = TARGET) override;
// Initialization
@ -621,17 +622,17 @@ private:
int rpitype = 0; // Type of Raspberry Pi
volatile uint32_t *gpio = 0; // GPIO register
volatile uint32_t *gpio = nullptr; // GPIO register
volatile uint32_t *pads = 0; // PADS register
volatile uint32_t *pads = nullptr; // PADS register
volatile uint32_t *level = 0; // GPIO input level
volatile uint32_t *level = nullptr; // GPIO input level
volatile uint32_t *irpctl = 0; // Interrupt control register
volatile uint32_t *irpctl = nullptr; // Interrupt control register
volatile uint32_t irptenb; // Interrupt enabled state
volatile uint32_t *qa7regs = 0; // QA7 register
volatile uint32_t *qa7regs = nullptr; // QA7 register
volatile int tintcore; // Interupt control target CPU.
@ -639,9 +640,9 @@ private:
volatile uint32_t giccpmr; // GICC priority setting
volatile uint32_t *gicd = 0; // GIC Interrupt distributor register
volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register
volatile uint32_t *gicc = 0; // GIC CPU interface register
volatile uint32_t *gicc = nullptr; // GIC CPU interface register
DWORD gpfsel[4]; // GPFSEL0-4 backup values

View File

@ -120,7 +120,7 @@ Localizer::Localizer()
Add(ERROR_BLOCK_SIZE_NOT_CONFIGURABLE, "es", "El tamaño del bloque para el tipo de dispositivo %1 no es configurable");
}
void Localizer::Add(LocalizationKey key, const string& locale, const string& value)
void Localizer::Add(LocalizationKey key, const string& locale, string_view value)
{
// Safeguards against empty messages, duplicate entries and unsupported locales
assert(locale.size());

View File

@ -45,13 +45,13 @@ class Localizer
public:
Localizer();
~Localizer() {};
~Localizer() = default;
string Localize(LocalizationKey, const string&, const string& = "", const string& = "", const string& = "");
private:
void Add(LocalizationKey, const string&, const string&);
void Add(LocalizationKey, const string&, string_view);
unordered_map<string, unordered_map<LocalizationKey, string>> localized_messages;
// Supported locales, always lower case

View File

@ -14,11 +14,11 @@
#include "scsi.h"
#include "gpiobus.h"
typedef struct data_capture
using data_capture_t = struct data_capture
{
DWORD data;
uint64_t timestamp;
} data_capture_t;
};
#define GET_PIN(SAMPLE, PIN) ((bool)((SAMPLE->data >> PIN) & 1))

View File

@ -27,15 +27,14 @@ DWORD scsimon_read_json(const char *json_filename, data_capture *data_capture_ar
while (fgets(str_buf, sizeof(str_buf), fp))
{
char timestamp[1024];
char data[1024];
uint64_t timestamp_uint;
uint32_t data_uint;
char *ptr;
char *timestamp_str;
char *data_str;
const char *timestamp_str;
const char *data_str;
timestamp_str = strstr(str_buf, timestamp_label);
if (!timestamp_str)
continue;
@ -62,7 +61,10 @@ DWORD scsimon_read_json(const char *json_filename, data_capture *data_capture_ar
break;
}
}
fclose(fp);
if (fp != nullptr) {
fclose(fp);
}
return sample_count;
}

View File

@ -40,10 +40,10 @@ const char SYMBOL_PIN_CD = '*';
const char SYMBOL_PIN_IO = '(';
const char SYMBOL_PIN_BSY = ')';
const char SYMBOL_PIN_SEL = '-';
const char SYMBOL_PIN_PHASE = '=';
const char SYMBOL_PIN_PHASE = '=';
// We'll use position 0 in the prev_value array to store the previous phase
#define PIN_PHASE 0
const int PIN_PHASE = 0;
//---------------------------------------------------------------------------
//
@ -122,7 +122,7 @@ void scsimon_generate_value_change_dump(const char *filename, const data_capture
// Get the current time
time_t rawtime;
time(&rawtime);
struct tm *timeinfo = localtime(&rawtime);
const struct tm *timeinfo = localtime(&rawtime);
char timestamp[256];
strftime(timestamp, sizeof(timestamp), "%d-%m-%Y %H-%M-%S", timeinfo);

View File

@ -50,17 +50,19 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <poll.h>
#include <dirent.h>
#include <pwd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#ifdef __linux
#include <sys/epoll.h>
#include <linux/gpio.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#endif
//---------------------------------------------------------------------------
//
@ -82,11 +84,11 @@
// Basic Type Definitions
//
//---------------------------------------------------------------------------
typedef unsigned char BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef int BOOL;
typedef char TCHAR;
using BYTE = unsigned char;
using WORD =uint16_t;
using DWORD = uint32_t;
using BOOL = int;
using TCHAR = char;
#if !defined(FALSE)
#define FALSE 0
@ -100,9 +102,9 @@ typedef char TCHAR;
#define _T(x) x
#endif
#define _MAX_PATH 260
#define _MAX_DIR 256
#define _MAX_FNAME 256
#define _MAX_EXT 256
static const int _MAX_PATH = 260;
static const int _MAX_DIR = 256;
static const int _MAX_FNAME = 256;
static const int _MAX_EXT = 256;
#endif // os_h

View File

@ -20,8 +20,8 @@ using namespace rascsi_interface;
#define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ )
#define COMPONENT_SEPARATOR ':'
#define KEY_VALUE_SEPARATOR '='
static const char COMPONENT_SEPARATOR = ':';
static const char KEY_VALUE_SEPARATOR = '=';
Localizer localizer;
@ -35,7 +35,7 @@ void protobuf_util::ParseParameters(PbDeviceDefinition& device, const string& pa
if (!p.empty()) {
size_t separator_pos = p.find(KEY_VALUE_SEPARATOR);
if (separator_pos != string::npos) {
AddParam(device, p.substr(0, separator_pos), p.substr(separator_pos + 1));
AddParam(device, p.substr(0, separator_pos), string_view(p).substr(separator_pos + 1));
}
}
}
@ -51,19 +51,19 @@ void protobuf_util::ParseParameters(PbDeviceDefinition& device, const string& pa
}
}
const string protobuf_util::GetParam(const PbCommand& command, const string& key)
string protobuf_util::GetParam(const PbCommand& command, const string& key)
{
auto map = command.params();
return map[key];
}
const string protobuf_util::GetParam(const PbDeviceDefinition& device, const string& key)
string protobuf_util::GetParam(const PbDeviceDefinition& device, const string& key)
{
auto map = device.params();
return map[key];
}
void protobuf_util::AddParam(PbCommand& command, const string& key, const string& value)
void protobuf_util::AddParam(PbCommand& command, const string& key, string_view value)
{
if (!key.empty() && !value.empty()) {
auto& map = *command.mutable_params();
@ -71,7 +71,7 @@ void protobuf_util::AddParam(PbCommand& command, const string& key, const string
}
}
void protobuf_util::AddParam(PbDevice& device, const string& key, const string& value)
void protobuf_util::AddParam(PbDevice& device, const string& key,string_view value)
{
if (!key.empty() && !value.empty()) {
auto& map = *device.mutable_params();
@ -79,7 +79,7 @@ void protobuf_util::AddParam(PbDevice& device, const string& key, const string&
}
}
void protobuf_util::AddParam(PbDeviceDefinition& device, const string& key, const string& value)
void protobuf_util::AddParam(PbDeviceDefinition& device, const string& key, string_view value)
{
if (!key.empty() && !value.empty()) {
auto& map = *device.mutable_params();
@ -100,7 +100,7 @@ void protobuf_util::SerializeMessage(int fd, const google::protobuf::Message& me
message.SerializeToString(&data);
// Write the size of the protobuf data as a header
int32_t size = data.length();
auto size = (int32_t)data.length();
if (write(fd, &size, sizeof(size)) != sizeof(size)) {
throw io_exception("Can't write protobuf message header");
}
@ -125,15 +125,14 @@ void protobuf_util::DeserializeMessage(int fd, google::protobuf::Message& messag
}
// Read the binary protobuf data
uint8_t *data_buf = new uint8_t[size];
bytes_read = ReadNBytes(fd, data_buf, size);
auto data_buf = make_unique<uint8_t[]>(size);
bytes_read = ReadNBytes(fd, data_buf.get(), size);
if (bytes_read < size) {
throw io_exception("Missing protobuf message data");
}
// Create protobuf message
string data((const char *)data_buf, size);
delete[] data_buf;
string data((const char *)data_buf.get(), size);
message.ParseFromString(data);
}
@ -162,7 +161,8 @@ bool protobuf_util::ReturnLocalizedError(const CommandContext& context, const Lo
const PbErrorCode error_code, const string& arg1, const string& arg2, const string& arg3)
{
// For the logfile always use English
LOGERROR("%s", localizer.Localize(key, "en", arg1, arg2, arg3).c_str());
// TODO This line forces rasctl to depend on the localizer. This should be fixed.
LOGERROR("%s", localizer.Localize(key, "en", arg1, arg2, arg3).c_str())
return ReturnStatus(context, false, localizer.Localize(key, context.locale, arg1, arg2, arg3), error_code, false);
}
@ -172,7 +172,7 @@ bool protobuf_util::ReturnStatus(const CommandContext& context, bool status, con
{
// Do not log twice if logging has already been done in the localized error handling above
if (log && !status && !msg.empty()) {
LOGERROR("%s", msg.c_str());
LOGERROR("%s", msg.c_str())
}
if (context.fd == -1) {

View File

@ -24,11 +24,11 @@ using namespace rascsi_interface;
namespace protobuf_util
{
void ParseParameters(PbDeviceDefinition&, const string&);
const string GetParam(const PbCommand&, const string&);
const string GetParam(const PbDeviceDefinition&, const string&);
void AddParam(PbCommand&, const string&, const string&);
void AddParam(PbDevice&, const string&, const string&);
void AddParam(PbDeviceDefinition&, const string&, const string&);
string GetParam(const PbCommand&, const string&);
string GetParam(const PbDeviceDefinition&, const string&);
void AddParam(PbCommand&, const string&, string_view);
void AddParam(PbDevice&, const string&, string_view);
void AddParam(PbDeviceDefinition&, const string&, string_view);
void SerializeMessage(int, const google::protobuf::Message&);
void DeserializeMessage(int, google::protobuf::Message&);
size_t ReadNBytes(int, uint8_t *, size_t);

View File

@ -46,8 +46,8 @@ using namespace protobuf_util;
//
//---------------------------------------------------------------------------
#define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ )
#define DEFAULT_PORT 6868
#define COMPONENT_SEPARATOR ':'
static const int DEFAULT_PORT = 6868;
static const char COMPONENT_SEPARATOR = ':';
//---------------------------------------------------------------------------
//
@ -56,7 +56,7 @@ using namespace protobuf_util;
//---------------------------------------------------------------------------
static volatile bool running; // Running flag
static volatile bool active; // Processing flag
GPIOBUS *bus; // GPIO Bus
unique_ptr<GPIOBUS> bus; // GPIO Bus
int monsocket; // Monitor Socket
pthread_t monthread; // Monitor Thread
pthread_mutex_t ctrl_mutex; // Semaphore for the ctrl array
@ -126,14 +126,13 @@ void Banner(int argc, char* argv[])
bool InitService(int port)
{
int result = pthread_mutex_init(&ctrl_mutex, NULL);
if (result != EXIT_SUCCESS){
LOGERROR("Unable to create a mutex. Error code: %d", result);
if (int result = pthread_mutex_init(&ctrl_mutex, nullptr); result != EXIT_SUCCESS){
LOGERROR("Unable to create a mutex. Error code: %d", result)
return false;
}
// Create socket for monitor
struct sockaddr_in server;
sockaddr_in server;
monsocket = socket(PF_INET, SOCK_STREAM, 0);
memset(&server, 0, sizeof(server));
server.sin_family = PF_INET;
@ -141,22 +140,20 @@ bool InitService(int port)
server.sin_addr.s_addr = htonl(INADDR_ANY);
// allow address reuse
int yes = 1;
if (setsockopt(monsocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
if (int yes = 1; setsockopt(monsocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
return false;
}
signal(SIGPIPE, SIG_IGN);
// Bind
if (bind(monsocket, (struct sockaddr *)&server,
sizeof(struct sockaddr_in)) < 0) {
if (bind(monsocket, (sockaddr *)&server, sizeof(sockaddr_in)) < 0) {
FPRT(stderr, "Error: Port %d is in use, is rascsi already running?\n", port);
return false;
}
// Create Monitor Thread
pthread_create(&monthread, NULL, MonThread, NULL);
pthread_create(&monthread, nullptr, MonThread, nullptr);
// Interrupt handler settings
if (signal(SIGINT, KillHandler) == SIG_ERR) {
@ -178,11 +175,10 @@ bool InitService(int port)
bool InitBus()
{
// GPIOBUS creation
bus = new GPIOBUS();
bus = make_unique<GPIOBUS>();
// GPIO Initialization
if (!bus->Init()) {
delete bus;
return false;
}
@ -197,9 +193,8 @@ void Cleanup()
DetachAll();
// Clean up and discard the bus
if (bus) {
if (bus != nullptr) {
bus->Cleanup();
delete bus;
}
// Close the monitor socket
@ -308,25 +303,25 @@ bool SetLogLevel(const string& log_level)
current_log_level = log_level;
LOGINFO("Set log level to '%s'", current_log_level.c_str());
LOGINFO("Set log level to '%s'", current_log_level.c_str())
return true;
}
void LogDevices(const string& devices)
void LogDevices(string_view devices)
{
stringstream ss(devices);
stringstream ss(devices.data());
string line;
while (getline(ss, line, '\n')) {
LOGINFO("%s", line.c_str());
LOGINFO("%s", line.c_str())
}
}
string SetReservedIds(const string& ids)
string SetReservedIds(string_view ids)
{
list<string> ids_to_reserve;
stringstream ss(ids);
stringstream ss(ids.data());
string id;
while (getline(ss, id, ',')) {
if (!id.empty()) {
@ -361,10 +356,10 @@ string SetReservedIds(const string& ids)
s += to_string(reserved_id);
}
LOGINFO("Reserved ID(s) set to %s", s.c_str());
LOGINFO("Reserved ID(s) set to %s", s.c_str())
}
else {
LOGINFO("Cleared reserved ID(s)");
LOGINFO("Cleared reserved ID(s)")
}
return "";
@ -374,7 +369,7 @@ void DetachAll()
{
controller_manager.DeleteAllControllersAndDevices();
LOGINFO("Detached all devices");
LOGINFO("Detached all devices")
}
bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device, bool dryRun)
@ -405,7 +400,7 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
}
// If no filename was provided the medium is considered removed
FileSupport *file_support = dynamic_cast<FileSupport *>(device);
auto file_support = dynamic_cast<FileSupport *>(device);
if (file_support != nullptr) {
device->SetRemoved(filename.empty());
}
@ -426,12 +421,12 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
device->SetRevision(pb_device.revision());
}
}
catch(const illegal_argument_exception& e) {
catch(const illegal_argument_exception& e) { //NOSONAR This exception is handled properly
return ReturnStatus(context, false, e.get_msg());
}
if (pb_device.block_size()) {
Disk *disk = dynamic_cast<Disk *>(device);
auto disk = dynamic_cast<Disk *>(device);
if (disk != nullptr && disk->IsSectorSizeConfigurable()) {
if (!disk->SetConfiguredSectorSize(pb_device.block_size())) {
device_factory.DeleteDevice(device);
@ -518,8 +513,9 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
// Replace with the newly created unit
pthread_mutex_lock(&ctrl_mutex);
PrimaryDevice *primary_device = static_cast<PrimaryDevice *>(device);
if (!controller_manager.CreateScsiController(bus, primary_device)) {
if (auto primary_device = static_cast<PrimaryDevice *>(device);
!controller_manager.CreateScsiController(bus.get(), primary_device)) {
pthread_mutex_unlock(&ctrl_mutex);
return ReturnStatus(context, false, "Couldn't create SCSI controller instance");
@ -534,7 +530,7 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
msg += "protected ";
}
msg += device->GetType() + " device, ID " + to_string(id) + ", unit " + to_string(unit);
LOGINFO("%s", msg.c_str());
LOGINFO("%s", msg.c_str())
return true;
}
@ -556,8 +552,7 @@ bool Detach(const CommandContext& context, PrimaryDevice *device, bool dryRun)
int lun = device->GetLun();
string type = device->GetType();
FileSupport *file_support = dynamic_cast<FileSupport *>(device);
if (file_support != nullptr) {
if (auto file_support = dynamic_cast<FileSupport *>(device); file_support != nullptr) {
file_support->UnreserveFile();
}
@ -571,7 +566,7 @@ bool Detach(const CommandContext& context, PrimaryDevice *device, bool dryRun)
device_factory.DeleteDevice(device);
pthread_mutex_unlock(&ctrl_mutex);
LOGINFO("Detached %s device with ID %d, unit %d", type.c_str(), id, lun);
LOGINFO("Detached %s device with ID %d, unit %d", type.c_str(), id, lun)
}
return true;
@ -597,9 +592,9 @@ bool Insert(const CommandContext& context, const PbDeviceDefinition& pb_device,
}
LOGINFO("Insert %sfile '%s' requested into %s ID %d, unit %d", pb_device.protected_() ? "protected " : "",
filename.c_str(), device->GetType().c_str(), pb_device.id(), pb_device.unit());
filename.c_str(), device->GetType().c_str(), pb_device.id(), pb_device.unit())
Disk *disk = dynamic_cast<Disk *>(device);
auto disk = dynamic_cast<Disk *>(device);
if (pb_device.block_size()) {
if (disk != nullptr&& disk->IsSectorSizeConfigurable()) {
@ -622,7 +617,7 @@ bool Insert(const CommandContext& context, const PbDeviceDefinition& pb_device,
return ReturnLocalizedError(context, ERROR_IMAGE_IN_USE, filename, to_string(id), to_string(unit));
}
FileSupport *file_support = dynamic_cast<FileSupport *>(device);
auto file_support = dynamic_cast<FileSupport *>(device);
try {
try {
file_support->Open(filepath);
@ -638,7 +633,7 @@ bool Insert(const CommandContext& context, const PbDeviceDefinition& pb_device,
file_support->Open(filepath);
}
}
catch(const io_exception& e) {
catch(const io_exception& e) { //NOSONAR This exception is handled properly
return ReturnLocalizedError(context, ERROR_FILE_OPEN, initial_filename, e.get_msg());
}
@ -685,13 +680,13 @@ bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_devi
if (!params.empty()) {
s << ", command params=";
bool isFirst = true;
for (const auto& param: params) {
for (const auto& [key, value]: params) {
if (!isFirst) {
s << ", ";
}
isFirst = false;
string value = param.first != "token" ? param.second : "???";
s << "'" << param.first << "=" << value << "'";
string v = key != "token" ? value : "???";
s << "'" << key << "=" << v << "'";
}
}
@ -700,19 +695,19 @@ bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_devi
if (pb_device.params_size()) {
s << ", device params=";
bool isFirst = true;
for (const auto& param: pb_device.params()) {
for (const auto& [key, value]: pb_device.params()) {
if (!isFirst) {
s << ":";
}
isFirst = false;
s << "'" << param.first << "=" << param.second << "'";
s << "'" << key << "=" << value << "'";
}
}
s << ", vendor='" << pb_device.vendor() << "', product='" << pb_device.product()
<< "', revision='" << pb_device.revision()
<< "', block size=" << pb_device.block_size();
LOGINFO("%s", s.str().c_str());
LOGINFO("%s", s.str().c_str())
// Check the Controller Number
if (id < 0) {
@ -769,17 +764,17 @@ bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_devi
switch (operation) {
case START:
if (!dryRun) {
LOGINFO("Start requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit);
LOGINFO("Start requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit)
if (!device->Start()) {
LOGWARN("Starting %s ID %d, unit %d failed", device->GetType().c_str(), id, unit);
LOGWARN("Starting %s ID %d, unit %d failed", device->GetType().c_str(), id, unit)
}
}
break;
case STOP:
if (!dryRun) {
LOGINFO("Stop requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit);
LOGINFO("Stop requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit)
// STOP is idempotent
device->Stop();
@ -791,17 +786,17 @@ bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_devi
case EJECT:
if (!dryRun) {
LOGINFO("Eject requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit);
LOGINFO("Eject requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit)
if (!device->Eject(true)) {
LOGWARN("Ejecting %s ID %d, unit %d failed", device->GetType().c_str(), id, unit);
LOGWARN("Ejecting %s ID %d, unit %d failed", device->GetType().c_str(), id, unit)
}
}
break;
case PROTECT:
if (!dryRun) {
LOGINFO("Write protection requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit);
LOGINFO("Write protection requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit)
// PROTECT is idempotent
device->SetProtected(true);
@ -810,7 +805,7 @@ bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_devi
case UNPROTECT:
if (!dryRun) {
LOGINFO("Write unprotection requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit);
LOGINFO("Write unprotection requested for %s ID %d, unit %d", device->GetType().c_str(), id, unit)
// UNPROTECT is idempotent
device->SetProtected(false);
@ -826,7 +821,7 @@ bool ProcessCmd(const CommandContext& context, const PbDeviceDefinition& pb_devi
case CHECK_AUTHENTICATION:
case NO_OPERATION:
// Do nothing, just log
LOGTRACE("Received %s command", PbOperation_Name(operation).c_str());
LOGTRACE("Received %s command", PbOperation_Name(operation).c_str())
break;
default:
@ -887,8 +882,7 @@ bool ProcessCmd(const CommandContext& context, const PbCommand& command)
// Restore the list of reserved files before proceeding
FileSupport::SetReservedFiles(reserved_files);
string result = ValidateLunSetup(command);
if (!result.empty()) {
if (string result = ValidateLunSetup(command); !result.empty()) {
return ReturnStatus(context, false, result);
}
@ -911,10 +905,9 @@ bool ProcessCmd(const CommandContext& context, const PbCommand& command)
return ReturnStatus(context);
}
bool ProcessId(const string id_spec, int& id, int& unit)
bool ProcessId(const string& id_spec, int& id, int& unit)
{
size_t separator_pos = id_spec.find(COMPONENT_SEPARATOR);
if (separator_pos == string::npos) {
if (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;
@ -955,25 +948,25 @@ void ShutDown(const CommandContext& context, const string& mode) {
}
if (mode == "system") {
LOGINFO("System shutdown requested");
LOGINFO("System shutdown requested")
SerializeMessage(context.fd, result);
DetachAll();
if (system("init 0") == -1) {
LOGERROR("System shutdown failed: %s", strerror(errno));
LOGERROR("System shutdown failed: %s", strerror(errno))
}
}
else if (mode == "reboot") {
LOGINFO("System reboot requested");
LOGINFO("System reboot requested")
SerializeMessage(context.fd, result);
DetachAll();
if (system("init 6") == -1) {
LOGERROR("System reboot failed: %s", strerror(errno));
LOGERROR("System reboot failed: %s", strerror(errno))
}
}
else {
@ -1033,8 +1026,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue;
case 'F': {
string result = rascsi_image.SetDefaultImageFolder(optarg);
if (!result.empty()) {
if (string result = rascsi_image.SetDefaultImageFolder(optarg); !result.empty()) {
cerr << result << endl;
return false;
}
@ -1090,12 +1082,12 @@ bool ParseArgument(int argc, char* argv[], int& port)
}
continue;
default:
return false;
case 1:
// Encountered filename
break;
default:
return false;
}
if (optopt) {
@ -1111,8 +1103,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
ParseParameters(*device, optarg);
size_t separator_pos = name.find(COMPONENT_SEPARATOR);
if (separator_pos != string::npos) {
if (size_t separator_pos = name.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
device->set_vendor(name.substr(0, separator_pos));
name = name.substr(separator_pos + 1);
separator_pos = name.find(COMPONENT_SEPARATOR);
@ -1135,7 +1126,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
}
if (!log_level.empty() && !SetLogLevel(log_level)) {
LOGWARN("Invalid log level '%s'", log_level.c_str());
LOGWARN("Invalid log level '%s'", log_level.c_str())
}
// Attach all specified devices
@ -1185,10 +1176,10 @@ void FixCpu(int cpu)
// Monitor Thread
//
//---------------------------------------------------------------------------
static void *MonThread(void *)
static void *MonThread(void *) //NOSONAR The pointer cannot be const void * because of the thread API
{
// Scheduler Settings
struct sched_param schedparam;
sched_param schedparam;
schedparam.sched_priority = 0;
sched_setscheduler(0, SCHED_IDLE, &schedparam);
@ -1209,10 +1200,10 @@ static void *MonThread(void *)
try {
// Wait for connection
struct sockaddr_in client;
sockaddr_in client;
socklen_t socklen = sizeof(client);
memset(&client, 0, socklen);
context.fd = accept(monsocket, (struct sockaddr*)&client, &socklen);
context.fd = accept(monsocket, (sockaddr*)&client, &socklen);
if (context.fd < 0) {
throw io_exception("accept() failed");
}
@ -1242,21 +1233,20 @@ static void *MonThread(void *)
}
if (!PbOperation_IsValid(command.operation())) {
LOGERROR("Received unknown command with operation opcode %d", command.operation());
LOGERROR("Received unknown command with operation opcode %d", command.operation())
ReturnLocalizedError(context, ERROR_OPERATION, UNKNOWN_OPERATION);
continue;
}
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str())
PbResult result;
switch(command.operation()) {
case LOG_LEVEL: {
string log_level = GetParam(command, "level");
bool status = SetLogLevel(log_level);
if (!status) {
if (bool status = SetLogLevel(log_level); !status) {
ReturnLocalizedError(context, ERROR_LOG_LEVEL, log_level);
}
else {
@ -1266,9 +1256,8 @@ static void *MonThread(void *)
}
case DEFAULT_FOLDER: {
string result = rascsi_image.SetDefaultImageFolder(GetParam(command, "folder"));
if (!result.empty()) {
ReturnStatus(context, false, result);
if (string status = rascsi_image.SetDefaultImageFolder(GetParam(command, "folder")); !status.empty()) {
ReturnStatus(context, false, status);
}
else {
ReturnStatus(context);
@ -1317,16 +1306,15 @@ static void *MonThread(void *)
}
case IMAGE_FILE_INFO: {
string filename = GetParam(command, "file");
if (filename.empty()) {
if (string filename = GetParam(command, "file"); filename.empty()) {
ReturnLocalizedError(context, ERROR_MISSING_FILENAME);
}
else {
PbImageFile* image_file = new PbImageFile();
bool status = rascsi_response.GetImageFile(image_file, filename);
auto image_file = make_unique<PbImageFile>();
bool status = rascsi_response.GetImageFile(image_file.get(), filename);
if (status) {
result.set_status(true);
result.set_allocated_image_file_info(image_file);
result.set_allocated_image_file_info(image_file.get());
SerializeMessage(context.fd, result);
}
else {
@ -1378,7 +1366,7 @@ static void *MonThread(void *)
}
}
catch(const io_exception& e) {
LOGWARN("%s", e.get_msg().c_str());
LOGWARN("%s", e.get_msg().c_str())
// Fall through
}
@ -1404,15 +1392,14 @@ int main(int argc, char* argv[])
// Get temporary operation info, in order to trigger an assertion on startup if the operation list is incomplete
// TODO Move to unit test?
PbResult pb_operation_info_result;
const PbOperationInfo *operation_info = rascsi_response.GetOperationInfo(pb_operation_info_result, 0);
const auto operation_info = unique_ptr<PbOperationInfo>(rascsi_response.GetOperationInfo(pb_operation_info_result, 0));
assert(operation_info->operations_size() == PbOperation_ARRAYSIZE - 1);
delete operation_info;
#endif
BUS::phase_t phase;
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdout, nullptr, _IONBF, 0);
// Output the Banner
Banner(argc, argv);
@ -1450,8 +1437,8 @@ int main(int argc, char* argv[])
termination_handler.sa_handler = TerminationHandler;
sigemptyset(&termination_handler.sa_mask);
termination_handler.sa_flags = 0;
sigaction(SIGINT, &termination_handler, NULL);
sigaction(SIGTERM, &termination_handler, NULL);
sigaction(SIGINT, &termination_handler, nullptr);
sigaction(SIGTERM, &termination_handler, nullptr);
// Reset
Reset();
@ -1459,7 +1446,7 @@ int main(int argc, char* argv[])
// Set the affinity to a specific processor core
FixCpu(3);
struct sched_param schparam;
sched_param schparam;
#ifdef USE_SEL_EVENT_ENABLE
// Scheduling policy setting (highest priority)
schparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
@ -1491,6 +1478,7 @@ int main(int argc, char* argv[])
#else
bus->Acquire();
if (!bus->GetSEL()) {
// TODO Why sleep for 0 microseconds?
usleep(0);
continue;
}

View File

@ -20,8 +20,8 @@ private:
string msg;
public:
illegal_argument_exception(const string& msg) : msg(msg) {}
~illegal_argument_exception() {}
explicit illegal_argument_exception(const string& msg) : msg(msg) {}
~illegal_argument_exception() override = default;
const string& get_msg() const { return msg; }
};
@ -31,16 +31,14 @@ private:
string msg;
public:
io_exception(const string& msg) : msg(msg) {}
virtual ~io_exception() {}
explicit io_exception(const string& msg) : msg(msg) {}
~io_exception() override = default;
const string& get_msg() const { return msg; }
};
class file_not_found_exception : public io_exception {
public:
file_not_found_exception(const string& msg) : io_exception(msg) {}
~file_not_found_exception() {}
using io_exception::io_exception;
};
class scsi_error_exception : public exception {
@ -54,7 +52,7 @@ public:
scsi_defs::asc asc = scsi_defs::asc::NO_ADDITIONAL_SENSE_INFORMATION,
scsi_defs::status status = scsi_defs::status::CHECK_CONDITION)
: sense_key(sense_key), asc(asc), status(status) {}
~scsi_error_exception() {};
~scsi_error_exception() final = default;
scsi_defs::sense_key get_sense_key() const { return sense_key; }
scsi_defs::asc get_asc() const { return asc; }

View File

@ -30,8 +30,7 @@ RascsiImage::RascsiImage()
{
// ~/images is the default folder for device image files, for the root user it is /home/pi/images
int uid = getuid();
const char *sudo_user = getenv("SUDO_UID");
if (sudo_user) {
if (auto sudo_user = getenv("SUDO_UID"); sudo_user) {
uid = stoi(sudo_user);
}
@ -45,15 +44,14 @@ RascsiImage::RascsiImage()
}
}
bool RascsiImage::CheckDepth(const string& filename)
bool RascsiImage::CheckDepth(string_view filename) const
{
return count(filename.begin(), filename.end(), '/') <= depth;
}
bool RascsiImage::CreateImageFolder(const CommandContext& context, const string& filename)
bool RascsiImage::CreateImageFolder(const CommandContext& context, const string& filename) const
{
size_t filename_start = filename.rfind('/');
if (filename_start != string::npos) {
if (size_t filename_start = filename.rfind('/'); filename_start != string::npos) {
string folder = filename.substr(0, filename_start);
// Checking for existence first prevents an error if the top-level folder is a softlink
@ -82,8 +80,7 @@ string RascsiImage::SetDefaultImageFolder(const string& f)
// If a relative path is specified the path is assumed to be relative to the user's home directory
if (folder[0] != '/') {
int uid = getuid();
const char *sudo_user = getenv("SUDO_UID");
if (sudo_user) {
if (const char *sudo_user = getenv("SUDO_UID"); sudo_user) {
uid = stoi(sudo_user);
}
@ -108,19 +105,19 @@ string RascsiImage::SetDefaultImageFolder(const string& f)
default_image_folder = folder;
LOGINFO("Default image folder set to '%s'", default_image_folder.c_str());
LOGINFO("Default image folder set to '%s'", default_image_folder.c_str())
return "";
}
bool RascsiImage::IsValidSrcFilename(const string& filename)
bool RascsiImage::IsValidSrcFilename(const string& filename) const
{
// Source file must exist and must be a regular file or a symlink
struct stat st;
return !stat(filename.c_str(), &st) && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode));
}
bool RascsiImage::IsValidDstFilename(const string& filename)
bool RascsiImage::IsValidDstFilename(const string& filename) const
{
// Destination file must not yet exist
struct stat st;
@ -152,10 +149,10 @@ bool RascsiImage::CreateImage(const CommandContext& context, const PbCommand& co
try {
len = stoull(size);
}
catch(const invalid_argument& e) {
catch(const invalid_argument&) { //NOSONAR This exception is handled properly
return ReturnStatus(context, false, "Can't create image file '" + full_filename + "': Invalid file size " + size);
}
catch(const out_of_range& e) {
catch(const out_of_range&) { //NOSONAR This exception is handled properly
return ReturnStatus(context, false, "Can't create image file '" + full_filename + "': Invalid file size " + size);
}
if (len < 512 || (len & 0x1ff)) {
@ -187,7 +184,7 @@ bool RascsiImage::CreateImage(const CommandContext& context, const PbCommand& co
close(image_fd);
LOGINFO("%s", string("Created " + string(permissions & S_IWUSR ? "": "read-only ") + "image file '" + full_filename +
"' with a size of " + to_string(len) + " bytes").c_str());
"' with a size of " + to_string(len) + " bytes").c_str())
return ReturnStatus(context);
}
@ -224,8 +221,7 @@ bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& co
string folder = filename.substr(0, last_slash);
string full_folder = default_image_folder + "/" + folder;
std::error_code error;
if (!filesystem::is_empty(full_folder, error) || error) {
if (error_code error; !filesystem::is_empty(full_folder, error) || error) {
break;
}
@ -236,7 +232,7 @@ bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& co
last_slash = folder.rfind('/');
}
LOGINFO("Deleted image file '%s'", full_filename.c_str());
LOGINFO("Deleted image file '%s'", full_filename.c_str())
return ReturnStatus(context);
}
@ -279,7 +275,7 @@ bool RascsiImage::RenameImage(const CommandContext& context, const PbCommand& co
return ReturnStatus(context, false, "Can't rename/move image file '" + from + "' to '" + to + "': " + string(strerror(errno)));
}
LOGINFO("Renamed/Moved image file '%s' to '%s'", from.c_str(), to.c_str());
LOGINFO("Renamed/Moved image file '%s' to '%s'", from.c_str(), to.c_str())
return ReturnStatus(context);
}
@ -329,7 +325,7 @@ bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& comm
return ReturnStatus(context, false, "Can't copy symlink '" + from + "': " + string(strerror(errno)));
}
LOGINFO("Copied symlink '%s' to '%s'", from.c_str(), to.c_str());
LOGINFO("Copied symlink '%s' to '%s'", from.c_str(), to.c_str())
return ReturnStatus(context);
}
@ -351,7 +347,7 @@ bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& comm
return ReturnStatus(context, false, "Can't open destination image file '" + to + "': " + string(strerror(errno)));
}
if (sendfile(fd_dst, fd_src, 0, st.st_size) == -1) {
if (sendfile(fd_dst, fd_src, nullptr, st.st_size) == -1) {
close(fd_dst);
close(fd_src);
@ -363,7 +359,7 @@ bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& comm
close(fd_dst);
close(fd_src);
LOGINFO("Copied image file '%s' to '%s'", from.c_str(), to.c_str());
LOGINFO("Copied image file '%s' to '%s'", from.c_str(), to.c_str())
return ReturnStatus(context);
}
@ -386,18 +382,17 @@ bool RascsiImage::SetImagePermissions(const CommandContext& context, const PbCom
bool protect = command.operation() == PROTECT_IMAGE;
int permissions = protect ? S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
if (chmod(filename.c_str(), permissions) == -1) {
if (int permissions = protect ? S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
chmod(filename.c_str(), permissions) == -1) {
return ReturnStatus(context, false, "Can't " + string(protect ? "protect" : "unprotect") + " image file '" + filename + "': " +
strerror(errno));
}
if (protect) {
LOGINFO("Protected image file '%s'", filename.c_str());
LOGINFO("Protected image file '%s'", filename.c_str())
}
else {
LOGINFO("Unprotected image file '%s'", filename.c_str());
LOGINFO("Unprotected image file '%s'", filename.c_str())
}
return ReturnStatus(context);

View File

@ -21,16 +21,16 @@ class RascsiImage
public:
RascsiImage();
~RascsiImage() {};
~RascsiImage() = default;
void SetDepth(int depth) { this->depth = depth; }
int GetDepth() { return depth; }
bool CheckDepth(const string&);
bool CreateImageFolder(const CommandContext&, const string&);
void SetDepth(int d) { depth = d; }
int GetDepth() const { return depth; }
bool CheckDepth(string_view) const;
bool CreateImageFolder(const CommandContext&, const string&) const;
string GetDefaultImageFolder() const { return default_image_folder; }
string SetDefaultImageFolder(const string&);
bool IsValidSrcFilename(const string&);
bool IsValidDstFilename(const string&);
bool IsValidSrcFilename(const string&) const;
bool IsValidDstFilename(const string&) const;
bool CreateImage(const CommandContext&, const PbCommand&);
bool DeleteImage(const CommandContext&, const PbCommand&);
bool RenameImage(const CommandContext&, const PbCommand&);
@ -40,5 +40,5 @@ public:
private:
string default_image_folder;
int depth = -1;
int depth = 1;
};

View File

@ -24,7 +24,7 @@ list<string> RascsiResponse::log_levels = { "trace", "debug", "info", "warn", "e
PbDeviceProperties *RascsiResponse::GetDeviceProperties(const Device *device)
{
PbDeviceProperties *properties = new PbDeviceProperties();
auto properties = make_unique<PbDeviceProperties>().release();
properties->set_luns(AbstractController::LUN_MAX);
properties->set_read_only(device->IsReadOnly());
@ -39,9 +39,9 @@ PbDeviceProperties *RascsiResponse::GetDeviceProperties(const Device *device)
PbDeviceType_Parse(device->GetType(), &t);
if (device->SupportsParams()) {
for (const auto& param : device_factory->GetDefaultParams(t)) {
for (const auto& [key, value] : device_factory->GetDefaultParams(t)) {
auto& map = *properties->mutable_default_params();
map[param.first] = param.second;
map[key] = value;
}
}
@ -56,7 +56,7 @@ void RascsiResponse::GetDeviceTypeProperties(PbDeviceTypesInfo& device_types_inf
{
PbDeviceTypeProperties *type_properties = device_types_info.add_properties();
type_properties->set_type(type);
Device *device = device_factory->CreateDevice(type, "", -1);
const Device *device = device_factory->CreateDevice(type, "", -1);
type_properties->set_allocated_properties(GetDeviceProperties(device));
device_factory->DeleteDevice(device);
}
@ -87,7 +87,7 @@ void RascsiResponse::GetDevice(const Device *device, PbDevice *pb_device)
pb_device->set_allocated_properties(GetDeviceProperties(device));
PbDeviceStatus *status = new PbDeviceStatus();
auto status = make_unique<PbDeviceStatus>().release();
pb_device->set_allocated_status(status);
status->set_protected_(device->IsProtected());
status->set_stopped(device->IsStopped());
@ -95,22 +95,21 @@ void RascsiResponse::GetDevice(const Device *device, PbDevice *pb_device)
status->set_locked(device->IsLocked());
if (device->SupportsParams()) {
for (const auto& param : device->GetParams()) {
AddParam(*pb_device, param.first, param.second);
for (const auto& [key, value] : device->GetParams()) {
AddParam(*pb_device, key, value);
}
}
const Disk *disk = dynamic_cast<const Disk*>(device);
if (disk) {
if (const auto disk = dynamic_cast<const Disk*>(device); disk) {
pb_device->set_block_size(device->IsRemoved()? 0 : disk->GetSectorSizeInBytes());
pb_device->set_block_count(device->IsRemoved() ? 0: disk->GetBlockCount());
}
const FileSupport *file_support = dynamic_cast<const FileSupport *>(device);
const auto file_support = dynamic_cast<const FileSupport *>(device);
if (file_support) {
Filepath filepath;
file_support->GetPath(filepath);
PbImageFile *image_file = new PbImageFile();
auto image_file = make_unique<PbImageFile>().release();
GetImageFile(image_file, device->IsRemovable() && !device->IsReady() ? "" : filepath.GetPath());
pb_device->set_allocated_file(image_file);
}
@ -126,7 +125,7 @@ bool RascsiResponse::GetImageFile(PbImageFile *image_file, const string& filenam
image_file->set_read_only(access(f.c_str(), W_OK));
struct stat st;
struct stat st; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (!stat(f.c_str(), &st) && !S_ISDIR(st.st_mode)) {
image_file->set_size(st.st_size);
return true;
@ -136,7 +135,7 @@ bool RascsiResponse::GetImageFile(PbImageFile *image_file, const string& filenam
return false;
}
void RascsiResponse::GetAvailableImages(PbImageFilesInfo& image_files_info, const string& default_image_folder,
void RascsiResponse::GetAvailableImages(PbImageFilesInfo& image_files_info, string_view default_image_folder,
const string& folder, const string& folder_pattern, const string& file_pattern, int scan_depth) {
string folder_pattern_lower = folder_pattern;
transform(folder_pattern_lower.begin(), folder_pattern_lower.end(), folder_pattern_lower.begin(), ::tolower);
@ -145,9 +144,8 @@ void RascsiResponse::GetAvailableImages(PbImageFilesInfo& image_files_info, cons
transform(file_pattern_lower.begin(), file_pattern_lower.end(), file_pattern_lower.begin(), ::tolower);
if (scan_depth-- >= 0) {
DIR *d = opendir(folder.c_str());
if (d) {
struct dirent *dir;
if (DIR *d = opendir(folder.c_str()); d) {
const dirent *dir;
while ((dir = readdir(d))) {
bool is_supported_type = dir->d_type == DT_REG || dir->d_type == DT_DIR || dir->d_type == DT_LNK || dir->d_type == DT_BLK;
if (is_supported_type && dir->d_name[0] != '.') {
@ -161,11 +159,11 @@ void RascsiResponse::GetAvailableImages(PbImageFilesInfo& image_files_info, cons
struct stat st;
if (dir->d_type == DT_REG && !stat(filename.c_str(), &st)) {
if (!st.st_size) {
LOGWARN("File '%s' in image folder '%s' has a size of 0 bytes", dir->d_name, folder.c_str());
LOGWARN("File '%s' in image folder '%s' has a size of 0 bytes", dir->d_name, folder.c_str())
continue;
}
} else if (dir->d_type == DT_LNK && stat(filename.c_str(), &st)) {
LOGWARN("Symlink '%s' in image folder '%s' is broken", dir->d_name, folder.c_str());
LOGWARN("Symlink '%s' in image folder '%s' is broken", dir->d_name, folder.c_str())
continue;
} else if (dir->d_type == DT_DIR) {
if (folder_pattern_lower.empty() || name_lower.find(folder_pattern_lower) != string::npos) {
@ -176,11 +174,10 @@ void RascsiResponse::GetAvailableImages(PbImageFilesInfo& image_files_info, cons
}
if (file_pattern_lower.empty() || name_lower.find(file_pattern_lower) != string::npos) {
PbImageFile *image_file = new PbImageFile();
if (GetImageFile(image_file, filename)) {
auto image_file = make_unique<PbImageFile>();
if (GetImageFile(image_file.get(), filename)) {
GetImageFile(image_files_info.add_image_files(), filename.substr(default_image_folder.length() + 1));
}
delete image_file;
}
}
}
@ -193,7 +190,7 @@ void RascsiResponse::GetAvailableImages(PbImageFilesInfo& image_files_info, cons
PbImageFilesInfo *RascsiResponse::GetAvailableImages(PbResult& result, const string& folder_pattern,
const string& file_pattern, int scan_depth)
{
PbImageFilesInfo *image_files_info = new PbImageFilesInfo();
auto image_files_info = make_unique<PbImageFilesInfo>().release();
string default_image_folder = rascsi_image->GetDefaultImageFolder();
image_files_info->set_default_image_folder(default_image_folder);
@ -219,7 +216,7 @@ void RascsiResponse::GetAvailableImages(PbResult& result, PbServerInfo& server_i
PbReservedIdsInfo *RascsiResponse::GetReservedIds(PbResult& result, const unordered_set<int>& ids)
{
PbReservedIdsInfo *reserved_ids_info = new PbReservedIdsInfo();
auto reserved_ids_info = make_unique<PbReservedIdsInfo>().release();
for (int id : ids) {
reserved_ids_info->add_ids(id);
}
@ -258,7 +255,7 @@ void RascsiResponse::GetDevicesInfo(PbResult& result, const PbCommand& command)
}
}
PbDevicesInfo *devices_info = new PbDevicesInfo();
auto devices_info = make_unique<PbDevicesInfo>().release();
result.set_allocated_devices_info(devices_info);
for (const auto& id_set : id_sets) {
@ -270,7 +267,7 @@ void RascsiResponse::GetDevicesInfo(PbResult& result, const PbCommand& command)
PbDeviceTypesInfo *RascsiResponse::GetDeviceTypesInfo(PbResult& result)
{
PbDeviceTypesInfo *device_types_info = new PbDeviceTypesInfo();
auto device_types_info = make_unique<PbDeviceTypesInfo>().release();
GetAllDeviceTypeProperties(*device_types_info);
@ -282,7 +279,7 @@ PbDeviceTypesInfo *RascsiResponse::GetDeviceTypesInfo(PbResult& result)
PbServerInfo *RascsiResponse::GetServerInfo(PbResult& result, const unordered_set<int>& reserved_ids,
const string& current_log_level, const string& folder_pattern, const string& file_pattern, int scan_depth)
{
PbServerInfo *server_info = new PbServerInfo();
auto server_info = make_unique<PbServerInfo>().release();
server_info->set_allocated_version_info(GetVersionInfo(result));
server_info->set_allocated_log_level_info(GetLogLevelInfo(result, current_log_level));
@ -301,7 +298,7 @@ PbServerInfo *RascsiResponse::GetServerInfo(PbResult& result, const unordered_se
PbVersionInfo *RascsiResponse::GetVersionInfo(PbResult& result)
{
PbVersionInfo *version_info = new PbVersionInfo();
auto version_info = make_unique<PbVersionInfo>().release();
version_info->set_major_version(rascsi_major_version);
version_info->set_minor_version(rascsi_minor_version);
@ -314,7 +311,7 @@ PbVersionInfo *RascsiResponse::GetVersionInfo(PbResult& result)
PbLogLevelInfo *RascsiResponse::GetLogLevelInfo(PbResult& result, const string& current_log_level)
{
PbLogLevelInfo *log_level_info = new PbLogLevelInfo();
auto log_level_info = make_unique<PbLogLevelInfo>().release();
for (const auto& log_level : log_levels) {
log_level_info->add_log_levels(log_level);
@ -329,7 +326,7 @@ PbLogLevelInfo *RascsiResponse::GetLogLevelInfo(PbResult& result, const string&
PbNetworkInterfacesInfo *RascsiResponse::GetNetworkInterfacesInfo(PbResult& result)
{
PbNetworkInterfacesInfo *network_interfaces_info = new PbNetworkInterfacesInfo();
auto network_interfaces_info = make_unique<PbNetworkInterfacesInfo>().release();
for (const auto& network_interface : device_factory->GetNetworkInterfaces()) {
network_interfaces_info->add_name(network_interface);
@ -342,7 +339,7 @@ PbNetworkInterfacesInfo *RascsiResponse::GetNetworkInterfacesInfo(PbResult& resu
PbMappingInfo *RascsiResponse::GetMappingInfo(PbResult& result)
{
PbMappingInfo *mapping_info = new PbMappingInfo();
auto mapping_info = make_unique<PbMappingInfo>().release();
for (const auto& mapping : device_factory->GetExtensionMapping()) {
(*mapping_info->mutable_mapping())[mapping.first] = mapping.second;
@ -355,141 +352,141 @@ PbMappingInfo *RascsiResponse::GetMappingInfo(PbResult& result)
PbOperationInfo *RascsiResponse::GetOperationInfo(PbResult& result, int depth)
{
PbOperationInfo *operation_info = new PbOperationInfo();
auto operation_info = make_unique<PbOperationInfo>().release();
PbOperationMetaData *meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "name", "Image file name in case of a mass storage device");
AddOperationParameter(meta_data, "interface", "Comma-separated prioritized network interface list");
AddOperationParameter(meta_data, "inet", "IP address and netmask of the network bridge");
AddOperationParameter(meta_data, "cmd", "Print command for the printer device");
AddOperationParameter(meta_data, "timeout", "Reservation timeout for the printer device in seconds");
CreateOperation(operation_info, meta_data, ATTACH, "Attach device, device-specific parameters are required");
auto meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "name", "Image file name in case of a mass storage device");
AddOperationParameter(meta_data.get(), "interface", "Comma-separated prioritized network interface list");
AddOperationParameter(meta_data.get(), "inet", "IP address and netmask of the network bridge");
AddOperationParameter(meta_data.get(), "cmd", "Print command for the printer device");
AddOperationParameter(meta_data.get(), "timeout", "Reservation timeout for the printer device in seconds");
CreateOperation(operation_info, meta_data.get(), ATTACH, "Attach device, device-specific parameters are required");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, DETACH, "Detach device, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), DETACH, "Detach device, device-specific parameters are required");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, DETACH_ALL, "Detach all devices");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), DETACH_ALL, "Detach all devices");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, START, "Start device, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), START, "Start device, device-specific parameters are required");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, STOP, "Stop device, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), STOP, "Stop device, device-specific parameters are required");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data, INSERT, "Insert medium, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data.get(), INSERT, "Insert medium, device-specific parameters are required");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, EJECT, "Eject medium, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), EJECT, "Eject medium, device-specific parameters are required");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, PROTECT, "Protect medium, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), PROTECT, "Protect medium, device-specific parameters are required");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, UNPROTECT, "Unprotect medium, device-specific parameters are required");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), UNPROTECT, "Unprotect medium, device-specific parameters are required");
meta_data = new PbOperationMetaData();
meta_data = make_unique<PbOperationMetaData>();
if (depth) {
AddOperationParameter(meta_data, "folder_pattern", "Pattern for filtering image folder names");
AddOperationParameter(meta_data.get(), "folder_pattern", "Pattern for filtering image folder names");
}
AddOperationParameter(meta_data, "file_pattern", "Pattern for filtering image file names");
CreateOperation(operation_info, meta_data, SERVER_INFO, "Get rascsi server information");
AddOperationParameter(meta_data.get(), "file_pattern", "Pattern for filtering image file names");
CreateOperation(operation_info, meta_data.get(), SERVER_INFO, "Get rascsi server information");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, VERSION_INFO, "Get rascsi server version");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), VERSION_INFO, "Get rascsi server version");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, DEVICES_INFO, "Get information on attached devices");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), DEVICES_INFO, "Get information on attached devices");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, DEVICE_TYPES_INFO, "Get device properties by device type");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), DEVICE_TYPES_INFO, "Get device properties by device type");
meta_data = new PbOperationMetaData();
meta_data = make_unique<PbOperationMetaData>();
if (depth) {
AddOperationParameter(meta_data, "folder_pattern", "Pattern for filtering image folder names");
AddOperationParameter(meta_data.get(), "folder_pattern", "Pattern for filtering image folder names");
}
AddOperationParameter(meta_data, "file_pattern", "Pattern for filtering image file names");
CreateOperation(operation_info, meta_data, DEFAULT_IMAGE_FILES_INFO, "Get information on available image files");
AddOperationParameter(meta_data.get(), "file_pattern", "Pattern for filtering image file names");
CreateOperation(operation_info, meta_data.get(), DEFAULT_IMAGE_FILES_INFO, "Get information on available image files");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data, IMAGE_FILE_INFO, "Get information on image file");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data.get(), IMAGE_FILE_INFO, "Get information on image file");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, LOG_LEVEL_INFO, "Get log level information");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), LOG_LEVEL_INFO, "Get log level information");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, NETWORK_INTERFACES_INFO, "Get the available network interfaces");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), NETWORK_INTERFACES_INFO, "Get the available network interfaces");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, MAPPING_INFO, "Get mapping of extensions to device types");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), MAPPING_INFO, "Get mapping of extensions to device types");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, RESERVED_IDS_INFO, "Get list of reserved device IDs");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), RESERVED_IDS_INFO, "Get list of reserved device IDs");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "folder", "Default image file folder name", "", true);
CreateOperation(operation_info, meta_data, DEFAULT_FOLDER, "Set default image file folder");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "folder", "Default image file folder name", "", true);
CreateOperation(operation_info, meta_data.get(), DEFAULT_FOLDER, "Set default image file folder");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "level", "New log level", "", true);
CreateOperation(operation_info, meta_data, LOG_LEVEL, "Set log level");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "level", "New log level", "", true);
CreateOperation(operation_info, meta_data.get(), LOG_LEVEL, "Set log level");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "ids", "Comma-separated device ID list", "", true);
CreateOperation(operation_info, meta_data, RESERVE_IDS, "Reserve device IDs");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "ids", "Comma-separated device ID list", "", true);
CreateOperation(operation_info, meta_data.get(), RESERVE_IDS, "Reserve device IDs");
meta_data = new PbOperationMetaData();
PbOperationParameter *parameter = AddOperationParameter(meta_data, "mode", "Shutdown mode", "", true);
meta_data = make_unique<PbOperationMetaData>();
PbOperationParameter *parameter = AddOperationParameter(meta_data.get(), "mode", "Shutdown mode", "", true);
parameter->add_permitted_values("rascsi");
// System shutdown/reboot requires root permissions
if (!getuid()) {
parameter->add_permitted_values("system");
parameter->add_permitted_values("reboot");
}
CreateOperation(operation_info, meta_data, SHUT_DOWN, "Shut down or reboot");
CreateOperation(operation_info, meta_data.get(), SHUT_DOWN, "Shut down or reboot");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "file", "Image file name", "", true);
AddOperationParameter(meta_data, "size", "Image file size in bytes", "", true);
parameter = AddOperationParameter(meta_data, "read_only", "Read-only flag", "false");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "file", "Image file name", "", true);
AddOperationParameter(meta_data.get(), "size", "Image file size in bytes", "", true);
parameter = AddOperationParameter(meta_data.get(), "read_only", "Read-only flag", "false");
parameter->add_permitted_values("true");
parameter->add_permitted_values("false");
CreateOperation(operation_info, meta_data, CREATE_IMAGE, "Create an image file");
CreateOperation(operation_info, meta_data.get(), CREATE_IMAGE, "Create an image file");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data, DELETE_IMAGE, "Delete image file");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data.get(), DELETE_IMAGE, "Delete image file");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "from", "Source image file name", "", true);
AddOperationParameter(meta_data, "to", "Destination image file name", "", true);
CreateOperation(operation_info, meta_data, RENAME_IMAGE, "Rename image file");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "from", "Source image file name", "", true);
AddOperationParameter(meta_data.get(), "to", "Destination image file name", "", true);
CreateOperation(operation_info, meta_data.get(), RENAME_IMAGE, "Rename image file");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "from", "Source image file name", "", true);
AddOperationParameter(meta_data, "to", "Destination image file name", "", true);
parameter = AddOperationParameter(meta_data, "read_only", "Read-only flag", "false");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "from", "Source image file name", "", true);
AddOperationParameter(meta_data.get(), "to", "Destination image file name", "", true);
parameter = AddOperationParameter(meta_data.get(), "read_only", "Read-only flag", "false");
parameter->add_permitted_values("true");
parameter->add_permitted_values("false");
CreateOperation(operation_info, meta_data, COPY_IMAGE, "Copy image file");
CreateOperation(operation_info, meta_data.get(), COPY_IMAGE, "Copy image file");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data, PROTECT_IMAGE, "Write-protect image file");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data.get(), PROTECT_IMAGE, "Write-protect image file");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data, UNPROTECT_IMAGE, "Make image file writable");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "file", "Image file name", "", true);
CreateOperation(operation_info, meta_data.get(), UNPROTECT_IMAGE, "Make image file writable");
meta_data = new PbOperationMetaData();
AddOperationParameter(meta_data, "token", "Authentication token to be checked", "", true);
CreateOperation(operation_info, meta_data, CHECK_AUTHENTICATION, "Check whether an authentication token is valid");
meta_data = make_unique<PbOperationMetaData>();
AddOperationParameter(meta_data.get(), "token", "Authentication token to be checked", "", true);
CreateOperation(operation_info, meta_data.get(), CHECK_AUTHENTICATION, "Check whether an authentication token is valid");
meta_data = new PbOperationMetaData();
CreateOperation(operation_info, meta_data, OPERATION_INFO, "Get operation meta data");
meta_data = make_unique<PbOperationMetaData>();
CreateOperation(operation_info, meta_data.get(), OPERATION_INFO, "Get operation meta data");
result.set_status(true);
@ -503,7 +500,6 @@ void RascsiResponse::CreateOperation(PbOperationInfo *operation_info, PbOperatio
meta_data->set_description(description);
int ordinal = PbOperation_descriptor()->FindValueByName(PbOperation_Name(operation))->index();
(*operation_info->mutable_operations())[ordinal] = *meta_data;
delete meta_data;
}
PbOperationParameter *RascsiResponse::AddOperationParameter(PbOperationMetaData *meta_data, const string& name,

View File

@ -27,7 +27,7 @@ public:
RascsiResponse(DeviceFactory *device_factory, const RascsiImage *rascsi_image)
: device_factory(device_factory), rascsi_image(rascsi_image) {}
~RascsiResponse() {}
~RascsiResponse() = default;
bool GetImageFile(PbImageFile *, const string&);
PbImageFilesInfo *GetAvailableImages(PbResult&, const string&, const string&, int);
@ -53,7 +53,7 @@ private:
void GetDevice(const Device *, PbDevice *);
void GetAllDeviceTypeProperties(PbDeviceTypesInfo&);
void GetDeviceTypeProperties(PbDeviceTypesInfo&, PbDeviceType);
void GetAvailableImages(PbImageFilesInfo&, const string&, const string&, const string&, const string&, int);
void GetAvailableImages(PbImageFilesInfo&, string_view, const string&, const string&, const string&, int);
void GetAvailableImages(PbResult& result, PbServerInfo&, const string&, const string&, int);
void CreateOperation(PbOperationInfo *, PbOperationMetaData *, const PbOperation&, const string&);
PbOperationParameter *AddOperationParameter(PbOperationMetaData *, const string&, const string&,

View File

@ -21,16 +21,16 @@
#include <list>
// Separator for the INQUIRY name components and for compound parameters
#define COMPONENT_SEPARATOR ':'
static const char COMPONENT_SEPARATOR = ':';
using namespace std;
using namespace rascsi_interface;
using namespace ras_util;
using namespace protobuf_util;
PbOperation ParseOperation(const char *optarg)
PbOperation ParseOperation(const string& operation)
{
switch (tolower(optarg[0])) {
switch (tolower(operation[0])) {
case 'a':
return ATTACH;
@ -57,18 +57,17 @@ PbOperation ParseOperation(const char *optarg)
}
}
PbDeviceType ParseType(const char *optarg)
PbDeviceType ParseType(const char *type)
{
string t = optarg;
string t = type;
transform(t.begin(), t.end(), t.begin(), ::toupper);
PbDeviceType type;
if (PbDeviceType_Parse(t, &type)) {
return type;
if (PbDeviceType parsed_type; PbDeviceType_Parse(t, &parsed_type)) {
return parsed_type;
}
// Parse convenience device types (shortcuts)
switch (tolower(optarg[0])) {
switch (tolower(type[0])) {
case 'c':
return SCCD;
@ -98,12 +97,11 @@ PbDeviceType ParseType(const char *optarg)
}
}
void SetPatternParams(PbCommand& command, const string& patterns)
void SetPatternParams(PbCommand& command, string_view patterns)
{
string folder_pattern;
string file_pattern;
size_t separator_pos = patterns.find(COMPONENT_SEPARATOR);
if (separator_pos != string::npos) {
if (size_t separator_pos = patterns.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
folder_pattern = patterns.substr(0, separator_pos);
file_pattern = patterns.substr(separator_pos + 1);
}
@ -300,8 +298,7 @@ int main(int argc, char* argv[])
string revision;
string s = optarg;
size_t separator_pos = s.find(COMPONENT_SEPARATOR);
if (separator_pos != string::npos) {
if (size_t separator_pos = s.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
vendor = s.substr(0, separator_pos);
s = s.substr(separator_pos + 1);
separator_pos = s.find(COMPONENT_SEPARATOR);
@ -367,9 +364,14 @@ int main(int argc, char* argv[])
case 'z':
locale = optarg;
break;
default:
break;
}
}
// TODO For macos only 'if (optind != argc)' appears to work, but then non-argument options do not reject arguments
if (optopt) {
exit(EXIT_FAILURE);
}

View File

@ -18,13 +18,13 @@
#include <list>
// Separator for the INQUIRY name components
#define COMPONENT_SEPARATOR ':'
static const char COMPONENT_SEPARATOR = ':';
using namespace std;
using namespace rascsi_interface;
using namespace protobuf_util;
RasctlCommands::RasctlCommands(PbCommand& command, const string& hostname, int port, const string& token,
RasctlCommands::RasctlCommands(const PbCommand& command, const string& hostname, int port, const string& token,
const string& locale)
: command(command), hostname(hostname), port(port), token(token), locale(locale)
{
@ -43,7 +43,7 @@ void RasctlCommands::SendCommand()
// Send command
int fd = -1;
try {
struct hostent *host = gethostbyname(hostname.c_str());
const hostent *host = gethostbyname(hostname.c_str());
if (!host) {
throw io_exception("Can't resolve hostname '" + hostname + "'");
}
@ -53,10 +53,9 @@ void RasctlCommands::SendCommand()
throw io_exception("Can't create socket");
}
struct sockaddr_in server;
memset(&server, 0, sizeof(server));
sockaddr_in server = {};
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_port = htons((uint16_t)port);
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
memcpy(&server.sin_addr.s_addr, host->h_addr, host->h_length);
@ -127,10 +126,9 @@ void RasctlCommands::CommandReserveIds(const string& reserved_ids)
void RasctlCommands::CommandCreateImage(const string& image_params)
{
size_t separator_pos = image_params.find(COMPONENT_SEPARATOR);
if (separator_pos != string::npos) {
AddParam(command, "file", image_params.substr(0, separator_pos));
AddParam(command, "size", image_params.substr(separator_pos + 1));
if (size_t separator_pos = image_params.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
AddParam(command, "file", string_view(image_params).substr(0, separator_pos));
AddParam(command, "size", string_view(image_params).substr(separator_pos + 1));
}
else {
cerr << "Error: Invalid file descriptor '" << image_params << "', format is NAME:SIZE" << endl;
@ -151,10 +149,9 @@ void RasctlCommands::CommandDeleteImage(const string& filename)
void RasctlCommands::CommandRenameImage(const string& image_params)
{
size_t separator_pos = image_params.find(COMPONENT_SEPARATOR);
if (separator_pos != string::npos) {
AddParam(command, "from", image_params.substr(0, separator_pos));
AddParam(command, "to", image_params.substr(separator_pos + 1));
if (size_t separator_pos = image_params.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
AddParam(command, "from", string_view(image_params).substr(0, separator_pos));
AddParam(command, "to", string_view(image_params).substr(separator_pos + 1));
}
else {
cerr << "Error: Invalid file descriptor '" << image_params << "', format is CURRENT_NAME:NEW_NAME" << endl;
@ -166,10 +163,9 @@ void RasctlCommands::CommandRenameImage(const string& image_params)
void RasctlCommands::CommandCopyImage(const string& image_params)
{
size_t separator_pos = image_params.find(COMPONENT_SEPARATOR);
if (separator_pos != string::npos) {
AddParam(command, "from", image_params.substr(0, separator_pos));
AddParam(command, "to", image_params.substr(separator_pos + 1));
if (size_t separator_pos = image_params.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
AddParam(command, "from", string_view(image_params).substr(0, separator_pos));
AddParam(command, "to", string_view(image_params).substr(separator_pos + 1));
}
else {
cerr << "Error: Invalid file descriptor '" << image_params << "', format is CURRENT_NAME:NEW_NAME" << endl;

View File

@ -20,8 +20,8 @@ class RasctlCommands
{
public:
RasctlCommands(PbCommand&, const string&, int, const string&, const string&);
~RasctlCommands() {};
RasctlCommands(const PbCommand&, const string&, int, const string&, const string&);
~RasctlCommands() = default;
void SendCommand();
void CommandDevicesInfo();

View File

@ -3,7 +3,7 @@
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2021 Uwe Seimet
// Copyright (C) 2021-2022 Uwe Seimet
//
//---------------------------------------------------------------------------
@ -17,13 +17,13 @@ using namespace std;
using namespace rascsi_interface;
using namespace ras_util;
void RasctlDisplay::DisplayDevices(const PbDevicesInfo& devices_info)
void RasctlDisplay::DisplayDevices(const PbDevicesInfo& devices_info) const
{
const list<PbDevice>& devices = { devices_info.devices().begin(), devices_info.devices().end() };
cout << ListDevices(devices) << endl;
}
void RasctlDisplay::DisplayDeviceInfo(const PbDevice& pb_device)
void RasctlDisplay::DisplayDeviceInfo(const PbDevice& pb_device) const
{
cout << " " << pb_device.id() << ":" << pb_device.unit() << " " << PbDeviceType_Name(pb_device.type())
<< " " << pb_device.vendor() << ":" << pb_device.product() << ":" << pb_device.revision();
@ -79,18 +79,18 @@ void RasctlDisplay::DisplayDeviceInfo(const PbDevice& pb_device)
// Creates a sorted map
map<string, string> params = { pb_device.params().begin(), pb_device.params().end() };
bool isFirst = true;
for (const auto& param : params) {
for (const auto& [key, value] : params) {
if (!isFirst) {
cout << ":";
}
isFirst = false;
cout << param.first << "=" << param.second;
cout << key << "=" << value;
}
cout << endl;
}
void RasctlDisplay::DisplayVersionInfo(const PbVersionInfo& version_info)
void RasctlDisplay::DisplayVersionInfo(const PbVersionInfo& version_info) const
{
cout << "rascsi server version: " << version_info.major_version() << "." << version_info.minor_version();
if (version_info.patch_version() > 0) {
@ -102,7 +102,7 @@ void RasctlDisplay::DisplayVersionInfo(const PbVersionInfo& version_info)
cout << endl;
}
void RasctlDisplay::DisplayLogLevelInfo(const PbLogLevelInfo& log_level_info)
void RasctlDisplay::DisplayLogLevelInfo(const PbLogLevelInfo& log_level_info) const
{
if (!log_level_info.log_levels_size()) {
cout << " No log level settings available" << endl;
@ -117,7 +117,7 @@ void RasctlDisplay::DisplayLogLevelInfo(const PbLogLevelInfo& log_level_info)
cout << "Current rascsi log level: " << log_level_info.current_log_level() << endl;
}
void RasctlDisplay::DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types_info)
void RasctlDisplay::DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types_info) const
{
cout << "Supported device types and their properties:";
for (const auto& device_type_info : device_types_info.properties()) {
@ -125,8 +125,7 @@ void RasctlDisplay::DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types
const PbDeviceProperties& properties = device_type_info.properties();
if (properties.read_only() || properties.protectable() || properties.stoppable() || properties.read_only()
|| properties.lockable()) {
if (properties.read_only() || properties.protectable() || properties.stoppable() || properties.lockable()) {
cout << "Properties: ";
bool has_property = false;
if (properties.read_only()) {
@ -165,11 +164,11 @@ void RasctlDisplay::DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types
cout << "Default parameters: ";
bool isFirst = true;
for (const auto& param : params) {
for (const auto& [key, value] : params) {
if (!isFirst) {
cout << endl << " ";
}
cout << param.first << "=" << param.second;
cout << key << "=" << value;
isFirst = false;
}
@ -194,7 +193,7 @@ void RasctlDisplay::DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types
}
}
void RasctlDisplay::DisplayReservedIdsInfo(const PbReservedIdsInfo& reserved_ids_info)
void RasctlDisplay::DisplayReservedIdsInfo(const PbReservedIdsInfo& reserved_ids_info) const
{
if (reserved_ids_info.ids_size()) {
cout << "Reserved device IDs: ";
@ -208,7 +207,7 @@ void RasctlDisplay::DisplayReservedIdsInfo(const PbReservedIdsInfo& reserved_ids
}
}
void RasctlDisplay::DisplayImageFile(const PbImageFile& image_file_info)
void RasctlDisplay::DisplayImageFile(const PbImageFile& image_file_info) const
{
cout << image_file_info.name() << " " << image_file_info.size() << " bytes";
if (image_file_info.read_only()) {
@ -221,7 +220,7 @@ void RasctlDisplay::DisplayImageFile(const PbImageFile& image_file_info)
}
void RasctlDisplay::DisplayImageFiles(const PbImageFilesInfo& image_files_info)
void RasctlDisplay::DisplayImageFiles(const PbImageFilesInfo& image_files_info) const
{
cout << "Default image file folder: " << image_files_info.default_image_folder() << endl;
cout << "Supported folder depth: " << image_files_info.depth() << endl;
@ -241,7 +240,7 @@ void RasctlDisplay::DisplayImageFiles(const PbImageFilesInfo& image_files_info)
}
}
void RasctlDisplay::DisplayNetworkInterfaces(const PbNetworkInterfacesInfo& network_interfaces_info)
void RasctlDisplay::DisplayNetworkInterfaces(const PbNetworkInterfacesInfo& network_interfaces_info) const
{
// Creates a sorted list
const list<string> interfaces = { network_interfaces_info.name().begin(), network_interfaces_info.name().end() };
@ -261,45 +260,45 @@ void RasctlDisplay::DisplayNetworkInterfaces(const PbNetworkInterfacesInfo& netw
cout << endl;
}
void RasctlDisplay::DisplayMappingInfo(const PbMappingInfo& mapping_info)
void RasctlDisplay::DisplayMappingInfo(const PbMappingInfo& mapping_info) const
{
// Creates a sorted map
const map<string, PbDeviceType> mappings = { mapping_info.mapping().begin(), mapping_info.mapping().end() };
cout << "Supported image file extension to device type mappings:" << endl;
for (const auto& mapping : mappings) {
cout << " " << mapping.first << "->" << PbDeviceType_Name(mapping.second) << endl;
for (const auto& [extension, type] : mappings) {
cout << " " << extension << "->" << PbDeviceType_Name(type) << endl;
}
}
void RasctlDisplay::DisplayOperationInfo(const PbOperationInfo& operation_info)
void RasctlDisplay::DisplayOperationInfo(const PbOperationInfo& operation_info) const
{
const map<int, PbOperationMetaData> operations = { operation_info.operations().begin(), operation_info.operations().end() };
// Copies result into a map sorted by operation name
const PbOperationMetaData *unknown_operation = new PbOperationMetaData();
map<string, PbOperationMetaData> sorted_operations;
for (const auto& operation : operations) {
if (PbOperation_IsValid(static_cast<PbOperation>(operation.first))) {
sorted_operations[PbOperation_Name(static_cast<PbOperation>(operation.first))] = operation.second;
for (const auto& [ordinal, meta_data] : operations) {
if (PbOperation_IsValid(static_cast<PbOperation>(ordinal))) {
sorted_operations[PbOperation_Name(static_cast<PbOperation>(ordinal))] = meta_data;
}
else {
// If the server-side operation is unknown for the client use the server-provided operation name
// No further operation information is available in this case
sorted_operations[operation.second.server_side_name()] = *unknown_operation;
sorted_operations[meta_data.server_side_name()] = *unknown_operation;
}
}
cout << "Operations supported by rascsi server and their parameters:" << endl;
for (const auto& operation : sorted_operations) {
if (!operation.second.server_side_name().empty()) {
cout << " " << operation.first;
if (!operation.second.description().empty()) {
cout << " (" << operation.second.description() << ")";
for (const auto& [name, meta_data] : sorted_operations) {
if (!meta_data.server_side_name().empty()) {
cout << " " << name;
if (!meta_data.description().empty()) {
cout << " (" << meta_data.description() << ")";
}
cout << endl;
list<PbOperationParameter> sorted_parameters = { operation.second.parameters().begin(), operation.second.parameters().end() };
list<PbOperationParameter> sorted_parameters = { meta_data.parameters().begin(), meta_data.parameters().end() };
sorted_parameters.sort([](const auto& a, const auto& b) { return a.name() < b.name(); });
for (const auto& parameter : sorted_parameters) {
@ -329,7 +328,7 @@ void RasctlDisplay::DisplayOperationInfo(const PbOperationInfo& operation_info)
}
}
else {
cout << " " << operation.first << " (Unknown server-side operation)" << endl;
cout << " " << name << " (Unknown server-side operation)" << endl;
}
}
}

View File

@ -3,7 +3,7 @@
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2021 Uwe Seimet
// Copyright (C) 2021-2022 Uwe Seimet
//
//---------------------------------------------------------------------------
@ -17,18 +17,18 @@ class RasctlDisplay
{
public:
RasctlDisplay() {};
~RasctlDisplay() {};
RasctlDisplay() = default;
~RasctlDisplay() = default;
void DisplayDevices(const PbDevicesInfo&);
void DisplayDeviceInfo(const PbDevice&);
void DisplayVersionInfo(const PbVersionInfo&);
void DisplayLogLevelInfo(const PbLogLevelInfo&);
void DisplayDeviceTypesInfo(const PbDeviceTypesInfo&);
void DisplayReservedIdsInfo(const PbReservedIdsInfo&);
void DisplayImageFile(const PbImageFile&);
void DisplayImageFiles(const PbImageFilesInfo&);
void DisplayNetworkInterfaces(const PbNetworkInterfacesInfo&);
void DisplayMappingInfo(const PbMappingInfo&);
void DisplayOperationInfo(const PbOperationInfo&);
void DisplayDevices(const PbDevicesInfo&) const;
void DisplayDeviceInfo(const PbDevice&) const;
void DisplayVersionInfo(const PbVersionInfo&) const;
void DisplayLogLevelInfo(const PbLogLevelInfo&) const;
void DisplayDeviceTypesInfo(const PbDeviceTypesInfo&) const;
void DisplayReservedIdsInfo(const PbReservedIdsInfo&) const;
void DisplayImageFile(const PbImageFile&) const;
void DisplayImageFiles(const PbImageFilesInfo&) const;
void DisplayNetworkInterfaces(const PbNetworkInterfacesInfo&) const;
void DisplayMappingInfo(const PbMappingInfo&) const;
void DisplayOperationInfo(const PbOperationInfo&) const;
};

View File

@ -21,7 +21,7 @@
// Constant Declaration
//
//---------------------------------------------------------------------------
#define BUFSIZE 1024 * 64 // Buffer size of about 64KB
static const int BUFSIZE = 1024 * 64; // Buffer size of about 64KB
//---------------------------------------------------------------------------
//
@ -141,7 +141,7 @@ void Reset()
bool ParseArgument(int argc, char* argv[])
{
int opt;
char *file = nullptr;
const char *file = nullptr;
// Argument Parsing
opterr = 0;
@ -162,6 +162,9 @@ bool ParseArgument(int argc, char* argv[])
case 'r':
restore = true;
break;
default:
break;
}
}

View File

@ -3,7 +3,7 @@
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2021 Uwe Seimet
// Copyright (C) 2021-22 Uwe Seimet
//
//---------------------------------------------------------------------------
@ -22,12 +22,12 @@ bool ras_util::GetAsInt(const string& value, int& result)
}
try {
result = std::stoul(value);
result = (int)stoul(value);
}
catch(const invalid_argument& e) {
catch(const invalid_argument&) {
return false;
}
catch(const out_of_range& e) {
catch(const out_of_range&) {
return false;
}

View File

@ -43,8 +43,8 @@ public:
reserved // Unused
};
BUS() {}
virtual ~BUS() {}
BUS() = default;
virtual ~BUS() = default;
// Basic Functions
virtual bool Init(mode_e mode) = 0;
@ -108,9 +108,6 @@ public:
// Set SCSI output signal value
static const int SEND_NO_DELAY = -1;
// Passed into SendHandShake when we don't want to delay
protected:
phase_t m_current_phase = phase_t::reserved;
private:
static const phase_t phase_table[8];

View File

@ -24,27 +24,6 @@
using namespace std;
//---------------------------------------------------------------------------
//
// Constant declarations
//
//---------------------------------------------------------------------------
// Symbol definition for the VCD file
// These are just arbitrary symbols. They can be anything allowed by the VCD file format,
// as long as they're consistently used.
#define SYMBOL_PIN_DAT '#'
#define SYMBOL_PIN_ATN '+'
#define SYMBOL_PIN_RST '$'
#define SYMBOL_PIN_ACK '%'
#define SYMBOL_PIN_REQ '^'
#define SYMBOL_PIN_MSG '&'
#define SYMBOL_PIN_CD '*'
#define SYMBOL_PIN_IO '('
#define SYMBOL_PIN_BSY ')'
#define SYMBOL_PIN_SEL '-'
#define SYMBOL_PIN_PHASE '='
//---------------------------------------------------------------------------
//
// Variable declarations
@ -132,15 +111,15 @@ void parse_arguments(int argc, char *argv[])
//---------------------------------------------------------------------------
void print_copyright_text(int, char *[])
{
LOGINFO("SCSI Monitor Capture Tool - part of RaSCSI(*^..^*) ");
LOGINFO("SCSI Monitor Capture Tool - part of RaSCSI(*^..^*) ")
LOGINFO("version %s (%s, %s)",
rascsi_get_version_string(),
__DATE__,
__TIME__);
LOGINFO("Powered by XM6 TypeG Technology ");
LOGINFO("Copyright (C) 2016-2020 GIMONS");
LOGINFO("Copyright (C) 2020-2021 Contributors to the RaSCSI project");
LOGINFO(" ");
__TIME__)
LOGINFO("Powered by XM6 TypeG Technology ")
LOGINFO("Copyright (C) 2016-2020 GIMONS")
LOGINFO("Copyright (C) 2020-2021 Contributors to the RaSCSI project")
LOGINFO(" ")
}
//---------------------------------------------------------------------------
@ -150,12 +129,12 @@ void print_copyright_text(int, char *[])
//---------------------------------------------------------------------------
void print_help_text(int, char *argv[])
{
LOGINFO("%s -i [input file json] -b [buffer size] [output file]", argv[0]);
LOGINFO(" -i [input file json] - scsimon will parse the json file instead of capturing new data");
LOGINFO(" If -i option is not specified, scsimon will read the gpio pins");
LOGINFO(" -b [buffer size] - Override the default buffer size of %d.", buff_size);
LOGINFO(" [output file] - Base name of the output files. The file extension (ex: .json)");
LOGINFO(" will be appended to this file name");
LOGINFO("%s -i [input file json] -b [buffer size] [output file]", argv[0])
LOGINFO(" -i [input file json] - scsimon will parse the json file instead of capturing new data")
LOGINFO(" If -i option is not specified, scsimon will read the gpio pins")
LOGINFO(" -b [buffer size] - Override the default buffer size of %d.", buff_size)
LOGINFO(" [output file] - Base name of the output files. The file extension (ex: .json)")
LOGINFO(" will be appended to this file name")
}
//---------------------------------------------------------------------------
@ -167,19 +146,19 @@ void Banner(int, char *[])
{
if (import_data)
{
LOGINFO("Reading input file: %s", input_file_name);
LOGINFO("Reading input file: %s", input_file_name)
}
else
{
LOGINFO("Reading live data from the GPIO pins");
LOGINFO(" Connection type : %s", CONNECT_DESC);
LOGINFO("Reading live data from the GPIO pins")
LOGINFO(" Connection type : %s", CONNECT_DESC)
}
LOGINFO(" Data buffer size: %u", buff_size);
LOGINFO(" ");
LOGINFO("Generating output files:");
LOGINFO(" %s - Value Change Dump file that can be opened with GTKWave", vcd_file_name);
LOGINFO(" %s - JSON file with raw data", json_file_name);
LOGINFO(" %s - HTML file with summary of commands", html_file_name);
LOGINFO(" Data buffer size: %u", buff_size)
LOGINFO(" ")
LOGINFO("Generating output files:")
LOGINFO(" %s - Value Change Dump file that can be opened with GTKWave", vcd_file_name)
LOGINFO(" %s - JSON file with raw data", json_file_name)
LOGINFO(" %s - HTML file with summary of commands", html_file_name)
}
//---------------------------------------------------------------------------
@ -207,7 +186,7 @@ bool Init()
bus = new GPIOBUS();
if (!bus->Init())
{
LOGERROR("Unable to intiailize the GPIO bus. Exiting....");
LOGERROR("Unable to intiailize the GPIO bus. Exiting....")
return false;
}
@ -224,14 +203,14 @@ void Cleanup()
{
if (!import_data)
{
LOGINFO("Stopping data collection....");
LOGINFO("Stopping data collection....")
}
LOGINFO(" ");
LOGINFO("Generating %s...", vcd_file_name);
LOGINFO(" ")
LOGINFO("Generating %s...", vcd_file_name)
scsimon_generate_value_change_dump(vcd_file_name, data_buffer, data_idx);
LOGINFO("Generating %s...", json_file_name);
LOGINFO("Generating %s...", json_file_name)
scsimon_generate_json(json_file_name, data_buffer, data_idx);
LOGINFO("Generating %s...", html_file_name);
LOGINFO("Generating %s...", html_file_name)
scsimon_generate_html(html_file_name, data_buffer, data_idx);
if (bus)
@ -317,23 +296,22 @@ int main(int argc, char *argv[])
// Output the Banner
Banner(argc, argv);
data_buffer = (data_capture *)malloc(sizeof(data_capture_t) * buff_size);
bzero(data_buffer, sizeof(data_capture_t) * buff_size);
data_buffer = (data_capture *)calloc(buff_size, sizeof(data_capture_t));
if (import_data)
{
data_idx = scsimon_read_json(input_file_name, data_buffer, buff_size);
if (data_idx > 0)
{
LOGDEBUG("Read %d samples from %s", data_idx, input_file_name);
LOGDEBUG("Read %d samples from %s", data_idx, input_file_name)
Cleanup();
}
exit(0);
}
LOGINFO(" ");
LOGINFO(" ")
LOGINFO("Now collecting data.... Press CTRL-C to stop.")
LOGINFO(" ");
LOGINFO(" ")
// Initialize
int ret = 0;
@ -360,9 +338,9 @@ int main(int argc, char *argv[])
running = true;
bus->SetACT(FALSE);
(void)gettimeofday(&start_time, NULL);
(void)gettimeofday(&start_time, nullptr);
LOGDEBUG("ALL_SCSI_PINS %08X\n", ALL_SCSI_PINS);
LOGDEBUG("ALL_SCSI_PINS %08X\n", ALL_SCSI_PINS)
// Main Loop
while (running)
@ -372,12 +350,12 @@ int main(int argc, char *argv[])
loop_count++;
if (loop_count > LLONG_MAX - 1)
{
LOGINFO("Maximum amount of time has elapsed. SCSIMON is terminating.");
LOGINFO("Maximum amount of time has elapsed. SCSIMON is terminating.")
running = false;
}
if (data_idx >= (buff_size - 2))
{
LOGINFO("Internal data buffer is full. SCSIMON is terminating.");
LOGINFO("Internal data buffer is full. SCSIMON is terminating.")
running = false;
}
@ -391,7 +369,7 @@ int main(int argc, char *argv[])
low_bits &= this_sample;
if ((high_bits != prev_high) || (low_bits != prev_low))
{
LOGDEBUG(" %08X %08X\n", high_bits, low_bits);
LOGDEBUG(" %08X %08X\n", high_bits, low_bits)
}
prev_high = high_bits;
prev_low = low_bits;
@ -399,7 +377,7 @@ int main(int argc, char *argv[])
{
s.str("");
s << "Collected " << data_idx << " samples...";
LOGDEBUG("%s", s.str().c_str());
LOGDEBUG("%s", s.str().c_str())
}
#endif
data_buffer[data_idx].data = this_sample;
@ -419,23 +397,23 @@ int main(int argc, char *argv[])
data_idx++;
}
(void)gettimeofday(&stop_time, NULL);
(void)gettimeofday(&stop_time, nullptr);
timersub(&stop_time, &start_time, &time_diff);
elapsed_us = ((time_diff.tv_sec * 1000000) + time_diff.tv_usec);
s.str("");
s << "Elapsed time: " << elapsed_us << " microseconds (" << elapsed_us / 1000000 << " seconds)";
LOGINFO("%s", s.str().c_str());
LOGINFO("%s", s.str().c_str())
s.str("");
s << "Collected " << data_idx << " changes";
LOGINFO("%s", s.str().c_str());
LOGINFO("%s", s.str().c_str())
// Note: ns_per_loop is a global variable that is used by Cleanup() to printout the timestamps.
ns_per_loop = (elapsed_us * 1000) / (double)loop_count;
s.str("");
s << "Read the SCSI bus " << loop_count << " times with an average of " << ns_per_loop << " ns for each read";
LOGINFO("%s", s.str().c_str());
LOGINFO("%s", s.str().c_str())
Cleanup();

View File

@ -16,7 +16,7 @@ class TestDevice : public Device
public:
TestDevice() : Device("test") {}
~TestDevice() {}
~TestDevice() = default;
bool Dispatch() { return false; }
};

View File

@ -12,7 +12,9 @@
class TestFileSupport : public FileSupport
{
void Open(const Filepath&) {}
void Open(const Filepath&) {
// Do nothing when running unit tests
}
};
TEST(FileSupportTest, FileSupport)

View File

@ -19,7 +19,7 @@
using namespace std;
unordered_set<uint32_t> sector_sizes;
const unordered_set<uint32_t> sector_sizes;
TEST(ModePagesTest, ModePageDevice_AddModePages)
{
@ -54,7 +54,7 @@ TEST(ModePagesTest, SCSIHD_NEC_AddModePages)
{
map<int, vector<BYTE>> mode_pages;
MockSCSIHD_NEC device(sector_sizes);
MockSCSIHD_NEC device;
device.AddModePages(mode_pages, 0x3f, false);
EXPECT_EQ(5, mode_pages.size()) << "Unexpected number of code pages";

View File

@ -17,8 +17,8 @@ class Environment : public ::testing::Environment
{
public:
Environment() {}
~Environment() {}
Environment() = default;
~Environment() final = default;
// Turn off logging
void SetUp() override { spdlog::set_level(spdlog::level::off); }

View File

@ -60,8 +60,8 @@ public:
MOCK_METHOD(bool, GetSignal, (int), (const, override));
MOCK_METHOD(void, SetSignal, (int, bool), (override));
MockBus() {}
~MockBus() {}
MockBus() = default;
~MockBus() = default;
};
class MockAbstractController : public AbstractController
@ -97,8 +97,8 @@ public:
MOCK_METHOD(void, SetPhase, (BUS::phase_t), (override));
MOCK_METHOD(void, Reset, (), (override));
MockAbstractController(int target_id) : AbstractController(nullptr, target_id) {}
~MockAbstractController() {}
explicit MockAbstractController(int target_id) : AbstractController(nullptr, target_id) {}
~MockAbstractController() = default;
};
class MockScsiController : public ScsiController
@ -106,7 +106,6 @@ class MockScsiController : public ScsiController
public:
MOCK_METHOD(BUS::phase_t, Process, (int), (override));
MOCK_METHOD(int, GetEffectiveLun, (), (const override));
MOCK_METHOD(void, Error, (scsi_defs::sense_key, scsi_defs::asc, scsi_defs::status), (override));
MOCK_METHOD(int, GetInitiatorId, (), (const override));
MOCK_METHOD(void, SetUnit, (int), ());
@ -138,7 +137,7 @@ public:
FRIEND_TEST(PrimaryDeviceTest, UnknownCommand);
MockScsiController(BUS *bus, int target_id) : ScsiController(bus, target_id) {}
~MockScsiController() {}
~MockScsiController() = default;
};
class MockPrimaryDevice : public PrimaryDevice
@ -148,7 +147,7 @@ public:
MOCK_METHOD(vector<BYTE>, InquiryInternal, (), (const));
MockPrimaryDevice() : PrimaryDevice("test") {}
~MockPrimaryDevice() {}
~MockPrimaryDevice() = default;
// Make protected methods visible for testing
@ -164,8 +163,8 @@ class MockModePageDevice : public ModePageDevice
{
public:
MockModePageDevice() : ModePageDevice("test") { }
~MockModePageDevice() { }
MockModePageDevice() : ModePageDevice("test") {}
~MockModePageDevice() = default;
MOCK_METHOD(vector<BYTE>, InquiryInternal, (), (const));
MOCK_METHOD(int, ModeSense6, (const DWORD *, BYTE *, int), ());
@ -191,24 +190,24 @@ class MockSCSIHD : public SCSIHD
{
FRIEND_TEST(ModePagesTest, SCSIHD_AddModePages);
MockSCSIHD(const unordered_set<uint32_t>& sector_sizes) : SCSIHD(sector_sizes, false) { };
~MockSCSIHD() { };
explicit MockSCSIHD(const unordered_set<uint32_t>& sector_sizes) : SCSIHD(sector_sizes, false) {}
~MockSCSIHD() = default;
};
class MockSCSIHD_NEC : public SCSIHD_NEC
{
FRIEND_TEST(ModePagesTest, SCSIHD_NEC_AddModePages);
MockSCSIHD_NEC(const unordered_set<uint32_t>& sector_sizes) : SCSIHD_NEC(sector_sizes) { };
~MockSCSIHD_NEC() { };
MockSCSIHD_NEC() = default;
~MockSCSIHD_NEC() = default;
};
class MockSCSICD : public SCSICD
{
FRIEND_TEST(ModePagesTest, SCSICD_AddModePages);
MockSCSICD(const unordered_set<uint32_t>& sector_sizes) : SCSICD(sector_sizes) { };
~MockSCSICD() { };
explicit MockSCSICD(const unordered_set<uint32_t>& sector_sizes) : SCSICD(sector_sizes) {}
~MockSCSICD() = default;
};
class MockSCSIMO : public SCSIMO
@ -216,14 +215,14 @@ class MockSCSIMO : public SCSIMO
FRIEND_TEST(ModePagesTest, SCSIMO_AddModePages);
MockSCSIMO(const unordered_set<uint32_t>& sector_sizes, const unordered_map<uint64_t, Geometry>& geometries)
: SCSIMO(sector_sizes, geometries) { };
~MockSCSIMO() { };
: SCSIMO(sector_sizes, geometries) {}
~MockSCSIMO() = default;
};
class MockHostServices : public HostServices
{
FRIEND_TEST(ModePagesTest, HostServices_AddModePages);
MockHostServices() { };
~MockHostServices() { };
MockHostServices() = default;
~MockHostServices() = default;
};