aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAlexander Tkachev2016-07-08 13:31:47 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commitb69cc3effbbe2cccefc29eb2db097945d78cf89b (patch)
treed35d741f9169950bb67cfd4f77a3e9847bb3494a /backends
parentbca05b2720298b17f9078465cd0896cc5d627819 (diff)
downloadscummvm-rg350-b69cc3effbbe2cccefc29eb2db097945d78cf89b.tar.gz
scummvm-rg350-b69cc3effbbe2cccefc29eb2db097945d78cf89b.tar.bz2
scummvm-rg350-b69cc3effbbe2cccefc29eb2db097945d78cf89b.zip
CLOUD: Update Reader to delete temp files
Diffstat (limited to 'backends')
-rw-r--r--backends/networking/sdl_net/reader.cpp94
-rw-r--r--backends/networking/sdl_net/reader.h7
2 files changed, 93 insertions, 8 deletions
diff --git a/backends/networking/sdl_net/reader.cpp b/backends/networking/sdl_net/reader.cpp
index 2037ef747e..7fe9d7b15a 100644
--- a/backends/networking/sdl_net/reader.cpp
+++ b/backends/networking/sdl_net/reader.cpp
@@ -29,9 +29,18 @@
#include "common/memstream.h"
#include "backends/fs/fs-factory.h"
+// This define lets us use the system function remove() on Symbian, which
+// is disabled by default due to a macro conflict.
+// See backends/platform/symbian/src/portdefs.h .
+#define SYMBIAN_USE_SYSTEM_REMOVE
+
+#ifndef _WIN32_WCE
+#include <errno.h> // for removeFile()
+#endif
+
namespace Networking {
-Reader::Reader() {
+Reader::Reader(): _randomSource("Networking::Reader") {
_state = RS_NONE;
_content = nullptr;
_bytesLeft = 0;
@@ -49,10 +58,79 @@ Reader::Reader() {
_isBadRequest = false;
}
+namespace {
+bool removeFile(const char *filename) {
+ // FIXME: remove does not exist on all systems. If your port fails to
+ // compile because of this, please let us know (scummvm-devel).
+ // There is a nicely portable workaround, too: Make this method overloadable.
+ if (remove(filename) != 0) {
+#ifndef _WIN32_WCE
+ if (errno == EACCES)
+ error("Reader: removeFile(): Search or write permission denied: %s", filename);
+
+ if (errno == ENOENT)
+ error("Reader: removeFile(): '%s' does not exist or path is invalid", filename);
+#endif
+ return false;
+ } else {
+ return true;
+ }
+}
+}
+
Reader::~Reader() {
- //TODO: free everything
+ cleanup();
+}
+
+Reader &Reader::operator=(Reader &r) {
+ if (this == &r) return *this;
+ cleanup();
+
+ _state = r._state;
+ _content = r._content;
+ _bytesLeft = r._bytesLeft;
+ r._state = RS_NONE;
+
+ _window = r._window;
+ _windowUsed = r._windowUsed;
+ _windowSize = r._windowSize;
+ r._window = nullptr;
+
+ _headers = r._headers;
+ _stream = r._stream;
+ r._stream = nullptr;
+
+ _headers = r._headers;
+ _method = r._method;
+ _path = r._path;
+ _query = r._query;
+ _anchor = r._anchor;
+ _queryParameters = r._queryParameters;
+ _attachedFiles = r._attachedFiles;
+ r._attachedFiles.clear();
+ _contentLength = r._contentLength;
+ _boundary = r._boundary;
+ _availableBytes = r._availableBytes;
+ _currentFieldName = r._currentFieldName;
+ _currentFileName = r._currentFileName;
+ _currentTempFileName = r._currentTempFileName;
+ _isFileField = r._isFileField;
+ _isBadRequest = r._isBadRequest;
+
+ return *this;
+}
+
+void Reader::cleanup() {
+ //_content is not to be freed, it's not owned by Reader
+
if (_window != nullptr) freeWindow();
delete _stream;
+
+ //delete temp files (by the time Reader is destucted those must be renamed or read)
+ for (Common::HashMap<Common::String, Common::String>::iterator i = _attachedFiles.begin(); i != _attachedFiles.end(); ++i) {
+ AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(i->_value);
+ if (node->exists()) removeFile(node->getPath().c_str());
+ }
}
bool Reader::readRequest() {
@@ -264,14 +342,14 @@ void Reader::parseQueryParameters() {
}
namespace {
-char generateRandomChar() {
- int r = rand() % 36;
+char generateRandomChar(Common::RandomSource &random) {
+ int r = random.getRandomNumber(36);
char c = '0' + r;
if (r > 9) c = 'a' + r - 10;
return c;
}
-Common::String generateTempFileName(Common::String originalFilename) {
+Common::String generateTempFileName(Common::String originalFilename, Common::RandomSource &random) {
//generates "./<originalFilename>-<uniqueSequence>.scummtmp"
//normalize <originalFilename>
Common::String prefix = "./";
@@ -288,13 +366,13 @@ Common::String generateTempFileName(Common::String originalFilename) {
//generate initial sequence
Common::String uniqueSequence;
for (uint32 i = 0; i < 5; ++i)
- uniqueSequence += generateRandomChar();
+ uniqueSequence += generateRandomChar(random);
//update sequence while generate path exists
AbstractFSNode *node;
Common::String path;
do {
- uniqueSequence += generateRandomChar();
+ uniqueSequence += generateRandomChar(random);
path = prefix + uniqueSequence + ".scummtmp";
node = g_system->getFilesystemFactory()->makeFileNodePath(path);
} while (node->exists());
@@ -311,7 +389,7 @@ bool Reader::readContent() {
if (_stream) delete _stream;
if (_isFileField) {
//create temporary file
- _currentTempFileName = generateTempFileName(_currentFileName);
+ _currentTempFileName = generateTempFileName(_currentFileName, _randomSource);
AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(_currentTempFileName);
_stream = node->createWriteStream();
if (_stream == nullptr)
diff --git a/backends/networking/sdl_net/reader.h b/backends/networking/sdl_net/reader.h
index 20b2a6148f..09550e09c9 100644
--- a/backends/networking/sdl_net/reader.h
+++ b/backends/networking/sdl_net/reader.h
@@ -27,6 +27,7 @@
#include "common/str.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
+#include "common/random.h"
namespace Common {
class WriteStream;
@@ -41,6 +42,8 @@ enum ReaderState {
};
class Reader {
+ Common::RandomSource _randomSource; //for temp file names
+
ReaderState _state;
byte *_content;
uint32 _bytesLeft;
@@ -62,6 +65,8 @@ class Reader {
bool _isFileField;
bool _isBadRequest;
+ void cleanup();
+
bool readHeaders(); //true when ended reading
bool readContent(); //true when ended reading
void handleHeaders(Common::String headers);
@@ -84,6 +89,8 @@ public:
Reader();
~Reader();
+ Reader &operator=(Reader &r);
+
bool readRequest(); //true when ended reading
void setContent(byte *buffer, uint32 size);
bool badRequest();