Subversion Repositories Kolibri OS

Rev

Rev 8686 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2. WHOIS port for KolibriOS (Adapted by turbocat2001).
  3. The main code is taken from the site:
  4. https://www.binarytides.com/whois-client-code-in-c-with-linux-sockets/
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <conio.h>     
  9. #include <string.h>    
  10. #include <stdlib.h>    
  11. #include <net/socket.h>
  12. #include <net/network.h>
  13.  
  14. #define stdout (FILE*)0
  15.  
  16. FILE *out=stdout;
  17.  
  18. #ifdef DEBUG
  19. FILE *out=stderr;
  20. #endif
  21.  
  22. #define EXIT_SUCCESS 0
  23. #define EXIT_FAILURE 1
  24. #define perror(STR) debug_printf(STR);
  25.  
  26. int unix_fprintf(FILE* file, const char* format, ...)
  27. {
  28.     va_list     arg;
  29.     va_start (arg, format);
  30.     if(file==stdout){
  31.                 return vprintf(format, arg);
  32.         }else if(file==stderr){
  33.                 char log_board[300];
  34.                 vsnprintf(log_board, sizeof log_board, format, arg);
  35.         debug_out_str(log_board);
  36.                 return 0;
  37.         }else{
  38.                 return vfprintf(file, format, arg);
  39.         }
  40. }
  41.  
  42. void show_help()
  43. {
  44.         puts("Usage: whois <host> [-f <file>]\n");
  45.         puts(" host         Connect to server host");
  46.         puts(" -f file      Redirecting output to file\n");
  47.         puts("Example: whois google.com -f my.txt");
  48. }
  49.  
  50. int get_whois_data(char * , char **);
  51. int hostname_to_ip(char * , char *);
  52. int whois_query(char * , char * , char **);
  53. char *str_replace(char *search , char *replace , char *subject );
  54. char* str_copy(char*);
  55.  
  56. void start_console()
  57. {
  58.         con_init_console_dll();
  59.         con_set_title("Whois");
  60. }
  61.  
  62. int main(int argc , char *argv[])
  63. {      
  64.         networklib_init();
  65.         char *domain , *data = NULL;
  66.         int f_flag=0;
  67.  
  68.         if(argc==2){
  69.                 start_console();
  70.                 domain=strdup(argv[1]);
  71.         }
  72.  
  73.         else if(!strcmp(argv[2], "-f") && argc==4){
  74.                 domain=strdup(argv[1]);
  75.                 if((out=fopen(argv[3],"w"))==NULL){
  76.                         printf("Error writing to file: '%s' !\n", argv[3]);
  77.                         exit(0);
  78.                 }
  79.         }else{
  80.                 start_console();
  81.                 show_help();
  82.                 exit(0);
  83.         }
  84.  
  85.         get_whois_data(domain , &data);
  86.         exit(0);
  87. }
  88.  
  89. /*
  90.     Get the whois data of a domain
  91. */
  92.  
  93. int get_whois_data(char *domain , char **data)
  94. {
  95.         char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt;
  96.  
  97.         //remove "http://" and "www."
  98.         domain = str_replace("http://" , "" , domain);
  99.         domain = str_replace("www." , "" , domain);
  100.  
  101.         //get the extension , com , org , edu
  102.         dt = strdup(domain);
  103.         if(dt == NULL){
  104.                 unix_fprintf(out, "strdup failed");
  105.         }
  106.         pch = (char*)strtok(dt , ".");
  107.         while(pch != NULL){
  108.                 strcpy(ext , pch);
  109.                 pch = strtok(NULL , ".");
  110.         }
  111.        
  112.         // This will tell the whois server for the particular TLD like com , org
  113.         if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE){
  114.                 unix_fprintf(out, "Whois query failed");
  115.         return 1;
  116.         }
  117.         unix_fprintf(out, "\n\nResponse is:\n\n");
  118.         unix_fprintf(out, "%s", response);
  119.        
  120.         // Now analysze the response
  121.         pch = strtok(response , "\n");
  122.         while(pch != NULL){
  123.                 // Check if whois line
  124.                 wch = strstr(pch , "whois.");
  125.                 if(wch != NULL){
  126.                         break;
  127.                 }
  128.  
  129.                 // Next line please
  130.                 pch = strtok(NULL , "\n");
  131.         }
  132.         // Now we have the TLD whois server in wch , query again
  133.         //This will provide minimal whois information along with the parent whois server of the specific domain :)
  134.         free(response);
  135.     //This should not be necessary , but segmentation fault without this , why ?
  136.         response = NULL;
  137.         if(wch != NULL){
  138.                 unix_fprintf(out, "\nTLD Whois server is : %s" , wch);
  139.         if( whois_query(wch , domain , &response) == EXIT_FAILURE){
  140.                         unix_fprintf(out, "Whois query failed\n");
  141.             return EXIT_FAILURE;
  142.                 }
  143.         }else{
  144.                 unix_fprintf(out, "\nTLD whois server for %s not found\n" , ext);
  145.                 return EXIT_SUCCESS;
  146.         }
  147.        
  148.         response_2 = strdup(response);
  149.        
  150.     // Again search for a whois server in this response. :)
  151.         pch = strtok(response , "\n");
  152.         while(pch != NULL){
  153.                 // Check if whois line
  154.                 wch = strstr(pch , "whois.");
  155.                 if(wch != NULL){
  156.                         break;
  157.                 }
  158.                 //Next line please
  159.                 pch = strtok(NULL , "\n");
  160.         }
  161.  
  162.         /*
  163.         If a registrar whois server is found then query it
  164.     */
  165.         if(wch){
  166.                 // Now we have the registrar whois server , this has the direct full information of the particular domain
  167.                 // so lets query again
  168.                
  169.                 unix_fprintf(out, "\nRegistrar Whois server is : %s" , wch);
  170.                
  171.                 if( whois_query(wch , domain , &response) == EXIT_FAILURE ){
  172.                         unix_fprintf(out, "Whois query failed");
  173.                 }else{
  174.             unix_fprintf(out, "\n%s" , response);
  175.         }
  176.         }
  177.         /*
  178.         otherwise echo the output from the previous whois result
  179.     */
  180.         else{
  181.                 unix_fprintf(out, "%s" , response_2);
  182.         }      
  183.         return 0;
  184. }
  185.  
  186. /*
  187.     Perform a whois query to a server and record the response
  188. */
  189. int whois_query(char *server , char *query , char **response)
  190. {
  191.         char ip[32] , message[100] , buffer[1500];
  192.         int sock , read_size , total_size = 0;
  193.         int WHOIS_PORT = 43;
  194.     struct sockaddr dest;
  195.    
  196.         sock = socket(AF_INET4 , SOCK_STREAM , IPPROTO_TCP);
  197.      
  198.     //Prepare connection structures :)
  199.     memset( &dest , 0 , sizeof(dest) );
  200.     dest.sin_family = AF_INET;
  201.    
  202.     server = str_copy(server);
  203.     server[strcspn(server, "\r\n")] = '\0';
  204.    
  205.         unix_fprintf(out, "\nResolving: %s ...\n" , server);
  206.         if( hostname_to_ip(server , ip) == EXIT_FAILURE ){
  207.         unix_fprintf(out, "Failed\n");
  208.         return EXIT_FAILURE;
  209.         }
  210.        
  211.         unix_fprintf(out, "Found ip: %s \n" , ip);    
  212.        
  213.     dest.sin_addr = inet_addr(ip);
  214.         dest.sin_port = PORT(WHOIS_PORT);
  215.  
  216.         //Now connect to remote server
  217.         if(connect(sock , (const struct sockaddr*) &dest , sizeof(dest)) < 0){
  218.                 perror("connect failed");
  219.         return EXIT_FAILURE;
  220.         }
  221.        
  222.         //Now send some data or message
  223.         unix_fprintf(out, "\nQuerying for: %s ...\n" , query);
  224.         sprintf(message , "%s\r\n" , query);
  225.         if( send(sock , message , strlen(message) , 0) < 0){
  226.                 perror("send failed");
  227.         return EXIT_FAILURE;
  228.         }
  229.        
  230.         //Now receive the response
  231.         while((read_size = recv(sock, buffer, sizeof(buffer), 0))){
  232.                 *response = realloc(*response , read_size + total_size);
  233.                 if(*response == NULL){
  234.                         unix_fprintf(out, "realloc failed");
  235.             return EXIT_FAILURE;
  236.                 }
  237.                 memcpy(*response + total_size , buffer , read_size);
  238.                 total_size += read_size;
  239.         }
  240.        
  241.         unix_fprintf(out, "Done\n");
  242.         //fflush(stdout);
  243.        
  244.         *response = realloc(*response , total_size + 1);
  245.         *(*response + total_size) = '\0';
  246.         close(sock);
  247.     return EXIT_SUCCESS;
  248. }
  249. /*
  250.     Get the ip address of a given hostname
  251. */
  252. int hostname_to_ip(char *hostname , char *ip)
  253. {
  254.         struct addrinfo *addr_info;
  255.     char port_str[16]; sprintf(port_str, "%d", 80);
  256.     struct addrinfo hints;
  257.     memset(&hints, 0, sizeof(hints));
  258.     hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 doesnt matter
  259.     hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
  260.     if (getaddrinfo(hostname, port_str, 0, &addr_info) != 0) {
  261.         freeaddrinfo(addr_info);
  262.                 return EXIT_FAILURE;
  263.     }else{
  264.                 strcpy(ip, inet_ntoa(addr_info->ai_addr->sin_addr));
  265.                 return EXIT_SUCCESS;
  266.         }
  267. }
  268. /*
  269.     Search and replace a string with another string , in a string
  270. */
  271. char *str_replace(char *search , char *replace , char *subject)
  272. {
  273.         char  *p = NULL , *old = NULL , *new_subject = NULL ;
  274.         int c = 0 , search_size;
  275.        
  276.         search_size = strlen(search);
  277.        
  278.         //Count how many occurences
  279.         for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)){
  280.                 c++;
  281.         }
  282.         //Final size
  283.         c = ( strlen(replace) - search_size )*c + strlen(subject);
  284.        
  285.         //New subject with new size
  286.         new_subject = malloc( c );
  287.        
  288.         //Set it to blank
  289.         strcpy(new_subject , "");
  290.        
  291.         //The start position
  292.         old = subject;
  293.        
  294.         for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)){
  295.                 //move ahead and copy some text from original subject , from a certain position
  296.                 strncpy(new_subject + strlen(new_subject) , old , p - old);
  297.                
  298.                 //move ahead and copy the replacement text
  299.                 strcpy(new_subject + strlen(new_subject) , replace);
  300.                
  301.                 //The new start position after this search match
  302.                 old = p + search_size;
  303.         }
  304.        
  305.         //Copy the part after the last search match
  306.         strcpy(new_subject + strlen(new_subject) , old);
  307.        
  308.         return new_subject;
  309. }
  310.  
  311. char* str_copy(char *source)
  312. {
  313.     char *copy = malloc(strlen(source) + 1);
  314.    
  315.     if(copy){
  316.         strcpy(copy, source);
  317.     }
  318.     return copy;
  319. }
  320.