mail.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. #include <stdint.h>
  2. #include <pthread.h>
  3. #include "cfg.h"
  4. #include "common.h"
  5. #include "thread.h"
  6. #include "xlist.h"
  7. #include "elog.h"
  8. #include "lock.h"
  9. #include "sqlite_handle.h"
  10. #include <curl/curl.h>
  11. #include "mail.h"
  12. #if 1
  13. #define LOGD log_d
  14. #define LOGE log_e
  15. #define LOGW log_w
  16. #else
  17. #define LOGD printf
  18. #define LOGE printf
  19. #define LOGW printf
  20. #endif
  21. typedef struct {
  22. char sub[128];
  23. char body[2048];
  24. char attach[128];
  25. }mail_pkt_t;
  26. typedef struct {
  27. handle_t list;
  28. mail_info_t *info;
  29. GlobalDeviceManager *dm;
  30. int inited;
  31. }mail_handle_t;
  32. static mail_handle_t maHandle;
  33. static char send_buff[1024] = {0};
  34. struct upload_status
  35. {
  36. size_t bytes_read;
  37. };
  38. static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
  39. {
  40. struct upload_status *upload_ctx = (struct upload_status *)userp;
  41. const char *data;
  42. size_t room = size * nmemb;
  43. if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
  44. return 0;
  45. }
  46. data = &send_buff[upload_ctx->bytes_read];
  47. if(data) {
  48. size_t len = strlen(data);
  49. if(room < len)
  50. len = room;
  51. memcpy(ptr, data, len);
  52. upload_ctx->bytes_read += len;
  53. return len;
  54. }
  55. return 0;
  56. }
  57. static void fill_send_buff(const char *to,const char *from,const char *subject,const char *body)
  58. {
  59. time_t timer;//time_t就是long int 类型
  60. struct tm *tblock;
  61. timer = time(NULL);
  62. tblock = localtime(&timer);
  63. memset(send_buff,0,1024);
  64. sprintf(send_buff,"Subject: %s\r\n"
  65. "From: %s\r\n"
  66. "To: %s\r\n"
  67. "Date: %s\r\n"
  68. "\r\n"
  69. "%s\r\n"
  70. "\r\n",subject,from,to,asctime(tblock),body);
  71. }
  72. static int send_mail(mail_send_t *send, void *addr, char *sub, char *body, char *attach, int multi)
  73. {
  74. int i=0;
  75. CURLcode r=CURLE_OK;
  76. char tmp[100];
  77. char url_buff[256]={0};
  78. char to_buff[256]={0};
  79. mail_handle_t *h=&maHandle;
  80. struct upload_status upload_ctx = { 0 };
  81. struct curl_slist *recipients = NULL;
  82. mail_recv_t *recv=(mail_recv_t*)addr;
  83. curl_mime *mm=NULL;
  84. lock_s_hold(LOCK_ID_MAIL);
  85. CURL *curl = curl_easy_init();
  86. if(!curl) {
  87. goto out;
  88. }
  89. sprintf(url_buff,"%s:%s",send->server,send->port);
  90. r = curl_easy_setopt(curl,CURLOPT_URL,url_buff);
  91. //curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXPN");
  92. //curl_easy_setopt(curl, CURLOPT_MAIL_AUTH, "<secret@cave>");
  93. //curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "ursel");
  94. //sprintf(tmp, "AUTH=%s", send->auth);
  95. //curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, tmp);
  96. r = curl_easy_setopt(curl, CURLOPT_USERNAME, send->account); //setting user
  97. r = curl_easy_setopt(curl, CURLOPT_PASSWORD, send->password); //setting password
  98. if(strcmp(send->port, "587")==0) { //tls
  99. r = curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); //setting openssl/tls
  100. //curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
  101. }
  102. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
  103. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
  104. //curl_easy_setopt(curl, CURLOPT_USERAGENT, CLIENT_USERAGENT);
  105. r = curl_easy_setopt(curl, CURLOPT_MAIL_FROM, send->account);
  106. r = curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
  107. r = curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
  108. if(attach && strlen(attach)>0) {
  109. mm = curl_mime_init(curl);
  110. if(mm) {
  111. curl_mimepart *part = curl_mime_addpart(mm);
  112. curl_mime_name(part, "file");
  113. curl_mime_filedata(part, attach);
  114. }
  115. }
  116. if(multi) {
  117. for(int i=0; i<MAIL_RECV_MAX; i++) {
  118. if(recv[i].use && strlen(recv[i].account)>0) {
  119. recipients = curl_slist_append(recipients, recv[i].account);
  120. //recipients = curl_slist_append(recipients, CC_MAIL);
  121. strcat(to_buff,recv[i].account);
  122. strcat(to_buff,";");
  123. }
  124. }
  125. }
  126. else {
  127. char *sendto=(char*)addr;
  128. recipients = curl_slist_append(recipients,sendto);
  129. strcat(to_buff,sendto);
  130. strcat(to_buff,";");
  131. }
  132. fill_send_buff(to_buff,send->account,sub,body);
  133. r = curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
  134. r = curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
  135. r = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
  136. r = curl_easy_perform(curl);
  137. if(r != CURLE_OK) {
  138. LOGE("send mail failed, %s\n", curl_easy_strerror(r));
  139. }
  140. else {
  141. LOGD("send mail ok!\n");
  142. }
  143. curl_slist_free_all(recipients);
  144. curl_mime_free(mm);
  145. out:
  146. if(curl) curl_easy_cleanup(curl);
  147. lock_s_release(LOCK_ID_MAIL);
  148. return (r==CURLE_OK)?0:-1;
  149. }
  150. ////////////////////////////////////////////////////////////////////////////
  151. static void sleep_ms(int ms)
  152. {
  153. usleep(ms*1000);
  154. }
  155. static void* mail_thread(void *arg)
  156. {
  157. #ifdef USE_MAIL
  158. int r;
  159. thread_handle_t *th=(thread_handle_t*)arg;
  160. mail_handle_t *h=(mail_handle_t*)th->arg;
  161. list_node_t *ln=NULL;
  162. mail_pkt_t *pkt=NULL;
  163. mail_send_t *send=&h->info->send;
  164. mail_recv_t *recv=h->info->recv;
  165. while(th->quit==0) {
  166. r = xlist_take_node(h->list, &ln, 0);
  167. if(r==0) {
  168. pkt = (mail_pkt_t*)ln->data.buf;
  169. send_mail(send, recv, pkt->sub, pkt->body, pkt->attach, 1);
  170. xlist_back_node(h->list, ln);
  171. }
  172. sleep_ms(100);
  173. }
  174. #endif
  175. pthread_exit(NULL);
  176. }
  177. int mail_init(void)
  178. {
  179. #ifdef USE_MAIL
  180. list_cfg_t lc;
  181. mail_handle_t *h=&maHandle;
  182. GlobalDeviceManager *dm=&__globalDeviceManage;
  183. lc.mode = LIST_FULL_FIFO;
  184. lc.max = 100;
  185. lc.log = 0;
  186. h->list = xlist_init(&lc);
  187. h->dm = dm;
  188. h->info = &h->dm->mailInfo;
  189. dev_mail_init(dm->db, h->info);
  190. thread_start(THREAD_ID_MAIL, mail_thread, h);
  191. h->inited = 1;
  192. //mail_test();
  193. #endif
  194. return 0;
  195. }
  196. int mail_deinit(void)
  197. {
  198. #ifdef USE_MAIL
  199. mail_handle_t *h=&maHandle;
  200. thread_stop(THREAD_ID_MAIL);
  201. xlist_free(h->list);
  202. h->inited = 0;
  203. #endif
  204. return 0;
  205. }
  206. static int post_data(char *sub, char *body, char *attach)
  207. {
  208. int r=0;
  209. #ifdef USE_MAIL
  210. mail_pkt_t pkt;
  211. mail_handle_t *h=&maHandle;
  212. snprintf(pkt.sub, sizeof(pkt.sub), "%s", sub?sub:"");
  213. snprintf(pkt.body, sizeof(pkt.body), "%s", body?body:"");
  214. snprintf(pkt.attach, sizeof(pkt.attach), "%s", attach?attach:"");
  215. r = xlist_append(h->list, 0, &pkt, sizeof(pkt));
  216. #endif
  217. return r;
  218. }
  219. int mail_send(char *sub, char *body, char *attach)
  220. {
  221. int r=-1;
  222. #ifdef USE_MAIL
  223. mail_handle_t *h=&maHandle;
  224. if(!h->inited || !h->info || !h->info->send.mode) {
  225. return -1;
  226. }
  227. r = send_mail(&h->info->send, h->info->recv, sub?sub:"", body?body:"", attach?attach:"", 1);
  228. #endif
  229. return r;
  230. }
  231. int mail_post(char *sub, char *body, char *attach)
  232. {
  233. int r=-1;
  234. #ifdef USE_MAIL
  235. mail_handle_t *h=&maHandle;
  236. if(!h->inited || !h->info || !h->info->send.mode) {
  237. return -1;
  238. }
  239. r = post_data(sub, body, attach);
  240. #endif
  241. return r;
  242. }
  243. int mail_post_alarm(int type, int subtype, int alarm_type, char *content)
  244. {
  245. int r=0;
  246. #ifdef USE_MAIL
  247. mail_pkt_t pkt;
  248. char temp[128];
  249. mail_handle_t *h=&maHandle;
  250. if(!h->inited || !content || !h->info || !h->info->send.mode) {
  251. return -1;
  252. }
  253. char *prod_name=h->dm->_globalDevInfo.product.name;
  254. int prod_id=h->dm->_globalDevInfo.product.id;
  255. int langID=h->dm->_globalDevInfo.product.language;
  256. switch(type) {
  257. case ALARM_TYPE_POWER:
  258. {
  259. if(subtype) {
  260. switch(alarm_type) {
  261. case ENABLE_TAC_V_UP:
  262. case ENABLE_TAC_V_DOWN:
  263. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]);
  264. break;
  265. case ENABLE_TAC_A_UP:
  266. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]);
  267. break;
  268. case ENABLE_TAC_W_UP:
  269. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]);
  270. break;
  271. case ENABLE_TAC_P_UP:
  272. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]);
  273. break;
  274. case ENABLE_TAC_STIME:
  275. case ENABLE_TAC_ETIME:
  276. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]);
  277. break;
  278. default:
  279. return -1;
  280. }
  281. }
  282. else {
  283. switch(alarm_type) {
  284. case WARNING_V_UP:
  285. case WARNING_V_DOWN:
  286. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]);
  287. break;
  288. case WARNING_A_UP:
  289. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]);
  290. break;
  291. case WARNING_W_UP:
  292. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]);
  293. break;
  294. case WARNING_P_UP:
  295. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]);
  296. break;
  297. case 0 ... 2:
  298. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]);
  299. break;
  300. default:
  301. return -1;
  302. }
  303. }
  304. }
  305. break;
  306. case ALARM_TYPE_SENSOR:
  307. {
  308. switch(subtype) {
  309. case SENSOR_TYPE_DoubleT:
  310. case SENSOR_TYPE_TEMPERATURE:
  311. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_temperature[langID], language_alarm[langID]);
  312. break;
  313. case SENSOR_TYPE_SMOKE:
  314. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_sensor_smoke[langID], language_alarm[langID]);
  315. break;
  316. case SENSOR_TYPE_WATER:
  317. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_humidity[langID], language_alarm[langID]);
  318. break;
  319. case SENSOR_TYPE_DOOR:
  320. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_sensor_access[langID], language_alarm[langID]);
  321. break;
  322. case SENSOR_TYPE_GAS:
  323. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_atmosphere_gas[langID], language_alarm[langID]);
  324. break;
  325. case SENSOR_TYPE_AIR_PRESS:
  326. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_atmosphere_pressure[langID], language_alarm[langID]);
  327. break;
  328. default:
  329. return -1;
  330. }
  331. }
  332. break;
  333. case ALARM_TYPE_NETWORK:
  334. {
  335. snprintf(temp, sizeof(temp), "%s %d %s", prod_name, prod_id, language_alarm_Type_Network[langID]);
  336. }
  337. break;
  338. default:
  339. return -1;
  340. }
  341. replace_sequences(content, h->dm->alarmTab);
  342. r = post_data(temp, content, NULL);
  343. #endif
  344. return r;
  345. }
  346. int mail_test(void)
  347. {
  348. int r=0,cnt=0;
  349. #ifdef USE_MAIL
  350. char temp[200];
  351. mail_handle_t *h=&maHandle;
  352. mail_info_t info={
  353. .send = {
  354. .id = 0,
  355. .mode = 1,
  356. #if 0
  357. .account = "rcp064867@163.com",
  358. .password = "YWKVURARCJXYXQVS",
  359. .server = "smtp.163.com",
  360. .port = "25",
  361. //.port = "465",
  362. //.port = "587",
  363. .auth = "PLAIN",
  364. //.auth = "LOGIN",
  365. //.auth = "CRAM-MD5",
  366. #else
  367. .account = "jiuci4902@gmail.com",
  368. .password = "wmfoedxaycdwllvs",
  369. .server = "smtp.gmail.com",
  370. //.port = "25",
  371. //.port = "465",
  372. .port = "587",
  373. //.auth = "PLAIN",
  374. .auth = "LOGIN",
  375. //.auth = "CRAM-MD5",
  376. #endif
  377. },
  378. .recv = {
  379. {0, 1, "1556907721@qq.com"},
  380. {1, 1, "rcp064867@163.com"},
  381. {2, 1, "cijiu0219@sina.com"},
  382. {3, 1, "jiuci4902@gmail.com"},
  383. {4, 1, "cijiu0219@hotmail.com"},
  384. {5, 1, "cijiu990219@outlook.com"},
  385. {6, 1, "iauther@163.com"},
  386. }
  387. };
  388. *h->info = info;
  389. char *sub="123";
  390. char *body="hello everyone";
  391. while(cnt++<5) {
  392. sprintf(temp, "%s %d", body, cnt);
  393. r = mail_send(sub, temp, NULL);
  394. sleep(2);
  395. }
  396. #endif
  397. return r;
  398. }