| 1 |
|
|---|
| 2 | /********************************************************************\
|
|---|
| 3 |
|
|---|
| 4 | Name: CCCommand.cc
|
|---|
| 5 |
|
|---|
| 6 | Created by: Oliver Grimm, Sebastian Commichau, January 2009
|
|---|
| 7 | oliver.grimm@phys.ethz.ch, commichau@phys.ethz.ch
|
|---|
| 8 |
|
|---|
| 9 | Actions: Listen to commands from Central Control (CC)
|
|---|
| 10 |
|
|---|
| 11 | \********************************************************************/
|
|---|
| 12 |
|
|---|
| 13 | #include "CCCommand.h"
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 | void CCCommand(ProcessIO *m) {
|
|---|
| 17 |
|
|---|
| 18 | siginterrupt(SIGUSR1, true);
|
|---|
| 19 |
|
|---|
| 20 | int ServerSocket,ConnectionSocket,ReadResult;
|
|---|
| 21 | struct sockaddr_in SocketAddress, ClientAddress;
|
|---|
| 22 | socklen_t SizeClientAddress=sizeof(ClientAddress);
|
|---|
| 23 | char comline[MAX_COM_SIZE], str[MAX_COM_SIZE];
|
|---|
| 24 |
|
|---|
| 25 | // Set up server socket
|
|---|
| 26 | if ((ServerSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
|
|---|
| 27 | sprintf(str,"error: could not open server socket, no remote connection possible");
|
|---|
| 28 | m->PrintMessage(str);
|
|---|
| 29 | return;
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | // Allows immediate reuse of socket after closing (circumvents TIME_WAIT)
|
|---|
| 33 | int Value=1;
|
|---|
| 34 | if (setsockopt(ServerSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &Value, sizeof (Value)) == -1) {
|
|---|
| 35 | sprintf(str,"Warning: Could not set server socket option SO_REUSEADDR (%s).\n",strerror(errno));
|
|---|
| 36 | m->PrintMessage(str);
|
|---|
| 37 | }
|
|---|
| 38 |
|
|---|
| 39 | SocketAddress.sin_family = PF_INET;
|
|---|
| 40 | SocketAddress.sin_port = htons((unsigned short) m->config->fCCPort);
|
|---|
| 41 | SocketAddress.sin_addr.s_addr = INADDR_ANY;
|
|---|
| 42 |
|
|---|
| 43 | if (bind(ServerSocket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
|
|---|
| 44 | sprintf(str,"error: could not bind port to socket");
|
|---|
| 45 | m->PrintMessage(str);
|
|---|
| 46 | close(ServerSocket);
|
|---|
| 47 | return;
|
|---|
| 48 | }
|
|---|
| 49 | if (listen(ServerSocket, 0) == -1) {
|
|---|
| 50 | sprintf(str,"error: could not set socket to listening");
|
|---|
| 51 | m->PrintMessage(str);
|
|---|
| 52 | close(ServerSocket);
|
|---|
| 53 | return;
|
|---|
| 54 | }
|
|---|
| 55 |
|
|---|
| 56 | while (!m->status->Exit) { // Looping to wait for incoming connection
|
|---|
| 57 |
|
|---|
| 58 | if ((ConnectionSocket = accept(ServerSocket, (struct sockaddr *) &ClientAddress, &SizeClientAddress)) == -1) {
|
|---|
| 59 | if (errno!=EINTR) {
|
|---|
| 60 | sprintf(str,"error: failed to accept incoming connection");
|
|---|
| 61 | m->PrintMessage(str);
|
|---|
| 62 | }
|
|---|
| 63 | close(ServerSocket);
|
|---|
| 64 | return;
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | pthread_mutex_lock(&m->control_mutex);
|
|---|
| 68 | m->status->Socket = ConnectionSocket;
|
|---|
| 69 | m->status->cc_state = connected;
|
|---|
| 70 | sprintf(str,"connected to client (%s)",inet_ntoa(ClientAddress.sin_addr));
|
|---|
| 71 | m->PrintMessage(str);
|
|---|
| 72 | pthread_mutex_unlock(&m->control_mutex);
|
|---|
| 73 |
|
|---|
| 74 | while (!m->status->Exit) { // Looping as long as client exists
|
|---|
| 75 | bzero(comline,sizeof(comline));
|
|---|
| 76 | ReadResult = read(ConnectionSocket, comline, MAX_COM_SIZE);
|
|---|
| 77 | if (ReadResult==0) break; // Client does not exist anymore
|
|---|
| 78 | if (ReadResult==-1) {
|
|---|
| 79 | if (errno!=EINTR) {
|
|---|
| 80 | sprintf(str,"error: socket read failed");
|
|---|
| 81 | m->PrintMessage(str);
|
|---|
| 82 | }
|
|---|
| 83 | break;
|
|---|
| 84 | }
|
|---|
| 85 |
|
|---|
| 86 | m->status->Pc = comline;
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 | ParseInput(m->status->Pc,&(m->status->NParam),m->status->Param);
|
|---|
| 90 |
|
|---|
| 91 | if (!(Match(m->status->Param[0], "exit") || Match(m->status->Param[0], "quit"))) {
|
|---|
| 92 |
|
|---|
| 93 | sprintf(str,"CC> %s",m->status->Pc);
|
|---|
| 94 | m->log->LogWrite(str);
|
|---|
| 95 |
|
|---|
| 96 | sprintf(str,"%s",m->status->Pc);
|
|---|
| 97 | printf(str);
|
|---|
| 98 |
|
|---|
| 99 | pthread_mutex_lock(&m->control_mutex);
|
|---|
| 100 | // Process CC command
|
|---|
| 101 | if (m->CommandControl()==0)
|
|---|
| 102 | pthread_cond_broadcast(&m->control_cond);
|
|---|
| 103 | pthread_mutex_unlock(&m->control_mutex);
|
|---|
| 104 |
|
|---|
| 105 | }
|
|---|
| 106 | else
|
|---|
| 107 | printf("remote exit|quit forbidden\n");
|
|---|
| 108 |
|
|---|
| 109 | m->PrintMessage(NULL);
|
|---|
| 110 |
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | if (!(m->status->Exit)) {
|
|---|
| 114 | sprintf(str,"disconnected from client (%s)",inet_ntoa(ClientAddress.sin_addr));
|
|---|
| 115 | m->PrintMessage(str);
|
|---|
| 116 | }
|
|---|
| 117 | m->status->Socket = -1;
|
|---|
| 118 | pthread_mutex_lock(&m->control_mutex);
|
|---|
| 119 | m->status->cc_state = disconnected;
|
|---|
| 120 | pthread_mutex_unlock(&m->control_mutex);
|
|---|
| 121 | close(ConnectionSocket);
|
|---|
| 122 |
|
|---|
| 123 | }
|
|---|
| 124 | close(ServerSocket);
|
|---|
| 125 |
|
|---|
| 126 | }
|
|---|