]>
git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/remote.c
2 * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <netinet/tcp.h>
29 #include <arpa/inet.h>
42 #include "asl_memory.h"
45 #define forever for(;;)
47 #define MY_ID "remote"
49 #define LOCKDOWN_PATH "/var/run/lockdown"
50 #define SYSLOG_SOCK_PATH "/var/run/lockdown/syslog.sock"
51 #define ASL_REMOTE_PORT 203
57 #define WATCH_LOCKDOWN_START 1
60 #define SESSION_FLAGS_LOCKDOWN 0x00000001
69 typedef uint32_t notify_state_t
;
70 extern int notify_set_state(int, notify_state_t
);
72 typedef uint64_t notify_state_t
;
75 extern char *asl_list_to_string(asl_search_result_t
*list
, uint32_t *outlen
);
76 extern size_t asl_memory_size(asl_memory_t
*s
);
77 extern uint32_t db_query(aslresponse query
, aslresponse
*res
, uint64_t startid
, int count
, int flags
, uint64_t *lastid
, int32_t ruid
, int32_t rgid
);
79 #define SESSION_WRITE(f,x) if (write(f, x, strlen(x)) < 0) goto exit_session
88 remote_db_size(uint32_t sel
)
90 if (sel
== DB_TYPE_FILE
) return global
.db_file_max
;
91 if (sel
== DB_TYPE_MEMORY
) return global
.db_memory_max
;
92 if (sel
== DB_TYPE_MINI
) return global
.db_mini_max
;
97 remote_db_set_size(uint32_t sel
, uint32_t size
)
99 if (sel
== DB_TYPE_FILE
) global
.db_file_max
= size
;
100 if (sel
== DB_TYPE_MEMORY
) global
.db_memory_max
= size
;
101 if (sel
== DB_TYPE_MINI
) global
.db_mini_max
= size
;
106 remote_db_stats(uint32_t sel
)
111 if (sel
== DB_TYPE_FILE
) asl_store_statistics(global
.file_db
, &m
);
112 if (sel
== DB_TYPE_MEMORY
) asl_memory_statistics(global
.memory_db
, &m
);
113 if (sel
== DB_TYPE_MINI
) asl_mini_memory_statistics(global
.mini_db
, &m
);
120 int i
, s
, wfd
, status
, pfmt
, watch
, wtoken
, nfd
, do_prompt
, filter
;
122 asl_search_result_t ql
;
127 char str
[1024], *p
, *qs
, *out
;
130 uint64_t low_id
, high_id
;
131 notify_state_t nstate
;
132 uint32_t dbselect
, flags
;
135 if (x
== NULL
) pthread_exit(NULL
);
137 sp
= (session_args_t
*)x
;
147 if (global
.dbtype
& DB_TYPE_MEMORY
) dbselect
= DB_TYPE_MEMORY
;
148 else if (global
.dbtype
& DB_TYPE_MINI
) dbselect
= DB_TYPE_MINI
;
149 else if (global
.dbtype
& DB_TYPE_FILE
) dbselect
= DB_TYPE_FILE
;
156 memset(&ql
, 0, sizeof(asl_search_result_t
));
158 snprintf(str
, sizeof(str
) - 1, "\n========================\nASL is here to serve you\n");
159 if (write(s
, str
, strlen(str
)) < 0)
172 snprintf(str
, sizeof(str
) - 1, "> ");
173 SESSION_WRITE(s
, str
);
177 memset(str
, 0, sizeof(str
));
185 FD_SET(wfd
, &readfds
);
186 if (wfd
> nfd
) nfd
= wfd
;
189 status
= select(nfd
+ 1, &readfds
, NULL
, NULL
, NULL
);
191 if ((wfd
!= -1) && (FD_ISSET(wfd
, &readfds
)))
193 len
= read(wfd
, &i
, sizeof(int));
196 if (FD_ISSET(s
, &readfds
))
198 len
= read(s
, str
, sizeof(str
) - 1);
199 if (len
<= 0) goto exit_session
;
201 while ((len
> 1) && ((str
[len
- 1] == '\n') || (str
[len
- 1] == '\r')))
207 if ((!strcmp(str
, "q")) || (!strcmp(str
, "quit")) || (!strcmp(str
, "exit")))
209 snprintf(str
, sizeof(str
) - 1, "Goodbye\n");
210 write(s
, str
, strlen(str
));
216 if ((!strcmp(str
, "?")) || (!strcmp(str
, "help")))
218 snprintf(str
, sizeof(str
) - 1, "Commands\n");
219 SESSION_WRITE(s
, str
);
220 snprintf(str
, sizeof(str
) - 1, " quit exit session\n");
221 SESSION_WRITE(s
, str
);
222 snprintf(str
, sizeof(str
) - 1, " select [val] get [set] current database\n");
223 SESSION_WRITE(s
, str
);
224 snprintf(str
, sizeof(str
) - 1, " val must be \"file\", \"mem\", or \"mini\"\n");
225 SESSION_WRITE(s
, str
);
226 snprintf(str
, sizeof(str
) - 1, " file [on/off] enable / disable file store\n");
227 SESSION_WRITE(s
, str
);
228 snprintf(str
, sizeof(str
) - 1, " memory [on/off] enable / disable memory store\n");
229 SESSION_WRITE(s
, str
);
230 snprintf(str
, sizeof(str
) - 1, " mini [on/off] enable / disable mini memory store\n");
231 SESSION_WRITE(s
, str
);
232 snprintf(str
, sizeof(str
) - 1, " stats database statistics\n");
233 SESSION_WRITE(s
, str
);
234 snprintf(str
, sizeof(str
) - 1, " flush flush database\n");
235 SESSION_WRITE(s
, str
);
236 snprintf(str
, sizeof(str
) - 1, " dbsize [val] get [set] database size (# of records)\n");
237 SESSION_WRITE(s
, str
);
238 snprintf(str
, sizeof(str
) - 1, " filter [val] get [set] current database filter\n");
239 SESSION_WRITE(s
, str
);
240 snprintf(str
, sizeof(str
) - 1, " [p]anic (emergency) [a]lert [c]ritical [e]rror\n");
241 SESSION_WRITE(s
, str
);
242 snprintf(str
, sizeof(str
) - 1, " [w]arning [n]otice [i]nfo [d]ebug\n");
243 SESSION_WRITE(s
, str
);
244 snprintf(str
, sizeof(str
) - 1, " watch print new messages as they arrive\n");
245 SESSION_WRITE(s
, str
);
246 snprintf(str
, sizeof(str
) - 1, " stop stop watching for new messages\n");
247 SESSION_WRITE(s
, str
);
248 snprintf(str
, sizeof(str
) - 1, " raw use raw format for printing messages\n");
249 SESSION_WRITE(s
, str
);
250 snprintf(str
, sizeof(str
) - 1, " std use standard format for printing messages\n");
251 SESSION_WRITE(s
, str
);
252 snprintf(str
, sizeof(str
) - 1, " * show all log messages\n");
253 SESSION_WRITE(s
, str
);
254 snprintf(str
, sizeof(str
) - 1, " * key val equality search for messages (single key/value pair)\n");
255 SESSION_WRITE(s
, str
);
256 snprintf(str
, sizeof(str
) - 1, " * op key val search for matching messages (single key/value pair)\n");
257 SESSION_WRITE(s
, str
);
258 snprintf(str
, sizeof(str
) - 1, " * [op key val] ... search for matching messages (multiple key/value pairs)\n");
259 SESSION_WRITE(s
, str
);
260 snprintf(str
, sizeof(str
) - 1, " operators: = < > ! (not equal) T (key exists) R (regex)\n");
261 SESSION_WRITE(s
, str
);
262 snprintf(str
, sizeof(str
) - 1, " modifiers (must follow operator):\n");
263 SESSION_WRITE(s
, str
);
264 snprintf(str
, sizeof(str
) - 1, " C=casefold N=numeric S=substring A=prefix Z=suffix\n");
265 SESSION_WRITE(s
, str
);
266 snprintf(str
, sizeof(str
) - 1, "\n");
267 SESSION_WRITE(s
, str
);
270 else if (!strcmp(str
, "stats"))
272 stats
= remote_db_stats(dbselect
);
273 out
= asl_format_message((asl_msg_t
*)stats
, ASL_MSG_FMT_RAW
, ASL_TIME_FMT_SEC
, ASL_ENCODE_NONE
, &outlen
);
274 write(s
, out
, outlen
);
279 else if (!strcmp(str
, "flush"))
281 else if (!strncmp(str
, "select", 6))
284 while ((*p
== ' ') || (*p
== '\t')) p
++;
287 if (dbselect
== 0) snprintf(str
, sizeof(str
) - 1, "no store\n");
288 else if (dbselect
== DB_TYPE_FILE
) snprintf(str
, sizeof(str
) - 1, "file store\n");
289 else if (dbselect
== DB_TYPE_MEMORY
) snprintf(str
, sizeof(str
) - 1, "memory store\n");
290 else if (dbselect
== DB_TYPE_MINI
) snprintf(str
, sizeof(str
) - 1, "mini memory store\n");
291 SESSION_WRITE(s
, str
);
295 if (!strncmp(p
, "file", 4))
297 if ((global
.dbtype
& DB_TYPE_FILE
) == 0)
299 snprintf(str
, sizeof(str
) - 1, "file database is not enabled\n");
300 SESSION_WRITE(s
, str
);
304 dbselect
= DB_TYPE_FILE
;
306 else if (!strncmp(p
, "mem", 3))
308 if ((global
.dbtype
& DB_TYPE_MEMORY
) == 0)
310 snprintf(str
, sizeof(str
) - 1, "memory database is not enabled\n");
311 SESSION_WRITE(s
, str
);
315 dbselect
= DB_TYPE_MEMORY
;
317 else if (!strncmp(p
, "mini", 4))
319 if ((global
.dbtype
& DB_TYPE_MINI
) == 0)
321 if (global
.mini_db
!= NULL
)
323 snprintf(str
, sizeof(str
) - 1, "mini memory database is enabled for disaster messages\n");
324 SESSION_WRITE(s
, str
);
328 snprintf(str
, sizeof(str
) - 1, "mini memory database is not enabled\n");
329 SESSION_WRITE(s
, str
);
334 dbselect
= DB_TYPE_MINI
;
338 snprintf(str
, sizeof(str
) - 1, "unknown database type\n");
339 SESSION_WRITE(s
, str
);
343 snprintf(str
, sizeof(str
) - 1, "OK\n");
344 SESSION_WRITE(s
, str
);
347 else if (!strncmp(str
, "file", 4))
350 while ((*p
== ' ') || (*p
== '\t')) p
++;
353 snprintf(str
, sizeof(str
) - 1, "file database is %senabled\n", (global
.dbtype
& DB_TYPE_FILE
) ? "" : "not ");
354 SESSION_WRITE(s
, str
);
355 if ((global
.dbtype
& DB_TYPE_FILE
) != 0) dbselect
= DB_TYPE_FILE
;
359 if (!strcmp(p
, "on")) global
.dbtype
|= DB_TYPE_FILE
;
360 else if (!strcmp(p
, "off")) global
.dbtype
&= ~ DB_TYPE_FILE
;
362 snprintf(str
, sizeof(str
) - 1, "OK\n");
363 SESSION_WRITE(s
, str
);
366 else if (!strncmp(str
, "memory", 6))
369 while ((*p
== ' ') || (*p
== '\t')) p
++;
372 snprintf(str
, sizeof(str
) - 1, "memory database is %senabled\n", (global
.dbtype
& DB_TYPE_MEMORY
) ? "" : "not ");
373 SESSION_WRITE(s
, str
);
374 if ((global
.dbtype
& DB_TYPE_MEMORY
) != 0) dbselect
= DB_TYPE_MEMORY
;
378 if (!strcmp(p
, "on")) global
.dbtype
|= DB_TYPE_MEMORY
;
379 else if (!strcmp(p
, "off")) global
.dbtype
&= ~ DB_TYPE_MEMORY
;
381 snprintf(str
, sizeof(str
) - 1, "OK\n");
382 SESSION_WRITE(s
, str
);
385 else if (!strncmp(str
, "mini", 4))
388 while ((*p
== ' ') || (*p
== '\t')) p
++;
391 snprintf(str
, sizeof(str
) - 1, "mini database is %senabled\n", (global
.dbtype
& DB_TYPE_MINI
) ? "" : "not ");
392 SESSION_WRITE(s
, str
);
393 if ((global
.dbtype
& DB_TYPE_MINI
) != 0) dbselect
= DB_TYPE_MINI
;
397 if (!strcmp(p
, "on")) global
.dbtype
|= DB_TYPE_MINI
;
398 else if (!strcmp(p
, "off")) global
.dbtype
&= ~ DB_TYPE_MINI
;
400 snprintf(str
, sizeof(str
) - 1, "OK\n");
401 SESSION_WRITE(s
, str
);
404 else if (!strncmp(str
, "dbsize", 6))
408 snprintf(str
, sizeof(str
) - 1, "no store\n");
409 SESSION_WRITE(s
, str
);
414 while ((*p
== ' ') || (*p
== '\t')) p
++;
417 snprintf(str
, sizeof(str
) - 1, "DB size %u\n", remote_db_size(dbselect
));
418 SESSION_WRITE(s
, str
);
423 remote_db_set_size(dbselect
, i
);
425 snprintf(str
, sizeof(str
) - 1, "OK\n");
426 SESSION_WRITE(s
, str
);
429 else if (!strncmp(str
, "filter", 6))
432 while ((*p
== ' ') || (*p
== '\t')) p
++;
435 snprintf(str
, sizeof(str
) - 1, "%s%s%s%s%s%s%s%s\n",
436 (global
.asl_log_filter
& ASL_FILTER_MASK_EMERG
) ? "p" : "",
437 (global
.asl_log_filter
& ASL_FILTER_MASK_ALERT
) ? "a" : "",
438 (global
.asl_log_filter
& ASL_FILTER_MASK_CRIT
) ? "c" : "",
439 (global
.asl_log_filter
& ASL_FILTER_MASK_ERR
) ? "e" : "",
440 (global
.asl_log_filter
& ASL_FILTER_MASK_WARNING
) ? "w" : "",
441 (global
.asl_log_filter
& ASL_FILTER_MASK_NOTICE
) ? "n" : "",
442 (global
.asl_log_filter
& ASL_FILTER_MASK_INFO
) ? "i" : "",
443 (global
.asl_log_filter
& ASL_FILTER_MASK_DEBUG
) ? "d" : "");
444 SESSION_WRITE(s
, str
);
449 if ((*p
>= '0') && (*p
<= '7'))
452 filter
= ASL_FILTER_MASK_UPTO(i
);
458 if ((*p
== 'p') || (*p
== 'P')) filter
|= ASL_FILTER_MASK_EMERG
;
459 else if ((*p
== 'a') || (*p
== 'A')) filter
|= ASL_FILTER_MASK_ALERT
;
460 else if ((*p
== 'c') || (*p
== 'C')) filter
|= ASL_FILTER_MASK_CRIT
;
461 else if ((*p
== 'e') || (*p
== 'E')) filter
|= ASL_FILTER_MASK_ERR
;
462 else if ((*p
== 'w') || (*p
== 'W')) filter
|= ASL_FILTER_MASK_WARNING
;
463 else if ((*p
== 'n') || (*p
== 'N')) filter
|= ASL_FILTER_MASK_NOTICE
;
464 else if ((*p
== 'i') || (*p
== 'I')) filter
|= ASL_FILTER_MASK_INFO
;
465 else if ((*p
== 'd') || (*p
== 'D')) filter
|= ASL_FILTER_MASK_DEBUG
;
470 status
= notify_register_check(NOTIFY_SYSTEM_ASL_FILTER
, &i
);
471 if (status
!= NOTIFY_STATUS_OK
)
473 snprintf(str
, sizeof(str
) - 1, "FAILED %d\n", status
);
474 SESSION_WRITE(s
, str
);
479 status
= notify_set_state(i
, nstate
);
480 if (status
!= NOTIFY_STATUS_OK
)
482 snprintf(str
, sizeof(str
) - 1, "FAILED %d\n", status
);
483 SESSION_WRITE(s
, str
);
487 status
= notify_post(NOTIFY_SYSTEM_ASL_FILTER
);
490 global
.asl_log_filter
= filter
;
492 snprintf(str
, sizeof(str
) - 1, "OK\n");
493 SESSION_WRITE(s
, str
);
498 else if (!strcmp(str
, "stop"))
500 if (watch
!= WATCH_OFF
)
503 notify_cancel(wtoken
);
510 if (query
!= NULL
) free(query
);
513 snprintf(str
, sizeof(str
) - 1, "OK\n");
514 SESSION_WRITE(s
, str
);
518 snprintf(str
, sizeof(str
) - 1, "not watching!\n");
519 SESSION_WRITE(s
, str
);
522 else if (!strcmp(str
, "raw"))
527 else if (!strcmp(str
, "std"))
532 else if (!strcmp(str
, "watch"))
534 if (watch
!= WATCH_OFF
)
536 snprintf(str
, sizeof(str
) - 1, "already watching!\n");
537 SESSION_WRITE(s
, str
);
541 if (flags
& SESSION_FLAGS_LOCKDOWN
)
543 watch
= WATCH_LOCKDOWN_START
;
547 status
= notify_register_file_descriptor(ASL_DB_NOTIFICATION
, &wfd
, 0, &wtoken
);
550 snprintf(str
, sizeof(str
) - 1, "notify_register_file_descriptor failed: %d\n", status
);
551 SESSION_WRITE(s
, str
);
558 snprintf(str
, sizeof(str
) - 1, "OK\n");
559 SESSION_WRITE(s
, str
);
562 else if ((str
[0] == '*') || (str
[0] == 'T') || (str
[0] == '=') || (str
[0] == '!') || (str
[0] == '<') || (str
[0] == '>'))
564 memset(&ql
, 0, sizeof(asl_search_result_t
));
565 if (query
!= NULL
) free(query
);
570 while ((*p
== ' ') || (*p
== '\t')) p
++;
579 asprintf(&qs
, "Q %s", p
);
580 query
= asl_msg_from_string(qs
);
583 else if ((*p
== 'T') || (*p
== '=') || (*p
== '!') || (*p
== '<') || (*p
== '>') || (*p
== 'R'))
586 asprintf(&qs
, "Q [%s]", p
);
587 query
= asl_msg_from_string(qs
);
593 asprintf(&qs
, "Q [= %s]", p
);
594 query
= asl_msg_from_string(qs
);
600 snprintf(str
, sizeof(str
) - 1, "unrecognized command\n");
601 SESSION_WRITE(s
, str
);
602 snprintf(str
, sizeof(str
) - 1, "enter \"help\" for help\n");
603 SESSION_WRITE(s
, str
);
609 * If this session is PurpleConsole watching for log messages,
610 * we pass through this part of the loop once initially to pick up
611 * existing messages already in memory. After that, dbserver will
612 * send new messages in send_to_direct_watchers(). We wait until
613 * the initial messages are sent to PurpleConsole before setting
614 * global.lockdown_session_fd to allow this query to complete before
615 * dbserver starts sending. To prevent a race between this query and
616 * when the first message is sent by send_to_direct_watchers, we hold
617 * the work queue lock between the time of the query and the time that
618 * lockdown_session_fd is set.
620 if ((flags
& SESSION_FLAGS_LOCKDOWN
) && (watch
== WATCH_RUN
)) continue;
622 if (watch
== WATCH_LOCKDOWN_START
)
624 pthread_mutex_lock(global
.work_queue_lock
);
634 if (watch
== WATCH_OFF
) low_id
= 0;
636 memset(&res
, 0, sizeof(aslresponse
));
638 status
= db_query(&ql
, (aslresponse
*)&res
, low_id
, 0, 0, &high_id
, 0, 0);
640 if ((watch
== WATCH_RUN
) && (high_id
>= low_id
)) low_id
= high_id
+ 1;
644 if (watch
== WATCH_OFF
)
646 snprintf(str
, sizeof(str
) - 1, "-nil-\n");
647 SESSION_WRITE(s
, str
);
651 if (do_prompt
!= 2) do_prompt
= 0;
654 else if (pfmt
== PRINT_RAW
)
656 if (watch
== WATCH_RUN
)
658 snprintf(str
, sizeof(str
) - 1, "\n");
659 SESSION_WRITE(s
, str
);
663 out
= asl_list_to_string((asl_search_result_t
*)res
, &outlen
);
664 write(s
, out
, outlen
);
667 snprintf(str
, sizeof(str
) - 1, "\n");
668 SESSION_WRITE(s
, str
);
672 if (watch
== WATCH_RUN
)
674 snprintf(str
, sizeof(str
) - 1, "\n");
675 SESSION_WRITE(s
, str
);
678 for (i
= 0; i
< res
->count
; i
++)
680 out
= asl_format_message(res
->msg
[i
], ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &outlen
);
681 write(s
, out
, outlen
);
686 aslresponse_free(res
);
688 if (watch
== WATCH_LOCKDOWN_START
)
690 global
.lockdown_session_fd
= s
;
691 global
.watchers_active
++;
694 pthread_mutex_unlock(global
.work_queue_lock
);
702 if (s
== global
.lockdown_session_fd
) global
.lockdown_session_fd
= -1;
703 if (global
.watchers_active
> 0) global
.watchers_active
--;
708 if (watch
!= WATCH_OFF
) notify_cancel(wtoken
);
709 if (query
!= NULL
) asl_msg_release(query
);
714 remote_acceptmsg(int fd
, int tcp
)
717 int s
, status
, flags
, v
;
720 struct sockaddr_storage from
;
723 fromlen
= sizeof(struct sockaddr_un
);
724 if (tcp
== 1) fromlen
= sizeof(struct sockaddr_storage
);
726 memset(&from
, 0, sizeof(from
));
728 s
= accept(fd
, (struct sockaddr
*)&from
, &fromlen
);
731 asldebug("%s: accept: %s\n", MY_ID
, strerror(errno
));
735 flags
= fcntl(s
, F_GETFL
, 0);
736 flags
&= ~ O_NONBLOCK
;
737 status
= fcntl(s
, F_SETFL
, flags
);
740 asldebug("%s: fcntl: %s\n", MY_ID
, strerror(errno
));
746 setsockopt(s
, SOL_SOCKET
, SO_NOSIGPIPE
, &v
, sizeof(v
));
751 setsockopt(s
, IPPROTO_TCP
, TCP_NODELAY
, &flags
, sizeof(int));
754 sp
= (session_args_t
*)calloc(1, sizeof(session_args_t
));
757 asldebug("%s: malloc: %s\n", MY_ID
, strerror(errno
));
763 if ((tcp
== 0) && (global
.lockdown_session_fd
< 0))
765 sp
->flags
|= SESSION_FLAGS_LOCKDOWN
;
768 pthread_attr_init(&attr
);
769 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
770 pthread_create(&t
, &attr
, (void *(*)(void *))session
, (void *)sp
);
771 pthread_attr_destroy(&attr
);
777 remote_acceptmsg_local(int fd
)
779 return remote_acceptmsg(fd
, 0);
783 remote_acceptmsg_tcp(int fd
)
785 return remote_acceptmsg(fd
, 1);
789 remote_init_lockdown(void)
791 int status
, reuse
, fd
;
792 struct sockaddr_un local
;
794 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
797 asldebug("%s: socket: %s\n", MY_ID
, strerror(errno
));
802 status
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEPORT
, &reuse
, sizeof(int));
805 asldebug("%s: setsockopt: %s\n", MY_ID
, strerror(errno
));
810 /* make sure the lockdown directory exists */
811 mkdir(LOCKDOWN_PATH
, 0777);
813 memset(&local
, 0, sizeof(local
));
814 local
.sun_family
= AF_UNIX
;
815 strlcpy(local
.sun_path
, SYSLOG_SOCK_PATH
, sizeof(local
.sun_path
));
816 unlink(local
.sun_path
);
818 status
= bind(fd
, (struct sockaddr
*)&local
, sizeof(local
.sun_family
) + sizeof(local
.sun_path
));
822 asldebug("%s: bind: %s\n", MY_ID
, strerror(errno
));
827 status
= fcntl(fd
, F_SETFL
, O_NONBLOCK
);
830 asldebug("%s: fcntl: %s\n", MY_ID
, strerror(errno
));
835 status
= listen(fd
, 5);
838 asldebug("%s: listen: %s\n", MY_ID
, strerror(errno
));
843 chmod(SYSLOG_SOCK_PATH
, 0666);
845 aslevent_addfd(SOURCE_SESSION
, fd
, 0, remote_acceptmsg_local
, NULL
, NULL
);
850 remote_init_tcp(int family
)
852 int status
, reuse
, fd
;
853 struct sockaddr_in a4
;
854 struct sockaddr_in6 a6
;
858 fd
= socket(family
, SOCK_STREAM
, 0);
861 asldebug("%s: socket: %s\n", MY_ID
, strerror(errno
));
866 status
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEPORT
, &reuse
, sizeof(int));
869 asldebug("%s: setsockopt: %s\n", MY_ID
, strerror(errno
));
874 memset(&(a4
.sin_addr
), 0, sizeof(struct in_addr
));
875 a4
.sin_family
= AF_INET
;
876 a4
.sin_port
= htons(ASL_REMOTE_PORT
);
878 memset(&(a6
.sin6_addr
), 0, sizeof(struct in6_addr
));
879 a6
.sin6_family
= AF_INET6
;
880 a6
.sin6_port
= htons(ASL_REMOTE_PORT
);
882 s
= (struct sockaddr
*)&a4
;
883 len
= sizeof(struct sockaddr_in
);
885 if (family
== AF_INET6
)
887 s
= (struct sockaddr
*)&a6
;
888 len
= sizeof(struct sockaddr_in6
);
891 status
= bind(fd
, s
, len
);
894 asldebug("%s: bind: %s\n", MY_ID
, strerror(errno
));
899 status
= fcntl(fd
, F_SETFL
, O_NONBLOCK
);
902 asldebug("%s: fcntl: %s\n", MY_ID
, strerror(errno
));
907 status
= listen(fd
, 5);
910 asldebug("%s: listen: %s\n", MY_ID
, strerror(errno
));
915 aslevent_addfd(SOURCE_SESSION
, fd
, 0, remote_acceptmsg_tcp
, NULL
, NULL
);
922 asldebug("%s: init\n", MY_ID
);
925 rfdl
= remote_init_lockdown();
929 rfd4
= remote_init_tcp(AF_INET
);
933 rfd6
= remote_init_tcp(AF_INET6
);
944 aslevent_removefd(rfdl
);
952 aslevent_removefd(rfd4
);
960 aslevent_removefd(rfd6
);
973 return remote_init();