base init

This commit is contained in:
d1str4ught
2025-08-18 00:36:52 +02:00
parent cff3015742
commit 4e679320a3
527 changed files with 199969 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
file(GLOB_RECURSE LIBTHECORE_SOURCES "*.h" "*.cpp")
add_library(libthecore STATIC ${LIBTHECORE_SOURCES})
target_link_libraries(libthecore
common
)

326
src/libthecore/DES_table.h Normal file
View File

@@ -0,0 +1,326 @@
static DWORD SP_boxes[8][64]=
{
/* 0 */
{
0x00820200, 0x00020000, 0x80800000, 0x80820200,
0x00800000, 0x80020200, 0x80020000, 0x80800000,
0x80020200, 0x00820200, 0x00820000, 0x80000200,
0x80800200, 0x00800000, 0x00000000, 0x80020000,
0x00020000, 0x80000000, 0x00800200, 0x00020200,
0x80820200, 0x00820000, 0x80000200, 0x00800200,
0x80000000, 0x00000200, 0x00020200, 0x80820000,
0x00000200, 0x80800200, 0x80820000, 0x00000000,
0x00000000, 0x80820200, 0x00800200, 0x80020000,
0x00820200, 0x00020000, 0x80000200, 0x00800200,
0x80820000, 0x00000200, 0x00020200, 0x80800000,
0x80020200, 0x80000000, 0x80800000, 0x00820000,
0x80820200, 0x00020200, 0x00820000, 0x80800200,
0x00800000, 0x80000200, 0x80020000, 0x00000000,
0x00020000, 0x00800000, 0x80800200, 0x00820200,
0x80000000, 0x80820000, 0x00000200, 0x80020200
},
/* 1 */
{
0x10042004, 0x00000000, 0x00042000, 0x10040000,
0x10000004, 0x00002004, 0x10002000, 0x00042000,
0x00002000, 0x10040004, 0x00000004, 0x10002000,
0x00040004, 0x10042000, 0x10040000, 0x00000004,
0x00040000, 0x10002004, 0x10040004, 0x00002000,
0x00042004, 0x10000000, 0x00000000, 0x00040004,
0x10002004, 0x00042004, 0x10042000, 0x10000004,
0x10000000, 0x00040000, 0x00002004, 0x10042004,
0x00040004, 0x10042000, 0x10002000, 0x00042004,
0x10042004, 0x00040004, 0x10000004, 0x00000000,
0x10000000, 0x00002004, 0x00040000, 0x10040004,
0x00002000, 0x10000000, 0x00042004, 0x10002004,
0x10042000, 0x00002000, 0x00000000, 0x10000004,
0x00000004, 0x10042004, 0x00042000, 0x10040000,
0x10040004, 0x00040000, 0x00002004, 0x10002000,
0x10002004, 0x00000004, 0x10040000, 0x00042000
},
/* 2 */
{
0x41000000, 0x01010040, 0x00000040, 0x41000040,
0x40010000, 0x01000000, 0x41000040, 0x00010040,
0x01000040, 0x00010000, 0x01010000, 0x40000000,
0x41010040, 0x40000040, 0x40000000, 0x41010000,
0x00000000, 0x40010000, 0x01010040, 0x00000040,
0x40000040, 0x41010040, 0x00010000, 0x41000000,
0x41010000, 0x01000040, 0x40010040, 0x01010000,
0x00010040, 0x00000000, 0x01000000, 0x40010040,
0x01010040, 0x00000040, 0x40000000, 0x00010000,
0x40000040, 0x40010000, 0x01010000, 0x41000040,
0x00000000, 0x01010040, 0x00010040, 0x41010000,
0x40010000, 0x01000000, 0x41010040, 0x40000000,
0x40010040, 0x41000000, 0x01000000, 0x41010040,
0x00010000, 0x01000040, 0x41000040, 0x00010040,
0x01000040, 0x00000000, 0x41010000, 0x40000040,
0x41000000, 0x40010040, 0x00000040, 0x01010000
},
/* 3 */
{
0x00100402, 0x04000400, 0x00000002, 0x04100402,
0x00000000, 0x04100000, 0x04000402, 0x00100002,
0x04100400, 0x04000002, 0x04000000, 0x00000402,
0x04000002, 0x00100402, 0x00100000, 0x04000000,
0x04100002, 0x00100400, 0x00000400, 0x00000002,
0x00100400, 0x04000402, 0x04100000, 0x00000400,
0x00000402, 0x00000000, 0x00100002, 0x04100400,
0x04000400, 0x04100002, 0x04100402, 0x00100000,
0x04100002, 0x00000402, 0x00100000, 0x04000002,
0x00100400, 0x04000400, 0x00000002, 0x04100000,
0x04000402, 0x00000000, 0x00000400, 0x00100002,
0x00000000, 0x04100002, 0x04100400, 0x00000400,
0x04000000, 0x04100402, 0x00100402, 0x00100000,
0x04100402, 0x00000002, 0x04000400, 0x00100402,
0x00100002, 0x00100400, 0x04100000, 0x04000402,
0x00000402, 0x04000000, 0x04000002, 0x04100400
},
/* 4 */
{
0x02000000, 0x00004000, 0x00000100, 0x02004108,
0x02004008, 0x02000100, 0x00004108, 0x02004000,
0x00004000, 0x00000008, 0x02000008, 0x00004100,
0x02000108, 0x02004008, 0x02004100, 0x00000000,
0x00004100, 0x02000000, 0x00004008, 0x00000108,
0x02000100, 0x00004108, 0x00000000, 0x02000008,
0x00000008, 0x02000108, 0x02004108, 0x00004008,
0x02004000, 0x00000100, 0x00000108, 0x02004100,
0x02004100, 0x02000108, 0x00004008, 0x02004000,
0x00004000, 0x00000008, 0x02000008, 0x02000100,
0x02000000, 0x00004100, 0x02004108, 0x00000000,
0x00004108, 0x02000000, 0x00000100, 0x00004008,
0x02000108, 0x00000100, 0x00000000, 0x02004108,
0x02004008, 0x02004100, 0x00000108, 0x00004000,
0x00004100, 0x02004008, 0x02000100, 0x00000108,
0x00000008, 0x00004108, 0x02004000, 0x02000008
},
/* 5 */
{
0x20000010, 0x00080010, 0x00000000, 0x20080800,
0x00080010, 0x00000800, 0x20000810, 0x00080000,
0x00000810, 0x20080810, 0x00080800, 0x20000000,
0x20000800, 0x20000010, 0x20080000, 0x00080810,
0x00080000, 0x20000810, 0x20080010, 0x00000000,
0x00000800, 0x00000010, 0x20080800, 0x20080010,
0x20080810, 0x20080000, 0x20000000, 0x00000810,
0x00000010, 0x00080800, 0x00080810, 0x20000800,
0x00000810, 0x20000000, 0x20000800, 0x00080810,
0x20080800, 0x00080010, 0x00000000, 0x20000800,
0x20000000, 0x00000800, 0x20080010, 0x00080000,
0x00080010, 0x20080810, 0x00080800, 0x00000010,
0x20080810, 0x00080800, 0x00080000, 0x20000810,
0x20000010, 0x20080000, 0x00080810, 0x00000000,
0x00000800, 0x20000010, 0x20000810, 0x20080800,
0x20080000, 0x00000810, 0x00000010, 0x20080010
},
/* 6 */
{
0x00001000, 0x00000080, 0x00400080, 0x00400001,
0x00401081, 0x00001001, 0x00001080, 0x00000000,
0x00400000, 0x00400081, 0x00000081, 0x00401000,
0x00000001, 0x00401080, 0x00401000, 0x00000081,
0x00400081, 0x00001000, 0x00001001, 0x00401081,
0x00000000, 0x00400080, 0x00400001, 0x00001080,
0x00401001, 0x00001081, 0x00401080, 0x00000001,
0x00001081, 0x00401001, 0x00000080, 0x00400000,
0x00001081, 0x00401000, 0x00401001, 0x00000081,
0x00001000, 0x00000080, 0x00400000, 0x00401001,
0x00400081, 0x00001081, 0x00001080, 0x00000000,
0x00000080, 0x00400001, 0x00000001, 0x00400080,
0x00000000, 0x00400081, 0x00400080, 0x00001080,
0x00000081, 0x00001000, 0x00401081, 0x00400000,
0x00401080, 0x00000001, 0x00001001, 0x00401081,
0x00400001, 0x00401080, 0x00401000, 0x00001001
},
/* 7 */
{
0x08200020, 0x08208000, 0x00008020, 0x00000000,
0x08008000, 0x00200020, 0x08200000, 0x08208020,
0x00000020, 0x08000000, 0x00208000, 0x00008020,
0x00208020, 0x08008020, 0x08000020, 0x08200000,
0x00008000, 0x00208020, 0x00200020, 0x08008000,
0x08208020, 0x08000020, 0x00000000, 0x00208000,
0x08000000, 0x00200000, 0x08008020, 0x08200020,
0x00200000, 0x00008000, 0x08208000, 0x00000020,
0x00200000, 0x00008000, 0x08000020, 0x08208020,
0x00008020, 0x08000000, 0x00000000, 0x00208000,
0x08200020, 0x08008020, 0x08008000, 0x00200020,
0x08208000, 0x00000020, 0x00200020, 0x08008000,
0x08208020, 0x00200000, 0x08200000, 0x08000020,
0x00208000, 0x00008020, 0x08008020, 0x08200000,
0x00000020, 0x08208000, 0x00208020, 0x00000000,
0x08000000, 0x08200020, 0x00008000, 0x00208020
}
};
static DWORD KeyPerm[8][64] =
{
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
{
0x00000000,0x00000010,0x20000000,0x20000010,
0x00010000,0x00010010,0x20010000,0x20010010,
0x00000800,0x00000810,0x20000800,0x20000810,
0x00010800,0x00010810,0x20010800,0x20010810,
0x00000020,0x00000030,0x20000020,0x20000030,
0x00010020,0x00010030,0x20010020,0x20010030,
0x00000820,0x00000830,0x20000820,0x20000830,
0x00010820,0x00010830,0x20010820,0x20010830,
0x00080000,0x00080010,0x20080000,0x20080010,
0x00090000,0x00090010,0x20090000,0x20090010,
0x00080800,0x00080810,0x20080800,0x20080810,
0x00090800,0x00090810,0x20090800,0x20090810,
0x00080020,0x00080030,0x20080020,0x20080030,
0x00090020,0x00090030,0x20090020,0x20090030,
0x00080820,0x00080830,0x20080820,0x20080830,
0x00090820,0x00090830,0x20090820,0x20090830
},
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
{
0x00000000,0x02000000,0x00002000,0x02002000,
0x00200000,0x02200000,0x00202000,0x02202000,
0x00000004,0x02000004,0x00002004,0x02002004,
0x00200004,0x02200004,0x00202004,0x02202004,
0x00000400,0x02000400,0x00002400,0x02002400,
0x00200400,0x02200400,0x00202400,0x02202400,
0x00000404,0x02000404,0x00002404,0x02002404,
0x00200404,0x02200404,0x00202404,0x02202404,
0x10000000,0x12000000,0x10002000,0x12002000,
0x10200000,0x12200000,0x10202000,0x12202000,
0x10000004,0x12000004,0x10002004,0x12002004,
0x10200004,0x12200004,0x10202004,0x12202004,
0x10000400,0x12000400,0x10002400,0x12002400,
0x10200400,0x12200400,0x10202400,0x12202400,
0x10000404,0x12000404,0x10002404,0x12002404,
0x10200404,0x12200404,0x10202404,0x12202404
},
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
{
0x00000000,0x00000001,0x00040000,0x00040001,
0x01000000,0x01000001,0x01040000,0x01040001,
0x00000002,0x00000003,0x00040002,0x00040003,
0x01000002,0x01000003,0x01040002,0x01040003,
0x00000200,0x00000201,0x00040200,0x00040201,
0x01000200,0x01000201,0x01040200,0x01040201,
0x00000202,0x00000203,0x00040202,0x00040203,
0x01000202,0x01000203,0x01040202,0x01040203,
0x08000000,0x08000001,0x08040000,0x08040001,
0x09000000,0x09000001,0x09040000,0x09040001,
0x08000002,0x08000003,0x08040002,0x08040003,
0x09000002,0x09000003,0x09040002,0x09040003,
0x08000200,0x08000201,0x08040200,0x08040201,
0x09000200,0x09000201,0x09040200,0x09040201,
0x08000202,0x08000203,0x08040202,0x08040203,
0x09000202,0x09000203,0x09040202,0x09040203
},
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
{
0x00000000,0x00100000,0x00000100,0x00100100,
0x00000008,0x00100008,0x00000108,0x00100108,
0x00001000,0x00101000,0x00001100,0x00101100,
0x00001008,0x00101008,0x00001108,0x00101108,
0x04000000,0x04100000,0x04000100,0x04100100,
0x04000008,0x04100008,0x04000108,0x04100108,
0x04001000,0x04101000,0x04001100,0x04101100,
0x04001008,0x04101008,0x04001108,0x04101108,
0x00020000,0x00120000,0x00020100,0x00120100,
0x00020008,0x00120008,0x00020108,0x00120108,
0x00021000,0x00121000,0x00021100,0x00121100,
0x00021008,0x00121008,0x00021108,0x00121108,
0x04020000,0x04120000,0x04020100,0x04120100,
0x04020008,0x04120008,0x04020108,0x04120108,
0x04021000,0x04121000,0x04021100,0x04121100,
0x04021008,0x04121008,0x04021108,0x04121108
},
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
{
0x00000000,0x10000000,0x00010000,0x10010000,
0x00000004,0x10000004,0x00010004,0x10010004,
0x20000000,0x30000000,0x20010000,0x30010000,
0x20000004,0x30000004,0x20010004,0x30010004,
0x00100000,0x10100000,0x00110000,0x10110000,
0x00100004,0x10100004,0x00110004,0x10110004,
0x20100000,0x30100000,0x20110000,0x30110000,
0x20100004,0x30100004,0x20110004,0x30110004,
0x00001000,0x10001000,0x00011000,0x10011000,
0x00001004,0x10001004,0x00011004,0x10011004,
0x20001000,0x30001000,0x20011000,0x30011000,
0x20001004,0x30001004,0x20011004,0x30011004,
0x00101000,0x10101000,0x00111000,0x10111000,
0x00101004,0x10101004,0x00111004,0x10111004,
0x20101000,0x30101000,0x20111000,0x30111000,
0x20101004,0x30101004,0x20111004,0x30111004
},
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
{
0x00000000,0x08000000,0x00000008,0x08000008,
0x00000400,0x08000400,0x00000408,0x08000408,
0x00020000,0x08020000,0x00020008,0x08020008,
0x00020400,0x08020400,0x00020408,0x08020408,
0x00000001,0x08000001,0x00000009,0x08000009,
0x00000401,0x08000401,0x00000409,0x08000409,
0x00020001,0x08020001,0x00020009,0x08020009,
0x00020401,0x08020401,0x00020409,0x08020409,
0x02000000,0x0A000000,0x02000008,0x0A000008,
0x02000400,0x0A000400,0x02000408,0x0A000408,
0x02020000,0x0A020000,0x02020008,0x0A020008,
0x02020400,0x0A020400,0x02020408,0x0A020408,
0x02000001,0x0A000001,0x02000009,0x0A000009,
0x02000401,0x0A000401,0x02000409,0x0A000409,
0x02020001,0x0A020001,0x02020009,0x0A020009,
0x02020401,0x0A020401,0x02020409,0x0A020409
},
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
{
0x00000000,0x00000100,0x00080000,0x00080100,
0x01000000,0x01000100,0x01080000,0x01080100,
0x00000010,0x00000110,0x00080010,0x00080110,
0x01000010,0x01000110,0x01080010,0x01080110,
0x00200000,0x00200100,0x00280000,0x00280100,
0x01200000,0x01200100,0x01280000,0x01280100,
0x00200010,0x00200110,0x00280010,0x00280110,
0x01200010,0x01200110,0x01280010,0x01280110,
0x00000200,0x00000300,0x00080200,0x00080300,
0x01000200,0x01000300,0x01080200,0x01080300,
0x00000210,0x00000310,0x00080210,0x00080310,
0x01000210,0x01000310,0x01080210,0x01080310,
0x00200200,0x00200300,0x00280200,0x00280300,
0x01200200,0x01200300,0x01280200,0x01280300,
0x00200210,0x00200310,0x00280210,0x00280310,
0x01200210,0x01200310,0x01280210,0x01280310
},
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
{
0x00000000,0x04000000,0x00040000,0x04040000,
0x00000002,0x04000002,0x00040002,0x04040002,
0x00002000,0x04002000,0x00042000,0x04042000,
0x00002002,0x04002002,0x00042002,0x04042002,
0x00000020,0x04000020,0x00040020,0x04040020,
0x00000022,0x04000022,0x00040022,0x04040022,
0x00002020,0x04002020,0x00042020,0x04042020,
0x00002022,0x04002022,0x00042022,0x04042022,
0x00000800,0x04000800,0x00040800,0x04040800,
0x00000802,0x04000802,0x00040802,0x04040802,
0x00002800,0x04002800,0x00042800,0x04042800,
0x00002802,0x04002802,0x00042802,0x04042802,
0x00000820,0x04000820,0x00040820,0x04040820,
0x00000822,0x04000822,0x00040822,0x04040822,
0x00002820,0x04002820,0x00042820,0x04042820,
0x00002822,0x04002822,0x00042822,0x04042822
}
};

294
src/libthecore/buffer.cpp Normal file
View File

@@ -0,0 +1,294 @@
/*
* Filename: buffer.c
* Description: Buffer 처리 모듈
*
* Author: 김한주 (aka. 비엽, Cronan)
*/
#define __LIBTHECORE__
#include "stdafx.h"
static LPBUFFER normalized_buffer_pool[32] = { NULL, };
#define DEFAULT_POOL_SIZE 8192
// internal function forward
void buffer_realloc(LPBUFFER& buffer, int length);
static int buffer_get_pool_index(int size) {
int i;
for (i = 0; i < 32; ++i) {
if ((1 << i) >= size) {
return i;
}
}
return -1; // too big... not pooled
}
static int buffer_get_exac_pool_index(int size) {
int i;
for (i = 0; i < 32; ++i) {
if ((1 << i) == size) {
return i;
}
}
return -1; // too big... not pooled
}
// 모든 buffer pool 해제.
static void buffer_pool_free ()
{
for (int i = 31; i >= 0; i--)
{
if (normalized_buffer_pool[i] != NULL)
{
LPBUFFER next;
for (LPBUFFER p = normalized_buffer_pool[i]; p != NULL; p = next)
{
next = p->next;
free(p->mem_data);
free(p);
}
normalized_buffer_pool[i] = NULL;
}
}
}
// n보다 큰 buffer pool 하나를 해제.
static bool buffer_larger_pool_free (int n)
{
for (int i = 31; i > n; i--)
{
if (normalized_buffer_pool[i] != NULL)
{
LPBUFFER buffer = normalized_buffer_pool[i];
LPBUFFER next = buffer->next;
free(buffer->mem_data);
free(buffer);
normalized_buffer_pool[i] = next;
return true;
}
}
return false;
}
bool safe_create(char** pdata, int number)
{
if (!((*pdata) = (char *) calloc (number, sizeof(char))))
{
sys_err("calloc failed [%d] %s", errno, strerror(errno));
return false;
}
else
{
return true;
}
}
LPBUFFER buffer_new(int size)
{
if (size < 0) {
return NULL;
}
LPBUFFER buffer = NULL;
int pool_index = buffer_get_pool_index(size);
if (pool_index >= 0) {
BUFFER** buffer_pool = normalized_buffer_pool + pool_index;
size = 1 << pool_index;
if (*buffer_pool) {
buffer = *buffer_pool;
*buffer_pool = buffer->next;
}
}
if (buffer == NULL)
{
CREATE(buffer, BUFFER, 1);
buffer->mem_size = size;
// buffer_new에서 calloc failed가 자주 발생하여(터키의 빈약한 머신에서 주로 발생),
// calloc이 실패하면, buffer pool을 비우고 다시 시도한다.
if (!safe_create(&buffer->mem_data, size))
{
// 필요한 buffer보다 큰 buffer pool에서 하나를 해제.
if (!buffer_larger_pool_free(pool_index))
// 실패하면 최후의 수단으로, 모든 pool을 해제한다.
buffer_pool_free();
CREATE(buffer->mem_data, char, size);
sys_err ("buffer pool free success.");
}
}
assert(buffer != NULL);
assert(buffer->mem_size == size);
assert(buffer->mem_data != NULL);
buffer_reset(buffer);
return buffer;
}
void buffer_delete(LPBUFFER buffer)
{
if (buffer == NULL) {
return;
}
buffer_reset(buffer);
int size = buffer->mem_size;
int pool_index = buffer_get_exac_pool_index(size);
if (pool_index >= 0) {
BUFFER** buffer_pool = normalized_buffer_pool + pool_index;
buffer->next = *buffer_pool;
*buffer_pool = buffer;
}
else {
free(buffer->mem_data);
free(buffer);
}
}
DWORD buffer_size(LPBUFFER buffer)
{
return (buffer->length);
}
void buffer_reset(LPBUFFER buffer)
{
buffer->read_point = buffer->mem_data;
buffer->write_point = buffer->mem_data;
buffer->write_point_pos = 0;
buffer->length = 0;
buffer->next = NULL;
buffer->flag = 0;
}
void buffer_write(LPBUFFER& buffer, const void *src, int length)
{
if (buffer->write_point_pos + length >= buffer->mem_size)
buffer_realloc(buffer, buffer->mem_size + length + MIN(10240, length));
thecore_memcpy(buffer->write_point, src, length);
buffer_write_proceed(buffer, length);
}
void buffer_read(LPBUFFER buffer, void * buf, int bytes)
{
thecore_memcpy(buf, buffer->read_point, bytes);
buffer_read_proceed(buffer, bytes);
}
BYTE buffer_byte(LPBUFFER buffer)
{
BYTE val = *(BYTE *) buffer->read_point;
buffer_read_proceed(buffer, sizeof(BYTE));
return val;
}
WORD buffer_word(LPBUFFER buffer)
{
WORD val = *(WORD *) buffer->read_point;
buffer_read_proceed(buffer, sizeof(WORD));
return val;
}
DWORD buffer_dword(LPBUFFER buffer)
{
DWORD val = *(DWORD *) buffer->read_point;
buffer_read_proceed(buffer, sizeof(DWORD));
return val;
}
const void * buffer_read_peek(LPBUFFER buffer)
{
return (const void *) buffer->read_point;
}
void buffer_read_proceed(LPBUFFER buffer, int length)
{
if (length == 0)
return;
if (length < 0)
sys_err("buffer_proceed: length argument lower than zero (length: %d)", length);
else if (length > buffer->length)
{
sys_err("buffer_proceed: length argument bigger than buffer (length: %d, buffer: %d)", length, buffer->length);
length = buffer->length;
}
// 처리할 길이가 버퍼 길이보다 작다면, 버퍼를 남겨두어야 한다.
if (length < buffer->length)
{
// write_point 와 pos 는 그대로 두고 read_point 만 증가 시킨다.
if (buffer->read_point + length - buffer->mem_data > buffer->mem_size)
{
sys_err("buffer_read_proceed: buffer overflow! length %d read_point %d", length, buffer->read_point - buffer->mem_data);
abort();
}
buffer->read_point += length;
buffer->length -= length;
}
else
{
buffer_reset(buffer);
}
}
void * buffer_write_peek(LPBUFFER buffer)
{
return (buffer->write_point);
}
void buffer_write_proceed(LPBUFFER buffer, int length)
{
buffer->length += length;
buffer->write_point += length;
buffer->write_point_pos += length;
}
int buffer_has_space(LPBUFFER buffer)
{
return (buffer->mem_size - buffer->write_point_pos);
}
void buffer_adjust_size(LPBUFFER& buffer, int add_size)
{
if (buffer->mem_size >= buffer->write_point_pos + add_size)
return;
sys_log(0, "buffer_adjust %d current %d/%d", add_size, buffer->length, buffer->mem_size);
buffer_realloc(buffer, buffer->mem_size + add_size);
}
void buffer_realloc(LPBUFFER& buffer, int length)
{
int i, read_point_pos;
LPBUFFER temp;
assert(length >= 0 && "buffer_realloc: length is lower than zero");
if (buffer->mem_size >= length)
return;
// i 는 새로 할당된 크기와 이전크기의 차, 실제로 새로 생긴
// 메모리의 크기를 뜻한다.
i = length - buffer->mem_size;
if (i <= 0)
return;
temp = buffer_new (length);
sys_log(0, "reallocating buffer to %d, current %d", temp->mem_size, buffer->mem_size);
thecore_memcpy(temp->mem_data, buffer->mem_data, buffer->mem_size);
read_point_pos = buffer->read_point - buffer->mem_data;
// write_point 와 read_point 를 재 연결 시킨다.
temp->write_point = temp->mem_data + buffer->write_point_pos;
temp->write_point_pos = buffer->write_point_pos;
temp->read_point = temp->mem_data + read_point_pos;
temp->flag = buffer->flag;
temp->next = NULL;
temp->length = buffer->length;
buffer_delete(buffer);
buffer = temp;
}

