]> git.saurik.com Git - apple/launchd.git/blob - launchd/src/launchdebugd.c
7d746c45cb7090c30be45edbe3aa663c48976113
[apple/launchd.git] / launchd / src / launchdebugd.c
1 /*
2 * Copyright (c) 2005 Apple Computer, 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 #include <sys/types.h>
24 #include <sys/event.h>
25 #include <sys/socket.h>
26 #include <sys/time.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdbool.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <syslog.h>
35 #include <libgen.h>
36
37 #include "launch.h"
38
39 static void launch_print_obj(launch_data_t o, FILE *w);
40
41 static int kq = -1;
42
43 static void find_fds(launch_data_t o, const char *key __attribute__((unused)), void *context __attribute__((unused)))
44 {
45 struct kevent kev;
46 size_t i;
47
48 switch (launch_data_get_type(o)) {
49 case LAUNCH_DATA_FD:
50 EV_SET(&kev, launch_data_get_fd(o), EVFILT_READ, EV_ADD, 0, 0, NULL);
51 if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1)
52 syslog(LOG_DEBUG, "kevent(): %m");
53 break;
54 case LAUNCH_DATA_ARRAY:
55 for (i = 0; i < launch_data_array_get_count(o); i++)
56 find_fds(launch_data_array_get_index(o, i), NULL, NULL);
57 break;
58 case LAUNCH_DATA_DICTIONARY:
59 launch_data_dict_iterate(o, find_fds, NULL);
60 break;
61 default:
62 break;
63 }
64 }
65
66 int main(void)
67 {
68 int r;
69 struct sockaddr_storage ss;
70 socklen_t slen = sizeof(ss);
71 struct kevent kev;
72 FILE *c;
73 launch_data_t tmp, resp, msg = launch_data_alloc(LAUNCH_DATA_STRING);
74
75 kq = kqueue();
76
77 launch_data_set_string(msg, LAUNCH_KEY_CHECKIN);
78
79 openlog(getprogname(), LOG_PERROR|LOG_PID|LOG_CONS, LOG_DAEMON);
80
81 if ((resp = launch_msg(msg)) == NULL) {
82 syslog(LOG_ERR, "launch_msg(\"" LAUNCH_KEY_CHECKIN "\"): %m");
83 exit(EXIT_FAILURE);
84 }
85
86 tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS);
87 if (tmp) {
88 find_fds(tmp, NULL, NULL);
89 } else {
90 syslog(LOG_ERR, "No FDs found to answer requests on!");
91 exit(EXIT_FAILURE);
92 }
93
94 launch_data_free(resp);
95
96 if ((r = kevent(kq, NULL, 0, &kev, 1, NULL)) == -1) {
97 syslog(LOG_ERR, "kevent(): %m");
98 exit(EXIT_FAILURE);
99 } else if (r == 0) {
100 exit(EXIT_SUCCESS);
101 }
102 if ((r = accept(kev.ident, (struct sockaddr *)&ss, &slen)) == -1) {
103 syslog(LOG_ERR, "accept(): %m");
104 exit(EXIT_FAILURE);
105 }
106
107 c = fdopen(r, "r+");
108
109 fprintf(c, "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
110
111 fprintf(c, "<html>\n<body>\n");
112
113 launch_data_set_string(msg, LAUNCH_KEY_GETJOBS);
114
115 resp = launch_msg(msg);
116
117 launch_print_obj(resp, c);
118
119 fprintf(c, "</body>\n</html>\n");
120
121 fclose(c);
122
123 exit(EXIT_SUCCESS);
124 }
125
126 static void launch_print_obj(launch_data_t o, FILE *w)
127 {
128 size_t i;
129 void launch_print_obj_dict_callback(launch_data_t obj, const char *key, void *context __attribute__((unused))) {
130 fprintf(w, "<i>%s</i>\n", key);
131 if (launch_data_get_type(obj) != LAUNCH_DATA_ARRAY &&
132 launch_data_get_type(obj) != LAUNCH_DATA_DICTIONARY)
133 fprintf(w, "<ul><li>\n");
134 launch_print_obj(obj, w);
135 if (launch_data_get_type(obj) != LAUNCH_DATA_ARRAY &&
136 launch_data_get_type(obj) != LAUNCH_DATA_DICTIONARY)
137 fprintf(w, "</li></ul>\n");
138 }
139
140
141 switch (launch_data_get_type(o)) {
142 case LAUNCH_DATA_DICTIONARY:
143 fprintf(w, "<ul><li>\n");
144 launch_data_dict_iterate(o, launch_print_obj_dict_callback, NULL);
145 fprintf(w, "</li></ul>\n");
146 break;
147 case LAUNCH_DATA_ARRAY:
148 fprintf(w, "<ol>\n");
149 for (i = 0; i < launch_data_array_get_count(o); i++) {
150 fprintf(w, "<li>");
151 launch_print_obj(launch_data_array_get_index(o, i), w);
152 fprintf(w, "</li>\n");
153 }
154 fprintf(w, "</ol>\n");
155 break;
156 case LAUNCH_DATA_INTEGER:
157 fprintf(w, "Number: %lld", launch_data_get_integer(o));
158 break;
159 case LAUNCH_DATA_REAL:
160 fprintf(w, "Float: %f", launch_data_get_real(o));
161 break;
162 case LAUNCH_DATA_STRING:
163 fprintf(w, "String: %s", launch_data_get_string(o));
164 break;
165 case LAUNCH_DATA_OPAQUE:
166 fprintf(w, "Opaque: %p size %zu", launch_data_get_opaque(o), launch_data_get_opaque_size(o));
167 break;
168 case LAUNCH_DATA_FD:
169 fprintf(w, "FD: %d", launch_data_get_fd(o));
170 break;
171 case LAUNCH_DATA_BOOL:
172 fprintf(w, "Bool: %s", launch_data_get_bool(o) ? "true" : "false");
173 break;
174 default:
175 fprintf(w, "type %d is unknown", launch_data_get_type(o));
176 break;
177 }
178 }