#include "rasctl_command.h" #include "rascsi_mgr.h" #include // 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; 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(char* buff, int size){ Rasctl_Command *return_command = new Rasctl_Command(); char err_message[256]; char *cur_token; char *command = buff; serial_token_order cur_token_idx = serial_token_first_token; cur_token = strtok(command, m_delimiter); // Loop through all of the tokens in the message while (cur_token != NULL){ switch(cur_token_idx){ case serial_token_cmd: return_command->cmd = (rasctl_command)atoi(cur_token); break; case serial_token_type: 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); break; case serial_token_un: return_command->un = atoi(cur_token); break; default: for(size_t i=0; i= Rascsi_Manager::CtrlMax)){ FPRT(fp, "Invalid ID. Must be between 0 and %d",Rascsi_Manager::CtrlMax-1); return FALSE; } // Check that unit number is in range if((un < 0) || (un >= Rascsi_Manager::UnitNum)){ FPRT(fp, "Invalid unit number. Must be between 0 and %d",Rascsi_Manager::UnitNum-1); return FALSE; } // If the command is attach, make sure we're adding a valid type if(cmd == rasctl_cmd_attach){ if(type == rasctl_dev_invalid){ FPRT(fp, "Unknown device type being attached"); return FALSE; } } // If we're trying to insert a disk, we need to make sure a file is specified. // Also, if we're trying to attach a hard drive, the image must be specified if((cmd == rasctl_cmd_insert) || ((cmd == rasctl_cmd_attach) && (rasctl_dev_is_hd(type)))){ if(file == nullptr){ FPRT(fp, "File name must be specified for this operation"); return FALSE; } // Check that the file exists if specified if(stat(file, &stat_buffer) != 0){ FPRT(fp, "File %s is not accessible", file); return FALSE; } // Check that the file is 1 byte or larger if(stat_buffer.st_size < 1){ FPRT(fp, "File must not be empty. %s is %lld bytes in size",file,stat_buffer.st_size); return FALSE; } } //!!!!! THIS DOESN'T WORK QUITE RIGHT..... // Check if the filename extension matches the device type // if(strlen(file) > 0){ // 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; }