Subversion Repositories Kolibri OS

Rev

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

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