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