1*2c2f96dcSApple OSS Distributions /*
2*2c2f96dcSApple OSS Distributions * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3*2c2f96dcSApple OSS Distributions *
4*2c2f96dcSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*2c2f96dcSApple OSS Distributions *
6*2c2f96dcSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*2c2f96dcSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*2c2f96dcSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*2c2f96dcSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*2c2f96dcSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*2c2f96dcSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*2c2f96dcSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*2c2f96dcSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*2c2f96dcSApple OSS Distributions *
15*2c2f96dcSApple OSS Distributions * Please obtain a copy of the License at
16*2c2f96dcSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*2c2f96dcSApple OSS Distributions *
18*2c2f96dcSApple OSS Distributions * The Original Code and all software distributed under the License are
19*2c2f96dcSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*2c2f96dcSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*2c2f96dcSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*2c2f96dcSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*2c2f96dcSApple OSS Distributions * Please see the License for the specific language governing rights and
24*2c2f96dcSApple OSS Distributions * limitations under the License.
25*2c2f96dcSApple OSS Distributions *
26*2c2f96dcSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*2c2f96dcSApple OSS Distributions */
28*2c2f96dcSApple OSS Distributions /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
29*2c2f96dcSApple OSS Distributions /*
30*2c2f96dcSApple OSS Distributions * Copyright (c) 1993, 1994 Theo de Raadt
31*2c2f96dcSApple OSS Distributions * All rights reserved.
32*2c2f96dcSApple OSS Distributions *
33*2c2f96dcSApple OSS Distributions * Redistribution and use in source and binary forms, with or without
34*2c2f96dcSApple OSS Distributions * modification, are permitted provided that the following conditions
35*2c2f96dcSApple OSS Distributions * are met:
36*2c2f96dcSApple OSS Distributions * 1. Redistributions of source code must retain the above copyright
37*2c2f96dcSApple OSS Distributions * notice unmodified, this list of conditions, and the following
38*2c2f96dcSApple OSS Distributions * disclaimer.
39*2c2f96dcSApple OSS Distributions * 2. Redistributions in binary form must reproduce the above copyright
40*2c2f96dcSApple OSS Distributions * notice, this list of conditions and the following disclaimer in the
41*2c2f96dcSApple OSS Distributions * documentation and/or other materials provided with the distribution.
42*2c2f96dcSApple OSS Distributions *
43*2c2f96dcSApple OSS Distributions * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44*2c2f96dcSApple OSS Distributions * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45*2c2f96dcSApple OSS Distributions * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46*2c2f96dcSApple OSS Distributions * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47*2c2f96dcSApple OSS Distributions * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48*2c2f96dcSApple OSS Distributions * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49*2c2f96dcSApple OSS Distributions * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50*2c2f96dcSApple OSS Distributions * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51*2c2f96dcSApple OSS Distributions * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52*2c2f96dcSApple OSS Distributions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53*2c2f96dcSApple OSS Distributions * SUCH DAMAGE.
54*2c2f96dcSApple OSS Distributions *
55*2c2f96dcSApple OSS Distributions */
56*2c2f96dcSApple OSS Distributions
57*2c2f96dcSApple OSS Distributions /*
58*2c2f96dcSApple OSS Distributions * We use the NetBSD based clist system, it is much more efficient than the
59*2c2f96dcSApple OSS Distributions * old style clist stuff used by free bsd.
60*2c2f96dcSApple OSS Distributions */
61*2c2f96dcSApple OSS Distributions
62*2c2f96dcSApple OSS Distributions #include <sys/param.h>
63*2c2f96dcSApple OSS Distributions #include <sys/systm.h>
64*2c2f96dcSApple OSS Distributions #include <sys/ioctl.h>
65*2c2f96dcSApple OSS Distributions #include <sys/tty.h>
66*2c2f96dcSApple OSS Distributions #include <sys/malloc.h>
67*2c2f96dcSApple OSS Distributions
68*2c2f96dcSApple OSS Distributions
69*2c2f96dcSApple OSS Distributions /*
70*2c2f96dcSApple OSS Distributions * At compile time, choose:
71*2c2f96dcSApple OSS Distributions * There are two ways the TTY_QUOTE bit can be stored. If QBITS is
72*2c2f96dcSApple OSS Distributions * defined we allocate an array of bits -- 1/8th as much memory but
73*2c2f96dcSApple OSS Distributions * setbit(), clrbit(), and isset() take more cpu. If QBITS is
74*2c2f96dcSApple OSS Distributions * undefined, we just use an array of bytes.
75*2c2f96dcSApple OSS Distributions *
76*2c2f96dcSApple OSS Distributions * If TTY_QUOTE functionality isn't required by a line discipline,
77*2c2f96dcSApple OSS Distributions * it can free c_cq and set it to NULL. This speeds things up,
78*2c2f96dcSApple OSS Distributions * and also does not use any extra memory. This is useful for (say)
79*2c2f96dcSApple OSS Distributions * a SLIP line discipline that wants a 32K ring buffer for data
80*2c2f96dcSApple OSS Distributions * but doesn't need quoting.
81*2c2f96dcSApple OSS Distributions */
82*2c2f96dcSApple OSS Distributions #define QBITS
83*2c2f96dcSApple OSS Distributions
84*2c2f96dcSApple OSS Distributions #ifdef QBITS
85*2c2f96dcSApple OSS Distributions #define QMEM(n) ((((n)-1)/NBBY)+1)
86*2c2f96dcSApple OSS Distributions #else
87*2c2f96dcSApple OSS Distributions #define QMEM(n) (n)
88*2c2f96dcSApple OSS Distributions #endif
89*2c2f96dcSApple OSS Distributions
90*2c2f96dcSApple OSS Distributions
91*2c2f96dcSApple OSS Distributions /*
92*2c2f96dcSApple OSS Distributions * Initialize clists.
93*2c2f96dcSApple OSS Distributions */
94*2c2f96dcSApple OSS Distributions void
cinit(void)95*2c2f96dcSApple OSS Distributions cinit(void)
96*2c2f96dcSApple OSS Distributions {
97*2c2f96dcSApple OSS Distributions }
98*2c2f96dcSApple OSS Distributions
99*2c2f96dcSApple OSS Distributions /*
100*2c2f96dcSApple OSS Distributions * Initialize a particular clist. Ok, they are really ring buffers,
101*2c2f96dcSApple OSS Distributions * of the specified length, with/without quoting support.
102*2c2f96dcSApple OSS Distributions */
103*2c2f96dcSApple OSS Distributions int
clalloc(struct clist * clp,int size,int quot)104*2c2f96dcSApple OSS Distributions clalloc(struct clist *clp, int size, int quot)
105*2c2f96dcSApple OSS Distributions {
106*2c2f96dcSApple OSS Distributions clp->c_cs = kalloc_data(size, Z_WAITOK | Z_ZERO);
107*2c2f96dcSApple OSS Distributions if (!clp->c_cs) {
108*2c2f96dcSApple OSS Distributions return -1;
109*2c2f96dcSApple OSS Distributions }
110*2c2f96dcSApple OSS Distributions
111*2c2f96dcSApple OSS Distributions if (quot) {
112*2c2f96dcSApple OSS Distributions clp->c_cq = kalloc_data(QMEM(size), Z_WAITOK | Z_ZERO);
113*2c2f96dcSApple OSS Distributions if (!clp->c_cq) {
114*2c2f96dcSApple OSS Distributions kfree_data(clp->c_cs, size);
115*2c2f96dcSApple OSS Distributions return -1;
116*2c2f96dcSApple OSS Distributions }
117*2c2f96dcSApple OSS Distributions } else {
118*2c2f96dcSApple OSS Distributions clp->c_cq = (u_char *)0;
119*2c2f96dcSApple OSS Distributions }
120*2c2f96dcSApple OSS Distributions
121*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = (u_char *)0;
122*2c2f96dcSApple OSS Distributions clp->c_ce = clp->c_cs + size;
123*2c2f96dcSApple OSS Distributions clp->c_cn = size;
124*2c2f96dcSApple OSS Distributions clp->c_cc = 0;
125*2c2f96dcSApple OSS Distributions return 0;
126*2c2f96dcSApple OSS Distributions }
127*2c2f96dcSApple OSS Distributions
128*2c2f96dcSApple OSS Distributions void
clfree(struct clist * clp)129*2c2f96dcSApple OSS Distributions clfree(struct clist *clp)
130*2c2f96dcSApple OSS Distributions {
131*2c2f96dcSApple OSS Distributions if (clp->c_cs) {
132*2c2f96dcSApple OSS Distributions kfree_data(clp->c_cs, clp->c_cn);
133*2c2f96dcSApple OSS Distributions }
134*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
135*2c2f96dcSApple OSS Distributions kfree_data(clp->c_cq, QMEM(clp->c_cn));
136*2c2f96dcSApple OSS Distributions }
137*2c2f96dcSApple OSS Distributions clp->c_cs = clp->c_cq = (u_char *)0;
138*2c2f96dcSApple OSS Distributions }
139*2c2f96dcSApple OSS Distributions
140*2c2f96dcSApple OSS Distributions
141*2c2f96dcSApple OSS Distributions /*
142*2c2f96dcSApple OSS Distributions * Get a character from a clist.
143*2c2f96dcSApple OSS Distributions */
144*2c2f96dcSApple OSS Distributions int
getc(struct clist * clp)145*2c2f96dcSApple OSS Distributions getc(struct clist *clp)
146*2c2f96dcSApple OSS Distributions {
147*2c2f96dcSApple OSS Distributions int c = -1;
148*2c2f96dcSApple OSS Distributions
149*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
150*2c2f96dcSApple OSS Distributions goto out;
151*2c2f96dcSApple OSS Distributions }
152*2c2f96dcSApple OSS Distributions
153*2c2f96dcSApple OSS Distributions c = *clp->c_cf & 0xff;
154*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
155*2c2f96dcSApple OSS Distributions #ifdef QBITS
156*2c2f96dcSApple OSS Distributions if (isset(clp->c_cq, clp->c_cf - clp->c_cs)) {
157*2c2f96dcSApple OSS Distributions c |= TTY_QUOTE;
158*2c2f96dcSApple OSS Distributions }
159*2c2f96dcSApple OSS Distributions #else
160*2c2f96dcSApple OSS Distributions if (*(clp->c_cf - clp->c_cs + clp->c_cq)) {
161*2c2f96dcSApple OSS Distributions c |= TTY_QUOTE;
162*2c2f96dcSApple OSS Distributions }
163*2c2f96dcSApple OSS Distributions #endif
164*2c2f96dcSApple OSS Distributions }
165*2c2f96dcSApple OSS Distributions if (++clp->c_cf == clp->c_ce) {
166*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cs;
167*2c2f96dcSApple OSS Distributions }
168*2c2f96dcSApple OSS Distributions if (--clp->c_cc == 0) {
169*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = (u_char *)0;
170*2c2f96dcSApple OSS Distributions }
171*2c2f96dcSApple OSS Distributions out:
172*2c2f96dcSApple OSS Distributions return c;
173*2c2f96dcSApple OSS Distributions }
174*2c2f96dcSApple OSS Distributions
175*2c2f96dcSApple OSS Distributions /*
176*2c2f96dcSApple OSS Distributions * Copy clist to buffer.
177*2c2f96dcSApple OSS Distributions * Return number of bytes moved.
178*2c2f96dcSApple OSS Distributions */
179*2c2f96dcSApple OSS Distributions int
q_to_b(struct clist * clp,u_char * cp,int count)180*2c2f96dcSApple OSS Distributions q_to_b(struct clist *clp, u_char *cp, int count)
181*2c2f96dcSApple OSS Distributions {
182*2c2f96dcSApple OSS Distributions size_t cc;
183*2c2f96dcSApple OSS Distributions u_char *p = cp;
184*2c2f96dcSApple OSS Distributions
185*2c2f96dcSApple OSS Distributions /* optimize this while loop */
186*2c2f96dcSApple OSS Distributions while (count > 0 && clp->c_cc > 0) {
187*2c2f96dcSApple OSS Distributions cc = clp->c_cl - clp->c_cf;
188*2c2f96dcSApple OSS Distributions if (clp->c_cf >= clp->c_cl) {
189*2c2f96dcSApple OSS Distributions cc = clp->c_ce - clp->c_cf;
190*2c2f96dcSApple OSS Distributions }
191*2c2f96dcSApple OSS Distributions if (cc > INT_MAX || (int)cc > count) {
192*2c2f96dcSApple OSS Distributions cc = count;
193*2c2f96dcSApple OSS Distributions }
194*2c2f96dcSApple OSS Distributions bcopy(clp->c_cf, p, cc);
195*2c2f96dcSApple OSS Distributions count -= cc;
196*2c2f96dcSApple OSS Distributions p += cc;
197*2c2f96dcSApple OSS Distributions clp->c_cc -= cc;
198*2c2f96dcSApple OSS Distributions clp->c_cf += cc;
199*2c2f96dcSApple OSS Distributions if (clp->c_cf == clp->c_ce) {
200*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cs;
201*2c2f96dcSApple OSS Distributions }
202*2c2f96dcSApple OSS Distributions }
203*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
204*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = (u_char *)0;
205*2c2f96dcSApple OSS Distributions }
206*2c2f96dcSApple OSS Distributions return (int)MIN(INT32_MAX, p - cp);
207*2c2f96dcSApple OSS Distributions }
208*2c2f96dcSApple OSS Distributions
209*2c2f96dcSApple OSS Distributions /*
210*2c2f96dcSApple OSS Distributions * Return count of contiguous characters in clist.
211*2c2f96dcSApple OSS Distributions * Stop counting if flag&character is non-null.
212*2c2f96dcSApple OSS Distributions */
213*2c2f96dcSApple OSS Distributions int
ndqb(struct clist * clp,int flag)214*2c2f96dcSApple OSS Distributions ndqb(struct clist *clp, int flag)
215*2c2f96dcSApple OSS Distributions {
216*2c2f96dcSApple OSS Distributions size_t count = 0;
217*2c2f96dcSApple OSS Distributions size_t i;
218*2c2f96dcSApple OSS Distributions int cc;
219*2c2f96dcSApple OSS Distributions
220*2c2f96dcSApple OSS Distributions if ((cc = clp->c_cc) == 0) {
221*2c2f96dcSApple OSS Distributions goto out;
222*2c2f96dcSApple OSS Distributions }
223*2c2f96dcSApple OSS Distributions
224*2c2f96dcSApple OSS Distributions if (flag == 0) {
225*2c2f96dcSApple OSS Distributions count = clp->c_cl - clp->c_cf;
226*2c2f96dcSApple OSS Distributions if (count <= 0) {
227*2c2f96dcSApple OSS Distributions count = clp->c_ce - clp->c_cf;
228*2c2f96dcSApple OSS Distributions }
229*2c2f96dcSApple OSS Distributions goto out;
230*2c2f96dcSApple OSS Distributions }
231*2c2f96dcSApple OSS Distributions
232*2c2f96dcSApple OSS Distributions i = clp->c_cf - clp->c_cs;
233*2c2f96dcSApple OSS Distributions if (i > INT_MAX) {
234*2c2f96dcSApple OSS Distributions return 0;
235*2c2f96dcSApple OSS Distributions }
236*2c2f96dcSApple OSS Distributions if (flag & TTY_QUOTE) {
237*2c2f96dcSApple OSS Distributions while (cc-- > 0 && !(clp->c_cs[i++] & (flag & ~TTY_QUOTE) ||
238*2c2f96dcSApple OSS Distributions isset(clp->c_cq, i))) {
239*2c2f96dcSApple OSS Distributions count++;
240*2c2f96dcSApple OSS Distributions if ((int)i == clp->c_cn) {
241*2c2f96dcSApple OSS Distributions break;
242*2c2f96dcSApple OSS Distributions }
243*2c2f96dcSApple OSS Distributions }
244*2c2f96dcSApple OSS Distributions } else {
245*2c2f96dcSApple OSS Distributions while (cc-- > 0 && !(clp->c_cs[i++] & flag)) {
246*2c2f96dcSApple OSS Distributions count++;
247*2c2f96dcSApple OSS Distributions if ((int)i == clp->c_cn) {
248*2c2f96dcSApple OSS Distributions break;
249*2c2f96dcSApple OSS Distributions }
250*2c2f96dcSApple OSS Distributions }
251*2c2f96dcSApple OSS Distributions }
252*2c2f96dcSApple OSS Distributions out:
253*2c2f96dcSApple OSS Distributions if (count > INT_MAX) {
254*2c2f96dcSApple OSS Distributions return 0;
255*2c2f96dcSApple OSS Distributions }
256*2c2f96dcSApple OSS Distributions return (int)count;
257*2c2f96dcSApple OSS Distributions }
258*2c2f96dcSApple OSS Distributions
259*2c2f96dcSApple OSS Distributions /*
260*2c2f96dcSApple OSS Distributions * Flush count bytes from clist.
261*2c2f96dcSApple OSS Distributions */
262*2c2f96dcSApple OSS Distributions void
ndflush(struct clist * clp,int count)263*2c2f96dcSApple OSS Distributions ndflush(struct clist *clp, int count)
264*2c2f96dcSApple OSS Distributions {
265*2c2f96dcSApple OSS Distributions size_t cc;
266*2c2f96dcSApple OSS Distributions
267*2c2f96dcSApple OSS Distributions if (count == clp->c_cc) {
268*2c2f96dcSApple OSS Distributions clp->c_cc = 0;
269*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = (u_char *)0;
270*2c2f96dcSApple OSS Distributions return;
271*2c2f96dcSApple OSS Distributions }
272*2c2f96dcSApple OSS Distributions /* optimize this while loop */
273*2c2f96dcSApple OSS Distributions while (count > 0 && clp->c_cc > 0) {
274*2c2f96dcSApple OSS Distributions cc = clp->c_cl - clp->c_cf;
275*2c2f96dcSApple OSS Distributions if (clp->c_cf >= clp->c_cl) {
276*2c2f96dcSApple OSS Distributions cc = clp->c_ce - clp->c_cf;
277*2c2f96dcSApple OSS Distributions }
278*2c2f96dcSApple OSS Distributions if (cc > INT_MAX || (int)cc > count) {
279*2c2f96dcSApple OSS Distributions cc = count;
280*2c2f96dcSApple OSS Distributions }
281*2c2f96dcSApple OSS Distributions count -= cc;
282*2c2f96dcSApple OSS Distributions clp->c_cc -= cc;
283*2c2f96dcSApple OSS Distributions clp->c_cf += cc;
284*2c2f96dcSApple OSS Distributions if (clp->c_cf == clp->c_ce) {
285*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cs;
286*2c2f96dcSApple OSS Distributions }
287*2c2f96dcSApple OSS Distributions }
288*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
289*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = (u_char *)0;
290*2c2f96dcSApple OSS Distributions }
291*2c2f96dcSApple OSS Distributions }
292*2c2f96dcSApple OSS Distributions
293*2c2f96dcSApple OSS Distributions /*
294*2c2f96dcSApple OSS Distributions * Put a character into the output queue.
295*2c2f96dcSApple OSS Distributions */
296*2c2f96dcSApple OSS Distributions int
putc(int c,struct clist * clp)297*2c2f96dcSApple OSS Distributions putc(int c, struct clist *clp)
298*2c2f96dcSApple OSS Distributions {
299*2c2f96dcSApple OSS Distributions size_t i;
300*2c2f96dcSApple OSS Distributions
301*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
302*2c2f96dcSApple OSS Distributions if (!clp->c_cs) {
303*2c2f96dcSApple OSS Distributions #if DIAGNOSTIC
304*2c2f96dcSApple OSS Distributions //printf("putc: required clalloc\n");
305*2c2f96dcSApple OSS Distributions #endif
306*2c2f96dcSApple OSS Distributions if (clalloc(clp, 1024, 1)) {
307*2c2f96dcSApple OSS Distributions return -1;
308*2c2f96dcSApple OSS Distributions }
309*2c2f96dcSApple OSS Distributions }
310*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = clp->c_cs;
311*2c2f96dcSApple OSS Distributions }
312*2c2f96dcSApple OSS Distributions
313*2c2f96dcSApple OSS Distributions if (clp->c_cc == clp->c_cn) {
314*2c2f96dcSApple OSS Distributions return -1;
315*2c2f96dcSApple OSS Distributions }
316*2c2f96dcSApple OSS Distributions
317*2c2f96dcSApple OSS Distributions *clp->c_cl = c & 0xff;
318*2c2f96dcSApple OSS Distributions i = clp->c_cl - clp->c_cs;
319*2c2f96dcSApple OSS Distributions if (i > INT_MAX) {
320*2c2f96dcSApple OSS Distributions return -1;
321*2c2f96dcSApple OSS Distributions }
322*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
323*2c2f96dcSApple OSS Distributions #ifdef QBITS
324*2c2f96dcSApple OSS Distributions if (c & TTY_QUOTE) {
325*2c2f96dcSApple OSS Distributions setbit(clp->c_cq, i);
326*2c2f96dcSApple OSS Distributions } else {
327*2c2f96dcSApple OSS Distributions clrbit(clp->c_cq, i);
328*2c2f96dcSApple OSS Distributions }
329*2c2f96dcSApple OSS Distributions #else
330*2c2f96dcSApple OSS Distributions q = clp->c_cq + i;
331*2c2f96dcSApple OSS Distributions *q = (c & TTY_QUOTE) ? 1 : 0;
332*2c2f96dcSApple OSS Distributions #endif
333*2c2f96dcSApple OSS Distributions }
334*2c2f96dcSApple OSS Distributions clp->c_cc++;
335*2c2f96dcSApple OSS Distributions clp->c_cl++;
336*2c2f96dcSApple OSS Distributions if (clp->c_cl == clp->c_ce) {
337*2c2f96dcSApple OSS Distributions clp->c_cl = clp->c_cs;
338*2c2f96dcSApple OSS Distributions }
339*2c2f96dcSApple OSS Distributions return 0;
340*2c2f96dcSApple OSS Distributions }
341*2c2f96dcSApple OSS Distributions
342*2c2f96dcSApple OSS Distributions #ifdef QBITS
343*2c2f96dcSApple OSS Distributions /*
344*2c2f96dcSApple OSS Distributions * optimized version of
345*2c2f96dcSApple OSS Distributions *
346*2c2f96dcSApple OSS Distributions * for (i = 0; i < len; i++)
347*2c2f96dcSApple OSS Distributions * clrbit(cp, off + len);
348*2c2f96dcSApple OSS Distributions */
349*2c2f96dcSApple OSS Distributions void
clrbits(u_char * cp,int off,int len)350*2c2f96dcSApple OSS Distributions clrbits(u_char *cp, int off, int len)
351*2c2f96dcSApple OSS Distributions {
352*2c2f96dcSApple OSS Distributions int sby, sbi, eby, ebi;
353*2c2f96dcSApple OSS Distributions int i;
354*2c2f96dcSApple OSS Distributions u_char mask;
355*2c2f96dcSApple OSS Distributions
356*2c2f96dcSApple OSS Distributions if (len == 1) {
357*2c2f96dcSApple OSS Distributions clrbit(cp, off);
358*2c2f96dcSApple OSS Distributions return;
359*2c2f96dcSApple OSS Distributions }
360*2c2f96dcSApple OSS Distributions
361*2c2f96dcSApple OSS Distributions sby = off / NBBY;
362*2c2f96dcSApple OSS Distributions sbi = off % NBBY;
363*2c2f96dcSApple OSS Distributions eby = (off + len) / NBBY;
364*2c2f96dcSApple OSS Distributions ebi = (off + len) % NBBY;
365*2c2f96dcSApple OSS Distributions if (sby == eby) {
366*2c2f96dcSApple OSS Distributions mask = (u_char)(((1 << (ebi - sbi)) - 1) << sbi);
367*2c2f96dcSApple OSS Distributions cp[sby] &= ~mask;
368*2c2f96dcSApple OSS Distributions } else {
369*2c2f96dcSApple OSS Distributions mask = (u_char)((1 << sbi) - 1);
370*2c2f96dcSApple OSS Distributions cp[sby++] &= mask;
371*2c2f96dcSApple OSS Distributions
372*2c2f96dcSApple OSS Distributions mask = (u_char)((1 << ebi) - 1);
373*2c2f96dcSApple OSS Distributions /* handle remainder bits, if any, for a non-0 ebi value */
374*2c2f96dcSApple OSS Distributions if (mask) {
375*2c2f96dcSApple OSS Distributions cp[eby] &= ~mask;
376*2c2f96dcSApple OSS Distributions }
377*2c2f96dcSApple OSS Distributions
378*2c2f96dcSApple OSS Distributions for (i = sby; i < eby; i++) {
379*2c2f96dcSApple OSS Distributions cp[i] = 0x00;
380*2c2f96dcSApple OSS Distributions }
381*2c2f96dcSApple OSS Distributions }
382*2c2f96dcSApple OSS Distributions }
383*2c2f96dcSApple OSS Distributions #endif
384*2c2f96dcSApple OSS Distributions
385*2c2f96dcSApple OSS Distributions /*
386*2c2f96dcSApple OSS Distributions * Copy buffer to clist.
387*2c2f96dcSApple OSS Distributions * Return number of bytes not transfered.
388*2c2f96dcSApple OSS Distributions */
389*2c2f96dcSApple OSS Distributions int
b_to_q(const u_char * cp,int count,struct clist * clp)390*2c2f96dcSApple OSS Distributions b_to_q(const u_char *cp, int count, struct clist *clp)
391*2c2f96dcSApple OSS Distributions {
392*2c2f96dcSApple OSS Distributions size_t cc;
393*2c2f96dcSApple OSS Distributions const u_char *p = cp;
394*2c2f96dcSApple OSS Distributions
395*2c2f96dcSApple OSS Distributions if (count <= 0) {
396*2c2f96dcSApple OSS Distributions return 0;
397*2c2f96dcSApple OSS Distributions }
398*2c2f96dcSApple OSS Distributions
399*2c2f96dcSApple OSS Distributions
400*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
401*2c2f96dcSApple OSS Distributions if (!clp->c_cs) {
402*2c2f96dcSApple OSS Distributions #if DIAGNOSTIC
403*2c2f96dcSApple OSS Distributions printf("b_to_q: required clalloc\n");
404*2c2f96dcSApple OSS Distributions #endif
405*2c2f96dcSApple OSS Distributions if (clalloc(clp, 1024, 1)) {
406*2c2f96dcSApple OSS Distributions goto out;
407*2c2f96dcSApple OSS Distributions }
408*2c2f96dcSApple OSS Distributions }
409*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = clp->c_cs;
410*2c2f96dcSApple OSS Distributions }
411*2c2f96dcSApple OSS Distributions
412*2c2f96dcSApple OSS Distributions if (clp->c_cc == clp->c_cn) {
413*2c2f96dcSApple OSS Distributions goto out;
414*2c2f96dcSApple OSS Distributions }
415*2c2f96dcSApple OSS Distributions
416*2c2f96dcSApple OSS Distributions /* optimize this while loop */
417*2c2f96dcSApple OSS Distributions while (count > 0 && clp->c_cc < clp->c_cn) {
418*2c2f96dcSApple OSS Distributions cc = clp->c_ce - clp->c_cl;
419*2c2f96dcSApple OSS Distributions if (clp->c_cf > clp->c_cl) {
420*2c2f96dcSApple OSS Distributions cc = clp->c_cf - clp->c_cl;
421*2c2f96dcSApple OSS Distributions }
422*2c2f96dcSApple OSS Distributions if (cc > INT_MAX || (int)cc > count) {
423*2c2f96dcSApple OSS Distributions cc = count;
424*2c2f96dcSApple OSS Distributions }
425*2c2f96dcSApple OSS Distributions bcopy(p, clp->c_cl, cc);
426*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
427*2c2f96dcSApple OSS Distributions #ifdef QBITS
428*2c2f96dcSApple OSS Distributions if (clp->c_cl - clp->c_cs > INT_MAX || cc > INT_MAX) {
429*2c2f96dcSApple OSS Distributions count = 0;
430*2c2f96dcSApple OSS Distributions goto out;
431*2c2f96dcSApple OSS Distributions }
432*2c2f96dcSApple OSS Distributions clrbits(clp->c_cq, (int)(clp->c_cl - clp->c_cs), (int)cc);
433*2c2f96dcSApple OSS Distributions #else
434*2c2f96dcSApple OSS Distributions bzero(clp->c_cl - clp->c_cs + clp->c_cq, cc);
435*2c2f96dcSApple OSS Distributions #endif
436*2c2f96dcSApple OSS Distributions }
437*2c2f96dcSApple OSS Distributions p += cc;
438*2c2f96dcSApple OSS Distributions count -= cc;
439*2c2f96dcSApple OSS Distributions clp->c_cc += cc;
440*2c2f96dcSApple OSS Distributions clp->c_cl += cc;
441*2c2f96dcSApple OSS Distributions if (clp->c_cl == clp->c_ce) {
442*2c2f96dcSApple OSS Distributions clp->c_cl = clp->c_cs;
443*2c2f96dcSApple OSS Distributions }
444*2c2f96dcSApple OSS Distributions }
445*2c2f96dcSApple OSS Distributions out:
446*2c2f96dcSApple OSS Distributions return count;
447*2c2f96dcSApple OSS Distributions }
448*2c2f96dcSApple OSS Distributions
449*2c2f96dcSApple OSS Distributions static int cc;
450*2c2f96dcSApple OSS Distributions
451*2c2f96dcSApple OSS Distributions /*
452*2c2f96dcSApple OSS Distributions * Given a non-NULL pointer into the clist return the pointer
453*2c2f96dcSApple OSS Distributions * to the next character in the list or return NULL if no more chars.
454*2c2f96dcSApple OSS Distributions *
455*2c2f96dcSApple OSS Distributions * Callers must not allow getc's to happen between firstc's and getc's
456*2c2f96dcSApple OSS Distributions * so that the pointer becomes invalid. Note that interrupts are NOT
457*2c2f96dcSApple OSS Distributions * masked.
458*2c2f96dcSApple OSS Distributions */
459*2c2f96dcSApple OSS Distributions u_char *
nextc(struct clist * clp,u_char * cp,int * c)460*2c2f96dcSApple OSS Distributions nextc(struct clist *clp, u_char *cp, int *c)
461*2c2f96dcSApple OSS Distributions {
462*2c2f96dcSApple OSS Distributions if (clp->c_cf == cp) {
463*2c2f96dcSApple OSS Distributions /*
464*2c2f96dcSApple OSS Distributions * First time initialization.
465*2c2f96dcSApple OSS Distributions */
466*2c2f96dcSApple OSS Distributions cc = clp->c_cc;
467*2c2f96dcSApple OSS Distributions }
468*2c2f96dcSApple OSS Distributions if (cc == 0 || cp == NULL) {
469*2c2f96dcSApple OSS Distributions return NULL;
470*2c2f96dcSApple OSS Distributions }
471*2c2f96dcSApple OSS Distributions if (--cc == 0) {
472*2c2f96dcSApple OSS Distributions return NULL;
473*2c2f96dcSApple OSS Distributions }
474*2c2f96dcSApple OSS Distributions if (++cp == clp->c_ce) {
475*2c2f96dcSApple OSS Distributions cp = clp->c_cs;
476*2c2f96dcSApple OSS Distributions }
477*2c2f96dcSApple OSS Distributions *c = *cp & 0xff;
478*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
479*2c2f96dcSApple OSS Distributions #ifdef QBITS
480*2c2f96dcSApple OSS Distributions if (isset(clp->c_cq, cp - clp->c_cs)) {
481*2c2f96dcSApple OSS Distributions *c |= TTY_QUOTE;
482*2c2f96dcSApple OSS Distributions }
483*2c2f96dcSApple OSS Distributions #else
484*2c2f96dcSApple OSS Distributions if (*(clp->c_cf - clp->c_cs + clp->c_cq)) {
485*2c2f96dcSApple OSS Distributions *c |= TTY_QUOTE;
486*2c2f96dcSApple OSS Distributions }
487*2c2f96dcSApple OSS Distributions #endif
488*2c2f96dcSApple OSS Distributions }
489*2c2f96dcSApple OSS Distributions return cp;
490*2c2f96dcSApple OSS Distributions }
491*2c2f96dcSApple OSS Distributions
492*2c2f96dcSApple OSS Distributions /*
493*2c2f96dcSApple OSS Distributions * Given a non-NULL pointer into the clist return the pointer
494*2c2f96dcSApple OSS Distributions * to the first character in the list or return NULL if no more chars.
495*2c2f96dcSApple OSS Distributions *
496*2c2f96dcSApple OSS Distributions * Callers must not allow getc's to happen between firstc's and getc's
497*2c2f96dcSApple OSS Distributions * so that the pointer becomes invalid. Note that interrupts are NOT
498*2c2f96dcSApple OSS Distributions * masked.
499*2c2f96dcSApple OSS Distributions *
500*2c2f96dcSApple OSS Distributions * *c is set to the NEXT character
501*2c2f96dcSApple OSS Distributions */
502*2c2f96dcSApple OSS Distributions u_char *
firstc(struct clist * clp,int * c)503*2c2f96dcSApple OSS Distributions firstc(struct clist *clp, int *c)
504*2c2f96dcSApple OSS Distributions {
505*2c2f96dcSApple OSS Distributions u_char *cp;
506*2c2f96dcSApple OSS Distributions
507*2c2f96dcSApple OSS Distributions cc = clp->c_cc;
508*2c2f96dcSApple OSS Distributions if (cc == 0) {
509*2c2f96dcSApple OSS Distributions return NULL;
510*2c2f96dcSApple OSS Distributions }
511*2c2f96dcSApple OSS Distributions cp = clp->c_cf;
512*2c2f96dcSApple OSS Distributions *c = *cp & 0xff;
513*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
514*2c2f96dcSApple OSS Distributions #ifdef QBITS
515*2c2f96dcSApple OSS Distributions if (isset(clp->c_cq, cp - clp->c_cs)) {
516*2c2f96dcSApple OSS Distributions *c |= TTY_QUOTE;
517*2c2f96dcSApple OSS Distributions }
518*2c2f96dcSApple OSS Distributions #else
519*2c2f96dcSApple OSS Distributions if (*(cp - clp->c_cs + clp->c_cq)) {
520*2c2f96dcSApple OSS Distributions *c |= TTY_QUOTE;
521*2c2f96dcSApple OSS Distributions }
522*2c2f96dcSApple OSS Distributions #endif
523*2c2f96dcSApple OSS Distributions }
524*2c2f96dcSApple OSS Distributions return clp->c_cf;
525*2c2f96dcSApple OSS Distributions }
526*2c2f96dcSApple OSS Distributions
527*2c2f96dcSApple OSS Distributions /*
528*2c2f96dcSApple OSS Distributions * Remove the last character in the clist and return it.
529*2c2f96dcSApple OSS Distributions */
530*2c2f96dcSApple OSS Distributions int
unputc(struct clist * clp)531*2c2f96dcSApple OSS Distributions unputc(struct clist *clp)
532*2c2f96dcSApple OSS Distributions {
533*2c2f96dcSApple OSS Distributions unsigned int c = -1;
534*2c2f96dcSApple OSS Distributions
535*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
536*2c2f96dcSApple OSS Distributions goto out;
537*2c2f96dcSApple OSS Distributions }
538*2c2f96dcSApple OSS Distributions
539*2c2f96dcSApple OSS Distributions if (clp->c_cl == clp->c_cs) {
540*2c2f96dcSApple OSS Distributions clp->c_cl = clp->c_ce - 1;
541*2c2f96dcSApple OSS Distributions } else {
542*2c2f96dcSApple OSS Distributions --clp->c_cl;
543*2c2f96dcSApple OSS Distributions }
544*2c2f96dcSApple OSS Distributions clp->c_cc--;
545*2c2f96dcSApple OSS Distributions
546*2c2f96dcSApple OSS Distributions c = *clp->c_cl & 0xff;
547*2c2f96dcSApple OSS Distributions if (clp->c_cq) {
548*2c2f96dcSApple OSS Distributions #ifdef QBITS
549*2c2f96dcSApple OSS Distributions if (isset(clp->c_cq, clp->c_cl - clp->c_cs)) {
550*2c2f96dcSApple OSS Distributions c |= TTY_QUOTE;
551*2c2f96dcSApple OSS Distributions }
552*2c2f96dcSApple OSS Distributions #else
553*2c2f96dcSApple OSS Distributions if (*(clp->c_cf - clp->c_cs + clp->c_cq)) {
554*2c2f96dcSApple OSS Distributions c |= TTY_QUOTE;
555*2c2f96dcSApple OSS Distributions }
556*2c2f96dcSApple OSS Distributions #endif
557*2c2f96dcSApple OSS Distributions }
558*2c2f96dcSApple OSS Distributions if (clp->c_cc == 0) {
559*2c2f96dcSApple OSS Distributions clp->c_cf = clp->c_cl = (u_char *)0;
560*2c2f96dcSApple OSS Distributions }
561*2c2f96dcSApple OSS Distributions out:
562*2c2f96dcSApple OSS Distributions return c;
563*2c2f96dcSApple OSS Distributions }
564*2c2f96dcSApple OSS Distributions
565*2c2f96dcSApple OSS Distributions /*
566*2c2f96dcSApple OSS Distributions * Put the chars in the from queue on the end of the to queue.
567*2c2f96dcSApple OSS Distributions */
568*2c2f96dcSApple OSS Distributions void
catq(struct clist * from,struct clist * to)569*2c2f96dcSApple OSS Distributions catq(struct clist *from, struct clist *to)
570*2c2f96dcSApple OSS Distributions {
571*2c2f96dcSApple OSS Distributions int c;
572*2c2f96dcSApple OSS Distributions
573*2c2f96dcSApple OSS Distributions while ((c = getc(from)) != -1) {
574*2c2f96dcSApple OSS Distributions putc(c, to);
575*2c2f96dcSApple OSS Distributions }
576*2c2f96dcSApple OSS Distributions }
577