mirror of
https://github.com/thewesker/RASCSI.git
synced 2025-12-21 12:51:13 -05:00
Additional changes.... command interface works?
This commit is contained in:
@@ -1,7 +1,26 @@
|
||||
#include "os.h"
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ Command thread ]
|
||||
//
|
||||
// This is a background thread that runs, listening for commands on port
|
||||
// 6868 for commands from the rasctl utility. This also includes the logic
|
||||
// for handling the initialization commands that are specified at startup.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "rasctl_command.h"
|
||||
#include "command_thread.h"
|
||||
|
||||
#include "os.h"
|
||||
#include "rasctl_command.h"
|
||||
#include "rascsi_mgr.h"
|
||||
#include "sasihd.h"
|
||||
#include "scsihd.h"
|
||||
@@ -11,23 +30,9 @@
|
||||
#include "scsimo.h"
|
||||
#include "scsi_host_bridge.h"
|
||||
|
||||
BOOL Command_Thread::m_running = FALSE;
|
||||
int Command_Thread::m_monsocket = -1; // Monitor Socket
|
||||
pthread_t Command_Thread::m_monthread; // Monitor Thread
|
||||
|
||||
|
||||
void Command_Thread::Start(){
|
||||
m_running = TRUE;
|
||||
}
|
||||
void Command_Thread::Stop(){
|
||||
m_running = FALSE;
|
||||
}
|
||||
|
||||
BOOL Command_Thread::IsRunning(){
|
||||
return m_running;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Initialization
|
||||
@@ -44,7 +49,7 @@ BOOL Command_Thread::Init()
|
||||
m_monsocket = socket(PF_INET, SOCK_STREAM, 0);
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = PF_INET;
|
||||
server.sin_port = htons(6868);
|
||||
server.sin_port = htons(Rasctl_Command::PortNumber);
|
||||
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
// allow address reuse
|
||||
@@ -70,6 +75,11 @@ BOOL Command_Thread::Init()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Close/Cleanup the command thread
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void Command_Thread::Close(){
|
||||
// Close the monitor socket
|
||||
if (m_monsocket >= 0) {
|
||||
@@ -292,15 +302,10 @@ void *Command_Thread::MonThread(void *param)
|
||||
// Set the affinity to a specific processor core
|
||||
FixCpu(2);
|
||||
|
||||
// Wait for the execution to start
|
||||
while (!m_running) {
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
// Setup the monitor socket to receive commands
|
||||
listen(m_monsocket, 1);
|
||||
|
||||
while (1) {
|
||||
while (Rascsi_Manager::IsRunning()) {
|
||||
// Wait for connection
|
||||
memset(&client, 0, sizeof(client));
|
||||
len = sizeof(client);
|
||||
@@ -316,16 +321,7 @@ void *Command_Thread::MonThread(void *param)
|
||||
// If we received a command....
|
||||
if (p) {
|
||||
|
||||
// // Remove the newline character
|
||||
// p[strlen(p) - 1] = 0;
|
||||
|
||||
// // List all of the devices
|
||||
// if (xstrncasecmp(p, "list", 4) == 0) {
|
||||
// Rascsi_Manager::GetInstance()->ListDevice(fp);
|
||||
// goto next;
|
||||
// }
|
||||
|
||||
new_command = Rasctl_Command::DeSerialize((BYTE*)p,BUFSIZ);
|
||||
new_command = Rasctl_Command::DeSerialize(p,BUFSIZ);
|
||||
|
||||
if(new_command != nullptr){
|
||||
// Execute the command
|
||||
@@ -377,22 +373,20 @@ BOOL Command_Thread::ExecuteCommand(FILE *fp, Rasctl_Command *incoming_command)
|
||||
result = DoDetach(fp,incoming_command);
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN COMMAND RECEIVED\n");
|
||||
fprintf(fp, "UNKNOWN COMMAND RECEIVED\n");
|
||||
}
|
||||
|
||||
if(!result){
|
||||
fputs("Unknown server error", fp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL Command_Thread::DoShutdown(FILE *fp, Rasctl_Command *incoming_command){
|
||||
m_running = FALSE;
|
||||
fprintf(fp, "Stopping the RaSCSI application\n");
|
||||
Rascsi_Manager::Stop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Command_Thread::DoList(FILE *fp, Rasctl_Command *incoming_command){
|
||||
Rascsi_Manager::GetInstance()->ListDevice(fp);
|
||||
Rascsi_Manager::ListDevice(fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -405,13 +399,13 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
||||
case rasctl_dev_sasi_hd: // HDF
|
||||
pUnit = new SASIHD();
|
||||
break;
|
||||
case rasctl_dev_scsi_hd: // HDS/HDN/HDI/NHD/HDA
|
||||
case rasctl_dev_scsi_hd: // HDS/HDI
|
||||
pUnit = new SCSIHD();
|
||||
break;
|
||||
case rasctl_dev_scsi_hd_appl:
|
||||
case rasctl_dev_scsi_hd_appl: // HDA
|
||||
pUnit = new SCSIHD_APPLE();
|
||||
break;
|
||||
case rasctl_dev_scsi_hd_nec:
|
||||
case rasctl_dev_scsi_hd_nec: // HDN/NHD
|
||||
pUnit = new SCSIHD_NEC();
|
||||
break;
|
||||
case rasctl_dev_mo:
|
||||
@@ -436,6 +430,7 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
||||
case rasctl_dev_scsi_hd:
|
||||
case rasctl_dev_cd:
|
||||
case rasctl_dev_scsi_hd_appl:
|
||||
if((incoming_command->file != nullptr) && (strnlen(incoming_command->file,_MAX_PATH) > 0)){
|
||||
// Set the Path
|
||||
filepath.SetPath(incoming_command->file);
|
||||
|
||||
@@ -445,6 +440,8 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
||||
delete pUnit;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case rasctl_dev_br:
|
||||
case rasctl_dev_invalid:
|
||||
@@ -457,17 +454,17 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
||||
pUnit->SetCacheWB(FALSE);
|
||||
|
||||
// Map the controller
|
||||
return Rascsi_Manager::GetInstance()->AttachDevice(fp, pUnit, incoming_command->id, incoming_command->un);
|
||||
|
||||
return Rascsi_Manager::AttachDevice(fp, pUnit, incoming_command->id, incoming_command->un);
|
||||
}
|
||||
|
||||
BOOL Command_Thread::DoDetach(FILE *fp, Rasctl_Command *incoming_command){
|
||||
return Rascsi_Manager::GetInstance()->DetachDevice(fp, incoming_command->id, incoming_command->un);
|
||||
return Rascsi_Manager::DetachDevice(fp, incoming_command->id, incoming_command->un);
|
||||
}
|
||||
|
||||
BOOL Command_Thread::DoInsert(FILE *fp, Rasctl_Command *incoming_command){
|
||||
|
||||
Filepath filepath;
|
||||
Disk *pUnit = Rascsi_Manager::GetInstance()->GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||
Disk *pUnit = Rascsi_Manager::GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||
|
||||
|
||||
// Does the device exist?
|
||||
@@ -495,7 +492,7 @@ BOOL Command_Thread::DoInsert(FILE *fp, Rasctl_Command *incoming_command){
|
||||
return TRUE;
|
||||
}
|
||||
BOOL Command_Thread::DoEject(FILE *fp, Rasctl_Command *incoming_command){
|
||||
Disk *pUnit = Rascsi_Manager::GetInstance()->GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||
Disk *pUnit = Rascsi_Manager::GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||
|
||||
// Does the device exist?
|
||||
if (pUnit == nullptr) {
|
||||
@@ -515,7 +512,7 @@ BOOL Command_Thread::DoEject(FILE *fp, Rasctl_Command *incoming_command){
|
||||
|
||||
BOOL Command_Thread::DoProtect(FILE *fp, Rasctl_Command *incoming_command){
|
||||
|
||||
Disk *pUnit = Rascsi_Manager::GetInstance()->GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||
Disk *pUnit = Rascsi_Manager::GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||
|
||||
// Does the device exist?
|
||||
if (pUnit == nullptr) {
|
||||
|
||||
@@ -26,9 +26,6 @@ class Command_Thread{
|
||||
|
||||
public:
|
||||
static BOOL Init();
|
||||
static void Start();
|
||||
static void Stop();
|
||||
static BOOL IsRunning();
|
||||
static void Close();
|
||||
static void KillHandler();
|
||||
static BOOL ParseArgument(int argc, char* argv[]);
|
||||
@@ -40,7 +37,7 @@ class Command_Thread{
|
||||
private:
|
||||
static int m_monsocket; // Monitor Socket
|
||||
static pthread_t m_monthread; // Monitor Thread
|
||||
static BOOL m_running;
|
||||
static uint16_t m_monitor_port_num; // Port number to listen for commands
|
||||
|
||||
static BOOL HasSuffix(const char* string, const char* suffix);
|
||||
static BOOL DoShutdown(FILE *fp, Rasctl_Command *incoming_command);
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
FATFS fatfs; // FatFS
|
||||
#else
|
||||
#endif // BAREMETAL
|
||||
Rascsi_Manager *mgr;
|
||||
|
||||
#ifndef CONNECT_DESC
|
||||
#define CONNECT_DESC "UNKNOWN"
|
||||
@@ -71,7 +70,7 @@ Rascsi_Manager *mgr;
|
||||
void KillHandler(int sig)
|
||||
{
|
||||
// Stop instruction
|
||||
Command_Thread::Stop();
|
||||
Rascsi_Manager::Stop();
|
||||
}
|
||||
#endif // BAREMETAL
|
||||
|
||||
@@ -127,12 +126,11 @@ void Banner(int argc, char* argv[])
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL Init()
|
||||
{
|
||||
if(!Command_Thread::Init()){
|
||||
if(!Rascsi_Manager::Init()){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mgr = Rascsi_Manager::GetInstance();
|
||||
if(!mgr->Init()){
|
||||
if(!Command_Thread::Init()){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -157,7 +155,7 @@ BOOL Init()
|
||||
//---------------------------------------------------------------------------
|
||||
void Cleanup()
|
||||
{
|
||||
mgr->Close();
|
||||
Rascsi_Manager::Close();
|
||||
|
||||
#ifndef BAREMETAL
|
||||
Command_Thread::Close();
|
||||
@@ -223,12 +221,9 @@ int main(int argc, char* argv[])
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
#endif // BAREMETAL
|
||||
|
||||
// Start execution
|
||||
Command_Thread::Start();
|
||||
|
||||
// Main Loop
|
||||
while (Command_Thread::IsRunning()) {
|
||||
mgr->Step();
|
||||
while (Rascsi_Manager::IsRunning()) {
|
||||
Rascsi_Manager::Step();
|
||||
}
|
||||
#ifdef BAREMETAL
|
||||
err_exit:
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
#include "sasidev_ctrl.h"
|
||||
#include "scsidev_ctrl.h"
|
||||
|
||||
Rascsi_Manager *Rascsi_Manager::m_instance = (Rascsi_Manager*)nullptr;
|
||||
|
||||
|
||||
SASIDEV *Rascsi_Manager::m_ctrl[CtrlMax]; // Controller
|
||||
Disk *Rascsi_Manager::m_disk[CtrlMax * UnitNum]; // Disk
|
||||
GPIOBUS *Rascsi_Manager::m_bus;
|
||||
@@ -17,13 +14,7 @@ DWORD Rascsi_Manager::m_now = 0;
|
||||
BOOL Rascsi_Manager::m_active = FALSE;
|
||||
BOOL Rascsi_Manager::m_running = FALSE;
|
||||
std::timed_mutex Rascsi_Manager::m_locked;
|
||||
|
||||
Rascsi_Manager* Rascsi_Manager::GetInstance(){
|
||||
if(m_instance != nullptr){
|
||||
m_instance = new Rascsi_Manager();
|
||||
}
|
||||
return m_instance;
|
||||
}
|
||||
BOOL Rascsi_Manager::m_initialized = FALSE;
|
||||
|
||||
BOOL Rascsi_Manager::AttachDevice(FILE *fp, Disk *disk, int id, int unit_num){
|
||||
BOOL result;
|
||||
@@ -54,7 +45,7 @@ BOOL Rascsi_Manager::AttachDevicePrivate(FILE *fp, Disk *disk, int id, int unit_
|
||||
|
||||
// Check if something already exists at that SCSI ID / Unit Number
|
||||
if (m_disk[unitno]) {
|
||||
DetachDevice(fp,id,unit_num);
|
||||
DetachDevicePrivate(fp,id,unit_num);
|
||||
}
|
||||
|
||||
// Add the new unit
|
||||
@@ -260,12 +251,11 @@ void Rascsi_Manager::Close(){
|
||||
|
||||
BOOL Rascsi_Manager::Init(){
|
||||
|
||||
if(m_instance != nullptr){
|
||||
if(m_initialized != FALSE){
|
||||
printf("Can not initialize Rascsi_Manager twice!!!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_instance = new Rascsi_Manager();
|
||||
m_initialized = TRUE;
|
||||
|
||||
// GPIOBUS creation
|
||||
m_bus = new GPIOBUS();
|
||||
@@ -288,10 +278,11 @@ BOOL Rascsi_Manager::Init(){
|
||||
m_disk[i] = NULL;
|
||||
}
|
||||
|
||||
|
||||
// Reset
|
||||
Reset();
|
||||
|
||||
m_running = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -405,3 +396,11 @@ BOOL Rascsi_Manager::Step()
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Rascsi_Manager::Stop(){
|
||||
m_running = FALSE;
|
||||
}
|
||||
BOOL Rascsi_Manager::IsRunning(){
|
||||
return (m_running == TRUE);
|
||||
}
|
||||
@@ -37,18 +37,20 @@ enum Rascsi_Device_Mode_e{
|
||||
class Rascsi_Manager{
|
||||
public:
|
||||
static Rascsi_Manager* GetInstance();
|
||||
void MapControler(FILE *fp, Disk **map);
|
||||
static void MapControler(FILE *fp, Disk **map);
|
||||
|
||||
static void Stop();
|
||||
static BOOL IsRunning();
|
||||
|
||||
BOOL AttachDevice(FILE *fp, Disk *disk, int id, int ui);
|
||||
BOOL DetachDevice(FILE *fp, int id, int ui);
|
||||
Disk* GetDevice(FILE *fp, int id, int ui);
|
||||
void ListDevice(FILE *fp);
|
||||
BOOL Init();
|
||||
void Close();
|
||||
void Reset();
|
||||
BOOL Step();
|
||||
Rascsi_Device_Mode_e GetCurrentDeviceMode();
|
||||
static BOOL AttachDevice(FILE *fp, Disk *disk, int id, int ui);
|
||||
static BOOL DetachDevice(FILE *fp, int id, int ui);
|
||||
static Disk* GetDevice(FILE *fp, int id, int ui);
|
||||
static void ListDevice(FILE *fp);
|
||||
static BOOL Init();
|
||||
static void Close();
|
||||
static void Reset();
|
||||
static BOOL Step();
|
||||
static Rascsi_Device_Mode_e GetCurrentDeviceMode();
|
||||
|
||||
static const int CtrlMax = 8; // Maximum number of SCSI controllers
|
||||
static const int UnitNum=2; // Number of units around controller
|
||||
@@ -68,12 +70,12 @@ class Rascsi_Manager{
|
||||
static BUS::phase_t m_phase;
|
||||
static BYTE m_data;
|
||||
static DWORD m_now;
|
||||
static Rascsi_Manager *m_instance;
|
||||
static BOOL m_active;
|
||||
static BOOL m_running;
|
||||
static BOOL m_initialized;
|
||||
|
||||
BOOL AttachDevicePrivate(FILE *fp, Disk *disk, int id, int ui);
|
||||
BOOL DetachDevicePrivate(FILE *fp, int id, int ui);
|
||||
static BOOL AttachDevicePrivate(FILE *fp, Disk *disk, int id, int ui);
|
||||
static BOOL DetachDevicePrivate(FILE *fp, int id, int ui);
|
||||
|
||||
// Any PUBLIC functions should lock this before accessing the m_ctrl
|
||||
// m_disk or m_bus data structures. The Public functions could be
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// Send Command
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL SendCommand(BYTE *buf)
|
||||
BOOL SendCommand(char *buf)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_in server;
|
||||
@@ -27,7 +27,7 @@ BOOL SendCommand(BYTE *buf)
|
||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = PF_INET;
|
||||
server.sin_port = htons(6868);
|
||||
server.sin_port = htons(Rasctl_Command::PortNumber);
|
||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
// Connect
|
||||
@@ -68,16 +68,14 @@ int main(int argc, char* argv[])
|
||||
int id;
|
||||
int un;
|
||||
char *file;
|
||||
int len;
|
||||
char *ext;
|
||||
BYTE buf[BUFSIZ];
|
||||
char buf[BUFSIZ];
|
||||
rasctl_command cmd = rasctl_cmd_invalid;
|
||||
rasctl_dev_type type = rasctl_dev_invalid;
|
||||
Rasctl_Command *rasctl_cmd;
|
||||
|
||||
id = -1;
|
||||
un = 0;
|
||||
file = NULL;
|
||||
file = nullptr;
|
||||
|
||||
// Display help
|
||||
if (argc < 2) {
|
||||
@@ -102,11 +100,11 @@ int main(int argc, char* argv[])
|
||||
while ((opt = getopt(argc, argv, "i:u:c:t:f:l")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
id = optarg[0] - '0';
|
||||
id = atoi((char*)optarg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
un = optarg[0] - '0';
|
||||
un = atoi((char*)optarg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
@@ -175,13 +173,13 @@ int main(int argc, char* argv[])
|
||||
|
||||
// Check the ID number
|
||||
if (id < 0 || id > 7) {
|
||||
fprintf(stderr, "Error : Invalid ID\n");
|
||||
fprintf(stderr, "Error : Invalid SCSI/SASI ID number %d\n", id);
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
// Check the unit number
|
||||
if (un < 0 || un > 1) {
|
||||
fprintf(stderr, "Error : Invalid UNIT\n");
|
||||
fprintf(stderr, "Error : Invalid UNIT number %d\n", un);
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
@@ -190,33 +188,10 @@ int main(int argc, char* argv[])
|
||||
cmd = rasctl_cmd_attach; // Default command is ATTATCH
|
||||
}
|
||||
|
||||
// Type Check
|
||||
if (cmd == rasctl_cmd_attach && type == rasctl_dev_invalid) {
|
||||
|
||||
// Try to determine the file type from the extension
|
||||
len = file ? strlen(file) : 0;
|
||||
if (len > 4 && file[len - 4] == '.') {
|
||||
ext = &file[len - 3];
|
||||
if (xstrcasecmp(ext, "hdf") == 0){
|
||||
type = rasctl_dev_sasi_hd;
|
||||
}else if(xstrcasecmp(ext, "hds") == 0 ||
|
||||
xstrcasecmp(ext, "hdi") == 0 ||
|
||||
xstrcasecmp(ext, "nhd") == 0){
|
||||
type = rasctl_dev_scsi_hd;
|
||||
}else if(xstrcasecmp(ext, "hdn") == 0) {
|
||||
// NEC HD(SASI/SCSI)
|
||||
type = rasctl_dev_scsi_hd_appl;
|
||||
}else if(xstrcasecmp(ext, "hda") == 0) {
|
||||
// Apple HD(SASI/SCSI)
|
||||
type = rasctl_dev_scsi_hd_appl;
|
||||
}else if (xstrcasecmp(ext, "mos") == 0) {
|
||||
// MO
|
||||
type = rasctl_dev_mo;
|
||||
}else if (xstrcasecmp(ext, "iso") == 0) {
|
||||
// CD
|
||||
type = rasctl_dev_cd;
|
||||
}
|
||||
}
|
||||
// If the device type is still "invalid" (unknown), try to figure it out
|
||||
// from the image file name.
|
||||
if (cmd == rasctl_cmd_attach && type == rasctl_dev_invalid && file != nullptr) {
|
||||
type = Rasctl_Command::DeviceTypeFromFilename(stderr, file);
|
||||
|
||||
if (type == rasctl_dev_invalid) {
|
||||
fprintf(stderr, "Error : Invalid type\n");
|
||||
@@ -255,12 +230,14 @@ int main(int argc, char* argv[])
|
||||
strncpy(rasctl_cmd->file,file,_MAX_PATH);
|
||||
}
|
||||
|
||||
if(rasctl_cmd->IsValid(stderr)){
|
||||
// Generate the command and send it
|
||||
rasctl_cmd->Serialize(buf,BUFSIZ);
|
||||
|
||||
if (!SendCommand(buf)) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
}
|
||||
|
||||
// All done!
|
||||
exit(0);
|
||||
|
||||
@@ -1,23 +1,41 @@
|
||||
#include "rasctl_command.h"
|
||||
#include "rascsi_mgr.h"
|
||||
#include <string.h>
|
||||
|
||||
const char* Rasctl_Command::m_delimiter = "\x1E"; // Record separator charater
|
||||
//const char* Rasctl_Command::m_delimiter = " "; // Record separator charater
|
||||
// In the serialized string from rasctl
|
||||
const char* Rasctl_Command::m_delimiter = "\x1E\n"; // Record separator charater
|
||||
const char* Rasctl_Command::m_no_file = "----";
|
||||
const uint16_t Rasctl_Command::PortNumber = 6868;
|
||||
|
||||
void Rasctl_Command::Serialize(BYTE *buff, int max_buff_size){
|
||||
snprintf((char*)buff, max_buff_size, "%d%s%d%s%d%s%d%s%s%s\n",
|
||||
this->id, this->m_delimiter,
|
||||
this->un, this->m_delimiter,
|
||||
this->cmd, this->m_delimiter,
|
||||
this->type, this->m_delimiter,
|
||||
this->file, this->m_delimiter);
|
||||
const char* Rasctl_Command::dev_type_lookup[] = {
|
||||
"SASI Hard Drive", // rasctl_dev_sasi_hd = 0,
|
||||
"SCSI Hard Drive", // rasctl_dev_scsi_hd = 1,
|
||||
"Magneto Optical Drive", // rasctl_dev_mo = 2,
|
||||
"CD-ROM", // rasctl_dev_cd = 3,
|
||||
"Host Bridge", // rasctl_dev_br = 4,
|
||||
"Apple SCSI Hard Drive", // rasctl_dev_scsi_hd_appl = 5,
|
||||
"NEC SCSI Hard DRive", // rasctl_dev_scsi_hd_nec = 6,
|
||||
};
|
||||
|
||||
void Rasctl_Command::Serialize(char *buff, int max_buff_size){
|
||||
// The filename string can't be empty. Otherwise, strtok will
|
||||
// ignore the field on the receiving end.
|
||||
if(strlen(this->file) < 1){
|
||||
strcpy(this->file,m_no_file);
|
||||
}
|
||||
snprintf(buff, max_buff_size, "%d%c%d%c%d%c%d%c%s%c\n",
|
||||
this->id, this->m_delimiter[0],
|
||||
this->un, this->m_delimiter[0],
|
||||
this->cmd, this->m_delimiter[0],
|
||||
this->type, this->m_delimiter[0],
|
||||
this->file, this->m_delimiter[0]);
|
||||
}
|
||||
|
||||
Rasctl_Command* Rasctl_Command::DeSerialize(BYTE* buff, int size){
|
||||
Rasctl_Command* Rasctl_Command::DeSerialize(char* buff, int size){
|
||||
Rasctl_Command *return_command = new Rasctl_Command();
|
||||
char err_message[256];
|
||||
char *cur_token;
|
||||
char *command = (char*)buff;
|
||||
char *command = buff;
|
||||
serial_token_order cur_token_idx = serial_token_first_token;
|
||||
|
||||
cur_token = strtok(command, m_delimiter);
|
||||
@@ -31,7 +49,11 @@ Rasctl_Command* Rasctl_Command::DeSerialize(BYTE* buff, int size){
|
||||
return_command->type = (rasctl_dev_type)atoi(cur_token);
|
||||
break;
|
||||
case serial_token_file_name:
|
||||
if(strncmp(cur_token,m_no_file,strlen(m_no_file)) != 0){
|
||||
strncpy(return_command->file,cur_token,_MAX_PATH);
|
||||
} else {
|
||||
strncpy(return_command->file,"",_MAX_PATH);
|
||||
}
|
||||
break;
|
||||
case serial_token_id:
|
||||
return_command->id = atoi(cur_token);
|
||||
@@ -78,6 +100,7 @@ BOOL Rasctl_Command::rasctl_dev_is_hd(rasctl_dev_type type)
|
||||
|
||||
BOOL Rasctl_Command::IsValid(FILE *fp){
|
||||
struct stat stat_buffer;
|
||||
rasctl_dev_type expected_type = rasctl_dev_invalid;
|
||||
|
||||
// If the command is "invalid" we can just return FALSE
|
||||
if(cmd == rasctl_cmd_invalid){
|
||||
@@ -117,7 +140,7 @@ BOOL Rasctl_Command::IsValid(FILE *fp){
|
||||
return FALSE;
|
||||
}
|
||||
// Check that the file exists if specified
|
||||
if(stat(file, &stat_buffer) == 0){
|
||||
if(stat(file, &stat_buffer) != 0){
|
||||
FPRT(fp, "File %s is not accessible", file);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -128,74 +151,49 @@ BOOL Rasctl_Command::IsValid(FILE *fp){
|
||||
}
|
||||
}
|
||||
|
||||
// char* path = optarg;
|
||||
// int type = -1;
|
||||
// if (HasSuffix(path, ".hdf")
|
||||
// || HasSuffix(path, ".hds")
|
||||
// || HasSuffix(path, ".hdn")
|
||||
// || HasSuffix(path, ".hdi")
|
||||
// || HasSuffix(path, ".hda")
|
||||
// || HasSuffix(path, ".nhd")) {
|
||||
// type = 0;
|
||||
// } else if (HasSuffix(path, ".mos")) {
|
||||
// type = 2;
|
||||
// } else if (HasSuffix(path, ".iso")) {
|
||||
// type = 3;
|
||||
// } else if (xstrcasecmp(path, "bridge") == 0) {
|
||||
// type = 4;
|
||||
// } else {
|
||||
// // Cannot determine the file type
|
||||
// fprintf(stderr,
|
||||
// "%s: unknown file extension\n", path);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// int un = 0;
|
||||
// if (is_sasi) {
|
||||
// un = id % Rascsi_Manager::UnitNum;
|
||||
// id /= Rascsi_Manager::UnitNum;
|
||||
// }
|
||||
|
||||
// // Execute the command
|
||||
// if (!ExecuteCommand(stderr, id, un, 0, type, path)) {
|
||||
// return false;
|
||||
// }
|
||||
// id = -1;
|
||||
// }
|
||||
|
||||
// // Display the device list
|
||||
// Rascsi_Manager::GetInstance()->ListDevice(stdout);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// if (type == 0) {
|
||||
// // Passed the check
|
||||
// if (!file) {
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
// // Check that command is at least 5 characters long
|
||||
// len = strlen(file);
|
||||
// if (len < 5) {
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
// // Check the extension
|
||||
// if (file[len - 4] != '.') {
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
// // If the extension is not SASI type, replace with SCSI
|
||||
// ext = &file[len - 3];
|
||||
// if (xstrcasecmp(ext, "hdf") != 0) {
|
||||
// type = 1;
|
||||
// }
|
||||
|
||||
// Check if the filename extension matches the device type
|
||||
expected_type = DeviceTypeFromFilename(fp, file);
|
||||
if(expected_type != rasctl_dev_invalid){
|
||||
if((file != nullptr) && (type != expected_type)) {
|
||||
FPRT(fp, "Filename specified is for type %s. This isn't compatible with a %s device.",
|
||||
dev_type_lookup[expected_type], dev_type_lookup[type]);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Everything appears to be OK
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
rasctl_dev_type Rasctl_Command::DeviceTypeFromFilename(FILE *fp, const char* filename){
|
||||
|
||||
const char *extension = strrchr(filename,'.');
|
||||
rasctl_dev_type ret_type = rasctl_dev_invalid;
|
||||
|
||||
if(extension == nullptr){
|
||||
fprintf(fp, "Missing file extension from %s",filename);
|
||||
return rasctl_dev_invalid;
|
||||
}
|
||||
|
||||
if(strcasecmp(extension,".hdf") == 0){
|
||||
ret_type = rasctl_dev_sasi_hd;
|
||||
}else if((strcasecmp(extension,".hds") == 0) ||
|
||||
(strcasecmp(extension,".hdi") == 0) ||
|
||||
(strcasecmp(extension,".nhd") == 0)){
|
||||
ret_type = rasctl_dev_scsi_hd;
|
||||
}else if(strcasecmp(extension,".hdn") == 0){
|
||||
ret_type = rasctl_dev_scsi_hd_nec;
|
||||
}else if(strcasecmp(extension,".hdi") == 0){
|
||||
ret_type = rasctl_dev_scsi_hd_nec;
|
||||
}else if(strcasecmp(extension,".hda") == 0){
|
||||
ret_type = rasctl_dev_scsi_hd_appl;
|
||||
}else if(strcasecmp(extension,".mos") == 0){
|
||||
ret_type = rasctl_dev_mo;
|
||||
}else if(strcasecmp(extension,".iso") == 0){
|
||||
ret_type = rasctl_dev_cd;
|
||||
}
|
||||
|
||||
return ret_type;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ enum rasctl_dev_type : int {
|
||||
|
||||
class Rasctl_Command{
|
||||
public:
|
||||
void Serialize(BYTE *buff, int max_buff_size);
|
||||
static Rasctl_Command* DeSerialize(BYTE* buff, int size);
|
||||
void Serialize(char *buff, int max_buff_size);
|
||||
static Rasctl_Command* DeSerialize(char* buff, int size);
|
||||
BOOL IsValid(FILE *fp);
|
||||
|
||||
|
||||
@@ -49,12 +49,17 @@ class Rasctl_Command{
|
||||
rasctl_dev_type type = rasctl_dev_invalid;
|
||||
int id = -1;
|
||||
int un = -1;
|
||||
char file[_MAX_PATH];
|
||||
char file[_MAX_PATH] = "";
|
||||
|
||||
static BOOL rasctl_dev_is_hd(rasctl_dev_type dev);
|
||||
static const uint16_t PortNumber;
|
||||
|
||||
static rasctl_dev_type DeviceTypeFromFilename(FILE *fp, const char* filename);
|
||||
|
||||
private:
|
||||
static const char* m_delimiter; // Record separator charater
|
||||
static const char* m_no_file; // Special character sequence indicating an empty file name.
|
||||
|
||||
|
||||
enum serial_token_order : int {
|
||||
serial_token_first_token = 0,
|
||||
@@ -65,4 +70,6 @@ class Rasctl_Command{
|
||||
serial_token_file_name = 4,
|
||||
serial_token_last_token = 5,
|
||||
};
|
||||
|
||||
static const char* dev_type_lookup[];
|
||||
};
|
||||
Reference in New Issue
Block a user