ktp.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <sys/socket.h>
  11. #include <sys/un.h>
  12. #include <syslog.h>
  13. #include <faux/str.h>
  14. #include <faux/msg.h>
  15. #include <faux/eloop.h>
  16. #include <faux/async.h>
  17. #include <klish/ktp_session.h>
  18. int ktp_connect_unix(const char *sun_path)
  19. {
  20. int sock = -1;
  21. int opt = 1;
  22. struct sockaddr_un laddr = {};
  23. assert(sun_path);
  24. if (!sun_path)
  25. return -1;
  26. // Create socket
  27. if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  28. return -1;
  29. if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
  30. close(sock);
  31. return -1;
  32. }
  33. laddr.sun_family = AF_UNIX;
  34. strncpy(laddr.sun_path, sun_path, USOCK_PATH_MAX);
  35. laddr.sun_path[USOCK_PATH_MAX - 1] = '\0';
  36. // Connect to server
  37. if (connect(sock, (struct sockaddr *)&laddr, sizeof(laddr))) {
  38. close(sock);
  39. return -1;
  40. }
  41. return sock;
  42. }
  43. void ktp_disconnect(int fd)
  44. {
  45. if (fd < 0)
  46. return;
  47. close(fd);
  48. }
  49. int ktp_accept(int listen_sock)
  50. {
  51. int new_conn = -1;
  52. new_conn = accept(listen_sock, NULL, NULL);
  53. return new_conn;
  54. }
  55. bool_t ktp_check_header(faux_hdr_t *hdr)
  56. {
  57. assert(hdr);
  58. if (!hdr)
  59. return BOOL_FALSE;
  60. if (faux_hdr_magic(hdr) != KTP_MAGIC)
  61. return BOOL_FALSE;
  62. if (faux_hdr_major(hdr) != KTP_MAJOR)
  63. return BOOL_FALSE;
  64. if (faux_hdr_minor(hdr) != KTP_MINOR)
  65. return BOOL_FALSE;
  66. if (faux_hdr_len(hdr) < (int)sizeof(*hdr))
  67. return BOOL_FALSE;
  68. return BOOL_TRUE;
  69. }
  70. faux_msg_t *ktp_msg_preform(ktp_cmd_e cmd, uint32_t status)
  71. {
  72. faux_msg_t *msg = NULL;
  73. msg = faux_msg_new(KTP_MAGIC, KTP_MAJOR, KTP_MINOR);
  74. assert(msg);
  75. if (!msg)
  76. return NULL;
  77. faux_msg_set_cmd(msg, cmd);
  78. faux_msg_set_status(msg, status);
  79. return msg;
  80. }
  81. bool_t ktp_send_error(faux_async_t *async, ktp_cmd_e cmd, const char *error)
  82. {
  83. faux_msg_t *msg = NULL;
  84. assert(async);
  85. if (!async)
  86. return BOOL_FALSE;
  87. msg = ktp_msg_preform(cmd, KTP_STATUS_ERROR);
  88. if (error)
  89. faux_msg_add_param(msg, KTP_PARAM_ERROR, error, strlen(error));
  90. faux_msg_send_async(msg, async);
  91. faux_msg_free(msg);
  92. return BOOL_TRUE;
  93. }
  94. bool_t ktp_peer_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
  95. void *associated_data, void *user_data)
  96. {
  97. faux_eloop_info_fd_t *info = (faux_eloop_info_fd_t *)associated_data;
  98. faux_async_t *async = (faux_async_t *)user_data;
  99. assert(async);
  100. // Write data
  101. if (info->revents & POLLOUT) {
  102. faux_eloop_exclude_fd_event(eloop, info->fd, POLLOUT);
  103. if (faux_async_out(async) < 0) {
  104. // Someting went wrong
  105. faux_eloop_del_fd(eloop, info->fd);
  106. syslog(LOG_ERR, "Problem with async output");
  107. return BOOL_FALSE; // Stop event loop
  108. }
  109. }
  110. // Read data
  111. if (info->revents & POLLIN) {
  112. if (faux_async_in(async) < 0) {
  113. // Someting went wrong
  114. faux_eloop_del_fd(eloop, info->fd);
  115. syslog(LOG_ERR, "Problem with async input");
  116. return BOOL_FALSE; // Stop event loop
  117. }
  118. }
  119. // EOF
  120. if (info->revents & POLLHUP) {
  121. faux_eloop_del_fd(eloop, info->fd);
  122. syslog(LOG_DEBUG, "Close connection %d", info->fd);
  123. return BOOL_FALSE; // Stop event loop
  124. }
  125. // POLLERR
  126. if (info->revents & POLLERR) {
  127. faux_eloop_del_fd(eloop, info->fd);
  128. syslog(LOG_DEBUG, "POLLERR received %d", info->fd);
  129. return BOOL_FALSE; // Stop event loop
  130. }
  131. // POLLNVAL
  132. if (info->revents & POLLNVAL) {
  133. faux_eloop_del_fd(eloop, info->fd);
  134. syslog(LOG_DEBUG, "POLLNVAL received %d", info->fd);
  135. return BOOL_FALSE; // Stop event loop
  136. }
  137. type = type; // Happy compiler
  138. return BOOL_TRUE;
  139. }
  140. bool_t ktp_stall_cb(faux_async_t *async, size_t len, void *user_data)
  141. {
  142. faux_eloop_t *eloop = (faux_eloop_t *)user_data;
  143. assert(eloop);
  144. faux_eloop_include_fd_event(eloop, faux_async_fd(async), POLLOUT);
  145. len = len; // Happy compiler
  146. return BOOL_TRUE;
  147. }