57
src/libthecore/buffer.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* Filename: buffer.h
* Description: Buffer 처리 모듈
*
* Author: 김한주 (aka. 비엽, Cronan), 송영진 (aka. myevan, 빗자루)
*/
#ifndef __INC_LIBTHECORE_BUFFER_H__
#define __INC_LIBTHECORE_BUFFER_H__
#define SAFE_BUFFER_DELETE(buf) { if(buf != NULL) { buffer_delete(buf); buf = NULL; } }
typedef struct buffer BUFFER;
typedef struct buffer * LPBUFFER;
struct buffer
{
struct buffer * next;
char * write_point;
int write_point_pos;
const char * read_point;
int length;
char * mem_data;
int mem_size;
long flag;
};
extern LPBUFFER buffer_new(int size); // 새 버퍼 생성
extern void buffer_delete(LPBUFFER buffer); // 버퍼 삭제
extern void buffer_reset(LPBUFFER buffer); // 버퍼 길이들을 초기화
extern DWORD buffer_size(LPBUFFER buffer); // 버퍼에 남은 길이
extern int buffer_has_space(LPBUFFER buffer); // 쓸 수 있는 길이를 리턴
extern void buffer_write (LPBUFFER& buffer, const void* src, int length); // 버퍼에 쓴다.
extern void buffer_read(LPBUFFER buffer, void * buf, int bytes); // 버퍼에서 읽는다.
extern BYTE buffer_get_byte(LPBUFFER buffer);
extern WORD buffer_get_word(LPBUFFER buffer);
extern DWORD buffer_get_dword(LPBUFFER buffer);
// buffer_proceed 함수는 buffer_peek으로 읽기용 포인터를 리턴 받아서 쓸 필요가
// 있을 때 처리가 끝나면 얼마나 처리가 끝났다고 통보해야 할 때 쓴다.
// (buffer_read, buffer_get_* 시리즈의 경우에는 알아서 처리되지만 peek으로 처리했을
// 때는 그렇게 될 수가 없으므로)
extern const void * buffer_read_peek(LPBUFFER buffer); // 읽는 위치를 리턴
extern void buffer_read_proceed(LPBUFFER buffer, int length); // length만큼의 처리가 끝남
// 마찬가지로 write_peek으로 쓰기 위치를 얻어온 다음 얼마나 썼나 통보할 때
// buffer_write_proceed를 사용한다.
extern void * buffer_write_peek(LPBUFFER buffer); // 쓰는 위치를 리턴
extern void buffer_write_proceed(LPBUFFER buffer, int length); // length만 증가 시킨다.
extern void buffer_adjust_size(LPBUFFER & buffer, int add_size); // add_size만큼 추가할 크기를 확보
#endif

23
src/libthecore/crypt.h Normal file
View File

@@ -0,0 +1,23 @@
#ifdef __cplusplus
extern "C" {
#endif
/* TEA is a 64-bit symmetric block cipher with a 128-bit key, developed
by David J. Wheeler and Roger M. Needham, and described in their
paper at <URL:http://www.cl.cam.ac.uk/ftp/users/djw3/tea.ps>.
This implementation is based on their code in
<URL:http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps> */
extern int TEA_Encrypt(DWORD *dest, const DWORD *src, const DWORD *key, int size);
extern int TEA_Decrypt(DWORD *dest, const DWORD *src, const DWORD *key, int size);
extern int GOST_Encrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector);
extern int GOST_Decrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector);
extern int DES_Encrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector);
extern int DES_Decrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector);
#ifdef __cplusplus
};
#endif

281
src/libthecore/des.cpp Normal file
View File

@@ -0,0 +1,281 @@
#include "stdafx.h"
#include "DES_table.h"
#define DES_ECB_ENCRYPT 0
#define DES_ECB_DECRYPT 1
// DES ECB encryption code
extern DWORD SP_boxes[8][64];
//extern DWORD KeyPerm[8][64];
/*
* Macroses to transform array of 4 bytes to 32-bit dwords
* (and reverse) without depending on the Little-Endian or
* Big-Endian processor's architecture
*/
#define BYTES_TO_DWORD(b,d) (d = ((DWORD)(*((b)++))), \
d |= ((DWORD)(*((b)++)))<< 8, \
d |= ((DWORD)(*((b)++)))<<16, \
d |= ((DWORD)(*((b)++)))<<24)
#define DWORD_TO_4BYTES(d,b) (*((b)++)=(BYTE)(((d) )&0xff), \
*((b)++)=(BYTE)(((d)>> 8)&0xff), \
*((b)++)=(BYTE)(((d)>>16)&0xff), \
*((b)++)=(BYTE)(((d)>>24)&0xff))
/*
* First of all, take into accounts the bytes and bites ordering
* used in DES:
*
* DES: 1 2 3 4 5 6 7 8 .... 57 58 59 60 61 62 63 64
* INTEL: 63 62 61 60 59 58 57 56 .... 7 6 5 4 3 2 1 0
*
* According to the DES, every 8-th bits is not used:
* for DES the bites 8, 16, 32, ..., 64 are excluded,
* for INTEL: 56, 48, 40, ..., 0 are excluded
*
* According to the above rool of numbering, the tables
* used in DES (for Initial Permutation, Final Permutation,
* Key Permutation, Compression Permutation, Expansion
* Permutation and P-Box permutation) have to be re-written.
*
*/
/*
Some main ideas used to optimize DES software
implementation:
a). Do not make an Expansion Permutation of 32-bit to
48 bit (32-bit of data - right half of 64-bit of data),
but make a correspondent preparation of the Key. So,
the step of Expansion Permutation and XORing 48 bit of
Expanded data and 48 bit of Compressed key will be
replaced by 2 XOR operations: 32 bit of data XOR first
32 bit part of prepeared key, then, the same 32 bit of
data XOR second 32-bit part of prepeared key
b). Combine S-Box Substitution and P-Box Permutation
operations.
c). For the best performance 56-bit encryption key
have to be extendended to 128-byte array, i.e. for each
of 16 rounds of DES we prepare a unique pair of two
32-bit (4-bytes) words (see 'a)' above).
d). We can use XOR, SHIFT, AND operations to swap
bits between words. For example, we have:
word A word B
0 1 2 3 4 5 6 7
We want to get:
word A word B
0 4 2 6 1 5 3 7
First, shift word A to get bites 1, 3 on the "right place"
word TMP = (word A) >> 1 = 1 2 3 -
TMP = TMP ^ B = 1^4 2^5 3^6 7
we don't want to change bits 5 and 7 in the B word, so
TMP = TMP & MASK = TMP & 1010 = 1^4 - 3^6 -
now we can easy get the word B:
B = B ^ TMP = (4 5 6 7) ^ (1^4 - 3^6 -) = 1 5 3 7
if we shift our "masking" TMP word reverse - we get
a mask for A word:
TMP = TMP << 1 = - 1^4 - 3^6
now we can easy get the word A:
A = A ^ TMP = (0 1 2 3) ^ (- 1^4 - 3^6) = 0 4 2 6
The example above may be used to swap not only single
bits, but also bit sequencies. In this case you should
use shift on the value, equal to the number of bits
in pattern.
As you see, all this opearations may be written like:
TMP = ((A >> size) ^ B) & mask;
B ^ = TMP;
A ^= TMP << size;
*/
#define PERMUTATION(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
(b)^=(t),\
(a)^=((t)<<(n)))
#define HPERMUTATION(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
(a)=(a)^(t)^(t>>(16-(n))))
#define D_ENCRYPT(Left, Right, Ks, Num, TmpA, TmpB) \
TmpA = (Right ^ Ks[Num ]); \
TmpB = (Right ^ Ks[Num+1]); \
TmpB = ((TmpB >> 4) + (TmpB << 28)); \
Left ^= SP_boxes[1][(TmpB )&0x3f]| \
SP_boxes[3][(TmpB>> 8)&0x3f]| \
SP_boxes[5][(TmpB>>16)&0x3f]| \
SP_boxes[7][(TmpB>>24)&0x3f]| \
SP_boxes[0][(TmpA )&0x3f]| \
SP_boxes[2][(TmpA>> 8)&0x3f]| \
SP_boxes[4][(TmpA>>16)&0x3f]| \
SP_boxes[6][(TmpA>>24)&0x3f];
void DES_ECB_mode(BYTE * Input, /* 8 bytes of input data */
BYTE * Output, /* 8 bytes of output data */
const DWORD * KeySchedule, /* [16][2] array of DWORDs */
BYTE Operation) /* DES_ECB_ENCRYPT or DES_ECB_DECRYPT */
{
static BYTE * bInp, * bOut;
static DWORD dwLeft, dwRigh, dwTmp, dwTmp1;
bInp = Input;
bOut = Output;
BYTES_TO_DWORD(bInp, dwLeft);
BYTES_TO_DWORD(bInp, dwRigh);
/* Initial Permutation */
PERMUTATION(dwRigh, dwLeft, dwTmp, 4, 0x0f0f0f0f);
PERMUTATION(dwLeft, dwRigh, dwTmp,16, 0x0000ffff);
PERMUTATION(dwRigh, dwLeft, dwTmp, 2, 0x33333333);
PERMUTATION(dwLeft, dwRigh, dwTmp, 8, 0x00ff00ff);
PERMUTATION(dwRigh, dwLeft, dwTmp, 1, 0x55555555);
/* dwRigh and dwLeft has reversed bit orders - itwill be taken
into account in the next step */
/* The initial rotate is done outside the loop. This required the
* SP_boxes values to be rotated 1 bit to the right.
*/
dwTmp = (dwRigh<<1) | (dwRigh>>31);
dwRigh = (dwLeft<<1) | (dwLeft>>31);
dwLeft = dwTmp;
/* clear the top bits on machines with 8byte longs */
dwLeft &= 0xffffffff;
dwRigh &= 0xffffffff;
if (Operation == DES_ECB_ENCRYPT)
{ /* Key order */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 0, dwTmp, dwTmp1); /* 1 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 2, dwTmp, dwTmp1); /* 2 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 4, dwTmp, dwTmp1); /* 3 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 6, dwTmp, dwTmp1); /* 4 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 8, dwTmp, dwTmp1); /* 5 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 10, dwTmp, dwTmp1); /* 6 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 12, dwTmp, dwTmp1); /* 7 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 14, dwTmp, dwTmp1); /* 8 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 16, dwTmp, dwTmp1); /* 9 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 18, dwTmp, dwTmp1); /* 10 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 20, dwTmp, dwTmp1); /* 11 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 22, dwTmp, dwTmp1); /* 12 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 24, dwTmp, dwTmp1); /* 13 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 26, dwTmp, dwTmp1); /* 14 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 28, dwTmp, dwTmp1); /* 15 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 30, dwTmp, dwTmp1); /* 16 */
}
else
{
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 30, dwTmp, dwTmp1); /* 16 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 28, dwTmp, dwTmp1); /* 15 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 26, dwTmp, dwTmp1); /* 14 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 24, dwTmp, dwTmp1); /* 13 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 22, dwTmp, dwTmp1); /* 12 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 20, dwTmp, dwTmp1); /* 11 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 18, dwTmp, dwTmp1); /* 10 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 16, dwTmp, dwTmp1); /* 9 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 14, dwTmp, dwTmp1); /* 8 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 12, dwTmp, dwTmp1); /* 7 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 10, dwTmp, dwTmp1); /* 6 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 8, dwTmp, dwTmp1); /* 5 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 6, dwTmp, dwTmp1); /* 4 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 4, dwTmp, dwTmp1); /* 3 */
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 2, dwTmp, dwTmp1); /* 2 */
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 0, dwTmp, dwTmp1); /* 1 */
}
dwLeft = (dwLeft>>1) | (dwLeft<<31);
dwRigh = (dwRigh>>1) | (dwRigh<<31);
/* clear the top bits on machines with 8byte longs */
dwLeft &= 0xffffffff;
dwRigh &= 0xffffffff;
/*
* Do we need to swap dwLeft and dwRigh?
* We have not to do the swap
* (We remember they are reversed)
* So - all we have to do is to make a correspondent Final Permutation
*/
PERMUTATION(dwRigh, dwLeft, dwTmp, 1,0x55555555);
PERMUTATION(dwLeft, dwRigh, dwTmp, 8,0x00ff00ff);
PERMUTATION(dwRigh, dwLeft, dwTmp, 2,0x33333333);
PERMUTATION(dwLeft, dwRigh, dwTmp,16,0x0000ffff);
PERMUTATION(dwRigh, dwLeft, dwTmp, 4,0x0f0f0f0f);
/* Place our two 32-bits results into 8 bytes of output data */
DWORD_TO_4BYTES(dwLeft, bOut);
DWORD_TO_4BYTES(dwRigh, bOut);
}
//************ DES CBC mode encryption **************
int DES_Encrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector)
{
DWORD i;
DWORD buffer[2];
buffer[0] = IVector[0];
buffer[1] = IVector[1];
for (i = 0; i < (Length >> 2); i = i+2)
{
// do EBC encryption of (Initial_Vector XOR Data)
buffer[0] ^= SrcBuffer[i];
buffer[1] ^= SrcBuffer[i+1];
DES_ECB_mode((BYTE *) buffer, (BYTE *) buffer, KeyAddress, DES_ECB_ENCRYPT);
DstBuffer[i] = buffer[0];
DstBuffer[i+1] = buffer[1];
}
return Length;
}
//************ DES CBC mode decryption **************
int DES_Decrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector)
{
DWORD i;
DWORD buffer[2], ivectorL, ivectorR, oldSrcL, oldSrcR;
ivectorL = IVector[0];
ivectorR = IVector[1];
for (i = 0; i < (Length >> 2); i = i + 2)
{
buffer[0] = oldSrcL = SrcBuffer[i];
buffer[1] = oldSrcR = SrcBuffer[i+1];
// Encrypted Data -> new IV,
// then do EBC decryption of Encrypted Data,
// then XOR decrypted data with old IV
DES_ECB_mode((BYTE *)buffer, (BYTE *)buffer, KeyAddress, DES_ECB_DECRYPT);
DstBuffer[i] = buffer[0] ^ ivectorL;
DstBuffer[i+1] = buffer[1] ^ ivectorR;
ivectorL = oldSrcL;
ivectorR = oldSrcR;
}
return Length;
}

461
src/libthecore/fdwatch.cpp Normal file
View File

