Removed ISO CD block size check, optionally set r/o status when copying a file (#311)

* Removed ISO CD-ROM block size check

* Removed CD size checks

* Replicate read-only status when copying an image file

* Cleanup

* Copied images can optionally be created read-only

* Check path of default image folder

* Comment update

* Updated error message
This commit is contained in:
Uwe Seimet 2021-10-08 13:05:57 +02:00 committed by GitHub
parent 5bd8807c9e
commit f5a6f5dce2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 37 deletions

View File

@ -426,21 +426,10 @@ void SCSICD::OpenIso(const Filepath& path)
error << "Raw ISO CD-ROM file size must be a multiple of 2536 bytes but is " << size << " bytes"; error << "Raw ISO CD-ROM file size must be a multiple of 2536 bytes but is " << size << " bytes";
throw io_exception(error.str()); throw io_exception(error.str());
} }
if (size > 912579600) {
throw io_exception("Raw ISO CD-ROM file size must not exceed 700 MB");
}
// Set the number of blocks // Set the number of blocks
SetBlockCount((DWORD)(size / 0x930)); SetBlockCount((DWORD)(size / 0x930));
} else { } else {
// Size must be a multiple of 2048 and less than 700MB
if (size % 2048) {
throw io_exception("ISO CD-ROM file size must be a multiple of 2048 bytes");
}
if (size > 0x2bed5000) {
throw io_exception("ISO CD-ROM file size must not exceed 700 MB");
}
// Set the number of blocks // Set the number of blocks
SetBlockCount((DWORD)(size >> 11)); SetBlockCount((DWORD)(size >> 11));
} }

View File

