client.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * This file client.c, handles clients of the WOE server.
  3. */
  4. #if !defined(_WIN32)
  5. # if !defined(_POSIX_SOURCE)
  6. # define _POSIX_SOURCE
  7. # endif
  8. # if !defined(_BSD_SOURCE)
  9. # define _BSD_SOURCE
  10. # endif
  11. # include <sys/socket.h>
  12. # include <netinet/in.h>
  13. # include <arpa/inet.h>
  14. # include <netdb.h>
  15. # include <poll.h>
  16. # include <unistd.h>
  17. #else
  18. # include <winsock2.h>
  19. # include <ws2tcpip.h>
  20. # define snprintf _snprintf
  21. # define poll WSAPoll
  22. # define close closesocket
  23. # define strdup _strdup
  24. # define ECONNRESET WSAECONNRESET
  25. #endif
  26. #include <errno.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <ctype.h>
  31. #include "libtelnet.h"
  32. #include "monolog.h"
  33. #include "rh.h"
  34. #include "client.h"
  35. #include "server.h"
  36. struct woe_client * woe_client_alloc() {
  37. return calloc(sizeof(struct woe_client), 1);
  38. }
  39. struct woe_client * woe_client_init(struct woe_client * client,
  40. struct woe_server * server, int index, int socket,
  41. struct sockaddr_in *addr, socklen_t addrlen) {
  42. if (!client) return NULL;
  43. client->server = server;
  44. client->sock = socket;
  45. client->addr = *addr;
  46. client->addrlen = addrlen;
  47. client->busy = !0;
  48. return client;
  49. }
  50. struct woe_client * woe_client_new(struct woe_server * server, int index, int socket,
  51. struct sockaddr_in *addr, socklen_t addrlen) {
  52. struct woe_client * client = woe_client_alloc();
  53. return woe_client_init(client, server, index, socket, addr, addrlen);
  54. }
  55. struct woe_client * woe_client_done(struct woe_client * client) {
  56. /* Do nothing yet, refactor later. */
  57. if (!client) return NULL;
  58. if (client->telnet) telnet_free(client->telnet);
  59. client->sock = -1;
  60. client->telnet = NULL;
  61. LOG_NOTE("Connection to client %d closed.\n", client->index);
  62. client->index = -1;
  63. return client;
  64. }
  65. struct woe_client * woe_client_free(struct woe_client * client) {
  66. woe_client_done(client);
  67. free(client);
  68. return NULL;
  69. }
  70. int woe_client_send(struct woe_client * client, const char *buffer, unsigned int size) {
  71. int res;
  72. if (!client) return 1;
  73. /* ignore on invalid socket */
  74. if (client->sock < 0) return 2;
  75. /* send data */
  76. while (size > 0) {
  77. if ((res = send(client->sock, buffer, size, 0)) == -1) {
  78. if (errno != EINTR && errno != ECONNRESET) {
  79. LOG_ERROR("send() failed: %s\n", strerror(errno));
  80. return 3;
  81. } else {
  82. return 0;
  83. }
  84. } else if (res == 0) {
  85. LOG_ERROR("send() unexpectedly returned 0\n");
  86. return 4;
  87. }
  88. /* Update pointer and size to see if we've got more to send */
  89. buffer += res;
  90. size -= res;
  91. }
  92. return 0;
  93. }
  94. int woe_client_input(struct woe_client * cli, const char *buffer, size_t size) {
  95. unsigned int i;
  96. mrb_state * mrb;
  97. LOG_NOTE("Received input for client %d");
  98. mrb = woe_server_get_mrb(cli->server);
  99. if (mrb) {
  100. rh_run_toplevel(mrb, "woe_on_input", "is", cli->index, buffer, size);
  101. }
  102. return 0;
  103. }
  104. int woe_client_zmp(struct woe_client * cli, int argc, char *argv[]) {
  105. unsigned int i;
  106. mrb_state * mrb;
  107. LOG_NOTE("Received ZMP reply for client %d");
  108. mrb = woe_server_get_mrb(cli->server);
  109. if (mrb) {
  110. rh_run_toplevel(mrb, "woe_begin_zmp", "ii", cli->index, argc);
  111. for (i=0; i < argc; i++) {
  112. rh_run_toplevel(mrb, "woe_zmp_arg", "is", cli->index, argv[i]);
  113. }
  114. rh_run_toplevel(mrb, "woe_finish_zmp", "ii", cli->index, argc);
  115. }
  116. return 0;
  117. }