#include #include #include #include #include #include "ulog.h" #include "log_common.h" #include "ulog_in.h" #include "sev_sched.h" #define FILTER_CONTENT ":msg,contains,\""MODULE_FMT"\"\n" #define DEFAULT_CONFIG_FILE_TMP "/etc/log-sched.conf.tmp" static int copy_file(const char *src, const char *dst) { //return -1; int ret = -1; FILE *src_fp = NULL,*dst_fp = NULL; src_fp = fopen(src, "r"); if (src_fp == NULL) { ULOG_ERR(g_log, "Opening src file:%s is failure:%s", src, strerror(errno)); goto END; } dst_fp = fopen(dst, "w"); if (dst_fp == NULL) { ULOG_ERR(g_log, "Opening dst file:%s is failure:%s", src, strerror(errno)); goto END; } char buff[1024]; int len; int n; while((len = fread(buff, 1, sizeof(buff), src_fp)) > 0) { n = fwrite(buff, 1, len ,dst_fp); if (n != len) { ULOG_ERR(g_log, "Configure file which is written[length:%d, actual len:%n] is failure:%s", n, len, strerror(errno)); goto END; } if (feof(src_fp) == 0) { break; } } ret = 0; END: if (src_fp != NULL) { fclose(src_fp); } if (dst_fp != NULL) { fclose(dst_fp); } return ret; } static int __log_conf(const char *mode, const u8 level, const char *conf_path, const char *conf_file, const char *filter_mod, int (*cb_content)(FILE *fp, const u8 level, const char *filter_mod, void *arg), void *arg) { FILE *fp = NULL; int ret = -1; u8 exist_backup = 1; /********** rsyslog configure **********/ char conf_path_file[MAX_PATH_SZ], bak_file[MAX_PATH_SZ]; snprintf(conf_path_file, sizeof(conf_path_file), "%s%s", conf_path, conf_file); snprintf(bak_file, sizeof(bak_file), BAK_FILE, conf_file); //if (rename(conf_path_file, bak_file) < 0) { if (copy_file(conf_path_file, bak_file) != 0) { if (errno == ENOENT) { exist_backup = 0; ULOG_INFO(g_log, "Been not exist, Configure file:%s don't need to backup", conf_path_file); } else { ULOG_ERR(g_log, "Baking configure file:%s is failure:%s", conf_path_file, strerror(errno)); return ret; } } fp = fopen(conf_path_file, mode); if (fp == NULL) { ULOG_ERR(g_log, "Opening log configure file:%s is failure:%s", conf_path_file, strerror(errno)); goto END; } ULOG_DEBUG(g_log, "cb_content:%x", cb_content); if (cb_content(fp, level, filter_mod, arg) != 0) { ULOG_ERR(g_log, "Callback log content is failure"); goto END; } ret = 0; END: if (fp != NULL) { fclose(fp); } if (exist_backup == 1) { if (ret == -1) { // 恢复备份配置 if (rename(bak_file, conf_path_file) < 0) { ULOG_ERR(g_log, "Restoring configure file:%s is failure:%s", conf_path_file, strerror(errno)); } } else { if (unlink(bak_file) < 0) { ULOG_WARNING(g_log, "Delete back file:%s is failure", bak_file); } } } return ret; } int log_conf(const u8 level, const char *conf_path, const char *conf_file, const char *filter_mod, int (*cb_content)(FILE *fp, const u8 level, const char *filter_mod, void *arg), void *arg) { return __log_conf("w", level, conf_path, conf_file, filter_mod, cb_content, arg); } int log_conf_append(const u8 level, const char *conf_path, const char *conf_file, const char *filter_mod, int (*cb_content)(FILE *fp, const u8 level, const char *filter_mod, void *arg), void *arg) { return __log_conf("a", level, conf_path, conf_file, filter_mod, cb_content, arg); } int log_level_to_str(const u8 level, char *str, u32 len) { u8 i; char tmp[20]; for (i = 0; i <= level;) { if (snprintf(tmp, sizeof(tmp), "*.=%s", g_level_array[i].str) < 0) { ULOG_ERR(g_log, "Setting content of log file configure is failure"); return -1; } strcat(str, tmp); i++; if (level >= i) { strcat(str, ";"); } } return 0; } int write_conf_content(FILE *fp, const u8 level, const char *filter_mod, void *arg) { int i; int ret = -1; char line[MAX_LINE_SZ + 100] = {0}; ULOG_DEBUG(g_log, "filter module:%s\n", filter_mod); if ((filter_mod != NULL) && (strlen(filter_mod) > 0)) { snprintf(line, sizeof(line), FILTER_CONTENT, filter_mod); if (fputs(line, fp) == EOF) { ULOG_ERR(g_log, "Message filter:%s of configure file which is written is failure:%s", filter_mod, strerror(errno)); goto END; } } line[0] = '\0'; // 清零 if (log_level_to_str(level, line, sizeof(line)) != 0) { ULOG_ERR(g_log, "Setting content of log file configure is failure"); goto END; } strcat(line, REDIRECT_SEPERATE); strcat(line, (const char *)arg); strcat(line, "\n"); //if (fputs(line, fp) == EOF) { int n = fwrite(line, 1, strlen(line), fp); if (n != strlen(line)) { ULOG_ERR(g_log, "Configure file which is written[length:%d] is failure:%s", n, strerror(errno)); goto END; } ret = 0; END: return ret; } int modify_authorizing(const char *redirect_path) { if (chmod(redirect_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) { ULOG_ERR(g_log, "Authorizing of %s which is modified is failure:%s", redirect_path, strerror(errno)); return -1; } return 0; } int write_conf_content_authorizing(FILE *fp, const u8 level, const char *filter_mod, void *arg) { if (write_conf_content(fp, level, filter_mod, arg) != 0) { ULOG_ERR(g_log, "configure of log conosle which is written is failure"); return -1; } if (modify_authorizing((const char *)arg) != 0) { ULOG_ERR(g_log, "Modifying authorizing of %s is failure", (const char *)arg); return -1; } return 0; } int log_off_with_file(const char *path, const char *file_name) { char file[MAX_PATH_SZ]; int ret = -1; if (snprintf(file, sizeof(file), "%s%s", path, file_name) < 0) { ULOG_ERR(g_log, "Setting file path(dir:%s, file:%s) is failure", path, file_name); return ret; } if (unlink(file) < 0) { if (errno != ENOENT) { ULOG_ERR(g_log, "Deleting configure file(dir:%s, file:%s) is failure:%s", path, file_name, strerror(errno)); return ret; } else { ULOG_DEBUG(g_log, "File(dir:%s, file:%s) is not exist", path, file_name); } } ret = 0; return ret; } void rpc_conf_proc(rpc_conn *conn, pointer input, int input_len, int need_len, rpc_cb cb, void *arg) { char str_err[1024]; if (input == NULL) { strncpy(str_err, "Input is not null", sizeof(str_err)); ULOG_WARNING(g_log, str_err); goto FAIL; } if (input_len < need_len) { if (snprintf(str_err, sizeof(str_err), "The input paramter of rpc log is needed length of %u, but the actual length is %u", need_len, input_len) < 0) { strncpy(str_err, "Setting error message is failure", sizeof(str_err)); ULOG_ERR(g_log, str_err); } else { ULOG_WARNING(g_log, str_err); } goto FAIL; } // ret == 1,不需要重启服务;ret == 0,需要重启服务 int ret = cb(input, arg, str_err, sizeof(str_err)); if (ret < 0) { ULOG_ERR(g_log, str_err); goto FAIL; } if ((ret == 0) && (log_sev_restart() != 0)) { if (snprintf(str_err, sizeof(str_err), "Restarting log service is failure") < 0) { strncpy(str_err, "Setting error message is failure", sizeof(str_err)); ULOG_ERR(g_log, str_err); } goto FAIL; } rpc_return_null(conn); return; FAIL: rpc_return_error(conn, RET_ERR, str_err); } /* 写配置到配置文件。追加在配置文件最后 */ int write_log_file_conf(const char *p_key_str, const char *p_value_str) { char conf_value_str[MAX_LINE_SZ] = ""; char buffer[MAX_LINE_SZ] = ""; char *p_pos = NULL; int is_exist = 0; FILE *tmp_conf_fp = NULL; if (NULL == p_key_str || '\0' == p_key_str[0] || NULL == p_value_str) { ULOG_ERR(g_log, "Bad input"); return -1; } /* 定位到起始位置 */ if (fseek(g_conf_fp, 0, SEEK_SET) == -1) { ULOG_ERR(g_log, "Seeknig config to begin is faiure:%s", strerror(errno)); return -1; } /* 查看配置是否已存在 */ while (fgets(buffer,MAX_LINE_SZ,g_conf_fp)!=NULL) { p_pos = strstr(buffer, p_key_str); if (p_pos != NULL) { memset(conf_value_str, 0, sizeof(conf_value_str)); strcpy(conf_value_str, p_pos+strlen(p_key_str)); is_exist = 1; break; } } if (is_exist == 1) { /* 判断已有配置是否与当前传入配置相同 */ if (strlen(conf_value_str) == strlen(p_value_str) && 0 == strcmp(conf_value_str, p_value_str)) { /* 无需做任何变更,本函数返回 */ return 0; } /* 定位到起始位置 */ if (fseek(g_conf_fp, 0, SEEK_SET) == -1) { ULOG_ERR(g_log, "Seeknig config to begin is faiure:%s", strerror(errno)); return -1; } /* 打开临时文件 */ tmp_conf_fp = fopen(DEFAULT_CONFIG_FILE_TMP, "w+"); if (NULL == tmp_conf_fp){ ULOG_ERR(g_log, "Open temp config file failed: %s", strerror(errno)); return -1; } /* 将原文件内容写入临时文件,但跳过当前配置相关项 */ while (fgets(buffer,MAX_LINE_SZ,g_conf_fp)!=NULL) { if (strstr(buffer, p_key_str) != NULL) { continue; } fputs(buffer,tmp_conf_fp); } fflush(tmp_conf_fp); /* 将临时文件写回原配置文件 */ truncate(g_conf_file, 0); // fclose(g_conf_fp); // g_conf_fp = fopen(g_conf_file, "w+"); if (fseek(g_conf_fp, 0, SEEK_SET) == -1) { ULOG_ERR(g_log, "Seeknig config to begin is faiure:%s", strerror(errno)); return -1; } if (fseek(tmp_conf_fp, 0, SEEK_SET) == -1) { ULOG_ERR(g_log, "Seeknig config to begin is faiure:%s", strerror(errno)); return -1; } while (fgets(buffer,MAX_LINE_SZ,tmp_conf_fp)!=NULL) { fputs(buffer,g_conf_fp); } fflush(g_conf_fp); /* 关闭临时文件 */ fclose(tmp_conf_fp); tmp_conf_fp = NULL; } else { /* 定位到结束位置 */ if (fseek(g_conf_fp, 0, SEEK_END) == -1) { ULOG_ERR(g_log, "Seeknig config to end is faiure:%s", strerror(errno)); return -1; } } /* 向配置文件中追加配置项 */ char fmt[MAX_LINE_SZ]=""; snprintf(fmt, sizeof(fmt), "%s=%s\n", p_key_str, p_value_str); ULOG_DEBUG(g_log, "Configure content is %s", fmt); int len = strlen(fmt); int n = fwrite(fmt, 1, len, g_conf_fp); if (len != n) { ULOG_ERR(g_log, "Writing conf is failure:%s", strerror(errno)); return -1; } fflush(g_conf_fp); return 0; } int get_log_file_conf(const char *key_str, char *value_str, int value_len) { int ret = -1; if (fseek(g_conf_fp, 0, SEEK_SET) == -1) { ULOG_ERR(g_log, "Seeknig config to begin is faiure:%s", strerror(errno)); return ret; } ssize_t n, n1, n2; char *line = NULL; char tmp_key[MAX_LINE_SZ], tmp_value[MAX_LINE_SZ]; while ((n1 = getline(&line, &n, g_conf_fp)) != -1) { ULOG_DEBUG(g_log, "config file line:%s", line); n2 = sscanf(line, "%s=%s", tmp_key, tmp_value); if (n2 == 1) { if (strcmp(tmp_key, key_str) == 0) { strncpy(value_str, tmp_value, value_len); ret = 0; break; } } else if (n2 == EOF) { ULOG_ERR(g_log, "Parsing level from configure is failure:%s", strerror(errno)); break; } else { ULOG_DEBUG(g_log, "Unknown row:%s", line); } } return ret; }