Subversion Repositories Kolibri OS

Rev

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