/* * Copyright (c) 2020 YuQing <384681@qq.com> * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #ifdef OS_LINUX #include #endif #include #include #include #include #include "sf_define.h" #include "sf_util.h" int64_t getticks() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000; } void log_plus(const int priority, const char* file, int line, const char* fmt, ...) { char buf[2048]; int hlen; va_list ap; #ifdef DEBUG_FLAG long tid; #endif if (g_log_context.log_level < priority) { return; } #ifdef DEBUG_FLAG #ifdef OS_LINUX #ifdef SYS_gettid tid = (long)syscall(SYS_gettid); #else tid = (long)pthread_self(); #endif #else tid = (long)pthread_self(); #endif hlen = snprintf(buf, sizeof(buf), "%s:%d %ld ", file, line, tid); #else hlen = snprintf(buf, sizeof(buf), "%s:%d ", file, line); #endif va_start(ap, fmt); hlen += vsnprintf(buf+hlen, sizeof(buf)-hlen, fmt, ap); va_end(ap); if (hlen >= sizeof(buf)) { hlen = sizeof(buf) - 1; } log_it_ex1(&g_log_context, priority, buf, hlen); } int sf_printbuffer(char* buffer,int32_t len) { int i; if(buffer == NULL) { fprintf(stderr, "common-utils parameter is fail"); return(-1); } for(i=0; i " "[start | stop | restart | status]\n\noptions:\n", program); if (other_options != NULL) { const SFCMDOption *option; option = other_options; while (option->name.str != NULL) { fprintf(stderr, "\t%s\n", option->desc); option++; } } fprintf(stderr, "\t-N | --no-daemon: run in foreground\n" "\t-V | --version: show version info\n" "\t-h | --help: for this usage\n\n"); } static int match_option(const char *str, const SFCMDOption *option) { const char *start; const char *end; if (str[1] == '-') { start = str + 2; while (option->name.str != NULL) { if (strncmp(option->name.str, start, option->name.len) == 0) { end = start + option->name.len; if (*end == '\0') { return option->has_arg ? 2 : 1; } else if (*end == '=') { return 1; } } option++; } } else { while (option->name.str != NULL) { if (option->val == str[1]) { if (str[2] == '\0') { return option->has_arg ? 2 : 1; } else { return 1; } } option++; } } return 0; } const char *sf_parse_daemon_mode_and_action_ex(int argc, char *argv[], const Version *version, bool *daemon_mode, char **action, const char *default_action, const SFCMDOption *other_options) { #define CMD_NORMAL_ARG_COUNT 2 int i; int inc; struct { int argc; char *argv[CMD_NORMAL_ARG_COUNT]; } normal; const char *config_filepath; normal.argc = 0; *daemon_mode = true; i = 1; while (i < argc) { if (argv[i][0] != '-') { if (normal.argc == CMD_NORMAL_ARG_COUNT) { fprintf(stderr, "\nError: too many arguments!\n"); sf_usage_ex(argv[0], other_options); return NULL; } normal.argv[normal.argc++] = argv[i++]; continue; } if (other_options != NULL) { inc = match_option(argv[i], other_options); if (inc > 0) { i += inc; if (i > argc) { fprintf(stderr, "\nError: expect argument!\n"); sf_usage_ex(argv[0], other_options); return NULL; } continue; } } if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--version") == 0) { char *last_slash; char *proc_name; if ((last_slash=strrchr(argv[0], '/')) != NULL) { proc_name = last_slash + 1; } else { proc_name = argv[0]; } printf("\n%s V%d.%d.%d\n\n", proc_name, version->major, version->minor, version->patch); return NULL; } if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { sf_usage_ex(argv[0], other_options); return NULL; } if (strcmp(argv[i], "-N") == 0 || strcmp(argv[i], "--no-daemon") == 0) { *daemon_mode = false; i++; } else { fprintf(stderr, "\nError: unrecognized option: %s\n", argv[i]); sf_usage_ex(argv[0], other_options); return NULL; } } if (normal.argc == 0) { fprintf(stderr, "\nError: expect config file!\n"); sf_usage_ex(argv[0], other_options); return NULL; } config_filepath = normal.argv[0]; if (normal.argc > 1) { *action = normal.argv[1]; } else { *action = (char *)default_action; } return config_filepath; } void sf_parse_cmd_option_bool(int argc, char *argv[], const string_t *short_option, const string_t *long_option, bool *value) { char **pp; char **end; int len; *value = false; end = argv + argc; for (pp=argv + 1; ppsync_log_buff_interval, log_sync_func, pContext); pScheduleEntry++; if (log_cfg->rotate_everyday) { INIT_SCHEDULE_ENTRY_EX(*pScheduleEntry, sched_generate_next_id(), log_cfg->rotate_time, 86400, log_notify_rotate, pContext); pScheduleEntry++; } if ((log_cfg->rotate_everyday || log_cfg->rotate_on_size > 0) && (log_cfg->keep_days > 0)) { log_set_keep_days(pContext, log_cfg->keep_days); INIT_SCHEDULE_ENTRY_EX(*pScheduleEntry, sched_generate_next_id(), log_cfg->delete_old_time, 86400, log_delete_old_files, pContext); pScheduleEntry++; } return pScheduleEntry; } const char *sf_strerror(const int errnum) { switch (errnum) { case SF_CLUSTER_ERROR_BINLOG_MISSED: return "binlog missed"; case SF_CLUSTER_ERROR_BINLOG_INCONSISTENT: return "binlog inconsistent"; case SF_CLUSTER_ERROR_LEADER_INCONSISTENT: return "leader or master inconsistent"; case SF_RETRIABLE_ERROR_NO_SERVER: return "no server available"; case SF_RETRIABLE_ERROR_NOT_MASTER: return "i am not master"; case SF_RETRIABLE_ERROR_NOT_ACTIVE: return "i am not active"; case SF_RETRIABLE_ERROR_NO_CHANNEL: return "idempotency channel not exist"; case SF_RETRIABLE_ERROR_CHANNEL_INVALID: return "idempotency channel is invalid"; case SF_ERROR_EINVAL: return STRERROR(EINVAL); case SF_ERROR_EAGAIN: return STRERROR(EAGAIN); case SF_ERROR_EINPROGRESS: return STRERROR(EINPROGRESS); case SF_ERROR_EOVERFLOW: return STRERROR(EOVERFLOW); case SF_ERROR_ENODATA: return STRERROR(ENODATA); default: return STRERROR(errnum); } }