Ansify some function definitions that were previously overlooked.
[dragonfly.git] / usr.bin / telnet / ring.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
1de703da
MD
32 *
33 * @(#)ring.c 8.2 (Berkeley) 5/30/95
068e7061 34 * $FreeBSD: src/crypto/telnet/telnet/ring.c,v 1.2.8.2 2002/04/13 10:59:08 markm Exp $
984263bc
MD
35 */
36
984263bc
MD
37/*
38 * This defines a structure for a ring buffer.
39 *
40 * The circular buffer has two parts:
41 *(((
42 * full: [consume, supply)
43 * empty: [supply, consume)
44 *]]]
45 *
46 */
47
48#include <errno.h>
49#include <stdio.h>
50#include <string.h>
51
52#ifdef size_t
53#undef size_t
54#endif
55
56#include <sys/types.h>
57#ifndef FILIO_H
58#include <sys/ioctl.h>
59#endif
60#include <sys/socket.h>
61
62#include "ring.h"
63#include "general.h"
64
65/* Internal macros */
66
67#if !defined(MIN)
68#define MIN(a,b) (((a)<(b))? (a):(b))
69#endif /* !defined(MIN) */
70
71#define ring_subtract(d,a,b) (((a)-(b) >= 0)? \
72 (a)-(b): (((a)-(b))+(d)->size))
73
74#define ring_increment(d,a,c) (((a)+(c) < (d)->top)? \
75 (a)+(c) : (((a)+(c))-(d)->size))
76
77#define ring_decrement(d,a,c) (((a)-(c) >= (d)->bottom)? \
78 (a)-(c) : (((a)-(c))-(d)->size))
79
80
81/*
82 * The following is a clock, used to determine full, empty, etc.
83 *
84 * There is some trickiness here. Since the ring buffers are initialized
85 * to ZERO on allocation, we need to make sure, when interpreting the
86 * clock, that when the times are EQUAL, then the buffer is FULL.
87 */
88static u_long ring_clock = 0;
89
90
91#define ring_empty(d) (((d)->consume == (d)->supply) && \
92 ((d)->consumetime >= (d)->supplytime))
93#define ring_full(d) (((d)->supply == (d)->consume) && \
94 ((d)->supplytime > (d)->consumetime))
95
96/* Buffer state transition routines */
97
98int
99ring_init(Ring *ring, unsigned char *buffer, int count)
100{
101 memset((char *)ring, 0, sizeof *ring);
102
103 ring->size = count;
104
105 ring->supply = ring->consume = ring->bottom = buffer;
106
107 ring->top = ring->bottom+ring->size;
108
068e7061
PA
109#ifdef ENCRYPTION
110 ring->clearto = 0;
111#endif /* ENCRYPTION */
984263bc
MD
112
113 return 1;
114}
115
116/* Mark routines */
117
118/*
119 * Mark the most recently supplied byte.
120 */
121
122void
123ring_mark(Ring *ring)
124{
125 ring->mark = ring_decrement(ring, ring->supply, 1);
126}
127
128/*
129 * Is the ring pointing to the mark?
130 */
131
132int
133ring_at_mark(Ring *ring)
134{
135 if (ring->mark == ring->consume) {
136 return 1;
137 } else {
138 return 0;
139 }
140}
141
142/*
143 * Clear any mark set on the ring.
144 */
145
146void
147ring_clear_mark(Ring *ring)
148{
149 ring->mark = 0;
150}
151
152/*
153 * Add characters from current segment to ring buffer.
154 */
155void
156ring_supplied(Ring *ring, int count)
157{
158 ring->supply = ring_increment(ring, ring->supply, count);
159 ring->supplytime = ++ring_clock;
160}
161
162/*
163 * We have just consumed "c" bytes.
164 */
165void
166ring_consumed(Ring *ring, int count)
167{
168 if (count == 0) /* don't update anything */
169 return;
170
171 if (ring->mark &&
172 (ring_subtract(ring, ring->mark, ring->consume) < count)) {
173 ring->mark = 0;
174 }
068e7061
PA
175#ifdef ENCRYPTION
176 if (ring->consume < ring->clearto &&
177 ring->clearto <= ring->consume + count)
178 ring->clearto = 0;
179 else if (ring->consume + count > ring->top &&
180 ring->bottom <= ring->clearto &&
181 ring->bottom + ((ring->consume + count) - ring->top))
182 ring->clearto = 0;
183#endif /* ENCRYPTION */
984263bc
MD
184 ring->consume = ring_increment(ring, ring->consume, count);
185 ring->consumetime = ++ring_clock;
186 /*
187 * Try to encourage "ring_empty_consecutive()" to be large.
188 */
189 if (ring_empty(ring)) {
190 ring->consume = ring->supply = ring->bottom;
191 }
192}
193
194
195
196/* Buffer state query routines */
197
198
199/* Number of bytes that may be supplied */
200int
201ring_empty_count(Ring *ring)
202{
203 if (ring_empty(ring)) { /* if empty */
204 return ring->size;
205 } else {
206 return ring_subtract(ring, ring->consume, ring->supply);
207 }
208}
209
210/* number of CONSECUTIVE bytes that may be supplied */
211int
212ring_empty_consecutive(Ring *ring)
213{
214 if ((ring->consume < ring->supply) || ring_empty(ring)) {
215 /*
216 * if consume is "below" supply, or empty, then
217 * return distance to the top
218 */
219 return ring_subtract(ring, ring->top, ring->supply);
220 } else {
221 /*
222 * else, return what we may.
223 */
224 return ring_subtract(ring, ring->consume, ring->supply);
225 }
226}
227
228/* Return the number of bytes that are available for consuming
229 * (but don't give more than enough to get to cross over set mark)
230 */
231
232int
233ring_full_count(Ring *ring)
234{
235 if ((ring->mark == 0) || (ring->mark == ring->consume)) {
236 if (ring_full(ring)) {
237 return ring->size; /* nothing consumed, but full */
238 } else {
239 return ring_subtract(ring, ring->supply, ring->consume);
240 }
241 } else {
242 return ring_subtract(ring, ring->mark, ring->consume);
243 }
244}
245
246/*
247 * Return the number of CONSECUTIVE bytes available for consuming.
248 * However, don't return more than enough to cross over set mark.
249 */
250int
251ring_full_consecutive(Ring *ring)
252{
253 if ((ring->mark == 0) || (ring->mark == ring->consume)) {
254 if ((ring->supply < ring->consume) || ring_full(ring)) {
255 return ring_subtract(ring, ring->top, ring->consume);
256 } else {
257 return ring_subtract(ring, ring->supply, ring->consume);
258 }
259 } else {
260 if (ring->mark < ring->consume) {
261 return ring_subtract(ring, ring->top, ring->consume);
262 } else { /* Else, distance to mark */
263 return ring_subtract(ring, ring->mark, ring->consume);
264 }
265 }
266}
267
268/*
269 * Move data into the "supply" portion of of the ring buffer.
270 */
271void
272ring_supply_data(Ring *ring, unsigned char *buffer, int count)
273{
274 int i;
275
276 while (count) {
277 i = MIN(count, ring_empty_consecutive(ring));
278 memcpy(ring->supply, buffer, i);
279 ring_supplied(ring, i);
280 count -= i;
281 buffer += i;
282 }
283}
284
068e7061
PA
285#ifdef ENCRYPTION
286void
287ring_encrypt(Ring *ring, void (*encryptor)(unsigned char *, int))
288{
289 unsigned char *s, *c;
290
291 if (ring_empty(ring) || ring->clearto == ring->supply)
292 return;
293
294 if (!(c = ring->clearto))
295 c = ring->consume;
296
297 s = ring->supply;
298
299 if (s <= c) {
300 (*encryptor)(c, ring->top - c);
301 (*encryptor)(ring->bottom, s - ring->bottom);
302 } else
303 (*encryptor)(c, s - c);
304
305 ring->clearto = ring->supply;
306}
307
89a89091
SW
308void
309ring_clearto(Ring *ring)
068e7061
PA
310{
311 if (!ring_empty(ring))
312 ring->clearto = ring->supply;
313 else
314 ring->clearto = 0;
315}
316#endif /* ENCRYPTION */