]> git.saurik.com Git - apple/libc.git/blob - gen/asl_util.c
4a0130b2e604fa9ca5ac2ebe53690d4971886b22
[apple/libc.git] / gen / asl_util.c
1 /*
2 * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
18 * License for the specific language governing rights and limitations
19 * under the License."
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * These routines needs to be separate from asl.c, so that dyld can build
25 * and suck in these without the rest of asl.
26 */
27
28 #include <string.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/un.h>
32 #include <fcntl.h>
33 #include <stdint.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <unistd.h>
37
38 #define _PATH_ASL_IN "/var/run/asl_input"
39
40 static uint8_t *b64charset = (uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
41
42 __private_extern__ int
43 _asl_server_socket(int *sock, struct sockaddr_un *server)
44 {
45 socklen_t len;
46 int status, flags;
47
48 *sock = socket(AF_UNIX, SOCK_STREAM, 0);
49 if (*sock < 0) return -1;
50
51 memset(server, 0, sizeof(struct sockaddr_un));
52 server->sun_family = AF_UNIX;
53
54 strcpy(server->sun_path, _PATH_ASL_IN);
55 server->sun_len = strlen(server->sun_path) + 1;
56 len = sizeof(server->sun_len) + sizeof(server->sun_family) + server->sun_len;
57
58 status = connect(*sock, (const struct sockaddr *)server, len);
59
60 if (status < 0)
61 {
62 close(*sock);
63 *sock = -1;
64 return -1;
65 }
66
67 /* set close-on-exec flag */
68 fcntl(*sock, F_SETFD, 1);
69
70 /* set non-blocking flag */
71 flags = fcntl(*sock, F_GETFL, 0);
72 if (flags >= 0) fcntl(*sock, F_SETFL, flags | O_NONBLOCK);
73
74 return 0;
75 }
76
77 __private_extern__ const char *
78 _asl_escape(unsigned char c)
79 {
80 switch(c)
81 {
82 case '\\':
83 return "\\\\";
84 case '[':
85 return "\\[";
86 case ']':
87 return "\\]";
88 case '\n':
89 return "\\n";
90 }
91 return NULL;
92 }
93
94 static int
95 asl_is_utf8_char(const unsigned char *p, int *state, int *ctype)
96 {
97 switch (*state)
98 {
99 case 0:
100 {
101 *ctype = 0;
102
103 if (*p >= 0x80)
104 {
105 *state = 1;
106 if ((*p >= 0xc2) && (*p <= 0xdf)) *ctype = 1;
107 else if (*p == 0xe0) *ctype = 2;
108 else if ((*p >= 0xe1) && (*p <= 0xef)) *ctype = 3;
109 else if (*p == 0xf0) *ctype = 4;
110 else if ((*p >= 0xf1) && (*p <= 0xf3)) *ctype = 5;
111 else if (*p == 0xf4) *ctype = 6;
112 else return 0;
113 }
114
115 break;
116 }
117
118 case 1:
119 {
120 switch (*ctype)
121 {
122 case 1:
123 {
124 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
125 else return 0;
126 break;
127 }
128
129 case 2:
130 {
131 if ((*p >= 0xa0) && (*p <= 0xbf)) *state = 2;
132 else return 0;
133 break;
134 }
135
136 case 3:
137 {
138 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
139 else return 0;
140 break;
141 }
142
143 case 4:
144 {
145 if ((*p >= 0x90) && (*p <= 0xbf)) *state = 2;
146 else return 0;
147 break;
148 }
149
150 case 5:
151 {
152 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
153 else return 0;
154 break;
155 }
156
157 case 6:
158 {
159 if ((*p >= 0x80) && (*p <= 0x8f)) *state = 2;
160 else return 0;
161 break;
162 }
163
164 default: return 0;
165 }
166
167 break;
168 }
169
170 case 2:
171 {
172 if ((*ctype >= 2) && (*ctype <= 3))
173 {
174 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
175 else return 0;
176 }
177 else if ((*ctype >= 4) && (*ctype <= 6))
178 {
179 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 3;
180 else return 0;
181 }
182 else
183 {
184 return 0;
185 }
186
187 break;
188 }
189
190 case 3:
191 {
192 if ((*ctype >= 4) && (*ctype <= 6))
193 {
194 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
195 else return 0;
196 }
197 else
198 {
199 return 0;
200 }
201
202 break;
203 }
204
205 default: return 0;
206 }
207
208 return 1;
209 }
210
211 __private_extern__ int
212 asl_is_utf8(const char *str)
213 {
214 const unsigned char *p;
215 int flag = 1;
216 int state = 0;
217 int ctype = 0;
218
219 if (str == NULL) return flag;
220
221 for (p = (const unsigned char *)str; (*p != '\0') && (flag == 1); p++)
222 {
223 flag = asl_is_utf8_char(p, &state, &ctype);
224 }
225
226 return flag;
227 }
228
229 __private_extern__ uint8_t *
230 asl_b64_encode(const uint8_t *buf, size_t len)
231 {
232 uint8_t *out;
233 uint8_t b;
234 size_t i0, i1, i2, j, outlen;
235
236 if (buf == NULL) return NULL;
237 if (len == 0) return NULL;
238
239 outlen = ((len + 2) / 3) * 4;
240 out = (uint8_t *)malloc(outlen + 1);
241 if (out == NULL)
242 {
243 errno = ENOMEM;
244 return NULL;
245 }
246
247 out[outlen] = 0;
248
249 i0 = 0;
250 i1 = 1;
251 i2 = 2;
252 j = 0;
253
254 while (i2 < len)
255 {
256 b = buf[i0] >> 2;
257 out[j++] = b64charset[b];
258
259 b = ((buf[i0] & 0x03) << 4) | (buf[i1] >> 4);
260 out[j++] = b64charset[b];
261
262 b = ((buf[i1] & 0x0f) << 2) | ((buf[i2] & 0xc0) >> 6);
263 out[j++] = b64charset[b];
264
265 b = buf[i2] & 0x3f;
266 out[j++] = b64charset[b];
267
268 i0 += 3;
269 i1 = i0 + 1;
270 i2 = i1 + 1;
271 }
272
273 if (i0 < len)
274 {
275 b = buf[i0] >> 2;
276 out[j++] = b64charset[b];
277
278 b = (buf[i0] & 0x03) << 4;
279
280 if (i1 < len) b |= (buf[i1] >> 4);
281 out[j++] = b64charset[b];
282
283 if (i1 >= len)
284 {
285 out[j++] = '=';
286 out[j++] = '=';
287 return out;
288 }
289
290 b = (buf[i1] & 0x0f) << 2;
291 out[j++] = b64charset[b];
292 out[j++] = '=';
293 }
294
295 return out;
296 }