Exemple #1
0
static char cmdIf( tPSStackItem **topStack, void* /*dummy*/, const char* path )
{
	char error = FALSE;
	char aa = popBool( topStack, &error );
	tPSCommand *cmdFalse = popCommand( topStack, &error );
	tPSCommand *cmdTrue = popCommand( topStack, &error );

	if( error )
		return FALSE;

	if( aa )
		return execCommands( topStack, cmdTrue, path );
	else
		return execCommands( topStack, cmdFalse, path );
}
AREXPORT void ArServerClient::handleRequests(void)
{
  if (myState != STATE_CONNECTED)
    return;  

  std::list<ArServerClientData *>::iterator it;
  ArServerClientData *data;  
  ArServerData *serverData;
  ArTime lastSent;

  // walk through our list
  for (it = myRequested.begin(); it != myRequested.end(); ++it)
  {
    data = (*it);
    lastSent = data->getLastSent();
    // see if this needs to be called
    if (data->getMSec() != -1 && 
	(data->getMSec() == 0 || lastSent.mSecSince() > data->getMSec()))
    {
      serverData = data->getServerData();
      // call it, then set it so we know we did
      pushCommand(serverData->getCommand());
      pushForceTcpFlag(false);
      if (serverData->getFunctor() != NULL)
	serverData->getFunctor()->invoke(this, data->getPacket());
      popCommand();
      popForceTcpFlag();
      data->setLastSentToNow();
    }
  }
}
void readDatalink(void){

    struct command* cmd = popCommand();
    if ( cmd ) {
        if (lastCommandSentCode == cmd->cmd){
            lastCommandSentCode++;
        }
        else{
            lastCommandSentCode = cmd->cmd * 100;
        }
        switch (cmd->cmd) {
            case DEBUG_TEST:             // Debugging command, writes to debug UART
                debug((char*) cmd->data);
                break;
            //TODO: Add commands here
            default:
                break;
        }
        destroyCommand( cmd );
    }

}
//--------------------------------------------------------------
void ofxThreadedVideo::threadedFunction(){

    while (isThreadRunning()){

        lock();
        ofxThreadedVideoGlobalMutex.lock();
        if(!ofxThreadedVideoGlobalCritical && !bCriticalSection){
            ofxThreadedVideoGlobalCritical = true;
            bCriticalSection = true;
            int videoID = currentVideoID;
            ofxThreadedVideoCommand c = getCommand();
            bool bCanLoad = !bLoaded;
            bool bPopCommand = false;
            unlock();
            ofxThreadedVideoGlobalMutex.unlock();
            
            if(c.getInstance() == instanceID){
                
                if(c.getCommand() == "play"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    video[videoID].play();
                    
                    lock();
                    bIsPlaying = true;
                    bIsPaused = false;
                    unlock();
                    
                    bPopCommand = true;
                }
                
                if(c.getCommand() == "setPosition"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    lock();
                    position = c.getArgument<float>(0);
                    unlock();
                    video[videoID].setPosition(position);
                    bPopCommand = true;
                }

                if(c.getCommand() == "setVolume"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    lock();
                    volume = c.getArgument<float>(0);
                    unlock();
                    video[videoID].setVolume(volume);
                    bPopCommand = true;
                }
                
#ifdef USE_QUICKTIME_7
                if(c.getCommand() == "setPan"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    lock();
                    pan = c.getArgument<float>(0);
                    unlock();
                    video[videoID].setPan(pan);
                    bPopCommand = true;
                }
#endif
                
                if(c.getCommand() == "setLoopState"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    lock();
                    loopState = (ofLoopType)c.getArgument<int>(0);
                    unlock();
                    video[videoID].setLoopState(loopState);
                    bPopCommand = true;
                }
                
//                if(c.getCommand() == "setSpeed"){
//                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
//                    lock();
//                    speed = c.getArgument<float>(0);
//                    unlock();
//                    video[videoID].setSpeed(speed);
//                    bPopCommand = true;
//                }
                
//                if(c.getCommand() == "setFrame"){
//                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
//                    int frameTarget = c.getArgument<int>(0);
//                    CLAMP(frameTarget, 0, frameTotal);
//                    video[videoID].setFrame(frameTarget);
//                    bForceFrameNew = true;
//                    bPopCommand = true;
//                }
                
//                if(c.getCommand() == "setFrame"){
//                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
//                    lock();
//                    int frameTarget = c.getArgument<int>(0);
//                    bForceFrameNew = true;
//                    frameTarget = CLAMP(frameTarget, 0, frameTotal);
//                    cout << "setframe A: " << frameTarget << " " << videoID << " " << bCriticalSection << endl;
//                    video[videoID].setFrame(frameTarget);
//                    cout << "setframe B: " << frameTarget << " " << videoID << " " << bCriticalSection << endl;
//                    unlock();
//                    bPopCommand = true;
//                }
                
                if(c.getCommand() == "setPaused"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    lock();
                    bIsPaused = c.getArgument<bool>(0);
                    unlock();
                    video[videoID].setPaused(bIsPaused);
                    bPopCommand = true;
                }
                
                if(c.getCommand() == "setAnchorPercent"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    video[videoID].setAnchorPercent(c.getArgument<float>(0), c.getArgument<float>(0));
                    bPopCommand = true;
                }

                if(c.getCommand() == "setAnchorPoint"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    video[videoID].setAnchorPercent(c.getArgument<float>(0), c.getArgument<float>(0));
                    bPopCommand = true;
                }
                
                if(c.getCommand() == "resetAnchor"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    video[videoID].resetAnchor();
                    bPopCommand = true;
                }
                
                if(c.getCommand() == "setFade"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    
                    int frameEnd;
                    int frameStart = c.getArgument<int>(0);
                    int durationMillis = c.getArgument<int>(1);
                    float fadeTarget = c.getArgument<float>(2);
                    bool fadeSound = c.getArgument<bool>(3);
                    bool fadeVideo = c.getArgument<bool>(4);
                    bool fadeOnce = c.getArgument<bool>(5);
                    
                    CLAMP(fadeTarget, 0.0f, 1.0f);
                    
                    if(frameStart == -1){ // fade is durationMillis from the end
                        frameEnd = frameTotal;
                        frameStart = frameTotal - ((float)durationMillis / 1000.0) * 25.0;
                    }else{
                        frameEnd = frameStart + ((float)durationMillis / 1000.0) * 25.0;
                    }
                    
                    if(frameStart == frameEnd){
                        _fade = fadeTarget;
                        if(fadeVideo) fade = _fade;
                        lock();
                        if(fadeSound) video[videoID].setVolume(_fade);
                        unlock();
                    }else{
                        frameEnd -= 1;
                        
                        // assert(frameStart >= 0);
                        // assert(frameEnd >= frameStart);
                        // assert(frameEnd <= frameTotal);
                        
                        fades.push_back(ofxThreadedVideoFade(frameStart, frameEnd, fadeTarget, fadeSound, fadeVideo, fadeOnce));
                    }
                    

                    
                    bPopCommand = true;
                }
                
#ifdef USE_JACK_AUDIO
                if(c.getCommand() == "setAudioTrackToChannel"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    video[videoID].setAudioTrackToChannel(c.getArgument<int>(0), c.getArgument<int>(1), c.getArgument<int>(2));
                    bPopCommand = true;
                }
                
                if(c.getCommand() == "setAudioDevice"){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    video[videoID].setAudioDevice(c.getArgument<string>(0));
                    bPopCommand = true;
                }
#endif
                
                if(c.getCommand() == "loadMovie" && bCanLoad){
                    if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                    
                    if(video[videoID].loadMovie(c.getArgument<string>(0))){
                        
                        if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString() << " executed in thread";;

//                        lock();
                        
                        fades.clear();
                        width = video[videoID].getWidth();
                        height = video[videoID].getHeight();
                        speed = video[videoID].getSpeed();
                        duration = video[videoID].getDuration();
                        position = video[videoID].getPosition();
                        frameCurrent = video[videoID].getCurrentFrame();
                        frameTotal = video[videoID].getTotalNumFrames();
#ifdef USE_QUICKTIME_7
                        volume = video[videoID].getVolume(); // we should implement for QT6
                        pan = video[videoID].getPan();
#endif
                        loopState = video[videoID].getLoopState();
                        
                        moviePath = c.getArgument<string>(0);
#ifdef TARGET_OSX
                        vector<string> pathParts = ofSplitString(moviePath, "/");
#else
                        vector<string> pathParts = ofSplitString(moviePath, "\\");
#endif
                        movieName = pathParts[pathParts.size() - 1];
                        
                        bIsPaused = true;
                        bIsPlaying = false;
                        bIsTextureReady = false;
                        bIsLoading = false;
                        bIsMovieDone = false;
                        bLoaded = true;
                        
                        pixels = &video[videoID].getPixelsRef();

                        unlock();
                        
                        bPopCommand = true;
                        
                        ofxThreadedVideoEvent e = ofxThreadedVideoEvent(moviePath, VIDEO_EVENT_LOAD_OK, this);
                        ofNotifyEvent(threadedVideoEvent, e, this);
                        
                        ofxThreadedVideoLoadOk++;
                        
                    }else{
                        
                        ofLogError() << "Could not load: " << instanceID << " + " << c.getCommandAsString();
                        
                        ofxThreadedVideoEvent e = ofxThreadedVideoEvent(moviePath, VIDEO_EVENT_LOAD_FAIL, this);
                        ofNotifyEvent(threadedVideoEvent, e, this);
                        
                        ofxThreadedVideoLoadFail++;
                    }
                    
                }
                
            }
            
            if(bPopCommand){
                video[videoID].update();
            }
        
            lock();
            
            if(bIsFrameNew){
                for(unsigned int i = 0; i < fades.size(); i++){
                    
                    ofxThreadedVideoFade& currentFade = fades.at(i);
                    
                    if(currentFade.getIsFading(frameCurrent)){
                        _fade = currentFade.getFade(_fade, frameCurrent);
                        
                        if(currentFade.fadeVideo){
                            if(fade != _fade) fade = _fade;
                        }
#ifdef USE_QUICKTIME_7
                        if(currentFade.fadeSound){ // we should implement for QT6
                            if(video[videoID].getVolume() != _fade) video[videoID].setVolume(_fade);
                        }
#endif
                    }
                    
                    if(currentFade.fadeOnce && currentFade.getFadeDone(frameCurrent)){
                        fades.erase(fades.begin() + i);
                        i--;
                    }

                }
            }
            
            ofxThreadedVideoGlobalMutex.lock();
            
            if(bPopCommand) popCommand();
            
            ofxThreadedVideoGlobalCritical = false;
            bCriticalSection = false;
            ofxThreadedVideoGlobalMutex.unlock();
            unlock();
        }else{
            ofxThreadedVideoGlobalMutex.unlock();
            unlock();
        }
        
        ofSleepMillis(1);

    }
        
}
//--------------------------------------------------------------
void ofxThreadedVideo::update(){
    
    lock();
    
    if(!bCriticalSection && bLoaded){
        bCriticalSection = true;
        int videoID = currentVideoID;
        bool bUpdate = bLoaded;
        unlock();
        
        if(bUpdate){
            
//            lock();
            video[videoID].update();
            
            bIsFrameNew = video[videoID].isFrameNew();
            position = video[videoID].getPosition();
            frameCurrent = video[videoID].getCurrentFrame();
            bIsMovieDone = video[videoID].getIsMovieDone();
//            unlock();
            
            if(bIsFrameNew || bForceFrameNew){
                
                if(bForceFrameNew) lock();
                
                if(!bIsTextureReady) bIsTextureReady = true;
                
                if(drawTexture.getWidth() != width || drawTexture.getHeight() != height){
                    drawTexture.allocate(width, height, ofGetGLTypeFromPixelFormat(video[videoID].getPixelFormat()));
                }
                
                unsigned char * pixels = video[videoID].getPixels();
                if(pixels != NULL && bUseTexture) drawTexture.loadData(pixels, width, height, ofGetGLTypeFromPixelFormat(video[videoID].getPixelFormat()));
                
                if(bForceFrameNew){
                    bForceFrameNew = false;
                    unlock();
                }
                
                // calculate frameRate -> taken from ofAppRunner
                prevMillis = ofGetElapsedTimeMillis();
                timeNow = ofGetElapsedTimef();
                double diff = timeNow-timeThen;
                if( diff  > 0.00001 ){
                    fps			= 1.0 / diff;
                    frameRate	*= 0.9f;
                    frameRate	+= 0.1f*fps;
                }
                lastFrameTime	= diff;
                timeThen		= timeNow;
                
            }
        }
        
        lock();
        bCriticalSection = false;
        unlock();
    }else{
        unlock();
    }
    
    lock();
    ofxThreadedVideoGlobalMutex.lock();
    if(!ofxThreadedVideoGlobalCritical && !bCriticalSection){
        int videoID = currentVideoID;
        ofxThreadedVideoGlobalCritical = true;
        bCriticalSection = true;
        ofxThreadedVideoCommand c = getCommand();
        bool bCanStop = (bLoaded && !bIsLoading) || (!bLoaded && !bIsLoading);
        bool bPopCommand = false;
        unlock();
        ofxThreadedVideoGlobalMutex.unlock();

        if(c.getInstance() == instanceID){
            
            if(c.getCommand() == "stop" && bCanStop){
                if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                if(bIsPlaying) video[videoID].stop();
                lock();
                //fade = 1.0;
                fades.clear();
                bIsPlaying = false;
                bIsPaused = false; // ????
                bIsLoading = false;
                bIsFrameNew = false;
                bIsMovieDone = false;
                bLoaded = false;
                unlock();
                bPopCommand = true;
            }
            
            if(c.getCommand() == "loadMovie" && bCanStop){
                if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString() << " execute in update";
                if(bIsPlaying) video[videoID].stop();
                lock();
                currentVideoID = getNextLoadID();
                bIsPaused = false;
                bLoaded = false;
                bIsLoading = true;
                bIsPlaying = false;
                bIsMovieDone = false;
                unlock();
            }
            
            if(c.getCommand() == "setSpeed"){
                if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                lock();
                speed = c.getArgument<float>(0);
                unlock();
                video[videoID].setSpeed(speed);
                bPopCommand = true;
            }
            
            if(c.getCommand() == "setFrame"){
                if(bVerbose) ofLogVerbose() << instanceID << " = " << c.getCommandAsString();
                lock();
                int frameTarget = c.getArgument<int>(0);
                bForceFrameNew = true;
                frameTarget = CLAMP(frameTarget, 0, frameTotal);
                //cout << "setframe A: " << frameTarget << " " << videoID << " " << bCriticalSection << endl;
                video[videoID].setFrame(frameTarget);
                //cout << "setframe B: " << frameTarget << " " << videoID << " " << bCriticalSection << endl;
                unlock();
                bPopCommand = true;
            }
            
        }
        
        lock();
        ofxThreadedVideoGlobalMutex.lock();
        
        if(bPopCommand) popCommand();
        
        ofxThreadedVideoGlobalCritical = false;
        bCriticalSection = false;
        ofxThreadedVideoGlobalMutex.unlock();
        unlock();
    }else{
        ofxThreadedVideoGlobalMutex.unlock();
        unlock();
    }
}
AREXPORT void ArServerClient::processPacket(ArNetPacket *packet, bool tcp)
{
  std::string str;
  struct sockaddr_in sin;
  unsigned int clientUdpPort;
  ArNetPacket retPacket;

  //printf("Command number %d\n", packet->getCommand());
  // if we're in intro mode and received back the intro
  if (myState == STATE_SENT_INTRO && 
      packet->getCommand() == ArClientCommands::INTRODUCTION)
  {
    char user[512];
    unsigned char password[16];
    clientUdpPort = packet->bufToUByte2();
    packet->bufToStr(user, sizeof(user));
    packet->bufToData((char *)password, 16);

    if (myRejecting != 0)
    {
      retPacket.empty();
      retPacket.setCommand(ArServerCommands::REJECTED);
      retPacket.byte2ToBuf(myRejecting);
      retPacket.strToBuf(myRejectingString.c_str());
      sendPacketTcp(&retPacket);
      if (myRejecting == 2)
	ArLog::log(ArLog::Normal, 
   "%sRejected connection from %s since we're using a central server at %s",
		   myLogPrefix.c_str(), getIPString(), 
		   myRejectingString.c_str());
      internalSwitchState(STATE_REJECTED);
      return;
    }

    // if user info is NULL we're not checking passwords
    if (myUserInfo != NULL && 
	!myUserInfo->matchUserPassword(user, password, myPasswordKey.c_str(),
				       myServerKey.c_str(),
				       myLogPasswordFailureVerbosely))
    {
      retPacket.empty();
      retPacket.setCommand(ArServerCommands::REJECTED);
      retPacket.byte2ToBuf(1);
      retPacket.strToBuf("");
      sendPacketTcp(&retPacket);
      ArLog::log(ArLog::Normal, "%sRejected user '%s' or password from %s",
		 myLogPrefix.c_str(), user, getIPString());
      internalSwitchState(STATE_REJECTED);
      return;
    }
    if (myUserInfo != NULL)
      myGroups = myUserInfo->getUsersGroups(user);
    else
      myGroups.clear();
    sin.sin_family = AF_INET;
    sin.sin_addr = *myTcpSocket.inAddr();
    sin.sin_port = ArSocket::hostToNetOrder(clientUdpPort);
    if (myUserInfo != NULL)
      ArLog::log(ArLog::Normal, 
		 "%sClient connected from %s with user %s", 
		 myLogPrefix.c_str(), getIPString(), user);
    else
      ArLog::log(ArLog::Normal, 
		 "%sClient connected from %s", myLogPrefix.c_str(), 
		 getIPString());

    setUdpAddress(&sin);
    // send that we've connected
    retPacket.empty();
    retPacket.setCommand(ArServerCommands::CONNECTED);
    sendPacketTcp(&retPacket);
    // note that we're connected
    internalSwitchState(STATE_CONNECTED);

    // send them the list
    sendListPacket();
    // send the udp introduction if we're using udp
    if (!myTcpOnly)
    {
      retPacket.empty();
      retPacket.setCommand(ArServerCommands::UDP_INTRODUCTION);
      retPacket.byte4ToBuf(myIntroKey);
      sendPacketUdp(&retPacket);
    }
  }
  // if we aren't in intro mode and got an intro somethings wrong
  else if (packet->getCommand() == ArClientCommands::INTRODUCTION)
  {
    ArLog::log(ArLog::Terse, 
	       "%sReceived introduction when not in intro mode",
	       myLogPrefix.c_str());
    return;
  }
  // if we got this over tcp then they only want tcp
  else if (packet->getCommand() == ArClientCommands::UDP_INTRODUCTION)
  {
    if (!myTcpOnly)
    {
      ArLog::log(ArLog::Normal, "%sGot UDP introduction over tcp, assuming client only wants tcp data.", myLogPrefix.c_str());
      myTcpOnly = true;
    }
    return;
  }
  // if we're connected and got a udp confirmation
  else if ((myState == STATE_CONNECTED || 
	    myState == STATE_SENT_INTRO) && 
	   packet->getCommand() == ArClientCommands::UDP_CONFIRMATION)
  {
    myUdpConfirmedTo = true;
    ArLog::log(myVerboseLogLevel, 
	       "%s: udp connection to client confirmed.", myLogPrefix.c_str());
    return;
  }
  // if we're not connected (or close) and got a confirmation
  else if (packet->getCommand() == ArClientCommands::UDP_CONFIRMATION)
  {
    ArLog::log(ArLog::Normal, 
	       "%sReceived udp confirmation when not connected.",
	       myLogPrefix.c_str());
    return;
  }
  else if (packet->getCommand() == ArClientCommands::TCP_ONLY)
  {
    ArLog::log(myVerboseLogLevel, "%sClient only wants tcp data.", myLogPrefix.c_str());
    myTcpOnly = true;
    return;
  }
  else if (packet->getCommand() == ArClientCommands::SHUTDOWN)
  {
    ArLog::log(ArLog::Normal, "%sClient from %s has disconnected.",
	       myLogPrefix.c_str(), getIPString());
    internalSwitchState(STATE_DISCONNECTED);
    return;
  }
  // if we're connected its a request, then set all that up
  else if (myState == STATE_CONNECTED && 
	   packet->getCommand() == ArClientCommands::REQUEST)
  {
    std::list<ArServerClientData *>::iterator it;
    ArServerClientData *data;
    ArServerData *serverData;
    unsigned int command;
    long mSec;
    // see which one they requested
    command = packet->bufToUByte2();
    mSec = packet->bufToByte4();

    // first we see if we already have this one
    for (it = myRequested.begin(); it != myRequested.end(); ++it)
    {
      data = (*it);
      serverData = data->getServerData();
      if (serverData->getCommand() == command)
      {
	trackPacketReceived(packet, command);
	data->setMSec(mSec);
	data->setPacket(packet);
	data->getPacket()->setCommand(command);
	serverData->callRequestChangedFunctor();
	ArLog::log(myVerboseLogLevel, 
	   "%sRevised request for command %s to %d mSec with new argument", 
		   myLogPrefix.c_str(), 
		   findCommandName(serverData->getCommand()), mSec);
	return;
      }
    }
    // we didn't have it, so make a new one
    std::map<unsigned int, ArServerData *>::iterator sdit;
    if ((sdit = myDataMap->find(command)) == myDataMap->end())
    {
      ArLog::log(ArLog::Terse, 
  	      "%sGot request for command %d which doesn't exist", 
		 myLogPrefix.c_str(), command);
      return;
    }
    serverData = (*sdit).second;
    if (serverData == NULL) 
    {
      ArLog::log(ArLog::Terse, 
		 "%sprocessPackets request handler has NULL serverData", 
		 myLogPrefix.c_str());
    }
    if (myUserInfo != NULL && 
	serverData->getCommandGroup() != NULL &&
	serverData->getCommandGroup()[0] != '\0' &&
	myGroups.count(serverData->getCommandGroup()) == 0 &&
	myGroups.count("all") == 0)
    {
      ArLog::log(ArLog::Normal, 
		 "%s%s tried to request command '%s' but it doesn't have access to that command", 
		 myLogPrefix.c_str(), getIPString(), 
		 serverData->getName());
      return;
    }
    trackPacketReceived(packet, command);
    data = new ArServerClientData(serverData, mSec, packet);
    data->getPacket()->setCommand(command);
    ArLog::log(myVerboseLogLevel, 
	       "%sadded request for command %s every %d mSec", 
	       myLogPrefix.c_str(), serverData->getName(), mSec);
    if (mSec == 0)
      ArLog::log(ArLog::Normal, "%sClient from %s requested command %s every at 0 msec", myLogPrefix.c_str(), 
		 getIPString(), serverData->getName());
    myRequested.push_front(data);
    serverData->callRequestChangedFunctor();
    pushCommand(command);
    pushForceTcpFlag(false);
    if (serverData->getFunctor() != NULL)
      serverData->getFunctor()->invoke(this, data->getPacket());
    popCommand();
    popForceTcpFlag();
    return;
  }
  // if we got a request when we're not connected
  else if (packet->getCommand() == ArClientCommands::REQUEST)
  {
    ArLog::log(ArLog::Normal, 
	       "Got a request while not connected.",
	       myLogPrefix.c_str());
    return;
  }
  // if we're connected its a requestStop, then set all that up
  else if (myState == STATE_CONNECTED && 
	   packet->getCommand() == ArClientCommands::REQUESTSTOP)
  {
    std::list<ArServerClientData *>::iterator it;
    ArServerClientData *data;
    ArServerData *serverData;
    unsigned int command;
    // see which one they requested
    command = packet->bufToUByte2();

    // first we see if we have this one
    for (it = myRequested.begin(); it != myRequested.end(); ++it)
    {
      data = (*it);
      serverData = data->getServerData();
      // we have a match, so set the new params then return
      if (data->getServerData()->getCommand() == command)
      {
	trackPacketReceived(packet, command);
	myRequested.erase(it);
	ArLog::log(myVerboseLogLevel, "%sStopped request for command %s", 
		   myLogPrefix.c_str(), 
		   findCommandName(serverData->getCommand()));
	delete data;
	serverData->callRequestChangedFunctor();
	return;
      }
    }
    // if we don't have it... that means that it wasn't here
    
    // find out what to call it
    std::map<unsigned int, ArServerData *>::iterator sdit;
    if ((sdit = myDataMap->find(command)) == myDataMap->end())
    {
      ArLog::log(ArLog::Terse, 
		 "%sGot a requeststop for command %d which doesn't exist", 
		 myLogPrefix.c_str(), command);
      return;
    }
    trackPacketReceived(packet, command);
    serverData = (*sdit).second;
    if (serverData == NULL) 
      ArLog::log(ArLog::Terse, 
		 "%srequeststop handler has NULL serverData on back command %d", 
		 myLogPrefix.c_str(), command);
    else
      ArLog::log(ArLog::Normal, "%s: Got a stop request for command %s that isn't requested", myLogPrefix.c_str(), serverData->getName());
    return;
  }
  // if we got a requestStop when we're not connected
  else if (packet->getCommand() == ArClientCommands::REQUESTSTOP)
  {
    ArLog::log(ArLog::Normal, 
	       "%sGot a requeststop while not connected.", 
	       myLogPrefix.c_str());
    return;
  }
  // if we're connected and its a command to execute just once
  else if (myState == STATE_CONNECTED)
  {
    unsigned int command;
    std::map<unsigned int, ArServerData *>::iterator it;
    ArServerData *serverData;

    command = packet->getCommand();
    if ((it = myDataMap->find(command)) == myDataMap->end())
    {
      ArLog::log(ArLog::Terse, 
  	      "%sArServerClient got request for command %d which doesn't exist", 
		 myLogPrefix.c_str(), command);
      return;
    }
    serverData = (*it).second;
    if (myUserInfo != NULL && 
	serverData->getCommandGroup() != NULL &&
	serverData->getCommandGroup()[0] != '\0' &&
	myGroups.count(serverData->getCommandGroup()) == 0 &&
	myGroups.count("all") == 0)
    {
      ArLog::log(ArLog::Normal, 
		 "%s%s tried to request command '%s' once but it doesn't have access to that command", myLogPrefix.c_str(),
		 getIPString(), 
		 serverData->getName());
      return;
    }
    trackPacketReceived(packet, command);

    // copy it out and return if its an idle packet
    if (myAllowIdlePackets && serverData->isIdlePacket())
    {
      myHaveIdlePackets = true;
      if (command <= 255)
	ArLog::log(myVerboseLogLevel, "%sStoring idle command %d", 
		   myLogPrefix.c_str(), command);
      else
	ArLog::log(myVerboseLogLevel, "%sStoring idle command %s", 
		   myLogPrefix.c_str(), serverData->getName());
      myIdlePacketsMutex.lock();
      ArNetPacket *idlePacket = new ArNetPacket(packet->getLength() + 5);
      idlePacket->duplicatePacket(packet);
      myIdlePackets.push_back(idlePacket);
      myIdlePacketsMutex.unlock();
      return;
    }
    // If its a slow or an idle packet (and we're not allowing the
    // idle behavior) and we allow slow packets then copy it
    else if (myAllowSlowPackets && (serverData->isSlowPacket() || 
				    serverData->isIdlePacket()))
    {
      myHaveSlowPackets = true;
      if (command <= 255)
	ArLog::log(myVerboseLogLevel, "%sStoring slow command %d", 
		   myLogPrefix.c_str(), command);
      else
	ArLog::log(myVerboseLogLevel, "%sStoring slow command %s", 
		   myLogPrefix.c_str(), serverData->getName());
      mySlowPacketsMutex.lock();
      ArNetPacket *slowPacket = new ArNetPacket(packet->getLength() + 5);
      slowPacket->duplicatePacket(packet);
      mySlowPackets.push_back(slowPacket);
      mySlowPacketsMutex.unlock();
      return;
    }


    if (command <= 255)
      ArLog::log(myVerboseLogLevel, "%sGot command %s", 
		 myLogPrefix.c_str(), serverData->getName());
    else
      ArLog::log(ArLog::Verbose, "%sGot command %s", 
		 myLogPrefix.c_str(), serverData->getName());
    pushCommand(command);
    pushForceTcpFlag(tcp);
    if (serverData->getFunctor() != NULL)
      serverData->getFunctor()->invoke(this, packet);
    if (serverData->getRequestOnceFunctor() != NULL)
      serverData->getRequestOnceFunctor()->invoke(this, packet);
    popCommand();
    popForceTcpFlag();
    return;
  }
  else
  {
    ArLog::log(ArLog::Terse, 
	       "%sRogue packet command %s in state %d", myLogPrefix.c_str(),
	       findCommandName(packet->getCommand()), myState);
  }
}
Exemple #7
0
command_stream* evaluatePostfix(token* finalTokenStream)
{
	/*
	notes on structures and types declared above
	typedef enum
	{
		WORD_TOKEN, //ls foo
		SEMICOLON_TOKEN, // ;
		PIPE_TOKEN, // |
		AND_TOKEN, // &&
		OR_TOKEN, // ||
		LEFT_PAREN_TOKEN, // ( //not relevant at this point
		RIGHT_PAREN_TOKEN, // )//not relevant at this point
		GREATER_TOKEN, // >
		LESS_TOKEN, // <
		NEWLINE_TOKEN, // \n //not relevant at this point
		NULL_TOKEN, // //not relevant at this point
	} tokentype;
	
	enum command_type
	{
		AND_COMMAND,         // A && B
		SEQUENCE_COMMAND,    // A ; B
		OR_COMMAND,          // A || B
		PIPE_COMMAND,        // A | B
		SIMPLE_COMMAND,      // a simple command
		SUBSHELL_COMMAND,    // ( A )
	};
	  
	typedef struct command_stream
	{
		struct command_stream* next;
		struct command_stream* prev;
		struct command* root;
		
	} command_stream;
	
	struct command
	{
		command* prev;
		command* next; //for linked list before tree conversion
		enum command_type type;
		// Exit status, or -1 if not known (e.g., because it has not exited yet).
		int status;
		// I/O redirections, or 0 if none.
		char *input;
		char *output;
		union
		{
			// for AND_COMMAND, SEQUENCE_COMMAND, OR_COMMAND, PIPE_COMMAND:
			struct command *command[2];
			// for SIMPLE_COMMAND:
			char **word;
			// for SUBSHELL_COMMAND:
			struct command *subshell_command;
		} u;
	};
	*/
	command* cmd_start = NULL;
	command* cmd_end = NULL;
	
	command_stream* str_start = NULL;
	command_stream* str_end = NULL;
	
	command_stream* firststream = malloc(sizeof(command_stream));
	addStream(&str_start, &str_end, firststream);
	
	token* curr;
	for (curr = finalTokenStream; curr != NULL; curr = curr->next)
		if (curr->t == WORD_TOKEN) //add simple command to command stack
		{
			command* newcommand = malloc(sizeof(command));
			newcommand->type = SIMPLE_COMMAND;
			newcommand->status = -1;
			newcommand->input = newcommand->output = 0;
			newcommand->u.word = curr->words;
			if (curr->prev && curr->prev->sub > 1 && curr->sub == 1) //if we just ended a subshell, then make what was there a subshell command on itself
			{
				command* prevcmd = malloc(sizeof(command));
				prevcmd->type = SUBSHELL_COMMAND;
				prevcmd->input = prevcmd->output = 0;
				prevcmd->status = -1;
				prevcmd->u.subshell_command = popCommand(&cmd_start, &cmd_end);
				addCommand(&cmd_start, &cmd_end, prevcmd);
			}
			
			addCommand(&cmd_start, &cmd_end, newcommand);
		}
		else if (curr->t == SEMICOLON_TOKEN && curr->sub == 1) //stop working on the current stream and instead make a new stream if no subshell, otherwise make a sequence command
		{
			if (curr->prev && curr->prev->sub > 1) //if we just ended a subshell, then make cmd_start a subshell command on itself
			{
				command* newcommand = malloc(sizeof(command));
				newcommand->type = SUBSHELL_COMMAND;
				newcommand->input = newcommand->output = 0;
				newcommand->status = -1;
				newcommand->u.subshell_command = cmd_start;
				cmd_start = newcommand;
			}
			str_end->root=cmd_start;
			cmd_start = cmd_end = NULL;
			command_stream* newstream = malloc(sizeof(command_stream));
			addStream(&str_start, &str_end, newstream);
		}
		else if (curr->t == LESS_TOKEN || curr->t == GREATER_TOKEN) //change the input based on what command you are redirecting
		{
			//remove two last commands and make them a subtree with correct depth level and add subtree back to command list
			command* dest = popCommand(&cmd_start, &cmd_end); //where to redirect
			command* operation = popCommand(&cmd_start, &cmd_end); //what to do, assume always simple command
			
			command* newcommand = malloc(sizeof(command));
			newcommand->type = SIMPLE_COMMAND;
			newcommand->status = -1;
			if (curr->t == LESS_TOKEN)
			{
				newcommand->input = concat(dest->u.word[0], dest->u.word[1]);
				newcommand->output= operation->output;
			}
			else
			{
				newcommand->output= concat(dest->u.word[0], dest->u.word[1]);
				newcommand->input = operation->input;
			}
			newcommand->u.word = operation->u.word;
			addCommand(&cmd_start, &cmd_end, newcommand);
		}
		else //an operation that needs to be made into a tree
		{
			command* operand2 = popCommand(&cmd_start, &cmd_end), *operand1 = popCommand(&cmd_start, &cmd_end);
			
			if ((curr->prev && curr->prev->sub > 1 && curr->sub == 1) || operand2->type == SEQUENCE_COMMAND) //if we just ended a subshell, then make operand2 a subshell command on itself
			{
				command* newcommand = malloc(sizeof(command));
				newcommand->type = SUBSHELL_COMMAND;
				newcommand->input = newcommand->output = 0;
				newcommand->status = -1;
				newcommand->u.subshell_command = operand2;
				operand2 = newcommand;
			}
			if (operand1->type == SEQUENCE_COMMAND) //convert operand1 into subshell if it was a sequence, as sequences are only possible in subshells
			{
				command* newcommand = malloc(sizeof(command));
				newcommand->type = SUBSHELL_COMMAND;
				newcommand->input = newcommand->output = 0;
				newcommand->status = -1;
				newcommand->u.subshell_command = operand1;
				operand1 = newcommand;
			}
			command* newcommand = malloc(sizeof(command));
			newcommand->type = tokenToCommandType(curr->t);
			newcommand->status = -1;
			newcommand->input = newcommand->output = 0;
			newcommand->u.command[0] = operand1;
			newcommand->u.command[1] = operand2;
			addCommand(&cmd_start, &cmd_end, newcommand);
		}
	
	str_end->root=cmd_start;
	
	return str_start;
}