@ -451,7 +451,7 @@ void LogDevices(const string& devices)
} }
} }
bool SetDefaultImageFolder(const string& f) const char *SetDefaultImageFolder(const string& f)
{ {
string folder = f; string folder = f;
@ -470,18 +470,23 @@ bool SetDefaultImageFolder(const string& f)
folder += f; folder += f;
} }
} }
else {
if (folder.find("/home/") != 0) {
return "Default image folder must be located in '/home/'";
}
}
struct stat info; struct stat info;
stat(folder.c_str(), &info); stat(folder.c_str(), &info);
if (!S_ISDIR(info.st_mode) || access(folder.c_str(), F_OK) == -1) { if (!S_ISDIR(info.st_mode) || access(folder.c_str(), F_OK) == -1) {
return false; return string("Folder '" + f + "' does not exist or is not accessible").c_str();
} }
default_image_folder = folder; 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 true; return NULL;
} }
string SetReservedIds(const string& ids) string SetReservedIds(const string& ids)
@ -564,18 +569,6 @@ bool CreateImage(int fd, const PbCommand& command)
return ReturnStatus(fd, false, "Can't create image file '" + filename + "': Missing image size"); return ReturnStatus(fd, false, "Can't create image file '" + filename + "': Missing image size");
} }
const string permission = GetParam(command, "read_only");
if (permission.empty()) {
return ReturnStatus(fd, false, "Can't create image file'" + filename + "': Missing read-only flag");
}
if (strcasecmp(permission.c_str(), "true") && strcasecmp(permission.c_str(), "false")) {
return ReturnStatus(fd, false, "Can't create image file '" + filename + "': Invalid read-only flag '" + permission + "'");
}
int permissions = !strcasecmp(permission.c_str(), "true") ?
S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
off_t len; off_t len;
try { try {
len = stoul(size); len = stoul(size);
@ -597,7 +590,11 @@ bool CreateImage(int fd, const PbCommand& command)
return ReturnStatus(fd, false, "Can't create image file '" + filename + "': File already exists"); return ReturnStatus(fd, false, "Can't create image file '" + filename + "': File already exists");
} }
string permission = GetParam(command, "read_only");
// Since rascsi is running as root ensure that others can access the file // Since rascsi is running as root ensure that others can access the file
int permissions = !strcasecmp(permission.c_str(), "true") ?
S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int image_fd = open(filename.c_str(), O_CREAT|O_WRONLY, permissions); int image_fd = open(filename.c_str(), O_CREAT|O_WRONLY, permissions);
if (image_fd == -1) { if (image_fd == -1) {
return ReturnStatus(fd, false, "Can't create image file '" + filename + "': " + string(strerror(errno))); return ReturnStatus(fd, false, "Can't create image file '" + filename + "': " + string(strerror(errno)));
@ -736,7 +733,12 @@ bool CopyImage(int fd, const PbCommand& command)
return ReturnStatus(fd, false, "Can't open source image file '" + from + "': " + string(strerror(errno))); return ReturnStatus(fd, false, "Can't open source image file '" + from + "': " + string(strerror(errno)));
} }
int fd_dst = open(to.c_str(), O_WRONLY | O_CREAT, st.st_mode); string permission = GetParam(command, "read_only");
// Since rascsi is running as root ensure that others can access the file
int permissions = !strcasecmp(permission.c_str(), "true") ?
S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fd_dst = open(to.c_str(), O_WRONLY | O_CREAT, permissions);
if (fd_dst == -1) { if (fd_dst == -1) {
close(fd_src); close(fd_src);
@ -896,7 +898,7 @@ bool Attach(int fd, const PbDeviceDefinition& pb_device, Device *map[], bool dry
catch(const io_exception& e) { catch(const io_exception& e) {
delete device; delete device;
return ReturnStatus(fd, false, "Tried to open an invalid file '" + initial_filename + "': " + e.getmsg()); return ReturnStatus(fd, false, "Tried to open an invalid or non-existing file '" + initial_filename + "': " + e.getmsg());
} }
int id; int id;
@ -1043,7 +1045,7 @@ bool Insert(int fd, const PbDeviceDefinition& pb_device, Device *device, bool dr
} }
} }
catch(const io_exception& e) { catch(const io_exception& e) {
return ReturnStatus(fd, false, "Tried to open an invalid file '" + initial_filename + "': " + e.getmsg()); return ReturnStatus(fd, false, "Tried to open an invalid or non-existing file '" + initial_filename + "': " + e.getmsg());
} }
file_support->ReserveFile(filepath, device->GetId(), device->GetLun()); file_support->ReserveFile(filepath, device->GetId(), device->GetLun());
@ -1343,12 +1345,14 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue; continue;
} }
case 'F': case 'F': {
if (!SetDefaultImageFolder(optarg)) { const char *result = SetDefaultImageFolder(optarg);
cerr << "Folder '" << optarg << "' does not exist or is not accessible"; if (result) {
cerr << result << endl;
return false; return false;
} }
continue; continue;
}
case 'L': case 'L':
log_level = optarg; log_level = optarg;
@ -1539,8 +1543,9 @@ static void *MonThread(void *param)
ReturnStatus(fd, false, "Can't set default image folder: Missing folder name"); ReturnStatus(fd, false, "Can't set default image folder: Missing folder name");
} }
if (!SetDefaultImageFolder(folder)) { const char *result = SetDefaultImageFolder(folder);
ReturnStatus(fd, false, "Folder '" + folder + "' does not exist or is not accessible"); if (result) {
ReturnStatus(fd, false, result);
} }
else { else {
ReturnStatus(fd); ReturnStatus(fd);

View File

@ -95,9 +95,9 @@ enum PbOperation {
// Get the list of reserved device IDs // Get the list of reserved device IDs
RESERVED_IDS_INFO = 19; RESERVED_IDS_INFO = 19;
// Set the default folder for image files. // Set the default folder for image files. This folder must be located in /home.
// Parameters: // Parameters:
// "folder": The default folder name. // "folder": The path of the default folder, relative to the user's home folder if relative.
DEFAULT_FOLDER = 20; DEFAULT_FOLDER = 20;
// Set a new log level. // Set a new log level.
@ -114,7 +114,7 @@ enum PbOperation {
// Parameters: // Parameters:
// "file": The filename, relative to the default image folder. It must not contain a slash. // "file": The filename, relative to the default image folder. It must not contain a slash.
// "size": The file size in bytes, must be a multiple of 512 // "size": The file size in bytes, must be a multiple of 512
// "read_only": "true" (case-insensitive) in order to create a read-only file, otherwise "false" // "read_only": Optional, "true" (case-insensitive) in order to create a read-only file
CREATE_IMAGE = 23; CREATE_IMAGE = 23;
// Delete an image file. // Delete an image file.
@ -133,6 +133,7 @@ enum PbOperation {
// Parameters: // Parameters:
// "from": The source filename, relative to the default image folder. It must not contain a slash. // "from": The source filename, relative to the default image folder. It must not contain a slash.
// "to": The destination filename, relative to the default image folder. It must not contain a slash. // "to": The destination filename, relative to the default image folder. It must not contain a slash.
// "read_only": Optional, "true" (case-insensitive) in order to create a read-only file
// The destination filename must not yet exist. // The destination filename must not yet exist.
COPY_IMAGE = 26; COPY_IMAGE = 26;