2011-12-11 03:45:04 +04:00
|
|
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
|
|
|
*/
|
2011-01-16 04:01:19 +03:00
|
|
|
#ifndef __SYSTEM_H
|
|
|
|
#define __SYSTEM_H
|
2011-03-22 07:57:24 +03:00
|
|
|
#define _KERNEL_
|
2011-02-22 08:51:06 +03:00
|
|
|
#include <types.h>
|
2011-04-17 05:01:04 +04:00
|
|
|
#include <fs.h>
|
2011-02-22 04:36:18 +03:00
|
|
|
|
2011-03-29 22:49:15 +04:00
|
|
|
/* Binary Literals */
|
|
|
|
#define b(x) ((uint8_t)b_(0 ## x ## uL))
|
|
|
|
#define b_(x) ((x & 1) | (x >> 2 & 2) | (x >> 4 & 4) | (x >> 6 & 8) | (x >> 8 & 16) | (x >> 10 & 32) | (x >> 12 & 64) | (x >> 14 & 128))
|
2011-03-22 07:57:24 +03:00
|
|
|
|
2011-01-19 09:04:27 +03:00
|
|
|
/* Unimportant Kernel Strings */
|
|
|
|
#define KERNEL_UNAME "ToAruOS"
|
|
|
|
#define KERNEL_VERSION_STRING "0.0.1"
|
|
|
|
|
2011-10-31 10:17:26 +04:00
|
|
|
#define asm __asm__
|
|
|
|
#define volatile __volatile__
|
|
|
|
|
|
|
|
#define IRQ_OFF asm volatile ("cli")
|
|
|
|
#define IRQ_ON asm volatile ("sti")
|
|
|
|
#define PAUSE asm volatile ("hlt")
|
|
|
|
|
|
|
|
#define STOP while (1) { PAUSE; }
|
2011-10-27 04:11:05 +04:00
|
|
|
|
2011-01-31 02:00:38 +03:00
|
|
|
extern void *sbrk(uintptr_t increment);
|
2011-01-22 08:57:08 +03:00
|
|
|
|
2011-03-30 06:08:56 +04:00
|
|
|
extern void tss_flush();
|
2011-03-29 05:34:53 +04:00
|
|
|
|
2011-01-16 04:01:19 +03:00
|
|
|
/* Kernel Main */
|
2011-03-30 01:35:02 +04:00
|
|
|
extern int max(int,int);
|
|
|
|
extern int abs(int);
|
|
|
|
extern void swap(int *, int *);
|
2011-01-31 02:00:38 +03:00
|
|
|
extern void *memcpy(void *restrict dest, const void *restrict src, size_t count);
|
2011-03-29 04:34:44 +04:00
|
|
|
extern void *memmove(void *restrict dest, const void *restrict src, size_t count);
|
2011-01-18 03:22:48 +03:00
|
|
|
extern void *memset(void *dest, int val, size_t count);
|
2011-01-16 04:01:19 +03:00
|
|
|
extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
|
2011-11-18 01:55:59 +04:00
|
|
|
extern uint32_t strlen(const char *str);
|
2011-02-11 06:45:29 +03:00
|
|
|
extern int atoi(const char *str);
|
2011-01-31 02:00:38 +03:00
|
|
|
extern unsigned char inportb(unsigned short _port);
|
|
|
|
extern void outportb(unsigned short _port, unsigned char _data);
|
2011-03-26 06:29:54 +03:00
|
|
|
extern unsigned short inports(unsigned short _port);
|
|
|
|
extern void outports(unsigned short _port, unsigned short _data);
|
2011-03-29 04:34:44 +04:00
|
|
|
extern unsigned int inportl(unsigned short _port);
|
|
|
|
extern void outportl(unsigned short _port, unsigned int _data);
|
2011-02-07 23:30:17 +03:00
|
|
|
extern int strcmp(const char *a, const char *b);
|
|
|
|
extern char * strtok_r(char * str, const char * delim, char ** saveptr);
|
|
|
|
extern size_t lfind(const char * str, const char accept);
|
2011-11-02 03:51:15 +04:00
|
|
|
extern size_t rfind(const char * str, const char accept);
|
2011-02-07 23:30:17 +03:00
|
|
|
extern size_t strspn(const char * str, const char * accept);
|
|
|
|
extern char * strpbrk(const char * str, const char * accept);
|
2011-03-26 06:29:54 +03:00
|
|
|
extern uint32_t krand();
|
2011-11-27 01:25:59 +04:00
|
|
|
extern char * strstr(const char * haystack, const char * needle);
|
|
|
|
extern uint8_t startswith(const char * str, const char * accept);
|
2011-01-16 04:01:19 +03:00
|
|
|
|
|
|
|
/* VGA driver */
|
|
|
|
extern void cls();
|
2011-01-16 19:56:44 +03:00
|
|
|
extern void puts(char *str);
|
2011-01-16 04:01:19 +03:00
|
|
|
extern void settextcolor(unsigned char forecolor, unsigned char backcolor);
|
2011-01-19 09:04:27 +03:00
|
|
|
extern void resettextcolor();
|
2011-03-25 04:24:59 +03:00
|
|
|
extern void brighttextcolor();
|
2011-01-16 04:01:19 +03:00
|
|
|
extern void init_video();
|
2011-02-11 00:13:33 +03:00
|
|
|
extern void placech(unsigned char c, int x, int y, int attr);
|
|
|
|
extern void writechf(unsigned char c);
|
2011-02-07 23:30:17 +03:00
|
|
|
extern void writech(unsigned char c);
|
2011-03-25 04:03:52 +03:00
|
|
|
extern void place_csr(uint32_t x, uint32_t y);
|
2011-03-25 04:18:14 +03:00
|
|
|
extern void store_csr();
|
|
|
|
extern void restore_csr();
|
|
|
|
extern void set_serial(int);
|
2011-03-25 08:13:44 +03:00
|
|
|
extern void set_csr(int);
|
2011-01-16 04:01:19 +03:00
|
|
|
|
2011-01-16 04:59:11 +03:00
|
|
|
/* GDT */
|
|
|
|
extern void gdt_install();
|
2011-01-31 02:00:38 +03:00
|
|
|
extern void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access,
|
|
|
|
unsigned char gran);
|
2011-03-30 06:08:56 +04:00
|
|
|
extern void set_kernel_stack(uintptr_t stack);
|
2011-01-16 04:59:11 +03:00
|
|
|
|
2011-01-16 06:41:17 +03:00
|
|
|
/* IDT */
|
|
|
|
extern void idt_install();
|
2011-01-31 02:00:38 +03:00
|
|
|
extern void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel,
|
|
|
|
unsigned char flags);
|
2011-01-16 06:41:17 +03:00
|
|
|
|
|
|
|
/* Registers */
|
|
|
|
struct regs {
|
2011-01-31 02:00:38 +03:00
|
|
|
unsigned int gs, fs, es, ds;
|
|
|
|
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
|
|
|
unsigned int int_no, err_code;
|
|
|
|
unsigned int eip, cs, eflags, useresp, ss;
|
2011-01-16 06:41:17 +03:00
|
|
|
};
|
|
|
|
|
2011-01-31 02:00:38 +03:00
|
|
|
typedef void (*irq_handler_t) (struct regs *);
|
2011-01-18 03:22:48 +03:00
|
|
|
|
2011-03-30 11:16:30 +04:00
|
|
|
/* Panic */
|
|
|
|
#define HALT_AND_CATCH_FIRE(mesg, regs) halt_and_catch_fire(mesg, __FILE__, __LINE__, regs)
|
|
|
|
#define ASSERT(statement) ((statement) ? (void)0 : assert_failed(__FILE__, __LINE__, #statement))
|
|
|
|
#define assert(statement) ((statement) ? (void)0 : assert_failed(__FILE__, __LINE__, #statement))
|
|
|
|
void halt_and_catch_fire(char *error_message, const char *file, int line, struct regs * regs);
|
|
|
|
void assert_failed(const char *file, uint32_t line, const char *desc);
|
|
|
|
|
2011-01-16 19:56:44 +03:00
|
|
|
/* ISRS */
|
|
|
|
extern void isrs_install();
|
2011-01-21 04:49:35 +03:00
|
|
|
extern void isrs_install_handler(int isrs, irq_handler_t);
|
|
|
|
extern void isrs_uninstall_handler(int isrs);
|
2011-01-16 19:56:44 +03:00
|
|
|
|
2011-01-16 07:17:42 +03:00
|
|
|
/* Interrupt Handlers */
|
|
|
|
extern void irq_install();
|
2011-01-18 03:22:48 +03:00
|
|
|
extern void irq_install_handler(int irq, irq_handler_t);
|
2011-01-16 07:17:42 +03:00
|
|
|
extern void irq_uninstall_handler(int irq);
|
2011-05-07 10:55:49 +04:00
|
|
|
extern void irq_gates();
|
2011-01-16 07:17:42 +03:00
|
|
|
|
2011-01-16 19:56:44 +03:00
|
|
|
/* Timer */
|
|
|
|
extern void timer_install();
|
2011-01-18 03:22:48 +03:00
|
|
|
extern long timer_ticks;
|
2011-01-16 19:56:44 +03:00
|
|
|
extern void timer_wait(int ticks);
|
|
|
|
|
2011-01-16 21:45:51 +03:00
|
|
|
/* Keyboard */
|
2011-02-07 23:30:17 +03:00
|
|
|
typedef void (*keyboard_buffer_t)(char ch);
|
|
|
|
keyboard_buffer_t keyboard_buffer_handler;
|
2011-04-30 12:40:36 +04:00
|
|
|
keyboard_buffer_t keyboard_direct_handler;
|
2011-01-16 21:45:51 +03:00
|
|
|
extern void keyboard_install();
|
|
|
|
extern void keyboard_wait();
|
2011-02-07 23:30:17 +03:00
|
|
|
extern void putch(unsigned char c);
|
2011-04-05 03:51:55 +04:00
|
|
|
extern void set_kbd(int,int,int);
|
2011-01-16 21:45:51 +03:00
|
|
|
|
2011-10-30 05:33:24 +04:00
|
|
|
/* Mouse */
|
|
|
|
extern void mouse_install();
|
|
|
|
|
2011-01-17 19:24:55 +03:00
|
|
|
/* kprintf */
|
|
|
|
extern void kprintf(const char *fmt, ...);
|
2011-11-18 01:55:59 +04:00
|
|
|
extern int sprintf(char *buf, const char *fmt, ...);
|
|
|
|
extern int kgets(char *buf, int size);
|
2011-11-24 07:22:25 +04:00
|
|
|
typedef void (*kgets_redraw_t)();
|
|
|
|
extern kgets_redraw_t kgets_redraw_func;
|
2011-11-25 04:59:23 +04:00
|
|
|
typedef void (*kgets_tab_complete_t)(char *);
|
|
|
|
extern kgets_tab_complete_t kgets_tab_complete_func;
|
|
|
|
extern void kgets_redraw_buffer();
|
2011-11-27 02:14:35 +04:00
|
|
|
typedef void (*kgets_special_t)(char *);
|
|
|
|
extern kgets_special_t kgets_key_down;
|
|
|
|
extern kgets_special_t kgets_key_up;
|
|
|
|
extern kgets_special_t kgets_key_left;
|
|
|
|
extern kgets_special_t kgets_key_right;
|
2011-01-17 19:24:55 +03:00
|
|
|
|
2011-01-21 04:49:35 +03:00
|
|
|
/* Memory Management */
|
|
|
|
extern uintptr_t placement_pointer;
|
2011-01-22 10:38:25 +03:00
|
|
|
extern void kmalloc_startat(uintptr_t address);
|
2011-01-21 04:49:35 +03:00
|
|
|
extern uintptr_t kmalloc_real(size_t size, int align, uintptr_t * phys);
|
|
|
|
extern uintptr_t kmalloc(size_t size);
|
|
|
|
extern uintptr_t kvmalloc(size_t size);
|
|
|
|
extern uintptr_t kmalloc_p(size_t size, uintptr_t * phys);
|
|
|
|
extern uintptr_t kvmalloc_p(size_t size, uintptr_t * phys);
|
|
|
|
|
|
|
|
typedef struct page {
|
2011-01-31 02:00:38 +03:00
|
|
|
uint32_t present:1;
|
|
|
|
uint32_t rw:1;
|
|
|
|
uint32_t user:1;
|
|
|
|
uint32_t accessed:1;
|
|
|
|
uint32_t dirty:1;
|
|
|
|
uint32_t unused:7;
|
|
|
|
uint32_t frame:20;
|
2011-01-21 04:49:35 +03:00
|
|
|
} page_t;
|
|
|
|
|
|
|
|
typedef struct page_table {
|
|
|
|
page_t pages[1024];
|
|
|
|
} page_table_t;
|
|
|
|
|
|
|
|
typedef struct page_directory {
|
2011-01-31 02:00:38 +03:00
|
|
|
page_table_t *tables[1024]; /* 1024 pointers to page tables... */
|
|
|
|
uintptr_t physical_tables[1024]; /* Physical addresses of the tables */
|
|
|
|
uintptr_t physical_address; /* The physical address of physical_tables */
|
2011-01-21 04:49:35 +03:00
|
|
|
} page_directory_t;
|
|
|
|
|
2011-01-31 02:00:38 +03:00
|
|
|
page_directory_t *kernel_directory;
|
|
|
|
page_directory_t *current_directory;
|
2011-01-21 04:49:35 +03:00
|
|
|
|
|
|
|
extern void paging_install(uint32_t memsize);
|
2011-01-31 02:00:38 +03:00
|
|
|
extern void switch_page_directory(page_directory_t * new);
|
|
|
|
extern page_t *get_page(uintptr_t address, int make, page_directory_t * dir);
|
2011-01-21 04:49:35 +03:00
|
|
|
extern void page_fault(struct regs *r);
|
2011-03-29 23:43:39 +04:00
|
|
|
extern void dma_frame(page_t * page, int, int, uintptr_t);
|
2011-12-07 05:43:45 +04:00
|
|
|
extern void debug_print_directory();
|
2011-01-21 04:49:35 +03:00
|
|
|
|
2011-01-22 09:03:26 +03:00
|
|
|
void heap_install();
|
2011-01-21 04:49:35 +03:00
|
|
|
|
2011-03-02 02:48:39 +03:00
|
|
|
void alloc_frame(page_t *page, int is_kernel, int is_writeable);
|
2011-04-09 02:53:52 +04:00
|
|
|
void free_frame(page_t *page);
|
2011-03-02 02:48:39 +03:00
|
|
|
|
2011-01-22 08:57:08 +03:00
|
|
|
/* klmalloc */
|
|
|
|
void * __attribute__ ((malloc)) malloc(size_t size);
|
2011-01-31 02:00:38 +03:00
|
|
|
void * __attribute__ ((malloc)) realloc(void *ptr, size_t size);
|
2011-01-22 08:57:08 +03:00
|
|
|
void * __attribute__ ((malloc)) calloc(size_t nmemb, size_t size);
|
2011-02-28 07:00:08 +03:00
|
|
|
void * __attribute__ ((malloc)) valloc(size_t size);
|
2011-01-31 02:00:38 +03:00
|
|
|
void free(void *ptr);
|
2011-01-21 04:49:35 +03:00
|
|
|
|
2011-02-07 23:30:17 +03:00
|
|
|
/* shell */
|
|
|
|
extern void start_shell();
|
|
|
|
|
2011-02-11 06:45:29 +03:00
|
|
|
/* Serial */
|
|
|
|
extern void serial_install();
|
|
|
|
extern char serial_recv();
|
|
|
|
extern void serial_send(char out);
|
2011-04-05 03:51:55 +04:00
|
|
|
extern void serial_string(char * out);
|
2011-02-11 06:45:29 +03:00
|
|
|
|
2011-03-02 02:48:39 +03:00
|
|
|
/* Tasks */
|
2011-04-09 00:27:12 +04:00
|
|
|
extern uintptr_t read_eip();
|
|
|
|
extern void copy_page_physical(uint32_t, uint32_t);
|
|
|
|
extern page_directory_t * clone_directory(page_directory_t * src);
|
|
|
|
extern page_table_t * clone_table(page_table_t * src, uintptr_t * physAddr);
|
|
|
|
extern void move_stack(void *new_stack_start, size_t size);
|
|
|
|
extern void kexit(int retval);
|
2011-04-09 01:26:34 +04:00
|
|
|
extern void task_exit(int retval);
|
2011-04-13 00:48:00 +04:00
|
|
|
extern uint32_t next_pid;
|
2011-03-30 06:08:56 +04:00
|
|
|
|
|
|
|
typedef struct tss_entry {
|
|
|
|
uint32_t prev_tss;
|
|
|
|
uint32_t esp0;
|
|
|
|
uint32_t ss0;
|
|
|
|
uint32_t esp1;
|
|
|
|
uint32_t ss1;
|
|
|
|
uint32_t esp2;
|
|
|
|
uint32_t ss2;
|
|
|
|
uint32_t cr3;
|
|
|
|
uint32_t eip;
|
|
|
|
uint32_t eflags;
|
|
|
|
uint32_t eax;
|
|
|
|
uint32_t ecx;
|
|
|
|
uint32_t edx;
|
|
|
|
uint32_t ebx;
|
|
|
|
uint32_t esp;
|
|
|
|
uint32_t ebp;
|
|
|
|
uint32_t esi;
|
|
|
|
uint32_t edi;
|
|
|
|
uint32_t es;
|
|
|
|
uint32_t cs;
|
|
|
|
uint32_t ss;
|
|
|
|
uint32_t ds;
|
|
|
|
uint32_t fs;
|
|
|
|
uint32_t gs;
|
|
|
|
uint32_t ldt;
|
|
|
|
uint16_t trap;
|
|
|
|
uint16_t iomap_base;
|
|
|
|
} __attribute__ ((packed)) tss_entry_t;
|
|
|
|
|
2011-03-02 02:48:39 +03:00
|
|
|
extern void tasking_install();
|
|
|
|
extern void switch_task();
|
2011-12-09 01:25:48 +04:00
|
|
|
extern void switch_next();
|
2011-03-02 02:48:39 +03:00
|
|
|
extern uint32_t fork();
|
|
|
|
extern uint32_t getpid();
|
2011-04-18 02:44:29 +04:00
|
|
|
extern void enter_user_jmp(uintptr_t location, int argc, char ** argv, uintptr_t stack);
|
2011-03-02 02:48:39 +03:00
|
|
|
|
|
|
|
uintptr_t initial_esp;
|
2011-02-11 06:45:29 +03:00
|
|
|
|
2011-03-26 21:30:08 +03:00
|
|
|
/* Kernel Argument Parser */
|
|
|
|
extern void parse_args(char * argv);
|
|
|
|
|
2011-03-25 08:09:23 +03:00
|
|
|
/* CMOS */
|
|
|
|
extern void get_time(uint16_t * hours, uint16_t * minutes, uint16_t * seconds);
|
2011-04-05 03:51:55 +04:00
|
|
|
extern void get_date(uint16_t * month, uint16_t * day);
|
2011-03-25 08:09:23 +03:00
|
|
|
|
2011-04-17 22:26:31 +04:00
|
|
|
struct timeval {
|
|
|
|
uint32_t tv_sec;
|
|
|
|
uint32_t tv_usec;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern int gettimeofday(struct timeval * t, void * z);
|
2011-11-18 09:29:08 +04:00
|
|
|
extern uint32_t now();
|
2011-04-17 22:26:31 +04:00
|
|
|
|
|
|
|
|
2011-03-27 06:36:49 +04:00
|
|
|
/* CPU Detect by Brynet */
|
|
|
|
extern int detect_cpu();
|
|
|
|
|
2011-03-26 06:29:54 +03:00
|
|
|
/* Video Drivers */
|
|
|
|
/* BOCHS / QEMU VBE Driver */
|
|
|
|
extern void graphics_install_bochs();
|
2011-04-16 06:48:20 +04:00
|
|
|
extern void bochs_set_csr(int x, int y);
|
|
|
|
extern int bochs_get_csr_x();
|
|
|
|
extern int bochs_get_csr_y();
|
|
|
|
extern void bochs_set_csr_on(uint8_t);
|
2011-03-26 07:24:22 +03:00
|
|
|
extern void bochs_set_bank(uint16_t bank);
|
|
|
|
extern void bochs_set_coord(uint16_t x, uint16_t y, uint32_t color);
|
2011-03-29 00:18:48 +04:00
|
|
|
extern void bochs_fill_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color);
|
2011-03-27 22:41:00 +04:00
|
|
|
extern void bochs_draw_logo(char *);
|
2011-03-26 22:15:24 +03:00
|
|
|
extern void bochs_scroll();
|
2011-03-29 01:29:59 +04:00
|
|
|
extern void bochs_write_char(uint8_t val, uint16_t x, uint16_t y, uint32_t fg, uint32_t bg);
|
2011-03-29 00:18:48 +04:00
|
|
|
extern uint16_t bochs_resolution_x;
|
|
|
|
extern uint16_t bochs_resolution_y;
|
|
|
|
extern uint16_t bochs_resolution_b;
|
2011-03-29 04:34:44 +04:00
|
|
|
extern uint32_t bochs_colors[];
|
2011-04-05 03:51:55 +04:00
|
|
|
extern void bochs_set_y_offset(uint16_t y);
|
|
|
|
extern uint16_t bochs_current_scroll();
|
2011-03-29 04:34:44 +04:00
|
|
|
/* Terminal functions */
|
|
|
|
extern void bochs_term_clear();
|
|
|
|
extern void bochs_write(char c);
|
|
|
|
extern void bochs_reset_colors();
|
|
|
|
extern void bochs_set_colors(uint8_t, uint8_t);
|
2011-03-30 01:35:02 +04:00
|
|
|
extern void bochs_draw_line(uint16_t,uint16_t,uint16_t,uint16_t,uint32_t);
|
2011-04-16 06:48:20 +04:00
|
|
|
extern int bochs_get_width();
|
|
|
|
extern int bochs_get_height();
|
|
|
|
extern void bochs_set_cell(int x, int y, char c);
|
2011-04-30 04:54:07 +04:00
|
|
|
extern uintptr_t bochs_get_address();
|
2011-10-31 04:11:04 +04:00
|
|
|
extern void bochs_redraw_cell(int x, int y);
|
2011-11-01 02:41:16 +04:00
|
|
|
extern void bochs_install_wallpaper();
|
|
|
|
extern void bochs_screenshot();
|
2011-11-27 03:18:20 +04:00
|
|
|
extern void bochs_redraw_cursor();
|
2011-03-29 00:18:48 +04:00
|
|
|
|
2011-04-05 03:51:55 +04:00
|
|
|
/* ANSI Terminal Escape Processor */
|
|
|
|
void ansi_put(char c);
|
|
|
|
void ansi_print(char * c);
|
|
|
|
void ansi_init();
|
|
|
|
int ansi_ready;
|
|
|
|
|
2011-03-29 01:29:59 +04:00
|
|
|
extern uint8_t number_font[][12];
|
2011-03-26 06:29:54 +03:00
|
|
|
|
2011-03-30 01:35:02 +04:00
|
|
|
/* Floating Point Unit */
|
|
|
|
|
|
|
|
void set_fpu_cw(const uint16_t);
|
|
|
|
void enable_fpu();
|
|
|
|
|
2011-04-09 00:27:12 +04:00
|
|
|
/* ELF */
|
|
|
|
int exec( char *, int, char **);
|
2011-04-16 02:33:19 +04:00
|
|
|
int system( char *, int, char **);
|
2011-04-09 00:27:12 +04:00
|
|
|
|
2011-03-30 06:08:56 +04:00
|
|
|
/* Sytem Calls */
|
|
|
|
void syscalls_install();
|
|
|
|
|
2011-11-04 02:06:27 +04:00
|
|
|
/* PCI */
|
|
|
|
uint16_t pci_read_word(uint32_t bus, uint32_t slot, uint32_t func, uint16_t offset);
|
|
|
|
void pci_write_word(uint32_t bus, uint32_t slot, uint32_t func, uint16_t offset, uint32_t data);
|
|
|
|
|
2011-10-26 08:33:14 +04:00
|
|
|
/* IDE / PATA */
|
2011-11-01 02:41:16 +04:00
|
|
|
void ide_read_sector(uint16_t bus, uint8_t slave, uint32_t lba, uint8_t * buf);
|
|
|
|
void ide_write_sector(uint16_t bus, uint8_t slave, uint32_t lba, uint8_t * buf);
|
2011-10-26 08:33:14 +04:00
|
|
|
|
2011-01-16 04:01:19 +03:00
|
|
|
#endif
|