Files
DenyIP/common.c
aixiao 5e441c068f 优化:
添加主要处理函数Processing_IP_addresses(src_ip);
数据处理放到cache.c
暂时未发现Bug
2025-02-17 12:59:02 +08:00

285 lines
7.4 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(const char *str) {
if (str == NULL)
return 0;
const char *_p = strchr(str, '\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() {
static char temp[BUFFER];
const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
time_t t = time(NULL);
struct tm *p = localtime(&t);
if (!p) {
perror("localtime failed");
return NULL;
}
snprintf(temp, sizeof(temp), "[%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 temp; // 返回静态缓冲区地址
}
// 将字符串转换为IPv4地址
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());
if (oldprio == -1 && errno != 0) {
perror("getpriority failed");
return -1;
}
printf("Current priority: %d\n", oldprio);
// 检查是否溢出
if ((increment > 0 && oldprio > INT_MAX - increment) ||
(increment < 0 && oldprio < INT_MIN - increment)) {
fprintf(stderr, "Priority overflow error\n");
return -1;
}
// 计算新的优先级
int newprio = oldprio + increment;
// 检查新的优先级是否在有效范围内
if (newprio < PRIO_MIN || newprio > PRIO_MAX) {
fprintf(stderr, "New priority out of range: %d (valid range is %d to %d)\n", newprio, PRIO_MIN, PRIO_MAX);
return -1;
}
// 设置新的优先级
if (setpriority(PRIO_PROCESS, getpid(), newprio) == -1) {
perror("setpriority failed");
return -1;
}
printf("New priority: %d\n", newprio);
return 0;
}
// 判断命令是否存在
int _command_exists(const char *command) {
const char *path_env = getenv("PATH");
if (!path_env) {
return 0; // 如果 PATH 不存在,返回不存在
}
char filepath[1024]; // 缓冲区大小
const char *dir = path_env;
while (dir && *dir) {
// 查找 PATH 中的下一个目录
const char *end = strchr(dir, ':');
size_t len = end ? (size_t)(end - dir) : strlen(dir);
// 构建路径并检查长度
if (snprintf(filepath, sizeof(filepath), "%.*s/%s", (int)len, dir, command) >= (int)sizeof(filepath)) {
return 0; // 缓冲区溢出,返回不存在
}
// 检查文件是否存在且可执行
if (access(filepath, X_OK) == 0) {
puts(filepath);
return 1; // 命令存在
}
// 更新 dir 指针
dir = end ? end + 1 : NULL;
}
return 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;
}
void remove_char(char *str, char c)
{
int i = 0, j = 0;
while (str[i]) {
if (str[i] != c) {
str[j++] = str[i];
}
i++;
}
str[j] = '\0';
}