]> git.saurik.com Git - apple/launchd.git/blobdiff - launchd/src/launchproxy.c
launchd-329.3.1.tar.gz
[apple/launchd.git] / launchd / src / launchproxy.c
index 3149b378941e97795c5dcd77519ea287e3a6e702..3a909359607182c8f7dca676f337b54b186724af 100644 (file)
@@ -1,28 +1,28 @@
 /*
  * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_APACHE_LICENSE_HEADER_START@
  * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_APACHE_LICENSE_HEADER_END@
  */
+#include "config.h"
+#if HAVE_SECURITY
 #include <Security/Authorization.h>
 #include <Security/AuthorizationTags.h>
 #include <Security/AuthSession.h>
+#endif
 #include <sys/types.h>
 #include <sys/select.h>
 #include <sys/event.h>
 #include <getopt.h>
 #include <signal.h>
 #include <netdb.h>
-#include <assert.h>
 
 #include "launch.h"
 
-#if __GNUC__ >= 4
+#if __GNUC__ >= 4 && HAVE_SECURITY
 OSStatus SessionCreate(SessionCreationFlags flags, SessionAttributeBits attributes) __attribute__((weak));
 #endif
 
@@ -52,36 +51,37 @@ static int kq = 0;
 
 static void find_fds(launch_data_t o, const char *key __attribute__((unused)), void *context __attribute__((unused)))
 {
-        struct kevent kev;
-        size_t i;
+       struct kevent kev;
+       size_t i;
        int fd;
 
-        switch (launch_data_get_type(o)) {
-        case LAUNCH_DATA_FD:
+       switch (launch_data_get_type(o)) {
+       case LAUNCH_DATA_FD:
                fd = launch_data_get_fd(o);
                if (-1 == fd)
                        break;
-               assert(fcntl(fd, F_SETFD, 1) != -1);
+               fcntl(fd, F_SETFD, 1);
                EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
-               assert(kevent(kq, &kev, 1, NULL, 0, NULL) != -1);
-                break;
-        case LAUNCH_DATA_ARRAY:
-                for (i = 0; i < launch_data_array_get_count(o); i++)
-                        find_fds(launch_data_array_get_index(o, i), NULL, NULL);
-                break;
-        case LAUNCH_DATA_DICTIONARY:
-                launch_data_dict_iterate(o, find_fds, NULL);
-                break;
-        default:
-                break;
-        }
+               if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1)
+                       syslog(LOG_DEBUG, "kevent(%d): %m", fd);
+               break;
+       case LAUNCH_DATA_ARRAY:
+               for (i = 0; i < launch_data_array_get_count(o); i++)
+                       find_fds(launch_data_array_get_index(o, i), NULL, NULL);
+               break;
+       case LAUNCH_DATA_DICTIONARY:
+               launch_data_dict_iterate(o, find_fds, NULL);
+               break;
+       default:
+               break;
+       }
 }
 
 int main(int argc __attribute__((unused)), char *argv[])
 {
-       struct timespec timeout = { 120, 0 };
+       struct timespec timeout = { 10, 0 };
        struct sockaddr_storage ss;
-       socklen_t slen = sizeof(ss);
+       socklen_t slen = (socklen_t)sizeof ss;
        struct kevent kev;
        int r, ec = EXIT_FAILURE;
        launch_data_t tmp, resp, msg = launch_data_alloc(LAUNCH_DATA_STRING);
@@ -111,7 +111,7 @@ int main(int argc __attribute__((unused)), char *argv[])
 
        tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT);
        if (tmp)
-               timeout.tv_sec = launch_data_get_integer(tmp);
+               timeout.tv_sec = (int)launch_data_get_integer(tmp);
 
        tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_PROGRAM);
        if (tmp)
