Annotation of src/usr.bin/ssh/buffer.c, Revision 1.2
1.1 deraadt 1: /*
2:
3: buffer.c
4:
5: Author: Tatu Ylonen <ylo@cs.hut.fi>
6:
7: Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8: All rights reserved
9:
10: Created: Sat Mar 18 04:15:33 1995 ylo
11:
12: Functions for manipulating fifo buffers (that can grow if needed).
13:
14: */
15:
16: #include "includes.h"
1.2 ! markus 17: RCSID("$Id: buffer.c,v 1.1 1999/09/26 20:53:34 deraadt Exp $");
1.1 deraadt 18:
19: #include "xmalloc.h"
20: #include "buffer.h"
21: #include "ssh.h"
22:
23: /* Initializes the buffer structure. */
24:
1.2 ! markus 25: void
! 26: buffer_init(Buffer *buffer)
1.1 deraadt 27: {
1.2 ! markus 28: buffer->alloc = 4096;
! 29: buffer->buf = xmalloc(buffer->alloc);
! 30: buffer->offset = 0;
! 31: buffer->end = 0;
1.1 deraadt 32: }
33:
34: /* Frees any memory used for the buffer. */
35:
1.2 ! markus 36: void
! 37: buffer_free(Buffer *buffer)
1.1 deraadt 38: {
1.2 ! markus 39: memset(buffer->buf, 0, buffer->alloc);
! 40: xfree(buffer->buf);
1.1 deraadt 41: }
42:
43: /* Clears any data from the buffer, making it empty. This does not actually
44: zero the memory. */
45:
1.2 ! markus 46: void
! 47: buffer_clear(Buffer *buffer)
1.1 deraadt 48: {
1.2 ! markus 49: buffer->offset = 0;
! 50: buffer->end = 0;
1.1 deraadt 51: }
52:
53: /* Appends data to the buffer, expanding it if necessary. */
54:
1.2 ! markus 55: void
! 56: buffer_append(Buffer *buffer, const char *data, unsigned int len)
1.1 deraadt 57: {
1.2 ! markus 58: char *cp;
! 59: buffer_append_space(buffer, &cp, len);
! 60: memcpy(cp, data, len);
1.1 deraadt 61: }
62:
63: /* Appends space to the buffer, expanding the buffer if necessary.
64: This does not actually copy the data into the buffer, but instead
65: returns a pointer to the allocated region. */
66:
1.2 ! markus 67: void
! 68: buffer_append_space(Buffer *buffer, char **datap, unsigned int len)
1.1 deraadt 69: {
1.2 ! markus 70: /* If the buffer is empty, start using it from the beginning. */
! 71: if (buffer->offset == buffer->end) {
! 72: buffer->offset = 0;
! 73: buffer->end = 0;
! 74: }
! 75: restart:
! 76: /* If there is enough space to store all data, store it now. */
! 77: if (buffer->end + len < buffer->alloc) {
! 78: *datap = buffer->buf + buffer->end;
! 79: buffer->end += len;
! 80: return;
! 81: }
! 82: /* If the buffer is quite empty, but all data is at the end, move
! 83: the data to the beginning and retry. */
! 84: if (buffer->offset > buffer->alloc / 2) {
! 85: memmove(buffer->buf, buffer->buf + buffer->offset,
! 86: buffer->end - buffer->offset);
! 87: buffer->end -= buffer->offset;
! 88: buffer->offset = 0;
! 89: goto restart;
! 90: }
! 91: /* Increase the size of the buffer and retry. */
! 92: buffer->alloc += len + 32768;
! 93: buffer->buf = xrealloc(buffer->buf, buffer->alloc);
! 94: goto restart;
1.1 deraadt 95: }
96:
97: /* Returns the number of bytes of data in the buffer. */
98:
1.2 ! markus 99: unsigned int
! 100: buffer_len(Buffer *buffer)
1.1 deraadt 101: {
1.2 ! markus 102: return buffer->end - buffer->offset;
1.1 deraadt 103: }
104:
105: /* Gets data from the beginning of the buffer. */
106:
1.2 ! markus 107: void
! 108: buffer_get(Buffer *buffer, char *buf, unsigned int len)
1.1 deraadt 109: {
1.2 ! markus 110: if (len > buffer->end - buffer->offset)
! 111: fatal("buffer_get trying to get more bytes than in buffer");
! 112: memcpy(buf, buffer->buf + buffer->offset, len);
! 113: buffer->offset += len;
1.1 deraadt 114: }
115:
116: /* Consumes the given number of bytes from the beginning of the buffer. */
117:
1.2 ! markus 118: void
! 119: buffer_consume(Buffer *buffer, unsigned int bytes)
1.1 deraadt 120: {
1.2 ! markus 121: if (bytes > buffer->end - buffer->offset)
! 122: fatal("buffer_get trying to get more bytes than in buffer");
! 123: buffer->offset += bytes;
! 124: }
1.1 deraadt 125:
126: /* Consumes the given number of bytes from the end of the buffer. */
127:
1.2 ! markus 128: void
! 129: buffer_consume_end(Buffer *buffer, unsigned int bytes)
1.1 deraadt 130: {
1.2 ! markus 131: if (bytes > buffer->end - buffer->offset)
! 132: fatal("buffer_get trying to get more bytes than in buffer");
! 133: buffer->end -= bytes;
! 134: }
1.1 deraadt 135:
136: /* Returns a pointer to the first used byte in the buffer. */
137:
1.2 ! markus 138: char *
! 139: buffer_ptr(Buffer *buffer)
1.1 deraadt 140: {
1.2 ! markus 141: return buffer->buf + buffer->offset;
1.1 deraadt 142: }
143:
144: /* Dumps the contents of the buffer to stderr. */
145:
1.2 ! markus 146: void
! 147: buffer_dump(Buffer *buffer)
1.1 deraadt 148: {
1.2 ! markus 149: int i;
! 150: unsigned char *ucp = (unsigned char *) buffer->buf;
! 151:
! 152: for (i = buffer->offset; i < buffer->end; i++)
! 153: fprintf(stderr, " %02x", ucp[i]);
! 154: fprintf(stderr, "\n");
1.1 deraadt 155: }