]> jspc29.x-matter.uni-frankfurt.de Git - hadesdaq.git/commitdiff
added command server,mt
authorHADES_DAQ <hadaq@hades31.gsi.de>
Tue, 29 Oct 2013 11:14:32 +0000 (12:14 +0100)
committerHADES_DAQ <hadaq@hades31.gsi.de>
Tue, 29 Oct 2013 11:14:32 +0000 (12:14 +0100)
utils/src/command_server/command_server [new file with mode: 0755]
utils/src/command_server/command_server.c [new file with mode: 0644]

diff --git a/utils/src/command_server/command_server b/utils/src/command_server/command_server
new file mode 100755 (executable)
index 0000000..7bbec03
Binary files /dev/null and b/utils/src/command_server/command_server differ
diff --git a/utils/src/command_server/command_server.c b/utils/src/command_server/command_server.c
new file mode 100644 (file)
index 0000000..9084b1f
--- /dev/null
@@ -0,0 +1,313 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fnmatch.h>
+#include <signal.h>
+#include <syslog.h>
+#include <sys/wait.h>
+
+#define MAX_QUEUE 5
+#define BUF_SIZE 2048
+
+int sock_1, sock_2;     /* file descriptors for sockets */ 
+FILE *fp;
+
+void exit(int);
+
+typedef struct TheArgsS {
+    unsigned long verbosity;
+    unsigned long port;
+} TheArgs;
+
+void  SIGhandler(int);     
+
+void  SIGhandler(int sig)
+{
+    syslog(LOG_ERR, "Caught signal %d, trying to safely exit...", sig);
+
+     if(fp)
+        fclose(fp);
+
+     if(sock_2)
+        close(sock_2);
+
+     if(sock_1)
+        close(sock_1);
+
+     exit(0);
+}
+void SigCatcher(int n)
+{
+  wait3(NULL,WNOHANG,NULL);
+}
+
+static void argsDefault(TheArgs *my)
+{
+    my->verbosity = 0;
+    my->port = 4712;
+}
+
+static int argsFromCL(TheArgs *my, int argc, char *argv[])
+{
+    extern char *optarg;                              
+    int i;                                            
+    
+    while ((i = getopt(argc, argv, "vp:")) != -1) {
+       switch (i) {
+            case 'p':
+               my->port = atoi(optarg);
+               break;
+            case 'v':
+               my->verbosity = 1;
+               break;
+            default:
+               return -1;
+               break;
+       }
+    }
+
+    return 0;
+}
+
+static void usage(const char *progName)
+{
+    printf("Usage: %s\n", progName);
+    printf("       [-p port]    : Port number for connection (default: 4712).\n");
+    printf("       [-v]         : More verbose.\n");
+}
+
+void talk2client(int sock_2, TheArgs *theArgs)
+{
+    int firstCmdLine = 0;
+    int rec_value;
+    int r = 0;
+
+    struct stat file_status;
+
+    char buf[BUF_SIZE];
+    char buf2[BUF_SIZE+300];
+    char buf3[BUF_SIZE+300];
+    char tmp[BUF_SIZE+300];
+    char *token;
+    char redirect1[100]; 
+    char redirect2[100]; 
+    char fstdout[100];
+    char fstderr[100];
+
+    sprintf(fstdout, "%s%d%s", "/tmp/stdout", (int) getpid(), ".txt");
+    sprintf(fstderr, "%s%d%s", "/tmp/stderr", (int) getpid(), ".txt");
+    sprintf(redirect1, "1>%s 2>%s", fstdout, fstderr);
+    sprintf(redirect2, "1>>%s 2>>%s", fstdout, fstderr);
+    
+
+    char mypattern[BUF_SIZE+100];
+    sprintf(mypattern, "iamfromhadesdaq"); /* password */
+    
+    /* Read command from sock_2 */
+    while( (rec_value = read( sock_2, buf, BUF_SIZE )) ){
+       if( rec_value < 0 ){
+           perror("reading stream message");
+           exit(1);
+       }
+       else
+           snprintf( buf2, rec_value, "%s", buf );
+       
+       if(theArgs->verbosity)
+           printf("Received: \"%s\"\n", buf2);
+       
+       /* check password only for the first cmd line */
+       if( firstCmdLine == 0 ){
+           if( 0 != fnmatch(mypattern, buf2, 0) ){
+               sprintf( buf, "Error: wrong password! Break connection.\n" );
+               printf( "%s", buf );
+               printf( "Local pass  : %s", mypattern );
+               printf( "Remote pass : %s", buf2 );
+               write( sock_2, buf, strlen(buf) );    
+               break;
+           }
+           else{
+               sprintf( buf,  "------------- Connection accepted -------------\n" );
+               write( sock_2, buf, strlen(buf) );
+               firstCmdLine = 1; /* set to 1 to avoid checking pass second time */
+               continue;
+           }
+       }
+       
+       /* raise(SIGUSR1);  */
+       
+       /* Prepare cmd for execution. Write standard out/err to tmp. */
+       strcpy(tmp, buf2);
+       strcpy(buf3, "");
+       
+       /* Split string and build cmd 'buf3' */
+       token = strtok( tmp, ";" );     
+       while( token != (char*)NULL ){
+           if( strcmp(buf3, "") != 0 )
+               sprintf( buf3,  "%s %s %s;", buf3, token, redirect2);
+           else
+               sprintf( buf3,  "%s %s;", token, redirect1);
+           
+           token = strtok( NULL, ";" );
+       }
+       
+       /* sprintf( buf3,  "%s 1>/tmp/stdout.txt 2>/tmp/stderr.txt", buf2 ); */
+       
+       if(theArgs->verbosity)
+           printf("Command: \"%s\"\n", buf3);
+       
+       if(theArgs->verbosity)
+           printf("before Return value of system: %d\n", r);
+
+       /* Execute cmd and get the return value */
+       r = system(buf3);
+       
+       if(theArgs->verbosity)
+           printf("Return value of system: %d\n", r);
+       
+       /* Prepare and send the return value of cmd */
+       sprintf( buf, "> return value of command: %i\n", r );
+       write( sock_2, buf, strlen(buf) );
+       
+       /* Check size of the stdout file, anything to read from file? */
+       if(stat(fstdout, &file_status) != 0){
+           perror("could not stat");
+       }
+       
+       if( (int)file_status.st_size ){
+           sprintf( buf, "> stdout: \n" );
+           write( sock_2, buf, strlen(buf) );
+           
+           /* Open and send the stardard output */
+           fp = fopen(fstdout, "r");
+           while( (r = fread( buf, sizeof(char), BUF_SIZE, fp )) ){
+               write( sock_2, buf, r ); 
+           }
+           
+           fclose(fp);
+       }
+       
+       /* Check size of the stderr file, anything to read from file? */
+       if(stat(fstderr, &file_status) != 0){
+           perror("could not stat");
+       }
+       
+       if( (int)file_status.st_size ){
+           sprintf( buf, "> stderr: \n" );
+           write( sock_2, buf, strlen(buf) );
+           
+           /* Open and send the standard error */
+           fp = fopen(fstderr, "r");
+           while( (r = fread(buf, sizeof(char), BUF_SIZE, fp)) ){
+               write( sock_2, buf, r );
+           }
+           
+           fclose(fp);
+       }
+       
+       sprintf( buf, "------------- END OF OUTPUT ------------\n" );
+       write( sock_2, buf, strlen(buf) );
+       
+       /* write(1,buf,rec_value); */
+       
+    } /* End of while( (rec_value = read( sock_2, buf, BUF_SIZE )) ) */
+
+    if(remove(fstdout)) syslog(LOG_ERR, "%s:%d: %s %s", __FILE__, __LINE__, "Cannot remove file", fstdout);
+    if(remove(fstderr)) syslog(LOG_ERR, "%s:%d: %s %s", __FILE__, __LINE__, "Cannot remove file", fstderr);
+}
+
+int main( int argc, char *argv[] )
+{
+    int sockopt_on = 1;
+    struct sockaddr_in server;
+    int pid;
+
+    TheArgs theArgsS, *theArgs = &theArgsS;
+
+    /* signal(SIGCHLD, SIG_IGN); */
+    signal(SIGCHLD, SigCatcher);
+    signal(SIGUSR1, SIGhandler);
+    signal(SIGTERM, SIGhandler);
+    signal(SIGABRT, SIGhandler);
+    signal(SIGILL,  SIGhandler);
+    signal(SIGINT,  SIGhandler);
+    signal(SIGPIPE, SIGhandler);
+    signal(SIGSEGV, SIGhandler); 
+
+    openlog(argv[0], LOG_PID | LOG_PERROR, LOG_LOCAL0);
+    setlogmask(LOG_UPTO(LOG_INFO));
+
+    argsDefault(theArgs);
+    if (0 > argsFromCL(theArgs, argc, argv)) {
+       usage(argv[0]);
+       exit(1);
+    }
+   
+    /* Init to zero */
+    bzero((char *) &server, sizeof(server));
+
+    /* Build address in internet domain */
+    server.sin_family      = AF_INET;
+    server.sin_addr.s_addr = INADDR_ANY; /* everyone is allowed to connet to server */
+    server.sin_port        = htons(theArgs->port);
+    
+    /* Create stream socket in internet domain */
+    sock_1 = socket( AF_INET, SOCK_STREAM, 0 );
+    if( sock_1 < 0 ){
+       syslog(LOG_ERR, "%s:%d: %s", __FILE__, __LINE__, "Cannot open stream socket");
+       exit(1);
+    }
+
+    /* Make the socket reusable */
+    if( 0 > setsockopt( sock_1, SOL_SOCKET, SO_REUSEADDR, &sockopt_on, sizeof(int)) ){
+       syslog(LOG_ERR, "%s:%d: %s", __FILE__, __LINE__, "Cannot make socket reusable");
+    }
+
+    /* Bind socket */
+    if( 0 > bind(sock_1, (struct sockaddr *)&server,sizeof(struct sockaddr_in)) ){
+       syslog(LOG_ERR, "%s:%d: %s", __FILE__, __LINE__, "Cannot bind socket");
+       exit(1);
+    }
+
+    listen( sock_1, MAX_QUEUE );
+
+    while(1){
+       /* Start accepting connection */    
+       sock_2 = accept( sock_1, 0, 0);
+
+       if( sock_2 < 0 ){
+           syslog(LOG_ERR, "%s:%d: %s", __FILE__, __LINE__, "Cannot accept connections");
+       }
+       
+       /* Fork new process */
+       pid = fork();
+
+       if( pid < 0 )
+           syslog(LOG_ERR, "%s:%d: %s", __FILE__, __LINE__, "Cannot fork");
+
+       if( pid == 0 ){                /* Child */
+           close(sock_1);
+           talk2client(sock_2, theArgs);
+           close(sock_2);
+           exit(0);
+       }
+       else{     /* Parent */
+           close(sock_2);
+       }
+       
+       if(theArgs->verbosity){
+           printf("Ending connection.\n");
+       }
+
+    } /* End of while(1) */
+    
+    close(sock_1); 
+
+    return 0;
+}
+