r25068: Older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for every opcode on the
[Samba.git] / source / lib / launchd.c
blob2c3f7cac89fdeb0cd8380ca41c64575ea742d912
1 /*
2 Unix SMB/CIFS implementation.
3 Launchd integration wrapper API
5 Copyright (C) 2007 James Peach
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
23 #include "smb_launchd.h"
25 /* launchd source code and documentation is available here:
26 * http://launchd.macosforge.org/
29 #if defined(WITH_LAUNCHD_SUPPORT)
31 #include <launch.h>
32 #include <stdarg.h>
34 typedef void (*launchd_iterator)(launch_data_t, const char*, void*);
36 #define LAUNCHD_TRACE_LEVEL 10
38 void smb_launchd_checkout(struct smb_launch_info *linfo)
40 talloc_free(linfo->socket_list);
43 static void pull_launch_sockets(launch_data_t key,
44 const char *name,
45 struct smb_launch_info *linfo)
47 launch_data_type_t type;
49 type = launch_data_get_type(key);
50 DEBUG(LAUNCHD_TRACE_LEVEL,
51 ("Searching item name='%s' type=%d for sockets\n",
52 name ? name : "", (int)type));
54 switch (type) {
55 case LAUNCH_DATA_FD:
56 if (!linfo->socket_list) {
57 /* We are counting the number of sockets. */
58 linfo->num_sockets++;
59 } else {
60 /* We are collecting the socket fds. */
61 int fd = launch_data_get_fd(key);
63 linfo->socket_list[linfo->num_sockets] = fd;
64 linfo->num_sockets++;
65 DEBUG(LAUNCHD_TRACE_LEVEL,
66 ("Added fd=%d to launchd set\n", fd));
68 return;
69 case LAUNCH_DATA_ARRAY:
71 int i;
72 launch_data_t item;
74 for (i = 0; i < launch_data_array_get_count(key); ++i) {
75 item = launch_data_array_get_index(key, i);
76 pull_launch_sockets(item, name, linfo);
78 return;
80 case LAUNCH_DATA_DICTIONARY:
81 launch_data_dict_iterate(key,
82 (launchd_iterator)pull_launch_sockets, linfo);
83 return;
84 default:
85 return;
89 BOOL smb_launchd_checkin_names(struct smb_launch_info *linfo, ...)
91 launch_data_t msg;
92 launch_data_t resp;
93 launch_data_t item;
94 BOOL is_launchd = False;
96 ZERO_STRUCTP(linfo);
98 msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
99 resp = launch_msg(msg);
100 if (resp == NULL) {
101 /* IPC to launchd failed. */
102 launch_data_free(msg);
103 return is_launchd;
106 if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
107 errno = launch_data_get_errno(resp);
108 goto done;
111 /* At this point, we know we are running under launchd. */
112 linfo->idle_timeout_secs = 600;
113 is_launchd = True;
115 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
116 linfo->idle_timeout_secs = launch_data_get_integer(item);
119 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) {
120 int count = 0;
121 const char * sockname = NULL;
122 launch_data_t sockdata;
123 va_list args;
125 /* Figure out the maximum number of sockets. */
126 va_start(args, linfo);
127 while ((sockname = va_arg(args, const char *))) {
128 ++count;
130 va_end(args);
132 DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n",
133 linfo->num_sockets));
135 if (launch_data_dict_get_count(item) < count) {
136 DEBUG(0, ("%d launchd sockets requested, "
137 "but only %d are available\n",
138 count, launch_data_dict_get_count(item)));
141 linfo->socket_list = TALLOC_ARRAY(NULL, int, count);
142 if (linfo->socket_list == NULL) {
143 goto done;
146 linfo->num_sockets = 0;
147 va_start(args, linfo);
148 while ((sockname = va_arg(args, const char *))) {
149 sockdata = launch_data_dict_lookup(item, sockname);
151 pull_launch_sockets(sockdata, sockname, linfo);
152 DEBUG(LAUNCHD_TRACE_LEVEL,
153 ("Added launchd socket \"%s\"\n", sockname));
156 SMB_ASSERT(count >= linfo->num_sockets);
159 done:
160 launch_data_free(msg);
161 launch_data_free(resp);
162 return is_launchd;
165 BOOL smb_launchd_checkin(struct smb_launch_info *linfo)
167 launch_data_t msg;
168 launch_data_t resp;
169 launch_data_t item;
170 BOOL is_launchd = False;
172 ZERO_STRUCTP(linfo);
174 msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
175 resp = launch_msg(msg);
176 if (resp == NULL) {
177 /* IPC to launchd failed. */
178 launch_data_free(msg);
179 return is_launchd;
182 if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
183 errno = launch_data_get_errno(resp);
184 goto done;
187 /* At this point, we know we are running under launchd. */
188 linfo->idle_timeout_secs = 600;
189 is_launchd = True;
191 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
192 linfo->idle_timeout_secs = launch_data_get_integer(item);
195 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) {
196 int count;
198 pull_launch_sockets(item, NULL, linfo);
199 DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n",
200 linfo->num_sockets));
202 count = linfo->num_sockets;
203 linfo->socket_list = TALLOC_ARRAY(NULL, int, count);
204 if (linfo->socket_list == NULL) {
205 goto done;
208 linfo->num_sockets = 0;
209 pull_launch_sockets(item, NULL, linfo);
211 DEBUG(LAUNCHD_TRACE_LEVEL, ("Added %d launchd sockets\n",
212 linfo->num_sockets));
214 SMB_ASSERT(count == linfo->num_sockets);
217 done:
218 launch_data_free(msg);
219 launch_data_free(resp);
220 return is_launchd;
223 #else /* defined(WITH_LAUNCHD_SUPPORT) */
225 BOOL smb_launchd_checkin(struct smb_launch_info * UNUSED(linfo))
227 ZERO_STRUCTP(linfo);
228 return False;
231 BOOL smb_launchd_checkin_names(struct smb_launch_info * UNUSED(linfo), ...)
233 ZERO_STRUCTP(linfo);
234 return False;
237 void smb_launchd_checkout(struct smb_launch_info * UNUSED(linfo))
241 #endif /* defined(WITH_LAUNCHD_SUPPORT) */