@@ -0,0 +1,461 @@
#define __LIBTHECORE__
#include "stdafx.h"
#ifndef __USE_SELECT__
LPFDWATCH fdwatch_new(int nfiles)
{
LPFDWATCH fdw;
int kq;
kq = kqueue();
if (kq == -1)
{
sys_err("%s", strerror(errno));
return NULL;
}
CREATE(fdw, FDWATCH, 1);
fdw->kq = kq;
fdw->nfiles = nfiles;
fdw->nkqevents = 0;
CREATE(fdw->kqevents, KEVENT, nfiles * 2);
CREATE(fdw->kqrevents, KEVENT, nfiles * 2);
CREATE(fdw->fd_event_idx, int, nfiles);
CREATE(fdw->fd_rw, int, nfiles);
CREATE(fdw->fd_data, void*, nfiles);
return (fdw);
}
void fdwatch_delete(LPFDWATCH fdw)
{
free(fdw->fd_data);
free(fdw->fd_rw);
free(fdw->kqevents);
free(fdw->kqrevents);
free(fdw->fd_event_idx);
free(fdw);
}
int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
{
int i, r;
struct timespec ts;
if (fdw->nkqevents)
sys_log(2, "fdwatch: nkqevents %d", fdw->nkqevents);
if (!timeout)
{
ts.tv_sec = 0;
ts.tv_nsec = 0;
r = kevent(fdw->kq, fdw->kqevents, fdw->nkqevents, fdw->kqrevents, fdw->nfiles, &ts);
}
else
{
ts.tv_sec = timeout->tv_sec;
ts.tv_nsec = timeout->tv_usec;
r = kevent(fdw->kq, fdw->kqevents, fdw->nkqevents, fdw->kqrevents, fdw->nfiles, &ts);
}
fdw->nkqevents = 0;
if (r == -1)
return -1;
memset(fdw->fd_event_idx, 0, sizeof(int) * fdw->nfiles);
for (i = 0; i < r; i++)
{
int fd = fdw->kqrevents[i].ident;
if (fd >= fdw->nfiles)
sys_err("ident overflow %d nfiles: %d", fdw->kqrevents[i].ident, fdw->nfiles);
else
{
if (fdw->kqrevents[i].filter == EVFILT_WRITE)
fdw->fd_event_idx[fd] = i;
}
}
return (r);
}
void fdwatch_register(LPFDWATCH fdw, int flag, int fd, int rw)
{
if (flag == EV_DELETE)
{
if (fdw->fd_rw[fd] & FDW_READ)
{
fdw->kqevents[fdw->nkqevents].ident = fd;
fdw->kqevents[fdw->nkqevents].flags = flag;
fdw->kqevents[fdw->nkqevents].filter = EVFILT_READ;
++fdw->nkqevents;
}
if (fdw->fd_rw[fd] & FDW_WRITE)
{
fdw->kqevents[fdw->nkqevents].ident = fd;
fdw->kqevents[fdw->nkqevents].flags = flag;
fdw->kqevents[fdw->nkqevents].filter = EVFILT_WRITE;
++fdw->nkqevents;
}
}
else
{
fdw->kqevents[fdw->nkqevents].ident = fd;
fdw->kqevents[fdw->nkqevents].flags = flag;
fdw->kqevents[fdw->nkqevents].filter = (rw == FDW_READ) ? EVFILT_READ : EVFILT_WRITE;
++fdw->nkqevents;
}
}
void fdwatch_clear_fd(LPFDWATCH fdw, socket_t fd)
{
fdw->fd_data[fd] = NULL;
fdw->fd_rw[fd] = 0;
}
void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void * client_data, int rw, int oneshot)
{
int flag;
if (fd >= fdw->nfiles)
{
sys_err("fd overflow %d", fd);
return;
}
if (fdw->fd_rw[fd] & rw)
return;
fdw->fd_rw[fd] |= rw;
sys_log(2, "FDWATCH_fdw %p fd %d rw %d data %p", fdw, fd, rw, client_data);
if (!oneshot)
flag = EV_ADD;
else
{
sys_log(2, "ADD ONESHOT fd_rw %d", fdw->fd_rw[fd]);
flag = EV_ADD | EV_ONESHOT;
fdw->fd_rw[fd] |= FDW_WRITE_ONESHOT;
}
fdw->fd_data[fd] = client_data;
fdwatch_register(fdw, flag, fd, rw);
}
void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd)
{
fdwatch_register(fdw, EV_DELETE, fd, 0);
fdwatch_clear_fd(fdw, fd);
}
void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
{
assert(event_idx < fdw->nfiles * 2);
if (fdw->kqrevents[event_idx].ident != fd)
return;
fdw->kqrevents[event_idx].ident = 0;
}
int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
{
assert(event_idx < fdw->nfiles * 2);
if (fdw->kqrevents[event_idx].ident != fd)
return 0;
if (fdw->kqrevents[event_idx].flags & EV_ERROR)
return FDW_EOF;
if (fdw->kqrevents[event_idx].flags & EV_EOF)
return FDW_EOF;
if (fdw->kqrevents[event_idx].filter == EVFILT_READ)
{
if (fdw->fd_rw[fd] & FDW_READ)
return FDW_READ;
}
else if (fdw->kqrevents[event_idx].filter == EVFILT_WRITE)
{
if (fdw->fd_rw[fd] & FDW_WRITE)
{
if (fdw->fd_rw[fd] & FDW_WRITE_ONESHOT)
fdw->fd_rw[fd] &= ~FDW_WRITE;
return FDW_WRITE;
}
}
else
sys_err("fdwatch_check_event: Unknown filter %d (descriptor %d)", fdw->kqrevents[event_idx].filter, fd);
return 0;
}
int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
{
assert(event_idx < fdw->nfiles * 2);
return fdw->kqrevents[event_idx].ident;
}
int fdwatch_get_buffer_size(LPFDWATCH fdw, socket_t fd)
{
int event_idx = fdw->fd_event_idx[fd];
if (fdw->kqrevents[event_idx].filter == EVFILT_WRITE)
return fdw->kqrevents[event_idx].data;
return 0;
}
void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
{
int fd;
assert(event_idx < fdw->nfiles * 2);
fd = fdw->kqrevents[event_idx].ident;
if (fd >= fdw->nfiles)
return NULL;
return (fdw->fd_data[fd]);
}
#else // ifndef __USE_SELECT__
#ifdef __WIN32__
static int win32_init_refcount = 0;
static bool win32_init()
{
if (win32_init_refcount > 0)
{
win32_init_refcount++;
return true;
}
WORD wVersion = MAKEWORD(2, 0);
WSADATA wsaData;
if (WSAStartup(wVersion, &wsaData) != 0)
return false;
win32_init_refcount++;
return true;
}
static void win32_deinit()
{
if (--win32_init_refcount <= 0)
WSACleanup();
}
#endif
LPFDWATCH fdwatch_new(int nfiles)
{
LPFDWATCH fdw;
#ifdef __WIN32__
if (!win32_init())
return NULL;
#endif
// nfiles value is limited to FD_SETSIZE (64)
CREATE(fdw, FDWATCH, 1);
fdw->nfiles = MIN(nfiles, FD_SETSIZE);
FD_ZERO(&fdw->rfd_set);
FD_ZERO(&fdw->wfd_set);
CREATE(fdw->select_fds, socket_t, nfiles);
CREATE(fdw->select_rfdidx, int, nfiles);
fdw->nselect_fds = 0;
CREATE(fdw->fd_rw, int, nfiles);
CREATE(fdw->fd_data, void*, nfiles);
return (fdw);
}
void fdwatch_delete(LPFDWATCH fdw)
{
free(fdw->fd_data);
free(fdw->fd_rw);
free(fdw->select_fds);
free(fdw->select_rfdidx);
free(fdw);
#ifdef __WIN32__
win32_deinit();
#endif
}
static int fdwatch_get_fdidx(LPFDWATCH fdw, socket_t fd) {
int i;
for (i = 0; i < fdw->nselect_fds; ++i) {
if (fdw->select_fds[i] == fd) {
return i;
}
}
return -1;
}
void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int oneshot)
{
int idx = fdwatch_get_fdidx(fdw, fd);
if (idx < 0) {
if (fdw->nselect_fds >= fdw->nfiles) {
return;
}
idx = fdw->nselect_fds;
fdw->select_fds[fdw->nselect_fds++] = fd;
fdw->fd_rw[idx] = rw;
} else {
fdw->fd_rw[idx] |= rw;
}
fdw->fd_data[idx] = client_data;
if (rw & FDW_READ)
FD_SET(fd, &fdw->rfd_set);
if (rw & FDW_WRITE)
FD_SET(fd, &fdw->wfd_set);
}
void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd)
{
if (fdw->nselect_fds <= 0) {
return;
}
int idx = fdwatch_get_fdidx(fdw, fd);
if (idx < 0) {
return;
}
--fdw->nselect_fds;
fdw->select_fds[idx] = fdw->select_fds[fdw->nselect_fds];
fdw->fd_data[idx] = fdw->fd_data[fdw->nselect_fds];
fdw->fd_rw[idx] = fdw->fd_rw[fdw->nselect_fds];
FD_CLR(fd, &fdw->rfd_set);
FD_CLR(fd, &fdw->wfd_set);
}
int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
{
int r, i, event_idx;
struct timeval tv;
fdw->working_rfd_set = fdw->rfd_set;
fdw->working_wfd_set = fdw->wfd_set;
if (!timeout)
{
tv.tv_sec = 0;
tv.tv_usec = 0;
r = select(0, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
}
else
{
tv = *timeout;
r = select(0, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
}
if (r == -1)
return -1;
event_idx = 0;
for (i = 0; i < fdw->nselect_fds; ++i)
{
if (fdwatch_check_fd(fdw, fdw->select_fds[i]))
fdw->select_rfdidx[event_idx++] = i;
}
return event_idx;
}
int fdwatch_check_fd(LPFDWATCH fdw, socket_t fd)
{
int idx = fdwatch_get_fdidx(fdw, fd);
if (idx < 0) {
return 0;
}
int result = 0;
if ((fdw->fd_rw[idx] & FDW_READ) && FD_ISSET(fd, &fdw->working_rfd_set)) {
result |= FDW_READ;
}
if ((fdw->fd_rw[idx] & FDW_WRITE) && FD_ISSET(fd, &fdw->working_wfd_set)) {
result |= FDW_WRITE;
}
return result;
}
void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
{
int idx = fdw->select_rfdidx[event_idx];
if (idx < 0 || fdw->nfiles <= idx) {
return NULL;
}
return fdw->fd_data[idx];
}
int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
{
int idx = fdw->select_rfdidx[event_idx];
if (idx < 0 || fdw->nfiles <= idx) {
return 0;
}
return (int)fdw->select_fds[idx];
}
void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
{
int idx = fdw->select_rfdidx[event_idx];
if (idx < 0 || fdw->nfiles <= idx) {
return;
}
socket_t rfd = fdw->select_fds[idx];
if (fd != rfd) {
return;
}
FD_CLR(fd, &fdw->working_rfd_set);
FD_CLR(fd, &fdw->working_wfd_set);
}
int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
{
int idx = fdw->select_rfdidx[event_idx];
if (idx < 0 || fdw->nfiles <= idx) {
return 0;
}
socket_t rfd = fdw->select_fds[idx];
if (fd != rfd) {
return 0;
}
int result = fdwatch_check_fd(fdw, fd);
if (result & FDW_READ) {
return FDW_READ;
} else if (result & FDW_WRITE) {
return FDW_WRITE;
}
return 0;
}
int fdwatch_get_buffer_size(LPFDWATCH fdw, socket_t fd)
{
return INT_MAX; // XXX TODO
}
#endif

95
src/libthecore/fdwatch.h Normal file
View File

@@ -0,0 +1,95 @@
#ifndef __INC_LIBTHECORE_FDWATCH_H__
#define __INC_LIBTHECORE_FDWATCH_H__
#ifndef __WIN32__
typedef struct fdwatch FDWATCH;
typedef struct fdwatch * LPFDWATCH;
enum EFdwatch
{
FDW_NONE = 0,
FDW_READ = 1,
FDW_WRITE = 2,
FDW_WRITE_ONESHOT = 4,
FDW_EOF = 8,
};
typedef struct kevent KEVENT;
typedef struct kevent * LPKEVENT;
typedef int KQUEUE;
struct fdwatch
{
KQUEUE kq;
int nfiles;
LPKEVENT kqevents;
int nkqevents;
LPKEVENT kqrevents;
int * fd_event_idx;
void ** fd_data;
int * fd_rw;
};
#else
typedef struct fdwatch FDWATCH;
typedef struct fdwatch * LPFDWATCH;
enum EFdwatch
{
FDW_NONE = 0,
FDW_READ = 1,
FDW_WRITE = 2,
FDW_WRITE_ONESHOT = 4,
FDW_EOF = 8,
};
struct fdwatch
{
fd_set rfd_set;
fd_set wfd_set;
socket_t* select_fds;
int* select_rfdidx;
int nselect_fds;
fd_set working_rfd_set;
fd_set working_wfd_set;
int nfiles;
void** fd_data;
int* fd_rw;
};
#endif // WIN32
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
extern LPFDWATCH fdwatch_new(int nfiles);
extern void fdwatch_clear_fd(LPFDWATCH fdw, socket_t fd);
extern void fdwatch_delete(LPFDWATCH fdw);
extern int fdwatch_check_fd(LPFDWATCH fdw, socket_t fd);
extern int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx);
extern void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx);
extern void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int oneshot);
extern int fdwatch(LPFDWATCH fdw, struct timeval *timeout);
extern void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx);
extern void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd);
extern int fdwatch_get_buffer_size(LPFDWATCH fdw, socket_t fd);
extern int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx);
#ifdef __cplusplus
}
#endif
#endif

234
src/libthecore/gost.cpp Normal file
View File

@@ -0,0 +1,234 @@
#include "stdafx.h"
/*
static unsigned char const k8[16] = { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 };
static unsigned char const k7[16] = { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 };
static unsigned char const k6[16] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 };
static unsigned char const k5[16] = { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 };
static unsigned char const k4[16] = { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 };
static unsigned char const k3[16] = { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 };
static unsigned char const k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 };
static unsigned char const k1[16] = { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 };
*/
static unsigned char const k8[16] = { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 };
static unsigned char const k7[16] = { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 };
static unsigned char const k6[16] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 };
static unsigned char const k5[16] = { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 };
static unsigned char const k4[16] = { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 };
static unsigned char const k3[16] = { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 };
static unsigned char const k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 };
static unsigned char const k1[16] = { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 };
/* Byte-at-a-time substitution boxes */
static unsigned char k87[256];
static unsigned char k65[256];
static unsigned char k43[256];
static unsigned char k21[256];
void GOST_Init()
{
int i;
for (i = 0; i < 256; i++)
{
k87[i] = k8[i >> 4] << 4 | k7[i & 15];
k65[i] = k6[i >> 4] << 4 | k5[i & 15];
k43[i] = k4[i >> 4] << 4 | k3[i & 15];
k21[i] = k2[i >> 4] << 4 | k1[i & 15];
}
}
INLINE static DWORD f(DWORD x)
{
x = k87[x >> 24 & 255] << 24 | k65[x >> 16 & 255] << 16 | k43[x >> 8 & 255] << 8 | k21[x & 255];
return x << 11 | x >> (32 - 11);
}
/*
static void GOST_ECB_Encrypt(DWORD * N1, DWORD * N2, const DWORD * KeyAddress)
{
DWORD n1, n2; // As named in the GOST
n1 = *N1;
n2 = *N2;
// Instead of swapping halves, swap names each round
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[7]);
n1 ^= f(n2+KeyAddress[6]);
n2 ^= f(n1+KeyAddress[5]);
n1 ^= f(n2+KeyAddress[4]);
n2 ^= f(n1+KeyAddress[3]);
n1 ^= f(n2+KeyAddress[2]);
n2 ^= f(n1+KeyAddress[1]);
n1 ^= f(n2+KeyAddress[0]);
// There is no swap after the last round
*N1 = n2;
*N2 = n1;
}
*/
int GOST_Encrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector)
{
DWORD i;
DWORD N1,N2;
N1 = IVector[0];
N2 = IVector[1];
for (i = 0; i < (Length >> 2); i = i+2)
{
DWORD n1, n2; // As named in the GOST
n1 = N1;
n2 = N2;
// Instead of swapping halves, swap names each round
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[7]);
n1 ^= f(n2+KeyAddress[6]);
n2 ^= f(n1+KeyAddress[5]);
n1 ^= f(n2+KeyAddress[4]);
n2 ^= f(n1+KeyAddress[3]);
n1 ^= f(n2+KeyAddress[2]);
n2 ^= f(n1+KeyAddress[1]);
n1 ^= f(n2+KeyAddress[0]);
N1 = n2;
N2 = n1;
//GOST_ECB_Encrypt(&N1, &N2, KeyAddress);
// XOR plaintext with initial vector,
// move rezult to ciphertext and to initial vector
DstBuffer[i] = SrcBuffer[i] ^ N1;
N1 = DstBuffer[i];
DstBuffer[i+1] = SrcBuffer[i+1] ^ N2;
N2 = DstBuffer[i+1];
}
return Length;
}
// ************ GOST CBC decryption **************
int GOST_Decrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector)
{
DWORD i;
DWORD N1, N2, dwTmp;
N1 = IVector[0];
N2 = IVector[1];
for (i = 0; i < (Length >> 2); i = i + 2)
{
DWORD n1, n2; // As named in the GOST
n1 = N1;
n2 = N2;
// Instead of swapping halves, swap names each round
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[0]);
n1 ^= f(n2+KeyAddress[1]);
n2 ^= f(n1+KeyAddress[2]);
n1 ^= f(n2+KeyAddress[3]);
n2 ^= f(n1+KeyAddress[4]);
n1 ^= f(n2+KeyAddress[5]);
n2 ^= f(n1+KeyAddress[6]);
n1 ^= f(n2+KeyAddress[7]);
n2 ^= f(n1+KeyAddress[7]);
n1 ^= f(n2+KeyAddress[6]);
n2 ^= f(n1+KeyAddress[5]);
n1 ^= f(n2+KeyAddress[4]);
n2 ^= f(n1+KeyAddress[3]);
n1 ^= f(n2+KeyAddress[2]);
n2 ^= f(n1+KeyAddress[1]);
n1 ^= f(n2+KeyAddress[0]);
// There is no swap after the last round
N1 = n2;
N2 = n1;
//GOST_ECB_Encrypt(&N1, &N2, KeyAddress);
// XOR encrypted text with encrypted initial vector (we get rezult - decrypted text),
// move encrypted text to new initial vector.
// We need dwTmp because SrcBuffer may be the same as DstBuffer
dwTmp = SrcBuffer[i] ^ N1;
N1 = SrcBuffer[i];
DstBuffer[i] = dwTmp;
dwTmp = SrcBuffer[i+1] ^ N2;
N2 = SrcBuffer[i+1];
DstBuffer[i+1] = dwTmp;
}
return Length;
}

411
src/libthecore/gost_old.cpp Normal file
View File

@@ -0,0 +1,411 @@
/*
* The GOST 28147-89 cipher
*
* This is based on the 25 Movember 1993 draft translation
* by Aleksandr Malchik, with Whitfield Diffie, of the Government
* Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation
* Algorithm", effective 1 July 1990. (Whitfield.Diffie@eng.sun.com)
*
* That is a draft, and may contain errors, which will be faithfully
* reflected here, along with possible exciting new bugs.
*
* Some details have been cleared up by the paper "Soviet Encryption
* Algorithm" by Josef Pieprzyk and Leonid Tombak of the University
* of Wollongong, New South Wales. (josef/leo@cs.adfa.oz.au)
*
* The standard is written by A. Zabotin (project leader), G.P. Glazkov,
* and V.B. Isaeva. It was accepted and introduced into use by the
* action of the State Standards Committee of the USSR on 2 June 89 as
* No. 1409. It was to be reviewed in 1993, but whether anyone wishes
* to take on this obligation from the USSR is questionable.
*
* This code is placed in the public domain.
*/
/*
* If you read the standard, it belabors the point of copying corresponding
* bits from point A to point B quite a bit. It helps to understand that
* the standard is uniformly little-endian, although it numbers bits from
* 1 rather than 0, so bit n has value 2^(n-1). The least significant bit
* of the 32-bit words that are manipulated in the algorithm is the first,
* lowest-numbered, in the bit string.
*/
/* A 32-bit data type */
#ifdef __alpha /* Any other 64-bit machines? */
typedef unsigned int word32;
#else
typedef unsigned long word32;
#endif
/*
* The standard does not specify the contents of the 8 4 bit->4 bit
* substitution boxes, saying they're a parameter of the network
* being set up. For illustration purposes here, I have used
* the first rows of the 8 S-boxes from the DES. (Note that the
* DES S-boxes are numbered starting from 1 at the msb. In keeping
* with the rest of the GOST, I have used little-endian numbering.
* Thus, k8 is S-box 1.
*
* Obviously, a careful look at the cryptographic properties of the cipher
* must be undertaken before "production" substitution boxes are defined.
*
* The standard also does not specify a standard bit-string representation
* for the contents of these blocks.
*/
static unsigned char const k8[16] = { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 };
static unsigned char const k7[16] = { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 };
static unsigned char const k6[16] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 };
static unsigned char const k5[16] = { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 };
static unsigned char const k4[16] = { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 };
static unsigned char const k3[16] = { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 };
static unsigned char const k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 };
static unsigned char const k1[16] = { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 };
/* Byte-at-a-time substitution boxes */
static unsigned char k87[256];
static unsigned char k65[256];
static unsigned char k43[256];
static unsigned char k21[256];
/*
* Build byte-at-a-time subtitution tables.
* This must be called once for global setup.
*/
#include <stdio.h>
void kboxinit(void)
{
int i;
for (i = 0; i < 256; i++)
{
k87[i] = k8[i >> 4] << 4 | k7[i & 15];
k65[i] = k6[i >> 4] << 4 | k5[i & 15];
k43[i] = k4[i >> 4] << 4 | k3[i & 15];
k21[i] = k2[i >> 4] << 4 | k1[i & 15];
}
}
/*
* Do the substitution and rotation that are the core of the operation,
* like the expansion, substitution and permutation of the DES.
* It would be possible to perform DES-like optimisations and store
* the table entries as 32-bit words, already rotated, but the
* efficiency gain is questionable.
*
* This should be inlined for maximum speed
*/
#if __GNUC__
__inline__
#endif
static word32 f(word32 x)
{
/* Do substitutions */
#if 0
/* This is annoyingly slow */
x = k8[x>>28 & 15] << 28 | k7[x>>24 & 15] << 24 |
k6[x>>20 & 15] << 20 | k5[x>>16 & 15] << 16 |
k4[x>>12 & 15] << 12 | k3[x>> 8 & 15] << 8 |
k2[x>> 4 & 15] << 4 | k1[x & 15];
#else
/* This is faster */
x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 | k43[x>> 8 & 255] << 8 | k21[x & 255];
#endif
/* Rotate left 11 bits */
return x << 11 | x >> (32 - 11);
}
/*
* The GOST standard defines the input in terms of bits 1..64, with
* bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].
*
* The keys are defined similarly, with bit 256 being the msb of key[7].
*/
void gostcrypt(word32 const in[2], word32 out[2], word32 const key[8])
{
word32 n1, n2; /* As named in the GOST */
n1 = in[0];
n2 = in[1];
/* Instead of swapping halves, swap names each round */
n2 ^= f(n1+key[0]);
n1 ^= f(n2+key[1]);
n2 ^= f(n1+key[2]);
n1 ^= f(n2+key[3]);
n2 ^= f(n1+key[4]);
n1 ^= f(n2+key[5]);
n2 ^= f(n1+key[6]);
n1 ^= f(n2+key[7]);
n2 ^= f(n1+key[0]);
n1 ^= f(n2+key[1]);
n2 ^= f(n1+key[2]);
n1 ^= f(n2+key[3]);
n2 ^= f(n1+key[4]);
n1 ^= f(n2+key[5]);
n2 ^= f(n1+key[6]);
n1 ^= f(n2+key[7]);
n2 ^= f(n1+key[0]);
n1 ^= f(n2+key[1]);
n2 ^= f(n1+key[2]);
n1 ^= f(n2+key[3]);
n2 ^= f(n1+key[4]);
n1 ^= f(n2+key[5]);
n2 ^= f(n1+key[6]);
n1 ^= f(n2+key[7]);
n2 ^= f(n1+key[7]);
n1 ^= f(n2+key[6]);
n2 ^= f(n1+key[5]);
n1 ^= f(n2+key[4]);
n2 ^= f(n1+key[3]);
n1 ^= f(n2+key[2]);
n2 ^= f(n1+key[1]);
n1 ^= f(n2+key[0]);
/* There is no swap after the last round */
out[0] = n2;
out[1] = n1;
}
/*
* The key schedule is somewhat different for decryption.
* (The key table is used once forward and three times backward.)
* You could define an expanded key, or just write the code twice,
* as done here.
*/
void gostdecrypt(word32 const in[2], word32 out[2], word32 const key[8])
{
word32 n1, n2; /* As named in the GOST */
n1 = in[0];
n2 = in[1];
n2 ^= f(n1+key[0]);
n1 ^= f(n2+key[1]);
n2 ^= f(n1+key[2]);
n1 ^= f(n2+key[3]);
n2 ^= f(n1+key[4]);
n1 ^= f(n2+key[5]);
n2 ^= f(n1+key[6]);
n1 ^= f(n2+key[7]);
n2 ^= f(n1+key[7]);
n1 ^= f(n2+key[6]);
n2 ^= f(n1+key[5]);
n1 ^= f(n2+key[4]);
n2 ^= f(n1+key[3]);
n1 ^= f(n2+key[2]);
n2 ^= f(n1+key[1]);
n1 ^= f(n2+key[0]);
n2 ^= f(n1+key[7]);
n1 ^= f(n2+key[6]);
n2 ^= f(n1+key[5]);
n1 ^= f(n2+key[4]);
n2 ^= f(n1+key[3]);
n1 ^= f(n2+key[2]);
n2 ^= f(n1+key[1]);
n1 ^= f(n2+key[0]);
n2 ^= f(n1+key[7]);
n1 ^= f(n2+key[6]);
n2 ^= f(n1+key[5]);
n1 ^= f(n2+key[4]);
n2 ^= f(n1+key[3]);
n1 ^= f(n2+key[2]);
n2 ^= f(n1+key[1]);
n1 ^= f(n2+key[0]);
out[0] = n2;
out[1] = n1;
}
/*
* The GOST "Output feedback" standard. It seems closer morally
* to the counter feedback mode some people have proposed for DES.
* The avoidance of the short cycles that are possible in OFB seems
* like a Good Thing.
*
* Calling it the stream mode makes more sense.
*
* The IV is encrypted with the key to produce the initial counter value.
* Then, for each output block, a constant is added, modulo 2^32-1
* (0 is represented as all-ones, not all-zeros), to each half of
* the counter, and the counter is encrypted to produce the value
* to XOR with the output.
*
* Len is the number of blocks. Sub-block encryption is
* left as an exercise for the user. Remember that the
* standard defines everything in a little-endian manner,
* so you want to use the low bit of gamma[0] first.
*
* OFB is, of course, self-inverse, so there is only one function.
*/
/* The constants for addition */
#define C1 0x01010104
#define C2 0x01010101
void gostofb(word32 const *in, word32 *out, int len, word32 const iv[2], word32 const key[8])
{
word32 temp[2]; /* Counter */
word32 gamma[2]; /* Output XOR value */
/* Compute starting value for counter */
gostcrypt(iv, temp, key);
while (len--)
{
temp[0] += C2;
if (temp[0] < C2) /* Wrap modulo 2^32? */
temp[0]++; /* Make it modulo 2^32-1 */
temp[1] += C1;
if (temp[1] < C1) /* Wrap modulo 2^32? */
temp[1]++; /* Make it modulo 2^32-1 */
gostcrypt(temp, gamma, key);
*out++ = *in++ ^ gamma[0];
*out++ = *in++ ^ gamma[1];
}
}
/*
* The CFB mode is just what you'd expect. Each block of ciphertext y[] is
* derived from the input x[] by the following pseudocode:
* y[i] = x[i] ^ gostcrypt(y[i-1])
* x[i] = y[i] ^ gostcrypt(y[i-1])
* Where y[-1] is the IV.
*
* The IV is modified in place. Again, len is in *blocks*.
*/
void gostcfbencrypt(word32 const *in, word32 *out, int len, word32 iv[2], word32 const key[8])
{
while (len--)
{
gostcrypt(iv, iv, key);
iv[0] = *out++ ^= iv[0];
iv[1] = *out++ ^= iv[1];
}
}
void gostcfbdecrypt(word32 const *in, word32 *out, int len, word32 iv[2], word32 const key[8])
{
word32 t;
while (len--)
{
gostcrypt(iv, iv, key);
t = *out;
*out++ ^= iv[0];
iv[0] = t;
t = *out;
*out++ ^= iv[1];
iv[1] = t;
}
}
/*
* The message suthetication code uses only 16 of the 32 rounds.
* There *is* a swap after the 16th round.
* The last block should be padded to 64 bits with zeros.
* len is the number of *blocks* in the input.
*/
void gostmac(word32 const *in, int len, word32 out[2], word32 const key[8])
{
word32 n1, n2; /* As named in the GOST */
n1 = 0;
n2 = 0;
while (len--)
{
n1 ^= *in++;
n2 = *in++;
/* Instead of swapping halves, swap names each round */
n2 ^= f(n1+key[0]);
n1 ^= f(n2+key[1]);
n2 ^= f(n1+key[2]);
n1 ^= f(n2+key[3]);
n2 ^= f(n1+key[4]);
n1 ^= f(n2+key[5]);
n2 ^= f(n1+key[6]);
n1 ^= f(n2+key[7]);
n2 ^= f(n1+key[0]);
n1 ^= f(n2+key[1]);
n2 ^= f(n1+key[2]);
n1 ^= f(n2+key[3]);
n2 ^= f(n1+key[4]);
n1 ^= f(n2+key[5]);
n2 ^= f(n1+key[6]);
n1 ^= f(n2+key[7]);
}
out[0] = n1;
out[1] = n2;
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
/* Designed to cope with 15-bit rand() implementations */
#define RAND32 ((word32)rand() << 17 ^ (word32)rand() << 9 ^ rand())
int main(void)
{
word32 key[8];
word32 plain[2];
word32 cipher[2];
int i, j;
kboxinit();
printf("GOST 21847-89 test driver.\n");
for (i = 0; i < 1000; i++)
{
for (j = 0; j < 8; j++)
key[j] = RAND32;
plain[0] = RAND32;
plain[1] = RAND32;
printf("%3d\r", i);
fflush(stdout);
gostcrypt(plain, cipher, key);
for (j = 0; j < 99; j++)
gostcrypt(cipher, cipher, key);
for (j = 0; j < 100; j++)
gostdecrypt(cipher, cipher, key);
if (plain[0] != cipher[0] || plain[1] != cipher[1])
{
fprintf(stderr, "\nError! i = %d\n", i);
return 1;
}
}
printf("All tests passed.\n");
return 0;
}
#endif /* TEST */

123
src/libthecore/hangul.cpp Normal file
View File

@@ -0,0 +1,123 @@
/*
* Filename: hangul.c
* Description: ÇÑ±Û °ü·Ã ±¸Çö ¼Ò½º
*
* Author: ºñ¿± aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
int is_hangul(const BYTE * str)
{
if (str[0] >= 0xb0 && str[0] <= 0xc8 && str[1] >= 0xa1 && str[1] <= 0xfe)
return 1;
return 0;
}
int check_han(const char *str)
{
int i, code;
if (!str || !*str)
return 0;
for (i = 0; str[i]; i += 2)
{
if (isnhspace(str[i]))
return 0;
if (isalpha(str[i]) || isdigit(str[i]))
continue;
code = str[i];
code += 256;
if (code < 176 || code > 200)
return 0;
}
return 1;
}
const char *first_han(const BYTE *str)
{
unsigned char high, low;
int len, i;
char *p = "±×¿Ü";
static const char* wansung[] =
{
"°¡", "°¡", "³ª", "´Ù", "´Ù",
"¶ó", "¸¶", "¹Ù", "¹Ù", "»ç",
"»ç", "¾Æ", "ÀÚ", "ÀÚ", "Â÷",
"Ä«", "Ÿ", "ÆÄ", "ÇÏ", ""
};
static const char* johab[] =
{
"ˆa", "Œa", "<EFBFBD>a", "”a", "˜a",
"œa", " a", "¤a", "¨a", "¬a",
"°a", "´a", "¸a", "¼a", "Àa",
"Äa", "?", "?", "?", ""
};
len = strlen((const char*) str);
if (len < 2)
return p;
high = str[0];
low = str[1];
if (!is_hangul(str))
{
return p;
}
high = (KStbl[(high - 0xb0) * 94 + low - 0xa1] >> 8) & 0x7c;
for (i = 0; johab[i][0]; i++)
{
low = (johab[i][0] & 0x7f);
if (low == high)
return (wansung[i]);
}
return (p);
}
int under_han(const void * orig)
{
const BYTE * str = (const BYTE *) orig;
BYTE high, low;
int len;
len = strlen((const char*) str);
if (len < 2)
return 0;
if (str[len - 1] == ')')
{
while (str[len] != '(')
len--;
}
high = str[len - 2];
low = str[len - 1];
if (!is_hangul(&str[len - 2]))
return 0;
high = KStbl[(high - 0xb0) * 94 + low - 0xa1] & 0x1f;
if (high < 2)
return 0;
if (high > 28)
return 0;
return 1;
}

31
src/libthecore/hangul.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef __INC_LIBTHECORE_HANGUL_H__
#define __INC_LIBTHECORE_HANGUL_H__
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#ifdef __WIN32__
#define isdigit iswdigit
#define isspace iswspace
#endif
#define ishan(ch) (((ch) & 0xE0) > 0x90)
#define ishanasc(ch) (isascii(ch) || ishan(ch))
#define ishanalp(ch) (isalpha(ch) || ishan(ch))
#define isnhdigit(ch) (!ishan(ch) && isdigit(ch))
#define isnhspace(ch) (!ishan(ch) && isspace(ch))
extern const char * first_han(const BYTE * str); // 첫번째 두 글자의 모음(ㄱㄴㄷ)을 뽑아 가/나/다/..를 리턴한다.
extern int check_han(const char * str); // 한글이면 true 스트링 전부 체크
extern int is_hangul(const BYTE * str); // 한글이면 true (2바이트만 체크)
extern int under_han(const void * orig); // 받침이 있으면 true
#define UNDER(str) under_han(str)
#ifdef __cplusplus
};
#endif
#endif

94
src/libthecore/heart.cpp Normal file
View File

@@ -0,0 +1,94 @@
/*
* Filename: heart.c
* Description: fps 에 한번씩 호출되는 "심장" 이다.
*
* Author: 비엽 aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
extern volatile int num_events_called;
LPHEART heart_new(int opt_usec, HEARTFUNC func)
{
LPHEART ht;
if (!func)
{
sys_err("no function defined");
return NULL;
}
CREATE(ht, HEART, 1);
ht->func = func;
ht->opt_time.tv_sec = 0;
ht->opt_time.tv_usec = opt_usec;
ht->passes_per_sec = 1000000 / opt_usec;
gettimeofday(&ht->last_time, (struct timezone *) 0);
gettimeofday(&ht->before_sleep, (struct timezone *) 0);
return (ht);
}
void heart_delete(LPHEART ht)
{
free(ht);
}
int heart_idle(LPHEART ht)
{
struct timeval now, process_time, timeout, temp_time;
int missed_pulse;
gettimeofday(&ht->before_sleep, (struct timezone *) 0);
process_time = *timediff(&ht->before_sleep, &ht->last_time);
/*
* If we were asleep for more than one pass, count missed pulses and sleep
* until we're resynchronized with the next upcoming pulse.
*/
if (process_time.tv_sec == 0 && process_time.tv_usec < ht->opt_time.tv_usec)
{
missed_pulse = 0;
}
else
{
missed_pulse = process_time.tv_sec * ht->passes_per_sec;
missed_pulse += process_time.tv_usec / ht->opt_time.tv_usec;
}
// 바빠서 pulse도 놓쳤는데 잘 시간이 어딨어...
// 펄스 fps 어차피 틀어져있는데, 정확히 맞추는 건 중요하지 않아.
if (missed_pulse > 0)
{
gettimeofday(&ht->last_time, (struct timezone *) 0);
}
else
{
/* Calculate the time we should wake up */
temp_time = *timediff(&ht->opt_time, &process_time);
ht->last_time = *timeadd(&ht->before_sleep, &temp_time);
/* Now keep sleeping until that time has come */
gettimeofday(&now, (struct timezone *) 0);
timeout = *timediff(&ht->last_time, &now);
thecore_sleep(&timeout);
}
++missed_pulse;
if (missed_pulse <= 0)
{
sys_err("missed_pulse is not positive! (%d)", missed_pulse);
missed_pulse = 1;
}
if (missed_pulse > (30 * ht->passes_per_sec))
{
sys_err("losing %d seconds. (lag occured)", missed_pulse / ht->passes_per_sec);
missed_pulse = 30 * ht->passes_per_sec;
}
return missed_pulse;
}

