mirror of
https://github.com/akuker/RASCSI.git
synced 2025-02-27 15:30:06 +00:00
Added Devices message to protobuf interface (#141)
* Removed all BAREMETAL ifdefs * Cleaned up subfolders * Fixed regression * Re-added underscores * Fixed merge conflicts * Assume RASCSI is always defined * Fixed mege issue * Re-added result message * Added Devices message to protobuf interface * Fixed typo * Fixed include file names * Updated files to be ignored by git * Merge with develop branch * Synchronized output with develop branch * Fixed missing dependency, causing issues when running "make -j1" * Fixed handling of connection errors * Improved protobuf interface upwards compatibility * Use -g instead of -s, this has less conflict potential with future options * Made log level options consistent (rascsi and rasctl used a different option)
This commit is contained in:
parent
3c5a0003a4
commit
62e7727a48
5
src/raspberrypi/.gitignore
vendored
5
src/raspberrypi/.gitignore
vendored
@ -12,3 +12,8 @@ sasidump
|
|||||||
rasdump
|
rasdump
|
||||||
obj
|
obj
|
||||||
bin
|
bin
|
||||||
|
/rascsi_interface.pb.cpp
|
||||||
|
/rascsi_interface.pb.h
|
||||||
|
.project
|
||||||
|
.cproject
|
||||||
|
.settings
|
||||||
|
@ -74,10 +74,10 @@ BINDIR := ./bin/$(shell echo $(CONNECT_TYPE) | tr '[:upper:]' '[:lower:]')
|
|||||||
BIN_ALL = $(BINDIR)/$(RASCSI) $(BINDIR)/$(RASCTL) $(BINDIR)/$(SCSIMON)
|
BIN_ALL = $(BINDIR)/$(RASCSI) $(BINDIR)/$(RASCTL) $(BINDIR)/$(SCSIMON)
|
||||||
|
|
||||||
SRC_PROTOC = \
|
SRC_PROTOC = \
|
||||||
rasctl_interface.proto
|
rascsi_interface.proto
|
||||||
|
|
||||||
SRC_PROTOBUF = \
|
SRC_PROTOBUF = \
|
||||||
rasctl_interface.pb.cpp
|
rascsi_interface.pb.cpp
|
||||||
|
|
||||||
SRC_RASCSI = \
|
SRC_RASCSI = \
|
||||||
rascsi.cpp \
|
rascsi.cpp \
|
||||||
@ -138,7 +138,7 @@ OBJ_RASDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASDUMP:%.cpp=%.o)))
|
|||||||
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
|
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
|
||||||
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o)))
|
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o)))
|
||||||
|
|
||||||
GEN_PROTOBUF := $(SRC_PROTOBUF) rasctl_interface.pb.h
|
GEN_PROTOBUF := $(SRC_PROTOBUF) rascsi_interface.pb.h
|
||||||
|
|
||||||
|
|
||||||
# The following will include all of the auto-generated dependency files (*.d)
|
# The following will include all of the auto-generated dependency files (*.d)
|
||||||
@ -156,7 +156,7 @@ $(OBJDIR)/%.o: %.cpp | $(OBJDIR)
|
|||||||
$(SRC_PROTOBUF): $(SRC_PROTOC)
|
$(SRC_PROTOBUF): $(SRC_PROTOC)
|
||||||
echo "-- Generating protobuf-based source files"
|
echo "-- Generating protobuf-based source files"
|
||||||
protoc --cpp_out=. $(SRC_PROTOC)
|
protoc --cpp_out=. $(SRC_PROTOC)
|
||||||
mv rasctl_interface.pb.cc $@
|
mv rascsi_interface.pb.cc $@
|
||||||
|
|
||||||
## Build Targets:
|
## Build Targets:
|
||||||
## all : Rebuild all of the executable files and re-generate
|
## all : Rebuild all of the executable files and re-generate
|
||||||
@ -169,10 +169,10 @@ ALL: all
|
|||||||
|
|
||||||
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt
|
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt
|
||||||
|
|
||||||
$(BINDIR)/$(RASCSI): $(OBJ_RASCSI) | $(BINDIR)
|
$(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI) | $(BINDIR)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz -lpcap -lprotobuf-lite
|
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz -lpcap -lprotobuf-lite
|
||||||
|
|
||||||
$(BINDIR)/$(RASCTL): $(OBJ_RASCTL) | $(BINDIR)
|
$(BINDIR)/$(RASCTL): $(SRC_PROTOBUF) $(OBJ_RASCTL) | $(BINDIR)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) -lprotobuf-lite
|
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) -lprotobuf-lite
|
||||||
|
|
||||||
$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR)
|
$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "rascsi_version.h"
|
#include "rascsi_version.h"
|
||||||
#include "rasutil.h"
|
#include "rasutil.h"
|
||||||
#include "rasctl_interface.pb.h"
|
#include "rascsi_interface.pb.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
#include <spdlog/async.h>
|
#include <spdlog/async.h>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace spdlog;
|
using namespace spdlog;
|
||||||
using namespace rasctl_interface;
|
using namespace rascsi_interface;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@ -250,75 +250,88 @@ void Reset()
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// List Devices
|
// Get the list of attached devices
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
string ListDevice() {
|
Devices GetDevices() {
|
||||||
char type[5];
|
Devices devices;
|
||||||
char dev_status[_MAX_FNAME+26];
|
|
||||||
ostringstream s;
|
|
||||||
|
|
||||||
bool has_header = false;
|
|
||||||
type[4] = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < CtrlMax * UnitNum; i++) {
|
for (int i = 0; i < CtrlMax * UnitNum; i++) {
|
||||||
strncpy(dev_status,"",sizeof(dev_status));
|
|
||||||
// Initialize ID and unit number
|
|
||||||
int id = i / UnitNum;
|
|
||||||
int un = i % UnitNum;
|
|
||||||
Disk *pUnit = disk[i];
|
|
||||||
|
|
||||||
// skip if unit does not exist or null disk
|
// skip if unit does not exist or null disk
|
||||||
if (pUnit == NULL || pUnit->IsNULL()) {
|
Disk *pUnit = disk[i];
|
||||||
|
if (!pUnit || pUnit->IsNULL()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the header
|
Device *device = devices.add_devices();
|
||||||
if (!has_header) {
|
|
||||||
s << endl
|
// Initialize ID and unit number
|
||||||
<< "+----+----+------+-------------------------------------" << endl
|
device->set_id(i / UnitNum);
|
||||||
<< "| ID | UN | TYPE | DEVICE STATUS" << endl
|
device->set_un(i % UnitNum);
|
||||||
<< "+----+----+------+-------------------------------------" << endl;
|
|
||||||
LOGINFO( "+----+----+------+-------------------------------------");
|
|
||||||
LOGINFO( "| ID | UN | TYPE | DEVICE STATUS");
|
|
||||||
LOGINFO( "+----+----+------+-------------------------------------\n");
|
|
||||||
has_header = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID,UNIT,Type,Device Status
|
// ID,UNIT,Type,Device Status
|
||||||
|
char type[5];
|
||||||
type[0] = (char)(pUnit->GetID() >> 24);
|
type[0] = (char)(pUnit->GetID() >> 24);
|
||||||
type[1] = (char)(pUnit->GetID() >> 16);
|
type[1] = (char)(pUnit->GetID() >> 16);
|
||||||
type[2] = (char)(pUnit->GetID() >> 8);
|
type[2] = (char)(pUnit->GetID() >> 8);
|
||||||
type[3] = (char)(pUnit->GetID());
|
type[3] = (char)(pUnit->GetID());
|
||||||
|
type[4] = 0;
|
||||||
|
device->set_type(type);
|
||||||
|
|
||||||
// mount status output
|
// mount status output
|
||||||
if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) {
|
if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) {
|
||||||
strncpy(dev_status,"X68000 HOST BRIDGE",sizeof(dev_status));
|
device->set_file("X68000 HOST BRIDGE");
|
||||||
} else if (pUnit->GetID() == MAKEID('S', 'C', 'D', 'P')) {
|
} else if (pUnit->GetID() == MAKEID('S', 'C', 'D', 'P')) {
|
||||||
strncpy(dev_status,"DaynaPort SCSI/Link",sizeof(dev_status));
|
device->set_file("DaynaPort SCSI/Link");
|
||||||
} else {
|
} else {
|
||||||
Filepath filepath;
|
Filepath filepath;
|
||||||
pUnit->GetPath(filepath);
|
pUnit->GetPath(filepath);
|
||||||
snprintf(dev_status, sizeof(dev_status), "%s",
|
device->set_file(pUnit->IsRemovable() && !pUnit->IsReady() ? "NO MEDIA" : filepath.GetPath());
|
||||||
(pUnit->IsRemovable() && !pUnit->IsReady()) ?
|
|
||||||
"NO MEDIA" : filepath.GetPath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write protection status
|
// Write protection status
|
||||||
if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) {
|
if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) {
|
||||||
strcat(dev_status, " (WRITEPROTECT)");
|
device->set_read_only(true);
|
||||||
}
|
}
|
||||||
s << "| " << id << " | " << un << " | " << type << " | " << dev_status << endl;
|
|
||||||
LOGINFO( "| %d | %d | %s | %s", id, un, type, dev_status);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no controller, find will be null
|
return devices;
|
||||||
if (!has_header) {
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// List and log devices
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
string ListDevices(Devices devices) {
|
||||||
|
ostringstream s;
|
||||||
|
|
||||||
|
if (devices.devices_size()) {
|
||||||
|
s << endl
|
||||||
|
<< "+----+----+------+-------------------------------------" << endl
|
||||||
|
<< "| ID | UN | TYPE | DEVICE STATUS" << endl
|
||||||
|
<< "+----+----+------+-------------------------------------" << endl;
|
||||||
|
|
||||||
|
LOGINFO( "+----+----+------+-------------------------------------");
|
||||||
|
LOGINFO( "| ID | UN | TYPE | DEVICE STATUS");
|
||||||
|
LOGINFO( "+----+----+------+-------------------------------------\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
return "No images currently attached.\n";
|
return "No images currently attached.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < devices.devices_size() ; i++) {
|
||||||
|
Device device = devices.devices(i);
|
||||||
|
|
||||||
|
s << "| " << device.id() << " | " << device.un() << " | " << device.type() << " | "
|
||||||
|
<< device.file() << (device.read_only() ? " (WRITEPROTECT)" : "") << endl;
|
||||||
|
|
||||||
|
LOGINFO( "| %d | %d | %s | %s%s", device.id(), device.un(), device.type().c_str(),
|
||||||
|
device.file().c_str(), device.read_only() ? " (WRITEPROTECT)" : "");
|
||||||
|
}
|
||||||
|
|
||||||
s << "+----+----+------+-------------------------------------" << endl;
|
s << "+----+----+------+-------------------------------------" << endl;
|
||||||
|
|
||||||
LOGINFO( "+----+----+------+-------------------------------------");
|
LOGINFO( "+----+----+------+-------------------------------------");
|
||||||
|
|
||||||
return s.str();
|
return s.str();
|
||||||
@ -574,9 +587,9 @@ bool ProcessCmd(int fd, const Command &command)
|
|||||||
pUnit = new SCSIDaynaPort();
|
pUnit = new SCSIDaynaPort();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ostringstream msg;
|
ostringstream error;
|
||||||
msg << "rasctl sent a command for an invalid drive type: " << type;
|
error << "rasctl sent a command for an invalid drive type: " << type;
|
||||||
return ReturnStatus(fd, false, msg.str());
|
return ReturnStatus(fd, false, error.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// drive checks files
|
// drive checks files
|
||||||
@ -593,9 +606,9 @@ bool ProcessCmd(int fd, const Command &command)
|
|||||||
|
|
||||||
LOGWARN("rasctl tried to open an invalid file %s", file.c_str());
|
LOGWARN("rasctl tried to open an invalid file %s", file.c_str());
|
||||||
|
|
||||||
ostringstream msg;
|
ostringstream error;
|
||||||
msg << "Error : File open error [" << file << "]";
|
error << "File open error [" << file << "]";
|
||||||
return ReturnStatus(fd, false, msg.str());
|
return ReturnStatus(fd, false, error.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,9 +671,9 @@ bool ProcessCmd(int fd, const Command &command)
|
|||||||
pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) {
|
pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) {
|
||||||
LOGWARN("rasctl sent an Insert/Eject/Protect command (%d) for incompatible type %s", cmd, type_str);
|
LOGWARN("rasctl sent an Insert/Eject/Protect command (%d) for incompatible type %s", cmd, type_str);
|
||||||
|
|
||||||
ostringstream msg;
|
ostringstream error;
|
||||||
msg << "Error : Operation denied (Device type " << type_str << " isn't removable)";
|
error << "Operation denied (Device type " << type_str << " isn't removable)";
|
||||||
return ReturnStatus(fd, false, msg.str());
|
return ReturnStatus(fd, false, error.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@ -669,10 +682,10 @@ bool ProcessCmd(int fd, const Command &command)
|
|||||||
LOGINFO("rasctl commanded insert file %s into %s ID: %d UN: %d", params.c_str(), type_str, id, un);
|
LOGINFO("rasctl commanded insert file %s into %s ID: %d UN: %d", params.c_str(), type_str, id, un);
|
||||||
|
|
||||||
if (!pUnit->Open(filepath)) {
|
if (!pUnit->Open(filepath)) {
|
||||||
ostringstream msg;
|
ostringstream error;
|
||||||
msg << "Error : File open error [" << params << "]";
|
error << "File open error [" << params << "]";
|
||||||
|
|
||||||
return ReturnStatus(fd, false, msg.str());
|
return ReturnStatus(fd, false, error.str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -692,10 +705,10 @@ bool ProcessCmd(int fd, const Command &command)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ostringstream msg;
|
ostringstream error;
|
||||||
msg << "Received unknown command from rasctl: " << cmd;
|
error << "Received unknown command from rasctl: " << cmd;
|
||||||
LOGWARN("%s", msg.str().c_str());
|
LOGWARN("%s", error.str().c_str());
|
||||||
return ReturnStatus(fd, false, msg.str());
|
return ReturnStatus(fd, false, error.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReturnStatus(fd, true);
|
return ReturnStatus(fd, true);
|
||||||
@ -718,7 +731,7 @@ bool ParseArgument(int argc, char* argv[])
|
|||||||
string log_level = "trace";
|
string log_level = "trace";
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "-IiHhL:l:D:d:")) != -1) {
|
while ((opt = getopt(argc, argv, "-IiHhG:g:D:d:")) != -1) {
|
||||||
switch (tolower(opt)) {
|
switch (tolower(opt)) {
|
||||||
case 'i':
|
case 'i':
|
||||||
is_sasi = false;
|
is_sasi = false;
|
||||||
@ -732,7 +745,7 @@ bool ParseArgument(int argc, char* argv[])
|
|||||||
id = -1;
|
id = -1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'l':
|
case 'g':
|
||||||
log_level = optarg;
|
log_level = optarg;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -801,7 +814,9 @@ bool ParseArgument(int argc, char* argv[])
|
|||||||
SetLogLevel(log_level);
|
SetLogLevel(log_level);
|
||||||
|
|
||||||
// Display the device list
|
// Display the device list
|
||||||
fprintf(stdout, "%s", ListDevice().c_str());
|
Devices devices = GetDevices();
|
||||||
|
cout << ListDevices(devices) << endl;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,12 +883,11 @@ static void *MonThread(void *param)
|
|||||||
|
|
||||||
// List all of the devices
|
// List all of the devices
|
||||||
if (command.cmd() == LIST) {
|
if (command.cmd() == LIST) {
|
||||||
Result result;
|
Devices devices = GetDevices();
|
||||||
result.set_msg(ListDevice() + "\n");
|
ListDevices(devices);
|
||||||
result.set_status(true);
|
|
||||||
|
|
||||||
string data;
|
string data;
|
||||||
result.SerializeToString(&data);
|
devices.SerializeToString(&data);
|
||||||
SerializeProtobufData(fd, data);
|
SerializeProtobufData(fd, data);
|
||||||
}
|
}
|
||||||
else if (command.cmd() == LOG_LEVEL) {
|
else if (command.cmd() == LOG_LEVEL) {
|
||||||
@ -912,6 +926,8 @@ static void *MonThread(void *param)
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int actid;
|
int actid;
|
||||||
DWORD now;
|
DWORD now;
|
||||||
|
57
src/raspberrypi/rascsi_interface.proto
Normal file
57
src/raspberrypi/rascsi_interface.proto
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
|
||||||
|
package rascsi_interface;
|
||||||
|
|
||||||
|
// The supported device types
|
||||||
|
enum DeviceType {
|
||||||
|
UNDEFINED = 0;
|
||||||
|
SASI_HD = 1;
|
||||||
|
SCSI_HD = 2;
|
||||||
|
MO = 3;
|
||||||
|
CD = 4;
|
||||||
|
BR = 5;
|
||||||
|
NUVOLINK = 6;
|
||||||
|
DAYNAPORT = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rascsi remote operations
|
||||||
|
enum Operation {
|
||||||
|
NONE = 0;
|
||||||
|
LIST = 1;
|
||||||
|
ATTACH = 2;
|
||||||
|
DETACH = 3;
|
||||||
|
INSERT = 4;
|
||||||
|
EJECT = 5;
|
||||||
|
PROTECT = 6;
|
||||||
|
LOG_LEVEL = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commands rascsi can execute
|
||||||
|
message Command {
|
||||||
|
Operation cmd = 1;
|
||||||
|
int32 id = 2;
|
||||||
|
int32 un = 3;
|
||||||
|
DeviceType type = 4;
|
||||||
|
string params = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The result of a command
|
||||||
|
message Result {
|
||||||
|
bool status = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The device meta data
|
||||||
|
message Device {
|
||||||
|
int32 id = 1;
|
||||||
|
int32 un = 2;
|
||||||
|
string type = 3;
|
||||||
|
string file = 4;
|
||||||
|
bool read_only = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Devices {
|
||||||
|
repeated Device devices = 1;
|
||||||
|
}
|
@ -14,17 +14,19 @@
|
|||||||
#include "rascsi_version.h"
|
#include "rascsi_version.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "rasutil.h"
|
#include "rasutil.h"
|
||||||
#include "rasctl_interface.pb.h"
|
#include "rascsi_interface.pb.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rasctl_interface;
|
using namespace rascsi_interface;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Send Command
|
// Send Command
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL SendCommand(const char *hostname, const Command& command)
|
int SendCommand(const char *hostname, const Command& command)
|
||||||
{
|
{
|
||||||
// Create a socket to send the command
|
// Create a socket to send the command
|
||||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
@ -43,24 +45,43 @@ BOOL SendCommand(const char *hostname, const Command& command)
|
|||||||
|
|
||||||
// Connect
|
// Connect
|
||||||
if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
|
if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
|
||||||
fprintf(stderr, "Error : Can't connect to rascsi process on host '%s'\n", hostname);
|
cerr << "Error: Can't connect to rascsi process on host '" << hostname << "'" << endl;
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string data;
|
string data;
|
||||||
command.SerializeToString(&data);
|
command.SerializeToString(&data);
|
||||||
|
|
||||||
// Receive the message
|
|
||||||
bool status = true;
|
|
||||||
try {
|
try {
|
||||||
SerializeProtobufData(fd, data);
|
SerializeProtobufData(fd, data);
|
||||||
|
}
|
||||||
|
catch(const ioexception& e) {
|
||||||
|
cerr << "Error : " << e.getmsg() << endl;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Receive command result
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
bool ReceiveResult(int fd) {
|
||||||
|
bool status = true;
|
||||||
|
try {
|
||||||
Result result;
|
Result result;
|
||||||
result.ParseFromString(DeserializeProtobufData(fd));
|
result.ParseFromString(DeserializeProtobufData(fd));
|
||||||
|
|
||||||
status = result.status();
|
status = result.status();
|
||||||
|
if (status) {
|
||||||
if (!result.msg().empty()) {
|
cerr << result.msg();
|
||||||
|
}
|
||||||
|
else {
|
||||||
cout << result.msg();
|
cout << result.msg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +89,8 @@ BOOL SendCommand(const char *hostname, const Command& command)
|
|||||||
cerr << "Error: " << e.getmsg() << endl;
|
cerr << "Error: " << e.getmsg() << endl;
|
||||||
|
|
||||||
// Fall through
|
// Fall through
|
||||||
|
|
||||||
|
status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -75,6 +98,31 @@ BOOL SendCommand(const char *hostname, const Command& command)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ListDevices(const Devices& devices) {
|
||||||
|
ostringstream s;
|
||||||
|
|
||||||
|
if (devices.devices_size()) {
|
||||||
|
s << endl
|
||||||
|
<< "+----+----+------+-------------------------------------" << endl
|
||||||
|
<< "| ID | UN | TYPE | DEVICE STATUS" << endl
|
||||||
|
<< "+----+----+------+-------------------------------------" << endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No images currently attached.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < devices.devices_size() ; i++) {
|
||||||
|
Device device = devices.devices(i);
|
||||||
|
|
||||||
|
s << "| " << device.id() << " | " << device.un() << " | " << device.type() << " | "
|
||||||
|
<< device.file() << (device.read_only() ? " (WRITEPROTECT)" : "") << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
s << "+----+----+------+-------------------------------------" << endl;
|
||||||
|
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Main processing
|
// Main processing
|
||||||
@ -88,7 +136,7 @@ int main(int argc, char* argv[])
|
|||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
cerr << "SCSI Target Emulator RaSCSI Controller" << endl;
|
cerr << "SCSI Target Emulator RaSCSI Controller" << endl;
|
||||||
cerr << "version " << rascsi_get_version_string() << " (" << __DATE__ << ", " << __TIME__ << ")" << endl;
|
cerr << "version " << rascsi_get_version_string() << " (" << __DATE__ << ", " << __TIME__ << ")" << endl;
|
||||||
cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE] [-h HOSTNAME] [-s LOG_LEVEL]" << endl;
|
cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE] [-h HOSTNAME] [-g LOG_LEVEL]" << endl;
|
||||||
cerr << " where ID := {0|1|2|3|4|5|6|7}" << endl;
|
cerr << " where ID := {0|1|2|3|4|5|6|7}" << endl;
|
||||||
cerr << " UNIT := {0|1} default setting is 0." << endl;
|
cerr << " UNIT := {0|1} default setting is 0." << endl;
|
||||||
cerr << " CMD := {attach|detach|insert|eject|protect}" << endl;
|
cerr << " CMD := {attach|detach|insert|eject|protect}" << endl;
|
||||||
@ -112,7 +160,7 @@ int main(int argc, char* argv[])
|
|||||||
const char *hostname = "localhost";
|
const char *hostname = "localhost";
|
||||||
string params;
|
string params;
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
while ((opt = getopt(argc, argv, "i:u:c:t:f:h:s:l")) != -1) {
|
while ((opt = getopt(argc, argv, "i:u:c:t:f:h:g:l")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
id = optarg[0] - '0';
|
id = optarg[0] - '0';
|
||||||
@ -190,7 +238,7 @@ int main(int argc, char* argv[])
|
|||||||
hostname = optarg;
|
hostname = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 'g':
|
||||||
cmd = LOG_LEVEL;
|
cmd = LOG_LEVEL;
|
||||||
params = optarg;
|
params = optarg;
|
||||||
break;
|
break;
|
||||||
@ -202,14 +250,39 @@ int main(int argc, char* argv[])
|
|||||||
if (cmd == LOG_LEVEL) {
|
if (cmd == LOG_LEVEL) {
|
||||||
command.set_cmd(LOG_LEVEL);
|
command.set_cmd(LOG_LEVEL);
|
||||||
command.set_params(params);
|
command.set_params(params);
|
||||||
SendCommand(hostname, command);
|
int fd = SendCommand(hostname, command);
|
||||||
|
if (fd < 0) {
|
||||||
|
exit(ENOTCONN);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveResult(fd);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List display only
|
// List display only
|
||||||
if (cmd == LIST || (id < 0 && type == UNDEFINED && params.empty())) {
|
if (cmd == LIST || (id < 0 && type == UNDEFINED && params.empty())) {
|
||||||
command.set_cmd(LIST);
|
command.set_cmd(LIST);
|
||||||
SendCommand(hostname, command);
|
int fd = SendCommand(hostname, command);
|
||||||
|
if (fd < 0) {
|
||||||
|
exit(ENOTCONN);
|
||||||
|
}
|
||||||
|
|
||||||
|
Devices devices;
|
||||||
|
try {
|
||||||
|
devices.ParseFromString(DeserializeProtobufData(fd));
|
||||||
|
}
|
||||||
|
catch(const ioexception& e) {
|
||||||
|
cerr << "Error : " << e.getmsg() << endl;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
cout << ListDevices(devices) << endl;
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,10 +334,15 @@ int main(int argc, char* argv[])
|
|||||||
if (!params.empty()) {
|
if (!params.empty()) {
|
||||||
command.set_params(params);
|
command.set_params(params);
|
||||||
}
|
}
|
||||||
if (!SendCommand(hostname, command)) {
|
|
||||||
|
int fd = SendCommand(hostname, command);
|
||||||
|
if (fd == -1) {
|
||||||
exit(ENOTCONN);
|
exit(ENOTCONN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool status = ReceiveResult(fd);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
// All done!
|
// All done!
|
||||||
exit(0);
|
exit(status ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option optimize_for = LITE_RUNTIME;
|
|
||||||
|
|
||||||
package rasctl_interface;
|
|
||||||
|
|
||||||
enum Operation {
|
|
||||||
LIST = 0;
|
|
||||||
ATTACH = 1;
|
|
||||||
DETACH = 2;
|
|
||||||
INSERT = 3;
|
|
||||||
EJECT = 4;
|
|
||||||
PROTECT = 5;
|
|
||||||
LOG_LEVEL = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DeviceType {
|
|
||||||
UNDEFINED = 0;
|
|
||||||
SASI_HD = 1;
|
|
||||||
SCSI_HD = 2;
|
|
||||||
MO = 3;
|
|
||||||
CD = 4;
|
|
||||||
BR = 5;
|
|
||||||
NUVOLINK = 6;
|
|
||||||
DAYNAPORT = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Command {
|
|
||||||
Operation cmd = 1;
|
|
||||||
int32 id = 2;
|
|
||||||
int32 un = 3;
|
|
||||||
DeviceType type = 4;
|
|
||||||
string params = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Result {
|
|
||||||
bool status = 1;
|
|
||||||
string msg = 2;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user