kolibri-libc:
Move to folder with tcc. Part 1 git-svn-id: svn://kolibrios.org@8793 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
29
programs/develop/ktcc/trunk/libc.obj/samples/Makefile
Normal file
29
programs/develop/ktcc/trunk/libc.obj/samples/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
KTCC=../../../ktcc/trunk/bin/kos32-tcc
|
||||
FASM= fasm
|
||||
KPACK = kpack
|
||||
CFLAGS = -I../include
|
||||
LDFLAGS = -nostdlib -L../lib ../lib/crt0.o
|
||||
|
||||
BIN= stdio_test.kex \
|
||||
basic_gui.kex \
|
||||
http_tcp_demo.kex \
|
||||
math_test.kex \
|
||||
string_test.kex \
|
||||
whois.kex \
|
||||
file_io.kex \
|
||||
tmpdisk_work.kex \
|
||||
fasm/sprintf_test.kex
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
%.kex : %.c
|
||||
$(KTCC) $(CFLAGS) $(LDFLAGS) $< -o $@ -ltcc -lnetwork -lc.obj
|
||||
$(KPACK) --nologo $@
|
||||
|
||||
%.kex : %.asm
|
||||
$(FASM) $< $@
|
||||
$(KPACK) --nologo $@
|
||||
|
||||
clean:
|
||||
rm *.kex
|
||||
115
programs/develop/ktcc/trunk/libc.obj/samples/basic_gui.c
Normal file
115
programs/develop/ktcc/trunk/libc.obj/samples/basic_gui.c
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
ksys_colors_table_t sys_color_table;
|
||||
|
||||
char statusbar[255];
|
||||
ksys_proc_table_t proc_info;
|
||||
char text_line[255];
|
||||
|
||||
enum BUTTONS
|
||||
{
|
||||
BTN_QUIT = 1,
|
||||
BTN_POP = 10,
|
||||
BTN_UNLOCK = 11
|
||||
};
|
||||
|
||||
#define FONT_W 8
|
||||
#define FONT_H 14
|
||||
#define LINES 10
|
||||
|
||||
void draw_window()
|
||||
{
|
||||
int win_hight, win_width, i, pos_y = _ksys_get_skin_height() + 36; // 60 == 24+36
|
||||
|
||||
// start redraw
|
||||
_ksys_start_draw();
|
||||
// define&draw window
|
||||
_ksys_create_window(10, 40, 600, 400, "My window", sys_color_table.work_area, 0x13);
|
||||
_ksys_process_info(&proc_info, -1);
|
||||
|
||||
win_width = proc_info.winx_size;
|
||||
win_hight = proc_info.winy_size;
|
||||
|
||||
_ksys_define_button(10, 30, 70, 20, BTN_POP, sys_color_table.work_button);
|
||||
_ksys_draw_text("BUTTON1", 15, 34, 0, 0x90000000 | sys_color_table.work_button_text); //0x80000000 asciiz
|
||||
_ksys_define_button(100, 30, 80, 20, BTN_UNLOCK, sys_color_table.work_button);
|
||||
_ksys_draw_text("BUTTTON2", 110, 34, 0, 0x90000000 | sys_color_table.work_button_text);
|
||||
|
||||
// display statusbar
|
||||
_ksys_draw_bar(6, win_hight - 17, win_width - 11, 12, 0x80000000 | sys_color_table.work_area); //0x80000000 gradient
|
||||
_ksys_draw_text(statusbar, 10, win_hight - 15, 0, 0x80000000 | sys_color_table.work_text);
|
||||
|
||||
// display strings
|
||||
for (i = LINES; i > 0; i--){
|
||||
snprintf (text_line, sizeof text_line, "Line[%d]<<Just a text>>", i);
|
||||
|
||||
text_line[(win_width - 10 - 5) / FONT_W + 1] = '\0'; // clip text size, seems to big lines crashing OS, and form len by window size
|
||||
_ksys_draw_text(text_line, 5, pos_y, 0, 0x90000000 | sys_color_table.work_text);
|
||||
pos_y += FONT_H;
|
||||
|
||||
if(pos_y + 29 > win_hight) break; // 12 font + 12 statusbar + 5 border
|
||||
}
|
||||
// end redraw
|
||||
_ksys_end_draw();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int gui_event;
|
||||
uint32_t pressed_button = 0, mouse_button;
|
||||
ksys_pos_t mouse_pos;
|
||||
strcpy(statusbar, "Program running...Double click on TEXT for details");
|
||||
|
||||
_ksys_get_system_colors(&sys_color_table);
|
||||
_ksys_set_event_mask(0xC0000027); // mouse events only when focused window and mouse inside
|
||||
|
||||
do{
|
||||
gui_event = _ksys_get_event();
|
||||
switch(gui_event)
|
||||
{
|
||||
case KSYS_EVENT_NONE:
|
||||
break;
|
||||
case KSYS_EVENT_REDRAW:
|
||||
draw_window();
|
||||
break;
|
||||
case KSYS_EVENT_KEY:
|
||||
break;
|
||||
case KSYS_EVENT_BUTTON:
|
||||
pressed_button = _ksys_get_button();
|
||||
switch (pressed_button)
|
||||
{
|
||||
case BTN_POP:
|
||||
strcpy(statusbar, "POP pressed....");
|
||||
draw_window();
|
||||
break;
|
||||
case BTN_UNLOCK:
|
||||
strcpy(statusbar, "UNLOCK pressed....");
|
||||
draw_window();
|
||||
break;
|
||||
case BTN_QUIT:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KSYS_EVENT_MOUSE:
|
||||
mouse_pos = _ksys_get_mouse_pos(KSYS_MOUSE_WINDOW_POS); // window relative
|
||||
mouse_button = _ksys_get_mouse_eventstate();
|
||||
debug_printf("mouse ev (%d,%d)%x\n", mouse_pos.x, mouse_pos.y, mouse_button);
|
||||
if (mouse_button & (1<<24)) // double click
|
||||
{
|
||||
int n = (mouse_pos.y - 60) / FONT_H;
|
||||
if (n < 0 || n >= LINES) break;
|
||||
debug_printf("click on str(%d), clip slot(%d)\n", n, LINES - n - 1);
|
||||
sprintf(statusbar, "click on str(%d), clip slot(%d)\n", n, LINES - n - 1);
|
||||
draw_window();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while(1) ; /* End of main activity loop */
|
||||
|
||||
return 0;
|
||||
}
|
||||
45
programs/develop/ktcc/trunk/libc.obj/samples/dir_example.c
Normal file
45
programs/develop/ktcc/trunk/libc.obj/samples/dir_example.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/dir.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <conio.h>
|
||||
|
||||
const char *folder_type = "Folder";
|
||||
const char *file_type = "File";
|
||||
|
||||
int main()
|
||||
{
|
||||
char *path=getcwd(NULL, PATH_MAX);
|
||||
printf("Current directory: %s\n", path);
|
||||
if(mkdir("test")){
|
||||
puts("Test folder created!");
|
||||
}
|
||||
else{
|
||||
puts("Error creating folder!");
|
||||
}
|
||||
|
||||
DIR *mydir = opendir(path);
|
||||
if(!mydir){
|
||||
puts("File system error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct dirent *file_info;
|
||||
char *str_type=NULL;
|
||||
putc(' ');
|
||||
while((file_info = readdir(mydir))!=NULL){
|
||||
if(file_info->d_type==IS_FOLDER){
|
||||
(*con_set_flags)(CON_COLOR_GREEN);
|
||||
str_type = (char*)folder_type;
|
||||
}else {
|
||||
(*con_set_flags)(7);
|
||||
str_type = (char*)file_type;
|
||||
}
|
||||
printf("%3d %20s %s\n ", file_info->d_ino ,file_info->d_name, str_type);
|
||||
};
|
||||
|
||||
setcwd("/sys/develop");
|
||||
path=getcwd(NULL, PATH_MAX);
|
||||
printf("Move to the directory: %s\n", path);
|
||||
free(path);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
format binary as "kex"
|
||||
|
||||
use32
|
||||
org 0x0
|
||||
db 'MENUET01'
|
||||
dd 0x01
|
||||
dd START
|
||||
dd IM_END
|
||||
dd MEM
|
||||
dd MEM
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
include '../../../../../macros.inc'
|
||||
include '../../../../../proc32.inc'
|
||||
include '../../../../../KOSfuncs.inc'
|
||||
include '../../../../../dll.inc'
|
||||
;include '../../../../../debug-fdo.inc'
|
||||
|
||||
;__DEBUG__ = 1
|
||||
;__DEBUG_LEVEL__ = 2
|
||||
|
||||
START:
|
||||
stdcall dll.Load, @IMPORT
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
cinvoke libc_strlen, test_str1
|
||||
;DEBUGF 2, "%d", eax
|
||||
mcall SF_SYS_MISC, SSF_MEM_ALLOC, eax
|
||||
mov [test_str2], eax
|
||||
|
||||
cinvoke libc_sprintf, [test_str2], format_str, str_var, [dec_var], dword [float_var], dword[float_var+4], [hex_var]
|
||||
cinvoke libc_puts, test_str1
|
||||
cinvoke libc_puts, [test_str2]
|
||||
|
||||
cinvoke libc_strcmp, test_str1, [test_str2]
|
||||
|
||||
test eax, eax
|
||||
jz print_succ
|
||||
jmp print_fail
|
||||
|
||||
print_succ:
|
||||
cinvoke libc_puts, success_msg
|
||||
jmp exit
|
||||
|
||||
print_fail:
|
||||
cinvoke libc_puts, failed_msg
|
||||
|
||||
exit:
|
||||
mcall SF_SYS_MISC, SSF_MEM_FREE, [test_str2]
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
; data
|
||||
|
||||
format_str db "%s %d %f 0x%x", 0
|
||||
test_str1 db "Test 463 -26.432100 0x9d81", 0
|
||||
test_str2 dd 0
|
||||
|
||||
str_var db "Test",0
|
||||
dec_var dd 463
|
||||
float_var dq -26.4321
|
||||
hex_var dd 40321
|
||||
|
||||
success_msg db "Test successful!", 0
|
||||
failed_msg db "Test failed!", 0
|
||||
|
||||
align 4
|
||||
|
||||
@IMPORT:
|
||||
library libc, 'libc.obj'
|
||||
import libc, \
|
||||
libc_sprintf, 'sprintf', \
|
||||
libc_strcmp, 'strcmp', \
|
||||
libc_strlen, 'strlen', \
|
||||
libc_puts, 'puts'
|
||||
|
||||
IM_END:
|
||||
align 4
|
||||
rb 1024 ; stack
|
||||
MEM:
|
||||
50
programs/develop/ktcc/trunk/libc.obj/samples/file_io.c
Normal file
50
programs/develop/ktcc/trunk/libc.obj/samples/file_io.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define READ_MAX 255
|
||||
|
||||
static char test_str1[] = "123454567890abcdefghijklmnopqrstufvwxyz";
|
||||
static char test_str2[READ_MAX];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i=0;
|
||||
FILE *f;
|
||||
|
||||
//write to file
|
||||
debug_printf("Write file...\n");
|
||||
f=fopen("testfile.txt","w");
|
||||
|
||||
while(test_str1[i]!='a'){
|
||||
fputc(test_str1[i],f);
|
||||
i++;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
//append to file
|
||||
debug_printf("Apend file...\n");
|
||||
f=fopen("testfile.txt","a");
|
||||
fputs(test_str1+i,f);
|
||||
char null_term = '\0';
|
||||
fwrite(&null_term, sizeof(char), 1, f);
|
||||
printf("Error: %s\n",strerror(errno));
|
||||
fclose(f);
|
||||
|
||||
//copy from testfile.txt to copyfile.txt
|
||||
debug_printf("Read file...\n");
|
||||
f=fopen("testfile.txt","r");
|
||||
i=0;
|
||||
while((test_str2[i]=fgetc(f))!=EOF && i<READ_MAX){
|
||||
fputc(test_str2[i], stdout);
|
||||
i++;
|
||||
}
|
||||
printf("\n%s\n", test_str1);
|
||||
if(!strcmp(test_str2, test_str1)){
|
||||
puts("TEST: OK!");
|
||||
}else{
|
||||
puts("TEST: FAIL!");
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
61
programs/develop/ktcc/trunk/libc.obj/samples/http_tcp_demo.c
Normal file
61
programs/develop/ktcc/trunk/libc.obj/samples/http_tcp_demo.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <clayer/network.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int errno;
|
||||
|
||||
int main() {
|
||||
networklib_init();
|
||||
|
||||
char *host = "kolibrios.org";
|
||||
int port = 80;
|
||||
printf("Connecting to %s on port %d\n", host, port);
|
||||
struct addrinfo *addr_info;
|
||||
char port_str[16]; sprintf(port_str, "%d", port);
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 doesnt matter
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
|
||||
if (getaddrinfo(host, port_str, 0, &addr_info) != 0) {
|
||||
printf("Host %s not found!\n", host);
|
||||
freeaddrinfo(addr_info);
|
||||
exit(-1);
|
||||
}
|
||||
printf("IP address of %s is %s\n", host, inet_ntoa(addr_info->ai_addr->sin_addr));
|
||||
//printf("Host port = %d\n", addr_info->ai_addr->sin_port >> 8);
|
||||
|
||||
char request[256];
|
||||
sprintf(request, "GET /en/ HTTP/1.1\r\nHost: %s\r\n\r\n", host);
|
||||
printf("request = %s\n", request);
|
||||
|
||||
int sock = socket(AF_INET4, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
puts("Connecting...\n");
|
||||
if (connect(sock, addr_info->ai_addr, addr_info->ai_addrlen) != 0) {
|
||||
printf("Connection failed, errno = %d\n", errno);
|
||||
exit(errno);
|
||||
}
|
||||
puts("Connected successfully\n");
|
||||
|
||||
puts("Sending request...\n");
|
||||
if (send(sock, request, strlen(request), MSG_NOFLAG) == -1) {
|
||||
printf("Sending failed, errno = %d\n", errno);
|
||||
exit(errno);
|
||||
}
|
||||
puts("Request sended successfully, waiting for response...\n");
|
||||
|
||||
char buf[512 + 1];
|
||||
if (recv(sock, buf, 512, MSG_NOFLAG) == -1) {
|
||||
printf("Receive failed, errno = %d\n", errno);
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
printf("Response = %s\n", buf);
|
||||
|
||||
freeaddrinfo(addr_info);
|
||||
|
||||
close(sock);
|
||||
puts("\n goodbye)\n");
|
||||
exit(0);
|
||||
}
|
||||
43
programs/develop/ktcc/trunk/libc.obj/samples/math_test.c
Normal file
43
programs/develop/ktcc/trunk/libc.obj/samples/math_test.c
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
printf("------------------------------------------------------\n");
|
||||
// printf ( "remainder of 5.3 / 2 is %f\n", remainder (5.3,2) );
|
||||
// printf ( "remainder of 18.5 / 4.2 is %f\n", remainder (18.5,4.2) );
|
||||
//remainder of 5.3 / 2 is -0.700000
|
||||
//remainder of 18.5 / 4.2 is 1.700000
|
||||
|
||||
printf ( "fmod of 5.3 / 2 is %f\n", fmod (5.3,2) );
|
||||
printf ( "fmod of 18.5 / 4.2 is %f\n", fmod (18.5,4.2) );
|
||||
// fmod of 5.3 / 2 is 1.300000
|
||||
// fmod of 18.5 / 4.2 is 1.700000
|
||||
|
||||
double param, fractpart, intpart, result;
|
||||
int n;
|
||||
|
||||
param = 3.14159265;
|
||||
fractpart = modf (param , &intpart);
|
||||
printf ("%f = %f + %f \n", param, intpart, fractpart);
|
||||
//3.141593 = 3.000000 + 0.141593
|
||||
|
||||
param = 0.95;
|
||||
n = 4;
|
||||
result = ldexp (param , n);
|
||||
printf ("%f * 2^%d = %f\n", param, n, result);
|
||||
//0.950000 * 2^4 = 15.200000
|
||||
|
||||
param = 8.0;
|
||||
result = frexp (param , &n);
|
||||
printf ("%f = %f * 2^%d\n", param, result, n);
|
||||
//8.000000 = 0.500000 * 2^4
|
||||
param = 50;
|
||||
result = frexp (param , &n);
|
||||
printf ("%f = %f * 2^%d\n", param, result, n);
|
||||
|
||||
}
|
||||
}
|
||||
19
programs/develop/ktcc/trunk/libc.obj/samples/stdio_test.c
Normal file
19
programs/develop/ktcc/trunk/libc.obj/samples/stdio_test.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <sys/ksys.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
char* test_string1 = "Hello world!";
|
||||
int a, b;
|
||||
|
||||
int main(int argc, char** argv){
|
||||
sscanf("43 53","%d %d",&a, &b);
|
||||
printf("(43 53) = (%d %d)\n", a, b);
|
||||
printf("Hello world! = %s\n", test_string1);
|
||||
printf("345.358980 = %f\n", 345.35898);
|
||||
printf("345 = %d\n", (int)345.35898);
|
||||
printf("ff = %x\n", 255);
|
||||
printf("-1 = %d\n", UINT_MAX);
|
||||
printf("5A-4B-N$ = %s%c-%u%c-N%c\n", "5", 'A', 4, 'B', '$');
|
||||
puts("Done!");
|
||||
return 0;
|
||||
}
|
||||
18
programs/develop/ktcc/trunk/libc.obj/samples/string_test.c
Normal file
18
programs/develop/ktcc/trunk/libc.obj/samples/string_test.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <errno.h>
|
||||
#include <sys/ksys.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
char hello1[]="Hello, KolibriOS!";
|
||||
char hello2[20];
|
||||
memcpy(hello1, hello2, strlen(hello1));
|
||||
if(!_ksys_strcmp(hello1, hello2)){
|
||||
printf("memcpy: Successfully!\n");
|
||||
return 0;
|
||||
} else{
|
||||
printf("memcpy: Failure\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
56
programs/develop/ktcc/trunk/libc.obj/samples/tmpdisk_work.c
Normal file
56
programs/develop/ktcc/trunk/libc.obj/samples/tmpdisk_work.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "stddef.h"
|
||||
#include <sys/ksys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEV_ADD_DISK 1
|
||||
|
||||
#define TMPDISK_SIZE 10 //Mb
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct{
|
||||
unsigned disk_size;
|
||||
unsigned char disk_id;
|
||||
}tmpdisk_add;
|
||||
#pragma pack(pop)
|
||||
|
||||
char *tmpdisk_res_text[]={
|
||||
"TmpDisk operation completed successfully",
|
||||
"Unknown IOCTL code, wrong input/output size...",
|
||||
"DiskId must be from 0 to 9",
|
||||
"DiskSize is too large",
|
||||
"DiskSize is too small, might be too little free RAM",
|
||||
"Memory allocation failed",
|
||||
"Unknown error O_o",
|
||||
0};
|
||||
|
||||
|
||||
int main(){
|
||||
ksys_drv_hand_t tmpdisk_drv = _ksys_load_driver("tmpdisk");
|
||||
if(!tmpdisk_drv){
|
||||
puts("tmpdisk.sys driver not load!");
|
||||
exit(0);
|
||||
}else{
|
||||
puts("tmpdisk.sys driver is load!");
|
||||
}
|
||||
|
||||
tmpdisk_add.disk_size = TMPDISK_SIZE*1024*1024/512;
|
||||
tmpdisk_add.disk_id = 5;
|
||||
|
||||
ksys_ioctl_t ioctl;
|
||||
ioctl.func_num = DEV_ADD_DISK;
|
||||
ioctl.handler = tmpdisk_drv;
|
||||
ioctl.in_data_ptr = &tmpdisk_add;
|
||||
ioctl.in_data_size = sizeof(tmpdisk_add);
|
||||
ioctl.out_data_ptr = NULL;
|
||||
ioctl.out_data_size = 0;
|
||||
|
||||
printf("Create '/tmp%u/' disk a %u Mb size...\n", tmpdisk_add.disk_id, TMPDISK_SIZE);
|
||||
unsigned status =_ksys_work_driver(&ioctl);
|
||||
if(status<7){
|
||||
puts(tmpdisk_res_text[status]);
|
||||
}else{
|
||||
puts(tmpdisk_res_text[6]);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
301
programs/develop/ktcc/trunk/libc.obj/samples/whois.c
Normal file
301
programs/develop/ktcc/trunk/libc.obj/samples/whois.c
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
WHOIS port for KolibriOS (Adapted by turbocat2001).
|
||||
The main code is taken from the site:
|
||||
https://www.binarytides.com/whois-client-code-in-c-with-linux-sockets/
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
int errno;
|
||||
|
||||
#include "sys/ksys.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <clayer/network.h>
|
||||
#include <conio.h>
|
||||
|
||||
FILE *out=stdout;
|
||||
|
||||
#ifdef DEBUG
|
||||
FILE *out=stderr;
|
||||
#endif
|
||||
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
#define fprintf fprintf
|
||||
|
||||
void show_help()
|
||||
{
|
||||
puts("Usage: whois <host> [-f <file>]\n");
|
||||
puts(" host Connect to server host");
|
||||
puts(" -f file Redirecting output to file\n");
|
||||
puts("Example: whois google.com -f my.txt");
|
||||
}
|
||||
|
||||
int get_whois_data(char * , char **);
|
||||
int hostname_to_ip(char * , char *);
|
||||
int whois_query(char * , char * , char **);
|
||||
char *str_replace(char *search , char *replace , char *subject );
|
||||
char* str_copy(char*);
|
||||
|
||||
|
||||
int main(int argc , char *argv[])
|
||||
{
|
||||
networklib_init();
|
||||
char *domain , *data = NULL;
|
||||
int f_flag=0;
|
||||
|
||||
if(argc==2){
|
||||
domain=strdup(argv[1]);
|
||||
}
|
||||
|
||||
else if(!strcmp(argv[2], "-f") && argc==4){
|
||||
domain=strdup(argv[1]);
|
||||
if((out=fopen(argv[3],"w"))==NULL){
|
||||
printf("Error writing to file: '%s' !\n", argv[3]);
|
||||
exit(0);
|
||||
}
|
||||
}else{
|
||||
show_help();
|
||||
exit(0);
|
||||
}
|
||||
if(out==stdout){
|
||||
con_init();
|
||||
(*con_set_title)("Whois");
|
||||
}
|
||||
get_whois_data(domain , &data);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Get the whois data of a domain
|
||||
*/
|
||||
|
||||
int get_whois_data(char *domain , char **data)
|
||||
{
|
||||
char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt;
|
||||
|
||||
//remove "http://" and "www."
|
||||
domain = str_replace("http://" , "" , domain);
|
||||
domain = str_replace("www." , "" , domain);
|
||||
|
||||
//get the extension , com , org , edu
|
||||
dt = strdup(domain);
|
||||
|
||||
if(dt == NULL){
|
||||
fprintf(out, "strdup failed");
|
||||
}
|
||||
pch = (char*)strtok(dt , ".");
|
||||
while(pch != NULL){
|
||||
strcpy(ext , pch);
|
||||
pch = strtok(NULL , ".");
|
||||
}
|
||||
// This will tell the whois server for the particular TLD like com , org
|
||||
if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE){
|
||||
fprintf(out, "Whois query failed");
|
||||
return 1;
|
||||
}
|
||||
fprintf(out, "\n\nResponse is:\n\n");
|
||||
fprintf(out, "%s", response);
|
||||
|
||||
// Now analysze the response
|
||||
pch = strtok(response , "\n");
|
||||
while(pch != NULL){
|
||||
// Check if whois line
|
||||
wch = strstr(pch , "whois.");
|
||||
if(wch != NULL){
|
||||
break;
|
||||
}
|
||||
|
||||
// Next line please
|
||||
pch = strtok(NULL , "\n");
|
||||
}
|
||||
// Now we have the TLD whois server in wch , query again
|
||||
//This will provide minimal whois information along with the parent whois server of the specific domain :)
|
||||
wch = strdup(wch);
|
||||
free(response);
|
||||
//This should not be necessary , but segmentation fault without this , why ?
|
||||
response = NULL;
|
||||
if(wch != NULL){
|
||||
fprintf(out,"\nTLD Whois server is : %s" , wch);
|
||||
if( whois_query(wch , domain , &response) == EXIT_FAILURE){
|
||||
fprintf(out, "Whois query failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}else{
|
||||
fprintf(out, "\nTLD whois server for %s not found\n" , ext);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
response_2 = strdup(response);
|
||||
|
||||
// Again search for a whois server in this response. :)
|
||||
pch = strtok(response , "\n");
|
||||
while(pch != NULL){
|
||||
// Check if whois line
|
||||
wch = strstr(pch , "whois.");
|
||||
if(wch != NULL){
|
||||
break;
|
||||
}
|
||||
//Next line please
|
||||
pch = strtok(NULL , "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
If a registrar whois server is found then query it
|
||||
*/
|
||||
if(wch){
|
||||
// Now we have the registrar whois server , this has the direct full information of the particular domain
|
||||
// so lets query again
|
||||
|
||||
fprintf(out, "\nRegistrar Whois server is : %s" , wch);
|
||||
|
||||
if( whois_query(wch , domain , &response) == EXIT_FAILURE ){
|
||||
fprintf(out, "Whois query failed");
|
||||
}else{
|
||||
fprintf(out, "\n%s" , response);
|
||||
}
|
||||
}
|
||||
/*
|
||||
otherwise echo the output from the previous whois result
|
||||
*/
|
||||
else{
|
||||
fprintf(out, "%s" , response_2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Perform a whois query to a server and record the response
|
||||
*/
|
||||
int whois_query(char *server , char *query , char **response)
|
||||
{
|
||||
char ip[32] , message[100] , buffer[1500];
|
||||
int sock , read_size , total_size = 0;
|
||||
int WHOIS_PORT = 43;
|
||||
struct sockaddr dest;
|
||||
|
||||
sock = socket(AF_INET4 , SOCK_STREAM , IPPROTO_TCP);
|
||||
|
||||
//Prepare connection structures :)
|
||||
memset(&dest , 0 , sizeof(dest) );
|
||||
dest.sin_family = AF_INET;
|
||||
server = str_copy(server);
|
||||
|
||||
server[strcspn(server, "\r\n")] = '\0';
|
||||
fprintf(out, "\nResolving: %s ...\n" , server);
|
||||
if(hostname_to_ip(server , ip) == EXIT_FAILURE ){
|
||||
fprintf(out, "Failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
fprintf(out, "Found ip: %s \n" , ip);
|
||||
dest.sin_addr = inet_addr(ip);
|
||||
dest.sin_port = PORT(WHOIS_PORT);
|
||||
|
||||
; //Now connect to remote server
|
||||
if(connect(sock , (const struct sockaddr*) &dest , sizeof(dest)) < 0){
|
||||
perror("connect failed");
|
||||
perror(strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
//Now send some data or message
|
||||
fprintf(out, "\nQuerying for: %s ...\n" , query);
|
||||
sprintf(message , "%s\r\n" , query);
|
||||
if( send(sock , message , strlen(message) , 0) < 0){
|
||||
perror("send failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
//Now receive the response
|
||||
while((read_size = recv(sock, buffer, sizeof(buffer), 0))){
|
||||
*response = realloc(*response , read_size + total_size);
|
||||
if(*response == NULL){
|
||||
fprintf(out, "realloc failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
memcpy(*response + total_size , buffer , read_size);
|
||||
total_size += read_size;
|
||||
}
|
||||
|
||||
fprintf(out, "Done\n");
|
||||
|
||||
*response = realloc(*response , total_size + 1);
|
||||
*(*response + total_size) = '\0';
|
||||
close(sock);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
/*
|
||||
Get the ip address of a given hostname
|
||||
*/
|
||||
int hostname_to_ip(char *hostname , char *ip)
|
||||
{
|
||||
struct addrinfo *addr_info;
|
||||
char port_str[16]; sprintf(port_str, "%d", 80);
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 doesnt matter
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
|
||||
if (getaddrinfo(hostname, port_str, 0, &addr_info) != 0) {
|
||||
freeaddrinfo(addr_info);
|
||||
return EXIT_FAILURE;
|
||||
}else{
|
||||
strcpy(ip, inet_ntoa(addr_info->ai_addr->sin_addr));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Search and replace a string with another string , in a string
|
||||
*/
|
||||
char *str_replace(char *search , char *replace , char *subject)
|
||||
{
|
||||
char *p = NULL , *old = NULL , *new_subject = NULL ;
|
||||
int c = 0 , search_size;
|
||||
|
||||
search_size = strlen(search);
|
||||
|
||||
//Count how many occurences
|
||||
for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)){
|
||||
c++;
|
||||
}
|
||||
//Final size
|
||||
c = ( strlen(replace) - search_size )*c + strlen(subject);
|
||||
|
||||
//New subject with new size
|
||||
new_subject = malloc( c );
|
||||
|
||||
//Set it to blank
|
||||
strcpy(new_subject , "");
|
||||
|
||||
//The start position
|
||||
old = subject;
|
||||
|
||||
for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)){
|
||||
//move ahead and copy some text from original subject , from a certain position
|
||||
strncpy(new_subject + strlen(new_subject) , old , p - old);
|
||||
|
||||
//move ahead and copy the replacement text
|
||||
strcpy(new_subject + strlen(new_subject) , replace);
|
||||
|
||||
//The new start position after this search match
|
||||
old = p + search_size;
|
||||
}
|
||||
|
||||
//Copy the part after the last search match
|
||||
strcpy(new_subject + strlen(new_subject) , old);
|
||||
|
||||
return new_subject;
|
||||
}
|
||||
|
||||
char* str_copy(char *source)
|
||||
{
|
||||
char *copy = malloc(strlen(source) + 1);
|
||||
|
||||
if(copy){
|
||||
strcpy(copy, source);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
Reference in New Issue
Block a user