ast_init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. ============================================================================
  3. Name : ast_init
  4. Author : dy
  5. Version : v1.0
  6. Copyright : ZYCOO copyright
  7. Description : set init info to mysql and redis
  8. ============================================================================
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. #include <assert.h>
  15. #include <sys/time.h>
  16. #include <time.h>
  17. #include <ctype.h>
  18. #include <mysql/mysql.h>
  19. #include "hiredis/hiredis.h"
  20. MYSQL *g_conn; // mysql 连接
  21. MYSQL_RES *g_res; // mysql 记录集
  22. MYSQL_ROW g_row; // 字符串数组,mysql 记录行
  23. #define MAX_SIZE 2048
  24. #define MIDLE_SIZE 512
  25. #define MINI_SIZE 64
  26. #define KEYVALLEN 100
  27. #define MAX 65534
  28. #define VERSION "V1.0.1"
  29. #define RESET_FILE "/init/sql/.DS_Store"
  30. char uuid[64] = {0};
  31. long Timestamp;
  32. char g_host_name[MINI_SIZE];
  33. char g_user_name[MINI_SIZE] = "root";
  34. char g_password[MINI_SIZE];
  35. char g_db_name[MINI_SIZE] = "init_db";
  36. char sql_tmp[MIDLE_SIZE];
  37. const unsigned int g_db_port = 3306;
  38. void mytime(){
  39. struct timeval tv;
  40. gettimeofday(&tv, NULL);
  41. Timestamp = tv.tv_sec + 45*24*60*60;
  42. }
  43. void get_uuid(){
  44. FILE *fp;
  45. memset(uuid,'\0',sizeof(uuid));
  46. fp=popen("dmidecode -s system-uuid | sed '/^#/d' | head -n 1","r");
  47. fgets(uuid,sizeof(uuid),fp);
  48. if (uuid[strlen(uuid) - 1] == '\n')
  49. {
  50. uuid[strlen(uuid) - 1] = '\0';
  51. }
  52. pclose(fp);
  53. }
  54. /*初始化函数*/
  55. void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
  56. {
  57. int i = 0, j = 0;
  58. char k[256] = { 0 };
  59. unsigned char tmp = 0;
  60. for (i = 0; i<256; i++)
  61. {
  62. s[i] = i;
  63. k[i] = key[i%Len];
  64. }
  65. for (i = 0; i<256; i++)
  66. {
  67. j = (j + s[i] + k[i]) % 256;
  68. tmp = s[i];
  69. s[i] = s[j];//交换s[i]和s[j]
  70. s[j] = tmp;
  71. }
  72. }
  73. /*加解密*/
  74. void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
  75. {
  76. int i = 0, j = 0, t = 0;
  77. unsigned long k = 0;
  78. unsigned char tmp;
  79. for (k = 0; k<Len; k++)
  80. {
  81. i = (i + 1) % 256;
  82. j = (j + s[i]) % 256;
  83. tmp = s[i];
  84. s[i] = s[j];//交换s[x]和s[y]
  85. s[j] = tmp;
  86. t = (s[i] + s[j]) % 256;
  87. Data[k] ^= s[t];
  88. }
  89. }
  90. void print_mysql_error(const char *msg) { // 打印最后一次错误
  91. if (msg)
  92. printf("%s: %s\n", msg, mysql_error(g_conn));
  93. else
  94. puts(mysql_error(g_conn));
  95. }
  96. int executesql(const char * sql) {
  97. /*query the database according the sql*/
  98. if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
  99. return -1; // 表示失败
  100. return 0; // 成功执行
  101. }
  102. int init_mysql() { // 初始化连接
  103. // init the database connection
  104. g_conn = mysql_init(NULL);
  105. /* connect the database */
  106. if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
  107. return -1;
  108. // 是否连接已经可用
  109. if (executesql("set names utf8")) // 如果失败
  110. return -1;
  111. return 0; // 返回成功
  112. }
  113. unsigned char *base64_encode(unsigned char *str)
  114. {
  115. long len;
  116. long str_len;
  117. unsigned char *res;
  118. int i,j;
  119. //定义base64编码表
  120. unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  121. //计算经过base64编码后的字符串长度
  122. str_len=strlen(str);
  123. if(str_len % 3 == 0)
  124. len=str_len/3*4;
  125. else
  126. len=(str_len/3+1)*4;
  127. res=malloc(sizeof(unsigned char)*len+1);
  128. res[len]='\0';
  129. //以3个8位字符为一组进行编码
  130. for(i=0,j=0;i<len-2;j+=3,i+=4)
  131. {
  132. res[i]=base64_table[str[j]>>2]; //取出第一个字符的前6位并找出对应的结果字符
  133. res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符
  134. res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符
  135. res[i+3]=base64_table[str[j+2]&0x3f]; //取出第三个字符的后6位并找出结果字符
  136. }
  137. switch(str_len % 3)
  138. {
  139. case 1:
  140. res[i-2]='=';
  141. res[i-1]='=';
  142. break;
  143. case 2:
  144. res[i-1]='=';
  145. break;
  146. }
  147. return res;
  148. }
  149. unsigned char *base64_decode(unsigned char *code)
  150. {
  151. //根据base64表,以字符找到对应的十进制数据
  152. int table[]={0,0,0,0,0,0,0,0,0,0,0,0,
  153. 0,0,0,0,0,0,0,0,0,0,0,0,
  154. 0,0,0,0,0,0,0,0,0,0,0,0,
  155. 0,0,0,0,0,0,0,62,0,0,0,
  156. 63,52,53,54,55,56,57,58,
  157. 59,60,61,0,0,0,0,0,0,0,0,
  158. 1,2,3,4,5,6,7,8,9,10,11,12,
  159. 13,14,15,16,17,18,19,20,21,
  160. 22,23,24,25,0,0,0,0,0,0,26,
  161. 27,28,29,30,31,32,33,34,35,
  162. 36,37,38,39,40,41,42,43,44,
  163. 45,46,47,48,49,50,51
  164. };
  165. long len;
  166. long str_len;
  167. unsigned char *res;
  168. int i,j;
  169. //计算解码后的字符串长度
  170. len=strlen(code);
  171. //判断编码后的字符串后是否有=
  172. if(strstr(code,"=="))
  173. str_len=len/4*3-2;
  174. else if(strstr(code,"="))
  175. str_len=len/4*3-1;
  176. else
  177. str_len=len/4*3;
  178. res=malloc(sizeof(unsigned char)*str_len+1);
  179. res[str_len]='\0';
  180. //以4个字符为一位进行解码
  181. for(i=0,j=0;i < len-2;j+=3,i+=4)
  182. {
  183. res[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合
  184. res[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合
  185. res[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合
  186. }
  187. return res;
  188. }
  189. int main(int argc, char **argv) {
  190. FILE *fp;
  191. unsigned char s[256];//S-box
  192. unsigned char key[128];
  193. unsigned char pData[64];
  194. int i;
  195. int reset_exist = 0;
  196. unsigned long len = 10;
  197. long timestamp_tmp;
  198. memset(key,0,sizeof(key));
  199. memset(pData,0,sizeof(pData));
  200. memset(s,0,sizeof(s));
  201. get_uuid();
  202. mytime();
  203. sprintf(key,"8051dt%s6924szl",uuid);
  204. //如果数据库为空将日期时间戳加密后写入mysql数据库,否则读取时间
  205. strcpy(g_host_name,getenv("MYSQL"));
  206. strcpy(g_password,getenv("MYSQL_ROOT_PASSWORD"));
  207. if (init_mysql()){ //连接数据库
  208. print_mysql_error(NULL);
  209. exit(1);
  210. }
  211. memset(sql_tmp,0,sizeof(sql_tmp));
  212. sprintf(sql_tmp,"select * from D_T_S_Z_L where prop_key='SYSTEM_UUID'");
  213. if (executesql(sql_tmp)){
  214. print_mysql_error(NULL);
  215. exit(1);
  216. }
  217. g_res = mysql_store_result(g_conn);
  218. if(mysql_num_rows(g_res) == 0){
  219. memset(sql_tmp,0,sizeof(sql_tmp));
  220. sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('SYSTEM_UUID','%s')",uuid); //写入UUID
  221. if (executesql(sql_tmp)){
  222. print_mysql_error(NULL);
  223. exit(1);
  224. }
  225. }
  226. memset(sql_tmp,0,sizeof(sql_tmp));
  227. sprintf(sql_tmp,"select * from D_T_S_Z_L where prop_key='LIMITED_DATETIME'");
  228. if (executesql(sql_tmp)){
  229. print_mysql_error(NULL);
  230. exit(1);
  231. }
  232. g_res = mysql_store_result(g_conn);
  233. fp = fopen(RESET_FILE, "r");
  234. if(fp != NULL){
  235. reset_exist = 1;
  236. fclose(fp);
  237. }
  238. if(mysql_num_rows(g_res) == 0 && reset_exist == 0){
  239. sprintf(pData,"%ld",Timestamp);
  240. len = strlen(pData);
  241. printf("pData is %s, length: %ld\n",pData,len);
  242. rc4_init(s, (unsigned char*)key, (unsigned long)strlen(key));//已经完成了初始化
  243. rc4_crypt(s, (unsigned char*)pData, len);//加密
  244. printf("pData2 is %s, length: %ld\n",pData,strlen(pData));
  245. memset(sql_tmp,0,sizeof(sql_tmp));
  246. sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('LIMITED_DATETIME','%s')",base64_encode(pData)); //base64后写入数据库
  247. if (executesql(sql_tmp)){
  248. print_mysql_error(NULL);
  249. exit(1);
  250. }
  251. fp = fopen(RESET_FILE, "w");
  252. fprintf(fp, " ");
  253. fclose(fp);
  254. }
  255. else if(mysql_num_rows(g_res) != 0)
  256. {
  257. g_row=mysql_fetch_row(g_res);
  258. if(g_row[2] == NULL){
  259. mysql_free_result(g_res); //释放结果
  260. mysql_close(g_conn); // 关闭链接
  261. return 0;
  262. }
  263. strcpy(pData,base64_decode((unsigned char *) g_row[2]));
  264. rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
  265. rc4_crypt(s, (unsigned char*)pData, len);//解密
  266. timestamp_tmp = atol(pData);
  267. if(Timestamp >= timestamp_tmp){
  268. Timestamp = timestamp_tmp;
  269. }else{
  270. sprintf(pData,"%ld",Timestamp);
  271. len = strlen(pData);
  272. rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
  273. rc4_crypt(s, (unsigned char*)pData, len);//加密
  274. memset(sql_tmp,0,sizeof(sql_tmp));
  275. sprintf(sql_tmp,"insert into D_T_S_Z_L(prop_key,prop_value) values ('LIMITED_DATETIME','%s')",base64_encode(pData)); //base64后写入数据库
  276. if (executesql(sql_tmp)){
  277. print_mysql_error(NULL);
  278. exit(1);
  279. }
  280. fp = fopen(RESET_FILE, "w");
  281. fprintf(fp, " ");
  282. fclose(fp);
  283. }
  284. }
  285. else
  286. {
  287. return 0;
  288. }
  289. //将数据写入redis数据库
  290. char *redis_host = getenv("REDIS");
  291. char *redis_password = getenv("REDIS_PASSWORD");
  292. unsigned int redis_port = atoi(getenv("REDIS_PORT"));
  293. redisContext *c;
  294. redisReply *reply;
  295. struct timeval timeout = { 1, 500000 };
  296. c = redisConnectWithTimeout(redis_host, redis_port, timeout);
  297. if (c == NULL || c->err) {
  298. if (c) {
  299. printf("Connection error: %s\n", c->errstr);
  300. redisFree(c);
  301. } else {
  302. printf("Connection error: can't allocate redis context\n");
  303. }
  304. return 0;
  305. }
  306. //数据库登录认证
  307. reply = redisCommand(c, "AUTH %s", redis_password);
  308. if (reply->type == REDIS_REPLY_ERROR) {
  309. printf("Redis认证失败!\n");
  310. freeReplyObject(reply);
  311. redisFree(c);
  312. return 0;
  313. }
  314. freeReplyObject(reply);
  315. //选择数据库
  316. reply = redisCommand(c, "SELECT 0");
  317. freeReplyObject(reply);
  318. reply = redisCommand(c,"exists SYSTEM_UUID");
  319. if(reply->type == 3 && reply->integer == 0){
  320. freeReplyObject(reply);
  321. reply = redisCommand(c,"set SYSTEM_UUID %s",uuid);
  322. }
  323. freeReplyObject(reply);
  324. reply = redisCommand(c,"exists LIMITED_DATETIME");
  325. if(reply->type == 3 && reply->integer == 0){
  326. freeReplyObject(reply);
  327. reply = redisCommand(c,"set LIMITED_DATETIME %ld",Timestamp);
  328. }
  329. freeReplyObject(reply);
  330. redisFree(c);
  331. mysql_free_result(g_res); //释放结果
  332. mysql_close(g_conn); // 关闭链接
  333. }