/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/network/lscpserver.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2516 by schoenebeck, Thu Feb 6 21:11:23 2014 UTC revision 2528 by schoenebeck, Mon Mar 3 12:02:40 2014 UTC
# Line 47  Line 47 
47    
48  namespace LinuxSampler {  namespace LinuxSampler {
49    
50  String lscpParserProcessShellInteraction(String& line, yyparse_param_t* param);  String lscpParserProcessShellInteraction(String& line, yyparse_param_t* param, bool possibilities);
51    
52  /**  /**
53   * Returns a copy of the given string where all special characters are   * Returns a copy of the given string where all special characters are
# Line 722  extern yyparse_param_t* GetCurrentYaccSe Line 722  extern yyparse_param_t* GetCurrentYaccSe
722   */   */
723  bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {  bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {
724          int socket = (*iter).hSession;          int socket = (*iter).hSession;
725            int result;
726          char c;          char c;
727          int i = 0;          std::vector<char> input;
728    
729            // first get as many character as possible and add it to the 'input' buffer
730          while (true) {          while (true) {
731                  #if defined(WIN32)                  #if defined(WIN32)
732                  int result = recv(socket, (char *)&c, 1, 0); //Read one character at a time for now                  result = recv(socket, (char *)&c, 1, 0); //Read one character at a time for now
733                  #else                  #else
734                  int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now                  result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now
735                  #endif                  #endif
736                  if (result == 0) { //socket was selected, so 0 here means client has closed the connection                  if (result == 1) input.push_back(c);
737                          CloseConnection(iter);                  else break; // end of input or some error
738                          break;                  if (c == '\n') break; // process line by line
739                  }          }
740                  if (result == 1) {  
741                          if (c == '\r')          // process input buffer
742                                  continue; //Ignore CR          for (int i = 0; i < input.size(); ++i) {
743                          if (c == '\n') {                  c = input[i];
744                                  LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));                  if (c == '\r') continue; //Ignore CR
745                                  bufferedCommands[socket] += "\r\n";                  if (c == '\n') {
                                 return true; //Complete command was read  
                         }  
                         // backspace character - should only happen with shell  
                         if (c == '\b') {  
                                 if (!bufferedCommands[socket].empty()) {  
                                         bufferedCommands[socket] = bufferedCommands[socket].substr(  
                                                 0, bufferedCommands[socket].length() - 1  
                                         );  
                                 }  
                         } else bufferedCommands[socket] += c;  
746                          // only if the other side is the LSCP shell application:                          // only if the other side is the LSCP shell application:
747                          // check the current (incomplete) command line for syntax errors,                          // check the current (incomplete) command line for syntax errors,
748                          // possible completions and report everything back to the shell                          // possible completions and report everything back to the shell
749                          if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {                          if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
750                                  String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter));                                  String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), false);
751                                  if (!s.empty() && (*iter).bShellInteract) AnswerClient(s + "\n");                                  if (!s.empty() && (*iter).bShellInteract) AnswerClient(s + "\n");
752                          }                          }
753    
754                            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
755                            bufferedCommands[socket] += "\r\n";
756                            return true; //Complete command was read
757                  }                  }
758                  #if defined(WIN32)                  // backspace character - should only happen with shell
759                  if (result == SOCKET_ERROR) {                  if (c == '\b') {
760                      int wsa_lasterror = WSAGetLastError();                          if (!bufferedCommands[socket].empty()) {
761                          if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.                                  bufferedCommands[socket] = bufferedCommands[socket].substr(
762                                  return false;                                          0, bufferedCommands[socket].length() - 1
763                          dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));                                  );
764                          CloseConnection(iter);                          }
765                          break;                  } else bufferedCommands[socket] += c;
766                    // only if the other side is the LSCP shell application:
767                    // check the current (incomplete) command line for syntax errors,
768                    // possible completions and report everything back to the shell
769                    if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
770                            String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), true);
771                            if (!s.empty() && (*iter).bShellInteract && i == input.size() - 1)
772                                    AnswerClient(s + "\n");
773                  }                  }
774                  #else          }
775                  if (result == -1) {  
776                          if (errno == EAGAIN) //Would block, try again later.          // handle network errors ...
777            if (result == 0) { //socket was selected, so 0 here means client has closed the connection
778                    CloseConnection(iter);
779                    return false;
780            }
781            #if defined(WIN32)
782            if (result == SOCKET_ERROR) {
783                    int wsa_lasterror = WSAGetLastError();
784                    if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.
785                            return false;
786                    dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));
787                    CloseConnection(iter);
788                    return false;
789            }
790            #else
791            if (result == -1) {
792                    if (errno == EAGAIN) //Would block, try again later.
793                            return false;
794                    switch(errno) {
795                            case EBADF:
796                                    dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
797                                    return false;
798                            case ECONNREFUSED:
799                                    dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
800                                    return false;
801                            case ENOTCONN:
802                                    dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
803                                    return false;
804                            case ENOTSOCK:
805                                    dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
806                                    return false;
807                            case EAGAIN:
808                                    dmsg(2,("LSCPScanner: The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.\n"));
809                                    return false;
810                            case EINTR:
811                                    dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
812                                    return false;
813                            case EFAULT:
814                                    dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
815                                    return false;
816                            case EINVAL:
817                                    dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
818                                    return false;
819                            case ENOMEM:
820                                    dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
821                                    return false;
822                            default:
823                                    dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
824                                  return false;                                  return false;
                         switch(errno) {  
                                 case EBADF:  
                                         dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));  
                                         break;  
                                 case ECONNREFUSED:  
                                         dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));  
                                         break;  
                                 case ENOTCONN:  
                                         dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));  
                                         break;  
                                 case ENOTSOCK:  
                                         dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));  
                                         break;  
                                 case EAGAIN:  
                                         dmsg(2,("LSCPScanner: The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.\n"));  
                                         break;  
                                 case EINTR:  
                                         dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));  
                                         break;  
                                 case EFAULT:  
                                         dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));  
                                         break;  
                                 case EINVAL:  
                                         dmsg(2,("LSCPScanner: Invalid argument passed.\n"));  
                                         break;  
                                 case ENOMEM:  
                                         dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));  
                                         break;  
                                 default:  
                                         dmsg(2,("LSCPScanner: Unknown recv() error.\n"));  
                                         break;  
                         }  
                         CloseConnection(iter);  
                         break;  
825                  }                  }
826                  #endif                  CloseConnection(iter);
827                    return false;
828          }          }
829            #endif
830    
831          return false;          return false;
832  }  }
833    

Legend:
Removed from v.2516  
changed lines
  Added in v.2528

  ViewVC Help
Powered by ViewVC