26
src/libthecore/heart.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef __INC_LIBTHECORE_HEART_H__
#define __INC_LIBTHECORE_HEART_H__
typedef struct heart HEART;
typedef struct heart * LPHEART;
typedef void (*HEARTFUNC) (LPHEART heart, int pulse);
struct heart
{
HEARTFUNC func;
struct timeval before_sleep;
struct timeval opt_time;
struct timeval last_time;
int passes_per_sec;
int pulse;
};
extern LPHEART heart_new(int opt_usec, HEARTFUNC func);
extern void heart_delete(LPHEART ht);
extern int heart_idle(LPHEART ht); // ¸î pulse°¡ Áö³µ³ª ¸®ÅÏÇÑ´Ù.
extern void heart_beat(LPHEART ht, int pulses);
#endif

335
src/libthecore/kstbl.cpp Normal file
View File

@@ -0,0 +1,335 @@
/*
* Filename: kstbl.c
* Description: 아래 설명 대로다.
*
* Author: 비엽 aka. Cronan
*/
#define __LIBTHECORE__
unsigned KStbl[2350] =
{
/* KS 완성형 2350자의 조합형 코드 */
0x8861,0x8862,0x8865,0x8868,0x8869,0x886a,0x886b,0x8871,
0x8873,0x8874,0x8875,0x8876,0x8877,0x8878,0x8879,0x887b,
0x887c,0x887d,0x8881,0x8882,0x8885,0x8889,0x8891,0x8893,
0x8895,0x8896,0x8897,0x88a1,0x88a2,0x88a5,0x88a9,0x88b5,
0x88b7,0x88c1,0x88c5,0x88c9,0x88e1,0x88e2,0x88e5,0x88e8,
0x88e9,0x88eb,0x88f1,0x88f3,0x88f5,0x88f6,0x88f7,0x88f8,
0x88fb,0x88fc,0x88fd,0x8941,0x8945,0x8949,0x8951,0x8953,
0x8955,0x8956,0x8957,0x8961,0x8962,0x8963,0x8965,0x8968,
0x8969,0x8971,0x8973,0x8975,0x8976,0x8977,0x897b,0x8981,
0x8985,0x8989,0x8993,0x8995,0x89a1,0x89a2,0x89a5,0x89a8,
0x89a9,0x89ab,0x89ad,0x89b0,0x89b1,0x89b3,0x89b5,0x89b7,
0x89b8,0x89c1,0x89c2,0x89c5,0x89c9,0x89cb,
0x89d1,0x89d3,0x89d5,0x89d7,0x89e1,0x89e5,0x89e9,0x89f1,
0x89f6,0x89f7,0x8a41,0x8a42,0x8a45,0x8a49,0x8a51,0x8a53,
0x8a55,0x8a57,0x8a61,0x8a65,0x8a69,0x8a73,0x8a75,0x8a81,
0x8a82,0x8a85,0x8a88,0x8a89,0x8a8a,0x8a8b,0x8a90,0x8a91,
0x8a93,0x8a95,0x8a97,0x8a98,0x8aa1,0x8aa2,0x8aa5,0x8aa9,
0x8ab6,0x8ab7,0x8ac1,0x8ad5,0x8ae1,0x8ae2,0x8ae5,0x8ae9,
0x8af1,0x8af3,0x8af5,0x8b41,0x8b45,0x8b49,0x8b61,0x8b62,
0x8b65,0x8b68,0x8b69,0x8b6a,0x8b71,0x8b73,0x8b75,0x8b77,
0x8b81,0x8ba1,0x8ba2,0x8ba5,0x8ba8,0x8ba9,0x8bab,0x8bb1,
0x8bb3,0x8bb5,0x8bb7,0x8bb8,0x8bbc,0x8c61,0x8c62,0x8c63,
0x8c65,0x8c69,0x8c6b,0x8c71,0x8c73,0x8c75,0x8c76,0x8c77,
0x8c7b,0x8c81,0x8c82,0x8c85,0x8c89,0x8c91,
0x8c93,0x8c95,0x8c96,0x8c97,0x8ca1,0x8ca2,0x8ca9,0x8ce1,
0x8ce2,0x8ce3,0x8ce5,0x8ce9,0x8cf1,0x8cf3,0x8cf5,0x8cf6,
0x8cf7,0x8d41,0x8d42,0x8d45,0x8d51,0x8d55,0x8d57,0x8d61,
0x8d65,0x8d69,0x8d75,0x8d76,0x8d7b,0x8d81,0x8da1,0x8da2,
0x8da5,0x8da7,0x8da9,0x8db1,0x8db3,0x8db5,0x8db7,0x8db8,
0x8db9,0x8dc1,0x8dc2,0x8dc9,0x8dd6,0x8dd7,0x8de1,0x8de2,
0x8df7,0x8e41,0x8e45,0x8e49,0x8e51,0x8e53,0x8e57,0x8e61,
0x8e81,0x8e82,0x8e85,0x8e89,0x8e90,0x8e91,0x8e93,0x8e95,
0x8e97,0x8e98,0x8ea1,0x8ea9,0x8eb6,0x8eb7,0x8ec1,0x8ec2,
0x8ec5,0x8ec9,0x8ed1,0x8ed3,0x8ed6,0x8ee1,0x8ee5,0x8ee9,
0x8ef1,0x8ef3,0x8f41,0x8f61,0x8f62,0x8f65,0x8f67,0x8f69,
0x8f6b,0x8f70,0x8f71,0x8f73,0x8f75,0x8f77,
0x8f7b,0x8fa1,0x8fa2,0x8fa5,0x8fa9,0x8fb1,0x8fb3,0x8fb5,
0x8fb7,0x9061,0x9062,0x9063,0x9065,0x9068,0x9069,0x906a,
0x906b,0x9071,0x9073,0x9075,0x9076,0x9077,0x9078,0x9079,
0x907b,0x907d,0x9081,0x9082,0x9085,0x9089,0x9091,0x9093,
0x9095,0x9096,0x9097,0x90a1,0x90a2,0x90a5,0x90a9,0x90b1,
0x90b7,0x90e1,0x90e2,0x90e4,0x90e5,0x90e9,0x90eb,0x90ec,
0x90f1,0x90f3,0x90f5,0x90f6,0x90f7,0x90fd,0x9141,0x9142,
0x9145,0x9149,0x9151,0x9153,0x9155,0x9156,0x9157,0x9161,
0x9162,0x9165,0x9169,0x9171,0x9173,0x9176,0x9177,0x917a,
0x9181,0x9185,0x91a1,0x91a2,0x91a5,0x91a9,0x91ab,0x91b1,
0x91b3,0x91b5,0x91b7,0x91bc,0x91bd,0x91c1,0x91c5,0x91c9,
0x91d6,0x9241,0x9245,0x9249,0x9251,0x9253,
0x9255,0x9261,0x9262,0x9265,0x9269,0x9273,0x9275,0x9277,
0x9281,0x9282,0x9285,0x9288,0x9289,0x9291,0x9293,0x9295,
0x9297,0x92a1,0x92b6,0x92c1,0x92e1,0x92e5,0x92e9,0x92f1,
0x92f3,0x9341,0x9342,0x9349,0x9351,0x9353,0x9357,0x9361,
0x9362,0x9365,0x9369,0x936a,0x936b,0x9371,0x9373,0x9375,
0x9377,0x9378,0x937c,0x9381,0x9385,0x9389,0x93a1,0x93a2,
0x93a5,0x93a9,0x93af,0x93b1,0x93b3,0x93b5,0x93b7,0x93bc,
0x9461,0x9462,0x9463,0x9465,0x9468,0x9469,0x946a,0x946b,
0x946c,0x9470,0x9471,0x9473,0x9475,0x9476,0x9477,0x9478,
0x9479,0x947d,0x9481,0x9482,0x9485,0x9489,0x9491,0x9493,
0x9495,0x9496,0x9497,0x94a1,0x94e1,0x94e2,0x94e3,0x94e5,
0x94e8,0x94e9,0x94eb,0x94ec,0x94f1,0x94f3,
0x94f5,0x94f7,0x94f9,0x94fc,0x9541,0x9542,0x9545,0x9549,
0x9551,0x9553,0x9555,0x9556,0x9557,0x9561,0x9565,0x9569,
0x9576,0x9577,0x9581,0x9585,0x95a1,0x95a2,0x95a5,0x95a8,
0x95a9,0x95ab,0x95ad,0x95b1,0x95b3,0x95b5,0x95b7,0x95b9,
0x95bb,0x95c1,0x95c5,0x95c9,0x95e1,0x95f6,0x9641,0x9645,
0x9649,0x9651,0x9653,0x9655,0x9661,0x9681,0x9682,0x9685,
0x9689,0x9691,0x9693,0x9695,0x9697,0x96a1,0x96b6,0x96c1,
0x96d7,0x96e1,0x96e5,0x96e9,0x96f3,0x96f5,0x96f7,0x9741,
0x9745,0x9749,0x9751,0x9757,0x9761,0x9762,0x9765,0x9768,
0x9769,0x976b,0x9771,0x9773,0x9775,0x9777,0x9781,0x97a1,
0x97a2,0x97a5,0x97a8,0x97a9,0x97b1,0x97b3,0x97b5,0x97b6,
0x97b7,0x97b8,0x9861,0x9862,0x9865,0x9869,
0x9871,0x9873,0x9875,0x9876,0x9877,0x987d,0x9881,0x9882,
0x9885,0x9889,0x9891,0x9893,0x9895,0x9896,0x9897,0x98e1,
0x98e2,0x98e5,0x98e9,0x98eb,0x98ec,0x98f1,0x98f3,0x98f5,
0x98f6,0x98f7,0x98fd,0x9941,0x9942,0x9945,0x9949,0x9951,
0x9953,0x9955,0x9956,0x9957,0x9961,0x9976,0x99a1,0x99a2,
0x99a5,0x99a9,0x99b7,0x99c1,0x99c9,0x99e1,0x9a41,0x9a45,
0x9a81,0x9a82,0x9a85,0x9a89,0x9a90,0x9a91,0x9a97,0x9ac1,
0x9ae1,0x9ae5,0x9ae9,0x9af1,0x9af3,0x9af7,0x9b61,0x9b62,
0x9b65,0x9b68,0x9b69,0x9b71,0x9b73,0x9b75,0x9b81,0x9b85,
0x9b89,0x9b91,0x9b93,0x9ba1,0x9ba5,0x9ba9,0x9bb1,0x9bb3,
0x9bb5,0x9bb7,0x9c61,0x9c62,0x9c65,0x9c69,0x9c71,0x9c73,
0x9c75,0x9c76,0x9c77,0x9c78,0x9c7c,0x9c7d,
0x9c81,0x9c82,0x9c85,0x9c89,0x9c91,0x9c93,0x9c95,0x9c96,
0x9c97,0x9ca1,0x9ca2,0x9ca5,0x9cb5,0x9cb7,0x9ce1,0x9ce2,
0x9ce5,0x9ce9,0x9cf1,0x9cf3,0x9cf5,0x9cf6,0x9cf7,0x9cfd,
0x9d41,0x9d42,0x9d45,0x9d49,0x9d51,0x9d53,0x9d55,0x9d57,
0x9d61,0x9d62,0x9d65,0x9d69,0x9d71,0x9d73,0x9d75,0x9d76,
0x9d77,0x9d81,0x9d85,0x9d93,0x9d95,0x9da1,0x9da2,0x9da5,
0x9da9,0x9db1,0x9db3,0x9db5,0x9db7,0x9dc1,0x9dc5,0x9dd7,
0x9df6,0x9e41,0x9e45,0x9e49,0x9e51,0x9e53,0x9e55,0x9e57,
0x9e61,0x9e65,0x9e69,0x9e73,0x9e75,0x9e77,0x9e81,0x9e82,
0x9e85,0x9e89,0x9e91,0x9e93,0x9e95,0x9e97,0x9ea1,0x9eb6,
0x9ec1,0x9ee1,0x9ee2,0x9ee5,0x9ee9,0x9ef1,0x9ef5,0x9ef7,
0x9f41,0x9f42,0x9f45,0x9f49,0x9f51,0x9f53,
0x9f55,0x9f57,0x9f61,0x9f62,0x9f65,0x9f69,0x9f71,0x9f73,
0x9f75,0x9f77,0x9f78,0x9f7b,0x9f7c,0x9fa1,0x9fa2,0x9fa5,
0x9fa9,0x9fb1,0x9fb3,0x9fb5,0x9fb7,0xa061,0xa062,0xa065,
0xa067,0xa068,0xa069,0xa06a,0xa06b,0xa071,0xa073,0xa075,
0xa077,0xa078,0xa07b,0xa07d,0xa081,0xa082,0xa085,0xa089,
0xa091,0xa093,0xa095,0xa096,0xa097,0xa098,0xa0a1,0xa0a2,
0xa0a9,0xa0b7,0xa0e1,0xa0e2,0xa0e5,0xa0e9,0xa0eb,0xa0f1,
0xa0f3,0xa0f5,0xa0f7,0xa0f8,0xa0fd,0xa141,0xa142,0xa145,
0xa149,0xa151,0xa153,0xa155,0xa156,0xa157,0xa161,0xa162,
0xa165,0xa169,0xa175,0xa176,0xa177,0xa179,0xa181,0xa1a1,
0xa1a2,0xa1a4,0xa1a5,0xa1a9,0xa1ab,0xa1b1,0xa1b3,0xa1b5,
0xa1b7,0xa1c1,0xa1c5,0xa1d6,0xa1d7,0xa241,
0xa245,0xa249,0xa253,0xa255,0xa257,0xa261,0xa265,0xa269,
0xa273,0xa275,0xa281,0xa282,0xa283,0xa285,0xa288,0xa289,
0xa28a,0xa28b,0xa291,0xa293,0xa295,0xa297,0xa29b,0xa29d,
0xa2a1,0xa2a5,0xa2a9,0xa2b3,0xa2b5,0xa2c1,0xa2e1,0xa2e5,
0xa2e9,0xa341,0xa345,0xa349,0xa351,0xa355,0xa361,0xa365,
0xa369,0xa371,0xa375,0xa3a1,0xa3a2,0xa3a5,0xa3a8,0xa3a9,
0xa3ab,0xa3b1,0xa3b3,0xa3b5,0xa3b6,0xa3b7,0xa3b9,0xa3bb,
0xa461,0xa462,0xa463,0xa464,0xa465,0xa468,0xa469,0xa46a,
0xa46b,0xa46c,0xa471,0xa473,0xa475,0xa477,0xa47b,0xa481,
0xa482,0xa485,0xa489,0xa491,0xa493,0xa495,0xa496,0xa497,
0xa49b,0xa4a1,0xa4a2,0xa4a5,0xa4b3,0xa4e1,0xa4e2,0xa4e5,
0xa4e8,0xa4e9,0xa4eb,0xa4f1,0xa4f3,0xa4f5,
0xa4f7,0xa4f8,0xa541,0xa542,0xa545,0xa548,0xa549,0xa551,
0xa553,0xa555,0xa556,0xa557,0xa561,0xa562,0xa565,0xa569,
0xa573,0xa575,0xa576,0xa577,0xa57b,0xa581,0xa585,0xa5a1,
0xa5a2,0xa5a3,0xa5a5,0xa5a9,0xa5b1,0xa5b3,0xa5b5,0xa5b7,
0xa5c1,0xa5c5,0xa5d6,0xa5e1,0xa5f6,0xa641,0xa642,0xa645,
0xa649,0xa651,0xa653,0xa661,0xa665,0xa681,0xa682,0xa685,
0xa688,0xa689,0xa68a,0xa68b,0xa691,0xa693,0xa695,0xa697,
0xa69b,0xa69c,0xa6a1,0xa6a9,0xa6b6,0xa6c1,0xa6e1,0xa6e2,
0xa6e5,0xa6e9,0xa6f7,0xa741,0xa745,0xa749,0xa751,0xa755,
0xa757,0xa761,0xa762,0xa765,0xa769,0xa771,0xa773,0xa775,
0xa7a1,0xa7a2,0xa7a5,0xa7a9,0xa7ab,0xa7b1,0xa7b3,0xa7b5,
0xa7b7,0xa7b8,0xa7b9,0xa861,0xa862,0xa865,
0xa869,0xa86b,0xa871,0xa873,0xa875,0xa876,0xa877,0xa87d,
0xa881,0xa882,0xa885,0xa889,0xa891,0xa893,0xa895,0xa896,
0xa897,0xa8a1,0xa8a2,0xa8b1,0xa8e1,0xa8e2,0xa8e5,0xa8e8,
0xa8e9,0xa8f1,0xa8f5,0xa8f6,0xa8f7,0xa941,0xa957,0xa961,
0xa962,0xa971,0xa973,0xa975,0xa976,0xa977,0xa9a1,0xa9a2,
0xa9a5,0xa9a9,0xa9b1,0xa9b3,0xa9b7,0xaa41,0xaa61,0xaa77,
0xaa81,0xaa82,0xaa85,0xaa89,0xaa91,0xaa95,0xaa97,0xab41,
0xab57,0xab61,0xab65,0xab69,0xab71,0xab73,0xaba1,0xaba2,
0xaba5,0xaba9,0xabb1,0xabb3,0xabb5,0xabb7,0xac61,0xac62,
0xac64,0xac65,0xac68,0xac69,0xac6a,0xac6b,0xac71,0xac73,
0xac75,0xac76,0xac77,0xac7b,0xac81,0xac82,0xac85,0xac89,
0xac91,0xac93,0xac95,0xac96,0xac97,0xaca1,
0xaca2,0xaca5,0xaca9,0xacb1,0xacb3,0xacb5,0xacb7,0xacc1,
0xacc5,0xacc9,0xacd1,0xacd7,0xace1,0xace2,0xace3,0xace4,
0xace5,0xace8,0xace9,0xaceb,0xacec,0xacf1,0xacf3,0xacf5,
0xacf6,0xacf7,0xacfc,0xad41,0xad42,0xad45,0xad49,0xad51,
0xad53,0xad55,0xad56,0xad57,0xad61,0xad62,0xad65,0xad69,
0xad71,0xad73,0xad75,0xad76,0xad77,0xad81,0xad85,0xad89,
0xad97,0xada1,0xada2,0xada3,0xada5,0xada9,0xadab,0xadb1,
0xadb3,0xadb5,0xadb7,0xadbb,0xadc1,0xadc2,0xadc5,0xadc9,
0xadd7,0xade1,0xade5,0xade9,0xadf1,0xadf5,0xadf6,0xae41,
0xae45,0xae49,0xae51,0xae53,0xae55,0xae61,0xae62,0xae65,
0xae69,0xae71,0xae73,0xae75,0xae77,0xae81,0xae82,0xae85,
0xae88,0xae89,0xae91,0xae93,0xae95,0xae97,
0xae99,0xae9b,0xae9c,0xaea1,0xaeb6,0xaec1,0xaec2,0xaec5,
0xaec9,0xaed1,0xaed7,0xaee1,0xaee2,0xaee5,0xaee9,0xaef1,
0xaef3,0xaef5,0xaef7,0xaf41,0xaf42,0xaf49,0xaf51,0xaf55,
0xaf57,0xaf61,0xaf62,0xaf65,0xaf69,0xaf6a,0xaf71,0xaf73,
0xaf75,0xaf77,0xafa1,0xafa2,0xafa5,0xafa8,0xafa9,0xafb0,
0xafb1,0xafb3,0xafb5,0xafb7,0xafbc,0xb061,0xb062,0xb064,
0xb065,0xb069,0xb071,0xb073,0xb076,0xb077,0xb07d,0xb081,
0xb082,0xb085,0xb089,0xb091,0xb093,0xb096,0xb097,0xb0b7,
0xb0e1,0xb0e2,0xb0e5,0xb0e9,0xb0eb,0xb0f1,0xb0f3,0xb0f6,
0xb0f7,0xb141,0xb145,0xb149,0xb157,0xb1a1,0xb1a2,0xb1a5,
0xb1a8,0xb1a9,0xb1ab,0xb1b1,0xb1b3,0xb1b7,0xb1c1,0xb1c2,
0xb1c5,0xb1d6,0xb1e1,0xb1f6,0xb241,0xb245,
0xb249,0xb251,0xb253,0xb261,0xb281,0xb282,0xb285,0xb289,
0xb291,0xb293,0xb297,0xb2a1,0xb2b6,0xb2c1,0xb2e1,0xb2e5,
0xb357,0xb361,0xb362,0xb365,0xb369,0xb36b,0xb370,0xb371,
0xb373,0xb381,0xb385,0xb389,0xb391,0xb3a1,0xb3a2,0xb3a5,
0xb3a9,0xb3b1,0xb3b3,0xb3b5,0xb3b7,0xb461,0xb462,0xb465,
0xb466,0xb467,0xb469,0xb46a,0xb46b,0xb470,0xb471,0xb473,
0xb475,0xb476,0xb477,0xb47b,0xb47c,0xb481,0xb482,0xb485,
0xb489,0xb491,0xb493,0xb495,0xb496,0xb497,0xb4a1,0xb4a2,
0xb4a5,0xb4a9,0xb4ac,0xb4b1,0xb4b3,0xb4b5,0xb4b7,0xb4bb,
0xb4bd,0xb4c1,0xb4c5,0xb4c9,0xb4d3,0xb4e1,0xb4e2,0xb4e5,
0xb4e6,0xb4e8,0xb4e9,0xb4ea,0xb4eb,0xb4f1,0xb4f3,0xb4f4,
0xb4f5,0xb4f6,0xb4f7,0xb4f8,0xb4fa,0xb4fc,
0xb541,0xb542,0xb545,0xb549,0xb551,0xb553,0xb555,0xb557,
0xb561,0xb562,0xb563,0xb565,0xb569,0xb56b,0xb56c,0xb571,
0xb573,0xb574,0xb575,0xb576,0xb577,0xb57b,0xb57c,0xb57d,
0xb581,0xb585,0xb589,0xb591,0xb593,0xb595,0xb596,0xb5a1,
0xb5a2,0xb5a5,0xb5a9,0xb5aa,0xb5ab,0xb5ad,0xb5b0,0xb5b1,
0xb5b3,0xb5b5,0xb5b7,0xb5b9,0xb5c1,0xb5c2,0xb5c5,0xb5c9,
0xb5d1,0xb5d3,0xb5d5,0xb5d6,0xb5d7,0xb5e1,0xb5e2,0xb5e5,
0xb5f1,0xb5f5,0xb5f7,0xb641,0xb642,0xb645,0xb649,0xb651,
0xb653,0xb655,0xb657,0xb661,0xb662,0xb665,0xb669,0xb671,
0xb673,0xb675,0xb677,0xb681,0xb682,0xb685,0xb689,0xb68a,
0xb68b,0xb691,0xb693,0xb695,0xb697,0xb6a1,0xb6a2,0xb6a5,
0xb6a9,0xb6b1,0xb6b3,0xb6b6,0xb6b7,0xb6c1,
0xb6c2,0xb6c5,0xb6c9,0xb6d1,0xb6d3,0xb6d7,0xb6e1,0xb6e2,
0xb6e5,0xb6e9,0xb6f1,0xb6f3,0xb6f5,0xb6f7,0xb741,0xb742,
0xb745,0xb749,0xb751,0xb753,0xb755,0xb757,0xb759,0xb761,
0xb762,0xb765,0xb769,0xb76f,0xb771,0xb773,0xb775,0xb777,
0xb778,0xb779,0xb77a,0xb77b,0xb77c,0xb77d,0xb781,0xb785,
0xb789,0xb791,0xb795,0xb7a1,0xb7a2,0xb7a5,0xb7a9,0xb7aa,
0xb7ab,0xb7b0,0xb7b1,0xb7b3,0xb7b5,0xb7b6,0xb7b7,0xb7b8,
0xb7bc,0xb861,0xb862,0xb865,0xb867,0xb868,0xb869,0xb86b,
0xb871,0xb873,0xb875,0xb876,0xb877,0xb878,0xb881,0xb882,
0xb885,0xb889,0xb891,0xb893,0xb895,0xb896,0xb897,0xb8a1,
0xb8a2,0xb8a5,0xb8a7,0xb8a9,0xb8b1,0xb8b7,0xb8c1,0xb8c5,
0xb8c9,0xb8e1,0xb8e2,0xb8e5,0xb8e9,0xb8eb,
0xb8f1,0xb8f3,0xb8f5,0xb8f7,0xb8f8,0xb941,0xb942,0xb945,
0xb949,0xb951,0xb953,0xb955,0xb957,0xb961,0xb965,0xb969,
0xb971,0xb973,0xb976,0xb977,0xb981,0xb9a1,0xb9a2,0xb9a5,
0xb9a9,0xb9ab,0xb9b1,0xb9b3,0xb9b5,0xb9b7,0xb9b8,0xb9b9,
0xb9bd,0xb9c1,0xb9c2,0xb9c9,0xb9d3,0xb9d5,0xb9d7,0xb9e1,
0xb9f6,0xb9f7,0xba41,0xba45,0xba49,0xba51,0xba53,0xba55,
0xba57,0xba61,0xba62,0xba65,0xba77,0xba81,0xba82,0xba85,
0xba89,0xba8a,0xba8b,0xba91,0xba93,0xba95,0xba97,0xbaa1,
0xbab6,0xbac1,0xbae1,0xbae2,0xbae5,0xbae9,0xbaf1,0xbaf3,
0xbaf5,0xbb41,0xbb45,0xbb49,0xbb51,0xbb61,0xbb62,0xbb65,
0xbb69,0xbb71,0xbb73,0xbb75,0xbb77,0xbba1,0xbba2,0xbba5,
0xbba8,0xbba9,0xbbab,0xbbb1,0xbbb3,0xbbb5,
0xbbb7,0xbbb8,0xbbbb,0xbbbc,0xbc61,0xbc62,0xbc65,0xbc67,
0xbc69,0xbc6c,0xbc71,0xbc73,0xbc75,0xbc76,0xbc77,0xbc81,
0xbc82,0xbc85,0xbc89,0xbc91,0xbc93,0xbc95,0xbc96,0xbc97,
0xbca1,0xbca5,0xbcb7,0xbce1,0xbce2,0xbce5,0xbce9,0xbcf1,
0xbcf3,0xbcf5,0xbcf6,0xbcf7,0xbd41,0xbd57,0xbd61,0xbd76,
0xbda1,0xbda2,0xbda5,0xbda9,0xbdb1,0xbdb3,0xbdb5,0xbdb7,
0xbdb9,0xbdc1,0xbdc2,0xbdc9,0xbdd6,0xbde1,0xbdf6,0xbe41,
0xbe45,0xbe49,0xbe51,0xbe53,0xbe77,0xbe81,0xbe82,0xbe85,
0xbe89,0xbe91,0xbe93,0xbe97,0xbea1,0xbeb6,0xbeb7,0xbee1,
0xbf41,0xbf61,0xbf71,0xbf75,0xbf77,0xbfa1,0xbfa2,0xbfa5,
0xbfa9,0xbfb1,0xbfb3,0xbfb7,0xbfb8,0xbfbd,0xc061,0xc062,
0xc065,0xc067,0xc069,0xc071,0xc073,0xc075,
0xc076,0xc077,0xc078,0xc081,0xc082,0xc085,0xc089,0xc091,
0xc093,0xc095,0xc096,0xc097,0xc0a1,0xc0a5,0xc0a7,0xc0a9,
0xc0b1,0xc0b7,0xc0e1,0xc0e2,0xc0e5,0xc0e9,0xc0f1,0xc0f3,
0xc0f5,0xc0f6,0xc0f7,0xc141,0xc142,0xc145,0xc149,0xc151,
0xc153,0xc155,0xc157,0xc161,0xc165,0xc176,0xc181,0xc185,
0xc197,0xc1a1,0xc1a2,0xc1a5,0xc1a9,0xc1b1,0xc1b3,0xc1b5,
0xc1b7,0xc1c1,0xc1c5,0xc1c9,0xc1d7,0xc241,0xc245,0xc249,
0xc251,0xc253,0xc255,0xc257,0xc261,0xc271,0xc281,0xc282,
0xc285,0xc289,0xc291,0xc293,0xc295,0xc297,0xc2a1,0xc2b6,
0xc2c1,0xc2c5,0xc2e1,0xc2e5,0xc2e9,0xc2f1,0xc2f3,0xc2f5,
0xc2f7,0xc341,0xc345,0xc349,0xc351,0xc357,0xc361,0xc362,
0xc365,0xc369,0xc371,0xc373,0xc375,0xc377,
0xc3a1,0xc3a2,0xc3a5,0xc3a8,0xc3a9,0xc3aa,0xc3b1,0xc3b3,
0xc3b5,0xc3b7,0xc461,0xc462,0xc465,0xc469,0xc471,0xc473,
0xc475,0xc477,0xc481,0xc482,0xc485,0xc489,0xc491,0xc493,
0xc495,0xc496,0xc497,0xc4a1,0xc4a2,0xc4b7,0xc4e1,0xc4e2,
0xc4e5,0xc4e8,0xc4e9,0xc4f1,0xc4f3,0xc4f5,0xc4f6,0xc4f7,
0xc541,0xc542,0xc545,0xc549,0xc551,0xc553,0xc555,0xc557,
0xc561,0xc565,0xc569,0xc571,0xc573,0xc575,0xc576,0xc577,
0xc581,0xc5a1,0xc5a2,0xc5a5,0xc5a9,0xc5b1,0xc5b3,0xc5b5,
0xc5b7,0xc5c1,0xc5c2,0xc5c5,0xc5c9,0xc5d1,0xc5d7,0xc5e1,
0xc5f7,0xc641,0xc649,0xc661,0xc681,0xc682,0xc685,0xc689,
0xc691,0xc693,0xc695,0xc697,0xc6a1,0xc6a5,0xc6a9,0xc6b7,
0xc6c1,0xc6d7,0xc6e1,0xc6e2,0xc6e5,0xc6e9,
0xc6f1,0xc6f3,0xc6f5,0xc6f7,0xc741,0xc745,0xc749,0xc751,
0xc761,0xc762,0xc765,0xc769,0xc771,0xc773,0xc777,0xc7a1,
0xc7a2,0xc7a5,0xc7a9,0xc7b1,0xc7b3,0xc7b5,0xc7b7,0xc861,
0xc862,0xc865,0xc869,0xc86a,0xc871,0xc873,0xc875,0xc876,
0xc877,0xc881,0xc882,0xc885,0xc889,0xc891,0xc893,0xc895,
0xc896,0xc897,0xc8a1,0xc8b7,0xc8e1,0xc8e2,0xc8e5,0xc8e9,
0xc8eb,0xc8f1,0xc8f3,0xc8f5,0xc8f6,0xc8f7,0xc941,0xc942,
0xc945,0xc949,0xc951,0xc953,0xc955,0xc957,0xc961,0xc965,
0xc976,0xc981,0xc985,0xc9a1,0xc9a2,0xc9a5,0xc9a9,0xc9b1,
0xc9b3,0xc9b5,0xc9b7,0xc9bc,0xc9c1,0xc9c5,0xc9e1,0xca41,
0xca45,0xca55,0xca57,0xca61,0xca81,0xca82,0xca85,0xca89,
0xca91,0xca93,0xca95,0xca97,0xcaa1,0xcab6,
0xcac1,0xcae1,0xcae2,0xcae5,0xcae9,0xcaf1,0xcaf3,0xcaf7,
0xcb41,0xcb45,0xcb49,0xcb51,0xcb57,0xcb61,0xcb62,0xcb65,
0xcb68,0xcb69,0xcb6b,0xcb71,0xcb73,0xcb75,0xcb81,0xcb85,
0xcb89,0xcb91,0xcb93,0xcba1,0xcba2,0xcba5,0xcba9,0xcbb1,
0xcbb3,0xcbb5,0xcbb7,0xcc61,0xcc62,0xcc63,0xcc65,0xcc69,
0xcc6b,0xcc71,0xcc73,0xcc75,0xcc76,0xcc77,0xcc7b,0xcc81,
0xcc82,0xcc85,0xcc89,0xcc91,0xcc93,0xcc95,0xcc96,0xcc97,
0xcca1,0xcca2,0xcce1,0xcce2,0xcce5,0xcce9,0xccf1,0xccf3,
0xccf5,0xccf6,0xccf7,0xcd41,0xcd42,0xcd45,0xcd49,0xcd51,
0xcd53,0xcd55,0xcd57,0xcd61,0xcd65,0xcd69,0xcd71,0xcd73,
0xcd76,0xcd77,0xcd81,0xcd89,0xcd93,0xcd95,0xcda1,0xcda2,
0xcda5,0xcda9,0xcdb1,0xcdb3,0xcdb5,0xcdb7,
0xcdc1,0xcdd7,0xce41,0xce45,0xce61,0xce65,0xce69,0xce73,
0xce75,0xce81,0xce82,0xce85,0xce88,0xce89,0xce8b,0xce91,
0xce93,0xce95,0xce97,0xcea1,0xceb7,0xcee1,0xcee5,0xcee9,
0xcef1,0xcef5,0xcf41,0xcf45,0xcf49,0xcf51,0xcf55,0xcf57,
0xcf61,0xcf65,0xcf69,0xcf71,0xcf73,0xcf75,0xcfa1,0xcfa2,
0xcfa5,0xcfa9,0xcfb1,0xcfb3,0xcfb5,0xcfb7,0xd061,0xd062,
0xd065,0xd069,0xd06e,0xd071,0xd073,0xd075,0xd077,0xd081,
0xd082,0xd085,0xd089,0xd091,0xd093,0xd095,0xd096,0xd097,
0xd0a1,0xd0b7,0xd0e1,0xd0e2,0xd0e5,0xd0e9,0xd0eb,0xd0f1,
0xd0f3,0xd0f5,0xd0f7,0xd141,0xd142,0xd145,0xd149,0xd151,
0xd153,0xd155,0xd157,0xd161,0xd162,0xd165,0xd169,0xd171,
0xd173,0xd175,0xd176,0xd177,0xd181,0xd185,
0xd189,0xd193,0xd1a1,0xd1a2,0xd1a5,0xd1a9,0xd1ae,0xd1b1,
0xd1b3,0xd1b5,0xd1b7,0xd1bb,0xd1c1,0xd1c2,0xd1c5,0xd1c9,
0xd1d5,0xd1d7,0xd1e1,0xd1e2,0xd1e5,0xd1f5,0xd1f7,0xd241,
0xd242,0xd245,0xd249,0xd253,0xd255,0xd257,0xd261,0xd265,
0xd269,0xd273,0xd275,0xd281,0xd282,0xd285,0xd289,0xd28e,
0xd291,0xd295,0xd297,0xd2a1,0xd2a5,0xd2a9,0xd2b1,0xd2b7,
0xd2c1,0xd2c2,0xd2c5,0xd2c9,0xd2d7,0xd2e1,0xd2e2,0xd2e5,
0xd2e9,0xd2f1,0xd2f3,0xd2f5,0xd2f7,0xd341,0xd342,0xd345,
0xd349,0xd351,0xd355,0xd357,0xd361,0xd362,0xd365,0xd367,
0xd368,0xd369,0xd36a,0xd371,0xd373,0xd375,0xd377,0xd37b,
0xd381,0xd385,0xd389,0xd391,0xd393,0xd397,0xd3a1,0xd3a2,
0xd3a5,0xd3a9,0xd3b1,0xd3b3,0xd3b5,0xd3b7
};

