We now build libssh2 in Xcode and it's a much better UB/10.4 citizen
[printdrop.git] / Vendor / libssh2 / Source / misc.c
1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms,
5 * with or without modification, are permitted provided
6 * that the following conditions are met:
7 *
8 * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 *
17 * Neither the name of the copyright holder nor the names
18 * of any other contributors may be used to endorse or
19 * promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 * OF SUCH DAMAGE.
36 */
37
38 #include "libssh2_priv.h"
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 /* {{{ libssh2_ntohu32
44 */
45 unsigned long
46 libssh2_ntohu32(const unsigned char *buf)
47 {
48 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
49 }
50
51 /* }}} */
52
53 /* {{{ libssh2_ntohu64
54 * Note: Some 32-bit platforms have issues with bitops on long longs
55 * Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses
56 */
57 libssh2_uint64_t
58 libssh2_ntohu64(const unsigned char *buf)
59 {
60 unsigned long msl, lsl;
61
62 msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
63 lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
64
65 return ((msl * 65536) * 65536) + lsl;
66 }
67
68 /* }}} */
69
70 /* {{{ libssh2_htonu32
71 */
72 void
73 libssh2_htonu32(unsigned char *buf, unsigned long value)
74 {
75 buf[0] = (value >> 24) & 0xFF;
76 buf[1] = (value >> 16) & 0xFF;
77 buf[2] = (value >> 8) & 0xFF;
78 buf[3] = value & 0xFF;
79 }
80
81 /* }}} */
82
83 /* {{{ libssh2_htonu64
84 */
85 void
86 libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
87 {
88 unsigned long msl = (value / 65536) / 65536;
89
90 buf[0] = (msl >> 24) & 0xFF;
91 buf[1] = (msl >> 16) & 0xFF;
92 buf[2] = (msl >> 8) & 0xFF;
93 buf[3] = msl & 0xFF;
94
95 buf[4] = (value >> 24) & 0xFF;
96 buf[5] = (value >> 16) & 0xFF;
97 buf[6] = (value >> 8) & 0xFF;
98 buf[7] = value & 0xFF;
99 }
100
101 /* }}} */
102
103 /* Base64 Conversion */
104
105 /* {{{ */
106 static const char libssh2_base64_table[] =
107 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
108 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
109 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
110 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
111 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
112 };
113
114 static const char libssh2_base64_pad = '=';
115
116 static const short libssh2_base64_reverse_table[256] = {
117 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
118 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
119 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
120 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
121 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
122 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
123 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
124 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
125 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
126 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
127 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
128 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
129 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
130 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
131 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
133 };
134
135 /* }}} */
136
137
138 /* {{{ libssh2_base64_decode
139 * Decode a base64 chunk and store it into a newly alloc'd buffer
140 */
141 LIBSSH2_API int
142 libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
143 unsigned int *datalen, const char *src,
144 unsigned int src_len)
145 {
146 unsigned char *s, *d;
147 short v;
148 int i = 0, len = 0;
149
150 *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
151 d = (unsigned char *) *data;
152 if (!d) {
153 return -1;
154 }
155
156 for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
157 if ((v = libssh2_base64_reverse_table[*s]) < 0)
158 continue;
159 switch (i % 4) {
160 case 0:
161 d[len] = v << 2;
162 break;
163 case 1:
164 d[len++] |= v >> 4;
165 d[len] = v << 4;
166 break;
167 case 2:
168 d[len++] |= v >> 2;
169 d[len] = v << 6;
170 break;
171 case 3:
172 d[len++] |= v;
173 break;
174 }
175 i++;
176 }
177 if ((i % 4) == 1) {
178 /* Invalid -- We have a byte which belongs exclusively to a partial octet */
179 LIBSSH2_FREE(session, *data);
180 return -1;
181 }
182
183 *datalen = len;
184 return 0;
185 }
186
187 /* }}} */
188
189 #ifdef LIBSSH2DEBUG
190 LIBSSH2_API int
191 libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
192 {
193 session->showmask = bitmask;
194 return 0;
195 }
196
197 void
198 _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
199 {
200 char buffer[1536];
201 int len;
202 va_list vargs;
203 static const char *const contexts[9] = {
204 "Unknown",
205 "Transport",
206 "Key Exchange",
207 "Userauth",
208 "Connection",
209 "scp",
210 "SFTP Subsystem",
211 "Failure Event",
212 "Publickey Subsystem",
213 };
214
215 if (context < 1 || context > 8) {
216 context = 0;
217 }
218 if (!(session->showmask & (1 << context))) {
219 /* no such output asked for */
220 return;
221 }
222
223 len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]);
224
225 va_start(vargs, format);
226 len += vsnprintf(buffer + len, 1535 - len, format, vargs);
227 buffer[len] = '\n';
228 va_end(vargs);
229 write(2, buffer, len + 1);
230
231 }
232
233 #else
234 LIBSSH2_API int
235 libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
236 {
237 (void) session;
238 (void) bitmask;
239 return 0;
240 }
241 #endif