Files
DenyIP/common.c
2024-10-30 10:59:48 +08:00

224 lines
5.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}