server.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. # if !defined(_POSIX_SOURCE)
  2. # define _POSIX_SOURCE
  3. # endif
  4. # if !defined(_BSD_SOURCE)
  5. # define _BSD_SOURCE
  6. # endif
  7. # include <sys/socket.h>
  8. # include <netinet/in.h>
  9. # include <arpa/inet.h>
  10. # include <netdb.h>
  11. # include <poll.h>
  12. # include <unistd.h>
  13. #include <errno.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <ctype.h>
  18. #include "client.h"
  19. #include "server.h"
  20. #include "monolog.h"
  21. #include "libtelnet.h"
  22. #include "rh.h"
  23. static const telnet_telopt_t woe_telnet_opts[] = {
  24. { TELNET_TELOPT_COMPRESS2, TELNET_WILL, TELNET_DONT },
  25. { TELNET_TELOPT_ECHO , TELNET_WONT, TELNET_DONT },
  26. { -1, 0, 0 }
  27. };
  28. #define WOE_SERVER_BUFFER_SIZE 10000
  29. #define WOE_SERVER_LISTEN_BACKLOG 8
  30. struct woe_server {
  31. char buffer[WOE_SERVER_BUFFER_SIZE];
  32. short listen_port;
  33. int listen_sock;
  34. int busy;
  35. struct sockaddr_in addr;
  36. socklen_t addrlen;
  37. mrb_state * mrb;
  38. struct pollfd pfd[WOE_CLIENTS_MAX + 1];
  39. struct woe_client * clients[WOE_CLIENTS_MAX];
  40. void (*event_handler) (telnet_t *telnet, telnet_event_t *ev, void *user_data);
  41. void (*disconnect_handler) (struct woe_server * srv, struct woe_client * cli, void *user_data);
  42. };
  43. int woe_server_disconnect(struct woe_server * srv, struct woe_client * client);
  44. int woe_send(int sock, const char *buffer, unsigned int size) {
  45. int res;
  46. if (sock == -1)
  47. return -1;
  48. /* send data */
  49. while (size > 0) {
  50. if ((res = send(sock, buffer, size, 0)) == -1) {
  51. if (errno != EINTR && errno != ECONNRESET) {
  52. LOG_ERROR("send() failed: %s\n", strerror(errno));
  53. return -2;
  54. } else {
  55. return 0;
  56. }
  57. } else if (res == 0) {
  58. LOG_ERROR("send() unexpectedly returned 0\n");
  59. return -3;
  60. }
  61. /* update pointer and size to see if we've got more to send */
  62. buffer += res;
  63. size -= res;
  64. }
  65. return 0;
  66. }
  67. static void woe_event_handler(telnet_t *telnet, telnet_event_t *ev, void *user_data) {
  68. struct woe_client * client = (struct woe_client *) user_data;
  69. switch (ev->type) {
  70. /* data received */
  71. case TELNET_EV_DATA:
  72. woe_client_input(client, ev->data.buffer, ev->data.size);
  73. /* telnet_negotiate(telnet, TELNET_WONT, TELNET_TELOPT_ECHO);
  74. telnet_negotiate(telnet, TELNET_WILL, TELNET_TELOPT_ECHO); */
  75. break;
  76. /* data must be sent */
  77. case TELNET_EV_SEND:
  78. woe_send(client->sock, ev->data.buffer, ev->data.size);
  79. break;
  80. /* enable compress2 if accepted by client */
  81. case TELNET_EV_DO:
  82. if (ev->neg.telopt == TELNET_TELOPT_COMPRESS2) telnet_begin_compress2(telnet);
  83. woe_client_negotiate(client, TELNET_DO, ev->neg.telopt);
  84. break;
  85. case TELNET_EV_DONT:
  86. woe_client_negotiate(client, TELNET_DONT, ev->neg.telopt);
  87. break;
  88. case TELNET_EV_WILL:
  89. woe_client_negotiate(client, TELNET_WILL, ev->neg.telopt);
  90. break;
  91. case TELNET_EV_WONT:
  92. woe_client_negotiate(client, TELNET_WILL, ev->neg.telopt);
  93. break;
  94. /* error */
  95. case TELNET_EV_ERROR:
  96. LOG_ERROR("Telnet error for client.\n");
  97. woe_server_disconnect(client->server, client);
  98. break;
  99. case TELNET_EV_ZMP
  100. woe_client_zmp(client, ev->zmp.argc, ev->zmp.argv);
  101. break;
  102. default:
  103. LOG_NOTE("Ignored telnet event %d.\n", ev->type);
  104. /* ignore */
  105. break;
  106. }
  107. }
  108. void woe_server_request_shutdown(struct woe_server * srv) {
  109. if (srv) srv->busy = 0;
  110. }
  111. int woe_server_busy(struct woe_server * srv) {
  112. if (!srv) return 0;
  113. return srv->busy;
  114. }
  115. struct woe_server * woe_server_free(struct woe_server * srv) {
  116. close(srv->listen_sock);
  117. free(srv);
  118. return NULL;
  119. }
  120. struct woe_server * woe_server_init(struct woe_server * srv, int port) {
  121. int index;
  122. if (!srv) return NULL;
  123. srv->listen_sock = -1;
  124. srv->listen_port = port;
  125. srv->busy = !0;
  126. srv->mrb = NULL;
  127. memset(srv->buffer , '\0' , sizeof(srv->buffer));
  128. memset(srv->pfd , 0 , sizeof(srv->pfd));
  129. memset(&srv->addr , 0 , sizeof(srv->addr));
  130. for (index = 0; index < WOE_CLIENTS_MAX; ++index) {
  131. srv->clients[index] = NULL;
  132. }
  133. srv->event_handler = woe_event_handler;
  134. return srv;
  135. }
  136. struct woe_server * woe_server_new(int port) {
  137. struct woe_server * srv = calloc(1, sizeof(struct woe_server));
  138. if (!srv) return NULL;
  139. return woe_server_init(srv, port);
  140. }
  141. static const telnet_telopt_t telopts[] = {
  142. { TELNET_TELOPT_COMPRESS2, TELNET_WILL, TELNET_DONT },
  143. { -1, 0, 0 }
  144. };
  145. struct woe_server * woe_server_set_mrb(struct woe_server * srv, mrb_state * mrb) {
  146. if (!srv) return NULL;
  147. srv->mrb = mrb;
  148. return srv;
  149. }
  150. mrb_state * woe_server_get_mrb(struct woe_server * srv) {
  151. if (!srv) return NULL;
  152. return srv->mrb;
  153. }
  154. /** Sets up the server to listen at its configured port. */
  155. int woe_server_listen(struct woe_server * srv) {
  156. int res;
  157. /* create listening socket */
  158. if ((srv->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  159. LOG_ERROR("socket() failed: %s\n", strerror(errno));
  160. return 1;
  161. }
  162. /* Reuse address option */
  163. res = 1;
  164. if (setsockopt(srv->listen_sock, SOL_SOCKET, SO_REUSEADDR, (void*)&res, sizeof(res))
  165. == -1) {
  166. LOG_ERROR("setsockopt() failed: %s\n", strerror(errno));
  167. return 2;
  168. }
  169. /* Bind to listening addr/port */
  170. srv->addr.sin_family = AF_INET;
  171. srv->addr.sin_addr.s_addr = INADDR_ANY;
  172. srv->addr.sin_port = htons(srv->listen_port);
  173. if (bind(srv->listen_sock, (struct sockaddr *)&srv->addr, sizeof(srv->addr)) == -1) {
  174. LOG_ERROR("setsockopt() failed: %s\n", strerror(errno));
  175. return 3;
  176. }
  177. /* listen for clients */
  178. if (listen(srv->listen_sock, WOE_SERVER_LISTEN_BACKLOG) == -1) {
  179. fprintf(stderr, "listen() failed: %s\n", strerror(errno));
  180. return 4;
  181. }
  182. LOG_NOTE("Listening on port %d\n", srv->listen_port);
  183. /* Initialize listening descriptors */
  184. srv->pfd[WOE_CLIENTS_MAX].fd = srv->listen_sock;
  185. srv->pfd[WOE_CLIENTS_MAX].events = POLLIN;
  186. return 0;
  187. }
  188. /** Returns one of the clients of the server or NULL if not in use or out of
  189. * range */
  190. struct woe_client * woe_server_get_client(struct woe_server * srv, int index) {
  191. if (!srv) return NULL;
  192. if (index < 0) return NULL;
  193. if (index >= WOE_CLIENTS_MAX) return NULL;
  194. return srv->clients[index];
  195. }
  196. /** Stores a client of the server at the given index*/
  197. struct woe_client * woe_server_put_client(struct woe_server * srv, int index, struct woe_client * cli) {
  198. if (!srv) return NULL;
  199. if (!cli) return NULL;
  200. if (index < 0) return NULL;
  201. if (index >= WOE_CLIENTS_MAX) return NULL;
  202. if (srv->clients[index]) {
  203. woe_client_free(srv->clients[index]);
  204. }
  205. srv->clients[index] = cli;
  206. return cli;
  207. }
  208. /** Removes a client of the server at the given index*/
  209. struct woe_client * woe_server_remove_client(struct woe_server * srv, int index) {
  210. if (!srv) return NULL;
  211. if (index < 0) return NULL;
  212. if (index >= WOE_CLIENTS_MAX) return NULL;
  213. if (srv->clients[index]) {
  214. woe_client_free(srv->clients[index]);
  215. }
  216. srv->clients[index] = NULL;
  217. return NULL;
  218. }
  219. /** Find an index to put a new user and returns a pointer to it.
  220. * Returns -1 if no free space is available.
  221. **/
  222. int woe_server_get_available_client_index(struct woe_server * srv) {
  223. int i;
  224. for (i = 0; i < WOE_CLIENTS_MAX; ++i) {
  225. struct woe_client * client = woe_server_get_client(srv, i);
  226. if (!client) {
  227. return i;
  228. }
  229. }
  230. return -1;
  231. }
  232. /** Creates a new client for this server. Return null if no memory or no space
  233. * for a new client. */
  234. struct woe_client * woe_server_make_new_client(struct woe_server * srv,
  235. int socket, struct sockaddr_in *addr, socklen_t addrlen) {
  236. struct woe_client * new;
  237. int index = woe_server_get_available_client_index(srv);
  238. if (index < 0) return NULL;
  239. new = woe_client_new(srv, index, socket, addr, addrlen);
  240. return woe_server_put_client(srv, index, new);
  241. }
  242. /* Handles a new connection to this server. */
  243. int woe_server_handle_connect(struct woe_server * srv) {
  244. struct woe_client * client;
  245. int res;
  246. struct sockaddr_in addr;
  247. socklen_t addrlen;
  248. /* accept the connection */
  249. addrlen = sizeof(addr);
  250. if ((res = accept(srv->listen_sock, (struct sockaddr *)&addr, &addrlen)) == -1) {
  251. LOG_ERROR("accept() failed: %s\n", strerror(errno));
  252. return 1;
  253. }
  254. LOG_NOTE("Connection received.\n");
  255. client = woe_server_make_new_client(srv, res, &addr, addrlen);
  256. /* No space for a new client */
  257. if (!client) {
  258. LOG_WARNING("Connection rejected (too many users or OOM)\n");
  259. write(res, "Too many users.\r\n", 14);
  260. close(res);
  261. return 2;
  262. }
  263. /* init, welcome */
  264. client->telnet = telnet_init(woe_telnet_opts, srv->event_handler, 0, client);
  265. if (!client->telnet) {
  266. LOG_ERROR("Could not initialize telnet connection for user.");
  267. woe_server_disconnect(srv, client);
  268. return 3;
  269. }
  270. /*telnet_negotiate(client->telnet, TELNET_DO, TELNET_TELOPT_ECHO);*/
  271. telnet_negotiate(client->telnet, TELNET_WILL, TELNET_TELOPT_COMPRESS2);
  272. telnet_printf(client->telnet, "Welcome to WOE!\r\n");
  273. /* telnet_negotiate(client->telnet, TELNET_WILL, TELNET_TELOPT_ECHO); */
  274. if (srv->mrb) {
  275. rh_run_toplevel(srv->mrb, "woe_on_connect", "i", client->index);
  276. }
  277. return 0;
  278. }
  279. /** Sends a telnet command to the numbered client. */
  280. int woe_server_iac(struct woe_server * srv, int client, int command) {
  281. struct woe_client * pclient;
  282. if (!srv) return -1;
  283. pclient = woe_server_get_client(srv, client);
  284. if (!pclient) return -2;
  285. telnet_iac(pclient->telnet, command);
  286. return 0;
  287. }
  288. /** Send a telnet negotiation to the numbered client. */
  289. int woe_server_negotiate(struct woe_server * srv, int client, int how, int option) {
  290. struct woe_client * pclient;
  291. if (!srv) return -1;
  292. pclient = woe_server_get_client(srv, client);
  293. if (!pclient) return -2;
  294. telnet_negotiate(pclient->telnet, how, option);
  295. return 0;
  296. }
  297. /** Sends a telnet start of subnegotiation to the numbered client. */
  298. int woe_server_begin_sb(struct woe_server * srv, int client, int telopt) {
  299. struct woe_client * pclient;
  300. if (!srv) return -1;
  301. pclient = woe_server_get_client(srv, client);
  302. if (!pclient) return -2;
  303. telnet_begin_sb(pclient->telnet, telopt);
  304. return 0;
  305. }
  306. /** Sends a telnet end of subnegotiation to the numbered client. */
  307. int woe_server_finish_sb(struct woe_server * srv, int client) {
  308. struct woe_client * pclient;
  309. if (!srv) return -1;
  310. pclient = woe_server_get_client(srv, client);
  311. if (!pclient) return -2;
  312. telnet_finish_sb(pclient->telnet);
  313. return 0;
  314. }
  315. /** Sends a complete telnet subnegotiation buffer to the numbered client. */
  316. int woe_server_subnegotiation(struct woe_server * srv, int client, int telopt, char * buffer, int size) {
  317. struct woe_client * pclient;
  318. if (!srv) return -1;
  319. pclient = woe_server_get_client(srv, client);
  320. if (!pclient) return -2;
  321. telnet_subnegotiation(pclient->telnet, telopt, buffer, size);
  322. return 0;
  323. }
  324. /** Begin sending compressed data to the to the numbered client. */
  325. int woe_server_begin_compress2(struct woe_server * srv, int client) {
  326. struct woe_client * pclient;
  327. if (!srv) return -1;
  328. pclient = woe_server_get_client(srv, client);
  329. if (!pclient) return -2;
  330. telnet_begin_compress2(pclient->telnet);
  331. return 0;
  332. }
  333. /** Send formated output with newline escaping to the to the numbered client. */
  334. int woe_server_vprintf(struct woe_server * srv, int client, const char *fmt, va_list va) {
  335. struct woe_client * pclient;
  336. if (!srv) return -1;
  337. pclient = woe_server_get_client(srv, client);
  338. if (!pclient) return -2;
  339. telnet_vprintf(pclient->telnet, fmt, va);
  340. return 0;
  341. }
  342. /** Send formated output with newline escaping to the to the numbered client. */
  343. int woe_server_printf(struct woe_server * srv, int client, const char *fmt, ...) {
  344. va_list va;
  345. int res;
  346. struct woe_client * pclient;
  347. if (!srv) return -1;
  348. pclient = woe_server_get_client(srv, client);
  349. if (!pclient) return -2;
  350. va_start(va, fmt);
  351. telnet_vprintf(pclient->telnet, fmt, va);
  352. va_end(va);
  353. return 0;
  354. }
  355. /** Send formated output without newline escaping to the to the numbered client. */
  356. int woe_server_raw_vprintf(struct woe_server * srv, int client, const char *fmt, va_list va) {
  357. struct woe_client * pclient;
  358. if (!srv) return -1;
  359. pclient = woe_server_get_client(srv, client);
  360. if (!pclient) return -2;
  361. telnet_raw_vprintf(pclient->telnet, fmt, va);
  362. return 0;
  363. }
  364. /** Send formated output without newline escaping to the to the numbered client. */
  365. int woe_server_raw_printf(struct woe_server * srv, int client, const char *fmt, ...) {
  366. va_list va;
  367. int res;
  368. struct woe_client * pclient;
  369. if (!srv) return -1;
  370. pclient = woe_server_get_client(srv, client);
  371. if (!pclient) return -2;
  372. va_start(va, fmt);
  373. res = telnet_raw_vprintf(pclient->telnet, fmt, va);
  374. va_end(va);
  375. return 0;
  376. }
  377. /** Begin a NEW-ENVIRON subnegotiation with the numbered client. */
  378. int woe_server_begin_newenviron(struct woe_server * srv, int client, int type) {
  379. struct woe_client * pclient;
  380. if (!srv) return -1;
  381. pclient = woe_server_get_client(srv, client);
  382. if (!pclient) return -2;
  383. telnet_begin_newenviron(pclient->telnet, type);
  384. return 0;
  385. }
  386. /** Send a NEW-ENVIRON variable name or value to the numbered client. */
  387. int woe_server_newenviron_value(struct woe_server * srv, int client, int type, char * value) {
  388. struct woe_client * pclient;
  389. if (!srv) return -1;
  390. pclient = woe_server_get_client(srv, client);
  391. if (!pclient) return -2;
  392. telnet_newenviron_value(pclient->telnet, type, value);
  393. return 0;
  394. }
  395. /** Finish a NEW-ENVIRON subnegotiation with the numbered client. */
  396. int woe_server_finish_newenviron(struct woe_server * srv, int client) {
  397. struct woe_client * pclient;
  398. if (!srv) return -1;
  399. pclient = woe_server_get_client(srv, client);
  400. if (!pclient) return -2;
  401. telnet_finish_newenviron(pclient->telnet);
  402. return 0;
  403. }
  404. /** Send a TERMINAL-TYPE SEND command to the numbered client. */
  405. int woe_server_ttype_send(struct woe_server * srv, int client) {
  406. struct woe_client * pclient;
  407. if (!srv) return -1;
  408. pclient = woe_server_get_client(srv, client);
  409. if (!pclient) return -2;
  410. telnet_ttype_send(pclient->telnet);
  411. return 0;
  412. }
  413. /** Send a TERMINAL-TYPE IS command to the numbered client. */
  414. int woe_server_ttype_is(struct woe_server * srv, int client, char * ttype) {
  415. struct woe_client * pclient;
  416. if (!srv) return -1;
  417. pclient = woe_server_get_client(srv, client);
  418. if (!pclient) return -2;
  419. telnet_ttype_is(pclient->telnet, ttype);
  420. return 0;
  421. }
  422. /** Send a ZMP command to the numbered client. */
  423. int woe_server_send_zmp(struct woe_server * srv, int client, int argc, const char ** argv) {
  424. struct woe_client * pclient;
  425. if (!srv) return -1;
  426. pclient = woe_server_get_client(srv, client);
  427. if (!pclient) return -2;
  428. telnet_send_zmp(pclient->telnet, argc, argv);
  429. return 0;
  430. }
  431. /** Send a ZMP command to the numbered client. */
  432. int woe_server_send_vzmpv(struct woe_server * srv, int client, va_list va) {
  433. struct woe_client * pclient;
  434. if (!srv) return -1;
  435. pclient = woe_server_get_client(srv, client);
  436. if (!pclient) return -2;
  437. telnet_send_vzmpv(pclient->telnet, va);
  438. return 0;
  439. }
  440. /** Send a ZMP command to the numbered client. */
  441. int woe_server_send_zmpv(struct woe_server * srv, int client, ...) {
  442. va_list va;
  443. struct woe_client * pclient;
  444. if (!srv) return -1;
  445. pclient = woe_server_get_client(srv, client);
  446. if (!pclient) return -2;
  447. va_start(va, client);
  448. telnet_send_vzmpv(pclient->telnet, va);
  449. va_end(va);
  450. return 0;
  451. }
  452. /** Begin sending a ZMP command to the numbered client. */
  453. int woe_server_begin_zmp(struct woe_server * srv, int client, const char * cmd) {
  454. struct woe_client * pclient;
  455. if (!srv) return -1;
  456. pclient = woe_server_get_client(srv, client);
  457. if (!pclient) return -2;
  458. telnet_begin_zmp(pclient->telnet, cmd);
  459. return 0;
  460. }
  461. /** Send a ZMP command argument to the numbered client. */
  462. int woe_server_zmp_arg(struct woe_server * srv, int client, const char * arg) {
  463. struct woe_client * pclient;
  464. if (!srv) return -1;
  465. pclient = woe_server_get_client(srv, client);
  466. if (!pclient) return -2;
  467. telnet_zmp_arg(pclient->telnet, arg);
  468. return 0;
  469. }
  470. /** Finish sending a ZMP command to the numbered client. */
  471. int woe_server_finish_zmp(struct woe_server * srv, int client, const char * cmd) {
  472. struct woe_client * pclient;
  473. if (!srv) return -1;
  474. pclient = woe_server_get_client(srv, client);
  475. if (!pclient) return -2;
  476. telnet_finish_zmp(pclient->telnet);
  477. return 0;
  478. }
  479. /** Disconnect a client from the server. */
  480. int woe_server_disconnect(struct woe_server * srv, struct woe_client * client) {
  481. int index;
  482. if (!srv) return 1;
  483. if (!client) return 2;
  484. close(client->sock);
  485. if (srv->disconnect_handler) {
  486. srv->disconnect_handler(srv, client, NULL);
  487. }
  488. index = client->index;
  489. if (srv->mrb) {
  490. rh_run_toplevel(srv->mrb, "woe_on_disconnect", "i", index);
  491. }
  492. /* Get rid of client, will also free memory asociated. */
  493. woe_server_remove_client(srv, index);
  494. return 0;
  495. }
  496. /** Forcfullly disconnect a client from the server by id.
  497. * Set a quit flag that woe_server_update will check. */
  498. int woe_server_disconnect_id(struct woe_server * srv, int id) {
  499. struct woe_client * client = woe_server_get_client(srv, id);
  500. if (!client) return -1;
  501. client->busy = 0;
  502. return 0;
  503. }
  504. /** Polls the server once and updates any of the clients if needed. */
  505. int woe_server_update(struct woe_server * srv, int timeout) {
  506. int i, res;
  507. /* prepare for poll */
  508. memset(srv->pfd , 0 , sizeof(srv->pfd));
  509. for (i = 0; i != WOE_CLIENTS_MAX; ++i) {
  510. struct woe_client * client = woe_server_get_client(srv, i);
  511. if (client) {
  512. srv->pfd[i].fd = client->sock;
  513. srv->pfd[i].events = POLLIN;
  514. } else {
  515. srv->pfd[i].fd = -1;
  516. srv->pfd[i].events = 0;
  517. }
  518. }
  519. /* Also listen for connnect events. */
  520. srv->pfd[WOE_CLIENTS_MAX].fd = srv->listen_sock;
  521. srv->pfd[WOE_CLIENTS_MAX].events = POLLIN;
  522. /* Poll for activity */
  523. res = poll(srv->pfd, WOE_CLIENTS_MAX + 1, timeout);
  524. /* Check for time out */
  525. if (res == 0) {
  526. /* Time out but that's OK. */
  527. return 0;
  528. }
  529. /* Log errors. */
  530. if (res == -1 && errno != EINTR) {
  531. LOG_ERROR("poll() failed: %s\n", strerror(errno));
  532. return 1;
  533. }
  534. /* Handle new connection connection */
  535. if (srv->pfd[WOE_CLIENTS_MAX].revents & POLLIN) {
  536. woe_server_handle_connect(srv);
  537. }
  538. /* Read from clients */
  539. for (i = 0; i < WOE_CLIENTS_MAX; ++i) {
  540. struct woe_client * client = woe_server_get_client(srv, i);
  541. if (!client) continue;
  542. /* Input from clients. */
  543. if (srv->pfd[i].revents & POLLIN) {
  544. res = recv(client->sock, srv->buffer, sizeof(srv->buffer), 0);
  545. if (res < 0) {
  546. LOG_ERROR("recv(client) failed: %s\n", strerror(errno));
  547. } else if (res == 0) {
  548. /* Disconnect the client. */
  549. woe_server_disconnect(srv, client);
  550. } else {
  551. /* Let telnet lib process incoming data. */
  552. telnet_recv(client->telnet, srv->buffer, res);
  553. // telnet_send(client->telnet, srv->buffer, res);
  554. // telnet_send(telnet, ev->data.buffer, ev->data.size);
  555. }
  556. }
  557. }
  558. /* Disconnect clients that should quit */
  559. for (i = 0; i < WOE_CLIENTS_MAX; ++i) {
  560. struct woe_client * client = woe_server_get_client(srv, i);
  561. if (!client) continue;
  562. if (!client->busy) {
  563. woe_server_disconnect(srv, client);
  564. }
  565. }
  566. return 0;
  567. }
  568. int woe_server_send_to_client(struct woe_server * srv, int client, char * data, size_t size) {
  569. struct woe_client * pclient = woe_server_get_client(srv, client);
  570. if (!pclient) return -1;
  571. telnet_send(pclient->telnet, data, size);
  572. return size;
  573. }