diff --git a/.gitignore b/.gitignore index 796b96d..189b414 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /build +/CMakeLists.txt.user diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d30acd..1f485e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,99 +1,55 @@ cmake_minimum_required(VERSION 3.0) -project(xmrig C) - -option(WITH_LIBCPUID "Use Libcpuid" ON) -option(WITH_AEON "CryptoNight-Lite support" ON) +project(xmrig) set(HEADERS - compat.h - algo/cryptonight/cryptonight.h - algo/cryptonight/cryptonight_aesni.h - algo/cryptonight/cryptonight_softaes.h - elist.h - xmrig.h - version.h - options.h - cpu.h - persistent_memory.h - stratum.h - stats.h - util.h - donate.h - ) - -set(HEADERS_CRYPTO - crypto/c_groestl.h - crypto/c_blake256.h - crypto/c_jh.h - crypto/c_skein.h - ) - -set(HEADERS_COMPAT - compat/winansi.h - ) - -set(HEADERS_UTILS - utils/applog.h - utils/threads.h - utils/summary.h + src/App.h + src/interfaces/IClientListener.h + src/net/Client.h + src/net/Network.h + src/net/Url.h + src/Options.h + src/Console.h + src/version.h ) set(SOURCES - xmrig.c - algo/cryptonight/cryptonight.c - algo/cryptonight/cryptonight_av1_aesni.c - algo/cryptonight/cryptonight_av2_aesni_double.c - algo/cryptonight/cryptonight_av3_softaes.c - algo/cryptonight/cryptonight_av4_softaes_double.c - util.c - options.c - stratum.c - stats.c - memory.c - ) - -set(SOURCES_CRYPTO - crypto/c_keccak.c - crypto/c_groestl.c - crypto/c_blake256.c - crypto/c_jh.c - crypto/c_skein.c - crypto/soft_aes.c - ) - -set(SOURCES_UTILS - utils/applog.c - utils/summary.c + src/App.cpp + src/net/Client.cpp + src/net/Network.cpp + src/net/Url.cpp + src/Options.cpp + src/Console.cpp + src/xmrig.cpp ) if (WIN32) - set(SOURCES_OS win/cpu_win.c win/memory_win.c win/xmrig_win.c win/app.rc compat/winansi.c) - set(EXTRA_LIBS ws2_32) - add_definitions(/D_WIN32_WINNT=0x600) -elseif (APPLE) - set(SOURCES_OS mac/cpu_mac.c mac/memory_mac.c mac/xmrig_mac.c) + set(SOURCES_OS + res/app.rc + src/3rdparty/winansi.cpp + src/3rdparty/winansi.h + src/net/Network_win.cpp + ) + + set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) else() set(SOURCES_OS unix/cpu_unix.c unix/memory_unix.c unix/xmrig_unix.c) set(EXTRA_LIBS pthread) endif() -include_directories(.) -add_definitions(/DUSE_NATIVE_THREADS) add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) +add_definitions(/DAPP_DEBUG) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") + +find_package(UV REQUIRED) if ("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wno-pointer-to-int-cast") - -if (CMAKE_C_COMPILER_ID MATCHES "Clang") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") -else() - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -endif() - +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-use -fprofile-correction") @@ -102,45 +58,12 @@ if (WIN32) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") endif() -include_directories(compat/jansson) -add_subdirectory(compat/jansson) +include_directories(src) +include_directories(src/3rdparty) +include_directories(src/3rdparty/jansson) +include_directories(${UV_INCLUDE_DIR}) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") - -find_package(CURL REQUIRED) -include_directories(${CURL_INCLUDE_DIRS}) -add_definitions(/DCURL_STATICLIB) -link_directories(${CURL_LIBRARIES}) - -if (WITH_LIBCPUID) - add_subdirectory(compat/libcpuid) - - include_directories(compat/libcpuid) - set(CPUID_LIB cpuid) - set(SOURCES_CPUID cpu.c) -else() - add_definitions(/DXMRIG_NO_LIBCPUID) - set(SOURCES_CPUID cpu_stub.c) -endif() - -if (WITH_AEON) - set(SOURCES_AEON - algo/cryptonight-lite/cryptonight_lite_av1_aesni.c - algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c - algo/cryptonight-lite/cryptonight_lite_av3_softaes.c - algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c - algo/cryptonight-lite/cryptonight_lite_aesni.h - algo/cryptonight-lite/cryptonight_lite_softaes.h - ) -else() - add_definitions(/DXMRIG_NO_AEON) -endif() - -if (CMAKE_SIZEOF_VOID_P EQUAL 8) - add_executable(xmrig ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS} ${SOURCES_CPUID} ${SOURCES_AEON}) - target_link_libraries(xmrig jansson curl ${CPUID_LIB} ${EXTRA_LIBS}) -else() - add_executable(xmrig32 ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS} ${SOURCES_CPUID} ${SOURCES_AEON}) - target_link_libraries(xmrig32 jansson curl ${CPUID_LIB} ${EXTRA_LIBS}) -endif() +add_subdirectory(src/3rdparty/jansson) +add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS}) +target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS}) diff --git a/cmake/FindUV.cmake b/cmake/FindUV.cmake new file mode 100644 index 0000000..c8a95e7 --- /dev/null +++ b/cmake/FindUV.cmake @@ -0,0 +1,8 @@ +find_path(UV_INCLUDE_DIR NAMES uv.h) +find_library(UV_LIBRARY NAMES libuv) + +set(UV_LIBRARIES ${UV_LIBRARY}) +set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UV DEFAULT_MSG UV_LIBRARY UV_INCLUDE_DIR) diff --git a/win/app.ico b/res/app.ico similarity index 100% rename from win/app.ico rename to res/app.ico diff --git a/win/app.rc b/res/app.rc similarity index 96% rename from win/app.rc rename to res/app.rc index cb47aa3..800ce2d 100644 --- a/win/app.rc +++ b/res/app.rc @@ -1,5 +1,5 @@ #include -#include "../version.h" +#include "../src/version.h" IDI_ICON1 ICON DISCARDABLE "app.ico" diff --git a/compat/jansson/CMakeLists.txt b/src/3rdparty/jansson/CMakeLists.txt similarity index 91% rename from compat/jansson/CMakeLists.txt rename to src/3rdparty/jansson/CMakeLists.txt index 9a73da2..7bd74c6 100644 --- a/compat/jansson/CMakeLists.txt +++ b/src/3rdparty/jansson/CMakeLists.txt @@ -6,6 +6,8 @@ add_definitions(-DHAVE_CONFIG_H) # Add the lib sources. file(GLOB JANSSON_SRC *.c) +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") + set(JANSSON_HDR_PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/hashtable.h ${CMAKE_CURRENT_SOURCE_DIR}/jansson_private.h diff --git a/compat/jansson/LICENSE b/src/3rdparty/jansson/LICENSE similarity index 100% rename from compat/jansson/LICENSE rename to src/3rdparty/jansson/LICENSE diff --git a/compat/jansson/dump.c b/src/3rdparty/jansson/dump.c similarity index 89% rename from compat/jansson/dump.c rename to src/3rdparty/jansson/dump.c index 6b1aabd..a23fabb 100644 --- a/compat/jansson/dump.c +++ b/src/3rdparty/jansson/dump.c @@ -9,13 +9,17 @@ #define _GNU_SOURCE #endif +#include "jansson_private.h" + #include #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif #include "jansson.h" -#include "jansson_private.h" #include "strbuffer.h" #include "utf.h" @@ -25,11 +29,28 @@ #define FLAGS_TO_INDENT(f) ((f) & 0x1F) #define FLAGS_TO_PRECISION(f) (((f) >> 11) & 0x1F) +struct buffer { + const size_t size; + size_t used; + char *data; +}; + static int dump_to_strbuffer(const char *buffer, size_t size, void *data) { return strbuffer_append_bytes((strbuffer_t *)data, buffer, size); } +static int dump_to_buffer(const char *buffer, size_t size, void *data) +{ + struct buffer *buf = (struct buffer *)data; + + if(buf->used + size <= buf->size) + memcpy(&buf->data[buf->used], buffer, size); + + buf->used += size; + return 0; +} + static int dump_to_file(const char *buffer, size_t size, void *data) { FILE *dest = (FILE *)data; @@ -38,6 +59,16 @@ static int dump_to_file(const char *buffer, size_t size, void *data) return 0; } +static int dump_to_fd(const char *buffer, size_t size, void *data) +{ + int *dest = (int *)data; +#ifdef HAVE_UNISTD_H + if(write(*dest, buffer, size) == (ssize_t)size) + return 0; +#endif + return -1; +} + /* 32 spaces (the maximum indentation size) */ static const char whitespace[] = " "; @@ -168,6 +199,10 @@ static int compare_keys(const void *key1, const void *key2) static int do_dump(const json_t *json, size_t flags, int depth, json_dump_callback_t dump, void *data) { + int embed = flags & JSON_EMBED; + + flags &= ~JSON_EMBED; + if(!json) return -1; @@ -227,11 +262,11 @@ static int do_dump(const json_t *json, size_t flags, int depth, n = json_array_size(json); - if(dump("[", 1, data)) + if(!embed && dump("[", 1, data)) goto array_error; if(n == 0) { array->visited = 0; - return dump("]", 1, data); + return embed ? 0 : dump("]", 1, data); } if(dump_indent(flags, depth + 1, 0, dump, data)) goto array_error; @@ -255,7 +290,7 @@ static int do_dump(const json_t *json, size_t flags, int depth, } array->visited = 0; - return dump("]", 1, data); + return embed ? 0 : dump("]", 1, data); array_error: array->visited = 0; @@ -286,11 +321,11 @@ static int do_dump(const json_t *json, size_t flags, int depth, iter = json_object_iter((json_t *)json); - if(dump("{", 1, data)) + if(!embed && dump("{", 1, data)) goto object_error; if(!iter) { object->visited = 0; - return dump("}", 1, data); + return embed ? 0 : dump("}", 1, data); } if(dump_indent(flags, depth + 1, 0, dump, data)) goto object_error; @@ -386,7 +421,7 @@ static int do_dump(const json_t *json, size_t flags, int depth, } object->visited = 0; - return dump("}", 1, data); + return embed ? 0 : dump("}", 1, data); object_error: object->visited = 0; @@ -416,11 +451,26 @@ char *json_dumps(const json_t *json, size_t flags) return result; } +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags) +{ + struct buffer buf = { size, 0, buffer }; + + if(json_dump_callback(json, dump_to_buffer, (void *)&buf, flags)) + return 0; + + return buf.used; +} + int json_dumpf(const json_t *json, FILE *output, size_t flags) { return json_dump_callback(json, dump_to_file, (void *)output, flags); } +int json_dumpfd(const json_t *json, int output, size_t flags) +{ + return json_dump_callback(json, dump_to_fd, (void *)&output, flags); +} + int json_dump_file(const json_t *json, const char *path, size_t flags) { int result; diff --git a/compat/jansson/error.c b/src/3rdparty/jansson/error.c similarity index 100% rename from compat/jansson/error.c rename to src/3rdparty/jansson/error.c diff --git a/compat/jansson/hashtable.c b/src/3rdparty/jansson/hashtable.c similarity index 100% rename from compat/jansson/hashtable.c rename to src/3rdparty/jansson/hashtable.c diff --git a/compat/jansson/hashtable.h b/src/3rdparty/jansson/hashtable.h similarity index 100% rename from compat/jansson/hashtable.h rename to src/3rdparty/jansson/hashtable.h diff --git a/compat/jansson/hashtable_seed.c b/src/3rdparty/jansson/hashtable_seed.c similarity index 98% rename from compat/jansson/hashtable_seed.c rename to src/3rdparty/jansson/hashtable_seed.c index 751e0e3..8aed540 100644 --- a/compat/jansson/hashtable_seed.c +++ b/src/3rdparty/jansson/hashtable_seed.c @@ -168,12 +168,12 @@ static uint32_t generate_seed() { int done = 0; #if !defined(_WIN32) && defined(USE_URANDOM) - if (!done && seed_from_urandom(&seed) == 0) + if (seed_from_urandom(&seed) == 0) done = 1; #endif #if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI) - if (!done && seed_from_windows_cryptoapi(&seed) == 0) + if (seed_from_windows_cryptoapi(&seed) == 0) done = 1; #endif diff --git a/compat/jansson/jansson.h b/src/3rdparty/jansson/jansson.h similarity index 96% rename from compat/jansson/jansson.h rename to src/3rdparty/jansson/jansson.h index 591f2a9..a5927bd 100644 --- a/compat/jansson/jansson.h +++ b/src/3rdparty/jansson/jansson.h @@ -21,11 +21,11 @@ extern "C" { /* version */ #define JANSSON_MAJOR_VERSION 2 -#define JANSSON_MINOR_VERSION 9 +#define JANSSON_MINOR_VERSION 10 #define JANSSON_MICRO_VERSION 0 /* Micro version is omitted if it's 0 */ -#define JANSSON_VERSION "2.9" +#define JANSSON_VERSION "2.10" /* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ @@ -273,6 +273,7 @@ typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data); json_t *json_loads(const char *input, size_t flags, json_error_t *error); json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error); json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); +json_t *json_loadfd(int input, size_t flags, json_error_t *error); json_t *json_load_file(const char *path, size_t flags, json_error_t *error); json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error); @@ -288,11 +289,14 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla #define JSON_ENCODE_ANY 0x200 #define JSON_ESCAPE_SLASH 0x400 #define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) +#define JSON_EMBED 0x10000 typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data); char *json_dumps(const json_t *json, size_t flags); +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); int json_dumpf(const json_t *json, FILE *output, size_t flags); +int json_dumpfd(const json_t *json, int output, size_t flags); int json_dump_file(const json_t *json, const char *path, size_t flags); int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags); diff --git a/compat/jansson/jansson_config.h b/src/3rdparty/jansson/jansson_config.h similarity index 100% rename from compat/jansson/jansson_config.h rename to src/3rdparty/jansson/jansson_config.h diff --git a/compat/jansson/jansson_private.h b/src/3rdparty/jansson/jansson_private.h similarity index 98% rename from compat/jansson/jansson_private.h rename to src/3rdparty/jansson/jansson_private.h index 4a4927b..5ed9615 100644 --- a/compat/jansson/jansson_private.h +++ b/src/3rdparty/jansson/jansson_private.h @@ -8,6 +8,7 @@ #ifndef JANSSON_PRIVATE_H #define JANSSON_PRIVATE_H +#include "jansson_private_config.h" #include #include "jansson.h" #include "hashtable.h" diff --git a/compat/jansson/jansson_private_config.h b/src/3rdparty/jansson/jansson_private_config.h similarity index 100% rename from compat/jansson/jansson_private_config.h rename to src/3rdparty/jansson/jansson_private_config.h diff --git a/compat/jansson/load.c b/src/3rdparty/jansson/load.c similarity index 96% rename from compat/jansson/load.c rename to src/3rdparty/jansson/load.c index 7a8f96e..c212489 100644 --- a/compat/jansson/load.c +++ b/src/3rdparty/jansson/load.c @@ -9,15 +9,19 @@ #define _GNU_SOURCE #endif +#include "jansson_private.h" + #include #include #include #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif #include "jansson.h" -#include "jansson_private.h" #include "strbuffer.h" #include "utf.h" @@ -340,7 +344,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) /* control character */ lex_unget_unsave(lex, c); if(c == '\n') - error_set(error, lex, "unexpected newline", c); + error_set(error, lex, "unexpected newline"); else error_set(error, lex, "control character 0x%x", c); goto out; @@ -914,7 +918,7 @@ static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) typedef struct { const char *data; - int pos; + size_t pos; } string_data_t; static int string_get(void *data) @@ -1028,6 +1032,45 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) return result; } +static int fd_get_func(int *fd) +{ + uint8_t c; +#ifdef HAVE_UNISTD_H + if (read(*fd, &c, 1) == 1) + return c; +#endif + return EOF; +} + +json_t *json_loadfd(int input, size_t flags, json_error_t *error) +{ + lex_t lex; + const char *source; + json_t *result; + +#ifdef HAVE_UNISTD_H + if(input == STDIN_FILENO) + source = ""; + else +#endif + source = ""; + + jsonp_error_init(error, source); + + if (input < 0) { + error_set(error, NULL, "wrong arguments"); + return NULL; + } + + if(lex_init(&lex, (get_func)fd_get_func, flags, &input)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { json_t *result; diff --git a/compat/jansson/lookup3.h b/src/3rdparty/jansson/lookup3.h similarity index 100% rename from compat/jansson/lookup3.h rename to src/3rdparty/jansson/lookup3.h diff --git a/compat/jansson/memory.c b/src/3rdparty/jansson/memory.c similarity index 100% rename from compat/jansson/memory.c rename to src/3rdparty/jansson/memory.c diff --git a/compat/jansson/pack_unpack.c b/src/3rdparty/jansson/pack_unpack.c similarity index 100% rename from compat/jansson/pack_unpack.c rename to src/3rdparty/jansson/pack_unpack.c diff --git a/compat/jansson/strbuffer.c b/src/3rdparty/jansson/strbuffer.c similarity index 100% rename from compat/jansson/strbuffer.c rename to src/3rdparty/jansson/strbuffer.c diff --git a/compat/jansson/strbuffer.h b/src/3rdparty/jansson/strbuffer.h similarity index 100% rename from compat/jansson/strbuffer.h rename to src/3rdparty/jansson/strbuffer.h diff --git a/compat/jansson/strconv.c b/src/3rdparty/jansson/strconv.c similarity index 100% rename from compat/jansson/strconv.c rename to src/3rdparty/jansson/strconv.c diff --git a/compat/jansson/utf.c b/src/3rdparty/jansson/utf.c similarity index 100% rename from compat/jansson/utf.c rename to src/3rdparty/jansson/utf.c diff --git a/compat/jansson/utf.h b/src/3rdparty/jansson/utf.h similarity index 100% rename from compat/jansson/utf.h rename to src/3rdparty/jansson/utf.h diff --git a/compat/jansson/value.c b/src/3rdparty/jansson/value.c similarity index 100% rename from compat/jansson/value.c rename to src/3rdparty/jansson/value.c diff --git a/compat/winansi.c b/src/3rdparty/winansi.cpp similarity index 98% rename from compat/winansi.c rename to src/3rdparty/winansi.cpp index 41cecd6..c6fbbc2 100644 --- a/compat/winansi.c +++ b/src/3rdparty/winansi.cpp @@ -11,7 +11,7 @@ #include #include -#include "compat/winansi.h" +#include "winansi.h" /* * Copyright 2008 Peter Harris */ @@ -344,8 +344,8 @@ int winansi_vfprintf(FILE *stream, const char *format, va_list list) #endif va_end(cp); - if (len > sizeof(small_buf) - 1) { - buf = malloc(len + 1); + if ((unsigned) len > sizeof(small_buf) - 1) { + buf = (char*)malloc(len + 1); if (!buf) goto abort; @@ -389,4 +389,4 @@ int winansi_printf(const char *format, ...) va_end(list); return rv; -} \ No newline at end of file +} diff --git a/compat/winansi.h b/src/3rdparty/winansi.h similarity index 92% rename from compat/winansi.h rename to src/3rdparty/winansi.h index 70c1373..47914c3 100644 --- a/compat/winansi.h +++ b/src/3rdparty/winansi.h @@ -1,12 +1,11 @@ /* * ANSI emulation wrappers */ -#ifdef WIN32 + #include #include #include -#define isatty(fd) _isatty(fd) #define fileno(fd) _fileno(fd) #ifdef __cplusplus @@ -28,5 +27,3 @@ extern "C" { #define printf winansi_printf #define fprintf winansi_fprintf #define vfprintf winansi_vfprintf - -#endif \ No newline at end of file diff --git a/src/App.cpp b/src/App.cpp new file mode 100644 index 0000000..ce9d2b2 --- /dev/null +++ b/src/App.cpp @@ -0,0 +1,84 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include + + +#include "App.h" +#include "Console.h" +#include "net/Client.h" +#include "net/Network.h" +#include "Options.h" +#include "version.h" + + +Client *client; +uv_timer_t timer_req; + + +void timer_cb(uv_timer_t* handle) { + LOG_DEBUG("TIMER"); + + client->disconnect(); +} + + +App::App(int argc, char **argv) +{ + Console::init(); + m_options = Options::parse(argc, argv); + + m_network = new Network(m_options); +} + + +App::~App() +{ + LOG_DEBUG("~APP"); + + free(m_network); + free(m_options); +} + + +App::exec() +{ + if (!m_options->isReady()) { + return 0; + } + + m_network->connect(); + +// uv_timer_init(uv_default_loop(), &timer_req); +// uv_timer_start(&timer_req, timer_cb, 5000, 5000); + + +// client = new Client(); +// client->connect("192.168.2.34", 3333); + + const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + uv_loop_close(uv_default_loop()); + + return r; +} diff --git a/utils/threads.h b/src/App.h similarity index 62% rename from utils/threads.h rename to src/App.h index a2ef09f..a6aef6f 100644 --- a/utils/threads.h +++ b/src/App.h @@ -21,21 +21,26 @@ * along with this program. If not, see . */ -#ifndef __THREADS_H__ -#define __THREADS_H__ +#ifndef __APP_H__ +#define __APP_H__ -#if defined(WIN32) && defined(USE_NATIVE_THREADS) -# include -# define MUTEX CRITICAL_SECTION -# define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex) -# define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex) -# define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex) -#else -# include -# define MUTEX pthread_mutex_t -# define MUTEX_INIT(mutex) pthread_mutex_init(&mutex, NULL) -# define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex) -# define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex) -#endif -#endif /* __THREADS_H__ */ +class Options; +class Network; + + +class App +{ +public: + App(int argc, char **argv); + ~App(); + + int exec(); + +private: + Options *m_options; + Network *m_network; +}; + + +#endif /* __APP_H__ */ diff --git a/src/Console.cpp b/src/Console.cpp new file mode 100644 index 0000000..f57a714 --- /dev/null +++ b/src/Console.cpp @@ -0,0 +1,139 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include + +#ifdef WIN32 +# include +# include "3rdparty/winansi.h" +#endif + +#include "Console.h" + + +Console *Console::m_self = nullptr; + + +void Console::init() +{ + if (!m_self) { + m_self = new Console(); + } +} + + +void Console::message(Console::Level level, const char* fmt, ...) +{ + time_t now = time(nullptr); + tm stime; + +# ifdef _WIN32 + localtime_s(&stime, &now); +# else + localtime_r(&now, &stime); +# endif + + va_list ap; + va_start(ap, fmt); + + const char* color = nullptr; + if (m_colors) { + switch (level) { + case ERR: + color = kCL_RED; + break; + + case WARNING: + color = kCL_YELLOW; + break; + + case NOTICE: + color = kCL_WHITE; + break; + + case DEBUG: + color = kCL_GRAY; + break; + + default: + color = ""; + break; + } + } + + const size_t len = 64 + strlen(fmt) + 2; + char *buf = static_cast(alloca(len)); + + sprintf(buf, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec, + color, + fmt, + m_colors ? kCL_N : "" + ); + + uv_mutex_lock(&m_mutex); + + vfprintf(stdout, buf, ap); + fflush(stdout); + + uv_mutex_unlock(&m_mutex); + + va_end(ap); +} + + +void Console::text(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + const int len = 64 + strlen(fmt) + 2; + char *buf = static_cast(alloca(len)); + + sprintf(buf, "%s%s\n", + fmt, + m_colors ? kCL_N : "" + ); + + uv_mutex_lock(&m_mutex); + + vfprintf(stdout, buf, ap); + fflush(stdout); + + uv_mutex_unlock(&m_mutex); + + va_end(ap); +} + + +Console::Console() : + m_colors(true) +{ + uv_mutex_init(&m_mutex); +} diff --git a/src/Console.h b/src/Console.h new file mode 100644 index 0000000..a02e376 --- /dev/null +++ b/src/Console.h @@ -0,0 +1,81 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#ifndef __CONSOLE_H__ +#define __CONSOLE_H__ + + +#include + + +class Console +{ +public: + enum Level { + ERR, + WARNING, + NOTICE, + INFO, + DEBUG + }; + + constexpr static const char* kCL_N = "\x1B[0m"; + constexpr static const char* kCL_RED = "\x1B[31m"; + constexpr static const char* kCL_YELLOW = "\x1B[33m"; + constexpr static const char* kCL_WHITE = "\x1B[01;37m"; + +# ifdef WIN32 + constexpr static const char* kCL_GRAY = "\x1B[01;30m"; +# else + constexpr static const char* kCL_GRAY = "\x1B[90m"; +# endif + + static inline Console* i() { return m_self; } + static void init(); + + void message(Level level, const char* fmt, ...); + void text(const char* fmt, ...); + +private: + Console(); + + static Console *m_self; + bool m_colors; + uv_mutex_t m_mutex; +}; + + +#define LOG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) +#define LOG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__) +#define LOG_NOTICE(x, ...) Console::i()->message(Console::NOTICE, x, ##__VA_ARGS__) +#define LOG_INFO(x, ...) Console::i()->message(Console::INFO, x, ##__VA_ARGS__) + +#ifdef APP_DEBUG +# define LOG_DEBUG(x, ...) Console::i()->message(Console::DEBUG, x, ##__VA_ARGS__) +# define LOG_DEBUG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) +#else +# define LOG_DEBUG(x, ...) +# define LOG_DEBUG_ERR(x, ...) +#endif + +#endif /* __CONSOLE_H__ */ diff --git a/src/Options.cpp b/src/Options.cpp new file mode 100644 index 0000000..5a8551c --- /dev/null +++ b/src/Options.cpp @@ -0,0 +1,433 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include +#include +#include + + +#include "Console.h" +#include "Options.h" +#include "version.h" +#include "donate.h" +#include "net/Url.h" + + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + + +Options *Options::m_self = nullptr; + + +static char const usage[] = "\ +Usage: " APP_ID " [OPTIONS]\n\ +Options:\n\ + -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ + -o, --url=URL URL of mining server\n\ + -b, --backup-url=URL URL of backup mining server\n\ + -O, --userpass=U:P username:password pair for mining server\n\ + -u, --user=USERNAME username for mining server\n\ + -p, --pass=PASSWORD password for mining server\n\ + -t, --threads=N number of miner threads\n\ + -v, --av=N algorithm variation, 0 auto select\n\ + -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ + -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ + -R, --retry-pause=N time to pause between retries (default: 5)\n\ + --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ + --no-color disable colored output\n\ + --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ + -B, --background run the miner in the background\n\ + -c, --config=FILE load a JSON-format configuration file\n\ + --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ + --safe safe adjust threads and av settings for current CPU\n\ + --nicehash enable nicehash support\n\ + -h, --help display this help and exit\n\ + -V, --version output version information and exit\n\ +"; + + +static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:"; + + +static struct option const options[] = { + { "algo", 1, nullptr, 'a' }, + { "av", 1, nullptr, 'v' }, + { "background", 0, nullptr, 'B' }, + { "backup-url", 1, nullptr, 'b' }, + { "config", 1, nullptr, 'c' }, + { "cpu-affinity", 1, nullptr, 1020 }, + { "donate-level", 1, nullptr, 1003 }, + { "help", 0, nullptr, 'h' }, + { "keepalive", 0, nullptr ,'k' }, + { "max-cpu-usage", 1, nullptr, 1004 }, + { "nicehash", 0, nullptr, 1006 }, + { "no-color", 0, nullptr, 1002 }, + { "pass", 1, nullptr, 'p' }, + { "retries", 1, nullptr, 'r' }, + { "retry-pause", 1, nullptr, 'R' }, + { "safe", 0, nullptr, 1005 }, + { "threads", 1, nullptr, 't' }, + { "url", 1, nullptr, 'o' }, + { "user", 1, nullptr, 'u' }, + { "userpass", 1, nullptr, 'O' }, + { "version", 0, nullptr, 'V' }, + { 0, 0, 0, 0 } +}; + + +static const char *algo_names[] = { + "cryptonight", +# ifndef XMRIG_NO_AEON + "cryptonight-lite" +# endif +}; + + +Options *Options::parse(int argc, char **argv) +{ + if (!m_self) { + m_self = new Options(argc, argv); + } + + return m_self; +} + + +Options::Options(int argc, char **argv) : + m_background(false), + m_colors(true), + m_doubleHash(false), + m_keepalive(false), + m_nicehash(false), + m_ready(false), + m_safe(false), + m_pass(nullptr), + m_user(nullptr), + m_algo(0), + m_algoVariant(0), + m_donateLevel(DONATE_LEVEL), + m_maxCpuUsage(75), + m_retries(5), + m_retryPause(5), + m_threads(0), + m_affinity(-1L), + m_backupUrl(nullptr), + m_url(nullptr) +{ + int key; + + while (1) { + key = getopt_long(argc, argv, short_options, options, NULL); + if (key < 0) { + break; + } + + if (!parseArg(key, optarg)) { + return; + } + } + + if (optind < argc) { + fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]); + return; + } + + if (!m_url) { + LOG_ERR("No pool URL supplied. Exiting.", argv[0]); + return; + } + + if (!m_nicehash && m_url->isNicehash()) { + m_nicehash = true; + } + + if (!m_user) { + m_user = strdup("x"); + } + + if (!m_pass) { + m_pass = strdup("x"); + } + + m_ready = true; +} + + +Options::~Options() +{ + delete m_url; + delete m_backupUrl; + + free(m_user); + free(m_pass); +} + + +bool Options::parseArg(int key, char *arg) +{ +// char *p; + int v; +// uint64_t ul; + Url *url; + + switch (key) { + case 'a': /* --algo */ + if (!setAlgo(arg)) { + return false; + } + break; + + case 'O': /* --userpass */ + if (!setUserpass(arg)) { + return false; + } + break; + + case 'o': /* --url */ + url = parseUrl(arg); + if (url) { + free(m_url); + m_url = url; + } + break; + + case 'b': /* --backup-url */ + url = parseUrl(arg); + if (url) { + free(m_backupUrl); + m_backupUrl = url; + } + break; + + case 'u': /* --user */ + free(m_user); + m_user = strdup(arg); + break; + + case 'p': /* --pass */ + free(m_pass); + m_pass = strdup(arg); + break; + + case 'r': /* --retries */ + v = atoi(arg); + if (v < 1 || v > 1000) { + showUsage(1); + return false; + } + + m_retries = v; + break; + + case 'R': /* --retry-pause */ + v = atoi(arg); + if (v < 1 || v > 3600) { + showUsage(1); + return false; + } + + m_retryPause = v; + break; + + case 't': /* --threads */ + v = atoi(arg); + if (v < 1 || v > 1024) { + showUsage(1); + return false; + } + + m_threads = v; + break; + + case 1004: /* --max-cpu-usage */ + v = atoi(arg); + if (v < 1 || v > 100) { + showUsage(1); + return false; + } + + m_maxCpuUsage = v; + break; + + case 1005: /* --safe */ + m_safe = true; + break; + + case 'k': /* --keepalive */ + m_keepalive = true; + break; + + case 'V': /* --version */ + showVersion(); + return false; + + case 'h': /* --help */ + showUsage(0); + return false; + + case 'B': /* --background */ + m_background = true; + m_colors = false; + break; + + case 'v': /* --av */ + v = atoi(arg); + if (v < 0 || v > 1000) { + showUsage(1); + return false; + } + + m_algoVariant = v; + break; + + case 1020: /* --cpu-affinity */ +// p = strstr(arg, "0x"); +// ul = p ? strtoul(p, NULL, 16) : atol(arg); +// if (ul > (1UL << cpu_info.total_logical_cpus) -1) { +// ul = -1; +// } + +// opt_affinity = ul; + break; + + case 1002: /* --no-color */ + m_colors = false; + break; + + case 1003: /* --donate-level */ + v = atoi(arg); + if (v < 1 || v > 99) { + showUsage(1); + return false; + } + + m_donateLevel = v; + break; + + case 1006: /* --nicehash */ + m_nicehash = true; + break; + + default: + showUsage(1); + return false; + } + + return true; +} + + +Url *Options::parseUrl(const char *arg) const +{ + auto url = new Url(arg); + if (!url->isValid()) { + delete url; + return nullptr; + } + + return url; +} + + +void Options::showUsage(int status) const +{ + if (status) { + fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n"); + } + else { + printf(usage); + } +} + + +void Options::showVersion() +{ + printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ + + #ifdef __GNUC__ + " with GCC"); + printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); + #endif + + printf("\n features:" + #ifdef __i386__ + " i386" + #endif + #ifdef __x86_64__ + " x86_64" + #endif + #ifdef __AES__ + " AES-NI" + #endif + "\n"); + + printf("\nlibuv/%s\n", uv_version_string()); + printf("libjansson/%s\n", JANSSON_VERSION); +} + + +bool Options::setAlgo(const char *algo) +{ + for (size_t i = 0; i < ARRAY_SIZE(algo_names); i++) { + if (algo_names[i] && !strcmp(algo, algo_names[i])) { + m_algo = i; + break; + } + +# ifndef XMRIG_NO_AEON + if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) { + m_algo = ALGO_CRYPTONIGHT_LITE; + break; + } +# endif + + if (i == ARRAY_SIZE(algo_names) - 1) { + showUsage(1); + return false; + } + } + + return true; +} + + +bool Options::setUserpass(const char *userpass) +{ + char *p = strchr(userpass, ':'); + if (!p) { + showUsage(1); + return false; + } + + free(m_user); + free(m_pass); + + m_user = static_cast(calloc(p - userpass + 1, 1)); + strncpy(m_user, userpass, p - userpass); + m_pass = strdup(p + 1); + + return true; +} diff --git a/src/Options.h b/src/Options.h new file mode 100644 index 0000000..eccfbcf --- /dev/null +++ b/src/Options.h @@ -0,0 +1,94 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#ifndef __OPTIONS_H__ +#define __OPTIONS_H__ + + +#include + + +class Url; + + +class Options +{ +public: + enum Algo { + ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ + ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ + }; + + enum AlgoVariant { + AV0_AUTO, + AV1_AESNI, + AV2_AESNI_DOUBLE, + AV3_SOFT_AES, + AV4_SOFT_AES_DOUBLE, + AV_MAX + }; + + static inline Options* i() { return m_self; } + static Options *parse(int argc, char **argv); + + inline bool isReady() const { return m_ready; } + inline const char *pass() const { return m_pass; } + inline const char *user() const { return m_user; } + inline Url *url() const { return m_url; } + +private: + Options(int argc, char **argv); + ~Options(); + + static Options *m_self; + + bool parseArg(int key, char *arg); + Url *parseUrl(const char *arg) const; + void showUsage(int status) const; + void showVersion(void); + + bool setAlgo(const char *algo); + bool setUserpass(const char *userpass); + + bool m_background; + bool m_colors; + bool m_doubleHash; + bool m_keepalive; + bool m_nicehash; + bool m_ready; + bool m_safe; + char *m_pass; + char *m_user; + int m_algo; + int m_algoVariant; + int m_donateLevel; + int m_maxCpuUsage; + int m_retries; + int m_retryPause; + int m_threads; + int64_t m_affinity; + Url *m_backupUrl; + Url *m_url; +}; + +#endif /* __OPTIONS_H__ */ diff --git a/donate.h b/src/donate.h similarity index 100% rename from donate.h rename to src/donate.h diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h new file mode 100644 index 0000000..26ff10a --- /dev/null +++ b/src/interfaces/IClientListener.h @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#ifndef __ICLIENTLISTENER_H__ +#define __ICLIENTLISTENER_H__ + + +class Client; + + +class IClientListener +{ +public: + virtual ~IClientListener() {} + + virtual void onLoginCredentialsRequired(Client *client) = 0; +}; + + +#endif // __ICLIENTLISTENER_H__ diff --git a/src/net/Client.cpp b/src/net/Client.cpp new file mode 100644 index 0000000..cb77eba --- /dev/null +++ b/src/net/Client.cpp @@ -0,0 +1,311 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include + + +#include "Console.h" +#include "interfaces/IClientListener.h" +#include "net/Client.h" +#include "net/Url.h" + + +Client::Client(IClientListener *listener) : + m_host(nullptr), + m_listener(listener), + m_recvBufPos(0), + m_state(UnconnectedState), + m_port(0), + m_stream(nullptr), + m_socket(nullptr) +{ + m_resolver.data = this; + + m_hints.ai_family = PF_INET; + m_hints.ai_socktype = SOCK_STREAM; + m_hints.ai_protocol = IPPROTO_TCP; + m_hints.ai_flags = 0; + + m_recvBuf.base = static_cast(malloc(kRecvBufSize)); + m_recvBuf.len = kRecvBufSize; +} + + +Client::~Client() +{ + free(m_recvBuf.base); + free(m_socket); + free(m_host); +} + + +/** + * @brief Connect to server. + * + * @param host + * @param port + */ +void Client::connect(const char *host, uint16_t port) +{ + m_host = strdup(host); + m_port = port; + + LOG_DEBUG("[%s:%u] connect", m_host, m_port); + + resolve(host); +} + + +/** + * @brief Connect to server. + * + * @param url + */ +void Client::connect(const Url *url) +{ + connect(url->host(), url->port()); +} + + +void Client::disconnect() +{ + close(); +} + + +void Client::login(const char *user, const char *pass, const char *agent) +{ + const size_t size = 96 + strlen(user) + strlen(pass) + strlen(agent); + char *req = static_cast(malloc(size)); + snprintf(req, size, "{\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"},\"id\":1}\n", user, pass, agent); + + send(req); +} + + +/** + * @brief Send raw data to server. + * + * @param data + */ +void Client::send(char *data) +{ + LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_host, m_port, strlen(data), data); + if (state() != ConnectedState) { + LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_host, m_port, m_state); + return; + } + + uv_buf_t buf = uv_buf_init(data, strlen(data)); + + uv_write_t *req = static_cast(malloc(sizeof(uv_write_t))); + req->data = buf.base; + + uv_write(req, m_stream, &buf, 1, [](uv_write_t *req, int status) { + if (status) { + auto client = getClient(req->data); + LOG_ERR("[%s:%u] write error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + } + + free(req->data); + free(req); + }); +} + + +int Client::resolve(const char *host) +{ + setState(HostLookupState); + + m_recvBufPos = 0; + + const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); + if (r) { + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_port, uv_strerror(r)); + return 1; + } + + return 0; +} + + +void Client::close() +{ + if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) { + return; + } + + setState(ClosingState); + uv_close(reinterpret_cast(m_socket), Client::onClose); +} + + +void Client::connect(struct sockaddr *addr) +{ + setState(ConnectingState); + + reinterpret_cast(addr)->sin_port = htons(m_port); + free(m_socket); + + uv_connect_t *req = (uv_connect_t*) malloc(sizeof(uv_connect_t)); + req->data = this; + + m_socket = static_cast(malloc(sizeof(uv_tcp_t))); + m_socket->data = this; + + uv_tcp_init(uv_default_loop(), m_socket); + uv_tcp_nodelay(m_socket, 1); + uv_tcp_keepalive(m_socket, 1, 60); + + uv_tcp_connect(req, m_socket, (const sockaddr*) addr, Client::onConnect); +} + + +void Client::parse(char *line, size_t len) +{ + line[len - 1] = '\0'; + + LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_host, m_port, len, line); + + json_error_t err; + json_t *val = json_loads(line, 0, &err); + + if (!val) { + LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_host, m_port, err.text); + return; + } +} + + +void Client::setState(SocketState state) +{ + LOG_DEBUG("[%s:%u] state: %d", m_host, m_port, state); + + if (m_state == state) { + return; + } + + m_state = state; +} + + +void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) +{ + auto client = getClient(handle->data); + + buf->base = &client->m_recvBuf.base[client->m_recvBufPos]; + buf->len = client->m_recvBuf.len - client->m_recvBufPos; +} + + +void Client::onClose(uv_handle_t *handle) +{ + auto client = getClient(handle->data); + + free(client->m_socket); + + client->m_stream = nullptr; + client->m_socket = nullptr; + client->setState(UnconnectedState); +} + + +void Client::onConnect(uv_connect_t *req, int status) +{ + auto client = getClient(req->data); + if (status < 0) { + LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + free(req); + return; + } + + client->m_stream = static_cast(req->handle); + client->m_stream->data = req->data; + client->setState(ConnectedState); + + uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); + free(req); + + client->m_listener->onLoginCredentialsRequired(client); +} + + +void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) +{ + auto client = getClient(stream->data); + if (nread < 0) { + if (nread != UV_EOF) { + LOG_ERR("[%s:%u] read error: \"%s\"", client->m_host, client->m_port, uv_strerror(nread)); + } + + client->close(); + return; + } + + client->m_recvBufPos += nread; + + char* end; + char* start = client->m_recvBuf.base; + size_t remaining = client->m_recvBufPos; + + while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) { + end++; + size_t len = end - start; + client->parse(start, len); + + remaining -= len; + start = end; + } + + if (remaining == 0) { + client->m_recvBufPos = 0; + return; + } + + if (start == client->m_recvBuf.base) { + return; + } + + memcpy(client->m_recvBuf.base, start, remaining); + client->m_recvBufPos = remaining; +} + + +void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) +{ + auto client = getClient(req->data); + if (status < 0) { + LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + return; + } + + client->connect(res->ai_addr); + uv_freeaddrinfo(res); +} + + +Client *Client::getClient(void *data) +{ + return static_cast(data); +} diff --git a/src/net/Client.h b/src/net/Client.h new file mode 100644 index 0000000..181ea64 --- /dev/null +++ b/src/net/Client.h @@ -0,0 +1,87 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#ifndef __CLIENT_H__ +#define __CLIENT_H__ + + +#include + + +class Url; +class IClientListener; + + +class Client +{ +public: + enum SocketState { + UnconnectedState, + HostLookupState, + ConnectingState, + ConnectedState, + ClosingState + }; + + Client(IClientListener *listener); + ~Client(); + + void connect(const char *host, uint16_t port); + void connect(const Url *url); + void disconnect(); + void login(const char *user, const char *pass, const char *agent); + void send(char *data); + + inline SocketState state() const { return m_state; } + +private: + constexpr static size_t kRecvBufSize = 4096; + + int resolve(const char *host); + void close(); + void connect(struct sockaddr *addr); + void parse(char *line, size_t len); + void setState(SocketState state); + + static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); + static void onClose(uv_handle_t *handle); + static void onConnect(uv_connect_t *req, int status); + static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res); + + static Client *getClient(void *data); + + char *m_host; + IClientListener *m_listener; + size_t m_recvBufPos; + SocketState m_state; + struct addrinfo m_hints; + uint16_t m_port; + uv_buf_t m_recvBuf; + uv_getaddrinfo_t m_resolver; + uv_stream_t *m_stream; + uv_tcp_t *m_socket; +}; + + +#endif /* __CLIENT_H__ */ diff --git a/src/net/Network.cpp b/src/net/Network.cpp new file mode 100644 index 0000000..91b6262 --- /dev/null +++ b/src/net/Network.cpp @@ -0,0 +1,65 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include + + +#include "Console.h" +#include "net/Client.h" +#include "net/Network.h" +#include "Options.h" + + +Network::Network(const Options *options) : + m_backupPool(nullptr), + m_donatePool(nullptr), + m_pool(nullptr), + m_options(options) +{ + m_agent = userAgent(); + m_pool = new Client(this); +} + + +Network::~Network() +{ + delete m_pool; + delete m_donatePool; + delete m_backupPool; + + free(m_agent); +} + + +void Network::connect() +{ + m_pool->connect(m_options->url()); +// LOG_DEBUG("XX %s", m_options->url()); +} + + +void Network::onLoginCredentialsRequired(Client *client) +{ + client->login(m_options->user(), m_options->pass(), m_agent); +} diff --git a/src/net/Network.h b/src/net/Network.h new file mode 100644 index 0000000..5ee7c29 --- /dev/null +++ b/src/net/Network.h @@ -0,0 +1,56 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#ifndef __NETWORK_H__ +#define __NETWORK_H__ + + +#include "interfaces/IClientListener.h" + + +class Options; + + +class Network : public IClientListener +{ +public: + Network(const Options *options); + ~Network(); + + void connect(); + + static char *userAgent(); + +protected: + void onLoginCredentialsRequired(Client *client) override; + +private: + char *m_agent; + Client *m_backupPool; + Client *m_donatePool; + Client *m_pool; + const Options *m_options; +}; + + +#endif /* __NETWORK_H__ */ diff --git a/src/net/Network_win.cpp b/src/net/Network_win.cpp new file mode 100644 index 0000000..432ea71 --- /dev/null +++ b/src/net/Network_win.cpp @@ -0,0 +1,64 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include +#include + + +#include "net/Network.h" +#include "version.h" + + +static inline OSVERSIONINFOEX winOsVersion() +{ + typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO); + OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0}; + + HMODULE ntdll = GetModuleHandleW(L"ntdll.dll"); + if (ntdll ) { + RtlGetVersionFunction pRtlGetVersion = reinterpret_cast(GetProcAddress(ntdll, "RtlGetVersion")); + + if (pRtlGetVersion) { + pRtlGetVersion((LPOSVERSIONINFO) &result); + } + } + + return result; +} + + +char *Network::userAgent() +{ + const auto osver = winOsVersion(); + + char *buf = static_cast(malloc(128)); + +# ifdef __GNUC__ + snprintf(buf, 128, "%s/%s (Windows NT %lu.%lu; Win64; x64) libuv/%s gcc/%d.%d.%d", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion, uv_version_string(), __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# else + snprintf(buf, 128, "%s/%s (Windows NT %lu.%lu; Win64; x64) libuv/%s", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion, uv_version_string()); +# endif + + return buf; +} diff --git a/src/net/Url.cpp b/src/net/Url.cpp new file mode 100644 index 0000000..f54b0b9 --- /dev/null +++ b/src/net/Url.cpp @@ -0,0 +1,93 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + + +#include +#include + + +#include "net/Url.h" + + +/** + * @brief Parse url. + * + * Valid urls: + * example.com + * example.com:3333 + * stratum+tcp://example.com + * stratum+tcp://example.com:3333 + * + * @param url + */ +Url::Url(const char *url) : + m_host(nullptr), + m_port(3333) +{ + const char *p = strstr(url, "://"); + const char *base = url; + + if (p) { + if (strncasecmp(url, "stratum+tcp://", 14)) { + return; + } + + base = url + 14; + } + + if (!strlen(base) || *base == '/') { + return; + } + + char *port = strchr(base, ':'); + if (!port) { + m_host = strdup(base); + return; + } + + const size_t size = port++ - base + 1; + m_host = static_cast(malloc(size)); + memcpy(m_host, base, size - 1); + m_host[size - 1] = '\0'; + + m_port = strtol(port, nullptr, 10); +} + + +Url::Url(const char *host, uint16_t port) : + m_port(port) +{ + m_host = strdup(host); +} + + +Url::~Url() +{ + free(m_host); +} + + +bool Url::isNicehash() const +{ + return isValid() && strstr(m_host, ".nicehash.com"); +} diff --git a/src/net/Url.h b/src/net/Url.h new file mode 100644 index 0000000..a0e2d48 --- /dev/null +++ b/src/net/Url.h @@ -0,0 +1,49 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#ifndef __URL_H__ +#define __URL_H__ + + +#include + + +class Url +{ +public: + Url(const char *url); + Url(const char *host, uint16_t port); + ~Url(); + + bool isNicehash() const; + + inline bool isValid() const { return m_host && m_port > 0; } + inline const char *host() const { return m_host; } + inline uint16_t port() const { return m_port; } + +private: + char *m_host; + uint16_t m_port; +}; + +#endif /* __URL_H__ */ diff --git a/version.h b/src/version.h similarity index 92% rename from version.h rename to src/version.h index 330d969..d7bde17 100644 --- a/version.h +++ b/src/version.h @@ -27,14 +27,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "0.8.3" +#define APP_VERSION "1.0.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" -#define APP_VER_MAJOR 0 -#define APP_VER_MINOR 8 -#define APP_VER_BUILD 3 +#define APP_VER_MAJOR 1 +#define APP_VER_MINOR 0 +#define APP_VER_BUILD 0 #define APP_VER_REV 0 #endif /* __VERSION_H__ */ diff --git a/src/xmrig.cpp b/src/xmrig.cpp new file mode 100644 index 0000000..4b4afcd --- /dev/null +++ b/src/xmrig.cpp @@ -0,0 +1,31 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +#include "App.h" + + +int main(int argc, char **argv) { + auto app = new App(argc, argv); + + return app->exec(); +} diff --git a/utils/applog.c b/utils/applog.c deleted file mode 100644 index e0043c8..0000000 --- a/utils/applog.c +++ /dev/null @@ -1,151 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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, see . - */ - -#include "xmrig.h" -#include "applog.h" -#include "threads.h" -#include -#include - -#ifdef WIN32 -# include "compat/winansi.h" -#endif - -#include "options.h" - - -MUTEX applog_mutex; - - -void applog_init() -{ - MUTEX_INIT(applog_mutex); -} - - -void applog(int prio, const char *fmt, ...) -{ - if (opt_background) { - return; - } - - va_list ap; - va_start(ap, fmt); - - struct tm tm; - struct tm *tm_p; - time_t now = time(NULL); - - MUTEX_LOCK(applog_mutex); - tm_p = localtime(&now); - memcpy(&tm, tm_p, sizeof(tm)); - MUTEX_UNLOCK(applog_mutex); - - const char* color = ""; - - if (opt_colors) { - switch (prio) { - case LOG_ERR: color = CL_RED; break; - case LOG_WARNING: color = CL_YLW; break; - case LOG_NOTICE: color = CL_WHT; break; - case LOG_INFO: color = ""; break; - case LOG_DEBUG: color = CL_GRY; break; - - case LOG_BLUE: - prio = LOG_NOTICE; - color = CL_CYN; - break; - - case LOG_GREEN: - prio = LOG_NOTICE; - color = CL_LGR; - break; - } - } - - const int len = 64 + strlen(fmt) + 2; - char *f = alloca(len); - - sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", - tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec, - color, - fmt, - opt_colors ? CL_N : "" - ); - - MUTEX_LOCK(applog_mutex); - vfprintf(stderr, f, ap); - fflush(stderr); - MUTEX_UNLOCK(applog_mutex); - - va_end(ap); -} - - -void applog_notime(int prio, const char *fmt, ...) -{ - if (opt_background) { - return; - } - - va_list ap; - va_start(ap, fmt); - - const char* color = ""; - - if (opt_colors) { - switch (prio) { - case LOG_ERR: color = CL_RED; break; - case LOG_WARNING: color = CL_LYL; break; - case LOG_NOTICE: color = CL_WHT; break; - case LOG_INFO: color = ""; break; - case LOG_DEBUG: color = CL_GRY; break; - - case LOG_BLUE: - prio = LOG_NOTICE; - color = CL_CYN; - break; - } - } - - const int len = 64 + strlen(fmt) + 2; - char *f = alloca(len); - - sprintf(f, "%s%s%s\n", - color, - fmt, - opt_colors ? CL_N : "" - ); - - MUTEX_LOCK(applog_mutex); - vfprintf(stderr, f, ap); - fflush(stderr); - MUTEX_UNLOCK(applog_mutex); - - va_end(ap); -} diff --git a/utils/applog.h b/utils/applog.h deleted file mode 100644 index 24a7322..0000000 --- a/utils/applog.h +++ /dev/null @@ -1,75 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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, see . - */ - -#ifndef __APPLOG_H__ -#define __APPLOG_H__ - -enum { - LOG_ERR, - LOG_WARNING, - LOG_NOTICE, - LOG_INFO, - LOG_DEBUG, - LOG_BLUE = 0x10, - LOG_GREEN -}; - -#define CL_N "\x1B[0m" -#define CL_RED "\x1B[31m" -#define CL_GRN "\x1B[32m" -#define CL_YLW "\x1B[33m" -#define CL_BLU "\x1B[34m" -#define CL_MAG "\x1B[35m" -#define CL_CYN "\x1B[36m" - -#define CL_BLK "\x1B[22;30m" /* black */ -#define CL_RD2 "\x1B[22;31m" /* red */ -#define CL_GR2 "\x1B[22;32m" /* green */ -#define CL_BRW "\x1B[22;33m" /* brown */ -#define CL_BL2 "\x1B[22;34m" /* blue */ -#define CL_MA2 "\x1B[22;35m" /* magenta */ -#define CL_CY2 "\x1B[22;36m" /* cyan */ -#define CL_SIL "\x1B[22;37m" /* gray */ - -#ifdef WIN32 -#define CL_GRY "\x1B[01;30m" /* dark gray */ -#else -#define CL_GRY "\x1B[90m" /* dark gray selectable in putty */ -#endif -#define CL_LRD "\x1B[01;31m" /* light red */ -#define CL_LGR "\x1B[01;32m" /* light green */ -#define CL_LYL "\x1B[01;33m" /* light yellow */ -#define CL_LBL "\x1B[01;34m" /* light blue */ -#define CL_LMA "\x1B[01;35m" /* light magenta */ -#define CL_LCY "\x1B[01;36m" /* light cyan */ - -#define CL_WHT "\x1B[01;37m" /* white */ - -#define OPT_COLOR(color, text) (opt_colors ? (color text CL_N) : text) - - -void applog_init(); -void applog(int prio, const char *fmt, ...); -void applog_notime(int prio, const char *fmt, ...); - -#endif /* __APPLOG_H__ */