#include "common.h" // 计算字符串长度 int _strlen(char *str) { char *_p = NULL; if (str == NULL) return 0; _p = strchr(str, '\0'); if (_p == NULL) return 0; return _p - str; } // 自定义 printf 函数 void _printf(const char *format, ...) { va_list args; va_start(args, format); // 获取当前时间 time_t now = time(NULL); struct tm local_time; localtime_r(&now, &local_time); char time_str[20]; // YYYY-MM-DD HH:MM:SS 格式 strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time); // 打印时间戳到控制台 printf("[%s] ", time_str); vprintf(format, args); // 打印内容到控制台 va_end(args); // 结束对变参列表的处理 // 重新启动变参列表 va_start(args, format); // 打开日志文件(追加模式) FILE *log_file = fopen(PRINT_LOG_FILE, "a"); if (log_file != NULL) { // 打印时间戳到日志文件 fprintf(log_file, "[%s] ", time_str); // 打印内容到日志文件 vfprintf(log_file, format, args); // 关闭日志文件 fclose(log_file); } else { perror("Unable to open log file"); } va_end(args); // 结束对变参列表的处理 } void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM]) { int i = 0; char *result = NULL; char temp[WHITELIST_IP_NUM]; // 创建一个足够大的副本缓冲区 // 复制原始字符串到副本 strncpy(temp, string, sizeof(temp) - 1); temp[sizeof(temp) - 1] = '\0'; // 确保字符串以 '\0' 结尾 result = strtok(temp, delims); // 使用副本进行拆分 while (result != NULL && i < WHITELIST_IP_NUM) { strncpy(whitelist_ip[i], result, WHITELIST_IP_NUM - 1); whitelist_ip[i][WHITELIST_IP_NUM - 1] = '\0'; // 确保每个元素以 '\0' 结尾 i++; result = strtok(NULL, delims); } } // IP段白名单对比 int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM]) { int i; for (i = 0; i < WHITELIST_IP_NUM; i++) { // 从 i = 0 开始 // 如果白名单 IP 是空字符串,跳出循环 if (whitelist_ip[i][0] == '\0') { break; } // 对比client_ip的前缀是否与白名单中的IP段匹配 if (strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i])) == 0) { return 1; // 匹配成功 } } return 0; // 未找到匹配 } // 地域段白名单对比 int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM]) { int i; char *p; for (i = 0; i < WHITELIST_IP_NUM; i++) { // 如果region_list[i]为空字符串,跳出循环 if (region_list[i][0] == '\0') { break; } // 在str中查找region_list[i] p = strstr(str, region_list[i]); if (p != NULL) { return 1; // 匹配成功,返回1 } } return 0; // 没有匹配,返回0 } int8_t _copy_new_mem(char *src, int src_len, char **dest) { *dest = (char *)malloc(src_len + 1); if (*dest == NULL) return 1; memcpy(*dest, src, src_len); *((*dest) + src_len) = '\0'; return 0; } char *_time() { char temp[BUFFER]; char *wday[] = { "0", "1", "2", "3", "4", "5", "6" }; time_t t; struct tm *p; time(&t); p = localtime(&t); // 取得当地时间 memset(temp, 0, BUFFER); snprintf(temp, BUFFER, "[%d/%02d/%02d %s %02d:%02d:%02d] ", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); return strdup(temp); } int is_valid_ip(const char *ip) { struct sockaddr_in sa; // 尝试将字符串转换为IPv4地址 int result = inet_pton(AF_INET, ip, &(sa.sin_addr)); return result != 0; } int _nice(int increment) { int oldprio = getpriority(PRIO_PROCESS, getpid()); printf("%d\n", oldprio); return setpriority(PRIO_PROCESS, getpid(), oldprio + increment); } // 判断命令是否存在 int _command_exists(const char *command) { char buffer[BUFFER]; snprintf(buffer, sizeof(buffer), "%s > /dev/null 2>&1", command); int status = system(buffer); return (status == 0); } // 定义一个函数,执行命令并返回输出 char *_execute_command(const char *command) { FILE *fp; char buffer[1024]; char *output = NULL; size_t output_size = 0; size_t total_read = 0; // 打开管道,执行命令 fp = popen(command, "r"); if (fp == NULL) { perror("popen"); return NULL; } // 读取命令的输出 while (fgets(buffer, sizeof(buffer), fp) != NULL) { size_t len = strlen(buffer); if (total_read + len + 1 > output_size) { output_size = output_size == 0 ? 128 : output_size * 2; char *new_output = realloc(output, output_size); if (new_output == NULL) { perror("realloc"); free(output); // 释放已分配的内存 pclose(fp); // 关闭管道 return NULL; } output = new_output; } // 复制内容并增加总计读取的长度 strcpy(output + total_read, buffer); total_read += len; } // 确保输出以 null 结尾 if (output_size > 0) { output[total_read] = '\0'; } // 关闭管道 if (pclose(fp) == -1) { perror("pclose"); free(output); // pclose 失败时释放内存 return NULL; } return output; }