void gpiDisconnect( GPConnection * connection, GPIBool tellServer ) { GPIConnection * iconnection = (GPIConnection*)*connection; GPIPeer * peer; GPIPeer * delPeer; GPIBool connClosed; // Check if we're already disconnected. // PANTS|05.15.00 /////////////////////////////////////// if(iconnection->connectState == GPI_DISCONNECTED) return; // Skip most of this stuff if we never actually connected. // PANTS|05.16.00 ////////////////////////////////////////////////////////// if(iconnection->connectState != GPI_NOT_CONNECTED) { // Are we connected? //////////////////// if(tellServer && (iconnection->connectState == GPI_CONNECTED)) { // Send the disconnect. /////////////////////// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\logout\\\\sesskey\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); } // Always flush remaining messages. // PANTS|05.16.00 /////////////////////////////////// gpiSendFromBuffer(connection, iconnection->cmSocket, &iconnection->outputBuffer, &connClosed, GPITrue, "CM"); // Cleanup the connection. ////////////////////////// if(iconnection->cmSocket != INVALID_SOCKET) { shutdown(iconnection->cmSocket, 2); closesocket(iconnection->cmSocket); iconnection->cmSocket = INVALID_SOCKET; } if(/*iconnection->peerSocket != INVALID_SOCKET*/ gsUdpEngineIsInitialized()) { //shutdown(iconnection->peerSocket, 2); //closesocket(iconnection->peerSocket); //iconnection->peerSocket = INVALID_SOCKET; gsUdpEngineRemoveMsgHandler(iconnection->mHeader); if (gsUdpEngineNoMoreMsgHandlers() && gsUdpEngineNoApp()) gsUdpEngineShutdown(); } // We're disconnected. ////////////////////// iconnection->connectState = GPI_DISCONNECTED; // Don't keep the userid/profileid. /////////////////////////////////// iconnection->userid = 0; iconnection->profileid = 0; } // freeclear all the memory. /////////////////////// freeclear(iconnection->socketBuffer.buffer); freeclear(iconnection->inputBuffer); freeclear(iconnection->outputBuffer.buffer); freeclear(iconnection->updateproBuffer.buffer); freeclear(iconnection->updateuiBuffer.buffer); while(iconnection->operationList != NULL) gpiRemoveOperation(connection, iconnection->operationList); iconnection->operationList = NULL; for(peer = iconnection->peerList ; peer != NULL ; ) { delPeer = peer; peer = peer->pnext; gpiDestroyPeer(connection, delPeer); } iconnection->peerList = NULL; // Cleanup buddies. // This is not optimal - because we can't continue the mapping // after freeing a profile, we need to start it all over again. /////////////////////////////////////////////////////////////// while(!gpiProfileMap(connection, gpiDisconnectCleanupProfile, NULL)) { }; }
void gpiRemovePeer( GPConnection * connection, GPIPeer * peer ) { GPIPeer * pprev; GPIConnection * iconnection = (GPIConnection*)*connection; GPIMessage * message; GS_ASSERT(peer != NULL); if (peer == NULL) return; GS_ASSERT(iconnection->peerList); if (iconnection->peerList == NULL) return; // Check if this is the first peer. /////////////////////////////////// if(iconnection->peerList == peer) { iconnection->peerList = peer->pnext; } else { // Find the previous peer. ////////////////////////// for(pprev = iconnection->peerList ; pprev->pnext != peer ; pprev = pprev->pnext) { if(pprev->pnext == NULL) { // Can't find this peer in the list! //////////////////////////////////// assert(0); gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "Tried to remove peer not in list."); return; } } pprev->pnext = peer->pnext; } // Check for pending messages. ////////////////////////////// while(ArrayLength(peer->messages)) { // Get the next message. //////////////////////// message = (GPIMessage *)ArrayNth(peer->messages, 0); // Don't forward protocol messages. /////////////////////////////////// if(message->type < 100) gpiSendServerBuddyMessage(connection, peer->profile, message->type, message->buffer.buffer + message->start); // Remove the message. ////////////////////// ArrayDeleteAt(peer->messages, 0); } gpiDestroyPeer(connection, peer); }