📄 misdn_config.c
字号:
#define CLI_ERROR(name, value, section) ({ \ ast_log(LOG_WARNING, "misdn.conf: \"%s=%s\" (section: %s) invalid or out of range. " \ "Please edit your misdn.conf and then do a \"misdn reload\".\n", name, value, section); \})static int _enum_array_map (void){ int i, j, ok; for (i = MISDN_CFG_FIRST + 1; i < MISDN_CFG_LAST; ++i) { if (i == MISDN_CFG_PTP) continue; ok = 0; for (j = 0; j < NUM_PORT_ELEMENTS; ++j) { if (port_spec[j].elem == i) { map[i] = j; ok = 1; break; } } if (!ok) { ast_log(LOG_WARNING, "Enum element %d in misdn_cfg_elements (port section) has no corresponding element in the config struct!\n", i); return -1; } } for (i = MISDN_GEN_FIRST + 1; i < MISDN_GEN_LAST; ++i) { ok = 0; for (j = 0; j < NUM_GEN_ELEMENTS; ++j) { if (gen_spec[j].elem == i) { map[i] = j; ok = 1; break; } } if (!ok) { ast_log(LOG_WARNING, "Enum element %d in misdn_cfg_elements (general section) has no corresponding element in the config struct!\n", i); return -1; } } return 0;}static int get_cfg_position (char *name, int type){ int i; switch (type) { case PORT_CFG: for (i = 0; i < NUM_PORT_ELEMENTS; ++i) { if (!strcasecmp(name, port_spec[i].name)) return i; } break; case GEN_CFG: for (i = 0; i < NUM_GEN_ELEMENTS; ++i) { if (!strcasecmp(name, gen_spec[i].name)) return i; } } return -1;}static inline void misdn_cfg_lock (void){ ast_mutex_lock(&config_mutex);}static inline void misdn_cfg_unlock (void){ ast_mutex_unlock(&config_mutex);}static void _free_msn_list (struct msn_list* iter){ if (iter->next) _free_msn_list(iter->next); if (iter->msn) free(iter->msn); free(iter);}static void _free_port_cfg (void){ int i, j; int gn = map[MISDN_CFG_GROUPNAME]; union misdn_cfg_pt* free_list[max_ports + 2]; memset(free_list, 0, sizeof(free_list)); free_list[0] = port_cfg[0]; for (i = 1; i <= max_ports; ++i) { if (port_cfg[i][gn].str) { /* we always have a groupname in the non-default case, so this is fine */ for (j = 1; j <= max_ports; ++j) { if (free_list[j] && free_list[j][gn].str == port_cfg[i][gn].str) break; else if (!free_list[j]) { free_list[j] = port_cfg[i]; break; } } } } for (j = 0; free_list[j]; ++j) { for (i = 0; i < NUM_PORT_ELEMENTS; ++i) { if (free_list[j][i].any) { if (port_spec[i].type == MISDN_CTYPE_MSNLIST) _free_msn_list(free_list[j][i].ml); else free(free_list[j][i].any); } } }}static void _free_general_cfg (void){ int i; for (i = 0; i < NUM_GEN_ELEMENTS; i++) if (general_cfg[i].any) free(general_cfg[i].any);}void misdn_cfg_get (int port, enum misdn_cfg_elements elem, void *buf, int bufsize){ int place; if ((elem < MISDN_CFG_LAST) && !misdn_cfg_is_port_valid(port)) { memset(buf, 0, bufsize); ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get! Port number %d is not valid.\n", port); return; } misdn_cfg_lock(); if (elem == MISDN_CFG_PTP) { if (!memcpy(buf, &ptp[port], (bufsize > ptp[port]) ? sizeof(ptp[port]) : bufsize)) memset(buf, 0, bufsize); } else { if ((place = map[elem]) < 0) { memset (buf, 0, bufsize); ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get! Invalid element (%d) requested.\n", elem); } else { if (elem < MISDN_CFG_LAST) { switch (port_spec[place].type) { case MISDN_CTYPE_STR: if (port_cfg[port][place].str) { if (!memccpy(buf, port_cfg[port][place].str, 0, bufsize)) memset(buf, 0, 1); } else if (port_cfg[0][place].str) { if (!memccpy(buf, port_cfg[0][place].str, 0, bufsize)) memset(buf, 0, 1); } else memset(buf, 0, bufsize); break; default: if (port_cfg[port][place].any) memcpy(buf, port_cfg[port][place].any, bufsize); else if (port_cfg[0][place].any) memcpy(buf, port_cfg[0][place].any, bufsize); else memset(buf, 0, bufsize); } } else { switch (gen_spec[place].type) { case MISDN_CTYPE_STR: if (!general_cfg[place].str || !memccpy(buf, general_cfg[place].str, 0, bufsize)) memset(buf, 0, 1); break; default: if (general_cfg[place].any) memcpy(buf, general_cfg[place].any, bufsize); else memset(buf, 0, bufsize); } } } } misdn_cfg_unlock();}enum misdn_cfg_elements misdn_cfg_get_elem (char *name){ int pos; /* here comes a hack to replace the (not existing) "name" element with the "ports" element */ if (!strcmp(name, "ports")) return MISDN_CFG_GROUPNAME; if (!strcmp(name, "name")) return MISDN_CFG_FIRST; pos = get_cfg_position (name, PORT_CFG); if (pos >= 0) return port_spec[pos].elem; pos = get_cfg_position (name, GEN_CFG); if (pos >= 0) return gen_spec[pos].elem; return MISDN_CFG_FIRST;}void misdn_cfg_get_name (enum misdn_cfg_elements elem, void *buf, int bufsize){ struct misdn_cfg_spec *spec = NULL; int place = map[elem]; /* the ptp hack */ if (elem == MISDN_CFG_PTP) { memset(buf, 0, 1); return; } /* here comes a hack to replace the (not existing) "name" element with the "ports" element */ if (elem == MISDN_CFG_GROUPNAME) { if (!snprintf(buf, bufsize, "ports")) memset(buf, 0, 1); return; } if ((elem > MISDN_CFG_FIRST) && (elem < MISDN_CFG_LAST)) spec = (struct misdn_cfg_spec *)port_spec; else if ((elem > MISDN_GEN_FIRST) && (elem < MISDN_GEN_LAST)) spec = (struct misdn_cfg_spec *)gen_spec; if (!spec || !memccpy(buf, spec[place].name, 0, bufsize)) memset(buf, 0, 1);}void misdn_cfg_get_desc (enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default){ int place = map[elem]; struct misdn_cfg_spec *spec = NULL; /* here comes a hack to replace the (not existing) "name" element with the "ports" element */ if (elem == MISDN_CFG_GROUPNAME) { if (!memccpy(buf, ports_description, 0, bufsize)) memset(buf, 0, 1); if (buf_default && bufsize_default) memset(buf_default, 0, 1); return; } if ((elem > MISDN_CFG_FIRST) && (elem < MISDN_CFG_LAST)) spec = (struct misdn_cfg_spec *)port_spec; else if ((elem > MISDN_GEN_FIRST) && (elem < MISDN_GEN_LAST)) spec = (struct misdn_cfg_spec *)gen_spec; if (!spec || !spec[place].desc) memset(buf, 0, 1); else { if (!memccpy(buf, spec[place].desc, 0, bufsize)) memset(buf, 0, 1); if (buf_default && bufsize) { if (!strcmp(spec[place].def, NO_DEFAULT)) memset(buf_default, 0, 1); else if (!memccpy(buf_default, spec[place].def, 0, bufsize_default)) memset(buf_default, 0, 1); } }}int misdn_cfg_is_msn_valid (int port, char* msn){ int re = 0; struct msn_list *iter; if (!misdn_cfg_is_port_valid(port)) { ast_log(LOG_WARNING, "Invalid call to misdn_cfg_is_msn_valid! Port number %d is not valid.\n", port); return 0; } misdn_cfg_lock(); if (port_cfg[port][map[MISDN_CFG_MSNS]].ml) iter = port_cfg[port][map[MISDN_CFG_MSNS]].ml; else iter = port_cfg[0][map[MISDN_CFG_MSNS]].ml; for (; iter; iter = iter->next) if (*(iter->msn) == '*' || ast_extension_match(iter->msn, msn)) { re = 1; break; } misdn_cfg_unlock(); return re;}int misdn_cfg_is_port_valid (int port){ int gn = map[MISDN_CFG_GROUPNAME]; return (port >= 1 && port <= max_ports && port_cfg[port][gn].str);}int misdn_cfg_is_group_method (char *group, enum misdn_cfg_method meth){ int i, re = 0; char *method ; misdn_cfg_lock(); method = port_cfg[0][map[MISDN_CFG_METHOD]].str; for (i = 1; i <= max_ports; i++) { if (port_cfg[i] && port_cfg[i][map[MISDN_CFG_GROUPNAME]].str) { if (!strcasecmp(port_cfg[i][map[MISDN_CFG_GROUPNAME]].str, group)) method = (port_cfg[i][map[MISDN_CFG_METHOD]].str ? port_cfg[i][map[MISDN_CFG_METHOD]].str : port_cfg[0][map[MISDN_CFG_METHOD]].str); } } if (method) { switch (meth) { case METHOD_STANDARD: re = !strcasecmp(method, "standard"); break; case METHOD_ROUND_ROBIN: re = !strcasecmp(method, "round_robin"); break; case METHOD_STANDARD_DEC: re = !strcasecmp(method, "standard_dec"); break; } } misdn_cfg_unlock(); return re;}/*! * \brief Generate a comma separated list of all active ports */void misdn_cfg_get_ports_string (char *ports){ char tmp[16]; int l, i; int gn = map[MISDN_CFG_GROUPNAME]; *ports = 0; misdn_cfg_lock(); for (i = 1; i <= max_ports; i++) { if (port_cfg[i][gn].str) { if (ptp[i]) sprintf(tmp, "%dptp,", i); else sprintf(tmp, "%d,", i); strcat(ports, tmp); } } misdn_cfg_unlock(); if ((l = strlen(ports))) { /* Strip trailing ',' */ ports[l-1] = 0; }}void misdn_cfg_get_config_string (int port, enum misdn_cfg_elements elem, char* buf, int bufsize){ int place; char tempbuf[BUFFERSIZE] = ""; struct msn_list *iter; if ((elem < MISDN_CFG_LAST) && !misdn_cfg_is_port_valid(port)) { *buf = 0; ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get_config_string! Port number %d is not valid.\n", port); return; } place = map[elem]; misdn_cfg_lock(); if (elem == MISDN_CFG_PTP) { snprintf(buf, bufsize, " -> ptp: %s", ptp[port] ? "yes" : "no"); } else if (elem > MISDN_CFG_FIRST && elem < MISDN_CFG_LAST) { switch (port_spec[place].type) { case MISDN_CTYPE_INT: case MISDN_CTYPE_BOOLINT: if (port_cfg[port][place].num) snprintf(buf, bufsize, " -> %s: %d", port_spec[place].name, *port_cfg[port][place].num); else if (port_cfg[0][place].num) snprintf(buf, bufsize, " -> %s: %d", port_spec[place].name, *port_cfg[0][place].num); else snprintf(buf, bufsize, " -> %s:", port_spec[place].name); break; case MISDN_CTYPE_BOOL: if (port_cfg[port][place].num)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -