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); } }
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; }