Guest User

Untitled

a guest
Jul 21st, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.95 KB | None | 0 0
  1. /** \file ServerCatchcopy.cpp
  2. \brief Define the server of catchcopy
  3. \author alpha_one_x86
  4. \version 0002
  5. \date 2010 */
  6.  
  7. #include "ServerCatchcopy.h"
  8. #include "VariablesCatchcopy.h"
  9. #include "ExtraSocketCatchcopy.h"
  10.  
  11. #include <QFile>
  12.  
  13. ServerCatchcopy::ServerCatchcopy()
  14. {
  15.     name="Default avanced copier";
  16.     autoReply=true;
  17.     idNextClient=0;
  18.     error_string="Unknown error";
  19.     connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection()));
  20.     #ifdef Q_OS_WIN32
  21.     connect(this,SIGNAL(trySetRights()),this,SLOT(setRights()));
  22.     #endif
  23. }
  24.  
  25. ServerCatchcopy::~ServerCatchcopy()
  26. {
  27.     close();
  28. }
  29.  
  30. bool ServerCatchcopy::isListening()
  31. {
  32.     return server.isListening();
  33. }
  34.  
  35. void ServerCatchcopy::setName(const QString & name)
  36. {
  37.     this->name=name;
  38. }
  39.  
  40. QString ServerCatchcopy::getName()
  41. {
  42.     return name;
  43. }
  44.  
  45. #ifdef Q_OS_WIN32
  46. int ServerCatchcopy::ChangeFileOwner()
  47. {
  48.     emit error("Start: ChangeFileOwner");
  49.     HANDLE token;
  50.     wchar_t filename[1024];
  51.     int size=QString("\\\\.\\pipe\\"+pathSocket).toWCharArray(filename);
  52.     DWORD len;
  53.     PSECURITY_DESCRIPTOR security = NULL;
  54.     int retValue = 1;
  55.     PSID sid;
  56.  
  57.     emit error("ChangeFileOwner: Get the privileges you need");
  58.     // Get the privileges you need
  59.     if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
  60.  
  61.     if(!SetPrivilege(L"SeTakeOwnershipPrivilege", 1))retValue=0;
  62.         if(!SetPrivilege(L"SeSecurityPrivilege", 1))retValue=0;
  63.         if(!SetPrivilege(L"SeBackupPrivilege", 1))retValue=0;
  64.         if(!SetPrivilege(L"SeRestorePrivilege", 1))retValue=0;
  65.     } else retValue = 0;
  66.     emit error("ChangeFileOwner: retValue: "+QString::number(retValue));
  67.  
  68.     // Create the security descriptor
  69.     if (retValue) {
  70.         emit error("ChangeFileOwner: Create the security descriptor");
  71.         GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, security, 0, &len);
  72.         security = (PSECURITY_DESCRIPTOR)malloc(len);
  73.         if (!InitializeSecurityDescriptor(security,SECURITY_DESCRIPTOR_REVISION))
  74.         retValue = 0;
  75.     }
  76.  
  77.     // Get the sid for the username
  78.     if (retValue) {
  79.         emit error("ChangeFileOwner: Get the sid for the username");
  80.         GetLogonSID(token, &sid) ;
  81.         }
  82.  
  83.     // Set the sid to be the new owner
  84.     if (retValue && !SetSecurityDescriptorOwner(security, sid, 0))
  85.     {
  86.         emit error("ChangeFileOwner: Set the sid to be the new owner: failed");
  87.         retValue = 0;
  88.     }
  89.     else
  90.         emit error("ChangeFileOwner: Set the sid to be the new owner: success");
  91.  
  92.     // Save the security descriptor
  93.     if (retValue)
  94.     {
  95.         retValue = SetFileSecurity(filename, OWNER_SECURITY_INFORMATION, security);
  96.         emit error("ChangeFileOwner: Save the security descriptor: "+QString::number(retValue));
  97.         #ifdef CATCHCOPY_EXPLORER_PLUGIN_DEBUG
  98.         void* lpBuffer;
  99.         FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  100.         NULL,
  101.         ::GetLastError(),
  102.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  103.         (LPTSTR) &lpBuffer,
  104.         0,
  105.         NULL );
  106.         MessageBox(NULL,(LPCTSTR)lpBuffer, L"GetUserName Failed", MB_OK);
  107.         LocalFree( lpBuffer );
  108.         #endif // CATCHCOPY_EXPLORER_PLUGIN_DEBUG
  109.     }
  110.     if (security) free(security);
  111.  
  112.     return retValue;
  113. }
  114.  
  115. BOOL ServerCatchcopy::GetLogonSID (HANDLE hToken, PSID *ppsid)
  116. {
  117.    BOOL bSuccess = FALSE;
  118.    DWORD dwIndex;
  119.    DWORD dwLength = 0;
  120.    PTOKEN_GROUPS ptg = NULL;
  121. // Get required buffer size and allocate the TOKEN_GROUPS buffer.
  122.    GetTokenInformation(hToken,TokenGroups,(LPVOID) ptg,0,&dwLength) ;
  123.  
  124.    ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
  125.      HEAP_ZERO_MEMORY, dwLength);
  126. // Get the token group information from the access token.
  127.    GetTokenInformation(hToken,TokenGroups,(LPVOID) ptg,dwLength,&dwLength) ;
  128. // Loop through the groups to find the logon SID.
  129.    for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
  130.    {
  131.       if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
  132.          ==  SE_GROUP_LOGON_ID)
  133.       {
  134.       // Found the logon SID; make a copy of it.
  135.  
  136.      dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
  137.      *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
  138.              HEAP_ZERO_MEMORY, dwLength);
  139.      CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid);
  140.  
  141.      break;
  142.       }
  143.    }
  144. return TRUE;
  145.  
  146. }
  147.  
  148. int ServerCatchcopy::SetPrivilege(WCHAR *privilege, int enable)
  149. {
  150.     TOKEN_PRIVILEGES tp;
  151.     LUID luid;
  152.     HANDLE token;
  153.  
  154.     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) return 0;
  155.     if (!LookupPrivilegeValue(NULL, privilege, &luid)) return 0;
  156.  
  157.     tp.PrivilegeCount = 1;
  158.     tp.Privileges[0].Luid = luid;
  159.     if (enable) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  160.     else tp.Privileges[0].Attributes = 0;
  161.  
  162.     // Enable the privilege or disable all privileges.
  163.     return AdjustTokenPrivileges(token, 0, &tp, NULL, NULL, NULL);
  164. }
  165.  
  166. void ServerCatchcopy::setRights()
  167. {
  168.     ChangeFileOwner();
  169.     QFlags<QFile::Permission> perms = ( QFile::ReadOwner | QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther );
  170.     if(!QFile::setPermissions("\\\\.\\pipe\\"+pathSocket,perms))
  171.     {
  172.         error_string="Socket error: Qt unable to set the rights";
  173.         emit error(error_string);
  174.     }
  175.     wchar_t lpPath[1024];
  176.     int size=QString("\\\\.\\pipe\\"+pathSocket).toWCharArray(lpPath);
  177.     emit error(QString::fromWCharArray(lpPath,size));
  178.     HANDLE windows_pipe = CreateFile(lpPath,READ_CONTROL|WRITE_DAC|WRITE_OWNER,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
  179.     //HANDLE windows_pipe = CreateFileW(lpPath, GENERIC_READ|GENERIC_WRITE|FILE_FLAG_OVERLAPPED , 0, NULL, OPEN_EXISTING, 0, NULL);
  180.     if(windows_pipe == INVALID_HANDLE_VALUE)
  181.     {
  182.         void* lpBuffer;
  183.         FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  184.         NULL,
  185.         ::GetLastError(),
  186.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  187.         (LPTSTR) &lpBuffer,
  188.         0,
  189.         NULL );
  190.         MessageBox(NULL,(LPCTSTR)lpBuffer, L"GetUserName Failed", MB_OK);
  191.         LocalFree( lpBuffer );
  192.         error_string="Socket error: INVALID_HANDLE_VALUE for windows";
  193.         emit error(error_string);
  194.         return;
  195.     }
  196.  
  197.     ACL* pOldDACL;
  198.     SECURITY_DESCRIPTOR* pSD = NULL;
  199.     #if defined(_M_X64) //_WIN64
  200.         //windows 64Bits
  201.         GetSecurityInfo(windows_pipe, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, (void**)&pSD);
  202.     #else
  203.         //windows 32Bits
  204.         GetSecurityInfo(windows_pipe, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, &pSD);
  205.     #endif
  206.  
  207.  
  208.     PSID pSid = NULL;
  209.     SID_IDENTIFIER_AUTHORITY authNt = SECURITY_WORLD_SID_AUTHORITY;
  210.     AllocateAndInitializeSid(&authNt,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_USERS,0,0,0,0,0,0,&pSid);
  211.  
  212.     EXPLICIT_ACCESS ea={0};
  213.     ea.grfAccessMode = GRANT_ACCESS;
  214.     ea.grfAccessPermissions = GENERIC_ALL;
  215.     ea.grfInheritance = CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;
  216.     ea.Trustee.TrusteeType = TRUSTEE_IS_COMPUTER;
  217.     ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  218.     ea.Trustee.ptstrName = (LPTSTR)pSid;
  219.  
  220.     ACL* pNewDACL = 0;
  221.     DWORD err = SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);
  222.  
  223.     if(pNewDACL)
  224.     SetSecurityInfo(windows_pipe,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, pNewDACL, NULL);
  225.  
  226.     FreeSid(pSid);
  227.     LocalFree(pNewDACL);
  228.     LocalFree(pSD);
  229.     LocalFree(pOldDACL);
  230.     CloseHandle(windows_pipe);
  231. }
  232. #endif
  233.  
  234. bool ServerCatchcopy::listen()
  235. {
  236.     QLocalSocket socketTestConnection;
  237.     pathSocket=ExtraSocketCatchcopy::pathSocket();
  238.     socketTestConnection.connectToServer(pathSocket);
  239.     if(socketTestConnection.waitForConnected(CATCHCOPY_COMMUNICATION_TIMEOUT))
  240.     {
  241.         error_string="Other server is listening";
  242.         emit error(error_string);
  243.         return false;
  244.     }
  245.     else
  246.     {
  247.         if(!server.removeServer(pathSocket))
  248.         {
  249.             error_string="Unable to remove the old server";
  250.             emit error(error_string);
  251.         }
  252.         if(server.listen(pathSocket))
  253.         {
  254.             #ifdef Q_OS_WIN32
  255.             emit trySetRights();
  256.             #endif
  257.             return true;
  258.         }
  259.         else
  260.         {
  261.             error_string=QString("Unable to listen %1: %2").arg(pathSocket).arg(server.errorString());
  262.             emit error(error_string);
  263.             return false;
  264.         }
  265.     }
  266. }
  267.  
  268. void ServerCatchcopy::close()
  269. {
  270.     if(server.isListening())
  271.     {
  272.         int index=0;
  273.         while(index<ClientList.size())
  274.         {
  275.             ClientList.at(index).socket->disconnectFromServer();
  276.             index++;
  277.         }
  278.         server.close();
  279.         if(!server.removeServer(pathSocket))
  280.         {
  281.             error_string="Unable to remove the old server";
  282.             emit error(error_string);
  283.         }
  284.     }
  285. }
  286.  
  287. const QString ServerCatchcopy::errorStringServer()
  288. {
  289.     return server.errorString();
  290. }
  291.  
  292. const QString ServerCatchcopy::errorString()
  293. {
  294.     return error_string;
  295. }
  296.  
  297. /// \brief New connexion
  298. void ServerCatchcopy::newConnection()
  299. {
  300.     while(server.hasPendingConnections())
  301.     {
  302.         QLocalSocket *clientSocket = server.nextPendingConnection();
  303.         if(clientSocket!=NULL)
  304.         {
  305.             do
  306.             {
  307.                 idNextClient++;
  308.                 if(idNextClient>2000000000)
  309.                     idNextClient=0;
  310.             } while(clientIdFound(idNextClient));
  311.             Client newClient;
  312.             newClient.id            = idNextClient;
  313.             newClient.socket        = clientSocket;
  314.             newClient.haveData      = false;
  315.             newClient.firstProtocolReplied  = false;
  316.             newClient.detectTimeOut     = new QTimer(this);
  317.             newClient.detectTimeOut->setSingleShot(true);
  318.             newClient.detectTimeOut->setInterval(CATCHCOPY_COMMUNICATION_TIMEOUT);
  319.             connect(newClient.socket,   SIGNAL(error(QLocalSocket::LocalSocketError))this, SLOT(connectionError(QLocalSocket::LocalSocketError)));
  320.             connect(newClient.socket,   SIGNAL(readyRead()),                this, SLOT(readyRead()));
  321.             connect(newClient.socket,   SIGNAL(disconnected()),             this, SLOT(disconnected()));
  322.             connect(newClient.detectTimeOut,SIGNAL(timeout()),              this, SLOT(checkTimeOut()));
  323.             ClientList << newClient;
  324.             emit connectedClient(newClient.id);
  325.         }
  326.     }
  327. }
  328.  
  329. bool ServerCatchcopy::clientIdFound(quint32 id)
  330. {
  331.     int index=0;
  332.     while(index<ClientList.size())
  333.     {
  334.         if(ClientList.at(index).id==id)
  335.             return true;
  336.         index++;
  337.     }
  338.     return false;
  339. }
  340.  
  341. /// \brief new error at connexion
  342. void ServerCatchcopy::connectionError(QLocalSocket::LocalSocketError error)
  343. {
  344.     QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender());
  345.     if(socket==NULL)
  346.     {
  347.         qWarning() << "Unlocated client socket!";
  348.         return;
  349.     }
  350.     int index=0;
  351.     while(index<ClientList.size())
  352.     {
  353.         if(ClientList.at(index).socket==socket)
  354.         {
  355.             if(error!=QLocalSocket::PeerClosedError)
  356.                 qWarning() << "error detected for the client: " << index << ", type: " << error;
  357.             ClientList.at(index).socket->disconnectFromServer();
  358.             return;
  359.         }
  360.         index++;
  361.     }
  362. }
  363.  
  364. void ServerCatchcopy::disconnected()
  365. {
  366.     QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender());
  367.     if(socket==NULL)
  368.     {
  369.         qWarning() << "Unlocated client socket!";
  370.         return;
  371.     }
  372.     int index=0;
  373.     while(index<ClientList.size())
  374.     {
  375.         if(ClientList.at(index).socket==socket)
  376.         {
  377.             emit disconnectedClient(ClientList.at(index).id);
  378.             disconnect(ClientList.at(index).socket);
  379.             disconnect(ClientList.at(index).detectTimeOut);
  380.             delete ClientList.at(index).detectTimeOut;
  381.             ClientList.at(index).socket->abort();
  382.             ClientList.at(index).socket->disconnectFromServer();
  383.             ClientList.at(index).socket->deleteLater();
  384.             ClientList.removeAt(index);
  385.             return;
  386.         }
  387.         index++;
  388.     }
  389.     qWarning() << "Unlocated client!";
  390. }
  391.  
  392. void ServerCatchcopy::disconnectClient(quint32 id)
  393. {
  394.     int index=0;
  395.     while(index<ClientList.size())
  396.     {
  397.         if(ClientList.at(index).id==id)
  398.         {
  399.             ClientList.at(index).socket->disconnectFromServer();
  400.             return;
  401.         }
  402.         index++;
  403.     }
  404.     qWarning() << "Unlocated client!";
  405. }
  406.  
  407. void ServerCatchcopy::readyRead()
  408. {
  409.     QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender());
  410.     if(socket==NULL)
  411.     {
  412.         qWarning() << "Unlocated client socket!";
  413.         return;
  414.     }
  415.     int index=0;
  416.     while(index<ClientList.size())
  417.     {
  418.         if(ClientList.at(index).socket==socket)
  419.         {
  420.             while(socket->bytesAvailable()>0)
  421.             {
  422.                 if(!ClientList.at(index).haveData)
  423.                 {
  424.                     if(socket->bytesAvailable()<(int)sizeof(int))//ignore because first int is cuted!
  425.                     {
  426.                         /*error_string="Bytes available is not sufficient to do a int";
  427.                         emit error(error_string);
  428.                         disconnectClient(ClientList.at(index).id);*/
  429.                         return;
  430.                     }
  431.                     QDataStream in(socket);
  432.                     in.setVersion(QDataStream::Qt_4_4);
  433.                     in >> ClientList[index].dataSize;
  434.                     ClientList[index].dataSize-=sizeof(int);
  435.                     if(ClientList.at(index).dataSize>64*1024*1024) // 64MB
  436.                     {
  437.                         error_string="Reply size is >64MB, seam corrupted";
  438.                         emit error(error_string);
  439.                         disconnectClient(ClientList.at(index).id);
  440.                         return;
  441.                     }
  442.                     if(ClientList.at(index).dataSize<(int)(sizeof(int) //orderId
  443.                              + sizeof(quint32) //returnCode
  444.                              + sizeof(quint32) //string list size
  445.                                 ))
  446.                     {
  447.                         error_string="Reply size is too small to have correct code";
  448.                         emit error(error_string);
  449.                         disconnectClient(ClientList.at(index).id);
  450.                         return;
  451.                     }
  452.                     ClientList[index].haveData=true;
  453.                 }
  454.                 if(ClientList.at(index).dataSize<(ClientList.at(index).data.size()+socket->bytesAvailable()))
  455.                     ClientList[index].data.append(socket->read(ClientList.at(index).dataSize-ClientList.at(index).data.size()));
  456.                 else
  457.                     ClientList[index].data.append(socket->readAll());
  458.                 if(ClientList.at(index).dataSize==(quint32)ClientList.at(index).data.size())
  459.                 {
  460.                     if(!checkDataIntegrity(ClientList.at(index).data))
  461.                     {
  462.                         emit error("Data integrity wrong: "+QString(ClientList.at(index).data.toHex()));
  463.                         ClientList[index].data.clear();
  464.                         ClientList[index].haveData=false;
  465.                         qWarning() << "Data integrity wrong";
  466.                         return;
  467.                     }
  468.                     QStringList returnList;
  469.                     quint32 orderId;
  470.                     QDataStream in(ClientList.at(index).data);
  471.                     in.setVersion(QDataStream::Qt_4_4);
  472.                     in >> orderId;
  473.                     in >> returnList;
  474.                     ClientList[index].data.clear();
  475.                     ClientList[index].haveData=false;
  476.                     if(ClientList.at(index).queryNoReplied.contains(orderId))
  477.                     {
  478.                         emit error("Duplicate query id");
  479.                         qWarning() << "Duplicate query id";
  480.                         return;
  481.                     }
  482.                     ClientList[index].queryNoReplied << orderId;
  483.                     if(!ClientList.at(index).firstProtocolReplied && returnList.size()==2 && returnList.first()=="protocol" && autoReply)
  484.                     {
  485.                         ClientList[index].firstProtocolReplied=true;
  486.                         protocolSupported(ClientList.at(index).id,orderId,(returnList.last()==CATCHCOPY_PROTOCOL_VERSION));
  487.                     }
  488.                     else
  489.                         parseInput(ClientList.at(index).id,orderId,returnList);
  490.                 }
  491.             }
  492.             if(ClientList.at(index).haveData)
  493.                 ClientList.at(index).detectTimeOut->start();
  494.             else
  495.                 ClientList.at(index).detectTimeOut->stop();
  496.             return;
  497.         }
  498.         index++;
  499.     }
  500.     emit error("Unallocated client!");
  501.     qWarning() << "Unallocated client!";
  502. }
  503.  
  504. bool ServerCatchcopy::checkDataIntegrity(QByteArray data)
  505. {
  506.     quint32 orderId;
  507.     qint32 listSize;
  508.     QDataStream in(data);
  509.     in.setVersion(QDataStream::Qt_4_4);
  510.     in >> orderId;
  511.     in >> listSize;
  512.     if(listSize>65535)
  513.     {
  514.         emit error("List size is wrong");
  515.         qWarning() << "List size is wrong";
  516.         return false;
  517.     }
  518.     int index=0;
  519.     while(index<listSize)
  520.     {
  521.         qint32 stringSize;
  522.         in >> stringSize;
  523.         if(stringSize>65535)
  524.         {
  525.             emit error("String size is wrong");
  526.             return false;
  527.         }
  528.         if(stringSize>(in.device()->size()-in.device()->pos()))
  529.         {
  530.             emit error(QString("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos()));
  531.             return false;
  532.         }
  533.         in.device()->seek(in.device()->pos()+stringSize);
  534.         index++;
  535.     }
  536.     if(in.device()->size()!=in.device()->pos())
  537.     {
  538.         emit error("Remaining data after string list parsing");
  539.         return false;
  540.     }
  541.     return true;
  542. }
  543.  
  544. void ServerCatchcopy::parseInput(quint32 client,quint32 orderId,QStringList returnList)
  545. {
  546.     switch(parseInputCurrentProtocol(client,orderId,returnList))
  547.     {
  548.         case Ok:
  549.             emit newQuery(client,orderId,returnList);
  550.         break;
  551.         case Replied:
  552.         break;
  553.         case ExtensionWrong:
  554.             if(autoReply)
  555.                 protocolExtensionSupported(client,orderId,false);
  556.             else
  557.                 emit newQuery(client,orderId,returnList);
  558.         break;
  559.         case WrongArgument:
  560.             if(autoReply)
  561.                 incorrectArgument(client,orderId);
  562.             else
  563.                 emit newQuery(client,orderId,returnList);
  564.         break;
  565.         case WrongArgumentListSize:
  566.             if(autoReply)
  567.                 incorrectArgumentListSize(client,orderId);
  568.             else
  569.                 emit newQuery(client,orderId,returnList);
  570.         break;
  571.         case UnknowOrder:
  572.             emit error("Unknown query");
  573.             qWarning() << "Unknown query";
  574.             if(autoReply)
  575.                 unknowOrder(client,orderId);
  576.             else
  577.                 emit newQuery(client,orderId,returnList);
  578.         break;
  579.     }
  580. }
  581.  
  582. ServerCatchcopy::inputReturnType ServerCatchcopy::parseInputCurrentProtocol(quint32 client,quint32 orderId,QStringList returnList)
  583. {
  584.     if(returnList.size()==0)
  585.         return WrongArgumentListSize;
  586.     //if is supported
  587.     QString firstArgument=returnList.first();
  588.     if(firstArgument=="protocol")
  589.     {
  590.         if(returnList.size()!=2)
  591.             return WrongArgumentListSize;
  592.         emit askProtocolCompatibility(client,orderId,returnList.last());
  593.         return Ok;
  594.     }
  595.     else if(firstArgument=="protocol extension")
  596.     {
  597.         if(returnList.size()>3 || returnList.size()<2)
  598.             return WrongArgumentListSize;
  599.         if(!autoReply)
  600.         {
  601.             if(returnList.size()==2)
  602.                 emit askProtocolExtension(client,orderId,returnList.last());
  603.             else
  604.                 emit askProtocolExtension(client,orderId,returnList.at(1),returnList.last());
  605.         }
  606.         return ExtensionWrong;
  607.     }
  608.     else if(firstArgument=="client")
  609.     {
  610.         if(returnList.size()!=2)
  611.             return WrongArgumentListSize;
  612.         emit clientName(client,returnList.last());
  613.         if(autoReply)
  614.         {
  615.             clientRegistered(client,orderId);
  616.             return Replied;
  617.         }
  618.         else
  619.         {
  620.             emit clientName(client,orderId,returnList.last());
  621.             return Ok;
  622.         }
  623.     }
  624.     else if(firstArgument=="server")
  625.     {
  626.         if(returnList.size()!=2)
  627.             return WrongArgumentListSize;
  628.         if(returnList.last()!="name?")
  629.             return WrongArgument;
  630.         if(autoReply)
  631.         {
  632.             serverName(client,orderId,name);
  633.             return Replied;
  634.         }
  635.         else
  636.         {
  637.             askServerName(client,orderId);
  638.             return Ok;
  639.         }
  640.     }
  641.     else if(firstArgument=="cp")
  642.     {
  643.         if(returnList.size()<3)
  644.             return WrongArgumentListSize;
  645.         QStringList sourceList=returnList;
  646.         sourceList.removeFirst();
  647.         sourceList.removeLast();
  648.         emitNewCopy(client,orderId,sourceList,returnList.last());
  649.         return Ok;
  650.     }
  651.     else if(firstArgument=="cp-?")
  652.     {
  653.         if(returnList.size()<2)
  654.             return WrongArgumentListSize;
  655.         QStringList sourceList=returnList;
  656.         sourceList.removeFirst();
  657.         emitNewCopy(client,orderId,sourceList);
  658.         return Ok;
  659.     }
  660.     else if(firstArgument=="mv")
  661.     {
  662.         if(returnList.size()<3)
  663.             return WrongArgumentListSize;
  664.         QStringList sourceList=returnList;
  665.         sourceList.removeFirst();
  666.         sourceList.removeLast();
  667.         emitNewMove(client,orderId,sourceList,returnList.last());
  668.         return Ok;
  669.     }
  670.     else if(firstArgument=="mv-?")
  671.     {
  672.         if(returnList.size()<2)
  673.             return WrongArgumentListSize;
  674.         QStringList sourceList=returnList;
  675.         sourceList.removeFirst();
  676.         emitNewMove(client,orderId,sourceList);
  677.         return Ok;
  678.     }
  679.     else //if is not supported
  680.         return UnknowOrder;
  681. }
  682.  
  683. void ServerCatchcopy::emitNewCopy(quint32 client,quint32 orderId,QStringList sources)
  684. {
  685.     emit newCopy(client,orderId,sources);
  686.     LinkGlobalToLocalClient newAssociation;
  687.     newAssociation.idClient=client;
  688.     newAssociation.orderId=orderId;
  689.     newAssociation.globalOrderId=incrementOrderId();
  690.     LinkGlobalToLocalClientList << newAssociation;
  691.     emit newCopy(newAssociation.globalOrderId,sources);
  692. }
  693.  
  694. void ServerCatchcopy::emitNewCopy(quint32 client,quint32 orderId,QStringList sources,QString destination)
  695. {
  696.     emit newCopy(client,orderId,sources,destination);
  697.     LinkGlobalToLocalClient newAssociation;
  698.     newAssociation.idClient=client;
  699.     newAssociation.orderId=orderId;
  700.     newAssociation.globalOrderId=incrementOrderId();
  701.     LinkGlobalToLocalClientList << newAssociation;
  702.     emit newCopy(newAssociation.globalOrderId,sources,destination);
  703. }
  704.  
  705. void ServerCatchcopy::emitNewMove(quint32 client,quint32 orderId,QStringList sources)
  706. {
  707.     emit newMove(client,orderId,sources);
  708.     LinkGlobalToLocalClient newAssociation;
  709.     newAssociation.idClient=client;
  710.     newAssociation.orderId=orderId;
  711.     newAssociation.globalOrderId=incrementOrderId();
  712.     LinkGlobalToLocalClientList << newAssociation;
  713.     emit newMove(newAssociation.globalOrderId,sources);
  714. }
  715.  
  716. void ServerCatchcopy::emitNewMove(quint32 client,quint32 orderId,QStringList sources,QString destination)
  717. {
  718.     emit newMove(client,orderId,sources,destination);
  719.     LinkGlobalToLocalClient newAssociation;
  720.     newAssociation.idClient=client;
  721.     newAssociation.orderId=orderId;
  722.     newAssociation.globalOrderId=incrementOrderId();
  723.     LinkGlobalToLocalClientList << newAssociation;
  724.     emit newMove(newAssociation.globalOrderId,sources,destination);
  725. }
  726.  
  727. void ServerCatchcopy::copyFinished(quint32 globalOrderId,bool withError)
  728. {
  729.     int index=0;
  730.     while(index<LinkGlobalToLocalClientList.size())
  731.     {
  732.         if(LinkGlobalToLocalClientList.at(index).globalOrderId==globalOrderId)
  733.         {
  734.             copyFinished(LinkGlobalToLocalClientList.at(index).idClient,LinkGlobalToLocalClientList.at(index).orderId,withError);
  735.             LinkGlobalToLocalClientList.removeAt(index);
  736.             orderList.removeOne(globalOrderId);
  737.             return;
  738.         }
  739.         index++;
  740.     }
  741. }
  742.  
  743. void ServerCatchcopy::copyCanceled(quint32 globalOrderId)
  744. {
  745.     int index=0;
  746.     while(index<LinkGlobalToLocalClientList.size())
  747.     {
  748.         if(LinkGlobalToLocalClientList.at(index).globalOrderId==globalOrderId)
  749.         {
  750.             copyCanceled(LinkGlobalToLocalClientList.at(index).idClient,LinkGlobalToLocalClientList.at(index).orderId);
  751.             LinkGlobalToLocalClientList.removeAt(index);
  752.             orderList.removeOne(globalOrderId);
  753.             return;
  754.         }
  755.         index++;
  756.     }
  757. }
  758.  
  759. void ServerCatchcopy::setAutoReply(bool value)
  760. {
  761.     autoReply=value;
  762. }
  763.  
  764. bool ServerCatchcopy::getAutoReply()
  765. {
  766.     return autoReply;
  767. }
  768.  
  769. void ServerCatchcopy::reply(quint32 client,quint32 orderId,quint32 returnCode,QString returnString)
  770. {
  771.     reply(client,orderId,returnCode,QStringList() << returnString);
  772. }
  773.  
  774. void ServerCatchcopy::reply(quint32 client,quint32 orderId,quint32 returnCode,QStringList returnList)
  775. {
  776.     int index=0;
  777.     while(index<ClientList.size())
  778.     {
  779.         if(ClientList.at(index).id==client)
  780.         {
  781.             if(ClientList.at(index).socket->isValid() && ClientList.at(index).socket->state()==QLocalSocket::ConnectedState)
  782.             {
  783.                 if(!ClientList.at(index).queryNoReplied.contains(orderId))
  784.                 {
  785.                     qWarning() << "Reply to missing query or previously replied";
  786.                     return;
  787.                 }
  788.                 ClientList[index].queryNoReplied.removeOne(orderId);
  789.                 //cut string list and send it as block of 32KB
  790.                 QByteArray block;
  791.                 QDataStream out(&block, QIODevice::WriteOnly);
  792.                 out.setVersion(QDataStream::Qt_4_4);
  793.                 out << int(0);
  794.                 out << orderId;
  795.                 out << returnCode;
  796.                 out << returnList;
  797.                 out.device()->seek(0);
  798.                 out << block.size();
  799.                 emit dataSend(client,orderId,returnCode,block);
  800.                 emit dataSend(client,orderId,returnCode,returnList);
  801.                 do
  802.                 {
  803.                     QByteArray blockToSend;
  804.                     int byteWriten;
  805.                     blockToSend=block.left(32*1024);//32KB
  806.                     block.remove(0,blockToSend.size());
  807.                     byteWriten = ClientList[index].socket->write(blockToSend);
  808.                     if(!ClientList[index].socket->isValid())
  809.                     {
  810.                         error_string="Socket is not valid";
  811.                         emit error(error_string);
  812.                         return;
  813.                     }
  814.                     if(ClientList[index].socket->errorString()!="Unknown error" && ClientList[index].socket->errorString()!="")
  815.                     {
  816.                         error_string="Error with socket: "+ClientList[index].socket->errorString();
  817.                         emit error(error_string);
  818.                         return;
  819.                     }
  820.                     if(blockToSend.size()!=byteWriten)
  821.                     {
  822.                         error_string="All the bytes have not be written";
  823.                         emit error(error_string);
  824.                         return;
  825.                     }
  826.                 }
  827.                 while(block.size());
  828.             }
  829.             else
  830.             {
  831.                 error_string="Socket is not valid or not connected";
  832.                 emit error(error_string);
  833.             }
  834.             return;
  835.         }
  836.         index++;
  837.     }
  838.     qWarning() << "Client id not found:" << client;
  839. }
  840.  
  841. void ServerCatchcopy::protocolSupported(quint32 client,quint32 orderId,bool value)
  842. {
  843.     if(value)
  844.         reply(client,orderId,1000,"protocol supported");
  845.     else
  846.         reply(client,orderId,5003,"protocol not supported");
  847. }
  848.  
  849. void ServerCatchcopy::incorrectArgumentListSize(quint32 client,quint32 orderId)
  850. {
  851.     reply(client,orderId,5000,"incorrect argument list size");
  852. }
  853.  
  854. void ServerCatchcopy::incorrectArgument(quint32 client,quint32 orderId)
  855. {
  856.     reply(client,orderId,5001,"incorrect argument");
  857. }
  858.  
  859. void ServerCatchcopy::protocolExtensionSupported(quint32 client,quint32 orderId,bool value)
  860. {
  861.     if(value)
  862.         reply(client,orderId,1001,"protocol extension supported");
  863.     else
  864.         reply(client,orderId,1002,"protocol extension not supported");
  865. }
  866.  
  867. void ServerCatchcopy::clientRegistered(quint32 client,quint32 orderId)
  868. {
  869.     reply(client,orderId,1003,"client registered");
  870. }
  871.  
  872. void ServerCatchcopy::serverName(quint32 client,quint32 orderId,QString name)
  873. {
  874.     reply(client,orderId,1004,name);
  875. }
  876.  
  877. void ServerCatchcopy::copyFinished(quint32 client,quint32 orderId,bool withError)
  878. {
  879.     if(!withError)
  880.         reply(client,orderId,1005,"finished");
  881.     else
  882.         reply(client,orderId,1006,"finished with error(s)");
  883. }
  884.  
  885. void ServerCatchcopy::copyCanceled(quint32 client,quint32 orderId)
  886. {
  887.     reply(client,orderId,1007,"canceled");
  888. }
  889.  
  890. void ServerCatchcopy::unknowOrder(quint32 client,quint32 orderId)
  891. {
  892.     reply(client,orderId,5002,"unknown order");
  893. }
  894.  
  895. void ServerCatchcopy::checkTimeOut()
  896. {
  897.     QTimer *timer=qobject_cast<QTimer *>(QObject::sender());
  898.     if(timer==NULL)
  899.     {
  900.         qWarning() << "Unallocated client timer!";
  901.         return;
  902.     }
  903.     int index=0;
  904.     while(index<ClientList.size())
  905.     {
  906.         if(ClientList.at(index).detectTimeOut==timer)
  907.         {
  908.             ClientList.at(index).detectTimeOut->stop();
  909.             if(ClientList.at(index).haveData)
  910.             {
  911.                 error_string="The client is too long to send the next part of the reply: "+ClientList.at(index).data;
  912.                 ClientList[index].haveData=false;
  913.                 ClientList[index].data.clear();
  914.                 ClientList.at(index).socket->disconnectFromServer();
  915.                 emit error(error_string);
  916.             }
  917.             return;
  918.         }
  919.         index++;
  920.     }
  921. }
  922.  
  923. quint32 ServerCatchcopy::incrementOrderId()
  924. {
  925.     do
  926.     {
  927.         nextOrderId++;
  928.         if(nextOrderId>2000000)
  929.             nextOrderId=0;
  930.     } while(orderList.contains(nextOrderId));
  931.     return nextOrderId;
  932. }
Add Comment
Please, Sign In to add comment