/[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 2515 by schoenebeck, Wed Feb 5 20:45:18 2014 UTC revision 2531 by schoenebeck, Wed Mar 5 00:02:21 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) {                          if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
750                                  String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter));                                  String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), false);
751                                  if (!s.empty()) 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                    } else if (c == 2) { // custom ASCII code usage for moving cursor left (LSCP shell)
758                            if (iter->iCursorOffset + bufferedCommands[socket].size() > 0)
759                                    iter->iCursorOffset--;
760                    } else if (c == 3) { // custom ASCII code usage for moving cursor right (LSCP shell)
761                            if (iter->iCursorOffset < 0) iter->iCursorOffset++;
762                    } else {
763                            size_t cursorPos = bufferedCommands[socket].size() + iter->iCursorOffset;
764                            // backspace character - should only happen with shell
765                            if (c == '\b') {
766                                    if (!bufferedCommands[socket].empty() && cursorPos > 0)
767                                            bufferedCommands[socket].erase(cursorPos - 1, 1);
768                            } else { // append (or insert) new character (at current cursor position) ...
769                                    if (cursorPos >= 0)
770                                            bufferedCommands[socket].insert(cursorPos, String(1,c)); // insert
771                                    else
772                                            bufferedCommands[socket] += c; // append
773                          }                          }
774                  }                  }
775                  #if defined(WIN32)                  // only if the other side is the LSCP shell application:
776                  if (result == SOCKET_ERROR) {                  // check the current (incomplete) command line for syntax errors,
777                      int wsa_lasterror = WSAGetLastError();                  // possible completions and report everything back to the shell
778                          if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.                  if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
779                                  return false;                          String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), true);
780                          dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));                          if (!s.empty() && (*iter).bShellInteract && i == input.size() - 1)
781                          CloseConnection(iter);                                  AnswerClient(s + "\n");
                         break;  
782                  }                  }
783                  #else          }
784                  if (result == -1) {  
785                          if (errno == EAGAIN) //Would block, try again later.          // handle network errors ...
786            if (result == 0) { //socket was selected, so 0 here means client has closed the connection
787                    CloseConnection(iter);
788                    return false;
789            }
790            #if defined(WIN32)
791            if (result == SOCKET_ERROR) {
792                    int wsa_lasterror = WSAGetLastError();
793                    if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.
794                            return false;
795                    dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));
796                    CloseConnection(iter);
797                    return false;
798            }
799            #else
800            if (result == -1) {
801                    if (errno == EAGAIN) //Would block, try again later.
802                            return false;
803                    switch(errno) {
804                            case EBADF:
805                                    dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
806                                    return false;
807                            case ECONNREFUSED:
808                                    dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
809                                    return false;
810                            case ENOTCONN:
811                                    dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
812                                    return false;
813                            case ENOTSOCK:
814                                    dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
815                                    return false;
816                            case EAGAIN:
817                                    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"));
818                                    return false;
819                            case EINTR:
820                                    dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
821                                    return false;
822                            case EFAULT:
823                                    dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
824                                    return false;
825                            case EINVAL:
826                                    dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
827                                    return false;
828                            case ENOMEM:
829                                    dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
830                                    return false;
831                            default:
832                                    dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
833                                  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;  
834                  }                  }
835                  #endif                  CloseConnection(iter);
836                    return false;
837          }          }
838            #endif
839    
840          return false;          return false;
841  }  }
842    
# Line 4006  String LSCPServer::SetShellInteract(yypa Line 4035  String LSCPServer::SetShellInteract(yypa
4035          else throw Exception("Not a boolean value, must either be 0 or 1");          else throw Exception("Not a boolean value, must either be 0 or 1");
4036      } catch (Exception e) {      } catch (Exception e) {
4037          result.Error(e);          result.Error(e);
4038        }
4039        return result.Produce();
4040    }
4041    
4042    String LSCPServer::SetShellAutoCorrect(yyparse_param_t* pSession, double boolean_value) {
4043        dmsg(2,("LSCPServer: SetShellAutoCorrect(val=%f)\n", boolean_value));
4044        LSCPResultSet result;
4045        try {
4046            if      (boolean_value == 0) pSession->bShellAutoCorrect = false;
4047            else if (boolean_value == 1) pSession->bShellAutoCorrect = true;
4048            else throw Exception("Not a boolean value, must either be 0 or 1");
4049        } catch (Exception e) {
4050            result.Error(e);
4051      }      }
4052      return result.Produce();      return result.Produce();
4053  }  }

Legend:
Removed from v.2515  
changed lines
  Added in v.2531

  ViewVC Help
Powered by ViewVC