10
src/libthecore/kstbl.h Normal file
View File

@@ -0,0 +1,10 @@
/*
* Filename: kstbl.h
* Description: KS 완성형 2350자의 조합형 코드
*
* Author: 비엽 (server), myevan (Client)
*/
#ifndef __KSTBL_H__
#define __KSTBL_H__
extern unsigned KStbl[2350];
#endif

459
src/libthecore/log.cpp Normal file
View File

@@ -0,0 +1,459 @@
/*
* Filename: log.c
* Description: local log file 관련
*
* Author: 비엽 aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
#ifndef __WIN32__
#define SYSLOG_FILENAME "syslog"
#define SYSERR_FILENAME "syserr"
#define PTS_FILENAME "PTS"
#else
#define SYSLOG_FILENAME "syslog.txt"
#define SYSERR_FILENAME "syserr.txt"
#define PTS_FILENAME "PTS.txt"
#endif
typedef struct log_file_s * LPLOGFILE;
typedef struct log_file_s LOGFILE;
struct log_file_s
{
char* filename;
FILE* fp;
int last_hour;
int last_day;
};
LPLOGFILE log_file_sys = NULL;
LPLOGFILE log_file_err = NULL;
LPLOGFILE log_file_pt = NULL;
static char log_dir[32] = { 0, };
unsigned int log_keep_days = 3;
// Internal functions
LPLOGFILE log_file_init(const char* filename, const char *openmode);
void log_file_destroy(LPLOGFILE logfile);
void log_file_rotate(LPLOGFILE logfile);
void log_file_check(LPLOGFILE logfile);
void log_file_set_dir(const char *dir);
static unsigned int log_level_bits = 0;
void log_set_level(unsigned int bit)
{
log_level_bits |= bit;
}
void log_unset_level(unsigned int bit)
{
log_level_bits &= ~bit;
}
void log_set_expiration_days(unsigned int days)
{
log_keep_days = days;
}
int log_get_expiration_days(void)
{
return log_keep_days;
}
int log_init(void)
{
log_file_set_dir("./log");
do
{
log_file_sys = log_file_init(SYSLOG_FILENAME, "a+");
if( NULL == log_file_sys ) break;
log_file_err = log_file_init(SYSERR_FILENAME, "a+");
if( NULL == log_file_err ) break;
log_file_pt = log_file_init(PTS_FILENAME, "w");
if( NULL == log_file_pt ) break;
return true;
}
while( false );
return false;
}
void log_destroy(void)
{
log_file_destroy(log_file_sys);
log_file_destroy(log_file_err);
log_file_destroy(log_file_pt);
log_file_sys = NULL;
log_file_err = NULL;
log_file_pt = NULL;
}
void log_rotate(void)
{
log_file_check(log_file_sys);
log_file_check(log_file_err);
log_file_check(log_file_pt);
log_file_rotate(log_file_sys);
}
#ifndef __WIN32__
void _sys_err(const char *func, int line, const char *format, ...)
{
va_list args;
time_t ct = time(0);
char *time_s = asctime(localtime(&ct));
char buf[1024 + 2]; // \n을 붙이기 위해..
int len;
if (!log_file_err)
return;
time_s[strlen(time_s) - 1] = '\0';
len = snprintf(buf, 1024, "SYSERR: %-15.15s :: %s: ", time_s + 4, func);
buf[1025] = '\0';
if (len < 1024)
{
va_start(args, format);
vsnprintf(buf + len, 1024 - len, format, args);
va_end(args);
}
strcat(buf, "\n");
// log_file_err 에 출력
fputs(buf, log_file_err->fp);
fflush(log_file_err->fp);
// log_file_sys 에도 출력
fputs(buf, log_file_sys->fp);
fflush(log_file_sys->fp);
}
#else
void _sys_err(const char *func, int line, const char *format, ...)
{
va_list args;
time_t ct = time(0);
char *time_s = asctime(localtime(&ct));
char buf[1024 + 2]; // \n을 붙이기 위해..
int len;
if (!log_file_err)
return;
time_s[strlen(time_s) - 1] = '\0';
len = snprintf(buf, 1024, "SYSERR: %-15.15s :: %s: ", time_s + 4, func);
buf[1025] = '\0';
if (len < 1024)
{
va_start(args, format);
vsnprintf(buf + len, 1024 - len, format, args);
va_end(args);
}
strcat(buf, "\n");
// log_file_err 에 출력
fputs(buf, log_file_err->fp);
fflush(log_file_err->fp);
// log_file_sys 에도 출력
fputs(buf, log_file_sys->fp);
fflush(log_file_sys->fp);
fputs(buf, stdout);
fflush(stdout);
}
#endif
static char sys_log_header_string[33] = { 0, };
void sys_log_header(const char *header)
{
strncpy(sys_log_header_string, header, 32);
}
void sys_log(unsigned int bit, const char *format, ...)
{
va_list args;
if (bit != 0 && !(log_level_bits & bit))
return;
if (log_file_sys)
{
time_t ct = time(0);
char *time_s = asctime(localtime(&ct));
fprintf(log_file_sys->fp, sys_log_header_string);
time_s[strlen(time_s) - 1] = '\0';
fprintf(log_file_sys->fp, "%-15.15s :: ", time_s + 4);
va_start(args, format);
vfprintf(log_file_sys->fp, format, args);
va_end(args);
fputc('\n', log_file_sys->fp);
fflush(log_file_sys->fp);
}
#ifndef __WIN32__
// log_level이 1 이상일 경우에는 테스트일 경우가 많으니 stdout에도 출력한다.
if (log_level_bits > 1)
{
#endif
fprintf(stdout, sys_log_header_string);
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fputc('\n', stdout);
fflush(stdout);
#ifndef __WIN32__
}
#endif
}
void pt_log(const char *format, ...)
{
va_list args;
if (!log_file_pt)
return;
va_start(args, format);
vfprintf(log_file_pt->fp, format, args);
va_end(args);
fputc('\n', log_file_pt->fp);
fflush(log_file_pt->fp);
}
LPLOGFILE log_file_init(const char * filename, const char * openmode)
{
LPLOGFILE logfile;
FILE * fp;
struct tm curr_tm;
time_t time_s;
time_s = time(0);
curr_tm = *localtime(&time_s);
fp = fopen(filename, openmode);
if (!fp)
return NULL;
logfile = (LPLOGFILE) malloc(sizeof(LOGFILE));
logfile->filename = strdup(filename);
logfile->fp = fp;
logfile->last_hour = curr_tm.tm_hour;
logfile->last_day = curr_tm.tm_mday;
return (logfile);
}
void log_file_destroy(LPLOGFILE logfile)
{
if (logfile == NULL) {
return;
}
if (logfile->filename)
{
free(logfile->filename);
logfile->filename = NULL;
}
if (logfile->fp)
{
fclose(logfile->fp);
logfile->fp = NULL;
}
free(logfile);
}
void log_file_check(LPLOGFILE logfile)
{
struct stat sb;
// 파일이 없으므로 다시 연다.
if (stat(logfile->filename, &sb) != 0 && errno == ENOENT)
{
fclose(logfile->fp);
logfile->fp = fopen(logfile->filename, "a+");
}
}
void log_file_delete_old(const char *filename)
{
struct stat sb;
int num1, num2;
char buf[32];
char system_cmd[64];
struct tm new_tm;
if (stat(filename, &sb) == -1)
{
perror("log_file_delete_old: stat");
return;
}
if (!S_ISDIR(sb.st_mode))
return;
new_tm = *tm_calc(NULL, -log_keep_days);
sprintf(buf, "%04d%02d%02d", new_tm.tm_year + 1900, new_tm.tm_mon + 1, new_tm.tm_mday);
num1 = atoi(buf);
#ifndef __WIN32__
{
struct dirent ** namelist;
int n;
n = scandir(filename, &namelist, 0, alphasort);
if (n < 0)
perror("scandir");
else
{
char name[MAXNAMLEN+1];
while (n-- > 0)
{
strncpy(name, namelist[n]->d_name, 255);
name[255] = '\0';
free(namelist[n]);
if (*name == '.')
continue;
if (!isdigit(*name))
continue;
num2 = atoi(name);
if (num2 <= num1)
{
sprintf(system_cmd, "rm -rf %s/%s", filename, name);
system(system_cmd);
sys_log(0, "%s: SYSTEM_CMD: %s", __FUNCTION__, system_cmd);
fprintf(stderr, "%s: SYSTEM_CMD: %s %s:%d %s:%d\n", __FUNCTION__, system_cmd, buf, num1, name, num2);
}
}
}
free(namelist);
}
#else
{
WIN32_FIND_DATA fdata;
HANDLE hFind;
if ((hFind = FindFirstFile(filename, &fdata)) != INVALID_HANDLE_VALUE)
{
do
{
if (!isdigit(*fdata.cFileName))
continue;
num2 = atoi(fdata.cFileName);
if (num2 <= num1)
{
sprintf(system_cmd, "del %s\\%s", filename, fdata.cFileName);
system(system_cmd);
sys_log(0, "SYSTEM_CMD: %s", system_cmd);
}
}
while (FindNextFile(hFind, &fdata));
}
}
#endif
}
void log_file_rotate(LPLOGFILE logfile)
{
struct tm curr_tm;
time_t time_s;
char dir[128];
char system_cmd[128];
time_s = time(0);
curr_tm = *localtime(&time_s);
if (curr_tm.tm_mday != logfile->last_day)
{
struct tm new_tm;
new_tm = *tm_calc(&curr_tm, -3);
#ifndef __WIN32__
sprintf(system_cmd, "rm -rf %s/%04d%02d%02d", log_dir, new_tm.tm_year + 1900, new_tm.tm_mon + 1, new_tm.tm_mday);
#else
sprintf(system_cmd, "del %s\\%04d%02d%02d", log_dir, new_tm.tm_year + 1900, new_tm.tm_mon + 1, new_tm.tm_mday);
#endif
system(system_cmd);
sys_log(0, "SYSTEM_CMD: %s", system_cmd);
logfile->last_day = curr_tm.tm_mday;
}
if (curr_tm.tm_hour != logfile->last_hour)
{
struct stat stat_buf;
snprintf(dir, 128, "%s/%04d%02d%02d", log_dir, curr_tm.tm_year + 1900, curr_tm.tm_mon + 1, curr_tm.tm_mday);
if (stat(dir, &stat_buf) != 0 || S_ISDIR(stat_buf.st_mode))
{
#ifdef __WIN32__
CreateDirectory(dir, NULL);
#else
mkdir(dir, S_IRWXU);
#endif
}
sys_log(0, "SYSTEM: LOG ROTATE (%04d-%02d-%02d %d)",
curr_tm.tm_year + 1900, curr_tm.tm_mon + 1, curr_tm.tm_mday, logfile->last_hour);
// 로그 파일을 닫고
fclose(logfile->fp);
// 옮긴다.
#ifndef __WIN32__
snprintf(system_cmd, 128, "mv %s %s/%s.%02d", logfile->filename, dir, logfile->filename, logfile->last_hour);
#else
snprintf(system_cmd, 128, "move %s %s\\%s.%02d", logfile->filename, dir, logfile->filename, logfile->last_hour);
#endif
system(system_cmd);
// 마지막 저장시간 저장
logfile->last_hour = curr_tm.tm_hour;
// 로그 파일을 다시 연다.
logfile->fp = fopen(logfile->filename, "a+");
}
}
void log_file_set_dir(const char *dir)
{
strcpy(log_dir, dir);
log_file_delete_old(log_dir);
}

39
src/libthecore/log.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef __INC_LIBTHECORE_LOG_H__
#define __INC_LIBTHECORE_LOG_H__
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
extern int log_init(void);
extern void log_destroy(void);
extern void log_rotate(void);
// 로그 레벨 처리 (레벨은 bitvector로 처리된다)
extern void log_set_level(unsigned int level);
extern void log_unset_level(unsigned int level);
// 로그 파일을 얼만큼 보관하는가에 대한 함수
extern void log_set_expiration_days(unsigned int days);
extern int log_get_expiration_days(void);
#ifndef __WIN32__
extern void _sys_err(const char *func, int line, const char *format, ...);
#else
extern void _sys_err(const char *func, int line, const char *format, ...);
#endif
extern void sys_log_header(const char *header);
extern void sys_log(unsigned int lv, const char *format, ...);
extern void pt_log(const char *format, ...);
#ifndef __WIN32__
#define sys_err(fmt, args...) _sys_err(__FUNCTION__, __LINE__, fmt, ##args)
#else
#define sys_err(fmt, ...) _sys_err(__FUNCTION__, __LINE__, fmt, __VA_ARGS__)
#endif // __WIN32__
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __INC_LOG_H__

124
src/libthecore/main.cpp Normal file
View File

@@ -0,0 +1,124 @@
/*
* Filename: main.c
* Description: 라이브러리 초기화/삭제 등
*
* Author: 비엽 aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
#include "memory.h"
extern void GOST_Init();
LPHEART thecore_heart = NULL;
volatile int shutdowned = FALSE;
volatile int tics = 0;
unsigned int thecore_profiler[NUM_PF];
static int pid_init(void)
{
#ifdef __WIN32__
return true;
#else
FILE* fp;
if ((fp = fopen("pid", "w")))
{
fprintf(fp, "%d", getpid());
fclose(fp);
sys_err("\nStart of pid: %d\n", getpid());
}
else
{
printf("pid_init(): could not open file for writing. (filename: ./pid)");
sys_err("\nError writing pid file\n");
return false;
}
return true;
#endif
}
static void pid_deinit(void)
{
#ifdef __WIN32__
return;
#else
remove("./pid");
sys_err("\nEnd of pid\n");
#endif
}
int thecore_init(int fps, HEARTFUNC heartbeat_func)
{
#ifdef __WIN32__
srand(time(0));
#else
srandom(time(0) + getpid() + getuid());
srandomdev();
#endif
signal_setup();
if (!log_init() || !pid_init())
return false;
GOST_Init();
thecore_heart = heart_new(1000000 / fps, heartbeat_func);
return true;
}
void thecore_shutdown()
{
shutdowned = TRUE;
}
int thecore_idle(void)
{
thecore_tick();
if (shutdowned)
return 0;
int pulses;
DWORD t = get_dword_time();
if (!(pulses = heart_idle(thecore_heart)))
{
thecore_profiler[PF_IDLE] += (get_dword_time() - t);
return 0;
}
thecore_profiler[PF_IDLE] += (get_dword_time() - t);
return pulses;
}
void thecore_destroy(void)
{
pid_deinit();
log_destroy();
}
int thecore_pulse(void)
{
return (thecore_heart->pulse);
}
float thecore_pulse_per_second(void)
{
return ((float) thecore_heart->passes_per_sec);
}
float thecore_time(void)
{
return ((float) thecore_heart->pulse / (float) thecore_heart->passes_per_sec);
}
int thecore_is_shutdowned(void)
{
return shutdowned;
}
void thecore_tick(void)
{
++tics;
}

40
src/libthecore/main.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef __INC_LIBTHECORE_MAIN_H__
#define __INC_LIBTHECORE_MAIN_H__
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#ifdef __LIBTHECORE__
extern volatile int tics;
extern volatile int shutdowned;
#endif
#include "heart.h"
extern LPHEART thecore_heart;
enum ENUM_PROFILER
{
PF_IDLE,
PF_HEARTBEAT,
NUM_PF
};
extern unsigned int thecore_profiler[NUM_PF];
extern int thecore_init(int fps, HEARTFUNC heartbeat_func);
extern int thecore_idle(void);
extern void thecore_shutdown(void);
extern void thecore_destroy(void);
extern int thecore_pulse(void);
extern float thecore_time(void);
extern float thecore_pulse_per_second(void);
extern int thecore_is_shutdowned(void);
extern void thecore_tick(void); // tics Áõ°¡
#ifdef __cplusplus
}
#endif
#endif

134
src/libthecore/memcpy.cpp Normal file
View File

@@ -0,0 +1,134 @@
/*
(c) Copyright 2000-2002 convergence integrated media GmbH.
(c) Copyright 2002 convergence GmbH.
All rights reserved.
Written by Denis Oliver Kropp <dok@directfb.org>,
Andreas Hundt <andi@fischlustig.de> and
Sven Neumann <sven@convergence.de>.
Fast memcpy code was taken from xine (see below).
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/*
* Copyright (C) 2001 the xine project
*
* This file is part of xine, a unix video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* These are the MMX/MMX2/SSE optimized versions of memcpy
*
* This code was adapted from Linux Kernel sources by Nick Kurshev to
* the mplayer program. (http://mplayer.sourceforge.net)
*
* Miguel Freitas split the #ifdefs into several specialized functions that
* are benchmarked at runtime by xine. Some original comments from Nick
* have been preserved documenting some MMX/SSE oddities.
* Also added kernel memcpy function that seems faster than glibc one.
*
*/
/* Original comments from mplayer (file: aclib.c) This part of code
was taken by me from Linux-2.4.3 and slightly modified for MMX, MMX2,
SSE instruction set. I have done it since linux uses page aligned
blocks but mplayer uses weakly ordered data and original sources can
not speedup them. Only using PREFETCHNTA and MOVNTQ together have
effect!
From IA-32 Intel Architecture Software Developer's Manual Volume 1,
Order Number 245470:
"10.4.6. Cacheability Control, Prefetch, and Memory Ordering Instructions"
Data referenced by a program can be temporal (data will be used
again) or non-temporal (data will be referenced once and not reused
in the immediate future). To make efficient use of the processor's
caches, it is generally desirable to cache temporal data and not
cache non-temporal data. Overloading the processor's caches with
non-temporal data is sometimes referred to as "polluting the
caches". The non-temporal data is written to memory with
Write-Combining semantics.
The PREFETCHh instructions permits a program to load data into the
processor at a suggested cache level, so that it is closer to the
processors load and store unit when it is needed. If the data is
already present in a level of the cache hierarchy that is closer to
the processor, the PREFETCHh instruction will not result in any data
movement. But we should you PREFETCHNTA: Non-temporal data fetch
data into location close to the processor, minimizing cache
pollution.
The MOVNTQ (store quadword using non-temporal hint) instruction
stores packed integer data from an MMX to memory, using a
non-temporal hint. The MOVNTPS (store packed single-precision
floating-point values using non-temporal hint) instruction stores
packed floating-point data from an XMM to memory, using a
non-temporal hint.
The SFENCE (Store Fence) instruction controls write ordering by
creating a fence for memory store operations. This instruction
guarantees that the results of every store instruction that precedes
the store fence in program order is globally visible before any
store instruction that follows the fence. The SFENCE instruction
provides an efficient way of ensuring ordering between procedures
that produce weakly-ordered data and procedures that consume that
data.
If you have questions please contact with me: Nick Kurshev:
nickols_k@mail.ru.
*/
/* mmx v.1 Note: Since we added alignment of destinition it speedups
of memory copying on PentMMX, Celeron-1 and P2 upto 12% versus
standard (non MMX-optimized) version.
Note: on K6-2+ it speedups memory copying upto 25% and
on K7 and P3 about 500% (5 times).
*/
/* Additional notes on gcc assembly and processors: [MF]
prefetch is specific for AMD processors, the intel ones should be
prefetch0, prefetch1, prefetch2 which are not recognized by my gcc.
prefetchnta is supported both on athlon and pentium 3.
therefore i will take off prefetchnta instructions from the mmx1
version to avoid problems on pentium mmx and k6-2.
quote of the day:
"Using prefetches efficiently is more of an art than a science"
*/
#ifndef __WIN32__
#include <string.h>
void *(*thecore_memcpy) (void * to, const void * from, size_t len) = memcpy;
#endif

