]> git.saurik.com Git - apple/libc.git/blob - gen/asl_util.c
a7240a6b1941ba97150a8fddfc774b9ca0234dac
[apple/libc.git] / gen / asl_util.c
1 /*
2 * Copyright (c) 2006-2007 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 <errno.h>
35
36 #define _PATH_ASL_IN "/var/run/asl_input"
37
38 static uint8_t *b64charset = (uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
39
40 __private_extern__ int
41 _asl_server_socket(int *sock, struct sockaddr_un *server)
42 {
43 socklen_t len;
44 int status, flags;
45
46 *sock = socket(AF_UNIX, SOCK_STREAM, 0);
47 if (*sock < 0) return -1;
48
49 memset(server, 0, sizeof(struct sockaddr_un));
50 server->sun_family = AF_UNIX;
51
52 strcpy(server->sun_path, _PATH_ASL_IN);
53 server->sun_len = strlen(server->sun_path) + 1;
54 len = sizeof(server->sun_len) + sizeof(server->sun_family) + server->sun_len;
55
56 status = connect(*sock, (const struct sockaddr *)server, len);
57
58 if (status < 0)
59 {
60 close(*sock);
61 *sock = -1;
62 return -1;
63 }
64
65 /* set close-on-exec flag */
66 fcntl(*sock, F_SETFD, 1);
67
68 /* set non-blocking flag */
69 flags = fcntl(*sock, F_GETFL, 0);
70 if (flags >= 0) fcntl(*sock, F_SETFL, flags | O_NONBLOCK);
71
72 return 0;
73 }
74
75 __private_extern__ const char *
76 _asl_escape(unsigned char c)
77 {
78 switch(c)
79 {
80 case '\\':
81 return "\\\\";
82 case '[':
83 return "\\[";
84 case ']':
85 return "\\]";
86 case '\n':
87 return "\\n";
88 }
89 return NULL;
90 }
91
92 static int
93 asl_is_utf8_char(const unsigned char *p, int *state, int *ctype)
94 {
95 switch (*state)
96 {
97 case 0:
98 {
99 *ctype = 0;
100
101 if (*p >= 0x80)
102 {
103 *state = 1;
104 if ((*p >= 0xc2) && (*p <= 0xdf)) *ctype = 1;
105 else if (*p == 0xe0) *ctype = 2;
106 else if ((*p >= 0xe1) && (*p <= 0xef)) *ctype = 3;
107 else if (*p == 0xf0) *ctype = 4;
108 else if ((*p >= 0xf1) && (*p <= 0xf3)) *ctype = 5;
109 else if (*p == 0xf4) *ctype = 6;
110 else return 0;
111 }
112
113 break;
114 }
115
116 case 1:
117 {
118 switch (*ctype)
119 {
120 case 1:
121 {
122 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
123 else return 0;
124 break;
125 }
126
127 case 2:
128 {
129 if ((*p >= 0xa0) && (*p <= 0xbf)) *state = 2;
130 else return 0;
131 break;
132 }
133
134 case 3:
135 {
136 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
137 else return 0;
138 break;
139 }
140
141 case 4:
142 {
143 if ((*p >= 0x90) && (*p <= 0xbf)) *state = 2;
144 else return 0;
145 break;
146 }
147
148 case 5:
149 {
150 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
151 else return 0;
152 break;
153 }
154
155 case 6:
156 {
157 if ((*p >= 0x80) && (*p <= 0x8f)) *state = 2;
158 else return 0;
159 break;
160 }
161
162 default: return 0;
163 }
164
165 break;
166 }
167
168 case 2:
169 {
170 if ((*ctype >= 2) && (*ctype <= 3))
171 {
172 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
173 else return 0;
174 }
175 else if ((*ctype >= 4) && (*ctype <= 6))
176 {
177 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 3;
178 else return 0;
179 }
180 else
181 {
182 return 0;
183 }
184
185 break;
186 }
187
188 case 3:
189 {
190 if ((*ctype >= 4) && (*ctype <= 6))
191 {
192 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
193 else return 0;
194 }
195 else
196 {
197 return 0;
198 }
199
200 break;
201 }
202
203 default: return 0;
204 }
205
206 return 1;
207 }
208
209 __private_extern__ int
210 asl_is_utf8(const char *str)
211 {
212 const unsigned char *p;
213 int flag = 1;
214 int state = 0;
215 int ctype = 0;
216
217 if (str == NULL) return flag;
218
219 for (p = (const unsigned char *)str; (*p != '\0') && (flag == 1); p++)
220 {
221 flag = asl_is_utf8_char(p, &state, &ctype);
222 }
223
224 return flag;
225 }
226
227 __private_extern__ uint8_t *
228 asl_b64_encode(const uint8_t *buf, size_t len)
229 {
230 uint8_t *out;
231 uint8_t b;
232 size_t i0, i1, i2, j, outlen;
233
234 if (buf == NULL) return NULL;
235 if (len == 0) return NULL;
236
237 outlen = ((len + 2) / 3) * 4;
238 out = (uint8_t *)malloc(outlen + 1);
239 if (out == NULL)
240 {
241 errno = ENOMEM;
242 return NULL;
243 }
244
245 out[outlen] = 0;
246
247 i0 = 0;
248 i1 = 1;
249 i2 = 2;
250 j = 0;
251
252 while (i2 < len)
253 {
254 b = buf[i0] >> 2;
255 out[j++] = b64charset[b];
256
257 b = ((buf[i0] & 0x03) << 4) | (buf[i1] >> 4);
258 out[j++] = b64charset[b];
259
260 b = ((buf[i1] & 0x0f) << 2) | ((buf[i2] & 0xc0) >> 6);
261 out[j++] = b64charset[b];
262
263 b = buf[i2] & 0x3f;
264 out[j++] = b64charset[b];
265
266 i0 += 3;
267 i1 = i0 + 1;
268 i2 = i1 + 1;
269 }
270
271 if (i0 < len)
272 {
273 b = buf[i0] >> 2;
274 out[j++] = b64charset[b];
275
276 b = (buf[i0] & 0x03) << 4;
277
278 if (i1 < len) b |= (buf[i1] >> 4);
279 out[j++] = b64charset[b];
280
281 if (i1 >= len)
282 {
283 out[j++] = '=';
284 out[j++] = '=';
285 return out;
286 }
287
288 b = (buf[i1] & 0x0f) << 2;
289 out[j++] = b64charset[b];
290 out[j++] = '=';
291 }
292
293 return out;
294 }