diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c8a3bee84e4c9bacfd258793ba0f12240777ad7c..2120d03f2c277454dfa33241eb15bc6272c0e1ce 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8) project (dap_client) -set(CLIENT_SRCS dap_client.c dap_client_internal.c dap_client_remote.c) +set(CLIENT_SRCS dap_client.c dap_client_internal.c dap_client_remote.c dap_common.c) add_library(${PROJECT_NAME} STATIC ${CLIENT_SRCS}) diff --git a/client/dap_common.c b/client/dap_common.c new file mode 100644 index 0000000000000000000000000000000000000000..b81ba5d687404620513f5b521f65b79c041fb658 --- /dev/null +++ b/client/dap_common.c @@ -0,0 +1,304 @@ +#ifdef DAP_OS_ANDROID +#include <android/log.h> +#endif + +#ifndef _MSC_VER +#include <unistd.h> /* 'pipe', 'read', 'write' */ +#include <pthread.h> +#include <syslog.h> +#elif defined(_MSC_VER) +#include <stdio.h> +#include <stdlib.h> +#include <windows.h> +#include <process.h> +typedef HANDLE pthread_mutex_t; +#define popen _popen +#define pclose _pclose +#define PTHREAD_MUTEX_INITIALIZER 0 +int pthread_mutex_lock(HANDLE **obj) +{ + return (( *obj = (HANDLE) CreateMutex(0, 1, 0) ) == NULL) ? 0 : 1; +} +int pthread_mutex_unlock(HANDLE *obj) { + return (ReleaseMutex(obj) == 0) ? 0 : 1; +} +#endif +#include <time.h> /* 'nanosleep' */ +#include <string.h> +#include <stdarg.h> +#include <stdio.h> +#include "dap_common.h" +#define LAST_ERROR_MAX 255 + +#define LOG_TAG "common" + +char last_error[LAST_ERROR_MAX]={0}; +enum log_level log_level=L_DEBUG; +static FILE * s_lf=NULL; + +int dap_common_init( const char * a_log_file ) +{ + if ( a_log_file ) { + s_lf=fopen( a_log_file , "a"); + if(s_lf==NULL){ + fprintf(stderr,"Can't open log file %s to append\n", a_log_file); + s_lf=stdout; + return -1; + } + } + + return 0; +} + +void common_deinit() +{ + if(s_lf) fclose(s_lf); +} + +void _log_it(const char * log_tag,enum log_level ll, const char * format,...) +{ + if(ll<log_level) + return; + + va_list ap; + + + + va_start(ap,format); + _vlog_it(log_tag,ll, format,ap); + va_end(ap); +} + +void _vlog_it(const char * log_tag,enum log_level ll, const char * format,va_list ap) +{ + va_list ap2; + + static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&mutex); +#ifdef DAP_OS_ANDROID + char buf[4096]; + vsnprintf(buf,sizeof(buf),format,ap); + switch (ll) { + case L_INFO: + __android_log_write(ANDROID_LOG_INFO,DAP_BRAND,buf); + break; + case L_WARNING: + __android_log_write(ANDROID_LOG_WARN,DAP_BRAND,buf); + break; + case L_ERROR: + __android_log_write(ANDROID_LOG_ERROR,DAP_BRAND,buf); + break; + case L_CRITICAL: + __android_log_write(ANDROID_LOG_FATAL,DAP_BRAND,buf); + abort(); + break; + case L_DEBUG: + default: + __android_log_write(ANDROID_LOG_DEBUG,DAP_BRAND,buf); + } +#endif + time_t t=time(NULL); + struct tm* tmp=localtime(&t); + static char s_time[1024]={0}; + strftime(s_time,sizeof(s_time),"%x-%X",tmp); + + + va_copy(ap2,ap); + if (s_lf ) fprintf(s_lf,"[%s] ",s_time); + printf("[%s] ",s_time); + /*if(ll>=ERROR){ + vsnprintf(last_error,LAST_ERROR_MAX,format,ap); + }*/ + + if(ll==L_DEBUG){ + if (s_lf ) fprintf(s_lf,"[DBG] "); + printf( "\x1b[37;2m[DBG] "); + }else if(ll==L_INFO){ + if (s_lf ) fprintf(s_lf,"[ ] "); + printf("\x1b[32;2m[ ] "); + }else if(ll==L_NOTICE){ + if (s_lf ) fprintf(s_lf,"[ * ] "); + printf("\x1b[32m[ * ] "); + }else if(ll==L_WARNING){ + if (s_lf ) fprintf(s_lf,"[WRN] "); + printf("\x1b[31;2m[WRN] "); + }else if(ll==L_ERROR){ + if (s_lf ) fprintf(s_lf,"[ERR] "); + printf("\x1b[31m[ERR] "); + }else if(ll==L_CRITICAL){ + if (s_lf ) fprintf(s_lf,"[!!!] "); + printf("\x1b[1;5;31m[!!!] "); + } + if (s_lf ) fprintf(s_lf,"[%8s]\t",log_tag); + printf("[%8s]\t",log_tag); + + if (s_lf ) vfprintf(s_lf,format,ap); + vprintf(format,ap2); + if (s_lf ) fprintf(s_lf,"\n"); + printf("\x1b[0m\n"); + va_end(ap2); + if (s_lf ) fflush(s_lf); + fflush(stdout); + pthread_mutex_unlock(&mutex); +} + +const char * log_error() +{ + return last_error; +} + +#define INT_DIGITS 19 /* enough for 64 bit integer */ + +char *itoa(int i) +{ + /* Room for INT_DIGITS digits, - and '\0' */ + static char buf[INT_DIGITS + 2]; + char *p = buf + INT_DIGITS + 1; /* points to terminating '\0' */ + if (i >= 0) { + do { + *--p = '0' + (i % 10); + i /= 10; + } while (i != 0); + return p; + } + else { /* i < 0 */ + do { + *--p = '0' - (i % 10); + i /= 10; + } while (i != 0); + *--p = '-'; + } + return p; +} + +/** + * @brief time_to_rfc822 Convert time_t to string with RFC822 formatted date and time + * @param out Output buffer + * @param out_size_mac Maximum size of output buffer + * @param t UNIX time + * @return Length of resulting string if ok or lesser than zero if not + */ +int time_to_rfc822(char * out, size_t out_size_max, time_t t) +{ + struct tm *tmp; + tmp=localtime(&t); + if(tmp== NULL){ + log_it(L_ERROR,"Can't convert data from unix fromat to structured one"); + return -2; + }else{ + int ret; + ret=strftime(out, out_size_max,"%a, %d %b %y %T %z",tmp); + //free(tmp); + if(ret>0){ + return ret; + }else{ + log_it(L_ERROR,"Can't print formatted time in string"); + return -1; + } + } +} + + + +static int breaker_set[2] = { -1, -1 }; +static int initialized = 0; +static struct timespec break_latency = {0, 1 * 1000 * 1000 }; +#ifndef _MSC_VER +int get_select_breaker() +{ + if (!initialized) + { + if (pipe(breaker_set) < 0) return -1; + else initialized = 1; + } + + return breaker_set[0]; +} + +int send_select_break() +{ + if (!initialized) return -1; + char buffer[1]; + if (write(breaker_set[1], "\0", 1) <= 0) return -1; + nanosleep(&break_latency, NULL); + if (read(breaker_set[0], buffer, 1) <= 0 || buffer[0] != '\0') return -1; + return 0; +} +#else +char *strndup(const char *s, size_t n) { + char *p = memchr(s, '\0', n); + if (p != NULL) + n = p - s; + p = malloc(n + 1); + if (p != NULL) { + memcpy(p, s, n); + p[n] = '\0'; + } + return p; +} +#endif + +#ifdef ANDROID1 +static u_long myNextRandom = 1; + +double atof(const char *nptr) +{ + return (strtod(nptr, NULL)); +} + +int rand(void) +{ + return (int)((myNextRandom = (1103515245 * myNextRandom) + 12345) % ((u_long)RAND_MAX + 1)); +} + +void srand(u_int seed) +{ + myNextRandom = seed; +} + +#endif + +/** + * @brief exec_with_ret + * @param a_cmd + * @return + */ +char * exec_with_ret(const char * a_cmd) +{ + FILE * fp; + size_t buf_len = 0; + char buf[4096] = {0}; + fp= popen(a_cmd, "r"); + if (!fp) { + goto FIN; + } + memset(buf,0,sizeof(buf)); + fgets(buf,sizeof(buf)-1,fp); + pclose(fp); + buf_len=strlen(buf); + if(buf[buf_len-1] =='\n')buf[buf_len-1] ='\0'; +FIN: + return strdup(buf); +} + +char * exec_with_ret_multistring(const char * a_cmd) +{ + FILE * fp; + size_t buf_len = 0; + char buf[4096] = {0}; + fp= popen(a_cmd, "r"); + if (!fp) { + goto FIN; + } + memset(buf,0,sizeof(buf)); + char retbuf[4096] = {0}; + while(fgets(buf,sizeof(buf)-1,fp)) { + strcat(retbuf, buf); + } + pclose(fp); + buf_len=strlen(retbuf); + if(retbuf[buf_len-1] =='\n')retbuf[buf_len-1] ='\0'; +FIN: + return strdup(retbuf); +} diff --git a/client/dap_common.h b/client/dap_common.h new file mode 100644 index 0000000000000000000000000000000000000000..621d485a316c9c61a32be3c954ff82a8a6bfe366 --- /dev/null +++ b/client/dap_common.h @@ -0,0 +1,49 @@ + +#ifndef DAP_COMMON_H +#define DAP_COMMON_H + +#include <stdarg.h> +#include <stddef.h> +#include <stdlib.h> +#include <time.h> + +#define MALLOC(a) ((a *) malloc(sizeof(a))) +#define CALLOC(a) ((a *) calloc(1,sizeof(a))) +#define DUP(a) (__typeof(a) ret = memcpy(ret,a,sizeof(*a)) ) + +#define DAP_PROTOCOL_VERSION 20 + +enum log_level{L_CRITICAL=5,L_ERROR=4, L_WARNING=3,L_NOTICE=2,L_INFO=1,L_DEBUG=0}; +extern enum log_level log_level; + +#ifdef __cplusplus +extern "C" { +#endif + +int dap_common_init( const char * a_log_file ); +void common_deinit(); + +void _log_it(const char * log_tag, enum log_level, const char * format,...); +void _vlog_it(const char * log_tag, enum log_level, const char * format, va_list ap ); +#define log_it(_log_level,...) _log_it(LOG_TAG,_log_level,##__VA_ARGS__) +#define vlog_it(a_log_level,a_format,a_ap) _vlog_it(LOG_TAG,a_log_level,a_format,a_ap) + +const char * log_error(); + +#ifdef __GNUC__ +char *itoa(int i); +#elif _MSC_VER +char *strndup(const char *s, size_t n); +#endif +int time_to_rfc822(char * out, size_t out_size_max, time_t t); + +int get_select_breaker(); +int send_select_break(); +char * exec_with_ret(const char * a_cmd); +char * exec_with_ret_multistring(const char * a_cmd); + +#ifdef __cplusplus +} +#endif + +#endif