/src/dropbear/src/circbuffer.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Dropbear SSH |
3 | | * |
4 | | * Copyright (c) 2002-2004 Matt Johnston |
5 | | * All rights reserved. |
6 | | * |
7 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | | * of this software and associated documentation files (the "Software"), to deal |
9 | | * in the Software without restriction, including without limitation the rights |
10 | | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | | * copies of the Software, and to permit persons to whom the Software is |
12 | | * furnished to do so, subject to the following conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be included in |
15 | | * all copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 | | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | | * SOFTWARE. */ |
24 | | |
25 | | #include "includes.h" |
26 | | #include "dbutil.h" |
27 | | #include "circbuffer.h" |
28 | | |
29 | 4.80k | #define MAX_CBUF_SIZE 100000000 |
30 | | |
31 | 4.80k | circbuffer * cbuf_new(unsigned int size) { |
32 | | |
33 | 4.80k | circbuffer *cbuf = NULL; |
34 | | |
35 | 4.80k | if (size > MAX_CBUF_SIZE) { |
36 | 0 | dropbear_exit("Bad cbuf size"); |
37 | 0 | } |
38 | | |
39 | 4.80k | cbuf = (circbuffer*)m_malloc(sizeof(circbuffer)); |
40 | | /* data is malloced on first write */ |
41 | 4.80k | cbuf->data = NULL; |
42 | 4.80k | cbuf->used = 0; |
43 | 4.80k | cbuf->readpos = 0; |
44 | 4.80k | cbuf->writepos = 0; |
45 | 4.80k | cbuf->size = size; |
46 | | |
47 | 4.80k | return cbuf; |
48 | 4.80k | } |
49 | | |
50 | 4.80k | void cbuf_free(circbuffer * cbuf) { |
51 | | |
52 | 4.80k | if (cbuf->data) { |
53 | 0 | m_burn(cbuf->data, cbuf->size); |
54 | 0 | m_free(cbuf->data); |
55 | 0 | } |
56 | 4.80k | m_free(cbuf); |
57 | 4.80k | } |
58 | | |
59 | 980k | unsigned int cbuf_getused(const circbuffer * cbuf) { |
60 | | |
61 | 980k | return cbuf->used; |
62 | | |
63 | 980k | } |
64 | | |
65 | 33 | unsigned int cbuf_getavail(const circbuffer * cbuf) { |
66 | | |
67 | 33 | return cbuf->size - cbuf->used; |
68 | | |
69 | 33 | } |
70 | | |
71 | 0 | unsigned int cbuf_writelen(const circbuffer *cbuf) { |
72 | |
|
73 | 0 | dropbear_assert(cbuf->used <= cbuf->size); |
74 | 0 | dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size); |
75 | 0 | dropbear_assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); |
76 | | |
77 | 0 | if (cbuf->used == cbuf->size) { |
78 | 0 | TRACE(("cbuf_writelen: full buffer")) |
79 | 0 | return 0; /* full */ |
80 | 0 | } |
81 | | |
82 | 0 | if (cbuf->writepos < cbuf->readpos) { |
83 | 0 | return cbuf->readpos - cbuf->writepos; |
84 | 0 | } |
85 | | |
86 | 0 | return cbuf->size - cbuf->writepos; |
87 | 0 | } |
88 | | |
89 | | void cbuf_readptrs(const circbuffer *cbuf, |
90 | | unsigned char **p1, unsigned int *len1, |
91 | 15 | unsigned char **p2, unsigned int *len2) { |
92 | 15 | *p1 = &cbuf->data[cbuf->readpos]; |
93 | 15 | *len1 = MIN(cbuf->used, cbuf->size - cbuf->readpos); |
94 | | |
95 | 15 | if (*len1 < cbuf->used) { |
96 | 0 | *p2 = cbuf->data; |
97 | 0 | *len2 = cbuf->used - *len1; |
98 | 15 | } else { |
99 | 15 | *p2 = NULL; |
100 | 15 | *len2 = 0; |
101 | 15 | } |
102 | 15 | } |
103 | | |
104 | 0 | unsigned char* cbuf_writeptr(circbuffer *cbuf, unsigned int len) { |
105 | |
|
106 | 0 | if (len > cbuf_writelen(cbuf)) { |
107 | 0 | dropbear_exit("Bad cbuf write"); |
108 | 0 | } |
109 | | |
110 | 0 | if (!cbuf->data) { |
111 | | /* lazy allocation */ |
112 | 0 | cbuf->data = (unsigned char*)m_malloc(cbuf->size); |
113 | 0 | } |
114 | |
|
115 | 0 | return &cbuf->data[cbuf->writepos]; |
116 | 0 | } |
117 | | |
118 | 0 | void cbuf_incrwrite(circbuffer *cbuf, unsigned int len) { |
119 | 0 | if (len > cbuf_writelen(cbuf)) { |
120 | 0 | dropbear_exit("Bad cbuf write"); |
121 | 0 | } |
122 | | |
123 | 0 | cbuf->used += len; |
124 | 0 | dropbear_assert(cbuf->used <= cbuf->size); |
125 | 0 | cbuf->writepos = (cbuf->writepos + len) % cbuf->size; |
126 | 0 | } |
127 | | |
128 | | |
129 | 0 | void cbuf_incrread(circbuffer *cbuf, unsigned int len) { |
130 | 0 | dropbear_assert(cbuf->used >= len); |
131 | 0 | cbuf->used -= len; |
132 | 0 | cbuf->readpos = (cbuf->readpos + len) % cbuf->size; |
133 | 0 | } |