1/* 2 * Copyright (c) 2004-2011 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 <TargetConditionals.h> 25 26#include <sys/types.h> 27#include <sys/stat.h> 28#include <sys/socket.h> 29#include <sys/fcntl.h> 30#include <sys/un.h> 31#include <sys/uio.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <string.h> 35#include <unistd.h> 36#include <errno.h> 37#include "daemon.h" 38 39#define BSD_SOCKET_NAME "BSDSystemLogger" 40#define MY_ID "bsd_in" 41#define MAXLINE 4096 42 43static int sock = -1; 44static dispatch_source_t in_src; 45static dispatch_queue_t in_queue; 46 47void 48bsd_in_acceptmsg(int fd) 49{ 50 uint32_t len; 51 int n; 52 char line[MAXLINE]; 53 struct sockaddr_un sun; 54 aslmsg m; 55 56 len = sizeof(struct sockaddr_un); 57 n = recvfrom(fd, line, MAXLINE, 0, (struct sockaddr *)&sun, &len); 58 59 if (n <= 0) return; 60 61 line[n] = '\0'; 62 63 m = asl_input_parse(line, n, NULL, SOURCE_BSD_SOCKET); 64 process_message(m, SOURCE_BSD_SOCKET); 65} 66 67int 68bsd_in_init() 69{ 70 int rbufsize; 71 int len; 72 launch_data_t sockets_dict, fd_array, fd_dict; 73 static dispatch_once_t once; 74 75#if TARGET_IPHONE_SIMULATOR 76 const char *_PATH_SYSLOG_IN = getenv("IOS_SIMULATOR_SYSLOG_SOCKET"); 77#endif 78 79 dispatch_once(&once, ^{ 80 in_queue = dispatch_queue_create(MY_ID, NULL); 81 }); 82 83 asldebug("%s: init\n", MY_ID); 84 if (sock >= 0) return -1; 85 86 if (global.launch_dict == NULL) 87 { 88 asldebug("%s: launchd dict is NULL\n", MY_ID); 89 return -1; 90 } 91 92 sockets_dict = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_SOCKETS); 93 if (sockets_dict == NULL) 94 { 95 asldebug("%s: launchd lookup of LAUNCH_JOBKEY_SOCKETS failed\n", MY_ID); 96 return -1; 97 } 98 99 fd_array = launch_data_dict_lookup(sockets_dict, BSD_SOCKET_NAME); 100 if (fd_array == NULL) 101 { 102 asldebug("%s: launchd lookup of BSD_SOCKET_NAME failed\n", MY_ID); 103 return -1; 104 } 105 106 len = launch_data_array_get_count(fd_array); 107 if (len <= 0) 108 { 109 asldebug("%s: launchd fd array is empty\n", MY_ID); 110 return -1; 111 } 112 113 if (len > 1) 114 { 115 asldebug("%s: warning! launchd fd array has %d sockets\n", MY_ID, len); 116 } 117 118 fd_dict = launch_data_array_get_index(fd_array, 0); 119 if (fd_dict == NULL) 120 { 121 asldebug("%s: launchd file discriptor array element 0 is NULL\n", MY_ID); 122 return -1; 123 } 124 125 sock = launch_data_get_fd(fd_dict); 126 127 rbufsize = 128 * 1024; 128 len = sizeof(rbufsize); 129 130 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rbufsize, len) < 0) 131 { 132 asldebug("%s: couldn't set receive buffer size for socket %d (%s): %s\n", MY_ID, sock, _PATH_SYSLOG_IN, strerror(errno)); 133 close(sock); 134 sock = -1; 135 return -1; 136 } 137 138 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) 139 { 140 asldebug("%s: couldn't set O_NONBLOCK for socket %d (%s): %s\n", MY_ID, sock, _PATH_SYSLOG_IN, strerror(errno)); 141 close(sock); 142 sock = -1; 143 return -1; 144 } 145 146 in_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)sock, 0, in_queue); 147 dispatch_source_set_event_handler(in_src, ^{ bsd_in_acceptmsg(sock); }); 148 149 dispatch_resume(in_src); 150 return 0; 151} 152 153int 154bsd_in_close(void) 155{ 156 if (sock < 0) return 1; 157 158 dispatch_source_cancel(in_src); 159 dispatch_release(in_src); 160 in_src = NULL; 161 162 close(sock); 163 sock = -1; 164 165 return 0; 166} 167 168int 169bsd_in_reset(void) 170{ 171 return 0; 172} 173