2 * Copyright (c) 2005 Apple Computer, 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@
23 #include <Security/Authorization.h>
24 #include <Security/AuthorizationTags.h>
25 #include <Security/AuthSession.h>
26 #include <sys/types.h>
27 #include <sys/select.h>
28 #include <sys/event.h>
29 #include <sys/socket.h>
48 static void find_fds(launch_data_t o
, const char *key
__attribute__((unused
)), void *context
__attribute__((unused
)))
54 switch (launch_data_get_type(o
)) {
56 fd
= launch_data_get_fd(o
);
59 fcntl(fd
, F_SETFD
, 1);
60 EV_SET(&kev
, fd
, EVFILT_READ
, EV_ADD
, 0, 0, NULL
);
61 if (kevent(kq
, &kev
, 1, NULL
, 0, NULL
) == -1)
62 syslog(LOG_DEBUG
, "kevent(%d): %m", fd
);
64 case LAUNCH_DATA_ARRAY
:
65 for (i
= 0; i
< launch_data_array_get_count(o
); i
++)
66 find_fds(launch_data_array_get_index(o
, i
), NULL
, NULL
);
68 case LAUNCH_DATA_DICTIONARY
:
69 launch_data_dict_iterate(o
, find_fds
, NULL
);
76 int main(int argc
__attribute__((unused
)), char *argv
[])
78 struct timespec timeout
= { 10, 0 };
79 struct sockaddr_storage ss
;
80 socklen_t slen
= sizeof(ss
);
82 int r
, ec
= EXIT_FAILURE
;
83 launch_data_t tmp
, resp
, msg
= launch_data_alloc(LAUNCH_DATA_STRING
);
84 const char *prog
= argv
[1];
85 bool w
= false, dupstdout
= true, dupstderr
= true;
87 launch_data_set_string(msg
, LAUNCH_KEY_CHECKIN
);
89 openlog(getprogname(), LOG_PERROR
|LOG_PID
|LOG_CONS
, LOG_LAUNCHD
);
93 if ((resp
= launch_msg(msg
)) == NULL
) {
94 syslog(LOG_ERR
, "launch_msg(%s): %m", LAUNCH_KEY_CHECKIN
);
98 launch_data_free(msg
);
100 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_SOCKETS
);
102 find_fds(tmp
, NULL
, NULL
);
104 syslog(LOG_ERR
, "No FDs found to answer requests on!");
108 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_TIMEOUT
);
110 timeout
.tv_sec
= launch_data_get_integer(tmp
);
112 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_PROGRAM
);
114 prog
= launch_data_get_string(tmp
);
116 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_INETDCOMPATIBILITY
);
118 tmp
= launch_data_dict_lookup(tmp
, LAUNCH_JOBINETDCOMPATIBILITY_WAIT
);
120 w
= launch_data_get_bool(tmp
);
123 if (launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_STANDARDOUTPATH
))
126 if (launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_STANDARDERRORPATH
))
130 signal(SIGCHLD
, SIG_IGN
);
133 if ((r
= kevent(kq
, NULL
, 0, &kev
, 1, &timeout
)) == -1) {
134 syslog(LOG_DEBUG
, "kevent(): %m");
142 dup2(kev
.ident
, STDIN_FILENO
);
144 dup2(kev
.ident
, STDOUT_FILENO
);
146 dup2(kev
.ident
, STDERR_FILENO
);
147 execv(prog
, argv
+ 1);
148 syslog(LOG_ERR
, "execv(): %m");
152 if ((r
= accept(kev
.ident
, (struct sockaddr
*)&ss
, &slen
)) == -1) {
153 if (errno
== EWOULDBLOCK
)
155 syslog(LOG_DEBUG
, "accept(): %m");
158 char fromhost
[NI_MAXHOST
];
159 char fromport
[NI_MAXSERV
];
162 gni_r
= getnameinfo((struct sockaddr
*)&ss
, slen
,
163 fromhost
, sizeof(fromhost
),
164 fromport
, sizeof(fromport
),
165 NI_NUMERICHOST
| NI_NUMERICSERV
);
168 syslog(LOG_WARNING
, "%s: getnameinfo(): %s", prog
, gai_strerror(gni_r
));
170 syslog(LOG_INFO
, "%s: Connection from: %s on port: %s", prog
, fromhost
, fromport
);
175 syslog(LOG_WARNING
, "fork(): %m");
184 if ((tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_SESSIONCREATE
)) && launch_data_get_bool(tmp
)) {
186 OSStatus scr
= SessionCreate(0, 0);
188 syslog(LOG_NOTICE
, "%s: SessionCreate() failed: %d", prog
, scr
);
190 syslog(LOG_NOTICE
, "%s: SessionCreate == NULL!", prog
);
193 fcntl(r
, F_SETFL
, 0);
194 dup2(r
, STDIN_FILENO
);
196 dup2(r
, STDOUT_FILENO
);
198 dup2(r
, STDERR_FILENO
);
199 signal(SIGCHLD
, SIG_DFL
);
200 execv(prog
, argv
+ 1);
201 syslog(LOG_ERR
, "execv(): %m");