/********************************************************************\ Name: CCCommand.cc Created by: Oliver Grimm, Sebastian Commichau, January 2009 oliver.grimm@phys.ethz.ch, commichau@phys.ethz.ch Actions: Listen to commands from Central Control (CC) \********************************************************************/ #include "CCCommand.h" void CCCommand(ProcessIO *m) { siginterrupt(SIGUSR1, true); int ServerSocket,ConnectionSocket,ReadResult; struct sockaddr_in SocketAddress, ClientAddress; socklen_t SizeClientAddress=sizeof(ClientAddress); char comline[MAX_COM_SIZE], str[MAX_COM_SIZE]; // Set up server socket if ((ServerSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { sprintf(str,"error: could not open server socket, no remote connection possible"); m->PrintMessage(str); return; } // Allows immediate reuse of socket after closing (circumvents TIME_WAIT) int Value=1; if (setsockopt(ServerSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &Value, sizeof (Value)) == -1) { sprintf(str,"Warning: Could not set server socket option SO_REUSEADDR (%s).\n",strerror(errno)); m->PrintMessage(str); } SocketAddress.sin_family = PF_INET; SocketAddress.sin_port = htons((unsigned short) m->config->fCCPort); SocketAddress.sin_addr.s_addr = INADDR_ANY; if (bind(ServerSocket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) { sprintf(str,"error: could not bind port to socket"); m->PrintMessage(str); close(ServerSocket); return; } if (listen(ServerSocket, 0) == -1) { sprintf(str,"error: could not set socket to listening"); m->PrintMessage(str); close(ServerSocket); return; } while (!m->status->Exit) { // Looping to wait for incoming connection if ((ConnectionSocket = accept(ServerSocket, (struct sockaddr *) &ClientAddress, &SizeClientAddress)) == -1) { if (errno!=EINTR) { sprintf(str,"error: failed to accept incoming connection"); m->PrintMessage(str); } close(ServerSocket); return; } pthread_mutex_lock(&m->control_mutex); m->status->Socket = ConnectionSocket; m->status->cc_state = connected; sprintf(str,"connected to client (%s)",inet_ntoa(ClientAddress.sin_addr)); m->PrintMessage(str); pthread_mutex_unlock(&m->control_mutex); while (!m->status->Exit) { // Looping as long as client exists bzero(comline,sizeof(comline)); ReadResult = read(ConnectionSocket, comline, MAX_COM_SIZE); if (ReadResult==0) break; // Client does not exist anymore if (ReadResult==-1) { if (errno!=EINTR) { sprintf(str,"error: socket read failed"); m->PrintMessage(str); } break; } m->status->Pc = comline; ParseInput(m->status->Pc,&(m->status->NParam),m->status->Param); if (!(Match(m->status->Param[0], "exit") || Match(m->status->Param[0], "quit"))) { sprintf(str,"CC> %s",m->status->Pc); m->log->LogWrite(str); sprintf(str,"%s",m->status->Pc); printf(str); pthread_mutex_lock(&m->control_mutex); // Process CC command if (m->CommandControl()==0) pthread_cond_broadcast(&m->control_cond); pthread_mutex_unlock(&m->control_mutex); } else printf("remote exit|quit forbidden\n"); m->PrintMessage(NULL); } if (!(m->status->Exit)) { sprintf(str,"disconnected from client (%s)",inet_ntoa(ClientAddress.sin_addr)); m->PrintMessage(str); } m->status->Socket = -1; pthread_mutex_lock(&m->control_mutex); m->status->cc_state = disconnected; pthread_mutex_unlock(&m->control_mutex); close(ConnectionSocket); } close(ServerSocket); }