diff options
author | rubidium <rubidium@openttd.org> | 2010-10-24 16:40:02 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2010-10-24 16:40:02 +0000 |
commit | 744bc2a614bf373b341cf8cb798a9d56ed31c155 (patch) | |
tree | 2133a92bb0cb24396709c9c98f296d5521e271c6 | |
parent | c5015bb5bddd25dc912319a692b3fcbef1d030a6 (diff) | |
download | openttd-744bc2a614bf373b341cf8cb798a9d56ed31c155.tar.xz |
(svn r21027) -Change/Fix: under some circumstances the file handle of the downloaded savegame wouldn't be closed, and validity of the handled wasn't checked in all cases
-rw-r--r-- | src/network/network_client.cpp | 23 | ||||
-rw-r--r-- | src/network/network_client.h | 3 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 719433def..17ea3cdbb 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -40,7 +40,7 @@ * Create a new socket for the client side of the game connection. * @param s The socket to connect with. */ -ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s) +ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s), download_file(NULL) { assert(ClientNetworkGameSocketHandler::my_client == NULL); ClientNetworkGameSocketHandler::my_client = this; @@ -51,6 +51,9 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler() { assert(ClientNetworkGameSocketHandler::my_client == this); ClientNetworkGameSocketHandler::my_client = NULL; + + /* If for whatever reason the handle isn't closed, do it now. */ + if (this->download_file != NULL) fclose(this->download_file); } NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status) @@ -660,8 +663,6 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WAIT) DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP) { - static FILE *file_pointer; - byte maptype; maptype = p->Recv_uint8(); @@ -670,8 +671,9 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP) /* First packet, init some stuff */ if (maptype == MAP_PACKET_START) { - file_pointer = FioFOpenFile("network_client.tmp", "wb", AUTOSAVE_DIR); - if (file_pointer == NULL) { + if (this->download_file != NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + this->download_file = FioFOpenFile("network_client.tmp", "wb", AUTOSAVE_DIR); + if (this->download_file == NULL) { _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; return NETWORK_RECV_STATUS_SAVEGAME; } @@ -696,20 +698,25 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP) return NETWORK_RECV_STATUS_OKAY; } + if (this->download_file == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + if (maptype == MAP_PACKET_NORMAL) { /* We are still receiving data, put it to the file */ - if (fwrite(p->buffer + p->pos, 1, p->size - p->pos, file_pointer) != (size_t)(p->size - p->pos)) { + if (fwrite(p->buffer + p->pos, 1, p->size - p->pos, this->download_file) != (size_t)(p->size - p->pos)) { _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; + fclose(this->download_file); + this->download_file = NULL; return NETWORK_RECV_STATUS_SAVEGAME; } - _network_join_bytes = ftell(file_pointer); + _network_join_bytes = ftell(this->download_file); SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); } /* Check if this was the last packet */ if (maptype == MAP_PACKET_END) { - fclose(file_pointer); + fclose(this->download_file); + this->download_file = NULL; _network_join_status = NETWORK_JOIN_STATUS_PROCESSING; SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); diff --git a/src/network/network_client.h b/src/network/network_client.h index bdf8209a5..578b8026b 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -18,6 +18,9 @@ /** Class for handling the client side of the game connection. */ class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler { +private: + FILE *download_file; ///< Handle used for downloading the savegame. + protected: friend void NetworkExecuteLocalCommandQueue(); friend void NetworkClose(bool close_admins); |