utils.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "common.h"
  2. #include <ctype.h>
  3. #include <sys/time.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. /* 全局日志回调 */
  7. LogCallback g_log_callback = NULL;
  8. void set_log_callback(LogCallback cb) {
  9. g_log_callback = cb;
  10. }
  11. char* get_timestamp(char* buf, size_t bufsize, const char* fmt) {
  12. time_t now = time(NULL);
  13. struct tm* tm_info = localtime(&now);
  14. if (fmt == NULL) {
  15. fmt = "%Y-%m-%d %H:%M:%S";
  16. }
  17. strftime(buf, bufsize, fmt, tm_info);
  18. return buf;
  19. }
  20. char* str_tolower(char* str) {
  21. char* p = str;
  22. while (*p) {
  23. *p = tolower((unsigned char)*p);
  24. p++;
  25. }
  26. return str;
  27. }
  28. size_t safe_strcpy(char* dest, const char* src, size_t size) {
  29. if (size == 0 || src == NULL) return 0;
  30. size_t len = strlen(src);
  31. if (len >= size) {
  32. len = size - 1;
  33. }
  34. memcpy(dest, src, len);
  35. dest[len] = '\0';
  36. return len;
  37. }
  38. /* 简单的文件写入工具 */
  39. int write_file(const char* path, const char* content) {
  40. FILE* fp = fopen(path, "w");
  41. if (fp == NULL) {
  42. LOG_ERROR("Failed to open file: %s, error: %s", path, strerror(errno));
  43. return FAILURE;
  44. }
  45. fprintf(fp, "%s", content);
  46. fclose(fp);
  47. return SUCCESS;
  48. }
  49. /* 读取配置文件(简单键值对格式) */
  50. char* read_config_value(const char* file, const char* key) {
  51. static char value[256];
  52. FILE* fp = fopen(file, "r");
  53. if (fp == NULL) {
  54. LOG_ERROR("Failed to open config file: %s", file);
  55. return NULL;
  56. }
  57. char line[512];
  58. while (fgets(line, sizeof(line), fp)) {
  59. /* 跳过注释和空行 */
  60. if (line[0] == '#' || line[0] == ';' || line[0] == '\n') continue;
  61. /* 移除换行符 */
  62. line[strcspn(line, "\n")] = '\0';
  63. char* eq = strchr(line, '=');
  64. if (eq != NULL) {
  65. *eq = '\0';
  66. if (strcmp(line, key) == 0) {
  67. safe_strcpy(value, eq + 1, sizeof(value));
  68. fclose(fp);
  69. return value;
  70. }
  71. }
  72. }
  73. fclose(fp);
  74. return NULL;
  75. }
  76. /* 确保目录存在 */
  77. int ensure_directory(const char* path) {
  78. struct stat st;
  79. if (stat(path, &st) == 0) {
  80. return S_ISDIR(st.st_mode) ? SUCCESS : FAILURE;
  81. }
  82. /* 递归创建目录 */
  83. char tmp[MAX_PATH_SIZE];
  84. safe_strcpy(tmp, path, sizeof(tmp));
  85. char* p = tmp;
  86. while (*p) {
  87. if (*p == '/') {
  88. *p = '\0';
  89. mkdir(tmp, 0755);
  90. *p = '/';
  91. }
  92. p++;
  93. }
  94. mkdir(tmp, 0755);
  95. return SUCCESS;
  96. }
  97. /* 生成唯一ID */
  98. static int g_id_counter = 0;
  99. int generate_id(void) {
  100. return ++g_id_counter;
  101. }
  102. /* 睡眠(可中断) */
  103. int sleep_milliseconds(int ms) {
  104. struct timespec ts;
  105. ts.tv_sec = ms / 1000;
  106. ts.tv_nsec = (ms % 1000) * 1000000L;
  107. return nanosleep(&ts, NULL);
  108. }
  109. /* 获取当前毫秒时间戳 */
  110. long long get_current_ms(void) {
  111. struct timeval tv;
  112. gettimeofday(&tv, NULL);
  113. return (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
  114. }
  115. /* 获取当前秒时间戳 */
  116. long long get_current_s(void) {
  117. return (long long)time(NULL);
  118. }