]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/configd_server.c
configd-1061.0.2.tar.gz
[apple/configd.git] / configd.tproj / configd_server.c
1 /*
2 * Copyright (c) 2000-2011, 2013, 2015-2017, 2019 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 /*
25 * Modification History
26 *
27 * March 9, 2004 Allan Nathanson <ajn@apple.com>
28 * - add DNS configuration server
29 *
30 * June 1, 2001 Allan Nathanson <ajn@apple.com>
31 * - public API conversion
32 *
33 * March 24, 2000 Allan Nathanson <ajn@apple.com>
34 * - initial revision
35 */
36
37 #include <TargetConditionals.h>
38 #include <sysexits.h>
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <servers/bootstrap.h>
42
43 #include "configd.h"
44 #include "configd_server.h"
45 #include "session.h"
46
47 /* MiG generated externals and functions */
48 extern struct mig_subsystem _config_subsystem;
49
50
51 __private_extern__
52 void
53 server_mach_channel_handler(void *context, // serverSessionRef
54 dispatch_mach_reason_t reason,
55 dispatch_mach_msg_t message,
56 mach_error_t error)
57 {
58 #pragma unused(error)
59 bool ok;
60 serverSessionRef session = (serverSessionRef)context;
61
62 static const struct mig_subsystem * const subsystems[] = {
63 (mig_subsystem_t)&_config_subsystem,
64 };
65
66 switch (reason) {
67 case DISPATCH_MACH_MESSAGE_RECEIVED:
68 ok = dispatch_mach_mig_demux(context, subsystems, 1, message);
69 if (ok) {
70 /*
71 * the dispatch mach message has been consumed as per
72 * usual MIG rules. Check for, and if necessary, push
73 * out [SCDynamicStore] change notifications to other
74 * processes.
75 */
76 pushNotifications();
77 } else {
78 /*
79 * no subsystem claimed the message, destroy it
80 */
81 mach_msg_destroy(dispatch_mach_msg_get_msg(message, NULL));
82 }
83 break;
84
85 case DISPATCH_MACH_NO_SENDERS:
86 __MACH_PORT_DEBUG(TRUE, "*** server_mach_channel_handler DISPATCH_MACH_NO_SENDERS", session->key);
87 closeSession(session);
88 break;
89
90 case DISPATCH_MACH_CANCELED:
91 __MACH_PORT_DEBUG(TRUE, "*** server_mach_channel_handler DISPATCH_MACH_CANCELED", session->key);
92 cleanupSession(session);
93 break;
94
95 default:
96 break;
97 }
98
99 return;
100 }
101
102
103 __private_extern__
104 dispatch_workloop_t
105 server_queue(void)
106 {
107 static dispatch_once_t once;
108 static dispatch_workloop_t workloop;
109
110 dispatch_once(&once, ^{
111 workloop = dispatch_workloop_create_inactive("configd/SCDynamicStore");
112 dispatch_set_qos_class_fallback(workloop, QOS_CLASS_UTILITY);
113 dispatch_activate(workloop);
114 });
115
116 return workloop;
117 }
118
119
120 __private_extern__
121 void
122 server_init()
123 {
124 char *service_name;
125 mach_port_t service_port = MACH_PORT_NULL;
126 kern_return_t status;
127
128 service_name = getenv("SCD_SERVER");
129 if (service_name == NULL) {
130 service_name = SCD_SERVER;
131 }
132
133 /* Check "configd" server status */
134 status = bootstrap_check_in(bootstrap_port, service_name, &service_port);
135 switch (status) {
136 case BOOTSTRAP_SUCCESS :
137 /* if we are being [re-]started by launchd */
138 break;
139 case BOOTSTRAP_NOT_PRIVILEGED :
140 /* if another instance of the server is starting */
141 SC_log(LOG_ERR, "'%s' server already starting", service_name);
142 exit (EX_UNAVAILABLE);
143 case BOOTSTRAP_SERVICE_ACTIVE :
144 /* if another instance of the server is active */
145 SC_log(LOG_ERR, "'%s' server already active", service_name);
146 exit (EX_UNAVAILABLE);
147 default :
148 SC_log(LOG_ERR, "server_init bootstrap_check_in(..., '%s', ...) failed: %s",
149 service_name,
150 bootstrap_strerror(status));
151 exit (EX_UNAVAILABLE);
152 }
153
154 /* Create the primary / new connection port and backing session */
155 addServer(service_port);
156
157 return;
158 }