23
src/libthecore/memcpy.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef __INC_LIBTHECORE_MEMCPY_H__
#define __INC_LIBTHECORE_MEMCPY_H__
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __LIBTHECORE__
void thecore_find_best_memcpy();
#endif
#ifndef __WIN32__
extern void *(*thecore_memcpy) (void * to, const void * from, size_t len);
#else
#include <cstring>
#define thecore_memcpy memcpy
#endif
#ifdef __cplusplus
};
#endif
#endif

91
src/libthecore/signal.cpp Normal file
View File

@@ -0,0 +1,91 @@
/*
* Filename: signal.c
* Description: ½Ã±×³Î °ü·Ã ÇÔ¼ö.
*
* Author: ºñ¿± aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
#ifdef __WIN32__
void signal_setup() {}
void signal_timer_disable() {}
void signal_timer_enable(int timeout_seconds) {}
#elif __FreeBSD__
#define RETSIGTYPE void
RETSIGTYPE reap(int sig)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
signal(SIGCHLD, reap);
}
RETSIGTYPE checkpointing(int sig)
{
if (!tics)
{
sys_err("CHECKPOINT shutdown: tics did not updated.");
abort();
}
else
tics = 0;
}
RETSIGTYPE hupsig(int sig)
{
shutdowned = TRUE;
sys_err("SIGHUP, SIGINT, SIGTERM signal has been received. shutting down.");
}
RETSIGTYPE usrsig(int sig)
{
core_dump();
}
void signal_timer_disable(void)
{
struct itimerval itime;
struct timeval interval;
interval.tv_sec = 0;
interval.tv_usec = 0;
itime.it_interval = interval;
itime.it_value = interval;
setitimer(ITIMER_VIRTUAL, &itime, NULL);
}
void signal_timer_enable(int sec)
{
struct itimerval itime;
struct timeval interval;
interval.tv_sec = sec;
interval.tv_usec = 0;
itime.it_interval = interval;
itime.it_value = interval;
setitimer(ITIMER_VIRTUAL, &itime, NULL);
}
void signal_setup(void)
{
signal_timer_enable(30);
signal(SIGVTALRM, checkpointing);
/* just to be on the safe side: */
signal(SIGHUP, hupsig);
signal(SIGCHLD, reap);
signal(SIGINT, hupsig);
signal(SIGTERM, hupsig);
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, SIG_IGN);
signal(SIGUSR1, usrsig);
}
#endif

16
src/libthecore/signal.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef __INC_LIBTHECORE_SIGNAL_H__
#define __INC_LIBTHECORE_SIGNAL_H__
#ifdef __cplusplus
extern "C"
{
#endif
extern void signal_setup();
extern void signal_timer_disable();
extern void signal_timer_enable(int timeout_seconds);
#ifdef __cplusplus
};
#endif
#endif

547
src/libthecore/socket.cpp Normal file
View File

