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 |
||
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 | }>> |