Subversion Repositories Kolibri OS

Rev

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