]> andersk Git - gssapi-openssh.git/blob - openssh/openbsd-compat/vis.c
Initial revision
[gssapi-openssh.git] / openssh / openbsd-compat / vis.c
1 /*-
2  * Copyright (c) 1989, 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.
32  */
33 #include "config.h"
34 #if !defined(HAVE_STRNVIS)
35
36 #if defined(LIBC_SCCS) && !defined(lint)
37 static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $";
38 #endif /* LIBC_SCCS and not lint */
39
40 #include <ctype.h>
41
42 #include "vis.h"
43
44 #define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
45 #define isvisible(c)    (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \
46                                 isgraph((u_char)(c))) ||                     \
47                                 ((flag & VIS_SP) == 0 && (c) == ' ') ||      \
48                                 ((flag & VIS_TAB) == 0 && (c) == '\t') ||    \
49                                 ((flag & VIS_NL) == 0 && (c) == '\n') ||     \
50                                 ((flag & VIS_SAFE) &&                        \
51                                 ((c) == '\b' || (c) == '\007' || (c) == '\r')))
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         register char *dst;
173         register const char *src;
174         size_t siz;
175         int flag;
176 {
177         register char c;
178         char *start, *end;
179
180         for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
181                 if (isvisible(c)) {
182                         *dst++ = c;
183                         if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
184                                 /* need space for the extra '\\' */
185                                 if (dst < end)
186                                         *dst++ = '\\';
187                                 else {
188                                         dst--;
189                                         break;
190                                 }
191                         }
192                         src++;
193                 } else {
194                         /* vis(3) requires up to 4 chars */
195                         if (dst + 3 < end)
196                                 dst = vis(dst, c, flag, *++src);
197                         else
198                                 break;
199                 }
200         }
201         *dst = '\0';
202         if (dst >= end) {
203                 char tbuf[5];
204
205                 /* adjust return value for truncation */
206                 while ((c = *src))
207                         dst += vis(tbuf, c, flag, *++src) - tbuf;
208         }
209         return (dst - start);
210 }
211
212 int
213 strvisx(dst, src, len, flag)
214         register char *dst;
215         register const char *src;
216         register size_t len;
217         int flag;
218 {
219         register char c;
220         char *start;
221
222         for (start = dst; len > 1; len--) {
223                 c = *src;
224                 dst = vis(dst, c, flag, *++src);
225         }
226         if (len)
227                 dst = vis(dst, *src, flag, '\0');
228         *dst = '\0';
229         return (dst - start);
230 }
231
232 #endif
This page took 0.059835 seconds and 5 git commands to generate.