]> git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/asl_in.c
syslog-100.2.tar.gz
[apple/syslog.git] / syslogd.tproj / asl_in.c
1 /*
2 * Copyright (c) 2004-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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/fcntl.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29 #include <sys/uio.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #include "daemon.h"
36
37 #define forever for(;;)
38
39 #define ASL_SOCKET_NAME "AppleSystemLogger"
40 #define MY_ID "asl_in"
41
42 static int sock = -1;
43
44 asl_msg_t *
45 asl_in_getmsg(int fd)
46 {
47 char *out;
48 asl_msg_t *m;
49 uint32_t len, n;
50 char tmp[16];
51 int status;
52 uid_t uid;
53 gid_t gid;
54
55 n = read(fd, tmp, 11);
56 if (n < 11)
57 {
58 if (n == 0)
59 {
60 asl_client_count_decrement();
61
62 close(fd);
63 aslevent_removefd(fd);
64 return NULL;
65 }
66
67 if (n < 0)
68 {
69 asldebug("%s: read error (len=%d): %s\n", MY_ID, n, strerror(errno));
70 if (errno != EINTR)
71 {
72 asl_client_count_decrement();
73
74 close(fd);
75 aslevent_removefd(fd);
76 return NULL;
77 }
78 }
79
80 return NULL;
81 }
82
83 len = atoi(tmp);
84 if (len == 0) return NULL;
85
86 out = malloc(len);
87 if (out == NULL) return NULL;
88
89 n = read(fd, out, len);
90 if (n < len)
91 {
92 if (n <= 0)
93 {
94 asldebug("%s: read error (body): %s\n", MY_ID, strerror(errno));
95 if (errno != EINTR)
96 {
97 asl_client_count_decrement();
98
99 close(fd);
100 aslevent_removefd(fd);
101 free(out);
102 return NULL;
103 }
104 }
105 }
106
107 asldebug("asl_in_getmsg: %s\n", (out == NULL) ? "NULL" : out);
108
109 uid = -2;
110 gid = -2;
111
112 status = getpeereid(fd, &uid, &gid);
113 m = asl_msg_from_string(out);
114 if (m == NULL)
115 {
116 free(out);
117 return NULL;
118 }
119
120 snprintf(tmp, sizeof(tmp), "%d", uid);
121 asl_set(m, ASL_KEY_UID, tmp);
122
123 snprintf(tmp, sizeof(tmp), "%d", gid);
124 asl_set(m, ASL_KEY_GID, tmp);
125
126 free(out);
127 return m;
128 }
129
130 asl_msg_t *
131 asl_in_new_connection(int fd)
132 {
133 int clientfd;
134
135 asldebug("%s: accepting connection\n", MY_ID);
136 clientfd = accept(fd, NULL, 0);
137 if (clientfd < 0)
138 {
139 asldebug("%s: error connecting socket fd %d: %s\n", MY_ID, fd, strerror(errno));
140 return NULL;
141 }
142
143 if (fcntl(clientfd, F_SETFL, O_NONBLOCK) < 0)
144 {
145 close(clientfd);
146 clientfd = -1;
147 asldebug("%s: couldn't set O_NONBLOCK for fd %d: %s\n", MY_ID, clientfd, strerror(errno));
148 return NULL;
149 }
150
151 asl_client_count_increment();
152
153 aslevent_addfd(SOURCE_ASL_SOCKET, clientfd, ADDFD_FLAGS_LOCAL, asl_in_getmsg, NULL, NULL);
154 return NULL;
155 }
156
157 int
158 asl_in_init(void)
159 {
160 int rbufsize;
161 int len;
162 launch_data_t sockets_dict, fd_array, fd_dict;
163
164 asldebug("%s: init\n", MY_ID);
165 if (sock >= 0) return sock;
166 if (global.launch_dict == NULL)
167 {
168 asldebug("%s: launchd dict is NULL\n", MY_ID);
169 return -1;
170 }
171
172 sockets_dict = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_SOCKETS);
173 if (sockets_dict == NULL)
174 {
175 asldebug("%s: launchd lookup of LAUNCH_JOBKEY_SOCKETS failed\n", MY_ID);
176 return -1;
177 }
178
179 fd_array = launch_data_dict_lookup(sockets_dict, ASL_SOCKET_NAME);
180 if (fd_array == NULL)
181 {
182 asldebug("%s: launchd lookup of ASL_SOCKET_NAME failed\n", MY_ID);
183 return -1;
184 }
185
186 len = launch_data_array_get_count(fd_array);
187 if (len <= 0)
188 {
189 asldebug("%s: launchd fd array is empty\n", MY_ID);
190 return -1;
191 }
192
193 if (len > 1)
194 {
195 asldebug("%s: warning! launchd fd array has %d sockets\n", MY_ID, len);
196 }
197
198 fd_dict = launch_data_array_get_index(fd_array, 0);
199 if (fd_dict == NULL)
200 {
201 asldebug("%s: launchd file discriptor array element 0 is NULL\n", MY_ID);
202 return -1;
203 }
204
205 sock = launch_data_get_fd(fd_dict);
206
207 rbufsize = 128 * 1024;
208 len = sizeof(rbufsize);
209
210 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rbufsize, len) < 0)
211 {
212 asldebug("%s: couldn't set receive buffer size for %d (%s): %s\n", MY_ID, sock, _PATH_ASL_IN, strerror(errno));
213 close(sock);
214 sock = -1;
215 return -1;
216 }
217
218 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
219 {
220 asldebug("%s: couldn't set O_NONBLOCK for socket %d (%s): %s\n", MY_ID, sock, _PATH_ASL_IN, strerror(errno));
221 close(sock);
222 sock = -1;
223 return -1;
224 }
225
226 return aslevent_addfd(SOURCE_ASL_SOCKET, sock, ADDFD_FLAGS_LOCAL, asl_in_new_connection, NULL, NULL);
227 }
228
229 int
230 asl_in_reset(void)
231 {
232 return 0;
233 }
234
235 int
236 asl_in_close(void)
237 {
238 if (sock < 0) return 1;
239
240 close(sock);
241 unlink(_PATH_ASL_IN);
242
243 return 0;
244 }