Import OpenSSH-5.1p1.
[dragonfly.git] / crypto / openssh-3.8.1p1 / openbsd-compat / vis.c
1 /* OPENBSD ORIGINAL: lib/libc/gen/vis.c */
2
3 /*-
4  * Copyright (c) 1989, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 #include "includes.h"
32 #if !defined(HAVE_STRNVIS)
33
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char rcsid[] = "$OpenBSD: vis.c,v 1.12 2003/06/02 20:18:35 millert Exp $";
36 #endif /* LIBC_SCCS and not lint */
37
38 #include <ctype.h>
39 #include <string.h>
40
41 #include "vis.h"
42
43 #define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
44 #define isvisible(c)    (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \
45                                 isgraph((u_char)(c))) ||                     \
46                                 ((flag & VIS_SP) == 0 && (c) == ' ') ||      \
47                                 ((flag & VIS_TAB) == 0 && (c) == '\t') ||    \
48                                 ((flag & VIS_NL) == 0 && (c) == '\n') ||     \
49                                 ((flag & VIS_SAFE) && ((c) == '\b' ||        \
50                                 (c) == '\007' || (c) == '\r' ||              \
51                                 isgraph((u_char)(c)))))
52
53 /*
54  * vis - visually encode characters
55  */
56 char *
57 vis(dst, c, flag, nextc)
58         register char *dst;
59         int c, nextc;
60         register int flag;
61 {
62         if (isvisible(c)) {
63                 *dst++ = c;
64                 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
65                         *dst++ = '\\';
66                 *dst = '\0';
67                 return (dst);
68         }
69
70         if (flag & VIS_CSTYLE) {
71                 switch(c) {
72                 case '\n':
73                         *dst++ = '\\';
74                         *dst++ = 'n';
75                         goto done;
76                 case '\r':
77                         *dst++ = '\\';
78                         *dst++ = 'r';
79                         goto done;
80                 case '\b':
81                         *dst++ = '\\';
82                         *dst++ = 'b';
83                         goto done;
84                 case '\a':
85                         *dst++ = '\\';
86                         *dst++ = 'a';
87                         goto done;
88                 case '\v':
89                         *dst++ = '\\';
90                         *dst++ = 'v';
91                         goto done;
92                 case '\t':
93                         *dst++ = '\\';
94                         *dst++ = 't';
95                         goto done;
96                 case '\f':
97                         *dst++ = '\\';
98                         *dst++ = 'f';
99                         goto done;
100                 case ' ':
101                         *dst++ = '\\';
102                         *dst++ = 's';
103                         goto done;
104                 case '\0':
105                         *dst++ = '\\';
106                         *dst++ = '0';
107                         if (isoctal(nextc)) {
108                                 *dst++ = '0';
109                                 *dst++ = '0';
110                         }
111                         goto done;
112                 }
113         }
114         if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {        
115                 *dst++ = '\\';
116                 *dst++ = ((u_char)c >> 6 & 07) + '0';
117                 *dst++ = ((u_char)c >> 3 & 07) + '0';
118                 *dst++ = ((u_char)c & 07) + '0';
119                 goto done;
120         }
121         if ((flag & VIS_NOSLASH) == 0)
122                 *dst++ = '\\';
123         if (c & 0200) {
124                 c &= 0177;
125                 *dst++ = 'M';
126         }
127         if (iscntrl(c)) {
128                 *dst++ = '^';
129                 if (c == 0177)
130                         *dst++ = '?';
131                 else
132                         *dst++ = c + '@';
133         } else {
134                 *dst++ = '-';
135                 *dst++ = c;
136         }
137 done:
138         *dst = '\0';
139         return (dst);
140 }
141
142 /*
143  * strvis, strnvis, strvisx - visually encode characters from src into dst
144  *      
145  *      Dst must be 4 times the size of src to account for possible
146  *      expansion.  The length of dst, not including the trailing NULL,
147  *      is returned. 
148  *
149  *      Strnvis will write no more than siz-1 bytes (and will NULL terminate).
150  *      The number of bytes needed to fully encode the string is returned.
151  *
152  *      Strvisx encodes exactly len bytes from src into dst.
153  *      This is useful for encoding a block of data.
154  */
155 int
156 strvis(dst, src, flag)
157         register char *dst;
158         register const char *src;
159         int flag;
160 {
161         register char c;
162         char *start;
163
164         for (start = dst; (c = *src);)
165                 dst = vis(dst, c, flag, *++src);
166         *dst = '\0';
167         return (dst - start);
168 }
169
170 int
171 strnvis(dst, src, siz, flag)
172         char *dst;
173         const char *src;
174         size_t siz;
175         int flag;
176 {
177         char c;
178         char *start, *end;
179         char tbuf[5];
180         int  i;
181
182         i = 0;
183         for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
184                 if (isvisible(c)) {
185                         i = 1;
186                         *dst++ = c;
187                         if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
188                                 /* need space for the extra '\\' */
189                                 if (dst < end)
190                                         *dst++ = '\\';
191                                 else {
192                                         dst--;
193                                         i = 2;
194                                         break;
195                                 }
196                         }
197                         src++;
198                 } else {
199                         i = vis(tbuf, c, flag, *++src) - tbuf;
200                         if (dst + i <= end) {
201                                 memcpy(dst, tbuf, i);
202                                 dst += i;
203                         } else {
204                                 src--;
205                                 break;
206                         }
207                 }
208         }
209         if (siz > 0)
210                 *dst = '\0';
211         if (dst + i > end) {
212                 /* adjust return value for truncation */
213                 while ((c = *src))
214                         dst += vis(tbuf, c, flag, *++src) - tbuf;
215         }
216         return (dst - start);
217 }
218
219 int
220 strvisx(dst, src, len, flag)
221         register char *dst;
222         register const char *src;
223         register size_t len;
224         int flag;
225 {
226         register char c;
227         char *start;
228
229         for (start = dst; len > 1; len--) {
230                 c = *src;
231                 dst = vis(dst, c, flag, *++src);
232         }
233         if (len)
234                 dst = vis(dst, *src, flag, '\0');
235         *dst = '\0';
236         return (dst - start);
237 }
238
239 #endif