]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCDOpen.c
configd-24.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDOpen.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include <mach/mach.h>
24 #include <mach/mach_error.h>
25 #include <servers/bootstrap.h>
26
27 #include <SystemConfiguration/SCD.h>
28 #include "config.h" /* MiG generated file */
29 #include "SCDPrivate.h"
30
31
32 SCDSessionRef
33 _SCDSessionCreatePrivate()
34 {
35 SCDSessionRef newSession;
36 SCDSessionPrivateRef newPrivate;
37
38 /* allocate space */
39 newSession = (SCDSessionRef)CFAllocatorAllocate(NULL, sizeof(SCDSessionPrivate), 0);
40 newPrivate = (SCDSessionPrivateRef)newSession;
41
42 /* server side of the "configd" session */
43 newPrivate->server = MACH_PORT_NULL;
44
45 /* per-session flags */
46 SCDOptionSet(newSession, kSCDOptionDebug, SCDOptionGet(NULL, kSCDOptionDebug ));
47 SCDOptionSet(newSession, kSCDOptionVerbose, SCDOptionGet(NULL, kSCDOptionVerbose ));
48 SCDOptionSet(newSession, kSCDOptionIsLocked, FALSE);
49 SCDOptionSet(newSession, kSCDOptionUseSyslog, SCDOptionGet(NULL, kSCDOptionUseSyslog ));
50 SCDOptionSet(newSession, kSCDOptionUseCFRunLoop, SCDOptionGet(NULL, kSCDOptionUseCFRunLoop));
51
52 /* SCDKeys being watched */
53 newPrivate->keys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
54 newPrivate->reKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
55
56 /* No notifications pending */
57 newPrivate->notifyStatus = NotifierNotRegistered;
58
59 /* "client" information about active (notification) callback */
60 newPrivate->callbackFunction = NULL;
61 newPrivate->callbackArgument = NULL;
62 newPrivate->callbackPort = NULL;
63 newPrivate->callbackRunLoopSource = NULL; /* XXX */
64 newPrivate->callbackHelper = NULL;
65
66 /* "server" information associated with SCDNotifierInformViaMachPort(); */
67 newPrivate->notifyPort = MACH_PORT_NULL;
68 newPrivate->notifyPortIdentifier = 0;
69
70 /* "server" information associated with SCDNotifierInformViaFD(); */
71 newPrivate->notifyFile = -1;
72 newPrivate->notifyFileIdentifier = 0;
73
74 /* "server" information associated with SCDNotifierInformViaSignal(); */
75 newPrivate->notifySignal = 0;
76 newPrivate->notifySignalTask = TASK_NULL;
77
78 return newSession;
79 }
80
81
82 SCDStatus
83 SCDOpen(SCDSessionRef *session, CFStringRef name)
84 {
85 SCDSessionPrivateRef sessionPrivate;
86 kern_return_t status;
87 mach_port_t bootstrap_port;
88 mach_port_t server;
89 CFDataRef xmlName; /* serialized name */
90 xmlData_t myNameRef;
91 CFIndex myNameLen;
92 SCDStatus scd_status;
93
94 SCDLog(LOG_DEBUG, CFSTR("SCDOpen:"));
95 SCDLog(LOG_DEBUG, CFSTR(" name = %@"), name);
96
97 /*
98 * allocate and initialize a new session
99 */
100 sessionPrivate = (SCDSessionPrivateRef)_SCDSessionCreatePrivate();
101 *session = (SCDSessionRef)sessionPrivate;
102
103 status = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
104 if (status != KERN_SUCCESS) {
105 SCDLog(LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
106 CFAllocatorDeallocate(NULL, sessionPrivate);
107 *session = NULL;
108 return SCD_NOSERVER;
109 }
110
111 status = bootstrap_look_up(bootstrap_port, SCD_SERVER, &server);
112 switch (status) {
113 case BOOTSTRAP_SUCCESS :
114 /* service currently registered, "a good thing" (tm) */
115 break;
116 case BOOTSTRAP_UNKNOWN_SERVICE :
117 /* service not currently registered, try again later */
118 CFAllocatorDeallocate(NULL, sessionPrivate);
119 *session = NULL;
120 return SCD_NOSERVER;
121 break;
122 default :
123 #ifdef DEBUG
124 SCDLog(LOG_DEBUG, CFSTR("bootstrap_status: %s"), mach_error_string(status));
125 #endif /* DEBUG */
126 CFAllocatorDeallocate(NULL, sessionPrivate);
127 *session = NULL;
128 return SCD_NOSERVER;
129 }
130
131 /* serialize the name */
132 xmlName = CFPropertyListCreateXMLData(NULL, name);
133 myNameRef = (xmlData_t)CFDataGetBytePtr(xmlName);
134 myNameLen = CFDataGetLength(xmlName);
135
136 /* open a new session with the server */
137 status = configopen(server, myNameRef, myNameLen, &sessionPrivate->server, (int *)&scd_status);
138
139 /* clean up */
140 CFRelease(xmlName);
141
142 if (status != KERN_SUCCESS) {
143 if (status != MACH_SEND_INVALID_DEST)
144 SCDLog(LOG_DEBUG, CFSTR("configopen(): %s"), mach_error_string(status));
145 CFAllocatorDeallocate(NULL, sessionPrivate);
146 *session = NULL;
147 return SCD_NOSERVER;
148 }
149
150 SCDLog(LOG_DEBUG, CFSTR(" server port = %d"), sessionPrivate->server);
151 return scd_status;
152 }