xref: /titanic_52/usr/src/cmd/cmd-inet/usr.bin/telnet/ring.c (revision 740638c8fa5a1c03618a9c75c3161dba57259a17)
17c478bd9Sstevel@tonic-gate /*
2*740638c8Sbw  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
77c478bd9Sstevel@tonic-gate 
87c478bd9Sstevel@tonic-gate /*
97c478bd9Sstevel@tonic-gate  * usr/src/cmd/cmd-inet/usr.bin/telnet/ring.c
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate /*
137c478bd9Sstevel@tonic-gate  * Copyright (c) 1988, 1993
147c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
177c478bd9Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
187c478bd9Sstevel@tonic-gate  * are met:
197c478bd9Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
207c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
217c478bd9Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
227c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
237c478bd9Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
247c478bd9Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
257c478bd9Sstevel@tonic-gate  *    must display the following acknowledgement:
267c478bd9Sstevel@tonic-gate  *	This product includes software developed by the University of
277c478bd9Sstevel@tonic-gate  *	California, Berkeley and its contributors.
287c478bd9Sstevel@tonic-gate  * 4. Neither the name of the University nor the names of its contributors
297c478bd9Sstevel@tonic-gate  *    may be used to endorse or promote products derived from this software
307c478bd9Sstevel@tonic-gate  *    without specific prior written permission.
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
337c478bd9Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
347c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
357c478bd9Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
367c478bd9Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
377c478bd9Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
387c478bd9Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
397c478bd9Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
407c478bd9Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
417c478bd9Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
427c478bd9Sstevel@tonic-gate  * SUCH DAMAGE.
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #ifndef lint
467c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)ring.c	8.1 (Berkeley) 6/6/93";
477c478bd9Sstevel@tonic-gate #endif /* not lint */
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate  * This defines a structure for a ring buffer.
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  * The circular buffer has two parts:
537c478bd9Sstevel@tonic-gate  * (((
547c478bd9Sstevel@tonic-gate  *	full:	[consume, supply)
557c478bd9Sstevel@tonic-gate  *	empty:	[supply, consume)
567c478bd9Sstevel@tonic-gate  * ]]]
577c478bd9Sstevel@tonic-gate  *
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate #include	<stdio.h>
617c478bd9Sstevel@tonic-gate #include	<errno.h>
627c478bd9Sstevel@tonic-gate #include	<string.h>
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #include	<sys/types.h>
657c478bd9Sstevel@tonic-gate #include	<sys/socket.h>
667c478bd9Sstevel@tonic-gate #include	<sys/sysmacros.h>
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate #include	"ring.h"
697c478bd9Sstevel@tonic-gate #include	"general.h"
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate #define	ring_subtract(d, a, b)	(((a)-(b) >= 0)? \
737c478bd9Sstevel@tonic-gate 					(a)-(b): (((a)-(b))+(d)->size))
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate #define	ring_increment(d, a, c)	(((a)+(c) < (d)->top)? \
767c478bd9Sstevel@tonic-gate 					(a)+(c) : (((a)+(c))-(d)->size))
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #define	ring_decrement(d, a, c)	(((a)-(c) >= (d)->bottom)? \
797c478bd9Sstevel@tonic-gate 					(a)-(c) : (((a)-(c))-(d)->size))
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate  * The following is a clock, used to determine full, empty, etc.
847c478bd9Sstevel@tonic-gate  *
857c478bd9Sstevel@tonic-gate  * There is some trickiness here.  Since the ring buffers are initialized
867c478bd9Sstevel@tonic-gate  * to ZERO on allocation, we need to make sure, when interpreting the
877c478bd9Sstevel@tonic-gate  * clock, that when the times are EQUAL, then the buffer is FULL.
887c478bd9Sstevel@tonic-gate  */
897c478bd9Sstevel@tonic-gate ulong_t ring_clock = 0;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate #define	ring_empty(d) (((d)->consume == (d)->supply) && \
937c478bd9Sstevel@tonic-gate 				((d)->consumetime >= (d)->supplytime))
947c478bd9Sstevel@tonic-gate #define	ring_full(d) (((d)->supply == (d)->consume) && \
957c478bd9Sstevel@tonic-gate 				((d)->supplytime > (d)->consumetime))
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /* Buffer state transition routines */
1027c478bd9Sstevel@tonic-gate 
103*740638c8Sbw int
1047c478bd9Sstevel@tonic-gate     ring_init(ring, buffer, count)
1057c478bd9Sstevel@tonic-gate Ring *ring;
1067c478bd9Sstevel@tonic-gate     unsigned char *buffer;
1077c478bd9Sstevel@tonic-gate     int count;
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	(void) memset(ring, 0, sizeof (*ring));
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	ring->size = count;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	ring->supply = ring->consume = ring->bottom = buffer;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	ring->top = ring->bottom+ring->size;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	ring->clearto = 0;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	return (1);
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate /* Mark routines */
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  * Mark the most recently supplied byte.
1267c478bd9Sstevel@tonic-gate  */
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate void
1297c478bd9Sstevel@tonic-gate ring_mark(ring)
1307c478bd9Sstevel@tonic-gate 	Ring *ring;
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	ring->mark = ring_decrement(ring, ring->supply, 1);
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate  * Is the ring pointing to the mark?
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate int
1407c478bd9Sstevel@tonic-gate ring_at_mark(ring)
1417c478bd9Sstevel@tonic-gate 	Ring *ring;
1427c478bd9Sstevel@tonic-gate {
1437c478bd9Sstevel@tonic-gate 	if (ring->mark == ring->consume) {
1447c478bd9Sstevel@tonic-gate 		return (1);
1457c478bd9Sstevel@tonic-gate 	} else {
1467c478bd9Sstevel@tonic-gate 		return (0);
1477c478bd9Sstevel@tonic-gate 	}
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate  * Clear any mark set on the ring.
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate void
1557c478bd9Sstevel@tonic-gate ring_clear_mark(ring)
1567c478bd9Sstevel@tonic-gate 	Ring *ring;
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate 	ring->mark = 0;
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate  * Add characters from current segment to ring buffer.
1637c478bd9Sstevel@tonic-gate  */
1647c478bd9Sstevel@tonic-gate     void
1657c478bd9Sstevel@tonic-gate ring_supplied(ring, count)
1667c478bd9Sstevel@tonic-gate     Ring *ring;
1677c478bd9Sstevel@tonic-gate     int count;
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate     ring->supply = ring_increment(ring, ring->supply, count);
1707c478bd9Sstevel@tonic-gate     ring->supplytime = ++ring_clock;
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate /*
1747c478bd9Sstevel@tonic-gate  * We have just consumed "c" bytes.
1757c478bd9Sstevel@tonic-gate  */
1767c478bd9Sstevel@tonic-gate void
1777c478bd9Sstevel@tonic-gate ring_consumed(ring, count)
1787c478bd9Sstevel@tonic-gate 	Ring *ring;
1797c478bd9Sstevel@tonic-gate 	int count;
1807c478bd9Sstevel@tonic-gate {
1817c478bd9Sstevel@tonic-gate 	if (count == 0)	/* don't update anything */
1827c478bd9Sstevel@tonic-gate 		return;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	if (ring->mark &&
1857c478bd9Sstevel@tonic-gate 	    (ring_subtract(ring, ring->mark, ring->consume) < count)) {
1867c478bd9Sstevel@tonic-gate 		ring->mark = 0;
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	if (ring->consume < ring->clearto &&
1907c478bd9Sstevel@tonic-gate 	    ring->clearto <= ring->consume + count)
1917c478bd9Sstevel@tonic-gate 		ring->clearto = 0;
1927c478bd9Sstevel@tonic-gate 	else if (ring->consume + count > ring->top &&
1937c478bd9Sstevel@tonic-gate 	    ring->bottom <= ring->clearto &&
1947c478bd9Sstevel@tonic-gate 	    ring->bottom + ((ring->consume + count) - ring->top))
1957c478bd9Sstevel@tonic-gate 		ring->clearto = 0;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	ring->consume = ring_increment(ring, ring->consume, count);
1987c478bd9Sstevel@tonic-gate 	ring->consumetime = ++ring_clock;
1997c478bd9Sstevel@tonic-gate 	/*
2007c478bd9Sstevel@tonic-gate 	 * Try to encourage "ring_empty_consecutive()" to be large.
2017c478bd9Sstevel@tonic-gate 	 */
2027c478bd9Sstevel@tonic-gate 	if (ring_empty(ring)) {
2037c478bd9Sstevel@tonic-gate 		ring->consume = ring->supply = ring->bottom;
2047c478bd9Sstevel@tonic-gate 	}
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate /* Buffer state query routines */
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate /* Number of bytes that may be supplied */
2137c478bd9Sstevel@tonic-gate int
2147c478bd9Sstevel@tonic-gate ring_empty_count(ring)
2157c478bd9Sstevel@tonic-gate 	Ring *ring;
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate 	if (ring_empty(ring)) {	/* if empty */
2187c478bd9Sstevel@tonic-gate 		return (ring->size);
2197c478bd9Sstevel@tonic-gate 	} else {
2207c478bd9Sstevel@tonic-gate 		return (ring_subtract(ring, ring->consume, ring->supply));
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate /* number of CONSECUTIVE bytes that may be supplied */
2257c478bd9Sstevel@tonic-gate int
2267c478bd9Sstevel@tonic-gate ring_empty_consecutive(ring)
2277c478bd9Sstevel@tonic-gate 	Ring *ring;
2287c478bd9Sstevel@tonic-gate {
2297c478bd9Sstevel@tonic-gate 	if ((ring->consume < ring->supply) || ring_empty(ring)) {
2307c478bd9Sstevel@tonic-gate 		/*
2317c478bd9Sstevel@tonic-gate 		 * if consume is "below" supply, or empty, then
2327c478bd9Sstevel@tonic-gate 		 * return distance to the top
2337c478bd9Sstevel@tonic-gate 		 */
2347c478bd9Sstevel@tonic-gate 		return (ring_subtract(ring, ring->top, ring->supply));
2357c478bd9Sstevel@tonic-gate 	} else {
2367c478bd9Sstevel@tonic-gate 		/*
2377c478bd9Sstevel@tonic-gate 		 * else, return what we may.
2387c478bd9Sstevel@tonic-gate 		 */
2397c478bd9Sstevel@tonic-gate 		return (ring_subtract(ring, ring->consume, ring->supply));
2407c478bd9Sstevel@tonic-gate 	}
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate /*
2447c478bd9Sstevel@tonic-gate  * Return the number of bytes that are available for consuming
2457c478bd9Sstevel@tonic-gate  * (but don't give more than enough to get to cross over set mark)
2467c478bd9Sstevel@tonic-gate  */
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate int
2497c478bd9Sstevel@tonic-gate ring_full_count(ring)
2507c478bd9Sstevel@tonic-gate 	Ring *ring;
2517c478bd9Sstevel@tonic-gate {
2527c478bd9Sstevel@tonic-gate 	if ((ring->mark == 0) || (ring->mark == ring->consume)) {
2537c478bd9Sstevel@tonic-gate 		if (ring_full(ring)) {
2547c478bd9Sstevel@tonic-gate 			return (ring->size);	/* nothing consumed, but full */
2557c478bd9Sstevel@tonic-gate 		} else {
2567c478bd9Sstevel@tonic-gate 			return (ring_subtract(ring, ring->supply,
2577c478bd9Sstevel@tonic-gate 			    ring->consume));
2587c478bd9Sstevel@tonic-gate 		}
2597c478bd9Sstevel@tonic-gate 	} else {
2607c478bd9Sstevel@tonic-gate 		return (ring_subtract(ring, ring->mark, ring->consume));
2617c478bd9Sstevel@tonic-gate 	}
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate /*
2657c478bd9Sstevel@tonic-gate  * Return the number of CONSECUTIVE bytes available for consuming.
2667c478bd9Sstevel@tonic-gate  * However, don't return more than enough to cross over set mark.
2677c478bd9Sstevel@tonic-gate  */
2687c478bd9Sstevel@tonic-gate int
2697c478bd9Sstevel@tonic-gate ring_full_consecutive(ring)
2707c478bd9Sstevel@tonic-gate 	Ring *ring;
2717c478bd9Sstevel@tonic-gate {
2727c478bd9Sstevel@tonic-gate 	if ((ring->mark == 0) || (ring->mark == ring->consume)) {
2737c478bd9Sstevel@tonic-gate 		if ((ring->supply < ring->consume) || ring_full(ring)) {
2747c478bd9Sstevel@tonic-gate 			return (ring_subtract(ring, ring->top, ring->consume));
2757c478bd9Sstevel@tonic-gate 		} else {
2767c478bd9Sstevel@tonic-gate 			return (ring_subtract(ring, ring->supply,
2777c478bd9Sstevel@tonic-gate 			    ring->consume));
2787c478bd9Sstevel@tonic-gate 		}
2797c478bd9Sstevel@tonic-gate 	} else {
2807c478bd9Sstevel@tonic-gate 		if (ring->mark < ring->consume) {
2817c478bd9Sstevel@tonic-gate 			return (ring_subtract(ring, ring->top, ring->consume));
2827c478bd9Sstevel@tonic-gate 		} else {	/* Else, distance to mark */
2837c478bd9Sstevel@tonic-gate 			return (ring_subtract(ring, ring->mark, ring->consume));
2847c478bd9Sstevel@tonic-gate 		}
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate /*
2897c478bd9Sstevel@tonic-gate  * Move data into the "supply" portion of of the ring buffer.
2907c478bd9Sstevel@tonic-gate  */
2917c478bd9Sstevel@tonic-gate void
2927c478bd9Sstevel@tonic-gate ring_supply_data(ring, buffer, count)
2937c478bd9Sstevel@tonic-gate 	Ring *ring;
2947c478bd9Sstevel@tonic-gate 	unsigned char *buffer;
2957c478bd9Sstevel@tonic-gate 	int count;
2967c478bd9Sstevel@tonic-gate {
2977c478bd9Sstevel@tonic-gate 	int i;
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	while (count) {
3007c478bd9Sstevel@tonic-gate 		i = MIN(count, ring_empty_consecutive(ring));
3017c478bd9Sstevel@tonic-gate 		(void) memcpy(ring->supply, buffer, i);
3027c478bd9Sstevel@tonic-gate 		ring_supplied(ring, i);
3037c478bd9Sstevel@tonic-gate 		count -= i;
3047c478bd9Sstevel@tonic-gate 		buffer += i;
3057c478bd9Sstevel@tonic-gate 	}
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate #ifdef notdef
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate /*
3117c478bd9Sstevel@tonic-gate  * Move data from the "consume" portion of the ring buffer
3127c478bd9Sstevel@tonic-gate  */
3137c478bd9Sstevel@tonic-gate void
3147c478bd9Sstevel@tonic-gate ring_consume_data(ring, buffer, count)
3157c478bd9Sstevel@tonic-gate 	Ring *ring;
3167c478bd9Sstevel@tonic-gate 	unsigned char *buffer;
3177c478bd9Sstevel@tonic-gate 	int count;
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate 	int i;
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	while (count) {
3227c478bd9Sstevel@tonic-gate 		i = MIN(count, ring_full_consecutive(ring));
3237c478bd9Sstevel@tonic-gate 		memcpy(buffer, ring->consume, i);
3247c478bd9Sstevel@tonic-gate 		ring_consumed(ring, i);
3257c478bd9Sstevel@tonic-gate 		count -= i;
3267c478bd9Sstevel@tonic-gate 		buffer += i;
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate #endif
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate void
3327c478bd9Sstevel@tonic-gate ring_encrypt(ring, encryptor)
3337c478bd9Sstevel@tonic-gate 	Ring *ring;
3347c478bd9Sstevel@tonic-gate 	void (*encryptor)();
3357c478bd9Sstevel@tonic-gate {
3367c478bd9Sstevel@tonic-gate 	unsigned char *s, *c;
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	if (ring_empty(ring) || ring->clearto == ring->supply)
3397c478bd9Sstevel@tonic-gate 		return;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	if ((c = ring->clearto) == NULL)
3427c478bd9Sstevel@tonic-gate 		c = ring->consume;
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	s = ring->supply;
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	if (s <= c) {
3477c478bd9Sstevel@tonic-gate 		(*encryptor)(c, ring->top - c);
3487c478bd9Sstevel@tonic-gate 		(*encryptor)(ring->bottom, s - ring->bottom);
3497c478bd9Sstevel@tonic-gate 	} else
3507c478bd9Sstevel@tonic-gate 		(*encryptor)(c, s - c);
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	ring->clearto = ring->supply;
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate     void
3567c478bd9Sstevel@tonic-gate ring_clearto(ring)
3577c478bd9Sstevel@tonic-gate     Ring *ring;
3587c478bd9Sstevel@tonic-gate {
3597c478bd9Sstevel@tonic-gate     if (!ring_empty(ring))
3607c478bd9Sstevel@tonic-gate 	ring->clearto = ring->supply;
3617c478bd9Sstevel@tonic-gate     else
3627c478bd9Sstevel@tonic-gate 	ring->clearto = 0;
3637c478bd9Sstevel@tonic-gate }
364