[BACK]Return to buffer.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

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: }