CGI Bash Shell Interface
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

buffer.c 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * @PROJECT CGI Bash Shell Interface
  3. * @COPYRIGHT See COPYING in the top level directory
  4. * @FILE buffer.c
  5. * @PURPOSE CBSI Buffers
  6. * @DEVELOPERS Nathan Angelacos <nangel@users.sourceforge.net>
  7. * Rafal Kupiec <belliash@asiotec.eu.org>
  8. */
  9. #include <stdio.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include <errno.h>
  15. #include <fcntl.h>
  16. #include "buffer.h"
  17. void buffer_add(buffer_t* buf, const void* data, unsigned long size) {
  18. unsigned long newsize;
  19. unsigned long index;
  20. if((buf->ptr + size) >= buf->limit) {
  21. index = (buf->limit - buf->data);
  22. newsize = index;
  23. while(newsize <= index + size) {
  24. newsize += 1024;
  25. }
  26. index = buf->ptr - buf->data;
  27. buf->data = realloc(buf->data, newsize);
  28. buf->limit = buf->data + newsize;
  29. buf->ptr = buf->data + index;
  30. }
  31. memcpy(buf->ptr, data, size);
  32. buf->ptr += size;
  33. }
  34. void buffer_destroy(buffer_t* buf) {
  35. if(buf->data) {
  36. free(buf->data);
  37. }
  38. buffer_init(buf);
  39. }
  40. void buffer_init(buffer_t* buf) {
  41. buf->data = NULL;
  42. buf->ptr = NULL;
  43. buf->limit = NULL;
  44. }
  45. void buffer_reset(buffer_t* buf) {
  46. if(buf->data) {
  47. buf->ptr = buf->data;
  48. } else {
  49. buf->ptr = NULL;
  50. }
  51. }
  52. void sbuffer_destroy(sbuffer_t* sbuf) {
  53. free(sbuf->buf);
  54. }
  55. int sbuffer_init(sbuffer_t* sbuf, int size) {
  56. sbuf->maxsize = size;
  57. sbuf->buf = malloc (sbuf->maxsize);
  58. sbuf->maxsize -= 1;
  59. sbuf->fh = 0;
  60. sbuf->eof = 0;
  61. sbuf->len = 0;
  62. sbuf->ptr = sbuf->buf;
  63. sbuf->bufsize = 0;
  64. sbuf->maxread = 0;
  65. sbuf->nrread = 0;
  66. return (sbuf->buf != NULL);
  67. }
  68. int sbuffer_read(sbuffer_t* sbuf, char* matchstr) {
  69. int len, pos;
  70. int r;
  71. if((sbuf->eof) && (sbuf->ptr > sbuf->buf)) {
  72. return 0;
  73. }
  74. if((sbuf->bufsize == 0) || (sbuf->ptr >= (sbuf->buf + sbuf->bufsize - strlen (matchstr)))) {
  75. len = sbuf->bufsize - (sbuf->ptr - sbuf->buf);
  76. if(len) {
  77. memmove(sbuf->buf, sbuf->ptr, len);
  78. }
  79. sbuf->ptr = sbuf->buf;
  80. sbuf->bufsize = len;
  81. if(fcntl(sbuf->fh, F_GETFL) == -1) {
  82. r = 0;
  83. } else {
  84. size_t n = sbuf->maxsize - len;
  85. if(sbuf->maxread && sbuf->maxread < sbuf->nrread + n) {
  86. n = sbuf->maxread - sbuf->nrread;
  87. }
  88. r = read(sbuf->fh, sbuf->buf + len, n);
  89. }
  90. if(r == 0 || (r < 0 && errno != EINTR)) {
  91. sbuf->eof = -1;
  92. } else {
  93. sbuf->bufsize += (r > 0) ? r : 0;
  94. sbuf->nrread += (r > 0) ? r : 0;
  95. }
  96. }
  97. pos = 0;
  98. len = sbuf->bufsize - (int) (sbuf->ptr - sbuf->buf) - strlen(matchstr);
  99. while(memcmp(matchstr, sbuf->ptr + pos, strlen(matchstr)) && (pos < len)) {
  100. pos++;
  101. }
  102. if(pos < len) {
  103. sbuf->len = pos;
  104. sbuf->segment = sbuf->ptr;
  105. sbuf->ptr = sbuf->segment + pos + strlen(matchstr);
  106. return -1;
  107. }
  108. if(sbuf->eof) {
  109. len += strlen(matchstr);
  110. }
  111. sbuf->segment = sbuf->ptr;
  112. sbuf->len = len;
  113. sbuf->ptr += sbuf->len;
  114. return (sbuf->eof) ? (-1) : (0);
  115. }