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 3 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, see <http://www.gnu.org/licenses/>.
22 #include "smb_launchd.h"
24 /* launchd source code and documentation is available here:
25 * http://launchd.macosforge.org/
28 #if defined(WITH_LAUNCHD_SUPPORT)
33 typedef void (*launchd_iterator)(launch_data_t, const char*, void*);
35 #define LAUNCHD_TRACE_LEVEL 10
37 void smb_launchd_checkout(struct smb_launch_info *linfo)
39 talloc_free(linfo->socket_list);
42 static void pull_launch_sockets(launch_data_t key,
44 struct smb_launch_info *linfo)
46 launch_data_type_t type;
48 type = launch_data_get_type(key);
49 DEBUG(LAUNCHD_TRACE_LEVEL,
50 ("Searching item name='%s' type=%d for sockets\n",
51 name ? name : "", (int)type));
55 if (!linfo->socket_list) {
56 /* We are counting the number of sockets. */
59 /* We are collecting the socket fds. */
60 int fd = launch_data_get_fd(key);
62 linfo->socket_list[linfo->num_sockets] = fd;
64 DEBUG(LAUNCHD_TRACE_LEVEL,
65 ("Added fd=%d to launchd set\n", fd));
68 case LAUNCH_DATA_ARRAY:
73 for (i = 0; i < launch_data_array_get_count(key); ++i) {
74 item = launch_data_array_get_index(key, i);
75 pull_launch_sockets(item, name, linfo);
79 case LAUNCH_DATA_DICTIONARY:
80 launch_data_dict_iterate(key,
81 (launchd_iterator)pull_launch_sockets, linfo);
88 BOOL smb_launchd_checkin_names(struct smb_launch_info *linfo, ...)
93 BOOL is_launchd = False;
97 msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
98 resp = launch_msg(msg);
100 /* IPC to launchd failed. */
101 launch_data_free(msg);
105 if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
106 errno = launch_data_get_errno(resp);
110 /* At this point, we know we are running under launchd. */
111 linfo->idle_timeout_secs = 600;
114 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
115 linfo->idle_timeout_secs = launch_data_get_integer(item);
118 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) {
120 const char * sockname = NULL;
121 launch_data_t sockdata;
124 /* Figure out the maximum number of sockets. */
125 va_start(args, linfo);
126 while ((sockname = va_arg(args, const char *))) {
131 DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n",
132 linfo->num_sockets));
134 if (launch_data_dict_get_count(item) < count) {
135 DEBUG(0, ("%d launchd sockets requested, "
136 "but only %d are available\n",
137 count, launch_data_dict_get_count(item)));
140 linfo->socket_list = TALLOC_ARRAY(NULL, int, count);
141 if (linfo->socket_list == NULL) {
145 linfo->num_sockets = 0;
146 va_start(args, linfo);
147 while ((sockname = va_arg(args, const char *))) {
148 sockdata = launch_data_dict_lookup(item, sockname);
150 pull_launch_sockets(sockdata, sockname, linfo);
151 DEBUG(LAUNCHD_TRACE_LEVEL,
152 ("Added launchd socket \"%s\"\n", sockname));
155 SMB_ASSERT(count >= linfo->num_sockets);
159 launch_data_free(msg);
160 launch_data_free(resp);
164 BOOL smb_launchd_checkin(struct smb_launch_info *linfo)
169 BOOL is_launchd = False;
173 msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
174 resp = launch_msg(msg);
176 /* IPC to launchd failed. */
177 launch_data_free(msg);
181 if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
182 errno = launch_data_get_errno(resp);
186 /* At this point, we know we are running under launchd. */
187 linfo->idle_timeout_secs = 600;
190 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
191 linfo->idle_timeout_secs = launch_data_get_integer(item);
194 if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) {
197 pull_launch_sockets(item, NULL, linfo);
198 DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n",
199 linfo->num_sockets));
201 count = linfo->num_sockets;
202 linfo->socket_list = TALLOC_ARRAY(NULL, int, count);
203 if (linfo->socket_list == NULL) {
207 linfo->num_sockets = 0;
208 pull_launch_sockets(item, NULL, linfo);
210 DEBUG(LAUNCHD_TRACE_LEVEL, ("Added %d launchd sockets\n",
211 linfo->num_sockets));
213 SMB_ASSERT(count == linfo->num_sockets);
217 launch_data_free(msg);
218 launch_data_free(resp);
222 #else /* defined(WITH_LAUNCHD_SUPPORT) */
224 BOOL smb_launchd_checkin(struct smb_launch_info * UNUSED(linfo))
230 BOOL smb_launchd_checkin_names(struct smb_launch_info * UNUSED(linfo), ...)
236 void smb_launchd_checkout(struct smb_launch_info * UNUSED(linfo))
240 #endif /* defined(WITH_LAUNCHD_SUPPORT) */