Yu.Ding 5 月之前
當前提交
8f62f1dca4
共有 17 個文件被更改,包括 7722 次插入0 次删除
  1. 380 0
      ast_init.c
  2. 380 0
      ast_init_raspberrypi.c
  3. 18 0
      createlicense.sh
  4. 176 0
      discover.c
  5. 696 0
      extension_gen.bak.c
  6. 697 0
      extension_gen.c
  7. 337 0
      fail2ban_conf.c
  8. 333 0
      fail2ban_init.c
  9. 321 0
      fail2ban_rule.bak.c
  10. 292 0
      fail2ban_rule.c
  11. 475 0
      generate_context_conf.c
  12. 888 0
      generate_extension_conf.c
  13. 454 0
      generate_group_conf.c
  14. 380 0
      generate_group_conf.c.acorp
  15. 378 0
      generate_group_conf1.c
  16. 1136 0
      generate_trunk_conf.c
  17. 381 0
      generate_user_conf.c

+ 380 - 0
ast_init.c

@@ -0,0 +1,380 @@
+/*
+============================================================================
+Name        : ast_init
+Author      : dy
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : set init info to mysql and redis
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <time.h>
+#include <ctype.h>
+#include <mysql/mysql.h>
+#include "hiredis/hiredis.h"
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql 记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define KEYVALLEN 100
+#define MAX 65534
+#define VERSION "V1.0.1"
+#define RESET_FILE "/init/sql/.DS_Store"
+
+char uuid[64] = {0};
+long Timestamp;
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE] = "root";
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE] = "init_db";
+char sql_tmp[MIDLE_SIZE];
+const unsigned int g_db_port = 3306;
+
+void mytime(){
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    Timestamp = tv.tv_sec + 45*24*60*60;
+}
+
+void get_uuid(){
+    FILE *fp;
+    memset(uuid,'\0',sizeof(uuid));
+    fp=popen("dmidecode -s system-uuid | sed '/^#/d' | head -n 1","r");
+    fgets(uuid,sizeof(uuid),fp);
+    if (uuid[strlen(uuid) - 1] == '\n')
+    {
+        uuid[strlen(uuid) - 1] = '\0';
+    }
+    pclose(fp);
+}
+
+/*初始化函数*/
+void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
+{
+    int i = 0, j = 0;
+    char k[256] = { 0 };
+    unsigned char tmp = 0;
+    for (i = 0; i<256; i++)
+    {
+        s[i] = i;
+        k[i] = key[i%Len];
+    }
+    for (i = 0; i<256; i++)
+    {
+        j = (j + s[i] + k[i]) % 256;
+        tmp = s[i];
+        s[i] = s[j];//交换s[i]和s[j]
+        s[j] = tmp;
+    }
+}
+ 
+/*加解密*/
+void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
+{
+    int i = 0, j = 0, t = 0;
+    unsigned long k = 0;
+    unsigned char tmp;
+    for (k = 0; k<Len; k++)
+    {
+        i = (i + 1) % 256;
+        j = (j + s[i]) % 256;
+        tmp = s[i];
+        s[i] = s[j];//交换s[x]和s[y]
+        s[j] = tmp;
+        t = (s[i] + s[j]) % 256;
+        Data[k] ^= s[t];
+    }
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+unsigned char *base64_encode(unsigned char *str)  
+{  
+    long len;  
+    long str_len;  
+    unsigned char *res;  
+    int i,j;  
+//定义base64编码表  
+    unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
+  
+//计算经过base64编码后的字符串长度  
+    str_len=strlen(str);  
+    if(str_len % 3 == 0)
+        len=str_len/3*4;  
+    else  
+        len=(str_len/3+1)*4;  
+  
+    res=malloc(sizeof(unsigned char)*len+1);  
+    res[len]='\0';  
+  
+//以3个8位字符为一组进行编码  
+    for(i=0,j=0;i<len-2;j+=3,i+=4)  
+    {  
+        res[i]=base64_table[str[j]>>2]; //取出第一个字符的前6位并找出对应的结果字符  
+        res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符  
+        res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符  
+        res[i+3]=base64_table[str[j+2]&0x3f]; //取出第三个字符的后6位并找出结果字符  
+    }  
+  
+    switch(str_len % 3)  
+    {  
+        case 1:  
+            res[i-2]='=';  
+            res[i-1]='=';  
+            break;  
+        case 2:  
+            res[i-1]='=';  
+            break;  
+    }  
+  
+    return res;  
+}
+
+unsigned char *base64_decode(unsigned char *code)  
+{  
+//根据base64表,以字符找到对应的十进制数据  
+    int table[]={0,0,0,0,0,0,0,0,0,0,0,0,
+    		 0,0,0,0,0,0,0,0,0,0,0,0,
+    		 0,0,0,0,0,0,0,0,0,0,0,0,
+    		 0,0,0,0,0,0,0,62,0,0,0,
+    		 63,52,53,54,55,56,57,58,
+    		 59,60,61,0,0,0,0,0,0,0,0,
+    		 1,2,3,4,5,6,7,8,9,10,11,12,
+    		 13,14,15,16,17,18,19,20,21,
+    		 22,23,24,25,0,0,0,0,0,0,26,
+    		 27,28,29,30,31,32,33,34,35,
+    		 36,37,38,39,40,41,42,43,44,
+    		 45,46,47,48,49,50,51
+    	       };  
+    long len;  
+    long str_len;  
+    unsigned char *res;  
+    int i,j;  
+  
+//计算解码后的字符串长度  
+    len=strlen(code);  
+//判断编码后的字符串后是否有=  
+    if(strstr(code,"=="))  
+        str_len=len/4*3-2;  
+    else if(strstr(code,"="))  
+        str_len=len/4*3-1;  
+    else  
+        str_len=len/4*3;  
+  
+    res=malloc(sizeof(unsigned char)*str_len+1);  
+    res[str_len]='\0';  
+  
+//以4个字符为一位进行解码  
+    for(i=0,j=0;i < len-2;j+=3,i+=4)  
+    {  
+        res[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合  
+        res[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合  
+        res[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合  
+    }  
+  
+    return res;  
+  
+}
+
+int main(int argc, char **argv) {
+    FILE *fp;
+    unsigned char s[256];//S-box
+    unsigned char key[128];
+    unsigned char pData[64];
+    int i;
+    int reset_exist = 0;
+    unsigned long len = 10;
+    long timestamp_tmp;
+
+    memset(key,0,sizeof(key));
+    memset(pData,0,sizeof(pData));
+    memset(s,0,sizeof(s));
+    get_uuid();
+    mytime();
+    sprintf(key,"8051dt%s6924szl",uuid);
+    //如果数据库为空将日期时间戳加密后写入mysql数据库,否则读取时间
+    strcpy(g_host_name,getenv("MYSQL"));
+    strcpy(g_password,getenv("MYSQL_ROOT_PASSWORD"));
+
+    if (init_mysql()){              //连接数据库
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select * from D_T_S_Z_L where prop_key='SYSTEM_UUID'");
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    g_res = mysql_store_result(g_conn); 
+    if(mysql_num_rows(g_res) == 0){
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('SYSTEM_UUID','%s')",uuid);  //写入UUID
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+    }
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select * from D_T_S_Z_L where prop_key='LIMITED_DATETIME'");
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    g_res = mysql_store_result(g_conn); 
+    
+    fp = fopen(RESET_FILE, "r");
+    if(fp != NULL){
+        reset_exist = 1;
+        fclose(fp);
+    }
+
+    if(mysql_num_rows(g_res) == 0 && reset_exist == 0){
+        sprintf(pData,"%ld",Timestamp);
+
+        len = strlen(pData);
+        printf("pData is %s, length: %ld\n",pData,len);
+        rc4_init(s, (unsigned char*)key, (unsigned long)strlen(key));//已经完成了初始化
+        rc4_crypt(s, (unsigned char*)pData, len);//加密
+        printf("pData2 is %s, length: %ld\n",pData,strlen(pData));
+
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('LIMITED_DATETIME','%s')",base64_encode(pData));  //base64后写入数据库
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+        fp = fopen(RESET_FILE, "w");
+        fprintf(fp, " ");
+        fclose(fp);
+    }
+    else if(mysql_num_rows(g_res) != 0)
+    {
+        g_row=mysql_fetch_row(g_res);
+
+		if(g_row[2] == NULL){
+			mysql_free_result(g_res); //释放结果
+			mysql_close(g_conn); // 关闭链接
+			return 0;
+		}
+        strcpy(pData,base64_decode((unsigned char *) g_row[2]));
+		rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
+		rc4_crypt(s, (unsigned char*)pData, len);//解密
+        timestamp_tmp = atol(pData);
+        if(Timestamp >= timestamp_tmp){
+            Timestamp = timestamp_tmp;
+        }else{
+            sprintf(pData,"%ld",Timestamp);
+
+            len = strlen(pData);
+            rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
+            rc4_crypt(s, (unsigned char*)pData, len);//加密
+
+            memset(sql_tmp,0,sizeof(sql_tmp));
+            sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('LIMITED_DATETIME','%s')",base64_encode(pData));  //base64后写入数据库
+            if (executesql(sql_tmp)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            fp = fopen(RESET_FILE, "w");
+            fprintf(fp, " ");
+            fclose(fp);
+        }
+    }
+    else
+    {
+        return 0;
+    }
+    
+    //将数据写入redis数据库
+    char *redis_host = getenv("REDIS");
+    char *redis_password = getenv("REDIS_PASSWORD");
+    unsigned int redis_port = atoi(getenv("REDIS_PORT"));
+    redisContext *c;
+    redisReply *reply;
+
+    struct timeval timeout = { 1, 500000 };
+    c = redisConnectWithTimeout(redis_host, redis_port, timeout);
+    if (c == NULL || c->err) {
+        if (c) {
+            printf("Connection error: %s\n", c->errstr);
+            redisFree(c);
+        } else {
+            printf("Connection error: can't allocate redis context\n");
+        }
+        return 0;
+    }
+
+    //数据库登录认证
+    reply = redisCommand(c, "AUTH %s", redis_password);
+    if (reply->type == REDIS_REPLY_ERROR) {
+        printf("Redis认证失败!\n");
+        freeReplyObject(reply);
+        redisFree(c);
+        return 0;
+    }
+    freeReplyObject(reply);
+
+    //选择数据库
+    reply = redisCommand(c, "SELECT 0");
+    freeReplyObject(reply);
+
+    reply = redisCommand(c,"exists SYSTEM_UUID");
+    if(reply->type == 3 && reply->integer == 0){
+        freeReplyObject(reply);
+        reply = redisCommand(c,"set SYSTEM_UUID %s",uuid);
+    }
+    freeReplyObject(reply);
+
+    reply = redisCommand(c,"exists LIMITED_DATETIME");
+    if(reply->type == 3 && reply->integer == 0){
+        freeReplyObject(reply);
+        reply = redisCommand(c,"set LIMITED_DATETIME %ld",Timestamp);
+    }
+    freeReplyObject(reply);
+        
+    redisFree(c);
+
+    mysql_free_result(g_res); //释放结果
+    mysql_close(g_conn); // 关闭链接
+}
+

+ 380 - 0
ast_init_raspberrypi.c

@@ -0,0 +1,380 @@
+/*
+============================================================================
+Name        : ast_init
+Author      : dy
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : set init info to mysql and redis
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <time.h>
+#include <ctype.h>
+#include <mysql/mysql.h>
+#include "hiredis/hiredis.h"
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql 记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define KEYVALLEN 100
+#define MAX 65534
+#define VERSION "V1.0.1"
+#define RESET_FILE "/init/sql/.DS_Store"
+
+char uuid[64] = {0};
+long Timestamp;
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE] = "root";
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE] = "init_db";
+char sql_tmp[MIDLE_SIZE];
+const unsigned int g_db_port = 3306;
+
+void mytime(){
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    Timestamp = tv.tv_sec + 45*24*60*60;
+}
+
+void get_uuid(){
+    FILE *fp;
+    memset(uuid,'\0',sizeof(uuid));
+    fp=popen("cat /proc/cpuinfo | grep 'Serial' | awk '{print $3}'","r");
+    fgets(uuid,sizeof(uuid),fp);
+    if (uuid[strlen(uuid) - 1] == '\n')
+    {
+        uuid[strlen(uuid) - 1] = '\0';
+    }
+    pclose(fp);
+}
+
+/*初始化函数*/
+void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
+{
+    int i = 0, j = 0;
+    char k[256] = { 0 };
+    unsigned char tmp = 0;
+    for (i = 0; i<256; i++)
+    {
+        s[i] = i;
+        k[i] = key[i%Len];
+    }
+    for (i = 0; i<256; i++)
+    {
+        j = (j + s[i] + k[i]) % 256;
+        tmp = s[i];
+        s[i] = s[j];//交换s[i]和s[j]
+        s[j] = tmp;
+    }
+}
+ 
+/*加解密*/
+void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
+{
+    int i = 0, j = 0, t = 0;
+    unsigned long k = 0;
+    unsigned char tmp;
+    for (k = 0; k<Len; k++)
+    {
+        i = (i + 1) % 256;
+        j = (j + s[i]) % 256;
+        tmp = s[i];
+        s[i] = s[j];//交换s[x]和s[y]
+        s[j] = tmp;
+        t = (s[i] + s[j]) % 256;
+        Data[k] ^= s[t];
+    }
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+unsigned char *base64_encode(unsigned char *str)  
+{  
+    long len;  
+    long str_len;  
+    unsigned char *res;  
+    int i,j;  
+//定义base64编码表  
+    unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
+  
+//计算经过base64编码后的字符串长度  
+    str_len=strlen(str);  
+    if(str_len % 3 == 0)
+        len=str_len/3*4;  
+    else  
+        len=(str_len/3+1)*4;  
+  
+    res=malloc(sizeof(unsigned char)*len+1);  
+    res[len]='\0';  
+  
+//以3个8位字符为一组进行编码  
+    for(i=0,j=0;i<len-2;j+=3,i+=4)  
+    {  
+        res[i]=base64_table[str[j]>>2]; //取出第一个字符的前6位并找出对应的结果字符  
+        res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符  
+        res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符  
+        res[i+3]=base64_table[str[j+2]&0x3f]; //取出第三个字符的后6位并找出结果字符  
+    }  
+  
+    switch(str_len % 3)  
+    {  
+        case 1:  
+            res[i-2]='=';  
+            res[i-1]='=';  
+            break;  
+        case 2:  
+            res[i-1]='=';  
+            break;  
+    }  
+  
+    return res;  
+}
+
+unsigned char *base64_decode(unsigned char *code)  
+{  
+//根据base64表,以字符找到对应的十进制数据  
+    int table[]={0,0,0,0,0,0,0,0,0,0,0,0,
+    		 0,0,0,0,0,0,0,0,0,0,0,0,
+    		 0,0,0,0,0,0,0,0,0,0,0,0,
+    		 0,0,0,0,0,0,0,62,0,0,0,
+    		 63,52,53,54,55,56,57,58,
+    		 59,60,61,0,0,0,0,0,0,0,0,
+    		 1,2,3,4,5,6,7,8,9,10,11,12,
+    		 13,14,15,16,17,18,19,20,21,
+    		 22,23,24,25,0,0,0,0,0,0,26,
+    		 27,28,29,30,31,32,33,34,35,
+    		 36,37,38,39,40,41,42,43,44,
+    		 45,46,47,48,49,50,51
+    	       };  
+    long len;  
+    long str_len;  
+    unsigned char *res;  
+    int i,j;  
+  
+//计算解码后的字符串长度  
+    len=strlen(code);  
+//判断编码后的字符串后是否有=  
+    if(strstr(code,"=="))  
+        str_len=len/4*3-2;  
+    else if(strstr(code,"="))  
+        str_len=len/4*3-1;  
+    else  
+        str_len=len/4*3;  
+  
+    res=malloc(sizeof(unsigned char)*str_len+1);  
+    res[str_len]='\0';  
+  
+//以4个字符为一位进行解码  
+    for(i=0,j=0;i < len-2;j+=3,i+=4)  
+    {  
+        res[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合  
+        res[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合  
+        res[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合  
+    }  
+  
+    return res;  
+  
+}
+
+int main(int argc, char **argv) {
+    FILE *fp;
+    unsigned char s[256];//S-box
+    unsigned char key[128];
+    unsigned char pData[64];
+    int i;
+    int reset_exist = 0;
+    unsigned long len = 10;
+    long timestamp_tmp;
+
+    memset(key,0,sizeof(key));
+    memset(pData,0,sizeof(pData));
+    memset(s,0,sizeof(s));
+    get_uuid();
+    mytime();
+    sprintf(key,"8051dt%s6924szl",uuid);
+    //如果数据库为空将日期时间戳加密后写入mysql数据库,否则读取时间
+    strcpy(g_host_name,getenv("MYSQL"));
+    strcpy(g_password,getenv("MYSQL_ROOT_PASSWORD"));
+
+    if (init_mysql()){              //连接数据库
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select * from D_T_S_Z_L where prop_key='SYSTEM_UUID'");
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    g_res = mysql_store_result(g_conn); 
+    if(mysql_num_rows(g_res) == 0){
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('SYSTEM_UUID','%s')",uuid);  //写入UUID
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+    }
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select * from D_T_S_Z_L where prop_key='LIMITED_DATETIME'");
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    g_res = mysql_store_result(g_conn); 
+    
+    fp = fopen(RESET_FILE, "r");
+    if(fp != NULL){
+        reset_exist = 1;
+        fclose(fp);
+    }
+
+    if(mysql_num_rows(g_res) == 0 && reset_exist == 0){
+        sprintf(pData,"%ld",Timestamp);
+
+        len = strlen(pData);
+        printf("pData is %s, length: %ld\n",pData,len);
+        rc4_init(s, (unsigned char*)key, (unsigned long)strlen(key));//已经完成了初始化
+        rc4_crypt(s, (unsigned char*)pData, len);//加密
+        printf("pData2 is %s, length: %ld\n",pData,strlen(pData));
+
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('LIMITED_DATETIME','%s')",base64_encode(pData));  //base64后写入数据库
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+        fp = fopen(RESET_FILE, "w");
+        fprintf(fp, " ");
+        fclose(fp);
+    }
+    else if(mysql_num_rows(g_res) != 0)
+    {
+        g_row=mysql_fetch_row(g_res);
+
+		if(g_row[2] == NULL){
+			mysql_free_result(g_res); //释放结果
+			mysql_close(g_conn); // 关闭链接
+			return 0;
+		}
+        strcpy(pData,base64_decode((unsigned char *) g_row[2]));
+		rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
+		rc4_crypt(s, (unsigned char*)pData, len);//解密
+        timestamp_tmp = atol(pData);
+        if(Timestamp >= timestamp_tmp){
+            Timestamp = timestamp_tmp;
+        }else{
+            sprintf(pData,"%ld",Timestamp);
+
+            len = strlen(pData);
+            rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
+            rc4_crypt(s, (unsigned char*)pData, len);//加密
+
+            memset(sql_tmp,0,sizeof(sql_tmp));
+            sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('LIMITED_DATETIME','%s')",base64_encode(pData));  //base64后写入数据库
+            if (executesql(sql_tmp)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            fp = fopen(RESET_FILE, "w");
+            fprintf(fp, " ");
+            fclose(fp);
+        }
+    }
+    else
+    {
+        return 0;
+    }
+    
+    //将数据写入redis数据库
+    char *redis_host = getenv("REDIS");
+    char *redis_password = getenv("REDIS_PASSWORD");
+    unsigned int redis_port = atoi(getenv("REDIS_PORT"));
+    redisContext *c;
+    redisReply *reply;
+
+    struct timeval timeout = { 1, 500000 };
+    c = redisConnectWithTimeout(redis_host, redis_port, timeout);
+    if (c == NULL || c->err) {
+        if (c) {
+            printf("Connection error: %s\n", c->errstr);
+            redisFree(c);
+        } else {
+            printf("Connection error: can't allocate redis context\n");
+        }
+        return 0;
+    }
+
+    //数据库登录认证
+    reply = redisCommand(c, "AUTH %s", redis_password);
+    if (reply->type == REDIS_REPLY_ERROR) {
+        printf("Redis认证失败!\n");
+        freeReplyObject(reply);
+        redisFree(c);
+        return 0;
+    }
+    freeReplyObject(reply);
+
+    //选择数据库
+    reply = redisCommand(c, "SELECT 0");
+    freeReplyObject(reply);
+
+    reply = redisCommand(c,"exists SYSTEM_UUID");
+    if(reply->type == 3 && reply->integer == 0){
+        freeReplyObject(reply);
+        reply = redisCommand(c,"set SYSTEM_UUID %s",uuid);
+    }
+    freeReplyObject(reply);
+
+    reply = redisCommand(c,"exists LIMITED_DATETIME");
+    if(reply->type == 3 && reply->integer == 0){
+        freeReplyObject(reply);
+        reply = redisCommand(c,"set LIMITED_DATETIME %ld",Timestamp);
+    }
+    freeReplyObject(reply);
+        
+    redisFree(c);
+
+    mysql_free_result(g_res); //释放结果
+    mysql_close(g_conn); // 关闭链接
+}
+

+ 18 - 0
createlicense.sh

@@ -0,0 +1,18 @@
+#!/bin/sh
+#set license
+licensefile='/app/broadcast-system/data/zycoo_init/sql/.limited'
+cid=`cat /sys/block/mmcblk1/device/cid`e845116521d590069f285ddde46ee2cf
+openssl rand -hex 32 > $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+echo `openssl rand -hex 5``echo -n $cid |md5sum|awk '{print $1}'``openssl rand -hex 11` >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+openssl rand -hex 32 >> $licensefile
+
+rm -f /createlicense.sh

+ 176 - 0
discover.c

@@ -0,0 +1,176 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<strings.h>
+#include<string.h>
+#include<stdarg.h>
+#include<mysql/mysql.h>
+#include<mysql/mysqld_error.h>
+
+#define USE_OLD_FUNCTIONS
+#define DBCONFIG "/etc/asterisk/exten_gen.ini"
+//#define PNPCONF "/etc/asterisk/pnp.conf"
+//#define CMD "arp-scan -I eth0 --localnet | grep '..:..:'|awk -F ' ' '{print $1,$2}' > /tmp/dis.tmp"
+#define TMP "/tmp/dis.tmp"
+#define SIZE 256
+
+char *getconfig(const char *file_path, const char *name)
+{
+	char str[SIZE] = {0};
+	char *p;
+	char *value;
+	int tmp = 0;
+	int len = 0;
+	FILE *fp = fopen(file_path, "r");
+	while(fgets(str, SIZE, fp)){
+		if(strstr(str, name)){
+			p = strstr(str, "=");
+			len = p - str;
+			value = malloc(50);
+			bzero(value,50);
+			while(str[len] != '\n'){
+				if(str[len] == ' ' || str[len] == '='){
+					len++;
+					continue;
+				}else
+					value[tmp++] = str[len++];
+			}
+			//printf("%s : %s\n",name, value);
+			break;
+		}
+		
+	}
+	return value;
+}
+
+MYSQL *connect_mysql(MYSQL *conn)
+{
+	char *dbserver = getconfig(DBCONFIG, "dbserverip");
+	char *dbuser = getconfig(DBCONFIG, "dbuser");
+	char *dbpasswd = getconfig(DBCONFIG, "dbpasswd");
+	char *dbname = getconfig(DBCONFIG, "dbname");
+	mysql_init(conn);
+	if(mysql_real_connect(conn, dbserver, dbuser, dbpasswd, dbname,0,"",0)){
+		printf("Connected to mysql !\n");
+	}else{
+		printf("error:%s\n",mysql_error(conn));
+		return NULL;
+	}
+	int utf8;  
+	utf8=mysql_query(conn,"set names utf8");  	
+	return conn;
+}
+
+MYSQL conn;
+MYSQL_RES *res;
+
+int main(int argc, char *argv[])
+{
+	int i = 0, j = 0, mx = 0;
+	char buf[SIZE]={0}, ip[50], mac[50];
+	char sql[SIZE] = {0};
+	char *pos = NULL;
+	char ch = 0;
+	char CMD[SIZE] = {0};
+	char m[6]={0};
+
+	
+	//char *dev = getconfig(PNPCONF, "pnp_interface");
+	MYSQL *conn_mysql = &conn;
+	if (connect_mysql(conn_mysql) == NULL)
+		return -1;
+
+	//sprintf(CMD,"arp-scan -I %s --localnet | grep '..:..:'|awk -F ' ' '{print $1,$2}' > /tmp/dis.tmp",dev);
+	sprintf(CMD,"arp-scan -I eth0 --localnet | grep '..:..:'|awk -F ' ' '{print $1,$2}' > /tmp/dis.tmp");
+	//printf("%s\n",CMD);
+	system(CMD);	//get arp info
+	//free(dev);
+	
+	FILE *fp = fopen(TMP,"r");
+	while(fgets(buf, SIZE, fp))
+	{
+		pos = strstr(buf, " ");
+		i = pos -buf;
+		bzero(ip, 50);
+		strncpy(ip, buf, i);
+		while(buf[i++]){
+			if(buf[i] != ' ' && buf[i] != '\n'){
+				if(buf[i] != ':')
+					mac[j++] = buf[i];
+			}else{
+				continue;
+			}
+		}	
+
+		bzero(sql, SIZE);
+		if(!strncmp(mac, "68692e", 6)){
+			bzero(m,6);
+			sscanf(mac, "%02x%02x%02x%02x%02x%02x",&m[0], &m[1], &m[2], &m[3], &m[4], &m[5]);
+			int a=m[3] & 0x000000FF;
+			int a1=m[4] & 0x000000FF;
+			int a2=m[5] & 0x000000FF;
+			mx = (a << 16)|(a1 << 8)|a2;
+			//printf("===%x\n",mx);
+			if(0x006D3F < mx && mx < 0x00FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "H81/H81P", ip);
+			else if(0x012124 <= mx && mx <= 0x01FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "H81/H81P",  ip);
+			else if(0x023F48 <= mx && mx <= 0x02FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "H83", ip);
+			else if(0x0D0000 <= mx && mx <= 0x0DFFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "X30", ip);
+			else if(0x0E0000 <= mx && mx <= 0x0EFFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "IX100", ip);
+			else if(0x0F0000 <= mx && mx <= 0x0FFFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "IX200", ip);
+			else if(0x200000 <= mx && mx <= 0x20FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "X20", ip);
+			else if(0x210000 <= mx && mx <= 0x21FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "HE30", ip);
+			else if(0x220000 <= mx && mx <= 0x22FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "WE20", ip);
+			else if(0x230000 <= mx && mx <= 0x23FFFF )
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','%s','%s')", mac, "Zycoo", "CE20", ip);
+			mx = 0;
+		}
+		/*
+		else if(!strncmp(mac, "000b82", 6))//chao liu   SELECT func_record_discover_phone_device('005544444444','zycoo','h83','192.168.10.12');
+			sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Grandstream", ip);
+		else if(!strncmp(mac, "001565", 6))//yi lian 
+			sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Yealink", ip);
+		else if(!strncmp(mac, "00268b", 6))		        
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Escene", ip);
+		else if(!strncmp(mac, "0c1105", 6))
+				sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "AkuVox", ip);
+		else if(!strncmp(mac, "001fc1", 6))//han long
+		        sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Htek", ip);
+		else if(!strncmp(mac, "0c383e", 6))//fang wei
+		        sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Fanvil", ip);		
+		else if(!strncmp(mac, "000413", 6))//snom
+		        sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Snom", ip);	
+		else if(!strncmp(mac, "00304f", 6))//planet
+		        sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Planet", ip);	
+		else if(!strncmp(mac, "0021f2", 6))//Flyingvoice
+		        sprintf(sql, "SELECT func_record_discover_phone_device('%s','%s','','%s')", mac, "Flyingvoice", ip);			
+		 */	
+		//printf("%s\n",sql);
+		if(strlen(sql) > 0){
+			printf("sql_insert cmd: %s \n", sql);
+			if(mysql_real_query(conn_mysql, sql, strlen(sql))){
+				printf("Insert data faild :%s !\n",mysql_error(conn_mysql));
+				return -1;
+			}
+			//
+			do 
+			{ 
+				res = mysql_store_result( conn_mysql ); 
+				mysql_free_result(res); 
+			}while( !mysql_next_result( conn_mysql ) );			
+		}
+		bzero(buf,SIZE);
+		i = 0;j = 0;
+	}
+	fclose(fp);
+	mysql_close(conn_mysql);
+	return 0;
+}
+

+ 696 - 0
extension_gen.bak.c

@@ -0,0 +1,696 @@
+/***
+2016.1.20 support Chinese utf8
+2016.4.5  support wmi gen ,by zhi.qin changed
+2016.06.24 modify codec prioty.
+2016.07.01 modify _F1 field 
+2016.07.27 add _opus for opus  _vp8 for vp8  ,extensions and webrtc
+2016.09.26 add _F2 field  for EX16S MAC storage
+2016.11.21  modify _F2 to _exmacaddr ,add _exdahdichan
+在users_extension新增字段: _exmacaddr   (原来的_F2)  not use
+在users_extension新增字段: _exdahdichan	   (原来的_F3) not use
+在users_extension新增字段:_vp8
+在users_extension新增字段:_opus
+***/
+
+#include<stdlib.h>
+#include<stdio.h>
+#include<string.h>
+#include<mysql/mysql.h>
+#include<mysql/mysqld_error.h>
+#include<mysql/errmsg.h>
+
+#define EXTEN_GEN_CFG "/etc/asterisk/exten_gen.ini"
+#define USER_WEBRTC_CONFIG_FILE "/etc/asterisk/users_webrtc.conf" 
+
+MYSQL conn;
+MYSQL_RES *res_exten;
+MYSQL_ROW exten_row;
+char corr_str[20];
+
+void connection(const char *host,const char *user,const char *password,const char *database){
+	
+	mysql_init(&conn);
+	if(mysql_real_connect(&conn,host,user,password,database,3306,NULL,0)){
+		mysql_set_character_set(&conn,"utf8");
+		printf("Connection success!\n");
+	}else{
+		fprintf(stderr,"Connection failed!\n");
+		if(mysql_errno(&conn)){
+			fprintf(stderr,"Connection error %d: %s\n",mysql_errno(&conn),mysql_error(&conn));
+		}
+	exit -1;
+	}
+}
+/*
+*file exten_gen.ini 
+*dbserverip=
+*dbuser=
+*dbpasswd=
+*dbname=
+*/
+
+void getstring(char *buf,char *db_cfg){
+	
+	char str1[100],str2[100],*tmp;
+	int len;
+	strcpy(str1,buf);
+	tmp=strchr(str1,'=');
+	strcpy(str2,tmp);
+	if (isspace(str2[1]))
+			strcpy(str1,&str2[2]);
+	else
+			strcpy(str1,&str2[1]);
+	len=strlen(str1);
+	if(str1[len-2] == '\r')
+			str1[len-2]='\0';
+	else if(str1[len-1] == '\n')
+			str1[len-1]='\0';
+	else
+			str1[len]='\0';
+	//printf("str1=%s\n",str1);
+	strcpy(db_cfg,str1);
+}
+
+int main(int argc, char *argv[]){
+
+	FILE *fp,*fp_cfg;
+	MYSQL_FIELD *exten_field;
+	unsigned int field_count;
+	unsigned int i;
+	//int dahdichan_en = 0;
+	char *field_name = NULL;
+	char codecs[100] = {0},dahdichan[10] = {0},buffer[100] = {0};//,db_cfg[4][30];
+	char *code_addr = NULL;//,*dbserverip = NULL,*dbuser = NULL,*dbpasswd = NULL,*dbname = NULL;
+	char new_codecs[20][100]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	if ((fp_cfg=fopen(EXTEN_GEN_CFG,"r"))==NULL) {
+		printf("File: %s is not open ,fail.\n",EXTEN_GEN_CFG);
+		return -1;
+	}
+	/*
+	while(fgets(buffer,100,fp_cfg)){
+		if(!strncasecmp(buffer,"dbserverip",10))
+			getstring(buffer,db_cfg[0]);
+		if(!strncasecmp(buffer,"dbuser",6))
+			getstring(buffer,db_cfg[1]);
+		if(!strncasecmp(buffer,"dbpasswd",8))
+			getstring(buffer,db_cfg[2]);
+		if(!strncasecmp(buffer,"dbname",6))
+			getstring(buffer,db_cfg[3]);
+	}
+	*/
+    char *hostname = getenv("MYSQL");
+    char *username = getenv("MYSQL_USER");
+    char *password = getenv("MYSQL_PASSWORD");
+    char *dbname = getenv("MYSQL_DATABASE");
+	connection(hostname,username,password,dbname);
+	int res ;
+	if(NULL != argv[1]){
+		switch(*argv[1]){
+			case '0':
+				res	= mysql_query(&conn,"SELECT * from t_pbx_users_extension order by exten asc");
+				if(res){
+					fprintf(stderr,"SELECT error: %s\n",mysql_error(&conn));
+					return -1;
+				}else{
+					res_exten = mysql_store_result(&conn);
+					if(res_exten){
+						printf("Recieved %lu rows\n",(unsigned long)mysql_num_rows(res_exten));
+					}
+					if(!(fp = fopen("/etc/asterisk/users_extension.conf","w+"))){
+						printf("Creating extension config file failed,please check it.\n");
+						return -1;
+					}
+				
+					field_count = mysql_num_fields(res_exten);
+					printf("field_count = %d\n",field_count);
+					while(exten_row = mysql_fetch_row(res_exten)){
+											
+						memset(codecs,0,sizeof(codecs));
+					//	dahdichan_en = 0;
+					//	printf("....%s...\n",codecs[0]);
+						for (i=0;i<20;i++)
+						{
+							memset(new_codecs[i],0,sizeof(new_codecs[i]));
+						}
+						//mysql_field_seek(res_exten,0);//point to the first field.
+						for(i=0;i<field_count;i++){
+				
+							exten_field = mysql_fetch_field(res_exten);
+							
+							if(!strncasecmp(exten_field->name,"id",strlen(exten_field->name)))
+								continue;
+							
+							if(!strncasecmp(exten_field->name,"createdAt",strlen(exten_field->name)))
+								continue;
+							
+							if(!strncasecmp(exten_field->name,"updatedAt",strlen(exten_field->name)))
+								continue;
+
+							if(!strncasecmp(exten_field->name,"exten",strlen(exten_field->name))){
+								
+								fprintf(fp,"[%s]\n",exten_row[i]);
+								continue;
+							}
+#if 0								
+							//support EX16S
+							if(!strncasecmp(exten_field->name,"_dahdichan",strlen(exten_field->name))){
+								
+								if (strlen(exten_row[i])  > 0 )
+									strcpy(dahdichan,exten_row[i]);//save dahdi chan num
+								continue;
+							}
+						
+							if(!strncasecmp(exten_field->name,"_exmacaddr",strlen(exten_field->name))){
+								if (strlen(exten_row[i]) > 15)
+									dahdichan_en = 1;
+								continue;
+							}
+#endif							
+							//end support
+							//add acl for extensions
+							if(!strncasecmp(exten_field->name,"F1",strlen(exten_field->name))){
+								if(!strncasecmp(exten_row[i],"remote",6)) {									
+									fprintf(fp,"acl = remote_extensions_acl\n");	
+								} else
+									fprintf(fp,"acl = local_extensions_acl\n");		
+								continue;
+							}
+								if(!strncasecmp(exten_field->name,"F2",strlen(exten_field->name)))
+										continue;
+								if(!strncasecmp(exten_field->name,"F3",strlen(exten_field->name)))
+										continue;
+								if(!strncasecmp(exten_field->name,"F4",strlen(exten_field->name)))
+										continue;
+
+								//add codecs to cfg file. 
+								
+								if(!strncasecmp(exten_field->name,"alaw",strlen(exten_field->name))){
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;									
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"ulaw",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;	
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"g729",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"g726",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"g722",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"gsm",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"speex",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"opus",strlen(exten_field->name))){
+									
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}								
+								if(!strncasecmp(exten_field->name,"h261",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"h263",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"h263p",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"h264",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"vp8",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+							if(0 == strlen(exten_row[i])){
+								if(!strncasecmp(exten_field->name,"secret",strlen(exten_field->name)))
+								;
+								else if(!strncasecmp(exten_field->name,"_vmsecret",strlen(exten_field->name)))
+								;
+								else continue;
+							}
+							field_name = exten_field->name;
+
+						//add by zhi.qin 					
+							if(!strncasecmp(exten_field->name,"mailbox",strlen(exten_field->name)))
+							{
+								if(0 < strlen(exten_row[i]) && !strstr(exten_row[i],"@")){
+									fprintf(fp,"%s = %s@default\n",field_name,exten_row[i]);
+									continue;
+								}
+							}//end 2016.04.05
+							//printf("%s = %s\n",field_name,exten_row[i]);
+							fprintf(fp,"%s = %s\n",field_name,exten_row[i]);
+						}
+//						printf("codecs len %d\n",strlen(codecs));
+//						if(strlen(codecs) <= 4){
+//							printf("something wrong happened to codecs selection.\n");
+//							exit -1;
+//						}
+//						codecs[strlen(codecs)-1] = '\0';
+//						printf("codecs = %s\n",code_addr);
+						fputs("disallow = all\n",fp);
+						//process new_codecs
+
+						for (i=0;i<20;i++)
+						{
+							if (new_codecs[i][0] != '\0')
+								if (codecs[0] != '\0' )
+									strcat(codecs,",");
+								code_addr = strcat(codecs,new_codecs[i]);
+						}
+						//printf("codecs = %s\n",code_addr);
+						fprintf(fp,"allow = %s\n",code_addr);
+						//if ( (dahdichan_en == 1) && (strlen(dahdichan) > 0) )
+						//	fprintf(fp,"dahdichan = %s\n",dahdichan);
+						fprintf(fp,"subscribemwi = no\n");//add by zhi.qin for sub mwi
+						//fprintf(fp,"allow = %s\n",code_addr);
+						fprintf(fp,"read = NULL\nwrite = NULL\n\n");//refuese sip exten permit access						
+
+					}
+				}
+				fclose(fp);
+				break;
+			case '1':
+						res = mysql_query(&conn,"SELECT * from t_pbx_users_webrtc order by exten asc");
+						if(res){
+							fprintf(stderr,"SELECT error: %s\n",mysql_error(&conn));
+							return -1;
+						}else{
+							res_exten = mysql_store_result(&conn);
+
+						if((fp=fopen(USER_WEBRTC_CONFIG_FILE,"w+"))==NULL)
+							{printf( "cannot open %s file,please check.\n",USER_WEBRTC_CONFIG_FILE);return -1;}
+
+						fputs("[webrtc](!)\n",fp);
+						fputs("srtpcapable = yes\n",fp);
+						fputs("encryption = yes\n",fp);
+						fputs("avpf = yes\n",fp);
+						fputs("rtcp_mux = yes\n",fp);
+						fputs("force_avp = yes\n",fp);
+						fputs("icesupport = yes\n",fp);
+						fputs("dtlsenable = yes\n",fp);
+						fputs("dtlsverify = no\n",fp);
+						fputs("dtlscertfile = /etc/asterisk/keys/asterisk.pem\n",fp);
+						fputs("dtlscafile = /etc/asterisk/keys/ca.crt\n",fp);
+						fputs("dtlssetup = actpass\n",fp);
+						fputs("transport = ws,wss\n",fp);
+						fputs("videosupport = no\n\n",fp);
+						fputs("rtcp_mux = yes\n\n",fp);
+						
+						field_count = mysql_num_fields(res_exten);
+						printf("field_count = %d\n",field_count);
+					
+						while(exten_row = mysql_fetch_row(res_exten)){
+							memset(codecs,0,sizeof(codecs));
+						//	printf("....%s...\n",codecs[0]);
+							//mysql_field_seek(res_exten,0);//point to the first field.
+							for (i=0;i<20;i++)
+							{
+								memset(new_codecs[i],0,sizeof(new_codecs[i]));
+							}							
+							for(i=0;i<field_count;i++){
+					
+								exten_field = mysql_fetch_field(res_exten);
+								
+								if(!strncasecmp(exten_field->name,"id",strlen(exten_field->name)))
+									continue;
+
+								if(!strncasecmp(exten_field->name,"exten",strlen(exten_field->name))){
+									
+									fprintf(fp,"[%s](webrtc)\n",exten_row[i]);
+									continue;
+								}
+
+									if(!strncasecmp(exten_field->name,"F1",strlen(exten_field->name)))
+											continue;
+
+									if(!strncasecmp(exten_field->name,"F2",strlen(exten_field->name)))
+											continue;
+
+									if(!strncasecmp(exten_field->name,"F3",strlen(exten_field->name)))
+											continue;
+
+									if(!strncasecmp(exten_field->name,"F4",strlen(exten_field->name)))
+											continue;
+									
+									if(!strncasecmp(exten_field->name,"email",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dahdichan",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"hasexten",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"directmedia",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"videosupport",strlen(exten_field->name)))
+											continue;
+							#if 0   //del 2015.11.19
+									if(!strncasecmp(exten_field->name,"_transport",strlen(exten_field->name)))
+											continue;
+							#endif
+									if(!strncasecmp(exten_field->name,"encryption",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"srtpcapable",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"deny",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"permit",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"avpf",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"force_avp",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"icesupport",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlsverify",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlsenable",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlscertfile",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlscafile",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlssetup",strlen(exten_field->name)))
+											continue;						
+										//add codecs to cfg file.
+									if(!strncasecmp(exten_field->name,"alaw",strlen(exten_field->name))){
+						
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"ulaw",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"g729",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"g726",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"g722",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"gsm",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"speex",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"opus",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}									
+									if(!strncasecmp(exten_field->name,"h261",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"h263",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"h263p",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"h264",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"vp8",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}									
+								if(0 == strlen(exten_row[i])){
+									if(!strncasecmp(exten_field->name,"secret",strlen(exten_field->name)))
+									;
+									else if(!strncasecmp(exten_field->name,"vmsecret",strlen(exten_field->name)))
+									;
+									else continue;
+								}
+								field_name = exten_field->name;
+
+								fprintf(fp,"%s = %s\n",field_name,exten_row[i]);
+							}
+				//						printf("codecs len %d\n",strlen(codecs));
+							//if(strlen(codecs) <= 4){
+							//	printf("something wrong happened to codecs selection.\n");
+							//	exit -1;
+							//}
+							//codecs[strlen(codecs)-1] = '\0';
+							for (i=0;i<20;i++)
+							{
+							if (new_codecs[i][0] != '\0')
+								if (codecs[0] != '\0' )
+									strcat(codecs,",");
+								code_addr = strcat(codecs,new_codecs[i]);
+							}
+				//						printf("codecs = %s\n",code_addr);
+							fputs("disallow = all\n",fp);
+							fprintf(fp,"allow = %s\n",code_addr);
+							fprintf(fp,"read = NULL\nwrite=NULL\n\n");//refuese sip exten permit access
+						}
+					}
+				fclose(fp);
+				break;				
+			default:
+				printf("You enter the wrong parameters.please check it\n");
+				break;
+			}
+		fclose(fp_cfg);
+		mysql_free_result(res_exten);
+		mysql_close(&conn);
+		return 0;
+	} else {
+		fclose(fp_cfg);
+		mysql_free_result(res_exten);
+		mysql_close(&conn);
+		return 0;
+	}
+}
+

+ 697 - 0
extension_gen.c

@@ -0,0 +1,697 @@
+/***
+2016.1.20 support Chinese utf8
+2016.4.5  support wmi gen ,by zhi.qin changed
+2016.06.24 modify codec prioty.
+2016.07.01 modify _F1 field 
+2016.07.27 add _opus for opus  _vp8 for vp8  ,extensions and webrtc
+2016.09.26 add _F2 field  for EX16S MAC storage
+2016.11.21  modify _F2 to _exmacaddr ,add _exdahdichan
+在users_extension新增字段: _exmacaddr   (原来的_F2)  not use
+在users_extension新增字段: _exdahdichan	   (原来的_F3) not use
+在users_extension新增字段:_vp8
+在users_extension新增字段:_opus
+***/
+
+#include<stdlib.h>
+#include<stdio.h>
+#include<string.h>
+#include<mysql/mysql.h>
+#include<mysql/mysqld_error.h>
+#include<mysql/errmsg.h>
+#include <ctype.h>
+
+#define EXTEN_GEN_CFG "/etc/asterisk/exten_gen.ini"
+#define USER_WEBRTC_CONFIG_FILE "/etc/asterisk/users_webrtc.conf" 
+
+MYSQL conn;
+MYSQL_RES *res_exten;
+MYSQL_ROW exten_row;
+char corr_str[20];
+
+void connection(const char *host,const char *user,const char *password,const char *database){
+	
+	mysql_init(&conn);
+	if(mysql_real_connect(&conn,host,user,password,database,3306,NULL,0)){
+		mysql_set_character_set(&conn,"utf8");
+		printf("Connection success!\n");
+	}else{
+		fprintf(stderr,"Connection failed!\n");
+		if(mysql_errno(&conn)){
+			fprintf(stderr,"Connection error %d: %s\n",mysql_errno(&conn),mysql_error(&conn));
+		}
+	exit -1;
+	}
+}
+/*
+*file exten_gen.ini 
+*dbserverip=
+*dbuser=
+*dbpasswd=
+*dbname=
+*/
+
+void getstring(char *buf,char *db_cfg){
+	
+	char str1[100],str2[100],*tmp;
+	int len;
+	strcpy(str1,buf);
+	tmp=strchr(str1,'=');
+	strcpy(str2,tmp);
+	if (isspace(str2[1]))
+			strcpy(str1,&str2[2]);
+	else
+			strcpy(str1,&str2[1]);
+	len=strlen(str1);
+	if(str1[len-2] == '\r')
+			str1[len-2]='\0';
+	else if(str1[len-1] == '\n')
+			str1[len-1]='\0';
+	else
+			str1[len]='\0';
+	//printf("str1=%s\n",str1);
+	strcpy(db_cfg,str1);
+}
+
+int main(int argc, char *argv[]){
+	FILE *fp,*fp_cfg;
+	MYSQL_FIELD *exten_field;
+	unsigned int field_count;
+	unsigned int i;
+	//int dahdichan_en = 0;
+	char *field_name = NULL;
+	char codecs[100] = {0},dahdichan[10] = {0},buffer[100] = {0};//,db_cfg[4][30];
+	char *code_addr = NULL;//,*dbserverip = NULL,*dbuser = NULL,*dbpasswd = NULL,*dbname = NULL;
+	char new_codecs[20][100]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	if ((fp_cfg=fopen(EXTEN_GEN_CFG,"r"))==NULL) {
+		printf("File: %s is not open ,fail.\n",EXTEN_GEN_CFG);
+		return -1;
+	}
+	/*
+	while(fgets(buffer,100,fp_cfg)){
+		if(!strncasecmp(buffer,"dbserverip",10))
+			getstring(buffer,db_cfg[0]);
+		if(!strncasecmp(buffer,"dbuser",6))
+			getstring(buffer,db_cfg[1]);
+		if(!strncasecmp(buffer,"dbpasswd",8))
+			getstring(buffer,db_cfg[2]);
+		if(!strncasecmp(buffer,"dbname",6))
+			getstring(buffer,db_cfg[3]);
+	}
+	*/
+    char *hostname = getenv("MYSQL");
+    char *username = getenv("MYSQL_USER");
+    char *password = getenv("MYSQL_PASSWORD");
+    char *dbname = getenv("MYSQL_DATABASE");
+	connection(hostname,username,password,dbname);
+	int res ;
+	if(NULL != argv[1]){
+		switch(*argv[1]){
+			case '0':
+				//res	= mysql_query(&conn,"SELECT * from t_pbx_users_extension order by exten asc");
+				res	= mysql_query(&conn,"SELECT * from t_pbx_users_extension order by exten asc");
+				if(res){
+					fprintf(stderr,"SELECT error: %s\n",mysql_error(&conn));
+					return -1;
+				}else{
+					res_exten = mysql_store_result(&conn);
+					if(res_exten){
+						printf("Recieved %lu rows\n",(unsigned long)mysql_num_rows(res_exten));
+					}
+					if(!(fp = fopen("/etc/asterisk/users_extension.conf","w+"))){
+						printf("Creating extension config file failed,please check it.\n");
+						return -1;
+					}
+				
+					field_count = mysql_num_fields(res_exten);
+					printf("field_count = %d\n",field_count);
+					while(exten_row = mysql_fetch_row(res_exten)){
+											
+						memset(codecs,0,sizeof(codecs));
+					//	dahdichan_en = 0;
+					//	printf("....%s...\n",codecs[0]);
+						for (i=0;i<20;i++)
+						{
+							memset(new_codecs[i],0,sizeof(new_codecs[i]));
+						}
+						mysql_field_seek(res_exten,0);//point to the first field.
+						for(i=0;i<field_count;i++){
+				
+							exten_field = mysql_fetch_field(res_exten);
+							
+							if(!strncasecmp(exten_field->name,"id",strlen(exten_field->name)))
+								continue;
+							
+							if(!strncasecmp(exten_field->name,"createdAt",strlen(exten_field->name)))
+								continue;
+							
+							if(!strncasecmp(exten_field->name,"updatedAt",strlen(exten_field->name)))
+								continue;
+
+							if(!strncasecmp(exten_field->name,"exten",strlen(exten_field->name))){
+								
+								fprintf(fp,"[%s]\n",exten_row[i]);
+								continue;
+							}
+#if 0								
+							//support EX16S
+							if(!strncasecmp(exten_field->name,"_dahdichan",strlen(exten_field->name))){
+								
+								if (strlen(exten_row[i])  > 0 )
+									strcpy(dahdichan,exten_row[i]);//save dahdi chan num
+								continue;
+							}
+						
+							if(!strncasecmp(exten_field->name,"_exmacaddr",strlen(exten_field->name))){
+								if (strlen(exten_row[i]) > 15)
+									dahdichan_en = 1;
+								continue;
+							}
+#endif							
+							//end support
+							//add acl for extensions
+							if(!strncasecmp(exten_field->name,"F1",strlen(exten_field->name))){
+								//if(!strncasecmp(exten_row[i],"remote",6)) {									
+								//	fprintf(fp,"acl = remote_extensions_acl\n");	
+								//} else
+								//	fprintf(fp,"acl = local_extensions_acl\n");		
+								continue;
+							}
+								if(!strncasecmp(exten_field->name,"F2",strlen(exten_field->name)))
+										continue;
+								if(!strncasecmp(exten_field->name,"F3",strlen(exten_field->name)))
+										continue;
+								if(!strncasecmp(exten_field->name,"F4",strlen(exten_field->name)))
+										continue;
+
+								//add codecs to cfg file. 
+								
+								if(!strncasecmp(exten_field->name,"alaw",strlen(exten_field->name))){
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;									
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"ulaw",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;	
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"g729",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"g726",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"g722",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"gsm",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"speex",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"opus",strlen(exten_field->name))){
+									
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}								
+								if(!strncasecmp(exten_field->name,"h261",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"h263",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"h263p",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"h264",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+								if(!strncasecmp(exten_field->name,"vp8",strlen(exten_field->name))){
+
+										if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;
+										}
+										else
+												continue;
+								}
+							if(0 == strlen(exten_row[i])){
+								if(!strncasecmp(exten_field->name,"secret",strlen(exten_field->name)))
+								;
+								else if(!strncasecmp(exten_field->name,"_vmsecret",strlen(exten_field->name)))
+								;
+								else continue;
+							}
+							field_name = exten_field->name;
+
+						//add by zhi.qin 					
+							if(!strncasecmp(exten_field->name,"mailbox",strlen(exten_field->name)))
+							{
+								if(0 < strlen(exten_row[i]) && !strstr(exten_row[i],"@")){
+									fprintf(fp,"%s = %s@default\n",field_name,exten_row[i]);
+									continue;
+								}
+							}//end 2016.04.05
+							//printf("%s = %s\n",field_name,exten_row[i]);
+							fprintf(fp,"%s = %s\n",field_name,exten_row[i]);
+						}
+//						printf("codecs len %d\n",strlen(codecs));
+//						if(strlen(codecs) <= 4){
+//							printf("something wrong happened to codecs selection.\n");
+//							exit -1;
+//						}
+//						codecs[strlen(codecs)-1] = '\0';
+//						printf("codecs = %s\n",code_addr);
+						fputs("disallow = all\n",fp);
+						//process new_codecs
+
+						for (i=0;i<20;i++)
+						{
+							if (new_codecs[i][0] != '\0')
+								if (codecs[0] != '\0' )
+									strcat(codecs,",");
+								code_addr = strcat(codecs,new_codecs[i]);
+						}
+						//printf("codecs = %s\n",code_addr);
+						fprintf(fp,"allow = %s\n",code_addr);
+						//if ( (dahdichan_en == 1) && (strlen(dahdichan) > 0) )
+						//	fprintf(fp,"dahdichan = %s\n",dahdichan);
+						fprintf(fp,"subscribemwi = no\n");//add by zhi.qin for sub mwi
+						//fprintf(fp,"allow = %s\n",code_addr);
+						fprintf(fp,"read = NULL\nwrite = NULL\n\n");//refuese sip exten permit access						
+
+					}
+				}
+				fclose(fp);
+				break;
+			case '1':
+						res = mysql_query(&conn,"SELECT * from t_pbx_users_webrtc order by exten asc");
+						if(res){
+							fprintf(stderr,"SELECT error: %s\n",mysql_error(&conn));
+							return -1;
+						}else{
+							res_exten = mysql_store_result(&conn);
+
+						if((fp=fopen(USER_WEBRTC_CONFIG_FILE,"w+"))==NULL)
+							{printf( "cannot open %s file,please check.\n",USER_WEBRTC_CONFIG_FILE);return -1;}
+
+						fputs("[webrtc](!)\n",fp);
+						fputs("srtpcapable = yes\n",fp);
+						fputs("encryption = yes\n",fp);
+						fputs("avpf = yes\n",fp);
+						fputs("rtcp_mux = yes\n",fp);
+						fputs("force_avp = yes\n",fp);
+						fputs("icesupport = yes\n",fp);
+						fputs("dtlsenable = yes\n",fp);
+						fputs("dtlsverify = no\n",fp);
+						fputs("dtlscertfile = /etc/asterisk/keys/asterisk.pem\n",fp);
+						fputs("dtlscafile = /etc/asterisk/keys/ca.crt\n",fp);
+						fputs("dtlssetup = actpass\n",fp);
+						fputs("transport = ws,wss\n",fp);
+						fputs("videosupport = yes\n\n",fp);
+						fputs("rtcp_mux = yes\n\n",fp);
+						
+						field_count = mysql_num_fields(res_exten);
+						printf("field_count = %d\n",field_count);
+					
+						while(exten_row = mysql_fetch_row(res_exten)){
+							memset(codecs,0,sizeof(codecs));
+						//	printf("....%s...\n",codecs[0]);
+							mysql_field_seek(res_exten,0);//point to the first field.
+							for (i=0;i<20;i++)
+							{
+								memset(new_codecs[i],0,sizeof(new_codecs[i]));
+							}							
+							for(i=0;i<field_count;i++){
+					
+								exten_field = mysql_fetch_field(res_exten);
+								
+								if(!strncasecmp(exten_field->name,"id",strlen(exten_field->name)))
+									continue;
+
+								if(!strncasecmp(exten_field->name,"exten",strlen(exten_field->name))){
+									
+									fprintf(fp,"[%s](webrtc)\n",exten_row[i]);
+									continue;
+								}
+
+									if(!strncasecmp(exten_field->name,"F1",strlen(exten_field->name)))
+											continue;
+
+									if(!strncasecmp(exten_field->name,"F2",strlen(exten_field->name)))
+											continue;
+
+									if(!strncasecmp(exten_field->name,"F3",strlen(exten_field->name)))
+											continue;
+
+									if(!strncasecmp(exten_field->name,"F4",strlen(exten_field->name)))
+											continue;
+									
+									if(!strncasecmp(exten_field->name,"email",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dahdichan",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"hasexten",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"directmedia",strlen(exten_field->name)))
+											continue;
+							#if 0
+									if(!strncasecmp(exten_field->name,"videosupport",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"transport",strlen(exten_field->name)))
+											continue;
+							#endif
+									if(!strncasecmp(exten_field->name,"encryption",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"srtpcapable",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"deny",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"permit",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"avpf",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"force_avp",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"icesupport",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlsverify",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlsenable",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlscertfile",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlscafile",strlen(exten_field->name)))
+											continue;
+									if(!strncasecmp(exten_field->name,"dtlssetup",strlen(exten_field->name)))
+											continue;						
+										//add codecs to cfg file.
+									if(!strncasecmp(exten_field->name,"alaw",strlen(exten_field->name))){
+						
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"ulaw",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"g729",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"g726",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"g722",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"gsm",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"speex",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"opus",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}									
+									if(!strncasecmp(exten_field->name,"h261",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"h263",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"h263p",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"h264",strlen(exten_field->name))){
+
+									if(atoi(exten_row[i]) < 20 ) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}
+									if(!strncasecmp(exten_field->name,"vp8",strlen(exten_field->name))){
+
+									if((atoi(exten_row[i]) > 0) && (atoi(exten_row[i]) < 20 )) {
+											if (new_codecs[atoi(exten_row[i])][0] != '\0') { 
+												code_addr = strcat(new_codecs[atoi(exten_row[i])], ",");//not null
+											}											
+											code_addr = strcat(new_codecs[atoi(exten_row[i])],exten_field->name);
+											continue;;
+											}
+											else
+													continue;
+									}									
+								if(0 == strlen(exten_row[i])){
+									if(!strncasecmp(exten_field->name,"secret",strlen(exten_field->name)))
+									;
+									else if(!strncasecmp(exten_field->name,"vmsecret",strlen(exten_field->name)))
+									;
+									else continue;
+								}
+								field_name = exten_field->name;
+
+								fprintf(fp,"%s = %s\n",field_name,exten_row[i]);
+							}
+				//						printf("codecs len %d\n",strlen(codecs));
+							//if(strlen(codecs) <= 4){
+							//	printf("something wrong happened to codecs selection.\n");
+							//	exit -1;
+							//}
+							//codecs[strlen(codecs)-1] = '\0';
+							for (i=0;i<20;i++)
+							{
+							if (new_codecs[i][0] != '\0')
+								if (codecs[0] != '\0' )
+									strcat(codecs,",");
+								code_addr = strcat(codecs,new_codecs[i]);
+							}
+				//						printf("codecs = %s\n",code_addr);
+							fputs("disallow = all\n",fp);
+							fprintf(fp,"allow = %s\n",code_addr);
+							fprintf(fp,"read = NULL\nwrite=NULL\n\n");//refuese sip exten permit access
+						}
+					}
+				fclose(fp);
+				break;				
+			default:
+				printf("You enter the wrong parameters.please check it\n");
+				break;
+			}
+		fclose(fp_cfg);
+		mysql_free_result(res_exten);
+		mysql_close(&conn);
+		return 0;
+	} else {
+		fclose(fp_cfg);
+		mysql_free_result(res_exten);
+		mysql_close(&conn);
+		return 0;
+	}
+}
+

+ 337 - 0
fail2ban_conf.c

@@ -0,0 +1,337 @@
+/*
+============================================================================
+Name        : generate_paging_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate paging info from mysql to paging conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql group记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql device记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+
+#define NORMAL_SIZE 256
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define CONFIG_FILE "/etc/fail2ban/jail.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define FAIL2BAN_BASIC_SQL "select name,enable,max_retry,find_time,ban_time from t_pbx_fail2ban_basic"
+#define FAIL2BAN_SIP_IGNORED_SQL "select ip,netmask_length from t_pbx_fail2ban_ignored where protocol_sip='1' and enable='1'"
+#define FAIL2BAN_SSH_IGNORED_SQL "select ip,netmask_length from t_pbx_fail2ban_ignored where protocol_ssh='1' and enable='1'"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+int main(int argc, char **argv) {
+    char in[8] = {0};
+	char tmp[MIDLE_SIZE] = {0};
+	char ignored[MIDLE_SIZE] = {0};
+	char cmd[MIDLE_SIZE] = {0};
+
+    strcpy(g_host_name,getenv("MYSQL"));
+    strcpy(g_user_name,getenv("MYSQL_USER"));
+    strcpy(g_password,getenv("MYSQL_PASSWORD"));
+    strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+
+    if (init_mysql()){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+
+    if (executesql(FAIL2BAN_BASIC_SQL)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+
+    g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    FILE *conf_fail2ban_fp = fopen(CONFIG_FILE, "w+");
+
+    if (conf_fail2ban_fp == NULL){
+        perror("Open paging conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(conf_fail2ban_fp, "[DEFAULT]\n\
+ignoreip = 127.0.0.1/32\n\
+bantime  = 3600\n\
+maxretry = 3\n\
+backend = auto\n\
+banaction = iptables-multiport\n\
+mta = mail\n\
+protocol = tcp\n\
+chain = INPUT\n\
+action_ = %%(banaction)s[name=%%(__name__)s, port=\"%%(port)s\", protocol=\"%%(protocol)s\", chain=\"%%(chain)s\"]\n\
+action_mw = %%(banaction)s[name=%%(__name__)s, port=\"%%(port)s\", protocol=\"%%(protocol)s\", chain=\"%%(chain)s\"]\n\
+action_mwl = %%(banaction)s[name=%%(__name__)s, port=\"%%(port)s\", protocol=\"%%(protocol)s\", chain=\"%%(chain)s\"]\n\
+action = %%(action_)s\n\n\
+"\
+);
+
+    while ((g_row=mysql_fetch_row(g_res)))
+    { // 打印结果集
+        if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL || g_row[3] == NULL || g_row[4] == NULL)
+        {
+            printf("some feild is empty!\n");
+            continue;
+        }
+
+        if(strcmp((const char *)g_row[1], "1") == 0)
+            strcpy(in, "true");
+        else
+            strcpy(in, "false");
+
+        if(strcmp((const char*)g_row[0], "sip") == 0){
+            if (executesql(FAIL2BAN_SIP_IGNORED_SQL)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn);
+            memset(ignored,0,sizeof(ignored));
+            while(d_row = mysql_fetch_row(d_res))
+            {
+                strcat(ignored,(char *)d_row[0]);
+                strcat(ignored,"/");
+                strcat(ignored,(char *)d_row[1]);
+                strcat(ignored," ");
+            }
+            fprintf(conf_fail2ban_fp, "[sip-iptables]\n\
+enabled = %s\n\
+ignoreip = 127.0.0.1/32 %s \n\
+filter = sip\n\
+action = iptables-allports[name=VOIP, protocol=all]\n\
+logpath = /var/log/asterisk/messages\n\
+maxretry = %s\n\
+findtime = %s\n\
+bantime = %s\n\n\
+",\
+in, ignored, g_row[2], g_row[3], g_row[4]
+);
+            mysql_free_result(d_res);
+        }
+        else if(strcmp((const char*)g_row[0], "ssh") == 0)
+        {
+            if (executesql(FAIL2BAN_SSH_IGNORED_SQL)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn);
+            memset(ignored,0,sizeof(ignored));
+            while(d_row = mysql_fetch_row(d_res))
+            {
+                strcat(ignored,(char *)d_row[0]);
+                strcat(ignored,"/");
+                strcat(ignored,(char *)d_row[1]);
+                strcat(ignored," ");
+            }
+            fprintf(conf_fail2ban_fp, "[SSH]\n\
+enabled = %s\n\
+ignoreip = 127.0.0.1/32 %s \n\
+port = 22\n\
+filter = sshd\n\
+logpath = /init/logs/auth.log\n\
+maxretry = %s\n\
+findtime = %s\n\
+bantime = %s\n\n\
+",\
+in, ignored, g_row[2], g_row[3], g_row[4]
+);
+            mysql_free_result(d_res);
+        }
+    }
+    fclose(conf_fail2ban_fp);
+    mysql_free_result(g_res); // 释放结果集
+    mysql_close(g_conn); // 关闭链接
+    	
+	sprintf(cmd,"echo \"\" > /init/logs/auth.log;echo \"\" > /var/log/fail2ban.log ;echo \"\" > /var/log/asterisk/messages;asterisk -rx \"logger reload\";service fail2ban restart");
+
+	system(cmd);
+}

+ 333 - 0
fail2ban_init.c

@@ -0,0 +1,333 @@
+/*
+============================================================================
+Name        : generate_paging_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate paging info from mysql to paging conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql group记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql device记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+
+#define NORMAL_SIZE 256
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define CONFIG_FILE "/etc/fail2ban/jail.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define FAIL2BAN_BASIC_SQL "select name,enable,max_retry,find_time,ban_time from t_pbx_fail2ban_basic"
+#define FAIL2BAN_SIP_IGNORED_SQL "select ip,netmask_length from t_pbx_fail2ban_ignored where protocol_sip='1' and enable='1'"
+#define FAIL2BAN_SSH_IGNORED_SQL "select ip,netmask_length from t_pbx_fail2ban_ignored where protocol_ssh='1' and enable='1'"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+int main(int argc, char **argv) {
+    char in[8] = {0};
+	char tmp[MIDLE_SIZE] = {0};
+	char ignored[MIDLE_SIZE] = {0};
+	char cmd[MIDLE_SIZE] = {0};
+
+    strcpy(g_host_name,getenv("MYSQL"));
+    strcpy(g_user_name,getenv("MYSQL_USER"));
+    strcpy(g_password,getenv("MYSQL_PASSWORD"));
+    strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+
+    if (init_mysql()){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+
+    if (executesql(FAIL2BAN_BASIC_SQL)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+
+    g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    FILE *conf_fail2ban_fp = fopen(CONFIG_FILE, "w+");
+
+    if (conf_fail2ban_fp == NULL){
+        perror("Open paging conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(conf_fail2ban_fp, "[DEFAULT]\n\
+ignoreip = 127.0.0.1/32\n\
+bantime  = 3600\n\
+maxretry = 3\n\
+backend = auto\n\
+banaction = iptables-multiport\n\
+mta = mail\n\
+protocol = tcp\n\
+chain = INPUT\n\
+action_ = %%(banaction)s[name=%%(__name__)s, port=\"%%(port)s\", protocol=\"%%(protocol)s\", chain=\"%%(chain)s\"]\n\
+action_mw = %%(banaction)s[name=%%(__name__)s, port=\"%%(port)s\", protocol=\"%%(protocol)s\", chain=\"%%(chain)s\"]\n\
+action_mwl = %%(banaction)s[name=%%(__name__)s, port=\"%%(port)s\", protocol=\"%%(protocol)s\", chain=\"%%(chain)s\"]\n\
+action = %%(action_)s\n\n\
+"\
+);
+
+    while ((g_row=mysql_fetch_row(g_res)))
+    { // 打印结果集
+        if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL || g_row[3] == NULL || g_row[4] == NULL)
+        {
+            printf("some feild is empty!\n");
+            continue;
+        }
+
+        if(strcmp((const char *)g_row[1], "1") == 0)
+            strcpy(in, "true");
+        else
+            strcpy(in, "false");
+
+        if(strcmp((const char*)g_row[0], "sip") == 0){
+            if (executesql(FAIL2BAN_SIP_IGNORED_SQL)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn);
+            memset(ignored,0,sizeof(ignored));
+            while(d_row = mysql_fetch_row(d_res))
+            {
+                strcat(ignored,(char *)d_row[0]);
+                strcat(ignored,"/");
+                strcat(ignored,(char *)d_row[1]);
+                strcat(ignored," ");
+            }
+            fprintf(conf_fail2ban_fp, "[sip-iptables]\n\
+enabled = %s\n\
+ignoreip = 127.0.0.1/32 %s \n\
+filter = sip\n\
+action = iptables-allports[name=VOIP, protocol=all]\n\
+logpath = /var/log/asterisk/messages\n\
+maxretry = %s\n\
+findtime = %s\n\
+bantime = %s\n\n\
+",\
+in, ignored, g_row[2], g_row[3], g_row[4]
+);
+            mysql_free_result(d_res);
+        }
+        else if(strcmp((const char*)g_row[0], "ssh") == 0)
+        {
+            if (executesql(FAIL2BAN_SSH_IGNORED_SQL)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn);
+            memset(ignored,0,sizeof(ignored));
+            while(d_row = mysql_fetch_row(d_res))
+            {
+                strcat(ignored,(char *)d_row[0]);
+                strcat(ignored,"/");
+                strcat(ignored,(char *)d_row[1]);
+                strcat(ignored," ");
+            }
+            fprintf(conf_fail2ban_fp, "[SSH]\n\
+enabled = %s\n\
+ignoreip = 127.0.0.1/32 %s \n\
+port = 22\n\
+filter = sshd\n\
+logpath = /init/logs/auth.log\n\
+maxretry = %s\n\
+findtime = %s\n\
+bantime = %s\n\n\
+",\
+in, ignored, g_row[2], g_row[3], g_row[4]
+);
+            mysql_free_result(d_res);
+        }
+    }
+    fclose(conf_fail2ban_fp);
+    mysql_free_result(g_res); // 释放结果集
+    mysql_close(g_conn); // 关闭链接
+}

+ 321 - 0
fail2ban_rule.bak.c

@@ -0,0 +1,321 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<strings.h>
+#include<string.h>
+#include<mysql/mysql.h>
+#include<mysql/mysqld_error.h>
+#include<stdarg.h>
+#include<ctype.h>
+#include<sys/types.h>  
+#include<ifaddrs.h>  
+#include<netinet/in.h>   
+#include<arpa/inet.h>  
+#include<net/if.h> 
+#include <sys/ioctl.h> 
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#define CONFIG_FILE "/etc/fail2ban/jail.conf"
+#define DBCONFIG "/etc/asterisk/exten_gen.ini"
+#define NETCONFIG "/etc/rc.conf"
+#define WEBCONFIG "/usr/local/rest-server/config/application.properties"
+#define SIZE 256
+#define SIZE_K 1024
+/*该程序的功能是从数据库中读取fail2ban的配置信息然后写到fail2ban的配置文件中然后重启fail2ban服务使配置生效,界面配置fail2ban的时候调用,需要编译*/
+
+char *getconfig(const char *file_path, const char *name)
+{
+	char str[SIZE] = {0};
+	char *p = NULL, *value = NULL;
+	int tmp = 0, len = 0;
+
+	FILE *fp = fopen(file_path, "r");
+	while(fgets(str, SIZE, fp)){
+		if(strstr(str, name)){
+			p = strstr(str, "=");
+			len = p - str;
+			value = malloc(50);
+			bzero(value, 50);
+			while(str[len] != '\n'){
+				if(str[len] == ' ' || str[len] == '='){
+					len++;
+					continue;
+				}else
+					value[tmp++] = str[len++];
+			}
+			//printf("%s : %s\n",name, value);
+			break;
+		}
+		
+	}
+	return value;
+}
+
+MYSQL *connect_mysql(MYSQL *conn)
+{
+	char *dbserver = getconfig(DBCONFIG, "dbserverip");
+	char *dbuser = getconfig(DBCONFIG, "dbuser");
+	char *dbpasswd = getconfig(DBCONFIG, "dbpasswd");
+	char *dbname = getconfig(DBCONFIG, "dbname");
+	mysql_init(conn);
+	if(!mysql_real_connect(conn, dbserver, dbuser, dbpasswd, dbname,0,"",0)){
+		printf("error:%s\n",mysql_error(conn));	
+		return NULL;
+	}
+	if(dbserver)free(dbserver);
+	if(dbuser)free(dbuser);
+	if(dbpasswd)free(dbpasswd);
+	if(dbname)free(dbname);
+	int utf8;  
+	utf8=mysql_query(conn,"set names utf8");  	
+	return conn;
+}
+
+int netmask_str2len(char* mask)
+{
+    int netmask = 0;
+    unsigned int mask_tmp;
+
+    mask_tmp = ntohl((int)inet_addr(mask));
+    while (mask_tmp & 0x80000000)
+    {
+        netmask++;
+        mask_tmp = (mask_tmp << 1);
+    }
+
+    return netmask;    
+}
+
+char * get_addr(char *addr, int flag, char *dev)
+{
+    int sockfd = 0;  
+    struct sockaddr_in *sin;
+    struct ifreq ifr;
+
+    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    {
+        perror("socket error!\n");
+        return NULL;
+    }
+
+    memset(&ifr, 0, sizeof(ifr));
+    snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", dev);
+
+    if(ioctl(sockfd, flag, &ifr) < 0 )
+    {
+        perror("ioctl error!\n");
+        close(sockfd);
+        return NULL;
+    }
+    close(sockfd);
+
+    sin = (struct sockaddr_in *)&ifr.ifr_addr;
+    snprintf((char *)addr, 32, "%s", inet_ntoa(sin->sin_addr));        
+
+    return addr;
+}
+
+char *get_fb_config(char *buf)
+{
+	MYSQL conn;
+	MYSQL_RES *res;
+	MYSQL_ROW row;
+	MYSQL conn1;
+	MYSQL_RES *res1;
+	MYSQL_ROW row1;
+	char sql[SIZE] = {0};
+	char tmp[SIZE_K*2] = {0};
+	char ignored[SIZE_K*2] = {0};
+	int len1 = 16, len2 = 16, len3 = 16,len4 = 16;
+	char wanip[32] = {0};
+	char lanip[32] = {0};
+	char virip[32] = {0};
+	char virip_lan[32] = {0};
+	char netmask_wan[32] = {0};
+	char netmask_lan[32] = {0};
+	char netmask_vir[32] = {0};
+	char netmask_vir_lan[32] = {0};
+	
+	get_addr(wanip, SIOCGIFADDR,"eth0");
+	get_addr(lanip, SIOCGIFADDR,"eth1");
+	get_addr(virip, SIOCGIFADDR,"eth0:0");
+	get_addr(virip_lan, SIOCGIFADDR,"eth1:0");
+#if 0	
+	get_addr(netmask_wan, SIOCGIFNETMASK,"eth0");
+	get_addr(netmask_lan, SIOCGIFNETMASK,"eth1");
+	get_addr(netmask_vir, SIOCGIFNETMASK,"eth0:0");
+	get_addr(netmask_vir_lan, SIOCGIFNETMASK,"eth1:0");
+	
+	if(strlen(netmask_wan))
+		len1 = netmask_str2len(netmask_wan);
+	
+	if(strlen(netmask_lan))
+		len2 = netmask_str2len(netmask_lan);
+	
+	if(strlen(netmask_vir))
+		len3 = netmask_str2len(netmask_vir);
+	if(strlen(netmask_vir_lan))
+		len4 = netmask_str2len(netmask_vir_lan);
+#endif	
+	/*set default rules*/
+	strcat(buf,"[DEFAULT]\n");
+	strcat(buf,"ignoreip = 127.0.0.1/32\n");
+	strcat(buf,"bantime  = 3600\n");
+	strcat(buf,"maxretry = 3\n");
+	strcat(buf,"backend = auto\n");
+	strcat(buf,"banaction = iptables-multiport\n");
+	strcat(buf,"mta = mail\n");
+	strcat(buf,"protocol = tcp\n");
+	strcat(buf,"chain = INPUT\n");
+	strcat(buf,"action_ = \%(banaction)s[name=\%(__name__)s, port=\"\%(port)s\", protocol=\"\%(protocol)s\", chain=\"\%(chain)s\"]\n");
+	strcat(buf,"action_mw = \%(banaction)s[name=\%(__name__)s, port=\"\%(port)s\", protocol=\"\%(protocol)s\", chain=\"\%(chain)s\"]\n");
+	strcat(buf,"action_mwl = \%(banaction)s[name=\%(__name__)s, port=\"\%(port)s\", protocol=\"\%(protocol)s\", chain=\"\%(chain)s\"]\n");
+	strcat(buf,"action = \%(action_)s\n\n");
+
+	MYSQL *conn_mysql = &conn;
+	if(!connect_mysql(conn_mysql))
+		return 0;
+
+	sprintf(sql, "select name,enable,max_retry,find_time,ban_time from t_fail2ban_basic");
+	if(mysql_real_query(conn_mysql, sql, strlen(sql))){
+		printf("select  data from table t_fail2ban_basic faild !\n");
+		return 0;
+	}
+	res = mysql_store_result(conn_mysql);
+
+	char in[10] = {0};
+
+	MYSQL *conn_mysql1 = &conn1;
+	if(!connect_mysql(conn_mysql1))
+		return 0;
+
+	while(row = mysql_fetch_row(res))
+	{
+		bzero(in, 10);
+		bzero(tmp,strlen(tmp));
+		bzero(ignored,strlen(ignored));
+		if(!strcmp((const char *)row[1], "1"))
+			strcpy(in, "true");
+		else
+			strcpy(in, "false");
+		
+		if(strlen(virip) && strlen(virip_lan))
+			sprintf(ignored,"%s/%d %s/%d %s/%d %s/%d ",wanip,len1, lanip,len2,virip,len3,virip_lan,len4);
+		else if(strlen(virip))
+			sprintf(ignored,"%s/%d %s/%d %s/%d ",wanip,len1, lanip,len2,virip,len3);
+		else if(strlen(virip_lan))
+			sprintf(ignored,"%s/%d %s/%d %s/%d ",wanip,len1, lanip,len2,virip_lan,len4);
+		else
+			sprintf(ignored,"%s/%d %s/%d ",wanip,len1, lanip,len2);
+		
+		if(!strcmp((const char*)row[0], "sip")){
+			bzero(sql,strlen(sql));
+			sprintf(sql, "select ip,netmask_length from t_fail2ban_ignored where protocol_sip='1' and enable='1'");
+			if(mysql_real_query(conn_mysql1, sql, strlen(sql))){
+				printf("select  data from table t_fail2ban_ignored faild !\n");
+				return 0;
+			}
+			res1 = mysql_store_result(conn_mysql1);
+			while(row1 = mysql_fetch_row(res1))
+			{
+				strcat(ignored,(char *)row1[0]);
+				strcat(ignored,"/");
+				strcat(ignored,(char *)row1[1]);
+				strcat(ignored," ");
+			}
+			
+			sprintf(tmp,"[sip-iptables]\nenabled = %s\nignoreip = 127.0.0.1/32 %s \nfilter = sip\naction = iptables-allports[name=VOIP, protocol=all]\nlogpath = /var/log/asterisk/messages\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n", in, ignored, row[2], row[3], row[4]);
+			mysql_free_result(res1);
+		}
+		else if(!strcmp((const char*)row[0], "ssh")){
+			bzero(sql,strlen(sql));
+			sprintf(sql, "select ip,netmask_length from t_fail2ban_ignored where protocol_ssh='1' and enable='1'");
+			if(mysql_real_query(conn_mysql1, sql, strlen(sql))){
+				printf("select  data from table t_fail2ban_ignored faild !\n");
+				return 0;
+			}
+			res1 = mysql_store_result(conn_mysql1);
+			while(row1 = mysql_fetch_row(res1))
+			{
+				strcat(ignored,(char *)row1[0]);
+				strcat(ignored,"/");
+				strcat(ignored,(char *)row1[1]);
+				strcat(ignored," ");
+			}
+			char *sshport = getconfig("/etc/asterisk/service.conf","ssh_port");
+			sprintf(tmp,"[SSH]\nenabled = %s\nignoreip = 127.0.0.1/32 %s \nport = %s\nfilter = sshd\nlogpath = /var/log/auth.log\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n",in, ignored, sshport, row[2], row[3], row[4]);
+			free(sshport);
+			mysql_free_result(res1);
+		}
+		else if(!strcmp((const char*)row[0], "https")){
+		#if 1
+			bzero(sql,strlen(sql));
+			sprintf(sql, "select ip,netmask_length from t_fail2ban_ignored where protocol_https='1' and enable='1'");
+			if(mysql_real_query(conn_mysql1, sql, strlen(sql))){
+				printf("select  data from table t_fail2ban_ignored faild !\n");
+				return 0;
+			}
+			res1 = mysql_store_result(conn_mysql1);
+			while(row1 = mysql_fetch_row(res1))
+			{
+				strcat(ignored,(char *)row1[0]);
+				strcat(ignored,"/");
+				strcat(ignored,(char *)row1[1]);
+				strcat(ignored," ");
+			}
+			char *web_port=getconfig(WEBCONFIG, "server.port");
+			sprintf(tmp,"[HTTPS]\nenabled = %s\nignoreip = 127.0.0.1/32 %s \nport = %s\nfilter = https\nlogpath = /var/log/invalid_web_visit.log\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n",in, ignored, web_port, row[2], row[3], row[4]);
+			free(web_port);
+			mysql_free_result(res1);
+		#endif
+		}
+		else if(!strcmp((const char*)row[0], "iax")){
+			bzero(sql,strlen(sql));
+			sprintf(sql, "select ip,netmask_length from t_fail2ban_ignored where protocol_iax='1' and enable='1'");
+			if(mysql_real_query(conn_mysql1, sql, strlen(sql))){
+				printf("select  data from table t_fail2ban_ignored faild !\n");
+				return 0;
+			}
+			res1 = mysql_store_result(conn_mysql1);
+			while(row1 = mysql_fetch_row(res1))
+			{
+				strcat(ignored,(char *)row1[0]);
+				strcat(ignored,"/");
+				strcat(ignored,(char *)row1[1]);
+				strcat(ignored," ");
+			}
+			sprintf(tmp, "[iax-iptables]\nenabled = %s\nignoreip = 127.0.0.1/32 %s\nfilter = iax2\naction = iptables-allports[name=VOIP, protocol=all]\nlogpath = /var/log/asterisk/messages\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n", in, ignored, row[2], row[3], row[4]);
+			mysql_free_result(res1);
+		}
+		strcat(buf,tmp);
+	}
+	
+	mysql_free_result(res);
+	mysql_close(conn_mysql);
+	mysql_close(conn_mysql1);
+
+	return buf;
+}
+
+
+int main(int argc, char *argv[])
+{
+	char buf[SIZE_K*8]={0};
+	char cmd[SIZE] = {0};
+	FILE *fp = NULL;
+
+#if 1	
+	get_fb_config(buf);
+	printf("%s",buf);
+	fp = fopen(CONFIG_FILE, "w");
+	if(strlen(buf))
+		fputs(buf, fp);
+	fclose(fp);
+	
+	sprintf(cmd,"echo \"\" > /var/log/auth.log;echo \"\" > /var/log/fail2ban.log ;echo \"\" >/var/log/invalid_web_visit.log;echo \"\" > /var/log/asterisk/messages;asterisk -rx \"logger reload\";service fail2ban restart");
+
+	system(cmd);
+#endif
+	return 0;
+}
+

+ 292 - 0
fail2ban_rule.c

@@ -0,0 +1,292 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<strings.h>
+#include<string.h>
+#include<mysql/mysql.h>
+#include<mysql/mysqld_error.h>
+#include<stdarg.h>
+#include<ctype.h>
+#include<sys/types.h>  
+#include<ifaddrs.h>  
+#include<netinet/in.h>   
+#include<arpa/inet.h>  
+#include<net/if.h> 
+#include <sys/ioctl.h> 
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define CONFIG_FILE "/etc/fail2ban/jail.conf"
+#define DBCONFIG "/etc/asterisk/exten_gen.ini"
+#define NETCONFIG "/etc/rc.conf"
+#define WEBCONFIG "/usr/local/rest-server/config/application.properties"
+#define SIZE 256
+#define SIZE_K 1024
+/*该程序的功能是从数据库中读取fail2ban的配置信息然后写到fail2ban的配置文件中然后重启fail2ban服务使配置生效,界面配置fail2ban的时候调用,需要编译*/
+
+char *getconfig(const char *file_path, const char *name)
+{
+	char str[SIZE] = {0};
+	char *p = NULL, *value = NULL;
+	int tmp = 0, len = 0;
+
+	FILE *fp = fopen(file_path, "r");
+	while(fgets(str, SIZE, fp)){
+		if(strstr(str, name)){
+			p = strstr(str, "=");
+			len = p - str;
+			value = malloc(50);
+			bzero(value, 50);
+			while(str[len] != '\n'){
+				if(str[len] == ' ' || str[len] == '='){
+					len++;
+					continue;
+				}else
+					value[tmp++] = str[len++];
+			}
+			//printf("%s : %s\n",name, value);
+			break;
+		}
+		
+	}
+	return value;
+}
+
+int connect_mysql(MYSQL *conn)
+{
+	//char *dbserver = getconfig(DBCONFIG, "dbserverip");
+	//char *dbuser = getconfig(DBCONFIG, "dbuser");
+	//char *dbpasswd = getconfig(DBCONFIG, "dbpasswd");
+	//char *dbname = getconfig(DBCONFIG, "dbname");
+	char dbserver[64];
+	char dbuser[64];
+	char dbpasswd[64];
+	char dbname[64];
+	unsigned int dbport = 3306;
+
+	strcpy(dbserver,getenv("MYSQL"));
+	strcpy(dbuser,getenv("MYSQL_USER"));
+	strcpy(dbpasswd,getenv("MYSQL_PASSWORD"));
+	strcpy(dbname,getenv("MYSQL_DATABASE"));
+
+	printf("connect---1\n");
+	conn = mysql_init(NULL);
+	printf("connect---2\n");
+	if(!mysql_real_connect(conn, dbserver, dbuser, dbpasswd, dbname,dbport,NULL,0)){
+		printf("error:%s\n",mysql_error(conn));	
+		return -1;
+	}
+	// 是否连接已经可用
+	if (mysql_query(conn,"set names utf8")) // 如果失败
+		return -1;
+	printf("connect---3\n");
+	return 0;
+}
+
+int netmask_str2len(char* mask)
+{
+    int netmask = 0;
+    unsigned int mask_tmp;
+
+    mask_tmp = ntohl((int)inet_addr(mask));
+    while (mask_tmp & 0x80000000)
+    {
+        netmask++;
+        mask_tmp = (mask_tmp << 1);
+    }
+
+    return netmask;    
+}
+
+char * get_addr(char *addr, int flag, char *dev)
+{
+    int sockfd = 0;  
+    struct sockaddr_in *sin;
+    struct ifreq ifr;
+
+    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    {
+        perror("socket error!\n");
+        return NULL;
+    }
+
+    memset(&ifr, 0, sizeof(ifr));
+    snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", dev);
+
+    if(ioctl(sockfd, flag, &ifr) < 0 )
+    {
+        perror("ioctl error!\n");
+        close(sockfd);
+        return NULL;
+    }
+    close(sockfd);
+
+    sin = (struct sockaddr_in *)&ifr.ifr_addr;
+    snprintf((char *)addr, 32, "%s", inet_ntoa(sin->sin_addr));        
+
+    return addr;
+}
+
+char *get_fb_config(char *buf)
+{
+	MYSQL *conn;
+	MYSQL_RES *res;
+	MYSQL_ROW row;
+	MYSQL_RES *res1;
+	MYSQL_ROW row1;
+	char sql[SIZE] = {0};
+	char tmp[SIZE_K*3] = {0};
+	char ignored[SIZE_K*2] = {0};
+	int len1 = 16, len2 = 16, len3 = 16,len4 = 16;
+/*
+	char wanip[32] = {0};
+	char lanip[32] = {0};
+	char virip[32] = {0};
+	char virip_lan[32] = {0};
+	char netmask_wan[32] = {0};
+	char netmask_lan[32] = {0};
+	char netmask_vir[32] = {0};
+	char netmask_vir_lan[32] = {0};
+	
+	get_addr(wanip, SIOCGIFADDR,"eth0");
+	get_addr(lanip, SIOCGIFADDR,"eth1");
+	get_addr(virip, SIOCGIFADDR,"eth0:0");
+	get_addr(virip_lan, SIOCGIFADDR,"eth1:0");
+	get_addr(netmask_wan, SIOCGIFNETMASK,"eth0");
+	get_addr(netmask_lan, SIOCGIFNETMASK,"eth1");
+	get_addr(netmask_vir, SIOCGIFNETMASK,"eth0:0");
+	get_addr(netmask_vir_lan, SIOCGIFNETMASK,"eth1:0");
+	
+	if(strlen(netmask_wan))
+		len1 = netmask_str2len(netmask_wan);
+	
+	if(strlen(netmask_lan))
+		len2 = netmask_str2len(netmask_lan);
+	
+	if(strlen(netmask_vir))
+		len3 = netmask_str2len(netmask_vir);
+	if(strlen(netmask_vir_lan))
+		len4 = netmask_str2len(netmask_vir_lan);
+*/
+	/*set default rules
+	strcat(buf,"[DEFAULT]\n");
+	strcat(buf,"ignoreip = 127.0.0.1/32\n");
+	strcat(buf,"bantime  = 3600\n");
+	strcat(buf,"maxretry = 3\n");
+	strcat(buf,"backend = auto\n");
+	strcat(buf,"banaction = iptables-multiport\n");
+	strcat(buf,"mta = mail\n");
+	strcat(buf,"protocol = tcp\n");
+	strcat(buf,"chain = INPUT\n");
+	strcat(buf,"action_ = \%(banaction)s[name=\%(__name__)s, port=\"\%(port)s\", protocol=\"\%(protocol)s\", chain=\"\%(chain)s\"]\n");
+	strcat(buf,"action_mw = \%(banaction)s[name=\%(__name__)s, port=\"\%(port)s\", protocol=\"\%(protocol)s\", chain=\"\%(chain)s\"]\n");
+	strcat(buf,"action_mwl = \%(banaction)s[name=\%(__name__)s, port=\"\%(port)s\", protocol=\"\%(protocol)s\", chain=\"\%(chain)s\"]\n");
+	strcat(buf,"action = \%(action_)s\n\n");
+*/
+	printf("connect mysql!\n");
+	if(connect_mysql(conn))
+		return 0;
+
+	sprintf(sql, "select name,enable,max_retry,find_time,ban_time from t_pbx_fail2ban_basic");
+	if(mysql_real_query(conn, sql, strlen(sql))){
+		printf("select  data from table t_pbx_fail2ban_basic faild !\n");
+		return 0;
+	}
+	printf("sql result for '%s'!\n", sql);
+	res = mysql_store_result(conn);
+
+	char in[10] = {0};
+
+	while(row = mysql_fetch_row(res))
+	{
+		printf("datainfo %s,%s,%s,%s,%s !\n", row[0], row[1], row[2], row[3], row[4]);
+		bzero(in, 10);
+		bzero(tmp,strlen(tmp));
+		bzero(ignored,strlen(ignored));
+		if(!strcmp((const char *)row[1], "1"))
+			strcpy(in, "true");
+		else
+			strcpy(in, "false");
+		
+		/*
+		if(strlen(virip) && strlen(virip_lan))
+			sprintf(ignored,"%s/%d %s/%d %s/%d %s/%d ",wanip,len1, lanip,len2,virip,len3,virip_lan,len4);
+		else if(strlen(virip))
+			sprintf(ignored,"%s/%d %s/%d %s/%d ",wanip,len1, lanip,len2,virip,len3);
+		else if(strlen(virip_lan))
+			sprintf(ignored,"%s/%d %s/%d %s/%d ",wanip,len1, lanip,len2,virip_lan,len4);
+		else
+			sprintf(ignored,"%s/%d %s/%d ",wanip,len1, lanip,len2);
+		*/
+		if(!strcmp((const char*)row[0], "sip")){
+			bzero(sql,strlen(sql));
+			sprintf(sql, "select ip,netmask_length from t_pbx_fail2ban_ignored where protocol_sip='1' and enable='1'");
+			if(mysql_real_query(conn, sql, strlen(sql))){
+				printf("select  data from table t_pbx_fail2ban_ignored faild !\n");
+				return 0;
+			}
+			printf("sql result for '%s'!\n", sql);
+			res1 = mysql_store_result(conn);
+			while(row1 = mysql_fetch_row(res1))
+			{
+				strcat(ignored,(char *)row1[0]);
+				strcat(ignored,"/");
+				strcat(ignored,(char *)row1[1]);
+				strcat(ignored," ");
+			}
+			
+			sprintf(tmp,"[sip-iptables]\nenabled = %s\nignoreip = 127.0.0.1/32 %s \nfilter = sip\naction = iptables-allports[name=VOIP, protocol=all]\nlogpath = /var/log/asterisk/messages\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n", in, ignored, row[2], row[3], row[4]);
+			mysql_free_result(res1);
+		}
+		else if(!strcmp((const char*)row[0], "ssh")){
+			bzero(sql,strlen(sql));
+			sprintf(sql, "select ip,netmask_length from t_fail2ban_ignored where protocol_ssh='1' and enable='1'");
+			if(mysql_real_query(conn, sql, strlen(sql))){
+				printf("select  data from table t_fail2ban_ignored faild !\n");
+				return 0;
+			}
+			res1 = mysql_store_result(conn);
+			while(row1 = mysql_fetch_row(res1))
+			{
+				strcat(ignored,(char *)row1[0]);
+				strcat(ignored,"/");
+				strcat(ignored,(char *)row1[1]);
+				strcat(ignored," ");
+			}
+			//char *sshport = getconfig("/etc/asterisk/service.conf","ssh_port");
+			sprintf(tmp,"[SSH]\nenabled = %s\nignoreip = 127.0.0.1/32 %s \nport = 22\nfilter = sshd\nlogpath = /var/log/auth.log\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n",in, ignored, row[2], row[3], row[4]);
+			//sprintf(tmp,"[SSH]\nenabled = %s\nignoreip = 127.0.0.1/32 %s \nport = %s\nfilter = sshd\nlogpath = /var/log/auth.log\nmaxretry = %s\nfindtime = %s\nbantime = %s\n\n",in, ignored, sshport, row[2], row[3], row[4]);
+			//free(sshport);
+			mysql_free_result(res1);
+		}
+		strcat(buf,tmp);
+	}
+	
+	mysql_free_result(res);
+	mysql_close(conn);
+
+	return buf;
+}
+
+
+int main(int argc, char *argv[])
+{
+	char buf[SIZE_K*8]={0};
+	char cmd[SIZE] = {0};
+	FILE *fp = NULL;
+
+#if 1	
+	get_fb_config(buf);
+	printf("%s",buf);
+	fp = fopen(CONFIG_FILE, "w");
+	if(strlen(buf))
+		fputs(buf, fp);
+	fclose(fp);
+	
+	sprintf(cmd,"echo \"\" > /var/log/auth.log;echo \"\" > /var/log/fail2ban.log ;echo \"\" >/var/log/invalid_web_visit.log;echo \"\" > /var/log/asterisk/messages;asterisk -rx \"logger reload\";service fail2ban restart");
+
+	system(cmd);
+#endif
+	return 0;
+}
+

+ 475 - 0
generate_context_conf.c

@@ -0,0 +1,475 @@
+/*
+============================================================================
+Name        : generate_context_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate context info from mysql to context conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <cjson/cJSON.h>
+
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql intercom记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql phone记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+
+#define MAX_TRUNK_SIZE 256
+#define MAX_SIZE 1024
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define MYSQL_CONNECT_CONF "/etc/asterisk/exten_gen.ini"
+#define EXTEN_CONTEXT_FILE "/etc/asterisk/extensions_context_custom.conf"
+#define EXTEN_USERS_CONTEXT_FILE "/etc/asterisk/extensions_users_context_custom.conf"
+#define EXTEN_USERS_GLOBAL_FILE "/etc/asterisk/extensions_users_global_custom.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define QUERY_INTERCOM_SQL "select id,exten from t_paging_devices where type_id in('2','5')"
+#define QUERY_IPPHONE_SQL "select id,exten,user_id from t_paging_devices where type_id in('3','6')"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+char sql_tmp[MAX_SIZE];
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+
+int main(int argc, char **argv) {
+/*
+memset(g_host_name, 0, sizeof(g_host_name));
+memset(g_user_name, 0, sizeof(g_user_name));
+memset(g_password, 0, sizeof(g_password));
+memset(g_db_name, 0, sizeof(g_db_name));
+
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbserverip", g_host_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbuser", g_user_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbpasswd", g_password);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbname", g_db_name);
+*/
+strcpy(g_host_name,getenv("MYSQL"));
+strcpy(g_user_name,getenv("MYSQL_USER"));
+strcpy(g_password,getenv("MYSQL_PASSWORD"));
+strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+
+FILE *conf_fp = fopen(EXTEN_CONTEXT_FILE, "w+");
+FILE *conf_users_fp = fopen(EXTEN_USERS_CONTEXT_FILE, "w+");
+FILE *global_fp = fopen(EXTEN_USERS_GLOBAL_FILE, "w+");
+
+if (conf_fp == NULL){
+        perror("Open context conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(conf_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_context_custom.conf (/etc/asterisk/extensions_context_custom.conf)\n\
+;! Generator: Generator Context\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_users_fp == NULL){
+        perror("Open context conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(conf_users_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_users_context_custom.conf (/etc/asterisk/extensions_users_context_custom.conf)\n\
+;! Generator: Generator User Context\n\
+;! Creation Date: %s\n\
+;!\n\n\
+[DialRule_users]\n\
+",\
+mytime()\
+);
+
+if (global_fp == NULL){
+        perror("Open context conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(global_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_users_global_custom.conf (/etc/asterisk/extensions_users_global_custom.conf)\n\
+;! Generator: Generator User Global\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+    if (init_mysql()){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    //将所有类型为对讲终端的设备赋予所在group的权限。
+    if (executesql(QUERY_INTERCOM_SQL)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+
+    g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    
+    while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+        if (g_row[0] == NULL || g_row[1] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+        int setout = 1;
+        fprintf(conf_fp, "[DialRule_%s]\n",g_row[1]);
+        fprintf(conf_fp, "include => cdr-action\n");
+        fprintf(conf_fp, "include => call-trigger\n");
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        //获取对讲终端所在队列的号码
+        sprintf(sql_tmp,"select exten from t_paging_deviceGroups JOIN t_paging_groups on t_paging_groups.id = t_paging_deviceGroups.GroupId where DeviceId = %s",g_row[0]);
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+        d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+        while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+            if (d_row[0] == NULL){
+                printf("some feild is empty!\n");
+                continue;
+            }
+            fprintf(conf_fp, "include => extens-group-%s\n", d_row[0]);
+            fprintf(conf_fp, "include => phones-group-%s\n", d_row[0]);
+        }
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        //获取对讲终端所在队列的管理员ID
+        sprintf(sql_tmp,"select UserId from t_paging_deviceGroups JOIN t_paging_userGroups on t_paging_deviceGroups.GroupId = t_paging_userGroups.GroupId where DeviceId = %s group by UserId",g_row[0]);
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+        d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+        while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+            if (d_row[0] == NULL){
+                printf("some feild is empty!\n");
+                continue;
+            }
+            int q = 100000 + atoi(d_row[0]);
+            fprintf(conf_fp, "include => manager-queue-%d\n", q);
+        }
+
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        sprintf(sql_tmp,"select exten from t_paging_groups JOIN t_paging_userGroups on\
+        t_paging_groups.id = t_paging_userGroups.GroupId where t_paging_userGroups.UserId\
+        in(select UserId from t_paging_deviceGroups JOIN t_paging_userGroups on\
+        t_paging_deviceGroups.GroupId = t_paging_userGroups.GroupId where DeviceId = %s) group by exten",g_row[0]);
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+        d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+        while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+            if (d_row[0] == NULL){
+                printf("some feild is empty!\n");
+                continue;
+            }
+            fprintf(conf_fp, "include => paging-group-%s\n", d_row[0]);
+        }
+
+    }
+
+    //IP话机根据所绑定的用户赋予所在group的权限。
+    if (executesql(QUERY_IPPHONE_SQL)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    
+    g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    
+    while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+        if (g_row[0] == NULL || g_row[1] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+        int setout = 1;
+        fprintf(conf_fp, "[DialRule_%s]\n",g_row[1]);
+        fprintf(conf_fp, "include => cdr-action\n");
+        fprintf(conf_fp, "include => featurecodes\n");
+        
+        //获取对讲终端所在队列的号码
+        memset(sql_tmp,0,sizeof(sql_tmp));
+        sprintf(sql_tmp,"select exten from t_paging_deviceGroups JOIN t_paging_groups on t_paging_groups.id = t_paging_deviceGroups.GroupId where DeviceId = %s",g_row[0]);
+        if (executesql(sql_tmp)){
+            print_mysql_error(NULL);
+            exit(1);
+        }
+        d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+        while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+            if (d_row[0] == NULL){
+                printf("some feild is empty!\n");
+                continue;
+            }
+            fprintf(conf_fp, "include => phones-group-%s\n", d_row[0]);
+            fprintf(conf_fp, "include => paging-group-%s\n", d_row[0]);
+        }
+        if(g_row[2]){
+            memset(sql_tmp,0,sizeof(sql_tmp));
+            sprintf(sql_tmp,"select t_paging_users.id,t_paging_users.level from t_paging_users join t_paging_devices on t_paging_users.id = t_paging_devices.user_id\
+            where t_paging_devices.exten=%s",g_row[1]);     //查询分机号所属的用户ID和等级
+            if (executesql(sql_tmp)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+            while((d_row=mysql_fetch_row(d_res))){
+                if (d_row[0] == NULL || d_row[1] == NULL){
+                    printf("some feild is empty!\n");
+                    continue;
+                }
+                fprintf(conf_fp, "include => DialRule_users\n");
+                fprintf(conf_users_fp, "exten => %s,1,Macro(stdexten,%s,SIP/%s)\n",g_row[1],g_row[1],g_row[1]);
+                fprintf(global_fp, "USER_ID_%s = %s\n",g_row[1],d_row[0]);
+                fprintf(global_fp, "USER_LEVEL_%s = %s\n",g_row[1],d_row[1]);
+            }
+            memset(sql_tmp,0,sizeof(sql_tmp));
+            sprintf(sql_tmp,"select exten,t_paging_userServices.tPagingServiceId as service_id from t_paging_groups\
+            JOIN t_paging_userGroups on t_paging_groups.id = t_paging_userGroups.GroupId\
+            JOIN t_paging_userServices on t_paging_userServices.UserId = t_paging_userGroups.UserId\
+            where t_paging_userServices.tPagingServiceId in(1,4,7,9) and t_paging_userGroups.UserId\
+            in(select t_paging_users.id from t_paging_users join t_paging_devices on t_paging_users.id = t_paging_devices.user_id\
+            where t_paging_devices.exten=%s) order by t_paging_userServices.tPagingServiceId",g_row[1]);        //查询分机所属管理员的权限以及所管理的组
+            if (executesql(sql_tmp)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+            while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+                if (d_row[0] == NULL || d_row[1] == NULL){
+                    printf("some feild is empty!\n");
+                    continue;
+                }
+                int id = atoi(d_row[1]);
+                switch(id){
+                    case 1:
+                        fprintf(conf_fp, "include => paging-group-%s\n", d_row[0]);
+                        break;
+                    case 4:
+                        fprintf(conf_fp, "include => extens-group-%s\n", d_row[0]);
+                        break;
+                    case 7:
+                        fprintf(conf_fp, "include => call-trigger\n");
+                        break;
+                    case 9:
+                        if(setout){
+                            fprintf(conf_fp, "include => CallingRule_OutCall\n");
+                            setout = 0;
+                        }
+                        break;
+                }
+            }
+        }else{
+            memset(sql_tmp,0,sizeof(sql_tmp));
+            sprintf(sql_tmp,"select UserId from t_paging_deviceGroups JOIN t_paging_userGroups on t_paging_deviceGroups.GroupId = t_paging_userGroups.GroupId where DeviceId = %s group by UserId",g_row[0]);
+            if (executesql(sql_tmp)){
+                print_mysql_error(NULL);
+                exit(1);
+            }
+            d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+            while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+                if (d_row[0] == NULL){
+                    printf("some feild is empty!\n");
+                    continue;
+                }
+                int q = 100000 + atoi(d_row[0]);
+                fprintf(conf_fp, "include => manager-queue-%d\n", q);
+            }
+        }
+        
+    }
+fclose(conf_fp);
+fclose(conf_users_fp);
+fclose(global_fp);
+mysql_free_result(g_res); // 释放结果集
+mysql_free_result(d_res); // 释放结果集
+mysql_close(g_conn); // 关闭链接
+}

+ 888 - 0
generate_extension_conf.c

@@ -0,0 +1,888 @@
+/*
+============================================================================
+Name        : generate_trunk_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate trunk info from mysql to turnk conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <cjson/cJSON.h>
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql 记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define MYSQL_CONNECT_CONF "/etc/asterisk/exten_gen.ini"
+#define EXTEN_IVR_FILE "/etc/asterisk/extensions_ivr_custom.conf"
+#define EXTEN_DIALRULE_FILE "/etc/asterisk/extensions_dialrule_custom.conf"
+#define EXTEN_INBOUND_FILE "/etc/asterisk/extensions_inbound_custom.conf"
+#define EXTEN_GLOBAL_FILE "/etc/asterisk/extensions_global_custom.conf"
+#define EXTEN_CALLTRIGGER_FILE "/etc/asterisk/extensions_call_trigger_custom.conf"
+#define EXTEN_FEATURECODES_FILE "/etc/asterisk/extensions_featurecodes_custom.conf"
+#define SIP_NAT_FILE "/etc/asterisk/sip_nat.conf"
+#define SIP_SETTINGS_FILE "/etc/asterisk/sip_settings.conf"
+#define RTP_SETTINGS_FILE "/etc/asterisk/rtp_settings.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define QUERY_IVR_SQL "select name,exten,prompt,loops,timeout,language,dialplan,keys_action from t_pbx_ivr"
+#define QUERY_DIALRULE_SQL "select t_pbx_users_voiptrunk.trunk as trunk,rule,del_prefix,add_before,add_after from t_pbx_dialrule join t_pbx_users_voiptrunk on t_pbx_users_voiptrunk.id=t_pbx_dialrule.trunk_id"
+#define QUERY_GLOBAL_SQL "select * from t_global_config"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+char dialrule[MIDLE_SIZE];
+char ivrstr[MAX_SIZE];
+char inboundstr[MIDLE_SIZE];
+char prompt[MINI_SIZE];
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+/*   删除右边的空格   */
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+/*   删除两边的空格   */
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+int main(int argc, char **argv) {
+cJSON *pJson,*pSub;
+int iCount=0;
+
+typedef struct keys_action {
+    char key[MINI_SIZE];
+    char type[MINI_SIZE];
+    char exten[MINI_SIZE];
+} KeysObject;
+
+strcpy(g_host_name,getenv("MYSQL"));
+strcpy(g_user_name,getenv("MYSQL_USER"));
+strcpy(g_password,getenv("MYSQL_PASSWORD"));
+strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+
+if (init_mysql()){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+//读取自动话务员的数据,并写入配置文件
+if (executesql(QUERY_IVR_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_ivr_fp = fopen(EXTEN_IVR_FILE, "w+");
+
+if (conf_ivr_fp == NULL){
+        perror("Open paging conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(conf_ivr_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_ivr_custom.conf (/etc/asterisk/extensions_ivr_custom.conf)\n\
+;! Generator: Generator IVR\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+//name:g_row[0],exten:g_row[1],prompt:g_row[2],loops:g_row[3],timeout:g_row[4],language:g_row[5],dialplan:g_row[6],keys_action
+//+----+--------------+-------+---------------------------------------+-------+---------+----------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+
+//| id | name         | exten | prompt                                | loops | timeout | language | dialplan | keys_action                                                                                                                                    | createdAt           | updatedAt           |
+//+----+--------------+-------+---------------------------------------+-------+---------+----------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+
+//|  1 | 上班时间      | 6500  | /etc/asterisk/sysconf/prompts/welcome |     1 |       3 | NULL     | default  | [{"key": "i", "type": "hangup", "exten": ""}, {"key": "t", "type": "hangup", "exten": ""}, {"key": "0", "type": "extension", "exten": "8001"}] | 2019-07-31 17:58:00 | 2019-08-05 01:30:48 |
+//|  2 | 下班时间      | 6501  | /etc/asterisk/sysconf/prompts/closed  |     1 |       3 | NULL     | default  | [{"key": "i", "type": "hangup", "exten": ""}, {"key": "t", "type": "hangup", "exten": ""}]                                                     | 2019-07-31 17:58:00 | 2019-08-06 01:30:24 |
+//|  4 | test         | 6505  | /etc/asterisk/sysconf/prompts/welcome |     1 |       3 | NULL     | default  | [{"key": "i", "type": "hangup", "exten": ""}, {"key": "t", "type": "hangup", "exten": ""}, {"key": "1", "type": "extension", "exten": "8500"}] | 2019-08-05 01:33:58 | 2019-08-05 13:02:10 |
+//+----+--------------+-------+---------------------------------------+-------+---------+----------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+
+//3 rows in set (0.00 sec)
+while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+    if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL){
+        printf("some feild is empty!\n");
+        continue;
+    }
+    fprintf(conf_ivr_fp,"\
+[voicemenu-custom-%s]\n\
+include => %s\n\
+exten => %s,1,NoOp(%s)\n",\
+g_row[1],\
+g_row[6],\
+g_row[1],\
+g_row[0]\
+    );
+    if(g_row[5] != NULL){
+        fprintf(conf_ivr_fp,"same => n,Set(CHANNEL(language)=%s)\n",g_row[5]);
+    }
+    memset(prompt, 0, sizeof(prompt));
+    strncpy(prompt,g_row[2],strlen(g_row[2])-4);
+    fprintf(conf_ivr_fp,"\
+same => n,Set(COUNT=%s)\n\
+same => n(loop),Background(%s)\n",\
+g_row[3],\
+prompt
+    );
+    if(strcmp(g_row[4], "0") != 0 && g_row[4] != NULL){
+        fprintf(conf_ivr_fp,"same => n,WaitExten(%s)\n",g_row[4]);
+    }
+    fprintf(conf_ivr_fp,"\
+same => n,Set(COUNT=$[${COUNT}-1])\n\
+same => n,GotoIf($[${COUNT} < 0]?:loop)\n\
+same => n,WaitExten(1)\n");
+    KeysObject keysObject[MINI_SIZE];
+    memset(keysObject, 0, sizeof(keysObject));
+    if(g_row[7] != NULL){
+        pJson = cJSON_Parse(g_row[7]);
+        iCount = cJSON_GetArraySize(pJson);
+        for(int i = 0;i < iCount;i++){
+            pSub = cJSON_GetArrayItem(pJson,i);
+            if(pSub != NULL){
+                strcpy(keysObject[i].key,cJSON_GetObjectItem(pSub, "key")->valuestring);
+                strcpy(keysObject[i].type,cJSON_GetObjectItem(pSub, "type")->valuestring);
+                strcpy(keysObject[i].exten,cJSON_GetObjectItem(pSub, "exten")->valuestring);
+                if(strcmp(keysObject[i].type, "hangup") == 0){
+                    fprintf(conf_ivr_fp,"exten => %s,1,Hangup()\n",keysObject[i].key);
+                }
+                else if(strcmp(keysObject[i].type, "extension") == 0){
+                    fprintf(conf_ivr_fp,"exten => %s,1,Goto(default,%s,1)\n",keysObject[i].key,keysObject[i].exten);
+                }
+                else if(strcmp(keysObject[i].type, "ivr") == 0){
+                    fprintf(conf_ivr_fp,"exten => %s,1,Goto(voicemenu-custom-%s,%s,1)\n",keysObject[i].key,keysObject[i].exten,keysObject[i].exten);
+                }
+                else if(strcmp(keysObject[i].type, "group") == 0){
+                    fprintf(conf_ivr_fp,"exten => %s,1,Goto(paging-group-%s,%s,1)\n",keysObject[i].key,keysObject[i].exten,keysObject[i].exten);
+                }
+                else if(strcmp(keysObject[i].type, "user") == 0){
+                    int id = 100000 + atoi(keysObject[i].exten);
+                    fprintf(conf_ivr_fp,"exten => %s,1,Goto(manager-queue-%d,s,1)\n",keysObject[i].key,id);
+                }
+            }
+        }
+    }
+    fprintf(conf_ivr_fp,"\n\n");
+}
+/*
+while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+    if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL){
+        printf("some feild is empty!\n");
+        continue;
+    }
+    sprintf(ivrstr,"\
+[voicemenu-custom-%s]\n\
+include => %s\n\
+exten => %s,1,NoOp(%s)",\
+g_row[1],\
+g_row[6],\
+g_row[1],\
+g_row[0]\
+    );
+    if(g_row[5] != NULL){
+        sprintf(ivrstr,"%s\nsame => n,Set(CHANNEL(language)=%s)",ivrstr,g_row[5]);
+    }
+    memset(prompt, 0, sizeof(prompt));
+    strncpy(prompt,g_row[2],strlen(g_row[2])-4);
+    sprintf(ivrstr,"%s\n\
+same => n,Set(COUNT=%s)\n\
+same => n(loop),Background(%s)",ivrstr,\
+g_row[3],\
+prompt
+    );
+    if(strcmp(g_row[4], "0") != 0 && g_row[4] != NULL){
+        sprintf(ivrstr,"%s\nsame => n,WaitExten(%s)",ivrstr,g_row[4]);
+    }
+    sprintf(ivrstr,"%s\n\
+same => n,Set(COUNT=$[${COUNT}-1])\n\
+same => n,GotoIf($[${COUNT} < 0]?:loop)\n\
+same => n,WaitExten(1)",ivrstr
+    );
+    KeysObject keysObject[MINI_SIZE];
+    memset(keysObject, 0, sizeof(keysObject));
+    if(g_row[7] != NULL){
+        pJson = cJSON_Parse(g_row[7]);
+        iCount = cJSON_GetArraySize(pJson);
+        for(int i = 0;i < iCount;i++){
+            pSub = cJSON_GetArrayItem(pJson,i);
+            if(pSub != NULL){
+                strcpy(keysObject[i].key,cJSON_GetObjectItem(pSub, "key")->valuestring);
+                strcpy(keysObject[i].type,cJSON_GetObjectItem(pSub, "type")->valuestring);
+                strcpy(keysObject[i].exten,cJSON_GetObjectItem(pSub, "exten")->valuestring);
+                if(strcmp(keysObject[i].type, "hangup") == 0){
+                    sprintf(ivrstr,"%s\nexten => %s,1,Hangup()",ivrstr,keysObject[i].key);
+                }
+                else if(strcmp(keysObject[i].type, "extension") == 0){
+                    sprintf(ivrstr,"%s\nexten => %s,1,Goto(default,%s,1)",ivrstr,keysObject[i].key,keysObject[i].exten);
+                }
+                else if(strcmp(keysObject[i].type, "ivr") == 0){
+                    sprintf(ivrstr,"%s\nexten => %s,1,Goto(voicemenu-custom-%s,%s,1)",ivrstr,keysObject[i].key,keysObject[i].exten,keysObject[i].exten);
+                }
+                else if(strcmp(keysObject[i].type, "group") == 0){
+                    sprintf(ivrstr,"%s\nexten => %s,1,Goto(paging-group-%s,%s,1)",ivrstr,keysObject[i].key,keysObject[i].exten,keysObject[i].exten);
+                }
+            }
+        }
+    }
+    strcat(ivrstr,"\n\n");
+    fputs(ivrstr,conf_ivr_fp);
+}
+/*
+[voicemenu-custom-%s]
+include = default
+exten = _IVR-X.,1,NoOp(%s)
+exten = _IVR-X.,n,NoOp(Default language)
+exten = _IVR-X.,n,Set(COUNT=3)
+exten = _IVR-X.,n(loop),Background(%s)
+exten = _IVR-X.,n,Set(COUNT=$[${COUNT}-1])
+exten = _IVR-X.,n,WaitExten(%s)
+exten = _IVR-X.,n,GotoIf($[${COUNT}>1]?6)
+exten = _IVR-X.,n,WaitExten(1)
+exten = t,1,Hangup
+*/
+
+//读取拨号规则的数据,并写入配置文件
+if (executesql(QUERY_DIALRULE_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_dialrule_fp = fopen(EXTEN_DIALRULE_FILE, "w+");
+
+if (conf_dialrule_fp == NULL){
+        perror("Open paging conf file Error: ");
+        exit(1);
+    }
+
+    fprintf(conf_dialrule_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_dialrule_custom.conf (/etc/asterisk/extensions_dialrule_custom.conf)\n\
+;! Generator: Generator DIALRULE\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+fputs("[CallingRule_OutCall]\n",conf_dialrule_fp);
+//t_pbx_users_voiptrunk.trunk as trunk,rule,del_prefix,add_before,add_after
+    while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+        if (g_row[0] == NULL || g_row[1] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+
+        memset(dialrule,0,sizeof(dialrule));
+        sprintf(dialrule, "exten => _%s,1,Macro(trunkdial-failover,${EXTEN},${%s}",g_row[1], g_row[0]);
+        if(g_row[3] != NULL){
+            strcat(dialrule,g_row[3]);
+        }
+        strcat(dialrule,"${EXTEN:");
+        if(g_row[2] != NULL){
+            strcat(dialrule,g_row[2]);
+        }
+        strcat(dialrule,"}");
+        if(g_row[4] != NULL){
+            strcat(dialrule,g_row[4]);
+        }
+        strcat(dialrule,")\n");
+        fputs(dialrule,conf_dialrule_fp);
+    }
+
+
+//读取全局配置数据,并写入配置文件
+if (executesql(QUERY_GLOBAL_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_inbound_fp = fopen(EXTEN_INBOUND_FILE, "w+");
+if (conf_inbound_fp == NULL){
+    perror("Open inbound conf file Error: ");
+    exit(1);
+}
+
+FILE *conf_global_fp = fopen(EXTEN_GLOBAL_FILE, "w+");
+if (conf_global_fp == NULL){
+    perror("Open global conf file Error: ");
+    exit(1);
+}
+
+FILE *conf_calltrigger_fp = fopen(EXTEN_CALLTRIGGER_FILE, "w+");
+if (conf_calltrigger_fp == NULL){
+    perror("Open calltrigger conf file Error: ");
+    exit(1);
+}
+
+FILE *conf_featurecodes_fp = fopen(EXTEN_FEATURECODES_FILE, "w+");
+if (conf_featurecodes_fp == NULL){
+    perror("Open featurecodes conf file Error: ");
+    exit(1);
+}
+
+FILE *conf_sip_nat_fp = fopen(SIP_NAT_FILE, "w+");
+if (conf_sip_nat_fp == NULL){
+    perror("Open sip nat conf file Error: ");
+    exit(1);
+}
+
+FILE *conf_sipsetting_fp = fopen(SIP_SETTINGS_FILE, "w+");
+if (conf_sipsetting_fp == NULL){
+    perror("Open sip settings conf file Error: ");
+    exit(1);
+}
+
+FILE *conf_rtpsetting_fp = fopen(RTP_SETTINGS_FILE, "w+");
+if (conf_rtpsetting_fp == NULL){
+    perror("Open rtp settings conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_inbound_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_inbound_custom.conf (/etc/asterisk/extensions_inbound_custom.conf)\n\
+;! Generator: Generator INBOUND\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+    fprintf(conf_global_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_global_custom.conf (/etc/asterisk/extensions_global_custom.conf)\n\
+;! Generator: Generator GLOBAL\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+fprintf(conf_global_fp, "\
+AGISERVERHOST = %s\n\
+AGISERVERPORT = %s\n\
+",\
+getenv("BROADCAST_GATEWAY"),\
+getenv("AGI_SERVER_PORT")\
+);
+
+    fprintf(conf_calltrigger_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_call_trigger_custom.conf (/etc/asterisk/extensions_call_trigger_custom.conf)\n\
+;! Generator: Generator TRIGGER\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+    fprintf(conf_featurecodes_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_featurecodes_custom.conf (/etc/asterisk/extensions_featurecodes_custom.conf)\n\
+;! Generator: Generator FEATURECODES\n\
+;! Creation Date: %s\n\
+;!\n\n\
+[featurecodes]\n",\
+mytime()\
+);
+
+    fprintf(conf_sip_nat_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: sip_nat.conf (/etc/asterisk/sip_nat.conf)\n\
+;! Generator: Generator SIP NAT\n\
+;! Creation Date: %s\n\
+;!\n\n\
+\n",\
+mytime()\
+);
+
+    fprintf(conf_sipsetting_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: sip_settings.conf (/etc/asterisk/sip_settings.conf)\n\
+;! Generator: Generator SIP SETTINGS\n\
+;! Creation Date: %s\n\
+;!\n\n\
+\n",\
+mytime()\
+);
+
+    fprintf(conf_rtpsetting_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: rtp_settings.conf (/etc/asterisk/rtp_settings.conf)\n\
+;! Generator: Generator RTP SETTINGS\n\
+;! Creation Date: %s\n\
+;!\n\n\
+\n",\
+mytime()\
+);
+
+//t_pbx_users_voiptrunk.trunk as trunk,rule,del_prefix,add_before,add_after
+    while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+        if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+
+        if(strcmp(g_row[1],"pbx.voip.inbound") == 0){
+            memset(inboundstr,0,sizeof(inboundstr));
+            pJson = cJSON_Parse(g_row[2]);
+            if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "hangup") == 0){
+                sprintf(inboundstr,"\
+[direct-analog]\n\
+exten => direct,1,Hangup()\n\
+[direct-voip]\n\
+exten => direct,1,Hangup()\n"
+    );
+            }
+            else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "extension") == 0){
+                sprintf(inboundstr,"\
+[direct-analog]\n\
+exten => direct,1,Goto(default,%s,1)\n\
+[direct-voip]\n\
+exten => direct,1,Goto(default,%s,1)\n",\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring\
+    );
+            }
+            else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "ivr") == 0){
+                sprintf(inboundstr,"\
+[direct-analog]\n\
+exten => direct,1,Goto(voicemenu-custom-%s,%s,1)\n\
+[direct-voip]\n\
+exten => direct,1,Goto(voicemenu-custom-%s,%s,1)\n",\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring\
+    );
+            }
+            else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "group") == 0){
+                sprintf(inboundstr,"\
+[direct-analog]\n\
+exten => direct,1,Goto(paging-group-%s,%s,1)\n\
+[direct-voip]\n\
+exten => direct,1,Goto(paging-group-%s,%s,1)\n",\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring,\
+cJSON_GetObjectItem(pJson, "exten")->valuestring\
+    );
+            }
+            fputs(inboundstr,conf_inbound_fp);
+        }
+        else if(strcmp(g_row[1],"paging.prompt.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            fprintf(conf_global_fp, "\
+enPaging_prompt_start = %s\n\
+enPaging_prompt_end = %s\n\
+",\
+cJSON_GetObjectItem(pJson, "start")->valuestring,\
+cJSON_GetObjectItem(pJson, "end")->valuestring\
+);
+            if(cJSON_GetObjectItem(pJson, "startfile") != NULL){
+                memset(prompt, 0, sizeof(prompt));
+                if(strcmp(cJSON_GetObjectItem(pJson, "startfile")->valuestring,"start") == 0)
+                    strcpy(prompt,cJSON_GetObjectItem(pJson, "startfile")->valuestring);
+                else
+                    strncpy(prompt,cJSON_GetObjectItem(pJson, "startfile")->valuestring,strlen(cJSON_GetObjectItem(pJson, "startfile")->valuestring)-4);
+                fprintf(conf_global_fp, "\
+Paging_start_file = %s\n\
+",\
+prompt\
+);
+            }else{
+                fprintf(conf_global_fp, "\
+Paging_start_file = start\n\
+");
+            }
+        }
+        else if(strcmp(g_row[1],"pbx.ringtime.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            if(cJSON_GetObjectItem(pJson, "ringtime") != NULL){
+            fprintf(conf_global_fp, "\
+RINGTIME = %d\n\
+",\
+cJSON_GetObjectItem(pJson, "ringtime")->valueint\
+);
+            }else{
+                fprintf(conf_global_fp, "\
+RINGTIME = 30\n\
+");
+            }
+        }
+        else if(strcmp(g_row[1],"pbx.nat.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            if(pJson && cJSON_GetObjectItem(pJson, "enable")->valueint == 1){
+                fprintf(conf_sip_nat_fp, "\
+externaddr = %s\n\
+externhost = %s\n\
+externrefresh = %d\n\
+",\
+cJSON_GetObjectItem(pJson, "externaddr")->valuestring,\
+cJSON_GetObjectItem(pJson, "externhost")->valuestring,\
+cJSON_GetObjectItem(pJson, "externrefresh")->valueint\
+);
+                if(cJSON_GetObjectItem(pJson, "externtcpport") && cJSON_GetObjectItem(pJson, "externtcpport")->valueint != 0)
+                {
+                    fprintf(conf_sip_nat_fp, "\
+externtcpport = %d\n\
+",\
+cJSON_GetObjectItem(pJson, "externtcpport")->valueint\
+);
+                }
+                if(cJSON_GetObjectItem(pJson, "externtlsport") && cJSON_GetObjectItem(pJson, "externtlsport")->valueint != 0)
+                {
+                    fprintf(conf_sip_nat_fp, "\
+externtlsport = %d\n\
+",\
+cJSON_GetObjectItem(pJson, "externtlsport")->valueint\
+);
+                }
+                cJSON *localnetArray = cJSON_GetObjectItem( pJson, "localnet");
+                if(localnetArray != NULL){
+                    int array_size = cJSON_GetArraySize (localnetArray);
+                    for(int n = 0; n < array_size; n++){
+                        pSub = cJSON_GetArrayItem(localnetArray, n);
+                        if(NULL == pSub ){ continue ; }
+                        fprintf(conf_sip_nat_fp, "\
+localnet = %s\n\
+",\
+pSub->valuestring\
+);
+                    }
+                }
+            }
+        }
+        else if(strcmp(g_row[1],"paging.record.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            if(cJSON_GetObjectItem(pJson, "paging_record") != NULL){
+            fprintf(conf_global_fp, "\
+PAGING_RECORD = %s\n\
+",\
+cJSON_GetObjectItem(pJson, "paging_record")->valuestring\
+);
+            }
+            if(cJSON_GetObjectItem(pJson, "intercom_record") != NULL){
+            fprintf(conf_global_fp, "\
+INTERCOM_RECORD = %s\n\
+",\
+cJSON_GetObjectItem(pJson, "intercom_record")->valuestring\
+);
+            }
+            if(cJSON_GetObjectItem(pJson, "conference_record") != NULL){
+            fprintf(conf_global_fp, "\
+CONFERENCE_RECORD = %s\n\
+",\
+cJSON_GetObjectItem(pJson, "conference_record")->valuestring\
+);
+            }
+        }
+        else if(strcmp(g_row[1],"pbx.autoanswer.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            if(cJSON_GetObjectItem(pJson, "intercom_autoanswer") != NULL){
+            fprintf(conf_global_fp, "\
+INTERCOM_AUTO = %s\n\
+",\
+cJSON_GetObjectItem(pJson, "intercom_autoanswer")->valuestring\
+);
+            }
+            else
+            {
+                fprintf(conf_global_fp, "\
+INTERCOM_AUTO = yes\n\
+");
+            }
+            if(cJSON_GetObjectItem(pJson, "paging_autoanswer") != NULL){
+            fprintf(conf_global_fp, "\
+PAGING_AUTO = %s\n\
+",\
+cJSON_GetObjectItem(pJson, "paging_autoanswer")->valuestring\
+);
+            }
+            else
+            {
+                fprintf(conf_global_fp, "\
+PAGING_AUTO = yes\n\
+");
+            }
+        }
+        else if(strcmp(g_row[1],"paging.calltrigger.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            fprintf(conf_calltrigger_fp, "\
+exten => _%s.,1,Macro(calltrigger,${EXTEN})\n\
+exten => _%s.,1,Macro(calltrigger,${EXTEN})\n\
+",\
+cJSON_GetObjectItem(pJson, "start")->valuestring,\
+cJSON_GetObjectItem(pJson, "stop")->valuestring\
+);
+        }
+        else if(strcmp(g_row[1],"pbx.sipsettings.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            if(cJSON_GetObjectItem(pJson, "udp"))
+            {
+                fprintf(conf_sipsetting_fp, "udpbindaddr = 0.0.0.0:%d\n",cJSON_GetObjectItem(pJson, "udp")->valueint);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "tcp");
+            if(pSub && cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_sipsetting_fp, "\
+tcpenable = yes\n\
+tcpbindaddr = 0.0.0.0:%d\n\
+",\
+cJSON_GetObjectItem(pSub, "port")->valueint\
+);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "tls");
+            if(pSub && cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_sipsetting_fp, "\
+tlsenable = yes\n\
+tlsbindaddr = 0.0.0.0:%d\n\
+",\
+cJSON_GetObjectItem(pSub, "port")->valueint\
+);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "rtp");
+            if(pSub){
+                fprintf(conf_rtpsetting_fp, "\
+rtpstart = %d\n\
+rtpend = %d\n\
+",\
+cJSON_GetObjectItem(pSub, "start_port")->valueint,\
+cJSON_GetObjectItem(pSub, "end_port")->valueint\
+);
+            }
+        }
+        else if(strcmp(g_row[1],"paging.featurecodes.config") == 0){
+            pJson = cJSON_Parse(g_row[2]);
+            pSub = cJSON_GetObjectItem(pJson, "bargein");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Macro(spy-barge,${EXTEN:%ld},${CALLERID(num)})\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+            }
+            pSub = cJSON_GetObjectItem(pJson, "clear");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Macro(exten-clear,${EXTEN:%ld},${CALLERID(num)})\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+            }
+            pSub = cJSON_GetObjectItem(pJson, "syp");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Macro(spy-normal,${EXTEN:%ld},${CALLERID(num)})\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+            }
+            pSub = cJSON_GetObjectItem(pJson, "whisper");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Macro(spy-whisper,${EXTEN:%ld},${CALLERID(num)})\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+            }
+            pSub = cJSON_GetObjectItem(pJson, "wakeup");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = %s,1,Macro(wakeup-call,${CALLERID(num)})\n",cJSON_GetObjectItem(pSub, "code")->valuestring);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "dnd");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = %s,1,Goto(app-dnd-on,s,1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "cf-alway");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Goto(app-cf-on,cf-${EXTEN:%ld},1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+                fprintf(conf_featurecodes_fp, "exten = %s,1,Goto(app-cf-off,s,1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "cf-busy");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Goto(app-cfb-on,cf-${EXTEN:%ld},1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+                fprintf(conf_featurecodes_fp, "exten = %s,1,Goto(app-cfb-off,s,1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring);
+            }
+            pSub = cJSON_GetObjectItem(pJson, "cf-noanswer");
+            if(cJSON_GetObjectItem(pSub, "enable")->valueint == 1){
+                fprintf(conf_featurecodes_fp, "exten = _%s.,1,Goto(app-cfu-on,cf-${EXTEN:%ld},1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring,strlen(cJSON_GetObjectItem(pSub, "code")->valuestring));
+                fprintf(conf_featurecodes_fp, "exten = %s,1,Goto(app-cfu-off,s,1)\n",cJSON_GetObjectItem(pSub, "code")->valuestring);
+            }
+        }
+    }
+
+
+fclose(conf_dialrule_fp);
+fclose(conf_ivr_fp);
+fclose(conf_inbound_fp);
+fclose(conf_global_fp);
+fclose(conf_calltrigger_fp);
+fclose(conf_featurecodes_fp);
+fclose(conf_sip_nat_fp);
+fclose(conf_sipsetting_fp);
+mysql_free_result(g_res); // 释放结果集
+mysql_close(g_conn); // 关闭链接
+cJSON_Delete(pJson);
+}
+

+ 454 - 0
generate_group_conf.c

@@ -0,0 +1,454 @@
+/*
+============================================================================
+Name        : generate_paging_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate paging info from mysql to paging conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <cjson/cJSON.h>
+
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql group记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql device记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+MYSQL_RES *r_res; // mysql device记录集
+MYSQL_ROW r_row; // 字符串数组,mysql 记录行
+
+#define MAX_TRUNK_SIZE 256
+#define MAX_SIZE 20480
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define MYSQL_CONNECT_CONF "/etc/asterisk/exten_gen.ini"
+#define EXTEN_PAGING_FILE "/etc/asterisk/extensions_paging_custom.conf"
+#define EXTEN_EXTENS_FILE "/etc/asterisk/extensions_extens_custom.conf"
+#define EXTEN_IPPHONES_FILE "/etc/asterisk/extensions_phones_custom.conf"
+#define EXTEN_HINTS_FILE "/etc/asterisk/extensions_hints_custom.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define QUERY_PAGING_GROUP_SQL "select id,name,exten,paging_mode,paging_volume from t_paging_groups"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+char sql_tmp[MIDLE_SIZE];
+char exten_tmp[MAX_SIZE];
+char dest_tmp[MAX_SIZE];
+char page_option[MINI_SIZE];
+char page_volume[MINI_SIZE];
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+int main(int argc, char **argv) {
+cJSON *pJson;
+    
+memset(g_host_name, 0, sizeof(g_host_name));
+memset(g_user_name, 0, sizeof(g_user_name));
+memset(g_password, 0, sizeof(g_password));
+memset(g_db_name, 0, sizeof(g_db_name));
+
+
+strcpy(g_host_name,getenv("MYSQL"));
+strcpy(g_user_name,getenv("MYSQL_USER"));
+strcpy(g_password,getenv("MYSQL_PASSWORD"));
+strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+if (init_mysql()){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+if (executesql(QUERY_PAGING_GROUP_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_paging_fp = fopen(EXTEN_PAGING_FILE, "w+");
+FILE *conf_extens_fp = fopen(EXTEN_EXTENS_FILE, "w+");
+FILE *conf_ipphones_fp = fopen(EXTEN_IPPHONES_FILE, "w+");
+FILE *conf_hints_fp = fopen(EXTEN_HINTS_FILE, "w+");
+
+if (conf_paging_fp == NULL){
+    perror("Open paging conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_paging_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_paging_custom.conf (/etc/asterisk/extensions_paging_custom.conf)\n\
+;! Generator: Generator Paging\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_extens_fp == NULL){
+    perror("Open extens conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_extens_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_extens_custom.conf (/etc/asterisk/extensions_extens_custom.conf)\n\
+;! Generator: Generator Extens\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_ipphones_fp == NULL){
+    perror("Open ipphones conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_ipphones_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_phones_custom.conf (/etc/asterisk/extensions_phones_custom.conf)\n\
+;! Generator: Generator phones\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_hints_fp == NULL){
+    perror("Open hints conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_hints_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_hints_custom.conf (/etc/asterisk/extensions_hints_custom.conf)\n\
+;! Generator: Generator hints\n\
+;! Creation Date: %s\n\
+;!\n\n\
+[default]\n\
+",\
+mytime()\
+);
+while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+    if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL || g_row[3] == NULL){
+        printf("some feild is empty!\n");
+        continue;
+    }
+    fprintf(conf_extens_fp, "[extens-group-%s]\n",g_row[2]);
+    fprintf(conf_ipphones_fp, "[phones-group-%s]\n",g_row[2]);
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select exten,type_id,allowed_pa from t_paging_deviceGroups JOIN t_paging_devices on t_paging_devices.id = t_paging_deviceGroups.DeviceId\
+    where GroupId = %s and t_paging_devices.type_id in('1','2','3','5') and t_paging_devices.user_id is NULL",g_row[0]);
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    memset(exten_tmp,0,sizeof(exten_tmp));
+    memset(dest_tmp,0,sizeof(dest_tmp));
+    while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+        if (d_row[0] == NULL || d_row[1] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+        if(strcmp(d_row[2],"yes") == 0){
+            //sprintf(exten_tmp, "%sSIP/%s&", exten_tmp, d_row[0]);
+            //sprintf(dest_tmp, "%s%s|", dest_tmp, d_row[0]);
+            strcat(exten_tmp,"SIP/");
+            strcat(exten_tmp,d_row[0]);
+            strcat(exten_tmp,"&");
+            strcat(dest_tmp,d_row[0]);
+            strcat(dest_tmp,"|");
+        }
+        
+        int id = atoi(d_row[1]);
+        switch(id){
+            case 1:
+                fprintf(conf_extens_fp, "exten => %s,1,Macro(page,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+            case 2:
+                fprintf(conf_extens_fp, "exten => %s,1,Macro(intercom,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+            case 3:
+            case 7:
+                fprintf(conf_ipphones_fp, "exten => %s,1,Macro(stdexten,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+        }
+    }
+    if(strlen(exten_tmp) > 0){
+        exten_tmp[strlen(exten_tmp) - 1] = '\0';
+        dest_tmp[strlen(dest_tmp) - 1] = '\0';
+    }
+
+    fprintf(conf_extens_fp, "\n");
+
+    memset(page_option, 0, sizeof(page_option));
+    if(strcmp(g_row[3],"duplex") == 0){
+        strcat(page_option,"d");
+    }
+    memset(page_volume, '\0', sizeof(page_volume));
+    if(g_row[4] != NULL)
+    {
+        pJson = cJSON_Parse(g_row[4]);
+        if(pJson && cJSON_HasObjectItem(pJson, "enableForce"))
+        {
+            if(cJSON_IsBool(cJSON_GetObjectItem(pJson, "enableForce")) && cJSON_IsTrue(cJSON_GetObjectItem(pJson, "enableForce")))
+            {
+                sprintf(page_volume,"\\;volume=%d",cJSON_GetObjectItem(pJson, "softvolume")->valueint);
+            }
+        }
+    }
+
+    fprintf(conf_paging_fp, "\
+[paging-group-%s]\n\
+exten => %s,1,NoOp(%s)\n\
+same => n,MSet(__SRCEXTEN=${CALLERID(num)},__DESTS=%s,DATE=${STRFTIME(${EPOCH},,%%Y%%m%%d)},__UUID=${UNIQUEID})\n\
+same => n,GotoIf($[\"foo${PAGING_AUTO}\" = \"foono\"]?manual)\n\
+same => n,MSet(ALERTINFO=Alert-Info: Ring Answer,CALLINFO=Call-Info: <uri>\\;answer-after=0%s)\n\
+same => n,SIPAddHeader(${ALERTINFO})\n\
+same => n,SIPAddHeader(${CALLINFO})\n\
+same => n(manual),GotoIf($[\"foo${PAGING_RECORD}\" != \"fooyes\"]?unrc)\n\
+same => n,System(/bin/sh /etc/scripts/shell_scripts.sh mkrcdir paging ${DATE})\n\
+same => n,Set(FILENAME=paging/${DATE}/paging-${SRCEXTEN}-${UUID}.wav)\n\
+same => n,MixMonitor(${FILENAME},b)\n\
+same => n(unrc),Macro(get-user-level,${SRCEXTEN},)\n\
+same => n,AGI(agi://${AGISERVERHOST}:${AGISERVERPORT},paging,${DESTS},${SESSION_LEVEL},${SESSION_USERID})\n\
+same => n,ExecIf(${ISNULL(${DESTS})}?Hangup())\n\
+same => n,ExecIf($['foo${enPaging_prompt_start}'='fooyes']?Set(STARTPROMPT=qA(${Paging_start_file})))\n\
+same => n,UserEvent(controlEvent,sessionlevel:${SESSION_LEVEL},sessionuserid:${SESSION_USERID},src:${SRCEXTEN},dest:${DESTS},uuid:${UUID},status:paging)\n\
+same => n,Wait(1)\n\
+same => n,GotoIf(${ISNULL(${DESTCHANS})}?default)\n\
+same => n,MSet(startT=${STRFTIME(${EPOCH},,%%s)},__CALLEE=${DESTS},__calltype=paging,DEVICE_STATE(Custom:${EXTEN})=INUSE,__GROUPID=${EXTEN})\n\
+same => n,Page(${DESTCHANS},%sb(paging-update-status^s^1)${STARTPROMPT})\n\
+same => n,Hangup\n\
+same => n(default),MSet(startT=${STRFTIME(${EPOCH},,%%s)},__CALLEE=${DESTS},__calltype=paging,DEVICE_STATE(Custom:${EXTEN})=INUSE,__GROUPID=${EXTEN})\n\
+same => n,Page(%s,%sb(paging-update-status^s^1)${STARTPROMPT})\n\
+same => n,Hangup\
+\n\n", \
+g_row[2],\
+g_row[2],\
+g_row[1],\
+dest_tmp,\
+page_volume,\
+page_option,\
+exten_tmp,\
+page_option\
+);
+    fprintf(conf_hints_fp,"\
+exten => %s,hint,Custom:%s\n\
+",\
+g_row[2],\
+g_row[2]\
+    );
+}
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select conditions from t_paging_tasks where type='numberrule'");
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    r_res = mysql_store_result(g_conn);
+    while(r_row=mysql_fetch_row(r_res))
+    {
+        pJson = cJSON_Parse(r_row[0]);
+        if(cJSON_GetObjectItem(pJson, "extension"))
+        {
+            fprintf(conf_hints_fp,"\
+exten => *11%s,hint,Custom:*11%s\n\
+",\
+cJSON_GetObjectItem(pJson, "extension")->valuestring,\
+cJSON_GetObjectItem(pJson, "extension")->valuestring\
+            );
+        }
+    }
+fclose(conf_paging_fp);
+fclose(conf_extens_fp);
+fclose(conf_hints_fp);
+mysql_free_result(g_res); // 释放结果集
+mysql_free_result(d_res);
+mysql_free_result(r_res);
+mysql_close(g_conn); // 关闭链接
+cJSON_Delete(pJson);
+}

+ 380 - 0
generate_group_conf.c.acorp

@@ -0,0 +1,380 @@
+/*
+============================================================================
+Name        : generate_paging_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate paging info from mysql to paging conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <cjson/cJSON.h>
+
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql group记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql device记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+
+#define MAX_TRUNK_SIZE 256
+#define MAX_SIZE 5120
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define MYSQL_CONNECT_CONF "/etc/asterisk/exten_gen.ini"
+#define EXTEN_PAGING_FILE "/etc/asterisk/extensions_paging_custom.conf"
+#define EXTEN_EXTENS_FILE "/etc/asterisk/extensions_extens_custom.conf"
+#define EXTEN_IPPHONES_FILE "/etc/asterisk/extensions_phones_custom.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define QUERY_PAGING_GROUP_SQL "select id,name,exten,paging_mode from t_paging_groups"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+char sql_tmp[MIDLE_SIZE];
+char exten_tmp[MAX_SIZE];
+char dest_tmp[MAX_SIZE];
+char page_option[MINI_SIZE];
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+int main(int argc, char **argv) {
+/*
+memset(g_host_name, 0, sizeof(g_host_name));
+memset(g_user_name, 0, sizeof(g_user_name));
+memset(g_password, 0, sizeof(g_password));
+memset(g_db_name, 0, sizeof(g_db_name));
+
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbserverip", g_host_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbuser", g_user_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbpasswd", g_password);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbname", g_db_name);
+*/
+strcpy(g_host_name,getenv("MYSQL"));
+strcpy(g_user_name,getenv("MYSQL_USER"));
+strcpy(g_password,getenv("MYSQL_PASSWORD"));
+strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+if (init_mysql()){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+if (executesql(QUERY_PAGING_GROUP_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_paging_fp = fopen(EXTEN_PAGING_FILE, "w+");
+FILE *conf_extens_fp = fopen(EXTEN_EXTENS_FILE, "w+");
+FILE *conf_ipphones_fp = fopen(EXTEN_IPPHONES_FILE, "w+");
+
+if (conf_paging_fp == NULL){
+    perror("Open paging conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_paging_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_paging_custom.conf (/etc/asterisk/extensions_paging_custom.conf)\n\
+;! Generator: Generator Paging\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_extens_fp == NULL){
+    perror("Open extens conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_extens_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_extens_custom.conf (/etc/asterisk/extensions_extens_custom.conf)\n\
+;! Generator: Generator Extens\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_ipphones_fp == NULL){
+    perror("Open ipphones conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_ipphones_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_phones_custom.conf (/etc/asterisk/extensions_phones_custom.conf)\n\
+;! Generator: Generator phones\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+    if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL || g_row[3] == NULL){
+        printf("some feild is empty!\n");
+        continue;
+    }
+    fprintf(conf_extens_fp, "[extens-group-%s]\n",g_row[2]);
+    fprintf(conf_ipphones_fp, "[phones-group-%s]\n",g_row[2]);
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select exten,type_id,allowed_pa from t_paging_deviceGroups JOIN t_paging_devices on t_paging_devices.id = t_paging_deviceGroups.DeviceId\
+    where GroupId = %s and t_paging_devices.type_id in('1','2','3','5')",g_row[0]);
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    memset(exten_tmp,0,sizeof(exten_tmp));
+    memset(dest_tmp,0,sizeof(dest_tmp));
+    while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+        if (d_row[0] == NULL || d_row[1] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+        //sprintf(exten_tmp, "%sSIP/%s&", exten_tmp, d_row[0]);
+        //sprintf(dest_tmp, "%s%s|", dest_tmp, d_row[0]);
+        strcat(exten_tmp,"SIP/");
+        strcat(exten_tmp,d_row[0]);
+        strcat(exten_tmp,"&");
+        strcat(dest_tmp,d_row[0]);
+        strcat(dest_tmp,"|");
+        
+        int id = atoi(d_row[1]);
+        switch(id){
+            case 1:
+                fprintf(conf_extens_fp, "exten => %s,1,Macro(page,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+            case 2:
+                fprintf(conf_extens_fp, "exten => %s,1,Macro(intercom,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+            case 3:
+            case 7:
+                fprintf(conf_ipphones_fp, "exten => %s,1,Macro(stdexten,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+        }
+    }
+    if(strlen(exten_tmp) > 0){
+        exten_tmp[strlen(exten_tmp) - 1] = '\0';
+        dest_tmp[strlen(dest_tmp) - 1] = '\0';
+    }
+
+    fprintf(conf_extens_fp, "\n");
+
+    memset(page_option, 0, sizeof(page_option));
+    if(strcmp(g_row[3],"duplex") == 0){
+        strcat(page_option,"d");
+    }
+
+    fprintf(conf_paging_fp, "\
+[paging-group-%s]\n\
+exten => %s,1,NoOp(%s)\n\
+same => n,MSet(__SRCEXTEN=${CALLERID(num)},__DESTS=%s,DATE=${STRFTIME(${EPOCH},,%%Y%%m%%d)},__UUID=${UNIQUEID})\n\
+same => n,GotoIf($[\"foo${PAGING_RECORD}\" != \"fooyes\"]?unrc)\n\
+same => n,System(/bin/sh /etc/scripts/shell_scripts.sh mkrcdir paging ${DATE})\n\
+same => n,Set(FILENAME=paging/${DATE}/paging-${SRCEXTEN}-${UUID}.wav)\n\
+same => n,MixMonitor(${FILENAME},b)\n\
+same => n(unrc),Wait(0.5)\n\
+same => n,Set(__CONFNO=${EXTEN})\n\
+same => n,MSet(startT=${STRFTIME(${EPOCH},,%%s)},__CALLEE=${DESTS},__calltype=paging)\n\
+same => n,MSet(CONFBRIDGE(user,quiet)=yes,CONFBRIDGE(user,marked)=yes)\n\
+same => n,AGI(joinmeetme.agi,${CONFNO},${SRCEXTEN},${DESTS})\n\
+same => n,ConfBridge(${CONFNO})\n\
+same => n,Hangup\n\
+exten => h,1,Goto(checkmeetme,s,1)\
+\n\n", \
+g_row[2],\
+g_row[2],\
+g_row[1],\
+dest_tmp\
+);
+    }
+fclose(conf_paging_fp);
+fclose(conf_extens_fp);
+mysql_free_result(g_res); // 释放结果集
+mysql_free_result(d_res);
+mysql_close(g_conn); // 关闭链接
+}

+ 378 - 0
generate_group_conf1.c

@@ -0,0 +1,378 @@
+/*
+============================================================================
+Name        : generate_paging_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate paging info from mysql to paging conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <cjson/cJSON.h>
+
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql group记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql device记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+
+#define MAX_TRUNK_SIZE 256
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define MYSQL_CONNECT_CONF "/etc/asterisk/exten_gen.ini"
+#define EXTEN_PAGING_FILE "/etc/asterisk/extensions_paging_custom.conf"
+#define EXTEN_EXTENS_FILE "/etc/asterisk/extensions_extens_custom.conf"
+#define EXTEN_IPPHONES_FILE "/etc/asterisk/extensions_phones_custom.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define QUERY_PAGING_GROUP_SQL "select id,name,exten from t_paging_groups"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+char sql_tmp[MIDLE_SIZE];
+char exten_tmp[MAX_SIZE];
+char dest_tmp[MAX_SIZE];
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+
+int main(int argc, char **argv) {
+/*
+memset(g_host_name, 0, sizeof(g_host_name));
+memset(g_user_name, 0, sizeof(g_user_name));
+memset(g_password, 0, sizeof(g_password));
+memset(g_db_name, 0, sizeof(g_db_name));
+
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbserverip", g_host_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbuser", g_user_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbpasswd", g_password);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbname", g_db_name);
+*/
+strcpy(g_host_name,getenv("MYSQL"));
+strcpy(g_user_name,getenv("MYSQL_USER"));
+strcpy(g_password,getenv("MYSQL_PASSWORD"));
+strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+if (init_mysql()){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+if (executesql(QUERY_PAGING_GROUP_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_paging_fp = fopen(EXTEN_PAGING_FILE, "w+");
+FILE *conf_extens_fp = fopen(EXTEN_EXTENS_FILE, "w+");
+FILE *conf_ipphones_fp = fopen(EXTEN_IPPHONES_FILE, "w+");
+
+if (conf_paging_fp == NULL){
+    perror("Open paging conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_paging_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_paging_custom.conf (/etc/asterisk/extensions_paging_custom.conf)\n\
+;! Generator: Generator Paging\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_extens_fp == NULL){
+    perror("Open extens conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_extens_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_extens_custom.conf (/etc/asterisk/extensions_extens_custom.conf)\n\
+;! Generator: Generator Extens\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_ipphones_fp == NULL){
+    perror("Open ipphones conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_ipphones_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_phones_custom.conf (/etc/asterisk/extensions_phones_custom.conf)\n\
+;! Generator: Generator phones\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+    if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL){
+        printf("some feild is empty!\n");
+        continue;
+    }
+    fprintf(conf_extens_fp, "[extens-group-%s]\n",g_row[2]);
+    fprintf(conf_ipphones_fp, "[phones-group-%s]\n",g_row[2]);
+    memset(sql_tmp,0,sizeof(sql_tmp));
+    sprintf(sql_tmp,"select exten,type_id,allowed_pa from t_paging_deviceGroups JOIN t_paging_devices on t_paging_devices.id = t_paging_deviceGroups.DeviceId\
+    where GroupId = %s and t_paging_devices.type_id in('1','2','3','5') and t_paging_devices.user_id is NULL",g_row[0]);
+    if (executesql(sql_tmp)){
+        print_mysql_error(NULL);
+        exit(1);
+    }
+    d_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+    memset(exten_tmp,0,sizeof(exten_tmp));
+    memset(dest_tmp,0,sizeof(dest_tmp));
+    while ((d_row=mysql_fetch_row(d_res))){ // 打印结果集
+        if (d_row[0] == NULL || d_row[1] == NULL){
+            printf("some feild is empty!\n");
+            continue;
+        }
+        if(strcmp(d_row[2],"yes") == 0){
+            sprintf(exten_tmp, "%sSIP/%s&", exten_tmp, d_row[0]);
+            sprintf(dest_tmp, "%s%s|", dest_tmp, d_row[0]);
+        }
+        
+        int id = atoi(d_row[1]);
+        switch(id){
+            case 1:
+                fprintf(conf_extens_fp, "exten => %s,1,Macro(page,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+            case 2:
+                fprintf(conf_extens_fp, "exten => %s,1,Macro(intercom,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+            case 3:
+            case 7:
+                fprintf(conf_ipphones_fp, "exten => %s,1,Macro(stdexten,%s,SIP/%s)\n",d_row[0],d_row[0],d_row[0]);
+                break;
+        }
+    }
+    if(strlen(exten_tmp) > 0){
+        exten_tmp[strlen(exten_tmp) - 1] = '\0';
+        dest_tmp[strlen(dest_tmp) - 1] = '\0';
+    }
+
+    fprintf(conf_extens_fp, "\n");
+
+    fprintf(conf_paging_fp, "\
+[paging-group-%s]\n\
+exten => %s,1,NoOp(%s)\n\
+same => n,MSet(__SRCEXTEN=${CALLERID(num)},__DESTS=%s,DATE=${STRFTIME(${EPOCH},,%%Y%%m%%d)},__UUID=${UNIQUEID},ALERTINFO=Alert-Info: Ring Answer,CALLINFO=Call-Info: <uri>\\;answer-after=0)\n\
+same => n,SIPAddHeader(${ALERTINFO})\n\
+same => n,SIPAddHeader(${CALLINFO})\n\
+same => n,System(/bin/sh /etc/scripts/shell_scripts.sh mkrcdir paging ${DATE})\n\
+same => n,Set(FILENAME=paging/${DATE}/paging-${SRCEXTEN}-${UUID}.wav)\n\
+same => n,MixMonitor(${FILENAME},b)\n\
+same => n,Macro(get-user-level,${SRCEXTEN},)\n\
+same => n,AGI(agi://${AGISERVERHOST}:${AGISERVERPORT},paging,${DESTS},${SESSION_LEVEL},${SESSION_USERID})\n\
+same => n,ExecIf(${ISNULL(${DESTS})}?Goto(paging_failed,s,1))\n\
+same => n,ExecIf($['foo${enPaging_prompt_start}'='fooyes']?Set(STARTPROMPT=qA(start)))\n\
+same => n,UserEvent(controlEvent,sessionlevel:${SESSION_LEVEL},sessionuserid:${SESSION_USERID},src:${SRCEXTEN},dest:${DESTS},uuid:${UUID},status:stop)\n\
+same => n,Wait(1)\n\
+same => n,GotoIf(${ISNULL(${DESTCHANS})}?default)\n\
+same => n,MSet(startT=${STRFTIME(${EPOCH},,%%s)},__CALLEE=${DESTS},__calltype=paging)\n\
+same => n,Page(${DESTCHANS},b(paging-update-status^s^1)${STARTPROMPT})\n\
+same => n,Hangup\n\
+same => n(default),Page(%s,b(paging-update-status^s^1)${STARTPROMPT})\n\
+same => n,Hangup\
+\n\n", \
+g_row[2],\
+g_row[2],\
+g_row[1],\
+dest_tmp,\
+exten_tmp\
+);
+    }
+fclose(conf_paging_fp);
+fclose(conf_extens_fp);
+mysql_free_result(g_res); // 释放结果集
+mysql_free_result(d_res);
+mysql_close(g_conn); // 关闭链接
+}

文件差異過大導致無法顯示
+ 1136 - 0
generate_trunk_conf.c


+ 381 - 0
generate_user_conf.c

@@ -0,0 +1,381 @@
+/*
+============================================================================
+Name        : generate_paging_conf.sh
+Author      : ssc
+Version     : v1.0
+Copyright   : ZYCOO copyright
+Description : Generate paging info from mysql to paging conf file
+============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <cjson/cJSON.h>
+
+#include <mysql/mysql.h>
+
+MYSQL *g_conn; // mysql 连接
+MYSQL_RES *g_res; // mysql group记录集
+MYSQL_ROW g_row; // 字符串数组,mysql 记录行
+MYSQL_RES *d_res; // mysql device记录集
+MYSQL_ROW d_row; // 字符串数组,mysql 记录行
+
+#define MAX_TRUNK_SIZE 256
+#define MAX_SIZE 2048
+#define MIDLE_SIZE 512
+#define MINI_SIZE 64
+#define MYSQL_CONNECT_CONF "/etc/asterisk/exten_gen.ini"
+#define EXTEN_USER_QUEUE_FILE "/etc/asterisk/extensions_users_queue_custom.conf"
+#define QUEUES_FILE "/etc/asterisk/queues.conf"
+#define KEYVALLEN 100
+#define VERSION "V1.0.1"
+
+#define QUERY_PAGING_USER_SQL "select id,phones,strategy,ring_duration,noanswer_dest from t_paging_users"
+
+char g_host_name[MINI_SIZE];
+char g_user_name[MINI_SIZE];
+char g_password[MINI_SIZE];
+char g_db_name[MINI_SIZE];
+const unsigned int g_db_port = 3306;
+char sql_tmp[MIDLE_SIZE];
+char exten_tmp[MAX_SIZE];
+
+//读取配置文件函数----功能:删除左边空格
+char *l_trim(char *szOutput, const char *szInput)
+{
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    for   (NULL; *szInput != '\0' && isspace(*szInput); ++szInput)
+    {
+        ;
+    }
+    return strcpy(szOutput, szInput);
+}
+
+//   删除右边的空格   
+char *r_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    assert(szOutput != szInput);
+    strcpy(szOutput, szInput);
+    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+
+//   删除两边的空格   
+char *a_trim(char *szOutput, const char *szInput)
+{
+    char *p = NULL;
+    assert(szInput != NULL);
+    assert(szOutput != NULL);
+    l_trim(szOutput, szInput);
+    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
+    {
+        ;
+    }
+    *(++p) = '\0';
+    return szOutput;
+}
+//main函数接口 参数1:配置文件路径 参数2:配置文件的那一部分,如general 参数3:键名 参数4:键值
+int GetProfileString(char *profile, char *AppName, char *KeyName, char *KeyVal )
+{
+    char appname[32], keyname[32];
+    char *buf, *c;
+    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
+    FILE *fp;
+    int found = 0; /* 1 AppName 2 KeyName */
+    if( (fp = fopen( profile, "r" )) == NULL )
+    {
+        printf( "openfile [%s] error [%s]\n", profile, strerror(errno) );
+        return(-1);
+    }
+    fseek( fp, 0, SEEK_SET );
+    memset( appname, 0, sizeof(appname) );
+    sprintf( appname, "[%s]", AppName );
+
+    while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
+    {
+        l_trim(buf_o, buf_i);
+        if( strlen(buf_o) <= 0 )
+            continue;
+        buf = NULL;
+        buf = buf_o;
+
+        if( found == 0 )
+        {
+            if( buf[0] != '[' )
+            {
+                continue;
+            }
+            else if ( strncmp(buf, appname, strlen(appname)) == 0 )
+            {
+                found = 1;
+                continue;
+            }
+
+        }
+        else if( found == 1 )
+        {
+            if( buf[0] == '#' )
+            {
+                continue;
+            }
+            else if ( buf[0] == '[' )
+            {
+                break;
+            }
+            else
+            {
+                if( (c = (char *)strchr(buf, '=')) == NULL )
+                    continue;
+                memset( keyname, 0, sizeof(keyname) );
+
+                sscanf( buf, "%[^=|^ |^\t]", keyname );
+                if( strcmp(keyname, KeyName) == 0 )
+                {
+                    sscanf( ++c, "%[^\n]", KeyVal );
+                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
+                    if(KeyVal_o != NULL)
+                    {
+                        memset(KeyVal_o, 0, sizeof(KeyVal_o));
+                        a_trim(KeyVal_o, KeyVal);
+                        if(KeyVal_o && strlen(KeyVal_o) > 0)
+                            strcpy(KeyVal, KeyVal_o);
+                        free(KeyVal_o);
+                        KeyVal_o = NULL;
+                    }
+                    found = 2;
+                    break;
+                }
+                else
+                {
+                    continue;
+                }
+            }
+        }
+    }
+    fclose( fp );
+    if( found == 2 )
+        return(0);
+    else
+        return(-1);
+}
+
+char * mytime(){
+        time_t my_time;
+        time(&my_time);
+        char *time_string = ctime(&my_time);
+        if (time_string[strlen(time_string) - 1] == '\n')
+        {
+                time_string[strlen(time_string) - 1] = '\0';
+        }
+        return time_string;
+}
+
+void print_mysql_error(const char *msg) { // 打印最后一次错误
+if (msg)
+    printf("%s: %s\n", msg, mysql_error(g_conn));
+else
+    puts(mysql_error(g_conn));
+}
+
+int executesql(const char * sql) {
+/*query the database according the sql*/
+if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
+    return -1; // 表示失败
+
+return 0; // 成功执行
+}
+
+
+int init_mysql() { // 初始化连接
+// init the database connection
+g_conn = mysql_init(NULL);
+
+/* connect the database */
+if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
+    return -1;
+
+// 是否连接已经可用
+if (executesql("set names utf8")) // 如果失败
+    return -1;
+
+return 0; // 返回成功
+}
+
+int main(int argc, char **argv) {
+cJSON *pJson,*pSub,*dJson;
+int iCount=0;
+char noanswer_dest[64];
+/*
+memset(g_host_name, 0, sizeof(g_host_name));
+memset(g_user_name, 0, sizeof(g_user_name));
+memset(g_password, 0, sizeof(g_password));
+memset(g_db_name, 0, sizeof(g_db_name));
+
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbserverip", g_host_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbuser", g_user_name);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbpasswd", g_password);
+GetProfileString(MYSQL_CONNECT_CONF, "general", "dbname", g_db_name);
+*/
+strcpy(g_host_name,getenv("MYSQL"));
+strcpy(g_user_name,getenv("MYSQL_USER"));
+strcpy(g_password,getenv("MYSQL_PASSWORD"));
+strcpy(g_db_name,getenv("MYSQL_DATABASE"));
+if (init_mysql()){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+if (executesql(QUERY_PAGING_USER_SQL)){
+    print_mysql_error(NULL);
+    exit(1);
+}
+
+g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集
+FILE *conf_user_queue_fp = fopen(EXTEN_USER_QUEUE_FILE, "w+");
+FILE *conf_queues_fp = fopen(QUEUES_FILE, "w+");
+
+if (conf_user_queue_fp == NULL){
+    perror("Open paging conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_user_queue_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: extensions_users_queue_custom.conf (/etc/asterisk/extensions_users_queue_custom.conf)\n\
+;! Generator: Generator Paging\n\
+;! Creation Date: %s\n\
+;!\n\n\
+",\
+mytime()\
+);
+
+if (conf_queues_fp == NULL){
+    perror("Open paging conf file Error: ");
+    exit(1);
+}
+
+    fprintf(conf_queues_fp, ";!\n\
+;! Automatically generated configuration file\n\
+;! Filename: queues.conf (/etc/asterisk/queues.conf)\n\
+;! Generator: Generator Paging\n\
+;! Creation Date: %s\n\
+;!\n\n\
+\n\
+[general]\n\
+persistentmembers = yes\n\
+\n\
+",\
+mytime()\
+);
+
+while ((g_row=mysql_fetch_row(g_res))){ // 打印结果集
+    if (g_row[0] == NULL || g_row[1] == NULL || g_row[2] == NULL){
+        printf("some feild is empty!\n");
+        continue;
+    }
+    if(g_row[1] != NULL){
+        pJson = cJSON_Parse(g_row[1]);
+        iCount = cJSON_GetArraySize(pJson);
+        if(iCount > 0){
+            int q = 100000 + atoi(g_row[0]);
+            fprintf(conf_user_queue_fp, "[manager-queue-%d]\n", q);
+            fprintf(conf_queues_fp, "\
+[Q%d]\n\
+setinterfacevar = yes\n\
+setqueueentryvar = yes\n\
+strategy = %s\n\
+timeout = 30\n\
+wrapuptime = 0\n\
+autofill = yes\n\
+autopause = no\n\
+ringinuse = no\n\
+maxlen = 8\n\
+context = queue-custom\n\
+joinempty = no\n\
+leavewhenempty = paused,unavailable,invalid,unknown\n\
+periodic-announce-frequency = 0\n\
+reportholdtime = no\n\
+announce-frequency = 0\n\
+announce-holdtime = no\n\
+announce-position = no\n\
+queue-youarenext =\n\
+queue-callswaiting =\n\
+queue-holdtime =\n\
+queue-minutes =\n\
+queue-thankyou =\n\
+musicclass = queuemusic\n\
+\n",q,g_row[2]);
+            dJson = cJSON_Parse(g_row[4]);
+            memset(noanswer_dest,0,sizeof(noanswer_dest));
+            if(dJson)
+            {
+                if(strcmp(cJSON_GetObjectItem(dJson, "type")->valuestring, "hangup") == 0){
+                    strcpy(noanswer_dest,"Goto(hangup,s,1)");
+                }
+                else if(strcmp(cJSON_GetObjectItem(dJson, "type")->valuestring, "extension") == 0){
+                    sprintf(noanswer_dest,"Goto(default,%s,1)",cJSON_GetObjectItem(dJson, "exten")->valuestring);
+                }
+                else if(strcmp(cJSON_GetObjectItem(dJson, "type")->valuestring, "user") == 0){
+                    int id = 100000 + cJSON_GetObjectItem(dJson, "id")->valueint;
+                    sprintf(noanswer_dest,"Goto(manager-queue-%d,s,1)",id);
+                }
+                else if(strcmp(cJSON_GetObjectItem(dJson, "type")->valuestring, "outcall") == 0){
+                    sprintf(noanswer_dest,"Goto(CallingRule_OutCall,%s,1)",cJSON_GetObjectItem(dJson, "exten")->valuestring);
+                }
+            }
+            else
+            {
+                strcpy(noanswer_dest,"Goto(hangup,s,1)");
+            }
+            printf("parse success\n");
+            if(iCount > 0)
+            {
+                if(strcmp(g_row[2],"ringall") == 0){
+                    for(int i = 0;i < iCount;i++){
+                        pSub = cJSON_GetArrayItem(pJson,i);
+                        if(pSub != NULL){
+                            fprintf(conf_queues_fp, "member => SIP/%s\n",pSub->valuestring);
+                            fprintf(conf_user_queue_fp, "exten => %s,1,Macro(queue,Q%d,${EXTEN},%s)\n", pSub->valuestring,q,g_row[3]);
+                            fprintf(conf_user_queue_fp, "same => n,%s\n", noanswer_dest);
+                        }
+                    }
+                    fprintf(conf_user_queue_fp, "exten => s,1,Macro(queue,Q%d,%s,%s)\n", q, pSub->valuestring,g_row[3]);
+                    fprintf(conf_user_queue_fp, "same => n,%s\n", noanswer_dest);
+                }else{
+                    for(int i = 0;i < iCount;i++){
+                        pSub = cJSON_GetArrayItem(pJson,i);
+                        if(pSub != NULL){
+                            fprintf(conf_queues_fp, "member => SIP/%s,%d\n",pSub->valuestring,i);
+                            fprintf(conf_user_queue_fp, "exten => %s,1,Macro(queue,Q%d,${EXTEN},%s)\n", pSub->valuestring,q,g_row[3]);
+                            fprintf(conf_user_queue_fp, "same => n,%s\n", noanswer_dest);
+                        }
+                    }
+                    fprintf(conf_user_queue_fp, "exten => s,1,Macro(queue,Q%d,%s,%s)\n", q, pSub->valuestring,g_row[3]);
+                    fprintf(conf_user_queue_fp, "same => n,%s\n", noanswer_dest);
+                }
+            }
+        }
+    }
+}
+fclose(conf_queues_fp);
+fclose(conf_user_queue_fp);
+mysql_free_result(g_res); // 释放结果集
+mysql_free_result(d_res);
+mysql_close(g_conn); // 关闭链接
+cJSON_Delete(dJson);
+cJSON_Delete(pJson);
+}