@@ -0,0 +1,547 @@
/*
* Filename: socket.c
* Description: 소켓 관련 소스.
*
* Author: 비엽 aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
/* Forwards */
void socket_lingeron(socket_t s);
void socket_lingeroff(socket_t s);
void socket_timeout(socket_t s, long sec, long usec);
void socket_reuse(socket_t s);
void socket_keepalive(socket_t s);
int socket_udp_read(socket_t desc, char * read_point, size_t space_left, struct sockaddr * from, socklen_t * fromlen)
{
/*
ssize_t recvfrom(int s, void * buf, size_t len, int flags, struct sockaddr * from, socklen_t * fromlen);
*/
ssize_t ret;
ret = recvfrom(desc, read_point, space_left, 0, from, fromlen);
return (ret);
}
int socket_read(socket_t desc, char* read_point, size_t space_left)
{
int ret;
ret = recv(desc, read_point, space_left, 0);
if (ret > 0)
return ret;
if (ret == 0) // 정상적으로 접속 끊김
return -1;
#ifdef EINTR /* Interrupted system call - various platforms */
if (errno == EINTR)
return (0);
#endif
#ifdef EAGAIN /* POSIX */
if (errno == EAGAIN)
return (0);
#endif
#ifdef EWOULDBLOCK /* BSD */
if (errno == EWOULDBLOCK)
return (0);
#endif /* EWOULDBLOCK */
#ifdef EDEADLK /* Macintosh */
if (errno == EDEADLK)
return (0);
#endif
#ifdef __WIN32__
int wsa_error = WSAGetLastError();
if (wsa_error == WSAEWOULDBLOCK) {
return 0;
}
sys_log(0, "socket_read: WSAGetLastError returned %d", wsa_error);
#endif
sys_err("about to lose connection");
return -1;
}
int socket_write_tcp(socket_t desc, const char *txt, int length)
{
int bytes_written = send(desc, txt, length, 0);
// 성공
if (bytes_written > 0)
return (bytes_written);
if (bytes_written == 0)
return -1;
#ifdef EAGAIN /* POSIX */
if (errno == EAGAIN)
return 0;
#endif
#ifdef EWOULDBLOCK /* BSD */
if (errno == EWOULDBLOCK)
return 0;
#endif
#ifdef EDEADLK /* Macintosh */
if (errno == EDEADLK)
return 0;
#endif
#ifdef __WIN32__
int wsa_error = WSAGetLastError();
if (wsa_error == WSAEWOULDBLOCK) {
return 0;
}
sys_log(0, "socket_write_tcp: WSAGetLastError returned %d", wsa_error);
#endif
/* Looks like the error was fatal. Too bad. */
return -1;
}
int socket_write(socket_t desc, const char *data, size_t length)
{
size_t total;
int bytes_written;
total = length;
do
{
if ((bytes_written = socket_write_tcp(desc, data, total)) < 0)
{
#ifdef EWOULDBLOCK
if (errno == EWOULDBLOCK)
errno = EAGAIN;
#endif
if (errno == EAGAIN)
sys_err("socket write would block, about to close!");
else
sys_err("write to desc error"); // '보통' 상대편으로 부터 접속이 끊긴 것이다.
return -1;
}
else
{
data += bytes_written;
total -= bytes_written;
}
}
while (total > 0);
return 0;
}
int socket_bind(const char * ip, int port, int protocol)
{
int s;
#ifdef __WIN32
SOCKADDR_IN sa;
#else
struct sockaddr_in sa;
#endif
if ((s = socket(AF_INET, protocol, 0)) < 0)
{
sys_err("socket: %s", strerror(errno));
return -1;
}
socket_reuse(s);
#ifndef __WIN32__
socket_lingeroff(s);
#else
// Winsock2: SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER, and SO_OOBINLINE are
// not supported on sockets of type SOCK_DGRAM
if (protocol == SOCK_STREAM) {
socket_lingeroff(s);
}
#endif
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
//윈도우 서버는 개발용으로만 쓰기 때문에 BIND ip를 INADDR_ANY로 고정
//(테스트의 편의성을 위해)
#ifndef __WIN32__
sa.sin_addr.s_addr = inet_addr(ip);
#else
sa.sin_addr.s_addr = INADDR_ANY;
#endif
sa.sin_port = htons((unsigned short) port);
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
{
sys_err("bind: %s", strerror(errno));
return -1;
}
socket_nonblock(s);
if (protocol == SOCK_STREAM)
{
sys_log(0, "SYSTEM: BINDING TCP PORT ON [%d] (fd %d)", port, s);
listen(s, SOMAXCONN);
}
else
sys_log(0, "SYSTEM: BINDING UDP PORT ON [%d] (fd %d)", port, s);
return s;
}
int socket_tcp_bind(const char * ip, int port)
{
return socket_bind(ip, port, SOCK_STREAM);
}
int socket_udp_bind(const char * ip, int port)
{
return socket_bind(ip, port, SOCK_DGRAM);
}
void socket_close(socket_t s)
{
#ifdef __WIN32__
closesocket(s);
#else
close(s);
#endif
}
socket_t socket_accept(socket_t s, struct sockaddr_in *peer)
{
socket_t desc;
socklen_t i;
i = sizeof(*peer);
if ((desc = accept(s, (struct sockaddr *) peer, &i)) == -1)
{
sys_err("accept: %s (fd %d)", strerror(errno), s);
return -1;
}
if (desc >= 65500)
{
sys_err("SOCKET FD 65500 LIMIT! %d", desc);
socket_close(s);
return -1;
}
socket_nonblock(desc);
socket_lingeroff(desc);
return (desc);
}
socket_t socket_connect(const char* host, WORD port)
{
socket_t s = 0;
struct sockaddr_in server_addr;
int rslt;
/* 소켓주소 구조체 초기화 */
memset(&server_addr, 0, sizeof(server_addr));
if (isdigit(*host))
server_addr.sin_addr.s_addr = inet_addr(host);
else
{
struct hostent *hp;
if ((hp = gethostbyname(host)) == NULL)
{
sys_err("socket_connect(): can not connect to %s:%d", host, port);
return -1;
}
thecore_memcpy((char* ) &server_addr.sin_addr, hp->h_addr, sizeof(server_addr.sin_addr));
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
return -1;
}
socket_keepalive(s);
socket_sndbuf(s, 233016);
socket_rcvbuf(s, 233016);
socket_timeout(s, 10, 0);
socket_lingeron(s);
/* 연결요청 */
if ((rslt = connect(s, (struct sockaddr *) &server_addr, sizeof(server_addr))) < 0)
{
socket_close(s);
#ifdef __WIN32__
switch (WSAGetLastError())
#else
switch (rslt)
#endif
{
#ifdef __WIN32__
case WSAETIMEDOUT:
#else
case EINTR:
#endif
sys_err("HOST %s:%d connection timeout.", host, port);
break;
#ifdef __WIN32__
case WSAECONNREFUSED:
#else
case ECONNREFUSED:
#endif
sys_err("HOST %s:%d port is not opened. connection refused.", host, port);
break;
#ifdef __WIN32__
case WSAENETUNREACH:
#else
case ENETUNREACH:
#endif
sys_err("HOST %s:%d is not reachable from this host.", host, port);
break;
default:
sys_err("HOST %s:%d, could not connect.", host, port);
break;
}
perror("connect");
return (-1);
}
return (s);
}
#ifndef __WIN32__
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
#endif
void socket_nonblock(socket_t s)
{
int flags;
flags = fcntl(s, F_GETFL, 0);
flags |= O_NONBLOCK;
if (fcntl(s, F_SETFL, flags) < 0)
{
sys_err("fcntl: nonblock: %s", strerror(errno));
return;
}
}
void socket_block(socket_t s)
{
int flags;
flags = fcntl(s, F_GETFL, 0);
flags &= ~O_NONBLOCK;
if (fcntl(s, F_SETFL, flags) < 0)
{
sys_err("fcntl: nonblock: %s", strerror(errno));
return;
}
}
#else
void socket_nonblock(socket_t s)
{
unsigned long val = 1;
ioctlsocket(s, FIONBIO, &val);
}
void socket_block(socket_t s)
{
unsigned long val = 0;
ioctlsocket(s, FIONBIO, &val);
}
#endif
void socket_dontroute(socket_t s)
{
int set;
if (setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (const char *) &set, sizeof(int)) < 0)
{
sys_err("setsockopt: dontroute: %s", strerror(errno));
socket_close(s);
return;
}
}
void socket_lingeroff(socket_t s)
{
#ifdef __WIN32__
int linger;
linger = 0;
#else
struct linger linger;
linger.l_onoff = 0;
linger.l_linger = 0;
#endif
if (setsockopt(s, SOL_SOCKET, SO_LINGER, (const char*) &linger, sizeof(linger)) < 0)
{
sys_err("setsockopt: linger: %s", strerror(errno));
socket_close(s);
return;
}
}
void socket_lingeron(socket_t s)
{
#ifdef __WIN32__
int linger;
linger = 0;
#else
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
#endif
if (setsockopt(s, SOL_SOCKET, SO_LINGER, (const char*) &linger, sizeof(linger)) < 0)
{
sys_err("setsockopt: linger: %s", strerror(errno));
socket_close(s);
return;
}
}
void socket_rcvbuf(socket_t s, unsigned int opt)
{
socklen_t optlen;
optlen = sizeof(opt);
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const char*) &opt, optlen) < 0)
{
sys_err("setsockopt: rcvbuf: %s", strerror(errno));
socket_close(s);
return;
}
opt = 0;
optlen = sizeof(opt);
if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*) &opt, &optlen) < 0)
{
sys_err("getsockopt: rcvbuf: %s", strerror(errno));
socket_close(s);
return;
}
sys_log(1, "SYSTEM: %d: receive buffer changed to %d", s, opt);
}
void socket_sndbuf(socket_t s, unsigned int opt)
{
socklen_t optlen;
optlen = sizeof(opt);
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char*) &opt, optlen) < 0)
{
sys_err("setsockopt: sndbuf: %s", strerror(errno));
return;
}
opt = 0;
optlen = sizeof(opt);
if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*) &opt, &optlen) < 0)
{
sys_err("getsockopt: sndbuf: %s", strerror(errno));
return;
}
sys_log(1, "SYSTEM: %d: send buffer changed to %d", s, opt);
}
// sec : seconds, usec : microseconds
void socket_timeout(socket_t s, long sec, long usec)
{
#ifndef __WIN32__
struct timeval rcvopt;
struct timeval sndopt;
socklen_t optlen = sizeof(rcvopt);
rcvopt.tv_sec = sndopt.tv_sec = sec;
rcvopt.tv_usec = sndopt.tv_usec = usec;
#else
socklen_t rcvopt, sndopt;
socklen_t optlen = sizeof(rcvopt);
sndopt = rcvopt = (sec * 1000) + (usec / 1000);
#endif
if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*) &rcvopt, optlen) < 0)
{
sys_err("setsockopt: timeout: %s", strerror(errno));
socket_close(s);
return;
}
if (getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*) &rcvopt, &optlen) < 0)
{
sys_err("getsockopt: timeout: %s", strerror(errno));
socket_close(s);
return;
}
optlen = sizeof(sndopt);
if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*) &sndopt, optlen) < 0)
{
sys_err("setsockopt: timeout: %s", strerror(errno));
socket_close(s);
return;
}
if (getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*) &sndopt, &optlen) < 0)
{
sys_err("getsockopt: timeout: %s", strerror(errno));
socket_close(s);
return;
}
#ifndef __WIN32__
sys_log(1, "SYSTEM: %d: TIMEOUT RCV: %d.%d, SND: %d.%d", s, rcvopt.tv_sec, rcvopt.tv_usec, sndopt.tv_sec, sndopt.tv_usec);
#endif
}
void socket_reuse(socket_t s)
{
int opt = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*) &opt, sizeof(opt)) < 0)
{
sys_err("setsockopt: reuse: %s", strerror(errno));
socket_close(s);
return;
}
}
void socket_keepalive(socket_t s)
{
int opt = 1;
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (const char*) &opt, sizeof(opt)) < 0)
{
perror("setsockopt: keepalive");
socket_close(s);
return;
}
}

45
src/libthecore/socket.h Normal file
View File

@@ -0,0 +1,45 @@
/*
* Filename: socket.c
* Description: ¼ÒÄÏ °ü·Ã ÇÔ¼ö Çì´õ.
*
* Author: ºñ¿± (server), myevan (Client)
*/
#ifndef __INC_LIBTHECORE_SOCKET_H__
#define __INC_LIBTHECORE_SOCKET_H__
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#ifdef __WIN32__
typedef int socklen_t;
#else
#define INVALID_SOCKET -1
#endif
extern int socket_read(socket_t desc, char* read_point, size_t space_left);
extern int socket_write(socket_t desc, const char *data, size_t length);
extern int socket_udp_read(socket_t desc, char * read_point, size_t space_left, struct sockaddr * from, socklen_t * fromlen);
extern int socket_tcp_bind(const char * ip, int port);
extern int socket_udp_bind(const char * ip, int port);
extern socket_t socket_accept(socket_t s, struct sockaddr_in *peer);
extern void socket_close(socket_t s);
extern socket_t socket_connect(const char* host, WORD port);
extern void socket_nonblock(socket_t s);
extern void socket_block(socket_t s);
extern void socket_dontroute(socket_t s);
extern void socket_lingeroff(socket_t s);
extern void socket_lingeron(socket_t s);
extern void socket_sndbuf(socket_t s, unsigned int opt);
extern void socket_rcvbuf(socket_t s, unsigned int opt);
#ifdef __cplusplus
};
#endif
#endif

145
src/libthecore/stdafx.h Normal file
View File

@@ -0,0 +1,145 @@
#ifndef __INC_LIBTHECORE_STDAFX_H__
#define __INC_LIBTHECORE_STDAFX_H__
#if defined(__GNUC__)
#define INLINE __inline__
#elif defined(_MSC_VER)
#define INLINE inline
#endif
#ifdef __WIN32__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <tchar.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <conio.h>
#include <process.h>
#include <limits.h>
#include <math.h>
#include <locale.h>
#include <io.h>
#include <direct.h>
#include <fcntl.h>
#include "xdirent.h"
#include "xgetopt.h"
#define S_ISDIR(m) (m & _S_IFDIR)
#define snprintf _snprintf
struct timespec
{
time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
#define __USE_SELECT__
#define PATH_MAX _MAX_PATH
// C runtime library adjustments
#define strlcat(dst, src, size) strcat_s(dst, size, src)
#define strlcpy(dst, src, size) strncpy_s(dst, size, src, _TRUNCATE)
#define strtoull(str, endptr, base) _strtoui64(str, endptr, base)
#define strtof(str, endptr) (float)strtod(str, endptr)
#define strcasecmp(s1, s2) stricmp(s1, s2)
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
#define atoll(str) _atoi64(str)
#define localtime_r(timet, result) localtime_s(result, timet)
#define strtok_r(s, delim, ptrptr) strtok_s(s, delim, ptrptr)
#include <boost/__typeof/__typeof.hpp>
#define __typeof(t) BOOST_TYPEOF(t)
// dummy declaration of non-supported signals
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
inline void usleep(unsigned long usec) {
::Sleep(usec / 1000);
}
inline unsigned sleep(unsigned sec) {
::Sleep(sec * 1000);
return 0;
}
inline double rint(double x)
{
return ::floor(x+.5);
}
#else
#ifndef __FreeBSD__
#define __USE_SELECT__
#ifdef __CYGWIN__
#define _POSIX_SOURCE 1
#endif
#endif
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
#ifdef __FreeBSD__
#include <sys/event.h>
#endif
#endif
#ifndef false
#define false 0
#define true (!false)
#endif
#ifndef FALSE
#define FALSE false
#define TRUE (!FALSE)
#endif
#include "typedef.h"
#include "heart.h"
#include "fdwatch.h"
#include "socket.h"
#include "kstbl.h"
#include "hangul.h"
#include "buffer.h"
#include "signal.h"
#include "log.h"
#include "main.h"
#include "utils.h"
#include "crypt.h"
#include "memcpy.h"
#endif // __INC_LIBTHECORE_STDAFX_H__

338
src/libthecore/tea.cpp Normal file
View File

@@ -0,0 +1,338 @@
/*
* Filename: tea.c
* Description: TEA 암호화 모듈
*
* Author: 김한주 (aka. 비엽, Cronan), 송영진 (aka. myevan, 빗자루)
*/
#include "stdafx.h"
/*
* TEA Encryption Module Instruction
* Edited by 김한주 aka. 비엽, Cronan
*
* void tea_code(const DWORD sz, const DWORD sy, const DWORD *key, DWORD *dest)
* void tea_decode(const DWORD sz, const DWORD sy, const DWORD *key, DWORD *dest)
* 8바이트를 암호/복호화 할때 사용된다. key 는 16 바이트여야 한다.
* sz, sy 는 8바이트의 역순으로 대입한다.
*
* int tea_decrypt(DWORD *dest, const DWORD *src, const DWORD *key, int size);
* int tea_encrypt(DWORD *dest, const DWORD *src, const DWORD *key, int size);
* 한꺼번에 8 바이트 이상을 암호/복호화 할때 사용한다. 만약 size 가
* 8의 배수가 아니면 8의 배수로 크기를 "늘려서" 암호화 한다.
*
* ex. tea_code(pdwSrc[1], pdwSrc[0], pdwKey, pdwDest);
* tea_decrypt(pdwDest, pdwSrc, pdwKey, nSize);
*/
#define TEA_ROUND 32 // 32 를 권장하며, 높을 수록 결과가 난해해 진다.
#define DELTA 0x9E3779B9 // DELTA 값 바꾸지 말것.
char tea_nilbuf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
INLINE void tea_code(const DWORD sz, const DWORD sy, const DWORD *key, DWORD *dest)
{
DWORD y = sy, z = sz, sum = 0;
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 1
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 2
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 3
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 4
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 5
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 6
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 7
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 8
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 9
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 10
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 11
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 12
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 13
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 14
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 15
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 16
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 17
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 18
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 19
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 20
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 21
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 22
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 23
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 24
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 25
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 26
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 27
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 28
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 29
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 30
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 31
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); // 32
sum += DELTA;
z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
*(dest++) = y;
*dest = z;
}
INLINE void tea_decode(const DWORD sz, const DWORD sy, const DWORD *key, DWORD *dest)
{
DWORD y = sy, z = sz, sum = DELTA * TEA_ROUND;
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 1
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 2
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 3
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 4
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 5
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 6
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 7
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 8
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 9
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 10
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 11
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 12
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 13
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 14
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 15
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 16
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 17
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 18
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 19
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 20
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 21
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 22
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 23
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 24
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 25
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 26
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 27
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 28
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 29
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 30
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 31
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); // 32
sum -= DELTA;
y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
*(dest++) = y;
*dest = z;
}
int TEA_Encrypt(DWORD *dest, const DWORD *src, const DWORD * key, int size)
{
int i;
int resize;
if (size % 8 != 0)
{
resize = size + 8 - (size % 8);
memset((char *) src + size, 0, resize - size);
}
else
resize = size;
for (i = 0; i < resize >> 3; i++, dest += 2, src += 2)
tea_code(*(src + 1), *src, key, dest);
return (resize);
}
int TEA_Decrypt(DWORD *dest, const DWORD *src, const DWORD * key, int size)
{
int i;
int resize;
if (size % 8 != 0)
resize = size + 8 - (size % 8);
else
resize = size;
for (i = 0; i < resize >> 3; i++, dest += 2, src += 2)
tea_decode(*(src + 1), *src, key, dest);
return (resize);
}

8682
src/libthecore/tea.s Normal file

File diff suppressed because it is too large Load Diff

62
src/libthecore/typedef.h Normal file
View File

