]> andersk Git - openssh.git/blob - openbsd-compat/vis.c
- (djm) Big KNF on openbsd-compat/
[openssh.git] / 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.11 2003/05/14 05:16:43 pjanzen Exp $";
38 #endif /* LIBC_SCCS and not lint */
39
40 #include <ctype.h>
41 #include <string.h>
42
43 #include "vis.h"
44
45 #define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
46 #define isvisible(c)    (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \
47                                 isgraph((u_char)(c))) ||                     \
48                                 ((flag & VIS_SP) == 0 && (c) == ' ') ||      \
49                                 ((flag & VIS_TAB) == 0 && (c) == '\t') ||    \
50                                 ((flag & VIS_NL) == 0 && (c) == '\n') ||     \
51                                 ((flag & VIS_SAFE) && ((c) == '\b' ||        \
52                                 (c) == '\007' || (c) == '\r' ||              \
53                                 isgraph((u_char)(c)))))
54
55 /*
56  * vis - visually encode characters
57  */
58 char *
59 vis(dst, c, flag, nextc)
60         register char *dst;
61         int c, nextc;
62         register int flag;
63 {
64         if (isvisible(c)) {
65                 *dst++ = c;
66                 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
67                         *dst++ = '\\';
68                 *dst = '\0';
69                 return (dst);
70         }
71
72         if (flag & VIS_CSTYLE) {
73                 switch(c) {
74                 case '\n':
75                         *dst++ = '\\';
76                         *dst++ = 'n';
77                         goto done;
78                 case '\r':
79                         *dst++ = '\\';
80                         *dst++ = 'r';
81                         goto done;
82                 case '\b':
83                         *dst++ = '\\';
84                         *dst++ = 'b';
85                         goto done;
86                 case '\a':
87                         *dst++ = '\\';
88                         *dst++ = 'a';
89                         goto done;
90                 case '\v':
91                         *dst++ = '\\';
92                         *dst++ = 'v';
93                         goto done;
94                 case '\t':
95                         *dst++ = '\\';
96                         *dst++ = 't';
97                         goto done;
98                 case '\f':
99                         *dst++ = '\\';
100                         *dst++ = 'f';
101                         goto done;
102                 case ' ':
103                         *dst++ = '\\';
104                         *dst++ = 's';
105                         goto done;
106                 case '\0':
107                         *dst++ = '\\';
108                         *dst++ = '0';
109                         if (isoctal(nextc)) {
110                                 *dst++ = '0';
111                                 *dst++ = '0';
112                         }
113                         goto done;
114                 }
115         }
116         if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {        
117                 *dst++ = '\\';
118                 *dst++ = ((u_char)c >> 6 & 07) + '0';
119                 *dst++ = ((u_char)c >> 3 & 07) + '0';
120                 *dst++ = ((u_char)c & 07) + '0';
121                 goto done;
122         }
123         if ((flag & VIS_NOSLASH) == 0)
124                 *dst++ = '\\';
125         if (c & 0200) {
126                 c &= 0177;
127                 *dst++ = 'M';
128         }
129         if (iscntrl(c)) {
130                 *dst++ = '^';
131                 if (c == 0177)
132                         *dst++ = '?';
133                 else
134                         *dst++ = c + '@';
135         } else {
136                 *dst++ = '-';
137                 *dst++ = c;
138         }
139 done:
140         *dst = '\0';
141         return (dst);
142 }
143
144 /*
145  * strvis, strnvis, strvisx - visually encode characters from src into dst
146  *      
147  *      Dst must be 4 times the size of src to account for possible
148  *      expansion.  The length of dst, not including the trailing NULL,
149  *      is returned. 
150  *
151  *      Strnvis will write no more than siz-1 bytes (and will NULL terminate).
152  *      The number of bytes needed to fully encode the string is returned.
153  *
154  *      Strvisx encodes exactly len bytes from src into dst.
155  *      This is useful for encoding a block of data.
156  */
157 int
158 strvis(dst, src, flag)
159         register char *dst;
160         register const char *src;
161         int flag;
162 {
163         register char c;
164         char *start;
165
166         for (start = dst; (c = *src);)
167                 dst = vis(dst, c, flag, *++src);
168         *dst = '\0';
169         return (dst - start);
170 }
171
172 int
173 strnvis(dst, src, siz, flag)
174         char *dst;
175         const char *src;
176         size_t siz;
177         int flag;
178 {
179         char c;
180         char *start, *end;
181         char tbuf[5];
182         int  i;
183
184         i = 0;
185         for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
186                 if (isvisible(c)) {
187                         i = 1;
188                         *dst++ = c;
189                         if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
190                                 /* need space for the extra '\\' */
191                                 if (dst < end)
192                                         *dst++ = '\\';
193                                 else {
194                                         dst--;
195                                         i = 2;
196                                         break;
197                                 }
198                         }
199                         src++;
200                 } else {
201                         i = vis(tbuf, c, flag, *++src) - tbuf;
202                         if (dst + i <= end) {
203                                 memcpy(dst, tbuf, i);
204                                 dst += i;
205                         } else {
206                                 src--;
207                                 break;
208                         }
209                 }
210         }
211         if (siz > 0)
212                 *dst = '\0';
213         if (dst + i > end) {
214                 /* adjust return value for truncation */
215                 while ((c = *src))
216                         dst += vis(tbuf, c, flag, *++src) - tbuf;
217         }
218         return (dst - start);
219 }
220
221 int
222 strvisx(dst, src, len, flag)
223         register char *dst;
224         register const char *src;
225         register size_t len;
226         int flag;
227 {
228         register char c;
229         char *start;
230
231         for (start = dst; len > 1; len--) {
232                 c = *src;
233                 dst = vis(dst, c, flag, *++src);
234         }
235         if (len)
236                 dst = vis(dst, *src, flag, '\0');
237         *dst = '\0';
238         return (dst - start);
239 }
240
241 #endif
This page took 0.072564 seconds and 5 git commands to generate.