// // Created by xajhu on 2019/11/18 0018. // #include #include #include #include #include #include #include #include #include "common.h" #include "log.h" #include "err_code.h" #include "config.h" static char *g_ztpFilePath = NULL; static config_t g_ztpCfg; static pthread_t g_monThreadId; static ZTP_CONFIG g_ztpInfo; int reload_ztp_config(const char *pPath) { ZTP_CONFIG ztpInfo; memset(&ztpInfo, 0, sizeof(ZTP_CONFIG)); if(config_read_file(&g_ztpCfg, pPath) != CONFIG_TRUE) { LOG_EX(LOG_Error, "Read ztp configre file %s error %s at %d\n", pPath, config_error_text(&g_ztpCfg), config_error_file(&g_ztpCfg)); config_destroy(&g_ztpCfg); return -ERR_READFILE; } ztpInfo.svr_cfg.port = cfg_get_int_value("ztp.server.port", 10000); strncpy(ztpInfo.svr_cfg.server_url, cfg_get_string_value("ztp.server.domain", ""), MAX_PATH * 2 - 1); strncpy(ztpInfo.dev_dir, cfg_get_string_value("ztp.dev_dir", DEVICE_ZTP_PATH), MAX_PATH - 1); if(g_ztpInfo.svr_cfg.port != ztpInfo.svr_cfg.port) { LOG_EX(LOG_Info, "Port Changed: [%d] --> [%d]\n", g_ztpInfo.svr_cfg.port, ztpInfo.svr_cfg.port); g_ztpInfo.svr_cfg.port = ztpInfo.svr_cfg.port; } if(strcmp(g_ztpInfo.svr_cfg.server_url, ztpInfo.svr_cfg.server_url) != 0) { LOG_EX(LOG_Info, "Url Changed: [%s] --> [%s]\n", g_ztpInfo.svr_cfg.server_url, ztpInfo.svr_cfg.server_url); memset(g_ztpInfo.svr_cfg.server_url, 0, MAX_PATH * 2); strncpy(g_ztpInfo.svr_cfg.server_url, ztpInfo.svr_cfg.server_url, MAX_PATH * 2 - 1); } if(strcmp(g_ztpInfo.dev_dir, ztpInfo.dev_dir) != 0) { LOG_EX(LOG_Info, "Device Changed: [%s] --> [%s]\n", g_ztpInfo.dev_dir, ztpInfo.dev_dir); memset(g_ztpInfo.dev_dir, 0, MAX_PATH); strncpy(g_ztpInfo.dev_dir, ztpInfo.dev_dir, MAX_PATH - 1); } return ERR_OK; } static void *__cfg_file_monitor(void *p) { int wd; int fd = inotify_init(); if(fd == -1) { LOG_EX(LOG_Error, "Create file watch error: %s\n", strerror(errno)); return NULL; } wd = inotify_add_watch(fd, g_ztpFilePath, (IN_CREATE + IN_DELETE + IN_MODIFY + IN_MOVED_FROM + IN_MOVED_TO)); if(wd < 0) { LOG_EX(LOG_Error, "Watch %s error %s\n", g_ztpFilePath, strerror(errno)); close(fd); free(g_ztpFilePath); return NULL; } while(g_ztpFilePath && strlen(g_ztpFilePath) > 0) { unsigned char buf[MAX_PATH]; struct inotify_event *event = NULL; fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); memset(buf, 0, MAX_PATH); if(select(fd + 1, &fds, NULL, NULL, NULL) > 0) { unsigned int len, index = 0; while(((len = read(fd, &buf, sizeof(buf))) < 0) && (errno == EINTR)); //没有读取到事件。 while(index < len) { event = (struct inotify_event *)(buf + index); //LOG_EX(LOG_Info, "event->mask: 0x%08x\n", event->mask); switch(event->mask) { case IN_MODIFY: case IN_MOVED_FROM: reload_ztp_config(g_ztpFilePath); break; case IN_MOVED_TO: case IN_DELETE: case IN_CREATE: config_destroy(&g_ztpCfg); break; } //获取事件。 index += sizeof(struct inotify_event) + event->len; //移动index指向下一个事件。 } } } inotify_rm_watch(fd, wd); free(g_ztpFilePath); pthread_detach(pthread_self()); } int init_configure(const char *pPath) { memset(&g_ztpInfo, 0, sizeof(ZTP_CONFIG)); if(!pPath || strlen(pPath) == 0) { LOG_EX(LOG_Warn, "Load default ztp configure file: %s\n", DEVICE_ZTP_PATH); pPath = DEVICE_ZTP_PATH; } else { LOG_EX(LOG_Debug, "Load ztp configure file: %s\n", pPath); } if(access(pPath, F_OK) != 0) { LOG_EX(LOG_Error, "Configure file %s not exists\n", pPath); return -ERR_NOTFOUND; } config_init(&g_ztpCfg); config_set_tab_width(&g_ztpCfg, 4u); g_ztpFilePath = strdup(pPath); reload_ztp_config(g_ztpFilePath); pthread_create(&g_monThreadId, NULL, __cfg_file_monitor, &g_ztpCfg); return ERR_OK; } char *cfg_get_string_value(const char *pTags, char *pDefValue) { char *pValue = pDefValue; if(pTags == NULL || strlen(pTags) == 0) { return pDefValue; } if(config_lookup_string(&g_ztpCfg, pTags, (const char **)&pValue) != CONFIG_TRUE) { return pDefValue; } return pValue; } int cfg_get_int_value(const char *pTags, int defValue) { int iValue = defValue; if(pTags == NULL || strlen(pTags) == 0) { return defValue; } if(config_lookup_int(&g_ztpCfg, pTags, &iValue) != CONFIG_TRUE) { return defValue; } return iValue; } double cfg_get_float_value(const char *pTags, double defValue) { double dValue = defValue; if(pTags == NULL || strlen(pTags) == 0) { return defValue; } if(config_lookup_float(&g_ztpCfg, pTags, &dValue) != CONFIG_TRUE) { return defValue; } return dValue; } int cfg_get_bool_value(const char *pTags, int defValue) { int iValue = defValue; if(pTags == NULL || strlen(pTags) == 0) { return defValue; } if(config_lookup_bool(&g_ztpCfg, pTags, &iValue) != CONFIG_TRUE) { return defValue; } return iValue; }