// Server.java
// Code by Jan Humble


import java.net.*;
import java.io.*;
import java.util.*;

public class Server { 
    	
    public static void main( String argv[] ) throws IOException {
	
	// Get the port number from the command line.

	int portNr = Integer.parseInt(argv[0]);
	// Create a ServerSocket object to watch that port for clients
	ServerSocket ss = new ServerSocket(portNr);
	System.out.println("starting...");
	
	// Here we loop indefinitely, just waiting for clients to connect
	while ( true ) {
	    
	    // accept() does not return until a client requests a connection
	    // Now that a client has arrived, create an instance of our special
	    // thread subclass to respond to it.
	    new ServerConnection( ss.accept() ).start();
	    System.out.println("new connection");
	    
	} // Now loop back around and wait for next client to be accepted.
    }
}


class ServerConnection extends Thread {
    
    Socket client;
    
    // Pass the socket as a argument to the constructor
    ServerConnection ( Socket client ) throws SocketException {
	this.client = client;
	
	// Set the thread priority down so that the ServerSocket
	// will be responsive to new clients.
	setPriority( NORM_PRIORITY - 1 );
    }
    
    public void run() {
	
	boolean connection = true; // connection tester for current client
	
	try {
	    while (connection) {
		
		// Use the client socket to obtain an input stream from it.
		// For text input we wrap an InputStreamReader around 
		// the raw input stream and set ASCII character encoding. 
		// Finally, use a BufferReader wrapper to obtain 
		// buffering and higher order read methods.
		BufferedReader in = new BufferedReader( 
		  new InputStreamReader(client.getInputStream(), "8859_1") );
		
		// Now get an output stream to the client.
		 OutputStream out = client.getOutputStream(); 
		 
		 // For text output we wrap an OutputStreamWriter around 
		 // the raw output stream and set ASCII character encoding.
		 // Finally, we use a PrintWriter wrapper to obtain its
		 // higher level output methods. 
		 // Open in append mode.
		 PrintWriter pout = new PrintWriter( 
			 new OutputStreamWriter(out, "8859_1"), true );
		 
		 
		 // First read the request line from the client
		 String request = in.readLine();
		 System.out.println( "Request: "+request );
		 
		 // Use aStringTokenizer to examine the request text.
		 StringTokenizer st = new StringTokenizer( request );
		 
		 String reqCommand = st.nextToken();
		 

		 // EXECUTE rutine at Server side
		 if ( (st.countTokens() >= 1) && 
		      (
		       reqCommand.equals("EXECUTE") || 
		       reqCommand.equals("EXEC"))) 
		     {
			 // read entire string command
			 String promptCommand = ""; 
			 while(st.hasMoreTokens()) {
			     promptCommand += st.nextToken();
			     promptCommand += " ";
			 }
			 
			 // execute rutine on System
			 executeCommand(promptCommand);
			 
		     } 
		 
		 // Disconnect request
		 else if((st.countTokens() >= 0) 
			 && reqCommand.equals("DISCONNECT") ) {
		     connection = false;
		
		     
		 }
		 
		 // Socket ID request
		 else if((st.countTokens() >= 0) 
			 && reqCommand.equals("ID") ) {
		     
		     System.out.println(client.toString()); 
		     
		 }
		 
		 else if((st.countTokens() >= 0) 
			 && reqCommand.equals("INFO") ) {
		     System.out.println( "Hello client, this is Server. ");
		     
		 }
		 
		 else {
		     System.out.println( "Request not available."); 
		 } 
	     } 
	    
	    // Disconnect (and ID) client
	    System.out.println(client.toString()); 
	    System.out.println( "Disconnecting... ");
	    client.close();
	     
	 } catch ( IOException e ) {
	     System.out.println( "I/O error " + e ); }
	 // On return from run() the thread process will stop. 
    }
    
    
    
	
    // Execute command on Server side
    public void executeCommand(String command) {
	try {
	    Runtime rt = Runtime.getRuntime();      
	    
	    Process prcs = rt.exec(command);          
	    
	    InputStreamReader isr =                 
		new InputStreamReader( prcs.getInputStream() );
	    
	    BufferedReader br = new BufferedReader(isr);
	    String line;
	    while  ((line = br.readLine()) != null)
		System.out.println(line);
	    
	} catch(IOException ioe) { System.out.println(ioe); }
    } 

}


