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