denyhosts/disk.c
2024-05-28 11:08:55 +08:00

119 lines
3.4 KiB
C

#include "disk.h"
// 获取指定路径的磁盘使用率
int get_disk_usage(const char *path, double *usage) {
struct statvfs stat;
if (statvfs(path, &stat) != 0) {
perror("statvfs failed");
return -1;
}
// 计算磁盘使用率
unsigned long total_blocks = stat.f_blocks;
unsigned long free_blocks = stat.f_bfree;
unsigned long used_blocks = total_blocks - free_blocks;
*usage = (double)used_blocks / total_blocks * 100;
return 0;
}
// 第三方邮箱告警, 磁盘使用率
int QQ_mail_warning_Disk_Use(const char *recv_mail, const char *local_ip, const char *text, int current_length) {
int command_len = current_length + sizeof(QQMAIL_DISK_USE) + strlen(recv_mail) + strlen(local_ip) + 256;
char command[command_len];
// 生成邮件正文
char mail_text[command_len];
snprintf(mail_text, command_len, "Host:%s\n%s", local_ip, text);
// 生成命令字符串
snprintf(command, command_len, QQMAIL_DISK_USE, recv_mail, mail_text);
// 打印命令用于调试
printf("Command: %s %d\n", command, current_length);
// 执行命令
int ret = system(command);
if (ret == -1) {
perror("system command failed");
return -1;
}
return 0;
}
int disk_usage(conf *conf, char *local_ip, int threshold) {
FILE *mounts;
struct mntent *ent;
char *result;
size_t result_size = INITIAL_SIZE;
size_t current_length = 0;
result = (char *)malloc(result_size);
if (result == NULL) {
perror("内存分配失败");
return 1;
}
result[0] = '\0'; // 初始化为空字符串
// 打开挂载表
mounts = setmntent("/etc/mtab", "r");
if (mounts == NULL) {
perror("打开挂载表失败");
free(result);
return 1;
}
// 遍历每个挂载的文件系统
while ((ent = getmntent(mounts)) != NULL) {
double usage = 0;
// 检查文件系统是否为设备
if (strstr(ent->mnt_fsname, "/dev/") != NULL) {
// 获取挂载点的磁盘使用率
if (get_disk_usage(ent->mnt_dir, &usage) != 0) {
fprintf(stderr, "获取 %s 的磁盘使用率失败\n", ent->mnt_dir);
continue;
}
// 如果使用率超过阈值则拼接字符串
if (usage > threshold) {
char buffer[BUFFER_INCREMENT];
int len = snprintf(buffer, BUFFER_INCREMENT, "挂载点:%s 使用率:%.2f%% 阀值:%d%%\n", ent->mnt_dir, usage, threshold);
// 检查缓冲区大小是否足够
if (current_length + len >= result_size) {
result_size += BUFFER_INCREMENT;
result = (char *)realloc(result, result_size);
if (result == NULL) {
perror("内存重新分配失败");
endmntent(mounts);
return 1;
}
}
strcat(result, buffer);
current_length += len;
}
}
}
// 发送邮件警告
if (current_length > 0) {
if (QQ_mail_warning_Disk_Use(conf->RECV_MAIL, local_ip, result, current_length) != 0) {
fprintf(stderr, "发送邮件失败\n");
}
}
// 清理
free(result);
endmntent(mounts);
return 0;
}