Subversion Repositories Kolibri OS

Rev

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