Subversion Repositories Kolibri OS

Rev

Rev 9558 | Go to most recent revision | 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 
8
#include "sys/ksys.h"
9
#include 
10
#include 
11
#include 
12
#include 
13
#include 
8787 turbocat 14
#include 
8687 turbocat 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  [-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");
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
 
42
int main(int argc , char *argv[])
9620 turbocat 43
{
8687 turbocat 44
	char *domain , *data = NULL;
45
	int f_flag=0;
46
 
47
	if(argc==2){
48
		domain=strdup(argv[1]);
49
	}
50
 
51
	else if(!strcmp(argv[2], "-f") && argc==4){
52
		domain=strdup(argv[1]);
53
		if((out=fopen(argv[3],"w"))==NULL){
54
			printf("Error writing to file: '%s' !\n", argv[3]);
55
			exit(0);
56
		}
57
	}else{
58
		show_help();
59
		exit(0);
60
	}
61
	if(out==stdout){
8787 turbocat 62
		con_init();
63
		(*con_set_title)("Whois");
8687 turbocat 64
	}
65
	get_whois_data(domain , &data);
66
	exit(0);
67
}
68
 
69
/*
70
    Get the whois data of a domain
71
*/
72
 
73
int get_whois_data(char *domain , char **data)
74
{
75
	char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt;
76
 
77
	//remove "http://" and "www."
78
	domain = str_replace("http://" , "" , domain);
79
	domain = str_replace("www." , "" , domain);
80
 
81
	//get the extension , com , org , edu
82
	dt = strdup(domain);
83
 
84
	if(dt == NULL){
85
		fprintf(out, "strdup failed");
86
	}
87
	pch = (char*)strtok(dt , ".");
88
	while(pch != NULL){
89
		strcpy(ext , pch);
90
		pch = strtok(NULL , ".");
91
	}
92
	// This will tell the whois server for the particular TLD like com , org
93
	if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE){
94
		fprintf(out, "Whois query failed");
95
        return 1;
96
	}
97
	fprintf(out, "\n\nResponse is:\n\n");
98
	fprintf(out, "%s", response);
99
 
100
	// Now analysze the response
101
	pch = strtok(response , "\n");
102
	while(pch != NULL){
103
		// Check if whois line
104
		wch = strstr(pch , "whois.");
105
		if(wch != NULL){
106
			break;
107
		}
108
 
109
		// Next line please
110
		pch = strtok(NULL , "\n");
111
	}
112
	// Now we have the TLD whois server in wch , query again
113
	//This will provide minimal whois information along with the parent whois server of the specific domain :)
114
	wch = strdup(wch);
115
	free(response);
116
    //This should not be necessary , but segmentation fault without this , why ?
117
	response = NULL;
118
	if(wch != NULL){
119
		fprintf(out,"\nTLD Whois server is : %s" , wch);
120
		if( whois_query(wch , domain , &response) == EXIT_FAILURE){
121
			fprintf(out, "Whois query failed\n");
122
            return EXIT_FAILURE;
123
		}
124
	}else{
125
		fprintf(out, "\nTLD whois server for %s not found\n" , ext);
126
		return EXIT_SUCCESS;
127
	}
128
 
129
	response_2 = strdup(response);
130
 
131
    // Again search for a whois server in this response. :)
132
	pch = strtok(response , "\n");
133
	while(pch != NULL){
134
		// Check if whois line
135
		wch = strstr(pch , "whois.");
136
		if(wch != NULL){
137
			break;
138
		}
139
		//Next line please
140
		pch = strtok(NULL , "\n");
141
	}
142
 
143
	/*
144
        If a registrar whois server is found then query it
145
    */
146
	if(wch){
147
		// Now we have the registrar whois server , this has the direct full information of the particular domain
148
		// so lets query again
149
 
150
		fprintf(out, "\nRegistrar Whois server is : %s" , wch);
151
 
152
		if( whois_query(wch , domain , &response) == EXIT_FAILURE ){
153
			fprintf(out, "Whois query failed");
154
		}else{
155
            fprintf(out, "\n%s" , response);
156
        }
157
	}
158
	/*
159
        otherwise echo the output from the previous whois result
160
    */
161
	else{
162
		fprintf(out, "%s" , response_2);
163
	}
164
	return 0;
165
}
166
 
167
/*
168
    Perform a whois query to a server and record the response
169
*/
170
int whois_query(char *server , char *query , char **response)
171
{
172
	char ip[32] , message[100] , buffer[1500];
173
	int sock , read_size , total_size = 0;
174
	int WHOIS_PORT = 43;
175
    struct sockaddr dest;
176
 
177
	sock = socket(AF_INET4 , SOCK_STREAM , IPPROTO_TCP);
178
 
179
    //Prepare connection structures :)
180
    memset(&dest , 0 , sizeof(dest) );
181
	dest.sin_family = AF_INET;
182
    server = str_copy(server);
183
 
184
    server[strcspn(server, "\r\n")] = '\0';
185
	fprintf(out, "\nResolving: %s ...\n" , server);
186
	if(hostname_to_ip(server , ip) == EXIT_FAILURE ){
187
        fprintf(out, "Failed\n");
188
        return EXIT_FAILURE;
189
	}
190
 
191
	fprintf(out, "Found ip: %s \n" , ip);
192
    dest.sin_addr = inet_addr(ip);
193
	dest.sin_port = PORT(WHOIS_PORT);
194
 
195
;	//Now connect to remote server
196
	if(connect(sock , (const struct sockaddr*) &dest , sizeof(dest)) < 0){
197
		perror("connect failed");
198
		perror(strerror(errno));
199
        return EXIT_FAILURE;
200
	}
201
 
202
	//Now send some data or message
203
	fprintf(out, "\nQuerying for: %s ...\n" , query);
204
	sprintf(message , "%s\r\n" , query);
205
	if( send(sock , message , strlen(message) , 0) < 0){
206
		perror("send failed");
207
        return EXIT_FAILURE;
208
	}
209
 
210
	//Now receive the response
211
	while((read_size = recv(sock, buffer, sizeof(buffer), 0))){
212
		*response = realloc(*response , read_size + total_size);
213
		if(*response == NULL){
214
			fprintf(out, "realloc failed");
215
            return EXIT_FAILURE;
216
		}
217
		memcpy(*response + total_size , buffer , read_size);
218
		total_size += read_size;
219
	}
220
 
221
	fprintf(out, "Done\n");
222
 
223
	*response = realloc(*response , total_size + 1);
224
	*(*response + total_size) = '\0';
225
	close(sock);
226
    return EXIT_SUCCESS;
227
}
228
/*
229
    Get the ip address of a given hostname
230
*/
231
int hostname_to_ip(char *hostname , char *ip)
232
{
233
	struct addrinfo *addr_info;
234
    char port_str[16]; 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
}