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