@@ -0,0 +1,62 @@
#ifndef __INC_LIBTHECORE_TYPEDEF_H__
#define __INC_LIBTHECORE_TYPEDEF_H__
typedef unsigned long int QWORD;
typedef unsigned char UBYTE;
typedef signed char sbyte;
typedef unsigned short sh_int;
#ifndef __WIN32__
#ifndef __cplusplus
typedef unsigned char bool;
#endif
typedef unsigned int DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef long LONG;
typedef unsigned long ULONG;
typedef int INT;
typedef unsigned int UINT;
typedef int socket_t;
#else
struct timezone
{
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
typedef SOCKET socket_t;
#if !defined(_W64)
#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
#define _W64 __w64
#else
#define _W64
#endif
#endif
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef _W64 int ssize_t;
#endif
// Fixed-size integer types
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#endif
typedef unsigned int uint;
#endif
#endif // __INC_LIBTHECORE_TYPEDEF_H__

475
src/libthecore/utils.cpp Normal file
View File

@@ -0,0 +1,475 @@
/*
* Filename: utils.c
* Description: 각종 유틸리티
*
* Author: 비엽 aka. Cronan
*/
#define __LIBTHECORE__
#include "stdafx.h"
static struct timeval null_time = { 0, 0 };
#define ishprint(x) ((((x) & 0xE0) > 0x90) || isprint(x))
void printdata(const unsigned char *data, int bytes)
{
int i, j, k;
const unsigned char *p;
fprintf(stderr, "------------------------------------------------------------------\n");
j = bytes;
while (1)
{
k = j >= 16 ? 16 : j;
p = data;
for (i = 0; i < 16; i++)
{
if (i >= k)
fprintf(stderr, " ");
else
fprintf(stderr, "%02x ", *p);
p++;
}
fprintf(stderr, "| ");
p = data;
for (i = 0; i < k; i++)
{
if (i >= k)
fprintf(stderr, " ");
else
{
fprintf(stderr, "%c", ishprint(*p) && ishprint(*(p+1)) ? *p : '.');
}
p++;
}
fprintf(stderr, "\n");
j -= 16;
data += 16;
if (j <= 0)
break;
}
fprintf(stderr, "------------------------------------------------------------------\n");
}
struct timeval * timediff(const struct timeval *a, const struct timeval *b)
{
static struct timeval rslt;
if (a->tv_sec < b->tv_sec)
return &null_time;
else if (a->tv_sec == b->tv_sec)
{
if (a->tv_usec < b->tv_usec)
return &null_time;
else
{
rslt.tv_sec = 0;
rslt.tv_usec = a->tv_usec - b->tv_usec;
return &rslt;
}
}
else
{ /* a->tv_sec > b->tv_sec */
rslt.tv_sec = a->tv_sec - b->tv_sec;
if (a->tv_usec < b->tv_usec)
{
rslt.tv_usec = a->tv_usec + 1000000 - b->tv_usec;
rslt.tv_sec--;
} else
rslt.tv_usec = a->tv_usec - b->tv_usec;
return &rslt;
}
}
struct timeval * timeadd(struct timeval *a, struct timeval *b)
{
static struct timeval rslt;
rslt.tv_sec = a->tv_sec + b->tv_sec;
rslt.tv_usec = a->tv_usec + b->tv_usec;
while (rslt.tv_usec >= 1000000)
{
rslt.tv_usec -= 1000000;
rslt.tv_sec++;
}
return &rslt;
}
char *time_str(time_t ct)
{
static char * time_s;
time_s = asctime(localtime(&ct));
time_s[strlen(time_s) - 6] = '\0';
time_s += 4;
return (time_s);
}
void trim_and_lower(const char * src, char * dest, size_t dest_size)
{
const char * tmp = src;
size_t len = 0;
if (!dest || dest_size == 0)
return;
if (!src)
{
*dest = '\0';
return;
}
// 앞에 빈칸 건너 뛰기
while (*tmp)
{
if (!isnhspace(*tmp))
break;
tmp++;
}
// \0 확보
--dest_size;
while (*tmp && len < dest_size)
{
*(dest++) = LOWER(*tmp); // LOWER는 매크로라 ++ 쓰면 안됨
++tmp;
++len;
}
*dest = '\0';
if (len > 0)
{
// 뒤에 빈칸 지우기
--dest;
while (*dest && isnhspace(*dest) && len--)
*(dest--) = '\0';
}
}
void lower_string(const char *src, char *dest, size_t dest_size)
{
const char* tmp = src;
size_t len = 0;
if (!dest || dest_size == 0)
return;
if (!src)
{
*dest = '\0';
return;
}
// \0 확보
--dest_size;
while (*tmp && len < dest_size)
{
*(dest++) = LOWER(*tmp); // LOWER는 매크로라 ++ 쓰면 안됨
++tmp;
++len;
}
*dest = '\0';
}
char *str_dup(const char *source)
{
char *new_line;
CREATE(new_line, char, strlen(source) + 1);
return (strcpy(new_line, source));
}
/* arg1 이 arg2 의 앞단과 같을 때 1 을 리턴한다. */
int is_abbrev(char *arg1, char *arg2)
{
if (!*arg1)
return 0;
for (; *arg1 && *arg2; arg1++, arg2++)
if (LOWER(*arg1) != LOWER(*arg2))
return 0;
if (!*arg1)
return 1;
else
return 0;
}
int filesize(FILE *fp)
{
int pos;
int size;
pos = ftell(fp);
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, pos, SEEK_SET);
return (size);
}
/* "Name : 비엽" 과 같이 "항목 : 값" 으로 이루어진 문자열에서
항목을 token 으로, 값을 value 로 복사하여 리턴한다. */
void parse_token(char *src, char *token, char *value)
{
char *tmp;
for (tmp = src; *tmp && *tmp != ':'; tmp++)
{
if (isnhspace(*tmp))
continue;
*(token++) = LOWER(*tmp);
}
*token = '\0';
for (tmp += 2; *tmp; tmp++)
{
if (*tmp == '\n' || *tmp == '\r')
continue;
*(value++) = *tmp;
}
*value = '\0';
}
struct tm * tm_calc(const struct tm * curr_tm, int days)
{
char yoon = FALSE;
static struct tm new_tm;
int monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (!curr_tm)
{
time_t time_s = time(0);
new_tm = *localtime(&time_s);
}
else
thecore_memcpy(&new_tm, curr_tm, sizeof(struct tm));
if (new_tm.tm_mon == 1)
{
if (!((new_tm.tm_year + 1900) % 4))
{
if (!((new_tm.tm_year + 1900) % 100))
{
if (!((new_tm.tm_year + 1900) % 400))
yoon = TRUE;
}
else
yoon = TRUE;
}
if (yoon)
new_tm.tm_mday += 1;
}
if (yoon)
monthdays[1] = 29;
else
monthdays[1] = 28;
new_tm.tm_mday += days;
if (new_tm.tm_mday <= 0)
{
new_tm.tm_mon--;
if (new_tm.tm_mon < 0)
{
new_tm.tm_year--;
new_tm.tm_mon = 11;
}
new_tm.tm_mday = monthdays[new_tm.tm_mon] + new_tm.tm_mday;
}
else if (new_tm.tm_mday > monthdays[new_tm.tm_mon])
{
new_tm.tm_mon++;
if (new_tm.tm_mon > 11)
{
new_tm.tm_year++;
new_tm.tm_mon = 0;
}
new_tm.tm_mday = monthdays[new_tm.tm_mon] - new_tm.tm_mday;
}
return (&new_tm);
}
int MIN(int a, int b)
{
return a < b ? a : b;
}
int MAX(int a, int b)
{
return a > b ? a : b;
}
int MINMAX(int min, int value, int max)
{
int tv;
tv = (min > value ? min : value);
return (max < tv) ? max : tv;
}
DWORD thecore_random()
{
#ifdef __WIN32__
return rand();
#else
return random();
#endif
}
int number_ex(int from, int to, const char *file, int line)
{
if (from > to)
{
int tmp = from;
sys_err("number(): first argument is bigger than second argument %d -> %d, %s %d", from, to, file, line);
from = to;
to = tmp;
}
int returnValue = 0;
if ((to - from + 1) != 0)
returnValue = ((thecore_random() % (to - from + 1)) + from);
else
sys_err("number(): devided by 0");
return returnValue;
}
float fnumber(float from, float to)
{
return (((float)thecore_random() / (float)RAND_MAX) * (to - from)) + from;
}
#ifndef __WIN32__
void thecore_sleep(struct timeval* timeout)
{
if (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, timeout) < 0)
{
if (errno != EINTR)
{
sys_err("select sleep %s", strerror(errno));
return;
}
}
}
void thecore_msleep(DWORD dwMillisecond)
{
static struct timeval tv_sleep;
tv_sleep.tv_sec = dwMillisecond / 1000;
tv_sleep.tv_usec = dwMillisecond * 1000;
thecore_sleep(&tv_sleep);
}
void core_dump_unix(const char *who, WORD line)
{
sys_err("*** Dumping Core %s:%d ***", who, line);
fflush(stdout);
fflush(stderr);
if (fork() == 0)
abort();
}
/*
uint64_t rdtsc()
{
uint64_t x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
*/
#else
void thecore_sleep(struct timeval* timeout)
{
Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
}
void thecore_msleep(DWORD dwMillisecond)
{
Sleep(dwMillisecond);
}
void gettimeofday(struct timeval* t, struct timezone* dummy)
{
DWORD millisec = GetTickCount();
t->tv_sec = (millisec / 1000);
t->tv_usec = (millisec % 1000) * 1000;
}
void core_dump_unix(const char *who, WORD line)
{
}
#endif
float get_float_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
tv.tv_sec -= 1057699978;
return ((float) tv.tv_sec + ((float) tv.tv_usec / 1000000.0f));
}
static DWORD get_boot_sec()
{
static struct timeval tv_boot = {0L, 0L};
if (tv_boot.tv_sec == 0)
gettimeofday(&tv_boot, NULL);
return tv_boot.tv_sec;
}
DWORD get_dword_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
//tv.tv_sec -= 1057699978;
tv.tv_sec -= get_boot_sec();
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}

152
src/libthecore/utils.h Normal file
View File

@@ -0,0 +1,152 @@
#ifndef __INC_LIBTHECORE_UTILS_H__
#define __INC_LIBTHECORE_UTILS_H__
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define SAFE_FREE(p) { if (p) { free( (void *) p); (p) = NULL; } }
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = NULL; } }
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } }
#define LOWER(c) (((c)>='A' && (c) <= 'Z') ? ((c)+('a'-'A')) : (c))
#define UPPER(c) (((c)>='a' && (c) <= 'z') ? ((c)+('A'-'a')) : (c))
#define str_cmp strcasecmp
#define STRNCPY(dst, src, len) do {strncpy(dst, src, len); dst[len] = '\0'; } while(0)
extern char * str_dup(const char * source); // 메모리 할당 해서 source 복사 한거 리턴
extern void printdata(const unsigned char * data, int bytes); // data를 hex랑 ascii로 출력 (패킷 분석 등에 쓰임)
extern int filesize(FILE * fp); // 파일 크기 리턴
#define core_dump() core_dump_unix(__FILE__, __LINE__)
extern void core_dump_unix(const char *who, WORD line); // 코어를 강제로 덤프
#define TOKEN(string) if (!str_cmp(token_string, string))
// src = 토큰 : 값
extern void parse_token(char * src, char * token, char * value);
extern void trim_and_lower(const char * src, char * dest, size_t dest_size);
// 문자열을 소문자로
extern void lower_string(const char * src, char * dest, size_t dest_len);
// arg1이 arg2로 시작하는가? (대소문자 구별하지 않음)
extern int is_abbrev(char *arg1, char *arg2);
// a와 b의 시간이 얼마나 차이나는지 리턴
extern struct timeval * timediff(const struct timeval *a, const struct timeval *b);
// a의 시간에 b의 시간을 더해 리턴
extern struct timeval * timeadd(struct timeval *a, struct timeval *b);
// 현재 시간 curr_tm으로 부터 days가 지난 날을 리턴
extern struct tm * tm_calc(const struct tm *curr_tm, int days);
extern int MAX(int a, int b); // 둘중에 큰 값을 리턴
extern int MIN(int a, int b); // 둘중에 작은 값을 리턴
extern int MINMAX(int min, int value, int max); // 최소 최대 값을 함께 비교해서 리턴
extern int number_ex(int from, int to, const char *file, int line); // from으로 부터 to까지의 랜덤 값 리턴
#define number(from, to) number_ex(from, to, __FILE__, __LINE__)
float fnumber(float from, float to);
extern void thecore_sleep(struct timeval * timeout); // timeout만큼 프로세스 쉬기
extern DWORD thecore_random(); // 랜덤 함수
extern float get_float_time();
extern DWORD get_dword_time();
extern char * time_str(time_t ct);
#define CREATE(result, type, number) do { \
if (!((result) = (type *) calloc ((number), sizeof(type)))) { \
sys_err("calloc failed [%d] %s", errno, strerror(errno)); \
abort(); } } while(0)
#define RECREATE(result,type,number) do { \
if (!((result) = (type *) realloc ((result), sizeof(type) * (number)))) { \
sys_err("realloc failed [%d] %s", errno, strerror(errno)); \
abort(); } } while(0)
// Next 와 Prev 가 있는 리스트에 추가
#define INSERT_TO_TW_LIST(item, head, prev, next) \
if (!(head)) \
{ \
head = item; \
(head)->prev = (head)->next = NULL; \
} \
else \
{ \
(head)->prev = item; \
(item)->next = head; \
(item)->prev = NULL; \
head = item; \
}
#define REMOVE_FROM_TW_LIST(item, head, prev, next) \
if ((item) == (head)) \
{ \
if (((head) = (item)->next)) \
(head)->prev = NULL; \
} \
else \
{ \
if ((item)->next) \
(item)->next->prev = (item)->prev; \
\
if ((item)->prev) \
(item)->prev->next = (item)->next; \
}
#define INSERT_TO_LIST(item, head, next) \
(item)->next = (head); \
(head) = (item); \
#define REMOVE_FROM_LIST(item, head, next) \
if ((item) == (head)) \
head = (item)->next; \
else \
{ \
temp = head; \
\
while (temp && (temp->next != (item))) \
temp = temp->next; \
\
if (temp) \
temp->next = (item)->next; \
} \
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \
((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24))
#endif // defined(MAKEFOURCC)
#ifdef __cplusplus
}
#endif // __cplusplus
// _countof for gcc/g++
#if !defined(_countof)
#if !defined(__cplusplus)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#else
extern "C++"
{
template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(_CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
#define _countof(_Array) sizeof(*__countof_helper(_Array))
}
#endif
#endif
#ifdef __WIN32__
extern void gettimeofday(struct timeval* t, struct timezone* dummy);
#endif
#endif // __INC_UTILS_H__

152
src/libthecore/xdirent.cpp Normal file
View File

@@ -0,0 +1,152 @@
#include "stdafx.h"
#ifdef __WIN32__
/*
Implementation of POSIX directory browsing functions and types for Win32.
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
History: Created March 1997. Updated June 2003.
Rights: See end of file.
*/
#include "xdirent.h"
#include <errno.h>
#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct DIR
{
long handle; /* -1 for failed rewind */
struct _finddata_t info;
struct dirent result; /* d_name null iff first time */
char *name; /* null-terminated char string */
};
DIR *opendir(const char *name)
{
DIR *dir = 0;
if(name && name[0])
{
size_t base_length = strlen(name);
const char *all = /* search pattern must end with suitable wildcard */
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
(dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
{
strcat(strcpy(dir->name, name), all);
if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
{
dir->result.d_name = 0;
}
else /* rollback */
{
free(dir->name);
free(dir);
dir = 0;
}
}
else /* rollback */
{
free(dir);
dir = 0;
errno = ENOMEM;
}
}
else
{
errno = EINVAL;
}
return dir;
}
int closedir(DIR *dir)
{
int result = -1;
if(dir)
{
if(dir->handle != -1)
{
result = _findclose(dir->handle);
}
free(dir->name);
free(dir);
}
if(result == -1) /* map all errors to EBADF */
{
errno = EBADF;
}
return result;
}
struct dirent *readdir(DIR *dir)
{
struct dirent *result = 0;
if(dir && dir->handle != -1)
{
if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
{
result = &dir->result;
result->d_name = dir->info.name;
}
}
else
{
errno = EBADF;
}
return result;
}
void rewinddir(DIR *dir)
{
if(dir && dir->handle != -1)
{
_findclose(dir->handle);
dir->handle = (long) _findfirst(dir->name, &dir->info);
dir->result.d_name = 0;
}
else
{
errno = EBADF;
}
}
#ifdef __cplusplus
}
#endif
/*
Copyright Kevlin Henney, 1997, 2003. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives.
This software is supplied "as is" without express or implied warranty.
But that said, if there are any problems please get in touch.
*/
#endif // #ifdef __WIN32__

50
src/libthecore/xdirent.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef DIRENT_INCLUDED
#define DIRENT_INCLUDED
/*
Declaration of POSIX directory browsing functions and types for Win32.
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
History: Created March 1997. Updated June 2003.
Rights: See end of file.
*/
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct DIR DIR;
struct dirent
{
char *d_name;
};
DIR *opendir(const char *);
int closedir(DIR *);
struct dirent *readdir(DIR *);
void rewinddir(DIR *);
/*
Copyright Kevlin Henney, 1997, 2003. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives.
This software is supplied "as is" without express or implied warranty.
But that said, if there are any problems please get in touch.
*/
#ifdef __cplusplus
}
#endif
#endif

228
src/libthecore/xgetopt.cpp Normal file
View File

@@ -0,0 +1,228 @@
// XGetopt.cpp Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// Description:
// XGetopt.cpp implements getopt(), a function to parse command lines.
//
// History
// Version 1.2 - 2003 May 17
// - Added Unicode support
//
// Version 1.1 - 2002 March 10
// - Added example to XGetopt.cpp module header
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// if you are using precompiled headers then include this line:
#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////
#ifdef __WIN32__
///////////////////////////////////////////////////////////////////////////////
// if you are not using precompiled headers then include these lines:
//#include <windows.h>
//#include <stdio.h>
//#include <tchar.h>
///////////////////////////////////////////////////////////////////////////////
#include "xgetopt.h"
///////////////////////////////////////////////////////////////////////////////
//
// X G e t o p t . c p p
//
//
// NAME
// getopt -- parse command line options
//
// SYNOPSIS
// int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
//
// extern TCHAR *optarg;
// extern int optind;
//
// DESCRIPTION
// The getopt() function parses the command line arguments. Its
// arguments argc and argv are the argument count and array as
// passed into the application on program invocation. In the case
// of Visual C++ programs, argc and argv are available via the
// variables __argc and __argv (double underscores), respectively.
// getopt returns the next option letter in argv that matches a
// letter in optstring. (Note: Unicode programs should use
// __targv instead of __argv. Also, all character and string
// literals should be enclosed in _T( ) ).
//
// optstring is a string of recognized option letters; if a letter
// is followed by a colon, the option is expected to have an argument
// that may or may not be separated from it by white space. optarg
// is set to point to the start of the option argument on return from
// getopt.
//
// Option letters may be combined, e.g., "-ab" is equivalent to
// "-a -b". Option letters are case sensitive.
//
// getopt places in the external variable optind the argv index
// of the next argument to be processed. optind is initialized
// to 0 before the first call to getopt.
//
// When all options have been processed (i.e., up to the first
// non-option argument), getopt returns EOF, optarg will point
// to the argument, and optind will be set to the argv index of
// the argument. If there are no non-option arguments, optarg
// will be set to NULL.
//
// The special option "--" may be used to delimit the end of the
// options; EOF will be returned, and "--" (and everything after it)
// will be skipped.
//
// RETURN VALUE
// For option letters contained in the string optstring, getopt
// will return the option letter. getopt returns a question mark (?)
// when it encounters an option letter not included in optstring.
// EOF is returned when processing is finished.
//
// BUGS
// 1) Long options are not supported.
// 2) The GNU double-colon extension is not supported.
// 3) The environment variable POSIXLY_CORRECT is not supported.
// 4) The + syntax is not supported.
// 5) The automatic permutation of arguments is not supported.
// 6) This implementation of getopt() returns EOF if an error is
// encountered, instead of -1 as the latest standard requires.
//
// EXAMPLE
// BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
// {
// int c;
//
// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
// {
// switch (c)
// {
// case _T('a'):
// TRACE(_T("option a\n"));
// //
// // set some flag here
// //
// break;
//
// case _T('B'):
// TRACE( _T("option B\n"));
// //
// // set some other flag here
// //
// break;
//
// case _T('n'):
// TRACE(_T("option n: value=%d\n"), atoi(optarg));
// //
// // do something with value here
// //
// break;
//
// case _T('?'):
// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
// return FALSE;
// break;
//
// default:
// TRACE(_T("WARNING: no handler for option %c\n"), c);
// return FALSE;
// break;
// }
// }
// //
// // check for non-option args here
// //
// return TRUE;
// }
//
///////////////////////////////////////////////////////////////////////////////
TCHAR *optarg; // global argument pointer
int optind = 0; // global argv index
int optreset = 0;
int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
{
static TCHAR *next = NULL;
if (optreset != 0) {
optind = 0;
}
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == _T('\0'))
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\0'))
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (_tcscmp(argv[optind], _T("--")) == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
TCHAR c = *next++;
TCHAR *cp = _tcschr(optstring, c);
if (cp == NULL || c == _T(':'))
return _T('?');
cp++;
if (*cp == _T(':'))
{
if (*next != _T('\0'))
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return _T('?');
}
}
return c;
}
#endif // #ifdef __WIN32__

23
src/libthecore/xgetopt.h Normal file
View File

@@ -0,0 +1,23 @@
// XGetopt.h Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef XGETOPT_H
#define XGETOPT_H
extern int optind, opterr, optreset;
extern TCHAR *optarg;
int getopt(int argc, TCHAR *argv[], TCHAR *optstring);
#endif //XGETOPT_H

345
src/libthecore/xmd5.cpp Normal file
View File

@@ -0,0 +1,345 @@
#include "stdafx.h"
#ifndef __FreeBSD__
/*
* luau (Lib Update/Auto-Update): Simple Update Library
* Copyright (C) 2003 David Eklund
*
* - This library is free software; you can redistribute it and/or -
* - modify it under the terms of the GNU Lesser General Public -
* - License as published by the Free Software Foundation; either -
* - version 2.1 of the License, or (at your option) any later version. -
* - -
* - This library is distributed in the hope that it will be useful, -
* - but WITHOUT ANY WARRANTY; without even the implied warranty of -
* - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -
* - Lesser General Public License for more details. -
* - -
* - You should have received a copy of the GNU Lesser General Public -
* - License along with this library; if not, write to the Free Software -
* - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -
*/
/*
* md5.h and md5.c are based off of md5hl.c, md5c.c, and md5.h from libmd, which in turn is
* based off the FreeBSD libmd library. Their respective copyright notices follow:
*/
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*/
/* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id: md5.c,v 1.1.1.1 2004/04/02 05:11:38 deklund2 Exp $
*
*/
#include "xmd5.h"
#if __BYTE_ORDER == 1234
#define byteReverse(buf, len) /* Nothing */
#else
void byteReverse(unsigned char *buf, unsigned longs);
/*
* Note: this code is harmless on little-endian machines.
*/
void byteReverse(unsigned char *buf, unsigned longs)
{
uint32_t t;
do {
t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(uint32_t *) buf = t;
buf += 4;
} while (--longs);
}
#endif /* ! __BYTE_ORDER == 1234 */
char *
lutil_md5_file (const char *filename, char *buf)
{
unsigned char buffer[BUFSIZ];
MD5_CTX ctx;
int f,i,j;
MD5Init(&ctx);
#ifndef __WIN32__
f = open(filename,O_RDONLY);
#else
f = _open(filename, _O_RDONLY);
#endif
if (f < 0) return 0;
while ((i = read(f,buffer,sizeof buffer)) > 0) {
MD5Update(&ctx,buffer,i);
}
j = errno;
close(f);
errno = j;
if (i < 0) return 0;
return MD5End(&ctx, buf);
}
char *
lutil_md5_data (const unsigned char *data, unsigned int len, char *buf)
{
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx,data,len);
return MD5End(&ctx, buf);
}
/* Non-Interface Methods */
/* from md5hl.c */
char *
MD5End(MD5_CTX *ctx, char *buf)
{
int i;
unsigned char digest[MD5_HASHBYTES];
static const char hex[]="0123456789abcdef";
if (!buf)
buf = (char*)malloc(33);
if (!buf)
return 0;
MD5Final(digest,ctx);
for (i=0;i<MD5_HASHBYTES;i++) {
buf[i+i] = hex[digest[i] >> 4];
buf[i+i+1] = hex[digest[i] & 0x0f];
}
buf[i+i] = '\0';
return buf;
}
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void MD5Init(MD5_CTX *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len)
{
uint32_t t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void MD5Final(unsigned char digest[16], MD5_CTX *ctx)
{
unsigned count;
unsigned char *p;
/* Compute number of bytes mod 64 */
count = (ctx->bits[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = ctx->in + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
((uint32_t *) ctx->in)[14] = ctx->bits[0];
((uint32_t *) ctx->in)[15] = ctx->bits[1];
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
}
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void MD5Transform(uint32_t buf[4], uint32_t const in[16])
{
uint32_t a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif // #ifndef __FreeBSD__

82
src/libthecore/xmd5.h Normal file
View File

@@ -0,0 +1,82 @@
#ifndef __FreeBSD__
/*
* luau (Lib Update/Auto-Update): Simple Update Library
* Copyright (C) 2003 David Eklund
*
* - This library is free software; you can redistribute it and/or -
* - modify it under the terms of the GNU Lesser General Public -
* - License as published by the Free Software Foundation; either -
* - version 2.1 of the License, or (at your option) any later version. -
* - -
* - This library is distributed in the hope that it will be useful, -
* - but WITHOUT ANY WARRANTY; without even the implied warranty of -
* - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -
* - Lesser General Public License for more details. -
* - -
* - You should have received a copy of the GNU Lesser General Public -
* - License along with this library; if not, write to the Free Software -
* - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -
*/
/*
* md5.h and md5.c are based off of md5hl.c, md5c.c, and md5.h from libmd, which in turn are
* based off the FreeBSD libmd library. Their respective copyright notices follow:
*/
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*/
/* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id: md5.h,v 1.1.1.1 2004/04/02 05:11:38 deklund2 Exp $
*
*/
#ifndef MD5_H
#define MD5_H
#include <sys/types.h>
#define MD5_HASHBYTES 16
typedef struct MD5Context {
uint32_t buf[4];
uint32_t bits[2];
unsigned char in[64];
} MD5_CTX;
#ifdef __cplusplus
extern "C" {
#endif
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char const *buf, unsigned len);
void MD5Final(unsigned char digest[MD5_HASHBYTES], MD5_CTX *context);
void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
char* MD5End(MD5_CTX *, char *);
char* lutil_md5_file(const char *filename, char *buf);
char* lutil_md5_data(const unsigned char *data, unsigned int len, char *buf);
#ifdef __cplusplus
}
#endif
#endif /* MD5_H */
#endif // #ifndef __FreeBSD__