@@ -143,40 +143,47 @@ int main(int argc __attribute__((unused)), char *argv[])
                }
 
                if (w) {
-                       assert(dup2(kev.ident, STDIN_FILENO) != -1);
+                       dup2((int)kev.ident, STDIN_FILENO);
                        if (dupstdout)
-                               assert(dup2(kev.ident, STDOUT_FILENO) != -1);
+                               dup2((int)kev.ident, STDOUT_FILENO);
                        if (dupstderr)
-                               assert(dup2(kev.ident, STDERR_FILENO) != -1);
+                               dup2((int)kev.ident, STDERR_FILENO);
                        execv(prog, argv + 1);
                        syslog(LOG_ERR, "execv(): %m");
                        exit(EXIT_FAILURE);
                }
 
-               if ((r = accept(kev.ident, (struct sockaddr *)&ss, &slen)) == -1) {
+               if ((r = accept((int)kev.ident, (struct sockaddr *)&ss, &slen)) == -1) {
                        if (errno == EWOULDBLOCK)
                                continue;
-                       syslog(LOG_DEBUG, "accept(): %m");
+                       syslog(LOG_WARNING, "accept(): %m");
                        goto out;
                } else {
-                       char fromhost[NI_MAXHOST];
-                       char fromport[NI_MAXSERV];
-                       int gni_r;
-
-                       gni_r = getnameinfo((struct sockaddr *)&ss, slen,
-                                       fromhost, sizeof(fromhost),
-                                       fromport, sizeof(fromport),
-                                       NI_NUMERICHOST | NI_NUMERICSERV);
-
-                       if (gni_r) {
-                               syslog(LOG_WARNING, "%s: getnameinfo(): %s", prog, gai_strerror(gni_r));
+                       if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
+                               char fromhost[NI_MAXHOST];
+                               char fromport[NI_MAXSERV];
+                               int gni_r;
+
+                               gni_r = getnameinfo((struct sockaddr *)&ss, slen,
+                                               fromhost, (socklen_t) sizeof fromhost,
+                                               fromport, (socklen_t) sizeof fromport,
+                                               NI_NUMERICHOST | NI_NUMERICSERV);
+
+                               if (gni_r) {
+                                       syslog(LOG_WARNING, "%s: getnameinfo(): %s", prog, gai_strerror(gni_r));
+                               } else {
+                                       syslog(LOG_INFO, "%s: Connection from: %s on port: %s", prog, fromhost, fromport);
+                               }
                        } else {
-                               syslog(LOG_INFO, "%s: Connection from: %s on port: %s", prog, fromhost, fromport);
+                               syslog(LOG_WARNING, "%s: getnameinfo() only supports IPv4/IPv6. Connection from address family: %u", prog, ss.ss_family);
                        }
 
                        switch (fork()) {
                        case -1:
                                syslog(LOG_WARNING, "fork(): %m");
+                               if( errno != ENOMEM ) {
+                                       continue;
+                               }
                                goto out;
                        case 0:
                                break;
@@ -185,6 +192,9 @@ int main(int argc __attribute__((unused)), char *argv[])
                                continue;
                        }
 
+                       setpgid(0, 0);
+
+#if HAVE_SECURITY
                        if ((tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SESSIONCREATE)) && launch_data_get_bool(tmp)) {
                                if (SessionCreate) {
                                        OSStatus scr = SessionCreate(0, 0);
@@ -194,17 +204,18 @@ int main(int argc __attribute__((unused)), char *argv[])
                                        syslog(LOG_NOTICE, "%s: SessionCreate == NULL!", prog);
                                }
                        }
-                       assert(fcntl(r, F_SETFL, 0) != -1);
-                       assert(dup2(r, STDIN_FILENO) != -1);
+#endif
+                       fcntl(r, F_SETFL, 0);
+                       fcntl(r, F_SETFD, 1);
+                       dup2(r, STDIN_FILENO);
                        if (dupstdout)
-                               assert(dup2(r, STDOUT_FILENO) != -1);
+                               dup2(r, STDOUT_FILENO);
                        if (dupstderr)
-                               assert(dup2(r, STDERR_FILENO) != -1);
-                       assert(close(r) != -1);
+                               dup2(r, STDERR_FILENO);
                        signal(SIGCHLD, SIG_DFL);
                        execv(prog, argv + 1);
                        syslog(LOG_ERR, "execv(): %m");
-                       _exit(EXIT_FAILURE);
+                       exit(EXIT_FAILURE);
                }
        }