esl.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638
  1. /*
  2. * Copyright (c) 2007-2014, Anthony Minessale II
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of the original author; nor the names of any contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  25. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. /* Use select on windows and poll everywhere else.
  34. Select is the devil. Especially if you are doing a lot of small socket connections.
  35. If your FD number is bigger than 1024 you will silently create memory corruption.
  36. If you have build errors on your platform because you don't have poll find a way to detect it and #define ESL_USE_SELECT and #undef ESL_USE_POLL
  37. All of this will be upgraded to autoheadache eventually.
  38. */
  39. /* TBD for win32 figure out how to tell if you have WSAPoll (vista or higher) and use it when available by #defining ESL_USE_WSAPOLL (see below) */
  40. #ifdef _MSC_VER
  41. #define FD_SETSIZE 8192
  42. #define ESL_USE_SELECT
  43. #else
  44. #define ESL_USE_POLL
  45. #endif
  46. #include <esl.h>
  47. #ifndef WIN32
  48. #define closesocket(x) shutdown(x, 2); close(x)
  49. #include <fcntl.h>
  50. #include <errno.h>
  51. #else
  52. #pragma warning (disable:6386)
  53. /* These warnings need to be ignored warning in sdk header */
  54. #include <Ws2tcpip.h>
  55. #include <windows.h>
  56. #include <errno.h>
  57. #ifndef errno
  58. #define errno WSAGetLastError()
  59. #endif
  60. #ifndef EINTR
  61. #define EINTR WSAEINTR
  62. #endif
  63. #pragma warning (default:6386)
  64. #endif
  65. #ifdef ESL_USE_POLL
  66. #include <poll.h>
  67. #endif
  68. #ifndef ESL_MIN
  69. #define ESL_MIN(x,y) ((x) < (y) ? (x) : (y))
  70. #endif
  71. #ifndef ESL_MAX
  72. #define ESL_MAX(x,y) ((x) > (y) ? (x) : (y))
  73. #endif
  74. #ifndef ESL_CLAMP
  75. #define ESL_CLAMP(min,max,val) (ESL_MIN(max,ESL_MAX(val,min)))
  76. #endif
  77. /* Written by Marc Espie, public domain */
  78. #define ESL_CTYPE_NUM_CHARS 256
  79. const short _esl_C_toupper_[1 + ESL_CTYPE_NUM_CHARS] = {
  80. EOF,
  81. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  82. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  83. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  84. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  85. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  86. 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  87. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  88. 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  89. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  90. 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  91. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  92. 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  93. 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  94. 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  95. 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  96. 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  97. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  98. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  99. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  100. 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  101. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  102. 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  103. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  104. 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  105. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  106. 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  107. 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  108. 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  109. 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  110. 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  111. 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  112. 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  113. };
  114. const short *_esl_toupper_tab_ = _esl_C_toupper_;
  115. ESL_DECLARE(int) esl_toupper(int c)
  116. {
  117. if ((unsigned int)c > 255)
  118. return(c);
  119. if (c < -1)
  120. return EOF;
  121. return((_esl_toupper_tab_ + 1)[c]);
  122. }
  123. const short _esl_C_tolower_[1 + ESL_CTYPE_NUM_CHARS] = {
  124. EOF,
  125. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  126. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  127. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  128. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  129. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  130. 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  131. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  132. 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  133. 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  134. 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  135. 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  136. 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  137. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  138. 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  139. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  140. 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  141. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  142. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  143. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  144. 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  145. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  146. 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  147. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  148. 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  149. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  150. 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  151. 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  152. 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  153. 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  154. 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  155. 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  156. 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  157. };
  158. const short *_esl_tolower_tab_ = _esl_C_tolower_;
  159. ESL_DECLARE(int) esl_tolower(int c)
  160. {
  161. if ((unsigned int)c > 255)
  162. return(c);
  163. if (c < -1)
  164. return EOF;
  165. return((_esl_tolower_tab_ + 1)[c]);
  166. }
  167. ESL_DECLARE(const char *)esl_stristr(const char *instr, const char *str)
  168. {
  169. /*
  170. ** Rev History: 16/07/97 Greg Thayer Optimized
  171. ** 07/04/95 Bob Stout ANSI-fy
  172. ** 02/03/94 Fred Cole Original
  173. ** 09/01/03 Bob Stout Bug fix (lines 40-41) per Fred Bulback
  174. **
  175. ** Hereby donated to public domain.
  176. */
  177. const char *pptr, *sptr, *start;
  178. if (!str || !instr)
  179. return NULL;
  180. for (start = str; *start; start++) {
  181. /* find start of pattern in string */
  182. for (; ((*start) && (esl_toupper(*start) != esl_toupper(*instr))); start++);
  183. if (!*start)
  184. return NULL;
  185. pptr = instr;
  186. sptr = start;
  187. while (esl_toupper(*sptr) == esl_toupper(*pptr)) {
  188. sptr++;
  189. pptr++;
  190. /* if end of pattern then pattern was found */
  191. if (!*pptr)
  192. return (start);
  193. if (!*sptr)
  194. return NULL;
  195. }
  196. }
  197. return NULL;
  198. }
  199. #ifdef WIN32
  200. #ifndef vsnprintf
  201. #define vsnprintf _vsnprintf
  202. #endif
  203. #endif
  204. int vasprintf(char **ret, const char *format, va_list ap);
  205. ESL_DECLARE(int) esl_vasprintf(char **ret, const char *fmt, va_list ap)
  206. {
  207. #if !defined(WIN32) && !defined(__sun)
  208. return vasprintf(ret, fmt, ap);
  209. #else
  210. char *buf;
  211. int len;
  212. size_t buflen;
  213. va_list ap2;
  214. char *tmp = NULL;
  215. #ifdef _MSC_VER
  216. #if _MSC_VER >= 1500
  217. /* hack for incorrect assumption in msvc header files for code analysis */
  218. __analysis_assume(tmp);
  219. #endif
  220. ap2 = ap;
  221. #else
  222. va_copy(ap2, ap);
  223. #endif
  224. len = vsnprintf(tmp, 0, fmt, ap2);
  225. if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) {
  226. len = vsnprintf(buf, buflen, fmt, ap);
  227. *ret = buf;
  228. } else {
  229. *ret = NULL;
  230. len = -1;
  231. }
  232. va_end(ap2);
  233. return len;
  234. #endif
  235. }
  236. ESL_DECLARE(int) esl_snprintf(char *buffer, size_t count, const char *fmt, ...)
  237. {
  238. va_list ap;
  239. int ret;
  240. va_start(ap, fmt);
  241. ret = vsnprintf(buffer, count-1, fmt, ap);
  242. if (ret < 0)
  243. buffer[count-1] = '\0';
  244. va_end(ap);
  245. return ret;
  246. }
  247. static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
  248. {
  249. if (file && func && line && level && fmt) {
  250. return;
  251. }
  252. return;
  253. }
  254. static const char *LEVEL_NAMES[] = {
  255. "EMERG",
  256. "ALERT",
  257. "CRIT",
  258. "ERROR",
  259. "WARNING",
  260. "NOTICE",
  261. "INFO",
  262. "DEBUG",
  263. NULL
  264. };
  265. static int esl_log_level = 7;
  266. static const char *cut_path(const char *in)
  267. {
  268. const char *p, *ret = in;
  269. char delims[] = "/\\";
  270. char *i;
  271. for (i = delims; *i; i++) {
  272. p = in;
  273. while ((p = strchr(p, *i)) != 0) {
  274. ret = ++p;
  275. }
  276. }
  277. return ret;
  278. }
  279. static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
  280. {
  281. const char *fp;
  282. char *data;
  283. va_list ap;
  284. int ret;
  285. if (level < 0 || level > 7) {
  286. level = 7;
  287. }
  288. if (level > esl_log_level) {
  289. return;
  290. }
  291. fp = cut_path(file);
  292. va_start(ap, fmt);
  293. ret = esl_vasprintf(&data, fmt, ap);
  294. if (ret != -1) {
  295. fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
  296. free(data);
  297. }
  298. va_end(ap);
  299. }
  300. esl_logger_t esl_log = null_logger;
  301. ESL_DECLARE(void) esl_global_set_logger(esl_logger_t logger)
  302. {
  303. if (logger) {
  304. esl_log = logger;
  305. } else {
  306. esl_log = null_logger;
  307. }
  308. }
  309. ESL_DECLARE(void) esl_global_set_default_logger(int level)
  310. {
  311. if (level < 0 || level > 7) {
  312. level = 7;
  313. }
  314. esl_log = default_logger;
  315. esl_log_level = level;
  316. }
  317. ESL_DECLARE(size_t) esl_url_encode(const char *url, char *buf, size_t len)
  318. {
  319. const char *p;
  320. size_t x = 0;
  321. const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}";
  322. const char hex[] = "0123456789ABCDEF";
  323. if (!buf) {
  324. return 0;
  325. }
  326. if (!url) {
  327. return 0;
  328. }
  329. len--;
  330. for (p = url; *p; p++) {
  331. if (x >= len) {
  332. break;
  333. }
  334. if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) {
  335. if ((x + 3) >= len) {
  336. break;
  337. }
  338. buf[x++] = '%';
  339. buf[x++] = hex[*p >> 4];
  340. buf[x++] = hex[*p & 0x0f];
  341. } else {
  342. buf[x++] = *p;
  343. }
  344. }
  345. buf[x] = '\0';
  346. return x;
  347. }
  348. ESL_DECLARE(char *)esl_url_decode(char *s)
  349. {
  350. char *o;
  351. unsigned int tmp;
  352. for (o = s; *s; s++, o++) {
  353. if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
  354. *o = (char) tmp;
  355. s += 2;
  356. } else {
  357. *o = *s;
  358. }
  359. }
  360. *o = '\0';
  361. return s;
  362. }
  363. static int sock_setup(esl_handle_t *handle)
  364. {
  365. if (handle->sock == ESL_SOCK_INVALID) {
  366. return ESL_FAIL;
  367. }
  368. #ifdef WIN32
  369. {
  370. BOOL bOptVal = TRUE;
  371. int bOptLen = sizeof(BOOL);
  372. setsockopt(handle->sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&bOptVal, bOptLen);
  373. }
  374. #else
  375. {
  376. int x = 1;
  377. setsockopt(handle->sock, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
  378. }
  379. #endif
  380. return ESL_SUCCESS;
  381. }
  382. ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t socket, struct sockaddr_in *addr)
  383. {
  384. if (!handle || socket == ESL_SOCK_INVALID) {
  385. return ESL_FAIL;
  386. }
  387. handle->sock = socket;
  388. if (addr) {
  389. handle->addr = *addr;
  390. }
  391. if (sock_setup(handle) != ESL_SUCCESS) {
  392. return ESL_FAIL;
  393. }
  394. if (!handle->mutex) {
  395. esl_mutex_create(&handle->mutex);
  396. }
  397. if (!handle->packet_buf) {
  398. esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
  399. }
  400. handle->connected = 1;
  401. esl_send_recv(handle, "connect\n\n");
  402. if (handle->last_sr_event) {
  403. handle->info_event = handle->last_sr_event;
  404. handle->last_sr_event = NULL;
  405. return ESL_SUCCESS;
  406. }
  407. esl_disconnect(handle);
  408. return ESL_FAIL;
  409. }
  410. ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event)
  411. {
  412. char *txt;
  413. char *event_buf = NULL;
  414. esl_status_t status = ESL_FAIL;
  415. size_t len = 0;
  416. if (!handle->connected || !event) {
  417. return ESL_FAIL;
  418. }
  419. esl_event_serialize(event, &txt, ESL_FALSE);
  420. esl_log(ESL_LOG_DEBUG, "SEND EVENT\n%s\n", txt);
  421. len = strlen(txt) + 100;
  422. event_buf = malloc(len);
  423. assert(event_buf);
  424. if (!event_buf) {
  425. return ESL_FAIL;
  426. }
  427. memset(event_buf, 0, len);
  428. snprintf(event_buf, len, "sendevent %s\n%s", esl_event_name(event->event_id), txt);
  429. status = esl_send_recv(handle, event_buf);
  430. free(txt);
  431. free(event_buf);
  432. return status;
  433. }
  434. ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, const char *arg, const char *uuid)
  435. {
  436. char cmd_buf[128] = "sendmsg";
  437. char app_buf[512] = "";
  438. char arg_buf[4096] = "";
  439. const char *el_buf = "event-lock: true\n";
  440. const char *bl_buf = "async: true\n";
  441. char send_buf[5120] = "";
  442. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  443. return ESL_FAIL;
  444. }
  445. if (uuid) {
  446. snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg %s", uuid);
  447. }
  448. if (app) {
  449. snprintf(app_buf, sizeof(app_buf), "execute-app-name: %s\n", app);
  450. }
  451. if (arg) {
  452. snprintf(arg_buf, sizeof(arg_buf), "execute-app-arg: %s\n", arg);
  453. }
  454. snprintf(send_buf, sizeof(send_buf), "%s\ncall-command: execute\n%s%s%s%s\n",
  455. cmd_buf, app_buf, arg_buf, handle->event_lock ? el_buf : "", handle->async_execute ? bl_buf : "");
  456. return esl_send_recv(handle, send_buf);
  457. }
  458. ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event, const char *uuid)
  459. {
  460. char *cmd_buf = NULL;
  461. char *txt;
  462. size_t len = 0;
  463. esl_status_t status = ESL_FAIL;
  464. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  465. return ESL_FAIL;
  466. }
  467. esl_event_serialize(event, &txt, ESL_FALSE);
  468. len = strlen(txt) + 100;
  469. cmd_buf = malloc(len);
  470. assert(cmd_buf);
  471. if (!cmd_buf) {
  472. return ESL_FAIL;
  473. }
  474. memset(cmd_buf, 0, len);
  475. if (uuid) {
  476. snprintf(cmd_buf, len, "sendmsg %s\n%s", uuid, txt);
  477. } else {
  478. snprintf(cmd_buf, len, "sendmsg\n%s", txt);
  479. }
  480. esl_log(ESL_LOG_DEBUG, "%s%s\n", cmd_buf, txt);
  481. status = esl_send_recv(handle, cmd_buf);
  482. free(txt);
  483. free(cmd_buf);
  484. return status;
  485. }
  486. ESL_DECLARE(esl_status_t) esl_filter(esl_handle_t *handle, const char *header, const char *value)
  487. {
  488. char send_buf[1024] = "";
  489. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  490. return ESL_FAIL;
  491. }
  492. snprintf(send_buf, sizeof(send_buf), "filter %s %s\n\n", header, value);
  493. return esl_send_recv(handle, send_buf);
  494. }
  495. ESL_DECLARE(esl_status_t) esl_events(esl_handle_t *handle, esl_event_type_t etype, const char *value)
  496. {
  497. char send_buf[1024] = "";
  498. const char *type = "plain";
  499. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  500. return ESL_FAIL;
  501. }
  502. if (etype == ESL_EVENT_TYPE_XML) {
  503. type = "xml";
  504. } else if (etype == ESL_EVENT_TYPE_JSON) {
  505. type = "json";
  506. }
  507. snprintf(send_buf, sizeof(send_buf), "event %s %s\n\n", type, value);
  508. return esl_send_recv(handle, send_buf);
  509. }
  510. static int esl_socket_reuseaddr(esl_socket_t socket)
  511. {
  512. #ifdef WIN32
  513. BOOL reuse_addr = TRUE;
  514. return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr));
  515. #else
  516. int reuse_addr = 1;
  517. return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
  518. #endif
  519. }
  520. struct thread_handler {
  521. esl_listen_callback_t callback;
  522. esl_socket_t server_sock;
  523. esl_socket_t client_sock;
  524. struct sockaddr_in addr;
  525. void *user_data;
  526. };
  527. static void *client_thread(esl_thread_t *me, void *obj)
  528. {
  529. struct thread_handler *handler = (struct thread_handler *) obj;
  530. handler->callback(handler->server_sock, handler->client_sock, &handler->addr, handler->user_data);
  531. free(handler);
  532. return NULL;
  533. }
  534. static int prepare_sock(esl_socket_t sock)
  535. {
  536. int r = 0;
  537. #ifdef WIN32
  538. u_long arg = 1;
  539. if (ioctlsocket(sock, FIONBIO, &arg) == SOCKET_ERROR) {
  540. r = -1;
  541. }
  542. #else
  543. int fd_flags = fcntl(sock, F_GETFL, 0);
  544. if (fcntl(sock, F_SETFL, fd_flags | O_NONBLOCK)) {
  545. r = -1;
  546. }
  547. #endif
  548. return r;
  549. }
  550. ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, void *user_data, esl_socket_t *server_sockP)
  551. {
  552. esl_socket_t server_sock = ESL_SOCK_INVALID;
  553. struct sockaddr_in addr;
  554. esl_status_t status = ESL_SUCCESS;
  555. if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  556. return ESL_FAIL;
  557. }
  558. if (server_sockP) {
  559. *server_sockP = server_sock;
  560. }
  561. esl_socket_reuseaddr(server_sock);
  562. memset(&addr, 0, sizeof(addr));
  563. addr.sin_family = AF_INET;
  564. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  565. addr.sin_port = htons(port);
  566. if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  567. status = ESL_FAIL;
  568. goto end;
  569. }
  570. if (listen(server_sock, 10000) < 0) {
  571. status = ESL_FAIL;
  572. goto end;
  573. }
  574. for (;;) {
  575. int client_sock;
  576. struct sockaddr_in echoClntAddr;
  577. #ifdef WIN32
  578. int clntLen;
  579. #else
  580. unsigned int clntLen;
  581. #endif
  582. clntLen = sizeof(echoClntAddr);
  583. if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == ESL_SOCK_INVALID && errno != EINTR) {
  584. status = ESL_FAIL;
  585. goto end;
  586. }
  587. prepare_sock(client_sock);
  588. callback(server_sock, client_sock, &echoClntAddr, user_data);
  589. }
  590. end:
  591. if (server_sock != ESL_SOCK_INVALID) {
  592. closesocket(server_sock);
  593. }
  594. return status;
  595. }
  596. ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, void *user_data, int max)
  597. {
  598. esl_socket_t server_sock = ESL_SOCK_INVALID;
  599. struct sockaddr_in addr;
  600. esl_status_t status = ESL_SUCCESS;
  601. struct thread_handler *handler = NULL;
  602. if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  603. return ESL_FAIL;
  604. }
  605. esl_socket_reuseaddr(server_sock);
  606. memset(&addr, 0, sizeof(addr));
  607. addr.sin_family = AF_INET;
  608. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  609. addr.sin_port = htons(port);
  610. if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  611. status = ESL_FAIL;
  612. goto end;
  613. }
  614. if (listen(server_sock, max) < 0) {
  615. status = ESL_FAIL;
  616. goto end;
  617. }
  618. for (;;) {
  619. int client_sock;
  620. struct sockaddr_in echoClntAddr;
  621. #ifdef WIN32
  622. int clntLen;
  623. #else
  624. unsigned int clntLen;
  625. #endif
  626. clntLen = sizeof(echoClntAddr);
  627. if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == ESL_SOCK_INVALID && errno != EINTR) {
  628. status = ESL_FAIL;
  629. goto end;
  630. }
  631. prepare_sock(client_sock);
  632. handler = malloc(sizeof(*handler));
  633. esl_assert(handler);
  634. memset(handler, 0, sizeof(*handler));
  635. handler->callback = callback;
  636. handler->server_sock = server_sock;
  637. handler->client_sock = client_sock;
  638. handler->addr = echoClntAddr;
  639. handler->user_data = user_data;
  640. esl_thread_create_detached(client_thread, handler);
  641. }
  642. end:
  643. if (server_sock != ESL_SOCK_INVALID) {
  644. closesocket(server_sock);
  645. }
  646. return status;
  647. }
  648. /* USE WSAPoll on vista or higher */
  649. #ifdef ESL_USE_WSAPOLL
  650. ESL_DECLARE(int) esl_wait_sock(esl_socket_t sock, uint32_t ms, esl_poll_t flags)
  651. {
  652. }
  653. #endif
  654. #ifdef ESL_USE_SELECT
  655. #ifdef WIN32
  656. #pragma warning( push )
  657. #pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */
  658. #endif
  659. ESL_DECLARE(int) esl_wait_sock(esl_socket_t sock, uint32_t ms, esl_poll_t flags)
  660. {
  661. int s = 0, r = 0;
  662. fd_set rfds;
  663. fd_set wfds;
  664. fd_set efds;
  665. struct timeval tv;
  666. if (sock == ESL_SOCK_INVALID) {
  667. return ESL_SOCK_INVALID;
  668. }
  669. FD_ZERO(&rfds);
  670. FD_ZERO(&wfds);
  671. FD_ZERO(&efds);
  672. #ifndef WIN32
  673. /* Wouldn't you rather know?? */
  674. assert(sock <= FD_SETSIZE);
  675. #endif
  676. if ((flags & ESL_POLL_READ)) {
  677. #ifdef WIN32
  678. #pragma warning( push )
  679. #pragma warning( disable : 4127 )
  680. FD_SET(sock, &rfds);
  681. #pragma warning( pop )
  682. #else
  683. FD_SET(sock, &rfds);
  684. #endif
  685. }
  686. if ((flags & ESL_POLL_WRITE)) {
  687. #ifdef WIN32
  688. #pragma warning( push )
  689. #pragma warning( disable : 4127 )
  690. FD_SET(sock, &wfds);
  691. #pragma warning( pop )
  692. #else
  693. FD_SET(sock, &wfds);
  694. #endif
  695. }
  696. if ((flags & ESL_POLL_ERROR)) {
  697. #ifdef WIN32
  698. #pragma warning( push )
  699. #pragma warning( disable : 4127 )
  700. FD_SET(sock, &efds);
  701. #pragma warning( pop )
  702. #else
  703. FD_SET(sock, &efds);
  704. #endif
  705. }
  706. tv.tv_sec = ms / 1000;
  707. tv.tv_usec = (ms % 1000) * ms;
  708. s = select(sock + 1, (flags & ESL_POLL_READ) ? &rfds : NULL, (flags & ESL_POLL_WRITE) ? &wfds : NULL, (flags & ESL_POLL_ERROR) ? &efds : NULL, &tv);
  709. if (s < 0) {
  710. r = s;
  711. } else if (s > 0) {
  712. if ((flags & ESL_POLL_READ) && FD_ISSET(sock, &rfds)) {
  713. r |= ESL_POLL_READ;
  714. }
  715. if ((flags & ESL_POLL_WRITE) && FD_ISSET(sock, &wfds)) {
  716. r |= ESL_POLL_WRITE;
  717. }
  718. if ((flags & ESL_POLL_ERROR) && FD_ISSET(sock, &efds)) {
  719. r |= ESL_POLL_ERROR;
  720. }
  721. }
  722. return r;
  723. }
  724. #ifdef WIN32
  725. #pragma warning( pop )
  726. #endif
  727. #endif
  728. #ifdef ESL_USE_POLL
  729. ESL_DECLARE(int) esl_wait_sock(esl_socket_t sock, uint32_t ms, esl_poll_t flags)
  730. {
  731. struct pollfd pfds[2] = { { 0 } };
  732. int s = 0, r = 0;
  733. if (sock == ESL_SOCK_INVALID) {
  734. return ESL_SOCK_INVALID;
  735. }
  736. pfds[0].fd = sock;
  737. if ((flags & ESL_POLL_READ)) {
  738. pfds[0].events |= POLLIN;
  739. }
  740. if ((flags & ESL_POLL_WRITE)) {
  741. pfds[0].events |= POLLOUT;
  742. }
  743. if ((flags & ESL_POLL_ERROR)) {
  744. pfds[0].events |= POLLERR;
  745. }
  746. s = poll(pfds, 1, ms);
  747. if (s < 0) {
  748. r = s;
  749. } else if (s > 0) {
  750. if ((pfds[0].revents & POLLIN)) {
  751. r |= ESL_POLL_READ;
  752. }
  753. if ((pfds[0].revents & POLLOUT)) {
  754. r |= ESL_POLL_WRITE;
  755. }
  756. if ((pfds[0].revents & POLLERR)) {
  757. r |= ESL_POLL_ERROR;
  758. }
  759. }
  760. return r;
  761. }
  762. #endif
  763. ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password, uint32_t timeout)
  764. {
  765. char sendbuf[256];
  766. int rval = 0;
  767. const char *hval;
  768. struct addrinfo hints = { 0 }, *result;
  769. struct sockaddr_in *sockaddr_in;
  770. struct sockaddr_in6 *sockaddr_in6;
  771. socklen_t socklen;
  772. #ifndef WIN32
  773. int fd_flags = 0;
  774. #else
  775. WORD wVersionRequested = MAKEWORD(2, 0);
  776. WSADATA wsaData;
  777. int err = WSAStartup(wVersionRequested, &wsaData);
  778. if (err != 0) {
  779. snprintf(handle->err, sizeof(handle->err), "WSAStartup Error");
  780. goto fail;
  781. }
  782. #endif
  783. if (!handle->mutex) {
  784. esl_mutex_create(&handle->mutex);
  785. }
  786. if (!handle->packet_buf) {
  787. esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
  788. }
  789. hints.ai_socktype = SOCK_STREAM;
  790. if (getaddrinfo(host, NULL, &hints, &result)) {
  791. strncpy(handle->err, "Cannot resolve host", sizeof(handle->err));
  792. goto fail;
  793. }
  794. memcpy(&handle->sockaddr, result->ai_addr, result->ai_addrlen);
  795. switch(handle->sockaddr.ss_family) {
  796. case AF_INET:
  797. sockaddr_in = (struct sockaddr_in*)&(handle->sockaddr);
  798. sockaddr_in->sin_port = htons(port);
  799. socklen = sizeof(struct sockaddr_in);
  800. break;
  801. case AF_INET6:
  802. sockaddr_in6 = (struct sockaddr_in6*)&(handle->sockaddr);
  803. sockaddr_in6->sin6_port = htons(port);
  804. socklen = sizeof(struct sockaddr_in6);
  805. break;
  806. default:
  807. strncpy(handle->err, "Host resolves to unsupported address family", sizeof(handle->err));
  808. goto fail;
  809. }
  810. freeaddrinfo(result);
  811. handle->sock = socket(handle->sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
  812. if (handle->sock == ESL_SOCK_INVALID) {
  813. snprintf(handle->err, sizeof(handle->err), "Socket Error");
  814. goto fail;
  815. }
  816. if (timeout) {
  817. #ifdef WIN32
  818. u_long arg = 1;
  819. if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) {
  820. snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
  821. goto fail;
  822. }
  823. #else
  824. fd_flags = fcntl(handle->sock, F_GETFL, 0);
  825. if (fcntl(handle->sock, F_SETFL, fd_flags | O_NONBLOCK)) {
  826. snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
  827. goto fail;
  828. }
  829. #endif
  830. }
  831. rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, socklen);
  832. if (timeout) {
  833. int r;
  834. r = esl_wait_sock(handle->sock, timeout, ESL_POLL_WRITE);
  835. if (r <= 0) {
  836. snprintf(handle->err, sizeof(handle->err), "Connection timed out");
  837. goto fail;
  838. }
  839. if (!(r & ESL_POLL_WRITE)) {
  840. snprintf(handle->err, sizeof(handle->err), "Connection timed out");
  841. goto fail;
  842. }
  843. #ifdef WIN32
  844. {
  845. u_long arg = 0;
  846. if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) {
  847. snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
  848. goto fail;
  849. }
  850. }
  851. #else
  852. fcntl(handle->sock, F_SETFL, fd_flags);
  853. #endif
  854. rval = 0;
  855. }
  856. result = NULL;
  857. if (rval) {
  858. snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
  859. goto fail;
  860. }
  861. sock_setup(handle);
  862. handle->connected = 1;
  863. if (esl_recv_timed(handle, timeout)) {
  864. snprintf(handle->err, sizeof(handle->err), "Connection Error");
  865. goto fail;
  866. }
  867. hval = esl_event_get_header(handle->last_event, "content-type");
  868. if (esl_safe_strcasecmp(hval, "auth/request")) {
  869. snprintf(handle->err, sizeof(handle->err), "Connection Error");
  870. goto fail;
  871. }
  872. if (esl_strlen_zero(user)) {
  873. snprintf(sendbuf, sizeof(sendbuf), "auth %s\n\n", password);
  874. } else {
  875. snprintf(sendbuf, sizeof(sendbuf), "userauth %s:%s\n\n", user, password);
  876. }
  877. esl_send(handle, sendbuf);
  878. if (esl_recv_timed(handle, timeout)) {
  879. snprintf(handle->err, sizeof(handle->err), "Authentication Error");
  880. goto fail;
  881. }
  882. hval = esl_event_get_header(handle->last_event, "reply-text");
  883. if (esl_safe_strcasecmp(hval, "+OK accepted")) {
  884. snprintf(handle->err, sizeof(handle->err), "Authentication Error");
  885. goto fail;
  886. }
  887. return ESL_SUCCESS;
  888. fail:
  889. handle->connected = 0;
  890. return ESL_FAIL;
  891. }
  892. ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle)
  893. {
  894. esl_mutex_t *mutex = handle->mutex;
  895. esl_status_t status = ESL_FAIL;
  896. esl_event_t *ep;
  897. if (handle->destroyed) {
  898. return ESL_FAIL;
  899. }
  900. if (handle->sock != ESL_SOCK_INVALID) {
  901. closesocket(handle->sock);
  902. handle->sock = ESL_SOCK_INVALID;
  903. status = ESL_SUCCESS;
  904. }
  905. if (mutex) {
  906. esl_mutex_lock(mutex);
  907. }
  908. handle->connected = 0;
  909. ep = handle->race_event;
  910. while(ep) {
  911. esl_event_t *e = ep;
  912. ep = ep->next;
  913. if (e) {
  914. esl_event_destroy(&e);
  915. }
  916. }
  917. esl_event_safe_destroy(&handle->last_event);
  918. esl_event_safe_destroy(&handle->last_sr_event);
  919. esl_event_safe_destroy(&handle->last_ievent);
  920. esl_event_safe_destroy(&handle->info_event);
  921. if (mutex) {
  922. esl_mutex_unlock(mutex);
  923. esl_mutex_lock(mutex);
  924. esl_mutex_unlock(mutex);
  925. esl_mutex_destroy(&mutex);
  926. }
  927. if (handle->packet_buf) {
  928. esl_buffer_destroy(&handle->packet_buf);
  929. }
  930. memset(handle, 0, sizeof(*handle));
  931. handle->destroyed = 1;
  932. return status;
  933. }
  934. ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms, int check_q, esl_event_t **save_event)
  935. {
  936. int activity;
  937. esl_status_t status = ESL_SUCCESS;
  938. if (!ms) {
  939. return esl_recv_event(handle, check_q, save_event);
  940. }
  941. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  942. return ESL_FAIL;
  943. }
  944. if (check_q) {
  945. esl_mutex_lock(handle->mutex);
  946. if (handle->race_event || esl_buffer_packet_count(handle->packet_buf)) {
  947. esl_mutex_unlock(handle->mutex);
  948. return esl_recv_event(handle, check_q, save_event);
  949. }
  950. esl_mutex_unlock(handle->mutex);
  951. }
  952. if (handle->packet_buf && esl_buffer_inuse(handle->packet_buf)) {
  953. activity = ESL_POLL_READ;
  954. } else {
  955. activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR);
  956. }
  957. if (activity < 0) {
  958. handle->connected = 0;
  959. return ESL_FAIL;
  960. }
  961. if (activity == 0 || !(activity & ESL_POLL_READ) || (esl_mutex_trylock(handle->mutex) != ESL_SUCCESS)) {
  962. return ESL_BREAK;
  963. }
  964. if (activity < 0) {
  965. handle->connected = 0;
  966. status = ESL_FAIL;
  967. } else if (activity > 0 && (activity & ESL_POLL_READ)) {
  968. if (esl_recv_event(handle, check_q, save_event)) {
  969. status = ESL_FAIL;
  970. }
  971. } else {
  972. status = ESL_BREAK;
  973. }
  974. if (handle->mutex) esl_mutex_unlock(handle->mutex);
  975. return status;
  976. }
  977. static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen)
  978. {
  979. esl_ssize_t activity = -1;
  980. if (handle->connected) {
  981. if ((activity = esl_wait_sock(handle->sock, 1000, ESL_POLL_READ|ESL_POLL_ERROR)) > 0) {
  982. if (activity < 0) {
  983. activity = -1;
  984. } else if ((activity & ESL_POLL_ERROR)) {
  985. activity = -1;
  986. } else if ((activity & ESL_POLL_READ)) {
  987. if (!(activity = recv(handle->sock, data, datalen, 0))) {
  988. activity = -1;
  989. } else if (activity < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) {
  990. activity = 0;
  991. }
  992. }
  993. }
  994. }
  995. return activity;
  996. }
  997. ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
  998. {
  999. char *c;
  1000. esl_ssize_t rrval;
  1001. esl_event_t *revent = NULL;
  1002. char *beg;
  1003. char *hname, *hval;
  1004. char *col;
  1005. char *cl;
  1006. esl_ssize_t len;
  1007. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  1008. return ESL_FAIL;
  1009. }
  1010. esl_mutex_lock(handle->mutex);
  1011. if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
  1012. goto fail;
  1013. }
  1014. esl_event_safe_destroy(&handle->last_ievent);
  1015. if (check_q && handle->race_event) {
  1016. revent = handle->race_event;
  1017. handle->race_event = handle->race_event->next;
  1018. revent->next = NULL;
  1019. goto parse_event;
  1020. }
  1021. while(!revent && handle->connected) {
  1022. esl_size_t len1;
  1023. if ((len1 = esl_buffer_read_packet(handle->packet_buf, handle->socket_buf, sizeof(handle->socket_buf) - 1))) {
  1024. char *data = (char *) handle->socket_buf;
  1025. char *p, *e;
  1026. *(data + len1) = '\0';
  1027. esl_event_create(&revent, ESL_EVENT_CLONE);
  1028. revent->event_id = ESL_EVENT_SOCKET_DATA;
  1029. esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA");
  1030. p = data;
  1031. while(p) {
  1032. hname = p;
  1033. p = NULL;
  1034. if ((hval = strchr(hname, ':'))) {
  1035. *hval++ = '\0';
  1036. while(*hval == ' ' || *hval == '\t') hval++;
  1037. if ((e = strchr(hval, '\n'))) {
  1038. *e++ = '\0';
  1039. while(*e == '\n' || *e == '\r') e++;
  1040. if (hname && hval) {
  1041. esl_url_decode(hval);
  1042. esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval);
  1043. if (!strncmp(hval, "ARRAY::", 7)) {
  1044. esl_event_add_array(revent, hname, hval);
  1045. } else {
  1046. esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval);
  1047. }
  1048. }
  1049. p = e;
  1050. }
  1051. }
  1052. }
  1053. break;
  1054. }
  1055. rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1);
  1056. if (rrval == 0) {
  1057. continue;
  1058. } else if (rrval < 0) {
  1059. if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err))))
  1060. *(handle->err)=0;
  1061. goto fail;
  1062. }
  1063. *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, rrval)) = '\0';
  1064. esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval);
  1065. }
  1066. if (!revent) {
  1067. goto fail;
  1068. }
  1069. if ((cl = esl_event_get_header(revent, "content-length"))) {
  1070. char *body;
  1071. esl_ssize_t sofar = 0;
  1072. len = atol(cl);
  1073. body = malloc(len+1);
  1074. esl_assert(body);
  1075. *(body + len) = '\0';
  1076. do {
  1077. esl_ssize_t r,s = esl_buffer_inuse(handle->packet_buf);
  1078. if (s >= len) {
  1079. sofar = esl_buffer_read(handle->packet_buf, body, len);
  1080. } else {
  1081. r = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1);
  1082. if (r < 0) {
  1083. if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err))))
  1084. *(handle->err)=0;
  1085. free(body);
  1086. goto fail;
  1087. } else if (r == 0) {
  1088. continue;
  1089. }
  1090. *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, r)) = '\0';
  1091. esl_buffer_write(handle->packet_buf, handle->socket_buf, r);
  1092. }
  1093. } while (sofar < len);
  1094. revent->body = body;
  1095. }
  1096. parse_event:
  1097. if (save_event) {
  1098. *save_event = revent;
  1099. revent = NULL;
  1100. } else {
  1101. esl_event_safe_destroy(&handle->last_event);
  1102. handle->last_event = revent;
  1103. }
  1104. if (revent) {
  1105. hval = esl_event_get_header(revent, "reply-text");
  1106. if (!esl_strlen_zero(hval)) {
  1107. strncpy(handle->last_reply, hval, sizeof(handle->last_reply));
  1108. }
  1109. hval = esl_event_get_header(revent, "content-type");
  1110. if (!esl_safe_strcasecmp(hval, "text/disconnect-notice") && revent->body) {
  1111. const char *dval = esl_event_get_header(revent, "content-disposition");
  1112. if (esl_strlen_zero(dval) || strcasecmp(dval, "linger")) {
  1113. goto fail;
  1114. }
  1115. }
  1116. if (revent->body) {
  1117. if (!esl_safe_strcasecmp(hval, "text/event-plain")) {
  1118. esl_event_types_t et = ESL_EVENT_CLONE;
  1119. char *body = strdup(revent->body);
  1120. esl_event_create(&handle->last_ievent, et);
  1121. beg = body;
  1122. while(beg) {
  1123. if (!(c = strchr(beg, '\n'))) {
  1124. break;
  1125. }
  1126. hname = beg;
  1127. hval = col = NULL;
  1128. if (hname && (col = strchr(hname, ':'))) {
  1129. hval = col + 1;
  1130. *col = '\0';
  1131. while(*hval == ' ') hval++;
  1132. }
  1133. *c = '\0';
  1134. if (hname && hval) {
  1135. esl_url_decode(hval);
  1136. esl_log(ESL_LOG_DEBUG, "RECV INNER HEADER [%s] = [%s]\n", hname, hval);
  1137. if (!strcasecmp(hname, "event-name")) {
  1138. esl_event_del_header(handle->last_ievent, "event-name");
  1139. esl_name_event(hval, &handle->last_ievent->event_id);
  1140. }
  1141. if (!strncmp(hval, "ARRAY::", 7)) {
  1142. esl_event_add_array(handle->last_ievent, hname, hval);
  1143. } else {
  1144. esl_event_add_header_string(handle->last_ievent, ESL_STACK_BOTTOM, hname, hval);
  1145. }
  1146. }
  1147. beg = c + 1;
  1148. if (*beg == '\n') {
  1149. beg++;
  1150. break;
  1151. }
  1152. }
  1153. if ((cl = esl_event_get_header(handle->last_ievent, "content-length"))) {
  1154. handle->last_ievent->body = strdup(beg);
  1155. }
  1156. free(body);
  1157. if (esl_log_level >= 7) {
  1158. char *foo;
  1159. esl_event_serialize(handle->last_ievent, &foo, ESL_FALSE);
  1160. esl_log(ESL_LOG_DEBUG, "RECV EVENT\n%s\n", foo);
  1161. free(foo);
  1162. }
  1163. } else if (!esl_safe_strcasecmp(hval, "text/event-json")) {
  1164. esl_event_create_json(&handle->last_ievent, revent->body);
  1165. }
  1166. }
  1167. if (esl_log_level >= 7) {
  1168. char *foo;
  1169. esl_event_serialize(revent, &foo, ESL_FALSE);
  1170. esl_log(ESL_LOG_DEBUG, "RECV MESSAGE\n%s\n", foo);
  1171. free(foo);
  1172. }
  1173. }
  1174. esl_mutex_unlock(handle->mutex);
  1175. return ESL_SUCCESS;
  1176. fail:
  1177. esl_mutex_unlock(handle->mutex);
  1178. handle->connected = 0;
  1179. return ESL_FAIL;
  1180. }
  1181. ESL_DECLARE(esl_status_t) esl_send(esl_handle_t *handle, const char *cmd)
  1182. {
  1183. const char *e = cmd + strlen(cmd) -1;
  1184. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  1185. return ESL_FAIL;
  1186. }
  1187. esl_log(ESL_LOG_DEBUG, "SEND\n%s\n", cmd);
  1188. if (send(handle->sock, cmd, strlen(cmd), 0) != (int)strlen(cmd)) {
  1189. handle->connected = 0;
  1190. if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err))))
  1191. *(handle->err)=0;
  1192. return ESL_FAIL;
  1193. }
  1194. if (!(*e == '\n' && *(e-1) == '\n')) {
  1195. if (send(handle->sock, "\n\n", 2, 0) != 2) {
  1196. handle->connected = 0;
  1197. if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err))))
  1198. *(handle->err)=0;
  1199. return ESL_FAIL;
  1200. }
  1201. }
  1202. return ESL_SUCCESS;
  1203. }
  1204. ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *cmd, uint32_t ms)
  1205. {
  1206. const char *hval;
  1207. esl_status_t status;
  1208. if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
  1209. return ESL_FAIL;
  1210. }
  1211. esl_mutex_lock(handle->mutex);
  1212. if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
  1213. handle->connected = 0;
  1214. esl_mutex_unlock(handle->mutex);
  1215. return ESL_FAIL;
  1216. }
  1217. esl_event_safe_destroy(&handle->last_sr_event);
  1218. *handle->last_sr_reply = '\0';
  1219. if ((status = esl_send(handle, cmd))) {
  1220. esl_mutex_unlock(handle->mutex);
  1221. return status;
  1222. }
  1223. recv:
  1224. esl_event_safe_destroy(&handle->last_sr_event);
  1225. *handle->last_sr_reply = '\0';
  1226. status = esl_recv_event_timed(handle, ms, 0, &handle->last_sr_event);
  1227. if (handle->last_sr_event) {
  1228. char *ct = esl_event_get_header(handle->last_sr_event,"content-type");
  1229. if (ct && strcasecmp(ct, "api/response") && strcasecmp(ct, "command/reply")) {
  1230. esl_event_t *ep;
  1231. for(ep = handle->race_event; ep && ep->next; ep = ep->next);
  1232. if (ep) {
  1233. ep->next = handle->last_sr_event;
  1234. } else {
  1235. handle->race_event = handle->last_sr_event;
  1236. }
  1237. handle->last_sr_event = NULL;
  1238. esl_mutex_unlock(handle->mutex);
  1239. esl_mutex_lock(handle->mutex);
  1240. if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
  1241. handle->connected = 0;
  1242. esl_mutex_unlock(handle->mutex);
  1243. return ESL_FAIL;
  1244. }
  1245. goto recv;
  1246. }
  1247. if (handle->last_sr_event) {
  1248. hval = esl_event_get_header(handle->last_sr_event, "reply-text");
  1249. if (!esl_strlen_zero(hval)) {
  1250. strncpy(handle->last_sr_reply, hval, sizeof(handle->last_sr_reply));
  1251. }
  1252. }
  1253. }
  1254. esl_mutex_unlock(handle->mutex);
  1255. return status;
  1256. }
  1257. ESL_DECLARE(unsigned int) esl_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen)
  1258. {
  1259. unsigned int count = 0;
  1260. char *d;
  1261. size_t dlen = strlen(delim);
  1262. array[count++] = buf;
  1263. while (count < arraylen && array[count - 1]) {
  1264. if ((d = strstr(array[count - 1], delim))) {
  1265. *d = '\0';
  1266. d += dlen;
  1267. array[count++] = d;
  1268. } else
  1269. break;
  1270. }
  1271. return count;
  1272. }
  1273. /* For Emacs:
  1274. * Local Variables:
  1275. * mode:c
  1276. * indent-tabs-mode:t
  1277. * tab-width:4
  1278. * c-basic-offset:4
  1279. * End:
  1280. * For VIM:
  1281. * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
  1282. */