message.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* This file is part of libepistle.
  2. *
  3. * libepistle is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU Lesser General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * libepistle is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public License
  14. * along with libepistle. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <arpa/inet.h>
  17. #include <string.h>
  18. #include "err.h"
  19. #include "transfer.h"
  20. #include "message.h"
  21. int
  22. msg_copy(Msg *des, const Msg *src, Err *err)
  23. {
  24. *des = *src;
  25. if (!src->buf_freeable)
  26. return 0;
  27. if (!(des->buf = malloc(src->len))) {
  28. err_std(err);
  29. return -1;
  30. }
  31. memcpy(des->buf, src->buf, src->len);
  32. return 0;
  33. }
  34. int
  35. msg_extend(Msg *msg, uint32_t amt, Err *err)
  36. {
  37. void *tmp;
  38. if (msg->buf_freeable) {
  39. if (!(tmp = realloc(msg->buf, msg->len + amt)))
  40. goto error;
  41. } else {
  42. if (!(tmp = malloc(msg->len + amt)))
  43. goto error;
  44. memcpy(tmp, msg->buf, msg->len);
  45. }
  46. msg->buf = tmp;
  47. msg->buf_freeable = 1;
  48. return 0;
  49. error:
  50. err_std(err);
  51. return -1;
  52. }
  53. void
  54. msg_send_init(Msg *msg, uint32_t len, void *buf, int buf_freeable)
  55. {
  56. msg->len_tnsfd = msg->buf_tnsfd = 0;
  57. msg->len = len;
  58. msg->buf = buf;
  59. msg->buf_freeable = buf_freeable;
  60. }
  61. int
  62. msg_send(int fd, Msg *msg, int wait, Err *err)
  63. {
  64. if (msg->len_tnsfd < sizeof(msg->len)) {
  65. uint32_t net_len = htonl(msg->len);
  66. if (send_buf(&net_len, fd, sizeof(net_len),
  67. &msg->len_tnsfd, wait, err) < 0)
  68. return -1;
  69. if (msg->len_tnsfd < sizeof(msg->len))
  70. return 0;
  71. }
  72. if (msg->buf_tnsfd >= msg->len)
  73. return 0;
  74. return send_buf(msg->buf, fd, msg->len, &msg->buf_tnsfd, wait, err);
  75. }
  76. void
  77. msg_recv_init(Msg *msg)
  78. {
  79. msg->len_tnsfd = msg->buf_tnsfd = 0;
  80. msg->buf = NULL;
  81. msg->buf_freeable = 1;
  82. }
  83. int
  84. msg_recv(int fd, Msg *msg, uint32_t max_len, int wait, Err *err)
  85. {
  86. if (msg->len_tnsfd < sizeof(msg->len)) {
  87. if (recv_buf(&msg->len, fd, sizeof(msg->len),
  88. &msg->len_tnsfd, wait, err) < 0)
  89. return -1;
  90. if (msg->len_tnsfd < sizeof(msg->len))
  91. return 0;
  92. msg->len = ntohl(msg->len);
  93. }
  94. if (msg->len > max_len) {
  95. err_epistle(err, EPISTLE_ERR_LEN);
  96. return -1;
  97. }
  98. if (msg->buf_tnsfd >= msg->len)
  99. return 0;
  100. if (!msg->buf && !(msg->buf = malloc(msg->len))) {
  101. err_std(err);
  102. return -1;
  103. }
  104. return recv_buf(msg->buf, fd, msg->len, &msg->buf_tnsfd, wait, err);
  105. }
  106. void
  107. msg_dispose(Msg *msg)
  108. {
  109. if (msg->buf_freeable)
  110. free(msg->buf);
  111. }
  112. int
  113. msg_tnsfd(Msg *msg)
  114. {
  115. return msg->len_tnsfd == sizeof(msg->len) &&
  116. msg->buf_tnsfd == msg->len;
  117. }
  118. void
  119. msg_reuse(Msg *msg)
  120. {
  121. msg->len_tnsfd = msg->buf_tnsfd = 0;
  122. }