Subversion Repositories Kolibri OS

Rev

Rev 9620 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8687 turbocat 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 
8787 turbocat 9
#include 
9766 turbocat 10
#include 
11
#include 
12
#include 
13
#include 
14
#include 
8687 turbocat 15
 
9766 turbocat 16
FILE* out = stdout;
8687 turbocat 17
 
18
#ifdef DEBUG
9766 turbocat 19
FILE* out = stderr;
8687 turbocat 20
#endif
21
 
22
#define EXIT_SUCCESS 0
23
#define EXIT_FAILURE 1
24
 
25
#define fprintf fprintf
26
 
27
void show_help()
28
{
9766 turbocat 29
    puts("Usage: whois  [-f ]\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");
8687 turbocat 33
}
34
 
9766 turbocat 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);
8687 turbocat 39
char* str_copy(char*);
40
 
9766 turbocat 41
int main(int argc, char* argv[])
9620 turbocat 42
{
9766 turbocat 43
    char *domain, *data = NULL;
44
    int f_flag = 0;
8687 turbocat 45
 
9766 turbocat 46
    if (argc == 2) {
47
        domain = strdup(argv[1]);
48
    }
8687 turbocat 49
 
9766 turbocat 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);
8687 turbocat 66
}
67
 
68
/*
69
    Get the whois data of a domain
70
*/
71
 
9766 turbocat 72
int get_whois_data(char* domain, char** data)
8687 turbocat 73
{
9766 turbocat 74
    char ext[1024], *pch, *response = NULL, *response_2 = NULL, *wch, *dt;
8687 turbocat 75
 
9766 turbocat 76
    // remove "http://" and "www."
77
    domain = str_replace("http://", "", domain);
78
    domain = str_replace("www.", "", domain);
8687 turbocat 79
 
9766 turbocat 80
    // get the extension , com , org , edu
81
    dt = strdup(domain);
8687 turbocat 82
 
9766 turbocat 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");
8687 turbocat 94
        return 1;
9766 turbocat 95
    }
96
    fprintf(out, "\n\nResponse is:\n\n");
97
    fprintf(out, "%s", response);
8687 turbocat 98
 
9766 turbocat 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
        }
8687 turbocat 107
 
9766 turbocat 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");
8687 turbocat 121
            return EXIT_FAILURE;
9766 turbocat 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
 
8687 turbocat 130
    // Again search for a whois server in this response. :)
9766 turbocat 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
    }
8687 turbocat 141
 
9766 turbocat 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);
8687 turbocat 155
        }
9766 turbocat 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;
8687 turbocat 164
}
165
 
166
/*
167
    Perform a whois query to a server and record the response
168
*/
9766 turbocat 169
int whois_query(char* server, char* query, char** response)
8687 turbocat 170
{
9766 turbocat 171
    char ip[32], message[100], buffer[1500];
172
    int sock, read_size, total_size = 0;
173
    int WHOIS_PORT = 43;
8687 turbocat 174
    struct sockaddr dest;
9766 turbocat 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;
8687 turbocat 181
    server = str_copy(server);
9766 turbocat 182
 
8687 turbocat 183
    server[strcspn(server, "\r\n")] = '\0';
9766 turbocat 184
    fprintf(out, "\nResolving: %s ...\n", server);
185
    if (hostname_to_ip(server, ip) == EXIT_FAILURE) {
8687 turbocat 186
        fprintf(out, "Failed\n");
187
        return EXIT_FAILURE;
9766 turbocat 188
    }
189
 
190
    fprintf(out, "Found ip: %s \n", ip);
8687 turbocat 191
    dest.sin_addr = inet_addr(ip);
9766 turbocat 192
    dest.sin_port = PORT(WHOIS_PORT);
8687 turbocat 193
 
9766 turbocat 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));
8687 turbocat 198
        return EXIT_FAILURE;
9766 turbocat 199
    }
8687 turbocat 200
 
9766 turbocat 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");
8687 turbocat 206
        return EXIT_FAILURE;
9766 turbocat 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");
8687 turbocat 214
            return EXIT_FAILURE;
9766 turbocat 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);
8687 turbocat 225
    return EXIT_SUCCESS;
226
}
227
/*
228
    Get the ip address of a given hostname
229
*/
9766 turbocat 230
int hostname_to_ip(char* hostname, char* ip)
8687 turbocat 231
{
9766 turbocat 232
    struct addrinfo* addr_info;
233
    char port_str[16];
234
    sprintf(port_str, "%d", 80);
8687 turbocat 235
    struct addrinfo hints;
236
    memset(&hints, 0, sizeof(hints));
9766 turbocat 237
    hints.ai_family = AF_UNSPEC;     // IPv4 or IPv6 doesnt matter
8687 turbocat 238
    hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
239
    if (getaddrinfo(hostname, port_str, 0, &addr_info) != 0) {
240
        freeaddrinfo(addr_info);
9766 turbocat 241
        return EXIT_FAILURE;
242
    } else {
243
        strcpy(ip, inet_ntoa(addr_info->ai_addr->sin_addr));
244
        return EXIT_SUCCESS;
245
    }
8687 turbocat 246
}
247
/*
248
    Search and replace a string with another string , in a string
249
*/
9766 turbocat 250
char* str_replace(char* search, char* replace, char* subject)
8687 turbocat 251
{
9766 turbocat 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;
8687 turbocat 288
}
289
 
9766 turbocat 290
char* str_copy(char* source)
8687 turbocat 291
{
9766 turbocat 292
    char* copy = malloc(strlen(source) + 1);
293
 
294
    if (copy) {
8687 turbocat 295
        strcpy(copy, source);
296
    }
297
    return copy;
9766 turbocat 298
}